xref: /Universal-ctags/parsers/cpreprocessor.h (revision d711b26b07c2fa826faf4de3347e540c202cb6b3)
1 /*
2 *   Copyright (c) 1998-2002, Darren Hiebert
3 *
4 *   This source code is released for free distribution under the terms of the
5 *   GNU General Public License version 2 or (at your option) any later version.
6 *
7 *   External interface to get.c
8 */
9 #ifndef CTAGS_MAIN_GET_H
10 #define CTAGS_MAIN_GET_H
11 
12 /*
13 *   INCLUDE FILES
14 */
15 #include "general.h"  /* must always come first */
16 #include "ptrarray.h"
17 #include "types.h"
18 #include "vstring.h"
19 
20 /*
21 *   MACROS
22 */
23 
24 /*
25  * cppIs... macros are for the value returned from cppGetc().  Don't
26  * use "char" value. Don't pass a value stored to C-string
27  * (char*... or char[]) or vString.
28  *
29  * cppGetc() can return the value out of range of unsigned char.
30  * cppGetc calls skipToEndOfString() and skipToEndOfString() internally.
31  * They return STRING_SYMBOL (== 338) and CHAR_SYMBOL (== 322) in a
32  * case. (cppGetc() can return EOF (== -1). However, it is not an issue
33  * here.)
34  *
35  * is...() macros/functions defined in ctype.h can handle the value of
36  * an unsigned char or EOF; we cannot pass STRING_SYMBOL or CHAR_SYMBOL
37  * returned from cppGetc().
38  *
39  * Depending on the platform, isalpha(338) returns different value.
40  * As far as Fedora22, it returns 0. On Windows 2010, it returns 1.
41  *
42  * So, we need cppIs... macros.
43  * cppIs... macros considers STRING_SYMBOL and CHAR_SYMBOL */
44 
45 #define cppIsascii(c) ((c >= 0) && (c < 0x80))
46 /* isascii is not portable enough. */
47 
48 /*  Is the character valid as a character of a C identifier?
49  *  VMS allows '$' in identifiers.
50  */
51 #define cppIsalnum(c)  (cppIsascii(c) && isalnum(c))
52 #define cppIsident(c)  (cppIsalnum(c)					\
53 						|| (c) == '_' || (c) == '$')
54 
55 /*  Is the character valid as the first character of a C identifier?
56  *  C++ allows '~' in destructors.
57  *  VMS allows '$' in identifiers.
58  */
59 #define cppIsalpha(c)   (cppIsascii(c) && isalpha(c))
60 #define cppIsident1(c)  (cppIsalpha(c)					\
61 						  || (c) == '_' || (c) == '~' || (c) == '$')
62 
63 #define cppIsspace(c)   (cppIsascii(c) && isspace(c))
64 #define cppIsdigit(c)   (cppIsascii(c) && isdigit(c))
65 
66 
67 #define RoleTemplateUndef { true, "undef", "undefined" }
68 #define RoleTemplateCondition { false, "condition", "used in part of #if/#ifdef/#elif conditions" }
69 
70 #define RoleTemplateSystem { true, "system", "system header" }
71 #define RoleTemplateLocal  { true, "local", "local header" }
72 
73 /*
74 *   FUNCTION PROTOTYPES
75 */
76 extern bool cppIsBraceFormat (void);
77 extern unsigned int cppGetDirectiveNestLevel (void);
78 
79 /* Don't forget to set useCort true in your parser.
80  * The corkQueue is needed to capture macro parameters.
81  */
82 extern void cppInit (const bool state,
83 		     const bool hasAtLiteralStrings,
84 		     const bool hasCxxRawLiteralStrings,
85 		     const bool hasSingleQuoteLiteralNumbers,
86 		     int defineMacroKindIndex,
87 		     int macroUndefRoleIndex,
88 		     int macroConditionRoleIndex,
89 		     int headerKindIndex,
90 		     int headerSystemRoleIndex, int headerLocalRoleIndex,
91 		     int macroParamKindIndex,
92 		     int macrodefFieldIndex);
93 
94 extern void cppTerminate (void);
95 extern void cppBeginStatement (void);
96 extern void cppEndStatement (void);
97 extern void cppUngetc (const int c);
98 extern int cppUngetBufferSize();
99 extern void cppUngetString(const char * string,int len);
100 extern int cppGetc (void);
101 extern const vString * cppGetLastCharOrStringContents (void);
102 
103 /* Notify the external parser state for the purpose of conditional
104  * branch choice. The CXX parser stores the block level here. */
105 extern void cppPushExternalParserBlock(void);
106 extern void cppPopExternalParserBlock(void);
107 
108 #define CPP_MACRO_REPLACEMENT_FLAG_VARARGS 1
109 #define CPP_MACRO_REPLACEMENT_FLAG_STRINGIFY 2
110 
111 typedef struct sCppMacroReplacementPartInfo {
112 	int parameterIndex; /* -1 if this part is a constant */
113 	int flags;
114 	vString * constant; /* not NULL only if parameterIndex != -1 */
115 	struct sCppMacroReplacementPartInfo * next;
116 } cppMacroReplacementPartInfo;
117 
118 typedef struct sCppMacroInfo {
119 	char *name;			/* the name of macro. Useful for debugging. */
120 	bool hasParameterList; /* true if the macro has a trailing () */
121 	cppMacroReplacementPartInfo * replacements;
122 	int useCount;
123 	struct sCppMacroInfo * next;
124 } cppMacroInfo;
125 
126 extern cppMacroInfo * cppFindMacro (const char *const name);
127 extern void cppUngetStringBuiltByMacro (const char * string,int len, cppMacroInfo *macro);
128 
129 /*
130 * Build a replacement string for the specified macro.
131 * If the macro has parameters, they will be used.
132 * Parameters not found in the list will be assumed to be empty.
133 * May return NULL or equivalently an empty replacement string.
134 */
135 extern vString * cppBuildMacroReplacement(
136 		const cppMacroInfo * macro,
137 		const char ** parameters, /* may be NULL */
138 		int parameterCount
139 	);
140 
141 /* Do the same as cppBuildMacroReplacement with ptrArray<const char*>,
142  * and unget the result of expansion to input cpp stream. */
143 extern void cppBuildMacroReplacementWithPtrArrayAndUngetResult(
144 		cppMacroInfo * macro,
145 		const ptrArray * args);
146 
147 #endif  /* CTAGS_MAIN_GET_H */
148