567 /* this function was taken from rpm 4.0.4 and rewritten */ 568 int _alpm_versioncmp(const char *a, const char *b) 569 { 570 char str1[64], str2[64]; 571 char *ptr1, *ptr2; 572 char *one, *two; 573 char *rel1 = NULL, *rel2 = NULL; 574 char oldch1, oldch2; 575 int is1num, is2num; 576 int rc; 577 578 ALPM_LOG_FUNC; 579 580 if(!strcmp(a,b)) { 581 return(0); 582 } 583 584 strncpy(str1, a, 64); 585 str1[63] = 0; 586 strncpy(str2, b, 64); 587 str2[63] = 0; 588 589 /* lose the release number */ 590 for(one = str1; *one && *one != '-'; one++); 591 if(one) { 592 *one = '\0'; 593 rel1 = ++one; 594 } 595 for(two = str2; *two && *two != '-'; two++); 596 if(two) { 597 *two = '\0'; 598 rel2 = ++two; 599 } 600 601 one = str1; 602 two = str2; 603 604 while(*one || *two) { 605 while(*one && !isalnum((int)*one)) one++; 606 while(*two && !isalnum((int)*two)) two++; 607 608 ptr1 = one; 609 ptr2 = two; 610 611 /* find the next segment for each string */ 612 if(isdigit((int)*ptr1)) { 613 is1num = 1; 614 while(*ptr1 && isdigit((int)*ptr1)) ptr1++; 615 } else { 616 is1num = 0; 617 while(*ptr1 && isalpha((int)*ptr1)) ptr1++; 618 } 619 if(isdigit((int)*ptr2)) { 620 is2num = 1; 621 while(*ptr2 && isdigit((int)*ptr2)) ptr2++; 622 } else { 623 is2num = 0; 624 while(*ptr2 && isalpha((int)*ptr2)) ptr2++; 625 } 626 627 oldch1 = *ptr1; 628 *ptr1 = '\0'; 629 oldch2 = *ptr2; 630 *ptr2 = '\0'; 631 632 /* see if we ran out of segments on one string */ 633 if(one == ptr1 && two != ptr2) { 634 return(is2num ? -1 : 1); 635 } 636 if(one != ptr1 && two == ptr2) { 637 return(is1num ? 1 : -1); 638 } 639 640 /* see if we have a type mismatch (ie, one is alpha and one is digits) */ 641 if(is1num && !is2num) return(1); 642 if(!is1num && is2num) return(-1); 643 644 if(is1num) while(*one == '0') one++; 645 if(is2num) while(*two == '0') two++; 646 647 rc = strverscmp(one, two); 648 if(rc) return(rc); 649 650 *ptr1 = oldch1; 651 *ptr2 = oldch2; 652 one = ptr1; 653 two = ptr2; 654 } 655 656 if((!*one) && (!*two)) { 657 /* compare release numbers */ 658 if(rel1 && rel2 && strlen(rel1) && strlen(rel2)) return(_alpm_versioncmp(rel1, rel2)); 659 return(0); 660 } 661 662 return(*one ? 1 : -1); 663 }