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