mirror of https://github.com/pygos/pkg-utils.git
cleanup: reimplement process_file using foreach_line_in_file
Signed-off-by: David Oberhollenzer <goliath@infraroot.at>master
parent
b688a39149
commit
4a682b83f1
@ -1,23 +1,18 @@
|
||||
#ifndef INPUT_FILE_H
|
||||
#define INPUT_FILE_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
typedef struct {
|
||||
FILE *f;
|
||||
char *line;
|
||||
const char *filename;
|
||||
size_t linenum;
|
||||
} input_file_t;
|
||||
#include <stddef.h>
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
int (*handle)(input_file_t *f, void *obj);
|
||||
int (*handle)(char *line, const char *filename,
|
||||
size_t linenum, void *obj);
|
||||
} keyword_handler_t;
|
||||
|
||||
int process_file(const char *filename, const keyword_handler_t *handlers,
|
||||
size_t count, void *obj);
|
||||
|
||||
void input_file_complain(const input_file_t *f, const char *msg);
|
||||
void input_file_complain(const char *filename, size_t linenum,
|
||||
const char *msg);
|
||||
|
||||
#endif /* INPUT_FILE_H */
|
||||
|
@ -1,122 +1,58 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "util/input_file.h"
|
||||
#include "util/util.h"
|
||||
|
||||
static int prefetch_line(input_file_t *f)
|
||||
void input_file_complain(const char *filename, size_t linenum, const char *msg)
|
||||
{
|
||||
char *line, *ptr;
|
||||
ssize_t ret;
|
||||
size_t n;
|
||||
retry:
|
||||
free(f->line);
|
||||
f->line = NULL;
|
||||
|
||||
errno = 0;
|
||||
line = NULL;
|
||||
n = 0;
|
||||
ret = getline(&line, &n, f->f);
|
||||
|
||||
if (ret < 0) {
|
||||
if (errno != 0) {
|
||||
perror(f->filename);
|
||||
free(line);
|
||||
return -1;
|
||||
}
|
||||
free(line);
|
||||
return 1;
|
||||
}
|
||||
|
||||
n = strlen(line);
|
||||
while (n >0 && isspace(line[n - 1]))
|
||||
--n;
|
||||
line[n] = '\0';
|
||||
fprintf(stderr, "%s: %zu: %s\n", filename, linenum, msg);
|
||||
}
|
||||
|
||||
f->line = line;
|
||||
f->linenum += 1;
|
||||
struct userdata {
|
||||
const keyword_handler_t *handlers;
|
||||
size_t count;
|
||||
void *obj;
|
||||
};
|
||||
|
||||
for (ptr = f->line; isspace(*ptr); ++ptr)
|
||||
;
|
||||
static int handle_line(void *usr, const char *filename,
|
||||
size_t linenum, char *line)
|
||||
{
|
||||
struct userdata *u = usr;
|
||||
size_t i, len;
|
||||
|
||||
if (*ptr == '\0' || *ptr == '#')
|
||||
goto retry;
|
||||
while (isspace(*line))
|
||||
++line;
|
||||
|
||||
if (ptr != f->line)
|
||||
memmove(f->line, ptr, strlen(ptr) + 1);
|
||||
if (*line == '\0' || *line == '#')
|
||||
return 0;
|
||||
|
||||
ptr = f->line + strlen(f->line);
|
||||
for (i = 0; i < u->count; ++i) {
|
||||
len = strlen(u->handlers[i].name);
|
||||
|
||||
while (ptr > f->line && isspace(ptr[-1]))
|
||||
--ptr;
|
||||
*ptr = '\0';
|
||||
if (strncmp(line, u->handlers[i].name, len) != 0)
|
||||
continue;
|
||||
if (!isspace(line[len]) && line[len] != '\0')
|
||||
continue;
|
||||
for (line += len; isspace(*line); ++line)
|
||||
;
|
||||
break;
|
||||
}
|
||||
|
||||
if (f->line[0] == '\0')
|
||||
goto retry;
|
||||
return 0;
|
||||
}
|
||||
if (i == u->count) {
|
||||
fprintf(stderr, "%s: %zu: unknown keyword\n",
|
||||
filename, linenum);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void input_file_complain(const input_file_t *f, const char *msg)
|
||||
{
|
||||
fprintf(stderr, "%s: %zu: %s\n", f->filename, f->linenum, msg);
|
||||
return u->handlers[i].handle(line, filename, linenum, u->obj);
|
||||
}
|
||||
|
||||
int process_file(const char *filename, const keyword_handler_t *handlers,
|
||||
size_t count, void *obj)
|
||||
{
|
||||
input_file_t f;
|
||||
size_t i, len;
|
||||
char *ptr;
|
||||
int ret;
|
||||
|
||||
memset(&f, 0, sizeof(f));
|
||||
|
||||
f.filename = filename;
|
||||
f.f = fopen(filename, "r");
|
||||
|
||||
if (f.f == NULL) {
|
||||
perror(f.filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
ret = prefetch_line(&f);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
if (ret > 0)
|
||||
break;
|
||||
|
||||
ptr = f.line;
|
||||
|
||||
for (i = 0; i < count; ++i) {
|
||||
len = strlen(handlers[i].name);
|
||||
|
||||
if (strncmp(ptr, handlers[i].name, len) != 0)
|
||||
continue;
|
||||
if (!isspace(ptr[len]) && ptr[len] != '\0')
|
||||
continue;
|
||||
for (ptr += len; isspace(*ptr); ++ptr)
|
||||
;
|
||||
memmove(f.line, ptr, strlen(ptr) + 1);
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == count) {
|
||||
fprintf(stderr, "%s: %zu: unknown keyword\n",
|
||||
f.filename, f.linenum);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (handlers[i].handle(&f, obj))
|
||||
goto fail;
|
||||
}
|
||||
struct userdata u = { handlers, count, obj };
|
||||
|
||||
fclose(f.f);
|
||||
free(f.line);
|
||||
return 0;
|
||||
fail:
|
||||
fclose(f.f);
|
||||
free(f.line);
|
||||
return -1;
|
||||
return foreach_line_in_file(filename, &u, handle_line);
|
||||
}
|
||||
|
Loading…
Reference in New Issue