replace.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. /* $Header$ */
  2. /* PREPROCESSOR: MACRO-TEXT REPLACEMENT ROUTINES */
  3. #include "nopp.h"
  4. #ifndef NOPP
  5. #include "debug.h" /* UF */
  6. #include "pathlength.h" /* UF */
  7. #include "strsize.h" /* UF */
  8. #include "alloc.h"
  9. #include "idf.h"
  10. #include "input.h"
  11. #include "macro.h"
  12. #include "arith.h"
  13. #include "LLlex.h"
  14. #include "class.h"
  15. #include "assert.h"
  16. #include "interface.h"
  17. #include "static.h"
  18. char *strcpy(), *strcat();
  19. char *long2str();
  20. EXPORT int
  21. replace(idef)
  22. struct idf *idef;
  23. {
  24. /* replace() is called by the lexical analyzer to perform
  25. macro replacement. "idef" is the description of the
  26. identifier which leads to the replacement. If the
  27. optional actual parameters of the macro are OK, the text
  28. of the macro is prepared to serve as an input buffer,
  29. which is pushed onto the input stack.
  30. replace() returns 1 if the replacement succeeded and 0 if
  31. some error has occurred.
  32. */
  33. register char c;
  34. register char flags = idef->id_macro->mc_flag;
  35. char **actpars, **getactuals();
  36. char *reptext, *macro2buffer();
  37. int size;
  38. if (idef->id_macro->mc_nps != -1) { /* with parameter list */
  39. LoadChar(c);
  40. c = skipspaces(c);
  41. if (c != '(') { /* no replacement if no () */
  42. lexerror("(warning) macro %s needs arguments",
  43. idef->id_text);
  44. PushBack();
  45. return 0;
  46. }
  47. actpars = getactuals(idef); /* get act.param. list */
  48. }
  49. if ((flags & PREDEF) && (UnknownIdIsZero == 0))
  50. /* don't replace this one... */
  51. return 0;
  52. if (flags & FUNC) /* this macro leads to special action */
  53. macro_func(idef);
  54. /* create and input buffer */
  55. reptext = macro2buffer(idef, actpars, &size);
  56. InsertText(reptext, size);
  57. return 1;
  58. }
  59. GSTATIC char FilNamBuf[PATHLENGTH];
  60. PRIVATE
  61. macro_func(idef)
  62. struct idf *idef;
  63. {
  64. /* macro_func() performs the special actions needed with some
  65. macros. These macros are __FILE__ and __LINE__ which
  66. replacement texts must be evaluated at the time they are
  67. used.
  68. */
  69. /* This switch is very blunt... */
  70. switch (idef->id_text[2]) {
  71. case 'F' : /* __FILE__ */
  72. FilNamBuf[0] = '"';
  73. strcpy(&FilNamBuf[1], FileName);
  74. strcat(FilNamBuf, "\"");
  75. idef->id_macro->mc_text = FilNamBuf;
  76. idef->id_macro->mc_length = strlen(FilNamBuf);
  77. break;
  78. case 'L' : /* __LINE__ */
  79. idef->id_macro->mc_text = long2str((long)LineNumber, 10);
  80. idef->id_macro->mc_length = 1;
  81. break;
  82. default :
  83. crash("(macro_func)");
  84. }
  85. }
  86. PRIVATE char *
  87. macro2buffer(idef, actpars, siztext)
  88. struct idf *idef;
  89. char **actpars;
  90. int *siztext;
  91. {
  92. /* Macro2buffer() turns the macro replacement text, as it is
  93. stored, into an input buffer, while each occurrence of the
  94. non-ascii formal parameter mark is replaced by its
  95. corresponding actual parameter specified in the actual
  96. parameter list actpars. A pointer to the beginning of the
  97. constructed text is returned, while *siztext is filled
  98. with its length.
  99. If there are no parameters, this function behaves
  100. the same as strcpy().
  101. */
  102. register int size = 8;
  103. register char *text = Malloc(size);
  104. register pos = 0;
  105. register char *ptr = idef->id_macro->mc_text;
  106. text[pos++] = '\0'; /* allow pushback */
  107. while (*ptr) {
  108. if (*ptr & FORMALP) { /* non-asc formal param. mark */
  109. register int n = *ptr++ & 0177;
  110. register char *p;
  111. ASSERT(n != 0);
  112. /* copy the text of the actual parameter
  113. into the replacement text
  114. */
  115. for (p = actpars[n - 1]; *p; p++) {
  116. text[pos++] = *p;
  117. if (pos == size)
  118. text = Srealloc(text,
  119. size += RSTRSIZE);
  120. }
  121. }
  122. else {
  123. text[pos++] = *ptr++;
  124. if (pos == size)
  125. text = Srealloc(text, size += RSTRSIZE);
  126. }
  127. }
  128. text[pos] = '\0';
  129. *siztext = pos;
  130. return text;
  131. }
  132. #endif NOPP