|
ali@0
|
1 |
#include <stdlib.h>
|
|
ali@0
|
2 |
#include <string.h>
|
|
ali@0
|
3 |
#include <math.h>
|
|
ali@0
|
4 |
#include <glib.h>
|
|
ali@0
|
5 |
#include <libxml/parser.h>
|
|
ali@0
|
6 |
#include <libxexpr/xexpr.h>
|
|
ali@0
|
7 |
|
|
ali@0
|
8 |
gboolean dump_tree,dump_result,test_result,do_xinclude;
|
|
ali@0
|
9 |
gchar **files;
|
|
ali@0
|
10 |
|
|
ali@0
|
11 |
gboolean trace_symbol(const gchar *option_name,const gchar *value,gpointer data,
|
|
ali@0
|
12 |
GError **err)
|
|
ali@0
|
13 |
{
|
|
ali@0
|
14 |
Xexpr *xexpr=data;
|
|
ali@0
|
15 |
xexpr_start_tracing(xexpr,value);
|
|
ali@0
|
16 |
return TRUE;
|
|
ali@0
|
17 |
}
|
|
ali@0
|
18 |
|
|
ali@0
|
19 |
gboolean set_param(const gchar *option_name,const gchar *value,gpointer data,
|
|
ali@0
|
20 |
GError **err)
|
|
ali@0
|
21 |
{
|
|
ali@0
|
22 |
const char *s;
|
|
ali@0
|
23 |
char *endptr;
|
|
ali@0
|
24 |
double d,integer;
|
|
ali@0
|
25 |
gchar *name;
|
|
ali@0
|
26 |
XexprConstant *arg;
|
|
ali@0
|
27 |
Xexpr *xexpr=data;
|
|
ali@0
|
28 |
s=strchr(value,',');
|
|
ali@0
|
29 |
if (!s)
|
|
ali@0
|
30 |
{
|
|
ali@0
|
31 |
g_set_error(err,G_OPTION_ERROR,G_OPTION_ERROR_BAD_VALUE,
|
|
ali@0
|
32 |
"No comma found in --param argument \"%s\"",value);
|
|
ali@0
|
33 |
return FALSE;
|
|
ali@0
|
34 |
}
|
|
ali@0
|
35 |
name=g_strndup(value,s-value);
|
|
ali@0
|
36 |
d=strtod(s+1,&endptr);
|
|
ali@0
|
37 |
if (!d || *endptr)
|
|
ali@0
|
38 |
{
|
|
ali@0
|
39 |
g_set_error(err,G_OPTION_ERROR,G_OPTION_ERROR_BAD_VALUE,
|
|
ali@0
|
40 |
"Invalid number in --param argument: \"%s\"",s);
|
|
ali@0
|
41 |
return FALSE;
|
|
ali@0
|
42 |
}
|
|
ali@0
|
43 |
if (!modf(d,&integer))
|
|
ali@0
|
44 |
arg=xexpr_new_integer(integer);
|
|
ali@0
|
45 |
else
|
|
ali@0
|
46 |
arg=xexpr_new_number(d);
|
|
ali@0
|
47 |
xexpr_var_set(xexpr,name,arg);
|
|
ali@0
|
48 |
xexpr_constant_free(arg);
|
|
ali@0
|
49 |
return TRUE;
|
|
ali@0
|
50 |
}
|
|
ali@0
|
51 |
|
|
ali@0
|
52 |
gboolean set_string_param(const gchar *option_name,const gchar *value,
|
|
ali@0
|
53 |
gpointer data,GError **err)
|
|
ali@0
|
54 |
{
|
|
ali@0
|
55 |
const char *s;
|
|
ali@0
|
56 |
char *endptr;
|
|
ali@0
|
57 |
double d,integer;
|
|
ali@0
|
58 |
gchar *name;
|
|
ali@0
|
59 |
XexprConstant *arg;
|
|
ali@0
|
60 |
Xexpr *xexpr=data;
|
|
ali@0
|
61 |
s=strchr(value,',');
|
|
ali@0
|
62 |
if (!s)
|
|
ali@0
|
63 |
{
|
|
ali@0
|
64 |
g_set_error(err,G_OPTION_ERROR,G_OPTION_ERROR_BAD_VALUE,
|
|
ali@0
|
65 |
"No comma found in --stringparam argument \"%s\"",value);
|
|
ali@0
|
66 |
return FALSE;
|
|
ali@0
|
67 |
}
|
|
ali@0
|
68 |
name=g_strndup(value,s-value);
|
|
ali@0
|
69 |
arg=xexpr_new_string(s+1,-1);
|
|
ali@0
|
70 |
xexpr_var_set(xexpr,name,arg);
|
|
ali@0
|
71 |
xexpr_constant_free(arg);
|
|
ali@0
|
72 |
return TRUE;
|
|
ali@0
|
73 |
}
|
|
ali@0
|
74 |
|
|
ali@0
|
75 |
static GOptionEntry entries[]={
|
|
ali@0
|
76 |
{ "dump-tree",'d',0,G_OPTION_ARG_NONE,&dump_tree,"Dump parsed file",NULL },
|
|
ali@0
|
77 |
{ "dump-result",'D',0,G_OPTION_ARG_NONE,&dump_result,"Dump result",NULL },
|
|
ali@0
|
78 |
{ "test-result",'t',0,G_OPTION_ARG_NONE,&test_result,"Test result",NULL },
|
|
ali@0
|
79 |
{ "trace",'T',0,G_OPTION_ARG_CALLBACK,trace_symbol,"Trace symbol",NULL },
|
|
ali@0
|
80 |
{ G_OPTION_REMAINING,0,0,G_OPTION_ARG_FILENAME_ARRAY,&files,NULL,
|
|
ali@0
|
81 |
"[<input>]" },
|
|
ali@0
|
82 |
{ "xinclude",0,0,G_OPTION_ARG_NONE,&do_xinclude,"Do XInclude processing",
|
|
ali@0
|
83 |
NULL },
|
|
ali@0
|
84 |
{ "param",0,0,G_OPTION_ARG_CALLBACK,set_param,
|
|
ali@0
|
85 |
"Pass a (parameter,number) pair",NULL },
|
|
ali@0
|
86 |
{ "stringparam",0,0,G_OPTION_ARG_CALLBACK,set_string_param,
|
|
ali@0
|
87 |
"Pass a (parameter,string) pair",NULL },
|
|
ali@0
|
88 |
{ NULL }
|
|
ali@0
|
89 |
};
|
|
ali@0
|
90 |
|
|
ali@0
|
91 |
gboolean set_variable(gpointer key,gpointer value,gpointer data)
|
|
ali@0
|
92 |
{
|
|
ali@0
|
93 |
xexpr_var_set(data,key,value);
|
|
ali@0
|
94 |
return FALSE;
|
|
ali@0
|
95 |
}
|
|
ali@0
|
96 |
|
|
ali@0
|
97 |
gboolean run_xexpr(Xexpr *xexpr,xmlDocPtr doc,const char *filename)
|
|
ali@0
|
98 |
{
|
|
ali@0
|
99 |
gboolean retval=TRUE;
|
|
ali@0
|
100 |
GError *err=NULL;
|
|
ali@0
|
101 |
Xexpr *sub,*result;
|
|
ali@0
|
102 |
sub=xexpr_sub(xexpr);
|
|
ali@0
|
103 |
xexpr_environment_foreach(xexpr_get_environment(xexpr),set_variable,sub);
|
|
ali@0
|
104 |
if (!xexpr_parse_node(sub,xmlDocGetRootElement(doc),&err))
|
|
ali@0
|
105 |
{
|
|
ali@0
|
106 |
fprintf(stderr,"%s: %s\n",filename,err->message);
|
|
ali@0
|
107 |
exit(1);
|
|
ali@0
|
108 |
}
|
|
ali@0
|
109 |
if (dump_tree)
|
|
ali@0
|
110 |
{
|
|
ali@0
|
111 |
xexpr_dump(sub,stdout);
|
|
ali@0
|
112 |
putchar('\n');
|
|
ali@0
|
113 |
}
|
|
ali@0
|
114 |
else
|
|
ali@0
|
115 |
{
|
|
ali@0
|
116 |
result=xexpr_evaluate(sub,&err);
|
|
ali@0
|
117 |
if (err)
|
|
ali@0
|
118 |
{
|
|
ali@0
|
119 |
fprintf(stderr,"%s: %s\n",filename,err->message);
|
|
ali@0
|
120 |
g_clear_error(&err);
|
|
ali@0
|
121 |
xexpr_free(sub);
|
|
ali@0
|
122 |
return FALSE;
|
|
ali@0
|
123 |
}
|
|
ali@0
|
124 |
if (dump_result)
|
|
ali@0
|
125 |
{
|
|
ali@0
|
126 |
printf("\nResult: ");
|
|
ali@0
|
127 |
xexpr_dump(result,stdout);
|
|
ali@0
|
128 |
putchar('\n');
|
|
ali@0
|
129 |
}
|
|
ali@0
|
130 |
if (test_result)
|
|
ali@0
|
131 |
retval=xexpr_test(result,NULL);
|
|
ali@0
|
132 |
xexpr_free(result);
|
|
ali@0
|
133 |
}
|
|
ali@0
|
134 |
xexpr_free(sub);
|
|
ali@0
|
135 |
return retval;
|
|
ali@0
|
136 |
}
|
|
ali@0
|
137 |
|
|
ali@0
|
138 |
int main(int argc,char **argv)
|
|
ali@0
|
139 |
{
|
|
ali@0
|
140 |
int i;
|
|
ali@0
|
141 |
xmlDocPtr doc;
|
|
ali@0
|
142 |
int xml_options=XML_PARSE_NOENT;
|
|
ali@0
|
143 |
gboolean result=TRUE;
|
|
ali@0
|
144 |
GError *err=NULL;
|
|
ali@0
|
145 |
GOptionGroup *group;
|
|
ali@0
|
146 |
GOptionContext *context;
|
|
ali@0
|
147 |
Xexpr *xexpr;
|
|
ali@0
|
148 |
xexpr=xexpr_new();
|
|
ali@0
|
149 |
context=g_option_context_new("- XEXPR interpreter");
|
|
ali@0
|
150 |
group=g_option_group_new(NULL,NULL,NULL,xexpr,NULL);
|
|
ali@0
|
151 |
g_option_group_add_entries(group,entries);
|
|
ali@0
|
152 |
g_option_context_set_main_group(context,group);
|
|
ali@0
|
153 |
if (!g_option_context_parse(context,&argc,&argv,&err))
|
|
ali@0
|
154 |
{
|
|
ali@0
|
155 |
fprintf(stderr,"%s\n",err->message);
|
|
ali@0
|
156 |
exit(1);
|
|
ali@0
|
157 |
}
|
|
ali@0
|
158 |
if (do_xinclude)
|
|
ali@0
|
159 |
xml_options|=XML_PARSE_XINCLUDE|XML_PARSE_NOXINCNODE;
|
|
ali@0
|
160 |
if (files && files[0])
|
|
ali@0
|
161 |
{
|
|
ali@0
|
162 |
for(i=0;files[i];i++)
|
|
ali@0
|
163 |
{
|
|
ali@0
|
164 |
doc=xmlReadFile(files[i],NULL,xml_options);
|
|
ali@0
|
165 |
if (!doc)
|
|
ali@0
|
166 |
result=FALSE;
|
|
ali@0
|
167 |
else
|
|
ali@0
|
168 |
{
|
|
ali@0
|
169 |
if (do_xinclude && xmlXIncludeProcessFlags(doc,xml_options)<0)
|
|
ali@0
|
170 |
result=FALSE;
|
|
ali@0
|
171 |
else if (!run_xexpr(xexpr,doc,files[i]))
|
|
ali@0
|
172 |
result=FALSE;
|
|
ali@0
|
173 |
xmlFreeDoc(doc);
|
|
ali@0
|
174 |
}
|
|
ali@0
|
175 |
}
|
|
ali@0
|
176 |
}
|
|
ali@0
|
177 |
else
|
|
ali@0
|
178 |
{
|
|
ali@0
|
179 |
doc=xmlReadFd(0,NULL,NULL,xml_options);
|
|
ali@0
|
180 |
if (!doc)
|
|
ali@0
|
181 |
result=FALSE;
|
|
ali@0
|
182 |
else
|
|
ali@0
|
183 |
{
|
|
ali@0
|
184 |
if (do_xinclude && xmlXIncludeProcessFlags(doc,xml_options)<0)
|
|
ali@0
|
185 |
result=FALSE;
|
|
ali@0
|
186 |
else if (!run_xexpr(xexpr,doc,"stdin"))
|
|
ali@0
|
187 |
result=FALSE;
|
|
ali@0
|
188 |
xmlFreeDoc(doc);
|
|
ali@0
|
189 |
}
|
|
ali@0
|
190 |
}
|
|
ali@0
|
191 |
xexpr_free(xexpr);
|
|
ali@0
|
192 |
exit(result?0:1);
|
|
ali@0
|
193 |
}
|