Hello Hackers,

this is probably not the right list, but I'd like to collect reviews of a strverscmp(3) function I wrote. It is used by the graphics/gqview port (if present in libc) and since I want/need that functionality I whipped up a somewhat working version.

It tries to sort strings like "jan1", "jan2", "jan10", etc. into the "natural" order.

Is there a chance this might get included into libc? Or is it considered bloat?

The GNU version can be found here
http://refspecs.freestandards.org/LSB_2.0.1/LSB-generic/LSB-generic/baselib-strverscmp.html

Quite frankly, I don't understand their integral/fraction distinction, and my version differs in that regard. See the return values of the attached sample code.

Ulrich Spoerlein
--
 PGP Key ID: 20FEE9DD                           Encrypted mail welcome!
Fingerprint: AEC9 AF5E 01AC 4EE1 8F70  6CBD E76E 2227 20FE E9DD
Which is worse: ignorance or apathy?
Don't know. Don't care.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>

#ifdef __FreeBSD__
int
strverscmp(const char *s1, const char *s2);

int
strverscmp(const char *s1, const char *s2)
{
  static const char *digits = "0123456789";
  int ret;
  long n1, n2;
  size_t p1, p2;

  do {
    p1 = strcspn(s1, digits);
    p2 = strcspn(s2, digits);
  
    /* Different prefix */
    if ((ret = strncmp(s1, s2, p1)) != 0)
      return ret;

    s1 += p1;
    s2 += p2;
    n1 = strtol(s1, NULL, 10);
    n2 = strtol(s2, NULL, 10);
    
    if (n1 < n2)
      return -1;
    else if (n1 > n2)
      return 1;

    /* Numbers are equal or not present, try with next ones. */
    p1 = strspn(s1, digits);
    p2 = strspn(s2, digits);
    s1 += p1;
    s2 += p2;
  } while (p1 == p2 && p1 != 0 && p1 != 0);
  
  return strcmp(s1, s2);
}
#endif

int
main(int argc, char **argv)
{
  char **array, *temp;
  int i, j, n = 10;

  array = (char **) calloc(n, sizeof(char *));
  array[0] = strdup("jan2");
  array[1] = strdup("jan10");
  array[2] = strdup("jan");
  array[3] = strdup("jan0a");
  array[4] = strdup("jan17b");
  array[5] = strdup("jan17a");
  array[6] = strdup("jan17x1234");
  array[7] = strdup("jan17x123");
  array[8] = strdup("jan17x123a");
  array[9] = strdup("jan9");

  /* Bubble sort */
  for (i=0; i<n; ++i) {
    for (j=i; j<n; ++j) {
      if (strverscmp(array[i], array[j]) > 0) {
        temp = array[j];
        array[j] = array[i];
        array[i] = temp;
      }
    }
  }

  for (i=0; i<n; ++i) {
    printf("%s\n", array[i]);
  }

  printf("%d\n", strverscmp("a", "a"));
  printf("%d\n", strverscmp("item#99", "item#100"));
  printf("%d\n", strverscmp("alpha1", "alpha001"));
  printf("%d\n", strverscmp("part1_f012", "part1_f01"));
  printf("%d\n", strverscmp("foo.009", "foo.0"));

  return 0;
}

Attachment: pgpREa1U5fcJv.pgp
Description: PGP signature

Reply via email to