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 36 typedef 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; 45 yasm_symtab *nasm_symtab; 46 static yasm_linemap *cur_lm; 47 static yasm_errwarns *cur_errwarns; 48 int tasm_compatible_mode = 0; 49 int tasm_locals; 50 const char *tasm_segment; 51 52 #include "nasm-version.c" 53 54 typedef struct preproc_dep { 55 STAILQ_ENTRY(preproc_dep) link; 56 char *name; 57 } preproc_dep; 58 59 static STAILQ_HEAD(preproc_dep_head, preproc_dep) *preproc_deps; 60 static int done_dep_preproc; 61 62 yasm_preproc_module yasm_nasm_LTX_preproc; 63 64 static void 65 nil_listgen_init(char *p, efunc e) 66 { 67 } 68 69 static void 70 nil_listgen_cleanup(void) 71 { 72 } 73 74 static void 75 nil_listgen_output(long v, const void *d, unsigned long v2) 76 { 77 } 78 79 static void 80 nil_listgen_line(int v, char *p) 81 { 82 } 83 84 static void 85 nil_listgen_uplevel(int v) 86 { 87 } 88 89 static void 90 nil_listgen_downlevel(int v) 91 { 92 } 93 94 static 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 104 static void 105 nasm_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 133 static yasm_preproc * 134 nasm_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 167 static void 168 nasm_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 181 static char * 182 nasm_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 217 void 218 nasm_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 232 static size_t 233 nasm_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 271 static void 272 nasm_preproc_add_include_file(yasm_preproc *preproc, const char *filename) 273 { 274 pp_pre_include(filename); 275 } 276 277 static void 278 nasm_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 285 static void 286 nasm_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 293 static void 294 nasm_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 301 static void 302 nasm_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 */ 308 yasm_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 322 static yasm_preproc * 323 tasm_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 330 yasm_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