Added a generic string splitter utility function that is based on callbacks instead of populating a list.

This commit is contained in:
Jan Vidar Krey 2010-01-27 23:55:05 +01:00
parent f0a13b4c23
commit 1faca92167
2 changed files with 64 additions and 31 deletions

View File

@ -171,14 +171,64 @@ void base32_decode(const char* src, unsigned char* dst, size_t len) {
} }
} }
int string_split(const char* string, const char* split, void* data, string_split_handler_t handler)
{
char* buf = strdup(string);
char* start;
char* pos;
int count = 0;
start = buf;
while ((pos = strstr(start, split)))
{
pos[0] = '\0';
start = strip_white_space(start);
if (*start)
{
if (handler(start, count, data) < 0)
{
hub_free(buf);
return -1;
}
}
start = &pos[1];
count++;
}
start = strip_white_space(start);
if (*start)
{
if (handler(start, count, data) < 0)
{
hub_free(buf);
return -1;
}
}
hub_free(buf);
return count+1;
}
struct file_read_line_data
{
file_line_handler_t handler;
void* data;
};
static int file_read_line_handler(char* line, int count, void* ptr)
{
struct file_read_line_data* data = (struct file_read_line_data*) ptr;
LOG_DUMP("Line: %s", line);
if (data->handler(line, count+1, data->data) < 0)
return -1;
return 0;
}
int file_read_lines(const char* file, void* data, file_line_handler_t handler) int file_read_lines(const char* file, void* data, file_line_handler_t handler)
{ {
int fd; int fd;
ssize_t ret; ssize_t ret;
char buf[MAX_RECV_BUF]; char buf[MAX_RECV_BUF];
char *pos, *start;
size_t line_count = 0;
memset(buf, 0, MAX_RECV_BUF); memset(buf, 0, MAX_RECV_BUF);
@ -192,45 +242,25 @@ int file_read_lines(const char* file, void* data, file_line_handler_t handler)
} }
ret = read(fd, buf, MAX_RECV_BUF); ret = read(fd, buf, MAX_RECV_BUF);
close(fd);
if (ret < 0) if (ret < 0)
{ {
LOG_ERROR("Unable to read from file %s: %s", file, strerror(errno)); LOG_ERROR("Unable to read from file %s: %s", file, strerror(errno));
close(fd);
return -1; return -1;
} }
else if (ret == 0) else if (ret == 0)
{ {
close(fd);
LOG_WARN("File is empty."); LOG_WARN("File is empty.");
return 0; return 0;
} }
else
{
close(fd);
/* Parse configuaration */ /* Parse configuaration */
start = buf; struct file_read_line_data split_data;
while ((pos = strchr(start, '\n'))) split_data.handler = handler;
{ split_data.data = data;
pos[0] = '\0';
if (*start)
{
LOG_DUMP("Line: %s", start);
if (handler(start, line_count+1, data) < 0)
return -1;
}
start = &pos[1];
line_count++;
}
if (*start) return string_split(buf, "\n", &split_data, file_read_line_handler);
{
LOG_DUMP("Line: %s", start);
if (handler(start, line_count+1, data) < 0)
return -1;
}
}
return line_count+1;
} }

View File

@ -36,6 +36,7 @@ extern char* strip_white_space(char* string);
extern int file_read_lines(const char* file, void* data, file_line_handler_t handler); extern int file_read_lines(const char* file, void* data, file_line_handler_t handler);
extern const char* uhub_itoa(int val); extern const char* uhub_itoa(int val);
extern const char* uhub_ulltoa(uint64_t val); extern const char* uhub_ulltoa(uint64_t val);
@ -61,6 +62,8 @@ void* memmem(const void *haystack, size_t haystacklen, const void *needle, size_
struct linked_list; struct linked_list;
extern int split_string(const char* string, const char* split, struct linked_list* list, int allow_empty); extern int split_string(const char* string, const char* split, struct linked_list* list, int allow_empty);
typedef int (*string_split_handler_t)(char* string, int count, void* data);
extern int string_split(const char* string, const char* split, void* data, string_split_handler_t handler);
#endif /* HAVE_UHUB_MISC_H */ #endif /* HAVE_UHUB_MISC_H */