summaryrefslogtreecommitdiff
path: root/legacy/efreet
diff options
context:
space:
mode:
authorSebastian Dransfeld <sd@tango.flipp.net>2012-10-18 11:19:28 +0000
committerSebastian Dransfeld <sd@tango.flipp.net>2012-10-18 11:19:28 +0000
commit4468ee3a7f4916971f87b16d1de093dfcf9c4272 (patch)
tree2595b343296d029d75cea275223955f174ea705f /legacy/efreet
parente327361844a2e352040a5e8a4905c08d2f92d054 (diff)
efreet: use eina_file_map
SVN revision: 78179
Diffstat (limited to 'legacy/efreet')
-rw-r--r--legacy/efreet/src/lib/efreet_ini.c203
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)
97static Eina_Hash * 94static Eina_Hash *
98efreet_ini_parse(const char *file) 95efreet_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
267next_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;
282error: 243error:
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