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

Defined functions

addlfile defined in line 275; used 2 times
alclfile defined in line 237; used 1 times
allocate defined in line 219; used 15 times
canread defined in line 338; used 1 times
dumplfiles defined in line 261; never used
getlfile defined in line 319; used 3 times
meminit defined in line 59; used 1 times
trypath defined in line 354; used 1 times

Defined variables

code defined in line 26; used 12 times
codep defined in line 33; used 15 times
csize defined in line 37; used 5 times
ctable defined in line 19; used 13 times
ffree defined in line 30; used 5 times
fhash defined in line 15; used 9 times
fhsize defined in line 44; used 10 times
fmask defined in line 49; used 3 times
fsize defined in line 39; used 5 times
gfree defined in line 28; used 7 times
ghash defined in line 13; used 10 times
ghsize defined in line 42; used 10 times
gmask defined in line 47; used 3 times
gsize defined in line 36; used 5 times
ifree defined in line 29; used 4 times
ihash defined in line 14; used 8 times
ihsize defined in line 43; used 10 times
imask defined in line 48; used 3 times
ipath defined in line 54; used 3 times
isize defined in line 38; used 5 times
itable defined in line 20; used 5 times
labels defined in line 25; used 9 times
lsize defined in line 35; used 5 times
ltable defined in line 17; used 14 times
maxcode defined in line 46; used 6 times
maxlabels defined in line 45; used 7 times
memfree defined in line 53; used 3 times
pptr defined in line 274; used 6 times
rfree defined in line 31; used 4 times
rsize defined in line 40; used 5 times
rtable defined in line 22; used 5 times
sfree defined in line 32; used 15 times
ssize defined in line 41; used 4 times
strings defined in line 24; used 22 times
Last modified: 1984-11-18
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1711
Valid CSS Valid XHTML 1.0 Strict