1 /* 2 This file is part of GNU APL, a free implementation of the 3 ISO/IEC Standard 13751, "Programming Language APL, Extended" 4 5 Copyright (C) 2008-2016 Dr. Jürgen Sauermann 6 7 This program is free software: you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation, either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <http://www.gnu.org/licenses/>. 19 */ 20 21 #ifndef __INPUT_FILE_HH_DEFINED__ 22 #define __INPUT_FILE_HH_DEFINED__ 23 24 #include <vector> 25 26 #include "UTF8_string.hh" 27 #include "UCS_string_vector.hh" 28 29 /** an input file and its properties. The file can be an apl script(.apl) file 30 or a testcase (.tc) file. The file names initially come from the command 31 line, but can be extended by )COPY commands 32 */ 33 /// A single input file to be executed by the interpreter 34 struct InputFile 35 { 36 friend class IO_Files; 37 38 /// empty constructor InputFileInputFile39 InputFile() {} 40 41 /// Normal constructor InputFileInputFile42 InputFile(const UTF8_string & _filename, FILE * _file, 43 bool _test, bool _echo, bool _is_script, LX_mode LX) 44 : file (_file), 45 filename (&_filename[0], _filename.size()), 46 test (_test), 47 echo (_echo), 48 is_script(_is_script), 49 with_LX (LX), 50 line_no (0), 51 in_html (0), 52 in_function(false), 53 in_variable(false), 54 in_matched(false), 55 from_COPY(false) 56 {} 57 58 /// set the from_COPY flag set_COPYInputFile59 void set_COPY() 60 { from_COPY = true; } 61 62 /// set the current line number set_line_noInputFile63 void set_line_no(int num) 64 { line_no = num; } 65 66 /// set the current HTML mode set_htmlInputFile67 void set_html(int html) 68 { in_html = html; } 69 70 /// return the current HTML mode get_htmlInputFile71 int get_html() const 72 { return in_html; } 73 74 /// the current file current_fileInputFile75 static InputFile * current_file() 76 { return files_todo.size() ? &files_todo[0] : 0; } 77 78 /// the name of the currrent file current_filenameInputFile79 static const char * current_filename() 80 { return files_todo.size() ? files_todo[0].filename.c_str() : "stdin"; } 81 82 /// the line number of the currrent file current_line_noInputFile83 static int current_line_no() 84 { return files_todo.size() ? files_todo[0].line_no : stdin_line_no; } 85 86 /// increment the line number of the current file increment_current_line_noInputFile87 static void increment_current_line_no() 88 { if (files_todo.size()) ++files_todo[0].line_no; else ++stdin_line_no; } 89 90 /// return true iff input comes from a script (as opposed to running 91 /// interactively) running_scriptInputFile92 static bool running_script() 93 { return files_todo.size() > 0 && files_todo[0].is_script; } 94 95 /// return true iff the current input file exists and is a test file is_validatingInputFile96 static bool is_validating() 97 { return files_todo.size() > 0 && files_todo[0].test; } 98 99 /// the number of testcase (.tc) files testcase_file_countInputFile100 static int testcase_file_count() 101 { 102 int count = 0; 103 loop(f, files_todo.size()) 104 { 105 if (files_todo[f].test) ++count; 106 } 107 return count; 108 } 109 110 /// add object to object_filter add_filter_objectInputFile111 void add_filter_object(UCS_string & object) 112 { 113 object_filter.push_back(object); 114 } 115 116 /// return true if this file as an oject filter (from )COPY file names...) has_object_filterInputFile117 bool has_object_filter() const 118 { return object_filter.size() > 0; } 119 120 /// check the current line and return true if the line is permitted by the 121 /// object_filter. This function also updates \b in_function and \b 122 /// in_variable 123 bool check_filter(const UTF8_string & line); 124 125 /// true if echo (of the input) is on for the current file 126 static bool echo_current_file(); 127 128 /// open current file unless already open 129 static void open_current_file(); 130 131 /// close the current file and perform some cleanup 132 static void close_current_file(); 133 134 /// randomize the order of test_file_names 135 static void randomize_files(); 136 137 /// files that need to be processed 138 static std::vector<InputFile> files_todo; 139 140 /// the initial set of files provided on the command line 141 static std::vector<InputFile> files_orig; 142 143 /// FILE * from fopen (or 0 if file is closed) 144 FILE * file; 145 146 /// the file name 147 UTF8_string filename; 148 149 protected: 150 151 bool test; ///< true for -T testfile, false for -f APL file 152 bool echo; ///< echo stdin 153 bool is_script; ///< script (override existing functions) 154 LX_mode with_LX; ///< execute ⎕LX at the end 155 int line_no; ///< line number in file 156 int in_html; ///< 0: no HTML, 1: in HTML file 2: in HTML header 157 158 /// functions and vars that shoule be )COPIED 159 UCS_string_vector object_filter; 160 161 /// true if current line belongs to a function. Cleared at final ∇ 162 bool in_function; 163 164 /// return true if current line belongs to a variable. Cleared by empty line 165 bool in_variable; 166 167 /// true if current function or variable was mentioned in object_filter 168 bool in_matched; 169 170 /// true if this file comes from a )COPY XXX.apl (but not XXX.xml 171 bool from_COPY; 172 173 /// line number in stdin 174 static int stdin_line_no; 175 }; 176 177 #endif // __INPUT_FILE_HH_DEFINED__ 178