00001
00025 #include <ctype.h>
00026 #include <stdio.h>
00027 #include <stdlib.h>
00028 #include <string.h>
00029 #include "keyfile.h"
00030
00032 typedef struct _keyval {
00033 char *key;
00034 char *val;
00035 void *next;
00036 } KeyVal;
00037
00038 KeyVal *kv_add(KeyVal * kv, char *k, char *v);
00039 void kv_free(KeyVal * kv);
00040 char *kv_getval(KeyVal * kv, char *k);
00041 KeyVal *kv_new(char *k, char *v);
00042 void kv_setval(KeyVal * kv, char *k, char *v);
00043
00044
00045 char *kf_getvalue(void *kf, char *k);
00046 void kf_load(void *kf, char *fn);
00047 void *kf_new(char sep);
00048 void kf_save(void *kf, char *fn);
00049 void kf_setvalue(void *kf, char *k, char *v);
00050 char *trim(char *s);
00051
00052
00055 KeyVal *kv_add(KeyVal * kv, char *k, char *v)
00056 {
00057
00058 if (!kv)
00059 return kv_new(k, v);
00060
00061
00062 if (kv->next)
00063 return kv_add(kv->next, k, v);
00064
00065
00066 kv->next = kv_new(k, v);
00067 return kv;
00068 }
00069
00071 void kv_free(KeyVal * kv)
00072 {
00073 if (!kv)
00074 return;
00075
00076 if (kv->next)
00077 kv_free(kv->next);
00078
00079 if (kv) {
00080 if (kv->key)
00081 free(kv->key);
00082 if (kv->val)
00083 free(kv->val);
00084 free(kv);
00085 }
00086 }
00087
00090 char *kv_getval(KeyVal * kv, char *k)
00091 {
00092 if (!kv)
00093 return NULL;
00094
00095 if (strcmp(kv->key, k) == 0)
00096 return kv->val;
00097 else if (kv->next)
00098 return kv_getval(kv->next, k);
00099
00100 return NULL;
00101 }
00102
00103
00105 KeyVal *kv_new(char *k, char *v)
00106 {
00107 KeyVal *kv = malloc(sizeof(KeyVal));
00108 if (kv) {
00109 kv->key = k;
00110 kv->val = v;
00111 kv->next = NULL;
00112 }
00113 return kv;
00114 }
00115
00117 void kv_setval(KeyVal * kv, char *k, char *v)
00118 {
00119 if (!kv)
00120 return;
00121
00122 if (strcmp(kv->key, k) == 0) {
00123 if (kv->val)
00124 free(kv->val);
00125 kv->val = strdup(v);
00126 return;
00127 }
00128
00129 if (kv->next)
00130 kv_setval(kv->next, k, v);
00131 else
00132 kv_add(kv, k, v);
00133 }
00134
00136 void kv_write(KeyVal * kv, char sep, FILE * f)
00137 {
00138 if (!kv)
00139 return;
00140
00141 if (kv->key) {
00142 if (kv->val)
00143 fprintf(f, "%s%c%s\n", kv->key, sep, kv->val);
00144 else
00145 fprintf(f, "%s\n", kv->key);
00146 }
00147 else
00148 fprintf(f, "\n");
00149
00150 if (kv->next)
00151 kv_write(kv->next, sep, f);
00152 }
00153
00155 typedef struct _keyfile {
00156 int changed;
00157 char separator;
00158 KeyVal *keys;
00159 } KeyFile;
00160
00162 char *kf_getvalue(void *kf, char *k)
00163 {
00164 KeyFile *kff = (KeyFile *) kf;
00165 if (!kff)
00166 return NULL;
00167
00168 return kv_getval(kff->keys, k);
00169 }
00170
00172 void kf_load(void *kf, char *fn)
00173 {
00174 char *p;
00175 FILE *f;
00176 char *s;
00177 char buf[2048];
00178 KeyFile *kff = (KeyFile *) kf;
00179 if (!kff)
00180 return;
00181
00182 f = fopen(fn, "r+");
00183 while (fgets(buf, sizeof(buf), f)) {
00184 p = strchr(buf, kff->separator);
00185 if (p) {
00186 *p = '\0';
00187 s = trim(buf);
00188 *p = kff->separator;
00189 p++;
00190 p = trim(p);
00191 kff->keys = kv_add(kff->keys, s, p);
00192 free(p);
00193 free(s);
00194 }
00195 else {
00196 kff->keys = kv_add(kff->keys, buf, NULL);
00197 }
00198 }
00199 fclose(f);
00200 kff->changed = 0;
00201 }
00202
00204 void *kf_new(char sep)
00205 {
00206 KeyFile *kf = malloc(sizeof(KeyFile));
00207 if (kf) {
00208 kf->changed = 0;
00209 kf->separator = sep;
00210 kf->keys = NULL;
00211 }
00212 return kf;
00213 }
00214
00216 void kf_save(void *kf, char *fn)
00217 {
00218 FILE *f;
00219 KeyFile *kff = (KeyFile *) kf;
00220 if (!kff)
00221 return;
00222
00223 f = fopen(fn, "w");
00224 kv_write(kff->keys, kff->separator, f);
00225 fclose(f);
00226 kff->changed = 0;
00227 }
00228
00230 void kf_setvalue(void *kf, char *k, char *v)
00231 {
00232 KeyFile *kff = (KeyFile *) kf;
00233 if (!kff)
00234 return;
00235
00236 kv_setval(kff->keys, k, v);
00237 }
00238
00240 char *trim(char *s)
00241 {
00242 char *end;
00243 char *start = s;
00244
00245 while (isspace(*start) && (*start != '\0')) {
00246 start++;
00247 }
00248 end = start;
00249
00250 while (*end != '\0')
00251 end++;
00252
00253
00254 while ((isspace(*end)) && (end >= start))
00255 *end = '\0';
00256
00257 return strdup(start);
00258 }