|
|
1.1 ! root 1: /* ! 2: * Memory initialization and allocation; also parses arguments. ! 3: */ ! 4: ! 5: #include "ilink.h" ! 6: #ifndef VMS ! 7: #ifndef ATT3B ! 8: #ifndef LATTICE ! 9: #include <sys/types.h> ! 10: #include <sys/stat.h> ! 11: #endif LATTICE ! 12: #endif ATT3B ! 13: #endif VMS ! 14: ! 15: /* ! 16: * Memory initialization ! 17: */ ! 18: ! 19: struct gentry **ghash; /* hash area for global table */ ! 20: struct ientry **ihash; /* hash area for identifier table */ ! 21: struct fentry **fhash; /* hash area for field table */ ! 22: ! 23: struct lentry *ltable; /* local table */ ! 24: struct gentry *gtable; /* global table */ ! 25: struct centry *ctable; /* constant table */ ! 26: struct ientry *itable; /* identifier table */ ! 27: struct fentry *ftable; /* field table headers */ ! 28: struct rentry *rtable; /* field table record lists */ ! 29: ! 30: char *strings; /* string space */ ! 31: word *labels; /* label table */ ! 32: char *code; /* generated code space */ ! 33: ! 34: struct gentry *gfree; /* free pointer for global table */ ! 35: struct ientry *ifree; /* free pointer for identifier table */ ! 36: struct fentry *ffree; /* free pointer for field table headers */ ! 37: struct rentry *rfree; /* free pointer for field table record lists */ ! 38: char *strfree; /* free pointer for string space */ ! 39: char *codep; /* free pointer for code space */ ! 40: ! 41: word lsize = Lsize; /* size of local table */ ! 42: word gsize = GSize; /* size of global table */ ! 43: word csize = CSize; /* size of constant table */ ! 44: word isize = ISize; /* size of identifier table */ ! 45: word fsize = FSize; /* size of field table headers */ ! 46: word rsize = RSize; /* size of field table record lists */ ! 47: word ssize = StrSize; /* size of string space */ ! 48: word ghsize = GhSize; /* size of global hash table */ ! 49: word ihsize = IhSize; /* size of identifier hash table */ ! 50: word fhsize = FhSize; /* size of field hash table */ ! 51: word maxlabels = MaxLabels; /* maximum number of labels per procedure */ ! 52: word maxcode = MaxCode; /* maximum amount of code per procedure */ ! 53: int gmask; /* mask for global table hash */ ! 54: int imask; /* mask for identifier table hash */ ! 55: int fmask; /* mask for field table hash */ ! 56: ! 57: char *ipath; ! 58: ! 59: #ifdef VMS ! 60: #define MaxNAME 256 ! 61: char lclname[MaxNAME]; /* local name string for access() */ ! 62: #endif VMS ! 63: #ifdef MSDOS ! 64: #define MaxNAME 256 ! 65: char lclname[MaxNAME]; /* local name string for access() */ ! 66: #endif MSDOS ! 67: ! 68: char *maknam(); ! 69: char *maknam2(); ! 70: ! 71: /* ! 72: * meminit - scan the command line arguments and initialize data structures. ! 73: */ ! 74: meminit(argc,argv) ! 75: int argc; ! 76: char **argv; ! 77: { ! 78: int aval; ! 79: register int i; ! 80: register union { ! 81: struct gentry **gp; ! 82: struct ientry **ip; ! 83: struct fentry **fp; ! 84: } p; ! 85: extern char *allocate(); ! 86: extern char *instalid(); ! 87: extern char *getenv(); ! 88: extern struct gentry *putglob(); ! 89: ! 90: lfiles = NULL; /* Zero queue of files to link. */ ! 91: if ((ipath = getenv("IPATH")) == NULL) ! 92: #ifndef VMS ! 93: #ifndef MSDOS ! 94: ipath = "."; /* Just look in current directory if no IPATH. */ ! 95: #else MSDOS ! 96: ipath = ";"; /* Just look in current directory if no IPATH. */ ! 97: #endif MSDOS ! 98: #else VMS ! 99: ipath = "[]"; /* Just look in current directory if no IPATH. */ ! 100: #endif VMS ! 101: /* ! 102: * Process the command line arguments. ! 103: */ ! 104: while (--argc) { ! 105: if (**++argv == '-') { ! 106: switch ((*argv)[1]) { ! 107: case 'm': /* -m and -u are for the translator. */ ! 108: case 'u': ! 109: continue; ! 110: case 't': /* Set &trace to -1 when Icon starts up. */ ! 111: trace = -1; ! 112: continue; ! 113: case 'D': /* Produce a .ux file, which is a readable ! 114: version of the icode file produced. */ ! 115: Dflag++; ! 116: continue; ! 117: case 'o': /* Output file is next argument. */ ! 118: strcpy(outname,*++argv); ! 119: argc--; ! 120: continue; ! 121: #ifdef VMS ! 122: case 'r': ! 123: #endif VMS ! 124: case 'S': /* Change some table size. */ ! 125: if ((*argv)[3] == 'h') { /* Change hash table size. */ ! 126: aval = atoi(&(*argv)[4]); ! 127: if (aval <= 0) ! 128: goto badarg; ! 129: switch ((*argv)[2]) { ! 130: case 'i': ihsize = aval; continue; ! 131: case 'g': ghsize = aval; continue; ! 132: case 'c': continue; ! 133: case 'f': fhsize = aval; continue; ! 134: case 'l': continue; ! 135: } ! 136: } ! 137: else { /* Change symbol table size. */ ! 138: aval = atoi(&(*argv)[3]); ! 139: if (aval <= 0) ! 140: goto badarg; ! 141: switch ((*argv)[2]) { ! 142: case 'c': csize = aval; continue; ! 143: case 'i': isize = aval; continue; ! 144: case 'g': gsize = aval; continue; ! 145: case 'l': lsize = aval; continue; ! 146: case 's': ssize = aval; continue; ! 147: case 't': continue; ! 148: case 'f': fsize = aval; continue; ! 149: case 'r': rsize = aval; continue; ! 150: case 'L': maxlabels = aval; continue; ! 151: case 'C': maxcode = aval; continue; ! 152: } ! 153: } ! 154: case 'i': { ! 155: iconx = *++argv; ! 156: argc--; ! 157: continue; ! 158: } ! 159: default: ! 160: badarg: ! 161: printf("bad argument: %s\n", *argv); ! 162: continue; ! 163: } ! 164: } ! 165: else { /* If not an argument, assume it's an input file. */ ! 166: #ifndef VMS ! 167: #ifndef MSDOS ! 168: if (access(*argv,4) != 0) { ! 169: #else MSDOS ! 170: /* *********** I don't know why this is here, addlfile ! 171: searches the paths for the file and determines if the file ! 172: can be read */ ! 173: #endif MSDOS ! 174: #else VMS ! 175: if ( access( maknam2(lclname,*argv,".u1"),4 ) != 0 ) { ! 176: #endif VMS ! 177: #ifndef MSDOS ! 178: fprintf(stderr, "ilink: cannot open %s\n", *argv); ! 179: exit(ErrorExit); ! 180: } ! 181: #endif MSDOS ! 182: addlfile(*argv); ! 183: } ! 184: } ! 185: ! 186: /* ! 187: * Round sizes of hash tables for locals, globals, constants, and ! 188: * identifiers to next larger power of two. The corresponding ! 189: * mask values are set to one less than the hash table size so that ! 190: * an integer value can be &'d with the mask to produce a hash value. ! 191: * (See [lgc]hasher in sym.h.) ! 192: */ ! 193: for (i = 1; i < ghsize; i <<= 1) ; ! 194: ghsize = i; ! 195: gmask = i - 1; ! 196: for (i = 1; i < ihsize; i <<= 1) ; ! 197: ihsize = i; ! 198: imask = i - 1; ! 199: for (i = 1; i < fhsize; i <<= 1) ; ! 200: fhsize = i; ! 201: fmask = i - 1; ! 202: /* ! 203: * Allocate the various data structures that are made on a per-file ! 204: * basis. ! 205: */ ! 206: ghash = (struct gentry **) allocate((int)ghsize, sizeof(struct gentry *)); ! 207: ihash = (struct ientry **) allocate((int)ihsize, sizeof(struct ientry *)); ! 208: fhash = (struct fentry **) allocate((int)fhsize, sizeof(struct fentry *)); ! 209: ltable = (struct lentry *) allocate((int)lsize, sizeof(struct lentry)); ! 210: gtable = (struct gentry *) allocate((int)gsize, sizeof(struct gentry)); ! 211: ctable = (struct centry *) allocate((int)csize, sizeof(struct centry)); ! 212: itable = (struct ientry *) allocate((int)isize, sizeof(struct ientry )); ! 213: ftable = (struct fentry *) allocate((int)fsize, sizeof(struct fentry)); ! 214: rtable = (struct rentry *) allocate((int)rsize, sizeof(struct rentry)); ! 215: strings = (char *) allocate((int)ssize, sizeof(char *)); ! 216: labels = (word *) allocate((int)maxlabels, sizeof(word *)); ! 217: code = (char *) allocate((int)maxcode, sizeof(char *)); ! 218: /* ! 219: * Check to see if there was enough memory. This assumes that the ! 220: * allocation for strings fails if any of the other allocations ! 221: * failed. Apparent bug - that assumption is not necessarily valid. ! 222: */ ! 223: ! 224: if (code == NULL) ! 225: syserr("can't get enough memory"); ! 226: /* ! 227: * Reset the free pointer for each region. ! 228: */ ! 229: gfree = gtable; ! 230: ifree = itable; ! 231: ffree = ftable; ! 232: rfree = rtable; ! 233: strfree = strings; ! 234: codep = code; ! 235: /* ! 236: * Zero out the hash tables. ! 237: */ ! 238: for (p.gp = ghash; p.gp < &ghash[ghsize]; p.gp++) ! 239: *p.gp = NULL; ! 240: for (p.ip = ihash; p.ip < &ihash[ihsize]; p.ip++) ! 241: *p.ip = NULL; ! 242: for (p.fp = fhash; p.fp < &fhash[fhsize]; p.fp++) ! 243: *p.fp = NULL; ! 244: /* ! 245: * Install "main" as a global variable in order to insure that it ! 246: * is the first global variable. iconx/start.s depends on main ! 247: * being global number 0. ! 248: */ ! 249: putglob(instalid("main"), F_Global, 0); ! 250: } ! 251: ! 252: /* ! 253: * allocate - get more memory from system. ! 254: */ ! 255: char *allocate(n, size) ! 256: int n, size; ! 257: { ! 258: #ifndef MSDOS ! 259: return (char *)malloc(n * size); ! 260: #else MSDOS ! 261: return (char *)calloc(n,size); ! 262: #endif MSDOS ! 263: } ! 264: ! 265: /* ! 266: * alclfile - allocate an lfile structure for the named file, fill ! 267: * in the name and return a pointer to it. ! 268: */ ! 269: struct lfile *alclfile(name) ! 270: char *name; ! 271: { ! 272: struct lfile *p; ! 273: char *np; ! 274: int l; ! 275: ! 276: p = (struct lfile *)allocate(1,sizeof(struct lfile)); ! 277: if (!p) ! 278: syserr("not enough memory for file list"); ! 279: p->lf_link = NULL; ! 280: l = strlen(name); ! 281: np = allocate(1,(l+1+sizeof(int *)) & ~(sizeof(int *)-1)); ! 282: if (!np) ! 283: syserr("not enough memory for file list"); ! 284: strncpy(np,name,l); ! 285: p->lf_name = np; ! 286: return p; ! 287: } ! 288: ! 289: /* ! 290: * dumplfiles - print the list of files to link. Used for debugging only. ! 291: */ ! 292: ! 293: dumplfiles() ! 294: { ! 295: struct lfile *p,*lfls; ! 296: ! 297: printf("lfiles:\n"); ! 298: lfls = lfiles; ! 299: while (p = getlfile(&lfls)) ! 300: printf("'%s'\n",p->lf_name); ! 301: } ! 302: /* ! 303: * addlfile - create an lfile structure for the named file and add it to the ! 304: * end of the list of files (lfiles) to generate link instructions for. ! 305: */ ! 306: char *pptr; ! 307: addlfile(name) ! 308: char *name; ! 309: { ! 310: struct lfile *nlf, *p; ! 311: char file[256], ok; ! 312: ! 313: #ifndef VMS ! 314: #ifndef MSDOS ! 315: if (index(name,'/') == 0) { ! 316: #else MSDOS ! 317: if (index(name,'/') == 0 && ! 318: index(name,'\\') == 0 && ! 319: index(name,':') == 0) { ! 320: #endif MSDOS ! 321: #else VMS ! 322: if (strchr(name,']') == 0 && strchr(name,':') == 0) { ! 323: #endif VMS ! 324: pptr = ipath; ! 325: ok = 0; ! 326: #ifdef MSDOS ! 327: strcpy(file,name); ! 328: if (canread(file)) ok++; /* See if we can read the file here */ ! 329: else ! 330: #endif MSDOS ! 331: while (trypath(name,file)) { ! 332: if (canread(file)) { ! 333: ok++; ! 334: break; ! 335: } ! 336: } ! 337: if (!ok) { ! 338: fprintf(stderr, "Can't resolve reference to file '%s'\n",name); ! 339: exit(ErrorExit); ! 340: } ! 341: } ! 342: else ! 343: strcpy(file,name); ! 344: nlf = alclfile(file); ! 345: if (lfiles == NULL) { ! 346: lfiles = nlf; ! 347: } ! 348: else { ! 349: p = lfiles; ! 350: while (p->lf_link != NULL) { ! 351: if (strcmp(p->lf_name,file) == 0) ! 352: return; ! 353: p = p->lf_link; ! 354: } ! 355: if (strcmp(p->lf_name,file) == 0) ! 356: return; ! 357: p->lf_link = nlf; ! 358: } ! 359: } ! 360: ! 361: /* ! 362: * getlfile - return a pointer (p) to the lfile structure pointed at by lptr ! 363: * and move lptr to the lfile structure that p points at. That is, getlfile ! 364: * returns a pointer to the current (wrt. lptr) lfile and advances lptr. ! 365: */ ! 366: struct lfile * ! 367: getlfile(lptr) ! 368: struct lfile **lptr; ! 369: { ! 370: struct lfile *p; ! 371: ! 372: if (*lptr == NULL) ! 373: return NULL; ! 374: else { ! 375: p = *lptr; ! 376: *lptr = p->lf_link; ! 377: return p; ! 378: } ! 379: } ! 380: ! 381: /* ! 382: * canread - see if file can be read and be sure that it's just an ! 383: * ordinary file. ! 384: */ ! 385: canread(file) ! 386: char *file; ! 387: { ! 388: #ifndef VMS ! 389: #ifndef LATTICE ! 390: struct stat statb; ! 391: #endif LATTICE ! 392: #endif VMS ! 393: ! 394: #ifndef VMS ! 395: #ifndef LATTICE ! 396: if (access(file,4) == 0) { ! 397: stat(file,&statb); ! 398: if (statb.st_mode & S_IFREG) ! 399: return 1; ! 400: } ! 401: #else LATTICE ! 402: if (access( maknam2(lclname,file,".u1"), 4 ) == 0 ) ! 403: return 1; ! 404: #endif LATTICE ! 405: #else VMS ! 406: if (access( maknam2(lclname,file,".u1"), 4 ) == 0 ) ! 407: return 1; ! 408: #endif VMS ! 409: ! 410: return 0; ! 411: } ! 412: ! 413: /* ! 414: * trypath - form a file name in file by concatenating name onto the ! 415: * next path element. ! 416: */ ! 417: trypath(name,file) ! 418: char *name, *file; ! 419: { ! 420: char *n, c; ! 421: ! 422: #ifndef VMS ! 423: #ifndef MSDOS ! 424: while (*pptr == ':') ! 425: #else MSDOS ! 426: while (*pptr ==';') ! 427: #endif MSDOS ! 428: #else VMS ! 429: while (*pptr == ' ') ! 430: #endif VMS ! 431: pptr++; ! 432: if (!*pptr) ! 433: return 0; ! 434: do { ! 435: c = (*file++ = *pptr++); ! 436: #ifndef VMS ! 437: #ifndef MSDOS ! 438: } while (c != ':' && c); ! 439: #else MSDOS ! 440: } while (c != ';' && c); ! 441: #endif MSDOS ! 442: #else VMS ! 443: } while (c != ' ' && c); ! 444: #endif VMS ! 445: pptr--; ! 446: file--; ! 447: ! 448: #ifndef VMS ! 449: *file++ = '/'; ! 450: #endif VMS ! 451: while (*file++ = *name++); ! 452: *file = 0; ! 453: return(1); ! 454: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.