Imported gammu 0.90.7
[gammu.git] / common / misc / cfg.c
blob824de7008e911b00b3eb0cafa9ea993a8de1b901
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <ctype.h>
6 #include <errno.h>
7 #ifndef __OpenBSD__
8 # include <wchar.h>
9 # include <wctype.h>
10 #endif
12 #include "../config.h"
13 #include "coding/coding.h"
14 #include "cfg.h"
15 #include "misc.h"
17 /*
18 * Read information from file in Windows INI format style
20 INI_Section *INI_ReadFile(char *FileName, bool Unicode)
22 FILE *f;
23 bool FFEEUnicode=false;
24 int level = -1, buffer1used, buffer2used, bufferused, i, buffused=1000,buffread=1000;
25 unsigned char ch[3], *buffer = NULL, *buffer1 = NULL, *buffer2 = NULL;
26 unsigned char buff[1000];
27 INI_Section *INI_info = NULL, *INI_head = NULL, *heading;
28 INI_Entry *entry;
30 f = fopen(FileName,"rb");
31 if (f == NULL) return NULL;
33 while(1) {
34 /* We read one line from file */
35 bufferused = 0;
36 while (1) {
37 if (buffused == buffread) {
38 buffused = fread(buff,1,1000,f);
39 buffread = 0;
40 if (buffused == 0) {
41 free(buffer); free(buffer1); free(buffer2);
42 fclose(f);
43 return INI_head;
46 if (Unicode) {
47 ch[0] = buff[buffread++];
48 if (buffused == buffread) continue;
49 ch[1] = buff[buffread++];
50 if (buffused == buffread) continue;
51 if (level == -1) {
52 if (ch[0] == 0xFF && ch[1] == 0xFE) FFEEUnicode = true;
53 level = 0;
54 continue;
56 if (FFEEUnicode) {
57 ch[2] = ch[0]; ch[0] = ch[1]; ch[1] = ch[2];
59 } else {
60 ch[0] = 0;
61 ch[1] = buff[buffread++];
62 if (buffused == buffread) continue;
63 if (level == -1) level = 0;
65 if ((ch[0] == 0 && ch[1] == 13) ||
66 (ch[0] == 0 && ch[1] == 10)) {
67 break;
69 buffer = realloc(buffer,bufferused+2);
70 buffer[bufferused] = ch[0];
71 buffer[bufferused+1] = ch[1];
72 bufferused = bufferused + 2;
74 // printf("line \"%s\"\n",DecodeUnicodeConsole(buffer));
76 buffer1used = 0;
77 buffer2used = 0;
78 if (level == 1) level = 0;
79 if (level == 3 || level == 4 || level == 5) level = 2;
81 /* We parse read line */
82 for (i=0;i<bufferused/2;i++) {
83 ch[0] = buffer[i*2];
84 ch[1] = buffer[i*2+1];
85 if (level == 0) { //search for name of section
86 if (ch[0] == 0 && ch[1] == '[') level = 1;
87 if (ch[0] == 0 && ch[1] == ';') break;
88 if (ch[0] == 0 && ch[1] == '#') break;
89 continue;
91 if (level == 1) { //section name
92 if (ch[0] == 0 && ch[1] == ']') {
93 if (buffer1used == 0) break;
94 if (Unicode) {
95 buffer1 = realloc(buffer1,buffer1used+2);
96 buffer1[buffer1used] = 0;
97 buffer1[buffer1used+1] = 0;
98 buffer1used = buffer1used + 2;
99 } else {
100 buffer1 = realloc(buffer1,buffer1used+1);
101 buffer1[buffer1used] = 0x00;
102 buffer1used = buffer1used + 1;
104 heading = (INI_Section *)malloc(sizeof(*heading));
105 if (heading == NULL) {
106 free(buffer); free(buffer1); free(buffer2);
107 fclose(f);
108 return NULL;
110 heading->SectionName = (char *)malloc(buffer1used);
111 memcpy(heading->SectionName,buffer1,buffer1used);
112 heading->Prev = INI_info;
113 heading->Next = NULL;
114 if (INI_info != NULL) {
115 INI_info->Next = heading;
116 } else {
117 INI_head = heading;
119 INI_info = heading;
120 INI_info->SubEntries = NULL;
121 level = 2;
122 // printf("[%s]\n",DecodeUnicodeConsole(buffer1));
123 break;
125 if (Unicode) {
126 buffer1 = realloc(buffer1,buffer1used+2);
127 buffer1[buffer1used] = ch[0];
128 buffer1[buffer1used+1] = ch[1];
129 buffer1used = buffer1used + 2;
130 } else {
131 buffer1 = realloc(buffer1,buffer1used+1);
132 buffer1[buffer1used] = ch[1];
133 buffer1used = buffer1used + 1;
135 continue;
137 if (level == 2) { //search for key name
138 if (ch[0] == 0 && ch[1] == ';') break;
139 if (ch[0] == 0 && ch[1] == '#') break;
140 if (ch[0] == 0 && ch[1] == '[') {
141 level = 1;
142 continue;
144 if (Unicode) {
145 if (myiswspace(ch)) continue;
146 } else {
147 if (isspace((int) ch[1])) continue;
149 level = 3;
151 if (level == 3) { //key name
152 if (ch[0] == 0 && ch[1] == '=') {
153 if (buffer1used == 0) break;
154 while(1) {
155 if (Unicode) {
156 if (!myiswspace(buffer1+(buffer1used-2))) break;
157 buffer1used = buffer1used - 2;
158 } else {
159 if (!isspace((int)buffer1[buffer1used-1])) break;
160 buffer1used = buffer1used - 1;
163 level = 4;
164 continue;
166 if (Unicode) {
167 buffer1 = realloc(buffer1,buffer1used+2);
168 buffer1[buffer1used] = ch[0];
169 buffer1[buffer1used+1] = ch[1];
170 buffer1used = buffer1used + 2;
171 } else {
172 buffer1 = realloc(buffer1,buffer1used+1);
173 buffer1[buffer1used] = ch[1];
174 buffer1used = buffer1used + 1;
177 if (level == 4) { //search for key value
178 if (Unicode) {
179 if (myiswspace(ch)) continue;
180 } else {
181 if (isspace((int) ch[1])) continue;
183 level = 5;
185 if (level == 5) { //key value
186 if (Unicode) {
187 buffer2 = realloc(buffer2,buffer2used+2);
188 buffer2[buffer2used] = ch[0];
189 buffer2[buffer2used+1] = ch[1];
190 buffer2used = buffer2used + 2;
191 } else {
192 buffer2 = realloc(buffer2,buffer2used+1);
193 buffer2[buffer2used] = ch[1];
194 buffer2used = buffer2used + 1;
198 if (level == 5) {
199 if (buffer2used == 0) continue;
201 entry = (INI_Entry *)malloc(sizeof(*entry));
202 if (entry == NULL) {
203 free(buffer); free(buffer1); free(buffer2);
204 fclose(f);
205 return NULL;
207 if (Unicode) {
208 buffer1 = realloc(buffer1,buffer1used+2);
209 buffer1[buffer1used] = 0;
210 buffer1[buffer1used+1] = 0;
211 buffer1used = buffer1used + 2;
212 buffer2 = realloc(buffer2,buffer2used+2);
213 buffer2[buffer2used] = 0;
214 buffer2[buffer2used+1] = 0;
215 buffer2used = buffer2used + 2;
216 } else {
217 buffer1 = realloc(buffer1,buffer1used+1);
218 buffer1[buffer1used] = 0x00;
219 buffer1used = buffer1used + 1;
220 buffer2 = realloc(buffer2,buffer2used+1);
221 buffer2[buffer2used] = 0x00;
222 buffer2used = buffer2used + 1;
224 // printf("\"%s\"=\"%s\"\n",buffer1,buffer2);
225 // printf("\"%s\"=",DecodeUnicodeConsole(buffer1));
226 // printf("\"%s\"\n",DecodeUnicodeConsole(buffer2));
228 entry->EntryName = (char *)malloc(buffer1used);
229 memcpy(entry->EntryName,buffer1,buffer1used);
231 entry->EntryValue = (char *)malloc(buffer2used);
232 memcpy(entry->EntryValue,buffer2,buffer2used);
234 entry->Prev = NULL;
235 entry->Next = INI_info->SubEntries;
236 if (INI_info->SubEntries != NULL) INI_info->SubEntries->Prev = entry;
237 INI_info->SubEntries = entry;
240 free(buffer); free(buffer1); free(buffer2);
241 fclose(f);
242 return INI_head;
246 * Search for key value in file in Windows INI format style
247 * Returns found value or NULL
249 unsigned char *INI_GetValue(INI_Section *cfg, unsigned char *section, unsigned char *key, bool Unicode)
251 INI_Section *h;
252 INI_Entry *e;
254 if (cfg == NULL || section == NULL || key == NULL) return NULL;
256 if (Unicode) {
257 /* Search for section */
258 for (h = cfg; h != NULL; h = h->Next) {
259 if (mywstrncasecmp(section, h->SectionName, 0)) {
260 /* Search for key inside section */
261 for (e = h->SubEntries; e != NULL; e = e->Next) {
262 if (mywstrncasecmp(key,e->EntryName,0)) {
263 return e->EntryValue;
268 } else {
269 /* Search for section */
270 for (h = cfg; h != NULL; h = h->Next) {
271 // printf("[%s]\n",h->SectionName);
272 if (mystrncasecmp(section, h->SectionName, 0)) {
273 /* Search for key inside section */
274 for (e = h->SubEntries; e != NULL; e = e->Next) {
275 // printf("\"%s\"=\"%s\"\n",e->EntryName,e->EntryValue);
276 if (mystrncasecmp(key, e->EntryName, 0)) {
277 return e->EntryValue;
283 return NULL;
286 /* Return last value in specified section */
287 INI_Entry *INI_FindLastSectionEntry(INI_Section *file_info, unsigned char *section, bool Unicode)
289 INI_Section *h;
290 INI_Entry *e;
292 e = NULL;
293 /* First find our section */
294 for (h = file_info; h != NULL; h = h->Next) {
295 if (Unicode) {
296 if (mywstrncasecmp(section, h->SectionName, 0)) {
297 e = h->SubEntries;
298 break;
300 } else {
301 if (mystrncasecmp(section, h->SectionName, 0)) {
302 e = h->SubEntries;
303 break;
307 /* Goes into last value in section */
308 while (1) {
309 if (e == NULL) break;
310 if (e->Next != NULL) {
311 e = e->Next;
312 } else break;
314 return e;
317 /* How should editor hadle tabs in this file? Add editor commands here.
318 * vim: noexpandtab sw=8 ts=8 sts=8: