% % Tango/Weevil - A WEB Tangler and Weaver % Copyright (C) 1995 Corey Minyard % % This program is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation; either version 2 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; if not, write to the Free Software % Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. % % Corey Minyard - minyard@metronet.com % \section{Weevil Information Include Introduction} This file contains the information used by weevil and the language and output handlers that interface to weevil. @code <*> #ifdef __cplusplus__ extern "C" { #endif @ @ @ @ #ifdef __cplusplus__ } #endif @endcode \section{Interfacing Languages to Weevil} A language definition requires two simple procedure calls. A character handler handles all code a character at a time. It's job is to tell weevil how to handle the character. It is passed the standard weevil data, a character, and the next character in the sequence. It returns the following codes: \begin{description} \item[PROCESS\_CHAR\_NORMALLY] This is a standard character that should be handled normally by weevil. \item[PROCESS\_CHAR\_INSTRING] This character is in a string or comment, it should not be scanned for special weevil characters. \item[PROCESS\_CHAR\_SKIPNEXT] This character and the following character should be skipped without being scanned for special weevil characters. \end{description} The other procedure is an initialization handler, which may initialize the language handler. \section{Interfacing Output Types to Weevil} An output type requires a lot of function calls but is conceptually simple. Each function call output a certain portion of the output, just provide the proper output mechanism, add all the functions to the list of output modes, and it's done. Section~\ref{weevinfo-defines} has the typedefs and descriptions for all the functions. \begin{sloppypar} Weevil has a number of output modes. Documentation modes is the mode weevil starts in, it will just output everything as-is until it finds a code chunk (marked by \verb|@code|). Then it switches to code mode after calling \verb|begin_macro_handler|. Code mode calls the language character handler on each character to find out if it is in a string, comment, etc. It will output characters normally until it sees an \verb|@| (unless in a string or comment). If it sees an \verb|@@|, it will output a single \verb|@|. If it sees a \verb|@|, it will call \verb|output_macro_use_handler| with the name. It will \emph{not} output the \verb|@|. At the end of the code chunk, \verb|end_macro_handler| will be called. At the beginning of each line, \verb|output_linenum_handler| will be called. \end{sloppypar} After a code chunk has been output, if cross references for any variable uses exist for the code chunk then uses mode will be entered, where each variable used by the code chunk will be output. A begin handler is called, then for each cross reference the name handle is called and a handler is called for each place where the name is declared is given. Then an end name handler is called. After all uses have been output, an end handler is called. If declaration cross references exist, they are output next. A begin handler is called, then a handler for each variable name, then an end handler for the declaration list. If any cross references were output, a handler is called after all cross references have been output. Then documentation mode is entered again. \section{Defines} \label{weevinfo-defines} The following code chunk has miscellaneous definitions and the typedefs for all the language-specific and output-specific procedures used by weevil. Each procedure is also described in detail in the comment before it. @code #define MAXLINESIZE 200 #define TRUE 1 #define FALSE 0 typedef int bool; /* Is the processor processing stuff between @code and @endcode or is is processing documentation? Used by the codestate variable. */ #define IN_CODE 1 #define NOT_IN_CODE 2 #define PROCESS_CHAR_NORMALLY 0 #define PROCESS_CHAR_INSTRING 1 #define PROCESS_CHAR_SKIPNEXT 2 struct s_lpweevildat; /**************************************************************** ** ** These are for languages. ** ****************************************************************/ /* * Process the code a character at a time. The current and next * character are provided. Return PROCESS_CHAR_NORMALLY for * standard output, PROCESS_CHAR_INSTRING if in a string or * comment, or PROCESS_CHAR_SKIPNEXT if the current and next * character should not be processed (just output). */ typedef int (*char_handler)(struct s_lpweevildat *lpwd, char c, char next_c); /* * Initialize the language handler. This may use the * language-specific pointer in lpwd to store info for * itself. */ typedef void (*handler_init)(struct s_lpweevildat *lpwd); /**************************************************************** ** ** These are for documentation output. ** ****************************************************************/ /* * Initialize the mode handler. This may use the mode-specific * pointer in lpwd to store info for itself. */ typedef void (*mode_init)(struct s_lpweevildat *lpwd); /* * Handle the beginning of a code chunk. The name of the code * chunk is passed in. */ typedef void (*begin_macro_handler)(struct s_lpweevildat *lpwd, char *name); /* * Handle the end of a code chunk. */ typedef void (*end_macro_handler)(struct s_lpweevildat *lpwd); /* * Handle the end after all cross references and everything. */ typedef void (*finalend_chunk_handler)(struct s_lpweevildat *lpwd); /* * Output the use of a code chunk in some code. The name of * the code chunk is given. */ typedef void (*output_macro_use_handler)(struct s_lpweevildat *lpwd, char *macro_name); /* * Output the line number at the beginning of the code chunk. */ typedef void (*output_linenum_handler)(struct s_lpweevildat *lpwd); /* * Output a single normal character. */ typedef void (*output_char_handler)(struct s_lpweevildat *lpwd, char c); /* * Handle the beginning of a list of uses cross-references. */ typedef void (*output_begin_uses_handler)(struct s_lpweevildat *lpwd); /* * Handle the end of a list of uses cross-references. */ typedef void (*output_end_uses_handler)(struct s_lpweevildat *lpwd); /* * Handle the start of a single use cross reference. The name of * the variable is given. */ typedef void (*output_use_start_handler)(struct s_lpweevildat *lpwd, char *name); /* * Handle the end of a single use cross reference. The name of * the variable is given. */ typedef void (*output_use_end_handler)(struct s_lpweevildat *lpwd, char *name); /* * Output a use cross reference location. The file and macro * of the declaration is given. The name being cross-referenced * is also given. */ typedef void (*output_use_ref_handler)(struct s_lpweevildat *lpwd, char *file, char *macro, char *name); /* * Handle between each use of a cross reference. */ typedef void (*output_between_use_refs_handler)(struct s_lpweevildat *lpwd, char *name); /* * Handle the beginning of a list of declares cross-references. */ typedef void (*output_begin_decls_handler)(struct s_lpweevildat *lpwd); /* * Handle the end of a list of declares cross-references. */ typedef void (*output_end_decls_handler)(struct s_lpweevildat *lpwd); /* * Handle the output of a single declaration. */ typedef void (*output_decl_handler)(struct s_lpweevildat *lpwd, char *name); /* * Handle the end of cross references. This is only called if * cross-references were created. */ typedef void (*output_after_xrefs_handler)(struct s_lpweevildat *lpwd); @endcode \section{Structures} Various structures used by weevil are put here. @code @ @ @endcode \subsection{xreflist} This list contains list of cross references and information on where they are declared. @code typedef struct s_xreflist { struct s_xreflist *next; char *file; char *macro; char *name; } xreflist; @endcode \subsection{lpweevildat} This large structure contains everything there is to know about what weevil is doing. @code typedef struct s_lpweevildat { FILE *infile; /* File to get input from. */ FILE *outfile; /* File to send output. */ char line[MAXLINESIZE]; /* Current input line. */ int codestate; /* Current output state. */ char *curr_filename; /* Name of the input file being processed. */ char *curr_macro; /* Current macro being input. */ int maxlinesize; /* Maximum size of an input line. */ int curr_lineno; /* Current input line number. */ int code_lineno; /* Current code output line number. */ int retcode; /* Program return code. */ void *lang_data; /* Data for language mode. */ void *mode_data; /* Data for output mode. */ xreflist *pounddefs; /* List of #defines. */ xreflist *vardefs; /* List of variable defines. */ xreflist *uses; /* List of variable uses. */ xreflist *includes; /* List of places to look for .xfr files. */ /* Routine to scan code in a language-specific way. */ char_handler handle_char; /* Routines to output data for the output mode. */ begin_macro_handler begin_macro; end_macro_handler end_macro; finalend_chunk_handler finalend_chunk; output_macro_use_handler output_macro_use; output_linenum_handler output_linenum; output_char_handler output_char; output_begin_uses_handler output_begin_uses; output_end_uses_handler output_end_uses; output_use_start_handler output_use_start; output_use_end_handler output_use_end; output_use_ref_handler output_use_ref; output_between_use_refs_handler output_between_use_refs; output_begin_decls_handler output_begin_decls; output_end_decls_handler output_end_decls; output_decl_handler output_decl; output_after_xrefs_handler output_after_xrefs; } t_lpweevildat; @endcode \section{Language Dependent Routines} Here are forward-declared all the routines for the various languages handled by weevil. \subsection{C} @code int c_handle_char(t_lpweevildat *lpwd, char c, char next_c); void init_c_lang(t_lpweevildat *lpwd); @endcode \section{Output Mode Routines} Here are forward-declared all the routines for the various output modes handled by weevil. \subsection{\LaTeX} @code void latex_mode_init(t_lpweevildat *lpwd); void latex_begin_macro(t_lpweevildat *lpwd, char *name); void latex_end_macro(t_lpweevildat *lpwd); void latex_finalend_chunk(t_lpweevildat *lpwd); void latex_output_macro_use(t_lpweevildat *lpwd, char *macro_name); void latex_output_linenum(t_lpweevildat *lpwd); void latex_output_char(t_lpweevildat *lpwd, char c); void latex_output_begin_uses(t_lpweevildat *lpwd); void latex_output_end_uses(t_lpweevildat *lpwd); void latex_output_use_start(t_lpweevildat *lpwd, char *name); void latex_output_use_end(t_lpweevildat *lpwd, char *name); void latex_output_use_ref(t_lpweevildat *lpwd, char *file, char *macro, char *name); void latex_output_between_use_refs(t_lpweevildat *lpwd, char *name); void latex_output_begin_decls(t_lpweevildat *lpwd); void latex_output_end_decls(t_lpweevildat *lpwd); void latex_output_decl(t_lpweevildat *lpwd, char *name); void latex_output_after_xrefs(t_lpweevildat *lpwd); @endcode