]> cygwin.com Git - cygwin-apps/setup.git/blame - UserSettings.cc
Use solver to check for problems and produce a list of package transactions
[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>
f882d56e 16#include <memory>
ead15931 17#include "UserSettings.h"
f0fd8856 18#include "io_stream.h"
4d10ec8c 19#include "win32.h"
f0fd8856 20
f26f525f
CF
21class io_stream_key : public io_stream
22{
23 const char *key;
24 std::string buf;
25public:
26 io_stream_key (const char *);
27 ~io_stream_key ();
26922cd2 28 int set_mtime(time_t) {return 0;}
f26f525f
CF
29 time_t get_mtime () {return 0;}
30 mode_t get_mode () {return 0;}
31 size_t get_size () {return 0;}
32 ssize_t read (void *buffer, size_t len) {return 0;}
33 ssize_t write (const void *buffer, size_t len) {return 0;}
34 ssize_t peek (void *buffer, size_t len) {return 0;}
35 long tell () {return 0;}
36 int seek (long, io_stream_seek_t) {return 0;}
37 int error () {return 0;}
38 void operator << (std::string);
39 void operator << (const char *);
40 friend io_stream *UserSettings::open (const char *);
41};
ead15931 42
f26f525f 43UserSettings *UserSettings::global;
ead15931 44
55ea101d 45// '#' indicates a comment if it's the first non-whitespace character.
f26f525f
CF
46static char *
47trim (char *p)
ead15931 48{
f26f525f 49 p += strspn (p, " \t");
55ea101d
KB
50 if (*p == '#')
51 *p = '\0';
52 for (char *q = strchr (p, '\0') - 1; q >= p && (*q == ' ' || *q == '\t' || *q == '\r' || *q == '\n'); q--)
f26f525f
CF
53 *q = '\0';
54 return p;
ead15931
RC
55}
56
f26f525f
CF
57inline void
58UserSettings::extend_table (ssize_t i)
ead15931 59{
f26f525f
CF
60 if (i < table_len)
61 return;
62 table_len = i + 100;
63 table = (Element **) realloc (table, sizeof (*table) * (table_len + 1));
64 table[i] = NULL;
ead15931
RC
65}
66
f26f525f
CF
67io_stream *
68UserSettings::open_settings (const char *filename, std::string &pathname)
69{
70 pathname = "file://";
71 pathname += cwd;
4d10ec8c 72 if (!isdirsep (cwd[cwd.size () - 1]) && !isdirsep (filename[0]))
32049a60 73 pathname += "/";
f26f525f 74 pathname += filename;
26922cd2 75 io_stream *f = io_stream::open(pathname, "rt", 0);
f26f525f
CF
76 if (!f)
77 {
78 pathname = "cygfile:///etc/setup/";
79 pathname += filename;
26922cd2 80 f = io_stream::open (pathname, "rt", 0);
f26f525f
CF
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 ();
f882d56e
CV
96 std::unique_ptr<char[]> buf (new char [sz + 2]);
97 ssize_t szread = f->read (buf.get (), sz);
f26f525f
CF
98 delete f;
99
100 if (szread > 0)
101 {
102 buf[szread] = '\0';
103 buf[szread + 1] = '\0';
f882d56e 104 for (char *p = strtok (buf.get (), "\n"); p; p = strtok (p, "\n"))
f26f525f
CF
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 }
ead15931
RC
135}
136
f26f525f
CF
137unsigned int
138UserSettings::get_index (const char *key)
ead15931 139{
f26f525f
CF
140 unsigned int i;
141 for (i = 0; table[i]; i++)
142 if (strcmp (key, table[i]->key) == 0)
143 break;
144 return i;
ead15931 145}
bf137801 146
f26f525f
CF
147const char *
148UserSettings::get (const char *key)
bf137801 149{
f26f525f 150 unsigned int i = get_index (key);
f57981db 151 return table[i] ? table[i]->value : NULL;
f26f525f
CF
152}
153
154const char *
155UserSettings::set (const char *key, const char *val)
156{
157 ssize_t i = get_index (key);
158 if (table[i])
159 {
160 free ((void *) table[i]->key);
161 free ((void *) table[i]->value);
162 }
163 else
164 {
165 extend_table (i);
166 table[i] = new Element ();
167 table[i + 1] = NULL;
168 }
169 table[i]->key = strdup (key);
170 table[i]->value = strdup (val);
171 return table[i]->value;
bf137801
RC
172}
173
174void
f26f525f 175UserSettings::save ()
bf137801 176{
26922cd2 177 io_stream *f = io_stream::open(filename, "wb", 0644);
f26f525f
CF
178 if (!f)
179 return;
180 for (Element **e = table; *e; e++)
181 {
182 f->write ((*e)->key, strlen ((*e)->key));
183 f->write ("\n", 1);
184 std::string s = (*e)->value;
185 s.append ("\n");
186 size_t n;
187 for (int i = 0; (n = s.find_first_of ('\n', i)) != std::string::npos; i = n + 1)
188 {
189 std::string elem = s.substr (i, 1 + n - i);
190 f->write ("\t", 1);
191 f->write (elem.c_str (), elem.length ());
192 }
193 }
194 delete f;
bf137801 195}
f0fd8856
RC
196
197io_stream *
f26f525f 198UserSettings::open (const char *key)
f0fd8856 199{
f26f525f
CF
200 io_stream *f = new io_stream_key (key);
201 return f;
f0fd8856
RC
202}
203
f26f525f
CF
204io_stream_key::io_stream_key (const char *in_key)
205 : key (in_key), buf ("")
f0fd8856 206{
f26f525f 207}
f0fd8856 208
f26f525f
CF
209void
210io_stream_key::operator << (std::string in)
211{
212 buf += in;
213 buf += "\n";
214}
215
216void
217io_stream_key::operator << (const char *in)
218{
219 std::string s = in;
220 *this << s;
221}
222
223io_stream_key::~io_stream_key ()
224{
225 if (buf.length() > 0 && buf[buf.length () - 1] == '\n')
226 buf.resize (buf.length () - 1);
227 UserSettings::instance().set (key, buf);
f0fd8856 228}
This page took 0.087118 seconds and 5 git commands to generate.