imgtools/buildrom/src/configpaging.cpp
changeset 600 6d08f4a05d93
equal deleted inserted replaced
599:fa7a3cc6effd 600:6d08f4a05d93
       
     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 = &copyOfA[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