source: Daodan/MSVC/inifile_reader.c@ 787

Last change on this file since 787 was 567, checked in by gumby, 14 years ago

Daodan MSVC

File size: 3.2 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include "bool.h"
4#include <string.h>
5#include <ctype.h>
6
7#include "inifile.h"
8
9char* inifile_cleanstr(char* str)
10{
11 int i;
12 for (i = strlen(str) - 1; i >= 0; i --)
13 if (isspace(str[i]))
14 str[i] = '\0';
15 else
16 break;
17
18 while (isspace(*str))
19 str++;
20
21 return str;
22}
23
24int64_t inifile_parseint(const char* str, bool issigned)
25{
26 int64_t ret = 0;
27 bool neg = false;
28 if (str[0] == '0' && str[1] == 'x')
29 {
30 int i;
31 if (str[2] == '\0')
32 return 0x100000000LL;
33
34 for (i = 0, str += 2; *str; i++, str++)
35 {
36 if (i == 8)
37 return 0x100000000LL;
38
39 ret <<= 4;
40 if (*str >= '0' && *str <= '9')
41 ret |= *str - '0';
42 else if (*str >= 'a' && *str <= 'f')
43 ret |= *str - 'a' + 10;
44 else if (*str >= 'A' && *str <= 'F')
45 ret |= *str - 'A' + 10;
46 else
47 return 0x100000000LL;
48 }
49 return ret;
50 }
51 else if ((*str >= '0' && *str <= '9') || (neg = (*str == '-')))
52 {
53 int i;
54 if (neg)
55 str++;
56 for (i = 0; *str; i++, str++)
57 {
58 if (i == 10)
59 return 0x100000000LL;
60 else if (i == 9 && !issigned && (ret > 429496729LL || (ret == 429496729LL && *str > '5')))
61 return 0x100000000LL;
62 else if (i == 9 && issigned && (ret > 214748364LL || (ret == 214748364LL && *str > (neg ? '8' : '7'))))
63 return 0x100000000LL;
64
65 ret *= 10;
66 if (*str >= '0' && *str <= '9')
67 ret += *str - '0';
68 else
69 return 0x100000000LL;
70 }
71 if (neg)
72 ret *= -1;
73 return ret;
74 }
75 else
76 return 0x100000000LL;
77}
78
79bool inifile_read(const char* filename, inifile_callback callback)
80{
81 FILE* fp = fopen(filename, "r");
82 char* inisection = "";
83 char readbuf[4096] = "";
84 char* readptr;
85 bool success = true;
86 bool newsection = false;
87
88 if (!fp)
89 return inifile_cantread;
90
91 while ((readptr = fgets(readbuf, sizeof(readbuf), fp))) // Loop through each line.
92 {
93 while (isspace(readptr[0])) // Skip whitespace.
94 readptr++;
95
96 if (readptr[0] == '\0' || readptr[0] == '#' || readptr[0] == '!') // Skip empty lines and comments.
97 continue;
98 else if (readptr[0] == '[' && readptr[1] != ']') // It's a section header.
99 {
100 int i;
101 for (i = 2; readptr[i]; i ++) // Look for the ]
102 if (readptr[i] == ']')
103 break;
104
105 if (readptr[i]) // Replace with a null or crash with error.
106 readptr[i] = '\0';
107 else
108 {
109 success = false;
110 break;
111 }
112
113 if (inisection[0])
114 free(inisection);
115 inisection = _strdup(readptr + 1); // Skip the first [
116 newsection = true;
117 }
118 else // It's a value.
119 {
120 int i;
121 int equals = 0;
122 for (i = 0; readptr[i]; i ++) // Find the =
123 if (readptr[i] == '=')
124 equals = i;
125
126 if (readptr[i - 1] == '\n')
127 readptr[i - 1] = '\0'; // Remove the trailing newline.
128
129 if (equals)
130 {
131 readptr[equals] = '\0';
132 if (!callback(inisection, newsection, readptr, readptr + equals + 1)) // If the callback is false, exit.
133 break;
134 newsection = false;
135 }
136 else // If there's no equals, crash with error.
137 {
138 success = false;
139 break;
140 }
141 }
142 }
143
144 if (inisection[0])
145 free(inisection);
146
147 fclose(fp);
148 return success;
149}
Note: See TracBrowser for help on using the repository browser.