bison-patches
[Top][All Lists]
Advanced

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

Bison + Autoscan + Coreutils


From: Akim Demaille
Subject: Bison + Autoscan + Coreutils
Date: 27 Sep 2002 15:03:15 +0200
User-agent: Gnus/5.0808 (Gnus v5.8.8) XEmacs/21.4 (Honest Recruiter)

I'm applying the following patch, which has bits that concern the
Coreutils, in particular the prereq.m4 parts.  Playing with autoscan
revealed I was not performing all the checks required by argmatch, so
I introduced jm_PREREQ_ARGMATCH.  But there is also the first
ocurrence of something I have been wanting for a looong time, but was
not possible before Automake 1.7 and Autoconf 2.54: having a means to
say `I use argmatch' in configure.ac, and have the right thing happen:
shipping, compilation etc.

Here is the plan: introduce a macro which says `I swear I'm GPL'.
Then we can start shipping quotearg, argmatch etc. with Autoconf, and
have it be able to run the corresponding tests, ask for their shipping
to Automake etc.  Another Autoconf release? => autoreconf --install
update the files.  Maybe it even adds a new requirement for argmatch,
say quotearg => without noticing, quotearg.[ch] are shipped set up
etc.

Needless to say that we can then add argmatch etc. in autoscan.

I'm very interested in knowing if you two guys think I'm walking
towards a good direction.

Index: ChangeLog
from  Akim Demaille  <address@hidden>

        Playing with Autoscan.

        * m4/prereq.m4 (jm_PREREQ_ARGMATCH, jm_FUNC_ARGMATCH): New.
        * lib/Makefile.am (libbison_a_SOURCES): No longer include
        argmatch.c and argmatch.h, since they are AC_LIBSOURCE'd.
        * lib/strcasecmp.c, lib/strncasecmp.c, lib/memcmp.c: New, from the
        Coreutils 4.5.1.

Index: configure.ac
===================================================================
RCS file: /cvsroot/bison/bison/configure.ac,v
retrieving revision 1.4
diff -u -u -r1.4 configure.ac
--- configure.ac 13 Sep 2002 15:39:52 -0000 1.4
+++ configure.ac 27 Sep 2002 13:02:05 -0000
@@ -98,6 +98,7 @@
 AC_FUNC_MALLOC
 AC_FUNC_REALLOC
 jm_PREREQ_QUOTEARG
+jm_FUNC_ARGMATCH
 jm_PREREQ_ERROR
 jm_PREREQ_TEMPNAME
 AM_WITH_DMALLOC
Index: lib/Makefile.am
===================================================================
RCS file: /cvsroot/bison/bison/lib/Makefile.am,v
retrieving revision 1.29
diff -u -u -r1.29 Makefile.am
--- lib/Makefile.am 12 Aug 2002 14:08:04 -0000 1.29
+++ lib/Makefile.am 27 Sep 2002 13:02:05 -0000
@@ -32,7 +32,6 @@
 EXTRA_DIST = malloc.c realloc.c strnlen.c
 
 libbison_a_SOURCES = \
-  argmatch.h argmatch.c \
   gettext.h \
   basename.c dirname.h dirname.c \
   getopt.h getopt.c getopt1.c \
