int traverse(const parsetree_statement_t *stmt, void *bgtheme) { const char *identifier; const parsetree_parameter_t *param_list; const parsetree_parameter_t *p1; background_t *bg; bgtheme_t *theme = (bgtheme_t*)bgtheme; identifier = nanoparser_get_identifier(stmt); param_list = nanoparser_get_parameter_list(stmt); if(str_icmp(identifier, "background") == 0) { p1 = nanoparser_get_nth_parameter(param_list, 1); nanoparser_expect_program(p1, "Can't read background. Missing background attributes"); bg = background_new(); theme->data = reallocx(theme->data, (++(theme->length)) * sizeof(*(theme->data))); theme->data[theme->length-1] = bg; nanoparser_traverse_program_ex(nanoparser_get_program(p1), (void*)bg, traverse_background_attributes); validate_background(bg); actor_change_animation(bg->actor, bg->data->animation_data[0]); } else fatal_error("Can't read background. Unknown identifier: '%s'", identifier); return 0; }
static int realloc_eval_stack( cexception_t * ex ) { /* The 'eval' stack should not have any references from the garbage-collected blocks, so it can be safely reallocated. */ if( stack_realloc_delta <= 0 ) { return 0; } else { stackcell_t *old_eval_stack = istate.eval_stack; ssize_t old_eval_stack_length = istate.eval_stack_length; ssize_t delta, offset, full_offset; istate.eval_stack = reallocx( istate.eval_stack, sizeof(istate.eval_stack[0]) * (istate.eval_stack_length + stack_realloc_delta), ex ); istate.eval_stack_length += stack_realloc_delta; delta = (char*)istate.eval_stack - (char*)old_eval_stack; offset = stack_realloc_delta * sizeof(istate.eval_stack[0]); full_offset = offset + delta; /* We must use memmove() since the source and the destination overlap: */ memmove( ((char*)istate.eval_stack) + offset, istate.eval_stack, old_eval_stack_length * sizeof(istate.eval_stack[0])); istate.ep_bottom = (stackcell_t*)(((char*)istate.ep_bottom) + full_offset); istate.ep = (stackcell_t*)(((char*)istate.ep) + full_offset); istate.ep_top = istate.eval_stack + STACK_SAFETY_MARGIN; struct interpret_exception_t *current_xp; for( current_xp = istate.xp; current_xp != NULL; current_xp = current_xp->old_xp.ptr ) { current_xp->ep = (stackcell_t*)((char*)(current_xp->ep) + full_offset ); } #if 0 memset( istate.eval_stack, 0xAA, stack_realloc_delta * sizeof(istate.eval_stack[0])); #endif return 1; } }
void badd(blk *b, void *data, int len) { if (b->alloc_bytes - b->used_bytes < len) { while (b->alloc_bytes - b->used_bytes < len) { b->alloc_bytes+= (b->chunk_size * b->elem_bytes); } b->ptr=reallocx(b->ptr, b->alloc_bytes); } memcpy(b->ptr + b->used_bytes, data, len); b->used_bytes += len; memset(b->ptr + b->used_bytes, 0, b->alloc_bytes - b->used_bytes); }
/* * Sync any changes to disk, then truncate or extend file so its size * is length. This is only intended to be called before close, if the * file is open for writing and the actual size does not match the * calculated size, perhaps as the result of having been previously * written in NOFILL mode. */ static int memio_pad_length(ncio* nciop, off_t length) { NCMEMIO* memio; size_t len = (size_t)length; if(nciop == NULL || nciop->pvt == NULL) return NC_EINVAL; memio = (NCMEMIO*)nciop->pvt; if(!fIsSet(nciop->ioflags,NC_WRITE)) return EPERM; /* attempt to write readonly file*/ if(memio->locked) return NC_EINMEMORY; if(len > memio->alloc) { /* Realloc the allocated memory to a multiple of the pagesize*/ size_t newsize = (size_t)len; void* newmem = NULL; /* Round to a multiple of pagesize */ if((newsize % pagesize) != 0) newsize += (pagesize - (newsize % pagesize)); newmem = (char*)reallocx(memio->memory,newsize,memio->alloc); if(newmem == NULL) return NC_ENOMEM; /* If not copy is set, then fail if the newmem address is different from old address */ if(newmem != memio->memory) { memio->modified++; if(memio->locked) { free(newmem); return NC_EINMEMORY; } } /* zero out the extra memory */ memset((void*)((char*)newmem+memio->alloc),0,(size_t)(newsize - memio->alloc)); #ifdef DEBUG fprintf(stderr,"realloc: %lu/%lu -> %lu/%lu\n", (unsigned long)memio->memory,(unsigned long)memio->alloc, (unsigned long)newmem,(unsigned long)newsize); #endif if(memio->memory != NULL && (!memio->locked || memio->modified)) free(memio->memory); memio->memory = newmem; memio->alloc = newsize; memio->modified = 1; } memio->size = len; return NC_NOERR; }
static void thrcode_alloc( THRCODE *bc, size_t delta, cexception_t *ex ) { size_t new_capacity; assert( delta >= 0 ); assert( bc->length <= bc->capacity ); if( bc->length + delta <= bc->capacity ) return; new_capacity = bc->capacity + (ALLOC_CHUNK > delta ? ALLOC_CHUNK : delta); bc->opcodes = reallocx( bc->opcodes, new_capacity * sizeof(bc->opcodes[0]), ex ); bc->capacity = new_capacity; }
static THRCODE *thrcode_insert_string( THRCODE *tc, char * volatile *str, cexception_t *ex ) { ssize_t len = thrcode_line_count( tc );; assert( tc ); assert( str ); tc->lines = reallocx( tc->lines, sizeof(tc->lines[0]) * (len + 2), ex ); tc->lines[len+1] = NULL; tc->lines[len] = *str; *str = NULL; return tc; }
// assumes a content type of "application/x-www-form-urlencoded" (the default type) void get_form_values(struct hitArgs *args, char *body) { char *saveptr; int t=0, i, alloc = FORM_VALUE_BLOCK; char *tmp, *token = strtok_r(body, "&", &saveptr); args->form_values = mallocx(alloc * sizeof(FORM_VALUE)); memset(args->form_values, 0, alloc * sizeof(FORM_VALUE)); while(token != NULL) { tmp = mallocx((int)strlen(token)+1); strcpy(tmp, token); url_decode(tmp); for (i=0; i<strlen(tmp); i++) { if (tmp[i]=='=') break; } // don't allow i to be set to strlen(tmp) - to prevent reading other memory if (i>0 && i==strlen(tmp)) i--; if (alloc <= t) { int newsize = alloc+FORM_VALUE_BLOCK; args->form_values = reallocx(args->form_values, newsize * sizeof(FORM_VALUE)); memset(args->form_values+alloc, 0, FORM_VALUE_BLOCK * sizeof(FORM_VALUE)); alloc = newsize; } args->form_values[t].data = mallocx((int)strlen(tmp)+1); strcpy(args->form_values[t].data, tmp); args->form_values[t].name = args->form_values[t].data; args->form_values[t].value = args->form_values[t].data+1+i; args->form_values[t++].data[i] = 0; token = strtok_r(NULL, "&", &saveptr); free (tmp); } args->form_value_counter = t; }
static void thrcode_merge_line_lists( THRCODE *code1, THRCODE *code2, cexception_t *ex ) { ssize_t i; ssize_t len1 = thrcode_line_count( code1 ); ssize_t len2 = thrcode_line_count( code2 ); ssize_t len = len1 + len2; if( code1->flags & THRF_IMMEDIATE_PRINTOUT ) { thrcode_flush_lines( code2 ); } else { code1->lines = reallocx( code1->lines, sizeof(code1->lines[0]) * (len + 1), ex ); memmove( code1->lines + len1, code2->lines, sizeof(code1->lines[0]) * len2 ); code1->lines[len] = NULL; for( i = 0; i < len2; i ++ ) { code2->lines = NULL; } } }
int main( int argc, char *argv[], char *env[] ) { cexception_t inner; char ** volatile files = NULL; CIF * volatile cif = NULL; int retval = 0; int i; progname = argv[0]; tags.value.s = ""; separator.value.s = " "; vseparator.value.s = ","; print_filename.value.b = 0; print_dataname.value.b = 1; char ** taglist = NULL; int tagcount = 0; cexception_guard( inner ) { files = get_optionsx( argc, argv, options, &inner ); char * tag_pointer = tags.value.s; char * end_pointer = strchr( tags.value.s, ',' ); if( !tags.present || !tags.value.s || !tags.value.s[0] ) { fprintf( stderr, "%s: no data items to extract from the input, please " "specify them using --tag option (--help for examples)\n", argv[0] ); exit(0); } while( tag_pointer != NULL ) { tagcount++; int taglen; if( end_pointer != NULL ) { taglen = end_pointer - tag_pointer; } else { taglen = strchr( tag_pointer, '\0' ) - tag_pointer; } taglist = reallocx( taglist, sizeof( char * ) * tagcount, &inner ); taglist[tagcount - 1] = mallocx( taglen * sizeof( char ) + 1, &inner ); strncpy( taglist[tagcount - 1], tag_pointer, taglen ); int i; for( i = 0; i < taglen; i++ ) { taglist[tagcount - 1][i] = tolower( taglist[tagcount - 1][i] ); } taglist[tagcount - 1][taglen] = '\0'; if( end_pointer != NULL ) { tag_pointer = end_pointer + 1; end_pointer = strchr( tag_pointer, ',' ); } else { tag_pointer = NULL; } } } cexception_catch { fprintf( stderr, "%s: %s\n", argv[0], cexception_message( &inner )); exit(1); } if( files[0] == NULL && isatty(0) && isatty(1) ) { fprintf( stderr, "%s: Usage: %s data.cif\n", argv[0], argv[0] ); exit(2); } cif_yy_debug_off(); cif_flex_debug_off(); cif_debug_off(); if( debug.present ) { if( strstr(debug.value.s, "lex") != NULL ) cif_flex_debug_yyflex(); if( strstr(debug.value.s, "yacc") != NULL ) cif_yy_debug_on(); if( strstr(debug.value.s, "yylval") != NULL ) cif_flex_debug_yylval(); if( strstr(debug.value.s, "text") != NULL ) cif_flex_debug_yytext(); if( strstr(debug.value.s, "code") != NULL ) { cif_flex_debug_lines(); cif_debug_on(); } } for( i = 0; i == 0 || files[i] != NULL; i++ ) { char * volatile filename = NULL; cexception_guard( inner ) { filename = files[i] ? files[i] : "-"; cif = new_cif_from_cif_file( files[i], cif_option_default(), &inner ); if( cif && cif_nerrors( cif ) == 0 ) { if( debug.present && strstr(debug.value.s, "dump") != NULL ) { cif_print( cif ); } else { if( ( !cif_datablock_list( cif ) || !datablock_next( cif_datablock_list( cif ))) && !datablock_name( cif_datablock_list( cif ))) { fprintf( stderr, "%s: file '%s' seems to be empty (no named datablocks)\n", argv[0], filename ); } else { cif_print_tag_values ( cif, taglist, tagcount, ( print_filename.value.b == 1 ? filename : "" ), print_dataname.value.b, separator.value.s, vseparator.value.s ); } } delete_cif( cif ); cif = NULL; filename = NULL; } } cexception_catch { if( filename ) { fprintf( stderr, "%s: %s: %s\n", argv[0], filename, cexception_message( &inner )); } else { fprintf( stderr, "%s: %s\n", argv[0], cexception_message( &inner )); } delete_cif( cif ); retval = 3; cif = NULL; } } delete_cif( cif ); freex( files ); return retval; }
/* This function opens the data file or inmemory data path - path of data file. ioflags - flags passed into nc_open. igeto - looks like this function can do an initial page get, and igeto is going to be the offset for that. But it appears to be unused igetsz - the size in bytes of initial page get (a.k.a. extent). Not ever used in the library. sizehintp - the size of a page of data for buffered reads and writes. parameters - arbitrary data nciopp - pointer to pointer that will get address of newly created and inited ncio struct. mempp - pointer to pointer to the initial memory read. */ int memio_open(const char* path, int ioflags, off_t igeto, size_t igetsz, size_t* sizehintp, void* parameters, ncio* *nciopp, void** const mempp) { ncio* nciop = NULL; int fd = -1; int status = NC_NOERR; size_t sizehint = 0; NC_memio meminfo; /* use struct to avoid worrying about free'ing it */ NCMEMIO* memio = NULL; size_t initialsize; /* Should be the case that diskless => inmemory but not converse */ int diskless = (fIsSet(ioflags,NC_DISKLESS)); int inmemory = fIsSet(ioflags,NC_INMEMORY); int locked = 0; assert(inmemory ? !diskless : 1); if(path == NULL || strlen(path) == 0) return NC_EINVAL; assert(sizehintp != NULL); sizehint = *sizehintp; memset(&meminfo,0,sizeof(meminfo)); if(inmemory) { /* parameters provide the memory chunk */ NC_memio* memparams = (NC_memio*)parameters; meminfo = *memparams; locked = fIsSet(meminfo.flags,NC_MEMIO_LOCKED); /* As a safeguard, if !locked and NC_WRITE is set, then we must take control of the incoming memory */ if(!locked && fIsSet(ioflags,NC_WRITE)) { memparams->memory = NULL; } } else { /* read the file into a chunk of memory*/ assert(diskless); status = readfile(path,&meminfo); if(status != NC_NOERR) {goto unwind_open;} } /* Fix up initial size */ initialsize = meminfo.size; /* create the NCMEMIO structure */ status = memio_new(path, ioflags, initialsize, &nciop, &memio); if(status != NC_NOERR) {goto unwind_open;} memio->locked = locked; /* Initialize the memio memory */ memio->memory = meminfo.memory; /* memio_new may have modified the allocated size, in which case, reallocate the memory unless the memory is locked. */ if(memio->alloc > meminfo.size) { if(memio->locked) memio->alloc = meminfo.size; /* force it back to what it was */ else { void* oldmem = memio->memory; memio->memory = reallocx(oldmem,memio->alloc,meminfo.size); if(memio->memory == NULL) {status = NC_ENOMEM; goto unwind_open;} } } #ifdef DEBUG fprintf(stderr,"memio_open: initial memory: %lu/%lu\n",(unsigned long)memio->memory,(unsigned long)memio->alloc); #endif if(memio->persist) { /* Verify the file is writeable and exists */ if(!fileexists(path)) {status = ENOENT; goto unwind_open;} if(!fileiswriteable(path)) {status = EACCES; goto unwind_open;} } /* Use half the filesize as the blocksize ; why? */ sizehint = (size_t)(memio->alloc/2); /* sizehint must be multiple of 8 */ sizehint = (sizehint / 8) * 8; if(sizehint < 8) sizehint = 8; fd = nc__pseudofd(); *((int* )&nciop->fd) = fd; if(igetsz != 0) { status = nciop->get(nciop, igeto, igetsz, 0, mempp); if(status != NC_NOERR) goto unwind_open; } if(sizehintp) *sizehintp = sizehint; if(nciopp) *nciopp = nciop; else {ncio_close(nciop,0);} return NC_NOERR; unwind_open: if(fd >= 0) close(fd); memio_close(nciop,0); return status; }
/* * traverse_sprite_attributes() * Sprite attributes traversal */ int traverse_sprite_attributes(const parsetree_statement_t *stmt, void *spriteinfo) { const char *identifier; const parsetree_parameter_t *param_list; const parsetree_parameter_t *p1, *p2, *p3, *p4; spriteinfo_t *s = (spriteinfo_t*)spriteinfo; int anim_id = 0; identifier = nanoparser_get_identifier(stmt); param_list = nanoparser_get_parameter_list(stmt); if(str_icmp(identifier, "source_file") == 0) { p1 = nanoparser_get_nth_parameter(param_list, 1); nanoparser_expect_string(p1, "Must provide path to the source_file"); if(s->source_file != NULL) free(s->source_file); s->source_file = str_dup(nanoparser_get_string(p1)); } else if(str_icmp(identifier, "source_rect") == 0) { p1 = nanoparser_get_nth_parameter(param_list, 1); p2 = nanoparser_get_nth_parameter(param_list, 2); p3 = nanoparser_get_nth_parameter(param_list, 3); p4 = nanoparser_get_nth_parameter(param_list, 4); nanoparser_expect_string(p1, "Must provide four numbers to source_rect: xpos, ypos, width, height"); nanoparser_expect_string(p2, "Must provide four numbers to source_rect: xpos, ypos, width, height"); nanoparser_expect_string(p3, "Must provide four numbers to source_rect: xpos, ypos, width, height"); nanoparser_expect_string(p4, "Must provide four numbers to source_rect: xpos, ypos, width, height"); s->rect_x = max(0, atoi(nanoparser_get_string(p1))); s->rect_y = max(0, atoi(nanoparser_get_string(p2))); s->rect_w = max(1, atoi(nanoparser_get_string(p3))); s->rect_h = max(1, atoi(nanoparser_get_string(p4))); } else if(str_icmp(identifier, "frame_size") == 0) { p1 = nanoparser_get_nth_parameter(param_list, 1); p2 = nanoparser_get_nth_parameter(param_list, 2); nanoparser_expect_string(p1, "Must provide two numbers to frame_size: width, height"); nanoparser_expect_string(p2, "Must provide two numbers to frame_size: width, height"); s->frame_w = max(1, atoi(nanoparser_get_string(p1))); s->frame_h = max(1, atoi(nanoparser_get_string(p2))); } else if(str_icmp(identifier, "hot_spot") == 0) { p1 = nanoparser_get_nth_parameter(param_list, 1); p2 = nanoparser_get_nth_parameter(param_list, 2); nanoparser_expect_string(p1, "Must provide two numbers to hot_spot: xpos, ypos"); nanoparser_expect_string(p2, "Must provide two numbers to hot_spot: xpos, ypos"); s->hot_spot.x = (float)atoi(nanoparser_get_string(p1)); s->hot_spot.y = (float)atoi(nanoparser_get_string(p2)); } else if(str_icmp(identifier, "animation") == 0) { p1 = nanoparser_get_nth_parameter(param_list, 1); p2 = nanoparser_get_nth_parameter(param_list, 2); if(p1 && p2) { nanoparser_expect_string(p1, "Must provide animation number"); nanoparser_expect_program(p2, "Must provide animation attributes"); anim_id = atoi(nanoparser_get_string(p1)); if(anim_id < 0 || anim_id >= SPRITE_MAX_ANIM) fatal_error("Can't load sprites. Animation number must be in range 0..%d\nin\"%s\" near line %d", SPRITE_MAX_ANIM-1, nanoparser_get_file(stmt), nanoparser_get_line_number(stmt)); } else if(p1) { nanoparser_expect_program(p1, "Must provide animation attributes"); anim_id = 0; p2 = p1; } else fatal_error("No attributes provided to 'animation' block\nin\"%s\" near line %d", nanoparser_get_file(stmt), nanoparser_get_line_number(stmt)); if(anim_id < s->animation_count && NULL != s->animation_data[anim_id]) s->animation_data[anim_id] = animation_delete(s->animation_data[anim_id]); s->animation_count = max(s->animation_count, anim_id+1); s->animation_data = reallocx(s->animation_data, sizeof(animation_t*) * s->animation_count); /* TODO: watch this! It may generate garbage in the middle. */ s->animation_data[anim_id] = animation_new(anim_id); nanoparser_traverse_program_ex(nanoparser_get_program(p2), s->animation_data[anim_id], traverse_animation_attributes); validate_animation(s->animation_data[anim_id]); } else fatal_error("Can't load sprites. Unknown identifier '%s'\nin\"%s\" near line %d", identifier, nanoparser_get_file(stmt), nanoparser_get_line_number(stmt)); return 0; }
static int realloc_call_stack( cexception_t * ex ) { /* The 'call' can be pointed to from the evaluation stack, therefore references on the evaluation stack must be adjusted after the reallocation. */ if( stack_realloc_delta <= 0 ) { return 0; } else { stackcell_t *old_call_stack = istate.call_stack; stackcell_t *old_call_limit = istate.call_stack + istate.call_stack_length; stackcell_t *ep, *ep_limit, *sp, *sp_limit; ssize_t old_call_stack_length = istate.call_stack_length; ssize_t delta, offset, full_offset; istate.call_stack = reallocx( istate.call_stack, sizeof(istate.call_stack[0]) * (istate.call_stack_length + stack_realloc_delta), ex ); istate.call_stack_length += stack_realloc_delta; offset = stack_realloc_delta * sizeof(istate.call_stack[0]); /* We must use memmove() since the source and the destination overlap: */ memmove( ((char*)istate.call_stack) + offset, istate.call_stack, old_call_stack_length * sizeof(istate.call_stack[0])); delta = (char*)istate.call_stack - (char*)old_call_stack; full_offset = offset + delta; /* Adjust pointers on the evaluation stack so that they point to the moved elements on the newly reallocated call stack: */ if( full_offset != 0 ) { ep_limit = istate.eval_stack + istate.eval_stack_length; for( ep = istate.eval_stack; ep < ep_limit; ep++ ) { if( ep->PTR >= (void*)old_call_stack && ep->PTR < (void*)old_call_limit ) { ep->PTR = (char*)(ep->PTR) + full_offset; //printf( "<<<< Moving on eval: %p -> %p\n", ep->PTR-full_offset, ep->PTR ); } } sp_limit = istate.call_stack + istate.call_stack_length; for( sp = istate.call_stack; sp < sp_limit; sp++ ) { //printf( ">>> checking call stack %p, PTR = %p\n", sp, sp->PTR ); if( sp->PTR >= (void*)old_call_stack && sp->PTR < (void*)old_call_limit ) { sp->PTR = (char*)(sp->PTR) + full_offset; //printf( ">>> Moving on call: %p -> %p\n", sp->PTR-full_offset, sp->PTR ); } } } #if 0 printf( "reallocating call stack, length = %d, delta = %d, full_offset = %d\n", istate.call_stack_length, delta, full_offset ); printf( "old call stack = %p, new call stack = %p\n", old_call_stack, istate.call_stack ); #endif istate.bottom = (stackcell_t*)((char*)(istate.bottom) + full_offset); istate.fp = (stackcell_t*)((char*)(istate.fp) + full_offset); istate.sp = (stackcell_t*)((char*)(istate.sp) + full_offset); istate.gp = (stackcell_t*)((char*)(istate.gp) + full_offset); istate.top = istate.call_stack + STACK_SAFETY_MARGIN; /* Adjust exception structure pointers: */ struct interpret_exception_t *current_xp; for( current_xp = istate.xp; current_xp != NULL; current_xp = current_xp->old_xp.ptr ) { current_xp->fp = (stackcell_t*)((char*)(current_xp->fp) + full_offset ); current_xp->sp = (stackcell_t*)((char*)(current_xp->sp) + full_offset ); } #if 1 memset( istate.call_stack, 0x55, stack_realloc_delta * sizeof(istate.call_stack[0])); #endif return 1; } }