--- textutils-2.0/lib/Makefile.am	Sun Jul  4 06:16:53 1999
+++ textutils/lib/Makefile.am	Wed Mar  8 18:44:08 2000
@@ -10,7 +10,8 @@
   getopt1.c hard-locale.c human.c \
   linebuffer.c long-options.c md5.c memcasecmp.c memcoll.c \
   obstack.c quotearg.c readtokens.c safe-read.c \
-  version-etc.c xmalloc.c xstrdup.c xstrtod.c xstrtol.c xstrtoul.c xstrtoumax.c
+  version-etc.c xmalloc.c xstrdup.c xstrtod.c xstrtol.c xstrtoul.c xstrtoumax.c \
+  strnatcmp.c
 
 libtu_a_LIBADD = @LIBOBJS@ @ALLOCA@
 libtu_a_DEPENDENCIES = $(libtu_a_LIBADD)
@@ -21,7 +22,8 @@
   lchown.h linebuffer.h long-options.h md5.h \
   memcasecmp.h memcoll.h obstack.h quotearg.h \
   readtokens.h regex.h safe-read.h \
-  version-etc.h xalloc.h xstrtod.h xstrtol.h
+  version-etc.h xalloc.h xstrtod.h xstrtol.h \
+  strnatcmp.h
 
 BUILT_SOURCES = lstat.c stat.c
 
--- textutils-2.0/src/sort.c	Thu Aug  5 03:42:49 1999
+++ textutils/src/sort.c	Fri Mar 10 15:00:35 2000
@@ -1,5 +1,5 @@
 /* sort - sort lines of text (with all kinds of options).
-   Copyright (C) 88, 1991-1999 Free Software Foundation, Inc.
+   Copyright (C) 1988, 1991-2000 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
@@ -19,7 +19,9 @@
    The author may be reached (Email) at the address mike@gnu.ai.mit.edu,
    or (US mail) as Mike Haertel c/o Free Software Foundation.
 
-   Ørn E. Hansen added NLS support in 1997.  */
+   Ørn E. Hansen added NLS support in 1997.
+
+   Martin Pool <mbp@humbug.org.au> added natural order sorting in 2000. */
 
 #include <config.h>
 
@@ -33,17 +35,18 @@
 #include "hard-locale.h"
 #include "memcoll.h"
 #include "xalloc.h"
+#include "strnatcmp.h"
 
 /* The official name of this program (e.g., no `g' prefix).  */
 #define PROGRAM_NAME "sort"
 
 #define AUTHORS "Mike Haertel"
 
-#if defined ENABLE_NLS && HAVE_LANGINFO_H
+#if defined(ENABLE_NLS) && HAVE_LANGINFO_H
 # include <langinfo.h>
 #endif
 
-#if HAVE_PATHCONF && defined _PC_NAME_MAX
+#if HAVE_PATHCONF && defined(_PC_NAME_MAX)
 # define NAME_MAX_IN_DIR(Dir) pathconf (Dir, _PC_NAME_MAX)
 #else
 # define NAME_MAX_IN_DIR(Dir) 255
@@ -150,6 +153,8 @@
 				   Handle numbers in exponential notation. */
   int month;			/* Flag for comparison by month name. */
   int reverse;			/* Reverse the sense of comparison. */
+  int natural;			/* Natural sort that handles strings
+				   containing integer substrings. */
   struct keyfield *next;	/* Next keyfield to try. */
 };
 
@@ -177,7 +182,7 @@
 
 #define MONTHS_PER_YEAR 12
 
-#if defined ENABLE_NLS && HAVE_NL_LANGINFO
+#if defined(ENABLE_NLS) && HAVE_NL_LANGINFO
 # define MONTHTAB_CONST /* empty */
 #else
 # define MONTHTAB_CONST const
@@ -274,6 +279,7 @@
   -m               merge already sorted files, do not sort\n\
   -M               compare (unknown) < `JAN' < ... < `DEC', imply -b\n\
   -n               compare according to string numerical value, imply -b\n\
+  -N               natural sort order for numbers in strings\n\
   -o FILE          write result on FILE instead of standard output\n\
   -r               reverse the result of comparisons\n\
   -s               stabilize sort by disabling last resort comparison\n\
@@ -290,8 +296,8 @@
       printf (_("\
 POS is F[.C][OPTS], where F is the field number and C the character position\n\
 in the field, both counted from one with -k, from zero with the obsolescent\n\
-form.  OPTS is made up of one or more of Mbdfinr; this effectively disables\n\
-global -Mbdfinr settings for that key.  If no key is given, use the entire\n\
+form.  OPTS is made up of one or more of MbdfinrN; this effectively disables\n\
+global -MbdfinrN settings for that key.  If no key is given, use the entire\n\
 line as the key.  With no FILE, or when FILE is -, read standard input.\n\
 ")
 	      );
@@ -497,7 +503,7 @@
 	fold_toupper[i] = i;
     }
 
-#if defined ENABLE_NLS && HAVE_NL_LANGINFO
+#if defined(ENABLE_NLS) && HAVE_NL_LANGINFO
   /* If we're not in the "C" locale, read different names for months.  */
   if (hard_LC_TIME)
     {
@@ -1039,6 +1045,44 @@
 	  : memcmp ((char *) &a, (char *) &b, sizeof a));
 }
 
+
+static int
+natural_compare (const char *texta, int lena, const char *textb, int lenb,
+		 int const *ignore, char const *translate)
+{
+  if (ignore || translate)
+    {
+      char *copy_a = (char *) alloca (lena + 1);
+      char *copy_b = (char *) alloca (lenb + 1);
+      int new_len_a, new_len_b, i;
+
+      /* Ignore and/or translate chars before comparing.  */
+      for (new_len_a = new_len_b = i = 0; i < max (lena, lenb); i++)
+	{
+	  if (i < lena)
+	    {
+	      copy_a[new_len_a] = (translate
+				   ? translate[UCHAR (texta[i])]
+				   : texta[i]);
+	      if (!ignore || !ignore[UCHAR (texta[i])])
+		++new_len_a;
+	    }
+	  if (i < lenb)
+	    {
+	      copy_b[new_len_b] = (translate
+				   ? translate[UCHAR (textb[i])]
+				   : textb [i]);
+	      if (!ignore || !ignore[UCHAR (textb[i])])
+		++new_len_b;
+	    }
+	}
+
+      return memcoll (copy_a, new_len_a, copy_b, new_len_b);
+    }
+  else
+    return strnatcmp (texta, textb);
+}
+
 /* Return an integer in 1..12 of the month name S with length LEN.
    Return 0 if the name in S is not recognized.  */
 
@@ -1178,6 +1222,16 @@
 	    return key->reverse ? -diff : diff;
 	  continue;
 	}
+      else if (key->natural)
+	{
+	  diff = natural_compare (texta, lena, textb, lenb, ignore, translate);
+	  if (diff)
+	    return key->reverse ? -diff : diff;
+
+	  /* if this didn't match, then we continue on to try other
+             fields. */
+	  continue;
+	}
 #ifdef ENABLE_NLS
 
       /* Sorting like this may become slow, so in a simple locale the user
@@ -1872,6 +1926,9 @@
 	case 'n':
 	  key->numeric = 1;
 	  break;
+	case 'N':
+	  key->natural = 1;
+	  break;
 	case 'r':
 	  key->reverse = 1;
 	  break;
@@ -1981,6 +2038,7 @@
   gkey.ignore = NULL;
   gkey.translate = NULL;
   gkey.numeric = gkey.general_numeric = gkey.month = gkey.reverse = 0;
+  gkey.natural = 0;
   gkey.skipsblanks = gkey.skipeblanks = 0;
 
   files = (char **) xmalloc (sizeof (char *) * argc);
@@ -2239,7 +2297,7 @@
   /* Inheritance of global options to individual keys. */
   for (key = keyhead.next; key; key = key->next)
     if (!key->ignore && !key->translate && !key->skipsblanks && !key->reverse
-	&& !key->skipeblanks && !key->month && !key->numeric
+	&& !key->skipeblanks && !key->month && !key->numeric && !key->natural
         && !key->general_numeric)
       {
 	key->ignore = gkey.ignore;
@@ -2250,11 +2308,12 @@
 	key->numeric = gkey.numeric;
 	key->general_numeric = gkey.general_numeric;
 	key->reverse = gkey.reverse;
+	key->natural = gkey.natural;
       }
 
   if (!keyhead.next && (gkey.ignore || gkey.translate || gkey.skipsblanks
 			|| gkey.skipeblanks || gkey.month || gkey.numeric
-                        || gkey.general_numeric))
+                        || gkey.natural || gkey.general_numeric))
     insertkey (&gkey);
   reverse = gkey.reverse;
 
