home *** CD-ROM | disk | FTP | other *** search
/ Education Sampler 1992 [NeXTSTEP] / Education_1992_Sampler.iso / NeXT / GnuSource / emacs-15.0.3 / etc / sorted-doc.c < prev    next >
C/C++ Source or Header  |  1990-07-19  |  5KB  |  239 lines

  1. /* Give this program DOCSTR.mm.nn as standard input
  2.    and it outputs to standard output
  3.    a file of texinfo input containing the doc strings.
  4.    
  5.    This version sorts the output by function name.
  6.    */
  7.  
  8. #include <stdio.h>
  9. #include <ctype.h>
  10.  
  11. extern char *malloc ();
  12. char *xmalloc ();
  13.  
  14. #define NUL    '\0'
  15. #define MARKER '\037'
  16.  
  17. #define DEBUG 0
  18.  
  19. typedef struct line LINE;
  20.  
  21. struct line
  22. {
  23.   LINE *next;            /* ptr to next or NULL */
  24.   char *line;            /* text of the line */
  25. };
  26.  
  27. typedef struct docstr DOCSTR;
  28.  
  29. struct docstr            /* Allocated thing for an entry. */
  30. {
  31.   DOCSTR *next;            /* next in the chain */
  32.   char *name;            /* name of the function or var */
  33.   LINE *first;            /* first line of doc text. */
  34.   char type;            /* 'F' for function, 'V' for variable */
  35. };
  36.  
  37.  
  38. /* Print error message and exit.  */
  39.  
  40. fatal (s1, s2)
  41.      char *s1, *s2;
  42. {
  43.   error (s1, s2);
  44.   exit (1);
  45. }
  46.  
  47. /* Print error message.  `s1' is printf control string, `s2' is arg for it. */
  48.  
  49. error (s1, s2)
  50.      char *s1, *s2;
  51. {
  52.   fprintf (stderr, "sorted-doc: ");
  53.   fprintf (stderr, s1, s2);
  54.   fprintf (stderr, "\n");
  55. }
  56.  
  57. /* Like malloc but get fatal error if memory is exhausted.  */
  58.  
  59. char *
  60. xmalloc (size)
  61.      int size;
  62. {
  63.   char *result = malloc ((unsigned)size);
  64.   if (result == NULL)
  65.     fatal ("%s", "virtual memory exhausted");
  66.   return result;
  67. }
  68.  
  69. char *
  70. strsav (str)
  71.      char * str;
  72. {
  73.   char *buf = xmalloc (strlen (str) + 1);
  74.   (void) strcpy (buf, str);
  75.   return (buf);
  76. }
  77.  
  78. /* Comparison function for qsort to call.  */
  79.  
  80. int
  81. cmpdoc (a, b)
  82.      DOCSTR **a;
  83.      DOCSTR **b;
  84. {
  85.   register int val = strcmp ((*a)->name, (*b)->name);
  86.   if (val) return val;
  87.   return (*a)->type - (*b)->type;
  88. }
  89.  
  90.  
  91. enum state
  92. {
  93.   WAITING, BEG_NAME, NAME_GET, BEG_DESC, DESC_GET
  94. };
  95.  
  96. char *states[] =
  97. {
  98.   "WAITING", "BEG_NAME", "NAME_GET", "BEG_DESC", "DESC_GET"
  99. };
  100.     
  101. main ()
  102. {
  103.   register DOCSTR *dp = NULL;    /* allocated DOCSTR */
  104.   register LINE *lp = NULL;    /* allocated line */
  105.   register char *bp;        /* ptr inside line buffer */
  106.   int notfirst = 0;        /* set after read something */
  107.   register enum state state = WAITING; /* state at start */
  108.   int cnt = 0;            /* number of DOCSTRs read */
  109.  
  110.   DOCSTR *docs;            /* chain of allocated DOCSTRS */
  111.   char buf[512];        /* line buffer */
  112.     
  113.   while (1)            /* process one char at a time */
  114.     {
  115.       /* this char from the DOCSTR file */
  116.       register int ch = getchar ();
  117.  
  118.       /* Beginnings */
  119.  
  120.       if (state == WAITING)
  121.     {
  122.       if (ch == MARKER)
  123.         state = BEG_NAME;
  124.     }
  125.       else if (state == BEG_NAME)
  126.     {
  127.       cnt++;
  128.       if (dp == NULL)    /* first dp allocated */
  129.         {
  130.           docs = dp = (DOCSTR*) xmalloc (sizeof (DOCSTR));
  131.         }
  132.       else            /* all the rest */
  133.         {
  134.           dp->next = (DOCSTR*) xmalloc (sizeof (DOCSTR));
  135.           dp = dp->next;
  136.         }
  137.       lp = NULL;
  138.       dp->next = NULL;
  139.       bp = buf;
  140.       state = NAME_GET;
  141.       /* Record whether function or variable.  */
  142.       dp->type = ch;
  143.       ch = getchar ();
  144.     }
  145.       else if (state == BEG_DESC)
  146.     {
  147.       if (lp == NULL)    /* first line for dp */
  148.         {
  149.           dp->first = lp = (LINE*)xmalloc (sizeof (LINE));
  150.         }
  151.       else            /* continuing lines */
  152.         {
  153.           lp->next = (LINE*)xmalloc (sizeof (LINE));
  154.           lp = lp->next;
  155.         }
  156.       lp->next = NULL;
  157.       bp = buf;
  158.       state = DESC_GET;
  159.     }
  160.     
  161.       /* process gets */
  162.  
  163.       if (state == NAME_GET || state == DESC_GET)
  164.     {
  165.       if (ch != MARKER && ch != '\n' && ch != EOF)
  166.         {
  167.           *bp++ = ch;
  168.         }
  169.       else            /* saving and changing state */
  170.         {
  171.           *bp = NUL;
  172.           bp = strsav (buf);
  173.  
  174.           if (state == NAME_GET)
  175.         dp->name = bp;
  176.           else
  177.         lp->line = bp;
  178.  
  179.           bp = buf;
  180.           state =  (ch == MARKER) ? BEG_NAME : BEG_DESC;
  181.         }
  182.     }            /* NAME_GET || DESC_GET */
  183.       if (ch == EOF)
  184.     break;
  185.     }
  186.  
  187.   {
  188.     DOCSTR **array;
  189.     register int i;        /* counter */
  190.  
  191.     /* build array of ptrs to DOCSTRs */
  192.  
  193.     array = (DOCSTR**)xmalloc (cnt * sizeof (*array));
  194.     for (dp = docs, i = 0; dp != NULL ; dp = dp->next)
  195.       array[i++] = dp;
  196.  
  197.     /* sort the array by name; within each name, by type */
  198.  
  199.     qsort ((char*)array, cnt, sizeof (DOCSTR*), cmpdoc);
  200.  
  201.     /* write the output header */
  202.  
  203.     printf ("\\input texinfo  @c -*-texinfo-*-\n");
  204.     printf ("@setfilename ../info/summary\n");
  205.     printf ("@settitle Command Summary for GNU Emacs\n");
  206.     printf ("@unnumbered Command Summary for GNU Emacs\n");
  207.     printf ("@table @asis\n");
  208.  
  209.     /* print each function from the array */
  210.  
  211.     for (i = 0; i < cnt; i++)
  212.       {
  213.     printf ("\n@item %s @code{%s}\n@display\n",
  214.         array[i]->type == 'F' ? "Function" : "Variable",
  215.         array[i]->name);
  216.  
  217.     for (lp = array[i]->first; lp != NULL ; lp = lp->next)
  218.       {
  219.         for (bp = lp->line; *bp; bp++)
  220.           {
  221.         /* the characters "@{}" need special treatment */
  222.         if (*bp == '@' || *bp == '{' || *bp == '}')
  223.           {
  224.             putchar('@');
  225.           }
  226.         putchar(*bp);
  227.           }
  228.         putchar ('\n');
  229.       }
  230.     printf("@end display\n");
  231.       }
  232.  
  233.     printf ("@end table\n");
  234.     printf ("@bye\n");
  235.   }
  236.  
  237.   return 0;
  238. }
  239.