OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rtems-20020807/] [doc/] [tools/] [bmenu/] [bmenu2.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.