source: libcfa/src/parseconfig.cfa@ 58ebd786

ADT ast-experimental enum forall-pointer-decay jacob/cs343-translation pthread-emulation qualifiedEnum stuck-waitfor-destruct
Last change on this file since 58ebd786 was 58ebd786, checked in by Jacob Prud'homme <jafprudhomme@…>, 5 years ago

Made some small changes

Comments, spacing, etc.

  • Property mode set to 100644
File size: 3.8 KB
Line 
1#include <fstream.hfa>
2#include <heap.hfa>
3#include "parseconfig.hfa"
4
5struct KVPairs {
6 int size, max_size;
7 * [ char *, char * ] data;
8};
9void ?{}( KVPairs & kvp ) with ( kvp ) { // default constructor
10 size = 0; max_size = 0; data = 0p;
11}
12void ?{}( KVPairs & kvp, int size ) { // initialization
13 kvp.[ size, max_size ] = [ 0, size ];
14 kvp.data = alloc( size );
15}
16void ^?{}( KVPairs & kvp ) with ( kvp ) { // destructor
17 free( data );
18 size = 0; max_size = 0; data = 0p;
19}
20
21void add_kv_pair( KVPairs kv_pairs, char * k, char * v ) with ( kv_pairs ) {
22 if ( size == max_size ) {
23 max_size *= 2;
24 data = resize( data, max_size );
25 }
26
27 data[size] = [ k, v ];
28 ++size;
29}
30
31bool comments( ifstream & in, char * name ) {
32 while () {
33 in | name;
34 if ( fail( in ) ) return true;
35 if ( name[0] != '#' ) break;
36 in | nl; // ignore remainder of line
37 } // for
38 return false;
39} // comments
40
41// Parse configuration from a file formatted in shell style
42KVPairs & parse_shell_config_format( const char * config_file, size_t num_entries ) {
43 KVPairs kv_pairs = { num_entries };
44
45 ifstream in;
46 try {
47 open( in, config_file ); // open the configuration file for input
48
49 while () {
50 char * key;
51 char * value;
52 if ( comments( in, key ) ) break; // eof ?
53 // Should we just overwrite duplicate config entries? Having a hash map would make this much easier
54 in | value;
55
56 add_kv_pair( kv_pairs, key, value );
57
58 if ( fail( in ) ) break;
59 in | nl; // ignore remainder of line
60 } // for
61 } catch( Open_Failure * ex; ex->istream == &in ) {
62 exit | "Error: could not open input file \"" | config_file | "\"";
63 } // try
64 close( in );
65
66 return kv_pairs;
67}
68
69// Parse configuration values from intermediate format
70void parse_config( const char * config_file, config_entry entries[], size_t num_entries ) {
71 KVPairs kv_pairs = parse_shell_config_format( config_file, num_entries );
72
73 int entries_so_far = 0;
74 for ( i; kv_pairs.size ) {
75 if ( entries_so_far == num_entries ) break;
76
77 char * src_key, * src_value;
78 [ src_key, src_value ] = kv_pairs.data[i];
79
80 for ( j; num_entries ) {
81 if ( strcmp( src_key, entries[j].key ) != 0 ) continue;
82 if ( entries[j].parse( src_value, entries[j].variable ) ) {
83 ++entries_so_far;
84 break;
85 }
86
87 serr | "Value '" | src_value | "' for key '" | src_key | "' could not be parsed";
88 }
89 }
90} // processConfigFile
91
92
93//-----------------------------------------------------------------------------
94// Typed argument parsing
95
96bool parse( const char * arg, const char * & value ) {
97 value = arg;
98 return true;
99}
100
101bool parse( const char * arg, int & value ) {
102 char * end;
103 int r = strtoll( arg, &end, 10 );
104 if ( *end != '\0' ) return false;
105
106 value = r;
107 return true;
108}
109
110bool parse( const char * arg, unsigned & value ) {
111 char * end;
112 unsigned long long int r = strtoull( arg, &end, 10 );
113 if ( *end != '\0' ) return false;
114 if ( r > (unsigned)MAX ) return false;
115
116 value = r;
117 return true;
118}
119
120bool parse( const char * arg, unsigned long & value ) {
121 char * end;
122 unsigned long long int r = strtoull( arg, &end, 10 );
123 if ( *end != '\0' ) return false;
124 if ( r > (unsigned long)MAX ) return false;
125
126 value = r;
127 return true;
128}
129
130bool parse( const char * arg, unsigned long long & value ) {
131 char * end;
132 unsigned long long int r = strtoull( arg, &end, 10 );
133 if ( *end != '\0' ) return false;
134 if ( r > (unsigned long long)MAX ) return false;
135
136 value = r;
137 return true;
138}
139
140bool parse( const char * arg, float & value ) {
141 char * end;
142 float r = strtof( arg, &end );
143 if ( *end != '\0' ) return false;
144
145 value = r;
146 return true;
147}
148
149bool parse( const char * arg, double & value ) {
150 char * end;
151 double r = strtod( arg, &end );
152 if ( *end != '\0' ) return false;
153
154 value = r;
155 return true;
156}
157
158
159// Local Variables: //
160// tab-width: 4 //
161// compile-command: "cfa parseconfig.cfa" //
162// End: //
Note: See TracBrowser for help on using the repository browser.