Репозиторий Sisyphus
Последнее обновление: 1 октября 2023 | Пакетов: 18631 | Посещений: 37833304
en ru br
Репозитории ALT
S:1.60-alt19
5.1: 1.60-alt15
4.1: 1.60-alt13
4.0: 1.60-alt13
3.0: 1.60-alt12
www.altlinux.org/Changes

Группа :: Система/Настройка/Сеть
Пакет: net-tools

 Главная   Изменения   Спек   Патчи   Sources   Загрузить   Gear   Bugs and FR  Repocop 

Патч: net-tools-1.60-alt-nstrcmp.patch
Скачать


--- net-tools-1.60/lib/nstrcmp.c~	1999-01-09 18:55:20 +0300
+++ net-tools-1.60/lib/nstrcmp.c	2002-07-03 01:35:04 +0400
@@ -1,34 +1,157 @@
-/* Copyright 1998 by Andi Kleen. Subject to the GPL. */
-/* $Id: nstrcmp.c,v 1.2 1998/11/15 20:11:38 freitag Exp $ */ 
+/* 
+  compare alpha and numeric segments of two strings.
+
+  Copyright (c) 1998 by Red Hat Software, Inc.
+  Copyright (c) 2002 by Dmitry V. Levin <ldv@altlinux.org>
+
+  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 of the License, 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
+*/
+#include <string.h>
 #include <ctype.h>
 #include <stdlib.h>
-#include "util.h"
 
-/* like strcmp(), but knows about numbers */
-int nstrcmp(const char *astr, const char *b)
+/*
+ * compares alpha and numeric segments of two strings.
+ * returns an integer less than, equal to, or greater
+ * than zero if a is found, respectively, to be less
+ * than, to match, or be greater than b.
+*/
+int
+nstrcmp (const char *a, const char *b)
 {
-    const char *a = astr;
+	char   *str1, *str2;
+	char   *one, *two;
 
-    while (*a == *b) {
-	if (*a == '\0')
-	    return 0;
-	a++;
-	b++;
-    }
-    if (isdigit(*a)) {
-	if (!isdigit(*b))
-	    return -1;
-	while (a > astr) {
-	    a--;
-	    if (!isdigit(*a)) {
-		a++;
-		break;
-	    }
-	    if (!isdigit(*b))
-		return -1;
-	    b--;
+	/* easy comparison to see if versions are identical */
+	if (!strcmp (a, b))
+		return 0;
+
+	str1 = alloca (strlen (a) + 1);
+	str2 = alloca (strlen (b) + 1);
+
+	strcpy (str1, a);
+	strcpy (str2, b);
+
+	one = str1;
+	two = str2;
+
+	/* loop through each version segment of str1 and str2 and compare them */
+	while (*one && *two)
+	{
+		int     isalnum1 = isalnum (*one);
+		int     isalnum2 = isalnum (*two);
+		int     isnum, rc;
+		char    oldch1, oldch2;
+
+		if (*one == *two)
+		{
+			if (!isalnum1)
+			{
+				++one;
+				++two;
+				continue;
+			}
+		} else
+		{
+			if (!(isalnum1 && isalnum2))
+				return *one - *two;
+		}
+
+		str1 = one;
+		str2 = two;
+
+		/* grab first completely alpha or completely numeric segment */
+		/* leave one and two pointing to the start of the alpha or numeric */
+		/* segment and walk str1 and str2 to end of segment */
+		/* Also take care of the case where the two version segments are */
+		/* different types: one numeric and one alpha */
+		if (isdigit (*str1))
+		{
+			if (isalpha (*str2))
+				return -1;
+			while (*str1 && isdigit (*str1))
+				str1++;
+			while (*str2 && isdigit (*str2))
+				str2++;
+			isnum = 1;
+		} else
+		{
+			while (*str1 && isalpha (*str1))
+				str1++;
+			while (*str2 && isalpha (*str2))
+				str2++;
+			isnum = 0;
+		}
+
+		/* Again, take care of the case where the two version segments are */
+		/* different types: one numeric and one alpha */
+		if (one == str1)
+			return -1;
+		if (two == str2)
+			return 1;
+
+		/* save character at the end of the alpha or numeric segment */
+		/* so that they can be restored after the comparison */
+		oldch1 = *str1;
+		*str1 = '\0';
+		oldch2 = *str2;
+		*str2 = '\0';
+
+		if (isnum)
+		{
+			/* this used to be done by converting the digit segments */
+			/* to ints using atoi() - it's changed because long  */
+			/* digit segments can overflow an int - this should fix that. */
+
+			/* throw away any leading zeros - it's a number, right? */
+			while (*one == '0')
+				one++;
+			while (*two == '0')
+				two++;
+
+			/* whichever number has more digits wins */
+			if (strlen (one) > strlen (two))
+				return 1;
+			if (strlen (two) > strlen (one))
+				return -1;
+		}
+
+		/* strcmp will return which one is greater - even if the two */
+		/* segments are alpha or if they are numeric.  don't return  */
+		/* if they are equal because there might be more segments to */
+		/* compare */
+		rc = strcmp (one, two);
+		if (rc)
+			return rc;
+
+		/* restore character that was replaced by null above */
+		*str1 = oldch1;
+		one = str1;
+		*str2 = oldch2;
+		two = str2;
 	}
-	return atoi(a) > atoi(b) ? 1 : -1;
-    }
-    return *a - *b;
+
+	/* this catches the case where all numeric and alpha segments have */
+	/* compared identically but the segment sepparating characters were */
+	/* different */
+	if (!*one && !*two)
+		return 0;
+
+	/* whichever version still has characters left over wins */
+	if (!*one)
+		return -1;
+	else
+		return 1;
 }
 
дизайн и разработка: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
текущий майнтейнер: Michael Shigorin