m4-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Changes to m4/modules/m4.c,v


From: Eric Blake
Subject: Changes to m4/modules/m4.c,v
Date: Tue, 31 Oct 2006 14:14:20 +0000

CVSROOT:        /sources/m4
Module name:    m4
Changes by:     Eric Blake <ericb>      06/10/31 14:14:19

Index: modules/m4.c
===================================================================
RCS file: /sources/m4/m4/modules/m4.c,v
retrieving revision 1.89
retrieving revision 1.90
diff -u -b -r1.89 -r1.90
--- modules/m4.c        31 Oct 2006 02:05:37 -0000      1.89
+++ modules/m4.c        31 Oct 2006 14:14:18 -0000      1.90
@@ -23,6 +23,7 @@
 #include <errno.h>
 
 #include "stdlib--.h"
+#include "strstr.h"
 #include "tempname.h"
 #include "unistd--.h"
 
@@ -550,7 +551,7 @@
 {
   int i = 0;
 
-  if (argc == 2 && !m4_numeric_arg (context, argc, argv, 1, &i))
+  if (argc >= 2 && !m4_numeric_arg (context, argc, argv, 1, &i))
     return;
 
   m4_make_diversion (context, i);
@@ -878,20 +879,9 @@
    argument.  */
 M4BUILTIN_HANDLER (index)
 {
-  const char *cp, *last;
-  int l1, l2, retval;
-
-  l1 = strlen (M4ARG (1));
-  l2 = strlen (M4ARG (2));
-
-  last = M4ARG (1) + l1 - l2;
-
-  for (cp = M4ARG (1); cp <= last; cp++)
-    {
-      if (strncmp (cp, M4ARG (2), l2) == 0)
-       break;
-    }
-  retval = (cp <= last) ? cp - M4ARG (1) : -1;
+  const char *haystack = M4ARG (1);
+  const char *result = strstr (haystack, M4ARG (2));
+  int retval = result ? result - haystack : -1;
 
   m4_shipout_int (obs, retval);
 }
@@ -908,7 +898,7 @@
   if (!m4_numeric_arg (context, argc, argv, 2, &start))
     return;
 
-  if (argc == 4 && !m4_numeric_arg (context, argc, argv, 3, &length))
+  if (argc >= 4 && !m4_numeric_arg (context, argc, argv, 3, &length))
     return;
 
   if (start < 0 || length <= 0 || start >= avail)
@@ -969,45 +959,49 @@
    deleted from the first (pueh)  */
 M4BUILTIN_HANDLER (translit)
 {
-  register const char *data, *tmp;
-  const char *from, *to;
-  int tolen;
+  const unsigned char *data;
+  const unsigned char *from;
+  const unsigned char *to;
+  char map[256] = {0};
+  char found[256] = {0};
 
   from = M4ARG (2);
   if (strchr (from, '-') != NULL)
     {
       from = m4_expand_ranges (from, obs);
-      if (from == NULL)
-       return;
+      assert (from);
     }
 
-  if (argc == 4)
-    {
       to = M4ARG (3);
       if (strchr (to, '-') != NULL)
        {
          to = m4_expand_ranges (to, obs);
-         if (to == NULL)
-           return;
-       }
+      assert (to);
     }
-  else
-    to = "";
-
-  tolen = strlen (to);
 
-  for (data = M4ARG (1); *data; data++)
+  /* Calling strchr(from) for each character in data is quadratic,
+     since both strings can be arbitrarily long.  Instead, create a
+     from-to mapping in one pass of data, then use that map in one
+     pass of from, for linear behavior.  Traditional behavior is that
+     only the first instance of a character in from is consulted,
+     hence the found map.  */
+  for ( ; *from; from++)
     {
-      tmp = strchr (from, *data);
-      if (tmp == NULL)
+      if (! found[*from])
        {
-         obstack_1grow (obs, *data);
+         found[*from] = 1;
+         map[*from] = *to;
        }
-      else
-       {
-         if (tmp - from < tolen)
-           obstack_1grow (obs, *(to + (tmp - from)));
+      if (*to != '\0')
+       to++;
        }
+
+  for (data = M4ARG (1); *data; data++)
+    {
+      if (! found[*data])
+       obstack_1grow (obs, *data);
+      else if (map[*data])
+       obstack_1grow (obs, map[*data]);
     }
 }
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]