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:    }

Defined functions

err defined in line 251; used 3 times
main defined in line 30; never used
maknam defined in line 168; used 5 times
maknam2 defined in line 197; used 3 times
syserr defined in line 222; used 17 times
warn defined in line 232; used 1 times

Defined variables

Dflag defined in line 25; used 34 times
dbgname defined in line 16; used 3 times
fatalerrs defined in line 24; used 2 times
file defined in line 23; used 20 times
filep defined in line 28; used 6 times
hdrloc defined in line 19; used 5 times
icnname defined in line 15; used 4 times
iconx defined in line 18; used 2 times
inbuf defined in line 12; used 2 times
inname defined in line 13; used 6 times
ixhdr defined in line 17; used 5 times
lfiles defined in line 20; used 9 times
line defined in line 22; used 7 times
outname defined in line 14; used 5 times
pname defined in line 27; used 5 times

Defined macros

MAXNAME defined in line 7; used 4 times
Last modified: 1984-11-18
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1460
Valid CSS Valid XHTML 1.0 Strict