src/xexpr.c
author ali <ali@juiblex.co.uk>
Wed Oct 10 22:58:21 2012 +0100 (2012-10-10)
changeset 0 bc8c9a11cbfc
permissions -rw-r--r--
Initial version
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
}