yaubil.c
changeset 4 faaed3ae3fa8
parent 2 6a47079725da
child 8 2033d1c5d226
equal deleted inserted replaced
3:7b0b509e02e4 4:faaed3ae3fa8
    53 
    53 
    54 static int check_value_type (const char *value)
    54 static int check_value_type (const char *value)
    55 {
    55 {
    56 	if (value) {
    56 	if (value) {
    57 		const char *e;
    57 		const char *e;
    58 		gboolean    integer = (*value == '-') ? FALSE : (g_ascii_isdigit (*value) ? TRUE : FALSE);
    58 		gboolean    integer = (*value == '-') ? TRUE : (g_ascii_isdigit (*value) ? TRUE : FALSE);
    59 
    59 
    60 		if (integer) {
    60 		if (integer) {
    61 			for (e = value + 1; *e; ++e) {
    61 			for (e = value + 1; *e; ++e) {
    62 				if (g_ascii_isdigit (*e))
    62 				if (g_ascii_isdigit (*e))
    63 					integer = TRUE;
    63 					integer = TRUE;
    76 		return TYPE_UNDEF;
    76 		return TYPE_UNDEF;
    77 }
    77 }
    78 
    78 
    79 static gboolean op_concat (value_t *l, value_t *r)
    79 static gboolean op_concat (value_t *l, value_t *r)
    80 {
    80 {
    81 	GString *res = g_string_new (NULL);;
    81 	GString *res = g_string_new (NULL);
    82 
    82 
    83 	if (l->type == TYPE_INT)
    83 	if (l->type == TYPE_INT)
    84 		g_string_append_printf (res, "%d", l->int_value);
    84 		g_string_append_printf (res, "%d", l->int_value);
    85 	else if (l->type == TYPE_STR)
    85 	else if (l->type == TYPE_STR)
    86 		g_string_append (res, l->str_value);
    86 		g_string_append (res, l->str_value);
    93 	l->type = TYPE_STR;
    93 	l->type = TYPE_STR;
    94 	g_free (l->str_value);
    94 	g_free (l->str_value);
    95 	l->str_value = g_string_free (res, FALSE);
    95 	l->str_value = g_string_free (res, FALSE);
    96 
    96 
    97 	return TRUE;
    97 	return TRUE;
       
    98 }
       
    99 
       
   100 static gboolean op_head (value_t *l, value_t *r)
       
   101 {
       
   102 	if (l->type == TYPE_UNDEF) {
       
   103 		l->type      = TYPE_INT;
       
   104 		l->int_value = 0;
       
   105 	}
       
   106 	if (r->type == TYPE_UNDEF) {
       
   107 		r->type      = TYPE_INT;
       
   108 		r->int_value = 0;
       
   109 	}
       
   110 
       
   111 	if (l -> type == TYPE_INT) {
       
   112 		l -> type = TYPE_STR;
       
   113 		if (!l -> str_value)
       
   114 			l -> str_value = g_strdup_printf ("%d", l -> int_value);
       
   115 	}
       
   116 	if (r->type == TYPE_STR && check_value_type (r->str_value) == TYPE_INT) {
       
   117 		r->type      = TYPE_INT;
       
   118 		r->int_value = atoi (r->str_value);
       
   119 		g_free (r->str_value);
       
   120 		r->str_value = NULL;
       
   121 	}
       
   122 
       
   123 	if (l->type == TYPE_STR && r->type == TYPE_INT) {
       
   124 		gchar *res = NULL;
       
   125 		int    len = l -> str_value ? strlen (l -> str_value) : 0; // XXX can str_value be NULL?
       
   126 		int    off = r -> int_value;
       
   127 		if (off < 0 && len + off > 0)
       
   128 			res = g_strndup (l -> str_value, len + off);
       
   129 		else if (off > 0 && len > off)
       
   130 			res = g_strndup (l -> str_value, off);
       
   131 		else
       
   132 			res = g_strdup (""); // XXX leave NULL here?
       
   133 		g_free (l->str_value);
       
   134 		l->str_value = res;
       
   135 	} else
       
   136 		return FALSE;
       
   137 }
       
   138 
       
   139 static gboolean op_tail (value_t *l, value_t *r)
       
   140 {
       
   141 	if (l->type == TYPE_UNDEF) {
       
   142 		l->type      = TYPE_INT;
       
   143 		l->int_value = 0;
       
   144 	}
       
   145 	if (r->type == TYPE_UNDEF) {
       
   146 		r->type      = TYPE_INT;
       
   147 		r->int_value = 0;
       
   148 	}
       
   149 
       
   150 	if (l -> type == TYPE_INT) {
       
   151 		l -> type = TYPE_STR;
       
   152 		if (!l -> str_value)
       
   153 			l -> str_value = g_strdup_printf ("%d", l -> int_value);
       
   154 	}
       
   155 	if (r->type == TYPE_STR && check_value_type (r->str_value) == TYPE_INT) {
       
   156 		r->type      = TYPE_INT;
       
   157 		r->int_value = atoi (r->str_value);
       
   158 		g_free (r->str_value);
       
   159 		r->str_value = NULL;
       
   160 	}
       
   161 
       
   162 	if (l->type == TYPE_STR && r->type == TYPE_INT) {
       
   163 		gchar *res = NULL;
       
   164 		int    len = l -> str_value ? strlen (l -> str_value) : 0; // XXX can str_value be NULL?
       
   165 		int    off = r -> int_value;
       
   166 		if (off < 0 && len + off > 0)
       
   167 			res = g_strdup (l -> str_value + (-off));
       
   168 		else if (off > 0 && len > off)
       
   169 			res = g_strdup (l -> str_value + (len - off));
       
   170 		else
       
   171 			res = g_strdup (""); // XXX leave NULL here?
       
   172 		g_free (l->str_value);
       
   173 		l->str_value = res;
       
   174 	} else
       
   175 		return FALSE;
    98 }
   176 }
    99 
   177 
   100 static gboolean op_plus (value_t *l, value_t *r)
   178 static gboolean op_plus (value_t *l, value_t *r)
   101 {
   179 {
   102 	if (l->type == TYPE_UNDEF) {
   180 	if (l->type == TYPE_UNDEF) {
   452 	return TRUE;
   530 	return TRUE;
   453 }
   531 }
   454 
   532 
   455 static op_t operators[] = {
   533 static op_t operators[] = {
   456 	{ '.', op_concat   },
   534 	{ '.', op_concat   },
       
   535 	{ ':', op_head     },
       
   536 	{ '^', op_tail     },
   457 	{ '+', op_plus     },
   537 	{ '+', op_plus     },
   458 	{ '-', op_minus    },
   538 	{ '-', op_minus    },
   459 	{ '*', op_multiply },
   539 	{ '*', op_multiply },
   460 	{ '/', op_divide   },
   540 	{ '/', op_divide   },
   461 	{ '%', op_remain   },
   541 	{ '%', op_remain   },