]> git.sur5r.net Git - cc65/blobdiff - src/ca65/main.c
Renamed some stuff. Write out the segment size as var, not 32 bit.
[cc65] / src / ca65 / main.c
index 42b2891b0486b5b900a2faa1328c2722d923e711..7364891bc7208c54fac12eed9fbde5f7bd8c7678 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2004 Ullrich von Bassewitz                                       */
-/*               Römerstraße 52                                              */
-/*               D-70794 Filderstadt                                         */
-/* EMail:        uz@cc65.org                                                 */
+/* (C) 1998-2011, 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,8 @@
 #include "cmdline.h"
 #include "mmodel.h"
 #include "print.h"
+#include "scopedefs.h"
+#include "strbuf.h"
 #include "target.h"
 #include "tgttrans.h"
 #include "version.h"
@@ -61,6 +63,7 @@
 #include "istack.h"
 #include "lineinfo.h"
 #include "listing.h"
+#include "macpack.h"
 #include "macro.h"
 #include "nexttok.h"
 #include "objfile.h"
@@ -70,6 +73,7 @@
 #include "segment.h"
 #include "sizeof.h"
 #include "spool.h"
+#include "symbol.h"
 #include "symtab.h"
 #include "ulabel.h"
 
@@ -86,37 +90,42 @@ static void Usage (void)
 {
     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"
+            "  -D name[=value]\t\tDefine a symbol\n"
+            "  -I dir\t\t\tSet an include directory search path\n"
+            "  -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"
+            "  -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 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"
+            "  -t sys\t\t\tSet the target system\n"
+            "  -v\t\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",
+            "  --auto-import\t\t\tMark unresolved symbols as import\n"
+            "  --bin-include-dir dir\t\tSet a search path for binary includes\n"
+            "  --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-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 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"
+            "  --smart\t\t\tEnable smart mode\n"
+            "  --target sys\t\t\tSet the target system\n"
+            "  --verbose\t\t\tIncrease verbosity\n"
+            "  --version\t\t\tPrint the assembler version\n",
             ProgName);
 }
 
@@ -125,14 +134,17 @@ 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%s", GetVersionAsString ());
+    OptTranslator (&Buf);
 
     /* Set date and time */
     OptDateTime ((unsigned long) time(0));
+
+    /* Release memory for the string */
+    SB_Done (&Buf);
 }
 
 
@@ -141,9 +153,14 @@ 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 */
-    SymEntry* Sym = SymFind (CurrentScope, SymName, SYM_ALLOC_NEW);
+    Sym = SymFind (CurrentScope, &SymBuf, SYM_ALLOC_NEW);
 
     /* Check if have already a symbol with this name */
     if (SymIsDef (Sym)) {
@@ -155,6 +172,9 @@ static void NewSymbol (const char* SymName, long Val)
 
     /* Mark the symbol as defined */
     SymDef (Sym, Expr, ADDR_SIZE_DEFAULT, SF_NONE);
+
+    /* Free string buffer memory */
+    SB_Done (&SymBuf);
 }
 
 
@@ -200,10 +220,6 @@ static void SetSys (const char* Sys)
            CBMSystem ("__C128__");
            break;
 
-       case TGT_ACE:
-           CBMSystem ("__ACE__");
-           break;
-
        case TGT_PLUS4:
            CBMSystem ("__PLUS4__");
            break;
@@ -268,30 +284,41 @@ static void SetSys (const char* Sys)
 
 
 
+static void FileNameOption (const char* Opt, const char* Arg, StrBuf* Name)
+/* Handle an option that remembers a file name for later */
+{
+    /* Cannot have the option twice */
+    if (SB_NotEmpty (Name)) {
+        AbEnd ("Cannot use option `%s' twice", Opt);
+    }
+    /* Remember the file name for later */
+    SB_CopyStr (Name, Arg);
+    SB_Terminate (Name);
+}
+
+
+
 static void DefineSymbol (const char* Def)
 /* Define a symbol from the command line */
 {
     const char* P;
     unsigned I;
     long Val;
-    char SymName [MAX_STR_LEN+1];
+    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 != '=') {
@@ -315,7 +342,10 @@ static void DefineSymbol (const char* Def)
     }
 
     /* Define the new symbol */
