[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

gEDA-cvs: pcb.git: branch: master updated (3126e746bfe6bc4f93e17699c32a3bd8938a243d)



The branch, master has been updated
       via  3126e746bfe6bc4f93e17699c32a3bd8938a243d (commit)
       via  83a5eb93ba68ad2161ee72bc23939d28788e7f62 (commit)
      from  2e0849b339504000c47772851b4262e08609f13e (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


=========
 Summary
=========

 doc/pcb.texi                     |   35 +++++++---
 src/action.c                     |    2 +-
 src/hid.h                        |   16 +++--
 src/hid/batch/batch.c            |   44 +------------
 src/hid/common/actions.c         |  139 ++++++++++++++++++++++++++------------
 src/hid/common/hid_resource.c    |    6 +-
 src/hid/gtk/gui-command-window.c |    6 +-
 src/hid/gtk/gui-top-window.c     |    4 +-
 src/hid/lesstif/main.c           |   48 +-------------
 src/hid/lesstif/menu.c           |   51 +-------------
 src/main.c                       |    2 +-
 11 files changed, 146 insertions(+), 207 deletions(-)


=================
 Commit Messages
=================

commit 3126e746bfe6bc4f93e17699c32a3bd8938a243d
Author: Jared Casper <jaredcasper@xxxxxxxxx>
Commit: DJ Delorie <dj@xxxxxxxxxxx>

    Check action name at registration.
    
    Prevent actions with spaces and '(' in their names from being
    registered; these will cause ambiguity and problems in
    hid_parse_actionstring.

:100644 100644 42e1e08... 9fa129d... M	src/hid/common/actions.c

commit 83a5eb93ba68ad2161ee72bc23939d28788e7f62
Author: Jared Casper <jaredcasper@xxxxxxxxx>
Commit: DJ Delorie <dj@xxxxxxxxxxx>

    Consolidate hid action parsing.
    
    - Create a common routine hid_parse_command, which handles both action
    script style "action(arg1, arg2);" and command entry style "action
    arg1 arg2".  This is done by making a static hid_parse_actionstring
    function, which takes a boolean to determine whether or not it should
    accept command entry style strings.  hid_parse_actions functions as it
    currently does, only accepting action script style, but does so by
    calling hid_parse_actionstring with TRUE.
    
    - Use hid_parse_command across all hids for user command entry,
    removing command_parse in lesstif/main.c and batch/batch.c.
    
    - Added extra error handling to common hid_actionv to match
    lesstif_call_action and remove lesstif_call_action.

:100644 100644 2f4c374... 51989ee... M	doc/pcb.texi
:100644 100644 a81c142... 6bbee09... M	src/action.c
:100644 100644 7b30022... dd34b8e... M	src/hid.h
:100644 100644 f26321d... 3129466... M	src/hid/batch/batch.c
:100644 100644 a2ad612... 42e1e08... M	src/hid/common/actions.c
:100644 100644 8802070... d5ba274... M	src/hid/common/hid_resource.c
:100644 100644 8bfd853... 3dfe95e... M	src/hid/gtk/gui-command-window.c
:100644 100644 a594330... e61c9f3... M	src/hid/gtk/gui-top-window.c
:100644 100644 51c52fe... 1613547... M	src/hid/lesstif/main.c
:100644 100644 44edaba... f88664d... M	src/hid/lesstif/menu.c
:100644 100644 3026f8d... 7e29d56... M	src/main.c

=========
 Changes
=========

commit 3126e746bfe6bc4f93e17699c32a3bd8938a243d
Author: Jared Casper <jaredcasper@xxxxxxxxx>
Commit: DJ Delorie <dj@xxxxxxxxxxx>

    Check action name at registration.
    
    Prevent actions with spaces and '(' in their names from being
    registered; these will cause ambiguity and problems in
    hid_parse_actionstring.

diff --git a/src/hid/common/actions.c b/src/hid/common/actions.c
index 42e1e08..9fa129d 100644
--- a/src/hid/common/actions.c
+++ b/src/hid/common/actions.c
@@ -28,16 +28,33 @@ static int n_actions = 0;
 
 HID_Action *current_action = NULL;
 
+static const char *
+check_action_name (const char *s)
+{
+  while (*s)
+    if (isspace ((int) *s++) || *s == '(')
+      return (s-1);
+  return NULL;
+}
+
 void
 hid_register_actions (HID_Action * a, int n)
 {
-  int i;
+  int i, count = 0;
   
   all_actions = realloc (all_actions,
                          (n_actions + n) * sizeof (HID_Action*));
   for (i = 0; i < n; i++)
-    all_actions[n_actions + i] = a + i;
-  n_actions += n;
+    {
+      if (check_action_name (a[i].name))
+        {
+          Message (_("ERROR! Invalid action name, "
+                     "action \"%s\" not registered.\n"), a[i].name);
+          continue;
+        }
+      all_actions[n_actions + count++] = a + i;
+    }
+  n_actions += count;
   all_actions_sorted = 0;
 }
 

commit 83a5eb93ba68ad2161ee72bc23939d28788e7f62
Author: Jared Casper <jaredcasper@xxxxxxxxx>
Commit: DJ Delorie <dj@xxxxxxxxxxx>

    Consolidate hid action parsing.
    
    - Create a common routine hid_parse_command, which handles both action
    script style "action(arg1, arg2);" and command entry style "action
    arg1 arg2".  This is done by making a static hid_parse_actionstring
    function, which takes a boolean to determine whether or not it should
    accept command entry style strings.  hid_parse_actions functions as it
    currently does, only accepting action script style, but does so by
    calling hid_parse_actionstring with TRUE.
    
    - Use hid_parse_command across all hids for user command entry,
    removing command_parse in lesstif/main.c and batch/batch.c.
    
    - Added extra error handling to common hid_actionv to match
    lesstif_call_action and remove lesstif_call_action.

diff --git a/doc/pcb.texi b/doc/pcb.texi
index 2f4c374..51989ee 100644
--- a/doc/pcb.texi
+++ b/doc/pcb.texi
@@ -2405,20 +2405,35 @@ the trace optimizer.
 @cindex user commands
 @cindex entering user commands
 The entering of user-commands is initiated by the action routine
-@emph{Command()} (the @code{(":")} character) and finished by either
-@emph{<Key>Return}
-or @emph{<Key>Escape} to confirm or to abort. These two key-bindings
-cannot be changed from the resource file.
-The triggering event, normally a key press, is ignored.
-The input area will replace the bottom statusline. It pops
-up when @emph{Command()} is called. The arguments of the user-commands
-are passed to the external commands without modification.
-See also, the resource @emph{saveInTMP}.
+@emph{Command()} (normally bound to the @code{(":")} character) which
+replaces the bottom statusline with an input area or opens a separate
+command window.  It is finished by either @emph{<Key>Return} or
+@emph{<Key>Escape} to confirm or to abort. These two key-bindings
+cannot be changed from the resource file.  The triggering event,
+normally a key press, is ignored.
+
+Commands can be entered in one of two styles, command entry syntax:
+``@emph{Command arg1 arg2}'' or action script syntax ``@emph{Action1(arg1,
+arg2); Action2(arg1, arg2);}''.  Quoting arguments works similar to
+bash quoting:
+
+@itemize
+@item A backslash (\) is the escape character.  It preserves the literal
+value of the next character that follows.  To get a literal '\' use
+"\\".
+
+@item Enclosing characters in single quotes preserves the literal value of
+each character within the quotes.  A single quote may not occur
+between single quotes, even when preceded by a blackslash.
+
+@item Enclosing characters in double quotes preserves the literal value of
+all characters within the quotes, with the exception of '\' which
+maintains its special meaning as an escape character.
+@end itemize
 
 There are simple @emph{usage} dialogs for each command and one for the
 complete set of commands.
 
-
 @table @samp
 
 @findex :l
diff --git a/src/action.c b/src/action.c
index a81c142..6bbee09 100644
--- a/src/action.c
+++ b/src/action.c
@@ -6794,7 +6794,7 @@ ActionExecuteFile (int argc, char **argv, int x, int y)
       if (*sp && *sp != '#')
 	{
 	  /*Message ("%s : line %-3d : \"%s\"\n", fname, n, sp);*/
-	  hid_parse_actions (sp, 0);
+	  hid_parse_actions (sp);
 	}
     }
 
diff --git a/src/hid.h b/src/hid.h
index 7b30022..dd34b8e 100644
--- a/src/hid.h
+++ b/src/hid.h
@@ -119,11 +119,17 @@ extern "C"
   void hid_save_settings (int);
   void hid_load_settings (void);
 
-/* Parse the given string into action calls, and call `f' for each
-   action found.  Returns nonzero if the action handler(s) return
-   nonzero.  If f is NULL, hid_actionv is called.  */
-  int hid_parse_actions (const char *str_,
-			 int (*_f) (const char *, int, char **));
+/* Parse the given command string into action calls, and call
+   hid_actionv for each action found.  Accepts both "action(arg1,
+   arg2)" and command-style "action arg1 arg2", allowing only one
+   action in the later case.  Returns nonzero if the action handler(s)
+   return nonzero. */
+  int hid_parse_command (const char *str_);
+
+/* Parse the given string into action calls, and call
+   hid_actionv for each action found.  Accepts only
+   "action(arg1, arg2)" */
+  int hid_parse_actions (const char *str_);
 
   typedef struct
   {
diff --git a/src/hid/batch/batch.c b/src/hid/batch/batch.c
index f26321d..3129466 100644
--- a/src/hid/batch/batch.c
+++ b/src/hid/batch/batch.c
@@ -114,45 +114,6 @@ REGISTER_ACTIONS (batch_action_list)
 /* ----------------------------------------------------------------------------- */
 
 static void
-command_parse (char *s)
-{
-  int n = 0, ws = 1;
-  char *cp;
-  char **argv;
-
-  for (cp = s; *cp; cp++)
-    {
-      if (isspace ((int) *cp))
-	ws = 1;
-      else
-	{
-	  n += ws;
-	  ws = 0;
-	}
-    }
-  argv = (char **) malloc ((n + 1) * sizeof (char *));
-
-  n = 0;
-  ws = 1;
-  for (cp = s; *cp; cp++)
-    {
-      if (isspace ((int) *cp))
-	{
-	  ws = 1;
-	  *cp = 0;
-	}
-      else
-	{
-	  if (ws)
-	    argv[n++] = cp;
-	  ws = 0;
-	}
-    }
-  argv[n] = 0;
-  hid_actionv (argv[0], n - 1, argv + 1);
-}
-
-static void
 batch_do_export (HID_Attr_Val * options)
 {
   int interactive;
@@ -177,10 +138,7 @@ batch_do_export (HID_Attr_Val * options)
 	}
       if (fgets(line, sizeof(line)-1, stdin) == NULL)
 	return;
-      if (strchr (line, '('))
-	hid_parse_actions (line, 0);
-      else
-	command_parse (line);
+      hid_parse_command (line);
     }
 }
 