Index: lib/memcmp.c
===================================================================
RCS file: lib/memcmp.c
diff -N lib/memcmp.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ lib/memcmp.c 27 Sep 2002 13:02:05 -0000
@@ -0,0 +1,386 @@
+/* Copyright (C) 1991, 1993, 1995, 1997, 1998 Free Software Foundation, Inc.
+   Contributed by Torbjorn Granlund (address@hidden).
+
+   NOTE: The canonical source of this file is maintained with the GNU C 
Library.
+   Bugs can be reported to address@hidden
+
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by the
+   Free Software Foundation; either version 2, or (at your option) any
+   later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+   USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#undef __ptr_t
+#if defined __cplusplus || (defined __STDC__ && __STDC__)
+# define __ptr_t       void *
+#else /* Not C++ or ANSI C.  */
+# undef        const
+# define const
+# define __ptr_t       char *
+#endif /* C++ or ANSI C.  */
+
+#ifndef __P
+# if defined __GNUC__ || (defined __STDC__ && __STDC__)
+#  define __P(args) args
+# else
+#  define __P(args) ()
+# endif  /* GCC.  */
+#endif  /* Not __P.  */
+
+#if defined HAVE_STRING_H || defined _LIBC
+# include <string.h>
+#endif
+
+#undef memcmp
+
+#ifdef _LIBC
+
+# include <memcopy.h>
+# include <endian.h>
+
+# if __BYTE_ORDER == __BIG_ENDIAN
+#  define WORDS_BIGENDIAN
+# endif
+
+#else  /* Not in the GNU C library.  */
+
+# include <sys/types.h>
+
+/* Type to use for aligned memory operations.
+   This should normally be the biggest type supported by a single load
+   and store.  Must be an unsigned type.  */
+# define op_t  unsigned long int
+# define OPSIZ (sizeof(op_t))
+
+/* Threshold value for when to enter the unrolled loops.  */
+# define OP_T_THRES    16
+
+/* Type to use for unaligned operations.  */
+typedef unsigned char byte;
+
+# ifndef WORDS_BIGENDIAN
+#  define MERGE(w0, sh_1, w1, sh_2) (((w0) >> (sh_1)) | ((w1) << (sh_2)))
+# else
+#  define MERGE(w0, sh_1, w1, sh_2) (((w0) << (sh_1)) | ((w1) >> (sh_2)))
+# endif
+
+#endif /* In the GNU C library.  */
+
+#ifdef WORDS_BIGENDIAN
+# define CMP_LT_OR_GT(a, b) ((a) > (b) ? 1 : -1)
+#else
+# define CMP_LT_OR_GT(a, b) memcmp_bytes ((a), (b))
+#endif
+
+/* BE VERY CAREFUL IF YOU CHANGE THIS CODE!  */
+
+/* The strategy of this memcmp is:
+
+   1. Compare bytes until one of the block pointers is aligned.
+
+   2. Compare using memcmp_common_alignment or
+      memcmp_not_common_alignment, regarding the alignment of the other
+      block after the initial byte operations.  The maximum number of
+      full words (of type op_t) are compared in this way.
+
+   3. Compare the few remaining bytes.  */
+
+#ifndef WORDS_BIGENDIAN
+/* memcmp_bytes -- Compare A and B bytewise in the byte order of the machine.
+   A and B are known to be different.
+   This is needed only on little-endian machines.  */
+
+static int memcmp_bytes __P((op_t, op_t));
+
+# ifdef  __GNUC__
+__inline
+# endif
+static int
+memcmp_bytes (long unsigned int a, long unsigned int b)
+{
+  long int srcp1 = (long int) &a;
+  long int srcp2 = (long int) &b;
+  op_t a0, b0;
+
+  do
+    {
+      a0 = ((byte *) srcp1)[0];
+      b0 = ((byte *) srcp2)[0];
+      srcp1 += 1;
+      srcp2 += 1;
+    }
+  while (a0 == b0);
+  return a0 - b0;
+}
+#endif
+
+static int memcmp_common_alignment __P((long, long, size_t));
+
+/* memcmp_common_alignment -- Compare blocks at SRCP1 and SRCP2 with LEN `op_t'
+   objects (not LEN bytes!).  Both SRCP1 and SRCP2 should be aligned for
+   memory operations on `op_t's.  */
+#ifdef __GNUC__
+__inline
+#endif
+static int
+memcmp_common_alignment (long int srcp1, long int srcp2, size_t len)
+{
+  op_t a0, a1;
+  op_t b0, b1;
+
+  switch (len % 4)
+    {
+    default: /* Avoid warning about uninitialized local variables.  */
+    case 2:
+      a0 = ((op_t *) srcp1)[0];
+      b0 = ((op_t *) srcp2)[0];
+      srcp1 -= 2 * OPSIZ;
+      srcp2 -= 2 * OPSIZ;
+      len += 2;
+      goto do1;
+    case 3:
+      a1 = ((op_t *) srcp1)[0];
+      b1 = ((op_t *) srcp2)[0];
+      srcp1 -= OPSIZ;
+      srcp2 -= OPSIZ;
+      len += 1;
+      goto do2;
+    case 0:
+      if (OP_T_THRES <= 3 * OPSIZ && len == 0)
+       return 0;
+      a0 = ((op_t *) srcp1)[0];
+      b0 = ((op_t *) srcp2)[0];
+      goto do3;
+    case 1:
+      a1 = ((op_t *) srcp1)[0];
+      b1 = ((op_t *) srcp2)[0];
+      srcp1 += OPSIZ;
+      srcp2 += OPSIZ;
+      len -= 1;
+      if (OP_T_THRES <= 3 * OPSIZ && len == 0)
+       goto do0;
+      /* Fall through.  */
+    }
+
+  do
+    {
+      a0 = ((op_t *) srcp1)[0];
+      b0 = ((op_t *) srcp2)[0];
+      if (a1 != b1)
+       return CMP_LT_OR_GT (a1, b1);
+
+    do3:
+      a1 = ((op_t *) srcp1)[1];
+      b1 = ((op_t *) srcp2)[1];
+      if (a0 != b0)
+       return CMP_LT_OR_GT (a0, b0);
+
+    do2:
+      a0 = ((op_t *) srcp1)[2];
+      b0 = ((op_t *) srcp2)[2];
+      if (a1 != b1)
+       return CMP_LT_OR_GT (a1, b1);
+
+    do1:
+      a1 = ((op_t *) srcp1)[3];
+      b1 = ((op_t *) srcp2)[3];
+      if (a0 != b0)
+       return CMP_LT_OR_GT (a0, b0);
+
+      srcp1 += 4 * OPSIZ;
+      srcp2 += 4 * OPSIZ;
+      len -= 4;
+    }
+  while (len != 0);
+
+  /* This is the right position for do0.  Please don't move
+     it into the loop.  */
+ do0:
+  if (a1 != b1)
+    return CMP_LT_OR_GT (a1, b1);
+  return 0;
+}
+
+static int memcmp_not_common_alignment __P((long, long, size_t));
+
+/* memcmp_not_common_alignment -- Compare blocks at SRCP1 and SRCP2 with LEN
+   `op_t' objects (not LEN bytes!).  SRCP2 should be aligned for memory
+   operations on `op_t', but SRCP1 *should be unaligned*.  */
+#ifdef __GNUC__
+__inline
+#endif
+static int
+memcmp_not_common_alignment (long int srcp1, long int srcp2, size_t len)
+{
+  op_t a0, a1, a2, a3;
+  op_t b0, b1, b2, b3;
+  op_t x;
+  int shl, shr;
+
+  /* Calculate how to shift a word read at the memory operation
+     aligned srcp1 to make it aligned for comparison.  */
+
+  shl = 8 * (srcp1 % OPSIZ);
+  shr = 8 * OPSIZ - shl;
+
+  /* Make SRCP1 aligned by rounding it down to the beginning of the `op_t'
+     it points in the middle of.  */
+  srcp1 &= -OPSIZ;
+
+  switch (len % 4)
+    {
+    default: /* Avoid warning about uninitialized local variables.  */
+    case 2:
+      a1 = ((op_t *) srcp1)[0];
+      a2 = ((op_t *) srcp1)[1];
+      b2 = ((op_t *) srcp2)[0];
+      srcp1 -= 1 * OPSIZ;
+      srcp2 -= 2 * OPSIZ;
+      len += 2;
+      goto do1;
+    case 3:
+      a0 = ((op_t *) srcp1)[0];
+      a1 = ((op_t *) srcp1)[1];
+      b1 = ((op_t *) srcp2)[0];
+      srcp2 -= 1 * OPSIZ;
+      len += 1;
+      goto do2;
+    case 0:
+      if (OP_T_THRES <= 3 * OPSIZ && len == 0)
+       return 0;
+      a3 = ((op_t *) srcp1)[0];
+      a0 = ((op_t *) srcp1)[1];
+      b0 = ((op_t *) srcp2)[0];
+      srcp1 += 1 * OPSIZ;
+      goto do3;
+    case 1:
+      a2 = ((op_t *) srcp1)[0];
+      a3 = ((op_t *) srcp1)[1];
+      b3 = ((op_t *) srcp2)[0];
+      srcp1 += 2 * OPSIZ;
+      srcp2 += 1 * OPSIZ;
+      len -= 1;
+      if (OP_T_THRES <= 3 * OPSIZ && len == 0)
+       goto do0;
+      /* Fall through.  */
+    }
+
+  do
+    {
+      a0 = ((op_t *) srcp1)[0];
+      b0 = ((op_t *) srcp2)[0];
+      x = MERGE(a2, shl, a3, shr);
+      if (x != b3)
+       return CMP_LT_OR_GT (x, b3);
+
+    do3:
+      a1 = ((op_t *) srcp1)[1];
+      b1 = ((op_t *) srcp2)[1];
+      x = MERGE(a3, shl, a0, shr);
+      if (x != b0)
+       return CMP_LT_OR_GT (x, b0);
+
+    do2:
+      a2 = ((op_t *) srcp1)[2];
+      b2 = ((op_t *) srcp2)[2];
+      x = MERGE(a0, shl, a1, shr);
+      if (x != b1)
+       return CMP_LT_OR_GT (x, b1);
+
+    do1:
+      a3 = ((op_t *) srcp1)[3];
+      b3 = ((op_t *) srcp2)[3];
+      x = MERGE(a1, shl, a2, shr);
+      if (x != b2)
+       return CMP_LT_OR_GT (x, b2);
+
+      srcp1 += 4 * OPSIZ;
+      srcp2 += 4 * OPSIZ;
+      len -= 4;
+    }
+  while (len != 0);
+
+  /* This is the right position for do0.  Please don't move
+     it into the loop.  */
+ do0:
+  x = MERGE(a2, shl, a3, shr);
+  if (x != b3)
+    return CMP_LT_OR_GT (x, b3);
+  return 0;
+}
+
+int
+rpl_memcmp (const void *s1, const void *s2, size_t len)
+{
+  op_t a0;
+  op_t b0;
+  long int srcp1 = (long int) s1;
+  long int srcp2 = (long int) s2;
+  op_t res;
+
+  if (len >= OP_T_THRES)
+    {
+      /* There are at least some bytes to compare.  No need to test
+        for LEN == 0 in this alignment loop.  */
+      while (srcp2 % OPSIZ != 0)
+       {
+         a0 = ((byte *) srcp1)[0];
+         b0 = ((byte *) srcp2)[0];
+         srcp1 += 1;
+         srcp2 += 1;
+         res = a0 - b0;
+         if (res != 0)
+           return res;
+         len -= 1;
+       }
+
+      /* SRCP2 is now aligned for memory operations on `op_t'.
+        SRCP1 alignment determines if we can do a simple,
+        aligned compare or need to shuffle bits.  */
+
+      if (srcp1 % OPSIZ == 0)
+       res = memcmp_common_alignment (srcp1, srcp2, len / OPSIZ);
+      else
+       res = memcmp_not_common_alignment (srcp1, srcp2, len / OPSIZ);
+      if (res != 0)
+       return res;
+
+      /* Number of bytes remaining in the interval [0..OPSIZ-1].  */
+      srcp1 += len & -OPSIZ;
+      srcp2 += len & -OPSIZ;
+      len %= OPSIZ;
+    }
+
+  /* There are just a few bytes to compare.  Use byte memory operations.  */
+  while (len != 0)
+    {
+      a0 = ((byte *) srcp1)[0];
+      b0 = ((byte *) srcp2)[0];
+      srcp1 += 1;
+      srcp2 += 1;
+      res = a0 - b0;
+      if (res != 0)
+       return res;
+      len -= 1;
+    }
+
+  return 0;
+}
+
+#ifdef weak_alias
+# undef bcmp
+weak_alias (memcmp, bcmp)
+#endif
Index: lib/strcasecmp.c
===================================================================
RCS file: lib/strcasecmp.c
diff -N lib/strcasecmp.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ lib/strcasecmp.c 27 Sep 2002 13:02:05 -0000
@@ -0,0 +1,66 @@
+/* strcasecmp.c -- case insensitive string comparator
+   Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef LENGTH_LIMIT
+# define STRXCASECMP_FUNCTION strncasecmp
+# define STRXCASECMP_DECLARE_N , size_t n
+# define LENGTH_LIMIT_EXPR(Expr) Expr
+#else
+# define STRXCASECMP_FUNCTION strcasecmp
+# define STRXCASECMP_DECLARE_N /* empty */
+# define LENGTH_LIMIT_EXPR(Expr) 0
+#endif
+
+#include <sys/types.h>
+#include <ctype.h>
+
+#define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch))
+
+/* Compare {{no more than N characters of }}strings S1 and S2,
+   ignoring case, returning less than, equal to or
+   greater than zero if S1 is lexicographically less
+   than, equal to or greater than S2.  */
+
+int
+STRXCASECMP_FUNCTION (const char *s1, const char *s2 STRXCASECMP_DECLARE_N)
+{
+  register const unsigned char *p1 = (const unsigned char *) s1;
+  register const unsigned char *p2 = (const unsigned char *) s2;
+  unsigned char c1, c2;
+
+  if (p1 == p2 || LENGTH_LIMIT_EXPR (n == 0))
+    return 0;
+
+  do
+    {
+      c1 = TOLOWER (*p1);
+      c2 = TOLOWER (*p2);
+
+      if (LENGTH_LIMIT_EXPR (--n == 0) || c1 == '\0')
+       break;
+
+      ++p1;
+      ++p2;
+    }
+  while (c1 == c2);
+
+  return c1 - c2;
+}
Index: lib/strncasecmp.c
===================================================================
RCS file: lib/strncasecmp.c
diff -N lib/strncasecmp.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ lib/strncasecmp.c 27 Sep 2002 13:02:05 -0000
@@ -0,0 +1,2 @@
+#define LENGTH_LIMIT
+#include "strcasecmp.c"
Index: m4/prereq.m4
===================================================================
RCS file: /cvsroot/bison/bison/m4/prereq.m4,v
retrieving revision 1.6
diff -u -u -r1.6 prereq.m4
--- m4/prereq.m4 13 Sep 2002 16:12:21 -0000 1.6
+++ m4/prereq.m4 27 Sep 2002 13:02:05 -0000
@@ -1,10 +1,10 @@
-#serial 27
+#serial 28                                                         -*- 
Autoconf -*-
 
 dnl We use jm_ for non Autoconf macros.
 m4_pattern_forbid([^jm_[ABCDEFGHIJKLMNOPQRSTUVXYZ]])dnl
 
 # These are the prerequisite macros for files in the lib/
-# directories of the coreutils package.
+# directories of the fileutils, sh-utils, and textutils packages.
 
 AC_DEFUN([jm_PREREQ],
 [
@@ -30,6 +30,20 @@
   jm_PREREQ_TEMPNAME # called by mkstemp
   jm_PREREQ_XGETCWD
   jm_PREREQ_XREADLINK
+])
+
+AC_DEFUN([jm_PREREQ_ARGMATCH],
+[
+  AC_REQUIRE([jm_PREREQ_QUOTEARG])
+  AC_REPLACE_FUNCS(strcasecmp strncasecmp)
+])
+
+# Ask for argmatch.[ch], and set it up.
+AC_DEFUN([jm_FUNC_ARGMATCH],
+[
+  AC_REQUIRE([jm_PREREQ_ARGMATCH])
+  AC_LIBOBJ([argmatch])
+  AC_LIBSOURCES([argmatch.c, argmatch.h])
 ])
 
 AC_DEFUN([jm_PREREQ_ADDEXT],




reply via email to

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