Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 19 Sep 2009 22:54:38 GMT
From:      Gabor Kovesdan <gabor@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 168696 for review
Message-ID:  <200909192254.n8JMscBw043727@repoman.freebsd.org>

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

Change 168696 by gabor@gabor_aspire on 2009/09/19 22:53:58

	- More readable code by simplifications concerning fflag and rflag
	- Some changes to -g and -n

Affected files ...

.. //depot/projects/soc2008/gabor_textproc/newsort/coll.c#4 edit

Differences ...

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

@@ -36,6 +36,7 @@
 
 static wchar_t		**months;
 
+static inline int	 _wcscoll(const wchar_t *, const wchar_t *);
 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 *);
@@ -151,16 +152,26 @@
 	ps1 = preproc(s1);
 	ps2 = preproc(s2);
 
+	if (rflag) {
+		wchar_t	*tmp = ps1;
+
+		ps1 = ps2;
+		ps2 = tmp;
+	}
 	if (nflag)
-		return (rflag ? numcoll(ps2, ps1) : numcoll(ps1, ps2));
+		return (numcoll(ps1, ps2));
 	else if (gflag)
-		return (rflag ? gnumcoll(ps2, ps1) : gnumcoll(ps1, ps2));
+		return (gnumcoll(ps1, ps2));
 	else if (Mflag)
-		return (rflag ? monthcoll(ps2, ps1) : monthcoll(ps1, ps2));
+		return (monthcoll(ps1, ps2));
 	else
-		return (fflag ?
-		    (rflag ? wcscasecoll(ps2, ps1) : wcscasecoll(ps1, ps2)) :
-		    (rflag ? wcscoll(ps2, ps1) : wcscoll(ps1, ps2)));
+		return (_wcscoll(s1, s2));
+}
+
+static inline int
+_wcscoll(const wchar_t *s1, const wchar_t *s2) {
+
+	return (fflag ? wcscasecoll(s1, s2) : wcscoll(s1, s2));
 }
 
 /*
@@ -187,32 +198,47 @@
 	return (wcscoll(ss1, ss2));
 }
 
+#define NUMCHECK_COMMON(a, b) \
+	double	 d1, d2; \
+	errno = 0; \
+	d1 = wcstod(#a, &ep1); \
+\
+	if ((errno == ERANGE) && (d1 == HUGE_VAL)) \
+		return (1); \
+\
+	d2 = wcstod(#b, &ep2); \
+\
+	if ((errno == ERANGE) && (d2 == HUGE_VAL)) \
+		return (-1);
+
 /*
  * Implements numeric sort (-n).
  */
 static int
 numcoll(const wchar_t *s1, const wchar_t *s2) {
-	int		n1 = 0, n2 = 0;
+	int		 n1, n2;
+	wchar_t		*ns1, *ns2, *ep1 = NULL, *ep2 = NULL;
+
+	if (s1[0] == L'-')
+		s1++;
+
+	if (s2[0] == L'-')
+		s2++;
+
+	n1 = wcsspn(s1, L".0123456789");
+	n2 = wcsspn(s2, L".0123456789");
+
+	ns1 = sort_malloc((n1 + 1) * sizeof(wint_t));
+	ns2 = sort_malloc((n2 + 1) * sizeof(wint_t));
 
-	while (iswdigit(s1[n1]))
-		n1++;
+	wcslcpy(ns1, s1, n1);
+	wcslcpy(ns2, s2, n2);
 
-	while (iswdigit(s2[n2]))
-		n2++;
+	NUMCHECK_COMMON(ns1, ns2);
 
-	if (n1 > n2)
-		return (n2 = 0 ? -1 : 1);
-	else if (n2 > n1)
-		return (n1 = 0 ? 1 : -1);
-	else if ((n1 == 0) && (n2 == 0)) {
-		if (fflag)
-			return (wcscasecoll(&s1[n1], &s2[n2]));
-		else
-			return (wcscoll(&s1[n1], &s2[n2]));
-	} else {
-		/* TODO */
-		return (0);
-	}
+	if (d1 == d2)
+		return (_wcscoll(ep1, ep2));
+	return (d1 > d2 ? 1 : -1);
 }
 
 /*
@@ -220,12 +246,11 @@
  */
 static int
 gnumcoll(const wchar_t *s1, const wchar_t *s2) {
-	double		 d1, d2;
 	wchar_t		*ep1 = NULL, *ep2 = NULL;
 
+	/* XXX: what if - (minus sign) comes first? */
 	if (iswalpha(s1[0]) && iswalpha(s2[0]))
-		return (fflag ? wcscasecoll(s1, s2) :
-		    wcscoll(s1, s2));
+		return (_wcscoll(s1, s2));
 
 	if (!iswnumber(s1[0]) && !iswnumber(s2[0]))
 		return (0);
@@ -234,18 +259,10 @@
 	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);
+	NUMCHECK_COMMON(s1, s2);
 
 	if (d1 == d2)
-		return (fflag ? wcscasecoll(ep1, ep2) :
-		    wcscoll(ep1, ep2));
+		return (_wcscoll(ep1, ep2));
 	else if ((d1 == NAN) && (d2 != NAN))
 		return (-1);
 	else if ((d1 != NAN) && (d2 == NAN))
@@ -315,10 +332,7 @@
 
 	if ((val = month_score(s1)) == month_score(s2)) {
 		val = (val < 0) ? 0 : wcslen(months[val]);
-		if (fflag)
-			return (wcscasecoll(&s1[val], &s2[val]));
-		else
-			return (wcscoll(&s1[val], &s2[val]));
+		return (_wcscoll(&s1[val], &s2[val]));
 	} else {
 		return (month_score(s1) > month_score(s2) ? 1 : -1);
 	}



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