Line data Source code
1 : /** \file generate_error_t.cpp
2 : * \brief Generates error_t.hpp from the configured mxlib error list.
3 : * \author Jared Males
4 : */
5 :
6 : #include <cerrno>
7 : #include <cstring>
8 : #include <fstream>
9 : #include <iostream>
10 : #include <vector>
11 : #include <string>
12 : #include <format>
13 : #include <algorithm>
14 :
15 : #include <errno_info.hpp>
16 : #include <fits_status_info.hpp>
17 :
18 : #ifdef MXLIB_CUDA
19 : #include <cudaError_info.hpp>
20 : #endif
21 :
22 0 : int main()
23 : {
24 0 : std::vector<std::string> error_ts, error_t_msgs;
25 :
26 0 : std::ifstream fin;
27 0 : fin.open( "error_t_list.txt" );
28 :
29 0 : while( fin )
30 : {
31 0 : std::string line;
32 0 : std::getline( fin, line );
33 :
34 0 : size_t start = line.find_first_not_of( " \t" );
35 :
36 0 : if( start == std::string::npos )
37 : {
38 0 : continue;
39 : }
40 :
41 0 : if( line[start] == '#' )
42 : {
43 0 : continue;
44 : }
45 :
46 0 : size_t space = line.find( ' ', start );
47 :
48 0 : if( space == std::string::npos )
49 : {
50 0 : continue;
51 : }
52 :
53 0 : size_t quotest = line.find( '"', space );
54 :
55 0 : if( quotest == std::string::npos )
56 : {
57 0 : continue;
58 : }
59 :
60 0 : ++quotest;
61 :
62 0 : size_t quoteed = line.find( '"', quotest );
63 :
64 0 : if( quoteed == std::string::npos )
65 : {
66 0 : continue;
67 : }
68 :
69 0 : error_ts.push_back( line.substr( start, space - start ) );
70 0 : error_t_msgs.push_back( line.substr( quotest, quoteed - quotest ) );
71 0 : }
72 0 : fin.close();
73 :
74 0 : std::vector<std::string> ERRNOs, errnos, errno_msgs;
75 0 : std::vector<int> EVALs;
76 0 : errno_info( ERRNOs, EVALs, errnos, errno_msgs );
77 :
78 0 : std::vector<std::string> fits_codes, fits_vals, fits_msgs;
79 0 : fits_status_info( fits_codes, fits_vals, fits_msgs );
80 :
81 : #ifdef MXLIB_CUDA
82 : std::vector<std::string> cuda_codes, cuda_vals, cuda_msgs;
83 : cuda_info(cuda_vals, cuda_codes, cuda_msgs);
84 : #endif
85 :
86 : // Get max length of a name for formatting
87 0 : int maxlen = 0;
88 0 : for( auto &en : error_ts )
89 : {
90 0 : if( en.length() > maxlen )
91 : {
92 0 : maxlen = en.length();
93 : }
94 : }
95 :
96 0 : for( auto &en : errnos )
97 : {
98 0 : if( en.length() > maxlen )
99 : {
100 0 : maxlen = en.length();
101 : }
102 : }
103 :
104 0 : for( auto &ft : fits_codes )
105 : {
106 0 : if( ft.length() > maxlen )
107 : {
108 0 : maxlen = ft.length();
109 : }
110 : }
111 :
112 : #ifdef MXLIB_CUDA
113 : for( auto &ct : cuda_codes )
114 : {
115 : if( ct.length() > maxlen )
116 : {
117 : maxlen = ct.length();
118 : }
119 : }
120 : #endif
121 :
122 0 : std::vector<std::string> uniqueERRNOs, uniqueerrnos;
123 0 : for( size_t n = 1; n < ERRNOs.size(); ++n )
124 : {
125 0 : bool unique = true;
126 0 : for( size_t m = 0; m < n; ++m )
127 : {
128 0 : if( EVALs[n] == EVALs[m] )
129 : {
130 0 : unique = false;
131 0 : break;
132 : }
133 : }
134 :
135 0 : if( unique )
136 : {
137 0 : uniqueERRNOs.push_back( ERRNOs[n] );
138 0 : uniqueerrnos.push_back( errnos[n] );
139 : }
140 : }
141 :
142 0 : std::cerr << "Unique ECODES: " << uniqueERRNOs.size() << '/' << ERRNOs.size() << '\n';
143 :
144 0 : std::ofstream fout;
145 0 : fout.open( "../error_t.hpp" );
146 :
147 0 : fout << "/** \\file error_t.hpp" << '\n';
148 0 : fout << " * \\brief The mxlib error_t type and utilities" << '\n';
149 0 : fout << " * \\ingroup error_handling_files" << '\n';
150 0 : fout << " */" << '\n';
151 0 : fout << '\n';
152 0 : fout << "/* ********** THIS FILE IS GENERATED ********** */" << '\n';
153 0 : fout << "/* ********** DO NOT MODIFY OR COMMIT ********** */" << '\n';
154 0 : fout << '\n';
155 0 : fout << "#include <fitsio.h>" << '\n';
156 : #ifdef MXLIB_CUDA
157 : fout << "\n";
158 : fout << "#ifdef MXLIB_CUDA" << '\n';
159 : fout << "#include <cuda_runtime.h>" << '\n';
160 : fout << "#endif //MXLIB_CUDA\n";
161 : #endif
162 0 : fout << '\n';
163 0 : fout << "#ifndef mx_error_t_hpp" << '\n';
164 0 : fout << "#define mx_error_t_hpp" << '\n';
165 0 : fout << '\n';
166 0 : fout << "namespace mx" << '\n';
167 0 : fout << "{\n" << '\n';
168 0 : fout << '\n';
169 0 : fout << "/// The mxlib error codes" << '\n';
170 0 : fout << "/** \\ingroup error_handling_codes" << '\n';
171 0 : fout << " */" << '\n';
172 0 : fout << "enum class error_t" << '\n';
173 0 : fout << "{" << '\n';
174 0 : for( size_t n = 0; n < error_ts.size(); ++n )
175 : {
176 0 : std::string symbol = error_ts[n] + ',';
177 0 : fout << std::format( " {:{}} ///< {}\n", symbol, maxlen + 1, error_t_msgs[n] );
178 0 : }
179 :
180 0 : for( size_t n = 0; n < errnos.size(); ++n )
181 : {
182 0 : error_ts.push_back( errnos[n] );
183 0 : error_t_msgs.push_back( errno_msgs[n] );
184 :
185 0 : std::string symbol = errnos[n] + ',';
186 0 : fout << std::format( " {:{}} ///< {} ({})\n", symbol, maxlen + 1, errno_msgs[n], ERRNOs[n] );
187 0 : }
188 :
189 0 : for( size_t n = 0; n < fits_codes.size() ; ++n )
190 : {
191 0 : error_ts.push_back( fits_codes[n] );
192 0 : error_t_msgs.push_back( fits_msgs[n] );
193 0 : std::string symbol = fits_codes[n] + ',';
194 0 : fout << std::format( " {:{}} ///< {}\n", symbol, maxlen + 1, fits_msgs[n] );
195 0 : }
196 :
197 : #ifdef MXLIB_CUDA
198 : for( size_t n = 0; n < cuda_codes.size(); ++n )
199 : {
200 : error_ts.push_back( cuda_codes[n] );
201 : error_t_msgs.push_back( cuda_msgs[n] );
202 : std::string symbol = cuda_codes[n] + ',';
203 : fout << std::format( " {:{}} ///< {}\n", symbol, maxlen + 1, cuda_msgs[n] );
204 : }
205 : #endif
206 0 : fout << std::format( " {:{}} ///< {}\n", "__sentinel", maxlen + 1, "do not use" );
207 :
208 :
209 0 : fout << "}; //enum class error_t" << "\n" << '\n';
210 :
211 0 : fout << "/// Convert a \\ref error_t code to its name" << '\n';
212 0 : fout << "/**" << '\n';
213 0 : fout << " * \\returns the name of the \\ref error_t code" << '\n';
214 0 : fout << " *" << '\n';
215 0 : fout << " * \\ingroup error_handling_codes" << '\n';
216 0 : fout << " */" << '\n';
217 : fout << "static constexpr const char * errorName( const error_t & errc /**< [in] the error code to convert*/)"
218 0 : << '\n';
219 0 : fout << "{" << '\n';
220 0 : fout << " switch(errc)" << '\n';
221 0 : fout << " {" << '\n';
222 :
223 0 : for( size_t n = 0; n < error_ts.size(); ++n )
224 : {
225 0 : fout << " case error_t::" << error_ts[n] << ":" << '\n';
226 0 : fout << " return \"" << error_ts[n] << "\";" << '\n';
227 : }
228 0 : fout << " default:" << '\n';
229 0 : fout << " return \"unknown error_t (bug)\";" << '\n';
230 0 : fout << " }" << '\n';
231 0 : fout << "} //errorName" << '\n';
232 0 : fout << '\n';
233 :
234 0 : fout << "/// Get the descriptive message for a \\ref error_t code." << '\n';
235 0 : fout << "/**" << '\n';
236 0 : fout << " * \\returns the descriptive message corresponding to the \\ref error_t code" << '\n';
237 0 : fout << " *" << '\n';
238 0 : fout << " * \\ingroup error_handling_codes" << '\n';
239 0 : fout << " */" << '\n';
240 : fout << "static constexpr const char * errorMessage( const error_t & errc /**< [in] the error code for which to "
241 : "get the message*/)"
242 0 : << '\n';
243 0 : fout << "{" << '\n';
244 0 : fout << " switch(errc)" << '\n';
245 0 : fout << " {" << '\n';
246 :
247 0 : for( size_t n = 0; n < error_ts.size(); ++n )
248 : {
249 0 : fout << " case error_t::" << error_ts[n] << ":" << '\n';
250 0 : fout << " return \"" << error_t_msgs[n] << "\";" << '\n';
251 : }
252 0 : fout << " default:" << '\n';
253 0 : fout << " return \"unknown error_t (bug)\";" << '\n';
254 0 : fout << " }" << '\n';
255 0 : fout << "} //errorMessage" << '\n';
256 0 : fout << '\n';
257 :
258 0 : fout << "/// Convert an errno code to \\ref error_t" << '\n';
259 0 : fout << "/**" << '\n';
260 0 : fout << " * \\returns the \\ref error_t code corresponding to the errno code" << '\n';
261 0 : fout << " *" << '\n';
262 0 : fout << " * \\ingroup error_handling_codes" << '\n';
263 0 : fout << " */" << '\n';
264 0 : fout << "static constexpr error_t errno2error_t( const int & err/**< [in] the errno code to convert*/)" << '\n';
265 0 : fout << "{" << '\n';
266 0 : fout << " switch(err)" << '\n';
267 0 : fout << " {" << '\n';
268 :
269 0 : for( size_t n = 0; n < uniqueERRNOs.size(); ++n )
270 : {
271 0 : fout << " case " << uniqueERRNOs[n] << ":" << '\n';
272 0 : fout << " return error_t::" << uniqueerrnos[n] << ";" << '\n';
273 : }
274 0 : fout << " default:" << '\n';
275 0 : fout << " return error_t::error;" << '\n';
276 0 : fout << " }" << '\n';
277 0 : fout << "} //errno2error_t" << '\n';
278 :
279 0 : fout << '\n';
280 :
281 0 : fout << "/// Convert a FITS status code to \\ref error_t" << '\n';
282 0 : fout << "/**" << '\n';
283 0 : fout << " * \\returns the \\ref error_t code corresponding to the FITS status code" << '\n';
284 0 : fout << " *" << '\n';
285 0 : fout << " * \\ingroup fits_utils" << '\n';
286 0 : fout << " */" << '\n';
287 : fout << "static constexpr error_t fits_status2error_t( const int & err/**< [in] the fits status code to convert*/)"
288 0 : << '\n';
289 0 : fout << "{" << '\n';
290 0 : fout << " switch(err)" << '\n';
291 0 : fout << " {" << '\n';
292 0 : fout << " case " << "0" << ":" << '\n'; // this is not specified
293 0 : fout << " return error_t::noerror;" << '\n';
294 :
295 0 : for( size_t n = 0; n < fits_vals.size(); ++n )
296 : {
297 0 : fout << " case " << fits_vals[n] << ":" << '\n';
298 0 : fout << " return error_t::" << fits_codes[n] << ";" << '\n';
299 : }
300 0 : fout << " default:" << '\n';
301 0 : fout << " return error_t::error;" << '\n';
302 0 : fout << " }" << '\n';
303 0 : fout << "} //fits_status2error_t" << '\n';
304 0 : fout << '\n';
305 :
306 : #ifdef MXLIB_CUDA
307 : fout << "#ifdef MXLIB_CUDA\n";
308 : fout << "/// Convert a cudaError code to \\ref error_t" << '\n';
309 : fout << "/**" << '\n';
310 : fout << " * \\returns the \\ref error_t code corresponding to the cudaError code" << '\n';
311 : fout << " *" << '\n';
312 : fout << " * \\ingroup cuda_utils" << '\n';
313 : fout << " */" << '\n';
314 : fout << "static constexpr error_t cudaError2error_t( const cudaError_t & err/**< [in] the cudaError code to convert*/)"
315 : << '\n';
316 : fout << "{" << '\n';
317 : fout << " switch(err)" << '\n';
318 : fout << " {" << '\n';
319 : for( size_t n = 0; n < cuda_vals.size(); ++n )
320 : {
321 : fout << " case " << cuda_vals[n] << ":" << '\n';
322 : fout << " return error_t::" << cuda_codes[n] << ";" << '\n';
323 : }
324 : fout << " default:" << '\n';
325 : fout << " return error_t::error;" << '\n';
326 : fout << " }" << '\n';
327 : fout << "} //cudaError2error_t" << '\n';
328 : fout << "#endif //MXLIB_CUDA\n";
329 : fout << '\n';
330 : #endif //MXLIB_CUDA
331 :
332 0 : fout << "} //namespace mx" << '\n';
333 0 : fout << "#endif //mx_error_t_hpp" << '\n';
334 :
335 0 : fout << "\n\n";
336 0 : fout << "#ifdef MXLIBTEST_ERROR_T_TESTS" << '\n';
337 0 : fout << "#ifndef MXLIBTEST_ERROR_T_TESTS_INC" << '\n';
338 0 : fout << "#define MXLIBTEST_ERROR_T_TESTS_INC" << '\n';
339 0 : fout << '\n';
340 0 : fout << "namespace mx" << '\n';
341 0 : fout << "{" << '\n';
342 0 : fout << '\n';
343 0 : fout << "void error_t_vector( std::vector<error_t> & errcs )" << '\n';
344 0 : fout << '{' << '\n';
345 0 : fout << " errcs = { error_t::" << error_ts[0] << ',' << '\n';
346 0 : for( size_t n = 1; n < error_ts.size() - 1; ++n )
347 : {
348 0 : fout << " error_t::" << error_ts[n] << ',' << '\n';
349 : }
350 0 : fout << " error_t::" << error_ts.back() << "};" << '\n';
351 0 : fout << '\n';
352 0 : fout << "} //error_t_vector" << '\n';
353 0 : fout <<'\n';
354 0 : fout << "void errno_vector( std::vector<int> & errnos )" << '\n';
355 0 : fout << '{' << '\n';
356 0 : fout << " errnos = { " << uniqueERRNOs[0] << ',' << '\n';
357 0 : for( size_t n = 1; n < uniqueERRNOs.size() - 1; ++n )
358 : {
359 0 : fout << " " << uniqueERRNOs[n] << ',' << '\n';
360 : }
361 0 : fout << " " << uniqueERRNOs.back() << "};" << '\n';
362 0 : fout << '\n';
363 0 : fout << "} //errno_vector" << '\n';
364 0 : fout << "void fitserr_vector( std::vector<int> & fitserrs )" << '\n';
365 0 : fout << '{' << '\n';
366 0 : fout << " fitserrs= { " << fits_vals[0] << ',' << '\n';
367 0 : for( size_t n = 1; n < fits_vals.size() - 1; ++n )
368 : {
369 0 : fout << " " << fits_vals[n] << ',' << '\n';
370 : }
371 0 : fout << " " << fits_vals.back() << "};" << '\n';
372 0 : fout << '\n';
373 0 : fout << "} //fitserr_vector" << '\n';
374 0 : fout <<'\n';
375 0 : fout << "} //namespace mx" << '\n';
376 0 : fout << '\n';
377 0 : fout << "#endif //MXLIBTEST_ERROR_T_TESTS_INC" << '\n';
378 0 : fout << "#endif //MXLIBTEST_ERROR_T_TESTS" << '\n';
379 0 : fout.close();
380 :
381 0 : return 0;
382 0 : }
|