nasm-preproc.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  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. #include <libyasm.h>
  29. #include "nasm.h"
  30. #include "nasmlib.h"
  31. #include "nasm-pp.h"
  32. #include "nasm-eval.h"
  33. typedef struct yasm_preproc_nasm {
  34. yasm_preproc_base preproc; /* Base structure */
  35. FILE *in;
  36. char *line;
  37. char *file_name;
  38. long prior_linnum;
  39. int lineinc;
  40. } yasm_preproc_nasm;
  41. yasm_symtab *nasm_symtab;
  42. static yasm_linemap *cur_lm;
  43. static yasm_errwarns *cur_errwarns;
  44. int tasm_compatible_mode = 0;
  45. int tasm_locals;
  46. const char *tasm_segment;
  47. #include "nasm-version.c"
  48. typedef struct preproc_dep {
  49. STAILQ_ENTRY(preproc_dep) link;
  50. char *name;
  51. } preproc_dep;
  52. static STAILQ_HEAD(preproc_dep_head, preproc_dep) *preproc_deps;
  53. static int done_dep_preproc;
  54. yasm_preproc_module yasm_nasm_LTX_preproc;
  55. static void
  56. nil_listgen_init(char *p, efunc e)
  57. {
  58. }
  59. static void
  60. nil_listgen_cleanup(void)
  61. {
  62. }
  63. static void
  64. nil_listgen_output(long v, const void *d, unsigned long v2)
  65. {
  66. }
  67. static void
  68. nil_listgen_line(int v, char *p)
  69. {
  70. }
  71. static void
  72. nil_listgen_uplevel(int v)
  73. {
  74. }
  75. static void
  76. nil_listgen_downlevel(int v)
  77. {
  78. }
  79. static ListGen nil_list = {
  80. nil_listgen_init,
  81. nil_listgen_cleanup,
  82. nil_listgen_output,
  83. nil_listgen_line,
  84. nil_listgen_uplevel,
  85. nil_listgen_downlevel
  86. };
  87. static void
  88. nasm_efunc(int severity, const char *fmt, ...)
  89. {
  90. va_list va;
  91. va_start(va, fmt);
  92. switch (severity & ERR_MASK) {
  93. case ERR_WARNING:
  94. yasm_warn_set_va(YASM_WARN_PREPROC, fmt, va);
  95. break;
  96. case ERR_NONFATAL:
  97. yasm_error_set_va(YASM_ERROR_GENERAL, fmt, va);
  98. break;
  99. case ERR_FATAL:
  100. yasm_fatal(fmt, va);
  101. /*@notreached@*/
  102. break;
  103. case ERR_PANIC:
  104. yasm_internal_error(fmt); /* FIXME */
  105. break;
  106. case ERR_DEBUG:
  107. break;
  108. }
  109. va_end(va);
  110. yasm_errwarn_propagate(cur_errwarns,
  111. yasm_linemap_poke(cur_lm, nasm_src_get_fname(),
  112. (unsigned long)nasm_src_get_linnum()));
  113. }
  114. static yasm_preproc *
  115. nasm_preproc_create(const char *in_filename, yasm_symtab *symtab,
  116. yasm_linemap *lm, yasm_errwarns *errwarns)
  117. {
  118. FILE *f;
  119. yasm_preproc_nasm *preproc_nasm = yasm_xmalloc(sizeof(yasm_preproc_nasm));
  120. preproc_nasm->preproc.module = &yasm_nasm_LTX_preproc;
  121. if (strcmp(in_filename, "-") != 0) {
  122. f = fopen(in_filename, "r");
  123. if (!f)
  124. yasm__fatal_missing_input_file( N_("Could not open input file"), in_filename );
  125. }
  126. else
  127. f = stdin;
  128. preproc_nasm->in = f;
  129. nasm_symtab = symtab;
  130. cur_lm = lm;
  131. cur_errwarns = errwarns;
  132. preproc_deps = NULL;
  133. done_dep_preproc = 0;
  134. preproc_nasm->line = NULL;
  135. preproc_nasm->file_name = NULL;
  136. preproc_nasm->prior_linnum = 0;
  137. preproc_nasm->lineinc = 0;
  138. nasmpp.reset(f, in_filename, 2, nasm_efunc, nasm_evaluate, &nil_list);
  139. pp_extra_stdmac(nasm_version_mac);
  140. return (yasm_preproc *)preproc_nasm;
  141. }
  142. static void
  143. nasm_preproc_destroy(yasm_preproc *preproc)
  144. {
  145. yasm_preproc_nasm *preproc_nasm = (yasm_preproc_nasm *)preproc;
  146. nasmpp.cleanup(0);
  147. if (preproc_nasm->line)
  148. yasm_xfree(preproc_nasm->line);
  149. if (preproc_nasm->file_name)
  150. yasm_xfree(preproc_nasm->file_name);
  151. yasm_xfree(preproc);
  152. if (preproc_deps)
  153. yasm_xfree(preproc_deps);
  154. }
  155. static char *
  156. nasm_preproc_get_line(yasm_preproc *preproc)
  157. {
  158. yasm_preproc_nasm *preproc_nasm = (yasm_preproc_nasm *)preproc;
  159. long linnum;
  160. int altline;
  161. char *line;
  162. if (preproc_nasm->line) {
  163. char *retval = preproc_nasm->line;
  164. preproc_nasm->line = NULL;
  165. return retval;
  166. }
  167. line = nasmpp.getline();
  168. if (!line)
  169. {
  170. nasmpp.cleanup(1);
  171. return NULL; /* EOF */
  172. }
  173. linnum = preproc_nasm->prior_linnum += preproc_nasm->lineinc;
  174. altline = nasm_src_get(&linnum, &preproc_nasm->file_name);
  175. if (altline != 0) {
  176. preproc_nasm->lineinc =
  177. (altline != -1 || preproc_nasm->lineinc != 1);
  178. preproc_nasm->line = line;
  179. line = yasm_xmalloc(40+strlen(preproc_nasm->file_name));
  180. sprintf(line, "%%line %ld+%d %s", linnum,
  181. preproc_nasm->lineinc, preproc_nasm->file_name);
  182. preproc_nasm->prior_linnum = linnum;
  183. }
  184. return line;
  185. }
  186. void
  187. nasm_preproc_add_dep(char *name)
  188. {
  189. preproc_dep *dep;
  190. /* If not processing dependencies, simply return */
  191. if (!preproc_deps)
  192. return;
  193. /* Save in preproc_deps */
  194. dep = yasm_xmalloc(sizeof(preproc_dep));
  195. dep->name = yasm__xstrdup(name);
  196. STAILQ_INSERT_TAIL(preproc_deps, dep, link);
  197. }
  198. static size_t
  199. nasm_preproc_get_included_file(yasm_preproc *preproc, /*@out@*/ char *buf,
  200. size_t max_size)
  201. {
  202. if (!preproc_deps) {
  203. preproc_deps = yasm_xmalloc(sizeof(struct preproc_dep_head));
  204. STAILQ_INIT(preproc_deps);
  205. }
  206. for (;;) {
  207. char *line;
  208. /* Pull first dep out of preproc_deps and return it if there is one */
  209. if (!STAILQ_EMPTY(preproc_deps)) {
  210. char *name;
  211. preproc_dep *dep = STAILQ_FIRST(preproc_deps);
  212. STAILQ_REMOVE_HEAD(preproc_deps, link);
  213. name = dep->name;
  214. yasm_xfree(dep);
  215. strncpy(buf, name, max_size);
  216. buf[max_size-1] = '\0';
  217. yasm_xfree(name);
  218. return strlen(buf);
  219. }
  220. /* No more preprocessing to do */
  221. if (done_dep_preproc) {
  222. return 0;
  223. }
  224. /* Preprocess some more, throwing away the result */
  225. line = nasmpp.getline();
  226. if (line)
  227. yasm_xfree(line);
  228. else
  229. done_dep_preproc = 1;
  230. }
  231. }
  232. static void
  233. nasm_preproc_add_include_file(yasm_preproc *preproc, const char *filename)
  234. {
  235. pp_pre_include(filename);
  236. }
  237. static void
  238. nasm_preproc_predefine_macro(yasm_preproc *preproc, const char *macronameval)
  239. {
  240. char *mnv = yasm__xstrdup(macronameval);
  241. pp_pre_define(mnv);
  242. yasm_xfree(mnv);
  243. }
  244. static void
  245. nasm_preproc_undefine_macro(yasm_preproc *preproc, const char *macroname)
  246. {
  247. char *mn = yasm__xstrdup(macroname);
  248. pp_pre_undefine(mn);
  249. yasm_xfree(mn);
  250. }
  251. static void
  252. nasm_preproc_define_builtin(yasm_preproc *preproc, const char *macronameval)
  253. {
  254. char *mnv = yasm__xstrdup(macronameval);
  255. pp_builtin_define(mnv);
  256. yasm_xfree(mnv);
  257. }
  258. static void
  259. nasm_preproc_add_standard(yasm_preproc *preproc, const char **macros)
  260. {
  261. pp_extra_stdmac(macros);
  262. }
  263. /* Define preproc structure -- see preproc.h for details */
  264. yasm_preproc_module yasm_nasm_LTX_preproc = {
  265. "Real NASM Preprocessor",
  266. "nasm",
  267. nasm_preproc_create,
  268. nasm_preproc_destroy,
  269. nasm_preproc_get_line,
  270. nasm_preproc_get_included_file,
  271. nasm_preproc_add_include_file,
  272. nasm_preproc_predefine_macro,
  273. nasm_preproc_undefine_macro,
  274. nasm_preproc_define_builtin,
  275. nasm_preproc_add_standard
  276. };
  277. static yasm_preproc *
  278. tasm_preproc_create(const char *in_filename, yasm_symtab *symtab,
  279. yasm_linemap *lm, yasm_errwarns *errwarns)
  280. {
  281. tasm_compatible_mode = 1;
  282. return nasm_preproc_create(in_filename, symtab, lm, errwarns);
  283. }
  284. yasm_preproc_module yasm_tasm_LTX_preproc = {
  285. "Real TASM Preprocessor",
  286. "tasm",
  287. tasm_preproc_create,
  288. nasm_preproc_destroy,
  289. nasm_preproc_get_line,
  290. nasm_preproc_get_included_file,
  291. nasm_preproc_add_include_file,
  292. nasm_preproc_predefine_macro,
  293. nasm_preproc_undefine_macro,
  294. nasm_preproc_define_builtin,
  295. nasm_preproc_add_standard
  296. };