1/**
2 * \file libyasm/preproc.h
3 * \brief YASM preprocessor module interface.
4 *
5 * \license
6 *  Copyright (C) 2001-2007  Peter Johnson
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 * \endlicense
29 */
30#ifndef YASM_PREPROC_H
31#define YASM_PREPROC_H
32
33#ifndef YASM_DOXYGEN
34/** Base #yasm_preproc structure.  Must be present as the first element in any
35 * #yasm_preproc implementation.
36 */
37typedef struct yasm_preproc_base {
38    /** #yasm_preproc_module implementation for this preprocessor. */
39    const struct yasm_preproc_module *module;
40} yasm_preproc_base;
41#endif
42
43/** YASM preprocesor module interface. */
44typedef struct yasm_preproc_module {
45    /** One-line description of the preprocessor. */
46    const char *name;
47
48    /** Keyword used to select preprocessor on the command line. */
49    const char *keyword;
50
51    /** Create preprocessor.
52     * Module-level implementation of yasm_preproc_create().
53     * Call yasm_preproc_create() instead of calling this function.
54     *
55     * \param in_filename       initial starting filename, or "-" to read from
56     *                          stdin
57     * \param symtab            symbol table (may be NULL if none)
58     * \param lm                line mapping repository
59     * \param errwarns          error/warnning set.
60     * \return New preprocessor.
61     *
62     * \note Any preprocessor errors and warnings are stored into errwarns.
63     */
64    /*@only@*/ yasm_preproc * (*create) (const char *in_filename,
65                                         yasm_symtab *symtab,
66                                         yasm_linemap *lm,
67                                         yasm_errwarns *errwarns);
68
69    /** Module-level implementation of yasm_preproc_destroy().
70     * Call yasm_preproc_destroy() instead of calling this function.
71     */
72    void (*destroy) (/*@only@*/ yasm_preproc *preproc);
73
74    /** Module-level implementation of yasm_preproc_get_line().
75     * Call yasm_preproc_get_line() instead of calling this function.
76     */
77    char * (*get_line) (yasm_preproc *preproc);
78
79    /** Module-level implementation of yasm_preproc_get_included_file().
80     * Call yasm_preproc_get_included_file() instead of calling this function.
81     */
82    size_t (*get_included_file) (yasm_preproc *preproc, /*@out@*/ char *buf,
83                                 size_t max_size);
84
85    /** Module-level implementation of yasm_preproc_add_include_file().
86     * Call yasm_preproc_add_include_file() instead of calling this function.
87     */
88    void (*add_include_file) (yasm_preproc *preproc, const char *filename);
89
90    /** Module-level implementation of yasm_preproc_predefine_macro().
91     * Call yasm_preproc_predefine_macro() instead of calling this function.
92     */
93    void (*predefine_macro) (yasm_preproc *preproc, const char *macronameval);
94
95    /** Module-level implementation of yasm_preproc_undefine_macro().
96     * Call yasm_preproc_undefine_macro() instead of calling this function.
97     */
98    void (*undefine_macro) (yasm_preproc *preproc, const char *macroname);
99
100    /** Module-level implementation of yasm_preproc_builtin_define().
101     * Call yasm_preproc_builtin_define() instead of calling this function.
102     */
103    void (*define_builtin) (yasm_preproc *preproc, const char *macronameval);
104
105    /** Module-level implementation of yasm_preproc_add_standard().
106     * Call yasm_preproc_add_standard() instead of calling this function.
107     */
108    void (*add_standard) (yasm_preproc *preproc, const char **macros);
109} yasm_preproc_module;
110
111/** Initialize preprocessor.
112 * The preprocessor needs access to the object format module to find out
113 * any output format specific macros.
114 * \param module        preprocessor module
115 * \param in_filename   initial starting filename, or "-" to read from stdin
116 * \param symtab        symbol table (may be NULL if none)
117 * \param lm            line mapping repository
118 * \param errwarns      error/warning set
119 * \return New preprocessor.
120 * \note Errors/warnings are stored into errwarns.
121 */
122/*@only@*/ yasm_preproc *yasm_preproc_create
123    (yasm_preproc_module *module, const char *in_filename,
124     yasm_symtab *symtab, yasm_linemap *lm, yasm_errwarns *errwarns);
125
126/** Cleans up any allocated preproc memory.
127 * \param preproc       preprocessor
128 */
129void yasm_preproc_destroy(/*@only@*/ yasm_preproc *preproc);
130
131/** Gets a single line of preprocessed source code.
132 * \param preproc       preprocessor
133 * \return Allocated line of code, without the trailing \n.
134 */
135char *yasm_preproc_get_line(yasm_preproc *preproc);
136
137/** Get the next filename included by the source code.
138 * \param preproc       preprocessor
139 * \param buf           destination buffer for filename
140 * \param max_size      maximum number of bytes that can be returned in buf
141 * \return Actual number of bytes returned in buf.
142 */
143size_t yasm_preproc_get_included_file(yasm_preproc *preproc,
144                                      /*@out@*/ char *buf, size_t max_size);
145
146/** Pre-include a file.
147 * \param preproc       preprocessor
148 * \param filename      filename
149 */
150void yasm_preproc_add_include_file(yasm_preproc *preproc,
151                                   const char *filename);
152
153/** Pre-define a macro.
154 * \param preproc       preprocessor
155 * \param macronameval  "name=value" string
156 */
157void yasm_preproc_predefine_macro(yasm_preproc *preproc,
158                                  const char *macronameval);
159
160/** Un-define a macro.
161 * \param preproc       preprocessor
162 * \param macroname     macro name
163 */
164void yasm_preproc_undefine_macro(yasm_preproc *preproc, const char *macroname);
165
166/** Define a builtin macro, preprocessed before the "standard" macros.
167 * \param preproc       preprocessor
168 * \param macronameval  "name=value" string
169 */
170void yasm_preproc_define_builtin(yasm_preproc *preproc,
171                                 const char *macronameval);
172
173/** Define additional standard macros, preprocessed after the builtins but
174 * prior to any user-defined macros.
175 * \param preproc       preprocessor
176 * \param macros        NULL-terminated array of macro strings
177 */
178void yasm_preproc_add_standard(yasm_preproc *preproc,
179                               const char **macros);
180
181#ifndef YASM_DOXYGEN
182
183/* Inline macro implementations for preproc functions */
184
185#define yasm_preproc_create(module, in_filename, symtab, lm, ews) \
186    module->create(in_filename, symtab, lm, ews)
187
188#define yasm_preproc_destroy(preproc) \
189    ((yasm_preproc_base *)preproc)->module->destroy(preproc)
190#define yasm_preproc_get_line(preproc) \
191    ((yasm_preproc_base *)preproc)->module->get_line(preproc)
192#define yasm_preproc_get_included_file(preproc, buf, max_size) \
193    ((yasm_preproc_base *)preproc)->module->get_included_file(preproc, buf, max_size)
194#define yasm_preproc_add_include_file(preproc, filename) \
195    ((yasm_preproc_base *)preproc)->module->add_include_file(preproc, filename)
196#define yasm_preproc_predefine_macro(preproc, macronameval) \
197    ((yasm_preproc_base *)preproc)->module->predefine_macro(preproc, \
198                                                            macronameval)
199#define yasm_preproc_undefine_macro(preproc, macroname) \
200    ((yasm_preproc_base *)preproc)->module->undefine_macro(preproc, macroname)
201#define yasm_preproc_define_builtin(preproc, macronameval) \
202    ((yasm_preproc_base *)preproc)->module->define_builtin(preproc, \
203                                                           macronameval)
204#define yasm_preproc_add_standard(preproc, macros) \
205    ((yasm_preproc_base *)preproc)->module->add_standard(preproc, \
206                                                         macros)
207
208#endif
209
210#endif
211