Exemple #1
0
/* undefine a #define symbol */
void tok_del_define(tokcxdef *ctx, char *sym, int len)
{
    int       hsh;
    tokdfdef *df;
    tokdfdef *prv;
    
    /* find the appropriate chain the hash table */
    hsh = tokdfhsh(sym, len);

    /* search the chain for this symbol */
    for (prv = 0, df = ctx->tokcxdf[hsh] ; df ; prv = df, df = df->nxt)
    {
        /* if this one matches, delete it */
        if (df->len == len && !memcmp(df->nm, sym, (size_t)len))
        {
            /* unlink it from the chain */
            if (prv)
                prv->nxt = df->nxt;
            else
                ctx->tokcxdf[hsh] = df->nxt;

            /* delete this symbol, and we're done */
            mchfre(df);
            break;
        }
    }
}
Exemple #2
0
/*
 *   Read preprocessor state from a file 
 */
void tok_read_defines(tokcxdef *ctx, osfildef *fp, errcxdef *ec)
{
    int        i;
    tokdfdef **dfp;
    tokdfdef  *df;
    char       buf[4];

    /* write each element of the hash chains */
    for (i = TOKDFHSHSIZ, dfp = ctx->tokcxdf ; i ; ++dfp, --i)
    {
        /* read this hash chain */
        for (;;)
        {
            /* read the next entry's header, and stop if this is the end */
            if (osfrb(fp, buf, 4)) errsig(ec, ERR_RDGAM);
            if (osrp2(buf) == 0) break;

            /* set up a new symbol of the appropriate size */
            df = (tokdfdef *)mchalo(ec,
                                    (sizeof(tokdfdef) + osrp2(buf)
                                     + osrp2(buf+2) - 1),
                                    "tok_read_defines");
            df->explen = osrp2(buf+2);
            df->nm = df->expan + df->explen;
            df->len = osrp2(buf);

            /* read the rest of the symbol */
            if (osfrb(fp, df->nm, df->len)
                || (df->explen != 0 && osfrb(fp, df->expan, df->explen)))
                errsig(ec, ERR_RDGAM);

            /*
             *   If a symbol with this name already exists in the table,
             *   discard the new one -- the symbols defined by -D and the
             *   current set of built-in symbols takes precedence over the
             *   set loaded from the file.  
             */
            if (tok_find_define(ctx, df->nm, df->len))
            {
                /* simply discard this symbol */
                mchfre(df);
            }
            else
            {
                /* link it into this hash chain */
                df->nxt = *dfp;
                *dfp = df;
            }
        }
    }
}
Exemple #3
0
/* set up contents property for load-on-demand */
void supcont(void *ctx0, objnum obj, prpnum prp)
{
    supcxdef  *ctx = (supcxdef *)ctx0;
    vocidef ***vpg;
    vocidef  **v;
    voccxdef  *voc = ctx->supcxvoc;
    int        i;
    int        j;
    int        len = 2;
    objnum     chi;
    objnum     loc;

    /* be sure the buffer is allocated */
    if (!ctx->supcxbuf)
    {
        ctx->supcxlen = 512;
        ctx->supcxbuf = mchalo(ctx->supcxerr, ctx->supcxlen,
                               "supcont");
    }

    assert(prp == PRP_CONTENTS);         /* the only thing that makes sense */
    for (vpg = voc->voccxinh, i = 0 ; i < VOCINHMAX ; ++vpg, ++i)
    {
        if (!*vpg) continue;                     /* no entries on this page */
        for (v = *vpg, chi = (i << 8), j = 0 ; j < 256 ; ++v, ++chi, ++j)
        {
            /* if there's no record at this location, skip it */
            if (!*v) continue;

            /* inherit the location if it hasn't been set to any value */
            if ((*v)->vociloc == MCMONINV
                && !((*v)->vociflg & VOCIFLOCNIL))
                loc = (*v)->vociilc;
            else
                loc = (*v)->vociloc;

            /* if this object is in the indicated location, add it */
            if (loc == obj && !((*v)->vociflg & VOCIFCLASS))
            {
                /* see if we have room in list buffer; expand buffer if not */
                if (len + 3 > ctx->supcxlen)
                {
                    uchar *newbuf;

                    /* allocate a new buffer */
                    newbuf = mchalo(ctx->supcxerr,
                                    (len + 512), "supcont");

                    /* copy the old buffer's contents into the new buffer */
                    memcpy(newbuf, ctx->supcxbuf, ctx->supcxlen);

                    /* remember the new buffer length */
                    ctx->supcxlen = len + 512;

                    /* free the old buffer */
                    mchfre(ctx->supcxbuf);

                    /* remember the new buffer */
                    ctx->supcxbuf = newbuf;

                    /* sanity check for integer overflow */
                    if (len + 3 > ctx->supcxlen)
                        errsig(ctx->supcxmem->mcmcxgl->mcmcxerr, ERR_SUPOVF);
                }
                ctx->supcxbuf[len] = DAT_OBJECT;
                oswp2(ctx->supcxbuf + len + 1, chi);
                len += 3;
            }
        }
    }

    oswp2(ctx->supcxbuf, len);
    objsetp(ctx->supcxmem, obj, prp, DAT_LIST, ctx->supcxbuf,
            ctx->supcxrun->runcxundo);
}
Exemple #4
0
/* get a new line from line source, processing '#' directives */
static int tokgetlin(tokcxdef *ctx, int dopound)
{
    for (;;)
    {
        if (linget(ctx->tokcxlin))
        {
            /* at eof in current source; resume parent if there is one */
            if (ctx->tokcxlin->linpar)
            {
                lindef *parent;
                
                parent = ctx->tokcxlin->linpar;          /* remember parent */
                lincls(ctx->tokcxlin);               /* close included file */
                if (!ctx->tokcxdbg)               /* if no debug context... */
                    mchfre(ctx->tokcxlin);              /* free line source */
                ctx->tokcxlin = parent;      /* reset to parent line source */
                if (parent->linflg & LINFCMODE)
                    ctx->tokcxflg |= TOKCXFCMODE;
                else
                    ctx->tokcxflg &= ~TOKCXFCMODE;
                continue;                       /* back for another attempt */
            }
            else
            {
                /* check for outstanding #if/#ifdef */
                if (ctx->tokcxifcnt)
                    errlog(ctx->tokcxerr, ERR_NOENDIF);

                /* return end-of-file indication */
                return TRUE;
            }
        }
        
        /* if this is a multi-segment line, copy it into our own buffer */
        if (ctx->tokcxlin->linflg & LINFMORE)
        {
            char *p;
            uint  rem;
            int   done;
            
            if (!ctx->tokcxbuf)
            {
                /* allocate 1k as a default buffer */
                ctx->tokcxbuf = (char *)mchalo(ctx->tokcxerr, 1024,
                                               "tok");
                ctx->tokcxbsz = 1024;
            }
            ctx->tokcxlen = 0;
            
            for (done = FALSE, p = ctx->tokcxbuf, rem = ctx->tokcxbsz ;
                 !done ; )
            {
                size_t len = ctx->tokcxlin->linlen;

                /* add the current segment's length into line length */
                ctx->tokcxlen += len;
                
                /* we're done after this piece if the last fetch was all */
                done = !(ctx->tokcxlin->linflg & LINFMORE);
                if (len + 1 > rem)
                {
                    char *newp;

                    /* increase the size of the buffer */
                    if (ctx->tokcxbsz > (unsigned)0x8000)
                        errsig(ctx->tokcxerr, ERR_LONGLIN);
                    rem += 4096;
                    ctx->tokcxbsz += 4096;
                    
                    /* allocate a new buffer and copy line into it */
                    newp = (char *)mchalo(ctx->tokcxerr, ctx->tokcxbsz, "tok");
                    memcpy(newp, ctx->tokcxbuf, (size_t)(p - ctx->tokcxbuf));
                    
                    /* free the original buffer, and use the new one */
                    p = (p - ctx->tokcxbuf) + newp;
                    mchfre(ctx->tokcxbuf);
                    ctx->tokcxbuf = newp;
                }
                
                /* add the line to the buffer */
                memcpy(p, ctx->tokcxlin->linbuf, len);
                p += len;
                rem -= len;
                
                /* get the next piece of the line if there is one */
                if (!done)
                {
                    if (linget(ctx->tokcxlin)) break;
                }
            }
            
            /* null-terminate the buffer, and use it for input */
            *p = '\0';
            ctx->tokcxptr = ctx->tokcxbuf;
        }
        else
        {
            ctx->tokcxptr = ctx->tokcxlin->linbuf;
            ctx->tokcxlen = ctx->tokcxlin->linlen;
        }
        
        /* check for preprocessor directives */
        if (dopound && ctx->tokcxlen != 0 && ctx->tokcxptr[0] == '#'
            && !(ctx->tokcxlin->linflg & LINFNOINC))
        {
            char   *p;
            int     len;
            static  struct
            {
                char  *nm;
                int    len;
                int    ok_in_if;
                void (*fn)(tokcxdef *, char *, int);
            }
            *dirp, dir[] =
            {
                { "include", 7, FALSE, tokinclude },
                { "pragma",  6, FALSE, tokpragma },
                { "define",  6, FALSE, tokdefine },
                { "ifdef",   5, TRUE, tokifdef },
                { "ifndef",  6, TRUE, tokifndef },
                { "if",      2, TRUE, tokif },
                { "else",    4, TRUE, tokelse },
                { "elif",    4, TRUE, tokelif },
                { "endif",   5, TRUE, tokendif },
                { "undef",   5, FALSE, tokundef },
                { "error",   5, FALSE, tok_p_error }
            };
            int  i;

            /* scan off spaces between '#' and directive */
            for (len = ctx->tokcxlen - 1, p = &ctx->tokcxptr[1] ;
                 len && t_isspace(*p) ; --len, ++p) ;

            /* find and process the directive */
            for (dirp = dir, i = sizeof(dir)/sizeof(dir[0]) ; i ; --i, ++dirp)
            {
                /* compare this directive; if it wins, call its function */
                if (len >= dirp->len && !memcmp(p, dirp->nm, (size_t)dirp->len)
                    && (len == dirp->len || t_isspace(*(p + dirp->len))))
                {
                    int cnt;
                    int stat;
                    
                    /*
                     *   if we're not in a #if's false part, or if the
                     *   directive is processed even in #if false parts,
                     *   process the line, otherwise skip it 
                     */
                    cnt = ctx->tokcxifcnt;
                    if (dirp->ok_in_if || cnt == 0
                        || ((stat = ctx->tokcxifcur) == TOKIF_IF_YES
                            || stat == TOKIF_ELSE_YES))
                    {
                        /* skip whitespace following the directive */
                        for (p += dirp->len, len -= dirp->len ;
                             len && t_isspace(*p) ;
                             --len, ++p) ;

                        /* invoke the function to process this directive */
                        (*dirp->fn)(ctx, p, len);
                    }

                    /* there's no need to look at more directives */
                    break;
                }
            }

            /* if we didn't find anything, flag the error */
            if (i == 0)
                errlog(ctx->tokcxerr, ERR_PRPDIR);

            /* ignore this line */
            continue;
        }
        else
        {
            /*
             *   Check the #if level.  If we're in an #if, and we're to
             *   ignore lines (because of a false condition or an #else
             *   part for a true condition), skip this line. 
             */
            if (ctx->tokcxifcnt != 0)
            {
                switch(ctx->tokcxifcur)
                {
                case TOKIF_IF_NO:
                case TOKIF_ELSE_NO:
                    /* ignore this line */
                    continue;

                default:
                    /* we're in a true part - keep the line */
                    break;
                }
            }
            
            ctx->tokcxlin->linflg &= ~LINFDBG;       /* no debug record yet */
            return(FALSE);                      /* return the line we found */
        }
    }
}