int evalcmd(int argc, char **argv) { char *p; char *concat; char **ap; if (argc > 1) { p = argv[1]; if (argc > 2) { STARTSTACKSTR(concat); ap = argv + 2; for (;;) { concat = stputs(p, concat); if ((p = *ap++) == NULL) break; STPUTC(' ', concat); } STPUTC('\0', concat); p = grabstackstr(concat); } return evalstring(p, ~SKIPEVAL); } return 0; }
void add_deps (const char *s) { if (calculating_deps && can_dep) { log_printf (1, "new dependency: \"%s\"\n", s); if (!depstream) depstream = stopen (NULL, NULL); stputs (s, depstream); stputc ('\n', depstream); } }
/* process a block of text like a file */ char *process_text (const char *s) { STREAM *in, *out; char *r; in = stopen (NULL, NULL); out = stopen (NULL, NULL); stputs (s, in); stseek (in, 0, SEEK_SET); process_file (in, out); stclose (in); r = stbuffer (out); return (r) ? r : strdup (""); }
/* executes an extern command and redirects the stdout */ static char *tag_exec (int argc, char *argv[]) { if (argc >= 1) { char *s, *filename = temp_filename (); int outbak = dup (1); int outdsc = open (filename, O_WRONLY | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE); char buf[4096] = ""; STREAM *in; int c; /* make the command to run */ for (c = 0; c < argc; c++) { s = process_text (argv[c]); sprintf (buf + strlen (buf), "%s ", s); free (s); } /* redirect the stdout */ fflush (stdout); dup2 (outdsc, 1); /* run the command */ system (buf); /* restore the stdout */ dup2 (outbak, 1); close (outdsc); close (outbak); /* read the redirected output from the file and put it to the active output stream */ in = stopen (filename, "r"); while (stgets (buf, sizeof (buf), in)) stputs (buf, _o_stream); stclose (in); /* close */ remove (filename); free (filename); } /* nothing to add */ return NULL; }
static void read_function_body (STREAM * in, STREAM * out) { char *s, *buf = current_line; int done = FALSE; do { for (s = current_col; *s; s++) { /* tag beginning */ if ((*s == '<') && (s[1] == '!')) { char *tag = s + 1; int c; /* jump the comment? */ if ((s[2] == '-') && (s[3] == '-')) { if (!kill_comments) stputs ("<!", out); s += 2; for (;;) { if (strncmp (s, "-->", 3) == 0) { if (!kill_comments) stputs ("-->", out); s += 2; break; } else if (*s == 0) { if (!stgets (buf, MAX_BYTES, in)) break; s = buf; } else { if (!kill_comments) stputc (*s, out); s++; } } continue; } /* jump nested tags */ for (c = 0;; s++) { if (*s == '<') c++; else if (*s == '>') { c--; if (c == 0) break; } else if (*s == 0) { if (!stgets (buf + strlen (buf), MAX_BYTES - strlen (buf), in)) break; s--; } } c = *s; *s = 0; /* check for <!end...> */ if (strncmp (tag + 1, "end", 3) == 0) { current_col = s + 1; done = TRUE; break; } /* all other tags go to function */ else { stputc ('<', out); stputs (tag, out); stputc ('>', out); } if (!c) s--; else *s = c; } /* put a character in the output file */ else stputc (*s, out); } if (done) break; current_col = buf; } while (stgets (buf, MAX_BYTES, in)); }
/* process the file `in' and output the result to `out' file */ void process_file (STREAM *in, STREAM *out) { STREAM *old_i_stream = _i_stream; STREAM *old_o_stream = _o_stream; char *old_current_line = current_line; char *old_current_col = current_col; char *s, buf[MAX_BYTES]; _i_stream = in; _o_stream = out; old_current_line = current_line; old_current_col = current_col; new_token (TOK_SPACE); update_state (); while (stgets (buf, MAX_BYTES, in)) { for (s = buf; *s; s++) { /* tag beginning */ if ((*s == '<') && (s[1] == '!')) { int c, i, used = FALSE; int restore = TRUE; char *tag = s + 1; /* jump the comment? */ if ((s[2] == '-') && (s[3] == '-')) { if (!kill_comments) stputs ("<!", out); s += 2; for (;;) { if (strncmp (s, "-->", 3) == 0) { if (!kill_comments) stputs ("-->", out); s += 2; break; } else if (*s == 0) { if (!stgets (buf, MAX_BYTES, in)) break; s = buf; } else { if (!kill_comments) stputc (*s, out); s++; } } continue; } /* jump nested tags */ for (c = 0;; s++) { if (*s == '<') c++; else if (*s == '>') { c--; if (c == 0) break; } else if (*s == 0) { if (!stgets (buf + strlen (buf), MAX_BYTES - strlen (buf), in)) break; s--; } } c = *s; *s = 0; log_printf (2, "tag found: \"%s\"\n", tag + 1); /* check for <!arg...> */ if (strncmp (tag + 1, "arg", 3) == 0) { if (can_attach) { /* <!args...> */ if (tag[4] == 's') { char temp[32]; sprintf (temp, "%d", nargs); stputs (temp, out); } /* <!arg[1-9][0-9]*...> */ else { int arg = strtol (tag + 4, NULL, 10); if ((arg > 0) && (arg <= nargs) && (args[arg - 1])) stputs (args[arg - 1], out); } } used = TRUE; } /* check for built-ins functions <!...> */ if (!used) { for (i = 0; i < ntags; i++) { if (strncmp (tag + 1, tags[i].name, strlen (tags[i].name)) == 0) { int x = tag[1 + strlen (tags[i].name)]; if (IS_BLANK (x) || (!x)) { char *tok, *argv[MAX_ARGS]; char *replacement; char *holder = NULL; int argc = 0; for (tok = own_strtok (tag + 2, &holder), tok = own_strtok (NULL, &holder); tok; tok = own_strtok (NULL, &holder)) argv[argc++] = tok; if ((tags[i].if_tag) || (can_attach)) { current_line = buf; current_col = s + 1; /* call the tag procedure */ replacement = (*tags[i].proc) (argc, argv); if (s != current_col - 1) { s = current_col - 1; restore = FALSE; } /* text to replace */ if (replacement) { stputs (replacement, out); free (replacement); } log_printf (2, "tag \"%s\" was processed\n", tags[i].name); } else log_printf (2, "tag \"%s\" wasn't processed\n", tags[i].name); used = TRUE; break; } } } } /* check for user functional macros <!...> */ if (!used && can_attach) { char *replacement = function_macro (macros_space[nmacros_space-1], tag); if (replacement) { stputs (replacement, out); free (replacement); used = TRUE; } } /* well, this is an unknown tag */ if (!used) { char *ptag = process_text (tag); if (can_attach) stputc ('<', out); if (ptag) { if (can_attach) stputs (ptag, out); free (ptag); } if (can_attach) stputc ('>', out); } if (restore) { if (!c) s--; else *s = c; } } /* put a character in the output file */ else if (can_attach) { char *replacement = NULL; int c, length = 0; /* check for macros */ for (c = 0; c < nmacros_space; c++) { replacement = replace_by_macro (macros_space[c], s, &length); if (replacement) break; } /* just put the character */ if (!replacement) { stputc (*s, out); } /* put the value of the macro */ else { stputs (replacement, out); s += length - 1; free (replacement); } } } } delete_token (); update_state (); _i_stream = old_i_stream; _o_stream = old_o_stream; current_line = old_current_line; current_col = old_current_col; }