1 /*
2 * Copyright (c) 2021, Masatake YAMATO
3 * Copyright (c) 2021, Red Hat, Inc.
4 *
5 * This source code is released for free distribution under the terms of the
6 * GNU General Public License version 2 or (at your option) any later version.
7 */
8
9 /*
10 * INCLUDES
11 */
12
13 #include "formatter.h"
14 #include "dsl.h"
15 #include "es.h"
16
17 #include <stdlib.h>
18 #include <string.h>
19
20 static EsObject* formatter_proc_list (EsObject* args, DSLEnv *env);
21
22 /*
23 * DATA DEFINITIONS
24 */
25 static DSLProcBind pbinds [] = {
26 { "list", formatter_proc_list, NULL, 0, 0UL,
27 .helpstr = "(list <any> ...) -> (<any> ...)" },
28 };
29
formatter_proc_list(EsObject * args,DSLEnv * env)30 static EsObject* formatter_proc_list (EsObject* args, DSLEnv *env)
31 {
32 return args;
33 }
34
35 /*
36 * Procs
37 */
initialize(void)38 static int initialize (void)
39 {
40 static int initialized;
41
42 if (initialized)
43 return 1;
44
45 if (!dsl_init (DSL_FORMATTER, pbinds, sizeof(pbinds)/sizeof(pbinds [0])))
46 {
47 fprintf(stderr, "MEMORY EXHAUSTED\n");
48 return 0;
49 }
50
51 initialized = 1;
52 return 1;
53 }
54
55 /*
56 * FCode
57 */
58 struct sFCode
59 {
60 DSLCode *dsl;
61 };
62
f_compile(EsObject * exp)63 FCode *f_compile (EsObject *exp)
64 {
65 FCode *code;
66
67 if (!initialize ())
68 exit (1);
69
70 code = malloc (sizeof (FCode));
71 if (code == NULL)
72 {
73 fprintf(stderr, "MEMORY EXHAUSTED\n");
74 return NULL;
75 }
76
77 code->dsl = dsl_compile (DSL_FORMATTER, exp);
78 if (code->dsl == NULL)
79 {
80 fprintf(stderr, "MEMORY EXHAUSTED or SYNTAX ERROR\n");
81 free (code);
82 return NULL;
83 }
84
85 return code;
86 }
87
f_print0(EsObject * r,FILE * out)88 static int f_print0(EsObject *r, FILE *out)
89 {
90 if (es_error_p (r))
91 {
92 dsl_report_error ("GOT ERROR in FORMATTING", r);
93 return 1;
94 }
95 else if (es_string_p (r))
96 {
97 fputs (es_string_get(r), out);
98 return 0;
99 }
100 else if (es_integer_p (r))
101 {
102 fprintf(out, "%d", es_integer_get(r));
103 return 0;
104 }
105 else if (es_object_equal(r, es_false))
106 {
107 return 0;
108 }
109 else if (es_object_equal(r, es_true))
110 {
111 putc ('\n', out);
112 return 0;
113 }
114 else if (es_cons_p (r))
115 {
116 EsObject *car = es_car (r);
117 EsObject *cdr = es_cdr(r);
118
119 for (; !es_null (car);
120 car = es_car (cdr), cdr = es_cdr (cdr))
121 {
122 if (f_print0 (car, out))
123 return 1;
124 }
125 return 0;
126 }
127 else
128 {
129 dsl_report_error ("UNEXPECTED VALUE IN FORMATTING", r);
130 return 1;
131 }
132 }
133
f_print(const tagEntry * entry,FCode * code,FILE * out)134 int f_print (const tagEntry * entry, FCode *code, FILE *out)
135 {
136 EsObject *r;
137 int exit_code = 0;
138
139 DSLEnv env = {
140 .engine = DSL_FORMATTER,
141 .entry = entry,
142 };
143
144 es_autounref_pool_push ();
145 r = dsl_eval (code->dsl, &env);
146 exit_code = f_print0 (r, out);
147 es_autounref_pool_pop ();
148
149 dsl_cache_reset (DSL_FORMATTER);
150
151 if (exit_code)
152 exit (exit_code);
153
154 return 0;
155 }
156
f_destroy(FCode * code)157 void f_destroy (FCode *code)
158 {
159 dsl_release (DSL_FORMATTER, code->dsl);
160 free (code);
161 }
162
f_help(FILE * fp)163 void f_help (FILE *fp)
164 {
165 if (!initialize ())
166 exit (1);
167 dsl_help (DSL_FORMATTER, fp);
168 }
169