1 #include <u.h> 2 #include <libc.h> 3 #include "cpp.h" 4 5 Includelist includelist[NINCLUDE] = { 6 { 0, 1, "/usr/include" }, 7 }; 8 9 void 10 doinclude(Tokenrow *trp) 11 { 12 char fname[256], iname[256]; 13 Includelist *ip; 14 int angled, len, fd, i; 15 16 trp->tp += 1; 17 if (trp->tp>=trp->lp) 18 goto syntax; 19 if (trp->tp->type!=STRING && trp->tp->type!=LT) { 20 len = trp->tp - trp->bp; 21 expandrow(trp, "<include>"); 22 trp->tp = trp->bp+len; 23 } 24 if (trp->tp->type==STRING) { 25 len = trp->tp->len-2; 26 if (len > sizeof(fname) - 1) 27 len = sizeof(fname) - 1; 28 strncpy(fname, (char*)trp->tp->t+1, len); 29 angled = 0; 30 } else { 31 len = 0; 32 trp->tp++; 33 while (trp->tp->type!=GT) { 34 if (trp->tp>trp->lp || len+trp->tp->len+2 >= sizeof(fname)) 35 goto syntax; 36 strncpy(fname+len, (char*)trp->tp->t, trp->tp->len); 37 len += trp->tp->len; 38 trp->tp++; 39 } 40 angled = 1; 41 } 42 trp->tp += 2; 43 if (trp->tp < trp->lp || len==0) 44 goto syntax; 45 fname[len] = '\0'; 46 if (fname[0]=='/') { 47 fd = open(fname, 0); 48 strcpy(iname, fname); 49 } else for (fd=-1,i=NINCLUDE-1; i>=0; i--) { 50 ip = &includelist[i]; 51 if (ip->file==NULL || ip->deleted || (angled && ip->always==0)) 52 continue; 53 if (strlen(fname)+strlen(ip->file)+2 > sizeof(iname)) 54 continue; 55 strcpy(iname, ip->file); 56 strcat(iname, "/"); 57 strcat(iname, fname); 58 if ((fd = open(iname, 0)) >= 0) 59 break; 60 } 61 if (fd >= 0) { 62 if (++incdepth > 10) 63 error(FATAL, "#include too deeply nested"); 64 setsource((char*)newstring((uchar*)iname, strlen(iname), 0), fd, NULL); 65 genline(); 66 } else { 67 trp->tp = trp->bp+2; 68 error(ERROR, "Could not find include file %r", trp); 69 } 70 return; 71 syntax: 72 error(ERROR, "Syntax error in #include"); 73 return; 74 } 75 76 /* 77 * Generate a line directive for cursource 78 */ 79 void 80 genline(void) 81 { 82 static Token ta = { UNCLASS, NULL, 0, 0 }; 83 static Tokenrow tr = { &ta, &ta, &ta+1, 1 }; 84 uchar *p; 85 86 ta.t = p = (uchar*)outp; 87 strcpy((char*)p, "#line "); 88 p += sizeof("#line ")-1; 89 p = (uchar*)outnum((char*)p, cursource->line); 90 *p++ = ' '; *p++ = '"'; 91 strcpy((char*)p, cursource->filename); 92 p += strlen((char*)p); 93 *p++ = '"'; *p++ = '\n'; 94 ta.len = (char*)p-outp; 95 outp = (char*)p; 96 tr.tp = tr.bp; 97 puttokens(&tr); 98 } 99