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

Generated by: LCOV version 1.10