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

unix.superglobalmegacorp.com

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