Add strnatcmp by Martin Pool for 'natural order' string comparisons, and make use...
authorChris Maynard <Christopher.Maynard@GTECH.COM>
Wed, 10 Jul 2013 16:18:37 +0000 (16:18 -0000)
committerChris Maynard <Christopher.Maynard@GTECH.COM>
Wed, 10 Jul 2013 16:18:37 +0000 (16:18 -0000)
Before:
    user0 - USER 0
    user1 - USER 1
    user10 - USER 10
    user11 - USER 11
    user12 - USER 12
    user13 - USER 13
    user14 - USER 14
    user15 - USER 15
    user2 - USER 2
    user3 - USER 3
    user4 - USER 4
    user5 - USER 5
    user6 - USER 6
    user7 - USER 7
    user8 - USER 8
    user9 - USER 9

After:
    user0 - USER 0
    user1 - USER 1
    user2 - USER 2
    user3 - USER 3
    user4 - USER 4
    user5 - USER 5
    user6 - USER 6
    user7 - USER 7
    user8 - USER 8
    user9 - USER 9
    user10 - USER 10
    user11 - USER 11
    user12 - USER 12
    user13 - USER 13
    user14 - USER 14
    user15 - USER 15

svn path=/trunk/; revision=50482

CMakeLists.txt
Makefile.common
Makefile.nmake
editcap.c
epan/CMakeLists.txt
epan/Makefile.common
epan/strnatcmp.c [new file with mode: 0755]
epan/strnatcmp.h [new file with mode: 0755]
mergecap.c

index 2f023677e49556ee7ba2960edcdc1726223dd6cf..315e2f9c59dc5f797f46e3da90635d7bf3edfb52 100644 (file)
@@ -942,6 +942,7 @@ if(BUILD_mergecap)
        set(mergecap_FILES
                mergecap.c
                merge.c
+               epan/strnatcmp.c
                svnversion.h
                ${WTAP_PLUGIN_SOURCES}
        )
@@ -995,6 +996,7 @@ if(BUILD_editcap)
        set(editcap_FILES
                editcap.c
                epan/crypt/md5.c
+               epan/strnatcmp.c
                ${WTAP_PLUGIN_SOURCES}
        )
        add_executable(editcap ${editcap_FILES})
index 79880dc534cc9c85e6493a1210a8980f5c792791..447af8694fd52e9b3e6be59dfa6f5e096b9c08ed 100644 (file)
@@ -161,12 +161,13 @@ text2pcap_INCLUDES = \
 mergecap_SOURCES = \
        mergecap.c \
        merge.c \
-       svnversion.h
+       epan/strnatcmp.c
 
 # editcap specifics
 editcap_SOURCES = \
        editcap.c       \
        epan/crypt/md5.c \
+       epan/strnatcmp.c \
        $(WTAP_PLUGIN_SOURCES)
 
 # reordercap specifics
index 0aac1709e9a66365e2aa776e6b6f44decac08686..236f26dc1166ad0c6a657c7790c733921e89ec9f 100644 (file)
@@ -64,7 +64,7 @@ wireshark_OBJECTS = $(WIRESHARK_COMMON_SRC:.c=.obj)
 tshark_OBJECTS = $(tshark_SOURCES:.c=.obj)
 rawshark_OBJECTS = $(rawshark_SOURCES:.c=.obj)
 ###text2pcap_OBJECTS = $(text2pcap_SOURCES:.c=.obj)
-###mergecap_OBJECTS = $(mergecap_SOURCES:.c=.obj)
+mergecap_OBJECTS = $(mergecap_SOURCES:.c=.obj)
 editcap_OBJECTS = $(editcap_SOURCES:.c=.obj)
 capinfos_OBJECTS = $(capinfos_SOURCES:.c=.obj)
 dftest_OBJECTS = $(dftest_SOURCES:.c=.obj)
@@ -348,10 +348,10 @@ editcap.exe       : $(LIBS_CHECK) config.h $(editcap_OBJECTS) wsutil\libwsutil.lib wir
 !ENDIF
 
 # Linking with setargv.obj enables "wildcard expansion" of command-line arguments
-mergecap.exe   : $(LIBS_CHECK)  config.h mergecap.obj merge.obj wsutil\libwsutil.lib wiretap\wiretap-$(WTAP_VERSION).lib image\mergecap.res
+mergecap.exe   : $(LIBS_CHECK)  config.h $(mergecap_OBJECTS) wsutil\libwsutil.lib wiretap\wiretap-$(WTAP_VERSION).lib image\mergecap.res
        @echo Linking $@
        $(LINK) @<<
-               /OUT:mergecap.exe $(conflags) $(conlibsdll) $(LDFLAGS) mergecap.obj merge.obj $(mergecap_LIBS) setargv.obj image\mergecap.res
+               /OUT:mergecap.exe $(conflags) $(conlibsdll) $(LDFLAGS) $(mergecap_OBJECTS) $(mergecap_LIBS) image\mergecap.res
 <<
 !IFDEF MANIFEST_INFO_REQUIRED
        mt.exe -nologo -manifest "mergecap.exe.manifest" -outputresource:mergecap.exe;1
