/* build arguments' internal interrelations */ void build_args_map(EtalisExecNode* Node,term_t lhs,term_t rhs) { /* assuming that all arguments are int. Further Datatypes will be supported in the future. */ /* Arity of all the involved events */ /* Note : need to test if this is more efficient than directly calling the struct's members*/ int arg_count = Node->leftChild->event.arity+Node->rightChild->event.arity+Node->parentEvent->event.arity; int arg_iterator=0; char* arguments=calloc(arg_count*256,sizeof(char)); char Goal[256]; char Goal2[256]; char WhereGoal[256]; termToString(rhs,Goal2,arguments); termToString(lhs,Goal,arguments); char* arguments_cond=calloc(arg_count*256,sizeof(char)); termToStringVerbatim(rhs,WhereGoal,arguments_cond); int extra_args=0; /* used if a where clause is available */ char* orig_args=arguments; if(Node->has_condition == ETALIS_TRUE) { while(*arguments) { if(*arguments == '_') extra_args++; arguments++; } extra_args = extra_args - arg_count; arguments=orig_args; char * whereRightBound; char * whereLeftBound; whereRightBound = WhereGoal + strlen(WhereGoal); while(*whereRightBound != ',') whereRightBound--; whereRightBound--; whereLeftBound = strstr(WhereGoal,"wheref"); whereLeftBound = whereLeftBound+7; int leftParenth=0, rightParenth=0; while(*whereLeftBound != '\0') { if(*whereLeftBound == ')') rightParenth++; if(*whereLeftBound == '(') leftParenth++; if(leftParenth == rightParenth && leftParenth != 0) break; whereLeftBound++; } whereLeftBound=whereLeftBound+2; char* constraints_verbatim = malloc(256*sizeof(char)); strncpy(constraints_verbatim,whereLeftBound,strlen(whereLeftBound)-strlen(whereRightBound)); Node->whereNode->conditions=constraints_verbatim; printf("CONSTRAINTS: %s\n",constraints_verbatim); } #ifdef DEBUG printf("rule args : %s\n",arguments); #endif char** argument_array = malloc((arg_count+extra_args)*sizeof(char*)); char* pch; pch = strtok(arguments,"_"); while(pch != NULL) { argument_array[arg_iterator] = malloc(sizeof(char)*strlen(pch)); strcpy(argument_array[arg_iterator],pch); arg_iterator++; pch = strtok(NULL,"_"); } #ifdef DEBUG for(arg_iterator=0;arg_iterator<(arg_count+extra_args);arg_iterator++) printf("arg[%d] : %s\n",arg_iterator,argument_array[arg_iterator]); #endif argument_link* temp_arg =NULL; size_t left_s = Node->leftChild->event.arity; size_t right_s = Node->rightChild->event.arity; size_t cplx_s = Node->parentEvent->event.arity; /* handling of left event args : Usually these are unbound */ Node->leftChild->arg_links = calloc(Node->leftChild->event.arity,sizeof(argument_link)); temp_arg = Node->leftChild->arg_links; for(arg_iterator=0;arg_iterator<(Node->leftChild->event.arity);arg_iterator++) { (temp_arg+arg_iterator)->event_= UNBOUND_ARGUMENT; (temp_arg+arg_iterator)->argument_number = UNBOUND_ARGUMENT; } /* handling of right event args */ /* todo check for the unbound event case */ Node->rightChild->arg_links = calloc(Node->rightChild->event.arity,sizeof(argument_link)); temp_arg = Node->rightChild->arg_links; for(arg_iterator=0;arg_iterator<(Node->rightChild->event.arity);arg_iterator++) { int pos=-1; pos = findInStringArray(0,left_s,argument_array,argument_array[left_s+arg_iterator]); (temp_arg+arg_iterator)->event_= (pos == -1 ? UNBOUND_ARGUMENT : 1 ); (temp_arg+arg_iterator)->argument_number = (pos == -1 ? UNBOUND_ARGUMENT : pos ); } #ifdef DEBUG for(arg_iterator=0;arg_iterator<right_s;arg_iterator++) printf("ARG[%d] of right event is bound to Event %d : arg [%d]\n",arg_iterator,Node->rightChild->arg_links[arg_iterator].event_,Node->rightChild->arg_links[arg_iterator].argument_number); #endif /* handling of additional clauses : where, etc ..*/ if(Node->has_condition == ETALIS_TRUE) { Node->whereNode->arg_links=(argument_link*)malloc(sizeof(argument_link)*extra_args); /* search for the conditions in the events */ temp_arg = Node->whereNode->arg_links; for(arg_iterator=0;arg_iterator<extra_args;arg_iterator++) { int pos=-1; pos= findInStringArray(0,left_s,argument_array,argument_array[left_s+right_s+arg_iterator]); if (pos == -1) /* Unbound event */ { (temp_arg+arg_iterator)->event_= UNBOUND_ARGUMENT; (temp_arg+arg_iterator)->argument_number = UNBOUND_ARGUMENT; continue; } else { (temp_arg+arg_iterator)->event_= 1; (temp_arg+arg_iterator)->argument_number = pos; continue; } /* this should be fixed */ pos= findInStringArray(left_s,right_s+left_s,argument_array,argument_array[left_s+right_s+arg_iterator]); } } /* handling of complex event args */ Node->parentEvent->arg_links = (argument_link*)malloc(Node->parentEvent->event.arity*sizeof(argument_link)); temp_arg = Node->parentEvent->arg_links; for(arg_iterator=0;arg_iterator<(Node->parentEvent->event.arity);arg_iterator++) { int pos=-1; pos = findInStringArray(0,left_s+right_s,argument_array,argument_array[extra_args+left_s+right_s+arg_iterator]); if (pos == -1) /* Unbound event */ { (temp_arg+arg_iterator)->event_= UNBOUND_ARGUMENT; (temp_arg+arg_iterator)->argument_number = UNBOUND_ARGUMENT; continue; } else if (pos <left_s) { (temp_arg+arg_iterator)->event_=1; (temp_arg+arg_iterator)->argument_number = pos; continue; } else if (pos-left_s < right_s) { (temp_arg+arg_iterator)->event_=2; (temp_arg+arg_iterator)->argument_number = pos-left_s; /* todo correct offset */ continue; } } #ifdef DEBUG for(arg_iterator=0;arg_iterator<cplx_s;arg_iterator++) printf("ARG[%d] of complex event is bound to Event %d : arg [%d]\n",arg_iterator,Node->parentEvent->arg_links[arg_iterator].event_,Node->parentEvent->arg_links[arg_iterator].argument_number); #endif /* free temporary data */ /* todo fixme win7 Heap FTH : look here : http://stackoverflow.com/questions/1621059/breakpoints-out-of-nowhere-when-debugging-with-gdb-inside-ntdll */ /* for(arg_iterator=0;arg_iterator<arg_count;arg_iterator++) free(argument_array[arg_iterator]); */ free(argument_array); free(arguments); return; }
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; }