1 /*
2  # This file is part of the Astrometry.net suite.
3  # Licensed under a 3-clause BSD style license - see LICENSE
4  */
5 
6 #ifndef AN_ERRORS_H
7 #define AN_ERRORS_H
8 
9 #include <stdarg.h>
10 #include <stdio.h>
11 #include <sys/types.h>
12 #include <regex.h>
13 
14 #include "astrometry/an-bool.h"
15 #include "astrometry/bl.h"
16 #include "astrometry/keywords.h"
17 
18 // forward declaration
19 struct errors;
20 typedef struct errors err_t;
21 
22 typedef void (errfunc_t)(void* baton, err_t* errstate, const char* file, int line, const char* func, const char* format, va_list va);
23 
24 struct errentry {
25     char* file;
26     int line;
27     char* func;
28     char* str;
29 };
30 typedef struct errentry errentry_t;
31 
32 struct errors {
33     FILE* print;
34     anbool save;
35     bl* errstack;
36 
37     errfunc_t* errfunc;
38     void* baton;
39 };
40 
41 /***    Global functions    ***/
42 
43 err_t* errors_get_state();
44 
45 // takes a (deep) snapshot of the current error handling state and pushes it onto the
46 // stack.
47 void errors_push_state();
48 
49 //
50 void errors_pop_state();
51 
52 void
53 ATTRIB_FORMAT(printf,4,5)
54     report_error(const char* modfile, int modline, const char* modfunc, const char* fmt, ...);
55 
56 void report_errno();
57 
58 #define ERROR(fmt, ...) report_error(__FILE__, __LINE__, __func__, fmt, ##__VA_ARGS__)
59 
60 #define SYSERROR(fmt, ...) do { report_errno(); report_error(__FILE__, __LINE__, __func__, fmt, ##__VA_ARGS__); } while(0)
61 
62 void errors_log_to(FILE* f);
63 
64 /* Sends all errors to the given function for processing;
65  turns off printing and saving (ie, err_t.print and err_t.save)
66  */
67 void errors_use_function(errfunc_t* func, void* baton);
68 
69 void errors_print_stack(FILE* f);
70 
71 void errors_clear_stack();
72 
73 int errors_print_on_exit(FILE* fid);
74 
75 // free globals.
76 void errors_free();
77 
78 /*
79  A convenience routine for times when you want to suppress printing error
80  messages and instead capture them to a string.  Use in conjunction with
81  the following...
82  */
83 void errors_start_logging_to_string();
84 
85 /*
86  Reverts the error-processing system to its previous state and returns the
87  captured error string.
88  Returns a newly-allocated string which you must free().
89  */
90 char* errors_stop_logging_to_string(const char* separator);
91 
92 /*
93  Convenience function to report an error from the regex module.
94  */
95 void errors_regex_error(int errcode, const regex_t* re);
96 
97 /***    End globals   ***/
98 
99 
100 err_t* error_new();
101 
102 void error_free(err_t* e);
103 
104 void error_stack_add_entryv(err_t* e, const char* file, int line, const char* func, const char* format, va_list va);
105 
106 void error_stack_add_entry(err_t* e, const char* file, int line, const char* func, const char* str);
107 
108 errentry_t* error_stack_get_entry(const err_t* e, int i);
109 
110 int error_stack_N_entries(const err_t* e);
111 
112 int error_nerrs(const err_t* e);
113 
114 char* error_get_errstr(const err_t* e, int i);
115 
116 void error_stack_clear(err_t* e);
117 
118 void
119 ATTRIB_FORMAT(printf,5,6)
120     error_report(err_t* e, const char* module, int line, const char* func,
121                  const char* fmt, ...);
122 
123 void error_reportv(err_t* e, const char* module, int line,
124                    const char* func, const char* fmt, va_list va);
125 
126 void error_print_stack(err_t* e, FILE* f);
127 
128 // returns the error messages (not module:lines) in a newly-allocated string
129 char* error_get_errs(err_t* e, const char* separator);
130 
131 
132 #endif
133 
134