* as/hc08/aslex.c,
[fw/sdcc] / as / mcs51 / asmain.c
index 32cde0eb35486d569e3c437a819ddd17e7bc2e2e..3d31bf03b5776e3f2e1eaf51ed2cccf3242304df 100644 (file)
  * 29-Oct-97 JLH pass ";!" comments to output file
  */
 
+#include <stdlib.h>
 #include <stdio.h>
 #include <setjmp.h>
 #include <string.h>
-#include <alloc.h>
+
 #include "asm.h"
+#include "strcmpi.h"
 
-extern VOID machine(struct mne *);
 /*)Module      asmain.c
  *
  *     The module asmain.c includes the command argument parser,
@@ -81,7 +82,7 @@ extern VOID machine(struct mne *);
  *             int     fflag           -f(f), relocations flagged flag
  *             int     flevel          IF-ELSE-ENDIF flag will be non
  *                                     zero for false conditional case
- *             addr_t  fuzz            tracks pass to pass changes in the
+ *             Addr_T  fuzz            tracks pass to pass changes in the
  *                                     address of symbols caused by
  *                                     variable length instruction formats
  *             int     gflag           -g, make undefined symbols global flag
@@ -129,7 +130,7 @@ extern VOID machine(struct mne *);
  *             VOID    diag()          assubr.c
  *             VOID    err()           assubr.c
  *             int     fprintf()       c-library
- *             int     getline()       aslex.c
+ *             int     as_getline()    aslex.c
  *             VOID    list()          aslist.c
  *             VOID    lstsym()        aslist.c
  *             VOID    minit()         ___mch.c
@@ -147,6 +148,9 @@ extern VOID machine(struct mne *);
  *             REL, LST, and/or SYM files may be generated.
  */
 
+int fatalErrors=0;
+char relFile[128];
+
 int
 main(argc, argv)
 char *argv[];
@@ -241,8 +245,11 @@ char *argv[];
                        if (inpfil == 0) {
                                if (lflag)
                                        lfp = afile(p, "lst", 1);
-                               if (oflag)
-                                       ofp = afile(p, "rel", 1);
+                               if (oflag) {
+                                 ofp = afile(p, "rel", 1);
+                                 // save the file name if we have to delete it on error
+                                 strcpy(relFile,afn);
+                               }
                                if (sflag)
                                        tfp = afile(p, "sym", 1);
                        }
@@ -282,7 +289,7 @@ char *argv[];
                dot.s_area = &dca;
                symp = &dot;
                minit();
-               while (getline()) {
+               while (as_getline()) {
                        cp = cb;
                        cpt = cbt;
                        ep = eb;
@@ -317,8 +324,10 @@ char *argv[];
        if (lflag) {
                lstsym(lfp);
        }
-       asexit(aserr != 0);
-       return 0;
+       //printf ("aserr: %d\n", aserr);
+       //printf ("fatalErrors: %d\n", fatalErrors);
+       asexit(fatalErrors);
+       return 0; // hush the compiler
 }
 
 /*)Function    VOID    asexit(i)
@@ -363,7 +372,11 @@ int i;
        /*for (j=0; j<MAXINC && ifp[j] != NULL; j++) {
                fclose(ifp[j]);
                }*/
-
+       if (i) {
+         // remove output file
+         printf ("removing %s\n", relFile);
+         unlink(relFile);
+       }
        exit(i);
 }
 
@@ -398,7 +411,7 @@ int i;
  *                                     ASCII character
  *             int     flevel          IF-ELSE-ENDIF flag will be non
  *                                     zero for false conditional case
- *             addr_t  fuzz            tracks pass to pass changes in the
+ *             Addr_T  fuzz            tracks pass to pass changes in the
  *                                     address of symbols caused by
  *                                     variable length instruction formats
  *             int     ifcnd[]         array of IF statement condition
@@ -410,7 +423,7 @@ int i;
  *             int     incline[]       current include file line
  *             int     incfil          current file handle index
  *                                     for include files
