Example #1
0
/*
 * substitute the argument list into the replacement string
 *  This would be simple except for ## and #
 */
void
substargs(Nlist* np, Tokenrow* rtr, Tokenrow** atr) {
    Tokenrow tatr;
    Token* tp;
    int ntok, argno;

    for (rtr->tp = rtr->bp; rtr->tp < rtr->lp;) {
        if (rtr->tp->type == SHARP) { /* string operator */
            tp = rtr->tp;
            rtr->tp += 1;
            if ((argno = lookuparg(np, rtr->tp)) < 0) {
                error(ERROR, "# not followed by macro parameter");
                continue;
            }
            ntok = 1 + (rtr->tp - tp);
            rtr->tp = tp;
            insertrow(rtr, ntok, stringify(atr[argno]));
            continue;
        }
        if (rtr->tp->type == NAME
                && (argno = lookuparg(np, rtr->tp)) >= 0) {
            if ((rtr->tp + 1)->type == DSHARP
                    || (rtr->tp != rtr->bp && (rtr->tp - 1)->type == DSHARP))
                insertrow(rtr, 1, atr[argno]);
            else {
                copytokenrow(&tatr, atr[argno]);
                expandrow(&tatr, "<macro>");
                insertrow(rtr, 1, &tatr);
                dofree(tatr.bp);
            }
            continue;
        }
        rtr->tp++;
    }
}
Example #2
0
/*
 * Expand the macro whose name is np, at token trp->tp, in the tokenrow.
 * Return trp->tp at the first token next to be expanded
 * (ordinarily the beginning of the expansion)
 */
void
expand(Tokenrow *trp, Nlist *np)
{
	Tokenrow ntr;
	int ntokc, narg, i;
	Token *tp;
	int hs;
#ifdef __ORCAC__
	Tokenrow **atr;

	atr = domalloc(sizeof(Tokenrow *) * (NARG+1));
#define RETURN free(atr);return
#else
	Tokenrow *atr[NARG+1];
#define RETURN return;
#endif

	copytokenrow(&ntr, np->vp);		/* copy macro value */
	if (np->ap==NULL)			/* parameterless */
		ntokc = 1;
	else {
		ntokc = gatherargs(trp, atr, &narg);
		if (narg<0) {			/* not actually a call (no '(') */
			trp->tp++;
			RETURN;
		}
		if (narg != rowlen(np->ap)) {
			error(ERROR, "Disagreement in number of macro arguments");
			trp->tp->hideset = newhideset(trp->tp->hideset, np);
			trp->tp += ntokc;
			RETURN;
		}
		substargs(np, &ntr, atr);	/* put args into replacement */
		for (i=0; i<narg; i++) {
			dofree(atr[i]->bp);
			dofree(atr[i]);
		}
	}
	doconcat(&ntr);				/* execute ## operators */
	hs = newhideset(trp->tp->hideset, np);
	for (tp=ntr.bp; tp<ntr.lp; tp++) {	/* distribute hidesets */
		if (tp->type==NAME) {
			if (tp->hideset==0)
				tp->hideset = hs;
			else
				tp->hideset = unionhideset(tp->hideset, hs);
		}
	}
	ntr.tp = ntr.bp;
	insertrow(trp, ntokc, &ntr);
	trp->tp -= rowlen(&ntr);
	dofree(ntr.bp);
	RETURN;
}	
Example #3
0
void rmenu(void)
/* Executes the commands in the row menu */
{
 switch(getcommand(RMENU, RCOMMAND))
 {
  case 0 :
   insertrow(currow);
   break;
  case 1 :
   deleterow(currow);
   break;
 } /* switch */
} /* rmenu */
Example #4
0
/*
 * Expand the macro whose name is np, at token trp->tp, in the tokenrow.
 * Return trp->tp at the first token next to be expanded
 * (ordinarily the beginning of the expansion)
 */
