mirror of
https://github.com/MidnightCommander/mc
synced 2024-12-22 12:32:40 +03:00
Fix file version sort.
Use filevercmp() instead of str_verscmp(). Source code of filevercmp() is taken from Gnulib. Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
This commit is contained in:
parent
2163009270
commit
a2a5fa017e
@ -538,6 +538,28 @@ const char *str_detect_termencoding (void);
|
|||||||
|
|
||||||
int str_verscmp (const char *s1, const char *s2);
|
int str_verscmp (const char *s1, const char *s2);
|
||||||
|
|
||||||
|
/* Compare version strings:
|
||||||
|
|
||||||
|
This function compares strings s1 and s2:
|
||||||
|
1) By PREFIX in the same way as strcmp.
|
||||||
|
2) Then by VERSION (most similarly to version compare of Debian's dpkg).
|
||||||
|
Leading zeros in version numbers are ignored.
|
||||||
|
3) If both (PREFIX and VERSION) are equal, strcmp function is used for
|
||||||
|
comparison. So this function can return 0 if (and only if) strings s1
|
||||||
|
and s2 are identical.
|
||||||
|
|
||||||
|
It returns number > 0 for s1 > s2, 0 for s1 == s2 and number < 0 for s1 < s2.
|
||||||
|
|
||||||
|
This function compares strings, in a way that if VER1 and VER2 are version
|
||||||
|
numbers and PREFIX and SUFFIX (SUFFIX defined as (\.[A-Za-z~][A-Za-z0-9~]*)*)
|
||||||
|
are strings then VER1 < VER2 implies filevercmp (PREFIX VER1 SUFFIX,
|
||||||
|
PREFIX VER2 SUFFIX) < 0.
|
||||||
|
|
||||||
|
This function is intended to be a replacement for strverscmp.
|
||||||
|
*/
|
||||||
|
int filevercmp (const char *s1, const char *s2);
|
||||||
|
|
||||||
|
|
||||||
/* return how many lines and columns will text occupy on terminal
|
/* return how many lines and columns will text occupy on terminal
|
||||||
*/
|
*/
|
||||||
void str_msg_term_size (const char *text, int *lines, int *columns);
|
void str_msg_term_size (const char *text, int *lines, int *columns);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
noinst_LTLIBRARIES = libmcstrutil.la
|
noinst_LTLIBRARIES = libmcstrutil.la
|
||||||
|
|
||||||
libmcstrutil_la_SOURCES = \
|
libmcstrutil_la_SOURCES = \
|
||||||
|
filevercmp.c \
|
||||||
replace.c \
|
replace.c \
|
||||||
strescape.c \
|
strescape.c \
|
||||||
strutil8bit.c \
|
strutil8bit.c \
|
||||||
|
232
lib/strutil/filevercmp.c
Normal file
232
lib/strutil/filevercmp.c
Normal file
@ -0,0 +1,232 @@
|
|||||||
|
/*
|
||||||
|
Copyright (C) 1995 Ian Jackson <iwj10@cus.cam.ac.uk>
|
||||||
|
Copyright (C) 2001 Anthony Towns <aj@azure.humbug.org.au>
|
||||||
|
Copyright (C) 2008-2018 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
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 3 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, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
#include "lib/strutil.h"
|
||||||
|
|
||||||
|
/*** global variables ****************************************************************************/
|
||||||
|
|
||||||
|
/*** file scope macro definitions ****************************************************************/
|
||||||
|
|
||||||
|
/*** file scope type declarations ****************************************************************/
|
||||||
|
|
||||||
|
/*** file scope variables ************************************************************************/
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
/*** file scope functions ************************************************************************/
|
||||||
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* Match a file suffix defined by this regular expression: /(\.[A-Za-z~][A-Za-z0-9~]*)*$/
|
||||||
|
*
|
||||||
|
* @str pointer to string to scan.
|
||||||
|
*
|
||||||
|
* @return pointer to the matching suffix, or NULL if not found.
|
||||||
|
* Upon return, @str points to terminating NUL.
|
||||||
|
*/
|
||||||
|
static const char *
|
||||||
|
match_suffix (const char **str)
|
||||||
|
{
|
||||||
|
const char *match = NULL;
|
||||||
|
gboolean read_alpha = FALSE;
|
||||||
|
|
||||||
|
while (**str != '\0')
|
||||||
|
{
|
||||||
|
if (read_alpha)
|
||||||
|
{
|
||||||
|
read_alpha = FALSE;
|
||||||
|
if (!g_ascii_isalpha (**str) && **str != '~')
|
||||||
|
match = NULL;
|
||||||
|
}
|
||||||
|
else if (**str == '.')
|
||||||
|
{
|
||||||
|
read_alpha = TRUE;
|
||||||
|
if (match == NULL)
|
||||||
|
match = *str;
|
||||||
|
}
|
||||||
|
else if (!g_ascii_isalnum (**str) && **str != '~')
|
||||||
|
match = NULL;
|
||||||
|
(*str)++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* verrevcmp helper function */
|
||||||
|
static int
|
||||||
|
order (unsigned char c)
|
||||||
|
{
|
||||||
|
if (g_ascii_isdigit (c))
|
||||||
|
return 0;
|
||||||
|
if (g_ascii_isalpha (c))
|
||||||
|
return c;
|
||||||
|
if (c == '~')
|
||||||
|
return -1;
|
||||||
|
return (int) c + UCHAR_MAX + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* Slightly modified verrevcmp function from dpkg
|
||||||
|
*
|
||||||
|
* This implements the algorithm for comparison of version strings
|
||||||
|
* specified by Debian and now widely adopted. The detailed
|
||||||
|
* specification can be found in the Debian Policy Manual in the
|
||||||
|
* section on the 'Version' control field. This version of the code
|
||||||
|
* implements that from s5.6.12 of Debian Policy v3.8.0.1
|
||||||
|
* https://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Version
|
||||||
|
*
|
||||||
|
* @s1 first string to compare
|
||||||
|
* @s1_len length of @s1
|
||||||
|
* @s2 second string to compare
|
||||||
|
* @s2_len length of @s2
|
||||||
|
*
|
||||||
|
* @return an integer less than, equal to, or greater than zero, if @s1 is <, == or > than @s2.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
verrevcmp (const char *s1, size_t s1_len, const char *s2, size_t s2_len)
|
||||||
|
{
|
||||||
|
size_t s1_pos = 0;
|
||||||
|
size_t s2_pos = 0;
|
||||||
|
|
||||||
|
while (s1_pos < s1_len || s2_pos < s2_len)
|
||||||
|
{
|
||||||
|
int first_diff = 0;
|
||||||
|
|
||||||
|
while ((s1_pos < s1_len && !g_ascii_isdigit (s1[s1_pos]))
|
||||||
|
|| (s2_pos < s2_len && !g_ascii_isdigit (s2[s2_pos])))
|
||||||
|
{
|
||||||
|
int s1_c = 0;
|
||||||
|
int s2_c = 0;
|
||||||
|
|
||||||
|
if (s1_pos != s1_len)
|
||||||
|
s1_c = order (s1[s1_pos]);
|
||||||
|
if (s2_pos != s2_len)
|
||||||
|
s2_c = order (s2[s2_pos]);
|
||||||
|
|
||||||
|
if (s1_c != s2_c)
|
||||||
|
return (s1_c - s2_c);
|
||||||
|
|
||||||
|
s1_pos++;
|
||||||
|
s2_pos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (s1[s1_pos] == '0')
|
||||||
|
s1_pos++;
|
||||||
|
while (s2[s2_pos] == '0')
|
||||||
|
s2_pos++;
|
||||||
|
|
||||||
|
while (g_ascii_isdigit (s1[s1_pos]) && g_ascii_isdigit (s2[s2_pos]))
|
||||||
|
{
|
||||||
|
if (first_diff == 0)
|
||||||
|
first_diff = s1[s1_pos] - s2[s2_pos];
|
||||||
|
|
||||||
|
s1_pos++;
|
||||||
|
s2_pos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_ascii_isdigit (s1[s1_pos]))
|
||||||
|
return 1;
|
||||||
|
if (g_ascii_isdigit (s2[s2_pos]))
|
||||||
|
return -1;
|
||||||
|
if (first_diff != 0)
|
||||||
|
return first_diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
/*** public functions ****************************************************************************/
|
||||||
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* Compare version strings.
|
||||||
|
*
|
||||||
|
* @s1 first string to compare
|
||||||
|
* @s2 second string to compare
|
||||||
|
*
|
||||||
|
* @return an integer less than, equal to, or greater than zero, if @s1 is <, == or > than @s2.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
filevercmp (const char *s1, const char *s2)
|
||||||
|
{
|
||||||
|
const char *s1_pos, *s2_pos;
|
||||||
|
const char *s1_suffix, *s2_suffix;
|
||||||
|
size_t s1_len, s2_len;
|
||||||
|
int simple_cmp, result;
|
||||||
|
|
||||||
|
/* easy comparison to see if strings are identical */
|
||||||
|
simple_cmp = strcmp (s1, s2);
|
||||||
|
if (simple_cmp == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* special handle for "", "." and ".." */
|
||||||
|
if (*s1 == '\0')
|
||||||
|
return -1;
|
||||||
|
if (*s2 == '\0')
|
||||||
|
return 1;
|
||||||
|
if (DIR_IS_DOT (s1))
|
||||||
|
return -1;
|
||||||
|
if (DIR_IS_DOT (s2))
|
||||||
|
return 1;
|
||||||
|
if (DIR_IS_DOTDOT (s1))
|
||||||
|
return -1;
|
||||||
|
if (DIR_IS_DOTDOT (s2))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* special handle for other hidden files */
|
||||||
|
if (*s1 == '.' && *s2 != '.')
|
||||||
|
return -1;
|
||||||
|
if (*s1 != '.' && *s2 == '.')
|
||||||
|
return 1;
|
||||||
|
if (*s1 == '.' && *s2 == '.')
|
||||||
|
{
|
||||||
|
s1++;
|
||||||
|
s2++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* "cut" file suffixes */
|
||||||
|
s1_pos = s1;
|
||||||
|
s2_pos = s2;
|
||||||
|
s1_suffix = match_suffix (&s1_pos);
|
||||||
|
s2_suffix = match_suffix (&s2_pos);
|
||||||
|
s1_len = (s1_suffix != NULL ? s1_suffix : s1_pos) - s1;
|
||||||
|
s2_len = (s2_suffix != NULL ? s2_suffix : s2_pos) - s2;
|
||||||
|
|
||||||
|
/* restore file suffixes if strings are identical after "cut" */
|
||||||
|
if ((s1_suffix != NULL || s2_suffix != NULL) && (s1_len == s2_len)
|
||||||
|
&& strncmp (s1, s2, s1_len) == 0)
|
||||||
|
{
|
||||||
|
s1_len = s1_pos - s1;
|
||||||
|
s2_len = s2_pos - s2;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = verrevcmp (s1, s1_len, s2, s2_len);
|
||||||
|
|
||||||
|
return result == 0 ? simple_cmp : result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------- */
|
@ -354,7 +354,7 @@ sort_vers (file_entry_t * a, file_entry_t * b)
|
|||||||
|
|
||||||
if (ad == bd || panels_options.mix_all_files)
|
if (ad == bd || panels_options.mix_all_files)
|
||||||
{
|
{
|
||||||
return str_verscmp (a->fname, b->fname) * reverse;
|
return filevercmp (a->fname, b->fname) * reverse;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -16,7 +16,8 @@ endif
|
|||||||
TESTS = \
|
TESTS = \
|
||||||
replace__str_replace_all \
|
replace__str_replace_all \
|
||||||
parse_integer \
|
parse_integer \
|
||||||
str_verscmp
|
str_verscmp \
|
||||||
|
filevercmp
|
||||||
|
|
||||||
check_PROGRAMS = $(TESTS)
|
check_PROGRAMS = $(TESTS)
|
||||||
|
|
||||||
@ -28,3 +29,6 @@ parse_integer_SOURCES = \
|
|||||||
|
|
||||||
str_verscmp_SOURCES = \
|
str_verscmp_SOURCES = \
|
||||||
str_verscmp.c
|
str_verscmp.c
|
||||||
|
|
||||||
|
filevercmp_SOURCES = \
|
||||||
|
filevercmp.c
|
||||||
|
296
tests/lib/strutil/filevercmp.c
Normal file
296
tests/lib/strutil/filevercmp.c
Normal file
@ -0,0 +1,296 @@
|
|||||||
|
/*
|
||||||
|
lib/strutil - tests for lib/strutil/fileverscmp function.
|
||||||
|
|
||||||
|
Copyright (C) 2019
|
||||||
|
Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
Written by:
|
||||||
|
Andrew Borodin <aborodin@vmail.ru>, 2019
|
||||||
|
|
||||||
|
This file is part of the Midnight Commander.
|
||||||
|
|
||||||
|
The Midnight Commander 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 3 of the License,
|
||||||
|
or (at your option) any later version.
|
||||||
|
|
||||||
|
The Midnight Commander 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define TEST_SUITE_NAME "/lib/strutil"
|
||||||
|
|
||||||
|
#include "tests/mctest.h"
|
||||||
|
|
||||||
|
#include "lib/strutil.h"
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* @Before */
|
||||||
|
static void
|
||||||
|
setup (void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* @After */
|
||||||
|
static void
|
||||||
|
teardown (void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
static int
|
||||||
|
sign (int n)
|
||||||
|
{
|
||||||
|
return ((n < 0) ? -1 : (n == 0) ? 0 : 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* @DataSource("filevercmp_test_ds1") */
|
||||||
|
/* Testcases are taken from Gnulib */
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
static const struct filevercmp_test_struct
|
||||||
|
{
|
||||||
|
const char *s1;
|
||||||
|
const char *s2;
|
||||||
|
int expected_result;
|
||||||
|
} filevercmp_test_ds1[] =
|
||||||
|
{
|
||||||
|
{ "", "", 0 },
|
||||||
|
{ "a", "a", 0 },
|
||||||
|
{ "a", "b", -1 },
|
||||||
|
{ "b", "a", 1 },
|
||||||
|
{ "a0", "a", 1 },
|
||||||
|
{ "00", "01", -1 },
|
||||||
|
{ "01", "010", -1 },
|
||||||
|
{ "9", "10", -1 },
|
||||||
|
{ "0a", "0", 1 }
|
||||||
|
};
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
|
||||||
|
/* @Test(dataSource = "filevercmp_test_ds1") */
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
START_TEST (filevercmp_test1)
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
{
|
||||||
|
/* given */
|
||||||
|
int actual_result;
|
||||||
|
const struct filevercmp_test_struct *data = &filevercmp_test_ds1[_i];
|
||||||
|
|
||||||
|
/* when */
|
||||||
|
actual_result = filevercmp (data->s1, data->s2);
|
||||||
|
|
||||||
|
/* then */
|
||||||
|
mctest_assert_int_eq (sign (actual_result), sign (data->expected_result));
|
||||||
|
}
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
END_TEST
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* @DataSource("filevercmp_test_ds2") */
|
||||||
|
/* Testcases are taken from Gnulib */
|
||||||
|
static const char *filevercmp_test_ds2[] = {
|
||||||
|
"",
|
||||||
|
".",
|
||||||
|
"..",
|
||||||
|
".0",
|
||||||
|
".9",
|
||||||
|
".A",
|
||||||
|
".Z",
|
||||||
|
".a~",
|
||||||
|
".a",
|
||||||
|
".b~",
|
||||||
|
".b",
|
||||||
|
".z",
|
||||||
|
".zz~",
|
||||||
|
".zz",
|
||||||
|
".zz.~1~",
|
||||||
|
".zz.0",
|
||||||
|
"0",
|
||||||
|
"9",
|
||||||
|
"A",
|
||||||
|
"Z",
|
||||||
|
"a~",
|
||||||
|
"a",
|
||||||
|
"a.b~",
|
||||||
|
"a.b",
|
||||||
|
"a.bc~",
|
||||||
|
"a.bc",
|
||||||
|
"b~",
|
||||||
|
"b",
|
||||||
|
"gcc-c++-10.fc9.tar.gz",
|
||||||
|
"gcc-c++-10.fc9.tar.gz.~1~",
|
||||||
|
"gcc-c++-10.fc9.tar.gz.~2~",
|
||||||
|
"gcc-c++-10.8.12-0.7rc2.fc9.tar.bz2",
|
||||||
|
"gcc-c++-10.8.12-0.7rc2.fc9.tar.bz2.~1~",
|
||||||
|
"glibc-2-0.1.beta1.fc10.rpm",
|
||||||
|
"glibc-common-5-0.2.beta2.fc9.ebuild",
|
||||||
|
"glibc-common-5-0.2b.deb",
|
||||||
|
"glibc-common-11b.ebuild",
|
||||||
|
"glibc-common-11-0.6rc2.ebuild",
|
||||||
|
"libstdc++-0.5.8.11-0.7rc2.fc10.tar.gz",
|
||||||
|
"libstdc++-4a.fc8.tar.gz",
|
||||||
|
"libstdc++-4.10.4.20040204svn.rpm",
|
||||||
|
"libstdc++-devel-3.fc8.ebuild",
|
||||||
|
"libstdc++-devel-3a.fc9.tar.gz",
|
||||||
|
"libstdc++-devel-8.fc8.deb",
|
||||||
|
"libstdc++-devel-8.6.2-0.4b.fc8",
|
||||||
|
"nss_ldap-1-0.2b.fc9.tar.bz2",
|
||||||
|
"nss_ldap-1-0.6rc2.fc8.tar.gz",
|
||||||
|
"nss_ldap-1.0-0.1a.tar.gz",
|
||||||
|
"nss_ldap-10beta1.fc8.tar.gz",
|
||||||
|
"nss_ldap-10.11.8.6.20040204cvs.fc10.ebuild",
|
||||||
|
"z",
|
||||||
|
"zz~",
|
||||||
|
"zz",
|
||||||
|
"zz.~1~",
|
||||||
|
"zz.0",
|
||||||
|
"#.b#"
|
||||||
|
};
|
||||||
|
|
||||||
|
const size_t filevercmp_test_ds2_len = G_N_ELEMENTS (filevercmp_test_ds2);
|
||||||
|
|
||||||
|
/* @Test(dataSource = "filevercmp_test_ds2") */
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
START_TEST (filevercmp_test2)
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
{
|
||||||
|
const char *i = filevercmp_test_ds2[_i];
|
||||||
|
size_t _j;
|
||||||
|
|
||||||
|
for (_j = 0; _j < filevercmp_test_ds2_len; _j++)
|
||||||
|
{
|
||||||
|
const char *j = filevercmp_test_ds2[_j];
|
||||||
|
int result;
|
||||||
|
|
||||||
|
result = filevercmp (i, j);
|
||||||
|
|
||||||
|
if (result < 0)
|
||||||
|
ck_assert_int_eq (!!((size_t) _i < _j), 1);
|
||||||
|
else if (0 < result)
|
||||||
|
ck_assert_int_eq (!!(_j < (size_t) _i), 1);
|
||||||
|
else
|
||||||
|
ck_assert_int_eq (!!(_j == (size_t) _i), 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
END_TEST
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
|
||||||
|
/* @DataSource("filevercmp_test_ds3") */
|
||||||
|
/* Ticket #3959 */
|
||||||
|
static const char *filevercmp_test_ds3[] = {
|
||||||
|
"application-1.10.tar.gz",
|
||||||
|
"application-1.10.1.tar.gz"
|
||||||
|
};
|
||||||
|
|
||||||
|
const size_t filevercmp_test_ds3_len = G_N_ELEMENTS (filevercmp_test_ds3);
|
||||||
|
|
||||||
|
/* @Test(dataSource = "filevercmp_test_ds3") */
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
START_TEST (filevercmp_test3)
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
{
|
||||||
|
const char *i = filevercmp_test_ds3[_i];
|
||||||
|
size_t _j;
|
||||||
|
|
||||||
|
for (_j = 0; _j < filevercmp_test_ds3_len; _j++)
|
||||||
|
{
|
||||||
|
const char *j = filevercmp_test_ds3[_j];
|
||||||
|
int result;
|
||||||
|
|
||||||
|
result = filevercmp (i, j);
|
||||||
|
|
||||||
|
if (result < 0)
|
||||||
|
ck_assert_int_eq (!!((size_t) _i < _j), 1);
|
||||||
|
else if (0 < result)
|
||||||
|
ck_assert_int_eq (!!(_j < (size_t) _i), 1);
|
||||||
|
else
|
||||||
|
ck_assert_int_eq (!!(_j == (size_t) _i), 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
END_TEST
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
|
||||||
|
/* @DataSource("filevercmp_test_ds4") */
|
||||||
|
/* Ticket #3905 */
|
||||||
|
static const char *filevercmp_test_ds4[] = {
|
||||||
|
"firefox-58.0.1+build1.tar.gz",
|
||||||
|
"firefox-59.0~b14+build1.tar.gz",
|
||||||
|
"firefox-59.0.1+build1.tar.gz"
|
||||||
|
};
|
||||||
|
|
||||||
|
const size_t filevercmp_test_ds4_len = G_N_ELEMENTS (filevercmp_test_ds4);
|
||||||
|
|
||||||
|
/* @Test(dataSource = "filevercmp_test_ds4") */
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
START_TEST (filevercmp_test4)
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
{
|
||||||
|
const char *i = filevercmp_test_ds4[_i];
|
||||||
|
size_t _j;
|
||||||
|
|
||||||
|
for (_j = 0; _j < filevercmp_test_ds4_len; _j++)
|
||||||
|
{
|
||||||
|
const char *j = filevercmp_test_ds4[_j];
|
||||||
|
int result;
|
||||||
|
|
||||||
|
result = filevercmp (i, j);
|
||||||
|
|
||||||
|
if (result < 0)
|
||||||
|
ck_assert_int_eq (!!((size_t) _i < _j), 1);
|
||||||
|
else if (0 < result)
|
||||||
|
ck_assert_int_eq (!!(_j < (size_t) _i), 1);
|
||||||
|
else
|
||||||
|
ck_assert_int_eq (!!(_j == (size_t) _i), 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
END_TEST
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
int
|
||||||
|
main (void)
|
||||||
|
{
|
||||||
|
int number_failed;
|
||||||
|
|
||||||
|
Suite *s = suite_create (TEST_SUITE_NAME);
|
||||||
|
TCase *tc_core = tcase_create ("Core");
|
||||||
|
SRunner *sr;
|
||||||
|
|
||||||
|
tcase_add_checked_fixture (tc_core, setup, teardown);
|
||||||
|
|
||||||
|
/* Add new tests here: *************** */
|
||||||
|
mctest_add_parameterized_test (tc_core, filevercmp_test1, filevercmp_test_ds1);
|
||||||
|
tcase_add_loop_test (tc_core, filevercmp_test2, 0, filevercmp_test_ds2_len);
|
||||||
|
tcase_add_loop_test (tc_core, filevercmp_test3, 0, filevercmp_test_ds3_len);
|
||||||
|
tcase_add_loop_test (tc_core, filevercmp_test4, 0, filevercmp_test_ds4_len);
|
||||||
|
/* *********************************** */
|
||||||
|
|
||||||
|
suite_add_tcase (s, tc_core);
|
||||||
|
sr = srunner_create (s);
|
||||||
|
srunner_set_log (sr, "filevercmp.log");
|
||||||
|
srunner_run_all (sr, CK_ENV);
|
||||||
|
number_failed = srunner_ntests_failed (sr);
|
||||||
|
srunner_free (sr);
|
||||||
|
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------- */
|
Loading…
Reference in New Issue
Block a user