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