home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 3 / PDCD_3.iso / tex / texsrc2 / Src / web2c / c / fixwrites next >
Encoding:
Text File  |  1993-01-29  |  7.3 KB  |  414 lines

  1. /* fixwrites -- convert Pascal write/writeln's into fprintf's or putc's.
  2.    Originally by Tim Morgan, October 10, 1987.  */
  3.  
  4. #include "config.h"
  5.  
  6.  
  7. char buf[BUFSIZ], filename[PATH_MAX], args[100];
  8. char *file, *argp, *as, *cmd;
  9.  
  10. int tex = false;
  11.  
  12.  
  13.  
  14. /* Replace the last (should be only) newline in S with a null.  */
  15.  
  16. void
  17. remove_newline (s)
  18.      char *s;
  19. {
  20.   char *temp = strrchr (s, '\n');
  21.   if (temp == NULL)
  22.     {
  23.       fprintf (stderr, "Lost newline somehow.\n");
  24.       uexit (1);
  25.     }
  26.  
  27.   *temp = 0;
  28. }
  29.  
  30.  
  31. char *
  32. insert_long (cp)
  33.      char *cp;
  34. {
  35.   char tbuf[BUFSIZ];
  36.   register int i;
  37.  
  38.   for (i = 0; &buf[i] < cp; ++i)
  39.     tbuf[i] = buf[i];
  40.   strcpy (&tbuf[i], "(long)");
  41.   strcpy (&tbuf[i + 6], cp);
  42.   strcpy (buf, tbuf);
  43.   return cp + 6;
  44. }
  45.  
  46.  
  47. void
  48. join (cp)
  49.      char *cp;
  50. {
  51.   char temp[BUFSIZ], *tp;
  52.  
  53.   if (!fgets (temp, BUFSIZ, stdin))
  54.     return;
  55.   remove_newline (temp);
  56.  
  57.   *cp++ = ' ';
  58.   for (tp = temp; *tp == ' '; ++tp)
  59.     ;
  60.  
  61.   strcpy (cp, tp);
  62. }
  63.  
  64.  
  65. void
  66. do_blanks (indent)
  67.      int indent;
  68. {
  69.   register int i;
  70.  
  71.   for (i = 0; i < indent / 8; i++)
  72.     putchar ('\t');
  73.   indent %= 8;
  74.   for (i = 0; i < indent; i++)
  75.     putchar (' ');
  76. }
  77.  
  78.  
  79. /*
  80.  * Return true if we have a whole write/writeln statement.  We determine
  81.  * this by matching parens, ignoring those within strings.
  82.  */
  83. whole (cp)
  84.      register char *cp;
  85. {
  86.   register int depth = 0;
  87.  
  88.   while (cp && *cp)
  89.     {
  90.       switch (*cp)
  91.     {
  92.     case '(':
  93.       ++depth;
  94.       break;
  95.     case ')':
  96.       --depth;
  97.       break;
  98.     case '"':
  99.       for (++cp; cp && *cp && *cp != '"'; ++cp)
  100.         if (*cp == '\\')
  101.           ++cp;
  102.       break;
  103.     case '\'':
  104.       ++cp;
  105.       if (*cp == '\\') ++cp;
  106.       ++cp;
  107.       break;
  108.     }
  109.       ++cp;
  110.     }
  111.   return depth <= 0;
  112. }
  113.  
  114.  
  115. /* Skips to the next , or ), skipping over balanced paren pairs.  */
  116.  
  117. char *
  118. skip_balanced (cp)
  119.      char *cp;
  120. {
  121.   register int depth = 0;
  122.  
  123.   while (depth > 0 || (*cp != ',' && *cp != ')'))
  124.     {
  125.       switch (*cp)
  126.     {
  127.     case '(':
  128.       ++depth;
  129.       break;
  130.     case ')':
  131.       --depth;
  132.       break;
  133.     }
  134.       ++cp;
  135.     }
  136.   return cp;
  137. }
  138.  
  139.  
  140. /* Return true if c appears, except inside a quoted string */
  141.  
  142. int
  143. bare (cp, c)
  144.   char *cp;
  145.   char c;
  146. {
  147.   for (; *cp && *cp != c; ++cp)
  148.     {
  149.       if (*cp == '"')
  150.     {
  151.       ++cp;            /* skip over initial quotation mark */
  152.       while (*cp && *cp != '"')
  153.         {            /* skip to closing double quote */
  154.           if (*cp == '\\')
  155.         ++cp;
  156.           ++cp;
  157.         }
  158.     }
  159.       else if (*cp == '\'')
  160.     {
  161.       ++cp;            /* skip to contained char */
  162.       if (*cp == '\'')
  163.         ++cp;        /* if backslashed, it's double */
  164.       ++cp;            /* skip to closing single-quote mark */
  165.     }
  166.     }
  167.   return *cp;
  168. }
  169.  
  170.  
  171. int
  172. main (argc, argv)
  173.     int argc;
  174.     char *argv[];
  175. {
  176.   register char *cp;
  177.   int blanks_done, indent, i;
  178.   char *program_name = "";
  179.  
  180.   for (i = 1; i < argc; i++)
  181.     {
  182.       switch (argv[i][1])
  183.     {
  184.     case 't':
  185.       tex = true;
  186.       break;
  187.  
  188.     default:
  189.       program_name = argv[i];
  190.     }
  191.     }
  192.  
  193.   while (fgets (buf, BUFSIZ, stdin))
  194.     {
  195.       remove_newline (buf);
  196.       blanks_done = false;
  197.  
  198.       for (cp = buf; *cp; ++cp) ;
  199.  
  200.       while (*--cp == ' ') ;
  201.  
  202.       while (*cp == '.')
  203.     {
  204.       join (cp + 1);
  205.       while (*cp)
  206.         ++cp;
  207.       while (*--cp == ' ') ;
  208.     }
  209.  
  210.       for (cp = buf, indent = 0; *cp == ' ' || *cp == '\t'; ++cp)
  211.     {
  212.       if (*cp == ' ')
  213.         indent++;
  214.       else
  215.         indent += 8;
  216.     }
  217.  
  218.       if (!*cp)
  219.     {            /* All blanks, possibly with "{" */
  220.       puts (buf);
  221.       continue;
  222.     }
  223.       if (*cp == '{')
  224.  
  225.         {
  226.       do_blanks (indent);
  227.       putchar ('{');
  228.       ++cp;
  229.       while (*cp == ' ' || *cp == '\t')
  230.         ++cp;
  231.       blanks_done = true;
  232.       if (!*cp)
  233.         {
  234.           putchar ('\n');
  235.           continue;
  236.         }
  237.     }
  238.  
  239.       if (!blanks_done)
  240.     do_blanks (indent);
  241.  
  242.       if (strncmp (cp, "read ( input", 12) == 0)
  243.     {
  244.       char variable_name[20];
  245.       if (sscanf (cp, "read ( input , %s )", variable_name) != 1)
  246.             {
  247.             fprintf (stderr, "sscanf failed\n");
  248.               uexit (1);
  249.             }
  250.       printf ("%s = getint();\n", variable_name);
  251.       continue;
  252.     }
  253.  
  254.       if (strncmp (cp, "lab", 3) == 0 && strchr (cp, ':'))
  255.     {
  256.       do
  257.         {
  258.           putchar (*cp);
  259.         }
  260.           while (*cp++ != ':');
  261.  
  262.           while (*cp == ' ')
  263.         ++cp;
  264.       putchar (' ');
  265.     }
  266.  
  267.       if (strncmp (cp, "else write", 10) == 0)
  268.     {
  269.       puts ("else");
  270.       do_blanks (indent);
  271.       cp += 5;
  272.       while (*cp == ' ')
  273.         ++cp;
  274.     }
  275.  
  276.       if (bare (cp, '{'))
  277.     {
  278.       while (*cp != '{')
  279.         {
  280.           putchar (*cp);
  281.           ++cp;
  282.         }
  283.       ++cp;
  284.       puts ("{");
  285.       indent += 4;
  286.       do_blanks (indent);
  287.       while (*cp == ' ')
  288.         ++cp;
  289.     }
  290.  
  291.       if (strncmp (cp, "write (", 7) && strncmp (cp, "writeln (", 9))
  292.     {
  293.       /* if not a write/writeln, just copy it to stdout and continue */
  294.       puts (cp);
  295.       continue;
  296.     }
  297.       cmd = cp;
  298.       while (!whole (buf))    /* make sure we have whole stmt */
  299.     {
  300.       fgets (&buf[strlen (buf)], BUFSIZ - strlen (buf), stdin);
  301.       remove_newline (buf);
  302.     }
  303.  
  304.       while (*cp != '(')
  305.     ++cp;
  306.       ++cp;
  307.       while (*(cp + 1) == ' ')
  308.     ++cp;
  309.  
  310.       /* Some writes start with a variable, instead of a file. */
  311.       if (*(cp + 1) == '"' || *(cp + 1) == '\''
  312.           || strncmp (cp + 1, "buffer", 6) == 0
  313.           || strncmp (cp + 1, "dig", 3) == 0
  314.           || strncmp (cp + 1, "xchr", 4) == 0
  315.           || strncmp (cp + 1, "versionstring", 13) == 0
  316.           || strncmp (cp + 1, "k ,", 3) == 0
  317.           || strncmp (cp + 1, "s ,", 3) == 0)
  318.     strcpy (filename, "stdout");
  319.       else
  320.     {
  321.       file = filename;
  322.       while (*cp != ',' && *cp != ')')
  323.         *file++ = *cp++;
  324.       *file = '\0';
  325.     }
  326.       if (*cp == ')')
  327.     {
  328.       printf ("putc ('\\n', %s);\n", filename);
  329.       continue;
  330.     }
  331.       argp = ++cp;
  332.       as = args;
  333.       while (*cp == ' ')
  334.     ++cp;
  335.       while (*cp != ')')
  336.     {
  337.       if (*cp == '\'' || strncmp (cp, "xchr", 4) == 0
  338.           || strncmp (cp, "ASCII04", 7) == 0
  339.           || strncmp (cp, "ASCII1", 6) == 0
  340.           || strncmp (cp, "ASCIIall", 8) == 0              
  341.           || strncmp (cp, "nameoffile", 10) == 0
  342.           || (strncmp (cp, "buffer", 6) == 0
  343.                   && (strcmp (program_name, "vptovf") == 0
  344.                       || strcmp (program_name, "pltotf") == 0))
  345.           || strncmp (cp, "months", 6) == 0)
  346.         {
  347.           *as++ = '%';
  348.           *as++ = 'c';
  349.           if (tex && strncmp (cp, "xchr", 4) == 0)
  350.         {
  351.           *cp = 'X';
  352.           cp = strchr (cp, '[');
  353.           *cp = '(';
  354.           cp = strchr (cp, ']');
  355.           *cp++ = ')';
  356.         }
  357.           else if (*cp == '\'')
  358.         cp += 2;
  359.         }
  360.           
  361.       else if (*cp == '"')
  362.         {
  363.           *as++ = '%';
  364.           *as++ = 's';
  365.           while (*++cp != '"')    /* skip to end of string */
  366.         if (*cp == '\\')
  367.           ++cp;        /* allow \" in string */
  368.         }
  369.  
  370.           /* More kludge -- versionstring is a string, not a number, so
  371.              we have to use %s.  */
  372.           else if (strncmp (cp, "versionstring", 13) == 0)
  373.             {
  374.               *as++ = '%';
  375.               *as++ = 's';
  376.             }
  377.  
  378.           else
  379.         {
  380.           *as++ = '%';
  381.           *as++ = 'l';
  382.           *as++ = 'd';
  383.           cp = insert_long (cp);
  384.           cp = skip_balanced (cp);    /* It's a numeric expression */
  385.         }
  386.       while (*cp != ',' && *cp != ')')
  387.         ++cp;
  388.       while (*cp == ',' || *cp == ' ')
  389.         ++cp;
  390.     }
  391.  
  392.       if (strncmp (cmd, "writeln", 7) == 0)
  393.     {
  394.       *as++ = '\\';
  395.       *as++ = 'n';
  396.     }
  397.  
  398.       *as = '\0';
  399.       if (strcmp (args, "%c") == 0)
  400.     {
  401.       for (as = argp; *as; ++as) ;
  402.       while (*--as != ')') ;
  403.       *as = '\0';
  404.       printf ("putc (%s, %s);\n", argp, filename);
  405.     }
  406.       else if (STREQ (args, "%s"))
  407.         printf ("Fputs(%s, %s\n", filename, argp);
  408.       else
  409.         printf ("fprintf(%s, \"%s\", %s\n", filename, args, argp);
  410.     }
  411.  
  412.   uexit (0);
  413. }
  414.