e32tools/elf2e32/source/deffile.cpp
changeset 0 044383f39525
child 682 2c32f186fa1f
equal deleted inserted replaced
-1:000000000000 0:044383f39525
       
     1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Implementation of the Class DefFile for the elf2e32 tool
       
    15 // @internalComponent
       
    16 // @released
       
    17 // 
       
    18 //
       
    19 
       
    20 //
       
    21 #include <stdio.h>
       
    22 #include <iostream>
       
    23 #include <stdlib.h>
       
    24 
       
    25 #include "pl_symbol.h"
       
    26 #include "deffile.h"
       
    27 #include "errorhandler.h"
       
    28 
       
    29 #ifdef __LINUX__
       
    30     #include "h_utl.h"
       
    31     #define STRUPR strupr
       
    32 #else 
       
    33     #define STRUPR _strupr
       
    34 #endif
       
    35 
       
    36 using std::cerr;
       
    37 using std::cout;
       
    38 using std::endl;
       
    39 
       
    40 #define SUCCESS 1
       
    41 #define FAILURE 0
       
    42 
       
    43 /**
       
    44 Destructor to release all the allocated memory
       
    45 @internalComponent
       
    46 @released
       
    47 */
       
    48 DefFile::~DefFile()
       
    49 {
       
    50 	if(iSymbolList && iSymbolList->size())
       
    51 	{
       
    52 		SymbolList::iterator aItr = iSymbolList->begin();
       
    53 		SymbolList::iterator last = iSymbolList->end();
       
    54 		Symbol *temp;
       
    55 
       
    56 		while(aItr != last)
       
    57 		{
       
    58 			temp = *aItr;
       
    59 			aItr++;
       
    60 			delete temp;
       
    61 		}
       
    62 		iSymbolList->clear();
       
    63 	}
       
    64 	delete iSymbolList;
       
    65 }
       
    66 /**
       
    67 Function to Get File Size.
       
    68 @param fptrDef - File pointer to DEF file
       
    69 @internalComponent
       
    70 @released
       
    71 */
       
    72 int DefFile::GetFileSize(FILE *fptrDef)
       
    73 {
       
    74 	int fileSize,status;
       
    75 
       
    76 	status=fseek(fptrDef, 0, SEEK_END);
       
    77 	if(status!=0)
       
    78 	{
       
    79 		throw FileError(FILEREADERROR,iFileName);
       
    80 	}
       
    81 	fileSize=ftell(fptrDef);
       
    82 	rewind(fptrDef);
       
    83 
       
    84 	return fileSize;
       
    85 
       
    86 }
       
    87 
       
    88 /**
       
    89 Function to Open File and read it in memory.
       
    90 @param defFile - DEF File name
       
    91 @internalComponent
       
    92 @released
       
    93 */
       
    94 char* DefFile::OpenDefFile(char * defFile)
       
    95 {
       
    96 	int fileSize;
       
    97 	char *defFileEntries;
       
    98 	FILE *fptrDef;
       
    99 
       
   100 	iFileName=defFile;
       
   101 	if((fptrDef=fopen(defFile,"rb"))==NULL)
       
   102 	{
       
   103 		throw FileError(FILEOPENERROR,defFile);
       
   104 	}
       
   105 
       
   106 	fileSize=GetFileSize(fptrDef);
       
   107 
       
   108 	if((defFileEntries= new char[fileSize+2]) ==NULL)
       
   109 	{
       
   110 		throw MemoryAllocationError(MEMORYALLOCATIONERROR,defFile);
       
   111 	}
       
   112 
       
   113 	//Getting whole file in memory
       
   114 	if(!fread(defFileEntries, fileSize, 1, fptrDef))
       
   115 	{
       
   116 		throw FileError(FILEREADERROR,defFile);
       
   117 	}
       
   118 
       
   119 	//Adding ENTER at end
       
   120 	*(defFileEntries+fileSize)='\n';
       
   121 	//Adding '\0' at end
       
   122 	*(defFileEntries+fileSize+1)='\0';
       
   123 
       
   124 	fclose(fptrDef);
       
   125 
       
   126 	return defFileEntries;
       
   127 
       
   128 }
       
   129 
       
   130 /**
       
   131 Function to Parse Def File which has been read in buffer.
       
   132 @param defFileEntries - pointer to def file entries which has been read in buffer
       
   133 @internalComponent
       
   134 @released
       
   135 */
       
   136 void DefFile::ParseDefFile(char *defFileEntries)
       
   137 {
       
   138 	iSymbolList = new SymbolList;
       
   139 
       
   140 	int ordinalNo = 0;
       
   141 	int symbolType=SymbolTypeCode;
       
   142 	int PreviousOrdinal=0;
       
   143 	char MultiLineStatement[1024]="";
       
   144 	bool NAMEorLIBRARYallowed=true;
       
   145 	int LineNum = 0;
       
   146 	bool isComment;
       
   147 
       
   148 	char *lineToken;
       
   149 	int aLineLength = 0, width = 0;
       
   150 	unsigned i;
       
   151 	char *ptrEntry,*ptrEntryType;
       
   152 	char entryType[256];
       
   153 	bool entryFlag;
       
   154 
       
   155 
       
   156 	lineToken=strtok(defFileEntries,"\n");
       
   157 	while(lineToken != NULL)
       
   158 	{
       
   159 		symbolType=SymbolTypeCode;
       
   160 		isComment=false;
       
   161 		entryType[0]='\0';
       
   162 		aLineLength = strlen(lineToken);
       
   163 		LineNum++;
       
   164 
       
   165 		if (lineToken == NULL || lineToken[0]==13)
       
   166 		{
       
   167 			lineToken=strtok(NULL,"\n");
       
   168 			continue;
       
   169 		}
       
   170 
       
   171 		// comment lines
       
   172 		if (lineToken[0] == ';')
       
   173 		{
       
   174 			lineToken=strtok(NULL,"\n");
       
   175 			continue;
       
   176 		}
       
   177 
       
   178 		ptrEntry=lineToken;
       
   179 
       
   180 		if((!strstr(lineToken, "NONAME") && ((ptrEntryType=strstr(lineToken, "NAME")) != NULL)) ||
       
   181 			((ptrEntryType=strstr(lineToken, "EXPORTS")) != NULL) ||
       
   182 			((ptrEntryType=strstr(lineToken, "IMPORTS")) != NULL) ||
       
   183 			((ptrEntryType=strstr(lineToken, "SECTIONS")) != NULL) ||
       
   184 			((ptrEntryType=strstr(lineToken, "LIBRARY")) != NULL) ||
       
   185 			((ptrEntryType=strstr(lineToken, "DESCRIPTION")) != NULL)||
       
   186 			((ptrEntryType=strstr(lineToken, "STACKSIZE")) != NULL)||
       
   187 			((ptrEntryType=strstr(lineToken, "VERSION")) != NULL)
       
   188 			)
       
   189 		{
       
   190 			entryFlag=true;
       
   191 
       
   192 			for(i=0; ptrEntry!=ptrEntryType; i++,ptrEntry++)
       
   193 			{
       
   194 				switch(lineToken[i])
       
   195 				{
       
   196 				case ' ':
       
   197 				case '\t':
       
   198 					continue;
       
   199 				default:
       
   200 					entryFlag=false;
       
   201 					break;
       
   202 				}
       
   203 				if(entryFlag==false)
       
   204 					break;
       
   205 			}
       
   206 
       
   207 			if(entryFlag==false && !strcmp(MultiLineStatement,""))
       
   208 			{
       
   209 				throw DEFFileError(UNRECOGNIZEDTOKEN,iFileName,LineNum,lineToken);
       
   210 			}
       
   211 
       
   212 			if(entryFlag==true)
       
   213 			{
       
   214 				switch(ptrEntryType[0])
       
   215 				{
       
   216 				case 'E':
       
   217 				case 'I':
       
   218 				case 'L':
       
   219 				case 'V':
       
   220 					width=7;
       
   221 					break;
       
   222 				case 'S':
       
   223 					if(ptrEntryType[1]=='E')
       
   224 						width=8;
       
   225 					else
       
   226 						width=9;
       
   227 					break;
       
   228 				case 'N':
       
   229 					width=4;
       
   230 					break;
       
   231 				case 'D':
       
   232 					width=11;
       
   233 					break;
       
   234 				}
       
   235 			}
       
   236 
       
   237 			if(entryFlag==true)
       
   238 			{
       
   239   				for(i=i+width; i<strlen(lineToken); i++)
       
   240 				{
       
   241 					switch(lineToken[i])
       
   242 					{
       
   243 					case ' ':
       
   244 					case '\t':
       
   245 						continue;
       
   246 					case '\r':
       
   247 					case '\0':
       
   248 						break;
       
   249 					default:
       
   250 						entryFlag=false;
       
   251 						break;
       
   252 					}
       
   253 
       
   254 					if(entryFlag==false)
       
   255 						break;
       
   256 				}
       
   257 			}
       
   258 
       
   259 			if(entryFlag==false && !strcmp(MultiLineStatement,""))
       
   260 			{
       
   261 				throw DEFFileError(UNRECOGNIZEDTOKEN,iFileName,LineNum,lineToken+i);
       
   262 			}
       
   263 
       
   264 			if(entryFlag==true)
       
   265 			{
       
   266 				strncpy(entryType, ptrEntryType, width);
       
   267 				entryType[width]='\0';
       
   268 
       
   269 				switch(ptrEntryType[0])
       
   270 				{
       
   271 				case 'E':		// check for multi-line sections starting
       
   272 					strcpy(MultiLineStatement, STRUPR(entryType)); // Uppercase token
       
   273 					NAMEorLIBRARYallowed = false;
       
   274 					lineToken = strtok(NULL, "\n" ); // Get the next line
       
   275 					continue;
       
   276 				case 'N':
       
   277 					break;
       
   278 				case 'L':
       
   279 					break;
       
   280 				case 'D':
       
   281 					break;
       
   282 				case 'S':
       
   283 				case 'V':
       
   284 					if(entryType[1]!='E')
       
   285 					{
       
   286 						// set MULTI-LINE statement to OFF
       
   287 						strcpy(MultiLineStatement, STRUPR(entryType)); // Uppercase token
       
   288 						// check single-line statements are specified correctly
       
   289 						// check NAME or LIBRARY statements aren't supplied incorrectly
       
   290 						if (!strcmp(entryType, "NAME") ||
       
   291 							!strcmp(entryType, "LIBRARY")
       
   292 							)
       
   293 						{
       
   294 							if (NAMEorLIBRARYallowed == false)
       
   295 							{
       
   296 								throw DEFFileError(NAMELIBRARYNOTCORRECT,iFileName,LineNum,lineToken);
       
   297 							}
       
   298 							lineToken=strtok(NULL,"\n");
       
   299 							continue;
       
   300 						}
       
   301 						NAMEorLIBRARYallowed = false;
       
   302 						lineToken=strtok(NULL,"\n");
       
   303 						continue;
       
   304 					}
       
   305 					continue;
       
   306 				case 'I':
       
   307 					strcpy(MultiLineStatement, STRUPR(entryType)); // Uppercase token
       
   308 					lineToken = strtok(NULL, "\n" ); // Get the next line
       
   309 					continue;
       
   310 				}
       
   311 			}
       
   312 
       
   313 		}
       
   314 		else
       
   315 		{
       
   316 			if (!strcmp(MultiLineStatement,""))
       
   317 		    {
       
   318 				throw DEFFileError(EXPORTSEXPECTED,iFileName,LineNum,lineToken);
       
   319 			}
       
   320 		}	
       
   321 			
       
   322 		// Get Export entries
       
   323 		if (!strcmp(MultiLineStatement,"EXPORTS"))
       
   324 		{
       
   325 			Symbol aSymbol(NULL, SymbolTypeCode);
       
   326 			if( Tokenize(lineToken, LineNum, aSymbol) )
       
   327 			{
       
   328 				Symbol *newSymbolEntry = new Symbol(aSymbol);
       
   329 				iSymbolList->push_back(newSymbolEntry);
       
   330 
       
   331 				ordinalNo = aSymbol.OrdNum();
       
   332 				//Check for ordinal sequence
       
   333 				if (ordinalNo != PreviousOrdinal+1)
       
   334 		   		{
       
   335 					throw DEFFileError(ORDINALSEQUENCEERROR,iFileName,LineNum,(char*)aSymbol.SymbolName());
       
   336 				}
       
   337 
       
   338 				PreviousOrdinal = ordinalNo;
       
   339 
       
   340 			}
       
   341 			lineToken=strtok(NULL,"\n");
       
   342 			continue;
       
   343 		}
       
   344 		else if(strcmp(MultiLineStatement,"")!=0)//For entry other than exports
       
   345 			lineToken = strtok(NULL, "\n" ); // Get the next line
       
   346 
       
   347 	}//End of while
       
   348 }
       
   349 
       
   350 /**
       
   351 This Function calls LineToken's Tokenize function.
       
   352 @param aTokens   - Input string at the current line number
       
   353 @param aLineNum  - Current line number
       
   354 @param aSymbol   - Symbol to be populated while parsing the line.
       
   355 Return value     - It returns true if a valid def file entry is found.
       
   356 @internalComponent
       
   357 @released
       
   358 */
       
   359 bool DefFile::Tokenize(char* aTokens, int aLineNum, Symbol& aSymbol)
       
   360 {
       
   361 	/*
       
   362 	 * Pattern to match is:
       
   363 	 * START\s*(\S+)\s+@\s*(d+)\s*(NONAME)?\s*(R3UNUSED)?\s*(ABSENT)?\s*(;\s*(.*))END
       
   364 	 */
       
   365 	LineToken aLine(iFileName, aLineNum, aTokens, &aSymbol);
       
   366 	return aLine.Tokenize();
       
   367 }
       
   368 
       
   369 
       
   370 char * DefFilePatterns[] =
       
   371 	{
       
   372 		"NONAME",//index 0
       
   373 		"DATA",
       
   374 		"R3UNUSED",
       
   375 		"ABSENT"
       
   376 	};
       
   377 
       
   378 #define DEF_NONAME		0
       
   379 #define DEF_DATA		1
       
   380 #define DEF_R3UNUSED	2
       
   381 #define DEF_ABSENT		3
       
   382 
       
   383 /**
       
   384 This constructor creates an instance of LineToken class.
       
   385 @param aFileName - Def File Name.
       
   386 @param aLineNum  - Current line number
       
   387 @param aLn       - Input string at the current line number
       
   388 @param aSym      - Symbol to be populated while parsing the line.
       
   389 @internalComponent
       
   390 @released
       
   391 */
       
   392 LineToken::LineToken(char* aFileName, int aLineNum, char *aLn, Symbol* aSym) : \
       
   393 		iLine(aLn) , iSymbol(aSym) , iOffset(0), iState(EInitState),iFileName(aFileName), iLineNum(aLineNum) 
       
   394 {
       
   395 }
       
   396 
       
   397 /**
       
   398 This function tokenizes the line and populates a symbol entry 
       
   399 if there is one.
       
   400 Return Value - True, if the current line has a valid def entry.
       
   401 @internalComponent
       
   402 @released
       
   403 */
       
   404 bool LineToken::Tokenize()
       
   405 {
       
   406 	while (1) 
       
   407 	{
       
   408 		switch( iState )
       
   409 		{
       
   410 		case EFinalState:
       
   411 			return true;
       
   412 		case EInitState:
       
   413 			if( *(iLine + iOffset) == '\0' || 
       
   414 				*(iLine + iOffset) == '\r' || 
       
   415 				*(iLine + iOffset) == '\n')
       
   416 			{
       
   417 				/*
       
   418 				 * Skip empty lines.
       
   419 				 */
       
   420 				return false;
       
   421 			}
       
   422 			else
       
   423 			{
       
   424 				NextToken();
       
   425 			}
       
   426 			break;
       
   427 		default:
       
   428 			NextToken();
       
   429 			break;
       
   430 		}
       
   431 	}
       
   432 	return false;
       
   433 }
       
   434 
       
   435 /**
       
   436 This function parses a line of the def file based on the current 
       
   437 state it is in.
       
   438 @internalComponent
       
   439 @released
       
   440 */
       
   441 void LineToken::NextToken()
       
   442 {
       
   443 	int aCurrentPos = 0;
       
   444 	char *aSymbolName;
       
   445 
       
   446 	switch( iState )
       
   447 	{
       
   448 	case EInitState:
       
   449 		if(IsWhiteSpace((iLine + iOffset), aCurrentPos))
       
   450 		{
       
   451 			IncrOffset(aCurrentPos);
       
   452 		}
       
   453 
       
   454 		if(IsWord(iLine + iOffset, aCurrentPos))
       
   455 		{
       
   456 			SetState(ESymbolName);
       
   457 		}
       
   458 	break;
       
   459 
       
   460 	case ESymbolName:
       
   461 	{
       
   462 		// Get the length of the symbol
       
   463 		IsWord(iLine + iOffset, aCurrentPos);
       
   464 
       
   465 		char *cmt = strchr(iLine + iOffset, ';');
       
   466 		char *aAlias = strchr(iLine + iOffset, '=');
       
   467 
       
   468 		if( aAlias && (!cmt || (aAlias < cmt)) )
       
   469 		{
       
   470 			int aAliasPos = aAlias - (iLine+ iOffset);
       
   471 
       
   472 			//Check if alias name is also supplied, they should be separated 
       
   473 			// by whitespace, i.e., SymbolName=AliasName is valid while, 
       
   474 			// SymbolName =AliasName is invalid.
       
   475 			if( aAliasPos > aCurrentPos)
       
   476 			{
       
   477 				char *aToken = (iLine + iOffset + aCurrentPos);
       
   478 				throw DEFFileError(UNRECOGNIZEDTOKEN, iFileName, iLineNum, aToken);
       
   479 			}
       
   480 
       
   481 			aSymbolName = new char[aAliasPos+1];
       
   482 			strncpy(aSymbolName, iLine + iOffset, aAliasPos);
       
   483 			aSymbolName[aAliasPos] = '\0';
       
   484 			char *aExportName = new char[aCurrentPos - aAliasPos + 1];
       
   485 			strncpy(aExportName, aAlias +1, (aCurrentPos - aAliasPos));
       
   486 			aExportName[(aCurrentPos - aAliasPos)] = '\0';
       
   487 			iSymbol->ExportName(aExportName);
       
   488 		}
       
   489 		else
       
   490 		{
       
   491 			aSymbolName = new char[aCurrentPos+1];
       
   492 			strncpy(aSymbolName, iLine+ iOffset, aCurrentPos);
       
   493 			aSymbolName[aCurrentPos] = '\0';
       
   494 		}
       
   495 		iSymbol->SymbolName(aSymbolName);
       
   496 		
       
   497 		IncrOffset(aCurrentPos);
       
   498 
       
   499 		if(IsWhiteSpace((iLine + iOffset), aCurrentPos))
       
   500 		{
       
   501 			IncrOffset(aCurrentPos);
       
   502 		}
       
   503 		
       
   504 		if(*(iLine+iOffset) == '@')
       
   505 		{
       
   506 			SetState(EAtSymbol);
       
   507 			IncrOffset(1);
       
   508 		}
       
   509 		else
       
   510 		{
       
   511 			/*
       
   512 			 * The first non-whitespace entry in a line is assumed to be the 
       
   513 			 * symbol name and a symbol name might also have a '@' char. Hence
       
   514 			 * there MUST be a whitespace between symbol name and '@'.
       
   515 			 */
       
   516 			throw DEFFileError(ATRATEMISSING,iFileName,iLineNum,(iLine+iOffset));
       
   517 		}
       
   518 	}
       
   519 	break;
       
   520 
       
   521 	case EAtSymbol:
       
   522 		if(IsWhiteSpace((iLine + iOffset), aCurrentPos))
       
   523 		{
       
   524 			IncrOffset(aCurrentPos);
       
   525 		}
       
   526 		
       
   527 		SetState(EOrdinal);
       
   528 		break;
       
   529 	case EOrdinal:
       
   530 	{
       
   531 		if(!IsDigit(iLine+iOffset, aCurrentPos ) )
       
   532 		{
       
   533 			throw DEFFileError(ORDINALNOTANUMBER, iFileName, iLineNum, (iLine+iOffset));
       
   534 		}
       
   535 		char aTmp[32];
       
   536 		strncpy(aTmp, iLine+iOffset, aCurrentPos);
       
   537 		aTmp[aCurrentPos] = '\0';
       
   538 		int aOrdinal = atoi(aTmp);
       
   539 		iSymbol->SetOrdinal(aOrdinal);
       
   540 
       
   541 		IncrOffset(aCurrentPos);
       
   542 
       
   543 		if(IsWhiteSpace((iLine + iOffset), aCurrentPos))
       
   544 		{
       
   545 			IncrOffset(aCurrentPos);
       
   546 		}
       
   547 		SetState(EOptionals);
       
   548 	}
       
   549 	break;
       
   550 
       
   551 	case EOptionals:
       
   552 		{
       
   553 		int aPrevPatternIndex, aPatternIdx = 0;
       
   554 		aPrevPatternIndex = -1;
       
   555 		while (*(iLine + iOffset) != '\n' || *(iLine + iOffset) != '\r')
       
   556 		{
       
   557 			if(IsPattern(iLine+iOffset, aCurrentPos, aPatternIdx) )
       
   558 			{
       
   559 				switch(aPatternIdx)
       
   560 				{
       
   561 				case DEF_NONAME:
       
   562 					break;
       
   563 				case DEF_DATA:
       
   564 					iSymbol->CodeDataType(SymbolTypeData);
       
   565 
       
   566 					IncrOffset(aCurrentPos);
       
   567 					if(IsWhiteSpace((iLine + iOffset), aCurrentPos))
       
   568 					{
       
   569 						IncrOffset(aCurrentPos);
       
   570 					}
       
   571 					if(IsDigit(iLine+iOffset, aCurrentPos ) )
       
   572 					{
       
   573 						char aSymSz[16];
       
   574 						strncpy(aSymSz, (iLine + iOffset), aCurrentPos);
       
   575 						aSymSz[aCurrentPos] = '\0';
       
   576 						iSymbol->SetSymbolSize(atoi(aSymSz));
       
   577 					}
       
   578 					break;
       
   579 				case DEF_R3UNUSED:
       
   580 					iSymbol->R3Unused(true);
       
   581 					break;
       
   582 				case DEF_ABSENT:
       
   583 					iSymbol->SetAbsent(true);
       
   584 					break;
       
   585 				default:
       
   586 					break;
       
   587 				}
       
   588 
       
   589 				/*
       
   590 				 * NONAME , DATA, R3UNUSED and ABSENT, all the 3 are optional. But, if more than
       
   591 				 * one of them appear, they MUST appear in that order. 
       
   592 				 * Else, it is not accepted.
       
   593 				 */
       
   594 				if( aPrevPatternIndex >= aPatternIdx)
       
   595 				{
       
   596 					throw DEFFileError(UNRECOGNIZEDTOKEN, iFileName, iLineNum,(iLine + iOffset));
       
   597 				}
       
   598 				aPrevPatternIndex = aPatternIdx;
       
   599 
       
   600 				IncrOffset(aCurrentPos);
       
   601 				
       
   602 				if(IsWhiteSpace((iLine + iOffset), aCurrentPos))
       
   603 				{
       
   604 					IncrOffset(aCurrentPos);
       
   605 				}
       
   606 			}
       
   607 			else
       
   608 			{
       
   609 				if( *(iLine + iOffset) == ';' )
       
   610 				{
       
   611 					SetState(EComment);
       
   612 					IncrOffset(1);
       
   613 					return;
       
   614 				}
       
   615 				else if( *(iLine + iOffset) == '\0' || 
       
   616 						 *(iLine + iOffset) == '\r' || 
       
   617 						 *(iLine + iOffset) == '\n')
       
   618 				{
       
   619 					SetState(EFinalState);
       
   620 					return;
       
   621 				}
       
   622 				else
       
   623 				{
       
   624 					throw DEFFileError(UNRECOGNIZEDTOKEN, iFileName, iLineNum,(iLine + iOffset));
       
   625 				}
       
   626 			}
       
   627 		}
       
   628 		}
       
   629 	break;
       
   630 
       
   631 	case EComment:
       
   632 	{
       
   633 		if(IsWhiteSpace(iLine + iOffset, aCurrentPos))
       
   634 		{
       
   635 			IncrOffset(aCurrentPos);
       
   636 		}
       
   637 		
       
   638 	
       
   639 		int aLen = strlen(iLine + iOffset);
       
   640 		if( *(iLine + iOffset + aLen - 1 ) == '\n' ||  *(iLine + iOffset + aLen - 1 ) == '\r')
       
   641 			aLen -=1;
       
   642 
       
   643 		char * aComment = new char[ aLen + 1];
       
   644 		strncpy( aComment, iLine + iOffset, aLen);
       
   645 		aComment[aLen] = '\0';
       
   646 
       
   647 		IncrOffset(aLen);
       
   648 
       
   649 		iSymbol->Comment(aComment);
       
   650 		SetState(EFinalState);
       
   651 	}
       
   652 	break;
       
   653 
       
   654 	case EFinalState:
       
   655 		return;
       
   656 	default:
       
   657 		break;	
       
   658 	}
       
   659 }
       
   660 
       
   661 /**
       
   662 This function returns true if the string starts with one
       
   663 of the fixed patterns.
       
   664 It also updates the length  and index of this pattern.
       
   665 @param aChar - Line Token
       
   666 @param aTill - Length of the pattern
       
   667 @param aTill - Index of the pattern
       
   668 Return Value - True, if the string starts with one of the patterns.
       
   669 @internalComponent
       
   670 @released
       
   671 */
       
   672 bool LineToken::IsPattern(char* aStr, int& aTill, int& aIndex)
       
   673 {
       
   674 	int pos = 0;
       
   675 	int aLength;
       
   676 	int size = sizeof(DefFilePatterns)/sizeof(char*);
       
   677 	while(size > pos)
       
   678 	{
       
   679 		aLength = strlen(DefFilePatterns[pos]);
       
   680 		if(!strncmp(aStr, DefFilePatterns[pos], aLength))
       
   681 		{
       
   682 			aTill = aLength;
       
   683 			aIndex = pos;
       
   684 			return true;
       
   685 		}
       
   686 		pos++;
       
   687 	}
       
   688 	return false;
       
   689 }
       
   690 
       
   691 /**
       
   692 This function returns true if the string starts with digits.
       
   693 It also updates the length of this digit string.
       
   694 @param aChar - Line Token
       
   695 @param aTill - Length of the digit string
       
   696 Return Value - True, if the string starts with digit(s)
       
   697 @internalComponent
       
   698 @released
       
   699 */
       
   700 bool LineToken::IsDigit(char *aChar, int &aTill)
       
   701 {
       
   702 	int pos = 0;
       
   703 	if( aChar[pos] - '0' >= 0 &&  aChar[pos] - '0' <= 9)
       
   704 	{
       
   705 		pos++;
       
   706 		while(aChar[pos] - '0' >= 0 &&  aChar[pos] - '0' <= 9)
       
   707 		{
       
   708 			pos++;
       
   709 		}
       
   710 		aTill = pos;
       
   711 		return true;
       
   712 	}
       
   713 	else
       
   714 	{
       
   715 		return false;
       
   716 	}
       
   717 }
       
   718 
       
   719 /**
       
   720 This function returns true if the string starts with white space.
       
   721 It also updates the length of this white string!
       
   722 @param aStr - Line Token
       
   723 @param aTill - Length of the white string
       
   724 Return Value - True, if the string starts with whitespace
       
   725 @internalComponent
       
   726 @released
       
   727 */
       
   728 bool LineToken::IsWhiteSpace(char *aStr, int &aTill)
       
   729 {
       
   730 	int pos = 0;
       
   731 	switch( aStr[pos] )
       
   732 	{
       
   733 	case ' ':
       
   734 	case '\t':
       
   735 		break;
       
   736 	default:
       
   737 		return false;
       
   738 	}
       
   739 
       
   740 	pos++;
       
   741 	while( aStr[pos])
       
   742 	{
       
   743 		switch(aStr[pos])
       
   744 		{
       
   745 			case ' ':
       
   746 			case '\t':
       
   747 				pos++;
       
   748 			break;
       
   749 			default:
       
   750 				aTill = pos;
       
   751 				return true;
       
   752 		}
       
   753 
       
   754 	}
       
   755 	aTill = pos;
       
   756 	return true;
       
   757 }
       
   758 
       
   759 /**
       
   760 This function returns true if the string starts with non-whitespace.
       
   761 It also updates the length of this word.
       
   762 @param aStr  - Line Token
       
   763 @param aTill - Length of the word
       
   764 Return Value - True, if the string starts with non-whitespace chars.
       
   765 It also updates the length of the word.
       
   766 @internalComponent
       
   767 @released
       
   768 */
       
   769 bool LineToken::IsWord(char *aStr, int &aTill)
       
   770 {
       
   771 	int pos = 0;
       
   772 	switch( aStr[pos] )
       
   773 	{
       
   774 	case '\0':
       
   775 	case ' ':
       
   776 	case '\t':
       
   777 	case '\r':
       
   778 	case '\n':
       
   779 		return false;
       
   780 	default:
       
   781 		break;
       
   782 	}
       
   783 
       
   784 	pos++;
       
   785 	while( aStr[pos])
       
   786 	{
       
   787 		switch(aStr[pos])
       
   788 		{
       
   789 			case ' ':
       
   790 			case '\t':
       
   791 			case '\r':
       
   792 			case '\n':
       
   793 				aTill = pos;
       
   794 				return true;
       
   795 			default:
       
   796 				pos++;
       
   797 				break;
       
   798 		}
       
   799 
       
   800 	}
       
   801 	aTill = pos;
       
   802 	return true;
       
   803 }
       
   804 
       
   805 /**
       
   806 This function increments the current offset.
       
   807 @param aOff  - increment by this value
       
   808 @internalComponent
       
   809 @released
       
   810 */
       
   811 void LineToken::IncrOffset(int aOff)
       
   812 { 
       
   813 	iOffset += aOff;
       
   814 }
       
   815 
       
   816 /**
       
   817 This function sets the state of the tokenizer that is parsing 
       
   818 the line.
       
   819 @param aState  - next state
       
   820 @internalComponent
       
   821 @released
       
   822 */
       
   823 void LineToken::SetState(DefStates aState)
       
   824 {
       
   825 	iState = aState;
       
   826 }
       
   827 
       
   828 /**
       
   829 Function to Read def file and get the internal representation in structure.
       
   830 @param defFile - DEF File name
       
   831 @internalComponent
       
   832 @released
       
   833 */
       
   834 SymbolList* DefFile::ReadDefFile(char *defFile)
       
   835 {
       
   836 	char *defFileEntries;
       
   837 
       
   838 	defFileEntries=OpenDefFile(defFile);
       
   839 	ParseDefFile(defFileEntries);
       
   840 
       
   841 	delete [] defFileEntries;//Free the memory which was required to read def file
       
   842 
       
   843 	return iSymbolList;
       
   844 
       
   845 }
       
   846 
       
   847 /**
       
   848 Function to get the internal representation of Def File.
       
   849 @param defFile - DEF File name
       
   850 @internalComponent
       
   851 @released
       
   852 */
       
   853 SymbolList* DefFile::GetSymbolEntryList(char *defFile)
       
   854 {
       
   855 	if(iSymbolList)
       
   856 	{
       
   857 		return iSymbolList;
       
   858 	}
       
   859 	else
       
   860 	{
       
   861 		iSymbolList=ReadDefFile(defFile);
       
   862 		return iSymbolList;
       
   863 	}
       
   864 
       
   865 }
       
   866 
       
   867 /**
       
   868 Function to write DEF file from symbol entry List.
       
   869 @param fileName - Def file name
       
   870 @param newSymbolList - pointer to SymbolList which we get as an input for writing in DEF File
       
   871 @internalComponent
       
   872 @released
       
   873 */
       
   874 void DefFile::WriteDefFile(char *fileName, SymbolList * newSymbolList)
       
   875 {
       
   876 
       
   877 	char ordinal[6];
       
   878 	int newDefEntry=0;
       
   879 	FILE *fptr;
       
   880 
       
   881 	if((fptr=fopen(fileName,"wb"))==NULL)
       
   882 	{
       
   883 		throw FileError(FILEOPENERROR,fileName);
       
   884 	}
       
   885 	else
       
   886 	{
       
   887 		SymbolList::iterator aItr = newSymbolList->begin();
       
   888 		SymbolList::iterator last = newSymbolList->end();
       
   889 		Symbol *aSym;
       
   890 
       
   891 		fputs("EXPORTS",fptr);
       
   892 		fputs("\r\n",fptr);
       
   893 		while( aItr != last)
       
   894 		{
       
   895 			aSym = *aItr;
       
   896 			//Do not write now if its a new entry
       
   897 			if(aSym->GetSymbolStatus()==New)
       
   898 			{
       
   899 				newDefEntry=1;
       
   900 				aItr++;
       
   901 				continue;
       
   902 			}
       
   903 
       
   904 			//Make it comment if its missing def entry
       
   905 			if(aSym->GetSymbolStatus()==Missing)
       
   906 				fputs("; MISSING:",fptr);
       
   907 
       
   908 			fputs("\t",fptr);
       
   909 			if((aSym->ExportName()) && strcmp(aSym->SymbolName(),aSym->ExportName())!=0)
       
   910 			{
       
   911 				fputs(aSym->ExportName(),fptr);
       
   912 				fputs("=",fptr);
       
   913 			}
       
   914 			fputs(aSym->SymbolName(),fptr);
       
   915 			fputs(" @ ",fptr);
       
   916 			sprintf(ordinal,"%d",aSym->OrdNum());
       
   917 			fputs(ordinal,fptr);
       
   918 			fputs(" NONAME",fptr);
       
   919 			if(aSym->CodeDataType()==SymbolTypeData) {
       
   920 				fputs(" DATA",fptr);
       
   921 				fputs(" ",fptr);
       
   922 				char aSymSize[16];
       
   923 				sprintf(aSymSize, "%d", aSym->SymbolSize());
       
   924 				fputs(aSymSize,fptr);
       
   925 			}
       
   926 			if(aSym->R3unused())
       
   927 				fputs(" R3UNUSED",fptr);
       
   928 			if(aSym->Absent())
       
   929 				fputs(" ABSENT",fptr);
       
   930 				
       
   931 			if(aSym->Comment()!=NULL)
       
   932 			{
       
   933 				fputs(" ; ",fptr);
       
   934 				fputs(aSym->Comment(),fptr);
       
   935 			}
       
   936 			fputs("\r\n",fptr);
       
   937 			aItr++;
       
   938 		}
       
   939 
       
   940 		//This is for writing new def entry in DEF File
       
   941 		if(newDefEntry)
       
   942 		{
       
   943 			fputs("; NEW:",fptr);
       
   944 			fputs("\r\n",fptr);
       
   945 			aItr = newSymbolList->begin();
       
   946 			last = newSymbolList->end();
       
   947 
       
   948 			while( aItr != last)
       
   949 			{
       
   950 				aSym = *aItr;
       
   951 				if(aSym->GetSymbolStatus()!=New)
       
   952 				{
       
   953 					aItr++;
       
   954 					continue;
       
   955 				}
       
   956 				fputs("\t",fptr);
       
   957 				if((aSym->ExportName()) && strcmp(aSym->SymbolName(),aSym->ExportName())!=0)
       
   958 				{
       
   959 					fputs(aSym->ExportName(),fptr);
       
   960 					fputs("=",fptr);
       
   961 				}
       
   962 				fputs(aSym->SymbolName(),fptr);
       
   963 				fputs(" @ ",fptr);
       
   964 				sprintf(ordinal,"%d",aSym->OrdNum());
       
   965 				fputs(ordinal,fptr);
       
   966 				fputs(" NONAME",fptr);
       
   967 
       
   968 				if(aSym->CodeDataType()==SymbolTypeData) {
       
   969 					fputs(" DATA",fptr);
       
   970 					fputs(" ",fptr);
       
   971 					char aSymSize[16];
       
   972 					sprintf(aSymSize, "%d", aSym->SymbolSize());
       
   973 					fputs(aSymSize,fptr);
       
   974 				}
       
   975 
       
   976 				if(aSym->R3unused())
       
   977 					fputs(" R3UNUSED",fptr);
       
   978 				if(aSym->Absent())
       
   979 					fputs(" ABSENT",fptr);
       
   980 
       
   981 				if(aSym->Comment()!=NULL)
       
   982 				{
       
   983 					if(aSym->CodeDataType()!=SymbolTypeCode &&
       
   984 						aSym->CodeDataType()!=SymbolTypeData)
       
   985 					{
       
   986 						fputs(" ; ",fptr);
       
   987 						fputs(aSym->Comment(),fptr);
       
   988 					}
       
   989 					else
       
   990 					{
       
   991 						fputs(" ",fptr);
       
   992 						fputs(aSym->Comment(),fptr);
       
   993 					}
       
   994 				}
       
   995 				fputs("\r\n",fptr);
       
   996 				aItr++;
       
   997 			}
       
   998 		}
       
   999 		fputs("\r\n",fptr);
       
  1000 		fclose(fptr);
       
  1001 	}
       
  1002 }