- *             addr_t  laddr           address of current assembler line
+ *             Addr_T  laddr           address of current assembler line
  *                                     or value of .if argument
  *             int     lmode           listing mode
  *             int     lop             current line number on page
@@ -425,7 +438,7 @@ int i;
  *             int     tlevel          current conditional level
  *
  *     functions called:
- *             addr_t  absexpr()       asexpr.c
+ *             Addr_T  absexpr()       asexpr.c
  *             area *  alookup()       assym.c
  *             VOID    clrexpr()       asexpr.c
  *             int     digit()         asexpr.c
@@ -439,7 +452,7 @@ int i;
  *             char    getnb()         aslex.c
  *             VOID    getst()         aslex.c
  *             sym *   lookup()        assym.c
- *             VOID    machin()        ___mch.c
+ *             VOID    machine()       ___mch.c
  *             mne *   mlookup()       assym.c
  *             int     more()          aslex.c
  *             VOID *  new()           assym.c
@@ -467,7 +480,7 @@ asmbl()
        struct expr e1;
        char id[NCPS];
        char opt[NCPS];
-       char fn[FILSPC];
+       char fn[PATH_MAX];
        char *p;
        int d, n, uaf, uf;
 
@@ -787,7 +800,7 @@ loop:
                break;
 
        case S_MODUL:
