1139804Simp/* CPP Library - directive only preprocessing for distributed compilation. 21541Srgrimes Copyright (C) 2007 31541Srgrimes Free Software Foundation, Inc. 41541Srgrimes Contributed by Ollie Wild <aaw@google.com>. 51541Srgrimes 61541SrgrimesThis program is free software; you can redistribute it and/or modify it 71541Srgrimesunder the terms of the GNU General Public License as published by the 81541SrgrimesFree Software Foundation; either version 2, or (at your option) any 91541Srgrimeslater version. 101541Srgrimes 111541SrgrimesThis program is distributed in the hope that it will be useful, 121541Srgrimesbut WITHOUT ANY WARRANTY; without even the implied warranty of 131541SrgrimesMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 141541SrgrimesGNU General Public License for more details. 151541Srgrimes 161541SrgrimesYou should have received a copy of the GNU General Public License 171541Srgrimesalong with this program; if not, write to the Free Software 181541SrgrimesFoundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 191541Srgrimes 201541Srgrimes#include "config.h" 211541Srgrimes#include "system.h" 221541Srgrimes#include "cpplib.h" 231541Srgrimes#include "internal.h" 241541Srgrimes 251541Srgrimes/* DO (Directive only) flags. */ 261541Srgrimes#define DO_BOL (1 << 0) /* At the beginning of a logical line. */ 271541Srgrimes#define DO_STRING (1 << 1) /* In a string constant. */ 281541Srgrimes#define DO_CHAR (1 << 2) /* In a character constant. */ 291541Srgrimes#define DO_BLOCK_COMMENT (1 << 3) /* In a block comment. */ 301541Srgrimes#define DO_LINE_COMMENT (1 << 4) /* In a single line "//-style" comment. */ 311541Srgrimes 321541Srgrimes#define DO_LINE_SPECIAL (DO_STRING | DO_CHAR | DO_LINE_COMMENT) 331541Srgrimes#define DO_SPECIAL (DO_LINE_SPECIAL | DO_BLOCK_COMMENT) 341541Srgrimes 351541Srgrimes/* Writes out the preprocessed file, handling spacing and paste 361541Srgrimes avoidance issues. */ 37116182Sobrienvoid 38116182Sobrien_cpp_preprocess_dir_only (cpp_reader *pfile, 39116182Sobrien const struct _cpp_dir_only_callbacks *cb) 4013203Swollman{ 41101127Srwatson struct cpp_buffer *buffer; 4213203Swollman const unsigned char *cur, *base, *next_line, *rlimit; 431541Srgrimes cppchar_t c, last_c; 442112Swollman unsigned flags; 4569664Speter int lines, col; 46177785Skib source_location loc; 4776166Smarkm 4889316Salfred restart: 491541Srgrimes /* Buffer initialization ala _cpp_clean_line(). */ 501541Srgrimes buffer = pfile->buffer; 511541Srgrimes buffer->cur_note = buffer->notes_used = 0; 521541Srgrimes buffer->cur = buffer->line_base = buffer->next_line; 531541Srgrimes buffer->need_line = false; 54141471Sjhb 55144613Sjeff /* This isn't really needed. It prevents a compiler warning, though. */ 561541Srgrimes loc = pfile->line_table->highest_line; 571541Srgrimes 581541Srgrimes /* Scan initialization. */ 591541Srgrimes next_line = cur = base = buffer->cur; 60155334Srwatson rlimit = buffer->rlimit; 61163606Srwatson flags = DO_BOL; 62155334Srwatson lines = 0; 6392751Sjeff col = 1; 6432011Sbde 65155168Sjeff for (last_c = '\n', c = *cur; cur < rlimit; last_c = c, c = *++cur, ++col) 66138345Sphk { 67138345Sphk /* Skip over escaped newlines. */ 681541Srgrimes if (__builtin_expect (c == '\\', false)) 6969664Speter { 7069664Speter const unsigned char *tmp = cur + 1; 7192751Sjeff 72166167Skib while (is_nvspace (*tmp) && tmp < rlimit) 73166167Skib tmp++; 74166167Skib if (*tmp == '\r') 75166167Skib tmp++; 7669664Speter if (*tmp == '\n' && tmp < rlimit) 7769664Speter { 7869664Speter CPP_INCREMENT_LINE (pfile, 0); 7969664Speter lines++; 80168138Srwatson col = 0; 81168138Srwatson cur = tmp; 8292654Sjeff c = last_c; 8392654Sjeff continue; 84168138Srwatson } 85168138Srwatson } 86168138Srwatson 87176519Sattilio if (__builtin_expect (last_c == '#', false) && !(flags & DO_SPECIAL)) 8869664Speter { 89177253Srwatson if (c != '#' && (flags & DO_BOL)) 9069664Speter { 91183520Sjhb struct line_maps *line_table; 92144613Sjeff 93144613Sjeff if (!pfile->state.skipping && next_line != base) 94183519Sjhb cb->print_lines (lines, base, next_line - base); 95144613Sjeff 9669664Speter /* Prep things for directive handling. */ 97161010Srwatson buffer->next_line = cur; 981541Srgrimes buffer->need_line = true; 991541Srgrimes _cpp_get_fresh_line (pfile); 1001541Srgrimes 1011541Srgrimes /* Ensure proper column numbering for generated error messages. */ 1021541Srgrimes buffer->line_base -= col - 1; 1031541Srgrimes 1041541Srgrimes _cpp_handle_directive (pfile, 0 /* ignore indented */); 1051541Srgrimes 1061541Srgrimes /* Sanitize the line settings. Duplicate #include's can mess 1071541Srgrimes things up. */ 1081541Srgrimes line_table = pfile->line_table; 1091541Srgrimes line_table->highest_location = line_table->highest_line; 1101541Srgrimes 1111541Srgrimes /* The if block prevents us from outputing line information when 1121541Srgrimes the file ends with a directive and no newline. Note that we 1131541Srgrimes must use pfile->buffer, not buffer. */ 1141541Srgrimes if (pfile->buffer->cur != pfile->buffer->rlimit) 1151541Srgrimes cb->maybe_print_line (pfile->line_table->highest_line); 1161541Srgrimes 117161011Srwatson goto restart; 1181541Srgrimes } 119161011Srwatson 120161011Srwatson flags &= ~DO_BOL; 121161011Srwatson pfile->mi_valid = false; 1221541Srgrimes } 1231541Srgrimes else if (__builtin_expect (last_c == '/', false) \ 1241541Srgrimes && !(flags & DO_SPECIAL) && c != '*' && c != '/') 1251541Srgrimes { 12683366Sjulian /* If a previous slash is not starting a block comment, clear the 12783366Sjulian DO_BOL flag. */ 128140714Sjeff flags &= ~DO_BOL; 1291541Srgrimes pfile->mi_valid = false; 130150164Scsjp } 131150164Scsjp 13291419Sjhb switch (c) 13383366Sjulian { 13442408Seivind case '/': 13542453Seivind if ((flags & DO_BLOCK_COMMENT) && last_c == '*') 13642408Seivind { 13742453Seivind flags &= ~DO_BLOCK_COMMENT; 138144613Sjeff c = 0; 139144613Sjeff } 14083366Sjulian else if (!(flags & DO_SPECIAL) && last_c == '/') 1411541Srgrimes flags |= DO_LINE_COMMENT; 1421541Srgrimes else if (!(flags & DO_SPECIAL)) 1431541Srgrimes /* Mark the position for possible error reporting. */ 1441541Srgrimes LINEMAP_POSITION_FOR_COLUMN (loc, pfile->line_table, col); 1451541Srgrimes 1461541Srgrimes break; 147111119Simp 1481541Srgrimes case '*': 1491541Srgrimes if (!(flags & DO_SPECIAL)) 15036735Sdfr { 1511541Srgrimes if (last_c == '/') 1521541Srgrimes flags |= DO_BLOCK_COMMENT; 15336735Sdfr else 15420069Sbde { 155155334Srwatson flags &= ~DO_BOL; 156155334Srwatson pfile->mi_valid = false; 157155334Srwatson } 158155334Srwatson } 159155334Srwatson 160155334Srwatson break; 16120069Sbde 16220069Sbde case '\'': 16320069Sbde case '"': 16420069Sbde { 16520069Sbde unsigned state = (c == '"') ? DO_STRING : DO_CHAR; 16620069Sbde 1671541Srgrimes if (!(flags & DO_SPECIAL)) 16892751Sjeff { 169100613Srwatson flags |= state; 170100613Srwatson flags &= ~DO_BOL; 171100613Srwatson pfile->mi_valid = false; 172100613Srwatson } 1731541Srgrimes else if ((flags & state) && last_c != '\\') 1741541Srgrimes flags &= ~state; 1751541Srgrimes 1761541Srgrimes break; 1771541Srgrimes } 17897994Sjhb 17997994Sjhb case '\\': 18097994Sjhb { 18197994Sjhb if ((flags & (DO_STRING | DO_CHAR)) && last_c == '\\') 18297994Sjhb c = 0; 1831541Srgrimes 1841541Srgrimes if (!(flags & DO_SPECIAL)) 1851541Srgrimes { 1861541Srgrimes flags &= ~DO_BOL; 1871541Srgrimes pfile->mi_valid = false; 188168355Srwatson } 18933360Sdyson 19051649Sphk break; 19133360Sdyson } 192185029Spjd 193185029Spjd case '\n': 194185029Spjd CPP_INCREMENT_LINE (pfile, 0); 195185029Spjd lines++; 196185029Spjd col = 0; 197185029Spjd flags &= ~DO_LINE_SPECIAL; 198185029Spjd if (!(flags & DO_SPECIAL)) 199185029Spjd flags |= DO_BOL; 200185029Spjd break; 201185029Spjd 202185029Spjd case '#': 203185029Spjd next_line = cur; 204185029Spjd /* Don't update DO_BOL yet. */ 205185029Spjd break; 206185029Spjd 207177785Skib case ' ': case '\t': case '\f': case '\v': case '\0': 208177785Skib break; 209177785Skib 210177785Skib default: 211177785Skib if (!(flags & DO_SPECIAL)) 212177785Skib { 213177785Skib flags &= ~DO_BOL; 214177785Skib pfile->mi_valid = false; 215177785Skib } 216185029Spjd break; 217185029Spjd } 218177785Skib } 219177785Skib 220177785Skib if (flags & DO_BLOCK_COMMENT) 221185029Spjd cpp_error_with_line (pfile, CPP_DL_ERROR, loc, 0, "unterminated comment"); 222185029Spjd 223185029Spjd if (!pfile->state.skipping && cur != base) 224185029Spjd cb->print_lines (lines, base, cur - base); 225185029Spjd 226177785Skib _cpp_pop_buffer (pfile); 227140714Sjeff if (pfile->buffer) 2281541Srgrimes goto restart; 2291541Srgrimes} 2301541Srgrimes