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