mirror of
https://github.com/pygos/pkg-utils.git
synced 2024-11-22 12:59:46 +01:00
Cleanup: unify input file processing code
Signed-off-by: David Oberhollenzer <goliath@infraroot.at>
This commit is contained in:
parent
6fc871b3ff
commit
a32a4cb149
7 changed files with 148 additions and 165 deletions
|
@ -24,7 +24,7 @@ EXTRA_DIST = autogen.sh
|
||||||
##### commands #####
|
##### commands #####
|
||||||
|
|
||||||
# pack command
|
# pack command
|
||||||
pkg_SOURCES += main/cmd/pack/filelist.c main/cmd/pack/filelist_read.c
|
pkg_SOURCES += main/cmd/pack/filelist.c
|
||||||
pkg_SOURCES += main/cmd/pack/write_toc.c main/cmd/pack/write_files.c
|
pkg_SOURCES += main/cmd/pack/write_toc.c main/cmd/pack/write_files.c
|
||||||
pkg_SOURCES += main/cmd/pack/pack.h main/cmd/pack/pack.c
|
pkg_SOURCES += main/cmd/pack/pack.h main/cmd/pack/pack.c
|
||||||
pkg_SOURCES += main/cmd/pack/desc.c main/cmd/pack/write_hdr.c
|
pkg_SOURCES += main/cmd/pack/desc.c main/cmd/pack/write_hdr.c
|
||||||
|
|
|
@ -10,10 +10,18 @@ typedef struct {
|
||||||
size_t linenum;
|
size_t linenum;
|
||||||
} input_file_t;
|
} input_file_t;
|
||||||
|
|
||||||
int prefetch_line(input_file_t *f);
|
typedef struct {
|
||||||
|
const char *name;
|
||||||
|
int (*handle)(input_file_t *f, void *obj);
|
||||||
|
} keyword_handler_t;
|
||||||
|
|
||||||
void cleanup_file(input_file_t *f);
|
void cleanup_file(input_file_t *f);
|
||||||
|
|
||||||
int open_file(input_file_t *f, const char *filename);
|
int open_file(input_file_t *f, const char *filename);
|
||||||
|
|
||||||
|
int process_file(input_file_t *f, const keyword_handler_t *handlers,
|
||||||
|
size_t count, void *obj);
|
||||||
|
|
||||||
|
void input_file_complain(const input_file_t *f, const char *msg);
|
||||||
|
|
||||||
#endif /* INPUT_FILE_H */
|
#endif /* INPUT_FILE_H */
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
#include "pack.h"
|
#include "pack.h"
|
||||||
|
|
||||||
static int handle_requires(input_file_t *f, pkg_desc_t *desc)
|
static int handle_requires(input_file_t *f, void *obj)
|
||||||
{
|
{
|
||||||
char *ptr = f->line, *end;
|
char *ptr = f->line, *end;
|
||||||
|
pkg_desc_t *desc = obj;
|
||||||
dependency_t *dep;
|
dependency_t *dep;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
|
@ -18,15 +19,13 @@ static int handle_requires(input_file_t *f, pkg_desc_t *desc)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (len > 0xFF) {
|
if (len > 0xFF) {
|
||||||
fprintf(stderr, "%s: %zu: dependency name too long\n",
|
input_file_complain(f, "dependency name too long");
|
||||||
f->filename, f->linenum);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
dep = calloc(1, sizeof(*dep) + len + 1);
|
dep = calloc(1, sizeof(*dep) + len + 1);
|
||||||
if (dep == NULL) {
|
if (dep == NULL) {
|
||||||
fprintf(stderr, "%s: %zu: out of memory\n",
|
input_file_complain(f, "out of memory");
|
||||||
f->filename, f->linenum);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,27 +40,25 @@ static int handle_requires(input_file_t *f, pkg_desc_t *desc)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int handle_name(input_file_t *f, pkg_desc_t *desc)
|
static int handle_name(input_file_t *f, void *obj)
|
||||||
{
|
{
|
||||||
|
pkg_desc_t *desc = obj;
|
||||||
|
|
||||||
if (desc->name != NULL) {
|
if (desc->name != NULL) {
|
||||||
fprintf(stderr, "%s: %zu: name redefined\n",
|
input_file_complain(f, "name redefined");
|
||||||
f->filename, f->linenum);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
desc->name = strdup(f->line);
|
desc->name = strdup(f->line);
|
||||||
if (desc->name == NULL) {
|
if (desc->name == NULL) {
|
||||||
fputs("out of memory\n", stderr);
|
input_file_complain(f, "out of memory");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct {
|
static const keyword_handler_t line_hooks[] = {
|
||||||
const char *name;
|
|
||||||
int (*handle)(input_file_t *f, pkg_desc_t *desc);
|
|
||||||
} line_hooks[] = {
|
|
||||||
{ "requires", handle_requires },
|
{ "requires", handle_requires },
|
||||||
{ "name", handle_name },
|
{ "name", handle_name },
|
||||||
};
|
};
|
||||||
|
@ -71,58 +68,19 @@ static const struct {
|
||||||
int desc_read(const char *path, pkg_desc_t *desc)
|
int desc_read(const char *path, pkg_desc_t *desc)
|
||||||
{
|
{
|
||||||
input_file_t f;
|
input_file_t f;
|
||||||
size_t i, len;
|
|
||||||
char *ptr;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
memset(desc, 0, sizeof(*desc));
|
memset(desc, 0, sizeof(*desc));
|
||||||
|
|
||||||
if (open_file(&f, path))
|
if (open_file(&f, path))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
for (;;) {
|
if (process_file(&f, line_hooks, NUM_LINE_HOOKS, desc)) {
|
||||||
ret = prefetch_line(&f);
|
cleanup_file(&f);
|
||||||
if (ret < 0)
|
return -1;
|
||||||
goto fail;
|
|
||||||
if (ret > 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
ptr = f.line;
|
|
||||||
|
|
||||||
for (i = 0; i < NUM_LINE_HOOKS; ++i) {
|
|
||||||
len = strlen(line_hooks[i].name);
|
|
||||||
|
|
||||||
if (strncmp(ptr, line_hooks[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 == NUM_LINE_HOOKS) {
|
|
||||||
fprintf(stderr, "%s: %zu: unknown description field\n",
|
|
||||||
f.filename, f.linenum);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = line_hooks[i].handle(&f, desc);
|
|
||||||
if (ret)
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (desc->name == NULL) {
|
|
||||||
fprintf(stderr, "%s: no name given in package description\n",
|
|
||||||
f.filename);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup_file(&f);
|
cleanup_file(&f);
|
||||||
return 0;
|
return 0;
|
||||||
fail:
|
|
||||||
cleanup_file(&f);
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void desc_free(pkg_desc_t *desc)
|
void desc_free(pkg_desc_t *desc)
|
||||||
|
|
|
@ -7,14 +7,9 @@ static char *skipspace(char *str)
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void complain(const input_file_t *f, const char *msg)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "%s: %zu: %s\n", f->filename, f->linenum, msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void oom(input_file_t *f)
|
static void oom(input_file_t *f)
|
||||||
{
|
{
|
||||||
complain(f, "out of memory");
|
input_file_complain(f, "out of memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
static image_entry_t *filelist_mkentry(input_file_t *f, mode_t filetype)
|
static image_entry_t *filelist_mkentry(input_file_t *f, mode_t filetype)
|
||||||
|
@ -34,7 +29,7 @@ static image_entry_t *filelist_mkentry(input_file_t *f, mode_t filetype)
|
||||||
;
|
;
|
||||||
|
|
||||||
if (!isspace(line[i])) {
|
if (!isspace(line[i])) {
|
||||||
complain(f, "expected space after file name");
|
input_file_complain(f, "expected space after file name");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,17 +41,17 @@ static image_entry_t *filelist_mkentry(input_file_t *f, mode_t filetype)
|
||||||
|
|
||||||
memcpy(ent->name, line, i);
|
memcpy(ent->name, line, i);
|
||||||
if (canonicalize_name(ent->name)) {
|
if (canonicalize_name(ent->name)) {
|
||||||
complain(f, "invalid file name");
|
input_file_complain(f, "invalid file name");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ent->name[0] == '\0') {
|
if (ent->name[0] == '\0') {
|
||||||
complain(f, "refusing to add entry for '/'");
|
input_file_complain(f, "refusing to add entry for '/'");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strlen(ent->name) > 0xFFFF) {
|
if (strlen(ent->name) > 0xFFFF) {
|
||||||
complain(f, "name too long");
|
input_file_complain(f, "name too long");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,20 +59,20 @@ static image_entry_t *filelist_mkentry(input_file_t *f, mode_t filetype)
|
||||||
|
|
||||||
/* mode */
|
/* mode */
|
||||||
if (!isdigit(*line)) {
|
if (!isdigit(*line)) {
|
||||||
complain(f, "expected numeric mode after file name");
|
input_file_complain(f, "expected numeric mode after file name");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (isdigit(*line)) {
|
while (isdigit(*line)) {
|
||||||
if (*line > '7') {
|
if (*line > '7') {
|
||||||
complain(f, "mode must be octal number");
|
input_file_complain(f, "mode must be octal number");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
ent->mode = (ent->mode << 3) | (*(line++) - '0');
|
ent->mode = (ent->mode << 3) | (*(line++) - '0');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isspace(*line)) {
|
if (!isspace(*line)) {
|
||||||
complain(f, "expected space after file mode");
|
input_file_complain(f, "expected space after file mode");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,7 +82,7 @@ static image_entry_t *filelist_mkentry(input_file_t *f, mode_t filetype)
|
||||||
|
|
||||||
/* uid */
|
/* uid */
|
||||||
if (!isdigit(*line)) {
|
if (!isdigit(*line)) {
|
||||||
complain(f, "expected numeric UID after mode");
|
input_file_complain(f, "expected numeric UID after mode");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,7 +90,7 @@ static image_entry_t *filelist_mkentry(input_file_t *f, mode_t filetype)
|
||||||
ent->uid = (ent->uid * 10) + (*(line++) - '0');
|
ent->uid = (ent->uid * 10) + (*(line++) - '0');
|
||||||
|
|
||||||
if (!isspace(*line)) {
|
if (!isspace(*line)) {
|
||||||
complain(f, "expected space after UID");
|
input_file_complain(f, "expected space after UID");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +98,7 @@ static image_entry_t *filelist_mkentry(input_file_t *f, mode_t filetype)
|
||||||
|
|
||||||
/* gid */
|
/* gid */
|
||||||
if (!isdigit(*line)) {
|
if (!isdigit(*line)) {
|
||||||
complain(f, "expected numeric GID after UID");
|
input_file_complain(f, "expected numeric GID after UID");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,17 +116,26 @@ fail:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
image_entry_t *filelist_mkdir(input_file_t *f)
|
int filelist_mkdir(input_file_t *f, void *obj)
|
||||||
{
|
{
|
||||||
return filelist_mkentry(f, S_IFDIR);
|
image_entry_t *ent = filelist_mkentry(f, S_IFDIR);
|
||||||
}
|
image_entry_t **listptr = obj;
|
||||||
|
|
||||||
image_entry_t *filelist_mkslink(input_file_t *f)
|
|
||||||
{
|
|
||||||
image_entry_t *ent = filelist_mkentry(f, S_IFLNK);
|
|
||||||
|
|
||||||
if (ent == NULL)
|
if (ent == NULL)
|
||||||
return NULL;
|
return -1;
|
||||||
|
|
||||||
|
ent->next = *listptr;
|
||||||
|
*listptr = ent;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int filelist_mkslink(input_file_t *f, void *obj)
|
||||||
|
{
|
||||||
|
image_entry_t *ent = filelist_mkentry(f, S_IFLNK);
|
||||||
|
image_entry_t **listptr = obj;
|
||||||
|
|
||||||
|
if (ent == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
ent->data.symlink.target = strdup(f->line);
|
ent->data.symlink.target = strdup(f->line);
|
||||||
if (ent->data.symlink.target == NULL) {
|
if (ent->data.symlink.target == NULL) {
|
||||||
|
@ -140,23 +144,26 @@ image_entry_t *filelist_mkslink(input_file_t *f)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strlen(ent->data.symlink.target) > 0xFFFF) {
|
if (strlen(ent->data.symlink.target) > 0xFFFF) {
|
||||||
complain(f, "symlink target too long");
|
input_file_complain(f, "symlink target too long");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ent;
|
ent->next = *listptr;
|
||||||
|
*listptr = ent;
|
||||||
|
return 0;
|
||||||
fail:
|
fail:
|
||||||
image_entry_free(ent);
|
image_entry_free(ent);
|
||||||
return NULL;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
image_entry_t *filelist_mkfile(input_file_t *f)
|
int filelist_mkfile(input_file_t *f, void *obj)
|
||||||
{
|
{
|
||||||
image_entry_t *ent = filelist_mkentry(f, S_IFREG);
|
image_entry_t *ent = filelist_mkentry(f, S_IFREG);
|
||||||
|
image_entry_t **listptr = obj;
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
|
|
||||||
if (ent == NULL)
|
if (ent == NULL)
|
||||||
return NULL;
|
return -1;
|
||||||
|
|
||||||
ent->data.file.location = strdup(f->line);
|
ent->data.file.location = strdup(f->line);
|
||||||
if (ent->data.file.location == NULL) {
|
if (ent->data.file.location == NULL) {
|
||||||
|
@ -171,13 +178,49 @@ image_entry_t *filelist_mkfile(input_file_t *f)
|
||||||
|
|
||||||
if (sizeof(off_t) > sizeof(uint64_t) &&
|
if (sizeof(off_t) > sizeof(uint64_t) &&
|
||||||
sb.st_size > (off_t)(~((uint64_t)0))) {
|
sb.st_size > (off_t)(~((uint64_t)0))) {
|
||||||
complain(f, "input file is too big");
|
input_file_complain(f, "input file is too big");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
ent->data.file.size = sb.st_size;
|
ent->data.file.size = sb.st_size;
|
||||||
return ent;
|
|
||||||
|
ent->next = *listptr;
|
||||||
|
*listptr = ent;
|
||||||
|
return 0;
|
||||||
fail:
|
fail:
|
||||||
image_entry_free(ent);
|
image_entry_free(ent);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const keyword_handler_t line_hooks[] = {
|
||||||
|
{ "file", filelist_mkfile },
|
||||||
|
{ "dir", filelist_mkdir },
|
||||||
|
{ "slink", filelist_mkslink },
|
||||||
|
};
|
||||||
|
|
||||||
|
#define NUM_LINE_HOOKS (sizeof(line_hooks) / sizeof(line_hooks[0]))
|
||||||
|
|
||||||
|
image_entry_t *filelist_read(const char *filename)
|
||||||
|
{
|
||||||
|
image_entry_t *list = NULL;
|
||||||
|
input_file_t f;
|
||||||
|
|
||||||
|
if (open_file(&f, filename))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (process_file(&f, line_hooks, NUM_LINE_HOOKS, &list))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (list == NULL) {
|
||||||
|
fprintf(stderr, "%s: does not contain any entries\n",
|
||||||
|
f.filename);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup_file(&f);
|
||||||
|
return list;
|
||||||
|
fail:
|
||||||
|
cleanup_file(&f);
|
||||||
|
image_entry_free_list(list);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,73 +0,0 @@
|
||||||
#include "pack.h"
|
|
||||||
|
|
||||||
static const struct {
|
|
||||||
const char *name;
|
|
||||||
image_entry_t *(*handle)(input_file_t *f);
|
|
||||||
} line_hooks[] = {
|
|
||||||
{ "file", filelist_mkfile },
|
|
||||||
{ "dir", filelist_mkdir },
|
|
||||||
{ "slink", filelist_mkslink },
|
|
||||||
};
|
|
||||||
|
|
||||||
#define NUM_LINE_HOOKS (sizeof(line_hooks) / sizeof(line_hooks[0]))
|
|
||||||
|
|
||||||
image_entry_t *filelist_read(const char *filename)
|
|
||||||
{
|
|
||||||
image_entry_t *ent, *list = NULL;
|
|
||||||
input_file_t f;
|
|
||||||
size_t i, len;
|
|
||||||
char *ptr;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (open_file(&f, filename))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
ret = prefetch_line(&f);
|
|
||||||
if (ret < 0)
|
|
||||||
goto fail;
|
|
||||||
if (ret > 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
ptr = f.line;
|
|
||||||
|
|
||||||
for (i = 0; i < NUM_LINE_HOOKS; ++i) {
|
|
||||||
len = strlen(line_hooks[i].name);
|
|
||||||
|
|
||||||
if (strncmp(ptr, line_hooks[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 == NUM_LINE_HOOKS) {
|
|
||||||
fprintf(stderr, "%s: %zu: unknown entry type\n",
|
|
||||||
f.filename, f.linenum);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
ent = line_hooks[i].handle(&f);
|
|
||||||
if (ent == NULL)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
ent->next = list;
|
|
||||||
list = ent;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (list == NULL) {
|
|
||||||
fprintf(stderr, "%s: does not contain any entries\n",
|
|
||||||
f.filename);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup_file(&f);
|
|
||||||
return list;
|
|
||||||
fail:
|
|
||||||
cleanup_file(&f);
|
|
||||||
image_entry_free_list(list);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
|
@ -33,11 +33,11 @@ typedef struct {
|
||||||
char *name;
|
char *name;
|
||||||
} pkg_desc_t;
|
} pkg_desc_t;
|
||||||
|
|
||||||
image_entry_t *filelist_mkdir(input_file_t *f);
|
int filelist_mkdir(input_file_t *f, void *obj);
|
||||||
|
|
||||||
image_entry_t *filelist_mkslink(input_file_t *f);
|
int filelist_mkslink(input_file_t *f, void *obj);
|
||||||
|
|
||||||
image_entry_t *filelist_mkfile(input_file_t *f);
|
int filelist_mkfile(input_file_t *f, void *obj);
|
||||||
|
|
||||||
image_entry_t *filelist_read(const char *filename);
|
image_entry_t *filelist_read(const char *filename);
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
#include "input_file.h"
|
#include "input_file.h"
|
||||||
|
|
||||||
int prefetch_line(input_file_t *f)
|
static int prefetch_line(input_file_t *f)
|
||||||
{
|
{
|
||||||
char *line, *ptr;
|
char *line, *ptr;
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
@ -77,3 +77,50 @@ int open_file(input_file_t *f, const char *filename)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void input_file_complain(const input_file_t *f, const char *msg)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s: %zu: %s\n", f->filename, f->linenum, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
int process_file(input_file_t *f, const keyword_handler_t *handlers,
|
||||||
|
size_t count, void *obj)
|
||||||
|
{
|
||||||
|
size_t i, len;
|
||||||
|
char *ptr;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
ret = prefetch_line(f);
|
||||||
|
if (ret < 0)
|
||||||
|
return -1;
|
||||||
|
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);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handlers[i].handle(f, obj))
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue