Annotation of researchv10dc/cmd/icon/src/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: #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:    }

unix.superglobalmegacorp.com

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