1
0
mirror of https://gittea.dev/nova/th.git synced 2025-10-21 10:20:15 -04:00
Files
th/sorting.c
2025-08-29 22:42:46 +02:00

171 lines
4.3 KiB
C

#include <curses.h>
#include <dirent.h>
#include <stdlib.h>
#include <strings.h>
#include <string.h>
#include <pthread.h>
#include "defines.h"
extern time_t seed;
extern unsigned int settings;
extern unsigned int file_modifiers;
int skip_hidden_files(const struct dirent *entry){
if (entry->d_name[0] == '.') {
return 0;
}
return 1;
}
int skip_dot(const struct dirent *entry){
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
return 0;
}
return 1;
}
int sort_natural(const void *file0_, const void *file1_){
file *file0 = (file*)file0_;
file *file1 = (file*)file1_;
unsigned char *a = file0->file_name;
unsigned char *b = file1->file_name;
if (file0->file_type & (FILE_TYPE_SYMLINK | FILE_TYPE_DIR) && !(file1->file_type & (FILE_TYPE_SYMLINK | FILE_TYPE_DIR))) {
return -1;
}
if (!(file0->file_type & (FILE_TYPE_SYMLINK | FILE_TYPE_DIR)) && file1->file_type & (FILE_TYPE_SYMLINK | FILE_TYPE_DIR)) {
return 1;
}
unsigned long num0 = 0;
unsigned long num1 = 0;
/* bitwise OR a with ' ' turns turns caps into small letters
* while doing this on all chars may cause unexpected behaviour on the extended ascii set,
* for now i dont care */
while ((*a | ' ') == (*b | ' ') && *a != '\0') {
if ((*a >= '0') && (*a <= '9')) {
while((*a >= '0') && (*a <= '9')) {
num0 = (num0 * 10) + (*a - '0');
a++;
}
while((*b >= '0') && (*b <= '9')) {
num1 = (num1 * 10) + (*b - '0');
b++;
}
if (num0 != num1) {
break;
}
} else {
a++;
b++;
}
}
if (num0 == num1) {
if (*a == '\0') {
a--;
}
if (*b == '\0') {
b--;
}
unsigned char c0;
unsigned char c1;
/* in this case we actually check for a through z as otherwise unicode characters get ordered wrongly */
if (*a >= 'A' && *a <= 'Z') {
c0 = (*a | ' ');
} else {
c0 = *a;
}
if (*b >= 'A' && *b <= 'Z') {
c1 = (*b | ' ');
} else {
c1 = *b;
}
if (c0 > c1) {
return 1;
} else if (c0 < c1) {
return -1;
} else {
return 0;
}
} else if (num0 > num1) {
return 1;
} else {
return -1;
}
}
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_){
file *file0 = (file*)file0_;
file *file1 = (file*)file1_;
if (file0->file_type & (FILE_TYPE_SYMLINK | FILE_TYPE_DIR) && !(file1->file_type & (FILE_TYPE_SYMLINK | FILE_TYPE_DIR))) {
return -1;
}
if (!(file0->file_type & (FILE_TYPE_SYMLINK | FILE_TYPE_DIR)) && file1->file_type & (FILE_TYPE_SYMLINK | FILE_TYPE_DIR)) {
return 1;
}
int random = rand();
if (random & 1) {
return 1;
} else {
return -1;
}
}
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 (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);
}
}
}
}