1/* 2 * Imported NASM preprocessor - glue code 3 * 4 * Copyright (C) 2002-2007 Peter Johnson 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS'' 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE 19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * POSSIBILITY OF SUCH DAMAGE. 26 */ 27#include <util.h> 28 29#include <libyasm.h> 30 31#include "nasm.h" 32#include "nasmlib.h" 33#include "nasm-pp.h" 34#include "nasm-eval.h" 35 36typedef struct yasm_preproc_nasm { 37 yasm_preproc_base preproc; /* Base structure */ 38 39 FILE *in; 40 char *line; 41 char *file_name; 42 long prior_linnum; 43 int lineinc; 44} yasm_preproc_nasm; 45yasm_symtab *nasm_symtab; 46static yasm_linemap *cur_lm; 47static yasm_errwarns *cur_errwarns; 48int tasm_compatible_mode = 0; 49int tasm_locals; 50const char *tasm_segment; 51 52#include "nasm-version.c" 53 54typedef struct preproc_dep { 55 STAILQ_ENTRY(preproc_dep) link; 56 char *name; 57} preproc_dep; 58 59static STAILQ_HEAD(preproc_dep_head, preproc_dep) *preproc_deps; 60static int done_dep_preproc; 61 62yasm_preproc_module yasm_nasm_LTX_preproc; 63 64static void 65nil_listgen_init(char *p, efunc e) 66{ 67} 68 69static void 70nil_listgen_cleanup(void) 71{ 72} 73 74static void 75nil_listgen_output(long v, const void *d, unsigned long v2) 76{ 77} 78 79static void 80nil_listgen_line(int v, char *p) 81{ 82} 83 84static void 85nil_listgen_uplevel(int v) 86{ 87} 88 89static void 90nil_listgen_downlevel(int v) 91{ 92} 93 94static ListGen nil_list = { 95 nil_listgen_init, 96 nil_listgen_cleanup, 97 nil_listgen_output, 98 nil_listgen_line, 99 nil_listgen_uplevel, 100 nil_listgen_downlevel 101}; 102 103 104static void 105nasm_efunc(int severity, const char *fmt, ...) 106{ 107 va_list va; 108 109 va_start(va, fmt); 110 switch (severity & ERR_MASK) { 111 case ERR_WARNING: 112 yasm_warn_set_va(YASM_WARN_PREPROC, fmt, va); 113 break; 114 case ERR_NONFATAL: 115 yasm_error_set_va(YASM_ERROR_GENERAL, fmt, va); 116 break; 117 case ERR_FATAL: 118 yasm_fatal(fmt, va); 119 /*@notreached@*/ 120 break; 121 case ERR_PANIC: 122 yasm_internal_error(fmt); /* FIXME */ 123 break; 124 case ERR_DEBUG: 125 break; 126 } 127 va_end(va); 128 yasm_errwarn_propagate(cur_errwarns, 129 yasm_linemap_poke(cur_lm, nasm_src_get_fname(), 130 (unsigned long)nasm_src_get_linnum())); 131} 132 133static yasm_preproc * 134nasm_preproc_create(const char *in_filename, yasm_symtab *symtab, 135 yasm_linemap *lm, yasm_errwarns *errwarns) 136{ 137 FILE *f; 138 yasm_preproc_nasm *preproc_nasm = yasm_xmalloc(sizeof(yasm_preproc_nasm)); 139 140 preproc_nasm->preproc.module = &yasm_nasm_LTX_preproc; 141 142 if (strcmp(in_filename, "-") != 0) { 143 f = fopen(in_filename, "r"); 144 if (!f) 145 yasm__fatal( N_("Could not open input file") ); 146 } 147 else 148 f = stdin; 149 150 preproc_nasm->in = f; 151 nasm_symtab = symtab; 152 cur_lm = lm; 153 cur_errwarns = errwarns; 154 preproc_deps = NULL; 155 done_dep_preproc = 0; 156 preproc_nasm->line = NULL; 157 preproc_nasm->file_name = NULL; 158 preproc_nasm->prior_linnum = 0; 159 preproc_nasm->lineinc = 0; 160 nasmpp.reset(f, in_filename, 2, nasm_efunc, nasm_evaluate, &nil_list); 161 162 pp_extra_stdmac(nasm_version_mac); 163 164 return (yasm_preproc *)preproc_nasm; 165} 166 167static void 168nasm_preproc_destroy(yasm_preproc *preproc) 169{ 170 yasm_preproc_nasm *preproc_nasm = (yasm_preproc_nasm *)preproc; 171 nasmpp.cleanup(0); 172 if (preproc_nasm->line) 173 yasm_xfree(preproc_nasm->line); 174 if (preproc_nasm->file_name) 175 yasm_xfree(preproc_nasm->file_name); 176 yasm_xfree(preproc); 177 if (preproc_deps) 178 yasm_xfree(preproc_deps); 179} 180 181static char * 182nasm_preproc_get_line(yasm_preproc *preproc) 183{ 184 yasm_preproc_nasm *preproc_nasm = (yasm_preproc_nasm *)preproc; 185 long linnum; 186 int altline; 187 char *line; 188 189 if (preproc_nasm->line) { 190 char *retval = preproc_nasm->line; 191 preproc_nasm->line = NULL; 192 return retval; 193 } 194 195 line = nasmpp.getline(); 196 if (!line) 197 { 198 nasmpp.cleanup(1); 199 return NULL; /* EOF */ 200 } 201 202 linnum = preproc_nasm->prior_linnum += preproc_nasm->lineinc; 203 altline = nasm_src_get(&linnum, &preproc_nasm->file_name); 204 if (altline != 0) { 205 preproc_nasm->lineinc = 206 (altline != -1 || preproc_nasm->lineinc != 1); 207 preproc_nasm->line = line; 208 line = yasm_xmalloc(40+strlen(preproc_nasm->file_name)); 209 sprintf(line, "%%line %ld+%d %s", linnum, 210 preproc_nasm->lineinc, preproc_nasm->file_name); 211 preproc_nasm->prior_linnum = linnum; 212 } 213 214 return line; 215} 216 217void 218nasm_preproc_add_dep(char *name) 219{ 220 preproc_dep *dep; 221 222 /* If not processing dependencies, simply return */ 223 if (!preproc_deps) 224 return; 225 226 /* Save in preproc_deps */ 227 dep = yasm_xmalloc(sizeof(preproc_dep)); 228 dep->name = yasm__xstrdup(name); 229 STAILQ_INSERT_TAIL(preproc_deps, dep, link); 230} 231 232static size_t 233nasm_preproc_get_included_file(yasm_preproc *preproc, /*@out@*/ char *buf, 234 size_t max_size) 235{ 236 if (!preproc_deps) { 237 preproc_deps = yasm_xmalloc(sizeof(struct preproc_dep_head)); 238 STAILQ_INIT(preproc_deps); 239 } 240 241 for (;;) { 242 char *line; 243 244 /* Pull first dep out of preproc_deps and return it if there is one */ 245 if (!STAILQ_EMPTY(preproc_deps)) { 246 char *name; 247 preproc_dep *dep = STAILQ_FIRST(preproc_deps); 248 STAILQ_REMOVE_HEAD(preproc_deps, link); 249 name = dep->name; 250 yasm_xfree(dep); 251 strncpy(buf, name, max_size); 252 buf[max_size-1] = '\0'; 253 yasm_xfree(name); 254 return strlen(buf); 255 } 256 257 /* No more preprocessing to do */ 258 if (done_dep_preproc) { 259 return 0; 260 } 261 262 /* Preprocess some more, throwing away the result */ 263 line = nasmpp.getline(); 264 if (line) 265 yasm_xfree(line); 266 else 267 done_dep_preproc = 1; 268 } 269} 270 271static void 272nasm_preproc_add_include_file(yasm_preproc *preproc, const char *filename) 273{ 274 pp_pre_include(filename); 275} 276 277static void 278nasm_preproc_predefine_macro(yasm_preproc *preproc, const char *macronameval) 279{ 280 char *mnv = yasm__xstrdup(macronameval); 281 pp_pre_define(mnv); 282 yasm_xfree(mnv); 283} 284 285static void 286nasm_preproc_undefine_macro(yasm_preproc *preproc, const char *macroname) 287{ 288 char *mn = yasm__xstrdup(macroname); 289 pp_pre_undefine(mn); 290 yasm_xfree(mn); 291} 292 293static void 294nasm_preproc_define_builtin(yasm_preproc *preproc, const char *macronameval) 295{ 296 char *mnv = yasm__xstrdup(macronameval); 297 pp_builtin_define(mnv); 298 yasm_xfree(mnv); 299} 300 301static void 302nasm_preproc_add_standard(yasm_preproc *preproc, const char **macros) 303{ 304 pp_extra_stdmac(macros); 305} 306 307/* Define preproc structure -- see preproc.h for details */ 308yasm_preproc_module yasm_nasm_LTX_preproc = { 309 "Real NASM Preprocessor", 310 "nasm", 311 nasm_preproc_create, 312 nasm_preproc_destroy, 313 nasm_preproc_get_line, 314 nasm_preproc_get_included_file, 315 nasm_preproc_add_include_file, 316 nasm_preproc_predefine_macro, 317 nasm_preproc_undefine_macro, 318 nasm_preproc_define_builtin, 319 nasm_preproc_add_standard 320}; 321 322static yasm_preproc * 323tasm_preproc_create(const char *in_filename, yasm_symtab *symtab, 324 yasm_linemap *lm, yasm_errwarns *errwarns) 325{ 326 tasm_compatible_mode = 1; 327 return nasm_preproc_create(in_filename, symtab, lm, errwarns); 328} 329 330yasm_preproc_module yasm_tasm_LTX_preproc = { 331 "Real TASM Preprocessor", 332 "tasm", 333 tasm_preproc_create, 334 nasm_preproc_destroy, 335 nasm_preproc_get_line, 336 nasm_preproc_get_included_file, 337 nasm_preproc_add_include_file, 338 nasm_preproc_predefine_macro, 339 nasm_preproc_undefine_macro, 340 nasm_preproc_define_builtin, 341 nasm_preproc_add_standard 342}; 343