opkg: implement opkg_set_option() and opkg_get_option()
[oweals/opkg-lede.git] / libopkg / pkg.c
index fe9118f02ac5000027ea7a6aa8e6835f3d29576d..3038b4bd776cdb4b83ea7dab2d5f43bbf48ba48d 100644 (file)
@@ -1,4 +1,4 @@
-/* pkg.c - the itsy package management system
+/* pkg.c - the opkg package management system
 
    Carl D. Worth
 
@@ -15,7 +15,7 @@
    General Public License for more details.
 */
 
-#include "opkg.h"
+#include "includes.h"
 #include <ctype.h>
 #include <string.h>
 #include <errno.h>
@@ -206,6 +206,8 @@ void pkg_deinit(pkg_t *pkg)
      pkg->installed_files_ref_cnt = 1;
      pkg_free_installed_files(pkg);
      pkg->essential = 0;
+     free (pkg->tags);
+     pkg->tags = NULL;
 }
 
 int pkg_init_from_file(pkg_t *pkg, const char *filename)
@@ -522,6 +524,10 @@ char * pkg_formatted_info(pkg_t *pkg )
      strncat(buff ,line, strlen(line));
      free(line);
 
+     line = pkg_formatted_field(pkg, "Tags");
+     strncat(buff ,line, strlen(line));
+     free(line);
+
      return buff;
 }
 
@@ -937,6 +943,21 @@ char * pkg_formatted_field(pkg_t *pkg, const char *field )
          }
      }
          break;
+     case 't':
+     case 'T':
+         if (strcasecmp(field, "Tags") == 0) {
+              /* Tags */
+              if (pkg->tags) {
+                   temp = (char *)realloc(temp,strlen(pkg->tags)+8);
+                   if ( temp == NULL ){
+                     fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
+                     return NULL;
+                   }
+                   temp[0]='\0';
+                   snprintf(temp, (strlen(pkg->tags)+8), "Tags: %s\n", pkg->tags);
+              }
+         }
+         break;
      case 'v':
      case 'V': {
          /* Version */
@@ -1067,55 +1088,45 @@ int pkg_compare_versions(const pkg_t *pkg, const pkg_t *ref_pkg)
          return r;
      }
 
-#ifdef USE_DEBVERSION
      r = verrevcmp(pkg->revision, ref_pkg->revision);
      if (r) {
          return r;
      }
 
-     r = verrevcmp(pkg->familiar_revision, ref_pkg->familiar_revision);
-#endif
-
      return r;
 }
 
-int verrevcmp(const char *val, const char *ref)
-{
-     int vc, rc;
-     long vl, rl;
-     const char *vp, *rp;
-     const char *vsep, *rsep;
-    
-     if (!val) val= "";
-     if (!ref) ref= "";
-     for (;;) {
-         vp= val;  while (*vp && !isdigit(*vp)) vp++;
-         rp= ref;  while (*rp && !isdigit(*rp)) rp++;
-         for (;;) {
-              vc= (val == vp) ? 0 : *val++;
-              rc= (ref == rp) ? 0 : *ref++;
-              if (!rc && !vc) break;
-              if (vc && !isalpha(vc)) vc += 256; /* assumes ASCII character set */
-              if (rc && !isalpha(rc)) rc += 256;
-              if (vc != rc) return vc - rc;
-         }
-         val= vp;
-         ref= rp;
-         vl=0;  if (isdigit(*vp)) vl= strtol(val,(char**)&val,10);
-         rl=0;  if (isdigit(*rp)) rl= strtol(ref,(char**)&ref,10);
-         if (vl != rl) return vl - rl;
-
-         vc = *val;
-         rc = *ref;
-         vsep = strchr(".-", vc);
-         rsep = strchr(".-", rc);
-         if (vsep && !rsep) return -1;
-         if (!vsep && rsep) return +1;
-
-         if (!*val && !*ref) return 0;
-         if (!*val) return -1;
-         if (!*ref) return +1;
-     }
+/* assume ascii; warning: evaluates x multiple times! */
+#define order(x) ((x) == '~' ? -1 \
+               : isdigit((x)) ? 0 \
+               : !(x) ? 0 \
+               : isalpha((x)) ? (x) \
+               : (x) + 256)
+
+static int verrevcmp(const char *val, const char *ref) {
+  if (!val) val= "";
+  if (!ref) ref= "";
+
+  while (*val || *ref) {
+    int first_diff= 0;
+
+    while ( (*val && !isdigit(*val)) || (*ref && !isdigit(*ref)) ) {
+      int vc= order(*val), rc= order(*ref);
+      if (vc != rc) return vc - rc;
+      val++; ref++;
+    }
+
+    while ( *val == '0' ) val++;
+    while ( *ref == '0' ) ref++;
+    while (isdigit(*val) && isdigit(*ref)) {
+      if (!first_diff) first_diff= *val - *ref;
+      val++; ref++;
+    }
+    if (isdigit(*val)) return 1;
+    if (isdigit(*ref)) return -1;
+    if (first_diff) return first_diff;
+  }
+  return 0;
 }
 
 int pkg_version_satisfied(pkg_t *it, pkg_t *ref, const char *op)
