--- /dev/null
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+struct ver {
+ char str[1024]; /* string rep */
+ char *s; /* start component */
+ int cn; /* current component number */
+ char *next; /* start of potential next component */
+ char keep; /* character over-written with null byte */
+ int sep; /* number of characters in separator */
+
+ int nv; /* numeric value */
+ int type; /* 0 null, 1 text, 2 numeric */
+ int release;
+ char *relstr;
+};
+
+void init_ver(struct ver *v, char *s) {
+ strncpy(v->str, s, 1023);
+ v->str[1023] = 0;
+ v->s = 0;
+ v->cn = 0;
+ v->next = v->str;
+ v->relstr = 0;
+ v->keep = 0;
+ v->sep = 0;
+
+ /* scan for trailing release */
+ int n;
+ n = strlen(v->str) - 1;
+ if (n > 0 && isdigit(v->str[n])) {
+ while (isdigit(v->str[n])) {
+ n--;
+ }
+ if (s[n] == '-') {
+ v->relstr = v->str + n;
+ v->release = atoi(v->str + n + 1);
+ v->str[n] = 0;
+ }
+ }
+
+}
+
+int ver_cmp(struct ver *a, struct ver *b) {
+ if (a->type == 0 && b->type == 0) {
+ return 0;
+ }
+ if (a->type != b->type) {
+ return a->type < b->type ? -1 : 1;
+ }
+ if (a->type == 1) {
+ int cmp;
+ cmp = strcmp(a->s, b->s);
+ if (cmp == 0) {
+ return 0;
+ }
+ return cmp < 0 ? -1 : 1;
+ }
+ if (a->type == 2) {
+ if (a->nv != b->nv)
+ return a->nv < b->nv ? -1 : 1;
+ }
+ return 0;
+}
+
+int next_comp(struct ver *v) {
+ char *s;
+
+ /* restore over-written character */
+ if (v->keep) {
+ v->next[0] = v->keep;
+ v->keep = 0;
+ }
+ s = v->next;
+
+ /* skip over anything that isn't alphanumeric */
+ v->sep = 0;
+ while (*s && !isalnum(*s)) {
+ v->sep++;
+ s++;
+ }
+ v->next = s;
+
+ /* zero return if at end of string */
+ if (!*s) {
+ return 0;
+ }
+ if (isdigit(*s)) {
+ v->type = 2;
+ while (isdigit(*s)) s++;
+ v->keep = *s;
+ *s = 0;
+ v->s = v->next;
+ v->nv = atoi(v->s);
+ } else if (isalpha(*s)) {
+ v->type = 1;
+ while (isalpha(*s)) s++;
+ v->keep = *s;
+ *s = 0;
+ v->s = v->next;
+ }
+ v->next = s;
+
+ return ++v->cn;
+}
+
+/*
+ * alphabetic less than numeric
+ */
+int main(int ac, char *av[]) {
+ struct ver a, b;
+ int an, bn;
+ int cmp;
+
+ if (ac < 2) return 1;
+
+ init_ver(&a, av[1]);
+ init_ver(&b, av[2]);
+ do {
+ an = next_comp(&a);
+ bn = next_comp(&b);
+ if (an != bn) {
+ if (an == 0 && a.type == 2 && b.sep == 0 && b.type == 1) {
+ printf("1\n");
+ } else if (bn == 0 && b.type == 2 && a.sep == 0 && a.type == 1) {
+ printf("-1\n");
+ } else {
+ printf("%s\n", an < bn ? "-1" : "1");
+ }
+ exit(0);
+ }
+ cmp = ver_cmp(&a, &b);
+ if (cmp != 0) {
+ printf("%d\n", cmp);
+ exit(0);
+ }
+ } while (an && bn);
+
+ /* if we've gotten here, and both have releases, check those */
+ if (a.relstr && b.relstr && a.release != b.release) {
+ printf("%s\n", a.release < b.release ? "-1" : "1");
+ exit(0);
+ }
+
+ printf("0\n");
+ return 0;
+}