1/* Give this program DOC-mm.nn.oo as standard input and it outputs to 2 standard output a file of texinfo input containing the doc strings. 3 4 Copyright (C) 1989, 1992, 1994, 1996, 1999, 2000, 2001, 2002, 2003, 5 2004, 2005, 2006, 2007 Free Software Foundation, Inc. 6 7 This file is part of GNU Emacs. 8 9 GNU Emacs is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 2, or (at your option) 12 any later version. 13 14 GNU Emacs is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with GNU Emacs; see the file COPYING. If not, write to the 21 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 22 Boston, MA 02110-1301, USA. 23 24 This version sorts the output by function name. */ 25 26#ifdef HAVE_CONFIG_H 27#include <config.h> 28#endif 29 30#include <stdio.h> 31#include <ctype.h> 32#ifdef DOS_NT 33#include <fcntl.h> /* for O_BINARY */ 34#include <io.h> /* for setmode */ 35#endif 36#ifndef HAVE_STDLIB_H /* config.h includes stdlib. */ 37#ifndef WINDOWSNT /* src/s/ms-w32.h includes stdlib.h */ 38extern char *malloc (); 39#endif 40#endif 41 42#define NUL '\0' 43#define MARKER '\037' 44 45#define DEBUG 0 46 47typedef struct line LINE; 48 49struct line 50{ 51 LINE *next; /* ptr to next or NULL */ 52 char *line; /* text of the line */ 53}; 54 55typedef struct docstr DOCSTR; 56 57struct docstr /* Allocated thing for an entry. */ 58{ 59 DOCSTR *next; /* next in the chain */ 60 char *name; /* name of the function or var */ 61 LINE *first; /* first line of doc text. */ 62 char type; /* 'F' for function, 'V' for variable */ 63}; 64 65 66/* Print error message. `s1' is printf control string, `s2' is arg for it. */ 67 68void 69error (s1, s2) 70 char *s1, *s2; 71{ 72 fprintf (stderr, "sorted-doc: "); 73 fprintf (stderr, s1, s2); 74 fprintf (stderr, "\n"); 75} 76 77/* Print error message and exit. */ 78 79void 80fatal (s1, s2) 81 char *s1, *s2; 82{ 83 error (s1, s2); 84 exit (EXIT_FAILURE); 85} 86 87/* Like malloc but get fatal error if memory is exhausted. */ 88 89char * 90xmalloc (size) 91 int size; 92{ 93 char *result = malloc ((unsigned)size); 94 if (result == NULL) 95 fatal ("%s", "virtual memory exhausted"); 96 return result; 97} 98 99char * 100xstrdup (str) 101 char * str; 102{ 103 char *buf = xmalloc (strlen (str) + 1); 104 (void) strcpy (buf, str); 105 return (buf); 106} 107 108/* Comparison function for qsort to call. */ 109 110int 111cmpdoc (a, b) 112 DOCSTR **a; 113 DOCSTR **b; 114{ 115 register int val = strcmp ((*a)->name, (*b)->name); 116 if (val) return val; 117 return (*a)->type - (*b)->type; 118} 119 120 121enum state 122{ 123 WAITING, BEG_NAME, NAME_GET, BEG_DESC, DESC_GET 124}; 125 126char *states[] = 127{ 128 "WAITING", "BEG_NAME", "NAME_GET", "BEG_DESC", "DESC_GET" 129}; 130 131int 132main () 133{ 134 register DOCSTR *dp = NULL; /* allocated DOCSTR */ 135 register LINE *lp = NULL; /* allocated line */ 136 register char *bp; /* ptr inside line buffer */ 137 register enum state state = WAITING; /* state at start */ 138 int cnt = 0; /* number of DOCSTRs read */ 139 140 DOCSTR *docs = NULL; /* chain of allocated DOCSTRS */ 141 char buf[512]; /* line buffer */ 142 143#ifdef DOS_NT 144 /* DOC is a binary file. */ 145 if (!isatty (fileno (stdin))) 146 setmode (fileno (stdin), O_BINARY); 147#endif 148 149 bp = buf; 150 151 while (1) /* process one char at a time */ 152 { 153 /* this char from the DOCSTR file */ 154 register int ch = getchar (); 155 156 /* Beginnings */ 157 158 if (state == WAITING) 159 { 160 if (ch == MARKER) 161 state = BEG_NAME; 162 } 163 else if (state == BEG_NAME) 164 { 165 cnt++; 166 if (dp == NULL) /* first dp allocated */ 167 { 168 docs = dp = (DOCSTR*) xmalloc (sizeof (DOCSTR)); 169 } 170 else /* all the rest */ 171 { 172 dp->next = (DOCSTR*) xmalloc (sizeof (DOCSTR)); 173 dp = dp->next; 174 } 175 lp = NULL; 176 dp->next = NULL; 177 bp = buf; 178 state = NAME_GET; 179 /* Record whether function or variable. */ 180 dp->type = ch; 181 ch = getchar (); 182 } 183 else if (state == BEG_DESC) 184 { 185 if (lp == NULL) /* first line for dp */ 186 { 187 dp->first = lp = (LINE*)xmalloc (sizeof (LINE)); 188 } 189 else /* continuing lines */ 190 { 191 lp->next = (LINE*)xmalloc (sizeof (LINE)); 192 lp = lp->next; 193 } 194 lp->next = NULL; 195 bp = buf; 196 state = DESC_GET; 197 } 198 199 /* process gets */ 200 201 if (state == NAME_GET || state == DESC_GET) 202 { 203 if (ch != MARKER && ch != '\n' && ch != EOF) 204 { 205 *bp++ = ch; 206 } 207 else /* saving and changing state */ 208 { 209 *bp = NUL; 210 bp = xstrdup (buf); 211 212 if (state == NAME_GET) 213 dp->name = bp; 214 else 215 lp->line = bp; 216 217 bp = buf; 218 state = (ch == MARKER) ? BEG_NAME : BEG_DESC; 219 } 220 } /* NAME_GET || DESC_GET */ 221 if (ch == EOF) 222 break; 223 } 224 225 { 226 DOCSTR **array; 227 register int i; /* counter */ 228 229 /* build array of ptrs to DOCSTRs */ 230 231 array = (DOCSTR**)xmalloc (cnt * sizeof (*array)); 232 for (dp = docs, i = 0; dp != NULL ; dp = dp->next) 233 array[i++] = dp; 234 235 /* sort the array by name; within each name, by type */ 236 237 qsort ((char*)array, cnt, sizeof (DOCSTR*), cmpdoc); 238 239 /* write the output header */ 240 241 printf ("\\input texinfo @c -*-texinfo-*-\n"); 242 printf ("@setfilename ../info/summary\n"); 243 printf ("@settitle Command Summary for GNU Emacs\n"); 244 printf ("@finalout\n"); 245 printf ("@unnumbered Command Summary for GNU Emacs\n"); 246 printf ("@table @asis\n"); 247 printf ("\n"); 248 printf ("@iftex\n"); 249 printf ("@global@let@ITEM@item\n"); 250 printf ("@def@item{@filbreak@vskip5pt@ITEM}\n"); 251 printf ("@font@tensy cmsy10 scaled @magstephalf\n"); 252 printf ("@font@teni cmmi10 scaled @magstephalf\n"); 253 printf ("@def\\{{@tensy@char110}}\n"); /* this backslash goes with cmr10 */ 254 printf ("@def|{{@tensy@char106}}\n"); 255 printf ("@def@{{{@tensy@char102}}\n"); 256 printf ("@def@}{{@tensy@char103}}\n"); 257 printf ("@def<{{@teni@char62}}\n"); 258 printf ("@def>{{@teni@char60}}\n"); 259 printf ("@chardef@@64\n"); 260 printf ("@catcode43=12\n"); 261 printf ("@tableindent-0.2in\n"); 262 printf ("@end iftex\n"); 263 264 /* print each function from the array */ 265 266 for (i = 0; i < cnt; i++) 267 { 268 printf ("\n@item %s @code{%s}\n@display\n", 269 array[i]->type == 'F' ? "Function" : "Variable", 270 array[i]->name); 271 272 for (lp = array[i]->first; lp != NULL ; lp = lp->next) 273 { 274 for (bp = lp->line; *bp; bp++) 275 { 276 /* the characters "@{}" need special treatment */ 277 if (*bp == '@' || *bp == '{' || *bp == '}') 278 { 279 putchar('@'); 280 } 281 putchar(*bp); 282 } 283 putchar ('\n'); 284 } 285 printf("@end display\n"); 286 /* Try to avoid a save size overflow in the TeX output 287 routine. */ 288 if (i%100 == 0 && i > 0 && i != cnt) 289 printf("\n@end table\n@table @asis\n"); 290 } 291 292 printf ("@end table\n"); 293 printf ("@bye\n"); 294 } 295 296 return EXIT_SUCCESS; 297} 298 299/* arch-tag: ce28f204-1e70-4b34-8210-3d54a5662071 300 (do not change this comment) */ 301 302/* sorted-doc.c ends here */ 303