This is the mail archive of the gdb-patches@sourceware.org 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]

Fix python indented multi-line commands


Hi,

Today, if you try to use indentation in Python code within GDB you will
get this error:

(gdb) python
>def foo ():
>  print 'hooray'
>end
  File "<string>", line 2
    print 'hooray'
        ^
IndentationError: expected an indented block

The patch below, extracted from the python branch, fixes the problem.
It changes GDB to not trim whitespace from the beginning of the line
when storing multi-line commands internally. Tested with no regressions
on x86_64-linux. Ok?

:ADDPATCH cli:

-- 
[]'s
Thiago Jung Bauermann
IBM Linux Technology Center

gdb/
2008-08-13  Vladimir Prus  <vladimir@codesourcery.com>
            Thiago Jung Bauermann  <bauerman@br.ibm.com>

        * cli-script.c (read_next_line): Add special_processing argument.
        (recurse_read_control_structure): Adapt to new read_next_line
        signature.
        (read_command_lines): Add special_processing argument.
        (define_command): Adapt to new read_command_lines signature.
        (document_command): Likewise.
        * breakpoint.c (commands_command): Likewise.
        * defs.h (read_command_lines): Adjust function prototype.

testsuite/
2008-08-13  Thiago Jung Bauermann  <bauerman@br.ibm.com>

        * gdb.python/python.exp: Test indented multi-line command.

Index: gdb.git/gdb/breakpoint.c
===================================================================
--- gdb.git.orig/gdb/breakpoint.c       2008-08-13 03:21:05.000000000 -0300
+++ gdb.git/gdb/breakpoint.c    2008-08-13 03:21:07.000000000 -0300
@@ -652,7 +652,7 @@ commands_command (char *arg, int from_tt
        char *tmpbuf = xstrprintf ("Type commands for when breakpoint %d is hit, one per line.", 
                                 bnum);
        struct cleanup *cleanups = make_cleanup (xfree, tmpbuf);
-       l = read_command_lines (tmpbuf, from_tty);
+       l = read_command_lines (tmpbuf, from_tty, 1);
        do_cleanups (cleanups);
        free_command_lines (&b->commands);
        b->commands = l;
Index: gdb.git/gdb/cli/cli-script.c
===================================================================
--- gdb.git.orig/gdb/cli/cli-script.c   2008-08-13 03:21:05.000000000 -0300
+++ gdb.git/gdb/cli/cli-script.c        2008-08-13 03:22:19.000000000 -0300
@@ -840,13 +840,17 @@ realloc_body_list (struct command_line *
 }
 
 /* Read one line from the input stream.  If the command is an "else" or
-   "end", return such an indication to the caller.  */
+   "end", return such an indication to the caller.  If SPECIAL_PROCESSING
+   is true, strip leading and trailing whitespace in the line and attempt
+   to recognize GDB control commands.  Otherwise, only "end" is
+   recognized.  */
 
 static enum misc_command_type
-read_next_line (struct command_line **command)
+read_next_line (struct command_line **command, int special_processing)
 {
   char *p, *p1, *prompt_ptr, control_prompt[256];
   int i = 0;
+  int not_handled = 0;
 
   if (control_level >= 254)
     error (_("Control nesting too deep!"));
@@ -869,10 +873,14 @@ read_next_line (struct command_line **co
   if (p == NULL)
     return end_command;
 
-  /* Strip leading and trailing whitespace.  */
-  while (*p == ' ' || *p == '\t')
-    p++;
+  if (special_processing)
+    {
+      /* Strip leading whitespace.  */
+      while (*p == ' ' || *p == '\t')
+       p++;
+    }
 
+  /* Strip trailing whitespace.  */
   p1 = p + strlen (p);
   while (p1 != p && (p1[-1] == ' ' || p1[-1] == '\t'))
     p1--;
@@ -887,63 +895,69 @@ read_next_line (struct command_line **co
   if (p1 - p == 3 && !strncmp (p, "end", 3))
     return end_command;
 
-  /* Is the else clause of an if control structure?  */
-  if (p1 - p == 4 && !strncmp (p, "else", 4))
-    return else_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))
-    {
-      char *first_arg;
-      first_arg = p + 5;
-      while (first_arg < p1 && isspace (*first_arg))
-        first_arg++;
-      *command = build_command_line (while_control, first_arg);
-    }
-  else if (p1 - p > 2 && !strncmp (p, "if", 2))
-    {
-      char *first_arg;
-      first_arg = p + 2;
-      while (first_arg < p1 && isspace (*first_arg))
-        first_arg++;
-      *command = build_command_line (if_control, first_arg);
-    }
-  else if (p1 - p >= 8 && !strncmp (p, "commands", 8))
-    {
-      char *first_arg;
-      first_arg = p + 8;
-      while (first_arg < p1 && isspace (*first_arg))
-        first_arg++;
-      *command = build_command_line (commands_control, first_arg);
-    }
-  else if (p1 - p == 6 && !strncmp (p, "python", 6))
-    {
-      /* Note that we ignore the inline "python command" form
-        here.  */
-      *command = build_command_line (python_control, "");
-    }
-  else if (p1 - p == 10 && !strncmp (p, "loop_break", 10))
-    {
-      *command = (struct command_line *)
-       xmalloc (sizeof (struct command_line));
-      (*command)->next = NULL;
-      (*command)->line = NULL;
-      (*command)->control_type = break_control;
-      (*command)->body_count = 0;
-      (*command)->body_list = NULL;
-    }
-  else if (p1 - p == 13 && !strncmp (p, "loop_continue", 13))
+  if (special_processing)
     {
-      *command = (struct command_line *)
-       xmalloc (sizeof (struct command_line));
-      (*command)->next = NULL;
-      (*command)->line = NULL;
-      (*command)->control_type = continue_control;
-      (*command)->body_count = 0;
-      (*command)->body_list = NULL;
+      /* Is the else clause of an if control structure?  */
+      if (p1 - p == 4 && !strncmp (p, "else", 4))
+       return else_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))
+       {
+         char *first_arg;
+         first_arg = p + 5;
+         while (first_arg < p1 && isspace (*first_arg))
+           first_arg++;
+         *command = build_command_line (while_control, first_arg);
+       }
+      else if (p1 - p > 2 && !strncmp (p, "if", 2))
+       {
+         char *first_arg;
+         first_arg = p + 2;
+         while (first_arg < p1 && isspace (*first_arg))
+           first_arg++;
+         *command = build_command_line (if_control, first_arg);
+       }
+      else if (p1 - p >= 8 && !strncmp (p, "commands", 8))
+       {
+         char *first_arg;
+         first_arg = p + 8;
+         while (first_arg < p1 && isspace (*first_arg))
+           first_arg++;
+         *command = build_command_line (commands_control, first_arg);
+       }
+      else if (p1 - p == 6 && !strncmp (p, "python", 6))
+       {
+         /* Note that we ignore the inline "python command" form
+            here.  */
+         *command = build_command_line (python_control, "");
+       }
+      else if (p1 - p == 10 && !strncmp (p, "loop_break", 10))
+       {
+         *command = (struct command_line *)
+           xmalloc (sizeof (struct command_line));
+         (*command)->next = NULL;
+         (*command)->line = NULL;
+         (*command)->control_type = break_control;
+         (*command)->body_count = 0;
+         (*command)->body_list = NULL;
+       }
+      else if (p1 - p == 13 && !strncmp (p, "loop_continue", 13))
+       {
+         *command = (struct command_line *)
+           xmalloc (sizeof (struct command_line));
+         (*command)->next = NULL;
+         (*command)->line = NULL;
+         (*command)->control_type = continue_control;
+         (*command)->body_count = 0;
+         (*command)->body_list = NULL;
+       }
+      else
+       not_handled = 1;
     }
