Debugger - Stage 3 (artf511247)
[deliverable/titan.core.git] / core / Debugger.hh
index 370c0344919e7f6b2c1c3c01adf980463427fd35..de6eac1d09ae473af184f7f4682a0acfd8ecb19c 100644 (file)
 /** alias for record of charstring */
 typedef PreGenRecordOf::PREGEN__RECORD__OF__CHARSTRING charstring_list;
 
-// forward declarations
+// debugger forward declarations
 class TTCN3_Debug_Scope;
 class TTCN3_Debug_Function;
 
+// other forward declarations
+class Module_Param;
+
 
 //////////////////////////////////////////////////////
 ////////////////// TTCN3_Debugger ////////////////////
@@ -43,16 +46,29 @@ class TTCN3_Debug_Function;
 class TTCN3_Debugger {
 public:
   
+  struct variable_t;
+  
+  typedef CHARSTRING (*print_function_t)(const variable_t&);
+  typedef boolean (*set_function_t)(variable_t&, Module_Param&);
+  
   /** type for keeping track of a variable */
   struct variable_t {
     /** pointer to the variable object, not owned */
-    const void* value;
+    union {
+      /** container for non-constant variable objects */
+      void* value;
+      /** container for constant variable objects */
+      const void* cvalue;
+    };
     /** variable name (used for looking up variables), not owned */
     const char* name;
     /** name of the variable's type, not owned */
     const char* type_name;
     /** variable printing function (using the variable object's log() function) */
-    CHARSTRING (*print_function)(const variable_t&);
+    print_function_t print_function;
+    /** variable setting (overwriting) function (using the variable object's
+      * set_param() function) - set to NULL for constant variables */
+    set_function_t set_function;
   };
   
   /** this type pairs a debug scope with a name, used for storing global and
@@ -65,13 +81,22 @@ public:
     TTCN3_Debug_Scope* scope;
   };
   
+  /** type for storing a function call in the call stack */
+  struct function_call_t {
+    /** pointer to the debug function object */
+    TTCN3_Debug_Function* function;
+    /** TTCN-3 line number, where the function was called from */
+    int caller_line;
+  };
+  
   /** type for storing breakpoints */
   struct breakpoint_t {
     /** module name, owned */
     char* module;
     /** line number */
     int line;
-    // const char* batch_file;
+    /** batch file to be executed when the breakpoint is reached (optional) */
+    char* batch_file;
   };
   
   /** special breakpoint types, passed to breakpoint_entry() as the line parameter,
@@ -83,6 +108,22 @@ public:
     SBP_FAIL_VERDICT = -1
   };
   
+  /** type for storing the settings of automatic breakpoints */
+  struct automatic_breakpoint_behavior_t {
+    /** indicates whether the breakpoint should be triggered by the associated event */
+    bool trigger;
+    /** batch file to be executed if the breakpoint is triggered (optional) */
+    char* batch_file;
+  };
+  
+  /** stepping type */
+  enum stepping_t {
+    NOT_STEPPING,
+    STEP_OVER,
+    STEP_INTO,
+    STEP_OUT
+  };
+  
 private:
   
   /** indicates whether the debugger has been activated, meaning that the debugger's
@@ -116,9 +157,10 @@ private:
   /** list of component scopes */
   Vector<named_scope_t> component_scopes;
   
-  /** pointers to debug function objects (resembling a call stack), elements are not owned
-    * the current function is always the last element in the array (the top element in the stack) */
-  Vector<TTCN3_Debug_Function*> call_stack;
+  /** pointers to debug function objects and the lines they were called from
+    * (resembling a call stack), the current function is always the last element
+    * in the array (the top element in the stack) */
+  Vector<function_call_t> call_stack;
   
   /** list of breakpoints */
   Vector<breakpoint_t> breakpoints;
@@ -132,17 +174,44 @@ private:
   /** current stack level (reset when test execution is halted or resumed) */
   int stack_level;
   
-  /** behavior triggered by setting the local verdict to FAIL
-    * (a breakpoint is activated if set to true) */
-  bool fail_behavior;
+  /** automatic breakpoint triggered by setting the local verdict to FAIL */
+  automatic_breakpoint_behavior_t fail_behavior;
   
-  /** behavior triggered by setting the local verdict to ERROR
-    * (a breakpoint is activated if set to true) */
-  bool error_behavior;
+  /** automatic breakpoint triggered by setting the local verdict to ERROR */
+  automatic_breakpoint_behavior_t error_behavior;
   
-  /** result of the last executed or currently executing command */
+  /** batch file executed automatically when test execution is halted
+    * NULL if switched off
+    * is overridden by breakpoint-specific batch files */
+  char* global_batch_file;
+  
+  /** result of the currently executing command */
   char* command_result;
   
+  /** result of the last D_LIST_VARIABLES command */
+  char* last_variable_list;
+  
+  /** stores which stepping option was requested by the user (if any) */
+  stepping_t stepping_type;
+  
+  /** stores the size of the call stack when the last stepping operation was
+    * initiated */
+  size_t stepping_stack_size;
+  
+  /** temporary breakpoint set by the 'run to cursor' operation */
+  breakpoint_t temporary_breakpoint;
+  
+  /** true if an 'exit all' command was issued
+    * switched to false when test execution is restarted */
+  bool exiting;
+  
+  /** test execution is automatically halted at start if set to true */
+  bool halt_at_start;
+  
+  /** batch file executed automatically at the start of test execution
+    * if not set to NULL (not owned) */
+  const char* initial_batch_file;
+  
   //////////////////////////////////////////////////////
   ///////////////// internal functions /////////////////
   //////////////////////////////////////////////////////
@@ -151,19 +220,28 @@ private:
     * handles the D_SWITCH command */
   void switch_state(const char* p_state_str);
   
-  /** adds a new breakpoint at the specified module and line 
+  /** adds a new breakpoint at the specified module and line with the specified
+    * batch file (if not NULL), or changes the batch file of an existing
+    * breakpoint
     * handles the D_ADD_BREAKPOINT command */
-  void add_breakpoint(const char* p_module, int p_line /*const char* batch_file*/);
+  void set_breakpoint(const char* p_module, int p_line, const char* batch_file);
   
   /** removes the breakpoint from the specified module/line, if it exists
+    * can also be used to remove all breakpoints from the specified module or
+    * all breakpoints in all modules
     * handles the D_REMOVE_BREAKPOINT command  */
-  void remove_breakpoint(const char* p_module, int p_line);
-  
-  /** sets the behavior of a special breakpoint type 
-    * @param p_state_str "yes" turns the special breakpoint on (as if it was an
-    * actual breakpoint), "no" turns it off 
-    * handles the D_SET_ERROR_BEHAVIOR and D_SET_FAIL_BEHAVIOR commands */
-  void set_special_breakpoint(special_breakpoint_t p_type, const char* p_state_str);
+  void remove_breakpoint(const char* p_module, const char* p_line);
+  
+  /** switches an automatic breakpoint related to the specified event on or off
+    * and/or sets the batch file to run when the breakpoint is triggered
+    * @param p_event_str string representation of the event that triggers the
+    * breakpoint (either "error" or "fail")
+    * @param p_state_str "on" or "off", indicates the new state of the breakpoint
+    * @param p_batch_file name of the batch file to execute (NULL means don't
+    * execute anything)
+    * handles the D_SET_AUTOMATIC_BREAKPOINT command */
+  void set_automatic_breakpoint(const char* p_event_str, const char* p_state_str,
+    const char* p_batch_file);
   
   /** prints the current call stack
     * handles the D_PRINT_CALL_STACK command */
@@ -173,9 +251,13 @@ private:
     * handles the D_SET_STACK_LEVEL command */
   void set_stack_level(int new_level);
   
-  /** prints the specified variable
+  /** finds the variable with the specified name, and prints its value or an
+    * error message
     * handles (one parameter of) the D_PRINT_VARIABLE command */
-  void print_variable(const variable_t* p_var);
+  void print_variable(const char* p_var_name);
+  
+  void overwrite_variable(const char* p_var_name, int p_value_element_count,
+    char** p_value_elements);
   
   /** sets the debugger's output to the console and/or a text file
     * handles the D_SET_OUTPUT command
@@ -183,9 +265,27 @@ private:
     * @param p_file_name output file name or NULL */
   void set_output(const char* p_output_type, const char* p_file_name);
   
+  /** switches the global batch file on or off
+    * handles the D_SET_GLOBAL_BATCH_FILE command */
+  void set_global_batch_file(const char* p_state_str, const char* p_file_name);
+  
+  /** resumes execution until the next breakpoint entry (in the stack levels
+    * specified by the stepping type arguments) is reached (or until test execution
+    * is halted for any other reason)
+    * handles the D_STEP_OVER, D_STEP_INTO and D_STEP_OUT commands */
+  void step(stepping_t p_stepping_type);
+  
+  /** resumes execution until the specified location is reached 
+    * (or until test execution is halted for any other reason)
+    * handles the D_RUN_TO_CURSOR command */
+  void run_to_cursor(const char* p_module, int p_line);
+  
   /** halts test execution, processing only debug commands
+    * @param p_batch_file batch file executed after the halt (if not NULL)
+    * @param p_run_global_batch indicates whether the global batch file should
+    * be executed after the halt (only if p_batch_file is NULL)
     * handles the D_HALT command */
-  void halt();
+  void halt(const char* p_batch_file, bool p_run_global_batch);
   
   /** resumes the halted test execution
     * handles the D_CONTINUE command */
@@ -205,6 +305,14 @@ private:
   /** handles metacharacters in the specified file name skeleton
     * @return final file name (must be freed by caller) */
   static char* finalize_file_name(const char* p_file_name_skeleton);
+  
+  /** initialization function, called when the first function is added to the
+    * call stack */
+  void test_execution_started();
+  
+  /** clean up function, called when the last function is removed from the
+    * call stack */
+  void test_execution_finished();
 
 public:
   /** constructor - called once per process (at the beginning) */
@@ -237,37 +345,61 @@ public:
     * the special parameter values (SBP_ERROR_VERDICT and SBP_FAIL_VERDICT) only
     * trigger a breakpoint if their respective behaviors have been set to do so
     * (does nothing if the debugger is switched off) */
-  void breakpoint_entry(int p_line /*bool p_stepping_helper*/);
+  void breakpoint_entry(int p_line);
   
   /** variable printing function for base types */
   static CHARSTRING print_base_var(const variable_t& p_var);
   
+  /** variable setting function for base types */
+  static boolean set_base_var(variable_t& p_var, Module_Param& p_new_value);
+  
   /** variable printing function for value arrays */
   template <typename T_type, unsigned int array_size, int index_offset>
   static CHARSTRING print_value_array(const variable_t& p_var)
   {
+    const void* ptr = p_var.set_function != NULL ? p_var.value : p_var.cvalue;
     TTCN_Logger::begin_event_log2str();
-    ((VALUE_ARRAY<T_type, array_size, index_offset>*)p_var.value)->log();
+    ((VALUE_ARRAY<T_type, array_size, index_offset>*)ptr)->log();
     return TTCN_Logger::end_event_log2str();
   }
   
+  /** variable setting function for value arrays */
+  template <typename T_type, unsigned int array_size, int index_offset>
+  static boolean set_value_array(variable_t& p_var, Module_Param& p_new_value)
+  {
+    ((VALUE_ARRAY<T_type, array_size, index_offset>*)p_var.value)->set_param(p_new_value);
+    return TRUE;
+  }
+  
   /** variable printing function for template arrays */
   template <typename T_value_type, typename T_template_type,
     unsigned int array_size, int index_offset>
   static CHARSTRING print_template_array(const variable_t& p_var)
   {
+    const void* ptr = p_var.set_function != NULL ? p_var.value : p_var.cvalue;
     TTCN_Logger::begin_event_log2str();
     ((TEMPLATE_ARRAY<T_value_type, T_template_type, array_size,
-      index_offset>*)p_var.value)->log();
+      index_offset>*)ptr)->log();
     return TTCN_Logger::end_event_log2str();
   }
   
