/*
|
/*
|
* main.c
|
* main.c
|
*
|
*
|
* This program takes a texinfo file without node and menu commands,
|
* This program takes a texinfo file without node and menu commands,
|
* build those commands and inserts them.
|
* build those commands and inserts them.
|
*
|
*
|
* It works by reading the input file into a linked list of lines
|
* It works by reading the input file into a linked list of lines
|
* and then performing sweeps on that list until all formatting is
|
* and then performing sweeps on that list until all formatting is
|
* complete. After the program is run, there is still a little
|
* complete. After the program is run, there is still a little
|
* clean up to be performed by hand. The following have to be fixed
|
* clean up to be performed by hand. The following have to be fixed
|
* by hand:
|
* by hand:
|
* + previous of the first node
|
* + previous of the first node
|
* + next of the last node
|
* + next of the last node
|
*
|
*
|
* COPYRIGHT (c) 1988-2002.
|
* COPYRIGHT (c) 1988-2002.
|
* On-Line Applications Research Corporation (OAR).
|
* On-Line Applications Research Corporation (OAR).
|
* All rights reserved.
|
* All rights reserved.
|
*
|
*
|
* bmenu2.c,v 1.2 2002/01/17 21:47:47 joel Exp
|
* bmenu2.c,v 1.2 2002/01/17 21:47:47 joel Exp
|
*/
|
*/
|
|
|
#include <assert.h>
|
#include <assert.h>
|
#include <ctype.h>
|
#include <ctype.h>
|
#include <limits.h>
|
#include <limits.h>
|
#include <stdio.h>
|
#include <stdio.h>
|
#include <stdlib.h>
|
#include <stdlib.h>
|
#include <string.h>
|
#include <string.h>
|
|
|
/* XXX -- just for testing -- these should be set by options */
|
/* XXX -- just for testing -- these should be set by options */
|
char TopString[] = "Top";
|
char TopString[] = "Top";
|
char EmptyString[] = "";
|
char EmptyString[] = "";
|
|
|
char *DocsNextNode;
|
char *DocsNextNode;
|
char *DocsPreviousNode;
|
char *DocsPreviousNode;
|
char *DocsUpNode;
|
char *DocsUpNode;
|
int NodeNameIncludesChapter = 1;
|
int NodeNameIncludesChapter = 1;
|
|
|
extern int optind; /* Why is this not in <stdlib.h>? */
|
extern int optind; /* Why is this not in <stdlib.h>? */
|
extern char *optarg; /* Why is this not in <stdlib.h>? */
|
extern char *optarg; /* Why is this not in <stdlib.h>? */
|
|
|
#ifndef NAME_MAX
|
#ifndef NAME_MAX
|
#define NAME_MAX 14 /* Why is the one in limits.h not showing up? */
|
#define NAME_MAX 14 /* Why is the one in limits.h not showing up? */
|
#endif
|
#endif
|
#define INIT_DATA
|
#define INIT_DATA
|
#define EXTERN
|
#define EXTERN
|
|
|
#include "base.h"
|
#include "base.h"
|
|
|
FILE *OutFile;
|
FILE *OutFile;
|
|
|
static void ProcessFile2(
|
static void ProcessFile2(
|
FILE *infile,
|
FILE *infile,
|
FILE *outfile );
|
FILE *outfile );
|
static void PrintFile2(
|
static void PrintFile2(
|
FILE *outfile );
|
FILE *outfile );
|
static void ReadFileIntoChain2(
|
static void ReadFileIntoChain2(
|
FILE *InFile );
|
FILE *InFile );
|
|
|
/*************************************************************************
|
/*************************************************************************
|
*************************************************************************
|
*************************************************************************
|
***** DATA TYPES AND CONSTANT TABLES *****
|
***** DATA TYPES AND CONSTANT TABLES *****
|
*************************************************************************
|
*************************************************************************
|
*************************************************************************/
|
*************************************************************************/
|
/*
|
/*
|
* Usage Information
|
* Usage Information
|
*/
|
*/
|
|
|
char *Usage_Strings[] = {
|
char *Usage_Strings[] = {
|
"\n",
|
"\n",
|
"usage: cmd [-cv] [-p prev] [-n next] [-u up] \n",
|
"usage: cmd [-cv] [-p prev] [-n next] [-u up] \n",
|
"\n",
|
"\n",
|
"EOF"
|
"EOF"
|
};
|
};
|
|
|
/*
|
/*
|
* The page separator is not really a keyword and will be purged before
|
* The page separator is not really a keyword and will be purged before
|
* it is seen elsewhere.
|
* it is seen elsewhere.
|
*/
|
*/
|
|
|
#define PAGE_SEPARATOR "#PAGE"
|
#define PAGE_SEPARATOR "#PAGE"
|
|
|
/*
|
/*
|
* Section Delimiter Keywords
|
* Section Delimiter Keywords
|
*/
|
*/
|
|
|
#define MAXIMUM_KEYWORD_LENGTH 32
|
#define MAXIMUM_KEYWORD_LENGTH 32
|
|
|
/*
|
/*
|
* Level indicates where in the format the delimiter is allowed to occur.
|
* Level indicates where in the format the delimiter is allowed to occur.
|
* 1 indicates a major section divider (e.g. "ATTRIBUTE DESCRIPTIONS:").
|
* 1 indicates a major section divider (e.g. "ATTRIBUTE DESCRIPTIONS:").
|
* 2 indicates a subsection (e.g. "ATTRIBUTE:").
|
* 2 indicates a subsection (e.g. "ATTRIBUTE:").
|
* 3 indicates a heading (e.g. "DESCRIPTION:").
|
* 3 indicates a heading (e.g. "DESCRIPTION:").
|
*/
|
*/
|
|
|
#define TEXT 0
|
#define TEXT 0
|
#define SECTION 1
|
#define SECTION 1
|
#define SUBSECTION 2
|
#define SUBSECTION 2
|
#define SUBSUBSECTION 3
|
#define SUBSUBSECTION 3
|
#define HEADING 4
|
#define HEADING 4
|
|
|
typedef enum {
|
typedef enum {
|
UNUSED, /* dummy 0 slot */
|
UNUSED, /* dummy 0 slot */
|
KEYWORD_CHAPTER,
|
KEYWORD_CHAPTER,
|
KEYWORD_APPENDIX,
|
KEYWORD_APPENDIX,
|
KEYWORD_PREFACE,
|
KEYWORD_PREFACE,
|
KEYWORD_CHAPHEADING,
|
KEYWORD_CHAPHEADING,
|
KEYWORD_SECTION,
|
KEYWORD_SECTION,
|
KEYWORD_SUBSECTION,
|
KEYWORD_SUBSECTION,
|
KEYWORD_SUBSUBSECTION,
|
KEYWORD_SUBSUBSECTION,
|
KEYWORD_RAISE,
|
KEYWORD_RAISE,
|
KEYWORD_LOWER,
|
KEYWORD_LOWER,
|
KEYWORD_OTHER,
|
KEYWORD_OTHER,
|
KEYWORD_END
|
KEYWORD_END
|
|
|
} Keyword_indices_t;
|
} Keyword_indices_t;
|
|
|
#define KEYWORD_FIRST KEYOWRD_CHAPTER
|
#define KEYWORD_FIRST KEYOWRD_CHAPTER
|
#define KEYWORD_LAST KEYWORD_END
|
#define KEYWORD_LAST KEYWORD_END
|
|
|
/*
|
/*
|
* Line Management Structure
|
* Line Management Structure
|
*/
|
*/
|
|
|
typedef enum {
|
typedef enum {
|
NO_EXTRA_FORMATTING_INFO,
|
NO_EXTRA_FORMATTING_INFO,
|
RAW_OUTPUT,
|
RAW_OUTPUT,
|
PARAGRAPH_OUTPUT
|
PARAGRAPH_OUTPUT
|
} ExtraFormat_info_t;
|
} ExtraFormat_info_t;
|
|
|
typedef struct {
|
typedef struct {
|
Chain_Node Node;
|
Chain_Node Node;
|
Keyword_indices_t keyword; /* unused is unknown/undecided */
|
Keyword_indices_t keyword; /* unused is unknown/undecided */
|
ExtraFormat_info_t format;
|
ExtraFormat_info_t format;
|
int number;
|
int number;
|
int level;
|
int level;
|
char Contents[ PARAGRAPH_SIZE ];
|
char Contents[ PARAGRAPH_SIZE ];
|
} Line_Control;
|
} Line_Control;
|
|
|
typedef enum {
|
typedef enum {
|
RT_FORBIDDEN, /* no text to right allowed */
|
RT_FORBIDDEN, /* no text to right allowed */
|
RT_OPTIONAL, /* text to right optional -- none below */
|
RT_OPTIONAL, /* text to right optional -- none below */
|
RT_NONE, /* text to right is "none" or nothing -- none below */
|
RT_NONE, /* text to right is "none" or nothing -- none below */
|
RT_REQUIRED, /* text to right required -- none below */
|
RT_REQUIRED, /* text to right required -- none below */
|
RT_BELOW, /* text to right forbidden -- text below required */
|
RT_BELOW, /* text to right forbidden -- text below required */
|
RT_NONE_OR_BELOW, /* text to right is "none" OR there is text below */
|
RT_NONE_OR_BELOW, /* text to right is "none" OR there is text below */
|
RT_EITHER, /* text to right OR below */
|
RT_EITHER, /* text to right OR below */
|
RT_BOTH /* text to right AND below */
|
RT_BOTH /* text to right AND below */
|
} Keywords_text_mode_t;
|
} Keywords_text_mode_t;
|
|
|
typedef enum {
|
typedef enum {
|
BL_FORBIDDEN, /* text below forbidden */
|
BL_FORBIDDEN, /* text below forbidden */
|
BL_FORMATTED, /* text below is to be formatted as paragraphs */
|
BL_FORMATTED, /* text below is to be formatted as paragraphs */
|
BL_RAW, /* text below is to be unprocessed by this program */
|
BL_RAW, /* text below is to be unprocessed by this program */
|
} Keywords_text_below_t;
|
} Keywords_text_below_t;
|
|
|
typedef (*Keyword_validater_t)( Line_Control * );
|
typedef (*Keyword_validater_t)( Line_Control * );
|
|
|
typedef struct {
|
typedef struct {
|
char Name[ MAXIMUM_KEYWORD_LENGTH ];
|
char Name[ MAXIMUM_KEYWORD_LENGTH ];
|
int level;
|
int level;
|
Keywords_text_mode_t text_mode;
|
Keywords_text_mode_t text_mode;
|
Keywords_text_below_t text_below_mode;
|
Keywords_text_below_t text_below_mode;
|
Keyword_validater_t keyword_validation_routine;
|
Keyword_validater_t keyword_validation_routine;
|
} Keyword_info_t;
|
} Keyword_info_t;
|
|
|
Keyword_info_t Keywords[] = {
|
Keyword_info_t Keywords[] = {
|
{ "unused", 0, 0, 0, NULL }, /* so 0 can be invalid */
|
{ "unused", 0, 0, 0, NULL }, /* so 0 can be invalid */
|
{ "@chapter", SECTION, RT_FORBIDDEN, BL_FORBIDDEN, NULL },
|
{ "@chapter", SECTION, RT_FORBIDDEN, BL_FORBIDDEN, NULL },
|
{ "@appendix", SECTION, RT_FORBIDDEN, BL_FORBIDDEN, NULL },
|
{ "@appendix", SECTION, RT_FORBIDDEN, BL_FORBIDDEN, NULL },
|
{ "@preface", SECTION, RT_FORBIDDEN, BL_FORBIDDEN, NULL },
|
{ "@preface", SECTION, RT_FORBIDDEN, BL_FORBIDDEN, NULL },
|
{ "@chapheading", SECTION, RT_FORBIDDEN, BL_FORBIDDEN, NULL },
|
{ "@chapheading", SECTION, RT_FORBIDDEN, BL_FORBIDDEN, NULL },
|
{ "@section", SECTION, RT_FORBIDDEN, BL_FORBIDDEN, NULL },
|
{ "@section", SECTION, RT_FORBIDDEN, BL_FORBIDDEN, NULL },
|
{ "@subsection", SUBSECTION, RT_FORBIDDEN, BL_FORBIDDEN, NULL },
|
{ "@subsection", SUBSECTION, RT_FORBIDDEN, BL_FORBIDDEN, NULL },
|
{ "@subsubsection", SUBSUBSECTION, RT_FORBIDDEN, BL_FORBIDDEN, NULL },
|
{ "@subsubsection", SUBSUBSECTION, RT_FORBIDDEN, BL_FORBIDDEN, NULL },
|
{ "@raise", SUBSECTION, RT_FORBIDDEN, BL_FORBIDDEN, NULL },
|
{ "@raise", SUBSECTION, RT_FORBIDDEN, BL_FORBIDDEN, NULL },
|
{ "@lower", SUBSECTION, RT_FORBIDDEN, BL_FORBIDDEN, NULL },
|
{ "@lower", SUBSECTION, RT_FORBIDDEN, BL_FORBIDDEN, NULL },
|
{ "", HEADING, RT_FORBIDDEN, BL_FORBIDDEN, NULL },
|
{ "", HEADING, RT_FORBIDDEN, BL_FORBIDDEN, NULL },
|
{ "END OF FILE", SECTION, RT_FORBIDDEN, BL_FORBIDDEN, NULL }
|
{ "END OF FILE", SECTION, RT_FORBIDDEN, BL_FORBIDDEN, NULL }
|
};
|
};
|
|
|
#define NUMBER_OF_KEYWORDS \
|
#define NUMBER_OF_KEYWORDS \
|
( sizeof( Keywords ) / sizeof( Keyword_info_t ) ) - 2
|
( sizeof( Keywords ) / sizeof( Keyword_info_t ) ) - 2
|
|
|
/*
|
/*
|
* exit_application
|
* exit_application
|
*/
|
*/
|
|
|
void exit_application(
|
void exit_application(
|
int status
|
int status
|
)
|
)
|
{
|
{
|
fprintf( stderr, "*** Error encountered ***\n" );
|
fprintf( stderr, "*** Error encountered ***\n" );
|
/*
|
/*
|
fprintf( stderr, "*** Error encountered on line %d ***\n", CurrentLine );
|
fprintf( stderr, "*** Error encountered on line %d ***\n", CurrentLine );
|
*/
|
*/
|
fclose( OutFile );
|
fclose( OutFile );
|
exit( status );
|
exit( status );
|
}
|
}
|
|
|
/*************************************************************************
|
/*************************************************************************
|
*************************************************************************
|
*************************************************************************
|
***** LINE MANIPULATION ROUTINES *****
|
***** LINE MANIPULATION ROUTINES *****
|
*************************************************************************
|
*************************************************************************
|
*************************************************************************/
|
*************************************************************************/
|
|
|
/*
|
/*
|
* PrintLine
|
* PrintLine
|
*/
|
*/
|
|
|
void PrintLine(
|
void PrintLine(
|
Line_Control *line
|
Line_Control *line
|
)
|
)
|
{
|
{
|
assert( line );
|
assert( line );
|
|
|
if ( line->number == -1 )
|
if ( line->number == -1 )
|
fprintf( stderr, " " );
|
fprintf( stderr, " " );
|
else
|
else
|
fprintf( stderr, "%5d", line->number );
|
fprintf( stderr, "%5d", line->number );
|
|
|
#if 0
|
#if 0
|
fprintf( stderr, "%s\n", line->Contents );
|
fprintf( stderr, "%s\n", line->Contents );
|
#else
|
#else
|
/*
|
/*
|
* Include some debugging information
|
* Include some debugging information
|
*/
|
*/
|
fprintf(
|
fprintf(
|
stderr,
|
stderr,
|
"<%d,%d,%d>:%s\n",
|
"<%d,%d,%d>:%s\n",
|
line->keyword,
|
line->keyword,
|
line->format,
|
line->format,
|
line->level,
|
line->level,
|
line->Contents
|
line->Contents
|
);
|
);
|
#endif
|
#endif
|
}
|
}
|
|
|
Chain_Control Line_Pool;
|
Chain_Control Line_Pool;
|
|
|
/*
|
/*
|
* FillLinePool
|
* FillLinePool
|
*/
|
*/
|
|
|
void FillLinePool( void )
|
void FillLinePool( void )
|
{
|
{
|
void *pool;
|
void *pool;
|
|
|
#define LINE_POOL_FILL_COUNT 100
|
#define LINE_POOL_FILL_COUNT 100
|
|
|
pool = malloc( sizeof( Line_Control ) * LINE_POOL_FILL_COUNT );
|
pool = malloc( sizeof( Line_Control ) * LINE_POOL_FILL_COUNT );
|
assert( pool );
|
assert( pool );
|
|
|
_Chain_Initialize(
|
_Chain_Initialize(
|
&Line_Pool,
|
&Line_Pool,
|
pool,
|
pool,
|
LINE_POOL_FILL_COUNT,
|
LINE_POOL_FILL_COUNT,
|
sizeof( Line_Control )
|
sizeof( Line_Control )
|
);
|
);
|
}
|
}
|
|
|
/*
|
/*
|
* AllocateLine
|
* AllocateLine
|
*/
|
*/
|
|
|
Line_Control *AllocateLine( void )
|
Line_Control *AllocateLine( void )
|
{
|
{
|
Line_Control *new_line;
|
Line_Control *new_line;
|
|
|
new_line = (Line_Control *) _Chain_Get( &Line_Pool );
|
new_line = (Line_Control *) _Chain_Get( &Line_Pool );
|
if ( !new_line ) {
|
if ( !new_line ) {
|
FillLinePool();
|
FillLinePool();
|
new_line = (Line_Control *) _Chain_Get( &Line_Pool );
|
new_line = (Line_Control *) _Chain_Get( &Line_Pool );
|
assert( new_line );
|
assert( new_line );
|
}
|
}
|
|
|
/*
|
/*
|
* This is commented out because although it is helpful during debug,
|
* This is commented out because although it is helpful during debug,
|
* it consumes a significant percentage of the program's execution time.
|
* it consumes a significant percentage of the program's execution time.
|
|
|
memset( new_line->Contents, '\0', sizeof( new_line->Contents ) );
|
memset( new_line->Contents, '\0', sizeof( new_line->Contents ) );
|
*/
|
*/
|
new_line->number = -1;
|
new_line->number = -1;
|
new_line->level = -1;
|
new_line->level = -1;
|
|
|
new_line->keyword = UNUSED;
|
new_line->keyword = UNUSED;
|
new_line->format = NO_EXTRA_FORMATTING_INFO;
|
new_line->format = NO_EXTRA_FORMATTING_INFO;
|
|
|
new_line->Node.next = NULL;
|
new_line->Node.next = NULL;
|
new_line->Node.previous = NULL;
|
new_line->Node.previous = NULL;
|
|
|
return new_line;
|
return new_line;
|
}
|
}
|
|
|
/*
|
/*
|
* FreeLine
|
* FreeLine
|
*/
|
*/
|
|
|
void FreeLine(
|
void FreeLine(
|
Line_Control *line
|
Line_Control *line
|
)
|
)
|
{
|
{
|
fflush( stdout );
|
fflush( stdout );
|
_Chain_Append( &Line_Pool, &line->Node );
|
_Chain_Append( &Line_Pool, &line->Node );
|
}
|
}
|
|
|
/*
|
/*
|
* DeleteLine
|
* DeleteLine
|
*/
|
*/
|
|
|
Line_Control *DeleteLine(
|
Line_Control *DeleteLine(
|
Line_Control *line
|
Line_Control *line
|
)
|
)
|
{
|
{
|
Line_Control *next;
|
Line_Control *next;
|
|
|
next = (Line_Control *)line->Node.next;
|
next = (Line_Control *)line->Node.next;
|
_Chain_Extract( &line->Node );
|
_Chain_Extract( &line->Node );
|
FreeLine( line );
|
FreeLine( line );
|
return next;
|
return next;
|
}
|
}
|
|
|
/*
|
/*
|
* PrintSurroundingLines
|
* PrintSurroundingLines
|
*/
|
*/
|
|
|
void PrintSurroundingLines(
|
void PrintSurroundingLines(
|
Line_Control *line,
|
Line_Control *line,
|
int backward,
|
int backward,
|
int forward
|
int forward
|
)
|
)
|
{
|
{
|
int i;
|
int i;
|
int real_backward;
|
int real_backward;
|
Line_Control *local;
|
Line_Control *local;
|
|
|
for ( local=line, real_backward=0, i=1 ;
|
for ( local=line, real_backward=0, i=1 ;
|
i<=backward ;
|
i<=backward ;
|
i++, real_backward++ ) {
|
i++, real_backward++ ) {
|
if ( &local->Node == Lines.first )
|
if ( &local->Node == Lines.first )
|
break;
|
break;
|
local = (Line_Control *) local->Node.previous;
|
local = (Line_Control *) local->Node.previous;
|
}
|
}
|
|
|
for ( i=1 ; i<=real_backward ; i++ ) {
|
for ( i=1 ; i<=real_backward ; i++ ) {
|
PrintLine( local );
|
PrintLine( local );
|
local = (Line_Control *) local->Node.next;
|
local = (Line_Control *) local->Node.next;
|
}
|
}
|
|
|
PrintLine( local );
|
PrintLine( local );
|
|
|
for ( i=1 ; i<=forward ; i++ ) {
|
for ( i=1 ; i<=forward ; i++ ) {
|
local = (Line_Control *) local->Node.next;
|
local = (Line_Control *) local->Node.next;
|
if ( _Chain_Is_last( &local->Node ) )
|
if ( _Chain_Is_last( &local->Node ) )
|
break;
|
break;
|
PrintLine( local );
|
PrintLine( local );
|
}
|
}
|
|
|
}
|
}
|
|
|
/*
|
/*
|
* SetLineFormat
|
* SetLineFormat
|
*/
|
*/
|
|
|
void SetLineFormat(
|
void SetLineFormat(
|
Line_Control *line,
|
Line_Control *line,
|
ExtraFormat_info_t format
|
ExtraFormat_info_t format
|
)
|
)
|
{
|
{
|
if ( line->format != NO_EXTRA_FORMATTING_INFO ) {
|
if ( line->format != NO_EXTRA_FORMATTING_INFO ) {
|
fprintf( stderr, "Line %d is already formatted\n", line->number );
|
fprintf( stderr, "Line %d is already formatted\n", line->number );
|
PrintLine( line );
|
PrintLine( line );
|
assert( FALSE );
|
assert( FALSE );
|
}
|
}
|
|
|
line->format = format;
|
line->format = format;
|
}
|
}
|
|
|
/*
|
/*
|
* LineCopyFromRight
|
* LineCopyFromRight
|
*/
|
*/
|
|
|
void LineCopyFromRight(
|
void LineCopyFromRight(
|
Line_Control *line,
|
Line_Control *line,
|
char *dest
|
char *dest
|
)
|
)
|
{
|
{
|
char *p;
|
char *p;
|
|
|
for ( p=line->Contents ; *p != ' ' ; p++ )
|
for ( p=line->Contents ; *p != ' ' ; p++ )
|
;
|
;
|
p++; /* skip the ' ' */
|
p++; /* skip the ' ' */
|
for ( ; isspace( *p ) ; p++ )
|
for ( ; isspace( *p ) ; p++ )
|
;
|
;
|
|
|
strcpy( dest, p );
|
strcpy( dest, p );
|
|
|
}
|
}
|
|
|
/*
|
/*
|
* LineCopySectionName
|
* LineCopySectionName
|
*/
|
*/
|
|
|
void LineCopySectionName(
|
void LineCopySectionName(
|
Line_Control *line,
|
Line_Control *line,
|
char *dest
|
char *dest
|
)
|
)
|
{
|
{
|
char *p;
|
char *p;
|
char *d;
|
char *d;
|
|
|
p = line->Contents;
|
p = line->Contents;
|
d = dest;
|
d = dest;
|
|
|
if ( *p == '@' ) { /* skip texinfo command */
|
if ( *p == '@' ) { /* skip texinfo command */
|
while ( !isspace( *p++ ) )
|
while ( !isspace( *p++ ) )
|
;
|
;
|
}
|
}
|
|
|
for ( ; *p ; )
|
for ( ; *p ; )
|
*d++ = *p++;
|
*d++ = *p++;
|
|
|
*d = '\0';
|
*d = '\0';
|
}
|
}
|
|
|
/*************************************************************************
|
/*************************************************************************
|
*************************************************************************
|
*************************************************************************
|
***** END OF LINE MANIPULATION ROUTINES *****
|
***** END OF LINE MANIPULATION ROUTINES *****
|
*************************************************************************
|
*************************************************************************
|
*************************************************************************/
|
*************************************************************************/
|
|
|
/*
|
/*
|
* main
|
* main
|
*/
|
*/
|
|
|
int main(
|
int main(
|
int argc,
|
int argc,
|
char **argv
|
char **argv
|
)
|
)
|
{
|
{
|
int c;
|
int c;
|
int index;
|
int index;
|
boolean single_file_mode;
|
boolean single_file_mode;
|
|
|
OutFile = stdout;
|
OutFile = stdout;
|
Verbose = FALSE;
|
Verbose = FALSE;
|
DocsNextNode = EmptyString;
|
DocsNextNode = EmptyString;
|
DocsPreviousNode = TopString;
|
DocsPreviousNode = TopString;
|
DocsUpNode = TopString;
|
DocsUpNode = TopString;
|
|
|
while ((c = getopt(argc, argv, "vcp:n:u:")) != EOF) {
|
while ((c = getopt(argc, argv, "vcp:n:u:")) != EOF) {
|
switch (c) {
|
switch (c) {
|
case 'v':
|
case 'v':
|
Verbose = TRUE;
|
Verbose = TRUE;
|
break;
|
break;
|
case 'c':
|
case 'c':
|
NodeNameIncludesChapter = 0;
|
NodeNameIncludesChapter = 0;
|
break;
|
break;
|
case 'p':
|
case 'p':
|
DocsPreviousNode = strdup(optarg);
|
DocsPreviousNode = strdup(optarg);
|
break;
|
break;
|
case 'n':
|
case 'n':
|
DocsNextNode = strdup(optarg);
|
DocsNextNode = strdup(optarg);
|
break;
|
break;
|
case 'u':
|
case 'u':
|
DocsUpNode = strdup(optarg);
|
DocsUpNode = strdup(optarg);
|
break;
|
break;
|
|
|
case '?':
|
case '?':
|
usage();
|
usage();
|
return 0;
|
return 0;
|
}
|
}
|
}
|
}
|
|
|
if ( optind != argc )
|
if ( optind != argc )
|
{
|
{
|
usage();
|
usage();
|
return 0 ;
|
return 0 ;
|
}
|
}
|
|
|
if ( Verbose )
|
if ( Verbose )
|
fprintf( stderr, "Arguments successfully parsed\n" );
|
fprintf( stderr, "Arguments successfully parsed\n" );
|
|
|
FillLinePool();
|
FillLinePool();
|
|
|
ProcessFile2( stdin, stdout );
|
ProcessFile2( stdin, stdout );
|
|
|
if ( Verbose )
|
if ( Verbose )
|
fprintf( stderr, "Exitting\n" );
|
fprintf( stderr, "Exitting\n" );
|
|
|
return 0;
|
return 0;
|
}
|
}
|
|
|
/*
|
/*
|
* ProcessFile
|
* ProcessFile
|
*/
|
*/
|
|
|
void ProcessFile2(
|
void ProcessFile2(
|
FILE *infile,
|
FILE *infile,
|
FILE *outfile
|
FILE *outfile
|
)
|
)
|
{
|
{
|
int index;
|
int index;
|
|
|
/*
|
/*
|
* Read the file into our internal data structure
|
* Read the file into our internal data structure
|
*/
|
*/
|
|
|
if ( Verbose )
|
if ( Verbose )
|
printf( "Processing (%s) -> (%s)\n", "stdin", "stdout" );
|
printf( "Processing (%s) -> (%s)\n", "stdin", "stdout" );
|
|
|
ReadFileIntoChain2( infile );
|
ReadFileIntoChain2( infile );
|
|
|
if ( Verbose )
|
if ( Verbose )
|
fprintf( stderr, "-------->FILE READ IN\n" );
|
fprintf( stderr, "-------->FILE READ IN\n" );
|
|
|
/*
|
/*
|
* Remove any spaces before the keyword and mark each keyword line as
|
* Remove any spaces before the keyword and mark each keyword line as
|
* such. Also remove extra white space at the end of lines.
|
* such. Also remove extra white space at the end of lines.
|
*/
|
*/
|
|
|
StripBlanks();
|
StripBlanks();
|
|
|
if ( Verbose )
|
if ( Verbose )
|
fprintf( stderr, "-------->BLANKS BEFORE KEYWORDS STRIPPED\n" );
|
fprintf( stderr, "-------->BLANKS BEFORE KEYWORDS STRIPPED\n" );
|
|
|
|
|
FormatToTexinfo();
|
FormatToTexinfo();
|
|
|
if ( Verbose )
|
if ( Verbose )
|
fprintf( stderr, "-------->FILE FORMATTED TO TEXINFO\n" );
|
fprintf( stderr, "-------->FILE FORMATTED TO TEXINFO\n" );
|
|
|
/*
|
/*
|
* Print the file
|
* Print the file
|
*/
|
*/
|
|
|
PrintFile2( outfile );
|
PrintFile2( outfile );
|
|
|
if ( Verbose )
|
if ( Verbose )
|
fprintf( stderr, "-------->FILE PRINTED\n" );
|
fprintf( stderr, "-------->FILE PRINTED\n" );
|
|
|
/*
|
/*
|
* Clean Up
|
* Clean Up
|
*/
|
*/
|
|
|
ReleaseFile();
|
ReleaseFile();
|
|
|
if ( Verbose )
|
if ( Verbose )
|
fprintf( stderr, "-------->FILE RELEASED\n" );
|
fprintf( stderr, "-------->FILE RELEASED\n" );
|
}
|
}
|
|
|
/*
|
/*
|
* usage
|
* usage
|
*/
|
*/
|
|
|
void usage( void )
|
void usage( void )
|
{
|
{
|
int index;
|
int index;
|
|
|
for ( index=0 ; strcmp( Usage_Strings[ index ], "EOF" ) ; index++ )
|
for ( index=0 ; strcmp( Usage_Strings[ index ], "EOF" ) ; index++ )
|
fprintf( stderr, Usage_Strings[ index ] );
|
fprintf( stderr, Usage_Strings[ index ] );
|
}
|
}
|
|
|
/*
|
/*
|
* ReadFileIntoChain
|
* ReadFileIntoChain
|
*/
|
*/
|
|
|
void ReadFileIntoChain2(
|
void ReadFileIntoChain2(
|
FILE *InFile
|
FILE *InFile
|
)
|
)
|
{
|
{
|
int line_count;
|
int line_count;
|
int max_length;
|
int max_length;
|
char *line;
|
char *line;
|
char Buffer[ BUFFER_SIZE ];
|
char Buffer[ BUFFER_SIZE ];
|
Line_Control *new_line;
|
Line_Control *new_line;
|
|
|
if ( !InFile ) {
|
if ( !InFile ) {
|
fprintf( stderr, "Unable to open (%s)\n", "stdin" );
|
fprintf( stderr, "Unable to open (%s)\n", "stdin" );
|
exit( 1 );
|
exit( 1 );
|
}
|
}
|
assert( InFile );
|
assert( InFile );
|
|
|
max_length = 0;
|
max_length = 0;
|
line_count = 0;
|
line_count = 0;
|
|
|
_Chain_Initialize_empty( &Lines );
|
_Chain_Initialize_empty( &Lines );
|
|
|
for ( ;; ) {
|
for ( ;; ) {
|
line = fgets( Buffer, BUFFER_SIZE, InFile );
|
line = fgets( Buffer, BUFFER_SIZE, InFile );
|
if ( !line )
|
if ( !line )
|
break;
|
break;
|
|
|
Buffer[ strlen( Buffer ) - 1 ] = '\0';
|
Buffer[ strlen( Buffer ) - 1 ] = '\0';
|
|
|
new_line = AllocateLine();
|
new_line = AllocateLine();
|
|
|
strcpy( new_line->Contents, Buffer );
|
strcpy( new_line->Contents, Buffer );
|
|
|
new_line->number = ++line_count;
|
new_line->number = ++line_count;
|
|
|
_Chain_Append( &Lines, &new_line->Node );
|
_Chain_Append( &Lines, &new_line->Node );
|
}
|
}
|
|
|
fclose( InFile );
|
fclose( InFile );
|
}
|
}
|
|
|
/*
|
/*
|
* StripBlanks
|
* StripBlanks
|
*/
|
*/
|
|
|
void StripBlanks( void )
|
void StripBlanks( void )
|
{
|
{
|
Line_Control *line;
|
Line_Control *line;
|
Keyword_indices_t index;
|
Keyword_indices_t index;
|
int indentation;
|
int indentation;
|
int length;
|
int length;
|
|
|
for ( line = (Line_Control *) Lines.first ;
|
for ( line = (Line_Control *) Lines.first ;
|
!_Chain_Is_last( &line->Node ) ;
|
!_Chain_Is_last( &line->Node ) ;
|
line = (Line_Control *) line->Node.next
|
line = (Line_Control *) line->Node.next
|
) {
|
) {
|
|
|
/*
|
/*
|
* Strip white space from the end of each line
|
* Strip white space from the end of each line
|
*/
|
*/
|
|
|
length = strlen( line->Contents );
|
length = strlen( line->Contents );
|
|
|
while ( isspace( line->Contents[ --length ] ) )
|
while ( isspace( line->Contents[ --length ] ) )
|
line->Contents[ length ] = '\0';
|
line->Contents[ length ] = '\0';
|
|
|
if ( strstr( line->Contents, "@chapter" ) )
|
if ( strstr( line->Contents, "@chapter" ) )
|
line->keyword = KEYWORD_CHAPTER;
|
line->keyword = KEYWORD_CHAPTER;
|
else if ( strstr( line->Contents, "@appendix" ) )
|
else if ( strstr( line->Contents, "@appendix" ) )
|
line->keyword = KEYWORD_APPENDIX;
|
line->keyword = KEYWORD_APPENDIX;
|
else if ( strstr( line->Contents, "@preface" ) )
|
else if ( strstr( line->Contents, "@preface" ) )
|
line->keyword = KEYWORD_PREFACE;
|
line->keyword = KEYWORD_PREFACE;
|
else if ( strstr( line->Contents, "@chapheading" ) )
|
else if ( strstr( line->Contents, "@chapheading" ) )
|
line->keyword = KEYWORD_CHAPHEADING;
|
line->keyword = KEYWORD_CHAPHEADING;
|
else if ( strstr( line->Contents, "@section" ) )
|
else if ( strstr( line->Contents, "@section" ) )
|
line->keyword = KEYWORD_SECTION;
|
line->keyword = KEYWORD_SECTION;
|
else if ( strstr( line->Contents, "@subsection" ) )
|
else if ( strstr( line->Contents, "@subsection" ) )
|
line->keyword = KEYWORD_SUBSECTION;
|
line->keyword = KEYWORD_SUBSECTION;
|
else if ( strstr( line->Contents, "@subsubsection" ) )
|
else if ( strstr( line->Contents, "@subsubsection" ) )
|
line->keyword = KEYWORD_SUBSUBSECTION;
|
line->keyword = KEYWORD_SUBSUBSECTION;
|
else if ( strstr( line->Contents, "@raise" ) )
|
else if ( strstr( line->Contents, "@raise" ) )
|
line->keyword = KEYWORD_RAISE;
|
line->keyword = KEYWORD_RAISE;
|
else if ( strstr( line->Contents, "@lower" ) )
|
else if ( strstr( line->Contents, "@lower" ) )
|
line->keyword = KEYWORD_LOWER;
|
line->keyword = KEYWORD_LOWER;
|
else
|
else
|
line->keyword = KEYWORD_OTHER;
|
line->keyword = KEYWORD_OTHER;
|
|
|
}
|
}
|
line = AllocateLine();
|
line = AllocateLine();
|
line->keyword = KEYWORD_END;
|
line->keyword = KEYWORD_END;
|
_Chain_Append( &Lines, &line->Node );
|
_Chain_Append( &Lines, &line->Node );
|
}
|
}
|
|
|
/*
|
/*
|
* strIsAllSpace
|
* strIsAllSpace
|
*/
|
*/
|
|
|
boolean strIsAllSpace(
|
boolean strIsAllSpace(
|
char *s
|
char *s
|
)
|
)
|
{
|
{
|
char *p;
|
char *p;
|
|
|
for ( p = s ; *p ; p++ )
|
for ( p = s ; *p ; p++ )
|
if ( !isspace( *p ) )
|
if ( !isspace( *p ) )
|
return FALSE;
|
return FALSE;
|
|
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
/*
|
/*
|
* BuildTexinfoNodes
|
* BuildTexinfoNodes
|
*/
|
*/
|
|
|
void BuildTexinfoNodes( void )
|
void BuildTexinfoNodes( void )
|
{
|
{
|
char Buffer[ BUFFER_SIZE ];
|
char Buffer[ BUFFER_SIZE ];
|
Line_Control *line;
|
Line_Control *line;
|
Line_Control *next_node;
|
Line_Control *next_node;
|
Line_Control *up_node;
|
Line_Control *up_node;
|
Line_Control *new_line;
|
Line_Control *new_line;
|
Line_Control *menu_insert_point;
|
Line_Control *menu_insert_point;
|
Line_Control *node_line;
|
Line_Control *node_line;
|
int next_found;
|
int next_found;
|
int menu_items;
|
int menu_items;
|
Keyword_indices_t index;
|
Keyword_indices_t index;
|
char ChapterName[ BUFFER_SIZE ];
|
char ChapterName[ BUFFER_SIZE ];
|
char NodeName[ BUFFER_SIZE ];
|
char NodeName[ BUFFER_SIZE ];
|
char UpNodeName[ BUFFER_SIZE ];
|
char UpNodeName[ BUFFER_SIZE ];
|
char NextNodeName[ BUFFER_SIZE ];
|
char NextNodeName[ BUFFER_SIZE ];
|
char PreviousNodeName[ BUFFER_SIZE ];
|
char PreviousNodeName[ BUFFER_SIZE ];
|
|
|
/*
|
/*
|
* Set Initial Previous Node Name
|
* Set Initial Previous Node Name
|
*/
|
*/
|
|
|
strcpy( PreviousNodeName, DocsPreviousNode );
|
strcpy( PreviousNodeName, DocsPreviousNode );
|
|
|
for ( line = (Line_Control *) Lines.first ;
|
for ( line = (Line_Control *) Lines.first ;
|
!_Chain_Is_last( &line->Node ) ;
|
!_Chain_Is_last( &line->Node ) ;
|
line = (Line_Control *) line->Node.next
|
line = (Line_Control *) line->Node.next
|
) {
|
) {
|
|
|
if ( line->level == -1 )
|
if ( line->level == -1 )
|
continue;
|
continue;
|
|
|
LineCopyFromRight( line, NodeName );
|
LineCopyFromRight( line, NodeName );
|
|
|
if ( line->keyword == KEYWORD_CHAPTER ||
|
if ( line->keyword == KEYWORD_CHAPTER ||
|
line->keyword == KEYWORD_APPENDIX ||
|
line->keyword == KEYWORD_APPENDIX ||
|
line->keyword == KEYWORD_PREFACE ||
|
line->keyword == KEYWORD_PREFACE ||
|
line->keyword == KEYWORD_CHAPHEADING ) {
|
line->keyword == KEYWORD_CHAPHEADING ) {
|
|
|
strcpy( ChapterName, NodeName );
|
strcpy( ChapterName, NodeName );
|
|
|
} else if ( NodeNameIncludesChapter ) {
|
} else if ( NodeNameIncludesChapter ) {
|
|
|
sprintf( Buffer, "%s %s", ChapterName, NodeName );
|
sprintf( Buffer, "%s %s", ChapterName, NodeName );
|
strcpy( NodeName, Buffer );
|
strcpy( NodeName, Buffer );
|
}
|
}
|
|
|
/*
|
/*
|
* Set Default Next Node Name
|
* Set Default Next Node Name
|
*/
|
*/
|
|
|
next_found = FALSE;
|
next_found = FALSE;
|
strcpy( NextNodeName, DocsNextNode );
|
strcpy( NextNodeName, DocsNextNode );
|
|
|
/*
|
/*
|
* Go ahead and put it on the chain in the right order (ahead of
|
* 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).
|
* the menu) and we can fill it in later (after the menu is built).
|
*/
|
*/
|
|
|
new_line = AllocateLine();
|
new_line = AllocateLine();
|
strcpy( new_line->Contents, "" ); /*"@ifinfo" ); */
|
strcpy( new_line->Contents, "" ); /*"@ifinfo" ); */
|
_Chain_Insert( line->Node.previous, &new_line->Node );
|
_Chain_Insert( line->Node.previous, &new_line->Node );
|
|
|
node_line = AllocateLine();
|
node_line = AllocateLine();
|
_Chain_Insert( line->Node.previous, &node_line->Node );
|
_Chain_Insert( line->Node.previous, &node_line->Node );
|
|
|
new_line = AllocateLine();
|
new_line = AllocateLine();
|
strcpy( new_line->Contents, "" ); /* "@end ifinfo" ); */
|
strcpy( new_line->Contents, "" ); /* "@end ifinfo" ); */
|
_Chain_Insert( line->Node.previous, &new_line->Node );
|
_Chain_Insert( line->Node.previous, &new_line->Node );
|
|
|
next_node = (Line_Control *) line->Node.next;
|
next_node = (Line_Control *) line->Node.next;
|
menu_insert_point = next_node;
|
menu_insert_point = next_node;
|
menu_items = 0;
|
menu_items = 0;
|
|
|
for ( ; ; ) {
|
for ( ; ; ) {
|
if ( next_node->keyword == KEYWORD_END )
|
if ( next_node->keyword == KEYWORD_END )
|
break;
|
break;
|
|
|
if ( next_node->level == -1 )
|
if ( next_node->level == -1 )
|
goto continue_menu_loop;
|
goto continue_menu_loop;
|
|
|
LineCopySectionName( next_node, Buffer );
|
LineCopySectionName( next_node, Buffer );
|
if ( !next_found ) {
|
if ( !next_found ) {
|
next_found = TRUE;
|
next_found = TRUE;
|
if (NodeNameIncludesChapter)
|
if (NodeNameIncludesChapter)
|
sprintf( NextNodeName, "%s %s", ChapterName, Buffer );
|
sprintf( NextNodeName, "%s %s", ChapterName, Buffer );
|
else
|
else
|
sprintf( NextNodeName, "%s", Buffer );
|
sprintf( NextNodeName, "%s", Buffer );
|
}
|
}
|
|
|
if ( next_node->level <= line->level )
|
if ( next_node->level <= line->level )
|
break;
|
break;
|
|
|
if ( next_node->level != (line->level + 1) )
|
if ( next_node->level != (line->level + 1) )
|
goto continue_menu_loop;
|
goto continue_menu_loop;
|
|
|
if ( menu_items == 0 ) {
|
if ( menu_items == 0 ) {
|
new_line = AllocateLine();
|
new_line = AllocateLine();
|
strcpy( new_line->Contents, "@ifinfo" );
|
strcpy( new_line->Contents, "@ifinfo" );
|
_Chain_Insert( menu_insert_point->Node.previous, &new_line->Node );
|
_Chain_Insert( menu_insert_point->Node.previous, &new_line->Node );
|
|
|
new_line = AllocateLine();
|
new_line = AllocateLine();
|
strcpy( new_line->Contents, "@menu" );
|
strcpy( new_line->Contents, "@menu" );
|
_Chain_Insert( menu_insert_point->Node.previous, &new_line->Node );
|
_Chain_Insert( menu_insert_point->Node.previous, &new_line->Node );
|
}
|
}
|
|
|
menu_items++;
|
menu_items++;
|
|
|
new_line = AllocateLine();
|
new_line = AllocateLine();
|
if (NodeNameIncludesChapter)
|
if (NodeNameIncludesChapter)
|
sprintf( new_line->Contents, "* %s %s::", ChapterName, Buffer );
|
sprintf( new_line->Contents, "* %s %s::", ChapterName, Buffer );
|
else
|
else
|
sprintf( new_line->Contents, "* %s::", Buffer );
|
sprintf( new_line->Contents, "* %s::", Buffer );
|
_Chain_Insert( menu_insert_point->Node.previous, &new_line->Node );
|
_Chain_Insert( menu_insert_point->Node.previous, &new_line->Node );
|
|
|
continue_menu_loop:
|
continue_menu_loop:
|
next_node = (Line_Control *) next_node->Node.next;
|
next_node = (Line_Control *) next_node->Node.next;
|
}
|
}
|
|
|
/*
|
/*
|
* If menu items were generated, then insert the end of menu stuff.
|
* If menu items were generated, then insert the end of menu stuff.
|
*/
|
*/
|
|
|
if ( menu_items ) {
|
if ( menu_items ) {
|
new_line = AllocateLine();
|
new_line = AllocateLine();
|
strcpy( new_line->Contents, "@end menu" );
|
strcpy( new_line->Contents, "@end menu" );
|
_Chain_Insert( menu_insert_point->Node.previous, &new_line->Node );
|
_Chain_Insert( menu_insert_point->Node.previous, &new_line->Node );
|
|
|
new_line = AllocateLine();
|
new_line = AllocateLine();
|
strcpy( new_line->Contents, "@end ifinfo" );
|
strcpy( new_line->Contents, "@end ifinfo" );
|
_Chain_Insert( menu_insert_point->Node.previous, &new_line->Node );
|
_Chain_Insert( menu_insert_point->Node.previous, &new_line->Node );
|
}
|
}
|
|
|
/*
|
/*
|
* Find the UpNodeName
|
* Find the UpNodeName
|
*/
|
*/
|
|
|
/* DumpList( &Lines ); */
|
/* DumpList( &Lines ); */
|
|
|
if ( line->level == 0 ) {
|
if ( line->level == 0 ) {
|
strcpy( UpNodeName, DocsUpNode );
|
strcpy( UpNodeName, DocsUpNode );
|
} else {
|
} else {
|
for ( up_node = line;
|
for ( up_node = line;
|
up_node && !_Chain_Is_first((Chain_Node *)up_node) ;
|
up_node && !_Chain_Is_first((Chain_Node *)up_node) ;
|
up_node = (Line_Control *) up_node->Node.previous
|
up_node = (Line_Control *) up_node->Node.previous
|
) {
|
) {
|
|
|
if ( (up_node->level == -1) )
|
if ( (up_node->level == -1) )
|
continue;
|
continue;
|
|
|
if ( up_node->level == (line->level - 1) ) {
|
if ( up_node->level == (line->level - 1) ) {
|
LineCopySectionName( up_node, Buffer );
|
LineCopySectionName( up_node, Buffer );
|
if (NodeNameIncludesChapter) {
|
if (NodeNameIncludesChapter) {
|
if (!strcmp(ChapterName, Buffer))
|
if (!strcmp(ChapterName, Buffer))
|
sprintf( UpNodeName, "%s", Buffer );
|
sprintf( UpNodeName, "%s", Buffer );
|
else
|
else
|
sprintf( UpNodeName, "%s %s", ChapterName, Buffer );
|
sprintf( UpNodeName, "%s %s", ChapterName, Buffer );
|
} else
|
} else
|
sprintf( UpNodeName, "%s", Buffer );
|
sprintf( UpNodeName, "%s", Buffer );
|
break;
|
break;
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
/*
|
/*
|
* Update the node information
|
* Update the node information
|
*/
|
*/
|
|
|
#if 0
|
#if 0
|
fprintf(
|
fprintf(
|
stderr,
|
stderr,
|
"@node %s, %s, %s, %s\n",
|
"@node %s, %s, %s, %s\n",
|
NodeName,
|
NodeName,
|
NextNodeName,
|
NextNodeName,
|
PreviousNodeName,
|
PreviousNodeName,
|
UpNodeName
|
UpNodeName
|
);
|
);
|
#endif
|
#endif
|
|
|
/* node_line was previously inserted */
|
/* node_line was previously inserted */
|
if (!NodeNameIncludesChapter) {
|
if (!NodeNameIncludesChapter) {
|
sprintf(
|
sprintf(
|
node_line->Contents,
|
node_line->Contents,
|
"@node %s, %s, %s, %s",
|
"@node %s, %s, %s, %s",
|
NodeName,
|
NodeName,
|
NextNodeName,
|
NextNodeName,
|
PreviousNodeName,
|
PreviousNodeName,
|
UpNodeName
|
UpNodeName
|
);
|
);
|
} else {
|
} else {
|
sprintf(
|
sprintf(
|
node_line->Contents,
|
node_line->Contents,
|
"@node %s, %s, %s, %s",
|
"@node %s, %s, %s, %s",
|
NodeName,
|
NodeName,
|
NextNodeName,
|
NextNodeName,
|
PreviousNodeName,
|
PreviousNodeName,
|
UpNodeName
|
UpNodeName
|
);
|
);
|
}
|
}
|
|
|
strcpy( PreviousNodeName, NodeName );
|
strcpy( PreviousNodeName, NodeName );
|
|
|
/* PrintLine( line ); */
|
/* PrintLine( line ); */
|
}
|
}
|
}
|
}
|
|
|
/*
|
/*
|
* FormatToTexinfo
|
* FormatToTexinfo
|
*/
|
*/
|
|
|
void FormatToTexinfo( void )
|
void FormatToTexinfo( void )
|
{
|
{
|
Line_Control *line;
|
Line_Control *line;
|
int baselevel = 0;
|
int baselevel = 0;
|
int currentlevel;
|
int currentlevel;
|
|
|
if ( Verbose )
|
if ( Verbose )
|
fprintf( stderr, "-------->INSERTING TEXINFO MENUS\n" );
|
fprintf( stderr, "-------->INSERTING TEXINFO MENUS\n" );
|
|
|
for ( line = (Line_Control *) Lines.first ;
|
for ( line = (Line_Control *) Lines.first ;
|
!_Chain_Is_last( &line->Node ) ;
|
!_Chain_Is_last( &line->Node ) ;
|
line = (Line_Control *) line->Node.next ) {
|
line = (Line_Control *) line->Node.next ) {
|
|
|
switch (line->keyword) {
|
switch (line->keyword) {
|
case UNUSED:
|
case UNUSED:
|
case KEYWORD_OTHER:
|
case KEYWORD_OTHER:
|
case KEYWORD_END:
|
case KEYWORD_END:
|
line->level = -1;
|
line->level = -1;
|
break;
|
break;
|
case KEYWORD_CHAPTER:
|
case KEYWORD_CHAPTER:
|
case KEYWORD_APPENDIX:
|
case KEYWORD_APPENDIX:
|
case KEYWORD_PREFACE:
|
case KEYWORD_PREFACE:
|
case KEYWORD_CHAPHEADING:
|
case KEYWORD_CHAPHEADING:
|
currentlevel = 0;
|
currentlevel = 0;
|
line->level = baselevel + currentlevel;
|
line->level = baselevel + currentlevel;
|
break;
|
break;
|
case KEYWORD_SECTION:
|
case KEYWORD_SECTION:
|
currentlevel = 1;
|
currentlevel = 1;
|
line->level = baselevel + currentlevel;
|
line->level = baselevel + currentlevel;
|
break;
|
break;
|
case KEYWORD_SUBSECTION:
|
case KEYWORD_SUBSECTION:
|
currentlevel = 2;
|
currentlevel = 2;
|
line->level = baselevel + currentlevel;
|
line->level = baselevel + currentlevel;
|
break;
|
break;
|
case KEYWORD_SUBSUBSECTION:
|
case KEYWORD_SUBSUBSECTION:
|
currentlevel = 3;
|
currentlevel = 3;
|
line->level = baselevel + currentlevel;
|
line->level = baselevel + currentlevel;
|
break;
|
break;
|
case KEYWORD_RAISE:
|
case KEYWORD_RAISE:
|
assert( baselevel );
|
assert( baselevel );
|
baselevel--;
|
baselevel--;
|
line->level = -1;
|
line->level = -1;
|
break;
|
break;
|
case KEYWORD_LOWER:
|
case KEYWORD_LOWER:
|
baselevel++;
|
baselevel++;
|
line->level = -1;
|
line->level = -1;
|
break;
|
break;
|
}
|
}
|
}
|
}
|
|
|
BuildTexinfoNodes();
|
BuildTexinfoNodes();
|
}
|
}
|
|
|
/*
|
/*
|
* PrintFile
|
* PrintFile
|
*/
|
*/
|
|
|
void PrintFile2(
|
void PrintFile2(
|
FILE *OutFile
|
FILE *OutFile
|
)
|
)
|
{
|
{
|
Line_Control *line;
|
Line_Control *line;
|
|
|
if ( !OutFile ) {
|
if ( !OutFile ) {
|
fprintf( stderr, "Unable to open (%s) for output\n", "stdout" );
|
fprintf( stderr, "Unable to open (%s) for output\n", "stdout" );
|
exit_application( 1 );
|
exit_application( 1 );
|
}
|
}
|
assert( OutFile );
|
assert( OutFile );
|
|
|
for ( line = (Line_Control *) Lines.first ;
|
for ( line = (Line_Control *) Lines.first ;
|
!_Chain_Is_last( &line->Node ) ;
|
!_Chain_Is_last( &line->Node ) ;
|
line = (Line_Control *) line->Node.next ) {
|
line = (Line_Control *) line->Node.next ) {
|
fprintf( OutFile, "%s\n", line->Contents );
|
fprintf( OutFile, "%s\n", line->Contents );
|
/*
|
/*
|
fprintf(
|
fprintf(
|
OutFile,
|
OutFile,
|
"(%d,%d)%s\n",
|
"(%d,%d)%s\n",
|
line->keyword,
|
line->keyword,
|
line->format,
|
line->format,
|
line->Contents
|
line->Contents
|
);
|
);
|
*/
|
*/
|
}
|
}
|
}
|
}
|
|
|
/*
|
/*
|
* DumpList
|
* DumpList
|
*/
|
*/
|
|
|
void DumpList(
|
void DumpList(
|
Chain_Control *the_list
|
Chain_Control *the_list
|
)
|
)
|
{
|
{
|
Line_Control *line;
|
Line_Control *line;
|
|
|
fprintf( stderr, "---> Dumping list (%p)\n", the_list );
|
fprintf( stderr, "---> Dumping list (%p)\n", the_list );
|
|
|
for ( line = (Line_Control *) the_list->first ;
|
for ( line = (Line_Control *) the_list->first ;
|
!_Chain_Is_last( &line->Node ) ;
|
!_Chain_Is_last( &line->Node ) ;
|
line = (Line_Control *) line->Node.next ) {
|
line = (Line_Control *) line->Node.next ) {
|
/* if (line->level != -1) */
|
/* if (line->level != -1) */
|
PrintLine( line );
|
PrintLine( line );
|
/* fprintf( stderr, "%s\n", line->Contents ); */
|
/* fprintf( stderr, "%s\n", line->Contents ); */
|
}
|
}
|
}
|
}
|
|
|
/*
|
/*
|
* ReleaseFile
|
* ReleaseFile
|
*/
|
*/
|
|
|
void ReleaseFile()
|
void ReleaseFile()
|
{
|
{
|
Line_Control *line;
|
Line_Control *line;
|
Line_Control *next;
|
Line_Control *next;
|
|
|
for ( line = (Line_Control *) Lines.first ;
|
for ( line = (Line_Control *) Lines.first ;
|
!_Chain_Is_last( &line->Node ) ;
|
!_Chain_Is_last( &line->Node ) ;
|
) {
|
) {
|
next = (Line_Control *) line->Node.next;
|
next = (Line_Control *) line->Node.next;
|
line = next;
|
line = next;
|
}
|
}
|
}
|
}
|
|
|
/*
|
/*
|
* strtoInitialCaps
|
* strtoInitialCaps
|
*/
|
*/
|
|
|
void strtoInitialCaps(
|
void strtoInitialCaps(
|
char *dest,
|
char *dest,
|
char *src
|
char *src
|
)
|
)
|
{
|
{
|
char *source = src;
|
char *source = src;
|
char *destination = dest;
|
char *destination = dest;
|
|
|
source = src;
|
source = src;
|
destination = (dest) ? dest : src;
|
destination = (dest) ? dest : src;
|
|
|
while ( *source ) {
|
while ( *source ) {
|
while ( isspace( *source ) )
|
while ( isspace( *source ) )
|
*destination++ = *source++;
|
*destination++ = *source++;
|
|
|
if ( !*source )
|
if ( !*source )
|
break;
|
break;
|
|
|
*destination++ = toupper( *source++ );
|
*destination++ = toupper( *source++ );
|
|
|
for ( ; *source && !isspace( *source ) ; source++ )
|
for ( ; *source && !isspace( *source ) ; source++ )
|
*destination++ = tolower( *source );
|
*destination++ = tolower( *source );
|
|
|
if ( !*source )
|
if ( !*source )
|
break;
|
break;
|
}
|
}
|
|
|
*destination = '\0';
|
*destination = '\0';
|
}
|
}
|
|
|