Revision cac80f49
Added by Phil Davis almost 10 years ago
etc/inc/pkg-utils.inc | ||
---|---|---|
209 | 209 |
return array(); |
210 | 210 |
} |
211 | 211 |
|
212 |
/****f* pkg-utils/compare_pkg_versions |
|
213 |
* NAME |
|
214 |
* compare_pkg_versions - Decide if the installed package is newer, the same or older than the available package. |
|
215 |
* INPUTS |
|
216 |
* $installed_pkg_ver - the package version installed on the system. |
|
217 |
* $available_pkg_ver - the package version available from the package server. |
|
218 |
* RESULT |
|
219 |
* -1 - the installed package is older (an upgrade is available) |
|
220 |
* 0 - the package versions are the same |
|
221 |
* 1 - the installed package is newer (somebody has installed a newer version than is officially available) |
|
222 |
******/ |
|
223 |
function compare_pkg_versions($installed_pkg_ver, $available_pkg_ver) { |
|
224 |
// If the strings are the same then short-cut all the processing. |
|
225 |
if (strcmp($installed_pkg_ver, $available_pkg_ver) == 0) { |
|
226 |
return 0; |
|
227 |
} |
|
228 |
|
|
229 |
// Split into pieces that are groups of digits and groups of non-digits. |
|
230 |
$installed_arr = preg_split( '/([0-9]+)/', $installed_pkg_ver, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); |
|
231 |
$available_arr = preg_split( '/([0-9]+)/', $available_pkg_ver, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); |
|
232 |
foreach ($installed_arr as $n => $val) { |
|
233 |
if (array_key_exists($n, $available_arr)) { |
|
234 |
// Check if this piece looks like a genuine integer like "123", "0" rather than "05", "005", "1a", "abc". |
|
235 |
// Note: At this point the pieces cannot be like "-1", "+1" so we do not need to worry about those possibilities that filter_var() will see as "genuine integers". |
|
236 |
$val1_as_int = filter_var($val, FILTER_VALIDATE_INT); |
|
237 |
$val2_as_int = filter_var($available_arr[$n], FILTER_VALIDATE_INT); |
|
238 |
if (($val1_as_int === false) || ($val2_as_int === false)) { |
|
239 |
// One of them does not look like a genuine integer so use string comparison. |
|
240 |
if (strcmp($val, $available_arr[$n]) > 0) { |
|
241 |
return 1; |
|
242 |
} elseif (strcmp($val, $available_arr[$n]) < 0) { |
|
243 |
return -1; |
|
244 |
} |
|
245 |
} else { |
|
246 |
// Both look like genuine integers so compare as numbers. |
|
247 |
if ($val1_as_int > $val2_as_int) { |
|
248 |
return 1; |
|
249 |
} elseif ($val1_as_int < $val2_as_int) { |
|
250 |
return -1; |
|
251 |
} |
|
252 |
} |
|
253 |
} else { |
|
254 |
// The installed package version is greater, since all components have matched up to this point |
|
255 |
// and available_arr doesn't have any more data. |
|
256 |
return 1; |
|
257 |
} |
|
258 |
} |
|
259 |
|
|
260 |
if (count($available_arr) > count($installed_arr)) { |
|
261 |
// All the installed package components matched the corresponding available package components. |
|
262 |
// The available package is longer than the installed package, so the installed package is old. |
|
263 |
return -1; |
|
264 |
} else { |
|
265 |
// Both versions are of equal length and value. |
|
266 |
return 0; |
|
267 |
} |
|
268 |
|
|
269 |
return $resp ? $resp : array(); |
|
270 |
} |
|
271 |
|
|
212 | 272 |
/* |
213 | 273 |
* resync_all_package_configs() Force packages to setup their configuration and rc.d files. |
214 | 274 |
* This function may also print output to the terminal indicating progress. |
Also available in: Unified diff
Provide compare_pkg_versions
This function parses and compares two strings to see which one seems to represent the greater "version". It splits the strings into pieces that are digits and pieces that are anything else. e.g.
"utility-24.9_5 pkg v4.5"
becomes
"utility-"
24
"."
9
"_"
5
" pkg v"
4
"."
5
A new version might be:
"utility-24.10_5 pkg v4.5"
Each component is compared.
If both corresponding components are "integer chunks" they are compared using "<" and ">" - that means that 10 becomes greater than 9.
If either component is not "integer" then string comparison is done. This makes the ordinary string changes work as expected and also stuff like "1.05" and "1.1" - a change like this will be seen as an upgrade.
Not that I have left the string comparison case-sensitive. If someone making their version string changes the "fixed text" they have put in the version string then anything is possible :) It is a bit difficult to guess all of that.
Also if people use alphabetic versioning that does not follow strcmp() sort order then there is always trouble - it works by luck with "-BETA" then "-RELEASE" because the English words happen to sort as expected.