Annotation of 43BSD/contrib/icon/link/lmem.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.