| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: parse.c,v 1.346 2020/10/03 21:23:42 rillig Exp $ */ | | 1 | /* $NetBSD: parse.c,v 1.347 2020/10/03 21:43:41 rillig Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1988, 1989, 1990, 1993 | | 4 | * Copyright (c) 1988, 1989, 1990, 1993 |
5 | * The Regents of the University of California. All rights reserved. | | 5 | * The Regents of the University of California. All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to Berkeley by | | 7 | * This code is derived from software contributed to Berkeley by |
8 | * Adam de Boor. | | 8 | * Adam de Boor. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -122,27 +122,27 @@ | | | @@ -122,27 +122,27 @@ |
122 | #ifndef MAP_FILE | | 122 | #ifndef MAP_FILE |
123 | #define MAP_FILE 0 | | 123 | #define MAP_FILE 0 |
124 | #endif | | 124 | #endif |
125 | #ifndef MAP_COPY | | 125 | #ifndef MAP_COPY |
126 | #define MAP_COPY MAP_PRIVATE | | 126 | #define MAP_COPY MAP_PRIVATE |
127 | #endif | | 127 | #endif |
128 | | | 128 | |
129 | #include "make.h" | | 129 | #include "make.h" |
130 | #include "dir.h" | | 130 | #include "dir.h" |
131 | #include "job.h" | | 131 | #include "job.h" |
132 | #include "pathnames.h" | | 132 | #include "pathnames.h" |
133 | | | 133 | |
134 | /* "@(#)parse.c 8.3 (Berkeley) 3/19/94" */ | | 134 | /* "@(#)parse.c 8.3 (Berkeley) 3/19/94" */ |
135 | MAKE_RCSID("$NetBSD: parse.c,v 1.346 2020/10/03 21:23:42 rillig Exp $"); | | 135 | MAKE_RCSID("$NetBSD: parse.c,v 1.347 2020/10/03 21:43:41 rillig Exp $"); |
136 | | | 136 | |
137 | /* types and constants */ | | 137 | /* types and constants */ |
138 | | | 138 | |
139 | /* | | 139 | /* |
140 | * Structure for a file being read ("included file") | | 140 | * Structure for a file being read ("included file") |
141 | */ | | 141 | */ |
142 | typedef struct IFile { | | 142 | typedef struct IFile { |
143 | char *fname; /* name of file */ | | 143 | char *fname; /* name of file */ |
144 | Boolean fromForLoop; /* simulated .include by the .for loop */ | | 144 | Boolean fromForLoop; /* simulated .include by the .for loop */ |
145 | int lineno; /* current line number in file */ | | 145 | int lineno; /* current line number in file */ |
146 | int first_lineno; /* line number of start of text */ | | 146 | int first_lineno; /* line number of start of text */ |
147 | int cond_depth; /* 'if' nesting when file opened */ | | 147 | int cond_depth; /* 'if' nesting when file opened */ |
148 | Boolean depending; /* state of doing_depend on EOF */ | | 148 | Boolean depending; /* state of doing_depend on EOF */ |
| @@ -2510,27 +2510,27 @@ ParseEOF(void) | | | @@ -2510,27 +2510,27 @@ ParseEOF(void) |
2510 | | | 2510 | |
2511 | curFile = Stack_Pop(&includes); | | 2511 | curFile = Stack_Pop(&includes); |
2512 | DEBUG2(PARSE, "ParseEOF: returning to file %s, line %d\n", | | 2512 | DEBUG2(PARSE, "ParseEOF: returning to file %s, line %d\n", |
2513 | curFile->fname, curFile->lineno); | | 2513 | curFile->fname, curFile->lineno); |
2514 | | | 2514 | |
2515 | ParseSetParseFile(curFile->fname); | | 2515 | ParseSetParseFile(curFile->fname); |
2516 | return CONTINUE; | | 2516 | return CONTINUE; |
2517 | } | | 2517 | } |
2518 | | | 2518 | |
2519 | #define PARSE_RAW 1 | | 2519 | #define PARSE_RAW 1 |
2520 | #define PARSE_SKIP 2 | | 2520 | #define PARSE_SKIP 2 |
2521 | | | 2521 | |
2522 | static char * | | 2522 | static char * |
2523 | ParseGetLine(int flags, int *length) | | 2523 | ParseGetLine(int flags) |
2524 | { | | 2524 | { |
2525 | IFile *cf = curFile; | | 2525 | IFile *cf = curFile; |
2526 | char *ptr; | | 2526 | char *ptr; |
2527 | char ch; | | 2527 | char ch; |
2528 | char *line; | | 2528 | char *line; |
2529 | char *line_end; | | 2529 | char *line_end; |
2530 | char *escaped; | | 2530 | char *escaped; |
2531 | char *comment; | | 2531 | char *comment; |
2532 | char *tp; | | 2532 | char *tp; |
2533 | | | 2533 | |
2534 | /* Loop through blank lines and comment lines */ | | 2534 | /* Loop through blank lines and comment lines */ |
2535 | for (;;) { | | 2535 | for (;;) { |
2536 | cf->lineno++; | | 2536 | cf->lineno++; |
| @@ -2602,50 +2602,47 @@ ParseGetLine(int flags, int *length) | | | @@ -2602,50 +2602,47 @@ ParseGetLine(int flags, int *length) |
2602 | if (line_end == line || comment == line) { | | 2602 | if (line_end == line || comment == line) { |
2603 | if (ch == 0) | | 2603 | if (ch == 0) |
2604 | /* At end of file */ | | 2604 | /* At end of file */ |
2605 | return NULL; | | 2605 | return NULL; |
2606 | /* Parse another line */ | | 2606 | /* Parse another line */ |
2607 | continue; | | 2607 | continue; |
2608 | } | | 2608 | } |
2609 | | | 2609 | |
2610 | /* We now have a line of data */ | | 2610 | /* We now have a line of data */ |
2611 | *line_end = 0; | | 2611 | *line_end = 0; |
2612 | | | 2612 | |
2613 | if (flags & PARSE_RAW) { | | 2613 | if (flags & PARSE_RAW) { |
2614 | /* Leave '\' (etc) in line buffer (eg 'for' lines) */ | | 2614 | /* Leave '\' (etc) in line buffer (eg 'for' lines) */ |
2615 | *length = line_end - line; | | | |
2616 | return line; | | 2615 | return line; |
2617 | } | | 2616 | } |
2618 | | | 2617 | |
2619 | if (flags & PARSE_SKIP) { | | 2618 | if (flags & PARSE_SKIP) { |
2620 | /* Completely ignore non-directives */ | | 2619 | /* Completely ignore non-directives */ |
2621 | if (line[0] != '.') | | 2620 | if (line[0] != '.') |
2622 | continue; | | 2621 | continue; |
2623 | /* We could do more of the .else/.elif/.endif checks here */ | | 2622 | /* We could do more of the .else/.elif/.endif checks here */ |
2624 | } | | 2623 | } |
2625 | break; | | 2624 | break; |
2626 | } | | 2625 | } |
2627 | | | 2626 | |
2628 | /* Brutally ignore anything after a non-escaped '#' in non-commands */ | | 2627 | /* Brutally ignore anything after a non-escaped '#' in non-commands */ |
2629 | if (comment != NULL && line[0] != '\t') { | | 2628 | if (comment != NULL && line[0] != '\t') { |
2630 | line_end = comment; | | 2629 | line_end = comment; |
2631 | *line_end = 0; | | 2630 | *line_end = 0; |
2632 | } | | 2631 | } |
2633 | | | 2632 | |
2634 | /* If we didn't see a '\\' then the in-situ data is fine */ | | 2633 | /* If we didn't see a '\\' then the in-situ data is fine */ |
2635 | if (escaped == NULL) { | | 2634 | if (escaped == NULL) |
2636 | *length = line_end - line; | | | |
2637 | return line; | | 2635 | return line; |
2638 | } | | | |
2639 | | | 2636 | |
2640 | /* Remove escapes from '\n' and '#' */ | | 2637 | /* Remove escapes from '\n' and '#' */ |
2641 | tp = ptr = escaped; | | 2638 | tp = ptr = escaped; |
2642 | escaped = line; | | 2639 | escaped = line; |
2643 | for (; ; *tp++ = ch) { | | 2640 | for (; ; *tp++ = ch) { |
2644 | ch = *ptr++; | | 2641 | ch = *ptr++; |
2645 | if (ch != '\\') { | | 2642 | if (ch != '\\') { |
2646 | if (ch == 0) | | 2643 | if (ch == 0) |
2647 | break; | | 2644 | break; |
2648 | continue; | | 2645 | continue; |
2649 | } | | 2646 | } |
2650 | | | 2647 | |
2651 | ch = *ptr++; | | 2648 | ch = *ptr++; |
| @@ -2668,83 +2665,81 @@ ParseGetLine(int flags, int *length) | | | @@ -2668,83 +2665,81 @@ ParseGetLine(int flags, int *length) |
2668 | } | | 2665 | } |
2669 | | | 2666 | |
2670 | /* Escaped '\n' replace following whitespace with a single ' ' */ | | 2667 | /* Escaped '\n' replace following whitespace with a single ' ' */ |
2671 | while (ptr[0] == ' ' || ptr[0] == '\t') | | 2668 | while (ptr[0] == ' ' || ptr[0] == '\t') |
2672 | ptr++; | | 2669 | ptr++; |
2673 | ch = ' '; | | 2670 | ch = ' '; |
2674 | } | | 2671 | } |
2675 | | | 2672 | |
2676 | /* Delete any trailing spaces - eg from empty continuations */ | | 2673 | /* Delete any trailing spaces - eg from empty continuations */ |
2677 | while (tp > escaped && ch_isspace(tp[-1])) | | 2674 | while (tp > escaped && ch_isspace(tp[-1])) |
2678 | tp--; | | 2675 | tp--; |
2679 | | | 2676 | |
2680 | *tp = 0; | | 2677 | *tp = 0; |
2681 | *length = tp - line; | | | |
2682 | return line; | | 2678 | return line; |
2683 | } | | 2679 | } |
2684 | | | 2680 | |
2685 | /* Read an entire line from the input file. Called only by Parse_File. | | 2681 | /* Read an entire line from the input file. Called only by Parse_File. |
2686 | * | | 2682 | * |
2687 | * Results: | | 2683 | * Results: |
2688 | * A line without its newline. | | 2684 | * A line without its newline. |
2689 | * | | 2685 | * |
2690 | * Side Effects: | | 2686 | * Side Effects: |
2691 | * Only those associated with reading a character | | 2687 | * Only those associated with reading a character |
2692 | */ | | 2688 | */ |
2693 | static char * | | 2689 | static char * |
2694 | ParseReadLine(void) | | 2690 | ParseReadLine(void) |
2695 | { | | 2691 | { |
2696 | char *line; /* Result */ | | 2692 | char *line; /* Result */ |
2697 | int lineLength; /* Length of result */ | | | |
2698 | int lineno; /* Saved line # */ | | 2693 | int lineno; /* Saved line # */ |
2699 | int rval; | | 2694 | int rval; |
2700 | | | 2695 | |
2701 | for (;;) { | | 2696 | for (;;) { |
2702 | line = ParseGetLine(0, &lineLength); | | 2697 | line = ParseGetLine(0); |
2703 | if (line == NULL) | | 2698 | if (line == NULL) |
2704 | return NULL; | | 2699 | return NULL; |
2705 | | | 2700 | |
2706 | if (line[0] != '.') | | 2701 | if (line[0] != '.') |
2707 | return line; | | 2702 | return line; |
2708 | | | 2703 | |
2709 | /* | | 2704 | /* |
2710 | * The line might be a conditional. Ask the conditional module | | 2705 | * The line might be a conditional. Ask the conditional module |
2711 | * about it and act accordingly | | 2706 | * about it and act accordingly |
2712 | */ | | 2707 | */ |
2713 | switch (Cond_EvalLine(line)) { | | 2708 | switch (Cond_EvalLine(line)) { |
2714 | case COND_SKIP: | | 2709 | case COND_SKIP: |
2715 | /* Skip to next conditional that evaluates to COND_PARSE. */ | | 2710 | /* Skip to next conditional that evaluates to COND_PARSE. */ |
2716 | do { | | 2711 | do { |
2717 | line = ParseGetLine(PARSE_SKIP, &lineLength); | | 2712 | line = ParseGetLine(PARSE_SKIP); |
2718 | } while (line && Cond_EvalLine(line) != COND_PARSE); | | 2713 | } while (line && Cond_EvalLine(line) != COND_PARSE); |
2719 | if (line == NULL) | | 2714 | if (line == NULL) |
2720 | break; | | 2715 | break; |
2721 | continue; | | 2716 | continue; |
2722 | case COND_PARSE: | | 2717 | case COND_PARSE: |
2723 | continue; | | 2718 | continue; |
2724 | case COND_INVALID: /* Not a conditional line */ | | 2719 | case COND_INVALID: /* Not a conditional line */ |
2725 | /* Check for .for loops */ | | 2720 | /* Check for .for loops */ |
2726 | rval = For_Eval(line); | | 2721 | rval = For_Eval(line); |
2727 | if (rval == 0) | | 2722 | if (rval == 0) |
2728 | /* Not a .for line */ | | 2723 | /* Not a .for line */ |
2729 | break; | | 2724 | break; |
2730 | if (rval < 0) | | 2725 | if (rval < 0) |
2731 | /* Syntax error - error printed, ignore line */ | | 2726 | /* Syntax error - error printed, ignore line */ |
2732 | continue; | | 2727 | continue; |
2733 | /* Start of a .for loop */ | | 2728 | /* Start of a .for loop */ |
2734 | lineno = curFile->lineno; | | 2729 | lineno = curFile->lineno; |
2735 | /* Accumulate loop lines until matching .endfor */ | | 2730 | /* Accumulate loop lines until matching .endfor */ |
2736 | do { | | 2731 | do { |
2737 | line = ParseGetLine(PARSE_RAW, &lineLength); | | 2732 | line = ParseGetLine(PARSE_RAW); |
2738 | if (line == NULL) { | | 2733 | if (line == NULL) { |
2739 | Parse_Error(PARSE_FATAL, | | 2734 | Parse_Error(PARSE_FATAL, |
2740 | "Unexpected end of file in for loop."); | | 2735 | "Unexpected end of file in for loop."); |
2741 | break; | | 2736 | break; |
2742 | } | | 2737 | } |
2743 | } while (For_Accum(line)); | | 2738 | } while (For_Accum(line)); |
2744 | /* Stash each iteration as a new 'input file' */ | | 2739 | /* Stash each iteration as a new 'input file' */ |
2745 | For_Run(lineno); | | 2740 | For_Run(lineno); |
2746 | /* Read next line from for-loop buffer */ | | 2741 | /* Read next line from for-loop buffer */ |
2747 | continue; | | 2742 | continue; |
2748 | } | | 2743 | } |
2749 | return line; | | 2744 | return line; |
2750 | } | | 2745 | } |