static uint SrcRead( void ) { //=============================== uint len; file_handle fp; char msg[81]; fp = CurrFile->fileptr; if( CurrFile->flags & INC_LIB_MEMBER ) { len = LibRead( fp ); if( LibEof( fp ) ) { ProgSw |= PS_INC_EOF; } else if( LibError( fp, msg ) ) { InfoError( SM_IO_READ_ERR, CurrFile->name, msg ); ProgSw |= PS_INC_EOF; } } else { len = SDRead( fp, SrcBuff, SRCLEN ); if( SDEof( fp ) ) { ProgSw |= PS_INC_EOF; } else if( SDError( fp, msg ) ) { InfoError( SM_IO_READ_ERR, CurrFile->name, msg ); ProgSw |= PS_INC_EOF; } } return( len ); }
void InfoSpecialToken (const IdentTok* Table, unsigned Size, const char* Name) /* Map an identifier to one of the special tokens in the table */ { unsigned I; /* We need an identifier */ if (InfoTok == INFOTOK_IDENT) { /* Make it upper case */ I = 0; while (InfoSVal [I]) { InfoSVal [I] = toupper (InfoSVal [I]); ++I; } /* Linear search */ for (I = 0; I < Size; ++I) { if (strcmp (InfoSVal, Table [I].Ident) == 0) { InfoTok = Table [I].Tok; return; } } } /* Not found or no identifier */ InfoError ("%s expected", Name); }
void InfoRangeCheck (long Lo, long Hi) /* Check the range of InfoIVal */ { if (InfoIVal < Lo || InfoIVal > Hi) { InfoError ("Range error"); } }
void InfoAssureIdent (void) /* Make sure the next token is an identifier */ { if (InfoTok != INFOTOK_IDENT) { InfoError ("Identifier expected"); } }
void InfoAssureChar (void) /* Make sure the next token is a char constant */ { if (InfoTok != INFOTOK_STRCON) { InfoError ("Character constant expected"); } }
void InfoAssureStr (void) /* Make sure the next token is a string constant */ { if (InfoTok != INFOTOK_STRCON) { InfoError ("String constant expected"); } }
void InfoAssureInt (void) /* Make sure the next token is an integer */ { if (InfoTok != INFOTOK_INTCON) { InfoError ("Integer constant expected"); } }
void FiniLabels( int label_type ) { //==================================== // Free specified class of labels. label_entry **owner; label_entry *curr; owner = (label_entry **)&LabelList; for(;;) { curr = *owner; if( curr == NULL ) break; if( ( curr->label & FORMAT_LABEL ) == label_type ) { if( ( CGFlags & CG_FATAL ) == 0 ) { if( curr->label & FORMAT_LABEL ) { BEFiniBack( curr->handle ); BEFreeBack( curr->handle ); } else { InfoError( CP_ERROR, "unfreed label" ); BEFiniLabel( curr->handle ); } } *owner = curr->link; FMemFree( curr ); } else { owner = &curr->link; } } }
void InfoConsume (unsigned T, const char* Msg) /* Skip a token, print an error message if not found */ { if (InfoTok != T) { InfoError (Msg); } InfoNextTok (); }
static void AddAttr (const char* Name, unsigned* Set, unsigned Attr) /* Add an attribute to the set and check that it is not given twice */ { if (*Set & Attr) { /* Attribute is already in the set */ InfoError ("%s given twice", Name); } *Set |= Attr; }
void FiniMacros( void ) { //==================== // Finalize macro processor for a compilation. if( NestingLevel != 0 ) { InfoError( CO_MACRO_STRUCTURE_MISMATCH ); } FreeMacros( false ); }
static void IFCondition( bool cond ) { //======================================== // Process a IF condition. if( NestingLevel == MAX_NESTING ) { InfoError( CO_MACRO_NESTING_EXCEEDED ); } else { MacroCondition( cond ); ++NestingLevel; } }
void MacroENDIF( void ) { //==================== // Process ENDIF directive. if( NestingLevel == 0 ) { InfoError( CO_MACRO_STRUCTURE_MISMATCH ); } else { --NestingLevel; NestingFlags &= ~( 1 << NestingLevel ); SetSkipStatus(); } }
static bool AlreadyOpen( char *name ) { //========================================= source_t *src; src = CurrFile; for(;;) { if( src == NULL ) return( FALSE ); if( strcmp( name, src->name ) == 0 ) break; src = src->link; } InfoError( CO_ALREADY_OPEN, name ); return( TRUE ); }
void RefStmtLabel( sym_id sn ) { //================================= // Statement number has been referenced. if( sn->u.st.ref_count == 0 ) { InfoError( CP_ERROR, "unaccounted referenced to label" ); } else { sn->u.st.ref_count--; if( sn->u.st.ref_count == 0 ) { DoneLabel( sn->u.st.address ); } } }
void MacroELIFNDEF( char *macro, uint macro_len ) { //==================================================== // Process ELIFNDEF directive. --NestingLevel; if( !( NestingStack & ( 1 << NestingLevel ) ) ) { InfoError( CO_MACRO_STRUCTURE_MISMATCH ); } else { if( NestingFlags & ( 1 << NestingLevel ) ) { MacroCondition( FindMacroEntry( macro, macro_len ) == NULL ); } else { NestingFlags |= 1 << NestingLevel; SetSkipStatus(); } } ++NestingLevel; }
void MacroELSE( void ) { //=================== // Process ELSE directive. --NestingLevel; if( !( NestingStack & ( 1 << NestingLevel ) ) ) { InfoError( CO_MACRO_STRUCTURE_MISMATCH ); } else { NestingStack &= ~( 1 << NestingLevel ); if( NestingFlags & ( 1 << NestingLevel ) ) { NestingFlags &= ~( 1 << NestingLevel ); } else { NestingFlags |= 1 << NestingLevel; } SetSkipStatus(); } ++NestingLevel; }
void Include( char *inc_name ) { //================================= file_handle fp; char bld_name[MAX_FILE+1]; char err_msg[ERR_BUFF_SIZE+1]; SDInitAttr(); CopyMaxStr( inc_name, bld_name, MAX_FILE ); MakeName( bld_name, SDSrcExtn( bld_name ), bld_name ); if( AlreadyOpen( inc_name ) ) return; if( AlreadyOpen( bld_name ) ) return; // try file called <include_name>.FOR. fp = SDOpen( bld_name, READ_FILE ); if( fp != NULL ) { SrcInclude( bld_name ); CurrFile->fileptr = fp; } else { // get error message before next i/o SDError( NULL, err_msg ); // try library fp = IncSearch( inc_name ); if( fp != NULL ) { // SrcInclude( inc_name ) now done in LIBSUPP CurrFile->fileptr = fp; CurrFile->flags |= INC_LIB_MEMBER; } else { // could not open include file InfoError( SM_OPENING_FILE, bld_name, err_msg ); } } // clear RetCode so that we don't get "file not found" returned // because we could not open include file RetCode = _SUCCESSFUL; AddDependencyInfo( CurrFile ); }
void InfoBoolToken (void) /* Map an identifier or integer to a boolean token */ { static const IdentTok Booleans [] = { { "YES", INFOTOK_TRUE }, { "NO", INFOTOK_FALSE }, { "TRUE", INFOTOK_TRUE }, { "FALSE", INFOTOK_FALSE }, { "ON", INFOTOK_TRUE }, { "OFF", INFOTOK_FALSE }, }; /* If we have an identifier, map it to a boolean token */ if (InfoTok == INFOTOK_IDENT) { InfoSpecialToken (Booleans, ENTRY_COUNT (Booleans), "Boolean"); } else { /* We expected an integer here */ if (InfoTok != INFOTOK_INTCON) { InfoError ("Boolean value expected"); } InfoTok = (InfoIVal == 0)? INFOTOK_FALSE : INFOTOK_TRUE; } }
void OpenSrc( void ) { //======================= file_handle fp; char err_msg[ERR_BUFF_SIZE+1]; char bld_name[MAX_FILE+1]; bool erase_err; erase_err = ErrFile == NULL; SDInitAttr(); MakeName( SrcName, SrcExtn, bld_name ); fp = SDOpen( bld_name, READ_FILE ); if( fp != NULL ) { SrcInclude( bld_name ); CurrFile->fileptr = fp; } else { SDError( NULL, err_msg ); InfoError( SM_OPENING_FILE, bld_name, err_msg ); } if( erase_err ) { CloseErr(); Erase( ErrExtn ); } }
void InfoNextTok (void) /* Read the next token from the input stream */ { unsigned I; char DecodeBuf [2]; Again: /* Skip whitespace */ SkipBlanks (0); /* Remember the current position */ InfoErrorLine = InputLine; InfoErrorCol = InputCol; /* Identifier? */ if (C == '_' || IsAlpha (C)) { /* Read the identifier */ I = 0; while (C == '_' || IsAlNum (C)) { if (I < CFG_MAX_IDENT_LEN) { InfoSVal [I++] = C; } NextChar (); } InfoSVal [I] = '\0'; InfoTok = INFOTOK_IDENT; return; } /* Hex number? */ if (C == '$') { NextChar (); if (!IsXDigit (C)) { InfoError ("Hex digit expected"); } InfoIVal = 0; while (IsXDigit (C)) { InfoIVal = InfoIVal * 16 + DigitVal (C); NextChar (); } InfoTok = INFOTOK_INTCON; return; } /* Decimal number? */ if (IsDigit (C)) { InfoIVal = GetDecimalToken (); InfoTok = INFOTOK_INTCON; return; } /* Other characters */ switch (C) { case '{': NextChar (); InfoTok = INFOTOK_LCURLY; break; case '}': NextChar (); InfoTok = INFOTOK_RCURLY; break; case ';': NextChar (); InfoTok = INFOTOK_SEMI; break; case '.': NextChar (); InfoTok = INFOTOK_DOT; break; case ',': NextChar (); InfoTok = INFOTOK_COMMA; break; case '=': NextChar (); InfoTok = INFOTOK_EQ; break; case ':': NextChar (); InfoTok = INFOTOK_COLON; break; case '\"': NextChar (); I = 0; InfoSVal[0] = '\0'; while (C != EOF && C != '\"') { if (GetEncodedChar (InfoSVal, &I, sizeof InfoSVal) < 0) { if (C == EOF) { InfoError ("Unterminated string"); } else { InfoError ("Invalid escape char: %c", C); } } } if (C != '\"') { InfoError ("Unterminated string"); } NextChar (); InfoTok = INFOTOK_STRCON; break; case '\'': NextChar (); if (C == EOF || IsControl (C) || C == '\'') { InfoError ("Invalid character constant"); } if (GetEncodedChar (DecodeBuf, &I, sizeof DecodeBuf) < 0 || I != 1) { InfoError ("Invalid character constant"); } InfoIVal = DecodeBuf [0]; if (C != '\'') { InfoError ("Unterminated character constant"); } NextChar (); InfoTok = INFOTOK_CHARCON; break; case '#': /* # lineno "sourcefile" or # comment */ if (SyncLines && InputCol == 1) { LineMarkerOrComment (); } else { do { NextChar (); } while (C != EOF && C != '\n'); NextChar (); } if (C != EOF) { goto Again; } InfoTok = INFOTOK_EOF; break; case '/': /* C++ style comment */ NextChar (); if (C != '/') { InfoError ("Invalid token '/'"); } do { NextChar (); } while (C != '\n' && C != EOF); if (C != EOF) { goto Again; } InfoTok = INFOTOK_EOF; break; case EOF: InfoTok = INFOTOK_EOF; break; default: InfoError ("Invalid character '%c'", C); } }
static void GlobalSection (void) /* Parse a global section */ { static const IdentTok GlobalDefs[] = { { "ARGUMENTCOL", INFOTOK_ARGUMENT_COLUMN }, { "ARGUMENTCOLUMN", INFOTOK_ARGUMENT_COLUMN }, { "COMMENTCOL", INFOTOK_COMMENT_COLUMN }, { "COMMENTCOLUMN", INFOTOK_COMMENT_COLUMN }, { "COMMENTS", INFOTOK_COMMENTS }, { "CPU", INFOTOK_CPU }, { "HEXOFFS", INFOTOK_HEXOFFS }, { "INPUTNAME", INFOTOK_INPUTNAME }, { "INPUTOFFS", INFOTOK_INPUTOFFS }, { "INPUTSIZE", INFOTOK_INPUTSIZE }, { "LABELBREAK", INFOTOK_LABELBREAK }, { "MNEMONICCOL", INFOTOK_MNEMONIC_COLUMN }, { "MNEMONICCOLUMN", INFOTOK_MNEMONIC_COLUMN }, { "NEWLINEAFTERJMP", INFOTOK_NL_AFTER_JMP }, { "NEWLINEAFTERRTS", INFOTOK_NL_AFTER_RTS }, { "OUTPUTNAME", INFOTOK_OUTPUTNAME }, { "PAGELENGTH", INFOTOK_PAGELENGTH }, { "STARTADDR", INFOTOK_STARTADDR }, { "TEXTCOL", INFOTOK_TEXT_COLUMN }, { "TEXTCOLUMN", INFOTOK_TEXT_COLUMN }, }; /* Skip the token */ InfoNextTok (); /* Expect the opening curly brace */ InfoConsumeLCurly (); /* Look for section tokens */ while (InfoTok != INFOTOK_RCURLY) { /* Convert to special token */ InfoSpecialToken (GlobalDefs, ENTRY_COUNT (GlobalDefs), "Global directive"); /* Look at the token */ switch (InfoTok) { case INFOTOK_ARGUMENT_COLUMN: InfoNextTok (); InfoAssureInt (); InfoRangeCheck (MIN_ACOL, MAX_ACOL); ACol = InfoIVal; InfoNextTok (); break; case INFOTOK_COMMENT_COLUMN: InfoNextTok (); InfoAssureInt (); InfoRangeCheck (MIN_CCOL, MAX_CCOL); CCol = InfoIVal; InfoNextTok (); break; case INFOTOK_COMMENTS: InfoNextTok (); InfoAssureInt (); InfoRangeCheck (MIN_COMMENTS, MAX_COMMENTS); Comments = InfoIVal; InfoNextTok (); break; case INFOTOK_CPU: InfoNextTok (); InfoAssureStr (); if (CPU != CPU_UNKNOWN) { InfoError ("CPU already specified"); } CPU = FindCPU (InfoSVal); SetOpcTable (CPU); InfoNextTok (); break; case INFOTOK_HEXOFFS: InfoNextTok (); InfoBoolToken (); switch (InfoTok) { case INFOTOK_FALSE: UseHexOffs = 0; break; case INFOTOK_TRUE: UseHexOffs = 1; break; } InfoNextTok (); break; case INFOTOK_INPUTNAME: InfoNextTok (); InfoAssureStr (); if (InFile) { InfoError ("Input file name already given"); } InFile = xstrdup (InfoSVal); InfoNextTok (); break; case INFOTOK_INPUTOFFS: InfoNextTok (); InfoAssureInt (); InputOffs = InfoIVal; InfoNextTok (); break; case INFOTOK_INPUTSIZE: InfoNextTok (); InfoAssureInt (); InfoRangeCheck (1, 0x10000); InputSize = InfoIVal; InfoNextTok (); break; case INFOTOK_LABELBREAK: InfoNextTok (); InfoAssureInt (); InfoRangeCheck (0, UCHAR_MAX); LBreak = (unsigned char) InfoIVal; InfoNextTok (); break; case INFOTOK_MNEMONIC_COLUMN: InfoNextTok (); InfoAssureInt (); InfoRangeCheck (MIN_MCOL, MAX_MCOL); MCol = InfoIVal; InfoNextTok (); break; case INFOTOK_NL_AFTER_JMP: InfoNextTok (); if (NewlineAfterJMP != -1) { InfoError ("NLAfterJMP already specified"); } InfoBoolToken (); NewlineAfterJMP = (InfoTok != INFOTOK_FALSE); InfoNextTok (); break; case INFOTOK_NL_AFTER_RTS: InfoNextTok (); InfoBoolToken (); if (NewlineAfterRTS != -1) { InfoError ("NLAfterRTS already specified"); } NewlineAfterRTS = (InfoTok != INFOTOK_FALSE); InfoNextTok (); break; case INFOTOK_OUTPUTNAME: InfoNextTok (); InfoAssureStr (); if (OutFile) { InfoError ("Output file name already given"); } OutFile = xstrdup (InfoSVal); InfoNextTok (); break; case INFOTOK_PAGELENGTH: InfoNextTok (); InfoAssureInt (); if (InfoIVal != 0) { InfoRangeCheck (MIN_PAGE_LEN, MAX_PAGE_LEN); } PageLength = InfoIVal; InfoNextTok (); break; case INFOTOK_STARTADDR: InfoNextTok (); InfoAssureInt (); InfoRangeCheck (0x0000, 0xFFFF); StartAddr = InfoIVal; InfoNextTok (); break; case INFOTOK_TEXT_COLUMN: InfoNextTok (); InfoAssureInt (); InfoRangeCheck (MIN_TCOL, MAX_TCOL); TCol = InfoIVal; InfoNextTok (); break; default: Internal ("Unexpected token: %u", InfoTok); } /* Directive is followed by a semicolon */ InfoConsumeSemi (); } /* Consume the closing brace */ InfoConsumeRCurly (); }
static void LabelSection (void) /* Parse a label section */ { static const IdentTok LabelDefs[] = { { "COMMENT", INFOTOK_COMMENT }, { "ADDR", INFOTOK_ADDR }, { "NAME", INFOTOK_NAME }, { "SIZE", INFOTOK_SIZE }, }; /* Locals - initialize to avoid gcc warnings */ char* Name = 0; char* Comment = 0; long Value = -1; long Size = -1; /* Skip the token */ InfoNextTok (); /* Expect the opening curly brace */ InfoConsumeLCurly (); /* Look for section tokens */ while (InfoTok != INFOTOK_RCURLY) { /* Convert to special token */ InfoSpecialToken (LabelDefs, ENTRY_COUNT (LabelDefs), "Label attribute"); /* Look at the token */ switch (InfoTok) { case INFOTOK_ADDR: InfoNextTok (); if (Value >= 0) { InfoError ("Value already given"); } InfoAssureInt (); InfoRangeCheck (0, 0xFFFF); Value = InfoIVal; InfoNextTok (); break; case INFOTOK_COMMENT: InfoNextTok (); if (Comment) { InfoError ("Comment already given"); } InfoAssureStr (); if (InfoSVal[0] == '\0') { InfoError ("Comment may not be empty"); } Comment = xstrdup (InfoSVal); InfoNextTok (); break; case INFOTOK_NAME: InfoNextTok (); if (Name) { InfoError ("Name already given"); } InfoAssureStr (); Name = xstrdup (InfoSVal); InfoNextTok (); break; case INFOTOK_SIZE: InfoNextTok (); if (Size >= 0) { InfoError ("Size already given"); } InfoAssureInt (); InfoRangeCheck (1, 0x10000); Size = InfoIVal; InfoNextTok (); break; default: Internal ("Unexpected token: %u", InfoTok); } /* Directive is followed by a semicolon */ InfoConsumeSemi (); } /* Did we get the necessary data */ if (Name == 0) { InfoError ("Label name is missing"); } if (Name[0] == '\0' && Size > 1) { InfoError ("Unnamed labels must not have a size > 1"); } if (Value < 0) { InfoError ("Label value is missing"); } if (Size < 0) { /* Use default */ Size = 1; } if (Value + Size > 0x10000) { InfoError ("Invalid size (address out of range)"); } if (HaveLabel ((unsigned) Value)) { InfoError ("Label for address $%04lX already defined", Value); } /* Define the label(s) */ if (Name[0] == '\0') { /* Size has already beed checked */ AddUnnamedLabel (Value); } else { AddExtLabelRange ((unsigned) Value, Name, Size); } /* Define the comment */ if (Comment) { SetComment (Value, Comment); } /* Delete the dynamically allocated memory for Name and Comment */ xfree (Name); xfree (Comment); /* Consume the closing brace */ InfoConsumeRCurly (); }
static void RangeSection (void) /* Parse a range section */ { static const IdentTok RangeDefs[] = { { "COMMENT", INFOTOK_COMMENT }, { "END", INFOTOK_END }, { "NAME", INFOTOK_NAME }, { "START", INFOTOK_START }, { "TYPE", INFOTOK_TYPE }, }; static const IdentTok TypeDefs[] = { { "ADDRTABLE", INFOTOK_ADDRTAB }, { "BYTETABLE", INFOTOK_BYTETAB }, { "CODE", INFOTOK_CODE }, { "DBYTETABLE", INFOTOK_DBYTETAB }, { "DWORDTABLE", INFOTOK_DWORDTAB }, { "RTSTABLE", INFOTOK_RTSTAB }, { "SKIP", INFOTOK_SKIP }, { "TEXTTABLE", INFOTOK_TEXTTAB }, { "WORDTABLE", INFOTOK_WORDTAB }, }; /* Which values did we get? */ enum { tNone = 0x00, tStart = 0x01, tEnd = 0x02, tType = 0x04, tName = 0x08, tComment= 0x10, tNeeded = (tStart | tEnd | tType) }; unsigned Attributes = tNone; /* Locals - initialize to avoid gcc warnings */ unsigned Start = 0; unsigned End = 0; unsigned char Type = 0; char* Name = 0; char* Comment = 0; unsigned MemberSize = 0; /* Skip the token */ InfoNextTok (); /* Expect the opening curly brace */ InfoConsumeLCurly (); /* Look for section tokens */ while (InfoTok != INFOTOK_RCURLY) { /* Convert to special token */ InfoSpecialToken (RangeDefs, ENTRY_COUNT (RangeDefs), "Range attribute"); /* Look at the token */ switch (InfoTok) { case INFOTOK_COMMENT: AddAttr ("COMMENT", &Attributes, tComment); InfoNextTok (); InfoAssureStr (); if (InfoSVal[0] == '\0') { InfoError ("Comment may not be empty"); } Comment = xstrdup (InfoSVal); Attributes |= tComment; InfoNextTok (); break; case INFOTOK_END: AddAttr ("END", &Attributes, tEnd); InfoNextTok (); InfoAssureInt (); InfoRangeCheck (0x0000, 0xFFFF); End = InfoIVal; InfoNextTok (); break; case INFOTOK_NAME: AddAttr ("NAME", &Attributes, tName); InfoNextTok (); InfoAssureStr (); if (InfoSVal[0] == '\0') { InfoError ("Name may not be empty"); } Name = xstrdup (InfoSVal); Attributes |= tName; InfoNextTok (); break; case INFOTOK_START: AddAttr ("START", &Attributes, tStart); InfoNextTok (); InfoAssureInt (); InfoRangeCheck (0x0000, 0xFFFF); Start = InfoIVal; InfoNextTok (); break; case INFOTOK_TYPE: AddAttr ("TYPE", &Attributes, tType); InfoNextTok (); InfoSpecialToken (TypeDefs, ENTRY_COUNT (TypeDefs), "TYPE"); switch (InfoTok) { case INFOTOK_ADDRTAB: Type = atAddrTab; MemberSize = 2; break; case INFOTOK_BYTETAB: Type = atByteTab; MemberSize = 1; break; case INFOTOK_CODE: Type = atCode; MemberSize = 1; break; case INFOTOK_DBYTETAB: Type = atDByteTab; MemberSize = 2; break; case INFOTOK_DWORDTAB: Type = atDWordTab; MemberSize = 4; break; case INFOTOK_RTSTAB: Type = atRtsTab; MemberSize = 2; break; case INFOTOK_SKIP: Type = atSkip; MemberSize = 1; break; case INFOTOK_TEXTTAB: Type = atTextTab; MemberSize = 1; break; case INFOTOK_WORDTAB: Type = atWordTab; MemberSize = 2; break; } InfoNextTok (); break; default: Internal ("Unexpected token: %u", InfoTok); } /* Directive is followed by a semicolon */ InfoConsumeSemi (); } /* Did we get all required values? */ if ((Attributes & tNeeded) != tNeeded) { InfoError ("Required values missing from this section"); } /* Start must be less than end */ if (Start > End) { InfoError ("Start value must not be greater than end value"); } /* Check the granularity */ if (((End - Start + 1) % MemberSize) != 0) { InfoError ("Type of range needs a granularity of %u", MemberSize); } /* Set the range */ MarkRange (Start, End, Type); /* Do we have a label? */ if (Attributes & tName) { /* Define a label for the table */ AddExtLabel (Start, Name); /* Set the comment if we have one */ if (Comment) { SetComment (Start, Comment); } /* Delete name and comment */ xfree (Name); xfree (Comment); } /* Consume the closing brace */ InfoConsumeRCurly (); }
static void SegmentSection (void) /* Parse a segment section */ { static const IdentTok LabelDefs[] = { { "END", INFOTOK_END }, { "NAME", INFOTOK_NAME }, { "START", INFOTOK_START }, }; /* Locals - initialize to avoid gcc warnings */ long End = -1; long Start = -1; char* Name = 0; /* Skip the token */ InfoNextTok (); /* Expect the opening curly brace */ InfoConsumeLCurly (); /* Look for section tokens */ while (InfoTok != INFOTOK_RCURLY) { /* Convert to special token */ InfoSpecialToken (LabelDefs, ENTRY_COUNT (LabelDefs), "Segment attribute"); /* Look at the token */ switch (InfoTok) { case INFOTOK_END: InfoNextTok (); if (End >= 0) { InfoError ("Value already given"); } InfoAssureInt (); InfoRangeCheck (0, 0xFFFF); End = InfoIVal; InfoNextTok (); break; case INFOTOK_NAME: InfoNextTok (); if (Name) { InfoError ("Name already given"); } InfoAssureStr (); Name = xstrdup (InfoSVal); InfoNextTok (); break; case INFOTOK_START: InfoNextTok (); if (Start >= 0) { InfoError ("Value already given"); } InfoAssureInt (); InfoRangeCheck (0, 0xFFFF); Start = InfoIVal; InfoNextTok (); break; default: Internal ("Unexpected token: %u", InfoTok); } /* Directive is followed by a semicolon */ InfoConsumeSemi (); } /* Did we get the necessary data, and is it correct? */ if (Name == 0 || Name[0] == '\0') { InfoError ("Segment name is missing"); } if (End < 0) { InfoError ("End address is missing"); } if (Start < 0) { InfoError ("Start address is missing"); } if (Start > End) { InfoError ("Start address of segment is greater than end address"); } /* Check that segments do not overlap */ if (SegmentDefined ((unsigned) Start, (unsigned) End)) { InfoError ("Segments must not overlap"); } /* Remember the segment data */ AddAbsSegment ((unsigned) Start, (unsigned) End, Name); /* Delete the dynamically allocated memory for Name */ xfree (Name); /* Consume the closing brace */ InfoConsumeRCurly (); }
static void AsmIncSection (void) /* Parse a asminc section */ { static const IdentTok LabelDefs[] = { { "COMMENTSTART", INFOTOK_COMMENTSTART }, { "FILE", INFOTOK_FILE }, { "IGNOREUNKNOWN", INFOTOK_IGNOREUNKNOWN }, }; /* Locals - initialize to avoid gcc warnings */ char* Name = 0; int CommentStart = EOF; int IgnoreUnknown = -1; /* Skip the token */ InfoNextTok (); /* Expect the opening curly brace */ InfoConsumeLCurly (); /* Look for section tokens */ while (InfoTok != INFOTOK_RCURLY) { /* Convert to special token */ InfoSpecialToken (LabelDefs, ENTRY_COUNT (LabelDefs), "Asminc directive"); /* Look at the token */ switch (InfoTok) { case INFOTOK_COMMENTSTART: InfoNextTok (); if (CommentStart != EOF) { InfoError ("Commentstart already given"); } InfoAssureChar (); CommentStart = (char) InfoIVal; InfoNextTok (); break; case INFOTOK_FILE: InfoNextTok (); if (Name) { InfoError ("File name already given"); } InfoAssureStr (); if (InfoSVal[0] == '\0') { InfoError ("File name may not be empty"); } Name = xstrdup (InfoSVal); InfoNextTok (); break; case INFOTOK_IGNOREUNKNOWN: InfoNextTok (); if (IgnoreUnknown != -1) { InfoError ("Ignoreunknown already specified"); } InfoBoolToken (); IgnoreUnknown = (InfoTok != INFOTOK_FALSE); InfoNextTok (); break; default: Internal ("Unexpected token: %u", InfoTok); } /* Directive is followed by a semicolon */ InfoConsumeSemi (); } /* Check for the necessary data and assume defaults */ if (Name == 0) { InfoError ("File name is missing"); } if (CommentStart == EOF) { CommentStart = ';'; } if (IgnoreUnknown == -1) { IgnoreUnknown = 0; } /* Open the file and read the symbol definitions */ AsmInc (Name, CommentStart, IgnoreUnknown); /* Delete the dynamically allocated memory for Name */ xfree (Name); /* Consume the closing brace */ InfoConsumeRCurly (); }