-               getst(id, -1);
+               getst(id, getnb()); // a module can start with a digit
                if (pass == 0) {
                        if (module[0]) {
                                err('m');
@@ -798,6 +811,20 @@ loop:
                lmode = SLIST;
                break;
 
+    case S_OPTSDCC:
+               p = optsdcc;
+               if ((c = getnb()) != 0) {
+                       do {
+                               if (p < &optsdcc[NINPUT-1])
+                                       *p++ = c;
+                       } while ((c = get()) != 0);
+               }
+               *p = 0;
+               unget(c);
+               lmode = SLIST;
+        /*if (pass == 0) printf("optsdcc=%s\n", optsdcc);*/
+        break;
+
        case S_GLOBL:
                do {
                        getid(id, -1);
@@ -831,10 +858,6 @@ loop:
                if ((ap = alookup(id)) != NULL) {
                        if (uaf && uf != ap->a_flag)
                                err('m');
-                        if (ap->a_flag & A_OVR) {
-                               ap->a_size = 0; 
-                                ap->a_fuzz=0;
-                       }
                } else {
                        ap = (struct area *) new (sizeof(struct area));
                        ap->a_ap = areap;
@@ -899,7 +922,7 @@ loop:
                d = getnb();
                p = fn;
                while ((c = get()) != d) {
-                       if (p < &fn[FILSPC-1]) {
+                       if (p < &fn[PATH_MAX-1]) {
                                *p++ = c;
                        } else {
                                break;
@@ -923,12 +946,12 @@ loop:
                {
                    getst(id, -1);
                    
-                   if (!strcmpi(id, "on"))
+                   if (!as_strcmpi(id, "on"))
                    {
                        /* Quick sanity check: size of 
-                        * addr_t must be at least 24 bits.
+                        * Addr_T must be at least 24 bits.
                         */
-                       if (sizeof(addr_t) < 3)
+                       if (sizeof(Addr_T) < 3)
                        {
                            warnBanner();
                            fprintf(stderr,
@@ -941,7 +964,7 @@ loop:
                            flat24Mode = 1;
                        }
                    }
-                   else if (!strcmpi(id, "off"))
+                   else if (!as_strcmpi(id, "off"))
                    {
                        flat24Mode = 0;
                    }
@@ -1030,30 +1053,36 @@ char *fn;
 char *ft;
 int wf;
 {
-       register char *p1, *p2, *p3;
+       register char *p2, *p3;
        register int c;
        FILE *fp;
 
-       p1 = fn;
        p2 = afn;
        p3 = ft;
-       while ((c = *p1++) != 0 && c != FSEPX) {
-               if (p2 < &afn[FILSPC-4])
-                       *p2++ = c;
-       }
+
+       strcpy (afn, fn);
+       p2 = strrchr (afn, FSEPX);              // search last '.'
+       if (!p2)
+               p2 = afn + strlen (afn);
+       if (p2 > &afn[PATH_MAX-4])              // truncate filename, if it's too long
+               p2 = &afn[PATH_MAX-4];
        *p2++ = FSEPX;
-       if (*p3 == 0) {
-               if (c == FSEPX) {
-                       p3 = p1;
-               } else {
-                       p3 = dsft;
-               }
+
+       // choose a file-extension
+       if (*p3 == 0) {                                 // extension supplied?
+               p3 = strrchr (fn, FSEPX);       // no: extension in fn?
+               if (p3)
+                       ++p3;
+               else
+                       p3 = dsft;                                      // no: default extension
        }
-       while ((c = *p3++) != 0) {
-               if (p2 < &afn[FILSPC-1])
+
+       while ((c = *p3++) != 0) {              // strncpy
+               if (p2 < &afn[PATH_MAX-1])
                        *p2++ = c;
        }
        *p2++ = 0;
+
        if ((fp = fopen(afn, wf?"w":"r")) == NULL) {
                fprintf(stderr, "%s: cannot %s.\n", afn, wf?"create":"open");
                asexit(1);
@@ -1078,7 +1107,7 @@ int wf;
  *
  *     global variables:
  *             sym     dot             defined as sym[0]
- *             addr_t  fuzz            tracks pass to pass changes in the
+ *             Addr_T  fuzz            tracks pass to pass changes in the
  *                                     address of symbols caused by
  *                                     variable length instruction formats
  *
@@ -1096,18 +1125,33 @@ register struct area *nap;
        register struct area *oap;
 
        oap = dot.s_area;
+       /* fprintf (stderr, "%s dot.s_area->a_size: %d dot.s_addr: %d\n",
+            oap->a_id, dot.s_area->a_size, dot.s_addr); */
        oap->a_fuzz = fuzz;
-       oap->a_size = dot.s_addr;
-       fuzz = nap->a_fuzz;
+       if (oap->a_flag & A_OVR) {
+         // the size of an overlay is the biggest size encountered
+         if (oap->a_size < dot.s_addr) {
+           oap->a_size = dot.s_addr;
+         }
+       } else {
+         oap->a_size = dot.s_addr;
+       }
+       if (nap->a_flag & A_OVR) {
+         // a new overlay starts at 0, no fuzz
+         dot.s_addr = 0;
+         fuzz = 0;
+       } else {
+         dot.s_addr = nap->a_size;
+         fuzz = nap->a_fuzz;
+       }
        dot.s_area = nap;
-       dot.s_addr = nap->a_size;
        outall();
 }
 
 /*)Function    VOID    phase(ap, a)
  *
  *             area *  ap              pointer to area
- *             addr_t  a               address in area
+ *             Addr_T  a               address in area
  *
  *     Function phase() compares the area ap and address a
  *     with the current area dot.s_area and address dot.s_addr
@@ -1131,7 +1175,7 @@ register struct area *nap;
 VOID
 phase(ap, a)
 struct area *ap;
-addr_t a;
+Addr_T a;
 {
        if (ap != dot.s_area || a != dot.s_addr)
                err('p');
@@ -1147,9 +1191,9 @@ char *usetxt[] = {
        "  a    all user symbols made global",
        "  l    create list   output file1[LST]",
        "  o    create object output file1[REL]",
-        "  s    create symbol output file1[SYM]",
-        "  p    disable listing pagination",
-        "  f    flag relocatable references by `    in listing file",
+       "  s    create symbol output file1[SYM]",
+       "  p    disable listing pagination",
+       "  f    flag relocatable references by `    in listing file",
        " ff    flag relocatable references by mode in listing file",
        "",
        0