Branch data 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 : : #include <sal/types.h>
21 : : #include <stdio.h>
22 : : #include <ctype.h>
23 : : #include "cppdef.h"
24 : : #include "cpp.h"
25 : : /*
26 : : * parm[], parmp, and parlist[] are used to store #define() argument
27 : : * lists. nargs contains the actual number of parameters stored.
28 : : */
29 : : static char parm[NPARMWORK + 1]; /* define param work buffer */
30 : : static char *parmp; /* Free space in parm */
31 : : static char *parlist[LASTPARM]; /* -> start of each parameter */
32 : : static int nargs; /* Parameters for this macro */
33 : :
34 : 1320 : void InitCpp4()
35 : : {
36 : : int i;
37 [ + + ]: 337921320 : for( i = 0; i < NPARMWORK; i++ )
38 : 337920000 : parm[ i ] = 0;
39 [ + + ]: 335280 : for( i = 0; i < LASTPARM; i++ )
40 : 333960 : parlist[ i ] = NULL;
41 : :
42 : 1320 : nargs = 0;
43 : 1320 : }
44 : :
45 : :
46 : 2229068 : void dodefine()
47 : : /*
48 : : * Called from control when a #define is scanned. This module
49 : : * parses formal parameters and the replacement string. When
50 : : * the formal parameter name is encountered in the replacement
51 : : * string, it is replaced by a character in the range 128 to
52 : : * 128+NPARAM (this allows up to 32 parameters within the
53 : : * Dec Multinational range). If cpp is ported to an EBCDIC
54 : : * machine, you will have to make other arrangements.
55 : : *
56 : : * There is some special case code to distinguish
57 : : * #define foo bar
58 : : * from #define foo() bar
59 : : *
60 : : * Also, we make sure that
61 : : * #define foo foo
62 : : * expands to "foo" but doesn't put cpp into an infinite loop.
63 : : *
64 : : * A warning message is printed if you redefine a symbol to a
65 : : * different text. I.e,
66 : : * #define foo 123
67 : : * #define foo 123
68 : : * is ok, but
69 : : * #define foo 123
70 : : * #define foo +123
71 : : * is not.
72 : : *
73 : : * The following subroutines are called from define():
74 : : * checkparm called when a token is scanned. It checks through the
75 : : * array of formal parameters. If a match is found, the
76 : : * token is replaced by a control byte which will be used
77 : : * to locate the parameter when the macro is expanded.
78 : : * textput puts a string in the macro work area (parm[]), updating
79 : : * parmp to point to the first free byte in parm[].
80 : : * textput() tests for work buffer overflow.
81 : : * charput puts a single character in the macro work area (parm[])
82 : : * in a manner analogous to textput().
83 : : */
84 : : {
85 : : register int c;
86 : : register DEFBUF *dp; /* -> new definition */
87 : : int isredefine; /* TRUE if redefined */
88 : 2229068 : char *old = 0; /* Remember redefined */
89 : :
90 [ - + ]: 2229068 : if (type[(c = skipws())] != LET)
91 : 0 : goto bad_define;
92 : 2229068 : isredefine = FALSE; /* Set if redefining */
93 [ + + ]: 2229068 : if ((dp = lookid(c)) == NULL) /* If not known now */
94 : 2201218 : dp = defendel(token, FALSE); /* Save the name */
95 : : else { /* It's known: */
96 : 27850 : isredefine = TRUE; /* Remember this fact */
97 : 27850 : old = dp->repl; /* Remember replacement */
98 : 27850 : dp->repl = NULL; /* No replacement now */
99 : : }
100 : 2229068 : parlist[0] = parmp = parm; /* Setup parm buffer */
101 [ + + ]: 2229068 : if ((c = get()) == '(') { /* With arguments? */
102 : 2900 : nargs = 0; /* Init formals counter */
103 : : do { /* Collect formal parms */
104 [ - + ]: 3302 : if (nargs >= LASTPARM)
105 : 0 : cfatal("Too many arguments for macro", NULLST);
106 [ + + ]: 3302 : else if ((c = skipws()) == ')')
107 : 4 : break; /* Got them all */
108 [ - + ]: 3298 : else if (type[c] != LET) /* Bad formal syntax */
109 : 0 : goto bad_define;
110 : 3298 : scanid(c); /* Get the formal param */
111 : 3298 : parlist[nargs++] = parmp; /* Save its start */
112 : 3298 : textput(token); /* Save text in parm[] */
113 [ + + ]: 3298 : } while ((c = skipws()) == ','); /* Get another argument */
114 [ - + ]: 2900 : if (c != ')') /* Must end at ) */
115 : 0 : goto bad_define;
116 : 2900 : c = ' '; /* Will skip to body */
117 : : }
118 : : else {
119 : : /*
120 : : * DEF_NOARGS is needed to distinguish between
121 : : * "#define foo" and "#define foo()".
122 : : */
123 : 2226168 : nargs = DEF_NOARGS; /* No () parameters */
124 : : }
125 [ + + ]: 2229068 : if (type[c] == SPA) /* At whitespace? */
126 : 2216750 : c = skipws(); /* Not any more. */
127 : 2229068 : workp = work; /* Replacement put here */
128 : 2229068 : inmacro = TRUE; /* Keep \<newline> now */
129 [ + - ][ + + ]: 15662932 : while (c != EOF_CHAR && c != '\n') { /* Compile macro body */
130 : : #if OK_CONCAT
131 : : #if COMMENT_INVISIBLE
132 : : if (c == COM_SEP) { /* Token concatenation? */
133 : : save(TOK_SEP); /* Stuff a delimiter */
134 : : c = get();
135 : : #else
136 [ + + ]: 13433864 : if (c == '#') { /* Token concatenation? */
137 [ + + ][ - + ]: 1108 : while (workp > work && type[(int)workp[-1]] == SPA)
138 : 0 : --workp; /* Erase leading spaces */
139 : 1108 : save(TOK_SEP); /* Stuff a delimiter */
140 : 1108 : c = skipws(); /* Eat whitespace */
141 : : #endif
142 [ - + ]: 1108 : if (type[c] == LET) /* Another token here? */
143 : : ; /* Stuff it normally */
144 [ # # ]: 0 : else if (type[c] == DIG) { /* Digit string after? */
145 [ # # ]: 0 : while (type[c] == DIG) { /* Stuff the digits */
146 : 0 : save(c);
147 : 0 : c = get();
148 : : }
149 : 0 : save(TOK_SEP); /* Delimit 2nd token */
150 : : }
151 : : else {
152 : : #if ! COMMENT_INVISIBLE
153 : 0 : ciwarn("Strange character after # (%d.)", c);
154 : : #endif
155 : : }
156 : 1108 : continue;
157 : : }
158 : : #endif
159 [ + + + + : 13432756 : switch (type[c]) {
+ + ]
160 : : case LET:
161 : 1700580 : checkparm(c, dp); /* Might be a formal */
162 : 1700580 : break;
163 : :
164 : : case DIG: /* Number in mac. body */
165 : : case DOT: /* Maybe a float number */
166 : 1763636 : scannumber(c, save); /* Scan it off */
167 : 1763636 : break;
168 : :
169 : : case QUO: /* String in mac. body */
170 : : #if STRING_FORMAL
171 : : stparmscan(c, dp); /* Do string magic */
172 : : #else
173 : 414144 : stparmscan(c);
174 : : #endif
175 : 414144 : break;
176 : :
177 : : case BSH: /* Backslash */
178 : 37902 : save('\\');
179 [ + - ]: 37902 : if ((c = get()) == '\n')
180 : 37902 : wrongline = TRUE;
181 : 37902 : save(c);
182 : 37902 : break;
183 : :
184 : : case SPA: /* Absorb whitespace */
185 : : /*
186 : : * Note: the "end of comment" marker is passed on
187 : : * to allow comments to separate tokens.
188 : : */
189 [ + + ]: 4688984 : if (workp[-1] == ' ') /* Absorb multiple */
190 : 969936 : break; /* spaces */
191 [ - + ]: 3719048 : else if (c == '\t')
192 : 0 : c = ' '; /* Normalize tabs */
193 : : /* Fall through to store character */
194 : : default: /* Other character */
195 : 8546558 : save(c);
196 : 8546558 : break;
197 : : }
198 : 13432756 : c = get();
199 : : }
200 : 2229068 : inmacro = FALSE; /* Stop newline hack */
201 : 2229068 : unget(); /* For control check */
202 [ + + ][ + + ]: 2229068 : if (workp > work && workp[-1] == ' ') /* Drop trailing blank */
203 : 52758 : workp--;
204 : 2229068 : *workp = EOS; /* Terminate work */
205 : 2229068 : dp->repl = savestring(work); /* Save the string */
206 : 2229068 : dp->nargs = nargs; /* Save arg count */
207 : : #if OSL_DEBUG_LEVEL > 1
208 : : if (debug)
209 : : dumpadef("macro definition", dp);
210 : : else if (bDumpDefs)
211 : : dumpadef(NULL, dp);
212 : : #endif
213 [ + + ]: 2229068 : if (isredefine) { /* Error if redefined */
214 [ + - ][ + - ]: 27850 : if ((old != NULL && dp->repl != NULL && !streq(old, dp->repl))
[ + - ]
215 [ - + ][ # # ]: 27850 : || (old == NULL && dp->repl != NULL)
216 [ + - ][ - + ]: 27850 : || (old != NULL && dp->repl == NULL)) {
217 : : #ifdef STRICT_UNDEF
218 : : cerror("Redefining defined variable \"%s\"", dp->name);
219 : : #else
220 : 0 : cwarn("Redefining defined variable \"%s\"", dp->name);
221 : : #endif
222 : : }
223 [ + - ]: 27850 : if (old != NULL) /* We don't need the */
224 : 27850 : free(old); /* old definition now. */
225 : : }
226 : 2229068 : return;
227 : :
228 : : bad_define:
229 : 0 : cerror("#define syntax error", NULLST);
230 : 0 : inmacro = FALSE; /* Stop <newline> hack */
231 : : }
232 : :
233 : 1700580 : void checkparm(int c, DEFBUF* dp)
234 : : /*
235 : : * Replace this param if it's defined. Note that the macro name is a
236 : : * possible replacement token. We stuff DEF_MAGIC in front of the token
237 : : * which is treated as a LETTER by the token scanner and eaten by
238 : : * the output routine. This prevents the macro expander from
239 : : * looping if someone writes "#define foo foo".
240 : : */
241 : : {
242 : : register int i;
243 : : register char *cp;
244 : :
245 : 1700580 : scanid(c); /* Get parm to token[] */
246 [ + + ]: 1740338 : for (i = 0; i < nargs; i++) { /* For each argument */
247 [ + + ]: 44564 : if (streq(parlist[i], token)) { /* If it's known */
248 : : #ifdef SOLAR
249 : 4806 : save(DEL);
250 : : #endif
251 : 4806 : save(i + MAC_PARM); /* Save a magic cookie */
252 : 1700580 : return; /* And exit the search */
253 : : }
254 : : }
255 [ - + ]: 1695774 : if (streq(dp->name, token)) /* Macro name in body? */
256 : 0 : save(DEF_MAGIC); /* Save magic marker */
257 [ + + ]: 24773666 : for (cp = token; *cp != EOS;) /* And save */
258 : 23077892 : save(*cp++); /* The token itself */
259 : : }
260 : :
261 : : #if STRING_FORMAL
262 : : void stparmscan(delim, dp)
263 : : int delim;
264 : : register DEFBUF *dp;
265 : : /*
266 : : * Scan the string (starting with the given delimiter).
267 : : * The token is replaced if it is the only text in this string or
268 : : * character constant. The algorithm follows checkparm() above.
269 : : * Note that scanstring() has approved of the string.
270 : : */
271 : : {
272 : : register int c;
273 : :
274 : : /*
275 : : * Warning -- this code hasn't been tested for a while.
276 : : * It exists only to preserve compatibility with earlier
277 : : * implementations of cpp. It is not part of the Draft
278 : : * ANSI Standard C language.
279 : : */
280 : : save(delim);
281 : : instring = TRUE;
282 : : while ((c = get()) != delim
283 : : && c != '\n'
284 : : && c != EOF_CHAR) {
285 : : if (type[c] == LET) /* Maybe formal parm */
286 : : checkparm(c, dp);
287 : : else {
288 : : save(c);
289 : : if (c == '\\')
290 : : save(get());
291 : : }
292 : : }
293 : : instring = FALSE;
294 : : if (c != delim)
295 : : cerror("Unterminated string in macro body", NULLST);
296 : : save(c);
297 : : }
298 : : #else
299 : 414144 : void stparmscan(int delim)
300 : : /*
301 : : * Normal string parameter scan.
302 : : */
303 : : {
304 : : register char *wp;
305 : : register int i;
306 : :
307 : 414144 : wp = workp; /* Here's where it starts */
308 [ - + ]: 414144 : if (!scanstring(delim, save))
309 : 0 : return; /* Exit on scanstring error */
310 : 414144 : workp[-1] = EOS; /* Erase trailing quote */
311 : 414144 : wp++; /* -> first string content byte */
312 [ + + ]: 415984 : for (i = 0; i < nargs; i++) {
313 [ - + ]: 1840 : if (streq(parlist[i], wp)) {
314 : : #ifdef SOLAR
315 : 0 : *wp++ = DEL;
316 : 0 : *wp++ = MAC_PARM + PAR_MAC; /* Stuff a magic marker */
317 : 0 : *wp++ = (char)(i + MAC_PARM); /* Make a formal marker */
318 : 0 : *wp = wp[-4]; /* Add on closing quote */
319 : 0 : workp = wp + 1; /* Reset string end */
320 : : #else
321 : : *wp++ = MAC_PARM + PAR_MAC; /* Stuff a magic marker */
322 : : *wp++ = (i + MAC_PARM); /* Make a formal marker */
323 : : *wp = wp[-3]; /* Add on closing quote */
324 : : workp = wp + 1; /* Reset string end */
325 : : #endif
326 : 0 : return;
327 : : }
328 : : }
329 : 414144 : workp[-1] = wp[-1]; /* Nope, reset end quote. */
330 : : }
331 : : #endif
332 : :
333 : 210 : void doundef()
334 : : /*
335 : : * Remove the symbol from the defined list.
336 : : * Called from the #control processor.
337 : : */
338 : : {
339 : : register int c;
340 : :
341 [ - + ]: 210 : if (type[(c = skipws())] != LET)
342 : 0 : cerror("Illegal #undef argument", NULLST);
343 : : else {
344 : 210 : scanid(c); /* Get name to token[] */
345 : 210 : if (defendel(token, TRUE) == NULL) {
346 : : #ifdef STRICT_UNDEF
347 : : cwarn("Symbol \"%s\" not defined in #undef", token);
348 : : #endif
349 : : }
350 : : }
351 : 210 : }
352 : :
353 : 3298 : void textput(char* text)
354 : : /*
355 : : * Put the string in the parm[] buffer.
356 : : */
357 : : {
358 : : register int size;
359 : :
360 : 3298 : size = strlen(text) + 1;
361 [ - + ]: 3298 : if ((parmp + size) >= &parm[NPARMWORK])
362 : 0 : cfatal("Macro work area overflow", NULLST);
363 : : else {
364 : 3298 : strcpy(parmp, text);
365 : 3298 : parmp += size;
366 : : }
367 : 3298 : }
368 : :
369 : 38790 : void charput(int c)
370 : : /*
371 : : * Put the byte in the parm[] buffer.
372 : : */
373 : : {
374 [ - + ]: 38790 : if (parmp >= &parm[NPARMWORK])
375 : 0 : cfatal("Macro work area overflow", NULLST);
376 : : else {
377 : 38790 : *parmp++ = (char)c;
378 : : }
379 : 38790 : }
380 : :
381 : : /*
382 : : * M a c r o E x p a n s i o n
383 : : */
384 : :
385 : : static DEFBUF *macro; /* Catches start of infinite macro */
386 : :
387 : 238180 : void expand(DEFBUF* tokenp)
388 : : /*
389 : : * Expand a macro. Called from the cpp mainline routine (via subroutine
390 : : * macroid()) when a token is found in the symbol table. It calls
391 : : * expcollect() to parse actual parameters, checking for the correct number.
392 : : * It then creates a "file" containing a single line containing the
393 : : * macro with actual parameters inserted appropriately. This is
394 : : * "pushed back" onto the input stream. (When the get() routine runs
395 : : * off the end of the macro line, it will dismiss the macro itself.)
396 : : */
397 : : {
398 : : register int c;
399 : : register FILEINFO *file;
400 : : extern FILEINFO *getfile();
401 : :
402 : : #if OSL_DEBUG_LEVEL > 1
403 : : if (debug)
404 : : dumpadef("expand entry", tokenp);
405 : : #endif
406 : : /*
407 : : * If no macro is pending, save the name of this macro
408 : : * for an eventual error message.
409 : : */
410 [ + + ]: 238180 : if (recursion++ == 0)
411 : 75464 : macro = tokenp;
412 [ - + ]: 162716 : else if (recursion == RECURSION_LIMIT) {
413 : 0 : cerror("Recursive macro definition of \"%s\"", tokenp->name);
414 : 0 : fprintf(stderr, "(Defined by \"%s\")\n", macro->name);
415 [ # # ]: 0 : if (rec_recover) {
416 : : do {
417 : 0 : c = get();
418 [ # # ][ # # ]: 0 : } while (infile != NULL && infile->fp == NULL);
419 : 0 : unget();
420 : 0 : recursion = 0;
421 : 0 : return;
422 : : }
423 : : }
424 : : /*
425 : : * Here's a macro to expand.
426 : : */
427 : 238180 : nargs = 0; /* Formals counter */
428 : 238180 : parmp = parm; /* Setup parm buffer */
429 [ - - + + ]: 238180 : switch (tokenp->nargs) {
430 : : case (-2): /* __LINE__ */
431 : 0 : sprintf(work, "%d", line);
432 : 0 : ungetstring(work);
433 : 0 : break;
434 : :
435 : : case (-3): /* __FILE__ */
436 [ # # ]: 0 : for (file = infile; file != NULL; file = file->parent) {
437 [ # # ]: 0 : if (file->fp != NULL) {
438 [ # # ]: 0 : sprintf(work, "\"%s\"", (file->progname != NULL)
439 : : ? file->progname : file->filename);
440 : 0 : ungetstring(work);
441 : 0 : break;
442 : : }
443 : : }
444 : 0 : break;
445 : :
446 : : default:
447 : : /*
448 : : * Nothing funny about this macro.
449 : : */
450 [ - + ]: 2034 : if (tokenp->nargs < 0)
451 : 0 : cfatal("Bug: Illegal __ macro \"%s\"", tokenp->name);
452 [ - + ]: 2034 : while ((c = skipws()) == '\n') /* Look for (, skipping */
453 : 0 : wrongline = TRUE; /* spaces and newlines */
454 [ - + ]: 2034 : if (c != '(') {
455 : : /*
456 : : * If the programmer writes
457 : : * #define foo() ...
458 : : * ...
459 : : * foo [no ()]
460 : : * just write foo to the output stream.
461 : : */
462 : 0 : unget();
463 : 0 : cwarn("Macro \"%s\" needs arguments", tokenp->name);
464 : 0 : fputs(tokenp->name, pCppOut );
465 : 0 : return;
466 : : }
467 [ + - ]: 2034 : else if (expcollect()) { /* Collect arguments */
468 [ - + ]: 2034 : if (tokenp->nargs != nargs) { /* Should be an error? */
469 : 0 : cwarn("Wrong number of macro arguments for \"%s\"",
470 : 0 : tokenp->name);
471 : : }
472 : : #if OSL_DEBUG_LEVEL > 1
473 : : if (debug)
474 : : dumpparm("expand");
475 : : #endif
476 : : } /* Collect arguments */
477 : : case DEF_NOARGS: /* No parameters just stuffs */
478 : 238180 : expstuff(tokenp); /* Do actual parameters */
479 : : } /* nargs switch */
480 : : }
481 : :
482 : : FILE_LOCAL int
483 : 5106 : expcollect()
484 : : /*
485 : : * Collect the actual parameters for this macro. TRUE if ok.
486 : : */
487 : : {
488 : : register int c;
489 : : register int paren; /* For embedded ()'s */
490 : : for (;;) {
491 : 5106 : paren = 0; /* Collect next arg. */
492 [ - + ]: 5106 : while ((c = skipws()) == '\n') /* Skip over whitespace */
493 : 0 : wrongline = TRUE; /* and newlines. */
494 [ + + ]: 5106 : if (c == ')') { /* At end of all args? */
495 : : /*
496 : : * Note that there is a guard byte in parm[]
497 : : * so we don't have to check for overflow here.
498 : : */
499 : 2034 : *parmp = EOS; /* Make sure terminated */
500 : 2034 : break; /* Exit collection loop */
501 : : }
502 [ - + ]: 3072 : else if (nargs >= LASTPARM)
503 : 0 : cfatal("Too many arguments in macro expansion", NULLST);
504 : 3072 : parlist[nargs++] = parmp; /* At start of new arg */
505 : 35718 : for (;; c = cget()) { /* Collect arg's bytes */
506 [ - + ]: 38790 : if (c == EOF_CHAR) {
507 : 0 : cerror("end of file within macro argument", NULLST);
508 : 0 : return (FALSE); /* Sorry. */
509 : : }
510 [ - + ]: 38790 : else if (c == '\\') { /* Quote next character */
511 : 0 : charput(c); /* Save the \ for later */
512 : 0 : charput(cget()); /* Save the next char. */
513 : 0 : continue; /* And go get another */
514 : : }
515 [ - + ]: 38790 : else if (type[c] == QUO) { /* Start of string? */
516 : 0 : scanstring(c, charput); /* Scan it off */
517 : 0 : continue; /* Go get next char */
518 : : }
519 [ + + ]: 38790 : else if (c == '(') /* Worry about balance */
520 : 10 : paren++; /* To know about commas */
521 [ + + ]: 38780 : else if (c == ')') { /* Other side too */
522 [ + + ]: 1976 : if (paren == 0) { /* At the end? */
523 : 1966 : unget(); /* Look at it later */
524 : 1966 : break; /* Exit arg getter. */
525 : : }
526 : 10 : paren--; /* More to come. */
527 : : }
528 [ + + ][ - + ]: 36804 : else if (c == ',' && paren == 0) /* Comma delimits args */
529 : : break;
530 [ - + ]: 35698 : else if (c == '\n') /* Newline inside arg? */
531 : 0 : wrongline = TRUE; /* We'll need a #line */
532 : 35718 : charput(c); /* Store this one */
533 : 35718 : } /* Collect an argument */
534 : 3072 : charput(EOS); /* Terminate argument */
535 : : #if OSL_DEBUG_LEVEL > 1
536 : : if (debug)
537 : : fprintf( pCppOut, "parm[%d] = \"%s\"\n", nargs, parlist[nargs - 1]);
538 : : #endif
539 : 3072 : } /* Collect all args. */
540 : 2034 : return (TRUE); /* Normal return */
541 : : }
542 : :
543 : : FILE_LOCAL
544 : 238180 : void expstuff(DEFBUF* tokenp)
545 : : /*
546 : : * Stuff the macro body, replacing formal parameters by actual parameters.
547 : : */
548 : : {
549 : : register int c; /* Current character */
550 : : register char *inp; /* -> repl string */
551 : : register char *defp; /* -> macro output buff */
552 : : int size; /* Actual parm. size */
553 : : char *defend; /* -> output buff end */
554 : : int string_magic; /* String formal hack */
555 : : FILEINFO *file; /* Funny #include */
556 : : extern FILEINFO *getfile();
557 : :
558 : 238180 : file = getfile(NBUFF, tokenp->name);
559 : 238180 : inp = tokenp->repl; /* -> macro replacement */
560 : 238180 : defp = file->buffer; /* -> output buffer */
561 : 238180 : defend = defp + (NBUFF - 1); /* Note its end */
562 [ + - ]: 238180 : if (inp != NULL) {
563 [ + + ]: 4491658 : while ((c = (*inp++ & 0xFF)) != EOS) {
564 : : #ifdef SOLAR
565 [ + + ]: 4253478 : if (c == DEL) {
566 : 4670 : c = (*inp++ & 0xFF);
567 : : #else
568 : : if (c >= MAC_PARM && c <= (MAC_PARM + PAR_MAC)) {
569 : : #endif
570 : 4670 : string_magic = (c == (MAC_PARM + PAR_MAC));
571 [ - + ]: 4670 : if (string_magic)
572 : 0 : c = (*inp++ & 0xFF);
573 : : /*
574 : : * Replace formal parameter by actual parameter string.
575 : : */
576 [ + - ]: 4670 : if ((c -= MAC_PARM) < nargs) {
577 : 4670 : size = strlen(parlist[c]);
578 [ - + ]: 4670 : if ((defp + size) >= defend)
579 : 0 : goto nospace;
580 : : /*
581 : : * Erase the extra set of quotes.
582 : : */
583 [ - + ][ # # ]: 4670 : if (string_magic && defp[-1] == parlist[c][0]) {
584 : 0 : strcpy(defp-1, parlist[c]);
585 : 0 : defp += (size - 2);
586 : : }
587 : : else {
588 : 4670 : strcpy(defp, parlist[c]);
589 : 4670 : defp += size;
590 : : }
591 : : }
592 : : }
593 [ - + ]: 4248808 : else if (defp >= defend) {
594 : 0 : nospace: cfatal("Out of space in macro \"%s\" arg expansion",
595 : 0 : tokenp->name);
596 : : }
597 : : else {
598 : 4248808 : *defp++ = (char)c;
599 : : }
600 : : }
601 : : }
602 : 238180 : *defp = EOS;
603 : : #if OSL_DEBUG_LEVEL > 1
604 : : if (debug > 1)
605 : : fprintf( pCppOut, "macroline: \"%s\"\n", file->buffer);
606 : : #endif
607 : 238180 : }
608 : :
609 : : #if OSL_DEBUG_LEVEL > 1
610 : : void dumpparm(char* why)
611 : : /*
612 : : * Dump parameter list.
613 : : */
614 : : {
615 : : register int i;
616 : :
617 : : fprintf( pCppOut, "dump of %d parameters (%" SAL_PRI_SIZET "u bytes total) %s\n",
618 : : nargs, parmp - parm, why);
619 : : for (i = 0; i < nargs; i++) {
620 : : fprintf( pCppOut, "parm[%d] (%d) = \"%s\"\n",
621 : : i + 1, (int)strlen(parlist[i]), parlist[i]);
622 : : }
623 : : }
624 : : #endif
625 : :
626 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|