|
1 /* |
|
2 * Copyright (c) 2009 - 2010 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the License "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * @internalComponent * @released |
|
16 * configpaging mainfile to do configpaging in buildrom. |
|
17 * |
|
18 */ |
|
19 |
|
20 #include <boost/regex.hpp> |
|
21 #include <string> |
|
22 #include <iostream> |
|
23 #include <map> |
|
24 #include <vector> |
|
25 #include <fstream> |
|
26 #include <malloc.h> |
|
27 |
|
28 using namespace std; |
|
29 using namespace boost ; |
|
30 |
|
31 typedef const char* const_str ; |
|
32 |
|
33 static const string NULL_STRING(""); |
|
34 static const char CONSTANT_UNPAGED[] = "unpaged"; |
|
35 static const char CONSTANT_PAGED[] = "paged"; |
|
36 static const char CONSTANT_UNPAGEDCODE[] = "unpagedcode"; |
|
37 static const char CONSTANT_PAGEDCODE[] = "pagedcode"; |
|
38 static const char CONSTANT_UNPAGEDDATA[] = "unpageddata"; |
|
39 static const char CONSTANT_PAGEDDATA[] = "pageddata"; |
|
40 #ifdef WIN32 |
|
41 static const char CONSTANT_CONFIG_PATH[] = "epoc32\\rom\\configpaging\\"; |
|
42 static string epocroot("\\"); |
|
43 static const char SLASH_CHAR = '\\'; |
|
44 #else |
|
45 #include <strings.h> |
|
46 #define strnicmp strncasecmp |
|
47 #define _alloca alloca |
|
48 static const char CONSTANT_CONFIG_PATH[] = "epoc32/rom/configpaging/"; |
|
49 static string epocroot("/"); |
|
50 static const char SLASH_CHAR = '/'; |
|
51 #endif |
|
52 static const char CONSTANT_CONFIG_FILE[] = "configpaging.cfg" ; |
|
53 #define is_undef(s) (0 == s.length()) |
|
54 static const int MAJOR_VERSION = 1; |
|
55 static const int MINOR_VERSION = 2; |
|
56 static const int BUILD_NUMBER = 0; |
|
57 static const char COPYRIGHT[]="Copyright (c) 2010 Nokia Corporation."; |
|
58 struct ListElement{ |
|
59 const_str code ; |
|
60 const_str data ; |
|
61 }; |
|
62 |
|
63 |
|
64 static string configlist ; |
|
65 static regex e0("^(file|data|dll|secondary)(=|\\s+)",regex::perl|regex::icase); |
|
66 static regex e1("^(code|data)?pagingoverride=(.*)\\s*",regex::perl); |
|
67 static regex e2("^(un)?paged(code|data)?(\\s+(un)?paged(code|data)?)?:",regex::perl); |
|
68 static regex e3("^include\\s*\"(.*)\"",regex::perl); |
|
69 static regex e4("(\\S+)(\\s+(un)?paged(code|data)?(\\s+(un)?paged(code|data)?)?)?",regex::perl); |
|
70 static regex e5("\\b(un)?paged(data)?\\b\\s*$",regex::perl|regex::icase); |
|
71 static regex e6("\\b(un)?paged(code)?\\b\\s*$",regex::perl|regex::icase); |
|
72 static regex e7("\\b(un)?paged(code|data)?\\b",regex::perl|regex::icase); |
|
73 //static regex e8("tool=|\\s+)",regex::perl|regex::icase); |
|
74 |
|
75 |
|
76 |
|
77 static bool is_obystatement(const char* aLine) { |
|
78 if(!strnicmp(aLine,"file",4)|| !strnicmp(aLine,"data",4)) |
|
79 aLine += 4 ; |
|
80 else if(!strnicmp(aLine,"dll",3)) |
|
81 aLine += 3; |
|
82 else if(!strnicmp(aLine,"secondary",9)) |
|
83 aLine += 9 ; |
|
84 else |
|
85 return false ; |
|
86 |
|
87 return (*aLine =='=' || *aLine == ' '|| *aLine == '\t'); |
|
88 |
|
89 } |
|
90 static void trim(string& aStr){ |
|
91 |
|
92 char* data = const_cast<char*>(aStr.data()); |
|
93 int length = aStr.length(); |
|
94 int firstIndex = 0 ; |
|
95 int lastIndex = length - 1; |
|
96 // remove ending blanks |
|
97 while(lastIndex >= 0 && (data[lastIndex] == ' ' || data[lastIndex] == '\t')){ |
|
98 lastIndex -- ; |
|
99 } |
|
100 |
|
101 // remove heading blanks |
|
102 while((firstIndex < lastIndex ) && (data[firstIndex] == ' ' || data[firstIndex] == '\t')){ |
|
103 firstIndex ++ ; |
|
104 } |
|
105 lastIndex++ ; |
|
106 if(lastIndex < length){ |
|
107 aStr.erase(lastIndex,length - lastIndex); |
|
108 } |
|
109 if(firstIndex > 0){ |
|
110 aStr.erase(0,firstIndex); |
|
111 } |
|
112 } |
|
113 static void make_lower(char* aStr,size_t aLength){ |
|
114 |
|
115 for(size_t i = 0 ; i < aLength ; i++){ |
|
116 if(aStr[i] >= 'A' && aStr[i] <= 'Z') |
|
117 aStr[i] |= 0x20 ; |
|
118 } |
|
119 } |
|
120 static bool readConfigFile(const_str& aCodePagingRef, const_str& aDataPagingRef, |
|
121 map<string,ListElement>& aListRef, const_str aFileName ) { |
|
122 ifstream is(aFileName, ios_base::binary | ios_base::in); |
|
123 if(!is.is_open()){ |
|
124 cerr<< "Can not open \""<< aFileName << "\" for reading.\n"; |
|
125 return false ; |
|
126 } |
|
127 const_str filecodepaging = ""; |
|
128 const_str filedatapaging = ""; |
|
129 match_results<string::const_iterator> what; |
|
130 |
|
131 is.seekg(0,ios::end); |
|
132 size_t size = is.tellg(); |
|
133 is.seekg(0,ios::beg); |
|
134 |
|
135 char *buf = new char[size + 1]; |
|
136 is.read(buf,size); |
|
137 buf[size] = '\n' ; |
|
138 |
|
139 char* end = buf + size ; |
|
140 char* lineStart = buf ; |
|
141 int lfcr ; |
|
142 string line ; |
|
143 |
|
144 while(lineStart < end ){ |
|
145 // trim left ; |
|
146 while(*lineStart == ' ' || *lineStart == '\t' ){ |
|
147 lineStart++ ; |
|
148 } |
|
149 char* lineEnd = lineStart; |
|
150 while(*lineEnd != '\r' && *lineEnd != '\n'){ |
|
151 lineEnd++ ; |
|
152 } |
|
153 if(*lineEnd == '\r' && lineEnd[1] == '\n') |
|
154 lfcr = 2 ; |
|
155 else |
|
156 lfcr = 1 ; |
|
157 |
|
158 *lineEnd = 0 ; |
|
159 // empty line or comment |
|
160 if(lineEnd == lineStart || *lineStart == '#' ){ |
|
161 lineStart = lineEnd + lfcr ; |
|
162 continue ; |
|
163 } |
|
164 size_t lenOfLine = lineEnd - lineStart; |
|
165 make_lower(lineStart,lenOfLine); |
|
166 line.assign(lineStart,lenOfLine); |
|
167 |
|
168 if(regex_search(line, what, e1)){ |
|
169 string r1 = what[1].str(); |
|
170 string r2 = what[2].str(); |
|
171 if(is_undef(r1)){ //if ($1 eq undef) |
|
172 if(r2 == "defaultpaged"){ |
|
173 aCodePagingRef = CONSTANT_PAGED ; |
|
174 } else if(r2 == "defaultunpaged"){ |
|
175 aCodePagingRef = CONSTANT_UNPAGED ; |
|
176 aDataPagingRef = CONSTANT_UNPAGED; |
|
177 }else{ |
|
178 cerr << "Configpaging Warning: invalid pagingoverride setting: "<< r2 <<"\n" ; |
|
179 } |
|
180 }else if(r1 == "code"){ |
|
181 if(r2 == "defaultpaged"){ |
|
182 aCodePagingRef = CONSTANT_PAGED ; |
|
183 } else if(r2 == "defaultunpaged"){ |
|
184 aCodePagingRef = CONSTANT_UNPAGED ; |
|
185 }else{ |
|
186 cerr << "Configpaging Warning: invalid codepagingoverride setting: "<< r2 <<"\n" ; |
|
187 } |
|
188 } |
|
189 else if(r1 == "data" ){ |
|
190 if(r2 == "defaultpaged"){ |
|
191 aDataPagingRef = CONSTANT_PAGED ; |
|
192 } else if(r2 == "defaultunpaged"){ |
|
193 aDataPagingRef = CONSTANT_UNPAGED ; |
|
194 }else{ |
|
195 cerr << "Configpaging Warning: invalid datapagingoverride setting: "<< r2 <<"\n" ; |
|
196 } |
|
197 } |
|
198 }// check e1 |
|
199 else if(regex_search(line, what, e2)){ |
|
200 string r1 = what[1].str(); |
|
201 string r2 = what[2].str(); |
|
202 string r3 = what[3].str(); |
|
203 string r4 = what[4].str(); |
|
204 string r5 = what[5].str(); |
|
205 filecodepaging = ""; |
|
206 filedatapaging = ""; |
|
207 if (is_undef(r1)) { |
|
208 if (is_undef(r2)) { |
|
209 filecodepaging = CONSTANT_PAGED; |
|
210 }else if (r2 == "code") { |
|
211 filecodepaging = CONSTANT_PAGED; |
|
212 } else if(r2 == "data") { |
|
213 filedatapaging = CONSTANT_PAGED; |
|
214 } else { |
|
215 cerr << "Configpaging Warning: unrecognized line: "<< lineStart << "\n"; |
|
216 } |
|
217 } else if (r1 == "un"){ |
|
218 if (is_undef(r2)) { //$2 eq undef |
|
219 filecodepaging = CONSTANT_UNPAGED; |
|
220 filedatapaging = CONSTANT_UNPAGED; |
|
221 }else if (r2 == "code") { |
|
222 filecodepaging = CONSTANT_UNPAGED; |
|
223 } else if(r2 == "data") { |
|
224 filedatapaging = CONSTANT_UNPAGED; |
|
225 } else { |
|
226 cerr << "Configpaging Warning: unrecognized line: "<< lineStart << "\n"; |
|
227 } |
|
228 } else { |
|
229 cerr << "Configpaging Warning: unrecognized line: "<< lineStart << "\n"; |
|
230 } |
|
231 if (r3.length() > 0){ //$3 ne undef |
|
232 if (is_undef(r4)) { |
|
233 if (is_undef(r5)) { |
|
234 filecodepaging = CONSTANT_PAGED; |
|
235 }else if (r5 == "code") { |
|
236 filecodepaging = CONSTANT_PAGED; |
|
237 } else if(r5 == "data") { |
|
238 filedatapaging = CONSTANT_PAGED; |
|
239 } else { |
|
240 cerr << "Configpaging Warning: unrecognized line: "<< lineStart << "\n"; |
|
241 } |
|
242 } else if (r4 == "un") { |
|
243 if (is_undef(r5)) { |
|
244 filecodepaging = CONSTANT_UNPAGED; |
|
245 filedatapaging = CONSTANT_UNPAGED; |
|
246 }else if (r5 == "code") { |
|
247 filecodepaging = CONSTANT_UNPAGED; |
|
248 } else if(r5 == "data") { |
|
249 filedatapaging = CONSTANT_UNPAGED; |
|
250 } else { |
|
251 cerr << "Configpaging Warning: unrecognized line: "<< lineStart << "\n"; |
|
252 } |
|
253 } else { |
|
254 cerr << "Configpaging Warning: unrecognized line: "<< lineStart << "\n"; |
|
255 } |
|
256 } |
|
257 } |
|
258 else if(regex_search(line, what, e3)){ |
|
259 string filename = epocroot + CONSTANT_CONFIG_PATH; |
|
260 filename += what[1].str(); |
|
261 readConfigFile(aCodePagingRef, aDataPagingRef, aListRef, filename.c_str()); |
|
262 } |
|
263 else if(regex_search(line, what, e4)){ |
|
264 string r1 = what[1].str(); |
|
265 string r2 = what[2].str(); |
|
266 string r3 = what[3].str(); |
|
267 string r4 = what[4].str(); |
|
268 string r5 = what[5].str(); |
|
269 string r6 = what[6].str(); |
|
270 string r7 = what[7].str(); |
|
271 ListElement element = {aCodePagingRef, aDataPagingRef}; |
|
272 if (is_undef(r2)){ //($2 eq undef){ |
|
273 if (0 != *filecodepaging){//filecodepaging ne "") |
|
274 element.code = filecodepaging; //$element{code} = $filecodepaging; |
|
275 } |
|
276 if ( 0 != *filedatapaging){//$filedatapaging ne "") |
|
277 element.data = filedatapaging ;//element.data = $filedatapaging; |
|
278 } |
|
279 } else { |
|
280 if (is_undef(r4)){//$4 eq undef |
|
281 if (is_undef(r3)) {//$3 eq undef |
|
282 element.code = CONSTANT_PAGED; |
|
283 } else if (r3 == "un") { |
|
284 element.code = CONSTANT_UNPAGED; |
|
285 element.data = CONSTANT_UNPAGED; |
|
286 } |
|
287 } else if (r4 == "code") { |
|
288 if (is_undef(r3)) { |
|
289 element.code = CONSTANT_PAGED; |
|
290 } else if (r3 == "un") { |
|
291 element.code = CONSTANT_UNPAGED; |
|
292 } |
|
293 } else if (r4 == "data") { |
|
294 if (is_undef(r3)) { |
|
295 element.data = CONSTANT_PAGED; |
|
296 } else if (r3 == "un") { |
|
297 element.data = CONSTANT_UNPAGED; |
|
298 } |
|
299 } else { |
|
300 cerr << "Configpaging Warning: unrecognized attribute in line: "<< lineStart << "\n"; |
|
301 } |
|
302 if (r5.length() > 0){//$5 ne undef |
|
303 if (is_undef(r7)){ //$7 eq undef |
|
304 if (is_undef(r6)) { //$6 eq undef |
|
305 element.code = CONSTANT_PAGED; |
|
306 } else if (r6 == "un") { |
|
307 element.code = CONSTANT_UNPAGED; |
|
308 element.data = CONSTANT_UNPAGED; |
|
309 } |
|
310 } else if (r7 == "code") { |
|
311 if (is_undef(r6)) { |
|
312 element.code = CONSTANT_PAGED; |
|
313 } else if (r6 == "un") { |
|
314 element.code = CONSTANT_UNPAGED; |
|
315 } |
|
316 } else if (r7 == "data") { |
|
317 if (is_undef(r6)) { |
|
318 element.data = CONSTANT_PAGED; |
|
319 } else if (r6 == "un") { |
|
320 element.data = CONSTANT_UNPAGED; |
|
321 } |
|
322 } else { |
|
323 cerr << "Configpaging Warning: unrecognized attribute in line: "<< lineStart << "\n"; |
|
324 } |
|
325 } |
|
326 } |
|
327 //$$listref{$1} = \%element; |
|
328 aListRef.insert(pair<string,ListElement>(r1,element)); |
|
329 } |
|
330 lineStart = lineEnd + lfcr ; |
|
331 } |
|
332 |
|
333 delete []buf ; |
|
334 is.close(); |
|
335 |
|
336 return true ; |
|
337 } |
|
338 |
|
339 static bool match_icase(const string& a, const string& b){ |
|
340 int la = a.length(); |
|
341 int lb = b.length(); |
|
342 char *copyOfA = (char*)_alloca(la+2); |
|
343 *copyOfA = ' '; |
|
344 copyOfA++ ; |
|
345 memcpy(copyOfA ,a.c_str(),la); |
|
346 copyOfA[la] = 0; |
|
347 char* end = ©OfA[la]; |
|
348 make_lower(copyOfA,la); |
|
349 while(copyOfA < end){ |
|
350 char *found = strstr(copyOfA,b.c_str()); |
|
351 if(0 == found) |
|
352 return false ; |
|
353 if((found[-1] == ' ' || found[-1] == '\\'|| found[-1] == '/'|| found[-1] == '\t' || found[-1] == '"'|| found[-1] == '=') && |
|
354 ( found[lb] == ' '|| found[lb] == '\t' || found[lb] == '"'|| found[lb] == '\0')) |
|
355 return true ; |
|
356 copyOfA = found + lb ; |
|
357 } |
|
358 |
|
359 return false ; |
|
360 } |
|
361 |
|
362 static void configpaging_single(){ |
|
363 |
|
364 const_str codepaging=""; |
|
365 const_str datapaging=""; |
|
366 map<string, ListElement> list ; |
|
367 vector<string> keys ;//my @keys; |
|
368 string line ; |
|
369 |
|
370 cerr << "configpaging.exe: Modifying demand paging configuration using "<< configlist <<"\n"; |
|
371 readConfigFile(codepaging, datapaging, list, configlist.c_str()); |
|
372 match_results<string::const_iterator> what; |
|
373 string codepagingadd ,datapagingadd ; |
|
374 while(true){ |
|
375 getline(cin,line); |
|
376 if(cin.eof()) break ; |
|
377 if(line == ":q") break ; |
|
378 trim(line); |
|
379 const char* lineData = line.data(); |
|
380 if(*lineData == '#' ){ |
|
381 cout << lineData << "\n" ; |
|
382 continue ; |
|
383 } |
|
384 int length = line.length(); |
|
385 if( length > 2){ |
|
386 //check rem |
|
387 if((lineData[0] == 'R' || lineData[0] == 'r' ) && (lineData[1] == 'E' || lineData[1] == 'e' ) && (lineData[2] == 'M' || lineData[2] == 'm' )){ |
|
388 cout << lineData << "\n" ; |
|
389 continue ; |
|
390 } |
|
391 } |
|
392 codepagingadd = ""; |
|
393 datapagingadd = ""; |
|
394 |
|
395 if(is_obystatement(lineData)){ |
|
396 for( map<string,ListElement>::iterator it = list.begin() ; it != list.end() ; it++){ |
|
397 if(match_icase(line,it->first) ){ |
|
398 if (it->second.code == CONSTANT_PAGED ){ |
|
399 codepagingadd += " " ; |
|
400 codepagingadd += CONSTANT_PAGEDCODE; |
|
401 } else if (it->second.code == CONSTANT_UNPAGED) { |
|
402 codepagingadd += " " ; |
|
403 codepagingadd += CONSTANT_UNPAGEDCODE; |
|
404 } |
|
405 if (it->second.data == CONSTANT_PAGED) { |
|
406 datapagingadd += " " ; |
|
407 datapagingadd += CONSTANT_PAGEDDATA; |
|
408 } else if (it->second.data == CONSTANT_UNPAGED) { |
|
409 datapagingadd += " " ; |
|
410 datapagingadd += CONSTANT_UNPAGEDDATA; |
|
411 } |
|
412 break ; |
|
413 } |
|
414 }//for |
|
415 if (codepagingadd.length() == 0 && 0 != *codepaging) {//!$codepagingadd and $codepaging |
|
416 codepagingadd = " " ; |
|
417 codepagingadd += codepaging ; |
|
418 codepagingadd += "code"; |
|
419 } |
|
420 if (datapagingadd.length() == 0 && 0 != *datapaging) { //!$datapagingadd and $datapaging |
|
421 datapagingadd = " " ; |
|
422 datapagingadd += datapaging ; |
|
423 datapagingadd += "data"; |
|
424 } |
|
425 if (codepagingadd.length() > 0 && datapagingadd.length() == 0){ //$codepagingadd and !$datapagingadd |
|
426 if (regex_search(line,what,e5)){ //$line =~ /\b(un)?paged(data)?\b\s*$/) { //$line =~ /\b(un)?paged(data)?\b\s*$/ |
|
427 datapagingadd = " " ; |
|
428 if(what[1].length() > 0) |
|
429 { |
|
430 datapagingadd += what[1].str(); |
|
431 datapagingadd += "pageddata"; |
|
432 } |
|
433 } |
|
434 } else if (datapagingadd.length() > 0 && codepagingadd.length() == 0) {//$datapagingadd and !$codepagingadd |
|
435 if (regex_search(line,what,e6)){ |
|
436 codepagingadd = " " ; |
|
437 codepagingadd += what[1].str(); |
|
438 codepagingadd += "pagedcode"; |
|
439 } |
|
440 } |
|
441 if (datapagingadd.length() > 0 || datapagingadd.length() > 0) { // $datapagingadd or $datapagingadd |
|
442 line = regex_replace(line,e7,NULL_STRING); |
|
443 } |
|
444 } |
|
445 cout << line << codepagingadd << datapagingadd << "\n"; |
|
446 |
|
447 } |
|
448 } |
|
449 // |
|
450 int main(int argc , char* argv[]) { |
|
451 |
|
452 char* tmp = getenv("EPOCROOT"); |
|
453 if(tmp && *tmp) |
|
454 epocroot = string(tmp); |
|
455 char ch = epocroot.at(epocroot.length() - 1); |
|
456 if(ch != '\\' && ch != '/') |
|
457 epocroot += SLASH_CHAR; |
|
458 |
|
459 if(argc > 1 ){ |
|
460 char* arg = argv[1]; |
|
461 if('-' == *arg && (arg[1] | 0x20) == 'v'){ |
|
462 cout << "configpaging - The paging configuration plugin for BUILDROM V" ; |
|
463 cout << MAJOR_VERSION << "."<< MINOR_VERSION << "." << BUILD_NUMBER<< endl; |
|
464 cout << COPYRIGHT << endl << endl; |
|
465 return 0; |
|
466 } |
|
467 configlist = epocroot + CONSTANT_CONFIG_PATH; |
|
468 configlist += string(arg); |
|
469 } |
|
470 else{ |
|
471 configlist = epocroot + CONSTANT_CONFIG_PATH; |
|
472 configlist += CONSTANT_CONFIG_FILE; |
|
473 } |
|
474 configpaging_single(); |
|
475 |
|
476 return 0; |
|
477 } |
|
478 |