Mercurial > repo
view src/ploki/parse.c @ 8065:591b1467ccdf
<int-e> le/rn paste/"Paste" is a short story by Henry James. Its contents has been cut into pieces and distributed over numerous tin boxes on the World Wide Web, little pearls of wisdom buried among ordinary pastes.
author | HackBot |
---|---|
date | Sun, 15 May 2016 13:14:57 +0000 |
parents | ac0403686959 |
children |
line wrap: on
line source
#include "IO.h" #include "inc.h" #include "main.h" #include "main_label.h" #include "mars.h" #include "op.h" #include "parse.h" #include "text.h" #include "venus.h" #include <ctype.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> static void skipline(IO *f) { int c; for ( c = io_peek(f, 0); c != EOF && c != '\n'; c = io_peek(f, 0) ) { if (c == 'R' && io_cmppeek(f, 0, "REM", 3) == 0) { io_read(f, NULL, 3); skipline(f); } else { io_getc(f); } } if (c == '\n') { io_getc(f); } } static IO *open_inc(const char *s, enum io_flags mode) { size_t i; String cur; St_init(&cur); for (i = 0; inc_ludes[i]; ++i) { IO *tmp; St_cpy_s(&cur, s); St_tac_s(&cur, inc_ludes[i]); if ((tmp = io_open(St_ptr(&cur), mode))) { St_clear(&cur); return tmp; } } St_clear(&cur); return NULL; } void parse(IO *f, struct text *text, size_t *line) { int c; while ((c = io_peek(f, 0)) != EOF) { struct op node; String label; int is_static = 0; for ( ; c != EOF && c != '\n' && isspace(c); c = io_peek(f, 0) ) { io_getc(f); } if (c == EOF) { break; } if (io_cmppeek(f, 0, "INSERT", 6) == 0) { size_t start; size_t end; String ifname; IO *ifp; int inc; if (io_cmppeek(f, 6, " DA", 3) == 0) { inc = 0; start = 9; } else { inc = 1; start = 6; } for ( ; (c = io_peek(f, start)) != '\n' && isspace(c); ++start ) ; if (c == '\n' || c == EOF) { goto no_insert; } for ( end = start + 1; (c = io_peek(f, end)) != '\n' && c != EOF; ++end ) ; for ( ; end > start && isspace(io_peek(f, end - 1)); --end ) ; if (io_cmppeek(f, end - 4, "HERE", 4)) { goto no_insert; } for ( end -= 4; isspace(io_peek(f, end - 1)); --end ) ; io_read(f, NULL, start); St_init(&ifname); if (end > start) { io_read(f, &ifname, end - start); } if (!(ifp = (inc ? open_inc : io_open)(St_ptr(&ifname), IO_READ | IO_BUFFERED))) { fprintf(stderr, "%s: %s: %s\n", Prog, St_ptr(&ifname), strerror(errno)); St_clear(&ifname); exit(EXIT_FAILURE); } else { parse(ifp, text, line); io_decr(ifp); } St_clear(&ifname); io_getline(f, NULL); continue; } no_insert: op_init(&node); node.line = *line; St_init(&label); if (io_cmppeek(f, 0, "FOR", 3) == 0) { size_t p; for (p = 3; (c = io_peek(f, p)) != '\n' && isspace(c); ++p) ; if (c != EOF && c != '\n') { St_cat_c(&label, c); for (++p; (c = io_peek(f, p)) != EOF && !isspace(c); ++p) { St_cat_c(&label, c); } if (!ma_exists(&Mars, &label)) { is_static = 1; io_read(f, NULL, p); } else { St_zero(&label); } } } else { for (; (c = io_peek(f, 0)) == '0'; io_getc(f)) ; for (; isdigit(c); c = io_peek(f, 0)) { St_cat_c(&label, c); io_getc(f); } } for ( c = io_peek(f, 0); c != EOF && c != '\n' && isspace(c); c = io_peek(f, 0) ) { io_getc(f); } if (io_cmppeek(f, 0, "REM", 3) == 0) { io_read(f, &node.txt, 3); skipline(f); } else { size_t pos; io_getline(f, &node.txt); if ((pos = St_rstr_m(&node.txt, "?\?/\n", 4)) + 1u && pos + 4u == St_len(&node.txt)) { String buf; St_init(&buf); do { io_getline(f, &buf); St_del(&node.txt, St_len(&node.txt) - 4u, 4); St_cat(&node.txt, &buf); } while ((pos = St_rstr_m(&node.txt, "?\?/\n", 4)) + 1u && pos + 4u == St_len(&node.txt)); St_clear(&buf); } } { struct op *tmp; tmp = text_push(text, &node); if (is_static) { ma_enter(&Mars, &label, tmp); } else { ve_enter(&Venus, &label, tmp); ++*line; } } St_clear(&label); } }