This is the mail archive of the gdb-prs@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

pending/1382: [RFA] error-catching mechanism for scripts (fwd)


>Number:         1382
>Category:       pending
>Synopsis:       [RFA] error-catching mechanism for scripts (fwd)
>Confidential:   yes
>Severity:       serious
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          change-request
>Submitter-Id:   unknown
>Arrival-Date:   Thu Sep 18 21:28:00 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator:     
>Release:        
>Organization:
>Environment:
>Description:
 I don't know if this will apply against current gdb, but here's the state
 of things from when I last looked at this.
 
 
 -- 
 dhoward@redhat.com
 sustaining engineering
 
 
 ---------- Forwarded message ----------
 Date: Tue, 18 Dec 2001 15:48:18 -0800 (PST)
 From: Don Howard <dhoward@redhat.com>
 To: gdb-patches@sources.redhat.com
 Subject: [RFA] error-catching mechanism for scripts
 
 
 
 Here is an implementation of the error-catcher that I mentioned a few
 weeks ago.  I chose "try" and "except" as the keywords:
 
 
 	try
 	   some commands that might error
 	end
 
 		-- or --
 
 	try
 	  some commands that might error
 	except
 	  some commands to recover from error
 	  (errors in this block will not be caught)
 	end
 
 
 
 I've included a quick write-up for the gdb manual.  I'll submit new tests
 for the testsuite shortly.
 
 
 
 2001-12-18  Don Howard  <dhoward@redhat.com>
 
 	* cli/cli-script.h: New function.
 	* cli/cli-script.c (build_command_line): Add support for try
 	command.
 	(print_command_lines): Ditto.
 	(print_command_line): Ditto.
 	(execute_control_command): Ditto.
 	(read_next_line): Ditto.
 	(recurse_read_control_structure): Ditto.
 	(captured_execute_control_command): New function.
 	(try_command): Ditto.
 	* cli/cli-cmds.c (init_cli_cmds): Add try command.
 	* defs.h (enum misc_command_type): Added enum except_command.
 	 (enum command_control_type): Exclude zero from the range of
 	 command_control_type. Added enum try_control.
 
 
 2001-12-18  Don Howard  <dhoward@redhat.com>
 
 	* gdb.texinfo (User-defined commands): New section, documenting
 	try/except feature.
 
 
 
 Index: defs.h
 ===================================================================
 RCS file: /cvs/src/src/gdb/defs.h,v
 retrieving revision 1.68
 diff -p -u -w -r1.68 defs.h
 --- defs.h	2001/12/15 16:53:22	1.68
 +++ defs.h	2001/12/18 23:45:33
 @@ -811,16 +811,18 @@ enum misc_command_type
      ok_command,
      end_command,
      else_command,
 +    except_command,
      nop_command
    };
 
  enum command_control_type
    {
 -    simple_control,
 +    simple_control = 1,
      break_control,
      continue_control,
      while_control,
      if_control,
 +    try_control,
      invalid_control
    };
 
 Index: cli/cli-cmds.c
 ===================================================================
 RCS file: /cvs/src/src/gdb/cli/cli-cmds.c,v
 retrieving revision 1.10
 diff -p -u -w -r1.10 cli-cmds.c
 --- cli-cmds.c	2001/09/01 21:38:05	1.10
 +++ cli-cmds.c	2001/12/18 23:45:34
 @@ -721,6 +721,12 @@ The conditional expression must follow t
  followed by a new line.  The nested commands must be entered one per line,\n\
  and should be terminated by the word `end'.");
 
 +  add_com ("try", class_support, try_command,
 +"Execute nested commands. On error, terminate execution of the 'try' block\n\
 +and execute the optional 'except' block. Commands must be entered one per line,\n\
 +terminating with the word 'end'.");
 +
 +
    add_com ("if", class_support, if_command,
  	   "Execute nested commands once IF the conditional expression is non zero.\n\
  The conditional expression must follow the word `if' and must in turn be\n\
 Index: cli/cli-script.c
 ===================================================================
 RCS file: /cvs/src/src/gdb/cli/cli-script.c,v
 retrieving revision 1.8
 diff -p -u -w -r1.8 cli-script.c
 --- cli-script.c	2001/12/13 22:42:23	1.8
 +++ cli-script.c	2001/12/18 23:45:34
 @@ -83,7 +83,7 @@ build_command_line (enum command_control
  {
    struct command_line *cmd;
 
 -  if (args == NULL)
 +  if (args == NULL && type != try_control)
      error ("if/while commands require arguments.\n");
 
    cmd = (struct command_line *) xmalloc (sizeof (struct command_line));
 @@ -95,7 +95,12 @@ build_command_line (enum command_control
      = (struct command_line **) xmalloc (sizeof (struct command_line *)
  					* cmd->body_count);
    memset (cmd->body_list, 0, sizeof (struct command_line *) * cmd->body_count);
 +
 +  if (type != try_control)
    cmd->line = savestring (args, strlen (args));
 +  else
 +    cmd->line = savestring ("", strlen (""));
 +
    return cmd;
  }
 
 @@ -208,6 +213,33 @@ print_command_lines (struct ui_out *uiou
  	  continue;
  	}
 
 +      /* A try command.  Recursively print the try and catch blocks
 +        before continuing.  */
 +      if (list->control_type == try_control)
 +       {
 +	 ui_out_field_string (uiout, NULL, "try");
 +         ui_out_text (uiout, "\n");
 +         /* The true arm. */
 +         print_command_lines (uiout, list->body_list[0], depth + 1);
 +
 +         /* Show the except arm if it exists.  */
 +         if (list->body_count == 2)
 +           {
 +             if (depth)
 +               ui_out_spaces (uiout, 2 * depth);
 +             ui_out_field_string (uiout, NULL, "except");
 +             ui_out_text (uiout, "\n");
 +             print_command_lines (uiout, list->body_list[1], depth + 1);
 +           }
 +
 +         if (depth)
 +           ui_out_spaces (uiout, 2 * depth);
 +         ui_out_field_string (uiout, NULL, "end");
 +         ui_out_text (uiout, "\n");
 +         list = list->next;
 +         continue;
 +       }
 +
        /* ignore illegal command type and try next */
        list = list->next;
      }				/* while (list) */
 @@ -290,7 +322,33 @@ print_command_line (struct command_line
  	}
        fputs_filtered ("end\n", stream);
      }
 +
 +  /* A try command.  Recursively print both try and catch blocks.  */
 +  if (cmd->control_type == try_control)
 +    {
 +      fputs_filtered ("try\n", stream);
 +      /* The true arm. */
 +      print_command_line (cmd->body_list[0], depth + 1, stream);
 +
 +      /* Show the catch block if it exists.  */
 +      if (cmd->body_count == 2)
 +	{
 +	  if (depth)
 +	    {
 +	      for (i = 0; i < depth; i++)
 +		fputs_filtered ("  ", stream);
 +	    }
 +	  fputs_filtered ("except\n", stream);
 +	  print_command_line (cmd->body_list[1], depth + 1, stream);
 +	}
 +      if (depth)
 +	{
 +	  for (i = 0; i < depth; i++)
 +	    fputs_filtered ("  ", stream);
  }
 +      fputs_filtered ("end\n", stream);
 +    }
 +}
  #endif
 
  /* Execute the command in CMD.  */
 @@ -326,6 +384,13 @@ execute_user_command (struct cmd_list_el
    do_cleanups (old_chain);
  }
 
 +static int
 +captured_execute_control_command (PTR arg)
 +{
 +  struct command_line * cmd = (struct command_line *) arg;
 +  return execute_control_command (cmd);
 +}
 +
  enum command_control_type
  execute_control_command (struct command_line *cmd)
  {
 @@ -459,6 +524,30 @@ execute_control_command (struct command_
  	break;
        }
 
 +    case try_control:
 +      {
 +	current = cmd->body_list[0];
 +
 +	while (current)
 +	  {
 +	    ret = catch_errors (captured_execute_control_command, current,
 +				"", RETURN_MASK_ALL);
 +
 +	    if (ret == 0 || ret == invalid_control)
 +	      {
 +		if (cmd->body_count == 2)
 +		  current = cmd->body_list[1];
 +		else
 +		  current = NULL;
 +	      }
 +	    else
 +	      {
 +		current = current->next;
 +	      }
 +	  }
 +	break;
 +      }
 +
      default:
        warning ("Invalid control type in command structure.");
        return invalid_control;
 @@ -506,6 +595,21 @@ if_command (char *arg, int from_tty)
    free_command_lines (&command);
  }
 
 +void
 +try_command (char *block, int from_tty)
 +{
 +  struct command_line *command = NULL;
 +
 +  control_level = 1;
 +  command = get_command_line (try_control, block);
 +
 +  if (command == NULL)
 +    return;
 +
 +  execute_control_command (command);
 +  free_command_lines (&command);
 +}
 +
  /* Cleanup */
  static void
  arg_cleanup (void *ignore)
 @@ -758,12 +862,18 @@ read_next_line (struct command_line **co
    if (p1 - p == 4 && !strncmp (p, "else", 4))
      return else_command;
 
 +  /* Is the except clause of an if try structure?  */
 +  if (p1 - p == 6 && !strncmp (p, "except", 6))
 +    return except_command;
 +
    /* Check for while, if, break, continue, etc and build a new command
       line structure for them.  */
    if (p1 - p > 5 && !strncmp (p, "while", 5))
      *command = build_command_line (while_control, p + 6);
    else if (p1 - p > 2 && !strncmp (p, "if", 2))
      *command = build_command_line (if_control, p + 3);
 +  else if (p1 - p == 3 && !strncmp (p, "try", 3))
 +    *command = build_command_line (try_control, p + 4);
    else if (p1 - p == 10 && !strncmp (p, "loop_break", 10))
      {
        *command = (struct command_line *)
 @@ -845,7 +955,8 @@ recurse_read_control_structure (struct c
        if (val == end_command)
  	{
  	  if (current_cmd->control_type == while_control
 -	      || current_cmd->control_type == if_control)
 +	      || current_cmd->control_type == if_control
 +              || current_cmd->control_type == try_control)
  	    {
  	      /* Success reading an entire control structure.  */
  	      ret = simple_control;
 @@ -876,6 +987,23 @@ recurse_read_control_structure (struct c
  	    }
  	}
 
 +      if (val == except_command)
 +        {
 +          if (current_cmd->control_type == try_control
 +              && current_body == 1)
 +            {
 +              realloc_body_list (current_cmd, 2);
 +              current_body = 2;
 +              child_tail = NULL;
 +              continue;
 +            }
 +          else
 +            {
 +              ret = invalid_control;
 +              break;
 +            }
 +        }
 +
        if (child_tail)
  	{
  	  child_tail->next = next;
 @@ -895,7 +1023,8 @@ recurse_read_control_structure (struct c
        /* If the latest line is another control structure, then recurse
           on it.  */
        if (next->control_type == while_control
 -	  || next->control_type == if_control)
 +          || next->control_type == if_control
 +          || next->control_type == try_control)
  	{
  	  control_level++;
  	  ret = recurse_read_control_structure (next);
 @@ -962,7 +1091,8 @@ read_command_lines (char *prompt_arg, in
  	}
 
        if (next->control_type == while_control
 -	  || next->control_type == if_control)
 +          || next->control_type == if_control
 +          || next->control_type == try_control)
  	{
  	  control_level++;
  	  ret = recurse_read_control_structure (next);
 Index: cli/cli-script.h
 ===================================================================
 RCS file: /cvs/src/src/gdb/cli/cli-script.h,v
 retrieving revision 1.2
 diff -p -u -w -r1.2 cli-script.h
 --- cli-script.h	2001/03/06 08:21:20	1.2
 +++ cli-script.h	2001/12/18 23:45:34
 @@ -31,6 +31,8 @@ extern void while_command (char *arg, in
 
  extern void if_command (char *arg, int from_tty);
 
 +extern void try_command (char *block, int from_tty);
 +
  extern void show_user_1 (struct cmd_list_element *c, struct ui_file *stream);
 
  /* Exported to gdb/breakpoint.c */
 Index: doc/gdb.texinfo
 ===================================================================
 RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
 retrieving revision 1.59
 diff -p -u -w -r1.59 gdb.texinfo
 --- gdb.texinfo	2001/11/30 23:03:09	1.59
 +++ gdb.texinfo	2001/12/18 23:45:47
 @@ -13323,6 +13323,17 @@ execute, one per line, terminated by an
  The commands are executed repeatedly as long as the expression
  evaluates to true.
 
 +@kindex try
 +@kindex except
 +@item try
 +Takes no arguments and must be followed by a series of commands to be
 +executed, one per line.  Errors in the series of commands will terminate
 +execution of the series, but not the entire script.  There can be and
 +optional @code{except} line, which must also be followed by a series of
 +commands, one per line.  Commands in the @code{except} block are
 +executed if an error is encountered in the corresponding @code{try}
 +block.
 +
  @kindex document
  @item document @var{commandname}
  Document the user-defined command @var{commandname}, so that it can be
 
 -- 
 dhoward@redhat.com
 gdb engineering
 
 
 
>How-To-Repeat:
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted:


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]