LCOV - code coverage report
Current view: top level - rsc/source/rscpp - cpp2.c (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 110 179 61.5 %
Date: 2012-08-25 Functions: 6 6 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 81 150 54.0 %

           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        <stdio.h>
      21                 :            : #include        <ctype.h>
      22                 :            : #include        "cppdef.h"
      23                 :            : #include        "cpp.h"
      24                 :            : #if HOST == SYS_VMS
      25                 :            : /*
      26                 :            :  * Include the rms stuff.  (We can't just include rms.h as it uses the
      27                 :            :  * VaxC-specific library include syntax that Decus CPP doesn't support.
      28                 :            :  * By including things by hand, we can CPP ourself.)
      29                 :            :  */
      30                 :            : #include        <nam.h>
      31                 :            : #include        <fab.h>
      32                 :            : #include        <rab.h>
      33                 :            : #include        <rmsdef.h>
      34                 :            : #endif
      35                 :            : 
      36                 :            : /*
      37                 :            :  * Generate (by hand-inspection) a set of unique values for each control
      38                 :            :  * operator.  Note that this is not guaranteed to work for non-Ascii
      39                 :            :  * machines.  CPP won't compile if there are hash conflicts.
      40                 :            :  */
      41                 :            : 
      42                 :            : #define L_assert        ('a' + ('s' << 1))
      43                 :            : #define L_define        ('d' + ('f' << 1))
      44                 :            : #define L_elif          ('e' + ('i' << 1))
      45                 :            : #define L_else          ('e' + ('s' << 1))
      46                 :            : #define L_endif         ('e' + ('d' << 1))
      47                 :            : #define L_if            ('i' + (EOS << 1))
      48                 :            : #define L_ifdef         ('i' + ('d' << 1))
      49                 :            : #define L_ifndef        ('i' + ('n' << 1))
      50                 :            : #define L_include       ('i' + ('c' << 1))
      51                 :            : #define L_line          ('l' + ('n' << 1))
      52                 :            : #define L_nogood        (EOS + (EOS << 1))      /* To catch #i          */
      53                 :            : #define L_pragma        ('p' + ('a' << 1))
      54                 :            : #define L_undef         ('u' + ('d' << 1))
      55                 :            : #define L_error         ('e' + ('r' << 1))      /* BP 5.3.92, #error */
      56                 :            : #define MAXLINE 80                              /* BP 5.3.92, #error */
      57                 :            : #if OSL_DEBUG_LEVEL > 1
      58                 :            : #define L_debug         ('d' + ('b' << 1))      /* #debug               */
      59                 :            : #define L_nodebug       ('n' + ('d' << 1))      /* #nodebug             */
      60                 :            : #endif
      61                 :            : 
      62                 :            : 
      63                 :       1320 : void InitCpp2()
      64                 :            : {
      65                 :            : 
      66                 :       1320 : }
      67                 :            : 
      68                 :            : 
      69                 :            : int
      70                 :    3151892 : control(int counter)
      71                 :            : /*
      72                 :            :  * Process #control lines.  Simple commands are processed inline,
      73                 :            :  * while complex commands have their own subroutines.
      74                 :            :  *
      75                 :            :  * The counter is used to force out a newline before #line, and
      76                 :            :  * #pragma commands.  This prevents these commands from ending up at
      77                 :            :  * the end of the previous line if cpp is invoked with the -C option.
      78                 :            :  */
      79                 :            : {
      80                 :            :         register int            c;
      81                 :            :         register char           *tp;
      82                 :            :         register int            hash;
      83                 :            :         char                    *ep;
      84                 :            : 
      85                 :    3151892 :         c = skipws();
      86 [ -  + ][ +  - ]:    3151892 :         if (c == '\n' || c == EOF_CHAR)
      87                 :          0 :             return (counter + 1);
      88         [ +  - ]:    3151892 :         if (!isdigit(c))
      89                 :    3151892 :             scanid(c);                  /* Get #word to token[]         */
      90                 :            :         else {
      91                 :          0 :             unget();                    /* Hack -- allow #123 as a      */
      92                 :          0 :             strcpy(token, "line");      /* synonym for #line 123        */
      93                 :            :         }
      94         [ +  - ]:    3151892 :         hash = (token[1] == EOS) ? L_nogood : (token[0] + (token[2] << 1));
      95   [ -  +  +  +  :    3151892 :         switch (hash) {
          +  +  +  +  +  
          -  -  +  +  -  
                      - ]
      96                 :          0 :         case L_assert:  tp = "assert";          break;
      97                 :    3069978 :         case L_define:  tp = "define";          break;
      98                 :         80 :         case L_elif:    tp = "elif";            break;
      99                 :         60 :         case L_else:    tp = "else";            break;
     100                 :      28342 :         case L_endif:   tp = "endif";           break;
     101                 :       1556 :         case L_if:      tp = "if";              break;
     102                 :        606 :         case L_ifdef:   tp = "ifdef";           break;
     103                 :      26180 :         case L_ifndef:  tp = "ifndef";          break;
     104                 :      23076 :         case L_include: tp = "include";         break;
     105                 :          0 :         case L_line:    tp = "line";            break;
     106                 :          0 :         case L_pragma:  tp = "pragma";          break;
     107                 :        630 :         case L_undef:   tp = "undef";           break;
     108                 :       1384 :         case L_error:   tp = "error";           break;
     109                 :            : #if OSL_DEBUG_LEVEL > 1
     110                 :            :         case L_debug:   tp = "debug";           break;
     111                 :            :         case L_nodebug: tp = "nodebug";         break;
     112                 :            : #endif
     113                 :          0 :         default:        hash = L_nogood;
     114                 :          0 :         case L_nogood:  tp = "";                break;
     115                 :            :         }
     116         [ -  + ]:    3151892 :         if (!streq(tp, token))
     117                 :          0 :             hash = L_nogood;
     118                 :            :         /*
     119                 :            :          * hash is set to a unique value corresponding to the
     120                 :            :          * control keyword (or L_nogood if we think it's nonsense).
     121                 :            :          */
     122         [ -  + ]:    3151892 :         if (infile->fp == NULL)
     123                 :          0 :             cwarn("Control line \"%s\" within macro expansion", token);
     124         [ +  + ]:    3151892 :         if (!compiling) {                       /* Not compiling now    */
     125      [ +  +  + ]:     859392 :             switch (hash) {
     126                 :            :             case L_if:                          /* These can't turn     */
     127                 :            :             case L_ifdef:                       /*  compilation on, but */
     128                 :            :             case L_ifndef:                      /*   we must nest #if's */
     129         [ -  + ]:         78 :                 if (++ifptr >= &ifstack[BLK_NEST])
     130                 :          0 :                     goto if_nest_err;
     131                 :         78 :                 *ifptr = 0;                     /* !WAS_COMPILING       */
     132                 :            :             case L_line:                        /* Many                 */
     133                 :            :             /*
     134                 :            :              * Are pragma's always processed?
     135                 :            :              */
     136                 :            :             case L_pragma:                      /*  options             */
     137                 :            :             case L_include:                     /*   are uninteresting  */
     138                 :            :             case L_define:                      /*    if we             */
     139                 :            :             case L_undef:                       /*     aren't           */
     140                 :            :             case L_assert:                      /*      compiling.      */
     141                 :            :             case L_error:                       /* BP 5.3.92, #error */
     142                 :     847216 : dump_line:      skipnl();                       /* Ignore rest of line  */
     143                 :     847216 :                 return (counter + 1);
     144                 :            :             }
     145                 :            :         }
     146                 :            :         /*
     147                 :            :          * Make sure that #line and #pragma are output on a fresh line.
     148                 :            :          */
     149 [ +  + ][ +  - ]:    2304716 :         if (counter > 0 && (hash == L_line || hash == L_pragma)) {
                 [ -  + ]
     150                 :          0 :             PUTCHAR('\n');
     151                 :          0 :             counter--;
     152                 :            :         }
     153   [ -  +  +  +  :    2304716 :         switch (hash) {
          +  +  +  +  -  
                -  -  - ]
     154                 :            :         case L_line:
     155                 :            :             /*
     156                 :            :              * Parse the line to update the line number and "progname"
     157                 :            :              * field and line number for the next input line.
     158                 :            :              * Set wrongline to force it out later.
     159                 :            :              */
     160                 :          0 :             c = skipws();
     161                 :          0 :             workp = work;                       /* Save name in work    */
     162 [ #  # ][ #  # ]:          0 :             while (c != '\n' && c != EOF_CHAR) {
     163                 :          0 :                 save(c);
     164                 :          0 :                 c = get();
     165                 :            :             }
     166                 :          0 :             unget();
     167                 :          0 :             save(EOS);
     168                 :            :             /*
     169                 :            :              * Split #line argument into <line-number> and <name>
     170                 :            :              * We subtract 1 as we want the number of the next line.
     171                 :            :              */
     172                 :          0 :             line = atoi(work) - 1;              /* Reset line number    */
     173 [ #  # ][ #  # ]:          0 :             for (tp = work; isdigit(*tp) || type[(int)*tp] == SPA; tp++)
     174                 :            :                 ;                               /* Skip over digits     */
     175         [ #  # ]:          0 :             if (*tp != EOS) {                   /* Got a filename, so:  */
     176 [ #  # ][ #  # ]:          0 :                 if (*tp == '"' && (ep = strrchr(tp + 1, '"')) != NULL) {
     177                 :          0 :                     tp++;                       /* Skip over left quote */
     178                 :          0 :                     *ep = EOS;                  /* And ignore right one */
     179                 :            :                 }
     180         [ #  # ]:          0 :                 if (infile->progname != NULL)   /* Give up the old name */
     181                 :          0 :                     free(infile->progname);     /* if it's allocated.   */
     182                 :          0 :                 infile->progname = savestring(tp);
     183                 :            :             }
     184                 :          0 :             wrongline = TRUE;                   /* Force output later   */
     185                 :          0 :             break;
     186                 :            : 
     187                 :            :         case L_include:
     188                 :      18692 :             doinclude();
     189                 :      18692 :             break;
     190                 :            : 
     191                 :            :         case L_define:
     192                 :    2229068 :             dodefine();
     193                 :    2229068 :             break;
     194                 :            : 
     195                 :            :         case L_undef:
     196                 :        210 :             doundef();
     197                 :        210 :             break;
     198                 :            : 
     199                 :            :         case L_else:
     200         [ -  + ]:         60 :             if (ifptr == &ifstack[0])
     201                 :          0 :                 goto nest_err;
     202         [ -  + ]:         60 :             else if ((*ifptr & ELSE_SEEN) != 0)
     203                 :          0 :                 goto else_seen_err;
     204                 :         60 :             *ifptr |= ELSE_SEEN;
     205         [ +  + ]:         60 :             if ((*ifptr & WAS_COMPILING) != 0) {
     206 [ +  + ][ -  + ]:         58 :                 if (compiling || (*ifptr & TRUE_SEEN) != 0)
     207                 :         54 :                     compiling = FALSE;
     208                 :            :                 else {
     209                 :          4 :                     compiling = TRUE;
     210                 :            :                 }
     211                 :            :             }
     212                 :         60 :             break;
     213                 :            : 
     214                 :            :         case L_elif:
     215         [ -  + ]:         80 :             if (ifptr == &ifstack[0])
     216                 :          0 :                 goto nest_err;
     217         [ -  + ]:         80 :             else if ((*ifptr & ELSE_SEEN) != 0) {
     218                 :          0 : else_seen_err:  cerror("#%s may not follow #else", token);
     219                 :          0 :                 goto dump_line;
     220                 :            :             }
     221         [ +  + ]:         80 :             if ((*ifptr & (WAS_COMPILING | TRUE_SEEN)) != WAS_COMPILING) {
     222                 :         40 :                 compiling = FALSE;              /* Done compiling stuff */
     223                 :         40 :                 goto dump_line;                 /* Skip this clause     */
     224                 :            :             }
     225                 :         40 :             doif(L_if);
     226                 :         40 :             break;
     227                 :            : 
     228                 :            :         case L_if:
     229                 :            :         case L_ifdef:
     230                 :            :         case L_ifndef:
     231         [ -  + ]:      28264 :             if (++ifptr >= &ifstack[BLK_NEST])
     232                 :          0 : if_nest_err:    cfatal("Too many nested #%s statements", token);
     233                 :      28264 :             *ifptr = WAS_COMPILING;
     234                 :      28264 :             doif(hash);
     235                 :      28264 :             break;
     236                 :            : 
     237                 :            :         case L_endif:
     238         [ -  + ]:      28342 :             if (ifptr == &ifstack[0]) {
     239                 :          0 : nest_err:       cerror("#%s must be in an #if", token);
     240                 :          0 :                 goto dump_line;
     241                 :            :             }
     242 [ +  + ][ +  + ]:      28342 :             if (!compiling && (*ifptr & WAS_COMPILING) != 0)
     243                 :      12092 :                 wrongline = TRUE;
     244                 :      28342 :             compiling = ((*ifptr & WAS_COMPILING) != 0);
     245                 :      28342 :             --ifptr;
     246                 :      28342 :             break;
     247                 :            : 
     248                 :            :         case L_assert:
     249         [ #  # ]:          0 :             if (eval() == 0)
     250                 :          0 :                 cerror("Preprocessor assertion failure", NULLST);
     251                 :          0 :             break;
     252                 :            : 
     253                 :            :         case L_pragma:
     254                 :            :             /*
     255                 :            :              * #pragma is provided to pass "options" to later
     256                 :            :              * passes of the compiler.  cpp doesn't have any yet.
     257                 :            :              */
     258                 :          0 :             fprintf( pCppOut, "#pragma ");
     259 [ #  # ][ #  # ]:          0 :             while ((c = get()) != '\n' && c != EOF_CHAR)
     260         [ #  # ]:          0 :                 cput(c);
     261                 :          0 :             unget();
     262                 :          0 :             break;
     263                 :            : 
     264                 :            : #if OSL_DEBUG_LEVEL > 1
     265                 :            :         case L_debug:
     266                 :            :             if (debug == 0)
     267                 :            :                 dumpdef("debug set on");
     268                 :            :             debug++;
     269                 :            :             break;
     270                 :            : 
     271                 :            :         case L_nodebug:
     272                 :            :             debug--;
     273                 :            :             break;
     274                 :            : #endif
     275                 :            :         case L_error:                       /* BP 5.3.92, #error */
     276                 :            :         {
     277                 :          0 :             fprintf( pCppOut, "cpp: line %u, Error directive: ", line );
     278 [ #  # ][ #  # ]:          0 :             while ((c = get()) != '\n' && c != EOF_CHAR)
     279         [ #  # ]:          0 :                 cput(c);
     280                 :          0 :             fprintf( pCppOut, "\n" );
     281                 :          0 :             exit( 1 );
     282                 :            :             break;
     283                 :            :         }
     284                 :            :         default:
     285                 :            :             /*
     286                 :            :              * Undefined #control keyword.
     287                 :            :              * Note: the correct behavior may be to warn and
     288                 :            :              * pass the line to a subsequent compiler pass.
     289                 :            :              * This would allow #asm or similar extensions.
     290                 :            :              */
     291                 :          0 :             cerror("Illegal # command \"%s\"", token);
     292                 :          0 :             break;
     293                 :            :         }
     294         [ +  + ]:    2304676 :         if (hash != L_include) {
     295                 :            : #if OLD_PREPROCESSOR
     296                 :            :             /*
     297                 :            :              * Ignore the rest of the #control line so you can write
     298                 :            :              *          #if     foo
     299                 :            :              *          #endif  foo
     300                 :            :              */
     301                 :            :             goto dump_line;                     /* Take common exit     */
     302                 :            : #else
     303         [ -  + ]:    2285984 :             if (skipws() != '\n') {
     304                 :          0 :                 cwarn("Unexpected text in #control line ignored", NULLST);
     305                 :          0 :                 skipnl();
     306                 :            :             }
     307                 :            : #endif
     308                 :            :         }
     309                 :    3151892 :         return (counter + 1);
     310                 :            : }
     311                 :            : 
     312                 :            : FILE_LOCAL
     313                 :      28304 : void doif(int hash)
     314                 :            : /*
     315                 :            :  * Process an #if, #ifdef, or #ifndef.  The latter two are straightforward,
     316                 :            :  * while #if needs a subroutine of its own to evaluate the expression.
     317                 :            :  *
     318                 :            :  * doif() is called only if compiling is TRUE.  If false, compilation
     319                 :            :  * is always supressed, so we don't need to evaluate anything.  This
     320                 :            :  * supresses unnecessary warnings.
     321                 :            :  */
     322                 :            : {
     323                 :            :         register int            c;
     324                 :            :         register int            found;
     325                 :            : 
     326 [ +  - ][ -  + ]:      28304 :         if ((c = skipws()) == '\n' || c == EOF_CHAR) {
     327                 :          0 :             unget();
     328                 :          0 :             goto badif;
     329                 :            :         }
     330         [ +  + ]:      28304 :         if (hash == L_if) {
     331                 :       1556 :             unget();
     332                 :       1556 :             found = (eval() != 0);      /* Evaluate expr, != 0 is  TRUE */
     333                 :       1556 :             hash = L_ifdef;             /* #if is now like #ifdef       */
     334                 :            :         }
     335                 :            :         else {
     336         [ -  + ]:      26748 :             if (type[c] != LET)         /* Next non-blank isn't letter  */
     337                 :          0 :                 goto badif;             /* ... is an error              */
     338                 :      26748 :             found = (lookid(c) != NULL); /* Look for it in symbol table */
     339                 :            :         }
     340         [ +  + ]:      28304 :         if (found == (hash == L_ifdef)) {
     341                 :      16262 :             compiling = TRUE;
     342                 :      16262 :             *ifptr |= TRUE_SEEN;
     343                 :            :         }
     344                 :            :         else {
     345                 :      12042 :             compiling = FALSE;
     346                 :            :         }
     347                 :      28304 :         return;
     348                 :            : 
     349                 :          0 : badif:  cerror("#if, #ifdef, or #ifndef without an argument", NULLST);
     350                 :            : #if !OLD_PREPROCESSOR
     351                 :          0 :         skipnl();                               /* Prevent an extra     */
     352                 :          0 :         unget();                                /* Error message        */
     353                 :            : #endif
     354                 :      28304 :         return;
     355                 :            : }
     356                 :            : 
     357                 :            : FILE_LOCAL
     358                 :      18692 : void doinclude()
     359                 :            : /*
     360                 :            :  * Process the #include control line.
     361                 :            :  * There are three variations:
     362                 :            :  *      #include "file"         search somewhere relative to the
     363                 :            :  *                              current source file, if not found,
     364                 :            :  *                              treat as #include <file>.
     365                 :            :  *      #include <file>         Search in an implementation-dependent
     366                 :            :  *                              list of places.
     367                 :            :  *      #include token          Expand the token, it must be one of
     368                 :            :  *                              "file" or <file>, process as such.
     369                 :            :  *
     370                 :            :  * Note: the November 12 draft forbids '>' in the #include <file> format.
     371                 :            :  * This restriction is unnecessary and not implemented.
     372                 :            :  */
     373                 :            : {
     374                 :            :         register int            c;
     375                 :            :         register int            delim;
     376                 :            : #if HOST == SYS_VMS
     377                 :            :         char                    def_filename[NAM$C_MAXRSS + 1];
     378                 :            : #endif
     379                 :            : 
     380                 :      18692 :         delim = macroid(skipws());
     381 [ -  + ][ +  + ]:      18692 :         if (delim != '<' && delim != '"')
     382                 :          0 :             goto incerr;
     383         [ +  + ]:      18692 :         if (delim == '<')
     384                 :      14098 :             delim = '>';
     385                 :      18692 :         workp = work;
     386                 :      18692 :         instring = TRUE;                /* Accept all characters        */
     387                 :            : #ifdef CONTROL_COMMENTS_NOT_ALLOWED
     388                 :            :         while ((c = get()) != '\n' && c != EOF_CHAR)
     389                 :            :             save(c);                    /* Put it away.                 */
     390                 :            :         unget();                        /* Force nl after includee      */
     391                 :            :         /*
     392                 :            :          * The draft is unclear if the following should be done.
     393                 :            :          */
     394                 :            :         while (--workp >= work && *workp == ' ')
     395                 :            :             ;                           /* Trim blanks from filename    */
     396                 :            :         if (*workp != delim)
     397                 :            :             goto incerr;
     398                 :            : #else
     399 [ +  + ][ +  - ]:     284638 :         while ((c = get()) != delim && c != EOF_CHAR)
     400                 :     265946 :             save(c);
     401                 :            : #endif
     402                 :      18692 :         *workp = EOS;                   /* Terminate filename           */
     403                 :      18692 :         instring = FALSE;
     404                 :            : #if HOST == SYS_VMS
     405                 :            :         /*
     406                 :            :          * Assume the default .h filetype.
     407                 :            :          */
     408                 :            :         if (!vmsparse(work, ".H", def_filename)) {
     409                 :            :             perror(work);               /* Oops.                        */
     410                 :            :             goto incerr;
     411                 :            :         }
     412                 :            :         else if (openinclude(def_filename, (delim == '"')))
     413                 :            :             return;
     414                 :            : #else
     415         [ +  - ]:      18692 :         if (openinclude(work, (delim == '"')))
     416                 :      18692 :             return;
     417                 :            : #endif
     418                 :            :         /*
     419                 :            :          * No sense continuing if #include file isn't there.
     420                 :            :          */
     421                 :          0 :         cfatal("Cannot open include file \"%s\"", work);
     422                 :            : 
     423                 :          0 : incerr: cerror("#include syntax error", NULLST);
     424                 :      18692 :         return;
     425                 :            : }
     426                 :            : 
     427                 :            : FILE_LOCAL int
     428                 :      18692 : openinclude(char* filename, int searchlocal)
     429                 :            : /*
     430                 :            :  * Actually open an include file.  This routine is only called from
     431                 :            :  * doinclude() above, but was written as a separate subroutine for
     432                 :            :  * programmer convenience.  It searches the list of directories
     433                 :            :  * and actually opens the file, linking it into the list of
     434                 :            :  * active files.  Returns TRUE if the file was opened, FALSE
     435                 :            :  * if openinclude() fails.  No error message is printed.
     436                 :            :  */
     437                 :            : {
     438                 :            :         register char           **incptr;
     439                 :            : #if HOST == SYS_VMS
     440                 :            : #if NFWORK < (NAM$C_MAXRSS + 1)
     441                 :            :     << error, NFWORK is not greater than NAM$C_MAXRSS >>
     442                 :            : #endif
     443                 :            : #endif
     444                 :            :         char                    tmpname[NFWORK]; /* Filename work area   */
     445                 :            : 
     446         [ +  + ]:      18692 :         if (searchlocal) {
     447                 :            :             /*
     448                 :            :              * Look in local directory first
     449                 :            :              */
     450                 :            : #if HOST == SYS_UNIX
     451                 :            :             /*
     452                 :            :              * Try to open filename relative to the directory of the current
     453                 :            :              * source file (as opposed to the current directory). (ARF, SCK).
     454                 :            :              */
     455         [ +  - ]:       4594 :             if (filename[0] != '/'
     456         [ +  - ]:       4594 :              && hasdirectory(infile->filename, tmpname))
     457                 :       4594 :                 strcat(tmpname, filename);
     458                 :            :             else {
     459                 :          0 :                 strcpy(tmpname, filename);
     460                 :            :             }
     461                 :            : #else
     462                 :            :             if (!hasdirectory(filename, tmpname)
     463                 :            :              && hasdirectory(infile->filename, tmpname))
     464                 :            :                 strcat(tmpname, filename);
     465                 :            :             else {
     466                 :            :                 strcpy(tmpname, filename);
     467                 :            :             }
     468                 :            : #endif
     469         [ +  + ]:       4594 :             if (openfile(tmpname))
     470                 :       1982 :                 return (TRUE);
     471                 :            :         }
     472                 :            :         /*
     473                 :            :          * Look in any directories specified by -I command line
     474                 :            :          * arguments, then in the builtin search list.
     475                 :            :          */
     476         [ +  - ]:      65052 :         for (incptr = incdir; incptr < incend; incptr++) {
     477         [ -  + ]:      65052 :             if (strlen(*incptr) + strlen(filename) >= (NFWORK - 1))
     478                 :          0 :                 cfatal("Filename work buffer overflow", NULLST);
     479                 :            :             else {
     480                 :            : #if HOST == SYS_UNIX
     481         [ -  + ]:      65052 :                 if (filename[0] == '/')
     482                 :          0 :                     strcpy(tmpname, filename);
     483                 :            :                 else {
     484                 :      65052 :                     sprintf(tmpname, "%s/%s", *incptr, filename);
     485                 :            :                 }
     486                 :            : #elif HOST == SYS_UNKNOWN
     487                 :            :                 if (filename[0] == '\\')
     488                 :            :                     strcpy(tmpname, filename);
     489                 :            :                 else {
     490                 :            :                     sprintf(tmpname, "%s\\%s", *incptr, filename);
     491                 :            :                 }
     492                 :            : #else
     493                 :            :                 if (!hasdirectory(filename, tmpname))
     494                 :            :                     sprintf(tmpname, "%s%s", *incptr, filename);
     495                 :            : #endif
     496         [ +  + ]:      65052 :                 if (openfile(tmpname))
     497                 :      16710 :                     return (TRUE);
     498                 :            :             }
     499                 :            :         }
     500                 :      18692 :         return (FALSE);
     501                 :            : }
     502                 :            : 
     503                 :            : FILE_LOCAL int
     504                 :       4594 : hasdirectory(char* source, char* result)
     505                 :            : /*
     506                 :            :  * If a device or directory is found in the source filename string, the
     507                 :            :  * node/device/directory part of the string is copied to result and
     508                 :            :  * hasdirectory returns TRUE.  Else, nothing is copied and it returns FALSE.
     509                 :            :  */
     510                 :            : {
     511                 :            : #if HOST == SYS_UNIX
     512                 :            :         register char           *tp;
     513                 :            : 
     514         [ -  + ]:       4594 :         if ((tp = strrchr(source, '/')) == NULL)
     515                 :          0 :             return (FALSE);
     516                 :            :         else {
     517                 :       4594 :             strncpy(result, source, tp - source + 1);
     518                 :       4594 :             result[tp - source + 1] = EOS;
     519                 :       4594 :             return (TRUE);
     520                 :            :         }
     521                 :            : #else
     522                 :            : #if HOST == SYS_VMS
     523                 :            :         if (vmsparse(source, NULLST, result)
     524                 :            :          && result[0] != EOS)
     525                 :            :             return (TRUE);
     526                 :            :         else {
     527                 :            :             return (FALSE);
     528                 :            :         }
     529                 :            : #else
     530                 :            :         /*
     531                 :            :          * Random DEC operating system (RSX, RT11, RSTS/E)
     532                 :            :          */
     533                 :            :         register char           *tp;
     534                 :            : 
     535                 :            :         if ((tp = strrchr(source, ']')) == NULL
     536                 :            :          && (tp = strrchr(source, ':')) == NULL)
     537                 :            :             return (FALSE);
     538                 :            :         else {
     539                 :            :             strncpy(result, source, tp - source + 1);
     540                 :            :             result[tp - source + 1] = EOS;
     541                 :            :             return (TRUE);
     542                 :            :         }
     543                 :            : #endif
     544                 :            : #endif
     545                 :            : }
     546                 :            : 
     547                 :            : #if HOST == SYS_VMS
     548                 :            : 
     549                 :            : /*
     550                 :            :  * EXP_DEV is set if a device was specified, EXP_DIR if a directory
     551                 :            :  * is specified.  (Both set indicate a file-logical, but EXP_DEV
     552                 :            :  * would be set by itself if you are reading, say, SYS$INPUT:)
     553                 :            :  */
     554                 :            : #define DEVDIR (NAM$M_EXP_DEV | NAM$M_EXP_DIR)
     555                 :            : 
     556                 :            : FILE_LOCAL int
     557                 :            : vmsparse(source, defstring, result)
     558                 :            : char            *source;
     559                 :            : char            *defstring;     /* non-NULL -> default string.          */
     560                 :            : char            *result;        /* Size is at least NAM$C_MAXRSS + 1    */
     561                 :            : /*
     562                 :            :  * Parse the source string, applying the default (properly, using
     563                 :            :  * the system parse routine), storing it in result.
     564                 :            :  * TRUE if it parsed, FALSE on error.
     565                 :            :  *
     566                 :            :  * If defstring is NULL, there are no defaults and result gets
     567                 :            :  * (just) the node::[directory] part of the string (possibly "")
     568                 :            :  */
     569                 :            : {
     570                 :            :         struct FAB      fab = cc$rms_fab;       /* File access block    */
     571                 :            :         struct NAM      nam = cc$rms_nam;       /* File name block      */
     572                 :            :         char            fullname[NAM$C_MAXRSS + 1];
     573                 :            :         register char   *rp;                    /* Result pointer       */
     574                 :            : 
     575                 :            :         fab.fab$l_nam = &nam;                   /* fab -> nam           */
     576                 :            :         fab.fab$l_fna = source;                 /* Source filename      */
     577                 :            :         fab.fab$b_fns = strlen(source);         /* Size of source       */
     578                 :            :         fab.fab$l_dna = defstring;              /* Default string       */
     579                 :            :         if (defstring != NULLST)
     580                 :            :             fab.fab$b_dns = strlen(defstring);  /* Size of default      */
     581                 :            :         nam.nam$l_esa = fullname;               /* Expanded filename    */
     582                 :            :         nam.nam$b_ess = NAM$C_MAXRSS;           /* Expanded name size   */
     583                 :            :         if (sys$parse(&fab) == RMS$_NORMAL) {   /* Parse away           */
     584                 :            :             fullname[nam.nam$b_esl] = EOS;      /* Terminate string     */
     585                 :            :             result[0] = EOS;                    /* Just in case         */
     586                 :            :             rp = &result[0];
     587                 :            :             /*
     588                 :            :              * Remove stuff added implicitly, accepting node names and
     589                 :            :              * dev:[directory] strings (but not process-permanent files).
     590                 :            :              */
     591                 :            :             if ((nam.nam$l_fnb & NAM$M_PPF) == 0) {
     592                 :            :                 if ((nam.nam$l_fnb & NAM$M_NODE) != 0) {
     593                 :            :                     strncpy(result, nam.nam$l_node, nam.nam$b_node);
     594                 :            :                     rp += nam.nam$b_node;
     595                 :            :                     *rp = EOS;
     596                 :            :                 }
     597                 :            :                 if ((nam.nam$l_fnb & DEVDIR) == DEVDIR) {
     598                 :            :                     strncpy(rp, nam.nam$l_dev, nam.nam$b_dev + nam.nam$b_dir);
     599                 :            :                     rp += nam.nam$b_dev + nam.nam$b_dir;
     600                 :            :                     *rp = EOS;
     601                 :            :                 }
     602                 :            :             }
     603                 :            :             if (defstring != NULLST) {
     604                 :            :                 strncpy(rp, nam.nam$l_name, nam.nam$b_name + nam.nam$b_type);
     605                 :            :                 rp += nam.nam$b_name + nam.nam$b_type;
     606                 :            :                 *rp = EOS;
     607                 :            :                 if ((nam.nam$l_fnb & NAM$M_EXP_VER) != 0) {
     608                 :            :                     strncpy(rp, nam.nam$l_ver, nam.nam$b_ver);
     609                 :            :                     rp[nam.nam$b_ver] = EOS;
     610                 :            :                 }
     611                 :            :             }
     612                 :            :             return (TRUE);
     613                 :            :         }
     614                 :            :         return (FALSE);
     615                 :            : }
     616                 :            : #endif
     617                 :            : 
     618                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10