#define LIBDPKG_VOLATILE_API 1 #define _GNU_SOURCE #include #include #include #include #include #include #include // 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); }