diff --git a/src/hid/common/actions.c b/src/hid/common/actions.c
index a2ad612..42e1e08 100644
--- a/src/hid/common/actions.c
+++ b/src/hid/common/actions.c
@@ -11,6 +11,7 @@
 
 #include "global.h"
 #include "data.h"
+#include "error.h"
 
 #include "hid.h"
 #include "../hidint.h"
@@ -198,19 +199,30 @@ hid_actionv (const char *name, int argc, char **argv)
   int x = 0, y = 0, i, ret;
   HID_Action *a, *old_action;
 
-  if (Settings.verbose && name)
+  if (!name)
+    return 1;
+
+  a = hid_find_action (name);
+  if (!a)
     {
-      printf ("Action: \033[34m%s(", name);
+      int i;
+      Message ("no action %s(", name);
       for (i = 0; i < argc; i++)
-	printf ("%s%s", i ? "," : "", argv[i]);
-      printf (")\033[0m\n");
+        Message ("%s%s", i ? ", " : "", argv[i]);
+      Message (")\n");
+      return 1;
     }
 
-  a = hid_find_action (name);
-  if (!a)
-    return 1;
   if (a->need_coord_msg)
     gui->get_coords (a->need_coord_msg, &x, &y);
+
+  if (Settings.verbose)
+    {
+      printf ("Action: \033[34m%s(", name);
+      for (i = 0; i < argc; i++)
+	printf ("%s%s", i ? "," : "", argv[i]);
+      printf (")\033[0m\n");
+    }
   
   old_action     = current_action;
   current_action = a;
