]> cygwin.com Git - cygwin-apps/setup.git/blame - UserSettings.cc
* filemanip.cc (nt_wfopen): Only call nt_sec.SetPosixPerms if we have
[cygwin-apps/setup.git] / UserSettings.cc
CommitLineData
f26f525f
CF
1/* UserSettings.cc
2
3 Copyright (c) 2009, Christopher Faylor
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 A copy of the GNU General Public License can be found at http://www.gnu.org
11*/
12
ead15931
RC
13#include <stdio.h>
14#include <stdlib.h>
15#include <string.h>
ead15931 16#include "UserSettings.h"
f0fd8856
RC
17#include "io_stream.h"
18
f26f525f
CF
19class io_stream_key : public io_stream
20{
21 const char *key;
22 std::string buf;
23public:
24 io_stream_key (const char *);
25 ~io_stream_key ();
26 int set_mtime_and_mode (time_t, mode_t) {return 0;}
27 time_t get_mtime () {return 0;}
28 mode_t get_mode () {return 0;}
29 size_t get_size () {return 0;}
30 ssize_t read (void *buffer, size_t len) {return 0;}
31 ssize_t write (const void *buffer, size_t len) {return 0;}
32 ssize_t peek (void *buffer, size_t len) {return 0;}
33 long tell () {return 0;}
34 int seek (long, io_stream_seek_t) {return 0;}
35 int error () {return 0;}
36 void operator << (std::string);
37 void operator << (const char *);
38 friend io_stream *UserSettings::open (const char *);
39};
ead15931 40
f26f525f 41UserSettings *UserSettings::global;
ead15931 42
f26f525f
CF
43static char *
44trim (char *p)
ead15931 45{
f26f525f
CF
46 p += strspn (p, " \t");
47 char *q = strchr (p, '#');
48 if (q)
49 *q = '\0';
50 for (q = strchr (p, '\0') - 1; q >= p && (*q == ' ' || *q == '\t' || *q == '\r' || *q == '\n'); q--)
51 *q = '\0';
52 return p;
ead15931
RC
53}
54
f26f525f
CF
55inline void
56UserSettings::extend_table (ssize_t i)
ead15931 57{
f26f525f
CF
58 if (i < table_len)
59 return;
60 table_len = i + 100;
61 table = (Element **) realloc (table, sizeof (*table) * (table_len + 1));
62 table[i] = NULL;
ead15931
RC
63}
64
32049a60
CV
65#define isslash(c) ((c) == '\\' || (c) == '/')
66
f26f525f
CF
67io_stream *
68UserSettings::open_settings (const char *filename, std::string &pathname)
69{
70 pathname = "file://";
71 pathname += cwd;
32049a60
CV
72 if (!isslash (cwd[cwd.size () - 1]) && !isslash (filename[0]))
73 pathname += "/";
f26f525f
CF
74 pathname += filename;
75 io_stream *f = io_stream::open(pathname, "rt");
76 if (!f)
77 {
78 pathname = "cygfile:///etc/setup/";
79 pathname += filename;
80 f = io_stream::open (pathname, "rt");
81 }
82 return f;
83}
ead15931 84
f26f525f
CF
85UserSettings::UserSettings (std::string local_dir)
86 : table (NULL), table_len (-1), cwd (local_dir)
ead15931 87{
f26f525f
CF
88 global = this;
89 extend_table (0);
127febea 90 io_stream *f = open_settings ("setup.rc", filename);
f26f525f
CF
91
92 if (!f)
93 return;
94
95 size_t sz = f->get_size ();
96 char *buf = new char [sz + 2];
97 ssize_t szread = f->read (buf, sz);
98 delete f;
99
100 if (szread > 0)
101 {
102 buf[szread] = '\0';
103 buf[szread + 1] = '\0';
104 for (char *p = strtok (buf, "\n"); p; p = strtok (p, "\n"))
105 {
106 char *eol = strchr (p, '\0');
107 char *thiskey = trim (p);
108 if (!*thiskey)
109 {
110 p = eol + 1;
111 continue;
112 }
113 std::string thisval;
114 const char *nl = "";
115 while (*(p = eol + 1))
116 {
117 if (*p != ' ' && *p != '\t')
118 break;
119 eol = strchr (p, '\n');
120 if (eol)
121 *eol = '\0';
122 else
123 eol = strchr (p, '\0');
124 char *s = trim (p);
125 if (*s)
126 {
127 thisval += nl;
128 thisval += s;
129 nl = "\n";
130 }
131 }
132 set (thiskey, thisval);
133 }
134 }
135 delete buf;
ead15931
RC
136}
137
f26f525f
CF
138unsigned int
139UserSettings::get_index (const char *key)
ead15931 140{
f26f525f
CF
141 unsigned int i;
142 for (i = 0; table[i]; i++)
143 if (strcmp (key, table[i]->key) == 0)
144 break;
145 return i;
ead15931 146}
bf137801 147
f26f525f
CF
148const char *
149UserSettings::get (const char *key)
bf137801 150{
f26f525f
CF
151 unsigned int i = get_index (key);
152 if (table[i])
153 return table[i]->value;
154
155 std::string path;
156 io_stream *f = open_settings (key, path);
157 if (!f)
158 return NULL;
159
160 size_t sz = f->get_size ();
161 char *buf = new char [sz + 2];
162 ssize_t szread = f->read (buf, sz);
163 delete f;
164
165 if (szread < 0)
166 return NULL;
167
168 buf[szread] = '\0';
169 buf[szread + 1] = '\0';
170 std::string thisval;
171 const char *nl = "";
172 char *p = buf;
173 while (*p)
174 {
175 char *eol = strchr (p, '\n');
176 if (eol)
177 *eol = '\0';
178 else
179 eol = strchr (p, '\0');
180 const char *s = trim (p);
181 if (*s)
182 {
183 thisval += nl;
184 thisval += s;
185 nl = "\n";
186 }
187 p = eol + 1;
188 }
189
190 const char *outval = set (key, thisval);
191 delete buf;
192 return outval;
193}
194
195const char *
196UserSettings::set (const char *key, const char *val)
197{
198 ssize_t i = get_index (key);
199 if (table[i])
200 {
201 free ((void *) table[i]->key);
202 free ((void *) table[i]->value);
203 }
204 else
205 {
206 extend_table (i);
207 table[i] = new Element ();
208 table[i + 1] = NULL;
209 }
210 table[i]->key = strdup (key);
211 table[i]->value = strdup (val);
212 return table[i]->value;
bf137801
RC
213}
214
215void
f26f525f 216UserSettings::save ()
bf137801 217{
f26f525f
CF
218 io_stream *f = io_stream::open(filename, "wb");
219 if (!f)
220 return;
221 for (Element **e = table; *e; e++)
222 {
223 f->write ((*e)->key, strlen ((*e)->key));
224 f->write ("\n", 1);
225 std::string s = (*e)->value;
226 s.append ("\n");
227 size_t n;
228 for (int i = 0; (n = s.find_first_of ('\n', i)) != std::string::npos; i = n + 1)
229 {
230 std::string elem = s.substr (i, 1 + n - i);
231 f->write ("\t", 1);
232 f->write (elem.c_str (), elem.length ());
233 }
234 }
235 delete f;
bf137801 236}
f0fd8856
RC
237
238io_stream *
f26f525f 239UserSettings::open (const char *key)
f0fd8856 240{
f26f525f
CF
241 io_stream *f = new io_stream_key (key);
242 return f;
f0fd8856
RC
243}
244
f26f525f
CF
245io_stream_key::io_stream_key (const char *in_key)
246 : key (in_key), buf ("")
f0fd8856 247{
f26f525f 248}
f0fd8856 249
f26f525f
CF
250void
251io_stream_key::operator << (std::string in)
252{
253 buf += in;
254 buf += "\n";
255}
256
257void
258io_stream_key::operator << (const char *in)
259{
260 std::string s = in;
261 *this << s;
262}
263
264io_stream_key::~io_stream_key ()
265{
266 if (buf.length() > 0 && buf[buf.length () - 1] == '\n')
267 buf.resize (buf.length () - 1);
268 UserSettings::instance().set (key, buf);
f0fd8856 269}
This page took 0.06313 seconds and 5 git commands to generate.