diff --git a/main.c b/main.c index 89d0e09..7d21f45 100644 --- a/main.c +++ b/main.c @@ -130,7 +130,7 @@ int main(int argc, char **argv) { } if (proc->eof) - proc->eof ("", &out); + proc->eof (&proc->state, "", &out); if (out.fout) { fclose (out.fout); } diff --git a/p/cpp.h b/p/cpp.h index 7aa23b5..4c773ec 100644 --- a/p/cpp.h +++ b/p/cpp.h @@ -7,8 +7,8 @@ static TAG_CALLBACK(cpp_default) { static TAG_CALLBACK(cpp_error) { do_printf (out,"\n"); - if (echo[ifl] && buf != NULL) { - do_printf (out, "ERROR: %s (line=%d)\n", buf, lineno); + if (state->echo[state->ifl] && buf != NULL) { + do_printf (out, "ERROR: %s (line=%d)\n", buf, state->lineno); return -1; } return 0; @@ -16,8 +16,8 @@ static TAG_CALLBACK(cpp_error) { static TAG_CALLBACK(cpp_warning) { do_printf (out,"\n"); - if (echo[ifl] && buf != NULL) { - do_printf (out, "WARNING: line %d: %s\n", lineno, buf); + if (state->echo[state->ifl] && buf != NULL) { + do_printf (out, "WARNING: line %d: %s\n", state->lineno, buf); } return 0; } @@ -25,26 +25,26 @@ static TAG_CALLBACK(cpp_warning) { static TAG_CALLBACK(cpp_if) { char *var = getenv (buf + ((*buf == '!') ? 1 : 0)); if (var && *var=='1') - echo[ifl + 1] = 1; - else echo[ifl + 1] = 0; - if (*buf=='!') echo[ifl+1] = !!!echo[ifl+1]; + state->echo[state->ifl + 1] = 1; + else state->echo[state->ifl + 1] = 0; + if (*buf=='!') state->echo[state->ifl + 1] = !!!state->echo[state->ifl + 1]; return 1; } static TAG_CALLBACK(cpp_ifdef) { char *var = getenv (buf); - echo[ifl + 1] = var? 1: 0; + state->echo[state->ifl + 1] = var? 1: 0; return 1; } static TAG_CALLBACK(cpp_else) { - echo[ifl] = echo[ifl]? 0: 1; + state->echo[state->ifl] = state->echo[state->ifl]? 0: 1; return 0; } static TAG_CALLBACK(cpp_ifndef) { - cpp_ifdef (buf, out); - cpp_else (buf, out); + cpp_ifdef (state, buf, out); + cpp_else (state, buf, out); return 1; } @@ -111,7 +111,7 @@ static TAG_CALLBACK(cpp_endif) { } static TAG_CALLBACK(cpp_include) { - if (echo[ifl]) { + if (state->echo[state->ifl]) { spp_file (buf, out); } return 0; diff --git a/p/pod.h b/p/pod.h index fd1d949..e1b4253 100644 --- a/p/pod.h +++ b/p/pod.h @@ -7,12 +7,12 @@ static TAG_CALLBACK(pod_default) { static TAG_CALLBACK(pod_cut) { do_printf (out, "\n"); - echo[ifl] = 0; + state->echo[state->ifl] = 0; return 0; } static TAG_CALLBACK(pod_head1) { - echo[ifl] = 1; + state->echo[state->ifl] = 1; do_printf (out, "\n"); if (!buf) { return 0; diff --git a/p/spp.h b/p/spp.h index 343c308..54c0221 100644 --- a/p/spp.h +++ b/p/spp.h @@ -33,7 +33,7 @@ static char *cmd_to_str(const char *cmd) { static TAG_CALLBACK(spp_set) { char *eq, *val = ""; - if (!echo[ifl]) { + if (!state->echo[state->ifl]) { return 0; } for (eq=buf; eq[0]; eq++) { @@ -50,14 +50,14 @@ static TAG_CALLBACK(spp_set) { val = eq + 1; } if (spp_var_set (buf, val) == -1) { - fprintf (stderr, "Invalid variable name '%s' at line %d\n", buf, lineno); + fprintf (stderr, "Invalid variable name '%s' at line %d\n", buf, state->lineno); } return 0; } static TAG_CALLBACK(spp_get) { char *var; - if (!echo[ifl]) { + if (!state->echo[state->ifl]) { return 0; } var = spp_var_get (buf); @@ -69,7 +69,7 @@ static TAG_CALLBACK(spp_get) { static TAG_CALLBACK(spp_getrandom) { int max; - if (!echo[ifl]) { + if (!state->echo[state->ifl]) { return 0; } // XXX srsly? this is pretty bad random @@ -86,7 +86,7 @@ static TAG_CALLBACK(spp_add) { char res[32]; char *var, *eq = strchr (buf, ' '); int ret = 0; - if (!echo[ifl]) { + if (!state->echo[state->ifl]) { return 0; } if (eq) { @@ -108,7 +108,7 @@ static TAG_CALLBACK(spp_sub) { char *eq = strchr(buf, ' '); char *var; int ret = 0; - if (!echo[ifl]) { + if (!state->echo[state->ifl]) { return 0; } if (eq) { @@ -126,7 +126,7 @@ static TAG_CALLBACK(spp_sub) { // XXX This method needs some love static TAG_CALLBACK(spp_trace) { char b[1024]; - if (!echo[ifl]) return 0; + if (!state->echo[state->ifl]) return 0; snprintf(b, 1023, "echo '%s' >&2 ", buf); system(b); return 0; @@ -134,30 +134,30 @@ static TAG_CALLBACK(spp_trace) { /* TODO: deprecate */ static TAG_CALLBACK(spp_echo) { - if (!echo[ifl]) return 0; + if (!state->echo[state->ifl]) return 0; do_printf (out, "%s", buf); // TODO: add variable replacement here?? not necessary, done by {{get}} return 0; } static TAG_CALLBACK(spp_error) { - if (!echo[ifl]) { + if (!state->echo[state->ifl]) { return 0; } - fprintf (stderr, "ERROR: %s (line=%d)\n", buf, lineno); + fprintf (stderr, "ERROR: %s (line=%d)\n", buf, state->lineno); return -1; } static TAG_CALLBACK(spp_warning) { - if (!echo[ifl]) { + if (!state->echo[state->ifl]) { return 0; } - fprintf (stderr, "WARNING: %s (line=%d)\n", buf, lineno); + fprintf (stderr, "WARNING: %s (line=%d)\n", buf, state->lineno); return 0; } static TAG_CALLBACK(spp_system) { - if (!echo[ifl]) { + if (!state->echo[state->ifl]) { return 0; } char *str = cmd_to_str (buf); @@ -168,7 +168,7 @@ static TAG_CALLBACK(spp_system) { static TAG_CALLBACK(spp_include) { char *incdir; - if (!echo[ifl]) { + if (!state->echo[state->ifl]) { return 0; } incdir = getenv("SPP_INCDIR"); @@ -190,7 +190,7 @@ static TAG_CALLBACK(spp_include) { static TAG_CALLBACK(spp_if) { char *var = spp_var_get(buf); - echo[ifl + 1] = (var && *var != '0' && *var != '\0') ? 1 : 0; + state->echo[state->ifl + 1] = (var && *var != '0' && *var != '\0') ? 1 : 0; return 1; } @@ -202,14 +202,14 @@ static TAG_CALLBACK(spp_ifeq) { *eq = '\0'; value = spp_var_get(value); if (value && !strcmp(value, eq+1)) { - echo[ifl+1] = 1; - } else echo[ifl+1] = 0; + state->echo[state->ifl + 1] = 1; + } else state->echo[state->ifl + 1] = 0; //fprintf(stderr, "IFEQ(%s)(%s)=%d\n", buf, eq+1, echo[ifl]); } else { value = spp_var_get(buf); if (!value || *value=='\0') - echo[ifl+1] = 1; - else echo[ifl+1] = 0; + state->echo[state->ifl + 1] = 1; + else state->echo[state->ifl + 1] = 0; //fprintf(stderr, "IFEQ(%s)(%s)=%d\n", buf, value, echo[ifl]); } return 1; @@ -238,7 +238,7 @@ static TAG_CALLBACK(spp_grepline) { char *ptr; int line; - if (!echo[ifl]) return 1; + if (!state->echo[state->ifl]) return 1; ptr = strchr(buf, ' '); if (ptr) { *ptr= '\0'; @@ -257,28 +257,28 @@ static TAG_CALLBACK(spp_grepline) { } static TAG_CALLBACK(spp_else) { - echo[ifl] = echo[ifl] ? 0 : 1; + state->echo[state->ifl] = state->echo[state->ifl] ? 0 : 1; return 0; } static TAG_CALLBACK(spp_ifnot) { - spp_if (buf, out); - spp_else (buf, out); + spp_if (state, buf, out); + spp_else (state, buf, out); return 1; } static TAG_CALLBACK(spp_ifin) { char *var, *ptr; - if (!echo[ifl]) { + if (!state->echo[state->ifl]) { return 1; } ptr = strchr (buf, ' '); - echo[ifl + 1] = 0; + state->echo[state->ifl + 1] = 0; if (ptr) { *ptr='\0'; var = getenv(buf); if (strstr (ptr + 1, var)) { - echo[ifl + 1] = 1; + state->echo[state->ifl + 1] = 1; } } return 1; @@ -289,11 +289,11 @@ static TAG_CALLBACK(spp_endif) { } static TAG_CALLBACK(spp_default) { - if (!echo[ifl]) { + if (!state->echo[state->ifl]) { return 0; } if (buf[-1] != ';') { /* commented tag */ - fprintf (stderr, "WARNING: invalid command: '%s' at line %d\n", buf, lineno); + fprintf (stderr, "WARNING: invalid command: '%s' at line %d\n", buf, state->lineno); } return 0; } @@ -318,7 +318,7 @@ static TAG_CALLBACK(spp_switch) { } static TAG_CALLBACK(spp_case) { - echo[ifl] = strcmp (buf, spp_switch_str)?0:1; + state->echo[state->ifl] = strcmp (buf, spp_switch_str)?0:1; return 0; } diff --git a/spp.c b/spp.c index e32c5a0..d8b800c 100644 --- a/spp.c +++ b/spp.c @@ -3,19 +3,6 @@ #include "spp.h" #include "config.h" -// TODO: avoid globals - -static char *lbuf = NULL; -static int lbuf_s = 1024; -static int lbuf_n = 0; -static int incmd = 0; -static int printed = 0; -static char *tag_pre, *tag_post, *token = NULL; - -int lineno = 1; -int tag_begin, echo[MAXIFL]; -int ifl = 0; /* conditional nest level */ - int spp_run(char *buf, Output *out) { int i, ret = 0; char *tok; @@ -29,8 +16,8 @@ int spp_run(char *buf, Output *out) { } } - if (token) { - tok = strstr (buf, token); + if (proc->token) { + tok = strstr (buf, proc->token); if (tok) { *tok = '\0'; tok = tok + 1; @@ -46,14 +33,14 @@ int spp_run(char *buf, Output *out) { if (out->fout) { fflush (out->fout); } - ret = tags[i].callback (tok, out); - ifl += ret; + ret = tags[i].callback (&proc->state, tok, out); + proc->state.ifl += ret; if (ret == -1) { break; } if (ret) { - if (ifl < 0 || ifl >= MAXIFL) { + if (proc->state.ifl < 0 || proc->state.ifl >= MAXIFL) { fprintf (stderr, "Nested conditionals parsing error.\n"); break; } @@ -78,13 +65,13 @@ static char *spp_run_str(char *buf, int *rv) { return b; } -void lbuf_strcat(char *dst, char *src) { +void lbuf_strcat(SppBuf *dst, char *src) { int len = strlen (src); - if (!lbuf || (len + lbuf_n) > lbuf_s) { - lbuf = realloc (lbuf, lbuf_s << 1); + if (!dst->lbuf || (len + dst->lbuf_n) > dst->lbuf_s) { + dst->lbuf = realloc (dst->lbuf, dst->lbuf_s << 1); } - memcpy (lbuf + lbuf_n, src, len + 1); - lbuf_n += len; + memcpy (dst->lbuf + dst->lbuf_n, src, len + 1); + dst->lbuf_n += len; } void do_printf(Output *out, char *str, ...) { @@ -100,11 +87,12 @@ void do_printf(Output *out, char *str, ...) { va_end (ap); } -void do_fputs(Output *out, char *str) { +int do_fputs(Output *out, char *str) { int i; - for (i = 0; i <= ifl; i++) { - if (!echo[i]) { - return; + int printed = 0; + for (i = 0; i <= proc->state.ifl; i++) { + if (!proc->state.echo[i]) { + return printed; } } if (str[0]) { @@ -117,6 +105,7 @@ void do_fputs(Output *out, char *str) { fprintf (out->fout, "%s", str); } } + return printed; } void spp_eval(char *buf, Output *out) { @@ -124,12 +113,12 @@ void spp_eval(char *buf, Output *out) { char *ptrr = NULL; int delta; - printed = 0; + int printed = 0; retry: /* per word */ - if (!tag_pre && token) { + if (!proc->tag_pre && proc->token) { do { - ptr = strstr (buf, token); + ptr = strstr (buf, proc->token); if (ptr) { *ptr = '\0'; } @@ -145,44 +134,47 @@ void spp_eval(char *buf, Output *out) { return; } - if (!tag_post) { + if (!proc->tag_post) { /* handle per line here ? */ return; } // TODO: do it in scope! - delta = strlen (tag_post); + delta = strlen (proc->tag_post); /* (pre) tag */ - ptr = tag_pre? strstr (buf, tag_pre): NULL; + ptr = proc->tag_pre? strstr (buf, proc->tag_pre): NULL; if (ptr) { D printf ("==> 0.0 (%s)\n", ptr); - incmd = 1; - if (!tag_begin || (tag_begin && ptr == buf)) { + if (!proc->tag_begin || (proc->tag_begin && ptr == buf)) { *ptr = '\0'; - ptr = ptr + strlen (tag_pre); - do_fputs (out, buf); + ptr = ptr + strlen (proc->tag_pre); + if (do_fputs (out, buf)) { + printed = 1; + } D printf ("==> 0 (%s)\n", ptr); } - ptrr = strstr (ptr + strlen (tag_pre), tag_pre); + ptrr = strstr (ptr + strlen (proc->tag_pre), proc->tag_pre); } /* (post) tag */ if (!ptr) { - do_fputs (out, buf); + if (do_fputs (out, buf)) { + printed = 1; + } return; } - ptr2 = strstr (ptr, tag_post); + ptr2 = strstr (ptr, proc->tag_post); if (ptr2) { *ptr2 = '\0'; if (ptrr) { if (ptrr < ptr2) { char *p = strdup (ptr2 + 2); - char *s = spp_run_str (ptrr + strlen (tag_pre), NULL); + char *s = spp_run_str (ptrr + strlen (proc->tag_pre), NULL); D fprintf (stderr, "strcpy(%s)(%s)\n", ptrr, s); strcpy (ptrr, s); free (s); - ptr[-2] = tag_pre[0]; // XXX -2 check underflow? + ptr[-2] = proc->tag_pre[0]; // XXX -2 check underflow? D fprintf (stderr, "strcat(%s)(%s)\n", ptrr, p); strcat (ptrr, p); @@ -193,21 +185,22 @@ void spp_eval(char *buf, Output *out) { goto retry; } } - incmd = 0; - if (lbuf && lbuf[0]) { - D printf("==> 1 (%s)\n", lbuf); + if (proc->buf.lbuf && proc->buf.lbuf[0]) { + D printf("==> 1 (%s)\n", proc->buf.lbuf); if (ptr) { - lbuf_strcat (lbuf, buf); - do_fputs (out, lbuf); + lbuf_strcat (&proc->buf, buf); + if (do_fputs (out, buf)) { + printed = 1; + } spp_run (ptr, out); } else { - lbuf_strcat (lbuf, buf); - D printf ("=(1)=> spp_run(%s)\n", lbuf); - spp_run (lbuf+delta, out); - D printf ("=(1)=> spp_run(%s)\n", lbuf); + lbuf_strcat (&proc->buf, buf); + D printf ("=(1)=> spp_run(%s)\n", proc->buf.lbuf); + spp_run (proc->buf.lbuf + delta, out); + D printf ("=(1)=> spp_run(%s)\n", proc->buf.lbuf); } - lbuf[0]='\0'; - lbuf_n = 0; + proc->buf.lbuf[0]='\0'; + proc->buf.lbuf_n = 0; } else { D printf ("==> 2 (%s)\n", ptr); if (ptr) { @@ -220,13 +213,17 @@ void spp_eval(char *buf, Output *out) { D printf (" ==> 2.1: continue(%s)\n", buf); goto retry; } else { - do_fputs (out, "\n"); + if (do_fputs (out, buf)) { + printed = 1; + } } } - do_fputs (out, ptr2 + delta); + if (do_fputs (out, buf)) { + printed = 1; + } } else { D printf ("==> 3\n"); - lbuf_strcat (lbuf, ptr); + lbuf_strcat (&proc->buf, ptr); } } @@ -234,14 +231,15 @@ void spp_eval(char *buf, Output *out) { void spp_io(FILE *in, Output *out) { char buf[4096]; int lines; - if (!lbuf) { - lbuf = calloc (1, 4096); + if (!proc->buf.lbuf) { + proc->buf.lbuf = calloc (1, 4096); } - if (!lbuf) { + if (!proc->buf.lbuf) { fprintf (stderr, "Out of memory.\n"); return; } - lbuf[0] = '\0'; + proc->buf.lbuf[0] = '\0'; + proc->buf.lbuf_s = 1024; while (!feof (in)) { buf[0] = '\0'; // ??? fgets (buf, 1023, in); @@ -268,9 +266,9 @@ void spp_io(FILE *in, Output *out) { } } spp_eval (buf, out); - lineno += lines; + proc->state.lineno += lines; } - do_fputs (out, lbuf); + do_fputs (out, proc->buf.lbuf); } int spp_file(const char *file, Output *out) { @@ -317,15 +315,12 @@ void spp_proc_set(struct Proc *p, char *arg, int fail) { proc = p; } if (proc) { - // TODO: wtf! - tag_pre = proc->tag_pre; - tag_post = proc->tag_post; + proc->state.lineno = 1; + proc->state.ifl = 0; for (i = 0; i < MAXIFL; i++) { - echo[i] = proc->default_echo; + proc->state.echo[i] = proc->default_echo; } - token = proc->token; - tag_begin = proc->tag_begin; - args = (struct Arg*)proc->args; + //args = (struct Arg*)proc->args; tags = (struct Tag*)proc->tags; } } diff --git a/spp.h b/spp.h index 4b73003..8b2d46b 100644 --- a/spp.h +++ b/spp.h @@ -45,9 +45,22 @@ typedef struct { int size; } Output; + +typedef struct SppState { + int lineno; + int echo[MAXIFL]; + int ifl; +} SppState; + +typedef struct SppBuf { + char *lbuf; + int lbuf_s; + int lbuf_n; +} SppBuf; + #define ARG_CALLBACK(x) int x (char *arg) /* XXX swap arguments ?? */ -#define TAG_CALLBACK(x) int x (char *buf, Output *out) +#define TAG_CALLBACK(x) int x (SppState *state, Output *out, char *buf) #define PUT_CALLBACK(x) int x (Output *out, char *buf) #define IS_SPACE(x) ((x==' ')||(x=='\t')||(x=='\r')||(x=='\n')) @@ -76,10 +89,10 @@ struct Proc { int chop; int tag_begin; int default_echo; + SppState state; + SppBuf buf; }; - - int spp_file(const char *file, Output *out); int spp_run(char *buf, Output *out); void spp_eval(char *buf, Output *out);