4 * Copyright (C) 2015 Alexander Andrejevic <theflash AT sdf DOT lonestar DOT org>
5 * Copyright (C) 2015, 2019, 2020 Jason Self <j@jxself.org>
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as
9 * published by the Free Software Foundation, either version 3 of the
10 * License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Affero General Public License for more details.
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>
20 * SPDX-License-Identifier: AGPL-3.0-or-later
32 //using namespace std;
37 //#include <strings.h>
46 //#include "opcodes.h"
48 //#include "directives.h"
50 //#include "compiler.h"
53 #include "include_all.h"
55 const int DEFAULT_ZVERSION = 6;
58 { ZVERSION = 11, ZORKID, ZSERIAL };
62 static struct option const long_options[] = {
63 {"help", no_argument, NULL, 'h'},
64 {"version", no_argument, NULL, 'V'},
65 {"output", required_argument, NULL, 'o'},
66 {"zversion", required_argument, NULL, ZVERSION},
67 {"zorkid", required_argument, NULL, ZORKID},
68 {"serial", required_argument, NULL, ZSERIAL},
83 int zversion; /* 0 - 8 */
84 int zorkid; /* 0 - 65535 */
85 char zserial[7]; /* YYMMDD */
86 Opcode_dict *opcode_dict;
90 CCompiler::get_arguments (int argc, char *argv[], char *envp[])
93 while ((opt = getopt_long (argc, argv, "hVo:", long_options, NULL)) != -1)
103 wrong_arg ("Output file must be given once\n");
104 m_output_file = optarg;
107 parse_intarg (&Config.zversion, "zversion", 1, 8, 1);
110 parse_intarg (&Config.zorkid, "zorkid", 0, 0xFFFF, 0);
120 int first_input_file = optind;
121 if (first_input_file >= argc)
122 wrong_arg ("Missing input file\n");
124 m_output_file = build_output_filename (argv[first_input_file], ".dat");
126 // TODO: Everything :)
129 printf ("Input files:\n");
130 for (int i = optind; i < argc; i++)
131 printf ("\t%s\n", argv[i]);
133 printf ("Output file: %s\n\n", m_output_file);
138 "- ZSerial: %s\n", Config.zversion, Config.zorkid, Config.zserial);
144 CCompiler::wrong_arg (const char *err, ...)
150 vfprintf (stderr, err, ap);
153 fprintf (stderr, "Try `" PACKAGE_NAME " --help' for more information.\n");
159 CCompiler::print_version ()
161 printf (PACKAGE_STRING "\n"
162 "License AGPLv3+: GNU AGPL version 3 or later\n"
163 "<http://gnu.org/licenses/agpl.html>\n"
164 "This is free software: you are free to change and redistribute it.\n"
165 "There is NO WARRANTY, to the extent permitted by law.\n");
171 CCompiler::print_usage (int failed)
173 printf ("Usage: " PACKAGE_NAME " [OPTION...] [FILES...]\n"
175 "--version Display program version and exit\n"
176 "--help Display this help\n"
178 "--zversion (accepts numbers 1 - 8, defaults to %d if not specified)\n"
179 "--zorkid (integer between 0 and 65535, defaults to 0 if not specified)\n"
180 "--serial (six characters of ASCII, defaults to current date\n"
181 " in the form YYMMDD if not specified)\n",
187 CCompiler::fill_zserial (void)
192 timeinfo = localtime (&t);
193 strftime (Config.zserial, sizeof (Config.zserial), "%y%m%d", timeinfo);
198 CCompiler::fill_config (void)
200 bzero (&Config, sizeof (Config));
201 Config.zversion = DEFAULT_ZVERSION;
207 CCompiler::parse_intarg (int *dest, const char name[], int min, int max,
215 int n = atoi (optarg);
216 if (n >= min && n <= max)
221 wrong_arg ("Wrong %s value %s, must be integer between %d and %d\n",
222 name, optarg, min, max);
227 CCompiler::parse_zserial (void)
234 size_t n = strlen (optarg);
235 if (n == sizeof (Config.zserial) - 1)
238 while (*p && isalnum (*p))
241 { /* ..optarg contains alphanumeric only? */
242 strncpy (Config.zserial, optarg, sizeof (Config.zserial));
246 wrong_arg ("Wrong zserial value %s, must be 6 ascii characters\n", optarg);
251 CCompiler::new_file_suffix (char *result, size_t maxlen, const char *src,
252 const char *newsuffix)
254 strncpy (result, src, maxlen);
255 char *p = strrchr (result, '.');
256 if (p && strchr (p, '/'))
260 strncpy (p, newsuffix, maxlen - (p - result));
264 strncat (result, newsuffix, maxlen);
271 CCompiler::build_output_filename (const char basename[], const char *suffix)
273 int n = strlen (basename) + strlen (suffix);
274 char *ofile = (char *) malloc (n + 1); /* todo!!! check for NULL. free. */
275 new_file_suffix (ofile, n, basename, suffix);
289 CCompiler::output_code_section ()
296 main (int argc, char *argv[], char *envp[])
300 compiler.fill_config ();
301 compiler.get_arguments (argc, argv, envp);
302 init_opcodes (Config.zversion, 0);
305 //for (int i = optind; i < argc; i++)
306 // parse_file(argv[i]);
308 string file_name = argv[optind];
312 char delimeter = '\\';
314 char delimeter = '/';
317 if (file_name.rfind(delimeter) == string::npos)
319 pc.current_directory = "";
320 pc.current_file_name = file_name;
324 pc.current_directory = file_name.substr(0, file_name.rfind(delimeter)+1);
325 pc.current_file_name = file_name.substr(file_name.rfind(delimeter)+1);
327 g_parsing_contexts.push(pc);
329 compiler.parser.parse_file();// argv[optind]);
330 if ( !compiler.parser.have_errors())
331 compiler.assembly ();
333 /* TODO! List global symbols */
334 /* TODO! Find abbreviations */