0
|
1 #include "datum.h"
|
|
2 #include "structs.h"
|
|
3 #include "interp.h"
|
|
4 #include <string.h>
|
|
5 #include <stdlib.h>
|
|
6
|
|
7
|
|
8 int vis_inttostring(datum ** inputlist, queue_entry * worker_entry)
|
|
9 {
|
|
10 int i,j,val;
|
|
11 char temp_buf[12];
|
|
12 datum * output;
|
|
13 char * out_buf;
|
|
14 //sprintf(temp_buf, "%d", inputlist[0]->c.integers.num_a);
|
|
15 val = (inputlist[0]->c.integers.num_a >= 0 ? inputlist[0]->c.integers.num_a : 0-inputlist[0]->c.integers.num_a);
|
|
16 i = 0;
|
|
17 if(!val)
|
|
18 temp_buf[i++] = '0';
|
|
19
|
|
20 while(val > 0)
|
|
21 {
|
|
22 temp_buf[i] = (val % 10) + '0';
|
|
23 val /= 10;
|
|
24 ++i;
|
|
25 }
|
|
26 if(inputlist[0]->c.integers.num_a < 0)
|
|
27 {
|
|
28 temp_buf[i] = '-';
|
|
29 ++i;
|
|
30 }
|
|
31 release_ref(inputlist[0]);
|
|
32 inputlist[0] = new_datum(BUILTIN_TYPE_STRING, 1, i+1, worker_entry->instance->def->program);
|
|
33 out_buf = inputlist[0]->c.generic.data;
|
|
34 out_buf[i] = '\0';
|
|
35 j = 0;
|
|
36 --i;
|
|
37 while(i >= 0)
|
|
38 {
|
|
39 out_buf[j] = temp_buf[i];
|
|
40 ++j;
|
|
41 --i;
|
|
42 }
|
|
43 //strcpy(inputlist[0]->c.generic.data, temp_buf);
|
|
44 return 0;
|
|
45
|
|
46 }
|
|
47
|
|
48 #ifndef SEGA
|
|
49 int vis_realtostring(datum ** inputlist, queue_entry * worker_entry)
|
|
50 {
|
|
51 char temp_buf[30];//Is this enough?
|
|
52 datum * output;
|
|
53 sprintf(temp_buf, "%f", inputlist[0]->c.real);
|
|
54 release_ref(inputlist[0]);
|
|
55 inputlist[0] = new_datum(BUILTIN_TYPE_STRING, 1, strlen(temp_buf)+1, worker_entry->instance->def->program);
|
|
56 strcpy(inputlist[0]->c.generic.data, temp_buf);
|
|
57 return 0;
|
|
58
|
|
59 }
|
|
60 #endif
|
|
61
|
|
62 int vis_stringequal(datum ** inputlist, queue_entry * worker_entry)
|
|
63 {
|
|
64 int result = strcmp(inputlist[0]->c.generic.data, inputlist[1]->c.generic.data);
|
|
65 release_ref(inputlist[0]);
|
|
66 release_ref(inputlist[1]);
|
|
67 inputlist[0] = new_datum(BUILTIN_TYPE_YESNO, 2, 0, worker_entry->instance->def->program);
|
|
68 datum_set_yesno(inputlist[0], (result == 0 ? 1 : 0));
|
|
69 return 0;
|
|
70 }
|
|
71
|
|
72 int vis_append(datum ** inputlist, queue_entry * worker_entry)
|
|
73 {
|
|
74 datum * output;
|
|
75 int temp_size = inputlist[0]->c.generic.len;
|
|
76 DEBUGPUTS("Begin vis_append\n");
|
|
77
|
|
78 DEBUGPRINTF("Left: %s(%d)\n", inputlist[0]->c.generic.data, inputlist[0]->c.generic.len);
|
|
79 DEBUGPRINTF("Right: %s(%d)\n", inputlist[1]->c.generic.data, inputlist[1]->c.generic.len);
|
|
80 output = new_datum(BUILTIN_TYPE_STRING, 1, temp_size+inputlist[1]->c.generic.len-1, worker_entry->instance->def->program);
|
|
81 memcpy(output->c.generic.data, inputlist[0]->c.generic.data, temp_size-1);
|
|
82 memcpy(((char *)output->c.generic.data)+temp_size-1, inputlist[1]->c.generic.data, inputlist[1]->c.generic.len-1);
|
|
83 ((char *)output->c.generic.data)[temp_size + inputlist[1]->c.generic.len-2]='\0';
|
|
84 DEBUGPRINTF("Appended string: %s(%d)\n", output->c.generic.data, output->c.generic.len);
|
|
85 release_ref(inputlist[0]);
|
|
86 release_ref(inputlist[1]);
|
|
87 inputlist[0] = output;
|
|
88 DEBUGPUTS("End vis_append\n");
|
|
89
|
|
90 return 0;
|
|
91 }
|
|
92
|
|
93 int vis_yesnotostring(datum ** inputlist, queue_entry * worker_entry)
|
|
94 {
|
|
95 int result = inputlist[0]->c.integers.num_a;
|
|
96 release_ref(inputlist[0]);
|
|
97 if(result)
|
|
98 {
|
|
99 inputlist[0] = new_datum(BUILTIN_TYPE_STRING, 1, 4, worker_entry->instance->def->program);
|
|
100 strcpy(inputlist[0]->c.generic.data, "Yes");
|
|
101 }
|
|
102 else
|
|
103 {
|
|
104 inputlist[0] = new_datum(BUILTIN_TYPE_STRING, 1, 3, worker_entry->instance->def->program);
|
|
105 strcpy(inputlist[0]->c.generic.data, "No");
|
|
106 }
|
|
107 return 0;
|
|
108 }
|
|
109
|
|
110 int vis_greaterstring(datum ** inputlist, queue_entry * worker_entry)
|
|
111 {
|
|
112 int result;
|
|
113 if(strcmp(inputlist[0]->c.generic.data, inputlist[1]->c.generic.data) > 0)
|
|
114 result = 1;
|
|
115 else
|
|
116 result = 0;
|
|
117 release_ref(inputlist[0]);
|
|
118 release_ref(inputlist[1]);
|
|
119 inputlist[0] = new_datum(BUILTIN_TYPE_YESNO, 2, 0, worker_entry->instance->def->program);
|
|
120 datum_set_yesno(inputlist[0], result);
|
|
121 return 0;
|
|
122 }
|
|
123
|
|
124 int vis_lesserstring(datum ** inputlist, queue_entry * worker_entry)
|
|
125 {
|
|
126 int result;
|
|
127 if(strcmp(inputlist[0]->c.generic.data, inputlist[1]->c.generic.data) < 0)
|
|
128 result = 1;
|
|
129 else
|
|
130 result = 0;
|
|
131 release_ref(inputlist[0]);
|
|
132 release_ref(inputlist[1]);
|
|
133 inputlist[0] = new_datum(BUILTIN_TYPE_YESNO, 2, 0, worker_entry->instance->def->program);
|
|
134 datum_set_yesno(inputlist[0], result);
|
|
135 return 0;
|
|
136 }
|
|
137
|
|
138 datum * make_string(const char * string, int len, program * prog)
|
|
139 {
|
|
140 datum * output;
|
|
141 if(len < 0)
|
|
142 len = strlen(string);
|
|
143 output = new_datum(BUILTIN_TYPE_STRING, 1, len+1, prog);
|
|
144 memcpy(output->c.generic.data, string, len);
|
|
145 ((char *)output->c.generic.data)[len] = '\0';
|
|
146 return output;
|
|
147 }
|
|
148
|
|
149 int vis_string_split(datum ** inputlist, queue_entry * worker_entry)
|
|
150 {
|
|
151 int i, start=0, len = inputlist[0]->c.generic.len-1;
|
|
152 char * string = inputlist[0]->c.generic.data;
|
|
153 char * delim = inputlist[1]->c.generic.data;
|
|
154 int delimlen = inputlist[1]->c.generic.len-1;
|
|
155 int search_offset = 0;
|
|
156 datum * params[2];
|
|
157 params[0] = create_list(worker_entry->instance->def->program);
|
|
158 DEBUGPRINTF("Split@String: delim(%s) string(%s)\n", delim, string);
|
|
159 for(i = 0; i < len; ++i)
|
|
160 {
|
|
161 if(string[i] == delim[search_offset])
|
|
162 {
|
|
163 if(search_offset == (delimlen-1))
|
|
164 {
|
|
165 params[1] = make_string(string + start, i-start-(delimlen-1), worker_entry->instance->def->program);
|
|
166 DEBUGPRINTF("Appending %s(%d) to list\n", params[1]->c.generic.data, params[1]->c.generic.len);
|
|
167 vis_list_append(params, worker_entry);
|
|
168 start = i+1;
|
|
169 search_offset = 0;
|
|
170 }
|
|
171 else
|
|
172 ++search_offset;
|
|
173 }
|
|
174 else if(search_offset > 0)
|
|
175 {
|
|
176 i = (i-search_offset+1);
|
|
177 search_offset = 0;
|
|
178 }
|
|
179 }
|
|
180 if(len)
|
|
181 {
|
|
182 params[1] = make_string(string + start, i-start, worker_entry->instance->def->program);
|
|
183 vis_list_append(params, worker_entry);
|
|
184 }
|
|
185 DEBUGPUTS("End Split@String\n");
|
|
186
|
|
187 release_ref(inputlist[0]);
|
|
188 release_ref(inputlist[1]);
|
|
189 inputlist[0] = params[0];
|
|
190 return 0;
|
|
191 }
|
|
192
|
|
193 int vis_string_put_raw(datum ** inputlist, queue_entry * worker_entry)
|
|
194 {
|
|
195 int old_len = inputlist[0]->c.generic.len;
|
|
196 char * data;
|
|
197 inputlist[0] = copy_datum(inputlist[0], old_len + inputlist[1]->c.generic.len);
|
|
198 data = inputlist[0]->c.generic.data;
|
|
199 memcpy(data + old_len - 1, inputlist[1]->c.generic.data, inputlist[1]->c.generic.len);
|
|
200 release_ref(inputlist[1]);
|
|
201 data[inputlist[0]->c.generic.len-1] = '\0';
|
|
202 return 0;
|
|
203 }
|
|
204
|
|
205 int vis_string_get_raw(datum ** inputlist, queue_entry * worker_entry)
|
|
206 {
|
|
207 char * data = inputlist[0]->c.generic.data;
|
|
208 datum * output;
|
|
209 inputlist[1] = copy_datum(inputlist[1], 0);
|
|
210 memcpy(inputlist[1]->c.generic.data, data, inputlist[1]->c.generic.len);
|
|
211 output = make_string(data + inputlist[1]->c.generic.len, inputlist[0]->c.generic.len - inputlist[1]->c.generic.len - 1, worker_entry->instance->def->program);
|
|
212 release_ref(inputlist[0]);
|
|
213 inputlist[0] = output;
|
|
214 return 0;
|
|
215 }
|
|
216
|
|
217 int vis_string_slice(datum ** inputlist, queue_entry * worker_entry)
|
|
218 {
|
|
219 char * string;
|
|
220 int index = inputlist[1]->c.integers.num_a;
|
|
221 release_ref(inputlist[1]);
|
|
222 if(index < (inputlist[0]->c.generic.len-1))
|
|
223 {
|
|
224 inputlist[1] = new_datum_comp(inputlist[0]->company, 1, inputlist[0]->c.generic.len-index);
|
|
225 memcpy(inputlist[1]->c.generic.data, (char *)(inputlist[0]->c.generic.data) + index, inputlist[0]->c.generic.len-index);
|
|
226 inputlist[0] = copy_datum(inputlist[0], index+1);
|
|
227 string = inputlist[0]->c.generic.data;
|
|
228 string[index] = '\0';
|
|
229 }
|
|
230 else
|
|
231 {
|
|
232 inputlist[1] = new_datum_comp(inputlist[0]->company, 1, 1);
|
|
233 string = inputlist[1]->c.generic.data;
|
|
234 string[0] = '\0';
|
|
235 }
|
|
236 return 0;
|
|
237 }
|
|
238
|
|
239 int vis_string_reverse(datum ** inputlist, queue_entry * worker_entry)
|
|
240 {
|
|
241 int ref_count, i,j;
|
|
242 datum * output;
|
|
243 char *source, *dest, tmp;
|
|
244 VIS_EnterCriticalSection(inputlist[0]->lock);
|
|
245 ref_count = inputlist[0]->ref_count;
|
|
246 VIS_LeaveCriticalSection(inputlist[0]->lock);
|
|
247
|
|
248 if(ref_count > 1)
|
|
249 output = new_datum_comp(inputlist[0]->company, 1, inputlist[0]->c.generic.len);
|
|
250 else
|
|
251 output = inputlist[0];
|
|
252 source = inputlist[0]->c.generic.data;
|
|
253
|
|
254 if(ref_count > 1)
|
|
255 {
|
|
256 dest = output->c.generic.data;
|
|
257 i = 0;
|
|
258 for(j = output->c.generic.len-2; j >= 0; --j)
|
|
259 dest[j] = source[i++];
|
|
260 release_ref(inputlist[0]);
|
|
261 inputlist[0] = output;
|
|
262 }
|
|
263 else
|
|
264 {
|
|
265 i = 0;
|
|
266 for(j = output->c.generic.len-2; j > i; --j)
|
|
267 {
|
|
268 tmp = source[i];
|
|
269 source[i++] = source[j];
|
|
270 source[j] = tmp;
|
|
271 }
|
|
272 }
|
|
273 return 0;
|
|
274 }
|
|
275
|
|
276 int vis_string_length(datum ** inputlist, queue_entry * worker_entry)
|
|
277 {
|
|
278 int len = inputlist[0]->c.generic.len-1;
|
|
279 release_ref(inputlist[0]);
|
|
280 inputlist[0] = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, worker_entry->instance->def->program);
|
|
281 inputlist[0]->c.integers.num_a = len;
|
|
282 return 0;
|
|
283 }
|
|
284
|
|
285 int vis_string_put_byte(datum ** inputlist, queue_entry * worker_entry)
|
|
286 {
|
|
287 inputlist[0] = copy_datum(inputlist[0], inputlist[0]->c.generic.len + 1);
|
|
288 ((unsigned char *)(inputlist[0]->c.generic.data))[inputlist[0]->c.generic.len - 2] = (unsigned char)inputlist[1]->c.integers.num_a;
|
|
289 ((unsigned char *)(inputlist[0]->c.generic.data))[inputlist[0]->c.generic.len - 1] = '\0';
|
|
290 release_ref(inputlist[1]);
|
|
291 return 0;
|
|
292 }
|
|
293
|
|
294 int vis_string_get_dstring(datum ** inputlist, queue_entry * worker_entry)
|
|
295 {
|
|
296 datum ** delimlist;
|
|
297 int num_delims;
|
|
298 int i,len,delimlen;
|
|
299 char *current;
|
|
300 BOOL match=FALSE;
|
|
301 datum * temp;
|
|
302 if(inputlist[1]->company->type_id == BUILTIN_TYPE_LIST)
|
|
303 {
|
|
304 delimlist = ((list_data *)inputlist[1]->c.generic.data)->entries;
|
|
305 num_delims = ((list_data *)inputlist[1]->c.generic.data)->num_entries;
|
|
306 //TODO: check to make sure that all of the list entries are strings
|
|
307 }
|
|
308 else if(inputlist[1]->company->type_id == BUILTIN_TYPE_STRING)
|
|
309 {
|
|
310 delimlist = inputlist+1;
|
|
311 num_delims = 1;
|
|
312 }
|
|
313 else
|
|
314 {
|
|
315 ERRORPUTS("Second argument to Get DString@String must be either a String or a List");
|
|
316 release_ref(inputlist[0]);
|
|
317 release_ref(inputlist[1]);
|
|
318 return -1;
|
|
319 }
|
|
320 current = inputlist[0]->c.generic.data;
|
|
321 len = inputlist[0]->c.generic.len - 1;
|
|
322 while(len && !match)
|
|
323 {
|
|
324 for(i = 0; i < num_delims; ++i)
|
|
325 {
|
|
326 delimlen = delimlist[i]->c.generic.len-1;
|
|
327 if(len >= delimlen && !memcmp(current, delimlist[i]->c.generic.data, delimlen))
|
|
328 {
|
|
329 match = TRUE;
|
|
330 //deal with the fact that we're going to adjust current and len even though we're done
|
|
331 --current;
|
|
332 ++len;
|
|
333 break;
|
|
334 }
|
|
335 }
|
|
336 ++current;
|
|
337 --len;
|
|
338 }
|
|
339 if(match)
|
|
340 {
|
|
341 inputlist[2] = add_ref(delimlist[i]);
|
|
342 release_ref(inputlist[1]);
|
|
343 inputlist[1] = make_string(inputlist[0]->c.generic.data, current - ((char *)inputlist[0]->c.generic.data), worker_entry->instance->def->program);
|
|
344 delimlen = inputlist[2]->c.generic.len-1;
|
|
345 temp = make_string(current+delimlen, len-delimlen, worker_entry->instance->def->program);
|
|
346 release_ref(inputlist[0]);
|
|
347 inputlist[0] = temp;
|
|
348 inputlist[3] = NULL;
|
|
349 }
|
|
350 else
|
|
351 {
|
|
352 release_ref(inputlist[1]);
|
|
353 inputlist[1] = inputlist[0];
|
|
354 inputlist[0] = NULL;
|
|
355 inputlist[2] = NULL;
|
|
356 inputlist[3] = new_datum(BUILTIN_TYPE_YESNO, 2, 0, worker_entry->instance->def->program);
|
|
357 inputlist[3]->c.integers.num_a = 0;
|
|
358 }
|
|
359 return 0;
|
|
360 }
|