normalize #include
[ppastats.git] / src / lp.c
index 9ba2eec..7346236 100644 (file)
--- a/src/lp.c
+++ b/src/lp.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2012 jeanfi@gmail.com
+ * Copyright (C) 2011-2014 jeanfi@gmail.com
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -21,7 +21,9 @@
 #include <stdio.h>
 #include <string.h>
 
-#include "lp.h"
+#include <list.h>
+#include <lp.h>
+#include <ptime.h>
 
 struct distro_series *distro_series_new(const char *name,
                                        const char *version,
@@ -68,7 +70,9 @@ struct bpph *bpph_new(const char *binary_package_name,
                      const char *binary_package_version,
                      const char *distro_arch_series_link,
                      const char *self_link,
-                     int architecture_specific)
+                     const char *status,
+                     int architecture_specific,
+                     time_t date_created)
 {
        struct bpph *h;
 
@@ -79,22 +83,26 @@ struct bpph *bpph_new(const char *binary_package_name,
        h->distro_arch_series_link = strdup(distro_arch_series_link);
        h->self_link = strdup(self_link);
        h->architecture_specific = architecture_specific;
-       h->status = NULL;
-       h->date_created.tm_isdst = -1;
+       h->status = strdup(status);
+       h->date_created = date_created;
 
        return h;
 }
 
 void bpph_list_free(struct bpph **list)
 {
-       struct bpph **l_cur = list;
+       struct bpph **cur;
 
-       while (*l_cur) {
-               bpph_free(*l_cur);
-               l_cur++;
-       }
+       if (list) {
+               cur = list;
 
-       free(list);
+               while (*cur) {
+                       bpph_free(*cur);
+                       cur++;
+               }
+
+               free(list);
+       }
 }
 
 char *get_archive_url(const char *owner, const char *ppa)
@@ -146,10 +154,13 @@ void distro_arch_series_free(struct distro_arch_series *d)
 
 void distro_arch_series_list_free(struct distro_arch_series **list)
 {
+       struct distro_arch_series **cur;
+
        if (list) {
-               while (*list) {
-                       distro_arch_series_free(*list);
-                       list++;
+               cur = list;
+               while (*cur) {
+                       distro_arch_series_free(*cur);
+                       cur++;
                }
                free(list);
        }
@@ -169,3 +180,169 @@ void daily_download_total_list_free(struct daily_download_total **list)
        }
 }
 
+struct bpph **bpph_list_add(struct bpph **list, struct bpph *new)
+{
+       struct bpph **cur, *bpph, **result;
+
+       if (list)
+               for (cur = list; *cur; cur++) {
+                       bpph = *cur;
+
+                       if (!strcmp(bpph->self_link, new->self_link))
+                               return list;
+               }
+
+       result = (struct bpph **)list_add((void **)list, new);
+
+       free(list);
+
+       return result;
+}
+
+struct bpph **bpph_list_append_list(struct bpph **list1, struct bpph **list2)
+{
+       struct bpph **cur;
+
+       if (!list2)
+               return list1;
+
+       for (cur = list2; *cur; cur++)
+               list1 = bpph_list_add(list1, *cur);
+
+       return list1;
+}
+
+time_t ddts_get_last_date(struct daily_download_total **ddts)
+{
+       struct daily_download_total **cur;
+       time_t t, last_t;
+
+       if (!ddts)
+               return 0;
+
+       last_t = 0;
+       for (cur = ddts; *cur; cur++) {
+               t = mktime(&(*cur)->date);
+               if (t > last_t)
+                       last_t = t;
+       }
+
+       return last_t;
+}
+
+int ddts_length(struct daily_download_total **ddts)
+{
+       int n;
+       struct daily_download_total **cur;
+
+       n = 0;
+
+       if (ddts)
+               for (cur = ddts; *cur; cur++)
+                       n++;
+
+       return n;
+}
+
+struct daily_download_total *ddt_clone(struct daily_download_total *ddt)
+{
+       struct daily_download_total *new;
+
+       new = malloc(sizeof(struct daily_download_total));
+
+       new->date = ddt->date;
+       new->count = ddt->count;
+
+       return new;
+}
+
+struct daily_download_total **
+ddts_clone(struct daily_download_total **ddts)
+{
+       int n, i;
+       struct daily_download_total **new;
+
+       n = ddts_length(ddts);
+
+       new = malloc((n + 1) * sizeof(struct daily_download_total *));
+
+       for (i = 0; i < n; i++)
+               new[i] = ddt_clone(ddts[i]);
+
+       new[n] = NULL;
+
+       return new;
+}
+
+/*
+  Return a newly allocated list with an additional ddt.
+  All ddts are cloned.
+ */
+static struct daily_download_total **add_ddt
+(struct daily_download_total **totals, struct daily_download_total *total)
+{
+       struct daily_download_total **cur, **ddts, **result;
+       struct daily_download_total *item;
+
+       if (totals) {
+               cur = totals;
+               while (*cur) {
+                       item = *cur;
+
+                       if (item->date.tm_year == total->date.tm_year &&
+                           item->date.tm_mon == total->date.tm_mon &&
+                           item->date.tm_mday == total->date.tm_mday) {
+                               item->count = total->count;
+                               return totals;
+                       }
+
+                       cur++;
+               }
+       }
+
+       ddts = ddts_clone(totals);
+
+       result = (struct daily_download_total **)
+               list_add((void **)ddts, ddt_clone((void *)total));
+
+       free(ddts);
+
+       return result;
+}
+
+struct daily_download_total **
+ddts_merge(struct daily_download_total **ddts1,
+          struct daily_download_total **ddts2)
+{
+       struct daily_download_total **ddts, **cur, **tmp;
+
+       if (ddts1) {
+               ddts = ddts_clone(ddts1);
+       } else {
+               ddts = malloc(sizeof(struct daily_download_total *));
+               ddts[0] = NULL;
+       }
+
+       if (ddts2)
+               for (cur = ddts2; *cur; cur++) {
+                       tmp = add_ddt(ddts, *cur);
+                       if (tmp != ddts) {
+                               daily_download_total_list_free(ddts);
+                               ddts = tmp;
+                       }
+               }
+
+       return ddts;
+}
+
+int ddts_get_count(struct daily_download_total **ddts)
+{
+       struct daily_download_total **cur;
+       int i;
+
+       i = 0;
+       for (cur = ddts; *cur; cur++)
+               i += (*cur)->count;
+
+       return i;
+}