mirror of
https://gittea.dev/nova/th.git
synced 2025-10-21 10:20:15 -04:00
169 lines
4.5 KiB
C
169 lines
4.5 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){
|
|
|
|
if (((file*)file0)->file_type & (FILE_TYPE_SYMLINK | FILE_TYPE_DIR) && !(((file*)file1)->file_type & (FILE_TYPE_SYMLINK | FILE_TYPE_DIR))) {
|
|
return -1;
|
|
}
|
|
if (!(((file*)file0)->file_type & (FILE_TYPE_SYMLINK | FILE_TYPE_DIR)) && ((file*)file1)->file_type & (FILE_TYPE_SYMLINK | 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 {
|
|
is_num = 0;
|
|
|
|
if ((*a >= '0') && (*a <= '9')) {
|
|
parsed_number0 = 0;
|
|
while((*a >= '0') && (*a <= '9')) {
|
|
parsed_number0 = (parsed_number0 * 10) + (*a - '0');
|
|
a++;
|
|
}
|
|
is_num |= 1;
|
|
}
|
|
if ((*b >= '0') && (*b <= '9')) {
|
|
parsed_number1 = 0;
|
|
while((*b >= '0') && (*b <= '9')) {
|
|
parsed_number1 = (parsed_number1 * 10) + (*b - '0');
|
|
b++;
|
|
}
|
|
is_num |= 2;
|
|
}
|
|
|
|
if (is_num) {
|
|
if (is_num == 1) {
|
|
if (*b < '0') {
|
|
result = 1;
|
|
} else {
|
|
result = -1;
|
|
}
|
|
break;
|
|
} else if (is_num == 2) {
|
|
if (*a < '0') {
|
|
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 */
|
|
}
|
|
|
|
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){
|
|
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){
|
|
|
|
if (((file*)file0)->file_type & (FILE_TYPE_SYMLINK | FILE_TYPE_DIR) && !(((file*)file1)->file_type & (FILE_TYPE_SYMLINK | FILE_TYPE_DIR))) {
|
|
return -1;
|
|
}
|
|
if (!(((file*)file0)->file_type & (FILE_TYPE_SYMLINK | FILE_TYPE_DIR)) && ((file*)file1)->file_type & (FILE_TYPE_SYMLINK | FILE_TYPE_DIR)) {
|
|
return 1;
|
|
}
|
|
return ((rand()%3)-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);
|
|
}
|
|
}
|
|
}
|
|
}
|