Colour targets: Revert an optimisation from almost 18 months ago that actually turned...
[Rockbox.git] / apps / plugins / lib / configfile.c
blob4fb037cb8ed6a7a46678fc8fd8bb66470d8e1019
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 Linus Nielsen Feltzing
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
21 #include "plugin.h"
22 #include "configfile.h"
24 static const struct plugin_api *cfg_rb;
26 void configfile_init(const struct plugin_api* newrb)
28 cfg_rb = newrb;
31 static void get_cfg_filename(char* buf, int buf_len, const char* filename)
33 char *s;
34 cfg_rb->strcpy(buf, cfg_rb->plugin_get_current_filename());
35 s = cfg_rb->strrchr(buf, '/');
36 if (!s) /* should never happen */
38 cfg_rb->snprintf(buf, buf_len, PLUGIN_DIR "/%s", filename);
40 else
42 s++;
43 *s = '\0';
44 cfg_rb->strcat(s, filename);
48 int configfile_save(const char *filename, struct configdata *cfg,
49 int num_items, int version)
51 int fd;
52 int i;
53 char buf[MAX_PATH];
55 get_cfg_filename(buf, MAX_PATH, filename);
56 fd = cfg_rb->creat(buf);
57 if(fd < 0)
58 return fd*10 - 1;
60 /* pre-allocate 10 bytes for INT */
61 cfg_rb->fdprintf(fd, "file version: %10d\n", version);
63 for(i = 0;i < num_items;i++) {
64 switch(cfg[i].type) {
65 case TYPE_INT:
66 /* pre-allocate 10 bytes for INT */
67 cfg_rb->fdprintf(fd, "%s: %10d\n",
68 cfg[i].name,
69 *cfg[i].val);
70 break;
72 case TYPE_ENUM:
73 cfg_rb->fdprintf(fd, "%s: %s\n",
74 cfg[i].name,
75 cfg[i].values[*cfg[i].val]);
76 break;
78 case TYPE_STRING:
79 cfg_rb->fdprintf(fd, "%s: %s\n",
80 cfg[i].name,
81 cfg[i].string);
82 break;
87 cfg_rb->close(fd);
88 return 0;
91 int configfile_load(const char *filename, struct configdata *cfg,
92 int num_items, int min_version)
94 int fd;
95 int i, j;
96 char *name;
97 char *val;
98 char buf[MAX_PATH];
99 int file_version = -1;
100 int tmp;
102 get_cfg_filename(buf, MAX_PATH, filename);
103 fd = cfg_rb->open(buf, O_RDONLY);
104 if(fd < 0)
105 return fd*10 - 1;
107 while(cfg_rb->read_line(fd, buf, MAX_PATH) > 0) {
108 cfg_rb->settings_parseline(buf, &name, &val);
110 /* Bail out if the file version is too old */
111 if(!cfg_rb->strcmp("file version", name)) {
112 file_version = cfg_rb->atoi(val);
113 if(file_version < min_version) {
114 cfg_rb->close(fd);
115 return -1;
119 for(i = 0;i < num_items;i++) {
120 if(!cfg_rb->strcmp(cfg[i].name, name)) {
121 switch(cfg[i].type) {
122 case TYPE_INT:
123 tmp = cfg_rb->atoi(val);
124 /* Only set it if it's within range */
125 if(tmp >= cfg[i].min && tmp <= cfg[i].max)
126 *cfg[i].val = tmp;
127 break;
129 case TYPE_ENUM:
130 for(j = 0;j < cfg[i].max;j++) {
131 if(!cfg_rb->strcmp(cfg[i].values[j], val)) {
132 *cfg[i].val = j;
135 break;
137 case TYPE_STRING:
138 cfg_rb->strncpy(cfg[i].string, val, cfg[i].max);
139 break;
145 cfg_rb->close(fd);
146 return 0;
149 int configfile_get_value(const char* filename, const char* name)
151 int fd;
152 char *pname;
153 char *pval;
154 char buf[MAX_PATH];
156 get_cfg_filename(buf, MAX_PATH, filename);
157 fd = cfg_rb->open(buf, O_RDONLY);
158 if(fd < 0)
159 return -1;
161 while(cfg_rb->read_line(fd, buf, MAX_PATH) > 0)
163 cfg_rb->settings_parseline(buf, &pname, &pval);
164 if(!cfg_rb->strcmp(name, pname))
166 cfg_rb->close(fd);
167 return cfg_rb->atoi(pval);
171 cfg_rb->close(fd);
172 return -1;
175 int configfile_update_entry(const char* filename, const char* name, int val)
177 int fd;
178 char *pname;
179 char *pval;
180 char path[MAX_PATH];
181 char buf[256];
182 int found = 0;
183 int line_len = 0;
184 int pos = 0;
186 /* open the current config file */
187 get_cfg_filename(path, MAX_PATH, filename);
188 fd = cfg_rb->open(path, O_RDWR);
189 if(fd < 0)
190 return -1;
192 /* read in the current stored settings */
193 while((line_len = cfg_rb->read_line(fd, buf, 256)) > 0)
195 cfg_rb->settings_parseline(buf, &pname, &pval);
196 if(!cfg_rb->strcmp(name, pname))
198 found = 1;
199 cfg_rb->lseek(fd, pos, SEEK_SET);
200 /* pre-allocate 10 bytes for INT */
201 cfg_rb->fdprintf(fd, "%s: %10d\n", pname, val);
202 break;
204 pos += line_len;
207 /* if (name/val) is a new entry just append to file */
208 if (found == 0)
209 /* pre-allocate 10 bytes for INT */
210 cfg_rb->fdprintf(fd, "%s: %10d\n", name, val);
212 cfg_rb->close(fd);
214 return found;