Mercurial > repos > rhope
diff string.c @ 0:76568becd6d6
Rhope Alpha 2a source import
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Tue, 28 Apr 2009 23:06:07 +0000 |
parents | |
children | 94c885692eb5 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/string.c Tue Apr 28 23:06:07 2009 +0000 @@ -0,0 +1,360 @@ +#include "datum.h" +#include "structs.h" +#include "interp.h" +#include <string.h> +#include <stdlib.h> + + +int vis_inttostring(datum ** inputlist, queue_entry * worker_entry) +{ + int i,j,val; + char temp_buf[12]; + datum * output; + char * out_buf; + //sprintf(temp_buf, "%d", inputlist[0]->c.integers.num_a); + val = (inputlist[0]->c.integers.num_a >= 0 ? inputlist[0]->c.integers.num_a : 0-inputlist[0]->c.integers.num_a); + i = 0; + if(!val) + temp_buf[i++] = '0'; + + while(val > 0) + { + temp_buf[i] = (val % 10) + '0'; + val /= 10; + ++i; + } + if(inputlist[0]->c.integers.num_a < 0) + { + temp_buf[i] = '-'; + ++i; + } + release_ref(inputlist[0]); + inputlist[0] = new_datum(BUILTIN_TYPE_STRING, 1, i+1, worker_entry->instance->def->program); + out_buf = inputlist[0]->c.generic.data; + out_buf[i] = '\0'; + j = 0; + --i; + while(i >= 0) + { + out_buf[j] = temp_buf[i]; + ++j; + --i; + } + //strcpy(inputlist[0]->c.generic.data, temp_buf); + return 0; + +} + +#ifndef SEGA +int vis_realtostring(datum ** inputlist, queue_entry * worker_entry) +{ + char temp_buf[30];//Is this enough? + datum * output; + sprintf(temp_buf, "%f", inputlist[0]->c.real); + release_ref(inputlist[0]); + inputlist[0] = new_datum(BUILTIN_TYPE_STRING, 1, strlen(temp_buf)+1, worker_entry->instance->def->program); + strcpy(inputlist[0]->c.generic.data, temp_buf); + return 0; + +} +#endif + +int vis_stringequal(datum ** inputlist, queue_entry * worker_entry) +{ + int result = strcmp(inputlist[0]->c.generic.data, inputlist[1]->c.generic.data); + release_ref(inputlist[0]); + release_ref(inputlist[1]); + inputlist[0] = new_datum(BUILTIN_TYPE_YESNO, 2, 0, worker_entry->instance->def->program); + datum_set_yesno(inputlist[0], (result == 0 ? 1 : 0)); + return 0; +} + +int vis_append(datum ** inputlist, queue_entry * worker_entry) +{ + datum * output; + int temp_size = inputlist[0]->c.generic.len; + DEBUGPUTS("Begin vis_append\n"); + + DEBUGPRINTF("Left: %s(%d)\n", inputlist[0]->c.generic.data, inputlist[0]->c.generic.len); + DEBUGPRINTF("Right: %s(%d)\n", inputlist[1]->c.generic.data, inputlist[1]->c.generic.len); + output = new_datum(BUILTIN_TYPE_STRING, 1, temp_size+inputlist[1]->c.generic.len-1, worker_entry->instance->def->program); + memcpy(output->c.generic.data, inputlist[0]->c.generic.data, temp_size-1); + memcpy(((char *)output->c.generic.data)+temp_size-1, inputlist[1]->c.generic.data, inputlist[1]->c.generic.len-1); + ((char *)output->c.generic.data)[temp_size + inputlist[1]->c.generic.len-2]='\0'; + DEBUGPRINTF("Appended string: %s(%d)\n", output->c.generic.data, output->c.generic.len); + release_ref(inputlist[0]); + release_ref(inputlist[1]); + inputlist[0] = output; + DEBUGPUTS("End vis_append\n"); + + return 0; +} + +int vis_yesnotostring(datum ** inputlist, queue_entry * worker_entry) +{ + int result = inputlist[0]->c.integers.num_a; + release_ref(inputlist[0]); + if(result) + { + inputlist[0] = new_datum(BUILTIN_TYPE_STRING, 1, 4, worker_entry->instance->def->program); + strcpy(inputlist[0]->c.generic.data, "Yes"); + } + else + { + inputlist[0] = new_datum(BUILTIN_TYPE_STRING, 1, 3, worker_entry->instance->def->program); + strcpy(inputlist[0]->c.generic.data, "No"); + } + return 0; +} + +int vis_greaterstring(datum ** inputlist, queue_entry * worker_entry) +{ + int result; + if(strcmp(inputlist[0]->c.generic.data, inputlist[1]->c.generic.data) > 0) + result = 1; + else + result = 0; + release_ref(inputlist[0]); + release_ref(inputlist[1]); + inputlist[0] = new_datum(BUILTIN_TYPE_YESNO, 2, 0, worker_entry->instance->def->program); + datum_set_yesno(inputlist[0], result); + return 0; +} + +int vis_lesserstring(datum ** inputlist, queue_entry * worker_entry) +{ + int result; + if(strcmp(inputlist[0]->c.generic.data, inputlist[1]->c.generic.data) < 0) + result = 1; + else + result = 0; + release_ref(inputlist[0]); + release_ref(inputlist[1]); + inputlist[0] = new_datum(BUILTIN_TYPE_YESNO, 2, 0, worker_entry->instance->def->program); + datum_set_yesno(inputlist[0], result); + return 0; +} + +datum * make_string(const char * string, int len, program * prog) +{ + datum * output; + if(len < 0) + len = strlen(string); + output = new_datum(BUILTIN_TYPE_STRING, 1, len+1, prog); + memcpy(output->c.generic.data, string, len); + ((char *)output->c.generic.data)[len] = '\0'; + return output; +} + +int vis_string_split(datum ** inputlist, queue_entry * worker_entry) +{ + int i, start=0, len = inputlist[0]->c.generic.len-1; + char * string = inputlist[0]->c.generic.data; + char * delim = inputlist[1]->c.generic.data; + int delimlen = inputlist[1]->c.generic.len-1; + int search_offset = 0; + datum * params[2]; + params[0] = create_list(worker_entry->instance->def->program); + DEBUGPRINTF("Split@String: delim(%s) string(%s)\n", delim, string); + for(i = 0; i < len; ++i) + { + if(string[i] == delim[search_offset]) + { + if(search_offset == (delimlen-1)) + { + params[1] = make_string(string + start, i-start-(delimlen-1), worker_entry->instance->def->program); + DEBUGPRINTF("Appending %s(%d) to list\n", params[1]->c.generic.data, params[1]->c.generic.len); + vis_list_append(params, worker_entry); + start = i+1; + search_offset = 0; + } + else + ++search_offset; + } + else if(search_offset > 0) + { + i = (i-search_offset+1); + search_offset = 0; + } + } + if(len) + { + params[1] = make_string(string + start, i-start, worker_entry->instance->def->program); + vis_list_append(params, worker_entry); + } + DEBUGPUTS("End Split@String\n"); + + release_ref(inputlist[0]); + release_ref(inputlist[1]); + inputlist[0] = params[0]; + return 0; +} + +int vis_string_put_raw(datum ** inputlist, queue_entry * worker_entry) +{ + int old_len = inputlist[0]->c.generic.len; + char * data; + inputlist[0] = copy_datum(inputlist[0], old_len + inputlist[1]->c.generic.len); + data = inputlist[0]->c.generic.data; + memcpy(data + old_len - 1, inputlist[1]->c.generic.data, inputlist[1]->c.generic.len); + release_ref(inputlist[1]); + data[inputlist[0]->c.generic.len-1] = '\0'; + return 0; +} + +int vis_string_get_raw(datum ** inputlist, queue_entry * worker_entry) +{ + char * data = inputlist[0]->c.generic.data; + datum * output; + inputlist[1] = copy_datum(inputlist[1], 0); + memcpy(inputlist[1]->c.generic.data, data, inputlist[1]->c.generic.len); + 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); + release_ref(inputlist[0]); + inputlist[0] = output; + return 0; +} + +int vis_string_slice(datum ** inputlist, queue_entry * worker_entry) +{ + char * string; + int index = inputlist[1]->c.integers.num_a; + release_ref(inputlist[1]); + if(index < (inputlist[0]->c.generic.len-1)) + { + inputlist[1] = new_datum_comp(inputlist[0]->company, 1, inputlist[0]->c.generic.len-index); + memcpy(inputlist[1]->c.generic.data, (char *)(inputlist[0]->c.generic.data) + index, inputlist[0]->c.generic.len-index); + inputlist[0] = copy_datum(inputlist[0], index+1); + string = inputlist[0]->c.generic.data; + string[index] = '\0'; + } + else + { + inputlist[1] = new_datum_comp(inputlist[0]->company, 1, 1); + string = inputlist[1]->c.generic.data; + string[0] = '\0'; + } + return 0; +} + +int vis_string_reverse(datum ** inputlist, queue_entry * worker_entry) +{ + int ref_count, i,j; + datum * output; + char *source, *dest, tmp; + VIS_EnterCriticalSection(inputlist[0]->lock); + ref_count = inputlist[0]->ref_count; + VIS_LeaveCriticalSection(inputlist[0]->lock); + + if(ref_count > 1) + output = new_datum_comp(inputlist[0]->company, 1, inputlist[0]->c.generic.len); + else + output = inputlist[0]; + source = inputlist[0]->c.generic.data; + + if(ref_count > 1) + { + dest = output->c.generic.data; + i = 0; + for(j = output->c.generic.len-2; j >= 0; --j) + dest[j] = source[i++]; + release_ref(inputlist[0]); + inputlist[0] = output; + } + else + { + i = 0; + for(j = output->c.generic.len-2; j > i; --j) + { + tmp = source[i]; + source[i++] = source[j]; + source[j] = tmp; + } + } + return 0; +} + +int vis_string_length(datum ** inputlist, queue_entry * worker_entry) +{ + int len = inputlist[0]->c.generic.len-1; + release_ref(inputlist[0]); + inputlist[0] = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, worker_entry->instance->def->program); + inputlist[0]->c.integers.num_a = len; + return 0; +} + +int vis_string_put_byte(datum ** inputlist, queue_entry * worker_entry) +{ + inputlist[0] = copy_datum(inputlist[0], inputlist[0]->c.generic.len + 1); + ((unsigned char *)(inputlist[0]->c.generic.data))[inputlist[0]->c.generic.len - 2] = (unsigned char)inputlist[1]->c.integers.num_a; + ((unsigned char *)(inputlist[0]->c.generic.data))[inputlist[0]->c.generic.len - 1] = '\0'; + release_ref(inputlist[1]); + return 0; +} + +int vis_string_get_dstring(datum ** inputlist, queue_entry * worker_entry) +{ + datum ** delimlist; + int num_delims; + int i,len,delimlen; + char *current; + BOOL match=FALSE; + datum * temp; + if(inputlist[1]->company->type_id == BUILTIN_TYPE_LIST) + { + delimlist = ((list_data *)inputlist[1]->c.generic.data)->entries; + num_delims = ((list_data *)inputlist[1]->c.generic.data)->num_entries; + //TODO: check to make sure that all of the list entries are strings + } + else if(inputlist[1]->company->type_id == BUILTIN_TYPE_STRING) + { + delimlist = inputlist+1; + num_delims = 1; + } + else + { + ERRORPUTS("Second argument to Get DString@String must be either a String or a List"); + release_ref(inputlist[0]); + release_ref(inputlist[1]); + return -1; + } + current = inputlist[0]->c.generic.data; + len = inputlist[0]->c.generic.len - 1; + while(len && !match) + { + for(i = 0; i < num_delims; ++i) + { + delimlen = delimlist[i]->c.generic.len-1; + if(len >= delimlen && !memcmp(current, delimlist[i]->c.generic.data, delimlen)) + { + match = TRUE; + //deal with the fact that we're going to adjust current and len even though we're done + --current; + ++len; + break; + } + } + ++current; + --len; + } + if(match) + { + inputlist[2] = add_ref(delimlist[i]); + release_ref(inputlist[1]); + inputlist[1] = make_string(inputlist[0]->c.generic.data, current - ((char *)inputlist[0]->c.generic.data), worker_entry->instance->def->program); + delimlen = inputlist[2]->c.generic.len-1; + temp = make_string(current+delimlen, len-delimlen, worker_entry->instance->def->program); + release_ref(inputlist[0]); + inputlist[0] = temp; + inputlist[3] = NULL; + } + else + { + release_ref(inputlist[1]); + inputlist[1] = inputlist[0]; + inputlist[0] = NULL; + inputlist[2] = NULL; + inputlist[3] = new_datum(BUILTIN_TYPE_YESNO, 2, 0, worker_entry->instance->def->program); + inputlist[3]->c.integers.num_a = 0; + } + return 0; +}