diff options
| -rw-r--r-- | include/data_management.h | 1 | ||||
| -rw-r--r-- | include/options.h | 2 | ||||
| -rw-r--r-- | src/data_management.c | 64 | ||||
| -rw-r--r-- | src/options.c | 22 |
4 files changed, 70 insertions, 19 deletions
diff --git a/include/data_management.h b/include/data_management.h index e5d1581..a8d3648 100644 --- a/include/data_management.h +++ b/include/data_management.h @@ -27,6 +27,7 @@ struct list_head *create_list_sort_reversed(struct list_head *list); void destroy_list(struct list_head *list); struct list_head *get_data_from_directory(char *path); +int insert_sorted_by_name(struct list_head *list, struct list_node *node); int insert_sorted_by_size(struct list_head *list, struct list_node *node); int insert_sorted_by_time(struct list_head *list, struct list_node *node); diff --git a/include/options.h b/include/options.h index cfc9246..5e951b2 100644 --- a/include/options.h +++ b/include/options.h @@ -21,7 +21,7 @@ #define PATH_SEP '/' #endif -enum esort_type { SORT_BY_SIZE, SORT_BY_TIME }; +enum esort_type { SORT_BY_NAME, SORT_BY_SIZE, SORT_BY_TIME }; /* === GLOBAL VARIABLES === */ diff --git a/src/data_management.c b/src/data_management.c index a0a1667..d4cf76c 100644 --- a/src/data_management.c +++ b/src/data_management.c @@ -121,6 +121,39 @@ inline int insert_sorted_by_time(struct list_head *list, struct list_node *node) } +inline int insert_sorted_by_name(struct list_head *list, struct list_node *node) { + struct list_node *ptr = NULL; + if (list == NULL) { LOGERR("ERROR: No list given.\n"); return -1; } + if (node == NULL) { LOGERR("ERROR: No node given.\n"); return -2; } + + if (list->first == NULL) { + list->first = node; + return 0; + } + + if (strncmp(node->fname, list->first->fname, 255) < 0) { + node->next = list->first; + list->first = node; + return 0; + } + + ptr = list->first; + while (ptr != NULL) { + if (ptr->next == NULL) { + ptr->next = node; + return 0; + } + if (strncmp(node->fname, ptr->next->fname, 255) < 0) { + node->next = ptr->next; + ptr->next = node; + return 0; + } + ptr = ptr->next; + } + return -3; +} + + inline struct list_head *create_list_sort_reversed(struct list_head *list) { struct list_head *lh = NULL; struct list_node *cpynode = NULL, *ptr = NULL; @@ -152,20 +185,13 @@ inline struct list_head *create_list_sort_reversed(struct list_head *list) { /* This function contains the only time critical code. The loop over * the directory content. - * - * Note for future: - * I myself use the dir_monitor in combination with watch on a directory - * containing temporary data, it may happen that a run into an error occurs, - * but it's not tragic. To reduce the chance of the error the first step - * would be to optimize the loop with putting the data into a list in stack - * form and moving the nodes into a sorted list afterwards. */ struct list_head *get_data_from_directory(char *path) { char *fullpath = NULL, *fname_in_path = NULL; DIR *dir = NULL; size_t l; struct dirent *de = NULL; - struct list_node *tmp = NULL; + struct list_node *lnstack = NULL, *tmp = NULL; struct list_head *list = NULL; struct stat stat_res; @@ -213,6 +239,20 @@ struct list_head *get_data_from_directory(char *path) { LOGERR("ERROR: Skipping entry %s\n", de->d_name); continue; } + /* Performance: Put every node on the stack and do the sorting afterwards */ + tmp->next = lnstack; + lnstack = tmp; + } + free(fullpath); + closedir(dir); + + DBGTRC("Finished reading data from directory\n"); + + while (lnstack != NULL) { + tmp = lnstack; + lnstack = lnstack->next; + tmp->next = NULL; + /* SORT_BY_SIZE is the default value, always check it first. */ switch (option_sort_type) { case SORT_BY_SIZE: @@ -221,11 +261,15 @@ struct list_head *get_data_from_directory(char *path) { case SORT_BY_TIME: insert_sorted_by_time(list, tmp); break; + case SORT_BY_NAME: + insert_sorted_by_name(list, tmp); + break; + default: /* Never should be the case, but as so often, better safe than sorry */ + LOGERR("ERROR: No valid sort option set: %d\n", option_sort_type); + exit(EXIT_FAILURE); }; } - free(fullpath); - closedir(dir); return list; } diff --git a/src/options.c b/src/options.c index 5d7aaaa..8a2216d 100644 --- a/src/options.c +++ b/src/options.c @@ -47,18 +47,22 @@ void usage(char *executable) { fprintf(stderr, "Call: %s OPTIONS path_to_open\n", executable); fprintf(stderr, "\nOPTIONS are\n"); /* long name, short name, optional argument, explanation */ - fprintf(stderr, " %-25s %2s %10s %s\n", "--help", "-h", "", + fprintf(stderr, " %-25s %2s %10s - %s\n", "--help", "-h", "", "Show this message and exit"); - fprintf(stderr, " %-25s %2s %10s %s\n", "--long-timestamp", "-t", "", + fprintf(stderr, " %-25s %2s %10s - %s\n", "--long-timestamp", "-t", "", "Print timestamp in long form yyyymmdd HH:MM:SS ZONE"); - fprintf(stderr, " %-25s %2s %10s %s\n", "--reverse-sort", "", "", + fprintf(stderr, " %-25s %2s %10s - %s\n", "--reverse-sort", "", "", "Sort reversed"); - fprintf(stderr, " %-25s %2s %10s %s\n", "--show-hidden-entries", "-v", "", + fprintf(stderr, " %-25s %2s %10s - %s\n", "--show-hidden-entries", "-v", "", "Show hidden entries in the directory"); - fprintf(stderr, " %-25s %2s %10s %s\n", "--sort-by", "", "size|time", + fprintf(stderr, " %-25s %2s %10s - %s\n", "--sort-by", "", "variant", "Sort either by size or time"); - fprintf(stderr, " %-25s %2s %10s %s\n", "--time-field", "", "a|c|m", + fprintf(stderr, " %-25s %2s %10s - %s\n", "--time-field", "", "a|c|m", "Sort by (a)ccess, (c)hange or (m)odification time. Default: m"); + + /* fputc_width_x('-', 72, stderr); */ + + fprintf(stderr, "\n\n--sort-by variants: name | size | time\n"); } @@ -99,12 +103,14 @@ void set_option(const char *option_name, char *option_argument) { } if (strcmp("sort-by", option_name) == 0) { - if (strncmp("size", option_argument, 4) == 0) { + if (strncmp("name", option_argument, 4) == 0) { + option_sort_type = SORT_BY_NAME; + } else if (strncmp("size", option_argument, 4) == 0) { option_sort_type = SORT_BY_SIZE; } else if (strncmp("time", option_argument, 4) == 0) { option_sort_type = SORT_BY_TIME; } else { - LOGERR("WARNING: '%s' is an invalig argument for %s\n", + LOGERR("WARNING: '%s' is an invalid argument for %s\n", option_argument, option_name); } return; |