@@ -1148,10 +1159,10 @@ int pkg_version_satisfied(pkg_t *it, pkg_t *ref, const char *op)
      return 0;
 }
 
-int pkg_name_version_and_architecture_compare(void *p1, void *p2)
+int pkg_name_version_and_architecture_compare(const void *p1, const void *p2)
 {
-     const pkg_t *a = *(const pkg_t **)p1;
-     const pkg_t *b = *(const pkg_t **)p2;
+     const pkg_t *a = *(const pkg_t**) p1;
+     const pkg_t *b = *(const pkg_t**) p2;
      int namecmp;
      int vercmp;
      if (!a->name || !b->name) {
@@ -1178,7 +1189,7 @@ int pkg_name_version_and_architecture_compare(void *p1, void *p2)
      return 0;
 }
 
-int abstract_pkg_name_compare(void *p1, void *p2)
+int abstract_pkg_name_compare(const void *p1, const void *p2)
 {
      const abstract_pkg_t *a = *(const abstract_pkg_t **)p1;
      const abstract_pkg_t *b = *(const abstract_pkg_t **)p2;
@@ -1195,10 +1206,7 @@ char *pkg_version_str_alloc(pkg_t *pkg)
 {
      char *complete_version;
      char *epoch_str;
-#ifdef USE_DEBVERSION
      char *revision_str;
-     char *familiar_revision_str;
-#endif
 
      if (pkg->epoch) {
          sprintf_alloc(&epoch_str, "%d:", pkg->epoch);
@@ -1206,33 +1214,18 @@ char *pkg_version_str_alloc(pkg_t *pkg)
          epoch_str = strdup("");
      }
 
-#ifdef USE_DEBVERSION
      if (pkg->revision && strlen(pkg->revision)) {
          sprintf_alloc(&revision_str, "-%s", pkg->revision);
      } else {
          revision_str = strdup("");
      }
 
-     if (pkg->familiar_revision && strlen(pkg->familiar_revision)) {
-         sprintf_alloc(&familiar_revision_str, "-fam%s", pkg->familiar_revision);
-     } else {
-         familiar_revision_str = strdup("");
-     }
-#endif
 
-#ifdef USE_DEBVERSION
-     sprintf_alloc(&complete_version, "%s%s%s%s",
-                  epoch_str, pkg->version, revision_str, familiar_revision_str);
-#else
-     sprintf_alloc(&complete_version, "%s%s",
-                  epoch_str, pkg->version);
-#endif
+     sprintf_alloc(&complete_version, "%s%s%s",
+                  epoch_str, pkg->version, revision_str);
 
      free(epoch_str);
-#ifdef USE_DEBVERSION
      free(revision_str);
-     free(familiar_revision_str);
-#endif
 
      return complete_version;
 }