home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / OS2 / gnuinfo.zip / util / deref.c next >
C/C++ Source or Header  |  1997-12-26  |  5KB  |  241 lines

  1. /*
  2.  * deref.c
  3.  
  4.  *  compile command:  gcc -g -o deref deref.c
  5.  
  6.  *  execute command:  deref filename.texi > newfile.texi
  7.  
  8.  * To: bob@gnu.ai.mit.edu
  9.  * Subject: another tool
  10.  * Date: 18 Dec 91 16:03:13 EST (Wed)
  11.  * From: gatech!skeeve!arnold@eddie.mit.edu (Arnold D. Robbins)
  12.  *
  13.  * Here is deref.c.  It turns texinfo cross references back into the
  14.  * one argument form. It has the same limitations as fixref; one xref per
  15.  * line and can't cross lines.  You can use it to find references that do
  16.  * cross a line boundary this way:
  17.  *
  18.  *     deref < manual > /dev/null 2>errs
  19.  *
  20.  * (This assumes bash or /bin/sh.)  The file errs will have list of lines
  21.  * where deref could not find matching braces.
  22.  *
  23.  * A gawk manual processed by deref goes through makeinfo without complaint.
  24.  * Compile with gcc and you should be set.
  25.  *
  26.  * Enjoy,
  27.  *
  28.  * Arnold
  29.  * -----------
  30.  */
  31.  
  32. /*
  33.  * deref.c
  34.  *
  35.  * Make all texinfo references into the one argument form.
  36.  *
  37.  * Arnold Robbins
  38.  * arnold@skeeve.atl.ga.us
  39.  * December, 1991
  40.  *
  41.  * Copyright, 1991, Arnold Robbins
  42.  */
  43.  
  44. /*
  45.  * LIMITATIONS:
  46.  *    One texinfo cross reference per line.
  47.  *    Cross references may not cross newlines.
  48.  *    Use of fgets for input (to be fixed).
  49.  */
  50.  
  51. #include <config.h>
  52.  
  53. #include <stdio.h>
  54. #include <ctype.h>
  55. #include <errno.h>
  56.  
  57. /* for gcc on the 3B1, delete if this gives you grief */
  58. extern int fclose (FILE * fp);
  59. extern int fprintf (FILE * fp, const char *str,...);
  60.  
  61. extern char *strerror (int errno);
  62. extern char *strchr (char *cp, int ch);
  63. extern int strncmp (const char *s1, const char *s2, int count);
  64.  
  65. extern int errno;
  66.  
  67. void process (FILE * fp);
  68. void repair (char *line, char *ref, int toffset);
  69.  
  70. int Errs = 0;
  71. char *Name = "stdin";
  72. int Line = 0;
  73. char *Me;
  74.  
  75. /* main --- handle arguments, global vars for errors */
  76.  
  77. int
  78. main (int argc, char **argv)
  79. {
  80.   FILE *fp;
  81.  
  82.   Me = argv[0];
  83.  
  84.   if (argc == 1)
  85.     process (stdin);
  86.   else
  87.     for (argc--, argv++; *argv != NULL; argc--, argv++)
  88.       {
  89.     if (argv[0][0] == '-' && argv[0][1] == '\0')
  90.       {
  91.         Name = "stdin";
  92.         Line = 0;
  93.         process (stdin);
  94.       }
  95.     else if ((fp = fopen (*argv, "r")) != NULL)
  96.       {
  97.         Name = *argv;
  98.         Line = 0;
  99.         process (fp);
  100.         fclose (fp);
  101.       }
  102.     else
  103.       {
  104.         fprintf (stderr, "%s: can not open: %s\n",
  105.              *argv, strerror (errno));
  106.         Errs++;
  107.       }
  108.       }
  109.   return Errs != 0;
  110. }
  111.  
  112. /* isref --- decide if we've seen a texinfo cross reference */
  113.  
  114. int
  115. isref (char *cp)
  116. {
  117.   if (strncmp (cp, "@ref{", 5) == 0)
  118.     return 5;
  119.   if (strncmp (cp, "@xref{", 6) == 0)
  120.     return 6;
  121.   if (strncmp (cp, "@pxref{", 7) == 0)
  122.     return 7;
  123.   return 0;
  124. }
  125.  
  126. /* process --- read files, look for references, fix them up */
  127.  
  128. void
  129. process (FILE * fp)
  130. {
  131.   char buf[BUFSIZ];
  132.   char *cp;
  133.   int count;
  134.  
  135.   while (fgets (buf, sizeof buf, fp) != NULL)
  136.     {
  137.       Line++;
  138.       cp = strchr (buf, '@');
  139.       if (cp == NULL)
  140.     {
  141.       fputs (buf, stdout);
  142.       continue;
  143.     }
  144.       do
  145.     {
  146.       count = isref (cp);
  147.       if (count == 0)
  148.         {
  149.           cp++;
  150.           cp = strchr (cp, '@');
  151.           if (cp == NULL)
  152.         {
  153.           fputs (buf, stdout);
  154.           goto next;
  155.         }
  156.           continue;
  157.         }
  158.       /* got one */
  159.       repair (buf, cp, count);
  160.       break;
  161.     }
  162.       while (cp != NULL);
  163.     next:;
  164.     }
  165. }
  166.  
  167. /* repair --- turn all texinfo cross references into the one argument form */
  168.  
  169. void
  170. repair (char *line, char *ref, int toffset)
  171. {
  172.   int braces = 1;        /* have seen first left brace */
  173.   char *cp;
  174.  
  175.   ref += toffset;
  176.  
  177.   /* output line up to and including left brace in reference */
  178.   for (cp = line; cp <= ref; cp++)
  179.     putchar (*cp);
  180.  
  181.   /* output node name */
  182.   for (; *cp && *cp != '}' && *cp != ',' && *cp != '\n'; cp++)
  183.     putchar (*cp);
  184.  
  185.   if (*cp != '}')
  186.     {                /* could have been one arg xref */
  187.       /* skip to matching right brace */
  188.       for (; braces > 0; cp++)
  189.     {
  190.       switch (*cp)
  191.         {
  192.         case '@':
  193.           cp++;        /* blindly skip next character */
  194.           break;
  195.         case '{':
  196.           braces++;
  197.           break;
  198.         case '}':
  199.           braces--;
  200.           break;
  201.         case '\n':
  202.         case '\0':
  203.           Errs++;
  204.           fprintf (stderr,
  205.                "%s: %s: %d: mismatched braces\n",
  206.                Me, Name, Line);
  207.           goto out;
  208.         default:
  209.           break;
  210.         }
  211.     }
  212.     out:
  213.       ;
  214.     }
  215.  
  216.   putchar ('}');
  217.   if (*cp == '}')
  218.     cp++;
  219.  
  220.   /* now the rest of the line */
  221.   for (; *cp; cp++)
  222.     putchar (*cp);
  223.   return;
  224. }
  225.  
  226. /* strerror --- return error string, delete if in your library */
  227.  
  228. char *
  229. strerror (int errno)
  230. {
  231.   static char buf[100];
  232.   extern int sys_nerr;
  233.   extern char *sys_errlist[];
  234.  
  235.   if (errno < sys_nerr && errno >= 0)
  236.     return sys_errlist[errno];
  237.  
  238.   sprintf (buf, "unknown error %d", errno);
  239.   return buf;
  240. }
  241.