1 /***********************************************************************
3 * This software is part of the ast package *
4 * Copyright (c) 1986-2009 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
13 * Information and Software Systems Research *
17 * Glenn Fowler <gsf@research.att.com> *
19 ***********************************************************************/
25 * miscellaneous preprocessor support
31 * macro symbol def|ref
35 pprefmac(char* name
, int ref
)
37 register struct ppsymbol
* sym
;
39 if (!(sym
= ppsymget(pp
.symtab
, name
)) && (ref
<= REF_NORMAL
&& pp
.macref
|| ref
== REF_CREATE
|| ref
== REF_DELETE
&& (pp
.mode
& (INIT
|READONLY
))))
41 if ((pp
.state
& COMPILE
) && pp
.truncate
&& strlen(name
) > pp
.truncate
)
42 name
[pp
.truncate
] = 0;
43 sym
= ppsymset(pp
.symtab
, NiL
);
45 if (sym
&& ref
<= REF_NORMAL
)
47 if (pp
.macref
) (*pp
.macref
)(sym
, error_info
.file
, error_info
.line
, ref
== REF_NORMAL
&& (pp
.state
& CONDITIONAL
) ? REF_IF
: ref
, 0L);
48 if (!sym
->macro
) sym
= 0;
51 if (!(pp
.state
& COMPATIBILITY
))
53 if (ref
== REF_IF
&& sym
&& (sym
->flags
& SYM_PREDEFINED
) && *name
!= '_' && !(pp
.mode
& (HOSTED
|INACTIVE
)))
55 if (pp
.state
& STRICT
)
57 error(1, "%s: obsolete predefined symbol reference disabled", name
);
60 error(1, "%s: obsolete predefined symbol referenced", name
);
66 * common predicate assertion operations
67 * op is DEFINE or UNDEF
71 ppassert(int op
, char* pred
, char* args
)
73 register struct pplist
* a
;
74 register struct ppsymbol
* sym
;
75 register struct pplist
* p
;
76 register struct pplist
* q
;
78 if (!args
) switch (op
)
86 if (a
= (struct pplist
*)hashget(pp
.prdtab
, pred
))
92 if (streq(q
->value
, args
))
94 if (op
== DEFINE
) return;
108 hashput(pp
.prdtab
, pred
, a
);
109 if (sym
= ppsymref(pp
.symtab
, pred
))
110 sym
->flags
&= ~SYM_PREDICATE
;
116 p
= newof(0, struct pplist
, 1, 0);
118 p
->value
= strdup(args
);
119 hashput(pp
.prdtab
, NiL
, p
);
121 if ((pp
.state
& COMPILE
) && pp
.truncate
) return;
122 if (sym
= ppsymset(pp
.symtab
, pred
))
123 sym
->flags
|= SYM_PREDICATE
;
128 * parse a predicate argument list
129 * the args are placed in pp.args
130 * the first non-space/paren argument token type is returned
133 * predicate <identifier> type=T_ID
134 * predicate ( <identifier> ) type=T_ID
135 * predicate ( ) type=0
136 * predicate ( <balanced-paren-list> ) type=T_STRING
137 * otherwise type=<other>
150 switch (type
= pplex())
158 pp
.state
&= ~NOSPACE
;
168 error(2, "missing %d )%s in predicate argument list", n
, n
== 1 ? "" : "'s");
175 pp
.token
= pp
.toknxt
;
178 if (type
) type
= T_STRING
;
179 else type
= (c
== T_ID
) ? T_ID
: T_STRING
;
185 pp
.state
|= NOSPACE
|STRIP
;
186 if (pp
.token
> pp
.args
&& *(pp
.token
- 1) == ' ') pp
.token
--;
199 * sync output line number
207 if ((pp
.state
& (ADD
|HIDDEN
)))
212 m
= pp
.addp
- pp
.addbuf
;
214 ppprintf("%-.*s", m
, pp
.addbuf
);
218 if ((pp
.state
& SYNCLINE
) || pp
.hidden
>= MAXHIDDEN
)
221 pp
.state
&= ~(HIDDEN
|SYNCLINE
);
223 (*pp
.linesync
)(error_info
.line
, error_info
.file
);