]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/cpp/include.c
show line numbers in dtracy type errors
[plan9front.git] / sys / src / cmd / cpp / include.c
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>", Notinmacro);
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 {
51                 fd = -1;
52                 if (!angled) {
53                         strcpy(iname, cursource->filename);
54                         p = strrchr(iname, '/');
55                         if (p != NULL) {
56                                 *p = '\0';
57                                 strcat(iname, "/");
58                                 strcat(iname, fname);
59                                 fd = open(iname, 0);
60                         }
61                 }
62                 for (i=NINCLUDE-1; fd<0 && i>=0; i--) {
63                         ip = &includelist[i];
64                         if (ip->file==NULL || ip->deleted || (angled && ip->always==0))
65                                 continue;
66                         if (strlen(fname)+strlen(ip->file)+2 > sizeof(iname))
67                                 continue;
68                         strcpy(iname, ip->file);
69                         strcat(iname, "/");
70                         strcat(iname, fname);
71                         fd = open(iname, 0);
72                 }
73                 if (fd<0 && angled) {
74                         strcpy(iname, cursource->filename);
75                         p = strrchr(iname, '/');
76                         if(p != NULL) {
77                                 *p = '\0';
78                                 strcat(iname, "/");
79                                 strcat(iname, fname);
80                                 fd = open(iname, 0);
81                         }
82                 }
83         }
84         if ( Mflag>1 || !angled&&Mflag==1 ) {
85                 write(1,objname,strlen(objname));
86                 write(1,iname,strlen(iname));
87                 write(1,"\n",1);
88         }
89         if (fd >= 0) {
90                 if (++incdepth > 20)
91                         error(FATAL, "#include too deeply nested");
92                 setsource((char*)newstring((uchar*)iname, strlen(iname), 0), fd, NULL);
93                 genline();
94         } else {
95                 trp->tp = trp->bp+2;
96                 error(ERROR, "Could not find include file %r", trp);
97         }
98         return;
99 syntax:
100         error(ERROR, "Syntax error in #include");
101         return;
102 }
103
104 /*
105  * Generate a line directive for cursource
106  */
107 void
108 genline(void)
109 {
110         static Token ta = { UNCLASS, NULL, 0, 0 };
111         static Tokenrow tr = { &ta, &ta, &ta+1, 1 };
112         uchar *p;
113
114         if(nolineinfo)
115                 return;
116
117         ta.t = p = (uchar*)outp;
118         strcpy((char*)p, "#line ");
119         p += sizeof("#line ")-1;
120         p = (uchar*)outnum((char*)p, cursource->line);
121         *p++ = ' '; *p++ = '"';
122         if (cursource->filename[0]!='/' && wd[0]) {
123                 strcpy((char*)p, wd);
124                 p += strlen(wd);
125                 *p++ = '/';
126         }
127         strcpy((char*)p, cursource->filename);
128         p += strlen((char*)p);
129         *p++ = '"'; *p++ = '\n';
130         ta.len = (char*)p-outp;
131         outp = (char*)p;
132         tr.tp = tr.bp;
133         puttokens(&tr);
134 }
135
136 void
137 setobjname(char *f)
138 {
139         int n = strlen(f);
140         objname = (char*)domalloc(n+5);
141         strcpy(objname,f);
142         if(objname[n-2]=='.'){
143                 strcpy(objname+n-1,"$O: ");
144         }else{
145                 strcpy(objname+n,"$O: ");
146         }
147 }