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) { |