%{ /*---------------------------------------------------------------------------* Project: NitroSDK - tools - makelcf File: tlcf.y Copyright 2003-2008 Nintendo. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Log: tlcf.y,v $ Revision 1.23 2007/07/09 12:17:54 yasu Support for TARGET_NAME Revision 1.22 2007/07/09 07:02:00 yasu Support for IF.EXIST Revision 1.21 2007/04/12 03:29:45 yasu Revised such that IF FIRST/LAST can also support FOREACH OBJECT/LIBRARY Revision 1.20 2007/04/10 14:13:20 yasu Support for multiple uses of SEARCH_SYMBOL Revision 1.19 2006/05/11 12:55:30 yasu Halted warnings Revision 1.18 2006/05/10 03:14:01 yasu Corrected an error in the IF-ELSE-ENDIF conditional determination Revision 1.17 2006/05/10 02:06:00 yasu Added support for CodeWarrior 2.x Revision 1.16 2006/03/30 23:59:45 yasu Updated copyright year Revision 1.15 2006/03/29 13:13:22 yasu IF-ELSE-ENDIF support Revision 1.14 2005/09/01 04:30:58 yasu Support for Overlay Group Revision 1.13 2005/08/26 11:23:11 yasu Overlay support for ITCM/DTCM Revision 1.12 2005/06/22 00:50:06 yasu Updated copyright year Revision 1.11 2005/06/20 12:21:48 yasu Changed Surffix to Suffix Revision 1.10 2004/07/10 04:06:17 yasu Added support for command 'Library' Support for modifier ':x' in template Fixed line continue '\' issue Revision 1.9 2004/07/02 07:34:53 yasu Added support for OBJECT( ) Revision 1.8 2004/06/24 07:18:54 yasu Support for keyword "Autoload" Revision 1.7 2004/06/14 11:28:45 yasu Support for section filter "FOREACH.STATIC.OBJECTS=.sectionName" Revision 1.6 2004/02/13 07:13:03 yasu Support for SDK_IRQ_STACKSIZE Revision 1.5 2004/02/05 07:09:03 yasu Changed SDK prefix from iris to nitro Revision 1.4 2004/01/15 10:47:56 yasu Implementation of a static StackSize Revision 1.3 2004/01/14 12:38:08 yasu Changed OverlayName to OverlayDefs Revision 1.2 2004/01/07 13:10:17 yasu Fixed all warnings at compile -Wall Revision 1.1 2004/01/05 02:32:59 yasu Initial version $NoKeywords: $ *---------------------------------------------------------------------------*/ #include #include #include "makelcf.h" #include "defval.h" // IF-ELSE-ENDIF static tCondStack cond_stack[COND_STACK_MAX]; static int cond_stack_level = 0; static BOOL cond_valid = TRUE; static tCondBlock cond_block = COND_BLOCK_NOCOND; static BOOL GetCompResult(const char* id, const char* comp, const char* value, BOOL* pvalid) { int result; BOOL valid; const char* defval; defval = SearchDefValCleaned(id); result = strcmp(defval, value); if ( strcmp( comp, ".EQ." ) == 0 || strcmp( comp, "==" ) == 0 ) valid = ( result == 0 ); else if ( strcmp( comp, ".NE." ) == 0 || strcmp( comp, "!=" ) == 0 ) valid = ( result != 0 ); else if ( strcmp( comp, ".GT." ) == 0 ) valid = ( result > 0 ); else if ( strcmp( comp, ".GE." ) == 0 ) valid = ( result >= 0 ); else if ( strcmp( comp, ".LT." ) == 0 ) valid = ( result < 0 ); else if ( strcmp( comp, ".LE." ) == 0 ) valid = ( result <= 0 ); else { tlcf_yyerror( "Illegal IF-condition" ); return FALSE; } debug_printf("id(%s)=[%s] comp=[%s] value=[%s] valid=%d\n", id, defval, comp, value, valid); *pvalid = valid; return TRUE; } static BOOL CondIf(const char* id, const char* comp, const char* value) { if (cond_stack_level >= COND_STACK_MAX) { tlcf_yyerror( "Too deep if-else-endif block" ); return FALSE; } cond_stack[cond_stack_level].block = cond_block; cond_stack[cond_stack_level].valid = cond_valid; cond_stack_level ++; cond_block = COND_BLOCK_IF; // Update validation only if previous level validation is TRUE if (cond_stack[cond_stack_level-1].valid) { if (!GetCompResult(id, comp, value, &cond_valid)) { tlcf_yyerror( "Unresolved IF condition" ); return FALSE; } } return TRUE; } static BOOL CondElse(void) { if (cond_block != COND_BLOCK_IF || cond_stack_level <= 0) { tlcf_yyerror( "IF-ELSE-ENDIF unmatched" ); return FALSE; } cond_block = COND_BLOCK_ELSE; // Update validation only if previous level validation is TRUE if (cond_stack[cond_stack_level-1].valid) { cond_valid = cond_valid ? FALSE : TRUE; // Flip validation } return TRUE; } static BOOL CondEndIf(void) { if ((cond_block != COND_BLOCK_IF && cond_block != COND_BLOCK_ELSE) || cond_stack_level <= 0) { tlcf_yyerror( "IF-ELSE-ENDIF unmatched" ); return FALSE; } cond_stack_level --; cond_block = cond_stack[cond_stack_level].block; cond_valid = cond_stack[cond_stack_level].valid; return TRUE; } // TOKEN HANDLING tTokenBuffer tokenBuffer[TOKEN_LEN]; int tokenBufferEnd = 0; static tLoopStack loop_stack[LOOP_STACK_MAX]; static int loop_stack_level = 0; static BOOL StoreToken( int id, const char *str ) { // Validation check for IF-ELSE-ENDIF if ( !cond_valid ) return TRUE; if ( tokenBufferEnd >= TOKEN_LEN ) { tlcf_yyerror( "Out of token buffer" ); return FALSE; } tokenBuffer[tokenBufferEnd].id = id; tokenBuffer[tokenBufferEnd].string = str; tokenBufferEnd ++; return TRUE; } static BOOL PushLoopStack( int id, const char* sectionName ) { // Validation check for IF-ELSE-ENDIF if ( !cond_valid ) return TRUE; if ( loop_stack_level >= LOOP_STACK_MAX ) { tlcf_yyerror( "Out of stack level" ); return FALSE; } loop_stack[loop_stack_level].id = id; loop_stack[loop_stack_level].start = tokenBufferEnd; loop_stack_level ++; return StoreToken( id, sectionName ); } static BOOL PopLoopStack( int id ) { int start; // Validation check for IF-ELSE-ENDIF if ( !cond_valid ) return TRUE; loop_stack_level --; if ( loop_stack_level < 0 || id != loop_stack[loop_stack_level].id ) { tlcf_yyerror( "Unmatched foreach-end" ); return FALSE; } start = loop_stack[loop_stack_level].start; tokenBuffer[start].loop_end = tokenBufferEnd-1; // Don't store 'END' token to TokenBuffer return TRUE; } BOOL GetLoopStackLevel( void ) { return loop_stack_level; } %} %union { char *string; }; %token tSTRING %token tTARGET_NAME %token tSTATIC_NAME %token tSTATIC_ADDRESS %token tSTATIC_STACKSIZE %token tSTATIC_IRQSTACKSIZE %token tSTATIC_OBJECT %token tSTATIC_LIBRARY %token tSTATIC_SEARCHSYMBOL %token tFOREACH_STATIC_OBJECTS %token tFOREACH_STATIC_LIBRARIES %token tFOREACH_STATIC_SEARCHSYMBOLS %token tEND_STATIC_OBJECTS %token tEND_STATIC_LIBRARIES %token tEND_STATIC_SEARCHSYMBOLS %token tIF_STATIC_OBJECT_FIRST %token tIF_STATIC_OBJECT_LAST %token tIF_STATIC_LIBRARY_FIRST %token tIF_STATIC_LIBRARY_LAST %token tIF_STATIC_SEARCHSYMBOL_FIRST %token tIF_STATIC_SEARCHSYMBOL_LAST %token tNUMBER_AUTOLOADS %token tAUTOLOAD_ID %token tAUTOLOAD_NAME %token tAUTOLOAD_ADDRESS %token tAUTOLOAD_OBJECT %token tAUTOLOAD_LIBRARY %token tAUTOLOAD_SEARCHSYMBOL %token tFOREACH_AUTOLOADS %token tFOREACH_AUTOLOAD_OBJECTS %token tFOREACH_AUTOLOAD_LIBRARIES %token tFOREACH_AUTOLOAD_SEARCHSYMBOLS %token tEND_AUTOLOADS %token tEND_AUTOLOAD_OBJECTS %token tEND_AUTOLOAD_LIBRARIES %token tEND_AUTOLOAD_SEARCHSYMBOLS %token tIF_AUTOLOAD_FIRST %token tIF_AUTOLOAD_LAST %token tIF_AUTOLOAD_OBJECT_FIRST %token tIF_AUTOLOAD_OBJECT_LAST %token tIF_AUTOLOAD_LIBRARY_FIRST %token tIF_AUTOLOAD_LIBRARY_LAST %token tIF_AUTOLOAD_SEARCHSYMBOL_FIRST %token tIF_AUTOLOAD_SEARCHSYMBOL_LAST %token tNUMBER_OVERLAYS %token tOVERLAY_ID %token tOVERLAY_NAME %token tOVERLAY_GROUP %token tOVERLAY_ADDRESS %token tOVERLAY_OBJECT %token tOVERLAY_LIBRARY %token tOVERLAY_SEARCHSYMBOL %token tFOREACH_OVERLAYS %token tFOREACH_OVERLAY_OBJECTS %token tFOREACH_OVERLAY_LIBRARIES %token tFOREACH_OVERLAY_SEARCHSYMBOLS %token tEND_OVERLAYS %token tEND_OVERLAY_OBJECTS %token tEND_OVERLAY_LIBRARIES %token tEND_OVERLAY_SEARCHSYMBOLS %token tIF_OVERLAY_FIRST %token tIF_OVERLAY_LAST %token tIF_OVERLAY_OBJECT_FIRST %token tIF_OVERLAY_OBJECT_LAST %token tIF_OVERLAY_LIBRARY_FIRST %token tIF_OVERLAY_LIBRARY_LAST %token tIF_OVERLAY_SEARCHSYMBOL_FIRST %token tIF_OVERLAY_SEARCHSYMBOL_LAST %token tIF_EXIST_SECTION %token tIF_EXIST_STATIC %token tIF_EXIST_AUTOLOAD %token tIF_EXIST_OVERLAY %token tPROPERTY_OVERLAYDEFS %token tPROPERTY_OVERLAYTABLE %token tPROPERTY_SUFFIX %token tIF_OPEN %token tIF_CLOSE %token tIF_ID %token tIF_COMP %token tIF_VALUE %token tIF_ELSE %token tIF_ENDIF %% /*=========================================================================* ConfigFile *=========================================================================*/ tlcfFile : tokens ; tokens : /*NULL*/ | tokens token ; token : tSTRING { if (!StoreToken( tSTRING, $1 )) YYABORT; } | tTARGET_NAME { if (!StoreToken( tTARGET_NAME, $1 )) YYABORT; } | tSTATIC_NAME { if (!StoreToken( tSTATIC_NAME, NULL )) YYABORT; } | tSTATIC_ADDRESS { if (!StoreToken( tSTATIC_ADDRESS, NULL )) YYABORT; } | tSTATIC_OBJECT { if (!StoreToken( tSTATIC_OBJECT, $1 )) YYABORT; } | tSTATIC_LIBRARY { if (!StoreToken( tSTATIC_LIBRARY, $1 )) YYABORT; } | tSTATIC_SEARCHSYMBOL { if (!StoreToken( tSTATIC_SEARCHSYMBOL, $1 )) YYABORT; } | tSTATIC_STACKSIZE { if (!StoreToken( tSTATIC_STACKSIZE, NULL )) YYABORT; } | tSTATIC_IRQSTACKSIZE { if (!StoreToken( tSTATIC_IRQSTACKSIZE, NULL )) YYABORT; } | tFOREACH_STATIC_OBJECTS { if (!PushLoopStack( tFOREACH_STATIC_OBJECTS, $1 )) YYABORT; } | tEND_STATIC_OBJECTS { if (!PopLoopStack ( tFOREACH_STATIC_OBJECTS )) YYABORT; } | tFOREACH_STATIC_LIBRARIES { if (!PushLoopStack( tFOREACH_STATIC_LIBRARIES, $1 )) YYABORT; } | tEND_STATIC_LIBRARIES { if (!PopLoopStack ( tFOREACH_STATIC_LIBRARIES )) YYABORT; } | tFOREACH_STATIC_SEARCHSYMBOLS { if (!PushLoopStack( tFOREACH_STATIC_SEARCHSYMBOLS, $1 )) YYABORT; } | tEND_STATIC_SEARCHSYMBOLS { if (!PopLoopStack ( tFOREACH_STATIC_SEARCHSYMBOLS )) YYABORT; } | tIF_STATIC_OBJECT_FIRST { if (!StoreToken( tIF_STATIC_OBJECT_FIRST, $1 )) YYABORT; } | tIF_STATIC_OBJECT_LAST { if (!StoreToken( tIF_STATIC_OBJECT_LAST, $1 )) YYABORT; } | tIF_STATIC_LIBRARY_FIRST { if (!StoreToken( tIF_STATIC_LIBRARY_FIRST, $1 )) YYABORT; } | tIF_STATIC_LIBRARY_LAST { if (!StoreToken( tIF_STATIC_LIBRARY_LAST, $1 )) YYABORT; } | tIF_STATIC_SEARCHSYMBOL_FIRST { if (!StoreToken( tIF_STATIC_SEARCHSYMBOL_FIRST, $1 )) YYABORT; } | tIF_STATIC_SEARCHSYMBOL_LAST { if (!StoreToken( tIF_STATIC_SEARCHSYMBOL_LAST, $1 )) YYABORT; } | tAUTOLOAD_ID { if (!StoreToken( tAUTOLOAD_ID, NULL )) YYABORT; } | tAUTOLOAD_NAME { if (!StoreToken( tAUTOLOAD_NAME, NULL )) YYABORT; } | tAUTOLOAD_ADDRESS { if (!StoreToken( tAUTOLOAD_ADDRESS, NULL )) YYABORT; } | tAUTOLOAD_OBJECT { if (!StoreToken( tAUTOLOAD_OBJECT, $1 )) YYABORT; } | tAUTOLOAD_LIBRARY { if (!StoreToken( tAUTOLOAD_LIBRARY, $1 )) YYABORT; } | tAUTOLOAD_SEARCHSYMBOL { if (!StoreToken( tAUTOLOAD_SEARCHSYMBOL, $1 )) YYABORT; } | tNUMBER_AUTOLOADS { if (!StoreToken( tNUMBER_AUTOLOADS, NULL )) YYABORT; } | tFOREACH_AUTOLOADS { if (!PushLoopStack( tFOREACH_AUTOLOADS, $1 )) YYABORT; } | tEND_AUTOLOADS { if (!PopLoopStack ( tFOREACH_AUTOLOADS )) YYABORT; } | tFOREACH_AUTOLOAD_OBJECTS { if (!PushLoopStack( tFOREACH_AUTOLOAD_OBJECTS, $1 )) YYABORT; } | tEND_AUTOLOAD_OBJECTS { if (!PopLoopStack ( tFOREACH_AUTOLOAD_OBJECTS )) YYABORT; } | tFOREACH_AUTOLOAD_LIBRARIES { if (!PushLoopStack( tFOREACH_AUTOLOAD_LIBRARIES, $1 )) YYABORT; } | tEND_AUTOLOAD_LIBRARIES { if (!PopLoopStack ( tFOREACH_AUTOLOAD_LIBRARIES )) YYABORT; } | tFOREACH_AUTOLOAD_SEARCHSYMBOLS{ if (!PushLoopStack( tFOREACH_AUTOLOAD_SEARCHSYMBOLS, $1 )) YYABORT; } | tEND_AUTOLOAD_SEARCHSYMBOLS { if (!PopLoopStack ( tFOREACH_AUTOLOAD_SEARCHSYMBOLS )) YYABORT; } | tIF_AUTOLOAD_FIRST { if (!StoreToken( tIF_AUTOLOAD_FIRST, $1 )) YYABORT; } | tIF_AUTOLOAD_LAST { if (!StoreToken( tIF_AUTOLOAD_LAST, $1 )) YYABORT; } | tIF_AUTOLOAD_OBJECT_FIRST { if (!StoreToken( tIF_AUTOLOAD_OBJECT_FIRST, $1 )) YYABORT; } | tIF_AUTOLOAD_OBJECT_LAST { if (!StoreToken( tIF_AUTOLOAD_OBJECT_LAST, $1 )) YYABORT; } | tIF_AUTOLOAD_LIBRARY_FIRST { if (!StoreToken( tIF_AUTOLOAD_LIBRARY_FIRST, $1 )) YYABORT; } | tIF_AUTOLOAD_LIBRARY_LAST { if (!StoreToken( tIF_AUTOLOAD_LIBRARY_LAST, $1 )) YYABORT; } | tIF_AUTOLOAD_SEARCHSYMBOL_FIRST{ if (!StoreToken( tIF_AUTOLOAD_SEARCHSYMBOL_FIRST, $1 )) YYABORT; } | tIF_AUTOLOAD_SEARCHSYMBOL_LAST { if (!StoreToken( tIF_AUTOLOAD_SEARCHSYMBOL_LAST, $1 )) YYABORT; } | tOVERLAY_ID { if (!StoreToken( tOVERLAY_ID, NULL )) YYABORT; } | tOVERLAY_NAME { if (!StoreToken( tOVERLAY_NAME, NULL )) YYABORT; } | tOVERLAY_GROUP { if (!StoreToken( tOVERLAY_GROUP, NULL )) YYABORT; } | tOVERLAY_ADDRESS { if (!StoreToken( tOVERLAY_ADDRESS, NULL )) YYABORT; } | tOVERLAY_OBJECT { if (!StoreToken( tOVERLAY_OBJECT, $1 )) YYABORT; } | tOVERLAY_LIBRARY { if (!StoreToken( tOVERLAY_LIBRARY, $1 )) YYABORT; } | tOVERLAY_SEARCHSYMBOL { if (!StoreToken( tOVERLAY_SEARCHSYMBOL, $1 )) YYABORT; } | tNUMBER_OVERLAYS { if (!StoreToken( tNUMBER_OVERLAYS, NULL )) YYABORT; } | tFOREACH_OVERLAYS { if (!PushLoopStack( tFOREACH_OVERLAYS, $1 )) YYABORT; } | tEND_OVERLAYS { if (!PopLoopStack ( tFOREACH_OVERLAYS )) YYABORT; } | tFOREACH_OVERLAY_OBJECTS { if (!PushLoopStack( tFOREACH_OVERLAY_OBJECTS, $1 )) YYABORT; } | tEND_OVERLAY_OBJECTS { if (!PopLoopStack ( tFOREACH_OVERLAY_OBJECTS )) YYABORT; } | tFOREACH_OVERLAY_LIBRARIES { if (!PushLoopStack( tFOREACH_OVERLAY_LIBRARIES, $1 )) YYABORT; } | tEND_OVERLAY_LIBRARIES { if (!PopLoopStack ( tFOREACH_OVERLAY_LIBRARIES )) YYABORT; } | tFOREACH_OVERLAY_SEARCHSYMBOLS{ if (!PushLoopStack( tFOREACH_OVERLAY_SEARCHSYMBOLS, $1 )) YYABORT; } | tEND_OVERLAY_SEARCHSYMBOLS { if (!PopLoopStack ( tFOREACH_OVERLAY_SEARCHSYMBOLS )) YYABORT; } | tIF_OVERLAY_FIRST { if (!StoreToken( tIF_OVERLAY_FIRST, $1 )) YYABORT; } | tIF_OVERLAY_LAST { if (!StoreToken( tIF_OVERLAY_LAST, $1 )) YYABORT; } | tIF_OVERLAY_OBJECT_FIRST { if (!StoreToken( tIF_OVERLAY_OBJECT_FIRST, $1 )) YYABORT; } | tIF_OVERLAY_OBJECT_LAST { if (!StoreToken( tIF_OVERLAY_OBJECT_LAST, $1 )) YYABORT; } | tIF_OVERLAY_LIBRARY_FIRST { if (!StoreToken( tIF_OVERLAY_LIBRARY_FIRST, $1 )) YYABORT; } | tIF_OVERLAY_LIBRARY_LAST { if (!StoreToken( tIF_OVERLAY_LIBRARY_LAST, $1 )) YYABORT; } | tIF_OVERLAY_SEARCHSYMBOL_FIRST{ if (!StoreToken( tIF_OVERLAY_SEARCHSYMBOL_FIRST, $1 )) YYABORT; } | tIF_OVERLAY_SEARCHSYMBOL_LAST { if (!StoreToken( tIF_OVERLAY_SEARCHSYMBOL_LAST, $1 )) YYABORT; } | tPROPERTY_OVERLAYDEFS { if (!StoreToken( tPROPERTY_OVERLAYDEFS, NULL )) YYABORT; } | tPROPERTY_OVERLAYTABLE { if (!StoreToken( tPROPERTY_OVERLAYTABLE, NULL )) YYABORT; } | tPROPERTY_SUFFIX { if (!StoreToken( tPROPERTY_SUFFIX, NULL )) YYABORT; } | tIF_EXIST_SECTION { if (!StoreToken( tIF_EXIST_SECTION, $1 )) YYABORT; } | tIF_EXIST_STATIC { if (!StoreToken( tIF_EXIST_STATIC, $1 )) YYABORT; } | tIF_EXIST_AUTOLOAD { if (!StoreToken( tIF_EXIST_AUTOLOAD, $1 )) YYABORT; } | tIF_EXIST_OVERLAY { if (!StoreToken( tIF_EXIST_OVERLAY, $1 )) YYABORT; } | cond_if | cond_else | cond_endif ; cond_if : tIF_OPEN tIF_ID tIF_COMP tIF_VALUE tIF_CLOSE { if (!CondIf( $2, $3, $4 )) YYABORT; } | tIF_OPEN tIF_ID tIF_COMP tIF_CLOSE { if (!CondIf( $2, $3, "" )) YYABORT; } ; cond_else : tIF_ELSE { if (!CondElse()) YYABORT; } ; cond_endif : tIF_ENDIF { if (!CondEndIf()) YYABORT; } ; %%