123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- /* $Header$ */
- /* PREPROCESSOR: MACRO-TEXT REPLACEMENT ROUTINES */
- #include "nopp.h"
- #ifndef NOPP
- #include "debug.h" /* UF */
- #include "pathlength.h" /* UF */
- #include "strsize.h" /* UF */
- #include "alloc.h"
- #include "idf.h"
- #include "input.h"
- #include "macro.h"
- #include "arith.h"
- #include "LLlex.h"
- #include "class.h"
- #include "assert.h"
- #include "interface.h"
- #include "static.h"
- char *strcpy(), *strcat();
- char *long2str();
- EXPORT int
- replace(idef)
- struct idf *idef;
- {
- /* replace() is called by the lexical analyzer to perform
- macro replacement. "idef" is the description of the
- identifier which leads to the replacement. If the
- optional actual parameters of the macro are OK, the text
- of the macro is prepared to serve as an input buffer,
- which is pushed onto the input stack.
- replace() returns 1 if the replacement succeeded and 0 if
- some error has occurred.
- */
- register char c;
- register char flags = idef->id_macro->mc_flag;
- char **actpars, **getactuals();
- char *reptext, *macro2buffer();
- int size;
- if (idef->id_macro->mc_nps != -1) { /* with parameter list */
- LoadChar(c);
- c = skipspaces(c);
- if (c != '(') { /* no replacement if no () */
- lexerror("(warning) macro %s needs arguments",
- idef->id_text);
- PushBack();
- return 0;
- }
- actpars = getactuals(idef); /* get act.param. list */
- }
- if ((flags & PREDEF) && (UnknownIdIsZero == 0))
- /* don't replace this one... */
- return 0;
- if (flags & FUNC) /* this macro leads to special action */
- macro_func(idef);
- /* create and input buffer */
- reptext = macro2buffer(idef, actpars, &size);
- InsertText(reptext, size);
- return 1;
- }
- GSTATIC char FilNamBuf[PATHLENGTH];
- PRIVATE
- macro_func(idef)
- struct idf *idef;
- {
- /* macro_func() performs the special actions needed with some
- macros. These macros are __FILE__ and __LINE__ which
- replacement texts must be evaluated at the time they are
- used.
- */
- /* This switch is very blunt... */
- switch (idef->id_text[2]) {
- case 'F' : /* __FILE__ */
- FilNamBuf[0] = '"';
- strcpy(&FilNamBuf[1], FileName);
- strcat(FilNamBuf, "\"");
- idef->id_macro->mc_text = FilNamBuf;
- idef->id_macro->mc_length = strlen(FilNamBuf);
- break;
- case 'L' : /* __LINE__ */
- idef->id_macro->mc_text = long2str((long)LineNumber, 10);
- idef->id_macro->mc_length = 1;
- break;
- default :
- crash("(macro_func)");
- }
- }
- PRIVATE char *
- macro2buffer(idef, actpars, siztext)
- struct idf *idef;
- char **actpars;
- int *siztext;
- {
- /* Macro2buffer() turns the macro replacement text, as it is
- stored, into an input buffer, while each occurrence of the
- non-ascii formal parameter mark is replaced by its
- corresponding actual parameter specified in the actual
- parameter list actpars. A pointer to the beginning of the
- constructed text is returned, while *siztext is filled
- with its length.
- If there are no parameters, this function behaves
- the same as strcpy().
- */
- register int size = 8;
- register char *text = Malloc(size);
- register pos = 0;
- register char *ptr = idef->id_macro->mc_text;
- text[pos++] = '\0'; /* allow pushback */
- while (*ptr) {
- if (*ptr & FORMALP) { /* non-asc formal param. mark */
- register int n = *ptr++ & 0177;
- register char *p;
- ASSERT(n != 0);
- /* copy the text of the actual parameter
- into the replacement text
- */
- for (p = actpars[n - 1]; *p; p++) {
- text[pos++] = *p;
- if (pos == size)
- text = Srealloc(text,
- size += RSTRSIZE);
- }
- }
- else {
- text[pos++] = *ptr++;
- if (pos == size)
- text = Srealloc(text, size += RSTRSIZE);
- }
- }
- text[pos] = '\0';
- *siztext = pos;
- return text;
- }
- #endif NOPP
|