1 /* 2 * (C) Copyright 2001-2015 Diomidis Spinellis 3 * 4 * This file is part of CScout. 5 * 6 * CScout is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * 11 * CScout 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 CScout. If not, see <http://www.gnu.org/licenses/>. 18 * 19 * 20 * A character coming from a file. 21 * This class also handles trigraphs and newline splicing. 22 * 23 */ 24 25 #ifndef FCHAR_ 26 #define FCHAR_ 27 28 #include <stack> 29 #include <deque> 30 #include <map> 31 32 #include "fileid.h" 33 #include "cpp.h" 34 #include "tokid.h" 35 #include "fchar.h" 36 #include "fifstream.h" 37 38 using namespace std; 39 40 /* 41 * A file position 42 * Assumes that the putback stack is empty. 43 * FcharContext is used for: 44 * - pushing/restoring include file handling 45 * - identifying begin/end locations of functions and macros 46 */ 47 class FcharContext { 48 private: 49 int line_number; 50 Tokid ti; 51 public: FcharContext()52 FcharContext() : line_number(-1) {} FcharContext(int l,Tokid t)53 FcharContext(int l, Tokid t) : 54 line_number(l), ti(t) {} 55 // Accessor methods get_line_number()56 int get_line_number() const { return line_number; } get_tokid()57 Tokid get_tokid() const { return ti; } 58 // Return true if correctly initialized is_valid()59 bool is_valid() const { return line_number != -1; } 60 }; 61 62 typedef stack <FcharContext> StackFcharContext; 63 64 class Fchar; 65 66 // For pushback; two token stack needed to parse the "..." 67 typedef stack <Fchar> stackFchar; 68 69 class Fchar { 70 private: 71 void simple_getnext(); // Trigraphs and slicing 72 static bool trigraphs_enabled; // True if trigraphs are enabled 73 static fifstream in; // Stream we are reading from 74 static Fileid fi; // and its Fileid 75 static int line_number; // Current line number 76 static bool yacc_file; // True if input file is yacc, not C 77 static StackFcharContext cs; // Pushed contexts (from push_input()) 78 static stackFchar ps; // Putback stack 79 static size_t stack_lock_size; // So many elements can not be removed 80 // from the push_input stack 81 82 static bool output_headers; // Debug print of files being processed 83 int val; 84 Tokid ti; // (pos_type from tellg(), fi) 85 86 public: 87 // Will read characters from file named s 88 static void set_input(const string& s); 89 // From now on will read from s; on EOF resume with previous file 90 // Offset is the location of the include file path where the file 91 // was located, and is used for implementing include_next 92 static void push_input(const string& s, int offset = 0); 93 // Next constructor will return c 94 static void putback(Fchar c); 95 /* 96 * Lock current context into the file stack, so it can not 97 * be popped by getnext until unlock is called. 98 * Call it after a push_input operation 99 */ lock_stack()100 static void lock_stack() { stack_lock_size = cs.size(); } unlock_stack()101 static void unlock_stack() { stack_lock_size = 0; } set_output_headers()102 static void set_output_headers() { output_headers = true; } 103 104 // Return the current file position get_context()105 static FcharContext get_context() { 106 return FcharContext(line_number, Tokid(fi, in.tellg())); 107 } 108 // 109 // Set the current file position 110 static void set_context(const FcharContext &c); 111 112 // Construct an unititialized one Fchar()113 Fchar() {}; 114 // Construct it with a given value and tokid Fchar(int v,Tokid t)115 Fchar(int v, Tokid t) : val(v), ti(t) {}; Fchar(int v)116 Fchar(int v) : val(v) {}; 117 // Read next from stream 118 void getnext(); 119 // Return the character value (or EOF) get_char()120 inline int get_char() const { return (val); }; 121 // Return the character's Tokid get_tokid()122 inline Tokid get_tokid() const { return (ti); }; 123 // Return the current line number get_line_num()124 static int get_line_num() { return line_number; } get_path()125 static string get_path() { return fi.get_path(); } get_fname()126 static string get_fname() { return fi.get_fname(); } get_dir()127 static string get_dir() { return fi.get_dir(); } 128 // Return the fileid of the file we are processing get_fileid()129 static Fileid get_fileid() { return fi; } 130 // Return true if the class's source is a file is_file_source()131 static bool is_file_source() { return true; } is_yacc_file()132 static bool is_yacc_file() { return yacc_file; } 133 // Enable the handling of trigraphs enable_trigraphs()134 static void enable_trigraphs() { trigraphs_enabled = true; } 135 }; 136 137 #endif /* FCHAR_ */ 138