145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/*
245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Imported NASM preprocessor - glue code
345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *
445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *  Copyright (C) 2002-2007  Peter Johnson
545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *
645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Redistribution and use in source and binary forms, with or without
745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * modification, are permitted provided that the following conditions
845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * are met:
945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 1. Redistributions of source code must retain the above copyright
1045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *    notice, this list of conditions and the following disclaimer.
1145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 2. Redistributions in binary form must reproduce the above copyright
1245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *    notice, this list of conditions and the following disclaimer in the
1345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *    documentation and/or other materials provided with the distribution.
1445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *
1545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
1645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
1945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * POSSIBILITY OF SUCH DAMAGE.
2645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */
2745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <util.h>
2845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
2945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <libyasm.h>
3045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
3145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "nasm.h"
3245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "nasmlib.h"
3345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "nasm-pp.h"
3445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "nasm-eval.h"
3545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
3645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct yasm_preproc_nasm {
3745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_preproc_base preproc;   /* Base structure */
3845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
3945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    FILE *in;
4045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    char *line;
4145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    char *file_name;
4245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    long prior_linnum;
4345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    int lineinc;
4445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} yasm_preproc_nasm;
4545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_symtab *nasm_symtab;
4645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic yasm_linemap *cur_lm;
4745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic yasm_errwarns *cur_errwarns;
4845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgint tasm_compatible_mode = 0;
4945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgint tasm_locals;
5045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgconst char *tasm_segment;
5145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
5245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "nasm-version.c"
5345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
5445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct preproc_dep {
5545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    STAILQ_ENTRY(preproc_dep) link;
5645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    char *name;
5745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} preproc_dep;
5845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
5945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic STAILQ_HEAD(preproc_dep_head, preproc_dep) *preproc_deps;
6045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int done_dep_preproc;
6145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
6245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_preproc_module yasm_nasm_LTX_preproc;
6345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
6445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void
6545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgnil_listgen_init(char *p, efunc e)
6645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
6745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
6845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
6945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void
7045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgnil_listgen_cleanup(void)
7145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
7245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
7345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
7445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void
7545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgnil_listgen_output(long v, const void *d, unsigned long v2)
7645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
7745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
7845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
7945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void
8045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgnil_listgen_line(int v, char *p)
8145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
8245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
8345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
8445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void
8545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgnil_listgen_uplevel(int v)
8645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
8745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
8845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
8945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void
9045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgnil_listgen_downlevel(int v)
9145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
9245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
9345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
9445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic ListGen nil_list = {
9545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    nil_listgen_init,
9645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    nil_listgen_cleanup,
9745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    nil_listgen_output,
9845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    nil_listgen_line,
9945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    nil_listgen_uplevel,
10045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    nil_listgen_downlevel
10145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org};
10245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
10345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
10445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void
10545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgnasm_efunc(int severity, const char *fmt, ...)
10645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
10745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    va_list va;
10845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
10945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    va_start(va, fmt);
11045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    switch (severity & ERR_MASK) {
11145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        case ERR_WARNING:
11245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            yasm_warn_set_va(YASM_WARN_PREPROC, fmt, va);
11345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            break;
11445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        case ERR_NONFATAL:
11545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            yasm_error_set_va(YASM_ERROR_GENERAL, fmt, va);
11645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            break;
11745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        case ERR_FATAL:
11845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            yasm_fatal(fmt, va);
11945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            /*@notreached@*/
12045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            break;
12145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        case ERR_PANIC:
12245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            yasm_internal_error(fmt);   /* FIXME */
12345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            break;
12445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        case ERR_DEBUG:
12545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            break;
12645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
12745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    va_end(va);
12845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_errwarn_propagate(cur_errwarns,
12945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_linemap_poke(cur_lm, nasm_src_get_fname(),
13045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                          (unsigned long)nasm_src_get_linnum()));
13145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
13245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
13345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic yasm_preproc *
13445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgnasm_preproc_create(const char *in_filename, yasm_symtab *symtab,
13545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    yasm_linemap *lm, yasm_errwarns *errwarns)
13645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
13745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    FILE *f;
13845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_preproc_nasm *preproc_nasm = yasm_xmalloc(sizeof(yasm_preproc_nasm));
13945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
14045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    preproc_nasm->preproc.module = &yasm_nasm_LTX_preproc;
14145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
14245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (strcmp(in_filename, "-") != 0) {
14345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        f = fopen(in_filename, "r");
14445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (!f)
14545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            yasm__fatal( N_("Could not open input file") );
14645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
14745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    else
14845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        f = stdin;
14945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
15045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    preproc_nasm->in = f;
15145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    nasm_symtab = symtab;
15245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cur_lm = lm;
15345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    cur_errwarns = errwarns;
15445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    preproc_deps = NULL;
15545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    done_dep_preproc = 0;
15645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    preproc_nasm->line = NULL;
15745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    preproc_nasm->file_name = NULL;
15845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    preproc_nasm->prior_linnum = 0;
15945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    preproc_nasm->lineinc = 0;
16045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    nasmpp.reset(f, in_filename, 2, nasm_efunc, nasm_evaluate, &nil_list);
16145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
16245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    pp_extra_stdmac(nasm_version_mac);
16345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
16445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return (yasm_preproc *)preproc_nasm;
16545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
16645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
16745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void
16845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgnasm_preproc_destroy(yasm_preproc *preproc)
16945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
17045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_preproc_nasm *preproc_nasm = (yasm_preproc_nasm *)preproc;
17145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    nasmpp.cleanup(0);
17245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (preproc_nasm->line)
17345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_xfree(preproc_nasm->line);
17445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (preproc_nasm->file_name)
17545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_xfree(preproc_nasm->file_name);
17645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_xfree(preproc);
17745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (preproc_deps)
17845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_xfree(preproc_deps);
17945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
18045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
18145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic char *
18245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgnasm_preproc_get_line(yasm_preproc *preproc)
18345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
18445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_preproc_nasm *preproc_nasm = (yasm_preproc_nasm *)preproc;
18545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    long linnum;
18645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    int altline;
18745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    char *line;
18845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
18945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (preproc_nasm->line) {
19045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        char *retval = preproc_nasm->line;
19145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        preproc_nasm->line = NULL;
19245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return retval;
19345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
19445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
19545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    line = nasmpp.getline();
19645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (!line)
19745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    {
19845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        nasmpp.cleanup(1);
19945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return NULL;    /* EOF */
20045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
20145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
20245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    linnum = preproc_nasm->prior_linnum += preproc_nasm->lineinc;
20345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    altline = nasm_src_get(&linnum, &preproc_nasm->file_name);
20445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (altline != 0) {
20545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        preproc_nasm->lineinc =
20645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            (altline != -1 || preproc_nasm->lineinc != 1);
20745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        preproc_nasm->line = line;
20845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        line = yasm_xmalloc(40+strlen(preproc_nasm->file_name));
20945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        sprintf(line, "%%line %ld+%d %s", linnum,
21045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                preproc_nasm->lineinc, preproc_nasm->file_name);
21145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        preproc_nasm->prior_linnum = linnum;
21245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
21345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
21445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return line;
21545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
21645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
21745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid
21845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgnasm_preproc_add_dep(char *name)
21945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
22045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    preproc_dep *dep;
22145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
22245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* If not processing dependencies, simply return */
22345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (!preproc_deps)
22445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return;
22545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
22645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Save in preproc_deps */
22745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    dep = yasm_xmalloc(sizeof(preproc_dep));
22845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    dep->name = yasm__xstrdup(name);
22945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    STAILQ_INSERT_TAIL(preproc_deps, dep, link);
23045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
23145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
23245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic size_t
23345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgnasm_preproc_get_included_file(yasm_preproc *preproc, /*@out@*/ char *buf,
23445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                               size_t max_size)
23545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
23645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (!preproc_deps) {
23745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        preproc_deps = yasm_xmalloc(sizeof(struct preproc_dep_head));
23845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        STAILQ_INIT(preproc_deps);
23945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
24045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
24145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    for (;;) {
24245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        char *line;
24345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
24445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        /* Pull first dep out of preproc_deps and return it if there is one */
24545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (!STAILQ_EMPTY(preproc_deps)) {
24645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            char *name;
24745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            preproc_dep *dep = STAILQ_FIRST(preproc_deps);
24845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            STAILQ_REMOVE_HEAD(preproc_deps, link);
24945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            name = dep->name;
25045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            yasm_xfree(dep);
25145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            strncpy(buf, name, max_size);
25245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            buf[max_size-1] = '\0';
25345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            yasm_xfree(name);
25445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return strlen(buf);
25545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        }
25645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
25745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        /* No more preprocessing to do */
25845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (done_dep_preproc) {
25945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            return 0;
26045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        }
26145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
26245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        /* Preprocess some more, throwing away the result */
26345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        line = nasmpp.getline();
26445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        if (line)
26545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            yasm_xfree(line);
26645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        else
26745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            done_dep_preproc = 1;
26845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
26945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
27045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
27145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void
27245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgnasm_preproc_add_include_file(yasm_preproc *preproc, const char *filename)
27345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
27445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    pp_pre_include(filename);
27545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
27645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
27745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void
27845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgnasm_preproc_predefine_macro(yasm_preproc *preproc, const char *macronameval)
27945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
28045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    char *mnv = yasm__xstrdup(macronameval);
28145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    pp_pre_define(mnv);
28245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_xfree(mnv);
28345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
28445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
28545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void
28645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgnasm_preproc_undefine_macro(yasm_preproc *preproc, const char *macroname)
28745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
28845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    char *mn = yasm__xstrdup(macroname);
28945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    pp_pre_undefine(mn);
29045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_xfree(mn);
29145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
29245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
29345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void
29445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgnasm_preproc_define_builtin(yasm_preproc *preproc, const char *macronameval)
29545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
29645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    char *mnv = yasm__xstrdup(macronameval);
29745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    pp_builtin_define(mnv);
29845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_xfree(mnv);
29945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
30045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
30145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void
30245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgnasm_preproc_add_standard(yasm_preproc *preproc, const char **macros)
30345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
30445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    pp_extra_stdmac(macros);
30545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
30645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
30745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* Define preproc structure -- see preproc.h for details */
30845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_preproc_module yasm_nasm_LTX_preproc = {
30945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    "Real NASM Preprocessor",
31045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    "nasm",
31145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    nasm_preproc_create,
31245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    nasm_preproc_destroy,
31345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    nasm_preproc_get_line,
31445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    nasm_preproc_get_included_file,
31545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    nasm_preproc_add_include_file,
31645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    nasm_preproc_predefine_macro,
31745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    nasm_preproc_undefine_macro,
31845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    nasm_preproc_define_builtin,
31945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    nasm_preproc_add_standard
32045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org};
32145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
32245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic yasm_preproc *
32345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtasm_preproc_create(const char *in_filename, yasm_symtab *symtab,
32445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    yasm_linemap *lm, yasm_errwarns *errwarns)
32545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
32645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    tasm_compatible_mode = 1;
32745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return nasm_preproc_create(in_filename, symtab, lm, errwarns);
32845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
32945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
33045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_preproc_module yasm_tasm_LTX_preproc = {
33145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    "Real TASM Preprocessor",
33245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    "tasm",
33345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    tasm_preproc_create,
33445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    nasm_preproc_destroy,
33545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    nasm_preproc_get_line,
33645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    nasm_preproc_get_included_file,
33745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    nasm_preproc_add_include_file,
33845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    nasm_preproc_predefine_macro,
33945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    nasm_preproc_undefine_macro,
34045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    nasm_preproc_define_builtin,
34145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    nasm_preproc_add_standard
34245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org};
343