1
0
mirror of https://gittea.dev/nova/th.git synced 2025-10-21 10:20:15 -04:00
Files
th/sorting.c
2025-10-05 00:57:18 +02:00

171 lines
4.2 KiB
C

#include <curses.h>
#include <dirent.h>
#include <stdlib.h>
#include <strings.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include "defines.h"
extern time_t *seed;
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){
if ((((file*)file0)->file_type & FILE_TYPE_DIR) && !(((file*)file1)->file_type & FILE_TYPE_DIR)) {
return -1;
}
if (!(((file*)file0)->file_type & FILE_TYPE_DIR) && (((file*)file1)->file_type & FILE_TYPE_DIR)) {
return 1;
}
const unsigned char *a = (unsigned char*)((file*)file0)->file_name;
const unsigned char *b = (unsigned char*)((file*)file1)->file_name;
long parsed_number0 = 0;
long parsed_number1 = 0;
char is_num = 0;
char result = 0;
do {
if ((*a <= '9') && (*a >= '0')) {
parsed_number0 = 0;
do {
parsed_number0 = (parsed_number0 * 10) + (*a - '0');
a++;
} while((*a <= '9') && (*a >= '0'));
is_num |= 1;
}
if ((*b <= '9') && (*b >= '0')) {
parsed_number1 = 0;
do {
parsed_number1 = (parsed_number1 * 10) + (*b - '0');
b++;
} while((*b <= '9') && (*b >= '0'));
is_num |= 2;
}
if (is_num) {
if (is_num == 1) {
if (*b > '9') {
result = -1;
} else {
result = 1;
}
break;
} else if (is_num == 2) {
if (*a > '9') {
result = 1;
} else {
result = -1;
}
break;
} else {
if (parsed_number0 > parsed_number1) {
result = 1;
break;
} else if (parsed_number0 < parsed_number1) {
result = -1;
break;
}
}
/* those breaks are not set here, due to the possibillity that both numbers are equal
* in which case the comparison should continue */
is_num = 0;
}
unsigned char aa = ((*a >= 'A') && (*a <= 'Z')) ? (*a | ' ') : *a;
unsigned char bb = ((*b >= 'A') && (*b <= 'Z')) ? (*b | ' ') : *b;
/*using a simple aa - bb would occasionaly cause underflows with wide chars*/
result = ((aa == bb) ? 0 : ((aa > bb) ? 1 : -1 ));
a++;
b++;
} while (result == 0);
return result;
}
int sort_alpha(const void *file0, const void *file1){
if ((((file*)file0)->file_type & FILE_TYPE_DIR) && !(((file*)file1)->file_type & FILE_TYPE_DIR)) {
return -1;
}
if (!(((file*)file0)->file_type & FILE_TYPE_DIR) && (((file*)file1)->file_type & FILE_TYPE_DIR)) {
return 1;
}
return strcmp(((file*)file0)->file_name, ((file*)file1)->file_name);
}
int sort_random(const void *file0, const void *file1){
if ((((file*)file0)->file_type & FILE_TYPE_DIR) && !(((file*)file1)->file_type & FILE_TYPE_DIR)) {
return -1;
}
if (!(((file*)file0)->file_type & FILE_TYPE_DIR) && (((file*)file1)->file_type & FILE_TYPE_DIR)) {
return 1;
}
time_t num = (time_t)&seed;
unsigned long i;
for (i = 0; i < 6; i++){
num ^= *seed;
if (num%2) {
num ^= (time_t)&num;
num ^= num << i;
} else {
num ^= (time_t)&seed;
num ^= num >> i;
}
}
num ^= getpid();
return ((num%3) - 1);
}
int sort_type(const void *file0, const void *file1){
if ((((file*)file0)->file_type & FILE_TYPE_DIR) && !(((file*)file1)->file_type & FILE_TYPE_DIR)) {
return -1;
}
if (!(((file*)file0)->file_type & FILE_TYPE_DIR) && (((file*)file1)->file_type & FILE_TYPE_DIR)) {
return 1;
}
if (((file*)file0)->file_type == ((file*)file1)->file_type) {
/*somehow relying on the else below, occasionaly trips either one of the checked for conditions*/
return strcasecmp(((file*)file0)->file_name, ((file*)file1)->file_name);
} else if (((file*)file0)->file_type > ((file*)file1)->file_type) {
return -1;
}
return 1;
}
int sort_size(const void *file0, const void *file1){
if ((((file*)file0)->file_type & FILE_TYPE_DIR) && !(((file*)file1)->file_type & FILE_TYPE_DIR)) {
return -1;
}
if (!(((file*)file0)->file_type & FILE_TYPE_DIR) && (((file*)file1)->file_type & FILE_TYPE_DIR)) {
return 1;
}
if (((file*)file0)->file_size == ((file*)file1)->file_size) {
return strcasecmp(((file*)file0)->file_name, ((file*)file1)->file_name);
} else if (((file*)file0)->file_size > ((file*)file1)->file_size) {
return -1;
}
return 1;
}