Should fix rhbz#896090 while NOT breaking rhbz#730887
--
vda
diff -x '*.po' -d -urpN libreport.0/src/lib/parse_release.c
libreport.1/src/lib/parse_release.c
--- libreport.0/src/lib/parse_release.c 2013-01-10 14:18:05.000000000 +0100
+++ libreport.1/src/lib/parse_release.c 2013-01-23 16:32:46.558850018 +0100
@@ -18,8 +18,34 @@
*/
#include "internal_libreport.h"
+/* Houston, we have a problem.
+ *
+ * Mapping from OS release string to (product,version) string tuple
+ * in different bug databases is non-trivial, and differs from DB to DB.
+ * OTOH, it does have a lot of similarities too, making it worthwhile
+ * to use a common function for parsing.
+ *
+ * To accomodate this, parse_release() takes a flag parameter
+ * with two types of bits:
+ *
+ * - some bits indicate a specific tweak to parsing algorithm (such as
+ * "remove everything after numeric version").
+ *
+ * - if there is a bug DB which requires a quirk not easily describable
+ * by a combination of aforementioned bits, it gets its own bit
+ * "parse OS release for bug database XYZ" (so far we have none).
+ *
+ * In order to not torture API users with the need to know these bits,
+ * we have convenience functions parse_release_for_XYZ()
+ * which call parse_release() with correct bits.
+ */
+enum {
+ APPEND_MAJOR_VER_TO_RHEL_PRODUCT = 1 << 0,
+ RETAIN_ALPHA_BETA_TAIL_IN_VER = 1 << 1,
+};
+
// caller is reposible for freeing *product* and *version*
-static void parse_release(const char *release, char** product, char** version,
bool append_rhel_version)
+static void parse_release(const char *release, char** product, char** version,
int flags)
{
if (strstr(release, "Rawhide"))
{
@@ -29,21 +55,29 @@ static void parse_release(const char *re
return;
}
+ bool it_is_rhel = false;
+
struct strbuf *buf_product = strbuf_new();
if (strstr(release, "Fedora"))
+ {
strbuf_append_str(buf_product, "Fedora");
+ }
else if (strstr(release, "Red Hat Enterprise Linux"))
+ {
strbuf_append_str(buf_product, "Red Hat Enterprise Linux");
+ it_is_rhel = true;
+ }
else
{
/* TODO: add logic for parsing other distros' names here */
strbuf_append_str(buf_product, release);
}
- /* examples of release strings:
- * installed system: Red Hat Enterprise Linux Server release 6.2 Beta
(Santiago)
- * anaconda: Red Hat Enterprise Linux 6.2
+ /* Examples of release strings:
+ * installed system: "Red Hat Enterprise Linux Server release 6.2 Beta
(Santiago)"
+ * anaconda: "Red Hat Enterprise Linux 6.2"
*/
+ struct strbuf *buf_version = strbuf_new();
const char *r = strstr(release, "release");
const char *space = r ? strchr(r, ' ') : NULL;
if (!space)
@@ -57,25 +91,48 @@ static void parse_release(const char *re
space++;
}
}
-
- struct strbuf *buf_version = strbuf_new();
if (space)
{
space++;
/* observed also: "Fedora F16-Alpha" rhbz#730887 */
- while (isdigit(*space) || *space == '.')
+ while ((*space >= '0' && *space <= '9') || *space == '.')
{
/* Eat string like "5.2" */
strbuf_append_char(buf_version, *space);
- if (append_rhel_version
- && strcmp(buf_product->buf, "Red Hat Enterprise Linux") == 0
- ) {
- strbuf_append_char(buf_product, ' ');
- strbuf_append_char(buf_product, *space);
- }
- append_rhel_version = false;
space++;
}
+
+ if (flags & RETAIN_ALPHA_BETA_TAIL_IN_VER)
+ {
+ /* Example: "... 6.2 [Beta ](Santiago)".
+ * 'space' variable points to non-digit char after "2".
+ * We assume that non-parenthesized text is "Alpha"/"Beta"/etc.
+ * If this text is only whitespace, we won't append it.
+ */
+ const char *to_append = space;
+ while (*space && *space != '(') /* go to '(' */
+ space++;
+ while (space > to_append && space[-1] == ' ') /* back to 1st
non-space */
+ space--;
+ strbuf_append_strf(buf_version, "%.*s", (int)(space - to_append),
to_append);
+ }
+ }
+
+ if ((flags & APPEND_MAJOR_VER_TO_RHEL_PRODUCT) && it_is_rhel)
+ {
+ char *v = buf_version->buf;
+
+ /* Append "integer part" of version to product:
+ * "10.2<anything>" -> append " 10"
+ * "10 <anything>" -> append " 10"
+ * "10" -> append " 10"
+ * "10abcde" -> append ?????
+ */
+ unsigned idx_dot = strchrnul(v, '.') - v;
+ unsigned idx_space = strchrnul(v, ' ') - v;
+ strbuf_append_strf(buf_product, " %.*s",
+ (idx_dot < idx_space ? idx_dot : idx_space), v
+ );
}
*version = strbuf_free_nobuf(buf_version);
@@ -86,12 +143,43 @@ static void parse_release(const char *re
void parse_release_for_bz(const char *release, char** product, char** version)
{
- /* Fedora/RH bugzilla uses "Red Hat Enterprise Linux N" product RHEL */
- parse_release(release, product, version, /*append_rhel_version:*/ true);
+ /* Fedora/RH bugzilla uses "Red Hat Enterprise Linux N" product for RHEL */
+ parse_release(release, product, version, 0
+ | APPEND_MAJOR_VER_TO_RHEL_PRODUCT
+ );
}
+/*
+ * Note to developers: you can use
+ * curl --silent -u $USER:$PASS
"https://api.access.redhat.com/rs/products/Red%20Hat%20Enterprise%20Linux/versions"
| xmllint --format -
+ * to query RHTS for valid set of versions. Currently (2013-01) I get:
+ * <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+ * <versions xmlns="http://www.redhat.com/gss/strata">
+ * <version>3 - ELS</version>
+ * <version>4</version>
+ * <version>4 - ELS</version>
+ * <version>5.0</version>
+ * <version>5.1</version>
+ * <version>5.2</version>
+ * <version>5.3</version>
+ * <version>5.4</version>
+ * <version>5.5</version>
+ * <version>5.6</version>
+ * <version>5.7</version>
+ * <version>5.8</version>
+ * <version>5.9</version>
+ * <version>6.0</version>
+ * <version>6.1</version>
+ * <version>6.2</version>
+ * <version>6.3</version>
+ * <version>6.4 Beta</version>
+ * <version>7.0 Alpha-2</version>
+ * <version>Unknown</version>
+ * </versions>
+ */
void parse_release_for_rhts(const char *release, char** product, char**
version)
{
- /* RHTS uses "Red Hat Enterprise Linux" product for RHEL */
- parse_release(release, product, version, /*append_rhel_version:*/ false);
+ parse_release(release, product, version, 0
+ | RETAIN_ALPHA_BETA_TAIL_IN_VER
+ );
}
diff -x '*.po' -d -urpN libreport.0/tests/osrelease.at
libreport.1/tests/osrelease.at
--- libreport.0/tests/osrelease.at 2013-01-10 14:18:05.000000000 +0100
+++ libreport.1/tests/osrelease.at 2013-01-23 16:52:05.136844531 +0100
@@ -113,7 +113,8 @@ int main(void)
{
char *releases_good[7][3] =
{
- {"Red Hat Enterprise Linux Server release 6.2 Beta (Santiago)", "Red
Hat Enterprise Linux", "6.2"},
+ {"Red Hat Enterprise Linux Server release 6.2 Beta (Santiago)", "Red
Hat Enterprise Linux", "6.2 Beta"},
+ {"Red Hat Enterprise Linux Server release 6.2 (Santiago)", "Red Hat
Enterprise Linux", "6.2"},
{"Red Hat Enterprise Linux 6.2", "Red Hat Enterprise Linux", "6.2"},
};