コード例 #1
0
ファイル: scanner.c プロジェクト: cc65/cc65
void InfoOptionalAssign (void)
/* Consume an equal sign if there is one */
{
    if (InfoTok == INFOTOK_EQ) {
        InfoNextTok ();
    }
}
コード例 #2
0
ファイル: scanner.c プロジェクト: cc65/cc65
void InfoOptionalComma (void)
/* Consume a comma if there is one */
{
    if (InfoTok == INFOTOK_COMMA) {
        InfoNextTok ();
    }
}
コード例 #3
0
ファイル: scanner.c プロジェクト: 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 ();
}
コード例 #4
0
ファイル: scanner.c プロジェクト: cc65/cc65
void InfoOpenInput (void)
/* Open the input file */
{
    /* Open the file */
    InputFile = fopen (InfoFile, "r");
    if (InputFile == 0) {
        Error ("Cannot open '%s': %s", InfoFile, strerror (errno));
    }

    /* Initialize variables */
    C         = ' ';
    InputLine = 1;
    InputCol  = 0;

    /* Start the ball rolling ... */
    InfoNextTok ();
}
コード例 #5
0
ファイル: infofile.c プロジェクト: Aliandrana/cc65
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 ();
}
コード例 #6
0
ファイル: infofile.c プロジェクト: Aliandrana/cc65
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 ();
}
コード例 #7
0
ファイル: infofile.c プロジェクト: Aliandrana/cc65
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 ();
}
コード例 #8
0
ファイル: infofile.c プロジェクト: Aliandrana/cc65
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 ();
}
コード例 #9
0
ファイル: infofile.c プロジェクト: Aliandrana/cc65
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 ();
}