Annotation of gforth/main.c, revision 1.12

1.1       anton       1: /*
1.12    ! pazsan      2:   $Id: main.c,v 1.11 1994/09/08 17:20:09 anton Exp $
1.1       anton       3:   Copyright 1993 by the ANSI figForth Development Group
                      4: */
                      5: 
                      6: #include <ctype.h>
                      7: #include <stdio.h>
                      8: #include <string.h>
                      9: #include <math.h>
                     10: #include <sys/types.h>
                     11: #include <sys/stat.h>
                     12: #include <fcntl.h>
                     13: #include <assert.h>
                     14: #include <stdlib.h>
                     15: #include "forth.h"
1.5       pazsan     16: #include "io.h"
1.12    ! pazsan     17: #ifdef USE_GETOPT
        !            18: #  include "getopt.h"
        !            19: #else
        !            20:      extern int getopt (argc, argv, optstring);
        !            21: 
        !            22:      extern char *optarg;
        !            23:      extern int optind, opterr;
        !            24: #endif
1.2       pazsan     25: 
1.10      anton      26: #ifndef DEFAULTPATH
                     27: #      define DEFAULTPATH "/usr/local/lib/gforth:."
                     28: #endif
                     29: 
1.1       anton      30: #ifdef DIRECT_THREADED
1.2       pazsan     31: #      define CA(n)    (symbols[(n)])
1.1       anton      32: #else
1.2       pazsan     33: #      define CA(n)    ((int)(symbols+(n)))
1.1       anton      34: #endif
                     35: 
1.10      anton      36: #define maxaligned(n)  ((((Cell)n)+sizeof(Float)-1)&-sizeof(Float))
                     37: 
                     38: static int dictsize=0;
                     39: static int dsize=0;
                     40: static int rsize=0;
                     41: static int fsize=0;
                     42: static int lsize=0;
                     43: char *progname;
                     44: 
                     45: 
1.1       anton      46: /* image file format:
                     47:  *   size of image with stacks without tags (in bytes)
                     48:  *   size of image without stacks and tags (in bytes)
1.5       pazsan     49:  *   size of data and FP stack (in bytes)
1.1       anton      50:  *   pointer to start of code
1.7       anton      51:  *   pointer into throw (for signal handling)
1.1       anton      52:  *   data (size in image[1])
                     53:  *   tags (1 bit/data cell)
                     54:  *
                     55:  * tag==1 mean that the corresponding word is an address;
                     56:  * If the word is >=0, the address is within the image;
                     57:  * addresses within the image are given relative to the start of the image.
                     58:  * If the word is =-1, the address is NIL,
1.2       pazsan     59:  * If the word is between -2 and -5, it's a CFA (:, Create, Constant, User)
                     60:  * If the word is -6, it's a DOES> CFA
                     61:  * If the word is -7, it's a DOES JUMP
                     62:  * If the word is <-7, it's a primitive
1.1       anton      63:  */
                     64: 
1.10      anton      65: void relocate(Cell *image, char *bitstring, int size, Label symbols[])
1.1       anton      66: {
1.5       pazsan     67:    int i=0, j, k, steps=(size/sizeof(Cell))/8;
                     68:    char bits;
                     69: /*   static char bits[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};*/
                     70:    
                     71:    for(k=0; k<=steps; k++)
                     72:      for(j=0, bits=bitstring[k]; j<8; j++, i++, bits<<=1)
                     73:        if(bits & 0x80)
                     74:          if(image[i]<0)
                     75:            switch(image[i])
                     76:              {
                     77:                case CF_NIL      : image[i]=0; break;
                     78:                case CF(DOCOL)   :
                     79:                case CF(DOVAR)   :
                     80:                case CF(DOCON)   :
1.9       anton      81:                case CF(DOUSER)  : 
                     82:                case CF(DODEFER)  : 
                     83:                  MAKE_CF(image+i,symbols[CF(image[i])]); break;
1.5       pazsan     84:                case CF(DODOES)  : MAKE_DOES_CF(image+i,image[i+1]+((int)image));
                     85:                                   break;
                     86:                case CF(DOESJUMP): MAKE_DOES_HANDLER(image+i); break;
                     87:                default          : image[i]=(Cell)CA(CF(image[i]));
                     88:             }
                     89:          else
                     90:            image[i]+=(Cell)image;
1.2       pazsan     91: 
1.5       pazsan     92:    CACHE_FLUSH(image,size);
1.1       anton      93: }
                     94: 
