diff options
author | Sebastian Dransfeld <sd@tango.flipp.net> | 2012-10-18 11:19:28 +0000 |
---|---|---|
committer | Sebastian Dransfeld <sd@tango.flipp.net> | 2012-10-18 11:19:28 +0000 |
commit | 4468ee3a7f4916971f87b16d1de093dfcf9c4272 (patch) | |
tree | 2595b343296d029d75cea275223955f174ea705f /legacy/efreet | |
parent | e327361844a2e352040a5e8a4905c08d2f92d054 (diff) |
efreet: use eina_file_map
SVN revision: 78179
Diffstat (limited to 'legacy/efreet')
-rw-r--r-- | legacy/efreet/src/lib/efreet_ini.c | 203 |
1 files changed, 83 insertions, 120 deletions
diff --git a/legacy/efreet/src/lib/efreet_ini.c b/legacy/efreet/src/lib/efreet_ini.c index 375fda1dc1..3b92fbb709 100644 --- a/legacy/efreet/src/lib/efreet_ini.c +++ b/legacy/efreet/src/lib/efreet_ini.c | |||
@@ -21,9 +21,6 @@ void *alloca (size_t); | |||
21 | #endif | 21 | #endif |
22 | 22 | ||
23 | #include <ctype.h> | 23 | #include <ctype.h> |
24 | #include <sys/stat.h> | ||
25 | #include <unistd.h> | ||
26 | #include <sys/mman.h> | ||
27 | 24 | ||
28 | #include <Ecore_File.h> | 25 | #include <Ecore_File.h> |
29 | 26 | ||
@@ -97,92 +94,60 @@ efreet_ini_new(const char *file) | |||
97 | static Eina_Hash * | 94 | static Eina_Hash * |
98 | efreet_ini_parse(const char *file) | 95 | efreet_ini_parse(const char *file) |
99 | { | 96 | { |
100 | const char *buffer, *line_start; | 97 | Eina_File *f; |
101 | FILE *f; | 98 | Eina_File_Line *line; |
102 | Eina_Hash *data, *section = NULL; | 99 | Eina_Hash *data, *section = NULL; |
103 | struct stat file_stat; | 100 | Eina_Iterator *it; |
104 | int line_length, left; | ||
105 | |||
106 | if (!file) return NULL; | ||
107 | 101 | ||
108 | f = fopen(file, "rb"); | 102 | f = eina_file_open(file, EINA_FALSE); |
109 | if (!f) return NULL; | 103 | if (!f) goto error; |
110 | 104 | ||
111 | if (fstat(fileno(f), &file_stat) || (file_stat.st_size < 1)) | 105 | data = eina_hash_string_small_new(EINA_FREE_CB(eina_hash_free)); |
112 | { | 106 | if (!data) goto error; |
113 | fclose(f); | ||
114 | return NULL; | ||
115 | } | ||
116 | if (!S_ISREG(file_stat.st_mode)) /* if not a regular file - close */ | ||
117 | { | ||
118 | fclose(f); | ||
119 | return NULL; | ||
120 | } | ||
121 | 107 | ||
122 | left = file_stat.st_size; | ||
123 | /* let's make mmap safe and just get 0 pages for IO erro */ | 108 | /* let's make mmap safe and just get 0 pages for IO erro */ |
124 | eina_mmap_safety_enabled_set(EINA_TRUE); | 109 | eina_mmap_safety_enabled_set(EINA_TRUE); |
125 | 110 | ||
126 | buffer = mmap(NULL, left, PROT_READ, MAP_SHARED, fileno(f), 0); | 111 | it = eina_file_map_lines(f); |
127 | if (buffer == MAP_FAILED) | 112 | if (!it) goto error; |
113 | EINA_ITERATOR_FOREACH(it, line) | ||
128 | { | 114 | { |
129 | fclose(f); | 115 | const char *eq; |
130 | return NULL; | 116 | unsigned int start = 0; |
131 | } | 117 | |
132 | 118 | /* skip empty lines */ | |
133 | data = eina_hash_string_small_new(EINA_FREE_CB(eina_hash_free)); | 119 | if (line->length == 0) continue; |
134 | 120 | /* skip white space at start of line */ | |
135 | line_start = buffer; | 121 | while ((start < line->length) && (isspace((unsigned char)line->start[start]))) |
136 | while (left > 0) | 122 | start++; |
137 | { | 123 | /* skip empty lines */ |
138 | int sep; | 124 | if (start == line->length) continue; |
139 | 125 | /* skip comments */ | |
140 | /* find the end of line */ | 126 | if (line->start[start] == '#') continue; |
141 | for (line_length = 0; | ||
142 | (line_length < left) && | ||
143 | (line_start[line_length] != '\n'); line_length++) | ||
144 | ; | ||
145 | |||
146 | /* check for all white space */ | ||
147 | while (isspace(line_start[0]) && (line_length > 0)) | ||
148 | { | ||
149 | line_start++; | ||
150 | line_length--; | ||
151 | } | ||
152 | |||
153 | /* skip empty lines and comments */ | ||
154 | if ((line_length == 0) || (line_start[0] == '\r') || | ||
155 | (line_start[0] == '\n') || (line_start[0] == '#') || | ||
156 | (line_start[0] == '\0')) | ||
157 | goto next_line; | ||
158 | 127 | ||
159 | /* new section */ | 128 | /* new section */ |
160 | if (line_start[0] == '[') | 129 | if (line->start[start] == '[') |
161 | { | 130 | { |
162 | int header_length; | 131 | const char *head_start; |
132 | const char *head_end; | ||
163 | 133 | ||
164 | /* find the ']' */ | 134 | head_start = &(line->start[start]) + 1; |
165 | for (header_length = 1; | 135 | head_end = memchr(line->start, ']', line->length); |
166 | (header_length < line_length) && | ||
167 | (line_start[header_length] != ']'); ++header_length) | ||
168 | ; | ||
169 | 136 | ||
170 | if (line_start[header_length] == ']') | 137 | if (head_end) |
171 | { | 138 | { |
172 | const char *header; | 139 | char *header; |
140 | size_t len; | ||
173 | 141 | ||
174 | header = alloca(header_length * sizeof(unsigned char)); | 142 | len = head_end - head_start + 1; |
175 | if (!header) goto next_line; | 143 | header = alloca(len); |
176 | 144 | ||
177 | memcpy((char*)header, line_start + 1, header_length - 1); | 145 | memcpy(header, head_start, len - 1); |
178 | ((char*)header)[header_length - 1] = '\0'; | 146 | header[len - 1] = '\0'; |
179 | 147 | ||
180 | section = eina_hash_string_small_new(EINA_FREE_CB(eina_stringshare_del)); | 148 | section = eina_hash_string_small_new(EINA_FREE_CB(eina_stringshare_del)); |
181 | 149 | ||
182 | eina_hash_del_by_key(data, header); | 150 | eina_hash_del_by_key(data, header); |
183 | // if (old) INF("[efreet] Warning: duplicate section '%s' " | ||
184 | // "in file '%s'", header, file); | ||
185 | |||
186 | eina_hash_add(data, header, section); | 151 | eina_hash_add(data, header, section); |
187 | } | 152 | } |
188 | else | 153 | else |
@@ -191,7 +156,7 @@ efreet_ini_parse(const char *file) | |||
191 | /* just printf for now till we figure out what to do */ | 156 | /* just printf for now till we figure out what to do */ |
192 | // ERR("Invalid file (%s) (missing ] on group name)", file); | 157 | // ERR("Invalid file (%s) (missing ] on group name)", file); |
193 | } | 158 | } |
194 | goto next_line; | 159 | continue; |
195 | } | 160 | } |
196 | 161 | ||
197 | if (!section) | 162 | if (!section) |
@@ -200,62 +165,62 @@ efreet_ini_parse(const char *file) | |||
200 | goto error; | 165 | goto error; |
201 | } | 166 | } |
202 | 167 | ||
203 | /* find for '=' */ | 168 | eq = memchr(line->start, '=', line->length); |
204 | for (sep = 0; (sep < line_length) && (line_start[sep] != '='); ++sep) | ||
205 | ; | ||
206 | 169 | ||
207 | if (sep < line_length && line_start[sep] == '=') | 170 | if (eq) |
208 | { | 171 | { |
172 | const char *key_start, *key_end; | ||
173 | const char *value_start, *value_end; | ||
209 | char *key, *value; | 174 | char *key, *value; |
210 | int key_end, value_start, value_end; | 175 | size_t len; |
176 | |||
177 | key_start = &(line->start[start]); | ||
178 | key_end = eq - 1; | ||
211 | 179 | ||
212 | /* trim whitespace from end of key */ | 180 | /* trim whitespace from end of key */ |
213 | for (key_end = sep - 1; | 181 | while ((isspace((unsigned char)*key_end)) && (key_end > key_start)) |
214 | (key_end > 0) && isspace(line_start[key_end]); --key_end) | 182 | key_end--; |
215 | ; | 183 | key_end++; |
216 | 184 | ||
217 | if (!isspace(line_start[key_end])) key_end++; | 185 | /* make sure we have a key */ |
186 | if (key_start == key_end) continue; | ||
218 | 187 | ||
219 | /* trim whitespace from start of value */ | 188 | value_start = eq + 1; |
220 | for (value_start = sep + 1; | 189 | value_end = line->end; |
221 | (value_start < line_length) && | ||
222 | isspace(line_start[value_start]); ++value_start) | ||
223 | ; | ||
224 | |||
225 | /* trim \n off of end of value */ | ||
226 | for (value_end = line_length; | ||
227 | (value_end > value_start) && | ||
228 | ((line_start[value_end] == '\n') || | ||
229 | (line_start[value_end] == '\r')); --value_end) | ||
230 | ; | ||
231 | |||
232 | if (line_start[value_end] != '\n' | ||
233 | && line_start[value_end] != '\r' | ||
234 | && value_end < line_length) | ||
235 | value_end++; | ||
236 | |||
237 | /* make sure we have a key. blank values are allowed */ | ||
238 | if (key_end <= 0) | ||
239 | { | ||
240 | /* invalid file... */ | ||
241 | // INF("Invalid file (%s) (invalid key=value pair)", file); | ||
242 | 190 | ||
243 | goto next_line; | 191 | /* line->end points to char after '\n' or '\r' */ |
244 | } | 192 | value_end--; |
193 | /* trim whitespace from end of value */ | ||
194 | while ((isspace((unsigned char)*value_end)) && (value_end > value_start)) | ||
195 | value_end--; | ||
196 | value_end++; | ||
245 | 197 | ||
246 | key = alloca(key_end + 1); | 198 | /* trim whitespace from start of value */ |
247 | value = alloca(value_end - value_start + 1); | 199 | while ((isspace((unsigned char)*value_start)) && (value_start < value_end)) |
248 | if (!key || !value) goto next_line; | 200 | value_start++; |
249 | 201 | ||
250 | memcpy(key, line_start, key_end); | 202 | len = key_end - key_start + 1; |
251 | key[key_end] = '\0'; | 203 | key = alloca(len); |
252 | 204 | ||
253 | memcpy(value, line_start + value_start, | 205 | memcpy(key, key_start, len - 1); |
254 | value_end - value_start); | 206 | key[len - 1] = '\0'; |
255 | value[value_end - value_start] = '\0'; | ||
256 | 207 | ||
257 | eina_hash_del_by_key(section, key); | 208 | /* empty value allowed */ |
258 | eina_hash_add(section, key, efreet_ini_unescape(value)); | 209 | if (value_end == value_start) |
210 | { | ||
211 | eina_hash_del_by_key(section, key); | ||
212 | eina_hash_add(section, key, ""); | ||
213 | } | ||
214 | else | ||
215 | { | ||
216 | len = value_end - value_start + 1; | ||
217 | value = alloca(len); | ||
218 | memcpy(value, value_start, len - 1); | ||
219 | value[len - 1] = '\0'; | ||
220 | |||
221 | eina_hash_del_by_key(section, key); | ||
222 | eina_hash_add(section, key, efreet_ini_unescape(value)); | ||
223 | } | ||
259 | } | 224 | } |
260 | else | 225 | else |
261 | { | 226 | { |
@@ -263,13 +228,9 @@ efreet_ini_parse(const char *file) | |||
263 | INF("Invalid file (%s) (missing = from key=value pair)", file); | 228 | INF("Invalid file (%s) (missing = from key=value pair)", file); |
264 | goto error; | 229 | goto error; |
265 | } | 230 | } |
266 | |||
267 | next_line: | ||
268 | left -= line_length + 1; | ||
269 | line_start += line_length + 1; | ||
270 | } | 231 | } |
271 | munmap((char*) buffer, file_stat.st_size); | 232 | eina_iterator_free(it); |
272 | fclose(f); | 233 | eina_file_close(f); |
273 | 234 | ||
274 | #if 0 | 235 | #if 0 |
275 | if (!eina_hash_population(data)) | 236 | if (!eina_hash_population(data)) |
@@ -281,6 +242,8 @@ next_line: | |||
281 | return data; | 242 | return data; |
282 | error: | 243 | error: |
283 | if (data) eina_hash_free(data); | 244 | if (data) eina_hash_free(data); |
245 | if (it) eina_iterator_free(it); | ||
246 | if (f) eina_file_close(f); | ||
284 | return NULL; | 247 | return NULL; |
285 | } | 248 | } |
286 | 249 | ||