+  /** variable setting function for template arrays */
+  template <typename T_value_type, typename T_template_type,
+    unsigned int array_size, int index_offset>
+  static boolean set_template_array(variable_t& p_var, Module_Param& p_new_value)
+  {
+    ((TEMPLATE_ARRAY<T_value_type, T_template_type, array_size,
+      index_offset>*)p_var.value)->set_param(p_new_value);
+    return TRUE;
+  }
+  
   /** variable printing function for port arrays */
   template <typename T_type, unsigned int array_size, int index_offset>
   static CHARSTRING print_port_array(const variable_t& p_var)
   {
+    const void* ptr = p_var.set_function != NULL ? p_var.value : p_var.cvalue;
     TTCN_Logger::begin_event_log2str();
-    ((PORT_ARRAY<T_type, array_size, index_offset>*)p_var.value)->log();
+    ((PORT_ARRAY<T_type, array_size, index_offset>*)ptr)->log();
     return TTCN_Logger::end_event_log2str();
   }
   
@@ -275,8 +407,9 @@ public:
   template <typename T_type, unsigned int array_size, int index_offset>
   static CHARSTRING print_timer_array(const variable_t& p_var)
   {
+    const void* ptr = p_var.set_function != NULL ? p_var.value : p_var.cvalue;
     TTCN_Logger::begin_event_log2str();
-    ((TIMER_ARRAY<T_type, array_size, index_offset>*)p_var.value)->log();
+    ((TIMER_ARRAY<T_type, array_size, index_offset>*)ptr)->log();
     return TTCN_Logger::end_event_log2str();
   }
   
