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;
+}