view string.c @ 163:9fab36cc706b

Add Raw Size method to blueprint to allow code to query the raw size of a type in bytes
author Mike Pavone <pavone@retrodev.com>
date Sun, 09 Jan 2011 23:03:30 -0500
parents 3cc5e4a42344
children
line wrap: on
line source

#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[512];//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);
	if(string)
		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");
		print_stack_trace(worker_entry->instance);
		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;
}

int vis_string_lefttrim(datum ** params, queue_entry * entry)
{
	BOOL isatrimchar;
	int i,j;
	char *string,*trim_chars;
	string = params[0]->c.generic.data;
	trim_chars = params[1]->c.generic.data;
	isatrimchar = TRUE;
	for(i = 0; i < params[0]->c.generic.len-1; ++i)
	{
		isatrimchar = FALSE;
		for(j = 0; j < params[1]->c.generic.len-1; ++j)
			if(string[i] == trim_chars[j])
			{
				isatrimchar = TRUE;
				break;
			}
		if(!isatrimchar)
			break;
	}
	release_ref(params[1]);
	params[1] = params[0];
	params[0] = make_string(string+i, params[1]->c.generic.len-1-i, entry->instance->def->program);
	release_ref(params[1]);
	return 0;
}

int vis_string_righttrim(datum ** params, queue_entry * entry)
{
	BOOL isatrimchar;
	int i,j;
	char *string,*trim_chars;
	string = params[0]->c.generic.data;
	trim_chars = params[1]->c.generic.data;
	isatrimchar = TRUE;
	for(i = params[0]->c.generic.len-2; i >= 0 ; --i)
	{
		isatrimchar = FALSE;
		for(j = 0; j < params[1]->c.generic.len-1; ++j)
			if(string[i] == trim_chars[j])
			{
				isatrimchar = TRUE;
				break;
			}
		if(!isatrimchar)
			break;
	}
	release_ref(params[1]);
	params[1] = params[0];
	params[0] = make_string(string, i+1, entry->instance->def->program);
	release_ref(params[1]);
	return 0;
}