forked from osmocom/wireshark
Add strnatcmp by Martin Pool for 'natural order' string comparisons, and make use of it in editcap and mergecap for listing encapsulation types. For example:
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
This commit is contained in:
parent
d3e9ec675a
commit
d602662b36
|
@ -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})
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
12
editcap.c
12
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) {
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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:
|
||||
*/
|
||||
|
|
@ -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 */
|
15
mergecap.c
15
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);
|
||||
|
|
Loading…
Reference in New Issue