Annotation of researchv10dc/cmd/icon/src/link/lmem.c, revision 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.