1 /***********************************************************************/
2 /* MANEXT - Extract manual pages from C source code.                   */
3 /***********************************************************************/
4 /*
5  * MANEXT - A program to extract manual pages from C source code.
6  * Copyright (C) 1991-2013 Mark Hessling
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to:
20  *
21  *    The Free Software Foundation, Inc.
22  *    675 Mass Ave,
23  *    Cambridge, MA 02139 USA.
24  *
25  *
26  * If you make modifications to this software that you feel increases
27  * it usefulness for the rest of the community, please email the
28  * changes, enhancements, bug fixes as well as any and all ideas to me.
29  * This software is going to be maintained and enhanced as deemed
30  * necessary by the community.
31  *
32  * Mark Hessling, mark@rexx.org  http://www.rexx.org/
33  */
34 
35 
36 #ifdef HAVE_CONFIG_H
37 # include <config.h>
38 #endif
39 
40 #include <stdio.h>
41 #ifdef HAVE_STDLIB_H
42 # include <stdlib.h>
43 #endif
44 #ifdef HAVE_STRING_H
45 # include <string.h>
46 #endif
47 
48 #ifdef HAVE_PROTO
49 void display_info(void);
50 #else
51 void display_info();
52 #endif
53 
54 #if !defined(__cplusplus)
55 typedef unsigned char bool;
56 #endif
57 typedef char CHARTYPE;
58 
59 #define TRUE    1
60 #define FALSE   0
61 
62 #define MAX_LINE 255
63 
64 #define FORMAT_MANUAL     0
65 #define FORMAT_QUICK_REF  1
66 
67 #define STATE_IGNORE    0
68 #define STATE_SYNTAX    1
69 #define STATE_COMMAND   2
70 #define STATE_DEFAULT   3
71 /***********************************************************************/
72 #ifdef HAVE_PROTO
strzne(CHARTYPE * str,CHARTYPE ch)73 short strzne(CHARTYPE *str,CHARTYPE ch)
74 #else
75 short strzne(str,ch)
76 CHARTYPE *str;
77 CHARTYPE ch;
78 #endif
79 /***********************************************************************/
80 {
81  register short len=0;
82  register short  i = 0;
83 
84  len = strlen(str);
85  for (; i<len && str[i]==ch; i++);
86  if (i>=len)
87     i = (-1);
88  return(i);
89 }
90 /***********************************************************************/
91 #ifdef HAVE_PROTO
strzrevne(CHARTYPE * str,CHARTYPE ch)92 short strzrevne(CHARTYPE *str,CHARTYPE ch)
93 #else
94 short strzrevne(str,ch)
95 CHARTYPE *str;
96 CHARTYPE ch;
97 #endif
98 /***********************************************************************/
99 {
100  register short len=0;
101 
102  len = strlen(str);
103  for (--len; len>=0 && str[len]==ch; len--);
104  return(len);
105 }
106 /***********************************************************************/
107 #ifdef HAVE_PROTO
blank_field(CHARTYPE * field)108 bool blank_field(CHARTYPE *field)
109 #else
110 bool blank_field(field)
111 CHARTYPE *field;
112 #endif
113 /***********************************************************************/
114 {
115  if (strzne(field,' ') == (-1))
116     return(TRUE);                /* field is NULL or just contains spaces */
117  return(FALSE);
118 }
119 /***********************************************************************/
120 #ifdef HAVE_PROTO
strtrunc(CHARTYPE * string)121 CHARTYPE *strtrunc(CHARTYPE *string)
122 #else
123 CHARTYPE *strtrunc(string)
124 CHARTYPE *string;
125 #endif
126 /***********************************************************************/
127 {
128  register short i=0;
129  short pos=0;
130 
131  pos = strzrevne(string,' ');
132  if (pos == (-1))
133     strcpy(string,"");
134  else
135     *(string+pos+1) = '\0';
136  pos = strzne(string,' ');
137  if (pos != (-1))
138  {
139     for (i=0;*(string+i+pos)!='\0';i++)
140        *(string+i) = *(string+i+pos);
141     *(string+i) = '\0';
142  }
143  return(string);
144 }
145 /***********************************************************************/
146 #ifdef HAVE_PROTO
strtrim(CHARTYPE * string,char ch)147 CHARTYPE *strtrim(CHARTYPE *string,char ch)
148 #else
149 CHARTYPE *strtrim(string,ch)
150 CHARTYPE *string,ch;
151 #endif
152 /***********************************************************************/
153 {
154  register short i=0;
155 
156  for (i=0;i<strlen(string);i++)
157  {
158     if (*(string+i) == ch)
159        return(string+i+1);
160  }
161  return(string);
162 }
163 /***********************************************************************/
164 #ifdef HAVE_PROTO
main(int argc,char * argv[])165 int main(int argc,char *argv[])
166 #else
167 int main(argc,argv)
168 int argc;
169 char *argv[];
170 #endif
171 /***********************************************************************/
172 {
173  char    s[MAX_LINE + 1];        /* input line */
174  char    save_line[MAX_LINE + 1];
175  register int     i = 0;
176  FILE *fp;
177  int format=FORMAT_MANUAL;
178  int state=STATE_IGNORE;
179  int file_start=1;
180 
181 #ifdef __EMX__
182  _wildcard(&argc,&argv);
183 #endif
184 
185  if (strcmp(argv[1],"-h") == 0)
186  {
187     display_info();
188     exit(1);
189  }
190  if (strcmp(argv[1],"-q") == 0) /* generate quick reference */
191  {
192     format = FORMAT_QUICK_REF;
193     file_start = 2;
194  }
195  for(i=file_start;i<argc;i++)
196  {
197      if ((fp = fopen(argv[i],"r")) == NULL)
198      {
199         fprintf(stderr,"\nCould not open %s\n",argv[i]);
200         continue;
201      }
202      while(1)
203      {
204         if (fgets(s, (int)sizeof(s), fp) == NULL)
205         {
206            if (ferror(fp) != 0)
207            {
208               fprintf(stderr, "*** Error reading %s.  Exiting.\n",argv[i]);
209               exit(1);
210            }
211            break;
212         }
213 
214         /* check for manual entry marker at beginning of line */
215         if (strncmp(s, "/*man-start*", 12) != 0)
216             continue;
217 
218         state = STATE_IGNORE;
219         /* inner loop */
220         for (;;)
221         {
222             /* read next line of manual entry */
223             if (fgets(s, (int)sizeof(s), fp) == NULL)
224             {
225                if (ferror(fp) != 0)
226                {
227                   fprintf(stderr, "*** Error reading %s.  Exiting.\n",argv[i]);
228                   exit(1);
229                }
230                break;
231             }
232             /* check for end of entry marker */
233             if (strncmp(s, "**man-end", 9) == 0)
234                break;
235             switch(format)
236             {
237                case FORMAT_MANUAL:
238                     printf("     %s",s);
239                     break;
240                case FORMAT_QUICK_REF:
241                     s[strlen(s)-1] = '\0';
242                     switch(state)
243                     {
244                        case STATE_IGNORE:
245                             if (strncmp(s, "COMMAND", 7) == 0)
246                             {
247                                state = STATE_COMMAND;
248                                break;
249                             }
250                             if (strncmp(s, "SYNTAX", 6) == 0)
251                             {
252                                state = STATE_SYNTAX;
253                                break;
254                             }
255                             if (strncmp(s, "DEFAULT", 7) == 0)
256                             {
257                                state = STATE_DEFAULT;
258                                break;
259                             }
260                             break;
261                        case STATE_COMMAND:
262                             strcpy(save_line,s);
263                             state = STATE_IGNORE;
264                             break;
265                        case STATE_DEFAULT:
266                             if (blank_field(s))
267                             {
268                                state = STATE_IGNORE;
269                                break;
270                             }
271                             printf("       Default: %s\n",strtrunc(s));
272                             break;
273                        case STATE_SYNTAX:
274                             if (blank_field(s))
275                             {
276                                printf("       %s\n",strtrunc(strtrim(save_line,'-')));
277                                state = STATE_IGNORE;
278                                break;
279                             }
280                             printf(" %s\n",strtrunc(s));
281                             break;
282                        default:
283                             break;
284                     }
285                     break;
286                default:
287                     break;
288             }
289         }
290         if (format == FORMAT_MANUAL)
291            printf("\n\n\n     --------------------------------------------------------------------------\n");
292 
293         /* check if end of file */
294         if (feof(fp) != 0)
295             break;
296      }
297      fclose(fp);
298  }
299  if (format == FORMAT_MANUAL)
300     printf("\n\n\n\n\n");
301  return(0);
302 }
303 /***********************************************************************/
304 #ifdef HAVE_PROTO
display_info(void)305 void display_info(void)
306 #else
307 void display_info()
308 #endif
309 /***********************************************************************/
310 {
311  fprintf(stderr,"\nMANEXT 1.00 Copyright (C) 1991-1999 Mark Hessling\n");
312  fprintf(stderr,"All rights reserved.\n");
313  fprintf(stderr,"MANEXT is distributed under the terms of the GNU\n");
314  fprintf(stderr,"General Public License and comes with NO WARRANTY.\n");
315  fprintf(stderr,"See the file COPYING for details.\n");
316  fprintf(stderr,"\nUsage: MANEXT sourcefile [...]\n\n");
317  fflush(stderr);
318  return;
319 }
320