%{ /*---------------------------------------------------------------------------* Project: NitroSDK - tools - makelcf File: tlcf.l 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.l,v $ Revision 1.25 2007/07/09 12:17:54 yasu Support for TARGET_NAME Revision 1.24 2007/07/09 07:02:00 yasu Support for IF.EXIST Revision 1.23 2007/04/12 03:29:45 yasu Revised such that IF FIRST/LAST can also support FOREACH OBJECT/LIBRARY Revision 1.22 2007/04/10 14:13:20 yasu Support for multiple uses of SEARCH_SYMBOL Revision 1.21 2006/05/10 02:06:00 yasu Added support for CodeWarrior 2.x Revision 1.20 2006/03/30 23:59:45 yasu Updated copyright year Revision 1.19 2006/03/30 03:17:46 yasu Also now recognizing NUMBER_OVERLAYS in order to deal with a bug Revision 1.18 2006/03/29 13:13:22 yasu IF-ELSE-ENDIF support Revision 1.17 2005/09/01 04:30:52 yasu Support for Overlay Group Revision 1.16 2005/08/26 11:23:11 yasu Overlay support for ITCM/DTCM Revision 1.15 2005/06/22 00:50:06 yasu Updated copyright year Revision 1.14 2005/06/20 12:21:48 yasu Changed Surffix to Suffix Revision 1.13 2004/07/10 04:06:17 yasu Added support for command 'Library' Support for modifier ':x' in template Fixed line continue '\' issue Revision 1.12 2004/07/02 07:34:53 yasu Added support for OBJECT( ) Revision 1.11 2004/06/24 07:18:54 yasu Support for keyword "Autoload" Revision 1.10 2004/06/14 11:28:45 yasu Support for section filter "FOREACH.STATIC.OBJECTS=.sectionName" Revision 1.9 2004/03/26 05:07:11 yasu Support for variables like as -DNAME=VALUE Revision 1.8 2004/02/13 07:13:03 yasu Support for SDK_IRQ_STACKSIZE Revision 1.7 2004/02/05 07:09:03 yasu Changed SDK prefix from iris to nitro Revision 1.6 2004/01/15 13:21:03 yasu One line command enabled Revision 1.5 2004/01/15 10:47:56 yasu Implementation of a static StackSize Revision 1.4 2004/01/14 12:58:47 yasu Handle '\r' as newline 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 "tlcf.tab.h" #define RETURN(x) { debug_printf( "%s [%s]\n", #x, tlcf_yytext ); return(x); } BOOL GetLoopStackLevel( void ); void tlcf_yyerror( const char* str ) { if ( tlcf_yytext[0] >= ' ' ) { fprintf( stderr, "makelcf: line %d: %s \'%s\'\n", tlcf_yylineno, str, tlcf_yytext ); } else { fprintf( stderr, "makelcf: line %d: %s\n", tlcf_yylineno, str ); } } static char* getSectionDot( int dotpos, const char* default_section ) { // Skip dotpos dots ('.') and begin from the following dot ('.'), if dotpos > 0 and there are at least that many dots char* head = NULL; char* p; for ( p = tlcf_yytext; *p; p ++ ) { switch ( *p ) { case '.': dotpos --; if (dotpos != 0) break; case '=': case ':': if ( !head ) { head = p; } break; case '>': if ( head ) { *p = '\0'; return strdup( head ); } break; default: break; } } return default_section ? strdup( default_section ) : NULL; } static char* getSection( const char* default_section ) { return getSectionDot( 0, default_section ); // Do not search for a dot } %} st [ \t]* ed [ \t]*\r?\n sec (=[.a-zA-Z]*)? mod (:[htre])? flt (:[f])? wordt =[^:>]* wordf (:[^:>]*)? identifier [A-Za-z_][A-Za-z_0-9]* equation (==|!=|\.EQ\.|\.NE\.|\.GT\.|\.GE\.|\.LT\.|\.LE\.) value [^>\n]* trgfmt (=[^>\n]*)? TARGET_NAME \ STATIC_OBJ \ F_S_OBJS \ E_S_OBJS \ FOR_STATIC_OBJS_1 ^{st}{F_S_OBJS}{ed} FOR_STATIC_OBJS_2 {F_S_OBJS} END_STATIC_OBJS_1 ^{st}{E_S_OBJS}{ed} END_STATIC_OBJS_2 {E_S_OBJS} IF_STATIC_OBJ_FIRST \ IF_STATIC_OBJ_LAST \ STATIC_LIB \ F_S_LIBS \ E_S_LIBS \ FOR_STATIC_LIBS_1 ^{st}{F_S_LIBS}{ed} FOR_STATIC_LIBS_2 {F_S_LIBS} END_STATIC_LIBS_1 ^{st}{E_S_LIBS}{ed} END_STATIC_LIBS_2 {E_S_LIBS} IF_STATIC_LIB_FIRST \ IF_STATIC_LIB_LAST \ STATIC_SYM \ F_S_SYMS \ E_S_SYMS \ FOR_STATIC_SYMS_1 ^{st}{F_S_SYMS}{ed} FOR_STATIC_SYMS_2 {F_S_SYMS} END_STATIC_SYMS_1 ^{st}{E_S_SYMS}{ed} END_STATIC_SYMS_2 {E_S_SYMS} IF_STATIC_SYM_FIRST \ IF_STATIC_SYM_LAST \ F_ATLS \ E_ATLS \ FOR_AUTOLOADS_1 ^{st}{F_ATLS}{ed} FOR_AUTOLOADS_2 {F_ATLS} END_AUTOLOADS_1 ^{st}{E_ATLS}{ed} END_AUTOLOADS_2 {E_ATLS} IF_AUTOLOAD_FIRST \ IF_AUTOLOAD_LAST \ AUTOLOAD_OBJ \ F_A_OBJS \ E_A_OBJS \ FOR_AUTOLOAD_OBJS_1 ^{st}{F_A_OBJS}{ed} FOR_AUTOLOAD_OBJS_2 {F_A_OBJS} END_AUTOLOAD_OBJS_1 ^{st}{E_A_OBJS}{ed} END_AUTOLOAD_OBJS_2 {E_A_OBJS} IF_AUTOLOAD_OBJ_FIRST \ IF_AUTOLOAD_OBJ_LAST \ AUTOLOAD_LIB \ F_A_LIBS \ E_A_LIBS \ FOR_AUTOLOAD_LIBS_1 ^{st}{F_A_LIBS}{ed} FOR_AUTOLOAD_LIBS_2 {F_A_LIBS} END_AUTOLOAD_LIBS_1 ^{st}{E_A_LIBS}{ed} END_AUTOLOAD_LIBS_2 {E_A_LIBS} IF_AUTOLOAD_LIB_FIRST \ IF_AUTOLOAD_LIB_LAST \ AUTOLOAD_SYM \ F_A_SYMS \ E_A_SYMS \ FOR_AUTOLOAD_SYMS_1 ^{st}{F_A_SYMS}{ed} FOR_AUTOLOAD_SYMS_2 {F_A_SYMS} END_AUTOLOAD_SYMS_1 ^{st}{E_A_SYMS}{ed} END_AUTOLOAD_SYMS_2 {E_A_SYMS} IF_AUTOLOAD_SYM_FIRST \ IF_AUTOLOAD_SYM_LAST \ F_OVLS \ E_OVLS \ FOR_OVERLAYS_1 ^{st}{F_OVLS}{ed} FOR_OVERLAYS_2 {F_OVLS} END_OVERLAYS_1 ^{st}{E_OVLS}{ed} END_OVERLAYS_2 {E_OVLS} IF_OVERLAY_FIRST \ IF_OVERLAY_LAST \ OVERLAY_OBJ \ F_O_OBJS \ E_O_OBJS \ FOR_OVERLAY_OBJS_1 ^{st}{F_O_OBJS}{ed} FOR_OVERLAY_OBJS_2 {F_O_OBJS} END_OVERLAY_OBJS_1 ^{st}{E_O_OBJS}{ed} END_OVERLAY_OBJS_2 {E_O_OBJS} IF_OVERLAY_OBJ_FIRST \ IF_OVERLAY_OBJ_LAST \ OVERLAY_LIB \ F_O_LIBS \ E_O_LIBS \ FOR_OVERLAY_LIBS_1 ^{st}{F_O_LIBS}{ed} FOR_OVERLAY_LIBS_2 {F_O_LIBS} END_OVERLAY_LIBS_1 ^{st}{E_O_LIBS}{ed} END_OVERLAY_LIBS_2 {E_O_LIBS} IF_OVERLAY_LIB_FIRST \ IF_OVERLAY_LIB_LAST \ OVERLAY_SYM \ F_O_SYMS \ E_O_SYMS \ FOR_OVERLAY_SYMS_1 ^{st}{F_O_SYMS}{ed} FOR_OVERLAY_SYMS_2 {F_O_SYMS} END_OVERLAY_SYMS_1 ^{st}{E_O_SYMS}{ed} END_OVERLAY_SYMS_2 {E_O_SYMS} IF_OVERLAY_SYM_FIRST \ IF_OVERLAY_SYM_LAST \ IF_EXIST_SECTION \ IF_EXIST_STATIC \ IF_EXIST_AUTOLOAD \ IF_EXIST_OVERLAY \ %x IFCOND1 %x IFCOND2 %x IFCOND3 %option pointer %option yylineno %option noyywrap %% //=========================================================================== // LCF TOKENS //=========================================================================== \{identifier} { BEGIN IFCOND2; tlcf_yylval.string = strdup(tlcf_yytext); RETURN(tIF_ID); } {equation} { BEGIN IFCOND3; tlcf_yylval.string = strdup(tlcf_yytext); RETURN(tIF_COMP); } {value} { tlcf_yylval.string = strdup(tlcf_yytext); RETURN(tIF_VALUE); } \> { BEGIN INITIAL; RETURN(tIF_CLOSE); } \ { RETURN(tIF_ELSE); } \ { RETURN(tIF_ENDIF); } {TARGET_NAME} { tlcf_yylval.string = getSection(NULL); RETURN(tTARGET_NAME); } \ { RETURN(tSTATIC_NAME); } \ { RETURN(tSTATIC_ADDRESS); } \ { RETURN(tSTATIC_STACKSIZE); } \ { RETURN(tSTATIC_IRQSTACKSIZE); } {STATIC_OBJ} { tlcf_yylval.string = getSection(NULL); RETURN(tSTATIC_OBJECT); } {FOR_STATIC_OBJS_1} { tlcf_yylval.string = getSection("=*"); RETURN(tFOREACH_STATIC_OBJECTS); } {FOR_STATIC_OBJS_2} { tlcf_yylval.string = getSection("=*"); RETURN(tFOREACH_STATIC_OBJECTS); } {END_STATIC_OBJS_1} { RETURN(tEND_STATIC_OBJECTS); } {END_STATIC_OBJS_2} { RETURN(tEND_STATIC_OBJECTS); } {IF_STATIC_OBJ_FIRST} { tlcf_yylval.string = getSection(NULL); RETURN(tIF_STATIC_OBJECT_FIRST); } {IF_STATIC_OBJ_LAST} { tlcf_yylval.string = getSection(NULL); RETURN(tIF_STATIC_OBJECT_LAST); } {STATIC_LIB} { tlcf_yylval.string = getSection(NULL); RETURN(tSTATIC_LIBRARY); } {FOR_STATIC_LIBS_1} { tlcf_yylval.string = getSection("=*"); RETURN(tFOREACH_STATIC_LIBRARIES); } {FOR_STATIC_LIBS_2} { tlcf_yylval.string = getSection("=*"); RETURN(tFOREACH_STATIC_LIBRARIES); } {END_STATIC_LIBS_1} { RETURN(tEND_STATIC_LIBRARIES); } {END_STATIC_LIBS_2} { RETURN(tEND_STATIC_LIBRARIES); } {IF_STATIC_LIB_FIRST} { tlcf_yylval.string = getSection(NULL); RETURN(tIF_STATIC_LIBRARY_FIRST); } {IF_STATIC_LIB_LAST} { tlcf_yylval.string = getSection(NULL); RETURN(tIF_STATIC_LIBRARY_LAST); } {STATIC_SYM} { tlcf_yylval.string = getSection(NULL); RETURN(tSTATIC_SEARCHSYMBOL); } {FOR_STATIC_SYMS_1} { tlcf_yylval.string = getSection("=*"); RETURN(tFOREACH_STATIC_SEARCHSYMBOLS); } {FOR_STATIC_SYMS_2} { tlcf_yylval.string = getSection("=*"); RETURN(tFOREACH_STATIC_SEARCHSYMBOLS); } {END_STATIC_SYMS_1} { RETURN(tEND_STATIC_SEARCHSYMBOLS); } {END_STATIC_SYMS_2} { RETURN(tEND_STATIC_SEARCHSYMBOLS); } {IF_STATIC_SYM_FIRST} { tlcf_yylval.string = getSection(NULL); RETURN(tIF_STATIC_SEARCHSYMBOL_FIRST); } {IF_STATIC_SYM_LAST} { tlcf_yylval.string = getSection(NULL); RETURN(tIF_STATIC_SEARCHSYMBOL_LAST); } \ { RETURN(tAUTOLOAD_ID); } \ { RETURN(tAUTOLOAD_NAME); } \ { RETURN(tAUTOLOAD_ADDRESS); } \ { RETURN(tNUMBER_AUTOLOADS); } {FOR_AUTOLOADS_1} { tlcf_yylval.string = getSection("=*"); RETURN(tFOREACH_AUTOLOADS); } {FOR_AUTOLOADS_2} { tlcf_yylval.string = getSection("=*"); RETURN(tFOREACH_AUTOLOADS); } {END_AUTOLOADS_1} { RETURN(tEND_AUTOLOADS); } {END_AUTOLOADS_2} { RETURN(tEND_AUTOLOADS); } {IF_AUTOLOAD_FIRST} { tlcf_yylval.string = getSection(NULL); RETURN(tIF_AUTOLOAD_FIRST); } {IF_AUTOLOAD_LAST} { tlcf_yylval.string = getSection(NULL); RETURN(tIF_AUTOLOAD_LAST); } {AUTOLOAD_OBJ} { tlcf_yylval.string = getSection(NULL); RETURN(tAUTOLOAD_OBJECT); } {FOR_AUTOLOAD_OBJS_1} { tlcf_yylval.string = getSection("=*"); RETURN(tFOREACH_AUTOLOAD_OBJECTS); } {FOR_AUTOLOAD_OBJS_2} { tlcf_yylval.string = getSection("=*"); RETURN(tFOREACH_AUTOLOAD_OBJECTS); } {END_AUTOLOAD_OBJS_1} { RETURN(tEND_AUTOLOAD_OBJECTS); } {END_AUTOLOAD_OBJS_2} { RETURN(tEND_AUTOLOAD_OBJECTS); } {IF_AUTOLOAD_OBJ_FIRST} { tlcf_yylval.string = getSection(NULL); RETURN(tIF_AUTOLOAD_OBJECT_FIRST); } {IF_AUTOLOAD_OBJ_LAST} { tlcf_yylval.string = getSection(NULL); RETURN(tIF_AUTOLOAD_OBJECT_LAST); } {AUTOLOAD_LIB} { tlcf_yylval.string = getSection(NULL); RETURN(tAUTOLOAD_LIBRARY); } {FOR_AUTOLOAD_LIBS_1} { tlcf_yylval.string = getSection("=*"); RETURN(tFOREACH_AUTOLOAD_LIBRARIES); } {FOR_AUTOLOAD_LIBS_2} { tlcf_yylval.string = getSection("=*"); RETURN(tFOREACH_AUTOLOAD_LIBRARIES); } {END_AUTOLOAD_LIBS_1} { RETURN(tEND_AUTOLOAD_LIBRARIES); } {END_AUTOLOAD_LIBS_2} { RETURN(tEND_AUTOLOAD_LIBRARIES); } {IF_AUTOLOAD_LIB_FIRST} { tlcf_yylval.string = getSection(NULL); RETURN(tIF_AUTOLOAD_LIBRARY_FIRST); } {IF_AUTOLOAD_LIB_LAST} { tlcf_yylval.string = getSection(NULL); RETURN(tIF_AUTOLOAD_LIBRARY_LAST); } {AUTOLOAD_SYM} { tlcf_yylval.string = getSection(NULL); RETURN(tAUTOLOAD_SEARCHSYMBOL); } {FOR_AUTOLOAD_SYMS_1} { tlcf_yylval.string = getSection("=*"); RETURN(tFOREACH_AUTOLOAD_SEARCHSYMBOLS); } {FOR_AUTOLOAD_SYMS_2} { tlcf_yylval.string = getSection("=*"); RETURN(tFOREACH_AUTOLOAD_SEARCHSYMBOLS); } {END_AUTOLOAD_SYMS_1} { RETURN(tEND_AUTOLOAD_SEARCHSYMBOLS); } {END_AUTOLOAD_SYMS_2} { RETURN(tEND_AUTOLOAD_SEARCHSYMBOLS); } {IF_AUTOLOAD_SYM_FIRST} { tlcf_yylval.string = getSection(NULL); RETURN(tIF_AUTOLOAD_SEARCHSYMBOL_FIRST); } {IF_AUTOLOAD_SYM_LAST} { tlcf_yylval.string = getSection(NULL); RETURN(tIF_AUTOLOAD_SEARCHSYMBOL_LAST); } \ { RETURN(tOVERLAY_ID); } \ { RETURN(tOVERLAY_NAME); } \ { RETURN(tOVERLAY_GROUP); } \ { RETURN(tOVERLAY_ADDRESS); } \ { RETURN(tNUMBER_OVERLAYS); } \ { RETURN(tNUMBER_OVERLAYS); } {FOR_OVERLAYS_1} { tlcf_yylval.string = getSection("=*"); RETURN(tFOREACH_OVERLAYS); } {FOR_OVERLAYS_2} { tlcf_yylval.string = getSection("=*"); RETURN(tFOREACH_OVERLAYS); } {END_OVERLAYS_1} { RETURN(tEND_OVERLAYS); } {END_OVERLAYS_2} { RETURN(tEND_OVERLAYS); } {IF_OVERLAY_FIRST} { tlcf_yylval.string = getSection(NULL); RETURN(tIF_OVERLAY_FIRST); } {IF_OVERLAY_LAST} { tlcf_yylval.string = getSection(NULL); RETURN(tIF_OVERLAY_LAST); } {OVERLAY_OBJ} { tlcf_yylval.string = getSection(NULL); RETURN(tOVERLAY_OBJECT); } {FOR_OVERLAY_OBJS_1} { tlcf_yylval.string = getSection("=*"); RETURN(tFOREACH_OVERLAY_OBJECTS); } {FOR_OVERLAY_OBJS_2} { tlcf_yylval.string = getSection("=*"); RETURN(tFOREACH_OVERLAY_OBJECTS); } {END_OVERLAY_OBJS_1} { RETURN(tEND_OVERLAY_OBJECTS); } {END_OVERLAY_OBJS_2} { RETURN(tEND_OVERLAY_OBJECTS); } {IF_OVERLAY_OBJ_FIRST} { tlcf_yylval.string = getSection(NULL); RETURN(tIF_OVERLAY_OBJECT_FIRST); } {IF_OVERLAY_OBJ_LAST} { tlcf_yylval.string = getSection(NULL); RETURN(tIF_OVERLAY_OBJECT_LAST); } {OVERLAY_LIB} { tlcf_yylval.string = getSection(NULL); RETURN(tOVERLAY_LIBRARY); } {FOR_OVERLAY_LIBS_1} { tlcf_yylval.string = getSection("=*"); RETURN(tFOREACH_OVERLAY_LIBRARIES); } {FOR_OVERLAY_LIBS_2} { tlcf_yylval.string = getSection("=*"); RETURN(tFOREACH_OVERLAY_LIBRARIES); } {END_OVERLAY_LIBS_1} { RETURN(tEND_OVERLAY_LIBRARIES); } {END_OVERLAY_LIBS_2} { RETURN(tEND_OVERLAY_LIBRARIES); } {IF_OVERLAY_LIB_FIRST} { tlcf_yylval.string = getSection(NULL); RETURN(tIF_OVERLAY_LIBRARY_FIRST); } {IF_OVERLAY_LIB_LAST} { tlcf_yylval.string = getSection(NULL); RETURN(tIF_OVERLAY_LIBRARY_LAST); } {OVERLAY_SYM} { tlcf_yylval.string = getSection(NULL); RETURN(tOVERLAY_SEARCHSYMBOL); } {FOR_OVERLAY_SYMS_1} { tlcf_yylval.string = getSection("=*"); RETURN(tFOREACH_OVERLAY_SEARCHSYMBOLS); } {FOR_OVERLAY_SYMS_2} { tlcf_yylval.string = getSection("=*"); RETURN(tFOREACH_OVERLAY_SEARCHSYMBOLS); } {END_OVERLAY_SYMS_1} { RETURN(tEND_OVERLAY_SEARCHSYMBOLS); } {END_OVERLAY_SYMS_2} { RETURN(tEND_OVERLAY_SEARCHSYMBOLS); } {IF_OVERLAY_SYM_FIRST} { tlcf_yylval.string = getSection(NULL); RETURN(tIF_OVERLAY_SEARCHSYMBOL_FIRST); } {IF_OVERLAY_SYM_LAST} { tlcf_yylval.string = getSection(NULL); RETURN(tIF_OVERLAY_SEARCHSYMBOL_LAST); } \ { RETURN(tPROPERTY_OVERLAYDEFS); } \ { RETURN(tPROPERTY_OVERLAYTABLE); } \ { RETURN(tPROPERTY_SUFFIX); } {IF_EXIST_SECTION} { tlcf_yylval.string = getSectionDot(3,NULL); RETURN(tIF_EXIST_SECTION); } {IF_EXIST_STATIC} { tlcf_yylval.string = getSectionDot(3,NULL); RETURN(tIF_EXIST_STATIC); } {IF_EXIST_AUTOLOAD} { tlcf_yylval.string = getSectionDot(3,NULL); RETURN(tIF_EXIST_AUTOLOAD); } {IF_EXIST_OVERLAY} { tlcf_yylval.string = getSectionDot(3,NULL); RETURN(tIF_EXIST_OVERLAY); } [^<\n]*\n? | \< { tlcf_yylval.string = strdup(tlcf_yytext); RETURN(tSTRING); } . { RETURN(tlcf_yytext[0]); } %% /*============================================================================ * PARSE TLCF FILE */ int ParseTlcfFile( const char* filename ) { FILE *fp; int result; if ( NULL == ( fp = fopen( filename, "r" ) ) ) { fprintf( stderr, "Cannot open %s\n", filename ); return 2; } tlcf_yyin = fp; result = tlcf_yyparse(); fclose( fp ); if ( GetLoopStackLevel( ) > 0 ) { tlcf_yyerror( "Unmatched foreach-end pair" ); return 1; } return result ? 1 : 0; }