1 | //---------------------------------------------------------------------------
|
---|
2 | //File name: lang.c
|
---|
3 | //---------------------------------------------------------------------------
|
---|
4 | #include "launchelf.h"
|
---|
5 |
|
---|
6 | #define lang(id, name, value) u8 Str_##name [] = value;
|
---|
7 | #include "lang.h"
|
---|
8 | #undef lang
|
---|
9 |
|
---|
10 | Language Lang_Default[]={
|
---|
11 | #define lang(id, name, value) {Str_##name},
|
---|
12 | #include "lang.h"
|
---|
13 | #undef lang
|
---|
14 | {NULL}
|
---|
15 | };
|
---|
16 |
|
---|
17 | Language Lang_String[sizeof(Lang_Default) / sizeof(Lang_Default[0])];
|
---|
18 | Language Lang_Extern[sizeof(Lang_Default) / sizeof(Lang_Default[0])];
|
---|
19 |
|
---|
20 | Language *External_Lang_Buffer = NULL;
|
---|
21 |
|
---|
22 | //---------------------------------------------------------------------------
|
---|
23 | // get_LANG_string is the main parser called for each language dependent
|
---|
24 | // string in a language header file. (eg: "Francais.h" or "Francais.lng")
|
---|
25 | // Call values for all input arguments should be addresses of string pointers
|
---|
26 | // LANG_p_p is for file to be scanned, moved to point beyond scanned data.
|
---|
27 | // id_p_p is for a string defining the index value (suitable for 'atoi')
|
---|
28 | // value_p_p is for the string value itself (not NUL-terminated)
|
---|
29 | // The function returns the length of each string found, but -1 at EOF,
|
---|
30 | // and various error codes less than -1 (-2 etc) for various syntax errors,
|
---|
31 | // which also applies to EOF occurring where valid macro parts are expected.
|
---|
32 | //---------------------------------------------------------------------------
|
---|
33 | int get_LANG_string(u8 **LANG_p_p, u8 **id_p_p, u8 **value_p_p)
|
---|
34 | {
|
---|
35 | u8 *cp, *ip, *vp, *tp = *LANG_p_p;
|
---|
36 | int ret, length;
|
---|
37 |
|
---|
38 | ip = NULL;
|
---|
39 | vp = NULL;
|
---|
40 | ret = -1;
|
---|
41 |
|
---|
42 | start_line:
|
---|
43 | while(*tp<=' ' && *tp>'\0') tp+=1; //Skip leading whitespace, if any
|
---|
44 | if(*tp=='\0') goto exit; //but exit at EOF
|
---|
45 | //Current pos is potential "lang(" entry, but we must verify this
|
---|
46 | if(tp[0]=='/' && tp[1]=='/') //It may be a comment line
|
---|
47 | { //We must skip a comment line
|
---|
48 | while(*tp!='\r' && *tp!='\n' && *tp>'\0') tp+=1; //Seek line end
|
---|
49 | goto start_line; //Go back to try next line
|
---|
50 | }
|
---|
51 | ret = -2;
|
---|
52 | //Here tp points to a non-zero string that is not a comment
|
---|
53 | if(strncmp(tp, "lang", 4)) goto exit; //Return error if not 'lang' macro
|
---|
54 | tp+=4; //but if it is, step past that name
|
---|
55 | ret = -3;
|
---|
56 | while(*tp<=' ' && *tp!='\r' && *tp!='\n' && *tp>'\0') tp+=1; //skip inline whitespace
|
---|
57 | if(*tp=='\0') goto exit; //but exit at EOF
|
---|
58 | ret = -4;
|
---|
59 | //Here tp points to a non-zero string that should be an opening parenthesis
|
---|
60 | if(*tp!='(') goto exit; //Return error if no opening parenthesis
|
---|
61 | tp+=1; //but if it is, step past this character
|
---|
62 | ret = -5;
|
---|
63 | while(*tp<=' ' && *tp!='\r' && *tp!='\n' && *tp>'\0') tp+=1; //skip inline whitespace
|
---|
64 | if(*tp=='\0') goto exit; //but exit at EOF
|
---|
65 | ret = -6;
|
---|
66 | //Here tp points to a non-zero string that should be an index number
|
---|
67 | if(*tp<'0' || *tp>'9') goto exit; //Return error if it's not a number
|
---|
68 | ip = tp; //but if it is, save this pos as id start
|
---|
69 | while(*tp>='0' && *tp<='9') tp+=1; //skip past the index number
|
---|
70 | ret = -7;
|
---|
71 | while(*tp<=' ' && *tp!='\r' && *tp!='\n' && *tp>'\0') tp+=1; //skip inline whitespace
|
---|
72 | if(*tp=='\0') goto exit; //but exit at EOF
|
---|
73 | ret = -8;
|
---|
74 | //Here tp points to a non-zero string that should be a comma
|
---|
75 | if(*tp!=',') goto exit; //Return error if no comma after index
|
---|
76 | tp+=1; //but if present, step past that comma
|
---|
77 | ret = -9;
|
---|
78 | while(*tp<=' ' && *tp!='\r' && *tp!='\n' && *tp>'\0') tp+=1; //skip inline whitespace
|
---|
79 | if(*tp=='\0') goto exit; //but exit at EOF
|
---|
80 | ret = -10;
|
---|
81 | //Here tp points to a non-zero string that should be a symbolic string name
|
---|
82 | //But we don't need to process this for language switch purposes, so we ignore it
|
---|
83 | //This may be changed later, to use the name for generating error messages
|
---|
84 | while(*tp!=',' && *tp!='\r' && *tp!='\n' && *tp>'\0') tp+=1; //seek inline comma
|
---|
85 | if(*tp!=',') goto exit; //Return error if no comma after string name
|
---|
86 | tp+=1; //but if present, step past that comma
|
---|
87 | ret = -11;
|
---|
88 | while(*tp<=' ' && *tp!='\r' && *tp!='\n' && *tp>'\0') tp+=1; //skip inline whitespace
|
---|
89 | if(*tp=='\0') goto exit; //but exit at EOF
|
---|
90 | ret = -12;
|
---|
91 | //Here tp points to a non-zero string that should be the opening quote character
|
---|
92 | if(*tp!='\"') goto exit; //Return error if no opening quote
|
---|
93 | tp+=1; //but if present, step past that quote
|
---|
94 | ret = -13;
|
---|
95 | vp = tp; //save this pos as value start
|
---|
96 | close_quote:
|
---|
97 | while(*tp!='\"' && *tp!='\r' && *tp!='\n' && *tp>'\0') tp+=1; //seek inline quote
|
---|
98 | if(*tp!='\"') return -13; //Return error if no closing quote
|
---|
99 | cp = tp-1; //save previous pos as check pointer
|
---|
100 | tp+=1; //step past the quote character
|
---|
101 | if(*cp=='\\') goto close_quote; //if this was an 'escaped' quote, try again
|
---|
102 | //Here tp points to the character after the closing quote.
|
---|
103 | length = (tp-1) - vp; //prepare string length for return value
|
---|
104 | ret = -14;
|
---|
105 | while(*tp<=' ' && *tp!='\r' && *tp!='\n' && *tp>'\0') tp+=1; //skip inline whitespace
|
---|
106 | if(*tp=='\0') goto exit; //but exit at EOF
|
---|
107 | ret = -15;
|
---|
108 | //Here tp points to a non-zero string that should be closing parenthesis
|
---|
109 | if(*tp!=')') goto exit; //Return error if no closing parenthesis
|
---|
110 | tp+=1; //but if present, step past the parenthesis
|
---|
111 | ret = -16;
|
---|
112 | while(*tp<=' ' && *tp!='\r' && *tp!='\n' && *tp>'\0') tp+=1; //skip inline whitespace
|
---|
113 | if(*tp=='\0') goto exit; //but exit at EOF
|
---|
114 | //Here tp points to a non-zero string that should be line end or a comment
|
---|
115 | if(tp[0]!='/' || tp[1]!='/') goto finish_line; //if no comment, go handle line end
|
---|
116 | ret = -17;
|
---|
117 | while(*tp!='\r' && *tp!='\n' && *tp>'\0') tp+=1; //Seek line end
|
---|
118 | if(*tp=='\0') goto exit; //but exit at EOF
|
---|
119 | finish_line:
|
---|
120 | ret = -18;
|
---|
121 | if(*tp!='\r' && *tp!='\n') goto exit; //Return error if not valid line end
|
---|
122 | if(tp[0]=='\r' && tp[1]=='\n') tp+=1; //Step an extra pos for CR+LF
|
---|
123 | tp+=1; //Step past valid line end
|
---|
124 | //Here tp points beyond the line of the processed string, so we're done
|
---|
125 | ret = length;
|
---|
126 |
|
---|
127 | exit:
|
---|
128 | *LANG_p_p = tp; //return new LANG file position
|
---|
129 | *id_p_p = ip; //return found index
|
---|
130 | *value_p_p = vp; //return found string value
|
---|
131 | return ret; //return control to caller
|
---|
132 | }
|
---|
133 | //Ends get_LANG_string
|
---|
134 | //---------------------------------------------------------------------------
|
---|
135 | void Init_Default_Language(void)
|
---|
136 | {
|
---|
137 | memcpy(Lang_String, Lang_Default, sizeof(Lang_String));
|
---|
138 | }
|
---|
139 | //Ends Init_Default_Language
|
---|
140 | //---------------------------------------------------------------------------
|
---|
141 | void Load_External_Language(void)
|
---|
142 | {
|
---|
143 | int error_id = -1;
|
---|
144 | int test = 0;
|
---|
145 | u32 index = 0;
|
---|
146 | char filePath[MAX_PATH];
|
---|
147 | u8 *file_bp, *file_tp, *lang_bp, *lang_tp, *oldf_tp=NULL;
|
---|
148 | u8 *id_p, *value_p;
|
---|
149 | int lang_size = 0;
|
---|
150 | int fd;
|
---|
151 |
|
---|
152 | if(External_Lang_Buffer!=NULL){ //if an external buffer was allocated before
|
---|
153 | free(External_Lang_Buffer); //release that buffer before the new attempt
|
---|
154 | External_Lang_Buffer = NULL;
|
---|
155 | }
|
---|
156 |
|
---|
157 | Language* Lang = Lang_Default;
|
---|
158 | memcpy(Lang_String, Lang, sizeof(Lang_String));
|
---|
159 |
|
---|
160 | if(strlen(setting->lang_file)!=0){ //if language file string set
|
---|
161 |
|
---|
162 | error_id = -2;
|
---|
163 | genFixPath(setting->lang_file, filePath);
|
---|
164 | fd = genOpen(filePath, O_RDONLY);
|
---|
165 | if(fd >= 0){ //if file opened OK
|
---|
166 | int file_size = genLseek(fd, 0, SEEK_END);
|
---|
167 |
|
---|
168 | error_id = -3;
|
---|
169 | if (file_size > 0) { //if file size OK
|
---|
170 | error_id = -4;
|
---|
171 | file_bp = (u8*) malloc(file_size + 1);
|
---|
172 | if(file_bp == NULL)
|
---|
173 | goto aborted_1;
|
---|
174 |
|
---|
175 | error_id = -5;
|
---|
176 | genLseek(fd, 0, SEEK_SET);
|
---|
177 | if(genRead(fd, file_bp, file_size) != file_size)
|
---|
178 | goto release_1;
|
---|
179 | file_bp[file_size] = '\0'; //enforce termination at buffer end
|
---|
180 |
|
---|
181 | error_id = -6;
|
---|
182 | file_tp = file_bp;
|
---|
183 | while(1){
|
---|
184 | oldf_tp = file_tp;
|
---|
185 | test = get_LANG_string(&file_tp, &id_p, &value_p);
|
---|
186 | if(test==-1) //if EOF reached without other error
|
---|
187 | break; //break from the loop normally
|
---|
188 | if(test<0) //At any fatal error result
|
---|
189 | goto release_1; //go release file buffer
|
---|
190 | index = atoi(id_p); //get the string index
|
---|
191 | if(index>=LANG_COUNT) //At any fatal error result
|
---|
192 | goto release_1; //go release file buffer
|
---|
193 | lang_size += test + 1; //Include terminator space for total size
|
---|
194 | }
|
---|
195 | //Here lang_size is the space needed for real language buffer,
|
---|
196 |
|
---|
197 | error_id = -7;
|
---|
198 | lang_bp = (u8*) malloc(lang_size + 1); //allocate real language buffer
|
---|
199 | if(lang_bp == NULL)
|
---|
200 | goto release_1;
|
---|
201 |
|
---|
202 | //We're ready to read language strings, but must first init all pointers
|
---|
203 | //to use default strings, for any indexes left undefined by the file
|
---|
204 | memcpy(Lang_Extern, Lang, sizeof(Lang_Extern));
|
---|
205 |
|
---|
206 | file_tp = file_bp;
|
---|
207 | lang_tp = lang_bp;
|
---|
208 | while((test = get_LANG_string(&file_tp, &id_p, &value_p)) >= 0){
|
---|
209 | index = atoi(id_p); //get the string index
|
---|
210 | Lang_Extern[index].String = lang_tp; //save pointer to this string base
|
---|
211 | strncpy(lang_tp, value_p, test); //transfer the string
|
---|
212 | lang_tp[test] = '\0'; //transfer a terminator
|
---|
213 | lang_tp += test + 1; //move dest pointer past this string
|
---|
214 | }
|
---|
215 | External_Lang_Buffer = (Language*) lang_bp; //Save base pointer for releases
|
---|
216 | Lang = Lang_Extern;
|
---|
217 | error_id = 0;
|
---|
218 | release_1:
|
---|
219 | free(file_bp);
|
---|
220 | } // end if clause for file size OK
|
---|
221 | aborted_1:
|
---|
222 | genClose( fd );
|
---|
223 | } // end if clause for file opened OK
|
---|
224 | } // end if language file string set
|
---|
225 |
|
---|
226 | if(error_id < -1){
|
---|
227 | u8 tmp_s[80*8], t1_s[102], t2_s[102];
|
---|
228 | int pos=0, stp=0;
|
---|
229 | sprintf(tmp_s,
|
---|
230 | "LNG loading failed with error_id==%d and test==%d\n"
|
---|
231 | "The latest string index (possibly invalid) was %d\n"
|
---|
232 | "%n"
|
---|
233 | , error_id, test, index, &stp
|
---|
234 | );
|
---|
235 | pos += stp;
|
---|
236 | if(error_id==-2) {//if file open failure
|
---|
237 | sprintf(tmp_s+pos,
|
---|
238 | "This was a failure to open the file:\n"
|
---|
239 | "\"%s\"\n"
|
---|
240 | , filePath
|
---|
241 | );
|
---|
242 | }
|
---|
243 | if(error_id==-6) {//if parsing error
|
---|
244 | strncpy(t1_s, oldf_tp, 100);
|
---|
245 | t1_s[100] = '\0';
|
---|
246 | strncpy(t2_s, file_tp, 100);
|
---|
247 | t2_s[100] = '\0';
|
---|
248 | sprintf(tmp_s+pos,
|
---|
249 | "This was a parsing error when trying to parse the text:\n"
|
---|
250 | "\"%s\"\n"
|
---|
251 | "That attempt failed somehow, after reaching this point:\n"
|
---|
252 | "\"%s\"\n"
|
---|
253 | , t1_s, t2_s
|
---|
254 | );
|
---|
255 | }
|
---|
256 | strcat(tmp_s, "Use either OK or CANCEL to continue (no diff)");
|
---|
257 | ynDialog(tmp_s);
|
---|
258 | }
|
---|
259 |
|
---|
260 | memcpy(Lang_String, Lang, sizeof(Lang_String));
|
---|
261 |
|
---|
262 | int i;
|
---|
263 | char *tmp;
|
---|
264 |
|
---|
265 | if(strlen(setting->Misc)>0){
|
---|
266 | for(i=0; i<16; i++){ //Loop to rename the ELF paths with new language for launch keys
|
---|
267 | if((i<12) || (setting->LK_Flag[i]!=0)){
|
---|
268 | if(!strncmp(setting->LK_Path[i], setting->Misc, strlen(setting->Misc))){
|
---|
269 | tmp = strrchr(setting->LK_Path[i], '/');
|
---|
270 | if(!strcmp(tmp+1, setting->Misc_PS2Disc+strlen(setting->Misc)))
|
---|
271 | sprintf(setting->LK_Path[i], "%s/%s", LNG(MISC), LNG(PS2Disc));
|
---|
272 | else if(!strcmp(tmp+1, setting->Misc_FileBrowser+strlen(setting->Misc)))
|
---|
273 | sprintf(setting->LK_Path[i], "%s/%s", LNG(MISC), LNG(FileBrowser));
|
---|
274 | else if(!strcmp(tmp+1, setting->Misc_PS2Browser+strlen(setting->Misc)))
|
---|
275 | sprintf(setting->LK_Path[i], "%s/%s", LNG(MISC), LNG(PS2Browser));
|
---|
276 | else if(!strcmp(tmp+1, setting->Misc_PS2Net+strlen(setting->Misc)))
|
---|
277 | sprintf(setting->LK_Path[i], "%s/%s", LNG(MISC), LNG(PS2Net));
|
---|
278 | else if(!strcmp(tmp+1, setting->Misc_PS2PowerOff+strlen(setting->Misc)))
|
---|
279 | sprintf(setting->LK_Path[i], "%s/%s", LNG(MISC), LNG(PS2PowerOff));
|
---|
280 | else if(!strcmp(tmp+1, setting->Misc_HddManager+strlen(setting->Misc)))
|
---|
281 | sprintf(setting->LK_Path[i], "%s/%s", LNG(MISC), LNG(HddManager));
|
---|
282 | else if(!strcmp(tmp+1, setting->Misc_TextEditor+strlen(setting->Misc)))
|
---|
283 | sprintf(setting->LK_Path[i], "%s/%s", LNG(MISC), LNG(TextEditor));
|
---|
284 | else if(!strcmp(tmp+1, setting->Misc_JpgViewer+strlen(setting->Misc)))
|
---|
285 | sprintf(setting->LK_Path[i], "%s/%s", LNG(MISC), LNG(JpgViewer));
|
---|
286 | else if(!strcmp(tmp+1, setting->Misc_Configure+strlen(setting->Misc)))
|
---|
287 | sprintf(setting->LK_Path[i], "%s/%s", LNG(MISC), LNG(Configure));
|
---|
288 | else if(!strcmp(tmp+1, setting->Misc_Load_CNFprev+strlen(setting->Misc)))
|
---|
289 | sprintf(setting->LK_Path[i], "%s/%s", LNG(MISC), LNG(Load_CNFprev));
|
---|
290 | else if(!strcmp(tmp+1, setting->Misc_Load_CNFnext+strlen(setting->Misc)))
|
---|
291 | sprintf(setting->LK_Path[i], "%s/%s", LNG(MISC), LNG(Load_CNFnext));
|
---|
292 | else if(!strcmp(tmp+1, setting->Misc_Set_CNF_Path+strlen(setting->Misc)))
|
---|
293 | sprintf(setting->LK_Path[i], "%s/%s", LNG(MISC), LNG(Set_CNF_Path));
|
---|
294 | else if(!strcmp(tmp+1, setting->Misc_Load_CNF+strlen(setting->Misc)))
|
---|
295 | sprintf(setting->LK_Path[i], "%s/%s", LNG(MISC), LNG(Load_CNF));
|
---|
296 | else if(!strcmp(tmp+1, setting->Misc_ShowFont+strlen(setting->Misc)))
|
---|
297 | sprintf(setting->LK_Path[i], "%s/%s", LNG(MISC), LNG(ShowFont));
|
---|
298 | else if(!strcmp(tmp+1, setting->Misc_Debug_Info+strlen(setting->Misc)))
|
---|
299 | sprintf(setting->LK_Path[i], "%s/%s", LNG(MISC), LNG(Debug_Info));
|
---|
300 | else if(!strcmp(tmp+1, setting->Misc_About_uLE+strlen(setting->Misc)))
|
---|
301 | sprintf(setting->LK_Path[i], "%s/%s", LNG(MISC), LNG(About_uLE));
|
---|
302 | } // end if Misc
|
---|
303 | } // end if LK assigned
|
---|
304 | } // end for
|
---|
305 | } // end if Misc Initialized
|
---|
306 |
|
---|
307 | sprintf(setting->Misc , "%s/", LNG(MISC));
|
---|
308 | sprintf(setting->Misc_PS2Disc , "%s/%s", LNG(MISC), LNG(PS2Disc));
|
---|
309 | sprintf(setting->Misc_FileBrowser , "%s/%s", LNG(MISC), LNG(FileBrowser));
|
---|
310 | sprintf(setting->Misc_PS2Browser , "%s/%s", LNG(MISC), LNG(PS2Browser));
|
---|
311 | sprintf(setting->Misc_PS2Net , "%s/%s", LNG(MISC), LNG(PS2Net));
|
---|
312 | sprintf(setting->Misc_PS2PowerOff , "%s/%s", LNG(MISC), LNG(PS2PowerOff));
|
---|
313 | sprintf(setting->Misc_HddManager , "%s/%s", LNG(MISC), LNG(HddManager));
|
---|
314 | sprintf(setting->Misc_TextEditor , "%s/%s", LNG(MISC), LNG(TextEditor));
|
---|
315 | sprintf(setting->Misc_JpgViewer , "%s/%s", LNG(MISC), LNG(JpgViewer));
|
---|
316 | sprintf(setting->Misc_Configure , "%s/%s", LNG(MISC), LNG(Configure));
|
---|
317 | sprintf(setting->Misc_Load_CNFprev , "%s/%s", LNG(MISC), LNG(Load_CNFprev));
|
---|
318 | sprintf(setting->Misc_Load_CNFnext , "%s/%s", LNG(MISC), LNG(Load_CNFnext));
|
---|
319 | sprintf(setting->Misc_Set_CNF_Path , "%s/%s", LNG(MISC), LNG(Set_CNF_Path));
|
---|
320 | sprintf(setting->Misc_Load_CNF , "%s/%s", LNG(MISC), LNG(Load_CNF));
|
---|
321 | sprintf(setting->Misc_ShowFont , "%s/%s", LNG(MISC), LNG(ShowFont));
|
---|
322 | sprintf(setting->Misc_Debug_Info , "%s/%s", LNG(MISC), LNG(Debug_Info));
|
---|
323 | sprintf(setting->Misc_About_uLE , "%s/%s", LNG(MISC), LNG(About_uLE));
|
---|
324 |
|
---|
325 | }
|
---|
326 | //Ends Load_External_Language
|
---|
327 | //---------------------------------------------------------------------------
|
---|
328 | //End of file: lang.c
|
---|
329 | //---------------------------------------------------------------------------
|
---|