Annotation of researchv10dc/cmd/icon/src/link/ilink.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Linker main program that controls the linking process.
                      3:  */
                      4: 
                      5: #include "ilink.h"
                      6: #include "../h/paths.h"
                      7: #include "../h/header.h"
                      8: 
                      9: #ifndef MaxHeader
                     10: #define MaxHeader MaxHdr
                     11: #endif MaxHeader
                     12: 
                     13: 
                     14: 
                     15: #define MaxName  256           /* maximum length of file name */
                     16: 
                     17: #ifndef Header
                     18: #define Header HeaderPath
                     19: #endif Header
                     20: FILE *infile;                  /* input file (.u1 or .u2) */
                     21: FILE *outfile;                 /* interpreter code output file */
                     22: FILE *dbgfile;                 /* debug file */
                     23: char inname[MaxName];          /* input file name */
                     24: char outname[MaxName];         /* output file name */
                     25: char icnname[MaxName];         /* icon source file name */
                     26: char dbgname[MaxName];         /* debug file name */
                     27: #ifdef VMS
                     28: char *iconx = "VMS ICONX";                              /* pathname of iconx */
                     29: #else VMS
                     30: #ifdef MSDOS
                     31: char *iconx = "CCW";
                     32: #else MSDOS
                     33: char *iconx = "/bin/echo iconx path not in";            /* pathname of iconx */
                     34: #endif MSDOS
                     35: #endif VMS
                     36: struct lfile *lfiles;          /* List of files to link */
                     37: 
                     38: int line = 0;                  /* current source program line number */
                     39: char *file = NULL;             /* current source program file */
                     40: int fatalerrs = 0;             /* number of errors encountered */
                     41: int Dflag = 0;                 /* debug flag */
                     42: 
                     43: char *pname;                   /* name of program that is running */
                     44: char **filep;                  /* name of current input file */
                     45: 
                     46: main(argc, argv)
                     47: int argc;
                     48: char **argv;
                     49:    {
                     50:    register int i;
                     51:    extern char *maknam(), *maknam2();
                     52:    char *p, *getenv();
                     53:    struct lfile *lf,*lfls;
                     54: 
                     55:    pname = "ilink";
                     56:    meminit(argc, argv); /* Note that meminit also processes arguments. */
                     57: 
                     58:    /*
                     59:     * Phase I: load global information contained in .u2 files into
                     60:     *  data structures.
                     61:     *
                     62:     * The list of files to link is maintained as a queue with lfiles
                     63:     *  as the base.  lf moves along the list.  Each file is processed
                     64:     *  in turn by forming .u2 and .icn names from each file name, each
                     65:     *  of which ends in .u1.  The .u2 file is opened and globals is called
                     66:     *  to process it.  When the end of the list is reached, lf becomes
                     67:     *  NULL and the loop is terminated, completing phase I.  Note that
                     68:     *  link instructions in the .u2 file cause files to be added to list
                     69:     *  of files to link.
                     70:     */
                     71:    if (!(lf = lfiles))
                     72:       exit(NormalExit);
                     73:    while (lf) {
                     74:       filep = &(lf->lf_name);
                     75:       maknam2(inname, *filep, ".u2");
                     76:       maknam(icnname, *filep, ".icn");
                     77:       infile = fopen(inname, "r");
                     78:       if (infile == NULL) {
                     79:         fprintf(stderr, "%s: cannot open %s\n", pname, inname);
                     80:         exit(ErrorExit);
                     81:         }
                     82:       globals(i);
                     83:       fclose(infile);
                     84:       lf = lf->lf_link;
                     85:       }
                     86: 
                     87:    /* Phase II: resolve undeclared variables and generate code. */
                     88: 
                     89:    /*
                     90:     * Open the output file.  If no file was named with -o, form the
                     91:     *  name from that of the first input file named.
                     92:     */
                     93:    if (!outname[0])
                     94:       maknam(outname, lfiles->lf_name, "");
                     95:    outfile = fopen(outname, "w");
                     96: #ifdef LATTICE
                     97:    fmode(outfile,1);   /* Set for untranslated mode */
                     98: #endif LATTICE
                     99: #ifdef MSoft
                    100:    setmode(fileno(outfile),0x8000);    /* Set for untranslated mode */
                    101: #endif MSoft
                    102:    if (outfile == NULL) {
                    103:       fprintf(stderr, "%s: cannot create %s\n", pname, outname);
                    104:       exit(ErrorExit);
                    105:       }
                    106: #ifndef NoHeader
                    107:    /*
                    108:     * Open Header, which contains the start-up program and copy it to the
                    109:     *  output file.  Then, set up for an fseek to the byte
                    110:     *  past the end of the start-up program.
                    111:     */
                    112:    {
                    113:    int hfile, hsize;
                    114:    char hdrdat[MaxHeader];
                    115: 
                    116: 
                    117:    hfile = open(Header,0);
                    118:    if (hfile == -1) {
                    119:       fprintf(stderr,"Can't open linker header file %s\n",Header);
                    120:       exit(ErrorExit);
                    121:       }
                    122:    hsize = read(hfile,hdrdat,MaxHeader);
                    123:    fwrite(hdrdat,sizeof(char),hsize,outfile);
                    124:    }
                    125:    fseek(outfile, (long)(MaxHeader + sizeof(struct header)), 0);
                    126: #else NoHeader
                    127:    fseek(outfile, (long)(sizeof(struct header)),0);
                    128: #endif NoHeader
                    129: 
                    130:    /*
                    131:     * Open the .ux file if debugging is on.
                    132:     */
                    133:    if (Dflag) {
                    134:       maknam(dbgname, lfiles->lf_name, ".ux");
                    135:       dbgfile = fopen(dbgname, "w");
                    136:       if (dbgfile == NULL) {
                    137:         fprintf(stderr, "%s: cannot create %s\n", pname, dbgname);
                    138:         exit(ErrorExit);
                    139:         }
                    140:       }
                    141: 
                    142:    /*
                    143:     * Loop through input files and generate code for each.
                    144:     */
                    145:    lfls = lfiles;
                    146:    while (lf = getlfile(&lfls)) {
                    147:       filep = &(lf->lf_name);
                    148:       maknam2(inname, *filep, ".u1");
                    149:       maknam(icnname, *filep, ".icn");
                    150:       infile = fopen(inname, "r");
                    151:       if (infile == NULL) {
                    152:         fprintf(stderr, "%s: cannot open %s\n", pname, inname);
                    153:         exit(ErrorExit);
                    154:         }
                    155:       gencode();
                    156:       fclose(infile);
                    157:       }
                    158:    gentables();        /* Generate record, field, global, global names,
                    159:                           static, and identifier tables. */
                    160:    if (fatalerrs > 0)
                    161:       exit(ErrorExit);
                    162: #ifndef VMS
                    163:    exit(NormalExit);
                    164: #else VMS
                    165:    exit(NormalExit);
                    166: #endif VMS
                    167:    }
                    168: 
                    169: /*
                    170:  * maknam - makes a file name from prefix and suffix.
                    171:  *
                    172:  * Uses only the last file specification if name is a path,
                    173:  * replaces suffix of name with suffix argument.
                    174:  */
                    175: char *maknam(dest, name, suffix)
                    176: char *dest, *name, *suffix;
                    177:    {
                    178:    register char *d, *pre, *suf;
                    179:    char *mark;
                    180: 
                    181:    d = dest;
                    182:    pre = name;
                    183:    suf = suffix;
                    184:    mark = pre;
                    185:    while (*pre)                /* find last delimiter */
                    186: #ifndef VMS
                    187: #ifndef MSDOS
                    188:       if (*pre++ == '/')
                    189:         mark = pre;
                    190: #else MSDOS
                    191:       if (*pre == '/' || *pre == '\\' || *pre == ':')
                    192:         mark = ++pre;
                    193:       else
                    194:         ++pre;
                    195: #endif MSDOS
                    196: #else VMS
                    197:       if (*pre == ']' || *pre == ':')
                    198:         mark = ++pre;
                    199:       else
                    200:         ++pre;
                    201: #endif VMS
                    202:    pre = mark;
                    203:    mark = 0;
                    204:    while (*d = *pre++)         /* copy from last slash into dest */
                    205:       if (*d++ == '.')          /*   look for last dot, too */
                    206:         mark = d - 1;
                    207:    if (mark)                   /* if no dot, just append suffix */
                    208:       d = mark;
                    209:    while (*d++ = *suf++) ;     /* copy suffix into dest */
                    210:    return dest;
                    211:    }
                    212: 
                    213: /*
                    214:  * maknam2 - makes a file name from prefix and suffix.
                    215:  *
                    216:  * Like maknam, but leaves initial pathname component intact.
                    217:  */
                    218: char *maknam2(dest, name, suffix)
                    219: char *dest, *name, *suffix;
                    220:    {
                    221:    register char *d, *pre, *suf;
                    222:    char *mark;
                    223: 
                    224:    d = dest;
                    225:    pre = name;
                    226:    suf = suffix;
                    227:    mark = 0;
                    228:    while (*d = *pre++) {
                    229: #ifndef VMS
                    230: #ifndef MSDOS
                    231:       if (*d == '/')
                    232:         mark = 0;
                    233: #else MSDOS
                    234:       if (*d == ':' || *d == '/' || *d == '\\')
                    235:         mark = 0;
                    236: #endif MSDOS
                    237: #else VMS
                    238:       if (*d == ']' || *d == ':')
                    239:         mark = 0;
                    240: #endif VMS
                    241:       if (*d++ == '.')          /*   look for last dot, too */
                    242:         mark = d - 1;
                    243:       }
                    244:    if (mark)                   /* if no dot, just append suffix */
                    245:       d = mark;
                    246:    while (*d++ = *suf++) ;     /* copy suffix into dest */
                    247:    return dest;
                    248:    }
                    249: 
                    250: /*
                    251:  * syserr - issue error message and die.
                    252:  */
                    253: syserr(s)
                    254: char *s;
                    255:    {
                    256:    fprintf(stderr, "%s\n", s);
                    257:    exit(ErrorExit);
                    258:    }
                    259: 
                    260: /*
                    261:  * warn - issue a warning message.
                    262:  */
                    263: warn(s1, s2, s3)
                    264: char *s1, *s2, *s3;
                    265:    {
                    266:    fprintf(stderr, "%s: ", icnname);
                    267:    if (line)
                    268:       fprintf(stderr, "%d: ", line);
                    269:    if (s1)
                    270:       fprintf(stderr, "\"%s\": ", s1);
                    271:    if (s2)
                    272:       fprintf(stderr, "%s", s2);
                    273:    if (s3)
                    274:       fprintf(stderr, "%s", s3);
                    275:    fprintf(stderr, "\n");
                    276:    }
                    277: 
                    278: /*
                    279:  * err - issue an error message.
                    280:  */
                    281: 
                    282: err(s1, s2, s3)
                    283: char *s1, *s2, *s3;
                    284:    {
                    285:    fprintf(stderr, "%s: ", icnname);
                    286:    if (line)
                    287:       fprintf(stderr, "%d: ", line);
                    288:    if (s1)
                    289:       fprintf(stderr, "\"%s\": ", s1);
                    290:    if (s2)
                    291:       fprintf(stderr, "%s", s2);
                    292:    if (s3)
                    293:       fprintf(stderr, "%s", s3);
                    294:    fprintf(stderr, "\n");
                    295:    fatalerrs++;
                    296:    }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.