Mercurial > repos > rhope
view string.c @ 121:1af91ceaaf49
Fixed memory leak when an output is only attached to a single null input
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Thu, 28 Oct 2010 21:04:12 -0400 |
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; }