misc: Add cr_str_to_nevr() and cr_str_to_nevra() and types cr_NEVR and cr_NEVRA
authorTomas Mlcoch <tmlcoch@redhat.com>
Tue, 8 Jul 2014 11:36:13 +0000 (13:36 +0200)
committerTomas Mlcoch <tmlcoch@redhat.com>
Wed, 16 Jul 2014 11:58:04 +0000 (13:58 +0200)
src/misc.c
src/misc.h
tests/test_misc.c

index 2976cb1..fbb70ad 100644 (file)
@@ -1055,6 +1055,130 @@ cr_nvrea_free(struct cr_NVREA *nvrea)
 }
 
 
+cr_NEVR *
+cr_str_to_nevr(const char *instr)
+{
+    cr_NEVR *nevr = NULL;
+    gchar *str, *copy;
+    size_t len;
+    int i;
+
+    if (!instr)
+        return NULL;
+
+    nevr = g_new0(cr_NEVR, 1);
+    copy = str = g_strdup(instr);
+    len = strlen(str);
+
+    // Get release
+    for (i = len-1; i >= 0; i--)
+        if (str[i] == '-') {
+            nevr->release = g_strdup(str+i+1);
+            str[i] = '\0';
+            len = i;
+            break;
+        }
+
+    int epoch = 1;
+
+    // Get version
+    for (i = len-1; i >= 0; i--)
+        if (str[i] == ':') {
+            nevr->version = g_strdup(str+i+1);
+            str[i] = '\0';
+            len = i;
+            break;
+        } else if (str[i] == '-') {
+            nevr->version = g_strdup(str+i+1);
+            str[i] = '\0';
+            len = i;
+            epoch = 0;
+            break;
+        }
+
+    // Get epoch
+    if (epoch) {
+        for (i = len-1; i >= 0; i--)
+            if (str[i] == '-') {
+                nevr->epoch = g_strdup(str+i+1);
+                str[i] = '\0';
+                break;
+            }
+    }
+
+    // Get name
+    nevr->name = g_strdup(str);
+    g_free(copy);
+
+    return nevr;
+}
+
+
+void
+cr_nevr_free(cr_NEVR *nevr)
+{
+    if (!nevr)
+        return;
+    g_free(nevr->name);
+    g_free(nevr->epoch);
+    g_free(nevr->version);
+    g_free(nevr->release);
+    g_free(nevr);
+}
+
+
+cr_NEVRA *
+cr_str_to_nevra(const char *instr)
+{
+    cr_NEVR *nevr;
+    cr_NEVRA *nevra = NULL;
+    gchar *str, *copy;
+    size_t len;
+    int i;
+
+    if (!instr)
+        return NULL;
+
+    nevra = g_new0(cr_NEVRA, 1);
+    copy = str = g_strdup(instr);
+    len = strlen(str);
+
+    // Get arch
+    for (i = len-1; i >= 0; i--)
+        if (str[i] == '.') {
+            nevra->arch = g_strdup(str+i+1);
+            str[i] = '\0';
+            len = i;
+            break;
+        }
+
+    nevr = cr_str_to_nevr(str);
+    nevra->name     = nevr->name;
+    nevra->epoch    = nevr->epoch;
+    nevra->version  = nevr->version;
+    nevra->release  = nevr->release;
+    g_free(nevr);
+
+    g_free(copy);
+
+    return nevra;
+}
+
+
+void
+cr_nevra_free(cr_NEVRA *nevra)
+{
+    if (!nevra)
+        return;
+    g_free(nevra->name);
+    g_free(nevra->epoch);
+    g_free(nevra->version);
+    g_free(nevra->release);
+    g_free(nevra->arch);
+    g_free(nevra);
+}
+
+
 int
 cr_compare_values(const char *str1, const char *str2)
 {
index c8c91eb..91b2148 100644 (file)
@@ -71,6 +71,21 @@ struct cr_NVREA {
     char *arch;         /*!< arch */
 };
 
+typedef struct {
+    char *name;
+    char *epoch;
+    char *version;
+    char *release;
+} cr_NEVR;
+
+typedef struct {
+    char *name;
+    char *epoch;
+    char *version;
+    char *release;
+    char *arch;
+} cr_NEVRA;
+
 /** Version representation
  * e.g. for openssl-devel-1.0.0i = version: 1, release: 0, patch: 0, suffix: i
  */
@@ -461,6 +476,32 @@ cr_append_pid_and_datetime(const char *str, const char *suffix);
 gboolean
 cr_spawn_check_exit_status(gint exit_status, GError **error);
 
+/** Parse NEVR (N-E:V-R) string.
+ * @param str           NEVR string
+ * @returns             Malloced cr_NEVR or NULL on error
+ */
+cr_NEVR *
+cr_str_to_nevr(const char *str);
+
+/** Free cr_NEVR
+ * @param nevr      cr_NEVR structure
+ */
+void
+cr_nevr_free(cr_NEVR *nevr);
+
+/** Parse NEVRA (N-E:V-R.A) string.
+ * @param str           NEVRA string
+ * @returns             Malloced cr_NEVRA or NULL on error
+ */
+cr_NEVRA *
+cr_str_to_nevra(const char *str);
+
+/** Free cr_NEVRA
+ * @param nevra     cr_NEVRA structure
+ */
+void
+cr_nevra_free(cr_NEVRA *nevra);
+
 /** @} */
 
 #ifdef __cplusplus
index 5f2604a..80dfacd 100644 (file)
@@ -983,7 +983,7 @@ test_cr_split_rpm_filename(void)
     res = cr_split_rpm_filename(NULL);
     g_assert(!res);
 
-    res = cr_split_rpm_filename("foo-1.0-1.i386.rpm");
+    res = cr_split_rpm_filename("foo-1.0-1.i386");
     g_assert(res);
     g_assert_cmpstr(res->name, ==, "foo");
     g_assert_cmpstr(res->version, ==, "1.0");
@@ -1022,6 +1022,49 @@ test_cr_split_rpm_filename(void)
 
 
 static void
+test_cr_str_to_nevr(void)
+{
+    cr_NEVR *res;
+
+    res = cr_str_to_nevr(NULL);
+    g_assert(!res);
+
+    res = cr_str_to_nevr("createrepo-0.9.9-22.fc20");
+    g_assert(res);
+    g_assert_cmpstr(res->name, ==, "createrepo");
+    g_assert_cmpstr(res->version, ==, "0.9.9");
+    g_assert_cmpstr(res->release, ==, "22.fc20");
+    g_assert(!res->epoch);
+    cr_nevr_free(res);
+
+    res = cr_str_to_nevr("bar:4-9-123a");
+    g_assert(res);
+    g_assert_cmpstr(res->name, ==, "bar");
+    g_assert_cmpstr(res->version, ==, "9");
+    g_assert_cmpstr(res->release, ==, "123a");
+    g_assert_cmpstr(res->epoch, ==, "4");
+    cr_nevr_free(res);
+
+    res = cr_str_to_nevr("a--.");
+    g_assert(res);
+    g_assert_cmpstr(res->name, ==, "a");
+    g_assert_cmpstr(res->version, ==, "");
+    g_assert_cmpstr(res->release, ==, ".");
+    g_assert(!res->epoch);
+    cr_nevr_free(res);
+
+    res = cr_str_to_nevr("b");
+    g_assert(res);
+    g_assert_cmpstr(res->name, ==, "b");
+    g_assert(!res->version);
+    g_assert(!res->release);
+    g_assert(!res->epoch);
+    cr_nevr_free(res);
+
+}
+
+
+static void
 test_cr_cmp_evr(void)
 {
     int res;
@@ -1124,6 +1167,8 @@ main(int argc, char *argv[])
             test_cr_cmp_version_str);
     g_test_add_func("/misc/test_cr_split_rpm_filename",
             test_cr_split_rpm_filename);
+    g_test_add_func("/misc/test_cr_str_to_nevr",
+            test_cr_str_to_nevr);
     g_test_add_func("/misc/test_cr_cmp_evr",
             test_cr_cmp_evr);