标签:global fputs eal should art utc span dialog pre
依赖的类
1 /*1 utils.h 2 *# A variety of utility functions. 3 *# 4 *# Some of the functions are duplicates of well known C functions that are not 5 *# standard. 6 *2 License 7 *[ 8 *# Author: Werner Stoop 9 *# This software is provided under the terms of the unlicense. 10 *# See http://unlicense.org/ for more details. 11 *] 12 *2 API 13 */ 14 #include "stdafx.h" 15 /*@ MY_MIN(a,b) 16 *# Macro that returns the smallest of its parameters.\n 17 *# As with all macros, {{a}} and {{b}} should not have side effects. 18 */ 19 #define MY_MIN(a,b) (((a)<(b))?(a):(b)) 20 21 /*@ MY_MAX(a,b) 22 *# Macro that returns the largest of its parameters.\n 23 *# As with all macros, {{a}} and {{b}} should not have side effects. 24 */ 25 #define MY_MAX(a,b) (((a)>(b))?(a):(b)) 26 27 /*@ int my_stricmp(const char *p, const char *q) 28 *# Compares two strings {{p}} and {{q}} case insensitively. 29 *# 30 *# It returns 0 if the strings are the same, a positive number if {{p}} comes after {{q}}, 31 *# and negative if {{p}} comes before {{q}}. 32 */ 33 int my_stricmp(const char *p, const char *q); 34 35 /*@ char *my_strdup(const char *s) 36 *# Creates a duplicate of a string {{s}} in a dynamic memory buffer.\n 37 *# The returned buffer needs to be {{free()}}d after use. It may return 38 *# {{NULL}} if the memory allocation fails. 39 */ 40 char *my_strdup(const char *s); 41 42 /*@ char *my_strlower (char *p) 43 *# Converts a string {{p}} to lowercase in place. 44 *# It returns {{p}}. 45 */ 46 char *my_strlower (char *p); 47 48 /*@ char *my_strupper (char *p) 49 *# Converts a string {{p}} to uppercase in place. 50 *# It returns {{p}}. 51 */ 52 char *my_strupper (char *p); 53 54 /*@ char *my_strtok_r(char *str, const char *delim, char **saveptr) 55 *# Works the same as {{strtok_r(3)}} for platforms which lack it. 56 */ 57 char *my_strtok_r(char *str, const char *delim, char **saveptr); 58 59 /*@ char *my_readfile (const char *fn) 60 *# Reads an entire file identified by {{fn}} into a dynamically allocated memory buffer.\n 61 *# The returned buffer needs to be {{free()}}d afterwards.\n 62 *# It returns {{NULL}} if the file could not be read. 63 */ 64 char *my_readfile (const char *fn);
1 /* 2 * A variety of utility functions. 3 * 4 * See utils.h for more info 5 * 6 * This is free and unencumbered software released into the public domain. 7 * http://unlicense.org/ 8 */ 9 #include "stdafx.h" 10 #include <stdlib.h> 11 #include <string.h> 12 #include <stdio.h> 13 #include <ctype.h> 14 15 /* Case insensitive strcmp() 16 */ 17 int my_stricmp(const char *p, const char *q) { 18 for(;*p && tolower(*p) == tolower(*q); p++, q++); 19 return tolower(*p) - tolower(*q); 20 } 21 22 /* strdup() is not ANSI C */ 23 char *my_strdup(const char *s) { 24 char *a; 25 size_t len = strlen(s); 26 a = (char*)malloc(len + 1); 27 if(!a) return NULL; 28 memcpy(a, s, len + 1); 29 return a; 30 } 31 32 /* converts a string to lowercase */ 33 char *my_strlower (char *p) { 34 char *s; 35 for (s = p; s[0]; s++) 36 s[0] = tolower (s[0]); 37 38 return p; 39 } 40 41 /* converts a string to lowercase */ 42 char *my_strupper (char *p) 43 { 44 char *s; 45 for (s = p; s[0]; s++) 46 s[0] = toupper (s[0]); 47 48 return p; 49 } 50 51 char *my_strtok_r(char *str, const char *delim, char **saveptr) { 52 if(!str) 53 str = *saveptr; 54 if(!str[0]) { 55 *saveptr = str; 56 return NULL; 57 } 58 char *s = strpbrk(str, delim); 59 if(s) { 60 s[0] = ‘\0‘; 61 *saveptr = s + 1; 62 } else 63 for(*saveptr = str; (*saveptr)[0]; (*saveptr)++); 64 return str; 65 } 66 67 /* Reads an entire file into a dynamically allocated memory buffer. 68 * The returned buffer needs to be free()d afterwards 69 */ 70 char *my_readfile(const char *fname) { 71 FILE *f; 72 long len,r; 73 char *str; 74 75 if(!(f = fopen(fname, "rb"))) 76 return NULL; 77 78 fseek(f, 0, SEEK_END); 79 len = ftell(f); 80 rewind(f); 81 82 if(!(str = (char*)malloc(len+2))) 83 return NULL; 84 r = fread(str, 1, len, f); 85 86 if(r != len) { 87 free(str); 88 return NULL; 89 } 90 91 fclose(f); 92 str[len] = ‘\0‘; 93 return str; 94 }
ini格式配置文件的读写
1 /*1 ini.h 2 *# Header file for the {*INI*} parser.\n 3 *# 4 *# This is a simple parser for {*.INI*} files. 5 *# It is based around the syntax described in the Wikipedia entry at 6 *# {_http://en.wikipedia.org/wiki/INI_file_}\n 7 *# 8 *# The API has these features: 9 *{ 10 ** Use {{~~ini_read()}} to read an INI file from the disc into an {{~~ini_file}} 11 *# structure or create an empty {{~~ini_file}} structure. 12 ** Use {{~~ini_get()}} to retrieve values from the {{~~ini_file}} structure. 13 ** Use {{~~ini_put()}} and {{~~ini_putf()}} to set values in the {{~~ini_file}} structure. 14 ** Use {{~~ini_write()}} to write the contents of the {{~~ini_file}} structure back to disc. 15 ** Use {{~~ini_free()}} to deallocate the {{~~ini_file}} structure. 16 ** {{~~ini_errstr()}} is used for reporting errors. 17 *} 18 *2 License 19 *[ 20 *# Author: Werner Stoop 21 *# This software is provided under the terms of the unlicense. 22 *# See http://unlicense.org/ for more details. 23 *] 24 *2 API 25 */ 26 #ifndef INI_H 27 #define INI_H 28 29 #if defined(__cplusplus) 30 extern "C" { 31 #endif 32 33 /* 34 * Encapsulates a parameter-value pair in an INI section. 35 * Parameters are stored in a binary search tree, which attempts (but does not 36 * guarantee) O(log(n)) behaviour. 37 */ 38 typedef struct INI_PAIR 39 { 40 char *param; /* The parameter */ 41 char *value; /* Its value */ 42 43 /* Nodes in the tree */ 44 struct INI_PAIR *left, *right; 45 } ini_pair; 46 47 /* 48 * Encapsulates a section within a INI file. 49 * Sections are stored in a binary search tree, which attempts (but does not 50 * guarantee) O(log(n)) behaviour. 51 */ 52 typedef struct INI_SECTION 53 { 54 char *name; /* Name of the section */ 55 ini_pair *fields; /* Fields in the section */ 56 57 /* Nodes in the tree */ 58 struct INI_SECTION *left, *right; 59 } ini_section; 60 61 /*@ struct ##ini_file; 62 *# Structure to encapsulate an INI file. 63 */ 64 struct ini_file 65 { 66 ini_pair *globals; 67 ini_section *sections; 68 }; 69 70 /*@ ini_file *##ini_read(const char *filename, int *err, int *line); 71 *# Reads an INI file named by {{filename}} and returns it as a {{~~ini_file}} object. 72 *# If {{filename}} is {{NULL}}, an empty {{ini_file}} object is created and returned. 73 *# Comments are discarded, so a later call to {{~~ini_write()}} will be 74 *# commentless.\n 75 *# It returns {{NULL}} if the INI file couldn‘t be read, in which case {{err}} will contain the error code 76 *# (see {{~~ini_errstr()}}) and {{line}} will contain the line in the file where the error occured. 77 *# ({{err}} and {{line}} may be {{NULL}}). 78 */ 79 struct ini_file *ini_read(const char *filename, int *err, int *line); 80 81 /*@ ini_file *##ini_parse(const char *text, int *err, int *line); 82 *# Parses a null-terminated string {{text}} as an INI file.\n 83 *# It returns {{NULL}} if the INI file couldn‘t be read, in which case {{err}} will contain the error code 84 *# (see {{~~ini_errstr()}}) and {{line}} will contain the line in the file where the error occured. 85 *# ({{err}} and {{line}} may be {{NULL}}). 86 */ 87 struct ini_file *ini_parse(const char *text, int *err, int *line); 88 89 /*@ int ##ini_write(ini_file *ini, const char *fname); 90 *# Saves all the sections and parameters in an {{ini_file}} to a file.\n 91 *# {{fname}} is the file to which to save. If {{fname}} is {{NULL}}, it is written to 92 *# {{stdout}}. 93 *# It returns 1 on success, an error code otherwise (see {{~~ini_errstr()}}). 94 */ 95 int ini_write(struct ini_file *ini, const char *fname); 96 97 /*@ void ##ini_free(ini_file *ini); 98 *# Free‘s all the memory allocated to a {{ini_file}} object created in {{~~ini_read()}}.\n 99 *# {{ini}} is the {{ini_file}} to free 100 */ 101 void ini_free(struct ini_file *ini); 102 103 /*@ int ini_has_section(struct ini_file *ini, const char *sec) 104 *# Returns true if the ini file has a specific section. 105 */ 106 int ini_has_section(struct ini_file *ini, const char *sec); 107 108 /*@ const char *##ini_get(struct ini_file *ini, const char *sec, const char *par, const char *def); 109 *# Retrieves a parameter {{par}} from a section {{sec}} within the struct ini_file {{ini}} 110 *# and returns its value.\n 111 *# If {{sec}} is {{NULL}}, the global parameters in {{ini}} are searched.\n 112 *# If the value is not found, the default {{def}}, which may be {{NULL}}, is 113 *# returned. 114 */ 115 const char *ini_get(struct ini_file *ini, 116 const char *sec, 117 const char *par, 118 const char *def); 119 120 /*@ int ##ini_put(struct ini_file *ini, const char *sec, const char *par, const char *val); 121 *# Sets a parameter {{par}} in section {{sec}}‘s value to {{val}}, replacing the 122 *# current value if it already exists, or creates the section if it does not 123 *# exist.\n 124 *# If {{sec}} is {{NULL}}, the parameter is added to {{ini}}‘s global parameters.\n 125 *# It returns 1 on success, 0 on failure (which only happens if {{malloc()}} fails). 126 */ 127 int ini_put(struct ini_file *ini, const char *sec, const char *par, const char *val); 128 129 /*@ int ##ini_putf(struct ini_file *ini, const char *sec, const char *par, const char *fmt, ...); 130 *# {{~~ini_putf()}} takes a {{printf()}} style format string and uses vsnprintf() to 131 *# pass a value to {{~~ini_put()}}. This function is intended for placing 132 *# data types that are not strings into the {{ini_file}} 133 *# 134 *# The other parameters are the same as those of {{ini_put()}}. 135 */ 136 int ini_putf(struct ini_file *ini, 137 const char *sec, 138 const char *par, 139 const char *fmt, 140 ...); 141 142 /*@ const char *##ini_errstr(int err) 143 *# Returns a textual description of an error code 144 */ 145 const char *ini_errstr(int err); 146 147 #if defined(__cplusplus) 148 } /* extern "C" */ 149 #endif 150 151 #endif /* INI_H */
1 /* 2 * This is a simple parser for .INI files. 3 * It is based around the syntax described in the Wikipedia entry at 4 * "http://en.wikipedia.org/wiki/INI_file" 5 * 6 * See ini.h for more info 7 * 8 * This is free and unencumbered software released into the public domain. 9 * http://unlicense.org/ 10 */ 11 #include "stdafx.h" 12 #include <stdio.h> 13 #include <stdlib.h> 14 #include <string.h> 15 #include <stdarg.h> 16 #include <ctype.h> 17 #include <setjmp.h> 18 19 #include <assert.h> /* Remember to define NDEBUG for release */ 20 21 #include "ini.h" 22 #include "utils.h" 23 #include <crtdbg.h> 24 25 /* Maximum number of characters expected on a line. 26 It is only used by the ini_putf() function. 27 */ 28 #define MAX_LINE 1024 29 30 /* Various error codes */ 31 #define SUCCESS 1 32 #define FILE_CREATED 0 33 #define NO_SUCH_FILE -1 34 #define OUT_OF_MEMORY -2 35 #define MISSING_END_BRACE -3 36 #define EMPTY_SECTION -4 37 #define EXPECTED_EQUALS -5 38 #define EXPECTED_END_OF_STRING -6 39 #define ER_FOPEN -7 40 #define BAD_SYMBOL -8 41 #define EXPECTED_PARAMETER -9 42 #define EXPECTED_VALUE -10 43 44 const char *ini_errstr(int err) 45 { 46 switch(err) 47 { 48 case SUCCESS : return "Success"; 49 case FILE_CREATED: return "New INI object created"; 50 case NO_SUCH_FILE: return "Unable to open file"; 51 case OUT_OF_MEMORY: return "Out of memory"; 52 case MISSING_END_BRACE: return "Missing ‘]‘ at end of section"; 53 case EMPTY_SECTION: return "Empty [] for section"; 54 case EXPECTED_EQUALS : return "Expected an ‘=‘/‘:‘"; 55 case EXPECTED_END_OF_STRING : return "Expected an end of string"; 56 case ER_FOPEN : return "Unable to open file"; 57 case BAD_SYMBOL : return "Bad symbol"; 58 case EXPECTED_PARAMETER : return "Expected a parameter (or section)"; 59 case EXPECTED_VALUE : return "Expected a value"; 60 } 61 return "Unknown"; 62 } 63 64 /** Configurable parameters *************************************************/ 65 66 /* 67 * Recursively adds sections to the tree of sections 68 */ 69 static void insert_section(ini_section *r, ini_section *n) { 70 assert(r); 71 assert(n); 72 73 if(my_stricmp(r->name, n->name) < 0) { 74 if(!r->left) 75 r->left = n; 76 else 77 insert_section(r->left, n); 78 } else { 79 if(!r->right) 80 r->right = n; 81 else 82 insert_section(r->right, n); 83 } 84 } 85 86 /* 87 * Searches a tree of pairs for a specific parameter 88 */ 89 static ini_pair *find_pair(ini_pair *root, const char *name) { 90 int c; 91 92 if(!root) return NULL; 93 94 c = my_stricmp(root->param, name); 95 if(c == 0) 96 return root; 97 else if(c < 0) 98 return find_pair(root->left, name); 99 else 100 return find_pair(root->right, name); 101 } 102 103 /* 104 * Searches for a specific section 105 */ 106 static ini_section *find_section(ini_section *root, const char *name) { 107 int c; 108 109 if(!root) return NULL; 110 111 c = my_stricmp(root->name, name); 112 if(c == 0) 113 return root; 114 else if(c < 0) 115 return find_section(root->left, name); 116 else 117 return find_section(root->right, name); 118 } 119 120 /* 121 * Creates a new section, and adds it to a tree of sections 122 */ 123 static ini_section *add_section(ini_section **root, char *name) { 124 ini_section *n; 125 126 assert(root); 127 assert(name); 128 129 n = find_section(*root, name); 130 if(n) { 131 free(name); 132 return n; 133 } 134 135 n = (ini_section*)malloc(sizeof *n); 136 if(!n) return NULL; 137 138 n->name = name; 139 140 n->fields = NULL; 141 n->left = n->right = NULL; 142 143 if(*root) 144 insert_section(*root, n); 145 else 146 *root = n; 147 148 return n; 149 } 150 151 /* 152 * Inserts a new pair n into a pair tree p 153 */ 154 static void insert_pair(ini_pair *p, ini_pair *n) { 155 if(my_stricmp(p->param, n->param) < 0) { 156 if(!p->left) 157 p->left = n; 158 else 159 insert_pair(p->left, n); 160 } else { 161 if(!p->right) 162 p->right = n; 163 else 164 insert_pair(p->right, n); 165 } 166 } 167 168 /* 169 * Adds a parameter-value pair to section s 170 */ 171 static ini_pair *add_pair(ini_section *s, char *p, char *v) { 172 ini_pair *n; 173 174 assert(s); 175 176 n = (ini_pair*)malloc(sizeof *n); 177 if(!n) return NULL; 178 179 n->param = p; 180 n->value = v; 181 182 n->left = n->right = NULL; 183 184 if(!s->fields) 185 s->fields = n; 186 else 187 insert_pair(s->fields, n); 188 189 return n; 190 } 191 192 /** Functions for memory deallocation ***************************************/ 193 194 /* 195 * Free‘s a tree of parameter-value pairs 196 */ 197 static void free_pair(ini_pair *p) { 198 if(!p) return; 199 200 free_pair(p->left); 201 free_pair(p->right); 202 203 free(p->param); 204 free(p->value); 205 free(p); 206 } 207 208 /* 209 * Free‘s all the memory allocated to a ini_section s 210 */ 211 static void free_section(ini_section *s) { 212 if(!s) return; 213 214 free_section(s->left); 215 free_section(s->right); 216 217 free(s->name); 218 free_pair(s->fields); 219 free(s); 220 } 221 222 /* 223 * Free‘s all the memory allocated to a ini_file object in ini_read() 224 */ 225 void ini_free(struct ini_file *ini) { 226 if(!ini) return; 227 free_pair(ini->globals); 228 free_section(ini->sections); 229 free(ini); 230 } 231 232 /** Parsing functions *******************************************************/ 233 234 static struct ini_file *make_ini() 235 { 236 struct ini_file *ini = (ini_file*)malloc(sizeof *ini); 237 if(!ini) return NULL; 238 ini->globals = NULL; 239 ini->sections = NULL; 240 return ini; 241 } 242 243 /* 244 * Reads an INI file and returns it as a ini_file object. 245 * If filename is NULL, an empty ini_file object is created and returned. 246 */ 247 struct ini_file *ini_read(const char *filename, int *err, int *line) { 248 if(line) *line = 0; 249 if(!filename) 250 { 251 if(err) *err = FILE_CREATED; 252 return make_ini(); 253 } 254 else 255 { 256 char *text = my_readfile(filename); 257 if(!text) { 258 if(err) *err = NO_SUCH_FILE; 259 return NULL; 260 } 261 struct ini_file * ini = ini_parse(text, err, line); 262 free(text); 263 return ini; 264 } 265 } 266 267 #define T_END 0 268 #define T_VALUE 1 269 270 static int get_token(const char **tp, const char **tstart, const char **tend, int *line, jmp_buf err) { 271 /* *tstart points to the start of the token, while *tend points one char past the end */ 272 273 const char *t = *tp; 274 int tok = T_END; 275 276 assert(tp && tstart && tend); 277 278 whitespace: 279 while(isspace(t[0])) { 280 if(t[0] == ‘\n‘ && line) 281 (*line)++; 282 t++; 283 } 284 if(t[0] == ‘;‘ || t[0] == ‘#‘) { 285 while(t[0] != ‘\n‘ && t[0] != ‘\0‘) 286 t++; 287 goto whitespace; 288 } 289 290 *tstart = t; 291 *tend = t; 292 if(t[0]) { 293 if(strchr("[]:=", t[0])) { 294 tok = *t++; 295 } else if(isgraph(t[0]) && !strchr("\"‘[];#", t[0])) { 296 while(isgraph(t[0]) && !strchr("\"‘[];#", t[0])) { 297 t++; 298 } 299 *tend = t; 300 tok = T_VALUE; 301 } else if(t[0] == ‘\"‘ || t[0] == ‘\‘‘) { 302 char delim = t[0]; 303 if(t[1] == delim && t[2] == delim) { 304 /* """Python style long strings""" */ 305 t += 3; 306 *tstart = t; 307 while(!(t[0] == delim && t[1] == delim && t[2] == delim)) { 308 if(t[0] == ‘\0‘) { 309 longjmp(err, EXPECTED_END_OF_STRING); 310 } else if(t[0] == ‘\\‘) 311 t++; 312 t++; 313 } 314 *tend = t; 315 t+=3; 316 } else { 317 *tstart = ++t; 318 while(t[0] != delim) { 319 if(t[0] == ‘\0‘ || t[0] == ‘\n‘) { 320 longjmp(err, EXPECTED_END_OF_STRING); 321 } else if(t[0] == ‘\\‘) 322 t++; 323 t++; 324 } 325 *tend = t++; 326 } 327 tok = T_VALUE; 328 } else { 329 /* Unrecognized token */ 330 longjmp(err, BAD_SYMBOL); 331 } 332 } 333 334 *tp = t; 335 return tok; 336 } 337 338 static char *get_string(const char *tstart, const char *tend, jmp_buf err) 339 { 340 char *string, *s; 341 const char *i; 342 343 assert(tend > tstart); 344 string = (char*)malloc(tend - tstart + 1); 345 if(!string) 346 longjmp(err, OUT_OF_MEMORY); 347 348 for(i = tstart, s = string; i < tend; i++) { 349 if(i[0] == ‘\\‘) { 350 switch(*++i) { 351 case ‘\\‘: 352 case ‘\‘‘: 353 case ‘\"‘: *s++ = i[0]; break; 354 case ‘r‘: *s++ = ‘\r‘; break; 355 case ‘n‘: *s++ = ‘\n‘; break; 356 case ‘t‘: *s++ = ‘\t‘; break; 357 case ‘0‘: *s++ = ‘\0‘; break; 358 default: break; 359 } 360 } else { 361 *s++ = i[0]; 362 } 363 } 364 assert(s - string <= tend - tstart); 365 s[0] = ‘\0‘; 366 return string; 367 } 368 369 struct ini_file *ini_parse(const char *text, int *err, int *line) { 370 jmp_buf on_error; 371 int e_code; 372 373 struct ini_file *ini = NULL; 374 ini_section *cur_sec = NULL; 375 376 const char *tstart, *tend; 377 378 int t; 379 380 if(err) *err = SUCCESS; 381 if(line) *line = 1; 382 383 ini = make_ini(); 384 385 if((e_code = setjmp(on_error)) != 0) { 386 if(err) *err = e_code; 387 ini_free(ini); 388 return NULL; 389 } 390 391 while((t = get_token(&text, &tstart, &tend, line, on_error)) != T_END) { 392 if(t == ‘[‘) { 393 char *section_name; 394 if(get_token(&text, &tstart, &tend, line, on_error) != T_VALUE) { 395 longjmp(on_error, EMPTY_SECTION); 396 } 397 398 section_name = get_string(tstart, tend, on_error); 399 400 cur_sec = add_section(&ini->sections, section_name); 401 if(!cur_sec) 402 longjmp(on_error, OUT_OF_MEMORY); 403 404 if(get_token(&text, &tstart, &tend, line, on_error) != ‘]‘) { 405 longjmp(on_error, MISSING_END_BRACE); 406 } 407 408 } else if (t == T_VALUE ) { 409 char *par, *val; 410 par = get_string(tstart, tend, on_error); 411 t = get_token(&text, &tstart, &tend, line, on_error); 412 if(t != ‘=‘ && t != ‘:‘) { 413 longjmp(on_error, EXPECTED_EQUALS); 414 } 415 if(get_token(&text, &tstart, &tend, line, on_error) != T_VALUE) { 416 longjmp(on_error, EXPECTED_VALUE); 417 } 418 val = get_string(tstart, tend, on_error); 419 420 if(cur_sec) 421 add_pair(cur_sec, par, val); 422 else { 423 /* Add the parameter and value to the INI file‘s globals */ 424 ini_pair *pair; 425 if(!(pair = (ini_pair*)malloc(sizeof *pair))) 426 longjmp(on_error, OUT_OF_MEMORY); 427 428 pair->param = par; 429 pair->value = val; 430 431 pair->left = pair->right = NULL; 432 433 if(!ini->globals) 434 ini->globals = pair; 435 else 436 insert_pair(ini->globals, pair); 437 } 438 439 440 } else 441 longjmp(on_error, EXPECTED_PARAMETER); 442 } 443 444 return ini; 445 } 446 447 /** Printing functions ******************************************************/ 448 449 static void string_to_file(FILE *f, const char *s) { 450 fputc(‘\"‘, f); 451 for(; s[0]; s++) { 452 switch(s[0]) { 453 case ‘\n‘: fputs("\\n",f); break; 454 case ‘\r‘: fputs("\\r",f); break; 455 case ‘\t‘: fputs("\\t",f); break; 456 case ‘\"‘: fputs("\\\"",f); break; 457 case ‘\‘‘: fputs("\\\‘",f); break; 458 case ‘\\‘: fputs("\\\\",f); break; 459 default : fputc(s[0], f); break; 460 } 461 } 462 fputc(‘\"‘, f); 463 } 464 465 /* 466 * Recursively prints a tree of ini_pairs 467 */ 468 static void write_pair(ini_pair *p, FILE *f) { 469 if(!p) return; 470 471 string_to_file(f, p->param); 472 fputs(" = ", f); 473 string_to_file(f, p->value); 474 fputc(‘\n‘, f); 475 476 write_pair(p->left, f); 477 write_pair(p->right, f); 478 } 479 480 /* 481 * Recursively prints a tree of INI sections 482 */ 483 static void write_section(ini_section *s, FILE *f) { 484 if(!s) return; 485 486 fputs("\n[", f); 487 string_to_file(f, s->name); 488 fputs("]\n", f); 489 490 write_pair(s->fields, f); 491 492 /* The akward sequence is to ensure that values are not written sorted */ 493 494 write_section(s->left, f); 495 write_section(s->right, f); 496 } 497 498 /* 499 * Saves all the sections and parameters in an ini_file to a file. 500 * If fname is NULL, it is written to stdout. 501 */ 502 int ini_write(struct ini_file *ini, const char *fname) { 503 FILE *f; 504 505 if(fname) { 506 f = fopen(fname, "w"); 507 if(!f) 508 return ER_FOPEN; 509 } else 510 f = stdout; 511 512 write_pair(ini->globals, f); 513 write_section(ini->sections, f); 514 515 if(fname) 516 fclose(f); 517 518 return SUCCESS; 519 } 520 521 /****************************************************************************/ 522 523 int ini_has_section(struct ini_file *ini, const char *sec) { 524 return find_section(ini->sections, sec) != NULL; 525 } 526 527 /* 528 * Finds a specific parameter-value pair in the configuration file 529 */ 530 static ini_pair *find_param(const struct ini_file *ini, 531 const char *sec, 532 const char *par) { 533 ini_section *s; 534 ini_pair *p; 535 536 if(!ini) return NULL; 537 538 if(sec) { 539 s = find_section(ini->sections, sec); 540 if(!s) return NULL; 541 p = s->fields; 542 } else 543 p = ini->globals; 544 545 if(!p) return NULL; 546 547 return find_pair(p, par); 548 } 549 550 /* 551 * Retrieves a parameter ‘par‘ from a section ‘sec‘ within the ini_file ‘ini‘ 552 * and returns its value. 553 * If ‘sec‘ is NULL, the global parameters ini ‘ini‘ are searched. 554 * If the value is not found, ‘def‘ is returned. 555 * It returns a string. Functions like atoi(), atof(), strtol() and even 556 * sscanf() can be used to convert it to the relevant type. 557 */ 558 const char *ini_get(struct ini_file *ini, 559 const char *sec, 560 const char *par, 561 const char *def) { 562 ini_pair *p; 563 564 p = find_param(ini, sec, par); 565 if(!p) { 566 if(def) 567 ini_put(ini, sec, par, def); 568 return def; 569 } 570 571 return p->value; 572 } 573 574 /* 575 * Sets a parameter ‘par‘ in section ‘sec‘s value to ‘val‘, replacing the 576 * current value if it already exists, or creates the section if it does not 577 * exist 578 */ 579 int ini_put(struct ini_file *ini, const char *sec, const char *par, const char *val) { 580 ini_section *s; 581 ini_pair *p, **pp; 582 583 if(!ini || !val) return 0; 584 585 p = find_param(ini, sec, par); 586 if(p) { 587 /* Replace the existing value */ 588 char *t = p->value; 589 if(!(p->value = my_strdup(val))) { 590 p->value = t; 591 return 0; 592 } 593 594 free(t); 595 return 1; 596 } 597 598 if(sec) { 599 s = find_section(ini->sections, sec); 600 if(!s) { 601 /* Create a new section */ 602 if(!(s = (ini_section*)malloc(sizeof *s))) return 0; 603 if(!(s->name = my_strdup(sec))) { 604 free(s); 605 return 0; 606 } 607 608 s->fields = NULL; 609 s->left = s->right = NULL; 610 611 if(ini->sections) 612 insert_section(ini->sections, s); 613 else 614 ini->sections = s; 615 } 616 617 pp = &s->fields; 618 } else 619 pp = &ini->globals; 620 621 if(!(p = (ini_pair*)malloc(sizeof *p))) 622 return 0; 623 624 if(!(p->param = my_strdup(par)) || !(p->value = my_strdup(val))) { 625 free(p); 626 return 0; 627 } 628 629 p->left = p->right = NULL; 630 631 if(!*pp) 632 *pp = p; 633 else 634 insert_pair(*pp, p); 635 636 return 1; 637 } 638 639 /* 640 * ini_putf() takes a printf() style format string and uses vsnprintf() to 641 * pass a value to ini_put(). This function is intended for placing 642 * data types that are not strings into the ini_file 643 * 644 * The other parameters are the same as those of ini_put(). 645 */ 646 int ini_putf(struct ini_file *ini, 647 const char *sec, 648 const char *par, 649 const char *fmt, 650 ...) { 651 char buffer[MAX_LINE]; 652 va_list arg; 653 654 va_start(arg, fmt); 655 656 #ifdef _MSC_VER /* Microsoft Visual C++? */ 657 /* VC++ messes around with _‘s before vsnprintf(): */ 658 #define vsnprintf _vsnprintf 659 #endif 660 661 #if 1 662 vsnprintf(buffer, MAX_LINE, fmt, arg); 663 #else 664 vsprintf(buffer, fmt, arg ); 665 assert(strlen(buffer) < MAX_LINE); 666 #endif 667 va_end(arg); 668 669 return ini_put(ini, sec, par, buffer); 670 }
调用
1 static struct ini_file *gamedb = NULL; 2 BOOL CRobomoduleTestDlg::ResetConfig() 3 { 4 ini_put(gamedb, "System", "Half", "0"); 5 ini_put(gamedb, "InitialPose", "X", "0.0"); 6 ini_put(gamedb, "InitialPose", "Y", "0.0"); 7 ini_put(gamedb, "InitialPose", "theta", "0.0"); 8 9 ini_put(gamedb, "TilingUnit_Pose", "XTrans", "0.0"); 10 ini_put(gamedb, "TilingUnit_Pose", "YTrans", "0.0"); 11 ini_put(gamedb, "TilingUnit_Pose", "Height", "1.10"); 12 13 ini_put(gamedb, "Laser_TilingUnitO", "RotateX", "0.0"); 14 ini_put(gamedb, "Laser_TilingUnitO", "RotateY", "0.0"); 15 ini_put(gamedb, "Laser_TilingUnitO", "RotateZ", "0.785398163"); 16 17 ini_put(gamedb, "Laser_TilingUnitO", "TransformX", "0.165"); 18 ini_put(gamedb, "Laser_TilingUnitO", "TransformY", "0.0"); 19 ini_put(gamedb, "Laser_TilingUnitO", "TransformZ", "0.0"); 20 21 ini_put(gamedb, "LaserO", "CalibRotateX", "-0.023289177"); 22 ini_put(gamedb, "LaserO", "CalibRotateY", "0.0"); 23 ini_put(gamedb, "LaserO", "CalibRotateZ", "-0.01573419"); 24 25 ini_put(gamedb, "LaserO", "CalibTransformX", "0.0"); 26 ini_put(gamedb, "LaserO", "CalibTransformY", "0.0"); 27 ini_put(gamedb, "LaserO", "CalibTransformZ", "0.0"); 28 29 char buffer[256]; 30 _snprintf(buffer, sizeof buffer, "%s/%s", "D:", "config.ini"); 31 32 int result = ini_write(gamedb,"config.ini"); 33 ini_free(gamedb); 34 35 gamedb=NULL ; 36 return TRUE; 37 } 38 39 BOOL CRobomoduleTestDlg::OnInitDialog() 40 { 41 CDialog::OnInitDialog(); 42 ini_free(gamedb); 43 gamedb = ini_read(NULL, NULL, NULL); 44 int err, line; 45 ini_free(gamedb); 46 gamedb = ini_read("config.ini", &err, &line); 47 if(ini_get(gamedb,"InitialPose", "X", NULL) != NULL) 48 { 49 const char* a=ini_get(gamedb, "InitialPose", "X", NULL); 50 InitialPoseX= atof(a); 51 } 52 if(ini_get(gamedb,"InitialPose", "Y", NULL) != NULL) 53 { 54 const char* a=ini_get(gamedb, "InitialPose", "Y", NULL); 55 InitialPoseY= atof(a); 56 } 57 if(ini_get(gamedb,"InitialPose", "theta", NULL) != NULL) 58 { 59 const char* a=ini_get(gamedb, "InitialPose", "theta", NULL); 60 InitialPoseTheta= atof(a); 61 } 62 if(ini_get(gamedb,"TilingUnit_Pose", "XTrans", NULL) != NULL) 63 { 64 const char* a=ini_get(gamedb, "TilingUnit_Pose", "XTrans", NULL); 65 XTrans= atof(a); 66 } 67 if(ini_get(gamedb,"TilingUnit_Pose", "YTrans", NULL) != NULL) 68 { 69 const char* a=ini_get(gamedb, "TilingUnit_Pose", "YTrans", NULL); 70 YTrans= atof(a); 71 } 72 if(ini_get(gamedb,"TilingUnit_Pose", "Height", NULL) != NULL) 73 { 74 const char* a=ini_get(gamedb, "TilingUnit_Pose", "Height", NULL); 75 Height= atof(a); 76 } 77 if(ini_get(gamedb,"Laser_TilingUnitO", "RotateX", NULL) != NULL) 78 { 79 const char* b=ini_get(gamedb, "Laser_TilingUnitO", "RotateX", NULL); 80 RotateX= atof(b); 81 } 82 if(ini_get(gamedb,"Laser_TilingUnitO", "RotateY", NULL) != NULL) 83 { 84 const char* a=ini_get(gamedb, "Laser_TilingUnitO", "RotateY", NULL); 85 RotateY= atof(a); 86 } 87 if(ini_get(gamedb,"Laser_TilingUnitO", "RotateZ", NULL) != NULL) 88 { 89 const char* a=ini_get(gamedb, "Laser_TilingUnitO", "RotateZ", NULL); 90 RotateZ= atof(a); 91 } 92 if(ini_get(gamedb,"Laser_TilingUnitO", "TransformX", NULL) != NULL) 93 { 94 const char* a=ini_get(gamedb, "Laser_TilingUnitO", "TransformX", NULL); 95 TransformX= atof(a); 96 } 97 if(ini_get(gamedb,"Laser_TilingUnitO", "TransformY", NULL) != NULL) 98 { 99 const char* a=ini_get(gamedb, "Laser_TilingUnitO", "TransformY", NULL); 100 TransformY= atof(a); 101 } 102 if(ini_get(gamedb,"Laser_TilingUnitO", "TransformZ", NULL) != NULL) 103 { 104 const char* a=ini_get(gamedb, "Laser_TilingUnitO", "TransformZ", NULL); 105 TransformZ= atof(a); 106 } 107 if(ini_get(gamedb,"LaserO", "CalibRotateX", NULL) != NULL) 108 { 109 const char* a=ini_get(gamedb, "LaserO", "CalibRotateX", NULL); 110 CalibRotateX= atof(a); 111 } 112 if(ini_get(gamedb,"LaserO", "CalibRotateY", NULL) != NULL) 113 { 114 const char* a=ini_get(gamedb, "LaserO", "CalibRotateY", NULL); 115 CalibRotateY= atof(a); 116 } 117 if(ini_get(gamedb,"LaserO", "CalibRotateZ", NULL) != NULL) 118 { 119 const char* a=ini_get(gamedb, "LaserO", "CalibRotateZ", NULL); 120 CalibRotateZ= atof(a); 121 } 122 if(ini_get(gamedb,"LaserO", "CalibTransformX", NULL) != NULL) 123 { 124 const char* a=ini_get(gamedb, "LaserO", "CalibTransformX", NULL); 125 CalibTransformX= atof(a); 126 } 127 if(ini_get(gamedb,"LaserO", "CalibTransformY", NULL) != NULL) 128 { 129 const char* a=ini_get(gamedb, "LaserO", "CalibTransformY", NULL); 130 CalibTransformY= atof(a); 131 } 132 if(ini_get(gamedb,"LaserO", "CalibTransformZ", NULL) != NULL) 133 { 134 const char* a=ini_get(gamedb, "LaserO", "CalibTransformZ", NULL); 135 CalibTransformZ= atof(a); 136 } 137 if(ini_get(gamedb,"System", "Half", NULL) != NULL) 138 { 139 const char* a=ini_get(gamedb, "System", "Half", NULL); 140 useHalf= atof(a); 141 }
参考:https://github.com/wernsey/rengine/blob/master/src/ini.c
标签:global fputs eal should art utc span dialog pre
原文地址:http://www.cnblogs.com/yhlx125/p/6639881.html