ali@0: #include ali@0: #include ali@0: #include ali@0: #include ali@0: #include ali@0: #include ali@0: ali@0: gboolean dump_tree,dump_result,test_result,do_xinclude; ali@0: gchar **files; ali@0: ali@0: gboolean trace_symbol(const gchar *option_name,const gchar *value,gpointer data, ali@0: GError **err) ali@0: { ali@0: Xexpr *xexpr=data; ali@0: xexpr_start_tracing(xexpr,value); ali@0: return TRUE; ali@0: } ali@0: ali@0: gboolean set_param(const gchar *option_name,const gchar *value,gpointer data, ali@0: GError **err) ali@0: { ali@0: const char *s; ali@0: char *endptr; ali@0: double d,integer; ali@0: gchar *name; ali@0: XexprConstant *arg; ali@0: Xexpr *xexpr=data; ali@0: s=strchr(value,','); ali@0: if (!s) ali@0: { ali@0: g_set_error(err,G_OPTION_ERROR,G_OPTION_ERROR_BAD_VALUE, ali@0: "No comma found in --param argument \"%s\"",value); ali@0: return FALSE; ali@0: } ali@0: name=g_strndup(value,s-value); ali@0: d=strtod(s+1,&endptr); ali@0: if (!d || *endptr) ali@0: { ali@0: g_set_error(err,G_OPTION_ERROR,G_OPTION_ERROR_BAD_VALUE, ali@0: "Invalid number in --param argument: \"%s\"",s); ali@0: return FALSE; ali@0: } ali@0: if (!modf(d,&integer)) ali@0: arg=xexpr_new_integer(integer); ali@0: else ali@0: arg=xexpr_new_number(d); ali@0: xexpr_var_set(xexpr,name,arg); ali@0: xexpr_constant_free(arg); ali@0: return TRUE; ali@0: } ali@0: ali@0: gboolean set_string_param(const gchar *option_name,const gchar *value, ali@0: gpointer data,GError **err) ali@0: { ali@0: const char *s; ali@0: char *endptr; ali@0: double d,integer; ali@0: gchar *name; ali@0: XexprConstant *arg; ali@0: Xexpr *xexpr=data; ali@0: s=strchr(value,','); ali@0: if (!s) ali@0: { ali@0: g_set_error(err,G_OPTION_ERROR,G_OPTION_ERROR_BAD_VALUE, ali@0: "No comma found in --stringparam argument \"%s\"",value); ali@0: return FALSE; ali@0: } ali@0: name=g_strndup(value,s-value); ali@0: arg=xexpr_new_string(s+1,-1); ali@0: xexpr_var_set(xexpr,name,arg); ali@0: xexpr_constant_free(arg); ali@0: return TRUE; ali@0: } ali@0: ali@0: static GOptionEntry entries[]={ ali@0: { "dump-tree",'d',0,G_OPTION_ARG_NONE,&dump_tree,"Dump parsed file",NULL }, ali@0: { "dump-result",'D',0,G_OPTION_ARG_NONE,&dump_result,"Dump result",NULL }, ali@0: { "test-result",'t',0,G_OPTION_ARG_NONE,&test_result,"Test result",NULL }, ali@0: { "trace",'T',0,G_OPTION_ARG_CALLBACK,trace_symbol,"Trace symbol",NULL }, ali@0: { G_OPTION_REMAINING,0,0,G_OPTION_ARG_FILENAME_ARRAY,&files,NULL, ali@0: "[]" }, ali@0: { "xinclude",0,0,G_OPTION_ARG_NONE,&do_xinclude,"Do XInclude processing", ali@0: NULL }, ali@0: { "param",0,0,G_OPTION_ARG_CALLBACK,set_param, ali@0: "Pass a (parameter,number) pair",NULL }, ali@0: { "stringparam",0,0,G_OPTION_ARG_CALLBACK,set_string_param, ali@0: "Pass a (parameter,string) pair",NULL }, ali@0: { NULL } ali@0: }; ali@0: ali@0: gboolean set_variable(gpointer key,gpointer value,gpointer data) ali@0: { ali@0: xexpr_var_set(data,key,value); ali@0: return FALSE; ali@0: } ali@0: ali@0: gboolean run_xexpr(Xexpr *xexpr,xmlDocPtr doc,const char *filename) ali@0: { ali@0: gboolean retval=TRUE; ali@0: GError *err=NULL; ali@0: Xexpr *sub,*result; ali@0: sub=xexpr_sub(xexpr); ali@0: xexpr_environment_foreach(xexpr_get_environment(xexpr),set_variable,sub); ali@0: if (!xexpr_parse_node(sub,xmlDocGetRootElement(doc),&err)) ali@0: { ali@0: fprintf(stderr,"%s: %s\n",filename,err->message); ali@0: exit(1); ali@0: } ali@0: if (dump_tree) ali@0: { ali@0: xexpr_dump(sub,stdout); ali@0: putchar('\n'); ali@0: } ali@0: else ali@0: { ali@0: result=xexpr_evaluate(sub,&err); ali@0: if (err) ali@0: { ali@0: fprintf(stderr,"%s: %s\n",filename,err->message); ali@0: g_clear_error(&err); ali@0: xexpr_free(sub); ali@0: return FALSE; ali@0: } ali@0: if (dump_result) ali@0: { ali@0: printf("\nResult: "); ali@0: xexpr_dump(result,stdout); ali@0: putchar('\n'); ali@0: } ali@0: if (test_result) ali@0: retval=xexpr_test(result,NULL); ali@0: xexpr_free(result); ali@0: } ali@0: xexpr_free(sub); ali@0: return retval; ali@0: } ali@0: ali@0: int main(int argc,char **argv) ali@0: { ali@0: int i; ali@0: xmlDocPtr doc; ali@0: int xml_options=XML_PARSE_NOENT; ali@0: gboolean result=TRUE; ali@0: GError *err=NULL; ali@0: GOptionGroup *group; ali@0: GOptionContext *context; ali@0: Xexpr *xexpr; ali@0: xexpr=xexpr_new(); ali@0: context=g_option_context_new("- XEXPR interpreter"); ali@0: group=g_option_group_new(NULL,NULL,NULL,xexpr,NULL); ali@0: g_option_group_add_entries(group,entries); ali@0: g_option_context_set_main_group(context,group); ali@0: if (!g_option_context_parse(context,&argc,&argv,&err)) ali@0: { ali@0: fprintf(stderr,"%s\n",err->message); ali@0: exit(1); ali@0: } ali@0: if (do_xinclude) ali@0: xml_options|=XML_PARSE_XINCLUDE|XML_PARSE_NOXINCNODE; ali@0: if (files && files[0]) ali@0: { ali@0: for(i=0;files[i];i++) ali@0: { ali@0: doc=xmlReadFile(files[i],NULL,xml_options); ali@0: if (!doc) ali@0: result=FALSE; ali@0: else ali@0: { ali@0: if (do_xinclude && xmlXIncludeProcessFlags(doc,xml_options)<0) ali@0: result=FALSE; ali@0: else if (!run_xexpr(xexpr,doc,files[i])) ali@0: result=FALSE; ali@0: xmlFreeDoc(doc); ali@0: } ali@0: } ali@0: } ali@0: else ali@0: { ali@0: doc=xmlReadFd(0,NULL,NULL,xml_options); ali@0: if (!doc) ali@0: result=FALSE; ali@0: else ali@0: { ali@0: if (do_xinclude && xmlXIncludeProcessFlags(doc,xml_options)<0) ali@0: result=FALSE; ali@0: else if (!run_xexpr(xexpr,doc,"stdin")) ali@0: result=FALSE; ali@0: xmlFreeDoc(doc); ali@0: } ali@0: } ali@0: xexpr_free(xexpr); ali@0: exit(result?0:1); ali@0: }