diff options
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | Makefile.common | 3 | ||||
-rw-r--r-- | Makefile.nmake | 6 | ||||
-rw-r--r-- | editcap.c | 12 | ||||
-rw-r--r-- | epan/CMakeLists.txt | 1 | ||||
-rw-r--r-- | epan/Makefile.common | 2 | ||||
-rwxr-xr-x | epan/strnatcmp.c | 202 | ||||
-rwxr-xr-x | epan/strnatcmp.h | 49 | ||||
-rw-r--r-- | mergecap.c | 15 |
9 files changed, 285 insertions, 7 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 2f023677e4..315e2f9c59 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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}) diff --git a/Makefile.common b/Makefile.common index 79880dc534..447af8694f 100644 --- a/Makefile.common +++ b/Makefile.common @@ -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 diff --git a/Makefile.nmake b/Makefile.nmake index 0aac1709e9..236f26dc11 100644 --- a/Makefile.nmake +++ b/Makefile.nmake @@ -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 @@ -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) { diff --git a/epan/CMakeLists.txt b/epan/CMakeLists.txt index 3ee44cdec1..1e33c1ae6e 100644 --- a/epan/CMakeLists.txt +++ b/epan/CMakeLists.txt @@ -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 diff --git a/epan/Makefile.common b/epan/Makefile.common index b9e84e8b2e..446bdead58 100644 --- a/epan/Makefile.common +++ b/epan/Makefile.common @@ -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 index 0000000000..ee4d14e8cc --- /dev/null +++ b/epan/strnatcmp.c @@ -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 index 0000000000..221ddbda3f --- /dev/null +++ b/epan/strnatcmp.h @@ -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 */ diff --git a/mergecap.c b/mergecap.c index 433518824f..74b0c004aa 100644 --- a/mergecap.c +++ b/mergecap.c @@ -47,6 +47,12 @@ #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); |