source: Daodan/MSVC/inifile_reader.c @ 567

Last change on this file since 567 was 567, checked in by gumby, 11 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.