2 * directives.c -- part of ZilUtils/ZilAsm
4 * Copyright (C) 2016, 2020 Jason Self <j@jxself.org>
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Affero General Public License as
8 * published by the Free Software Foundation, either version 3 of the
9 * License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Affero General Public License for more details.
16 * You should have received a copy of the GNU Affero General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>
19 * SPDX-License-Identifier: AGPL-3.0-or-later
22 #include "include_all.h"
24 #define ARRAY_SIZE(x) ((sizeof(x)) / (sizeof(x[0])))
26 int g_stopParsing = 0;
27 stack<FILE*> g_fileHandlers;
32 byte_handler (const char *args, CParser* parser)
39 end_handler (const char *args, CParser* parser)
46 endi_handler (const char *args, CParser* parser)
53 endt_handler (const char *args, CParser* parser)
60 fstr_handler (const char *args, CParser* parser)
67 funct_handler (const char *args, CParser* parser)
71 parser->add_function(args);
76 gstr_handler (const char *args, CParser* parser)
83 gvar_handler (const char *args, CParser* parser)
90 insert_handler (const char *args, CParser* parser)
93 char *p = (char*)args;
94 while (*p == ' ') p++;
104 while (*p != '"' && *p != 0 ) ;
112 } while (*p != ' ' && *p != '\n' && *p != '\r' && *p != '\t' && *p != 0);
115 if (file_name.find('.') == string::npos)
121 char delimeter = '\\';
123 char delimeter = '/';
127 if (file_name.rfind(delimeter) == string::npos)
129 pc.current_directory = "";
130 pc.current_file_name = file_name;
134 pc.current_directory = file_name.substr(0, file_name.rfind(delimeter)+1);
135 pc.current_file_name = file_name.substr(file_name.rfind(delimeter)+1);
138 pc.current_directory = g_parsing_contexts.top().current_directory + pc.current_directory;
139 //pc.current_file_name = s;
140 g_parsing_contexts.push(pc);
142 unsigned saveLineNumber = parser->m_current_line_number;
143 parser->parse_file(); //s.c_str());
144 parser->m_current_line_number = saveLineNumber;
149 len_handler (const char *args, CParser* parser)
156 newdirective_handler (const char *args, CParser* parser)
163 object_handler (const char *args, CParser* parser)
170 prop_handler (const char *args, CParser* parser)
177 str_handler (const char *args, CParser* parser)
184 strl_handler (const char *args, CParser* parser)
191 table_handler (const char *args, CParser* parser)
198 vocbeg_handler (const char *args, CParser* parser)
205 vocend_handler (const char *args, CParser* parser)
212 word_handler (const char *args, CParser* parser)
219 zword_handler (const char *args, CParser* parser)
229 const char *contents;
234 namecmp (const void *key, const void *elem)
236 const Name *p = (Name *) key;
237 const Directive *d = (Directive *) elem;
239 int len1 = p->length;
240 int len2 = strlen (d->name);
242 int rc = memcmp (p->contents, elem, len1 < len2 ? len1 : len2);
243 return rc ? rc : (len1 - len2);
247 CDirectives::directive_lookup (const char *name, unsigned namelen)
250 static Directive Directives[] = {
251 "BYTE", byte_handler,
253 "ENDI", endi_handler,
254 "ENDT", endt_handler,
255 "FSTR", fstr_handler,
256 "FUNCT", funct_handler,
257 "GSTR", gstr_handler,
258 "GVAR", gvar_handler,
259 "INSERT", insert_handler,
261 "NEW", newdirective_handler,
262 "OBJECT", object_handler,
263 "PROP", prop_handler,
265 "STRL", strl_handler,
266 "TABLE", table_handler,
267 "VOCBEG", vocbeg_handler,
268 "VOCEND", vocend_handler,
269 "WORD", word_handler,
270 "ZWORD", zword_handler
273 Name n = { name, namelen };
275 (Directive *) bsearch (&n, Directives, ARRAY_SIZE (Directives),
276 sizeof (Directive), namecmp);
277 return p ? p->handler : NULL;
281 CDirectives::CDirectives(CParser *parser) :m_parser(parser)