diff --git a/config.h b/config.h index e605e4b..4407f16 100644 --- a/config.h +++ b/config.h @@ -60,10 +60,10 @@ static binding key_binding[] = { { "on", order_by, sort_natural, "order natural" }, { "or", not_implemented, "", "order reverse" }, { "oe", not_implemented, "", "order extension" }, - { "os", not_implemented, "", "order size" }, - { "ot", not_implemented, "", "order type" }, - { "oz", not_implemented, "", "order random" }, - { "oa", order_by, sort_alpha, "order random" }, + { "os", order_by, sort_size, "order size" }, + { "ot", order_by, sort_type, "order type" }, + { "oz", order_by, sort_random, "order random" }, + { "oa", order_by, sort_alpha, "order alphabetically" }, { "mk", makedir, NULL, "create directory" }, { "mf", makefile, NULL, "create file" }, diff --git a/sorting.c b/sorting.c index b350b62..f9173e5 100644 --- a/sorting.c +++ b/sorting.c @@ -1,6 +1,7 @@ #include #include #include +#include #include "defines.h" extern unsigned int settings; @@ -40,9 +41,118 @@ int sort_natural(const void *file0, const void *file1){ } } } - int sort_alpha(const void *file0, const void *file1){ char *file_name0 = ((file*)file0)->file_name; char *file_name1 = ((file*)file1)->file_name; return strcmp(file_name0, file_name1); } +int sort_random(const void *file0, const void *file1){ + unsigned char file_type0 = ((file*)file0)->file_type; + unsigned char file_type1 = ((file*)file1)->file_type; + char *file_name0 = ((file*)file0)->file_name; + char *file_name1 = ((file*)file1)->file_name; + static int seed = 0; + static int random = 0; + + if (seed == 0) { + seed = rand(); + } + if (random == 0) { + random = seed; + } + if (strcmp(file_name0, ".") == 0 || strcmp(file_name0, "..") == 0) { + return -1; + } + char weight = 0; + if (file_type0 == FILE_TYPE_DIR || file_type0 == FILE_TYPE_SYMLINK) { + weight |= 1; + } + if (file_type1 == FILE_TYPE_DIR || file_type1 == FILE_TYPE_SYMLINK) { + weight |= 2; + } + if (weight == 0 || weight == 3) { + random = random > 1; + if ((random & 2) == 2) { + return -1; + } else { + if (random & 1){ + return 1; + } else { + return 0; + } + } + } else { + if (file_type0 > file_type1) { + return 1; + } else if (file_type0 < file_type1) { + return -1; + } else { + random = random > 1; + if ((random & 2) == 2) { + return -1; + } else { + if (random & 1){ + return 1; + } else { + return 0; + } + } + } + } + return 0; +} +int sort_type(const void *file0, const void *file1){ + unsigned char file_type0 = ((file*)file0)->file_type; + unsigned char file_type1 = ((file*)file1)->file_type; + char *file_name0 = ((file*)file0)->file_name; + char *file_name1 = ((file*)file1)->file_name; + if (file_type0 == file_type1) { + return strcasecmp(file_name0, file_name1); + } else if (file_type0 == FILE_TYPE_DIR || file_type0 == FILE_TYPE_SYMLINK) { + return -1; + } else if (file_type1 == FILE_TYPE_DIR || file_type1 == FILE_TYPE_SYMLINK) { + return 1; + } else { + if (file_type0 > file_type1) { + return -1; + } else if (file_type0 < file_type1) { + return 1; + } else { + return strcasecmp(file_name0, file_name1); + } + } +} +int sort_size(const void *file0, const void *file1){ + unsigned char file_type0 = ((file*)file0)->file_type; + unsigned char file_type1 = ((file*)file1)->file_type; + unsigned long file_size0 = ((file*)file0)->file_size; + unsigned long file_size1 = ((file*)file1)->file_size; + char *file_name0 = ((file*)file0)->file_name; + char *file_name1 = ((file*)file1)->file_name; + if (strcmp(file_name0, ".") == 0 || strcmp(file_name0, "..") == 0) { + return -1; + } + if (file_type0 == file_type1) { + if (file_size0 > file_size1) { + return -1; + } else if (file_size0 < file_size1) { + return 1; + } else { + return strcasecmp(file_name0, file_name1); + } + } else { + if (file_type0 == FILE_TYPE_DIR || file_type0 == FILE_TYPE_SYMLINK) { + return -1; + } else if (file_type1 == FILE_TYPE_DIR || file_type1 == FILE_TYPE_SYMLINK) { + return 1; + } else { + if (file_size0 > file_size1) { + return -1; + } else if (file_size0 < file_size1) { + return 1; + } else { + return strcasecmp(file_name0, file_name1); + } + } + } +} diff --git a/sorting.h b/sorting.h index 711d7aa..8170a20 100644 --- a/sorting.h +++ b/sorting.h @@ -10,4 +10,7 @@ void sort_dir(unsigned long *dir_length_width, char *dir_content); void sort_dir(unsigned long *dir_length_width, char *dir_content); int sort_natural(const void *file0, const void *file1); int sort_alpha(const void *file0, const void *file1); +int sort_random(const void *file0, const void *file1); +int sort_type(const void *file0, const void *file1); +int sort_size(const void *file0, const void *file1);