1 #include <u.h> 2 #include <libc.h> 3 #include "cpp.h" 4 5 Includelist includelist[NINCLUDE]; 6 7 char *objname; 8 9 void 10 doinclude(Tokenrow *trp) 11 { 12 char fname[256], iname[256], *p; 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 if (trp->tp->type==LT) { 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 } else 42 goto syntax; 43 trp->tp += 2; 44 if (trp->tp < trp->lp || len==0) 45 goto syntax; 46 fname[len] = '\0'; 47 if (fname[0]=='/') { 48 fd = open(fname, 0); 49 strcpy(iname, fname); 50 } else for (fd=-1,i=NINCLUDE-1; i>=0; i--) { 51 ip = &includelist[i]; 52 if (ip->file==NULL || ip->deleted || (angled && ip->always==0)) 53 continue; 54 if (strlen(fname)+strlen(ip->file)+2 > sizeof(iname)) 55 continue; 56 strcpy(iname, ip->file); 57 strcat(iname, "/"); 58 strcat(iname, fname); 59 if ((fd = open(iname, 0)) >= 0) 60 break; 61 } 62 if(fd < 0) { 63 strcpy(iname, cursource->filename); 64 p = strrchr(iname, '/'); 65 if(p != NULL) { 66 *p = '\0'; 67 strcat(iname, "/"); 68 strcat(iname, fname); 69 fd = open(iname, 0); 70 } 71 } 72 if ( Mflag>1 || !angled&&Mflag==1 ) { 73 write(1,objname,strlen(objname)); 74 write(1,iname,strlen(iname)); 75 write(1,"\n",1); 76 } 77 if (fd >= 0) { 78 if (++incdepth > 20) 79 error(FATAL, "#include too deeply nested"); 80 setsource((char*)newstring((uchar*)iname, strlen(iname), 0), fd, NULL); 81 genline(); 82 } else { 83 trp->tp = trp->bp+2; 84 error(ERROR, "Could not find include file %r", trp); 85 } 86 return; 87 syntax: 88 error(ERROR, "Syntax error in #include"); 89 return; 90 } 91 92 /* 93 * Generate a line directive for cursource 94 */ 95 void 96 genline(void) 97 { 98 static Token ta = { UNCLASS, NULL, 0, 0 }; 99 static Tokenrow tr = { &ta, &ta, &ta+1, 1 }; 100 uchar *p; 101 102 if(nolineinfo) 103 return; 104 105 ta.t = p = (uchar*)outp; 106 strcpy((char*)p, "#line "); 107 p += sizeof("#line ")-1; 108 p = (uchar*)outnum((char*)p, cursource->line); 109 *p++ = ' '; *p++ = '"'; 110 if (cursource->filename[0]!='/' && wd[0]) { 111 strcpy((char*)p, wd); 112 p += strlen(wd); 113 *p++ = '/'; 114 } 115 strcpy((char*)p, cursource->filename); 116 p += strlen((char*)p); 117 *p++ = '"'; *p++ = '\n'; 118 ta.len = (char*)p-outp; 119 outp = (char*)p; 120 tr.tp = tr.bp; 121 puttokens(&tr); 122 } 123 124 void 125 setobjname(char *f) 126 { 127 int n = strlen(f); 128 objname = (char*)domalloc(n+5); 129 strcpy(objname,f); 130 if(objname[n-2]=='.'){ 131 strcpy(objname+n-1,"$O: "); 132 }else{ 133 strcpy(objname+n,"$O: "); 134 } 135 } 136