calc: on editing invalidation of view with different zoom is wrong
[LibreOffice.git] / soltools / cpp / _cpp.c
blob9dd3a294d1b5caa9e4e4a32cd96ef45c391e875f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <time.h>
24 #include <stdarg.h>
25 #include "cpp.h"
27 #define OUTS 16384
28 static char outbuf[OUTS];
29 char* outptr = outbuf;
30 Source* cursource;
31 static int nerrs;
32 struct token nltoken = { NL, 0, 1, (uchar*)"\n", 0 };
33 char* curtime;
34 int incdepth;
35 int ifdepth;
36 int ifsatisfied[NIF];
37 int skipping;
39 int
40 #ifdef _WIN32
41 __cdecl
42 #endif // _WIN32
43 main(int argc, char** argv)
45 Tokenrow tr;
46 time_t t;
47 char ebuf[BUFSIZ];
49 setbuf(stderr, ebuf);
50 t = time(NULL);
51 curtime = ctime(&t);
52 maketokenrow(3, &tr);
53 expandlex();
54 // coverity[tainted_string] - build time test tool
55 setup(argc, argv);
56 fixlex();
57 if (!Pflag)
58 genline();
59 process(&tr);
60 flushout();
61 fflush(stderr);
62 exit(nerrs > 0);
65 void process(Tokenrow* trp)
67 int anymacros = 0;
69 for (;;)
71 if (trp->tp >= trp->lp)
73 trp->tp = trp->lp = trp->bp;
74 outptr = outbuf;
75 // coverity[overrun-buffer-arg: FALSE] - a multiple of trp->max is allocated, not trp->max itself
76 anymacros |= gettokens(trp, 1);
77 trp->tp = trp->bp;
79 if (trp->tp->type == END)
81 if (--incdepth >= 0)
83 if (cursource->ifdepth)
84 error(ERROR, "Unterminated conditional in #include");
85 unsetsource();
86 cursource->line += cursource->lineinc;
87 trp->tp = trp->lp;
88 if (!Pflag)
89 genline();
90 continue;
92 if (ifdepth)
93 error(ERROR, "Unterminated #if/#ifdef/#ifndef");
94 break;
96 if (trp->tp->type == SHARP)
98 trp->tp += 1;
99 control(trp);
101 else if (!skipping && anymacros)
102 expandrow(trp, NULL);
103 if (skipping)
104 setempty(trp);
105 puttokens(trp);
106 anymacros = 0;
107 cursource->line += cursource->lineinc;
108 if (cursource->lineinc > 1 && !Pflag)
109 genline();
113 void control(Tokenrow* trp)
115 Nlist* np;
116 Token* tp;
118 tp = trp->tp;
119 if (tp->type != NAME)
121 if (tp->type == NUMBER)
122 goto kline;
123 if (tp->type != NL)
124 error(ERROR, "Unidentifiable control line");
125 return; /* else empty line */
127 np = lookup(tp, 0);
128 if (np == NULL || ((np->flag & ISKW) == 0 && !skipping))
130 error(WARNING, "Unknown preprocessor control %t", tp);
131 return;
133 if (skipping)
135 switch (np->val)
137 case KENDIF:
138 if (--ifdepth < skipping)
139 skipping = 0;
140 --cursource->ifdepth;
141 setempty(trp);
142 return;
144 case KIFDEF:
145 case KIFNDEF:
146 case KIF:
147 if (++ifdepth >= NIF)
148 error(FATAL, "#if too deeply nested");
149 ++cursource->ifdepth;
150 return;
152 case KELIF:
153 case KELSE:
154 if (ifdepth <= skipping)
155 break;
156 return;
158 default:
159 return;
162 switch (np->val)
164 case KDEFINE:
165 dodefine(trp);
166 break;
168 case KUNDEF:
169 tp += 1;
170 if (tp->type != NAME || trp->lp - trp->bp != 4)
172 error(ERROR, "Syntax error in #undef");
173 break;
175 if ((np = lookup(tp, 0)) != NULL)
177 np->flag &= ~ISDEFINED;
179 if (Mflag)
181 if (np->ap)
182 error(INFO, "Macro deletion of %s(%r)", np->name, np->ap);
183 else
184 error(INFO, "Macro deletion of %s", np->name);
187 break;
189 case KPRAGMA:
190 case KIDENT:
191 for (tp = trp->tp - 1; ((tp->type != NL) && (tp < trp->lp)); tp++)
192 tp->type = UNCLASS;
193 return;
195 case KIFDEF:
196 case KIFNDEF:
197 case KIF:
198 if (++ifdepth >= NIF)
199 error(FATAL, "#if too deeply nested");
200 ++cursource->ifdepth;
201 ifsatisfied[ifdepth] = 0;
202 if (eval(trp, np->val))
203 ifsatisfied[ifdepth] = 1;
204 else
205 skipping = ifdepth;
206 break;
208 case KELIF:
209 if (ifdepth == 0)
211 error(ERROR, "#elif with no #if");
212 return;
214 if (ifsatisfied[ifdepth] == 2)
215 error(ERROR, "#elif after #else");
216 if (eval(trp, np->val))
218 if (ifsatisfied[ifdepth])
219 skipping = ifdepth;
220 else
222 skipping = 0;
223 ifsatisfied[ifdepth] = 1;
226 else
227 skipping = ifdepth;
228 break;
230 case KELSE:
231 if (ifdepth == 0 || cursource->ifdepth == 0)
233 error(ERROR, "#else with no #if");
234 return;
236 if (ifsatisfied[ifdepth] == 2)
237 error(ERROR, "#else after #else");
238 if (trp->lp - trp->bp != 3)
239 error(ERROR, "Syntax error in #else");
240 skipping = ifsatisfied[ifdepth] ? ifdepth : 0;
241 ifsatisfied[ifdepth] = 2;
242 break;
244 case KENDIF:
245 if (ifdepth == 0 || cursource->ifdepth == 0)
247 error(ERROR, "#endif with no #if");
248 return;
250 --ifdepth;
251 --cursource->ifdepth;
252 if (trp->lp - trp->bp != 3)
253 error(WARNING, "Syntax error in #endif");
254 break;
256 case KERROR:
257 trp->tp = tp + 1;
258 error(WARNING, "#error directive: %r", trp);
259 break;
261 case KLINE:
262 trp->tp = tp + 1;
263 expandrow(trp, "<line>");
264 tp = trp->bp + 2;
265 kline:
266 if (tp + 1 >= trp->lp || tp->type != NUMBER || tp + 3 < trp->lp
267 || (tp + 3 == trp->lp && ((tp + 1)->type != STRING || *(tp + 1)->t == 'L')))
269 error(ERROR, "Syntax error in #line");
270 return;
272 cursource->line = atol((char*)tp->t) - 1;
273 if (cursource->line < 0 || cursource->line >= 32768)
274 error(WARNING, "#line specifies number out of range");
275 tp = tp + 1;
276 if (tp + 1 < trp->lp)
277 cursource->filename = (char*)newstring(tp->t + 1, tp->len - 2, 0);
278 return;
280 case KDEFINED:
281 error(ERROR, "Bad syntax for control line");
282 break;
284 case KIMPORT:
285 doinclude(trp, -1, 1);
286 trp->lp = trp->bp;
287 return;
289 case KINCLUDE:
290 doinclude(trp, -1, 0);
291 trp->lp = trp->bp;
292 return;
294 case KINCLUDENEXT:
295 doinclude(trp, cursource->pathdepth, 0);
296 trp->lp = trp->bp;
297 return;
299 case KEVAL:
300 eval(trp, np->val);
301 break;
303 default:
304 error(ERROR, "Preprocessor control `%t' not yet implemented", tp);
305 break;
307 setempty(trp);
308 return;
311 void* domalloc(size_t size)
313 void* p = malloc(size);
315 if (p == NULL)
316 error(FATAL, "Out of memory from malloc");
317 return p;
320 void dofree(void* p) { free(p); }
322 void error(enum errtype type, char* string, ...)
324 va_list ap;
325 char c, *cp, *ep;
326 Token* tp;
327 Tokenrow* trp;
328 Source* s;
329 int i;
331 fprintf(stderr, "cpp: ");
332 for (s = cursource; s; s = s->next)
333 if (*s->filename)
334 fprintf(stderr, "%s:%d ", s->filename, s->line);
335 va_start(ap, string);
336 for (ep = string; *ep; ep++)
338 if (*ep == '%')
340 switch (*++ep)
342 case 'c':
343 c = (char)va_arg(ap, int);
344 fprintf(stderr, "%c", c);
345 break;
347 case 's':
348 cp = va_arg(ap, char*);
349 fprintf(stderr, "%s", cp);
350 break;
352 case 'd':
353 i = va_arg(ap, int);
354 fprintf(stderr, "%d", i);
355 break;
357 case 't':
358 tp = va_arg(ap, Token*);
359 fprintf(stderr, "%.*s", (int)tp->len, tp->t);
360 break;
362 case 'r':
363 trp = va_arg(ap, Tokenrow*);
364 for (tp = trp->tp; tp < trp->lp && tp->type != NL; tp++)
366 if (tp > trp->tp && tp->wslen)
367 fputc(' ', stderr);
368 fprintf(stderr, "%.*s", (int)tp->len, tp->t);
370 break;
372 default:
373 fputc(*ep, stderr);
374 break;
377 else
378 fputc(*ep, stderr);
380 va_end(ap);
381 fputc('\n', stderr);
382 if (type == FATAL)
383 exit(1);
384 if (type != WARNING)
385 nerrs = 1;
386 fflush(stderr);
389 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */