]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
[TOLOWER]: Define.
authorJim Meyering <jim@meyering.net>
Sun, 18 Feb 1996 18:08:01 +0000 (18:08 +0000)
committerJim Meyering <jim@meyering.net>
Sun, 18 Feb 1996 18:08:01 +0000 (18:08 +0000)
(usage): Briefly describe new --ignore-case (-i) option.
(memcasecmp): New function.
(main): Set IGNORE_CASE for -i.
(keycmp): Compare with memcasecmp if IGNORE_CASE is set.
Suggestion and an initial patch from Alberto Accomazzi
<alberto@cfa0.harvard.edu>.

src/join.c

index 8e00a7a5d3b3823d973c5095c9d5f05e21cc367d..16446eb583119bcf4f82210a022812249873b17b 100644 (file)
@@ -54,6 +54,12 @@ char *alloca ();
 # define INT_MAX ((int) (UINT_MAX >> 1))
 #endif
 
+#if _LIBC || STDC_HEADERS
+# define TOLOWER(c) tolower (c)
+#else
+# define TOLOWER(c) (ISUPPER (c) ? tolower (c) : (c))
+#endif
+
 #include "system.h"
 #include "version.h"
 #include "long-options.h"
@@ -141,6 +147,7 @@ static char tab;
    a character that is a short option.  */
 static struct option const longopts[] =
 {
+  {"ignore-case", no_argument, NULL, 'i'},
   {"j", required_argument, NULL, 'j'},
   {"j1", required_argument, NULL, '1'},
   {"j2", required_argument, NULL, '2'},
@@ -150,6 +157,9 @@ static struct option const longopts[] =
 /* Used to print non-joining lines */
 static struct line uni_blank;
 
+/* If nonzero, ignore case when comparing join fields.  */
+static int ignore_case;
+
 static void
 usage (int status)
 {
@@ -169,6 +179,7 @@ by whitespace.  When FILE1 or FILE2 (not both) is -, read standard input.\n\
 \n\
   -a SIDE          print unpairable lines coming from file SIDE\n\
   -e EMPTY         replace missing input fields with EMPTY\n\
+  -i, --ignore-case ignore differences in case when comparing fields\n\
   -j FIELD         (Obsolescent) equivalent to `-1 FIELD -2 FIELD'\n\
   -j1 FIELD        (Obsolescent) equivalent to `-1 FIELD'\n\
   -j2 FIELD        (Obsolescent) equivalent to `-2 FIELD'\n\
@@ -191,6 +202,24 @@ separated by CHAR.\n\
   exit (status);
 }
 
+/* Like memcmp, but ignore differences in case.  */
+
+static int
+memcasecmp (const void *vs1, const void *vs2, size_t n)
+{
+  int i;
+  unsigned char *s1 = (unsigned char *) vs1;
+  unsigned char *s2 = (unsigned char *) vs2;
+  for (i = 0; i < n; i++)
+    {
+      unsigned char u1 = *s1++;
+      unsigned char u2 = *s2++;
+      if (TOLOWER (u1) != TOLOWER (u2))
+        return TOLOWER (u1) - TOLOWER (u2);
+    }
+  return 0;
+}
+
 static void
 ADD_FIELD (struct line *line, const char *field, size_t len)
 {
@@ -373,7 +402,15 @@ keycmp (struct line *line1, struct line *line2)
     return len2 == 0 ? 0 : -1;
   if (len2 == 0)
     return 1;
-  diff = memcmp (beg1, beg2, min (len1, len2));
+
+  /* Use an if-statement here rather than a function variable to
+     avoid portability hassles of getting a non-conflicting declaration
+     of memcmp.  */
+  if (ignore_case)
+    diff = memcasecmp (beg1, beg2, min (len1, len2));
+  else
+    diff = memcmp (beg1, beg2, min (len1, len2));
+
   if (diff)
     return diff;
   return len1 - len2;
@@ -740,7 +777,7 @@ main (int argc, char **argv)
   nfiles = 0;
   print_pairables = 1;
 
-  while ((optc = getopt_long_only (argc, argv, "-a:e:1:2:o:t:v:", longopts,
+  while ((optc = getopt_long_only (argc, argv, "-a:e:i1:2:o:t:v:", longopts,
                                   (int *) 0)) != EOF)
     {
       long int val;
@@ -768,6 +805,10 @@ main (int argc, char **argv)
          empty_filler = optarg;
          break;
 
+       case 'i':
+         ignore_case = 1;
+         break;
+
        case '1':
          if (xstrtol (optarg, NULL, 10, &val, NULL) != LONGINT_OK
              || val <= 0 || val > INT_MAX)