bintools/rcomp/src/main.cpp
changeset 0 044383f39525
child 590 360bd6b35136
equal deleted inserted replaced
-1:000000000000 0:044383f39525
       
     1 /*
       
     2 * Copyright (c) 2000-2009 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 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <assert.h>
       
    20 #include <stdio.h>
       
    21 #include <string.h>
       
    22 
       
    23 #include "unistd.h"
       
    24 
       
    25 #if defined( __MSVCDOTNET__) || defined(__TOOLS2__)
       
    26 #include <iostream>
       
    27 using std::cout;
       
    28 using std::endl;
       
    29 using std::cerr;
       
    30 #else //!__MSVCDOTNET__
       
    31 #ifndef __LINUX__
       
    32 #include <io.h>
       
    33 #endif //!__LINUX__
       
    34 #endif //__MSVCDOTNET__
       
    35 
       
    36 #include "RESOURCE.H"
       
    37 #include "DATATYPE.H"
       
    38 #include "MEM.H"     
       
    39 #include "RCBINSTR.H"
       
    40 #include "NUMVAL.H"  
       
    41 #include "ERRORHAN.H"
       
    42 #include "FILEACC.H" 
       
    43 #include "VERSION.H" 
       
    44 #include "CTABLE.H"  
       
    45 #include "main.h"
       
    46 #include "TOKENS.H"
       
    47 #include "localise.h"
       
    48 #include "qualifar.h"
       
    49 #include "messages.h"
       
    50 
       
    51 extern NameIdMap* pResourceNameIds;
       
    52 extern long CurrentId;
       
    53 
       
    54 void WriteHeaderFile(FILE* aRSG, IndexTable& aIndex)
       
    55 	{
       
    56 	IndexTableIterator next(aIndex);
       
    57 	IndexTableItem * p;
       
    58 	while( ( p = next() ) != NULL)
       
    59 		{
       
    60 		ResourceHeader& r=p->Resource();
       
    61 		if (r.iLabel.Length()>0 && !r.iLocal)
       
    62 			{
       
    63 			r.iLabel.Upper();
       
    64 			if (r.iFormatAsHex)
       
    65 				fprintf(aRSG, "#define %-41s 0x%x\n", r.iLabel.GetAssertedNonEmptyBuffer(), r.iResourceId);
       
    66 			else
       
    67 				fprintf(aRSG, "#define %-41s %d\n", r.iLabel.GetAssertedNonEmptyBuffer(), r.iResourceId);
       
    68 			}
       
    69 		}
       
    70 	}
       
    71 
       
    72 void WriteBitArrayOfResourcesContainingCompressedUnicode(RCBinaryStream& aRSC, const IndexTable& aIndex)
       
    73 	{
       
    74 	IndexTableIterator next(aIndex);
       
    75 	unsigned char bitBuffer = 0;
       
    76 	int numberOfBitsInBuffer = 0;
       
    77 	for (;;)
       
    78 		{
       
    79 		IndexTableItem* const p = next();
       
    80 		if (p == NULL)
       
    81 			{
       
    82 			if (numberOfBitsInBuffer > 0)
       
    83 				{
       
    84 				aRSC.Write(&bitBuffer, 1);
       
    85 				}
       
    86 			break;
       
    87 			}
       
    88 		if (p->Resource().ContainsCompressedUnicode())
       
    89 			{
       
    90 			bitBuffer |= (1 << numberOfBitsInBuffer);
       
    91 			}
       
    92 		++numberOfBitsInBuffer;
       
    93 		if (numberOfBitsInBuffer == 8)
       
    94 			{
       
    95 			aRSC.Write(&bitBuffer, 1);
       
    96 			bitBuffer = 0;
       
    97 			numberOfBitsInBuffer = 0;
       
    98 			}
       
    99 		}
       
   100 	}
       
   101 
       
   102 void WriteBinaryResourceData(RCBinaryStream& aRSC, IndexTable& aIndex, int& aSizeOfLargestResourceWhenUncompressed, const char* aDumpDirectory)
       
   103 	{
       
   104 	IndexTableIterator next(aIndex);
       
   105 	IndexTableItem * p;
       
   106 	int resourceIndex=1;
       
   107 	while( ( p = next() ) != NULL)
       
   108 		{
       
   109 		char* dumpFile=NULL;
       
   110 		if (aDumpDirectory!=NULL)
       
   111 			{
       
   112 			dumpFile=new char[strlen(aDumpDirectory)+20];
       
   113 			strcpy(dumpFile, aDumpDirectory);
       
   114 			char resourceIndexAsString[20];
       
   115 			sprintf(resourceIndexAsString, "%d", resourceIndex);
       
   116 			strcat(dumpFile, resourceIndexAsString);
       
   117 			}
       
   118 		p->SetOffset(aRSC.GetPosition()); // record start of this resource in the index
       
   119 		p->Resource().StreamOut(aRSC, aSizeOfLargestResourceWhenUncompressed, dumpFile); // write out binary form of resource
       
   120 		delete [] dumpFile;
       
   121 		++resourceIndex;
       
   122 		}
       
   123 	}
       
   124 
       
   125 void WriteResourceFile(RCBinaryStream& aRSC, IndexTable& aIndex, bool aThirdUidIsOffset, const char* aDumpDirectory)
       
   126 	{
       
   127 	char flags=0;
       
   128 	if (aThirdUidIsOffset)
       
   129 		{
       
   130 		flags|=0x01;
       
   131 		}
       
   132 	aRSC << flags; // these flags are to be used only by a dictionary-compressing program rather than to be used directly by Bafl when reading non-dictionary-compressed resource files (as output by Rcomp)
       
   133 	const int positionToOverWriteFrom=aRSC.GetPosition();
       
   134 	NumericValue twoByteSizeOfLargestResourceWhenUncompressed(L_WORD);
       
   135 	aRSC << twoByteSizeOfLargestResourceWhenUncompressed;
       
   136 	WriteBitArrayOfResourcesContainingCompressedUnicode(aRSC, aIndex); // simply makes space for the bit-array without writing anything sensible in it (as we don't yet know which resources will contain compressed Unicode)
       
   137 	int sizeOfLargestResourceWhenUncompressed=0;
       
   138 	WriteBinaryResourceData(aRSC, aIndex, sizeOfLargestResourceWhenUncompressed, aDumpDirectory);
       
   139 	aIndex.SetIndexOffset(aRSC.GetPosition());
       
   140 	aRSC << aIndex;
       
   141 	aRSC.SetPosition(positionToOverWriteFrom);
       
   142 	twoByteSizeOfLargestResourceWhenUncompressed=sizeOfLargestResourceWhenUncompressed;
       
   143 	aRSC << twoByteSizeOfLargestResourceWhenUncompressed;
       
   144 	WriteBitArrayOfResourcesContainingCompressedUnicode(aRSC, aIndex); // overwrites the bit array with correct data
       
   145 
       
   146 	if(verbose) 
       
   147 		{
       
   148 		MOFF; cout << aIndex; cout << endl; MON;
       
   149 		}
       
   150 	}
       
   151 
       
   152 void CheckLabels() // checks whether the labels that are used in the input have been declared
       
   153 	{
       
   154 	QualifiedStringArrayIterator nextLabel(pG->UsedIdentifiers);
       
   155 	QualifiedString * pLabel;
       
   156 	while ((pLabel = nextLabel() ) != NULL)
       
   157 		{
       
   158 		bool found = false; // gets set to true if the label in question is declared
       
   159 		StringArrayIterator nextDeclared(pG->AllIdentifiers);
       
   160 		String * pDeclared;
       
   161 		while ( ( (pDeclared = nextDeclared() ) != NULL) && ( ! found ))
       
   162 			{
       
   163 			StringLess stringCompare;
       
   164 			if( !stringCompare(*pDeclared,(*pLabel).GetEntry()) && !stringCompare((*pLabel).GetEntry(),*pDeclared) )
       
   165 				{ // this comparison returns true if the label is the same as the declared label
       
   166 				found = true;
       
   167 				}
       
   168 			}
       
   169 		if( ! found ) // if label hasn't been declared emit warning
       
   170 			{
       
   171 			Message * message = pG->Messages.GetEntry(LT_045);
       
   172 			String fileName = (*pLabel).GetFileName();
       
   173 			int lineNumber = (*pLabel).GetLineNumber();
       
   174 			if(message->GetActivated())
       
   175 				{
       
   176 				String comment = message->GetMessageOutput();
       
   177 				comment += (*pLabel).GetEntry();
       
   178 				ErrorHandler::OutputWholeLine(fileName, lineNumber, comment);
       
   179 				}
       
   180 			}
       
   181 		}
       
   182 	}
       
   183 
       
   184 
       
   185 /*  Tokenize expects a string in the following format:
       
   186  *	  \d{3}(,\d{3})*
       
   187  *  i.e. comma-separated three digit numbers. 
       
   188  *  The string should contain no whitespace.
       
   189  */
       
   190 void Tokenize(String aString)
       
   191 	{
       
   192 	int length = aString.Length();
       
   193 
       
   194 	for(int end=3; end<=length; end+=4)
       
   195 		{
       
   196 		String messageNumber = aString.ExtractSubString(end-3,end-1);
       
   197 		if(messageNumber.IsDecNatural())
       
   198 			{
       
   199 			Message * message = pG->Messages.GetTextEntry(messageNumber);
       
   200 			if(message != NULL)
       
   201 				{
       
   202 				message->SetActivationStatus(false);
       
   203 				}
       
   204 			}
       
   205 		}
       
   206 	}
       
   207 				
       
   208 
       
   209 void OutputHelp()
       
   210 	{
       
   211 	cerr << "Resource compiler version " << version << " (Build " << build << ") (C) 1997-2009 Nokia Corporation." << endl;
       
   212 	cerr << "Usage: rcomp [-vpul] [-force] [-oRSCFile] [-{uid2,uid3}] [-hHeaderFile] [-sSourceFile] [-iBaseInputFileName]" << endl;
       
   213 	cerr << "\tv" << "\tverbose" << endl;
       
   214 	cerr << "\tp" << "\tParser debugging" << endl;
       
   215 	cerr << "\tl" << "\tCheck localisation comments" << endl;
       
   216 	cerr << "\tforce" << "\tEmit localisation warnings even if no localisation tags are present" << endl;
       
   217 	cerr << "\tadd-defaults" << "\tAmend input rss/rpp file to add missing default localisation options" << endl;
       
   218 	cerr << endl;
       
   219 	cerr << "\tu" << "\tGenerate Unicode resource binary" << endl;
       
   220 	cerr << endl;
       
   221 	cerr << "If no source file is specified, the source will be read from standard input." << endl;
       
   222 	cerr << "(-i is used to specify the file given to the preprocessor this " << endl;
       
   223 	cerr << "    name is used in generating debug output.)" << endl;
       
   224 	}
       
   225 
       
   226 
       
   227 
       
   228 GlobalData *pG;
       
   229 GlobalLocalisationData *pGL;
       
   230 String InputBaseName;
       
   231 
       
   232 int main(int argc, char * argv[])
       
   233 	{
       
   234 	cout << "\n"; 
       
   235 	int vParam=0;
       
   236 	bool lParam = false; // used as flag to specify whether checking of localisation comment tags should be performed
       
   237 	bool lForce = false; // used as flag to force localisation output even if there are no localisation comments
       
   238 	bool lAddDefaults = false; // used as flag to add missing default localisation data to input rss/rpp file, this is not the default behaviour
       
   239 	logmemorysetting = 0;
       
   240 	unsigned short	pParam = 0;
       
   241 	String			DataOutputFileName;
       
   242 	String			HeaderOutputFileName;
       
   243 	String			MessageSuppressionList;
       
   244 	String			BasePath;
       
   245 	String			SourceFileName;
       
   246 	FILE *			pSourceFile;
       
   247 	char*			uidsParameter=NULL;
       
   248 	char*			dumpDirectory=NULL;
       
   249 	fpos_t			filePositionIndicator;
       
   250 	int				i;
       
   251 	
       
   252 	char *fullcommand = argv[0];
       
   253 	std::string s(fullcommand);
       
   254 
       
   255 	if(argc<=1)
       
   256 		{
       
   257 		OutputHelp();
       
   258 		exit(-1);
       
   259 		}
       
   260 	else
       
   261 		{
       
   262 		// Look through arguments for ones beginning with '-?'.
       
   263 		for(i = 1; i < argc; i++)
       
   264 			{
       
   265 			if(* argv[i] == '-')
       
   266 				{
       
   267 				char * settings = argv[i] + 1;
       
   268 			
       
   269 				if(strchr(settings, '?') )
       
   270 					{
       
   271 					OutputHelp();
       
   272 					exit(-1);
       
   273 					}
       
   274 				}
       
   275 			}
       
   276 
       
   277 		for(i = 1; i < argc; i++)
       
   278 			{
       
   279 			if(* argv[i] == '-')
       
   280 				{
       
   281 				char * settings = argv[i] + 1;
       
   282 			
       
   283 				if(* settings == 'o' || * settings == 'O')
       
   284 					{
       
   285 					DataOutputFileName = (settings + 1);
       
   286 					continue;
       
   287 					}
       
   288 
       
   289 				if(* settings == 'm' || * settings == 'M')
       
   290 					{
       
   291 					MessageSuppressionList = (settings + 1);
       
   292 					continue;
       
   293 					}
       
   294 					
       
   295 				if(* settings == 'h' || * settings == 'H')
       
   296 					{
       
   297 					HeaderOutputFileName = (settings + 1);
       
   298 					continue;
       
   299 					}
       
   300 
       
   301 				if(* settings == 'i' || * settings == 'I')
       
   302 					{
       
   303 					InputBaseName = (settings + 1);
       
   304 					String DriveAndDirectory = FileAccess::GetDriveAndDirectory(InputBaseName);
       
   305 					BasePath = FileAccess::FullPath(DriveAndDirectory);
       
   306 					continue;
       
   307 					}
       
   308 
       
   309 				if(* settings == 's' || * settings == 'S')
       
   310 					{
       
   311 					SourceFileName = (settings + 1);
       
   312 					continue;
       
   313 					}
       
   314 
       
   315 				if(* settings == '{')
       
   316 					{
       
   317 					uidsParameter = settings + 1;
       
   318 					char* temp = strchr(uidsParameter, ',');
       
   319 					if ((temp == NULL) || (temp == uidsParameter) || (strchr(temp + 1, ',') != NULL)) // check that there is *one* comma in this parameter (no more and no less), and that it is not the first thing immediately after the '{'
       
   320 						{
       
   321 						OutputHelp();
       
   322 						exit(-1);
       
   323 						}
       
   324 					*temp = ' ';
       
   325 					temp = strchr(uidsParameter, '}');
       
   326 					if ((temp == NULL) || (temp[1] != '\0'))
       
   327 						{
       
   328 						OutputHelp();
       
   329 						exit(-1);
       
   330 						}
       
   331 					*temp = ' ';
       
   332 					continue;
       
   333 					}
       
   334 
       
   335 				if(* settings == ':')
       
   336 					{
       
   337 					dumpDirectory=settings+1;
       
   338 					continue;
       
   339 					}
       
   340 
       
   341 				if(strchr(settings, 'u') || strchr(settings, 'U') )
       
   342 					{
       
   343 					SourceCharacterSet = String::CP1252;
       
   344 					TargetCharacterSet = String::Unicode;
       
   345 					}
       
   346 
       
   347 				if(strchr(settings, 'v') || strchr(settings, 'V') )
       
   348 					vParam = 1;
       
   349 				if(strchr(settings, 'p') || strchr(settings, 'P') )
       
   350 					pParam = 1;
       
   351 				if(strchr(settings, 'l') || strchr(settings, 'L') )
       
   352 					lParam = true;
       
   353 				if(strchr(settings, 'f') || strchr(settings, 'F') )
       
   354 					lForce = true;
       
   355 				if(strchr(settings, 'a') || strchr(settings, 'A') )
       
   356 					lAddDefaults = true;
       
   357 				}
       
   358 			}
       
   359 		}
       
   360 	if(SourceFileName.Length() == 0)
       
   361 		{
       
   362 		pSourceFile = stdin;
       
   363 		}
       
   364 	else 
       
   365 		{
       
   366 		if((pSourceFile = fopen(SourceFileName.GetAssertedNonEmptyBuffer(), "r") ) == NULL)
       
   367 			{
       
   368 			cerr << "Failed to open " << SourceFileName << endl;
       
   369 			exit(-2);
       
   370 			}
       
   371 		}
       
   372 	//Searchig for BOM signature which if found will be ignored
       
   373 
       
   374 	unsigned char buffer[3];
       
   375 	fread( buffer, sizeof( char ), 3, pSourceFile);
       
   376 	
       
   377 	if((buffer[0]!=239) && (buffer[1]!=187) && (buffer[2]!=191))
       
   378 		{
       
   379 		// BOM not found. Set the file-position indicator to 0
       
   380 		filePositionIndicator = fpos_t();
       
   381 		if(fsetpos(pSourceFile, &filePositionIndicator) !=0)
       
   382 			{
       
   383 			perror("fsetpos error");
       
   384 			} 
       
   385 		}	
       
   386 	verbose = vParam;
       
   387 
       
   388 	pG = new GlobalData;
       
   389 	if (pG==NULL)
       
   390 		exit(-4);
       
   391 	
       
   392 	Tokenize(MessageSuppressionList);
       
   393 
       
   394 	pGL = new GlobalLocalisationData;
       
   395 	if(pG==NULL)
       
   396 		exit(-4);
       
   397 
       
   398 	pG->WarningMultiExplained = false;
       
   399 	pG->FileLineHandler.SetPath(BasePath);
       
   400 	
       
   401 	#ifdef __TOOLS2__
       
   402 	pG->FileLineHandler.SetBase(SourceFileName,0);
       
   403 	#endif
       
   404 	
       
   405 	int ret=ParseSourceFile(pSourceFile, pParam);
       
   406 	fclose(pSourceFile);
       
   407 	
       
   408 	pGL->StoreFinalComment(); // final comment not stored during running of lex and yacc
       
   409 	if(lParam && (pGL->LocalisationCommentsExist() || lForce))
       
   410 		{
       
   411 		pGL->AnalyseLocalisationData();
       
   412 		pGL->PrintLocalisationWarnings();
       
   413 		if(lAddDefaults)
       
   414 			{
       
   415 			// only add deafult localisation values to rpp/rss file if the option has been set on the command line
       
   416 			if(verbose)
       
   417 				{
       
   418 				cout << "* Reparsing source file and adding any missing default localisation comments" << endl;
       
   419 				}
       
   420 			pGL->OutputLocalisedFile(SourceFileName);
       
   421 			}
       
   422 		}
       
   423 	if (ret != 0) 
       
   424 		{
       
   425 		cerr << "RCOMP failed with code " << ret << endl;
       
   426 		exit(ret);
       
   427 		}
       
   428 	// A successful parse, now generate the output files
       
   429 
       
   430 	CheckLabels(); // check that all labels are declared and emit suitable warnings if not
       
   431 
       
   432 	if(DataOutputFileName.Length() != 0)
       
   433 		{
       
   434 
       
   435 
       
   436 #ifdef __LINUX__
       
   437 
       
   438 		std::string totalpath(s.substr( 0, s.rfind("/")+1 ));
       
   439 		const char* uidTool = "uidcrc";
       
   440 
       
   441 #else
       
   442 		std::string totalpath(s.substr( 0, s.rfind("\\")+1 ));
       
   443 		const char* uidTool = "uidcrc.exe";
       
   444 
       
   445 #endif
       
   446 
       
   447 		// Calls the uidcrc tool with the full path to where RCOMP resides in
       
   448 		std::string uidpath(uidTool);
       
   449 		totalpath += uidpath;
       
   450 		
       
   451 		// Find and replace all occurences of \ with /
       
   452 		std::string searchString( "\\" ); 
       
   453 		std::string replaceString( "/" );
       
   454  		std::string::size_type pos = 0;
       
   455 	    	while ( (pos = totalpath.find("\\", pos)) != std::string::npos ) {
       
   456         		totalpath.replace( pos, searchString.size(), replaceString );
       
   457 		        pos++;
       
   458 		    }
       
   459 			
       
   460 		const char *uidcrcTool = totalpath.c_str();
       
   461 
       
   462 		bool thirdUidIsOffset=true;
       
   463 		
       
   464 		char uidcrcUIDs[3][100];
       
   465 		strcpy (uidcrcUIDs[0], "0x101f4a6b");
       
   466 
       
   467 		if (uidsParameter)
       
   468 			{
       
   469 			// Command line argument takes precedence 
       
   470 			
       
   471 			strcpy (uidcrcUIDs[1], strtok (uidsParameter, " "));
       
   472 			strcpy (uidcrcUIDs[2], strtok (NULL, " "));
       
   473  
       
   474 			char* const temp = strchr(uidcrcUIDs[2], '*');		
       
   475 			if (temp == NULL)
       
   476 				{
       
   477 				thirdUidIsOffset=false;
       
   478 				}
       
   479 			}
       
   480 		else
       
   481 			{
       
   482 			// otherwise use values supplied in source
       
   483 
       
   484 			extern unsigned long Uid2;
       
   485 			extern unsigned long Uid3;
       
   486 			sprintf(uidcrcUIDs[1], "0x%08lx", Uid2);
       
   487 			if (Uid3 != 0)
       
   488 				{
       
   489 				sprintf(uidcrcUIDs[2], "0x%08lx", Uid3);
       
   490 				thirdUidIsOffset=false;
       
   491 				}
       
   492 			}
       
   493 
       
   494 
       
   495 		if (thirdUidIsOffset)
       
   496 			{
       
   497 			const unsigned int idOfAnyResource = CurrentId; // *must* be unsigned so that when we right-shift it, the top bit doesn't get propagated if its set (i.e. "negative")
       
   498 			sprintf(uidcrcUIDs[2], "0x%08x", idOfAnyResource >> 12); // use the 20 bits derived from the resource file's NAME as the 3rd UID
       
   499 			}
       
   500 
       
   501 		if (verbose)
       
   502 			{
       
   503 			MOFF; cout << uidcrcTool << " " << uidcrcUIDs[0] << " " << uidcrcUIDs[1] << " " << uidcrcUIDs[2] << " " << DataOutputFileName.GetAssertedNonEmptyBuffer(); cout << endl; MON;
       
   504 			}
       
   505 
       
   506 #ifndef __LINUX__
       
   507 		const int error = _spawnlp (_P_WAIT,
       
   508 									uidcrcTool,
       
   509 									uidcrcTool,
       
   510 									uidcrcUIDs[0],
       
   511 									uidcrcUIDs[1],
       
   512 									uidcrcUIDs[2],
       
   513 									DataOutputFileName.GetAssertedNonEmptyBuffer(),
       
   514 									NULL);
       
   515 #else
       
   516 		char uidcrc_params[256];
       
   517 		const int ret = snprintf(uidcrc_params,
       
   518 					 sizeof(uidcrc_params),
       
   519 					 "%s %s %s %s %s",
       
   520 					 uidcrcTool,
       
   521 					 uidcrcUIDs[0],
       
   522 					 uidcrcUIDs[1],
       
   523 					 uidcrcUIDs[2],
       
   524 					 DataOutputFileName.GetBuffer());
       
   525 		if(ret <= 0) {
       
   526 			cerr << "Failed to write UIDs to " << DataOutputFileName << endl;
       
   527 			exit(ret);
       
   528 		}
       
   529 		const int error = system(uidcrc_params);
       
   530 #endif //__LINUX__
       
   531 
       
   532 		if(error != 0)
       
   533 			{
       
   534 			cerr << "Failed to write UIDs to " << DataOutputFileName << endl;
       
   535 			exit(error);
       
   536 			}
       
   537 		RCBinaryStream RSCStream;
       
   538 		RSCStream.OpenForAppend(DataOutputFileName);
       
   539 		if(! RSCStream.IsOpen())
       
   540 			{
       
   541 			cerr << "Failed to open " << DataOutputFileName << endl;
       
   542 			exit(-2);
       
   543 			}
       
   544 		WriteResourceFile(RSCStream, pG->Index, thirdUidIsOffset, dumpDirectory);
       
   545 		}
       
   546 	
       
   547 	if(HeaderOutputFileName.Length() != 0)
       
   548 		{
       
   549 		FILE* RSG;
       
   550 		RSG = fopen(HeaderOutputFileName.GetAssertedNonEmptyBuffer(), "w");
       
   551 		if(RSG==NULL)
       
   552 			{
       
   553 			cerr << "Failed to open " << HeaderOutputFileName << endl;
       
   554 			exit(-2);
       
   555 			}
       
   556 		WriteHeaderFile(RSG, pG->Index);
       
   557 		fclose(RSG);
       
   558 		}
       
   559 
       
   560 	delete pG;
       
   561 	delete pGL;
       
   562 
       
   563 	return 0;
       
   564 	}
       
   565 
       
   566 
       
   567 
       
   568