xref: /Universal-ctags/dsl/formatter.c (revision d453aacfb88c1c59e3850594e8437c4ed9b52ebf)
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