|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.