111 lines
2.8 KiB
C
111 lines
2.8 KiB
C
|
/*****************************************************************************
|
||
|
*
|
||
|
* crackle.c
|
||
|
*
|
||
|
* User-defined macros.
|
||
|
*
|
||
|
*****************************************************************************/
|
||
|
|
||
|
#include "m4.h"
|
||
|
|
||
|
/*****************************************************************************
|
||
|
*
|
||
|
* opcAddDollar
|
||
|
*
|
||
|
* Add a $* or $@ to the current token buffer.
|
||
|
*
|
||
|
*****************************************************************************/
|
||
|
|
||
|
DeclareOpc(opcAddDollar)
|
||
|
{
|
||
|
if (itok > 1) {
|
||
|
AddExpTch(tchComma);
|
||
|
}
|
||
|
if (dw) {
|
||
|
AddExpTch(tchLquo);
|
||
|
}
|
||
|
AddExpPtok(ptok);
|
||
|
if (dw) {
|
||
|
AddExpTch(tchRquo);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************
|
||
|
*
|
||
|
* TraceArgv
|
||
|
*
|
||
|
* Trace a macro call. Collect the output in the Exp hold and smear it
|
||
|
* to stderr when it's all ready.
|
||
|
*
|
||
|
*****************************************************************************/
|
||
|
|
||
|
void STDCALL
|
||
|
TraceArgv(ARGV argv)
|
||
|
{
|
||
|
TOK tok;
|
||
|
OpenExpPtok(&tok);
|
||
|
AddExpPtok(&tokTraceLpar);
|
||
|
AddExpPtok(&tokRparColonSpace);
|
||
|
AddExpPtok(ptokArgv(0));
|
||
|
if (ctokArgv) {
|
||
|
AddExpTch('(');
|
||
|
EachOpcArgvDw(opcAddDollar, argv, 0); /* Dump in $* format */
|
||
|
AddExpTch(')');
|
||
|
}
|
||
|
AddExpPtok(&tokEol);
|
||
|
CsopExpDopPdivPtok(AddPdivPtok, g_pdivErr, &tok);
|
||
|
FlushPdiv(g_pdivErr);
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************
|
||
|
*
|
||
|
* PushSubstPtokArgv
|
||
|
*
|
||
|
* Produce a macro expansion and shove the result back into the stream.
|
||
|
*
|
||
|
*****************************************************************************/
|
||
|
|
||
|
void STDCALL
|
||
|
PushSubstPtokArgv(PTOK ptok, ARGV argv)
|
||
|
{
|
||
|
PTCH ptch;
|
||
|
TOK tok;
|
||
|
|
||
|
OpenExpPtok(&tok);
|
||
|
|
||
|
for (ptch = ptchPtok(ptok); ptch < ptchMaxPtok(ptok); ptch++) {
|
||
|
if (*ptch != '$' || ptch == ptchMaxPtok(ptok) - 1) {
|
||
|
JustAddIt:
|
||
|
AddExpTch(*ptch);
|
||
|
} else {
|
||
|
switch (ptch[1]) {
|
||
|
|
||
|
case '0': case '1': case '2': case '3': case '4':
|
||
|
case '5': case '6': case '7': case '8': case '9':
|
||
|
if (ptch[1] - '0' <= ctokArgv) {
|
||
|
AddExpPtok(ptokArgv(ptch[1] - '0'));
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case '#': /* $# = argc */
|
||
|
AddExpAt(ctokArgv); /* Note: Add, not Push! */
|
||
|
break;
|
||
|
|
||
|
case '*': /* $* = comma list */
|
||
|
EachOpcArgvDw(opcAddDollar, argv, 0);
|
||
|
break;
|
||
|
|
||
|
case '@': /* $@ = quoted comma list */
|
||
|
EachOpcArgvDw(opcAddDollar, argv, 1);
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
goto JustAddIt; /* Just add the '$' */
|
||
|
}
|
||
|
ptch++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
CsopExpDopPdivPtok((DIVOP)PushZPtok, 0, &tok);
|
||
|
}
|