parent
e327361844
commit
4468ee3a7f
|
@ -21,9 +21,6 @@ void *alloca (size_t);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
|
|
||||||
#include <Ecore_File.h>
|
#include <Ecore_File.h>
|
||||||
|
|
||||||
|
@ -97,92 +94,60 @@ efreet_ini_new(const char *file)
|
||||||
static Eina_Hash *
|
static Eina_Hash *
|
||||||
efreet_ini_parse(const char *file)
|
efreet_ini_parse(const char *file)
|
||||||
{
|
{
|
||||||
const char *buffer, *line_start;
|
Eina_File *f;
|
||||||
FILE *f;
|
Eina_File_Line *line;
|
||||||
Eina_Hash *data, *section = NULL;
|
Eina_Hash *data, *section = NULL;
|
||||||
struct stat file_stat;
|
Eina_Iterator *it;
|
||||||
int line_length, left;
|
|
||||||
|
|
||||||
if (!file) return NULL;
|
f = eina_file_open(file, EINA_FALSE);
|
||||||
|
if (!f) goto error;
|
||||||
|
|
||||||
f = fopen(file, "rb");
|
data = eina_hash_string_small_new(EINA_FREE_CB(eina_hash_free));
|
||||||
if (!f) return NULL;
|
if (!data) goto error;
|
||||||
|
|
||||||
if (fstat(fileno(f), &file_stat) || (file_stat.st_size < 1))
|
|
||||||
{
|
|
||||||
fclose(f);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (!S_ISREG(file_stat.st_mode)) /* if not a regular file - close */
|
|
||||||
{
|
|
||||||
fclose(f);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
left = file_stat.st_size;
|
|
||||||
/* let's make mmap safe and just get 0 pages for IO erro */
|
/* let's make mmap safe and just get 0 pages for IO erro */
|
||||||
eina_mmap_safety_enabled_set(EINA_TRUE);
|
eina_mmap_safety_enabled_set(EINA_TRUE);
|
||||||
|
|
||||||
buffer = mmap(NULL, left, PROT_READ, MAP_SHARED, fileno(f), 0);
|
it = eina_file_map_lines(f);
|
||||||
if (buffer == MAP_FAILED)
|
if (!it) goto error;
|
||||||
|
EINA_ITERATOR_FOREACH(it, line)
|
||||||
{
|
{
|
||||||
fclose(f);
|
const char *eq;
|
||||||
return NULL;
|
unsigned int start = 0;
|
||||||
}
|
|
||||||
|
|
||||||
data = eina_hash_string_small_new(EINA_FREE_CB(eina_hash_free));
|
/* skip empty lines */
|
||||||
|
if (line->length == 0) continue;
|
||||||
line_start = buffer;
|
/* skip white space at start of line */
|
||||||
while (left > 0)
|
while ((start < line->length) && (isspace((unsigned char)line->start[start])))
|
||||||
{
|
start++;
|
||||||
int sep;
|
/* skip empty lines */
|
||||||
|
if (start == line->length) continue;
|
||||||
/* find the end of line */
|
/* skip comments */
|
||||||
for (line_length = 0;
|
if (line->start[start] == '#') continue;
|
||||||
(line_length < left) &&
|
|
||||||
(line_start[line_length] != '\n'); line_length++)
|
|
||||||
;
|
|
||||||
|
|
||||||
/* check for all white space */
|
|
||||||
while (isspace(line_start[0]) && (line_length > 0))
|
|
||||||
{
|
|
||||||
line_start++;
|
|
||||||
line_length--;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* skip empty lines and comments */
|
|
||||||
if ((line_length == 0) || (line_start[0] == '\r') ||
|
|
||||||
(line_start[0] == '\n') || (line_start[0] == '#') ||
|
|
||||||
(line_start[0] == '\0'))
|
|
||||||
goto next_line;
|
|
||||||
|
|
||||||
/* new section */
|
/* new section */
|
||||||
if (line_start[0] == '[')
|
if (line->start[start] == '[')
|
||||||
{
|
{
|
||||||
int header_length;
|
const char *head_start;
|
||||||
|
const char *head_end;
|
||||||
|
|
||||||
/* find the ']' */
|
head_start = &(line->start[start]) + 1;
|
||||||
for (header_length = 1;
|
head_end = memchr(line->start, ']', line->length);
|
||||||
(header_length < line_length) &&
|
|
||||||
(line_start[header_length] != ']'); ++header_length)
|
|
||||||
;
|
|
||||||
|
|
||||||
if (line_start[header_length] == ']')
|
if (head_end)
|
||||||
{
|
{
|
||||||
const char *header;
|
char *header;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
header = alloca(header_length * sizeof(unsigned char));
|
len = head_end - head_start + 1;
|
||||||
if (!header) goto next_line;
|
header = alloca(len);
|
||||||
|
|
||||||
memcpy((char*)header, line_start + 1, header_length - 1);
|
memcpy(header, head_start, len - 1);
|
||||||
((char*)header)[header_length - 1] = '\0';
|
header[len - 1] = '\0';
|
||||||
|
|
||||||
section = eina_hash_string_small_new(EINA_FREE_CB(eina_stringshare_del));
|
section = eina_hash_string_small_new(EINA_FREE_CB(eina_stringshare_del));
|
||||||
|
|
||||||
eina_hash_del_by_key(data, header);
|
eina_hash_del_by_key(data, header);
|
||||||
// if (old) INF("[efreet] Warning: duplicate section '%s' "
|
|
||||||
// "in file '%s'", header, file);
|
|
||||||
|
|
||||||
eina_hash_add(data, header, section);
|
eina_hash_add(data, header, section);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -191,7 +156,7 @@ efreet_ini_parse(const char *file)
|
||||||
/* just printf for now till we figure out what to do */
|
/* just printf for now till we figure out what to do */
|
||||||
// ERR("Invalid file (%s) (missing ] on group name)", file);
|
// ERR("Invalid file (%s) (missing ] on group name)", file);
|
||||||
}
|
}
|
||||||
goto next_line;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!section)
|
if (!section)
|
||||||
|
@ -200,62 +165,62 @@ efreet_ini_parse(const char *file)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find for '=' */
|
eq = memchr(line->start, '=', line->length);
|
||||||
for (sep = 0; (sep < line_length) && (line_start[sep] != '='); ++sep)
|
|
||||||
;
|
|
||||||
|
|
||||||
if (sep < line_length && line_start[sep] == '=')
|
if (eq)
|
||||||
{
|
{
|
||||||
|
const char *key_start, *key_end;
|
||||||
|
const char *value_start, *value_end;
|
||||||
char *key, *value;
|
char *key, *value;
|
||||||
int key_end, value_start, value_end;
|
size_t len;
|
||||||
|
|
||||||
|
key_start = &(line->start[start]);
|
||||||
|
key_end = eq - 1;
|
||||||
|
|
||||||
/* trim whitespace from end of key */
|
/* trim whitespace from end of key */
|
||||||
for (key_end = sep - 1;
|
while ((isspace((unsigned char)*key_end)) && (key_end > key_start))
|
||||||
(key_end > 0) && isspace(line_start[key_end]); --key_end)
|
key_end--;
|
||||||
;
|
key_end++;
|
||||||
|
|
||||||
if (!isspace(line_start[key_end])) key_end++;
|
/* make sure we have a key */
|
||||||
|
if (key_start == key_end) continue;
|
||||||
|
|
||||||
|
value_start = eq + 1;
|
||||||
|
value_end = line->end;
|
||||||
|
|
||||||
|
/* line->end points to char after '\n' or '\r' */
|
||||||
|
value_end--;
|
||||||
|
/* trim whitespace from end of value */
|
||||||
|
while ((isspace((unsigned char)*value_end)) && (value_end > value_start))
|
||||||
|
value_end--;
|
||||||
|
value_end++;
|
||||||
|
|
||||||
/* trim whitespace from start of value */
|
/* trim whitespace from start of value */
|
||||||
for (value_start = sep + 1;
|
while ((isspace((unsigned char)*value_start)) && (value_start < value_end))
|
||||||
(value_start < line_length) &&
|
value_start++;
|
||||||
isspace(line_start[value_start]); ++value_start)
|
|
||||||
;
|
|
||||||
|
|
||||||
/* trim \n off of end of value */
|
len = key_end - key_start + 1;
|
||||||
for (value_end = line_length;
|
key = alloca(len);
|
||||||
(value_end > value_start) &&
|
|
||||||
((line_start[value_end] == '\n') ||
|
|
||||||
(line_start[value_end] == '\r')); --value_end)
|
|
||||||
;
|
|
||||||
|
|
||||||
if (line_start[value_end] != '\n'
|
memcpy(key, key_start, len - 1);
|
||||||
&& line_start[value_end] != '\r'
|
key[len - 1] = '\0';
|
||||||
&& value_end < line_length)
|
|
||||||
value_end++;
|
|
||||||
|
|
||||||
/* make sure we have a key. blank values are allowed */
|
/* empty value allowed */
|
||||||
if (key_end <= 0)
|
if (value_end == value_start)
|
||||||
{
|
{
|
||||||
/* invalid file... */
|
eina_hash_del_by_key(section, key);
|
||||||
// INF("Invalid file (%s) (invalid key=value pair)", file);
|
eina_hash_add(section, key, "");
|
||||||
|
|
||||||
goto next_line;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
len = value_end - value_start + 1;
|
||||||
|
value = alloca(len);
|
||||||
|
memcpy(value, value_start, len - 1);
|
||||||
|
value[len - 1] = '\0';
|
||||||
|
|
||||||
key = alloca(key_end + 1);
|
eina_hash_del_by_key(section, key);
|
||||||
value = alloca(value_end - value_start + 1);
|
eina_hash_add(section, key, efreet_ini_unescape(value));
|
||||||
if (!key || !value) goto next_line;
|
}
|
||||||
|
|
||||||
memcpy(key, line_start, key_end);
|
|
||||||
key[key_end] = '\0';
|
|
||||||
|
|
||||||
memcpy(value, line_start + value_start,
|
|
||||||
value_end - value_start);
|
|
||||||
value[value_end - value_start] = '\0';
|
|
||||||
|
|
||||||
eina_hash_del_by_key(section, key);
|
|
||||||
eina_hash_add(section, key, efreet_ini_unescape(value));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -263,13 +228,9 @@ efreet_ini_parse(const char *file)
|
||||||
INF("Invalid file (%s) (missing = from key=value pair)", file);
|
INF("Invalid file (%s) (missing = from key=value pair)", file);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
next_line:
|
|
||||||
left -= line_length + 1;
|
|
||||||
line_start += line_length + 1;
|
|
||||||
}
|
}
|
||||||
munmap((char*) buffer, file_stat.st_size);
|
eina_iterator_free(it);
|
||||||
fclose(f);
|
eina_file_close(f);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (!eina_hash_population(data))
|
if (!eina_hash_population(data))
|
||||||
|
@ -281,6 +242,8 @@ next_line:
|
||||||
return data;
|
return data;
|
||||||
error:
|
error:
|
||||||
if (data) eina_hash_free(data);
|
if (data) eina_hash_free(data);
|
||||||
|
if (it) eina_iterator_free(it);
|
||||||
|
if (f) eina_file_close(f);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue