From 0369340710734121e3b2bd3ad6082f8361478d89 Mon Sep 17 00:00:00 2001 From: Sami Kerola Date: Mon, 30 Nov 2015 00:49:42 +0000 Subject: [PATCH] remove upper limit of sort order definitions Unlikely to be needed by anyone, but because arbitrary limits are from code style point of view ugly. Signed-off-by: Sami Kerola --- man/dhcpd-pools.1.in | 6 ++--- src/dhcpd-pools.c | 32 +++++++++++++++++---------- src/dhcpd-pools.h | 52 +++++++++++++++++++++++++------------------- src/other.c | 6 +++++ src/sort.c | 35 +++++++++++------------------ 5 files changed, 72 insertions(+), 59 deletions(-) diff --git a/man/dhcpd-pools.1.in b/man/dhcpd-pools.1.in index 4f5ca76..df78f84 100644 --- a/man/dhcpd-pools.1.in +++ b/man/dhcpd-pools.1.in @@ -57,9 +57,9 @@ or monitor subset of data. Path to the dhcpd.leases file. .TP \fB\-s\fR, \fB\-\-sort\fR=\fI[nimcptTe]\fR -Sort ranges by chosen fields as a sorting keys. Maximum of five sort keys -can be defined. Keys weight from left to right, i.e., if more weighting keys -are equal next one is used. The IP field is default sort key. +Sort ranges by chosen fields as a sorting keys. Keys weight from left to +right, i.e., if more weighting keys are equal next one is used. The IP +field is default sort key. .TP \fB\-r\fR, \fB\-\-reverse\fR Sort results in reverse order. diff --git a/src/dhcpd-pools.c b/src/dhcpd-pools.c index ef22153..e4f0866 100644 --- a/src/dhcpd-pools.c +++ b/src/dhcpd-pools.c @@ -89,7 +89,7 @@ struct leases_t *(*find_lease) (union ipaddr_t *ip); * alarming. */ int main(int argc, char **argv) { - int i, sorts = 0; + int i; int option_index = 0; char const *tmp; struct range_t *tmp_ranges; @@ -150,6 +150,7 @@ int main(int argc, char **argv) /* Default sort order is by IPs small to big */ config.reverse_order = false; config.backups_found = false; + prepare_memory(); /* Parse command line options */ while (1) { int c; @@ -171,16 +172,23 @@ int main(int argc, char **argv) strncpy(config.output_format, optarg, (size_t)1); break; case 's': + { /* Output sorting option */ - sorts = strlen(optarg); - if (5 < sorts) { - error(0, 0, "main: only first 5 sort orders will be used"); - strncpy(config.sort, optarg, (size_t)5); - sorts = 5; - } else - strncpy(config.sort, optarg, (size_t)sorts); - for (i = 0; i < sorts; i++) - field_selector(config.sort[i]); + struct output_sort *p = config.sorts; + + while (p && p->next) + p = p->next; + for (i = 0; i < strlen(optarg); i++) { + if (config.sorts == NULL) { + config.sorts = xcalloc(1, sizeof(struct output_sort)); + p = config.sorts; + } else { + p->next = xcalloc(1, sizeof(struct output_sort)); + p = p->next; + } + p->func = field_selector(optarg[i]); + } + } break; case 'r': /* What ever sort in reverse order */ @@ -269,14 +277,13 @@ int main(int argc, char **argv) error(EXIT_FAILURE, 0, "main: unknown output format `%c'", config.output_format[0]); } /* Do the job */ - prepare_memory(); set_ipv_functions(VERSION_UNKNOWN); parse_config(true, config.dhcpdconf_file, shared_networks); parse_leases(); prepare_data(); do_counting(); tmp_ranges = xmalloc(sizeof(struct range_t) * num_ranges); - if (sorts != 0) + if (config.sorts != NULL) mergesort_ranges(ranges, num_ranges, tmp_ranges); if (config.reverse_order == true) flip_ranges(ranges, tmp_ranges); @@ -300,4 +307,5 @@ void prepare_memory(void) shared_networks->used = 0; shared_networks->touched = 0; shared_networks->backups = 0; + config.sorts = NULL; } diff --git a/src/dhcpd-pools.h b/src/dhcpd-pools.h index 79ee586..d413f89 100644 --- a/src/dhcpd-pools.h +++ b/src/dhcpd-pools.h @@ -115,27 +115,6 @@ enum prefix_t { PREFIX_HARDWARE_ETHERNET, NUM_OF_PREFIX }; -/*! \struct configuration_t - * \brief Runtime configuration. - */ -struct configuration_t { - char dhcpv6; - enum dhcp_version dhcp_version; - char *dhcpdconf_file; - char *dhcpdlease_file; - char output_format[2]; - char sort[6]; - bool reverse_order; - char *output_file; - int output_limit[2]; - bool backups_found; - bool snet_alarms; - double warning; - double critical; - double warn_count; - double crit_count; - double minsize; -}; /*! \struct shared_network_t * \brief Counters for an individual shared network. */ @@ -200,6 +179,36 @@ enum limbits { # define STATE_WARNING 1 # define STATE_CRITICAL 2 +typedef int (*comparer_t) (struct range_t *r1, struct range_t *r2); + +/*! \struct output_sort + * \brief Linked list of sort functions. + */ +struct output_sort { + comparer_t func; + struct output_sort *next; +}; +/*! \struct configuration_t + * \brief Runtime configuration. + */ +struct configuration_t { + char dhcpv6; + enum dhcp_version dhcp_version; + char *dhcpdconf_file; + char *dhcpdlease_file; + char output_format[2]; + struct output_sort *sorts; + bool reverse_order; + char *output_file; + int output_limit[2]; + bool backups_found; + bool snet_alarms; + double warning; + double critical; + double warn_count; + double crit_count; + double minsize; +}; /* Global variables */ /* \var prefix_length Length of each prefix. */ extern int prefix_length[2][NUM_OF_PREFIX]; @@ -289,7 +298,6 @@ extern int comp_touched(struct range_t *r1, struct range_t *r2) _DP_ATTRIBUTE_PU extern int rangecomp(const void *__restrict r1, const void *__restrict r2) __attribute__ ((nonnull(1, 2))); /* sort function pointer and functions */ -typedef int (*comparer_t) (struct range_t *r1, struct range_t *r2); extern comparer_t field_selector(char c); extern double ret_percent(struct range_t r); extern double ret_tc(struct range_t r) _DP_ATTRIBUTE_CONST; diff --git a/src/other.c b/src/other.c index bfdb6bb..eacc5c6 100644 --- a/src/other.c +++ b/src/other.c @@ -402,6 +402,8 @@ void flip_ranges(struct range_t *restrict flip_me, struct range_t *restrict tmp_ /*! \brief Free memory, flush buffers etc. */ void clean_up(void) { + struct output_sort *cur, *next; + /* Just in case there something in buffers */ if (fflush(NULL)) error(0, 0, "clean_up: fflush"); @@ -418,6 +420,10 @@ void clean_up(void) free((shared_networks + i)->name); free(shared_networks); } + for (cur = config.sorts; cur; cur = next) { + next = cur->next; + free(cur); + } } /*! \brief A version printing. */ diff --git a/src/sort.c b/src/sort.c index d0af3cb..266362d 100644 --- a/src/sort.c +++ b/src/sort.c @@ -220,7 +220,7 @@ comparer_t field_selector(char c) { switch (c) { case 'n': - break; + return NULL; case 'i': return comp_ip; case 'm': @@ -249,32 +249,23 @@ comparer_t field_selector(char c) */ static int merge(struct range_t *restrict left, struct range_t *restrict right) { - int i, len, ret; - comparer_t comparer; - int cmp; + struct output_sort *p; + int ret; - len = strlen(config.sort); - for (i = 0; i < len; i++) { - /* Handling strings is case of it's own */ - if (config.sort[i] == 'n') { + for (p = config.sorts; p; p = p->next) { + if (p->func == NULL) { + /* String sorting is special. */ ret = strcmp(left->shared_net->name, right->shared_net->name); - if (0 < ret) - return (0); - if (ret < 0) - return (1); - continue; + } else { + /* Range sorts are common. */ + ret = p->func(left, right); } - /* Select which function is pointed by comparer */ - comparer = field_selector(config.sort[i]); - cmp = comparer(left, right); - /* If fields are equal use next sort method */ - if (cmp == 0) - continue; - if (cmp < 0) + if (0 < ret) + return (0); + if (ret < 0) return (1); - return (0); } - /* If all comparers where equal */ + /* this is reached if nothing was sorted */ return (0); }