summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Jennings <mej@kainx.org>2002-07-14 03:31:38 +0000
committerMichael Jennings <mej@kainx.org>2002-07-14 03:31:38 +0000
commit0b1d8ad509b3e9b353fa96954ba0abf38bb9d843 (patch)
treeba9d57204a6fe1a26ff8a96f2a490ed36e90d322
parenta5f7c5eac03b9806627433d8d52563ebedd2d056 (diff)
downloadlibast-0b1d8ad509b3e9b353fa96954ba0abf38bb9d843.tar.gz
Sat Jul 13 23:26:12 2002 Michael Jennings (mej)
New function, version_compare(), which accurately compares package version numbers. Take a look at the various test cases to see what kinds of comparisons it can accurately make, and if you see any that aren't there, let me know. SVN revision: 6339
-rw-r--r--ChangeLog7
-rw-r--r--include/libast.h1
-rw-r--r--libast.spec2
-rw-r--r--src/conf.c6
-rw-r--r--src/mem.c2
-rw-r--r--src/strings.c110
-rw-r--r--src/tok.c5
-rw-r--r--test/test.c18
8 files changed, 144 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index 8c826c3..9897fe9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -244,3 +244,10 @@ Sun Jun 9 14:16:38 2002 Michael Jennings (mej)
Return on failed assert.
----------------------------------------------------------------------
+Sat Jul 13 23:26:12 2002 Michael Jennings (mej)
+
+New function, version_compare(), which accurately compares package
+version numbers. Take a look at the various test cases to see what
+kinds of comparisons it can accurately make, and if you see any that
+aren't there, let me know.
+----------------------------------------------------------------------
diff --git a/include/libast.h b/include/libast.h
index df6a34c..f5917f4 100644
--- a/include/libast.h
+++ b/include/libast.h
@@ -670,6 +670,7 @@ extern char *garbage_collect(char *, size_t);
extern char *file_garbage_collect(char *, size_t);
extern char *condense_whitespace(char *);
extern void hex_dump(void *, size_t);
+extern spif_cmp_t version_compare(const char *, const char *);
#ifndef HAVE_MEMMEM
extern void *memmem(const void *, size_t, const void *, size_t);
#endif
diff --git a/libast.spec b/libast.spec
index 2c2a8d8..5ed3177 100644
--- a/libast.spec
+++ b/libast.spec
@@ -1,7 +1,7 @@
Summary: Library of Assorted Spiffy Things
Name: libast
Version: 0.5
-Release: 1
+Release: 0.1
Copyright: BSD
Group: System Environment/Libraries
Source: %{name}-%{version}.tar.gz
diff --git a/src/conf.c b/src/conf.c
index 27d1765..be8a929 100644
--- a/src/conf.c
+++ b/src/conf.c
@@ -590,7 +590,7 @@ shell_expand(char *s)
for (pbuff++; *pbuff && *pbuff != '`' && l < max; pbuff++, l++) {
Command[l] = *pbuff;
}
- ASSERT(l < CONFIG_BUFF);
+ ASSERT_RVAL(l < CONFIG_BUFF, NULL);
Command[l] = 0;
Command = shell_expand(Command);
Output = builtin_exec(Command);
@@ -672,7 +672,7 @@ shell_expand(char *s)
newbuff[j] = *pbuff;
}
}
- ASSERT(j < CONFIG_BUFF);
+ ASSERT_RVAL(j < CONFIG_BUFF, NULL);
newbuff[j] = 0;
D_PARSE(("shell_expand(%s) returning \"%s\"\n", s, newbuff));
@@ -763,7 +763,7 @@ open_config_file(char *name)
int ver;
char buff[256], test[30], *begin_ptr, *end_ptr;
- ASSERT(name != NULL);
+ ASSERT_RVAL(name != NULL, NULL);
snprintf(test, sizeof(test), "<%s-", libast_program_name);
fp = fopen(name, "rt");
diff --git a/src/mem.c b/src/mem.c
index 4046595..372eac3 100644
--- a/src/mem.c
+++ b/src/mem.c
@@ -86,7 +86,7 @@ memrec_find_var(memrec_t *memrec, const void *ptr)
register ptr_t *p;
register unsigned long i;
- ASSERT(memrec != NULL);
+ ASSERT_RVAL(memrec != NULL, NULL);
REQUIRE_RVAL(ptr != NULL, NULL);
for (i = 0, p = memrec->ptrs; i < memrec->cnt; i++, p++) {
diff --git a/src/strings.c b/src/strings.c
index d5e81e5..8e59d34 100644
--- a/src/strings.c
+++ b/src/strings.c
@@ -736,8 +736,8 @@ hex_dump(void *buff, register size_t count)
for (ptr = (unsigned char *) buff, j = 0; j < count; j += 8) {
print_error(" %8p | %06lu | %07x | ", buff, (unsigned long) count, (unsigned int) j);
l = ((count - j < 8) ? (count - j) : (8));
- memset(buffr, 0, 9);
memcpy(buffr, ptr + j, l);
+ memset(buffr + l, 0, 9 - l);
for (k = 0; k < l; k++) {
print_error("%02x ", buffr[k]);
}
@@ -747,3 +747,111 @@ hex_dump(void *buff, register size_t count)
print_error("| %-8s\n", safe_str((char *) buffr, l));
}
}
+
+#define CHAR_CLASS_MATCH(a, b) ((isalpha(a) && isalpha(b)) \
+ || (isdigit(a) && isdigit(b)) \
+ || (!isalnum(a) && !isalnum(b)))
+spif_cmp_t
+version_compare(const char *v1, const char *v2)
+{
+ char buff1[128], buff2[128];
+
+ for (; *v1 && *v2; ) {
+ if (isalpha(*v1) && isalpha(*v2)) {
+ char *p1 = buff1, *p2 = buff2;
+ spif_int8_t ival1 = 5, ival2 = 5;
+
+ /* Compare words. First, copy each word into buffers. */
+ for (; isalpha(*v1); v1++, p1++) *p1 = *v1;
+ for (; isalpha(*v2); v2++, p2++) *p2 = *v2;
+ *p1 = *p2 = 0;
+
+ /* Change the buffered strings to lowercase for easier comparison. */
+ downcase_str(buff1);
+ downcase_str(buff2);
+
+ /* Some strings require special handling. */
+ if (!strcmp(buff1, "snap")) {
+ ival1 = 1;
+ } else if (!strcmp(buff1, "pre")) {
+ ival1 = 2;
+ } else if (!strcmp(buff1, "alpha")) {
+ ival1 = 3;
+ } else if (!strcmp(buff1, "beta")) {
+ ival1 = 4;
+ }
+ if (!strcmp(buff2, "snap")) {
+ ival2 = 1;
+ } else if (!strcmp(buff2, "pre")) {
+ ival2 = 2;
+ } else if (!strcmp(buff2, "alpha")) {
+ ival2 = 3;
+ } else if (!strcmp(buff2, "beta")) {
+ ival2 = 4;
+ }
+ if (ival1 != ival2) {
+ /* If the values are different, compare them. */
+ return SPIF_CMP_FROM_INT(ival1 - ival2);
+ } else if (ival1 == 5) {
+ int c;
+
+ /* Two arbitrary strings. Compare them too. */
+ if ((c = strcmp(buff1, buff2)) != 0) {
+ return SPIF_CMP_FROM_INT(c);
+ }
+ }
+ } else if (isdigit(*v1) && isdigit(*v2)) {
+ char *p1 = buff1, *p2 = buff2;
+ spif_int32_t ival1, ival2;
+ spif_cmp_t c;
+
+ /* Compare numbers. First, copy each number into buffers. */
+ for (; isdigit(*v1); v1++, p1++) *p1 = *v1;
+ for (; isdigit(*v2); v2++, p2++) *p2 = *v2;
+ *p1 = *p2 = 0;
+
+ /* Convert the strings into actual integers. */
+ ival1 = SPIF_CAST(int32) strtol(buff1, (char **) NULL, 10);
+ ival2 = SPIF_CAST(int32) strtol(buff2, (char **) NULL, 10);
+
+ /* Compare the integers and return if not equal. */
+ c = SPIF_CMP_FROM_INT(ival1 - ival2);
+ if (!SPIF_CMP_IS_EQUAL(c)) {
+ return c;
+ }
+ } else if (!isalnum(*v1) && !isalnum(*v2)) {
+ char *p1 = buff1, *p2 = buff2;
+ spif_cmp_t c;
+
+ /* Compare non-alphanumeric strings. */
+ for (; !isalnum(*v1); v1++, p1++) *p1 = *v1;
+ for (; !isalnum(*v2); v2++, p2++) *p2 = *v2;
+ *p1 = *p2 = 0;
+
+ c = SPIF_CMP_FROM_INT(strcasecmp(buff1, buff2));
+ if (!SPIF_CMP_IS_EQUAL(c)) {
+ return c;
+ }
+ } else {
+ return SPIF_CMP_FROM_INT(strcasecmp(buff1, buff2));
+ }
+ }
+
+ /* We've reached the end of one of the strings. */
+ if (*v1) {
+ if (!BEG_STRCASECMP(v1, "snap") || !BEG_STRCASECMP(v1, "pre")
+ || !BEG_STRCASECMP(v1, "alpha") || !BEG_STRCASECMP(v1, "beta")) {
+ return SPIF_CMP_LESS;
+ } else {
+ return SPIF_CMP_GREATER;
+ }
+ } else if (*v2) {
+ if (!BEG_STRCASECMP(v2, "snap") || !BEG_STRCASECMP(v2, "pre")
+ || !BEG_STRCASECMP(v2, "alpha") || !BEG_STRCASECMP(v2, "beta")) {
+ return SPIF_CMP_GREATER;
+ } else {
+ return SPIF_CMP_LESS;
+ }
+ }
+ return SPIF_CMP_EQUAL;
+}
diff --git a/src/tok.c b/src/tok.c
index c4427d7..11f7fc0 100644
--- a/src/tok.c
+++ b/src/tok.c
@@ -178,11 +178,13 @@ spif_tok_eval(spif_tok_t self)
const char *pstr, *delim = NULL;
spif_str_t tmp;
char quote;
+ size_t len;
if (SPIF_STR_ISNULL(self->src)) {
return FALSE;
}
pstr = SPIF_CAST_C(const char *) SPIF_STR_STR(SPIF_STR(self->src));
+ len = spif_str_get_len(SPIF_STR(self->src));
if (!SPIF_STR_ISNULL(self->sep)) {
delim = SPIF_CAST_C(const char *) SPIF_STR_STR(SPIF_STR(self->sep));
@@ -199,7 +201,7 @@ spif_tok_eval(spif_tok_t self)
/* The outermost for loop is where we traverse the string. Each new
word brings us back to the top where we resize our string list. */
for (quote = 0; *pstr; ) {
- tmp = spif_str_new_from_buff("", 4096);
+ tmp = spif_str_new_from_buff("", len);
spif_str_clear(tmp, 0);
/* This for loop is where we process each character. */
@@ -230,6 +232,7 @@ spif_tok_eval(spif_tok_t self)
/* Reallocate the new string to be just the right size. */
spif_str_trim(tmp);
+ len -= spif_str_get_len(tmp);
/* Add it to the list */
SPIF_LIST_APPEND(self->tokens, tmp);
diff --git a/test/test.c b/test/test.c
index 0e325a3..8d60dd7 100644
--- a/test/test.c
+++ b/test/test.c
@@ -221,6 +221,24 @@ test_strings(void)
free_array(SPIF_CAST(ptr) slist, 5);
TEST_PASS();
+ TEST_BEGIN("version_compare() function");
+ TEST_FAIL_IF(!SPIF_CMP_IS_LESS(version_compare("1.0", "1.0.1")));
+ TEST_FAIL_IF(!SPIF_CMP_IS_LESS(version_compare("2.9.99", "3.0")));
+ TEST_FAIL_IF(!SPIF_CMP_IS_LESS(version_compare("3.0", "29.9.9")));
+ TEST_FAIL_IF(!SPIF_CMP_IS_LESS(version_compare("1.0pre2", "1.0")));
+ TEST_FAIL_IF(!SPIF_CMP_IS_GREATER(version_compare("0.5.3", "0.5.3snap4")));
+ TEST_FAIL_IF(!SPIF_CMP_IS_GREATER(version_compare("2.2.4", "2.2.4beta3")));
+ TEST_FAIL_IF(!SPIF_CMP_IS_GREATER(version_compare("2.2.4beta3", "2.2.4alpha7")));
+ TEST_FAIL_IF(!SPIF_CMP_IS_GREATER(version_compare("1.27.3", "1.13.1")));
+ TEST_FAIL_IF(!SPIF_CMP_IS_GREATER(version_compare("0.10", "0.9.2")));
+ TEST_FAIL_IF(!SPIF_CMP_IS_GREATER(version_compare("2.3.2a", "2.3.2")));
+ TEST_FAIL_IF(!SPIF_CMP_IS_GREATER(version_compare("4.0p1", "4.0")));
+ TEST_FAIL_IF(!SPIF_CMP_IS_EQUAL(version_compare("3.4.5", "3.4.5")));
+ TEST_FAIL_IF(!SPIF_CMP_IS_EQUAL(version_compare("1.2.0b3", "1.2.0b3")));
+ TEST_FAIL_IF(!SPIF_CMP_IS_EQUAL(version_compare("2.0alpha", "2.0alpha")));
+ TEST_FAIL_IF(!SPIF_CMP_IS_EQUAL(version_compare("5.4pre1", "5.4pre1")));
+ TEST_PASS();
+
TEST_PASSED("string");
return 0;
}