scan.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. /* $Id$ */
  2. /*
  3. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  4. * See the copyright notice in the ACK home directory, in the file "Copyright".
  5. */
  6. /* PREPROCESSOR: SCANNER FOR THE ACTUAL PARAMETERS OF MACROS */
  7. /* This file contains the function getactuals() which scans an actual
  8. parameter list and splits it up into a list of strings, each one
  9. representing an actual parameter.
  10. */
  11. #include "lapbuf.h" /* UF */
  12. #include "nparams.h" /* UF */
  13. #include "input.h"
  14. #include "class.h"
  15. #include "idf.h"
  16. #include "macro.h"
  17. #include "interface.h"
  18. #include "file_info.h"
  19. #include "LLlex.h"
  20. #define EOS '\0'
  21. #define overflow() (fatal("actual parameter buffer overflow"))
  22. static char apbuf[LAPBUF]; /* temporary storage for actual parameters */
  23. static char *actparams[NPARAMS]; /* pointers to the text of the actuals */
  24. static char *aptr; /* pointer to last inserted character in apbuf */
  25. #define copy(ch) ((aptr < &apbuf[LAPBUF]) ? (*aptr++ = ch) : overflow())
  26. static int nr_of_params; /* number of actuals read until now */
  27. static void copyact(char ch1, char ch2, int level);
  28. char **getactuals(struct idf *idef)
  29. {
  30. /* getactuals() collects the actual parameters and turns them
  31. into a list of strings, a pointer to which is returned.
  32. */
  33. register acnt = idef->id_macro->mc_nps;
  34. nr_of_params = 0;
  35. actparams[0] = aptr = &apbuf[0];
  36. copyact('(', ')', 0); /* read the actual parameters */
  37. copy(EOS); /* mark the end of it all */
  38. if (!nr_of_params++) { /* 0 or 1 parameter */
  39. /* there could be a ( <spaces, comment, ...> )
  40. */
  41. register char *p = actparams[0];
  42. while ((class(*p) == STSKIP) || (*p == '\n')) {
  43. ++p;
  44. }
  45. if (!*p) { /* the case () : 0 parameters */
  46. nr_of_params--;
  47. }
  48. }
  49. if (nr_of_params != acnt) {
  50. /* argument mismatch: too many or too few
  51. actual parameters.
  52. */
  53. warning("argument mismatch, %s", idef->id_text);
  54. while (nr_of_params < acnt) {
  55. /* too few paraeters: remaining actuals are ""
  56. */
  57. actparams[nr_of_params] = "";
  58. nr_of_params++;
  59. }
  60. }
  61. return actparams;
  62. }
  63. static void copyact(char ch1, char ch2, int level)
  64. {
  65. /* copyact() is taken from Ceriel Jacobs' LLgen, with
  66. permission. Its task is to build a list of actuals
  67. parameters, which list is surrounded by '(' and ')' and in
  68. which the parameters are separated by ',' if there are
  69. more than 1. The balancing of '(',')' and '[',']' and
  70. '{','}' is taken care of by calling this function
  71. recursively. At each level, copyact() reads the input,
  72. upto the corresponding closing bracket.
  73. Opening bracket is ch1, closing bracket is ch2. If
  74. level != 0, copy opening and closing parameters too.
  75. */
  76. register int ch; /* Current char */
  77. register int match; /* used to read strings */
  78. if (level) {
  79. copy(ch1);
  80. }
  81. for (;;) {
  82. LoadChar(ch);
  83. if (ch == ch2) {
  84. if (level) {
  85. copy(ch);
  86. }
  87. return;
  88. }
  89. switch(ch) {
  90. #ifdef __MATCHING_PAR__
  91. case ')':
  92. case '}':
  93. case ']':
  94. error("unbalanced parenthesis");
  95. break;
  96. #endif /* __MATCHING_PAR__ */
  97. case '(':
  98. copyact('(', ')', level+1);
  99. break;
  100. #ifdef __MATCHING_PAR__
  101. case '{':
  102. /* example:
  103. #define declare(v, t) t v
  104. declare(v, union{int i, j; float r;});
  105. */
  106. copyact('{', '}', level+1);
  107. break;
  108. case '[':
  109. copyact('[', ']', level+1);
  110. break;
  111. #endif /* __MATCHING_PAR__ */
  112. case '\n':
  113. LineNumber++;
  114. LoadChar(ch);
  115. while (ch == '#') {
  116. /* This piece of code needs some
  117. explanation: consider the call of
  118. the macro defined as:
  119. #define sum(b,c) (b + c)
  120. in the following form:
  121. sum(
  122. #include my_phone_number
  123. ,2)
  124. in which case the include must be
  125. interpreted as such.
  126. */
  127. domacro(); /* has read nl, vt or ff */
  128. LoadChar(ch);
  129. /* Loop, for another control line */
  130. }
  131. PushBack();
  132. copy(' ');
  133. break;
  134. case '/':
  135. LoadChar(ch);
  136. if (ch == '*') { /* skip comment */
  137. skipcomment();
  138. continue;
  139. }
  140. PushBack();
  141. copy('/');
  142. break;
  143. case ',':
  144. if (!level) {
  145. /* next parameter encountered */
  146. copy(EOS);
  147. if (++nr_of_params >= NPARAMS) {
  148. fatal("(getact) too many actuals");
  149. }
  150. actparams[nr_of_params] = aptr;
  151. }
  152. else {
  153. copy(ch);
  154. }
  155. break;
  156. case '\'':
  157. case '"' :
  158. /* watch out for brackets in strings, they do
  159. not count !
  160. */
  161. match = ch;
  162. copy(ch);
  163. LoadChar(ch);
  164. while (ch != EOI) {
  165. if (ch == match) {
  166. break;
  167. }
  168. if (ch == '\\') {
  169. copy(ch);
  170. LoadChar(ch);
  171. }
  172. else
  173. if (ch == '\n') {
  174. LineNumber++;
  175. error("newline in string");
  176. copy(match);
  177. break;
  178. }
  179. copy(ch);
  180. LoadChar(ch);
  181. }
  182. if (ch == match) {
  183. copy(ch);
  184. break;
  185. }
  186. /* Fall through */
  187. case EOI :
  188. error("unterminated macro call");
  189. return;
  190. default:
  191. copy(ch);
  192. break;
  193. }
  194. }
  195. }