![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
32x64 3-color message board http://elektorembedded.blogspot.com/
Embed:
(wiki syntax)
Show/hide line numbers
ini.c
00001 /* inih -- simple .INI file parser 00002 00003 inih is released under the New BSD license (see LICENSE.txt). Go to the project 00004 home page for more info: 00005 00006 http://code.google.com/p/inih/ 00007 00008 */ 00009 00010 #include <stdio.h> 00011 #include <ctype.h> 00012 #include <string.h> 00013 00014 #include "ini.h" 00015 00016 #define MAX_LINE 200 00017 #define MAX_SECTION 50 00018 #define MAX_NAME 50 00019 00020 /* Strip whitespace chars off end of given string, in place. Return s. */ 00021 static char* rstrip(char* s) 00022 { 00023 char* p = s + strlen(s); 00024 while (p > s && isspace(*--p)) 00025 *p = '\0'; 00026 return s; 00027 } 00028 00029 /* Return pointer to first non-whitespace char in given string. */ 00030 static char* lskip(const char* s) 00031 { 00032 while (*s && isspace(*s)) 00033 s++; 00034 return (char*)s; 00035 } 00036 00037 /* Return pointer to first char c or ';' in given string, or pointer to 00038 null at end of string if neither found. */ 00039 static char* find_char_or_comment(const char* s, char c) 00040 { 00041 while (*s && *s != c && *s != ';') 00042 s++; 00043 return (char*)s; 00044 } 00045 00046 /* Version of strncpy that ensures dest (size bytes) is null-terminated. */ 00047 static char* strncpy0(char* dest, const char* src, size_t size) 00048 { 00049 strncpy(dest, src, size); 00050 dest[size - 1] = '\0'; 00051 return dest; 00052 } 00053 00054 /* See documentation in header file. */ 00055 int ini_parse(const char* filename, 00056 int (*handler)(void*, const char*, const char*, const char*), 00057 void* user) 00058 { 00059 /* Uses a fair bit of stack (use heap instead if you need to) */ 00060 char line[MAX_LINE]; 00061 char section[MAX_SECTION] = ""; 00062 char prev_name[MAX_NAME] = ""; 00063 00064 FILE* file; 00065 char* start; 00066 char* end; 00067 char* name; 00068 char* value; 00069 int lineno = 0; 00070 int error = 0; 00071 00072 file = fopen(filename, "r"); 00073 if (!file) 00074 return -1; 00075 00076 /* Scan through file line by line */ 00077 while (fgets(line, sizeof(line), file) != NULL) { 00078 lineno++; 00079 start = lskip(rstrip(line)); 00080 00081 #if INI_ALLOW_MULTILINE 00082 if (*prev_name && *start && start > line) { 00083 /* Non-black line with leading whitespace, treat as continuation 00084 of previous name's value (as per Python ConfigParser). */ 00085 if (!handler(user, section, prev_name, start) && !error) 00086 error = lineno; 00087 } 00088 else 00089 #endif 00090 if (*start == '[') { 00091 /* A "[section]" line */ 00092 end = find_char_or_comment(start + 1, ']'); 00093 if (*end == ']') { 00094 *end = '\0'; 00095 strncpy0(section, start + 1, sizeof(section)); 00096 *prev_name = '\0'; 00097 } 00098 else if (!error) { 00099 /* No ']' found on section line */ 00100 error = lineno; 00101 } 00102 } 00103 else if (*start && *start != ';') { 00104 /* Not a comment, must be a name=value pair */ 00105 end = find_char_or_comment(start, '='); 00106 if (*end == '=') { 00107 *end = '\0'; 00108 name = rstrip(start); 00109 value = lskip(end + 1); 00110 end = find_char_or_comment(value, ';'); 00111 if (*end == ';') 00112 *end = '\0'; 00113 rstrip(value); 00114 00115 /* Valid name=value pair found, call handler */ 00116 strncpy0(prev_name, name, sizeof(prev_name)); 00117 if (!handler(user, section, name, value) && !error) 00118 error = lineno; 00119 } 00120 else if (!error) { 00121 /* No '=' found on name=value line */ 00122 error = lineno; 00123 } 00124 } 00125 } 00126 00127 fclose(file); 00128 00129 return error; 00130 }
Generated on Thu Jul 14 2022 01:11:21 by
![doxygen](doxygen.png)