# HG changeset patch # User jjkang # Date 1277794374 -28800 # Node ID 30b30f9da0b71bf7b823e13895ef393d6f1d37dd # Parent 122d2b873fd14c8dabd94717326db60af79f5268 Add ..\dev\.. to path diff -r 122d2b873fd1 -r 30b30f9da0b7 bintools/checklib/group/checklib.mmp --- a/bintools/checklib/group/checklib.mmp Fri Jun 25 20:58:33 2010 +0800 +++ b/bintools/checklib/group/checklib.mmp Tue Jun 29 14:52:54 2010 +0800 @@ -20,6 +20,7 @@ userinclude .. userinclude ../object/coff userinclude ../.. +systeminclude ../../elftools/inc sourcepath .. diff -r 122d2b873fd1 -r 30b30f9da0b7 bintools/checklib/group/checklib.mrp --- a/bintools/checklib/group/checklib.mrp Fri Jun 25 20:58:33 2010 +0800 +++ b/bintools/checklib/group/checklib.mrp Tue Jun 29 14:52:54 2010 +0800 @@ -1,8 +1,8 @@ component dev_build_bintools_checklib -source /src/tools/dev/build/bintools/checklib -exports /src/tools/dev/build/bintools/checklib/group -binary /src/tools/dev/build/bintools/checklib/group all +source /src/tools/build/bintools/checklib +exports /src/tools/build/bintools/checklib/group +binary /src/tools/build/bintools/checklib/group all notes_source release.txt diff -r 122d2b873fd1 -r 30b30f9da0b7 bintools/checklib/group/release.txt --- a/bintools/checklib/group/release.txt Fri Jun 25 20:58:33 2010 +0800 +++ b/bintools/checklib/group/release.txt Tue Jun 29 14:52:54 2010 +0800 @@ -3,3 +3,8 @@ NOTESRC_RELEASE_REASON Checklib Release + +version ?? +=============== +Released by Zheng Shen, 22/02/2010 + 1) DPDEF144562 Build Tools cannot be built in Linux diff -r 122d2b873fd1 -r 30b30f9da0b7 bintools/checklib/object/elf/elf_file_header.h --- a/bintools/checklib/object/elf/elf_file_header.h Fri Jun 25 20:58:33 2010 +0800 +++ b/bintools/checklib/object/elf/elf_file_header.h Tue Jun 29 14:52:54 2010 +0800 @@ -16,7 +16,7 @@ #ifndef ELF_FILE_HEADER_H #define ELF_FILE_HEADER_H -#include "elftools/inc/elfdefs.h" +#include #include diff -r 122d2b873fd1 -r 30b30f9da0b7 bintools/checklib/object/elf/elf_section_header.h --- a/bintools/checklib/object/elf/elf_section_header.h Fri Jun 25 20:58:33 2010 +0800 +++ b/bintools/checklib/object/elf/elf_section_header.h Tue Jun 29 14:52:54 2010 +0800 @@ -16,7 +16,7 @@ #ifndef ELF_SECTION_HEADER_H #define ELF_SECTION_HEADER_H -#include "elftools/inc/elfdefs.h" +#include #include namespace elf diff -r 122d2b873fd1 -r 30b30f9da0b7 bintools/checklib/object/elf/elf_symbol.h --- a/bintools/checklib/object/elf/elf_symbol.h Fri Jun 25 20:58:33 2010 +0800 +++ b/bintools/checklib/object/elf/elf_symbol.h Tue Jun 29 14:52:54 2010 +0800 @@ -16,7 +16,7 @@ #ifndef ELF_SYMBOL_H #define ELF_SYMBOL_H -#include "elftools/inc/elfdefs.h" +#include #include diff -r 122d2b873fd1 -r 30b30f9da0b7 bintools/checklib/object/object.h --- a/bintools/checklib/object/object.h Fri Jun 25 20:58:33 2010 +0800 +++ b/bintools/checklib/object/object.h Tue Jun 29 14:52:54 2010 +0800 @@ -12,15 +12,10 @@ // // Description: // Classes for interpreting a memory area as an ELF or COFF object. -// -// +// // Object_factory -----------------> Object -// ^ -// | -// +------+------+ -// | | -// -// Elf_object Coff_object +// Elf_object Coff_object +// // #ifndef OBJECT_H diff -r 122d2b873fd1 -r 30b30f9da0b7 bintools/elftools/def2dll.pl --- a/bintools/elftools/def2dll.pl Fri Jun 25 20:58:33 2010 +0800 +++ b/bintools/elftools/def2dll.pl Tue Jun 29 14:52:54 2010 +0800 @@ -33,6 +33,11 @@ } } +# Version +my $MajorVersion = 1; +my $MinorVersion = 1; +my $PatchVersion = 0; + use lib $PerlLibPath; use Defutl; @@ -66,6 +71,14 @@ my $interworking = "${oP}apcs /nointer"; $interworking = "${oP}apcs /inter" if ($interworkingp); +my $gDelim; +if ($^O eq "MSWin32") { + $gDelim = '\\'; +} +else { + $gDelim = '/'; +} + my @objectFiles; &main; @@ -91,7 +104,7 @@ sub usage( ) { print "\n"; - print "DEF2DLL -Creates binary objects used to implement the Symbian OS DLL model\n"; + print "DEF2DLL -Creates binary objects used to implement the Symbian OS DLL model v$MajorVersion.$MinorVersion.$PatchVersion\n"; print "\n"; print "Usage: def2dll --deffile= [--path=] [--bldpath=] [--import=] [--linkas=] [--inter] [--export=] [--sym_name_lkup]\n"; @@ -103,7 +116,7 @@ print "\t--linkas= : linkas to file name specified\n"; print "\t--inter : enables interworking on ARM and THUMB\n"; print "\t--export= : export to filename\n"; - print "\t--sym_name_lkup : symbol name ordinal number lookupç\n"; + print "\t--sym_name_lkup : symbol name ordinal number lookup\n"; print "\n"; exit 1; } @@ -148,8 +161,8 @@ my $numkeys = keys %symbolIndexMap; my $failed = 0; - open EXPFILE, ">$path\\$expFile.s" or - die "Error: can't create $path\\$expFile.s\n"; + open EXPFILE, ">$path$gDelim$expFile.s" or + die "Error: can't create $path$gDelim$expFile.s\n"; print EXPFILE "\tEXPORT __DLL_Export_Table__\n\n"; print EXPFILE "\tEXPORT |DLL\#\#ExportTable|\n\n"; @@ -204,9 +217,9 @@ print EXPFILE "\tEND"; close EXPFILE; - $failed = system "armasm $floatingpointmodel $interworking -o $path\\$expFile.exp $path\\$expFile.s"; - unlink ("$path\\$expFile.s") unless $failed; - die "Error: cant create $path\\$expFile.exp\n" if $failed; + $failed = system "armasm $floatingpointmodel $interworking -o $path$gDelim$expFile.exp $path$gDelim$expFile.s"; + unlink ("$path$gDelim$expFile.s") unless $failed; + die "Error: cant create $path$gDelim$expFile.exp\n" if $failed; } my %DataSymbols = (); @@ -216,8 +229,8 @@ my ($bldpath, $dllName) = @_; my $FileName = "VtblExports"; - open VTBLFILE, ">$bldpath\\$FileName.s" or - die "Error: can't create $bldpath\\$FileName.s\n"; + open VTBLFILE, ">$bldpath$gDelim$FileName.s" or + die "Error: can't create $bldpath$gDelim$FileName.s\n"; print VTBLFILE "\tAREA |.directive|, NOALLOC, READONLY, ALIGN=2\n"; printf VTBLFILE "\tDCB \"\#\\#\\n\"\n"; @@ -233,23 +246,23 @@ print VTBLFILE "\tEND"; close VTBLFILE; - my $failed = system "armasm $floatingpointmodel $interworking -o $bldpath\\$FileName.o $bldpath\\$FileName.s"; - unlink ("$bldpath\\$FileName.s"); - die "Error: cant create $bldpath\\$FileName.o\n" if $failed; - push @objectFiles, "$bldpath\\$FileName.o"; + my $failed = system "armasm $floatingpointmodel $interworking -o $bldpath$gDelim$FileName.o $bldpath$gDelim$FileName.s"; + unlink ("$bldpath$gDelim$FileName.s"); + die "Error: cant create $bldpath$gDelim$FileName.o\n" if $failed; + push @objectFiles, "$bldpath$gDelim$FileName.o"; } sub genLibFile ($$$$) { my ($path, $bldpath, $libFile, $dllName) = @_; - my $tempFileName = "$bldpath\\$compName"; - my $viaFileName = sprintf("$bldpath\\_t%x_via_.txt", time); + my $tempFileName = "$bldpath$gDelim$compName"; + my $viaFileName = sprintf("$bldpath${gDelim}_t%x_via_.txt", time); my $keyz = keys %symbolIndexMap; my $failed = 0; my $key; if ($keyz > 0) { - open STUBGEN, "|$ENV{'EPOCROOT'}/epoc32/tools/genstubs" if $exports; + open STUBGEN, "|genstubs" if $exports; foreach $key (sort keys %symbolIndexMap) { my $symbol = $symbolIndexMap{$key}; my $stubFileName = "$tempFileName-$key"; @@ -263,7 +276,7 @@ genVtblExportFile($bldpath, $dllName); } else { # create dummy stub so armar creates a .lib for us - open STUBGEN, "|$ENV{'EPOCROOT'}/epoc32/tools/genstubs"; + open STUBGEN, "|genstubs"; print STUBGEN "$tempFileName-stub.o $tempFileName##stub $dllName##dummy\n"; push @objectFiles, "$tempFileName-stub.o"; } @@ -272,7 +285,7 @@ open VIAFILE, ">$viaFileName" or die "Error: can't create VIA fie $viaFileName\n"; - print VIAFILE "${oP}create \"$path\\$libFile\"\n"; + print VIAFILE "${oP}create \"$path$gDelim$libFile\"\n"; my $objectFile; foreach $objectFile (@objectFiles) { print VIAFILE "\"$objectFile\"\n"; @@ -282,7 +295,7 @@ $failed = system( "armar ${oP}via $viaFileName"); push @objectFiles, $viaFileName; unlink @objectFiles; - die "Error: can't create $path\\$libFile\n" if $failed; + die "Error: can't create $path$gDelim$libFile\n" if $failed; } __END__ diff -r 122d2b873fd1 -r 30b30f9da0b7 bintools/elftools/elftran/elf_dlld.cpp --- a/bintools/elftools/elftran/elf_dlld.cpp Fri Jun 25 20:58:33 2010 +0800 +++ b/bintools/elftools/elftran/elf_dlld.cpp Tue Jun 29 14:52:54 2010 +0800 @@ -1,954 +1,928 @@ -/* -* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of the License "Eclipse Public License v1.0" -* which accompanies this distribution, and is available -* at the URL "http://www.eclipse.org/legal/epl-v10.html". -* -* Initial Contributors: -* Nokia Corporation - initial contribution. -* -* Contributors: -* -* Description: -* -*/ - - - -#include -#include -#include -#include -#include "elfdll.h" -#include "elffile.h" -#include -#include - -ELFFile::ELFDllData::ELFDllData(ELFFile * f) - : - iElfFile(f), - - iDynStrTab(0), - iDynStrTabSize(0), - iDynSymTab(0), - - iSymSize(0), - iRela(0), - iRelaSz(0), - iRelaEnt(0), - - iRel(0), - iRelSz(0), - iRelEnt(0), - - iHashTable(0), - - iNamedExportSymbolHead(0), - iNamedExportCount(0), - - iSymStringTableSize(0), - iStringNameOffset(0), - - iDepRecords(0), - iDepRecordsTail(0), - - iNeededDllNames(0), - iNeededDllNamesTail(0), - - iOrdZeroRec(0), - - iNamedLookupEnabled(0), - - iDllHead(0), - iDllTail(0), - - iNumberOfImports(0), - iNumberOfExports(0), - iNumberOfImportDlls(0), - - iStringTableSize(0), - - iNumberOfRelocs(0), - iNumberOfCodeRelocs(0), - iNumberOfDataRelocs(0) - { - } - -ELFFile::ELFDllData::~ELFDllData() - { - delete iOrdZeroRec; - delete iDepRecords; - delete iNeededDllNames; - } - -TBool ELFFile::ELFDllData::Init() - { - // process imported symbols - // There will be at least one relocation (assumed to be Elf32_Rel) for each such symbol. - // S iterate over relocations looking for DLL symbols and add them to the record of - // of import info. - TInt nrelocs = iRelSz/iRelEnt; - TInt SrcSegIdx = -1; - TInt errors = 0; - - for (TInt idx = 0; idx < nrelocs; idx++) - { - Elf32_Rel * rel = &iRel[idx]; - TUint relType = ELF32_R_TYPE(rel->r_info); - - if (relType == R_ARM_ABS32) - { - TInt symIdx = ELF32_R_SYM(rel->r_info); - Elf32_Sym * sym = &iDynSymTab[symIdx]; - DllSymbol * dllSym = DllSymbolP(sym); - if (dllSym) - { - dllSym->iRel = rel; - dllSym->iSegment = iElfFile->GetSegment(SrcSegIdx); - if (!AddSymbol(dllSym)) return EFalse; - } - else errors++; - } - else if (relType == R_ARM_RABS32) - { - iNumberOfRelocs++; - if (iElfFile->CodeSegmentP(SrcSegIdx)) iNumberOfCodeRelocs++; - else iNumberOfDataRelocs++; - } - else if (relType == R_ARM_RBASE) - { - SrcSegIdx = ELF32_R_SYM(rel->r_info); - if (SrcSegIdx) SrcSegIdx--; - } - else - { - // Gives error with all other Relocation types.. - TInt symIdx = ELF32_R_SYM(rel->r_info); - Elf32_Sym * s = &iDynSymTab[symIdx]; - char * symName = ELFADDR(char,iDynStrTab,s->st_name); - Print(EPeError, "Unresolved symbol: %s\n", symName); - errors++; - } - } - // Set up export info - if (InitExportInfo()) - { - TText * sym = (TText *)"_E32Startup"; - // If _E32Startup is defined then this is not a DLL - iImageIsDll = !iElfFile->SymbolPresent(sym); - } - if (errors > 0) return EFalse; - return ETrue; - } - -TBool ELFFile::ELFDllData::ParseDllSymbol(Elf32_Sym * s, char *& dll, TUint& len, TInt& ord) - { - char * sym = ELFADDR(char,iDynStrTab,s->st_name); - if (!strncmp(sym, DLLSYMPREFIX, strlen(DLLSYMPREFIX))) - { - dll = sym + strlen(DLLSYMPREFIX); - TUint lim = strlen(dll); - TUint index = strcspn(dll, DLLSYMPREFIX0); - if ((index + strlen(DLLSYMSUFFIX)) < lim) - { - len = index; - char * dllSuffix = dll+index; - char * match = DLLSYMSUFFIX; - int suflen = strlen(DLLSYMSUFFIX); - if (!strncmp(dllSuffix, match, suflen)) - { - char * ordString = dll+index+suflen; - char * final; - TUint X = strtoul(ordString, &final, ORDBASE); - if (ordString != final) - { - ord = (TInt)X; - return ETrue; - } - - } - } - } - dll = 0; - len = 0; - ord = -1; - return EFalse; - } - -ELFFile::ELFDllData::DllSymbol * ELFFile::ELFDllData::DllSymbolP(Elf32_Sym * s) - { - char * dllName; - TUint nameLen; - TInt symOrd; - if (ParseDllSymbol(s, dllName, nameLen, symOrd)) - { - DllSymbol * ds = new DllSymbol(dllName, nameLen, symOrd); - if (ds) return ds; - Print(EPeError, "Out of memory.\n"); - return NULL; - } - // If we get here its not a valid 'dll symbol' and so it is an unresolved symbol - char * sym = ELFADDR(char,iDynStrTab,s->st_name); - Print(EPeError, "Unresolved symbol: %s\n", sym); - return NULL; - } - -TBool ELFFile::ELFDllData::AddSymbol(ELFFile::ELFDllData::DllSymbol * s) - { - DllRec * aDll = NULL; - - for (DllRec * r = iDllHead; r != NULL; r = r->iNext) - { - if (!strncmp(s->iDll, r->iName, s->iLen)) - { - aDll = r; - break; - } - } - if (aDll) - { - iNumberOfImports++; - aDll->AddSymbol(s); - return ETrue; - } - else - { - aDll = new DllRec(s->iDll, s->iLen, s); - if (aDll) - { - if (!iDllHead) - { - iDllHead = iDllTail = aDll; - } - else - { - iDllTail->iNext = aDll; - iDllTail = aDll; - } - iStringTableSize += (s->iLen + 1); - iNumberOfImportDlls++; - iNumberOfImports++; - return ETrue; - } - else - { - Print(EPeError, "Out of memory.\n"); - return EFalse; - } - } - } - -void ELFFile::ELFDllData::DllRec::AddSymbol(ELFFile::ELFDllData::DllSymbol * s) - { - nImports++; - iTail->iNext = s; - iTail = s; - } - -static unsigned long elf_hash(const unsigned char *name) - { - unsigned long h, g; - for (h = 0; *name != 0; ++name) - { - h = (h << 4) + *name; - g = h & 0xf0000000; - if (g != 0) h ^= g >> 24; - h &= ~g; - } - return h; - } - -Elf32_Word ELFFile::ELFDllData::FindSymbolIndex(TText * s) - { - TUint h = elf_hash(s); - TUint nb = iHashTable[0].nBuckets; - TUint probe = h%nb; - Elf32_Sword * bucket = ELFADDR(Elf32_Sword, iHashTable, sizeof(Elf32_HashTable)); - Elf32_Sword * chain = ELFADDR(Elf32_Sword, bucket, nb * sizeof(Elf32_Sword)); - Elf32_Sword idx = bucket[probe]; - - do - { - if (!strcmp(ELFADDR(char, iDynStrTab, iDynSymTab[idx].st_name), (char *)s)) return idx; - idx = chain[idx]; - } while (idx > 0); - if (idx == 0) idx = -1; - return idx; - } - -TBool ELFFile::ELFDllData::InitExportInfo() - { - memset(&iSymInfoHdr, 0, sizeof(iSymInfoHdr)); - TText * exp = (TText *)EXPORTTABLENAME; - if ( int(iExportTableSymIdx = FindSymbolIndex(exp)) != -1 ) - { - TText * exps = (TText *)EXPORTTABLESIZENAME; - iExportTableSizeSymIdx = FindSymbolIndex(exps); - //TUint offset = iDynSymTab[iExportTableSizeSymIdx].st_value - (TUint)code; - Elf32_Word * pNumberOfExports = iElfFile->CodePtrFromAddr(iDynSymTab[iExportTableSizeSymIdx].st_value); - iNumberOfExports = * pNumberOfExports; - iImageIsDll = ETrue; - return ETrue; - } - else iImageIsDll = EFalse; - return EFalse; - } - -TInt ELFFile::ELFDllData::NumberOfImports(void) - { - return iNumberOfImports; - } - -TInt ELFFile::ELFDllData::NumberOfExports(void) - { - return iNumberOfExports; - } - -TInt ELFFile::ELFDllData::NumberOfImportDlls(void) - { - return iNumberOfImportDlls; - } - -TInt ELFFile::ELFDllData::NumberOfRelocs() - { - return iNumberOfRelocs; - } - -char * ELFFile::ELFDllData::CreateImportSection(TInt &aSize) - { - if (!iNumberOfImports) - { - aSize = 0; - return 0; - } - - TInt byteSize = sizeof(E32ImportSection) + - (sizeof(E32ImportBlock) * iNumberOfImportDlls) + - (sizeof(TUint) * iNumberOfImports) + - iStringTableSize; - if(iNamedLookupEnabled) - { - // 0th ordinal of each DLL imported from. - byteSize += (sizeof(TUint) * iNumberOfImportDlls); - } - char * newSection = new char[byteSize]; - - if (!newSection) - { - Print(EPeError, "Failed to allocate new import section.\n"); - aSize = 0; - return 0; - } - - ((E32ImportSection *)newSection)->iSize = byteSize; - - // used to point to current ImportBlock - E32ImportBlock * bp = ELFADDR(E32ImportBlock, newSection, sizeof(E32ImportSection)); - // used to point to current import relocation entry - TUint * rp; - // used to point to current location in string table - char * sp = ELFADDR(char, newSection, (byteSize - iStringTableSize)); - OrdZeroRecord *aDep = iDepRecords; - - for (DllRec * dll = iDllHead; dll != NULL ; dll = dll->iNext, bp = (E32ImportBlock *)rp ) - { - // set up the offset from E32ImportBlock.iOffsetOfDllName to the - // corresponding string table location - bp->iOffsetOfDllName = (sp - (char *)newSection); - bp->iNumberOfImports = dll->nImports; - if(iNamedLookupEnabled) - { - bp->iNumberOfImports++; - } - - // copy the DLL name to the string table - memcpy(sp , dll->iName, dll->iLen); - sp[dll->iLen] = 0; - sp = sp + dll->iLen + 1; - - // sort out the import 'relocs' - rp = ELFADDR(TUint, bp, sizeof(E32ImportBlock)); - - for (DllSymbol * sym = dll->iHead; sym != NULL; sym = sym->iNext, rp++) - { - Elf32_Phdr * segment = sym->iSegment; - Elf32_Addr segBase = segment->p_vaddr; - - // sanity check: segment should be the code segment - if (!iElfFile->CodeSegmentP(segment)) - { - Print(EPeError, "Import relocation does not refer to code segment.\n"); - aSize = 0; - return 0; - } - - // This field is misnamed because it is actually given as a virtual address in - // dynamic relocations - Elf32_Addr dynOffset = sym->iRel->r_offset; - //So this is the 'real' offset of the reloc in the segment in which it occurs - Elf32_Addr segOffset = dynOffset - segBase; - TUint * relocAddr = ELFADDR(TUint, iElfFile->ELFFileBase(), (segment->p_offset + segOffset)); - // The only non-zero reloc vals we expect are for vtables. - // We store there reloc offset in the top 16 bits of the 'reloc info'. - // NB the ELF reloc values should only ever be multiples of 4. So we could optimize here, - // but we won't. - TUint relocVal = *relocAddr; - TUint importOrdinal = sym->iOrd; - if (relocVal > 0xFFFF) - Print(EPeError, "ELF relocation exceeds E32Image limit of 64K.\n"); - if (importOrdinal > 0xFFFF) - Print(EPeError, "Import ordinal exceeds E32Image limit of 64K.\n"); - - *rp = segOffset; - - // eek !! surgery on the code segment.... - *relocAddr = (relocVal<<16) | importOrdinal; - } - - if(iNamedLookupEnabled) - { - aDep = FindDependency(dll->iName, dll->iLen); - if( aDep ) - { - *rp = aDep->iOffset; - rp++; - } - } - } - - aSize = byteSize; - return newSection; - } - -TUint ELFFile::ELFDllData::GetExportTableOffset(void) - { - Elf32_Sym * et = &iDynSymTab[iExportTableSymIdx]; - Elf32_Phdr * segment = iElfFile->GetSegment(et->st_shndx - 1); - - return et->st_value - segment->p_vaddr; - } - -TBool ELFFile::ELFDllData::GetRelocs(Elf32_Rel **aCodeRelocs, Elf32_Rel **aDataRelocs) - // - // load the relocs from the reloc section into relocation and relocsection arrays - // - { - TInt nrelocs = iRelSz/iRelEnt; - - TInt SrcSegIdx = -1; - - TInt cidx = 0; - TInt didx = 0; - - for (TInt idx = 0; idx < nrelocs; idx++) - { - Elf32_Rel * rel = &iRel[idx]; - - if (ELF32_R_TYPE(rel->r_info) == R_ARM_RABS32) - { - if (iElfFile->CodeSegmentP(SrcSegIdx)) - aCodeRelocs[cidx++]=rel; - else if (iElfFile->DataSegmentP(SrcSegIdx)) - aDataRelocs[didx++]=rel; - } - else if (ELF32_R_TYPE(rel->r_info) == R_ARM_RBASE) - { - SrcSegIdx = ELF32_R_SYM(rel->r_info); - if (!(iElfFile->CodeSegmentP(SrcSegIdx-1) || iElfFile->DataSegmentP(SrcSegIdx-1))) - { - Print(EPeError, "Source segment for relocations is neither Code or Data.\n"); - return EFalse; - } - SrcSegIdx--; - } - } - - if(!iNamedLookupEnabled) - return ETrue; - - // Add the 0th ordinal of this binary - The relocation info is already setup. - aCodeRelocs[cidx++] = &iOrdZeroRec->iReloc; - - // add relocation entries for each of the symbols - NamedExportSymbol *aSym = iNamedExportSymbolHead; - while(aSym) - { - // The symbol name info is part of the code section hence all relocations - // are collected as part of Code relocations. - aCodeRelocs[cidx++] = &aSym->iReloc; - aSym = aSym->Next(); - } - - // Since we have added a few relocations, lets make sure - // they are still sorted on addresses they refer to. - - //Sorting the code relocs - TInt aIdx1, aIdx2; - Elf32_Rel *aTmp; - for (aIdx1 = 0; aIdx1 < cidx; aIdx1++) { - for (aIdx2 = aIdx1; aIdx2 < cidx; aIdx2++) { - if(aCodeRelocs[aIdx1]->r_offset > aCodeRelocs[aIdx2]->r_offset) { - aTmp = aCodeRelocs[aIdx2]; - aCodeRelocs[aIdx2] = aCodeRelocs[aIdx1]; - aCodeRelocs[aIdx1] = aTmp; - } - } - } - - //Sorting the data relocs - for (aIdx1 = 0; aIdx1 < didx; aIdx1++) { - for (aIdx2 = aIdx1; aIdx2 < didx; aIdx2++) { - if(aDataRelocs[aIdx1]->r_offset > aDataRelocs[aIdx2]->r_offset) { - aTmp = aDataRelocs[aIdx2]; - aDataRelocs[aIdx2] = aDataRelocs[aIdx1]; - aDataRelocs[aIdx1] = aTmp; - } - } - } - - return ETrue; - } - -NamedExportSymbol::NamedExportSymbol(char* aName, Elf32_Addr aValue) : \ - iSymbolName(aName), iValue(aValue), iNext(NULL) -{ -} - -TBool ELFFile::ELFDllData::CreateSymLookupTable() -{ - if( !SetupSymbolValues() ) - return FALSE; - - if( !SetupSymbolNames() ) - return FALSE; - - return TRUE; -} - -TBool ELFFile::ELFDllData::SetupSymbolValues() -{ - NamedExportSymbol *aSym, *aPrevSym; - - if( int(iExportTableSymIdx) == -1 || int(iExportTableSizeSymIdx) == -1) - return FALSE; - - // Fetch the 'export table' symbol from the dynamic symbol table. - Elf32_Sym *aElfExpTbl = &iDynSymTab[iExportTableSymIdx]; - - // Fetch the 'export table size' symbol from the dynamic symbol table. - Elf32_Sym *aElfExpTblSz = &iDynSymTab[iExportTableSizeSymIdx]; - - if((aElfExpTbl->st_value - aElfExpTblSz->st_value) != 4) - { - // Check that the word prior to the export table is not the export table size - // This is to make sure that there is space for the 0th ordinal and - // we dont overwrite the 'export table size' entry. - iNamedLookupEnabled = 1; - } - else - return FALSE; - - // Fetch the export table contents - Elf32_Word * aExpEntries = iElfFile->CodePtrFromAddr(aElfExpTbl->st_value); - - if(!aExpEntries) - return FALSE; - - aSym = aPrevSym = NULL; - TInt idx; - // Create symbols corresponding to export table entries. - for(idx = 0; idx < iNumberOfExports; idx++) - { - //Symbols marked Absent are ignored. - if( aExpEntries[idx] == iElfFile->iEntryPoint) - continue; - - aSym = new NamedExportSymbol(0, aExpEntries[idx]); - iNamedExportCount++; - if(aPrevSym) - { - aPrevSym->Next(aSym); - } - else - { - iNamedExportSymbolHead = aSym; - } - - aPrevSym = aSym; - } - - return TRUE; -} - -TBool ELFFile::ELFDllData::SetupSymbolNames() -{ - char *aSymName = NULL; - NamedExportSymbol *aSym; - TUint aDynSymbolTblCount = iHashTable->nChains; - TInt aCount = 0; - TInt aCodeSegIdx = iElfFile->CodeSegmentIndex() + 1; - TInt aDataSegIdx = iElfFile->DataSegmentIndex() + 1; - - // Traverse the dynamic symbol table - for(TUint idx = 0; idx < aDynSymbolTblCount; idx++) - { - //Consider only the the defined symbols - if( ELF32_ST_TYPE(iDynSymTab[idx].st_info) == STT_OBJECT || - ELF32_ST_TYPE(iDynSymTab[idx].st_info) == STT_FUNC ) - { - aSym = iNamedExportSymbolHead; - while(aSym) - { - // Name already set - if(aSym->Name()) - { - aSym = aSym->Next(); - continue; - } - Elf32_Addr aAddr = aSym->Value(); - - // If the exported symbol and the dynamic symbol table entry have the - // same values, setup the name - if(iDynSymTab[idx].st_value == aAddr) - { - aSymName = ELFADDR(char, iDynStrTab, iDynSymTab[idx].st_name); - aSym->Name(aSymName); - - if(iElfFile->CodeSegmentP (iElfFile->GetSegmentFromAddr(aAddr)) ) { - aSym->iReloc.r_info = aCodeSegIdx << 8 | R_ARM_RABS32; - aSym->iSymRelocType = KTextRelocType; - } - else { - aSym->iReloc.r_info = aDataSegIdx << 8 | R_ARM_RABS32; - aSym->iSymRelocType = KDataRelocType; - } - - iNumberOfCodeRelocs++; - iNumberOfRelocs++; - - // The offset to the name is always 4 byte aligned. - iStringNameOffset = iSymStringTableSize >> 2; - aSym->NameOffset( iSymStringTableSize ); - // These are NULL-terminated strings - iSymStringTableSize += (strlen(aSymName) + 1); - iSymStringTableSize = ALIGN4(iSymStringTableSize); - - aCount++; - break; - } - aSym = aSym->Next(); - } - } - } - - if(aCount != iNamedExportCount) - return FALSE; - - // Sort symbols on their names... - if(iNamedExportCount > 1) - { - NamedExportSymbol **aTmpStart = &iNamedExportSymbolHead; - Sort(aTmpStart, iNamedExportSymbolHead); - } - - return TRUE; -} - -void ELFFile::ELFDllData::SetLookupTblBase(TInt aBaseOffset) -{ - Elf32_Addr aBaseAddr = iElfFile->iLinkedBase + iElfFile->GetCodeSize(); - - Elf32_Addr aAddr; - - // setup relocations of each of the exported symbols. - aAddr = aBaseAddr + iSymInfoHdr.iSymbolTblOffset; - NamedExportSymbol *aSym = iNamedExportSymbolHead; - while(aSym) - { - aSym->iReloc.r_offset = aAddr; - aAddr += sizeof(Elf32_Addr); - aSym = aSym->Next(); - } - - // setup relocations for the 0th ordinal of this binary. - - iOrdZeroRec = new OrdZeroRecord(0); - Elf32_Sym * et = &iDynSymTab[iExportTableSymIdx]; - iOrdZeroRec->iReloc.r_offset = et->st_value - 4; // The word prior ro the first entry - // of the export table is the 0th ordinal entry. - - //At the 0th ordinal, write the address of the start of symbol info - TUint32 aZeroOrdOff = et->st_value - 4 - iElfFile->iLinkedBase; - aZeroOrdOff += (iElfFile->GetSegment(et->st_shndx - 1))->p_offset; - TUint32 *aZeroOrdLocation = ELFADDR(TUint32, iElfFile->ELFFileBase(), aZeroOrdOff); - *aZeroOrdLocation = aBaseAddr; - - iOrdZeroRec->iReloc.r_info = ELF32_R_INFO(et->st_shndx, R_ARM_RABS32); - iNumberOfCodeRelocs++; - iNumberOfRelocs++; - - TInt aOffset = aBaseOffset + iSymInfoHdr.iDepDllZeroOrdTableOffset; - - OrdZeroRecord *aDepRecord = iDepRecords; - - while( aDepRecord ) - { - // Setup the offset - This offset (relative code segment) is filled in the - // import table to point to this dependency record. - aDepRecord->iOffset = aOffset; - - aOffset += 4; - aDepRecord = aDepRecord->iNext; - } -} - -TBool ELFFile::ELFDllData::AddToDependency(TUint aOff) -{ - // Add the name found in DT_NEEDED into a list. - // The dynamic string table might not have been found in dynamic table yet. - // So store the offset (wrt base of dynamic string table) for now. - NeededDLLsList *aNeeded = new NeededDLLsList(aOff); - if(!aNeeded) - return FALSE; - - if ( iNeededDllNames ) { - iNeededDllNamesTail->iNext= aNeeded; - iNeededDllNamesTail = aNeeded; - } - else { - iNeededDllNames = iNeededDllNamesTail = aNeeded; - } - - return TRUE; -} - -TBool ELFFile::ELFDllData::CreateDependency() -{ - OrdZeroRecord *aDep; - NeededDLLsList *aNeeded = iNeededDllNames; - char *aDllName = NULL; - DllRec *aRec; - TInt aNeededFound; - - for(aNeededFound = 0; (aNeededFound < iNumberOfImportDlls) && aNeeded;) - { - aRec = 0; - while(aNeeded) { - aDllName = iDynStrTab + aNeeded->iOffset; - // aNeeded is just a guess that this binary might be dependent on aDllName - // Search through the import table to find if the guess was correct. - aRec = SearchImports(aDllName); - if(aRec && FindDependency(aRec->iName, aRec->iLen) == NULL) { - // Check if aDllName is listed in import table and it - // not added already in the depedency records. - aNeededFound++; - break; - } - // Bad guess...go to the next aNeeded - aNeeded = aNeeded->iNext; - } - - if( !aRec ) - return FALSE; - - aDep = new OrdZeroRecord(aDllName); - if(!iDepRecords) - { - iDepRecords = iDepRecordsTail = aDep; - } - else - { - iDepRecordsTail->iNext = aDep; - iDepRecordsTail = aDep; - } - aNeeded = aNeeded->iNext; - } - - return (aNeededFound == iNumberOfImportDlls); -} - -ELFFile::ELFDllData::DllRec* ELFFile::ELFDllData::SearchImports(char *aName) -{ - DllRec *aRec = iDllHead; - while (aRec) - { - if(strncmp(aRec->iName, aName, aRec->iLen) == 0) - return aRec; - aRec = aRec->iNext; - } - return NULL; -} - -OrdZeroRecord* ELFFile::ELFDllData::FindDependency(char* aName, TUint aLen) -{ - OrdZeroRecord* aDep = iDepRecords; - while(aDep) - { - if(strncmp(aName, aDep->iName, aLen) == 0) - return aDep; - aDep = aDep->iNext; - } - return NULL; -} - -void ELFFile::ELFDllData::GetExportSymInfoHeader(E32EpocExpSymInfoHdr& aSymInfoHdr) -{ - memcpy(&aSymInfoHdr, &iSymInfoHdr, sizeof(E32EpocExpSymInfoHdr)); -} - -void ELFFile::ELFDllData::SetExportSymInfo() -{ - iSymInfoHdr.iSymCount = (TUint16)iNamedExportCount; - iSymInfoHdr.iSymbolTblOffset = sizeof(E32EpocExpSymInfoHdr); - iSymInfoHdr.iStringTableSz = iSymStringTableSize; - TInt aSymTabSz; - if( iStringNameOffset > 0xffff){ - iSymInfoHdr.iFlags = KNameLookupOffsetFlag32; // Flag indicating 32 bit offsets - // for symbol names - aSymTabSz = iNamedExportCount* sizeof(TUint32);// symbol addresses - aSymTabSz += iNamedExportCount* sizeof(TUint32);// symbol name 32-bit offsets - } - else - { - iSymInfoHdr.iFlags &= ~KNameLookupOffsetFlag32;// Flag indicating 16-bit offsets - // for symbol names - aSymTabSz = iNamedExportCount* sizeof(TUint32); // symbol addresses - aSymTabSz += iNamedExportCount* sizeof(TUint16);// symbol name 16-bit offsets - aSymTabSz = ALIGN4(aSymTabSz); - } - iSymInfoHdr.iStringTableOffset = iSymInfoHdr.iSymbolTblOffset + aSymTabSz; - iSymInfoHdr.iDllCount = iNumberOfImportDlls; - iSymInfoHdr.iDepDllZeroOrdTableOffset = iSymInfoHdr.iStringTableOffset + \ - iSymInfoHdr.iStringTableSz; - - iSymInfoHdr.iSize = iSymInfoHdr.iDepDllZeroOrdTableOffset + \ - iSymInfoHdr.iDllCount * sizeof(Elf32_Addr); -} - -TUint ELFFile::ELFDllData::GetSymLookupSection(char* aBuff) -{ - if( !iNamedLookupEnabled) - return 0; - - memcpy(aBuff, &iSymInfoHdr, sizeof(iSymInfoHdr)); - - // Name offsets start after the end of symbol addresses. - TUint32 aNameOffsetStart = iSymInfoHdr.iSymbolTblOffset + \ - iNamedExportCount* sizeof(TUint32); - - TUint32 *aAddrPtr = (TUint32*)(aBuff + iSymInfoHdr.iSymbolTblOffset); - TUint32 aStringTabOff = 0; - char *aStringTab = aBuff + iSymInfoHdr.iStringTableOffset;//Start of the string table. - NamedExportSymbol *aSym = iNamedExportSymbolHead; - while(aSym) - { - *aAddrPtr = aSym->Value(); - aStringTabOff = aSym->NameOffset(); // Get the offset of symbol name (which is wrt - // string table base). - if( iSymInfoHdr.iFlags & KNameLookupOffsetFlag32 ) - { - TUint32 *aNameOffPtr = (TUint32*)(aBuff + aNameOffsetStart); - *aNameOffPtr = (aStringTabOff >> 2);//write the offset of the name - strcpy(aStringTab + aStringTabOff, aSym->Name());//write the symbol name - aNameOffsetStart +=4; - } - else - { - TUint16 *aNameOffPtr = (TUint16*)(aBuff + aNameOffsetStart); - *aNameOffPtr = (TUint16)(aStringTabOff >> 2);//write the offset of the name - strcpy(aStringTab + aStringTabOff, aSym->Name());//write the symbol name - aNameOffsetStart +=2; - } - aAddrPtr++; - aSym = aSym->Next(); - } - - OrdZeroRecord *aRec = iDepRecords; - TUint32* aDepsTable = (TUint32*)(aBuff + iSymInfoHdr.iDepDllZeroOrdTableOffset); - while(aRec) - { - *aDepsTable++ = 0; - aRec = aRec->iNext; - } - return iSymInfoHdr.iSize; -} - -void ELFFile::ELFDllData::Sort(NamedExportSymbol** aDstList, NamedExportSymbol* aSrcList) -{ - NamedExportSymbol *aSym = aSrcList; - NamedExportSymbol **aSymbols = new NamedExportSymbol*[iNamedExportCount]; - - TInt pos; - for (pos = 0; pos < iNamedExportCount; pos++) { - aSymbols[pos] = aSym; - aSym = aSym->Next(); - } - - NamedExportSymbol **aResult = new NamedExportSymbol*[iNamedExportCount]; - MergeSort(aResult, aSymbols); - iNamedExportSymbolHead = aResult[0]; - for (pos = 0; pos < iNamedExportCount; pos++) { - aSym = aResult[pos]; - if( pos == iNamedExportCount-1) - aSym->Next(NULL); - else - aSym->Next(aResult[pos+1]); - } - *aDstList = aResult[0]; - delete [] aResult; - delete [] aSymbols; -} - -void ELFFile::ELFDllData::MergeSort(NamedExportSymbol** aDstList, NamedExportSymbol** aSrcList) -{ - MergeSort(aDstList, aSrcList, 0, iNamedExportCount); -} - -void ELFFile::ELFDllData::MergeSort(NamedExportSymbol** aDstList, NamedExportSymbol** aSrcList, \ - TUint aLeft, TUint aRight) -{ - if( (aRight - aLeft) <= 1) - return; - - TUint aSize = aRight - aLeft; - TUint aCenter = aLeft + aSize/2; - - MergeSort(aDstList, aSrcList, aLeft, aCenter); - MergeSort(aDstList, aSrcList, aCenter, aRight); - - TUint aLPos, aRPos, aCnt; - aLPos = aLeft; - aRPos = aCenter; - for(aCnt = 0; aCnt < aSize; aCnt++) - { - if( (aLPos < aCenter) && - (aRPos == aRight || (strcmp(aSrcList[aLPos]->Name(), aSrcList[aRPos]->Name()) < 0) ) - ) - { - // Compare the left half with the right and add the lesser one. - // The comparision is done on the topmost element on each half. - // if aRPos is past the last element of the right half, the left element has - // nothing to compare with. Just add it to the result list. - aDstList[aCnt] = aSrcList[aLPos]; - aLPos++; - } - else - { - // Add the greater one into the list. - // if aLPos is past the element at the center, it anyway belongs to the - // right half. Add it to the result list. - aDstList[aCnt] = aSrcList[aRPos]; - aRPos++; - } - } - - // Once the sublist is sorted, put it back to the source list - // so that the parent has its left and right sublists are sorted. - for(aCnt = 0; aCnt < aSize; aCnt++) - { - aSrcList[aLeft+aCnt] = aDstList[aCnt]; - } -} - +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +#include +#include +#include +#include "elfdefs.h" +#include "elfdll.h" +#include "elffile.h" +#include "h_utl.h" +#include + +ELFFile::ELFDllData::ELFDllData(ELFFile * f) : + iElfFile(f), iDynStrTab(0), iDynStrTabSize(0), iDynSymTab(0), + iSymSize(0), iRela(0), iRelaSz(0), iRelaEnt(0), + iRel(0), iRelSz(0), iRelEnt(0), + iHashTable(0), iNamedExportSymbolHead(0), iNamedExportCount(0), + iSymStringTableSize(0),iStringNameOffset(0), + iDepRecords(0), iDepRecordsTail(0),iNeededDllNames(0),iNeededDllNamesTail(0), + iOrdZeroRec(0), iNamedLookupEnabled(0), + iDllHead(0), iDllTail(0), + iNumberOfImports(0), iNumberOfExports(0), iNumberOfImportDlls(0), + iStringTableSize(0), iNumberOfRelocs(0), iNumberOfCodeRelocs(0), + iNumberOfDataRelocs(0) + + { + } + +ELFFile::ELFDllData::~ELFDllData() + { + delete iOrdZeroRec; + delete iDepRecords; + delete iNeededDllNames; + } + +TBool ELFFile::ELFDllData::Init() + { + // process imported symbols + // There will be at least one relocation (assumed to be Elf32_Rel) for each such symbol. + // S iterate over relocations looking for DLL symbols and add them to the record of + // of import info. + TInt nrelocs = iRelSz/iRelEnt; + TInt SrcSegIdx = -1; + TInt errors = 0; + + for (TInt idx = 0; idx < nrelocs; idx++) + { + Elf32_Rel * rel = &iRel[idx]; + TUint relType = ELF32_R_TYPE(rel->r_info); + + if (relType == R_ARM_ABS32) + { + TInt symIdx = ELF32_R_SYM(rel->r_info); + Elf32_Sym * sym = &iDynSymTab[symIdx]; + DllSymbol * dllSym = DllSymbolP(sym); + if (dllSym) + { + dllSym->iRel = rel; + dllSym->iSegment = iElfFile->GetSegment(SrcSegIdx); + if (!AddSymbol(dllSym)) return EFalse; + } + else errors++; + } + else if (relType == R_ARM_RABS32) + { + iNumberOfRelocs++; + if (iElfFile->CodeSegmentP(SrcSegIdx)) iNumberOfCodeRelocs++; + else iNumberOfDataRelocs++; + } + else if (relType == R_ARM_RBASE) + { + SrcSegIdx = ELF32_R_SYM(rel->r_info); + if (SrcSegIdx) SrcSegIdx--; + } + else + { + // Gives error with all other Relocation types.. + TInt symIdx = ELF32_R_SYM(rel->r_info); + Elf32_Sym * s = &iDynSymTab[symIdx]; + char * symName = ELFADDR(char,iDynStrTab,s->st_name); + Print(EPeError, "Unresolved symbol: %s\n", symName); + errors++; + } + } + // Set up export info + if (InitExportInfo()) + { + // If _E32Startup is defined then this is not a DLL + iImageIsDll = !iElfFile->SymbolPresent("_E32Startup"); + } + if (errors > 0) return EFalse; + return ETrue; + } + +TBool ELFFile::ELFDllData::ParseDllSymbol(Elf32_Sym * s, char *& dll, TUint& len, TInt& ord) + { + char * sym = ELFADDR(char,iDynStrTab,s->st_name); + if (!strncmp(sym, DLLSYMPREFIX, strlen(DLLSYMPREFIX))) + { + dll = sym + strlen(DLLSYMPREFIX); + TUint lim = strlen(dll); + TUint index = strcspn(dll, DLLSYMPREFIX0); + if ((index + strlen(DLLSYMSUFFIX)) < lim) + { + len = index; + char * dllSuffix = dll+index; + char * match = DLLSYMSUFFIX; + int suflen = strlen(DLLSYMSUFFIX); + if (!strncmp(dllSuffix, match, suflen)) + { + char * ordString = dll+index+suflen; + char * final; + TUint X = strtoul(ordString, &final, ORDBASE); + if (ordString != final) + { + ord = (TInt)X; + return ETrue; + } + + } + } + } + dll = 0; + len = 0; + ord = -1; + return EFalse; + } + +ELFFile::ELFDllData::DllSymbol * ELFFile::ELFDllData::DllSymbolP(Elf32_Sym * s) + { + char * dllName; + TUint nameLen; + TInt symOrd; + if (ParseDllSymbol(s, dllName, nameLen, symOrd)) + { + DllSymbol * ds = new DllSymbol(dllName, nameLen, symOrd); + if (ds) return ds; + Print(EPeError, "Out of memory.\n"); + return NULL; + } + // If we get here its not a valid 'dll symbol' and so it is an unresolved symbol + char * sym = ELFADDR(char,iDynStrTab,s->st_name); + Print(EPeError, "Unresolved symbol: %s\n", sym); + return NULL; + } + +TBool ELFFile::ELFDllData::AddSymbol(ELFFile::ELFDllData::DllSymbol * s) + { + DllRec * aDll = NULL; + + for (DllRec * r = iDllHead; r != NULL; r = r->iNext) + { + if (!strncmp(s->iDll, r->iName, s->iLen)) + { + aDll = r; + break; + } + } + if (aDll) + { + iNumberOfImports++; + aDll->AddSymbol(s); + return ETrue; + } + else + { + aDll = new DllRec(s->iDll, s->iLen, s); + if (aDll) + { + if (!iDllHead) + { + iDllHead = iDllTail = aDll; + } + else + { + iDllTail->iNext = aDll; + iDllTail = aDll; + } + iStringTableSize += (s->iLen + 1); + iNumberOfImportDlls++; + iNumberOfImports++; + return ETrue; + } + else + { + Print(EPeError, "Out of memory.\n"); + return EFalse; + } + } + } + +void ELFFile::ELFDllData::DllRec::AddSymbol(ELFFile::ELFDllData::DllSymbol * s) + { + nImports++; + iTail->iNext = s; + iTail = s; + } + +static unsigned long elf_hash(const unsigned char* name) + { + unsigned long h, g; + for (h = 0; *name != 0; ++name) + { + h = (h << 4) + *name; + g = h & 0xf0000000; + if (g != 0) h ^= g >> 24; + h &= ~g; + } + return h; + } + +Elf32_Word ELFFile::ELFDllData::FindSymbolIndex(const char* s) + { + TUint h = elf_hash((const unsigned char*)s); + TUint nb = iHashTable[0].nBuckets; + TUint probe = h%nb; + Elf32_Sword * bucket = ELFADDR(Elf32_Sword, iHashTable, sizeof(Elf32_HashTable)); + Elf32_Sword * chain = ELFADDR(Elf32_Sword, bucket, nb * sizeof(Elf32_Sword)); + Elf32_Sword idx = bucket[probe]; + + do + { + if (!strcmp(ELFADDR(char, iDynStrTab, iDynSymTab[idx].st_name), s)) return idx; + idx = chain[idx]; + } while (idx > 0); + if (idx == 0) idx = -1; + return idx; + } + +TBool ELFFile::ELFDllData::InitExportInfo() + { + memset(&iSymInfoHdr, 0, sizeof(iSymInfoHdr)); + if ((iExportTableSymIdx = FindSymbolIndex(EXPORTTABLENAME)) != (Elf32_Word)-1) + { + iExportTableSizeSymIdx = FindSymbolIndex(EXPORTTABLESIZENAME); + //TUint offset = iDynSymTab[iExportTableSizeSymIdx].st_value - (TUint)code; + Elf32_Word * pNumberOfExports = iElfFile->CodePtrFromAddr(iDynSymTab[iExportTableSizeSymIdx].st_value); + iNumberOfExports = * pNumberOfExports; + iImageIsDll = ETrue; + return ETrue; + } + else iImageIsDll = EFalse; + return EFalse; + } + +TInt ELFFile::ELFDllData::NumberOfImports(void) + { + return iNumberOfImports; + } + +TInt ELFFile::ELFDllData::NumberOfExports(void) + { + return iNumberOfExports; + } + +TInt ELFFile::ELFDllData::NumberOfImportDlls(void) + { + return iNumberOfImportDlls; + } + +TInt ELFFile::ELFDllData::NumberOfRelocs() + { + return iNumberOfRelocs; + } + +char * ELFFile::ELFDllData::CreateImportSection(TInt &aSize) + { + if (!iNumberOfImports) + { + aSize = 0; + return 0; + } + + TInt byteSize = sizeof(E32ImportSection) + + (sizeof(E32ImportBlock) * iNumberOfImportDlls) + + (sizeof(TUint) * iNumberOfImports) + + iStringTableSize; + if(iNamedLookupEnabled) + { + // 0th ordinal of each DLL imported from. + byteSize += (sizeof(TUint) * iNumberOfImportDlls); + } + char * newSection = new char[byteSize]; + + if (!newSection) + { + Print(EPeError, "Failed to allocate new import section.\n"); + aSize = 0; + return 0; + } + + ((E32ImportSection *)newSection)->iSize = byteSize; + + // used to point to current ImportBlock + E32ImportBlock * bp = ELFADDR(E32ImportBlock, newSection, sizeof(E32ImportSection)); + // used to point to current import relocation entry + TUint * rp; + // used to point to current location in string table + char * sp = ELFADDR(char, newSection, (byteSize - iStringTableSize)); + OrdZeroRecord *aDep = iDepRecords; + + for (DllRec * dll = iDllHead; dll != NULL ; dll = dll->iNext, bp = (E32ImportBlock *)rp ) + { + // set up the offset from E32ImportBlock.iOffsetOfDllName to the + // corresponding string table location + bp->iOffsetOfDllName = (sp - (char *)newSection); + bp->iNumberOfImports = dll->nImports; + if(iNamedLookupEnabled) + { + bp->iNumberOfImports++; + } + + // copy the DLL name to the string table + memcpy(sp , dll->iName, dll->iLen); + sp[dll->iLen] = 0; + sp = sp + dll->iLen + 1; + + // sort out the import 'relocs' + rp = ELFADDR(TUint, bp, sizeof(E32ImportBlock)); + + for (DllSymbol * sym = dll->iHead; sym != NULL; sym = sym->iNext, rp++) + { + Elf32_Phdr * segment = sym->iSegment; + Elf32_Addr segBase = segment->p_vaddr; + + // sanity check: segment should be the code segment + if (!iElfFile->CodeSegmentP(segment)) + { + Print(EPeError, "Import relocation does not refer to code segment.\n"); + Print(EPeError, "Dll: %s\n", sym->iDll); + Print(EPeError, "Ordinal: %d\n", sym->iOrd); + Print(EPeError, "DLL name: %s\n", dll->iName); + aSize = 0; + return 0; + } + + // This field is misnamed because it is actually given as a virtual address in + // dynamic relocations + Elf32_Addr dynOffset = sym->iRel->r_offset; + //So this is the 'real' offset of the reloc in the segment in which it occurs + Elf32_Addr segOffset = dynOffset - segBase; + TUint * relocAddr = ELFADDR(TUint, iElfFile->ELFFileBase(), (segment->p_offset + segOffset)); + // The only non-zero reloc vals we expect are for vtables. + // We store there reloc offset in the top 16 bits of the 'reloc info'. + // NB the ELF reloc values should only ever be multiples of 4. So we could optimize here, + // but we won't. + TUint relocVal = *relocAddr; + TUint importOrdinal = sym->iOrd; + if (relocVal > 0xFFFF) { + Print(EPeError, "ELF relocation exceeds E32Image limit of 64K.\n"); + Print(EPeError, "Dll: %s\n", sym->iDll); + Print(EPeError, "Ordinal: %d\n", sym->iOrd); + Print(EPeError, "DLL name: %s\n", dll->iName); + } + if (importOrdinal > 0xFFFF) { + Print(EPeError, "Import ordinal exceeds E32Image limit of 64K.\n"); + Print(EPeError, "Dll: %s\n", sym->iDll); + Print(EPeError, "Ordinal: %d\n", sym->iOrd); + Print(EPeError, "DLL name: %s\n", dll->iName); + } + *rp = segOffset; + + // eek !! surgery on the code segment.... + *relocAddr = (relocVal<<16) | importOrdinal; + } + + if(iNamedLookupEnabled) + { + aDep = FindDependency(dll->iName, dll->iLen); + if( aDep ) + { + *rp = aDep->iOffset; + rp++; + } + } + } + + aSize = byteSize; + return newSection; + } + +TUint ELFFile::ELFDllData::GetExportTableOffset(void) + { + Elf32_Sym * et = &iDynSymTab[iExportTableSymIdx]; + Elf32_Phdr * segment = iElfFile->GetSegment(et->st_shndx - 1); + + return et->st_value - segment->p_vaddr; + } + +TBool ELFFile::ELFDllData::GetRelocs(Elf32_Rel **aCodeRelocs, Elf32_Rel **aDataRelocs) + // + // load the relocs from the reloc section into relocation and relocsection arrays + // + { + TInt nrelocs = iRelSz/iRelEnt; + + TInt SrcSegIdx = -1; + + TInt idx = 0; + TInt cidx = 0; + TInt didx = 0; + + for (idx = 0, cidx = 0, didx = 0; idx < nrelocs; idx++) + { + Elf32_Rel * rel = &iRel[idx]; + + if (ELF32_R_TYPE(rel->r_info) == R_ARM_RABS32) + { + if (iElfFile->CodeSegmentP(SrcSegIdx)) + aCodeRelocs[cidx++]=rel; + else if (iElfFile->DataSegmentP(SrcSegIdx)) + aDataRelocs[didx++]=rel; + } + else if (ELF32_R_TYPE(rel->r_info) == R_ARM_RBASE) + { + SrcSegIdx = ELF32_R_SYM(rel->r_info); + if (!(iElfFile->CodeSegmentP(SrcSegIdx-1) || iElfFile->DataSegmentP(SrcSegIdx-1))) + { + Print(EPeError, "Source segment for relocations is neither Code or Data.\n"); + return EFalse; + } + SrcSegIdx--; + } + } + + if(!iNamedLookupEnabled) + return ETrue; + + // Add the 0th ordinal of this binary - The relocation info is already setup. + aCodeRelocs[cidx++] = &iOrdZeroRec->iReloc; + + // add relocation entries for each of the symbols + NamedExportSymbol *aSym = iNamedExportSymbolHead; + while(aSym) + { + // The symbol name info is part of the code section hence all relocations + // are collected as part of Code relocations. + aCodeRelocs[cidx++] = &aSym->iReloc; + aSym = aSym->Next(); + } + + // Since we have added a few relocations, lets make sure + // they are still sorted on addresses they refer to. + + //Sorting the code relocs + TInt aIdx1, aIdx2; + Elf32_Rel *aTmp; + for (aIdx1 = 0; aIdx1 < cidx; aIdx1++) { + for (aIdx2 = aIdx1; aIdx2 < cidx; aIdx2++) { + if(aCodeRelocs[aIdx1]->r_offset > aCodeRelocs[aIdx2]->r_offset) { + aTmp = aCodeRelocs[aIdx2]; + aCodeRelocs[aIdx2] = aCodeRelocs[aIdx1]; + aCodeRelocs[aIdx1] = aTmp; + } + } + } + + //Sorting the data relocs + for (aIdx1 = 0; aIdx1 < didx; aIdx1++) { + for (aIdx2 = aIdx1; aIdx2 < didx; aIdx2++) { + if(aDataRelocs[aIdx1]->r_offset > aDataRelocs[aIdx2]->r_offset) { + aTmp = aDataRelocs[aIdx2]; + aDataRelocs[aIdx2] = aDataRelocs[aIdx1]; + aDataRelocs[aIdx1] = aTmp; + } + } + } + + return ETrue; + } + +NamedExportSymbol::NamedExportSymbol(char* aName, Elf32_Addr aValue) : \ + iSymbolName(aName), iValue(aValue), iNext(NULL) +{ +} + +TBool ELFFile::ELFDllData::CreateSymLookupTable() +{ + if( !SetupSymbolValues() ) + return FALSE; + + if( !SetupSymbolNames() ) + return FALSE; + + return TRUE; +} + +TBool ELFFile::ELFDllData::SetupSymbolValues() +{ + NamedExportSymbol *aSym, *aPrevSym; + + if( iExportTableSymIdx == (Elf32_Word)-1 || iExportTableSizeSymIdx == (Elf32_Word)-1) + return FALSE; + + // Fetch the 'export table' symbol from the dynamic symbol table. + Elf32_Sym *aElfExpTbl = &iDynSymTab[iExportTableSymIdx]; + + // Fetch the 'export table size' symbol from the dynamic symbol table. + Elf32_Sym *aElfExpTblSz = &iDynSymTab[iExportTableSizeSymIdx]; + + if((aElfExpTbl->st_value - aElfExpTblSz->st_value) != 4) + { + // Check that the word prior to the export table is not the export table size + // This is to make sure that there is space for the 0th ordinal and + // we dont overwrite the 'export table size' entry. + iNamedLookupEnabled = 1; + } + else + return FALSE; + + // Fetch the export table contents + Elf32_Word * aExpEntries = iElfFile->CodePtrFromAddr(aElfExpTbl->st_value); + + if(!aExpEntries) + return FALSE; + + aSym = aPrevSym = NULL; + TInt idx; + // Create symbols corresponding to export table entries. + for(idx = 0; idx < iNumberOfExports; idx++) + { + //Symbols marked Absent are ignored. + if( aExpEntries[idx] == iElfFile->iEntryPoint) + continue; + + aSym = new NamedExportSymbol(0, aExpEntries[idx]); + iNamedExportCount++; + if(aPrevSym) + { + aPrevSym->Next(aSym); + } + else + { + iNamedExportSymbolHead = aSym; + } + + aPrevSym = aSym; + } + + return TRUE; +} + +TBool ELFFile::ELFDllData::SetupSymbolNames() +{ + char *aSymName = NULL; + NamedExportSymbol *aSym; + TUint aDynSymbolTblCount = iHashTable->nChains; + TInt aCount = 0; + TInt aCodeSegIdx = iElfFile->CodeSegmentIndex() + 1; + TInt aDataSegIdx = iElfFile->DataSegmentIndex() + 1; + + // Traverse the dynamic symbol table + for(TUint idx = 0; idx < aDynSymbolTblCount; idx++) + { + //Consider only the the defined symbols + if( ELF32_ST_TYPE(iDynSymTab[idx].st_info) == STT_OBJECT || + ELF32_ST_TYPE(iDynSymTab[idx].st_info) == STT_FUNC ) + { + aSym = iNamedExportSymbolHead; + while(aSym) + { + // Name already set + if(aSym->Name()) + { + aSym = aSym->Next(); + continue; + } + Elf32_Addr aAddr = aSym->Value(); + + // If the exported symbol and the dynamic symbol table entry have the + // same values, setup the name + if(iDynSymTab[idx].st_value == aAddr) + { + aSymName = ELFADDR(char, iDynStrTab, iDynSymTab[idx].st_name); + aSym->Name(aSymName); + + if(iElfFile->CodeSegmentP (iElfFile->GetSegmentFromAddr(aAddr)) ) { + aSym->iReloc.r_info = aCodeSegIdx << 8 | R_ARM_RABS32; + aSym->iSymRelocType = KTextRelocType; + } + else { + aSym->iReloc.r_info = aDataSegIdx << 8 | R_ARM_RABS32; + aSym->iSymRelocType = KDataRelocType; + } + + iNumberOfCodeRelocs++; + iNumberOfRelocs++; + + // The offset to the name is always 4 byte aligned. + iStringNameOffset = iSymStringTableSize >> 2; + aSym->NameOffset( iSymStringTableSize ); + // These are NULL-terminated strings + iSymStringTableSize += (strlen(aSymName) + 1); + iSymStringTableSize = ALIGN4(iSymStringTableSize); + + aCount++; + break; + } + aSym = aSym->Next(); + } + } + } + + if(aCount != iNamedExportCount) + return FALSE; + + // Sort symbols on their names... + if(iNamedExportCount > 1) + { + NamedExportSymbol **aTmpStart = &iNamedExportSymbolHead; + Sort(aTmpStart, iNamedExportSymbolHead); + } + + return TRUE; +} + +void ELFFile::ELFDllData::SetLookupTblBase(TInt aBaseOffset) +{ + Elf32_Addr aBaseAddr = iElfFile->iLinkedBase + iElfFile->GetCodeSize(); + + Elf32_Addr aAddr; + + // setup relocations of each of the exported symbols. + aAddr = aBaseAddr + iSymInfoHdr.iSymbolTblOffset; + NamedExportSymbol *aSym = iNamedExportSymbolHead; + while(aSym) + { + aSym->iReloc.r_offset = aAddr; + aAddr += sizeof(Elf32_Addr); + aSym = aSym->Next(); + } + + // setup relocations for the 0th ordinal of this binary. + + iOrdZeroRec = new OrdZeroRecord(0); + Elf32_Sym * et = &iDynSymTab[iExportTableSymIdx]; + iOrdZeroRec->iReloc.r_offset = et->st_value - 4; // The word prior ro the first entry + // of the export table is the 0th ordinal entry. + + //At the 0th ordinal, write the address of the start of symbol info + TUint32 aZeroOrdOff = et->st_value - 4 - iElfFile->iLinkedBase; + aZeroOrdOff += (iElfFile->GetSegment(et->st_shndx - 1))->p_offset; + TUint32 *aZeroOrdLocation = ELFADDR(TUint32, iElfFile->ELFFileBase(), aZeroOrdOff); + *aZeroOrdLocation = aBaseAddr; + + iOrdZeroRec->iReloc.r_info = ELF32_R_INFO(et->st_shndx, R_ARM_RABS32); + iNumberOfCodeRelocs++; + iNumberOfRelocs++; + + TInt aOffset = aBaseOffset + iSymInfoHdr.iDepDllZeroOrdTableOffset; + + OrdZeroRecord *aDepRecord = iDepRecords; + + while( aDepRecord ) + { + // Setup the offset - This offset (relative code segment) is filled in the + // import table to point to this dependency record. + aDepRecord->iOffset = aOffset; + + aOffset += 4; + aDepRecord = aDepRecord->iNext; + } +} + +TBool ELFFile::ELFDllData::AddToDependency(TUint aOff) +{ + // Add the name found in DT_NEEDED into a list. + // The dynamic string table might not have been found in dynamic table yet. + // So store the offset (wrt base of dynamic string table) for now. + NeededDLLsList *aNeeded = new NeededDLLsList(aOff); + if(!aNeeded) + return FALSE; + + if ( iNeededDllNames ) { + iNeededDllNamesTail->iNext= aNeeded; + iNeededDllNamesTail = aNeeded; + } + else { + iNeededDllNames = iNeededDllNamesTail = aNeeded; + } + + return TRUE; +} + +TBool ELFFile::ELFDllData::CreateDependency() +{ + OrdZeroRecord *aDep; + NeededDLLsList *aNeeded = iNeededDllNames; + char *aDllName = NULL; + DllRec *aRec; + TInt aNeededFound; + + for(aNeededFound = 0; (aNeededFound < iNumberOfImportDlls) && aNeeded;) + { + aRec = 0; + while(aNeeded) { + aDllName = iDynStrTab + aNeeded->iOffset; + // aNeeded is just a guess that this binary might be dependent on aDllName + // Search through the import table to find if the guess was correct. + aRec = SearchImports(aDllName); + if(aRec && FindDependency(aRec->iName, aRec->iLen) == NULL) { + // Check if aDllName is listed in import table and it + // not added already in the depedency records. + aNeededFound++; + break; + } + // Bad guess...go to the next aNeeded + aNeeded = aNeeded->iNext; + } + + if( !aRec ) + return FALSE; + + aDep = new OrdZeroRecord(aDllName); + if(!iDepRecords) + { + iDepRecords = iDepRecordsTail = aDep; + } + else + { + iDepRecordsTail->iNext = aDep; + iDepRecordsTail = aDep; + } + aNeeded = aNeeded->iNext; + } + + return (aNeededFound == iNumberOfImportDlls); +} + +ELFFile::ELFDllData::DllRec* ELFFile::ELFDllData::SearchImports(char *aName) +{ + DllRec *aRec = iDllHead; + while (aRec) + { + if(strncmp(aRec->iName, aName, aRec->iLen) == 0) + return aRec; + aRec = aRec->iNext; + } + return NULL; +} + +OrdZeroRecord* ELFFile::ELFDllData::FindDependency(char* aName, TUint aLen) +{ + OrdZeroRecord* aDep = iDepRecords; + while(aDep) + { + if(strncmp(aName, aDep->iName, aLen) == 0) + return aDep; + aDep = aDep->iNext; + } + return NULL; +} + +void ELFFile::ELFDllData::GetExportSymInfoHeader(E32EpocExpSymInfoHdr& aSymInfoHdr) +{ + memcpy(&aSymInfoHdr, &iSymInfoHdr, sizeof(E32EpocExpSymInfoHdr)); +} + +void ELFFile::ELFDllData::SetExportSymInfo() +{ + iSymInfoHdr.iSymCount = (TUint16)iNamedExportCount; + iSymInfoHdr.iSymbolTblOffset = sizeof(E32EpocExpSymInfoHdr); + iSymInfoHdr.iStringTableSz = iSymStringTableSize; + TInt aSymTabSz; + if( iStringNameOffset > 0xffff){ + iSymInfoHdr.iFlags = KNameLookupOffsetFlag32; // Flag indicating 32 bit offsets + // for symbol names + aSymTabSz = iNamedExportCount* sizeof(TUint32);// symbol addresses + aSymTabSz += iNamedExportCount* sizeof(TUint32);// symbol name 32-bit offsets + } + else + { + iSymInfoHdr.iFlags &= ~KNameLookupOffsetFlag32;// Flag indicating 16-bit offsets + // for symbol names + aSymTabSz = iNamedExportCount* sizeof(TUint32); // symbol addresses + aSymTabSz += iNamedExportCount* sizeof(TUint16);// symbol name 16-bit offsets + aSymTabSz = ALIGN4(aSymTabSz); + } + iSymInfoHdr.iStringTableOffset = iSymInfoHdr.iSymbolTblOffset + aSymTabSz; + iSymInfoHdr.iDllCount = iNumberOfImportDlls; + iSymInfoHdr.iDepDllZeroOrdTableOffset = iSymInfoHdr.iStringTableOffset + \ + iSymInfoHdr.iStringTableSz; + + iSymInfoHdr.iSize = iSymInfoHdr.iDepDllZeroOrdTableOffset + \ + iSymInfoHdr.iDllCount * sizeof(Elf32_Addr); +} + +TUint ELFFile::ELFDllData::GetSymLookupSection(char* aBuff) +{ + if( !iNamedLookupEnabled) + return 0; + + memcpy(aBuff, &iSymInfoHdr, sizeof(iSymInfoHdr)); + + // Name offsets start after the end of symbol addresses. + TUint32 aNameOffsetStart = iSymInfoHdr.iSymbolTblOffset + \ + iNamedExportCount* sizeof(TUint32); + + TUint32 *aAddrPtr = (TUint32*)(aBuff + iSymInfoHdr.iSymbolTblOffset); + TUint32 aStringTabOff = 0; + char *aStringTab = aBuff + iSymInfoHdr.iStringTableOffset;//Start of the string table. + NamedExportSymbol *aSym = iNamedExportSymbolHead; + while(aSym) + { + *aAddrPtr = aSym->Value(); + aStringTabOff = aSym->NameOffset(); // Get the offset of symbol name (which is wrt + // string table base). + if( iSymInfoHdr.iFlags & KNameLookupOffsetFlag32 ) + { + TUint32 *aNameOffPtr = (TUint32*)(aBuff + aNameOffsetStart); + *aNameOffPtr = (aStringTabOff >> 2);//write the offset of the name + strcpy(aStringTab + aStringTabOff, aSym->Name());//write the symbol name + aNameOffsetStart +=4; + } + else + { + TUint16 *aNameOffPtr = (TUint16*)(aBuff + aNameOffsetStart); + *aNameOffPtr = (TUint16)(aStringTabOff >> 2);//write the offset of the name + strcpy(aStringTab + aStringTabOff, aSym->Name());//write the symbol name + aNameOffsetStart +=2; + } + aAddrPtr++; + aSym = aSym->Next(); + } + + OrdZeroRecord *aRec = iDepRecords; + TUint32* aDepsTable = (TUint32*)(aBuff + iSymInfoHdr.iDepDllZeroOrdTableOffset); + while(aRec) + { + *aDepsTable++ = 0; + aRec = aRec->iNext; + } + return iSymInfoHdr.iSize; +} + +void ELFFile::ELFDllData::Sort(NamedExportSymbol** aDstList, NamedExportSymbol* aSrcList) +{ + NamedExportSymbol *aSym = aSrcList; + NamedExportSymbol **aSymbols = new NamedExportSymbol*[iNamedExportCount]; + + TInt pos; + for (pos = 0; pos < iNamedExportCount; pos++) { + aSymbols[pos] = aSym; + aSym = aSym->Next(); + } + + NamedExportSymbol **aResult = new NamedExportSymbol*[iNamedExportCount]; + MergeSort(aResult, aSymbols); + iNamedExportSymbolHead = aResult[0]; + for (pos = 0; pos < iNamedExportCount; pos++) { + aSym = aResult[pos]; + if( pos == iNamedExportCount-1) + aSym->Next(NULL); + else + aSym->Next(aResult[pos+1]); + } + *aDstList = aResult[0]; + delete [] aResult; + delete [] aSymbols; +} + +void ELFFile::ELFDllData::MergeSort(NamedExportSymbol** aDstList, NamedExportSymbol** aSrcList) +{ + MergeSort(aDstList, aSrcList, 0, iNamedExportCount); +} + +void ELFFile::ELFDllData::MergeSort(NamedExportSymbol** aDstList, NamedExportSymbol** aSrcList, \ + TUint aLeft, TUint aRight) +{ + if( (aRight - aLeft) <= 1) + return; + + TUint aSize = aRight - aLeft; + TUint aCenter = aLeft + aSize/2; + + MergeSort(aDstList, aSrcList, aLeft, aCenter); + MergeSort(aDstList, aSrcList, aCenter, aRight); + + TUint aLPos, aRPos, aCnt; + aLPos = aLeft; + aRPos = aCenter; + for(aCnt = 0; aCnt < aSize; aCnt++) + { + if( (aLPos < aCenter) && + (aRPos == aRight || (strcmp(aSrcList[aLPos]->Name(), aSrcList[aRPos]->Name()) < 0) ) + ) + { + // Compare the left half with the right and add the lesser one. + // The comparision is done on the topmost element on each half. + // if aRPos is past the last element of the right half, the left element has + // nothing to compare with. Just add it to the result list. + aDstList[aCnt] = aSrcList[aLPos]; + aLPos++; + } + else + { + // Add the greater one into the list. + // if aLPos is past the element at the center, it anyway belongs to the + // right half. Add it to the result list. + aDstList[aCnt] = aSrcList[aRPos]; + aRPos++; + } + } + + // Once the sublist is sorted, put it back to the source list + // so that the parent has its left and right sublists are sorted. + for(aCnt = 0; aCnt < aSize; aCnt++) + { + aSrcList[aLeft+aCnt] = aDstList[aCnt]; + } +} + diff -r 122d2b873fd1 -r 30b30f9da0b7 bintools/elftools/elftran/elf_file.cpp --- a/bintools/elftools/elftran/elf_file.cpp Fri Jun 25 20:58:33 2010 +0800 +++ b/bintools/elftools/elftran/elf_file.cpp Tue Jun 29 14:52:54 2010 +0800 @@ -1,540 +1,527 @@ -/* -* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of the License "Eclipse Public License v1.0" -* which accompanies this distribution, and is available -* at the URL "http://www.eclipse.org/legal/epl-v10.html". -* -* Initial Contributors: -* Nokia Corporation - initial contribution. -* -* Contributors: -* -* Description: -* -*/ - - - -#include -#include -#include "elftran.h" -#include -#include "elffile.h" -#include "elfdll.h" -#include -#include -#include - -TBool hadText, hadReloc = EFalse; - -ELFFile::ELFFile() - : - iHeapCommittedSize(0x1000), - iHeapReservedSize(0x100000), - iStackCommittedSize(0), - - iFileName(0), - iFileHandle(-1), - iElfFile(0), - - iDynamicSegmentHdr(0), - iDynamicSegmentIdx(0), - - iCodeSegmentHdr(0), - iCodeSegmentIdx(0), - - iDataSegmentHdr(0), - iDataSegmentIdx(0), - - iDllData(0), - iCpu(ECpuUnknown) - {} - - - - -ELFFile::~ELFFile() - { - delete [] iFileName; - delete iElfFile; - delete iDllData; - } - - -TBool ELFFile::Init(const TText * const aFileName) -// -// Read the ELF file into memory -// - { - - delete [] iFileName; - iFileName = new TText[strlen((const char *)aFileName)+1]; - strcpy ((char *)iFileName, (const char *)aFileName); - - TInt error = HFile::Open(iFileName, &iFileHandle); - if (error!=0) - return EFalse; - - TInt flength = HFile::GetLength(iFileHandle); - - iElfFile = (Elf32_Ehdr *)HMem::Alloc(0,flength); - if (!iElfFile) - { - Print(EPeError,"Failed to allocate memory to read in file.\n"); - Close(); - return EFalse; - } - - if (!HFile::Read(iFileHandle,iElfFile,flength)) - { - Print(EPeError,"Unable to read file %s.\n",iFileName); - Close(); - return EFalse; - } - - Close(); - - if (!IsValidFileHeader(iElfFile)) - { - Print(EPeError,"Invalid file header.\n"); - return EFalse; - } - // we only support this....for the moment - iCpu = ECpuArmV4; - - if (!InitHeaders()) return EFalse; - - if (!InitDllData()) return EFalse; - - iEntryPoint = iElfFile->e_entry; - - iCodeSize = GetCodeSize(); - iDataSize = GetDataSize(); - iBssSize = GetBssSize(); - - iStackReservedSize = 0x2000; - iStackCommittedSize = 0x2000; - - iLinkedBase = iCodeSegmentHdr->p_vaddr; - - iImageIsDll = iDllData->ImageIsDll(); - - return ETrue; - } - -char * ELFFile::CreateImportSection(TInt &aSize) -// -// get ELFDLLData to do it -// - { - TInt size; - char * newSection = iDllData->CreateImportSection(size); - aSize = size; - return newSection; - } - -TUint ELFFile::GetExportTableOffset(void) - { - return iDllData->GetExportTableOffset(); - } - -TBool ELFFile::InitHeaders(void) - { - TInt nphdrs = iElfFile->e_phnum; - if (nphdrs) - { - // Find the dynamic segment - Elf32_Phdr * aPhdr = ELFADDR(Elf32_Phdr, iElfFile, iElfFile->e_phoff); - iPhdr = aPhdr; - for (TInt idx = 0; idx < nphdrs; idx++) - { - Elf32_Word ptype = aPhdr[idx].p_type; - if (ptype == PT_DYNAMIC) - { - iDynamicSegmentHdr = &aPhdr[idx]; - iDynamicSegmentIdx = idx; - } - else if (ptype == PT_LOAD && - (aPhdr[idx].p_flags & (PF_X + PF_ARM_ENTRY))) - { - iCodeSegmentHdr = &aPhdr[idx]; - iCodeSegmentIdx = idx; - } - else if (ptype == PT_LOAD && - (aPhdr[idx].p_flags & (PF_W + PF_R))) - { - iDataSegmentHdr = &aPhdr[idx]; - iDataSegmentIdx = idx; - } - } - } - - // cache pointer to symbol table - - // Get section header table - Elf32_Shdr * s = ELFADDR(Elf32_Shdr, iElfFile, iElfFile->e_shoff); - // Index of section header for section header string table - TInt stIdx = iElfFile->e_shstrndx; - TInt symIdx = -1; - // Section name string table - char * stringtable = ELFADDR(char, iElfFile, s[stIdx].sh_offset); - // the index at which we find '.symtab' is the index of the symtab section - for (TInt idx = 0; idx < iElfFile->e_shnum; idx++) - { - if (idx != stIdx) - { - if (!strcmp(&stringtable[s[idx].sh_name], ".symtab")) - { - symIdx = idx; - break; - } - } - } - if (symIdx == -1) return EFalse; - - // save section header table - iSectionHeaderTable = s; - // save the index - iSymIdx = symIdx; - // here's the symbol table - iSymTab = ELFADDR(Elf32_Sym, iElfFile, s[symIdx].sh_offset); - return ETrue; - } - -TBool ELFFile::InitDllData(void) - { - if (!iDynamicSegmentHdr) - { -#if defined(_DEBUG) - Print(EWarning, "Image '%s' has no import/export data.\n", iFileName); -#endif - return ETrue; - } - iDllData = new ELFDllData(this); - if (!iDllData) - { - Print(EPeError, "Out of memory allocating DLL data\n"); - return EFalse; - } - - Elf32_Dyn * dyn = ELFADDR(Elf32_Dyn, iElfFile, iDynamicSegmentHdr->p_offset); - TInt idx = 0; - TInt soNameOffset = 0; - while(dyn[idx].d_tag != DT_NULL) // best to make it explicit - { - switch (dyn[idx].d_tag) - { - case DT_HASH: - iDllData->iHashTable = ELFADDR(Elf32_HashTable, dyn, dyn[idx].d_val); - break; - case DT_STRTAB: - iDllData->iDynStrTab = ELFADDR(char, dyn, dyn[idx].d_val); - break; - case DT_SYMTAB: - iDllData->iDynSymTab = ELFADDR(Elf32_Sym, dyn, dyn[idx].d_val); - break; - case DT_RELA: - iDllData->iRela = ELFADDR(Elf32_Rela, dyn, dyn[idx].d_val); - break; - case DT_RELASZ: - iDllData->iRelaSz = dyn[idx].d_val; - break; - case DT_RELAENT: - iDllData->iRelaSz = dyn[idx].d_val; - break; - case DT_STRSZ: - iDllData->iDynStrTabSize = dyn[idx].d_val; - break; - case DT_ARM_SYMTABSZ_21: //For RVCT2.1 - //iDllData->iDynSymTabSize = dyn[idx].d_val; - case DT_ARM_SYMTABSZ: - /* This is same as DT_ARM_SYMTABSZ_21, but for RVCT 2.2 - * The tag value has been changed for RVC2.2 from RVCT2.1. - * We just ignore this. i.e., we get the symbol table size - * from the nchain field of the hash table as noted in section - * 3.2.2.2 of the BPABI. - */ - break; - case DT_SYMENT: - iDllData->iSymSize = dyn[idx].d_val; - break; - case DT_SONAME: - soNameOffset = dyn[idx].d_val; - break; - case DT_REL: - iDllData->iRel = ELFADDR(Elf32_Rel, dyn, dyn[idx].d_val); - break; - case DT_RELSZ: - iDllData->iRelSz = dyn[idx].d_val; - break; - case DT_RELENT: - iDllData->iRelEnt = dyn[idx].d_val; - break; - case DT_NEEDED: - iDllData->AddToDependency(dyn[idx].d_val); - break; - case DT_PLTRELSZ: - case DT_PLTGOT: - case DT_INIT: - case DT_FINI: - case DT_RPATH: - case DT_SYMBOLIC: - case DT_PLTREL: - case DT_DEBUG: - case DT_TEXTREL: - case DT_JMPREL: - case DT_BIND_NOW: - break; - default: - Print(EPeError,"Unrecognized Dyn Array tag in image '%s'.\n", iFileName); - return EFalse; - } - idx++; - } - return iDllData->Init(); - } - - -void ELFFile::Close() -// -// close the ELF file -// - { - HFile::Close(iFileHandle); - } - - - -TInt ELFFile::NumberOfImports() const -// -// Count the total number of imports for this image -// - { - return iDllData->NumberOfImports(); - } - -TInt ELFFile::NumberOfImportDlls() const -// -// Count the number of referenced Dlls -// - { - return iDllData->NumberOfImportDlls(); - } - -TInt ELFFile::NumberOfExports() const -// -// Count the number of exported symbols -// - { - return iDllData->NumberOfExports(); - } - -TInt ELFFile::NumberOfCodeRelocs() - { - return iDllData->NumberOfCodeRelocs(); - } - -TInt ELFFile::NumberOfDataRelocs() - { - return iDllData->NumberOfDataRelocs(); - } - -Elf32_Phdr * ELFFile::GetSegmentFromAddr(Elf32_Addr addr) - { - TInt nphdrs = iElfFile->e_phnum; - for (TInt idx = 0; idx < nphdrs; idx++) - { - // take advantage of unsignedness - if ((addr - iPhdr[idx].p_vaddr) < iPhdr[idx].p_memsz) return &iPhdr[idx]; - } - return NULL; - } - - -TInt ELFFile::NumberOfRelocs() - { - return iDllData->NumberOfRelocs(); - } - -TUint16 ELFFile::GetRelocType(Elf32_Rel *aReloc) - { - // We work out the type by figuring out the segment of the reloc - TInt segmentIdx = ELF32_R_SYM(aReloc->r_info); - - // check to see if its a reserved or special index. - if ((!segmentIdx) || ((segmentIdx >= SHN_LORESERVE) && (segmentIdx <= SHN_HIRESERVE))) - // up until now these have been treated as KInferredRelocType, so lets continue... - return KInferredRelocType; - - // need to see if this section is executable or writable - if (iPhdr[segmentIdx-1].p_flags & PF_X) - return KTextRelocType; - if (iPhdr[segmentIdx-1].p_flags & PF_W) - return KDataRelocType; - // perhaps we should error here. - return KInferredRelocType; - } - -TBool ELFFile::GetRelocs(Elf32_Rel **aCodeRelocs, Elf32_Rel **aDataRelocs) - { - return iDllData->GetRelocs(aCodeRelocs, aDataRelocs); - } - -TUint ELFFile::GetCodeSize() - { - return iCodeSegmentHdr->p_filesz; - } - -TBool ELFFile::HasInitialisedData() - { - return iDataSegmentHdr != NULL && iDataSegmentHdr->p_filesz != 0; - } - -TUint ELFFile::GetDataSize() - { - return iDataSegmentHdr != NULL ? iDataSegmentHdr->p_filesz : 0; - } - -TBool ELFFile::HasBssData() - { - return iDataSegmentHdr != NULL && (iDataSegmentHdr->p_memsz - iDataSegmentHdr->p_filesz) != 0; - } - -TUint ELFFile::GetBssSize() - { - return iDataSegmentHdr != NULL ? iDataSegmentHdr->p_memsz - iDataSegmentHdr->p_filesz: 0; - } - - - - - - -TBool ELFFile::IsValidFileHeader(Elf32_Ehdr * iElfFile) - { - if (!(iElfFile->e_ident[EI_MAG0] == ELFMAG0 && - iElfFile->e_ident[EI_MAG1] == ELFMAG1 && - iElfFile->e_ident[EI_MAG2] == ELFMAG2 && - iElfFile->e_ident[EI_MAG3] == ELFMAG3)) - { - Print(EPeError,"Invalid ELF magic.\n"); - return EFalse; - } - - if (iElfFile->e_ident[EI_CLASS] != ELFCLASS32) - { - Print(EPeError,"File is not a 32 bit object file.\n"); - return EFalse; - } - if (iElfFile->e_ident[EI_DATA] != ELFDATA2LSB) - { - Print(EPeError,"File data encoding is not Little Endian.\n"); - return EFalse; - } - - if (iElfFile->e_machine != EM_ARM) - { - Print(EPeError,"File does not target ARM/THUMB processors.\n"); - return EFalse; - } - - if (!(iElfFile->e_type == ET_EXEC || iElfFile->e_type == ET_DYN)) - { - Print(EPeError,"File is neither an executable nor a shared object\n"); - return EFalse; - } - - return ETrue; - } - - -// Get details of the next import to fix-up in the current file. Fill in the name of the dll -//it is imported from, the ordinal number and the address to write back to. -#define ORDINAL_DONE 0x40000000 - - -// The following static functions are passed an array of PE files to operate on - -Elf32_Sym * ELFFile::FindSymbol(const TText *aName) - { - Elf32_Shdr * s = ELFADDR(Elf32_Shdr, iElfFile, iElfFile->e_shoff); - TInt symIdx = iSymIdx; - Elf32_Sym * sym = iSymTab; - TInt nSyms = s[symIdx].sh_size / s[symIdx].sh_entsize; - char * symStringtable = ELFADDR(char, iElfFile, s[s[symIdx].sh_link].sh_offset); - for (TInt jdx = 0; jdx < nSyms; jdx++) - { - if (!strcmp(&symStringtable[sym[jdx].st_name], (char *)aName)) - return &sym[jdx]; - } - return (Elf32_Sym *)0; - } - -TBool ELFFile::SymbolPresent(TText *aName) - { - return (FindSymbol(aName) != 0); - } - -TBool ELFFile::GetExceptionIndexInfo(TUint32 &aOffset) - { - const TText * aBase = (TText *)".ARM.exidx$$Base"; - const TText * aLimit = (TText *)".ARM.exidx$$Limit"; - Elf32_Sym * exidxBase = FindSymbol(aBase); - Elf32_Sym * exidxLimit = FindSymbol(aLimit); - if (exidxBase && exidxLimit && (exidxLimit->st_value - exidxBase->st_value)) - { - const TText * aExceptionDescriptor = (TText *)"Symbian$$CPP$$Exception$$Descriptor"; - Elf32_Sym * aED = FindSymbol(aExceptionDescriptor); - if (aED) - { - // Set bottom bit so 0 in header slot means an old binary. - // The decriptor is always aligned on a 4 byte boundary. - aOffset = (aED->st_value - iLinkedBase) | 0x00000001; - return ETrue; - } - else - { - Print(EPeError,"Executable has exception table but no exception descriptor\n"); - exit(666); - } - } - return EFalse; - } - -TBool ELFFile::SetUpLookupTable() -{ - if(!iDllData->CreateSymLookupTable() ) { - Print(EPeError,"Failed to create named symbol lookup information\n"); - return FALSE; - } - if(!iDllData->CreateDependency()){ - Print(EPeError,"Failed to create dependency ordering for named symbol lookup\n"); - return FALSE; - } - - iDllData->SetExportSymInfo(); - return TRUE; -} - -void ELFFile::GetExportSymInfoHeader(E32EpocExpSymInfoHdr& aSymInfoHdr) -{ - iDllData->GetExportSymInfoHeader(aSymInfoHdr); -} - -void ELFFile::SetLookupTblBase(TInt aBaseOffset) -{ - iDllData->SetLookupTblBase(aBaseOffset); -} - -TInt ELFFile::GetLookupTblSize() -{ - return iDllData->GetLookupTblSize(); -} - -TUint ELFFile::GetSymLookupSection(char* aBuff) -{ - return iDllData->GetSymLookupSection(aBuff); -} - +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +#include +#include +#include "elftran.h" +#include "elfdefs.h" +#include "elffile.h" +#include "elfdll.h" +#include "h_utl.h" +#include +#include + +TBool hadText, hadReloc = EFalse; + +ELFFile::ELFFile() + : iHeapCommittedSize(0x1000), iHeapReservedSize(0x100000), iStackCommittedSize(0), + iFileName(0), iFileHandle(-1) , iElfFile(0), + iDynamicSegmentHdr(0), iDynamicSegmentIdx(0), + iCodeSegmentHdr(0), iCodeSegmentIdx(0), + iDataSegmentHdr(0), iDataSegmentIdx(0), + iDllData(0), iCpu(ECpuUnknown) + {} + +ELFFile::~ELFFile() + // + // Destructor + // + { + if(iFileName) + delete [] iFileName; + delete iElfFile; + delete iDllData; + } + + +TBool ELFFile::Init(const char* aFileName) +// +// Read the ELF file into memory +// + { + if(iFileName){ + delete [] iFileName; + iFileName = 0; + } + size_t length = strlen(aFileName) + 1 ; + iFileName = new char[length]; + memcpy (iFileName, aFileName,length); + + TInt error = HFile::Open(iFileName, &iFileHandle); + if (error!=0) + return EFalse; + + TInt flength = HFile::GetLength(iFileHandle); + + iElfFile = (Elf32_Ehdr *)HMem::Alloc(0,flength); + if (!iElfFile) + { + Print(EPeError,"Failed to allocate memory to read in file.\n"); + Close(); + return EFalse; + } + + if (!HFile::Read(iFileHandle,iElfFile,flength)) + { + Print(EPeError,"Unable to read file %s.\n",iFileName); + Close(); + return EFalse; + } + + Close(); + + if (!IsValidFileHeader(iElfFile)) + { + Print(EPeError,"Invalid file header.\n"); + return EFalse; + } + // we only support this....for the moment + iCpu = ECpuArmV4; + + if (!InitHeaders()) return EFalse; + + if (!InitDllData()) return EFalse; + + iEntryPoint = iElfFile->e_entry; + + iCodeSize = GetCodeSize(); + iDataSize = GetDataSize(); + iBssSize = GetBssSize(); + + iStackReservedSize = 0x2000; + iStackCommittedSize = 0x2000; + + iLinkedBase = iCodeSegmentHdr->p_vaddr; + + iImageIsDll = iDllData->ImageIsDll(); + + return ETrue; + } + +char * ELFFile::CreateImportSection(TInt &aSize) +// +// get ELFDLLData to do it +// + { + TInt size; + char * newSection = iDllData->CreateImportSection(size); + aSize = size; + return newSection; + } + +TUint ELFFile::GetExportTableOffset(void) + { + return iDllData->GetExportTableOffset(); + } + +TBool ELFFile::InitHeaders(void) + { + TInt nphdrs = iElfFile->e_phnum; + if (nphdrs) + { + // Find the dynamic segment + Elf32_Phdr * aPhdr = ELFADDR(Elf32_Phdr, iElfFile, iElfFile->e_phoff); + iPhdr = aPhdr; + for (TInt idx = 0; idx < nphdrs; idx++) + { + Elf32_Word ptype = aPhdr[idx].p_type; + if (ptype == PT_DYNAMIC) + { + iDynamicSegmentHdr = &aPhdr[idx]; + iDynamicSegmentIdx = idx; + } + else if (ptype == PT_LOAD && + (aPhdr[idx].p_flags & (PF_X + PF_ARM_ENTRY))) + { + iCodeSegmentHdr = &aPhdr[idx]; + iCodeSegmentIdx = idx; + } + else if (ptype == PT_LOAD && + (aPhdr[idx].p_flags & (PF_W + PF_R))) + { + iDataSegmentHdr = &aPhdr[idx]; + iDataSegmentIdx = idx; + } + } + } + + // cache pointer to symbol table + + // Get section header table + Elf32_Shdr * s = ELFADDR(Elf32_Shdr, iElfFile, iElfFile->e_shoff); + // Index of section header for section header string table + TInt stIdx = iElfFile->e_shstrndx; + TInt symIdx = -1; + // Section name string table + char * stringtable = ELFADDR(char, iElfFile, s[stIdx].sh_offset); + // the index at which we find '.symtab' is the index of the symtab section + for (TInt idx = 0; idx < iElfFile->e_shnum; idx++) + { + if (idx != stIdx) + { + if (!strcmp(&stringtable[s[idx].sh_name], ".symtab")) + { + symIdx = idx; + break; + } + } + } + if (symIdx == -1) return EFalse; + + // save section header table + iSectionHeaderTable = s; + // save the index + iSymIdx = symIdx; + // here's the symbol table + iSymTab = ELFADDR(Elf32_Sym, iElfFile, s[symIdx].sh_offset); + return ETrue; + } + +TBool ELFFile::InitDllData(void) + { + if (!iDynamicSegmentHdr) + { +#if defined(_DEBUG) + Print(EWarning, "Image '%s' has no import/export data.\n", iFileName); +#endif + return ETrue; + } + iDllData = new ELFDllData(this); + if (!iDllData) + { + Print(EPeError, "Out of memory allocating DLL data\n"); + return EFalse; + } + + Elf32_Dyn * dyn = ELFADDR(Elf32_Dyn, iElfFile, iDynamicSegmentHdr->p_offset); + TInt idx = 0; + TInt soNameOffset = 0; + while(dyn[idx].d_tag != DT_NULL) // best to make it explicit + { + switch (dyn[idx].d_tag) + { + case DT_HASH: + iDllData->iHashTable = ELFADDR(Elf32_HashTable, dyn, dyn[idx].d_val); + break; + case DT_STRTAB: + iDllData->iDynStrTab = ELFADDR(char, dyn, dyn[idx].d_val); + break; + case DT_SYMTAB: + iDllData->iDynSymTab = ELFADDR(Elf32_Sym, dyn, dyn[idx].d_val); + break; + case DT_RELA: + iDllData->iRela = ELFADDR(Elf32_Rela, dyn, dyn[idx].d_val); + break; + case DT_RELASZ: + iDllData->iRelaSz = dyn[idx].d_val; + break; + case DT_RELAENT: + iDllData->iRelaSz = dyn[idx].d_val; + break; + case DT_STRSZ: + iDllData->iDynStrTabSize = dyn[idx].d_val; + break; + case DT_ARM_SYMTABSZ_21: //For RVCT2.1 + //iDllData->iDynSymTabSize = dyn[idx].d_val; + case DT_ARM_SYMTABSZ: + /* This is same as DT_ARM_SYMTABSZ_21, but for RVCT 2.2 + * The tag value has been changed for RVC2.2 from RVCT2.1. + * We just ignore this. i.e., we get the symbol table size + * from the nchain field of the hash table as noted in section + * 3.2.2.2 of the BPABI. + */ + break; + case DT_SYMENT: + iDllData->iSymSize = dyn[idx].d_val; + break; + case DT_SONAME: + soNameOffset = dyn[idx].d_val; + break; + case DT_REL: + iDllData->iRel = ELFADDR(Elf32_Rel, dyn, dyn[idx].d_val); + break; + case DT_RELSZ: + iDllData->iRelSz = dyn[idx].d_val; + break; + case DT_RELENT: + iDllData->iRelEnt = dyn[idx].d_val; + break; + case DT_NEEDED: + iDllData->AddToDependency(dyn[idx].d_val); + break; + case DT_PLTRELSZ: + case DT_PLTGOT: + case DT_INIT: + case DT_FINI: + case DT_RPATH: + case DT_SYMBOLIC: + case DT_PLTREL: + case DT_DEBUG: + case DT_TEXTREL: + case DT_JMPREL: + case DT_BIND_NOW: + break; + default: + Print(EPeError,"Unrecognized Dyn Array tag in image '%s'.\n", iFileName); + return EFalse; + } + idx++; + } + return iDllData->Init(); + } + + +void ELFFile::Close() +// +// close the ELF file +// + { + HFile::Close(iFileHandle); + } + + + +TInt ELFFile::NumberOfImports() const +// +// Count the total number of imports for this image +// + { + return iDllData->NumberOfImports(); + } + +TInt ELFFile::NumberOfImportDlls() const +// +// Count the number of referenced Dlls +// + { + return iDllData->NumberOfImportDlls(); + } + +TInt ELFFile::NumberOfExports() const +// +// Count the number of exported symbols +// + { + return iDllData->NumberOfExports(); + } + +TInt ELFFile::NumberOfCodeRelocs() + { + return iDllData->NumberOfCodeRelocs(); + } + +TInt ELFFile::NumberOfDataRelocs() + { + return iDllData->NumberOfDataRelocs(); + } + +Elf32_Phdr * ELFFile::GetSegmentFromAddr(Elf32_Addr addr) + { + TInt nphdrs = iElfFile->e_phnum; + for (TInt idx = 0; idx < nphdrs; idx++) + { + // take advantage of unsignedness + if ((addr - iPhdr[idx].p_vaddr) < iPhdr[idx].p_memsz) return &iPhdr[idx]; + } + return NULL; + } + + +TInt ELFFile::NumberOfRelocs() + { + return iDllData->NumberOfRelocs(); + } + +TUint16 ELFFile::GetRelocType(Elf32_Rel *aReloc) + { + // We work out the type by figuring out the segment of the reloc + TInt segmentIdx = ELF32_R_SYM(aReloc->r_info); + + // check to see if its a reserved or special index. + if ((!segmentIdx) || ((segmentIdx >= SHN_LORESERVE) && (segmentIdx <= SHN_HIRESERVE))) + // up until now these have been treated as KInferredRelocType, so lets continue... + return KInferredRelocType; + + // need to see if this section is executable or writable + if (iPhdr[segmentIdx-1].p_flags & PF_X) + return KTextRelocType; + if (iPhdr[segmentIdx-1].p_flags & PF_W) + return KDataRelocType; + // perhaps we should error here. + return KInferredRelocType; + } + +TBool ELFFile::GetRelocs(Elf32_Rel **aCodeRelocs, Elf32_Rel **aDataRelocs) + { + return iDllData->GetRelocs(aCodeRelocs, aDataRelocs); + } + +TUint ELFFile::GetCodeSize() + { + return iCodeSegmentHdr->p_filesz; + } + +TBool ELFFile::HasInitialisedData() + { + return iDataSegmentHdr != NULL && iDataSegmentHdr->p_filesz != 0; + } + +TUint ELFFile::GetDataSize() + { + return iDataSegmentHdr != NULL ? iDataSegmentHdr->p_filesz : 0; + } + +TBool ELFFile::HasBssData() + { + return iDataSegmentHdr != NULL && (iDataSegmentHdr->p_memsz - iDataSegmentHdr->p_filesz) != 0; + } + +TUint ELFFile::GetBssSize() + { + return iDataSegmentHdr != NULL ? iDataSegmentHdr->p_memsz - iDataSegmentHdr->p_filesz: 0; + } + + + + + + +TBool ELFFile::IsValidFileHeader(Elf32_Ehdr * iElfFile) + { + if (!(iElfFile->e_ident[EI_MAG0] == ELFMAG0 && + iElfFile->e_ident[EI_MAG1] == ELFMAG1 && + iElfFile->e_ident[EI_MAG2] == ELFMAG2 && + iElfFile->e_ident[EI_MAG3] == ELFMAG3)) + { + Print(EPeError,"Invalid ELF magic.\n"); + return EFalse; + } + + if (iElfFile->e_ident[EI_CLASS] != ELFCLASS32) + { + Print(EPeError,"File is not a 32 bit object file.\n"); + return EFalse; + } + if (iElfFile->e_ident[EI_DATA] != ELFDATA2LSB) + { + Print(EPeError,"File data encoding is not Little Endian.\n"); + return EFalse; + } + + if (iElfFile->e_machine != EM_ARM) + { + Print(EPeError,"File does not target ARM/THUMB processors.\n"); + return EFalse; + } + + if (!(iElfFile->e_type == ET_EXEC || iElfFile->e_type == ET_DYN)) + { + Print(EPeError,"File is neither an executable nor a shared object\n"); + return EFalse; + } + + return ETrue; + } + + +// Get details of the next import to fix-up in the current file. Fill in the name of the dll +//it is imported from, the ordinal number and the address to write back to. +#define ORDINAL_DONE 0x40000000 + + +// The following static functions are passed an array of PE files to operate on + +Elf32_Sym * ELFFile::FindSymbol(const char* aName) + { + Elf32_Shdr * s = ELFADDR(Elf32_Shdr, iElfFile, iElfFile->e_shoff); + TInt symIdx = iSymIdx; + Elf32_Sym * sym = iSymTab; + TInt nSyms = s[symIdx].sh_size / s[symIdx].sh_entsize; + char * symStringtable = ELFADDR(char, iElfFile, s[s[symIdx].sh_link].sh_offset); + for (TInt jdx = 0; jdx < nSyms; jdx++) + { + if (!strcmp(&symStringtable[sym[jdx].st_name], (char *)aName)) + return &sym[jdx]; + } + return (Elf32_Sym *)0; + } + +TBool ELFFile::SymbolPresent(const char* aName) + { + return (FindSymbol(aName) != 0); + } + +TBool ELFFile::GetExceptionIndexInfo(TUint32 &aOffset) + { + Elf32_Sym * exidxBase = FindSymbol(".ARM.exidx$$Base"); + Elf32_Sym * exidxLimit = FindSymbol(".ARM.exidx$$Limit"); + if (exidxBase && exidxLimit && (exidxLimit->st_value - exidxBase->st_value)) + { + Elf32_Sym * aED = FindSymbol("Symbian$$CPP$$Exception$$Descriptor"); + if (aED) + { + // Set bottom bit so 0 in header slot means an old binary. + // The decriptor is always aligned on a 4 byte boundary. + aOffset = (aED->st_value - iLinkedBase) | 0x00000001; + return ETrue; + } + else + { + Print(EPeError,"Executable has exception table but no exception descriptor\n"); + exit(666); + } + } + return EFalse; + } + +TBool ELFFile::SetUpLookupTable() +{ + if(!iDllData->CreateSymLookupTable() ) { + Print(EPeError,"Failed to create named symbol lookup information\n"); + return FALSE; + } + if(!iDllData->CreateDependency()){ + Print(EPeError,"Failed to create dependency ordering for named symbol lookup\n"); + return FALSE; + } + + iDllData->SetExportSymInfo(); + return TRUE; +} + +void ELFFile::GetExportSymInfoHeader(E32EpocExpSymInfoHdr& aSymInfoHdr) +{ + iDllData->GetExportSymInfoHeader(aSymInfoHdr); +} + +void ELFFile::SetLookupTblBase(TInt aBaseOffset) +{ + iDllData->SetLookupTblBase(aBaseOffset); +} + +TInt ELFFile::GetLookupTblSize() +{ + return iDllData->GetLookupTblSize(); +} + +TUint ELFFile::GetSymLookupSection(char* aBuff) +{ + return iDllData->GetSymLookupSection(aBuff); +} + diff -r 122d2b873fd1 -r 30b30f9da0b7 bintools/elftools/elftran/elf_imp.cpp --- a/bintools/elftools/elftran/elf_imp.cpp Fri Jun 25 20:58:33 2010 +0800 +++ b/bintools/elftools/elftran/elf_imp.cpp Tue Jun 29 14:52:54 2010 +0800 @@ -1,39 +1,39 @@ -/* -* Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of the License "Eclipse Public License v1.0" -* which accompanies this distribution, and is available -* at the URL "http://www.eclipse.org/legal/epl-v10.html". -* -* Initial Contributors: -* Nokia Corporation - initial contribution. -* -* Contributors: -* -* Description: -* -*/ - - -#include -#include -#include -#include -#include "e32ldfmt.h" -#include "elftran.h" -#include "elffile.h" - -char* E32ImageFile_ELF::CreateImportSection(ELFFile& aElfFile, TInt& aSize) -// -// get the ELFFile to do it for us. -// - { - TInt size; - char * newSection = aElfFile.CreateImportSection(size); - aSize = size; - return newSection; - } - - - +/* +* Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#include +#include +#include +#include "h_utl.h" +#include "e32ldfmt.h" +#include "elftran.h" +#include "elffile.h" + +char* E32ImageFile_ELF::CreateImportSection(ELFFile& aElfFile, TInt& aSize) +// +// get the ELFFile to do it for us. +// + { + TInt size; + char * newSection = aElfFile.CreateImportSection(size); + aSize = size; + return newSection; + } + + + diff -r 122d2b873fd1 -r 30b30f9da0b7 bintools/elftools/elftran/elf_tran.cpp --- a/bintools/elftools/elftran/elf_tran.cpp Fri Jun 25 20:58:33 2010 +0800 +++ b/bintools/elftools/elftran/elf_tran.cpp Tue Jun 29 14:52:54 2010 +0800 @@ -1,301 +1,301 @@ -/* -* Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of the License "Eclipse Public License v1.0" -* which accompanies this distribution, and is available -* at the URL "http://www.eclipse.org/legal/epl-v10.html". -* -* Initial Contributors: -* Nokia Corporation - initial contribution. -* -* Contributors: -* -* Description: -* -*/ - - -#include -#include -#include -#include "elftran.h" -#include -#include -#include "elffile.h" -#include -#include - -extern TUid gUid1, gUid2, gUid3; -extern int gSetUid1, gSetUid2, gSetUid3; - -int gAlignConstSection=FALSE; -TUint gConstSectionAddressMask=0; - -E32ImageFile* E32ImageFile::New() - { - return new E32ImageFile_ELF; - } - -E32ImageFile_ELF::E32ImageFile_ELF() - { - } - -E32ImageFile_ELF::~E32ImageFile_ELF() - { - } - -TInt E32ImageFile_ELF::DoCodeHeader(ELFFile &aElfFile) -// -// Calculate the code parts of the ELFFile -// - { - - TInt size=ALIGN4(aElfFile.GetCodeSize()); - iHdr->iCodeSize = iHdr->iTextSize = size; - // make it the offset from the beginning of the file..... - if(iHdr->iExportDirCount==0) - iHdr->iExportDirOffset = 0; - else - iHdr->iExportDirOffset = aElfFile.GetExportTableOffset() + iHdr->iCodeOffset; - - return size; - } - -TInt E32ImageFile_ELF::DoDataHeader(ELFFile &aElfFile, TUint aDataBase) - { - - if (aDataBase==0 && aElfFile.iDataSegmentHdr) - aDataBase=aElfFile.iDataSegmentHdr->p_vaddr; - TInt size=0; - - iHdr->iDataBase=aDataBase; - - if (aElfFile.HasInitialisedData()) - { - size=ALIGN4(aElfFile.GetDataSize()); - iHdr->iDataOffset = iHdr->iCodeOffset + iHdr->iCodeSize; - iHdr->iDataSize = size; - } - if (aElfFile.HasBssData()) - { - iHdr->iBssSize = ALIGN4(aElfFile.GetBssSize()); - } - return size; - } - -TInt E32ImageFile_ELF::CopyCode(char *p, ELFFile &aElfFile) -// -// Copies the files code sections to p -// returns the number of bytes copied or KErrGeneral -// - { - TInt size=aElfFile.GetCodeSize(); - memcpy(p, (char *)aElfFile.GetCode(), size); - p+=ALIGN4(size); - return iHdr->iCodeSize = size; - } - -TInt E32ImageFile_ELF::CopyData(char *p, ELFFile &aElfFile) - { - TInt size=aElfFile.GetDataSize(); - if (size) memcpy(p, (char *)aElfFile.GetData(), size); - return size; - } - -TInt E32ImageFile_ELF::Translate(const char* aFileName, TUint aDataBase, TBool aAllowDllData, \ - TBool aSymLkupEnabled) -// -// Translate a ELF format file to a E32Image file -// - -{ - iSource = EElfFile; - ELFFile elffile; - if (!elffile.Init((const TText * const)aFileName)) return KErrGeneral; - - iFileName = strdup(aFileName); - - Adjust(ALIGN4(sizeof(E32ImageHeaderV))); // fixed for now because holes not supported - SetDefaultHeader(); - iHdr->iDllRefTableCount = elffile.NumberOfImportDlls(); - iHdr->iExportDirCount = elffile.NumberOfExports(); - iHdr->iCodeBase = elffile.iLinkedBase; - - if(aSymLkupEnabled) - { - if( !SetUpLookupTable(elffile) ) - return KErrGeneral; - } - - - TInt size = ALIGN4(sizeof(E32ImageHeaderV)); // fixed for now because holes not supported - iHdr->iCodeOffset = size; - TInt pos = size; - size+=DoCodeHeader(elffile); - - size += DoSymbolLookupHeader(elffile, size - pos); - - TInt nimports=elffile.NumberOfImports(); - TInt importSectionSize; - char *newImportSection=CreateImportSection(elffile, importSectionSize); - - TInt t=DoDataHeader(elffile, aDataBase); - if (t>0) - { - iHdr->iDataOffset = size; - size += t; - } - if (importSectionSize!=0) - { - iHdr->iImportOffset=size; - size+=ALIGN4(importSectionSize); - } - - char *newCodeRelocs=NULL; - char *newDataRelocs=NULL; - TInt codeRelocSize=0, dataRelocSize=0; - TInt nCodeRelocs=elffile.NumberOfCodeRelocs(); - TInt nDataRelocs=elffile.NumberOfDataRelocs(); - if (nCodeRelocs + nDataRelocs) - { - Elf32_Rel **codeRelocs=new Elf32_Rel * [nCodeRelocs]; - Elf32_Rel **dataRelocs=new Elf32_Rel * [nDataRelocs]; - if (!elffile.GetRelocs(codeRelocs, dataRelocs)) return KErrGeneral; - - FixRelocs(elffile, codeRelocs, dataRelocs); - if (elffile.iCodeSegmentHdr) - newCodeRelocs=CreateRelocs(elffile, codeRelocs, nCodeRelocs, codeRelocSize, elffile.iCodeSegmentHdr->p_vaddr); - if (elffile.iDataSegmentHdr) - newDataRelocs=CreateRelocs(elffile, dataRelocs, nDataRelocs, dataRelocSize, elffile.iDataSegmentHdr->p_vaddr); - if (codeRelocSize) - { - iHdr->iCodeRelocOffset = size; - size += codeRelocSize; - } - if (dataRelocSize) - { - iHdr->iDataRelocOffset = size; - size += dataRelocSize; - } - delete [] codeRelocs; - delete [] dataRelocs; - } - - Adjust(size); - t=CopyCode(iData + pos, elffile); - if (t<0) - return KErrGeneral; - pos += t; - t = CopyExportSymInfo(iData+pos, elffile); - if (t<0) - return KErrGeneral; - pos += t; - - pos += CopyData(iData + pos, elffile); - if (nimports) - { - memcpy(iData + pos, newImportSection, importSectionSize); - pos += ALIGN4(importSectionSize); - } - if (codeRelocSize) - { - memcpy(iData + pos, newCodeRelocs, codeRelocSize); - pos += codeRelocSize; - } - if (dataRelocSize) - { - memcpy(iData + pos, newDataRelocs, dataRelocSize); - pos += dataRelocSize; - } - - // locate the entry point - TUint entryPointOffset=elffile.GetEntryPointOffset(); - - // Arrange a header for this E32 Image - iHdr->iCpuIdentifier = (TUint16)ECpuArmV4; - // Import format is ELF-derived - iHdr->iFlags |= KImageImpFmt_ELF; - // ABI is ARM EABI - iHdr->iFlags |= KImageABI_EABI; - if (ImageIsDll(elffile)) - { - iHdr->iFlags |= KImageDll; - if (iHdr->iDataSize && !aAllowDllData) - return Print(EError, "Dll '%s' has initialised data.\n", iFileName); - if (iHdr->iBssSize && !aAllowDllData) - return Print(EError, "Dll '%s' has uninitialised data.\n", iFileName); - } - iHdr->iHeapSizeMin = elffile.iHeapCommittedSize; - iHdr->iHeapSizeMax = elffile.iHeapReservedSize; - iHdr->iStackSize = elffile.iStackCommittedSize; - iHdr->iEntryPoint = entryPointOffset; - TInt r = DetermineEntryPointType(); - if (r == KErrCorrupt) - return Print(EError, "File '%s': Bad Entry Point.\n", iFileName); - else if (r == KErrNotSupported) - return Print(EError, "File '%s': Bad Entry Point Type.\n", iFileName); - - SetUpExceptions(elffile); - - delete [] newImportSection; - delete [] newCodeRelocs; - delete [] newDataRelocs; - - return KErrNone; - } - -TBool E32ImageFile_ELF::Translate(ELFFile &aElfFile) - { - // VT fix for warning - // fix warning in Linux - return Translate((const char*)aElfFile.iFileName, 0, EFalse); - } - -TBool E32ImageFile_ELF::ImageIsDll(ELFFile& aElfFile) - { - return aElfFile.ImageIsDll(); - } - -void E32ImageFile_ELF::SetUpExceptions(ELFFile &aElfFile) - { - aElfFile.GetExceptionIndexInfo(iHdr->iExceptionDescriptor); - } - -void E32ImageFile_ELF::SetSymNameLookup(TInt aSymNameLkupEnabled) - { - if(aSymNameLkupEnabled) - iHdr->iFlags |= KImageNmdExpData; - else - iHdr->iFlags &= ~KImageNmdExpData; - } -TBool E32ImageFile_ELF::IsNamedLookupEnabled() -{ - return (iHdr->iFlags & KImageNmdExpData); -} - -TBool E32ImageFile_ELF::SetUpLookupTable(ELFFile &aElfFile) -// Symbol lookup by name is enabled. Create the symbol table with names -// and their values. -{ - if(!aElfFile.SetUpLookupTable() ) - return FALSE; - SetSymNameLookup(TRUE); - return TRUE; -} - -// Build the infrastructure for symbol lookup via name -TInt E32ImageFile_ELF::DoSymbolLookupHeader(ELFFile &aElfFile, TInt aBaseOffset) - { - if(!IsNamedLookupEnabled()) - return 0; - - aElfFile.SetLookupTblBase(aBaseOffset); - return aElfFile.GetLookupTblSize(); - } -TUint E32ImageFile_ELF::CopyExportSymInfo(char *p, ELFFile &aElfFile) - { - iHdr->iCodeSize += aElfFile.GetLookupTblSize(); - iHdr->iTextSize = iHdr->iCodeSize ; - return aElfFile.GetSymLookupSection(p); - } +/* +* Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#include +#include +#include +#include "elftran.h" +#include +#include "elfdefs.h" +#include "elffile.h" +#include "h_ver.h" +#include "h_utl.h" + +extern TUid gUid1, gUid2, gUid3; +extern int gSetUid1, gSetUid2, gSetUid3; + +int gAlignConstSection=FALSE; +TUint gConstSectionAddressMask=0; + +E32ImageFile* E32ImageFile::New() + { + return new E32ImageFile_ELF; + } + +E32ImageFile_ELF::E32ImageFile_ELF() + { + } + +E32ImageFile_ELF::~E32ImageFile_ELF() + { + } + +TInt E32ImageFile_ELF::DoCodeHeader(ELFFile &aElfFile) +// +// Calculate the code parts of the ELFFile +// + { + + TInt size=ALIGN4(aElfFile.GetCodeSize()); + iHdr->iCodeSize = iHdr->iTextSize = size; + // make it the offset from the beginning of the file..... + if(iHdr->iExportDirCount==0) + iHdr->iExportDirOffset = 0; + else + iHdr->iExportDirOffset = aElfFile.GetExportTableOffset() + iHdr->iCodeOffset; + + return size; + } + +TInt E32ImageFile_ELF::DoDataHeader(ELFFile &aElfFile, TUint aDataBase) + { + + if (aDataBase==0 && aElfFile.iDataSegmentHdr) + aDataBase=aElfFile.iDataSegmentHdr->p_vaddr; + TInt size=0; + + iHdr->iDataBase=aDataBase; + + if (aElfFile.HasInitialisedData()) + { + size=ALIGN4(aElfFile.GetDataSize()); + iHdr->iDataOffset = iHdr->iCodeOffset + iHdr->iCodeSize; + iHdr->iDataSize = size; + } + if (aElfFile.HasBssData()) + { + iHdr->iBssSize = ALIGN4(aElfFile.GetBssSize()); + } + return size; + } + +TInt E32ImageFile_ELF::CopyCode(char *p, ELFFile &aElfFile) +// +// Copies the files code sections to p +// returns the number of bytes copied or KErrGeneral +// + { + TInt size=aElfFile.GetCodeSize(); + memcpy(p, (char *)aElfFile.GetCode(), size); + p+=ALIGN4(size); + return iHdr->iCodeSize = size; + } + +TInt E32ImageFile_ELF::CopyData(char *p, ELFFile &aElfFile) + { + TInt size=aElfFile.GetDataSize(); + if (size) memcpy(p, (char *)aElfFile.GetData(), size); + return size; + } + +TInt E32ImageFile_ELF::Translate(const char* aFileName, TUint aDataBase, TBool aAllowDllData, \ + TBool aSymLkupEnabled) +// +// Translate a ELF format file to a E32Image file +// + +{ + iSource = EElfFile; + ELFFile elffile; + if (!elffile.Init(aFileName)) return KErrGeneral; + + iFileName = strdup(aFileName); + + Adjust(ALIGN4(sizeof(E32ImageHeaderV))); // fixed for now because holes not supported + SetDefaultHeader(); + iHdr->iDllRefTableCount = elffile.NumberOfImportDlls(); + iHdr->iExportDirCount = elffile.NumberOfExports(); + iHdr->iCodeBase = elffile.iLinkedBase; + + if(aSymLkupEnabled) + { + if( !SetUpLookupTable(elffile) ) + return KErrGeneral; + } + + + TInt size = ALIGN4(sizeof(E32ImageHeaderV)); // fixed for now because holes not supported + iHdr->iCodeOffset = size; + TInt pos = size; + size+=DoCodeHeader(elffile); + + size += DoSymbolLookupHeader(elffile, size - pos); + + TInt nimports=elffile.NumberOfImports(); + TInt importSectionSize; + char *newImportSection=CreateImportSection(elffile, importSectionSize); + + TInt t=DoDataHeader(elffile, aDataBase); + if (t>0) + { + iHdr->iDataOffset = size; + size += t; + } + if (importSectionSize!=0) + { + iHdr->iImportOffset=size; + size+=ALIGN4(importSectionSize); + } + + char *newCodeRelocs=NULL; + char *newDataRelocs=NULL; + TInt codeRelocSize=0, dataRelocSize=0; + TInt nCodeRelocs=elffile.NumberOfCodeRelocs(); + TInt nDataRelocs=elffile.NumberOfDataRelocs(); + if (nCodeRelocs + nDataRelocs) + { + Elf32_Rel **codeRelocs=new Elf32_Rel * [nCodeRelocs]; + Elf32_Rel **dataRelocs=new Elf32_Rel * [nDataRelocs]; + if (!elffile.GetRelocs(codeRelocs, dataRelocs)) return KErrGeneral; + + FixRelocs(elffile, codeRelocs, dataRelocs); + if (elffile.iCodeSegmentHdr) + newCodeRelocs=CreateRelocs(elffile, codeRelocs, nCodeRelocs, codeRelocSize, elffile.iCodeSegmentHdr->p_vaddr); + if (elffile.iDataSegmentHdr) + newDataRelocs=CreateRelocs(elffile, dataRelocs, nDataRelocs, dataRelocSize, elffile.iDataSegmentHdr->p_vaddr); + if (codeRelocSize) + { + iHdr->iCodeRelocOffset = size; + size += codeRelocSize; + } + if (dataRelocSize) + { + iHdr->iDataRelocOffset = size; + size += dataRelocSize; + } + delete [] codeRelocs; + delete [] dataRelocs; + } + + Adjust(size); + t=CopyCode(iData + pos, elffile); + if (t<0) + return KErrGeneral; + pos += t; + t = CopyExportSymInfo(iData+pos, elffile); + if (t<0) + return KErrGeneral; + pos += t; + + pos += CopyData(iData + pos, elffile); + if (nimports) + { + memcpy(iData + pos, newImportSection, importSectionSize); + pos += ALIGN4(importSectionSize); + } + if (codeRelocSize) + { + memcpy(iData + pos, newCodeRelocs, codeRelocSize); + pos += codeRelocSize; + } + if (dataRelocSize) + { + memcpy(iData + pos, newDataRelocs, dataRelocSize); + pos += dataRelocSize; + } + + // locate the entry point + TUint entryPointOffset=elffile.GetEntryPointOffset(); + + // Arrange a header for this E32 Image + iHdr->iCpuIdentifier = (TUint16)ECpuArmV4; + // Import format is ELF-derived + iHdr->iFlags |= KImageImpFmt_ELF; + // ABI is ARM EABI + iHdr->iFlags |= KImageABI_EABI; + if (ImageIsDll(elffile)) + { + iHdr->iFlags |= KImageDll; + if (iHdr->iDataSize && !aAllowDllData) + return Print(EError, "Dll '%s' has initialised data.\n", iFileName); + if (iHdr->iBssSize && !aAllowDllData) + return Print(EError, "Dll '%s' has uninitialised data.\n", iFileName); + } + iHdr->iHeapSizeMin = elffile.iHeapCommittedSize; + iHdr->iHeapSizeMax = elffile.iHeapReservedSize; + iHdr->iStackSize = elffile.iStackCommittedSize; + iHdr->iEntryPoint = entryPointOffset; + TInt r = DetermineEntryPointType(); + if (r == KErrCorrupt) + return Print(EError, "File '%s': Bad Entry Point.\n", iFileName); + else if (r == KErrNotSupported) + return Print(EError, "File '%s': Bad Entry Point Type.\n", iFileName); + + SetUpExceptions(elffile); + + delete [] newImportSection; + delete [] newCodeRelocs; + delete [] newDataRelocs; + + return KErrNone; + } + +TBool E32ImageFile_ELF::Translate(ELFFile &aElfFile) + { + // VT fix for warning + // fix warning in Linux + return Translate((const char*)aElfFile.iFileName, 0, EFalse); + } + +TBool E32ImageFile_ELF::ImageIsDll(ELFFile& aElfFile) + { + return aElfFile.ImageIsDll(); + } + +void E32ImageFile_ELF::SetUpExceptions(ELFFile &aElfFile) + { + aElfFile.GetExceptionIndexInfo(iHdr->iExceptionDescriptor); + } + +void E32ImageFile_ELF::SetSymNameLookup(TInt aSymNameLkupEnabled) + { + if(aSymNameLkupEnabled) + iHdr->iFlags |= KImageNmdExpData; + else + iHdr->iFlags &= ~KImageNmdExpData; + } +TBool E32ImageFile_ELF::IsNamedLookupEnabled() +{ + return (iHdr->iFlags & KImageNmdExpData); +} + +TBool E32ImageFile_ELF::SetUpLookupTable(ELFFile &aElfFile) +// Symbol lookup by name is enabled. Create the symbol table with names +// and their values. +{ + if(!aElfFile.SetUpLookupTable() ) + return FALSE; + SetSymNameLookup(TRUE); + return TRUE; +} + +// Build the infrastructure for symbol lookup via name +TInt E32ImageFile_ELF::DoSymbolLookupHeader(ELFFile &aElfFile, TInt aBaseOffset) + { + if(!IsNamedLookupEnabled()) + return 0; + + aElfFile.SetLookupTblBase(aBaseOffset); + return aElfFile.GetLookupTblSize(); + } +TUint E32ImageFile_ELF::CopyExportSymInfo(char *p, ELFFile &aElfFile) + { + iHdr->iCodeSize += aElfFile.GetLookupTblSize(); + iHdr->iTextSize = iHdr->iCodeSize ; + return aElfFile.GetSymLookupSection(p); + } diff -r 122d2b873fd1 -r 30b30f9da0b7 bintools/elftools/getexports/geninf.cpp --- a/bintools/elftools/getexports/geninf.cpp Fri Jun 25 20:58:33 2010 +0800 +++ b/bintools/elftools/getexports/geninf.cpp Tue Jun 29 14:52:54 2010 +0800 @@ -159,8 +159,8 @@ Elf32_Sym * symtab = 0; int nSyms = 0; char * strtab = 0; - int i=0; - + int i = 0; + for (i = 0; (i < shnum); i++) { if (shdr[i].sh_type == SHT_SYMTAB) { symtab = ELFADDR(Elf32_Sym, eh, shdr[i].sh_offset); @@ -283,7 +283,6 @@ int shoff = eh->e_shoff; // offset of section header table if (shoff) { Elf32_Shdr * shdr = ELFADDR(Elf32_Shdr, eh, shoff); - int i=0; int shnum = eh->e_shnum; // number of section headers @@ -307,7 +306,8 @@ Elf32_Sym * symtab = 0; int nSyms = 0; char * strtab = 0; - + int i = 0; + for (i = 0; (i < shnum); i++) { if (shdr[i].sh_type == SHT_DYNSYM) { symtab = ELFADDR(Elf32_Sym, eh, shdr[i].sh_offset); @@ -350,7 +350,7 @@ int shstrndx = eh->e_shstrndx; char *aSHdrStrTab = ELFADDR(char, eh, shdr[shstrndx].sh_offset); - int i=0; + int i; Elf32_Verdef *aVerDef = 0; char *aStringTab = 0; for(i = 0; i < shnum; i++) { diff -r 122d2b873fd1 -r 30b30f9da0b7 bintools/elftools/group/bld.inf --- a/bintools/elftools/group/bld.inf Fri Jun 25 20:58:33 2010 +0800 +++ b/bintools/elftools/group/bld.inf Tue Jun 29 14:52:54 2010 +0800 @@ -1,44 +1,45 @@ -/* -* Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of the License "Eclipse Public License v1.0" -* which accompanies this distribution, and is available -* at the URL "http://www.eclipse.org/legal/epl-v10.html". -* -* Initial Contributors: -* Nokia Corporation - initial contribution. -* -* Contributors: -* -* Description: -* Base tools (e.g. petran) -* -*/ - - - -PRJ_PLATFORMS -TOOLS TOOLS2 - -PRJ_EXPORTS - -../elf2inf.pl /epoc32/tools/elf2inf.pl -../def2dll.bat /epoc32/tools/def2dll.bat -../def2dll.pl /epoc32/tools/def2dll.pl -../deputil.pl /epoc32/tools/deputil.pl -../deputil.pm /epoc32/tools/deputil.pm -../inc/elfdefs.h /epoc32/include/tools/elfdefs.h - - -PRJ_MMPFILES -#ifdef TOOLS -genstubs -getexports -elftran -#else -elfdump -#endif - - - +/* +* Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* Base tools (e.g. petran) +* +*/ + + + +PRJ_PLATFORMS +TOOLS2 + +PRJ_EXPORTS +#ifndef TOOLS2_LINUX +../elf2inf.pl /epoc32/tools/elf2inf.pl +../def2dll.bat /epoc32/tools/def2dll.bat +../deputil.pl /epoc32/tools/deputil.pl +../deputil.pm /epoc32/tools/deputil.pm +#endif +../def2dll.pl /epoc32/tools/def2dll.pl +../inc/elfdefs.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(tools/elfdefs.h) + + +PRJ_MMPFILES +#ifndef TOOLS2_LINUX +getexports +#endif +elftran +genstubs +elfdump + + + + diff -r 122d2b873fd1 -r 30b30f9da0b7 bintools/elftools/group/elftools.mrp --- a/bintools/elftools/group/elftools.mrp Fri Jun 25 20:58:33 2010 +0800 +++ b/bintools/elftools/group/elftools.mrp Tue Jun 29 14:52:54 2010 +0800 @@ -1,8 +1,8 @@ component dev_build_bintools_elftools -source /src/tools/dev/build/bintools/elftools -exports /src/tools/dev/build/bintools/elftools/group -binary /src/tools/dev/build/bintools/elftools/group all +source /src/tools/build/bintools/elftools +exports /src/tools/build/bintools/elftools/group +binary /src/tools/build/bintools/elftools/group all notes_source release.txt diff -r 122d2b873fd1 -r 30b30f9da0b7 bintools/elftools/group/elftran.mmp --- a/bintools/elftools/group/elftran.mmp Fri Jun 25 20:58:33 2010 +0800 +++ b/bintools/elftools/group/elftran.mmp Tue Jun 29 14:52:54 2010 +0800 @@ -1,49 +1,49 @@ -/* -* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of the License "Eclipse Public License v1.0" -* which accompanies this distribution, and is available -* at the URL "http://www.eclipse.org/legal/epl-v10.html". -* -* Initial Contributors: -* Nokia Corporation - initial contribution. -* -* Contributors: -* -* Description: -* -*/ - - -macro __SUPPORT_ELF_FILES__ - -target elftran.exe -targettype exe - -sourcepath ../elftran -source elf_file.cpp elf_dlld.cpp elf_imp.cpp elf_reloc.cpp elf_tran.cpp - -sourcepath ../../../imgtools/imglib/e32uid -source e32uid.cpp - -sourcepath ../../../imgtools/imglib/host -source h_file.cpp h_mem.cpp h_utl.cpp - -userinclude ../inc -userinclude ../../../e32tools/e32lib/e32image/inc - -systeminclude ../../../e32tools/e32lib/e32image/inc - -sourcepath ../../../e32tools/e32lib/e32image -source e32image.cpp tr_main.cpp imgdump.cpp - -sourcepath ../../../e32tools/e32lib/e32image/deflate -source decode.cpp encode.cpp deflate.cpp inflate.cpp panic.cpp compress.cpp - -sourcepath ../../../imgtools/imglib/compress -source byte_pair.cpp pagedCompress.cpp - -systeminclude ../inc /epoc32/include ../../../imgtools/imglib/compress /epoc32/include/tools/ - -VENDORID 0x70000001 +/* +* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +macro __SUPPORT_ELF_FILES__ + +target elftran.exe +targettype exe + +sourcepath ../elftran +source elf_file.cpp elf_dlld.cpp elf_imp.cpp elf_reloc.cpp elf_tran.cpp + +sourcepath ../../../imgtools/imglib/e32uid +source e32uid.cpp + +sourcepath ../../../imgtools/imglib/host +source h_file.cpp h_mem.cpp h_utl.cpp + +userinclude ../inc +userinclude ../../../imgtools/imglib/e32image +userinclude ../../../imgtools/imglib/compress +userinclude ../../../imgtools/imglib/inc + +sourcepath ../../../imgtools/imglib/e32image +source e32image.cpp tr_main.cpp imgdump.cpp + +sourcepath ../../../imgtools/imglib/e32image/deflate +source decode.cpp encode.cpp deflate.cpp inflate.cpp panic.cpp compress.cpp + +sourcepath ../../../imgtools/imglib/compress +source byte_pair.cpp pagedCompress.cpp + +OS_LAYER_SYSTEMINCLUDE_SYMBIAN + +VENDORID 0x70000001 diff -r 122d2b873fd1 -r 30b30f9da0b7 bintools/elftools/group/release.txt --- a/bintools/elftools/group/release.txt Fri Jun 25 20:58:33 2010 +0800 +++ b/bintools/elftools/group/release.txt Tue Jun 29 14:52:54 2010 +0800 @@ -1,5 +1,20 @@ -NOTESRC_RELEASER -Nokia Corporation - -NOTESRC_RELEASE_REASON -ELFtools Release +NOTESRC_RELEASER +Nokia Corporation + +NOTESRC_RELEASE_REASON +ELFtools Release + +Version v1.1.0 - def2dll.pl +=============== +Released by Zheng Shen, 12/06/2010 + Minor: port def2dll.pl to Linux + +Version V02.02 (Build 002) +=============== +Released by Zheng Shen, 10/03/2010 + 1) DPDEF144887 [System build] : NE1 smoketest not booting up for TB92SF_1069 vtb92sf build + +Version V02.02 (Build 001) +=============== +Released by Zheng Shen, 05/03/2010 + 1) DPDEF144558 ELFTRAN'd give info in the illegal import of data message to allow debugging diff -r 122d2b873fd1 -r 30b30f9da0b7 bintools/elftools/inc/elfdll.h --- a/bintools/elftools/inc/elfdll.h Fri Jun 25 20:58:33 2010 +0800 +++ b/bintools/elftools/inc/elfdll.h Tue Jun 29 14:52:54 2010 +0800 @@ -1,254 +1,254 @@ -/* -* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of the License "Eclipse Public License v1.0" -* which accompanies this distribution, and is available -* at the URL "http://www.eclipse.org/legal/epl-v10.html". -* -* Initial Contributors: -* Nokia Corporation - initial contribution. -* -* Contributors: -* -* Description: -* -*/ - - -#if !defined(__ELFDLL_H__) -#define __ELFDLL_H__ -//#include -#include "e32ldfmt.h" -#include -#include "elffile.h" - -#define DLLSYMPREFIX "#" -#define DLLSYMPREFIX0 "#" -#define DLLSYMSUFFIX "#<\\DLL>" -#define ORDBASE 16 -#define EXPORTTABLENAME "DLL##ExportTable" -#define EXPORTTABLESIZENAME "DLL##ExportTableSize" - -class NamedExportSymbol; -class OrdZeroRecord; -struct NeededDLLsList; - -const TUint KNameLookupOffsetFlag32 = 0x0001; - -class ELFFile::ELFDllData - { -public: - ELFFile * iElfFile; - - char * iDynStrTab; - // bytesize of the dynamic string table - TInt iDynStrTabSize; - Elf32_Sym * iDynSymTab; - // size of an entry in the dynamic symbol table - TInt iSymSize; - // the rela relocation table - Elf32_Rela * iRela; - // size of rela relocation table in bytes - TInt iRelaSz; - // size of a rela entry in bytes - TInt iRelaEnt; - // the rel relocation table - Elf32_Rel * iRel; - // size of rel relocation table in bytes - TInt iRelSz; - // size of a rel entry in bytes - TInt iRelEnt; - - Elf32_HashTable * iHashTable; - - // Exported symbols required for lookup via names. - NamedExportSymbol *iNamedExportSymbolHead; - // Number of exported symbols - this doesn't nclude the absent symbols. - TInt iNamedExportCount; - // header of the export symbol info table - E32EpocExpSymInfoHdr iSymInfoHdr; - // String table size for the symbol names. - TUint iSymStringTableSize; - TUint iStringNameOffset; - - // Dependency list - // Static Dependencies - An 'import relocation' entry is required to be created - // for each such record. - OrdZeroRecord *iDepRecords; - OrdZeroRecord *iDepRecordsTail; - - // List of names obtained from DT_NEEDED entries in ELF. - // The order in which they appear is the order in which symbol - // lookup shall be followed. - NeededDLLsList *iNeededDllNames; - NeededDLLsList *iNeededDllNamesTail; - // Ordinal 0 of this binary. - A local relocation needs to be created for this - // record. - - OrdZeroRecord *iOrdZeroRec; - TInt iNamedLookupEnabled; - - ELFDllData(ELFFile * f); - ~ELFDllData(); - TBool Init(); - - TBool ParseDllSymbol(Elf32_Sym * s, char*& dll, TUint& len, TInt& ord); - class DllSymbol - { - public: - char * iDll; - TUint iLen; - TInt iOrd; - Elf32_Phdr * iSegment; - Elf32_Rel * iRel; - DllSymbol * iNext; - - DllSymbol(char * n, TUint l, TInt o) - : iDll(n), iLen(l), iOrd(o), iSegment(0),iRel(0),iNext(0) - {} - ~DllSymbol() - { - delete iNext; - } - }; - DllSymbol * DllSymbolP(Elf32_Sym * s); - TBool AddSymbol(DllSymbol * s); - - class DllRec - { - public: - char * iName; - TUint iLen; - TInt nImports; - DllSymbol * iHead; - DllSymbol * iTail; - DllRec * iNext; - - DllRec(char * n, TInt l, DllSymbol * s) : - iName(n), iLen(l), nImports(1), iHead(s), iTail(s), iNext(0) - {} - ~DllRec() - { - delete iHead; - delete iNext; - } - void AddSymbol(DllSymbol * s); - }; - - DllRec * iDllHead; - DllRec * iDllTail; - - Elf32_Word iExportTableSymIdx; - Elf32_Word iExportTableSizeSymIdx; - - TBool InitExportInfo(); - TBool iImageIsDll; - TBool ImageIsDll() { return iImageIsDll; } - - Elf32_Word FindSymbolIndex(TText * s); - - TInt iNumberOfImports; - TInt iNumberOfExports; - TInt iNumberOfImportDlls; - - TInt iStringTableSize; - - TInt iNumberOfRelocs; - TInt iNumberOfCodeRelocs; - TInt iNumberOfDataRelocs; - - TInt NumberOfImports(void); - TInt NumberOfExports(void); - TInt NumberOfImportDlls(void); - - TInt NumberOfRelocs(void); - - TInt NumberOfCodeRelocs() { return iNumberOfCodeRelocs; } - TInt NumberOfDataRelocs() { return iNumberOfDataRelocs; } - - TBool GetRelocs(Elf32_Rel **aCodeRelocs, Elf32_Rel **aDataRelocs); - - TUint GetExportTableOffset(void); - char * CreateImportSection(TInt &aSize); - TBool CreateSymLookupTable(); - TBool SetupSymbolValues(); - TBool SetupSymbolNames(); - void Sort(NamedExportSymbol** aDstList, NamedExportSymbol* aSrcList); - void MergeSort(NamedExportSymbol** aDstList, NamedExportSymbol** aSrcList); - void MergeSort(NamedExportSymbol** aDstList, NamedExportSymbol** aSrcList, \ - TUint aLeft, TUint aRight); - TBool AddToDependency(TUint aOff); - TBool CreateDependency(); - OrdZeroRecord* FindDependency(char* aName, TUint aLen); - DllRec * SearchImports(char *aName); - TInt GetLookupTblSize(){ return iSymInfoHdr.iSize;} - void SetLookupTblBase(TInt); - void GetExportSymInfoHeader(E32EpocExpSymInfoHdr& aSymInfoHdr); - void SetExportSymInfo(); - TUint GetSymLookupSection(char* aBuff); - }; - -// This class is used to create symbols to support named lookups. -// - class NamedExportSymbol - { - public: - NamedExportSymbol(char* aName, Elf32_Addr aValue); - ~NamedExportSymbol() - { - delete iNext; - } - - char* Name() { return iSymbolName;} - void Name(char* aName) {iSymbolName = aName;} - - TUint NameOffset() {return iSymbolNameOffset;} - void NameOffset(TUint aOffset) {iSymbolNameOffset = aOffset;} - - Elf32_Addr Value() { return iValue;} - void Value(Elf32_Addr aValue) { iValue = aValue;} - - NamedExportSymbol* Next() { return iNext;} - void Next(NamedExportSymbol* aNext) { iNext = aNext;} - - Elf32_Rel iReloc; // relocation entry for the symbol address - TUint iSymRelocType; // Whether it is a code or data relocation for this symbol - private: - char* iSymbolName; // Symbol name - TInt iSymIdx; - TUint iSymbolNameOffset;// offset of name in string table. - Elf32_Addr iValue; // symbol value - this is the address of the symbol - NamedExportSymbol *iNext; // next symbol - }; - -// This class is used to support symbol lookup of the static dependencies by linking in their -// 0th ordinal. - class OrdZeroRecord - { - public: - OrdZeroRecord(char* aName): - iName(aName), iNext(0){} - ~OrdZeroRecord() - { - delete iNext; - } - char *iName; // (linkas) name of the dependency - Elf32_Rel iReloc; // a relocation entry for the 0th ordinal of each dependency - OrdZeroRecord *iNext; // next dependency - TUint iOffset; - }; - struct NeededDLLsList - { - NeededDLLsList(TUint aOff) : iOffset(aOff), iNext(0) - {} - ~NeededDLLsList() - { - delete iNext; - } - TUint iOffset; - NeededDLLsList *iNext; - }; - -#endif - +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#if !defined(__ELFDLL_H__) +#define __ELFDLL_H__ +//#include +#include "e32ldfmt.h" +#include "elfdefs.h" +#include "elffile.h" + +#define DLLSYMPREFIX "#" +#define DLLSYMPREFIX0 "#" +#define DLLSYMSUFFIX "#<\\DLL>" +#define ORDBASE 16 +#define EXPORTTABLENAME "DLL##ExportTable" +#define EXPORTTABLESIZENAME "DLL##ExportTableSize" + +class NamedExportSymbol; +class OrdZeroRecord; +struct NeededDLLsList; + +const TUint KNameLookupOffsetFlag32 = 0x0001; + +class ELFFile::ELFDllData + { +public: + ELFFile * iElfFile; + + char * iDynStrTab; + // bytesize of the dynamic string table + TInt iDynStrTabSize; + Elf32_Sym * iDynSymTab; + // size of an entry in the dynamic symbol table + TInt iSymSize; + // the rela relocation table + Elf32_Rela * iRela; + // size of rela relocation table in bytes + TInt iRelaSz; + // size of a rela entry in bytes + TInt iRelaEnt; + // the rel relocation table + Elf32_Rel * iRel; + // size of rel relocation table in bytes + TInt iRelSz; + // size of a rel entry in bytes + TInt iRelEnt; + + Elf32_HashTable * iHashTable; + + // Exported symbols required for lookup via names. + NamedExportSymbol *iNamedExportSymbolHead; + // Number of exported symbols - this doesn't nclude the absent symbols. + TInt iNamedExportCount; + // header of the export symbol info table + E32EpocExpSymInfoHdr iSymInfoHdr; + // String table size for the symbol names. + TUint iSymStringTableSize; + TUint iStringNameOffset; + + // Dependency list + // Static Dependencies - An 'import relocation' entry is required to be created + // for each such record. + OrdZeroRecord *iDepRecords; + OrdZeroRecord *iDepRecordsTail; + + // List of names obtained from DT_NEEDED entries in ELF. + // The order in which they appear is the order in which symbol + // lookup shall be followed. + NeededDLLsList *iNeededDllNames; + NeededDLLsList *iNeededDllNamesTail; + // Ordinal 0 of this binary. - A local relocation needs to be created for this + // record. + + OrdZeroRecord *iOrdZeroRec; + TInt iNamedLookupEnabled; + + ELFDllData(ELFFile * f); + ~ELFDllData(); + TBool Init(); + + TBool ParseDllSymbol(Elf32_Sym * s, char*& dll, TUint& len, TInt& ord); + class DllSymbol + { + public: + char * iDll; + TUint iLen; + TInt iOrd; + Elf32_Phdr * iSegment; + Elf32_Rel * iRel; + DllSymbol * iNext; + + DllSymbol(char * n, TUint l, TInt o) + : iDll(n), iLen(l), iOrd(o), iSegment(0),iRel(0),iNext(0) + {} + ~DllSymbol() + { + delete iNext; + } + }; + DllSymbol * DllSymbolP(Elf32_Sym * s); + TBool AddSymbol(DllSymbol * s); + + class DllRec + { + public: + char * iName; + TUint iLen; + TInt nImports; + DllSymbol * iHead; + DllSymbol * iTail; + DllRec * iNext; + + DllRec(char * n, TInt l, DllSymbol * s) : + iName(n), iLen(l), nImports(1), iHead(s), iTail(s), iNext(0) + {} + ~DllRec() + { + delete iHead; + delete iNext; + } + void AddSymbol(DllSymbol * s); + }; + + DllRec * iDllHead; + DllRec * iDllTail; + + Elf32_Word iExportTableSymIdx; + Elf32_Word iExportTableSizeSymIdx; + + TBool InitExportInfo(); + TBool iImageIsDll; + TBool ImageIsDll() { return iImageIsDll; } + + Elf32_Word FindSymbolIndex(const char* s); + + TInt iNumberOfImports; + TInt iNumberOfExports; + TInt iNumberOfImportDlls; + + TInt iStringTableSize; + + TInt iNumberOfRelocs; + TInt iNumberOfCodeRelocs; + TInt iNumberOfDataRelocs; + + TInt NumberOfImports(void); + TInt NumberOfExports(void); + TInt NumberOfImportDlls(void); + + TInt NumberOfRelocs(void); + + TInt NumberOfCodeRelocs() { return iNumberOfCodeRelocs; } + TInt NumberOfDataRelocs() { return iNumberOfDataRelocs; } + + TBool GetRelocs(Elf32_Rel **aCodeRelocs, Elf32_Rel **aDataRelocs); + + TUint GetExportTableOffset(void); + char * CreateImportSection(TInt &aSize); + TBool CreateSymLookupTable(); + TBool SetupSymbolValues(); + TBool SetupSymbolNames(); + void Sort(NamedExportSymbol** aDstList, NamedExportSymbol* aSrcList); + void MergeSort(NamedExportSymbol** aDstList, NamedExportSymbol** aSrcList); + void MergeSort(NamedExportSymbol** aDstList, NamedExportSymbol** aSrcList, \ + TUint aLeft, TUint aRight); + TBool AddToDependency(TUint aOff); + TBool CreateDependency(); + OrdZeroRecord* FindDependency(char* aName, TUint aLen); + DllRec * SearchImports(char *aName); + TInt GetLookupTblSize(){ return iSymInfoHdr.iSize;} + void SetLookupTblBase(TInt); + void GetExportSymInfoHeader(E32EpocExpSymInfoHdr& aSymInfoHdr); + void SetExportSymInfo(); + TUint GetSymLookupSection(char* aBuff); + }; + +// This class is used to create symbols to support named lookups. +// + class NamedExportSymbol + { + public: + NamedExportSymbol(char* aName, Elf32_Addr aValue); + ~NamedExportSymbol() + { + delete iNext; + } + + char* Name() { return iSymbolName;} + void Name(char* aName) {iSymbolName = aName;} + + TUint NameOffset() {return iSymbolNameOffset;} + void NameOffset(TUint aOffset) {iSymbolNameOffset = aOffset;} + + Elf32_Addr Value() { return iValue;} + void Value(Elf32_Addr aValue) { iValue = aValue;} + + NamedExportSymbol* Next() { return iNext;} + void Next(NamedExportSymbol* aNext) { iNext = aNext;} + + Elf32_Rel iReloc; // relocation entry for the symbol address + TUint iSymRelocType; // Whether it is a code or data relocation for this symbol + private: + char* iSymbolName; // Symbol name + TInt iSymIdx; + TUint iSymbolNameOffset;// offset of name in string table. + Elf32_Addr iValue; // symbol value - this is the address of the symbol + NamedExportSymbol *iNext; // next symbol + }; + +// This class is used to support symbol lookup of the static dependencies by linking in their +// 0th ordinal. + class OrdZeroRecord + { + public: + OrdZeroRecord(char* aName): + iName(aName), iNext(0){} + ~OrdZeroRecord() + { + delete iNext; + } + char *iName; // (linkas) name of the dependency + Elf32_Rel iReloc; // a relocation entry for the 0th ordinal of each dependency + OrdZeroRecord *iNext; // next dependency + TUint iOffset; + }; + struct NeededDLLsList + { + NeededDLLsList(TUint aOff) : iOffset(aOff), iNext(0) + {} + ~NeededDLLsList() + { + delete iNext; + } + TUint iOffset; + NeededDLLsList *iNext; + }; + +#endif + diff -r 122d2b873fd1 -r 30b30f9da0b7 bintools/elftools/inc/elffile.h --- a/bintools/elftools/inc/elffile.h Fri Jun 25 20:58:33 2010 +0800 +++ b/bintools/elftools/inc/elffile.h Tue Jun 29 14:52:54 2010 +0800 @@ -1,160 +1,160 @@ -/* -* Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of the License "Eclipse Public License v1.0" -* which accompanies this distribution, and is available -* at the URL "http://www.eclipse.org/legal/epl-v10.html". -* -* Initial Contributors: -* Nokia Corporation - initial contribution. -* -* Contributors: -* -* Description: -* -*/ - - -#if !defined(__ELFFILE_H__) -#define __ELFFILE_H__ -#include -#include "e32ldfmt.h" -#include - -#define ELFADDR(rtype, p, o) (rtype *)(((char *)p) + o) - -// -enum TImportStat {EImpError, EImpSuccess, EImpDone}; -// -class ELFFile - { -public: - ELFFile(); - ~ELFFile(); - TBool Init(const TText * const aFileName); - void Close(void); - - char *CreateImportSection(TInt &aSize); - - TBool GetRelocs(Elf32_Rel **aCodeRelocs, Elf32_Rel **aDataRelocs); - TUint16 GetRelocType(Elf32_Rel* aReloc); - - TInt NumberOfImports() const; - TInt NumberOfImportDlls() const; - TInt NumberOfExports() const; - TInt NumberOfRelocs(); - - - - TInt NumberOfCodeRelocs(); - TInt NumberOfDataRelocs(); - -public: - TUint iCodeSize; - TUint iDataSize; - TUint iBssSize; - - - TUint GetCodeSize(); - TBool HasInitialisedData(); - TUint GetDataSize(); - TBool HasBssData(); - TUint GetBssSize(); - - - Elf32_Phdr * GetSegment(TInt idx) {return &iPhdr[idx];} - Elf32_Phdr * GetSegmentFromAddr(Elf32_Addr addr); - - char * GetCode() { return ELFADDR(char, iElfFile, iCodeSegmentHdr->p_offset); } - char * GetData() { return ELFADDR(char, iElfFile, iDataSegmentHdr->p_offset); } - TBool CodeSegmentP(Elf32_Phdr * s) { return (TBool)(s == iCodeSegmentHdr); } - TBool CodeSegmentP(TInt idx) { return (TBool)(idx == iCodeSegmentIdx); } - TInt CodeSegmentIndex() {return iCodeSegmentIdx;} - TBool DataSegmentP(Elf32_Phdr * s) { return (TBool)(s == iDataSegmentHdr); } - TBool DataSegmentP(TInt idx) { return (TBool)(idx == iDataSegmentIdx); } - TInt DataSegmentIndex() {return iDataSegmentIdx;} - - TUint * CodePtrFromAddr(Elf32_Addr addr) { return PtrInSegment(iCodeSegmentHdr, addr); } - TUint * DataPtrFromAddr(Elf32_Addr addr) { return PtrInSegment(iDataSegmentHdr, addr); } - - - char * ELFFileBase() { return (char *) iElfFile; } - - TUint GetExportTableOffset(void); - TUint GetEntryPointOffset(void) { return iElfFile->e_entry - iCodeSegmentHdr->p_vaddr; } - - TBool SymbolPresent(TText *s); - Elf32_Sym * FindSymbol(const TText *); - - TBool GetExceptionIndexInfo(TUint32 &aOffset); - TBool SetUpLookupTable(); - void SetLookupTblBase(TInt); - TInt GetLookupTblSize(); - void GetExportSymInfoHeader(E32EpocExpSymInfoHdr& aSymInfoHdr); - TUint GetSymLookupSection(char* aBuff); -private: - TBool InitHeaders(void); - TBool InitDllData(void); - - TUint * PtrInSegment(Elf32_Phdr * phdr, Elf32_Addr addr) - { - return ELFADDR(TUint, ELFADDR(TUint, iElfFile, phdr->p_offset), (addr - phdr->p_vaddr)); - } - - - TBool IsValidFileHeader(Elf32_Ehdr * aElfHdr); - void CopySectionData(TAny *source, TAny *dest, TUint32 fileLength, TUint32 memLength); - TBool ProcessRelocData(TAny *relocData,TInt dataSize); - ELFFile(const ELFFile&); - const ELFFile & operator = (const ELFFile&); -public: - TBool iImageIsDll; - TBool ImageIsDll() { return iImageIsDll; } - Elf32_Addr iLinkedBase; - - TUint iEntryPoint; - TUint iHeapCommittedSize; - TUint iHeapReservedSize; - TUint iStackCommittedSize; - TUint iStackReservedSize; -private: - friend class E32ImageFile; - friend class E32ImageFile_ELF; - - TText * iFileName; - TInt32 iFileHandle; - Elf32_Ehdr * iElfFile; - Elf32_Phdr * iPhdr; - Elf32_Phdr * iDynamicSegmentHdr; - TInt iDynamicSegmentIdx; - Elf32_Phdr * iCodeSegmentHdr; - TInt iCodeSegmentIdx; - Elf32_Phdr * iDataSegmentHdr; - TInt iDataSegmentIdx; - - Elf32_Shdr * iSectionHeaderTable; - TInt iSymIdx; - Elf32_Sym * iSymTab; - - class ELFDllData; - ELFDllData * iDllData; - - TCpu iCpu; - - - }; -#endif - - - - - - - - - - - - - +/* +* Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#if !defined(__ELFFILE_H__) +#define __ELFFILE_H__ +#include +#include "e32ldfmt.h" +#include "elfdefs.h" + +#define ELFADDR(rtype, p, o) (rtype *)(((char *)p) + o) + +// +enum TImportStat {EImpError, EImpSuccess, EImpDone}; +// +class ELFFile + { +public: + ELFFile(); + ~ELFFile(); + TBool Init(const char* aFileName); + void Close(void); + + char *CreateImportSection(TInt &aSize); + + TBool GetRelocs(Elf32_Rel **aCodeRelocs, Elf32_Rel **aDataRelocs); + TUint16 GetRelocType(Elf32_Rel* aReloc); + + TInt NumberOfImports() const; + TInt NumberOfImportDlls() const; + TInt NumberOfExports() const; + TInt NumberOfRelocs(); + + + + TInt NumberOfCodeRelocs(); + TInt NumberOfDataRelocs(); + +public: + TUint iCodeSize; + TUint iDataSize; + TUint iBssSize; + + + TUint GetCodeSize(); + TBool HasInitialisedData(); + TUint GetDataSize(); + TBool HasBssData(); + TUint GetBssSize(); + + + Elf32_Phdr * GetSegment(TInt idx) {return &iPhdr[idx];} + Elf32_Phdr * GetSegmentFromAddr(Elf32_Addr addr); + + char * GetCode() { return ELFADDR(char, iElfFile, iCodeSegmentHdr->p_offset); } + char * GetData() { return ELFADDR(char, iElfFile, iDataSegmentHdr->p_offset); } + TBool CodeSegmentP(Elf32_Phdr * s) { return (TBool)(s == iCodeSegmentHdr); } + TBool CodeSegmentP(TInt idx) { return (TBool)(idx == iCodeSegmentIdx); } + TInt CodeSegmentIndex() {return iCodeSegmentIdx;} + TBool DataSegmentP(Elf32_Phdr * s) { return (TBool)(s == iDataSegmentHdr); } + TBool DataSegmentP(TInt idx) { return (TBool)(idx == iDataSegmentIdx); } + TInt DataSegmentIndex() {return iDataSegmentIdx;} + + TUint * CodePtrFromAddr(Elf32_Addr addr) { return PtrInSegment(iCodeSegmentHdr, addr); } + TUint * DataPtrFromAddr(Elf32_Addr addr) { return PtrInSegment(iDataSegmentHdr, addr); } + + + char * ELFFileBase() { return (char *) iElfFile; } + + TUint GetExportTableOffset(void); + TUint GetEntryPointOffset(void) { return iElfFile->e_entry - iCodeSegmentHdr->p_vaddr; } + + TBool SymbolPresent(const char* s); + Elf32_Sym * FindSymbol(const char* s); + + TBool GetExceptionIndexInfo(TUint32 &aOffset); + TBool SetUpLookupTable(); + void SetLookupTblBase(TInt); + TInt GetLookupTblSize(); + void GetExportSymInfoHeader(E32EpocExpSymInfoHdr& aSymInfoHdr); + TUint GetSymLookupSection(char* aBuff); +private: + TBool InitHeaders(void); + TBool InitDllData(void); + + TUint * PtrInSegment(Elf32_Phdr * phdr, Elf32_Addr addr) + { + return ELFADDR(TUint, ELFADDR(TUint, iElfFile, phdr->p_offset), (addr - phdr->p_vaddr)); + } + + + TBool IsValidFileHeader(Elf32_Ehdr * aElfHdr); + void CopySectionData(TAny *source, TAny *dest, TUint32 fileLength, TUint32 memLength); + TBool ProcessRelocData(TAny *relocData,TInt dataSize); + ELFFile(const ELFFile&); + const ELFFile & operator = (const ELFFile&); +public: + TBool iImageIsDll; + TBool ImageIsDll() { return iImageIsDll; } + Elf32_Addr iLinkedBase; + + TUint iEntryPoint; + TUint iHeapCommittedSize; + TUint iHeapReservedSize; + TUint iStackCommittedSize; + TUint iStackReservedSize; +private: + friend class E32ImageFile; + friend class E32ImageFile_ELF; + + char* iFileName; + TInt32 iFileHandle; + Elf32_Ehdr * iElfFile; + Elf32_Phdr * iPhdr; + Elf32_Phdr * iDynamicSegmentHdr; + TInt iDynamicSegmentIdx; + Elf32_Phdr * iCodeSegmentHdr; + TInt iCodeSegmentIdx; + Elf32_Phdr * iDataSegmentHdr; + TInt iDataSegmentIdx; + + Elf32_Shdr * iSectionHeaderTable; + TInt iSymIdx; + Elf32_Sym * iSymTab; + + class ELFDllData; + ELFDllData * iDllData; + + TCpu iCpu; + + + }; +#endif + + + + + + + + + + + + + diff -r 122d2b873fd1 -r 30b30f9da0b7 bintools/elftools/inc/elftran.h --- a/bintools/elftools/inc/elftran.h Fri Jun 25 20:58:33 2010 +0800 +++ b/bintools/elftools/inc/elftran.h Tue Jun 29 14:52:54 2010 +0800 @@ -1,65 +1,65 @@ -/* -* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of the License "Eclipse Public License v1.0" -* which accompanies this distribution, and is available -* at the URL "http://www.eclipse.org/legal/epl-v10.html". -* -* Initial Contributors: -* Nokia Corporation - initial contribution. -* -* Contributors: -* -* Description: -* Derived in part from E32IMAGE.H -* -*/ - - -#ifndef __ELFTRAN_H__ -#define __ELFTRAN_H__ - -#include -#include -#include "e32ldfmt.h" -#include - -class ELFFile; - -// -class E32ImageFile_ELF : public E32ImageFile - { -public: - E32ImageFile_ELF(); - virtual ~E32ImageFile_ELF(); - virtual TBool Translate(const char* aFileName, TUint aDataBase, TBool aAllowDllData, \ - TBool aSymLkupEnabled = FALSE); - TBool Translate(ELFFile& aElfFile); - TBool ImageIsDll(ELFFile& aElfFile); -private: - TInt DoCodeHeader(ELFFile &aElfFile); - TInt DoDataHeader(ELFFile &aElfFile, TUint aDataBase); - TInt CopyCode(char *aPtr, ELFFile &aElfFile); - TInt CopyData(char *aPtr, ELFFile &aElfFile); - - char *CreateImportSection(ELFFile &aElfFile, TInt &aSize); - void CreateExportSection(char *aPtr, ELFFile &aElfFile); - - void FixRelocs(ELFFile &aElfFile, Elf32_Rel **codeRelocs, Elf32_Rel **dataRelocs); - char *CreateRelocs(ELFFile& aElfFile, Elf32_Rel **relocs, TInt nrelocs, TInt &aSize, TUint aBase); - - TUint FixAddress(ELFFile &aElfFile, TUint va, Elf32_Rel * rel); - - void SetUpExceptions(ELFFile &aElfFile); - void SetSymNameLookup(TInt aSymNameLkupEnabled); - TBool IsNamedLookupEnabled(); - TBool SetUpLookupTable(ELFFile &aElfFile); - TInt DoSymbolLookupHeader(ELFFile &aElfFile, TInt aBaseOffset); - TUint CopyExportSymInfo(char *aPtr, ELFFile &aElfFile); - }; - -#endif - - - +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* Derived in part from E32IMAGE.H +* +*/ + + +#ifndef __ELFTRAN_H__ +#define __ELFTRAN_H__ + +#include +#include "e32image.h" +#include "e32ldfmt.h" +#include "elfdefs.h" + +class ELFFile; + +// +class E32ImageFile_ELF : public E32ImageFile + { +public: + E32ImageFile_ELF(); + virtual ~E32ImageFile_ELF(); + virtual TBool Translate(const char* aFileName, TUint aDataBase, TBool aAllowDllData, \ + TBool aSymLkupEnabled = FALSE); + TBool Translate(ELFFile& aElfFile); + TBool ImageIsDll(ELFFile& aElfFile); +private: + TInt DoCodeHeader(ELFFile &aElfFile); + TInt DoDataHeader(ELFFile &aElfFile, TUint aDataBase); + TInt CopyCode(char *aPtr, ELFFile &aElfFile); + TInt CopyData(char *aPtr, ELFFile &aElfFile); + + char *CreateImportSection(ELFFile &aElfFile, TInt &aSize); + void CreateExportSection(char *aPtr, ELFFile &aElfFile); + + void FixRelocs(ELFFile &aElfFile, Elf32_Rel **codeRelocs, Elf32_Rel **dataRelocs); + char *CreateRelocs(ELFFile& aElfFile, Elf32_Rel **relocs, TInt nrelocs, TInt &aSize, TUint aBase); + + TUint FixAddress(ELFFile &aElfFile, TUint va, Elf32_Rel * rel); + + void SetUpExceptions(ELFFile &aElfFile); + void SetSymNameLookup(TInt aSymNameLkupEnabled); + TBool IsNamedLookupEnabled(); + TBool SetUpLookupTable(ELFFile &aElfFile); + TInt DoSymbolLookupHeader(ELFFile &aElfFile, TInt aBaseOffset); + TUint CopyExportSymInfo(char *aPtr, ELFFile &aElfFile); + }; + +#endif + + + diff -r 122d2b873fd1 -r 30b30f9da0b7 bintools/evalid/dev_build_bintools_evalid.mrp --- a/bintools/evalid/dev_build_bintools_evalid.mrp Fri Jun 25 20:58:33 2010 +0800 +++ b/bintools/evalid/dev_build_bintools_evalid.mrp Tue Jun 29 14:52:54 2010 +0800 @@ -1,7 +1,7 @@ component dev_build_bintools_evalid -source \src\dev\build\bintools\evalid -exports \src\dev\build\bintools\evalid +source \src\tools\build\bintools\evalid +exports \src\tools\build\bintools\evalid notes_source \component_defs\release.src diff -r 122d2b873fd1 -r 30b30f9da0b7 bintools/evalid/evalid.mrp --- a/bintools/evalid/evalid.mrp Fri Jun 25 20:58:33 2010 +0800 +++ b/bintools/evalid/evalid.mrp Tue Jun 29 14:52:54 2010 +0800 @@ -1,7 +1,7 @@ component dev_build_bintools_evalid -source \src\tools\dev\build\bintools\evalid -exports \src\tools\dev\build\bintools\evalid +source \src\tools\build\bintools\evalid +exports \src\tools\build\bintools\evalid notes_source \component_defs\release.src diff -r 122d2b873fd1 -r 30b30f9da0b7 bintools/rcomp/group/BLD.INF --- a/bintools/rcomp/group/BLD.INF Fri Jun 25 20:58:33 2010 +0800 +++ b/bintools/rcomp/group/BLD.INF Tue Jun 29 14:52:54 2010 +0800 @@ -1,42 +1,43 @@ -/* -* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of the License "Eclipse Public License v1.0" -* which accompanies this distribution, and is available -* at the URL "http://www.eclipse.org/legal/epl-v10.html". -* -* Initial Contributors: -* Nokia Corporation - initial contribution. -* -* Contributors: -* -* Description: -* Resource compiler -* -*/ - - -/** - @file -*/ - -PRJ_PLATFORMS - -TOOLS2 - -PRJ_EXPORTS -// Add the Symbian localisation header files to the epoc32\include directory. -// These files are needed by epocrc.pl to provide context information for -// localisation of resource files. - -../inc/loc/symbiantags.rh -../inc/loc/symbianbasictags.rh -../inc/loc/symbiancontexts.rh - - - -PRJ_MMPFILES - -// Additional extension makefile to process the lex and yacc source files -rcomp.mmp +/* +* Copyright (c) 2001-2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* Resource compiler +* +*/ + + +/** + @file +*/ + +PRJ_PLATFORMS + +TOOLS2 + +PRJ_EXPORTS +// Add the Symbian localisation header files to the epoc32\include directory. +// These files are needed by epocrc.pl to provide context information for +// localisation of resource files. + +../inc/loc/symbiantags.rh +../inc/loc/symbianbasictags.rh +../inc/loc/symbiancontexts.rh + + + +PRJ_MMPFILES + +// Additional extension makefile to process the lex and yacc source files +rcomp.mmp + diff -r 122d2b873fd1 -r 30b30f9da0b7 bintools/rcomp/group/RELEASE.TXT --- a/bintools/rcomp/group/RELEASE.TXT Fri Jun 25 20:58:33 2010 +0800 +++ b/bintools/rcomp/group/RELEASE.TXT Tue Jun 29 14:52:54 2010 +0800 @@ -1,628 +1,663 @@ -Version 8.1.005 -=============== -Released by KunalM, 06/03/2007 - - 1) RCOMP ported to the TOOLS2 platform, under PREQ1182, MS3.6.2 - - -Version 8.00.002 -================ -Released by AndrewR, 3/3/2005 - - 1) DEFECT FIX: DEF055559 - Problems building rcomp in VC6 IDE - -Version 8.00.001 -================ -Released by AndrewR, 7/2/2005 - - 1) DEFECT FIX: DEF054981 - tools_rcomp component is updated every day - -Version 8.00.000 -================ -Released by AndrewR, 4/2/2005 - 1) Fixed DEF054617 - rcomp doesn't build from source - 2) Fixed INC049059 - incorrect line number for error reported by rcomp when building \s60\gs - -Version 7.01.009 -============ -Released by KuldipN, 22/07/2004 - Add UID2 and UID3 keywords to RCOMP - (CR HBRT-5YJJ9C Specifying UID2 and UID3 in RSS files) - -Version 7.01.008 -============ -Released by DuskoJ, 10/07/2003 - 1) Fixed DEF022269 Resource value is read incorrectly - 2) Fixed INC036025 RCOMP chinese resource complation problem - -Version 7.01.007 -============ -Released by Jon Chatten, 03/06/2003 - 1) Fixed "DEF025433 RComp core dumps on certain resource files" - 2) Adjusted version number in release.txt to match binary. - - -Version 7.06 -============ -Released by Dusko Jahora, 03/06/2003 - 1) Reverted fix for DEF022269 - - -Version 7.05 -============ -Released by Dusko Jahora, 02/06/2003 -1) DuskoJ - 1) Changes to RCOMP whihch are part of CR PCHY-5L3RDW - "Typhoon must support 16bpp colour". - 2) Fixed DEF022269 Resource value is read incorrectly - (this fix was not submitted on 09/05/2003 because of - an integration error) - - -Version 7.04 -============ - -Released by Dusko Jahora, 09/05/2003 -1) DuskoJ - 1) Fixed DEF022269 Resource value is read incorrectly - - -Version 7.03 -============ - -Released by Dusko Jahora, April 2003 - 1) Fixed defect DEF017151 "RCOMP should be upgraded to support files with UTF8 - signature". - - -1) William - 1) Fixed defect ROS-58VCX8 "RCOMP doesn't allow + in filenames" by removing - the unnecessary validation of the filenames left by the C++ preprocessor. - 2) Fixed defect RED-5ACK5F "Resource compiler creates nothing for empty and bad - counted byte arrays" -2) Dusko - 1) Fixed defect ROS-5B7MHW "RCOMP fails to handle boundary values correctly - for WORD data type" - -NB. The handling of LABEL suggests that it would be pretty easy to add rls_string support -into the compiler directly. - -Version 7.01 -============ - -Released by Jon Chatten, February 2002 - -Fixed defect ROS-56PHFA - Replaced system() call to uidcrc.exe with a call to _spawnlp - -this addresses the IDE-hanging issue when epocrc.pl is integrated as a plug-in with the CW -IDE on Windows 98. - -Removed attempt to absolutely identify uidcrc.exe - this is no longer required as the CW RCOMP/EPOCRC.PL -plug-in now sets the PATH before invoking the command line tools. - - -1) William - 1) Fixed defect ROS-55KJ4U "RCOMP fails if epoc32\tools not on the path" - - -Version 7.00 -============ - -Released by David Batchelor (November/December 2001) - -The format of resource files changes as follows: - -- The initial 2 two-byte values are removed as they are completely redundant. (All the information - they provide can be derived from the last 2 bytes of the file combined with the size of the - file.) -- Resource files now have a standard 4-byte checked-UID field at the start. The first UID is - 0x101f4a6b, to indicate that the resource file potentially contains Unicode compressed according - to the "Standard Compression Scheme for Unicode" (see - http://www.unicode.org/unicode/reports/tr6/tr6-3.2.html). The second and third UIDs may be - specified on the command-line by using an optional parameter of the form - "-{0x12345678,0x9abcdef0}" (without the quotation marks). If "*" is used as the last UID, e.g. - "-{0x600ddea1,*}", then the resource file's "offset" (i.e. the 20-bit number generated from the - resource file's "NAME") is used as the last UID. -- The UID field is immediately followed by a bit-array, one bit for each resource in the resource - file, where each bit indicates whether the corresponding resource contains compressed Unicode. - The bit field is padded up to a multiple of 8-bits (if necessary) with zero bits. -- Each resource which contains compressed Unicode consists of a series of "runs" preceded by a 1 - or 2-byte run-length (1 byte if the run is <128 bytes, else 2 bytes). The run-length value does - not include itself in the byte count that it holds. The first run, the third run, the fifth run - etc contain compressed Unicode. The second run, the fourth run, the sixth run etc contain other - stuff. As the protocol defines that the first run is compressed Unicode, this run may obviously - be of zero length - no subsequent run in that resource may be of zero length. -- Rcomp only uses compressed Unicode for text fields if it yields any benefit (i.e. only if it - actually makes the output file smaller). -- The changes are completely transparent for code that reads resources. - - -Version 6.03 -============ - -Released by William Roberts, 30-Jul-2001 - -Fix defect EXT-4YSCUV "Resource compiler corrupts long strings" -Handle very long C++ comments, which previously caused a "token buffer overflow" message from the -lexical analyser. Avoid overruning the buffer for literals by using a CHECK_APPEND() macro which -discards characters rather than run off the end, giving errors like - -(5) : string too long - 1 ignored -(5) : string too long - 2 ignored - -Avoid overflowing the Value array in string expressions by checking the new length before -agreeing to concatenate the strings. Ultimately it would be best to replace Value[] with -a char* which has been created with strdup() and can therefore be realloc'd to grow the string. - -Fix defect ARG-4TZF7J "RCOMP needs warning waivers registered with SI" -Removed all warnings in tools rel build - some tools deb warnings will appear in rcomp.cpp -because of problems in the mks\etc\yyparse.cpp file, but I didn't want to hide related problems -in any new Symbian code we might add. - -Improve the -v output to show the primitive types being emitted, and to dump the IndexTable as hex -offsets followed by the resource name, e.g. - - IndexTable - IndexTableItem 4 - IndexTableItem c r_eikserv_panic_dialog - IndexTableItem b8 r_eiksrv_oom_event_top - IndexTableItem e4 r_eiksrv_oom_event_bot - IndexTableItem 144 r_eikserv_replace_main_batteries - IndexTableItem 170 r_eikserv_replace_backup_battery - -and - - ResourceHeader r_eiksrv_tasklist_dialog - ++ResourceItemArray - SimpleResourceItem [Long flags] 9 - SimpleResourceItem [LText16 title] - SimpleResourceItem [LLink pages] - SimpleResourceItem [LLink buttons] - StructArrayResourceItem (Level 0) [items] - ArrayLength [Word] 1 - ---------------------- - --ResourceItemArrayArray - ++ResourceItemArray - SimpleResourceItem [Word type] 1001 - SimpleResourceItem [LText16 prompt] - SimpleResourceItem [Word id] 1 - SimpleResourceItem [Long itemflags] 0 - StructTypeResourceItem (Level 0) [control] - ---------------------- - ++ResourceItemArray - SimpleResourceItem [Byte version] 0 - SimpleResourceItem [Word flags] 0 - SimpleResourceItem [Word height] 8 - SimpleResourceItem [Word width] 20 - SimpleResourceItem [LLink array_id] - ---------------------- - SimpleResourceItem [LText16 trailer] - ---------------------- - -Together these changes should make it significantly easier to step through the binary image of a -resource and work out which element has changed unexpectedly. - - -Version 6.02 -============ - -Released by William Roberts, 15-Feb-2001 - -Fix awful defect in version 6.01, which caused negative integer constants to be written to the file as -1. - -When testing with LOCKIT, RCOMP developer should be aware that the version of RCOMP.EXE used by lockit -is kept in \lockit\tools, not \epoc32\tools. - - -Version 6.01 -============ - -Released by William Roberts, 14-Feb-2001 - -Redefined character literals ('x') to be effectively strings so that they can contain UTF8 encodings -for interesting characters. This is handled using the same lexical rules as string literals, so -the limited escape processing is also supported. The introduction of strings surrounded by single-quotes -means that the sequence \' is now accepted as standing for '. - -If the character literal string decodes to more than one Unicode character, a warning is given and the -rest of the string is ignored. The prevailing source character encoding is used, but there is no support -narrow character literals in the difficult part of the CP1252 range: the interpretation of the literal -is always "the Unicode encoding for the first character of the string". For example, even in a -CP1252 source file building a narrow resource, a literal containing the Euro symbol will be interpreted -as 0x20ac, not 0x80. - -LTEXT strings are now checked to ensure that they are less than 256 characters in length. - -The NAME statement can now take a string literal or a label, instead of the previous behaviour where the -lexical analyser handled the following word differently. Any RSS file which used a keyword as a name, -for example WORD.RSS, will need to be changed to specify the name as a literal: the preferred syntax -is to use string literals in all cases. - - -Version 3.18 -============ - -Released by William Roberts, 05-Aug-1999. - -Requires BAFL 092. - -Changed the handling of Unicode string resources (TEXT16 and LTEXT16) to ensure that the -Unicode characters are aligned to a multiple of 2 bytes when the resource is used. - -Resources are never used in place: instead RResourceFile::AllocReadLC creates an HBufC8 to hold a -copy of the data. This means that rather than aligning from the start of the entire resource file, -instead we have to align to the start of the individual resource, because the data in an HBufC8 -always starts at an aligned address. - -Added RCBinaryStream::Align(int nBytes) and RCBinaryStream::SetAlignBase() to support the -generation of the necessary padding, and call them from suitable places in RCOSTRM.CPP. - -Also added code to add 1 to the offset of the end of the table of resource offsets: this is tested -in BAFL as a marker to indicate the new format of resource file. - -Added a /verbose flag to core.cmd which invokes RCOMP with -v. - -Added #pragma warning( disable : 4710 ) in a couple of places to cut down on the number of -unnecessary and useless "warnings". - -Regenerated the test resources. - - -Version 3.17 -============ - -Released by William Roberts, 25-Jun-1999. - -Fixed defect where embedded Unicode characters could cause BUF strings to fail a length check. -Updated test code include a check for this. - -Added more stuff for the Engineering Automated Build. - - -Version 3.16 -============ - -Released by Pute, 9-Jun-1999. Based on work by William Roberts, -26-May-1999 described in the "William's notes" section below. - - -Character sets --------------- - -We are moving towards a specific principle of character sets for RCOMP. - -Previously, the character set used by RCOMP was not well defined, later we -added the CHARACTER_SET identifier. This implied that any specific values -inserted into strings in format would be in the character set of the -source. - -In this design RCOMP will have trouble handling multibyte encodings like -Shift-JIS because the tools it relies upon, LEX and YACC, are based on -single-octet encodings only. Sometimes a multibyte encoding will produce -artefacts that appear to be syntax elements such as double quote marks. - -In future the intention is that RCOMP uses UTF-8 encoding internally, -provided by a pre-processing phase. This release is an interim step. - -In this release, when explicit values are inserted in text strings, they -are interpreted as Unicode values and converted to UTF-8. To retain -backward compatibility with CP1252 source, values 80-9F are also permitted -and these will be mapped to Unicode as before when the source character set -is defined to be CP1252. The use of explicit values 80-9F is deprecated -however. - -The default input character set is CP1252. Previously, the default -character set was "unknown". This possibility is no-longer supported. -This was also contrary to documentation. - - -Details: - -Test command procedure updated and enhanced. - -Test comparison files TUTEXT8.RSC and TUTEXT16.RSC have been updated to -allow for the introduction of the extra characters in the CP1252 character -set. (128 used to be "not used" and is now the euro sign) - -Note that compilation warning messages about deprecated characters will -appear durng this test. - -A new test source file TWTEXT.RSS and associated reference binaries have -been added to the test suite to demonstrate explicit use of values >255. - - - - -William's notes (edited by Pute): ---------------- - -Defined a new "character set" called UTF8, which supports the UTF8 -encoding of Unicode strings. -This actually allows the whole resource source file to be entered as -UTF8 if required. However the default charset remains CP1252. - -Arranged to support embedded Unicode characters constructed using the - notation, to support the use of 0x07ED as the end-of-paragraph -marker (see ETEXT 120). This exploits the UTF8 support by inserting the -appropriate UTF8 sequence into the 8-bit data. - -The embedded Unicode characters are also supported in the CP1252 -character set, with internal use of 0x81 as an "escape" character -indicating that the following bytes are a UTF8 encoded character. This -allows existing CP1252 resource source files to be used with the new -ETEXT. - -Added the Euro and the Z caron encodings to the cp1252_exceptions table. - - -Only RCOMP.EXE has been rebuilt. Judging from the timestamps, the other -executables haven't been rebuilt for the last few releases. - -To build rcomp, first run ..\src\BLDEX, then MNT BLDREL - -Building is only possible from NT and makes use of lex and yacc from -T:\mks - this should be updated to use the GNUPro tools which we use to -build GCC, as the Cygnus toolchain is something we expect to have always -available. - - - -Version 3.15 -============ - -Released by SimonC, 01-Feb-1999 - -Fixed defects - EDN484092 "RCOMP needs to be Symbianised" - EDN584421 "Need to rebuild RCOMP with boilerplated headers" - -Only RCOMP.EXE has been rebuilt. Judging from the timestamps, the other executables -haven't been rebuilt for the last few releases. - -To build rcomp, first run ..\src\BLDEX, then MNT BLDREL - -Building is only possible from the NT and makes use of executables on T: so this can't -be rebuilt by licensees (which doesn't seem to have been a problem so far...) - - - -Version 3.14 -============ - -Released by PNJ, 19-Mar-1997 - -The CORE command and the test procedures rely on NT command extensions. - - -Version 314 mods - - 1. In FILELINE.CPP, FileLineManager::ExtractFileName updated to add - filename information planted by the preprocessor. This is a rewrite of - the code that was removed in the previous release because it was - violating. - 2. Test code now in a formalised framework accessed via MNT TEST. The - formalism isn't perfect because of the limitations imposed by the - legacy command language. See TEST.HTM in the TSRC directory for more - information. The test procedure relies on NT command extensions. - 3. The CORE command procedure has been changed to allow preprocessor - symbols to be defined. See below. - -CORE syntax - -CORE filename [ object_directory [options] ] - -If options are being used the object directory parameter must be present, -the default value is "." for the current directory. - -Options are: - -/UNICODE - Specifies that strings are emitted as Unicode in the resource binary. - Previously, this option was selected with "-u", which is the parameter - currently used by RCOMP itself. -/DEFINE symbol [ symbol...] - Specifies one or more symbols to be defined for the preprocessor pass. - This must be the last option supplied because it is followed by an - arbitrary number of tokens and the command language is so primitive. - - - - - - - - -Version 3.13 -============ - -Released by PNJ, 13-Jan-1997 - -Version number scheme is independent of product-specific E32 chain -numbering. - -This is an interim release, to provide 16-bit character set functionality. -Later releases are planned to provide other requested features. Existing -RSS files produce identical binaries to previous releases when compiled -in the default non-Unicode mode. - -There are some serious defects in the source code which will take -a long time to address properly, eg misuse of assert as a status check. - -1. Minor changes to MNT and build settings. -2. Minor code changes to remove warnings. -3. Renamed STRING.CPP, .H to remove ambiguity with - standard header of the same name. -4. rcscan::yyerror function updated so that it actually - interprets formatted strings instead of ignoring the extra - parameters. -5. Fixed defect in String operator != which was doing the inverse - of what it is supposed to do! -6. Provide a qualifier for Unicode output. -7. Fix erroneous error message if source file not specified. -8. Fixed problem which caused run time fatal errors during - source context switching. -9. Introduce new tokens to differentiate between 8 and 16-bit - text strings. -10. Introduce a CHARACTER_SET token to specify the source - character set. -11. Introduce an extra test component directory. -12. Introduce a command procedure wrapper for RCOMP (called CoRe) - - -Language features ------------------ - -CHARACTER_SET name - -Specifies the character set of the input file. The implementation currently -does not do much with this, but will do in the nexty release or 2. Legal -values for name are currently: - -ASCII, CP1252, CP850, ISOLatin1, ShiftJIS, Unicode - -Note that Unicode source text is not likely to be supported any time soon, -largely because RCOMP relies on LEX and YACC which are not Unicode-aware. - -The default setting in this implementation is CP1252. - - -TEXT, LTEXT and BUF - -Now have explicit 8 and 16-bit variants, eg TEXT8, BUF16. The unadorned -variants are internally converted to the 8 or 16-bit equivalents depending -on the presence of the -u (for unicode) command line qualifier. - -The prefixed counter for an LTEXT16 is still an 8-bit field. - -The zero terminator for a TEXT16 is a 16-bit field. - -For text fields, it is recommended that you continue to use the unadorned -keywords. For binary data, you should use the explicit 8-bit keywords. This -is likely to apply most commonly to the BUF (BUF8) keyword. - - - - - -Version 0.03.12 -=============== - -1) Reduced verbosity. -2) Released a version compatible with NT4. - -Version 0.03.11 -=============== - -1) PVCS'ed RCOMP and generally tidied it up. -2) Fixed empty BUF crash. -3) Fixed extra trailing comma crash. -4) Cleaned up the build warnings. -5) Added ...BUF... where n is an integer giving max length of BUF. -6) The .exe is now called rcomp.exe. - -Version 3.06, MartinW, 05 Jul 96 -================================ -1. Added enum handling. - e.g. - ENUM ExampleEnum { Elem1, Elem2} - STRUCT a { BYTE b;} - RESOURCE a c { b = ExampleEnum::Elem2;} -This should set up b with the value 1. - -Version 3.05, MartinW, 30 May 96 -================================ -1.Deal with long (>42characters) resource names in output to header - file. -2.Prevent assertion failure in case of missing comma after first item - in an array of struct's. - -Version 3.04, MartinW, 29 Apr 96 -================================ -Avoid using cin by reading from a specified file (-s). The -cin approach suffered from something to do with the source file being -left open even when the program ended. This was the case at least with -a test program built using C++ 1.51 and run under NT 3.51. -e.g. void main() { char a; cin << a; } - TestProgram < a.src - del a.src <---- "file in use by another process". - -Version 3.03, MartinW, 18 Apr 96 -================================ -1.Handle syntax error with numbers more effectively so assert does not - fail. -2.Accept 0 for double without warning. - -Version 3.02, MartinW, 11 Apr 96 -================================ -Corrected defect to do with line number in error message for text being -converted to a number. - -Version 3.01, MartinW, 9 Apr 96 -=============================== -1.I added more error handling so that more proper error messages are - given. -2.I altered the error message format so that it is suitable for VC++. - Brief seems to cope with this new format quite happily. VC++ didn't - seem to like e.g. ".\t1.rss" at the start but "C:\rcomp\src\t1.rss" - worked. -3.The drive and directory for the file name specified with -i is used - to provide the full paths for all filenames given in error messages. - If the -i file name is not a full path then the current directory and - drive are used in combination with the partial path to create a full - path. - -Version 3.00, MartinW, 19 Mar 96 -================================ -To use this resource compiler execute "mnt getrel". The egrs.bat file -is an example of how the resource compiler may be run. The GNU -preprocessor is used (t:\tools\gnucpp.exe) first and the output -passed to rc3.exe. The fc4bat.exe file is used to avoid writing the -header output file if it has in fact not changed. - -Details about this version --------------------------- -This is a completely new version based on yacc and lex along with C++. - -Overview of system: - Source file (e.g.pic.rss) - -> Preprocessing - -> Lexer - -> Parser - -> Data structures (using C++ classes) - -> Data file output (e.g. pic.rsg) - -> Header file output (e.g. pic.h) - - The GNU C++ preprocessor was used. The output from this - includes directives giving line numbering following inclusion - of header files. The lexer uses this to store data which the - parser then uses to output error messages in Brief format. - - The lexer and parser are generated by lex and yacc - respectively from rcomp.l and rcomp.y. These define the - tokens and the grammar for the resource script language. - - Supporting C++ classes are compiled and linked along with the - output from lex and yacc. - - The batch file rs.bat takes the file specified by the first - parameter and passes it to the GNU preprocessor. The output - is piped through to rcomp.exe. The names of the data output - file and the header file are specified based on the name - given to rs.bat. The -i flag is used to give the original - name (as passed to the preprocessor) for error reporting. - - A program called fc4bat.exe is used to give an errorlevel if - the specified files do not match. This is used to avoid - changing the date on the header file if it has not changed. - -Issues for porting to other platforms: - 1) atof has been used. The output of this is written to the - rsc file. The format must be that expected by the program - reading the rsc file rather than the format of the - machine used to generate the file. - 2) The MKS versions of yacc and lex were used. These are PC - versions of the UNIX tools. The non-standard features - were avoided however only the PC versions have been used. - 3) Stream handling has been used. Apparently there may be - differences in implementations of this extension to C++. - - +version 8.4.001 +=============== +Released by Lorence Wang, 26/04/2010 + 1) DPDEF145375 RCOMP can not parse data passed to its STDIN correctly + +version 8.3.001 +=============== +Released by Zheng Shen, 16/03/2010 + 1) DPDEF145001 RCOMP failed if uidcrc is not located in the same directory as it is + +version 8.3.000 +=============== +Released by Zheng Shen, 22/02/2010 + 1) DPDEF144562 Build Tools cannot be built in Linux + +version 8.2.008 +=============== +Released by Marvin Shi, 25/01/2010 + 1) DPDEF143586 Add -o2 optimization to rcomp + +version 8.2.007 +=============== +Released by Marvin Shi, 15/01/2010 + 1) DPDEF143836 rcomp produces error messages which should be warning messages + +Version 8.2.006 +=============== +Released by Zheng Shen, 10/12/2009 + 1) DPDEF143045 rcomp produces a warning 'Cannot convert "1.0" + +Version 8.2.005 +=============== +Released by Jason Cui, 31/7/2009 (did not clear build number, should be done by next feature deliery) + 1) SITK v1.4, GT0499, MS3.5.3, DS.1772 PREQ2471: RIT: Resource compiler (RComp) must support characters outside of the BMP + +Version 8.1.005 +=============== +Released by KunalM, 06/03/2007 + + 1) RCOMP ported to the TOOLS2 platform, under PREQ1182, MS3.6.2 + + +Version 8.00.002 +================ +Released by AndrewR, 3/3/2005 + + 1) DEFECT FIX: DEF055559 - Problems building rcomp in VC6 IDE + +Version 8.00.001 +================ +Released by AndrewR, 7/2/2005 + + 1) DEFECT FIX: DEF054981 - tools_rcomp component is updated every day + +Version 8.00.000 +================ +Released by AndrewR, 4/2/2005 + 1) Fixed DEF054617 - rcomp doesn't build from source + 2) Fixed INC049059 - incorrect line number for error reported by rcomp when building \s60\gs + +Version 7.01.009 +============ +Released by KuldipN, 22/07/2004 + Add UID2 and UID3 keywords to RCOMP + (CR HBRT-5YJJ9C Specifying UID2 and UID3 in RSS files) + +Version 7.01.008 +============ +Released by DuskoJ, 10/07/2003 + 1) Fixed DEF022269 Resource value is read incorrectly + 2) Fixed INC036025 RCOMP chinese resource complation problem + +Version 7.01.007 +============ +Released by Jon Chatten, 03/06/2003 + 1) Fixed "DEF025433 RComp core dumps on certain resource files" + 2) Adjusted version number in release.txt to match binary. + + +Version 7.06 +============ +Released by Dusko Jahora, 03/06/2003 + 1) Reverted fix for DEF022269 + + +Version 7.05 +============ +Released by Dusko Jahora, 02/06/2003 +1) DuskoJ + 1) Changes to RCOMP whihch are part of CR PCHY-5L3RDW + "Typhoon must support 16bpp colour". + 2) Fixed DEF022269 Resource value is read incorrectly + (this fix was not submitted on 09/05/2003 because of + an integration error) + + +Version 7.04 +============ + +Released by Dusko Jahora, 09/05/2003 +1) DuskoJ + 1) Fixed DEF022269 Resource value is read incorrectly + + +Version 7.03 +============ + +Released by Dusko Jahora, April 2003 + 1) Fixed defect DEF017151 "RCOMP should be upgraded to support files with UTF8 + signature". + + +1) William + 1) Fixed defect ROS-58VCX8 "RCOMP doesn't allow + in filenames" by removing + the unnecessary validation of the filenames left by the C++ preprocessor. + 2) Fixed defect RED-5ACK5F "Resource compiler creates nothing for empty and bad + counted byte arrays" +2) Dusko + 1) Fixed defect ROS-5B7MHW "RCOMP fails to handle boundary values correctly + for WORD data type" + +NB. The handling of LABEL suggests that it would be pretty easy to add rls_string support +into the compiler directly. + +Version 7.01 +============ + +Released by Jon Chatten, February 2002 + +Fixed defect ROS-56PHFA - Replaced system() call to uidcrc.exe with a call to _spawnlp - +this addresses the IDE-hanging issue when epocrc.pl is integrated as a plug-in with the CW +IDE on Windows 98. + +Removed attempt to absolutely identify uidcrc.exe - this is no longer required as the CW RCOMP/EPOCRC.PL +plug-in now sets the PATH before invoking the command line tools. + + +1) William + 1) Fixed defect ROS-55KJ4U "RCOMP fails if epoc32\tools not on the path" + + +Version 7.00 +============ + +Released by David Batchelor (November/December 2001) + +The format of resource files changes as follows: + +- The initial 2 two-byte values are removed as they are completely redundant. (All the information + they provide can be derived from the last 2 bytes of the file combined with the size of the + file.) +- Resource files now have a standard 4-byte checked-UID field at the start. The first UID is + 0x101f4a6b, to indicate that the resource file potentially contains Unicode compressed according + to the "Standard Compression Scheme for Unicode" (see + http://www.unicode.org/unicode/reports/tr6/tr6-3.2.html). The second and third UIDs may be + specified on the command-line by using an optional parameter of the form + "-{0x12345678,0x9abcdef0}" (without the quotation marks). If "*" is used as the last UID, e.g. + "-{0x600ddea1,*}", then the resource file's "offset" (i.e. the 20-bit number generated from the + resource file's "NAME") is used as the last UID. +- The UID field is immediately followed by a bit-array, one bit for each resource in the resource + file, where each bit indicates whether the corresponding resource contains compressed Unicode. + The bit field is padded up to a multiple of 8-bits (if necessary) with zero bits. +- Each resource which contains compressed Unicode consists of a series of "runs" preceded by a 1 + or 2-byte run-length (1 byte if the run is <128 bytes, else 2 bytes). The run-length value does + not include itself in the byte count that it holds. The first run, the third run, the fifth run + etc contain compressed Unicode. The second run, the fourth run, the sixth run etc contain other + stuff. As the protocol defines that the first run is compressed Unicode, this run may obviously + be of zero length - no subsequent run in that resource may be of zero length. +- Rcomp only uses compressed Unicode for text fields if it yields any benefit (i.e. only if it + actually makes the output file smaller). +- The changes are completely transparent for code that reads resources. + + +Version 6.03 +============ + +Released by William Roberts, 30-Jul-2001 + +Fix defect EXT-4YSCUV "Resource compiler corrupts long strings" +Handle very long C++ comments, which previously caused a "token buffer overflow" message from the +lexical analyser. Avoid overruning the buffer for literals by using a CHECK_APPEND() macro which +discards characters rather than run off the end, giving errors like + +(5) : string too long - 1 ignored +(5) : string too long - 2 ignored + +Avoid overflowing the Value array in string expressions by checking the new length before +agreeing to concatenate the strings. Ultimately it would be best to replace Value[] with +a char* which has been created with strdup() and can therefore be realloc'd to grow the string. + +Fix defect ARG-4TZF7J "RCOMP needs warning waivers registered with SI" +Removed all warnings in tools rel build - some tools deb warnings will appear in rcomp.cpp +because of problems in the mks\etc\yyparse.cpp file, but I didn't want to hide related problems +in any new Symbian code we might add. + +Improve the -v output to show the primitive types being emitted, and to dump the IndexTable as hex +offsets followed by the resource name, e.g. + + IndexTable + IndexTableItem 4 + IndexTableItem c r_eikserv_panic_dialog + IndexTableItem b8 r_eiksrv_oom_event_top + IndexTableItem e4 r_eiksrv_oom_event_bot + IndexTableItem 144 r_eikserv_replace_main_batteries + IndexTableItem 170 r_eikserv_replace_backup_battery + +and + + ResourceHeader r_eiksrv_tasklist_dialog + ++ResourceItemArray + SimpleResourceItem [Long flags] 9 + SimpleResourceItem [LText16 title] + SimpleResourceItem [LLink pages] + SimpleResourceItem [LLink buttons] + StructArrayResourceItem (Level 0) [items] + ArrayLength [Word] 1 + ---------------------- + --ResourceItemArrayArray + ++ResourceItemArray + SimpleResourceItem [Word type] 1001 + SimpleResourceItem [LText16 prompt] + SimpleResourceItem [Word id] 1 + SimpleResourceItem [Long itemflags] 0 + StructTypeResourceItem (Level 0) [control] + ---------------------- + ++ResourceItemArray + SimpleResourceItem [Byte version] 0 + SimpleResourceItem [Word flags] 0 + SimpleResourceItem [Word height] 8 + SimpleResourceItem [Word width] 20 + SimpleResourceItem [LLink array_id] + ---------------------- + SimpleResourceItem [LText16 trailer] + ---------------------- + +Together these changes should make it significantly easier to step through the binary image of a +resource and work out which element has changed unexpectedly. + + +Version 6.02 +============ + +Released by William Roberts, 15-Feb-2001 + +Fix awful defect in version 6.01, which caused negative integer constants to be written to the file as -1. + +When testing with LOCKIT, RCOMP developer should be aware that the version of RCOMP.EXE used by lockit +is kept in \lockit\tools, not \epoc32\tools. + + +Version 6.01 +============ + +Released by William Roberts, 14-Feb-2001 + +Redefined character literals ('x') to be effectively strings so that they can contain UTF8 encodings +for interesting characters. This is handled using the same lexical rules as string literals, so +the limited escape processing is also supported. The introduction of strings surrounded by single-quotes +means that the sequence \' is now accepted as standing for '. + +If the character literal string decodes to more than one Unicode character, a warning is given and the +rest of the string is ignored. The prevailing source character encoding is used, but there is no support +narrow character literals in the difficult part of the CP1252 range: the interpretation of the literal +is always "the Unicode encoding for the first character of the string". For example, even in a +CP1252 source file building a narrow resource, a literal containing the Euro symbol will be interpreted +as 0x20ac, not 0x80. + +LTEXT strings are now checked to ensure that they are less than 256 characters in length. + +The NAME statement can now take a string literal or a label, instead of the previous behaviour where the +lexical analyser handled the following word differently. Any RSS file which used a keyword as a name, +for example WORD.RSS, will need to be changed to specify the name as a literal: the preferred syntax +is to use string literals in all cases. + + +Version 3.18 +============ + +Released by William Roberts, 05-Aug-1999. + +Requires BAFL 092. + +Changed the handling of Unicode string resources (TEXT16 and LTEXT16) to ensure that the +Unicode characters are aligned to a multiple of 2 bytes when the resource is used. + +Resources are never used in place: instead RResourceFile::AllocReadLC creates an HBufC8 to hold a +copy of the data. This means that rather than aligning from the start of the entire resource file, +instead we have to align to the start of the individual resource, because the data in an HBufC8 +always starts at an aligned address. + +Added RCBinaryStream::Align(int nBytes) and RCBinaryStream::SetAlignBase() to support the +generation of the necessary padding, and call them from suitable places in RCOSTRM.CPP. + +Also added code to add 1 to the offset of the end of the table of resource offsets: this is tested +in BAFL as a marker to indicate the new format of resource file. + +Added a /verbose flag to core.cmd which invokes RCOMP with -v. + +Added #pragma warning( disable : 4710 ) in a couple of places to cut down on the number of +unnecessary and useless "warnings". + +Regenerated the test resources. + + +Version 3.17 +============ + +Released by William Roberts, 25-Jun-1999. + +Fixed defect where embedded Unicode characters could cause BUF strings to fail a length check. +Updated test code include a check for this. + +Added more stuff for the Engineering Automated Build. + + +Version 3.16 +============ + +Released by Pute, 9-Jun-1999. Based on work by William Roberts, +26-May-1999 described in the "William's notes" section below. + + +Character sets +-------------- + +We are moving towards a specific principle of character sets for RCOMP. + +Previously, the character set used by RCOMP was not well defined, later we +added the CHARACTER_SET identifier. This implied that any specific values +inserted into strings in format would be in the character set of the +source. + +In this design RCOMP will have trouble handling multibyte encodings like +Shift-JIS because the tools it relies upon, LEX and YACC, are based on +single-octet encodings only. Sometimes a multibyte encoding will produce +artefacts that appear to be syntax elements such as double quote marks. + +In future the intention is that RCOMP uses UTF-8 encoding internally, +provided by a pre-processing phase. This release is an interim step. + +In this release, when explicit values are inserted in text strings, they +are interpreted as Unicode values and converted to UTF-8. To retain +backward compatibility with CP1252 source, values 80-9F are also permitted +and these will be mapped to Unicode as before when the source character set +is defined to be CP1252. The use of explicit values 80-9F is deprecated +however. + +The default input character set is CP1252. Previously, the default +character set was "unknown". This possibility is no-longer supported. +This was also contrary to documentation. + + +Details: + +Test command procedure updated and enhanced. + +Test comparison files TUTEXT8.RSC and TUTEXT16.RSC have been updated to +allow for the introduction of the extra characters in the CP1252 character +set. (128 used to be "not used" and is now the euro sign) + +Note that compilation warning messages about deprecated characters will +appear durng this test. + +A new test source file TWTEXT.RSS and associated reference binaries have +been added to the test suite to demonstrate explicit use of values >255. + + + + +William's notes (edited by Pute): +--------------- + +Defined a new "character set" called UTF8, which supports the UTF8 +encoding of Unicode strings. +This actually allows the whole resource source file to be entered as +UTF8 if required. However the default charset remains CP1252. + +Arranged to support embedded Unicode characters constructed using the + notation, to support the use of 0x07ED as the end-of-paragraph +marker (see ETEXT 120). This exploits the UTF8 support by inserting the +appropriate UTF8 sequence into the 8-bit data. + +The embedded Unicode characters are also supported in the CP1252 +character set, with internal use of 0x81 as an "escape" character +indicating that the following bytes are a UTF8 encoded character. This +allows existing CP1252 resource source files to be used with the new +ETEXT. + +Added the Euro and the Z caron encodings to the cp1252_exceptions table. + + +Only RCOMP.EXE has been rebuilt. Judging from the timestamps, the other +executables haven't been rebuilt for the last few releases. + +To build rcomp, first run ..\src\BLDEX, then MNT BLDREL + +Building is only possible from NT and makes use of lex and yacc from +T:\mks - this should be updated to use the GNUPro tools which we use to +build GCC, as the Cygnus toolchain is something we expect to have always +available. + + + +Version 3.15 +============ + +Released by SimonC, 01-Feb-1999 + +Fixed defects + EDN484092 "RCOMP needs to be Symbianised" + EDN584421 "Need to rebuild RCOMP with boilerplated headers" + +Only RCOMP.EXE has been rebuilt. Judging from the timestamps, the other executables +haven't been rebuilt for the last few releases. + +To build rcomp, first run ..\src\BLDEX, then MNT BLDREL + +Building is only possible from the NT and makes use of executables on T: so this can't +be rebuilt by licensees (which doesn't seem to have been a problem so far...) + + + +Version 3.14 +============ + +Released by PNJ, 19-Mar-1997 + +The CORE command and the test procedures rely on NT command extensions. + + +Version 314 mods + + 1. In FILELINE.CPP, FileLineManager::ExtractFileName updated to add + filename information planted by the preprocessor. This is a rewrite of + the code that was removed in the previous release because it was + violating. + 2. Test code now in a formalised framework accessed via MNT TEST. The + formalism isn't perfect because of the limitations imposed by the + legacy command language. See TEST.HTM in the TSRC directory for more + information. The test procedure relies on NT command extensions. + 3. The CORE command procedure has been changed to allow preprocessor + symbols to be defined. See below. + +CORE syntax + +CORE filename [ object_directory [options] ] + +If options are being used the object directory parameter must be present, +the default value is "." for the current directory. + +Options are: + +/UNICODE + Specifies that strings are emitted as Unicode in the resource binary. + Previously, this option was selected with "-u", which is the parameter + currently used by RCOMP itself. +/DEFINE symbol [ symbol...] + Specifies one or more symbols to be defined for the preprocessor pass. + This must be the last option supplied because it is followed by an + arbitrary number of tokens and the command language is so primitive. + + + + + + + + +Version 3.13 +============ + +Released by PNJ, 13-Jan-1997 + +Version number scheme is independent of product-specific E32 chain +numbering. + +This is an interim release, to provide 16-bit character set functionality. +Later releases are planned to provide other requested features. Existing +RSS files produce identical binaries to previous releases when compiled +in the default non-Unicode mode. + +There are some serious defects in the source code which will take +a long time to address properly, eg misuse of assert as a status check. + +1. Minor changes to MNT and build settings. +2. Minor code changes to remove warnings. +3. Renamed STRING.CPP, .H to remove ambiguity with + standard header of the same name. +4. rcscan::yyerror function updated so that it actually + interprets formatted strings instead of ignoring the extra + parameters. +5. Fixed defect in String operator != which was doing the inverse + of what it is supposed to do! +6. Provide a qualifier for Unicode output. +7. Fix erroneous error message if source file not specified. +8. Fixed problem which caused run time fatal errors during + source context switching. +9. Introduce new tokens to differentiate between 8 and 16-bit + text strings. +10. Introduce a CHARACTER_SET token to specify the source + character set. +11. Introduce an extra test component directory. +12. Introduce a command procedure wrapper for RCOMP (called CoRe) + + +Language features +----------------- + +CHARACTER_SET name + +Specifies the character set of the input file. The implementation currently +does not do much with this, but will do in the nexty release or 2. Legal +values for name are currently: + +ASCII, CP1252, CP850, ISOLatin1, ShiftJIS, Unicode + +Note that Unicode source text is not likely to be supported any time soon, +largely because RCOMP relies on LEX and YACC which are not Unicode-aware. + +The default setting in this implementation is CP1252. + + +TEXT, LTEXT and BUF + +Now have explicit 8 and 16-bit variants, eg TEXT8, BUF16. The unadorned +variants are internally converted to the 8 or 16-bit equivalents depending +on the presence of the -u (for unicode) command line qualifier. + +The prefixed counter for an LTEXT16 is still an 8-bit field. + +The zero terminator for a TEXT16 is a 16-bit field. + +For text fields, it is recommended that you continue to use the unadorned +keywords. For binary data, you should use the explicit 8-bit keywords. This +is likely to apply most commonly to the BUF (BUF8) keyword. + + + + + +Version 0.03.12 +=============== + +1) Reduced verbosity. +2) Released a version compatible with NT4. + +Version 0.03.11 +=============== + +1) PVCS'ed RCOMP and generally tidied it up. +2) Fixed empty BUF crash. +3) Fixed extra trailing comma crash. +4) Cleaned up the build warnings. +5) Added ...BUF... where n is an integer giving max length of BUF. +6) The .exe is now called rcomp.exe. + +Version 3.06, MartinW, 05 Jul 96 +================================ +1. Added enum handling. + e.g. + ENUM ExampleEnum { Elem1, Elem2} + STRUCT a { BYTE b;} + RESOURCE a c { b = ExampleEnum::Elem2;} +This should set up b with the value 1. + +Version 3.05, MartinW, 30 May 96 +================================ +1.Deal with long (>42characters) resource names in output to header + file. +2.Prevent assertion failure in case of missing comma after first item + in an array of struct's. + +Version 3.04, MartinW, 29 Apr 96 +================================ +Avoid using cin by reading from a specified file (-s). The +cin approach suffered from something to do with the source file being +left open even when the program ended. This was the case at least with +a test program built using C++ 1.51 and run under NT 3.51. +e.g. void main() { char a; cin << a; } + TestProgram < a.src + del a.src <---- "file in use by another process". + +Version 3.03, MartinW, 18 Apr 96 +================================ +1.Handle syntax error with numbers more effectively so assert does not + fail. +2.Accept 0 for double without warning. + +Version 3.02, MartinW, 11 Apr 96 +================================ +Corrected defect to do with line number in error message for text being +converted to a number. + +Version 3.01, MartinW, 9 Apr 96 +=============================== +1.I added more error handling so that more proper error messages are + given. +2.I altered the error message format so that it is suitable for VC++. + Brief seems to cope with this new format quite happily. VC++ didn't + seem to like e.g. ".\t1.rss" at the start but "C:\rcomp\src\t1.rss" + worked. +3.The drive and directory for the file name specified with -i is used + to provide the full paths for all filenames given in error messages. + If the -i file name is not a full path then the current directory and + drive are used in combination with the partial path to create a full + path. + +Version 3.00, MartinW, 19 Mar 96 +================================ +To use this resource compiler execute "mnt getrel". The egrs.bat file +is an example of how the resource compiler may be run. The GNU +preprocessor is used (t:\tools\gnucpp.exe) first and the output +passed to rc3.exe. The fc4bat.exe file is used to avoid writing the +header output file if it has in fact not changed. + +Details about this version +-------------------------- +This is a completely new version based on yacc and lex along with C++. + +Overview of system: + Source file (e.g.pic.rss) + -> Preprocessing + -> Lexer + -> Parser + -> Data structures (using C++ classes) + -> Data file output (e.g. pic.rsg) + -> Header file output (e.g. pic.h) + + The GNU C++ preprocessor was used. The output from this + includes directives giving line numbering following inclusion + of header files. The lexer uses this to store data which the + parser then uses to output error messages in Brief format. + + The lexer and parser are generated by lex and yacc + respectively from rcomp.l and rcomp.y. These define the + tokens and the grammar for the resource script language. + + Supporting C++ classes are compiled and linked along with the + output from lex and yacc. + + The batch file rs.bat takes the file specified by the first + parameter and passes it to the GNU preprocessor. The output + is piped through to rcomp.exe. The names of the data output + file and the header file are specified based on the name + given to rs.bat. The -i flag is used to give the original + name (as passed to the preprocessor) for error reporting. + + A program called fc4bat.exe is used to give an errorlevel if + the specified files do not match. This is used to avoid + changing the date on the header file if it has not changed. + +Issues for porting to other platforms: + 1) atof has been used. The output of this is written to the + rsc file. The format must be that expected by the program + reading the rsc file rather than the format of the + machine used to generate the file. + 2) The MKS versions of yacc and lex were used. These are PC + versions of the UNIX tools. The non-standard features + were avoided however only the PC versions have been used. + 3) Stream handling has been used. Apparently there may be + differences in implementations of this extension to C++. + + diff -r 122d2b873fd1 -r 30b30f9da0b7 bintools/rcomp/group/rcomp.mmp --- a/bintools/rcomp/group/rcomp.mmp Fri Jun 25 20:58:33 2010 +0800 +++ b/bintools/rcomp/group/rcomp.mmp Tue Jun 29 14:52:54 2010 +0800 @@ -1,47 +1,47 @@ -/* -* Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of the License "Eclipse Public License v1.0" -* which accompanies this distribution, and is available -* at the URL "http://www.eclipse.org/legal/epl-v10.html". -* -* Initial Contributors: -* Nokia Corporation - initial contribution. -* -* Contributors: -* -* Description: -* -*/ - - -TARGET rcomp.exe - -TARGETTYPE exe - -SOURCEPATH . - -SOURCEPATH ../src -SOURCE main.cpp -SOURCE ARRAY.CPP ASTRING.CPP CCODES.CPP CTABLE.CPP -SOURCE DATATYPE.CPP ERRORHAN.CPP FILEACC.CPP FILELINE.CPP -SOURCE INDEXTAB.CPP LINKLIST.CPP MEM.CPP -SOURCE NAMEIDMA.CPP NUMVAL.CPP RCBINSTR.CPP -SOURCE RCOSTRM.CPP -SOURCE RCSCAN.CPP RCSTACK.CPP RESOURCE.CPP -SOURCE STACK.CPP STRINGAR.CPP STRUCTST.CPP -SOURCE UNICODE_COMPRESSOR.CPP -SOURCE localise.cpp QUALIFAR.CPP -SOURCE messages.cpp - -SOURCE rcompl.cpp rcomp.cpp - -userinclude ../inc -SYSTEMINCLUDE ../src - -MACRO _WIN32 - -OPTION GCC -w //Disabling warnings for TOOLS2 build, since GCC warns of code generated by bison - -VENDORID 0x70000001 +/* +* Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +TARGET rcomp.exe + +TARGETTYPE exe + +SOURCEPATH . + +SOURCEPATH ../src +SOURCE main.cpp +SOURCE ARRAY.CPP ASTRING.CPP CCODES.CPP CTABLE.CPP +SOURCE DATATYPE.CPP ERRORHAN.CPP FILEACC.CPP FILELINE.CPP +SOURCE INDEXTAB.CPP LINKLIST.CPP MEM.CPP +SOURCE NAMEIDMA.CPP NUMVAL.CPP RCBINSTR.CPP +SOURCE RCOSTRM.CPP +SOURCE RCSCAN.CPP RCSTACK.CPP RESOURCE.CPP +SOURCE STACK.CPP STRINGAR.CPP STRUCTST.CPP +SOURCE UNICODE_COMPRESSOR.CPP +SOURCE localise.cpp QUALIFAR.CPP +SOURCE messages.cpp + +SOURCE rcompl.cpp rcomp.cpp + +userinclude ../inc +SYSTEMINCLUDE ../src + +// MACRO _WIN32 + +OPTION GCC -O2 -w + +VENDORID 0x70000001 diff -r 122d2b873fd1 -r 30b30f9da0b7 bintools/rcomp/group/rcomp.mrp --- a/bintools/rcomp/group/rcomp.mrp Fri Jun 25 20:58:33 2010 +0800 +++ b/bintools/rcomp/group/rcomp.mrp Tue Jun 29 14:52:54 2010 +0800 @@ -1,7 +1,7 @@ component dev_build_bintools_rcomp -source \src\tools\dev\build\bintools\rcomp -binary \src\tools\dev\build\bintools\rcomp\group all -exports \src\tools\dev\build\bintools\rcomp\group +source \src\tools\build\bintools\rcomp +binary \src\tools\build\bintools\rcomp\group all +exports \src\tools\build\bintools\rcomp\group binary \epoc32\release\tools2\rel\rcomp.exe diff -r 122d2b873fd1 -r 30b30f9da0b7 bintools/rcomp/inc/VERSION.H --- a/bintools/rcomp/inc/VERSION.H Fri Jun 25 20:58:33 2010 +0800 +++ b/bintools/rcomp/inc/VERSION.H Tue Jun 29 14:52:54 2010 +0800 @@ -1,23 +1,23 @@ -/* -* Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of the License "Eclipse Public License v1.0" -* which accompanies this distribution, and is available -* at the URL "http://www.eclipse.org/legal/epl-v10.html". -* -* Initial Contributors: -* Nokia Corporation - initial contribution. -* -* Contributors: -* -* Description: -* -*/ - - -const char version[]="8.2"; - -const char build[]="005"; - -// end of version.h +/* +* Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +const char version[]="8.4"; + +const char build[]="001"; + +// end of version.h diff -r 122d2b873fd1 -r 30b30f9da0b7 bintools/rcomp/inc/main.h --- a/bintools/rcomp/inc/main.h Fri Jun 25 20:58:33 2010 +0800 +++ b/bintools/rcomp/inc/main.h Tue Jun 29 14:52:54 2010 +0800 @@ -1,103 +1,106 @@ -/* -* Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of the License "Eclipse Public License v1.0" -* which accompanies this distribution, and is available -* at the URL "http://www.eclipse.org/legal/epl-v10.html". -* -* Initial Contributors: -* Nokia Corporation - initial contribution. -* -* Contributors: -* -* Description: -* VT fix here -* -*/ - - -#ifndef __MAIN_H__ -#define __MAIN_H__ - -#ifdef __VC32__ -#pragma warning( disable : 4786 ) // identifier truncated in debugging information. -#pragma warning( push, 1 ) // MS STL libraries do not compile cleanly, temporarily set warning level to 1 -#pragma warning( disable : 4530 ) // and disable this one as well. -#pragma warning(disable : 4710 ) -#endif -#include -#include -#ifdef __VC32__ -#pragma warning( pop ) -#endif - -// VT fix for Linux -#ifdef __LINUX__ - #include -#endif // LINUX -// end VT - -#include "STRUCTST.H" -#include "RCSTACK.H" -#include "INDEXTAB.H" -#include "FILELINE.H" -#include "Parser.h" -#include "qualifar.h" -#include "messages.h" - -struct RlsValue -{ - RlsValue(const String* aFileName, int aLineNo, - const char*a, TRlsType aType, TRlsCardinality aCard) - : iValue(a), iType(aType), iCardinality(aCard), iCitationCount(0), - iMaximumLength(0xFFFFFFF), - iLineNumber(aLineNo), iFileName(aFileName) { } - RlsValue(const String* aFileName, int aLineNo, - const char*a, TRlsType aType, TRlsCardinality aCard, - unsigned long aMaximumLength) - : iValue(a), iType(aType), iCardinality(aCard), iCitationCount(0), - iMaximumLength(aMaximumLength), - iLineNumber(aLineNo), iFileName(aFileName) { } - - String iValue; - TRlsType iType; - TRlsCardinality iCardinality; - int iCitationCount; - unsigned long iMaximumLength; - int iLineNumber; - const String* iFileName; -}; - -typedef std::map TNameIndex; -typedef TNameIndex::iterator TNameIndexIterator; - - -// Global data is held in a structure allocated in main(). This is in order for the memory leakage -// mechanism to be able see the allocation of this data. -struct GlobalData -{ - StructHeaderArray SHA; - ResourceItemArrayStack RIAStack; - StructResourceItemStack SRIStack; - IndexTable Index; - NameIdMap ResourceNameIds; - FileLineManager FileLineHandler; - NameIdMap EnumValues; - std::vector RlsValues; - TNameIndex RlsNameIndex; // index from Label -> RlsValues[] - bool WarningMultiExplained; - StringArray AllIdentifiers; - QualifiedStringArray UsedIdentifiers; - MessageArray Messages; -}; - -extern GlobalData *pG; -extern int verbose; -extern unsigned short logmemorysetting; // remove this - - - -extern int ParseSourceFile(FILE* aFile, unsigned short aYYDebug); - -#endif // end VT __MAIN_H__ +/* +* Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* VT fix here +* +*/ + + +#ifndef __MAIN_H__ +#define __MAIN_H__ + +#ifdef __VC32__ +#pragma warning( disable : 4786 ) // identifier truncated in debugging information. +#pragma warning( push, 1 ) // MS STL libraries do not compile cleanly, temporarily set warning level to 1 +#pragma warning( disable : 4530 ) // and disable this one as well. +#pragma warning(disable : 4710 ) +#endif +#include +#include +#ifdef __VC32__ +#pragma warning( pop ) +#endif + +// VT fix for Linux +#ifdef __LINUX__ + #include +#endif // LINUX +// end VT + +#include "STRUCTST.H" +#include "RCSTACK.H" +#include "INDEXTAB.H" +#include "FILELINE.H" +#include "Parser.h" +#include "qualifar.h" +#include "messages.h" + +struct RlsValue +{ + RlsValue(const String* aFileName, int aLineNo, + const char*a, TRlsType aType, TRlsCardinality aCard) + : iValue(a), iType(aType), iCardinality(aCard), iCitationCount(0), + iMaximumLength(0xFFFFFFF), + iLineNumber(aLineNo), iFileName(aFileName) { } + RlsValue(const String* aFileName, int aLineNo, + const char*a, TRlsType aType, TRlsCardinality aCard, + unsigned long aMaximumLength) + : iValue(a), iType(aType), iCardinality(aCard), iCitationCount(0), + iMaximumLength(aMaximumLength), + iLineNumber(aLineNo), iFileName(aFileName) { } + + String iValue; + TRlsType iType; + TRlsCardinality iCardinality; + int iCitationCount; + unsigned long iMaximumLength; + int iLineNumber; + const String* iFileName; +}; + +typedef std::map TNameIndex; +typedef TNameIndex::iterator TNameIndexIterator; + + +// Global data is held in a structure allocated in main(). This is in order for the memory leakage +// mechanism to be able see the allocation of this data. +struct GlobalData +{ + StructHeaderArray SHA; + ResourceItemArrayStack RIAStack; + StructResourceItemStack SRIStack; + IndexTable Index; + NameIdMap ResourceNameIds; + FileLineManager FileLineHandler; + NameIdMap EnumValues; + std::vector RlsValues; + TNameIndex RlsNameIndex; // index from Label -> RlsValues[] + bool WarningMultiExplained; + StringArray AllIdentifiers; + QualifiedStringArray UsedIdentifiers; + MessageArray Messages; + char* StdInBuffer ; + unsigned long StdInBufLength ; + unsigned long StdInfBufPos ; +}; + +extern GlobalData *pG; +extern int verbose; +extern unsigned short logmemorysetting; // remove this + + + +extern int ParseSourceFile(FILE* aFile, unsigned short aYYDebug); + +#endif // end VT __MAIN_H__ diff -r 122d2b873fd1 -r 30b30f9da0b7 bintools/rcomp/src/NUMVAL.CPP --- a/bintools/rcomp/src/NUMVAL.CPP Fri Jun 25 20:58:33 2010 +0800 +++ b/bintools/rcomp/src/NUMVAL.CPP Tue Jun 29 14:52:54 2010 +0800 @@ -1,473 +1,473 @@ -/* -* Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of the License "Eclipse Public License v1.0" -* which accompanies this distribution, and is available -* at the URL "http://www.eclipse.org/legal/epl-v10.html". -* -* Initial Contributors: -* Nokia Corporation - initial contribution. -* -* Contributors: -* -* Description: -* -*/ - - -#include -#include -#include -#include - -#if defined(__MSVCDOTNET__) || defined(__TOOLS2__) -#include -#include -using std::cerr; -using std::endl; -#else //!__MSVCDOTNET__ -#ifndef __LINUX__ -#include -#endif //!__LINUX__ -#endif //__MSVCDOTNET__ - -#include "ASTRING.H" -#include "NUMVAL.H" -#include "STRUCTST.H" -#include "Parser.h" -#include "rcomp.hpp" -#include "MEM.H" -#include "ERRORHAN.H" -#include "RCBINSTR.H" - -#if defined(__VC32__) -#pragma warning( disable : 4702 ) // unreachable code -#endif - -NumericValue::NumericValue( const String & Source, DataType NumericValueType): - iNumericValueType( NumericValueType), - iData( NULL), - iULongValue( 0), - iSignedValue( 0), - iDoubleValue( 0.0) - { - AllocateSpace(); - ConvertToNumber( Source); - } - -NumericValue::NumericValue( DataType NumericValueType): - iNumericValueType( NumericValueType), - iData( NULL), - iULongValue( 0), - iSignedValue( 0), - iDoubleValue( 0.0) - { - AllocateSpace(); - } - -NumericValue::NumericValue( unsigned long ValueToSet, DataType NumericValueType): - iNumericValueType( NumericValueType), - iData( NULL), - iULongValue( 0), - iSignedValue( 0), - iDoubleValue( 0.0) - { - AllocateSpace(); - StoreValue( ValueToSet); - } - -NumericValue::~NumericValue() - { - delete [] iData; - } - -NumericValue::NumericValue( const NumericValue & Source): - iNumericValueType( Source.iNumericValueType), - iData( NULL), - iULongValue( 0), - iSignedValue( 0), - iDoubleValue( 0.0) - { - AllocateSpace(); - memcpy( iData, Source.iData, iSize); - } - -void NumericValue::AllocateSpace() - { - switch(iNumericValueType) - { - case L_BYTE: - iData = new unsigned char [1]; - iSize = 1; - break; - case L_WORD: - iData = new unsigned char [2]; - iSize = 2; - break; - case L_LONG: - iData = new unsigned char [4]; - iSize = 4; - break; - default: - if ( iNumericValueType != L_DOUBLE) - assert(0); // Cannot use NumericValue for specified data type. - } - - if ( iNumericValueType != L_DOUBLE && iData == NULL) - { - ErrorHandler::OutputErrorLine( "Failed to allocate space for number."); - exit(1); - } - } - -const unsigned char * NumericValue::Data() const - { - return iData; - } - -unsigned long NumericValue::Size() const - { - return iSize; - } - -DataType NumericValue::NumericValueType() const - { - return iNumericValueType; - } - -void NumericValue::ConvertToNumber( const String & Source) - { - if ( iNumericValueType == L_DOUBLE) - ConvertToDouble( Source); - else - ConvertToNatural( Source); - } - -void NumericValue::ConvertToDouble( const String & Source) - { - assert( iNumericValueType == L_DOUBLE); - assert( Source.Length() > 0); - - double d = atof( Source.GetAssertedNonEmptyBuffer()); - if ( d == 0.0 && !( Source == "0.0" || Source == "0") ) - { MOFF; cerr << "atof may have failed for " << Source << endl; MON;} - - iDoubleValue = d; - } - -#if defined(__VC32__) -#pragma warning( disable : 4706 ) // assignment within conditional expression -#endif - -void NumericValue::ConvertToNatural( const String & Source) - { - unsigned long LongValue = 0; - - assert( sizeof( unsigned long) >= 4); // Assume that LongValue can hold at least 2^32 - 1. - - const char * pSourceChar = Source.iRep; - int bLeadingHyphen = 0; - int bHexNumber = 0; - - if ( pSourceChar[0] == '0' && pSourceChar[1] == 'x') - { - bHexNumber = 1; - pSourceChar++; - pSourceChar++; - } - - if ( pSourceChar[0] == '-') - { - bLeadingHyphen = 1; - pSourceChar++; - } - - while ( * pSourceChar != '\0') - { - unsigned char DigitValue; - - if ( bHexNumber) - { - assert( isxdigit( * pSourceChar) ); - if ( isdigit( * pSourceChar) ) - DigitValue = (unsigned char)(* pSourceChar - '0'); - else - DigitValue = (unsigned char)(toupper( * pSourceChar) - 'A' + 10); - if (LongValue >= 0x10000000) - { - String st("Number \""); - st += Source; - st += "\" is too big "; - ErrorHandler::OutputErrorLine(st); //prevents overflow if number is bigger than 2^32 - 1. - } - LongValue = LongValue * 16 + DigitValue; - } - else - { - if ( ! isdigit( * pSourceChar) ) - { - String s( "Cannot convert \""); - s += Source; - s += "\" to a number."; - ErrorHandler::OutputErrorLine( s); - exit(1); - // unreachable code - } - DigitValue = (unsigned char)(* pSourceChar - '0'); - if ((LongValue > 429496729) || ((LongValue == 429496729) && (DigitValue > 5))) - { - String st("Number \""); - st += Source; - st += "\" is too big "; - ErrorHandler::OutputErrorLine(st); //prevents overflow if number is bigger than 2^32 - 1. - } - LongValue = LongValue * 10 + DigitValue; - } - pSourceChar++; - assert( ( pSourceChar - Source.iRep) < 10000); // Safety check! - } - - int inrange=0; - - // Check value is within the allowed range for the type taking into account - // a leading hyphen (minus sign) if there was one. - switch( iNumericValueType) - { - case L_BYTE: // L_BYTE is 8 bits long. - if ( bLeadingHyphen) - { - if ( ! ( inrange = (LongValue <= 128) ) ) // 2 ^ 7 - ErrorHandler::OutputErrorLine( "Number too low for BYTE"); - } - else - if ( ! ( inrange = (LongValue <= 0xFF) ) ) - ErrorHandler::OutputErrorLine( "Number too big for BYTE"); - break; - case L_WORD: // L_WORD is 16-bits long. - if ( bLeadingHyphen) - { - if ( ! ( inrange = (LongValue <= 32768) ) ) // 2^15 - ErrorHandler::OutputErrorLine( "Number too low for WORD"); - } - else - if ( ! ( inrange = (LongValue <= 0xFFFF) ) ) - ErrorHandler::OutputErrorLine( "Number too big for WORD"); - break; - case L_LONG: // L_LONG is 32-bits long - if ( bLeadingHyphen) - { - if ( ! ( inrange = (LongValue <= 0x80000000) ) ) // 2^31 - ErrorHandler::OutputErrorLine( "Number too low for LONG"); - } - else - if ( ! ( inrange = (LongValue <= 0xFFFFFFFF ) ) ) // This test is a bit pointless as long cannot be greater than 0xffffffff - ErrorHandler::OutputErrorLine( "Number too big for LONG"); - break; - default: - assert(0); // Other data types cannot be converted to natural numbers. - } - - if(!inrange) - exit(1); - - StoreValue( LongValue); - - // If there was a hyphen then make the stored number negative (using two's complement). - if ( bLeadingHyphen) - { - LongValue = (LongValue ^ 0xFFFFFFFFu)+1; - - // Output file will be treated as little-endian. - switch ( iNumericValueType) - { - case L_LONG: - iData[3] = (unsigned char)((LongValue & 0xFF000000) >> 24); - iData[2] = (unsigned char)((LongValue & 0xFF0000) >> 16); - case L_WORD: - iData[1] = (unsigned char)((LongValue & 0xFF00) >> 8); - case L_BYTE: - iData[0] = (unsigned char)(LongValue & 0xFF); - } - } - } - -#if defined(__VC32__) -#pragma warning( default : 4706 ) // assignment within conditional expression -#endif - -void NumericValue::StoreValue( unsigned long LongValue) - { - iULongValue = LongValue; - - if ( LongValue <= 0x80000000) - iSignedValue = (unsigned long) LongValue; - - int inrange = 1; - - switch( iNumericValueType) - { - case L_BYTE: - inrange = ( LongValue <= 0xFF); - break; - case L_WORD: - inrange = ( LongValue <= 0xFFFF); - break; - case L_LONG: - inrange = ( LongValue <= 0xFFFFFFFF); - } - - if ( ! inrange) - { - ErrorHandler::OutputErrorLine( "Numeric value out of range for specified type"); - exit(1); - } - - // Output file will be treated as little-endian. - switch ( iNumericValueType) - { - case L_LONG: - iData[3] = (unsigned char)((LongValue & 0xFF000000) >> 24); - iData[2] = (unsigned char)((LongValue & 0xFF0000) >> 16); - case L_WORD: - iData[1] = (unsigned char)((LongValue & 0xFF00) >> 8); - case L_BYTE: - iData[0] = (unsigned char)(LongValue & 0xFF); - } - } - -template class __CompileTimeAssert {public: __CompileTimeAssert(...) {}}; -template<> class __CompileTimeAssert {}; -struct COMPILE_TIME_ERROR {}; -#define COMPILE_TIME_ASSERT(aCondition) { __CompileTimeAssert<(aCondition)> __temp = __CompileTimeAssert<(aCondition)>(COMPILE_TIME_ERROR()); } - -RCBinaryStream & operator<< ( RCBinaryStream & os, NumericValue o) - { - switch( o.iNumericValueType) - { - case L_BYTE: - os.Write( o.iData, 1); - break; - case L_WORD: - os.Write( o.iData, 2); - break; - case L_LONG: - os.Write( o.iData, 4); - break; - case L_DOUBLE: - COMPILE_TIME_ASSERT(sizeof(double) == 8); - os.Write(reinterpret_cast(&o.iDoubleValue), 8); - break; - default: - assert(0); - } - - return os; - } - -void NumericValue::StreamOut(ResourceDataStream& aStream) const - { - switch (iNumericValueType) - { - case L_BYTE: - aStream.StreamIn(iData, 1); - break; - case L_WORD: - aStream.StreamIn(iData, 2); - break; - case L_LONG: - aStream.StreamIn(iData, 4); - break; - case L_DOUBLE: - COMPILE_TIME_ASSERT(sizeof(double) == 8); - aStream.StreamIn(reinterpret_cast(&iDoubleValue), 8); - break; - default: - assert(0); - } - } - -NumericValue & NumericValue::operator= ( unsigned long ValueToSet) - { - StoreValue( ValueToSet); - - return * this; - } - -unsigned long NumericValue::GetULong() const - { - return iULongValue; - } - -long NumericValue::GetLong() const - { - assert( iULongValue <= 2147483647); // Check that we are not holding a number that is really positive only. - return iSignedValue; - } - -bool NumericValue::CheckSigned(unsigned long aValue, DataType aNumericValueType) - { - switch (aNumericValueType) - { - case L_BYTE: - if (aValue > 0x7f) return false; - break; - case L_WORD: - if (aValue > 0x7fff) return false; - break; - case L_LONG: - if (aValue > 0x7fffffff) return false; - break; - default: - assert(0); - } - return true; - } - -String NumericValue::ltoa( long Source) - { - char v[10]; // long can have no more than 10 digits in this implementation. - char * pv = v; - long x; - - if ( Source < 0) - x = - Source; - else - x = Source; - - if ( x == 0) - * pv++ = '0'; - else - { - while( x > 0) - { - assert( pv <= (v+9) ); - - * pv = char(x%10 + '0'); - pv++; - x /= 10; - } - } - - // Now reverse digits so they are in the correct order. Put in terminating null and hyphen - // if necessary. - - char r[12]; - char * pr = r; - - if ( Source < 0) - { - r[0] = '-'; - pr++; - } - - while( pv != v) - { - assert( pr < (r+11) ); - * pr++ = * --pv; - } - - * pr = '\0'; - - return r; - } +/* +* Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#include +#include +#include +#include + +#if defined(__MSVCDOTNET__) || defined(__TOOLS2__) +#include +#include +using std::cerr; +using std::endl; +#else //!__MSVCDOTNET__ +#ifndef __LINUX__ +#include +#endif //!__LINUX__ +#endif //__MSVCDOTNET__ + +#include "ASTRING.H" +#include "NUMVAL.H" +#include "STRUCTST.H" +#include "Parser.h" +#include "rcomp.hpp" +#include "MEM.H" +#include "ERRORHAN.H" +#include "RCBINSTR.H" + +#if defined(__VC32__) +#pragma warning( disable : 4702 ) // unreachable code +#endif + +NumericValue::NumericValue( const String & Source, DataType NumericValueType): + iNumericValueType( NumericValueType), + iData( NULL), + iULongValue( 0), + iSignedValue( 0), + iDoubleValue( 0.0) + { + AllocateSpace(); + ConvertToNumber( Source); + } + +NumericValue::NumericValue( DataType NumericValueType): + iNumericValueType( NumericValueType), + iData( NULL), + iULongValue( 0), + iSignedValue( 0), + iDoubleValue( 0.0) + { + AllocateSpace(); + } + +NumericValue::NumericValue( unsigned long ValueToSet, DataType NumericValueType): + iNumericValueType( NumericValueType), + iData( NULL), + iULongValue( 0), + iSignedValue( 0), + iDoubleValue( 0.0) + { + AllocateSpace(); + StoreValue( ValueToSet); + } + +NumericValue::~NumericValue() + { + delete [] iData; + } + +NumericValue::NumericValue( const NumericValue & Source): + iNumericValueType( Source.iNumericValueType), + iData( NULL), + iULongValue( 0), + iSignedValue( 0), + iDoubleValue( 0.0) + { + AllocateSpace(); + memcpy( iData, Source.iData, iSize); + } + +void NumericValue::AllocateSpace() + { + switch(iNumericValueType) + { + case L_BYTE: + iData = new unsigned char [1]; + iSize = 1; + break; + case L_WORD: + iData = new unsigned char [2]; + iSize = 2; + break; + case L_LONG: + iData = new unsigned char [4]; + iSize = 4; + break; + default: + if ( iNumericValueType != L_DOUBLE) + assert(0); // Cannot use NumericValue for specified data type. + } + + if ( iNumericValueType != L_DOUBLE && iData == NULL) + { + ErrorHandler::OutputErrorLine( "Error: Failed to allocate space for number."); + exit(1); + } + } + +const unsigned char * NumericValue::Data() const + { + return iData; + } + +unsigned long NumericValue::Size() const + { + return iSize; + } + +DataType NumericValue::NumericValueType() const + { + return iNumericValueType; + } + +void NumericValue::ConvertToNumber( const String & Source) + { + if ( iNumericValueType == L_DOUBLE) + ConvertToDouble( Source); + else + ConvertToNatural( Source); + } + +void NumericValue::ConvertToDouble( const String & Source) + { + assert( iNumericValueType == L_DOUBLE); + assert( Source.Length() > 0); + + double d = atof( Source.GetAssertedNonEmptyBuffer()); + if ( d == 0.0 && !( Source == "0.0" || Source == "0") ) + { MOFF; cerr << "atof may have failed for " << Source << endl; MON;} + + iDoubleValue = d; + } + +#if defined(__VC32__) +#pragma warning( disable : 4706 ) // assignment within conditional expression +#endif + +void NumericValue::ConvertToNatural( const String & Source) + { + unsigned long LongValue = 0; + + assert( sizeof( unsigned long) >= 4); // Assume that LongValue can hold at least 2^32 - 1. + + const char * pSourceChar = Source.iRep; + int bLeadingHyphen = 0; + int bHexNumber = 0; + + if ( pSourceChar[0] == '0' && pSourceChar[1] == 'x') + { + bHexNumber = 1; + pSourceChar++; + pSourceChar++; + } + + if ( pSourceChar[0] == '-') + { + bLeadingHyphen = 1; + pSourceChar++; + } + + while ( * pSourceChar != '\0') + { + unsigned char DigitValue; + + if ( bHexNumber) + { + assert( isxdigit( * pSourceChar) ); + if ( isdigit( * pSourceChar) ) + DigitValue = (unsigned char)(* pSourceChar - '0'); + else + DigitValue = (unsigned char)(toupper( * pSourceChar) - 'A' + 10); + if (LongValue >= 0x10000000) + { + String st("Number \""); + st += Source; + st += "\" is too big "; + ErrorHandler::OutputErrorLine(st); //prevents overflow if number is bigger than 2^32 - 1. + } + LongValue = LongValue * 16 + DigitValue; + } + else + { + if ( ! isdigit( * pSourceChar) ) + { + String s( "Error: Cannot convert \""); + s += Source; + s += "\" to a number."; + ErrorHandler::OutputErrorLine( s); + exit(1); + // unreachable code + } + DigitValue = (unsigned char)(* pSourceChar - '0'); + if ((LongValue > 429496729) || ((LongValue == 429496729) && (DigitValue > 5))) + { + String st("Number \""); + st += Source; + st += "\" is too big "; + ErrorHandler::OutputErrorLine(st); //prevents overflow if number is bigger than 2^32 - 1. + } + LongValue = LongValue * 10 + DigitValue; + } + pSourceChar++; + assert( ( pSourceChar - Source.iRep) < 10000); // Safety check! + } + + int inrange=0; + + // Check value is within the allowed range for the type taking into account + // a leading hyphen (minus sign) if there was one. + switch( iNumericValueType) + { + case L_BYTE: // L_BYTE is 8 bits long. + if ( bLeadingHyphen) + { + if ( ! ( inrange = (LongValue <= 128) ) ) // 2 ^ 7 + ErrorHandler::OutputErrorLine( "Error: Number too low for BYTE"); + } + else + if ( ! ( inrange = (LongValue <= 0xFF) ) ) + ErrorHandler::OutputErrorLine( "Error: Number too big for BYTE"); + break; + case L_WORD: // L_WORD is 16-bits long. + if ( bLeadingHyphen) + { + if ( ! ( inrange = (LongValue <= 32768) ) ) // 2^15 + ErrorHandler::OutputErrorLine( "Error: Number too low for WORD"); + } + else + if ( ! ( inrange = (LongValue <= 0xFFFF) ) ) + ErrorHandler::OutputErrorLine( "Error: Number too big for WORD"); + break; + case L_LONG: // L_LONG is 32-bits long + if ( bLeadingHyphen) + { + if ( ! ( inrange = (LongValue <= 0x80000000) ) ) // 2^31 + ErrorHandler::OutputErrorLine( "Error: Number too low for LONG"); + } + else + if ( ! ( inrange = (LongValue <= 0xFFFFFFFF ) ) ) // This test is a bit pointless as long cannot be greater than 0xffffffff + ErrorHandler::OutputErrorLine( "Error: Number too big for LONG"); + break; + default: + assert(0); // Other data types cannot be converted to natural numbers. + } + + if(!inrange) + exit(1); + + StoreValue( LongValue); + + // If there was a hyphen then make the stored number negative (using two's complement). + if ( bLeadingHyphen) + { + LongValue = (LongValue ^ 0xFFFFFFFFu)+1; + + // Output file will be treated as little-endian. + switch ( iNumericValueType) + { + case L_LONG: + iData[3] = (unsigned char)((LongValue & 0xFF000000) >> 24); + iData[2] = (unsigned char)((LongValue & 0xFF0000) >> 16); + case L_WORD: + iData[1] = (unsigned char)((LongValue & 0xFF00) >> 8); + case L_BYTE: + iData[0] = (unsigned char)(LongValue & 0xFF); + } + } + } + +#if defined(__VC32__) +#pragma warning( default : 4706 ) // assignment within conditional expression +#endif + +void NumericValue::StoreValue( unsigned long LongValue) + { + iULongValue = LongValue; + + if ( LongValue <= 0x80000000) + iSignedValue = (unsigned long) LongValue; + + int inrange = 1; + + switch( iNumericValueType) + { + case L_BYTE: + inrange = ( LongValue <= 0xFF); + break; + case L_WORD: + inrange = ( LongValue <= 0xFFFF); + break; + case L_LONG: + inrange = ( LongValue <= 0xFFFFFFFF); + } + + if ( ! inrange) + { + ErrorHandler::OutputErrorLine( "Error: Numeric value out of range for specified type"); + exit(1); + } + + // Output file will be treated as little-endian. + switch ( iNumericValueType) + { + case L_LONG: + iData[3] = (unsigned char)((LongValue & 0xFF000000) >> 24); + iData[2] = (unsigned char)((LongValue & 0xFF0000) >> 16); + case L_WORD: + iData[1] = (unsigned char)((LongValue & 0xFF00) >> 8); + case L_BYTE: + iData[0] = (unsigned char)(LongValue & 0xFF); + } + } + +template class __CompileTimeAssert {public: __CompileTimeAssert(...) {}}; +template<> class __CompileTimeAssert {}; +struct COMPILE_TIME_ERROR {}; +#define COMPILE_TIME_ASSERT(aCondition) { __CompileTimeAssert<(aCondition)> __temp = __CompileTimeAssert<(aCondition)>(COMPILE_TIME_ERROR()); } + +RCBinaryStream & operator<< ( RCBinaryStream & os, NumericValue o) + { + switch( o.iNumericValueType) + { + case L_BYTE: + os.Write( o.iData, 1); + break; + case L_WORD: + os.Write( o.iData, 2); + break; + case L_LONG: + os.Write( o.iData, 4); + break; + case L_DOUBLE: + COMPILE_TIME_ASSERT(sizeof(double) == 8); + os.Write(reinterpret_cast(&o.iDoubleValue), 8); + break; + default: + assert(0); + } + + return os; + } + +void NumericValue::StreamOut(ResourceDataStream& aStream) const + { + switch (iNumericValueType) + { + case L_BYTE: + aStream.StreamIn(iData, 1); + break; + case L_WORD: + aStream.StreamIn(iData, 2); + break; + case L_LONG: + aStream.StreamIn(iData, 4); + break; + case L_DOUBLE: + COMPILE_TIME_ASSERT(sizeof(double) == 8); + aStream.StreamIn(reinterpret_cast(&iDoubleValue), 8); + break; + default: + assert(0); + } + } + +NumericValue & NumericValue::operator= ( unsigned long ValueToSet) + { + StoreValue( ValueToSet); + + return * this; + } + +unsigned long NumericValue::GetULong() const + { + return iULongValue; + } + +long NumericValue::GetLong() const + { + assert( iULongValue <= 2147483647); // Check that we are not holding a number that is really positive only. + return iSignedValue; + } + +bool NumericValue::CheckSigned(unsigned long aValue, DataType aNumericValueType) + { + switch (aNumericValueType) + { + case L_BYTE: + if (aValue > 0x7f) return false; + break; + case L_WORD: + if (aValue > 0x7fff) return false; + break; + case L_LONG: + if (aValue > 0x7fffffff) return false; + break; + default: + assert(0); + } + return true; + } + +String NumericValue::ltoa( long Source) + { + char v[10]; // long can have no more than 10 digits in this implementation. + char * pv = v; + long x; + + if ( Source < 0) + x = - Source; + else + x = Source; + + if ( x == 0) + * pv++ = '0'; + else + { + while( x > 0) + { + assert( pv <= (v+9) ); + + * pv = char(x%10 + '0'); + pv++; + x /= 10; + } + } + + // Now reverse digits so they are in the correct order. Put in terminating null and hyphen + // if necessary. + + char r[12]; + char * pr = r; + + if ( Source < 0) + { + r[0] = '-'; + pr++; + } + + while( pv != v) + { + assert( pr < (r+11) ); + * pr++ = * --pv; + } + + * pr = '\0'; + + return r; + } diff -r 122d2b873fd1 -r 30b30f9da0b7 bintools/rcomp/src/RCBINSTR.CPP --- a/bintools/rcomp/src/RCBINSTR.CPP Fri Jun 25 20:58:33 2010 +0800 +++ b/bintools/rcomp/src/RCBINSTR.CPP Tue Jun 29 14:52:54 2010 +0800 @@ -1,539 +1,539 @@ -/* -* Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of the License "Eclipse Public License v1.0" -* which accompanies this distribution, and is available -* at the URL "http://www.eclipse.org/legal/epl-v10.html". -* -* Initial Contributors: -* Nokia Corporation - initial contribution. -* -* Contributors: -* -* Description: -* -*/ - - -#include -#include -#include "ASTRING.H" -#include -#include - -#include "RCBINSTR.H" -#include "TOKENS.H" -#include "STACK.H" -#include "NUMVAL.H" -#include "DATATYPE.H" - -#if defined(__MSVCDOTNET__) || defined(__TOOLS2__) -using std::ofstream; -using std::ios; -#endif //__MSVCDOTNET__ - -extern long CurrentId; -extern RCTypeArray gTypes; - -RCBinaryStream::RCBinaryStream() - {} - -RCBinaryStream::~RCBinaryStream() - { - if (iOs.is_open()) - { - iOs.flush(); - iOs.close(); - } - } - -void RCBinaryStream::OpenForAppend(const String& FileName) - { - assert( !IsOpen()); - - iOs.open( FileName.GetAssertedNonEmptyBuffer(), ios::in | ios::out | ios::binary | ios::ate); // ios::in to prevent overwriting - } - -int RCBinaryStream::IsOpen() - { - return(iOs.is_open()); - } - -RCBinaryStream & RCBinaryStream::operator<< ( char o) - { - Write((const unsigned char*)&o, 1); - return * this; - } - -RCBinaryStream & RCBinaryStream::operator<< ( char * o) - { - Write((const unsigned char*)o, strlen(o)); - return * this; - } - -int RCBinaryStream::SizeOfCompressedInteger(unsigned int aInteger) - { // static - assert((aInteger&~0x7fff)==0); - return (aInteger&~0x7f)? 2: 1; - } - -void RCBinaryStream::WriteCompressedInteger(unsigned int aInteger) - { - assert((aInteger&~0x7fff)==0); - if (aInteger&~0x7f) - { - *this << char((aInteger>>8)|0x80); - } - *this << char(aInteger&0xff); - } - -void RCBinaryStream::Write( const unsigned char * p, unsigned long count) - { - iOs.write( (const char*)p, count); -#if defined(_DEBUG) - iOs.flush(); -#endif - } - -unsigned long RCBinaryStream::GetPosition() - { - return iOs.tellp(); - } - -void RCBinaryStream::SetPosition(unsigned long aNewPosition) - { - assert(aNewPosition<=GetPosition()); - iOs.seekp(aNewPosition, ios::beg); - } - -// ResourceDataStream - this code makes the apparently valid assumption that the decompressing of compressed Unicode (done by BAFL) will yield exactly the same length of string as what you started with before it was compressed (by RCOMP) - -ResourceDataStream::ResourceDataStream() - :iBuffer(NULL), - iNumberOfBytesAllocated(0), - iNumberOfBytesUsed(0), - iContainsCompressedUnicode(false) - { - } - -ResourceDataStream::~ResourceDataStream() - { - delete [] iBuffer; - } - -void ResourceDataStream::StartOfBlockWithSizePrefix(DataType aDataTypeOfSizePrefix) - { - NumericValue* const sizeOfBlockWhenUncompressed=new NumericValue(aDataTypeOfSizePrefix); - assert(sizeOfBlockWhenUncompressed!=NULL); - iArrayOfMarks.AppendMark(iNumberOfBytesUsed, EMarkType_StartOfBlockWithSizePrefix, (unsigned int)sizeOfBlockWhenUncompressed); - } - -void ResourceDataStream::EndOfBlockWithSizePrefix() - { - iArrayOfMarks.AppendMark(iNumberOfBytesUsed, EMarkType_EndOfBlockWithSizePrefix); - } - -void ResourceDataStream::StartOfCompressedUnicodeRun(int aUncompressedUnicodeSizeInBytes, const unsigned char* aUncompressedUnicodeBuffer) - { - if (!iContainsCompressedUnicode) - { - // the first run *must* be a compressed Unicode run, so if it isn't, insert a zero-length one at the start - bool insertZeroLengthCompressedUnicodeRunAtStart=(iNumberOfBytesUsed>0); - if (!insertZeroLengthCompressedUnicodeRunAtStart) - { - const int numberOfMarks=iArrayOfMarks.Size(); - for (int i=0; i0, and we only execute this code if !insertZeroLengthCompressedUnicodeRunAtStart, i.e. if iNumberOfBytesUsed==0 (well, strictly speaking, if iNumberOfBytesUsed<=0) - if (mark.iMarkType==EMarkType_StartOfBlockWithSizePrefix) - { - insertZeroLengthCompressedUnicodeRunAtStart=true; - break; - } - } - } - if (insertZeroLengthCompressedUnicodeRunAtStart) - { - iArrayOfMarks.InsertMark(0, 0, EMarkType_StartOfCompressedUnicodeRun, (unsigned int)BinaryBuffer::New(0, NULL)); // mark the insertion point for the initial zero-length compressed-Unicode run - iArrayOfMarks.InsertMark(1, 0, EMarkType_EndOfCompressedUnicodeRun); // mark the insertion point for the subsquent run of "other stuff" - } - } - iArrayOfMarks.AppendMark(iNumberOfBytesUsed, EMarkType_StartOfCompressedUnicodeRun, (unsigned int)BinaryBuffer::New(aUncompressedUnicodeSizeInBytes, aUncompressedUnicodeBuffer)); - iContainsCompressedUnicode=true; - } - -void ResourceDataStream::EndOfCompressedUnicodeRun() - { -#if !defined(NDEBUG) - const Mark& markAtStartOfCompressedUnicodeRun=iArrayOfMarks.MarkAt(iArrayOfMarks.Size()-1); - assert(markAtStartOfCompressedUnicodeRun.iMarkType==EMarkType_StartOfCompressedUnicodeRun); - const int numberOfBytesWhenCompressed=iNumberOfBytesUsed-markAtStartOfCompressedUnicodeRun.iBufferPosition; - const BinaryBuffer& runWhenUncompressed=*(const BinaryBuffer*)markAtStartOfCompressedUnicodeRun.iOtherData; - assert(numberOfBytesWhenCompressed(iBuffer), numberOfBytesToFirstMark); - bufferIndex+=numberOfBytesToFirstMark; - } - for (int i=0; iNumericValueType()); - runLength+=sizeOfSizePrefix; - uncompressedSize+=sizeOfSizePrefix; - if (pass==0) - { - sizePrefixStack.Push(uncompressedSize, *(NumericValue*)mark.iOtherData); - } - else if (pass==2) - { - aStream << *sizeOfBlockWhenUncompressed; - delete sizeOfBlockWhenUncompressed; - mark.iOtherData=(unsigned int)(NumericValue*)NULL; - } - } - break; - case EMarkType_EndOfBlockWithSizePrefix: - if (pass==0) - { - SizePrefix* const sizePrefix=sizePrefixStack.Pop(); - assert(sizePrefix!=NULL); - sizePrefix->SizeOfBlockWhenUncompressed()=uncompressedSize-sizePrefix->UncompressedSizeOfResourceUpToStartOfBlock(); - delete sizePrefix; - } - break; - case EMarkType_StartOfCompressedUnicodeRun: - { - assert(runLength>=0); - if (addressToWriteSizeOfCompressedIntegerTo!=NULL) - { - *addressToWriteSizeOfCompressedIntegerTo=runLength; - addressToWriteSizeOfCompressedIntegerTo=NULL; - } - runLength=0; - BinaryBuffer& runWhenUncompressed=*(BinaryBuffer*)mark.iOtherData; - const int numberOfBytesWhenUncompressed=runWhenUncompressed.NumberOfBytes(); - const int numberOfBytesWhenUncompressedIncludingAnyPrecedingPaddingByte=numberOfBytesWhenUncompressed+((uncompressedSize%2!=0)? 1: 0); - assert((numberOfBytesWhenUncompressed>0) || !encounteredCompressedUnicode[pass]); // compressed-Unicode runs are of non-zero size apart from the compulsory initial compressed-Unicode run if the resource does not actually start with compressed Unicode - uncompressedSize+=numberOfBytesWhenUncompressedIncludingAnyPrecedingPaddingByte; - assert(i+10) || !encounteredCompressedUnicode[pass]); // compressed-Unicode runs are of non-zero size apart from the compulsory initial compressed-Unicode run if the resource does not actually start with compressed Unicode - assert((numberOfBytesWhenCompressed0)) - { - numberOfBytesWhenCompressedIncludingRunLengthsEitherSide+=RCBinaryStream::SizeOfCompressedInteger(*lengthOfOtherStuffRun); - } - if (numberOfBytesWhenCompressedIncludingRunLengthsEitherSide>=numberOfBytesWhenUncompressedIncludingAnyPrecedingPaddingByte) // use ">=" rather than just ">" as we want to get rid of any compressed-Unicode runs that don't actually give any benefit, so that if possible we can remove the initial compressed-Unicode run (if it's of zero length and it's the only compressed-Unicode run, in which case it's unnecessary overhead) - { - if (isTheFirstCompressedUnicodeRun && isTheLastCompressedUnicodeRun) // if this is the only compressed-Unicode run... - { - iContainsCompressedUnicode=false; - } - ConvertCompressedRunToUncompressed(i-1); - goto startOfFirstPass; // go back to the start of the first pass again as we need to calculate all the fiddly stuff again, e.g. whether two-byte alignment points need padding bytes, etc. - } - } - } - else - { - assert(pass==2); - runWhenUncompressed.Destroy(); - mark.iOtherData=(unsigned int)(BinaryBuffer*)NULL; - aStream.WriteCompressedInteger(numberOfBytesWhenCompressed); - aStream.Write(reinterpret_cast(iBuffer+bufferIndex), numberOfBytesWhenCompressed); - bufferIndex+=numberOfBytesWhenCompressed; - const unsigned int* const lengthOfOtherStuffRun=&nextMark.iOtherData; - if ((lengthOfLastRun!=lengthOfOtherStuffRun) || (*lengthOfOtherStuffRun>0)) - { - aStream.WriteCompressedInteger(*lengthOfOtherStuffRun); - } - } - encounteredCompressedUnicode[pass]=true; - } - break; - case EMarkType_TwoByteAlignmentPoint: - { - const bool needPaddingByte=(uncompressedSize%2!=0); - if (needPaddingByte) - { - ++runLength; - ++uncompressedSize; - if (pass==2) - { - aStream << (unsigned char)(0xab); - } - } - if (pass==0) - { - mark.iOtherData=needPaddingByte; - } - else - { - assert((mark.iOtherData!=0)==needPaddingByte); - } - } - break; - case EMarkType_EnquireStreamPositionWhenKnown: - if (pass==2) - { - unsigned long& streamPosition=*(unsigned long*)mark.iOtherData; - streamPosition=aStream.GetPosition(); - } - break; - default: - assert(0); - break; - } - const int numberOfBytesToNextMark=NumberOfBytesToNextMark(i); - if (pass==2) - { - aStream.Write(reinterpret_cast(iBuffer+bufferIndex), numberOfBytesToNextMark); - } - runLength+=numberOfBytesToNextMark; - uncompressedSize+=numberOfBytesToNextMark; - bufferIndex+=numberOfBytesToNextMark; - } - if (pass>0) - { - assert(aSizeWhenUncompressed==uncompressedSize); - } - else - { - aSizeWhenUncompressed=uncompressedSize; - lengthOfLastRun=addressToWriteSizeOfCompressedIntegerTo; - } - assert(runLength>=0); - if (addressToWriteSizeOfCompressedIntegerTo!=NULL) - { - *addressToWriteSizeOfCompressedIntegerTo=runLength; - addressToWriteSizeOfCompressedIntegerTo=NULL; - } - runLength=0; - } - } - - assert(encounteredCompressedUnicode[0]==iContainsCompressedUnicode); - assert(encounteredCompressedUnicode[1]==iContainsCompressedUnicode); - assert(encounteredCompressedUnicode[2]==iContainsCompressedUnicode); - return encounteredCompressedUnicode[0]; - } - -void ResourceDataStream::Dump(const char* aDumpFile) const - { - ofstream fileStream; - fileStream.open(aDumpFile, ios::out | ios::binary | ios::trunc); - fileStream.write((const char*)iBuffer, iNumberOfBytesUsed); - fileStream.flush(); - fileStream.close(); - } - -void ResourceDataStream::EnsureEnoughSpareBytes(int aNumberOfBytes) - { - const int numberOfBytesSpare=iNumberOfBytesAllocated-iNumberOfBytesUsed; - assert(numberOfBytesSpare>=0); - if (aNumberOfBytes>numberOfBytesSpare) - { - const int newNumberOfBytesAllocated=iNumberOfBytesAllocated+aNumberOfBytes+16; // 16 is just some extra bytes to stop the heap being thrashed too much - unsigned char* const newBuffer = new unsigned char[newNumberOfBytesAllocated]; - if (iNumberOfBytesUsed>0) - { - memcpy(newBuffer, iBuffer, iNumberOfBytesUsed); - } - delete [] iBuffer; - iNumberOfBytesAllocated=newNumberOfBytesAllocated; - iBuffer=newBuffer; - } - } - -int ResourceDataStream::NumberOfBytesToNextMark(int aMarkIndex) const - { - assert(aMarkIndex>=-1); - assert(aMarkIndex=0) - { - numberOfBytesToNextMark-=iArrayOfMarks.MarkAt(aMarkIndex).iBufferPosition; - } - return numberOfBytesToNextMark; - } - -void ResourceDataStream::ConvertCompressedRunToUncompressed(int aMarkIndexOfStartOfCompressedUnicodeRun) - { - // remove the EMarkType_StartOfCompressedUnicodeRun/EMarkType_EndOfCompressedUnicodeRun mark-pair - Mark* markForStartOfCompressedUnicodeRun=&iArrayOfMarks.MarkAt(aMarkIndexOfStartOfCompressedUnicodeRun); - assert(markForStartOfCompressedUnicodeRun->iMarkType==EMarkType_StartOfCompressedUnicodeRun); - BinaryBuffer& runWhenUncompressed=*(BinaryBuffer*)markForStartOfCompressedUnicodeRun->iOtherData; - markForStartOfCompressedUnicodeRun->iOtherData=(unsigned int)(BinaryBuffer*)NULL; - Mark* markForEndOfCompressedUnicodeRun=&iArrayOfMarks.MarkAt(aMarkIndexOfStartOfCompressedUnicodeRun+1); - assert(markForEndOfCompressedUnicodeRun->iMarkType==EMarkType_EndOfCompressedUnicodeRun); - const int bufferPositionOfStartOfCompressedUnicodeRun=markForStartOfCompressedUnicodeRun->iBufferPosition; - const int bufferPositionOfEndOfCompressedUnicodeRun=markForEndOfCompressedUnicodeRun->iBufferPosition; - const int numberOfBytesWhenCompressed=bufferPositionOfEndOfCompressedUnicodeRun-bufferPositionOfStartOfCompressedUnicodeRun; - iArrayOfMarks.RemoveMark(aMarkIndexOfStartOfCompressedUnicodeRun); // remove the EMarkType_StartOfCompressedUnicodeRun mark - iArrayOfMarks.RemoveMark(aMarkIndexOfStartOfCompressedUnicodeRun); // remove the EMarkType_EndOfCompressedUnicodeRun mark - markForStartOfCompressedUnicodeRun=NULL; // just in case we're tempted to use it again now that it's been removed - markForEndOfCompressedUnicodeRun=NULL; // just in case we're tempted to use it again now that it's been removed - const int numberOfBytesWhenUncompressed=runWhenUncompressed.NumberOfBytes(); - const int numberOfExtraBytes=numberOfBytesWhenUncompressed-numberOfBytesWhenCompressed; - - // insert a EMarkType_TwoByteAlignmentPoint mark if necessary - int startOfMarksToUpdate=aMarkIndexOfStartOfCompressedUnicodeRun; - if (numberOfBytesWhenCompressed==0) - { - assert(numberOfExtraBytes==0); - assert(numberOfBytesWhenUncompressed==0); - assert(aMarkIndexOfStartOfCompressedUnicodeRun==0); - } - else - { - assert(numberOfBytesWhenCompressed>0); - iArrayOfMarks.InsertMark(aMarkIndexOfStartOfCompressedUnicodeRun, bufferPositionOfStartOfCompressedUnicodeRun, EMarkType_TwoByteAlignmentPoint); - ++startOfMarksToUpdate; - assert(startOfMarksToUpdate==aMarkIndexOfStartOfCompressedUnicodeRun+1); - } - - // replace the compressed-Unicode bytes in the buffer with the uncompressed equivalent - if (numberOfExtraBytes==0) - { - assert(numberOfBytesWhenCompressed==0); - assert(numberOfBytesWhenUncompressed==0); - assert(aMarkIndexOfStartOfCompressedUnicodeRun==0); - } - else - { - assert(numberOfExtraBytes>0); - - // make room in the buffer to insert the uncompressed Unicode (replacing the compressed-Unicode run) - const int numberOfBytesToMove=iNumberOfBytesUsed-bufferPositionOfEndOfCompressedUnicodeRun; // must be done before MakePlaceHolder is called as MakePlaceHolder will increment iNumberOfBytesUsed by numberOfExtraBytes - MakePlaceHolder(numberOfExtraBytes); - unsigned char* basePointer=iBuffer+bufferPositionOfEndOfCompressedUnicodeRun; - memmove(basePointer+numberOfExtraBytes, basePointer, numberOfBytesToMove); // memmove copes with overlapping source and target areas - - // adjust all the subsequent mark's iBufferPositions - for (int i=iArrayOfMarks.Size()-1; i>=startOfMarksToUpdate; --i) - { - iArrayOfMarks.MarkAt(i).iBufferPosition+=numberOfExtraBytes; - } - } - - // copy in the uncompressed Unicode and destroying the old copy - memcpy(iBuffer+bufferPositionOfStartOfCompressedUnicodeRun, runWhenUncompressed.Buffer(), numberOfBytesWhenUncompressed); - runWhenUncompressed.Destroy(); - } - -ResourceDataStream::BinaryBuffer* ResourceDataStream::BinaryBuffer::New(int aNumberOfBytes, const unsigned char* aBuffer) - { // static - BinaryBuffer* const binaryBuffer=(BinaryBuffer*)malloc((size_t)&((BinaryBuffer*)0)->iBuffer[aNumberOfBytes]); - assert(binaryBuffer!=NULL); - binaryBuffer->iNumberOfBytes=aNumberOfBytes; - assert(aNumberOfBytes>=0); - if (aNumberOfBytes>0) - { - assert(aBuffer!=NULL); - memcpy(binaryBuffer->iBuffer, aBuffer, aNumberOfBytes); - } - return binaryBuffer; - } - -void ResourceDataStream::BinaryBuffer::Destroy() - { - free(this); - } - +/* +* Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#include +#include +#include "ASTRING.H" +#include +#include + +#include "RCBINSTR.H" +#include "TOKENS.H" +#include "STACK.H" +#include "NUMVAL.H" +#include "DATATYPE.H" + + +using namespace std ; + +extern long CurrentId; +extern RCTypeArray gTypes; + +RCBinaryStream::RCBinaryStream() + {} + +RCBinaryStream::~RCBinaryStream() + { + if (iOs.is_open()) + { + iOs.flush(); + iOs.close(); + } + } + +void RCBinaryStream::OpenForAppend(const String& FileName) + { + assert( !IsOpen()); + + iOs.open( FileName.GetAssertedNonEmptyBuffer(), ios::in | ios::out | ios::binary | ios::ate); // ios::in to prevent overwriting + } + +int RCBinaryStream::IsOpen() + { + return(iOs.is_open()); + } + +RCBinaryStream & RCBinaryStream::operator<< ( char o) + { + Write((const unsigned char*)&o, 1); + return * this; + } + +RCBinaryStream & RCBinaryStream::operator<< ( char * o) + { + Write((const unsigned char*)o, strlen(o)); + return * this; + } + +int RCBinaryStream::SizeOfCompressedInteger(unsigned int aInteger) + { // static + assert((aInteger&~0x7fff)==0); + return (aInteger&~0x7f)? 2: 1; + } + +void RCBinaryStream::WriteCompressedInteger(unsigned int aInteger) + { + assert((aInteger&~0x7fff)==0); + if (aInteger&~0x7f) + { + *this << char((aInteger>>8)|0x80); + } + *this << char(aInteger&0xff); + } + +void RCBinaryStream::Write( const unsigned char * p, unsigned long count) + { + iOs.write( (const char*)p, count); +#if defined(_DEBUG) + iOs.flush(); +#endif + } + +unsigned long RCBinaryStream::GetPosition() + { + return iOs.tellp(); + } + +void RCBinaryStream::SetPosition(unsigned long aNewPosition) + { + assert(aNewPosition<=GetPosition()); + iOs.seekp(aNewPosition, ios::beg); + } + +// ResourceDataStream - this code makes the apparently valid assumption that the decompressing of compressed Unicode (done by BAFL) will yield exactly the same length of string as what you started with before it was compressed (by RCOMP) + +ResourceDataStream::ResourceDataStream() + :iBuffer(NULL), + iNumberOfBytesAllocated(0), + iNumberOfBytesUsed(0), + iContainsCompressedUnicode(false) + { + } + +ResourceDataStream::~ResourceDataStream() + { + delete [] iBuffer; + } + +void ResourceDataStream::StartOfBlockWithSizePrefix(DataType aDataTypeOfSizePrefix) + { + NumericValue* const sizeOfBlockWhenUncompressed=new NumericValue(aDataTypeOfSizePrefix); + assert(sizeOfBlockWhenUncompressed!=NULL); + iArrayOfMarks.AppendMark(iNumberOfBytesUsed, EMarkType_StartOfBlockWithSizePrefix, (unsigned int)sizeOfBlockWhenUncompressed); + } + +void ResourceDataStream::EndOfBlockWithSizePrefix() + { + iArrayOfMarks.AppendMark(iNumberOfBytesUsed, EMarkType_EndOfBlockWithSizePrefix); + } + +void ResourceDataStream::StartOfCompressedUnicodeRun(int aUncompressedUnicodeSizeInBytes, const unsigned char* aUncompressedUnicodeBuffer) + { + if (!iContainsCompressedUnicode) + { + // the first run *must* be a compressed Unicode run, so if it isn't, insert a zero-length one at the start + bool insertZeroLengthCompressedUnicodeRunAtStart=(iNumberOfBytesUsed>0); + if (!insertZeroLengthCompressedUnicodeRunAtStart) + { + const int numberOfMarks=iArrayOfMarks.Size(); + for (int i=0; i0, and we only execute this code if !insertZeroLengthCompressedUnicodeRunAtStart, i.e. if iNumberOfBytesUsed==0 (well, strictly speaking, if iNumberOfBytesUsed<=0) + if (mark.iMarkType==EMarkType_StartOfBlockWithSizePrefix) + { + insertZeroLengthCompressedUnicodeRunAtStart=true; + break; + } + } + } + if (insertZeroLengthCompressedUnicodeRunAtStart) + { + iArrayOfMarks.InsertMark(0, 0, EMarkType_StartOfCompressedUnicodeRun, (unsigned int)BinaryBuffer::New(0, NULL)); // mark the insertion point for the initial zero-length compressed-Unicode run + iArrayOfMarks.InsertMark(1, 0, EMarkType_EndOfCompressedUnicodeRun); // mark the insertion point for the subsquent run of "other stuff" + } + } + iArrayOfMarks.AppendMark(iNumberOfBytesUsed, EMarkType_StartOfCompressedUnicodeRun, (unsigned int)BinaryBuffer::New(aUncompressedUnicodeSizeInBytes, aUncompressedUnicodeBuffer)); + iContainsCompressedUnicode=true; + } + +void ResourceDataStream::EndOfCompressedUnicodeRun() + { +#if !defined(NDEBUG) + const Mark& markAtStartOfCompressedUnicodeRun=iArrayOfMarks.MarkAt(iArrayOfMarks.Size()-1); + assert(markAtStartOfCompressedUnicodeRun.iMarkType==EMarkType_StartOfCompressedUnicodeRun); + const int numberOfBytesWhenCompressed=iNumberOfBytesUsed-markAtStartOfCompressedUnicodeRun.iBufferPosition; + const BinaryBuffer& runWhenUncompressed=*(const BinaryBuffer*)markAtStartOfCompressedUnicodeRun.iOtherData; + assert(numberOfBytesWhenCompressed(iBuffer), numberOfBytesToFirstMark); + bufferIndex+=numberOfBytesToFirstMark; + } + for (int i=0; iNumericValueType()); + runLength+=sizeOfSizePrefix; + uncompressedSize+=sizeOfSizePrefix; + if (pass==0) + { + sizePrefixStack.Push(uncompressedSize, *(NumericValue*)mark.iOtherData); + } + else if (pass==2) + { + aStream << *sizeOfBlockWhenUncompressed; + delete sizeOfBlockWhenUncompressed; + mark.iOtherData=(unsigned int)(NumericValue*)NULL; + } + } + break; + case EMarkType_EndOfBlockWithSizePrefix: + if (pass==0) + { + SizePrefix* const sizePrefix=sizePrefixStack.Pop(); + assert(sizePrefix!=NULL); + sizePrefix->SizeOfBlockWhenUncompressed()=uncompressedSize-sizePrefix->UncompressedSizeOfResourceUpToStartOfBlock(); + delete sizePrefix; + } + break; + case EMarkType_StartOfCompressedUnicodeRun: + { + assert(runLength>=0); + if (addressToWriteSizeOfCompressedIntegerTo!=NULL) + { + *addressToWriteSizeOfCompressedIntegerTo=runLength; + addressToWriteSizeOfCompressedIntegerTo=NULL; + } + runLength=0; + BinaryBuffer& runWhenUncompressed=*(BinaryBuffer*)mark.iOtherData; + const int numberOfBytesWhenUncompressed=runWhenUncompressed.NumberOfBytes(); + const int numberOfBytesWhenUncompressedIncludingAnyPrecedingPaddingByte=numberOfBytesWhenUncompressed+((uncompressedSize%2!=0)? 1: 0); + assert((numberOfBytesWhenUncompressed>0) || !encounteredCompressedUnicode[pass]); // compressed-Unicode runs are of non-zero size apart from the compulsory initial compressed-Unicode run if the resource does not actually start with compressed Unicode + uncompressedSize+=numberOfBytesWhenUncompressedIncludingAnyPrecedingPaddingByte; + assert(i+10) || !encounteredCompressedUnicode[pass]); // compressed-Unicode runs are of non-zero size apart from the compulsory initial compressed-Unicode run if the resource does not actually start with compressed Unicode + assert((numberOfBytesWhenCompressed0)) + { + numberOfBytesWhenCompressedIncludingRunLengthsEitherSide+=RCBinaryStream::SizeOfCompressedInteger(*lengthOfOtherStuffRun); + } + if (numberOfBytesWhenCompressedIncludingRunLengthsEitherSide>=numberOfBytesWhenUncompressedIncludingAnyPrecedingPaddingByte) // use ">=" rather than just ">" as we want to get rid of any compressed-Unicode runs that don't actually give any benefit, so that if possible we can remove the initial compressed-Unicode run (if it's of zero length and it's the only compressed-Unicode run, in which case it's unnecessary overhead) + { + if (isTheFirstCompressedUnicodeRun && isTheLastCompressedUnicodeRun) // if this is the only compressed-Unicode run... + { + iContainsCompressedUnicode=false; + } + ConvertCompressedRunToUncompressed(i-1); + goto startOfFirstPass; // go back to the start of the first pass again as we need to calculate all the fiddly stuff again, e.g. whether two-byte alignment points need padding bytes, etc. + } + } + } + else + { + assert(pass==2); + runWhenUncompressed.Destroy(); + mark.iOtherData=(unsigned int)(BinaryBuffer*)NULL; + aStream.WriteCompressedInteger(numberOfBytesWhenCompressed); + aStream.Write(reinterpret_cast(iBuffer+bufferIndex), numberOfBytesWhenCompressed); + bufferIndex+=numberOfBytesWhenCompressed; + const unsigned int* const lengthOfOtherStuffRun=&nextMark.iOtherData; + if ((lengthOfLastRun!=lengthOfOtherStuffRun) || (*lengthOfOtherStuffRun>0)) + { + aStream.WriteCompressedInteger(*lengthOfOtherStuffRun); + } + } + encounteredCompressedUnicode[pass]=true; + } + break; + case EMarkType_TwoByteAlignmentPoint: + { + const bool needPaddingByte=(uncompressedSize%2!=0); + if (needPaddingByte) + { + ++runLength; + ++uncompressedSize; + if (pass==2) + { + aStream << (unsigned char)(0xab); + } + } + if (pass==0) + { + mark.iOtherData=needPaddingByte; + } + else + { + assert((mark.iOtherData!=0)==needPaddingByte); + } + } + break; + case EMarkType_EnquireStreamPositionWhenKnown: + if (pass==2) + { + unsigned long& streamPosition=*(unsigned long*)mark.iOtherData; + streamPosition=aStream.GetPosition(); + } + break; + default: + assert(0); + break; + } + const int numberOfBytesToNextMark=NumberOfBytesToNextMark(i); + if (pass==2) + { + aStream.Write(reinterpret_cast(iBuffer+bufferIndex), numberOfBytesToNextMark); + } + runLength+=numberOfBytesToNextMark; + uncompressedSize+=numberOfBytesToNextMark; + bufferIndex+=numberOfBytesToNextMark; + } + if (pass>0) + { + assert(aSizeWhenUncompressed==uncompressedSize); + } + else + { + aSizeWhenUncompressed=uncompressedSize; + lengthOfLastRun=addressToWriteSizeOfCompressedIntegerTo; + } + assert(runLength>=0); + if (addressToWriteSizeOfCompressedIntegerTo!=NULL) + { + *addressToWriteSizeOfCompressedIntegerTo=runLength; + addressToWriteSizeOfCompressedIntegerTo=NULL; + } + runLength=0; + } + } + + assert(encounteredCompressedUnicode[0]==iContainsCompressedUnicode); + assert(encounteredCompressedUnicode[1]==iContainsCompressedUnicode); + assert(encounteredCompressedUnicode[2]==iContainsCompressedUnicode); + return encounteredCompressedUnicode[0]; + } + +void ResourceDataStream::Dump(const char* aDumpFile) const + { + ofstream fileStream; + fileStream.open(aDumpFile, ios::out | ios::binary | ios::trunc); + fileStream.write((const char*)iBuffer, iNumberOfBytesUsed); + fileStream.flush(); + fileStream.close(); + } + +void ResourceDataStream::EnsureEnoughSpareBytes(int aNumberOfBytes) + { + const int numberOfBytesSpare=iNumberOfBytesAllocated-iNumberOfBytesUsed; + assert(numberOfBytesSpare>=0); + if (aNumberOfBytes>numberOfBytesSpare) + { + const int newNumberOfBytesAllocated=iNumberOfBytesAllocated+aNumberOfBytes+16; // 16 is just some extra bytes to stop the heap being thrashed too much + unsigned char* const newBuffer = new unsigned char[newNumberOfBytesAllocated]; + if (iNumberOfBytesUsed>0) + { + memcpy(newBuffer, iBuffer, iNumberOfBytesUsed); + } + delete [] iBuffer; + iNumberOfBytesAllocated=newNumberOfBytesAllocated; + iBuffer=newBuffer; + } + } + +int ResourceDataStream::NumberOfBytesToNextMark(int aMarkIndex) const + { + assert(aMarkIndex>=-1); + assert(aMarkIndex=0) + { + numberOfBytesToNextMark-=iArrayOfMarks.MarkAt(aMarkIndex).iBufferPosition; + } + return numberOfBytesToNextMark; + } + +void ResourceDataStream::ConvertCompressedRunToUncompressed(int aMarkIndexOfStartOfCompressedUnicodeRun) + { + // remove the EMarkType_StartOfCompressedUnicodeRun/EMarkType_EndOfCompressedUnicodeRun mark-pair + Mark* markForStartOfCompressedUnicodeRun=&iArrayOfMarks.MarkAt(aMarkIndexOfStartOfCompressedUnicodeRun); + assert(markForStartOfCompressedUnicodeRun->iMarkType==EMarkType_StartOfCompressedUnicodeRun); + BinaryBuffer& runWhenUncompressed=*(BinaryBuffer*)markForStartOfCompressedUnicodeRun->iOtherData; + markForStartOfCompressedUnicodeRun->iOtherData=(unsigned int)(BinaryBuffer*)NULL; + Mark* markForEndOfCompressedUnicodeRun=&iArrayOfMarks.MarkAt(aMarkIndexOfStartOfCompressedUnicodeRun+1); + assert(markForEndOfCompressedUnicodeRun->iMarkType==EMarkType_EndOfCompressedUnicodeRun); + const int bufferPositionOfStartOfCompressedUnicodeRun=markForStartOfCompressedUnicodeRun->iBufferPosition; + const int bufferPositionOfEndOfCompressedUnicodeRun=markForEndOfCompressedUnicodeRun->iBufferPosition; + const int numberOfBytesWhenCompressed=bufferPositionOfEndOfCompressedUnicodeRun-bufferPositionOfStartOfCompressedUnicodeRun; + iArrayOfMarks.RemoveMark(aMarkIndexOfStartOfCompressedUnicodeRun); // remove the EMarkType_StartOfCompressedUnicodeRun mark + iArrayOfMarks.RemoveMark(aMarkIndexOfStartOfCompressedUnicodeRun); // remove the EMarkType_EndOfCompressedUnicodeRun mark + markForStartOfCompressedUnicodeRun=NULL; // just in case we're tempted to use it again now that it's been removed + markForEndOfCompressedUnicodeRun=NULL; // just in case we're tempted to use it again now that it's been removed + const int numberOfBytesWhenUncompressed=runWhenUncompressed.NumberOfBytes(); + const int numberOfExtraBytes=numberOfBytesWhenUncompressed-numberOfBytesWhenCompressed; + + // insert a EMarkType_TwoByteAlignmentPoint mark if necessary + int startOfMarksToUpdate=aMarkIndexOfStartOfCompressedUnicodeRun; + if (numberOfBytesWhenCompressed==0) + { + assert(numberOfExtraBytes==0); + assert(numberOfBytesWhenUncompressed==0); + assert(aMarkIndexOfStartOfCompressedUnicodeRun==0); + } + else + { + assert(numberOfBytesWhenCompressed>0); + iArrayOfMarks.InsertMark(aMarkIndexOfStartOfCompressedUnicodeRun, bufferPositionOfStartOfCompressedUnicodeRun, EMarkType_TwoByteAlignmentPoint); + ++startOfMarksToUpdate; + assert(startOfMarksToUpdate==aMarkIndexOfStartOfCompressedUnicodeRun+1); + } + + // replace the compressed-Unicode bytes in the buffer with the uncompressed equivalent + if (numberOfExtraBytes==0) + { + assert(numberOfBytesWhenCompressed==0); + assert(numberOfBytesWhenUncompressed==0); + assert(aMarkIndexOfStartOfCompressedUnicodeRun==0); + } + else + { + assert(numberOfExtraBytes>0); + + // make room in the buffer to insert the uncompressed Unicode (replacing the compressed-Unicode run) + const int numberOfBytesToMove=iNumberOfBytesUsed-bufferPositionOfEndOfCompressedUnicodeRun; // must be done before MakePlaceHolder is called as MakePlaceHolder will increment iNumberOfBytesUsed by numberOfExtraBytes + MakePlaceHolder(numberOfExtraBytes); + unsigned char* basePointer=iBuffer+bufferPositionOfEndOfCompressedUnicodeRun; + memmove(basePointer+numberOfExtraBytes, basePointer, numberOfBytesToMove); // memmove copes with overlapping source and target areas + + // adjust all the subsequent mark's iBufferPositions + for (int i=iArrayOfMarks.Size()-1; i>=startOfMarksToUpdate; --i) + { + iArrayOfMarks.MarkAt(i).iBufferPosition+=numberOfExtraBytes; + } + } + + // copy in the uncompressed Unicode and destroying the old copy + memcpy(iBuffer+bufferPositionOfStartOfCompressedUnicodeRun, runWhenUncompressed.Buffer(), numberOfBytesWhenUncompressed); + runWhenUncompressed.Destroy(); + } + +ResourceDataStream::BinaryBuffer* ResourceDataStream::BinaryBuffer::New(int aNumberOfBytes, const unsigned char* aBuffer) + { // static + BinaryBuffer *dummy = reinterpret_cast(0) ; + size_t offset = reinterpret_cast(&(dummy->iBuffer[aNumberOfBytes])) ; + BinaryBuffer* const binaryBuffer=(BinaryBuffer*)malloc(offset); + assert(binaryBuffer!=NULL); + binaryBuffer->iNumberOfBytes=aNumberOfBytes; + assert(aNumberOfBytes>=0); + if (aNumberOfBytes>0) + { + assert(aBuffer!=NULL); + memcpy(binaryBuffer->iBuffer, aBuffer, aNumberOfBytes); + } + return binaryBuffer; + } + +void ResourceDataStream::BinaryBuffer::Destroy() + { + free(this); + } + diff -r 122d2b873fd1 -r 30b30f9da0b7 bintools/rcomp/src/RCOMP.LEX --- a/bintools/rcomp/src/RCOMP.LEX Fri Jun 25 20:58:33 2010 +0800 +++ b/bintools/rcomp/src/RCOMP.LEX Tue Jun 29 14:52:54 2010 +0800 @@ -1,317 +1,302 @@ -%option yylineno -%{ -// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). -// All rights reserved. -// This component and the accompanying materials are made available -// under the terms of the License "Eclipse Public License v1.0" -// which accompanies this distribution, and is available -// at the URL "http://www.eclipse.org/legal/epl-v10.html". -// -// Initial Contributors: -// Nokia Corporation - initial contribution. -// -// Contributors: -// -// Description: -// RCOMPL.INL -// Generated from RCOMP.L - - -#include -#include -#include "main.h" -#include "structst.h" -#include "parser.h" -#include "localise.h" - -#define YY_SKIP_YYWRAP 1 -#define YY_NEVER_INTERACTIVE 1 -int yywrap(); -void yyerror(const char* string, ...); - -// Redefine YY_INPUT so we can parse binary data. -#undef YY_INPUT -#define YY_INPUT(buf, result, max_size) (result = new_yy_input(buf, max_size)) - -int new_yy_input(char *buf, int max_size) -{ - int result; - result = fread(buf, 1, max_size, yyin); - if (result == 0) - return YY_NULL; - - // check for utf8 (BOM) header in buf - for (int i = 0; i < result-3; i++) - { - if (buf[i] == 0xffffffef && buf[i+1] == 0xffffffbb && buf[i+2] == 0xffffffbf) - { - buf[i] = ' '; - buf[i+1] = ' '; - buf[i+2] = ' '; - } - } - return result; -} - -#include "rcomp.hpp" -#include "fileline.h" - -#define VALUE_LEN (1024*8) // must match sizeof(YYSTYPE.Value) -char buf[VALUE_LEN]; -char * pCh; -#define CHECK_APPEND(x) \ - if (pCh-buf==VALUE_LEN-1) { yyerror("string too long - %c ignored", (x)); } else {*pCh++ = (x); } - -int isCharLiteral; - -extern String InputBaseName; -extern FileLineManager* pFileLineHandler; -extern int* pCurrentLineNumber; -char RealLineNumber[200]; -// -// Disable MSVC warnings -// -#ifdef __VC32__ -#if 0 -..\src\RCOMP.L(95) : warning C4127: conditional expression is constant -..\src\RCOMP.L(114) : warning C4244: 'initializing' : conversion from 'const int' to 'YY_CHAR', possible loss of data -..\src\RCOMP.L(119) : warning C4244: '=' : conversion from 'const int' to 'YY_CHAR', possible loss of data -..\src\RCOMP.L(130) : warning C4102: 'find_rule' : unreferenced label -..\src\RCOMP.L(513) : warning C4244: 'initializing' : conversion from 'int' to 'YY_CHAR', possible loss of data -..\src\RCOMP.L(518) : warning C4244: '=' : conversion from 'const int' to 'YY_CHAR', possible loss of data -..\src\RCOMP.L(548) : warning C4244: '=' : conversion from 'const int' to 'YY_CHAR', possible loss of data -..\src\RCOMP.L(63) : warning C4505: 'yyunput' : unreferenced local function has been removed -\epoc32\BUILD\generatedcpp\rcomp\rcompl.cpp(243) : warning C4505: 'yy_flex_realloc' : unreferenced local function has been removed -#endif - -#pragma warning( disable : 4100 ) -#pragma warning( disable : 4102 ) -#pragma warning( disable : 4127 ) -#pragma warning( disable : 4244 ) -#pragma warning( disable : 4245 ) -#pragma warning( disable : 4505 ) -#endif //__VC32__ - -#include "errorhan.h" - -#define REGISTER_LINE ErrorHandler::Register(pFileLineHandler->GetCurrentFile(), pFileLineHandler->GetErrorLine(* pCurrentLineNumber)) - - -%} - -Digit [0-9] -Lower [a-z] -Upper [A-Z] -Letter {Lower}|{Upper} -Alphanumeric {Letter}|{Digit} -LetterOrUnderscore {Letter}|_ -AlphanumUscore {Alphanumeric}|_ -HexChar [A-Fa-f0-9] -ExpChar [eE] -FileNameChar [^"] - -%s string_rules - /* Rule set for string literals. */ - /* n.b. Exclusive rule sets i.e. %x are available in MKS only */ - /* so they are not used here; hence all the 's. */ - -%s file_line_rules - /* Rule set for file_line_directive.*/ - -%s cpp_comment - /* C++ comment to end of line */ - -%s c_comment - /* C comment */ - -%s comment_tag - /* Doxygen-style comment tag */ - -%% - - - /* Translations section */ - /* ==================== */ - - /*******************************************/ - /* Main keywords */ - /*******************************************/ -STRUCT return L_STRUCT; -RESOURCE return L_RESOURCE; -NAME return L_NAME; -CHARACTER_SET return L_CHARACTER_SET; -OFFSET return L_OFFSET; -SYSTEM return L_SYSTEM; -GLOBAL return L_GLOBAL; -LOCAL return L_LOCAL; -ENUM return L_ENUM; -enum return L_ENUM; -UID2 return L_UID_TWO; -UID3 return L_UID_THREE; -rls_string return L_RLS_STRING; -rls_string8 return L_RLS_STRING8; -rls_double return L_RLS_DOUBLE; -rls_byte return L_RLS_BYTE; -rls_word return L_RLS_WORD; -rls_long return L_RLS_LONG; -multi return L_MULTI; - - /*******************************************/ - /* Types */ - /*******************************************/ -BUF return L_BUF; -BUF8 return L_BUF8; -BUF16 return L_BUF16; -WORD return L_WORD; -BYTE return L_BYTE; -LONG return L_LONG; -DOUBLE return L_DOUBLE; -TEXT return L_TEXT; -LTEXT return L_LTEXT; -TEXT8 return L_TEXT8; -LTEXT8 return L_LTEXT8; -TEXT16 return L_TEXT16; -LTEXT16 return L_LTEXT16; -LINK return L_LINK; -LLINK return L_LLINK; -SRLINK return L_SRLINK; - - - /*******************************************/ - /* Others */ - /*******************************************/ -LEN return L_LEN; - - - /*******************************************/ - /* String & character literals */ - /*******************************************/ -\" { BEGIN(string_rules); pCh = buf; isCharLiteral=0; } -' { BEGIN(string_rules); pCh = buf; isCharLiteral=1; } - - /* Escaped single- and double-quotes.*/ -\\\" { CHECK_APPEND('"'); } -\\' { CHECK_APPEND('\''); }; - - /* Convert escaped character into corresponding actual character e.g. \t to tab. */ -\\[rbfntv] { CHECK_APPEND( * ( strchr("\rr\bb\ff\nn\tt\vv\aa", yytext[1])-1));} - - /* Escaped backslash */ -\\\\ { CHECK_APPEND('\\'); } - -\\\n /* Escaped newline ignored*/ ; - - /* End of line before terminating double-quotes.*/ -(\r)?\n { yyerror( isCharLiteral?"Unterminated character literal":"Unterminated string"); BEGIN 0; } - - /* End of string reached.*/ -\" { - if (!isCharLiteral) - { - *pCh = '\0'; BEGIN(0); strcpy( yylval.Value, buf); - return L_STRING_LITERAL; - } - CHECK_APPEND(*yytext); - } - -' { - if (isCharLiteral) - { - *pCh = '\0'; BEGIN(0); strcpy( yylval.Value, buf); return L_CHAR_LITERAL; - } - CHECK_APPEND(*yytext); - } - - /* Anything other than \n is stored.*/ -. { CHECK_APPEND(*yytext); } - - - /*******************************************/ - /* Labels */ - /*******************************************/ -{LetterOrUnderscore}{AlphanumUscore}* { - BEGIN(0); - strcpy( yylval.Value, yytext); - return L_LABEL; - } - - /*******************************************/ - /* Numbers */ - /*******************************************/ -{Digit}+ { strcpy( yylval.Value, yytext); return L_NUM_NATURAL; } -0x{HexChar}+ { strcpy( yylval.Value, yytext); return L_NUM_NATURAL; } -{Digit}+\.{Digit}+{ExpChar}{Digit}+ { strcpy( yylval.Value, yytext); return L_NUM_FLOAT;} --{Digit}+\.{Digit}+{ExpChar}{Digit}+ { strcpy( yylval.Value, yytext); return L_NUM_FLOAT;} -{Digit}+\.{Digit}+ { strcpy( yylval.Value, yytext); return L_NUM_FLOAT;} --{Digit}+\.{Digit}+ { strcpy( yylval.Value, yytext); return L_NUM_FLOAT;} -{Digit}+{ExpChar}{Digit}+ { strcpy( yylval.Value, yytext); return L_NUM_FLOAT;} --{Digit}+{ExpChar}{Digit}+ { strcpy( yylval.Value, yytext); return L_NUM_FLOAT;} - - /*******************************************/ - /* file_line_directive */ - /*******************************************/ -[#][ ]{Digit}+[ ]\" { BEGIN(file_line_rules); strcpy( RealLineNumber, yytext+2); } - -\"(\r)?$ { BEGIN(0); // # "" means start of base file. - pFileLineHandler->SetBase( InputBaseName, * pCurrentLineNumber); - } - -{FileNameChar}*\"(\r)?$ { BEGIN(0); // # means @ line of named base file. - pFileLineHandler->PostInclude( yytext, RealLineNumber, * pCurrentLineNumber); - } - -{FileNameChar}*\"[ ]1([ ]3){0,1}(\r)?$ { - BEGIN(0); // # 1 means start of an included file. - pFileLineHandler->SetInclude( yytext, * pCurrentLineNumber); - } - -{FileNameChar}*\"[ ]2([ ]3){0,1}(\r)?$ { - BEGIN(0); // # 2 means end of an included file and now at in . - pFileLineHandler->PostInclude( yytext, RealLineNumber, * pCurrentLineNumber); - } - - - - /*******************************************/ - /* White space */ - /*******************************************/ -[ \t] ; // skipped -[\n\r] ; // skipped -[\n\r] ; // skipped -"//" { BEGIN(cpp_comment); } -[\n\r] { BEGIN(0); } -. ; // skipped -"/*"/[^&\n] { BEGIN(c_comment); } -"/*"[\n\r] { BEGIN(c_comment); } -"*/" { BEGIN(0); } -[\n\r] ; // skipped -. ; // skipped - - /*******************************************/ - /* Comment tags */ - /*******************************************/ - -[ \t]*"/*&" { - BEGIN(comment_tag); - pGL->SetStart(*(pFileLineHandler->GetCurrentFile()), pFileLineHandler->GetErrorLine(* pCurrentLineNumber)); - return L_TAG_START; - } // any comment beginning with a slash followed by a star followed by an ampersand -"*/" { - BEGIN(0); - return L_TAG_END; - } -"@"[^* \t\r\n]+ { strcpy( yylval.Value, yytext); return L_TAG_COMMAND; } -[^*@ \t\n\r][^ *\t\r\n]* { strcpy( yylval.Value, yytext); return L_TAG_WORD; } -[\n\r] { strcpy( yylval.Value, "\n"); return L_TAG_NEW_LINE; } -[* \t] ; - - /*******************************************/ - /* Special single characters */ - /*******************************************/ -[.{};=\[\],()+\-*/|<>] return * yytext; - - - /*******************************************/ - /* Everything else cannot be recognised */ - /*******************************************/ -. { yyerror("*** Unknown character '%c' (value 0x%x) ", *yytext, *yytext);} +%option yylineno +%{ +// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// RCOMPL.INL +// Generated from RCOMP.L + + +#include +#include +#include "main.h" +#include "STRUCTST.H" +#include "Parser.h" +#include "localise.h" + +#define YY_SKIP_YYWRAP 1 +#define YY_NEVER_INTERACTIVE 1 +int yywrap(); +void yyerror(const char* string, ...); + +// Redefine YY_INPUT so we can parse binary data. +#undef YY_INPUT +#define YY_INPUT(buf, result, max_size) (result = new_yy_input(buf, max_size)) + +int new_yy_input(char *buf, int max_size) +{ + int result; + if(yyin != NULL) { + result = fread(buf, 1, max_size, yyin); + } + else if((pG->StdInBuffer != NULL) && (pG->StdInBufLength > 0)) { + int left = pG->StdInBufLength - pG->StdInfBufPos ; + if(left == 0) + return YY_NULL ; + result = (max_size < left) ? max_size : left ; + memcpy(buf,&(pG->StdInBuffer[pG->StdInfBufPos]),result); + pG->StdInfBufPos += result ; + } + + if (result == 0) + return YY_NULL; + + const unsigned char BOM[] = {0xef , 0xbb, 0xbf, 0x0 }; + // check for utf8 (BOM) header in buf + for (int i = 0; i < result-3; i++) { + if (0 == memcmp(&buf[i],BOM,3)) { + memset(&buf[i],0x20,3); + } + } + return result; +} + +#include "rcomp.hpp" +#include "FILELINE.H" + +#define VALUE_LEN (1024*8) // must match sizeof(YYSTYPE.Value) +char buf[VALUE_LEN]; +char * pCh; +#define CHECK_APPEND(x) \ + if (pCh-buf==VALUE_LEN-1) { yyerror("string too long - %c ignored", (x)); } else {*pCh++ = (x); } + +int isCharLiteral; + +extern String InputBaseName; +extern FileLineManager* pFileLineHandler; +extern int* pCurrentLineNumber; +char RealLineNumber[200]; + +#include "ERRORHAN.H" + +#define REGISTER_LINE ErrorHandler::Register(pFileLineHandler->GetCurrentFile(), pFileLineHandler->GetErrorLine(* pCurrentLineNumber)) + + +%} + +Digit [0-9] +Lower [a-z] +Upper [A-Z] +Letter {Lower}|{Upper} +Alphanumeric {Letter}|{Digit} +LetterOrUnderscore {Letter}|_ +AlphanumUscore {Alphanumeric}|_ +HexChar [A-Fa-f0-9] +ExpChar [eE] +FileNameChar [^"] + +%s string_rules + /* Rule set for string literals. */ + /* n.b. Exclusive rule sets i.e. %x are available in MKS only */ + /* so they are not used here; hence all the 's. */ + +%s file_line_rules + /* Rule set for file_line_directive.*/ + +%s cpp_comment + /* C++ comment to end of line */ + +%s c_comment + /* C comment */ + +%s comment_tag + /* Doxygen-style comment tag */ + +%% + + + /* Translations section */ + /* ==================== */ + + /*******************************************/ + /* Main keywords */ + /*******************************************/ +STRUCT return L_STRUCT; +RESOURCE return L_RESOURCE; +NAME return L_NAME; +CHARACTER_SET return L_CHARACTER_SET; +OFFSET return L_OFFSET; +SYSTEM return L_SYSTEM; +GLOBAL return L_GLOBAL; +LOCAL return L_LOCAL; +ENUM return L_ENUM; +enum return L_ENUM; +UID2 return L_UID_TWO; +UID3 return L_UID_THREE; +rls_string return L_RLS_STRING; +rls_string8 return L_RLS_STRING8; +rls_double return L_RLS_DOUBLE; +rls_byte return L_RLS_BYTE; +rls_word return L_RLS_WORD; +rls_long return L_RLS_LONG; +multi return L_MULTI; + + /*******************************************/ + /* Types */ + /*******************************************/ +BUF return L_BUF; +BUF8 return L_BUF8; +BUF16 return L_BUF16; +WORD return L_WORD; +BYTE return L_BYTE; +LONG return L_LONG; +DOUBLE return L_DOUBLE; +TEXT return L_TEXT; +LTEXT return L_LTEXT; +TEXT8 return L_TEXT8; +LTEXT8 return L_LTEXT8; +TEXT16 return L_TEXT16; +LTEXT16 return L_LTEXT16; +LINK return L_LINK; +LLINK return L_LLINK; +SRLINK return L_SRLINK; + + + /*******************************************/ + /* Others */ + /*******************************************/ +LEN return L_LEN; + + + /*******************************************/ + /* String & character literals */ + /*******************************************/ +\" { BEGIN(string_rules); pCh = buf; isCharLiteral=0; } +' { BEGIN(string_rules); pCh = buf; isCharLiteral=1; } + + /* Escaped single- and double-quotes.*/ +\\\" { CHECK_APPEND('"'); } +\\' { CHECK_APPEND('\''); }; + + /* Convert escaped character into corresponding actual character e.g. \t to tab. */ +\\[rbfntv] { CHECK_APPEND( * ( strchr("\rr\bb\ff\nn\tt\vv\aa", yytext[1])-1));} + + /* Escaped backslash */ +\\\\ { CHECK_APPEND('\\'); } + +\\\n /* Escaped newline ignored*/ ; + + /* End of line before terminating double-quotes.*/ +(\r)?\n { yyerror( isCharLiteral?"Unterminated character literal":"Unterminated string"); BEGIN 0; } + + /* End of string reached.*/ +\" { + if (!isCharLiteral) + { + *pCh = '\0'; BEGIN(0); strcpy( yylval.Value, buf); + return L_STRING_LITERAL; + } + CHECK_APPEND(*yytext); + } + +' { + if (isCharLiteral) + { + *pCh = '\0'; BEGIN(0); strcpy( yylval.Value, buf); return L_CHAR_LITERAL; + } + CHECK_APPEND(*yytext); + } + + /* Anything other than \n is stored.*/ +. { CHECK_APPEND(*yytext); } + + + /*******************************************/ + /* Labels */ + /*******************************************/ +{LetterOrUnderscore}{AlphanumUscore}* { + BEGIN(0); + strcpy( yylval.Value, yytext); + return L_LABEL; + } + + /*******************************************/ + /* Numbers */ + /*******************************************/ +{Digit}+ { strcpy( yylval.Value, yytext); return L_NUM_NATURAL; } +0x{HexChar}+ { strcpy( yylval.Value, yytext); return L_NUM_NATURAL; } +{Digit}+\.{Digit}+{ExpChar}{Digit}+ { strcpy( yylval.Value, yytext); return L_NUM_FLOAT;} +-{Digit}+\.{Digit}+{ExpChar}{Digit}+ { strcpy( yylval.Value, yytext); return L_NUM_FLOAT;} +{Digit}+\.{Digit}+ { strcpy( yylval.Value, yytext); return L_NUM_FLOAT;} +-{Digit}+\.{Digit}+ { strcpy( yylval.Value, yytext); return L_NUM_FLOAT;} +{Digit}+{ExpChar}{Digit}+ { strcpy( yylval.Value, yytext); return L_NUM_FLOAT;} +-{Digit}+{ExpChar}{Digit}+ { strcpy( yylval.Value, yytext); return L_NUM_FLOAT;} + + /*******************************************/ + /* file_line_directive */ + /*******************************************/ +[#][ ]{Digit}+[ ]\" { BEGIN(file_line_rules); strcpy( RealLineNumber, yytext+2); } + +\"(\r)?$ { BEGIN(0); // # "" means start of base file. + pFileLineHandler->SetBase( InputBaseName, * pCurrentLineNumber); + } + +{FileNameChar}*\"(\r)?$ { BEGIN(0); // # means @ line of named base file. + pFileLineHandler->PostInclude( yytext, RealLineNumber, * pCurrentLineNumber); + } + +{FileNameChar}*\"[ ]1([ ]3){0,1}(\r)?$ { + BEGIN(0); // # 1 means start of an included file. + pFileLineHandler->SetInclude( yytext, * pCurrentLineNumber); + } + +{FileNameChar}*\"[ ]2([ ]3){0,1}(\r)?$ { + BEGIN(0); // # 2 means end of an included file and now at in . + pFileLineHandler->PostInclude( yytext, RealLineNumber, * pCurrentLineNumber); + } + + + + /*******************************************/ + /* White space */ + /*******************************************/ +[ \t] ; // skipped +[\n\r] ; // skipped +[\n\r] ; // skipped +"//" { BEGIN(cpp_comment); } +[\n\r] { BEGIN(0); } +. ; // skipped +"/*"/[^&\n] { BEGIN(c_comment); } +"/*"[\n\r] { BEGIN(c_comment); } +"*/" { BEGIN(0); } +[\n\r] ; // skipped +. ; // skipped + + /*******************************************/ + /* Comment tags */ + /*******************************************/ + +[ \t]*"/*&" { + BEGIN(comment_tag); + pGL->SetStart(*(pFileLineHandler->GetCurrentFile()), pFileLineHandler->GetErrorLine(* pCurrentLineNumber)); + return L_TAG_START; + } // any comment beginning with a slash followed by a star followed by an ampersand +"*/" { + BEGIN(0); + return L_TAG_END; + } +"@"[^* \t\r\n]+ { strcpy( yylval.Value, yytext); return L_TAG_COMMAND; } +[^*@ \t\n\r][^ *\t\r\n]* { strcpy( yylval.Value, yytext); return L_TAG_WORD; } +[\n\r] { strcpy( yylval.Value, "\n"); return L_TAG_NEW_LINE; } +[* \t] ; + + /*******************************************/ + /* Special single characters */ + /*******************************************/ +[.{};=\[\],()+\-*/|<>] return * yytext; + + + /*******************************************/ + /* Everything else cannot be recognised */ + /*******************************************/ +. { yyerror("*** Unknown character '%c' (value 0x%x) ", *yytext, *yytext);} diff -r 122d2b873fd1 -r 30b30f9da0b7 bintools/rcomp/src/RCOMP.YACC --- a/bintools/rcomp/src/RCOMP.YACC Fri Jun 25 20:58:33 2010 +0800 +++ b/bintools/rcomp/src/RCOMP.YACC Tue Jun 29 14:52:54 2010 +0800 @@ -1,1295 +1,1297 @@ -%{ -// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). -// All rights reserved. -// This component and the accompanying materials are made available -// under the terms of the License "Eclipse Public License v1.0" -// which accompanies this distribution, and is available -// at the URL "http://www.eclipse.org/legal/epl-v10.html". -// -// Initial Contributors: -// Nokia Corporation - initial contribution. -// -// Contributors: -// -// RCOMP.CPP -// Generated from RCOMP.Y - -#include -#include -#include - -#if defined(__MSVCDOTNET__) || defined(__TOOLS2__) -#include -#include -using namespace std; -using std::cout; -using std::endl; -#else //!__MSVCDOTNET__ -#include -#endif //__MSVCDOTNET__ - -#ifdef __VC32__ -#pragma warning( disable : 4065 ) // C4065: switch statement contains 'default' but no 'case' labels -#pragma warning( disable : 4102 ) // C4102: 'yyerrlab1' : unreferenced label -#pragma warning( disable : 4127 ) // C4127: conditional expression is constant -#pragma warning( disable : 4244 ) // C4244: '=' : conversion from 'int' to 'short', possible loss of data -#endif //__VC32__ - -#include "resource.h" -#include "parser.h" - -int yylex(); -void yyerror(const char* string, ...); -int yywrap(); -#define YYDEBUG 1 -extern int yylineno; - -#include "rcomp.hpp" -#include "datatype.h" -#include "mem.h" -#include "rcbinstr.h" -#include "rcscan.h" -#include "errorhan.h" -#include "fileacc.h" -#include "version.h" -#include "ctable.h" -#include "localise.h" -#include "main.h" - -#if defined(__VC32__) && !defined(_DEBUG) -#pragma warning( disable : 4702 ) // unreachable code -#pragma warning( disable : 4102 ) // 'yyerrlabel' : unreferenced label -#pragma warning( disable : 4244 ) // '=' : conversion from 'int' to 'short', possible loss of data -#endif - - - -String::CharacterSet CharacterSetID( const String & character_set_name ); -void asUTF8(char* aUtf8, int aUnicode); -void SetIdFromName( const String & NameStatementValue); -void CheckStructUsage(); - -unsigned short & d = MemCheckControl::iLogMemory; - -StructHeader * pSH; - -StructHeaderArray * pSHA; // Used in resource struct handling functions. -ResourceHeader * pResourceHeader; -ResourceItemArray * pCurrentRIA; -StringArray * pUsedLabelsArray = new StringArray(); -int verbose; -String::CharacterSet SourceCharacterSet = String::CP1252; -String::CharacterSet TargetCharacterSet = String::CP1252; -unsigned short logmemorysetting; -int * pCurrentLineNumber; -FileLineManager * pFileLineHandler; -NameIdMap * pResourceNameIds; -long CurrentEnumValue; -String CurrentEnumName; -char TempStr[300]; -rcscan * pScan; - -int CurrentIdStep=1; -long CurrentId=0; -int FormatIdAsHex=0; // defaults to decimal, changes in SetIdFromName - -unsigned long Uid2=0; -unsigned long Uid3=0; - - - -const String Divider("*******************************************"); - -#define REGISTER_LINE ErrorHandler::Register(pFileLineHandler->GetCurrentFile(), pFileLineHandler->GetErrorLine(* pCurrentLineNumber)) - -// Convert a string containing a character literal in aQuoted -// into a value suitable for LCHAR_LITERAL -void SetCharacterLiteral(char* aOut, const String& aQuoted) - { - UTF16 first; - int length=1; - if (aQuoted.Length() < 1 ) - { - REGISTER_LINE; - ErrorHandler::OutputErrorLine("Warning: Empty Character literal"); - } - if (aQuoted.Length() > 1 ) - { - REGISTER_LINE; - ErrorHandler::OutputErrorLine("Error: String Literal length greater than 1"); - exit(1); - } - if (aQuoted.Export(&first, length, SourceCharacterSet)==0) - { - REGISTER_LINE; - ErrorHandler::OutputErrorLine("Warning: Ignoring trailing characters in character literal"); - } - sprintf(aOut, "%d", first); - } - -%} - -%union { - char Value[1024*8]; - TValueMaybeRls ValueMaybeRls; - unsigned long Id; - StructItem * pStructItem; - SimpleStructItem * pSimpleStructItem; - ArrayStructItem * pArrayStructItem; - StructArrayStructItem * pStructArrayStructItem; - StringArray * pStringArray; - long NumInitialiser; - TRlsQualifiers RlsQualifiers; - TRlsType RlsType; -} - -%token L_STRUCT L_RESOURCE L_NAME L_OFFSET L_SYSTEM L_GLOBAL L_LOCAL L_CHARACTER_SET -%token L_BUF L_WORD L_BYTE L_LONG L_DOUBLE L_TEXT L_LTEXT L_LINK L_LLINK L_SRLINK -%token L_BUF8 L_TEXT8 L_LTEXT8 L_BUF16 L_TEXT16 L_LTEXT16 L_UID_TWO L_UID_THREE -%token L_RLS_STRING L_RLS_STRING8 L_RLS_DOUBLE -%token L_RLS_BYTE L_RLS_WORD L_RLS_LONG -%token L_MULTI -%token L_TAG_START L_TAG_END -%token L_TAG_COMMAND L_TAG_WORD L_TAG_NEW_LINE -%token L_LABEL L_NUM_NATURAL L_NUM_FLOAT L_NATURAL_EXPR L_ENUM -%token L_LEN -%token L_CHAR_LITERAL L_STRING_LITERAL - -%type data_type len_declaration -%type struct_item array_struct_item simple_struct_item -%type simple_struct_item_start -%type struct_type_struct_item struct_array_struct_item -%type array_struct_item_start array_struct_item_base -%type struct_array_struct_item_base -%type simple_initialiser natural_expression -%type character_code_expression string_expression string_expression_item -%type simple_initialiser_list -%type natural_expression_numeric -%type rls_qualifiers rls_cardinality -%type rls_label -%type rls_string_item rls_num_item rls_float_item - -%left '+' '-' -%left '*' '/' -%left '|' -%left UMINUS - -%% - -/*****************************************************************/ -/* TOP-MOST RULE */ -/*****************************************************************/ -source : statement_list { if(verbose) { MOFF; cout << Divider << "\n" << Divider << endl; MON; } - } -; -/*****************************************************************/ -/* statement-list and statement */ -/*****************************************************************/ -statement_list: - statement_list statement -| statement_list comment_tag -| /* Nothing */ -; - -statement: - struct_statement maybe_semicolon -| resource_statement maybe_semicolon -| character_set_statement maybe_semicolon -| name_statement maybe_semicolon -| offset_statement maybe_semicolon -| system_statement maybe_semicolon -| enum_statement -| uidX_statement maybe_semicolon -| rls_item_statement maybe_semicolon -; - -maybe_semicolon: - ';' - { - // This is my gift to the world: no more "syntax error" for adding - // an extra semicolon at the end of a struct or resource. - REGISTER_LINE; - ErrorHandler::OutputErrorLine("Warning: unnecessary semicolon"); - } -| -; - -/******************************************************************/ -/* STRUCT statement */ -/******************************************************************/ -struct_statement: - struct_statement_start struct_item_list '}' - { if(verbose) { MOFF; cout << Divider << "\n" << * pSH << Divider << endl; MON;} } -; -struct_statement_start: - L_STRUCT L_LABEL maybe_comment_tag '{' - { if(verbose) { MOFF;cout << "struct_statement_start " << $2 << endl; MON;} - pSH = new StructHeader($2); - REGISTER_LINE; - pG->SHA.Add(pSH); - } -| L_STRUCT L_LABEL len_declaration maybe_comment_tag '{' - { if(verbose) { RCTypeArray Types; MOFF;cout << "struct_statement_start " << $2 << " " << Types.GetName($3) << endl; MON;} - pSH = new StructHeader($2, $3); - REGISTER_LINE; - pG->SHA.Add(pSH); - } -| L_STRUCT L_LABEL L_LEN maybe_comment_tag '{' - { if(verbose) { MOFF;cout << "struct_statement_start " << $2 << " (WORD)" << endl; MON;} - pSH = new StructHeader($2, L_WORD); - REGISTER_LINE; - pG->SHA.Add(pSH); - } -; -struct_item_list: - struct_item_list struct_item ';' { if(verbose) { MOFF;cout << "struct_item_list Adding struct_item." << endl; MON;} - REGISTER_LINE; - pSH->iSIA.Add($2); - } -| struct_item_list comment_tag struct_item ';' { if(verbose) { MOFF;cout << "tagged struct_item_list Adding struct_item." << endl; MON;} - REGISTER_LINE; - pSH->iSIA.Add($3); - } -| /* Nothing */ -; -struct_item: - simple_struct_item -| array_struct_item -| struct_type_struct_item -| struct_array_struct_item -; -simple_struct_item: - simple_struct_item_start { $$ = $1;} -| simple_struct_item_start '(' natural_expression ')' - { if(verbose) { MOFF;cout << " Limit: " << $3 << endl; MON;} - $1->iLengthLimit = $3; - $$ = $1; - } -| simple_struct_item_start '=' simple_initialiser /****************************************************************/ - { if(verbose) { MOFF;cout << " Default: " << $3 << endl; MON;} - $1->iDefault = $3; - $$ = $1; - } -| simple_struct_item_start '(' natural_expression ')' '=' string_expression /****************************************************************/ - { if(verbose) { MOFF;cout << " Limit: " << $3 << ", Default: " << $6 << endl; MON;} - NumericValue Limit($3, L_LONG); - if(String($6).ExportLength(TargetCharacterSet,SourceCharacterSet) > Limit.GetULong() ) - { - REGISTER_LINE; - ErrorHandler::OutputErrorLine("Text length exceeds specified limit"); - exit(1); - } - $1->iLengthLimit = $3; - $1->iDefault = $6; - $$ = $1; - } - -; -simple_struct_item_start: - data_type L_LABEL { if(verbose) - { - RCTypeArray Types; - MOFF;cout << "simple_struct_item " << Types.GetName($1) << " " << $2 << endl; MON; - } - $$ = new SimpleStructItem($1,$2); - assert($$ != NULL); - } -| data_type '<' natural_expression_numeric '>' L_LABEL - { if(verbose) - { RCTypeArray Types; - MOFF;cout << "simple_struct_item " << Types.GetName($1) << " " << $5 << endl; MON; - } - String s(NumericValue::ltoa($3)); - $$ = new SimpleStructItem($1,$5,s); - assert($$ != NULL); - } -; - -/* Note that generic text identifiers are converted to their explicit - 8 or 16-bit forms at this point, depending on the target character set. -*/ -data_type: - L_BYTE { $$ = L_BYTE;} -| L_WORD { $$ = L_WORD;} -| L_LONG { $$ = L_LONG;} -| L_DOUBLE { $$ = L_DOUBLE;} - - - -| L_TEXT - { - $$ = ( TargetCharacterSet == String::Unicode ) ? L_TEXT16: L_TEXT8; - REGISTER_LINE; - ErrorHandler::OutputErrorLine("Warning: Deprecated use of zero-terminated TEXT - use LTEXT instead"); - } -| L_LTEXT - { - $$ = ( TargetCharacterSet == String::Unicode ) ? L_LTEXT16: L_LTEXT8; - } -| L_BUF - { - $$ = ( TargetCharacterSet == String::Unicode ) ? L_BUF16: L_BUF8; - } - - - -| L_TEXT8 { $$ = L_TEXT8; - REGISTER_LINE; - ErrorHandler::OutputErrorLine("Warning: Deprecated use of zero-terminated TEXT8 - use LTEXT8 instead"); - } -| L_TEXT16 { $$ = L_TEXT16; - REGISTER_LINE; - ErrorHandler::OutputErrorLine("Warning: Deprecated use of zero-terminated TEXT16 - use LTEXT16 instead"); - } -| L_LTEXT8 { $$ = L_LTEXT8;} -| L_LTEXT16 { $$ = L_LTEXT16;} -| L_BUF8 { $$ = L_BUF8;} -| L_BUF16 { $$ = L_BUF16;} -| L_LINK { $$ = L_LINK;} -| L_LLINK { $$ = L_LLINK;} -| L_SRLINK { $$ = L_SRLINK;} -; -array_struct_item: - array_struct_item_base { $$ = $1;} -| array_struct_item_base '=' '{' simple_initialiser_list '}' - { if(verbose) { MOFF;cout << "array_struct_item with simple_initialiser_list" << endl;MON;} - $1->iDefaults = * $4; - if($1->iSize.Length() > 0) - { - NumericValue v($1->iSize, L_LONG); - REGISTER_LINE; - if($4->Size()!=long(v.GetULong())) - { - ErrorHandler::OutputErrorLine("Size does not match number of initialisers"); - exit(1); - } - } - $$ = $1; - delete $4; - } -; -array_struct_item_base: - array_struct_item_start ']' { if(verbose) { MOFF;cout << "array_struct_item_base with no size" << endl;MON;} - $$ =$1; - } -| array_struct_item_start natural_expression ']' - { if(verbose) { MOFF;cout << "array_struct_item_base with size " << $2 << endl;MON;} - $1->iSize = $2; - $$ = $1; - } -| L_LEN len_declaration array_struct_item_start ']' - { if(verbose) - { RCTypeArray Types; - MOFF;cout << "array_struct_item_base with LenType " << Types.GetName($2) << endl;MON; - } - $3->iLenType = $2; - $$ = $3; - } -| L_LEN len_declaration array_struct_item_start natural_expression ']' - { if(verbose) - { RCTypeArray Types; - MOFF;cout << "array_struct_item_base with size " << $4 << " and LenType " << Types.GetName($2) << endl;MON; - } - $3->iLenType = $2; - $3->iSize = $4; - $$ = $3; - } -; -array_struct_item_start: - data_type L_LABEL '[' { if(verbose) - { RCTypeArray Types; - MOFF;cout << "array_struct_item_start " << Types.GetName($1) << " " << $2 << endl;MON; - } - $$ = new ArrayStructItem($1, $2); - } -; -len_declaration: - L_BYTE { $$ = L_BYTE;} -| L_WORD { $$ = L_WORD;} -; -struct_type_struct_item: - L_STRUCT L_LABEL { if(verbose) { MOFF;cout << "struct_type_struct_item " << $2 << endl;MON;} - $$ = new StructTypeStructItem($2); - } -; -struct_array_struct_item: - struct_array_struct_item_base { $$ = $1;} -| L_LEN len_declaration struct_array_struct_item_base - { if(verbose) { RCTypeArray Types; MOFF;cout << "struct_array_struct_item - Setting Size to " << Types.GetName($2) << endl;MON;} - $3->iLenType = $2; $$ = $3; - } -; -struct_array_struct_item_base: - L_STRUCT L_LABEL '[' ']' { if(verbose) { MOFF;cout << "struct_array_struct_item_base " << $2 << endl;MON;} - $$ = new StructArrayStructItem($2); - } -| L_STRUCT L_LABEL '[' natural_expression ']' - { if(verbose) { MOFF;cout << "struct_array_struct_item_base " << $2 << " " << $4 << endl;MON;} - $$ = new StructArrayStructItem($2, $4); - } -; -/*********************************************************************/ -/* RESOURCE statement */ -/*********************************************************************/ -resource_statement: - resource_statement_start '{' resource_item_list '}' - { - pResourceHeader->AddDefault(); - CurrentId+=CurrentIdStep; - if(verbose) { MOFF;cout << "Resource ID "<< CurrentId << endl << Divider << "\n" << * pResourceHeader << Divider << endl;MON;} - pResourceHeader->SetResourceId(*pResourceNameIds,CurrentId,FormatIdAsHex); - pG->Index.Add(pResourceHeader); - - CheckStructUsage(); - - pUsedLabelsArray->Empty(); - - pResourceHeader = NULL; - } -; -resource_statement_start: - L_GLOBAL resource_statement_start_names {} /* Ignore GLOBAL (obsolete feature).*/ -| L_LOCAL resource_statement_start_names - { - if(verbose) { MOFF;cout << "resource_statement_start LOCAL" << endl;MON;} - assert(pResourceHeader != NULL); - pResourceHeader->iLocal = 1; - } -| resource_statement_start_names {} -; -resource_statement_start_names: - L_RESOURCE L_LABEL L_LABEL { if(verbose) { MOFF;cout << "resource_statement_start_names " << $2 << " " << $3 << endl;MON;} - assert(pResourceHeader == NULL); - pResourceHeader = new ResourceHeader($3); - pCurrentRIA = & (pResourceHeader->iRIA); - REGISTER_LINE; - if(pResourceNameIds->IsStored($3)) - { - ErrorHandler::OutputErrorLine("Resource with this name encountered already"); - exit(1); - } - pCurrentRIA->FillFromStruct($2); - pG->AllIdentifiers.Add(new String($3)); // Add label to store - } -| L_RESOURCE L_LABEL { if(verbose) { MOFF;cout << "resource_statement_start_names " << $2 << " " << endl;MON;} - assert(pResourceHeader == NULL); - pResourceHeader = new ResourceHeader; - pCurrentRIA = & (pResourceHeader->iRIA); - REGISTER_LINE; - pCurrentRIA->FillFromStruct($2); - } -; -resource_item_list: - resource_item_list resource_item ';'{ if(verbose) { MOFF;cout << "resource_item_list" << endl;MON;}} -| resource_item_list comment_tag resource_item ';'{ if(verbose) { MOFF;cout << "tagged resource_item_list" << endl;MON;}} -| resource_item_list error ';' { yyerrok; yyclearin; } -| /* Nothing */ -; -resource_item: - L_LABEL '=' simple_initialiser { if(verbose) { MOFF;cout << "resource_item " << $1 << " " << $3 << endl;MON;} - REGISTER_LINE;/****************************************************************/ - pCurrentRIA->Set($1, $3); - } -| resource_simple_array_item -| struct_resource_item -| struct_array_resource_item -; -resource_simple_array_item: - L_LABEL '=' '{' '}' - { - if (verbose) - { MOFF;cout << "resource_simple_array_item " << $1 << endl;MON;} - } -| L_LABEL '=' '{' simple_initialiser_list '}' - { - if (verbose) - { MOFF;cout << "resource_simple_array_item " << $1 << " with simple_initialiser_list" << endl;MON;} - REGISTER_LINE; - pCurrentRIA->Set($1, * $4); - delete $4; - } -; - -/*---------------------------------------------------------------------------*/ -/* A note about RIAStack, SRIStack and pCurrentRIA. */ -/* */ -/* RIA stands for Resource Item Array. */ -/* SRI stands for Struct Array Resource Item. */ -/* */ -/* A push to RIAStack is made when dropping inside a STRUCT or STRUCT[] in */ -/* order to set values for the components. When this happens pCurrentRIA is */ -/* set to the RIA for the STRUCT or last item of the STRUCT[]. */ -/* */ -/* pCurrentRIA is set to the result of popping from RIAStack when a closing */ -/* brace is reached. */ -/* */ -/* A push is made to SRIStack when going into an item for a STRUCT[]. On */ -/* reaching a closing brace the STRUCT[] is popped off the SRIStack. An new */ -/* item may then be added to this array. */ -/*---------------------------------------------------------------------------*/ -struct_resource_item: - struct_resource_item_start resource_item_list '}' - { if(verbose) { MOFF;cout << "struct_resource_item" << endl;MON;} - pCurrentRIA = pG->RIAStack.Pop(); - } -; -struct_resource_item_start: - L_LABEL '=' L_LABEL '{' { if(verbose) { MOFF;cout << "struct_resource_item_start " << $1 << " " << $3 << endl;MON;} - REGISTER_LINE; - pCurrentRIA->Set($1, $3); - String * thisLabel = new String($1); - pUsedLabelsArray->Add(thisLabel); - // in here add the label to a temp store - pG->RIAStack.Push(pCurrentRIA); - pCurrentRIA = pCurrentRIA->Find($1)->GetRIA(); - } -; -struct_array_resource_item: - struct_array_resource_item_start struct_array_resource_item_list_top '}' - { if(verbose) { MOFF;cout << "struct_array_resource_item" << endl;MON;} - pG->SRIStack.Pop(); - } -| struct_array_resource_item_start struct_array_resource_item_list_top error - { pG->SRIStack.Pop();} -; -struct_array_resource_item_start: - L_LABEL '=' '{' L_LABEL '{' { if(verbose) { MOFF;cout << "struct_array_resource_item_start " << $1 << " " << $4 << endl;MON;} - ResourceItem * p = pCurrentRIA->Find($1); - pG->SRIStack.Push(p); - REGISTER_LINE; - String * thisLabel = new String($1); - pUsedLabelsArray->Add(thisLabel); - // in here add the label to a temp store - p->Set($4); - pG->RIAStack.Push(pCurrentRIA); - pCurrentRIA = p->GetRIA(); - } -; -struct_array_resource_item_list_top: - struct_array_resource_item_list_top_start -| struct_array_resource_item_list_top_start ',' struct_array_resource_item_list -| struct_array_resource_item_list_top_start ',' error -; -struct_array_resource_item_list_top_start: - resource_item_list '}' { if(verbose) { MOFF;cout << "struct_array_resource_item_list_top " << endl;MON;} - pCurrentRIA = pG->RIAStack.Pop(); - } -; -struct_array_resource_item_list: - struct_array_resource_item_list_item -| struct_array_resource_item_list ',' struct_array_resource_item_list_item -; -struct_array_resource_item_list_item: - struct_array_resource_item_list_item_start resource_item_list '}' - { if(verbose) { MOFF;cout << "struct_array_resource_item_list_item " << endl;MON;} - pCurrentRIA = pG->RIAStack.Pop(); - } -; -struct_array_resource_item_list_item_start: - L_LABEL '{' { if(verbose) { MOFF;cout << "struct_array_resource_item_list_item_start " << $1 << endl;MON;} - ResourceItem * p = pG->SRIStack.Peek(); - REGISTER_LINE; - p->Set($1); - pG->RIAStack.Push(pCurrentRIA); - pCurrentRIA = p->GetRIA(); - } -; - - -/*****************************************************************/ -/* simple_initialiser and simple_initialiser_list */ -/*****************************************************************/ -simple_initialiser: - L_NUM_FLOAT -| L_CHAR_LITERAL - { - // convert literal to unsigned long value of 1st character - SetCharacterLiteral($$, $1); - } -| string_expression -| natural_expression -; -simple_initialiser_list: - simple_initialiser - { - if(verbose) - { - MOFF;cout << "simple_initialiser_list - single string " << $1 << endl;MON; - } - - $$ = new StringArray; - $$->Add(new String($1) ); - } -| simple_initialiser_list ',' simple_initialiser - { if(verbose) { MOFF;cout << "simple_initialiser_list - part of list " << $3 << endl;MON;} - assert($1 != NULL); - $1->Add(new String($3 ) ); - $$ = $1; - } -; - -natural_expression: - natural_expression_numeric { String s(NumericValue::ltoa($1) ); strcpy($$, s.GetAssertedNonEmptyBuffer() ); } -; -natural_expression_numeric: - L_NUM_NATURAL { if(verbose) { MOFF;cout << "Converting number " << $1 << endl;MON;} - REGISTER_LINE; - NumericValue v($1, L_LONG); $$ = (long)v.GetULong(); - } -| natural_expression_numeric '+' natural_expression_numeric { $$ = $1 + $3; } -| natural_expression_numeric '-' natural_expression_numeric { $$ = $1 - $3; } -| natural_expression_numeric '*' natural_expression_numeric { $$ = $1 * $3; } -| natural_expression_numeric '/' natural_expression_numeric { $$ = $1 / $3; } -| natural_expression_numeric '|' natural_expression_numeric { $$ = $1 | $3; } -| '-' natural_expression_numeric %prec UMINUS { if (!NumericValue::CheckSigned($2,L_LONG)) - { - REGISTER_LINE; - ErrorHandler::OutputErrorLine("Signed value too low"); - exit(1); - } - $$ = - $2; - } -| '(' natural_expression_numeric ')' { $$ = $2; } -; -string_expression: - string_expression_item -| string_expression_item string_expression { - if (strlen($$)+strlen($2) > sizeof($$)-1) - { - REGISTER_LINE; - ErrorHandler::OutputErrorLine("String expression is too long"); - exit(1); - } - strcat($$, $2); - } -; -string_expression_item: - L_STRING_LITERAL -| character_code_expression -| L_LABEL - { - const char * fileName = (*ErrorHandler::GetFileName()).GetBuffer(); - int lineNumber = ErrorHandler::GetLineNumber(); - QualifiedString * thisLabel = new QualifiedString($1, new String(fileName), lineNumber); - // store the label in the UsedIdentifiers array for checking - // whether label was declared - pG->UsedIdentifiers.Add(thisLabel); - - if (pG->EnumValues.IsStored($1)) - { - sprintf($$, "%d", pG->EnumValues.FindId($1)); - } - else if (pG->RlsNameIndex.count($1)) // if rls item has already been defined - { - // Found a reference to an rls_string. - RlsValue &rv = pG->RlsValues[pG->RlsNameIndex[$1]]; - ++rv.iCitationCount; // iCitationCount counts the number of times this rls value has been referneced - // Warn for multiple uses if 'multi' keyword not used. - if (1 < rv.iCitationCount && rv.iCardinality == ERlsCardinalitySingle) - { - Message * message = pG->Messages.GetEntry(LT_001); - String fileLine = *(rv.iFileName); - if(message->GetActivated()) - { - pGL->AddWarningToStore(fileLine, rv.iLineNumber, message->GetMessageOutput()); - } - REGISTER_LINE; - if (!pG->WarningMultiExplained) - { - Message * message = pG->Messages.GetEntry(LT_002); - fileLine = String(*(pFileLineHandler->GetCurrentFile())); - if(message->GetActivated()) - { - pGL->AddWarningToStore(fileLine, pFileLineHandler->GetErrorLine(* pCurrentLineNumber), message->GetMessageOutput()); - pG->WarningMultiExplained = true; - } - } - } - switch (rv.iType) - { - // Strings and numbers are just copied to the next layer up. - case ERlsString: - case ERlsString8: - case ERlsByte: - case ERlsWord: - case ERlsLong: - case ERlsDouble: - strcpy($$, rv.iValue.GetBuffer()); - break; - // Anything else is a character: this is converted to a number. - case ERlsStringChar: - case ERlsByteChar: - case ERlsWordChar: - case ERlsLongChar: - SetCharacterLiteral($$, rv.iValue); - break; - default: - Message * message = pG->Messages.GetEntry(LT_031); - if(message->GetActivated()) - { - ErrorHandler::OutputErrorLine(message->GetMessageOutput()); - exit(1); - } - break; - } - } - else - { - /* - Could be a reference to another resource, perhaps even a forward reference: - the OverwriteLink functions do FindId again when writing out the data. - Sadly this also permits things which are really syntax errors, inadvertently - converting labels into string literals.. - */ - } - } -; -character_code_expression: - '<' natural_expression_numeric '>' - { - REGISTER_LINE; - if($2 < 0 || ($2 > 255 && TargetCharacterSet != String::Unicode)) - { - ErrorHandler::OutputErrorLine("Character code must be a number in the range 0 to 255."); - exit(1); - } - if (TargetCharacterSet != String::Unicode) - { - * $$ = char($2); * ($$ + 1) = '\0'; - } - else - { - if (SourceCharacterSet == String::CP1252) - { - if ( ($2 >= 0x80) && ($2 <= 0x9F ) ) // 80-9F are illegal Unicode values. - { - ErrorHandler::OutputErrorLine("Warning: Deprecated non-unicode value in source stream"); - } - * $$ = char(UnicodeEscape); - asUTF8($$ + 1, $2); - } - else - if (SourceCharacterSet == String::UTF8) - { - asUTF8($$, $2); - } - else - { - // Unsatisfactory, but do people use other character sets? - if ($2 > 255) - { - ErrorHandler::OutputErrorLine("Don't know how to handle character > 255"); - } - * $$ = char($2); * ($$ + 1) = '\0'; - } - } - } -; - - -/*****************************************************************/ -/* name_statement */ -/*****************************************************************/ -name_statement: - L_NAME L_LABEL - { - REGISTER_LINE; - SetIdFromName($2); - } -| L_NAME L_STRING_LITERAL - { - REGISTER_LINE; - SetIdFromName($2); - } -; - - -/*****************************************************************/ -/* uidX_statement */ -/*****************************************************************/ -uidX_statement: - L_UID_TWO natural_expression_numeric - { - REGISTER_LINE; - if ($2 == 0) - { ErrorHandler::OutputErrorLine("UID2 must be non-zero"); exit(1); } - if (Uid2 != 0) - { ErrorHandler::OutputErrorLine("Warning: overwriting previous UID2 value"); } - Uid2=$2; - if(verbose) - { MOFF;cout << "uidX_statement UID2 " << Uid2 << endl;MON;} - } -| L_UID_THREE natural_expression_numeric - { - REGISTER_LINE; - if ($2 == 0) - { ErrorHandler::OutputErrorLine("UID3 must be non-zero"); exit(1); } - if (Uid3 != 0) - { ErrorHandler::OutputErrorLine("Warning: overwriting previous UID3 value"); } - Uid3=$2; - if(verbose) - { MOFF;cout << "uidX_statement UID3 " << Uid3 << endl;MON;} - } -; - - -/*****************************************************************/ -/* character_set_statement */ -/* Defines the SOURCE character set. Note that Unicode is a */ -/* character set id, but we can't read Unicode source */ -/* (because LEX and YACC can't handle it) */ -/*****************************************************************/ - -character_set_statement: - L_CHARACTER_SET L_LABEL { if(verbose) { MOFF;cout << "character_set_statement " << $2 << endl;MON;} - REGISTER_LINE; - SourceCharacterSet = CharacterSetID($2); - if ( SourceCharacterSet == String::UNKNOWN ) - { - String err = "Warning: Unrecognised character set name '"; - err += $2; - err += "'"; - ErrorHandler::OutputErrorLine(err); - } - if ( SourceCharacterSet == String::Unicode ) - { - SourceCharacterSet = String::UNKNOWN; - ErrorHandler::OutputErrorLine("Unicode source is unsupported"); - } - } -; - - - -/*****************************************************************/ -/* offset_statement */ -/*****************************************************************/ -offset_statement: - L_OFFSET natural_expression { if(verbose) { RCTypeArray Types; - MOFF;cout << "offset_statement " << $2 << endl;MON; } - REGISTER_LINE; - CurrentId=((long) NumericValue($2, L_LONG).GetULong() ); - } -; - -/*****************************************************************/ -/* system_statement */ -/*****************************************************************/ -system_statement: - L_SYSTEM { if(verbose) { MOFF;cout << "system_statement" << endl;MON;} - CurrentIdStep=-1; - } -; - -/*****************************************************************/ -/* enum_statement */ -/*****************************************************************/ -enum_statement: - enum_statement_start enum_list '}' -| enum_statement_start enum_list '}' ';' -; -enum_statement_start: - L_ENUM L_LABEL '{' - { - if(verbose) - { MOFF;cout << "enum_statement" << endl;MON;} - CurrentEnumName = $2; - CurrentEnumValue=0; - } -| L_ENUM '{' - { - if(verbose) - { MOFF;cout << "enum_statement" << endl;MON;} - CurrentEnumName = ""; - CurrentEnumValue=0; - } -; - -enum_list_entry: - L_LABEL - { - pG->EnumValues.Add($1, CurrentEnumValue++); - pG->AllIdentifiers.Add(new String($1)); // Add label to store - } -| L_LABEL '=' simple_initialiser - { - CurrentEnumValue = atol($3); - pG->EnumValues.Add($1, CurrentEnumValue); - CurrentEnumValue++; // Increment so that next field has value ($3+1) - pG->AllIdentifiers.Add(new String($1)); // Add label to store - } -; - - -enum_list: - maybe_comment_tag enum_list_entry -| enum_list ',' maybe_comment_tag enum_list_entry -; - -/************************/ -/* rls_xxxx statement */ -/************************/ -rls_item_statement: - rls_string_item rls_qualifiers rls_label string_expression - { - pG->RlsNameIndex[$3] = pG->RlsValues.size(); - pG->RlsValues.push_back(RlsValue(ErrorHandler::GetFileName(), - ErrorHandler::GetLineNumber(), $4, $1, - $2.iCardinality, $2.iMaxLength)); - if($2.iMaxLength - < String($4).ExportLength(TargetCharacterSet,SourceCharacterSet)) - { - Message * message = pG->Messages.GetEntry(LT_032); - if(message->GetActivated()) - { - ErrorHandler::OutputErrorLine(message->GetMessageOutput()); - exit(1); - } - } - } -| rls_string_item rls_qualifiers rls_label L_CHAR_LITERAL /* This section is only for compatibility */ - { - Message * message = pG->Messages.GetEntry(LT_033); - String fileName = *(pFileLineHandler->GetCurrentFile()); - int lineNumber = pFileLineHandler->GetErrorLine(* pCurrentLineNumber); - if(message->GetActivated()) - { - pGL->AddWarningToStore(fileName, lineNumber, message->GetMessageOutput()); - } - //... - /* Produce a warning "rls_string used for character constant: use rls_long, rls_word or rls_byte" */ - pG->RlsNameIndex[$3] = pG->RlsValues.size(); - pG->RlsValues.push_back(RlsValue(ErrorHandler::GetFileName(), - ErrorHandler::GetLineNumber(), $4, ERlsStringChar, - $2.iCardinality)); - } -| rls_float_item rls_cardinality rls_label L_NUM_FLOAT - { - pG->RlsNameIndex[$3] = pG->RlsValues.size(); - pG->RlsValues.push_back(RlsValue(ErrorHandler::GetFileName(), - ErrorHandler::GetLineNumber(), $4, $1, - $2.iCardinality)); - } -| rls_num_item rls_cardinality rls_label L_NUM_NATURAL - { - pG->RlsNameIndex[$3] = pG->RlsValues.size(); - pG->RlsValues.push_back(RlsValue(ErrorHandler::GetFileName(), - ErrorHandler::GetLineNumber(), $4, $1, - $2.iCardinality)); - } -| rls_num_item rls_cardinality rls_label L_CHAR_LITERAL - { - TRlsType rlsCharType = $1 == ERlsByte? ERlsByteChar - : ( $1 == ERlsWord? ERlsWordChar : ERlsLongChar ); - pG->RlsNameIndex[$3] = pG->RlsValues.size(); - pG->RlsValues.push_back(RlsValue(ErrorHandler::GetFileName(), - ErrorHandler::GetLineNumber(), $4, rlsCharType, - $2.iCardinality)); - } -; - -rls_label: L_LABEL - { - // Register line even if no warning here so that - // the rls_ item knows which line the label was on. - // Without this, the line registered would be the - // line following the declaration. - REGISTER_LINE; - strcpy($$, $1); - - if (pG->RlsNameIndex.count($1) != 0) - { - Message * message = pG->Messages.GetEntry(LT_003); - if(message->GetActivated()) - { - ErrorHandler::OutputErrorLine(message->GetMessageOutput()); - } - } - pG->AllIdentifiers.Add(new String($1)); // Add label to store - } - -rls_qualifiers: - '<' L_NUM_NATURAL '>' rls_cardinality - { - NumericValue v($2, L_LONG); - $$.iMaxLength = v.GetULong(); - $$.iCardinality = $4.iCardinality; - } -| rls_cardinality - { $$ = $1; } -; - -rls_cardinality: - L_MULTI - { - $$.iMaxLength = 0xFFFFFFF; - $$.iCardinality = ERlsCardinalityMultiple; - } -| - { - $$.iMaxLength = 0xFFFFFFF; - $$.iCardinality = ERlsCardinalitySingle; - } -; - -rls_string_item: - L_RLS_STRING - { $$ = ERlsString; } -| L_RLS_STRING8 - { $$ = ERlsString8; } -; - -rls_num_item: - L_RLS_BYTE - { $$ = ERlsByte; } -| L_RLS_WORD - { $$ = ERlsWord; } -| L_RLS_LONG - { $$ = ERlsLong; } -; - -rls_float_item: - L_RLS_DOUBLE - { $$ = ERlsDouble; } -; - -/************************/ -/* comment tags */ -/************************/ -maybe_comment_tag: - comment_tag -| -; - -comment_tag: - L_TAG_START tag_line L_TAG_END {ErrorHandler::Register(pFileLineHandler->GetCurrentFile(), pFileLineHandler->GetErrorLine(*pCurrentLineNumber)); } - ; - -tag_line: - tag_line tag_word - -| -; - -tag_word: - L_TAG_NEW_LINE { pGL->StoreComment($1); } -| L_TAG_COMMAND { pGL->StoreComment($1); } -| L_TAG_WORD { pGL->StoreComment($1); } -; - -%% - -// Function section -// ================ - -void asUTF8(char* aUtf8, int aUnicode) - { - if ( aUnicode > 0xffff ) - { - if ( aUnicode > 0x10ffff ) - { - ErrorHandler::OutputErrorLine("Surrogate character code must be a number in the range 0x10000 to 0x10ffff"); - exit(1); - } - - UTF16 high = (UTF16)(0xD7C0 + (aUnicode >> 10)); // high surrogate - UTF16 low = (UTF16)(0xDC00 | (aUnicode & 0x3FF)); // low surrogate - - *aUtf8++ =(char)(0xe0|(high>>12)); - *aUtf8++ =(char)(0x80|((high>>6)&0x3f)); - *aUtf8++ =(char)(0x80|(high&0x3f)); - *aUtf8++ =(char)(0xe0|(low>>12)); - *aUtf8++ =(char)(0x80|((low>>6)&0x3f)); - *aUtf8 =(char)(0x80|(low&0x3f)); - } - else if ((aUnicode & 0xff80) == 0x0000) - { - *aUtf8 = (char)aUnicode; - } - else if ((aUnicode & 0xf800) == 0x0000) - { - *aUtf8++ =(char)(0xc0|(aUnicode>>6)); - *aUtf8 =(char)(0x80|(aUnicode&0x3f)); - } - else - { - *aUtf8++ =(char)(0xe0|(aUnicode>>12)); - *aUtf8++ =(char)(0x80|((aUnicode>>6)&0x3f)); - *aUtf8 =(char)(0x80|(aUnicode&0x3f)); - } - *++aUtf8 = '\0'; - } - - -String::CharacterSet CharacterSetID( const String & character_set_name ) -// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -// Return a character set ID from a character set name. The value UNKNOWN -// is returned if the name is not recognised. -// ---------------------------------------------------------------------------- -{ - String::CharacterSet ids[] = { String::ISOLatin1, String::ASCII, String::CP1252 - , String::CP850, String::ShiftJIS, String::Unicode - , String::UTF8 - , String::UNKNOWN - }; - String names[] = { "ISOLATIN1", "ASCII", "CP1252", "CP850", "SHIFTJIS", "UNICODE", "UTF8" }; - - for ( int i=0; ids[i]!=String::UNKNOWN; i++ ) - { - if ( names[i] == character_set_name ) return ids[i]; - } - - return String::UNKNOWN; - -} // end of CharacterSetID code - -void SetIdFromName( const String & NameStatementValue) - { - // space 0 - // A 1 - // B 2 - // ... - // Z 26 - // - // ABCD corresponds to the number 4321 which becomes ( (4*27 + 3) * 27 + 2) * 27 + 1. - - if(verbose) - { MOFF;cout << "name_statement " << NameStatementValue << endl;MON;} - if ( NameStatementValue.Length() > 4) - { - ErrorHandler::OutputErrorLine( "Name must be no longer than four characters"); - exit( 1); - } - - long NewId = 0; - - for( unsigned long i = 0; i < NameStatementValue.Length(); i++) - { - NewId *= 27; - if ( isalpha( NameStatementValue[i]) ) - NewId += toupper( NameStatementValue[i]) - 'A' + 1; - } - - CurrentId = NewId << 12; - FormatIdAsHex = 1; - if(verbose) - { MOFF;cout << "Current id " << CurrentId << endl;MON;} - } - -void RlsUnusedWarnings() - { - TNameIndex::iterator end = pG->RlsNameIndex.end(); - for (TNameIndex::iterator i = pG->RlsNameIndex.begin(); i != end; ++i) - { - int index = i->second; - RlsValue& v = pG->RlsValues[index]; - if (v.iCitationCount == 0) - { - Message * message = pG->Messages.GetEntry(LT_004); - String fileLine = *(v.iFileName); - if(message->GetActivated()) - { - pGL->AddWarningToStore(fileLine, v.iLineNumber, message->GetMessageOutput()); - } - } - } - } - -int ParseSourceFile(FILE* aFile, unsigned short aYYDebug) - { - // Set up various global pointers which refer to the pG structure - pSHA = & (pG->SHA); - pFileLineHandler = & (pG->FileLineHandler); - pResourceNameIds = & (pG->ResourceNameIds); - - pScan = new rcscan(pG->FileLineHandler, aFile); - - yydebug = aYYDebug; - pCurrentLineNumber = &yylineno; - int ReturnValue = yyparse(); - - RlsUnusedWarnings(); - - int bScanErrorFound = pScan->ErrorWasFound(); - - delete pScan; - pScan = NULL; - - if(ReturnValue != 0) - return ReturnValue; - - if(bScanErrorFound) - return 1; - - return 0; // successful parse - parse tree now in the pG data structure - } - - -void CheckStructUsage() - { - ResourceItemArrayIterator nextRI( *pCurrentRIA); - ResourceItem * pRI; - while ( ( pRI = nextRI() ) != NULL) - { - int resourceItemType = pRI->GetResourceItemType(); - String resourceItemLabel = pRI->GetLabel(); - if( (resourceItemType == EStructTypeResourceItem) || (resourceItemType == EStructArrayResourceItem) ) - { - StringArrayIterator nextLabel( *pUsedLabelsArray); - String * pLabel; - bool flag = false; - while ( ( ( pLabel = nextLabel() ) != NULL ) && (! flag) ) - { - StringLess stringCompare; - if( !stringCompare(resourceItemLabel,*pLabel) && !stringCompare(*pLabel,resourceItemLabel) ) - { - flag = true; - } - } - if(! flag) - { - if(resourceItemType == EStructTypeResourceItem) - { - Message * message = pG->Messages.GetEntry(LT_046); - if(message->GetActivated()) - { - String comment = message->GetMessageOutput(); - comment += "'"; - comment += resourceItemLabel; - comment += "'"; - ErrorHandler::OutputErrorLine(comment); - } - } - else - { - Message * message = pG->Messages.GetEntry(LT_047); - if(message->GetActivated()) - { - String comment = message->GetMessageOutput(); - comment += "'"; - comment += resourceItemLabel; - comment += "'"; - ErrorHandler::OutputErrorLine(comment); - } - } - } - } - } - } - -int yywrap() -{ - return 1; -} - -/* Called by yyparse on error */ -#include -void yyerror (const char *s, ...) -{ - va_list list; - va_start(list, s); - pScan->yyerror(const_cast(s), list); - va_end(list); -} - - +%{ +// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// RCOMP.CPP +// Generated from RCOMP.Y + +#include +#include +#include + +#if defined(__MSVCDOTNET__) || defined(__TOOLS2__) +#include +#include +using namespace std; +using std::cout; +using std::endl; +#else //!__MSVCDOTNET__ +#include +#endif //__MSVCDOTNET__ + +#ifdef __VC32__ +#pragma warning( disable : 4065 ) // C4065: switch statement contains 'default' but no 'case' labels +#pragma warning( disable : 4102 ) // C4102: 'yyerrlab1' : unreferenced label +#pragma warning( disable : 4127 ) // C4127: conditional expression is constant +#pragma warning( disable : 4244 ) // C4244: '=' : conversion from 'int' to 'short', possible loss of data +#endif //__VC32__ + +//#include "resource.h" +//#include "parser.h" +#include "RESOURCE.H" +#include "parser.h" + +int yylex(); +void yyerror(const char* string, ...); +int yywrap(); +#define YYDEBUG 1 +extern int yylineno; + +#include "rcomp.hpp" +#include "datatype.h" +#include "mem.h" +#include "rcbinstr.h" +#include "rcscan.h" +#include "errorhan.h" +#include "fileacc.h" +#include "version.h" +#include "ctable.h" +#include "localise.h" +#include "main.h" + +#if defined(__VC32__) && !defined(_DEBUG) +#pragma warning( disable : 4702 ) // unreachable code +#pragma warning( disable : 4102 ) // 'yyerrlabel' : unreferenced label +#pragma warning( disable : 4244 ) // '=' : conversion from 'int' to 'short', possible loss of data +#endif + + + +String::CharacterSet CharacterSetID( const String & character_set_name ); +void asUTF8(char* aUtf8, int aUnicode); +void SetIdFromName( const String & NameStatementValue); +void CheckStructUsage(); + +unsigned short & d = MemCheckControl::iLogMemory; + +StructHeader * pSH; + +StructHeaderArray * pSHA; // Used in resource struct handling functions. +ResourceHeader * pResourceHeader; +ResourceItemArray * pCurrentRIA; +StringArray * pUsedLabelsArray = new StringArray(); +int verbose; +String::CharacterSet SourceCharacterSet = String::CP1252; +String::CharacterSet TargetCharacterSet = String::CP1252; +unsigned short logmemorysetting; +int * pCurrentLineNumber; +FileLineManager * pFileLineHandler; +NameIdMap * pResourceNameIds; +long CurrentEnumValue; +String CurrentEnumName; +char TempStr[300]; +rcscan * pScan; + +int CurrentIdStep=1; +long CurrentId=0; +int FormatIdAsHex=0; // defaults to decimal, changes in SetIdFromName + +unsigned long Uid2=0; +unsigned long Uid3=0; + + + +const String Divider("*******************************************"); + +#define REGISTER_LINE ErrorHandler::Register(pFileLineHandler->GetCurrentFile(), pFileLineHandler->GetErrorLine(* pCurrentLineNumber)) + +// Convert a string containing a character literal in aQuoted +// into a value suitable for LCHAR_LITERAL +void SetCharacterLiteral(char* aOut, const String& aQuoted) + { + UTF16 first; + int length=1; + if (aQuoted.Length() < 1 ) + { + REGISTER_LINE; + ErrorHandler::OutputErrorLine("Warning: Empty Character literal"); + } + if (aQuoted.Length() > 1 ) + { + REGISTER_LINE; + ErrorHandler::OutputErrorLine("Error: String Literal length greater than 1"); + exit(1); + } + if (aQuoted.Export(&first, length, SourceCharacterSet)==0) + { + REGISTER_LINE; + ErrorHandler::OutputErrorLine("Warning: Ignoring trailing characters in character literal"); + } + sprintf(aOut, "%d", first); + } + +%} + +%union { + char Value[1024*8]; + TValueMaybeRls ValueMaybeRls; + unsigned long Id; + StructItem * pStructItem; + SimpleStructItem * pSimpleStructItem; + ArrayStructItem * pArrayStructItem; + StructArrayStructItem * pStructArrayStructItem; + StringArray * pStringArray; + long NumInitialiser; + TRlsQualifiers RlsQualifiers; + TRlsType RlsType; +} + +%token L_STRUCT L_RESOURCE L_NAME L_OFFSET L_SYSTEM L_GLOBAL L_LOCAL L_CHARACTER_SET +%token L_BUF L_WORD L_BYTE L_LONG L_DOUBLE L_TEXT L_LTEXT L_LINK L_LLINK L_SRLINK +%token L_BUF8 L_TEXT8 L_LTEXT8 L_BUF16 L_TEXT16 L_LTEXT16 L_UID_TWO L_UID_THREE +%token L_RLS_STRING L_RLS_STRING8 L_RLS_DOUBLE +%token L_RLS_BYTE L_RLS_WORD L_RLS_LONG +%token L_MULTI +%token L_TAG_START L_TAG_END +%token L_TAG_COMMAND L_TAG_WORD L_TAG_NEW_LINE +%token L_LABEL L_NUM_NATURAL L_NUM_FLOAT L_NATURAL_EXPR L_ENUM +%token L_LEN +%token L_CHAR_LITERAL L_STRING_LITERAL + +%type data_type len_declaration +%type struct_item array_struct_item simple_struct_item +%type simple_struct_item_start +%type struct_type_struct_item struct_array_struct_item +%type array_struct_item_start array_struct_item_base +%type struct_array_struct_item_base +%type simple_initialiser natural_expression +%type character_code_expression string_expression string_expression_item +%type simple_initialiser_list +%type natural_expression_numeric +%type rls_qualifiers rls_cardinality +%type rls_label +%type rls_string_item rls_num_item rls_float_item + +%left '+' '-' +%left '*' '/' +%left '|' +%left UMINUS + +%% + +/*****************************************************************/ +/* TOP-MOST RULE */ +/*****************************************************************/ +source : statement_list { if(verbose) { MOFF; cout << Divider << "\n" << Divider << endl; MON; } + } +; +/*****************************************************************/ +/* statement-list and statement */ +/*****************************************************************/ +statement_list: + statement_list statement +| statement_list comment_tag +| /* Nothing */ +; + +statement: + struct_statement maybe_semicolon +| resource_statement maybe_semicolon +| character_set_statement maybe_semicolon +| name_statement maybe_semicolon +| offset_statement maybe_semicolon +| system_statement maybe_semicolon +| enum_statement +| uidX_statement maybe_semicolon +| rls_item_statement maybe_semicolon +; + +maybe_semicolon: + ';' + { + // This is my gift to the world: no more "syntax error" for adding + // an extra semicolon at the end of a struct or resource. + REGISTER_LINE; + ErrorHandler::OutputErrorLine("Warning: unnecessary semicolon"); + } +| +; + +/******************************************************************/ +/* STRUCT statement */ +/******************************************************************/ +struct_statement: + struct_statement_start struct_item_list '}' + { if(verbose) { MOFF; cout << Divider << "\n" << * pSH << Divider << endl; MON;} } +; +struct_statement_start: + L_STRUCT L_LABEL maybe_comment_tag '{' + { if(verbose) { MOFF;cout << "struct_statement_start " << $2 << endl; MON;} + pSH = new StructHeader($2); + REGISTER_LINE; + pG->SHA.Add(pSH); + } +| L_STRUCT L_LABEL len_declaration maybe_comment_tag '{' + { if(verbose) { RCTypeArray Types; MOFF;cout << "struct_statement_start " << $2 << " " << Types.GetName($3) << endl; MON;} + pSH = new StructHeader($2, $3); + REGISTER_LINE; + pG->SHA.Add(pSH); + } +| L_STRUCT L_LABEL L_LEN maybe_comment_tag '{' + { if(verbose) { MOFF;cout << "struct_statement_start " << $2 << " (WORD)" << endl; MON;} + pSH = new StructHeader($2, L_WORD); + REGISTER_LINE; + pG->SHA.Add(pSH); + } +; +struct_item_list: + struct_item_list struct_item ';' { if(verbose) { MOFF;cout << "struct_item_list Adding struct_item." << endl; MON;} + REGISTER_LINE; + pSH->iSIA.Add($2); + } +| struct_item_list comment_tag struct_item ';' { if(verbose) { MOFF;cout << "tagged struct_item_list Adding struct_item." << endl; MON;} + REGISTER_LINE; + pSH->iSIA.Add($3); + } +| /* Nothing */ +; +struct_item: + simple_struct_item +| array_struct_item +| struct_type_struct_item +| struct_array_struct_item +; +simple_struct_item: + simple_struct_item_start { $$ = $1;} +| simple_struct_item_start '(' natural_expression ')' + { if(verbose) { MOFF;cout << " Limit: " << $3 << endl; MON;} + $1->iLengthLimit = $3; + $$ = $1; + } +| simple_struct_item_start '=' simple_initialiser /****************************************************************/ + { if(verbose) { MOFF;cout << " Default: " << $3 << endl; MON;} + $1->iDefault = $3; + $$ = $1; + } +| simple_struct_item_start '(' natural_expression ')' '=' string_expression /****************************************************************/ + { if(verbose) { MOFF;cout << " Limit: " << $3 << ", Default: " << $6 << endl; MON;} + NumericValue Limit($3, L_LONG); + if(String($6).ExportLength(TargetCharacterSet,SourceCharacterSet) > Limit.GetULong() ) + { + REGISTER_LINE; + ErrorHandler::OutputErrorLine("Text length exceeds specified limit"); + exit(1); + } + $1->iLengthLimit = $3; + $1->iDefault = $6; + $$ = $1; + } + +; +simple_struct_item_start: + data_type L_LABEL { if(verbose) + { + RCTypeArray Types; + MOFF;cout << "simple_struct_item " << Types.GetName($1) << " " << $2 << endl; MON; + } + $$ = new SimpleStructItem($1,$2); + assert($$ != NULL); + } +| data_type '<' natural_expression_numeric '>' L_LABEL + { if(verbose) + { RCTypeArray Types; + MOFF;cout << "simple_struct_item " << Types.GetName($1) << " " << $5 << endl; MON; + } + String s(NumericValue::ltoa($3)); + $$ = new SimpleStructItem($1,$5,s); + assert($$ != NULL); + } +; + +/* Note that generic text identifiers are converted to their explicit + 8 or 16-bit forms at this point, depending on the target character set. +*/ +data_type: + L_BYTE { $$ = L_BYTE;} +| L_WORD { $$ = L_WORD;} +| L_LONG { $$ = L_LONG;} +| L_DOUBLE { $$ = L_DOUBLE;} + + + +| L_TEXT + { + $$ = ( TargetCharacterSet == String::Unicode ) ? L_TEXT16: L_TEXT8; + REGISTER_LINE; + ErrorHandler::OutputErrorLine("Warning: Deprecated use of zero-terminated TEXT - use LTEXT instead"); + } +| L_LTEXT + { + $$ = ( TargetCharacterSet == String::Unicode ) ? L_LTEXT16: L_LTEXT8; + } +| L_BUF + { + $$ = ( TargetCharacterSet == String::Unicode ) ? L_BUF16: L_BUF8; + } + + + +| L_TEXT8 { $$ = L_TEXT8; + REGISTER_LINE; + ErrorHandler::OutputErrorLine("Warning: Deprecated use of zero-terminated TEXT8 - use LTEXT8 instead"); + } +| L_TEXT16 { $$ = L_TEXT16; + REGISTER_LINE; + ErrorHandler::OutputErrorLine("Warning: Deprecated use of zero-terminated TEXT16 - use LTEXT16 instead"); + } +| L_LTEXT8 { $$ = L_LTEXT8;} +| L_LTEXT16 { $$ = L_LTEXT16;} +| L_BUF8 { $$ = L_BUF8;} +| L_BUF16 { $$ = L_BUF16;} +| L_LINK { $$ = L_LINK;} +| L_LLINK { $$ = L_LLINK;} +| L_SRLINK { $$ = L_SRLINK;} +; +array_struct_item: + array_struct_item_base { $$ = $1;} +| array_struct_item_base '=' '{' simple_initialiser_list '}' + { if(verbose) { MOFF;cout << "array_struct_item with simple_initialiser_list" << endl;MON;} + $1->iDefaults = * $4; + if($1->iSize.Length() > 0) + { + NumericValue v($1->iSize, L_LONG); + REGISTER_LINE; + if($4->Size()!=long(v.GetULong())) + { + ErrorHandler::OutputErrorLine("Size does not match number of initialisers"); + exit(1); + } + } + $$ = $1; + delete $4; + } +; +array_struct_item_base: + array_struct_item_start ']' { if(verbose) { MOFF;cout << "array_struct_item_base with no size" << endl;MON;} + $$ =$1; + } +| array_struct_item_start natural_expression ']' + { if(verbose) { MOFF;cout << "array_struct_item_base with size " << $2 << endl;MON;} + $1->iSize = $2; + $$ = $1; + } +| L_LEN len_declaration array_struct_item_start ']' + { if(verbose) + { RCTypeArray Types; + MOFF;cout << "array_struct_item_base with LenType " << Types.GetName($2) << endl;MON; + } + $3->iLenType = $2; + $$ = $3; + } +| L_LEN len_declaration array_struct_item_start natural_expression ']' + { if(verbose) + { RCTypeArray Types; + MOFF;cout << "array_struct_item_base with size " << $4 << " and LenType " << Types.GetName($2) << endl;MON; + } + $3->iLenType = $2; + $3->iSize = $4; + $$ = $3; + } +; +array_struct_item_start: + data_type L_LABEL '[' { if(verbose) + { RCTypeArray Types; + MOFF;cout << "array_struct_item_start " << Types.GetName($1) << " " << $2 << endl;MON; + } + $$ = new ArrayStructItem($1, $2); + } +; +len_declaration: + L_BYTE { $$ = L_BYTE;} +| L_WORD { $$ = L_WORD;} +; +struct_type_struct_item: + L_STRUCT L_LABEL { if(verbose) { MOFF;cout << "struct_type_struct_item " << $2 << endl;MON;} + $$ = new StructTypeStructItem($2); + } +; +struct_array_struct_item: + struct_array_struct_item_base { $$ = $1;} +| L_LEN len_declaration struct_array_struct_item_base + { if(verbose) { RCTypeArray Types; MOFF;cout << "struct_array_struct_item - Setting Size to " << Types.GetName($2) << endl;MON;} + $3->iLenType = $2; $$ = $3; + } +; +struct_array_struct_item_base: + L_STRUCT L_LABEL '[' ']' { if(verbose) { MOFF;cout << "struct_array_struct_item_base " << $2 << endl;MON;} + $$ = new StructArrayStructItem($2); + } +| L_STRUCT L_LABEL '[' natural_expression ']' + { if(verbose) { MOFF;cout << "struct_array_struct_item_base " << $2 << " " << $4 << endl;MON;} + $$ = new StructArrayStructItem($2, $4); + } +; +/*********************************************************************/ +/* RESOURCE statement */ +/*********************************************************************/ +resource_statement: + resource_statement_start '{' resource_item_list '}' + { + pResourceHeader->AddDefault(); + CurrentId+=CurrentIdStep; + if(verbose) { MOFF;cout << "Resource ID "<< CurrentId << endl << Divider << "\n" << * pResourceHeader << Divider << endl;MON;} + pResourceHeader->SetResourceId(*pResourceNameIds,CurrentId,FormatIdAsHex); + pG->Index.Add(pResourceHeader); + + CheckStructUsage(); + + pUsedLabelsArray->Empty(); + + pResourceHeader = NULL; + } +; +resource_statement_start: + L_GLOBAL resource_statement_start_names {} /* Ignore GLOBAL (obsolete feature).*/ +| L_LOCAL resource_statement_start_names + { + if(verbose) { MOFF;cout << "resource_statement_start LOCAL" << endl;MON;} + assert(pResourceHeader != NULL); + pResourceHeader->iLocal = 1; + } +| resource_statement_start_names {} +; +resource_statement_start_names: + L_RESOURCE L_LABEL L_LABEL { if(verbose) { MOFF;cout << "resource_statement_start_names " << $2 << " " << $3 << endl;MON;} + assert(pResourceHeader == NULL); + pResourceHeader = new ResourceHeader($3); + pCurrentRIA = & (pResourceHeader->iRIA); + REGISTER_LINE; + if(pResourceNameIds->IsStored($3)) + { + ErrorHandler::OutputErrorLine("Resource with this name encountered already"); + exit(1); + } + pCurrentRIA->FillFromStruct($2); + pG->AllIdentifiers.Add(new String($3)); // Add label to store + } +| L_RESOURCE L_LABEL { if(verbose) { MOFF;cout << "resource_statement_start_names " << $2 << " " << endl;MON;} + assert(pResourceHeader == NULL); + pResourceHeader = new ResourceHeader; + pCurrentRIA = & (pResourceHeader->iRIA); + REGISTER_LINE; + pCurrentRIA->FillFromStruct($2); + } +; +resource_item_list: + resource_item_list resource_item ';'{ if(verbose) { MOFF;cout << "resource_item_list" << endl;MON;}} +| resource_item_list comment_tag resource_item ';'{ if(verbose) { MOFF;cout << "tagged resource_item_list" << endl;MON;}} +| resource_item_list error ';' { yyerrok; yyclearin; } +| /* Nothing */ +; +resource_item: + L_LABEL '=' simple_initialiser { if(verbose) { MOFF;cout << "resource_item " << $1 << " " << $3 << endl;MON;} + REGISTER_LINE;/****************************************************************/ + pCurrentRIA->Set($1, $3); + } +| resource_simple_array_item +| struct_resource_item +| struct_array_resource_item +; +resource_simple_array_item: + L_LABEL '=' '{' '}' + { + if (verbose) + { MOFF;cout << "resource_simple_array_item " << $1 << endl;MON;} + } +| L_LABEL '=' '{' simple_initialiser_list '}' + { + if (verbose) + { MOFF;cout << "resource_simple_array_item " << $1 << " with simple_initialiser_list" << endl;MON;} + REGISTER_LINE; + pCurrentRIA->Set($1, * $4); + delete $4; + } +; + +/*---------------------------------------------------------------------------*/ +/* A note about RIAStack, SRIStack and pCurrentRIA. */ +/* */ +/* RIA stands for Resource Item Array. */ +/* SRI stands for Struct Array Resource Item. */ +/* */ +/* A push to RIAStack is made when dropping inside a STRUCT or STRUCT[] in */ +/* order to set values for the components. When this happens pCurrentRIA is */ +/* set to the RIA for the STRUCT or last item of the STRUCT[]. */ +/* */ +/* pCurrentRIA is set to the result of popping from RIAStack when a closing */ +/* brace is reached. */ +/* */ +/* A push is made to SRIStack when going into an item for a STRUCT[]. On */ +/* reaching a closing brace the STRUCT[] is popped off the SRIStack. An new */ +/* item may then be added to this array. */ +/*---------------------------------------------------------------------------*/ +struct_resource_item: + struct_resource_item_start resource_item_list '}' + { if(verbose) { MOFF;cout << "struct_resource_item" << endl;MON;} + pCurrentRIA = pG->RIAStack.Pop(); + } +; +struct_resource_item_start: + L_LABEL '=' L_LABEL '{' { if(verbose) { MOFF;cout << "struct_resource_item_start " << $1 << " " << $3 << endl;MON;} + REGISTER_LINE; + pCurrentRIA->Set($1, $3); + String * thisLabel = new String($1); + pUsedLabelsArray->Add(thisLabel); + // in here add the label to a temp store + pG->RIAStack.Push(pCurrentRIA); + pCurrentRIA = pCurrentRIA->Find($1)->GetRIA(); + } +; +struct_array_resource_item: + struct_array_resource_item_start struct_array_resource_item_list_top '}' + { if(verbose) { MOFF;cout << "struct_array_resource_item" << endl;MON;} + pG->SRIStack.Pop(); + } +| struct_array_resource_item_start struct_array_resource_item_list_top error + { pG->SRIStack.Pop();} +; +struct_array_resource_item_start: + L_LABEL '=' '{' L_LABEL '{' { if(verbose) { MOFF;cout << "struct_array_resource_item_start " << $1 << " " << $4 << endl;MON;} + ResourceItem * p = pCurrentRIA->Find($1); + pG->SRIStack.Push(p); + REGISTER_LINE; + String * thisLabel = new String($1); + pUsedLabelsArray->Add(thisLabel); + // in here add the label to a temp store + p->Set($4); + pG->RIAStack.Push(pCurrentRIA); + pCurrentRIA = p->GetRIA(); + } +; +struct_array_resource_item_list_top: + struct_array_resource_item_list_top_start +| struct_array_resource_item_list_top_start ',' struct_array_resource_item_list +| struct_array_resource_item_list_top_start ',' error +; +struct_array_resource_item_list_top_start: + resource_item_list '}' { if(verbose) { MOFF;cout << "struct_array_resource_item_list_top " << endl;MON;} + pCurrentRIA = pG->RIAStack.Pop(); + } +; +struct_array_resource_item_list: + struct_array_resource_item_list_item +| struct_array_resource_item_list ',' struct_array_resource_item_list_item +; +struct_array_resource_item_list_item: + struct_array_resource_item_list_item_start resource_item_list '}' + { if(verbose) { MOFF;cout << "struct_array_resource_item_list_item " << endl;MON;} + pCurrentRIA = pG->RIAStack.Pop(); + } +; +struct_array_resource_item_list_item_start: + L_LABEL '{' { if(verbose) { MOFF;cout << "struct_array_resource_item_list_item_start " << $1 << endl;MON;} + ResourceItem * p = pG->SRIStack.Peek(); + REGISTER_LINE; + p->Set($1); + pG->RIAStack.Push(pCurrentRIA); + pCurrentRIA = p->GetRIA(); + } +; + + +/*****************************************************************/ +/* simple_initialiser and simple_initialiser_list */ +/*****************************************************************/ +simple_initialiser: + L_NUM_FLOAT +| L_CHAR_LITERAL + { + // convert literal to unsigned long value of 1st character + SetCharacterLiteral($$, $1); + } +| string_expression +| natural_expression +; +simple_initialiser_list: + simple_initialiser + { + if(verbose) + { + MOFF;cout << "simple_initialiser_list - single string " << $1 << endl;MON; + } + + $$ = new StringArray; + $$->Add(new String($1) ); + } +| simple_initialiser_list ',' simple_initialiser + { if(verbose) { MOFF;cout << "simple_initialiser_list - part of list " << $3 << endl;MON;} + assert($1 != NULL); + $1->Add(new String($3 ) ); + $$ = $1; + } +; + +natural_expression: + natural_expression_numeric { String s(NumericValue::ltoa($1) ); strcpy($$, s.GetAssertedNonEmptyBuffer() ); } +; +natural_expression_numeric: + L_NUM_NATURAL { if(verbose) { MOFF;cout << "Converting number " << $1 << endl;MON;} + REGISTER_LINE; + NumericValue v($1, L_LONG); $$ = (long)v.GetULong(); + } +| natural_expression_numeric '+' natural_expression_numeric { $$ = $1 + $3; } +| natural_expression_numeric '-' natural_expression_numeric { $$ = $1 - $3; } +| natural_expression_numeric '*' natural_expression_numeric { $$ = $1 * $3; } +| natural_expression_numeric '/' natural_expression_numeric { $$ = $1 / $3; } +| natural_expression_numeric '|' natural_expression_numeric { $$ = $1 | $3; } +| '-' natural_expression_numeric %prec UMINUS { if (!NumericValue::CheckSigned($2,L_LONG)) + { + REGISTER_LINE; + ErrorHandler::OutputErrorLine("Signed value too low"); + exit(1); + } + $$ = - $2; + } +| '(' natural_expression_numeric ')' { $$ = $2; } +; +string_expression: + string_expression_item +| string_expression_item string_expression { + if (strlen($$)+strlen($2) > sizeof($$)-1) + { + REGISTER_LINE; + ErrorHandler::OutputErrorLine("String expression is too long"); + exit(1); + } + strcat($$, $2); + } +; +string_expression_item: + L_STRING_LITERAL +| character_code_expression +| L_LABEL + { + const char * fileName = (*ErrorHandler::GetFileName()).GetBuffer(); + int lineNumber = ErrorHandler::GetLineNumber(); + QualifiedString * thisLabel = new QualifiedString($1, new String(fileName), lineNumber); + // store the label in the UsedIdentifiers array for checking + // whether label was declared + pG->UsedIdentifiers.Add(thisLabel); + + if (pG->EnumValues.IsStored($1)) + { + sprintf($$, "%d", (int)(pG->EnumValues.FindId($1))); + } + else if (pG->RlsNameIndex.count($1)) // if rls item has already been defined + { + // Found a reference to an rls_string. + RlsValue &rv = pG->RlsValues[pG->RlsNameIndex[$1]]; + ++rv.iCitationCount; // iCitationCount counts the number of times this rls value has been referneced + // Warn for multiple uses if 'multi' keyword not used. + if (1 < rv.iCitationCount && rv.iCardinality == ERlsCardinalitySingle) + { + Message * message = pG->Messages.GetEntry(LT_001); + String fileLine = *(rv.iFileName); + if(message->GetActivated()) + { + pGL->AddWarningToStore(fileLine, rv.iLineNumber, message->GetMessageOutput()); + } + REGISTER_LINE; + if (!pG->WarningMultiExplained) + { + Message * message = pG->Messages.GetEntry(LT_002); + fileLine = String(*(pFileLineHandler->GetCurrentFile())); + if(message->GetActivated()) + { + pGL->AddWarningToStore(fileLine, pFileLineHandler->GetErrorLine(* pCurrentLineNumber), message->GetMessageOutput()); + pG->WarningMultiExplained = true; + } + } + } + switch (rv.iType) + { + // Strings and numbers are just copied to the next layer up. + case ERlsString: + case ERlsString8: + case ERlsByte: + case ERlsWord: + case ERlsLong: + case ERlsDouble: + strcpy($$, rv.iValue.GetBuffer()); + break; + // Anything else is a character: this is converted to a number. + case ERlsStringChar: + case ERlsByteChar: + case ERlsWordChar: + case ERlsLongChar: + SetCharacterLiteral($$, rv.iValue); + break; + default: + Message * message = pG->Messages.GetEntry(LT_031); + if(message->GetActivated()) + { + ErrorHandler::OutputErrorLine(message->GetMessageOutput()); + exit(1); + } + break; + } + } + else + { + /* + Could be a reference to another resource, perhaps even a forward reference: + the OverwriteLink functions do FindId again when writing out the data. + Sadly this also permits things which are really syntax errors, inadvertently + converting labels into string literals.. + */ + } + } +; +character_code_expression: + '<' natural_expression_numeric '>' + { + REGISTER_LINE; + if($2 < 0 || ($2 > 255 && TargetCharacterSet != String::Unicode)) + { + ErrorHandler::OutputErrorLine("Character code must be a number in the range 0 to 255."); + exit(1); + } + if (TargetCharacterSet != String::Unicode) + { + * $$ = char($2); * ($$ + 1) = '\0'; + } + else + { + if (SourceCharacterSet == String::CP1252) + { + if ( ($2 >= 0x80) && ($2 <= 0x9F ) ) // 80-9F are illegal Unicode values. + { + ErrorHandler::OutputErrorLine("Warning: Deprecated non-unicode value in source stream"); + } + * $$ = char(UnicodeEscape); + asUTF8($$ + 1, $2); + } + else + if (SourceCharacterSet == String::UTF8) + { + asUTF8($$, $2); + } + else + { + // Unsatisfactory, but do people use other character sets? + if ($2 > 255) + { + ErrorHandler::OutputErrorLine("Don't know how to handle character > 255"); + } + * $$ = char($2); * ($$ + 1) = '\0'; + } + } + } +; + + +/*****************************************************************/ +/* name_statement */ +/*****************************************************************/ +name_statement: + L_NAME L_LABEL + { + REGISTER_LINE; + SetIdFromName($2); + } +| L_NAME L_STRING_LITERAL + { + REGISTER_LINE; + SetIdFromName($2); + } +; + + +/*****************************************************************/ +/* uidX_statement */ +/*****************************************************************/ +uidX_statement: + L_UID_TWO natural_expression_numeric + { + REGISTER_LINE; + if ($2 == 0) + { ErrorHandler::OutputErrorLine("UID2 must be non-zero"); exit(1); } + if (Uid2 != 0) + { ErrorHandler::OutputErrorLine("Warning: overwriting previous UID2 value"); } + Uid2=$2; + if(verbose) + { MOFF;cout << "uidX_statement UID2 " << Uid2 << endl;MON;} + } +| L_UID_THREE natural_expression_numeric + { + REGISTER_LINE; + if ($2 == 0) + { ErrorHandler::OutputErrorLine("UID3 must be non-zero"); exit(1); } + if (Uid3 != 0) + { ErrorHandler::OutputErrorLine("Warning: overwriting previous UID3 value"); } + Uid3=$2; + if(verbose) + { MOFF;cout << "uidX_statement UID3 " << Uid3 << endl;MON;} + } +; + + +/*****************************************************************/ +/* character_set_statement */ +/* Defines the SOURCE character set. Note that Unicode is a */ +/* character set id, but we can't read Unicode source */ +/* (because LEX and YACC can't handle it) */ +/*****************************************************************/ + +character_set_statement: + L_CHARACTER_SET L_LABEL { if(verbose) { MOFF;cout << "character_set_statement " << $2 << endl;MON;} + REGISTER_LINE; + SourceCharacterSet = CharacterSetID($2); + if ( SourceCharacterSet == String::UNKNOWN ) + { + String err = "Warning: Unrecognised character set name '"; + err += $2; + err += "'"; + ErrorHandler::OutputErrorLine(err); + } + if ( SourceCharacterSet == String::Unicode ) + { + SourceCharacterSet = String::UNKNOWN; + ErrorHandler::OutputErrorLine("Unicode source is unsupported"); + } + } +; + + + +/*****************************************************************/ +/* offset_statement */ +/*****************************************************************/ +offset_statement: + L_OFFSET natural_expression { if(verbose) { RCTypeArray Types; + MOFF;cout << "offset_statement " << $2 << endl;MON; } + REGISTER_LINE; + CurrentId=((long) NumericValue($2, L_LONG).GetULong() ); + } +; + +/*****************************************************************/ +/* system_statement */ +/*****************************************************************/ +system_statement: + L_SYSTEM { if(verbose) { MOFF;cout << "system_statement" << endl;MON;} + CurrentIdStep=-1; + } +; + +/*****************************************************************/ +/* enum_statement */ +/*****************************************************************/ +enum_statement: + enum_statement_start enum_list '}' +| enum_statement_start enum_list '}' ';' +; +enum_statement_start: + L_ENUM L_LABEL '{' + { + if(verbose) + { MOFF;cout << "enum_statement" << endl;MON;} + CurrentEnumName = $2; + CurrentEnumValue=0; + } +| L_ENUM '{' + { + if(verbose) + { MOFF;cout << "enum_statement" << endl;MON;} + CurrentEnumName = ""; + CurrentEnumValue=0; + } +; + +enum_list_entry: + L_LABEL + { + pG->EnumValues.Add($1, CurrentEnumValue++); + pG->AllIdentifiers.Add(new String($1)); // Add label to store + } +| L_LABEL '=' simple_initialiser + { + CurrentEnumValue = atol($3); + pG->EnumValues.Add($1, CurrentEnumValue); + CurrentEnumValue++; // Increment so that next field has value ($3+1) + pG->AllIdentifiers.Add(new String($1)); // Add label to store + } +; + + +enum_list: + maybe_comment_tag enum_list_entry +| enum_list ',' maybe_comment_tag enum_list_entry +; + +/************************/ +/* rls_xxxx statement */ +/************************/ +rls_item_statement: + rls_string_item rls_qualifiers rls_label string_expression + { + pG->RlsNameIndex[$3] = pG->RlsValues.size(); + pG->RlsValues.push_back(RlsValue(ErrorHandler::GetFileName(), + ErrorHandler::GetLineNumber(), $4, $1, + $2.iCardinality, $2.iMaxLength)); + if($2.iMaxLength + < String($4).ExportLength(TargetCharacterSet,SourceCharacterSet)) + { + Message * message = pG->Messages.GetEntry(LT_032); + if(message->GetActivated()) + { + ErrorHandler::OutputErrorLine(message->GetMessageOutput()); + exit(1); + } + } + } +| rls_string_item rls_qualifiers rls_label L_CHAR_LITERAL /* This section is only for compatibility */ + { + Message * message = pG->Messages.GetEntry(LT_033); + String fileName = *(pFileLineHandler->GetCurrentFile()); + int lineNumber = pFileLineHandler->GetErrorLine(* pCurrentLineNumber); + if(message->GetActivated()) + { + pGL->AddWarningToStore(fileName, lineNumber, message->GetMessageOutput()); + } + //... + /* Produce a warning "rls_string used for character constant: use rls_long, rls_word or rls_byte" */ + pG->RlsNameIndex[$3] = pG->RlsValues.size(); + pG->RlsValues.push_back(RlsValue(ErrorHandler::GetFileName(), + ErrorHandler::GetLineNumber(), $4, ERlsStringChar, + $2.iCardinality)); + } +| rls_float_item rls_cardinality rls_label L_NUM_FLOAT + { + pG->RlsNameIndex[$3] = pG->RlsValues.size(); + pG->RlsValues.push_back(RlsValue(ErrorHandler::GetFileName(), + ErrorHandler::GetLineNumber(), $4, $1, + $2.iCardinality)); + } +| rls_num_item rls_cardinality rls_label L_NUM_NATURAL + { + pG->RlsNameIndex[$3] = pG->RlsValues.size(); + pG->RlsValues.push_back(RlsValue(ErrorHandler::GetFileName(), + ErrorHandler::GetLineNumber(), $4, $1, + $2.iCardinality)); + } +| rls_num_item rls_cardinality rls_label L_CHAR_LITERAL + { + TRlsType rlsCharType = $1 == ERlsByte? ERlsByteChar + : ( $1 == ERlsWord? ERlsWordChar : ERlsLongChar ); + pG->RlsNameIndex[$3] = pG->RlsValues.size(); + pG->RlsValues.push_back(RlsValue(ErrorHandler::GetFileName(), + ErrorHandler::GetLineNumber(), $4, rlsCharType, + $2.iCardinality)); + } +; + +rls_label: L_LABEL + { + // Register line even if no warning here so that + // the rls_ item knows which line the label was on. + // Without this, the line registered would be the + // line following the declaration. + REGISTER_LINE; + strcpy($$, $1); + + if (pG->RlsNameIndex.count($1) != 0) + { + Message * message = pG->Messages.GetEntry(LT_003); + if(message->GetActivated()) + { + ErrorHandler::OutputErrorLine(message->GetMessageOutput()); + } + } + pG->AllIdentifiers.Add(new String($1)); // Add label to store + } + +rls_qualifiers: + '<' L_NUM_NATURAL '>' rls_cardinality + { + NumericValue v($2, L_LONG); + $$.iMaxLength = v.GetULong(); + $$.iCardinality = $4.iCardinality; + } +| rls_cardinality + { $$ = $1; } +; + +rls_cardinality: + L_MULTI + { + $$.iMaxLength = 0xFFFFFFF; + $$.iCardinality = ERlsCardinalityMultiple; + } +| + { + $$.iMaxLength = 0xFFFFFFF; + $$.iCardinality = ERlsCardinalitySingle; + } +; + +rls_string_item: + L_RLS_STRING + { $$ = ERlsString; } +| L_RLS_STRING8 + { $$ = ERlsString8; } +; + +rls_num_item: + L_RLS_BYTE + { $$ = ERlsByte; } +| L_RLS_WORD + { $$ = ERlsWord; } +| L_RLS_LONG + { $$ = ERlsLong; } +; + +rls_float_item: + L_RLS_DOUBLE + { $$ = ERlsDouble; } +; + +/************************/ +/* comment tags */ +/************************/ +maybe_comment_tag: + comment_tag +| +; + +comment_tag: + L_TAG_START tag_line L_TAG_END {ErrorHandler::Register(pFileLineHandler->GetCurrentFile(), pFileLineHandler->GetErrorLine(*pCurrentLineNumber)); } + ; + +tag_line: + tag_line tag_word + +| +; + +tag_word: + L_TAG_NEW_LINE { pGL->StoreComment($1); } +| L_TAG_COMMAND { pGL->StoreComment($1); } +| L_TAG_WORD { pGL->StoreComment($1); } +; + +%% + +// Function section +// ================ + +void asUTF8(char* aUtf8, int aUnicode) + { + if ( aUnicode > 0xffff ) + { + if ( aUnicode > 0x10ffff ) + { + ErrorHandler::OutputErrorLine("Surrogate character code must be a number in the range 0x10000 to 0x10ffff"); + exit(1); + } + + UTF16 high = (UTF16)(0xD7C0 + (aUnicode >> 10)); // high surrogate + UTF16 low = (UTF16)(0xDC00 | (aUnicode & 0x3FF)); // low surrogate + + *aUtf8++ =(char)(0xe0|(high>>12)); + *aUtf8++ =(char)(0x80|((high>>6)&0x3f)); + *aUtf8++ =(char)(0x80|(high&0x3f)); + *aUtf8++ =(char)(0xe0|(low>>12)); + *aUtf8++ =(char)(0x80|((low>>6)&0x3f)); + *aUtf8 =(char)(0x80|(low&0x3f)); + } + else if ((aUnicode & 0xff80) == 0x0000) + { + *aUtf8 = (char)aUnicode; + } + else if ((aUnicode & 0xf800) == 0x0000) + { + *aUtf8++ =(char)(0xc0|(aUnicode>>6)); + *aUtf8 =(char)(0x80|(aUnicode&0x3f)); + } + else + { + *aUtf8++ =(char)(0xe0|(aUnicode>>12)); + *aUtf8++ =(char)(0x80|((aUnicode>>6)&0x3f)); + *aUtf8 =(char)(0x80|(aUnicode&0x3f)); + } + *++aUtf8 = '\0'; + } + + +String::CharacterSet CharacterSetID( const String & character_set_name ) +// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// Return a character set ID from a character set name. The value UNKNOWN +// is returned if the name is not recognised. +// ---------------------------------------------------------------------------- +{ + String::CharacterSet ids[] = { String::ISOLatin1, String::ASCII, String::CP1252 + , String::CP850, String::ShiftJIS, String::Unicode + , String::UTF8 + , String::UNKNOWN + }; + String names[] = { "ISOLATIN1", "ASCII", "CP1252", "CP850", "SHIFTJIS", "UNICODE", "UTF8" }; + + for ( int i=0; ids[i]!=String::UNKNOWN; i++ ) + { + if ( names[i] == character_set_name ) return ids[i]; + } + + return String::UNKNOWN; + +} // end of CharacterSetID code + +void SetIdFromName( const String & NameStatementValue) + { + // space 0 + // A 1 + // B 2 + // ... + // Z 26 + // + // ABCD corresponds to the number 4321 which becomes ( (4*27 + 3) * 27 + 2) * 27 + 1. + + if(verbose) + { MOFF;cout << "name_statement " << NameStatementValue << endl;MON;} + if ( NameStatementValue.Length() > 4) + { + ErrorHandler::OutputErrorLine( "Name must be no longer than four characters"); + exit( 1); + } + + long NewId = 0; + + for( unsigned long i = 0; i < NameStatementValue.Length(); i++) + { + NewId *= 27; + if ( isalpha( NameStatementValue[i]) ) + NewId += toupper( NameStatementValue[i]) - 'A' + 1; + } + + CurrentId = NewId << 12; + FormatIdAsHex = 1; + if(verbose) + { MOFF;cout << "Current id " << CurrentId << endl;MON;} + } + +void RlsUnusedWarnings() + { + TNameIndex::iterator end = pG->RlsNameIndex.end(); + for (TNameIndex::iterator i = pG->RlsNameIndex.begin(); i != end; ++i) + { + int index = i->second; + RlsValue& v = pG->RlsValues[index]; + if (v.iCitationCount == 0) + { + Message * message = pG->Messages.GetEntry(LT_004); + String fileLine = *(v.iFileName); + if(message->GetActivated()) + { + pGL->AddWarningToStore(fileLine, v.iLineNumber, message->GetMessageOutput()); + } + } + } + } + +int ParseSourceFile(FILE* aFile, unsigned short aYYDebug) + { + // Set up various global pointers which refer to the pG structure + pSHA = & (pG->SHA); + pFileLineHandler = & (pG->FileLineHandler); + pResourceNameIds = & (pG->ResourceNameIds); + + pScan = new rcscan(pG->FileLineHandler, aFile); + + yydebug = aYYDebug; + pCurrentLineNumber = &yylineno; + int ReturnValue = yyparse(); + + RlsUnusedWarnings(); + + int bScanErrorFound = pScan->ErrorWasFound(); + + delete pScan; + pScan = NULL; + + if(ReturnValue != 0) + return ReturnValue; + + if(bScanErrorFound) + return 1; + + return 0; // successful parse - parse tree now in the pG data structure + } + + +void CheckStructUsage() + { + ResourceItemArrayIterator nextRI( *pCurrentRIA); + ResourceItem * pRI; + while ( ( pRI = nextRI() ) != NULL) + { + int resourceItemType = pRI->GetResourceItemType(); + String resourceItemLabel = pRI->GetLabel(); + if( (resourceItemType == EStructTypeResourceItem) || (resourceItemType == EStructArrayResourceItem) ) + { + StringArrayIterator nextLabel( *pUsedLabelsArray); + String * pLabel; + bool flag = false; + while ( ( ( pLabel = nextLabel() ) != NULL ) && (! flag) ) + { + StringLess stringCompare; + if( !stringCompare(resourceItemLabel,*pLabel) && !stringCompare(*pLabel,resourceItemLabel) ) + { + flag = true; + } + } + if(! flag) + { + if(resourceItemType == EStructTypeResourceItem) + { + Message * message = pG->Messages.GetEntry(LT_046); + if(message->GetActivated()) + { + String comment = message->GetMessageOutput(); + comment += "'"; + comment += resourceItemLabel; + comment += "'"; + ErrorHandler::OutputErrorLine(comment); + } + } + else + { + Message * message = pG->Messages.GetEntry(LT_047); + if(message->GetActivated()) + { + String comment = message->GetMessageOutput(); + comment += "'"; + comment += resourceItemLabel; + comment += "'"; + ErrorHandler::OutputErrorLine(comment); + } + } + } + } + } + } + +int yywrap() +{ + return 1; +} + +/* Called by yyparse on error */ +#include +void yyerror (const char *s, ...) +{ + va_list list; + va_start(list, s); + pScan->yyerror(const_cast(s), list); + va_end(list); +} + + diff -r 122d2b873fd1 -r 30b30f9da0b7 bintools/rcomp/src/main.cpp --- a/bintools/rcomp/src/main.cpp Fri Jun 25 20:58:33 2010 +0800 +++ b/bintools/rcomp/src/main.cpp Tue Jun 29 14:52:54 2010 +0800 @@ -1,568 +1,630 @@ -/* -* Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of the License "Eclipse Public License v1.0" -* which accompanies this distribution, and is available -* at the URL "http://www.eclipse.org/legal/epl-v10.html". -* -* Initial Contributors: -* Nokia Corporation - initial contribution. -* -* Contributors: -* -* Description: -* -*/ - - -#include -#include -#include - -#include "unistd.h" - -#if defined( __MSVCDOTNET__) || defined(__TOOLS2__) -#include -using std::cout; -using std::endl; -using std::cerr; -#else //!__MSVCDOTNET__ -#ifndef __LINUX__ -#include -#endif //!__LINUX__ -#endif //__MSVCDOTNET__ - -#include "RESOURCE.H" -#include "DATATYPE.H" -#include "MEM.H" -#include "RCBINSTR.H" -#include "NUMVAL.H" -#include "ERRORHAN.H" -#include "FILEACC.H" -#include "VERSION.H" -#include "CTABLE.H" -#include "main.h" -#include "TOKENS.H" -#include "localise.h" -#include "qualifar.h" -#include "messages.h" - -extern NameIdMap* pResourceNameIds; -extern long CurrentId; - -void WriteHeaderFile(FILE* aRSG, IndexTable& aIndex) - { - IndexTableIterator next(aIndex); - IndexTableItem * p; - while( ( p = next() ) != NULL) - { - ResourceHeader& r=p->Resource(); - if (r.iLabel.Length()>0 && !r.iLocal) - { - r.iLabel.Upper(); - if (r.iFormatAsHex) - fprintf(aRSG, "#define %-41s 0x%x\n", r.iLabel.GetAssertedNonEmptyBuffer(), r.iResourceId); - else - fprintf(aRSG, "#define %-41s %d\n", r.iLabel.GetAssertedNonEmptyBuffer(), r.iResourceId); - } - } - } - -void WriteBitArrayOfResourcesContainingCompressedUnicode(RCBinaryStream& aRSC, const IndexTable& aIndex) - { - IndexTableIterator next(aIndex); - unsigned char bitBuffer = 0; - int numberOfBitsInBuffer = 0; - for (;;) - { - IndexTableItem* const p = next(); - if (p == NULL) - { - if (numberOfBitsInBuffer > 0) - { - aRSC.Write(&bitBuffer, 1); - } - break; - } - if (p->Resource().ContainsCompressedUnicode()) - { - bitBuffer |= (1 << numberOfBitsInBuffer); - } - ++numberOfBitsInBuffer; - if (numberOfBitsInBuffer == 8) - { - aRSC.Write(&bitBuffer, 1); - bitBuffer = 0; - numberOfBitsInBuffer = 0; - } - } - } - -void WriteBinaryResourceData(RCBinaryStream& aRSC, IndexTable& aIndex, int& aSizeOfLargestResourceWhenUncompressed, const char* aDumpDirectory) - { - IndexTableIterator next(aIndex); - IndexTableItem * p; - int resourceIndex=1; - while( ( p = next() ) != NULL) - { - char* dumpFile=NULL; - if (aDumpDirectory!=NULL) - { - dumpFile=new char[strlen(aDumpDirectory)+20]; - strcpy(dumpFile, aDumpDirectory); - char resourceIndexAsString[20]; - sprintf(resourceIndexAsString, "%d", resourceIndex); - strcat(dumpFile, resourceIndexAsString); - } - p->SetOffset(aRSC.GetPosition()); // record start of this resource in the index - p->Resource().StreamOut(aRSC, aSizeOfLargestResourceWhenUncompressed, dumpFile); // write out binary form of resource - delete [] dumpFile; - ++resourceIndex; - } - } - -void WriteResourceFile(RCBinaryStream& aRSC, IndexTable& aIndex, bool aThirdUidIsOffset, const char* aDumpDirectory) - { - char flags=0; - if (aThirdUidIsOffset) - { - flags|=0x01; - } - 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) - const int positionToOverWriteFrom=aRSC.GetPosition(); - NumericValue twoByteSizeOfLargestResourceWhenUncompressed(L_WORD); - aRSC << twoByteSizeOfLargestResourceWhenUncompressed; - 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) - int sizeOfLargestResourceWhenUncompressed=0; - WriteBinaryResourceData(aRSC, aIndex, sizeOfLargestResourceWhenUncompressed, aDumpDirectory); - aIndex.SetIndexOffset(aRSC.GetPosition()); - aRSC << aIndex; - aRSC.SetPosition(positionToOverWriteFrom); - twoByteSizeOfLargestResourceWhenUncompressed=sizeOfLargestResourceWhenUncompressed; - aRSC << twoByteSizeOfLargestResourceWhenUncompressed; - WriteBitArrayOfResourcesContainingCompressedUnicode(aRSC, aIndex); // overwrites the bit array with correct data - - if(verbose) - { - MOFF; cout << aIndex; cout << endl; MON; - } - } - -void CheckLabels() // checks whether the labels that are used in the input have been declared - { - QualifiedStringArrayIterator nextLabel(pG->UsedIdentifiers); - QualifiedString * pLabel; - while ((pLabel = nextLabel() ) != NULL) - { - bool found = false; // gets set to true if the label in question is declared - StringArrayIterator nextDeclared(pG->AllIdentifiers); - String * pDeclared; - while ( ( (pDeclared = nextDeclared() ) != NULL) && ( ! found )) - { - StringLess stringCompare; - if( !stringCompare(*pDeclared,(*pLabel).GetEntry()) && !stringCompare((*pLabel).GetEntry(),*pDeclared) ) - { // this comparison returns true if the label is the same as the declared label - found = true; - } - } - if( ! found ) // if label hasn't been declared emit warning - { - Message * message = pG->Messages.GetEntry(LT_045); - String fileName = (*pLabel).GetFileName(); - int lineNumber = (*pLabel).GetLineNumber(); - if(message->GetActivated()) - { - String comment = message->GetMessageOutput(); - comment += (*pLabel).GetEntry(); - ErrorHandler::OutputWholeLine(fileName, lineNumber, comment); - } - } - } - } - - -/* Tokenize expects a string in the following format: - * \d{3}(,\d{3})* - * i.e. comma-separated three digit numbers. - * The string should contain no whitespace. - */ -void Tokenize(String aString) - { - int length = aString.Length(); - - for(int end=3; end<=length; end+=4) - { - String messageNumber = aString.ExtractSubString(end-3,end-1); - if(messageNumber.IsDecNatural()) - { - Message * message = pG->Messages.GetTextEntry(messageNumber); - if(message != NULL) - { - message->SetActivationStatus(false); - } - } - } - } - - -void OutputHelp() - { - cerr << "Resource compiler version " << version << " (Build " << build << ") (C) 1997-2009 Nokia Corporation." << endl; - cerr << "Usage: rcomp [-vpul] [-force] [-oRSCFile] [-{uid2,uid3}] [-hHeaderFile] [-sSourceFile] [-iBaseInputFileName]" << endl; - cerr << "\tv" << "\tverbose" << endl; - cerr << "\tp" << "\tParser debugging" << endl; - cerr << "\tl" << "\tCheck localisation comments" << endl; - cerr << "\tforce" << "\tEmit localisation warnings even if no localisation tags are present" << endl; - cerr << "\tadd-defaults" << "\tAmend input rss/rpp file to add missing default localisation options" << endl; - cerr << endl; - cerr << "\tu" << "\tGenerate Unicode resource binary" << endl; - cerr << endl; - cerr << "If no source file is specified, the source will be read from standard input." << endl; - cerr << "(-i is used to specify the file given to the preprocessor this " << endl; - cerr << " name is used in generating debug output.)" << endl; - } - - - -GlobalData *pG; -GlobalLocalisationData *pGL; -String InputBaseName; - -int main(int argc, char * argv[]) - { - cout << "\n"; - int vParam=0; - bool lParam = false; // used as flag to specify whether checking of localisation comment tags should be performed - bool lForce = false; // used as flag to force localisation output even if there are no localisation comments - bool lAddDefaults = false; // used as flag to add missing default localisation data to input rss/rpp file, this is not the default behaviour - logmemorysetting = 0; - unsigned short pParam = 0; - String DataOutputFileName; - String HeaderOutputFileName; - String MessageSuppressionList; - String BasePath; - String SourceFileName; - FILE * pSourceFile; - char* uidsParameter=NULL; - char* dumpDirectory=NULL; - fpos_t filePositionIndicator; - int i; - - char *fullcommand = argv[0]; - std::string s(fullcommand); - - if(argc<=1) - { - OutputHelp(); - exit(-1); - } - else - { - // Look through arguments for ones beginning with '-?'. - for(i = 1; i < argc; i++) - { - if(* argv[i] == '-') - { - char * settings = argv[i] + 1; - - if(strchr(settings, '?') ) - { - OutputHelp(); - exit(-1); - } - } - } - - for(i = 1; i < argc; i++) - { - if(* argv[i] == '-') - { - char * settings = argv[i] + 1; - - if(* settings == 'o' || * settings == 'O') - { - DataOutputFileName = (settings + 1); - continue; - } - - if(* settings == 'm' || * settings == 'M') - { - MessageSuppressionList = (settings + 1); - continue; - } - - if(* settings == 'h' || * settings == 'H') - { - HeaderOutputFileName = (settings + 1); - continue; - } - - if(* settings == 'i' || * settings == 'I') - { - InputBaseName = (settings + 1); - String DriveAndDirectory = FileAccess::GetDriveAndDirectory(InputBaseName); - BasePath = FileAccess::FullPath(DriveAndDirectory); - continue; - } - - if(* settings == 's' || * settings == 'S') - { - SourceFileName = (settings + 1); - continue; - } - - if(* settings == '{') - { - uidsParameter = settings + 1; - char* temp = strchr(uidsParameter, ','); - 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 '{' - { - OutputHelp(); - exit(-1); - } - *temp = ' '; - temp = strchr(uidsParameter, '}'); - if ((temp == NULL) || (temp[1] != '\0')) - { - OutputHelp(); - exit(-1); - } - *temp = ' '; - continue; - } - - if(* settings == ':') - { - dumpDirectory=settings+1; - continue; - } - - if(strchr(settings, 'u') || strchr(settings, 'U') ) - { - SourceCharacterSet = String::CP1252; - TargetCharacterSet = String::Unicode; - } - - if(strchr(settings, 'v') || strchr(settings, 'V') ) - vParam = 1; - if(strchr(settings, 'p') || strchr(settings, 'P') ) - pParam = 1; - if(strchr(settings, 'l') || strchr(settings, 'L') ) - lParam = true; - if(strchr(settings, 'f') || strchr(settings, 'F') ) - lForce = true; - if(strchr(settings, 'a') || strchr(settings, 'A') ) - lAddDefaults = true; - } - } - } - if(SourceFileName.Length() == 0) - { - pSourceFile = stdin; - } - else - { - if((pSourceFile = fopen(SourceFileName.GetAssertedNonEmptyBuffer(), "r") ) == NULL) - { - cerr << "Failed to open " << SourceFileName << endl; - exit(-2); - } - } - //Searchig for BOM signature which if found will be ignored - - unsigned char buffer[3]; - fread( buffer, sizeof( char ), 3, pSourceFile); - - if((buffer[0]!=239) && (buffer[1]!=187) && (buffer[2]!=191)) - { - // BOM not found. Set the file-position indicator to 0 - filePositionIndicator = fpos_t(); - if(fsetpos(pSourceFile, &filePositionIndicator) !=0) - { - perror("fsetpos error"); - } - } - verbose = vParam; - - pG = new GlobalData; - if (pG==NULL) - exit(-4); - - Tokenize(MessageSuppressionList); - - pGL = new GlobalLocalisationData; - if(pG==NULL) - exit(-4); - - pG->WarningMultiExplained = false; - pG->FileLineHandler.SetPath(BasePath); - - #ifdef __TOOLS2__ - pG->FileLineHandler.SetBase(SourceFileName,0); - #endif - - int ret=ParseSourceFile(pSourceFile, pParam); - fclose(pSourceFile); - - pGL->StoreFinalComment(); // final comment not stored during running of lex and yacc - if(lParam && (pGL->LocalisationCommentsExist() || lForce)) - { - pGL->AnalyseLocalisationData(); - pGL->PrintLocalisationWarnings(); - if(lAddDefaults) - { - // only add deafult localisation values to rpp/rss file if the option has been set on the command line - if(verbose) - { - cout << "* Reparsing source file and adding any missing default localisation comments" << endl; - } - pGL->OutputLocalisedFile(SourceFileName); - } - } - if (ret != 0) - { - cerr << "RCOMP failed with code " << ret << endl; - exit(ret); - } - // A successful parse, now generate the output files - - CheckLabels(); // check that all labels are declared and emit suitable warnings if not - - if(DataOutputFileName.Length() != 0) - { - - -#ifdef __LINUX__ - - std::string totalpath(s.substr( 0, s.rfind("/")+1 )); - const char* uidTool = "uidcrc"; - -#else - std::string totalpath(s.substr( 0, s.rfind("\\")+1 )); - const char* uidTool = "uidcrc.exe"; - -#endif - - // Calls the uidcrc tool with the full path to where RCOMP resides in - std::string uidpath(uidTool); - totalpath += uidpath; - - // Find and replace all occurences of \ with / - std::string searchString( "\\" ); - std::string replaceString( "/" ); - std::string::size_type pos = 0; - while ( (pos = totalpath.find("\\", pos)) != std::string::npos ) { - totalpath.replace( pos, searchString.size(), replaceString ); - pos++; - } - - const char *uidcrcTool = totalpath.c_str(); - - bool thirdUidIsOffset=true; - - char uidcrcUIDs[3][100]; - strcpy (uidcrcUIDs[0], "0x101f4a6b"); - - if (uidsParameter) - { - // Command line argument takes precedence - - strcpy (uidcrcUIDs[1], strtok (uidsParameter, " ")); - strcpy (uidcrcUIDs[2], strtok (NULL, " ")); - - char* const temp = strchr(uidcrcUIDs[2], '*'); - if (temp == NULL) - { - thirdUidIsOffset=false; - } - } - else - { - // otherwise use values supplied in source - - extern unsigned long Uid2; - extern unsigned long Uid3; - sprintf(uidcrcUIDs[1], "0x%08lx", Uid2); - if (Uid3 != 0) - { - sprintf(uidcrcUIDs[2], "0x%08lx", Uid3); - thirdUidIsOffset=false; - } - } - - - if (thirdUidIsOffset) - { - 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") - sprintf(uidcrcUIDs[2], "0x%08x", idOfAnyResource >> 12); // use the 20 bits derived from the resource file's NAME as the 3rd UID - } - - if (verbose) - { - MOFF; cout << uidcrcTool << " " << uidcrcUIDs[0] << " " << uidcrcUIDs[1] << " " << uidcrcUIDs[2] << " " << DataOutputFileName.GetAssertedNonEmptyBuffer(); cout << endl; MON; - } - -#ifndef __LINUX__ - const int error = _spawnlp (_P_WAIT, - uidcrcTool, - uidcrcTool, - uidcrcUIDs[0], - uidcrcUIDs[1], - uidcrcUIDs[2], - DataOutputFileName.GetAssertedNonEmptyBuffer(), - NULL); -#else - char uidcrc_params[256]; - const int ret = snprintf(uidcrc_params, - sizeof(uidcrc_params), - "%s %s %s %s %s", - uidcrcTool, - uidcrcUIDs[0], - uidcrcUIDs[1], - uidcrcUIDs[2], - DataOutputFileName.GetBuffer()); - if(ret <= 0) { - cerr << "Failed to write UIDs to " << DataOutputFileName << endl; - exit(ret); - } - const int error = system(uidcrc_params); -#endif //__LINUX__ - - if(error != 0) - { - cerr << "Failed to write UIDs to " << DataOutputFileName << endl; - exit(error); - } - RCBinaryStream RSCStream; - RSCStream.OpenForAppend(DataOutputFileName); - if(! RSCStream.IsOpen()) - { - cerr << "Failed to open " << DataOutputFileName << endl; - exit(-2); - } - WriteResourceFile(RSCStream, pG->Index, thirdUidIsOffset, dumpDirectory); - } - - if(HeaderOutputFileName.Length() != 0) - { - FILE* RSG; - RSG = fopen(HeaderOutputFileName.GetAssertedNonEmptyBuffer(), "w"); - if(RSG==NULL) - { - cerr << "Failed to open " << HeaderOutputFileName << endl; - exit(-2); - } - WriteHeaderFile(RSG, pG->Index); - fclose(RSG); - } - - delete pG; - delete pGL; - - return 0; - } - - - - +/* +* Copyright (c) 2000-2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#include +#include +#include + + +#include "unistd.h" + +#if defined( __MSVCDOTNET__) || defined(__TOOLS2__) +#include +#include +using std::cout; +using std::endl; +using std::cerr; +#else //!__MSVCDOTNET__ +#ifndef __LINUX__ +#include +#endif //!__LINUX__ +#endif //__MSVCDOTNET__ + +#include "RESOURCE.H" +#include "DATATYPE.H" +#include "MEM.H" +#include "RCBINSTR.H" +#include "NUMVAL.H" +#include "ERRORHAN.H" +#include "FILEACC.H" +#include "VERSION.H" +#include "CTABLE.H" +#include "main.h" +#include "TOKENS.H" +#include "localise.h" +#include "qualifar.h" +#include "messages.h" + +extern NameIdMap* pResourceNameIds; +extern long CurrentId; + +void WriteHeaderFile(FILE* aRSG, IndexTable& aIndex) + { + IndexTableIterator next(aIndex); + IndexTableItem * p; + while( ( p = next() ) != NULL) + { + ResourceHeader& r=p->Resource(); + if (r.iLabel.Length()>0 && !r.iLocal) + { + r.iLabel.Upper(); + if (r.iFormatAsHex) + fprintf(aRSG, "#define %-41s 0x%x\n", r.iLabel.GetAssertedNonEmptyBuffer(), r.iResourceId); + else + fprintf(aRSG, "#define %-41s %d\n", r.iLabel.GetAssertedNonEmptyBuffer(), r.iResourceId); + } + } + } + +void WriteBitArrayOfResourcesContainingCompressedUnicode(RCBinaryStream& aRSC, const IndexTable& aIndex) + { + IndexTableIterator next(aIndex); + unsigned char bitBuffer = 0; + int numberOfBitsInBuffer = 0; + for (;;) + { + IndexTableItem* const p = next(); + if (p == NULL) + { + if (numberOfBitsInBuffer > 0) + { + aRSC.Write(&bitBuffer, 1); + } + break; + } + if (p->Resource().ContainsCompressedUnicode()) + { + bitBuffer |= (1 << numberOfBitsInBuffer); + } + ++numberOfBitsInBuffer; + if (numberOfBitsInBuffer == 8) + { + aRSC.Write(&bitBuffer, 1); + bitBuffer = 0; + numberOfBitsInBuffer = 0; + } + } + } + +void WriteBinaryResourceData(RCBinaryStream& aRSC, IndexTable& aIndex, int& aSizeOfLargestResourceWhenUncompressed, const char* aDumpDirectory) + { + IndexTableIterator next(aIndex); + IndexTableItem * p; + int resourceIndex=1; + while( ( p = next() ) != NULL) + { + char* dumpFile=NULL; + if (aDumpDirectory!=NULL) + { + dumpFile=new char[strlen(aDumpDirectory)+20]; + strcpy(dumpFile, aDumpDirectory); + char resourceIndexAsString[20]; + sprintf(resourceIndexAsString, "%d", resourceIndex); + strcat(dumpFile, resourceIndexAsString); + } + p->SetOffset(aRSC.GetPosition()); // record start of this resource in the index + p->Resource().StreamOut(aRSC, aSizeOfLargestResourceWhenUncompressed, dumpFile); // write out binary form of resource + delete [] dumpFile; + ++resourceIndex; + } + } + +void WriteResourceFile(RCBinaryStream& aRSC, IndexTable& aIndex, bool aThirdUidIsOffset, const char* aDumpDirectory) + { + char flags=0; + if (aThirdUidIsOffset) + { + flags|=0x01; + } + 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) + const int positionToOverWriteFrom=aRSC.GetPosition(); + NumericValue twoByteSizeOfLargestResourceWhenUncompressed(L_WORD); + aRSC << twoByteSizeOfLargestResourceWhenUncompressed; + 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) + int sizeOfLargestResourceWhenUncompressed=0; + WriteBinaryResourceData(aRSC, aIndex, sizeOfLargestResourceWhenUncompressed, aDumpDirectory); + aIndex.SetIndexOffset(aRSC.GetPosition()); + aRSC << aIndex; + aRSC.SetPosition(positionToOverWriteFrom); + twoByteSizeOfLargestResourceWhenUncompressed=sizeOfLargestResourceWhenUncompressed; + aRSC << twoByteSizeOfLargestResourceWhenUncompressed; + WriteBitArrayOfResourcesContainingCompressedUnicode(aRSC, aIndex); // overwrites the bit array with correct data + + if(verbose) + { + MOFF; cout << aIndex; cout << endl; MON; + } + } + +void CheckLabels() // checks whether the labels that are used in the input have been declared + { + QualifiedStringArrayIterator nextLabel(pG->UsedIdentifiers); + QualifiedString * pLabel; + while ((pLabel = nextLabel() ) != NULL) + { + bool found = false; // gets set to true if the label in question is declared + StringArrayIterator nextDeclared(pG->AllIdentifiers); + String * pDeclared; + while ( ( (pDeclared = nextDeclared() ) != NULL) && ( ! found )) + { + StringLess stringCompare; + if( !stringCompare(*pDeclared,(*pLabel).GetEntry()) && !stringCompare((*pLabel).GetEntry(),*pDeclared) ) + { // this comparison returns true if the label is the same as the declared label + found = true; + } + } + if( ! found ) // if label hasn't been declared emit warning + { + Message * message = pG->Messages.GetEntry(LT_045); + String fileName = (*pLabel).GetFileName(); + int lineNumber = (*pLabel).GetLineNumber(); + if(message->GetActivated()) + { + String comment = message->GetMessageOutput(); + comment += (*pLabel).GetEntry(); + ErrorHandler::OutputWholeLine(fileName, lineNumber, comment); + } + } + } + } + + +/* Tokenize expects a string in the following format: + * \d{3}(,\d{3})* + * i.e. comma-separated three digit numbers. + * The string should contain no whitespace. + */ +void Tokenize(String aString) + { + int length = aString.Length(); + + for(int end=3; end<=length; end+=4) + { + String messageNumber = aString.ExtractSubString(end-3,end-1); + if(messageNumber.IsDecNatural()) + { + Message * message = pG->Messages.GetTextEntry(messageNumber); + if(message != NULL) + { + message->SetActivationStatus(false); + } + } + } + } + + +void OutputHelp() + { + cerr << "Resource compiler version " << version << " (Build " << build << ") (C) 1997-2010 Nokia Corporation." << endl; + cerr << "Usage: rcomp [-vpul] [-force] [-oRSCFile] [-{uid2,uid3}] [-hHeaderFile] [-sSourceFile] [-iBaseInputFileName]" << endl; + cerr << "\tv" << "\tverbose" << endl; + cerr << "\tp" << "\tParser debugging" << endl; + cerr << "\tl" << "\tCheck localisation comments" << endl; + cerr << "\tforce" << "\tEmit localisation warnings even if no localisation tags are present" << endl; + cerr << "\tadd-defaults" << "\tAmend input rss/rpp file to add missing default localisation options" << endl; + cerr << endl; + cerr << "\tu" << "\tGenerate Unicode resource binary" << endl; + cerr << endl; + cerr << "If no source file is specified, the source will be read from standard input." << endl; + cerr << "(-i is used to specify the file given to the preprocessor this " << endl; + cerr << " name is used in generating debug output.)" << endl; + } + + + +GlobalData *pG; +GlobalLocalisationData *pGL; +String InputBaseName; + +int main(int argc, char * argv[]) + { + cout << "\n"; + int vParam=0; + bool lParam = false; // used as flag to specify whether checking of localisation comment tags should be performed + bool lForce = false; // used as flag to force localisation output even if there are no localisation comments + bool lAddDefaults = false; // used as flag to add missing default localisation data to input rss/rpp file, this is not the default behaviour + logmemorysetting = 0; + unsigned short pParam = 0; + String DataOutputFileName; + String HeaderOutputFileName; + String MessageSuppressionList; + String BasePath; + String SourceFileName; + FILE * pSourceFile; + char* uidsParameter=NULL; + char* dumpDirectory=NULL; + fpos_t filePositionIndicator; + int i; + + char *fullcommand = argv[0]; + std::string s(fullcommand); + + if(argc<=1) + { + OutputHelp(); + exit(-1); + } + else + { + // Look through arguments for ones beginning with '-?'. + for(i = 1; i < argc; i++) + { + if(* argv[i] == '-') + { + char * settings = argv[i] + 1; + + if(strchr(settings, '?') ) + { + OutputHelp(); + exit(-1); + } + } + } + + for(i = 1; i < argc; i++) + { + if(* argv[i] == '-') + { + char * settings = argv[i] + 1; + + if(* settings == 'o' || * settings == 'O') + { + DataOutputFileName = (settings + 1); + continue; + } + + if(* settings == 'm' || * settings == 'M') + { + MessageSuppressionList = (settings + 1); + continue; + } + + if(* settings == 'h' || * settings == 'H') + { + HeaderOutputFileName = (settings + 1); + continue; + } + + if(* settings == 'i' || * settings == 'I') + { + InputBaseName = (settings + 1); + String DriveAndDirectory = FileAccess::GetDriveAndDirectory(InputBaseName); + BasePath = FileAccess::FullPath(DriveAndDirectory); + continue; + } + + if(* settings == 's' || * settings == 'S') + { + SourceFileName = (settings + 1); + continue; + } + + if(* settings == '{') + { + uidsParameter = settings + 1; + char* temp = strchr(uidsParameter, ','); + 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 '{' + { + OutputHelp(); + exit(-1); + } + *temp = ' '; + temp = strchr(uidsParameter, '}'); + if ((temp == NULL) || (temp[1] != '\0')) + { + OutputHelp(); + exit(-1); + } + *temp = ' '; + continue; + } + + if(* settings == ':') + { + dumpDirectory=settings+1; + continue; + } + + if(strchr(settings, 'u') || strchr(settings, 'U') ) + { + SourceCharacterSet = String::CP1252; + TargetCharacterSet = String::Unicode; + } + + if(strchr(settings, 'v') || strchr(settings, 'V') ) + vParam = 1; + if(strchr(settings, 'p') || strchr(settings, 'P') ) + pParam = 1; + if(strchr(settings, 'l') || strchr(settings, 'L') ) + lParam = true; + if(strchr(settings, 'f') || strchr(settings, 'F') ) + lForce = true; + if(strchr(settings, 'a') || strchr(settings, 'A') ) + lAddDefaults = true; + } + } + } + if(SourceFileName.Length() == 0) + { + pSourceFile = NULL ; //stdin; + } + else + { + if((pSourceFile = fopen(SourceFileName.GetAssertedNonEmptyBuffer(), "r") ) == NULL) + { + cerr << "Failed to open " << SourceFileName << endl; + exit(-2); + } + //Searchig for BOM signature which if found will be ignored + unsigned char buffer[3]; + fread( buffer, sizeof( char ), 3, pSourceFile); + if((buffer[0]!=239) && (buffer[1]!=187) && (buffer[2]!=191)) + { + // BOM not found. Set the file-position indicator to 0 + filePositionIndicator = fpos_t(); + if(fsetpos(pSourceFile, &filePositionIndicator) !=0) + { + perror("fsetpos error"); + exit(-2); + } + } + } + + verbose = vParam; + pG = new GlobalData; + if (pG==NULL) + exit(-4); + + if(NULL == pSourceFile){ // Cache the standard input + pG->StdInBufLength = 0; + unsigned long allocSize = 0x100000 ; // 1M bytes + pG->StdInfBufPos = 0 ; + pG->StdInBuffer = (char*)malloc(allocSize); + if(NULL == pG->StdInBuffer){ + delete pG ; + exit(-4); + } + int result = 1; + char* buffer = pG->StdInBuffer; + FILE *file = stdin ; + const int KIOBytes = 0x20000 ; + while(1) { + result = fread(buffer, 1, KIOBytes, file); + if(result == 0){ + *buffer = 0; + break ; + } + buffer += result ; + pG->StdInBufLength += result ; + if((pG->StdInBufLength + KIOBytes) > allocSize) { + allocSize += KIOBytes ; + pG->StdInBuffer = (char*)realloc(pG->StdInBuffer,allocSize); + if(NULL == pG->StdInBuffer){ + delete pG ; + exit(-4); + } + buffer = pG->StdInBuffer + pG->StdInBufLength; + } + + } + const unsigned char BOM[] = {0xef , 0xbb, 0xbf, 0x0 }; + if(0 == memcmp(pG->StdInBuffer,BOM,3)) + pG->StdInfBufPos = 3 ; + } + else { + pG->StdInBuffer = 0 ; + pG->StdInBufLength = 0; + } + + Tokenize(MessageSuppressionList); + + pGL = new GlobalLocalisationData; + if(pG==NULL) + exit(-4); + + pG->WarningMultiExplained = false; + pG->FileLineHandler.SetPath(BasePath); + + #ifdef __TOOLS2__ + pG->FileLineHandler.SetBase(SourceFileName,0); + #endif + + int ret=ParseSourceFile(pSourceFile, pParam); + if(pSourceFile != NULL) + fclose(pSourceFile); + if(pG->StdInBuffer != NULL) + free(pG->StdInBuffer); + + pGL->StoreFinalComment(); // final comment not stored during running of lex and yacc + if(lParam && (pGL->LocalisationCommentsExist() || lForce)) + { + pGL->AnalyseLocalisationData(); + pGL->PrintLocalisationWarnings(); + if(lAddDefaults) + { + // only add deafult localisation values to rpp/rss file if the option has been set on the command line + if(verbose) + { + cout << "* Reparsing source file and adding any missing default localisation comments" << endl; + } + pGL->OutputLocalisedFile(SourceFileName); + } + } + if (ret != 0) + { + cerr << "RCOMP failed with code " << ret << endl; + exit(ret); + } + // A successful parse, now generate the output files + + CheckLabels(); // check that all labels are declared and emit suitable warnings if not + + if(DataOutputFileName.Length() != 0) + { + + +#ifdef __LINUX__ + + std::string totalpath(s.substr( 0, s.rfind("/")+1 )); + const char* uidTool = "uidcrc"; + +#else + + std::string totalpath(s.substr( 0, s.rfind("\\")+1 )); + const char* uidTool = "uidcrc.exe"; + + // in case unix style of seperator is used in windows. + if(!totalpath.length()){ + totalpath = s.substr( 0, s.rfind("/")+1 ); + } + +#endif + + std::string uidpath(uidTool); + + // try to call the uidcrc tool with the full path to where RCOMP resides in + // if does not exists, search uidcrc in PATH + if(totalpath.length()){ + + std::string trypath(totalpath); + trypath += uidpath; + + std::fstream _file; + _file.open(trypath.c_str(), std::ios::in); + if(!_file){ + // try to search from PATH + totalpath = uidpath; + } + else{ + _file.close(); + // invoke from the path RCOMP resides in + totalpath += uidpath; + } + } + else{ + // search from PATH + totalpath = uidpath; + } + + // Find and replace all occurences of \ with / + std::string searchString( "\\" ); + std::string replaceString( "/" ); + std::string::size_type pos = 0; + while ( (pos = totalpath.find("\\", pos)) != std::string::npos ) { + totalpath.replace( pos, searchString.size(), replaceString ); + pos++; + } + + const char *uidcrcTool = totalpath.c_str(); + + bool thirdUidIsOffset=true; + + char uidcrcUIDs[3][100]; + strcpy (uidcrcUIDs[0], "0x101f4a6b"); + + if (uidsParameter) + { + // Command line argument takes precedence + + strcpy (uidcrcUIDs[1], strtok (uidsParameter, " ")); + strcpy (uidcrcUIDs[2], strtok (NULL, " ")); + + char* const temp = strchr(uidcrcUIDs[2], '*'); + if (temp == NULL) + { + thirdUidIsOffset=false; + } + } + else + { + // otherwise use values supplied in source + + extern unsigned long Uid2; + extern unsigned long Uid3; + sprintf(uidcrcUIDs[1], "0x%08lx", Uid2); + if (Uid3 != 0) + { + sprintf(uidcrcUIDs[2], "0x%08lx", Uid3); + thirdUidIsOffset=false; + } + } + + + if (thirdUidIsOffset) + { + 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") + sprintf(uidcrcUIDs[2], "0x%08x", idOfAnyResource >> 12); // use the 20 bits derived from the resource file's NAME as the 3rd UID + } + + if (verbose) + { + MOFF; cout << uidcrcTool << " " << uidcrcUIDs[0] << " " << uidcrcUIDs[1] << " " << uidcrcUIDs[2] << " " << DataOutputFileName.GetAssertedNonEmptyBuffer(); cout << endl; MON; + } + + char uidcrc_params[512]; + const int ret = snprintf(uidcrc_params, + sizeof(uidcrc_params), + "%s %s %s %s %s", + uidcrcTool, + uidcrcUIDs[0], + uidcrcUIDs[1], + uidcrcUIDs[2], + DataOutputFileName.GetBuffer()); + if(ret <= 0) { + cerr << "Failed to write UIDs to " << DataOutputFileName << endl; + exit(ret); + } + const int error = system(uidcrc_params); + + if(error != 0) + { + cerr << "Failed to write UIDs to " << DataOutputFileName << endl; + exit(error); + } + RCBinaryStream RSCStream; + RSCStream.OpenForAppend(DataOutputFileName); + if(! RSCStream.IsOpen()) + { + cerr << "Failed to open " << DataOutputFileName << endl; + exit(-2); + } + WriteResourceFile(RSCStream, pG->Index, thirdUidIsOffset, dumpDirectory); + } + + if(HeaderOutputFileName.Length() != 0) + { + FILE* RSG; + RSG = fopen(HeaderOutputFileName.GetAssertedNonEmptyBuffer(), "w"); + if(RSG==NULL) + { + cerr << "Failed to open " << HeaderOutputFileName << endl; + exit(-2); + } + WriteHeaderFile(RSG, pG->Index); + fclose(RSG); + } + + delete pG; + delete pGL; + + return 0; + } + + + + diff -r 122d2b873fd1 -r 30b30f9da0b7 bintools/rcomp/src/rcomp.cpp --- a/bintools/rcomp/src/rcomp.cpp Fri Jun 25 20:58:33 2010 +0800 +++ b/bintools/rcomp/src/rcomp.cpp Tue Jun 29 14:52:54 2010 +0800 @@ -1,3449 +1,3449 @@ -/* A Bison parser, made by GNU Bison 2.4.1. */ - -/* Skeleton implementation for Bison's Yacc-like parsers in C - - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 - Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -/* C LALR(1) parser skeleton written by Richard Stallman, by - simplifying the original so-called "semantic" parser. */ - -/* All symbols defined below should begin with yy or YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -/* Identify Bison output. */ -#define YYBISON 1 - -/* Bison version. */ -#define YYBISON_VERSION "2.4.1" - -/* Skeleton name. */ -#define YYSKELETON_NAME "yacc.c" - -/* Pure parsers. */ -#define YYPURE 0 - -/* Push parsers. */ -#define YYPUSH 0 - -/* Pull parsers. */ -#define YYPULL 1 - -/* Using locations. */ -#define YYLSP_NEEDED 0 - - - -/* Copy the first part of user declarations. */ - -/* Line 189 of yacc.c */ -#line 1 "rcomp.yacc" - -#include -#include -#include - -#if defined(__MSVCDOTNET__) || defined(__TOOLS2__) -#include -#include -using namespace std; -using std::cout; -using std::endl; -#else //!__MSVCDOTNET__ -#include -#endif //__MSVCDOTNET__ - -#ifdef __VC32__ -#pragma warning( disable : 4065 ) // C4065: switch statement contains 'default' but no 'case' labels -#pragma warning( disable : 4102 ) // C4102: 'yyerrlab1' : unreferenced label -#pragma warning( disable : 4127 ) // C4127: conditional expression is constant -#pragma warning( disable : 4244 ) // C4244: '=' : conversion from 'int' to 'short', possible loss of data -#endif //__VC32__ - -#include "resource.h" -#include "parser.h" - -int yylex(); -void yyerror(const char* string, ...); -int yywrap(); -#define YYDEBUG 1 -extern int yylineno; - -#include "rcomp.hpp" -#include "datatype.h" -#include "mem.h" -#include "rcbinstr.h" -#include "rcscan.h" -#include "errorhan.h" -#include "fileacc.h" -#include "version.h" -#include "ctable.h" -#include "localise.h" -#include "main.h" - -#if defined(__VC32__) && !defined(_DEBUG) -#pragma warning( disable : 4702 ) // unreachable code -#pragma warning( disable : 4102 ) // 'yyerrlabel' : unreferenced label -#pragma warning( disable : 4244 ) // '=' : conversion from 'int' to 'short', possible loss of data -#endif - - - -String::CharacterSet CharacterSetID( const String & character_set_name ); -void asUTF8(char* aUtf8, int aUnicode); -void SetIdFromName( const String & NameStatementValue); -void CheckStructUsage(); - -unsigned short & d = MemCheckControl::iLogMemory; - -StructHeader * pSH; - -StructHeaderArray * pSHA; // Used in resource struct handling functions. -ResourceHeader * pResourceHeader; -ResourceItemArray * pCurrentRIA; -StringArray * pUsedLabelsArray = new StringArray(); -int verbose; -String::CharacterSet SourceCharacterSet = String::CP1252; -String::CharacterSet TargetCharacterSet = String::CP1252; -unsigned short logmemorysetting; -int * pCurrentLineNumber; -FileLineManager * pFileLineHandler; -NameIdMap * pResourceNameIds; -long CurrentEnumValue; -String CurrentEnumName; -char TempStr[300]; -rcscan * pScan; - -int CurrentIdStep=1; -long CurrentId=0; -int FormatIdAsHex=0; // defaults to decimal, changes in SetIdFromName - -unsigned long Uid2=0; -unsigned long Uid3=0; - - - -const String Divider("*******************************************"); - -#define REGISTER_LINE ErrorHandler::Register(pFileLineHandler->GetCurrentFile(), pFileLineHandler->GetErrorLine(* pCurrentLineNumber)) - -// Convert a string containing a character literal in aQuoted -// into a value suitable for LCHAR_LITERAL -void SetCharacterLiteral(char* aOut, const String& aQuoted) - { - UTF16 first; - int length=1; - if (aQuoted.Length() < 1 ) - { - REGISTER_LINE; - ErrorHandler::OutputErrorLine("Warning: Empty Character literal"); - } - if (aQuoted.Length() > 1 ) - { - REGISTER_LINE; - ErrorHandler::OutputErrorLine("Error: String Literal length greater than 1"); - exit(1); - } - if (aQuoted.Export(&first, length, SourceCharacterSet)==0) - { - REGISTER_LINE; - ErrorHandler::OutputErrorLine("Warning: Ignoring trailing characters in character literal"); - } - sprintf(aOut, "%d", first); - } - - - -/* Line 189 of yacc.c */ -#line 205 "rcomp.tab.cacc" - -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif - -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE 0 -#endif - -/* Enabling the token table. */ -#ifndef YYTOKEN_TABLE -# define YYTOKEN_TABLE 0 -#endif - - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - L_STRUCT = 258, - L_RESOURCE = 259, - L_NAME = 260, - L_OFFSET = 261, - L_SYSTEM = 262, - L_GLOBAL = 263, - L_LOCAL = 264, - L_CHARACTER_SET = 265, - L_BUF = 266, - L_WORD = 267, - L_BYTE = 268, - L_LONG = 269, - L_DOUBLE = 270, - L_TEXT = 271, - L_LTEXT = 272, - L_LINK = 273, - L_LLINK = 274, - L_SRLINK = 275, - L_BUF8 = 276, - L_TEXT8 = 277, - L_LTEXT8 = 278, - L_BUF16 = 279, - L_TEXT16 = 280, - L_LTEXT16 = 281, - L_UID_TWO = 282, - L_UID_THREE = 283, - L_RLS_STRING = 284, - L_RLS_STRING8 = 285, - L_RLS_DOUBLE = 286, - L_RLS_BYTE = 287, - L_RLS_WORD = 288, - L_RLS_LONG = 289, - L_MULTI = 290, - L_TAG_START = 291, - L_TAG_END = 292, - L_TAG_COMMAND = 293, - L_TAG_WORD = 294, - L_TAG_NEW_LINE = 295, - L_LABEL = 296, - L_NUM_NATURAL = 297, - L_NUM_FLOAT = 298, - L_NATURAL_EXPR = 299, - L_ENUM = 300, - L_LEN = 301, - L_CHAR_LITERAL = 302, - L_STRING_LITERAL = 303, - UMINUS = 304 - }; -#endif - - - -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE -{ - -/* Line 214 of yacc.c */ -#line 132 "rcomp.yacc" - - char Value[1024*8]; - TValueMaybeRls ValueMaybeRls; - unsigned long Id; - StructItem * pStructItem; - SimpleStructItem * pSimpleStructItem; - ArrayStructItem * pArrayStructItem; - StructArrayStructItem * pStructArrayStructItem; - StringArray * pStringArray; - long NumInitialiser; - TRlsQualifiers RlsQualifiers; - TRlsType RlsType; - - - -/* Line 214 of yacc.c */ -#line 306 "rcomp.tab.cacc" -} YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -#endif - - -/* Copy the second part of user declarations. */ - - -/* Line 264 of yacc.c */ -#line 318 "rcomp.tab.cacc" - -#ifdef short -# undef short -#endif - -#ifdef YYTYPE_UINT8 -typedef YYTYPE_UINT8 yytype_uint8; -#else -typedef unsigned char yytype_uint8; -#endif - -#ifdef YYTYPE_INT8 -typedef YYTYPE_INT8 yytype_int8; -#elif (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -typedef signed char yytype_int8; -#else -typedef short int yytype_int8; -#endif - -#ifdef YYTYPE_UINT16 -typedef YYTYPE_UINT16 yytype_uint16; -#else -typedef unsigned short int yytype_uint16; -#endif - -#ifdef YYTYPE_INT16 -typedef YYTYPE_INT16 yytype_int16; -#else -typedef short int yytype_int16; -#endif - -#ifndef YYSIZE_T -# ifdef __SIZE_TYPE__ -# define YYSIZE_T __SIZE_TYPE__ -# elif defined size_t -# define YYSIZE_T size_t -# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# else -# define YYSIZE_T unsigned int -# endif -#endif - -#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) - -#ifndef YY_ -# if YYENABLE_NLS -# if ENABLE_NLS -# include /* INFRINGES ON USER NAME SPACE */ -# define YY_(msgid) dgettext ("bison-runtime", msgid) -# endif -# endif -# ifndef YY_ -# define YY_(msgid) msgid -# endif -#endif - -/* Suppress unused-variable warnings by "using" E. */ -#if ! defined lint || defined __GNUC__ -# define YYUSE(e) ((void) (e)) -#else -# define YYUSE(e) /* empty */ -#endif - -/* Identity function, used to suppress warnings about constant conditions. */ -#ifndef lint -# define YYID(n) (n) -#else -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static int -YYID (int yyi) -#else -static int -YYID (yyi) - int yyi; -#endif -{ - return yyi; -} -#endif - -#if ! defined yyoverflow || YYERROR_VERBOSE - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# ifdef YYSTACK_USE_ALLOCA -# if YYSTACK_USE_ALLOCA -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# elif defined __BUILTIN_VA_ARG_INCR -# include /* INFRINGES ON USER NAME SPACE */ -# elif defined _AIX -# define YYSTACK_ALLOC __alloca -# elif defined _MSC_VER -# include /* INFRINGES ON USER NAME SPACE */ -# define alloca _alloca -# else -# define YYSTACK_ALLOC alloca -# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include /* INFRINGES ON USER NAME SPACE */ -# ifndef _STDLIB_H -# define _STDLIB_H 1 -# endif -# endif -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) -# ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely - invoke alloca (N) if N exceeds 4096. Use a slightly smaller number - to allow for a few compiler-allocated temporary stack slots. */ -# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ -# endif -# else -# define YYSTACK_ALLOC YYMALLOC -# define YYSTACK_FREE YYFREE -# ifndef YYSTACK_ALLOC_MAXIMUM -# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM -# endif -# if (defined __cplusplus && ! defined _STDLIB_H \ - && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) -# include /* INFRINGES ON USER NAME SPACE */ -# ifndef _STDLIB_H -# define _STDLIB_H 1 -# endif -# endif -# ifndef YYMALLOC -# define YYMALLOC malloc -# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# ifndef YYFREE -# define YYFREE free -# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -void free (void *); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# endif -#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ - - -#if (! defined yyoverflow \ - && (! defined __cplusplus \ - || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - yytype_int16 yyss_alloc; - YYSTYPE yyvs_alloc; -}; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# define YYSTACK_BYTES(N) \ - ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ - + YYSTACK_GAP_MAXIMUM) - -/* Copy COUNT objects from FROM to TO. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if defined __GNUC__ && 1 < __GNUC__ -# define YYCOPY(To, From, Count) \ - __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -# else -# define YYCOPY(To, From, Count) \ - do \ - { \ - YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (To)[yyi] = (From)[yyi]; \ - } \ - while (YYID (0)) -# endif -# endif - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ - Stack = &yyptr->Stack_alloc; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (YYID (0)) - -#endif - -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL 3 -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 303 - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 66 -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 61 -/* YYNRULES -- Number of rules. */ -#define YYNRULES 152 -/* YYNRULES -- Number of states. */ -#define YYNSTATES 255 - -/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -#define YYUNDEFTOK 2 -#define YYMAXUTOK 304 - -#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) - -/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -static const yytype_uint8 yytranslate[] = -{ - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 58, 59, 51, 49, 65, 50, 2, 52, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 55, - 61, 60, 62, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 64, 2, 63, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 57, 53, 56, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 54 -}; - -#if YYDEBUG -/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in - YYRHS. */ -static const yytype_uint16 yyprhs[] = -{ - 0, 0, 3, 5, 8, 11, 12, 15, 18, 21, - 24, 27, 30, 32, 35, 38, 40, 41, 45, 50, - 56, 62, 66, 71, 72, 74, 76, 78, 80, 82, - 87, 91, 98, 101, 107, 109, 111, 113, 115, 117, - 119, 121, 123, 125, 127, 129, 131, 133, 135, 137, - 139, 141, 147, 150, 154, 159, 165, 169, 171, 173, - 176, 178, 182, 187, 193, 198, 201, 204, 206, 210, - 213, 217, 222, 226, 227, 231, 233, 235, 237, 242, - 248, 252, 257, 261, 265, 271, 273, 277, 281, 284, - 286, 290, 294, 297, 299, 301, 303, 305, 307, 311, - 313, 315, 319, 323, 327, 331, 335, 338, 342, 344, - 347, 349, 351, 353, 357, 360, 363, 366, 369, 372, - 375, 377, 381, 386, 390, 393, 395, 399, 402, 407, - 412, 417, 422, 427, 432, 434, 439, 441, 443, 444, - 446, 448, 450, 452, 454, 456, 458, 459, 463, 466, - 467, 469, 471 -}; - -/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -static const yytype_int8 yyrhs[] = -{ - 67, 0, -1, 68, -1, 68, 69, -1, 68, 124, - -1, -1, 71, 70, -1, 85, 70, -1, 109, 70, - -1, 107, 70, -1, 110, 70, -1, 111, 70, -1, - 112, -1, 108, 70, -1, 116, 70, -1, 55, -1, - -1, 72, 73, 56, -1, 3, 41, 123, 57, -1, - 3, 41, 81, 123, 57, -1, 3, 41, 46, 123, - 57, -1, 73, 74, 55, -1, 73, 124, 74, 55, - -1, -1, 75, -1, 78, -1, 82, -1, 83, -1, - 76, -1, 76, 58, 102, 59, -1, 76, 60, 100, - -1, 76, 58, 102, 59, 60, 104, -1, 77, 41, - -1, 77, 61, 103, 62, 41, -1, 13, -1, 12, - -1, 14, -1, 15, -1, 16, -1, 17, -1, 11, - -1, 22, -1, 25, -1, 23, -1, 26, -1, 21, - -1, 24, -1, 18, -1, 19, -1, 20, -1, 79, - -1, 79, 60, 57, 101, 56, -1, 80, 63, -1, - 80, 102, 63, -1, 46, 81, 80, 63, -1, 46, - 81, 80, 102, 63, -1, 77, 41, 64, -1, 13, - -1, 12, -1, 3, 41, -1, 84, -1, 46, 81, - 84, -1, 3, 41, 64, 63, -1, 3, 41, 64, - 102, 63, -1, 86, 57, 88, 56, -1, 8, 87, - -1, 9, 87, -1, 87, -1, 4, 41, 41, -1, - 4, 41, -1, 88, 89, 55, -1, 88, 124, 89, - 55, -1, 88, 1, 55, -1, -1, 41, 60, 100, - -1, 90, -1, 91, -1, 93, -1, 41, 60, 57, - 56, -1, 41, 60, 57, 101, 56, -1, 92, 88, - 56, -1, 41, 60, 41, 57, -1, 94, 95, 56, - -1, 94, 95, 1, -1, 41, 60, 57, 41, 57, - -1, 96, -1, 96, 65, 97, -1, 96, 65, 1, - -1, 88, 56, -1, 98, -1, 97, 65, 98, -1, - 99, 88, 56, -1, 41, 57, -1, 43, -1, 47, - -1, 104, -1, 102, -1, 100, -1, 101, 65, 100, - -1, 103, -1, 42, -1, 103, 49, 103, -1, 103, - 50, 103, -1, 103, 51, 103, -1, 103, 52, 103, - -1, 103, 53, 103, -1, 50, 103, -1, 58, 103, - 59, -1, 105, -1, 105, 104, -1, 48, -1, 106, - -1, 41, -1, 61, 103, 62, -1, 5, 41, -1, - 5, 48, -1, 27, 103, -1, 28, 103, -1, 10, - 41, -1, 6, 102, -1, 7, -1, 113, 115, 56, - -1, 113, 115, 56, 55, -1, 45, 41, 57, -1, - 45, 57, -1, 41, -1, 41, 60, 100, -1, 123, - 114, -1, 115, 65, 123, 114, -1, 120, 118, 117, - 104, -1, 120, 118, 117, 47, -1, 122, 119, 117, - 43, -1, 121, 119, 117, 42, -1, 121, 119, 117, - 47, -1, 41, -1, 61, 42, 62, 119, -1, 119, - -1, 35, -1, -1, 29, -1, 30, -1, 32, -1, - 33, -1, 34, -1, 31, -1, 124, -1, -1, 36, - 125, 37, -1, 125, 126, -1, -1, 40, -1, 38, - -1, 39, -1 -}; - -/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -static const yytype_uint16 yyrline[] = -{ - 0, 182, 182, 189, 190, 191, 195, 196, 197, 198, - 199, 200, 201, 202, 203, 207, 214, 221, 225, 231, - 237, 245, 249, 253, 256, 257, 258, 259, 262, 263, - 268, 273, 289, 297, 312, 313, 314, 315, 319, 325, - 329, 336, 340, 344, 345, 346, 347, 348, 349, 350, - 353, 354, 372, 375, 380, 388, 399, 407, 408, 411, - 416, 417, 423, 426, 435, 451, 452, 458, 461, 474, - 483, 484, 485, 486, 489, 493, 494, 495, 498, 503, - 531, 537, 548, 552, 556, 569, 570, 571, 574, 579, - 580, 583, 589, 603, 604, 609, 610, 613, 623, 632, - 635, 639, 640, 641, 642, 643, 644, 652, 655, 656, - 667, 668, 669, 748, 794, 799, 811, 822, 844, 868, - 879, 888, 889, 892, 899, 909, 914, 925, 926, 933, - 950, 966, 973, 980, 991, 1012, 1018, 1023, 1029, 1036, - 1038, 1043, 1045, 1047, 1052, 1060, 1061, 1065, 1069, 1071, - 1075, 1076, 1077 -}; -#endif - -#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE -/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -static const char *const yytname[] = -{ - "$end", "error", "$undefined", "L_STRUCT", "L_RESOURCE", "L_NAME", - "L_OFFSET", "L_SYSTEM", "L_GLOBAL", "L_LOCAL", "L_CHARACTER_SET", - "L_BUF", "L_WORD", "L_BYTE", "L_LONG", "L_DOUBLE", "L_TEXT", "L_LTEXT", - "L_LINK", "L_LLINK", "L_SRLINK", "L_BUF8", "L_TEXT8", "L_LTEXT8", - "L_BUF16", "L_TEXT16", "L_LTEXT16", "L_UID_TWO", "L_UID_THREE", - "L_RLS_STRING", "L_RLS_STRING8", "L_RLS_DOUBLE", "L_RLS_BYTE", - "L_RLS_WORD", "L_RLS_LONG", "L_MULTI", "L_TAG_START", "L_TAG_END", - "L_TAG_COMMAND", "L_TAG_WORD", "L_TAG_NEW_LINE", "L_LABEL", - "L_NUM_NATURAL", "L_NUM_FLOAT", "L_NATURAL_EXPR", "L_ENUM", "L_LEN", - "L_CHAR_LITERAL", "L_STRING_LITERAL", "'+'", "'-'", "'*'", "'/'", "'|'", - "UMINUS", "';'", "'}'", "'{'", "'('", "')'", "'='", "'<'", "'>'", "']'", - "'['", "','", "$accept", "source", "statement_list", "statement", - "maybe_semicolon", "struct_statement", "struct_statement_start", - "struct_item_list", "struct_item", "simple_struct_item", - "simple_struct_item_start", "data_type", "array_struct_item", - "array_struct_item_base", "array_struct_item_start", "len_declaration", - "struct_type_struct_item", "struct_array_struct_item", - "struct_array_struct_item_base", "resource_statement", - "resource_statement_start", "resource_statement_start_names", - "resource_item_list", "resource_item", "resource_simple_array_item", - "struct_resource_item", "struct_resource_item_start", - "struct_array_resource_item", "struct_array_resource_item_start", - "struct_array_resource_item_list_top", - "struct_array_resource_item_list_top_start", - "struct_array_resource_item_list", - "struct_array_resource_item_list_item", - "struct_array_resource_item_list_item_start", "simple_initialiser", - "simple_initialiser_list", "natural_expression", - "natural_expression_numeric", "string_expression", - "string_expression_item", "character_code_expression", "name_statement", - "uidX_statement", "character_set_statement", "offset_statement", - "system_statement", "enum_statement", "enum_statement_start", - "enum_list_entry", "enum_list", "rls_item_statement", "rls_label", - "rls_qualifiers", "rls_cardinality", "rls_string_item", "rls_num_item", - "rls_float_item", "maybe_comment_tag", "comment_tag", "tag_line", - "tag_word", 0 -}; -#endif - -# ifdef YYPRINT -/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to - token YYLEX-NUM. */ -static const yytype_uint16 yytoknum[] = -{ - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 300, 301, 302, 303, 43, - 45, 42, 47, 124, 304, 59, 125, 123, 40, 41, - 61, 60, 62, 93, 91, 44 -}; -# endif - -/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const yytype_uint8 yyr1[] = -{ - 0, 66, 67, 68, 68, 68, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 70, 70, 71, 72, 72, - 72, 73, 73, 73, 74, 74, 74, 74, 75, 75, - 75, 75, 76, 76, 77, 77, 77, 77, 77, 77, - 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, - 78, 78, 79, 79, 79, 79, 80, 81, 81, 82, - 83, 83, 84, 84, 85, 86, 86, 86, 87, 87, - 88, 88, 88, 88, 89, 89, 89, 89, 90, 90, - 91, 92, 93, 93, 94, 95, 95, 95, 96, 97, - 97, 98, 99, 100, 100, 100, 100, 101, 101, 102, - 103, 103, 103, 103, 103, 103, 103, 103, 104, 104, - 105, 105, 105, 106, 107, 107, 108, 108, 109, 110, - 111, 112, 112, 113, 113, 114, 114, 115, 115, 116, - 116, 116, 116, 116, 117, 118, 118, 119, 119, 120, - 120, 121, 121, 121, 122, 123, 123, 124, 125, 125, - 126, 126, 126 -}; - -/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -static const yytype_uint8 yyr2[] = -{ - 0, 2, 1, 2, 2, 0, 2, 2, 2, 2, - 2, 2, 1, 2, 2, 1, 0, 3, 4, 5, - 5, 3, 4, 0, 1, 1, 1, 1, 1, 4, - 3, 6, 2, 5, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 5, 2, 3, 4, 5, 3, 1, 1, 2, - 1, 3, 4, 5, 4, 2, 2, 1, 3, 2, - 3, 4, 3, 0, 3, 1, 1, 1, 4, 5, - 3, 4, 3, 3, 5, 1, 3, 3, 2, 1, - 3, 3, 2, 1, 1, 1, 1, 1, 3, 1, - 1, 3, 3, 3, 3, 3, 2, 3, 1, 2, - 1, 1, 1, 3, 2, 2, 2, 2, 2, 2, - 1, 3, 4, 3, 2, 1, 3, 2, 4, 4, - 4, 4, 4, 4, 1, 4, 1, 1, 0, 1, - 1, 1, 1, 1, 1, 1, 0, 3, 2, 0, - 1, 1, 1 -}; - -/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state - STATE-NUM when YYTABLE doesn't specify something else to do. Zero - means the default is an error. */ -static const yytype_uint8 yydefact[] = -{ - 5, 0, 2, 1, 0, 0, 0, 0, 120, 0, - 0, 0, 0, 0, 139, 140, 144, 141, 142, 143, - 149, 0, 3, 16, 23, 16, 0, 67, 16, 16, - 16, 16, 16, 12, 146, 16, 138, 138, 138, 4, - 146, 69, 114, 115, 100, 0, 0, 119, 99, 65, - 66, 118, 116, 117, 0, 0, 124, 15, 6, 0, - 7, 73, 9, 13, 8, 10, 11, 0, 0, 145, - 14, 137, 0, 0, 136, 0, 0, 58, 57, 146, - 146, 0, 68, 106, 0, 0, 0, 0, 0, 0, - 147, 151, 152, 150, 148, 123, 0, 40, 35, 34, - 36, 37, 38, 39, 47, 48, 49, 45, 41, 43, - 46, 42, 44, 0, 17, 0, 24, 28, 0, 25, - 50, 0, 26, 27, 60, 0, 0, 121, 146, 125, - 127, 0, 134, 0, 0, 0, 0, 0, 18, 107, - 101, 102, 103, 104, 105, 59, 0, 21, 0, 0, - 32, 0, 0, 52, 0, 0, 0, 0, 64, 0, - 75, 76, 73, 77, 73, 0, 122, 0, 0, 138, - 112, 130, 110, 0, 129, 108, 111, 132, 133, 131, - 20, 19, 0, 0, 0, 0, 61, 0, 93, 94, - 30, 96, 95, 56, 0, 0, 53, 22, 72, 0, - 70, 0, 0, 0, 85, 0, 128, 126, 135, 0, - 109, 62, 0, 0, 0, 54, 0, 29, 0, 97, - 0, 112, 0, 74, 80, 88, 83, 82, 0, 71, - 113, 63, 55, 0, 33, 51, 0, 81, 112, 78, - 0, 87, 0, 86, 89, 73, 31, 98, 84, 79, - 92, 0, 0, 90, 91 -}; - -/* YYDEFGOTO[NTERM-NUM]. */ -static const yytype_int16 yydefgoto[] = -{ - -1, 1, 2, 22, 58, 23, 24, 59, 115, 116, - 117, 118, 119, 120, 121, 80, 122, 123, 124, 25, - 26, 27, 126, 159, 160, 161, 162, 163, 164, 203, - 204, 243, 244, 245, 219, 220, 191, 48, 192, 175, - 176, 28, 29, 30, 31, 32, 33, 34, 130, 67, - 35, 133, 73, 74, 36, 37, 38, 68, 69, 54, - 94 -}; - -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -#define YYPACT_NINF -156 -static const yytype_int16 yypact[] = -{ - -156, 20, 215, -156, -18, 15, 21, 41, -156, 13, - 13, 63, 41, 41, -156, -156, -156, -156, -156, -156, - -156, 4, -156, 27, -156, 27, 59, -156, 27, 27, - 27, 27, 27, -156, -5, 27, -21, 37, 37, -156, - 17, 78, -156, -156, -156, 41, 41, -156, 145, -156, - -156, -156, 145, 145, 74, 66, -156, -156, -156, 132, - -156, -156, -156, -156, -156, -156, -156, 32, 96, -156, - -156, -156, 97, 118, -156, 118, 118, -156, -156, -5, - -5, 124, -156, -156, 81, 41, 41, 41, 41, 41, - -156, -156, -156, -156, -156, -156, 141, -156, -156, -156, - -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, - -156, -156, -156, 80, -156, 129, -156, 62, -19, -156, - 125, -26, -156, -156, -156, 190, 10, 131, -5, 127, - -156, 128, -156, 23, -9, 146, 134, 135, -156, -156, - 34, 34, 164, 164, -156, 162, 250, -156, 41, 236, - 165, 41, 171, -156, 172, 183, 184, 180, -156, 186, - -156, -156, -156, -156, -156, 211, -156, 96, 236, 37, - -156, -156, -156, 41, -156, -20, -156, -156, -156, -156, - -156, -156, -24, 213, 214, 31, -156, 197, -156, -156, - -156, -156, -156, -156, 76, 236, -156, -156, -156, 60, - -156, 11, 18, 12, 192, 203, -156, -156, -156, 121, - -156, -156, 196, 162, 165, -156, 217, 221, 241, -156, - 40, 228, 119, -156, -156, -156, -156, -156, 14, -156, - -156, -156, -156, -20, -156, -156, 236, -156, 230, -156, - 44, -156, 231, 224, -156, -156, -156, -156, -156, -156, - -156, 249, 24, -156, -156 -}; - -/* YYPGOTO[NTERM-NUM]. */ -static const yytype_int16 yypgoto[] = -{ - -156, -156, -156, -156, 202, -156, -156, -156, 166, -156, - -156, 147, -156, -156, 149, 179, -156, -156, 150, -156, - -156, 155, -155, 133, -156, -156, -156, -156, -156, -156, - -156, -156, 48, -156, -141, 79, -6, -10, -127, -156, - -156, -156, -156, -156, -156, -156, -156, -156, 136, -156, - -156, -32, -156, -33, -156, -156, -156, -30, -2, -156, - -156 -}; - -/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule which - number is the opposite. If zero, do what YYDEFACT says. - If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -1 -static const yytype_uint8 yytable[] = -{ - 39, 47, 52, 53, 75, 76, 174, 201, 190, 202, - 81, 156, 156, 226, 71, 241, 44, 5, 44, 156, - 3, 170, 150, 40, 45, 156, 45, 207, 172, 77, - 78, 20, 46, 177, 46, 83, 84, 153, 178, 211, - 72, 173, 151, 134, 135, 55, 20, 20, 210, 136, - 137, 157, 157, 20, 20, 242, 41, 125, 223, 157, - 20, 56, 42, 79, 170, 157, 158, 224, 227, 43, - 171, 172, 71, 44, 225, 140, 141, 142, 143, 144, - 254, 45, 57, 44, 173, 87, 88, 89, 127, 46, - 252, 45, 77, 78, 215, 247, 235, 128, 167, 46, - 249, 221, 44, 188, 51, 236, 246, 189, 172, 236, - 45, 90, 91, 92, 93, 154, 61, 222, 46, 82, - 148, 173, 149, 95, 165, 85, 86, 87, 88, 89, - 85, 86, 87, 88, 89, 96, 208, 129, 218, 131, - 139, 194, 187, 97, 98, 99, 100, 101, 102, 103, - 104, 105, 106, 107, 108, 109, 110, 111, 112, 132, - 238, 44, 188, 209, 49, 50, 189, 172, 20, 45, - 85, 86, 87, 88, 89, 239, 212, 46, 113, 216, - 173, 138, 145, 230, 147, 152, 166, 168, 114, 179, - 169, 180, 181, 96, 85, 86, 87, 88, 89, 165, - 165, 97, 98, 99, 100, 101, 102, 103, 104, 105, - 106, 107, 108, 109, 110, 111, 112, 89, 4, 5, - 6, 7, 8, 9, 10, 11, 182, 60, 195, 193, - 62, 63, 64, 65, 66, 196, 113, 70, 197, 198, - 199, 200, 12, 13, 14, 15, 16, 17, 18, 19, - 165, 20, 157, 183, 213, 214, 217, 228, 229, 231, - 21, 97, 98, 99, 100, 101, 102, 103, 104, 105, - 106, 107, 108, 109, 110, 111, 112, 170, 44, 188, - 232, 233, 234, 189, 172, 237, 45, 248, 250, 251, - 242, 155, 146, 184, 46, 185, 186, 173, 205, 253, - 0, 240, 0, 206 -}; - -static const yytype_int16 yycheck[] = -{ - 2, 7, 12, 13, 37, 38, 133, 162, 149, 164, - 40, 1, 1, 1, 35, 1, 42, 4, 42, 1, - 0, 41, 41, 41, 50, 1, 50, 168, 48, 12, - 13, 36, 58, 42, 58, 45, 46, 63, 47, 63, - 61, 61, 61, 75, 76, 41, 36, 36, 175, 79, - 80, 41, 41, 36, 36, 41, 41, 59, 199, 41, - 36, 57, 41, 46, 41, 41, 56, 56, 56, 48, - 47, 48, 35, 42, 56, 85, 86, 87, 88, 89, - 56, 50, 55, 42, 61, 51, 52, 53, 56, 58, - 245, 50, 12, 13, 63, 236, 56, 65, 128, 58, - 56, 41, 42, 43, 41, 65, 233, 47, 48, 65, - 50, 37, 38, 39, 40, 121, 57, 57, 58, 41, - 58, 61, 60, 57, 126, 49, 50, 51, 52, 53, - 49, 50, 51, 52, 53, 3, 169, 41, 62, 42, - 59, 151, 148, 11, 12, 13, 14, 15, 16, 17, - 18, 19, 20, 21, 22, 23, 24, 25, 26, 41, - 41, 42, 43, 173, 9, 10, 47, 48, 36, 50, - 49, 50, 51, 52, 53, 56, 182, 58, 46, 185, - 61, 57, 41, 62, 55, 60, 55, 60, 56, 43, - 62, 57, 57, 3, 49, 50, 51, 52, 53, 201, - 202, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 53, 3, 4, - 5, 6, 7, 8, 9, 10, 64, 25, 57, 64, - 28, 29, 30, 31, 32, 63, 46, 35, 55, 55, - 60, 55, 27, 28, 29, 30, 31, 32, 33, 34, - 252, 36, 41, 3, 41, 41, 59, 65, 55, 63, - 45, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 41, 42, 43, - 63, 60, 41, 47, 48, 57, 50, 57, 57, 65, - 41, 125, 113, 146, 58, 146, 146, 61, 165, 251, - -1, 222, -1, 167 -}; - -/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const yytype_uint8 yystos[] = -{ - 0, 67, 68, 0, 3, 4, 5, 6, 7, 8, - 9, 10, 27, 28, 29, 30, 31, 32, 33, 34, - 36, 45, 69, 71, 72, 85, 86, 87, 107, 108, - 109, 110, 111, 112, 113, 116, 120, 121, 122, 124, - 41, 41, 41, 48, 42, 50, 58, 102, 103, 87, - 87, 41, 103, 103, 125, 41, 57, 55, 70, 73, - 70, 57, 70, 70, 70, 70, 70, 115, 123, 124, - 70, 35, 61, 118, 119, 119, 119, 12, 13, 46, - 81, 123, 41, 103, 103, 49, 50, 51, 52, 53, - 37, 38, 39, 40, 126, 57, 3, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 46, 56, 74, 75, 76, 77, 78, - 79, 80, 82, 83, 84, 124, 88, 56, 65, 41, - 114, 42, 41, 117, 117, 117, 123, 123, 57, 59, - 103, 103, 103, 103, 103, 41, 81, 55, 58, 60, - 41, 61, 60, 63, 102, 74, 1, 41, 56, 89, - 90, 91, 92, 93, 94, 124, 55, 123, 60, 62, - 41, 47, 48, 61, 104, 105, 106, 42, 47, 43, - 57, 57, 64, 3, 77, 80, 84, 102, 43, 47, - 100, 102, 104, 64, 103, 57, 63, 55, 55, 60, - 55, 88, 88, 95, 96, 89, 114, 100, 119, 103, - 104, 63, 102, 41, 41, 63, 102, 59, 62, 100, - 101, 41, 57, 100, 56, 56, 1, 56, 65, 55, - 62, 63, 63, 60, 41, 56, 65, 57, 41, 56, - 101, 1, 41, 97, 98, 99, 104, 100, 57, 56, - 57, 65, 88, 98, 56 -}; - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab - - -/* Like YYERROR except do call yyerror. This remains here temporarily - to ease the transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. */ - -#define YYFAIL goto yyerrlab - -#define YYRECOVERING() (!!yyerrstatus) - -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - yytoken = YYTRANSLATE (yychar); \ - YYPOPSTACK (1); \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (YYID (0)) - - -#define YYTERROR 1 -#define YYERRCODE 256 - - -/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. - If N is 0, then set CURRENT to the empty location which ends - the previous symbol: RHS[0] (always defined). */ - -#define YYRHSLOC(Rhs, K) ((Rhs)[K]) -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - do \ - if (YYID (N)) \ - { \ - (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ - (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - } \ - else \ - { \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC (Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC (Rhs, 0).last_column; \ - } \ - while (YYID (0)) -#endif - - -/* YY_LOCATION_PRINT -- Print the location on the stream. - This macro was not mandated originally: define only if we know - we won't break user code: when these are the locations we know. */ - -#ifndef YY_LOCATION_PRINT -# if YYLTYPE_IS_TRIVIAL -# define YY_LOCATION_PRINT(File, Loc) \ - fprintf (File, "%d.%d-%d.%d", \ - (Loc).first_line, (Loc).first_column, \ - (Loc).last_line, (Loc).last_column) -# else -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -# endif -#endif - - -/* YYLEX -- calling `yylex' with the right arguments. */ - -#ifdef YYLEX_PARAM -# define YYLEX yylex (YYLEX_PARAM) -#else -# define YYLEX yylex () -#endif - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (YYID (0)) - -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Type, Value); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (YYID (0)) - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) -#else -static void -yy_symbol_value_print (yyoutput, yytype, yyvaluep) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; -#endif -{ - if (!yyvaluep) - return; -# ifdef YYPRINT - if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# else - YYUSE (yyoutput); -# endif - switch (yytype) - { - default: - break; - } -} - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) -#else -static void -yy_symbol_print (yyoutput, yytype, yyvaluep) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; -#endif -{ - if (yytype < YYNTOKENS) - YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); - else - YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); - - yy_symbol_value_print (yyoutput, yytype, yyvaluep); - YYFPRINTF (yyoutput, ")"); -} - -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (included). | -`------------------------------------------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) -#else -static void -yy_stack_print (yybottom, yytop) - yytype_int16 *yybottom; - yytype_int16 *yytop; -#endif -{ - YYFPRINTF (stderr, "Stack now"); - for (; yybottom <= yytop; yybottom++) - { - int yybot = *yybottom; - YYFPRINTF (stderr, " %d", yybot); - } - YYFPRINTF (stderr, "\n"); -} - -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (YYID (0)) - - -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_reduce_print (YYSTYPE *yyvsp, int yyrule) -#else -static void -yy_reduce_print (yyvsp, yyrule) - YYSTYPE *yyvsp; - int yyrule; -#endif -{ - int yynrhs = yyr2[yyrule]; - int yyi; - unsigned long int yylno = yyrline[yyrule]; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", - yyrule - 1, yylno); - /* The symbols being reduced. */ - for (yyi = 0; yyi < yynrhs; yyi++) - { - YYFPRINTF (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], - &(yyvsp[(yyi + 1) - (yynrhs)]) - ); - YYFPRINTF (stderr, "\n"); - } -} - -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyvsp, Rule); \ -} while (YYID (0)) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ - - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif - - - -#if YYERROR_VERBOSE - -# ifndef yystrlen -# if defined __GLIBC__ && defined _STRING_H -# define yystrlen strlen -# else -/* Return the length of YYSTR. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static YYSIZE_T -yystrlen (const char *yystr) -#else -static YYSIZE_T -yystrlen (yystr) - const char *yystr; -#endif -{ - YYSIZE_T yylen; - for (yylen = 0; yystr[yylen]; yylen++) - continue; - return yylen; -} -# endif -# endif - -# ifndef yystpcpy -# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static char * -yystpcpy (char *yydest, const char *yysrc) -#else -static char * -yystpcpy (yydest, yysrc) - char *yydest; - const char *yysrc; -#endif -{ - char *yyd = yydest; - const char *yys = yysrc; - - while ((*yyd++ = *yys++) != '\0') - continue; - - return yyd - 1; -} -# endif -# endif - -# ifndef yytnamerr -/* Copy to YYRES the contents of YYSTR after stripping away unnecessary - quotes and backslashes, so that it's suitable for yyerror. The - heuristic is that double-quoting is unnecessary unless the string - contains an apostrophe, a comma, or backslash (other than - backslash-backslash). YYSTR is taken from yytname. If YYRES is - null, do not copy; instead, return the length of what the result - would have been. */ -static YYSIZE_T -yytnamerr (char *yyres, const char *yystr) -{ - if (*yystr == '"') - { - YYSIZE_T yyn = 0; - char const *yyp = yystr; - - for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; - - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - /* Fall through. */ - default: - if (yyres) - yyres[yyn] = *yyp; - yyn++; - break; - - case '"': - if (yyres) - yyres[yyn] = '\0'; - return yyn; - } - do_not_strip_quotes: ; - } - - if (! yyres) - return yystrlen (yystr); - - return yystpcpy (yyres, yystr) - yyres; -} -# endif - -/* Copy into YYRESULT an error message about the unexpected token - YYCHAR while in state YYSTATE. Return the number of bytes copied, - including the terminating null byte. If YYRESULT is null, do not - copy anything; just return the number of bytes that would be - copied. As a special case, return 0 if an ordinary "syntax error" - message will do. Return YYSIZE_MAXIMUM if overflow occurs during - size calculation. */ -static YYSIZE_T -yysyntax_error (char *yyresult, int yystate, int yychar) -{ - int yyn = yypact[yystate]; - - if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) - return 0; - else - { - int yytype = YYTRANSLATE (yychar); - YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); - YYSIZE_T yysize = yysize0; - YYSIZE_T yysize1; - int yysize_overflow = 0; - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - int yyx; - -# if 0 - /* This is so xgettext sees the translatable formats that are - constructed on the fly. */ - YY_("syntax error, unexpected %s"); - YY_("syntax error, unexpected %s, expecting %s"); - YY_("syntax error, unexpected %s, expecting %s or %s"); - YY_("syntax error, unexpected %s, expecting %s or %s or %s"); - YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); -# endif - char *yyfmt; - char const *yyf; - static char const yyunexpected[] = "syntax error, unexpected %s"; - static char const yyexpecting[] = ", expecting %s"; - static char const yyor[] = " or %s"; - char yyformat[sizeof yyunexpected - + sizeof yyexpecting - 1 - + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) - * (sizeof yyor - 1))]; - char const *yyprefix = yyexpecting; - - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = YYLAST - yyn + 1; - int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yycount = 1; - - yyarg[0] = yytname[yytype]; - yyfmt = yystpcpy (yyformat, yyunexpected); - - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - { - if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) - { - yycount = 1; - yysize = yysize0; - yyformat[sizeof yyunexpected - 1] = '\0'; - break; - } - yyarg[yycount++] = yytname[yyx]; - yysize1 = yysize + yytnamerr (0, yytname[yyx]); - yysize_overflow |= (yysize1 < yysize); - yysize = yysize1; - yyfmt = yystpcpy (yyfmt, yyprefix); - yyprefix = yyor; - } - - yyf = YY_(yyformat); - yysize1 = yysize + yystrlen (yyf); - yysize_overflow |= (yysize1 < yysize); - yysize = yysize1; - - if (yysize_overflow) - return YYSIZE_MAXIMUM; - - if (yyresult) - { - /* Avoid sprintf, as that infringes on the user's name space. - Don't have undefined behavior even if the translation - produced a string with the wrong number of "%s"s. */ - char *yyp = yyresult; - int yyi = 0; - while ((*yyp = *yyf) != '\0') - { - if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) - { - yyp += yytnamerr (yyp, yyarg[yyi++]); - yyf += 2; - } - else - { - yyp++; - yyf++; - } - } - } - return yysize; - } -} -#endif /* YYERROR_VERBOSE */ - - -/*-----------------------------------------------. -| Release the memory associated to this symbol. | -`-----------------------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) -#else -static void -yydestruct (yymsg, yytype, yyvaluep) - const char *yymsg; - int yytype; - YYSTYPE *yyvaluep; -#endif -{ - YYUSE (yyvaluep); - - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - - switch (yytype) - { - - default: - break; - } -} - -/* Prevent warnings from -Wmissing-prototypes. */ -#ifdef YYPARSE_PARAM -#if defined __STDC__ || defined __cplusplus -int yyparse (void *YYPARSE_PARAM); -#else -int yyparse (); -#endif -#else /* ! YYPARSE_PARAM */ -#if defined __STDC__ || defined __cplusplus -int yyparse (void); -#else -int yyparse (); -#endif -#endif /* ! YYPARSE_PARAM */ - - -/* The lookahead symbol. */ -int yychar; - -/* The semantic value of the lookahead symbol. */ -YYSTYPE yylval; - -/* Number of syntax errors so far. */ -int yynerrs; - - - -/*-------------------------. -| yyparse or yypush_parse. | -`-------------------------*/ - -#ifdef YYPARSE_PARAM -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (void *YYPARSE_PARAM) -#else -int -yyparse (YYPARSE_PARAM) - void *YYPARSE_PARAM; -#endif -#else /* ! YYPARSE_PARAM */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (void) -#else -int -yyparse () - -#endif -#endif -{ - - - int yystate; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - - /* The stacks and their tools: - `yyss': related to states. - `yyvs': related to semantic values. - - Refer to the stacks thru separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss; - yytype_int16 *yyssp; - - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs; - YYSTYPE *yyvsp; - - YYSIZE_T yystacksize; - - int yyn; - int yyresult; - /* Lookahead token as an internal (translated) token number. */ - int yytoken; - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; - -#if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; -#endif - -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) - - /* The number of symbols on the RHS of the reduced rule. - Keep to zero when no symbol should be popped. */ - int yylen = 0; - - yytoken = 0; - yyss = yyssa; - yyvs = yyvsa; - yystacksize = YYINITDEPTH; - - YYDPRINTF ((stderr, "Starting parse\n")); - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ - yyssp = yyss; - yyvsp = yyvs; - - goto yysetstate; - -/*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | -`------------------------------------------------------------*/ - yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. So pushing a state here evens the stacks. */ - yyssp++; - - yysetstate: - *yyssp = yystate; - - if (yyss + yystacksize - 1 <= yyssp) - { - /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; - -#ifdef yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - yytype_int16 *yyss1 = yyss; - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - &yystacksize); - - yyss = yyss1; - yyvs = yyvs1; - } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyexhaustedlab; -# else - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; - - { - yytype_int16 *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss_alloc, yyss); - YYSTACK_RELOCATE (yyvs_alloc, yyvs); -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif -#endif /* no yyoverflow */ - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); - - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; - } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - - if (yystate == YYFINAL) - YYACCEPT; - - goto yybackup; - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - - /* Do appropriate processing given the current state. Read a - lookahead token if we need one and don't already have one. */ - - /* First try to decide what to do without reference to lookahead token. */ - yyn = yypact[yystate]; - if (yyn == YYPACT_NINF) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token: ")); - yychar = YYLEX; - } - - if (yychar <= YYEOF) - { - yychar = yytoken = YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else - { - yytoken = YYTRANSLATE (yychar); - YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); - } - - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) - goto yydefault; - yyn = yytable[yyn]; - if (yyn <= 0) - { - if (yyn == 0 || yyn == YYTABLE_NINF) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - /* Shift the lookahead token. */ - YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - - /* Discard the shifted token. */ - yychar = YYEMPTY; - - yystate = yyn; - *++yyvsp = yylval; - - goto yynewstate; - - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - - -/*-----------------------------. -| yyreduce -- Do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: - `$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - - - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 2: - -/* Line 1455 of yacc.c */ -#line 182 "rcomp.yacc" - { if(verbose) { MOFF; cout << Divider << "\n" << Divider << endl; MON; } - ;} - break; - - case 15: - -/* Line 1455 of yacc.c */ -#line 208 "rcomp.yacc" - { - // This is my gift to the world: no more "syntax error" for adding - // an extra semicolon at the end of a struct or resource. - REGISTER_LINE; - ErrorHandler::OutputErrorLine("Warning: unnecessary semicolon"); - ;} - break; - - case 17: - -/* Line 1455 of yacc.c */ -#line 222 "rcomp.yacc" - { if(verbose) { MOFF; cout << Divider << "\n" << * pSH << Divider << endl; MON;} ;} - break; - - case 18: - -/* Line 1455 of yacc.c */ -#line 226 "rcomp.yacc" - { if(verbose) { MOFF;cout << "struct_statement_start " << (yyvsp[(2) - (4)].Value) << endl; MON;} - pSH = new StructHeader((yyvsp[(2) - (4)].Value)); - REGISTER_LINE; - pG->SHA.Add(pSH); - ;} - break; - - case 19: - -/* Line 1455 of yacc.c */ -#line 232 "rcomp.yacc" - { if(verbose) { RCTypeArray Types; MOFF;cout << "struct_statement_start " << (yyvsp[(2) - (5)].Value) << " " << Types.GetName((yyvsp[(3) - (5)].Id)) << endl; MON;} - pSH = new StructHeader((yyvsp[(2) - (5)].Value), (yyvsp[(3) - (5)].Id)); - REGISTER_LINE; - pG->SHA.Add(pSH); - ;} - break; - - case 20: - -/* Line 1455 of yacc.c */ -#line 238 "rcomp.yacc" - { if(verbose) { MOFF;cout << "struct_statement_start " << (yyvsp[(2) - (5)].Value) << " (WORD)" << endl; MON;} - pSH = new StructHeader((yyvsp[(2) - (5)].Value), L_WORD); - REGISTER_LINE; - pG->SHA.Add(pSH); - ;} - break; - - case 21: - -/* Line 1455 of yacc.c */ -#line 245 "rcomp.yacc" - { if(verbose) { MOFF;cout << "struct_item_list Adding struct_item." << endl; MON;} - REGISTER_LINE; - pSH->iSIA.Add((yyvsp[(2) - (3)].pStructItem)); - ;} - break; - - case 22: - -/* Line 1455 of yacc.c */ -#line 249 "rcomp.yacc" - { if(verbose) { MOFF;cout << "tagged struct_item_list Adding struct_item." << endl; MON;} - REGISTER_LINE; - pSH->iSIA.Add((yyvsp[(3) - (4)].pStructItem)); - ;} - break; - - case 28: - -/* Line 1455 of yacc.c */ -#line 262 "rcomp.yacc" - { (yyval.pStructItem) = (yyvsp[(1) - (1)].pSimpleStructItem);;} - break; - - case 29: - -/* Line 1455 of yacc.c */ -#line 264 "rcomp.yacc" - { if(verbose) { MOFF;cout << " Limit: " << (yyvsp[(3) - (4)].Value) << endl; MON;} - (yyvsp[(1) - (4)].pSimpleStructItem)->iLengthLimit = (yyvsp[(3) - (4)].Value); - (yyval.pStructItem) = (yyvsp[(1) - (4)].pSimpleStructItem); - ;} - break; - - case 30: - -/* Line 1455 of yacc.c */ -#line 269 "rcomp.yacc" - { if(verbose) { MOFF;cout << " Default: " << (yyvsp[(3) - (3)].Value) << endl; MON;} - (yyvsp[(1) - (3)].pSimpleStructItem)->iDefault = (yyvsp[(3) - (3)].Value); - (yyval.pStructItem) = (yyvsp[(1) - (3)].pSimpleStructItem); - ;} - break; - - case 31: - -/* Line 1455 of yacc.c */ -#line 274 "rcomp.yacc" - { if(verbose) { MOFF;cout << " Limit: " << (yyvsp[(3) - (6)].Value) << ", Default: " << (yyvsp[(6) - (6)].Value) << endl; MON;} - NumericValue Limit((yyvsp[(3) - (6)].Value), L_LONG); - if(String((yyvsp[(6) - (6)].Value)).ExportLength(TargetCharacterSet,SourceCharacterSet) > Limit.GetULong() ) - { - REGISTER_LINE; - ErrorHandler::OutputErrorLine("Text length exceeds specified limit"); - exit(1); - } - (yyvsp[(1) - (6)].pSimpleStructItem)->iLengthLimit = (yyvsp[(3) - (6)].Value); - (yyvsp[(1) - (6)].pSimpleStructItem)->iDefault = (yyvsp[(6) - (6)].Value); - (yyval.pStructItem) = (yyvsp[(1) - (6)].pSimpleStructItem); - ;} - break; - - case 32: - -/* Line 1455 of yacc.c */ -#line 289 "rcomp.yacc" - { if(verbose) - { - RCTypeArray Types; - MOFF;cout << "simple_struct_item " << Types.GetName((yyvsp[(1) - (2)].Id)) << " " << (yyvsp[(2) - (2)].Value) << endl; MON; - } - (yyval.pSimpleStructItem) = new SimpleStructItem((yyvsp[(1) - (2)].Id),(yyvsp[(2) - (2)].Value)); - assert((yyval.pSimpleStructItem) != NULL); - ;} - break; - - case 33: - -/* Line 1455 of yacc.c */ -#line 298 "rcomp.yacc" - { if(verbose) - { RCTypeArray Types; - MOFF;cout << "simple_struct_item " << Types.GetName((yyvsp[(1) - (5)].Id)) << " " << (yyvsp[(5) - (5)].Value) << endl; MON; - } - String s(NumericValue::ltoa((yyvsp[(3) - (5)].NumInitialiser))); - (yyval.pSimpleStructItem) = new SimpleStructItem((yyvsp[(1) - (5)].Id),(yyvsp[(5) - (5)].Value),s); - assert((yyval.pSimpleStructItem) != NULL); - ;} - break; - - case 34: - -/* Line 1455 of yacc.c */ -#line 312 "rcomp.yacc" - { (yyval.Id) = L_BYTE;;} - break; - - case 35: - -/* Line 1455 of yacc.c */ -#line 313 "rcomp.yacc" - { (yyval.Id) = L_WORD;;} - break; - - case 36: - -/* Line 1455 of yacc.c */ -#line 314 "rcomp.yacc" - { (yyval.Id) = L_LONG;;} - break; - - case 37: - -/* Line 1455 of yacc.c */ -#line 315 "rcomp.yacc" - { (yyval.Id) = L_DOUBLE;;} - break; - - case 38: - -/* Line 1455 of yacc.c */ -#line 320 "rcomp.yacc" - { - (yyval.Id) = ( TargetCharacterSet == String::Unicode ) ? L_TEXT16: L_TEXT8; - REGISTER_LINE; - ErrorHandler::OutputErrorLine("Warning: Deprecated use of zero-terminated TEXT - use LTEXT instead"); - ;} - break; - - case 39: - -/* Line 1455 of yacc.c */ -#line 326 "rcomp.yacc" - { - (yyval.Id) = ( TargetCharacterSet == String::Unicode ) ? L_LTEXT16: L_LTEXT8; - ;} - break; - - case 40: - -/* Line 1455 of yacc.c */ -#line 330 "rcomp.yacc" - { - (yyval.Id) = ( TargetCharacterSet == String::Unicode ) ? L_BUF16: L_BUF8; - ;} - break; - - case 41: - -/* Line 1455 of yacc.c */ -#line 336 "rcomp.yacc" - { (yyval.Id) = L_TEXT8; - REGISTER_LINE; - ErrorHandler::OutputErrorLine("Warning: Deprecated use of zero-terminated TEXT8 - use LTEXT8 instead"); - ;} - break; - - case 42: - -/* Line 1455 of yacc.c */ -#line 340 "rcomp.yacc" - { (yyval.Id) = L_TEXT16; - REGISTER_LINE; - ErrorHandler::OutputErrorLine("Warning: Deprecated use of zero-terminated TEXT16 - use LTEXT16 instead"); - ;} - break; - - case 43: - -/* Line 1455 of yacc.c */ -#line 344 "rcomp.yacc" - { (yyval.Id) = L_LTEXT8;;} - break; - - case 44: - -/* Line 1455 of yacc.c */ -#line 345 "rcomp.yacc" - { (yyval.Id) = L_LTEXT16;;} - break; - - case 45: - -/* Line 1455 of yacc.c */ -#line 346 "rcomp.yacc" - { (yyval.Id) = L_BUF8;;} - break; - - case 46: - -/* Line 1455 of yacc.c */ -#line 347 "rcomp.yacc" - { (yyval.Id) = L_BUF16;;} - break; - - case 47: - -/* Line 1455 of yacc.c */ -#line 348 "rcomp.yacc" - { (yyval.Id) = L_LINK;;} - break; - - case 48: - -/* Line 1455 of yacc.c */ -#line 349 "rcomp.yacc" - { (yyval.Id) = L_LLINK;;} - break; - - case 49: - -/* Line 1455 of yacc.c */ -#line 350 "rcomp.yacc" - { (yyval.Id) = L_SRLINK;;} - break; - - case 50: - -/* Line 1455 of yacc.c */ -#line 353 "rcomp.yacc" - { (yyval.pStructItem) = (yyvsp[(1) - (1)].pArrayStructItem);;} - break; - - case 51: - -/* Line 1455 of yacc.c */ -#line 355 "rcomp.yacc" - { if(verbose) { MOFF;cout << "array_struct_item with simple_initialiser_list" << endl;MON;} - (yyvsp[(1) - (5)].pArrayStructItem)->iDefaults = * (yyvsp[(4) - (5)].pStringArray); - if((yyvsp[(1) - (5)].pArrayStructItem)->iSize.Length() > 0) - { - NumericValue v((yyvsp[(1) - (5)].pArrayStructItem)->iSize, L_LONG); - REGISTER_LINE; - if((yyvsp[(4) - (5)].pStringArray)->Size()!=long(v.GetULong())) - { - ErrorHandler::OutputErrorLine("Size does not match number of initialisers"); - exit(1); - } - } - (yyval.pStructItem) = (yyvsp[(1) - (5)].pArrayStructItem); - delete (yyvsp[(4) - (5)].pStringArray); - ;} - break; - - case 52: - -/* Line 1455 of yacc.c */ -#line 372 "rcomp.yacc" - { if(verbose) { MOFF;cout << "array_struct_item_base with no size" << endl;MON;} - (yyval.pArrayStructItem) =(yyvsp[(1) - (2)].pArrayStructItem); - ;} - break; - - case 53: - -/* Line 1455 of yacc.c */ -#line 376 "rcomp.yacc" - { if(verbose) { MOFF;cout << "array_struct_item_base with size " << (yyvsp[(2) - (3)].Value) << endl;MON;} - (yyvsp[(1) - (3)].pArrayStructItem)->iSize = (yyvsp[(2) - (3)].Value); - (yyval.pArrayStructItem) = (yyvsp[(1) - (3)].pArrayStructItem); - ;} - break; - - case 54: - -/* Line 1455 of yacc.c */ -#line 381 "rcomp.yacc" - { if(verbose) - { RCTypeArray Types; - MOFF;cout << "array_struct_item_base with LenType " << Types.GetName((yyvsp[(2) - (4)].Id)) << endl;MON; - } - (yyvsp[(3) - (4)].pArrayStructItem)->iLenType = (yyvsp[(2) - (4)].Id); - (yyval.pArrayStructItem) = (yyvsp[(3) - (4)].pArrayStructItem); - ;} - break; - - case 55: - -/* Line 1455 of yacc.c */ -#line 389 "rcomp.yacc" - { if(verbose) - { RCTypeArray Types; - MOFF;cout << "array_struct_item_base with size " << (yyvsp[(4) - (5)].Value) << " and LenType " << Types.GetName((yyvsp[(2) - (5)].Id)) << endl;MON; - } - (yyvsp[(3) - (5)].pArrayStructItem)->iLenType = (yyvsp[(2) - (5)].Id); - (yyvsp[(3) - (5)].pArrayStructItem)->iSize = (yyvsp[(4) - (5)].Value); - (yyval.pArrayStructItem) = (yyvsp[(3) - (5)].pArrayStructItem); - ;} - break; - - case 56: - -/* Line 1455 of yacc.c */ -#line 399 "rcomp.yacc" - { if(verbose) - { RCTypeArray Types; - MOFF;cout << "array_struct_item_start " << Types.GetName((yyvsp[(1) - (3)].Id)) << " " << (yyvsp[(2) - (3)].Value) << endl;MON; - } - (yyval.pArrayStructItem) = new ArrayStructItem((yyvsp[(1) - (3)].Id), (yyvsp[(2) - (3)].Value)); - ;} - break; - - case 57: - -/* Line 1455 of yacc.c */ -#line 407 "rcomp.yacc" - { (yyval.Id) = L_BYTE;;} - break; - - case 58: - -/* Line 1455 of yacc.c */ -#line 408 "rcomp.yacc" - { (yyval.Id) = L_WORD;;} - break; - - case 59: - -/* Line 1455 of yacc.c */ -#line 411 "rcomp.yacc" - { if(verbose) { MOFF;cout << "struct_type_struct_item " << (yyvsp[(2) - (2)].Value) << endl;MON;} - (yyval.pStructItem) = new StructTypeStructItem((yyvsp[(2) - (2)].Value)); - ;} - break; - - case 60: - -/* Line 1455 of yacc.c */ -#line 416 "rcomp.yacc" - { (yyval.pStructItem) = (yyvsp[(1) - (1)].pStructArrayStructItem);;} - break; - - case 61: - -/* Line 1455 of yacc.c */ -#line 418 "rcomp.yacc" - { if(verbose) { RCTypeArray Types; MOFF;cout << "struct_array_struct_item - Setting Size to " << Types.GetName((yyvsp[(2) - (3)].Id)) << endl;MON;} - (yyvsp[(3) - (3)].pStructArrayStructItem)->iLenType = (yyvsp[(2) - (3)].Id); (yyval.pStructItem) = (yyvsp[(3) - (3)].pStructArrayStructItem); - ;} - break; - - case 62: - -/* Line 1455 of yacc.c */ -#line 423 "rcomp.yacc" - { if(verbose) { MOFF;cout << "struct_array_struct_item_base " << (yyvsp[(2) - (4)].Value) << endl;MON;} - (yyval.pStructArrayStructItem) = new StructArrayStructItem((yyvsp[(2) - (4)].Value)); - ;} - break; - - case 63: - -/* Line 1455 of yacc.c */ -#line 427 "rcomp.yacc" - { if(verbose) { MOFF;cout << "struct_array_struct_item_base " << (yyvsp[(2) - (5)].Value) << " " << (yyvsp[(4) - (5)].Value) << endl;MON;} - (yyval.pStructArrayStructItem) = new StructArrayStructItem((yyvsp[(2) - (5)].Value), (yyvsp[(4) - (5)].Value)); - ;} - break; - - case 64: - -/* Line 1455 of yacc.c */ -#line 436 "rcomp.yacc" - { - pResourceHeader->AddDefault(); - CurrentId+=CurrentIdStep; - if(verbose) { MOFF;cout << "Resource ID "<< CurrentId << endl << Divider << "\n" << * pResourceHeader << Divider << endl;MON;} - pResourceHeader->SetResourceId(*pResourceNameIds,CurrentId,FormatIdAsHex); - pG->Index.Add(pResourceHeader); - - CheckStructUsage(); - - pUsedLabelsArray->Empty(); - - pResourceHeader = NULL; - ;} - break; - - case 65: - -/* Line 1455 of yacc.c */ -#line 451 "rcomp.yacc" - {;} - break; - - case 66: - -/* Line 1455 of yacc.c */ -#line 453 "rcomp.yacc" - { - if(verbose) { MOFF;cout << "resource_statement_start LOCAL" << endl;MON;} - assert(pResourceHeader != NULL); - pResourceHeader->iLocal = 1; - ;} - break; - - case 67: - -/* Line 1455 of yacc.c */ -#line 458 "rcomp.yacc" - {;} - break; - - case 68: - -/* Line 1455 of yacc.c */ -#line 461 "rcomp.yacc" - { if(verbose) { MOFF;cout << "resource_statement_start_names " << (yyvsp[(2) - (3)].Value) << " " << (yyvsp[(3) - (3)].Value) << endl;MON;} - assert(pResourceHeader == NULL); - pResourceHeader = new ResourceHeader((yyvsp[(3) - (3)].Value)); - pCurrentRIA = & (pResourceHeader->iRIA); - REGISTER_LINE; - if(pResourceNameIds->IsStored((yyvsp[(3) - (3)].Value))) - { - ErrorHandler::OutputErrorLine("Resource with this name encountered already"); - exit(1); - } - pCurrentRIA->FillFromStruct((yyvsp[(2) - (3)].Value)); - pG->AllIdentifiers.Add(new String((yyvsp[(3) - (3)].Value))); // Add label to store - ;} - break; - - case 69: - -/* Line 1455 of yacc.c */ -#line 474 "rcomp.yacc" - { if(verbose) { MOFF;cout << "resource_statement_start_names " << (yyvsp[(2) - (2)].Value) << " " << endl;MON;} - assert(pResourceHeader == NULL); - pResourceHeader = new ResourceHeader; - pCurrentRIA = & (pResourceHeader->iRIA); - REGISTER_LINE; - pCurrentRIA->FillFromStruct((yyvsp[(2) - (2)].Value)); - ;} - break; - - case 70: - -/* Line 1455 of yacc.c */ -#line 483 "rcomp.yacc" - { if(verbose) { MOFF;cout << "resource_item_list" << endl;MON;};} - break; - - case 71: - -/* Line 1455 of yacc.c */ -#line 484 "rcomp.yacc" - { if(verbose) { MOFF;cout << "tagged resource_item_list" << endl;MON;};} - break; - - case 72: - -/* Line 1455 of yacc.c */ -#line 485 "rcomp.yacc" - { yyerrok; yyclearin; ;} - break; - - case 74: - -/* Line 1455 of yacc.c */ -#line 489 "rcomp.yacc" - { if(verbose) { MOFF;cout << "resource_item " << (yyvsp[(1) - (3)].Value) << " " << (yyvsp[(3) - (3)].Value) << endl;MON;} - REGISTER_LINE;/****************************************************************/ - pCurrentRIA->Set((yyvsp[(1) - (3)].Value), (yyvsp[(3) - (3)].Value)); - ;} - break; - - case 78: - -/* Line 1455 of yacc.c */ -#line 499 "rcomp.yacc" - { - if (verbose) - { MOFF;cout << "resource_simple_array_item " << (yyvsp[(1) - (4)].Value) << endl;MON;} - ;} - break; - - case 79: - -/* Line 1455 of yacc.c */ -#line 504 "rcomp.yacc" - { - if (verbose) - { MOFF;cout << "resource_simple_array_item " << (yyvsp[(1) - (5)].Value) << " with simple_initialiser_list" << endl;MON;} - REGISTER_LINE; - pCurrentRIA->Set((yyvsp[(1) - (5)].Value), * (yyvsp[(4) - (5)].pStringArray)); - delete (yyvsp[(4) - (5)].pStringArray); - ;} - break; - - case 80: - -/* Line 1455 of yacc.c */ -#line 532 "rcomp.yacc" - { if(verbose) { MOFF;cout << "struct_resource_item" << endl;MON;} - pCurrentRIA = pG->RIAStack.Pop(); - ;} - break; - - case 81: - -/* Line 1455 of yacc.c */ -#line 537 "rcomp.yacc" - { if(verbose) { MOFF;cout << "struct_resource_item_start " << (yyvsp[(1) - (4)].Value) << " " << (yyvsp[(3) - (4)].Value) << endl;MON;} - REGISTER_LINE; - pCurrentRIA->Set((yyvsp[(1) - (4)].Value), (yyvsp[(3) - (4)].Value)); - String * thisLabel = new String((yyvsp[(1) - (4)].Value)); - pUsedLabelsArray->Add(thisLabel); - // in here add the label to a temp store - pG->RIAStack.Push(pCurrentRIA); - pCurrentRIA = pCurrentRIA->Find((yyvsp[(1) - (4)].Value))->GetRIA(); - ;} - break; - - case 82: - -/* Line 1455 of yacc.c */ -#line 549 "rcomp.yacc" - { if(verbose) { MOFF;cout << "struct_array_resource_item" << endl;MON;} - pG->SRIStack.Pop(); - ;} - break; - - case 83: - -/* Line 1455 of yacc.c */ -#line 553 "rcomp.yacc" - { pG->SRIStack.Pop();;} - break; - - case 84: - -/* Line 1455 of yacc.c */ -#line 556 "rcomp.yacc" - { if(verbose) { MOFF;cout << "struct_array_resource_item_start " << (yyvsp[(1) - (5)].Value) << " " << (yyvsp[(4) - (5)].Value) << endl;MON;} - ResourceItem * p = pCurrentRIA->Find((yyvsp[(1) - (5)].Value)); - pG->SRIStack.Push(p); - REGISTER_LINE; - String * thisLabel = new String((yyvsp[(1) - (5)].Value)); - pUsedLabelsArray->Add(thisLabel); - // in here add the label to a temp store - p->Set((yyvsp[(4) - (5)].Value)); - pG->RIAStack.Push(pCurrentRIA); - pCurrentRIA = p->GetRIA(); - ;} - break; - - case 88: - -/* Line 1455 of yacc.c */ -#line 574 "rcomp.yacc" - { if(verbose) { MOFF;cout << "struct_array_resource_item_list_top " << endl;MON;} - pCurrentRIA = pG->RIAStack.Pop(); - ;} - break; - - case 91: - -/* Line 1455 of yacc.c */ -#line 584 "rcomp.yacc" - { if(verbose) { MOFF;cout << "struct_array_resource_item_list_item " << endl;MON;} - pCurrentRIA = pG->RIAStack.Pop(); - ;} - break; - - case 92: - -/* Line 1455 of yacc.c */ -#line 589 "rcomp.yacc" - { if(verbose) { MOFF;cout << "struct_array_resource_item_list_item_start " << (yyvsp[(1) - (2)].Value) << endl;MON;} - ResourceItem * p = pG->SRIStack.Peek(); - REGISTER_LINE; - p->Set((yyvsp[(1) - (2)].Value)); - pG->RIAStack.Push(pCurrentRIA); - pCurrentRIA = p->GetRIA(); - ;} - break; - - case 94: - -/* Line 1455 of yacc.c */ -#line 605 "rcomp.yacc" - { - // convert literal to unsigned long value of 1st character - SetCharacterLiteral((yyval.Value), (yyvsp[(1) - (1)].Value)); - ;} - break; - - case 97: - -/* Line 1455 of yacc.c */ -#line 614 "rcomp.yacc" - { - if(verbose) - { - MOFF;cout << "simple_initialiser_list - single string " << (yyvsp[(1) - (1)].Value) << endl;MON; - } - - (yyval.pStringArray) = new StringArray; - (yyval.pStringArray)->Add(new String((yyvsp[(1) - (1)].Value)) ); - ;} - break; - - case 98: - -/* Line 1455 of yacc.c */ -#line 624 "rcomp.yacc" - { if(verbose) { MOFF;cout << "simple_initialiser_list - part of list " << (yyvsp[(3) - (3)].Value) << endl;MON;} - assert((yyvsp[(1) - (3)].pStringArray) != NULL); - (yyvsp[(1) - (3)].pStringArray)->Add(new String((yyvsp[(3) - (3)].Value) ) ); - (yyval.pStringArray) = (yyvsp[(1) - (3)].pStringArray); - ;} - break; - - case 99: - -/* Line 1455 of yacc.c */ -#line 632 "rcomp.yacc" - { String s(NumericValue::ltoa((yyvsp[(1) - (1)].NumInitialiser)) ); strcpy((yyval.Value), s.GetAssertedNonEmptyBuffer() ); ;} - break; - - case 100: - -/* Line 1455 of yacc.c */ -#line 635 "rcomp.yacc" - { if(verbose) { MOFF;cout << "Converting number " << (yyvsp[(1) - (1)].Value) << endl;MON;} - REGISTER_LINE; - NumericValue v((yyvsp[(1) - (1)].Value), L_LONG); (yyval.NumInitialiser) = (long)v.GetULong(); - ;} - break; - - case 101: - -/* Line 1455 of yacc.c */ -#line 639 "rcomp.yacc" - { (yyval.NumInitialiser) = (yyvsp[(1) - (3)].NumInitialiser) + (yyvsp[(3) - (3)].NumInitialiser); ;} - break; - - case 102: - -/* Line 1455 of yacc.c */ -#line 640 "rcomp.yacc" - { (yyval.NumInitialiser) = (yyvsp[(1) - (3)].NumInitialiser) - (yyvsp[(3) - (3)].NumInitialiser); ;} - break; - - case 103: - -/* Line 1455 of yacc.c */ -#line 641 "rcomp.yacc" - { (yyval.NumInitialiser) = (yyvsp[(1) - (3)].NumInitialiser) * (yyvsp[(3) - (3)].NumInitialiser); ;} - break; - - case 104: - -/* Line 1455 of yacc.c */ -#line 642 "rcomp.yacc" - { (yyval.NumInitialiser) = (yyvsp[(1) - (3)].NumInitialiser) / (yyvsp[(3) - (3)].NumInitialiser); ;} - break; - - case 105: - -/* Line 1455 of yacc.c */ -#line 643 "rcomp.yacc" - { (yyval.NumInitialiser) = (yyvsp[(1) - (3)].NumInitialiser) | (yyvsp[(3) - (3)].NumInitialiser); ;} - break; - - case 106: - -/* Line 1455 of yacc.c */ -#line 644 "rcomp.yacc" - { if (!NumericValue::CheckSigned((yyvsp[(2) - (2)].NumInitialiser),L_LONG)) - { - REGISTER_LINE; - ErrorHandler::OutputErrorLine("Signed value too low"); - exit(1); - } - (yyval.NumInitialiser) = - (yyvsp[(2) - (2)].NumInitialiser); - ;} - break; - - case 107: - -/* Line 1455 of yacc.c */ -#line 652 "rcomp.yacc" - { (yyval.NumInitialiser) = (yyvsp[(2) - (3)].NumInitialiser); ;} - break; - - case 109: - -/* Line 1455 of yacc.c */ -#line 656 "rcomp.yacc" - { - if (strlen((yyval.Value))+strlen((yyvsp[(2) - (2)].Value)) > sizeof((yyval.Value))-1) - { - REGISTER_LINE; - ErrorHandler::OutputErrorLine("String expression is too long"); - exit(1); - } - strcat((yyval.Value), (yyvsp[(2) - (2)].Value)); - ;} - break; - - case 112: - -/* Line 1455 of yacc.c */ -#line 670 "rcomp.yacc" - { - const char * fileName = (*ErrorHandler::GetFileName()).GetBuffer(); - int lineNumber = ErrorHandler::GetLineNumber(); - QualifiedString * thisLabel = new QualifiedString((yyvsp[(1) - (1)].Value), new String(fileName), lineNumber); - // store the label in the UsedIdentifiers array for checking - // whether label was declared - pG->UsedIdentifiers.Add(thisLabel); - - if (pG->EnumValues.IsStored((yyvsp[(1) - (1)].Value))) - { - sprintf((yyval.Value), "%d", pG->EnumValues.FindId((yyvsp[(1) - (1)].Value))); - } - else if (pG->RlsNameIndex.count((yyvsp[(1) - (1)].Value))) // if rls item has already been defined - { - // Found a reference to an rls_string. - RlsValue &rv = pG->RlsValues[pG->RlsNameIndex[(yyvsp[(1) - (1)].Value)]]; - ++rv.iCitationCount; // iCitationCount counts the number of times this rls value has been referneced - // Warn for multiple uses if 'multi' keyword not used. - if (1 < rv.iCitationCount && rv.iCardinality == ERlsCardinalitySingle) - { - Message * message = pG->Messages.GetEntry(LT_001); - String fileLine = *(rv.iFileName); - if(message->GetActivated()) - { - pGL->AddWarningToStore(fileLine, rv.iLineNumber, message->GetMessageOutput()); - } - REGISTER_LINE; - if (!pG->WarningMultiExplained) - { - Message * message = pG->Messages.GetEntry(LT_002); - fileLine = String(*(pFileLineHandler->GetCurrentFile())); - if(message->GetActivated()) - { - pGL->AddWarningToStore(fileLine, pFileLineHandler->GetErrorLine(* pCurrentLineNumber), message->GetMessageOutput()); - pG->WarningMultiExplained = true; - } - } - } - switch (rv.iType) - { - // Strings and numbers are just copied to the next layer up. - case ERlsString: - case ERlsString8: - case ERlsByte: - case ERlsWord: - case ERlsLong: - case ERlsDouble: - strcpy((yyval.Value), rv.iValue.GetBuffer()); - break; - // Anything else is a character: this is converted to a number. - case ERlsStringChar: - case ERlsByteChar: - case ERlsWordChar: - case ERlsLongChar: - SetCharacterLiteral((yyval.Value), rv.iValue); - break; - default: - Message * message = pG->Messages.GetEntry(LT_031); - if(message->GetActivated()) - { - ErrorHandler::OutputErrorLine(message->GetMessageOutput()); - exit(1); - } - break; - } - } - else - { - /* - Could be a reference to another resource, perhaps even a forward reference: - the OverwriteLink functions do FindId again when writing out the data. - Sadly this also permits things which are really syntax errors, inadvertently - converting labels into string literals.. - */ - } - ;} - break; - - case 113: - -/* Line 1455 of yacc.c */ -#line 749 "rcomp.yacc" - { - REGISTER_LINE; - if((yyvsp[(2) - (3)].NumInitialiser) < 0 || ((yyvsp[(2) - (3)].NumInitialiser) > 255 && TargetCharacterSet != String::Unicode)) - { - ErrorHandler::OutputErrorLine("Character code must be a number in the range 0 to 255."); - exit(1); - } - if (TargetCharacterSet != String::Unicode) - { - * (yyval.Value) = char((yyvsp[(2) - (3)].NumInitialiser)); * ((yyval.Value) + 1) = '\0'; - } - else - { - if (SourceCharacterSet == String::CP1252) - { - if ( ((yyvsp[(2) - (3)].NumInitialiser) >= 0x80) && ((yyvsp[(2) - (3)].NumInitialiser) <= 0x9F ) ) // 80-9F are illegal Unicode values. - { - ErrorHandler::OutputErrorLine("Warning: Deprecated non-unicode value in source stream"); - } - * (yyval.Value) = char(UnicodeEscape); - asUTF8((yyval.Value) + 1, (yyvsp[(2) - (3)].NumInitialiser)); - } - else - if (SourceCharacterSet == String::UTF8) - { - asUTF8((yyval.Value), (yyvsp[(2) - (3)].NumInitialiser)); - } - else - { - // Unsatisfactory, but do people use other character sets? - if ((yyvsp[(2) - (3)].NumInitialiser) > 255) - { - ErrorHandler::OutputErrorLine("Don't know how to handle character > 255"); - } - * (yyval.Value) = char((yyvsp[(2) - (3)].NumInitialiser)); * ((yyval.Value) + 1) = '\0'; - } - } - ;} - break; - - case 114: - -/* Line 1455 of yacc.c */ -#line 795 "rcomp.yacc" - { - REGISTER_LINE; - SetIdFromName((yyvsp[(2) - (2)].Value)); - ;} - break; - - case 115: - -/* Line 1455 of yacc.c */ -#line 800 "rcomp.yacc" - { - REGISTER_LINE; - SetIdFromName((yyvsp[(2) - (2)].Value)); - ;} - break; - - case 116: - -/* Line 1455 of yacc.c */ -#line 812 "rcomp.yacc" - { - REGISTER_LINE; - if ((yyvsp[(2) - (2)].NumInitialiser) == 0) - { ErrorHandler::OutputErrorLine("UID2 must be non-zero"); exit(1); } - if (Uid2 != 0) - { ErrorHandler::OutputErrorLine("Warning: overwriting previous UID2 value"); } - Uid2=(yyvsp[(2) - (2)].NumInitialiser); - if(verbose) - { MOFF;cout << "uidX_statement UID2 " << Uid2 << endl;MON;} - ;} - break; - - case 117: - -/* Line 1455 of yacc.c */ -#line 823 "rcomp.yacc" - { - REGISTER_LINE; - if ((yyvsp[(2) - (2)].NumInitialiser) == 0) - { ErrorHandler::OutputErrorLine("UID3 must be non-zero"); exit(1); } - if (Uid3 != 0) - { ErrorHandler::OutputErrorLine("Warning: overwriting previous UID3 value"); } - Uid3=(yyvsp[(2) - (2)].NumInitialiser); - if(verbose) - { MOFF;cout << "uidX_statement UID3 " << Uid3 << endl;MON;} - ;} - break; - - case 118: - -/* Line 1455 of yacc.c */ -#line 844 "rcomp.yacc" - { if(verbose) { MOFF;cout << "character_set_statement " << (yyvsp[(2) - (2)].Value) << endl;MON;} - REGISTER_LINE; - SourceCharacterSet = CharacterSetID((yyvsp[(2) - (2)].Value)); - if ( SourceCharacterSet == String::UNKNOWN ) - { - String err = "Warning: Unrecognised character set name '"; - err += (yyvsp[(2) - (2)].Value); - err += "'"; - ErrorHandler::OutputErrorLine(err); - } - if ( SourceCharacterSet == String::Unicode ) - { - SourceCharacterSet = String::UNKNOWN; - ErrorHandler::OutputErrorLine("Unicode source is unsupported"); - } - ;} - break; - - case 119: - -/* Line 1455 of yacc.c */ -#line 868 "rcomp.yacc" - { if(verbose) { RCTypeArray Types; - MOFF;cout << "offset_statement " << (yyvsp[(2) - (2)].Value) << endl;MON; } - REGISTER_LINE; - CurrentId=((long) NumericValue((yyvsp[(2) - (2)].Value), L_LONG).GetULong() ); - ;} - break; - - case 120: - -/* Line 1455 of yacc.c */ -#line 879 "rcomp.yacc" - { if(verbose) { MOFF;cout << "system_statement" << endl;MON;} - CurrentIdStep=-1; - ;} - break; - - case 123: - -/* Line 1455 of yacc.c */ -#line 893 "rcomp.yacc" - { - if(verbose) - { MOFF;cout << "enum_statement" << endl;MON;} - CurrentEnumName = (yyvsp[(2) - (3)].Value); - CurrentEnumValue=0; - ;} - break; - - case 124: - -/* Line 1455 of yacc.c */ -#line 900 "rcomp.yacc" - { - if(verbose) - { MOFF;cout << "enum_statement" << endl;MON;} - CurrentEnumName = ""; - CurrentEnumValue=0; - ;} - break; - - case 125: - -/* Line 1455 of yacc.c */ -#line 910 "rcomp.yacc" - { - pG->EnumValues.Add((yyvsp[(1) - (1)].Value), CurrentEnumValue++); - pG->AllIdentifiers.Add(new String((yyvsp[(1) - (1)].Value))); // Add label to store - ;} - break; - - case 126: - -/* Line 1455 of yacc.c */ -#line 915 "rcomp.yacc" - { - CurrentEnumValue = atol((yyvsp[(3) - (3)].Value)); - pG->EnumValues.Add((yyvsp[(1) - (3)].Value), CurrentEnumValue); - CurrentEnumValue++; // Increment so that next field has value ($3+1) - pG->AllIdentifiers.Add(new String((yyvsp[(1) - (3)].Value))); // Add label to store - ;} - break; - - case 129: - -/* Line 1455 of yacc.c */ -#line 934 "rcomp.yacc" - { - pG->RlsNameIndex[(yyvsp[(3) - (4)].Value)] = pG->RlsValues.size(); - pG->RlsValues.push_back(RlsValue(ErrorHandler::GetFileName(), - ErrorHandler::GetLineNumber(), (yyvsp[(4) - (4)].Value), (yyvsp[(1) - (4)].RlsType), - (yyvsp[(2) - (4)].RlsQualifiers).iCardinality, (yyvsp[(2) - (4)].RlsQualifiers).iMaxLength)); - if((yyvsp[(2) - (4)].RlsQualifiers).iMaxLength - < String((yyvsp[(4) - (4)].Value)).ExportLength(TargetCharacterSet,SourceCharacterSet)) - { - Message * message = pG->Messages.GetEntry(LT_032); - if(message->GetActivated()) - { - ErrorHandler::OutputErrorLine(message->GetMessageOutput()); - exit(1); - } - } - ;} - break; - - case 130: - -/* Line 1455 of yacc.c */ -#line 951 "rcomp.yacc" - { - Message * message = pG->Messages.GetEntry(LT_033); - String fileName = *(pFileLineHandler->GetCurrentFile()); - int lineNumber = pFileLineHandler->GetErrorLine(* pCurrentLineNumber); - if(message->GetActivated()) - { - pGL->AddWarningToStore(fileName, lineNumber, message->GetMessageOutput()); - } - //... - /* Produce a warning "rls_string used for character constant: use rls_long, rls_word or rls_byte" */ - pG->RlsNameIndex[(yyvsp[(3) - (4)].Value)] = pG->RlsValues.size(); - pG->RlsValues.push_back(RlsValue(ErrorHandler::GetFileName(), - ErrorHandler::GetLineNumber(), (yyvsp[(4) - (4)].Value), ERlsStringChar, - (yyvsp[(2) - (4)].RlsQualifiers).iCardinality)); - ;} - break; - - case 131: - -/* Line 1455 of yacc.c */ -#line 967 "rcomp.yacc" - { - pG->RlsNameIndex[(yyvsp[(3) - (4)].Value)] = pG->RlsValues.size(); - pG->RlsValues.push_back(RlsValue(ErrorHandler::GetFileName(), - ErrorHandler::GetLineNumber(), (yyvsp[(4) - (4)].Value), (yyvsp[(1) - (4)].RlsType), - (yyvsp[(2) - (4)].RlsQualifiers).iCardinality)); - ;} - break; - - case 132: - -/* Line 1455 of yacc.c */ -#line 974 "rcomp.yacc" - { - pG->RlsNameIndex[(yyvsp[(3) - (4)].Value)] = pG->RlsValues.size(); - pG->RlsValues.push_back(RlsValue(ErrorHandler::GetFileName(), - ErrorHandler::GetLineNumber(), (yyvsp[(4) - (4)].Value), (yyvsp[(1) - (4)].RlsType), - (yyvsp[(2) - (4)].RlsQualifiers).iCardinality)); - ;} - break; - - case 133: - -/* Line 1455 of yacc.c */ -#line 981 "rcomp.yacc" - { - TRlsType rlsCharType = (yyvsp[(1) - (4)].RlsType) == ERlsByte? ERlsByteChar - : ( (yyvsp[(1) - (4)].RlsType) == ERlsWord? ERlsWordChar : ERlsLongChar ); - pG->RlsNameIndex[(yyvsp[(3) - (4)].Value)] = pG->RlsValues.size(); - pG->RlsValues.push_back(RlsValue(ErrorHandler::GetFileName(), - ErrorHandler::GetLineNumber(), (yyvsp[(4) - (4)].Value), rlsCharType, - (yyvsp[(2) - (4)].RlsQualifiers).iCardinality)); - ;} - break; - - case 134: - -/* Line 1455 of yacc.c */ -#line 992 "rcomp.yacc" - { - // Register line even if no warning here so that - // the rls_ item knows which line the label was on. - // Without this, the line registered would be the - // line following the declaration. - REGISTER_LINE; - strcpy((yyval.Value), (yyvsp[(1) - (1)].Value)); - - if (pG->RlsNameIndex.count((yyvsp[(1) - (1)].Value)) != 0) - { - Message * message = pG->Messages.GetEntry(LT_003); - if(message->GetActivated()) - { - ErrorHandler::OutputErrorLine(message->GetMessageOutput()); - } - } - pG->AllIdentifiers.Add(new String((yyvsp[(1) - (1)].Value))); // Add label to store - ;} - break; - - case 135: - -/* Line 1455 of yacc.c */ -#line 1013 "rcomp.yacc" - { - NumericValue v((yyvsp[(2) - (4)].Value), L_LONG); - (yyval.RlsQualifiers).iMaxLength = v.GetULong(); - (yyval.RlsQualifiers).iCardinality = (yyvsp[(4) - (4)].RlsQualifiers).iCardinality; - ;} - break; - - case 136: - -/* Line 1455 of yacc.c */ -#line 1019 "rcomp.yacc" - { (yyval.RlsQualifiers) = (yyvsp[(1) - (1)].RlsQualifiers); ;} - break; - - case 137: - -/* Line 1455 of yacc.c */ -#line 1024 "rcomp.yacc" - { - (yyval.RlsQualifiers).iMaxLength = 0xFFFFFFF; - (yyval.RlsQualifiers).iCardinality = ERlsCardinalityMultiple; - ;} - break; - - case 138: - -/* Line 1455 of yacc.c */ -#line 1029 "rcomp.yacc" - { - (yyval.RlsQualifiers).iMaxLength = 0xFFFFFFF; - (yyval.RlsQualifiers).iCardinality = ERlsCardinalitySingle; - ;} - break; - - case 139: - -/* Line 1455 of yacc.c */ -#line 1037 "rcomp.yacc" - { (yyval.RlsType) = ERlsString; ;} - break; - - case 140: - -/* Line 1455 of yacc.c */ -#line 1039 "rcomp.yacc" - { (yyval.RlsType) = ERlsString8; ;} - break; - - case 141: - -/* Line 1455 of yacc.c */ -#line 1044 "rcomp.yacc" - { (yyval.RlsType) = ERlsByte; ;} - break; - - case 142: - -/* Line 1455 of yacc.c */ -#line 1046 "rcomp.yacc" - { (yyval.RlsType) = ERlsWord; ;} - break; - - case 143: - -/* Line 1455 of yacc.c */ -#line 1048 "rcomp.yacc" - { (yyval.RlsType) = ERlsLong; ;} - break; - - case 144: - -/* Line 1455 of yacc.c */ -#line 1053 "rcomp.yacc" - { (yyval.RlsType) = ERlsDouble; ;} - break; - - case 147: - -/* Line 1455 of yacc.c */ -#line 1065 "rcomp.yacc" - {ErrorHandler::Register(pFileLineHandler->GetCurrentFile(), pFileLineHandler->GetErrorLine(*pCurrentLineNumber)); ;} - break; - - case 150: - -/* Line 1455 of yacc.c */ -#line 1075 "rcomp.yacc" - { pGL->StoreComment((yyvsp[(1) - (1)].Value)); ;} - break; - - case 151: - -/* Line 1455 of yacc.c */ -#line 1076 "rcomp.yacc" - { pGL->StoreComment((yyvsp[(1) - (1)].Value)); ;} - break; - - case 152: - -/* Line 1455 of yacc.c */ -#line 1077 "rcomp.yacc" - { pGL->StoreComment((yyvsp[(1) - (1)].Value)); ;} - break; - - - -/* Line 1455 of yacc.c */ -#line 3037 "rcomp.tab.cacc" - default: break; - } - YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); - - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - - *++yyvsp = yyval; - - /* Now `shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; - - goto yynewstate; - - -/*------------------------------------. -| yyerrlab -- here on detecting error | -`------------------------------------*/ -yyerrlab: - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; -#if ! YYERROR_VERBOSE - yyerror (YY_("syntax error")); -#else - { - YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); - if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) - { - YYSIZE_T yyalloc = 2 * yysize; - if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) - yyalloc = YYSTACK_ALLOC_MAXIMUM; - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - yymsg = (char *) YYSTACK_ALLOC (yyalloc); - if (yymsg) - yymsg_alloc = yyalloc; - else - { - yymsg = yymsgbuf; - yymsg_alloc = sizeof yymsgbuf; - } - } - - if (0 < yysize && yysize <= yymsg_alloc) - { - (void) yysyntax_error (yymsg, yystate, yychar); - yyerror (yymsg); - } - else - { - yyerror (YY_("syntax error")); - if (yysize != 0) - goto yyexhaustedlab; - } - } -#endif - } - - - - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse lookahead token after an - error, discard it. */ - - if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } - else - { - yydestruct ("Error: discarding", - yytoken, &yylval); - yychar = YYEMPTY; - } - } - - /* Else will try to reuse lookahead token after shifting the error - token. */ - goto yyerrlab1; - - -/*---------------------------------------------------. -| yyerrorlab -- error raised explicitly by YYERROR. | -`---------------------------------------------------*/ -yyerrorlab: - - /* Pacify compilers like GCC when the user code never invokes - YYERROR and the label yyerrorlab therefore never appears in user - code. */ - if (/*CONSTCOND*/ 0) - goto yyerrorlab; - - /* Do not reclaim the symbols of the rule which action triggered - this YYERROR. */ - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - yystate = *yyssp; - goto yyerrlab1; - - -/*-------------------------------------------------------------. -| yyerrlab1 -- common code for both syntax error and YYERROR. | -`-------------------------------------------------------------*/ -yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ - - for (;;) - { - yyn = yypact[yystate]; - if (yyn != YYPACT_NINF) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; - - - yydestruct ("Error: popping", - yystos[yystate], yyvsp); - YYPOPSTACK (1); - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } - - *++yyvsp = yylval; - - - /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturn; - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturn; - -#if !defined(yyoverflow) || YYERROR_VERBOSE -/*-------------------------------------------------. -| yyexhaustedlab -- memory exhaustion comes here. | -`-------------------------------------------------*/ -yyexhaustedlab: - yyerror (YY_("memory exhausted")); - yyresult = 2; - /* Fall through. */ -#endif - -yyreturn: - if (yychar != YYEMPTY) - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval); - /* Do not reclaim the symbols of the rule which action triggered - this YYABORT or YYACCEPT. */ - YYPOPSTACK (yylen); - YY_STACK_PRINT (yyss, yyssp); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp); - YYPOPSTACK (1); - } -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif -#if YYERROR_VERBOSE - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); -#endif - /* Make sure YYID is used. */ - return YYID (yyresult); -} - - - -/* Line 1675 of yacc.c */ -#line 1080 "rcomp.yacc" - - -// Function section -// ================ - -void asUTF8(char* aUtf8, int aUnicode) - { - if ( aUnicode > 0xffff ) - { - if ( aUnicode > 0x10ffff ) - { - ErrorHandler::OutputErrorLine("Surrogate character code must be a number in the range 0x10000 to 0x10ffff"); - exit(1); - } - - UTF16 high = (UTF16)(0xD7C0 + (aUnicode >> 10)); // high surrogate - UTF16 low = (UTF16)(0xDC00 | (aUnicode & 0x3FF)); // low surrogate - - *aUtf8++ =(char)(0xe0|(high>>12)); - *aUtf8++ =(char)(0x80|((high>>6)&0x3f)); - *aUtf8++ =(char)(0x80|(high&0x3f)); - *aUtf8++ =(char)(0xe0|(low>>12)); - *aUtf8++ =(char)(0x80|((low>>6)&0x3f)); - *aUtf8 =(char)(0x80|(low&0x3f)); - } - else if ((aUnicode & 0xff80) == 0x0000) - { - *aUtf8 = (char)aUnicode; - } - else if ((aUnicode & 0xf800) == 0x0000) - { - *aUtf8++ =(char)(0xc0|(aUnicode>>6)); - *aUtf8 =(char)(0x80|(aUnicode&0x3f)); - } - else - { - *aUtf8++ =(char)(0xe0|(aUnicode>>12)); - *aUtf8++ =(char)(0x80|((aUnicode>>6)&0x3f)); - *aUtf8 =(char)(0x80|(aUnicode&0x3f)); - } - *++aUtf8 = '\0'; - } - - -String::CharacterSet CharacterSetID( const String & character_set_name ) -// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -// Return a character set ID from a character set name. The value UNKNOWN -// is returned if the name is not recognised. -// ---------------------------------------------------------------------------- -{ - String::CharacterSet ids[] = { String::ISOLatin1, String::ASCII, String::CP1252 - , String::CP850, String::ShiftJIS, String::Unicode - , String::UTF8 - , String::UNKNOWN - }; - String names[] = { "ISOLATIN1", "ASCII", "CP1252", "CP850", "SHIFTJIS", "UNICODE", "UTF8" }; - - for ( int i=0; ids[i]!=String::UNKNOWN; i++ ) - { - if ( names[i] == character_set_name ) return ids[i]; - } - - return String::UNKNOWN; - -} // end of CharacterSetID code - -void SetIdFromName( const String & NameStatementValue) - { - // space 0 - // A 1 - // B 2 - // ... - // Z 26 - // - // ABCD corresponds to the number 4321 which becomes ( (4*27 + 3) * 27 + 2) * 27 + 1. - - if(verbose) - { MOFF;cout << "name_statement " << NameStatementValue << endl;MON;} - if ( NameStatementValue.Length() > 4) - { - ErrorHandler::OutputErrorLine( "Name must be no longer than four characters"); - exit( 1); - } - - long NewId = 0; - - for( unsigned long i = 0; i < NameStatementValue.Length(); i++) - { - NewId *= 27; - if ( isalpha( NameStatementValue[i]) ) - NewId += toupper( NameStatementValue[i]) - 'A' + 1; - } - - CurrentId = NewId << 12; - FormatIdAsHex = 1; - if(verbose) - { MOFF;cout << "Current id " << CurrentId << endl;MON;} - } - -void RlsUnusedWarnings() - { - TNameIndex::iterator end = pG->RlsNameIndex.end(); - for (TNameIndex::iterator i = pG->RlsNameIndex.begin(); i != end; ++i) - { - int index = i->second; - RlsValue& v = pG->RlsValues[index]; - if (v.iCitationCount == 0) - { - Message * message = pG->Messages.GetEntry(LT_004); - String fileLine = *(v.iFileName); - if(message->GetActivated()) - { - pGL->AddWarningToStore(fileLine, v.iLineNumber, message->GetMessageOutput()); - } - } - } - } - -int ParseSourceFile(FILE* aFile, unsigned short aYYDebug) - { - // Set up various global pointers which refer to the pG structure - pSHA = & (pG->SHA); - pFileLineHandler = & (pG->FileLineHandler); - pResourceNameIds = & (pG->ResourceNameIds); - - pScan = new rcscan(pG->FileLineHandler, aFile); - - yydebug = aYYDebug; - pCurrentLineNumber = &yylineno; - int ReturnValue = yyparse(); - - RlsUnusedWarnings(); - - int bScanErrorFound = pScan->ErrorWasFound(); - - delete pScan; - pScan = NULL; - - if(ReturnValue != 0) - return ReturnValue; - - if(bScanErrorFound) - return 1; - - return 0; // successful parse - parse tree now in the pG data structure - } - - -void CheckStructUsage() - { - ResourceItemArrayIterator nextRI( *pCurrentRIA); - ResourceItem * pRI; - while ( ( pRI = nextRI() ) != NULL) - { - int resourceItemType = pRI->GetResourceItemType(); - String resourceItemLabel = pRI->GetLabel(); - if( (resourceItemType == EStructTypeResourceItem) || (resourceItemType == EStructArrayResourceItem) ) - { - StringArrayIterator nextLabel( *pUsedLabelsArray); - String * pLabel; - bool flag = false; - while ( ( ( pLabel = nextLabel() ) != NULL ) && (! flag) ) - { - StringLess stringCompare; - if( !stringCompare(resourceItemLabel,*pLabel) && !stringCompare(*pLabel,resourceItemLabel) ) - { - flag = true; - } - } - if(! flag) - { - if(resourceItemType == EStructTypeResourceItem) - { - Message * message = pG->Messages.GetEntry(LT_046); - if(message->GetActivated()) - { - String comment = message->GetMessageOutput(); - comment += "'"; - comment += resourceItemLabel; - comment += "'"; - ErrorHandler::OutputErrorLine(comment); - } - } - else - { - Message * message = pG->Messages.GetEntry(LT_047); - if(message->GetActivated()) - { - String comment = message->GetMessageOutput(); - comment += "'"; - comment += resourceItemLabel; - comment += "'"; - ErrorHandler::OutputErrorLine(comment); - } - } - } - } - } - } - -int yywrap() -{ - return 1; -} - -/* Called by yyparse on error */ -#include -void yyerror (const char *s, ...) -{ - va_list list; - va_start(list, s); - pScan->yyerror(const_cast(s), list); - va_end(list); -} - - - +/* A Bison parser, made by GNU Bison 2.4.1. */ + +/* Skeleton implementation for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 + Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "2.4.1" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + +/* Using locations. */ +#define YYLSP_NEEDED 0 + + + +/* Copy the first part of user declarations. */ + +/* Line 189 of yacc.c */ +#line 1 "rcomp.yacc" + +#include +#include +#include + +#if defined(__MSVCDOTNET__) || defined(__TOOLS2__) +#include +#include +using namespace std; +using std::cout; +using std::endl; +#else //!__MSVCDOTNET__ +#include +#endif //__MSVCDOTNET__ + +#ifdef __VC32__ +#pragma warning( disable : 4065 ) // C4065: switch statement contains 'default' but no 'case' labels +#pragma warning( disable : 4102 ) // C4102: 'yyerrlab1' : unreferenced label +#pragma warning( disable : 4127 ) // C4127: conditional expression is constant +#pragma warning( disable : 4244 ) // C4244: '=' : conversion from 'int' to 'short', possible loss of data +#endif //__VC32__ + +#include "RESOURCE.H" +#include "Parser.h" + +int yylex(); +void yyerror(const char* string, ...); +int yywrap(); +#define YYDEBUG 1 +extern int yylineno; + +#include "rcomp.hpp" +#include "DATATYPE.H" +#include "MEM.H" +#include "RCBINSTR.H" +#include "RCSCAN.H" +#include "ERRORHAN.H" +#include "FILEACC.H" +#include "VERSION.H" +#include "CTABLE.H" +#include "localise.h" +#include "main.h" + +#if defined(__VC32__) && !defined(_DEBUG) +#pragma warning( disable : 4702 ) // unreachable code +#pragma warning( disable : 4102 ) // 'yyerrlabel' : unreferenced label +#pragma warning( disable : 4244 ) // '=' : conversion from 'int' to 'short', possible loss of data +#endif + + + +String::CharacterSet CharacterSetID( const String & character_set_name ); +void asUTF8(char* aUtf8, int aUnicode); +void SetIdFromName( const String & NameStatementValue); +void CheckStructUsage(); + +unsigned short & d = MemCheckControl::iLogMemory; + +StructHeader * pSH; + +StructHeaderArray * pSHA; // Used in resource struct handling functions. +ResourceHeader * pResourceHeader; +ResourceItemArray * pCurrentRIA; +StringArray * pUsedLabelsArray = new StringArray(); +int verbose; +String::CharacterSet SourceCharacterSet = String::CP1252; +String::CharacterSet TargetCharacterSet = String::CP1252; +unsigned short logmemorysetting; +int * pCurrentLineNumber; +FileLineManager * pFileLineHandler; +NameIdMap * pResourceNameIds; +long CurrentEnumValue; +String CurrentEnumName; +char TempStr[300]; +rcscan * pScan; + +int CurrentIdStep=1; +long CurrentId=0; +int FormatIdAsHex=0; // defaults to decimal, changes in SetIdFromName + +unsigned long Uid2=0; +unsigned long Uid3=0; + + + +const String Divider("*******************************************"); + +#define REGISTER_LINE ErrorHandler::Register(pFileLineHandler->GetCurrentFile(), pFileLineHandler->GetErrorLine(* pCurrentLineNumber)) + +// Convert a string containing a character literal in aQuoted +// into a value suitable for LCHAR_LITERAL +void SetCharacterLiteral(char* aOut, const String& aQuoted) + { + UTF16 first; + int length=1; + if (aQuoted.Length() < 1 ) + { + REGISTER_LINE; + ErrorHandler::OutputErrorLine("Warning: Empty Character literal"); + } + if (aQuoted.Length() > 1 ) + { + REGISTER_LINE; + ErrorHandler::OutputErrorLine("Error: String Literal length greater than 1"); + exit(1); + } + if (aQuoted.Export(&first, length, SourceCharacterSet)==0) + { + REGISTER_LINE; + ErrorHandler::OutputErrorLine("Warning: Ignoring trailing characters in character literal"); + } + sprintf(aOut, "%d", first); + } + + + +/* Line 189 of yacc.c */ +#line 205 "rcomp.tab.cacc" + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +/* Enabling the token table. */ +#ifndef YYTOKEN_TABLE +# define YYTOKEN_TABLE 0 +#endif + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + L_STRUCT = 258, + L_RESOURCE = 259, + L_NAME = 260, + L_OFFSET = 261, + L_SYSTEM = 262, + L_GLOBAL = 263, + L_LOCAL = 264, + L_CHARACTER_SET = 265, + L_BUF = 266, + L_WORD = 267, + L_BYTE = 268, + L_LONG = 269, + L_DOUBLE = 270, + L_TEXT = 271, + L_LTEXT = 272, + L_LINK = 273, + L_LLINK = 274, + L_SRLINK = 275, + L_BUF8 = 276, + L_TEXT8 = 277, + L_LTEXT8 = 278, + L_BUF16 = 279, + L_TEXT16 = 280, + L_LTEXT16 = 281, + L_UID_TWO = 282, + L_UID_THREE = 283, + L_RLS_STRING = 284, + L_RLS_STRING8 = 285, + L_RLS_DOUBLE = 286, + L_RLS_BYTE = 287, + L_RLS_WORD = 288, + L_RLS_LONG = 289, + L_MULTI = 290, + L_TAG_START = 291, + L_TAG_END = 292, + L_TAG_COMMAND = 293, + L_TAG_WORD = 294, + L_TAG_NEW_LINE = 295, + L_LABEL = 296, + L_NUM_NATURAL = 297, + L_NUM_FLOAT = 298, + L_NATURAL_EXPR = 299, + L_ENUM = 300, + L_LEN = 301, + L_CHAR_LITERAL = 302, + L_STRING_LITERAL = 303, + UMINUS = 304 + }; +#endif + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE +{ + +/* Line 214 of yacc.c */ +#line 132 "rcomp.yacc" + + char Value[1024*8]; + TValueMaybeRls ValueMaybeRls; + unsigned long Id; + StructItem * pStructItem; + SimpleStructItem * pSimpleStructItem; + ArrayStructItem * pArrayStructItem; + StructArrayStructItem * pStructArrayStructItem; + StringArray * pStringArray; + long NumInitialiser; + TRlsQualifiers RlsQualifiers; + TRlsType RlsType; + + + +/* Line 214 of yacc.c */ +#line 306 "rcomp.tab.cacc" +} YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + + +/* Copy the second part of user declarations. */ + + +/* Line 264 of yacc.c */ +#line 318 "rcomp.tab.cacc" + +#ifdef short +# undef short +#endif + +#ifdef YYTYPE_UINT8 +typedef YYTYPE_UINT8 yytype_uint8; +#else +typedef unsigned char yytype_uint8; +#endif + +#ifdef YYTYPE_INT8 +typedef YYTYPE_INT8 yytype_int8; +#elif (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +typedef signed char yytype_int8; +#else +typedef short int yytype_int8; +#endif + +#ifdef YYTYPE_UINT16 +typedef YYTYPE_UINT16 yytype_uint16; +#else +typedef unsigned short int yytype_uint16; +#endif + +#ifdef YYTYPE_INT16 +typedef YYTYPE_INT16 yytype_int16; +#else +typedef short int yytype_int16; +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned int +# endif +#endif + +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +#ifndef YY_ +# if YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(msgid) dgettext ("bison-runtime", msgid) +# endif +# endif +# ifndef YY_ +# define YY_(msgid) msgid +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(e) ((void) (e)) +#else +# define YYUSE(e) /* empty */ +#endif + +/* Identity function, used to suppress warnings about constant conditions. */ +#ifndef lint +# define YYID(n) (n) +#else +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static int +YYID (int yyi) +#else +static int +YYID (yyi) + int yyi; +#endif +{ + return yyi; +} +#endif + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef _STDLIB_H +# define _STDLIB_H 1 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined _STDLIB_H \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef _STDLIB_H +# define _STDLIB_H 1 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (YYID (0)) +# endif +# endif + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (YYID (0)) + +#endif + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 3 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 303 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 66 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 61 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 152 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 255 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 304 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const yytype_uint8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 58, 59, 51, 49, 65, 50, 2, 52, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 55, + 61, 60, 62, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 64, 2, 63, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 57, 53, 56, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 54 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const yytype_uint16 yyprhs[] = +{ + 0, 0, 3, 5, 8, 11, 12, 15, 18, 21, + 24, 27, 30, 32, 35, 38, 40, 41, 45, 50, + 56, 62, 66, 71, 72, 74, 76, 78, 80, 82, + 87, 91, 98, 101, 107, 109, 111, 113, 115, 117, + 119, 121, 123, 125, 127, 129, 131, 133, 135, 137, + 139, 141, 147, 150, 154, 159, 165, 169, 171, 173, + 176, 178, 182, 187, 193, 198, 201, 204, 206, 210, + 213, 217, 222, 226, 227, 231, 233, 235, 237, 242, + 248, 252, 257, 261, 265, 271, 273, 277, 281, 284, + 286, 290, 294, 297, 299, 301, 303, 305, 307, 311, + 313, 315, 319, 323, 327, 331, 335, 338, 342, 344, + 347, 349, 351, 353, 357, 360, 363, 366, 369, 372, + 375, 377, 381, 386, 390, 393, 395, 399, 402, 407, + 412, 417, 422, 427, 432, 434, 439, 441, 443, 444, + 446, 448, 450, 452, 454, 456, 458, 459, 463, 466, + 467, 469, 471 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yytype_int8 yyrhs[] = +{ + 67, 0, -1, 68, -1, 68, 69, -1, 68, 124, + -1, -1, 71, 70, -1, 85, 70, -1, 109, 70, + -1, 107, 70, -1, 110, 70, -1, 111, 70, -1, + 112, -1, 108, 70, -1, 116, 70, -1, 55, -1, + -1, 72, 73, 56, -1, 3, 41, 123, 57, -1, + 3, 41, 81, 123, 57, -1, 3, 41, 46, 123, + 57, -1, 73, 74, 55, -1, 73, 124, 74, 55, + -1, -1, 75, -1, 78, -1, 82, -1, 83, -1, + 76, -1, 76, 58, 102, 59, -1, 76, 60, 100, + -1, 76, 58, 102, 59, 60, 104, -1, 77, 41, + -1, 77, 61, 103, 62, 41, -1, 13, -1, 12, + -1, 14, -1, 15, -1, 16, -1, 17, -1, 11, + -1, 22, -1, 25, -1, 23, -1, 26, -1, 21, + -1, 24, -1, 18, -1, 19, -1, 20, -1, 79, + -1, 79, 60, 57, 101, 56, -1, 80, 63, -1, + 80, 102, 63, -1, 46, 81, 80, 63, -1, 46, + 81, 80, 102, 63, -1, 77, 41, 64, -1, 13, + -1, 12, -1, 3, 41, -1, 84, -1, 46, 81, + 84, -1, 3, 41, 64, 63, -1, 3, 41, 64, + 102, 63, -1, 86, 57, 88, 56, -1, 8, 87, + -1, 9, 87, -1, 87, -1, 4, 41, 41, -1, + 4, 41, -1, 88, 89, 55, -1, 88, 124, 89, + 55, -1, 88, 1, 55, -1, -1, 41, 60, 100, + -1, 90, -1, 91, -1, 93, -1, 41, 60, 57, + 56, -1, 41, 60, 57, 101, 56, -1, 92, 88, + 56, -1, 41, 60, 41, 57, -1, 94, 95, 56, + -1, 94, 95, 1, -1, 41, 60, 57, 41, 57, + -1, 96, -1, 96, 65, 97, -1, 96, 65, 1, + -1, 88, 56, -1, 98, -1, 97, 65, 98, -1, + 99, 88, 56, -1, 41, 57, -1, 43, -1, 47, + -1, 104, -1, 102, -1, 100, -1, 101, 65, 100, + -1, 103, -1, 42, -1, 103, 49, 103, -1, 103, + 50, 103, -1, 103, 51, 103, -1, 103, 52, 103, + -1, 103, 53, 103, -1, 50, 103, -1, 58, 103, + 59, -1, 105, -1, 105, 104, -1, 48, -1, 106, + -1, 41, -1, 61, 103, 62, -1, 5, 41, -1, + 5, 48, -1, 27, 103, -1, 28, 103, -1, 10, + 41, -1, 6, 102, -1, 7, -1, 113, 115, 56, + -1, 113, 115, 56, 55, -1, 45, 41, 57, -1, + 45, 57, -1, 41, -1, 41, 60, 100, -1, 123, + 114, -1, 115, 65, 123, 114, -1, 120, 118, 117, + 104, -1, 120, 118, 117, 47, -1, 122, 119, 117, + 43, -1, 121, 119, 117, 42, -1, 121, 119, 117, + 47, -1, 41, -1, 61, 42, 62, 119, -1, 119, + -1, 35, -1, -1, 29, -1, 30, -1, 32, -1, + 33, -1, 34, -1, 31, -1, 124, -1, -1, 36, + 125, 37, -1, 125, 126, -1, -1, 40, -1, 38, + -1, 39, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const yytype_uint16 yyrline[] = +{ + 0, 182, 182, 189, 190, 191, 195, 196, 197, 198, + 199, 200, 201, 202, 203, 207, 214, 221, 225, 231, + 237, 245, 249, 253, 256, 257, 258, 259, 262, 263, + 268, 273, 289, 297, 312, 313, 314, 315, 319, 325, + 329, 336, 340, 344, 345, 346, 347, 348, 349, 350, + 353, 354, 372, 375, 380, 388, 399, 407, 408, 411, + 416, 417, 423, 426, 435, 451, 452, 458, 461, 474, + 483, 484, 485, 486, 489, 493, 494, 495, 498, 503, + 531, 537, 548, 552, 556, 569, 570, 571, 574, 579, + 580, 583, 589, 603, 604, 609, 610, 613, 623, 632, + 635, 639, 640, 641, 642, 643, 644, 652, 655, 656, + 667, 668, 669, 748, 794, 799, 811, 822, 844, 868, + 879, 888, 889, 892, 899, 909, 914, 925, 926, 933, + 950, 966, 973, 980, 991, 1012, 1018, 1023, 1029, 1036, + 1038, 1043, 1045, 1047, 1052, 1060, 1061, 1065, 1069, 1071, + 1075, 1076, 1077 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "L_STRUCT", "L_RESOURCE", "L_NAME", + "L_OFFSET", "L_SYSTEM", "L_GLOBAL", "L_LOCAL", "L_CHARACTER_SET", + "L_BUF", "L_WORD", "L_BYTE", "L_LONG", "L_DOUBLE", "L_TEXT", "L_LTEXT", + "L_LINK", "L_LLINK", "L_SRLINK", "L_BUF8", "L_TEXT8", "L_LTEXT8", + "L_BUF16", "L_TEXT16", "L_LTEXT16", "L_UID_TWO", "L_UID_THREE", + "L_RLS_STRING", "L_RLS_STRING8", "L_RLS_DOUBLE", "L_RLS_BYTE", + "L_RLS_WORD", "L_RLS_LONG", "L_MULTI", "L_TAG_START", "L_TAG_END", + "L_TAG_COMMAND", "L_TAG_WORD", "L_TAG_NEW_LINE", "L_LABEL", + "L_NUM_NATURAL", "L_NUM_FLOAT", "L_NATURAL_EXPR", "L_ENUM", "L_LEN", + "L_CHAR_LITERAL", "L_STRING_LITERAL", "'+'", "'-'", "'*'", "'/'", "'|'", + "UMINUS", "';'", "'}'", "'{'", "'('", "')'", "'='", "'<'", "'>'", "']'", + "'['", "','", "$accept", "source", "statement_list", "statement", + "maybe_semicolon", "struct_statement", "struct_statement_start", + "struct_item_list", "struct_item", "simple_struct_item", + "simple_struct_item_start", "data_type", "array_struct_item", + "array_struct_item_base", "array_struct_item_start", "len_declaration", + "struct_type_struct_item", "struct_array_struct_item", + "struct_array_struct_item_base", "resource_statement", + "resource_statement_start", "resource_statement_start_names", + "resource_item_list", "resource_item", "resource_simple_array_item", + "struct_resource_item", "struct_resource_item_start", + "struct_array_resource_item", "struct_array_resource_item_start", + "struct_array_resource_item_list_top", + "struct_array_resource_item_list_top_start", + "struct_array_resource_item_list", + "struct_array_resource_item_list_item", + "struct_array_resource_item_list_item_start", "simple_initialiser", + "simple_initialiser_list", "natural_expression", + "natural_expression_numeric", "string_expression", + "string_expression_item", "character_code_expression", "name_statement", + "uidX_statement", "character_set_statement", "offset_statement", + "system_statement", "enum_statement", "enum_statement_start", + "enum_list_entry", "enum_list", "rls_item_statement", "rls_label", + "rls_qualifiers", "rls_cardinality", "rls_string_item", "rls_num_item", + "rls_float_item", "maybe_comment_tag", "comment_tag", "tag_line", + "tag_word", 0 +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const yytype_uint16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 43, + 45, 42, 47, 124, 304, 59, 125, 123, 40, 41, + 61, 60, 62, 93, 91, 44 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint8 yyr1[] = +{ + 0, 66, 67, 68, 68, 68, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 70, 70, 71, 72, 72, + 72, 73, 73, 73, 74, 74, 74, 74, 75, 75, + 75, 75, 76, 76, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, + 78, 78, 79, 79, 79, 79, 80, 81, 81, 82, + 83, 83, 84, 84, 85, 86, 86, 86, 87, 87, + 88, 88, 88, 88, 89, 89, 89, 89, 90, 90, + 91, 92, 93, 93, 94, 95, 95, 95, 96, 97, + 97, 98, 99, 100, 100, 100, 100, 101, 101, 102, + 103, 103, 103, 103, 103, 103, 103, 103, 104, 104, + 105, 105, 105, 106, 107, 107, 108, 108, 109, 110, + 111, 112, 112, 113, 113, 114, 114, 115, 115, 116, + 116, 116, 116, 116, 117, 118, 118, 119, 119, 120, + 120, 121, 121, 121, 122, 123, 123, 124, 125, 125, + 126, 126, 126 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 1, 2, 2, 0, 2, 2, 2, 2, + 2, 2, 1, 2, 2, 1, 0, 3, 4, 5, + 5, 3, 4, 0, 1, 1, 1, 1, 1, 4, + 3, 6, 2, 5, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 5, 2, 3, 4, 5, 3, 1, 1, 2, + 1, 3, 4, 5, 4, 2, 2, 1, 3, 2, + 3, 4, 3, 0, 3, 1, 1, 1, 4, 5, + 3, 4, 3, 3, 5, 1, 3, 3, 2, 1, + 3, 3, 2, 1, 1, 1, 1, 1, 3, 1, + 1, 3, 3, 3, 3, 3, 2, 3, 1, 2, + 1, 1, 1, 3, 2, 2, 2, 2, 2, 2, + 1, 3, 4, 3, 2, 1, 3, 2, 4, 4, + 4, 4, 4, 4, 1, 4, 1, 1, 0, 1, + 1, 1, 1, 1, 1, 1, 0, 3, 2, 0, + 1, 1, 1 +}; + +/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state + STATE-NUM when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const yytype_uint8 yydefact[] = +{ + 5, 0, 2, 1, 0, 0, 0, 0, 120, 0, + 0, 0, 0, 0, 139, 140, 144, 141, 142, 143, + 149, 0, 3, 16, 23, 16, 0, 67, 16, 16, + 16, 16, 16, 12, 146, 16, 138, 138, 138, 4, + 146, 69, 114, 115, 100, 0, 0, 119, 99, 65, + 66, 118, 116, 117, 0, 0, 124, 15, 6, 0, + 7, 73, 9, 13, 8, 10, 11, 0, 0, 145, + 14, 137, 0, 0, 136, 0, 0, 58, 57, 146, + 146, 0, 68, 106, 0, 0, 0, 0, 0, 0, + 147, 151, 152, 150, 148, 123, 0, 40, 35, 34, + 36, 37, 38, 39, 47, 48, 49, 45, 41, 43, + 46, 42, 44, 0, 17, 0, 24, 28, 0, 25, + 50, 0, 26, 27, 60, 0, 0, 121, 146, 125, + 127, 0, 134, 0, 0, 0, 0, 0, 18, 107, + 101, 102, 103, 104, 105, 59, 0, 21, 0, 0, + 32, 0, 0, 52, 0, 0, 0, 0, 64, 0, + 75, 76, 73, 77, 73, 0, 122, 0, 0, 138, + 112, 130, 110, 0, 129, 108, 111, 132, 133, 131, + 20, 19, 0, 0, 0, 0, 61, 0, 93, 94, + 30, 96, 95, 56, 0, 0, 53, 22, 72, 0, + 70, 0, 0, 0, 85, 0, 128, 126, 135, 0, + 109, 62, 0, 0, 0, 54, 0, 29, 0, 97, + 0, 112, 0, 74, 80, 88, 83, 82, 0, 71, + 113, 63, 55, 0, 33, 51, 0, 81, 112, 78, + 0, 87, 0, 86, 89, 73, 31, 98, 84, 79, + 92, 0, 0, 90, 91 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int16 yydefgoto[] = +{ + -1, 1, 2, 22, 58, 23, 24, 59, 115, 116, + 117, 118, 119, 120, 121, 80, 122, 123, 124, 25, + 26, 27, 126, 159, 160, 161, 162, 163, 164, 203, + 204, 243, 244, 245, 219, 220, 191, 48, 192, 175, + 176, 28, 29, 30, 31, 32, 33, 34, 130, 67, + 35, 133, 73, 74, 36, 37, 38, 68, 69, 54, + 94 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -156 +static const yytype_int16 yypact[] = +{ + -156, 20, 215, -156, -18, 15, 21, 41, -156, 13, + 13, 63, 41, 41, -156, -156, -156, -156, -156, -156, + -156, 4, -156, 27, -156, 27, 59, -156, 27, 27, + 27, 27, 27, -156, -5, 27, -21, 37, 37, -156, + 17, 78, -156, -156, -156, 41, 41, -156, 145, -156, + -156, -156, 145, 145, 74, 66, -156, -156, -156, 132, + -156, -156, -156, -156, -156, -156, -156, 32, 96, -156, + -156, -156, 97, 118, -156, 118, 118, -156, -156, -5, + -5, 124, -156, -156, 81, 41, 41, 41, 41, 41, + -156, -156, -156, -156, -156, -156, 141, -156, -156, -156, + -156, -156, -156, -156, -156, -156, -156, -156, -156, -156, + -156, -156, -156, 80, -156, 129, -156, 62, -19, -156, + 125, -26, -156, -156, -156, 190, 10, 131, -5, 127, + -156, 128, -156, 23, -9, 146, 134, 135, -156, -156, + 34, 34, 164, 164, -156, 162, 250, -156, 41, 236, + 165, 41, 171, -156, 172, 183, 184, 180, -156, 186, + -156, -156, -156, -156, -156, 211, -156, 96, 236, 37, + -156, -156, -156, 41, -156, -20, -156, -156, -156, -156, + -156, -156, -24, 213, 214, 31, -156, 197, -156, -156, + -156, -156, -156, -156, 76, 236, -156, -156, -156, 60, + -156, 11, 18, 12, 192, 203, -156, -156, -156, 121, + -156, -156, 196, 162, 165, -156, 217, 221, 241, -156, + 40, 228, 119, -156, -156, -156, -156, -156, 14, -156, + -156, -156, -156, -20, -156, -156, 236, -156, 230, -156, + 44, -156, 231, 224, -156, -156, -156, -156, -156, -156, + -156, 249, 24, -156, -156 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yytype_int16 yypgoto[] = +{ + -156, -156, -156, -156, 202, -156, -156, -156, 166, -156, + -156, 147, -156, -156, 149, 179, -156, -156, 150, -156, + -156, 155, -155, 133, -156, -156, -156, -156, -156, -156, + -156, -156, 48, -156, -141, 79, -6, -10, -127, -156, + -156, -156, -156, -156, -156, -156, -156, -156, 136, -156, + -156, -32, -156, -33, -156, -156, -156, -30, -2, -156, + -156 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If zero, do what YYDEFACT says. + If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -1 +static const yytype_uint8 yytable[] = +{ + 39, 47, 52, 53, 75, 76, 174, 201, 190, 202, + 81, 156, 156, 226, 71, 241, 44, 5, 44, 156, + 3, 170, 150, 40, 45, 156, 45, 207, 172, 77, + 78, 20, 46, 177, 46, 83, 84, 153, 178, 211, + 72, 173, 151, 134, 135, 55, 20, 20, 210, 136, + 137, 157, 157, 20, 20, 242, 41, 125, 223, 157, + 20, 56, 42, 79, 170, 157, 158, 224, 227, 43, + 171, 172, 71, 44, 225, 140, 141, 142, 143, 144, + 254, 45, 57, 44, 173, 87, 88, 89, 127, 46, + 252, 45, 77, 78, 215, 247, 235, 128, 167, 46, + 249, 221, 44, 188, 51, 236, 246, 189, 172, 236, + 45, 90, 91, 92, 93, 154, 61, 222, 46, 82, + 148, 173, 149, 95, 165, 85, 86, 87, 88, 89, + 85, 86, 87, 88, 89, 96, 208, 129, 218, 131, + 139, 194, 187, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, 112, 132, + 238, 44, 188, 209, 49, 50, 189, 172, 20, 45, + 85, 86, 87, 88, 89, 239, 212, 46, 113, 216, + 173, 138, 145, 230, 147, 152, 166, 168, 114, 179, + 169, 180, 181, 96, 85, 86, 87, 88, 89, 165, + 165, 97, 98, 99, 100, 101, 102, 103, 104, 105, + 106, 107, 108, 109, 110, 111, 112, 89, 4, 5, + 6, 7, 8, 9, 10, 11, 182, 60, 195, 193, + 62, 63, 64, 65, 66, 196, 113, 70, 197, 198, + 199, 200, 12, 13, 14, 15, 16, 17, 18, 19, + 165, 20, 157, 183, 213, 214, 217, 228, 229, 231, + 21, 97, 98, 99, 100, 101, 102, 103, 104, 105, + 106, 107, 108, 109, 110, 111, 112, 170, 44, 188, + 232, 233, 234, 189, 172, 237, 45, 248, 250, 251, + 242, 155, 146, 184, 46, 185, 186, 173, 205, 253, + 0, 240, 0, 206 +}; + +static const yytype_int16 yycheck[] = +{ + 2, 7, 12, 13, 37, 38, 133, 162, 149, 164, + 40, 1, 1, 1, 35, 1, 42, 4, 42, 1, + 0, 41, 41, 41, 50, 1, 50, 168, 48, 12, + 13, 36, 58, 42, 58, 45, 46, 63, 47, 63, + 61, 61, 61, 75, 76, 41, 36, 36, 175, 79, + 80, 41, 41, 36, 36, 41, 41, 59, 199, 41, + 36, 57, 41, 46, 41, 41, 56, 56, 56, 48, + 47, 48, 35, 42, 56, 85, 86, 87, 88, 89, + 56, 50, 55, 42, 61, 51, 52, 53, 56, 58, + 245, 50, 12, 13, 63, 236, 56, 65, 128, 58, + 56, 41, 42, 43, 41, 65, 233, 47, 48, 65, + 50, 37, 38, 39, 40, 121, 57, 57, 58, 41, + 58, 61, 60, 57, 126, 49, 50, 51, 52, 53, + 49, 50, 51, 52, 53, 3, 169, 41, 62, 42, + 59, 151, 148, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 41, + 41, 42, 43, 173, 9, 10, 47, 48, 36, 50, + 49, 50, 51, 52, 53, 56, 182, 58, 46, 185, + 61, 57, 41, 62, 55, 60, 55, 60, 56, 43, + 62, 57, 57, 3, 49, 50, 51, 52, 53, 201, + 202, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 53, 3, 4, + 5, 6, 7, 8, 9, 10, 64, 25, 57, 64, + 28, 29, 30, 31, 32, 63, 46, 35, 55, 55, + 60, 55, 27, 28, 29, 30, 31, 32, 33, 34, + 252, 36, 41, 3, 41, 41, 59, 65, 55, 63, + 45, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 41, 42, 43, + 63, 60, 41, 47, 48, 57, 50, 57, 57, 65, + 41, 125, 113, 146, 58, 146, 146, 61, 165, 251, + -1, 222, -1, 167 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint8 yystos[] = +{ + 0, 67, 68, 0, 3, 4, 5, 6, 7, 8, + 9, 10, 27, 28, 29, 30, 31, 32, 33, 34, + 36, 45, 69, 71, 72, 85, 86, 87, 107, 108, + 109, 110, 111, 112, 113, 116, 120, 121, 122, 124, + 41, 41, 41, 48, 42, 50, 58, 102, 103, 87, + 87, 41, 103, 103, 125, 41, 57, 55, 70, 73, + 70, 57, 70, 70, 70, 70, 70, 115, 123, 124, + 70, 35, 61, 118, 119, 119, 119, 12, 13, 46, + 81, 123, 41, 103, 103, 49, 50, 51, 52, 53, + 37, 38, 39, 40, 126, 57, 3, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 46, 56, 74, 75, 76, 77, 78, + 79, 80, 82, 83, 84, 124, 88, 56, 65, 41, + 114, 42, 41, 117, 117, 117, 123, 123, 57, 59, + 103, 103, 103, 103, 103, 41, 81, 55, 58, 60, + 41, 61, 60, 63, 102, 74, 1, 41, 56, 89, + 90, 91, 92, 93, 94, 124, 55, 123, 60, 62, + 41, 47, 48, 61, 104, 105, 106, 42, 47, 43, + 57, 57, 64, 3, 77, 80, 84, 102, 43, 47, + 100, 102, 104, 64, 103, 57, 63, 55, 55, 60, + 55, 88, 88, 95, 96, 89, 114, 100, 119, 103, + 104, 63, 102, 41, 41, 63, 102, 59, 62, 100, + 101, 41, 57, 100, 56, 56, 1, 56, 65, 55, + 62, 63, 63, 60, 41, 56, 65, 57, 41, 56, + 101, 1, 41, 97, 98, 99, 104, 100, 57, 56, + 57, 65, 88, 98, 56 +}; + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. */ + +#define YYFAIL goto yyerrlab + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ + YYPOPSTACK (1); \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ +while (YYID (0)) + + +#define YYTERROR 1 +#define YYERRCODE 256 + + +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +#define YYRHSLOC(Rhs, K) ((Rhs)[K]) +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (YYID (N)) \ + { \ + (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + } \ + else \ + { \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC (Rhs, 0).last_column; \ + } \ + while (YYID (0)) +#endif + + +/* YY_LOCATION_PRINT -- Print the location on the stream. + This macro was not mandated originally: define only if we know + we won't break user code: when these are the locations we know. */ + +#ifndef YY_LOCATION_PRINT +# if YYLTYPE_IS_TRIVIAL +# define YY_LOCATION_PRINT(File, Loc) \ + fprintf (File, "%d.%d-%d.%d", \ + (Loc).first_line, (Loc).first_column, \ + (Loc).last_line, (Loc).last_column) +# else +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +# endif +#endif + + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (YYLEX_PARAM) +#else +# define YYLEX yylex () +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (YYID (0)) + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (YYID (0)) + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +#else +static void +yy_symbol_value_print (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; +#endif +{ + if (!yyvaluep) + return; +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# else + YYUSE (yyoutput); +# endif + switch (yytype) + { + default: + break; + } +} + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +#else +static void +yy_symbol_print (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; +#endif +{ + if (yytype < YYNTOKENS) + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + yy_symbol_value_print (yyoutput, yytype, yyvaluep); + YYFPRINTF (yyoutput, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +#else +static void +yy_stack_print (yybottom, yytop) + yytype_int16 *yybottom; + yytype_int16 *yytop; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (YYID (0)) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_reduce_print (YYSTYPE *yyvsp, int yyrule) +#else +static void +yy_reduce_print (yyvsp, yyrule) + YYSTYPE *yyvsp; + int yyrule; +#endif +{ + int yynrhs = yyr2[yyrule]; + int yyi; + unsigned long int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], + &(yyvsp[(yyi + 1) - (yynrhs)]) + ); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyvsp, Rule); \ +} while (YYID (0)) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static YYSIZE_T +yystrlen (const char *yystr) +#else +static YYSIZE_T +yystrlen (yystr) + const char *yystr; +#endif +{ + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static char * +yystpcpy (char *yydest, const char *yysrc) +#else +static char * +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +#endif +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYSIZE_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return yystpcpy (yyres, yystr) - yyres; +} +# endif + +/* Copy into YYRESULT an error message about the unexpected token + YYCHAR while in state YYSTATE. Return the number of bytes copied, + including the terminating null byte. If YYRESULT is null, do not + copy anything; just return the number of bytes that would be + copied. As a special case, return 0 if an ordinary "syntax error" + message will do. Return YYSIZE_MAXIMUM if overflow occurs during + size calculation. */ +static YYSIZE_T +yysyntax_error (char *yyresult, int yystate, int yychar) +{ + int yyn = yypact[yystate]; + + if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) + return 0; + else + { + int yytype = YYTRANSLATE (yychar); + YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); + YYSIZE_T yysize = yysize0; + YYSIZE_T yysize1; + int yysize_overflow = 0; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + int yyx; + +# if 0 + /* This is so xgettext sees the translatable formats that are + constructed on the fly. */ + YY_("syntax error, unexpected %s"); + YY_("syntax error, unexpected %s, expecting %s"); + YY_("syntax error, unexpected %s, expecting %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); +# endif + char *yyfmt; + char const *yyf; + static char const yyunexpected[] = "syntax error, unexpected %s"; + static char const yyexpecting[] = ", expecting %s"; + static char const yyor[] = " or %s"; + char yyformat[sizeof yyunexpected + + sizeof yyexpecting - 1 + + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) + * (sizeof yyor - 1))]; + char const *yyprefix = yyexpecting; + + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yycount = 1; + + yyarg[0] = yytname[yytype]; + yyfmt = yystpcpy (yyformat, yyunexpected); + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + yyformat[sizeof yyunexpected - 1] = '\0'; + break; + } + yyarg[yycount++] = yytname[yyx]; + yysize1 = yysize + yytnamerr (0, yytname[yyx]); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; + yyfmt = yystpcpy (yyfmt, yyprefix); + yyprefix = yyor; + } + + yyf = YY_(yyformat); + yysize1 = yysize + yystrlen (yyf); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; + + if (yysize_overflow) + return YYSIZE_MAXIMUM; + + if (yyresult) + { + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + char *yyp = yyresult; + int yyi = 0; + while ((*yyp = *yyf) != '\0') + { + if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyf += 2; + } + else + { + yyp++; + yyf++; + } + } + } + return yysize; + } +} +#endif /* YYERROR_VERBOSE */ + + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +#else +static void +yydestruct (yymsg, yytype, yyvaluep) + const char *yymsg; + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + YYUSE (yyvaluep); + + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + switch (yytype) + { + + default: + break; + } +} + +/* Prevent warnings from -Wmissing-prototypes. */ +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int yyparse (void *YYPARSE_PARAM); +#else +int yyparse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int yyparse (void); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + + +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; + +/* Number of syntax errors so far. */ +int yynerrs; + + + +/*-------------------------. +| yyparse or yypush_parse. | +`-------------------------*/ + +#ifdef YYPARSE_PARAM +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void *YYPARSE_PARAM) +#else +int +yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +#endif +#else /* ! YYPARSE_PARAM */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void) +#else +int +yyparse () + +#endif +#endif +{ + + + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: + `yyss': related to states. + `yyvs': related to semantic values. + + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; + + YYSIZE_T yystacksize; + + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + yytoken = 0; + yyss = yyssa; + yyvs = yyvsa; + yystacksize = YYINITDEPTH; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + yyssp = yyss; + yyvsp = yyvs; + + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyexhaustedlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yyn == YYPACT_NINF) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yyn == 0 || yyn == YYTABLE_NINF) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the shifted token. */ + yychar = YYEMPTY; + + yystate = yyn; + *++yyvsp = yylval; + + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 2: + +/* Line 1455 of yacc.c */ +#line 182 "rcomp.yacc" + { if(verbose) { MOFF; cout << Divider << "\n" << Divider << endl; MON; } + ;} + break; + + case 15: + +/* Line 1455 of yacc.c */ +#line 208 "rcomp.yacc" + { + // This is my gift to the world: no more "syntax error" for adding + // an extra semicolon at the end of a struct or resource. + REGISTER_LINE; + ErrorHandler::OutputErrorLine("Warning: unnecessary semicolon"); + ;} + break; + + case 17: + +/* Line 1455 of yacc.c */ +#line 222 "rcomp.yacc" + { if(verbose) { MOFF; cout << Divider << "\n" << * pSH << Divider << endl; MON;} ;} + break; + + case 18: + +/* Line 1455 of yacc.c */ +#line 226 "rcomp.yacc" + { if(verbose) { MOFF;cout << "struct_statement_start " << (yyvsp[(2) - (4)].Value) << endl; MON;} + pSH = new StructHeader((yyvsp[(2) - (4)].Value)); + REGISTER_LINE; + pG->SHA.Add(pSH); + ;} + break; + + case 19: + +/* Line 1455 of yacc.c */ +#line 232 "rcomp.yacc" + { if(verbose) { RCTypeArray Types; MOFF;cout << "struct_statement_start " << (yyvsp[(2) - (5)].Value) << " " << Types.GetName((yyvsp[(3) - (5)].Id)) << endl; MON;} + pSH = new StructHeader((yyvsp[(2) - (5)].Value), (yyvsp[(3) - (5)].Id)); + REGISTER_LINE; + pG->SHA.Add(pSH); + ;} + break; + + case 20: + +/* Line 1455 of yacc.c */ +#line 238 "rcomp.yacc" + { if(verbose) { MOFF;cout << "struct_statement_start " << (yyvsp[(2) - (5)].Value) << " (WORD)" << endl; MON;} + pSH = new StructHeader((yyvsp[(2) - (5)].Value), L_WORD); + REGISTER_LINE; + pG->SHA.Add(pSH); + ;} + break; + + case 21: + +/* Line 1455 of yacc.c */ +#line 245 "rcomp.yacc" + { if(verbose) { MOFF;cout << "struct_item_list Adding struct_item." << endl; MON;} + REGISTER_LINE; + pSH->iSIA.Add((yyvsp[(2) - (3)].pStructItem)); + ;} + break; + + case 22: + +/* Line 1455 of yacc.c */ +#line 249 "rcomp.yacc" + { if(verbose) { MOFF;cout << "tagged struct_item_list Adding struct_item." << endl; MON;} + REGISTER_LINE; + pSH->iSIA.Add((yyvsp[(3) - (4)].pStructItem)); + ;} + break; + + case 28: + +/* Line 1455 of yacc.c */ +#line 262 "rcomp.yacc" + { (yyval.pStructItem) = (yyvsp[(1) - (1)].pSimpleStructItem);;} + break; + + case 29: + +/* Line 1455 of yacc.c */ +#line 264 "rcomp.yacc" + { if(verbose) { MOFF;cout << " Limit: " << (yyvsp[(3) - (4)].Value) << endl; MON;} + (yyvsp[(1) - (4)].pSimpleStructItem)->iLengthLimit = (yyvsp[(3) - (4)].Value); + (yyval.pStructItem) = (yyvsp[(1) - (4)].pSimpleStructItem); + ;} + break; + + case 30: + +/* Line 1455 of yacc.c */ +#line 269 "rcomp.yacc" + { if(verbose) { MOFF;cout << " Default: " << (yyvsp[(3) - (3)].Value) << endl; MON;} + (yyvsp[(1) - (3)].pSimpleStructItem)->iDefault = (yyvsp[(3) - (3)].Value); + (yyval.pStructItem) = (yyvsp[(1) - (3)].pSimpleStructItem); + ;} + break; + + case 31: + +/* Line 1455 of yacc.c */ +#line 274 "rcomp.yacc" + { if(verbose) { MOFF;cout << " Limit: " << (yyvsp[(3) - (6)].Value) << ", Default: " << (yyvsp[(6) - (6)].Value) << endl; MON;} + NumericValue Limit((yyvsp[(3) - (6)].Value), L_LONG); + if(String((yyvsp[(6) - (6)].Value)).ExportLength(TargetCharacterSet,SourceCharacterSet) > Limit.GetULong() ) + { + REGISTER_LINE; + ErrorHandler::OutputErrorLine("Text length exceeds specified limit"); + exit(1); + } + (yyvsp[(1) - (6)].pSimpleStructItem)->iLengthLimit = (yyvsp[(3) - (6)].Value); + (yyvsp[(1) - (6)].pSimpleStructItem)->iDefault = (yyvsp[(6) - (6)].Value); + (yyval.pStructItem) = (yyvsp[(1) - (6)].pSimpleStructItem); + ;} + break; + + case 32: + +/* Line 1455 of yacc.c */ +#line 289 "rcomp.yacc" + { if(verbose) + { + RCTypeArray Types; + MOFF;cout << "simple_struct_item " << Types.GetName((yyvsp[(1) - (2)].Id)) << " " << (yyvsp[(2) - (2)].Value) << endl; MON; + } + (yyval.pSimpleStructItem) = new SimpleStructItem((yyvsp[(1) - (2)].Id),(yyvsp[(2) - (2)].Value)); + assert((yyval.pSimpleStructItem) != NULL); + ;} + break; + + case 33: + +/* Line 1455 of yacc.c */ +#line 298 "rcomp.yacc" + { if(verbose) + { RCTypeArray Types; + MOFF;cout << "simple_struct_item " << Types.GetName((yyvsp[(1) - (5)].Id)) << " " << (yyvsp[(5) - (5)].Value) << endl; MON; + } + String s(NumericValue::ltoa((yyvsp[(3) - (5)].NumInitialiser))); + (yyval.pSimpleStructItem) = new SimpleStructItem((yyvsp[(1) - (5)].Id),(yyvsp[(5) - (5)].Value),s); + assert((yyval.pSimpleStructItem) != NULL); + ;} + break; + + case 34: + +/* Line 1455 of yacc.c */ +#line 312 "rcomp.yacc" + { (yyval.Id) = L_BYTE;;} + break; + + case 35: + +/* Line 1455 of yacc.c */ +#line 313 "rcomp.yacc" + { (yyval.Id) = L_WORD;;} + break; + + case 36: + +/* Line 1455 of yacc.c */ +#line 314 "rcomp.yacc" + { (yyval.Id) = L_LONG;;} + break; + + case 37: + +/* Line 1455 of yacc.c */ +#line 315 "rcomp.yacc" + { (yyval.Id) = L_DOUBLE;;} + break; + + case 38: + +/* Line 1455 of yacc.c */ +#line 320 "rcomp.yacc" + { + (yyval.Id) = ( TargetCharacterSet == String::Unicode ) ? L_TEXT16: L_TEXT8; + REGISTER_LINE; + ErrorHandler::OutputErrorLine("Warning: Deprecated use of zero-terminated TEXT - use LTEXT instead"); + ;} + break; + + case 39: + +/* Line 1455 of yacc.c */ +#line 326 "rcomp.yacc" + { + (yyval.Id) = ( TargetCharacterSet == String::Unicode ) ? L_LTEXT16: L_LTEXT8; + ;} + break; + + case 40: + +/* Line 1455 of yacc.c */ +#line 330 "rcomp.yacc" + { + (yyval.Id) = ( TargetCharacterSet == String::Unicode ) ? L_BUF16: L_BUF8; + ;} + break; + + case 41: + +/* Line 1455 of yacc.c */ +#line 336 "rcomp.yacc" + { (yyval.Id) = L_TEXT8; + REGISTER_LINE; + ErrorHandler::OutputErrorLine("Warning: Deprecated use of zero-terminated TEXT8 - use LTEXT8 instead"); + ;} + break; + + case 42: + +/* Line 1455 of yacc.c */ +#line 340 "rcomp.yacc" + { (yyval.Id) = L_TEXT16; + REGISTER_LINE; + ErrorHandler::OutputErrorLine("Warning: Deprecated use of zero-terminated TEXT16 - use LTEXT16 instead"); + ;} + break; + + case 43: + +/* Line 1455 of yacc.c */ +#line 344 "rcomp.yacc" + { (yyval.Id) = L_LTEXT8;;} + break; + + case 44: + +/* Line 1455 of yacc.c */ +#line 345 "rcomp.yacc" + { (yyval.Id) = L_LTEXT16;;} + break; + + case 45: + +/* Line 1455 of yacc.c */ +#line 346 "rcomp.yacc" + { (yyval.Id) = L_BUF8;;} + break; + + case 46: + +/* Line 1455 of yacc.c */ +#line 347 "rcomp.yacc" + { (yyval.Id) = L_BUF16;;} + break; + + case 47: + +/* Line 1455 of yacc.c */ +#line 348 "rcomp.yacc" + { (yyval.Id) = L_LINK;;} + break; + + case 48: + +/* Line 1455 of yacc.c */ +#line 349 "rcomp.yacc" + { (yyval.Id) = L_LLINK;;} + break; + + case 49: + +/* Line 1455 of yacc.c */ +#line 350 "rcomp.yacc" + { (yyval.Id) = L_SRLINK;;} + break; + + case 50: + +/* Line 1455 of yacc.c */ +#line 353 "rcomp.yacc" + { (yyval.pStructItem) = (yyvsp[(1) - (1)].pArrayStructItem);;} + break; + + case 51: + +/* Line 1455 of yacc.c */ +#line 355 "rcomp.yacc" + { if(verbose) { MOFF;cout << "array_struct_item with simple_initialiser_list" << endl;MON;} + (yyvsp[(1) - (5)].pArrayStructItem)->iDefaults = * (yyvsp[(4) - (5)].pStringArray); + if((yyvsp[(1) - (5)].pArrayStructItem)->iSize.Length() > 0) + { + NumericValue v((yyvsp[(1) - (5)].pArrayStructItem)->iSize, L_LONG); + REGISTER_LINE; + if((yyvsp[(4) - (5)].pStringArray)->Size()!=long(v.GetULong())) + { + ErrorHandler::OutputErrorLine("Size does not match number of initialisers"); + exit(1); + } + } + (yyval.pStructItem) = (yyvsp[(1) - (5)].pArrayStructItem); + delete (yyvsp[(4) - (5)].pStringArray); + ;} + break; + + case 52: + +/* Line 1455 of yacc.c */ +#line 372 "rcomp.yacc" + { if(verbose) { MOFF;cout << "array_struct_item_base with no size" << endl;MON;} + (yyval.pArrayStructItem) =(yyvsp[(1) - (2)].pArrayStructItem); + ;} + break; + + case 53: + +/* Line 1455 of yacc.c */ +#line 376 "rcomp.yacc" + { if(verbose) { MOFF;cout << "array_struct_item_base with size " << (yyvsp[(2) - (3)].Value) << endl;MON;} + (yyvsp[(1) - (3)].pArrayStructItem)->iSize = (yyvsp[(2) - (3)].Value); + (yyval.pArrayStructItem) = (yyvsp[(1) - (3)].pArrayStructItem); + ;} + break; + + case 54: + +/* Line 1455 of yacc.c */ +#line 381 "rcomp.yacc" + { if(verbose) + { RCTypeArray Types; + MOFF;cout << "array_struct_item_base with LenType " << Types.GetName((yyvsp[(2) - (4)].Id)) << endl;MON; + } + (yyvsp[(3) - (4)].pArrayStructItem)->iLenType = (yyvsp[(2) - (4)].Id); + (yyval.pArrayStructItem) = (yyvsp[(3) - (4)].pArrayStructItem); + ;} + break; + + case 55: + +/* Line 1455 of yacc.c */ +#line 389 "rcomp.yacc" + { if(verbose) + { RCTypeArray Types; + MOFF;cout << "array_struct_item_base with size " << (yyvsp[(4) - (5)].Value) << " and LenType " << Types.GetName((yyvsp[(2) - (5)].Id)) << endl;MON; + } + (yyvsp[(3) - (5)].pArrayStructItem)->iLenType = (yyvsp[(2) - (5)].Id); + (yyvsp[(3) - (5)].pArrayStructItem)->iSize = (yyvsp[(4) - (5)].Value); + (yyval.pArrayStructItem) = (yyvsp[(3) - (5)].pArrayStructItem); + ;} + break; + + case 56: + +/* Line 1455 of yacc.c */ +#line 399 "rcomp.yacc" + { if(verbose) + { RCTypeArray Types; + MOFF;cout << "array_struct_item_start " << Types.GetName((yyvsp[(1) - (3)].Id)) << " " << (yyvsp[(2) - (3)].Value) << endl;MON; + } + (yyval.pArrayStructItem) = new ArrayStructItem((yyvsp[(1) - (3)].Id), (yyvsp[(2) - (3)].Value)); + ;} + break; + + case 57: + +/* Line 1455 of yacc.c */ +#line 407 "rcomp.yacc" + { (yyval.Id) = L_BYTE;;} + break; + + case 58: + +/* Line 1455 of yacc.c */ +#line 408 "rcomp.yacc" + { (yyval.Id) = L_WORD;;} + break; + + case 59: + +/* Line 1455 of yacc.c */ +#line 411 "rcomp.yacc" + { if(verbose) { MOFF;cout << "struct_type_struct_item " << (yyvsp[(2) - (2)].Value) << endl;MON;} + (yyval.pStructItem) = new StructTypeStructItem((yyvsp[(2) - (2)].Value)); + ;} + break; + + case 60: + +/* Line 1455 of yacc.c */ +#line 416 "rcomp.yacc" + { (yyval.pStructItem) = (yyvsp[(1) - (1)].pStructArrayStructItem);;} + break; + + case 61: + +/* Line 1455 of yacc.c */ +#line 418 "rcomp.yacc" + { if(verbose) { RCTypeArray Types; MOFF;cout << "struct_array_struct_item - Setting Size to " << Types.GetName((yyvsp[(2) - (3)].Id)) << endl;MON;} + (yyvsp[(3) - (3)].pStructArrayStructItem)->iLenType = (yyvsp[(2) - (3)].Id); (yyval.pStructItem) = (yyvsp[(3) - (3)].pStructArrayStructItem); + ;} + break; + + case 62: + +/* Line 1455 of yacc.c */ +#line 423 "rcomp.yacc" + { if(verbose) { MOFF;cout << "struct_array_struct_item_base " << (yyvsp[(2) - (4)].Value) << endl;MON;} + (yyval.pStructArrayStructItem) = new StructArrayStructItem((yyvsp[(2) - (4)].Value)); + ;} + break; + + case 63: + +/* Line 1455 of yacc.c */ +#line 427 "rcomp.yacc" + { if(verbose) { MOFF;cout << "struct_array_struct_item_base " << (yyvsp[(2) - (5)].Value) << " " << (yyvsp[(4) - (5)].Value) << endl;MON;} + (yyval.pStructArrayStructItem) = new StructArrayStructItem((yyvsp[(2) - (5)].Value), (yyvsp[(4) - (5)].Value)); + ;} + break; + + case 64: + +/* Line 1455 of yacc.c */ +#line 436 "rcomp.yacc" + { + pResourceHeader->AddDefault(); + CurrentId+=CurrentIdStep; + if(verbose) { MOFF;cout << "Resource ID "<< CurrentId << endl << Divider << "\n" << * pResourceHeader << Divider << endl;MON;} + pResourceHeader->SetResourceId(*pResourceNameIds,CurrentId,FormatIdAsHex); + pG->Index.Add(pResourceHeader); + + CheckStructUsage(); + + pUsedLabelsArray->Empty(); + + pResourceHeader = NULL; + ;} + break; + + case 65: + +/* Line 1455 of yacc.c */ +#line 451 "rcomp.yacc" + {;} + break; + + case 66: + +/* Line 1455 of yacc.c */ +#line 453 "rcomp.yacc" + { + if(verbose) { MOFF;cout << "resource_statement_start LOCAL" << endl;MON;} + assert(pResourceHeader != NULL); + pResourceHeader->iLocal = 1; + ;} + break; + + case 67: + +/* Line 1455 of yacc.c */ +#line 458 "rcomp.yacc" + {;} + break; + + case 68: + +/* Line 1455 of yacc.c */ +#line 461 "rcomp.yacc" + { if(verbose) { MOFF;cout << "resource_statement_start_names " << (yyvsp[(2) - (3)].Value) << " " << (yyvsp[(3) - (3)].Value) << endl;MON;} + assert(pResourceHeader == NULL); + pResourceHeader = new ResourceHeader((yyvsp[(3) - (3)].Value)); + pCurrentRIA = & (pResourceHeader->iRIA); + REGISTER_LINE; + if(pResourceNameIds->IsStored((yyvsp[(3) - (3)].Value))) + { + ErrorHandler::OutputErrorLine("Resource with this name encountered already"); + exit(1); + } + pCurrentRIA->FillFromStruct((yyvsp[(2) - (3)].Value)); + pG->AllIdentifiers.Add(new String((yyvsp[(3) - (3)].Value))); // Add label to store + ;} + break; + + case 69: + +/* Line 1455 of yacc.c */ +#line 474 "rcomp.yacc" + { if(verbose) { MOFF;cout << "resource_statement_start_names " << (yyvsp[(2) - (2)].Value) << " " << endl;MON;} + assert(pResourceHeader == NULL); + pResourceHeader = new ResourceHeader; + pCurrentRIA = & (pResourceHeader->iRIA); + REGISTER_LINE; + pCurrentRIA->FillFromStruct((yyvsp[(2) - (2)].Value)); + ;} + break; + + case 70: + +/* Line 1455 of yacc.c */ +#line 483 "rcomp.yacc" + { if(verbose) { MOFF;cout << "resource_item_list" << endl;MON;};} + break; + + case 71: + +/* Line 1455 of yacc.c */ +#line 484 "rcomp.yacc" + { if(verbose) { MOFF;cout << "tagged resource_item_list" << endl;MON;};} + break; + + case 72: + +/* Line 1455 of yacc.c */ +#line 485 "rcomp.yacc" + { yyerrok; yyclearin; ;} + break; + + case 74: + +/* Line 1455 of yacc.c */ +#line 489 "rcomp.yacc" + { if(verbose) { MOFF;cout << "resource_item " << (yyvsp[(1) - (3)].Value) << " " << (yyvsp[(3) - (3)].Value) << endl;MON;} + REGISTER_LINE;/****************************************************************/ + pCurrentRIA->Set((yyvsp[(1) - (3)].Value), (yyvsp[(3) - (3)].Value)); + ;} + break; + + case 78: + +/* Line 1455 of yacc.c */ +#line 499 "rcomp.yacc" + { + if (verbose) + { MOFF;cout << "resource_simple_array_item " << (yyvsp[(1) - (4)].Value) << endl;MON;} + ;} + break; + + case 79: + +/* Line 1455 of yacc.c */ +#line 504 "rcomp.yacc" + { + if (verbose) + { MOFF;cout << "resource_simple_array_item " << (yyvsp[(1) - (5)].Value) << " with simple_initialiser_list" << endl;MON;} + REGISTER_LINE; + pCurrentRIA->Set((yyvsp[(1) - (5)].Value), * (yyvsp[(4) - (5)].pStringArray)); + delete (yyvsp[(4) - (5)].pStringArray); + ;} + break; + + case 80: + +/* Line 1455 of yacc.c */ +#line 532 "rcomp.yacc" + { if(verbose) { MOFF;cout << "struct_resource_item" << endl;MON;} + pCurrentRIA = pG->RIAStack.Pop(); + ;} + break; + + case 81: + +/* Line 1455 of yacc.c */ +#line 537 "rcomp.yacc" + { if(verbose) { MOFF;cout << "struct_resource_item_start " << (yyvsp[(1) - (4)].Value) << " " << (yyvsp[(3) - (4)].Value) << endl;MON;} + REGISTER_LINE; + pCurrentRIA->Set((yyvsp[(1) - (4)].Value), (yyvsp[(3) - (4)].Value)); + String * thisLabel = new String((yyvsp[(1) - (4)].Value)); + pUsedLabelsArray->Add(thisLabel); + // in here add the label to a temp store + pG->RIAStack.Push(pCurrentRIA); + pCurrentRIA = pCurrentRIA->Find((yyvsp[(1) - (4)].Value))->GetRIA(); + ;} + break; + + case 82: + +/* Line 1455 of yacc.c */ +#line 549 "rcomp.yacc" + { if(verbose) { MOFF;cout << "struct_array_resource_item" << endl;MON;} + pG->SRIStack.Pop(); + ;} + break; + + case 83: + +/* Line 1455 of yacc.c */ +#line 553 "rcomp.yacc" + { pG->SRIStack.Pop();;} + break; + + case 84: + +/* Line 1455 of yacc.c */ +#line 556 "rcomp.yacc" + { if(verbose) { MOFF;cout << "struct_array_resource_item_start " << (yyvsp[(1) - (5)].Value) << " " << (yyvsp[(4) - (5)].Value) << endl;MON;} + ResourceItem * p = pCurrentRIA->Find((yyvsp[(1) - (5)].Value)); + pG->SRIStack.Push(p); + REGISTER_LINE; + String * thisLabel = new String((yyvsp[(1) - (5)].Value)); + pUsedLabelsArray->Add(thisLabel); + // in here add the label to a temp store + p->Set((yyvsp[(4) - (5)].Value)); + pG->RIAStack.Push(pCurrentRIA); + pCurrentRIA = p->GetRIA(); + ;} + break; + + case 88: + +/* Line 1455 of yacc.c */ +#line 574 "rcomp.yacc" + { if(verbose) { MOFF;cout << "struct_array_resource_item_list_top " << endl;MON;} + pCurrentRIA = pG->RIAStack.Pop(); + ;} + break; + + case 91: + +/* Line 1455 of yacc.c */ +#line 584 "rcomp.yacc" + { if(verbose) { MOFF;cout << "struct_array_resource_item_list_item " << endl;MON;} + pCurrentRIA = pG->RIAStack.Pop(); + ;} + break; + + case 92: + +/* Line 1455 of yacc.c */ +#line 589 "rcomp.yacc" + { if(verbose) { MOFF;cout << "struct_array_resource_item_list_item_start " << (yyvsp[(1) - (2)].Value) << endl;MON;} + ResourceItem * p = pG->SRIStack.Peek(); + REGISTER_LINE; + p->Set((yyvsp[(1) - (2)].Value)); + pG->RIAStack.Push(pCurrentRIA); + pCurrentRIA = p->GetRIA(); + ;} + break; + + case 94: + +/* Line 1455 of yacc.c */ +#line 605 "rcomp.yacc" + { + // convert literal to unsigned long value of 1st character + SetCharacterLiteral((yyval.Value), (yyvsp[(1) - (1)].Value)); + ;} + break; + + case 97: + +/* Line 1455 of yacc.c */ +#line 614 "rcomp.yacc" + { + if(verbose) + { + MOFF;cout << "simple_initialiser_list - single string " << (yyvsp[(1) - (1)].Value) << endl;MON; + } + + (yyval.pStringArray) = new StringArray; + (yyval.pStringArray)->Add(new String((yyvsp[(1) - (1)].Value)) ); + ;} + break; + + case 98: + +/* Line 1455 of yacc.c */ +#line 624 "rcomp.yacc" + { if(verbose) { MOFF;cout << "simple_initialiser_list - part of list " << (yyvsp[(3) - (3)].Value) << endl;MON;} + assert((yyvsp[(1) - (3)].pStringArray) != NULL); + (yyvsp[(1) - (3)].pStringArray)->Add(new String((yyvsp[(3) - (3)].Value) ) ); + (yyval.pStringArray) = (yyvsp[(1) - (3)].pStringArray); + ;} + break; + + case 99: + +/* Line 1455 of yacc.c */ +#line 632 "rcomp.yacc" + { String s(NumericValue::ltoa((yyvsp[(1) - (1)].NumInitialiser)) ); strcpy((yyval.Value), s.GetAssertedNonEmptyBuffer() ); ;} + break; + + case 100: + +/* Line 1455 of yacc.c */ +#line 635 "rcomp.yacc" + { if(verbose) { MOFF;cout << "Converting number " << (yyvsp[(1) - (1)].Value) << endl;MON;} + REGISTER_LINE; + NumericValue v((yyvsp[(1) - (1)].Value), L_LONG); (yyval.NumInitialiser) = (long)v.GetULong(); + ;} + break; + + case 101: + +/* Line 1455 of yacc.c */ +#line 639 "rcomp.yacc" + { (yyval.NumInitialiser) = (yyvsp[(1) - (3)].NumInitialiser) + (yyvsp[(3) - (3)].NumInitialiser); ;} + break; + + case 102: + +/* Line 1455 of yacc.c */ +#line 640 "rcomp.yacc" + { (yyval.NumInitialiser) = (yyvsp[(1) - (3)].NumInitialiser) - (yyvsp[(3) - (3)].NumInitialiser); ;} + break; + + case 103: + +/* Line 1455 of yacc.c */ +#line 641 "rcomp.yacc" + { (yyval.NumInitialiser) = (yyvsp[(1) - (3)].NumInitialiser) * (yyvsp[(3) - (3)].NumInitialiser); ;} + break; + + case 104: + +/* Line 1455 of yacc.c */ +#line 642 "rcomp.yacc" + { (yyval.NumInitialiser) = (yyvsp[(1) - (3)].NumInitialiser) / (yyvsp[(3) - (3)].NumInitialiser); ;} + break; + + case 105: + +/* Line 1455 of yacc.c */ +#line 643 "rcomp.yacc" + { (yyval.NumInitialiser) = (yyvsp[(1) - (3)].NumInitialiser) | (yyvsp[(3) - (3)].NumInitialiser); ;} + break; + + case 106: + +/* Line 1455 of yacc.c */ +#line 644 "rcomp.yacc" + { if (!NumericValue::CheckSigned((yyvsp[(2) - (2)].NumInitialiser),L_LONG)) + { + REGISTER_LINE; + ErrorHandler::OutputErrorLine("Signed value too low"); + exit(1); + } + (yyval.NumInitialiser) = - (yyvsp[(2) - (2)].NumInitialiser); + ;} + break; + + case 107: + +/* Line 1455 of yacc.c */ +#line 652 "rcomp.yacc" + { (yyval.NumInitialiser) = (yyvsp[(2) - (3)].NumInitialiser); ;} + break; + + case 109: + +/* Line 1455 of yacc.c */ +#line 656 "rcomp.yacc" + { + if (strlen((yyval.Value))+strlen((yyvsp[(2) - (2)].Value)) > sizeof((yyval.Value))-1) + { + REGISTER_LINE; + ErrorHandler::OutputErrorLine("String expression is too long"); + exit(1); + } + strcat((yyval.Value), (yyvsp[(2) - (2)].Value)); + ;} + break; + + case 112: + +/* Line 1455 of yacc.c */ +#line 670 "rcomp.yacc" + { + const char * fileName = (*ErrorHandler::GetFileName()).GetBuffer(); + int lineNumber = ErrorHandler::GetLineNumber(); + QualifiedString * thisLabel = new QualifiedString((yyvsp[(1) - (1)].Value), new String(fileName), lineNumber); + // store the label in the UsedIdentifiers array for checking + // whether label was declared + pG->UsedIdentifiers.Add(thisLabel); + + if (pG->EnumValues.IsStored((yyvsp[(1) - (1)].Value))) + { + sprintf((yyval.Value), "%d", (int)(pG->EnumValues.FindId((yyvsp[(1) - (1)].Value)))); + } + else if (pG->RlsNameIndex.count((yyvsp[(1) - (1)].Value))) // if rls item has already been defined + { + // Found a reference to an rls_string. + RlsValue &rv = pG->RlsValues[pG->RlsNameIndex[(yyvsp[(1) - (1)].Value)]]; + ++rv.iCitationCount; // iCitationCount counts the number of times this rls value has been referneced + // Warn for multiple uses if 'multi' keyword not used. + if (1 < rv.iCitationCount && rv.iCardinality == ERlsCardinalitySingle) + { + Message * message = pG->Messages.GetEntry(LT_001); + String fileLine = *(rv.iFileName); + if(message->GetActivated()) + { + pGL->AddWarningToStore(fileLine, rv.iLineNumber, message->GetMessageOutput()); + } + REGISTER_LINE; + if (!pG->WarningMultiExplained) + { + Message * message = pG->Messages.GetEntry(LT_002); + fileLine = String(*(pFileLineHandler->GetCurrentFile())); + if(message->GetActivated()) + { + pGL->AddWarningToStore(fileLine, pFileLineHandler->GetErrorLine(* pCurrentLineNumber), message->GetMessageOutput()); + pG->WarningMultiExplained = true; + } + } + } + switch (rv.iType) + { + // Strings and numbers are just copied to the next layer up. + case ERlsString: + case ERlsString8: + case ERlsByte: + case ERlsWord: + case ERlsLong: + case ERlsDouble: + strcpy((yyval.Value), rv.iValue.GetBuffer()); + break; + // Anything else is a character: this is converted to a number. + case ERlsStringChar: + case ERlsByteChar: + case ERlsWordChar: + case ERlsLongChar: + SetCharacterLiteral((yyval.Value), rv.iValue); + break; + default: + Message * message = pG->Messages.GetEntry(LT_031); + if(message->GetActivated()) + { + ErrorHandler::OutputErrorLine(message->GetMessageOutput()); + exit(1); + } + break; + } + } + else + { + /* + Could be a reference to another resource, perhaps even a forward reference: + the OverwriteLink functions do FindId again when writing out the data. + Sadly this also permits things which are really syntax errors, inadvertently + converting labels into string literals.. + */ + } + ;} + break; + + case 113: + +/* Line 1455 of yacc.c */ +#line 749 "rcomp.yacc" + { + REGISTER_LINE; + if((yyvsp[(2) - (3)].NumInitialiser) < 0 || ((yyvsp[(2) - (3)].NumInitialiser) > 255 && TargetCharacterSet != String::Unicode)) + { + ErrorHandler::OutputErrorLine("Character code must be a number in the range 0 to 255."); + exit(1); + } + if (TargetCharacterSet != String::Unicode) + { + * (yyval.Value) = char((yyvsp[(2) - (3)].NumInitialiser)); * ((yyval.Value) + 1) = '\0'; + } + else + { + if (SourceCharacterSet == String::CP1252) + { + if ( ((yyvsp[(2) - (3)].NumInitialiser) >= 0x80) && ((yyvsp[(2) - (3)].NumInitialiser) <= 0x9F ) ) // 80-9F are illegal Unicode values. + { + ErrorHandler::OutputErrorLine("Warning: Deprecated non-unicode value in source stream"); + } + * (yyval.Value) = char(UnicodeEscape); + asUTF8((yyval.Value) + 1, (yyvsp[(2) - (3)].NumInitialiser)); + } + else + if (SourceCharacterSet == String::UTF8) + { + asUTF8((yyval.Value), (yyvsp[(2) - (3)].NumInitialiser)); + } + else + { + // Unsatisfactory, but do people use other character sets? + if ((yyvsp[(2) - (3)].NumInitialiser) > 255) + { + ErrorHandler::OutputErrorLine("Don't know how to handle character > 255"); + } + * (yyval.Value) = char((yyvsp[(2) - (3)].NumInitialiser)); * ((yyval.Value) + 1) = '\0'; + } + } + ;} + break; + + case 114: + +/* Line 1455 of yacc.c */ +#line 795 "rcomp.yacc" + { + REGISTER_LINE; + SetIdFromName((yyvsp[(2) - (2)].Value)); + ;} + break; + + case 115: + +/* Line 1455 of yacc.c */ +#line 800 "rcomp.yacc" + { + REGISTER_LINE; + SetIdFromName((yyvsp[(2) - (2)].Value)); + ;} + break; + + case 116: + +/* Line 1455 of yacc.c */ +#line 812 "rcomp.yacc" + { + REGISTER_LINE; + if ((yyvsp[(2) - (2)].NumInitialiser) == 0) + { ErrorHandler::OutputErrorLine("UID2 must be non-zero"); exit(1); } + if (Uid2 != 0) + { ErrorHandler::OutputErrorLine("Warning: overwriting previous UID2 value"); } + Uid2=(yyvsp[(2) - (2)].NumInitialiser); + if(verbose) + { MOFF;cout << "uidX_statement UID2 " << Uid2 << endl;MON;} + ;} + break; + + case 117: + +/* Line 1455 of yacc.c */ +#line 823 "rcomp.yacc" + { + REGISTER_LINE; + if ((yyvsp[(2) - (2)].NumInitialiser) == 0) + { ErrorHandler::OutputErrorLine("UID3 must be non-zero"); exit(1); } + if (Uid3 != 0) + { ErrorHandler::OutputErrorLine("Warning: overwriting previous UID3 value"); } + Uid3=(yyvsp[(2) - (2)].NumInitialiser); + if(verbose) + { MOFF;cout << "uidX_statement UID3 " << Uid3 << endl;MON;} + ;} + break; + + case 118: + +/* Line 1455 of yacc.c */ +#line 844 "rcomp.yacc" + { if(verbose) { MOFF;cout << "character_set_statement " << (yyvsp[(2) - (2)].Value) << endl;MON;} + REGISTER_LINE; + SourceCharacterSet = CharacterSetID((yyvsp[(2) - (2)].Value)); + if ( SourceCharacterSet == String::UNKNOWN ) + { + String err = "Warning: Unrecognised character set name '"; + err += (yyvsp[(2) - (2)].Value); + err += "'"; + ErrorHandler::OutputErrorLine(err); + } + if ( SourceCharacterSet == String::Unicode ) + { + SourceCharacterSet = String::UNKNOWN; + ErrorHandler::OutputErrorLine("Unicode source is unsupported"); + } + ;} + break; + + case 119: + +/* Line 1455 of yacc.c */ +#line 868 "rcomp.yacc" + { if(verbose) { RCTypeArray Types; + MOFF;cout << "offset_statement " << (yyvsp[(2) - (2)].Value) << endl;MON; } + REGISTER_LINE; + CurrentId=((long) NumericValue((yyvsp[(2) - (2)].Value), L_LONG).GetULong() ); + ;} + break; + + case 120: + +/* Line 1455 of yacc.c */ +#line 879 "rcomp.yacc" + { if(verbose) { MOFF;cout << "system_statement" << endl;MON;} + CurrentIdStep=-1; + ;} + break; + + case 123: + +/* Line 1455 of yacc.c */ +#line 893 "rcomp.yacc" + { + if(verbose) + { MOFF;cout << "enum_statement" << endl;MON;} + CurrentEnumName = (yyvsp[(2) - (3)].Value); + CurrentEnumValue=0; + ;} + break; + + case 124: + +/* Line 1455 of yacc.c */ +#line 900 "rcomp.yacc" + { + if(verbose) + { MOFF;cout << "enum_statement" << endl;MON;} + CurrentEnumName = ""; + CurrentEnumValue=0; + ;} + break; + + case 125: + +/* Line 1455 of yacc.c */ +#line 910 "rcomp.yacc" + { + pG->EnumValues.Add((yyvsp[(1) - (1)].Value), CurrentEnumValue++); + pG->AllIdentifiers.Add(new String((yyvsp[(1) - (1)].Value))); // Add label to store + ;} + break; + + case 126: + +/* Line 1455 of yacc.c */ +#line 915 "rcomp.yacc" + { + CurrentEnumValue = atol((yyvsp[(3) - (3)].Value)); + pG->EnumValues.Add((yyvsp[(1) - (3)].Value), CurrentEnumValue); + CurrentEnumValue++; // Increment so that next field has value ($3+1) + pG->AllIdentifiers.Add(new String((yyvsp[(1) - (3)].Value))); // Add label to store + ;} + break; + + case 129: + +/* Line 1455 of yacc.c */ +#line 934 "rcomp.yacc" + { + pG->RlsNameIndex[(yyvsp[(3) - (4)].Value)] = pG->RlsValues.size(); + pG->RlsValues.push_back(RlsValue(ErrorHandler::GetFileName(), + ErrorHandler::GetLineNumber(), (yyvsp[(4) - (4)].Value), (yyvsp[(1) - (4)].RlsType), + (yyvsp[(2) - (4)].RlsQualifiers).iCardinality, (yyvsp[(2) - (4)].RlsQualifiers).iMaxLength)); + if((yyvsp[(2) - (4)].RlsQualifiers).iMaxLength + < String((yyvsp[(4) - (4)].Value)).ExportLength(TargetCharacterSet,SourceCharacterSet)) + { + Message * message = pG->Messages.GetEntry(LT_032); + if(message->GetActivated()) + { + ErrorHandler::OutputErrorLine(message->GetMessageOutput()); + exit(1); + } + } + ;} + break; + + case 130: + +/* Line 1455 of yacc.c */ +#line 951 "rcomp.yacc" + { + Message * message = pG->Messages.GetEntry(LT_033); + String fileName = *(pFileLineHandler->GetCurrentFile()); + int lineNumber = pFileLineHandler->GetErrorLine(* pCurrentLineNumber); + if(message->GetActivated()) + { + pGL->AddWarningToStore(fileName, lineNumber, message->GetMessageOutput()); + } + //... + /* Produce a warning "rls_string used for character constant: use rls_long, rls_word or rls_byte" */ + pG->RlsNameIndex[(yyvsp[(3) - (4)].Value)] = pG->RlsValues.size(); + pG->RlsValues.push_back(RlsValue(ErrorHandler::GetFileName(), + ErrorHandler::GetLineNumber(), (yyvsp[(4) - (4)].Value), ERlsStringChar, + (yyvsp[(2) - (4)].RlsQualifiers).iCardinality)); + ;} + break; + + case 131: + +/* Line 1455 of yacc.c */ +#line 967 "rcomp.yacc" + { + pG->RlsNameIndex[(yyvsp[(3) - (4)].Value)] = pG->RlsValues.size(); + pG->RlsValues.push_back(RlsValue(ErrorHandler::GetFileName(), + ErrorHandler::GetLineNumber(), (yyvsp[(4) - (4)].Value), (yyvsp[(1) - (4)].RlsType), + (yyvsp[(2) - (4)].RlsQualifiers).iCardinality)); + ;} + break; + + case 132: + +/* Line 1455 of yacc.c */ +#line 974 "rcomp.yacc" + { + pG->RlsNameIndex[(yyvsp[(3) - (4)].Value)] = pG->RlsValues.size(); + pG->RlsValues.push_back(RlsValue(ErrorHandler::GetFileName(), + ErrorHandler::GetLineNumber(), (yyvsp[(4) - (4)].Value), (yyvsp[(1) - (4)].RlsType), + (yyvsp[(2) - (4)].RlsQualifiers).iCardinality)); + ;} + break; + + case 133: + +/* Line 1455 of yacc.c */ +#line 981 "rcomp.yacc" + { + TRlsType rlsCharType = (yyvsp[(1) - (4)].RlsType) == ERlsByte? ERlsByteChar + : ( (yyvsp[(1) - (4)].RlsType) == ERlsWord? ERlsWordChar : ERlsLongChar ); + pG->RlsNameIndex[(yyvsp[(3) - (4)].Value)] = pG->RlsValues.size(); + pG->RlsValues.push_back(RlsValue(ErrorHandler::GetFileName(), + ErrorHandler::GetLineNumber(), (yyvsp[(4) - (4)].Value), rlsCharType, + (yyvsp[(2) - (4)].RlsQualifiers).iCardinality)); + ;} + break; + + case 134: + +/* Line 1455 of yacc.c */ +#line 992 "rcomp.yacc" + { + // Register line even if no warning here so that + // the rls_ item knows which line the label was on. + // Without this, the line registered would be the + // line following the declaration. + REGISTER_LINE; + strcpy((yyval.Value), (yyvsp[(1) - (1)].Value)); + + if (pG->RlsNameIndex.count((yyvsp[(1) - (1)].Value)) != 0) + { + Message * message = pG->Messages.GetEntry(LT_003); + if(message->GetActivated()) + { + ErrorHandler::OutputErrorLine(message->GetMessageOutput()); + } + } + pG->AllIdentifiers.Add(new String((yyvsp[(1) - (1)].Value))); // Add label to store + ;} + break; + + case 135: + +/* Line 1455 of yacc.c */ +#line 1013 "rcomp.yacc" + { + NumericValue v((yyvsp[(2) - (4)].Value), L_LONG); + (yyval.RlsQualifiers).iMaxLength = v.GetULong(); + (yyval.RlsQualifiers).iCardinality = (yyvsp[(4) - (4)].RlsQualifiers).iCardinality; + ;} + break; + + case 136: + +/* Line 1455 of yacc.c */ +#line 1019 "rcomp.yacc" + { (yyval.RlsQualifiers) = (yyvsp[(1) - (1)].RlsQualifiers); ;} + break; + + case 137: + +/* Line 1455 of yacc.c */ +#line 1024 "rcomp.yacc" + { + (yyval.RlsQualifiers).iMaxLength = 0xFFFFFFF; + (yyval.RlsQualifiers).iCardinality = ERlsCardinalityMultiple; + ;} + break; + + case 138: + +/* Line 1455 of yacc.c */ +#line 1029 "rcomp.yacc" + { + (yyval.RlsQualifiers).iMaxLength = 0xFFFFFFF; + (yyval.RlsQualifiers).iCardinality = ERlsCardinalitySingle; + ;} + break; + + case 139: + +/* Line 1455 of yacc.c */ +#line 1037 "rcomp.yacc" + { (yyval.RlsType) = ERlsString; ;} + break; + + case 140: + +/* Line 1455 of yacc.c */ +#line 1039 "rcomp.yacc" + { (yyval.RlsType) = ERlsString8; ;} + break; + + case 141: + +/* Line 1455 of yacc.c */ +#line 1044 "rcomp.yacc" + { (yyval.RlsType) = ERlsByte; ;} + break; + + case 142: + +/* Line 1455 of yacc.c */ +#line 1046 "rcomp.yacc" + { (yyval.RlsType) = ERlsWord; ;} + break; + + case 143: + +/* Line 1455 of yacc.c */ +#line 1048 "rcomp.yacc" + { (yyval.RlsType) = ERlsLong; ;} + break; + + case 144: + +/* Line 1455 of yacc.c */ +#line 1053 "rcomp.yacc" + { (yyval.RlsType) = ERlsDouble; ;} + break; + + case 147: + +/* Line 1455 of yacc.c */ +#line 1065 "rcomp.yacc" + {ErrorHandler::Register(pFileLineHandler->GetCurrentFile(), pFileLineHandler->GetErrorLine(*pCurrentLineNumber)); ;} + break; + + case 150: + +/* Line 1455 of yacc.c */ +#line 1075 "rcomp.yacc" + { pGL->StoreComment((yyvsp[(1) - (1)].Value)); ;} + break; + + case 151: + +/* Line 1455 of yacc.c */ +#line 1076 "rcomp.yacc" + { pGL->StoreComment((yyvsp[(1) - (1)].Value)); ;} + break; + + case 152: + +/* Line 1455 of yacc.c */ +#line 1077 "rcomp.yacc" + { pGL->StoreComment((yyvsp[(1) - (1)].Value)); ;} + break; + + + +/* Line 1455 of yacc.c */ +#line 3037 "rcomp.tab.cacc" + default: break; + } + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if ! YYERROR_VERBOSE + yyerror (YY_("syntax error")); +#else + { + YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); + if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) + { + YYSIZE_T yyalloc = 2 * yysize; + if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) + yyalloc = YYSTACK_ALLOC_MAXIMUM; + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yyalloc); + if (yymsg) + yymsg_alloc = yyalloc; + else + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + } + } + + if (0 < yysize && yysize <= yymsg_alloc) + { + (void) yysyntax_error (yymsg, yystate, yychar); + yyerror (yymsg); + } + else + { + yyerror (YY_("syntax error")); + if (yysize != 0) + goto yyexhaustedlab; + } + } +#endif + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + + /* Pacify compilers like GCC when the user code never invokes + YYERROR and the label yyerrorlab therefore never appears in user + code. */ + if (/*CONSTCOND*/ 0) + goto yyerrorlab; + + /* Do not reclaim the symbols of the rule which action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (yyn != YYPACT_NINF) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", + yystos[yystate], yyvsp); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + *++yyvsp = yylval; + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#if !defined(yyoverflow) || YYERROR_VERBOSE +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: + if (yychar != YYEMPTY) + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval); + /* Do not reclaim the symbols of the rule which action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif +#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +#endif + /* Make sure YYID is used. */ + return YYID (yyresult); +} + + + +/* Line 1675 of yacc.c */ +#line 1080 "rcomp.yacc" + + +// Function section +// ================ + +void asUTF8(char* aUtf8, int aUnicode) + { + if ( aUnicode > 0xffff ) + { + if ( aUnicode > 0x10ffff ) + { + ErrorHandler::OutputErrorLine("Surrogate character code must be a number in the range 0x10000 to 0x10ffff"); + exit(1); + } + + UTF16 high = (UTF16)(0xD7C0 + (aUnicode >> 10)); // high surrogate + UTF16 low = (UTF16)(0xDC00 | (aUnicode & 0x3FF)); // low surrogate + + *aUtf8++ =(char)(0xe0|(high>>12)); + *aUtf8++ =(char)(0x80|((high>>6)&0x3f)); + *aUtf8++ =(char)(0x80|(high&0x3f)); + *aUtf8++ =(char)(0xe0|(low>>12)); + *aUtf8++ =(char)(0x80|((low>>6)&0x3f)); + *aUtf8 =(char)(0x80|(low&0x3f)); + } + else if ((aUnicode & 0xff80) == 0x0000) + { + *aUtf8 = (char)aUnicode; + } + else if ((aUnicode & 0xf800) == 0x0000) + { + *aUtf8++ =(char)(0xc0|(aUnicode>>6)); + *aUtf8 =(char)(0x80|(aUnicode&0x3f)); + } + else + { + *aUtf8++ =(char)(0xe0|(aUnicode>>12)); + *aUtf8++ =(char)(0x80|((aUnicode>>6)&0x3f)); + *aUtf8 =(char)(0x80|(aUnicode&0x3f)); + } + *++aUtf8 = '\0'; + } + + +String::CharacterSet CharacterSetID( const String & character_set_name ) +// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// Return a character set ID from a character set name. The value UNKNOWN +// is returned if the name is not recognised. +// ---------------------------------------------------------------------------- +{ + String::CharacterSet ids[] = { String::ISOLatin1, String::ASCII, String::CP1252 + , String::CP850, String::ShiftJIS, String::Unicode + , String::UTF8 + , String::UNKNOWN + }; + String names[] = { "ISOLATIN1", "ASCII", "CP1252", "CP850", "SHIFTJIS", "UNICODE", "UTF8" }; + + for ( int i=0; ids[i]!=String::UNKNOWN; i++ ) + { + if ( names[i] == character_set_name ) return ids[i]; + } + + return String::UNKNOWN; + +} // end of CharacterSetID code + +void SetIdFromName( const String & NameStatementValue) + { + // space 0 + // A 1 + // B 2 + // ... + // Z 26 + // + // ABCD corresponds to the number 4321 which becomes ( (4*27 + 3) * 27 + 2) * 27 + 1. + + if(verbose) + { MOFF;cout << "name_statement " << NameStatementValue << endl;MON;} + if ( NameStatementValue.Length() > 4) + { + ErrorHandler::OutputErrorLine( "Name must be no longer than four characters"); + exit( 1); + } + + long NewId = 0; + + for( unsigned long i = 0; i < NameStatementValue.Length(); i++) + { + NewId *= 27; + if ( isalpha( NameStatementValue[i]) ) + NewId += toupper( NameStatementValue[i]) - 'A' + 1; + } + + CurrentId = NewId << 12; + FormatIdAsHex = 1; + if(verbose) + { MOFF;cout << "Current id " << CurrentId << endl;MON;} + } + +void RlsUnusedWarnings() + { + TNameIndex::iterator end = pG->RlsNameIndex.end(); + for (TNameIndex::iterator i = pG->RlsNameIndex.begin(); i != end; ++i) + { + int index = i->second; + RlsValue& v = pG->RlsValues[index]; + if (v.iCitationCount == 0) + { + Message * message = pG->Messages.GetEntry(LT_004); + String fileLine = *(v.iFileName); + if(message->GetActivated()) + { + pGL->AddWarningToStore(fileLine, v.iLineNumber, message->GetMessageOutput()); + } + } + } + } + +int ParseSourceFile(FILE* aFile, unsigned short aYYDebug) + { + // Set up various global pointers which refer to the pG structure + pSHA = & (pG->SHA); + pFileLineHandler = & (pG->FileLineHandler); + pResourceNameIds = & (pG->ResourceNameIds); + + pScan = new rcscan(pG->FileLineHandler, aFile); + + yydebug = aYYDebug; + pCurrentLineNumber = &yylineno; + int ReturnValue = yyparse(); + + RlsUnusedWarnings(); + + int bScanErrorFound = pScan->ErrorWasFound(); + + delete pScan; + pScan = NULL; + + if(ReturnValue != 0) + return ReturnValue; + + if(bScanErrorFound) + return 1; + + return 0; // successful parse - parse tree now in the pG data structure + } + + +void CheckStructUsage() + { + ResourceItemArrayIterator nextRI( *pCurrentRIA); + ResourceItem * pRI; + while ( ( pRI = nextRI() ) != NULL) + { + int resourceItemType = pRI->GetResourceItemType(); + String resourceItemLabel = pRI->GetLabel(); + if( (resourceItemType == EStructTypeResourceItem) || (resourceItemType == EStructArrayResourceItem) ) + { + StringArrayIterator nextLabel( *pUsedLabelsArray); + String * pLabel; + bool flag = false; + while ( ( ( pLabel = nextLabel() ) != NULL ) && (! flag) ) + { + StringLess stringCompare; + if( !stringCompare(resourceItemLabel,*pLabel) && !stringCompare(*pLabel,resourceItemLabel) ) + { + flag = true; + } + } + if(! flag) + { + if(resourceItemType == EStructTypeResourceItem) + { + Message * message = pG->Messages.GetEntry(LT_046); + if(message->GetActivated()) + { + String comment = message->GetMessageOutput(); + comment += "'"; + comment += resourceItemLabel; + comment += "'"; + ErrorHandler::OutputErrorLine(comment); + } + } + else + { + Message * message = pG->Messages.GetEntry(LT_047); + if(message->GetActivated()) + { + String comment = message->GetMessageOutput(); + comment += "'"; + comment += resourceItemLabel; + comment += "'"; + ErrorHandler::OutputErrorLine(comment); + } + } + } + } + } + } + +int yywrap() +{ + return 1; +} + +/* Called by yyparse on error */ +#include +void yyerror (const char *s, ...) +{ + va_list list; + va_start(list, s); + pScan->yyerror(const_cast(s), list); + va_end(list); +} + + + diff -r 122d2b873fd1 -r 30b30f9da0b7 bintools/rcomp/src/rcompl.cpp --- a/bintools/rcomp/src/rcompl.cpp Fri Jun 25 20:58:33 2010 +0800 +++ b/bintools/rcomp/src/rcompl.cpp Tue Jun 29 14:52:54 2010 +0800 @@ -1,2390 +1,2376 @@ -/* -* Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of the License "Eclipse Public License v1.0" -* which accompanies this distribution, and is available -* at the URL "http://www.eclipse.org/legal/epl-v10.html". -* -* Initial Contributors: -* Nokia Corporation - initial contribution. -* -* Contributors: -* -* Description: -* A lexical scanner generated by flex. -* Scanner skeleton version: -* $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.91 96/09/10 16:58:48 vern Exp $ -* -*/ - - -#define FLEX_SCANNER -#define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 5 - -#include - - -/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ -#ifdef c_plusplus -#ifndef __cplusplus -#define __cplusplus -#endif -#endif - - -#ifdef __cplusplus - -#include -#include - -/* Use prototypes in function declarations. */ -#define YY_USE_PROTOS - -/* The "const" storage-class-modifier is valid. */ -#define YY_USE_CONST - -#else /* ! __cplusplus */ - -#if __STDC__ - -#define YY_USE_PROTOS -#define YY_USE_CONST - -#endif /* __STDC__ */ -#endif /* ! __cplusplus */ - -#ifdef __TURBOC__ - #pragma warn -rch - #pragma warn -use -#include -#include -#define YY_USE_CONST -#define YY_USE_PROTOS -#endif - -#ifdef YY_USE_CONST -#define yyconst const -#else -#define yyconst -#endif - - -#ifdef YY_USE_PROTOS -#define YY_PROTO(proto) proto -#else -#define YY_PROTO(proto) () -#endif - -/* Returned upon end-of-file. */ -#define YY_NULL 0 - -/* Promotes a possibly negative, possibly signed char to an unsigned - * integer for use as an array index. If the signed char is negative, - * we want to instead treat it as an 8-bit unsigned char, hence the - * double cast. - */ -#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) - -/* Enter a start condition. This macro really ought to take a parameter, - * but we do it the disgusting crufty way forced on us by the ()-less - * definition of BEGIN. - */ -#define BEGIN yy_start = 1 + 2 * - -/* Translate the current start state into a value that can be later handed - * to BEGIN to return to the state. The YYSTATE alias is for lex - * compatibility. - */ -#define YY_START ((yy_start - 1) / 2) -#define YYSTATE YY_START - -/* Action number for EOF rule of a given start state. */ -#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) - -/* Special action meaning "start processing a new file". */ -#define YY_NEW_FILE yyrestart( yyin ) - -#define YY_END_OF_BUFFER_CHAR 0 - -/* Size of default input buffer. */ -#define YY_BUF_SIZE 16384 - -typedef struct yy_buffer_state *YY_BUFFER_STATE; - -extern int yyleng; -extern FILE *yyin, *yyout; - -#define EOB_ACT_CONTINUE_SCAN 0 -#define EOB_ACT_END_OF_FILE 1 -#define EOB_ACT_LAST_MATCH 2 - -/* The funky do-while in the following #define is used to turn the definition - * int a single C statement (which needs a semi-colon terminator). This - * avoids problems with code like: - * - * if ( condition_holds ) - * yyless( 5 ); - * else - * do_something_else(); - * - * Prior to using the do-while the compiler would get upset at the - * "else" because it interpreted the "if" statement as being all - * done when it reached the ';' after the yyless() call. - */ - -/* Return all but the first 'n' matched characters back to the input stream. */ - -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - *yy_cp = yy_hold_char; \ - YY_RESTORE_YY_MORE_OFFSET \ - yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \ - YY_DO_BEFORE_ACTION; /* set up yytext again */ \ - } \ - while ( 0 ) - -#define unput(c) yyunput( c, yytext_ptr ) - -/* The following is because we cannot portably get our hands on size_t - * (without autoconf's help, which isn't available because we want - * flex-generated scanners to compile on their own). - */ -typedef unsigned int yy_size_t; - - -struct yy_buffer_state - { - FILE *yy_input_file; - - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ - - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ - yy_size_t yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ - int yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ - int yy_is_our_buffer; - - /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ - int yy_is_interactive; - - /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ - int yy_at_bol; - - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; -#define YY_BUFFER_NEW 0 -#define YY_BUFFER_NORMAL 1 - /* When an EOF's been seen but there's still some text to process - * then we mark the buffer as YY_EOF_PENDING, to indicate that we - * shouldn't try reading from the input source any more. We might - * still have a bunch of tokens to match, though, because of - * possible backing-up. - * - * When we actually see the EOF, we change the status to "new" - * (via yyrestart()), so that the user can continue scanning by - * just pointing yyin at a new input file. - */ -#define YY_BUFFER_EOF_PENDING 2 - }; - -static YY_BUFFER_STATE yy_current_buffer = 0; - -/* We provide macros for accessing buffer states in case in the - * future we want to put the buffer states in a more general - * "scanner state". - */ -#define YY_CURRENT_BUFFER yy_current_buffer - - -/* yy_hold_char holds the character lost when yytext is formed. */ -static char yy_hold_char; - -static int yy_n_chars; /* number of characters read into yy_ch_buf */ - - -int yyleng; - -/* Points to current character in buffer. */ -static char *yy_c_buf_p = (char *) 0; -static int yy_init = 1; /* whether we need to initialize */ -static int yy_start = 0; /* start state number */ - -/* Flag which is used to allow yywrap()'s to do buffer switches - * instead of setting up a fresh yyin. A bit of a hack ... - */ -static int yy_did_buffer_switch_on_eof; - -void yyrestart YY_PROTO(( FILE *input_file )); - -void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer )); -void yy_load_buffer_state YY_PROTO(( void )); -YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size )); -void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b )); -void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file )); -void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b )); -#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer ) - -YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size )); -YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str )); -YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len )); - -static void *yy_flex_alloc YY_PROTO(( yy_size_t )); -static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t )); -static void yy_flex_free YY_PROTO(( void * )); - -#define yy_new_buffer yy_create_buffer - -#define yy_set_interactive(is_interactive) \ - { \ - if ( ! yy_current_buffer ) \ - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ - yy_current_buffer->yy_is_interactive = is_interactive; \ - } - -#define yy_set_bol(at_bol) \ - { \ - if ( ! yy_current_buffer ) \ - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ - yy_current_buffer->yy_at_bol = at_bol; \ - } - -#define YY_AT_BOL() (yy_current_buffer->yy_at_bol) - - -#define YY_USES_REJECT -typedef unsigned char YY_CHAR; -FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; -typedef int yy_state_type; -extern int yylineno; -int yylineno = 1; -extern char *yytext; -#define yytext_ptr yytext - -static yy_state_type yy_get_previous_state YY_PROTO(( void )); -static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state )); -static int yy_get_next_buffer YY_PROTO(( void )); -static void yy_fatal_error YY_PROTO(( yyconst char msg[] )); - -/* Done after the current pattern has been matched and before the - * corresponding action - sets up yytext. - */ -#define YY_DO_BEFORE_ACTION \ - yytext_ptr = yy_bp; \ - yyleng = (int) (yy_cp - yy_bp); \ - yy_hold_char = *yy_cp; \ - *yy_cp = '\0'; \ - yy_c_buf_p = yy_cp; - -#define YY_NUM_RULES 81 -#define YY_END_OF_BUFFER 82 -static yyconst short int yy_acclist[363] = - { 0, - 82, 80, 81, 62, 80, 81, 63, 81, 63, 80, - 81, 37, 80, 81, 80, 81, 38, 80, 81, 79, - 80, 81, 79, 80, 81, 79, 80, 81, 49, 80, - 81, 49, 80, 81, 48, 80, 81, 48, 80, 81, - 48, 80, 81, 48, 80, 81, 48, 80, 81, 48, - 80, 81, 48, 80, 81, 48, 80, 81, 48, 80, - 81, 48, 80, 81, 48, 80, 81, 48, 80, 81, - 48, 80, 81, 48, 80, 81, 48, 80, 81, 48, - 80, 81, 48, 80, 81, 47, 80, 81, 44, 81, - 47, 80, 81, 45, 47, 80, 81, 46, 47, 80, - - 81, 47, 80, 81, 80, 81, 62, 80, 81, 64, - 81, 64, 80, 81, 80, 81, 80, 81, 67, 80, - 81, 66, 81, 66, 67, 80, 81, 72, 80, 81, - 71, 81, 71, 72, 80, 81, 72, 80, 81, 76, - 80, 81, 78, 80, 81, 77, 81, 77, 80, 81, - 78, 80, 81, 80, 81, 65, 49, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 44, 43, 39, 40, 42, 41, 58, 59, 65, - 70, 76, 74, 75, 68, 69, 68, 69, 73, 53, - - 55, 50, 20, 48, 48, 48, 48, 48, 48, 36, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 59, 68, - 69, 68, 69, 68, 73, 54, 56, 48, 21, 48, - 24, 48, 48, 48, 9, 48, 48, 33, 48, 48, - 48, 25, 48, 48, 3, 48, 48, 48, 48, 48, - 48, 27, 48, 11, 48, 12, 48, 23, 48, 10, - 48, 48, 48, 60, 61, 57, 51, 22, 48, 48, - 48, 48, 34, 48, 8, 48, 28, 48, 48, 48, - 48, 48, 48, 48, 29, 48, 19, 48, 48, 48, - - 48, 48, 48, 52, 48, 26, 48, 7, 48, 48, - 30, 48, 5, 48, 48, 35, 48, 1, 48, 6, - 48, 31, 48, 48, 48, 48, 48, 48, 48, 32, - 48, 48, 48, 48, 48, 48, 48, 48, 2, 48, - 16, 48, 48, 18, 48, 48, 17, 48, 48, 48, - 48, 48, 15, 48, 13, 48, 48, 14, 48, 48, - 4, 48 - } ; - -static yyconst short int yy_accept[270] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 2, 4, 7, 9, 12, 15, 17, - 20, 23, 26, 29, 32, 35, 38, 41, 44, 47, - 50, 53, 56, 59, 62, 65, 68, 71, 74, 77, - 80, 83, 86, 89, 91, 94, 98, 102, 105, 107, - 110, 112, 115, 117, 119, 122, 124, 128, 131, 133, - 137, 140, 143, 146, 148, 151, 154, 156, 156, 156, - 156, 156, 156, 157, 157, 158, 158, 158, 159, 160, - 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, - 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, - - 181, 182, 183, 184, 185, 186, 187, 188, 188, 188, - 188, 188, 190, 190, 190, 190, 191, 192, 193, 194, - 195, 195, 195, 195, 195, 196, 197, 199, 200, 201, - 202, 203, 205, 206, 207, 208, 209, 210, 212, 213, - 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, - 224, 225, 226, 227, 228, 229, 230, 230, 230, 230, - 230, 231, 232, 234, 235, 236, 236, 237, 238, 238, - 239, 241, 243, 244, 245, 247, 248, 250, 251, 252, - 254, 255, 257, 258, 259, 260, 261, 262, 264, 266, - 268, 270, 272, 273, 274, 275, 275, 275, 276, 276, - - 276, 277, 277, 278, 280, 281, 282, 283, 285, 287, - 289, 290, 291, 292, 293, 294, 295, 297, 299, 300, - 301, 302, 303, 304, 304, 304, 305, 306, 308, 310, - 311, 313, 315, 316, 318, 320, 322, 324, 325, 326, - 327, 328, 329, 330, 332, 333, 334, 335, 336, 337, - 338, 339, 341, 343, 344, 346, 347, 349, 350, 351, - 352, 353, 355, 357, 358, 360, 361, 363, 363 - } ; - -static yyconst int yy_ec[256] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, - 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 5, 1, 6, 7, 1, 1, 8, 9, 10, - 10, 11, 10, 10, 12, 13, 14, 15, 16, 17, - 18, 19, 19, 20, 19, 21, 19, 1, 10, 10, - 10, 10, 1, 22, 23, 24, 25, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 32, - 32, 38, 39, 40, 41, 32, 42, 43, 44, 32, - 10, 45, 10, 1, 46, 1, 47, 48, 47, 49, - - 50, 51, 52, 53, 54, 53, 53, 55, 56, 57, - 58, 53, 53, 59, 60, 61, 62, 63, 64, 65, - 66, 53, 10, 10, 10, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1 - } ; - -static yyconst int yy_meta[67] = - { 0, - 1, 2, 3, 2, 2, 4, 1, 1, 4, 1, - 2, 1, 5, 1, 6, 6, 6, 6, 6, 6, - 6, 1, 7, 7, 7, 7, 6, 7, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 4, 8, 7, 9, 7, 6, - 9, 8, 8, 8, 8, 8, 10, 8, 10, 8, - 10, 8, 10, 8, 11, 8 - } ; - -static yyconst short int yy_base[284] = - { 0, - 0, 0, 64, 68, 76, 81, 72, 85, 88, 90, - 100, 112, 566, 567, 105, 567, 567, 567, 560, 567, - 567, 109, 86, 85, 93, 0, 77, 534, 526, 526, - 527, 105, 537, 531, 531, 93, 530, 525, 518, 497, - 491, 497, 567, 567, 548, 567, 567, 135, 544, 146, - 543, 542, 150, 150, 567, 567, 567, 567, 567, 567, - 533, 0, 567, 567, 567, 532, 0, 157, 534, 157, - 136, 162, 567, 172, 0, 179, 0, 0, 516, 503, - 519, 500, 499, 502, 502, 501, 505, 121, 508, 499, - 505, 493, 497, 492, 490, 485, 501, 488, 463, 469, - - 463, 567, 567, 567, 567, 567, 567, 516, 164, 199, - 173, 567, 518, 165, 203, 514, 567, 0, 567, 0, - 511, 203, 210, 217, 567, 567, 567, 567, 224, 237, - 0, 194, 491, 479, 492, 480, 490, 0, 480, 476, - 488, 481, 466, 481, 468, 469, 474, 463, 463, 462, - 185, 475, 444, 438, 452, 567, 494, 177, 243, 256, - 490, 489, 488, 259, 487, 486, 250, 263, 270, 471, - 0, 0, 467, 455, 0, 465, 0, 454, 452, 0, - 445, 0, 457, 442, 446, 456, 453, 196, 0, 0, - 0, 0, 425, 244, 567, 475, 459, 567, 473, 457, - - 567, 294, 301, 0, 449, 446, 438, 0, 0, 280, - 431, 432, 436, 428, 432, 434, 0, 0, 364, 371, - 361, 357, 345, 246, 269, 308, 362, 0, 0, 381, - 0, 0, 375, 0, 0, 0, 0, 329, 327, 331, - 328, 248, 279, 0, 278, 253, 254, 246, 243, 246, - 256, 0, 0, 221, 0, 218, 0, 170, 164, 95, - 101, 0, 87, 69, 0, 29, 0, 567, 329, 340, - 351, 362, 373, 380, 386, 395, 405, 416, 427, 434, - 440, 446, 455 - } ; - -static yyconst short int yy_def[284] = - { 0, - 268, 1, 269, 269, 270, 270, 271, 271, 272, 272, - 273, 273, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268, 274, 274, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 268, 268, 268, 268, 268, 276, 277, 277, - 277, 277, 268, 277, 268, 268, 268, 268, 268, 268, - 268, 278, 268, 268, 268, 268, 279, 268, 268, 268, - 280, 281, 268, 268, 25, 268, 282, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - - 275, 268, 268, 268, 268, 268, 268, 277, 268, 277, - 277, 268, 268, 268, 283, 277, 268, 278, 268, 279, - 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 282, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 268, 268, 277, 268, 268, - 277, 277, 277, 268, 277, 268, 268, 268, 268, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 268, 268, 268, 268, 268, 268, - - 268, 268, 268, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 268, 268, 268, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, - 275, 275, 275, 275, 275, 275, 275, 0, 268, 268, - 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268 - } ; - -static yyconst short int yy_nxt[634] = - { 0, - 14, 15, 16, 17, 15, 18, 19, 14, 20, 21, - 21, 22, 21, 23, 24, 25, 25, 25, 25, 25, - 25, 14, 26, 27, 28, 29, 30, 26, 31, 26, - 26, 26, 26, 32, 26, 33, 34, 35, 36, 37, - 38, 39, 26, 26, 14, 26, 26, 26, 26, 40, - 26, 26, 26, 26, 26, 41, 26, 26, 42, 26, - 26, 26, 26, 26, 26, 26, 44, 45, 267, 46, - 44, 45, 47, 46, 56, 57, 47, 50, 51, 52, - 50, 53, 50, 51, 52, 50, 53, 56, 57, 54, - 59, 60, 59, 60, 54, 266, 72, 74, 61, 73, - - 61, 63, 64, 65, 63, 74, 68, 265, 48, 68, - 66, 76, 48, 63, 64, 65, 63, 79, 69, 76, - 80, 67, 66, 71, 71, 71, 71, 71, 71, 71, - 93, 85, 94, 67, 76, 86, 95, 103, 87, 264, - 104, 88, 76, 105, 89, 141, 263, 110, 123, 77, - 110, 109, 112, 113, 114, 109, 142, 268, 68, 111, - 115, 68, 124, 116, 126, 127, 156, 157, 114, 128, - 69, 122, 122, 122, 122, 122, 122, 122, 109, 106, - 159, 160, 109, 158, 165, 124, 129, 129, 129, 129, - 129, 129, 129, 130, 130, 130, 130, 130, 130, 130, - - 110, 189, 190, 110, 109, 162, 163, 166, 164, 170, - 165, 216, 111, 262, 171, 261, 217, 122, 122, 122, - 122, 122, 122, 122, 167, 167, 167, 167, 167, 167, - 167, 168, 168, 168, 168, 168, 168, 168, 129, 129, - 129, 129, 129, 129, 129, 195, 196, 197, 195, 196, - 169, 130, 130, 130, 130, 130, 130, 130, 198, 199, - 200, 156, 157, 114, 167, 167, 167, 167, 167, 167, - 167, 198, 199, 169, 260, 259, 202, 168, 168, 168, - 168, 168, 168, 168, 203, 203, 203, 203, 203, 203, - 203, 219, 220, 258, 257, 230, 256, 255, 221, 202, - - 231, 254, 253, 222, 252, 251, 250, 223, 226, 226, - 226, 226, 226, 226, 226, 203, 203, 203, 203, 203, - 203, 203, 226, 226, 226, 226, 226, 226, 226, 43, - 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 75, 75, 249, 248, 247, 246, - 75, 78, 78, 78, 78, 78, 78, 107, 107, 245, - - 244, 243, 242, 107, 107, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 118, 241, 240, 118, - 118, 118, 118, 118, 118, 118, 118, 120, 239, 238, - 120, 120, 120, 120, 120, 120, 120, 120, 71, 71, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 131, 131, 237, 131, 161, 161, 161, 161, 161, - 161, 161, 161, 161, 161, 161, 236, 235, 234, 233, - 232, 229, 228, 227, 225, 198, 224, 195, 218, 215, - 214, 213, 212, 211, 210, 209, 208, 207, 206, 205, - 204, 201, 109, 109, 109, 109, 156, 194, 193, 192, - - 191, 188, 187, 186, 185, 184, 183, 182, 181, 180, - 179, 178, 177, 176, 175, 174, 173, 172, 128, 109, - 112, 109, 155, 154, 153, 152, 151, 150, 149, 148, - 147, 146, 145, 144, 143, 140, 139, 138, 137, 136, - 135, 134, 133, 132, 121, 119, 117, 109, 109, 109, - 102, 101, 100, 99, 98, 97, 96, 92, 91, 90, - 84, 83, 82, 81, 70, 268, 13, 268, 268, 268, - 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - - 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268 - } ; - -static yyconst short int yy_chk[634] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 3, 3, 266, 3, - 4, 4, 3, 4, 7, 7, 4, 5, 5, 5, - 5, 5, 6, 6, 6, 6, 6, 8, 8, 5, - 9, 9, 10, 10, 6, 264, 23, 24, 9, 23, - - 10, 11, 11, 11, 11, 25, 15, 263, 3, 15, - 11, 24, 4, 12, 12, 12, 12, 27, 15, 25, - 27, 11, 12, 22, 22, 22, 22, 22, 22, 22, - 36, 32, 36, 12, 24, 32, 36, 48, 32, 261, - 48, 32, 25, 48, 32, 88, 260, 50, 71, 24, - 50, 50, 53, 53, 53, 54, 88, 25, 68, 50, - 54, 68, 71, 54, 72, 72, 109, 109, 109, 72, - 68, 70, 70, 70, 70, 70, 70, 70, 111, 48, - 114, 114, 158, 111, 158, 71, 74, 74, 74, 74, - 74, 74, 74, 76, 76, 76, 76, 76, 76, 76, - - 110, 151, 151, 110, 110, 115, 115, 122, 115, 132, - 115, 188, 110, 259, 132, 258, 188, 122, 122, 122, - 122, 122, 122, 122, 123, 123, 123, 123, 123, 123, - 123, 124, 124, 124, 124, 124, 124, 124, 129, 129, - 129, 129, 129, 129, 129, 159, 159, 159, 224, 224, - 129, 130, 130, 130, 130, 130, 130, 130, 160, 160, - 160, 164, 164, 164, 167, 167, 167, 167, 167, 167, - 167, 225, 225, 129, 256, 254, 167, 168, 168, 168, - 168, 168, 168, 168, 169, 169, 169, 169, 169, 169, - 169, 194, 194, 251, 250, 210, 249, 248, 194, 167, - - 210, 247, 246, 194, 245, 243, 242, 194, 202, 202, - 202, 202, 202, 202, 202, 203, 203, 203, 203, 203, - 203, 203, 226, 226, 226, 226, 226, 226, 226, 269, - 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, - 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, - 270, 271, 271, 271, 271, 271, 271, 271, 271, 271, - 271, 271, 272, 272, 272, 272, 272, 272, 272, 272, - 272, 272, 272, 273, 273, 273, 273, 273, 273, 273, - 273, 273, 273, 273, 274, 274, 241, 240, 239, 238, - 274, 275, 275, 275, 275, 275, 275, 276, 276, 233, - - 230, 227, 223, 276, 276, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 278, 222, 221, 278, - 278, 278, 278, 278, 278, 278, 278, 279, 220, 219, - 279, 279, 279, 279, 279, 279, 279, 279, 280, 280, - 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - 281, 282, 282, 216, 282, 283, 283, 283, 283, 283, - 283, 283, 283, 283, 283, 283, 215, 214, 213, 212, - 211, 207, 206, 205, 200, 199, 197, 196, 193, 187, - 186, 185, 184, 183, 181, 179, 178, 176, 174, 173, - 170, 166, 165, 163, 162, 161, 157, 155, 154, 153, - - 152, 150, 149, 148, 147, 146, 145, 144, 143, 142, - 141, 140, 139, 137, 136, 135, 134, 133, 121, 116, - 113, 108, 101, 100, 99, 98, 97, 96, 95, 94, - 93, 92, 91, 90, 89, 87, 86, 85, 84, 83, - 82, 81, 80, 79, 69, 66, 61, 52, 51, 49, - 45, 42, 41, 40, 39, 38, 37, 35, 34, 33, - 31, 30, 29, 28, 19, 13, 268, 268, 268, 268, - 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - - 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268 - } ; - -static yy_state_type yy_state_buf[YY_BUF_SIZE + 2], *yy_state_ptr; -static char *yy_full_match; -static int yy_lp; -#define REJECT \ -{ \ -*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ \ -yy_cp = yy_full_match; /* restore poss. backed-over text */ \ -++yy_lp; \ -goto find_rule; \ -} -#define yymore() yymore_used_but_not_detected -#define YY_MORE_ADJ 0 -#define YY_RESTORE_YY_MORE_OFFSET -char *yytext; -#line 1 "RCOMP.LEX" -#define INITIAL 0 -#line 3 "RCOMP.LEX" - -#include -#include -#include "main.h" -#include "structst.h" -#include "parser.h" -#include "localise.h" - -#define YY_SKIP_YYWRAP 1 -#define YY_NEVER_INTERACTIVE 1 -int yywrap(); -void yyerror(const char* string, ...); - -// Redefine YY_INPUT so we can parse binary data. -#undef YY_INPUT -#define YY_INPUT(buf, result, max_size) (result = new_yy_input(buf, max_size)) - -int new_yy_input(char *buf, int max_size) -{ - int result; - result = fread(buf, 1, max_size, yyin); - if (result == 0) - return YY_NULL; - - // check for utf8 (BOM) header in buf - for (int i = 0; i < result-3; i++) - { - if (buf[i] == 0xffffffef && buf[i+1] == 0xffffffbb && buf[i+2] == 0xffffffbf) - { - buf[i] = ' '; - buf[i+1] = ' '; - buf[i+2] = ' '; - } - } - return result; -} - -#include "rcomp.hpp" -#include "fileline.h" - -#define VALUE_LEN (1024*8) // must match sizeof(YYSTYPE.Value) -char buf[VALUE_LEN]; -char * pCh; -#define CHECK_APPEND(x) \ - if (pCh-buf==VALUE_LEN-1) { yyerror("string too long - %c ignored", (x)); } else {*pCh++ = (x); } - -int isCharLiteral; - -extern String InputBaseName; -extern FileLineManager* pFileLineHandler; -extern int* pCurrentLineNumber; -char RealLineNumber[200]; -// -// Disable MSVC warnings -// -#ifdef __VC32__ -#if 0 -..\src\RCOMP.L(95) : warning C4127: conditional expression is constant -..\src\RCOMP.L(114) : warning C4244: 'initializing' : conversion from 'const int' to 'YY_CHAR', possible loss of data -..\src\RCOMP.L(119) : warning C4244: '=' : conversion from 'const int' to 'YY_CHAR', possible loss of data -..\src\RCOMP.L(130) : warning C4102: 'find_rule' : unreferenced label -..\src\RCOMP.L(513) : warning C4244: 'initializing' : conversion from 'int' to 'YY_CHAR', possible loss of data -..\src\RCOMP.L(518) : warning C4244: '=' : conversion from 'const int' to 'YY_CHAR', possible loss of data -..\src\RCOMP.L(548) : warning C4244: '=' : conversion from 'const int' to 'YY_CHAR', possible loss of data -..\src\RCOMP.L(63) : warning C4505: 'yyunput' : unreferenced local function has been removed -\epoc32\BUILD\generatedcpp\rcomp\rcompl.cpp(243) : warning C4505: 'yy_flex_realloc' : unreferenced local function has been removed -#endif - -#pragma warning( disable : 4100 ) -#pragma warning( disable : 4102 ) -#pragma warning( disable : 4127 ) -#pragma warning( disable : 4244 ) -#pragma warning( disable : 4245 ) -#pragma warning( disable : 4505 ) -#endif //__VC32__ - -#include "errorhan.h" - -#define REGISTER_LINE ErrorHandler::Register(pFileLineHandler->GetCurrentFile(), pFileLineHandler->GetErrorLine(* pCurrentLineNumber)) - - -#define string_rules 1 - -/* Rule set for string literals. */ -/* n.b. Exclusive rule sets i.e. %x are available in MKS only */ -/* so they are not used here; hence all the 's. */ -#define file_line_rules 2 - -/* Rule set for file_line_directive.*/ -#define cpp_comment 3 - -/* C++ comment to end of line */ -#define c_comment 4 - -/* C comment */ -#define comment_tag 5 - -/* Doxygen-style comment tag */ -#line 761 "lex.yy.c" - -/* Macros after this point can all be overridden by user definitions in - * section 1. - */ - -#ifndef YY_SKIP_YYWRAP -#ifdef __cplusplus -extern "C" int yywrap YY_PROTO(( void )); -#else -extern int yywrap YY_PROTO(( void )); -#endif -#endif - -#ifndef YY_NO_UNPUT -static void yyunput YY_PROTO(( int c, char *buf_ptr )); -#endif - -#ifndef yytext_ptr -static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int )); -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen YY_PROTO(( yyconst char * )); -#endif - -#ifndef YY_NO_INPUT -#ifdef __cplusplus -static int yyinput YY_PROTO(( void )); -#else -static int input YY_PROTO(( void )); -#endif -#endif - -#if YY_STACK_USED -static int yy_start_stack_ptr = 0; -static int yy_start_stack_depth = 0; -static int *yy_start_stack = 0; -#ifndef YY_NO_PUSH_STATE -static void yy_push_state YY_PROTO(( int new_state )); -#endif -#ifndef YY_NO_POP_STATE -static void yy_pop_state YY_PROTO(( void )); -#endif -#ifndef YY_NO_TOP_STATE -static int yy_top_state YY_PROTO(( void )); -#endif - -#else -#define YY_NO_PUSH_STATE 1 -#define YY_NO_POP_STATE 1 -#define YY_NO_TOP_STATE 1 -#endif - -#ifdef YY_MALLOC_DECL -YY_MALLOC_DECL -#else -#if __STDC__ -#ifndef __cplusplus -#include -#endif -#else -/* Just try to get by without declaring the routines. This will fail - * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int) - * or sizeof(void*) != sizeof(int). - */ -#endif -#endif - -/* Amount of stuff to slurp up with each read. */ -#ifndef YY_READ_BUF_SIZE -#define YY_READ_BUF_SIZE 8192 -#endif - -/* Copy whatever the last rule matched to the standard output. */ - -#ifndef ECHO -/* This used to be an fputs(), but since the string might contain NUL's, - * we now use fwrite(). - */ -#define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) -#endif - -/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, - * is returned in "result". - */ -#ifndef YY_INPUT -#define YY_INPUT(buf,result,max_size) \ - if ( yy_current_buffer->yy_is_interactive ) \ - { \ - int c = '*', n; \ - for ( n = 0; n < max_size && \ - (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ - buf[n] = (char) c; \ - if ( c == '\n' ) \ - buf[n++] = (char) c; \ - if ( c == EOF && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - result = n; \ - } \ - else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \ - && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); -#endif - -/* No semi-colon after return; correct usage is to write "yyterminate();" - - * we don't want an extra ';' after the "return" because that will cause - * some compilers to complain about unreachable statements. - */ -#ifndef yyterminate -#define yyterminate() return YY_NULL -#endif - -/* Number of entries by which start-condition stack grows. */ -#ifndef YY_START_STACK_INCR -#define YY_START_STACK_INCR 25 -#endif - -/* Report a fatal error. */ -#ifndef YY_FATAL_ERROR -#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) -#endif - -/* Default declaration of generated scanner - a define so the user can - * easily add parameters. - */ -#ifndef YY_DECL -#define YY_DECL int yylex YY_PROTO(( void )) -#endif - -/* Code executed at the beginning of each rule, after yytext and yyleng - * have been set up. - */ -#ifndef YY_USER_ACTION -#define YY_USER_ACTION -#endif - -/* Code executed at the end of each rule. */ -#ifndef YY_BREAK -#define YY_BREAK break; -#endif - -#define YY_RULE_SETUP \ - YY_USER_ACTION - -YY_DECL - { - register yy_state_type yy_current_state; - register char *yy_cp, *yy_bp; - register int yy_act; - -#line 130 "RCOMP.LEX" - - - - /* Translations section */ - /* ==================== */ - - /*******************************************/ - /* Main keywords */ - /*******************************************/ -#line 922 "lex.yy.c" - - if ( yy_init ) - { - yy_init = 0; - -#ifdef YY_USER_INIT - YY_USER_INIT; -#endif - - if ( ! yy_start ) - yy_start = 1; /* first start state */ - - if ( ! yyin ) - yyin = stdin; - - if ( ! yyout ) - yyout = stdout; - - if ( ! yy_current_buffer ) - yy_current_buffer = - yy_create_buffer( yyin, YY_BUF_SIZE ); - - yy_load_buffer_state(); - } - - while ( 1 ) /* loops until end-of-file is reached */ - { - yy_cp = yy_c_buf_p; - - /* Support of yytext. */ - *yy_cp = yy_hold_char; - - /* yy_bp points to the position in yy_ch_buf of the start of - * the current run. - */ - yy_bp = yy_cp; - - yy_current_state = yy_start; - yy_state_ptr = yy_state_buf; - *yy_state_ptr++ = yy_current_state; -yy_match: - do - { - register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 269 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - *yy_state_ptr++ = yy_current_state; - ++yy_cp; - } - while ( yy_base[yy_current_state] != 567 ); - -yy_find_action: - yy_current_state = *--yy_state_ptr; - yy_lp = yy_accept[yy_current_state]; -find_rule: /* we branch to this label when backing up */ - for ( ; ; ) /* until we find what rule we matched */ - { - if ( yy_lp && yy_lp < yy_accept[yy_current_state + 1] ) - { - yy_act = yy_acclist[yy_lp]; - { - yy_full_match = yy_cp; - break; - } - } - --yy_cp; - yy_current_state = *--yy_state_ptr; - yy_lp = yy_accept[yy_current_state]; - } - - YY_DO_BEFORE_ACTION; - - if ( yy_act != YY_END_OF_BUFFER ) - { - int yyl; - for ( yyl = 0; yyl < yyleng; ++yyl ) - if ( yytext[yyl] == '\n' ) - ++yylineno; - } - -do_action: /* This label is used only to access EOF actions. */ - - - switch ( yy_act ) - { /* beginning of action switch */ -case 1: -YY_RULE_SETUP -#line 139 "RCOMP.LEX" -return L_STRUCT; - YY_BREAK -case 2: -YY_RULE_SETUP -#line 140 "RCOMP.LEX" -return L_RESOURCE; - YY_BREAK -case 3: -YY_RULE_SETUP -#line 141 "RCOMP.LEX" -return L_NAME; - YY_BREAK -case 4: -YY_RULE_SETUP -#line 142 "RCOMP.LEX" -return L_CHARACTER_SET; - YY_BREAK -case 5: -YY_RULE_SETUP -#line 143 "RCOMP.LEX" -return L_OFFSET; - YY_BREAK -case 6: -YY_RULE_SETUP -#line 144 "RCOMP.LEX" -return L_SYSTEM; - YY_BREAK -case 7: -YY_RULE_SETUP -#line 145 "RCOMP.LEX" -return L_GLOBAL; - YY_BREAK -case 8: -YY_RULE_SETUP -#line 146 "RCOMP.LEX" -return L_LOCAL; - YY_BREAK -case 9: -YY_RULE_SETUP -#line 147 "RCOMP.LEX" -return L_ENUM; - YY_BREAK -case 10: -YY_RULE_SETUP -#line 148 "RCOMP.LEX" -return L_ENUM; - YY_BREAK -case 11: -YY_RULE_SETUP -#line 149 "RCOMP.LEX" -return L_UID_TWO; - YY_BREAK -case 12: -YY_RULE_SETUP -#line 150 "RCOMP.LEX" -return L_UID_THREE; - YY_BREAK -case 13: -YY_RULE_SETUP -#line 151 "RCOMP.LEX" -return L_RLS_STRING; - YY_BREAK -case 14: -YY_RULE_SETUP -#line 152 "RCOMP.LEX" -return L_RLS_STRING8; - YY_BREAK -case 15: -YY_RULE_SETUP -#line 153 "RCOMP.LEX" -return L_RLS_DOUBLE; - YY_BREAK -case 16: -YY_RULE_SETUP -#line 154 "RCOMP.LEX" -return L_RLS_BYTE; - YY_BREAK -case 17: -YY_RULE_SETUP -#line 155 "RCOMP.LEX" -return L_RLS_WORD; - YY_BREAK -case 18: -YY_RULE_SETUP -#line 156 "RCOMP.LEX" -return L_RLS_LONG; - YY_BREAK -case 19: -YY_RULE_SETUP -#line 157 "RCOMP.LEX" -return L_MULTI; - YY_BREAK -/*******************************************/ -/* Types */ -/*******************************************/ -case 20: -YY_RULE_SETUP -#line 162 "RCOMP.LEX" -return L_BUF; - YY_BREAK -case 21: -YY_RULE_SETUP -#line 163 "RCOMP.LEX" -return L_BUF8; - YY_BREAK -case 22: -YY_RULE_SETUP -#line 164 "RCOMP.LEX" -return L_BUF16; - YY_BREAK -case 23: -YY_RULE_SETUP -#line 165 "RCOMP.LEX" -return L_WORD; - YY_BREAK -case 24: -YY_RULE_SETUP -#line 166 "RCOMP.LEX" -return L_BYTE; - YY_BREAK -case 25: -YY_RULE_SETUP -#line 167 "RCOMP.LEX" -return L_LONG; - YY_BREAK -case 26: -YY_RULE_SETUP -#line 168 "RCOMP.LEX" -return L_DOUBLE; - YY_BREAK -case 27: -YY_RULE_SETUP -#line 169 "RCOMP.LEX" -return L_TEXT; - YY_BREAK -case 28: -YY_RULE_SETUP -#line 170 "RCOMP.LEX" -return L_LTEXT; - YY_BREAK -case 29: -YY_RULE_SETUP -#line 171 "RCOMP.LEX" -return L_TEXT8; - YY_BREAK -case 30: -YY_RULE_SETUP -#line 172 "RCOMP.LEX" -return L_LTEXT8; - YY_BREAK -case 31: -YY_RULE_SETUP -#line 173 "RCOMP.LEX" -return L_TEXT16; - YY_BREAK -case 32: -YY_RULE_SETUP -#line 174 "RCOMP.LEX" -return L_LTEXT16; - YY_BREAK -case 33: -YY_RULE_SETUP -#line 175 "RCOMP.LEX" -return L_LINK; - YY_BREAK -case 34: -YY_RULE_SETUP -#line 176 "RCOMP.LEX" -return L_LLINK; - YY_BREAK -case 35: -YY_RULE_SETUP -#line 177 "RCOMP.LEX" -return L_SRLINK; - YY_BREAK -/*******************************************/ -/* Others */ -/*******************************************/ -case 36: -YY_RULE_SETUP -#line 183 "RCOMP.LEX" -return L_LEN; - YY_BREAK -/*******************************************/ -/* String & character literals */ -/*******************************************/ -case 37: -YY_RULE_SETUP -#line 189 "RCOMP.LEX" -{ BEGIN(string_rules); pCh = buf; isCharLiteral=0; } - YY_BREAK -case 38: -YY_RULE_SETUP -#line 190 "RCOMP.LEX" -{ BEGIN(string_rules); pCh = buf; isCharLiteral=1; } - YY_BREAK -/* Escaped single- and double-quotes.*/ -case 39: -YY_RULE_SETUP -#line 193 "RCOMP.LEX" -{ CHECK_APPEND('"'); } - YY_BREAK -case 40: -YY_RULE_SETUP -#line 194 "RCOMP.LEX" -{ CHECK_APPEND('\''); }; - YY_BREAK -/* Convert escaped character into corresponding actual character e.g. \t to tab. */ -case 41: -YY_RULE_SETUP -#line 197 "RCOMP.LEX" -{ CHECK_APPEND( * ( strchr("\rr\bb\ff\nn\tt\vv\aa", yytext[1])-1));} - YY_BREAK -/* Escaped backslash */ -case 42: -YY_RULE_SETUP -#line 200 "RCOMP.LEX" -{ CHECK_APPEND('\\'); } - YY_BREAK -case 43: -YY_RULE_SETUP -#line 202 "RCOMP.LEX" -/* Escaped newline ignored*/ ; - YY_BREAK -/* End of line before terminating double-quotes.*/ -case 44: -YY_RULE_SETUP -#line 205 "RCOMP.LEX" -{ yyerror( isCharLiteral?"Unterminated character literal":"Unterminated string"); BEGIN 0; } - YY_BREAK -/* End of string reached.*/ -case 45: -YY_RULE_SETUP -#line 208 "RCOMP.LEX" -{ - if (!isCharLiteral) - { - *pCh = '\0'; BEGIN(0); strcpy( yylval.Value, buf); - return L_STRING_LITERAL; - } - CHECK_APPEND(*yytext); - } - YY_BREAK -case 46: -YY_RULE_SETUP -#line 217 "RCOMP.LEX" -{ - if (isCharLiteral) - { - *pCh = '\0'; BEGIN(0); strcpy( yylval.Value, buf); return L_CHAR_LITERAL; - } - CHECK_APPEND(*yytext); - } - YY_BREAK -/* Anything other than \n is stored.*/ -case 47: -YY_RULE_SETUP -#line 226 "RCOMP.LEX" -{ CHECK_APPEND(*yytext); } - YY_BREAK -/*******************************************/ -/* Labels */ -/*******************************************/ -case 48: -YY_RULE_SETUP -#line 232 "RCOMP.LEX" -{ - BEGIN(0); - strcpy( yylval.Value, yytext); - return L_LABEL; - } - YY_BREAK -/*******************************************/ -/* Numbers */ -/*******************************************/ -case 49: -YY_RULE_SETUP -#line 241 "RCOMP.LEX" -{ strcpy( yylval.Value, yytext); return L_NUM_NATURAL; } - YY_BREAK -case 50: -YY_RULE_SETUP -#line 242 "RCOMP.LEX" -{ strcpy( yylval.Value, yytext); return L_NUM_NATURAL; } - YY_BREAK -case 51: -YY_RULE_SETUP -#line 243 "RCOMP.LEX" -{ strcpy( yylval.Value, yytext); return L_NUM_FLOAT;} - YY_BREAK -case 52: -YY_RULE_SETUP -#line 244 "RCOMP.LEX" -{ strcpy( yylval.Value, yytext); return L_NUM_FLOAT;} - YY_BREAK -case 53: -YY_RULE_SETUP -#line 245 "RCOMP.LEX" -{ strcpy( yylval.Value, yytext); return L_NUM_FLOAT;} - YY_BREAK -case 54: -YY_RULE_SETUP -#line 246 "RCOMP.LEX" -{ strcpy( yylval.Value, yytext); return L_NUM_FLOAT;} - YY_BREAK -case 55: -YY_RULE_SETUP -#line 247 "RCOMP.LEX" -{ strcpy( yylval.Value, yytext); return L_NUM_FLOAT;} - YY_BREAK -case 56: -YY_RULE_SETUP -#line 248 "RCOMP.LEX" -{ strcpy( yylval.Value, yytext); return L_NUM_FLOAT;} - YY_BREAK -/*******************************************/ -/* file_line_directive */ -/*******************************************/ -case 57: -YY_RULE_SETUP -#line 253 "RCOMP.LEX" -{ BEGIN(file_line_rules); strcpy( RealLineNumber, yytext+2); } - YY_BREAK -case 58: -*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ -yy_c_buf_p = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -YY_RULE_SETUP -#line 255 "RCOMP.LEX" -{ BEGIN(0); // # "" means start of base file. - pFileLineHandler->SetBase( InputBaseName, * pCurrentLineNumber); - } - YY_BREAK -case 59: -*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ -yy_c_buf_p = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -YY_RULE_SETUP -#line 259 "RCOMP.LEX" -{ BEGIN(0); // # means @ line of named base file. - pFileLineHandler->PostInclude( yytext, RealLineNumber, * pCurrentLineNumber); - } - YY_BREAK -case 60: -*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ -yy_c_buf_p = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -YY_RULE_SETUP -#line 263 "RCOMP.LEX" -{ - BEGIN(0); // # 1 means start of an included file. - pFileLineHandler->SetInclude( yytext, * pCurrentLineNumber); - } - YY_BREAK -case 61: -*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ -yy_c_buf_p = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -YY_RULE_SETUP -#line 268 "RCOMP.LEX" -{ - BEGIN(0); // # 2 means end of an included file and now at in . - pFileLineHandler->PostInclude( yytext, RealLineNumber, * pCurrentLineNumber); - } - YY_BREAK -/*******************************************/ -/* White space */ -/*******************************************/ -case 62: -YY_RULE_SETUP -#line 278 "RCOMP.LEX" -; // skipped - YY_BREAK -case 63: -YY_RULE_SETUP -#line 279 "RCOMP.LEX" -; // skipped - YY_BREAK -case 64: -YY_RULE_SETUP -#line 280 "RCOMP.LEX" -; // skipped - YY_BREAK -case 65: -YY_RULE_SETUP -#line 281 "RCOMP.LEX" -{ BEGIN(cpp_comment); } - YY_BREAK -case 66: -YY_RULE_SETUP -#line 282 "RCOMP.LEX" -{ BEGIN(0); } - YY_BREAK -case 67: -YY_RULE_SETUP -#line 283 "RCOMP.LEX" -; // skipped - YY_BREAK -case 68: -*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ -yy_c_buf_p = yy_cp = yy_bp + 2; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -YY_RULE_SETUP -#line 284 "RCOMP.LEX" -{ BEGIN(c_comment); } - YY_BREAK -case 69: -YY_RULE_SETUP -#line 285 "RCOMP.LEX" -{ BEGIN(c_comment); } - YY_BREAK -case 70: -YY_RULE_SETUP -#line 286 "RCOMP.LEX" -{ BEGIN(0); } - YY_BREAK -case 71: -YY_RULE_SETUP -#line 287 "RCOMP.LEX" -; // skipped - YY_BREAK -case 72: -YY_RULE_SETUP -#line 288 "RCOMP.LEX" -; // skipped - YY_BREAK -/*******************************************/ -/* Comment tags */ -/*******************************************/ -case 73: -YY_RULE_SETUP -#line 294 "RCOMP.LEX" -{ - BEGIN(comment_tag); - pGL->SetStart(*(pFileLineHandler->GetCurrentFile()), pFileLineHandler->GetErrorLine(* pCurrentLineNumber)); - return L_TAG_START; - } // any comment beginning with a slash followed by a star followed by an ampersand - YY_BREAK -case 74: -YY_RULE_SETUP -#line 299 "RCOMP.LEX" -{ - BEGIN(0); - return L_TAG_END; - } - YY_BREAK -case 75: -YY_RULE_SETUP -#line 303 "RCOMP.LEX" -{ strcpy( yylval.Value, yytext); return L_TAG_COMMAND; } - YY_BREAK -case 76: -YY_RULE_SETUP -#line 304 "RCOMP.LEX" -{ strcpy( yylval.Value, yytext); return L_TAG_WORD; } - YY_BREAK -case 77: -YY_RULE_SETUP -#line 305 "RCOMP.LEX" -{ strcpy( yylval.Value, "\n"); return L_TAG_NEW_LINE; } - YY_BREAK -case 78: -YY_RULE_SETUP -#line 306 "RCOMP.LEX" -; - YY_BREAK -/*******************************************/ -/* Special single characters */ -/*******************************************/ -case 79: -YY_RULE_SETUP -#line 311 "RCOMP.LEX" -return * yytext; - YY_BREAK -/*******************************************/ -/* Everything else cannot be recognised */ -/*******************************************/ -case 80: -YY_RULE_SETUP -#line 317 "RCOMP.LEX" -{ yyerror("*** Unknown character '%c' (value 0x%x) ", *yytext, *yytext);} - YY_BREAK -case 81: -YY_RULE_SETUP -#line 318 "RCOMP.LEX" -ECHO; - YY_BREAK -#line 1503 "lex.yy.c" - case YY_STATE_EOF(INITIAL): - case YY_STATE_EOF(string_rules): - case YY_STATE_EOF(file_line_rules): - case YY_STATE_EOF(cpp_comment): - case YY_STATE_EOF(c_comment): - case YY_STATE_EOF(comment_tag): - yyterminate(); - - case YY_END_OF_BUFFER: - { - /* Amount of text matched not including the EOB char. */ - int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1; - - /* Undo the effects of YY_DO_BEFORE_ACTION. */ - *yy_cp = yy_hold_char; - YY_RESTORE_YY_MORE_OFFSET - - if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW ) - { - /* We're scanning a new file or input source. It's - * possible that this happened because the user - * just pointed yyin at a new source and called - * yylex(). If so, then we have to assure - * consistency between yy_current_buffer and our - * globals. Here is the right place to do so, because - * this is the first action (other than possibly a - * back-up) that will match for the new input source. - */ - yy_n_chars = yy_current_buffer->yy_n_chars; - yy_current_buffer->yy_input_file = yyin; - yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL; - } - - /* Note that here we test for yy_c_buf_p "<=" to the position - * of the first EOB in the buffer, since yy_c_buf_p will - * already have been incremented past the NUL character - * (since all states make transitions on EOB to the - * end-of-buffer state). Contrast this with the test - * in input(). - */ - if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) - { /* This was really a NUL. */ - yy_state_type yy_next_state; - - yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state(); - - /* Okay, we're now positioned to make the NUL - * transition. We couldn't have - * yy_get_previous_state() go ahead and do it - * for us because it doesn't know how to deal - * with the possibility of jamming (and we don't - * want to build jamming into it because then it - * will run more slowly). - */ - - yy_next_state = yy_try_NUL_trans( yy_current_state ); - - yy_bp = yytext_ptr + YY_MORE_ADJ; - - if ( yy_next_state ) - { - /* Consume the NUL. */ - yy_cp = ++yy_c_buf_p; - yy_current_state = yy_next_state; - goto yy_match; - } - - else - { - yy_cp = yy_c_buf_p; - goto yy_find_action; - } - } - - else switch ( yy_get_next_buffer() ) - { - case EOB_ACT_END_OF_FILE: - { - yy_did_buffer_switch_on_eof = 0; - - if ( yywrap() ) - { - /* Note: because we've taken care in - * yy_get_next_buffer() to have set up - * yytext, we can now set up - * yy_c_buf_p so that if some total - * hoser (like flex itself) wants to - * call the scanner after we return the - * YY_NULL, it'll still work - another - * YY_NULL will get returned. - */ - yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; - - yy_act = YY_STATE_EOF(YY_START); - goto do_action; - } - - else - { - if ( ! yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; - } - break; - } - - case EOB_ACT_CONTINUE_SCAN: - yy_c_buf_p = - yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state(); - - yy_cp = yy_c_buf_p; - yy_bp = yytext_ptr + YY_MORE_ADJ; - goto yy_match; - - case EOB_ACT_LAST_MATCH: - yy_c_buf_p = - &yy_current_buffer->yy_ch_buf[yy_n_chars]; - - yy_current_state = yy_get_previous_state(); - - yy_cp = yy_c_buf_p; - yy_bp = yytext_ptr + YY_MORE_ADJ; - goto yy_find_action; - } - break; - } - - default: - YY_FATAL_ERROR( - "fatal flex scanner internal error--no action found" ); - } /* end of action switch */ - } /* end of scanning one token */ - } /* end of yylex */ - - -/* yy_get_next_buffer - try to read in a new buffer - * - * Returns a code representing an action: - * EOB_ACT_LAST_MATCH - - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position - * EOB_ACT_END_OF_FILE - end of file - */ - -static int yy_get_next_buffer() - { - register char *dest = yy_current_buffer->yy_ch_buf; - register char *source = yytext_ptr; - register int number_to_move, i; - int ret_val; - - if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) - YY_FATAL_ERROR( - "fatal flex scanner internal error--end of buffer missed" ); - - if ( yy_current_buffer->yy_fill_buffer == 0 ) - { /* Don't try to fill the buffer, so this is an EOF. */ - if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 ) - { - /* We matched a single character, the EOB, so - * treat this as a final EOF. - */ - return EOB_ACT_END_OF_FILE; - } - - else - { - /* We matched some text prior to the EOB, first - * process it. - */ - return EOB_ACT_LAST_MATCH; - } - } - - /* Try to read more data. */ - - /* First move last chars to start of buffer. */ - number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1; - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); - - if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING ) - /* don't do the read, it's not guaranteed to return an EOF, - * just force an EOF - */ - yy_current_buffer->yy_n_chars = yy_n_chars = 0; - - else - { - int num_to_read = - yy_current_buffer->yy_buf_size - number_to_move - 1; - - while ( num_to_read <= 0 ) - { /* Not enough room in the buffer - grow it. */ -#ifdef YY_USES_REJECT - YY_FATAL_ERROR( -"input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); -#else - - /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = yy_current_buffer; - - int yy_c_buf_p_offset = - (int) (yy_c_buf_p - b->yy_ch_buf); - - if ( b->yy_is_our_buffer ) - { - int new_size = b->yy_buf_size * 2; - - if ( new_size <= 0 ) - b->yy_buf_size += b->yy_buf_size / 8; - else - b->yy_buf_size *= 2; - - b->yy_ch_buf = (char *) - /* Include room in for 2 EOB chars. */ - yy_flex_realloc( (void *) b->yy_ch_buf, - b->yy_buf_size + 2 ); - } - else - /* Can't grow it, we don't own it. */ - b->yy_ch_buf = 0; - - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( - "fatal error - scanner input buffer overflow" ); - - yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; - - num_to_read = yy_current_buffer->yy_buf_size - - number_to_move - 1; -#endif - } - - if ( num_to_read > YY_READ_BUF_SIZE ) - num_to_read = YY_READ_BUF_SIZE; - - /* Read in more data. */ - YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), - yy_n_chars, num_to_read ); - - yy_current_buffer->yy_n_chars = yy_n_chars; - } - - if ( yy_n_chars == 0 ) - { - if ( number_to_move == YY_MORE_ADJ ) - { - ret_val = EOB_ACT_END_OF_FILE; - yyrestart( yyin ); - } - - else - { - ret_val = EOB_ACT_LAST_MATCH; - yy_current_buffer->yy_buffer_status = - YY_BUFFER_EOF_PENDING; - } - } - - else - ret_val = EOB_ACT_CONTINUE_SCAN; - - yy_n_chars += number_to_move; - yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; - yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; - - yytext_ptr = &yy_current_buffer->yy_ch_buf[0]; - - return ret_val; - } - - -/* yy_get_previous_state - get the state just before the EOB char was reached */ - -static yy_state_type yy_get_previous_state() - { - register yy_state_type yy_current_state; - register char *yy_cp; - - yy_current_state = yy_start; - yy_state_ptr = yy_state_buf; - *yy_state_ptr++ = yy_current_state; - - for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) - { - register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 269 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - *yy_state_ptr++ = yy_current_state; - } - - return yy_current_state; - } - - -/* yy_try_NUL_trans - try to make a transition on the NUL character - * - * synopsis - * next_state = yy_try_NUL_trans( current_state ); - */ - -#ifdef YY_USE_PROTOS -static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state ) -#else -static yy_state_type yy_try_NUL_trans( yy_current_state ) -yy_state_type yy_current_state; -#endif - { - register int yy_is_jam; - - register YY_CHAR yy_c = 1; - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 269 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 268); - if ( ! yy_is_jam ) - *yy_state_ptr++ = yy_current_state; - - return yy_is_jam ? 0 : yy_current_state; - } - - -#ifndef YY_NO_UNPUT -#ifdef YY_USE_PROTOS -static void yyunput( int c, register char *yy_bp ) -#else -static void yyunput( c, yy_bp ) -int c; -register char *yy_bp; -#endif - { - register char *yy_cp = yy_c_buf_p; - - /* undo effects of setting up yytext */ - *yy_cp = yy_hold_char; - - if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) - { /* need to shift things up to make room */ - /* +2 for EOB chars. */ - register int number_to_move = yy_n_chars + 2; - register char *dest = &yy_current_buffer->yy_ch_buf[ - yy_current_buffer->yy_buf_size + 2]; - register char *source = - &yy_current_buffer->yy_ch_buf[number_to_move]; - - while ( source > yy_current_buffer->yy_ch_buf ) - *--dest = *--source; - - yy_cp += (int) (dest - source); - yy_bp += (int) (dest - source); - yy_current_buffer->yy_n_chars = - yy_n_chars = yy_current_buffer->yy_buf_size; - - if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) - YY_FATAL_ERROR( "flex scanner push-back overflow" ); - } - - *--yy_cp = (char) c; - - if ( c == '\n' ) - --yylineno; - - yytext_ptr = yy_bp; - yy_hold_char = *yy_cp; - yy_c_buf_p = yy_cp; - } -#endif /* ifndef YY_NO_UNPUT */ - - -#ifdef __cplusplus -static int yyinput() -#else -static int input() -#endif - { - int c; - - *yy_c_buf_p = yy_hold_char; - - if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) - { - /* yy_c_buf_p now points to the character we want to return. - * If this occurs *before* the EOB characters, then it's a - * valid NUL; if not, then we've hit the end of the buffer. - */ - if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) - /* This was really a NUL. */ - *yy_c_buf_p = '\0'; - - else - { /* need more input */ - int offset = yy_c_buf_p - yytext_ptr; - ++yy_c_buf_p; - - switch ( yy_get_next_buffer() ) - { - case EOB_ACT_LAST_MATCH: - /* This happens because yy_g_n_b() - * sees that we've accumulated a - * token and flags that we need to - * try matching the token before - * proceeding. But for input(), - * there's no matching to consider. - * So convert the EOB_ACT_LAST_MATCH - * to EOB_ACT_END_OF_FILE. - */ - - /* Reset buffer status. */ - yyrestart( yyin ); - - /* fall through */ - - case EOB_ACT_END_OF_FILE: - { - if ( yywrap() ) - return EOF; - - if ( ! yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; -#ifdef __cplusplus - return yyinput(); -#else - return input(); -#endif - } - - case EOB_ACT_CONTINUE_SCAN: - yy_c_buf_p = yytext_ptr + offset; - break; - } - } - } - - c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */ - *yy_c_buf_p = '\0'; /* preserve yytext */ - yy_hold_char = *++yy_c_buf_p; - - if ( c == '\n' ) - ++yylineno; - - return c; - } - - -#ifdef YY_USE_PROTOS -void yyrestart( FILE *input_file ) -#else -void yyrestart( input_file ) -FILE *input_file; -#endif - { - if ( ! yy_current_buffer ) - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); - - yy_init_buffer( yy_current_buffer, input_file ); - yy_load_buffer_state(); - } - - -#ifdef YY_USE_PROTOS -void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) -#else -void yy_switch_to_buffer( new_buffer ) -YY_BUFFER_STATE new_buffer; -#endif - { - if ( yy_current_buffer == new_buffer ) - return; - - if ( yy_current_buffer ) - { - /* Flush out information for old buffer. */ - *yy_c_buf_p = yy_hold_char; - yy_current_buffer->yy_buf_pos = yy_c_buf_p; - yy_current_buffer->yy_n_chars = yy_n_chars; - } - - yy_current_buffer = new_buffer; - yy_load_buffer_state(); - - /* We don't actually know whether we did this switch during - * EOF (yywrap()) processing, but the only time this flag - * is looked at is after yywrap() is called, so it's safe - * to go ahead and always set it. - */ - yy_did_buffer_switch_on_eof = 1; - } - - -#ifdef YY_USE_PROTOS -void yy_load_buffer_state( void ) -#else -void yy_load_buffer_state() -#endif - { - yy_n_chars = yy_current_buffer->yy_n_chars; - yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos; - yyin = yy_current_buffer->yy_input_file; - yy_hold_char = *yy_c_buf_p; - } - - -#ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_create_buffer( FILE *file, int size ) -#else -YY_BUFFER_STATE yy_create_buffer( file, size ) -FILE *file; -int size; -#endif - { - YY_BUFFER_STATE b; - - b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_buf_size = size; - - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. - */ - b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 ); - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_is_our_buffer = 1; - - yy_init_buffer( b, file ); - - return b; - } - - -#ifdef YY_USE_PROTOS -void yy_delete_buffer( YY_BUFFER_STATE b ) -#else -void yy_delete_buffer( b ) -YY_BUFFER_STATE b; -#endif - { - if ( ! b ) - return; - - if ( b == yy_current_buffer ) - yy_current_buffer = (YY_BUFFER_STATE) 0; - - if ( b->yy_is_our_buffer ) - yy_flex_free( (void *) b->yy_ch_buf ); - - yy_flex_free( (void *) b ); - } - - -#ifndef YY_ALWAYS_INTERACTIVE -#ifndef YY_NEVER_INTERACTIVE -extern int isatty YY_PROTO(( int )); -#endif -#endif - -#ifdef YY_USE_PROTOS -void yy_init_buffer( YY_BUFFER_STATE b, FILE *file ) -#else -void yy_init_buffer( b, file ) -YY_BUFFER_STATE b; -FILE *file; -#endif - - - { - yy_flush_buffer( b ); - - b->yy_input_file = file; - b->yy_fill_buffer = 1; - -#if YY_ALWAYS_INTERACTIVE - b->yy_is_interactive = 1; -#else -#if YY_NEVER_INTERACTIVE - b->yy_is_interactive = 0; -#else - b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; -#endif -#endif - } - - -#ifdef YY_USE_PROTOS -void yy_flush_buffer( YY_BUFFER_STATE b ) -#else -void yy_flush_buffer( b ) -YY_BUFFER_STATE b; -#endif - - { - if ( ! b ) - return; - - b->yy_n_chars = 0; - - /* We always need two end-of-buffer characters. The first causes - * a transition to the end-of-buffer state. The second causes - * a jam in that state. - */ - b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; - b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; - - b->yy_buf_pos = &b->yy_ch_buf[0]; - - b->yy_at_bol = 1; - b->yy_buffer_status = YY_BUFFER_NEW; - - if ( b == yy_current_buffer ) - yy_load_buffer_state(); - } - - -#ifndef YY_NO_SCAN_BUFFER -#ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size ) -#else -YY_BUFFER_STATE yy_scan_buffer( base, size ) -char *base; -yy_size_t size; -#endif - { - YY_BUFFER_STATE b; - - if ( size < 2 || - base[size-2] != YY_END_OF_BUFFER_CHAR || - base[size-1] != YY_END_OF_BUFFER_CHAR ) - /* They forgot to leave room for the EOB's. */ - return 0; - - b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); - - b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ - b->yy_buf_pos = b->yy_ch_buf = base; - b->yy_is_our_buffer = 0; - b->yy_input_file = 0; - b->yy_n_chars = b->yy_buf_size; - b->yy_is_interactive = 0; - b->yy_at_bol = 1; - b->yy_fill_buffer = 0; - b->yy_buffer_status = YY_BUFFER_NEW; - - yy_switch_to_buffer( b ); - - return b; - } -#endif - - -#ifndef YY_NO_SCAN_STRING -#ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str ) -#else -YY_BUFFER_STATE yy_scan_string( yy_str ) -yyconst char *yy_str; -#endif - { - int len; - for ( len = 0; yy_str[len]; ++len ) - ; - - return yy_scan_bytes( yy_str, len ); - } -#endif - - -#ifndef YY_NO_SCAN_BYTES -#ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len ) -#else -YY_BUFFER_STATE yy_scan_bytes( bytes, len ) -yyconst char *bytes; -int len; -#endif - { - YY_BUFFER_STATE b; - char *buf; - yy_size_t n; - int i; - - /* Get memory for full buffer, including space for trailing EOB's. */ - n = len + 2; - buf = (char *) yy_flex_alloc( n ); - if ( ! buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); - - for ( i = 0; i < len; ++i ) - buf[i] = bytes[i]; - - buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; - - b = yy_scan_buffer( buf, n ); - if ( ! b ) - YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); - - /* It's okay to grow etc. this buffer, and we should throw it - * away when we're done. - */ - b->yy_is_our_buffer = 1; - - return b; - } -#endif - - -#ifndef YY_NO_PUSH_STATE -#ifdef YY_USE_PROTOS -static void yy_push_state( int new_state ) -#else -static void yy_push_state( new_state ) -int new_state; -#endif - { - if ( yy_start_stack_ptr >= yy_start_stack_depth ) - { - yy_size_t new_size; - - yy_start_stack_depth += YY_START_STACK_INCR; - new_size = yy_start_stack_depth * sizeof( int ); - - if ( ! yy_start_stack ) - yy_start_stack = (int *) yy_flex_alloc( new_size ); - - else - yy_start_stack = (int *) yy_flex_realloc( - (void *) yy_start_stack, new_size ); - - if ( ! yy_start_stack ) - YY_FATAL_ERROR( - "out of memory expanding start-condition stack" ); - } - - yy_start_stack[yy_start_stack_ptr++] = YY_START; - - BEGIN(new_state); - } -#endif - - -#ifndef YY_NO_POP_STATE -static void yy_pop_state() - { - if ( --yy_start_stack_ptr < 0 ) - YY_FATAL_ERROR( "start-condition stack underflow" ); - - BEGIN(yy_start_stack[yy_start_stack_ptr]); - } -#endif - - -#ifndef YY_NO_TOP_STATE -static int yy_top_state() - { - return yy_start_stack[yy_start_stack_ptr - 1]; - } -#endif - -#ifndef YY_EXIT_FAILURE -#define YY_EXIT_FAILURE 2 -#endif - -#ifdef YY_USE_PROTOS -static void yy_fatal_error( yyconst char msg[] ) -#else -static void yy_fatal_error( msg ) -char msg[]; -#endif - { - (void) fprintf( stderr, "%s\n", msg ); - exit( YY_EXIT_FAILURE ); - } - - - -/* Redefine yyless() so it works in section 3 code. */ - -#undef yyless -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - yytext[yyleng] = yy_hold_char; \ - yy_c_buf_p = yytext + n; \ - yy_hold_char = *yy_c_buf_p; \ - *yy_c_buf_p = '\0'; \ - yyleng = n; \ - } \ - while ( 0 ) - - -/* Internal utility routines. */ - -#ifndef yytext_ptr -#ifdef YY_USE_PROTOS -static void yy_flex_strncpy( char *s1, yyconst char *s2, int n ) -#else -static void yy_flex_strncpy( s1, s2, n ) -char *s1; -yyconst char *s2; -int n; -#endif - { - register int i; - for ( i = 0; i < n; ++i ) - s1[i] = s2[i]; - } -#endif - -#ifdef YY_NEED_STRLEN -#ifdef YY_USE_PROTOS -static int yy_flex_strlen( yyconst char *s ) -#else -static int yy_flex_strlen( s ) -yyconst char *s; -#endif - { - register int n; - for ( n = 0; s[n]; ++n ) - ; - - return n; - } -#endif - - -#ifdef YY_USE_PROTOS -static void *yy_flex_alloc( yy_size_t size ) -#else -static void *yy_flex_alloc( size ) -yy_size_t size; -#endif - { - return (void *) malloc( size ); - } - -#ifdef YY_USE_PROTOS -static void *yy_flex_realloc( void *ptr, yy_size_t size ) -#else -static void *yy_flex_realloc( ptr, size ) -void *ptr; -yy_size_t size; -#endif - { - /* The cast to (char *) in the following accommodates both - * implementations that use char* generic pointers, and those - * that use void* generic pointers. It works with the latter - * because both ANSI C and C++ allow castless assignment from - * any pointer type to void*, and deal with argument conversions - * as though doing an assignment. - */ - return (void *) realloc( (char *) ptr, size ); - } - -#ifdef YY_USE_PROTOS -static void yy_flex_free( void *ptr ) -#else -static void yy_flex_free( ptr ) -void *ptr; -#endif - { - free( ptr ); - } - -#if YY_MAIN -int main() - { - yylex(); - return 0; - } -#endif -#line 318 "RCOMP.LEX" +/* +* Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* A lexical scanner generated by flex. +* Scanner skeleton version: +* $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.91 96/09/10 16:58:48 vern Exp $ +* +*/ + + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 + +#include + + +/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ +#ifdef c_plusplus +#ifndef __cplusplus +#define __cplusplus +#endif +#endif + + +#ifdef __cplusplus + +#include +#include + +/* Use prototypes in function declarations. */ +#define YY_USE_PROTOS + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +#if __STDC__ + +#define YY_USE_PROTOS +#define YY_USE_CONST + +#endif /* __STDC__ */ +#endif /* ! __cplusplus */ + +#ifdef __TURBOC__ + #pragma warn -rch + #pragma warn -use +#include +#include +#define YY_USE_CONST +#define YY_USE_PROTOS +#endif + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + + +#ifdef YY_USE_PROTOS +#define YY_PROTO(proto) proto +#else +#define YY_PROTO(proto) () +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN yy_start = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START ((yy_start - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart( yyin ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#define YY_BUF_SIZE 16384 + +typedef struct yy_buffer_state *YY_BUFFER_STATE; + +extern int yyleng; +extern FILE *yyin, *yyout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + +/* The funky do-while in the following #define is used to turn the definition + * int a single C statement (which needs a semi-colon terminator). This + * avoids problems with code like: + * + * if ( condition_holds ) + * yyless( 5 ); + * else + * do_something_else(); + * + * Prior to using the do-while the compiler would get upset at the + * "else" because it interpreted the "if" statement as being all + * done when it reached the ';' after the yyless() call. + */ + +/* Return all but the first 'n' matched characters back to the input stream. */ + +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + *yy_cp = yy_hold_char; \ + YY_RESTORE_YY_MORE_OFFSET \ + yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, yytext_ptr ) + +/* The following is because we cannot portably get our hands on size_t + * (without autoconf's help, which isn't available because we want + * flex-generated scanners to compile on their own). + */ +typedef unsigned int yy_size_t; + + +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + }; + +static YY_BUFFER_STATE yy_current_buffer = 0; + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + */ +#define YY_CURRENT_BUFFER yy_current_buffer + + +/* yy_hold_char holds the character lost when yytext is formed. */ +static char yy_hold_char; + +static int yy_n_chars; /* number of characters read into yy_ch_buf */ + + +int yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = (char *) 0; +static int yy_init = 1; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void yyrestart YY_PROTO(( FILE *input_file )); + +void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer )); +void yy_load_buffer_state YY_PROTO(( void )); +YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size )); +void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b )); +void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file )); +void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b )); +#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer ) + +YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size )); +YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str )); +YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len )); + +static void *yy_flex_alloc YY_PROTO(( yy_size_t )); +static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t )); +static void yy_flex_free YY_PROTO(( void * )); + +#define yy_new_buffer yy_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! yy_current_buffer ) \ + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ + yy_current_buffer->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! yy_current_buffer ) \ + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ + yy_current_buffer->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (yy_current_buffer->yy_at_bol) + + +#define YY_USES_REJECT +typedef unsigned char YY_CHAR; +FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; +typedef int yy_state_type; +extern int yylineno; +int yylineno = 1; +extern char *yytext; +#define yytext_ptr yytext + +static yy_state_type yy_get_previous_state YY_PROTO(( void )); +static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state )); +static int yy_get_next_buffer YY_PROTO(( void )); +static void yy_fatal_error YY_PROTO(( yyconst char msg[] )); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + yytext_ptr = yy_bp; \ + yyleng = (int) (yy_cp - yy_bp); \ + yy_hold_char = *yy_cp; \ + *yy_cp = '\0'; \ + yy_c_buf_p = yy_cp; + +#define YY_NUM_RULES 81 +#define YY_END_OF_BUFFER 82 +static yyconst short int yy_acclist[363] = + { 0, + 82, 80, 81, 62, 80, 81, 63, 81, 63, 80, + 81, 37, 80, 81, 80, 81, 38, 80, 81, 79, + 80, 81, 79, 80, 81, 79, 80, 81, 49, 80, + 81, 49, 80, 81, 48, 80, 81, 48, 80, 81, + 48, 80, 81, 48, 80, 81, 48, 80, 81, 48, + 80, 81, 48, 80, 81, 48, 80, 81, 48, 80, + 81, 48, 80, 81, 48, 80, 81, 48, 80, 81, + 48, 80, 81, 48, 80, 81, 48, 80, 81, 48, + 80, 81, 48, 80, 81, 47, 80, 81, 44, 81, + 47, 80, 81, 45, 47, 80, 81, 46, 47, 80, + + 81, 47, 80, 81, 80, 81, 62, 80, 81, 64, + 81, 64, 80, 81, 80, 81, 80, 81, 67, 80, + 81, 66, 81, 66, 67, 80, 81, 72, 80, 81, + 71, 81, 71, 72, 80, 81, 72, 80, 81, 76, + 80, 81, 78, 80, 81, 77, 81, 77, 80, 81, + 78, 80, 81, 80, 81, 65, 49, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 44, 43, 39, 40, 42, 41, 58, 59, 65, + 70, 76, 74, 75, 68, 69, 68, 69, 73, 53, + + 55, 50, 20, 48, 48, 48, 48, 48, 48, 36, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 59, 68, + 69, 68, 69, 68, 73, 54, 56, 48, 21, 48, + 24, 48, 48, 48, 9, 48, 48, 33, 48, 48, + 48, 25, 48, 48, 3, 48, 48, 48, 48, 48, + 48, 27, 48, 11, 48, 12, 48, 23, 48, 10, + 48, 48, 48, 60, 61, 57, 51, 22, 48, 48, + 48, 48, 34, 48, 8, 48, 28, 48, 48, 48, + 48, 48, 48, 48, 29, 48, 19, 48, 48, 48, + + 48, 48, 48, 52, 48, 26, 48, 7, 48, 48, + 30, 48, 5, 48, 48, 35, 48, 1, 48, 6, + 48, 31, 48, 48, 48, 48, 48, 48, 48, 32, + 48, 48, 48, 48, 48, 48, 48, 48, 2, 48, + 16, 48, 48, 18, 48, 48, 17, 48, 48, 48, + 48, 48, 15, 48, 13, 48, 48, 14, 48, 48, + 4, 48 + } ; + +static yyconst short int yy_accept[270] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 2, 4, 7, 9, 12, 15, 17, + 20, 23, 26, 29, 32, 35, 38, 41, 44, 47, + 50, 53, 56, 59, 62, 65, 68, 71, 74, 77, + 80, 83, 86, 89, 91, 94, 98, 102, 105, 107, + 110, 112, 115, 117, 119, 122, 124, 128, 131, 133, + 137, 140, 143, 146, 148, 151, 154, 156, 156, 156, + 156, 156, 156, 157, 157, 158, 158, 158, 159, 160, + 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, + 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, + + 181, 182, 183, 184, 185, 186, 187, 188, 188, 188, + 188, 188, 190, 190, 190, 190, 191, 192, 193, 194, + 195, 195, 195, 195, 195, 196, 197, 199, 200, 201, + 202, 203, 205, 206, 207, 208, 209, 210, 212, 213, + 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 230, 230, 230, + 230, 231, 232, 234, 235, 236, 236, 237, 238, 238, + 239, 241, 243, 244, 245, 247, 248, 250, 251, 252, + 254, 255, 257, 258, 259, 260, 261, 262, 264, 266, + 268, 270, 272, 273, 274, 275, 275, 275, 276, 276, + + 276, 277, 277, 278, 280, 281, 282, 283, 285, 287, + 289, 290, 291, 292, 293, 294, 295, 297, 299, 300, + 301, 302, 303, 304, 304, 304, 305, 306, 308, 310, + 311, 313, 315, 316, 318, 320, 322, 324, 325, 326, + 327, 328, 329, 330, 332, 333, 334, 335, 336, 337, + 338, 339, 341, 343, 344, 346, 347, 349, 350, 351, + 352, 353, 355, 357, 358, 360, 361, 363, 363 + } ; + +static yyconst int yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 5, 1, 6, 7, 1, 1, 8, 9, 10, + 10, 11, 10, 10, 12, 13, 14, 15, 16, 17, + 18, 19, 19, 20, 19, 21, 19, 1, 10, 10, + 10, 10, 1, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 32, + 32, 38, 39, 40, 41, 32, 42, 43, 44, 32, + 10, 45, 10, 1, 46, 1, 47, 48, 47, 49, + + 50, 51, 52, 53, 54, 53, 53, 55, 56, 57, + 58, 53, 53, 59, 60, 61, 62, 63, 64, 65, + 66, 53, 10, 10, 10, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static yyconst int yy_meta[67] = + { 0, + 1, 2, 3, 2, 2, 4, 1, 1, 4, 1, + 2, 1, 5, 1, 6, 6, 6, 6, 6, 6, + 6, 1, 7, 7, 7, 7, 6, 7, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 4, 8, 7, 9, 7, 6, + 9, 8, 8, 8, 8, 8, 10, 8, 10, 8, + 10, 8, 10, 8, 11, 8 + } ; + +static yyconst short int yy_base[284] = + { 0, + 0, 0, 64, 68, 76, 81, 72, 85, 88, 90, + 100, 112, 566, 567, 105, 567, 567, 567, 560, 567, + 567, 109, 86, 85, 93, 0, 77, 534, 526, 526, + 527, 105, 537, 531, 531, 93, 530, 525, 518, 497, + 491, 497, 567, 567, 548, 567, 567, 135, 544, 146, + 543, 542, 150, 150, 567, 567, 567, 567, 567, 567, + 533, 0, 567, 567, 567, 532, 0, 157, 534, 157, + 136, 162, 567, 172, 0, 179, 0, 0, 516, 503, + 519, 500, 499, 502, 502, 501, 505, 121, 508, 499, + 505, 493, 497, 492, 490, 485, 501, 488, 463, 469, + + 463, 567, 567, 567, 567, 567, 567, 516, 164, 199, + 173, 567, 518, 165, 203, 514, 567, 0, 567, 0, + 511, 203, 210, 217, 567, 567, 567, 567, 224, 237, + 0, 194, 491, 479, 492, 480, 490, 0, 480, 476, + 488, 481, 466, 481, 468, 469, 474, 463, 463, 462, + 185, 475, 444, 438, 452, 567, 494, 177, 243, 256, + 490, 489, 488, 259, 487, 486, 250, 263, 270, 471, + 0, 0, 467, 455, 0, 465, 0, 454, 452, 0, + 445, 0, 457, 442, 446, 456, 453, 196, 0, 0, + 0, 0, 425, 244, 567, 475, 459, 567, 473, 457, + + 567, 294, 301, 0, 449, 446, 438, 0, 0, 280, + 431, 432, 436, 428, 432, 434, 0, 0, 364, 371, + 361, 357, 345, 246, 269, 308, 362, 0, 0, 381, + 0, 0, 375, 0, 0, 0, 0, 329, 327, 331, + 328, 248, 279, 0, 278, 253, 254, 246, 243, 246, + 256, 0, 0, 221, 0, 218, 0, 170, 164, 95, + 101, 0, 87, 69, 0, 29, 0, 567, 329, 340, + 351, 362, 373, 380, 386, 395, 405, 416, 427, 434, + 440, 446, 455 + } ; + +static yyconst short int yy_def[284] = + { 0, + 268, 1, 269, 269, 270, 270, 271, 271, 272, 272, + 273, 273, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 274, 274, 275, 275, 275, 275, 275, + 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, + 275, 275, 268, 268, 268, 268, 268, 276, 277, 277, + 277, 277, 268, 277, 268, 268, 268, 268, 268, 268, + 268, 278, 268, 268, 268, 268, 279, 268, 268, 268, + 280, 281, 268, 268, 25, 268, 282, 275, 275, 275, + 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, + 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, + + 275, 268, 268, 268, 268, 268, 268, 277, 268, 277, + 277, 268, 268, 268, 283, 277, 268, 278, 268, 279, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 282, 275, 275, 275, 275, 275, 275, 275, 275, 275, + 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, + 275, 275, 275, 275, 275, 268, 268, 277, 268, 268, + 277, 277, 277, 268, 277, 268, 268, 268, 268, 275, + 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, + 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, + 275, 275, 275, 275, 268, 268, 268, 268, 268, 268, + + 268, 268, 268, 275, 275, 275, 275, 275, 275, 275, + 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, + 275, 275, 275, 268, 268, 268, 275, 275, 275, 275, + 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, + 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, + 275, 275, 275, 275, 275, 275, 275, 275, 275, 275, + 275, 275, 275, 275, 275, 275, 275, 0, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268 + } ; + +static yyconst short int yy_nxt[634] = + { 0, + 14, 15, 16, 17, 15, 18, 19, 14, 20, 21, + 21, 22, 21, 23, 24, 25, 25, 25, 25, 25, + 25, 14, 26, 27, 28, 29, 30, 26, 31, 26, + 26, 26, 26, 32, 26, 33, 34, 35, 36, 37, + 38, 39, 26, 26, 14, 26, 26, 26, 26, 40, + 26, 26, 26, 26, 26, 41, 26, 26, 42, 26, + 26, 26, 26, 26, 26, 26, 44, 45, 267, 46, + 44, 45, 47, 46, 56, 57, 47, 50, 51, 52, + 50, 53, 50, 51, 52, 50, 53, 56, 57, 54, + 59, 60, 59, 60, 54, 266, 72, 74, 61, 73, + + 61, 63, 64, 65, 63, 74, 68, 265, 48, 68, + 66, 76, 48, 63, 64, 65, 63, 79, 69, 76, + 80, 67, 66, 71, 71, 71, 71, 71, 71, 71, + 93, 85, 94, 67, 76, 86, 95, 103, 87, 264, + 104, 88, 76, 105, 89, 141, 263, 110, 123, 77, + 110, 109, 112, 113, 114, 109, 142, 268, 68, 111, + 115, 68, 124, 116, 126, 127, 156, 157, 114, 128, + 69, 122, 122, 122, 122, 122, 122, 122, 109, 106, + 159, 160, 109, 158, 165, 124, 129, 129, 129, 129, + 129, 129, 129, 130, 130, 130, 130, 130, 130, 130, + + 110, 189, 190, 110, 109, 162, 163, 166, 164, 170, + 165, 216, 111, 262, 171, 261, 217, 122, 122, 122, + 122, 122, 122, 122, 167, 167, 167, 167, 167, 167, + 167, 168, 168, 168, 168, 168, 168, 168, 129, 129, + 129, 129, 129, 129, 129, 195, 196, 197, 195, 196, + 169, 130, 130, 130, 130, 130, 130, 130, 198, 199, + 200, 156, 157, 114, 167, 167, 167, 167, 167, 167, + 167, 198, 199, 169, 260, 259, 202, 168, 168, 168, + 168, 168, 168, 168, 203, 203, 203, 203, 203, 203, + 203, 219, 220, 258, 257, 230, 256, 255, 221, 202, + + 231, 254, 253, 222, 252, 251, 250, 223, 226, 226, + 226, 226, 226, 226, 226, 203, 203, 203, 203, 203, + 203, 203, 226, 226, 226, 226, 226, 226, 226, 43, + 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 75, 75, 249, 248, 247, 246, + 75, 78, 78, 78, 78, 78, 78, 107, 107, 245, + + 244, 243, 242, 107, 107, 108, 108, 108, 108, 108, + 108, 108, 108, 108, 108, 108, 118, 241, 240, 118, + 118, 118, 118, 118, 118, 118, 118, 120, 239, 238, + 120, 120, 120, 120, 120, 120, 120, 120, 71, 71, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 131, 131, 237, 131, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 236, 235, 234, 233, + 232, 229, 228, 227, 225, 198, 224, 195, 218, 215, + 214, 213, 212, 211, 210, 209, 208, 207, 206, 205, + 204, 201, 109, 109, 109, 109, 156, 194, 193, 192, + + 191, 188, 187, 186, 185, 184, 183, 182, 181, 180, + 179, 178, 177, 176, 175, 174, 173, 172, 128, 109, + 112, 109, 155, 154, 153, 152, 151, 150, 149, 148, + 147, 146, 145, 144, 143, 140, 139, 138, 137, 136, + 135, 134, 133, 132, 121, 119, 117, 109, 109, 109, + 102, 101, 100, 99, 98, 97, 96, 92, 91, 90, + 84, 83, 82, 81, 70, 268, 13, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268 + } ; + +static yyconst short int yy_chk[634] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 3, 3, 266, 3, + 4, 4, 3, 4, 7, 7, 4, 5, 5, 5, + 5, 5, 6, 6, 6, 6, 6, 8, 8, 5, + 9, 9, 10, 10, 6, 264, 23, 24, 9, 23, + + 10, 11, 11, 11, 11, 25, 15, 263, 3, 15, + 11, 24, 4, 12, 12, 12, 12, 27, 15, 25, + 27, 11, 12, 22, 22, 22, 22, 22, 22, 22, + 36, 32, 36, 12, 24, 32, 36, 48, 32, 261, + 48, 32, 25, 48, 32, 88, 260, 50, 71, 24, + 50, 50, 53, 53, 53, 54, 88, 25, 68, 50, + 54, 68, 71, 54, 72, 72, 109, 109, 109, 72, + 68, 70, 70, 70, 70, 70, 70, 70, 111, 48, + 114, 114, 158, 111, 158, 71, 74, 74, 74, 74, + 74, 74, 74, 76, 76, 76, 76, 76, 76, 76, + + 110, 151, 151, 110, 110, 115, 115, 122, 115, 132, + 115, 188, 110, 259, 132, 258, 188, 122, 122, 122, + 122, 122, 122, 122, 123, 123, 123, 123, 123, 123, + 123, 124, 124, 124, 124, 124, 124, 124, 129, 129, + 129, 129, 129, 129, 129, 159, 159, 159, 224, 224, + 129, 130, 130, 130, 130, 130, 130, 130, 160, 160, + 160, 164, 164, 164, 167, 167, 167, 167, 167, 167, + 167, 225, 225, 129, 256, 254, 167, 168, 168, 168, + 168, 168, 168, 168, 169, 169, 169, 169, 169, 169, + 169, 194, 194, 251, 250, 210, 249, 248, 194, 167, + + 210, 247, 246, 194, 245, 243, 242, 194, 202, 202, + 202, 202, 202, 202, 202, 203, 203, 203, 203, 203, + 203, 203, 226, 226, 226, 226, 226, 226, 226, 269, + 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, + 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, + 270, 271, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 273, 273, 273, 273, 273, 273, 273, + 273, 273, 273, 273, 274, 274, 241, 240, 239, 238, + 274, 275, 275, 275, 275, 275, 275, 276, 276, 233, + + 230, 227, 223, 276, 276, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 278, 222, 221, 278, + 278, 278, 278, 278, 278, 278, 278, 279, 220, 219, + 279, 279, 279, 279, 279, 279, 279, 279, 280, 280, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 282, 282, 216, 282, 283, 283, 283, 283, 283, + 283, 283, 283, 283, 283, 283, 215, 214, 213, 212, + 211, 207, 206, 205, 200, 199, 197, 196, 193, 187, + 186, 185, 184, 183, 181, 179, 178, 176, 174, 173, + 170, 166, 165, 163, 162, 161, 157, 155, 154, 153, + + 152, 150, 149, 148, 147, 146, 145, 144, 143, 142, + 141, 140, 139, 137, 136, 135, 134, 133, 121, 116, + 113, 108, 101, 100, 99, 98, 97, 96, 95, 94, + 93, 92, 91, 90, 89, 87, 86, 85, 84, 83, + 82, 81, 80, 79, 69, 66, 61, 52, 51, 49, + 45, 42, 41, 40, 39, 38, 37, 35, 34, 33, + 31, 30, 29, 28, 19, 13, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268 + } ; + +static yy_state_type yy_state_buf[YY_BUF_SIZE + 2], *yy_state_ptr; +static char *yy_full_match; +static int yy_lp; +#define REJECT \ +{ \ +*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ \ +yy_cp = yy_full_match; /* restore poss. backed-over text */ \ +++yy_lp; \ +goto find_rule; \ +} +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +char *yytext; +#line 1 "RCOMP.LEX" +#define INITIAL 0 +#line 3 "RCOMP.LEX" + +#include +#include +#include "main.h" +#include "STRUCTST.H" +#include "Parser.h" +#include "localise.h" + +#define YY_SKIP_YYWRAP 1 +#define YY_NEVER_INTERACTIVE 1 +int yywrap(); +void yyerror(const char* string, ...); + +// Redefine YY_INPUT so we can parse binary data. +#undef YY_INPUT +#define YY_INPUT(buf, result, max_size) (result = new_yy_input(buf, max_size)) + +int new_yy_input(char *buf, int max_size) +{ + int result; + if(yyin != NULL) { + result = fread(buf, 1, max_size, yyin); + } + else if((pG->StdInBuffer != NULL) && (pG->StdInBufLength > 0)) { + int left = pG->StdInBufLength - pG->StdInfBufPos ; + if(left == 0) + return YY_NULL ; + result = (max_size < left) ? max_size : left ; + memcpy(buf,&(pG->StdInBuffer[pG->StdInfBufPos]),result); + pG->StdInfBufPos += result ; + } + + if (result == 0) + return YY_NULL; + const unsigned char BOM[] = {0xef , 0xbb, 0xbf, 0x0 }; + // check for utf8 (BOM) header in buf + for (int i = 0; i < result-3; i++) { + if (0 == memcmp(&buf[i],BOM,3)) { + memset(&buf[i],0x20,3); + } + } + return result; +} + +#include "rcomp.hpp" +#include "FILELINE.H" + +#define VALUE_LEN (1024*8) // must match sizeof(YYSTYPE.Value) +char buf[VALUE_LEN]; +char * pCh; +#define CHECK_APPEND(x) \ + if (pCh-buf==VALUE_LEN-1) { yyerror("string too long - %c ignored", (x)); } else {*pCh++ = (x); } + +int isCharLiteral; + +extern String InputBaseName; +extern FileLineManager* pFileLineHandler; +extern int* pCurrentLineNumber; +char RealLineNumber[200]; + + +#include "ERRORHAN.H" + +#define REGISTER_LINE ErrorHandler::Register(pFileLineHandler->GetCurrentFile(), pFileLineHandler->GetErrorLine(* pCurrentLineNumber)) + + +#define string_rules 1 + +/* Rule set for string literals. */ +/* n.b. Exclusive rule sets i.e. %x are available in MKS only */ +/* so they are not used here; hence all the 's. */ +#define file_line_rules 2 + +/* Rule set for file_line_directive.*/ +#define cpp_comment 3 + +/* C++ comment to end of line */ +#define c_comment 4 + +/* C comment */ +#define comment_tag 5 + +/* Doxygen-style comment tag */ +#line 761 "lex.yy.c" + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap YY_PROTO(( void )); +#else +extern int yywrap YY_PROTO(( void )); +#endif +#endif + +#ifndef YY_NO_UNPUT +static void yyunput YY_PROTO(( int c, char *buf_ptr )); +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int )); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen YY_PROTO(( yyconst char * )); +#endif + +#ifndef YY_NO_INPUT +#ifdef __cplusplus +static int yyinput YY_PROTO(( void )); +#else +static int input YY_PROTO(( void )); +#endif +#endif + +#if YY_STACK_USED +static int yy_start_stack_ptr = 0; +static int yy_start_stack_depth = 0; +static int *yy_start_stack = 0; +#ifndef YY_NO_PUSH_STATE +static void yy_push_state YY_PROTO(( int new_state )); +#endif +#ifndef YY_NO_POP_STATE +static void yy_pop_state YY_PROTO(( void )); +#endif +#ifndef YY_NO_TOP_STATE +static int yy_top_state YY_PROTO(( void )); +#endif + +#else +#define YY_NO_PUSH_STATE 1 +#define YY_NO_POP_STATE 1 +#define YY_NO_TOP_STATE 1 +#endif + +#ifdef YY_MALLOC_DECL +YY_MALLOC_DECL +#else +#if __STDC__ +#ifndef __cplusplus +#include +#endif +#else +/* Just try to get by without declaring the routines. This will fail + * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int) + * or sizeof(void*) != sizeof(int). + */ +#endif +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ + +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#error "Unexpected behavior!" +#define YY_INPUT(buf,result,max_size) \ + if ( yy_current_buffer->yy_is_interactive ) \ + { \ + int c = '*', n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \ + && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL int yylex YY_PROTO(( void )) +#endif + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +YY_DECL + { + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + +#line 130 "RCOMP.LEX" + + + + /* Translations section */ + /* ==================== */ + + /*******************************************/ + /* Main keywords */ + /*******************************************/ +#line 922 "lex.yy.c" + + if ( yy_init ) + { + yy_init = 0; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! yy_start ) + yy_start = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! yy_current_buffer ) + yy_current_buffer = + yy_create_buffer( yyin, YY_BUF_SIZE ); + + yy_load_buffer_state(); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = yy_c_buf_p; + + /* Support of yytext. */ + *yy_cp = yy_hold_char; + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = yy_start; + yy_state_ptr = yy_state_buf; + *yy_state_ptr++ = yy_current_state; +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 269 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + *yy_state_ptr++ = yy_current_state; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 567 ); + +yy_find_action: + yy_current_state = *--yy_state_ptr; + yy_lp = yy_accept[yy_current_state]; +find_rule: /* we branch to this label when backing up */ + for ( ; ; ) /* until we find what rule we matched */ + { + if ( yy_lp && yy_lp < yy_accept[yy_current_state + 1] ) + { + yy_act = yy_acclist[yy_lp]; + { + yy_full_match = yy_cp; + break; + } + } + --yy_cp; + yy_current_state = *--yy_state_ptr; + yy_lp = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + + if ( yy_act != YY_END_OF_BUFFER ) + { + int yyl; + for ( yyl = 0; yyl < yyleng; ++yyl ) + if ( yytext[yyl] == '\n' ) + ++yylineno; + } + +do_action: /* This label is used only to access EOF actions. */ + + + switch ( yy_act ) + { /* beginning of action switch */ +case 1: +YY_RULE_SETUP +#line 139 "RCOMP.LEX" +return L_STRUCT; + YY_BREAK +case 2: +YY_RULE_SETUP +#line 140 "RCOMP.LEX" +return L_RESOURCE; + YY_BREAK +case 3: +YY_RULE_SETUP +#line 141 "RCOMP.LEX" +return L_NAME; + YY_BREAK +case 4: +YY_RULE_SETUP +#line 142 "RCOMP.LEX" +return L_CHARACTER_SET; + YY_BREAK +case 5: +YY_RULE_SETUP +#line 143 "RCOMP.LEX" +return L_OFFSET; + YY_BREAK +case 6: +YY_RULE_SETUP +#line 144 "RCOMP.LEX" +return L_SYSTEM; + YY_BREAK +case 7: +YY_RULE_SETUP +#line 145 "RCOMP.LEX" +return L_GLOBAL; + YY_BREAK +case 8: +YY_RULE_SETUP +#line 146 "RCOMP.LEX" +return L_LOCAL; + YY_BREAK +case 9: +YY_RULE_SETUP +#line 147 "RCOMP.LEX" +return L_ENUM; + YY_BREAK +case 10: +YY_RULE_SETUP +#line 148 "RCOMP.LEX" +return L_ENUM; + YY_BREAK +case 11: +YY_RULE_SETUP +#line 149 "RCOMP.LEX" +return L_UID_TWO; + YY_BREAK +case 12: +YY_RULE_SETUP +#line 150 "RCOMP.LEX" +return L_UID_THREE; + YY_BREAK +case 13: +YY_RULE_SETUP +#line 151 "RCOMP.LEX" +return L_RLS_STRING; + YY_BREAK +case 14: +YY_RULE_SETUP +#line 152 "RCOMP.LEX" +return L_RLS_STRING8; + YY_BREAK +case 15: +YY_RULE_SETUP +#line 153 "RCOMP.LEX" +return L_RLS_DOUBLE; + YY_BREAK +case 16: +YY_RULE_SETUP +#line 154 "RCOMP.LEX" +return L_RLS_BYTE; + YY_BREAK +case 17: +YY_RULE_SETUP +#line 155 "RCOMP.LEX" +return L_RLS_WORD; + YY_BREAK +case 18: +YY_RULE_SETUP +#line 156 "RCOMP.LEX" +return L_RLS_LONG; + YY_BREAK +case 19: +YY_RULE_SETUP +#line 157 "RCOMP.LEX" +return L_MULTI; + YY_BREAK +/*******************************************/ +/* Types */ +/*******************************************/ +case 20: +YY_RULE_SETUP +#line 162 "RCOMP.LEX" +return L_BUF; + YY_BREAK +case 21: +YY_RULE_SETUP +#line 163 "RCOMP.LEX" +return L_BUF8; + YY_BREAK +case 22: +YY_RULE_SETUP +#line 164 "RCOMP.LEX" +return L_BUF16; + YY_BREAK +case 23: +YY_RULE_SETUP +#line 165 "RCOMP.LEX" +return L_WORD; + YY_BREAK +case 24: +YY_RULE_SETUP +#line 166 "RCOMP.LEX" +return L_BYTE; + YY_BREAK +case 25: +YY_RULE_SETUP +#line 167 "RCOMP.LEX" +return L_LONG; + YY_BREAK +case 26: +YY_RULE_SETUP +#line 168 "RCOMP.LEX" +return L_DOUBLE; + YY_BREAK +case 27: +YY_RULE_SETUP +#line 169 "RCOMP.LEX" +return L_TEXT; + YY_BREAK +case 28: +YY_RULE_SETUP +#line 170 "RCOMP.LEX" +return L_LTEXT; + YY_BREAK +case 29: +YY_RULE_SETUP +#line 171 "RCOMP.LEX" +return L_TEXT8; + YY_BREAK +case 30: +YY_RULE_SETUP +#line 172 "RCOMP.LEX" +return L_LTEXT8; + YY_BREAK +case 31: +YY_RULE_SETUP +#line 173 "RCOMP.LEX" +return L_TEXT16; + YY_BREAK +case 32: +YY_RULE_SETUP +#line 174 "RCOMP.LEX" +return L_LTEXT16; + YY_BREAK +case 33: +YY_RULE_SETUP +#line 175 "RCOMP.LEX" +return L_LINK; + YY_BREAK +case 34: +YY_RULE_SETUP +#line 176 "RCOMP.LEX" +return L_LLINK; + YY_BREAK +case 35: +YY_RULE_SETUP +#line 177 "RCOMP.LEX" +return L_SRLINK; + YY_BREAK +/*******************************************/ +/* Others */ +/*******************************************/ +case 36: +YY_RULE_SETUP +#line 183 "RCOMP.LEX" +return L_LEN; + YY_BREAK +/*******************************************/ +/* String & character literals */ +/*******************************************/ +case 37: +YY_RULE_SETUP +#line 189 "RCOMP.LEX" +{ BEGIN(string_rules); pCh = buf; isCharLiteral=0; } + YY_BREAK +case 38: +YY_RULE_SETUP +#line 190 "RCOMP.LEX" +{ BEGIN(string_rules); pCh = buf; isCharLiteral=1; } + YY_BREAK +/* Escaped single- and double-quotes.*/ +case 39: +YY_RULE_SETUP +#line 193 "RCOMP.LEX" +{ CHECK_APPEND('"'); } + YY_BREAK +case 40: +YY_RULE_SETUP +#line 194 "RCOMP.LEX" +{ CHECK_APPEND('\''); }; + YY_BREAK +/* Convert escaped character into corresponding actual character e.g. \t to tab. */ +case 41: +YY_RULE_SETUP +#line 197 "RCOMP.LEX" +{ CHECK_APPEND( * ( strchr("\rr\bb\ff\nn\tt\vv\aa", yytext[1])-1));} + YY_BREAK +/* Escaped backslash */ +case 42: +YY_RULE_SETUP +#line 200 "RCOMP.LEX" +{ CHECK_APPEND('\\'); } + YY_BREAK +case 43: +YY_RULE_SETUP +#line 202 "RCOMP.LEX" +/* Escaped newline ignored*/ ; + YY_BREAK +/* End of line before terminating double-quotes.*/ +case 44: +YY_RULE_SETUP +#line 205 "RCOMP.LEX" +{ yyerror( isCharLiteral?"Unterminated character literal":"Unterminated string"); BEGIN 0; } + YY_BREAK +/* End of string reached.*/ +case 45: +YY_RULE_SETUP +#line 208 "RCOMP.LEX" +{ + if (!isCharLiteral) + { + *pCh = '\0'; BEGIN(0); strcpy( yylval.Value, buf); + return L_STRING_LITERAL; + } + CHECK_APPEND(*yytext); + } + YY_BREAK +case 46: +YY_RULE_SETUP +#line 217 "RCOMP.LEX" +{ + if (isCharLiteral) + { + *pCh = '\0'; BEGIN(0); strcpy( yylval.Value, buf); return L_CHAR_LITERAL; + } + CHECK_APPEND(*yytext); + } + YY_BREAK +/* Anything other than \n is stored.*/ +case 47: +YY_RULE_SETUP +#line 226 "RCOMP.LEX" +{ CHECK_APPEND(*yytext); } + YY_BREAK +/*******************************************/ +/* Labels */ +/*******************************************/ +case 48: +YY_RULE_SETUP +#line 232 "RCOMP.LEX" +{ + BEGIN(0); + strcpy( yylval.Value, yytext); + return L_LABEL; + } + YY_BREAK +/*******************************************/ +/* Numbers */ +/*******************************************/ +case 49: +YY_RULE_SETUP +#line 241 "RCOMP.LEX" +{ strcpy( yylval.Value, yytext); return L_NUM_NATURAL; } + YY_BREAK +case 50: +YY_RULE_SETUP +#line 242 "RCOMP.LEX" +{ strcpy( yylval.Value, yytext); return L_NUM_NATURAL; } + YY_BREAK +case 51: +YY_RULE_SETUP +#line 243 "RCOMP.LEX" +{ strcpy( yylval.Value, yytext); return L_NUM_FLOAT;} + YY_BREAK +case 52: +YY_RULE_SETUP +#line 244 "RCOMP.LEX" +{ strcpy( yylval.Value, yytext); return L_NUM_FLOAT;} + YY_BREAK +case 53: +YY_RULE_SETUP +#line 245 "RCOMP.LEX" +{ strcpy( yylval.Value, yytext); return L_NUM_FLOAT;} + YY_BREAK +case 54: +YY_RULE_SETUP +#line 246 "RCOMP.LEX" +{ strcpy( yylval.Value, yytext); return L_NUM_FLOAT;} + YY_BREAK +case 55: +YY_RULE_SETUP +#line 247 "RCOMP.LEX" +{ strcpy( yylval.Value, yytext); return L_NUM_FLOAT;} + YY_BREAK +case 56: +YY_RULE_SETUP +#line 248 "RCOMP.LEX" +{ strcpy( yylval.Value, yytext); return L_NUM_FLOAT;} + YY_BREAK +/*******************************************/ +/* file_line_directive */ +/*******************************************/ +case 57: +YY_RULE_SETUP +#line 253 "RCOMP.LEX" +{ BEGIN(file_line_rules); strcpy( RealLineNumber, yytext+2); } + YY_BREAK +case 58: +*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ +yy_c_buf_p = yy_cp -= 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 255 "RCOMP.LEX" +{ BEGIN(0); // # "" means start of base file. + pFileLineHandler->SetBase( InputBaseName, * pCurrentLineNumber); + } + YY_BREAK +case 59: +*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ +yy_c_buf_p = yy_cp -= 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 259 "RCOMP.LEX" +{ BEGIN(0); // # means @ line of named base file. + pFileLineHandler->PostInclude( yytext, RealLineNumber, * pCurrentLineNumber); + } + YY_BREAK +case 60: +*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ +yy_c_buf_p = yy_cp -= 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 263 "RCOMP.LEX" +{ + BEGIN(0); // # 1 means start of an included file. + pFileLineHandler->SetInclude( yytext, * pCurrentLineNumber); + } + YY_BREAK +case 61: +*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ +yy_c_buf_p = yy_cp -= 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 268 "RCOMP.LEX" +{ + BEGIN(0); // # 2 means end of an included file and now at in . + pFileLineHandler->PostInclude( yytext, RealLineNumber, * pCurrentLineNumber); + } + YY_BREAK +/*******************************************/ +/* White space */ +/*******************************************/ +case 62: +YY_RULE_SETUP +#line 278 "RCOMP.LEX" +; // skipped + YY_BREAK +case 63: +YY_RULE_SETUP +#line 279 "RCOMP.LEX" +; // skipped + YY_BREAK +case 64: +YY_RULE_SETUP +#line 280 "RCOMP.LEX" +; // skipped + YY_BREAK +case 65: +YY_RULE_SETUP +#line 281 "RCOMP.LEX" +{ BEGIN(cpp_comment); } + YY_BREAK +case 66: +YY_RULE_SETUP +#line 282 "RCOMP.LEX" +{ BEGIN(0); } + YY_BREAK +case 67: +YY_RULE_SETUP +#line 283 "RCOMP.LEX" +; // skipped + YY_BREAK +case 68: +*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ +yy_c_buf_p = yy_cp = yy_bp + 2; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 284 "RCOMP.LEX" +{ BEGIN(c_comment); } + YY_BREAK +case 69: +YY_RULE_SETUP +#line 285 "RCOMP.LEX" +{ BEGIN(c_comment); } + YY_BREAK +case 70: +YY_RULE_SETUP +#line 286 "RCOMP.LEX" +{ BEGIN(0); } + YY_BREAK +case 71: +YY_RULE_SETUP +#line 287 "RCOMP.LEX" +; // skipped + YY_BREAK +case 72: +YY_RULE_SETUP +#line 288 "RCOMP.LEX" +; // skipped + YY_BREAK +/*******************************************/ +/* Comment tags */ +/*******************************************/ +case 73: +YY_RULE_SETUP +#line 294 "RCOMP.LEX" +{ + BEGIN(comment_tag); + pGL->SetStart(*(pFileLineHandler->GetCurrentFile()), pFileLineHandler->GetErrorLine(* pCurrentLineNumber)); + return L_TAG_START; + } // any comment beginning with a slash followed by a star followed by an ampersand + YY_BREAK +case 74: +YY_RULE_SETUP +#line 299 "RCOMP.LEX" +{ + BEGIN(0); + return L_TAG_END; + } + YY_BREAK +case 75: +YY_RULE_SETUP +#line 303 "RCOMP.LEX" +{ strcpy( yylval.Value, yytext); return L_TAG_COMMAND; } + YY_BREAK +case 76: +YY_RULE_SETUP +#line 304 "RCOMP.LEX" +{ strcpy( yylval.Value, yytext); return L_TAG_WORD; } + YY_BREAK +case 77: +YY_RULE_SETUP +#line 305 "RCOMP.LEX" +{ strcpy( yylval.Value, "\n"); return L_TAG_NEW_LINE; } + YY_BREAK +case 78: +YY_RULE_SETUP +#line 306 "RCOMP.LEX" +; + YY_BREAK +/*******************************************/ +/* Special single characters */ +/*******************************************/ +case 79: +YY_RULE_SETUP +#line 311 "RCOMP.LEX" +return * yytext; + YY_BREAK +/*******************************************/ +/* Everything else cannot be recognised */ +/*******************************************/ +case 80: +YY_RULE_SETUP +#line 317 "RCOMP.LEX" +{ yyerror("*** Unknown character '%c' (value 0x%x) ", *yytext, *yytext);} + YY_BREAK +case 81: +YY_RULE_SETUP +#line 318 "RCOMP.LEX" +ECHO; + YY_BREAK +#line 1503 "lex.yy.c" + case YY_STATE_EOF(INITIAL): + case YY_STATE_EOF(string_rules): + case YY_STATE_EOF(file_line_rules): + case YY_STATE_EOF(cpp_comment): + case YY_STATE_EOF(c_comment): + case YY_STATE_EOF(comment_tag): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = yy_hold_char; + YY_RESTORE_YY_MORE_OFFSET + + if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between yy_current_buffer and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + yy_n_chars = yy_current_buffer->yy_n_chars; + yy_current_buffer->yy_input_file = yyin; + yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = yytext_ptr + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++yy_c_buf_p; + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = yy_c_buf_p; + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer() ) + { + case EOB_ACT_END_OF_FILE: + { + yy_did_buffer_switch_on_eof = 0; + + if ( yywrap() ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = + yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + yy_cp = yy_c_buf_p; + yy_bp = yytext_ptr + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + yy_c_buf_p = + &yy_current_buffer->yy_ch_buf[yy_n_chars]; + + yy_current_state = yy_get_previous_state(); + + yy_cp = yy_c_buf_p; + yy_bp = yytext_ptr + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ + } /* end of yylex */ + + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ + +static int yy_get_next_buffer() + { + register char *dest = yy_current_buffer->yy_ch_buf; + register char *source = yytext_ptr; + register int number_to_move, i; + int ret_val; + + if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( yy_current_buffer->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + yy_current_buffer->yy_n_chars = yy_n_chars = 0; + + else + { + int num_to_read = + yy_current_buffer->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ +#ifdef YY_USES_REJECT + YY_FATAL_ERROR( +"input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); +#else + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = yy_current_buffer; + + int yy_c_buf_p_offset = + (int) (yy_c_buf_p - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yy_flex_realloc( (void *) b->yy_ch_buf, + b->yy_buf_size + 2 ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = yy_current_buffer->yy_buf_size - + number_to_move - 1; +#endif + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), + yy_n_chars, num_to_read ); + + yy_current_buffer->yy_n_chars = yy_n_chars; + } + + if ( yy_n_chars == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart( yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + yy_current_buffer->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + yy_n_chars += number_to_move; + yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; + yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; + + yytext_ptr = &yy_current_buffer->yy_ch_buf[0]; + + return ret_val; + } + + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + +static yy_state_type yy_get_previous_state() + { + register yy_state_type yy_current_state; + register char *yy_cp; + + yy_current_state = yy_start; + yy_state_ptr = yy_state_buf; + *yy_state_ptr++ = yy_current_state; + + for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 269 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + *yy_state_ptr++ = yy_current_state; + } + + return yy_current_state; + } + + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + +#ifdef YY_USE_PROTOS +static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state ) +#else +static yy_state_type yy_try_NUL_trans( yy_current_state ) +yy_state_type yy_current_state; +#endif + { + register int yy_is_jam; + + register YY_CHAR yy_c = 1; + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 269 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 268); + if ( ! yy_is_jam ) + *yy_state_ptr++ = yy_current_state; + + return yy_is_jam ? 0 : yy_current_state; + } + + +#ifndef YY_NO_UNPUT +#ifdef YY_USE_PROTOS +static void yyunput( int c, register char *yy_bp ) +#else +static void yyunput( c, yy_bp ) +int c; +register char *yy_bp; +#endif + { + register char *yy_cp = yy_c_buf_p; + + /* undo effects of setting up yytext */ + *yy_cp = yy_hold_char; + + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register int number_to_move = yy_n_chars + 2; + register char *dest = &yy_current_buffer->yy_ch_buf[ + yy_current_buffer->yy_buf_size + 2]; + register char *source = + &yy_current_buffer->yy_ch_buf[number_to_move]; + + while ( source > yy_current_buffer->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + yy_current_buffer->yy_n_chars = + yy_n_chars = yy_current_buffer->yy_buf_size; + + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + + if ( c == '\n' ) + --yylineno; + + yytext_ptr = yy_bp; + yy_hold_char = *yy_cp; + yy_c_buf_p = yy_cp; + } +#endif /* ifndef YY_NO_UNPUT */ + + +#ifdef __cplusplus +static int yyinput() +#else +static int input() +#endif + { + int c; + + *yy_c_buf_p = yy_hold_char; + + if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + /* This was really a NUL. */ + *yy_c_buf_p = '\0'; + + else + { /* need more input */ + int offset = yy_c_buf_p - yytext_ptr; + ++yy_c_buf_p; + + switch ( yy_get_next_buffer() ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart( yyin ); + + /* fall through */ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap() ) + return EOF; + + if ( ! yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = yytext_ptr + offset; + break; + } + } + } + + c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */ + *yy_c_buf_p = '\0'; /* preserve yytext */ + yy_hold_char = *++yy_c_buf_p; + + if ( c == '\n' ) + ++yylineno; + + return c; + } + + +#ifdef YY_USE_PROTOS +void yyrestart( FILE *input_file ) +#else +void yyrestart( input_file ) +FILE *input_file; +#endif + { + if ( ! yy_current_buffer ) + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); + + yy_init_buffer( yy_current_buffer, input_file ); + yy_load_buffer_state(); + } + + +#ifdef YY_USE_PROTOS +void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) +#else +void yy_switch_to_buffer( new_buffer ) +YY_BUFFER_STATE new_buffer; +#endif + { + if ( yy_current_buffer == new_buffer ) + return; + + if ( yy_current_buffer ) + { + /* Flush out information for old buffer. */ + *yy_c_buf_p = yy_hold_char; + yy_current_buffer->yy_buf_pos = yy_c_buf_p; + yy_current_buffer->yy_n_chars = yy_n_chars; + } + + yy_current_buffer = new_buffer; + yy_load_buffer_state(); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + yy_did_buffer_switch_on_eof = 1; + } + + +#ifdef YY_USE_PROTOS +void yy_load_buffer_state( void ) +#else +void yy_load_buffer_state() +#endif + { + yy_n_chars = yy_current_buffer->yy_n_chars; + yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos; + yyin = yy_current_buffer->yy_input_file; + yy_hold_char = *yy_c_buf_p; + } + + +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_create_buffer( FILE *file, int size ) +#else +YY_BUFFER_STATE yy_create_buffer( file, size ) +FILE *file; +int size; +#endif + { + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer( b, file ); + + return b; + } + + +#ifdef YY_USE_PROTOS +void yy_delete_buffer( YY_BUFFER_STATE b ) +#else +void yy_delete_buffer( b ) +YY_BUFFER_STATE b; +#endif + { + if ( ! b ) + return; + + if ( b == yy_current_buffer ) + yy_current_buffer = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yy_flex_free( (void *) b->yy_ch_buf ); + + yy_flex_free( (void *) b ); + } + + +#ifndef YY_ALWAYS_INTERACTIVE +#ifndef YY_NEVER_INTERACTIVE +extern int isatty YY_PROTO(( int )); +#endif +#endif + +#ifdef YY_USE_PROTOS +void yy_init_buffer( YY_BUFFER_STATE b, FILE *file ) +#else +void yy_init_buffer( b, file ) +YY_BUFFER_STATE b; +FILE *file; +#endif + + + { + yy_flush_buffer( b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + +#if YY_ALWAYS_INTERACTIVE + b->yy_is_interactive = 1; +#else +#if YY_NEVER_INTERACTIVE + b->yy_is_interactive = 0; +#else + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; +#endif +#endif + } + + +#ifdef YY_USE_PROTOS +void yy_flush_buffer( YY_BUFFER_STATE b ) +#else +void yy_flush_buffer( b ) +YY_BUFFER_STATE b; +#endif + + { + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == yy_current_buffer ) + yy_load_buffer_state(); + } + + +#ifndef YY_NO_SCAN_BUFFER +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size ) +#else +YY_BUFFER_STATE yy_scan_buffer( base, size ) +char *base; +yy_size_t size; +#endif + { + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer( b ); + + return b; + } +#endif + + +#ifndef YY_NO_SCAN_STRING +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str ) +#else +YY_BUFFER_STATE yy_scan_string( yy_str ) +yyconst char *yy_str; +#endif + { + int len; + for ( len = 0; yy_str[len]; ++len ) + ; + + return yy_scan_bytes( yy_str, len ); + } +#endif + + +#ifndef YY_NO_SCAN_BYTES +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len ) +#else +YY_BUFFER_STATE yy_scan_bytes( bytes, len ) +yyconst char *bytes; +int len; +#endif + { + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = len + 2; + buf = (char *) yy_flex_alloc( n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < len; ++i ) + buf[i] = bytes[i]; + + buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer( buf, n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; + } +#endif + + +#ifndef YY_NO_PUSH_STATE +#ifdef YY_USE_PROTOS +static void yy_push_state( int new_state ) +#else +static void yy_push_state( new_state ) +int new_state; +#endif + { + if ( yy_start_stack_ptr >= yy_start_stack_depth ) + { + yy_size_t new_size; + + yy_start_stack_depth += YY_START_STACK_INCR; + new_size = yy_start_stack_depth * sizeof( int ); + + if ( ! yy_start_stack ) + yy_start_stack = (int *) yy_flex_alloc( new_size ); + + else + yy_start_stack = (int *) yy_flex_realloc( + (void *) yy_start_stack, new_size ); + + if ( ! yy_start_stack ) + YY_FATAL_ERROR( + "out of memory expanding start-condition stack" ); + } + + yy_start_stack[yy_start_stack_ptr++] = YY_START; + + BEGIN(new_state); + } +#endif + + +#ifndef YY_NO_POP_STATE +static void yy_pop_state() + { + if ( --yy_start_stack_ptr < 0 ) + YY_FATAL_ERROR( "start-condition stack underflow" ); + + BEGIN(yy_start_stack[yy_start_stack_ptr]); + } +#endif + + +#ifndef YY_NO_TOP_STATE +static int yy_top_state() + { + return yy_start_stack[yy_start_stack_ptr - 1]; + } +#endif + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +#ifdef YY_USE_PROTOS +static void yy_fatal_error( yyconst char msg[] ) +#else +static void yy_fatal_error( msg ) +char msg[]; +#endif + { + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); + } + + + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + yytext[yyleng] = yy_hold_char; \ + yy_c_buf_p = yytext + n; \ + yy_hold_char = *yy_c_buf_p; \ + *yy_c_buf_p = '\0'; \ + yyleng = n; \ + } \ + while ( 0 ) + + +/* Internal utility routines. */ + +#ifndef yytext_ptr +#ifdef YY_USE_PROTOS +static void yy_flex_strncpy( char *s1, yyconst char *s2, int n ) +#else +static void yy_flex_strncpy( s1, s2, n ) +char *s1; +yyconst char *s2; +int n; +#endif + { + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; + } +#endif + +#ifdef YY_NEED_STRLEN +#ifdef YY_USE_PROTOS +static int yy_flex_strlen( yyconst char *s ) +#else +static int yy_flex_strlen( s ) +yyconst char *s; +#endif + { + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; + } +#endif + + +#ifdef YY_USE_PROTOS +static void *yy_flex_alloc( yy_size_t size ) +#else +static void *yy_flex_alloc( size ) +yy_size_t size; +#endif + { + return (void *) malloc( size ); + } + +#ifdef YY_USE_PROTOS +static void *yy_flex_realloc( void *ptr, yy_size_t size ) +#else +static void *yy_flex_realloc( ptr, size ) +void *ptr; +yy_size_t size; +#endif + { + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); + } + +#ifdef YY_USE_PROTOS +static void yy_flex_free( void *ptr ) +#else +static void yy_flex_free( ptr ) +void *ptr; +#endif + { + free( ptr ); + } + +#if YY_MAIN +int main() + { + yylex(); + return 0; + } +#endif +#line 318 "RCOMP.LEX" diff -r 122d2b873fd1 -r 30b30f9da0b7 e32tools/e32lib/group/bld.inf --- a/e32tools/e32lib/group/bld.inf Fri Jun 25 20:58:33 2010 +0800 +++ b/e32tools/e32lib/group/bld.inf Tue Jun 29 14:52:54 2010 +0800 @@ -14,8 +14,12 @@ // PRJ_PLATFORMS -TOOLS2 +TOOLS TOOLS2 + +PRJ_EXPORTS +../seclib/seclib.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(seclib.h) PRJ_MMPFILES -seclib +seclib.mmp + diff -r 122d2b873fd1 -r 30b30f9da0b7 e32tools/e32lib/group/e32lib.mrp --- a/e32tools/e32lib/group/e32lib.mrp Fri Jun 25 20:58:33 2010 +0800 +++ b/e32tools/e32lib/group/e32lib.mrp Tue Jun 29 14:52:54 2010 +0800 @@ -1,7 +1,8 @@ component dev_build_e32tools_e32lib -source /src/tools/dev/build/e32tools/e32lib -binary /src/tools/dev/build/e32tools/e32lib/group all +source /src/tools/build/e32tools/e32lib +binary /src/tools/build/e32tools/e32lib/group all +exports /src/tools/build/e32tools/e32lib/group notes_source release.txt diff -r 122d2b873fd1 -r 30b30f9da0b7 e32tools/e32lib/group/release.txt --- a/e32tools/e32lib/group/release.txt Fri Jun 25 20:58:33 2010 +0800 +++ b/e32tools/e32lib/group/release.txt Tue Jun 29 14:52:54 2010 +0800 @@ -3,3 +3,8 @@ NOTESRC_RELEASE_REASON Seclib Release + +version ?? +=============== +Released by Zheng Shen, 22/02/2010 + 1) DPDEF144562 Build Tools cannot be built in Linux diff -r 122d2b873fd1 -r 30b30f9da0b7 e32tools/e32lib/group/seclib.mmp --- a/e32tools/e32lib/group/seclib.mmp Fri Jun 25 20:58:33 2010 +0800 +++ b/e32tools/e32lib/group/seclib.mmp Tue Jun 29 14:52:54 2010 +0800 @@ -23,10 +23,10 @@ sourcepath ../seclib source seclib.cpp -sourcepath ../e32image +sourcepath ../../../imgtools/imglib/e32image source e32image.cpp -sourcepath ../e32image/deflate +sourcepath ../../../imgtools/imglib/e32image/deflate source decode.cpp encode.cpp deflate.cpp inflate.cpp panic.cpp compress.cpp sourcepath ../../../imgtools/imglib/compress @@ -42,9 +42,11 @@ source h_file.cpp h_mem.cpp h_utl.cpp userinclude ../../../imgtools/imglib/compress +userinclude ../../../imgtools/imglib/inc userinclude ../setcap -userinclude ../../e32lib/e32image/inc -systeminclude /epoc32/include +userinclude ../seclib + +OS_LAYER_SYSTEMINCLUDE_SYMBIAN OPTION GCC -w diff -r 122d2b873fd1 -r 30b30f9da0b7 e32tools/e32lib/seclib/seclib.cpp --- a/e32tools/e32lib/seclib/seclib.cpp Fri Jun 25 20:58:33 2010 +0800 +++ b/e32tools/e32lib/seclib/seclib.cpp Tue Jun 29 14:52:54 2010 +0800 @@ -18,7 +18,7 @@ #include #include -#include +#include "seclib.h" #include "e32image.h" #include "h_utl.h" diff -r 122d2b873fd1 -r 30b30f9da0b7 e32tools/e32lib/setcap/setcap.h --- a/e32tools/e32lib/setcap/setcap.h Fri Jun 25 20:58:33 2010 +0800 +++ b/e32tools/e32lib/setcap/setcap.h Tue Jun 29 14:52:54 2010 +0800 @@ -17,8 +17,11 @@ #ifndef __SETCAP_H__ // We need to build for both TOOLS2 and TOOLS for the moment -#if !defined(__TOOLS2_LINUX__) +#ifdef WIN32 #include +#ifdef _STLP_INTERNAL_WINDOWS_H +#define __INTERLOCKED_DECLARED +#endif #include #endif #include diff -r 122d2b873fd1 -r 30b30f9da0b7 e32tools/elf2e32/group/elf2e32.mmp --- a/e32tools/elf2e32/group/elf2e32.mmp Fri Jun 25 20:58:33 2010 +0800 +++ b/e32tools/elf2e32/group/elf2e32.mmp Tue Jun 29 14:52:54 2010 +0800 @@ -19,17 +19,23 @@ sourcepath ../source source deffile.cpp deflatecompress.cpp dll_fb_target.cpp dll_rebuild_target.cpp e32exporttable.cpp -source filedump.cpp e32imagefile.cpp elf2e32.cpp elffilesupplied.cpp errorhandler.cpp exetarget.cpp exexp_fb_target.cpp -source exexp_rebuild_target.cpp export_type_fb_target.cpp export_type_rebuild_target.cpp export_type_target.cpp h_utl.cpp +source filedump.cpp elf2e32.cpp elffilesupplied.cpp errorhandler.cpp exetarget.cpp exexp_fb_target.cpp +source exexp_rebuild_target.cpp export_type_fb_target.cpp export_type_rebuild_target.cpp export_type_target.cpp source huffman.cpp imgdump.cpp inflate.cpp librarytarget.cpp main.cpp messagehandler.cpp messageimplementation.cpp source parameterlistinterface.cpp parametermanager.cpp pl_common.cpp pl_dllsymbol.cpp pl_dso_handler.cpp pl_elfconsumer.cpp source pl_elfexecutable.cpp pl_elfexports.cpp pl_elfimportrelocation.cpp pl_elfimports.cpp pl_elflocalrelocation.cpp pl_elfproducer.cpp source pl_elfrelocation.cpp pl_elfrelocations.cpp pl_symbol.cpp polydll_fb_target.cpp polydll_rebuild_target.cpp usecasebase.cpp -source byte_pair.cpp pagedcompress.cpp checksum.cpp stdexe_target.cpp +source checksum.cpp stdexe_target.cpp e32imagefile.cpp -systeminclude /epoc32/include /epoc32/include/tools -userinclude ../source ../include +sourcepath ../../../imgtools/imglib/host +source h_utl.cpp +sourcepath ../../../imgtools/imglib/compress +source byte_pair.cpp pagedcompress.cpp -option GCC -w +userinclude ../source ../include ../../../bintools/elftools/inc +userinclude ../../../imgtools/imglib/compress ../../../imgtools/imglib/inc +OS_LAYER_SYSTEMINCLUDE_SYMBIAN + +option GCC -O2 -w VENDORID 0x70000001 diff -r 122d2b873fd1 -r 30b30f9da0b7 e32tools/elf2e32/group/elf2e32.mrp --- a/e32tools/elf2e32/group/elf2e32.mrp Fri Jun 25 20:58:33 2010 +0800 +++ b/e32tools/elf2e32/group/elf2e32.mrp Tue Jun 29 14:52:54 2010 +0800 @@ -1,7 +1,7 @@ component dev_build_e32tools_elf2e32 -source /src/tools/dev/build/e32tools/elf2e32 -binary /src/tools/dev/build/e32tools/elf2e32/group all +source /src/tools/build/e32tools/elf2e32 +binary /src/tools/build/e32tools/elf2e32/group all notes_source release.txt diff -r 122d2b873fd1 -r 30b30f9da0b7 e32tools/elf2e32/group/release.txt --- a/e32tools/elf2e32/group/release.txt Fri Jun 25 20:58:33 2010 +0800 +++ b/e32tools/elf2e32/group/release.txt Tue Jun 29 14:52:54 2010 +0800 @@ -3,3 +3,28 @@ NOTESRC_RELEASE_REASON Postlinker(elf2e32) Release + +version 2.2 build(004) +=============== +Released by Lorence Wang, 11/06/2010 + 1) elf2e32 use new bytepair in imglib + +version 2.2 build(003) +=============== +Released by Lorence Wang, 26/04/2010 + 1) DPDEF145378 elf2e32 has compilation errors when buid with Gcc4.4 and STLport 5.2.1 + +version 2.2 build(002) +=============== +Released by Zheng Shen, 10/03/2010 + 1) DPDEF144887 [System build] : NE1 smoketest not booting up for TB92SF_1069 vtb92sf build + +version 2.2 build(001) +=============== +Released by Zheng Shen, 09/03/2010 + 1) DPDEF144861 elf2e32 in linux will do in wrong behavior when there is space in cmd line. + +version 2.2 build(000) +=============== +Released by Zheng Shen, 22/02/2010 + 1) DPDEF144562 Build Tools cannot be built in Linux diff -r 122d2b873fd1 -r 30b30f9da0b7 e32tools/elf2e32/include/h_ver.h --- a/e32tools/elf2e32/include/h_ver.h Fri Jun 25 20:58:33 2010 +0800 +++ b/e32tools/elf2e32/include/h_ver.h Tue Jun 29 14:52:54 2010 +0800 @@ -17,8 +17,8 @@ #define __H_VER_H__ const TInt MajorVersion=2; -const TInt MinorVersion=1; -const TInt Build=14; +const TInt MinorVersion=2; +const TInt Build=4; #endif diff -r 122d2b873fd1 -r 30b30f9da0b7 e32tools/elf2e32/source/deflatecompress.cpp --- a/e32tools/elf2e32/source/deflatecompress.cpp Fri Jun 25 20:58:33 2010 +0800 +++ b/e32tools/elf2e32/source/deflatecompress.cpp Tue Jun 29 14:52:54 2010 +0800 @@ -29,6 +29,15 @@ const TUint KDeflateHashMultiplier=0xAC4B9B19u; const TInt KDeflateHashShift=24; +#define COMPILE_TIME_ASSERT(e) \ + switch (0) \ + { \ + case 0: \ + case e: \ + ; \ + } + + /** Class HDeflateHash @internalComponent @@ -125,9 +134,31 @@ */ inline HDeflateHash* HDeflateHash::NewLC(TInt aLinks) { - //return new(HMem::Alloc(0,_FOFF(HDeflateHash,iOffset[Min(aLinks,KDeflateMaxDistance)]))) HDeflateHash; - return new(new char[_FOFF(HDeflateHash,iOffset[Min(aLinks,KDeflateMaxDistance)])]) HDeflateHash; -} +#if __GNUC__ >= 4 + // Try to detect if the class' layout has changed. + COMPILE_TIME_ASSERT( sizeof(HDeflateHash) == 1028 ); + COMPILE_TIME_ASSERT( sizeof(TOffset) == 2 ); + COMPILE_TIME_ASSERT( offsetof(HDeflateHash, iHash) < offsetof(HDeflateHash, iOffset) ); + + // Compute the size of the class, including rounding it up to a multiple of 4 + // bytes. + + unsigned n = sizeof(TInt) * 256 + sizeof(TOffset) * Min(aLinks, KDeflateMaxDistance); + + while (n & 0x1f) + { + n++; + } + // Allocate the raw memory ... + void* p = ::operator new(n); + // ... And create the object in that memory. + return new(p) HDeflateHash; +#else + return new(new char[_FOFF(HDeflateHash,iOffset[Min(aLinks,KDeflateMaxDistance)])]) HDeflateHash; +#endif + } + + /** Hash function for HDeflateHash diff -r 122d2b873fd1 -r 30b30f9da0b7 e32tools/elf2e32/source/e32imagefile.cpp --- a/e32tools/elf2e32/source/e32imagefile.cpp Fri Jun 25 20:58:33 2010 +0800 +++ b/e32tools/elf2e32/source/e32imagefile.cpp Tue Jun 29 14:52:54 2010 +0800 @@ -33,6 +33,7 @@ #include "h_ver.h" #include "checksum.h" #include "errorhandler.h" +#include "byte_pair.h" #include #include @@ -57,25 +58,6 @@ return (T)res; } -// Need a default constructor for TVersion, but don't want all the other stuff in h_utl.cpp -/** -Default constructor for TVersion class. -@internalComponent -@released -*/ -TVersion::TVersion(){} - -/** -Constructor for TVersion class. -@internalComponent -@released -*/ -TVersion::TVersion(TInt aMajor, TInt aMinor, TInt aBuild): - iMajor((TInt8)aMajor), iMinor((TInt8)aMinor), iBuild((TInt16)aBuild) -{ -} - - /** Constructor for E32ImageChunkDesc class. @internalComponent @@ -1177,6 +1159,10 @@ if (iUseCase->GetFPU() == 1) iHdr->iFlags |= KImageHWFloat_VFPv2; + else if (iUseCase->GetFPU() == 2) + iHdr->iFlags |= KImageHWFloat_VFPv3; + else if (iUseCase->GetFPU() == 3) + iHdr->iFlags |= KImageHWFloat_VFPv3D16; } /** @@ -1402,7 +1388,7 @@ @internalComponent @released */ -void CompressPages(TUint8 * bytes, TInt size, ofstream& os); +void CompressPages(TUint8 * bytes, TInt size, ostream& os, CBytePair *aBPE); /** @@ -1432,15 +1418,16 @@ os->write(iE32Image, aHeaderSize); // Compress and write out code part + CBytePair bpe; int srcStart = GetExtendedE32ImageHeaderSize(); - CompressPages( (TUint8*)iE32Image + srcStart, iHdr->iCodeSize, *os); + CompressPages( (TUint8*)iE32Image + srcStart, iHdr->iCodeSize, *os, &bpe); // Compress and write out data part srcStart += iHdr->iCodeSize; int srcLen = GetE32ImageSize() - srcStart; - CompressPages((TUint8*)iE32Image + srcStart, srcLen, *os); + CompressPages((TUint8*)iE32Image + srcStart, srcLen, *os, &bpe); } else if (compression == 0) @@ -1698,7 +1685,7 @@ } -int DecompressPages(TUint8 * bytes, ifstream& is); +int DecompressPages(TUint8 * bytes, istream& is, CBytePair *aBPE); /** @@ -1769,13 +1756,13 @@ oh = aImage.iOrigHdr; // Read and decompress code part of the image - - unsigned int uncompressedCodeSize = DecompressPages((TUint8 *) (aImage.iData + orighdrsz), is); + CBytePair bpe; + unsigned int uncompressedCodeSize = DecompressPages((TUint8 *) (aImage.iData + orighdrsz), is, &bpe); // Read and decompress data part of the image - unsigned int uncompressedDataSize = DecompressPages((TUint8 *) (aImage.iData + orighdrsz + uncompressedCodeSize), is); + unsigned int uncompressedDataSize = DecompressPages((TUint8 *) (aImage.iData + orighdrsz + uncompressedCodeSize), is, &bpe); if (uncompressedCodeSize + uncompressedDataSize != uncompsize) MessageHandler::GetInstance()->ReportMessage(WARNING, BYTEPAIRINCONSISTENTSIZEERROR); diff -r 122d2b873fd1 -r 30b30f9da0b7 e32tools/elf2e32/source/e32imagefile.h --- a/e32tools/elf2e32/source/e32imagefile.h Fri Jun 25 20:58:33 2010 +0800 +++ b/e32tools/elf2e32/source/e32imagefile.h Tue Jun 29 14:52:54 2010 +0800 @@ -173,10 +173,10 @@ void UpdateHeaderCrc(); - bool WriteImage(const char * aName); + bool WriteImage(const char* aName); public: - const char * iFileName; + const char* iFileName; char * iE32Image; uint8 * iExportBitMap; @@ -226,7 +226,7 @@ TUint32 Capability(); TUint32 Format(); - void Dump(TText *aFileName,TInt aDumpFlags); + void Dump(const char* aFileName,TInt aDumpFlags); void DumpHeader(TInt aDumpFlags); void DumpData(TInt aDumpFlags); void DumpSymbolInfo(E32EpocExpSymInfoHdr *aSymInfoHdr); diff -r 122d2b873fd1 -r 30b30f9da0b7 e32tools/elf2e32/source/elffilesupplied.cpp --- a/e32tools/elf2e32/source/elffilesupplied.cpp Fri Jun 25 20:58:33 2010 +0800 +++ b/e32tools/elf2e32/source/elffilesupplied.cpp Tue Jun 29 14:52:54 2010 +0800 @@ -234,14 +234,9 @@ while( aResultPos != aAbsentListEnd ) { - // intersection set {Absent,ELF_Symbols} is non-empty - // Ignore the non callable exports - if ((strncmp("_ZTI", (*aResultPos)->SymbolName(), len)) && - (strncmp("_ZTV", (*aResultPos)->SymbolName(), len))) - { - iSymList.insert(iSymList.end(), *aResultPos); - cout << "Elf2e32: Warning: Symbol " << (*aResultPos)->SymbolName() << " absent in the DEF file, but present in the ELF file" << endl; - } + // intersection set {Absent,ELF_Symbols} is non-empty + iSymList.insert(iSymList.end(), *aResultPos); + cout << "Elf2e32: Warning: Symbol " << (*aResultPos)->SymbolName() << " absent in the DEF file, but present in the ELF file" << endl; aResultPos++; } } diff -r 122d2b873fd1 -r 30b30f9da0b7 e32tools/elf2e32/source/filedump.cpp --- a/e32tools/elf2e32/source/filedump.cpp Fri Jun 25 20:58:33 2010 +0800 +++ b/e32tools/elf2e32/source/filedump.cpp Tue Jun 29 14:52:54 2010 +0800 @@ -170,16 +170,16 @@ return 1; else if (result == KErrCorrupt || result == KErrNotSupported) { - throw InvalidE32ImageError(INVALIDE32IMAGEERROR, (char *)afileName); + throw InvalidE32ImageError(INVALIDE32IMAGEERROR, (char*)afileName); } else if (result != 0) { - throw FileError(FILEREADERROR, (char *)afileName); + throw FileError(FILEREADERROR, (char*)afileName); } int dumpOptions=iParameterListInterface->DumpOptions(); - aE32Imagefile->Dump((TText*)afileName, dumpOptions); + aE32Imagefile->Dump(afileName, dumpOptions); delete aE32Imagefile; return KErrNone; } diff -r 122d2b873fd1 -r 30b30f9da0b7 e32tools/elf2e32/source/imgdump.cpp --- a/e32tools/elf2e32/source/imgdump.cpp Fri Jun 25 20:58:33 2010 +0800 +++ b/e32tools/elf2e32/source/imgdump.cpp Tue Jun 29 14:52:54 2010 +0800 @@ -46,7 +46,7 @@ */ void PrintString(const char *aFmt,...) { - TText imageText[KMaxStringLength]; + char imageText[KMaxStringLength]; va_list list; va_start(list,aFmt); VSNPRINTF((char *)imageText,KMaxStringLength,aFmt,list); @@ -122,7 +122,7 @@ @param aDumpFlags sub options passed to the 'dump' option */ -void E32ImageFile::Dump(TText *aFileName,TInt aDumpFlags) +void E32ImageFile::Dump(const char* aFileName,TInt aDumpFlags) { PrintString("E32ImageFile '%s'\n", aFileName); DumpHeader(aDumpFlags); diff -r 122d2b873fd1 -r 30b30f9da0b7 e32tools/elf2e32/source/parametermanager.cpp --- a/e32tools/elf2e32/source/parametermanager.cpp Fri Jun 25 20:58:33 2010 +0800 +++ b/e32tools/elf2e32/source/parametermanager.cpp Tue Jun 29 14:52:54 2010 +0800 @@ -18,13 +18,14 @@ // // This must go before ParameterManager.h -#define __INCLUDE_CAPABILITY_NAMES__ +#define __REFERENCE_CAPABILITY_NAMES__ #include #include "pl_common.h" #include "parametermanager.h" #include "errorhandler.h" #include +#include #include "h_utl.h" #include "h_ver.h" @@ -375,7 +376,7 @@ { "fpu", (void *)ParameterManager::ParseFPU, - "FPU type [softvfp|vfpv2]", + "FPU type [softvfp|vfpv2|vfpv3|vfpv3D16]", }, { "codepaging", @@ -2241,21 +2242,33 @@ int q = 0; unsigned int ordinalnum = 0; char *symbol = 0; - - int nq = aSysDefValues.find_first_of(",", q,sizeof(*p)); + int nq = aSysDefValues.find_first_not_of(" "); + if (nq && (nq != string::npos)) + { + sysdeflength -= nq; + aSysDefValues.erase(0, nq); + } + + nq = aSysDefValues.find_first_of(",", q,sizeof(*p)); if (nq && (nq != string::npos)) { int len = nq; + while (*(p+len-1) == ' ' || *(p+len-1) == ' ') + len --; symbol = new char[len+1]; memcpy(symbol, p, len); symbol[len] = 0; q = nq+1; + while (*(p+q) == ' ' || *(p+q) == ' ') + q ++; char val = *(p+q); if (!val || !isdigit(val)) throw ParameterParserError(SYSDEFERROR, "--sysdef"); ordinalnum = *(p+q) - '0'; aPM->SetSysDefs(ordinalnum, symbol, sysdefcount); + while (*(p+q+1) == ' ' || *(p+q+1) == ' ') + q ++; unsigned int separator = aSysDefValues.find(";", 0); @@ -2565,8 +2578,12 @@ if (strnicmp(aValue, "softvfp", 7)==0) aPM->SetFPU(0); - else if (strnicmp(aValue, "vfpv2", 5)==0) + else if ((strnicmp(aValue, "vfpv2", 5)==0) || (strnicmp(aValue, "softvfp+vfpv2",13 )==0)) aPM->SetFPU(1); + else if (strnicmp(aValue,"vfpv3", 5)==0) + aPM->SetFPU(2); + else if (strnicmp(aValue,"vfpv3D16", 8)==0) + aPM->SetFPU(3); else throw InvalidArgumentError(INVALIDARGUMENTERROR, aValue, aOption); } diff -r 122d2b873fd1 -r 30b30f9da0b7 imgtools/buildrom/group/BLD.INF --- a/imgtools/buildrom/group/BLD.INF Fri Jun 25 20:58:33 2010 +0800 +++ b/imgtools/buildrom/group/BLD.INF Tue Jun 29 14:52:54 2010 +0800 @@ -1,60 +1,79 @@ -/* -* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of the License "Eclipse Public License v1.0" -* which accompanies this distribution, and is available -* at the URL "http://www.eclipse.org/legal/epl-v10.html". -* -* Initial Contributors: -* Nokia Corporation - initial contribution. -* -* Contributors: -* -* Description: -* -*/ - - -/** -@file - -@SYMPurpose Tool for building ROMs -*/ - -PRJ_EXPORTS - -../tools/buildrom.pl /epoc32/tools/buildrom.pl -../tools/buildrom.pm /epoc32/tools/buildrom.pm -../tools/buildrom.cmd /epoc32/tools/buildrom.cmd -../tools/cdfparser.pm /epoc32/tools/cdfparser.pm -../tools/datadriveimage.pm /epoc32/tools/datadriveimage.pm -../tools/Dep_Lister.pm /epoc32/tools/dep_lister.pm -../tools/externaltools.pm /epoc32/tools/externaltools.pm -../tools/featureparser.pm /epoc32/tools/featureparser.pm -../tools/GenericParser.pm /epoc32/tools/genericparser.pm -../tools/ImageContentHandler.pm /epoc32/tools/imagecontenthandler.pm -../tools/spitool.pm /epoc32/tools/spitool.pm -../tools/spitool.pl /epoc32/tools/spitool.pl -../tools/CONVERT.PL /epoc32/rom/tools/ -../tools/CODESIZE.PL /epoc32/rom/tools/ -../tools/configpaging.pm /epoc32/tools/configpaging.pm -../tools/efficient_rom_paging.pm /epoc32/tools/efficient_rom_paging.pm - -// -// Files for Enhanced Feature Manager Support -// -../tools/featuresutil.pm /epoc32/tools/featuresutil.pm -../tools/featureregistry.pm /epoc32/tools/featureregistry.pm -../tools/featuremanager.pm /epoc32/tools/featuremanager.pm -../tools/featurefile.pm /epoc32/tools/featurefile.pm -../tools/featurecfg.pm /epoc32/tools/featurecfg.pm -../tools/featuresdat.pm /epoc32/tools/featuresdat.pm -../tools/features.cmd /epoc32/tools/features.cmd -../tools/features.pl /epoc32/tools/features.pl -../tools/features.pm /epoc32/tools/features.pm - -// backwards compatibility for buildrom commandlines... - -../tools/buildrom.cmd /epoc32/rom/tools/ - +/* +* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +PRJ_PLATFORMS +TOOLS2 + +/** +@file + +@SYMPurpose Tool for building ROMs +*/ + +PRJ_EXPORTS + +../tools/buildrom.pl /epoc32/tools/buildrom.pl +../tools/buildrom.pm /epoc32/tools/buildrom.pm +../tools/cdfparser.pm /epoc32/tools/cdfparser.pm +../tools/datadriveimage.pm /epoc32/tools/datadriveimage.pm +../tools/Dep_Lister.pm /epoc32/tools/dep_lister.pm +../tools/externaltools.pm /epoc32/tools/externaltools.pm +../tools/featureparser.pm /epoc32/tools/featureparser.pm +../tools/GenericParser.pm /epoc32/tools/genericparser.pm +../tools/ImageContentHandler.pm /epoc32/tools/imagecontenthandler.pm +../tools/spitool.pm /epoc32/tools/spitool.pm +../tools/spitool.pl /epoc32/tools/spitool.pl +../tools/CONVERT.PL /epoc32/rom/tools/ +../tools/CODESIZE.PL /epoc32/rom/tools/ +../tools/efficient_rom_paging.pm /epoc32/tools/efficient_rom_paging.pm +../tools/flexmodload.pm /epoc32/tools/flexmodload.pm +../tools/romutl.pm /epoc32/tools/romutl.pm +../tools/romosvariant.pm /epoc32/tools/romosvariant.pm +../tools/checkincludeslash.pl /epoc32/tools/checkincludeslash.pl +../tools/checkepocroot.pl /epoc32/tools/checkepocroot.pl +../tools/directory.bat /epoc32/tools/directory.bat + + +// +// Files for Enhanced Feature Manager Support +// +../tools/featuresutil.pm /epoc32/tools/featuresutil.pm +../tools/featureregistry.pm /epoc32/tools/featureregistry.pm +../tools/featuremanager.pm /epoc32/tools/featuremanager.pm +../tools/featurefile.pm /epoc32/tools/featurefile.pm +../tools/featurecfg.pm /epoc32/tools/featurecfg.pm +../tools/featuresdat.pm /epoc32/tools/featuresdat.pm +../tools/features.pl /epoc32/tools/features.pl +../tools/features.pm /epoc32/tools/features.pm + +#ifndef TOOLS2_LINUX +../tools/features.cmd /epoc32/tools/features.cmd +../tools/buildrom.cmd /epoc32/tools/buildrom.cmd +// backwards compatibility for buildrom commandlines... +../tools/buildrom.cmd /epoc32/rom/tools/buildrom.cmd +#else +../tools/features /epoc32/tools/features +../tools/buildrom /epoc32/tools/buildrom +// backwards compatibility for buildrom commandlines... +../tools/buildrom /epoc32/rom/tools/buildrom +#endif + +PRJ_MMPFILES +configpaging + + + diff -r 122d2b873fd1 -r 30b30f9da0b7 imgtools/buildrom/group/buildrom.mrp --- a/imgtools/buildrom/group/buildrom.mrp Fri Jun 25 20:58:33 2010 +0800 +++ b/imgtools/buildrom/group/buildrom.mrp Tue Jun 29 14:52:54 2010 +0800 @@ -1,7 +1,7 @@ component dev_build_imgtools_buildrom -source \src\tools\dev\build\imgtools\buildrom -binary \src\tools\dev\build\imgtools\buildrom\group all -exports \src\tools\dev\build\imgtools\buildrom\group +source \src\tools\build\imgtools\buildrom +binary \src\tools\build\imgtools\buildrom\group all +exports \src\tools\build\imgtools\buildrom\group notes_source \component_defs\release.src diff -r 122d2b873fd1 -r 30b30f9da0b7 imgtools/buildrom/group/release.txt --- a/imgtools/buildrom/group/release.txt Fri Jun 25 20:58:33 2010 +0800 +++ b/imgtools/buildrom/group/release.txt Tue Jun 29 14:52:54 2010 +0800 @@ -1,45 +1,176 @@ -Version 3.17.0 -================ -(Made by Zhi Dou, 26/10/2009) - 1. RM-RIM406-1263: BU: Visual ROM Layout - -Version 3.16.0 -================ -(Made by Zhi Dou, 21/10/2009) - 1. RM-RIM406-1229: BU: Feature Name Alias. - -Version 3.15.2 -================ -(Made by Zhi Dou, 19/10/2009) - 1. Minor change for copyright from SPL to EPL. - -Version 3.15.1 -================ -(Made by Zhi Dou, 19/08/2009) - 1. DPDEF141566 Textshell ROM fails to build due to 'cannot open obey file' - -Version 3.15.0 -================ -(Made by Zhi Dou, 31/07/2009) - 1. PREQ2465's REQ12562 Byte-pair compression update - -Version 3.14.0 -================ -(Made by Zhi Dou, 21/07/2009) - 1. PREQ2465's REQ12561 BUILDROM performance improvement - -Version 3.13.1 -================ -(Made by Zhi Dou, 21/07/2009) - 1. DPDEF140655 Update of tools_romkit for DEF140419 need to be propagated to TCL as well - -Version 3.13.0 -================ -(Made by Zhi Dou, 20/07/2009) - 1. PREQ2131 Hardware Configuration Repository - -Version 3.12.38 -================ -(Made by Zhi Dou, 16/07/2009) - 1. DPDEF140976 breaks textshell builds (RAM-ROM) - +Version 3.26.0 (BUILDROM) +=============== +Released by Lorence Wang 28/06/2010 + 1) Prepend EPOCROOT to epoc32 feature + +Version 3.25.2 (BUILDROM) +=============== +Reoleased by Jason Cui 11/06/2010 + 1) Empty Directory Support in FAT Image + +Version 3.24.2 (BUILDROM) +=============== +Reoleased by Jason Cui 09/06/2010 + 1) DPDEF145499: buildrom cannot support romname + +Version 3.24.1 (buildrom) +=============== +Released by Lorence Wang, 31/05/2010 + 1) DPDEF145359 Buildrom cannot find dso file in linux + 2) DPDEF145470 buildrom with "-wordir=pathname" has error + +Version 3.24.0 (buildrom) +=============== +Released by Lorence Wang, 20/05/2010 + 1) DPDEF145452 work path config -workdir feature + +Version 3.23.1 (buildrom) +=============== +Released by Lorence Wang, 04/05/2010 + 1) DPDEF145374 Symbian Foundation License found in package build + +Version 3.23.0 (buildrom) +=============== +Released by Lorence Wang, 21/04/2010 + 1) DPDEF145365 check path submit + +Version 3.22.2 (buildrom) +=============== +Released by Ross Qin, 14/04/2010 + 1) DPDEF145300 Rombuild hangs in S60 2010wk13 vasco_ui rom building + +Version 1.2.1 (configpaging) +=============== +Released by Zheng Shen, 09/04/2010 + 1) DPDEF145281 Paged meaning change + +Version 3.22.1 (buildrom) +=============== +Released by Zheng Shen, 07/04/2010 + 1) DPDEF145287 ROmbuild.exe will hang with -symbols on TB92 + +Version 3.22.0 (buildrom) +=============== +Released by Ross Qin, 26/03/2010 + 1. RM-RIM406-1232: BU: MAKSYMROFS Integration +Version 3.21.4 (buildrom) +=============== +Released by Lorence Wang, 25/03/2010 + 1) DPDEF145165: S60 build break caused by latest Buildrom. + +Version 3.21.3 (buildrom) +Version 1.1.1 (configpaging) +=============== +Released by Zheng Shen, 16/03/2010 + 1) DPDEF145030 configpaging will hang as some time. + 2) DPDEF144882 buildrom, rombuild,rofsbuil -keepgoing option + +Version 3.20.2 (buildrom) +=============== +Released by Zheng Shen, 08/03/2010 + 1) DPDEF144795 ROM Tools cannot handle mixed binary variation scenario. + 2) DPDEF144862 Correct handling of variant configuration file in a platform independent way + +Version 3.20.1 (buildrom) +=============== +Released by Zheng Shen, 05/03/2010 + 1) DPDEF144535 remove -fastcompress option for rombuild/rofsbuild + +version 3.20.0 (buildrom) +version 0.3 (features) +Version 1.1.0 (configpaging) +=============== +Released by Zheng Shen, 22/02/2010 + 1) DPDEF144562 Build Tools cannot be built in Linux + +Version 3.19.4 (buildrom) +================ +(Made by Marvin Shi, 27/01/2010) + 1. DPDEF143872 the warning from features.pl needs to be updated + +Version 3.19.3 (buildrom) +Version 1.0.0 (configpaging) +================ +(Made by Zheng Shen, 15/12/2009) + 1. DPDEF143392 Change Configpaging.pm to Configpaging.exe + +Version 3.19.2 +================ +(Made by Marvin Shi, 23/11/2009) + 1. DPDEF143057 BUILDROM reports "Invalid Switch" if one or more options contains "/" + 2. DPDEF143123 Feature variant failed in wk47 SOS. + +Version 3.19.1 +================ +(Made by Marvin Shi, 17/11/2009) + 1. DPDEF142921 TSW error CSTI-7X4GHW: Buildtool creates invalid long names in FAT images + 2. DEF142972 buildrom produces garbled logs + +Version 3.19.0 +================ +(Made by Marvin Shi, 13/11/2009) + 1. RM-RIM406-1233: BU: MAKSYMROFS Integration +Version 3.18.1 +================ +(Made by Marvin Shi, 13/11/2009) + 1. DPDEF142937 S60 image creation is failed at feature variant phase +Version 3.18.0 +================ +(Made by Zhi Dou, 03/11/2009) + 1. RM-RIM406-1228: BU: ROFSBUILD Cache + +Version 3.17.1 +================ +(Made by Zhi Dou, 28/10/2009) + 1. DPDEF142726 - ROM tools needs to be running stand alone according to the requirement of SymSEE + +Version 3.17.0 +================ +(Made by Zhi Dou, 26/10/2009) + 1. RM-RIM406-1263: BU: Visual ROM Layout + +Version 3.16.1 +================ +(Made by Zhi Dou, 26/10/2009) + 1. DEF142435 Configpaging is case sensitive when trying to match binary names + +Version 3.16.0 +================ +(Made by Zhi Dou, 21/10/2009) + 1. RM-RIM406-1229: BU: Feature Name Alias. + +Version 3.15.2 +================ +(Made by Zhi Dou, 19/10/2009) + 1. Minor change for copyright from SPL to EPL. + +Version 3.15.1 +================ +(Made by Zhi Dou, 19/08/2009) + 1. DPDEF141566 Textshell ROM fails to build due to 'cannot open obey file' + +Version 3.15.0 +================ +(Made by Zhi Dou, 31/07/2009) + 1. PREQ2465's REQ12562 Byte-pair compression update + +Version 3.14.0 +================ +(Made by Zhi Dou, 21/07/2009) + 1. PREQ2465's REQ12561 BUILDROM performance improvement + +Version 3.13.1 +================ +(Made by Zhi Dou, 21/07/2009) + 1. DPDEF140655 Update of tools_romkit for DEF140419 need to be propagated to TCL as well + +Version 3.13.0 +================ +(Made by Zhi Dou, 20/07/2009) + 1. PREQ2131 Hardware Configuration Repository + +Version 3.12.38 +================ +(Made by Zhi Dou, 16/07/2009) + 1. DPDEF140976 breaks textshell builds (RAM-ROM) + diff -r 122d2b873fd1 -r 30b30f9da0b7 imgtools/buildrom/tools/CODESIZE.PL --- a/imgtools/buildrom/tools/CODESIZE.PL Fri Jun 25 20:58:33 2010 +0800 +++ b/imgtools/buildrom/tools/CODESIZE.PL Tue Jun 29 14:52:54 2010 +0800 @@ -1,28 +1,29 @@ -# -# Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). -# All rights reserved. -# This component and the accompanying materials are made available -# under the terms of the License "Eclipse Public License v1.0" -# which accompanies this distribution, and is available -# at the URL "http://www.eclipse.org/legal/epl-v10.html". -# -# Initial Contributors: -# Nokia Corporation - initial contribution. -# -# Contributors: -# -# Description: -# Add up the codesize lines -# Code size: 00028f4c -# - -while ($line=<>) - { - if ($line =~ /^Code size:\s+(\S+)/i) - { - $totalcode += hex($1); - $count++; - } - } - -print "$count binaries totalling $totalcode\n"; +#!/usr/bin/perl +# +# Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# This component and the accompanying materials are made available +# under the terms of the License "Eclipse Public License v1.0" +# which accompanies this distribution, and is available +# at the URL "http://www.eclipse.org/legal/epl-v10.html". +# +# Initial Contributors: +# Nokia Corporation - initial contribution. +# +# Contributors: +# +# Description: +# Add up the codesize lines +# Code size: 00028f4c +# + +while ($line=<>) + { + if ($line =~ /^Code size:\s+(\S+)/i) + { + $totalcode += hex($1); + $count++; + } + } + +print "$count binaries totalling $totalcode\n"; diff -r 122d2b873fd1 -r 30b30f9da0b7 imgtools/buildrom/tools/CONVERT.PL --- a/imgtools/buildrom/tools/CONVERT.PL Fri Jun 25 20:58:33 2010 +0800 +++ b/imgtools/buildrom/tools/CONVERT.PL Tue Jun 29 14:52:54 2010 +0800 @@ -1,80 +1,85 @@ -# -# Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). -# All rights reserved. -# This component and the accompanying materials are made available -# under the terms of the License "Eclipse Public License v1.0" -# which accompanies this distribution, and is available -# at the URL "http://www.eclipse.org/legal/epl-v10.html". -# -# Initial Contributors: -# Nokia Corporation - initial contribution. -# -# Contributors: -# -# Description: -# parameter %1 is the string which is to occur around (i.e. before and after) the language names in the rest of the parameters to convert to 2-digit language codes -# parameter %2 is the command to execute -# parameters %3 onwards are the parameters to %2 -# example: -# perl -w CONVERT.PL # echo the language code for french is #french# - -$conversionDelimiter=shift; -open(E32STD_H, "< \\epoc32\\include\\E32STD.H") or die "\\epoc32\\include\\E32STD.H could not be opened"; -while ($line=) - { - if ($line=~/\benum\s+TLanguage\b(.*)$/) - { - $line=$1; - while (1) - { - if ($line=~/\{(.*)$/) - { - $line=$1; - last; - } - $line=; - } - $last=0; - $languageCode=0; - while (1) - { - if ($line=~/^(.*?)\}/) - { - $line=$1; - $last=1; - } - while ($line=~/^.*?ELang(\w+)\b(.*)$/) - { - $languageNameInLowerCase=lc $1; - $line=$2; - if ($line=~/^=(\d+)(.*)$/) - { - $languageCode=$1; - $line=$2; - } - $languageData{$languageNameInLowerCase}=$languageCode; - ++$languageCode; - } - if ($last) - { - last; - } - $line=; - } - last; - } - } -close(E32STD_H); -for ($i=$#ARGV; $i>=0; --$i) - { - if ($ARGV[$i]=~/^(.*?)$conversionDelimiter(.*?)$conversionDelimiter(.*)$/) - { - $bitBefore=$1; - $languageNameInLowerCase=lc $2; - $bitAfter=$3; - defined $languageData{$languageNameInLowerCase} or die "The language \"$languageNameInLowerCase\" is not defined in \\epoc32\\include\\E32STD.H"; - $ARGV[$i]=sprintf("$bitBefore%02d$bitAfter", $languageData{$languageNameInLowerCase}); - } - } -system("@ARGV"); - +#!/usr/bin/perl +# +# Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# This component and the accompanying materials are made available +# under the terms of the License "Eclipse Public License v1.0" +# which accompanies this distribution, and is available +# at the URL "http://www.eclipse.org/legal/epl-v10.html". +# +# Initial Contributors: +# Nokia Corporation - initial contribution. +# +# Contributors: +# +# Description: +# parameter %1 is the string which is to occur around (i.e. before and after) the language names in the rest of the parameters to convert to 2-digit language codes +# parameter %2 is the command to execute +# parameters %3 onwards are the parameters to %2 +# example: +# perl -w CONVERT.PL # echo the language code for french is #french# + +use romutl; + +my $include_path=&get_epocroot."epoc32\/include\/"; +$conversionDelimiter=shift; + +open(E32STD_H, "< ${include_path}E32STD.H") or die "${include_path}E32STD.H could not be opened"; +while ($line=) + { + if ($line=~/\benum\s+TLanguage\b(.*)$/) + { + $line=$1; + while (1) + { + if ($line=~/\{(.*)$/) + { + $line=$1; + last; + } + $line=; + } + $last=0; + $languageCode=0; + while (1) + { + if ($line=~/^(.*?)\}/) + { + $line=$1; + $last=1; + } + while ($line=~/^.*?ELang(\w+)\b(.*)$/) + { + $languageNameInLowerCase=lc $1; + $line=$2; + if ($line=~/^=(\d+)(.*)$/) + { + $languageCode=$1; + $line=$2; + } + $languageData{$languageNameInLowerCase}=$languageCode; + ++$languageCode; + } + if ($last) + { + last; + } + $line=; + } + last; + } + } +close(E32STD_H); +for ($i=$#ARGV; $i>=0; --$i) + { + if ($ARGV[$i]=~/^(.*?)$conversionDelimiter(.*?)$conversionDelimiter(.*)$/) + { + $bitBefore=$1; + $languageNameInLowerCase=lc $2; + $bitAfter=$3; + defined $languageData{$languageNameInLowerCase} or die "The language \"$languageNameInLowerCase\" is not defined in \/epoc32\/include\/E32STD.H"; + $ARGV[$i]=sprintf("$bitBefore%02d$bitAfter", $languageData{$languageNameInLowerCase}); + } + } +system("@ARGV"); + diff -r 122d2b873fd1 -r 30b30f9da0b7 imgtools/buildrom/tools/Dep_Lister.pm --- a/imgtools/buildrom/tools/Dep_Lister.pm Fri Jun 25 20:58:33 2010 +0800 +++ b/imgtools/buildrom/tools/Dep_Lister.pm Tue Jun 29 14:52:54 2010 +0800 @@ -1,86 +1,89 @@ -# -# Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). -# All rights reserved. -# This component and the accompanying materials are made available -# under the terms of the License "Eclipse Public License v1.0" -# which accompanies this distribution, and is available -# at the URL "http://www.eclipse.org/legal/epl-v10.html". -# -# Initial Contributors: -# Nokia Corporation - initial contribution. -# -# Contributors: -# -# Description: -# - -# This package contains routines to find the static and dynamic dependencies of a binary. -package Dep_Lister; - -use cdfparser; -require Exporter; -@ISA=qw(Exporter); -@EXPORT=qw( - StaticDeps -); - -use strict; - -# This subroutine evaluates the static dependencies of an E32 executable and returns the list of -# binary names that this binary is dependent on (as found in its import table). If the input file -# is not a valid E32 executable, this routine returns an 'undef'. -sub StaticDeps() -{ - my ($file) = @_; - my @statdeps; - - open PIPE, "elf2e32 --dump i --e32input=$file 2>&1 | "; - my $executable; - my $ver; - my $ext; - my $binary; - my $binaryInfoRef; - my $fileName; - - if($file =~ /.*\\(\S+)/) - { - $fileName = $1; - } - while() - { - if($_ =~ /(\d+) imports from (.*)\{(.*)\}\[?(.*)\]?\.(.*)/i) - { - my $skipLines = $1; - $executable = $2; - $ver = $3; - $ext = $5; - - $binary = $executable . "." . $ext; - - push @statdeps,$binary; - -# Each imported symbol's ordinal number is printed in these lines... -# Skip them - if($skipLines > 0) - { - while() - { - $skipLines--; - if($skipLines == 0 ) - { - last; - } - } - } - } - elsif($_ =~ /elf2e32 : Error: .* is not a valid E32Image file/) - { -# not an e32 image...mark the file as a data file - return undef; - } - } - close PIPE; - return (@statdeps); -} - -1; +# +# Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# This component and the accompanying materials are made available +# under the terms of the License "Eclipse Public License v1.0" +# which accompanies this distribution, and is available +# at the URL "http://www.eclipse.org/legal/epl-v10.html". +# +# Initial Contributors: +# Nokia Corporation - initial contribution. +# +# Contributors: +# +# Description: +# + +# This package contains routines to find the static and dynamic dependencies of a binary. +package dep_lister; + +use cdfparser; +use romutl; + +require Exporter; +@ISA=qw(Exporter); +@EXPORT=qw( + StaticDeps +); + +use strict; + +# This subroutine evaluates the static dependencies of an E32 executable and returns the list of +# binary names that this binary is dependent on (as found in its import table). If the input file +# is not a valid E32 executable, this routine returns an 'undef'. +sub StaticDeps() +{ + my ($file) = @_; + my @statdeps; + + is_existinpath("elf2e32", Romutl::DIE_NOT_FOUND); + open PIPE, "elf2e32 --dump i --e32input=$file 2>&1 | "; + my $executable; + my $ver; + my $ext; + my $binary; + my $binaryInfoRef; + my $fileName; + + if($file =~ /.*[\/\\](\S+)/) + { + $fileName = $1; + } + while() + { + if($_ =~ /(\d+) imports from (.*)\{(.*)\}\[?(.*)\]?\.(.*)/i) + { + my $skipLines = $1; + $executable = $2; + $ver = $3; + $ext = $5; + + $binary = $executable . "." . $ext; + + push @statdeps,$binary; + +# Each imported symbol's ordinal number is printed in these lines... +# Skip them + if($skipLines > 0) + { + while() + { + $skipLines--; + if($skipLines == 0 ) + { + last; + } + } + } + } + elsif($_ =~ /elf2e32 : Error: .* is not a valid E32Image file/) + { +# not an e32 image...mark the file as a data file + return undef; + } + } + close PIPE; + return (@statdeps); +} + +1; diff -r 122d2b873fd1 -r 30b30f9da0b7 imgtools/buildrom/tools/GenericParser.pm --- a/imgtools/buildrom/tools/GenericParser.pm Fri Jun 25 20:58:33 2010 +0800 +++ b/imgtools/buildrom/tools/GenericParser.pm Tue Jun 29 14:52:54 2010 +0800 @@ -1,194 +1,196 @@ -# -# Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). -# All rights reserved. -# This component and the accompanying materials are made available -# under the terms of the License "Eclipse Public License v1.0" -# which accompanies this distribution, and is available -# at the URL "http://www.eclipse.org/legal/epl-v10.html". -# -# Initial Contributors: -# Nokia Corporation - initial contribution. -# -# Contributors: -# -# Description: -# Provides generic methods retrieving data from the XML file. -# Internally uses DOM API. Uses XML Checker to validate the XML. -# - -package genericparser; -require Exporter; -@ISA=qw(Exporter); - -@EXPORT=qw( - - getRootElement - getAttrValue - getElementValue - getSiblingElements - getNodeAttributes - getChildElements - getNodeFromTree - getElementsTagName - getElementName -); - -use strict; -use XML::DOM; -use XML::DOM::ValParser;#XML Validator - -my $validxml; # XML validation status -$XML::Checker::FAIL = \&failhandler; # User defined fail handler - -# User defined fail handler for the XML checker -sub failhandler -{ - my ($code, $msg, @context) = @_; - print "ERROR: $msg\n"; - $validxml = 0; -} - -#Returns the root element of the XML file -sub getRootElement() { - my ($xmlfile) = shift; - die "ERROR: XML File does not exists in the specified path $xmlfile\n" if (!-f $xmlfile); - my $DOMParser = new XML::DOM::Parser(); #DOM Parser - #Set the SGML_SEARCH_PATH to the path where the DTD files are found ($ENV{EPOCROOT}epoc32\\tools). - XML::Checker::Parser::set_sgml_search_path ("$ENV{EPOCROOT}epoc32/tools"); - my $xmlValidator = new XML::Checker::Parser();#Validates XML against Schema - $validxml = 1; - $xmlValidator->parsefile($xmlfile); - - if($validxml) - { - my $document = $DOMParser->parsefile($xmlfile);#Parse XML file - my $root = $document->getDocumentElement(); - return $root; - } - - return 0; -} - -#Returns the attribute value of the element -#Optional argument strictcaseflg does not convert the case of the attribute value -sub getAttrValue(){ - my ($elementname, $name, $strictcaseflg) = @_; - my $attrVal = $elementname->getAttribute($name) ; - if ($attrVal eq "") { - return undef; - } - if(!defined $strictcaseflg) { - return lc($attrVal); - } - else { - return $attrVal; - } -} - -#Returns the element value -#Optional argument strictcaseflg does not convert the case of the element value -sub getElementValue(){ - my ($elementname) = shift; - my ($strictcaseflg)=shift; - my $elementVal; - if( !$elementname->hasChildNodes() ) - { - return undef; - } - if ($elementname->getNodeType == XML::DOM::ELEMENT_NODE) { - $elementVal = $elementname->getFirstChild()->getData ; - } - - if(!defined $strictcaseflg) { - return lc($elementVal); - } - else { - return $elementVal; - } -} - -#Returns the sibling elements for the given node -sub getSiblingElements { - my $child = shift; - my @nodeList; - while($child) { - if($child->getNodeType eq XML::DOM::ELEMENT_NODE) { - @nodeList=(@nodeList,$child); - } - $child = $child->getNextSibling; - } - return @nodeList; -} - -#Returns the attribute list reference for the given node -sub getNodeAttributes() { - my $node = shift; - my $attlist; - if ($node->getNodeType() eq XML::DOM::ELEMENT_NODE) { - $attlist = $node->getAttributes; - } - return $attlist; -} - -#Returns the children for the given node element -sub getChildElements { - my $child = shift; - my @childList; - my @newChildList; - - @childList=$child->getChildNodes; - foreach my $node (@childList) { - if($node->getNodeType eq XML::DOM::ELEMENT_NODE) { - @newChildList=(@newChildList,$node); - } - } - return @newChildList; -} - -#Returns the list of nodes that matches the specified node tree -sub getNodeFromTree(){ - - my @resultNodes; - my ($element, @nodeNames) = @_; - my $nodeName; - my @children = $element->getChildNodes(); - - foreach my $child (@children) { - if ($child->getNodeType eq XML::DOM::ELEMENT_NODE) { - if (($child->getNodeName) eq $nodeNames[0]) { - if ($#nodeNames) { - $nodeName = shift @nodeNames;#Pop unmatched node - push @resultNodes,&getNodeFromTree($child, @nodeNames); - unshift @nodeNames, $nodeName;#Put back the nodes to proper level - } - else { - push @resultNodes,$child;#Push matched node to the destination - } - - } - - } - - } - - return @resultNodes; -} - -#Returns the list of elements whose node matches with the node name supplied -sub getElementsTagName{ - my ($node, $name) = @_; - if ($node->getNodeType eq XML::DOM::ELEMENT_NODE) { - my @taggedElements = $node->getElementsByTagName($name); - return @taggedElements; - } -} - -#Returns the element name for the given node -sub getElementName{ - my $node = shift; - if ($node->getNodeType eq XML::DOM::ELEMENT_NODE) { - return lc($node->getNodeName); - } -} - -1; \ No newline at end of file +# +# Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# This component and the accompanying materials are made available +# under the terms of the License "Eclipse Public License v1.0" +# which accompanies this distribution, and is available +# at the URL "http://www.eclipse.org/legal/epl-v10.html". +# +# Initial Contributors: +# Nokia Corporation - initial contribution. +# +# Contributors: +# +# Description: +# Provides generic methods retrieving data from the XML file. +# Internally uses DOM API. Uses XML Checker to validate the XML. +# + +package genericparser; +require Exporter; +@ISA=qw(Exporter); + +@EXPORT=qw( + + getRootElement + getAttrValue + getElementValue + getSiblingElements + getNodeAttributes + getChildElements + getNodeFromTree + getElementsTagName + getElementName +); + +use strict; +use XML::DOM; +use XML::DOM::ValParser;#XML Validator + +use romutl; + +my $validxml; # XML validation status +$XML::Checker::FAIL = \&failhandler; # User defined fail handler + +# User defined fail handler for the XML checker +sub failhandler +{ + my ($code, $msg, @context) = @_; + print "ERROR: $msg\n"; + $validxml = 0; +} + +#Returns the root element of the XML file +sub getRootElement() { + my ($xmlfile) = shift; + die "ERROR: XML File does not exists in the specified path $xmlfile\n" if (!-f $xmlfile); + my $DOMParser = new XML::DOM::Parser(); #DOM Parser + #Set the SGML_SEARCH_PATH to the path where the DTD files are found ($ENV{EPOCROOT}epoc32\\tools). + XML::Checker::Parser::set_sgml_search_path (&get_epocroot."epoc32/tools"); + my $xmlValidator = new XML::Checker::Parser();#Validates XML against Schema + $validxml = 1; + $xmlValidator->parsefile($xmlfile); + + if($validxml) + { + my $document = $DOMParser->parsefile($xmlfile);#Parse XML file + my $root = $document->getDocumentElement(); + return $root; + } + + return 0; +} + +#Returns the attribute value of the element +#Optional argument strictcaseflg does not convert the case of the attribute value +sub getAttrValue(){ + my ($elementname, $name, $strictcaseflg) = @_; + my $attrVal = $elementname->getAttribute($name) ; + if ($attrVal eq "") { + return undef; + } + if(!defined $strictcaseflg) { + return lc($attrVal); + } + else { + return $attrVal; + } +} + +#Returns the element value +#Optional argument strictcaseflg does not convert the case of the element value +sub getElementValue(){ + my ($elementname) = shift; + my ($strictcaseflg)=shift; + my $elementVal; + if( !$elementname->hasChildNodes() ) + { + return undef; + } + if ($elementname->getNodeType == XML::DOM::ELEMENT_NODE) { + $elementVal = $elementname->getFirstChild()->getData ; + } + + if(!defined $strictcaseflg) { + return lc($elementVal); + } + else { + return $elementVal; + } +} + +#Returns the sibling elements for the given node +sub getSiblingElements { + my $child = shift; + my @nodeList; + while($child) { + if($child->getNodeType eq XML::DOM::ELEMENT_NODE) { + @nodeList=(@nodeList,$child); + } + $child = $child->getNextSibling; + } + return @nodeList; +} + +#Returns the attribute list reference for the given node +sub getNodeAttributes() { + my $node = shift; + my $attlist; + if ($node->getNodeType() eq XML::DOM::ELEMENT_NODE) { + $attlist = $node->getAttributes; + } + return $attlist; +} + +#Returns the children for the given node element +sub getChildElements { + my $child = shift; + my @childList; + my @newChildList; + + @childList=$child->getChildNodes; + foreach my $node (@childList) { + if($node->getNodeType eq XML::DOM::ELEMENT_NODE) { + @newChildList=(@newChildList,$node); + } + } + return @newChildList; +} + +#Returns the list of nodes that matches the specified node tree +sub getNodeFromTree(){ + + my @resultNodes; + my ($element, @nodeNames) = @_; + my $nodeName; + my @children = $element->getChildNodes(); + + foreach my $child (@children) { + if ($child->getNodeType eq XML::DOM::ELEMENT_NODE) { + if (($child->getNodeName) eq $nodeNames[0]) { + if ($#nodeNames) { + $nodeName = shift @nodeNames;#Pop unmatched node + push @resultNodes,&getNodeFromTree($child, @nodeNames); + unshift @nodeNames, $nodeName;#Put back the nodes to proper level + } + else { + push @resultNodes,$child;#Push matched node to the destination + } + + } + + } + + } + + return @resultNodes; +} + +#Returns the list of elements whose node matches with the node name supplied +sub getElementsTagName{ + my ($node, $name) = @_; + if ($node->getNodeType eq XML::DOM::ELEMENT_NODE) { + my @taggedElements = $node->getElementsByTagName($name); + return @taggedElements; + } +} + +#Returns the element name for the given node +sub getElementName{ + my $node = shift; + if ($node->getNodeType eq XML::DOM::ELEMENT_NODE) { + return lc($node->getNodeName); + } +} + +1; diff -r 122d2b873fd1 -r 30b30f9da0b7 imgtools/buildrom/tools/ImageContentHandler.pm --- a/imgtools/buildrom/tools/ImageContentHandler.pm Fri Jun 25 20:58:33 2010 +0800 +++ b/imgtools/buildrom/tools/ImageContentHandler.pm Tue Jun 29 14:52:54 2010 +0800 @@ -1,1550 +1,1551 @@ -# -# Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). -# All rights reserved. -# This component and the accompanying materials are made available -# under the terms of the License "Eclipse Public License v1.0" -# which accompanies this distribution, and is available -# at the URL "http://www.eclipse.org/legal/epl-v10.html". -# -# Initial Contributors: -# Nokia Corporation - initial contribution. -# -# Contributors: -# -# Description: -# - -# This package processes the Image Content XML, and creates an OBY file to create a Rom image. -package ImageContentHandler; - - -require Exporter; -@ISA=qw(Exporter); -@EXPORT=qw( - ParseImageContentXML - ProcessImageContent - AddBinary - GetBldRomOpts - SetBldRomOpts - GenObyFile - GetObyFiles - AddBinaryFromOby - UpdateObyBinaryStaticDep - PrintMsg - DumpBinaries -); - -use strict; -use genericparser; -use cdfparser; -use Dep_Lister; - -#Error list -my @errors; - -my %ImageContent=(); #Image details are stored in this tree -my $RootNode; #The root node of the XML root document element -my @TargetImageList; #The list of target element nodes in the XML. These are ordered based on their - # imageid (if it is a number, else, based on the availibility of Rom locations within 0..7). -my @binarySelectionArray; #This array stores the ABI directories to be looked up to select binaries. -my @ImageContentBinaries; #This list is for the biaries mentioned in Image content XML for - # keywords like, 'primary', 'secondary', 'device', 'extension', 'variant'. - -# List that contains information of binary from OBY file. This list is maintained to check if their static dependencies -# have been included already in Rom. -my %obyFileInfo=(); - -my $ImageIndex=-1; - -my @Includes; #List of included features. The included feature in this list is a hash table giving the - #Uid or the name. These features are collected either from the Image content or the CDF XMLs. -my @Excludes; #List of excluded features.The excluded feature in this list is a hash table giving the - #Uid or the name. These features are collected either from the Image content or the CDF XMLs. - -my %DefaultDirs =();#This hash table records the default ABI and the BUILD directories. These are updated in case - # the overriding buildrom options are provided e.g., -D_FULL_DEBUG or -D_PLAT=GCCE etc. - -my @BPABIPlats = &BPABIutl::BPABIutl_Plat_List; # Add the BPABI Platforms to be added - -my $isEcomPlugin=0; # This flag will be set when PLUGINs are provided in the CDF file. - -sub ParseImageContentXML -{ - my $XMLFile = shift; - - $XMLFile =~ s/\\/\//g; - $RootNode = &getRootElement($XMLFile); - - &SetImageDetails(\%ImageContent, $RootNode); -} - - -my @padding; -#This subroutine traverses the XML tree and stores the fields in the hast table %ImageContent. The keys -# are the branch names. For target nodes., it stores the nodes themselves in the hash table and doesn't -# go deeper. These nodes are processed laster. For the other nodes, it keeps traversing recursively. -# There are some special keys used to store the nodes and values in the tree. While storing an XML::DOM -# node, it sores with the keys 'nodes', while, for storing a value, it is stored with the key 'vals'. -# These are the keys used to retrieve the contents of the tree while generating the final OBY. -sub SetImageDetails -{ - my ($ImageDetailRef, $ImageNode) = @_; - my @children = &genericparser::getChildElements($ImageNode); - my $child; - my $TreeRef; - my $branch; - my $parentName = &genericparser::getElementName($ImageNode); - my $childCnt = scalar @children; - - my ($indent) = join('', @padding); - - my $val = &genericparser::getElementValue($ImageNode); - $val = Trim($val); - if($val ne "") - { - push @{$ImageDetailRef->{vals}}, $val; - } - - my $NodeRef; - foreach $child (@children) - { - $branch = &genericparser::getElementName($child); - - $NodeRef = \%{$ImageDetailRef->{$branch}}; - - if($branch eq "cdf" and $parentName eq "romscope") - { -# Record the romscope node. This node indicates the oby files or cdf files/directories -# that may be used. - push @{$NodeRef->{nodes}}, $child; - next; - } - if($branch eq "target" and $parentName eq "romtarget") - { - push @{$NodeRef->{nodes}}, $child; - next; - } - if( ($branch =~ /primary/i ) || - ($branch =~ /secondary/i) || - ($branch =~ /extension/i) || - ($branch =~ /variant/i ) || - ($branch =~ /device/i ) ) - { - next; - } - - if( $child->hasChildNodes() ) - { - $NodeRef->{hasChildren} = 1; - push @padding, "."; - SetImageDetails($NodeRef, $child); - } - else - { - $NodeRef->{hasChildren} = 0; - } - -# Get all attributes... - my $attribs = &genericparser::getNodeAttributes($child); - my $attrib; - - my $nodeName; - my $nodeVal; - my %attr=(); - my $attrLen = $attribs->getLength; - for (my $pos = 0; $pos < $attrLen;$pos++) - { - $attrib = $attribs->item($pos); - if(!$attrib) - { - next; - } - $nodeName = lc ($attrib->getName); - $nodeVal = lc ($attrib->getValue); - $attr{$nodeName}=$nodeVal; - - } - push @{$NodeRef->{vals}}, \%attr; - } - - pop @padding; -} - -my @romGeometry; #Array to store all Roms mentioned in RomGeometry -my %romGeometryHash = (); #This Hash table records the indices in @romGeometry array, keying on their Ids. - -my $curRomImageIndex; #This scalar records the current Rom image being processed. An binary encountered - # becomes part of the Rom image corresponding to this partition. - -# This subroutine associates the RomGeometry and the RomTarget sub-trees to set indices for the Rom-target -# nodes.It stores the Image content XML entries for primary/secondary/device/extension/variant keywords. -# It also stores the features that are included/excluded in Image content XML. - -sub ProcessImageContent -{ - my $TotalImages = &ProcessRomGeometry(); - - my @trgList; - if( defined @{$ImageContent{romtarget}{target}{nodes}}) - { - @trgList = @{$ImageContent{romtarget}{target}{nodes}}; - } - -# Go through the romgeometry to find the location of each image. The valid IDs are 0 through 7. - - foreach my $trg (@trgList) - { -# The ID field in romgeometry can be an integer in the range 0 through 7. -# If it is not a number, its location is assumed as its sequence number - my $imageid = &genericparser::getAttrValue($trg, "imageid"); - if($imageid =~ /Any/i) - { - next; - } - elsif(exists $romGeometryHash{$imageid}) - { - $ImageIndex = $romGeometryHash{$imageid}; - push @{$TargetImageList[$ImageIndex]} , $trg; - } - } - -# Romscope - update the maps if the files and directories are mentioned. - my @romScopeNodes; - if(defined @{$ImageContent{romscope}{cdf}{nodes}}) - { - @romScopeNodes = @{$ImageContent{romscope}{cdf}{nodes}}; - } - - my $type; - my $file; - my $dir; - foreach my $aNode (@romScopeNodes) - { - $type = &genericparser::getAttrValue($aNode, "type"); - if( $type =~ /dir/i) - { - $dir = &genericparser::getElementValue($aNode); - &cdfparser::CreateCDFFileBinaryMapFromDir($dir); - } - elsif($type =~ /file/i) - { - $file = &genericparser::getElementValue($aNode); - &cdfparser::CreateCDFFileBinaryMap($file); - } - } - - my $availablePos = 0; - foreach my $trg (@trgList) - { - if(&genericparser::getAttrValue($trg, "imageid") =~ /Any/i) - { - while($availablePos < $TotalImages) - { - if( !defined($TargetImageList[$availablePos][0]) ) - { - push @{$TargetImageList[$availablePos]}, $trg; - last; - } - $availablePos++; - } - } - } - - my $pos = 0; - while( $pos < 8) - { - if( defined $TargetImageList[$pos][0] ) - { -# Record the current Rom image index so that the binaries are included in the corresponding -# Rom image. -# The romGeometry and TargetImageList arrays are associated both being indexed on -# the Rom-image index. - - $curRomImageIndex = $pos; - &ProcessTarget($pos, \@{$TargetImageList[$pos]}); - } - $pos++; - } - -# Pick the primary/secondary/device binaries - my @nodes = &genericparser::getNodeFromTree($RootNode, "options", "primary", "file"); - if( defined @nodes) - { - &SaveImageContentBinaries(\@nodes, "primary"); - } - - @nodes = &genericparser::getNodeFromTree($RootNode, "options", "secondary", "file"); - if( defined @nodes) - { - &SaveImageContentBinaries(\@nodes, "secondary"); - } - - @nodes = &genericparser::getNodeFromTree($RootNode, "options", "extension", "file"); - if( defined @nodes) - { - &SaveImageContentBinaries(\@nodes, "extension"); - } - - @nodes = &genericparser::getNodeFromTree($RootNode, "options", "variant", "file"); - if( defined @nodes) - { - &SaveImageContentBinaries(\@nodes, "variant"); - } - - @nodes = &genericparser::getNodeFromTree($RootNode, "options", "device", "file"); - if( defined @nodes) - { - &SaveImageContentBinaries(\@nodes, "device"); - } - - foreach my $imgBin (@ImageContentBinaries) - { - &ProcessStaticDep($imgBin->{source}); - } - -# Pick the binary selection order - if (exists($ImageContent{options}{binaryselectionorder}{vals})) - { - my ($abiDirs) = @{$ImageContent{options}{binaryselectionorder}{vals}}; - @binarySelectionArray = split(',', $abiDirs); - @binarySelectionArray = Trim(@binarySelectionArray); - - } - - my $featureList = &cdfparser::GetIncludedFeatureList(); - foreach my $feature (@$featureList) - { - push @Includes, $feature; - } - - $featureList = &cdfparser::GetExcludedFeatureList(); - foreach my $feature (@$featureList) - { - push @Excludes, $feature; - } -} - -#Arrange the Rom-geometry according to their Id when they are numbers. The named images -#are arranged starting from the empty slots in Rom geometry array. -sub ProcessRomGeometry -{ - my $RomImageCount = 0; - my $pos = 0; - while($pos < 8) - { - $romGeometry[$pos++] = undef; - } - - my @roms = @{$ImageContent{romgeometry}{image}{vals}}; - $RomImageCount = scalar (@roms); - my @namedImages; - -# Visit all images and allocate them the indices they mention. - foreach my $img (@roms) - { - if($img->{id} =~ /(\d+)/) - { - $pos = $1; - if( defined($romGeometry[$pos]) ) - { - print "Error: $romGeometry[$pos]->{id} and $img->{id} cant be allocated the same position\n"; - exit; - } - $romGeometry[$pos] = $img; - -# Record the index of this Rom - $romGeometryHash{$img->{id}} = $pos; - } - else - { -# These are the named images that are allocated there positions sequentially starting from -# the first available empty position - push @namedImages, $img; - } - } - -# Revisit the images and allocate the remaining (unallocated) positions. - - $pos = 0; - my $namedImageCount = scalar (@namedImages); - my $firstNamedImgIdx = 0; - my $img; - while( ($pos < 8) and ($namedImageCount > 0) ) - { - if( $romGeometry[$pos] ) - { -# skip the positions already allocated. - $pos++; - next; - } - $img = $namedImages[$firstNamedImgIdx]; - $romGeometry[$pos] = $img; - -# Record the index of this Rom - $romGeometryHash{$img->{id}} = $pos; - - $pos++;$firstNamedImgIdx++; - $namedImageCount--; - } - - return $RomImageCount; -} - -my @ObyFileList; - -#This subrouting processes the target nodes that may include OBYs/CDFs or features. For CDFs, the satic/dynamic -# dependencies are evaluated. - -sub ProcessTarget -{ - my ($ImgPos , $trgNodesRef) = @_; - my @cdfFileList; - -# For all the 'target' nodes associated with an image in romgeometry at the given index... -# The link between a target and an image in romGeometry is the image id. If the imageid -# of a target is 'Any', then the first available image in romGeometry is allocated to -# that target. - - foreach my $target (@$trgNodesRef) - { - -# Fetch any cdfs included within the Image Content file - my @cdfs = &getNodeFromTree($target, "include","cdf"); - - my $type; - my $file; - my $dir; - foreach my $cdfNode (@cdfs) - { - $type = &genericparser::getAttrValue($cdfNode, "type"); - - if( !($type) || ($type eq "file") ) - { - $file = &genericparser::getElementValue($cdfNode); - push @cdfFileList, $file; - } - elsif($type eq "dir") - { - $dir = &genericparser::getElementValue($cdfNode); - &cdfparser::CreateCDFFileBinaryMapFromDir($dir); - } - } - -# Collect all the obey files mentioned in this 'target' node. - my @obys = &getNodeFromTree($target, "include","obyFile"); - foreach my $obyNode (@obys) - { - $file = &genericparser::getElementValue($obyNode); - push @ObyFileList, $file; - } - - &CollectFeatures($target, 1, \@Includes); - &CollectFeatures($target, 0, \@Excludes); - } - - ProcessCDFList(\@cdfFileList); -} - -# This subroutine updates the include or exclude feature list collected from Image content XML. -sub CollectFeatures -{ -# Collect all the features included/excluded in this 'target' node. - - my ($target, $Inc, $IncludeExcludeListRef) = @_; - my $IncExcStr; - if($Inc == 1) - { - $IncExcStr = "include"; - } - else - { - $IncExcStr = "exclude"; - } - - my @nodes = &getNodeFromTree($target, $IncExcStr,"feature"); - - foreach my $node (@nodes) - { - my %aFeatureInfo = (); - my $isValidFeature = 0; - my $feature = &genericparser::getAttrValue($node, "name"); - - if($Inc) - { -# Mark the feature included. - $aFeatureInfo{include} = 1; - } - else - { -# Mark the feature excluded. - $aFeatureInfo{exclude} = 1; - } - - if(defined $feature and $feature ne "") - { - $aFeatureInfo{name}= $feature; - $aFeatureInfo{uid} = undef; - $isValidFeature = 1; - } - else - { - $feature = &genericparser::getAttrValue($node, "uid"); - if(!defined $feature or $feature eq "") - { - print "Warning: Neither feature name nor uid is defined \n"; - } - else - { - if(&featureparser::ValidateUIDValue($feature)) - { - $feature = &featureparser::ConvertHexToDecimal($feature); - $aFeatureInfo{uid}= $feature; - $aFeatureInfo{name}= undef; - $isValidFeature = 1; - } - else - { - print "The uid value $feature specified in the Image Content Description is not a valid number\n"; - } - } - } - - if($isValidFeature) - { - push @$IncludeExcludeListRef, \%aFeatureInfo; - } - } -} - -sub DumpImageDetails -{ - my ($HRef) = @_; - my %hash = %$HRef; - my $ChildHRef; - - foreach my $Key (keys %hash) - { - if($Key eq "hasChildren" || $Key eq "vals") - { - next; - } - my $indent = join('', @padding); - &PrintMsg ($indent. $Key); - if($hash{$Key}{hasChildren} == 1) - { - push @padding, "."; - &PrintMsg ("\n"); - $ChildHRef = \%{$hash{$Key}}; - &DumpImageDetails($ChildHRef); - } - elsif( defined ($hash{$Key}{vals}) ) - { - &PrintMsg ("\nVals $hash{$Key}{vals}\n"); - push @padding, "."; - $indent = join('', @padding); - my @array = @{$hash{$Key}{vals}}; - &PrintMsg ("array len = " . scalar(@array) . "\n"); - foreach my $attrib ( @array ) - { - foreach my $key1 (keys %$attrib) - { - &PrintMsg ($indent . $Key. " ". "$key1=$$attrib{$key1}\n"); - } - &PrintMsg ("\n"); - } - } - elsif( defined (@{$hash{$Key}{nodes}}) ) - { - my $node = $hash{$Key}{nodes}[0]; - &PrintMsg ("{". scalar(@{$hash{$Key}{nodes}})."}\n"); - } - } - pop @padding; -} - -sub CheckErrors -{ - if($#errors > -1) - { - &PrintMsg ("errors..........$#errors \n"); - foreach (@errors) - { - &PrintMsg ($_ ."\n"); - } - exit; - } -} - -my @ImageBinaryList;#2d array storing the list of binaries per rom image -sub AddBinary -{ - my ($binaryName) = @_; - { - push @{$ImageBinaryList[$curRomImageIndex]}, $binaryName; - } -} - -sub SetBldRomOpts -{ - my ($key, $value) = @_; - if( $key eq undef ) - { -# The default ABI directory is armv5 unless specified otherwise in the buildrom command-line. -# The default build directory is urel unless specified otherwise in the buildrom command-line. - $DefaultDirs{ABI_DIR} = 'ARMV5'; - $DefaultDirs{BUILD_DIR}='urel'; - - $DefaultDirs{DEST_DIR}= "\\sys\\bin"; - - } - else - { -# trim the value for leading/trailing whitespace - $value = Trim($value); - $DefaultDirs{$key} = $value; - } -} - -sub Trim() -{ - my @out = @_; - for (@out) { - s/^\s+//; - s/\s+$//; - } - return wantarray ? @out : $out[0]; -} - -sub GetBldRomOpts -{ - my ($key) = @_; - return $DefaultDirs{$key}; -} - -sub DumpBinaries -{ - &PrintMsg ("***********Binaries in ROM***********\n"); - my $img_idx = 0; - while ($img_idx < 8 and defined ($ImageBinaryList[$img_idx])) - { - my @list = @{$ImageBinaryList[$img_idx]}; - &PrintMsg ("Image $img_idx has ". scalar (@list ) . " binaries\n"); - foreach my $bin (@list) - { - &PrintMsg ("file[$img_idx]=$bin\n"); - } - $img_idx++; - } - - &PrintMsg ("***********END***********\n"); -} - -sub PrintMsg -{ - my ($msg) = @_; - print "$msg"; -} - -# This subroutine is used to generate OBY-contents based on contents of the Image content XML. The image content XML -# may have, in turn, included other OBYs/CDFs. These contents are appended to the Phase-I OBY file (where, the -# Phase-I OBY file is generated by the preprocessor which is the conglomeration of all the buildrom supplied OBY files). -sub GenObyFile -{ - my ($ObyFileName) = @_; - open (OBYFH, ">>$ObyFileName") or die("* Can't open $ObyFileName\n"); - my $binRef; - my $line; - my $index; - my $new_src_path; - my $exec_src_path = $ENV{EPOCROOT};#This is the Executable source path - $exec_src_path .= "epoc32\\release\\"; - my $abidir = $DefaultDirs{ABI_DIR}; - my $blddir = $DefaultDirs{BUILD_DIR}; - - GenObyHeader(*OBYFH); - - for($index = 0;$index < 8;$index++) - { - if( !defined $romGeometry[$index] ) - { - next; - } - - $line = "rom_image $index "; - $line .= $romGeometry[$index]{name} . " "; - $line .= "size=" . $romGeometry[$index]{size} . " "; - if( $romGeometry[$index]{type} =~ /nonxip/) - { - $line .= " non-xip "; - } - else - { - $line .= " xip "; - } - - $line .= $romGeometry[$index]{compression} . " "; - if($romGeometry[$index]{extension} eq "yes") - { - $line .= " extension "; - } - - $line .= "\n"; - - print OBYFH $line; - - $line = "ROM_IMAGE[$index] {\n"; #Start of contents of this image - print OBYFH $line; - - foreach my $binary (@{$ImageBinaryList[$index]}) { - $binRef = &cdfparser::GetBinaryInfo($binary); - if( defined ($binRef) and $binRef->{IsFoundInCDF}) - { - if(exists $binRef->{default}) - { - $line = "DEFAULT_LANGUAGE $binRef->{default} \n"; - print OBYFH "$line"; - } - - if(exists $binRef->{language}) - { - my $langCodes = $binRef->{language}; - foreach my $lang (@$langCodes) - { - $line = "LANGUAGE_CODE $lang \n"; - print OBYFH "$line"; - } - } - -# Replace the BUILD_DIR with udeb or urel -# Default BUILD_DIR is urel and can be overridden by using cmd line option '_FULL_DEBUG' -# If a binary is to be picked always from udeb, then the src path in CDF must be mentioned -# as udeb e.g. abi_dir\udeb\drtaeabi.dll, in which case, the mentioned dir -# is picked as it is. - - $new_src_path = $binRef->{source}; - - $new_src_path =~ s/ABI_DIR/$abidir/i; - $new_src_path =~ s/BUILD_DIR/$blddir/i; - $new_src_path =~ s/DEBUG_DIR/udeb/i; - - $new_src_path =~ s/epocroot/EPOCROOT/; - $new_src_path =~ s/zresource/ZRESOURCE/; - $new_src_path =~ s/zprivate/ZPRIVATE/; - $new_src_path =~ s/zsystem/ZSYSTEM/; - - - my $FileFound = 0; - - if($binRef->{IsExecutable}) - { - $new_src_path = $exec_src_path . $new_src_path; - if(!-f $new_src_path) - { - foreach my $newAbiDir (@binarySelectionArray) - { - $new_src_path =~ s/$abidir/$newAbiDir/i; - if(-f $new_src_path) - { - $FileFound = 1; - last; - } - $abidir = $newAbiDir; - } - - if( !$FileFound ) - { - $FileFound = fallback($abidir, \$new_src_path); - if( !$FileFound ) - { - print "Missing file $binRef->{source} \n"; - $new_src_path = $binRef->{source}; - } - - } - } -# compress options - if(exists $binRef->{compress} and ($binRef->{compress} eq "uncompress") ) - { - $line = "fileuncompress="; - } - elsif($binRef->{compress} eq "compress") - { - $line = "filecompress="; - } - elsif( exists $binRef->{dll}) - { - $line = "dll="; - } -# Checks the plugin type - elsif( exists $binRef->{type} and $binRef->{type} eq "plugin") - { - if (exists $binRef->{plugin_name}) - { - $isEcomPlugin=1; - $line = "__$binRef->{plugin_name}_PLUGIN(ABI_DIR\\BUILD_DIR,ECOM_BIN_DIR,DATAZ_,ECOM_RSC_DIR,$binRef->{id},$binRef->{id})\n"; - } - } - else - { - $isEcomPlugin=0; - $line = "file="; - } - - if (!$isEcomPlugin) - { - $line .= $new_src_path . " "; - $line .= $binRef->{destination}; - } - - -# stack,heap,fixed,priority,uid,dll,dlldatatop - if( exists $binRef->{stack}) - { - $line .= " stack " . $binRef->{stack}; - } - if( exists $binRef->{heapmin}) - { - $line .= " heapmin " . $binRef->{heapmin}; - } - if( exists $binRef->{heapmax}) - { - $line .= " heapmax " . $binRef->{heapmax}; - } - if( exists $binRef->{fixed}) - { - $line .= " fixed"; - } - if( exists $binRef->{priority}) - { - $line .= " priority " . $binRef->{priority}; - } - if( exists $binRef->{uid1}) - { - $line .= " uid1 " . $binRef->{uid1}; - } - if( exists $binRef->{uid2}) - { - $line .= " uid2 " . $binRef->{uid2}; - } - if( exists $binRef->{uid3}) - { - $line .= " uid3 " . $binRef->{uid3}; - } - if( exists $binRef->{dlldatatop}) - { - $line .= " dlldatatop ". $binRef->{dlldatatop}; - } - if( exists $binRef->{customisable} and $binRef->{customisable} eq "true") - { - $line .= " patched "; - } - } - else - { - my $type = $binRef->{type}; - if($type =~ /normal/i) - { - $line = "data="; - } - if($type =~ /aif/i) - { - $line = "aif="; - } - elsif($type =~ /compressedbitmap/i) - { - $line = "compressed-bitmap="; - } - elsif($type =~ /autobitmap/i) - { - $line = "auto-bitmap="; - } - elsif($type =~ /bitmap/i) - { - $line = "bitmap="; - } - - if(exists $binRef->{multilinguify}) - { - my $extension; - my $srcNameWithoutExt; - my $dstNameWithoutExt; - - if($new_src_path =~ /(.*)\.(.*)/) - { - $srcNameWithoutExt = $1; - $extension = $2; - } - if($binRef->{destination} =~ /(.*)\.(.*)/) - { - $dstNameWithoutExt = $1; - } - - $line .= "MULTI_LINGUIFY("; - $line .= $extension . " "; - $line .= $srcNameWithoutExt . " "; - $line .= $dstNameWithoutExt; - $line .= ") "; - } - else - { - $line .= $new_src_path . " "; - $line .= $binRef->{destination}; - } - } - - $line .= "\n"; - print OBYFH $line; - } - else - { - #Check if the binary is from ImageContent XML file. - my $imagecontentbin = 0; - foreach my $bin (@ImageContentBinaries) { - my $source; - if( $bin->{source} =~ /.*\\(\S+)/) - { - $source = $1; - } - if (grep /$binary/i, $source) {#Skip the binary that is already included in the OBY Header - $imagecontentbin = 1; - next; - } - } - - if ($imagecontentbin) { - next; - } - my $obyInfo = &ImageContentHandler::GetObyBinaryInfo($binary); - if(!defined $obyInfo) - { - $line = "file=" . $exec_src_path. $DefaultDirs{ABI_DIR}. "\\" . $DefaultDirs{BUILD_DIR}. "\\". $binary. " "; - $line .= $DefaultDirs{DEST_DIR}. "\\". $binary; - $line .= "\n"; - print OBYFH $line; - } - } - } - $line = "\n}\n"; - print OBYFH $line; - } - close OBYFH; -} - -#Sets default target to ARMV5 directory if the requested binary is not found -sub fallback{ - - my ($abidir, $abiFileRef) = @_; - my $foundFile=0; - foreach my $BpabiPlat (@BPABIPlats) - { - if ($$abiFileRef =~ /^(.*)\\$BpabiPlat\\(.*)$/) - { - $$abiFileRef =~ s/$abidir/ARMV5/i; - if(-f $$abiFileRef) - { - $foundFile = 1; - last; - } - } - } - return $foundFile; -} - -# This subroutine generates the Rom configuration details like, 'bootbinary', 'romlinearbase', romalign, -# 'kerneldataaddress', 'kernelheapmin' etc. -sub GenObyHeader -{ - my ($fh) = @_; - my $line; - -# version - if( defined @{$ImageContent{version}{vals}}) - { - my $ver = @{$ImageContent{version}{vals}}[0]; - if(defined $ver) - { - $line = "version=$ver\n"; - print $fh $line; - } - } - -# romchecksum - if( defined @{$ImageContent{romchecksum}{vals}}) - { - my $cksum = @{$ImageContent{romchecksum}{vals}}[0]; - if(defined $cksum) - { - $line = "romchecksum=$cksum\n"; - print $fh $line; - } - } - -# time - if( defined @{$ImageContent{time}{vals}}) - { - my $time = @{$ImageContent{time}{vals}}[0]; - if(defined $time) - { - $line = "time=ROMDATE $time\n"; - print $fh $line; - } - } - - -# The Binary selection order - if(scalar @binarySelectionArray ) - { - my $abilist = join (',', @binarySelectionArray); - $line = "\nBINARY_SELECTION_ORDER $abilist\n"; - print $fh $line; - } - -# trace - if( defined @{$ImageContent{options}{trace}{vals}}) - { - my @traceFlags = @{$ImageContent{options}{trace}{vals}}; - if(scalar @traceFlags) - { - $line = "trace $traceFlags[0]\n"; - print $fh $line; - } - } - -# The bootbinary - if( defined @{$ImageContent{options}{bootbinary}{vals}}) - { - my $binary; - my @bootbin = @{$ImageContent{options}{bootbinary}{vals}}; - if(scalar @bootbin) - { - $binary = $bootbin[0]; - $binary =~ s/abi_dir/ABI_DIR/; - $line = "bootbinary=$binary\n"; - print $fh $line; - } - } - - -# dataaddress - if( defined @{$ImageContent{options}{dataaddress}{vals}}) - { - my @dataAddr = @{$ImageContent{options}{dataaddress}{vals}}; - if(scalar @dataAddr) - { - $line = "dataaddress=$dataAddr[0]\n"; - print $fh $line; - } - } - -# debugport - if( defined @{$ImageContent{options}{debugport}{vals}}) - { - my @dgbPort = @{$ImageContent{options}{debugport}{vals}}; - if(scalar @dgbPort) - { - $line = "debugport=$dgbPort[0]\n"; - print $fh $line; - } - } - -# defaultstackreserve - if( defined @{$ImageContent{options}{defaultstackreserve}{vals}}) - { - my @defStackRes = @{$ImageContent{options}{defaultstackreserve}{vals}}; - if(scalar @defStackRes) - { - $line = "defaultstackreserve=$defStackRes[0]\n"; - print $fh $line; - } - } - -# wrapper - if( defined @{$ImageContent{options}{wrapper}{vals}}) - { - my %tbl = @{$ImageContent{options}{wrapper}{vals}}[0]; - if(exists $tbl{epoc}) - { - $line = "epocwrapper\n"; - print $fh $line; - } - elsif(exists $tbl{coff}) - { - $line = "coffwrapper\n"; - print $fh $line; - } - elsif(exists $tbl{none}) - { - $line = "nowrapper\n"; - print $fh $line; - } - } - -# kernel options - my $val; - if( defined @{$ImageContent{options}{kernel}{name}{vals}}) - { - $val = @{$ImageContent{options}{kernel}{name}{vals}}[0]; - $line = "kernelromname=$val\n"; - print $fh $line; - } - if( defined @{$ImageContent{options}{kernel}{dataaddress}{vals}}) - { - $val = @{$ImageContent{options}{kernel}{dataaddress}{vals}}[0]; - $line = "kerneldataaddress=$val\n"; - print $fh $line; - } - if( defined @{$ImageContent{options}{kernel}{trace}{vals}}) - { - $val = @{$ImageContent{options}{kernel}{trace}{vals}}[0]; - $line = "kerneltrace $val\n"; - print $fh $line; - } - if( defined @{$ImageContent{options}{kernel}{heapmin}{vals}}) - { - $val = @{$ImageContent{options}{kernel}{heapmin}{vals}}[0]; - $line = "kernelheapmin=$val\n"; - print $fh $line; - } - if( defined @{$ImageContent{options}{kernel}{heapmax}{vals}}) - { - $val = @{$ImageContent{options}{kernel}{heapmax}{vals}}[0]; - $line = "kernelheapmax=$val\n"; - print $fh $line; - } -# romlinearbase - if( defined @{$ImageContent{options}{romlinearbase}{vals}}) - { - my @romLinBase = @{$ImageContent{options}{romlinearbase}{vals}}; - if(scalar @romLinBase) - { - $line = "romlinearbase=$romLinBase[0]\n"; - print $fh $line; - } - } - -# romalign - if( defined @{$ImageContent{options}{romalign}{vals}}) - { - my @romAlign = @{$ImageContent{options}{romalign}{vals}}; - if(scalar @romAlign ) - { - $line = "romalign=$romAlign[0]\n"; - print $fh $line; - } - } - - - - -# autosize keyword with the block size - if( defined @{$ImageContent{options}{autosize}{vals}}) - { - my @autoSz = @{$ImageContent{options}{autosize}{vals}}; - if(scalar @autoSz ) - { - $line = "autosize=$autoSz[0]\n"; - print $fh $line; - } - } - -# coreimage keyword with the coreimage name. - if( defined @{$ImageContent{options}{coreimage}{vals}}) - { - my @coreImg = @{$ImageContent{options}{coreimage}{vals}}; - if(scalar @coreImg) - { - $line = "coreimage=$coreImg[0]\n"; - print $fh $line; - } - } - - - - foreach my $imgBin (@ImageContentBinaries) - { - $line = $imgBin->{keyword}; - my $srcPath = $imgBin->{source}; - $srcPath =~ s/abi_dir/ABI_DIR/; - $srcPath =~ s/kernel_dir/KERNEL_DIR/; - $srcPath =~ s/debug_dir/DEBUG_DIR/; - $srcPath =~ s/build_dir/BUILD_DIR/; - if(! ($imgBin->{keyword} =~ /secondary/i) ) - { -# VARID mentioned for primary, device, extension and variant keywords. - $line .= "[VARID]" ; - } - $line .= "=" . $srcPath . "\t\t" . $imgBin->{destination}; - for my $key (keys %$imgBin) - { - if( ($key =~ /keyword/i) || - ($key =~ /source/i) || - ($key =~ /destination/i)) - { -# These keys are already taken care. - next; - } - -# Write the rest of the keywords if any, (e.g., 'fixed' or HEAPMAX(0x40000) ) to the oby line. - $line .= " ".($key); - if( defined $imgBin->{$key}) - { - $line .= "(". $imgBin->{$key}. ") "; - } - } - print $fh "$line\n"; - } -} - -sub GetObyFiles -{ - return \@ObyFileList; -} - -sub GetBinarySelectionOrder -{ - return \@binarySelectionArray; -} - -sub GetFeatures() -{ - my %FeatureMap = (); - my @FeatList; - my $featRef; - my $uid; - foreach my $feat (@Includes) - { - if($feat->{name}) - { - $uid = &featureparser::getFeatureUID($feat->{name}); - if(!defined $uid) - { - print "Error: Feature $feat->{name} not found in feature list XML\n"; - next; - } - $feat->{uid} = $uid; - } - else - { - $uid = $feat->{uid}; - if(!&featureparser::getFeatureInfo($uid)) - { - print "Error: Feature Uid $uid not found in feature list XML\n"; - next; - } - } - - $featRef = $FeatureMap{$uid}; - if( $featRef->{include} == 1 ) - { -# Already added to the final feature list - } - else - { - $FeatureMap{$uid} = $feat; - push @FeatList, $feat; - } - } - - foreach my $feat (@Excludes) - { - if($feat->{name}) - { - $uid = &featureparser::getFeatureUID($feat->{name}); - if(!defined $uid) - { - print "Error: Feature $feat->{name} not found in feature list XML\n"; - next; - } - $feat->{uid} = $uid; - } - else - { - $uid = $feat->{uid}; - if(!&featureparser::getFeatureInfo($uid)) - { - print "Error: Feature Uid $uid not found in feature list XML\n"; - next; - } - } - - $featRef = $FeatureMap{$uid}; - if( $featRef->{include} == 1 ) - { - print "Error:The feature Uid $uid was added into the include as well as exclude list\n"; - next; - } - elsif($featRef->{exclude} == 1) - { -# Already added to the final feature list - next; - } - else - { - $FeatureMap{$uid} = $feat; - push @FeatList, $feat; - } - } - return \@FeatList; -} - -sub AddBinaryFromOby -{ - my $aBinary = lc shift; - my $aFullPath = lc shift; - - my $bin = \%{$obyFileInfo{$aBinary}}; - $bin->{IsFoundInOby} = 1; - $bin->{fullpath} = $aFullPath; -} - -sub GetObyBinaryInfo -{ - my $aBinary = lc shift; - - my $aBinaryInfoHash = \%{$obyFileInfo{$aBinary}}; - - if( $aBinaryInfoHash->{IsFoundInOby} == 1) - { - return $aBinaryInfoHash; - } - return undef; -} - -sub UpdateObyBinaryStaticDep -{ -# Go through the files added from Oby to see if any of their static -# dependencies need to be resolved. - - foreach my $obyBin (keys %obyFileInfo) - { - if(!defined (&VisitedBinaryInfo($obyBin)) ) - { - &ProcessStaticDep($obyFileInfo{$obyBin}{fullpath}); - } - } -} - -sub SaveImageContentBinaries -{ - my ($binaryListRef, $aKeyword) = @_; - - foreach my $node (@$binaryListRef) - { - my %binInfo = (); - -# The keywords being primary, secondary, extension, variant and device - $binInfo{keyword} = $aKeyword; - - my @children = &genericparser::getChildElements($node); - - foreach my $child (@children) - { - my $name = &genericparser::getElementName($child); - my $val = &genericparser::getElementValue($child); - $binInfo{$name} = $val; - } - push @ImageContentBinaries, \%binInfo; - } -} - -my %VisitedBinaries = (); -my @RomIncludeList; - -sub ProcessCDFList { - - my ($CDFListRef) = @_; - - foreach my $cdf (@$CDFListRef) - { - &LoadFromCDF($cdf); - } - -} - -my @padding ; -sub LoadFromCDF -{ - my $cdf; - my $binFile; - - my @BinList; - ($cdf, $binFile) = @_; - -#Load the XML and get its contents - cdfparser::LoadCDF($cdf); - -#Get all binaries from the mdf - (@BinList) = &cdfparser::GetBinaries($cdf); - - my $DynBinListRef; - my $aBinary; - my $aFile; - - my $VisitedBinaryInfoHash; - my $indent = join('', @padding); - my $binInfo; - foreach $aBinary (@BinList) - { - $VisitedBinaryInfoHash = &VisitedBinaryInfo($aBinary); - if($VisitedBinaryInfoHash) - { - next; - } - else - { - $VisitedBinaryInfoHash = \%{$VisitedBinaries{$aBinary}}; - } - - &ImageContentHandler::AddBinary($aBinary); - - $VisitedBinaryInfoHash->{Marked} = 1; - push @RomIncludeList, $aBinary; - -# Include the dynamic dependencies. - ($DynBinListRef) = cdfparser::GetDynamicDependencies($aBinary); - foreach $aFile (@$DynBinListRef) - { - if(grep $aFile, @BinList) - { -# the dynamic dependency is found in the same cdf file which -# is already loaded. - next; - } - - my $new_cdf = cdfparser::GetCDFFileName($aFile); -# In case there is no cdf describing this binary, ignore it. - if( defined $new_cdf ) - { - push @padding, "."; - LoadFromCDF($new_cdf, $aFile); - } - } - $binInfo = cdfparser::GetBinaryInfo($aBinary); - &ProcessStaticDep($binInfo->{source}, $aBinary); - } -} - -sub ProcessStaticDep -{ - my ($aBinary) = @_; - - my $aAbsFile; -# Include the static dependencies. - - my $dir = "$ENV{EPOCROOT}epoc32\\release\\"; - my $abidir = &ImageContentHandler::GetBldRomOpts("ABI_DIR"); - my $blddir = &ImageContentHandler::GetBldRomOpts("BUILD_DIR"); - - if($aBinary =~ /(.*)\\.*/) - { - $aBinary =~ s/ABI_DIR/$abidir/i; - $aBinary =~ s/BUILD_DIR/$blddir/i; - $aBinary =~ s/DEBUG_DIR/udeb/i; - } - else - { - $dir .= $abidir . "\\"; - $dir .= $blddir. "\\"; - } - $aAbsFile = $dir. $aBinary; - - if(!-f $aAbsFile) - { -# While evaluating the static dependency, check if the file is found in the -# default abi directory. Otherwise, look into the binary selection order. - my $binSelOrderRef = &ImageContentHandler::GetBinarySelectionOrder(); - my $foundFile = 0; - foreach my $newAbiDir (@$binSelOrderRef) - { - $aAbsFile =~ s/$abidir/$newAbiDir/i; - if(-f $aAbsFile) - { - $foundFile = 1; - last; - } - $abidir = $newAbiDir; - } - if($foundFile == 0) - { -#While evaluating the static dependency, check if the file is found in the -#default abi directory. Otherwise, fallback to the default ARMV5 directory. - $foundFile = fallback($abidir, \$aAbsFile); - if($foundFile == 0) - { - return; - } - - } - } - -# Collect the static dependencies of this binary. - my (@StatDepsList) = &Dep_Lister::StaticDeps($aAbsFile); - -# Remove the path portion from the file name if found to get the filename. -# This is the key into the BinaryInfo map maintained by cdfparser. - my $filename; - - if( $aBinary =~ /.*\\(\S+)/) - { - $filename = $1; - } - else - { - $filename = $aBinary; - } - - my $binaryInfoRef = cdfparser::GetBinaryInfo($filename); - - if( defined $binaryInfoRef) - { -# Mark the binary it it is a valid E32 executable. - if(defined @StatDepsList) - { - $binaryInfoRef->{IsExecutable} = 1; - } - else - { - $binaryInfoRef->{IsExecutable} = 0; - } - } - - my $VisitedBinaryInfoHash; - foreach my $aFile (@StatDepsList) - { - my $new_cdf = cdfparser::GetCDFFileName($aFile); - - if(defined($new_cdf)) - { - LoadFromCDF($new_cdf, $aFile); - } - else - { -# Include the static dependencies even if there is no mdf describing this binary - - $VisitedBinaryInfoHash = &VisitedBinaryInfo($aFile); - if( !defined ($VisitedBinaryInfoHash) ) - { - $VisitedBinaryInfoHash = \%{$VisitedBinaries{$aFile}}; - $VisitedBinaryInfoHash->{Marked} = 1; - &ImageContentHandler::AddBinary($aFile); - &ProcessStaticDep($aFile); - } - else - { - } - } - } -} - -sub VisitedBinaryInfo -{ - my ($aBinary) = @_; - my $VisitedBinaryInfoHash = \%{$VisitedBinaries{$aBinary}}; - if($VisitedBinaryInfoHash->{Marked} == 1) - { - return $VisitedBinaryInfoHash; - } - return undef; -} - -1; +# +# Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# This component and the accompanying materials are made available +# under the terms of the License "Eclipse Public License v1.0" +# which accompanies this distribution, and is available +# at the URL "http://www.eclipse.org/legal/epl-v10.html". +# +# Initial Contributors: +# Nokia Corporation - initial contribution. +# +# Contributors: +# +# Description: +# + +# This package processes the Image Content XML, and creates an OBY file to create a Rom image. +package imagecontenthandler; + + +require Exporter; +@ISA=qw(Exporter); +@EXPORT=qw( + ParseImageContentXML + ProcessImageContent + AddBinary + GetBldRomOpts + SetBldRomOpts + GenObyFile + GetObyFiles + AddBinaryFromOby + UpdateObyBinaryStaticDep + PrintMsg + DumpBinaries +); + +use strict; +use genericparser; +use cdfparser; +use dep_lister; +use romutl; + +#Error list +my @errors; + +my %ImageContent=(); #Image details are stored in this tree +my $RootNode; #The root node of the XML root document element +my @TargetImageList; #The list of target element nodes in the XML. These are ordered based on their + # imageid (if it is a number, else, based on the availibility of Rom locations within 0..7). +my @binarySelectionArray; #This array stores the ABI directories to be looked up to select binaries. +my @ImageContentBinaries; #This list is for the biaries mentioned in Image content XML for + # keywords like, 'primary', 'secondary', 'device', 'extension', 'variant'. + +# List that contains information of binary from OBY file. This list is maintained to check if their static dependencies +# have been included already in Rom. +my %obyFileInfo=(); + +my $ImageIndex=-1; + +my @Includes; #List of included features. The included feature in this list is a hash table giving the + #Uid or the name. These features are collected either from the Image content or the CDF XMLs. +my @Excludes; #List of excluded features.The excluded feature in this list is a hash table giving the + #Uid or the name. These features are collected either from the Image content or the CDF XMLs. + +my %DefaultDirs =();#This hash table records the default ABI and the BUILD directories. These are updated in case + # the overriding buildrom options are provided e.g., -D_FULL_DEBUG or -D_PLAT=GCCE etc. + +my @BPABIPlats = &BPABIutl::BPABIutl_Plat_List; # Add the BPABI Platforms to be added + +my $isEcomPlugin=0; # This flag will be set when PLUGINs are provided in the CDF file. + +sub ParseImageContentXML +{ + my $XMLFile = shift; + + $XMLFile =~ s/\\/\//g; + $RootNode = &getRootElement($XMLFile); + + &SetImageDetails(\%ImageContent, $RootNode); +} + + +my @padding; +#This subroutine traverses the XML tree and stores the fields in the hast table %ImageContent. The keys +# are the branch names. For target nodes., it stores the nodes themselves in the hash table and doesn't +# go deeper. These nodes are processed laster. For the other nodes, it keeps traversing recursively. +# There are some special keys used to store the nodes and values in the tree. While storing an XML::DOM +# node, it sores with the keys 'nodes', while, for storing a value, it is stored with the key 'vals'. +# These are the keys used to retrieve the contents of the tree while generating the final OBY. +sub SetImageDetails +{ + my ($ImageDetailRef, $ImageNode) = @_; + my @children = &genericparser::getChildElements($ImageNode); + my $child; + my $TreeRef; + my $branch; + my $parentName = &genericparser::getElementName($ImageNode); + my $childCnt = scalar @children; + + my ($indent) = join('', @padding); + + my $val = &genericparser::getElementValue($ImageNode); + $val = Trim($val); + if($val ne "") + { + push @{$ImageDetailRef->{vals}}, $val; + } + + my $NodeRef; + foreach $child (@children) + { + $branch = &genericparser::getElementName($child); + + $NodeRef = \%{$ImageDetailRef->{$branch}}; + + if($branch eq "cdf" and $parentName eq "romscope") + { +# Record the romscope node. This node indicates the oby files or cdf files/directories +# that may be used. + push @{$NodeRef->{nodes}}, $child; + next; + } + if($branch eq "target" and $parentName eq "romtarget") + { + push @{$NodeRef->{nodes}}, $child; + next; + } + if( ($branch =~ /primary/i ) || + ($branch =~ /secondary/i) || + ($branch =~ /extension/i) || + ($branch =~ /variant/i ) || + ($branch =~ /device/i ) ) + { + next; + } + + if( $child->hasChildNodes() ) + { + $NodeRef->{hasChildren} = 1; + push @padding, "."; + SetImageDetails($NodeRef, $child); + } + else + { + $NodeRef->{hasChildren} = 0; + } + +# Get all attributes... + my $attribs = &genericparser::getNodeAttributes($child); + my $attrib; + + my $nodeName; + my $nodeVal; + my %attr=(); + my $attrLen = $attribs->getLength; + for (my $pos = 0; $pos < $attrLen;$pos++) + { + $attrib = $attribs->item($pos); + if(!$attrib) + { + next; + } + $nodeName = lc ($attrib->getName); + $nodeVal = lc ($attrib->getValue); + $attr{$nodeName}=$nodeVal; + + } + push @{$NodeRef->{vals}}, \%attr; + } + + pop @padding; +} + +my @romGeometry; #Array to store all Roms mentioned in RomGeometry +my %romGeometryHash = (); #This Hash table records the indices in @romGeometry array, keying on their Ids. + +my $curRomImageIndex; #This scalar records the current Rom image being processed. An binary encountered + # becomes part of the Rom image corresponding to this partition. + +# This subroutine associates the RomGeometry and the RomTarget sub-trees to set indices for the Rom-target +# nodes.It stores the Image content XML entries for primary/secondary/device/extension/variant keywords. +# It also stores the features that are included/excluded in Image content XML. + +sub ProcessImageContent +{ + my $TotalImages = &ProcessRomGeometry(); + + my @trgList; + if( defined @{$ImageContent{romtarget}{target}{nodes}}) + { + @trgList = @{$ImageContent{romtarget}{target}{nodes}}; + } + +# Go through the romgeometry to find the location of each image. The valid IDs are 0 through 7. + + foreach my $trg (@trgList) + { +# The ID field in romgeometry can be an integer in the range 0 through 7. +# If it is not a number, its location is assumed as its sequence number + my $imageid = &genericparser::getAttrValue($trg, "imageid"); + if($imageid =~ /Any/i) + { + next; + } + elsif(exists $romGeometryHash{$imageid}) + { + $ImageIndex = $romGeometryHash{$imageid}; + push @{$TargetImageList[$ImageIndex]} , $trg; + } + } + +# Romscope - update the maps if the files and directories are mentioned. + my @romScopeNodes; + if(defined @{$ImageContent{romscope}{cdf}{nodes}}) + { + @romScopeNodes = @{$ImageContent{romscope}{cdf}{nodes}}; + } + + my $type; + my $file; + my $dir; + foreach my $aNode (@romScopeNodes) + { + $type = &genericparser::getAttrValue($aNode, "type"); + if( $type =~ /dir/i) + { + $dir = &genericparser::getElementValue($aNode); + &cdfparser::CreateCDFFileBinaryMapFromDir($dir); + } + elsif($type =~ /file/i) + { + $file = &genericparser::getElementValue($aNode); + &cdfparser::CreateCDFFileBinaryMap($file); + } + } + + my $availablePos = 0; + foreach my $trg (@trgList) + { + if(&genericparser::getAttrValue($trg, "imageid") =~ /Any/i) + { + while($availablePos < $TotalImages) + { + if( !defined($TargetImageList[$availablePos][0]) ) + { + push @{$TargetImageList[$availablePos]}, $trg; + last; + } + $availablePos++; + } + } + } + + my $pos = 0; + while( $pos < 8) + { + if( defined $TargetImageList[$pos][0] ) + { +# Record the current Rom image index so that the binaries are included in the corresponding +# Rom image. +# The romGeometry and TargetImageList arrays are associated both being indexed on +# the Rom-image index. + + $curRomImageIndex = $pos; + &ProcessTarget($pos, \@{$TargetImageList[$pos]}); + } + $pos++; + } + +# Pick the primary/secondary/device binaries + my @nodes = &genericparser::getNodeFromTree($RootNode, "options", "primary", "file"); + if( defined @nodes) + { + &SaveImageContentBinaries(\@nodes, "primary"); + } + + @nodes = &genericparser::getNodeFromTree($RootNode, "options", "secondary", "file"); + if( defined @nodes) + { + &SaveImageContentBinaries(\@nodes, "secondary"); + } + + @nodes = &genericparser::getNodeFromTree($RootNode, "options", "extension", "file"); + if( defined @nodes) + { + &SaveImageContentBinaries(\@nodes, "extension"); + } + + @nodes = &genericparser::getNodeFromTree($RootNode, "options", "variant", "file"); + if( defined @nodes) + { + &SaveImageContentBinaries(\@nodes, "variant"); + } + + @nodes = &genericparser::getNodeFromTree($RootNode, "options", "device", "file"); + if( defined @nodes) + { + &SaveImageContentBinaries(\@nodes, "device"); + } + + foreach my $imgBin (@ImageContentBinaries) + { + &ProcessStaticDep($imgBin->{source}); + } + +# Pick the binary selection order + if (exists($ImageContent{options}{binaryselectionorder}{vals})) + { + my ($abiDirs) = @{$ImageContent{options}{binaryselectionorder}{vals}}; + @binarySelectionArray = split(',', $abiDirs); + @binarySelectionArray = Trim(@binarySelectionArray); + + } + + my $featureList = &cdfparser::GetIncludedFeatureList(); + foreach my $feature (@$featureList) + { + push @Includes, $feature; + } + + $featureList = &cdfparser::GetExcludedFeatureList(); + foreach my $feature (@$featureList) + { + push @Excludes, $feature; + } +} + +#Arrange the Rom-geometry according to their Id when they are numbers. The named images +#are arranged starting from the empty slots in Rom geometry array. +sub ProcessRomGeometry +{ + my $RomImageCount = 0; + my $pos = 0; + while($pos < 8) + { + $romGeometry[$pos++] = undef; + } + + my @roms = @{$ImageContent{romgeometry}{image}{vals}}; + $RomImageCount = scalar (@roms); + my @namedImages; + +# Visit all images and allocate them the indices they mention. + foreach my $img (@roms) + { + if($img->{id} =~ /(\d+)/) + { + $pos = $1; + if( defined($romGeometry[$pos]) ) + { + print "Error: $romGeometry[$pos]->{id} and $img->{id} cant be allocated the same position\n"; + exit; + } + $romGeometry[$pos] = $img; + +# Record the index of this Rom + $romGeometryHash{$img->{id}} = $pos; + } + else + { +# These are the named images that are allocated there positions sequentially starting from +# the first available empty position + push @namedImages, $img; + } + } + +# Revisit the images and allocate the remaining (unallocated) positions. + + $pos = 0; + my $namedImageCount = scalar (@namedImages); + my $firstNamedImgIdx = 0; + my $img; + while( ($pos < 8) and ($namedImageCount > 0) ) + { + if( $romGeometry[$pos] ) + { +# skip the positions already allocated. + $pos++; + next; + } + $img = $namedImages[$firstNamedImgIdx]; + $romGeometry[$pos] = $img; + +# Record the index of this Rom + $romGeometryHash{$img->{id}} = $pos; + + $pos++;$firstNamedImgIdx++; + $namedImageCount--; + } + + return $RomImageCount; +} + +my @ObyFileList; + +#This subrouting processes the target nodes that may include OBYs/CDFs or features. For CDFs, the satic/dynamic +# dependencies are evaluated. + +sub ProcessTarget +{ + my ($ImgPos , $trgNodesRef) = @_; + my @cdfFileList; + +# For all the 'target' nodes associated with an image in romgeometry at the given index... +# The link between a target and an image in romGeometry is the image id. If the imageid +# of a target is 'Any', then the first available image in romGeometry is allocated to +# that target. + + foreach my $target (@$trgNodesRef) + { + +# Fetch any cdfs included within the Image Content file + my @cdfs = &getNodeFromTree($target, "include","cdf"); + + my $type; + my $file; + my $dir; + foreach my $cdfNode (@cdfs) + { + $type = &genericparser::getAttrValue($cdfNode, "type"); + + if( !($type) || ($type eq "file") ) + { + $file = &genericparser::getElementValue($cdfNode); + push @cdfFileList, $file; + } + elsif($type eq "dir") + { + $dir = &genericparser::getElementValue($cdfNode); + &cdfparser::CreateCDFFileBinaryMapFromDir($dir); + } + } + +# Collect all the obey files mentioned in this 'target' node. + my @obys = &getNodeFromTree($target, "include","obyFile"); + foreach my $obyNode (@obys) + { + $file = &genericparser::getElementValue($obyNode); + push @ObyFileList, $file; + } + + &CollectFeatures($target, 1, \@Includes); + &CollectFeatures($target, 0, \@Excludes); + } + + ProcessCDFList(\@cdfFileList); +} + +# This subroutine updates the include or exclude feature list collected from Image content XML. +sub CollectFeatures +{ +# Collect all the features included/excluded in this 'target' node. + + my ($target, $Inc, $IncludeExcludeListRef) = @_; + my $IncExcStr; + if($Inc == 1) + { + $IncExcStr = "include"; + } + else + { + $IncExcStr = "exclude"; + } + + my @nodes = &getNodeFromTree($target, $IncExcStr,"feature"); + + foreach my $node (@nodes) + { + my %aFeatureInfo = (); + my $isValidFeature = 0; + my $feature = &genericparser::getAttrValue($node, "name"); + + if($Inc) + { +# Mark the feature included. + $aFeatureInfo{include} = 1; + } + else + { +# Mark the feature excluded. + $aFeatureInfo{exclude} = 1; + } + + if(defined $feature and $feature ne "") + { + $aFeatureInfo{name}= $feature; + $aFeatureInfo{uid} = undef; + $isValidFeature = 1; + } + else + { + $feature = &genericparser::getAttrValue($node, "uid"); + if(!defined $feature or $feature eq "") + { + print "Warning: Neither feature name nor uid is defined \n"; + } + else + { + if(&featureparser::ValidateUIDValue($feature)) + { + $feature = &featureparser::ConvertHexToDecimal($feature); + $aFeatureInfo{uid}= $feature; + $aFeatureInfo{name}= undef; + $isValidFeature = 1; + } + else + { + print "The uid value $feature specified in the Image Content Description is not a valid number\n"; + } + } + } + + if($isValidFeature) + { + push @$IncludeExcludeListRef, \%aFeatureInfo; + } + } +} + +sub DumpImageDetails +{ + my ($HRef) = @_; + my %hash = %$HRef; + my $ChildHRef; + + foreach my $Key (keys %hash) + { + if($Key eq "hasChildren" || $Key eq "vals") + { + next; + } + my $indent = join('', @padding); + &PrintMsg ($indent. $Key); + if($hash{$Key}{hasChildren} == 1) + { + push @padding, "."; + &PrintMsg ("\n"); + $ChildHRef = \%{$hash{$Key}}; + &DumpImageDetails($ChildHRef); + } + elsif( defined ($hash{$Key}{vals}) ) + { + &PrintMsg ("\nVals $hash{$Key}{vals}\n"); + push @padding, "."; + $indent = join('', @padding); + my @array = @{$hash{$Key}{vals}}; + &PrintMsg ("array len = " . scalar(@array) . "\n"); + foreach my $attrib ( @array ) + { + foreach my $key1 (keys %$attrib) + { + &PrintMsg ($indent . $Key. " ". "$key1=$$attrib{$key1}\n"); + } + &PrintMsg ("\n"); + } + } + elsif( defined (@{$hash{$Key}{nodes}}) ) + { + my $node = $hash{$Key}{nodes}[0]; + &PrintMsg ("{". scalar(@{$hash{$Key}{nodes}})."}\n"); + } + } + pop @padding; +} + +sub CheckErrors +{ + if($#errors > -1) + { + &PrintMsg ("errors..........$#errors \n"); + foreach (@errors) + { + &PrintMsg ($_ ."\n"); + } + exit; + } +} + +my @ImageBinaryList;#2d array storing the list of binaries per rom image +sub AddBinary +{ + my ($binaryName) = @_; + { + push @{$ImageBinaryList[$curRomImageIndex]}, $binaryName; + } +} + +sub SetBldRomOpts +{ + my ($key, $value) = @_; + if( $key eq undef ) + { +# The default ABI directory is armv5 unless specified otherwise in the buildrom command-line. +# The default build directory is urel unless specified otherwise in the buildrom command-line. + $DefaultDirs{ABI_DIR} = 'ARMV5'; + $DefaultDirs{BUILD_DIR}='urel'; + + $DefaultDirs{DEST_DIR}= "\/sys\/bin"; + + } + else + { +# trim the value for leading/trailing whitespace + $value = Trim($value); + $DefaultDirs{$key} = $value; + } +} + +sub Trim() +{ + my @out = @_; + for (@out) { + s/^\s+//; + s/\s+$//; + } + return wantarray ? @out : $out[0]; +} + +sub GetBldRomOpts +{ + my ($key) = @_; + return $DefaultDirs{$key}; +} + +sub DumpBinaries +{ + &PrintMsg ("***********Binaries in ROM***********\n"); + my $img_idx = 0; + while ($img_idx < 8 and defined ($ImageBinaryList[$img_idx])) + { + my @list = @{$ImageBinaryList[$img_idx]}; + &PrintMsg ("Image $img_idx has ". scalar (@list ) . " binaries\n"); + foreach my $bin (@list) + { + &PrintMsg ("file[$img_idx]=$bin\n"); + } + $img_idx++; + } + + &PrintMsg ("***********END***********\n"); +} + +sub PrintMsg +{ + my ($msg) = @_; + print "$msg"; +} + +# This subroutine is used to generate OBY-contents based on contents of the Image content XML. The image content XML +# may have, in turn, included other OBYs/CDFs. These contents are appended to the Phase-I OBY file (where, the +# Phase-I OBY file is generated by the preprocessor which is the conglomeration of all the buildrom supplied OBY files). +sub GenObyFile +{ + my ($ObyFileName) = @_; + open (OBYFH, ">>$ObyFileName") or die("* Can't open $ObyFileName\n"); + my $binRef; + my $line; + my $index; + my $new_src_path; + my $exec_src_path = &get_epocroot;#This is the Executable source path + $exec_src_path .= "epoc32\/release\/"; + my $abidir = $DefaultDirs{ABI_DIR}; + my $blddir = $DefaultDirs{BUILD_DIR}; + + GenObyHeader(*OBYFH); + + for($index = 0;$index < 8;$index++) + { + if( !defined $romGeometry[$index] ) + { + next; + } + + $line = "rom_image $index "; + $line .= $romGeometry[$index]{name} . " "; + $line .= "size=" . $romGeometry[$index]{size} . " "; + if( $romGeometry[$index]{type} =~ /nonxip/) + { + $line .= " non-xip "; + } + else + { + $line .= " xip "; + } + + $line .= $romGeometry[$index]{compression} . " "; + if($romGeometry[$index]{extension} eq "yes") + { + $line .= " extension "; + } + + $line .= "\n"; + + print OBYFH $line; + + $line = "ROM_IMAGE[$index] {\n"; #Start of contents of this image + print OBYFH $line; + + foreach my $binary (@{$ImageBinaryList[$index]}) { + $binRef = &cdfparser::GetBinaryInfo($binary); + if( defined ($binRef) and $binRef->{IsFoundInCDF}) + { + if(exists $binRef->{default}) + { + $line = "DEFAULT_LANGUAGE $binRef->{default} \n"; + print OBYFH "$line"; + } + + if(exists $binRef->{language}) + { + my $langCodes = $binRef->{language}; + foreach my $lang (@$langCodes) + { + $line = "LANGUAGE_CODE $lang \n"; + print OBYFH "$line"; + } + } + +# Replace the BUILD_DIR with udeb or urel +# Default BUILD_DIR is urel and can be overridden by using cmd line option '_FULL_DEBUG' +# If a binary is to be picked always from udeb, then the src path in CDF must be mentioned +# as udeb e.g. abi_dir\udeb\drtaeabi.dll, in which case, the mentioned dir +# is picked as it is. + + $new_src_path = $binRef->{source}; + + $new_src_path =~ s/ABI_DIR/$abidir/i; + $new_src_path =~ s/BUILD_DIR/$blddir/i; + $new_src_path =~ s/DEBUG_DIR/udeb/i; + + $new_src_path =~ s/epocroot/EPOCROOT/; + $new_src_path =~ s/zresource/ZRESOURCE/; + $new_src_path =~ s/zprivate/ZPRIVATE/; + $new_src_path =~ s/zsystem/ZSYSTEM/; + + + my $FileFound = 0; + + if($binRef->{IsExecutable}) + { + $new_src_path = $exec_src_path . $new_src_path; + if(!-f $new_src_path) + { + foreach my $newAbiDir (@binarySelectionArray) + { + $new_src_path =~ s/$abidir/$newAbiDir/i; + if(-f $new_src_path) + { + $FileFound = 1; + last; + } + $abidir = $newAbiDir; + } + + if( !$FileFound ) + { + $FileFound = fallback($abidir, \$new_src_path); + if( !$FileFound ) + { + print "Missing file $binRef->{source} \n"; + $new_src_path = $binRef->{source}; + } + + } + } +# compress options + if(exists $binRef->{compress} and ($binRef->{compress} eq "uncompress") ) + { + $line = "fileuncompress="; + } + elsif($binRef->{compress} eq "compress") + { + $line = "filecompress="; + } + elsif( exists $binRef->{dll}) + { + $line = "dll="; + } +# Checks the plugin type + elsif( exists $binRef->{type} and $binRef->{type} eq "plugin") + { + if (exists $binRef->{plugin_name}) + { + $isEcomPlugin=1; + $line = "__$binRef->{plugin_name}_PLUGIN(ABI_DIR\/BUILD_DIR,ECOM_BIN_DIR,DATAZ_,ECOM_RSC_DIR,$binRef->{id},$binRef->{id})\n"; + } + } + else + { + $isEcomPlugin=0; + $line = "file="; + } + + if (!$isEcomPlugin) + { + $line .= $new_src_path . " "; + $line .= $binRef->{destination}; + } + + +# stack,heap,fixed,priority,uid,dll,dlldatatop + if( exists $binRef->{stack}) + { + $line .= " stack " . $binRef->{stack}; + } + if( exists $binRef->{heapmin}) + { + $line .= " heapmin " . $binRef->{heapmin}; + } + if( exists $binRef->{heapmax}) + { + $line .= " heapmax " . $binRef->{heapmax}; + } + if( exists $binRef->{fixed}) + { + $line .= " fixed"; + } + if( exists $binRef->{priority}) + { + $line .= " priority " . $binRef->{priority}; + } + if( exists $binRef->{uid1}) + { + $line .= " uid1 " . $binRef->{uid1}; + } + if( exists $binRef->{uid2}) + { + $line .= " uid2 " . $binRef->{uid2}; + } + if( exists $binRef->{uid3}) + { + $line .= " uid3 " . $binRef->{uid3}; + } + if( exists $binRef->{dlldatatop}) + { + $line .= " dlldatatop ". $binRef->{dlldatatop}; + } + if( exists $binRef->{customisable} and $binRef->{customisable} eq "true") + { + $line .= " patched "; + } + } + else + { + my $type = $binRef->{type}; + if($type =~ /normal/i) + { + $line = "data="; + } + if($type =~ /aif/i) + { + $line = "aif="; + } + elsif($type =~ /compressedbitmap/i) + { + $line = "compressed-bitmap="; + } + elsif($type =~ /autobitmap/i) + { + $line = "auto-bitmap="; + } + elsif($type =~ /bitmap/i) + { + $line = "bitmap="; + } + + if(exists $binRef->{multilinguify}) + { + my $extension; + my $srcNameWithoutExt; + my $dstNameWithoutExt; + + if($new_src_path =~ /(.*)\.(.*)/) + { + $srcNameWithoutExt = $1; + $extension = $2; + } + if($binRef->{destination} =~ /(.*)\.(.*)/) + { + $dstNameWithoutExt = $1; + } + + $line .= "MULTI_LINGUIFY("; + $line .= $extension . " "; + $line .= $srcNameWithoutExt . " "; + $line .= $dstNameWithoutExt; + $line .= ") "; + } + else + { + $line .= $new_src_path . " "; + $line .= $binRef->{destination}; + } + } + + $line .= "\n"; + print OBYFH $line; + } + else + { + #Check if the binary is from ImageContent XML file. + my $imagecontentbin = 0; + foreach my $bin (@ImageContentBinaries) { + my $source; + if( $bin->{source} =~ /.*[\\\/](\S+)/) + { + $source = $1; + } + if (grep /$binary/i, $source) {#Skip the binary that is already included in the OBY Header + $imagecontentbin = 1; + next; + } + } + + if ($imagecontentbin) { + next; + } + my $obyInfo = &ImageContentHandler::GetObyBinaryInfo($binary); + if(!defined $obyInfo) + { + $line = "file=" . $exec_src_path. $DefaultDirs{ABI_DIR}. "\/" . $DefaultDirs{BUILD_DIR}. "\/". $binary. " "; + $line .= $DefaultDirs{DEST_DIR}. "\/". $binary; + $line .= "\n"; + print OBYFH $line; + } + } + } + $line = "\n}\n"; + print OBYFH $line; + } + close OBYFH; +} + +#Sets default target to ARMV5 directory if the requested binary is not found +sub fallback{ + + my ($abidir, $abiFileRef) = @_; + my $foundFile=0; + foreach my $BpabiPlat (@BPABIPlats) + { + if ($$abiFileRef =~ /^(.*)[\/\\]$BpabiPlat[\/\\](.*)$/) + { + $$abiFileRef =~ s/$abidir/ARMV5/i; + if(-f $$abiFileRef) + { + $foundFile = 1; + last; + } + } + } + return $foundFile; +} + +# This subroutine generates the Rom configuration details like, 'bootbinary', 'romlinearbase', romalign, +# 'kerneldataaddress', 'kernelheapmin' etc. +sub GenObyHeader +{ + my ($fh) = @_; + my $line; + +# version + if( defined @{$ImageContent{version}{vals}}) + { + my $ver = @{$ImageContent{version}{vals}}[0]; + if(defined $ver) + { + $line = "version=$ver\n"; + print $fh $line; + } + } + +# romchecksum + if( defined @{$ImageContent{romchecksum}{vals}}) + { + my $cksum = @{$ImageContent{romchecksum}{vals}}[0]; + if(defined $cksum) + { + $line = "romchecksum=$cksum\n"; + print $fh $line; + } + } + +# time + if( defined @{$ImageContent{time}{vals}}) + { + my $time = @{$ImageContent{time}{vals}}[0]; + if(defined $time) + { + $line = "time=ROMDATE $time\n"; + print $fh $line; + } + } + + +# The Binary selection order + if(scalar @binarySelectionArray ) + { + my $abilist = join (',', @binarySelectionArray); + $line = "\nBINARY_SELECTION_ORDER $abilist\n"; + print $fh $line; + } + +# trace + if( defined @{$ImageContent{options}{trace}{vals}}) + { + my @traceFlags = @{$ImageContent{options}{trace}{vals}}; + if(scalar @traceFlags) + { + $line = "trace $traceFlags[0]\n"; + print $fh $line; + } + } + +# The bootbinary + if( defined @{$ImageContent{options}{bootbinary}{vals}}) + { + my $binary; + my @bootbin = @{$ImageContent{options}{bootbinary}{vals}}; + if(scalar @bootbin) + { + $binary = $bootbin[0]; + $binary =~ s/abi_dir/ABI_DIR/; + $line = "bootbinary=$binary\n"; + print $fh $line; + } + } + + +# dataaddress + if( defined @{$ImageContent{options}{dataaddress}{vals}}) + { + my @dataAddr = @{$ImageContent{options}{dataaddress}{vals}}; + if(scalar @dataAddr) + { + $line = "dataaddress=$dataAddr[0]\n"; + print $fh $line; + } + } + +# debugport + if( defined @{$ImageContent{options}{debugport}{vals}}) + { + my @dgbPort = @{$ImageContent{options}{debugport}{vals}}; + if(scalar @dgbPort) + { + $line = "debugport=$dgbPort[0]\n"; + print $fh $line; + } + } + +# defaultstackreserve + if( defined @{$ImageContent{options}{defaultstackreserve}{vals}}) + { + my @defStackRes = @{$ImageContent{options}{defaultstackreserve}{vals}}; + if(scalar @defStackRes) + { + $line = "defaultstackreserve=$defStackRes[0]\n"; + print $fh $line; + } + } + +# wrapper + if( defined @{$ImageContent{options}{wrapper}{vals}}) + { + my %tbl = @{$ImageContent{options}{wrapper}{vals}}[0]; + if(exists $tbl{epoc}) + { + $line = "epocwrapper\n"; + print $fh $line; + } + elsif(exists $tbl{coff}) + { + $line = "coffwrapper\n"; + print $fh $line; + } + elsif(exists $tbl{none}) + { + $line = "nowrapper\n"; + print $fh $line; + } + } + +# kernel options + my $val; + if( defined @{$ImageContent{options}{kernel}{name}{vals}}) + { + $val = @{$ImageContent{options}{kernel}{name}{vals}}[0]; + $line = "kernelromname=$val\n"; + print $fh $line; + } + if( defined @{$ImageContent{options}{kernel}{dataaddress}{vals}}) + { + $val = @{$ImageContent{options}{kernel}{dataaddress}{vals}}[0]; + $line = "kerneldataaddress=$val\n"; + print $fh $line; + } + if( defined @{$ImageContent{options}{kernel}{trace}{vals}}) + { + $val = @{$ImageContent{options}{kernel}{trace}{vals}}[0]; + $line = "kerneltrace $val\n"; + print $fh $line; + } + if( defined @{$ImageContent{options}{kernel}{heapmin}{vals}}) + { + $val = @{$ImageContent{options}{kernel}{heapmin}{vals}}[0]; + $line = "kernelheapmin=$val\n"; + print $fh $line; + } + if( defined @{$ImageContent{options}{kernel}{heapmax}{vals}}) + { + $val = @{$ImageContent{options}{kernel}{heapmax}{vals}}[0]; + $line = "kernelheapmax=$val\n"; + print $fh $line; + } +# romlinearbase + if( defined @{$ImageContent{options}{romlinearbase}{vals}}) + { + my @romLinBase = @{$ImageContent{options}{romlinearbase}{vals}}; + if(scalar @romLinBase) + { + $line = "romlinearbase=$romLinBase[0]\n"; + print $fh $line; + } + } + +# romalign + if( defined @{$ImageContent{options}{romalign}{vals}}) + { + my @romAlign = @{$ImageContent{options}{romalign}{vals}}; + if(scalar @romAlign ) + { + $line = "romalign=$romAlign[0]\n"; + print $fh $line; + } + } + + + + +# autosize keyword with the block size + if( defined @{$ImageContent{options}{autosize}{vals}}) + { + my @autoSz = @{$ImageContent{options}{autosize}{vals}}; + if(scalar @autoSz ) + { + $line = "autosize=$autoSz[0]\n"; + print $fh $line; + } + } + +# coreimage keyword with the coreimage name. + if( defined @{$ImageContent{options}{coreimage}{vals}}) + { + my @coreImg = @{$ImageContent{options}{coreimage}{vals}}; + if(scalar @coreImg) + { + $line = "coreimage=$coreImg[0]\n"; + print $fh $line; + } + } + + + + foreach my $imgBin (@ImageContentBinaries) + { + $line = $imgBin->{keyword}; + my $srcPath = $imgBin->{source}; + $srcPath =~ s/abi_dir/ABI_DIR/; + $srcPath =~ s/kernel_dir/KERNEL_DIR/; + $srcPath =~ s/debug_dir/DEBUG_DIR/; + $srcPath =~ s/build_dir/BUILD_DIR/; + if(! ($imgBin->{keyword} =~ /secondary/i) ) + { +# VARID mentioned for primary, device, extension and variant keywords. + $line .= "[VARID]" ; + } + $line .= "=" . $srcPath . "\t\t" . $imgBin->{destination}; + for my $key (keys %$imgBin) + { + if( ($key =~ /keyword/i) || + ($key =~ /source/i) || + ($key =~ /destination/i)) + { +# These keys are already taken care. + next; + } + +# Write the rest of the keywords if any, (e.g., 'fixed' or HEAPMAX(0x40000) ) to the oby line. + $line .= " ".($key); + if( defined $imgBin->{$key}) + { + $line .= "(". $imgBin->{$key}. ") "; + } + } + print $fh "$line\n"; + } +} + +sub GetObyFiles +{ + return \@ObyFileList; +} + +sub GetBinarySelectionOrder +{ + return \@binarySelectionArray; +} + +sub GetFeatures() +{ + my %FeatureMap = (); + my @FeatList; + my $featRef; + my $uid; + foreach my $feat (@Includes) + { + if($feat->{name}) + { + $uid = &featureparser::getFeatureUID($feat->{name}); + if(!defined $uid) + { + print "Error: Feature $feat->{name} not found in feature list XML\n"; + next; + } + $feat->{uid} = $uid; + } + else + { + $uid = $feat->{uid}; + if(!&featureparser::getFeatureInfo($uid)) + { + print "Error: Feature Uid $uid not found in feature list XML\n"; + next; + } + } + + $featRef = $FeatureMap{$uid}; + if( $featRef->{include} == 1 ) + { +# Already added to the final feature list + } + else + { + $FeatureMap{$uid} = $feat; + push @FeatList, $feat; + } + } + + foreach my $feat (@Excludes) + { + if($feat->{name}) + { + $uid = &featureparser::getFeatureUID($feat->{name}); + if(!defined $uid) + { + print "Error: Feature $feat->{name} not found in feature list XML\n"; + next; + } + $feat->{uid} = $uid; + } + else + { + $uid = $feat->{uid}; + if(!&featureparser::getFeatureInfo($uid)) + { + print "Error: Feature Uid $uid not found in feature list XML\n"; + next; + } + } + + $featRef = $FeatureMap{$uid}; + if( $featRef->{include} == 1 ) + { + print "Error:The feature Uid $uid was added into the include as well as exclude list\n"; + next; + } + elsif($featRef->{exclude} == 1) + { +# Already added to the final feature list + next; + } + else + { + $FeatureMap{$uid} = $feat; + push @FeatList, $feat; + } + } + return \@FeatList; +} + +sub AddBinaryFromOby +{ + my $aBinary = lc shift; + my $aFullPath = lc shift; + + my $bin = \%{$obyFileInfo{$aBinary}}; + $bin->{IsFoundInOby} = 1; + $bin->{fullpath} = $aFullPath; +} + +sub GetObyBinaryInfo +{ + my $aBinary = lc shift; + + my $aBinaryInfoHash = \%{$obyFileInfo{$aBinary}}; + + if( $aBinaryInfoHash->{IsFoundInOby} == 1) + { + return $aBinaryInfoHash; + } + return undef; +} + +sub UpdateObyBinaryStaticDep +{ +# Go through the files added from Oby to see if any of their static +# dependencies need to be resolved. + + foreach my $obyBin (keys %obyFileInfo) + { + if(!defined (&VisitedBinaryInfo($obyBin)) ) + { + &ProcessStaticDep($obyFileInfo{$obyBin}{fullpath}); + } + } +} + +sub SaveImageContentBinaries +{ + my ($binaryListRef, $aKeyword) = @_; + + foreach my $node (@$binaryListRef) + { + my %binInfo = (); + +# The keywords being primary, secondary, extension, variant and device + $binInfo{keyword} = $aKeyword; + + my @children = &genericparser::getChildElements($node); + + foreach my $child (@children) + { + my $name = &genericparser::getElementName($child); + my $val = &genericparser::getElementValue($child); + $binInfo{$name} = $val; + } + push @ImageContentBinaries, \%binInfo; + } +} + +my %VisitedBinaries = (); +my @RomIncludeList; + +sub ProcessCDFList { + + my ($CDFListRef) = @_; + + foreach my $cdf (@$CDFListRef) + { + &LoadFromCDF($cdf); + } + +} + +my @padding ; +sub LoadFromCDF +{ + my $cdf; + my $binFile; + + my @BinList; + ($cdf, $binFile) = @_; + +#Load the XML and get its contents + cdfparser::LoadCDF($cdf); + +#Get all binaries from the mdf + (@BinList) = &cdfparser::GetBinaries($cdf); + + my $DynBinListRef; + my $aBinary; + my $aFile; + + my $VisitedBinaryInfoHash; + my $indent = join('', @padding); + my $binInfo; + foreach $aBinary (@BinList) + { + $VisitedBinaryInfoHash = &VisitedBinaryInfo($aBinary); + if($VisitedBinaryInfoHash) + { + next; + } + else + { + $VisitedBinaryInfoHash = \%{$VisitedBinaries{$aBinary}}; + } + + &ImageContentHandler::AddBinary($aBinary); + + $VisitedBinaryInfoHash->{Marked} = 1; + push @RomIncludeList, $aBinary; + +# Include the dynamic dependencies. + ($DynBinListRef) = cdfparser::GetDynamicDependencies($aBinary); + foreach $aFile (@$DynBinListRef) + { + if(grep $aFile, @BinList) + { +# the dynamic dependency is found in the same cdf file which +# is already loaded. + next; + } + + my $new_cdf = cdfparser::GetCDFFileName($aFile); +# In case there is no cdf describing this binary, ignore it. + if( defined $new_cdf ) + { + push @padding, "."; + LoadFromCDF($new_cdf, $aFile); + } + } + $binInfo = cdfparser::GetBinaryInfo($aBinary); + &ProcessStaticDep($binInfo->{source}, $aBinary); + } +} + +sub ProcessStaticDep +{ + my ($aBinary) = @_; + + my $aAbsFile; +# Include the static dependencies. + + my $dir = &get_epocroot()."epoc32\/release\/"; + my $abidir = &ImageContentHandler::GetBldRomOpts("ABI_DIR"); + my $blddir = &ImageContentHandler::GetBldRomOpts("BUILD_DIR"); + + if($aBinary =~ /(.*)[\\\/].*/) + { + $aBinary =~ s/ABI_DIR/$abidir/i; + $aBinary =~ s/BUILD_DIR/$blddir/i; + $aBinary =~ s/DEBUG_DIR/udeb/i; + } + else + { + $dir .= $abidir . "\/"; + $dir .= $blddir. "\/"; + } + $aAbsFile = $dir. $aBinary; + + if(!-f $aAbsFile) + { +# While evaluating the static dependency, check if the file is found in the +# default abi directory. Otherwise, look into the binary selection order. + my $binSelOrderRef = &ImageContentHandler::GetBinarySelectionOrder(); + my $foundFile = 0; + foreach my $newAbiDir (@$binSelOrderRef) + { + $aAbsFile =~ s/$abidir/$newAbiDir/i; + if(-f $aAbsFile) + { + $foundFile = 1; + last; + } + $abidir = $newAbiDir; + } + if($foundFile == 0) + { +#While evaluating the static dependency, check if the file is found in the +#default abi directory. Otherwise, fallback to the default ARMV5 directory. + $foundFile = fallback($abidir, \$aAbsFile); + if($foundFile == 0) + { + return; + } + + } + } + +# Collect the static dependencies of this binary. + my (@StatDepsList) = &Dep_Lister::StaticDeps($aAbsFile); + +# Remove the path portion from the file name if found to get the filename. +# This is the key into the BinaryInfo map maintained by cdfparser. + my $filename; + + if( $aBinary =~ /.*[\\\/](\S+)/) + { + $filename = $1; + } + else + { + $filename = $aBinary; + } + + my $binaryInfoRef = cdfparser::GetBinaryInfo($filename); + + if( defined $binaryInfoRef) + { +# Mark the binary it it is a valid E32 executable. + if(defined @StatDepsList) + { + $binaryInfoRef->{IsExecutable} = 1; + } + else + { + $binaryInfoRef->{IsExecutable} = 0; + } + } + + my $VisitedBinaryInfoHash; + foreach my $aFile (@StatDepsList) + { + my $new_cdf = cdfparser::GetCDFFileName($aFile); + + if(defined($new_cdf)) + { + LoadFromCDF($new_cdf, $aFile); + } + else + { +# Include the static dependencies even if there is no mdf describing this binary + + $VisitedBinaryInfoHash = &VisitedBinaryInfo($aFile); + if( !defined ($VisitedBinaryInfoHash) ) + { + $VisitedBinaryInfoHash = \%{$VisitedBinaries{$aFile}}; + $VisitedBinaryInfoHash->{Marked} = 1; + &ImageContentHandler::AddBinary($aFile); + &ProcessStaticDep($aFile); + } + else + { + } + } + } +} + +sub VisitedBinaryInfo +{ + my ($aBinary) = @_; + my $VisitedBinaryInfoHash = \%{$VisitedBinaries{$aBinary}}; + if($VisitedBinaryInfoHash->{Marked} == 1) + { + return $VisitedBinaryInfoHash; + } + return undef; +} + +1; diff -r 122d2b873fd1 -r 30b30f9da0b7 imgtools/buildrom/tools/buildrom.pl --- a/imgtools/buildrom/tools/buildrom.pl Fri Jun 25 20:58:33 2010 +0800 +++ b/imgtools/buildrom/tools/buildrom.pl Tue Jun 29 14:52:54 2010 +0800 @@ -1,118 +1,130 @@ -# -# Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). -# All rights reserved. -# This component and the accompanying materials are made available -# under the terms of the License "Eclipse Public License v1.0" -# which accompanies this distribution, and is available -# at the URL "http://www.eclipse.org/legal/epl-v10.html". -# -# Initial Contributors: -# Nokia Corporation - initial contribution. -# -# Contributors: -# -# Description: -# - - -use FindBin; # for FindBin::Bin -my $PerlLibPath; # fully qualified pathname of the directory containing our Perl modules - -BEGIN { -# check user has a version of perl that will cope - require 5.005_03; -# establish the path to the Perl libraries - $PerlLibPath = $FindBin::Bin; # X:/epoc32/tools - $PerlLibPath =~ s/\//\\/g; # X:\epoc32\tools - $PerlLibPath .= "\\"; -} - - -use lib $PerlLibPath; -#Includes the validation perl modules for XML validation against the given DTD. -use lib "$PerlLibPath/build/lib"; - -use buildrom; # for buildrom module -use externaltools; #To support External tool invocation - - -# Main block for buildrom module invocation -{ - # Processes the buildrom command line parameters. - &process_cmdline_arguments; - - &image_content_processing_phase; - - #Processes intermediate oby files. Also processes any new option added to the buildrom in future. - &processobyfiles; - - # Suppress ROM/ROFS/DataDrive Image creation if "-noimage" option is provided. - &suppress_image_generation; - - #Invokes ROMBUILD and ROFSBUILD - &invoke_rombuild; - - &create_smrimage; - - #Process data drive image. - &processData; -} - - -sub processobyfiles { - - - # Creates intermediate tmp1.oby file. Preprocessing phase - &preprocessing_phase; - - # Creates intermediate tmp2.oby file. Predefined substitutions - &substitution_phase; - - # Creates intermediate tmp3.oby file. Reorganises the ROM IMAGE[] - &reorganize_phase; - - # Creates feature registry configuration file/features data file. - &featurefile_creation_phase; - - # Run single Invocation external tool at InvocationPoint1 - - &externaltools::runExternalTool("InvocationPoint1", &getOBYDataRef); - - # Creates intermediate tmp4.oby file. Avoids processing of REM ECOM_PLUGIN(xxx,yyy) - &plugin_phase; - - # Creates intermediate tmp5.oby file. Multilinguify phase - &multlinguify_phase; - - # Creates intermediate tmp6.oby file. SPI file creation phase - &spi_creation_phase; - - # Run single Invocation external tool at InvocationPoint2 - &externaltools::runExternalTool("InvocationPoint2",&getOBYDataRef); - - # Creates intermediate tmp7.oby file. Problem Suppression phase - &suppress_phase; - - #Process the patched dll data - &process_dlldata; - - # Creates intermediate tmp8.oby file. For xip and non-xip images - &bitmap_aif_converison_phase; - - # Creates intermediate tmp9.oby file. Cleaning unnecessary data for ROM image creation. - &cleaning_phase; - - # Run single Invocation external tool at InvocationPoint2.5 - &externaltools::runExternalTool("InvocationPoint2.5",&getOBYDataRef); - - #Creates dump OBY file for final oby file - &create_dumpfile; - - # Run single Invocation external tool at InvocationPoint3 - &externaltools::runExternalTool("InvocationPoint3",&getOBYDataRef); - - #ROM directory listing - &create_dirlisting; - -} - +#!/usr/bin/perl +# +# Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# This component and the accompanying materials are made available +# under the terms of the License "Eclipse Public License v1.0" +# which accompanies this distribution, and is available +# at the URL "http://www.eclipse.org/legal/epl-v10.html". +# +# Initial Contributors: +# Nokia Corporation - initial contribution. +# +# Contributors: +# +# Description: +# + + +use FindBin; # for FindBin::Bin +my $PerlLibPath; # fully qualified pathname of the directory containing our Perl modules +my $PerlEPOCPath; + +BEGIN { +# check user has a version of perl that will cope + require 5.005_03; +# establish the path to the Perl libraries + $PerlLibPath = $FindBin::Bin; +# $PerlLibPath =~ s/\//\\/g; + $PerlLibPath .= "\\"; + $PerlLibPath =~ s/\\/\//g; + + $PerlEPOCPath = $ENV{EPOCROOT}; + $PerlEPOCPath =~ s/\\/\//g; + $PerlEPOCPath .= "\/" unless $PerlEPOCPath =~ /\/$/; + $PerlEPOCPath .= "epoc32\/tools\/"; +} +use lib $PerlEPOCPath."build/lib/"; +use lib $PerlEPOCPath; +use lib $PerlLibPath; + +use buildrom; # for buildrom module +use externaltools; #To support External tool invocation +use romutl; +use romosvariant; + +# add current path and SDK tool path to the begining of environment path +my $epocroot=&get_epocroot; +my $delimiter=&env_delimiter; +$ENV{PATH}="${PerlLibPath}$delimiter${epocroot}epoc32\/tools$delimiter${epocroot}epoc32\/gcc\/bin$delimiter${epocroot}epoc32\/gcc_mingw\/bin$delimiter".$ENV{PATH}; + +# Main block for buildrom module invocation +{ + # Processes the buildrom command line parameters. + &process_cmdline_arguments; + + &image_content_processing_phase; + + #Processes intermediate oby files. Also processes any new option added to the buildrom in future. + &processobyfiles; + + # Suppress ROM/ROFS/DataDrive Image creation if "-noimage" option is provided. + &suppress_image_generation; + + #Invokes ROMBUILD and ROFSBUILD + &invoke_rombuild; + + &create_smrimage; + + #Process data drive image. + &processData; +} + + +sub processobyfiles { + + + # Creates intermediate tmp1.oby file. Preprocessing phase + &preprocessing_phase; + + # Creates intermediate tmp2.oby file. Predefined substitutions + &substitution_phase; + + # Creates intermediate tmp3.oby file. Reorganises the ROM IMAGE[] + &reorganize_phase; + + # Creates feature registry configuration file/features data file. + &featurefile_creation_phase; + + # Run single Invocation external tool at InvocationPoint1 + + &externaltools::runExternalTool("InvocationPoint1", &getOBYDataRef); + + # Creates intermediate tmp4.oby file. Avoids processing of REM ECOM_PLUGIN(xxx,yyy) + &plugin_phase; + + # Creates intermediate tmp5.oby file. Multilinguify phase + &multlinguify_phase; + + # Creates intermediate tmp6.oby file. SPI file creation phase + &spi_creation_phase; + + # Run single Invocation external tool at InvocationPoint2 + &externaltools::runExternalTool("InvocationPoint2",&getOBYDataRef); + + # Creates intermediate tmp7.oby file. Problem Suppression phase + &suppress_phase; + + #Process the patched dll data + &process_dlldata; + + # Creates intermediate tmp8.oby file. For xip and non-xip images + &bitmap_aif_converison_phase; + + # Creates intermediate tmp9.oby file. Cleaning unnecessary data for ROM image creation. + &cleaning_phase; + + # Run single Invocation external tool at InvocationPoint2.5 + &externaltools::runExternalTool("InvocationPoint2.5",&getOBYDataRef); + + #Creates dump OBY file for final oby file + &create_dumpfile; + + # Run single Invocation external tool at InvocationPoint3 + &externaltools::runExternalTool("InvocationPoint3",&getOBYDataRef); + + #ROM directory listing + &create_dirlisting; + +} + diff -r 122d2b873fd1 -r 30b30f9da0b7 imgtools/buildrom/tools/buildrom.pm --- a/imgtools/buildrom/tools/buildrom.pm Fri Jun 25 20:58:33 2010 +0800 +++ b/imgtools/buildrom/tools/buildrom.pm Tue Jun 29 14:52:54 2010 +0800 @@ -1,4654 +1,5177 @@ -# -# Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). -# All rights reserved. -# This component and the accompanying materials are made available -# under the terms of the License "Eclipse Public License v1.0" -# which accompanies this distribution, and is available -# at the URL "http://www.eclipse.org/legal/epl-v10.html". -# -# Initial Contributors: -# Nokia Corporation - initial contribution. -# -# Contributors: -# -# Description: -# This package is to build rom image -# - -package buildrom; - -require Exporter; -@ISA=qw(Exporter); -@EXPORT=qw( - image_content_processing_phase - process_cmdline_arguments - preprocessing_phase - substitution_phase - reorganize_phase - plugin_phase - multlinguify_phase - spi_creation_phase - suppress_phase - bitmap_aif_converison_phase - cleaning_phase - create_dumpfile - create_dirlisting - suppress_image_generation - invoke_rombuild - getOBYDataRef - isobystatement - isdatastatement - isspidatastatement - isexecutablefile - isdirectorymetadata - isbitmap - isaif - isresource - hardwarevariant - executableextension - executabletype - getSourceFile - getDestFile - getOBYAttributes - getHardwareVariant - getObyCommand - process_dlldata - featurefile_creation_phase - processData - create_smrimage -); - -my $enforceFeatureManager = 0; # Flag to make Feature Manager mandatory if SYMBIAN_FEATURE_MANAGER macro is defined. - -my $BuildromMajorVersion = 3 ; -my $BuildromMinorVersion = 17; -my $BuildromPatchVersion = 0; - -sub print_usage -{ - - # Option "-fm" will be supported instead of option "-f|fr" if SYMBIAN_FEATURE_MANAGER macro is defined. - my $featuresOptionUsage = "-ffeatureuids or -fr=featureuids -- feature registry database XML file name"; - if ($enforceFeatureManager) - { - $featuresOptionUsage = "-fm=featuredatabasefile -- feature manager/feature registry database XML file name.\n". - "\t\t\t\t Multiple XML files can be passed seperated by commas.\n". - " -nofm=featuresdatafile -- don't generate features data file.". - " Instead use pre-built features data file."; - } - -#........1.........2.........3.........4.........5.........6.........7..... - print < -- do the main job with threads - -loglevel -- Level of information logging where loglevel is 0,1,2 - 0 default level of information - 1 host/ROM filenames, file size and the hidden attribute along with level0 log - 2 E32 file header attributes along with level1 log - -z=xxx or -zdrivepath=xxx -- specify a location to create Z drive directory. - -d=xxx or -datadrivepath=xxx -- specify a location to create data drive directory. - -k or -keepgoing -- enable keepgoing,continue to create the data drive image even - if the non-sis, sis or zdrive image file(s) are missing or corrupt. - -r or -retainfolder -- enable retainfolder,would retain pre-existence of z & data drive folder. - -zdriveimage=xxx -- specify Z drive image (ROM, CORE, ROFS or Ext-ROFS image). - -pfile=xxx -- specify a parameter file for interpretsis to take additional parameters. - -argforinterpretsis=xxx -- specify command line argument(s) for interpretsis which will override the - parameter file contents. - -l=xxx or -logimagecontents=xxx -- extract all stub-sis and SWI certificate store file(s) only - and log all the file(s) that are part of the Z drive image on to a log file. - -I -- Use for the referenced IBY/OBY files - -argfile=xxx -- specify argument-file name containing list of command-line arguments to buildrom - -lowmem -- use memory-mapped file for image build to reduce physical memory consumption - -Popular -D defines to use include - - -D_DEBUG -- select debug versions of some files - -D_FULL_DEBUG -- select debug versions of all files - -D_ARM4 -- specify the target platform - - -D_EABI=xxxx -- specify target for all files (e.g. ARMV5) - -D_KABI=xxxx -- specify the target platform for the Kernel (e.g. ARMV5) - -Other defines may be useful for particular OBY files. - -USAGE_EOF -} - -use strict; -my $PerlLibPath; # fully qualified pathname of the directory containing our Perl modules -# establish the path to the Perl libraries -$PerlLibPath = $FindBin::Bin; # X:/epoc32/tools -$PerlLibPath =~ s/\//\\/g; # X:\epoc32\tools -$PerlLibPath .= "\\"; -sub ExportDirs ($); - -use BPABIutl; # for BPABIutl::BPABIutl_Plat_List - -my $xmlrequired = 0; # assume xml required is false. Used to determine if xml - # modules should be loaded. - -use Modload; # To load modules dynamically - -# Work out the relative path to the epoc32 directory -use spitool qw(&createSpi); -use Cwd; -use Pathutl; -use E32Variant; -use E32Plat; -use Genutl; -use BPABIutl; # for BPABIutl::BPABIutl_Plat_List -use externaltools; #To invoke External Tools - -my @tempfiles; -my $preserve = 0; #flag to indicate if temporary files should be preserved -my $uppath="x"; # will be initialised when first needed - -my $epocroot = $ENV{EPOCROOT}; -die "ERROR: Must set the EPOCROOT environment variable\n" if (!defined($epocroot)); -$epocroot =~ s-/-\\-go; # for those working with UNIX shells -die "ERROR: EPOCROOT must not include a drive letter\n" if ($epocroot =~ /^.:/); -die "ERROR: EPOCROOT must be an absolute path without a drive letter\n" if ($epocroot !~ /^\\/); -die "ERROR: EPOCROOT must not be a UNC path\n" if ($epocroot =~ /^\\\\/); -die "ERROR: EPOCROOT must end with a backslash\n" if ($epocroot !~ /\\$/); -die "ERROR: EPOCROOT must specify an existing directory\n" if (!-d $epocroot); - -my $epoc32 = relative_path("${epocroot}epoc32"); -$epoc32 =~ s-\\-/-go; - -my @obyfiles; -my $cppargs = "-nostdinc -undef"; -my $opt_v = 0; -my $opt_o = ""; -my $strict = 0; -my $warnSelection = 0; # default is not warn about selecting files from - # different directories when the file is missing from - # the specified directory - -my $createspi = 0; # don't create SPI files by default -my $spiset=0; -my $spiplacement = 0; # enable the placement of spi file -my %spipositionflag = (); # map of Image index at which the keyword SPI_POSITION is used. - -use constant NONE => 0; -use constant INFLATE => 1; -use constant BYTEPAIR => 2; -my $opt_compression; # Default compression method parameter undefined - -use constant UNCOMPRESSED => 0; # Indicates the ROM image will not be compressed. -use constant ALLSECTIONS => 1; # Indicates both paged section and unpaged section will be compressed. -use constant PAGEDSECTION => 2; # Indicates only paged section will be compressed. -use constant UNPAGEDSECTION => 3; # Indicates only unpaged section will be compressed. -my $opt_compression_type = UNCOMPRESSED; # Leave the ROM image uncompressed by default. - -my $thisdir=cwd; -$thisdir=~s-/-\\-go; # separator from Perl 5.005_02+ is forward slash -$thisdir=~s-^(.*[^\\])$-$1\\-o; # ensure path ends with a backslash -$thisdir=~s-^.:\\--o; # remove drive letter and leading backslash - -my $rominclude = "$epoc32/rom/include"; -my %plugintypes; #hash of plugin types and their SPI files' destinations in ROM -$plugintypes{"ECOM"} = "\\private\\10009d8f\\"; #ECOM SPI files' destination in ROM image - -my @obydata; -my @newobydata; -my %substitutionData; -my @substitutionOrder; -my %languageCodes; -my $defaultLanguageCode; -my %multiLinguifyAlias; # to by-pass the 'mustbesysbin' option for multilinguify 'alias'es. -my $abiDowngrade; -my @binarySelectionOrder; -my $fromDIR; -my %rombuildOptions = ("-type-safe-link" => 1 ); -my $enforceSysBin = 0; - -my $line; -my $errors = 0; -my @romimage; -my $rombasename; - -my $sourcefile; -my $sourceline; -my ($line); -my %romfiles; - -# To handle BINARY_SELECTION_ORDER macro. -my $firstDIR; -my $binarySelectionOrderFlag = 0; - -my %DllDataMap = (); #Map to keep track of DLL Data patch statements. -my $patchDataStmtFlag = 0; - -my $featuremanager = 0; #Flag to enable support for feature manager database XML file and to generate - # features data file. -my $noFeatureManager = 0; # Flag to stop the generation of features.dat file and use pre-built features.dat if provided. -my $preBuiltFeaturesDataFile = ''; # To store the name of pre-built features.dat file provided with "-nofm" option. - -#Image Content XML file that supports specific feature to be added -my $image_content = undef; -#Feature list XML file that acts as database containing all features details -my $featureXml = undef; -my $geninc = ""; -my $gendep = ""; -my $nosymbols = ""; -my $noimage = ""; -my $customizedPlat = undef; -my $opt_fastcompress = ""; -my $opt_jobs= ""; - -#Summary of files(both executables and data files) currently includes -# host and ROM file names, -# size of the file in ROM -# whether the file is hidden -# This option is added so that the above additional information is emitted by rombuild/rofsbuild tools -# only when supplied with this option so that the existing tools don't get affected. -my $logLevel=""; - -# This option is used to pass -lowmem argument to rombuild/rofsbuild tools -my $lowMem=""; - -# Feature Variation modules and data -use featurevariantparser; -use featurevariantmap; -my %featureVariant; - -# global variables specific to data drive image generation. -use File::Path; # Module to provide functions to remove or create directories in a convenient way. -use File::Copy; # Module to provide functions to copy file(s) from source to destination. -use File::Find; -use datadriveimage; # module which provides all necessary functions to create data drive image. -my $ZDirloc = ""; # location of Z drive directory. -my $DataDriveDirloc = ""; # location of data drive directory. -my @sisfilelist; # an array to hold sis file(s). -my @zDriveImageList; # an array to hold z drive image name. -my @datadiveobydata; # an array to hold data drive oby data. -my @datadriveimage; # array which holds data drive image attribute. -my $rootdir = ""; # which holds root directory information. -my @datadrivedata; # array to maintain list of lines taken from processed data drive oby file. -my @nonsisFilelist; # array to maintain list of nonsis file(s). -my @sisobydata; # array to maintain all list of files(s) got by installing sis files. -my @renameList; # array to maintain list of file(s) that has to be renamed. -my @aliaslist; # array to maintain list of file(s) that has to be made alias. -my @hideList; # array to maintain list of file(s) that has to be made hidden. -my $sisfilepresent = 0; # enable if sis file(s) are present. -my $stubsisfilepresent = 0; # enable if stub-sis file(s) are present. -my $opt_k = 0; # enable if keepgoing option is specified by the user. -my $opt_r = 0; # enable if retain pre-existence of folder is specified by the user. -my $dataImageCount = 0; # no of data drive image that has to generated. -my @zdriveImageName; # list of Z drive image name(s) specified using zdriveimagename in oby/iby file. -my $opt_zimage = 0; # enable if z drive image is found. -my $zDrivePresent = 0; # flag to check whether Z drive needs to be created. -my @dataDriveFileList; # list of processed data drive related files. -my $paraFile = undef; # parameter file for interpretsis. -my @romImages; # list of generated z drive image(s)(rom/rofs). -my $imageEntryLogFile = undef; # a log file to log all the z drive image contents. -my $opt_logFile = 0; # enable if z drive entries has to be logged on to a log file. -my %dataIndexHash = (); # a hash which holds key-value pair between datadrive index and datadrive image count. -my $interpretsisOpt = undef; # enable if command line arguments are specified by the user to INTERPRETSIS. -my @interpretsisOptList; # an array which holds all the list of option(s) that needs to passed to INTERPRETSIS. -my @Global_BPABIPlats; -my @Global_PlatList; -my @smrImageFileList; -my $needSmrImage = 0; -my %smrPartitions; -my %smrNameInfo; -my @obeyFileList; -my $smrNoImageName = 0; -my $onlysmrimage = 1; - -sub match_obyfile -{ - my ($obyfile) = @_; - if (-f $obyfile) - { - push @obyfiles, $obyfile; - return 1; - } - - # search for the oby file in the list of include directories - my @otherDirs = ($rominclude); - - if ($featureVariant{'VALID'}) - { - my $dirRef = $featureVariant{'ROM_INCLUDES'}; - - @otherDirs = @$dirRef if ($dirRef); - } - foreach my $dir (@otherDirs) - { - if (-f "$dir/$obyfile") - { - push @obyfiles, "$dir/$obyfile"; - return 1; - } - } - return 0; -} - - -# This function invokes ROFSBUILD tool with appropriate parameters to generate data drive image. -# It also deletes zdrive and datadrive folder after all the image has been processed and generated -# if and only if preserve(-p) option is disabled. -sub create_datadriveImage -{ - for (my $dataidx=0; $dataidx < $dataImageCount; $dataidx++) - { - my $driveIndex = $dataIndexHash{$dataidx}; - - if(defined($driveIndex)) - { - my $obeyfile=$datadriveimage[$driveIndex]{obeyfile}; - my $compress=$datadriveimage[$driveIndex]{compress}; - my $uncompress=$datadriveimage[$driveIndex]{uncompress}; - - if ($obeyfile) - { - if(!defined $opt_compression) - { - if ($compress ne 0) - { - $compress=" -compress"; - } - elsif($uncompress ne 0) - { - $compress=" -uncompress"; - } - elsif($compress eq 0) - { - $compress=" "; - } - } - else - { - $compress = $opt_compression; - $compress =~m/\s-(compression)(method)\s(none|inflate|bytepair)/; - print "* ".$1." ".$2.": ".$3; - } - my $command = "rofsbuild -slog".$compress." -datadrive=$obeyfile.oby"; - print "* Executing $command\n" if ($opt_v); - system($command); - if ($? != 0) - { - &datadriveimage::reportError("* ROFSBUILD failed to generate data drive image",$opt_k); - } - else - { - push(@dataDriveFileList,$obeyfile.".img"); - } - } - } - } - # after processing all the data drive image(s) delete zdrive and datadrive directory - # if and only if preserve(-p) option is disabled. - if($dataImageCount) - { - # delete Z drive directory if and only if preserve(-p) option is disabled. - my $retVal = &deleteDirectory($ZDirloc,$opt_v)if(!($preserve)); - if($retVal) - { - &datadriveimage::reportError("* Warning could not delete $ZDirloc",$opt_k); - } - # delete data drive directory if and only if preserve(-p) option is disabled. - my $retVal = &deleteDirectory($DataDriveDirloc,$opt_v)if(!($preserve)); - if($retVal) - { - &datadriveimage::reportError("* Warning could not delete $DataDriveDirloc",$opt_k); - } - # reset image count to zero. - $dataImageCount = 0; - # reset z drive present to zero. - $zDrivePresent = 0; - } -} - -sub tidy_exit -{ - #------------------------------------------------------- - # Tidy and exit - - if (!$preserve) - { - foreach my $tempfiles (@tempfiles) - { - unlink "$tempfiles"; - } - } - if($rombasename) - { - system("dir $rombasename.*"); - } - if(@dataDriveFileList) - { - print "\n"; - print " ----------------------------------------------------------\n"; - print "| List of file(s) generated pertaining to data drive image |\n"; - print " ----------------------------------------------------------\n"; - my $arraySize = scalar(@dataDriveFileList); - for( my $i=0; $i < $arraySize; $i++ ) - { - # remove the first element from an array and return it - my $element = shift(@dataDriveFileList); - # get the size of the file. - my $size = -s $element; - print "Size = ".$size." bytes"."\t"."File = ".$element."\n"; - } - } - exit(0); -} - -# This is the main function which is responsible for processing data drive image. -# This function internally calls other functions to create datadrive folder,zdrive folder -# and external tools such as INTERPRETSIS, READIMAGE and finally ROFSBUILD to generate -# appropriate data drive image. -sub processData -{ - if($dataImageCount) - { - # set the default path for Z drive and Data drive directory, - # if and only if, path is not specified by the user. - $ZDirloc = &datadriveimage::setPath("zdrive") unless ($ZDirloc); - $DataDriveDirloc = &datadriveimage::setPath("datadrive") unless ($DataDriveDirloc); - #delete any existing Z drive directory. - my $retVal = &datadriveimage::deleteDirectory($ZDirloc,$opt_v)if(!$opt_r); - if($retVal) - { - exit(1) if(!$opt_k); - } - # delete pre-existence of data drive folder, if and only if -r option is not enabled. - my $retVal = &datadriveimage::deleteDirectory($DataDriveDirloc,$opt_v) if(!$opt_r); - if($retVal) - { - exit(1) if(!$opt_k); - } - if($opt_logFile) - { - # clean any pre-existance of log file. - unlink($ZDirloc."\\".$imageEntryLogFile); - } - - for (my $datadriveidx=0; $datadriveidx < $dataImageCount; $datadriveidx++) - { - my $driveIndex = $dataIndexHash{$datadriveidx}; - # get the data drive name. - if( defined( $driveIndex ) ) - { - my $datadrivename=$datadriveimage[$driveIndex]{obeyfile}; - # get the size of the data drive. - my $size = $datadriveimage[$driveIndex]{size}; - if( $datadrivename ) - { - # set data drive oby file. - my $datadriveobyfile = $datadrivename.".oby"; - # final location of prototype data drive. - my $proDataDriveDirloc; - # Location of stub-sis file(s) inside Z Drive folder. - my $zDriveSisFileLoc; - # check if more than one data drive image needs to be generated. - if( $dataImageCount > 1 ) - { - # if yes, then set the location of prototype data drive folder as - # DataDriveDirloc + datadrivename - $proDataDriveDirloc = $DataDriveDirloc."\\".$datadrivename; - } - else - { - # else, then set the location of prototype data drive folder as DataDriveDirloc - $proDataDriveDirloc = $DataDriveDirloc; - } - - # create prototype data drive folder. - print "creating data drive folder\n" if ($opt_v); - &datadriveimage::createDirectory($proDataDriveDirloc); - - # check for sis file keyword in ROM description file. - # if found,then locate for stub-sisfile. - # create Z drive( if and only if stub-sis files are present in ROM description file ) - # and dump all the non-sis files on to the Z drive folder. - if(&datadriveimage::checkForSisFile($datadriveobyfile,\@sisfilelist,\$sisfilepresent)) - { - my $zDriveImagePresent = 0; # flag to check whether z drive image is Present; - if(&datadriveimage::checkForZDriveImageKeyword($datadriveobyfile,\@zDriveImageList,\$zDriveImagePresent) ) - { - # find out size of the array - my $arraysize = scalar(@zDriveImageList); - for( my $i=0; $i < $arraysize; $i++ ) - { - $zDriveSisFileLoc = $ZDirloc."\\".$datadrivename; - &datadriveimage::invokeReadImage(pop(@zDriveImageList),$zDriveSisFileLoc,$opt_v,$imageEntryLogFile,$opt_k); - } - } - else - { - $zDriveSisFileLoc = $ZDirloc; - # locate and copy stub-sis file(s),for the first time. - if( !$zDrivePresent ) - { - # check for image file. - if( $opt_zimage ) - { - # image(s)supplied to BUILDROM(like rom,rofs,extrofs or core) using "-zdriveimage" option, - # are maintained in a seperate array and the element from the array is fetched one by one and is - # fed to READIMAGE as an input. - foreach my $element (@zdriveImageName) - { - # invoke READIMAGE to extract all /swi stub sis file(s) from the given image. - $zDrivePresent = &datadriveimage::invokeReadImage($element,$zDriveSisFileLoc,$opt_v,$imageEntryLogFile,$opt_k); - } - } - else - { - # if zdrive image(s) such as (rom,core,rofs or extrofs) are generated ealier to the data drive image processing - # then these images are maintained in an array and the element from the array is fetched one by one and is - # fed to READIMAGE as an input. - foreach my $element (@romImages) - { - # invoke READIMAGE to extract all /swi stub sis file(s) from the given image. - $zDrivePresent = &datadriveimage::invokeReadImage($element,$zDriveSisFileLoc,$opt_v,$imageEntryLogFile,$opt_k); - } - } - } - } - # invoke INTERPRETSIS tool with z drive folder location. - &datadriveimage::invokeInterpretsis( \@sisfilelist,$proDataDriveDirloc,$opt_v,$zDriveSisFileLoc,$paraFile,$opt_k,\@interpretsisOptList)if($sisfilepresent); - } - - # create an oby file by traversing through upated prototype data drive directory. - &datadriveimage::dumpDatadriveObydata( $proDataDriveDirloc,$datadriveobyfile,$size,\@nonsisFilelist, - \@renameList,\@aliaslist,\@hideList,\@sisobydata,\@datadrivedata,$opt_k,$opt_v ); - #reset sisfilepresent flag to zero; - $sisfilepresent =0; - } - } - } - create_datadriveImage(); - } - tidy_exit; -} -#Parse and process image content xml file -#Gets the oby files listed in the xml file -# Pushes all the oby files found to an array - -sub image_content_processing_phase -{ - if(!defined ($image_content)) - { - return; - } - &ImageContentHandler::ParseImageContentXML($image_content); - &ImageContentHandler::ProcessImageContent; - - if(defined ($image_content) ) - { -# Collect the oby files if any in the Image content file - my $files = &ImageContentHandler::GetObyFiles; - foreach my $obeyfile (@$files) - { - next if match_obyfile($obeyfile); - next if (match_obyfile("$obeyfile.oby")); - } - } -} - -# Subroutine to process parameter-file -sub parameterFileProcessor -{ - my $paramFile = shift(@_); - my @paramFileParamaters = (); - - my $fileOpenFlag = 1; - open FILE,"<", $paramFile or $fileOpenFlag = 0; - - if(!$fileOpenFlag) - { - print "Error: Could not open parameter-file \"$paramFile\" for reading.\n"; - return; - } - - # Parse parameter-file and collect all the parameters in an array - while(my $line = ) - { - # Read the line till character ';'(used for providing comments in the file) or EOL - $line = $1 if ($line =~ /(.*);/); - - # Split the parameters specified in a line based on white-spaces - my @paramaters = split(/(\s)/,$line); - - my $flag = 0; - my $argWithQuotes=''; - - foreach my $value (@paramaters) - { - # If the parameter doesn't conatian double quotes then push it - # to the list of parameters. - if(($value !~ /\"/) && (!$argWithQuotes)) - { - if ($value !~ /^\s*$/) - { - push @paramFileParamaters,$value; - } - } - # If the parameter is in the form -fm="faturedb.xml" then remove - # double quotes and push it to the list of parameters. - elsif(($value =~ /\".*\"/)) - { - $value =~ s/\"//g; - push @paramFileParamaters,$value; - } - # If the parameter is in the form -fm="fature db.xml" then read - # the parameter starting from opening quote till the closing quote. - elsif( ($value =~ /\"/) && $argWithQuotes) - { - $argWithQuotes .= $value; - $argWithQuotes =~ s/\"//g; - push @paramFileParamaters,$argWithQuotes; - $argWithQuotes=''; - } - else - { - $argWithQuotes .= $value; - } - } - } - - close FILE; - - if (!@paramFileParamaters) - { - print "Warning: No parameters specified in paramer-file \"$paramFile\".\n"; - return; - } - - my $paramFileFlag = 1; - - # Invoke subroutine "process_cmdline_arguments" to process the parameters read from - # the parameter file. - &process_cmdline_arguments($paramFileFlag, @paramFileParamaters); - -} - -# Processes the command line arguments passed to buildrom tool - -sub process_cmdline_arguments -{ - my %tmpBldRomOpts; - - my ($paramFileFlag, @argList); - - if (defined @_) - { - ($paramFileFlag, @argList) = @_; - } - else - { - @argList = @ARGV; - } - - if (!defined $paramFileFlag) - { - # Enforce Feature Manager if macro SYMBIAN_FEATURE_MANAGER is defined in the HRH file. - my @hrhMacros = &Variant_GetMacroList; - if (grep /^SYMBIAN_FEATURE_MANAGER\s*$/, @hrhMacros) - { - $enforceFeatureManager = 1; - } - - # Process the parameters of parameter-file if passed. - foreach my $arg (@argList) - { - if ($arg =~ /^-argfile=(.*)/) - { - ¶meterFileProcessor($1); - } - } - } - - foreach my $arg (@argList) - { - if ($arg =~ /^-argfile=(.*)/) - { - ¶meterFileProcessor($1) if (defined $paramFileFlag); - next; - } - if ($arg =~ /^-[DI]/) - { - $cppargs .= " $arg"; - #Set 'udeb' for debug option - if($arg =~ /^-D_FULL_DEBUG/) - { - $tmpBldRomOpts{"BUILD_DIR"} = "udeb"; - } - #Set specific platform supplied from the command option - elsif($arg =~ /^-D_PLAT=(.*)/) - { - $tmpBldRomOpts{"ABI_DIR"} = $1; - } - # Check for a Feature Variant - elsif ($arg =~ /^-DFEATUREVARIANT=(.*)/) - { - my $varname = $1; - - if ($varname =~ /^\.(.*)$/) - { - # for testing, locate the VAR file in the current directory - %featureVariant = featurevariantparser->GetVariant($1, "."); - } - else - { - %featureVariant = featurevariantparser->GetVariant($varname); - } - if (!$featureVariant{'VALID'}) - { - print "FEATUREVARIANT $varname is not VALID\n"; - $errors++; - } - if ($featureVariant{'VIRTUAL'}) - { - print "FEATUREVARIANT $varname is VIRTUAL\n"; - $errors++; - } - addDrivesToFeatureVariantPaths(); - } - next; - } - if ($arg =~ /^-o(.*)/i) - { - $opt_o = $1; - next; - } - if ($arg =~ /^-fastcompress$/i) - { - $opt_fastcompress = "-fastcompress"; - next; - } - if ($arg =~ /^-j(\d+)$/i) - { - $opt_jobs = "-j".$1; - next; - } - if ($arg =~ /^-v$/) - { - $opt_v =1; - next; - } - if ($arg =~ /^-s$/) - { - $strict = 1; - next; - } - if ($arg =~ /^-w$/) - { - $warnSelection = 1; - next; - } - if ($arg =~ /^-p$/) - { - $preserve = 1; - next; - } - if ($arg =~ /^-nospi$/) - { - $createspi=0; - $spiset=1; - next; - } - if ($arg =~ /^-spi$/) - { - $createspi=1; - $spiset=1; - next; - } - #Process External Tool - if ($arg =~/^-e(.*)/)#Match to get the tool perl module files - { - &externaltools::loadTools($1); - next; - } - #Process imagecontent file - if( $arg =~ /^-i(.*)/) - { -# Disabling -i option - print "Warning: Ignoring invalid Option $arg \n"; - next; - } - #Process feature manager database xml file - if($arg =~ /^-fm=(.*)/) - { - if (!$enforceFeatureManager) - { - print "Unknown arg: $arg\n"; - $errors++; - next; - } - $featureXml = $1; - $xmlrequired = 1; - $featuremanager = 1; - if ($featureXml =~ /^$/) - { - print "Error: No filename specified with \"-fm=\" option.\n"; - } - next; - } - #Process ROM image compression type if it's specified through command line option. - if($arg =~ /^-compress(.*)/) - { - if($1 eq '') - { - $opt_compression_type = ALLSECTIONS; - print "Whole ROM image will be compressed.\n"; - } - elsif($1 eq '=paged') - { - $opt_compression_type = PAGEDSECTION; - print "Paged section of the ROM image will be compressed.\n"; - } - elsif($1 eq '=unpaged') - { - $opt_compression_type = UNPAGEDSECTION; - print "Unpaged section of the ROM image will be compressed.\n"; - } - else - { - print "Unknown compression type: $1\n"; - $errors++; - } - next; - } - if ($arg =~ /^-nofm(=(.*))?$/) - { - if (!$enforceFeatureManager) - { - print "Unknown arg: $arg\n"; - $errors++; - next; - } - $noFeatureManager = 1; - #DEF125375 If caller is simply giving -nofm without any parameter, a warning message will be given. - if(!$2) - { - print "Warning: No filename specified with \"-nofm=\" option, feature data file might not be included.\n"; - } - else - { - $preBuiltFeaturesDataFile = $2; - } - next; - } - #Process feature registry database xml file - if($arg =~ /^-fr=(.*)/ || $arg =~ /^-f(.*)/) - { - if ($enforceFeatureManager) - { - print "Error: Option \"-f|-fr\" is no longer supported.\n"; - $errors++; - next; - } - $featureXml = $1; - $xmlrequired = 1; - if ($featureXml =~ /^$/) - { - print "Error: No filename specified with \"-f|-fr\" option.\n"; - } - next; - } - if ($arg =~ /^-spiplacement$/) - { - $spiplacement = 1; - next; - } - if ($arg =~ /^-noimage$/) - { - $noimage=1; - next; - } - if ($arg =~ /^-nosymbols$/) - { - $nosymbols=1; - next; - } - if ($arg =~ /^-geninc$/) - { - $geninc=1; - next; - } - if($arg =~ /^-gendep$/) - { - $gendep=1; - next; - } - if($arg =~/^-c(.*)/) - { - if($1 eq 'none' ) - { - $opt_compression = " -compressionmethod none"; - } - elsif($1 eq 'inflate' ) - { - $opt_compression = " -compressionmethod inflate"; - } - elsif($1 eq 'bytepair' ) - { - $opt_compression = " -compressionmethod bytepair"; - } - else - { - print "Unknown compression method: $1\n"; - $errors++; - } - next; - } - if( $arg =~ /^-loglevel\d+$/) - { - $logLevel= $arg; - next; - } - # get Z directory location if specified by the user. - # if yes, then extract directory location from the given array element. - if( $arg =~ /^-z=(.*)/ || $arg =~ /^-zdrivepath=(.*)/i ) - { - # check for white space in the specified folder path - # if "yes" then warn the user saying folder will be created under default location. - # else set the path specified by the user. - if(&datadriveimage::checkForWhiteSpace($1,"zdrive")) - { - next; - } - else - { - $ZDirloc = $1; - if( $ZDirloc !~ m/\\(\Z)/) - { - $ZDirloc .= "\\"; - } - if( $ZDirloc !~ m/:/) - { - print "drive letter not specified\n"; - $ZDirloc = &datadriveimage::setPath($ZDirloc); - } - print "Z Drive directory location = $ZDirloc\n"; - #set the location of Z Drive directory. - $ZDirloc .= "zdrive"; - } - next; - } - # get data directory location if specified by the user. - # if yes, then extract directory location from the given array element. - if( $arg =~ /^-d=(.*)/ || $arg =~ /^-datadrivepath=(.*)/i ) - { - # check for white space in the specified folder path - # if "yes" then warn the user saying folder will be created under default location. - # else set the path specified by the user. - if(&datadriveimage::checkForWhiteSpace($1,"datadrive")) - { - next; - } - else - { - $DataDriveDirloc = $1; - if( $DataDriveDirloc !~ m/\\(\Z)/) - { - $DataDriveDirloc .= "\\"; - } - if( $DataDriveDirloc !~ m/:/) - { - print "drive not specified\n"; - $DataDriveDirloc = &datadriveimage::setPath($DataDriveDirloc); - } - print "Data Drive directory location = $DataDriveDirloc\n"; - #set the location of Data Drive directory. - $DataDriveDirloc .= "datadrive"; - } - next; - } - # get Z dive image if specified by the user. - if( $arg =~ /^-zdriveimage=(.*)/i ) - { - my $imageName = $1; - if( $imageName =~ m/\,/) - { - @zdriveImageName = split(/\,/,$imageName); - } - else - { - push(@zdriveImageName,$imageName); - } - $opt_zimage = 1; - next; - } - # get command line arguments which needs to be passed to INTERPRETSIS, if specified by the user. - if( $arg =~ /^-argforinterpretsis=(.*)/i ) - { - my $interpretsisOpt = $1; - if( $interpretsisOpt =~ m/\,/) - { - @interpretsisOptList = split(/\,/,$interpretsisOpt); - } - else - { - push(@interpretsisOptList,$interpretsisOpt); - } - next; - } - if ( $arg =~ /^-k$/i || $arg =~ /^-keepgoing$/i ) - { - $opt_k = 1; - next; - } - if ( $arg =~ /^-r$/i || $arg =~ /^-retainfolder$/i ) - { - $opt_r = 1; - next; - } - if ( $arg =~ /^-pfile=(.*)/i ) - { - $paraFile = $1; - next; - } - if ( $arg =~ /^-l=(.*)/i || $arg =~ /^-logimageentry=(.*)/i ) - { - if( $1 =~/\\/ || $1 =~ m/:/) - { - print "* Warning: Invalid log file extension try filename.txt\n"; - next; - } - else - { - $opt_logFile = 1; - $imageEntryLogFile = $1; - } - next; - } - if ( $arg =~ /^-lowmem/i ) - { - $lowMem = $arg; - next; - } - if ($arg =~ /^-/) - { - print "Unknown arg: $arg\n"; - $errors++; - next; - } - # It's an OBY file - next if (match_obyfile($arg)); - next if (match_obyfile("$arg.oby")); - - print "Cannot find oby file: $arg\n"; - $errors++; - } - - if (defined $paramFileFlag) - { - return; - } - - if (@obyfiles<1) - { - print "Missing obyfile argument\n"; - $errors++; - } - - if ($errors) - { - print_usage(); - exit 1; - } - - if ($noFeatureManager && $featuremanager) - { - print "Warning: Ignoring \"-nofm\" option, as both \"-nofm\" and \"-fm\" options are provided.\n"; - $noFeatureManager = 0; - } - - # Adding variant specific macros by including a HRH file - # (only required if no Feature Variant is used) - if (!$featureVariant{'VALID'}) - { - my $variantMacroHRHFile = Variant_GetMacroHRHFile(); - if($variantMacroHRHFile){ - - my $variantFilePath = Path_Split('Path',$variantMacroHRHFile); - $cppargs .= " -I \"" . &Path_RltToWork($variantFilePath) . "\" -include \"" . &Path_RltToWork($variantMacroHRHFile) . "\""; - } - } - # load the required modules if xml is required - if ($xmlrequired == 1) - { - my $epocToolsPath = $ENV{EPOCROOT}."epoc32\\tools\\"; - Load_SetModulePath($epocToolsPath); - if (defined ($featureXml)) - { - load_featuresutil(); - } - - if ($image_content) - { - &Load_ModuleL("ImageContentHandler"); - # some variables for ImageContentHandler may have been setup - my ($key, $value); - &ImageContentHandler::SetBldRomOpts; # Defaults to ARMV5 platform - while (($key,$value) = each %tmpBldRomOpts) - { - &ImageContentHandler::SetBldRomOpts($key, $value); - } - } - - } -} - -#---------------------------------------------------------------------------------- -# Preprocessing phase -# -# Concatentate the specified .oby files and pass them through cpp -# to get the raw ROM specification in tmp1.oby - -sub preprocessing_phase -{ - unlink "tmp1.oby"; - -# Macro "ROM_FEATURE_MANAGEMENT" is defined when "-f|fr" or "-fm" is used - if (defined ($featureXml)) - { - $cppargs .= " -DROM_FEATURE_MANAGEMENT "; - } - - # add pre-include file and include directories for feature variants - if ($featureVariant{'VALID'}) - { - $cppargs .= " -I."; - my $incRef = $featureVariant{'ROM_INCLUDES'}; - if ($incRef) - { - foreach (@$incRef) - { - $cppargs .= " -I \"$_\""; - } - } - my $HRH = $featureVariant{'VARIANT_HRH'}; - if ($HRH) - { - $cppargs .= " -include \"$HRH\""; - } - } - else - { - # no feature variant so use the standard includes - $cppargs .= " -I. -I$rominclude"; - } - - print "* cpp -o tmp1.oby $cppargs\n" if ($opt_v); - - $errors = 0; - open CPP, "| cpp -o tmp1.oby $cppargs" or die "* Can't execute cpp"; - foreach my $arg (@obyfiles) - { - print CPP "\n#line 1 \"$arg\"\n"; - - open OBY, $arg or die "* Can't open $arg"; - print "* reading $arg\n" if ($opt_v); - while ($line=) - { - print CPP $line; - } - close OBY; - } - close CPP; - my $cpp_status = $?; - die "* cpp failed\n" if ($cpp_status != 0 || !-f "tmp1.oby"); - - my $temp1OBYFile = "tmp1.oby"; - if( defined ($image_content)) - { - #Read the OBY file that was generated by the pre-processor - &ReadPreprocessedFile($temp1OBYFile); - -# Check if the static dependencies of the OBY binaries are resolved. - &ImageContentHandler::UpdateObyBinaryStaticDep(); - - #Now append the files collected from cdfs. - &ImageContentHandler::GenObyFile($temp1OBYFile); - } - - # Setup default rom configuration - $romimage[0] = {xip=>1, compress=>0, extension=>0, composite=>"none",uncompress=>0 }; -} - -sub ReadPreprocessedFile -{ -# Read the OBY file that was generated by the pre-processor. This OBY is a conglomeration of all the OBYs -# passed directly to buildrom and/or the ones passed through Image Content XML. -# It marks the binaries coming from OBY. This is required to be able to point out the binaries that are -# mentioned neither in the OBY nor in the CDF. Such binaries are arrived at through static dependencies -# and need to be included in ROM. - - my $temp1OBYFile = shift; - my $tmpline; - my $srcFileName; - my $srcFilePath; - my $dstFileName; - my $dstFilePath; - open (OBYFH, "$temp1OBYFile") or die("* Can't open $temp1OBYFile\n"); - while($tmpline =) { - if ($tmpline=~/(\S+)\s*=\s*(\S+)\s+(\S+)/) {#Get the first parameter (source File path) from oby line - $srcFilePath = $2; - $dstFilePath = $3; - - if ($srcFilePath=~/.*\\(\S+)/) { - $srcFileName = $1; - } - if ($dstFilePath=~/.*\\(\S+)/) { - $dstFileName = $1; - } - my $binaryInfoRef = &cdfparser::GetBinaryInfo($dstFileName); - - if(defined($binaryInfoRef)) - { - #Found in CDF file - if($binaryInfoRef->{IsFoundInCDF}) - { - print "Warning: File $srcFileName mentioned in OBY as well as CDF file\n"; - } - } - else - { - #Found in OBY file - &ImageContentHandler::AddBinaryFromOby($dstFileName, $srcFilePath); - } - } - } - close OBYFH; -} - - -#---------------------------------------------------------------------------------- -# Substitution phase -# -# Handle the "define XXX YYY" lines, perform the substitutions. -# Print out any ECHO lines or ERROR lines. -# - -# Predefined substitutions: -# TODAY means todays' date -# RIGHT_NOW means the exact time -# EPOCROOT taken from the environment - -sub substitution_phase -{ - { - my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time); - $substitutionData{"TODAY"} = sprintf("%02d/%02d/%04d", $mday, $mon+1, $year+1900); - $substitutionData{"RIGHT_NOW"} = sprintf("%02d/%02d/%04d %02d:%02d:%02d", $mday, $mon+1, $year+1900, $hour, $min, $sec); - $substitutionData{"EPOCROOT"} = $epocroot; - @substitutionOrder = ("TODAY", "RIGHT_NOW", "EPOCROOT"); - } - - - open TMP1, "tmp1.oby" or die("* Can't open tmp1.oby\n"); - while ($line=) - { - - if(($line =~ /^\s*romsize\s*=/i) || ( $line=~ /^\s*rom_image/i) || ($line =~ /^\s*data_image/i)) - { - $onlysmrimage = 0; - last; - } - } - close TMP1; - if ($enforceFeatureManager && (!$featuremanager) && (!$noFeatureManager) ) - { - my $defaultFeatureDbFlag = 0; - open TMP1, "tmp1.oby" or die("* Can't open tmp1.oby\n"); - while ($line=) - { - if ($line=~/^\s*defaultfeaturedb\s*=?\s*(\S+)/i) - { - # Get the default value for featuredatabasefile - - $featureXml = "$epocroot$1"; - $featuremanager = 1; - $defaultFeatureDbFlag = 1; - load_featuresutil(); - last; - } - } - close TMP1; - - if(!$defaultFeatureDbFlag && !$onlysmrimage) - { - print "Error: Neither option \"-fm|-nofm\" nor default value for featuredatabase file is provided.\n"; - exit(1); - } - } - - open TMP1, "tmp1.oby" or die("* Can't open tmp1.oby\n"); - while ($line=) - { - track_source($line); - # - # Recognise keywords in lines that we process before substitution - # - # # lineno "file" flagno - # DEFINE name replacement-with-0-spaces - # - if($line=~/^\s*$/) - { - next; - } - if ($line=~/^# (\d+) "(.*)" (\d+)/) - { - push @obydata, $line; - next; - } - - if ($line=~/^\s*defaultfeaturedb\s*=?\s*(\S+)/i) - { - push @obydata, "REM $line"; - next; - } - #process the External tool invocation using IBY file - if ($line=~/externaltool=(.*),?/i) - { - &externaltools::loadTools($1); - next; - } - - #Process the patch statement - if($line =~ /^\s*patchdata\s*(.*)/i) - { - $patchDataStmtFlag = 1; - my $new_line = $1; - # syntax " addr " - # If the line matches with above syntax, just add the line into oby file. - if($new_line !~ /^\s*(\S+)\s+addr\s+(\S+)\s+(\S+)\s+(\S+)\s*$/i) - { - if(AddDllDataInfo($new_line)) - { - $line = "REM $line"; - } - } - } - - if($line =~ /^\s*FEATURE\s*(.*)/i || $line =~ /^\s*EXCLUDE_FEATURE\s*(.*)/i) - { - # Process the feature keywords only when "-f|fr" or "-fm" is passed to buildrom - if(defined ($featureXml)) - { - push @obydata, "$line"; - } - else - { - push @obydata, "REM handled $line"; - } - next; - } - - if ($line=~/^\s*DEFINE\s+(\w+)\s+(\S+)/i) - { - my $key=$1; - my $value=$2; - foreach my $wordToSubstitute (@substitutionOrder) - { - my $whatToSubstituteItWith=$substitutionData{$wordToSubstitute}; - $value=~s/$wordToSubstitute/$whatToSubstituteItWith/g; - } - $value=~s/##//g; - if (defined $substitutionData{$key}) - { - # If the key is redefined, apply it at the new position rather - # than the old one. - push @obydata, "REM redefined $key as $value\n";# Leave a record of the definition - @substitutionOrder = grep !/^$key$/, @substitutionOrder; - } - else - { - push @obydata, "REM defined $key as $value\n"; # Leave a record of the definition - } - $substitutionData{$key}=$value; - - foreach my $wordToSubstitute (@substitutionOrder) - { - if ($key =~ /$wordToSubstitute/) - { - print_source_error("Warning: $key is masked by earlier definition of $wordToSubstitute"); - } - } - - push @substitutionOrder, $key; - next; - } - # - # Do the substitutions in strict order of definition, - # then eliminate any old-fashioned ## things which may be left - # - foreach my $wordToSubstitute (@substitutionOrder) - { - my $whatToSubstituteItWith=$substitutionData{$wordToSubstitute}; - $line=~s/$wordToSubstitute/$whatToSubstituteItWith/g; - } - $line=~s/##//g; - # - # Recognise keywords in lines that we process after substitution - # - # ECHO anything at all - # WARNING anything at all - # ERROR anything at all - # LANGUAGE_CODE nnn - # DEFAULT_LANGUAGE nnn - # ABI_DOWNGRADE from to - # ROMBUILD_OPTION command-line-option - # ROM_IMAGE - # PlatSecEnforceSysBin on|off - # ENABLE_SPI/DISABLE_SPI - # - if ($line=~/^\s*ECHO\s+(.*?)\s*$/i) - { - print "$1\n"; - push @obydata, "REM handled $line"; - next; - } - if ($line=~/^\s*(ERROR|WARNING)\s+(.*?)\s*$/i) - { - print_source_error("$1 $2"); - $errors++ if ($1 =~ /ERROR/i); - push @obydata, "REM handled $line"; - next; - } - if ($line=~/^\s*(PlatSecEnforceSysBin)\s+(\S+)\s*$/i) - { - $enforceSysBin = ($2 =~ /ON/i); - push @obydata, $line; - next; - } - if ($line=~/^\s*LANGUAGE_CODE\s+(\S+)\s*/i) - { - my $code = $1; - if ($code !~ /^\d\d+$/) - { - print_source_error("bad language code $code"); - $errors++; - } - else - { - $languageCodes{$code} = 1; - } - push @obydata, "REM handled $line"; - next; - } - if ($line=~/^\s*DEFAULT_LANGUAGE\s+(\S+)\s*/i) - { - my $code = $1; - if ($code !~ /^\d\d+$/) - { - print_source_error("bad default language code $code"); - $errors++; - } - else - { - $defaultLanguageCode = $code; - } - push @obydata, "REM handled $line"; - next; - } - - if ($line=~/^\s*ABI_DOWNGRADE\s*/i) - { - if ($line =~ /\s(.+)\s*->\s*(.+)\s*$/) - { - $abiDowngrade = "$1 $2"; - } - else - { - print_source_error("bad ABI downgrade : $line"); - $errors++; - } - push @obydata, "REM handled $line"; - next; - } - if ($line=~/^\s*BINARY_SELECTION_ORDER\s*/i) - { - if ($line =~ /\s([^,]+)\s*,\s*(.+)\s*$/) - { - $binarySelectionOrderFlag = 1; - $firstDIR = $1; - # remove whitespaces - $firstDIR = trim($firstDIR); - @binarySelectionOrder = split(',', $2); - @binarySelectionOrder = trim(@binarySelectionOrder); - - } - else - { - print_source_error("bad order specified: $line"); - $errors++; - } - push @obydata, "REM handled $line"; - next; - } - - if ($line=~/^\s*ROMBUILD_OPTION\s+(\S+)\s*/i) - { - $rombuildOptions{$1} = 1; - push @obydata, "REM handled $line"; - next; - } - - if ($line=~/^\s*enable_spi\s*$/i) - { - if(!($spiset)) { - $createspi=1; - } - push @obydata, "REM handled $line"; - next; - } - - if ($line=~/^\s*disable_spi\s*/i) - { - if(!($spiset)) { - $createspi=0; - } - push @obydata, "REM handled $line"; - next; - } - - if ($line=~/^\s*DATA_IMAGE\s+/i) - { - if ($line =~ /\s+(\d+)\s+(\S+)\s+/i) - { - my $datadriveidx = $1; - my $datadriveimagename = $2; - # have a count on number of data drive images that needs to be created - print "data drive partion name = $datadriveimagename\n " if($opt_v); - my $dataimagesize = 0; - if ($line =~ /\s+size=(\S+)\s*/i) - { - $dataimagesize=$1; - } - my $fstype = ""; - my $compress=0; - my $uncompress=0; - if ($line =~ /\s+compress\s*/i) - { - $compress=1; - } - elsif($line =~ /\s+uncompress\s*/i) - { - $uncompress=1; - } - if ($line =~ /\s+fat16\s*/i) - { - $fstype = "fat16"; - } - if ($line =~ /\s+fat32\s*/i) - { - $fstype = "fat32"; - } - - $datadriveimage[$datadriveidx] = {name=>$datadriveimagename, size=>$dataimagesize, compress=>$compress, uncompress=>$uncompress, fstype=>$fstype}; - print "DATA_IMAGE[$datadriveidx] $datadriveimage[$datadriveidx]{name} size=$datadriveimage[$datadriveidx]{size} compress=$compress uncompress=$uncompress fstype=$fstype\n" if ($opt_v); - } - else - { - print_source_error("bad DATA_IMAGE specification : $line"); - $errors++; - } - push @obydata, "REM handled $line"; - next; - } - if ($line=~/^\s*ROM_IMAGE\s+/i) - { - if ($line =~ /\s+(\d+)\s+(\S+)\s+/i) - { - my $romidx=$1; - my $rompartitionname=$2; - my $rompartitionsize=0; - if ($line =~ /\s+size=(\S+)\s*/i) - { $rompartitionsize=$1; } - my $xip=1; - my $compress=0; - my $uncompress=0; - my $extend=0; - my $composite="none"; - if ($line =~ /\s+non-xip\s*/i) - { $xip=0; } - if ($line =~ /\s+compress\s*/i) - { $compress=1; } - elsif($line =~ /\s+uncompress\s*/i) - { $uncompress=1;} # This option is passed to rofsbuild. For rombuild, not saying --compress means to uncompress - if ($line =~ /\s+extension\s*/i) - { $extend=1; } - if ($line =~ /\s+composite_primary\s*/i) # added to support new composite_primary keyword in obey files - { if (!($extend)) - { $composite="composite_primary"; } - else - { print "Error: composite_primary keyword must be used with a core image\n"; } - } - if ($line =~ /\s+composite_secondary\s*/i) # added to support new composite_secondary keyword in obey files - { if (!($extend)) - { $composite="composite_secondary"; } - else - { print "Error: composite_secondary keyword must be used with core image\n"; } - } - - # Compress and Uncompress are 2 different options and - # not mentioning one of them doesn't necessarily mean the other. - - $romimage[$romidx] = {name=>$rompartitionname, size=>$rompartitionsize, xip=>$xip, compress=>$compress, extension=>$extend, composite=>$composite, uncompress=>$uncompress}; - print "ROM_IMAGE[$romidx] $romimage[$romidx]{name} size=$romimage[$romidx]{size} xip=$xip compress=$compress extension=$extend composite=$composite uncompress=$uncompress \n" if ($opt_v); - check_romimage($romidx, $line); - } - else - { - print_source_error("bad ROM_IMAGE specification : $line"); - $errors++; - } - push @obydata, "REM handled $line"; - next; - } - - push @obydata, $line; - } - - close TMP1; - exit(1) if ($errors); - - dump_obydata("tmp2.oby", "result of substitution phase") if ($opt_v); -} - -sub check_romimage -{ - my ($idx, $line) = @_; - if ($idx gt 7) - { - print_source_error("too many roms : $line"); - $errors++; - } - if ($romimage[$idx]{xip} eq 0) - { - if ($romimage[$idx]{size} eq 0) - { - print_source_error("must specify a size for non-xip ROM : $line"); - $errors++; - } - } - if ($romimage[$idx]{extension} ne 0) - { - if ($romimage[$idx-1]{extension} ne 0) - { - print_source_error("cannot extend ROM image multiple times : $line"); - $errors++; - } - } -} - -sub dump_obydata -{ - my ($dumpfile, $comment) = @_; - unlink($dumpfile); - open DUMPFILE, ">$dumpfile" or die("* Can't create $dumpfile\n"); - print "* Writing $dumpfile - $comment\n"; - my $line; - foreach $line (@obydata) - { - print DUMPFILE $line; - } - close DUMPFILE; -} - -sub track_source -{ - my ($line) = @_; - if ($line=~/^# (\d+) "(.*)"/) - { - $sourceline=$1-1; - $sourcefile=$2; - $sourcefile=~ s/\//\\/g; - $sourcefile=~ s/\\\\/\\/g; - return; - } - $sourceline++; -} - -sub print_source_error -{ - my ($message) = @_; - print "$sourcefile($sourceline): $message\n"; -} - -sub reassert_sourceline -{ - my ($offset) = @_; - return sprintf "# %d \"$sourcefile\" \n", $sourceline+1+$offset; -} - - -#---------------------------------------------------------------------------------- -# Reorganisation phase -# -# Group lines beginning with "rom_image[]" and deposit them in the appropriate -# order. Truncate the description at the "stop" line, if there is one. - -sub reorganize_phase -{ - - undef @newobydata; - my @section2; - my @part3; - my @part4; - my @part5; - my @part6; - my @part7; - my @part8; - my @partitions = ( \@newobydata, \@section2, \@part3, \@part4, \@part5, \@part6, \@part7, \@part8 ); - my @currentpartition; # partition stack - - my @processedImageIdx; # list of proccesed data drive image index. - my $dataDriveStartRegion = 0; - my $dataDriveEndRegion = 0; - my $dataDriveIdx; - my @datapartition; - my @linesArray; - my $curlyBraceShouldFollow; - - my $collect_section2=1; - my $smrImageStartRegion = 0; - my $smrImageEndRegion = 0; - my $smrImageIndex = 0; - - foreach $line (@obydata) - { - track_source($line); - if ($line=~/^\s*stop/i) - { - last; - } - if ($line =~ /^\s*ROM_IMAGE\[(\S+)\]\s+\{(.*)$/i) - { - # ROM_IMAGE[n] { - my $idx=$1; - my $partition=$partitions[$idx]; - push @currentpartition, $partition; - $line="REM handled $line"; - } - elsif( ($line =~ /^\s*DATA_IMAGE\[(\S+)\]\s*$/i) || ($line =~ /^\s*DATA_IMAGE\[(\S+)\]\s*\{\s*$/i)) - { - # DATA_IMAGE[n] or DATA_IMAGE[n] { is specified. - # get the index. - $dataDriveIdx=$1; - if($line !~ /\s*\{\s*/i) - { - $curlyBraceShouldFollow = 1; - } - # make a check if dataDriveIdx exists in the processedImageIdx array. - # if no, then push the dataDriveIdx on the processedImageIdx array. - # if yes,then dont execute the loop. - if(&datadriveimage::checkInArray(\@processedImageIdx,$dataDriveIdx)) - { - # push the index on to the array. - push(@processedImageIdx,$dataDriveIdx); - # increment the image count. - ++$dataImageCount; - } - - $dataIndexHash{($dataImageCount-1)} = $dataDriveIdx; - # set start of the image section. - $dataDriveStartRegion = 1; - # set end of image section to zero. - $dataDriveEndRegion = 0; - push (@linesArray,"\n"); - $line="REM handled $line"; - } - elsif( $line =~ /^\s*SMR_IMAGE\s*\{\s*$/i) - { - $smrImageStartRegion = 1; - $smrImageEndRegion = 0; - $needSmrImage = 1; - push (@linesArray, "\n"); - $line="REM handled $line"; - } - elsif((defined $curlyBraceShouldFollow) && ($line !~ /^\s*$/i)) - { - undef $curlyBraceShouldFollow; - if($line !~ /^\s*\{\s*/i) - { - print "Error: Symbol '{' not followed after the keyword DATA_IMAGE\[".$dataDriveIdx."\]\n"; - $errors++; - } - next; - } - # data drive specific keywords. - elsif( $line =~/^\s*dataimagename\s*\=\s*(\S+)/i ) - { - # set the name for the image, if image name is specified using driveimagename keyword. - $datadriveimage[$dataDriveIdx]{name} = $1 if($dataDriveStartRegion && !$dataDriveEndRegion); - print"datadriveimagename = $datadriveimage[$dataDriveIdx]{name}\n" if($dataDriveStartRegion && !$dataDriveEndRegion && $opt_v); - # skip the line. - next; - } - elsif( $line =~/^\s*dataimagesize\s*\=\s*(\S+)/i ) - { - # set the size for the image, if image size is specified using driveimagesize keyword. - $datadriveimage[$dataDriveIdx]{size} = $1 if($dataDriveStartRegion && !$dataDriveEndRegion); - print"datadriveimagesize = $datadriveimage[$dataDriveIdx]{size}\n" if($dataDriveStartRegion && !$dataDriveEndRegion && $opt_v); - # skip the line. - next; - } - elsif( $line =~/^\s*dataimagefilesystem\s*\=\s*(\S+)/i ) - { - # set the file system type for the image, if image file system is specified using dataimagefilesystem keyword. - $datadriveimage[$dataDriveIdx]{fstype} = $1 if($dataDriveStartRegion && !$dataDriveEndRegion); - print"datadriveimagefstype = $datadriveimage[$dataDriveIdx]{fstype}\n" if($dataDriveStartRegion && !$dataDriveEndRegion && $opt_v); - # skip the line. - next; - } - elsif( $line =~/^\s*compress/i ) - { - # Compresses the resulting data drive image using the Deflate, Huffman+LZ77 algorithm. - if($dataDriveStartRegion && !$dataDriveEndRegion) - { - $datadriveimage[$dataDriveIdx]{compress} = 1; - $datadriveimage[$dataDriveIdx]{uncompress} = 0; - print"datadriveimage[$dataDriveIdx] compress = $datadriveimage[$dataDriveIdx]{compress}\n" if($opt_v); - } - } - elsif( $line =~/^\s*uncompress/i ) - { - # Uncompresses the resulting data drive image. - if($dataDriveStartRegion && !$dataDriveEndRegion) - { - $datadriveimage[$dataDriveIdx]{uncompress} = 1; - $datadriveimage[$dataDriveIdx]{compress} = 0; - print"datadriveimage[$dataDriveIdx] uncompress = $datadriveimage[$dataDriveIdx]{uncompress}\n" if($opt_v); - } - } - elsif ($line =~ /^\s*ROM_IMAGE\[(\S+)\](.*)$/i) - { - # ROM_IMAGE[n] file=... - my $origline=$line; - $line="$2\n"; # remove the ROM_IMAGE[.] keyword - my $idx=$1; - my $partition=$partitions[$idx]; - push @$partition, reassert_sourceline(-1); - push @$partition, $line; - $line="REM handled $origline"; - } - elsif ($line =~ /^\s*DATA_IMAGE\[(\S+)\](.*)$/i) - { - # DATA_IMAGE[n] file=... - my $origline=$line; - # remove the DATA_IMAGE[.] keyword - $line="$2\n"; - # get the index value - my $idx=$1; - # iterate through the hash to get corresponding - # key from the value(i.e idx) - while (my($key, $value) = each(%dataIndexHash)) - { - if ($value eq $idx ) - { - $idx = $key; - } - } - push @{$datapartition[$idx]}, reassert_sourceline(-1); - push @{$datapartition[$idx]}, $line; - $line="REM handled $origline"; - } - elsif ($line =~ /^\s*\}.*$/i) - { - if($dataDriveStartRegion) - { - # since "}" brace is encountered - # reset the start of DATA_IMAGE to zero. - $dataDriveStartRegion = 0; - # mark the the end of the DATA_IMAGE. - $dataDriveEndRegion = 1; - if(!$datadriveimage[$dataDriveIdx]{name}) - { - # image name is not defined, define a default name. - $datadriveimage[$dataDriveIdx]{name} = "dataImage".$dataDriveIdx; - } - if(!$datadriveimage[$dataDriveIdx]{fstype}) - { - # image name is not defined, define a default name. - $datadriveimage[$dataDriveIdx]{fstype} = "fat16"; - } - foreach my $file (@linesArray) - { - push @{$datapartition[($dataImageCount-1)]},$file; - } - ## if end of the DATA_IMAGE is true, - ## make room for next DATA_IMAGE if any. - undef(@linesArray); - #un define $dataDriveIdx; - undef($dataDriveIdx); - } - elsif($smrImageStartRegion) - { - $smrImageStartRegion = 0; - $smrImageEndRegion = 1; - foreach my $file (@linesArray) - { - push @{$smrPartitions{$smrImageIndex}}, $file; - } - undef(@linesArray); - $smrImageIndex++; - } - elsif (scalar @currentpartition > 0) - { - pop @currentpartition; - } - else - { - print "WARNING: closing '}' found with no matching 'ROM_IMAGE[]/DATA_IMAGE[] {'\n"; - } - $line="REM handled $line"; - } - elsif ($line=~/^\s*section2(.*)$/i) - { - my $origline=$line; - $line="$1\n"; # remove the section2 keyword - if ($collect_section2) - { - push @section2, reassert_sourceline(-1); - push @section2, $line; - $line="REM handled $origline"; - } - } - elsif ($line=~/^\s*section/i) - { - push @newobydata, $line; # insert the section statement - if (@section2 != 0) - { - push @newobydata, "REM accumulated section2 lines\n"; - } - foreach $line (@section2) - { - push @newobydata, $line; # insert accumulated section2 lines - } - $collect_section2=0; - $line = reassert_sourceline(); - } - - elsif ($line=~/^\s*extensionrom/i) - { - # end of ROM description, so deposit accumulated lines - if (@section2 != 0) - { - push @newobydata, "REM accumulated section2 lines\n"; - } - foreach $line (@section2) - { - push @newobydata, $line; # insert accumulated section2 lines - } - $collect_section2=0; - push @newobydata, reassert_sourceline(); - } - - elsif ( scalar(@linesArray) ) - { - if($dataDriveStartRegion && !$dataDriveEndRegion) - { - my $modifiedLine = $line; - push @linesArray, $modifiedLine; - $line = "REM handled $line"; - } - elsif($smrImageStartRegion && !$smrImageEndRegion) - { - if($line =~ /^\s*IMAGENAME\s*=\s*(\S+)/i) - { - my $smrimagename = $1; - $smrimagename =~s/(\.img)//i; - if(exists($smrNameInfo{$smrimagename})) - { - $smrNameInfo{$smrimagename}++; - } - else - { - $smrNameInfo{$smrimagename} = 1; - } - $line =~s/(\.img)//i; - } - push @linesArray, $line; - $line = "REM handled $line"; - } - } - elsif (scalar @currentpartition) - { - my $modifiedLine = $line; - if ($line =~ /^\s*SPI_POSITION/i) - { - if(!($createspi && $spiplacement)) - { - # comment the line if the spi placement flag is not enabled or if the spi creation is not enabled. - $modifiedLine = "REM SPI creation/placement flag not enabled. Ignoring SPI_POSITION\n"; - print ("Warning: SPI creation/placement flag not enabled. Ignoring SPI_POSITION\n" ) if ($opt_v); - } - } - # a partition is specified - # push this line into the currently selected partition - my $partition=@currentpartition[-1]; - push @$partition, $modifiedLine; - $line="REM handled $line"; - } - elsif ($line =~ /^\s*SPI_POSITION/i) - { - if(!($createspi && $spiplacement)) - { - # comment the line if the spi placement flag is not enabled or if the spi creation is not enabled. - $line = "REM SPI creation/placement flag not enabled. Ignoring SPI_POSITION\n"; - print ("Warning: SPI creation/placement flag not enabled. Ignoring SPI_POSITION\n" ) if ($opt_v); - } - } - push @newobydata, $line; - } - - # output the grouped data - my $partitionidx=2; - if ($collect_section2) - { $partitionidx=1; } # output old "section2" if not done already - for (; $partitionidx<8; $partitionidx++) - { - my $partition=$partitions[$partitionidx]; - if (@$partition != 0) - { - push @newobydata, "REM ROM_IMAGE[$partitionidx]\n"; - foreach $line (@$partition) - { - push @newobydata, $line; # insert accumulated section2 lines - } - } - } - - for ( my $datapartitionidx=0; $datapartitionidx < $dataImageCount; $datapartitionidx++ ) - { - if( defined( @{ $datapartition[$datapartitionidx] } ) ) - { - push @newobydata, "REM DATA_IMAGE[$dataIndexHash{$datapartitionidx}]\n" ; - foreach my $file (@{$datapartition[$datapartitionidx]}) - { - push @newobydata, $file; - } - } - } - - - foreach my $imageIndex (keys(%smrPartitions)) - { - my $imagename; - my @obeyfile; - - foreach (@{$smrPartitions{$imageIndex}}) - { - if(/^\s*imagename\s*=\s*(\S+)/i) - { - $imagename = $1; - } - push @obeyfile, $_; - } - if($smrNameInfo{$imagename} == 1) - { - push @obeyFileList, $imagename; - push @newobydata, "REM SMR_IMAGE \n"; - push @newobydata, @obeyfile; - } - if(! defined($imagename)) - { - $smrNoImageName = 1; - } - undef $imagename; - undef @obeyfile; - } - - @obydata = @newobydata; - exit(1) if ($errors); - dump_obydata("tmp3.oby", "result of reorganisation phase") if ($opt_v); -} - - -#---------------------------------------------------------------------------------- -# Plugin phase -# -# Process any plugin annotation lines -# Note: This expands resource lines to include MULTI_LINGUIFY so must be done before -# the Multilinguify phase - -# hash of SPI file target directories is located near the start of this file, before sub match_obyfile - -sub plugin_phase -{ - undef @newobydata; - foreach $line (@obydata) - { - track_source($line); - if ($line =~ /^\s*REM/i) - { - # ignore REM statements, to avoid processing "REM ECOM_PLUGIN(xxx,yyy)" - } - elsif(plugin_match($line)) { - $line = reassert_sourceline(); - } - push @newobydata, $line; - } - - @obydata = @newobydata; - dump_obydata("tmp4.oby", "result of Plugin stage") if ($opt_v); -} - -sub plugin_match () -{ - my ($line) = @_; - foreach my $plugintype (keys(%plugintypes)) { - if ($line =~ m/^.*__$plugintype\_PLUGIN\(\s*(\S+)\s*,\s*(\S+)\s*,\s*(\S+)\s*,\s*(\S+)\s*,\s*(\S+)\s*,\s*(\S+)\s*\)/i) - # ___PLUGIN(emulator directory, file rom dir, dataz_, resource rom dir, filename, resource filename) - { - my $emulatorDir=$1; - my $fileRomDir=$2; - my $dataz_= $3; - my $resourceDir=$4; - my $pluginFileName=$5; - my $pluginResourceName=$6; - my $spidatahide = 0; - my $paged_data = ""; - - if ($line =~ m/paged\s*$/i) - { - $line =~ m/\s+(\S+)\s*$/; - $paged_data = $1; - } - - if ($line =~ m/^\s*(_hide)/i ) - { - $spidatahide = 1; - } - - # for resource files strip the .rsc or .dll from the end (will be .dll where we use - # SYMBIAN_SECURE_ECOM and are building resources to the same name as ecom plugin dlls) - - if ($pluginResourceName =~ m/^(.+)\./) - { - $pluginResourceName = $1; - } - else - { - print_source_error("Invalid Resource name: $pluginResourceName in " . $plugintype . "_PLUGIN :$line"); - #treat as error if strict option selected; - $errors++ if ($strict); - } - - if ($spidatahide) - { - push @newobydata, "hide=$fileRomDir\\$pluginFileName\n"; - } - else - { - push @newobydata, "file=$emulatorDir\\$pluginFileName $fileRomDir\\$pluginFileName $paged_data\n"; - } - - if($createspi) { - if ($spidatahide) - { - push @newobydata, "spidatahide=MULTI_LINGUIFY(RSC $dataz_\\$resourceDir\\$pluginResourceName $resourceDir\\$pluginResourceName) " . lc($plugintype) . "\.spi " . $plugintypes{$plugintype} . "\n"; - } - else - { - push @newobydata, "spidata=MULTI_LINGUIFY(RSC $dataz_\\$resourceDir\\$pluginResourceName $resourceDir\\$pluginResourceName) " . lc($plugintype) . "\.spi " . $plugintypes{$plugintype} . "\n"; - } - } else { - if ($spidatahide) - { - push @newobydata, "hide=MULTI_LINGUIFY(RSC $dataz_\\$resourceDir\\$pluginResourceName $resourceDir\\$pluginResourceName)\n"; - } - else - { - push @newobydata, "data=MULTI_LINGUIFY(RSC $dataz_\\$resourceDir\\$pluginResourceName $resourceDir\\$pluginResourceName)\n"; - } - } - return 1; #successful match - } - } -} - - -#---------------------------------------------------------------------------------- -# Multilinguify phase -# -# Process the MULTILINGUIFY() lines - -sub multlinguify_phase -{ - if ((scalar keys %languageCodes) == 0) - { - print "* No language codes specified, defaulting to 01\n"; - $defaultLanguageCode = "01"; - } - $languageCodes{$defaultLanguageCode} = 1; - - undef @newobydata; - foreach $line (@obydata) - { - track_source($line); - if ($line =~ /^\s*REM/i) - { - # ignore REM statements, to avoid processing "REM data=xxx yyy" - } - elsif ($line=~/^(.*?)\bMULTI_LINGUIFY\s*\(\s*(\S+)\s+(\S+)\s+(\S+)\s*\)(.*)$/i) - { - my $initialStuff=$1; - my $defaultFileNameExtension=$2; - my $sourceFileNameWithoutExtension=$3; - my $targetFileNameWithoutExtension=$4; - my $finalStuff=$5; - my $spidataflag = 0; - my $spidatahide = 0; - my $datahide = 0; - - if ($initialStuff=~/\w$/) - { - $initialStuff.=" "; - } - if ($finalStuff=~/^\w/) - { - $finalStuff=" ".$finalStuff; - } - if ($initialStuff =~ /^\s*spidata/i) - { - $spidataflag = 1; - } - if ($initialStuff =~ /^\s*spidatahide/i) - { - $spidataflag = 1; - $spidatahide = 1; - } - if ($initialStuff =~ /^\s*hide/i) - { - $datahide = 1; - } - - -# ecom.spi should contain the .RSC files - if ($spidataflag) - { - my $sourceFileNameExtension = $defaultFileNameExtension; - my $targetFileNameExtension = $defaultFileNameExtension; - if (-e "$sourceFileNameWithoutExtension.$sourceFileNameExtension") - { - if ($spidatahide) - { - push @newobydata, "$initialStuff$sourceFileNameWithoutExtension.$sourceFileNameExtension$finalStuff\n"; - } - else - { - push @newobydata, "$initialStuff$sourceFileNameWithoutExtension.$sourceFileNameExtension $targetFileNameWithoutExtension.$targetFileNameExtension$finalStuff\n"; - } - } - } - my $useDefaultFileNameExtension=1; - foreach my $languageCode (keys %languageCodes) { - my $sourceFileNameExtension=$defaultFileNameExtension; - $sourceFileNameExtension=~s/^(.*).{2}$/$1$languageCode/; - if (! -e "$sourceFileNameWithoutExtension.$sourceFileNameExtension") - { - if (!$spidataflag) - { - next if (!$useDefaultFileNameExtension); - next if (defined $defaultLanguageCode and !($languageCode eq $defaultLanguageCode)); - $useDefaultFileNameExtension=0; - if (!$datahide) - { - print "Converting >$sourceFileNameWithoutExtension.$sourceFileNameExtension< to $defaultFileNameExtension\n"; - $sourceFileNameExtension=$defaultFileNameExtension; - } - } - else - { - next; - } - } - - my $targetFileNameExtension; -# ecom.sNN should contain the corresponding language code .RNN files - if(!$spidataflag and (defined $defaultLanguageCode and ($languageCode eq $defaultLanguageCode))) - { - $targetFileNameExtension = $defaultFileNameExtension; - } - else - { - $targetFileNameExtension = $sourceFileNameExtension; - } - my $modifiedfinalStuff = $finalStuff; - $modifiedfinalStuff =~ s/\.spi/\.s$languageCode/i; - - if ($spidatahide) - { - push @newobydata, "$initialStuff$sourceFileNameWithoutExtension.$sourceFileNameExtension$modifiedfinalStuff\n"; - } - elsif ($datahide) - { - push @newobydata, "$initialStuff$targetFileNameWithoutExtension.$targetFileNameExtension$modifiedfinalStuff\n"; - if(!($sourceFileNameExtension eq $targetFileNameExtension)) - { - push @newobydata, "$initialStuff$targetFileNameWithoutExtension.$sourceFileNameExtension$modifiedfinalStuff\n"; - } - } - else - { - push @newobydata, "$initialStuff$sourceFileNameWithoutExtension.$sourceFileNameExtension $targetFileNameWithoutExtension.$sourceFileNameExtension$modifiedfinalStuff\n"; - if(!($sourceFileNameExtension eq $targetFileNameExtension)) - { - push @newobydata, "alias $targetFileNameWithoutExtension.$sourceFileNameExtension $targetFileNameWithoutExtension.$targetFileNameExtension $modifiedfinalStuff\n"; - $multiLinguifyAlias{"$targetFileNameWithoutExtension.$sourceFileNameExtension"} = 1; - } - } - } - $line = reassert_sourceline(); - } - push @newobydata, $line; - } - - @obydata = @newobydata; - dump_obydata("tmp5.oby", "result of choosing language-specific files") if ($opt_v); - undef @newobydata; - -} - -my @featurefilearray; #2d array storing names and locations of feature files in each rom image -my @featureslist; #array of hashes, stores all the features which are to go into the feature files -my $featurefilecount=0; #counts number of feature files in each rom image -my $featurescount=0; #counts number of features -my $dir; # Stores the ROM image location of features.dat/featreg.cfg files -my $featurefilename; # Stores the name of feature file to be generated(i.e. "features.dat" or "featreg.cfg") -my @spiarray; #2d array storing names and locations of spi files in each rom image -my @datafiles; #array of hashes, stores all the data files which are to go into the spi files -my @hidedatafiles; #array of hashes, stores all the data files which are to be hidden in the spi files -my $spicount=0; #counts number of spi files in each rom image -my $filescount=0; #counts number of data files -my $hidefilescount=0; #counts number of data files to be hidden -my $romimage=0; #number of rom image currently working with - -sub locateexisting -{ # if an SPI file of this type exists in a base image then returns name of SPI file from the array - my ($romimage, $spifile, $base) =@_; - my $i=0; - while(defined $spiarray[$base][$i]) { - if($spiarray[$base][$i]{spi} eq $spiarray[$romimage][$spifile]{spi}) { - my $spiname; - my $spiextension; - if($spiarray[$base][$i]{spifile} =~ /(.*)\.(.*)$/) { - $spiname=$1; - $spiextension=$2; - } - if(-e "$spiname-$base-$i\.$spiextension") { - return "$spiname-$base-$i\.$spiextension"; - } - } - $i++; - } - return ""; -} - -sub create -{ #called to create SPI file and store in specified directory - my ($romimage, $spifile, $base) =@_; #$romimage = current rom image number, $spifile = current spifile number, $base=number of rom image basing on - my $existingspi = ""; - if(defined($base)) { # checks core image for an existing SPI file of this type, if an existing file exists then $existingspi is set to -i which will later be passed to spitool.pm - $existingspi = locateexisting($romimage, $spifile, $base); - if($existingspi ne "") { - $existingspi = "-i$existingspi"; - - } - } - if($spiarray[$romimage][$spifile]{spifile} =~ /(.+)\.(.*)$/) { - my $targetspi="$1-$romimage-$spifile\.$2"; #add romimage number and identifier for spi file to spi file name to distinguish from other spi files - my @dataforspi; # array to store names of data files to include in spi file - my @hidedatainspi; # array to store names of data files that are to be hidden in spi file - for(my $k=0;$k