-  else
+
+  if (!special_processing || not_handled)
     {
       /* A normal command.  */
       *command = (struct command_line *)
@@ -989,7 +1003,7 @@ recurse_read_control_structure (struct c
       dont_repeat ();
 
       next = NULL;
-      val = read_next_line (&next);
+      val = read_next_line (&next, current_cmd->control_type != python_control);
 
       /* Just skip blanks and comments.  */
       if (val == nop_command)
@@ -1071,12 +1085,16 @@ recurse_read_control_structure (struct c
 /* Read lines from the input stream and accumulate them in a chain of
    struct command_line's, which is then returned.  For input from a
    terminal, the special command "end" is used to mark the end of the
-   input, and is not included in the returned chain of commands. */
+   input, and is not included in the returned chain of commands.
+
+   If SPECIAL_PROCESSING is true, strip leading and trailing whitespace
+   in the line and attempt to recognize GDB control commands.  Otherwise,
+   only "end" is recognized.  */
 
 #define END_MESSAGE "End with a line saying just \"end\"."
 
 struct command_line *
-read_command_lines (char *prompt_arg, int from_tty)
+read_command_lines (char *prompt_arg, int from_tty, int special_processing)
 {
   struct command_line *head, *tail, *next;
   struct cleanup *old_chain;
@@ -1105,7 +1123,7 @@ read_command_lines (char *prompt_arg, in
   while (1)
     {
       dont_repeat ();
-      val = read_next_line (&next);
+      val = read_next_line (&next, special_processing);
 
       /* Ignore blank lines or comments.  */
       if (val == nop_command)
@@ -1339,7 +1357,7 @@ define_command (char *comname, int from_
       *tem = tolower (*tem);
 
   sprintf (tmpbuf, "Type commands for definition of \"%s\".", comname);
-  cmds = read_command_lines (tmpbuf, from_tty);
+  cmds = read_command_lines (tmpbuf, from_tty, 1);
 
   if (c && c->class == class_user)
     free_command_lines (&c->user_commands);
@@ -1386,7 +1404,7 @@ document_command (char *comname, int fro
     error (_("Command \"%s\" is built-in."), comname);
 
   sprintf (tmpbuf, "Type documentation for \"%s\".", comname);
-  doclines = read_command_lines (tmpbuf, from_tty);
+  doclines = read_command_lines (tmpbuf, from_tty, 0);
 
   if (c->doc)
     xfree (c->doc);
Index: gdb.git/gdb/defs.h
===================================================================
--- gdb.git.orig/gdb/defs.h     2008-08-13 03:21:05.000000000 -0300
+++ gdb.git/gdb/defs.h  2008-08-13 03:21:07.000000000 -0300
@@ -668,7 +668,7 @@ struct command_line
     struct command_line **body_list;
   };
 
-extern struct command_line *read_command_lines (char *, int);
+extern struct command_line *read_command_lines (char *, int, int);
 
 extern void free_command_lines (struct command_line **);
 
Index: gdb.git/gdb/testsuite/gdb.python/python.exp
===================================================================
--- gdb.git.orig/gdb/testsuite/gdb.python/python.exp    2008-08-13 03:21:05.000000000 -0300
+++ gdb.git/gdb/testsuite/gdb.python/python.exp 2008-08-13 03:21:07.000000000 -0300
@@ -64,3 +64,10 @@ gdb_py_test_multiple "show python comman
   "end" "" \
   "end" "" \
   "show user zzq" "User command zzq:.*  python.*print 23.*  end"
+
+gdb_py_test_multiple "indented multi-line python command" \
+  "python" "" \
+  "def foo ():" "" \
+  "  print 'hello, world!'" "" \
+  "foo ()" "" \
+  "end" "hello, world!"


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