Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 25 Mar 2009 03:23:29 GMT
From:      Gabor Kovesdan <gabor@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 159779 for review
Message-ID:  <200903250323.n2P3NTcm052531@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=159779

Change 159779 by gabor@gabor_server on 2009/03/25 03:22:42

	- Implement general-numeric-sort properly
	- numeric-sort is there but not ready
	- -g/-n/-M should reset each other
	- fix wcscasecoll()
	- style(9)

Affected files ...

.. //depot/projects/soc2008/gabor_textproc/newsort/coll.c#3 edit
.. //depot/projects/soc2008/gabor_textproc/newsort/sort.c#3 edit
.. //depot/projects/soc2008/gabor_textproc/newsort/sort.h#2 edit

Differences ...

==== //depot/projects/soc2008/gabor_textproc/newsort/coll.c#3 (text+ko) ====

@@ -24,7 +24,9 @@
  * SUCH DAMAGE.
  */
 
+#include <errno.h>
 #include <langinfo.h>
+#include <math.h>
 #include <stdlib.h>
 #include <string.h>
 #include <wchar.h>
@@ -34,6 +36,7 @@
 
 static wchar_t		**months;
 
+static int		 gnumcoll(const wchar_t *, const wchar_t *);
 static int		 monthcoll(const wchar_t *, const wchar_t *);
 static int		 numcoll(const wchar_t *, const wchar_t *);
 static int		 wcscasecoll(const wchar_t *, const wchar_t *);
@@ -148,14 +151,16 @@
 	ps1 = preproc(s1);
 	ps2 = preproc(s2);
 
-	if (gflag)
+	if (nflag)
 		return (rflag ? numcoll(ps2, ps1) : numcoll(ps1, ps2));