-    NewSymbol (SymName, Val);
+    NewSymbol (SB_GetConstBuf (&SymName), Val);
+
+    /* Release string memory */
+    SB_Done (&SymName);
 }
 
 
@@ -329,6 +359,14 @@ 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 */
+{
+    AddSearchPath (BinSearchPath, Arg);
+}
+
+
+
 static void OptCPU (const char* Opt attribute ((unused)), const char* Arg)
 /* Handle the --cpu option */
 {
@@ -342,6 +380,23 @@ static void OptCPU (const char* Opt attribute ((unused)), const char* Arg)
 
 
 
+static void OptCreateDep (const char* Opt, const char* Arg)
+/* Handle the --create-dep option */
+{
+    FileNameOption (Opt, Arg, &DepName);
+}
+
+
+
+static void OptCreateFullDep (const char* Opt attribute ((unused)),
+                             const char* Arg)
+/* Handle the --create-full-dep option */
+{
+    FileNameOption (Opt, Arg, &FullDepName);
+}
+
+
+
 static void OptDebugInfo (const char* Opt attribute ((unused)),
                          const char* Arg attribute ((unused)))
 /* Add debug info to the object file */
@@ -354,14 +409,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 */
@@ -384,7 +451,7 @@ 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);
+    AddSearchPath (IncSearchPath, Arg);
 }
 
 
@@ -397,7 +464,7 @@ static void OptListBytes (const char* Opt, const char* Arg)
 
     /* Convert the argument to a number */
     if (sscanf (Arg, "%u%c", &Num, &Check) != 1) {
-        AbEnd ("Invalid argument for option `%s'", Opt);
+        InvArg (Opt, Arg);
     }
 
     /* Check the bounds */
@@ -411,11 +478,31 @@ 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;
+    /* 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);
+    }
+
+    /* Get the file name */
+    FileNameOption (Opt, Arg, &ListingName);
+}
+
+
+
+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));
 }
 
 
@@ -486,9 +573,7 @@ static void OptVersion (const char* Opt attribute ((unused)),
                        const char* Arg attribute ((unused)))
 /* Print the assembler version */
 {
-    fprintf (stderr,
-                    "ca65 V%u.%u.%u - %s\n",
-                    VER_MAJOR, VER_MINOR, VER_PATCH, Copyright);
+    fprintf (stderr, "ca65 V%s - %s\n", GetVersionAsString (), Copyright);
 }
 
 
@@ -500,7 +585,7 @@ static void DoPCAssign (void)
     if (PC < 0 || PC > 0xFFFFFF) {
        Error ("Range error");
     } else {
-       SetAbsPC (PC);
+       EnterAbsoluteMode (PC);
     }
 }
 
@@ -512,7 +597,7 @@ 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
@@ -522,8 +607,8 @@ static void OneLine (void)
                InitListingLine ();
     }
 
