pmalek
5/4/2016 - 10:02 AM

compare version c string like "1.2.10"

compare version c string like "1.2.10"

#include <stdlib.h>
#include <string.h>
#include <assert.h>

/*
 * Function used to compare version c strings like: "1.2.3" or "12.9.1314214"
 */
int compare_versions(char* first, char* second)
{
  size_t first_last_dot1 = 0;
  size_t first_last_dot2 = strcspn(first, ".");
  size_t second_last_dot1 = 0;
  size_t second_last_dot2 = strcspn(second, ".");

  char* first_c = (char*)calloc(first_last_dot2 + 1, sizeof(char));
  char* second_c = (char*)calloc(second_last_dot2 + 1, sizeof(char));
  int first_max = first_last_dot2;
  int second_max = second_last_dot2;

  while(first_last_dot2 || second_last_dot2)
  {
    // first longer than second ( different only by last segment )
    if(first_last_dot2 && !second_last_dot2) {
      free(first_c);
      free(second_c);
      return 1;
    }
    // second longer than first ( different only by last segment )
    if(!first_last_dot2 && second_last_dot2) {
      free(first_c);
      free(second_c);
      return -1;
    }

    if(first_last_dot2 > first_max) {
      first_max = first_last_dot2;
      first_c = (char*)realloc(first_c, first_last_dot2 + 1);
    }
    memset(first_c, 0, first_last_dot2);
    strncat(first_c, first + first_last_dot1, first_last_dot2);
    int first_n = atoi(first_c);
    first_last_dot1 += first_last_dot2 + 1;
    first_last_dot2 = strcspn(first + first_last_dot1, ".");

    if(second_last_dot2 > second_max) {
      second_max = second_last_dot2;
      second_c = (char*)realloc(second_c, second_last_dot2 + 1);
    }
    memset(second_c, 0, second_last_dot2);
    strncat(second_c, second + second_last_dot1, second_last_dot2);
    int second_n = atoi(second_c);
    second_last_dot1 += second_last_dot2 + 1;
    second_last_dot2 = strcspn(second + second_last_dot1, ".");

    if (first_n != second_n)
    {
      free(first_c);
      free(second_c);
      if(first_n < second_n) return -1;
      return 1;
    }
  }

  free(first_c);
  free(second_c);
  return 0;
}

int main()
{
  assert(0 == compare_versions("1.12345678.2", "1.12345678.2"));
  assert(-1 == compare_versions("1", "1.0"));
  assert(0 == compare_versions("1", "1"));
  assert(0 == compare_versions("1.11.2", "1.11.2"));
  assert(1 == compare_versions("1.3", "1.2"));
  assert(-1 == compare_versions("4.1", "4.88"));
  assert(1 == compare_versions("44.9.1", "44.8.2"));
  assert(0 == compare_versions("1.11.24.5.123.12314214", "1.11.24.5.123.12314214"));
  assert(-1 == compare_versions("1.11.24.5.123.12314214", "1.11.24.5.123.12314215"));
  assert(1 == compare_versions("1.11.24.5.123.123142199", "1.11.24.5.123.12314215"));

  return 0;
}