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>. 5 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 9 later version. 10 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. 15 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/>. */ 19 20 #include "config.h" 21 #include "system.h" 22 #include "cpplib.h" 23 #include "internal.h" 24 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. */ 31 32 #define DO_LINE_SPECIAL (DO_STRING | DO_CHAR | DO_LINE_COMMENT) 33 #define DO_SPECIAL (DO_LINE_SPECIAL | DO_BLOCK_COMMENT) 34 35 /* Writes out the preprocessed file, handling spacing and paste 36 avoidance issues. */ 37 void 38 _cpp_preprocess_dir_only (cpp_reader *pfile, 39 const struct _cpp_dir_only_callbacks *cb) 40 { 41 struct cpp_buffer *buffer; 42 const unsigned char *cur, *base, *next_line, *rlimit; 43 cppchar_t c, last_c; 44 unsigned flags; 45 linenum_type lines; 46 int col; 47 source_location loc; 48 49 restart: 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; 55 56 /* This isn't really needed. It prevents a compiler warning, though. */ 57 loc = pfile->line_table->highest_line; 58 59 /* Scan initialization. */ 60 next_line = cur = base = buffer->cur; 61 rlimit = buffer->rlimit; 62 flags = DO_BOL; 63 lines = 0; 64 col = 1; 65 66 for (last_c = '\n', c = *cur; cur < rlimit; last_c = c, c = *++cur, ++col) 67 { 68 /* Skip over escaped newlines. */ 69 if (__builtin_expect (c == '\\', false)) 70 { 71 const unsigned char *tmp = cur + 1; 72 73 while (is_nvspace (*tmp) && tmp < rlimit) 74 tmp++; 75 if (*tmp == '\r') 76 tmp++; 77 if (*tmp == '\n' && tmp < rlimit) 78 { 79 CPP_INCREMENT_LINE (pfile, 0); 80 lines++; 81 col = 0; 82 cur = tmp; 83 c = last_c; 84 continue; 85 } 86 } 87 88 if (__builtin_expect (last_c == '#', false) && !(flags & DO_SPECIAL)) 89 { 90 if (c != '#' && (flags & DO_BOL)) 91 { 92 struct line_maps *line_table; 93 94 if (!pfile->state.skipping && next_line != base) 95 cb->print_lines (lines, base, next_line - base); 96 97 /* Prep things for directive handling. */ 98 buffer->next_line = cur; 99 buffer->need_line = true; 100 _cpp_get_fresh_line (pfile); 101 102 /* Ensure proper column numbering for generated error messages. */ 103 buffer->line_base -= col - 1; 104 105 _cpp_handle_directive (pfile, 0 /* ignore indented */); 106 107 /* Sanitize the line settings. Duplicate #include's can mess 108 things up. */ 109 line_table = pfile->line_table; 110 line_table->highest_location = line_table->highest_line; 111 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); 117 118 goto restart; 119 } 120 121 flags &= ~DO_BOL; 122 pfile->mi_valid = false; 123 } 124 else if (__builtin_expect (last_c == '/', false) \ 125 && !(flags & DO_SPECIAL) && c != '*' && c != '/') 126 { 127 /* If a previous slash is not starting a block comment, clear the 128 DO_BOL flag. */ 129 flags &= ~DO_BOL; 130 pfile->mi_valid = false; 131 } 132 133 switch (c) 134 { 135 case '/': 136 if ((flags & DO_BLOCK_COMMENT) && last_c == '*') 137 { 138 flags &= ~DO_BLOCK_COMMENT; 139 c = 0; 140 } 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 loc = linemap_position_for_column (pfile->line_table, col); 146 147 break; 148 149 case '*': 150 if (!(flags & DO_SPECIAL)) 151 { 152 if (last_c == '/') 153 flags |= DO_BLOCK_COMMENT; 154 else 155 { 156 flags &= ~DO_BOL; 157 pfile->mi_valid = false; 158 } 159 } 160 161 break; 162 163 case '\'': 164 case '"': 165 { 166 unsigned state = (c == '"') ? DO_STRING : DO_CHAR; 167 168 if (!(flags & DO_SPECIAL)) 169 { 170 flags |= state; 171 flags &= ~DO_BOL; 172 pfile->mi_valid = false; 173 } 174 else if ((flags & state) && last_c != '\\') 175 flags &= ~state; 176 177 break; 178 } 179 180 case '\\': 181 { 182 if ((flags & (DO_STRING | DO_CHAR)) && last_c == '\\') 183 c = 0; 184 185 if (!(flags & DO_SPECIAL)) 186 { 187 flags &= ~DO_BOL; 188 pfile->mi_valid = false; 189 } 190 191 break; 192 } 193 194 case '\n': 195 CPP_INCREMENT_LINE (pfile, 0); 196 lines++; 197 col = 0; 198 flags &= ~DO_LINE_SPECIAL; 199 if (!(flags & DO_SPECIAL)) 200 flags |= DO_BOL; 201 break; 202 203 case '#': 204 next_line = cur; 205 /* Don't update DO_BOL yet. */ 206 break; 207 208 case ' ': case '\t': case '\f': case '\v': case '\0': 209 break; 210 211 default: 212 if (!(flags & DO_SPECIAL)) 213 { 214 flags &= ~DO_BOL; 215 pfile->mi_valid = false; 216 } 217 break; 218 } 219 } 220 221 if (flags & DO_BLOCK_COMMENT) 222 cpp_error_with_line (pfile, CPP_DL_ERROR, loc, 0, "unterminated comment"); 223 224 if (!pfile->state.skipping && cur != base) 225 { 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. */ 228 if (cur[-1] != '\n') 229 { 230 cur++; 231 CPP_INCREMENT_LINE (pfile, 0); 232 lines++; 233 } 234 235 cb->print_lines (lines, base, cur - base); 236 } 237 238 _cpp_pop_buffer (pfile); 239 if (pfile->buffer) 240 goto restart; 241 } 242