+	else if (gflag)
+		return (rflag ? gnumcoll(ps2, ps1) : gnumcoll(ps1, ps2));
 	else if (Mflag)
 		return (rflag ? monthcoll(ps2, ps1) : monthcoll(ps1, ps2));
 	else
 		return (fflag ?
-			(rflag ? wcscasecoll(ps2, ps1) : wcscasecoll(ps1, ps2)) :
-			(rflag ? wcscoll(ps2, ps1) : wcscoll(ps1, ps2)));
+		    (rflag ? wcscasecoll(ps2, ps1) : wcscasecoll(ps1, ps2)) :
+		    (rflag ? wcscoll(ps2, ps1) : wcscoll(ps1, ps2)));
 }
 
 /*
@@ -163,28 +168,27 @@
  */
 static int
 wcscasecoll(const wchar_t *s1, const wchar_t *s2) {
-	int		 len1, len2;
+	int		 len1, len2, i;
+	wchar_t		*ss1, *ss2;
 
 	len1 = wcslen(s1);
 	len2 = wcslen(s2);
 
-	for (int i = 0;; i++) {
-		if (s1[i] == s2[i])
-			continue;
-		else if (s1[i] == L'\0')
-			return (1);
-		else if (s2[i] == L'\0')
-			return (-1);
-		else if (towlower(s1[i]) == towlower(s2[i]))
-			return (iswupper(s1[i]) ? 1 : -1);
-		else
-			return (wcscoll(&s1[i], &s2[i]));
-	}
-	return (len2 - len1);
+	ss1 = sort_malloc(sizeof(wint_t) * (len1 + 1));
+	ss2 = sort_malloc(sizeof(wint_t) * (len2 + 1));
+
+	for (i = 0; i < len1; i++)
+		ss1[i]= towlower(s1[i]);
+	ss1[i + 1] = L'\0';
+	for (i = 0; i < len2; i++)
+		ss2[i]= towlower(s2[i]);
+	ss2[i + 1] = L'\0';
+
+	return (wcscoll(ss1, ss2));
 }
 
 /*
- * Implements general numeric sort (-g).
+ * Implements numeric sort (-n).
  */
 static int
 numcoll(const wchar_t *s1, const wchar_t *s2) {
@@ -212,6 +216,45 @@
 }
 
 /*
+ * Implements general numeric sort (-g).
+ */
+static int
+gnumcoll(const wchar_t *s1, const wchar_t *s2) {
+	double		 d1, d2;
+	wchar_t		*ep1 = NULL, *ep2 = NULL;
+
+	if (iswalpha(s1[0]) && iswalpha(s2[0]))
+		return (fflag ? wcscasecoll(s1, s2) :
+		    wcscoll(s1, s2));
+
+	if (!iswnumber(s1[0]) && !iswnumber(s2[0]))
+		return (0);
+	else if (!iswnumber(s1[0]) && iswnumber(s2[0]))
+		return (-1);
+	else if (iswnumber(s1[0]) && !iswnumber(s2[0]))
+		return (1);
+
+	d1 = wcstod(s1, &ep1);
+	d2 = wcstod(s2, &ep2);
+
+	if ((errno == ERANGE) && (d1 == HUGE_VAL))
+		return (1);
+
+	if ((errno == ERANGE) && (d2 == HUGE_VAL))
+		return (-1);
+
+	if (d1 == d2)
+		return (fflag ? wcscasecoll(ep1, ep2) :
+		    wcscoll(ep1, ep2));
+	else if ((d1 == NAN) && (d2 != NAN))
+		return (-1);
+	else if ((d1 != NAN) && (d2 == NAN))
+		return (1);
+
+	return (d1 > d2 ? 1 : -1);
+}
+
+/*
  * A helper function for monthcoll.  If a line matches
  * a month name, it returns (number of the month - 1),
  * while if there is no match, it just return -1.

==== //depot/projects/soc2008/gabor_textproc/newsort/sort.c#3 (text+ko) ====

@@ -75,12 +75,13 @@
 bool		 iflag;
 bool		 kflag;
 bool		 Mflag;
+bool		 nflag;
 bool		 mflag;
 bool		 rflag;
 bool		 uflag;
 bool		 zflag;
 
-#define	OPTIONS	"cbdfghik:Mmo:rS:t:T:uVz"
+#define	OPTIONS	"cbdfghik:Mmno:rS:t:T:uVz"
 
 struct option long_options[]=
 {
@@ -93,6 +94,7 @@
 	{"ignore-nonprinting",		no_argument,		NULL,	'i'},
 	{"key",				required_argument,	NULL,	'k'},
 	{"month-sort",			no_argument,		NULL,	'M'},
+	{"numeric-sort",		no_argument,		NULL,	'n'},
 	{"merge",			no_argument,		NULL,	'm'},
 	{"output",			required_argument,	NULL,	'o'},
 	{"reverse",			no_argument,		NULL,	'r'},
@@ -136,7 +138,8 @@
 			fflag = true;
 			break;
 		case 'g':
-			gflag = true;
+			Mflag = nflag = false;
+			bflag = gflag = true;
 			break;
 		case 'i':
 			iflag = true;
@@ -177,11 +180,16 @@
 			}
 			break;
 		case 'M':
+			gflag = nflag = false;
 			Mflag = true;
 			break;
 		case 'm':
 			mflag = true;
 			break;
+		case 'n':
+			gflag = Mflag = false;
+			bflag = nflag = true;
+			break;
 		case 'o':
 			outfile = sort_malloc(sizeof(char) * (strlen(optarg) + 1));
 			strlcpy(outfile, optarg, (strlen(optarg) + 1));

==== //depot/projects/soc2008/gabor_textproc/newsort/sort.h#2 (text+ko) ====

@@ -49,7 +49,7 @@
  * sort.c
  */
 extern bool	cflag, bflag, dflag, fflag, gflag, iflag, kflag, Mflag, mflag,
-		rflag, uflag, zflag;
+		nflag, rflag, uflag, zflag;
 extern int	 bufcnt, count, listlen, tempno;
 extern wchar_t	 field_sep, **list;
 extern char	**tempfiles, *tmpdir;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200903250323.n2P3NTcm052531>