void
expand(Tokenrow *trp, Nlist *np)
{
	Tokenrow ntr;
	int ntokc, narg, i;
	Token *tp;
	Tokenrow *atr[NARG+1];
	int hs;

	copytokenrow(&ntr, np->vp);		/* copy macro value */
	if (np->ap==NULL)			/* parameterless */
		ntokc = 1;
	else {
		ntokc = gatherargs(trp, atr, &narg);
		if (narg<0) {			/* not actually a call (no '(') */
			/* gatherargs has already pushed trp->tr to the next token */
			return;
		}
		if (narg != rowlen(np->ap)) {
			error(ERROR, "Disagreement in number of macro arguments");
			trp->tp->hideset = newhideset(trp->tp->hideset, np);
			trp->tp += ntokc;
			return;
		}
		substargs(np, &ntr, atr);	/* put args into replacement */
		for (i=0; i<narg; i++) {
			dofree(atr[i]->bp);
			dofree(atr[i]);
		}
	}
	doconcat(&ntr);				/* execute ## operators */
	hs = newhideset(trp->tp->hideset, np);
	for (tp=ntr.bp; tp<ntr.lp; tp++) {	/* distribute hidesets */
		if (tp->type==NAME) {
			if (tp->hideset==0)
				tp->hideset = hs;
			else
				tp->hideset = unionhideset(tp->hideset, hs);
		}
	}
	ntr.tp = ntr.bp;
	insertrow(trp, ntokc, &ntr);
	trp->tp -= rowlen(&ntr);
	dofree(ntr.bp);
	return;
}	
Example #5
0
/*
 * Evaluate the ## operators in a tokenrow
 */
void
doconcat(Tokenrow *trp)
{
	Token *ltp, *ntp;
	STATIC Tokenrow ntr;
	int len;

	CHECKIN();
	for (trp->tp=trp->bp; trp->tp<trp->lp; trp->tp++) {
		if (trp->tp->type==DSHARP1)
			trp->tp->type = DSHARP;
		else if (trp->tp->type==DSHARP) {
			STATIC char tt[128];
			ltp = trp->tp-1;
			ntp = trp->tp+1;
			if (ltp<trp->bp || ntp>=trp->lp) {
				error(ERROR, "## occurs at border of replacement");
				continue;
			}
			len = ltp->len + ntp->len;
			strncpy((char*)tt, (char*)ltp->t, ltp->len);
			strncpy((char*)tt+ltp->len, (char*)ntp->t, ntp->len);
			tt[len] = '\0';
			setsource("<##>", -1, tt);
			maketokenrow(3, &ntr);
			gettokens(&ntr, 1);
			unsetsource();
			if (ntr.lp-ntr.bp!=2 || ntr.bp->type==UNCLASS)
				error(WARNING, "Bad token %r produced by ##", &ntr);
			ntr.lp = ntr.bp+1;
			trp->tp = ltp;
			makespace(&ntr);
			insertrow(trp, (ntp-ltp)+1, &ntr);
			dofree(ntr.bp);
			trp->tp--;
		}
	}
	CHECKOUT();
}
Example #6
0
/*
 * Evaluate the ## operators in a tokenrow
 */
