void clearDelayed() { ListNode *n = envToClear.head; while ( n != NULL ) { /* deleteEnv((Env *) n->value, 1); */ listRemoveNoRegion( &envToClear, n ); n = envToClear.head; } n = hashtablesToClear.head; while ( n != NULL ) { deleteHashTable( ( Hashtable * ) n->value, nop ); listRemoveNoRegion( &hashtablesToClear, n ); n = hashtablesToClear.head; } n = regionsToClear.head; while ( n != NULL ) { region_free( ( Region * ) n->value ); listRemoveNoRegion( ®ionsToClear, n ); n = regionsToClear.head; } n = memoryToFree.head; while ( n != NULL ) { free( n->value ); listRemoveNoRegion( &memoryToFree, n ); n = memoryToFree.head; } }
int main(void){ //initialize stuff init_zobrist(); srand(time(NULL)); //create a new board Board_t* goal = newBoard(); //create a new visited cache HashTable_t* visited = newHashTable(32); //create a cloned state of the board and scrable it Board_t* scrabled = cloneBoard(goal); scramble_times(scrabled, TIMES_TO_SCRAMBLE); printf("Starting search...\n"); SearchNode_t* root = newSearchNode(scrabled, 0, NULL); SearchNode_t* result = idf_search(root, goal, visited, 30); //print out the search if(result!=NULL){ printf("Search Path:\n"); printSearchNode(result); } else printf("Search failed.\n"); //clean up deleteSearchNode(root, visited); assert(TOTAL_SEARCH_NODES==0); assert(TOTAL_HASH_NODES==0); deleteHashTable(visited); deleteBoard(goal); return 0; }
void resizeHashTable(int N) { //! reconstruct the hash table by (usually) doubling its size //! only call this when the current fill factor of your hash table > MAX_FILL_FACTOR //! careful, when resizing, the 'size' variable should be changed as well such that the 'hashFunction's distribution will work //! be double careful! all the elements which are already in the hash table have to be RE-hashed! (explanation @ lab) char ** newHash; int newSize = size * 2, i; nrOfResizes+=1; newHash = (char**) malloc (newSize * sizeof(char*)); for(i=0; i<newSize; i++) newHash[i] = NULL; // redistribute the elements of the old hash into the new hash for(i=0; i<size; i++) { if(hashTable[i] != NULL) collisions[i] += insertElement(hashTable[i], newSize, newHash); } //delete the old hash deleteHashTable(hashTable, size); //continue adding new elements into the new hash hashTable = newHash; size = newSize; }
void ws_status_timer(Timer tm, Name status) { UINT id; if ( (id = getIdTimer(tm)) ) { KillTimer(NULL, id); deleteHashTable(TimerTable, toInt(id)); setIdTimer(tm, 0); } if ( status != NAME_idle ) { long msec = (long) (valReal(tm->interval) * 1000.0); if ( (id = SetTimer(NULL, 0, (UINT)msec, (TIMERPROC) timer_proc)) ) { if ( !TimerTable ) { TimerTable = globalObject(CtoName("active_timers"), ClassHashTable, EAV); assign(TimerTable, refer, NAME_none); } appendHashTable(TimerTable, toInt(id), tm); setIdTimer(tm, id); DEBUG(NAME_timer, Cprintf("Created timer of %d milliseconds (id = %d)\n", msec, id)); } else Cprintf("Failed SetTimer()\n"); } }
static status unlinkElevation(Elevation e) { if ( notNil(e->name) ) deleteHashTable(ElevationTable, e->name); succeed; }
static status deleteChainTable(ChainTable ct, Any name, Any value) { Chain ch; if ( isDefault(value) ) return deleteHashTable((HashTable)ct, name); if ( (ch = getMemberHashTable((HashTable) ct, name)) ) { TRY(deleteChain(ch, value)); if ( emptyChain(ch) ) deleteHashTable((HashTable) ct, name); succeed; } fail; }
void deleteAssoc(Any obj) { if ( isObject(obj) && onFlag(obj, F_ASSOC) ) { PceITFSymbol symbol = getMemberHashTable(ObjectToITFTable, obj); if ( symbol ) { symbol->object = NULL; deleteHashTable(ObjectToITFTable, obj); clearFlag(obj, F_ASSOC); } } }
static void do_timer_proc(Timer tm, UINT id) { if ( tm->status != NAME_repeat ) { KillTimer(NULL, id); deleteHashTable(TimerTable, toInt(id)); assign(tm, status, NAME_idle); } executeTimer(tm); RedrawDisplayManager(TheDisplayManager()); }
static status unlinkSyntaxTable(SyntaxTable t) { if ( t->table ) { unalloc(FLAGS_SIZE(t), t->table); t->table = NULL; } if ( t->context ) { unalloc(CONTEXT_SIZE(t), t->context); t->context = NULL; } if ( notNil(t->name) ) deleteHashTable(SyntaxTables, t->name); succeed; }
/* Copy the data stored in a Cache struct into a continuously allocated memory block in *p. * All sub structure status are either uninitialized or compressed, which meaning that they are not allocated separately and therefore should not be deallocated. * Only coreRuleSet and coreFuncDescIndex are copied. * Starting from *p+size backwards, a list of pointers to pointers in the copied data structures are stored. * There pointers are used to quickly access all pointers in the stored data structures so that they can be offset when they are copied to a new memory address. * This function returns NULL if it runs out of memory allocated between in *p and *p+size. * The rule engine status is also set to uninitialized. */ Cache *copyCache( unsigned char **p, size_t size, Cache *ptr ) { /* size should be large enough and divisible by ALIGNMENT */ if (size < DEFAULT_BLOCK_SIZE || 0 != size % REGION_ALIGNMENT) { return NULL; } unsigned char *buf = *p; unsigned char *pointers0 = buf + size; /* shared objects */ unsigned char **pointers = &pointers0; int generatePtrDesc = 1; allocateInBuffer( Cache, ecopy, ptr ); MK_POINTER( &( ecopy->address ) ); MK_POINTER( &( ecopy->pointers ) ); // objectMap will use a hash table size that is twice the number of objects being held (to favor speed). // Example: The shared memory region has a size of SHMMAX (see shared_memory.hpp). SHMMAX == 30000000. // The upper bound of the passed-in size is the shared memory region size. // With an average compiled object size of 75 bytes (taken over sample of 9000 lines of rule code), SHMMAX / 75 = 400000 objects. // The maximum size of the hash table should be twice the objects that can fit in shared memory (400000 * 2 = 800000). // The ratio of the shared memory region size to the maximum hash table size is 30000000 / 800000 = 37.5 // Since the calculations are based on an average size, the ratio is rounded to 40 to avoid imbuing too much significance. // The size of the hash table for a cache of the passed-in size, then, should be the size of the cache divided by the ratio. // hashtable size upper limit == cache size upper limit / 40 == 30000000 / 40 < 800000 const int SHMEM_TO_MAX_HASHTABLE_SIZE_RATIO{40}; Hashtable *objectMap = newHashTable(size / SHMEM_TO_MAX_HASHTABLE_SIZE_RATIO); MK_PTR( RuleSet, coreRuleSet ); ecopy->coreRuleSetStatus = COMPRESSED; ecopy->appRuleSet = NULL; ecopy->appRuleSetStatus = UNINITIALIZED; ecopy->extRuleSet = NULL; ecopy->extRuleSetStatus = UNINITIALIZED; MK_PTR_TAPP( Env, coreFuncDescIndex, PARAM( Node ) ); ecopy->coreFuncDescIndexStatus = COMPRESSED; /* The coreFuncDescIndex is stored in a continuously allocated memory block in *buf */ ecopy->appFuncDescIndex = NULL; ecopy->appFuncDescIndexStatus = UNINITIALIZED; ecopy->extFuncDescIndex = NULL; ecopy->extFuncDescIndexStatus = UNINITIALIZED; ecopy->dataSize = ( *p - buf ); ecopy->address = buf; ecopy->pointers = pointers0; ecopy->cacheSize = size; ecopy->cacheStatus = INITIALIZED; ecopy->appRegion = NULL; ecopy->appRegionStatus = UNINITIALIZED; ecopy->coreRegion = NULL; ecopy->coreRegionStatus = UNINITIALIZED; ecopy->extRegion = NULL; ecopy->extRegionStatus = UNINITIALIZED; ecopy->sysRegion = NULL; ecopy->sysRegionStatus = UNINITIALIZED; ecopy->sysFuncDescIndex = NULL; ecopy->sysFuncDescIndexStatus = UNINITIALIZED; ecopy->ruleEngineStatus = UNINITIALIZED; MK_VAR_ARRAY_IN_STRUCT( char, ruleBase ); deleteHashTable( objectMap, nop ); return ecopy; }
// Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch int main () { //Create the hash table we are going to use HashTable h = newHashTable(); //Open up a dictionary of words to use from the start FILE * input = fopen("dictionary.txt", "r"); if (input == NULL) return EXIT_FAILURE; //Malloc some space for the strings we are reading in from the dictionary char ** temp = malloc(sizeof(char*) * MAX_DICT_SIZE); int k = 0; for (k = 0; k < MAX_DICT_SIZE; k++) { temp[k] = malloc(sizeof(char) * MAX_STRING_LENGTH); } //Read in everything from the dictionary int i = 1; int j = 0; temp[j][0] = fgetc(input); while (temp[j][i-1] != EOF) { temp[j][i] = fgetc(input); if (temp[j][i] == '\n') { temp[j][i] = '\0'; if (hashTableContains(temp[j], h)) { printf("\nSeen %s\n", temp[j]); } else { printf("\nNot seen %s\n", temp[j]); printf("Adding: %s\n", temp[j]); put(temp[j], h); } assert(hashTableContains(temp[j], h)); i = 0; j++; temp[j][0] = fgetc(input); } i++; } //close the dictionary fclose(input); /* TODO: read in some strings from the user using scanf until they enter an empty string or until the dictionary is full */ //j is each string //i is each character in a string while (fgets(temp[j],MAX_STRING_LENGTH,stdin) != NULL && j < MAX_DICT_SIZE) { //temp[j][i] = *s; if (temp[j][i] == '\n') { temp[j][i] = '\0'; if (hashTableContains(temp[j], h)) { printf("\nSeen %s\n", temp[j]); } else { printf("\nNot seen %s\n", temp[j]); printf("Adding: %s\n", temp[j]); put(temp[j], h); } assert(hashTableContains(temp[j], h)); i = 0; j++; //temp[j][0] = *s; //temp[j][0] = fgets(temp[j][i],MAX_STRING_LENGTH,stdin); } i++; } /* tell them if we have ever seen them before add them to the hash table */ //free all the strings we have malloc'ed for (k=0; k < MAX_DICT_SIZE; k++) { free(temp[k]); } free(temp); //delete the hash table we used h = deleteHashTable(h); //exit return EXIT_SUCCESS; }
int processXMsg( int streamId, char *readmsg, RuleEngineEventParam *param, Node *node, Env *env, ruleExecInfo_t *rei ) { char myhdr[HEADER_TYPE_LEN]; char mymsg[MAX_NAME_LEN]; char *outStr = NULL; int i, n; int iLevel, wCnt; int ruleInx = 0; Region *r; Res *res; rError_t errmsg; errmsg.len = 0; errmsg.errMsg = NULL; r = make_region( 0, NULL ); ParserContext *context = newParserContext( &errmsg, r ); Pointer *e = newPointer2( readmsg ); int rulegen = 1; int found; int grdf[2]; int cmd = 0; int smallW; snprintf( myhdr, HEADER_TYPE_LEN - 1, "idbug:%s", param->actionName ); memset( mymsg, 0, sizeof( mymsg ) ); PARSER_BEGIN( DbgCmd ) TRY( DbgCmd ) TTEXT2( "n", "next" ); cmd = REDEBUG_STEP_OVER; OR( DbgCmd ) TTEXT2( "s", "step" ); cmd = REDEBUG_NEXT; OR( DbgCmd ) TTEXT2( "f", "finish" ); cmd = REDEBUG_STEP_OUT; OR( DbgCmd ) TTEXT2( "b", "break" ); TRY( Param ) TTYPE( TK_TEXT ); int breakPointsInx2; for ( breakPointsInx2 = 0; breakPointsInx2 < 100; breakPointsInx2++ ) { if ( breakPoints[breakPointsInx2].actionName == NULL ) { break; } } if ( breakPointsInx2 == 100 ) { _writeXMsg( streamId, myhdr, "Maximum breakpoint count reached. Breakpoint not set.\n" ); cmd = REDEBUG_WAIT; } else { breakPoints[breakPointsInx2].actionName = strdup( token->text ); char * base_ptr = NULL; TRY( loc ) TTYPE( TK_TEXT ); base_ptr = ( char * ) malloc( sizeof( token->text ) + 2 ); base_ptr[0] = 'f'; strcpy( base_ptr + 1, token->text ); TTEXT( ":" ); TTYPE( TK_INT ); breakPoints[breakPointsInx2].base = strdup( base_ptr ); breakPoints[breakPointsInx2].line = atoi( token->text ); rodsLong_t range[2]; char rulesFileName[MAX_NAME_LEN]; getRuleBasePath( base_ptr, rulesFileName ); FILE *file; /* char errbuf[ERR_MSG_LEN]; */ file = fopen( rulesFileName, "r" ); if ( file == NULL ) { free( context ); deletePointer( e ); free( base_ptr ); return RULES_FILE_READ_ERROR; } Pointer *p = newPointer( file, base_ptr ); if ( getLineRange( p, breakPoints[breakPointsInx2].line, range ) == 0 ) { breakPoints[breakPointsInx2].start = range[0]; breakPoints[breakPointsInx2].finish = range[1]; } else { breakPoints[breakPointsInx2].actionName = NULL; } deletePointer( p ); OR( loc ) TTYPE( TK_INT ); if ( node != NULL ) { breakPoints[breakPointsInx2].base = strdup( node->base ); breakPoints[breakPointsInx2].line = atoi( token->text ); rodsLong_t range[2]; Pointer *p = newPointer2( breakPoints[breakPointsInx2].base ); if ( getLineRange( p, breakPoints[breakPointsInx2].line, range ) == 0 ) { breakPoints[breakPointsInx2].start = range[0]; breakPoints[breakPointsInx2].finish = range[1]; } else { breakPoints[breakPointsInx2].actionName = NULL; } deletePointer( p ); } else { breakPoints[breakPointsInx2].actionName = NULL; } OR( loc ) /* breakPoints[breakPointsInx].base = NULL; */ END_TRY( loc ) free( base_ptr ); if ( breakPoints[breakPointsInx2].actionName != NULL ) snprintf( mymsg, MAX_NAME_LEN, "Breakpoint %i set at %s\n", breakPointsInx2, breakPoints[breakPointsInx2].actionName ); else { snprintf( mymsg, MAX_NAME_LEN, "Cannot set breakpoint, source not available\n" ); } _writeXMsg( streamId, myhdr, mymsg ); if ( breakPointsInx <= breakPointsInx2 ) { breakPointsInx = breakPointsInx2 + 1; } cmd = REDEBUG_WAIT; } OR( Param ) NEXT_TOKEN_BASIC; _writeXMsg( streamId, myhdr, "Unknown parameter type.\n" ); cmd = REDEBUG_WAIT; OR( Param ) _writeXMsg( streamId, myhdr, "Debugger command \'break\' requires at least one argument.\n" ); cmd = REDEBUG_WAIT; END_TRY( Param ) OR( DbgCmd ) TRY( Where ) TTEXT2( "w", "where" ); smallW = 1; OR( Where ) TTEXT2( "W", "Where" ); smallW = 0; END_TRY( Where ) wCnt = 20; OPTIONAL_BEGIN( Param ) TTYPE( TK_INT ); wCnt = atoi( token->text ); OPTIONAL_END( Param ) iLevel = 0; i = reDebugStackCurrPtr - 1; while ( i >= 0 && wCnt > 0 ) { if ( !smallW || ( reDebugPCType( ( RuleEngineEvent ) reDebugStackCurr[i].label ) & 1 ) != 0 ) { snprintf( myhdr, HEADER_TYPE_LEN - 1, "idbug: Level %3i", iLevel ); char msg[HEADER_TYPE_LEN - 1]; RuleEngineEventParam param; param.ruleIndex = 0; param.actionName = reDebugStackCurr[i].step; printRuleEngineEventLabel( msg, HEADER_TYPE_LEN - 1, ( RuleEngineEvent ) reDebugStackCurr[i].label, ¶m ); _writeXMsg( streamId, myhdr, msg ); if ( reDebugStackCurr[i].label != EXEC_ACTION_BEGIN ) { iLevel++; } wCnt--; } i--; } OR( DbgCmd ) TTEXT2( "l", "list" ); TRY( Param ) TTEXT2( "r", "rule" ); TRY( ParamParam ) TTYPE( TK_TEXT ); mymsg[0] = '\n'; mymsg[1] = '\0'; snprintf( myhdr, HEADER_TYPE_LEN - 1, "idbug: Listing %s", token->text ); RuleIndexListNode *node; found = 0; while ( findNextRule2( token->text, ruleInx, &node ) != NO_MORE_RULES_ERR ) { found = 1; if ( node->secondaryIndex ) { n = node->condIndex->valIndex->len; int i; for ( i = 0; i < n; i++ ) { Bucket *b = node->condIndex->valIndex->buckets[i]; while ( b != NULL ) { RuleDesc *rd = getRuleDesc( *( int * )b->value ); char buf[MAX_RULE_LEN]; ruleToString( buf, MAX_RULE_LEN, rd ); snprintf( mymsg + strlen( mymsg ), MAX_NAME_LEN - strlen( mymsg ), "%i: %s\n%s\n", node->ruleIndex, rd->node->base[0] == 's' ? "<source>" : rd->node->base + 1, buf ); b = b->next; } } } else { RuleDesc *rd = getRuleDesc( node->ruleIndex ); char buf[MAX_RULE_LEN]; ruleToString( buf, MAX_RULE_LEN, rd ); snprintf( mymsg + strlen( mymsg ), MAX_NAME_LEN - strlen( mymsg ), "\n %i: %s\n%s\n", node->ruleIndex, rd->node->base[0] == 's' ? "<source>" : rd->node->base + 1, buf ); } ruleInx ++; } if ( !found ) { snprintf( mymsg, MAX_NAME_LEN, "Rule %s not found\n", token->text ); } _writeXMsg( streamId, myhdr, mymsg ); cmd = REDEBUG_WAIT; OR( ParamParam ) _writeXMsg( streamId, myhdr, "Debugger command \'list rule\' requires one argument.\n" ); cmd = REDEBUG_WAIT; END_TRY( ParamParam ) OR( Param ) TTEXT2( "b", "breakpoints" ); snprintf( myhdr, HEADER_TYPE_LEN - 1, "idbug: Listing %s", token->text ); mymsg[0] = '\n'; mymsg[1] = '\0'; for ( i = 0; i < breakPointsInx; i++ ) { if ( breakPoints[i].actionName != NULL ) { if ( breakPoints[i].base != NULL ) { snprintf( mymsg + strlen( mymsg ), MAX_NAME_LEN - strlen( mymsg ), "Breaking at BreakPoint %i:%s %s:%d\n", i , breakPoints[i].actionName, breakPoints[i].base[0] == 's' ? "<source>" : breakPoints[i].base + 1, breakPoints[i].line ); } else { snprintf( mymsg + strlen( mymsg ), MAX_NAME_LEN - strlen( mymsg ), "Breaking at BreakPoint %i:%s\n", i , breakPoints[i].actionName ); } } } _writeXMsg( streamId, myhdr, mymsg ); cmd = REDEBUG_WAIT; OR( Param ) TTEXT( "*" ); snprintf( myhdr, HEADER_TYPE_LEN - 1, "idbug: Listing %s", token->text ); Env *cenv = env; mymsg[0] = '\n'; mymsg[1] = '\0'; found = 0; while ( cenv != NULL ) { n = cenv->current->size; for ( i = 0; i < n; i++ ) { Bucket *b = cenv->current->buckets[i]; while ( b != NULL ) { if ( b->key[0] == '*' ) { /* skip none * variables */ found = 1; char typeString[128]; typeToString( ( ( Res * )b->value )->exprType, NULL, typeString, 128 ); snprintf( mymsg + strlen( mymsg ), MAX_NAME_LEN - strlen( mymsg ), "%s of type %s\n", b->key, typeString ); } b = b->next; } } cenv = cenv->previous; } if ( !found ) { snprintf( mymsg + strlen( mymsg ), MAX_NAME_LEN - strlen( mymsg ), "<empty>\n" ); } _writeXMsg( streamId, myhdr, mymsg ); cmd = REDEBUG_WAIT; OR( Param ) syncTokenQueue( e, context ); skipWhitespace( e ); ABORT( lookAhead( e, 0 ) != '$' ); snprintf( myhdr, HEADER_TYPE_LEN - 1, "idbug: Listing %s", token->text ); mymsg[0] = '\n'; mymsg[1] = '\0'; Hashtable *vars = newHashTable( 100 ); for ( i = 0; i < coreRuleVarDef .MaxNumOfDVars; i++ ) { if ( lookupFromHashTable( vars, coreRuleVarDef.varName[i] ) == NULL ) { snprintf( &mymsg[strlen( mymsg )], MAX_NAME_LEN - strlen( mymsg ), "$%s\n", coreRuleVarDef.varName[i] ); insertIntoHashTable( vars, coreRuleVarDef.varName[i], coreRuleVarDef.varName[i] ); } } deleteHashTable( vars, NULL ); _writeXMsg( streamId, myhdr, mymsg ); cmd = REDEBUG_WAIT; OR( Param ) NEXT_TOKEN_BASIC; _writeXMsg( streamId, myhdr, "Unknown parameter type.\n" ); cmd = REDEBUG_WAIT; OR( Param ) _writeXMsg( streamId, myhdr, "Debugger command \'list\' requires at least one argument.\n" ); cmd = REDEBUG_WAIT; END_TRY( Param ) OR( DbgCmd ) TTEXT2( "c", "continue" ); cmd = REDEBUG_STEP_CONTINUE; OR( DbgCmd ) TTEXT2( "C", "Continue" ); cmd = REDEBUG_CONTINUE_VERBOSE; OR( DbgCmd ) TTEXT2( "del", "delete" ); TRY( Param ) TTYPE( TK_INT ); n = atoi( token->text ); if ( breakPoints[n].actionName != NULL ) { free( breakPoints[n].actionName ); if ( breakPoints[n].base != NULL ) { free( breakPoints[n].base ); } breakPoints[n].actionName = NULL; breakPoints[n].base = NULL; snprintf( mymsg, MAX_NAME_LEN, "Breakpoint %i deleted\n", n ); } else { snprintf( mymsg, MAX_NAME_LEN, "Breakpoint %i has not been defined\n", n ); } _writeXMsg( streamId, myhdr, mymsg ); cmd = REDEBUG_WAIT; OR( Param ) _writeXMsg( streamId, myhdr, "Debugger command \'delete\' requires one argument.\n" ); cmd = REDEBUG_WAIT; END_TRY( Param ) OR( DbgCmd ) TTEXT2( "p", "print" ); Node *n = parseTermRuleGen( e, 1, context ); if ( getNodeType( n ) == N_ERROR ) { errMsgToString( context->errmsg, mymsg + strlen( mymsg ), MAX_NAME_LEN - strlen( mymsg ) ); } else { snprintf( myhdr, HEADER_TYPE_LEN - 1, "idbug: Printing " ); char * ptr = myhdr + strlen( myhdr ); i = HEADER_TYPE_LEN - 1 - strlen( myhdr ); termToString( &ptr, &i, 0, MIN_PREC, n, 0 ); snprintf( ptr, i, "\n" ); if ( env != NULL ) { disableReDebugger( grdf ); res = computeNode( n, NULL, regionRegionCpEnv( env, r, ( RegionRegionCopyFuncType * ) regionRegionCpNode ), rei, 0, &errmsg, r ); enableReDebugger( grdf ); outStr = convertResToString( res ); snprintf( mymsg, MAX_NAME_LEN, "%s\n", outStr ); free( outStr ); if ( getNodeType( res ) == N_ERROR ) { errMsgToString( &errmsg, mymsg + strlen( mymsg ), MAX_NAME_LEN - strlen( mymsg ) ); } } else { snprintf( mymsg, MAX_NAME_LEN, "Runtime environment: <empty>\n" ); } } _writeXMsg( streamId, myhdr, mymsg ); cmd = REDEBUG_WAIT; OR( DbgCmd ) TTEXT2( "d", "discontinue" ); cmd = REDEBUG_WAIT; OR( DbgCmd ) snprintf( mymsg, MAX_NAME_LEN, "Unknown Action: %s", readmsg ); _writeXMsg( streamId, myhdr, mymsg ); cmd = REDEBUG_WAIT; END_TRY( DbgCmd ) PARSER_END( DbgCmd ) freeRErrorContent( &errmsg ); region_free( r ); deletePointer( e ); free( context ); return cmd; }