diff options
author | Karl Berry <karl@freefriends.org> | 2006-01-17 21:41:51 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2006-01-17 21:41:51 +0000 |
commit | 487ca4806cc046076293cf6cc5fbba0db282bac7 (patch) | |
tree | 847b412ab5158dd7bdd7ed7e5a4cc3fbca94be32 /Build/source/texk/web2c/web2c/fixwrites.c | |
parent | a3d3111bfe26b8e5f5bc6049dfb2a4ca2edc7881 (diff) |
texk 1
git-svn-id: svn://tug.org/texlive/trunk@1485 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/web2c/web2c/fixwrites.c')
-rw-r--r-- | Build/source/texk/web2c/web2c/fixwrites.c | 450 |
1 files changed, 450 insertions, 0 deletions
diff --git a/Build/source/texk/web2c/web2c/fixwrites.c b/Build/source/texk/web2c/web2c/fixwrites.c new file mode 100644 index 00000000000..7a7e6a2aa1e --- /dev/null +++ b/Build/source/texk/web2c/web2c/fixwrites.c @@ -0,0 +1,450 @@ +/* fixwrites -- convert Pascal write/writeln's into fprintf's or putc's. + Originally by Tim Morgan, October 10, 1987. */ + +#include "config.h" +#include <kpathsea/c-pathmx.h> + +int argc; +char **gargv; + +char buf[BUFSIZ], filename[PATH_MAX], args[100]; +char *file, *argp, *as, *cmd; + +int tex = false; + +/* Replace the last (should be only) newline in S with a null. */ + +static void +remove_newline P1C(string, s) +{ + char *temp = strrchr (s, '\n'); + if (temp == NULL) + { + fprintf (stderr, "Lost newline somehow.\n"); + /* This is so the convert script can delete the output file on error. */ + puts ("@error@"); + exit (1); + } + + *temp = 0; +} + + +static char * +insert_long P1C(string, cp) +{ + char tbuf[BUFSIZ]; + register int i; + + for (i = 0; &buf[i] < cp; ++i) + tbuf[i] = buf[i]; + strcpy (&tbuf[i], "(long)"); + strcpy (&tbuf[i + 6], cp); + strcpy (buf, tbuf); + return cp + 6; +} + + +static void +join P1C(string, cp) +{ + char temp[BUFSIZ], *tp; + + if (!fgets (temp, BUFSIZ, stdin)) + return; + remove_newline (temp); + + *cp++ = ' '; + for (tp = temp; *tp == ' '; ++tp) + ; + + strcpy (cp, tp); +} + + +static void +do_blanks P1C(int, indent) +{ + register int i; + + for (i = 0; i < indent / 8; i++) + putchar ('\t'); + indent %= 8; + for (i = 0; i < indent; i++) + putchar (' '); +} + + +/* Return true if we have a whole write/writeln statement. We determine + this by matching parens, ignoring those within strings. */ +static int +whole P1C(string, cp) +{ + register int depth = 0; + + while (cp && *cp) + { + switch (*cp) + { + case '(': + ++depth; + break; + case ')': + --depth; + break; + case '"': + for (++cp; cp && *cp && *cp != '"'; ++cp) + if (*cp == '\\') + ++cp; + break; + case '\'': + ++cp; + if (*cp == '\\') ++cp; + ++cp; + break; + } + ++cp; + } + return depth <= 0; +} + + +/* Skips to the next , or ), skipping over balanced paren pairs. */ + +static char * +skip_balanced P1C(string, cp) +{ + register int depth = 0; + + while (depth > 0 || (*cp != ',' && *cp != ')')) + { + switch (*cp) + { + case '(': + ++depth; + break; + case ')': + --depth; + break; + } + ++cp; + } + return cp; +} + + +/* Return true if c appears, except inside a quoted string */ + +static int +bare P2C(string, cp, char, c) +{ + for (; *cp && *cp != c; ++cp) + { + if (*cp == '"') + { + ++cp; /* skip over initial quotation mark */ + while (*cp && *cp != '"') + { /* skip to closing double quote */ + if (*cp == '\\') + ++cp; + ++cp; + } + } + else if (*cp == '\'') + { + ++cp; /* skip to contained char */ + if (*cp == '\'') + ++cp; /* if backslashed, it's double */ + ++cp; /* skip to closing single-quote mark */ + } + } + return *cp; +} + + +/* xchr[...] is supposed to be replaced by Xchr(...) when characters + take more than a single octet each, as is the case in Omega. Now + there are several occurrences of xchr[...[...]...], which are + translated into Xchr(...[...)...], and the compiler dies on syntax + errors. Ensures that it is the matching bracket that is replaced, + not the first one. */ + +char * +advance_cp P2C(char *, cp, int, lefts) +{ + char *cp1; + char *cp2; + + cp1 = strchr (cp + 1, ']'); + cp2 = strchr (cp + 1, '['); + if (cp2 && cp2 < cp1) + return advance_cp (cp2, lefts + 1); + if (lefts == 1) + return cp1; + return advance_cp (cp1, lefts - 1); +} + +int +main P2C(int, argc, string *, argv) +{ + register char *cp; + int blanks_done, indent, i; + char *program_name = ""; + + for (i = 1; i < argc; i++) + { + if (STREQ(argv[i],"-t")) + tex = true; + else + program_name = argv[i]; + } + + while (fgets (buf, BUFSIZ, stdin)) + { + remove_newline (buf); + blanks_done = false; + + for (cp = buf; *cp; ++cp) ; + + while (cp != buf && *--cp == ' ') ; + + while (*cp == '.') + { + join (cp + 1); + while (*cp) + ++cp; + while (*--cp == ' ') ; + } + + for (cp = buf, indent = 0; *cp == ' ' || *cp == '\t'; ++cp) + { + if (*cp == ' ') + indent++; + else + indent += 8; + } + + if (!*cp) + { /* All blanks, possibly with "{" */ + puts (buf); + continue; + } + if (*cp == '{') + + { + do_blanks (indent); + putchar ('{'); + ++cp; + while (*cp == ' ' || *cp == '\t') + ++cp; + blanks_done = true; + if (!*cp) + { + putchar ('\n'); + continue; + } + } + + if (!blanks_done) + do_blanks (indent); + + if (strncmp (cp, "read ( input", 12) == 0) + { + char variable_name[20]; + if (sscanf (cp, "read ( input , %s )", variable_name) != 1) + { + fprintf (stderr, "sscanf failed\n"); + exit (1); + } + printf ("%s = getint();\n", variable_name); + continue; + } + + if (strncmp (cp, "lab", 3) == 0 && strchr (cp, ':')) + { + do + { + putchar (*cp); + } + while (*cp++ != ':'); + + while (*cp == ' ') + ++cp; + putchar (' '); + } + + if (strncmp (cp, "else write", 10) == 0) + { + puts ("else"); + do_blanks (indent); + cp += 5; + while (*cp == ' ') + ++cp; + } + + if (bare (cp, '{')) + { + while (*cp != '{') + { + putchar (*cp); + ++cp; + } + ++cp; + puts ("{"); + indent += 4; + do_blanks (indent); + while (*cp == ' ') + ++cp; + } + + if (strncmp (cp, "write (", 7) && strncmp (cp, "writeln (", 9)) + { + /* if not a write/writeln, just copy it to stdout and continue */ + puts (cp); + continue; + } + cmd = cp; + while (!whole (buf)) /* make sure we have whole stmt */ + { + fgets (&buf[strlen (buf)], BUFSIZ - strlen (buf), stdin); + remove_newline (buf); + } + + while (*cp != '(') + ++cp; + ++cp; + while (*(cp + 1) == ' ') + ++cp; + + /* Some writes start with a variable, instead of a file. */ + if (*(cp + 1) == '"' || *(cp + 1) == '\'' + || strncmp (cp + 1, "buffer", 6) == 0 + || strncmp (cp + 1, "xchr", 4) == 0 + || strncmp (cp + 1, "k ,", 3) == 0 + || strncmp (cp + 1, "s ,", 3) == 0 + || strncmp (cp + 1, "dig", 3) == 0 + || strncmp (cp + 1, "HEX", 3) == 0 + || strncmp (cp + 1, "versionstring", 13) == 0 + || strncmp (cp + 1, "kpathseaversionstring", 21) == 0 + ) + strcpy (filename, "stdout"); + else + { + file = filename; + while (*cp != ',' && *cp != ')') + *file++ = *cp++; + *file = '\0'; + } + if (*cp == ')') + { + printf ("putc ('\\n', %s);\n", filename); + continue; + } + argp = ++cp; + as = args; + while (*cp == ' ') + ++cp; + while (*cp != ')') + { + if (*cp == '\'' || strncmp (cp, "xchr", 4) == 0 + || (strncmp (cp ,"HEX", 3) == 0 + && (STREQ (program_name, "ofm2opl") + || STREQ (program_name, "opl2ofm") + || STREQ (program_name, "ovp2ovf") + || STREQ (program_name, "ovf2ovp"))) + || strncmp (cp, "ASCII04", 7) == 0 + || strncmp (cp, "ASCII1", 6) == 0 + || strncmp (cp, "ASCIIall", 8) == 0 + || strncmp (cp, "months", 6) == 0 + || strncmp (cp, "nameoffile", 10) == 0 + || (strncmp (cp, "buffer", 6) == 0 + && (STREQ (program_name, "vptovf") + || STREQ (program_name, "pltotf") + || STREQ (program_name, "ovp2ovf") + || STREQ (program_name, "ofm2opl"))) + || (((strncmp (cp, "buf", 3) == 0 + || strncmp (cp, "xdig", 4) == 0 + || strncmp (cp, "xext", 4) == 0 + || strncmp (cp, "xhyf", 4) == 0) + && STREQ (program_name, "patgen"))) + ) + { + *as++ = '%'; + *as++ = 'c'; + if (tex && strncmp (cp, "xchr", 4) == 0) + { + *cp = 'X'; + cp = strchr (cp, '['); + *cp = '('; + cp = advance_cp(cp,1); + *cp++ = ')'; + } + else if (*cp == '\'') + cp += 2; + } + + else if (*cp == '"') + { + *as++ = '%'; + *as++ = 's'; + while (*++cp != '"') /* skip to end of string */ + if (*cp == '\\') + ++cp; /* allow \" in string */ + } + + /* More kludges -- recognize some things as strings and use %s: + - versionstring + - poolname + - formatengine */ + else if (strncmp (cp, "versionstring", 13) == 0 + || strncmp (cp, "poolname", 8) == 0 + || strncmp (cp, "formatengine", 12) == 0) + { + *as++ = '%'; + *as++ = 's'; + } + + /* And yet another kludge, to handle stringcast (<whatever>) */ + else if (strncmp (cp, "stringcast", 10) == 0) + { + *as++ = '%'; + *as++ = 's'; + cp = skip_balanced (cp); /* Skip cast expression */ + } + + else + { + *as++ = '%'; + *as++ = 'l'; + *as++ = 'd'; + cp = insert_long (cp); + cp = skip_balanced (cp); /* It's a numeric expression */ + } + while (*cp != ',' && *cp != ')') + ++cp; + while (*cp == ',' || *cp == ' ') + ++cp; + } + + if (strncmp (cmd, "writeln", 7) == 0) + { + *as++ = '\\'; + *as++ = 'n'; + } + + *as = '\0'; + if (strcmp (args, "%c") == 0) + { + for (as = argp; *as; ++as) ; + while (*--as != ')') ; + *as = '\0'; + printf ("putc (%s, %s);\n", argp, filename); + } + else if (STREQ (args, "%s")) + printf ("Fputs (%s, %s\n", filename, argp); + else + printf ("fprintf (%s, \"%s\", %s\n", filename, args, argp); + } + + return EXIT_SUCCESS; +} |