]> cygwin.com Git - cygwin-apps/setup.git/blame - UserSettings.cc
Added dpiAwareness element to manifest
[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;}
67f7a530 35 off_t tell () {return 0;}
44d31ea0 36 off_t seek (off_t, io_stream_seek_t) {return 0;}
f26f525f
CF
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
bdf30e6e
JT
85UserSettings::UserSettings ()
86 : table (NULL), table_len (-1)
ead15931 87{
f26f525f
CF
88 global = this;
89 extend_table (0);
bdf30e6e
JT
90}
91
92void
93UserSettings::load (std::string local_dir)
94{
95 cwd = local_dir;
127febea 96 io_stream *f = open_settings ("setup.rc", filename);
f26f525f
CF
97
98 if (!f)
99 return;
100
101 size_t sz = f->get_size ();
f882d56e
CV
102 std::unique_ptr<char[]> buf (new char [sz + 2]);
103 ssize_t szread = f->read (buf.get (), sz);
f26f525f
CF
104 delete f;
105
106 if (szread > 0)
107 {
108 buf[szread] = '\0';
109 buf[szread + 1] = '\0';
f882d56e 110 for (char *p = strtok (buf.get (), "\n"); p; p = strtok (p, "\n"))
f26f525f
CF
111 {
112 char *eol = strchr (p, '\0');
113 char *thiskey = trim (p);
114 if (!*thiskey)
115 {
116 p = eol + 1;
117 continue;
118 }
119 std::string thisval;
120 const char *nl = "";
121 while (*(p = eol + 1))
122 {
123 if (*p != ' ' && *p != '\t')
124 break;
125 eol = strchr (p, '\n');
126 if (eol)
127 *eol = '\0';
128 else
129 eol = strchr (p, '\0');
130 char *s = trim (p);
131 if (*s)
132 {
133 thisval += nl;
134 thisval += s;
135 nl = "\n";
136 }
137 }
138 set (thiskey, thisval);
139 }
140 }
ead15931
RC
141}
142
f26f525f
CF
143unsigned int
144UserSettings::get_index (const char *key)
ead15931 145{
f26f525f
CF
146 unsigned int i;
147 for (i = 0; table[i]; i++)
148 if (strcmp (key, table[i]->key) == 0)
149 break;
150 return i;
ead15931 151}
bf137801 152
f26f525f
CF
153const char *
154UserSettings::get (const char *key)
bf137801 155{
f26f525f 156 unsigned int i = get_index (key);
f57981db 157 return table[i] ? table[i]->value : NULL;
f26f525f
CF
158}
159
160const char *
161UserSettings::set (const char *key, const char *val)
162{
163 ssize_t i = get_index (key);
164 if (table[i])
165 {
166 free ((void *) table[i]->key);
167 free ((void *) table[i]->value);
168 }
169 else
170 {
171 extend_table (i);
172 table[i] = new Element ();
173 table[i + 1] = NULL;
174 }
175 table[i]->key = strdup (key);
176 table[i]->value = strdup (val);
177 return table[i]->value;
bf137801
RC
178}
179
180void
f26f525f 181UserSettings::save ()
bf137801 182{
26922cd2 183 io_stream *f = io_stream::open(filename, "wb", 0644);
f26f525f
CF
184 if (!f)
185 return;
186 for (Element **e = table; *e; e++)
187 {
188 f->write ((*e)->key, strlen ((*e)->key));
189 f->write ("\n", 1);
190 std::string s = (*e)->value;
191 s.append ("\n");
192 size_t n;
193 for (int i = 0; (n = s.find_first_of ('\n', i)) != std::string::npos; i = n + 1)
194 {
195 std::string elem = s.substr (i, 1 + n - i);
196 f->write ("\t", 1);
197 f->write (elem.c_str (), elem.length ());
198 }
199 }
200 delete f;
bf137801 201}
f0fd8856
RC
202
203io_stream *
f26f525f 204UserSettings::open (const char *key)
f0fd8856 205{
f26f525f
CF
206 io_stream *f = new io_stream_key (key);
207 return f;
f0fd8856
RC
208}
209
f26f525f
CF
210io_stream_key::io_stream_key (const char *in_key)
211 : key (in_key), buf ("")
f0fd8856 212{
f26f525f 213}
f0fd8856 214
f26f525f
CF
215void
216io_stream_key::operator << (std::string in)
217{
218 buf += in;
219 buf += "\n";
220}
221
222void
223io_stream_key::operator << (const char *in)
224{
225 std::string s = in;
226 *this << s;
227}
228
229io_stream_key::~io_stream_key ()
230{
231 if (buf.length() > 0 && buf[buf.length () - 1] == '\n')
232 buf.resize (buf.length () - 1);
233 UserSettings::instance().set (key, buf);
f0fd8856 234}
This page took 0.162395 seconds and 6 git commands to generate.