111 lines
2.1 KiB
C
111 lines
2.1 KiB
C
#include "libscomp_amalg.h"
|
|
|
|
|
|
#ifdef LIBSCOMP_FREESTANDING
|
|
int strcmp(const char *s1, const char *s2) {
|
|
while (*s1 == *s2) {
|
|
if (!*s1)
|
|
break;
|
|
s1++;
|
|
s2++;
|
|
}
|
|
|
|
return *s1 - *s2;
|
|
}
|
|
#else
|
|
# include <string.h>
|
|
#endif
|
|
|
|
struct libscomp_cmd *hg_bsearch(const char *name,
|
|
const struct libscomp_cmd_store *cmds) {
|
|
size_t lower = 0, upper = cmds->len-1;
|
|
size_t i;
|
|
int rel;
|
|
|
|
while (upper >= lower) {
|
|
i = (upper - lower)/2 + lower;
|
|
rel = strcmp(name, cmds->arr[i].name);
|
|
/* x > cmds[i] */
|
|
if (rel > 0)
|
|
lower = i + 1;
|
|
/* x < cmds[i] */
|
|
else if (rel < 0)
|
|
upper = i - 1;
|
|
else
|
|
return &cmds->arr[i];
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
int libscomp_exec(const struct libscomp_cmd_store *cmds,
|
|
struct libscomp_line *ln, void *ptr) {
|
|
struct libscomp_cmd *cmd;
|
|
|
|
cmd = hg_bsearch(ln->buf[ln->name], cmds);
|
|
if (!cmd)
|
|
return LIBSCOMP_NOT_FOUND;
|
|
return cmd->exec(ln,ptr);
|
|
}
|
|
|
|
|
|
enum { LIBSCOMP_READ, LIBSCOMP_DISCARD };
|
|
|
|
void libscomp_reset(struct libscomp_input *in) {
|
|
in->state = LIBSCOMP_READ;
|
|
in->len = 0;
|
|
}
|
|
|
|
static enum libscomp_input_r libscomp_parse(
|
|
struct libscomp_input *in, struct libscomp_line *line) {
|
|
char *s = in->intbuf;
|
|
enum libscomp_input_r r = LIBSCOMP_ARG_OVERFLOW;
|
|
|
|
line->name = (*s == ':');
|
|
line->len = 0;
|
|
|
|
while (line->len < LIBSCOMP_MAXARG) {
|
|
line->buf[line->len++] = s;
|
|
for (; *s && *s != '\t'; s++);
|
|
|
|
if (!*s) {
|
|
r = LIBSCOMP_COMPLETE;
|
|
break;
|
|
} else {
|
|
*s = 0;
|
|
s++;
|
|
}
|
|
}
|
|
|
|
libscomp_reset(in);
|
|
return r;
|
|
}
|
|
|
|
enum libscomp_input_r libscomp_read(struct libscomp_input *in,
|
|
char **s,
|
|
struct libscomp_line *line) {
|
|
char c;
|
|
|
|
while ((c = **s)) {
|
|
(*s)++;
|
|
|
|
if (in->state == LIBSCOMP_DISCARD) {
|
|
if (c == '\n') {
|
|
libscomp_reset(in);
|
|
return LIBSCOMP_OVERFLOW;
|
|
}
|
|
} else {
|
|
switch (c) {
|
|
case '\n':
|
|
in->intbuf[in->len] = 0;
|
|
return libscomp_parse(in, line);
|
|
default:
|
|
in->intbuf[in->len++] = c;
|
|
if (in->len == LIBSCOMP_MAXBUF)
|
|
in->state = LIBSCOMP_DISCARD;
|
|
}
|
|
}
|
|
}
|
|
|
|
return LIBSCOMP_MORE;
|
|
}
|