@@ -220,9 +232,8 @@ hid_actionv (const char *name, int argc, char **argv)
   return ret;
 }
 
-int
-hid_parse_actions (const char *rstr,
-		   int (*function) (const char *, int, char **))
+static int
+hid_parse_actionstring (const char *rstr, char require_parens)
 {
   char **list = NULL;
   int max = 0;
@@ -232,11 +243,9 @@ hid_parse_actions (const char *rstr,
   char *cp, *aname, *cp2;
   int maybe_empty = 0;
   char in_quotes = 0;
+  char parens = 0;
   int retcode = 0;
 
-  if (function == NULL)
-    function = hid_actionv;
-
   /*fprintf(stderr, "invoke: `%s'\n", rstr);*/
 
   sp = rstr;
@@ -257,52 +266,65 @@ another:
     }
   
   aname = cp;
-  
-  /* search for the leading ( */
-  while (*sp && *sp != '(')
+
+  /* copy the action name, assumes name does not have a space or '('
+   * in its name */
+  while (*sp && !isspace ((int) *sp) && *sp != '(')
     *cp++ = *sp++;
   *cp++ = 0;
-  if (*sp)
+
+  /* skip whitespace */
+  while (*sp && isspace ((int) *sp))
     sp++;
 
   /*
-   * we didn't find a leading ( so invoke the action
+   * we only have an action name, so invoke the action
    * with no parameters or event.
    */
   if (!*sp)
     {
-      if (function (aname, 0, 0))
-        {
-          retcode = 1;
-          goto cleanup;
-        }
-      goto another;
+      retcode = hid_actionv (aname, 0, 0);
+      goto cleanup;
+    }
+
+  /* are we using parenthesis? */
+  if (*sp == '(')
+    {
+      parens = 1;
+      sp++;
+    }
+  else if (require_parens)
+    {
+      Message (_("Syntax error: %s\n"), rstr);
+      Message (_("    expected: Action(arg1, arg2)"));
+      retcode = 1;
+      goto cleanup;
     }
   
-  /* 
-   * we found a leading ( so see if we have parameters to pass to the
-   * action 
-   */
+  /* get the parameters to pass to the action */
   while (1)
     {
       /* 
        * maybe_empty == 0 means that the last char examined was not a
-       * "," 
+       * ","
        */
-      if (*sp == ')' && !maybe_empty)
+      if (!maybe_empty && ((parens && *sp == ')') || (!parens && !*sp)))
 	{
-	  if (function (aname, num, list))
-	    {
-	      retcode = 1;
-	      goto cleanup;
-	    }
-	  sp++;
+          retcode = hid_actionv (aname, num, list);
+          if (retcode)
+            goto cleanup;
+
+          /* strip any white space or ';' following the action */
+          if (parens)
+            sp++;
+          while (*sp && (isspace ((int) *sp) || *sp == ';'))
+            sp++;
 	  goto another;
 	}
       else if (*sp == 0 && !maybe_empty)
 	break;
       else
-	{
+        {
 	  maybe_empty = 0;
 	  in_quotes = 0;
 	  /* 
@@ -322,8 +344,12 @@ another:
 	    sp++;
 	  list[num++] = cp;
 	  
-	  /* search for a "," or a ")" */
-	  while (*sp && (in_quotes || (*sp != ',' && *sp != ')')))
+	  /* search for the end of the argument, we want to keep going
+           * if we are in quotes or the char is not a delimiter
+           */
+	  while (*sp && (in_quotes || ((*sp != ',')
+                                       && (!parens || *sp != ')')
+                                       && (parens || !isspace ((int) *sp)))))
 	    {
 	      /*
 	       * single quotes give literal value inside, including '\'. 
@@ -343,7 +369,7 @@ another:
 	    }
 	  cp2 = cp - 1;
 	  *cp++ = 0;
-	  if (*sp == ',')
+	  if (*sp == ',' || (!parens && isspace ((int) *sp)))
 	    {
 	      maybe_empty = 1;
 	      sp++;
@@ -365,6 +391,16 @@ another:
   return retcode;
 }
 
+int hid_parse_command (const char *str_)
+{
+  return hid_parse_actionstring (str_, FALSE);
+}
+
+int hid_parse_actions (const char *str_)
+{
+  return hid_parse_actionstring (str_, TRUE);
+}
+
 /* trick for the doc extractor */
 #define static
 
diff --git a/src/hid/common/hid_resource.c b/src/hid/common/hid_resource.c
index 8802070..d5ba274 100644
--- a/src/hid/common/hid_resource.c
+++ b/src/hid/common/hid_resource.c
@@ -198,8 +198,6 @@ do_mouse_action (int button, int mod_mask)
 
   for (i = 0; i < action->c; i++)
     if (action->v[i].value)
-      if (hid_parse_actions (action->v[i].value, hid_actionv))
-	return;
+      if (hid_parse_actions (action->v[i].value))
+        return;
 }
-
-
diff --git a/src/hid/gtk/gui-command-window.c b/src/hid/gtk/gui-command-window.c
index 8bfd853..3dfe95e 100644
--- a/src/hid/gtk/gui-command-window.c
+++ b/src/hid/gtk/gui-command-window.c
@@ -212,7 +212,7 @@ command_entry_activate_cb (GtkWidget * widget, gpointer data)
   if (ghidgui->use_command_window)
     {
       HideCrosshair (True);
-      hid_parse_actions (command, NULL);
+      hid_parse_command (command);
       RestoreCrosshair (True);
       g_free (command);
     }
@@ -473,13 +473,13 @@ ghid_handle_user_command (gboolean raise)
 	  /* copy new comand line to save buffer */
 	  g_free (previous);
 	  previous = g_strdup (command);
-	  hid_parse_actions (command, NULL);
+	  hid_parse_command (command);
 	  g_free (command);
 	}
       else if (previous)
 	{
 	  command = g_strdup (previous);
-	  hid_parse_actions (command, NULL);
+	  hid_parse_command (command);
 	  g_free (command);
 	}
       RestoreCrosshair (True);
diff --git a/src/hid/gtk/gui-top-window.c b/src/hid/gtk/gui-top-window.c
index a594330..e61c9f3 100644
--- a/src/hid/gtk/gui-top-window.c
+++ b/src/hid/gtk/gui-top-window.c
@@ -631,7 +631,7 @@ ghid_menu_cb (GtkAction * action, gpointer data)
 #ifdef DEBUG_MENUS
 	    printf ("    %s\n", node->v[vi].value);
 #endif
-	    hid_parse_actions (node->v[vi].value, NULL);
+	    hid_parse_actions (node->v[vi].value);
 	  }
     }
   else {
@@ -2544,7 +2544,7 @@ ghid_listener_cb (GIOChannel *source,
       switch (status)
 	{
 	case G_IO_STATUS_NORMAL:
-	  hid_parse_actions (str, NULL);
+	  hid_parse_actions (str);
 	  g_free (str);
 	  break;
 
diff --git a/src/hid/lesstif/main.c b/src/hid/lesstif/main.c
index 51c52fe..1613547 100644
--- a/src/hid/lesstif/main.c
+++ b/src/hid/lesstif/main.c
@@ -627,47 +627,6 @@ SwapSides (int argc, char **argv, int x, int y)
 static Widget m_cmd = 0, m_cmd_label;
 
 static void
-command_parse (char *s)
-{
-  int n = 0, ws = 1;
-  char *cp;
-  char **argv;
-
-  for (cp = s; *cp; cp++)
-    {
-      if (isspace ((int) *cp))
-	ws = 1;
-      else
-	{
-	  n += ws;
-	  ws = 0;
-	}
-    }
-  argv = (char **) malloc ((n + 1) * sizeof (char *));
-
-  n = 0;
-  ws = 1;
-  for (cp = s; *cp; cp++)
-    {
-      if (isspace ((int) *cp))
-	{
-	  ws = 1;
-	  *cp = 0;
-	}
-      else
-	{
-	  if (ws)
-	    argv[n++] = cp;
-	  ws = 0;
-	}
-    }
-  if (n == 0)
-    return;
-  argv[n] = 0;
-  lesstif_call_action (argv[0], n - 1, argv + 1);
-}
-
-static void
 command_callback (Widget w, XtPointer uptr, XmTextVerifyCallbackStruct * cbs)
 {
   char *s;
@@ -676,10 +635,7 @@ command_callback (Widget w, XtPointer uptr, XmTextVerifyCallbackStruct * cbs)
     case XmCR_ACTIVATE:
       s = XmTextGetString (w);
       lesstif_show_crosshair (0);
-      if (strchr (s, '('))
-	hid_parse_actions (s, lesstif_call_action);
-      else
-	command_parse (s);
+      hid_parse_command (s);
       XtFree (s);
       XmTextSetString (w, "");
     case XmCR_LOSING_FOCUS:
@@ -1966,7 +1922,7 @@ lesstif_listener_cb (XtPointer client_data, int *fid, XtInputId *id)
   if (nbytes)
     {
       buf[nbytes] = '\0';
-      hid_parse_actions (buf, NULL);
+      hid_parse_actions (buf);
     }
 }
 
diff --git a/src/hid/lesstif/menu.c b/src/hid/lesstif/menu.c
index 44edaba..f88664d 100644
--- a/src/hid/lesstif/menu.c
+++ b/src/hid/lesstif/menu.c
@@ -812,53 +812,6 @@ lesstif_get_coords (const char *msg, int *px, int *py)
     lesstif_coords_to_pcb (action_x, action_y, px, py);
 }
 
-int
-lesstif_call_action (const char *aname, int argc, char **argv)
-{
-  int px, py, ret;
-  HID_Action *a, *old_action;
-
-  if (!aname)
-    return 1;
-  a = hid_find_action (aname);
-  if (!a)
-    {
-      int i;
-      printf ("no action %s(", aname);
-      for (i = 0; i < argc; i++)
-	printf ("%s%s", i ? ", " : "", argv[i]);
-      printf (")\n");
-      return 1;
-    }
-
-  if (a->need_coord_msg && !have_xy)
-    {
-      const char *msg;
-      if (strcmp (aname, "GetXY") == 0)
-	msg = argv[0];
-      else
-	msg = a->need_coord_msg;
-      lesstif_get_xy (msg);
-    }
-  lesstif_coords_to_pcb (action_x, action_y, &px, &py);
-
-  if (Settings.verbose)
-    {
-      int i;
-      printf ("Action: \033[34m%s(", aname);
-      for (i = 0; i < argc; i++)
-	printf ("%s%s", i ? "," : "", argv[i]);
-      printf (")\033[0m\n");
-    }
-
-  old_action     = current_action;
-  current_action = a;
-  ret = current_action->trigger_cb (argc, argv, px, py);
-  current_action = old_action;
-
-  return ret;
-}
-
 static void
 callback (Widget w, Resource * node, XmPushButtonCallbackStruct * pbcs)
 {
@@ -893,7 +846,7 @@ callback (Widget w, Resource * node, XmPushButtonCallbackStruct * pbcs)
   lesstif_need_idle_proc ();
   for (vi = 1; vi < node->c; vi++)
     if (resource_type (node->v[vi]) == 10)
-      if (hid_parse_actions (node->v[vi].value, lesstif_call_action))
+      if (hid_parse_actions (node->v[vi].value))
 	return;
 }
 
@@ -1254,7 +1207,7 @@ lesstif_key_event (XKeyEvent * e)
   for (vi = 1; vi < cur_table[i].u.a.node->c; vi++)
     if (resource_type (cur_table[i].u.a.node->v[vi]) == 10)
       if (hid_parse_actions
-	  (cur_table[i].u.a.node->v[vi].value, lesstif_call_action))
+	  (cur_table[i].u.a.node->v[vi].value))
 	break;
   cur_table = 0;
   return 1;
diff --git a/src/main.c b/src/main.c
index 3026f8d..7e29d56 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1033,7 +1033,7 @@ main (int argc, char *argv[])
   if (Settings.ActionString)
     {
       Message (_("Executing startup action %s\n"), Settings.ActionString);
-      hid_parse_actions (Settings.ActionString, 0);
+      hid_parse_actions (Settings.ActionString);
     }
 
 #if HAVE_DBUS




_______________________________________________
geda-cvs mailing list
geda-cvs@xxxxxxxxxxxxxx
http://www.seul.org/cgi-bin/mailman/listinfo/geda-cvs