void
    doconcat(Tokenrow * trp)
{
    Token *ltp, *ntp;
    Tokenrow ntr;
    size_t len;

    for (trp->tp = trp->bp; trp->tp < trp->lp; trp->tp++)
    {
        if (trp->tp->type == DSHARP1)
            trp->tp->type = DSHARP;
        else
            if (trp->tp->type == DSHARP)
            {
                int  i;
                char tt[NCONCAT];

                ltp = trp->tp - 1;
                ntp = trp->tp + 1;

                if (ltp < trp->bp || ntp >= trp->lp)
                {
                    error(ERROR, "## occurs at border of replacement");
                    continue;
                }

                ntp = ltp;
                i   = 1;
                len = 0;

                do
                {
                    if (len + ntp->len + ntp->wslen > sizeof(tt))
                    {
                        error(ERROR, "## string concatination buffer overrun");
                        break;
                    }

                    if (ntp != trp->tp + 1)
                    {
                        strncpy((char *) tt + len, (char *) ntp->t - ntp->wslen,
                                ntp->len + ntp->wslen);
                        len += ntp->len + ntp->wslen;
                    }
                    else    // Leerzeichen um ## herum entfernen:
                    {
                        strncpy((char *) tt + len, (char *) ntp->t, ntp->len);
                        len += ntp->len;
                    }

                    ntp = trp->tp + i;
                    i++;
                }
                while (ntp < trp->lp);

                tt[len] = '\0';
                setsource("<##>", -1, -1, tt, 0);
                maketokenrow(3, &ntr);
                gettokens(&ntr, 1);
                unsetsource();
                if (ntr.bp->type == UNCLASS)
                    error(WARNING, "Bad token %r produced by ##", &ntr);
                while ((ntr.lp-1)->len == 0 && ntr.lp != ntr.bp)
                    ntr.lp--;

                doconcat(&ntr);
                trp->tp = ltp;
                makespace(&ntr, ltp);
                insertrow(trp, (int)(ntp - ltp), &ntr);
                dofree(ntr.bp);
                trp->tp--;
            }
    }
}
Example #7
0
/*
 * Expand the macro whose name is np, at token trp->tp, in the tokenrow.
 * Return trp->tp at the first token next to be expanded
 * (ordinarily the beginning of the expansion)
 * I.e.: the same position as before!
 * Only one expansion is performed, then we return to the expandrow()
 * loop and start at same position.
 */
void
    expand(Tokenrow * trp, Nlist * np, MacroValidatorList * pValidators)
{
    Tokenrow ntr;
    int ntokc, narg;
    Tokenrow *atr[NARG + 1];

    if (Mflag == 2)
    {
        if (np->ap)
            error(INFO, "Macro expansion of %t with %s(%r)", trp->tp, np->name, np->ap);
        else
            error(INFO, "Macro expansion of %t with %s", trp->tp, np->name);
    }

    copytokenrow(&ntr, np->vp);         /* copy macro value */
    if (np->ap == NULL)                 /* parameterless */
        ntokc = 1;
    else
    {
        int i;

        ntokc = gatherargs(trp, atr, &narg);
        if (narg < 0)
        {                               /* not actually a call (no '(') */
            trp->tp++;
            return;
        }
        if (narg != rowlen(np->ap))
        {
            error(ERROR, "Disagreement in number of macro arguments");
            trp->tp += ntokc;
            return;
        }

        /** If gatherargs passed a macro validating token, this token
            must become valid here.
            trp->tp+0 was checked in expandrow(), so we don't need to do it
            again here:
        */
        for (i = 1; i < ntokc; i++)
        {
            mvl_check(pValidators,trp->tp+i);
        }

        substargs(np, &ntr, atr);       /* put args into replacement */
        for (i = 0; i < narg; i++)
        {
            dofree(atr[i]->bp);
            dofree(atr[i]);
        }
    }

    doconcat(&ntr);                     /* execute ## operators */
    ntr.tp = ntr.bp;
    makespace(&ntr, trp->tp);

    tokenrow_zeroTokenIdentifiers(&ntr);
    insertrow(trp, ntokc, &ntr);

        /* add validator for just invalidated macro:
        */
    np->flag |= ISACTIVE;
    if (trp->tp != trp->lp)
    {   /* tp is a valid pointer: */
        mvl_add(pValidators,np,trp->tp);
    }
    else
    {   /* tp is == lp, therefore does not point to valid memory: */
        mvl_add(pValidators,np,0);
    }
        /* reset trp->tp to original position:
        */
    trp->tp -= ntr.lp - ntr.bp;         /* so the result will be tested for macros from the same position again */

    dofree(ntr.bp);

    return;
}