Added SILC Thread Queue API
[silc.git] / util / robodoc / Source / robodoc.c
1 /****h* Autodoc/ROBODoc [3.2]
2  * NAME
3  *   ROBODoc -- AutoDoc formatter
4  * COPYRIGHT
5  *  Copyright (C) 1994-2000  Frans Slothouber and Jacco van Weert.
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, write to the Free Software
19  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  *
21  * FUNCTION
22  *   ROBODoc is intended to be a replacement for the original AutoDocs
23  *   program.  ROBODoc will extract the procedure comment headers
24  *   from a source file, and put them into a separate documentation file.
25  *   There are five different file output formats:
26  *       ASCII
27  *       HTML (HyperText Markup Langauge) -- mainly used on the Internet;
28  *           thus the files can be viewed with a normal HTML viewer/browser
29  *       AmigaGuide -- this format can be viewed by AmigaGuide (Amiga only)
30  *       LaTeX - as input to LaTeX to produce .dvi files
31  *       RTF (Rich Text Format) -- as input to the Help compiler (Windows only)
32  *   For further information read the documentation in the archive.
33  * AUTHOR
34  *   Frans Slothouber:  <fslothouber@acm.org>.
35  *     Source code and additional extensions from version 2.0 and up.
36  *
37  *   Petteri Kettunen: <petterik@iki.fi>
38  *     Bug fixes, FOLD, C features.
39  *
40  *   Jacco van Weert: <weertj@xs4all.nl>
41  *     Original idea and program.
42  *
43  *   Bernd Koesling:  <KOESSI@CHESSY.aworld.de>
44  *     Bug fixes, functional improvements, code cleanup.
45  *
46  *   Anthon Pang:  <apang@mindlink.net>
47  *     RTF support, Bug fixes.
48  *
49  *   Thomas Aglassinger: <agi@sbox.tu-graz.ac.at>
50  *     Fixes and cleanup of HTML-output
51  *
52  * CREATION DATE
53  *   20-Dec-94
54  * MODIFICATION HISTORY
55  *   Modifications by Jacco van Weert.
56  *     19-Jan-95     -  v0.8:   First test beta-version
57  *     26-Jan-95     -  v0.92:  2nd test beta-version
58  *     2-Feb-95      -  v0.93:  Mungwall hit, solved.
59  *                              When item headers, are also available
60  *                              in body then parts are duplicated solved.
61  *     Mar-95        -  v1.0a:  Final version
62  *     2-Apr-95      -  v1.0b:  Bug fixes
63  *                              Procedure header search bug solved.
64  *                              Print 'created procedure' text
65  *     20-Apr-95     -  v1.1a:  INTERNALONLY option added.
66  *                              Sort problem solved.
67  *   Modifications by FNC Slothouber.
68  *     10-May-1995 -  v2.0a  * Program completely rewritten
69  *                           * added SOURCE item and LaTeX output.
70  *                           * added TAB converter.
71  *     11-May-1995 -  v2.0b  * Accepts headers that start with
72  *                             any sequence of non-spaces.
73  *                             RoboDoc should work with any
74  *                             type of programming language now.
75  *     12-May-1995 -  v2.0c  * Bug fixes.
76  *     15-May-1995 -  v2.0d  * New Defaults file.
77  *                           * Added Verbose option.
78  *     24-May-1995 -  v2.0e  * Fixed a bug that cause the
79  *                             CleanUp Routine to lock up.
80  *                           * Improved the HTML output,
81  *                             should work faster now.
82  *   Modifications by Koessi
83  *     01-Aug-1995  - v2.0?  * more robust parsing, less enforcer-hits
84  *                           * removed self-referencing links !
85  *                           * remarked most changes with *koessi*
86  *                           * added GoldEd-foldmarks
87  *                           * compiled successfully with SAS-C 6.3
88  *     07-Aug-1995   -       * automated foldmarks "\***"
89  *                           ! GoldEd's foldmarks == RoboDoc marker !
90  *                           * quoted source parsing enhanced
91  *     08-Aug-1995   -       * a lot of while instead of for
92  *                           * a lot of switch() instead of ifelse
93  *                           * version defined
94  *                           * RB_Say, RB_Panic now useable like printf()
95  *                             new formats for nearly all output-strings
96  *                           * char *whoami is global copy of argv[0]
97  *                           * BOLD <- MAKE_LARGE && AMIGAGUIDE
98  *                           * succesfully compiled&tested on HPUX
99  *                           (HP9000/800)
100  *                           * optimized listfunctions
101  *                           * encapsulated header- and link-
102  *                             allocating and freeing
103  *                           * RB_Find_Function_Name() replaced
104  *                             with RB_FilePart()
105  *  Modifications by FNC Slothouber.
106  *    18-Aug-1995   -  v3.0  
107  *      o New scanner that searches for a set default markers 
108  *        that define what is a comment or what is not and that 
109  *        define what or what is not a header/end marker.
110  *      o Added Beast Support
111  *    27-Aug-1995   - v3.0b  
112  *      o Fixed a bug with the defaults file
113  *      o Improved search algorithm RoboDoc is now 5.8 times faster.
114  *    06-Sep-1995   - v3.0c  
115  *      o Bug fixes
116  *    08-Oct-1995   - v3.0d  
117  *      o Bug fixes
118  *    04-Feb-1996   - v3.0e  
119  *      o fixed the problem with the TOC that included links to headers that
120  *                             were not selected. (i.e internal)
121  *  Modifications by apang
122  *    08-Mar-1996   - v3.0f  
123  *      o Cleaner build for Borland C++ 4.52
124  *      o Added more markers (C++, Pascal, Modula-2, COBOL)
125  *      o Added more item types/names
126  *      o Added #defines for the preamble (COMMENT_ROBODOC and 
127  *        COMMENT_COPYRIGHT)
128  *      o BLANK_HEADER for detection of asterisk'd lines
129  *      o RB_Say() the GENERIC header warning instead of using printf()
130  *      o Indents SOURCE body in output
131  *      o ASCII respects the TOC flag; removed extraneous newline after 
132  *        formfeed (so it's more like AutoDoc)
133  *      o HTML output fixed to handle '<', '>', and '&'
134  *      o LaTeX attributes and '%' handling added; fancied up the output a bit
135  *      o RTF support added
136  *      o Changed some fprintf()'s to fputc()'s for potentially lower overhead
137  *      o Fixed line eater bug
138  *      o More general fix to the TOC problem of including internal links 
139  *        when it wasn't selected
140  *  Modifications by FNC Slothouber.
141  *    01-April-1996  - v3.0h 
142  *      o Added ';' to &gt and &lt so lynx also recognizes them.
143  *      o Fancied up the HTML output.
144  *    10-July-1996   - v3.0i 
145  *      o Bug Fix, Both the options INTERNAL and INTERNALONLY did not 
146  *        work correctly.
147  *  Modifications by agi
148  *    15-Dec-1997    - v3.0j 
149  *      o cleaned the HTML-output, so it now conforms to the DTD for HTML-3.2
150  *      o TOC now is an ordered list (<OL> and <LI>)
151  *      o added "<!DOCTYPE..>"
152  *      o added quotes to values of some HTML-attributes
153  *      o more compatible implementation of the SGML-comment containing 
154  *        copyright-info replaced all occurrences of <B><PRE>.. by <PRE><B>
155  *      o replaced <H2/3> by <H1/2>
156  *      o fixed two minor warnings reported by gcc -Wall
157  *  Modifications by FNC Slothouber.
158  *    14-Aug-1998    - v3.0k * Tcl/Tk '#' handling added;
159  *       Feb-1999    - v3.0l * Added function to reverse the header list.
160  *  Modifications by Petteri Kettunen
161  *    Feb 1999      - v3.0m 
162  *      o Changed background color to white
163  *      o Changed size of Table of Contents title. (H3 instead of H1)
164  *      o The reverse function also reversed the sorted header list, 
165  *        fixed this.
166  *  Modifications by Petteri Kettunen
167  *   August 1999 - v3.0m+ 
168  *      o Support for folding in SOURCE items, HTML only.
169  *      o indent -kr 
170  *      o Added options FOLD and C
171  *  Modifications by FNC Slothouber. 
172  *   August 1999 - v3.1   
173  *      o More documentation and a more informative usage() function. 
174  *      o GPL-ed.
175  *      o robodoc -c prints licence
176  *      o removed a number of Source items from the documentation to reduce 
177  *        the size of the robodoc.c.html file...  no fun for people
178  *        to download a >100k file.
179  *      o removed the warning about not using a robodoc default file.
180  *      o indent -orig -i2 -nbc -ncdb -bad -bap
181  *      o Fixed the warnings. 
182  *      o Fixed some occurrences of (evil cast)malloc  (thou shalt not 
183  *        cast malloc :) 
184  *      o ROBODoc now returns EXIT_FAILURE or  EXIT_SUCCESS, as defined 
185  *        in <stdlib.h>
186  *      o Fixed a memory leak in RB_Analyse_Document()
187  *   Oct 1999 - v3.1b     
188  *      o <A NAME="source code file name"> is generated at the beginning of 
189  *        each document. A mention of the source code name in another 
190  *        document creates a link to this name (provided you use xrefs).
191  *      o Moved most #defines and enums to robodoc.h
192  *      o Made ROBODoc more forgiving in reading the xrefs file. Empty 
193  *        lines are allowed and also spaces at the end of a file name.
194  *   Nov 1999 - v3.1c  -- From patches that I received from Stefan Kost
195  *      o renamed BEAST METHODS -> METHODS
196  *      o renamed BEAST ATTRIBUTES -> ATTRIBUTES
197  *      o added new items useful for object oriented programming; some of 
198  *        these items are already used in os3.1 autodocs
199  *        TAGS, COMMANDS, DERIVED FROM, DERIVED BY, USES,
200  *        CHILDREN, USED BY, PARENTS, USAGE, PURPOSE
201  *      o commented the item names
202  *      o changed item-type enums to end all with _ITEM
203  *      o changed RB_Find_Link to accept names ending with '...'
204  *      o changed copyright comment to be a style-guide conform version string.
205  *      o changed RB_VER[] to be a style-guide conform version string
206  *      o changed AMIGA into _AMIGA, because the first one does not exists, 
207  *        when compiling with NOANSI on SAS C/C++
208  *   Dec 1999 - v3.1d
209  *      o added new header types for, classes, methods, variables, 
210  *        functions, strutures and constants. (Idea of Stefan Kost) 
211  *      o added a command to create a master index file that contains
212  *        sorted pointers to all classes, methods, variables, 
213  *        functions, strutures and constants.
214  *   Dec 1999 - v3.1e
215  *      o added markers for HTML.
216  *      o modified the RB_Find_Link() function to also words that include
217  *        "::". This is used for C++ methods.
218  *      o added a RB_Function_Name() function that correctly extracts the
219  *        function name (or the name of any other object that is documented)
220  *        from the header name.  The old code used RB_FilePart which failed
221  *        on C++ method names. 
222  *      o Fixed a core-dumping bug in RB_Set_Doc_Base()
223  *   Dec 1999 - v3.1f
224  *      o added RB_TimeStamp() to include time stamps in the documentation.
225  *      o Documentation is now generated in LaTeX2e format.
226  *      o added '|****' as begin marker, '|' as remark marker and '|***' as
227  *        end marker for GNU assembler support.
228  *      o ran ident on all source. Using the GNU standard now. 
229  *      o Added new fold markers provided by Petteri
230  *   May 2000 - v3.2
231  *      o Using automake and autoconf.
232  *      o Added fixes to folding code Petteri.
233  *      o Added markers for FORTAN 90
234  *   June 2000 - V3.2.1
235  *      o Added patch from Simo Muinonen: This solved the following
236  *        problem:
237  *          When e.g. a field of a structured C variable (with an
238  *          underscore in its name) is referred to using the
239  *          point notation (e.g. "g_Status.tpstat"), the variable
240  *          name is not recognized as a separate keyword.  This
241  *          can also happen when a keyword is in a comment at the
242  *          end of a sentence with an immediately following ".".
243  *      o Fixed the "stuctures" type in the master index file.
244  *      o Added mailto: support provided by Guillaume Etorre.
245  *    July 2000 - V3.2.2
246  *      o Added option SINGLEDOC
247  *        For LaTeX output this generates documentation without
248  *        the start and end headers.  This way the generated file
249  *        can be included in a master file.  
250  *      o Added master index file for LaTeX output.  The documentation
251  *        gathered from several source files can now be included into
252  *        one big file.
253  *      o Added the option NOSOURCE.  With this option the SOURCE item
254  *        is not included in the documentation.
255  *      o Added the TITLE option. This allows to set the title for
256  *        the master index file.
257  *      o Made the search for headermarkers case insensitve.
258  *        REM == Rem == rem  
259  *    July 2000 - V3.2.3
260  *      o Fixed a bug that caused links of the type
261  *        "someword/anotherword," to be ignored, while
262  *        "someword/anotherword" was recognized.
263  *    Sep 2000 
264  *      o Labels with identical names are now numbered.
265  *    Apr 2001
266  *      o The source file is opened "rb" this I hope will
267  *        make it possible to use Robodoc under windows.
268  *        (Thanks to Carlo Caminati) 
269  *
270  * NOTES
271  *   Has been succesfully compiled:
272  *     On an Amiga with SAS/C, DICE C and gcc (Amiga 1200)
273  *     On a Sun Sparc Station with gcc   (under SunOS 4.1)
274  *     On a Dec Alpha Station
275  *     Under HP/UX on a HP9000/800
276  *     Under IRIX
277  *     On a Linux box with gcc, Slackware, Redhat, and Debian 2.1.
278  * BUGS
279  *   - HTML output is not Lynx friendly -- attributes are applied
280  *     to leading white space =P ... solution: fix Lynx  >=)
281  *   - Can't get the escape character for @ to work in
282  *     AmigaGuide format.
283  *   - Horrible use of feof() and fgets() 
284  *   Other bugs?
285  *     Catch them in a jar and send them to fslothouber@acm.org
286  *     Latest version can be found on 
287  *       http://robodoc.sourceforge.net
288  *       http://www.xs4all.nl/~rfsber/Robo/
289  *       http://freshmeat.net/ 
290  *     
291  ****/
292
293 #include <stdlib.h>
294 #include <stdio.h>
295 #include <string.h>
296 #include <ctype.h>
297 #include "robodoc.h"
298 #include "folds.h"
299 #include "headers.h"
300 #include "items.h"
301 #include "util.h"
302 #include "links.h"
303 #include "analyser.h"
304 #include "generator.h"
305
306 #ifdef _AMIGA
307 char RB_VER[] = "\0$VER: robodoc " VERSION " " __AMIGADATE__ " (c) by Maverick Software Development 1994-2001";
308 #else
309 char RB_VER[] = "$VER: robodoc " VERSION " (" __DATE__ ") (c) by Maverick Software Development 1994-2001";
310 #endif
311
312
313 /****v* ROBODoc/source
314  * NAME
315  *   source -- source code file.
316  * PURPOSE
317  *   Pointer to the file with source code.   
318  * NOTES
319  *   This is a global. It is however only used by main() and
320  *   RB_Close_The_Shop(). All other functions are passed a copy.
321  *
322  *   It is a global so that the file can be closed by
323  *   RB_Close_The_Shop() when the program exits (normally or
324  *   abnormaly).
325  *****
326  */
327
328 FILE *source = NULL;
329
330 /****v* ROBODoc/documentation
331  * NAME
332  *   documentation -- documentation file.
333  * PURPOSE
334  *   Pointer to the file that will contain the documentation extracted
335  *   from the source code.   
336  * NOTES
337  *   This is a global. It is however only used by main() and
338  *   RB_Close_The_Shop(). All other functions are passed a copy.
339  *
340  *   It is a global so that the file can be closed by
341  *   RB_Close_The_Shop() when the program exits (normally or
342  *   abnormaly).
343  *****
344  */
345
346 FILE *documentation = NULL;
347
348
349 /****v* ROBODoc/document_title
350  * NAME
351  *   documentat_title -- title for the documentation.
352  * PURPOSE
353  *   Used as the title for master index files or for latex documentation.
354  *****
355  */
356
357 char *document_title = NULL;
358
359 /****v* ROBODoc/output_mode [2.0]
360  * NAME
361  *   output_mode -- the mode of output
362  * FUNCTION
363  *   Controls which type of output will be generated.
364  * SOURCE
365  */
366
367 int output_mode = ASCII;
368
369 /*******/
370
371
372 /****v* ROBODoc/course_of_action [2.0]
373  * NAME
374  *   course_of_action
375  * FUNCTION
376  *   Global Variable that defines the course of action.
377  * SOURCE
378  */
379
380 int course_of_action = DO_MAKE_DOCUMENT;
381
382 /*******/
383
384
385 /****v* ROBODoc/line_buffer [2.0]
386  * NAME
387  *   line_buffer -- global line buffer
388  * FUNCTION
389  *   Temporary storage area for lines
390  *   that are read from an input file.
391  * SOURCE
392  */
393
394 char line_buffer[MAX_LINE_LEN];
395
396 /*******/
397
398
399 /****v* ROBODoc/line_number [2.0]
400  * NAME
401  *   line_number -- global line counter
402  * PURPOSE
403  *   Keeps track of the number of lines that are read from the source file.
404  * AUTHOR
405  *   Koessi
406  * SOURCE
407  */
408
409 int line_number = 0;
410
411 /*******/
412
413
414 /****v* ROBODoc/use [3.0h]
415  * NAME
416  *   use -- usage string
417  * FUNCTION
418  *   Inform the user how to use ROBODoc.
419  * AUTHOR
420  *   Koessi
421  * SOURCE
422  */
423
424 char use[] =
425 "ROBODoc Version " VERSION ", autodocs formatter ($Revision$)\n"
426 "(c) 1994-2001 Frans Slothouber and Jacco van Weert\n"
427 "robodoc comes with ABSOLUTELY NO WARRANTY.\n"
428 "This is free software, and you are welcome to redistribute it\n"
429 "under certain conditions; type `robodoc -c' for details.\n"
430 "\n"
431 "Usage:\n"
432 "  robodoc <source file> <documentation file> [options]\n"
433 "    or\n"
434 "  robodoc <xrefs file> <master index file> INDEX [options]\n"
435 "\n"
436 "You can use one or more of the following options:\n"
437 "  GENXREF <xref file>  - to generate an xref file.\n"
438 "  XREF    <xrefs file> - if you want to use xref files to create\n"
439 "                         cross links.\n"
440 "  INDEX           - create a master index file.\n"
441 "  TABSIZE <nr_sp> - convert each TAB to nr_sp of spaces.\n"
442 "  TOC             - a table of contents will be generated.\n"
443 "  SORT            - the headers will be sorted.\n"
444 "  -v              - tell robodoc to tell you all about it.\n"
445 "  INTERNAL        - headers marked internal will also be included.\n"
446 "  INTERNALONLY    - only headers marked internal will be included.\n"
447 "  FOLD            - enable folding if HTML output is selected.\n"
448 "  C               - Use ANSI C grammar in source items (test, HTML only).\n"
449 "The type of output is selected with one of the following switches:\n"
450 "  ASCII, GUIDE, HTML, LATEX, or RTF\n"
451 "If no type is specified ASCII is used.\n"
452 "The following abbreviations are also allowed:\n"
453 "  TOC = -t  XREF = -x   SORT = -s  INTERNAL = -i \n"
454 "  GENXREF = -g  INTERNALONLY = -io  TABSIZE = -ts\n"
455 "Example:\n"
456 "  robodoc simulator.c simulator.html HTML -v TOC SORT\n"
457 "Authors/Contributors: Frans Slothouber <fslothouber@acm.org>,"
458 " Jacco van Weert,\n"
459 "  Petteri Kettunen, Bernd Koesling, Thomas Aglassinger, Anthon Pang, and\n"
460 "  Stefan Kost\n"
461 "For more information, and the lastest version:\n"
462 "  http://www.xs4all.nl/~rfsber/Robo/index.html\n"
463 "  Send bug reports to <fslothouber@acm.org>.\n";
464
465 /********/
466
467
468 /****v* ROBODoc/copying [3.1]
469  * NAME
470  *   copying -- licence information
471  * FUNCTION
472  *   inform the user how to copy me
473  * AUTHOR
474  *   Frans
475  *******
476  */
477
478 char copying[] =
479 "\n"
480 " Distributed under the GNU GENERAL PUBLIC LICENSE\n"
481 "   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n"
482 " See the source archive for a copy of the complete licence\n"
483 " If you do not have it you can get it from\n"
484 " http://freshmeat.net/appindex/1999/08/30/936003795.html\n";
485
486
487 /* Global variables */
488
489 char *whoami = NULL;            /* me,myself&i */
490 int tab_size = 8;
491 char doc_base[1024];            /* PetteriK */
492
493
494 /****f* ROBODoc/RB_Set_Doc_Base
495  * NAME
496  *   RB_Set_Doc_Base -- get file name without extension.
497  ******
498  */
499
500 void
501 RB_Set_Doc_Base (char *path)
502 {
503   int ptr = 0, n = -1;
504
505   while (path[ptr] != '\0')
506     {
507       if (path[ptr] == '.')
508         {
509           n = ptr;
510         }
511       ptr++;
512     }
513   if (n != -1)
514     {
515       strncpy (doc_base, path, n);
516     }
517   else
518     {
519       strcpy (doc_base, path);
520     }
521   RB_Say ("doc_base is \"%s\"\n", doc_base);
522 }
523
524
525
526
527 /****f* ROBODoc/main [2.0d]
528  * NAME
529  *   main -- Entry point of ROBODoc
530  * SYNOPSIS
531  *   main (int argc, char **argv)
532  * FUNCTION
533  *   Get and parse the arguments.
534  *   Analyse document and generate the documentation.
535  * SOURCE
536  */
537
538 int
539 main (int argc, char **argv)
540 {
541   char *file_with_xrefs, *output_file_for_xrefs;
542
543   whoami = argv[0];             /* global me,myself&i */
544   if (argc < 2)
545     {
546       printf ("%s", use);
547     }
548   else if (argc < 3)
549     {
550       if (strcmp (argv[1], "-c") == 0)
551         {
552           printf ("%s", copying);
553         }
554       else
555         {
556           printf ("%s", use);
557         }
558     }
559   else
560     {
561       RB_Analyse_Arguments (argc, argv, &file_with_xrefs,
562                             &output_file_for_xrefs);
563
564       RB_Say ("Analysing Defaults File\n");
565       RB_Analyse_Defaults_File ();
566
567       RB_Say ("trying to open source file \"%s\"\n", argv[1]);
568       if ((source = fopen (argv[1], "rb")) != NULL)
569         {
570           if (!(course_of_action & DO_INDEX))
571             {
572               RB_Say ("analysing source file \"%s\"\n", argv[1]);
573               RB_Analyse_Document (source);
574               RB_Number_Duplicate_Headers();
575
576               if (course_of_action & DO_SORT)
577                 {
578                   RB_Say ("sorting headers\n");
579                   RB_Slow_Sort ();
580                 }
581               else
582                 {
583                   RB_Reverse_List ();
584                 }
585               if ((course_of_action & DO_USE_XREFS) && file_with_xrefs)
586                 {
587                   if ((xreffiles_file = fopen (file_with_xrefs, "r")) != NULL)
588                     {
589                       RB_Analyse_Xrefs (xreffiles_file);
590                     }
591                   else
592                     {
593                       RB_Panic ("can't open file with xref files \"%s\"\n",
594                                 file_with_xrefs);
595                     }
596                 }
597             }
598           else
599             {                   /* INDEX */
600               if ((xreffiles_file = fopen (argv[1], "r")) != NULL)
601                 {
602                   RB_Analyse_Xrefs (xreffiles_file);
603                 }
604               else
605                 {
606                   RB_Panic ("can't open file with xref files \"%s\"\n",
607                             argv[1]);
608                 }
609             }
610           if (course_of_action & DO_MAKE_DOCUMENT)
611             {
612               RB_Say ("trying to open destination file \"%s\"\n", argv[2]);
613               if ((documentation = fopen (argv[2], "w")) != NULL)
614                 {
615                   RB_Say ("generating documentation\n");
616                   RB_Set_Doc_Base (argv[2]);
617                   RB_Generate_Documentation (documentation,
618                                              RB_FilePart (argv[1]),
619                                              RB_FilePart (argv[2]));
620                   fclose (documentation);
621                   documentation = NULL;
622                 }
623               else
624                 RB_Panic ("can't open destination file \"%s\"\n", argv[2]);
625             }
626           else if ((course_of_action & DO_MAKE_XREFS)
627                    && output_file_for_xrefs)
628             {
629               RB_Say ("trying to open xref destination file \"%s\"\n",
630                       output_file_for_xrefs);
631               if ((documentation = fopen (output_file_for_xrefs, "w")) != NULL)
632                 {
633                   RB_Say ("generating xref destination file \"%s\"\n",
634                           output_file_for_xrefs);
635                   RB_Generate_xrefs (documentation, argv[1], argv[2]);
636                   fclose (documentation);
637                   documentation = NULL;
638                 }
639               else
640                 RB_Panic ("can't open xref destination file \"%s\"\n",
641                           output_file_for_xrefs);
642             }
643           else if (course_of_action & DO_INDEX)
644             {
645               if ((documentation = fopen (argv[2], "w")) != NULL)
646                 {
647                   RB_Generate_Index (documentation, argv[1]);
648                   fclose (documentation);
649                   documentation = NULL;
650                 }
651               else
652                 {
653                   RB_Panic ("can't open destination file \"%s\"\n", argv[2]);
654                 }
655             }
656         }
657       else
658         RB_Panic ("can't open source file \"%s\"\n", argv[1]);
659     }
660   RB_Say ("Ready\n");
661   RB_Close_The_Shop ();
662   return EXIT_SUCCESS;
663 }
664
665 /*****/
666
667
668
669
670 /****f* ROBODoc/RB_Analyse_Arguments [3.0h]
671  * NAME
672  *   RB_Analyse_Arguments
673  * SYNOPSIS
674  *   RB_Analyse_Arguments (argc, argv, file_with_xrefs,
675  *                         output_file_for_xrefs)
676  *   RB_Analyse_Arguments (int, char **, char **, char **)
677  * FUNCTION
678  *   Get and parse the arguments. This is a quite complex function.
679  *   It assumes that the first and second parameter are the
680  *   name of the source file and name of the documentation file
681  *   respectively. They are therefore skipped.
682  *   May modifie: output_mode, course_of_action, file_with_xrefs, 
683  *   output_file_for_xrefs, document_title.
684  * SOURCE
685  */
686
687 void
688 RB_Analyse_Arguments (int argc, char **argv,
689                       char **file_with_xrefs,
690                       char **output_file_for_xrefs)
691 {
692   char **parameter;
693   int parameter_nr;
694
695   for (parameter_nr = argc - 3, parameter = argv + 3;
696        parameter_nr > 0;
697        parameter++, parameter_nr--)
698     {
699
700       if (!RB_Str_Case_Cmp (*parameter, "HTML"))
701         output_mode = HTML;
702       else if (!RB_Str_Case_Cmp (*parameter, "GUIDE"))
703         output_mode = AMIGAGUIDE;
704       else if (!RB_Str_Case_Cmp (*parameter, "LATEX"))
705         output_mode = LATEX;
706       else if (!RB_Str_Case_Cmp (*parameter, "ASCII"))
707         output_mode = ASCII;
708       else if (!RB_Str_Case_Cmp (*parameter, "RTF"))
709         output_mode = RTF;
710       else if (!RB_Str_Case_Cmp (*parameter, "FOLD"))
711         extra_flags |= FOLD;    /* PetteriK */
712       else if (!RB_Str_Case_Cmp (*parameter, "C"))
713         extra_flags |= C_MODE;  /* PetteriK */
714       else if (!RB_Str_Case_Cmp (*parameter, "SORT") ||
715                !RB_Str_Case_Cmp (*parameter, "-S"))
716         course_of_action |= DO_SORT;
717       else if (!RB_Str_Case_Cmp (*parameter, "INDEX"))
718         {
719           course_of_action |= DO_INDEX;
720           course_of_action &= ~DO_MAKE_DOCUMENT;
721         }
722       else if (!RB_Str_Case_Cmp (*parameter, "INTERNAL") ||
723                !RB_Str_Case_Cmp (*parameter, "-I"))
724         course_of_action |= DO_INCLUDE_INTERNAL;
725       else if (!RB_Str_Case_Cmp (*parameter, "SINGLEDOC"))             
726         course_of_action |= DO_SINGLEDOC;
727       else if (!RB_Str_Case_Cmp (*parameter, "NOSOURCE"))              
728         course_of_action |= DO_NOSOURCE;
729       else if (!RB_Str_Case_Cmp (*parameter, "INTERNALONLY") ||
730                !RB_Str_Case_Cmp (*parameter, "-IO"))
731         course_of_action |= DO_INTERNAL_ONLY;
732       else if (!RB_Str_Case_Cmp (*parameter, "TOC") ||
733                !RB_Str_Case_Cmp (*parameter, "-T"))
734         course_of_action |= DO_TOC;
735       else if (!RB_Str_Case_Cmp (*parameter, "-V"))
736         course_of_action |= DO_TELL;
737       else if (!RB_Str_Case_Cmp (*parameter, "TITLE"))
738         {
739           if (--parameter_nr)
740             {
741               parameter++;
742               document_title = *parameter;
743               RB_Say ("TITLE=\"%s\"\n", *document_title);
744             }
745           else
746             RB_Panic ("you must specify a title with the TITLE option\n");
747         }
748       else if (!RB_Str_Case_Cmp (*parameter, "XREF") ||
749                !RB_Str_Case_Cmp (*parameter, "-X"))
750         {
751           if (--parameter_nr)
752             {
753               parameter++;
754               *file_with_xrefs = *parameter;
755               RB_Say ("XREF=\"%s\"\n", *file_with_xrefs);
756               course_of_action |= DO_USE_XREFS;
757             }
758           else
759             RB_Panic ("you must specify a xref file with the XREF option\n");
760         }
761       else if (!RB_Str_Case_Cmp (*parameter, "TABSIZE") ||
762                !RB_Str_Case_Cmp (*parameter, "-TS"))
763         {
764           if (--parameter_nr)
765             {
766               parameter++;
767               tab_size = atoi (*parameter);
768             }
769           else
770             {
771               RB_Panic ("you must specify the number of spaces with the"
772                         " TABSIZE option\n");
773             }
774         }
775       else if (!RB_Str_Case_Cmp (*parameter, "GENXREF") ||
776                !RB_Str_Case_Cmp (*parameter, "-G"))
777         {
778           if (--parameter_nr)
779             {
780               ++parameter;
781               *output_file_for_xrefs = *parameter;
782               RB_Say ("GENXREF=\"%s\"\n", *output_file_for_xrefs);
783               course_of_action |= DO_MAKE_XREFS;
784               course_of_action &= ~DO_MAKE_DOCUMENT;
785             }
786           else
787             RB_Panic ("you must specify a xref file with the GENXREF option\n");
788         }
789       else
790         {
791           RB_Panic ("unknown option %s\n", *parameter);
792         }
793     }
794   if ((course_of_action & DO_USE_XREFS) &&
795       (output_mode == ASCII) &&
796       !(course_of_action & DO_INDEX))
797     {
798       printf ("%s: WARNING, you can not use xrefs when you generate\n"
799               "\t\tdocumentation in ASCII [discarding switch]\n",
800               argv[0]);
801       course_of_action &= ~DO_USE_XREFS;
802     }
803   if (course_of_action & DO_INDEX)
804     {
805       if ((output_mode != LATEX) && (output_mode != HTML)) { 
806             RB_Panic ("you can only use the INDEX option in combination with LATEX or HTML\n");
807       }
808     }
809 }
810
811 /******/
812
813
814
815 /****i* ROBODoc/RB_Close_The_Shop [3.0b]
816  * NAME
817  *   RB_Close_The_Shop -- free resources.
818  * SYNOPSIS
819  *   void RB_Close_The_Shop ()
820  * FUNCTION
821  *   Frees all resources used by robodoc.
822  * SEE ALSO
823  *   RB_Free_Header(), RB_Free_Link()
824  * SOURCE
825  */
826
827 void
828 RB_Close_The_Shop (void)
829 {
830   struct RB_header *cur_header, *tmp_header;
831   struct RB_link *cur_link, *tmp_link;
832
833   if (source)
834     fclose (source);
835   if (documentation)
836     fclose (documentation);
837   if (xreffiles_file)
838     fclose (xreffiles_file);
839   if (xref_file)
840     fclose (xref_file);
841
842   for (cur_header = first_header; cur_header;)
843     {
844       tmp_header = cur_header->next_header;
845       RB_Free_Header (cur_header);
846       cur_header = tmp_header;
847     }
848
849   for (cur_link = first_link; cur_link;)
850     {
851       tmp_link = cur_link->next_link;
852       RB_Free_Link (cur_link);
853       cur_link = tmp_link;
854     }
855
856   if (header_index)
857     free (header_index);
858   if (link_index)
859     free (link_index);
860 }
861
862 /******/