// filelist.h
// BarSSoft, 1999
#ifndef __FILELIST_H__
#define __FILELIST_H__
#include <pthread.h>
#define MAX_LIST_ITEMS 200
typedef enum
{
NoSort,
SortByName,
SortByType,
SortBySize,
SortByTime
} SortField;
struct sFileInf
{
char *name;
char *type;
int size;
time_t mtime;
struct sFileInf *next;
};
typedef struct sFileInf FileInf;
extern FileInf *fileList[MAX_LIST_ITEMS];
extern int nextItem;
extern SortField sortField;
extern int ascSort;
extern pthread_mutex_t lockFileList;
int fileList_Add(FileInf *item);
FileInf *fileList_CopyItem(const FileInf *src);
void fileList_Clear(void);
void fileList_Print(void);
void fileList_Sort(SortField field, int sortAsc);
#endif
#include
#include
#include "filelist.h"
FileInf *fileList[MAX_LIST_ITEMS];
int nextItem;
SortField sortField = NoSort;
int ascSort = 1;
pthread_mutex_t lockFileList;
static FileInf *top = 0;
#define MAX_INT_SEGMENTS 10
#define SEGMENT_DELTA 1000000000/MAX_INT_SEGMENTS
#define MAX_CHAR_SEGMENTS 27
int fileList_Add(FileInf *item)
{
int index;
item->next = top;
top = item;
fileList[nextItem] = item;
index = nextItem++;
if (sortField == NoSort || nextItem == MAX_LIST_ITEMS)
{
fileList_Print();
fileList_Clear();
}
return index;
}
FileInf *fileList_CopyItem(const FileInf *src)
{
FileInf* dest;
dest = (FileInf*)malloc(sizeof(FileInf));
memcpy(dest, src, sizeof(FileInf));
dest->name = (char*)malloc(strlen(src->name)+1);
strcpy(dest->name, src->name);
dest->type = (char*)malloc(strlen(src->type)+1);
strcpy(dest->type, src->type);
return dest;
}
void fileList_Clear(void)
{
int i;
for (i = 0; i < nextItem; i++)
{
free(fileList[i]->name);
free(fileList[i]->type);
free(fileList[i]);
}
nextItem = 0;
top = 0;
}
void fileList_Print(void)
{
FileInf *item;
struct tm *t;
int i = 0;
char s[10];
if (sortField != NoSort)
fileList_Sort(sortField, ascSort);
printf("%79s\r", "");
for (item = top; item; item = item->next)
{
t = localtime(&(item->mtime));
if (item->size < 10000)
sprintf(s, "%i", item->size);
else
if (item->size < 10000000)
sprintf(s, "%iK", item->size / 1000);
else
sprintf(s, "%iM", item->size / 1000000);
printf("%-30s\t%6s %2.2i.%2.2i.%4i %2.2i:%2.2i:%2.2i %s\n", item->name, s,
t->tm_mday, t->tm_mon + 1, 1900 + t->tm_year,
t->tm_hour, t->tm_min, t->tm_sec,
item->type);
}
}
char *returnName(FileInf *item)
{
return item->name;
}
char *returnType(FileInf *item)
{
return item->type;
}
int returnSize(FileInf *item)
{
return item->size;
}
int returnTime(FileInf *item)
{
return (int)item->mtime;
}
void joinSegments(FileInf **m, int max)
{
int i;
FileInf *item;
for (i = 0; i < max && !*m; i++, m++)
;
if (i >= max)
{
perror("all M[i] are null");
return;
}
top = *m;
item = top;
for(i++, m++; i < MAX_INT_SEGMENTS; i++, m++)
{
if (*m)
{
while (item->next) item = item->next;
item->next = *m;
}
}
}
void sortInt(int val(FileInf*))
{
FileInf *M[MAX_INT_SEGMENTS], *item, *cmpItem, *prev;
int i, v, ind;
memset(M, 0, MAX_INT_SEGMENTS * sizeof(FileInf*));
for (i = 0; i < nextItem; i++)
{
item = fileList[i];
ind = val(item) / SEGMENT_DELTA;
if (ind > MAX_INT_SEGMENTS - 1)
ind = MAX_INT_SEGMENTS - 1;
v = val(item);
if (!M[ind] || v <= val(M[ind]))
{
item->next = M[ind];
M[ind] = item;
}
else
{
for (prev = cmpItem = M[ind];
cmpItem && v > val(cmpItem);
prev = cmpItem, cmpItem = cmpItem->next)
;
item->next = cmpItem;
prev->next = item;
}
}
joinSegments(&M[0], MAX_INT_SEGMENTS);
}
int strcomp (char *s1, char *s2)
{
while (s1 && s2 && tolower(*s1) == tolower(*s2))
{s1++; s2++;}
if (!s1 && !s2)
return 0;
else
if (!s1)
return -1;
else
if (!s2)
return 1;
else
if (tolower(*s1) < tolower(*s2))
return -1;
else
return 1;
}
void sortChar(char *val(FileInf*))
{
FileInf *M[MAX_CHAR_SEGMENTS], *item, *cmpItem, *prev;
int i, ind = 0;
char *s, c;
memset(M, 0, MAX_CHAR_SEGMENTS * sizeof(FileInf*));
for (i = 0; i < nextItem; i++)
{
item = fileList[i];
s = val(item);
c = tolower(*s);
if (isalpha(c))
ind = (int)(c - 'a') + 1;
else
ind = 0;
if (!M[ind] || strcomp(s, val(M[ind])) <= 0)
{
item->next = M[ind];
M[ind] = item;
}
else
{
for (prev = cmpItem = M[ind];
cmpItem && strcomp(s, val(cmpItem)) > 0;
prev = cmpItem, cmpItem = cmpItem->next)
;
item->next = cmpItem;
prev->next = item;
}
}
joinSegments(&M[0], MAX_CHAR_SEGMENTS);
}
void fileList_Sort(SortField field, int sortAsc)
{
FileInf *next, *tmp;
if (!top)
return;
switch (field)
{
case SortByName:
sortChar(returnName);
break;
case SortByType:
sortChar(returnType);
break;
case SortBySize:
sortInt(returnSize);
break;
case SortByTime:
sortInt(returnTime);
break;
default:
return;
}
if (!sortAsc)
{
for (next = top->next, top->next = 0; next;)
{
tmp = next->next;
next->next = top;
top = next;
next = tmp;
}
}
}