@@ -284,8 +417,9 @@ public:
   template <typename EXPR_TYPE>
   static CHARSTRING print_lazy_param(const variable_t& p_var)
   {
+    const void* ptr = p_var.set_function != NULL ? p_var.value : p_var.cvalue;
     TTCN_Logger::begin_event_log2str();
-    ((Lazy_Param<EXPR_TYPE>*)p_var.value)->log();
+    ((Lazy_Param<EXPR_TYPE>*)ptr)->log();
     return TTCN_Logger::end_event_log2str();
   }
   
@@ -325,14 +459,19 @@ public:
     * (only if the call stack is not empty) */
   void remove_scope(TTCN3_Debug_Scope* p_scope);
   
-  /** finds or creates, and returns the variable entry specified by the parameters
+  /** finds or creates, and returns the constant variable entry specified by
+    * the parameters
     *
     * if the call stack is empty, an entry for a global or component variable is
     * created and stored in the main debugger object (if it doesn't already exist);
     * if the call stack is not empty (and if the debugger is switched on), the 
     * variable entry for a local variable is created and stored by the current function */
-  const variable_t* add_variable(const void* p_value, const char* p_name, const char* p_type,
-    CHARSTRING (*p_print_function)(const variable_t&));
+  variable_t* add_variable(const void* p_value, const char* p_name, const char* p_type,
+    print_function_t p_print_function);
+  
+  /** same as before, but for non-constant variables */
+  variable_t* add_variable(void* p_value, const char* p_name, const char* p_type,
+    print_function_t p_print_function, set_function_t p_set_function);
   
   /** removes the variable entry for the specified local variable in the current
     * function (only if the call stack is not empty) */
