Added translation using Weblate (Italian)
[cygwin-setup.git] / UserSettings.cc
blobc8ddd3d2b2cf6734d8b79dd16537b61718046a9b
1 /* UserSettings.cc
3 Copyright (c) 2009, Christopher Faylor
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.
10 A copy of the GNU General Public License can be found at http://www.gnu.org
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <memory>
17 #include "UserSettings.h"
18 #include "io_stream.h"
19 #include "win32.h"
21 class io_stream_key : public io_stream
23 const char *key;
24 std::string buf;
25 public:
26 io_stream_key (const char *);
27 ~io_stream_key ();
28 int set_mtime(time_t) {return 0;}
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 off_t tell () {return 0;}
36 off_t seek (off_t, 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 *);
43 UserSettings *UserSettings::global;
45 // '#' indicates a comment if it's the first non-whitespace character.
46 static char *
47 trim (char *p)
49 p += strspn (p, " \t");
50 if (*p == '#')
51 *p = '\0';
52 for (char *q = strchr (p, '\0') - 1; q >= p && (*q == ' ' || *q == '\t' || *q == '\r' || *q == '\n'); q--)
53 *q = '\0';
54 return p;
57 inline void
58 UserSettings::extend_table (ssize_t i)
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;
67 io_stream *
68 UserSettings::open_settings (const char *filename, std::string &pathname)
70 pathname = "file://";
71 pathname += cwd;
72 if (!isdirsep (cwd[cwd.size () - 1]) && !isdirsep (filename[0]))
73 pathname += "/";
74 pathname += filename;
75 io_stream *f = io_stream::open(pathname, "rt", 0);
76 if (!f)
78 pathname = "cygfile:///etc/setup/";
79 pathname += filename;
80 f = io_stream::open (pathname, "rt", 0);
82 return f;
85 UserSettings::UserSettings ()
86 : table (NULL), table_len (-1)
88 global = this;
89 extend_table (0);
92 void
93 UserSettings::load (std::string local_dir)
95 cwd = local_dir;
96 io_stream *f = open_settings ("setup.rc", filename);
98 if (!f)
99 return;
101 size_t sz = f->get_size ();
102 std::unique_ptr<char[]> buf (new char [sz + 2]);
103 ssize_t szread = f->read (buf.get (), sz);
104 delete f;
106 if (szread > 0)
108 buf[szread] = '\0';
109 buf[szread + 1] = '\0';
110 for (char *p = strtok (buf.get (), "\n"); p; p = strtok (p, "\n"))
112 char *eol = strchr (p, '\0');
113 char *thiskey = trim (p);
114 if (!*thiskey)
116 p = eol + 1;
117 continue;
119 std::string thisval;
120 const char *nl = "";
121 while (*(p = eol + 1))
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)
133 thisval += nl;
134 thisval += s;
135 nl = "\n";
138 set (thiskey, thisval);
143 unsigned int
144 UserSettings::get_index (const char *key)
146 unsigned int i;
147 for (i = 0; table[i]; i++)
148 if (strcmp (key, table[i]->key) == 0)
149 break;
150 return i;
153 const char *
154 UserSettings::get (const char *key)
156 unsigned int i = get_index (key);
157 return table[i] ? table[i]->value : NULL;
160 const char *
161 UserSettings::set (const char *key, const char *val)
163 ssize_t i = get_index (key);
164 if (table[i])
166 free ((void *) table[i]->key);
167 free ((void *) table[i]->value);
169 else
171 extend_table (i);
172 table[i] = new Element ();
173 table[i + 1] = NULL;
175 table[i]->key = strdup (key);
176 table[i]->value = strdup (val);
177 return table[i]->value;
180 void
181 UserSettings::save ()
183 io_stream *f = io_stream::open(filename, "wb", 0644);
184 if (!f)
185 return;
186 for (Element **e = table; *e; e++)
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)
195 std::string elem = s.substr (i, 1 + n - i);
196 f->write ("\t", 1);
197 f->write (elem.c_str (), elem.length ());
200 delete f;
203 io_stream *
204 UserSettings::open (const char *key)
206 io_stream *f = new io_stream_key (key);
207 return f;
210 io_stream_key::io_stream_key (const char *in_key)
211 : key (in_key), buf ("")
215 void
216 io_stream_key::operator << (std::string in)
218 buf += in;
219 buf += "\n";
222 void
223 io_stream_key::operator << (const char *in)
225 std::string s = in;
226 *this << s;
229 io_stream_key::~io_stream_key ()
231 if (buf.length() > 0 && buf[buf.length () - 1] == '\n')
232 buf.resize (buf.length () - 1);
233 UserSettings::instance().set (key, buf);