X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fca65%2Fmain.c;h=3ec6c16a31755ceb94bb91540fcdb5748a205673;hb=31f6f814af7491cb56f146e5372738e2f52fdc8a;hp=fdff409490febfbfd278b3fc2cc2b7785648faa3;hpb=1a68dd715a1c7b2131028c66c7393b61f787e0b0;p=cc65 diff --git a/src/ca65/main.c b/src/ca65/main.c index fdff40949..3ec6c16a3 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstraße 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ +/* (C) 1998-2009, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -44,6 +44,7 @@ #include "cmdline.h" #include "mmodel.h" #include "print.h" +#include "strbuf.h" #include "target.h" #include "tgttrans.h" #include "version.h" @@ -61,6 +62,7 @@ #include "istack.h" #include "lineinfo.h" #include "listing.h" +#include "macpack.h" #include "macro.h" #include "nexttok.h" #include "objfile.h" @@ -84,41 +86,42 @@ static void Usage (void) /* Print usage information and exit */ { - fprintf (stderr, - "Usage: %s [options] file\n" - "Short options:\n" - " -D name[=value]\tDefine a symbol\n" - " -I dir\t\tSet an include directory search path\n" - " -U\t\t\tMark unresolved symbols as import\n" - " -V\t\t\tPrint the assembler version\n" - " -W n\t\t\tSet warning level n\n" - " -g\t\t\tAdd debug info to object file\n" - " -h\t\t\tHelp (this text)\n" - " -i\t\t\tIgnore case of symbols\n" - " -l\t\t\tCreate a listing if assembly was ok\n" - " -mm model\t\tSet the memory model\n" - " -o name\t\tName the output file\n" - " -s\t\t\tEnable smart mode\n" - " -t sys\t\tSet the target system\n" - " -v\t\t\tIncrease verbosity\n" - "\n" - "Long options:\n" - " --auto-import\t\tMark unresolved symbols as import\n" - " --cpu type\t\tSet cpu type\n" - " --debug-info\t\tAdd debug info to object file\n" - " --feature name\tSet an emulation feature\n" - " --help\t\tHelp (this text)\n" - " --ignore-case\t\tIgnore case of symbols\n" - " --include-dir dir\tSet an include directory search path\n" - " --listing\t\tCreate a listing if assembly was ok\n" - " --list-bytes n\tMaximum number of bytes per listing line\n" - " --memory-model model\tSet the memory model\n" - " --pagelength n\tSet the page length for the listing\n" - " --smart\t\tEnable smart mode\n" - " --target sys\t\tSet the target system\n" - " --verbose\t\tIncrease verbosity\n" - " --version\t\tPrint the assembler version\n", - ProgName); + printf ("Usage: %s [options] file\n" + "Short options:\n" + " -D name[=value]\tDefine a symbol\n" + " -I dir\t\tSet an include directory search path\n" + " -U\t\t\tMark unresolved symbols as import\n" + " -V\t\t\tPrint the assembler version\n" + " -W n\t\t\tSet warning level n\n" + " -g\t\t\tAdd debug info to object file\n" + " -h\t\t\tHelp (this text)\n" + " -i\t\t\tIgnore case of symbols\n" + " -l\t\t\tCreate a listing if assembly was ok\n" + " -mm model\t\tSet the memory model\n" + " -o name\t\tName the output file\n" + " -s\t\t\tEnable smart mode\n" + " -t sys\t\tSet the target system\n" + " -v\t\t\tIncrease verbosity\n" + "\n" + "Long options:\n" + " --auto-import\t\tMark unresolved symbols as import\n" + " --cpu type\t\tSet cpu type\n" + " --debug-info\t\tAdd debug info to object file\n" + " --feature name\tSet an emulation feature\n" + " --forget-inc-paths\tForget include search paths\n" + " --help\t\tHelp (this text)\n" + " --ignore-case\t\tIgnore case of symbols\n" + " --include-dir dir\tSet an include directory search path\n" + " --listing\t\tCreate a listing if assembly was ok\n" + " --list-bytes n\tMaximum number of bytes per listing line\n" + " --macpack-dir dir\tSet a macro package directory\n" + " --memory-model model\tSet the memory model\n" + " --pagelength n\tSet the page length for the listing\n" + " --smart\t\tEnable smart mode\n" + " --target sys\t\tSet the target system\n" + " --verbose\t\tIncrease verbosity\n" + " --version\t\tPrint the assembler version\n", + ProgName); } @@ -126,14 +129,152 @@ static void Usage (void) static void SetOptions (void) /* Set the option for the translator */ { - char Buf [256]; + StrBuf Buf = STATIC_STRBUF_INITIALIZER; /* Set the translator */ - sprintf (Buf, "ca65 V%u.%u.%u", VER_MAJOR, VER_MINOR, VER_PATCH); - OptTranslator (Buf); + SB_Printf (&Buf, "ca65 V%u.%u.%u", VER_MAJOR, VER_MINOR, VER_PATCH); + OptTranslator (&Buf); /* Set date and time */ OptDateTime ((unsigned long) time(0)); + + /* Release memory for the string */ + SB_Done (&Buf); +} + + + +static void NewSymbol (const char* SymName, long Val) +/* Define a symbol with a fixed numeric value in the current scope */ +{ + ExprNode* Expr; + SymEntry* Sym; + + /* Convert the name to a string buffer */ + StrBuf SymBuf = STATIC_STRBUF_INITIALIZER; + SB_CopyStr (&SymBuf, SymName); + + /* Search for the symbol, allocate a new one if it doesn't exist */ + Sym = SymFind (CurrentScope, &SymBuf, SYM_ALLOC_NEW); + + /* Check if have already a symbol with this name */ + if (SymIsDef (Sym)) { + AbEnd ("`%s' is already defined", SymName); + } + + /* Generate an expression for the symbol */ + Expr = GenLiteralExpr (Val); + + /* Mark the symbol as defined */ + SymDef (Sym, Expr, ADDR_SIZE_DEFAULT, SF_NONE); + + /* Free string buffer memory */ + SB_Done (&SymBuf); +} + + + +static void CBMSystem (const char* Sys) +/* Define a CBM system */ +{ + NewSymbol ("__CBM__", 1); + NewSymbol (Sys, 1); +} + + + +static void SetSys (const char* Sys) +/* Define a target system */ +{ + switch (Target = FindTarget (Sys)) { + + case TGT_NONE: + break; + + case TGT_MODULE: + AbEnd ("Cannot use `module' as a target for the assembler"); + break; + + case TGT_ATARI: + NewSymbol ("__ATARI__", 1); + break; + + case TGT_C16: + CBMSystem ("__C16__"); + break; + + case TGT_C64: + CBMSystem ("__C64__"); + break; + + case TGT_VIC20: + CBMSystem ("__VIC20__"); + break; + + case TGT_C128: + CBMSystem ("__C128__"); + break; + + case TGT_PLUS4: + CBMSystem ("__PLUS4__"); + break; + + case TGT_CBM510: + CBMSystem ("__CBM510__"); + break; + + case TGT_CBM610: + CBMSystem ("__CBM610__"); + break; + + case TGT_PET: + CBMSystem ("__PET__"); + break; + + case TGT_BBC: + NewSymbol ("__BBC__", 1); + break; + + case TGT_APPLE2: + NewSymbol ("__APPLE2__", 1); + break; + + case TGT_APPLE2ENH: + NewSymbol ("__APPLE2ENH__", 1); + break; + + case TGT_GEOS: + /* Do not handle as a CBM system */ + NewSymbol ("__GEOS__", 1); + break; + + case TGT_LUNIX: + NewSymbol ("__LUNIX__", 1); + break; + + case TGT_ATMOS: + NewSymbol ("__ATMOS__", 1); + break; + + case TGT_NES: + NewSymbol ("__NES__", 1); + break; + + case TGT_SUPERVISION: + NewSymbol ("__SUPERVISION__", 1); + break; + + case TGT_LYNX: + NewSymbol ("__LYNX__", 1); + break; + + default: + AbEnd ("Invalid target name: `%s'", Sys); + + } + + /* Initialize the translation tables for the target system */ + TgtTranslateInit (); } @@ -144,26 +285,21 @@ static void DefineSymbol (const char* Def) const char* P; unsigned I; long Val; - char SymName [MAX_STR_LEN+1]; - SymEntry* Sym; - ExprNode* Expr; + StrBuf SymName = AUTO_STRBUF_INITIALIZER; /* The symbol must start with a character or underline */ - if (Def [0] != '_' && !IsAlpha (Def [0])) { + if (!IsIdStart (Def [0])) { InvDef (Def); } P = Def; /* Copy the symbol, checking the rest */ I = 0; - while (IsAlNum (*P) || *P == '_') { - if (I <= MAX_STR_LEN) { - SymName [I++] = *P; - } - ++P; + while (IsIdChar (*P)) { + SB_AppendChar (&SymName, *P++); } - SymName [I] = '\0'; + SB_Terminate (&SymName); /* Do we have a value given? */ if (*P != '=') { @@ -172,39 +308,31 @@ static void DefineSymbol (const char* Def) } Val = 0; } else { - /* We have a value */ - ++P; - if (*P == '$') { - ++P; - if (sscanf (P, "%lx", &Val) != 1) { - InvDef (Def); - } - } else { - if (sscanf (P, "%li", &Val) != 1) { - InvDef (Def); - } + /* We have a value */ + ++P; + if (*P == '$') { + ++P; + if (sscanf (P, "%lx", &Val) != 1) { + InvDef (Def); + } + } else { + if (sscanf (P, "%li", &Val) != 1) { + InvDef (Def); + } } } - /* Search for the symbol, allocate a new one if it doesn't exist */ - Sym = SymFind (CurrentScope, SymName, SYM_ALLOC_NEW); - - /* Check if have already a symbol with this name */ - if (SymIsDef (Sym)) { - AbEnd ("`%s' is already defined", SymName); - } - - /* Generate an expression for the symbol */ - Expr = GenLiteralExpr (Val); + /* Define the new symbol */ + NewSymbol (SB_GetConstBuf (&SymName), Val); - /* Mark the symbol as defined */ - SymDef (Sym, Expr, ADDR_SIZE_DEFAULT, SF_NONE); + /* Release string memory */ + SB_Done (&SymName); } static void OptAutoImport (const char* Opt attribute ((unused)), - const char* Arg attribute ((unused))) + const char* Arg attribute ((unused))) /* Mark unresolved symbols as imported */ { AutoImport = 1; @@ -226,7 +354,7 @@ static void OptCPU (const char* Opt attribute ((unused)), const char* Arg) static void OptDebugInfo (const char* Opt attribute ((unused)), - const char* Arg attribute ((unused))) + const char* Arg attribute ((unused))) /* Add debug info to the object file */ { DbgSyms = 1; @@ -237,14 +365,26 @@ static void OptDebugInfo (const char* Opt attribute ((unused)), static void OptFeature (const char* Opt attribute ((unused)), const char* Arg) /* Set an emulation feature */ { + /* Make a string buffer from Arg */ + StrBuf Feature; + /* Set the feature, check for errors */ - if (SetFeature (Arg) == FEAT_UNKNOWN) { + if (SetFeature (SB_InitFromString (&Feature, Arg)) == FEAT_UNKNOWN) { AbEnd ("Illegal emulation feature: `%s'", Arg); } } +static void OptForgetIncPaths (const char* Opt attribute ((unused)), + const char* Arg attribute ((unused))) +/* Forget all currently defined include paths */ +{ + ForgetAllIncludePaths (); +} + + + static void OptHelp (const char* Opt attribute ((unused)), const char* Arg attribute ((unused))) /* Print usage information and exit */ @@ -303,6 +443,18 @@ static void OptListing (const char* Opt attribute ((unused)), +static void OptMacPackDir (const char* Opt attribute ((unused)), const char* Arg) +/* Set a macro package directory */ +{ + /* Make a string buffer from Arg */ + StrBuf Dir; + + /* Use the directory */ + MacPackSetDir (SB_InitFromString (&Dir, Arg)); +} + + + static void OptMemoryModel (const char* Opt, const char* Arg) /* Set the memory model */ { @@ -351,13 +503,7 @@ static void OptSmart (const char* Opt attribute ((unused)), static void OptTarget (const char* Opt attribute ((unused)), const char* Arg) /* Set the target system */ { - /* Map the target name to a target id */ - Target = FindTarget (Arg); - if (Target == TGT_UNKNOWN) { - AbEnd ("Invalid target name: `%s'", Arg); - } else if (Target == TGT_MODULE) { - AbEnd ("Cannot use `module' as a target for the assembler"); - } + SetSys (Arg); } @@ -389,7 +535,7 @@ static void DoPCAssign (void) if (PC < 0 || PC > 0xFFFFFF) { Error ("Range error"); } else { - SetAbsPC (PC); + EnterAbsoluteMode (PC); } } @@ -423,13 +569,13 @@ static void OneLine (void) if (Tok == TOK_IDENT) { if (!UbiquitousIdents) { /* Macros and symbols cannot use instruction names */ - Instr = FindInstruction (SVal); + Instr = FindInstruction (&SVal); if (Instr < 0) { - Macro = IsMacro (SVal); + Macro = IsMacro (&SVal); } } else { /* Macros and symbols may use the names of instructions */ - Macro = IsMacro (SVal); + Macro = IsMacro (&SVal); } } @@ -441,9 +587,9 @@ static void OneLine (void) /* Generate the symbol table entry, then skip the name */ if (Tok == TOK_IDENT) { - Sym = SymFind (CurrentScope, SVal, SYM_ALLOC_NEW); + Sym = SymFind (CurrentScope, &SVal, SYM_ALLOC_NEW); } else { - Sym = SymFindLocal (SymLast, SVal, SYM_ALLOC_NEW); + Sym = SymFindLocal (SymLast, &SVal, SYM_ALLOC_NEW); } NextTok (); @@ -451,16 +597,41 @@ static void OneLine (void) * is no colon, it's an assignment. */ if (Tok == TOK_EQ || Tok == TOK_ASSIGN) { - /* If it's an assign token, we have a label */ + + /* Determine the symbol flags from the assignment token */ unsigned Flags = (Tok == TOK_ASSIGN)? SF_LABEL : SF_NONE; + /* Skip the '=' */ NextTok (); + /* Define the symbol with the expression following the '=' */ SymDef (Sym, Expression(), ADDR_SIZE_DEFAULT, Flags); + /* Don't allow anything after a symbol definition */ ConsumeSep (); return; + + } else if (Tok == TOK_SET) { + + ExprNode* Expr; + + /* .SET defines variables (= redefinable symbols) */ + NextTok (); + + /* Read the assignment expression, which must be constant */ + Expr = GenLiteralExpr (ConstExpression ()); + + /* Define the symbol with the constant expression following + * the '=' + */ + SymDef (Sym, Expr, ADDR_SIZE_DEFAULT, SF_VAR); + + /* Don't allow anything after a symbol definition */ + ConsumeSep (); + return; + } else { + /* A label. Remember the current segment, so we can later * determine the size of the data stored under the label. */ @@ -493,13 +664,13 @@ static void OneLine (void) if (Tok == TOK_IDENT) { if (!UbiquitousIdents) { /* Macros and symbols cannot use instruction names */ - Instr = FindInstruction (SVal); + Instr = FindInstruction (&SVal); if (Instr < 0) { - Macro = IsMacro (SVal); + Macro = IsMacro (&SVal); } } else { /* Macros and symbols may use the names of instructions */ - Macro = IsMacro (SVal); + Macro = IsMacro (&SVal); } } } @@ -513,7 +684,7 @@ static void OneLine (void) /* A macro expansion */ MacExpandStart (); } else if (Instr >= 0 || - (UbiquitousIdents && ((Instr = FindInstruction (SVal)) >= 0))) { + (UbiquitousIdents && ((Instr = FindInstruction (&SVal)) >= 0))) { /* A mnemonic - assemble one instruction */ HandleInstruction (Instr); } else if (PCAssignment && (Tok == TOK_STAR || Tok == TOK_PC)) { @@ -613,11 +784,13 @@ int main (int argc, char* argv []) { "--cpu", 1, OptCPU }, { "--debug-info", 0, OptDebugInfo }, { "--feature", 1, OptFeature }, + { "--forget-inc-paths", 0, OptForgetIncPaths }, { "--help", 0, OptHelp }, { "--ignore-case", 0, OptIgnoreCase }, { "--include-dir", 1, OptIncludeDir }, { "--list-bytes", 1, OptListBytes }, { "--listing", 0, OptListing }, + { "--macpack-dir", 1, OptMacPackDir }, { "--memory-model", 1, OptMemoryModel }, { "--pagelength", 1, OptPageLength }, { "--smart", 0, OptSmart }, @@ -626,15 +799,21 @@ int main (int argc, char* argv []) { "--version", 0, OptVersion }, }; + /* Name of the global name space */ + static const StrBuf GlobalNameSpace = STATIC_STRBUF_INITIALIZER; + unsigned I; /* Initialize the cmdline module */ InitCmdLine (&argc, &argv, "ca65"); + /* Initialize the include search paths */ + InitIncludePaths (); + /* Enter the base lexical level. We must do that here, since we may * define symbols using -D. */ - SymEnterLevel ("", ST_GLOBAL, ADDR_SIZE_DEFAULT); + SymEnterLevel (&GlobalNameSpace, ST_GLOBAL, ADDR_SIZE_DEFAULT); /* Check the parameters */ I = 1; @@ -751,9 +930,6 @@ int main (int argc, char* argv []) SetMemoryModel (MMODEL_NEAR); } - /* Intialize the target translation tables */ - TgtTranslateInit (); - /* Initialize the segments */ InitSegments (); @@ -786,6 +962,11 @@ int main (int argc, char* argv []) SegCheck (); } + /* If we didn't have any errors, check the assertions */ + if (ErrorCount == 0) { + CheckAssertions (); + } + /* If we didn't have an errors, index the line infos */ MakeLineInfoIndex ();