X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fca65%2Fmain.c;h=1da0ff36d717ff3ff1f376b3c4f62c8a1879d715;hb=07f840f11c8a502b85c95d2ef7baa44bd690bd90;hp=aaf0bd80223caf2907da52f172afe56c609bfd64;hpb=3fd52eb57faca1e92368c245ce6dc11bfe92fa5c;p=cc65 diff --git a/src/ca65/main.c b/src/ca65/main.c index aaf0bd802..1da0ff36d 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -1,12 +1,12 @@ /*****************************************************************************/ /* */ -/* main.c */ +/* main.c */ /* */ -/* Main program for the ca65 macroassembler */ +/* Main program for the ca65 macroassembler */ /* */ /* */ /* */ -/* (C) 1998-2010, Ullrich von Bassewitz */ +/* (C) 1998-2013, Ullrich von Bassewitz */ /* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ @@ -42,8 +42,10 @@ #include "addrsize.h" #include "chartype.h" #include "cmdline.h" +#include "debugflag.h" #include "mmodel.h" #include "print.h" +#include "scopedefs.h" #include "strbuf.h" #include "target.h" #include "tgttrans.h" @@ -52,6 +54,7 @@ /* ca65 */ #include "abend.h" #include "asserts.h" +#include "dbginfo.h" #include "error.h" #include "expr.h" #include "feature.h" @@ -62,7 +65,6 @@ #include "istack.h" #include "lineinfo.h" #include "listing.h" -#include "macpack.h" #include "macro.h" #include "nexttok.h" #include "objfile.h" @@ -71,6 +73,7 @@ #include "scanner.h" #include "segment.h" #include "sizeof.h" +#include "span.h" #include "spool.h" #include "symbol.h" #include "symtab.h" @@ -79,7 +82,7 @@ /*****************************************************************************/ -/* Code */ +/* Code */ /*****************************************************************************/ @@ -94,10 +97,11 @@ static void Usage (void) " -U\t\t\t\tMark unresolved symbols as import\n" " -V\t\t\t\tPrint the assembler version\n" " -W n\t\t\t\tSet warning level n\n" + " -d\t\t\t\tDebug mode\n" " -g\t\t\t\tAdd debug info to object file\n" " -h\t\t\t\tHelp (this text)\n" " -i\t\t\t\tIgnore case of symbols\n" - " -l\t\t\t\tCreate a listing if assembly was ok\n" + " -l name\t\t\tCreate a listing file if assembly was ok\n" " -mm model\t\t\tSet the memory model\n" " -o name\t\t\tName the output file\n" " -s\t\t\t\tEnable smart mode\n" @@ -110,17 +114,19 @@ static void Usage (void) " --cpu type\t\t\tSet cpu type\n" " --create-dep name\t\tCreate a make dependency file\n" " --create-full-dep name\tCreate a full make dependency file\n" + " --debug\t\t\tDebug mode\n" " --debug-info\t\t\tAdd debug info to object file\n" " --feature name\t\tSet an emulation feature\n" - " --forget-inc-paths\t\tForget include search paths\n" " --help\t\t\tHelp (this text)\n" " --ignore-case\t\t\tIgnore case of symbols\n" " --include-dir dir\t\tSet an include directory search path\n" - " --listing\t\t\tCreate a listing if assembly was ok\n" + " --large-alignment\t\tDon't warn about large alignments\n" + " --listing name\t\tCreate a listing file if assembly was ok\n" " --list-bytes n\t\tMaximum number of bytes per listing line\n" " --macpack-dir dir\t\tSet a macro package directory\n" " --memory-model model\t\tSet the memory model\n" " --pagelength n\t\tSet the page length for the listing\n" + " --relax-checks\t\tRelax some checks (see docs)\n" " --smart\t\t\tEnable smart mode\n" " --target sys\t\t\tSet the target system\n" " --verbose\t\t\tIncrease verbosity\n" @@ -163,7 +169,7 @@ static void NewSymbol (const char* SymName, long Val) /* Check if have already a symbol with this name */ if (SymIsDef (Sym)) { - AbEnd ("`%s' is already defined", SymName); + AbEnd ("`%s' is already defined", SymName); } /* Generate an expression for the symbol */ @@ -192,87 +198,136 @@ static void SetSys (const char* Sys) { switch (Target = FindTarget (Sys)) { - case TGT_NONE: - break; + 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_ATARI2600: + NewSymbol ("__ATARI2600__", 1); + break; - case TGT_C16: - CBMSystem ("__C16__"); - break; + case TGT_ATARI5200: + NewSymbol ("__ATARI5200__", 1); + break; + + case TGT_ATARI: + NewSymbol ("__ATARI__", 1); + break; + + case TGT_ATARIXL: + NewSymbol ("__ATARI__", 1); + NewSymbol ("__ATARIXL__", 1); + break; + + case TGT_C16: + CBMSystem ("__C16__"); + break; - case TGT_C64: - CBMSystem ("__C64__"); - break; + case TGT_C64: + CBMSystem ("__C64__"); + break; - case TGT_VIC20: - CBMSystem ("__VIC20__"); - break; + case TGT_C65: + CBMSystem ("__C65__"); + break; - case TGT_C128: - CBMSystem ("__C128__"); - break; + case TGT_VIC20: + CBMSystem ("__VIC20__"); + break; - case TGT_PLUS4: - CBMSystem ("__PLUS4__"); - break; + case TGT_C128: + CBMSystem ("__C128__"); + break; - case TGT_CBM510: - CBMSystem ("__CBM510__"); - break; + case TGT_PLUS4: + CBMSystem ("__C16__"); + NewSymbol ("__PLUS4__", 1); + break; - case TGT_CBM610: - CBMSystem ("__CBM610__"); - break; + case TGT_CBM510: + CBMSystem ("__CBM510__"); + break; - case TGT_PET: - CBMSystem ("__PET__"); - break; + case TGT_CBM610: + CBMSystem ("__CBM610__"); + break; - case TGT_BBC: - NewSymbol ("__BBC__", 1); - break; + case TGT_PET: + CBMSystem ("__PET__"); + break; - case TGT_APPLE2: - NewSymbol ("__APPLE2__", 1); - break; + case TGT_APPLE2: + NewSymbol ("__APPLE2__", 1); + break; - case TGT_APPLE2ENH: + case TGT_APPLE2ENH: + NewSymbol ("__APPLE2__", 1); NewSymbol ("__APPLE2ENH__", 1); - break; + break; - case TGT_GEOS: - /* Do not handle as a CBM system */ - NewSymbol ("__GEOS__", 1); - break; + case TGT_GAMATE: + NewSymbol ("__GAMATE__", 1); + break; - case TGT_LUNIX: - NewSymbol ("__LUNIX__", 1); - break; + case TGT_GEOS_CBM: + /* Do not handle as a CBM system */ + NewSymbol ("__GEOS__", 1); + NewSymbol ("__GEOS_CBM__", 1); + break; case TGT_ATMOS: NewSymbol ("__ATMOS__", 1); break; - case TGT_NES: - NewSymbol ("__NES__", 1); + case TGT_BBC: + NewSymbol ("__BBC__", 1); break; - case TGT_SUPERVISION: - NewSymbol ("__SUPERVISION__", 1); + case TGT_CREATIVISION: + NewSymbol ("__CREATIVISION__", 1); + break; + + case TGT_GEOS_APPLE: + NewSymbol ("__GEOS__", 1); + NewSymbol ("__GEOS_APPLE__", 1); + break; + + case TGT_LUNIX: + NewSymbol ("__LUNIX__", 1); break; case TGT_LYNX: NewSymbol ("__LYNX__", 1); break; - default: + case TGT_NES: + NewSymbol ("__NES__", 1); + break; + + case TGT_SIM6502: + NewSymbol ("__SIM6502__", 1); + break; + + case TGT_SIM65C02: + NewSymbol ("__SIM65C02__", 1); + break; + + case TGT_OSIC1P: + NewSymbol ("__OSIC1P__", 1); + break; + + case TGT_PCENGINE: + NewSymbol ("__PCE__", 1); + break; + + case TGT_SUPERVISION: + NewSymbol ("__SUPERVISION__", 1); + break; + + default: AbEnd ("Invalid target name: `%s'", Sys); } @@ -301,19 +356,17 @@ static void DefineSymbol (const char* Def) /* Define a symbol from the command line */ { const char* P; - unsigned I; long Val; StrBuf SymName = AUTO_STRBUF_INITIALIZER; /* The symbol must start with a character or underline */ if (!IsIdStart (Def [0])) { - InvDef (Def); + InvDef (Def); } P = Def; /* Copy the symbol, checking the rest */ - I = 0; while (IsIdChar (*P)) { SB_AppendChar (&SymName, *P++); } @@ -321,23 +374,23 @@ static void DefineSymbol (const char* Def) /* Do we have a value given? */ if (*P != '=') { - if (*P != '\0') { - InvDef (Def); - } - Val = 0; + if (*P != '\0') { + InvDef (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); + } + } } /* Define the new symbol */ @@ -350,7 +403,7 @@ static void DefineSymbol (const char* Def) 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; @@ -361,7 +414,7 @@ static void OptAutoImport (const char* Opt attribute ((unused)), static void OptBinIncludeDir (const char* Opt attribute ((unused)), const char* Arg) /* Add an include search path for binaries */ { - AddIncludePath (Arg, INC_BIN); + AddSearchPath (BinSearchPath, Arg); } @@ -371,9 +424,9 @@ static void OptCPU (const char* Opt attribute ((unused)), const char* Arg) { cpu_t CPU = FindCPU (Arg); if (CPU == CPU_UNKNOWN) { - AbEnd ("Invalid CPU: `%s'", Arg); + AbEnd ("Invalid CPU: `%s'", Arg); } else { - SetCPU (CPU); + SetCPU (CPU); } } @@ -388,7 +441,7 @@ static void OptCreateDep (const char* Opt, const char* Arg) static void OptCreateFullDep (const char* Opt attribute ((unused)), - const char* Arg) + const char* Arg) /* Handle the --create-full-dep option */ { FileNameOption (Opt, Arg, &FullDepName); @@ -396,8 +449,17 @@ static void OptCreateFullDep (const char* Opt attribute ((unused)), +static void OptDebug (const char* Opt attribute ((unused)), + const char* Arg attribute ((unused))) +/* Compiler debug mode */ +{ + ++Debug; +} + + + 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; @@ -413,23 +475,14 @@ static void OptFeature (const char* Opt attribute ((unused)), const char* Arg) /* Set the feature, check for errors */ if (SetFeature (SB_InitFromString (&Feature, Arg)) == FEAT_UNKNOWN) { - AbEnd ("Illegal emulation feature: `%s'", Arg); + 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))) + const char* Arg attribute ((unused))) /* Print usage information and exit */ { Usage (); @@ -439,7 +492,7 @@ static void OptHelp (const char* Opt attribute ((unused)), static void OptIgnoreCase (const char* Opt attribute ((unused)), - const char* Arg attribute ((unused))) + const char* Arg attribute ((unused))) /* Ignore case on symbols */ { IgnoreCase = 1; @@ -450,7 +503,16 @@ static void OptIgnoreCase (const char* Opt attribute ((unused)), static void OptIncludeDir (const char* Opt attribute ((unused)), const char* Arg) /* Add an include search path */ { - AddIncludePath (Arg, INC_STD); + AddSearchPath (IncSearchPath, Arg); +} + + + +static void OptLargeAlignment (const char* Opt attribute ((unused)), + const char* Arg attribute ((unused))) +/* Don't warn about large alignments */ +{ + LargeAlignment = 1; } @@ -477,23 +539,19 @@ static void OptListBytes (const char* Opt, const char* Arg) -static void OptListing (const char* Opt attribute ((unused)), - const char* Arg attribute ((unused))) +static void OptListing (const char* Opt, const char* Arg) /* Create a listing file */ { - Listing = 1; -} - - - -static void OptMacPackDir (const char* Opt attribute ((unused)), const char* Arg) -/* Set a macro package directory */ -{ - /* Make a string buffer from Arg */ - StrBuf Dir; + /* Since the meaning of -l and --listing has changed, print an error if + ** the filename is empty or begins with the option char. + */ + if (Arg == 0 || *Arg == '\0' || *Arg == '-') { + Fatal ("The meaning of `%s' has changed. It does now " + "expect a file name as argument.", Opt); + } - /* Use the directory */ - MacPackSetDir (SB_InitFromString (&Dir, Arg)); + /* Get the file name */ + FileNameOption (Opt, Arg, &ListingName); } @@ -527,15 +585,24 @@ static void OptPageLength (const char* Opt attribute ((unused)), const char* Arg { int Len = atoi (Arg); if (Len != -1 && (Len < MIN_PAGE_LEN || Len > MAX_PAGE_LEN)) { - AbEnd ("Invalid page length: %d", Len); + AbEnd ("Invalid page length: %d", Len); } PageLength = Len; } +static void OptRelaxChecks (const char* Opt attribute ((unused)), + const char* Arg attribute ((unused))) +/* Handle the --relax-checks options */ +{ + RelaxChecks = 1; +} + + + static void OptSmart (const char* Opt attribute ((unused)), - const char* Arg attribute ((unused))) + const char* Arg attribute ((unused))) /* Handle the -s/--smart options */ { SmartMode = 1; @@ -552,7 +619,7 @@ static void OptTarget (const char* Opt attribute ((unused)), const char* Arg) static void OptVerbose (const char* Opt attribute ((unused)), - const char* Arg attribute ((unused))) + const char* Arg attribute ((unused))) /* Increase verbosity */ { ++Verbosity; @@ -561,10 +628,11 @@ static void OptVerbose (const char* Opt attribute ((unused)), static void OptVersion (const char* Opt attribute ((unused)), - const char* Arg attribute ((unused))) + const char* Arg attribute ((unused))) /* Print the assembler version */ { - fprintf (stderr, "ca65 V%s - %s\n", GetVersionAsString (), Copyright); + fprintf (stderr, "%s V%s\n", ProgName, GetVersionAsString ()); + exit(EXIT_SUCCESS); } @@ -574,9 +642,9 @@ static void DoPCAssign (void) { long PC = ConstExpression (); if (PC < 0 || PC > 0xFFFFFF) { - Error ("Range error"); + Error ("Range error"); } else { - EnterAbsoluteMode (PC); + EnterAbsoluteMode (PC); } } @@ -588,64 +656,62 @@ static void OneLine (void) Segment* Seg = 0; unsigned long PC = 0; SymEntry* Sym = 0; - int Macro = 0; + Macro* Mac = 0; int Instr = -1; /* Initialize the new listing line if we are actually reading from file - * and not from internally pushed input. - */ + ** and not from internally pushed input. + */ if (!HavePushedInput ()) { - InitListingLine (); + InitListingLine (); } - if (Tok == TOK_COLON) { - /* An unnamed label */ - ULabDef (); - NextTok (); + /* Single colon means unnamed label */ + if (CurTok.Tok == TOK_COLON) { + ULabDef (); + NextTok (); } /* If the first token on the line is an identifier, check for a macro or - * an instruction. - */ - if (Tok == TOK_IDENT) { - if (!UbiquitousIdents) { - /* Macros and symbols cannot use instruction names */ - Instr = FindInstruction (&SVal); - if (Instr < 0) { - Macro = IsMacro (&SVal); + ** an instruction. + */ + if (CurTok.Tok == TOK_IDENT) { + if (UbiquitousIdents) { + /* Macros CAN be instructions, so check for them first */ + Mac = FindMacro (&CurTok.SVal); + if (Mac == 0) { + Instr = FindInstruction (&CurTok.SVal); } } else { - /* Macros and symbols may use the names of instructions */ - Macro = IsMacro (&SVal); + /* Macros and symbols may NOT use the names of instructions */ + Instr = FindInstruction (&CurTok.SVal); + if (Instr < 0) { + Mac = FindMacro (&CurTok.SVal); + } } } /* Handle an identifier. This may be a cheap local symbol, or a fully - * scoped identifier which may start with a namespace token (for global - * namespace) - */ - if (Tok == TOK_LOCAL_IDENT || - Tok == TOK_NAMESPACE || - (Tok == TOK_IDENT && Instr < 0 && !Macro)) { + ** scoped identifier which may start with a namespace token (for global + ** namespace) + */ + if (CurTok.Tok == TOK_LOCAL_IDENT || + CurTok.Tok == TOK_NAMESPACE || + (CurTok.Tok == TOK_IDENT && Instr < 0 && Mac == 0)) { /* Did we have whitespace before the ident? */ - int HadWS = WS; + int HadWS = CurTok.WS; /* Generate the symbol table entry, then skip the name */ - if (Tok == TOK_LOCAL_IDENT) { - Sym = SymFindLocal (SymLast, &SVal, SYM_ALLOC_NEW); - NextTok (); - } else { - Sym = ParseScopedSymName (SYM_ALLOC_NEW); - } + Sym = ParseAnySymName (SYM_ALLOC_NEW); /* If a colon follows, this is a label definition. If there - * is no colon, it's an assignment. - */ - if (Tok == TOK_EQ || Tok == TOK_ASSIGN) { + ** is no colon, it's an assignment. + */ + if (CurTok.Tok == TOK_EQ || CurTok.Tok == TOK_ASSIGN) { /* Determine the symbol flags from the assignment token */ - unsigned Flags = (Tok == TOK_ASSIGN)? SF_LABEL : SF_NONE; + unsigned Flags = (CurTok.Tok == TOK_ASSIGN)? SF_LABEL : SF_NONE; /* Skip the '=' */ NextTok (); @@ -657,7 +723,7 @@ static void OneLine (void) ConsumeSep (); return; - } else if (Tok == TOK_SET) { + } else if (CurTok.Tok == TOK_SET) { ExprNode* Expr; @@ -668,8 +734,8 @@ static void OneLine (void) Expr = GenLiteralExpr (ConstExpression ()); /* Define the symbol with the constant expression following - * the '=' - */ + ** the '=' + */ SymDef (Sym, Expr, ADDR_SIZE_DEFAULT, SF_VAR); /* Don't allow anything after a symbol definition */ @@ -679,8 +745,8 @@ static void OneLine (void) } else { /* A label. Remember the current segment, so we can later - * determine the size of the data stored under the label. - */ + ** determine the size of the data stored under the label. + */ Seg = ActiveSeg; PC = GetPC (); @@ -688,14 +754,14 @@ static void OneLine (void) SymDef (Sym, GenCurrentPC (), ADDR_SIZE_DEFAULT, SF_LABEL); /* Skip the colon. If NoColonLabels is enabled, allow labels - * without a colon if there is no whitespace before the - * identifier. - */ - if (Tok != TOK_COLON) { + ** without a colon if there is no whitespace before the + ** identifier. + */ + if (CurTok.Tok != TOK_COLON) { if (HadWS || !NoColonLabels) { Error ("`:' expected"); /* Try some smart error recovery */ - if (Tok == TOK_NAMESPACE) { + if (CurTok.Tok == TOK_NAMESPACE) { NextTok (); } } @@ -705,37 +771,39 @@ static void OneLine (void) } /* If we come here, a new identifier may be waiting, which may - * be a macro or instruction. - */ - if (Tok == TOK_IDENT) { - if (!UbiquitousIdents) { - /* Macros and symbols cannot use instruction names */ - Instr = FindInstruction (&SVal); - if (Instr < 0) { - Macro = IsMacro (&SVal); + ** be a macro or instruction. + */ + if (CurTok.Tok == TOK_IDENT) { + if (UbiquitousIdents) { + /* Macros CAN be instructions, so check for them first */ + Mac = FindMacro (&CurTok.SVal); + if (Mac == 0) { + Instr = FindInstruction (&CurTok.SVal); } } else { - /* Macros and symbols may use the names of instructions */ - Macro = IsMacro (&SVal); + /* Macros and symbols may NOT use the names of instructions */ + Instr = FindInstruction (&CurTok.SVal); + if (Instr < 0) { + Mac = FindMacro (&CurTok.SVal); + } } } } } /* We've handled a possible label, now handle the remainder of the line */ - if (Tok >= TOK_FIRSTPSEUDO && Tok <= TOK_LASTPSEUDO) { + if (CurTok.Tok >= TOK_FIRSTPSEUDO && CurTok.Tok <= TOK_LASTPSEUDO) { /* A control command */ HandlePseudo (); - } else if (Macro) { + } else if (Mac != 0) { /* A macro expansion */ - MacExpandStart (); - } else if (Instr >= 0 || - (UbiquitousIdents && ((Instr = FindInstruction (&SVal)) >= 0))) { + MacExpandStart (Mac); + } else if (Instr >= 0) { /* A mnemonic - assemble one instruction */ HandleInstruction (Instr); - } else if (PCAssignment && (Tok == TOK_STAR || Tok == TOK_PC)) { + } else if (PCAssignment && (CurTok.Tok == TOK_STAR || CurTok.Tok == TOK_PC)) { NextTok (); - if (Tok != TOK_EQ) { + if (CurTok.Tok != TOK_EQ) { Error ("`=' expected"); SkipUntilSep (); } else { @@ -747,9 +815,9 @@ static void OneLine (void) } /* If we have defined a label, remember its size. Sym is also set by - * a symbol assignment, but in this case Done is false, so we don't - * come here. - */ + ** a symbol assignment, but in this case Done is false, so we don't + ** come here. + */ if (Sym) { unsigned long Size; if (Seg == ActiveSeg) { @@ -775,8 +843,8 @@ static void Assemble (void) NextTok (); /* Assemble lines until end of file */ - while (Tok != TOK_EOF) { - OneLine (); + while (CurTok.Tok != TOK_EOF) { + OneLine (); } } @@ -806,8 +874,11 @@ static void CreateObjFile (void) /* Write debug symbols if requested */ WriteDbgSyms (); + /* Write the scopes if requested */ + WriteScopes (); + /* Write line infos if requested */ - WriteLineInfo (); + WriteLineInfos (); /* Write the string pool */ WriteStrPool (); @@ -815,6 +886,9 @@ static void CreateObjFile (void) /* Write the assertions */ WriteAssertions (); + /* Write the spans */ + WriteSpans (); + /* Write an updated header and close the file */ ObjClose (); } @@ -826,26 +900,27 @@ int main (int argc, char* argv []) { /* Program long options */ static const LongOpt OptTab[] = { - { "--auto-import", 0, OptAutoImport }, + { "--auto-import", 0, OptAutoImport }, { "--bin-include-dir", 1, OptBinIncludeDir }, - { "--cpu", 1, OptCPU }, + { "--cpu", 1, OptCPU }, { "--create-dep", 1, OptCreateDep }, { "--create-full-dep", 1, OptCreateFullDep }, - { "--debug-info", 0, OptDebugInfo }, - { "--feature", 1, OptFeature }, - { "--forget-inc-paths", 0, OptForgetIncPaths }, - { "--help", 0, OptHelp }, - { "--ignore-case", 0, OptIgnoreCase }, - { "--include-dir", 1, OptIncludeDir }, + { "--debug", 0, OptDebug }, + { "--debug-info", 0, OptDebugInfo }, + { "--feature", 1, OptFeature }, + { "--help", 0, OptHelp }, + { "--ignore-case", 0, OptIgnoreCase }, + { "--include-dir", 1, OptIncludeDir }, + { "--large-alignment", 0, OptLargeAlignment }, { "--list-bytes", 1, OptListBytes }, - { "--listing", 0, OptListing }, - { "--macpack-dir", 1, OptMacPackDir }, + { "--listing", 1, OptListing }, { "--memory-model", 1, OptMemoryModel }, - { "--pagelength", 1, OptPageLength }, - { "--smart", 0, OptSmart }, - { "--target", 1, OptTarget }, - { "--verbose", 0, OptVerbose }, - { "--version", 0, OptVersion }, + { "--pagelength", 1, OptPageLength }, + { "--relax-checks", 0, OptRelaxChecks }, + { "--smart", 0, OptSmart }, + { "--target", 1, OptTarget }, + { "--verbose", 0, OptVerbose }, + { "--version", 0, OptVersion }, }; /* Name of the global name space */ @@ -856,44 +931,59 @@ int main (int argc, char* argv []) /* Initialize the cmdline module */ InitCmdLine (&argc, &argv, "ca65"); + /* Initialize the string pool */ + InitStrPool (); + /* Initialize the include search paths */ InitIncludePaths (); + /* Create the predefined segments */ + SegInit (); + /* Enter the base lexical level. We must do that here, since we may - * define symbols using -D. - */ - SymEnterLevel (&GlobalNameSpace, ST_GLOBAL, ADDR_SIZE_DEFAULT); + ** define symbols using -D. + */ + SymEnterLevel (&GlobalNameSpace, SCOPE_FILE, ADDR_SIZE_DEFAULT, 0); + + /* Initialize the line infos. Must be done here, since we need line infos + ** for symbol definitions. + */ + InitLineInfo (); /* Check the parameters */ I = 1; while (I < ArgCount) { - /* Get the argument */ - const char* Arg = ArgVec [I]; + /* Get the argument */ + const char* Arg = ArgVec [I]; - /* Check for an option */ - if (Arg[0] == '-') { - switch (Arg[1]) { + /* Check for an option */ + if (Arg[0] == '-') { + switch (Arg[1]) { - case '-': - LongOption (&I, OptTab, sizeof(OptTab)/sizeof(OptTab[0])); - break; + case '-': + LongOption (&I, OptTab, sizeof(OptTab)/sizeof(OptTab[0])); + break; - case 'g': - OptDebugInfo (Arg, 0); - break; + case 'd': + OptDebug (Arg, 0); + break; - case 'h': - OptHelp (Arg, 0); - break; + case 'g': + OptDebugInfo (Arg, 0); + break; - case 'i': - OptIgnoreCase (Arg, 0); - break; + case 'h': + OptHelp (Arg, 0); + break; + + case 'i': + OptIgnoreCase (Arg, 0); + break; - case 'l': - OptListing (Arg, 0); - break; + case 'l': + OptListing (Arg, GetArg (&I, 2)); + break; case 'm': if (Arg[2] == 'm') { @@ -903,72 +993,75 @@ int main (int argc, char* argv []) } break; - case 'o': - OutFile = GetArg (&I, 2); - break; - - case 's': - OptSmart (Arg, 0); - break; - - case 't': - OptTarget (Arg, GetArg (&I, 2)); - break; - - case 'v': - OptVerbose (Arg, 0); - break; - - case 'D': - DefineSymbol (GetArg (&I, 2)); - break; - - case 'I': - OptIncludeDir (Arg, GetArg (&I, 2)); - break; - - case 'U': - OptAutoImport (Arg, 0); - break; - - case 'V': - OptVersion (Arg, 0); - break; - - case 'W': - WarnLevel = atoi (GetArg (&I, 2)); - break; - - default: - UnknownOption (Arg); - break; - - } - } else { - /* Filename. Check if we already had one */ - if (InFile) { - fprintf (stderr, "%s: Don't know what to do with `%s'\n", - ProgName, Arg); - exit (EXIT_FAILURE); - } else { - InFile = Arg; - } - } - - /* Next argument */ - ++I; + case 'o': + OutFile = GetArg (&I, 2); + break; + + case 's': + OptSmart (Arg, 0); + break; + + case 't': + OptTarget (Arg, GetArg (&I, 2)); + break; + + case 'v': + OptVerbose (Arg, 0); + break; + + case 'D': + DefineSymbol (GetArg (&I, 2)); + break; + + case 'I': + OptIncludeDir (Arg, GetArg (&I, 2)); + break; + + case 'U': + OptAutoImport (Arg, 0); + break; + + case 'V': + OptVersion (Arg, 0); + break; + + case 'W': + WarnLevel = atoi (GetArg (&I, 2)); + break; + + default: + UnknownOption (Arg); + break; + + } + } else { + /* Filename. Check if we already had one */ + if (InFile) { + fprintf (stderr, "%s: Don't know what to do with `%s'\n", + ProgName, Arg); + exit (EXIT_FAILURE); + } else { + InFile = Arg; + } + } + + /* Next argument */ + ++I; } /* Do we have an input file? */ if (InFile == 0) { - fprintf (stderr, "%s: No input files\n", ProgName); - exit (EXIT_FAILURE); + fprintf (stderr, "%s: No input files\n", ProgName); + exit (EXIT_FAILURE); } + /* Add the default include search paths. */ + FinishIncludePaths (); + /* If no CPU given, use the default CPU for the target */ if (GetCPU () == CPU_UNKNOWN) { if (Target != TGT_UNKNOWN) { - SetCPU (DefaultCPU[Target]); + SetCPU (GetTargetProperties (Target)->DefaultCPU); } else { SetCPU (CPU_6502); } @@ -979,8 +1072,8 @@ int main (int argc, char* argv []) SetMemoryModel (MMODEL_NEAR); } - /* Initialize the segments */ - InitSegments (); + /* Set the default segment sizes according to the memory model */ + SetSegmentSizes (); /* Initialize the scanner, open the input file */ InitScanner (InFile); @@ -996,9 +1089,9 @@ int main (int argc, char* argv []) CheckPseudo (); } - /* If we didn't have any errors, check the unnamed labels */ + /* If we didn't have any errors, check and cleanup the unnamed labels */ if (ErrorCount == 0) { - ULabCheck (); + ULabDone (); } /* If we didn't have any errors, check the symbol table */ @@ -1006,9 +1099,19 @@ int main (int argc, char* argv []) SymCheck (); } + /* If we didn't have any errors, check the hll debug symbols */ + if (ErrorCount == 0) { + DbgInfoCheck (); + } + + /* If we didn't have any errors, close the file scope lexical level */ + if (ErrorCount == 0) { + SymLeaveLevel (); + } + /* If we didn't have any errors, check and resolve the segment data */ if (ErrorCount == 0) { - SegCheck (); + SegDone (); } /* If we didn't have any errors, check the assertions */ @@ -1016,23 +1119,23 @@ int main (int argc, char* argv []) CheckAssertions (); } - /* If we didn't have an errors, index the line infos */ - MakeLineInfoIndex (); - /* Dump the data */ if (Verbosity >= 2) { SymDump (stdout); SegDump (); } - /* If we didn't have any errors, create the object, listing and - * dependency files - */ + /* If we didn't have an errors, finish off the line infos */ + DoneLineInfo (); + + /* If we didn't have any errors, create the object, listing and + ** dependency files + */ if (ErrorCount == 0) { - CreateObjFile (); - if (Listing) { - CreateListing (); - } + CreateObjFile (); + if (SB_GetLen (&ListingName) > 0) { + CreateListing (); + } CreateDependencies (); } @@ -1042,6 +1145,3 @@ int main (int argc, char* argv []) /* Return an apropriate exit code */ return (ErrorCount == 0)? EXIT_SUCCESS : EXIT_FAILURE; } - - -