1 /* CPP Library - directive only preprocessing for distributed compilation.
2 Copyright (C) 2007-2019 Free Software Foundation, Inc.
3 Contributed by Ollie Wild <aaw@google.com>.
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of the GNU General Public License as published by the
7 Free Software Foundation; either version 3, or (at your option) any
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; see the file COPYING3. If not see
17 <http://www.gnu.org/licenses/>. */
24 /* DO (Directive only) flags. */
25 #define DO_BOL (1 << 0) /* At the beginning of a logical line. */
26 #define DO_STRING (1 << 1) /* In a string constant. */
27 #define DO_CHAR (1 << 2) /* In a character constant. */
28 #define DO_BLOCK_COMMENT (1 << 3) /* In a block comment. */
29 #define DO_LINE_COMMENT (1 << 4) /* In a single line "//-style" comment. */
31 #define DO_LINE_SPECIAL (DO_STRING | DO_CHAR | DO_LINE_COMMENT)
32 #define DO_SPECIAL (DO_LINE_SPECIAL | DO_BLOCK_COMMENT)
34 /* Writes out the preprocessed file, handling spacing and paste
37 _cpp_preprocess_dir_only (cpp_reader
*pfile
,
38 const struct _cpp_dir_only_callbacks
*cb
)
40 struct cpp_buffer
*buffer
;
41 const unsigned char *cur
, *base
, *next_line
, *rlimit
;
49 /* Buffer initialization ala _cpp_clean_line(). */
50 buffer
= pfile
->buffer
;
51 buffer
->cur_note
= buffer
->notes_used
= 0;
52 buffer
->cur
= buffer
->line_base
= buffer
->next_line
;
53 buffer
->need_line
= false;
55 /* This isn't really needed. It prevents a compiler warning, though. */
56 loc
= pfile
->line_table
->highest_line
;
58 /* Scan initialization. */
59 next_line
= cur
= base
= buffer
->cur
;
60 rlimit
= buffer
->rlimit
;
65 for (last_c
= '\n', c
= *cur
; cur
< rlimit
; last_c
= c
, c
= *++cur
, ++col
)
67 /* Skip over escaped newlines. */
68 if (__builtin_expect (c
== '\\', false))
70 const unsigned char *tmp
= cur
+ 1;
72 while (is_nvspace (*tmp
) && tmp
< rlimit
)
76 if (*tmp
== '\n' && tmp
< rlimit
)
78 CPP_INCREMENT_LINE (pfile
, 0);
87 if (__builtin_expect (last_c
== '#', false) && !(flags
& DO_SPECIAL
))
89 if (c
!= '#' && (flags
& DO_BOL
))
91 class line_maps
*line_table
;
93 if (!pfile
->state
.skipping
&& next_line
!= base
)
94 cb
->print_lines (lines
, base
, next_line
- base
);
96 /* Prep things for directive handling. */
97 buffer
->next_line
= cur
;
98 buffer
->need_line
= true;
99 _cpp_get_fresh_line (pfile
);
101 /* Ensure proper column numbering for generated error messages. */
102 buffer
->line_base
-= col
- 1;
104 _cpp_handle_directive (pfile
, false /* ignore indented */);
106 /* Sanitize the line settings. Duplicate #include's can mess
108 line_table
= pfile
->line_table
;
109 line_table
->highest_location
= line_table
->highest_line
;
111 /* The if block prevents us from outputing line information when
112 the file ends with a directive and no newline. Note that we
113 must use pfile->buffer, not buffer. */
114 if (pfile
->buffer
->next_line
< pfile
->buffer
->rlimit
)
115 cb
->maybe_print_line (pfile
->line_table
->highest_line
);
121 pfile
->mi_valid
= false;
123 else if (__builtin_expect (last_c
== '/', false) \
124 && !(flags
& DO_SPECIAL
) && c
!= '*' && c
!= '/')
126 /* If a previous slash is not starting a block comment, clear the
129 pfile
->mi_valid
= false;
135 if ((flags
& DO_BLOCK_COMMENT
) && last_c
== '*')
137 flags
&= ~DO_BLOCK_COMMENT
;
140 else if (!(flags
& DO_SPECIAL
) && last_c
== '/')
141 flags
|= DO_LINE_COMMENT
;
142 else if (!(flags
& DO_SPECIAL
))
143 /* Mark the position for possible error reporting. */
144 loc
= linemap_position_for_column (pfile
->line_table
, col
);
149 if (!(flags
& DO_SPECIAL
))
152 flags
|= DO_BLOCK_COMMENT
;
156 pfile
->mi_valid
= false;
165 unsigned state
= (c
== '"') ? DO_STRING
: DO_CHAR
;
167 if (!(flags
& DO_SPECIAL
))
171 pfile
->mi_valid
= false;
173 else if ((flags
& state
) && last_c
!= '\\')
181 if ((flags
& (DO_STRING
| DO_CHAR
)) && last_c
== '\\')
184 if (!(flags
& DO_SPECIAL
))
187 pfile
->mi_valid
= false;
194 CPP_INCREMENT_LINE (pfile
, 0);
197 flags
&= ~DO_LINE_SPECIAL
;
198 if (!(flags
& DO_SPECIAL
))
204 /* Don't update DO_BOL yet. */
207 case ' ': case '\t': case '\f': case '\v': case '\0':
211 if (!(flags
& DO_SPECIAL
))
214 pfile
->mi_valid
= false;
220 if (flags
& DO_BLOCK_COMMENT
)
221 cpp_error_with_line (pfile
, CPP_DL_ERROR
, loc
, 0, "unterminated comment");
223 if (!pfile
->state
.skipping
&& cur
!= base
)
225 /* If the file was not newline terminated, add rlimit, which is
226 guaranteed to point to a newline, to the end of our range. */
230 CPP_INCREMENT_LINE (pfile
, 0);
234 cb
->print_lines (lines
, base
, cur
- base
);
237 _cpp_pop_buffer (pfile
);