UDI/Tools - Moved udi* tools to UDI/ tree
[tpg/acess2.git] / UDI / Tools / src / inifile.c
1 /*
2  * udibuild - UDI Compilation Utility
3  * - By John Hodge (thePowersGang)
4  *
5  * inifile.c
6  * - .ini file parsing
7  */
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <assert.h>
12 #include <ctype.h>
13 #include "include/inifile.h"
14
15 typedef struct sInifile_Section tIniFile_Section;
16 typedef struct sInifile_Value   tIniFile_Value;
17
18 struct sInifile_Value
19 {
20         tIniFile_Value  *Next;
21         const char      *Key;
22         const char      *Value;
23 };
24
25 struct sInifile_Section
26 {
27         tIniFile_Section        *Next;
28         const char *Name;
29         tIniFile_Value  *FirstValue;
30 };
31
32 struct sInifile
33 {
34         tIniFile_Section        RootSection;
35 };
36
37 // === CODE ===
38 static void rtrim(char *str)
39 {
40         char *pos = str;
41         while( *pos )
42                 pos ++;
43         while( pos != str && isspace(pos[-1]) )
44                 *--pos = '\0';
45 }
46
47 tIniFile *IniFile_Load(const char *Path)
48 {
49         FILE    *fp = fopen(Path, "r");
50         if( !fp )
51                 return NULL;
52         
53         tIniFile        *ret = malloc( sizeof(tIniFile) );
54         assert(ret);
55
56         ret->RootSection.Name = "";
57         ret->RootSection.FirstValue = NULL;
58
59         tIniFile_Section        *curSect = &ret->RootSection;
60         char buf[512];
61         while( fgets(buf, sizeof(buf)-1, fp) )
62         {
63                 if( strchr(buf, '#') )
64                         *strchr(buf, '#') = '\0';
65                 rtrim(buf);
66                 char name[64];
67                 size_t ofs = 0;
68                 if( sscanf(buf, "[%[^]]]", name) == 1 ) {
69                         //printf("section %s\n", name);
70                         // new section
71                         tIniFile_Section *new_sect = malloc(sizeof(tIniFile_Section)+strlen(name)+1);
72                         new_sect->Next = NULL;
73                         new_sect->Name = (const char*)(new_sect+1);
74                         new_sect->FirstValue = NULL;
75                         strcpy( (char*)new_sect->Name, name );
76                         curSect->Next = new_sect;
77                         curSect = new_sect;
78                 }
79                 else if( sscanf(buf, "%[^=]=%n", name, &ofs) >= 1 ) {
80                         //printf("key %s equals %s\n", name, value);
81                         const char *value = buf + ofs;
82                         tIniFile_Value *val = malloc(sizeof(tIniFile_Value)+strlen(name)+1+strlen(value)+1);
83                         val->Next = curSect->FirstValue;
84                         curSect->FirstValue = val;
85                         
86                         val->Key = (char*)(val+1);
87                         strcpy((char*)val->Key, name);
88                         val->Value = val->Key + strlen(val->Key) + 1;
89                         strcpy((char*)val->Value, value);
90                 }
91                 else {
92                         //printf("ignore %s\n", buf);
93                         // ignore
94                 }
95         }
96
97         fclose(fp);     
98
99         return ret;
100 }
101
102 const char *IniFile_Get(tIniFile *File, const char *Sect, const char *Key, const char *Default)
103 {
104         tIniFile_Section        *sect;
105         for( sect = &File->RootSection; sect; sect = sect->Next )
106         {
107                 if( strcmp(sect->Name, Sect) == 0 )
108                         break;
109         }
110         if( !sect )
111                 return Default;
112         
113         tIniFile_Value  *val;
114         for( val = sect->FirstValue; val; val = val->Next )
115         {
116                 if( strcmp(val->Key, Key) == 0 )
117                         break;
118         }
119         if( !val )
120                 return Default;
121         
122         return val->Value;
123 }
124
125 void IniFile_Free(tIniFile *File)
126 {
127         // TODO:
128 }

UCC git Repository :: git.ucc.asn.au