aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/data_management.h1
-rw-r--r--include/options.h2
-rw-r--r--src/data_management.c64
-rw-r--r--src/options.c22
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;