source: rtems/doc/tools/bmenu/main.c @ ae68ff0

4.104.114.84.95
Last change on this file since ae68ff0 was ae68ff0, checked in by Joel Sherrill <joel.sherrill@…>, on 05/27/97 at 12:40:11

Initial revision

  • Property mode set to 100644
File size: 22.1 KB
Line 
1/*
2 *  main.c
3 * 
4 *  This program takes a texinfo file without node and menu commands,
5 *  build those commands and inserts them.
6 *
7 *  It works by reading the input file into a linked list of lines
8 *  and then performing sweeps on that list until all formatting is
9 *  complete.  After the program is run, there is still a little
10 *  clean up to be performed by hand.  The following have to be fixed
11 *  by hand:
12 *    + previous of the first node
13 *    + next of the last node
14 */
15
16#include <assert.h>
17#include <ctype.h>
18#include <limits.h>
19#include <stdio.h>
20#include <stdlib.h>
21#include <string.h>
22
23/* XXX -- just for testing -- these should be set by options */
24char DocsNextNode[]     = "";
25char DocsPreviousNode[] = "Top";
26char DocsUpNode[]       = "Top";
27
28extern int   optind;     /* Why is this not in <stdlib.h>? */
29extern char *optarg;     /* Why is this not in <stdlib.h>? */
30
31#ifndef NAME_MAX
32#define NAME_MAX      14 /* Why is the one in limits.h not showing up? */
33#endif
34#define INIT_DATA
35#define EXTERN
36
37#include "base.h"
38
39FILE           *OutFile = stdout;
40
41/*************************************************************************
42 *************************************************************************
43 *****                 DATA TYPES AND CONSTANT TABLES                *****
44 *************************************************************************
45 *************************************************************************/
46/*
47 *  Usage Information
48 */
49
50char *Usage_Strings[] = {
51  "\n",
52  "usage: cmd [-bv] files ...\n",
53  "\n",
54  "EOF"
55};
56
57/*
58 *  The page separator is not really a keyword and will be purged before
59 *  it is seen elsewhere.
60 */
61
62#define PAGE_SEPARATOR                            "#PAGE"
63
64/*
65 *  Section Delimiter Keywords
66 */
67
68#define MAXIMUM_KEYWORD_LENGTH   32
69
70/*
71 *  Level indicates where in the format the delimiter is allowed to occur.
72 *    1 indicates a major section divider (e.g. "ATTRIBUTE DESCRIPTIONS:").
73 *    2 indicates a subsection (e.g. "ATTRIBUTE:").
74 *    3 indicates a heading (e.g. "DESCRIPTION:").
75 */
76
77#define TEXT         0
78#define SECTION      1
79#define SUBSECTION   2
80#define HEADING      3
81 
82typedef enum {
83  UNUSED,                            /* dummy 0 slot */
84  KEYWORD_CHAPTER,
85  KEYWORD_CHAPHEADING,
86  KEYWORD_SECTION,
87  KEYWORD_SUBSECTION,
88  KEYWORD_OTHER,
89  KEYWORD_END
90 
91}  Keyword_indices_t;
92
93#define KEYWORD_FIRST KEYOWRD_CHAPTER
94#define KEYWORD_LAST  KEYWORD_END
95
96/*
97 *  Line Management Structure
98 */
99
100typedef enum {
101  NO_EXTRA_FORMATTING_INFO,
102  RAW_OUTPUT,
103  PARAGRAPH_OUTPUT
104}  ExtraFormat_info_t;
105
106typedef struct {
107  Chain_Node         Node;
108  Keyword_indices_t  keyword;   /* unused is unknown/undecided */
109  ExtraFormat_info_t format;
110  int                number;
111  char               Contents[ PARAGRAPH_SIZE ];
112} Line_Control;
113
114typedef enum {
115  RT_FORBIDDEN,     /* no text to right allowed */
116  RT_OPTIONAL,      /* text to right optional -- none below */
117  RT_NONE,          /* text to right is "none" or nothing -- none below */
118  RT_REQUIRED,      /* text to right required -- none below */
119  RT_BELOW,         /* text to right forbidden -- text below required */
120  RT_NONE_OR_BELOW, /* text to right is "none" OR there is text below  */
121  RT_EITHER,        /* text to right OR below */
122  RT_BOTH           /* text to right AND below */
123}  Keywords_text_mode_t;
124
125typedef enum {
126  BL_FORBIDDEN,     /* text below forbidden */
127  BL_FORMATTED,     /* text below is to be formatted as paragraphs */
128  BL_RAW,           /* text below is to be unprocessed by this program */
129}  Keywords_text_below_t;
130
131typedef (*Keyword_validater_t)( Line_Control * );
132
133typedef struct {
134  char                      Name[ MAXIMUM_KEYWORD_LENGTH ];
135  int                       level;
136  Keywords_text_mode_t      text_mode;
137  Keywords_text_below_t     text_below_mode;
138  Keyword_validater_t       keyword_validation_routine;
139}  Keyword_info_t;
140
141Keyword_info_t Keywords[] = {
142  { "unused",
143        0,         0,                0, NULL }, /* so 0 can be invalid */
144  { "@chapter",    SECTION,    RT_FORBIDDEN,      BL_FORBIDDEN, NULL },
145  { "@chapheading",SECTION,    RT_FORBIDDEN,      BL_FORBIDDEN, NULL },
146  { "@section",    SECTION,    RT_FORBIDDEN,      BL_FORBIDDEN, NULL },
147  { "@subsection", SUBSECTION, RT_FORBIDDEN,      BL_FORBIDDEN, NULL },
148  { "",            HEADING,    RT_FORBIDDEN,      BL_FORBIDDEN, NULL },
149  { "END OF FILE", SECTION,    RT_FORBIDDEN,      BL_FORBIDDEN, NULL }
150};
151
152#define NUMBER_OF_KEYWORDS \
153  ( sizeof( Keywords ) / sizeof( Keyword_info_t ) ) - 2
154
155/*
156 *  exit_application
157 */
158
159void exit_application(
160  int status
161)
162{
163  fprintf( stderr, "*** Error encountered ***\n" );
164/*
165  fprintf( stderr, "*** Error encountered on line %d ***\n", CurrentLine );
166*/
167  fclose( OutFile );
168  exit( status );
169}
170
171/*************************************************************************
172 *************************************************************************
173 *****                LINE MANIPULATION ROUTINES                     *****
174 *************************************************************************
175 *************************************************************************/
176
177/*
178 * PrintLine
179 */
180
181void PrintLine(
182  Line_Control *line
183)
184{
185  assert( line );
186
187  if ( line->number == -1 )
188    fprintf( stderr, "     " );
189  else
190    fprintf( stderr, "%5d", line->number );
191
192#if 0
193  fprintf( stderr, "%s\n", line->Contents );
194#else
195  /*
196   *  Include some debugging information
197   */
198  fprintf(
199    stderr,
200    "<%d,%d>:%s\n",
201    line->keyword,
202    line->format,
203    line->Contents
204  );
205#endif
206}
207
208Chain_Control Line_Pool;
209
210/*
211 *  FillLinePool
212 */
213
214void FillLinePool( void )
215{
216  void *pool;
217
218#define LINE_POOL_FILL_COUNT 100
219
220  pool = malloc( sizeof( Line_Control ) * LINE_POOL_FILL_COUNT );
221  assert( pool );
222
223  _Chain_Initialize(
224    &Line_Pool,
225    pool,
226    LINE_POOL_FILL_COUNT,
227    sizeof( Line_Control )
228  );
229}
230
231/*
232 * AllocateLine
233 */
234
235Line_Control *AllocateLine( void )
236{
237  Line_Control  *new_line;
238
239  new_line = (Line_Control *) _Chain_Get( &Line_Pool );
240  if ( !new_line ) {
241    FillLinePool();
242    new_line = (Line_Control *) _Chain_Get( &Line_Pool );
243    assert( new_line );
244  }
245 
246/*
247 *  This is commented out because although it is helpful during debug,
248 *  it consumes a significant percentage of the program's execution time.
249 
250  memset( new_line->Contents, '\0', sizeof( new_line->Contents ) );
251*/
252  new_line->number = -1;
253
254  new_line->keyword = UNUSED;
255  new_line->format = NO_EXTRA_FORMATTING_INFO;
256
257  new_line->Node.next     = NULL;
258  new_line->Node.previous = NULL;
259
260  return new_line;
261}
262
263/*
264 * FreeLine
265 */
266
267void FreeLine(
268  Line_Control *line
269)
270{
271  fflush( stdout );
272  _Chain_Append( &Line_Pool, &line->Node );
273}
274
275/*
276 * DeleteLine
277 */
278
279Line_Control *DeleteLine(
280  Line_Control *line
281)
282{
283  Line_Control *next;
284 
285  next = (Line_Control *)line->Node.next;
286  _Chain_Extract( &line->Node );
287  FreeLine( line );
288  return next;
289}
290
291/*
292 *  PrintSurroundingLines
293 */
294
295void PrintSurroundingLines(
296  Line_Control *line,
297  int           backward,
298  int           forward
299)
300{
301  int           i;
302  int           real_backward;
303  Line_Control *local;
304
305  for ( local=line, real_backward=0, i=1 ;
306        i<=backward ;
307        i++, real_backward++ ) {
308    if ( &local->Node == Lines.first )
309      break;
310    local = (Line_Control *) local->Node.previous;
311  }
312
313  for ( i=1 ; i<=real_backward ; i++ ) {
314    PrintLine( local );
315    local = (Line_Control *) local->Node.next;
316  }
317 
318  PrintLine( local );
319
320  for ( i=1 ; i<=forward ; i++ ) {
321    local = (Line_Control *) local->Node.next;
322    if ( _Chain_Is_last( &local->Node ) )
323      break;
324    PrintLine( local );
325  }
326 
327}
328
329/*
330 *  SetLineFormat
331 */
332
333void SetLineFormat(
334  Line_Control       *line,
335  ExtraFormat_info_t  format
336)
337{
338  if ( line->format != NO_EXTRA_FORMATTING_INFO ) {
339    fprintf( stderr, "Line %d is already formatted\n", line->number );
340    PrintLine( line );
341    assert( FALSE );
342  }
343
344  line->format = format;
345}
346
347/*
348 *  LineCopyFromRight
349 */
350
351void LineCopyFromRight(
352  Line_Control *line,
353  char         *dest
354)
355{
356  char *p;
357
358  for ( p=line->Contents ; *p != ' ' ; p++ )
359    ;
360  p++;  /* skip the ' ' */
361  for ( ; isspace( *p ) ; p++ )
362    ;
363
364  strcpy( dest, p );
365
366}
367
368/*
369 *  LineCopySectionName
370 */
371
372void LineCopySectionName(
373  Line_Control *line,
374  char         *dest
375)
376{
377  char *p;
378  char *d;
379
380  p = line->Contents;
381  d = dest;
382
383  if ( *p == '@' ) {                /* skip texinfo command */
384    while ( !isspace( *p++ ) )
385      ;
386  }
387
388  for ( ; *p ; )
389    *d++ = *p++;
390
391  *d = '\0';
392}
393
394/*************************************************************************
395 *************************************************************************
396 *****              END OF LINE MANIPULATION ROUTINES                *****
397 *************************************************************************
398 *************************************************************************/
399
400/*
401 *  main
402 */
403
404int main(
405  int    argc,
406  char **argv
407)
408{
409  int      c;
410  int      index;
411  boolean  single_file_mode;
412
413  Verbose = FALSE;
414
415  while ((c = getopt(argc, argv, "bv")) != EOF) {
416    switch (c) {
417      case 'v':
418        Verbose = TRUE;
419        break;
420      case '?':
421        usage();
422        return 0;
423    }
424  }
425
426  if ( Verbose )
427    fprintf( stderr, "Arguments successfully parsed\n" );
428
429  FillLinePool();
430
431  for ( index=optind ; index < argc ; index++ ) {
432    ProcessFile( argv[ index ], NULL );
433  }
434   
435  if ( Verbose )
436    fprintf( stderr, "Exitting\n" );
437
438  return 0;
439}
440
441/*
442 *  ProcessFile
443 */
444
445void ProcessFile(
446  char   *inname,
447  char   *outname
448)
449{
450   char            out[ 256 ];
451   int             index;
452
453   /*
454    *  Automatically generate the output file name.
455    */
456
457   if ( outname == NULL ) {
458     for( index=0 ; inname[index] && inname[index] != '.' ; index++ ) {
459       out[ index ] = inname[ index ];
460     }
461
462     out[ index++ ] = '.';
463     out[ index++ ] = 't';
464     out[ index++ ] = 'x';
465     out[ index++ ] = 't';
466     out[ index ] = '\0';
467
468   }
469
470   /*
471    *  Read the file into our internal data structure
472    */
473
474   if ( Verbose )
475     printf( "Processing (%s) -> (%s)\n", inname, out );
476
477   ReadFileIntoChain( inname );
478
479   if ( Verbose )
480     fprintf( stderr, "-------->FILE READ IN\n" );
481
482   /*
483    *  Remove any spaces before the keyword and mark each keyword line as
484    *  such.  Also remove extra white space at the end of lines.
485    */
486
487   StripBlanks();
488
489   if ( Verbose )
490     fprintf( stderr, "-------->BLANKS BEFORE KEYWORDS STRIPPED\n" );
491
492
493   FormatToTexinfo();
494
495   if ( Verbose )
496     fprintf( stderr, "-------->FILE FORMATTED TO TEXINFO\n" );
497
498   /*
499    *  Print the file
500    */
501
502   PrintFile( out );
503
504   if ( Verbose )
505     fprintf( stderr, "-------->FILE PRINTED\n" );
506
507   /*
508    *  Clean Up
509    */
510
511   ReleaseFile();
512
513   if ( Verbose )
514     fprintf( stderr, "-------->FILE RELEASED\n" );
515}
516
517/*
518 *  usage
519 */
520
521void usage( void )
522{
523  int index;
524
525  for ( index=0 ; strcmp( Usage_Strings[ index ], "EOF" ) ; index++ )
526    fprintf( stderr, Usage_Strings[ index ] );
527}
528
529/*
530 *  ReadFileIntoChain
531 */
532
533void ReadFileIntoChain(
534  char *inname
535)
536{
537   FILE *InFile;
538   int   line_count;
539   int   max_length;
540   char *line;
541   char  Buffer[ BUFFER_SIZE ];
542   Line_Control *new_line;
543
544   InFile = fopen( inname, "r" );
545
546   if ( !InFile ) {
547     fprintf( stderr, "Unable to open (%s)\n", inname );
548     exit( 1 );
549   }
550   assert( InFile );
551
552   max_length = 0;
553   line_count = 0;
554
555   _Chain_Initialize_empty( &Lines );
556
557   for ( ;; ) {
558      line = fgets( Buffer, BUFFER_SIZE, InFile );
559      if ( !line )
560        break;
561
562      Buffer[ strlen( Buffer ) - 1 ] = '\0';
563
564      new_line = AllocateLine();
565 
566      strcpy( new_line->Contents, Buffer );
567
568      new_line->number = ++line_count;
569 
570      _Chain_Append( &Lines, &new_line->Node );
571   }
572
573   fclose( InFile );
574}
575
576/*
577 *  StripBlanks
578 */
579
580void StripBlanks( void )
581{
582  Line_Control      *line;
583  Keyword_indices_t  index;
584  int                indentation;
585  int                length;
586 
587  for ( line = (Line_Control *) Lines.first ;
588        !_Chain_Is_last( &line->Node ) ;
589        line = (Line_Control *) line->Node.next
590        ) {
591
592    /*
593     *  Strip white space from the end of each line
594     */
595
596    length = strlen( line->Contents );
597
598    while ( isspace( line->Contents[ --length ] ) )
599      line->Contents[ length ] = '\0';
600
601    if ( strstr( line->Contents, "@chapter" ) )
602      line->keyword = KEYWORD_CHAPTER;
603    else if ( strstr( line->Contents, "@chapheading" ) )
604      line->keyword = KEYWORD_CHAPHEADING;
605    else if ( strstr( line->Contents, "@section" ) )
606      line->keyword = KEYWORD_SECTION;
607    else if ( strstr( line->Contents, "@subsection" ) )
608      line->keyword = KEYWORD_SUBSECTION;
609    else
610      line->keyword = KEYWORD_OTHER;
611   
612  }
613  line = AllocateLine();
614  line->keyword = KEYWORD_END;
615  _Chain_Append( &Lines, &line->Node );
616}
617
618/*
619 *  strIsAllSpace
620 */
621
622boolean strIsAllSpace(
623  char *s
624)
625{
626  char *p;
627
628  for ( p = s ; *p ; p++ )
629    if ( !isspace( *p ) )
630      return FALSE;
631
632  return TRUE;
633}
634
635/*
636 *  BuildTexinfoNodes
637 */
638
639void BuildTexinfoNodes( void )
640{
641  Line_Control *line;
642  Line_Control *new_line;
643  Line_Control *next_node;
644  char          Buffer[ BUFFER_SIZE ];
645  char          ChapterName[ BUFFER_SIZE ];
646  char          NodeName[ BUFFER_SIZE ];
647  char          NextNode[ BUFFER_SIZE ];
648  char          NextNodeName[ BUFFER_SIZE ];
649  char          PreviousNodeName[ BUFFER_SIZE ];
650  char          UpNodeName[ BUFFER_SIZE ];
651  char          SectionName[ BUFFER_SIZE ];
652  char          MenuBuffer[ BUFFER_SIZE ];
653  Line_Control *node_insert_point;
654  Line_Control *menu_insert_point;
655  Line_Control *node_line;
656  boolean       next_found;
657  int           menu_items;
658
659  strcpy( PreviousNodeName, DocsPreviousNode );
660
661  for ( line = (Line_Control *) Lines.first ;
662        !_Chain_Is_last( &line->Node ) ;
663        line = (Line_Control *) line->Node.next
664      ) {
665
666    menu_insert_point = (Line_Control *) line->Node.next;
667
668    switch ( Keywords[ line->keyword ].level ) {
669      case TEXT:
670      case HEADING:
671        break;
672      case SECTION:
673        if ( line->keyword == KEYWORD_END )
674          goto bottom;
675
676        if ( line->keyword == KEYWORD_CHAPTER ||
677             line->keyword == KEYWORD_CHAPHEADING ) {
678          LineCopyFromRight( line, ChapterName );
679          strcpy( UpNodeName, DocsUpNode );
680          strcpy( NodeName, ChapterName );
681        } else {
682          LineCopySectionName( line, Buffer );
683          sprintf( NodeName, "%s %s", ChapterName, Buffer );
684          strcpy( UpNodeName, ChapterName );
685        }
686        strcpy( SectionName, NodeName );
687
688        /*
689         *  Go ahead and put it on the chain in the right order (ahead of
690         *  the menu) and we can fill it in later (after the menu is built).
691         */
692
693        new_line = AllocateLine();
694        strcpy( new_line->Contents, "@ifinfo" );
695        _Chain_Insert( line->Node.previous, &new_line->Node );
696
697        node_line = AllocateLine();
698        _Chain_Insert( line->Node.previous, &node_line->Node );
699
700        new_line = AllocateLine();
701        strcpy( new_line->Contents, "@end ifinfo" );
702        _Chain_Insert( line->Node.previous, &new_line->Node );
703
704        menu_items = 0;
705       
706        if ( line->keyword == KEYWORD_CHAPTER || line->keyword == KEYWORD_CHAPHEADING ) {
707          next_node = (Line_Control *) line->Node.next;
708          next_found = FALSE;
709          for ( ; ; ) {
710            if ( next_node->keyword == KEYWORD_END )
711              break;
712            if ( Keywords[ next_node->keyword ].level == SECTION ) {
713              LineCopySectionName( next_node, Buffer );
714              if ( !next_found ) {
715                next_found = TRUE;
716                sprintf( NextNodeName, "%s %s", ChapterName, Buffer );
717              }
718
719              if ( menu_items == 0 ) {
720                new_line = AllocateLine();
721                strcpy( new_line->Contents, "@ifinfo" );
722                _Chain_Insert( menu_insert_point->Node.previous, &new_line->Node );
723
724                new_line = AllocateLine();
725                strcpy( new_line->Contents, "@menu" );
726                _Chain_Insert( menu_insert_point->Node.previous, &new_line->Node );
727              }
728
729              menu_items++;
730
731              new_line = AllocateLine();
732              sprintf( new_line->Contents, "* %s %s::", ChapterName, Buffer );
733              _Chain_Insert( menu_insert_point->Node.previous, &new_line->Node );
734            }
735            next_node = (Line_Control *) next_node->Node.next;
736          }
737        } else {
738          next_node = (Line_Control *) line->Node.next;
739       
740          next_found = FALSE;
741          for ( ; ; ) {
742            if ( Keywords[ next_node->keyword ].level == SECTION ) {
743              if ( !next_found ) {
744                if ( next_node->keyword == KEYWORD_END ) {
745                  strcpy( NextNodeName, DocsNextNode );
746                } else {
747                  LineCopySectionName( next_node, Buffer );
748                  sprintf( NextNodeName, "%s %s", ChapterName, Buffer );
749                }
750                next_found = TRUE;
751              }
752              break;
753            } else if ( Keywords[ next_node->keyword ].level == SUBSECTION ) {
754              LineCopySectionName( next_node, MenuBuffer ); /* has next node */
755
756              if ( menu_items == 0 ) {
757                new_line = AllocateLine();
758                strcpy( new_line->Contents, "@ifinfo" );
759                _Chain_Insert( menu_insert_point->Node.previous, &new_line->Node );
760
761                new_line = AllocateLine();
762                strcpy( new_line->Contents, "@menu" );
763                _Chain_Insert( menu_insert_point->Node.previous, &new_line->Node );
764              }
765
766              menu_items++;
767
768              new_line = AllocateLine();
769              sprintf( new_line->Contents, "* %s::", MenuBuffer );
770              _Chain_Insert( menu_insert_point->Node.previous, &new_line->Node );
771
772              if ( !next_found ) {
773                next_found = TRUE;
774                strcpy( NextNodeName, MenuBuffer );
775              }
776            }
777            next_node = (Line_Control *) next_node->Node.next;
778          }
779        }
780
781        if ( menu_items ) {
782          new_line = AllocateLine();
783          strcpy( new_line->Contents, "@end menu" );
784          _Chain_Insert( menu_insert_point->Node.previous, &new_line->Node );
785
786          new_line = AllocateLine();
787          strcpy( new_line->Contents, "@end ifinfo" );
788          _Chain_Insert( menu_insert_point->Node.previous, &new_line->Node );
789        }
790#if 0
791        fprintf(
792          stderr,
793          "@node %s, %s, %s, %s\n",
794          NodeName,
795          NextNodeName,
796          PreviousNodeName,
797          UpNodeName
798        );
799#endif
800        /* node_line was previously inserted */
801        sprintf(
802          node_line->Contents,
803          "@node %s, %s, %s, %s",
804          NodeName,
805          NextNodeName,
806          PreviousNodeName,
807          UpNodeName
808        );
809
810        strcpy( PreviousNodeName, NodeName );
811        break;
812
813      case SUBSECTION:
814        strcpy( UpNodeName, SectionName );
815
816        LineCopyFromRight( line, NodeName );
817
818        new_line = AllocateLine();
819        strcpy( new_line->Contents, "@ifinfo" );
820        _Chain_Insert( line->Node.previous, &new_line->Node );
821
822        next_node = (Line_Control *) line->Node.next;
823        for ( ; ; ) {
824          if ( Keywords[ next_node->keyword ].level == SECTION ) {
825            if ( next_node->keyword == KEYWORD_END ) {
826              strcpy( NextNodeName, DocsNextNode );
827            } else {
828              LineCopySectionName( next_node, Buffer );
829              sprintf( NextNodeName, "%s %s", ChapterName, Buffer );
830            }
831            break;
832          } else if ( Keywords[ next_node->keyword ].level == SUBSECTION ) {
833            LineCopyFromRight( next_node, NextNodeName );
834            break;
835          }
836          next_node = (Line_Control *) next_node->Node.next;
837        }
838
839#if 0
840        fprintf(
841          stderr,
842          "@node %s, %s, %s, %s\n",
843          NodeName,
844          NextNodeName,
845          PreviousNodeName,
846          UpNodeName
847        );
848#endif
849        new_line = AllocateLine();
850        sprintf(
851          new_line->Contents,
852          "@node %s, %s, %s, %s",
853          NodeName,
854          NextNodeName,
855          PreviousNodeName,
856          UpNodeName
857        );
858        _Chain_Insert( line->Node.previous, &new_line->Node );
859
860        new_line = AllocateLine();
861        strcpy( new_line->Contents, "@end ifinfo" );
862        _Chain_Insert( line->Node.previous, &new_line->Node );
863
864        strcpy( PreviousNodeName, NodeName );
865        break;
866    }
867  }
868bottom:
869}
870
871/*
872 *  FormatToTexinfo
873 */
874
875void FormatToTexinfo( void )
876{
877  if ( Verbose )
878    fprintf( stderr, "-------->INSERTING TEXINFO MENUS\n" );
879
880  BuildTexinfoNodes();
881}
882
883/*
884 *  PrintFile
885 */
886
887void PrintFile(
888  char *out
889)
890{
891  Line_Control *line;
892
893  OutFile = fopen( out, "w+" );
894
895  if ( !OutFile ) {
896    fprintf( stderr, "Unable to open (%s) for output\n", out );
897    exit_application( 1 );
898  }
899  assert( OutFile );
900
901  for ( line = (Line_Control *) Lines.first ;
902        !_Chain_Is_last( &line->Node ) ;
903        line = (Line_Control *) line->Node.next ) {
904    fprintf( OutFile, "%s\n", line->Contents );
905/*
906    fprintf(
907      OutFile,
908      "(%d,%d)%s\n",
909      line->keyword,
910      line->format,
911      line->Contents
912    );
913*/
914  }
915}
916
917/*
918 *  DumpList
919 */
920
921void DumpList(
922  Chain_Control  *the_list
923)
924{
925  Line_Control  *line;
926
927  fprintf( stderr, "---> Dumping list (%p)\n", the_list );
928
929  for ( line = (Line_Control *) the_list->first ;
930      !_Chain_Is_last( &line->Node ) ;
931      line = (Line_Control *) line->Node.next ) {
932    fprintf( stderr, "%s\n", line->Contents );
933  }
934}
935
936/*
937 * ReleaseFile
938 */
939
940void ReleaseFile()
941{
942   Line_Control *line;
943   Line_Control *next;
944
945   for ( line = (Line_Control *) Lines.first ;
946         !_Chain_Is_last( &line->Node ) ;
947       ) {
948     next = (Line_Control *) line->Node.next;
949     line = next;
950   }
951}
952
953/*
954 *  strtoInitialCaps
955 */
956
957void strtoInitialCaps(
958  char *dest,
959  char *src
960)
961{
962  char *source = src;
963  char *destination = dest;
964
965  source = src;
966  destination = (dest) ? dest : src;
967
968  while ( *source ) {
969    while ( isspace( *source ) )
970      *destination++ = *source++;
971
972    if ( !*source )
973      break;
974
975    *destination++ = toupper( *source++ );
976
977    for ( ; *source && !isspace( *source ) ; source++ )
978      *destination++ = tolower( *source );
979     
980    if ( !*source )
981      break;
982  }
983
984  *destination = '\0';
985}
Note: See TracBrowser for help on using the repository browser.