nlist.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <stdio.h>
  4. #include "cpp.h"
  5. extern int getopt(int, char **, char *);
  6. extern char *optarg;
  7. extern int optind;
  8. int verbose;
  9. int Mflag;
  10. int Cplusplus;
  11. int nolineinfo;
  12. Nlist *kwdefined;
  13. char wd[128];
  14. #define NLSIZE 128
  15. Nlist *nlist[NLSIZE];
  16. struct kwtab {
  17. char *kw;
  18. int val;
  19. int flag;
  20. } kwtab[] = {
  21. "if", KIF, ISKW,
  22. "ifdef", KIFDEF, ISKW,
  23. "ifndef", KIFNDEF, ISKW,
  24. "elif", KELIF, ISKW,
  25. "else", KELSE, ISKW,
  26. "endif", KENDIF, ISKW,
  27. "include", KINCLUDE, ISKW,
  28. "define", KDEFINE, ISKW,
  29. "undef", KUNDEF, ISKW,
  30. "line", KLINE, ISKW,
  31. "error", KERROR, ISKW,
  32. "pragma", KPRAGMA, ISKW,
  33. "eval", KEVAL, ISKW,
  34. "defined", KDEFINED, ISDEFINED+ISUNCHANGE,
  35. "__LINE__", KLINENO, ISMAC+ISUNCHANGE,
  36. "__FILE__", KFILE, ISMAC+ISUNCHANGE,
  37. "__DATE__", KDATE, ISMAC+ISUNCHANGE,
  38. "__TIME__", KTIME, ISMAC+ISUNCHANGE,
  39. "__STDC__", KSTDC, ISUNCHANGE,
  40. NULL
  41. };
  42. unsigned long namebit[077+1];
  43. Nlist *np;
  44. void
  45. setup(int argc, char **argv)
  46. {
  47. struct kwtab *kp;
  48. Nlist *np;
  49. Token t;
  50. int fd, i;
  51. char *fp, *dp;
  52. Tokenrow tr;
  53. char *objtype;
  54. char *includeenv;
  55. int firstinclude;
  56. static char nbuf[40];
  57. static Token deftoken[1] = {{ NAME, 0, 0, 0, 7, (uchar*)"defined" }};
  58. static Tokenrow deftr = { deftoken, deftoken, deftoken+1, 1 };
  59. int debuginclude = 0;
  60. char xx[2] = { 0, 0};
  61. for (kp=kwtab; kp->kw; kp++) {
  62. t.t = (uchar*)kp->kw;
  63. t.len = strlen(kp->kw);
  64. np = lookup(&t, 1);
  65. np->flag = kp->flag;
  66. np->val = kp->val;
  67. if (np->val == KDEFINED) {
  68. kwdefined = np;
  69. np->val = NAME;
  70. np->vp = &deftr;
  71. np->ap = 0;
  72. }
  73. }
  74. /*
  75. * For Plan 9, search /objtype/include, then /sys/include
  76. * (Note that includelist is searched from high end to low)
  77. */
  78. if ((objtype = getenv("objtype"))){
  79. sprintf(nbuf, "/%s/include", objtype);
  80. includelist[1].file = nbuf;
  81. includelist[1].always = 1;
  82. } else {
  83. includelist[1].file = NULL;
  84. error(WARNING, "Unknown $objtype");
  85. }
  86. if (getwd(wd, sizeof(wd))==0)
  87. wd[0] = '\0';
  88. includelist[0].file = "/sys/include";
  89. includelist[0].always = 1;
  90. firstinclude = NINCLUDE-2;
  91. if ((includeenv=getenv("include")) != NULL) {
  92. char *cp;
  93. includeenv = strdup(includeenv);
  94. for (;firstinclude>0; firstinclude--) {
  95. cp = strtok(includeenv, " ");
  96. if (cp==NULL)
  97. break;
  98. includelist[firstinclude].file = cp;
  99. includelist[firstinclude].always = 1;
  100. includeenv = NULL;
  101. }
  102. }
  103. setsource("", -1, 0);
  104. ARGBEGIN {
  105. case 'N':
  106. for (i=0; i<NINCLUDE; i++)
  107. if (includelist[i].always==1)
  108. includelist[i].deleted = 1;
  109. break;
  110. case 'I':
  111. for (i=firstinclude; i>=0; i--) {
  112. if (includelist[i].file==NULL) {
  113. includelist[i].always = 1;
  114. includelist[i].file = ARGF();
  115. break;
  116. }
  117. }
  118. if (i<0)
  119. error(WARNING, "Too many -I directives");
  120. break;
  121. case 'D':
  122. case 'U':
  123. setsource("<cmdarg>", -1, ARGF());
  124. maketokenrow(3, &tr);
  125. gettokens(&tr, 1);
  126. doadefine(&tr, ARGC());
  127. unsetsource();
  128. break;
  129. case 'M':
  130. Mflag++;
  131. break;
  132. case 'V':
  133. verbose++;
  134. break;
  135. case '+':
  136. Cplusplus++;
  137. break;
  138. case 'i':
  139. debuginclude++;
  140. break;
  141. case 'P':
  142. nolineinfo++;
  143. break;
  144. default:
  145. xx[0] = ARGC();
  146. error(FATAL, "Unknown argument '%s'", xx);
  147. break;
  148. } ARGEND
  149. dp = ".";
  150. fp = "<stdin>";
  151. fd = 0;
  152. if (argc > 0) {
  153. if ((fp = strrchr(argv[0], '/')) != NULL) {
  154. int len = fp - argv[0];
  155. dp = (char*)newstring((uchar*)argv[0], len+1, 0);
  156. dp[len] = '\0';
  157. }
  158. fp = (char*)newstring((uchar*)argv[0], strlen(argv[0]), 0);
  159. if ((fd = open(fp, 0)) <= 0)
  160. error(FATAL, "Can't open input file %s", fp);
  161. }
  162. if (argc > 1) {
  163. int fdo = create(argv[1], 1, 0666);
  164. if (fdo<0)
  165. error(FATAL, "Can't open output file %s", argv[1]);
  166. dup(fdo, 1);
  167. }
  168. if (Mflag)
  169. setobjname(fp);
  170. includelist[NINCLUDE-1].always = 0;
  171. includelist[NINCLUDE-1].file = dp;
  172. setsource(fp, fd, NULL);
  173. if (debuginclude) {
  174. for (i=0; i<NINCLUDE; i++)
  175. if (includelist[i].file && includelist[i].deleted==0)
  176. error(WARNING, "Include: %s", includelist[i].file);
  177. }
  178. }
  179. Nlist *
  180. lookup(Token *tp, int install)
  181. {
  182. unsigned int h;
  183. Nlist *np;
  184. uchar *cp, *cpe;
  185. h = 0;
  186. for (cp=tp->t, cpe=cp+tp->len; cp<cpe; )
  187. h += *cp++;
  188. h %= NLSIZE;
  189. np = nlist[h];
  190. while (np) {
  191. if (*tp->t==*np->name && tp->len==np->len
  192. && strncmp((char*)tp->t, (char*)np->name, tp->len)==0)
  193. return np;
  194. np = np->next;
  195. }
  196. if (install) {
  197. np = new(Nlist);
  198. np->val = 0;
  199. np->vp = NULL;
  200. np->ap = NULL;
  201. np->flag = 0;
  202. np->len = tp->len;
  203. np->name = newstring(tp->t, tp->len, 0);
  204. np->next = nlist[h];
  205. nlist[h] = np;
  206. quickset(tp->t[0], tp->len>1? tp->t[1]:0);
  207. return np;
  208. }
  209. return NULL;
  210. }