index a0a4dfc227f627baab083027a8b81f84a93aa861..34a1509bedceed42662287324baff221440140f8 100644 (file)
--- a/editcap.c
+++ b/editcap.c
@@ -89,6 +89,7 @@
 #include "epan/plugins.h"
 #include "epan/report_err.h"
 #include "epan/filesystem.h"
+#include "epan/strnatcmp.h"
 #include "wsutil/nstime.h"
 #undef WS_BUILD_DLL
 #define RESET_SYMBOL_EXPORT
@@ -780,6 +781,13 @@ string_compare(gconstpointer a, gconstpointer b)
         ((const struct string_elem *)b)->sstr);
 }
 
+static gint
+string_nat_compare(gconstpointer a, gconstpointer b)
+{
+    return strnatcmp(((const struct string_elem *)a)->sstr,
+        ((const struct string_elem *)b)->sstr);
+}
+
 static void
 string_elem_print(gpointer data, gpointer not_used _U_)
 {
@@ -820,7 +828,7 @@ list_encap_types(void) {
         encaps[i].sstr = wtap_encap_short_string(i);
         if (encaps[i].sstr != NULL) {
             encaps[i].lstr = wtap_encap_string(i);
-            list = g_slist_insert_sorted(list, &encaps[i], string_compare);
+            list = g_slist_insert_sorted(list, &encaps[i], string_nat_compare);
         }
     }
     g_slist_foreach(list, string_elem_print, NULL);
@@ -900,7 +908,7 @@ main(int argc, char *argv[])
 #endif
 
   /* Process the options */
-  while ((opt = getopt(argc, argv, "A:B:c:C:dD:E:F:hrs:i:t:S:T:vw:")) !=-1) {
+  while ((opt = getopt(argc, argv, "A:B:c:C:dD:E:F:hi:rs:S:t:T:vw:")) !=-1) {
 
     switch (opt) {
 
index 3ee44cdec1d9d357cca71ec058f93ba874bb2b2a..1e33c1ae6eba921a0fac41931c082b47cba7cd40 100644 (file)
@@ -1469,6 +1469,7 @@ set(LIBWIRESHARK_FILES
        sna-utils.c
        stat_cmd_args.c
        stats_tree.c
+       strnatcmp.c
        strutil.c
        stream.c
        t35.c
index b9e84e8b2e2876091d4ea3026e67cc509415e9e1..446bdead58f89561ce55e01377c4d393056ad257 100644 (file)
@@ -83,6 +83,7 @@ LIBWIRESHARK_SRC =            \
        sna-utils.c             \
        stat_cmd_args.c         \
        stats_tree.c            \
+       strnatcmp.c             \
        strutil.c               \
        stream.c                \
        t35.c                   \
@@ -232,6 +233,7 @@ LIBWIRESHARK_INCLUDES =             \
        stats_tree.h            \
        stats_tree_priv.h       \
        stream.h                \
+       strnatcmp.h             \
        strutil.h               \
        t35.h                   \
        tap.h                   \
diff --git a/epan/strnatcmp.c b/epan/strnatcmp.c
new file mode 100755 (executable)
index 0000000..ee4d14e
--- /dev/null
@@ -0,0 +1,202 @@
+/* strnatcmp.c
+ *
+ * $Id$
+ *
+ * Original code downloaded from: http://sourcefrog.net/projects/natsort/
+
+  strnatcmp.c -- Perform 'natural order' comparisons of strings in C.
+  Copyright (C) 2000, 2004 by Martin Pool <mbp sourcefrog net>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+
+
+/* partial change history:
+ *
+ * 2004-10-10 mbp: Lift out character type dependencies into macros.
+ *
+ * Eric Sosman pointed out that ctype functions take a parameter whose
+ * value must be that of an unsigned int, even on platforms that have
+ * negative chars in their default char type.
+ */
+
+#include <ctype.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "strnatcmp.h"
+
+
+/* These are defined as macros to make it easier to adapt this code to
+ * different characters types or comparison functions. */
+static int
+nat_isdigit(nat_char a)
+{
+    return isdigit((unsigned char) a);
+}
+
+
+static int
+nat_isspace(nat_char a)
+{
+    return isspace((unsigned char) a);
+}
+
+
+static nat_char
+nat_toupper(nat_char a)
+{
+    return toupper((unsigned char) a);
+}
+
+
+static int
+compare_right(nat_char const *a, nat_char const *b)
+{
+    int bias = 0;
+
+    /* The longest run of digits wins.  That aside, the greatest
+       value wins, but we can't know that it will until we've scanned
+       both numbers to know that they have the same magnitude, so we
+       remember it in BIAS. */
+    for (;; a++, b++) {
+        if (!nat_isdigit(*a)  &&  !nat_isdigit(*b))
+            return bias;
+        else if (!nat_isdigit(*a))
+            return -1;
+        else if (!nat_isdigit(*b))
+            return +1;
+        else if (*a < *b) {
+            if (!bias)
+                bias = -1;
+        } else if (*a > *b) {
+            if (!bias)
+                bias = +1;
+        } else if (!*a  &&  !*b)
+            return bias;
+    }
+
+    return 0;
+}
+
+
+static int
+compare_left(nat_char const *a, nat_char const *b)
+{
+    /* Compare two left-aligned numbers: the first to have a
+       different value wins. */
+    for (;; a++, b++) {
+        if (!nat_isdigit(*a)  &&  !nat_isdigit(*b))
+            return 0;
+        else if (!nat_isdigit(*a))
+            return -1;
+        else if (!nat_isdigit(*b))
+            return +1;
+        else if (*a < *b)
+            return -1;
+        else if (*a > *b)
+            return +1;
+    }
+
+    return 0;
+}
+
+
+static int strnatcmp0(nat_char const *a, nat_char const *b, int fold_case)
+{
+    int ai, bi;
+    nat_char ca, cb;
+    int fractional, result;
+
+    if (!a || !b) {
+        if (!a && !b)
+            return 0;
+        if (!a)
+            return -1;
+        return +1;
+    }
+    ai = bi = 0;
+    while (1) {
+        ca = a[ai]; cb = b[bi];
+
+        /* skip over leading spaces or zeros */
+        while (nat_isspace(ca))
+            ca = a[++ai];
+
+        while (nat_isspace(cb))
+            cb = b[++bi];
+
+        /* process run of digits */
+        if (nat_isdigit(ca)  &&  nat_isdigit(cb)) {
+            fractional = (ca == '0' || cb == '0');
+
+            if (fractional) {
+                if ((result = compare_left(a+ai, b+bi)) != 0)
+                    return result;
+            } else {
+                if ((result = compare_right(a+ai, b+bi)) != 0)
+                    return result;
+            }
+        }
+
+        if (!ca && !cb) {
+            /* The strings compare the same.  Perhaps the caller
+               will want to call strcmp to break the tie. */
+            return 0;
+        }
+
+        if (fold_case) {
+            ca = nat_toupper(ca);
+            cb = nat_toupper(cb);
+        }
+
+        if (ca < cb)
+            return -1;
+        else if (ca > cb)
+            return +1;
+
+        ++ai; ++bi;
+    }
+}
+
+
+int strnatcmp(nat_char const *a, nat_char const *b)
+{
+    return strnatcmp0(a, b, 0);
+}
+
+
+/* Compare, recognizing numeric string and ignoring case. */
+int strnatcasecmp(nat_char const *a, nat_char const *b)
+{
+    return strnatcmp0(a, b, 1);
+}
+
+
+/*
+ * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=4 expandtab:
+ * :indentSize=4:tabSize=4:noTabs=true:
+ */
+
diff --git a/epan/strnatcmp.h b/epan/strnatcmp.h
new file mode 100755 (executable)
index 0000000..221ddbd
--- /dev/null
@@ -0,0 +1,49 @@
+/* strnatcmp.h
+ *
+ * $Id$
+ *
+ * Original code downloaded from: http://sourcefrog.net/projects/natsort/
+
+  strnatcmp.c -- Perform 'natural order' comparisons of strings in C.
+  Copyright (C) 2000, 2004 by Martin Pool <mbp sourcefrog net>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef STRNATCMP_H
+#define STRNATCMP_H
+
+#include "ws_symbol_export.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* CUSTOMIZATION SECTION
+ *
+ * You can change this typedef, but must then also change the inline
+ * functions in strnatcmp.c */
+typedef char nat_char;
+
+WS_DLL_PUBLIC int strnatcmp(nat_char const *a, nat_char const *b);
+WS_DLL_PUBLIC int strnatcasecmp(nat_char const *a, nat_char const *b);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* STRNATCMP_H */
index 433518824fe968db73511d983805a02851e3498f..74b0c004aaec91492be6c6db502de1c2a084a12a 100644 (file)
 #include "wsutil/wsgetopt.h"
 #endif
 
+#define WS_BUILD_DLL
+#define RESET_SYMBOL_EXPORT /* wsutil/wsgetopt.h set export behavior above. */
+#include "epan/strnatcmp.h"
+#undef WS_BUILD_DLL
+#define RESET_SYMBOL_EXPORT
+
 #include "svnversion.h"
 #include "merge.h"
 #include "wsutil/file_util.h"
@@ -145,6 +151,13 @@ string_compare(gconstpointer a, gconstpointer b)
         ((const struct string_elem *)b)->sstr);
 }
 
+static gint
+string_nat_compare(gconstpointer a, gconstpointer b)
+{
+    return strnatcmp(((const struct string_elem *)a)->sstr,
+        ((const struct string_elem *)b)->sstr);
+}
+
 static void
 string_elem_print(gpointer data, gpointer not_used _U_)
 {
@@ -186,7 +199,7 @@ list_encap_types(void) {
         encaps[i].sstr = wtap_encap_short_string(i);
         if (encaps[i].sstr != NULL) {
             encaps[i].lstr = wtap_encap_string(i);
-            list = g_slist_insert_sorted(list, &encaps[i], string_compare);
+            list = g_slist_insert_sorted(list, &encaps[i], string_nat_compare);
         }
     }
     g_slist_foreach(list, string_elem_print, NULL);