@@ -353,6 +492,19 @@ public:
   /** opens the debugger's output file for writing (if one has been set, but not
     * opened, in the HC process) */
   void open_output_file();
+  
+  /** indicates whether an 'exit all' command has been issued 
+    * (this causes the execution of tests in the current queue to stop) */
+  bool is_exiting() const { return exiting; }
+  
+  /** sets the debugger to halt test execution at start (only in single mode) */
+  void set_halt_at_start() { halt_at_start = true; }
+  
+  /** sets the specified batch file to be executed at the start of test execution
+    * (only in single mode) */
+  void set_initial_batch_file(const char* p_batch_file) {
+    initial_batch_file = p_batch_file;
+  }
 };
 
 /** the main debugger object */
@@ -377,7 +529,7 @@ class TTCN3_Debug_Scope {
   /** list of pointers to local variable entries from the current function object or
     * global or component variable entries from the main debugger object
     * (the elements are not owned)*/
-  Vector<const TTCN3_Debugger::variable_t*> variables;
+  Vector<TTCN3_Debugger::variable_t*> variables;
   
 public:
   
@@ -393,11 +545,16 @@ public:
   //////////////////////////////////////////////////////
   
   /** passes the parameters to the main debugger or current function object to 
-    * create and store a variable entry from them, and tracks this new variable
-    * by storing a pointer to it
+    * create and store a (constant) variable entry from them, and tracks this new
+    * variable by storing a pointer to it
     * (local variables are only created and stored if the debugger is switched on) */
   void add_variable(const void* p_value, const char* p_name, const char* p_type,
-    CHARSTRING (*p_print_function)(const TTCN3_Debugger::variable_t&));
+    TTCN3_Debugger::print_function_t p_print_function);
+  
+  /** same as before, but for non-constant variables */
+  void add_variable(void* p_value, const char* p_name, const char* p_type,
+    TTCN3_Debugger::print_function_t p_print_function,
+    TTCN3_Debugger::set_function_t p_set_function);
   
   //////////////////////////////////////////////////////
   ////// methods called by other debugger classes //////
