Annotation of 43BSD/contrib/icon/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: #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.