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: */
|