#include <errno.h>
#include <stdlib.h>
+#include <sys/queue.h>
#include <pakfire/archive.h>
#include <pakfire/linter.h>
#include <pakfire/logging.h>
#include <pakfire/package.h>
+struct pakfire_linter_result {
+ TAILQ_ENTRY(pakfire_linter_result) nodes;
+
+ // Priority
+ enum pakfire_linter_priority {
+ PAKFIRE_LINTER_INFO,
+ PAKFIRE_LINTER_WARNING,
+ PAKFIRE_LINTER_ERROR,
+ } priority;
+
+ // Comment
+ char* comment;
+};
+
struct pakfire_linter {
struct pakfire_ctx* ctx;
int nrefs;
// Package
struct pakfire_package* pkg;
+
+ // Results
+ TAILQ_HEAD(results, pakfire_linter_result) results;
};
-static void pakfire_linter_free(struct pakfire_linter* linter) {
- if (linter->archive)
- pakfire_archive_unref(linter->archive);
- if (linter->pkg)
- pakfire_package_unref(linter->pkg);
- if (linter->ctx)
- pakfire_ctx_unref(linter->ctx);
- free(linter);
+static void pakfire_linter_result_free(struct pakfire_linter_result* result) {
+ if (result->comment)
+ free(result->comment);
+ free(result);
+}
+
+static int pakfire_linter_result(struct pakfire_linter* linter, int priority,
+ const char* format, ...) __attribute__((format(printf, 3, 4)));
+
+static int pakfire_linter_result(
+ struct pakfire_linter* linter, int priority, const char* format, ...) {
+ struct pakfire_linter_result* result = NULL;
+ va_list args;
+ int r;
+
+ // Check inputs
+ if (!format)
+ return -EINVAL;
+
+ // Allocate a new result
+ result = calloc(1, sizeof(*result));
+ if (!result)
+ return -errno;
+
+ // Store priority
+ result->priority = priority;
+
+ // Store the comment
+ va_start(args, format);
+ r = vasprintf(&result->comment, format, args);
+ va_end(args);
+
+ // Fail on error
+ if (r < 0) {
+ pakfire_linter_result_free(result);
+ return r;
+ }
+
+ // Store the result
+ TAILQ_INSERT_TAIL(&linter->results, result, nodes);
+
+ // Log the result
+ CTX_DEBUG(linter->ctx, "%s: %s",
+ pakfire_archive_get_path(linter->archive), result->comment);
+
+ return 0;
}
int pakfire_linter_create(struct pakfire_linter** linter,
// Initialize reference counter
l->nrefs = 1;
+ // Initialize results
+ TAILQ_INIT(&l->results);
+
// Store the archive
l->archive = pakfire_archive_ref(archive);
return r;
}
+static void pakfire_linter_free(struct pakfire_linter* linter) {
+ struct pakfire_linter_result* result = NULL;
+
+ // Free all results
+ for (;;) {
+ result = TAILQ_LAST(&linter->results, results);
+ if (!result)
+ break;
+
+ TAILQ_REMOVE(&linter->results, result, nodes);
+ pakfire_linter_result_free(result);
+ }
+
+ if (linter->archive)
+ pakfire_archive_unref(linter->archive);
+ if (linter->pkg)
+ pakfire_package_unref(linter->pkg);
+ if (linter->ctx)
+ pakfire_ctx_unref(linter->ctx);
+ free(linter);
+}
+
struct pakfire_linter* pakfire_linter_ref(struct pakfire_linter* linter) {
++linter->nrefs;