summaryrefslogtreecommitdiffstats
path: root/doc/tools/bmenu
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1997-05-27 12:40:11 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1997-05-27 12:40:11 +0000
commitae68ff085724dd35d60151bd153e80b8b0776873 (patch)
tree2f1535a0497f5b872a4744ae13c9264b77e89c11 /doc/tools/bmenu
parentThis commit was generated by cvs2svn to compensate for changes in r832, (diff)
downloadrtems-ae68ff085724dd35d60151bd153e80b8b0776873.tar.bz2
Initial revision
Diffstat (limited to 'doc/tools/bmenu')
-rw-r--r--doc/tools/bmenu/Makefile43
-rw-r--r--doc/tools/bmenu/address.h112
-rw-r--r--doc/tools/bmenu/address.inl107
-rw-r--r--doc/tools/bmenu/base.h106
-rw-r--r--doc/tools/bmenu/bmenubin0 -> 38028 bytes
-rw-r--r--doc/tools/bmenu/chain.c232
-rw-r--r--doc/tools/bmenu/chain.h349
-rw-r--r--doc/tools/bmenu/chain.inl273
-rw-r--r--doc/tools/bmenu/chain.obin0 -> 6752 bytes
-rw-r--r--doc/tools/bmenu/isr.h11
-rw-r--r--doc/tools/bmenu/main.c985
-rw-r--r--doc/tools/bmenu/main.obin0 -> 28012 bytes
-rw-r--r--doc/tools/bmenu/system.h29
13 files changed, 2247 insertions, 0 deletions
diff --git a/doc/tools/bmenu/Makefile b/doc/tools/bmenu/Makefile
new file mode 100644
index 0000000000..597593dc57
--- /dev/null
+++ b/doc/tools/bmenu/Makefile
@@ -0,0 +1,43 @@
+#
+# COPYRIGHT (c) 1996.
+# On-Line Applications Research Corporation (OAR).
+# All rights reserved.
+#
+
+CC=gcc
+#CFLAGS=-O4 -fomit-frame-pointer
+CFLAGS=-g
+
+#TEXINPUTS=/home/gnu/work/binutils-2.6/texinfo:.
+PROG=bmenu
+
+all: $(PROG)
+
+$(BASE).txt: $(BASE).d ./$(PROG)
+ ./$(PROG) $(BASE).d
+
+$(PROG): main.o chain.o
+ gcc main.o chain.o -o $(PROG)
+
+main.o: main.c base.h
+
+chain.o: chain.c
+
+info: c_user.texinfo timer.texi
+ makeinfo c_user.texinfo
+
+TESTER=init
+test: all
+ #rm -f timer.txt
+ #./bmenu -v timer.texi
+ cp ../user/$(TESTER).texi .
+ ./bmenu $(TESTER).texi
+ mv $(TESTER).txt $(TESTER).texi
+ makeinfo c_user.texinfo
+
+
+clean:
+ rm -f *.o $(PROG) *.txt core *.html
+ rm -f *.dvi *.ps *.log *.aux *.cp *.fn *.ky *.pg *.toc *.tp *.vr $(BASE)
+ rm -f c_user c_user-* _*
+
diff --git a/doc/tools/bmenu/address.h b/doc/tools/bmenu/address.h
new file mode 100644
index 0000000000..f4ebf905b3
--- /dev/null
+++ b/doc/tools/bmenu/address.h
@@ -0,0 +1,112 @@
+/* address.h
+ *
+ * This include file contains the information required to manipulate
+ * physical addresses.
+ *
+ * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ * On-Line Applications Research Corporation (OAR).
+ * All rights assigned to U.S. Government, 1994.
+ *
+ * This material may be reproduced by or for the U.S. Government pursuant
+ * to the copyright license under the clause at DFARS 252.227-7013. This
+ * notice must appear in all copies of this file and its derivatives.
+ */
+
+#ifndef __ADDRESSES_h
+#define __ADDRESSES_h
+
+/*
+ * _Addresses_Add_offset
+ *
+ * DESCRIPTION:
+ *
+ * This function is used to add an offset to a base address.
+ * It returns the resulting address. This address is typically
+ * converted to an access type before being used further.
+ */
+
+STATIC INLINE void *_Addresses_Add_offset (
+ void *base,
+ unsigned32 offset
+);
+
+/*
+ * _Addresses_Subtract_offset
+ *
+ * DESCRIPTION:
+ *
+ * This function is used to subtract an offset from a base
+ * address. It returns the resulting address. This address is
+ * typically converted to an access type before being used further.
+ */
+
+STATIC INLINE void *_Addresses_Subtract_offset(
+ void *base,
+ unsigned32 offset
+);
+
+/*
+ * _Addresses_Add
+ *
+ * DESCRIPTION:
+ *
+ * This function is used to add two addresses. It returns the
+ * resulting address. This address is typically converted to an
+ * access type before being used further.
+ */
+
+STATIC INLINE void *_Addresses_Add (
+ void *left,
+ void *right
+);
+
+/*
+ * _Addresses_Subtract
+ *
+ * DESCRIPTION:
+ *
+ * This function is used to subtract two addresses. It returns the
+ * resulting offset.
+ */
+
+STATIC INLINE unsigned32 _Addresses_Subtract (
+ void *left,
+ void *right
+);
+
+/*
+ * _Addresses_Is_aligned
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the given address is correctly
+ * aligned for this processor and FALSE otherwise. Proper alignment
+ * is based on correctness and efficiency.
+ */
+
+STATIC INLINE boolean _Addresses_Is_aligned (
+ void *address
+);
+
+/*
+ * _Addresses_Is_in_range
+ *
+ * DESCRIPTION:
+ *
+ * This function returns TRUE if the given address is within the
+ * memory range specified and FALSE otherwise. base is the address
+ * of the first byte in the memory range and limit is the address
+ * of the last byte in the memory range. The base address is
+ * assumed to be lower than the limit address.
+ */
+
+STATIC INLINE boolean _Addresses_Is_in_range (
+ void *address,
+ void *base,
+ void *limit
+);
+
+#include "address.inl"
+
+#endif
+/* end of include file */
diff --git a/doc/tools/bmenu/address.inl b/doc/tools/bmenu/address.inl
new file mode 100644
index 0000000000..8b7489c257
--- /dev/null
+++ b/doc/tools/bmenu/address.inl
@@ -0,0 +1,107 @@
+/* inline/address.inl
+ *
+ * This include file contains the bodies of the routines
+ * about addresses which are inlined.
+ *
+ * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ * On-Line Applications Research Corporation (OAR).
+ * All rights assigned to U.S. Government, 1994.
+ *
+ * This material may be reproduced by or for the U.S. Government pursuant
+ * to the copyright license under the clause at DFARS 252.227-7013. This
+ * notice must appear in all copies of this file and its derivatives.
+ */
+
+#ifndef __INLINE_ADDRESSES_inl
+#define __INLINE_ADDRESSES_inl
+
+/*PAGE
+ *
+ * _Addresses_Add_offset
+ *
+ */
+
+STATIC INLINE void *_Addresses_Add_offset (
+ void *base,
+ unsigned32 offset
+)
+{
+ return (base + offset);
+}
+
+/*PAGE
+ *
+ * _Addresses_Subtract_offset
+ *
+ */
+
+STATIC INLINE void *_Addresses_Subtract_offset (
+ void *base,
+ unsigned32 offset
+)
+{
+ return (base - offset);
+}
+
+/*PAGE
+ *
+ * _Addresses_Add
+ *
+ * NOTE: The cast of an address to an unsigned32 makes this code
+ * dependent on an addresses being thirty two bits.
+ */
+
+STATIC INLINE void *_Addresses_Add (
+ void *left,
+ void *right
+)
+{
+ return (left + (unsigned32)right);
+}
+
+/*PAGE
+ *
+ * _Addresses_Subtract
+ *
+ * NOTE: The cast of an address to an unsigned32 makes this code
+ * dependent on an addresses being thirty two bits.
+ */
+
+STATIC INLINE unsigned32 _Addresses_Subtract (
+ void *left,
+ void *right
+)
+{
+ return (left - right);
+}
+
+/*PAGE
+ *
+ * _Addresses_Is_aligned
+ *
+ */
+
+STATIC INLINE boolean _Addresses_Is_aligned (
+ void *address
+)
+{
+ return ( ( (unsigned32)address % 4 ) == 0 );
+}
+
+/*PAGE
+ *
+ * _Addresses_Is_aligned
+ *
+ */
+
+STATIC INLINE boolean _Addresses_Is_in_range (
+ void *address,
+ void *base,
+ void *limit
+)
+{
+ return ( address >= base && address <= limit );
+}
+
+#endif
+/* end of include file */
diff --git a/doc/tools/bmenu/base.h b/doc/tools/bmenu/base.h
new file mode 100644
index 0000000000..2e60938aa9
--- /dev/null
+++ b/doc/tools/bmenu/base.h
@@ -0,0 +1,106 @@
+
+#ifndef __PDL2AMI_h
+#define __PDL2AMI_h
+
+#include "system.h"
+#include "chain.h"
+
+#ifndef EXTERN
+#define EXTERN extern
+#endif
+
+/*
+ * Paragraph size should be kept down because it is allocated for each
+ * Line_Control. If this number is large, the memory requirements for
+ * the program increase significantly.
+ */
+
+#define BUFFER_SIZE (2 * 1024)
+#define PARAGRAPH_SIZE (2 * 1024)
+
+#define NUMBER_ELEMENTS( _x ) (sizeof(_x) / sizeof _x[0])
+
+void exit_application(
+ int status
+);
+
+void ProcessFile(
+ char *inname,
+ char *outname
+);
+
+void strtolower(
+ char *dest,
+ char *src
+);
+
+void strtoInitialCaps(
+ char *dest,
+ char *src
+);
+
+void StripBlanks( void );
+
+void MergeParagraphs( void );
+
+int CheckForIncomplete( void );
+
+int CheckOutline( void );
+
+int CheckSections( void );
+
+void GenerateLists( void );
+
+void GenerateAList(
+ char *section,
+ Chain_Control *the_list
+);
+
+void LookForInternalInconsistencies( void );
+
+int Match_Argument(
+ char **array,
+ int entries,
+ char *users
+);
+
+void usage( void );
+
+void ReadFileIntoChain(
+ char *inname
+);
+
+int MergeText( void );
+
+int CheckForBadWhiteSpace();
+
+void RemoveCopyright();
+
+void RemovePagebreaks();
+
+int RemoveExtraBlankLines();
+
+void FormatToTexinfo( void );
+
+void PrintFile(
+ char *out
+);
+
+void DumpList(
+ Chain_Control *the_list
+);
+
+void ReleaseFile();
+
+EXTERN boolean Verbose; /* status/debug msgs */
+EXTERN boolean BlankAsWarnings;
+EXTERN Chain_Control Lines;
+
+EXTERN int NumberOfAttributes;
+EXTERN int NumberOfAssociations;
+EXTERN int NumberOfAbstractTypes;
+EXTERN int NumberOfDataItems;
+EXTERN int NumberOfMethods;
+EXTERN int NumberOfTasks;
+
+#endif
diff --git a/doc/tools/bmenu/bmenu b/doc/tools/bmenu/bmenu
new file mode 100644
index 0000000000..91796a8862
--- /dev/null
+++ b/doc/tools/bmenu/bmenu
Binary files differ
diff --git a/doc/tools/bmenu/chain.c b/doc/tools/bmenu/chain.c
new file mode 100644
index 0000000000..5ea2e0c51a
--- /dev/null
+++ b/doc/tools/bmenu/chain.c
@@ -0,0 +1,232 @@
+/*
+ * Chain Handler
+ *
+ *
+ * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ * On-Line Applications Research Corporation (OAR).
+ * All rights assigned to U.S. Government, 1994.
+ *
+ * This material may be reproduced by or for the U.S. Government pursuant
+ * to the copyright license under the clause at DFARS 252.227-7013. This
+ * notice must appear in all copies of this file and its derivatives.
+ */
+
+#include "system.h"
+#include "address.h"
+#include "chain.h"
+#include "isr.h"
+
+/*PAGE
+ *
+ * _Chain_Initialize
+ *
+ * This kernel routine initializes a doubly linked chain.
+ *
+ * Input parameters:
+ * the_chain - pointer to chain header
+ * starting_address - starting address of first node
+ * number_nodes - number of nodes in chain
+ * node_size - size of node in bytes
+ *
+ * Output parameters: NONE
+ */
+
+void _Chain_Initialize(
+ Chain_Control *the_chain,
+ void *starting_address,
+ unsigned32 number_nodes,
+ unsigned32 node_size
+)
+{
+ unsigned32 count;
+ Chain_Node *current;
+ Chain_Node *next;
+
+ count = number_nodes;
+ current = _Chain_Head( the_chain );
+ the_chain->permanent_null = NULL;
+ next = (Chain_Node *)starting_address;
+ while ( count-- ) {
+ current->next = next;
+ next->previous = current;
+ current = next;
+ next = (Chain_Node *)
+ _Addresses_Add_offset( (void *) next, node_size );
+ }
+ current->next = _Chain_Tail( the_chain );
+ the_chain->last = current;
+}
+
+/*PAGE
+ *
+ * _Chain_Get_first_unprotected
+ */
+
+#ifndef USE_INLINES
+STATIC INLINE Chain_Node *_Chain_Get_first_unprotected(
+ Chain_Control *the_chain
+)
+{
+ Chain_Node *return_node;
+ Chain_Node *new_first;
+
+ return_node = the_chain->first;
+ new_first = return_node->next;
+ the_chain->first = new_first;
+ new_first->previous = _Chain_Head( the_chain );
+
+ return return_node;
+}
+#endif /* USE_INLINES */
+
+/*PAGE
+ *
+ * _Chain_Get
+ *
+ * This kernel routine returns a pointer to a node taken from the
+ * given chain.
+ *
+ * Input parameters:
+ * the_chain - pointer to chain header
+ *
+ * Output parameters:
+ * return_node - pointer to node in chain allocated
+ * CHAIN_END - if no nodes available
+ *
+ * INTERRUPT LATENCY:
+ * only case
+ */
+
+Chain_Node *_Chain_Get(
+ Chain_Control *the_chain
+)
+{
+ ISR_Level level;
+ Chain_Node *return_node;
+
+ return_node = NULL;
+ _ISR_Disable( level );
+ if ( !_Chain_Is_empty( the_chain ) )
+ return_node = _Chain_Get_first_unprotected( the_chain );
+ _ISR_Enable( level );
+ return return_node;
+}
+
+/*PAGE
+ *
+ * _Chain_Append
+ *
+ * This kernel routine puts a node on the end of the specified chain.
+ *
+ * Input parameters:
+ * the_chain - pointer to chain header
+ * node - address of node to put at rear of chain
+ *
+ * Output parameters: NONE
+ *
+ * INTERRUPT LATENCY:
+ * only case
+ */
+
+void _Chain_Append(
+ Chain_Control *the_chain,
+ Chain_Node *node
+)
+{
+ ISR_Level level;
+
+ _ISR_Disable( level );
+ _Chain_Append_unprotected( the_chain, node );
+ _ISR_Enable( level );
+}
+
+/*PAGE
+ *
+ * _Chain_Extract
+ *
+ * This kernel routine deletes the given node from a chain.
+ *
+ * Input parameters:
+ * node - pointer to node in chain to be deleted
+ *
+ * Output parameters: NONE
+ *
+ * INTERRUPT LATENCY:
+ * only case
+ */
+
+void _Chain_Extract(
+ Chain_Node *node
+)
+{
+ ISR_Level level;
+
+ _ISR_Disable( level );
+ _Chain_Extract_unprotected( node );
+ _ISR_Enable( level );
+}
+
+/*PAGE
+ *
+ * _Chain_Insert
+ *
+ * This kernel routine inserts a given node after a specified node
+ * a requested chain.
+ *
+ * Input parameters:
+ * after_node - pointer to node in chain to be inserted after
+ * node - pointer to node to be inserted
+ *
+ * Output parameters: NONE
+ *
+ * INTERRUPT LATENCY:
+ * only case
+ */
+
+void _Chain_Insert(
+ Chain_Node *after_node,
+ Chain_Node *node
+)
+{
+ ISR_Level level;
+
+ _ISR_Disable( level );
+ _Chain_Insert_unprotected( after_node, node );
+ _ISR_Enable( level );
+}
+
+/*PAGE
+ *
+ * _Chain_Insert_chain
+ *
+ * This routine inserts a chain after the specified node in another
+ * chain. It is assumed that the insert after node is not on the
+ * second chain.
+ *
+ * Input parameters:
+ * insert_after - insert the chain after this node
+ * to_insert - the chain to insert
+ */
+
+void _Chain_Insert_chain(
+ Chain_Node *insert_after,
+ Chain_Control *to_insert
+)
+{
+ Chain_Node *first;
+ Chain_Node *last;
+ Chain_Node *insert_after_next;
+
+ first = to_insert->first;
+ last = to_insert->last;
+
+ insert_after_next = insert_after->next;
+
+ insert_after->next = first;
+ first->previous = insert_after;
+
+ insert_after_next->previous = last;
+ last->next = insert_after_next;
+
+ _Chain_Initialize_empty( to_insert );
+}
diff --git a/doc/tools/bmenu/chain.h b/doc/tools/bmenu/chain.h
new file mode 100644
index 0000000000..ba5d54e998
--- /dev/null
+++ b/doc/tools/bmenu/chain.h
@@ -0,0 +1,349 @@
+/* chain.h
+ *
+ * This include file contains all the constants and structures associated
+ * with the Doubly Linked Chain Handler.
+ *
+ * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ * On-Line Applications Research Corporation (OAR).
+ * All rights assigned to U.S. Government, 1994.
+ *
+ * This material may be reproduced by or for the U.S. Government pursuant
+ * to the copyright license under the clause at DFARS 252.227-7013. This
+ * notice must appear in all copies of this file and its derivatives.
+ */
+
+#ifndef __CHAIN_h
+#define __CHAIN_h
+
+#include "address.h"
+
+/*
+ * This is used to manage each element (node) which is placed
+ * on a chain.
+ *
+ * NOTE: Typically, a more complicated structure will use the
+ * chain package. The more complicated structure will
+ * include a chain node as the first element in its
+ * control structure. It will then call the chain package
+ * with a pointer to that node element. The node pointer
+ * and the higher level structure start at the same address
+ * so the user can cast the pointers back and forth.
+ */
+
+typedef struct Chain_Node_struct Chain_Node;
+
+struct Chain_Node_struct {
+ Chain_Node *next;
+ Chain_Node *previous;
+};
+
+/*
+ * This is used to manage a chain. A chain consists of a doubly
+ * linked list of zero or more nodes.
+ *
+ * NOTE: This implementation does not require special checks for
+ * manipulating the first and last elements on the chain.
+ * To accomplish this the chain control structure is
+ * treated as two overlapping chain nodes. The permanent
+ * head of the chain overlays a node structure on the
+ * first and permanent_null fields. The permanent tail
+ * of the chain overlays a node structure on the
+ * permanent_null and last elements of the structure.
+ */
+
+typedef struct {
+ Chain_Node *first;
+ Chain_Node *permanent_null;
+ Chain_Node *last;
+} Chain_Control;
+
+/*
+ * _Chain_Initialize
+ *
+ * This routine initializes the_chain structure to manage the
+ * contiguous array of number_nodes nodes which starts at
+ * starting_address. Each node is of node_size bytes.
+ */
+
+void _Chain_Initialize(
+ Chain_Control *the_chain,
+ void *starting_address,
+ unsigned32 number_nodes,
+ unsigned32 node_size
+);
+
+/*
+ * _Chain_Initialize_empty
+ *
+ * This routine initializes the specified chain to contain zero nodes.
+ */
+
+STATIC INLINE void _Chain_Initialize_empty(
+ Chain_Control *the_chain
+);
+
+/*
+ * _Chain_Extract_unprotected
+ *
+ * This routine extracts the_node from the chain on which it resides.
+ * It does NOT disable interrupts to insure the atomicity of the
+ * extract operation.
+ */
+
+STATIC INLINE void _Chain_Extract_unprotected(
+ Chain_Node *the_node
+);
+
+/*
+ * _Chain_Extract
+ *
+ * This routine extracts the_node from the chain on which it resides.
+ * It disables interrupts to insure the atomicity of the
+ * extract operation.
+ */
+
+void _Chain_Extract(
+ Chain_Node *the_node
+);
+
+/*
+ * _Chain_Get_unprotected
+ *
+ * This function removes the first node from the_chain and returns
+ * a pointer to that node. If the_chain is empty, then NULL is returned.
+ * It does NOT disable interrupts to insure the atomicity of the
+ * get operation.
+ */
+
+STATIC INLINE Chain_Node *_Chain_Get_unprotected(
+ Chain_Control *the_chain
+);
+
+/*
+ * _Chain_Get
+ *
+ * This function removes the first node from the_chain and returns
+ * a pointer to that node. If the_chain is empty, then NULL is returned.
+ * It disables interrupts to insure the atomicity of the
+ * get operation.
+ */
+
+Chain_Node *_Chain_Get(
+ Chain_Control *the_chain
+);
+
+/*
+ * _Chain_Get_first_unprotected
+ *
+ * This function removes the first node from the_chain and returns
+ * a pointer to that node. It does NOT disable interrupts to insure
+ * the atomicity of the get operation.
+ */
+
+STATIC INLINE Chain_Node *_Chain_Get_first_unprotected(
+ Chain_Control *the_chain
+);
+
+/*
+ * _Chain_Insert_unprotected
+ *
+ * This routine inserts the_node on a chain immediately following
+ * after_node. It does NOT disable interrupts to insure the atomicity
+ * of the extract operation.
+ */
+
+STATIC INLINE void _Chain_Insert_unprotected(
+ Chain_Node *after_node,
+ Chain_Node *the_node
+);
+
+/*
+ * _Chain_Insert
+ *
+ * This routine inserts the_node on a chain immediately following
+ * after_node. It disables interrupts to insure the atomicity
+ * of the extract operation.
+ */
+
+void _Chain_Insert(
+ Chain_Node *after_node,
+ Chain_Node *the_node
+);
+
+/*
+ * _Chain_Append_unprotected
+ *
+ * This routine appends the_node onto the end of the_chain.
+ * It does NOT disable interrupts to insure the atomicity of the
+ * append operation.
+ */
+
+STATIC INLINE void _Chain_Append_unprotected(
+ Chain_Control *the_chain,
+ Chain_Node *the_node
+);
+
+/*
+ * _Chain_Append
+ *
+ * This routine appends the_node onto the end of the_chain.
+ * It disables interrupts to insure the atomicity of the
+ * append operation.
+ */
+
+void _Chain_Append(
+ Chain_Control *the_chain,
+ Chain_Node *the_node
+);
+
+/*
+ * _Chain_Prepend_unprotected
+ *
+ * This routine prepends the_node onto the front of the_chain.
+ * It does NOT disable interrupts to insure the atomicity of the
+ * prepend operation.
+ */
+
+STATIC INLINE void _Chain_Prepend_unprotected(
+ Chain_Control *the_chain,
+ Chain_Node *the_node
+);
+
+/*
+ * _Chain_Prepend
+ *
+ * This routine prepends the_node onto the front of the_chain.
+ * It disables interrupts to insure the atomicity of the
+ * prepend operation.
+ */
+
+STATIC INLINE void _Chain_Prepend(
+ Chain_Control *the_chain,
+ Chain_Node *the_node
+);
+
+/*
+ * _Chain_Insert_chain
+ *
+ * This routine inserts a chain after the specified node in another
+ * chain. It is assumed that the insert after node is not on the
+ * second chain.
+ */
+
+void _Chain_Insert_chain(
+ Chain_Node *insert_after,
+ Chain_Control *to_insert
+);
+
+/*
+ * _Chain_Head
+ *
+ * This function returns a pointer to the first node on the chain.
+ */
+
+STATIC INLINE Chain_Node *_Chain_Head(
+ Chain_Control *the_chain
+);
+
+/*
+ * _Chain_Tail
+ *
+ * This function returns a pointer to the last node on the chain.
+ */
+
+STATIC INLINE Chain_Node *_Chain_Tail(
+ Chain_Control *the_chain
+);
+
+/*
+ * _Chain_Is_head
+ *
+ * This function returns TRUE if the_node is the head of the_chain and
+ * FALSE otherwise.
+ */
+
+STATIC INLINE boolean _Chain_Is_head(
+ Chain_Control *the_chain,
+ Chain_Node *the_node
+);
+
+/*
+ * _Chain_Is_tail
+ *
+ * This function returns TRUE if the_node is the tail of the_chain and
+ * FALSE otherwise.
+ */
+
+STATIC INLINE boolean _Chain_Is_tail(
+ Chain_Control *the_chain,
+ Chain_Node *the_node
+);
+
+/*
+ * _Chain_Is_first
+ *
+ * This function returns TRUE if the_node is the first node on a chain and
+ * FALSE otherwise.
+ */
+
+STATIC INLINE boolean _Chain_Is_first(
+ Chain_Node *the_node
+);
+
+/*
+ * _Chain_Is_last
+ *
+ * This function returns TRUE if the_node is the last node on a chain and
+ * FALSE otherwise.
+ */
+
+STATIC INLINE boolean _Chain_Is_last(
+ Chain_Node *the_node
+);
+
+/*
+ * _Chain_Is_empty
+ *
+ * This function returns TRUE if there a no nodes on the_chain and
+ * FALSE otherwise.
+ */
+
+STATIC INLINE boolean _Chain_Is_empty(
+ Chain_Control *the_chain
+);
+
+/*
+ * _Chain_Has_only_one_node
+ *
+ * This function returns TRUE if there is only one node on the_chain and
+ * FALSE otherwise.
+ */
+
+STATIC INLINE boolean _Chain_Has_only_one_node(
+ Chain_Control *the_chain
+);
+
+/*
+ * _Chain_Is_null
+ *
+ * This function returns TRUE if the_chain is NULL and FALSE otherwise.
+ */
+
+STATIC INLINE boolean _Chain_Is_null(
+ Chain_Control *the_chain
+);
+
+/*
+ * _Chain_Is_null_node
+ *
+ * This function returns TRUE if the_node is NULL and FALSE otherwise.
+ */
+
+STATIC INLINE boolean _Chain_Is_null_node(
+ Chain_Node *the_node
+);
+
+#include "chain.inl"
+
+#endif
+/* end of include file */
diff --git a/doc/tools/bmenu/chain.inl b/doc/tools/bmenu/chain.inl
new file mode 100644
index 0000000000..a1f7149732
--- /dev/null
+++ b/doc/tools/bmenu/chain.inl
@@ -0,0 +1,273 @@
+/* inline/chain.inl
+ *
+ * This include file contains the bodies of the routines which are
+ * associated with doubly linked chains and inlined.
+ *
+ * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ * On-Line Applications Research Corporation (OAR).
+ * All rights assigned to U.S. Government, 1994.
+ *
+ * This material may be reproduced by or for the U.S. Government pursuant
+ * to the copyright license under the clause at DFARS 252.227-7013. This
+ * notice must appear in all copies of this file and its derivatives.
+ */
+
+#ifndef __INLINE_CHAIN_inl
+#define __INLINE_CHAIN_inl
+
+/*PAGE
+ *
+ * _Chain_Is_null
+ */
+
+STATIC INLINE boolean _Chain_Is_null(
+ Chain_Control *the_chain
+)
+{
+ return ( the_chain == NULL );
+}
+
+/*PAGE
+ *
+ * _Chain_Is_null_node
+ */
+
+STATIC INLINE boolean _Chain_Is_null_node(
+ Chain_Node *the_node
+)
+{
+ return ( the_node == NULL );
+}
+
+/*PAGE
+ *
+ * _Chain_Head
+ */
+
+STATIC INLINE Chain_Node *_Chain_Head(
+ Chain_Control *the_chain
+)
+{
+ return (Chain_Node *) the_chain;
+}
+
+/*PAGE
+ *
+ * _Chain_Tail
+ */
+
+STATIC INLINE Chain_Node *_Chain_Tail(
+ Chain_Control *the_chain
+)
+{
+ return (Chain_Node *) &the_chain->permanent_null;
+}
+
+/*PAGE
+ *
+ * _Chain_Is_empty
+ */
+
+STATIC INLINE boolean _Chain_Is_empty(
+ Chain_Control *the_chain
+)
+{
+ return ( the_chain->first == _Chain_Tail( the_chain ) );
+}
+
+/*PAGE
+ *
+ * _Chain_Is_first
+ */
+
+STATIC INLINE boolean _Chain_Is_first(
+ Chain_Node *the_node
+)
+{
+ return ( the_node->previous == NULL );
+}
+
+/*PAGE
+ *
+ * _Chain_Is_last
+ */
+
+STATIC INLINE boolean _Chain_Is_last(
+ Chain_Node *the_node
+)
+{
+ return ( the_node->next == NULL );
+}
+
+/*PAGE
+ *
+ * _Chain_Has_only_one_node
+ */
+
+STATIC INLINE boolean _Chain_Has_only_one_node(
+ Chain_Control *the_chain
+)
+{
+ return ( the_chain->first == the_chain->last );
+}
+
+/*PAGE
+ *
+ * _Chain_Is_head
+ */
+
+STATIC INLINE boolean _Chain_Is_head(
+ Chain_Control *the_chain,
+ Chain_Node *the_node
+)
+{
+ return ( the_node == _Chain_Head( the_chain ) );
+}
+
+/*PAGE
+ *
+ * _Chain_Is_tail
+ */
+
+STATIC INLINE boolean _Chain_Is_tail(
+ Chain_Control *the_chain,
+ Chain_Node *the_node
+)
+{
+ return ( the_node == _Chain_Tail( the_chain ) );
+}
+
+/*PAGE
+ *
+ * Chain_Initialize_empty
+ */
+
+STATIC INLINE void _Chain_Initialize_empty(
+ Chain_Control *the_chain
+)
+{
+ the_chain->first = _Chain_Tail( the_chain );
+ the_chain->permanent_null = NULL;
+ the_chain->last = _Chain_Head( the_chain );
+}
+
+/*PAGE
+ *
+ * _Chain_Extract_unprotected
+ */
+
+STATIC INLINE void _Chain_Extract_unprotected(
+ Chain_Node *the_node
+)
+{
+ Chain_Node *next;
+ Chain_Node *previous;
+
+ next = the_node->next;
+ previous = the_node->previous;
+ next->previous = previous;
+ previous->next = next;
+}
+
+/*PAGE
+ *
+ * _Chain_Get_first_unprotected
+ */
+
+STATIC INLINE Chain_Node *_Chain_Get_first_unprotected(
+ Chain_Control *the_chain
+)
+{
+ Chain_Node *return_node;
+ Chain_Node *new_first;
+
+ return_node = the_chain->first;
+ new_first = return_node->next;
+ the_chain->first = new_first;
+ new_first->previous = _Chain_Head( the_chain );
+
+ return return_node;
+}
+
+/*PAGE
+ *
+ * Chain_Get_unprotected
+ */
+
+STATIC INLINE Chain_Node *_Chain_Get_unprotected(
+ Chain_Control *the_chain
+)
+{
+ if ( !_Chain_Is_empty( the_chain ) )
+ return _Chain_Get_first_unprotected( the_chain );
+ else
+ return NULL;
+}
+
+/*PAGE
+ *
+ * _Chain_Insert_unprotected
+ */
+
+STATIC INLINE void _Chain_Insert_unprotected(
+ Chain_Node *after_node,
+ Chain_Node *the_node
+)
+{
+ Chain_Node *before_node;
+
+ the_node->previous = after_node;
+ before_node = after_node->next;
+ after_node->next = the_node;
+ the_node->next = before_node;
+ before_node->previous = the_node;
+}
+
+/*PAGE
+ *
+ * _Chain_Append_unprotected
+ */
+
+STATIC INLINE void _Chain_Append_unprotected(
+ Chain_Control *the_chain,
+ Chain_Node *the_node
+)
+{
+ Chain_Node *old_last_node;
+
+ the_node->next = _Chain_Tail( the_chain );
+ old_last_node = the_chain->last;
+ the_chain->last = the_node;
+ old_last_node->next = the_node;
+ the_node->previous = old_last_node;
+}
+
+/*PAGE
+ *
+ * _Chain_Prepend_unprotected
+ */
+
+STATIC INLINE void _Chain_Prepend_unprotected(
+ Chain_Control *the_chain,
+ Chain_Node *the_node
+)
+{
+ _Chain_Insert_unprotected( _Chain_Head( the_chain ), the_node );
+
+}
+
+/*PAGE
+ *
+ * _Chain_Prepend
+ */
+
+STATIC INLINE void _Chain_Prepend(
+ Chain_Control *the_chain,
+ Chain_Node *the_node
+)
+{
+ _Chain_Insert( _Chain_Head( the_chain ), the_node );
+}
+
+#endif
+/* end of include file */
diff --git a/doc/tools/bmenu/chain.o b/doc/tools/bmenu/chain.o
new file mode 100644
index 0000000000..f26dd12af6
--- /dev/null
+++ b/doc/tools/bmenu/chain.o
Binary files differ
diff --git a/doc/tools/bmenu/isr.h b/doc/tools/bmenu/isr.h
new file mode 100644
index 0000000000..9c8344ca57
--- /dev/null
+++ b/doc/tools/bmenu/isr.h
@@ -0,0 +1,11 @@
+
+
+#ifndef __ISR_h
+#define __ISR_h
+
+typedef unsigned32 ISR_Level;
+
+#define _ISR_Disable
+#define _ISR_Enable
+
+#endif
diff --git a/doc/tools/bmenu/main.c b/doc/tools/bmenu/main.c
new file mode 100644
index 0000000000..1a9a309831
--- /dev/null
+++ b/doc/tools/bmenu/main.c
@@ -0,0 +1,985 @@
+/*
+ * main.c
+ *
+ * This program takes a texinfo file without node and menu commands,
+ * build those commands and inserts them.
+ *
+ * It works by reading the input file into a linked list of lines
+ * and then performing sweeps on that list until all formatting is
+ * complete. After the program is run, there is still a little
+ * clean up to be performed by hand. The following have to be fixed
+ * by hand:
+ * + previous of the first node
+ * + next of the last node
+ */
+
+#include <assert.h>
+#include <ctype.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* XXX -- just for testing -- these should be set by options */
+char DocsNextNode[] = "";
+char DocsPreviousNode[] = "Top";
+char DocsUpNode[] = "Top";
+
+extern int optind; /* Why is this not in <stdlib.h>? */
+extern char *optarg; /* Why is this not in <stdlib.h>? */
+
+#ifndef NAME_MAX
+#define NAME_MAX 14 /* Why is the one in limits.h not showing up? */
+#endif
+#define INIT_DATA
+#define EXTERN
+
+#include "base.h"
+
+FILE *OutFile = stdout;
+
+/*************************************************************************
+ *************************************************************************
+ ***** DATA TYPES AND CONSTANT TABLES *****
+ *************************************************************************
+ *************************************************************************/
+/*
+ * Usage Information
+ */
+
+char *Usage_Strings[] = {
+ "\n",
+ "usage: cmd [-bv] files ...\n",
+ "\n",
+ "EOF"
+};
+
+/*
+ * The page separator is not really a keyword and will be purged before
+ * it is seen elsewhere.
+ */
+
+#define PAGE_SEPARATOR "#PAGE"
+
+/*
+ * Section Delimiter Keywords
+ */
+
+#define MAXIMUM_KEYWORD_LENGTH 32
+
+/*
+ * Level indicates where in the format the delimiter is allowed to occur.
+ * 1 indicates a major section divider (e.g. "ATTRIBUTE DESCRIPTIONS:").
+ * 2 indicates a subsection (e.g. "ATTRIBUTE:").
+ * 3 indicates a heading (e.g. "DESCRIPTION:").
+ */
+
+#define TEXT 0
+#define SECTION 1
+#define SUBSECTION 2
+#define HEADING 3
+
+typedef enum {
+ UNUSED, /* dummy 0 slot */
+ KEYWORD_CHAPTER,
+ KEYWORD_CHAPHEADING,
+ KEYWORD_SECTION,
+ KEYWORD_SUBSECTION,
+ KEYWORD_OTHER,
+ KEYWORD_END
+
+} Keyword_indices_t;
+
+#define KEYWORD_FIRST KEYOWRD_CHAPTER
+#define KEYWORD_LAST KEYWORD_END
+
+/*
+ * Line Management Structure
+ */
+
+typedef enum {
+ NO_EXTRA_FORMATTING_INFO,
+ RAW_OUTPUT,
+ PARAGRAPH_OUTPUT
+} ExtraFormat_info_t;
+
+typedef struct {
+ Chain_Node Node;
+ Keyword_indices_t keyword; /* unused is unknown/undecided */
+ ExtraFormat_info_t format;
+ int number;
+ char Contents[ PARAGRAPH_SIZE ];
+} Line_Control;
+
+typedef enum {
+ RT_FORBIDDEN, /* no text to right allowed */
+ RT_OPTIONAL, /* text to right optional -- none below */
+ RT_NONE, /* text to right is "none" or nothing -- none below */
+ RT_REQUIRED, /* text to right required -- none below */
+ RT_BELOW, /* text to right forbidden -- text below required */
+ RT_NONE_OR_BELOW, /* text to right is "none" OR there is text below */
+ RT_EITHER, /* text to right OR below */
+ RT_BOTH /* text to right AND below */
+} Keywords_text_mode_t;
+
+typedef enum {
+ BL_FORBIDDEN, /* text below forbidden */
+ BL_FORMATTED, /* text below is to be formatted as paragraphs */
+ BL_RAW, /* text below is to be unprocessed by this program */
+} Keywords_text_below_t;
+
+typedef (*Keyword_validater_t)( Line_Control * );
+
+typedef struct {
+ char Name[ MAXIMUM_KEYWORD_LENGTH ];
+ int level;
+ Keywords_text_mode_t text_mode;
+ Keywords_text_below_t text_below_mode;
+ Keyword_validater_t keyword_validation_routine;
+} 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 }
+};
+
+#define NUMBER_OF_KEYWORDS \
+ ( sizeof( Keywords ) / sizeof( Keyword_info_t ) ) - 2
+
+/*
+ * exit_application
+ */
+
+void exit_application(
+ int status
+)
+{
+ fprintf( stderr, "*** Error encountered ***\n" );
+/*
+ fprintf( stderr, "*** Error encountered on line %d ***\n", CurrentLine );
+*/
+ fclose( OutFile );
+ exit( status );
+}
+
+/*************************************************************************
+ *************************************************************************
+ ***** LINE MANIPULATION ROUTINES *****
+ *************************************************************************
+ *************************************************************************/
+
+/*
+ * PrintLine
+ */
+
+void PrintLine(
+ Line_Control *line
+)
+{
+ assert( line );
+
+ if ( line->number == -1 )
+ fprintf( stderr, " " );
+ else
+ fprintf( stderr, "%5d", line->number );
+
+#if 0
+ fprintf( stderr, "%s\n", line->Contents );
+#else
+ /*
+ * Include some debugging information
+ */
+ fprintf(
+ stderr,
+ "<%d,%d>:%s\n",
+ line->keyword,
+ line->format,
+ line->Contents
+ );
+#endif
+}
+
+Chain_Control Line_Pool;
+
+/*
+ * FillLinePool
+ */
+
+void FillLinePool( void )
+{
+ void *pool;
+
+#define LINE_POOL_FILL_COUNT 100
+
+ pool = malloc( sizeof( Line_Control ) * LINE_POOL_FILL_COUNT );
+ assert( pool );
+
+ _Chain_Initialize(
+ &Line_Pool,
+ pool,
+ LINE_POOL_FILL_COUNT,
+ sizeof( Line_Control )
+ );
+}
+
+/*
+ * AllocateLine
+ */
+
+Line_Control *AllocateLine( void )
+{
+ Line_Control *new_line;
+
+ new_line = (Line_Control *) _Chain_Get( &Line_Pool );
+ if ( !new_line ) {
+ FillLinePool();
+ new_line = (Line_Control *) _Chain_Get( &Line_Pool );
+ assert( new_line );
+ }
+
+/*
+ * This is commented out because although it is helpful during debug,
+ * it consumes a significant percentage of the program's execution time.
+
+ memset( new_line->Contents, '\0', sizeof( new_line->Contents ) );
+*/
+ new_line->number = -1;
+
+ new_line->keyword = UNUSED;
+ new_line->format = NO_EXTRA_FORMATTING_INFO;
+
+ new_line->Node.next = NULL;
+ new_line->Node.previous = NULL;
+
+ return new_line;
+}
+
+/*
+ * FreeLine
+ */
+
+void FreeLine(
+ Line_Control *line
+)
+{
+ fflush( stdout );
+ _Chain_Append( &Line_Pool, &line->Node );
+}
+
+/*
+ * DeleteLine
+ */
+
+Line_Control *DeleteLine(
+ Line_Control *line
+)
+{
+ Line_Control *next;
+
+ next = (Line_Control *)line->Node.next;
+ _Chain_Extract( &line->Node );
+ FreeLine( line );
+ return next;
+}
+
+/*
+ * PrintSurroundingLines
+ */
+
+void PrintSurroundingLines(
+ Line_Control *line,
+ int backward,
+ int forward
+)
+{
+ int i;
+ int real_backward;
+ Line_Control *local;
+
+ for ( local=line, real_backward=0, i=1 ;
+ i<=backward ;
+ i++, real_backward++ ) {
+ if ( &local->Node == Lines.first )
+ break;
+ local = (Line_Control *) local->Node.previous;
+ }
+
+ for ( i=1 ; i<=real_backward ; i++ ) {
+ PrintLine( local );
+ local = (Line_Control *) local->Node.next;
+ }
+
+ PrintLine( local );
+
+ for ( i=1 ; i<=forward ; i++ ) {
+ local = (Line_Control *) local->Node.next;
+ if ( _Chain_Is_last( &local->Node ) )
+ break;
+ PrintLine( local );
+ }
+
+}
+
+/*
+ * SetLineFormat
+ */
+
+void SetLineFormat(
+ Line_Control *line,
+ ExtraFormat_info_t format
+)
+{
+ if ( line->format != NO_EXTRA_FORMATTING_INFO ) {
+ fprintf( stderr, "Line %d is already formatted\n", line->number );
+ PrintLine( line );
+ assert( FALSE );
+ }
+
+ line->format = format;
+}
+
+/*
+ * LineCopyFromRight
+ */
+
+void LineCopyFromRight(
+ Line_Control *line,
+ char *dest
+)
+{
+ char *p;
+
+ for ( p=line->Contents ; *p != ' ' ; p++ )
+ ;
+ p++; /* skip the ' ' */
+ for ( ; isspace( *p ) ; p++ )
+ ;
+
+ strcpy( dest, p );
+
+}
+
+/*
+ * LineCopySectionName
+ */
+
+void LineCopySectionName(
+ Line_Control *line,
+ char *dest
+)
+{
+ char *p;
+ char *d;
+
+ p = line->Contents;
+ d = dest;
+
+ if ( *p == '@' ) { /* skip texinfo command */
+ while ( !isspace( *p++ ) )
+ ;
+ }
+
+ for ( ; *p ; )
+ *d++ = *p++;
+
+ *d = '\0';
+}
+
+/*************************************************************************
+ *************************************************************************
+ ***** END OF LINE MANIPULATION ROUTINES *****
+ *************************************************************************
+ *************************************************************************/
+
+/*
+ * main
+ */
+
+int main(
+ int argc,
+ char **argv
+)
+{
+ int c;
+ int index;
+ boolean single_file_mode;
+
+ Verbose = FALSE;
+
+ while ((c = getopt(argc, argv, "bv")) != EOF) {
+ switch (c) {
+ case 'v':
+ Verbose = TRUE;
+ break;
+ case '?':
+ usage();
+ return 0;
+ }
+ }
+
+ if ( Verbose )
+ fprintf( stderr, "Arguments successfully parsed\n" );
+
+ FillLinePool();
+
+ for ( index=optind ; index < argc ; index++ ) {
+ ProcessFile( argv[ index ], NULL );
+ }
+
+ if ( Verbose )
+ fprintf( stderr, "Exitting\n" );
+
+ return 0;
+}
+
+/*
+ * ProcessFile
+ */
+
+void ProcessFile(
+ char *inname,
+ char *outname
+)
+{
+ char out[ 256 ];
+ int index;
+
+ /*
+ * Automatically generate the output file name.
+ */
+
+ if ( outname == NULL ) {
+ for( index=0 ; inname[index] && inname[index] != '.' ; index++ ) {
+ out[ index ] = inname[ index ];
+ }
+
+ out[ index++ ] = '.';
+ out[ index++ ] = 't';
+ out[ index++ ] = 'x';
+ out[ index++ ] = 't';
+ out[ index ] = '\0';
+
+ }
+
+ /*
+ * Read the file into our internal data structure
+ */
+
+ if ( Verbose )
+ printf( "Processing (%s) -> (%s)\n", inname, out );
+
+ ReadFileIntoChain( inname );
+
+ if ( Verbose )
+ fprintf( stderr, "-------->FILE READ IN\n" );
+
+ /*
+ * Remove any spaces before the keyword and mark each keyword line as
+ * such. Also remove extra white space at the end of lines.
+ */
+
+ StripBlanks();
+
+ if ( Verbose )
+ fprintf( stderr, "-------->BLANKS BEFORE KEYWORDS STRIPPED\n" );
+
+
+ FormatToTexinfo();
+
+ if ( Verbose )
+ fprintf( stderr, "-------->FILE FORMATTED TO TEXINFO\n" );
+
+ /*
+ * Print the file
+ */
+
+ PrintFile( out );
+
+ if ( Verbose )
+ fprintf( stderr, "-------->FILE PRINTED\n" );
+
+ /*
+ * Clean Up
+ */
+
+ ReleaseFile();
+
+ if ( Verbose )
+ fprintf( stderr, "-------->FILE RELEASED\n" );
+}
+
+/*
+ * usage
+ */
+
+void usage( void )
+{
+ int index;
+
+ for ( index=0 ; strcmp( Usage_Strings[ index ], "EOF" ) ; index++ )
+ fprintf( stderr, Usage_Strings[ index ] );
+}
+
+/*
+ * ReadFileIntoChain
+ */
+
+void ReadFileIntoChain(
+ char *inname
+)
+{
+ FILE *InFile;
+ int line_count;
+ int max_length;
+ char *line;
+ char Buffer[ BUFFER_SIZE ];
+ Line_Control *new_line;
+
+ InFile = fopen( inname, "r" );
+
+ if ( !InFile ) {
+ fprintf( stderr, "Unable to open (%s)\n", inname );
+ exit( 1 );
+ }
+ assert( InFile );
+
+ max_length = 0;
+ line_count = 0;
+
+ _Chain_Initialize_empty( &Lines );
+
+ for ( ;; ) {
+ line = fgets( Buffer, BUFFER_SIZE, InFile );
+ if ( !line )
+ break;
+
+ Buffer[ strlen( Buffer ) - 1 ] = '\0';
+
+ new_line = AllocateLine();
+
+ strcpy( new_line->Contents, Buffer );
+
+ new_line->number = ++line_count;
+
+ _Chain_Append( &Lines, &new_line->Node );
+ }
+
+ fclose( InFile );
+}
+
+/*
+ * StripBlanks
+ */
+
+void StripBlanks( void )
+{
+ Line_Control *line;
+ Keyword_indices_t index;
+ int indentation;
+ int length;
+
+ for ( line = (Line_Control *) Lines.first ;
+ !_Chain_Is_last( &line->Node ) ;
+ line = (Line_Control *) line->Node.next
+ ) {
+
+ /*
+ * Strip white space from the end of each line
+ */
+
+ length = strlen( line->Contents );
+
+ while ( isspace( line->Contents[ --length ] ) )
+ line->Contents[ length ] = '\0';
+
+ if ( strstr( line->Contents, "@chapter" ) )
+ line->keyword = KEYWORD_CHAPTER;
+ else if ( strstr( line->Contents, "@chapheading" ) )
+ line->keyword = KEYWORD_CHAPHEADING;
+ else if ( strstr( line->Contents, "@section" ) )
+ line->keyword = KEYWORD_SECTION;
+ else if ( strstr( line->Contents, "@subsection" ) )
+ line->keyword = KEYWORD_SUBSECTION;
+ else
+ line->keyword = KEYWORD_OTHER;
+
+ }
+ line = AllocateLine();
+ line->keyword = KEYWORD_END;
+ _Chain_Append( &Lines, &line->Node );
+}
+
+/*
+ * strIsAllSpace
+ */
+
+boolean strIsAllSpace(
+ char *s
+)
+{
+ char *p;
+
+ for ( p = s ; *p ; p++ )
+ if ( !isspace( *p ) )
+ return FALSE;
+
+ return TRUE;
+}
+
+/*
+ * BuildTexinfoNodes
+ */
+
+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;
+
+ strcpy( PreviousNodeName, DocsPreviousNode );
+
+ for ( line = (Line_Control *) Lines.first ;
+ !_Chain_Is_last( &line->Node ) ;
+ line = (Line_Control *) line->Node.next
+ ) {
+
+ menu_insert_point = (Line_Control *) line->Node.next;
+
+ 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 );
+
+ /*
+ * 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).
+ */
+
+ 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 );
+
+ 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;
+ }
+ }
+
+ 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 );
+ }
+#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 );
+ break;
+
+ case SUBSECTION:
+ strcpy( UpNodeName, SectionName );
+
+ LineCopyFromRight( line, NodeName );
+
+ 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;
+ }
+
+#if 0
+ 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 );
+
+ strcpy( PreviousNodeName, NodeName );
+ break;
+ }
+ }
+bottom:
+}
+
+/*
+ * FormatToTexinfo
+ */
+
+void FormatToTexinfo( void )
+{
+ if ( Verbose )
+ fprintf( stderr, "-------->INSERTING TEXINFO MENUS\n" );
+
+ BuildTexinfoNodes();
+}
+
+/*
+ * PrintFile
+ */
+
+void PrintFile(
+ char *out
+)
+{
+ Line_Control *line;
+
+ OutFile = fopen( out, "w+" );
+
+ if ( !OutFile ) {
+ fprintf( stderr, "Unable to open (%s) for output\n", out );
+ exit_application( 1 );
+ }
+ assert( OutFile );
+
+ for ( line = (Line_Control *) Lines.first ;
+ !_Chain_Is_last( &line->Node ) ;
+ line = (Line_Control *) line->Node.next ) {
+ fprintf( OutFile, "%s\n", line->Contents );
+/*
+ fprintf(
+ OutFile,
+ "(%d,%d)%s\n",
+ line->keyword,
+ line->format,
+ line->Contents
+ );
+*/
+ }
+}
+
+/*
+ * DumpList
+ */
+
+void DumpList(
+ Chain_Control *the_list
+)
+{
+ Line_Control *line;
+
+ fprintf( stderr, "---> Dumping list (%p)\n", the_list );
+
+ for ( line = (Line_Control *) the_list->first ;
+ !_Chain_Is_last( &line->Node ) ;
+ line = (Line_Control *) line->Node.next ) {
+ fprintf( stderr, "%s\n", line->Contents );
+ }
+}
+
+/*
+ * ReleaseFile
+ */
+
+void ReleaseFile()
+{
+ Line_Control *line;
+ Line_Control *next;
+
+ for ( line = (Line_Control *) Lines.first ;
+ !_Chain_Is_last( &line->Node ) ;
+ ) {
+ next = (Line_Control *) line->Node.next;
+ line = next;
+ }
+}
+
+/*
+ * strtoInitialCaps
+ */
+
+void strtoInitialCaps(
+ char *dest,
+ char *src
+)
+{
+ char *source = src;
+ char *destination = dest;
+
+ source = src;
+ destination = (dest) ? dest : src;
+
+ while ( *source ) {
+ while ( isspace( *source ) )
+ *destination++ = *source++;
+
+ if ( !*source )
+ break;
+
+ *destination++ = toupper( *source++ );
+
+ for ( ; *source && !isspace( *source ) ; source++ )
+ *destination++ = tolower( *source );
+
+ if ( !*source )
+ break;
+ }
+
+ *destination = '\0';
+}
diff --git a/doc/tools/bmenu/main.o b/doc/tools/bmenu/main.o
new file mode 100644
index 0000000000..e4b1fa7579
--- /dev/null
+++ b/doc/tools/bmenu/main.o
Binary files differ
diff --git a/doc/tools/bmenu/system.h b/doc/tools/bmenu/system.h
new file mode 100644
index 0000000000..21e163a35e
--- /dev/null
+++ b/doc/tools/bmenu/system.h
@@ -0,0 +1,29 @@
+
+#ifndef __SYSTEM_h
+#define __SYSTEM_h
+
+typedef unsigned int unsigned32;
+typedef unsigned short unsigned16;
+typedef unsigned char unsigned8;
+
+#define USE_INLINES
+#define STATIC static
+#define INLINE inline
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+typedef unsigned int boolean;
+
+#if !defined( TRUE ) || (TRUE != 1)
+#undef TRUE
+#define TRUE (1)
+#endif
+
+#if !defined( FALSE ) || (FALSE != 0)
+#undef FALSE
+#define FALSE 0
+#endif
+
+#endif