xref: /trunk/main/soltools/cpp/_include.c (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 #if (defined(_WIN32) || defined(_MSDOS) || defined(__IBMC__))
2 #   include <io.h>
3 #else
4 #   include <unistd.h>
5 #endif
6 
7 #ifdef _MSC_VER
8 #   define _POSIX_
9 #endif
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <fcntl.h>
14 
15 
16 #ifdef __hpux
17 #   define _HPUX_SOURCE
18 #endif
19 #if defined(__IBMC__) || defined(__EMX__)
20 #   include <fcntl.h>
21 #   define PATH_MAX _MAX_PATH
22 #endif
23 #include <limits.h>
24 
25 #include "cpp.h"
26 
27 Includelist includelist[NINCLUDE];
28 Wraplist wraplist[NINCLUDE];
29 
30 void
31     doinclude(Tokenrow * trp, int depth, int import)
32 {
33     char fname[PATH_MAX], iname[PATH_MAX];
34     Includelist *ip;
35     int angled, fd, i;
36     size_t len;
37 
38     trp->tp += 1;
39     if (trp->tp >= trp->lp)
40         goto syntax;
41     if (trp->tp->type != STRING && trp->tp->type != LT)
42     {
43         len = trp->tp - trp->bp;
44         expandrow(trp, "<include>");
45         trp->tp = trp->bp + len;
46     }
47     if (trp->tp->type == STRING)
48     {
49         len = trp->tp->len - 2;
50         if (len > sizeof(fname) - 1)
51             len = sizeof(fname) - 1;
52         strncpy(fname, (char *) trp->tp->t + 1, len);
53         angled = 0;
54     }
55     else
56     {
57         if (trp->tp->type == LT)
58         {
59             len = 0;
60             trp->tp++;
61             while (trp->tp->type != GT)
62             {
63                 if (trp->tp > trp->lp || len + trp->tp->len + 2 >= sizeof(fname))
64                     goto syntax;
65                 strncpy(fname + len, (char *) trp->tp->t, trp->tp->len);
66                 len += trp->tp->len;
67                 trp->tp++;
68             }
69             angled = 1;
70         }
71         else
72             goto syntax;
73     }
74     trp->tp += 2;
75     if (trp->tp < trp->lp || len == 0)
76         goto syntax;
77     fname[len] = '\0';
78     if (fname[0] == '/')
79     {
80         fd = open(fname, O_RDONLY);
81         strcpy(iname, fname);
82     }
83     else
84     {
85         for (fd = -1, i = (depth < 0) ? (NINCLUDE - 1) : (depth - 1); i >= 0; i--)
86         {
87             ip = &includelist[i];
88             if (ip->file == NULL || ip->deleted || (angled && ip->always == 0))
89                 continue;
90             if (strlen(fname) + strlen(ip->file) + 2 > sizeof(iname))
91                 continue;
92             strcpy(iname, ip->file);
93             strcat(iname, "/");
94             strcat(iname, fname);
95             if ((fd = open(iname, O_RDONLY)) >= 0)
96                 break;
97         }
98     }
99 
100     if (fd >= 0)
101     {
102         if (++incdepth > NINC )
103             error(FATAL, "#%s too deeply nested", import ? "import" : "include");
104         if (Xflag)
105             genimport(fname, angled, iname, import);
106         if (Iflag)
107             error(INFO, "Open %s file [%s]", import ? "import" : "include", iname );
108 
109         for (i = NINCLUDE - 1; i >= 0; i--)
110         {
111             if ((wraplist[i].file != NULL) &&
112                 (strncmp(wraplist[i].file, iname, strlen(wraplist[i].file)) == 0))
113                 break;
114         }
115 
116         setsource((char *) newstring((uchar *) iname, strlen(iname), 0), i, fd, NULL, (i >= 0) ? 1 : 0);
117 
118         if (!Pflag)
119             genline();
120     }
121     else
122     {
123         trp->tp = trp->bp + 2;
124         error(ERROR, "Could not find %s file %r", import ? "import" : "include", trp);
125     }
126     return;
127 syntax:
128     error(ERROR, "Syntax error in #%s", import ? "import" : "include");
129     return;
130 }
131 
132 /*
133  * Generate a line directive for cursource
134  */
135 void
136     genline(void)
137 {
138     static Token ta = {UNCLASS, 0, 0, 0, NULL, 0};
139     static Tokenrow tr = {&ta, &ta, &ta + 1, 1};
140     uchar *p;
141 
142     ta.t = p = (uchar *) outptr;
143     strcpy((char *) p, "#line ");
144     p += sizeof("#line ") - 1;
145     p = (uchar *) outnum((char *) p, cursource->line);
146     *p++ = ' ';
147     *p++ = '"';
148     if (cursource->filename[0] != '/' && wd[0])
149     {
150         strcpy((char *) p, wd);
151         p += strlen(wd);
152         *p++ = '/';
153     }
154     strcpy((char *) p, cursource->filename);
155     p += strlen((char *) p);
156     *p++ = '"';
157     *p++ = '\n';
158     ta.len = (char *) p - outptr;
159     outptr = (char *) p;
160     tr.tp = tr.bp;
161     puttokens(&tr);
162 }
163 
164 /*
165  * Generate a pragma import/include directive
166  */
167 void
168     genimport(char *fname, int angled, char *iname, int import)
169 {
170     static Token ta = {UNCLASS, 0, 0, 0, NULL, 0};
171     static Tokenrow tr = {&ta, &ta, &ta + 1, 1};
172     uchar *p;
173 
174     ta.t = p = (uchar *) outptr;
175 
176     if (import)
177         strcpy((char *) p, "#pragma import");
178     else
179         strcpy((char *) p, "#pragma include");
180 
181     p += strlen((char *) p);
182 
183     *p++ = '(';
184 
185     *p++ = angled ? '<' : '"';
186     strcpy((char *) p, fname);
187     p += strlen(fname);
188     *p++ = angled ? '>' : '"';
189 
190     *p++ = ',';
191 
192     *p++ = '"';
193     strcpy((char *) p, iname);
194     p += strlen(iname);
195     *p++ = '"';
196 
197     *p++ = ')';
198     *p++ = '\n';
199 
200     ta.len = (char *) p - outptr;
201     outptr = (char *) p;
202     tr.tp = tr.bp;
203     puttokens(&tr);
204 }
205 
206 /*
207  * Generate a extern C directive
208  */
209 void
210     genwrap(int end)
211 {
212     static Token ta = {UNCLASS, 0, 0, 0, NULL, 0};
213     static Tokenrow tr = {&ta, &ta, &ta + 1, 1};
214     uchar *p;
215 
216     if (Cplusplus)
217     {
218         ta.t = p = (uchar *) outptr;
219 
220         if (! end)
221             strcpy((char *) p, "extern \"C\" {");
222         else
223             strcpy((char *) p, "}");
224 
225         p += strlen((char *) p);
226 
227         *p++ = '\n';
228 
229         ta.len = (char *) p - outptr;
230         outptr = (char *) p;
231         tr.tp = tr.bp;
232         puttokens(&tr);
233     }
234 }
235 
236