#define LIBDPKG_VOLATILE_API 1
#define _GNU_SOURCE
#include <dpkg/dpkg.h>
#include <dpkg/dpkg-db.h>
#include <dpkg/version.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

// we need to keep track of the original string because some version strings
// include the implicit epoch of zero
struct myver {
	struct dpkg_version dv;
	char *sv;
};

int cmpver(const void *a, const void *b) {
	int ret = dpkg_version_compare(&(((struct myver *)a)->dv), &(((struct myver *)b)->dv));
	if (ret == 0) {
		return strcmp(((struct myver *)a)->sv, ((struct myver *)b)->sv);
	}
	return ret;
}

int main()
{
    char *line = NULL;
    size_t len = 0;
    size_t read;
	struct dpkg_version a;
	struct myver *versions = NULL;
	size_t num_versions = 0;
    while ((read = getline(&line, &len, stdin)) != -1) {
		num_versions += 1;
		versions = realloc(versions, sizeof(struct myver)*num_versions);
		if (versions == NULL) {
			perror("malloc failed");
			exit(EXIT_FAILURE);
		}
		if (line[read-1] == '\n') {
			line[read-1] = '\0';
		}
		if (parseversion(&((versions+num_versions-1)->dv), line, NULL)) {
			fprintf(stderr, "cannot parse version: %s\n", line);
			exit(EXIT_FAILURE);
		}
		(versions+num_versions-1)->sv = strdup(line);
	}
	qsort(versions, num_versions, sizeof(struct myver), cmpver);
	printf(versions->sv);
	for (int i = 1; i < num_versions; i++) {
		if (dpkg_version_compare(&((versions+i-1)->dv), &((versions+i)->dv)) == 0) {
			printf(" ");
		} else {
			printf("\n");
		}
		printf((versions+i)->sv);
	}
	printf("\n");
    exit(EXIT_SUCCESS);
}
