155 lines
3.7 KiB
C
155 lines
3.7 KiB
C
|
/*****************************************************************************
|
||
|
*
|
||
|
* define.c
|
||
|
*
|
||
|
* Builtins related to object definitions.
|
||
|
*
|
||
|
*****************************************************************************/
|
||
|
|
||
|
#include "m4.h"
|
||
|
|
||
|
/*****************************************************************************
|
||
|
*
|
||
|
* opDefineOrPushdef
|
||
|
*
|
||
|
* Common worker for opDefine and opPushdef.
|
||
|
*
|
||
|
* If we are not pushing, then we must pop off the previous value
|
||
|
* in order to free its memory, before pushing the new definition.
|
||
|
*
|
||
|
* QUIRK! GNU m4 emits a warning if $# > 2. AT&T silently ignores
|
||
|
* extra arguments. I side with AT&T on this one.
|
||
|
*
|
||
|
* QUIRK! GNU m4 emits `$0' if $# = 0. AT&T silently ignores
|
||
|
* the entire macro call. I side with GNU on this one.
|
||
|
*
|
||
|
* WARNING! main.c::DefinePtsz assumes that we don't look at
|
||
|
* argv[0] if the correct number of parameters are passed!
|
||
|
*
|
||
|
*****************************************************************************/
|
||
|
|
||
|
void STDCALL
|
||
|
opDefineOrPushdef(ARGV argv, BOOL fPush)
|
||
|
{
|
||
|
if (ctokArgv > 0) {
|
||
|
/*
|
||
|
* Ensure that we don't mess with argv[0].
|
||
|
*/
|
||
|
D(SIG sigOld = argv[0].sig);
|
||
|
D(argv[0].sig = 0);
|
||
|
if (fIdentPtok(ptokArgv(1))) {
|
||
|
PMAC pmac = pmacGetPtok(ptokArgv(1));
|
||
|
if (!fPush) {
|
||
|
if (pmac->pval) {
|
||
|
PopdefPmac(pmac); /* Pop off previous value */
|
||
|
}
|
||
|
}
|
||
|
PushdefPmacPtok(pmac, ptokArgv(2));
|
||
|
#ifdef STRICT_M4
|
||
|
if (ctokArgv > 2) {
|
||
|
Warn("extra arguments ignored");
|
||
|
}
|
||
|
#endif
|
||
|
} else {
|
||
|
Die("invalid macro name");
|
||
|
}
|
||
|
D(argv[0].sig = sigOld);
|
||
|
} else {
|
||
|
PushQuotedPtok(ptokArgv(0));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************
|
||
|
*
|
||
|
* opDefine
|
||
|
*
|
||
|
* Set the expansion of $1 to $2, destroying any previous value.
|
||
|
*
|
||
|
* opPushdef
|
||
|
*
|
||
|
* Same as opDefine, except pushes the previous value.
|
||
|
*
|
||
|
*****************************************************************************/
|
||
|
|
||
|
DeclareOp(opDefine)
|
||
|
{
|
||
|
opDefineOrPushdef(argv, 0);
|
||
|
}
|
||
|
|
||
|
DeclareOp(opPushdef)
|
||
|
{
|
||
|
opDefineOrPushdef(argv, 1);
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************
|
||
|
*
|
||
|
* opPopdef
|
||
|
*
|
||
|
* Restores the most recently pushed definition.
|
||
|
*
|
||
|
* If the macro name is invalid, fail silently.
|
||
|
*
|
||
|
*****************************************************************************/
|
||
|
|
||
|
DeclareOpc(opcPopdef)
|
||
|
{
|
||
|
PMAC pmac = pmacFindPtok(ptok);
|
||
|
if (pmac) {
|
||
|
Assert(pmac->pval);
|
||
|
if (pmac->pval->pvalPrev) {
|
||
|
PopdefPmac(pmac);
|
||
|
} else {
|
||
|
FreePmac(pmac);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
DeclareOp(opPopdef)
|
||
|
{
|
||
|
EachOpcArgvDw(opcPopdef, argv, 0);
|
||
|
}
|
||
|
|
||
|
/*****************************************************************************
|
||
|
*
|
||
|
* opUndefine
|
||
|
*
|
||
|
* Removes the definitions of all its arguments.
|
||
|
*
|
||
|
*****************************************************************************/
|
||
|
|
||
|
DeclareOpc(opcUndefine)
|
||
|
{
|
||
|
PMAC pmac = pmacFindPtok(ptok);
|
||
|
if (pmac) {
|
||
|
FreePmac(pmac);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
DeclareOp(opUndefine)
|
||
|
{
|
||
|
EachOpcArgvDw(opcUndefine, argv, 0);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*****************************************************************************
|
||
|
*
|
||
|
* opDefn
|
||
|
*
|
||
|
* Returns the quoted definition of its argument(s), concatenated
|
||
|
* from left to right.
|
||
|
*
|
||
|
*****************************************************************************/
|
||
|
|
||
|
DeclareOpc(opcDefn)
|
||
|
{
|
||
|
PMAC pmac = pmacFindPtok(ptok);
|
||
|
if (pmac) {
|
||
|
PushQuotedPtok(&pmac->pval->tok);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
DeclareOp(opDefn)
|
||
|
{
|
||
|
EachReverseOpcArgvDw(opcDefn, argv, 0);
|
||
|
}
|