]> cygwin.com Git - cygwin-apps/setup.git/blame - UserSettings.cc
Convert deprecated auto_ptr to C++11-conformant unique_ptr
[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 17#include "io_stream.h"
4d10ec8c 18#include "win32.h"
f0fd8856 19
f26f525f
CF
20class io_stream_key : public io_stream
21{
22 const char *key;
23 std::string buf;
24public:
25 io_stream_key (const char *);
26 ~io_stream_key ();
26922cd2 27 int set_mtime(time_t) {return 0;}
f26f525f
CF
28 time_t get_mtime () {return 0;}
29 mode_t get_mode () {return 0;}
30 size_t get_size () {return 0;}
31 ssize_t read (void *buffer, size_t len) {return 0;}
32 ssize_t write (const void *buffer, size_t len) {return 0;}
33 ssize_t peek (void *buffer, size_t len) {return 0;}
34 long tell () {return 0;}
35 int seek (long, io_stream_seek_t) {return 0;}
36 int error () {return 0;}
37 void operator << (std::string);
38 void operator << (const char *);
39 friend io_stream *UserSettings::open (const char *);
40};
ead15931 41
f26f525f 42UserSettings *UserSettings::global;
ead15931 43
f26f525f
CF
44static char *
45trim (char *p)
ead15931 46{
f26f525f
CF
47 p += strspn (p, " \t");
48 char *q = strchr (p, '#');
49 if (q)
50 *q = '\0';
51 for (q = strchr (p, '\0') - 1; q >= p && (*q == ' ' || *q == '\t' || *q == '\r' || *q == '\n'); q--)
52 *q = '\0';
53 return p;
ead15931
RC
54}
55
f26f525f
CF
56inline void
57UserSettings::extend_table (ssize_t i)
ead15931 58{
f26f525f
CF
59 if (i < table_len)
60 return;
61 table_len = i + 100;
62 table = (Element **) realloc (table, sizeof (*table) * (table_len + 1));
63 table[i] = NULL;
ead15931
RC
64}
65
f26f525f
CF
66io_stream *
67UserSettings::open_settings (const char *filename, std::string &pathname)
68{
69 pathname = "file://";
70 pathname += cwd;
4d10ec8c 71 if (!isdirsep (cwd[cwd.size () - 1]) && !isdirsep (filename[0]))
32049a60 72 pathname += "/";
f26f525f 73 pathname += filename;
26922cd2 74 io_stream *f = io_stream::open(pathname, "rt", 0);
f26f525f
CF
75 if (!f)
76 {
77 pathname = "cygfile:///etc/setup/";
78 pathname += filename;
26922cd2 79 f = io_stream::open (pathname, "rt", 0);
f26f525f
CF
80 }
81 return f;
82}
ead15931 83
f26f525f
CF
84UserSettings::UserSettings (std::string local_dir)
85 : table (NULL), table_len (-1), cwd (local_dir)
ead15931 86{
f26f525f
CF
87 global = this;
88 extend_table (0);
127febea 89 io_stream *f = open_settings ("setup.rc", filename);
f26f525f
CF
90
91 if (!f)
92 return;
93
94 size_t sz = f->get_size ();
95 char *buf = new char [sz + 2];
96 ssize_t szread = f->read (buf, sz);
97 delete f;
98
99 if (szread > 0)
100 {
101 buf[szread] = '\0';
102 buf[szread + 1] = '\0';
103 for (char *p = strtok (buf, "\n"); p; p = strtok (p, "\n"))
104 {
105 char *eol = strchr (p, '\0');
106 char *thiskey = trim (p);
107 if (!*thiskey)
108 {
109 p = eol + 1;
110 continue;
111 }
112 std::string thisval;
113 const char *nl = "";
114 while (*(p = eol + 1))
115 {
116 if (*p != ' ' && *p != '\t')
117 break;
118 eol = strchr (p, '\n');
119 if (eol)
120 *eol = '\0';
121 else
122 eol = strchr (p, '\0');
123 char *s = trim (p);
124 if (*s)
125 {
126 thisval += nl;
127 thisval += s;
128 nl = "\n";
129 }
130 }
131 set (thiskey, thisval);
132 }
133 }
134 delete buf;
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.065325 seconds and 5 git commands to generate.