From 2744eec4952b3280f323d85459e5c90648e7c45d Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Fri, 31 Oct 1997 19:44:23 +0000 Subject: Replaced the algorithm used to build the texinfo nodes and menus. This was necessary to fix some bugs and to support the "@subsubsection", "@raise", and "@lower" commands. The major known bug was that single section chapters were not being processed correctly. Added the -c option so chapter names do not always have to included in the node names. --- doc/tools/bmenu/main.c | 454 +++++++++++++++++++++++++------------------------ 1 file changed, 236 insertions(+), 218 deletions(-) (limited to 'doc/tools/bmenu/main.c') diff --git a/doc/tools/bmenu/main.c b/doc/tools/bmenu/main.c index d60c559ea5..a204da1dbb 100644 --- a/doc/tools/bmenu/main.c +++ b/doc/tools/bmenu/main.c @@ -33,6 +33,7 @@ char EmptyString[] = ""; char *DocsNextNode; char *DocsPreviousNode; char *DocsUpNode; +int NodeNameIncludesChapter = 1; extern int optind; /* Why is this not in ? */ extern char *optarg; /* Why is this not in ? */ @@ -58,7 +59,7 @@ FILE *OutFile = stdout; char *Usage_Strings[] = { "\n", - "usage: cmd [-bv] [-p prev] [-n next] [-u up] files ...\n", + "usage: cmd [-cv] [-p prev] [-n next] [-u up] files ...\n", "\n", "EOF" }; @@ -83,10 +84,11 @@ char *Usage_Strings[] = { * 3 indicates a heading (e.g. "DESCRIPTION:"). */ -#define TEXT 0 -#define SECTION 1 -#define SUBSECTION 2 -#define HEADING 3 +#define TEXT 0 +#define SECTION 1 +#define SUBSECTION 2 +#define SUBSUBSECTION 3 +#define HEADING 4 typedef enum { UNUSED, /* dummy 0 slot */ @@ -94,6 +96,9 @@ typedef enum { KEYWORD_CHAPHEADING, KEYWORD_SECTION, KEYWORD_SUBSECTION, + KEYWORD_SUBSUBSECTION, + KEYWORD_RAISE, + KEYWORD_LOWER, KEYWORD_OTHER, KEYWORD_END @@ -117,6 +122,7 @@ typedef struct { Keyword_indices_t keyword; /* unused is unknown/undecided */ ExtraFormat_info_t format; int number; + int level; char Contents[ PARAGRAPH_SIZE ]; } Line_Control; @@ -148,14 +154,16 @@ typedef struct { } Keyword_info_t; Keyword_info_t Keywords[] = { - { "unused", - 0, 0, 0, NULL }, /* so 0 can be invalid */ - { "@chapter", SECTION, RT_FORBIDDEN, BL_FORBIDDEN, NULL }, - { "@chapheading",SECTION, RT_FORBIDDEN, BL_FORBIDDEN, NULL }, - { "@section", SECTION, RT_FORBIDDEN, BL_FORBIDDEN, NULL }, - { "@subsection", SUBSECTION, RT_FORBIDDEN, BL_FORBIDDEN, NULL }, - { "", HEADING, RT_FORBIDDEN, BL_FORBIDDEN, NULL }, - { "END OF FILE", SECTION, RT_FORBIDDEN, BL_FORBIDDEN, NULL } + { "unused", 0, 0, 0, NULL }, /* so 0 can be invalid */ + { "@chapter", SECTION, RT_FORBIDDEN, BL_FORBIDDEN, NULL }, + { "@chapheading", SECTION, RT_FORBIDDEN, BL_FORBIDDEN, NULL }, + { "@section", SECTION, RT_FORBIDDEN, BL_FORBIDDEN, NULL }, + { "@subsection", SUBSECTION, RT_FORBIDDEN, BL_FORBIDDEN, NULL }, + { "@subsubsection", SUBSUBSECTION, RT_FORBIDDEN, BL_FORBIDDEN, NULL }, + { "@raise", SUBSECTION, RT_FORBIDDEN, BL_FORBIDDEN, NULL }, + { "@lower", SUBSECTION, RT_FORBIDDEN, BL_FORBIDDEN, NULL }, + { "", HEADING, RT_FORBIDDEN, BL_FORBIDDEN, NULL }, + { "END OF FILE", SECTION, RT_FORBIDDEN, BL_FORBIDDEN, NULL } }; #define NUMBER_OF_KEYWORDS \ @@ -206,9 +214,10 @@ void PrintLine( */ fprintf( stderr, - "<%d,%d>:%s\n", + "<%d,%d,%d>:%s\n", line->keyword, line->format, + line->level, line->Contents ); #endif @@ -259,6 +268,7 @@ Line_Control *AllocateLine( void ) memset( new_line->Contents, '\0', sizeof( new_line->Contents ) ); */ new_line->number = -1; + new_line->level = -1; new_line->keyword = UNUSED; new_line->format = NO_EXTRA_FORMATTING_INFO; @@ -424,11 +434,14 @@ int main( DocsPreviousNode = TopString; DocsUpNode = TopString; - while ((c = getopt(argc, argv, "vp:n:u:")) != EOF) { + while ((c = getopt(argc, argv, "vcp:n:u:")) != EOF) { switch (c) { case 'v': Verbose = TRUE; break; + case 'c': + NodeNameIncludesChapter = 0; + break; case 'p': DocsPreviousNode = strdup(optarg); break; @@ -633,6 +646,12 @@ void StripBlanks( void ) line->keyword = KEYWORD_SECTION; else if ( strstr( line->Contents, "@subsection" ) ) line->keyword = KEYWORD_SUBSECTION; + else if ( strstr( line->Contents, "@subsubsection" ) ) + line->keyword = KEYWORD_SUBSUBSECTION; + else if ( strstr( line->Contents, "@raise" ) ) + line->keyword = KEYWORD_RAISE; + else if ( strstr( line->Contents, "@lower" ) ) + line->keyword = KEYWORD_LOWER; else line->keyword = KEYWORD_OTHER; @@ -665,234 +684,188 @@ boolean strIsAllSpace( void BuildTexinfoNodes( void ) { - Line_Control *line; - Line_Control *new_line; - Line_Control *next_node; - char Buffer[ BUFFER_SIZE ]; - char ChapterName[ BUFFER_SIZE ]; - char NodeName[ BUFFER_SIZE ]; - char NextNode[ BUFFER_SIZE ]; - char NextNodeName[ BUFFER_SIZE ]; - char PreviousNodeName[ BUFFER_SIZE ]; - char UpNodeName[ BUFFER_SIZE ]; - char SectionName[ BUFFER_SIZE ]; - char MenuBuffer[ BUFFER_SIZE ]; - Line_Control *node_insert_point; - Line_Control *menu_insert_point; - Line_Control *node_line; - boolean next_found; - int menu_items; + char Buffer[ BUFFER_SIZE ]; + Line_Control *line; + Line_Control *next_node; + Line_Control *up_node; + Line_Control *new_line; + Line_Control *menu_insert_point; + Line_Control *node_line; + int next_found; + int menu_items; + Keyword_indices_t index; + char ChapterName[ BUFFER_SIZE ]; + char NodeName[ BUFFER_SIZE ]; + char UpNodeName[ BUFFER_SIZE ]; + char NextNodeName[ BUFFER_SIZE ]; + char PreviousNodeName[ BUFFER_SIZE ]; + + /* + * Set Initial Previous Node Name + */ strcpy( PreviousNodeName, DocsPreviousNode ); for ( line = (Line_Control *) Lines.first ; - !_Chain_Is_last( &line->Node ) ; + !_Chain_Is_last( &line->Node ) ; line = (Line_Control *) line->Node.next - ) { + ) { - menu_insert_point = (Line_Control *) line->Node.next; + if ( line->level == -1 ) + continue; - switch ( Keywords[ line->keyword ].level ) { - case TEXT: - case HEADING: - break; - case SECTION: - if ( line->keyword == KEYWORD_END ) - goto bottom; - - if ( line->keyword == KEYWORD_CHAPTER || - line->keyword == KEYWORD_CHAPHEADING ) { - LineCopyFromRight( line, ChapterName ); - strcpy( UpNodeName, DocsUpNode ); - strcpy( NodeName, ChapterName ); - } else { - LineCopySectionName( line, Buffer ); - sprintf( NodeName, "%s %s", ChapterName, Buffer ); - strcpy( UpNodeName, ChapterName ); - } - strcpy( SectionName, NodeName ); + LineCopyFromRight( line, NodeName ); - /* - * Go ahead and put it on the chain in the right order (ahead of - * the menu) and we can fill it in later (after the menu is built). - */ + if ( line->keyword == KEYWORD_CHAPTER || + line->keyword == KEYWORD_CHAPHEADING ) { + + strcpy( ChapterName, NodeName ); - new_line = AllocateLine(); - strcpy( new_line->Contents, "@ifinfo" ); - _Chain_Insert( line->Node.previous, &new_line->Node ); + } - node_line = AllocateLine(); - _Chain_Insert( line->Node.previous, &node_line->Node ); + /* + * Set Default Next Node Name + */ - new_line = AllocateLine(); - strcpy( new_line->Contents, "@end ifinfo" ); - _Chain_Insert( line->Node.previous, &new_line->Node ); - - menu_items = 0; - - if ( line->keyword == KEYWORD_CHAPTER || line->keyword == KEYWORD_CHAPHEADING ) { - next_node = (Line_Control *) line->Node.next; - next_found = FALSE; - for ( ; ; ) { - if ( next_node->keyword == KEYWORD_END ) - break; - if ( Keywords[ next_node->keyword ].level == SECTION ) { - LineCopySectionName( next_node, Buffer ); - if ( !next_found ) { - next_found = TRUE; - sprintf( NextNodeName, "%s %s", ChapterName, Buffer ); - } - - if ( menu_items == 0 ) { - new_line = AllocateLine(); - strcpy( new_line->Contents, "@ifinfo" ); - _Chain_Insert( menu_insert_point->Node.previous, &new_line->Node ); - - new_line = AllocateLine(); - strcpy( new_line->Contents, "@menu" ); - _Chain_Insert( menu_insert_point->Node.previous, &new_line->Node ); - } - - menu_items++; - - new_line = AllocateLine(); - sprintf( new_line->Contents, "* %s %s::", ChapterName, Buffer ); - _Chain_Insert( menu_insert_point->Node.previous, &new_line->Node ); - } - next_node = (Line_Control *) next_node->Node.next; - } - } else { - next_node = (Line_Control *) line->Node.next; - - next_found = FALSE; - for ( ; ; ) { - if ( Keywords[ next_node->keyword ].level == SECTION ) { - if ( !next_found ) { - if ( next_node->keyword == KEYWORD_END ) { - strcpy( NextNodeName, DocsNextNode ); - } else { - LineCopySectionName( next_node, Buffer ); - sprintf( NextNodeName, "%s %s", ChapterName, Buffer ); - } - next_found = TRUE; - } - break; - } else if ( Keywords[ next_node->keyword ].level == SUBSECTION ) { - LineCopySectionName( next_node, MenuBuffer ); /* has next node */ - - if ( menu_items == 0 ) { - new_line = AllocateLine(); - strcpy( new_line->Contents, "@ifinfo" ); - _Chain_Insert( menu_insert_point->Node.previous, &new_line->Node ); - - new_line = AllocateLine(); - strcpy( new_line->Contents, "@menu" ); - _Chain_Insert( menu_insert_point->Node.previous, &new_line->Node ); - } - - menu_items++; - - new_line = AllocateLine(); - sprintf( new_line->Contents, "* %s::", MenuBuffer ); - _Chain_Insert( menu_insert_point->Node.previous, &new_line->Node ); - - if ( !next_found ) { - next_found = TRUE; - strcpy( NextNodeName, MenuBuffer ); - } - } - next_node = (Line_Control *) next_node->Node.next; - } - } + next_found = FALSE; + strcpy( NextNodeName, DocsNextNode ); + + /* + * Go ahead and put it on the chain in the right order (ahead of + * the menu) and we can fill it in later (after the menu is built). + */ - if ( menu_items ) { - new_line = AllocateLine(); - strcpy( new_line->Contents, "@end menu" ); - _Chain_Insert( menu_insert_point->Node.previous, &new_line->Node ); + new_line = AllocateLine(); + strcpy( new_line->Contents, "@ifinfo" ); + _Chain_Insert( line->Node.previous, &new_line->Node ); - new_line = AllocateLine(); - strcpy( new_line->Contents, "@end ifinfo" ); - _Chain_Insert( menu_insert_point->Node.previous, &new_line->Node ); - } -#if 0 - fprintf( - stderr, - "@node %s, %s, %s, %s\n", - NodeName, - NextNodeName, - PreviousNodeName, - UpNodeName - ); -#endif - /* node_line was previously inserted */ - sprintf( - node_line->Contents, - "@node %s, %s, %s, %s", - NodeName, - NextNodeName, - PreviousNodeName, - UpNodeName - ); - - strcpy( PreviousNodeName, NodeName ); + node_line = AllocateLine(); + _Chain_Insert( line->Node.previous, &node_line->Node ); + + new_line = AllocateLine(); + strcpy( new_line->Contents, "@end ifinfo" ); + _Chain_Insert( line->Node.previous, &new_line->Node ); + + next_node = (Line_Control *) line->Node.next; + menu_insert_point = next_node; + menu_items = 0; + + for ( ; ; ) { + if ( next_node->keyword == KEYWORD_END ) break; - case SUBSECTION: - strcpy( UpNodeName, SectionName ); + if ( next_node->level == -1 ) + goto continue_menu_loop; - LineCopyFromRight( line, NodeName ); + LineCopySectionName( next_node, Buffer ); + if ( !next_found ) { + next_found = TRUE; + if (NodeNameIncludesChapter) + sprintf( NextNodeName, "%s %s", ChapterName, Buffer ); + else + sprintf( NextNodeName, "%s", Buffer ); + } + + if ( next_node->level <= line->level ) + break; + if ( next_node->level != (line->level + 1) ) + goto continue_menu_loop; + + if ( menu_items == 0 ) { new_line = AllocateLine(); strcpy( new_line->Contents, "@ifinfo" ); - _Chain_Insert( line->Node.previous, &new_line->Node ); - - next_node = (Line_Control *) line->Node.next; - for ( ; ; ) { - if ( Keywords[ next_node->keyword ].level == SECTION ) { - if ( next_node->keyword == KEYWORD_END ) { - strcpy( NextNodeName, DocsNextNode ); - } else { - LineCopySectionName( next_node, Buffer ); - sprintf( NextNodeName, "%s %s", ChapterName, Buffer ); - } - break; - } else if ( Keywords[ next_node->keyword ].level == SUBSECTION ) { - LineCopyFromRight( next_node, NextNodeName ); - break; - } - next_node = (Line_Control *) next_node->Node.next; + _Chain_Insert( menu_insert_point->Node.previous, &new_line->Node ); + + new_line = AllocateLine(); + strcpy( new_line->Contents, "@menu" ); + _Chain_Insert( menu_insert_point->Node.previous, &new_line->Node ); + } + + menu_items++; + + new_line = AllocateLine(); + if (NodeNameIncludesChapter) + sprintf( new_line->Contents, "* %s %s::", ChapterName, Buffer ); + else + sprintf( new_line->Contents, "* %s::", Buffer ); + _Chain_Insert( menu_insert_point->Node.previous, &new_line->Node ); + +continue_menu_loop: + next_node = (Line_Control *) next_node->Node.next; + } + + /* + * If menu items were generated, then insert the end of menu stuff. + */ + + if ( menu_items ) { + new_line = AllocateLine(); + strcpy( new_line->Contents, "@end menu" ); + _Chain_Insert( menu_insert_point->Node.previous, &new_line->Node ); + + new_line = AllocateLine(); + strcpy( new_line->Contents, "@end ifinfo" ); + _Chain_Insert( menu_insert_point->Node.previous, &new_line->Node ); + } + + /* + * Find the UpNodeName + */ + +/* DumpList( &Lines ); */ + + if ( line->level == 0 ) { + strcpy( UpNodeName, DocsUpNode ); + } else { + for ( up_node = line; + up_node && !_Chain_Is_first((Chain_Node *)up_node) ; + up_node = (Line_Control *) up_node->Node.previous + ) { + + if ( (up_node->level == -1) ) + continue; + + if ( up_node->level == (line->level - 1) ) { + LineCopySectionName( up_node, Buffer ); + if (NodeNameIncludesChapter) + sprintf( UpNodeName, "%s %s", ChapterName, Buffer ); + else + sprintf( UpNodeName, "%s", Buffer ); + break; } + } + } + + /* + * Update the node information + */ #if 0 - fprintf( - stderr, - "@node %s, %s, %s, %s\n", - NodeName, - NextNodeName, - PreviousNodeName, - UpNodeName - ); + fprintf( + stderr, + "@node %s, %s, %s, %s\n", + NodeName, + NextNodeName, + PreviousNodeName, + UpNodeName + ); #endif - new_line = AllocateLine(); - sprintf( - new_line->Contents, - "@node %s, %s, %s, %s", - NodeName, - NextNodeName, - PreviousNodeName, - UpNodeName - ); - _Chain_Insert( line->Node.previous, &new_line->Node ); - new_line = AllocateLine(); - strcpy( new_line->Contents, "@end ifinfo" ); - _Chain_Insert( line->Node.previous, &new_line->Node ); + /* node_line was previously inserted */ + sprintf( + node_line->Contents, + "@node %s, %s, %s, %s", + NodeName, + NextNodeName, + PreviousNodeName, + UpNodeName + ); - strcpy( PreviousNodeName, NodeName ); - break; - } + strcpy( PreviousNodeName, NodeName ); + + /* PrintLine( line ); */ } -bottom: } /* @@ -901,9 +874,52 @@ bottom: void FormatToTexinfo( void ) { + Line_Control *line; + int baselevel = 0; + int currentlevel; + if ( Verbose ) fprintf( stderr, "-------->INSERTING TEXINFO MENUS\n" ); + for ( line = (Line_Control *) Lines.first ; + !_Chain_Is_last( &line->Node ) ; + line = (Line_Control *) line->Node.next ) { + + switch (line->keyword) { + case UNUSED: + case KEYWORD_OTHER: + case KEYWORD_END: + line->level = -1; + break; + case KEYWORD_CHAPTER: + case KEYWORD_CHAPHEADING: + currentlevel = 0; + line->level = baselevel + currentlevel; + break; + case KEYWORD_SECTION: + currentlevel = 1; + line->level = baselevel + currentlevel; + break; + case KEYWORD_SUBSECTION: + currentlevel = 2; + line->level = baselevel + currentlevel; + break; + case KEYWORD_SUBSUBSECTION: + currentlevel = 3; + line->level = baselevel + currentlevel; + break; + case KEYWORD_RAISE: + assert( baselevel ); + baselevel--; + line->level = -1; + break; + case KEYWORD_LOWER: + baselevel++; + line->level = -1; + break; + } + } + BuildTexinfoNodes(); } @@ -956,7 +972,9 @@ void DumpList( for ( line = (Line_Control *) the_list->first ; !_Chain_Is_last( &line->Node ) ; line = (Line_Control *) line->Node.next ) { - fprintf( stderr, "%s\n", line->Contents ); + /* if (line->level != -1) */ + PrintLine( line ); + /* fprintf( stderr, "%s\n", line->Contents ); */ } } -- cgit v1.2.3