1.10      anton      95: Cell *loader(FILE *imagefile)
                     96: {
                     97:        Cell header[3];
                     98:        Cell *image;
                     99:        int wholesize;
                    100:        int imagesize; /* everything needed by the image */
                    101: 
                    102:        fread(header,1,3*sizeof(Cell),imagefile);
                    103:        if (dictsize==0)
                    104:          dictsize = header[0];
                    105:        if (dsize==0)
                    106:          dsize=header[2];
                    107:        if (rsize==0)
                    108:          rsize=header[2];
                    109:        if (fsize==0)
                    110:          fsize=header[2];
                    111:        if (lsize==0)
                    112:          lsize=header[2];
                    113:        dictsize=maxaligned(dictsize);
                    114:        dsize=maxaligned(dsize);
                    115:        rsize=maxaligned(rsize);
                    116:        lsize=maxaligned(lsize);
                    117:        fsize=maxaligned(fsize);
                    118: 
                    119:        wholesize = dictsize+dsize+rsize+fsize+lsize;
                    120:        imagesize = header[1]+((header[1]-1)/sizeof(Cell))/8+1;
                    121:        image=malloc(wholesize>imagesize?wholesize:imagesize);
                    122:        memset(image,0,wholesize); /* why? - anton */
1.1       anton     123:        image[0]=header[0];
                    124:        image[1]=header[1];
1.10      anton     125:        image[2]=header[2];
1.1       anton     126: 
1.10      anton     127:        fread(image+3,1,header[1]-3*sizeof(Cell),imagefile);
                    128:        fread(((void *)image)+header[1],1,((header[1]-1)/sizeof(Cell))/8+1,
1.1       anton     129:              imagefile);
                    130:        fclose(imagefile);
                    131: 
1.10      anton     132:        relocate(image,(char *)image+header[1],header[1],engine(0,0,0,0,0));
1.1       anton     133: 
                    134:        return(image);
                    135: }
                    136: 
1.10      anton     137: int go_forth(Cell *image, int stack, Cell *entries)
1.1       anton     138: {
1.10      anton     139:        Cell *sp=(Cell*)((void *)image+dictsize+dsize);
                    140:        Address lp=(Address)((void *)sp+lsize);
                    141:        Float *fp=(Float *)((void *)lp+fsize);
                    142:        Cell *rp=(Cell*)((void *)fp+rsize);
                    143:        Xt *ip=(Xt *)(image[3]);
1.8       pazsan    144:        int throw_code;
1.10      anton     145: 
1.1       anton     146:        for(;stack>0;stack--)
                    147:                *--sp=entries[stack-1];
                    148: 
                    149:        install_signal_handlers(); /* right place? */
1.8       pazsan    150: 
                    151:        if ((throw_code=setjmp(throw_jmp_buf))) {
                    152:                static Cell signal_data_stack[8];
                    153:                static Cell signal_return_stack[8];
                    154: 
                    155:                signal_data_stack[7]=throw_code;
                    156: 
1.10      anton     157:                return((int)engine((Xt *)image[4],signal_data_stack+7,
                    158:                                                  signal_return_stack+8,0,0));
1.8       pazsan    159:        }
1.1       anton     160: 
1.4       anton     161:        return((int)engine(ip,sp,rp,fp,lp));
1.1       anton     162: }
                    163: 
1.10      anton     164: int convsize(char *s, int elemsize)
                    165: /* converts s of the format #+u (e.g. 25k) into the number of bytes.
                    166:    the unit u can be one of bekM, where e stands for the element
                    167:    size. default is e */
                    168: {
                    169:   char *endp;
                    170:   int n,m;
                    171: 
                    172:   m = elemsize;
                    173:   n = strtoul(s,&endp,0);
                    174:   if (endp!=NULL) {
                    175:     if (strcmp(endp,"b")==0)
                    176:       m=1;
                    177:     else if (strcmp(endp,"k")==0)
                    178:       m=1024;
                    179:     else if (strcmp(endp,"M")==0)
                    180:       m=1024*1024;
                    181:     else if (strcmp(endp,"e")!=0) {
                    182:       fprintf(stderr,"%s: cannot grok size specification %s\n", progname, s);
                    183:       exit(1);
                    184:     }
                    185:   }
                    186:   return n*m;
                    187: }
                    188: 
