#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 #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; }