-    if (Tok == TOK_COLON) {
-               /* An unnamed label */
+    /* Single colon means unnamed label */
+    if (CurTok.Tok == TOK_COLON) {
                ULabDef ();
                NextTok ();
     }
@@ -531,40 +616,40 @@ static void OneLine (void)
     /* If the first token on the line is an identifier, check for a macro or
      * an instruction.
      */
-    if (Tok == TOK_IDENT) {
+    if (CurTok.Tok == TOK_IDENT) {
         if (!UbiquitousIdents) {
             /* Macros and symbols cannot use instruction names */
-            Instr = FindInstruction (SVal);
+            Instr = FindInstruction (&CurTok.SVal);
             if (Instr < 0) {
-                Macro = IsMacro (SVal);
+                Mac = FindMacro (&CurTok.SVal);
             }
         } else {
             /* Macros and symbols may use the names of instructions */
-            Macro = IsMacro (SVal);
+            Mac = FindMacro (&CurTok.SVal);
         }
     }
 
-    /* Handle an identifier */
-    if (Tok == TOK_LOCAL_IDENT || (Tok == TOK_IDENT && Instr < 0 && !Macro)) {
+    /* 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 (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_IDENT) {
-            Sym = SymFind (CurrentScope, SVal, SYM_ALLOC_NEW);
-        } else {
-            Sym = SymFindLocal (SymLast, SVal, SYM_ALLOC_NEW);
-        }
-        NextTok ();
+        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) {
+        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 ();
@@ -576,7 +661,7 @@ static void OneLine (void)
             ConsumeSep ();
             return;
 
-        } else if (Tok == TOK_SET) {
+        } else if (CurTok.Tok == TOK_SET) {
 
             ExprNode* Expr;
 
@@ -610,11 +695,11 @@ static void OneLine (void)
              * without a colon if there is no whitespace before the
              * identifier.
              */
-            if (Tok != TOK_COLON) {
+            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 ();
                     }
                 }
@@ -626,35 +711,35 @@ 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 (CurTok.Tok == TOK_IDENT) {
                 if (!UbiquitousIdents) {
                     /* Macros and symbols cannot use instruction names */
-                    Instr = FindInstruction (SVal);
+                    Instr = FindInstruction (&CurTok.SVal);
                     if (Instr < 0) {
-                        Macro = IsMacro (SVal);
+                        Mac = FindMacro (&CurTok.SVal);
                     }
                 } else {
                     /* Macros and symbols may use the names of instructions */
-                    Macro = IsMacro (SVal);
+                    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 ();
+        MacExpandStart (Mac);
     } else if (Instr >= 0 ||
-               (UbiquitousIdents && ((Instr = FindInstruction (SVal)) >= 0))) {
+               (UbiquitousIdents && ((Instr = FindInstruction (&CurTok.SVal)) >= 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 {
@@ -694,7 +779,7 @@ static void Assemble (void)
     NextTok ();
 
     /* Assemble lines until end of file */
-    while (Tok != TOK_EOF) {
+    while (CurTok.Tok != TOK_EOF) {
        OneLine ();
     }
 }
@@ -725,8 +810,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 ();
@@ -746,14 +834,19 @@ int main (int argc, char* argv [])
     /* Program long options */
     static const LongOpt OptTab[] = {
         { "--auto-import",             0,      OptAutoImport           },
+        { "--bin-include-dir",  1,      OptBinIncludeDir        },
         { "--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           },
         { "--list-bytes",       1,      OptListBytes            },
-       { "--listing",          0,      OptListing              },
+       { "--listing",          1,      OptListing              },
+        { "--macpack-dir",      1,      OptMacPackDir           },
         { "--memory-model",     1,      OptMemoryModel          },
        { "--pagelength",       1,      OptPageLength           },
        { "--smart",            0,      OptSmart                },
@@ -762,15 +855,29 @@ 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 ();
+
+    /* Create the predefined segments */
+    SegInit ();
+
     /* 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, 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;
@@ -800,7 +907,7 @@ int main (int argc, char* argv [])
                            break;
 
                        case 'l':
-                   OptListing (Arg, 0);
+                   OptListing (Arg, GetArg (&I, 2));
                            break;
 
                 case 'm':
@@ -812,7 +919,7 @@ int main (int argc, char* argv [])
                     break;
 
                        case 'o':
-                           OutFile = GetArg (&I, 2);
+                           OutFile = GetArg (&I, 2);
                            break;
 
                        case 's':
@@ -836,7 +943,7 @@ int main (int argc, char* argv [])
                    break;
 
                        case 'U':
-                   OptAutoImport (Arg, 0);
+                   OptAutoImport (Arg, 0);
                            break;
 
                        case 'V':
@@ -887,8 +994,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);
@@ -899,14 +1006,14 @@ int main (int argc, char* argv [])
     /* Assemble the input */
     Assemble ();
 
-    /* If we didn't have any errors, check the segment stack */
+    /* If we didn't have any errors, check the pseudo insn stacks */
     if (ErrorCount == 0) {
-        SegStackCheck ();
+        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 */
@@ -914,31 +1021,39 @@ int main (int argc, char* argv [])
         SymCheck ();
     }
 
+    /* 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 */
+    /* 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 ();
-
     /* Dump the data */
     if (Verbosity >= 2) {
         SymDump (stdout);
         SegDump ();
     }
 
-    /* If we didn't have any errors, create the object and listing 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 ();
     }
 
     /* Close the input file */