Esempio n. 1
0
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 );
}
Esempio n. 2
0
File: scanner.c Progetto: cc65/cc65
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);
}
Esempio n. 3
0
File: scanner.c Progetto: cc65/cc65
void InfoRangeCheck (long Lo, long Hi)
/* Check the range of InfoIVal */
{
    if (InfoIVal < Lo || InfoIVal > Hi) {
        InfoError ("Range error");
    }
}
Esempio n. 4
0
File: scanner.c Progetto: cc65/cc65
void InfoAssureIdent (void)
/* Make sure the next token is an identifier */
{
    if (InfoTok != INFOTOK_IDENT) {
        InfoError ("Identifier expected");
    }
}
Esempio n. 5
0
File: scanner.c Progetto: cc65/cc65
void InfoAssureChar (void)
/* Make sure the next token is a char constant */
{
    if (InfoTok != INFOTOK_STRCON) {
        InfoError ("Character constant expected");
    }
}
Esempio n. 6
0
File: scanner.c Progetto: cc65/cc65
void InfoAssureStr (void)
/* Make sure the next token is a string constant */
{
    if (InfoTok != INFOTOK_STRCON) {
        InfoError ("String constant expected");
    }
}
Esempio n. 7
0
File: scanner.c Progetto: cc65/cc65
void InfoAssureInt (void)
/* Make sure the next token is an integer */
{
    if (InfoTok != INFOTOK_INTCON) {
        InfoError ("Integer constant expected");
    }
}
Esempio n. 8
0
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;
        }
    }
}
Esempio n. 9
0
File: scanner.c Progetto: cc65/cc65
void InfoConsume (unsigned T, const char* Msg)
/* Skip a token, print an error message if not found */
{
    if (InfoTok != T) {
        InfoError (Msg);
    }
    InfoNextTok ();
}
Esempio n. 10
0
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;
}
Esempio n. 11
0
void    FiniMacros( void ) {
//====================

// Finalize macro processor for a compilation.

    if( NestingLevel != 0 ) {
        InfoError( CO_MACRO_STRUCTURE_MISMATCH );
    }
    FreeMacros( false );
}
Esempio n. 12
0
static  void    IFCondition( bool cond ) {
//========================================

// Process a IF condition.

    if( NestingLevel == MAX_NESTING ) {
        InfoError( CO_MACRO_NESTING_EXCEEDED );
    } else {
        MacroCondition( cond );
        ++NestingLevel;
    }
}
Esempio n. 13
0
void    MacroENDIF( void ) {
//====================

// Process ENDIF directive.

    if( NestingLevel == 0 ) {
        InfoError( CO_MACRO_STRUCTURE_MISMATCH );
    } else {
        --NestingLevel;
        NestingFlags &= ~( 1 << NestingLevel );
        SetSkipStatus();
    }
}
Esempio n. 14
0
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 );
}
Esempio n. 15
0
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 );
        }
    }
}
Esempio n. 16
0
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;
}
Esempio n. 17
0
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;
}
Esempio n. 18
0
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 );
}
Esempio n. 19
0
File: scanner.c Progetto: cc65/cc65
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;
    }
}
Esempio n. 20
0
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 );
    }
}
Esempio n. 21
0
File: scanner.c Progetto: cc65/cc65
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);

    }
}
Esempio n. 22
0
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 ();
}
Esempio n. 23
0
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 ();
}
Esempio n. 24
0
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 ();
}
Esempio n. 25
0
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 ();
}
Esempio n. 26
0
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 ();
}