Added error messages displaying using source file name and line number
[zilutils.git] / zilasm / directives.cpp
1 /*
2  * directives.c -- part of ZilUtils/ZilAsm
3  *
4  * Copyright (C) 2016, 2020 Jason Self <j@jxself.org>
5  *
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.
10  *
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.
15  *
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/>
18  *
19  * SPDX-License-Identifier: AGPL-3.0-or-later
20  */
21
22 #include <stdlib.h>             /* bsearch */
23 #include <string.h>             /* strcmp */
24 #include <stdio.h>
25 #include <stack>
26 #include <string>
27 using namespace std;
28
29 #include "header.h"
30 #include "parser.h"
31 #include "directives.h"
32
33 #define ARRAY_SIZE(x)  ((sizeof(x)) / (sizeof(x[0])))
34
35 int g_stopParsing = 0;
36 stack<FILE*> g_fileHandlers;
37
38
39
40 static int
41 byte_handler (const char *args)
42 {
43   /* !!! TODO !!! */
44   return 0;
45 }
46
47 static int
48 end_handler (const char *args)
49 {
50         g_stopParsing = 1;
51         return 0;
52 }
53
54 static int
55 endi_handler (const char *args)
56 {
57   /* !!! TODO !!! */
58   return 0;
59 }
60
61 static int
62 endt_handler (const char *args)
63 {
64   /* !!! TODO !!! */
65   return 0;
66 }
67
68 static int
69 fstr_handler (const char *args)
70 {
71   /* !!! TODO !!! */
72   return 0;
73 }
74
75 static int
76 funct_handler (const char *args)
77 {
78   /* !!! TODO !!! */
79   return 0;
80 }
81
82 static int
83 gstr_handler (const char *args)
84 {
85   /* !!! TODO !!! */
86   return 0;
87 }
88
89 static int
90 gvar_handler (const char *args)
91 {
92   /* !!! TODO !!! */
93   return 0;
94 }
95
96 static int
97 insert_handler (const char *args)
98 {
99         string file_name;
100         char *p = (char*)args;
101         while (*p == ' ') p++;
102
103         if (*p == '"')
104         {
105                 p++;
106                 do
107                 {
108                         file_name += *p;
109                         p++;
110                 }
111                 while (*p != '"' && *p != 0 ) ;
112         }
113         else
114         {
115                 do
116                 {
117                         file_name += *p;
118                         p++;
119                 } while (*p != ' ' && *p != '\n' && *p != '\r' && *p != '\t' && *p != 0);
120         }
121         
122         if (file_name.find('.') == string::npos)
123         {
124                 file_name += ".zap";
125         }
126
127 #ifdef WIN32
128         char delimeter = '\\';
129 #else
130         char delimeter = '/';
131 #endif
132
133         Parsing_Context pc;
134         if (file_name.rfind(delimeter) == string::npos)
135         {
136                 pc.current_directory = "";
137                 pc.current_file_name = file_name;
138         }
139         else
140         {
141                 pc.current_directory = file_name.substr(0, file_name.rfind(delimeter)+1);
142                 pc.current_file_name = file_name.substr(file_name.rfind(delimeter)+1);
143         }
144
145         pc.current_directory = g_parsing_contexts.top().current_directory + pc.current_directory;
146         //pc.current_file_name = s;
147         g_parsing_contexts.push(pc);
148         
149         
150         unsigned saveLineNumber = g_currentLineNumber;
151         parse_file(); //s.c_str());
152         g_currentLineNumber = saveLineNumber;
153         return strlen(args);
154 }
155
156 static int
157 len_handler (const char *args)
158 {
159   /* !!! TODO !!! */
160   return 0;
161 }
162
163 static int
164 newdirective_handler (const char *args)
165 {
166   /* !!! TODO !!! */
167   return 0;
168 }
169
170 static int
171 object_handler (const char *args)
172 {
173   /* !!! TODO !!! */
174   return 0;
175 }
176
177 static int
178 prop_handler (const char *args)
179 {
180   /* !!! TODO !!! */
181   return 0;
182 }
183
184 static int
185 str_handler (const char *args)
186 {
187   /* !!! TODO !!! */
188   return 0;
189 }
190
191 static int
192 strl_handler (const char *args)
193 {
194   /* !!! TODO !!! */
195   return 0;
196 }
197
198 static int
199 table_handler (const char *args)
200 {
201   /* !!! TODO !!! */
202   return 0;
203 }
204
205 static int
206 vocbeg_handler (const char *args)
207 {
208   /* !!! TODO !!! */
209   return 0;
210 }
211
212 static int
213 vocend_handler (const char *args)
214 {
215   /* !!! TODO !!! */
216   return 0;
217 }
218
219 static int
220 word_handler (const char *args)
221 {
222   /* !!! TODO !!! */
223   return 0;
224 }
225
226 static int
227 zword_handler (const char *args)
228 {
229   /* !!! TODO !!! */
230   return 0;
231 }
232
233 // Sorted array
234 static Directive Directives[] = {
235   "BYTE", byte_handler,
236   "END", end_handler,
237   "ENDI", endi_handler,
238   "ENDT", endt_handler,
239   "FSTR", fstr_handler,
240   "FUNCT", funct_handler,
241   "GSTR", gstr_handler,
242   "GVAR", gvar_handler,
243   "INSERT", insert_handler,
244   "LEN", len_handler,
245   "NEW", newdirective_handler,
246   "OBJECT", object_handler,
247   "PROP", prop_handler,
248   "STR", str_handler,
249   "STRL", strl_handler,
250   "TABLE", table_handler,
251   "VOCBEG", vocbeg_handler,
252   "VOCEND", vocend_handler,
253   "WORD", word_handler,
254   "ZWORD", zword_handler
255 };
256
257 typedef struct
258 {
259   const char *contents;
260   unsigned length;
261 } Name;
262
263 static int
264 namecmp (const void *key, const void *elem)
265 {
266   const Name *p = (Name *) key;
267   const Directive *d = (Directive *) elem;
268
269   int len1 = p->length;
270   int len2 = strlen (d->name);
271
272   int rc = memcmp (p->contents, elem, len1 < len2 ? len1 : len2);
273   return rc ? rc : (len1 - len2);
274 }
275
276 Directive_handler
277 directive_lookup (const char *name, unsigned namelen)
278 {
279   Name n = { name, namelen };
280   Directive *p =
281     (Directive *) bsearch (&n, Directives, ARRAY_SIZE (Directives),
282                            sizeof (Directive), namecmp);
283   return p ? p->handler : NULL;
284 }