1/*
2 * YASM module loader
3 *
4 *  Copyright (C) 2004-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
32typedef struct module {
33    const char *keyword;            /* module keyword */
34    void *data;                     /* associated data */
35} module;
36
37EXTERN_LIST
38
39static module arch_modules[] = {
40MODULES_arch_
41};
42
43static module dbgfmt_modules[] = {
44MODULES_dbgfmt_
45};
46
47static module objfmt_modules[] = {
48MODULES_objfmt_
49};
50
51static module listfmt_modules[] = {
52MODULES_listfmt_
53};
54
55static module parser_modules[] = {
56MODULES_parser_
57};
58
59static module preproc_modules[] = {
60MODULES_preproc_
61};
62
63static struct {
64    module *m;
65    size_t n;
66} module_types[] = {
67    {arch_modules, sizeof(arch_modules)/sizeof(module)},
68    {dbgfmt_modules, sizeof(dbgfmt_modules)/sizeof(module)},
69    {objfmt_modules, sizeof(objfmt_modules)/sizeof(module)},
70    {listfmt_modules, sizeof(listfmt_modules)/sizeof(module)},
71    {parser_modules, sizeof(parser_modules)/sizeof(module)},
72    {preproc_modules, sizeof(preproc_modules)/sizeof(module)},
73};
74
75typedef struct loaded_module {
76    yasm_module_type type;          /* module type */
77    const char *keyword;            /* module keyword */
78    void *data;                     /* associated data */
79} loaded_module;
80
81static loaded_module *loaded_modules = NULL;
82static size_t num_loaded_modules = 0;
83
84void *
85yasm_load_module(yasm_module_type type, const char *keyword)
86{
87    size_t i;
88    module *modules;
89    size_t n;
90
91    /* Look for the module/symbol, first in loaded modules */
92    if (loaded_modules) {
93        for (i=0; i<num_loaded_modules; i++) {
94            if (loaded_modules[i].type == type &&
95                yasm__strcasecmp(loaded_modules[i].keyword, keyword) == 0)
96                return loaded_modules[i].data;
97        }
98    }
99
100    modules = module_types[type].m;
101    n = module_types[type].n;
102    for (i=0; i<n; i++) {
103        if (yasm__strcasecmp(modules[i].keyword, keyword) == 0)
104            return modules[i].data;
105    }
106
107    return NULL;
108}
109
110void
111yasm_register_module(yasm_module_type type, const char *keyword, void *data)
112{
113    loaded_modules =
114        yasm_xrealloc(loaded_modules,
115                      (num_loaded_modules+1)*sizeof(loaded_module));
116    loaded_modules[num_loaded_modules].type = type;
117    loaded_modules[num_loaded_modules].keyword = keyword;
118    loaded_modules[num_loaded_modules].data = data;
119    num_loaded_modules++;
120}
121
122static void
123yasm_list_one_module(yasm_module_type type, void *data,
124                     void (*printfunc) (const char *name, const char *keyword))
125{
126    yasm_arch_module *arch;
127    yasm_dbgfmt_module *dbgfmt;
128    yasm_objfmt_module *objfmt;
129    yasm_listfmt_module *listfmt;
130    yasm_parser_module *parser;
131    yasm_preproc_module *preproc;
132
133    switch (type) {
134        case YASM_MODULE_ARCH:
135            arch = data;
136            printfunc(arch->name, arch->keyword);
137            break;
138        case YASM_MODULE_DBGFMT:
139            dbgfmt = data;
140            printfunc(dbgfmt->name, dbgfmt->keyword);
141            break;
142        case YASM_MODULE_OBJFMT:
143            objfmt = data;
144            printfunc(objfmt->name, objfmt->keyword);
145            break;
146        case YASM_MODULE_LISTFMT:
147            listfmt = data;
148            printfunc(listfmt->name, listfmt->keyword);
149            break;
150        case YASM_MODULE_PARSER:
151            parser = data;
152            printfunc(parser->name, parser->keyword);
153            break;
154        case YASM_MODULE_PREPROC:
155            preproc = data;
156            printfunc(preproc->name, preproc->keyword);
157            break;
158    }
159}
160
161void
162yasm_list_modules(yasm_module_type type,
163                  void (*printfunc) (const char *name, const char *keyword))
164{
165    size_t i;
166    module *modules;
167    size_t n;;
168
169    /* Go through available list, and try to load each one */
170    if (loaded_modules) {
171        for (i=0; i<num_loaded_modules; i++)
172            yasm_list_one_module(type, loaded_modules[i].data, printfunc);
173    }
174
175    modules = module_types[type].m;
176    n = module_types[type].n;
177    for (i=0; i<n; i++)
178        yasm_list_one_module(type, modules[i].data, printfunc);
179}
180