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
17 #include "UserSettings.h"
18 #include "io_stream.h"
21 class io_stream_key
: public io_stream
26 io_stream_key (const char *);
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.
49 p
+= strspn (p
, " \t");
52 for (char *q
= strchr (p
, '\0') - 1; q
>= p
&& (*q
== ' ' || *q
== '\t' || *q
== '\r' || *q
== '\n'); q
--)
58 UserSettings::extend_table (ssize_t i
)
63 table
= (Element
**) realloc (table
, sizeof (*table
) * (table_len
+ 1));
68 UserSettings::open_settings (const char *filename
, std::string
&pathname
)
72 if (!isdirsep (cwd
[cwd
.size () - 1]) && !isdirsep (filename
[0]))
75 io_stream
*f
= io_stream::open(pathname
, "rt", 0);
78 pathname
= "cygfile:///etc/setup/";
80 f
= io_stream::open (pathname
, "rt", 0);
85 UserSettings::UserSettings ()
86 : table (NULL
), table_len (-1)
93 UserSettings::load (std::string local_dir
)
96 io_stream
*f
= open_settings ("setup.rc", filename
);
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
);
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
);
121 while (*(p
= eol
+ 1))
123 if (*p
!= ' ' && *p
!= '\t')
125 eol
= strchr (p
, '\n');
129 eol
= strchr (p
, '\0');
138 set (thiskey
, thisval
);
144 UserSettings::get_index (const char *key
)
147 for (i
= 0; table
[i
]; i
++)
148 if (strcmp (key
, table
[i
]->key
) == 0)
154 UserSettings::get (const char *key
)
156 unsigned int i
= get_index (key
);
157 return table
[i
] ? table
[i
]->value
: NULL
;
161 UserSettings::set (const char *key
, const char *val
)
163 ssize_t i
= get_index (key
);
166 free ((void *) table
[i
]->key
);
167 free ((void *) table
[i
]->value
);
172 table
[i
] = new Element ();
175 table
[i
]->key
= strdup (key
);
176 table
[i
]->value
= strdup (val
);
177 return table
[i
]->value
;
181 UserSettings::save ()
183 io_stream
*f
= io_stream::open(filename
, "wb", 0644);
186 for (Element
**e
= table
; *e
; e
++)
188 f
->write ((*e
)->key
, strlen ((*e
)->key
));
190 std::string s
= (*e
)->value
;
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
);
197 f
->write (elem
.c_str (), elem
.length ());
204 UserSettings::open (const char *key
)
206 io_stream
*f
= new io_stream_key (key
);
210 io_stream_key::io_stream_key (const char *in_key
)
211 : key (in_key
), buf ("")
216 io_stream_key::operator << (std::string in
)
223 io_stream_key::operator << (const char *in
)
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
);