1d8f6b0edSMasatake YAMATO /*
2d8f6b0edSMasatake YAMATO * Copyright (c) 2020, Masatake YAMATO
3d8f6b0edSMasatake YAMATO * Copyright (c) 2020, Red Hat, Inc.
4d8f6b0edSMasatake YAMATO *
5d8f6b0edSMasatake YAMATO * This source code is released for free distribution under the terms of the
6d8f6b0edSMasatake YAMATO * GNU General Public License version 2 or (at your option) any later version.
7d8f6b0edSMasatake YAMATO */
8d8f6b0edSMasatake YAMATO
9d8f6b0edSMasatake YAMATO #include "general.h"
10d8f6b0edSMasatake YAMATO
11d8f6b0edSMasatake YAMATO #include "optscript.h"
12d8f6b0edSMasatake YAMATO #include "mio.h"
13d8f6b0edSMasatake YAMATO #include "routines.h"
14d8f6b0edSMasatake YAMATO
15d8f6b0edSMasatake YAMATO #include <string.h>
16d8f6b0edSMasatake YAMATO #include <stdlib.h>
17d8f6b0edSMasatake YAMATO
18d8f6b0edSMasatake YAMATO static void
help(const char * progname,int exit_status)19d8f6b0edSMasatake YAMATO help (const char* progname, int exit_status)
20d8f6b0edSMasatake YAMATO {
21d8f6b0edSMasatake YAMATO FILE *out = stderr;
22d8f6b0edSMasatake YAMATO if (exit_status == 0)
23d8f6b0edSMasatake YAMATO out = stdout;
24d8f6b0edSMasatake YAMATO
25d8f6b0edSMasatake YAMATO fprintf (out, "Usage: %s [options] [file|-]\n\n", progname);
26*949ffdd1SMasatake YAMATO fputs ( " -h|--help Print this option summary\n", out);
27d8f6b0edSMasatake YAMATO fputs ( " -l|--list-operators List built-in operators\n", out);
28d8f6b0edSMasatake YAMATO fputs ( " -e|--eval CODE Evaluate the CODE\n", out);
29d8f6b0edSMasatake YAMATO fputc ('\n', out);
30d8f6b0edSMasatake YAMATO exit (exit_status);
31d8f6b0edSMasatake YAMATO }
32d8f6b0edSMasatake YAMATO
33d8f6b0edSMasatake YAMATO static EsObject*
op_renew(OptVM * vm,EsObject * name)34d8f6b0edSMasatake YAMATO op_renew (OptVM *vm, EsObject *name)
35d8f6b0edSMasatake YAMATO {
36d8f6b0edSMasatake YAMATO bool *app_data = opt_vm_get_app_data (vm);
37d8f6b0edSMasatake YAMATO *app_data = true;
38d8f6b0edSMasatake YAMATO return OPT_ERR_QUIT;
39d8f6b0edSMasatake YAMATO }
40d8f6b0edSMasatake YAMATO
41d8f6b0edSMasatake YAMATO int
optscript_run(OptVM * vm,char * prompt,void * app_data)42d8f6b0edSMasatake YAMATO optscript_run (OptVM *vm, char *prompt, void *app_data)
43d8f6b0edSMasatake YAMATO {
44d8f6b0edSMasatake YAMATO int r = 0;
45d8f6b0edSMasatake YAMATO void *old_app_data = opt_vm_set_app_data (vm, app_data);
46d8f6b0edSMasatake YAMATO char *old_prompt = opt_vm_set_prompt (vm, prompt);
47d8f6b0edSMasatake YAMATO
48d8f6b0edSMasatake YAMATO opt_vm_print_prompt (vm);
49d8f6b0edSMasatake YAMATO
50d8f6b0edSMasatake YAMATO while (true)
51d8f6b0edSMasatake YAMATO {
52d8f6b0edSMasatake YAMATO EsObject *o = opt_vm_read (vm, NULL);
53d8f6b0edSMasatake YAMATO if (es_object_equal (o, ES_READER_EOF))
54d8f6b0edSMasatake YAMATO {
55d8f6b0edSMasatake YAMATO es_object_unref (o);
56d8f6b0edSMasatake YAMATO break;
57d8f6b0edSMasatake YAMATO }
58d8f6b0edSMasatake YAMATO EsObject *e = opt_vm_eval (vm, o);
59d8f6b0edSMasatake YAMATO es_object_unref (o);
60d8f6b0edSMasatake YAMATO
61d8f6b0edSMasatake YAMATO if (es_error_p (e))
62d8f6b0edSMasatake YAMATO {
63d8f6b0edSMasatake YAMATO if (!es_object_equal (e, OPT_ERR_QUIT))
64d8f6b0edSMasatake YAMATO {
65d8f6b0edSMasatake YAMATO opt_vm_report_error (vm, e, NULL);
66d8f6b0edSMasatake YAMATO r = 1;
67d8f6b0edSMasatake YAMATO }
68d8f6b0edSMasatake YAMATO break;
69d8f6b0edSMasatake YAMATO }
70d8f6b0edSMasatake YAMATO }
71d8f6b0edSMasatake YAMATO
72d8f6b0edSMasatake YAMATO opt_vm_set_prompt (vm, old_prompt);
73d8f6b0edSMasatake YAMATO opt_vm_set_app_data (vm, old_app_data);
74d8f6b0edSMasatake YAMATO return r;
75d8f6b0edSMasatake YAMATO }
76d8f6b0edSMasatake YAMATO
77d8f6b0edSMasatake YAMATO int
main(int argc,char ** argv)78d8f6b0edSMasatake YAMATO main(int argc, char **argv)
79d8f6b0edSMasatake YAMATO {
80d8f6b0edSMasatake YAMATO MIO *in = NULL;
81d8f6b0edSMasatake YAMATO const char *file = NULL;
82d8f6b0edSMasatake YAMATO bool help_ops = false;
83d8f6b0edSMasatake YAMATO
84d8f6b0edSMasatake YAMATO for (int i = 1; i < argc; i++)
85d8f6b0edSMasatake YAMATO {
86d8f6b0edSMasatake YAMATO if (strcmp (argv[i], "-h") == 0
87d8f6b0edSMasatake YAMATO || strcmp (argv[i], "--help") == 0)
88d8f6b0edSMasatake YAMATO help (argv[0], 0);
89d8f6b0edSMasatake YAMATO else if (strcmp (argv[i], "-l") == 0
90d8f6b0edSMasatake YAMATO || strcmp (argv[i], "--list-operators") == 0)
91d8f6b0edSMasatake YAMATO help_ops = true;
92d8f6b0edSMasatake YAMATO else if (strcmp (argv[i], "-e") == 0
93d8f6b0edSMasatake YAMATO || strcmp (argv[i], "--eval") == 0)
94d8f6b0edSMasatake YAMATO {
95d8f6b0edSMasatake YAMATO if (file)
96d8f6b0edSMasatake YAMATO {
97d8f6b0edSMasatake YAMATO fprintf (stderr, "Don't specify multiple input: %s, %s\n",
98d8f6b0edSMasatake YAMATO file, argv[i]);
99d8f6b0edSMasatake YAMATO exit (2);
100d8f6b0edSMasatake YAMATO }
101d8f6b0edSMasatake YAMATO
102d8f6b0edSMasatake YAMATO if (i == argc -1)
103d8f6b0edSMasatake YAMATO {
104d8f6b0edSMasatake YAMATO fprintf (stderr, "no code for %s\n", argv[i]);
105d8f6b0edSMasatake YAMATO exit (2);
106d8f6b0edSMasatake YAMATO }
107d8f6b0edSMasatake YAMATO file = "<cmdline>";
108d8f6b0edSMasatake YAMATO i++;
109d8f6b0edSMasatake YAMATO in = mio_new_memory ((unsigned char *)eStrdup(argv[i]), strlen (argv[i]), eRealloc, eFree);
110d8f6b0edSMasatake YAMATO if (!in)
111d8f6b0edSMasatake YAMATO {
112d8f6b0edSMasatake YAMATO fprintf (stderr, "failed to create mio from memory\n");
113d8f6b0edSMasatake YAMATO exit (1);
114d8f6b0edSMasatake YAMATO }
115d8f6b0edSMasatake YAMATO }
116d8f6b0edSMasatake YAMATO else if (argv[i][0] == '-' && argv[i][1] == '\0')
117d8f6b0edSMasatake YAMATO {
118d8f6b0edSMasatake YAMATO if (file)
119d8f6b0edSMasatake YAMATO {
120d8f6b0edSMasatake YAMATO fprintf (stderr, "Don't specify multiple input: %s, %s\n",
121d8f6b0edSMasatake YAMATO file, argv[i]);
122d8f6b0edSMasatake YAMATO exit (2);
123d8f6b0edSMasatake YAMATO }
124d8f6b0edSMasatake YAMATO
125d8f6b0edSMasatake YAMATO file = "<stdin>";
126d8f6b0edSMasatake YAMATO in = mio_new_fp (stdin, NULL);
127d8f6b0edSMasatake YAMATO if (!in)
128d8f6b0edSMasatake YAMATO {
129d8f6b0edSMasatake YAMATO fprintf (stderr, "failed to use <stdin>\n");
130d8f6b0edSMasatake YAMATO exit (1);
131d8f6b0edSMasatake YAMATO }
132d8f6b0edSMasatake YAMATO }
133d8f6b0edSMasatake YAMATO else if (argv[i][0] == '-')
134d8f6b0edSMasatake YAMATO {
135d8f6b0edSMasatake YAMATO fprintf (stderr, "unknown option: %s\n", argv[i]);
136d8f6b0edSMasatake YAMATO exit (2);
137d8f6b0edSMasatake YAMATO }
138d8f6b0edSMasatake YAMATO else if (in)
139d8f6b0edSMasatake YAMATO {
140d8f6b0edSMasatake YAMATO fprintf (stderr, "too many arugments\n");
141d8f6b0edSMasatake YAMATO mio_unref (in);
142d8f6b0edSMasatake YAMATO exit (2);
143d8f6b0edSMasatake YAMATO }
144d8f6b0edSMasatake YAMATO else
145d8f6b0edSMasatake YAMATO {
146d8f6b0edSMasatake YAMATO if (file)
147d8f6b0edSMasatake YAMATO {
148d8f6b0edSMasatake YAMATO fprintf (stderr, "Don't specify multiple input: %s, %s\n",
149d8f6b0edSMasatake YAMATO file, argv[i]);
150d8f6b0edSMasatake YAMATO exit (2);
151d8f6b0edSMasatake YAMATO }
152d8f6b0edSMasatake YAMATO
153d8f6b0edSMasatake YAMATO file = argv[i];
154d8f6b0edSMasatake YAMATO in = mio_new_file (file, "r");
155d8f6b0edSMasatake YAMATO if (!in)
156d8f6b0edSMasatake YAMATO {
157d8f6b0edSMasatake YAMATO fprintf (stderr, "failed to open: %s\n", file);
158d8f6b0edSMasatake YAMATO exit (1);
159d8f6b0edSMasatake YAMATO }
160d8f6b0edSMasatake YAMATO }
161d8f6b0edSMasatake YAMATO }
162d8f6b0edSMasatake YAMATO
163d8f6b0edSMasatake YAMATO opt_init ();
164d8f6b0edSMasatake YAMATO
165d8f6b0edSMasatake YAMATO if (!in)
166d8f6b0edSMasatake YAMATO in = mio_new_fp (stdin, NULL);
167d8f6b0edSMasatake YAMATO if (in == NULL)
168d8f6b0edSMasatake YAMATO {
169d8f6b0edSMasatake YAMATO fprintf (stderr, "failed to open input stream\n");
170d8f6b0edSMasatake YAMATO exit (1);
171d8f6b0edSMasatake YAMATO }
172d8f6b0edSMasatake YAMATO
173d8f6b0edSMasatake YAMATO MIO *out = mio_new_fp (stdout, NULL);
174d8f6b0edSMasatake YAMATO if (!out)
175d8f6b0edSMasatake YAMATO {
176d8f6b0edSMasatake YAMATO mio_unref (in);
177d8f6b0edSMasatake YAMATO fprintf (stderr, "failed to open output stream\n");
178d8f6b0edSMasatake YAMATO exit (1);
179d8f6b0edSMasatake YAMATO }
180d8f6b0edSMasatake YAMATO MIO *err = mio_new_fp (stderr, NULL);
181d8f6b0edSMasatake YAMATO if (!err)
182d8f6b0edSMasatake YAMATO {
183d8f6b0edSMasatake YAMATO mio_unref (out);
184d8f6b0edSMasatake YAMATO mio_unref (in);
185d8f6b0edSMasatake YAMATO fprintf (stderr, "failed to open error stream\n");
186d8f6b0edSMasatake YAMATO exit (1);
187d8f6b0edSMasatake YAMATO }
188d8f6b0edSMasatake YAMATO
189d8f6b0edSMasatake YAMATO OptVM *vm = opt_vm_new (in, out, err);
190d8f6b0edSMasatake YAMATO
191d8f6b0edSMasatake YAMATO int r;
192d8f6b0edSMasatake YAMATO
193d8f6b0edSMasatake YAMATO EsObject *dict = opt_dict_new (47);
194d8f6b0edSMasatake YAMATO {
195d8f6b0edSMasatake YAMATO EsObject *op;
196d8f6b0edSMasatake YAMATO EsObject *sym;
197d8f6b0edSMasatake YAMATO
198d8f6b0edSMasatake YAMATO op = opt_operator_new (op_renew, "_renew", 0, ":clear the state of vm%- _RENEW -");
199d8f6b0edSMasatake YAMATO sym = es_symbol_intern ("_renew");
200d8f6b0edSMasatake YAMATO opt_dict_def (dict, sym, op);
201d8f6b0edSMasatake YAMATO es_object_unref (op);
202d8f6b0edSMasatake YAMATO }
203d8f6b0edSMasatake YAMATO
204d8f6b0edSMasatake YAMATO opt_vm_dstack_push (vm, dict);
205d8f6b0edSMasatake YAMATO if (help_ops)
206d8f6b0edSMasatake YAMATO r = opt_vm_help (vm, NULL, NULL, NULL);
207d8f6b0edSMasatake YAMATO else
208d8f6b0edSMasatake YAMATO {
209d8f6b0edSMasatake YAMATO bool renew = false;
210d8f6b0edSMasatake YAMATO renew:
211d8f6b0edSMasatake YAMATO r = optscript_run (vm, file? NULL: "OPT", &renew);
212d8f6b0edSMasatake YAMATO if (renew)
213d8f6b0edSMasatake YAMATO {
214d8f6b0edSMasatake YAMATO opt_vm_clear (vm);
215d8f6b0edSMasatake YAMATO opt_vm_dstack_push (vm, dict);
216d8f6b0edSMasatake YAMATO renew = false;
217d8f6b0edSMasatake YAMATO goto renew;
218d8f6b0edSMasatake YAMATO }
219d8f6b0edSMasatake YAMATO }
220d8f6b0edSMasatake YAMATO es_object_unref (dict);
221d8f6b0edSMasatake YAMATO
222d8f6b0edSMasatake YAMATO opt_vm_delete (vm);
223d8f6b0edSMasatake YAMATO
224d8f6b0edSMasatake YAMATO mio_unref (err);
225d8f6b0edSMasatake YAMATO mio_unref (out);
226d8f6b0edSMasatake YAMATO mio_unref (in);
227d8f6b0edSMasatake YAMATO
228d8f6b0edSMasatake YAMATO return r;
229d8f6b0edSMasatake YAMATO }
230