LCOV - code coverage report
Current view: top level - soltools/cpp - _macro.c (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 380 0.0 %
Date: 2014-04-14 Functions: 0 10 0.0 %
Legend: Lines: hit not hit

          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             : #ifdef _MSC_VER
      21             : #   define _POSIX_
      22             : #endif
      23             : #include <stdio.h>
      24             : #include <stdlib.h>
      25             : #include <string.h>
      26             : #if defined(__IBMC__) || defined(__EMX__) || defined(_MSC_VER)
      27             : #   ifndef PATH_MAX
      28             : #       define PATH_MAX _MAX_PATH
      29             : #   endif
      30             : #endif
      31             : #include <limits.h>
      32             : 
      33             : #include "cpp.h"
      34             : 
      35             : #define NCONCAT 16384
      36             : 
      37             : /*
      38             :  * do a macro definition.  tp points to the name being defined in the line
      39             :  */
      40             : void
      41           0 :     dodefine(Tokenrow * trp)
      42             : {
      43             :     Token *tp;
      44             :     Nlist *np;
      45             :     Source *s;
      46             :     Tokenrow *def, *args;
      47             :     static uchar location[(PATH_MAX + 8) * NINC], *cp;
      48             : 
      49           0 :     tp = trp->tp + 1;
      50           0 :     if (tp >= trp->lp || tp->type != NAME)
      51             :     {
      52           0 :         error(ERROR, "#defined token is not a name");
      53           0 :         return;
      54             :     }
      55           0 :     np = lookup(tp, 1);
      56           0 :     if (np->flag & ISUNCHANGE)
      57             :     {
      58           0 :         error(ERROR, "#defined token %t can't be redefined", tp);
      59           0 :         return;
      60             :     }
      61             :     /* collect arguments */
      62           0 :     tp += 1;
      63           0 :     args = NULL;
      64           0 :     if (tp < trp->lp && tp->type == LP && tp->wslen == 0)
      65             :     {
      66           0 :         tp += 1;
      67           0 :         args = new(Tokenrow);
      68           0 :         maketokenrow(2, args);
      69           0 :         if (tp->type != RP)
      70             :         {
      71             :             /* macro with args */
      72           0 :             size_t narg = 0;
      73           0 :             int err = 0;
      74             : 
      75             :             for (;;)
      76             :             {
      77             :                 Token *atp;
      78             : 
      79           0 :                 if (tp->type != NAME)
      80             :                 {
      81           0 :                     err++;
      82           0 :                     break;
      83             :                 }
      84           0 :                 if (narg >= args->max)
      85           0 :                     growtokenrow(args);
      86           0 :                 for (atp = args->bp; atp < args->lp; atp++)
      87           0 :                     if (atp->len == tp->len
      88           0 :                         && strncmp((char *) atp->t, (char *) tp->t, tp->len) == 0)
      89           0 :                         error(ERROR, "Duplicate macro argument");
      90           0 :                 *args->lp++ = *tp;
      91           0 :                 narg++;
      92           0 :                 tp += 1;
      93           0 :                 if (tp->type == RP)
      94           0 :                     break;
      95           0 :                 if (tp->type != COMMA)
      96             :                 {
      97           0 :                     err++;
      98           0 :                     break;
      99             :                 }
     100           0 :                 tp += 1;
     101           0 :             }
     102           0 :             if (err)
     103             :             {
     104           0 :                 error(ERROR, "Syntax error in macro parameters");
     105           0 :                 return;
     106             :             }
     107             :         }
     108           0 :         tp += 1;
     109             :     }
     110           0 :     trp->tp = tp;
     111           0 :     if (((trp->lp) - 1)->type == NL)
     112           0 :         trp->lp -= 1;
     113           0 :     def = normtokenrow(trp);
     114           0 :     if (np->flag & ISDEFINED)
     115             :     {
     116           0 :         if (comparetokens(def, np->vp)
     117           0 :             || (np->ap == NULL) != (args == NULL)
     118           0 :             || (np->ap && comparetokens(args, np->ap)))
     119             :         {
     120           0 :             if ( np->loc )
     121           0 :                 error(ERROR,
     122             :                     "Macro redefinition of %t (already defined at %s)",
     123           0 :                     trp->bp + 2, np->loc);
     124             :             else
     125           0 :                 error(ERROR,
     126             :                     "Macro redefinition of %t (already defined at %s)",
     127           0 :                     trp->bp + 2, "commandline" );
     128             :         }
     129             :     }
     130           0 :     if (args)
     131             :     {
     132             :         Tokenrow *tap;
     133             : 
     134           0 :         tap = normtokenrow(args);
     135           0 :         dofree(args->bp);
     136           0 :         args = tap;
     137             :     }
     138           0 :     np->ap = args;
     139           0 :     np->vp = def;
     140           0 :     np->flag |= ISDEFINED;
     141             : 
     142             :     /* build location string of macro definition */
     143           0 :     for (cp = location, s = cursource; s; s = s->next)
     144           0 :         if (*s->filename)
     145             :         {
     146           0 :             if (cp != location)
     147           0 :                 *cp++ = ' ';
     148           0 :             sprintf((char *)cp, "%s:%d", s->filename, s->line);
     149           0 :             cp += strlen((char *)cp);
     150             :         }
     151             : 
     152           0 :     np->loc = newstring(location, strlen((char *)location), 0);
     153             : 
     154           0 :     if (Mflag)
     155             :     {
     156           0 :         if (np->ap)
     157           0 :             error(INFO, "Macro definition of %s(%r) [%r]", np->name, np->ap, np->vp);
     158             :         else
     159           0 :             error(INFO, "Macro definition of %s [%r]", np->name, np->vp);
     160             :     }
     161             : }
     162             : 
     163             : /*
     164             :  * Definition received via -D or -U
     165             :  */
     166             : void
     167           0 :     doadefine(Tokenrow * trp, int type)
     168             : {
     169             :     Nlist *np;
     170             :     static uchar onestr[2] = "1";
     171             :     static Token onetoken[1] = {{NUMBER, 0, 0, 1, onestr, 0}};
     172             :     static Tokenrow onetr = {onetoken, onetoken, onetoken + 1, 1};
     173             : 
     174           0 :     trp->tp = trp->bp;
     175           0 :     if (type == 'U')
     176             :     {
     177           0 :         if (trp->lp - trp->tp != 2 || trp->tp->type != NAME)
     178             :             goto syntax;
     179           0 :         if ((np = lookup(trp->tp, 0)) == NULL)
     180           0 :             return;
     181           0 :         np->flag &= ~ISDEFINED;
     182           0 :         return;
     183             :     }
     184             : 
     185           0 :     if (type == 'A')
     186             :     {
     187           0 :         if (trp->tp >= trp->lp || trp->tp->type != NAME)
     188             :             goto syntax;
     189           0 :         trp->tp->type = ARCHITECTURE;
     190           0 :         np = lookup(trp->tp, 1);
     191           0 :         np->flag |= ISARCHITECTURE;
     192           0 :         trp->tp += 1;
     193           0 :         if (trp->tp >= trp->lp || trp->tp->type == END)
     194             :         {
     195           0 :             np->vp = &onetr;
     196           0 :             return;
     197             :         }
     198             :         else
     199           0 :             error(FATAL, "Illegal -A argument %r", trp);
     200             :     }
     201             : 
     202           0 :     if (trp->tp >= trp->lp || trp->tp->type != NAME)
     203             :         goto syntax;
     204           0 :     np = lookup(trp->tp, 1);
     205           0 :     np->flag |= ISDEFINED;
     206           0 :     trp->tp += 1;
     207           0 :     if (trp->tp >= trp->lp || trp->tp->type == END)
     208             :     {
     209           0 :         np->vp = &onetr;
     210           0 :         return;
     211             :     }
     212           0 :     if (trp->tp->type != ASGN)
     213           0 :         goto syntax;
     214           0 :     trp->tp += 1;
     215           0 :     if ((trp->lp - 1)->type == END)
     216           0 :         trp->lp -= 1;
     217           0 :     np->vp = normtokenrow(trp);
     218           0 :     return;
     219             : syntax:
     220           0 :     error(FATAL, "Illegal -D or -U argument %r", trp);
     221             : }
     222             : 
     223             : 
     224             : 
     225             : /*
     226             :  * Do macro expansion in a row of tokens.
     227             :  * Flag is NULL if more input can be gathered.
     228             :  */
     229             : void
     230           0 :     expandrow(Tokenrow * trp, char *flag)
     231             : {
     232             :     Token * tp;
     233             :     Nlist * np;
     234             : 
     235             :     MacroValidatorList  validators;
     236           0 :     mvl_init(&validators);
     237             :     /* Sets all token-identifiers to 0 because tokens may not be initialised (never use C!) */
     238           0 :     tokenrow_zeroTokenIdentifiers(trp);
     239             : 
     240           0 :     if (flag)
     241           0 :         setsource(flag, -1, -1, "", 0);
     242           0 :     for (tp = trp->tp; tp < trp->lp;)
     243             :     {
     244           0 :         mvl_check(&validators, tp);
     245             : 
     246           0 :         if (tp->type != NAME
     247           0 :             || quicklook(tp->t[0], tp->len > 1 ? tp->t[1] : 0) == 0
     248           0 :             || (np = lookup(tp, 0)) == NULL
     249           0 :             || (np->flag & (ISDEFINED | ISMAC)) == 0
     250           0 :             || (np->flag & ISACTIVE) != 0)
     251             :         {
     252           0 :             tp++;
     253           0 :             continue;
     254             :         }
     255           0 :         trp->tp = tp;
     256           0 :         if (np->val == KDEFINED)
     257             :         {
     258           0 :             tp->type = DEFINED;
     259           0 :             if ((tp + 1) < trp->lp && (tp + 1)->type == NAME)
     260           0 :                 (tp + 1)->type = NAME1;
     261             :             else
     262           0 :                 if ((tp + 3) < trp->lp && (tp + 1)->type == LP
     263           0 :                     && (tp + 2)->type == NAME && (tp + 3)->type == RP)
     264           0 :                     (tp + 2)->type = NAME1;
     265             :                 else
     266           0 :                     error(ERROR, "Incorrect syntax for `defined'");
     267           0 :             tp++;
     268           0 :             continue;
     269             :         }
     270             :         else
     271           0 :             if (np->val == KMACHINE)
     272             :             {
     273           0 :                 if (((tp - 1) >= trp->bp) && ((tp - 1)->type == SHARP))
     274             :                 {
     275           0 :                     tp->type = ARCHITECTURE;
     276           0 :                     if ((tp + 1) < trp->lp && (tp + 1)->type == NAME)
     277           0 :                         (tp + 1)->type = NAME2;
     278             :                     else
     279           0 :                         if ((tp + 3) < trp->lp && (tp + 1)->type == LP
     280           0 :                             && (tp + 2)->type == NAME && (tp + 3)->type == RP)
     281           0 :                             (tp + 2)->type = NAME2;
     282             :                         else
     283           0 :                             error(ERROR, "Incorrect syntax for `#machine'");
     284             :                 }
     285           0 :                 tp++;
     286           0 :                 continue;
     287             :             }
     288             : 
     289           0 :         if (np->flag & ISMAC)
     290           0 :             builtin(trp, np->val);
     291             :         else
     292           0 :             expand(trp, np, &validators);
     293           0 :         tp = trp->tp;
     294             :     }   // end for
     295           0 :     if (flag)
     296           0 :         unsetsource();
     297             : 
     298           0 :     mvl_destruct(&validators);
     299           0 : }
     300             : 
     301             : /*
     302             :  * Expand the macro whose name is np, at token trp->tp, in the tokenrow.
     303             :  * Return trp->tp at the first token next to be expanded
     304             :  * (ordinarily the beginning of the expansion)
     305             :  * I.e.: the same position as before!
     306             :  * Only one expansion is performed, then we return to the expandrow()
     307             :  * loop and start at same position.
     308             :  */
     309             : void
     310           0 :     expand(Tokenrow * trp, Nlist * np, MacroValidatorList * pValidators)
     311             : {
     312             :     Tokenrow ntr;
     313             :     int ntokc, narg;
     314             :     Tokenrow *atr[NARG + 1];
     315             : 
     316           0 :     if (Mflag == 2)
     317             :     {
     318           0 :         if (np->ap)
     319           0 :             error(INFO, "Macro expansion of %t with %s(%r)", trp->tp, np->name, np->ap);
     320             :         else
     321           0 :             error(INFO, "Macro expansion of %t with %s", trp->tp, np->name);
     322             :     }
     323             : 
     324           0 :     copytokenrow(&ntr, np->vp);         /* copy macro value */
     325           0 :     if (np->ap == NULL)                 /* parameterless */
     326           0 :         ntokc = 1;
     327             :     else
     328             :     {
     329             :         int i;
     330             : 
     331           0 :         ntokc = gatherargs(trp, atr, &narg);
     332           0 :         if (narg < 0)
     333             :         {                               /* not actually a call (no '(') */
     334           0 :             trp->tp++;
     335           0 :             return;
     336             :         }
     337           0 :         if (narg != rowlen(np->ap))
     338             :         {
     339           0 :             error(ERROR, "Disagreement in number of macro arguments");
     340           0 :             trp->tp += ntokc;
     341           0 :             return;
     342             :         }
     343             : 
     344             :         /** If gatherargs passed a macro validating token, this token
     345             :             must become valid here.
     346             :             trp->tp+0 was checked in expandrow(), so we dont need to do it
     347             :             again here:
     348             :         */
     349           0 :         for (i = 1; i < ntokc; i++)
     350             :         {
     351           0 :             mvl_check(pValidators,trp->tp+i);
     352             :         }
     353             : 
     354           0 :         substargs(np, &ntr, atr);       /* put args into replacement */
     355           0 :         for (i = 0; i < narg; i++)
     356             :         {
     357           0 :             dofree(atr[i]->bp);
     358           0 :             dofree(atr[i]);
     359             :         }
     360             :     }
     361             : 
     362           0 :     doconcat(&ntr);                     /* execute ## operators */
     363           0 :     ntr.tp = ntr.bp;
     364           0 :     makespace(&ntr, trp->tp);
     365             : 
     366           0 :     tokenrow_zeroTokenIdentifiers(&ntr);
     367           0 :     insertrow(trp, ntokc, &ntr);
     368             : 
     369             :         /* add validator for just invalidated macro:
     370             :         */
     371           0 :     np->flag |= ISACTIVE;
     372           0 :     if (trp->tp != trp->lp)
     373             :     {   /* tp is a valid pointer: */
     374           0 :         mvl_add(pValidators,np,trp->tp);
     375             :     }
     376             :     else
     377             :     {   /* tp is == lp, therefore does not point to valid memory: */
     378           0 :         mvl_add(pValidators,np,0);
     379             :     }
     380             :         /* reset trp->tp to original position:
     381             :         */
     382           0 :     trp->tp -= ntr.lp - ntr.bp;         /* so the result will be tested for macros from the same position again */
     383             : 
     384           0 :     dofree(ntr.bp);
     385             : 
     386           0 :     return;
     387             : }
     388             : 
     389             : /*
     390             :  * Gather an arglist, starting in trp with tp pointing at the macro name.
     391             :  * Return total number of tokens passed, stash number of args found.
     392             :  * trp->tp is not changed relative to the tokenrow.
     393             :  */
     394             : int
     395           0 :     gatherargs(Tokenrow * trp, Tokenrow ** atr, int *narg)
     396             : {
     397           0 :     int parens = 1;
     398           0 :     int ntok = 0;
     399             :     Token *bp, *lp;
     400             :     Tokenrow ttr;
     401             :     int ntokp;
     402             :     int needspace;
     403             : 
     404           0 :     *narg = -1;                         /* means that there is no macro
     405             :                                          * call */
     406             :     /* look for the ( */
     407             :     for (;;)
     408             :     {
     409           0 :         trp->tp++;
     410           0 :         ntok++;
     411           0 :         if (trp->tp >= trp->lp)
     412             :         {
     413           0 :             gettokens(trp, 0);
     414           0 :             if ((trp->lp - 1)->type == END)
     415             :             {
     416           0 :                 trp->lp -= 1;
     417           0 :                 trp->tp -= ntok;
     418           0 :                 return ntok;
     419             :             }
     420             :         }
     421           0 :         if (trp->tp->type == LP)
     422           0 :             break;
     423           0 :         if (trp->tp->type != NL)
     424           0 :             return ntok;
     425           0 :     }
     426           0 :     *narg = 0;
     427           0 :     ntok++;
     428           0 :     ntokp = ntok;
     429           0 :     trp->tp++;
     430             :     /* search for the terminating ), possibly extending the row */
     431           0 :     needspace = 0;
     432           0 :     while (parens > 0)
     433             :     {
     434           0 :         if (trp->tp >= trp->lp)
     435           0 :             gettokens(trp, 0);
     436           0 :         if (needspace)
     437             :         {
     438           0 :             needspace = 0;
     439             :             /* makespace(trp); [rh] */
     440             :         }
     441           0 :         if (trp->tp->type == END)
     442             :         {
     443           0 :             trp->lp -= 1;
     444           0 :             trp->tp -= ntok;
     445           0 :             error(ERROR, "EOF in macro arglist");
     446           0 :             return ntok;
     447             :         }
     448           0 :         if (trp->tp->type == NL)
     449             :         {
     450           0 :             trp->tp += 1;
     451           0 :             adjustrow(trp, -1);
     452           0 :             trp->tp -= 1;
     453             :             /* makespace(trp); [rh] */
     454           0 :             needspace = 1;
     455           0 :             continue;
     456             :         }
     457           0 :         if (trp->tp->type == LP)
     458           0 :             parens++;
     459             :         else
     460           0 :             if (trp->tp->type == RP)
     461           0 :                 parens--;
     462           0 :         trp->tp++;
     463           0 :         ntok++;
     464             :     }
     465           0 :     trp->tp -= ntok;
     466             :     /* Now trp->tp won't move underneath us */
     467           0 :     lp = bp = trp->tp + ntokp;
     468           0 :     for (; parens >= 0; lp++)
     469             :     {
     470           0 :         if (lp->type == LP)
     471             :         {
     472           0 :             parens++;
     473           0 :             continue;
     474             :         }
     475           0 :         if (lp->type == RP)
     476           0 :             parens--;
     477           0 :         if (lp->type == DSHARP)
     478           0 :             lp->type = DSHARP1;         /* ## not special in arg */
     479           0 :         if ((lp->type == COMMA && parens == 0) ||
     480           0 :                 ( parens < 0 && ((lp - 1)->type != LP)))
     481             :         {
     482           0 :             if (*narg >= NARG - 1)
     483           0 :                 error(FATAL, "Sorry, too many macro arguments");
     484           0 :             ttr.bp = ttr.tp = bp;
     485           0 :             ttr.lp = lp;
     486           0 :             atr[(*narg)++] = normtokenrow(&ttr);
     487           0 :             bp = lp + 1;
     488             :         }
     489             :     }
     490           0 :     return ntok;
     491             : }
     492             : 
     493             : /*
     494             :  * substitute the argument list into the replacement string
     495             :  *  This would be simple except for ## and #
     496             :  */
     497             : void
     498           0 :     substargs(Nlist * np, Tokenrow * rtr, Tokenrow ** atr)
     499             : {
     500             :     Tokenrow tatr;
     501             :     Token *tp;
     502             :     int ntok, argno;
     503             : 
     504           0 :     for (rtr->tp = rtr->bp; rtr->tp < rtr->lp;)
     505             :     {
     506           0 :         if (rtr->tp->type == SHARP)
     507             :         {                               /* string operator */
     508           0 :             tp = rtr->tp;
     509           0 :             rtr->tp += 1;
     510           0 :             if ((argno = lookuparg(np, rtr->tp)) < 0)
     511             :             {
     512           0 :                 error(ERROR, "# not followed by macro parameter");
     513           0 :                 continue;
     514             :             }
     515           0 :             ntok = 1 + (int)(rtr->tp - tp);
     516           0 :             rtr->tp = tp;
     517           0 :             insertrow(rtr, ntok, stringify(atr[argno]));
     518           0 :             continue;
     519             :         }
     520           0 :         if (rtr->tp->type == NAME
     521           0 :             && (argno = lookuparg(np, rtr->tp)) >= 0)
     522             :         {
     523           0 :             if (((rtr->tp + 1) < rtr->lp && (rtr->tp + 1)->type == DSHARP)
     524           0 :                 || (rtr->tp != rtr->bp  && (rtr->tp - 1)->type == DSHARP))
     525             :             {
     526           0 :                 copytokenrow(&tatr, atr[argno]);
     527           0 :                 makespace(&tatr, rtr->tp);
     528           0 :                 insertrow(rtr, 1, &tatr);
     529           0 :                 dofree(tatr.bp);
     530             :             }
     531             :             else
     532             :             {
     533           0 :                 copytokenrow(&tatr, atr[argno]);
     534           0 :                 makespace(&tatr, rtr->tp);
     535           0 :                 expandrow(&tatr, "<macro>");
     536           0 :                 insertrow(rtr, 1, &tatr);
     537           0 :                 dofree(tatr.bp);
     538             :             }
     539           0 :             continue;
     540             :         }
     541           0 :         rtr->tp++;
     542             :     }
     543           0 : }
     544             : 
     545             : /*
     546             :  * Evaluate the ## operators in a tokenrow
     547             :  */
     548             : void
     549           0 :     doconcat(Tokenrow * trp)
     550             : {
     551             :     Token *ltp, *ntp;
     552             :     Tokenrow ntr;
     553             :     size_t len;
     554             : 
     555           0 :     for (trp->tp = trp->bp; trp->tp < trp->lp; trp->tp++)
     556             :     {
     557           0 :         if (trp->tp->type == DSHARP1)
     558           0 :             trp->tp->type = DSHARP;
     559             :         else
     560           0 :             if (trp->tp->type == DSHARP)
     561             :             {
     562             :                 int  i;
     563             :                 char tt[NCONCAT];
     564             : 
     565           0 :                 ltp = trp->tp - 1;
     566           0 :                 ntp = trp->tp + 1;
     567             : 
     568           0 :                 if (ltp < trp->bp || ntp >= trp->lp)
     569             :                 {
     570           0 :                     error(ERROR, "## occurs at border of replacement");
     571           0 :                     continue;
     572             :                 }
     573             : 
     574           0 :                 ntp = ltp;
     575           0 :                 i   = 1;
     576           0 :                 len = 0;
     577             : 
     578             :                 do
     579             :                 {
     580           0 :                     if (len + ntp->len + ntp->wslen > sizeof(tt))
     581             :                     {
     582           0 :                         error(ERROR, "## string concatination buffer overrun");
     583           0 :                         break;
     584             :                     }
     585             : 
     586           0 :                     if (ntp != trp->tp + 1)
     587             :                     {
     588           0 :                         strncpy((char *) tt + len, (char *) ntp->t - ntp->wslen,
     589           0 :                                 ntp->len + ntp->wslen);
     590           0 :                         len += ntp->len + ntp->wslen;
     591             :                     }
     592             :                     else    // Leerzeichen um ## herum entfernen:
     593             :                     {
     594           0 :                         strncpy((char *) tt + len, (char *) ntp->t, ntp->len);
     595           0 :                         len += ntp->len;
     596             :                     }
     597             : 
     598           0 :                     ntp = trp->tp + i;
     599           0 :                     i++;
     600             :                 }
     601           0 :                 while (ntp < trp->lp);
     602             : 
     603           0 :                 tt[len] = '\0';
     604           0 :                 setsource("<##>", -1, -1, tt, 0);
     605           0 :                 maketokenrow(3, &ntr);
     606           0 :                 gettokens(&ntr, 1);
     607           0 :                 unsetsource();
     608           0 :                 if (ntr.bp->type == UNCLASS)
     609           0 :                     error(WARNING, "Bad token %r produced by ##", &ntr);
     610           0 :                 while ((ntr.lp-1)->len == 0 && ntr.lp != ntr.bp)
     611           0 :                     ntr.lp--;
     612             : 
     613           0 :                 doconcat(&ntr);
     614           0 :                 trp->tp = ltp;
     615           0 :                 makespace(&ntr, ltp);
     616           0 :                 insertrow(trp, (int)(ntp - ltp), &ntr);
     617           0 :                 dofree(ntr.bp);
     618           0 :                 trp->tp--;
     619             :             }
     620             :     }
     621           0 : }
     622             : 
     623             : /*
     624             :  * tp is a potential parameter name of macro mac;
     625             :  * look it up in mac's arglist, and if found, return the
     626             :  * corresponding index in the argname array.  Return -1 if not found.
     627             :  */
     628             : int
     629           0 :     lookuparg(Nlist * mac, Token * tp)
     630             : {
     631             :     Token *ap;
     632             : 
     633           0 :     if (tp->type != NAME || mac->ap == NULL)
     634           0 :         return -1;
     635           0 :     for (ap = mac->ap->bp; ap < mac->ap->lp; ap++)
     636             :     {
     637           0 :         if (ap->len == tp->len && strncmp((char *) ap->t, (char *) tp->t, ap->len) == 0)
     638           0 :             return (int)(ap - mac->ap->bp);
     639             :     }
     640           0 :     return -1;
     641             : }
     642             : 
     643             : /*
     644             :  * Return a quoted version of the tokenrow (from # arg)
     645             :  */
     646             : #define STRLEN  512
     647             : Tokenrow *
     648           0 :     stringify(Tokenrow * vp)
     649             : {
     650             :     static Token t = {STRING, 0, 0, 0, NULL, 0};
     651             :     static Tokenrow tr = {&t, &t, &t + 1, 1};
     652             :     Token *tp;
     653             :     uchar s[STRLEN];
     654           0 :     uchar *sp = s, *cp;
     655             :     int i, instring;
     656             : 
     657           0 :     *sp++ = '"';
     658           0 :     for (tp = vp->bp; tp < vp->lp; tp++)
     659             :     {
     660           0 :         instring = tp->type == STRING || tp->type == CCON;
     661           0 :         if (sp + 2 * tp->len + tp->wslen  >= &s[STRLEN - 10])
     662             :         {
     663           0 :             error(ERROR, "Stringified macro arg is too long");
     664           0 :             break;
     665             :         }
     666             : 
     667             :         // Change by np 31.10.2001, #93725 - begin
     668           0 :         if ( tp->wslen > 0 )
     669           0 :             *sp++ = ' ';
     670             :         // change end.
     671             : 
     672           0 :         for (i = 0, cp = tp->t; (unsigned int)i < tp->len; i++)
     673             :         {
     674           0 :             if (instring && (*cp == '"' || *cp == '\\'))
     675           0 :                 *sp++ = '\\';
     676           0 :             *sp++ = *cp++;
     677             :         }
     678             :     }
     679           0 :     *sp++ = '"';
     680           0 :     *sp = '\0';
     681           0 :     sp = s;
     682           0 :     t.len = strlen((char *) sp);
     683           0 :     t.t = newstring(sp, t.len, 0);
     684           0 :     return &tr;
     685             : }
     686             : 
     687             : /*
     688             :  * expand a builtin name
     689             :  */
     690             : void
     691           0 :     builtin(Tokenrow * trp, int biname)
     692             : {
     693             :     char *op;
     694             :     Token *tp;
     695             :     Source *s;
     696             : 
     697           0 :     tp = trp->tp;
     698           0 :     trp->tp++;
     699             :     /* need to find the real source */
     700           0 :     s = cursource;
     701           0 :     while (s && s->fd == -1)
     702           0 :         s = s->next;
     703           0 :     if (s == NULL)
     704           0 :         s = cursource;
     705             :     /* most are strings */
     706           0 :     tp->type = STRING;
     707           0 :     if (tp->wslen)
     708             :     {
     709           0 :         *outptr++ = ' ';
     710           0 :         tp->wslen = 1;
     711             :     }
     712           0 :     op = outptr;
     713           0 :     *op++ = '"';
     714           0 :     switch (biname)
     715             :     {
     716             : 
     717             :         case KLINENO:
     718           0 :             tp->type = NUMBER;
     719           0 :             op = outnum(op - 1, s->line);
     720           0 :             break;
     721             : 
     722             :         case KFILE:
     723             :             {
     724           0 :                 char *src = s->filename;
     725             : 
     726           0 :                 while ((*op++ = *src++) != 0)
     727           0 :                     if (src[-1] == '\\')
     728           0 :                         *op++ = '\\';
     729           0 :                 op--;
     730           0 :                 break;
     731             :             }
     732             : 
     733             :         case KDATE:
     734           0 :             strncpy(op, curtime + 4, 7);
     735           0 :             strncpy(op + 7, curtime + 20, 4);
     736           0 :             op += 11;
     737           0 :             break;
     738             : 
     739             :         case KTIME:
     740           0 :             strncpy(op, curtime + 11, 8);
     741           0 :             op += 8;
     742           0 :             break;
     743             : 
     744             :         default:
     745           0 :             error(ERROR, "cpp botch: unknown internal macro");
     746           0 :             return;
     747             :     }
     748           0 :     if (tp->type == STRING)
     749           0 :         *op++ = '"';
     750           0 :     tp->t = (uchar *) outptr;
     751           0 :     tp->len = op - outptr;
     752           0 :     outptr = op;
     753             : }
     754             : 
     755             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10