📄 makeinfo.c
字号:
/* Makeinfo -- convert texinfo format files into info files Copyright (C) 1987 Free Software Foundation, Inc.This file is part of GNU Info.GNU Info is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 1, or (at your option)any later version.GNU Info is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU Info; see the file COPYING. If not, write tothe Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. *//* **************************************************************** *//* *//* Include File Declarations *//* *//* **************************************************************** */#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <ctype.h>#include <pwd.h>#include <errno.h>#include "getopt.h"#if defined (VMS)#include <perror.h>#endif#if defined (SYSV) || defined (VMS)#include <string.h>#else#include <strings.h>#endif#include <fcntl.h>#include <sys/file.h>#if defined (SYSV)#define bcopy(source, dest, count) memcpy (dest, source, count)#endif#if defined (__GNUC__)#define alloca __builtin_alloca#else#if defined (sparc)#include <alloca.h>#elseextern char *alloca ();#endif#endif/* Forward declarations. */char *xmalloc (), *xrealloc ();extern int in_fixed_width_font;/* Some systems don't declare this function in pwd.h. */struct passwd *getpwnam ();/* **************************************************************** *//* *//* Global Defines *//* *//* **************************************************************** *//* Error levels */#define NO_ERROR 0#define SYNTAX 2#define FATAL 4/* Boolean values. */#define true 1#define false 0typedef int boolean;/* How to allocate permanent storage for STRING. */#define savestring(x) \ ((char *)strcpy (xmalloc (1 + ((x) ? strlen (x) : 0)), (x) ? (x) : ""))/* C's standard macros don't check to make sure that the characters being changed are within range. So I have to check explicitly. *//* GNU Library doesn't have toupper(). Until GNU gets this fixed, I will have to do it. */#ifndef toupper#define toupper(c) ((c) - 32)#endif#define coerce_to_upper(c) ((islower(c) ? toupper(c) : (c)))#define coerce_to_lower(c) ((isupper(c) ? tolower(c) : (c)))#define control_character_bit 0x40 /* %01000000, must be off. */#define meta_character_bit 0x080/* %10000000, must be on. */#define CTL(c) ((c) & (~control_character_bit))#define UNCTL(c) coerce_to_upper(((c)|control_character_bit))#define META(c) ((c) | (meta_character_bit))#define UNMETA(c) ((c) & (~meta_character_bit))#define whitespace(c) (((c) == '\t') || ((c) == ' '))#define sentence_ender(c) ((c) == '.' || (c) == '?' || (c) == '!')#define cr_or_whitespace(c) (((c) == '\t') || ((c) == ' ') || ((c) == '\n'))#define member(c, s) (index (s, c) != NULL)#define COMMAND_PREFIX '@'/* Stuff for splitting large files. */#define SPLIT_SIZE_THRESHOLD 70000 /* What's good enough for Stallman... */#define DEFAULT_SPLIT_SIZE 50000/* Is probably good enough for me. */boolean splitting = true; /* Always true for now. */typedef int FUNCTION (); /* So I can say FUNCTION *foo; *//* **************************************************************** *//* *//* Global Variables *//* *//* **************************************************************** *//* Global pointer to argv[0]. */char *progname;/* The current input file state. */char *input_filename;char *input_text;int size_of_input_text;int input_text_offset;int line_number;#define curchar() input_text[input_text_offset]#define command_char(c) ((!whitespace(c)) && \ ((c) != '\n') && \ ((c) != '{'))#define skip_whitespace() while (input_text_offset != size_of_input_text \ && whitespace(curchar()))\ input_text_offset++/* And writing to the output. *//* The output file name. */char *output_filename, *pretty_output_filename;/* Current output stream. */FILE *output_stream;/* Position in the output file. */int output_position;/* Output paragraph buffer. */char *output_paragraph;/* Offset into OUTPUT_PARAGRAPH. */int output_paragraph_offset;/* The output paragraph "cursor" horizontal position. */int output_column = 0;/* non-zero means output_paragraph contains text. */boolean paragraph_is_open = false;#define INITIAL_PARAGRAPH_SPACE 5000int paragraph_buffer_len = INITIAL_PARAGRAPH_SPACE;/* Filling.. *//* True indicates that filling will take place on long lines. */boolean filling_enabled = true;/* Non-zero means that words are not to be split, even in long lines. This gets changed for cm_w (). */int non_splitting_words = 0;/* True indicates that filling a line also indents the new line. */boolean indented_fill = false;/* The column at which long lines are broken. */int fill_column = 72;/* The amount of indentation to apply at the start of each line. */int current_indent = 0;/* The amount of indentation to add at the starts of paragraphs. 0 means don't change existing indentation at paragraph starts. > 0 is amount to indent new paragraphs by. < 0 means indent to column zero by removing indentation if necessary. This is normally zero, but some people prefer paragraph starts to be somewhat more indented than paragraph bodies. A pretty value for this is 3. */int paragraph_start_indent = 3;/* Non-zero means that the use of paragraph_start_indent is inhibited. @example uses this to line up the left columns of the example text. */int inhibit_paragraph_indentation = 0;/* Indentation that is pending insertion. We have this for hacking lines which look blank, but contain whitespace. We want to treat those as blank lines. */int pending_indent = 0;/* The amount that indentation increases/decreases by. */int default_indentation_increment = 5;/* True indicates that indentation is temporarily turned off. */boolean no_indent = true;/* Command name in the process of being hacked. */char *command;/* The index in our internal command table of the currently executing command. */int command_index;/* A stack of file information records. If a new file is read in with "@input", we remember the old input file state on this stack. */typedef struct fstack{ struct fstack *next; char *filename; char *text; int size; int offset; int line_number;} FSTACK;FSTACK *filestack = (FSTACK *) NULL;/* Stuff for nodes. *//* The current nodes node name */char *current_node;/* The current nodes section level. */int current_section = 0;/* The filename of the current input file. This is never freed. */char *node_filename = (char *)NULL;/* What we remember for each node. */typedef struct tentry{ struct tentry *next_ent; char *node; /* name of this node. */ char *prev; /* name of "Prev:" for this node. */ char *next; /* name of "Next:" for this node. */ char *up; /* name of "Up:" for this node. */ int position; /* output file position of this node. */ int line_no; /* defining line in source file. */ char *filename; /* The file that this node was found in. */ int touched; /* non-zero means this node has been referenced. */ int flags; /* Room for growth. Right now, contains 1 bit. */} TAG_ENTRY;/* If node-a has a "Next" for node-b, but node-b has no "Prev" for node-a, we turn on this flag bit in node-b's tag entry. This means that when it is time to validate node-b, we don't report an additional error if there was no "Prev" field. */#define PREV_ERROR 0x1#define NEXT_ERROR 0x2#define UP_ERROR 0x4#define NO_WARN 0x8TAG_ENTRY *tag_table = (TAG_ENTRY *) NULL;/* Menu reference, *note reference, and validation hacking. *//* The various references that we know about. */enum reftype{ menu_reference, followed_reference};/* A structure to remember references with. A reference to a node is either an entry in a menu, or a cross-reference made with [px]ref. */typedef struct node_ref{ struct node_ref *next; char *node; /* Name of node referred to. */ char *containing_node; /* Name of node containing this reference. */ int line_no; /* Line number where the reference occurs. */ int section; /* Section level where the reference occurs. */ char *filename; /* Name of file where the reference occurs. */ enum reftype type; /* Type of reference, either menu or note. */} NODE_REF;/* The linked list of such structures. */NODE_REF *node_references = (NODE_REF *) NULL;/* Flag which tells us whether to examine menu lines or not. */int in_menu = 0;/* Flags controlling the operation of the program. *//* Default is to notify users of bad choices. */boolean print_warnings = true;/* Default is to check node references. */boolean validating = true;/* Number of errors that we tolerate on a given fileset. */int max_error_level = 100;/* Maximum number of references to a single node before complaining. */int reference_warning_limit = 1000;/* Non-zero means print out information about what is going on when it is going on. */int verbose_mode = 0;/* The list of commands that we hack in texinfo. Each one has an associated function. When the command is encountered in the text, the associated function is called with START as the argument. If the function expects arguments in braces, it remembers itself on the stack. When the corresponding close brace is encountered, the function is called with END as the argument. */#define START 0#define END 1typedef struct brace_element{ struct brace_element *next; FUNCTION *proc; int pos, line;} BRACE_ELEMENT;BRACE_ELEMENT *brace_stack = (BRACE_ELEMENT *) NULL;/* Forward declarations. */intinsert_self (), cm_tex (), cm_asterisk (), cm_dots (), cm_bullet (),cm_TeX (), cm_copyright (), cm_code (), cm_samp (), cm_file (), cm_kbd (),cm_key (), cm_ctrl (), cm_var (), cm_dfn (), cm_emph (), cm_strong (),cm_cite (), cm_italic (), cm_bold (), cm_roman (), cm_title (), cm_w (),cm_refill ();intcm_chapter (), cm_unnumbered (), cm_appendix (),cm_section (), cm_unnumberedsec (), cm_appendixsec (),cm_subsection (), cm_unnumberedsubsec (), cm_appendixsubsec (),cm_subsubsection (), cm_unnumberedsubsubsec (), cm_appendixsubsubsec (),cm_heading (), cm_chapheading (), cm_subheading (), cm_subsubheading (),cm_majorheading ();/* All @defxxx commands map to cm_defun (). */intcm_defun ();intcm_node (), cm_menu (), cm_xref (),cm_pxref (), cm_inforef (), cm_quotation (), cm_display (), cm_itemize (),cm_enumerate (), cm_table (), cm_itemx (), cm_noindent (), cm_setfilename (),cm_comment (), cm_ignore (), cm_br (), cm_sp (), cm_page (), cm_group (),cm_need (), cm_center (), cm_include (), cm_bye (), cm_item (), cm_end (),cm_infoinclude (), cm_ifinfo (), cm_iftex (), cm_titlepage (),cm_titlespec (),cm_kindex (), cm_cindex (), cm_findex (), cm_pindex (),cm_vindex (), cm_tindex (), cm_asis (), cm_synindex (), cm_settitle (),cm_setchapternewpage (), cm_printindex (), cm_minus (), cm_footnote (),cm_force_abbreviated_whitespace (), cm_force_sentence_end (), cm_example (),cm_smallexample (), cm_lisp (), cm_format (), cm_exdent (), cm_defindex (),cm_defcodeindex (), cm_sc (), cm_result (), cm_expansion (), cm_equiv (),cm_print (), cm_error (), cm_point (), cm_smallbook ();int do_nothing ();int misplaced_brace (), cm_obsolete ();typedef struct{ char *name; FUNCTION *proc; boolean argument_in_braces;} COMMAND;/* Stuff for defining commands on the fly. */COMMAND **user_command_array = (COMMAND **) NULL;int user_command_array_len = 0;static COMMAND CommandTable[] = { {"!", cm_force_sentence_end, false}, {"'", insert_self, false}, {"*", cm_asterisk, false}, {".", cm_force_sentence_end, false}, {":", cm_force_abbreviated_whitespace, false}, {"?", cm_force_sentence_end, false}, {"@", insert_self, false}, {" ", insert_self, false}, {"\n", insert_self, false}, {"TeX", cm_TeX, true}, {"`", insert_self, false}, {"appendix", cm_appendix, false}, {"appendixsec", cm_appendixsec, false}, {"appendixsubsec", cm_appendixsubsec, false}, {"appendixsubsubsec", cm_appendixsubsubsec, false}, {"asis", cm_asis, true}, {"b", cm_bold, true}, {"br", cm_br, false}, {"bullet", cm_bullet, true}, {"bye", cm_bye, false}, {"c", cm_comment, false}, {"center", cm_center, false}, {"chapheading", cm_chapheading, false}, {"chapter", cm_chapter, false}, {"cindex", cm_cindex, false}, {"cite", cm_cite, true}, {"code", cm_code, true}, {"comment", cm_comment, false}, {"contents", do_nothing, false}, {"copyright", cm_copyright, true}, {"ctrl", cm_ctrl, true}, {"defcodeindex", cm_defcodeindex, false}, {"defindex", cm_defindex, false}, {"dfn", cm_dfn, true},/* The `def' commands. */ {"defun", cm_defun, false}, {"defunx", cm_defun, false}, {"defvar", cm_defun, false}, {"defvarx", cm_defun, false}, {"defopt", cm_defun, false}, {"defoptx", cm_defun, false}, {"deffn", cm_defun, false}, {"deffnx", cm_defun, false}, {"defspec", cm_defun, false}, {"defspecx", cm_defun, false}, {"defmac", cm_defun, false}, {"defmacx", cm_defun, false},/* The end of the `def' commands. */ {"display", cm_display, false}, {"dots", cm_dots, true}, {"emph", cm_emph, true}, {"end", cm_end, false}, {"enumerate", cm_enumerate, false}, {"equiv", cm_equiv, true}, {"error", cm_error, true}, {"example", cm_example, false}, {"exdent", cm_exdent, false}, {"expansion", cm_expansion, true}, {"file", cm_file, true}, {"findex", cm_findex, false}, {"format", cm_format, false}, {"group", cm_group, false}, {"heading", cm_heading, false}, {"i", cm_italic, true}, {"iappendix", cm_appendix, false}, {"iappendixsec", cm_appendixsec, false}, {"iappendixsubsec", cm_appendixsubsec, false}, {"iappendixsubsubsec", cm_appendixsubsubsec, false}, {"ichapter", cm_chapter, false}, {"ifinfo", cm_ifinfo, false}, {"iftex", cm_iftex, false}, {"ignore", cm_ignore, false}, {"include", cm_include, false}, {"inforef", cm_inforef, true}, {"input", cm_include, false}, {"isection", cm_section, false}, {"isubsection", cm_subsection, false}, {"isubsubsection", cm_subsubsection, false}, {"item", cm_item, false}, {"itemize", cm_itemize, false}, {"itemx", cm_itemx, false}, {"iunnumbered", cm_unnumbered, false}, {"iunnumberedsec", cm_unnumberedsec, false}, {"iunnumberedsubsec", cm_unnumberedsubsec, false}, {"iunnumberedsubsubsec", cm_unnumberedsubsubsec, false}, {"kbd", cm_kbd, true}, {"key", cm_key, true}, {"kindex", cm_kindex, false}, {"lisp", cm_lisp, false}, {"majorheading", cm_majorheading, false}, {"menu", cm_menu}, {"minus", cm_minus, true}, {"need", cm_need, false}, {"node", cm_node, false}, {"noindent", cm_noindent, false}, {"page", do_nothing, false}, {"pindex", cm_pindex, false}, {"point", cm_point, true}, {"print", cm_print, true}, {"printindex", cm_printindex, false}, {"pxref", cm_pxref, true}, {"quotation", cm_quotation, false}, {"r", cm_roman, true}, {"ref", cm_xref, true}, {"refill", cm_refill, false}, {"result", cm_result, true}, {"samp", cm_samp, true}, {"sc", cm_sc, true}, {"section", cm_section, false}, {"setchapternewpage", cm_setchapternewpage, false}, {"setfilename", cm_setfilename, false}, {"settitle", cm_settitle, false}, {"smallexample", cm_smallexample, false}, {"smallbook", cm_smallbook, false}, {"sp", cm_sp, false}, {"strong", cm_strong, true}, {"subheading", cm_subheading, false}, {"subsection", cm_subsection, false}, {"subsubheading", cm_subsubheading, false}, {"subsubsection", cm_subsubsection, false}, {"summarycontents", do_nothing, false}, {"syncodeindex", cm_synindex, false}, {"synindex", cm_synindex, false}, {"t", cm_title, true}, {"table", cm_table, false}, {"tex", cm_tex, false}, {"tindex", cm_tindex, false}, {"titlepage", cm_titlepage, false}, {"titlespec", cm_titlespec, false}, {"unnumbered", cm_unnumbered, false}, {"unnumberedsec", cm_unnumberedsec, false}, {"unnumberedsubsec", cm_unnumberedsubsec, false}, {"unnumberedsubsubsec", cm_unnumberedsubsubsec, false}, {"var", cm_var, true}, {"vindex", cm_vindex, false},
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -