1 | #include <fstream.hfa> |
---|
2 | #include <parseconfig.hfa> |
---|
3 | #include <stdlib.hfa> |
---|
4 | |
---|
5 | extern "C" { |
---|
6 | extern long long int strtoll( const char* str, char** endptr, int base ); |
---|
7 | } |
---|
8 | |
---|
9 | #define xstr(s) str(s) |
---|
10 | #define str(s) #s |
---|
11 | |
---|
12 | bool custom_parse( const char * arg, int & value ) { |
---|
13 | char * end; |
---|
14 | int r = strtoll( arg, &end, 10 ); |
---|
15 | if ( *end != '\0' ) return false; |
---|
16 | |
---|
17 | value = r + 99; |
---|
18 | return true; |
---|
19 | } |
---|
20 | |
---|
21 | int main() { |
---|
22 | struct { |
---|
23 | int stop_cost; |
---|
24 | int num_students; |
---|
25 | int num_stops; |
---|
26 | int max_num_students; |
---|
27 | int timer_delay; |
---|
28 | int groupoff_delay; |
---|
29 | } config_params; |
---|
30 | int conductor_delay; |
---|
31 | [2] int parental_delay_and_num_couriers; |
---|
32 | [ int, int ] max_student_delay_and_trips; |
---|
33 | |
---|
34 | const size_t NUM_ENTRIES = 11; |
---|
35 | config_entry entries[NUM_ENTRIES] = { |
---|
36 | { "StopCost", config_params.stop_cost }, |
---|
37 | { "NumStudents", config_params.num_students }, |
---|
38 | { "NumStops", config_params.num_stops }, |
---|
39 | { "MaxNumStudents", config_params.max_num_students }, |
---|
40 | { "TimerDelay", config_params.timer_delay }, |
---|
41 | { "GroupoffDelay", config_params.groupoff_delay }, |
---|
42 | { "ConductorDelay", conductor_delay }, |
---|
43 | { "ParentalDelay", parental_delay_and_num_couriers[0] }, |
---|
44 | { "NumCouriers", parental_delay_and_num_couriers[1] }, |
---|
45 | { "MaxStudentDelay", max_student_delay_and_trips.0 }, |
---|
46 | { "MaxStudentTrips", max_student_delay_and_trips.1 } |
---|
47 | }; |
---|
48 | |
---|
49 | |
---|
50 | sout | "Different types of destination addresses"; |
---|
51 | |
---|
52 | parse_config( xstr(IN_DIR) "parseconfig-all.txt", entries, NUM_ENTRIES, parse_tabular_config_format ); |
---|
53 | |
---|
54 | sout | "Stop cost: " | config_params.stop_cost; |
---|
55 | sout | "Number of students: " | config_params.num_students; |
---|
56 | sout | "Number of stops: " | config_params.num_stops; |
---|
57 | sout | "Maximum number of students: " | config_params.max_num_students; |
---|
58 | sout | "Timer delay: " | config_params.timer_delay; |
---|
59 | sout | "Groupoff delay: " | config_params.groupoff_delay; |
---|
60 | sout | "Conductor delay: " | conductor_delay; |
---|
61 | sout | "Parental delay: " | parental_delay_and_num_couriers[0]; |
---|
62 | sout | "Number of couriers: " | parental_delay_and_num_couriers[1]; |
---|
63 | sout | "Maximum student delay: " | max_student_delay_and_trips.0; |
---|
64 | sout | "Maximum student trips: " | max_student_delay_and_trips.1; |
---|
65 | sout | nl; |
---|
66 | |
---|
67 | |
---|
68 | sout | "Open_Failure thrown when config file does not exist"; |
---|
69 | try { |
---|
70 | parse_config( xstr(IN_DIR) "doesnt-exist.txt", entries, NUM_ENTRIES, parse_tabular_config_format ); |
---|
71 | } catch( Open_Failure * ex ) { |
---|
72 | sout | "Failed to open the config file"; |
---|
73 | } |
---|
74 | sout | nl; |
---|
75 | |
---|
76 | |
---|
77 | sout | "Missing_Config_Entries thrown when config file is missing entries we want"; |
---|
78 | try { |
---|
79 | parse_config( xstr(IN_DIR) "parseconfig-missing.txt", entries, NUM_ENTRIES, parse_tabular_config_format ); |
---|
80 | } catch( Missing_Config_Entries * ex ) { |
---|
81 | msg( ex ); |
---|
82 | } |
---|
83 | sout | nl; |
---|
84 | |
---|
85 | |
---|
86 | sout | "Parse_Failure thrown when an entry cannot be parsed"; |
---|
87 | |
---|
88 | int non_int_val; |
---|
89 | config_entry entry[1] = { |
---|
90 | { "AnothaOne", non_int_val } |
---|
91 | }; |
---|
92 | |
---|
93 | try { |
---|
94 | parse_config( xstr(IN_DIR) "parseconfig-errors.txt", entry, 1, parse_tabular_config_format ); |
---|
95 | } catch( Parse_Failure * ex ) { |
---|
96 | msg( ex ); |
---|
97 | } |
---|
98 | sout | nl; |
---|
99 | |
---|
100 | |
---|
101 | sout | "Validation_Failure thrown when an entry fails validation"; |
---|
102 | |
---|
103 | // TODO: Fix compiler bug that makes casting necessary |
---|
104 | config_entry new_entry1 = { "StopCost", config_params.stop_cost, (bool (*)(int &))is_positive }; |
---|
105 | entries[0] = new_entry1; |
---|
106 | |
---|
107 | try { |
---|
108 | parse_config( xstr(IN_DIR) "parseconfig-errors.txt", entries, NUM_ENTRIES, parse_tabular_config_format ); |
---|
109 | } catch( Validation_Failure * ex ) { |
---|
110 | msg( ex ); |
---|
111 | } |
---|
112 | sout | nl; |
---|
113 | |
---|
114 | |
---|
115 | sout | "No error is thrown when validation succeeds"; |
---|
116 | config_params.stop_cost = -1; // Reset value |
---|
117 | parse_config( xstr(IN_DIR) "parseconfig-all.txt", entries, NUM_ENTRIES, parse_tabular_config_format ); |
---|
118 | sout | "Stop cost: " | config_params.stop_cost; |
---|
119 | sout | nl; |
---|
120 | |
---|
121 | |
---|
122 | sout | "A custom parse function can be accepted"; |
---|
123 | |
---|
124 | config_entry new_entry2 = { "StopCost", config_params.stop_cost, custom_parse }; |
---|
125 | entries[0] = new_entry2; |
---|
126 | |
---|
127 | config_params.stop_cost = -1; // Reset value |
---|
128 | parse_config( xstr(IN_DIR) "parseconfig-all.txt", entries, NUM_ENTRIES, parse_tabular_config_format ); |
---|
129 | |
---|
130 | sout | "Stop cost: " | config_params.stop_cost; |
---|
131 | sout | nl; |
---|
132 | |
---|
133 | |
---|
134 | sout | "Custom parse and validation functions can be provided together"; |
---|
135 | |
---|
136 | // TODO: Fix compiler bug that makes casting necessary |
---|
137 | config_entry new_entry3 = { "StopCost", config_params.stop_cost, custom_parse, (bool (*)(int &))is_positive }; |
---|
138 | entries[0] = new_entry3; |
---|
139 | |
---|
140 | config_params.stop_cost = -1; // Reset value |
---|
141 | parse_config( xstr(IN_DIR) "parseconfig-all.txt", entries, NUM_ENTRIES, parse_tabular_config_format ); |
---|
142 | |
---|
143 | sout | "Stop cost: " | config_params.stop_cost; |
---|
144 | |
---|
145 | exit( EXIT_SUCCESS ); // This is to avoid memory leak messages from the above exceptions |
---|
146 | } |
---|