Initial commit.
[liboconfig.git] / src / oconfig.c
1 /**
2  * octo's object oriented config library.
3  * Copyright (C) 2006  Florian octo Forster <octo at verplant.org>
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License, version 2, as published
7  * by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
17  */
18
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <assert.h>
23
24 #include "oconfig.h"
25
26 /*
27  * private structures
28  */
29 struct oconfig_obj
30 {
31         oconfig_item_obj_t *items;
32 };
33
34 struct oconfig_item_obj
35 {
36         char   *key;
37         char   *value;
38
39         oconfig_item_obj_t *child;
40         oconfig_item_obj_t *sibling;
41 };
42
43 /*
44  * private functions
45  */
46 static oconfig_item_obj_t *oconfig_item_alloc (const char *key, const char *value)
47 {
48         oconfig_item_obj_t *ret;
49
50         ret = calloc (1, sizeof (oconfig_item_obj_t));
51
52         if ((ret->key = strdup (key)) == NULL)
53         {
54                 free (ret);
55                 return (NULL);
56         }
57
58         if ((ret->value = strdup (value)) == NULL)
59         {
60                 free (ret->key);
61                 free (ret);
62                 return (NULL);
63         }
64
65         return (ret);
66 }
67
68 static void oconfig_item_free (oconfig_item_obj_t *item)
69 {
70         /* This temporary variable is used to prevent endless loops. They
71          * should not exist, but it doesn't cost much, so what the heck.. */
72         oconfig_item_obj_t *temp;
73
74         if (item->child != NULL)
75         {
76                 temp = item->child;
77                 item->child = NULL;
78                 oconfig_item_free (temp);
79         }
80
81         if (item->sibling != NULL)
82         {
83                 temp = item->sibling;
84                 item->sibling = NULL;
85                 oconfig_item_free (temp);
86         }
87
88         if (item->key != NULL)
89                 free (item->key);
90
91         if (item->value != NULL)
92                 free (item->value);
93
94         free (item);
95 }
96
97 static oconfig_item_obj_t *oconfig_item_parse_line (char *buffer)
98 {
99         char   *key;
100         char   *value;
101         size_t  value_len;
102
103         key = strtok (buffer, " \t\n\r");
104         if (key == NULL)
105                 return (NULL);
106
107         value = strtok (NULL, " \t\n\r");
108         if (value == NULL)
109                 return (NULL);
110
111         value_len = strlen (value);
112         while (value_len > 0)
113         {
114                 if ((value[value_len - 1] == ' ')
115                                 || (value[value_len - 1] == '\t')
116                                 || (value[value_len - 1] == '\n')
117                                 || (value[value_len - 1] == '\r'))
118                 {
119                         value[value_len - 1] = '\0';
120                         value_len--;
121                         continue;
122                 }
123
124                 break;
125         }
126
127         if (value_len == 0)
128                 return (NULL);
129
130         return (oconfig_item_alloc (key, value));
131 }
132
133 /*
134  * constructor and destructor
135  */
136 oconfig_obj_t *oconfig_construct (const char *file)
137 {
138         oconfig_obj_t *ret;
139
140         ret = calloc (1, sizeof (oconfig_obj_t));
141
142         /* FIXME: Implement the actual functionality */
143
144         return (ret);
145 }
146
147 void oconfig_destroy (oconfig_obj_t *obj)
148 {
149         assert (obj != NULL);
150
151         if (obj->items != NULL)
152                 oconfig_item_free (obj->items);
153
154         free (obj);
155 }
156
157 /*
158  * public methods
159  */
160 oconfig_item_obj_t *oconfig_item_get (oconfig_obj_t *obj);
161 oconfig_item_obj_t *oconfig_item_get_child (oconfig_item_obj_t *item);
162 oconfig_item_obj_t *oconfig_item_get_sibling (oconfig_item_obj_t *item);
163
164 const char *oconfig_item_get_key (oconfig_item_obj_t *);
165 size_t      oconfig_item_get_value (oconfig_item_obj_t *, void *buffer, size_t *buffer_size);