1.1       anton     189: int main(int argc, char **argv, char **env)
                    190: {
1.10      anton     191:        char *path, *path1;
                    192:        char *imagename="gforth.fi";
                    193:        FILE *image_file;
1.12    ! pazsan    194:        int c, retvalue;
1.10      anton     195:          
1.6       anton     196: #if defined(i386) && defined(ALIGNMENT_CHECK)
                    197:        /* turn on alignment checks on the 486.
                    198:         * on the 386 this should have no effect. */
                    199:        __asm__("pushfl; popl %eax; orl $0x40000, %eax; pushl %eax; popfl;");
                    200: #endif
1.2       pazsan    201: 
1.10      anton     202:        progname = argv[0];
                    203:        if ((path=getenv("GFORTHPATH"))==NULL)
                    204:          path = strcpy(malloc(strlen(DEFAULTPATH)+1),DEFAULTPATH);
                    205:        opterr=0;
                    206:        while (1) {
                    207:          int option_index=0;
1.12    ! pazsan    208: #ifdef USE_GETOPT
1.10      anton     209:          static struct option opts[] = {
                    210:            {"image-file", required_argument, NULL, 'i'},
                    211:            {"dictionary-size", required_argument, NULL, 'm'},
                    212:            {"data-stack-size", required_argument, NULL, 'd'},
                    213:            {"return-stack-size", required_argument, NULL, 'r'},
                    214:            {"fp-stack-size", required_argument, NULL, 'f'},
                    215:            {"locals-stack-size", required_argument, NULL, 'l'},
                    216:            {"path", required_argument, NULL, 'p'},
                    217:            {0,0,0,0}
                    218:            /* no-init-file, no-rc? */
                    219:          };
                    220: 
                    221:          c = getopt_long(argc, argv, "+drfl", opts, &option_index);
1.12    ! pazsan    222: #else
        !           223:          c = getopt(argc, argv, "imdrflp");
        !           224: #endif
        !           225: 
1.10      anton     226:          if (c==EOF)
                    227:            break;
                    228:          if (c=='?') {
                    229:            optind--;
                    230:            break;
                    231:          }
                    232:          switch (c) {
                    233:          case 'i': imagename = optarg; break;
                    234:          case 'm': dictsize = convsize(optarg,sizeof(Cell)); break;
                    235:          case 'd': dsize = convsize(optarg,sizeof(Cell)); break;
                    236:          case 'r': rsize = convsize(optarg,sizeof(Cell)); break;
                    237:          case 'f': fsize = convsize(optarg,sizeof(Float)); break;
                    238:          case 'l': lsize = convsize(optarg,sizeof(Cell)); break;
                    239:          case 'p': path = optarg; break;
                    240:          }
1.2       pazsan    241:        }
1.10      anton     242:        path1=path;
                    243:        do {
                    244:          char *pend=strchr(path, ':');
                    245:          if (pend==NULL)
                    246:            pend=path+strlen(path);
                    247:          if (strlen(path)==0) {
                    248:            fprintf(stderr,"%s: cannot open image file %s in path %s for reading\n", progname, imagename, path1);
                    249:            exit(1);
                    250:          }
                    251:          {
                    252:            int dirlen=pend-path;
                    253:            char fullfilename[dirlen+strlen(imagename)+2];
                    254:            memcpy(fullfilename, path, dirlen);
                    255:            if (fullfilename[dirlen-1]!='/')
                    256:              fullfilename[dirlen++]='/';
                    257:            strcpy(fullfilename+dirlen,imagename);
                    258:            image_file=fopen(fullfilename,"rb");
                    259:          }
                    260:          path=pend+(*pend==':');
                    261:        } while (image_file==NULL);
1.1       anton     262: 
                    263:        {
1.10      anton     264:          Cell environ[]= {(Cell)argc-(optind-1), (Cell)(argv+(optind-1)), (Cell)path1};
                    265:          argv[optind-1] = progname;
                    266: /*
                    267:          for (i=0; i<environ[0]; i++)
                    268:            printf("%s\n", ((char **)(environ[1]))[i]);
                    269: */
1.12    ! pazsan    270:      retvalue=go_forth(loader(image_file),3,environ);
        !           271:      deprep_terminal();
        !           272:      exit(retvalue);
1.1       anton     273:        }
                    274: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>