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-2015  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 __IO_FILES_HH_DEFINED__
22 #define __IO_FILES_HH_DEFINED__
23 
24 #include <stdio.h>
25 #include <iostream>
26 #include <fstream>
27 
28 #include "Assert.hh"
29 #include "UTF8_string.hh"
30 
31 using namespace std;
32 
33 /*
34  The classes below are used to combine normal user I/O and automatic
35  testcase execution. It works like this:
36 
37        (cin)
38          |
39          |
40          V
41      +---+---+             +-------------------+
42      | Input | <--------   | testcase files(s) |
43      +---+---+             +---------+---------+
44          |                           |
45          |                           |
46          V                           |
47       +--+--+                        |
48       | APL |                        |
49       +--+--+                        |
50          |                           |
51          |                           |
52          +-----------------------+   |
53          |                       |   |
54          |                       V   V
55          |                    +--+---+--+
56          |                    | compare |
57          |                    +----+----+
58          |                         |
59          |                         |
60          V                         V
61        (cout)                (test results)
62 
63  */
64 
65 /** handling of Input files. IO_Files reads lines from files until they
66     are all executed. The output of the APL interpreter is compared against
67     the testcase files and mismatches are recorded.
68  */
69 /// a sequence of files that are still to be executed
70 class IO_Files
71 {
72    friend int main(int argc, const char *argv[]);
73    friend struct UserPreferences;
74 
75 public:
76    /// count an error
reset_errors()77    static void reset_errors()
78       {
79         apl_errors = 0;
80         assert_errors = 0;
81         diff_errors = 0;
82         parse_errors = 0;
83       }
84 
85    /// return the total number of errors
error_count()86    static int error_count()
87       { return apl_errors + assert_errors + diff_errors + parse_errors; }
88 
89    /// count and report a parse error
90    static void syntax_error();
91 
92    /// reset APL errors, expecting cnt
93    static void expect_apl_errors(const UCS_string & arg);
94 
95    /// count an APL error
96    static void apl_error(const char * loc);
97 
98    /// count a failed assertion
99    static void assert_error();
100 
101    /// count a output diff error
102    static void diff_error();
103 
104    /// get one line from the current file, open the next file if necceessary
105    static void get_file_line(UTF8_string & line, bool & eof);
106 
107    /// open the next test file
108    static void open_next_file();
109 
110    /// close current testcase file (prematurely) and opem mext one
111    static void next_file();
112 
113    /// return the current test report
get_current_testreport()114    static ofstream & get_current_testreport()
115       { return current_testreport; }
116 
117    /// read one line from the current input file with CR and LF removed
118    static void read_file_line(UTF8_string & file_line, bool & eof);
119 
120 protected:
121    /// dito (close files, print errors, summary etc).
122    static bool end_of_current_file();
123 
124    /// how to handle test results
125    static enum TestMode
126       {
127         /// exit() after last testcase file
128         TM_EXIT_AFTER_LAST       = 0,
129 
130         /// exit() after last testcase file if no error
131         TM_EXIT_AFTER_LAST_IF_OK = 1,
132 
133         /// continue in APL interpreter after last testcase file
134         TM_STAY_AFTER_LAST       = 2,
135 
136         /// stop test execution after the first error (stay in APL interpreter)
137         TM_STOP_AFTER_ERROR      = 3,
138 
139         /// exit() after the first error
140         TM_EXIT_AFTER_ERROR      = 4,
141       } test_mode;   ///< the desired test mode as per --TM n
142 
143    /// write testcases summary file
144    static void print_summary();
145 
146    /// true until total error count is printed.
147    static bool need_total;
148 
149    /// the number of testcases provided
150    static int testcase_count;
151 
152    /// the number of testcases executed
153    static int testcases_done;
154 
155    /// the number of parse errors when executing test file
156    static int parse_errors;
157 
158    /// the tital number of errors in all test files
159    static int total_errors;
160 
161    /// the number of APL errors when executing in current file
162    static int apl_errors;
163 
164    /// the source location where the last APL error was thrown
165    static const char * last_apl_error_loc;
166 
167    /// the testcase file line that has triggered the last APL error
168    static int last_apl_error_line;
169 
170    /// the number of output differences when executing test file
171    static int diff_errors;
172 
173    /// the number of failed assertions when executing test file
174    static int assert_errors;
175 
176    /// the current test report
177    static ofstream current_testreport;
178 };
179 
180 #endif // __IO_FILES_HH_DEFINED__
181