index : pacman | |
Archlinux32 fork of pacman | gitolite user |
summaryrefslogtreecommitdiff |
-rw-r--r-- | lib/libalpm/package.c | 171 |
diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c index ed6d71d0..becbc60f 100644 --- a/lib/libalpm/package.c +++ b/lib/libalpm/package.c @@ -604,177 +604,6 @@ alpm_list_t SYMEXPORT *alpm_pkg_compute_requiredby(pmpkg_t *pkg) return(reqs); } -/** Compare two version strings and determine which one is 'newer'. - * Returns a value comparable to the way strcmp works. Returns 1 - * if a is newer than b, 0 if a and b are the same version, or -1 - * if b is newer than a. - * - * This function has been adopted from the rpmvercmp function located - * at lib/rpmvercmp.c, and was most recently updated against rpm - * version 4.4.2.3. Small modifications have been made to make it more - * consistent with the libalpm coding style. - * - * Keep in mind that the pkgrel is only compared if it is available - * on both versions handed to this function. For example, comparing - * 1.5-1 and 1.5 will yield 0; comparing 1.5-1 and 1.5-2 will yield - * -1 as expected. This is mainly for supporting versioned dependencies - * that do not include the pkgrel. - */ -int SYMEXPORT alpm_pkg_vercmp(const char *a, const char *b) -{ - char oldch1, oldch2; - char *str1, *str2; - char *ptr1, *ptr2; - char *one, *two; - int rc; - int isnum; - int ret = 0; - - ALPM_LOG_FUNC; - - /* libalpm added code. ensure our strings are not null */ - if(!a) { - if(!b) return(0); - return(-1); - } - if(!b) return(1); - - /* easy comparison to see if versions are identical */ - if(strcmp(a, b) == 0) return(0); - - str1 = strdup(a); - str2 = strdup(b); - - one = str1; - two = str2; - - /* loop through each version segment of str1 and str2 and compare them */ - while(*one && *two) { - while(*one && !isalnum((int)*one)) one++; - while(*two && !isalnum((int)*two)) two++; - - /* If we ran to the end of either, we are finished with the loop */ - if(!(*one && *two)) break; - - ptr1 = one; - ptr2 = two; - - /* grab first completely alpha or completely numeric segment */ - /* leave one and two pointing to the start of the alpha or numeric */ - /* segment and walk ptr1 and ptr2 to end of segment */ - if(isdigit((int)*ptr1)) { - while(*ptr1 && isdigit((int)*ptr1)) ptr1++; - while(*ptr2 && isdigit((int)*ptr2)) ptr2++; - isnum = 1; - } else { - while(*ptr1 && isalpha((int)*ptr1)) ptr1++; - while(*ptr2 && isalpha((int)*ptr2)) ptr2++; - isnum = 0; - } - - /* save character at the end of the alpha or numeric segment */ - /* so that they can be restored after the comparison */ - oldch1 = *ptr1; - *ptr1 = '\0'; - oldch2 = *ptr2; - *ptr2 = '\0'; - - /* this cannot happen, as we previously tested to make sure that */ - /* the first string has a non-null segment */ - if (one == ptr1) { - ret = -1; /* arbitrary */ - goto cleanup; - } - - /* take care of the case where the two version segments are */ - /* different types: one numeric, the other alpha (i.e. empty) */ - /* numeric segments are always newer than alpha segments */ - /* XXX See patch #60884 (and details) from bugzilla #50977. */ - if (two == ptr2) { - ret = isnum ? 1 : -1; - goto cleanup; - } - - if (isnum) { - /* this used to be done by converting the digit segments */ - /* to ints using atoi() - it's changed because long */ - /* digit segments can overflow an int - this should fix that. */ - - /* throw away any leading zeros - it's a number, right? */ - while (*one == '0') one++; - while (*two == '0') two++; - - /* whichever number has more digits wins */ - if (strlen(one) > strlen(two)) { - ret = 1; - goto cleanup; - } - if (strlen(two) > strlen(one)) { - ret = -1; - goto cleanup; - } - } - - /* strcmp will return which one is greater - even if the two */ - /* segments are alpha or if they are numeric. don't return */ - /* if they are equal because there might be more segments to */ - /* compare */ - rc = strcmp(one, two); - if (rc) { - ret = rc < 1 ? -1 : 1; - goto cleanup; - } - - /* restore character that was replaced by null above */ - *ptr1 = oldch1; - one = ptr1; - *ptr2 = oldch2; - two = ptr2; - - /* libalpm added code. check if version strings have hit the pkgrel - * portion. depending on which strings have hit, take correct action. - * this is all based on the premise that we only have one dash in - * the version string, and it separates pkgver from pkgrel. */ - if(*ptr1 == '-' && *ptr2 == '-') { - /* no-op, continue comparing since we are equivalent throughout */ - } else if(*ptr1 == '-') { - /* ptr1 has hit the pkgrel and ptr2 has not. continue version - * comparison after stripping the pkgrel from ptr1. */ - *ptr1 = '\0'; - } else if(*ptr2 == '-') { - /* ptr2 has hit the pkgrel and ptr1 has not. continue version - * comparison after stripping the pkgrel from ptr2. */ - *ptr2 = '\0'; - } - } - - /* this catches the case where all numeric and alpha segments have */ - /* compared identically but the segment separating characters were */ - /* different */ - if ((!*one) && (!*two)) { - ret = 0; - goto cleanup; - } - - /* the final showdown. we never want a remaining alpha string to - * beat an empty string. the logic is a bit weird, but: - * - if one is empty and two is not an alpha, two is newer. - * - if one is an alpha, two is newer. - * - otherwise one is newer. - * */ - if ( ( !*one && !isalpha((int)*two) ) - || isalpha((int)*one) ) { - ret = -1; - } else { - ret = 1; - } - -cleanup: - free(str1); - free(str2); - return(ret); -} - /** @} */ pmpkg_t *_alpm_pkg_new(void) |