@@ -407,7 +564,7 @@ public:
   bool has_variables() const { return !variables.empty(); }
   
   /** returns the specified variable, if found, otherwise returns NULL */
-  const TTCN3_Debugger::variable_t* find_variable(const char* p_name) const;
+  TTCN3_Debugger::variable_t* find_variable(const char* p_name) const;
   
   /** prints the names of variables in this scope that match the specified
     * @param p_posix_regexp the pattern converted into a POSIX regex structure
@@ -483,10 +640,15 @@ public:
   ////// methods called from TITAN generated code //////
   //////////////////////////////////////////////////////
   
-  /** creates, stores and returns the variable entry of the local variable
+  /** creates, stores and returns the variable entry of the local (constant) variable
     * specified by the parameters (only if the debugger is switched on) */
-  const TTCN3_Debugger::variable_t* add_variable(const void* p_value, const char* p_name,
-    const char* p_type, CHARSTRING (*p_print_function)(const TTCN3_Debugger::variable_t&));
+  TTCN3_Debugger::variable_t* add_variable(const void* p_value, const char* p_name,
+    const char* p_type, TTCN3_Debugger::print_function_t p_print_function);
+  
+  /** same as before, but for non-constant variables */
+  TTCN3_Debugger::variable_t* add_variable(void* p_value, const char* p_name,
+    const char* p_type, TTCN3_Debugger::print_function_t p_print_function,
+    TTCN3_Debugger::set_function_t p_set_function);
   
   /** stores the string representation of the value returned by the function */
   void set_return_value(const CHARSTRING& p_value);
@@ -513,7 +675,7 @@ public:
   /** searches for the variable entry with the specified name in the function's
     * local variable list, the global scope (if any) and the component scope (if any),
     * returns NULL, if the variable was not found */
-  const TTCN3_Debugger::variable_t* find_variable(const char* p_name) const;
+  TTCN3_Debugger::variable_t* find_variable(const char* p_name) const;
   
   /** prints the function's type, name and current values of parameters */
   void print_function() const;
@@ -530,6 +692,12 @@ public:
     * - "all" - all variables visible in the function (i.e. all of the above)
     * @param p_filter a pattern to filter variable names further */
   void list_variables(const char* p_scope, const char* p_filter) const;
+  
+  /** returns true if this instance belongs to a control part */
+  bool is_control_part() const;
+  
+  /** returns true if this instance belongs to a test case */
+  bool is_test_case() const;
 };
 
 /** This macro stores a function's return value in the current function.
This page took 0.027774 seconds and 5 git commands to generate.