1 /* CPP Library - directive only preprocessing for distributed compilation.
2 Copyright (C) 2007, 2009
3 Free Software Foundation, Inc.
4 Contributed by Ollie Wild <aaw@google.com>.
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 3, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
25 /* DO (Directive only) flags. */
26 #define DO_BOL (1 << 0) /* At the beginning of a logical line. */
27 #define DO_STRING (1 << 1) /* In a string constant. */
28 #define DO_CHAR (1 << 2) /* In a character constant. */
29 #define DO_BLOCK_COMMENT (1 << 3) /* In a block comment. */
30 #define DO_LINE_COMMENT (1 << 4) /* In a single line "//-style" comment. */
32 #define DO_LINE_SPECIAL (DO_STRING | DO_CHAR | DO_LINE_COMMENT)
33 #define DO_SPECIAL (DO_LINE_SPECIAL | DO_BLOCK_COMMENT)
35 /* Writes out the preprocessed file, handling spacing and paste
38 _cpp_preprocess_dir_only (cpp_reader
*pfile
,
39 const struct _cpp_dir_only_callbacks
*cb
)
41 struct cpp_buffer
*buffer
;
42 const unsigned char *cur
, *base
, *next_line
, *rlimit
;
50 /* Buffer initialization ala _cpp_clean_line(). */
51 buffer
= pfile
->buffer
;
52 buffer
->cur_note
= buffer
->notes_used
= 0;
53 buffer
->cur
= buffer
->line_base
= buffer
->next_line
;
54 buffer
->need_line
= false;
56 /* This isn't really needed. It prevents a compiler warning, though. */
57 loc
= pfile
->line_table
->highest_line
;
59 /* Scan initialization. */
60 next_line
= cur
= base
= buffer
->cur
;
61 rlimit
= buffer
->rlimit
;
66 for (last_c
= '\n', c
= *cur
; cur
< rlimit
; last_c
= c
, c
= *++cur
, ++col
)
68 /* Skip over escaped newlines. */
69 if (__builtin_expect (c
== '\\', false))
71 const unsigned char *tmp
= cur
+ 1;
73 while (is_nvspace (*tmp
) && tmp
< rlimit
)
77 if (*tmp
== '\n' && tmp
< rlimit
)
79 CPP_INCREMENT_LINE (pfile
, 0);
88 if (__builtin_expect (last_c
== '#', false) && !(flags
& DO_SPECIAL
))
90 if (c
!= '#' && (flags
& DO_BOL
))
92 struct line_maps
*line_table
;
94 if (!pfile
->state
.skipping
&& next_line
!= base
)
95 cb
->print_lines (lines
, base
, next_line
- base
);
97 /* Prep things for directive handling. */
98 buffer
->next_line
= cur
;
99 buffer
->need_line
= true;
100 _cpp_get_fresh_line (pfile
);
102 /* Ensure proper column numbering for generated error messages. */
103 buffer
->line_base
-= col
- 1;
105 _cpp_handle_directive (pfile
, 0 /* ignore indented */);
107 /* Sanitize the line settings. Duplicate #include's can mess
109 line_table
= pfile
->line_table
;
110 line_table
->highest_location
= line_table
->highest_line
;
112 /* The if block prevents us from outputing line information when
113 the file ends with a directive and no newline. Note that we
114 must use pfile->buffer, not buffer. */
115 if (pfile
->buffer
->next_line
< pfile
->buffer
->rlimit
)
116 cb
->maybe_print_line (pfile
->line_table
->highest_line
);
122 pfile
->mi_valid
= false;
124 else if (__builtin_expect (last_c
== '/', false) \
125 && !(flags
& DO_SPECIAL
) && c
!= '*' && c
!= '/')
127 /* If a previous slash is not starting a block comment, clear the
130 pfile
->mi_valid
= false;
136 if ((flags
& DO_BLOCK_COMMENT
) && last_c
== '*')
138 flags
&= ~DO_BLOCK_COMMENT
;
141 else if (!(flags
& DO_SPECIAL
) && last_c
== '/')
142 flags
|= DO_LINE_COMMENT
;
143 else if (!(flags
& DO_SPECIAL
))
144 /* Mark the position for possible error reporting. */
145 LINEMAP_POSITION_FOR_COLUMN (loc
, pfile
->line_table
, col
);
150 if (!(flags
& DO_SPECIAL
))
153 flags
|= DO_BLOCK_COMMENT
;
157 pfile
->mi_valid
= false;
166 unsigned state
= (c
== '"') ? DO_STRING
: DO_CHAR
;
168 if (!(flags
& DO_SPECIAL
))
172 pfile
->mi_valid
= false;
174 else if ((flags
& state
) && last_c
!= '\\')
182 if ((flags
& (DO_STRING
| DO_CHAR
)) && last_c
== '\\')
185 if (!(flags
& DO_SPECIAL
))
188 pfile
->mi_valid
= false;
195 CPP_INCREMENT_LINE (pfile
, 0);
198 flags
&= ~DO_LINE_SPECIAL
;
199 if (!(flags
& DO_SPECIAL
))
205 /* Don't update DO_BOL yet. */
208 case ' ': case '\t': case '\f': case '\v': case '\0':
212 if (!(flags
& DO_SPECIAL
))
215 pfile
->mi_valid
= false;
221 if (flags
& DO_BLOCK_COMMENT
)
222 cpp_error_with_line (pfile
, CPP_DL_ERROR
, loc
, 0, "unterminated comment");
224 if (!pfile
->state
.skipping
&& cur
!= base
)
226 /* If the file was not newline terminated, add rlimit, which is
227 guaranteed to point to a newline, to the end of our range. */
231 CPP_INCREMENT_LINE (pfile
, 0);
235 cb
->print_lines (lines
, base
, cur
- base
);
238 _cpp_pop_buffer (pfile
);