1 /*=========================================================================
3 Program: Visualization Toolkit
4 Module: vtkParsePreprocess.h
6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
10 This software is distributed WITHOUT ANY WARRANTY; without even
11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12 PURPOSE. See the above copyright notice for more information.
14 =========================================================================*/
15 /*-------------------------------------------------------------------------
16 Copyright (c) 2010 David Gobbi.
18 Contributed to the VisualizationToolkit by the author in June 2010
19 under the terms of the Visualization Toolkit 2008 copyright.
20 -------------------------------------------------------------------------*/
23 This file provides subroutines to assist in preprocessing
24 C/C++ header files. It evaluates preprocessor directives
25 and stores a list of all preprocessor macros.
27 The preprocessing is done in-line while the file is being
28 parsed. Macros that are defined in the file are stored but
29 are not automatically expanded. The parser can query the
30 macro definitions, expand them into plain text, or ask the
31 preprocessor to evaluate them and return an integer result.
33 The typical usage of this preprocessor is that the main
34 parser will pass any lines that begin with '#' to the
35 vtkParsePreprocess_HandleDirective() function, which will
36 evaluate the line and provide a return code. The return
37 code will tell the main parser if a syntax error or macro
38 lookup error occurred, and will also let the parser know
39 if an #if or #else directive requires that the next block
43 #ifndef VTK_PARSE_PREPROCESS_H
44 #define VTK_PARSE_PREPROCESS_H
47 * The preprocessor int type. Use the compiler's longest int type.
49 #if defined(_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
50 typedef __int64 preproc_int_t;
51 typedef unsigned __int64 preproc_uint_t;
53 typedef long long preproc_int_t;
54 typedef unsigned long long preproc_uint_t;
58 * Struct to describe a preprocessor symbol.
60 typedef struct _MacroInfo
63 const char *Definition;
64 const char *Comment; /* unused */
65 int NumberOfParameters; /* only if IsFunction == 1 */
66 const char **Parameters; /* symbols for parameters */
67 int IsFunction; /* this macro requires arguments */
68 int IsExternal; /* this macro is from an included file */
69 int IsExcluded; /* do not expand this macro */
73 * Contains all symbols defined thus far (including those defined
74 * in any included header files).
76 typedef struct _PreprocessInfo
78 const char *FileName; /* the file that is being parsed */
79 MacroInfo ***MacroHashTable; /* hash table for macro lookup */
80 int NumberOfIncludeDirectories;
81 const char **IncludeDirectories;
82 int NumberOfIncludeFiles; /* all included files */
83 const char **IncludeFiles;
84 int IsExternal; /* label all macros as "external" */
85 int ConditionalDepth; /* internal state variable */
86 int ConditionalDone; /* internal state variable */
90 * Platforms. Always choose native unless crosscompiling.
92 enum _preproc_platform_t {
97 * Directive return values.
99 enum _preproc_return_t {
101 VTK_PARSE_SKIP = 1, /* skip next block */
102 VTK_PARSE_PREPROC_DOUBLE = 2, /* encountered a double */
103 VTK_PARSE_PREPROC_FLOAT = 3, /* encountered a float */
104 VTK_PARSE_PREPROC_STRING = 4, /* encountered a string */
105 VTK_PARSE_MACRO_UNDEFINED = 5, /* macro lookup failed */
106 VTK_PARSE_MACRO_REDEFINED = 6, /* attempt to redefine a macro */
107 VTK_PARSE_FILE_NOT_FOUND = 7, /* include file not found */
108 VTK_PARSE_FILE_OPEN_ERROR = 8, /* include file not readable */
109 VTK_PARSE_FILE_READ_ERROR = 9, /* error during read */
110 VTK_PARSE_MACRO_NUMARGS = 10, /* wrong number of args to func macro */
111 VTK_PARSE_SYNTAX_ERROR = 11 /* any and all syntax errors */
115 * Bitfield for fatal errors.
117 #define VTK_PARSE_FATAL_ERROR 0xF8
124 * Handle a preprocessor directive. Return value VTK_PARSE_OK
125 * means that no errors occurred, while VTK_PARSE_SKIP means that
126 * a conditional directive was encountered and the next code
127 * block should be skipped. The preprocessor has an internal state
128 * machine that keeps track of conditional if/else/endif directives.
129 * All other return values indicate errors, and it is up to the
130 * parser to decide which errors are fatal. The preprocessor
131 * only considers syntax errors and I/O errors to be fatal.
133 int vtkParsePreprocess_HandleDirective(
134 PreprocessInfo *info, const char *directive);
137 * Evaluate a preprocessor expression, providing an integer result
138 * in "val", and whether it is unsigned in "is_unsigned". A return
139 * value of VTK_PARSE_OK means that no errors occurred, while
140 * VTK_PREPROC_DOUBLE, VTK_PREPROC_FLOAT, and VTK_PREPROC_STRING
141 * indicate that the preprocessor encountered a non-integer value.
142 * Error return values are VTK_PARSE_MACRO_UNDEFINED and
143 * VTK_PARSE_SYNTAX_ERRORS. Undefined macros evaluate to zero.
145 int vtkParsePreprocess_EvaluateExpression(
146 PreprocessInfo *info, const char *text,
147 preproc_int_t *val, int *is_unsigned);
150 * Add all standard preprocessor symbols. Use VTK_PARSE_NATIVE
151 * as the platform. In the future, other platform specifiers
152 * might be added to allow crosscompiling.
154 void vtkParsePreprocess_AddStandardMacros(
155 PreprocessInfo *info, int platform);
158 * Add a preprocessor symbol, including a definition. Return
159 * values are VTK_PARSE_OK and VTK_PARSE_MACRO_REDEFINED.
161 int vtkParsePreprocess_AddMacro(
162 PreprocessInfo *info, const char *name, const char *definition);
165 * Remove a preprocessor symbol. Return values are VTK_PARSE_OK
166 * and VTK_PARSE_MACRO_UNDEFINED.
168 int vtkParsePreprocess_RemoveMacro(
169 PreprocessInfo *info, const char *name);
172 * Return a preprocessor symbol struct, or NULL if not found.
174 MacroInfo *vtkParsePreprocess_GetMacro(
175 PreprocessInfo *info, const char *name);
178 * Expand a macro. A function macro must be given an argstring
179 * with args in parentheses, otherwise the argstring can be NULL.
180 * returns NULL if the wrong number of arguments were given.
182 const char *vtkParsePreprocess_ExpandMacro(
183 PreprocessInfo *info, MacroInfo *macro, const char *argstring);
186 * Free an expanded macro
188 void vtkParsePreprocess_FreeMacroExpansion(
189 PreprocessInfo *info, MacroInfo *macro, const char *text);
192 * Fully process a string with the preprocessor, and
193 * return a new string or NULL if a fatal error occurred.
195 const char *vtkParsePreprocess_ProcessString(
196 PreprocessInfo *info, const char *text);
199 * Free a processed string. Only call this method if
200 * the string returned by ProcessString is different from
201 * the original string, because ProcessString will just
202 * return the original string if no processing was needed.
204 void vtkParsePreprocess_FreeProcessedString(
205 PreprocessInfo *info, const char *text);
208 * Add an include directory. The directories that were added
209 * first will be searched first.
211 void vtkParsePreprocess_IncludeDirectory(
212 PreprocessInfo *info, const char *name);
215 * Find an include file in the path. If system_first is set, then
216 * the current directory is ignored unless it is explicitly in the
217 * path. A null return value indicates that the file was not found.
218 * If already_loaded is set, then the file was already loaded. This
219 * preprocessor never loads the same file twice.
221 const char *vtkParsePreprocess_FindIncludeFile(
222 PreprocessInfo *info, const char *filename, int system_first,
223 int *already_loaded);
226 * Initialize a preprocessor symbol struct.
228 void vtkParsePreprocess_InitMacro(MacroInfo *symbol);
231 * Free a preprocessor macro struct
233 void vtkParsePreprocess_FreeMacro(MacroInfo *macro);
236 * Initialize a preprocessor struct.
238 void vtkParsePreprocess_Init(
239 PreprocessInfo *info, const char *filename);
242 * Free a preprocessor struct and its contents;
244 void vtkParsePreprocess_Free(PreprocessInfo *info);