📄 linelist.c
字号:
/* linelist.c
*
* Copyright (c) 1996-2001 Mike Gleason, NCEMRSoft.
* All rights reserved.
*
*/
#include "syshdrs.h"
/* Dynamically make a copy of a string. */
char *
StrDup(const char *buf)
{
char *cp;
size_t len;
if (buf == NULL)
return (NULL);
len = strlen(buf) + 1;
cp = (char *) malloc(len);
if (cp != NULL)
(void) memcpy(cp, buf, len);
return (cp);
} /* StrDup */
/* Disposes each node of a LineList. Does a few extra things
* so the disposed memory won't be very useful after it is freed.
*/
void
DisposeLineListContents(LineListPtr list)
{
LinePtr lp, lp2;
for (lp = list->first; lp != NULL; ) {
lp2 = lp;
lp = lp->next;
if (lp2->line != NULL) {
lp2->line[0] = '\0';
free(lp2->line);
}
free(lp2);
}
/* Same as InitLineList. */
(void) memset(list, 0, sizeof(LineList));
} /* DisposeLineListContents */
void
InitLineList(LineListPtr list)
{
(void) memset(list, 0, sizeof(LineList));
} /* InitLineList */
LinePtr
RemoveLine(LineListPtr list, LinePtr killMe)
{
LinePtr nextLine, prevLine;
nextLine = killMe->next;
prevLine = killMe->prev;
if (killMe->line != NULL) {
killMe->line[0] = '\0'; /* Make it useless just in case. */
free(killMe->line);
}
if (list->first == killMe)
list->first = nextLine;
if (list->last == killMe)
list->last = prevLine;
if (nextLine != NULL)
nextLine->prev = prevLine;
if (prevLine != NULL)
prevLine->next = nextLine;
free(killMe);
list->nLines--;
return (nextLine);
} /* RemoveLine */
/* Adds a string to the LineList specified. */
LinePtr
AddLine(LineListPtr list, const char *buf1)
{
LinePtr lp;
char *buf;
lp = (LinePtr) malloc(sizeof(Line));
if (lp != NULL) {
buf = StrDup(buf1);
if (buf == NULL) {
free(lp);
lp = NULL;
} else {
lp->line = buf;
lp->next = NULL;
if (list->first == NULL) {
list->first = list->last = lp;
lp->prev = NULL;
list->nLines = 1;
} else {
lp->prev = list->last;
list->last->next = lp;
list->last = lp;
list->nLines++;
}
}
}
return lp;
} /* AddLine */
int
CopyLineList(LineListPtr dst, LineListPtr src)
{
LinePtr lp, lp2;
InitLineList(dst);
for (lp = src->first; lp != NULL; ) {
lp2 = lp;
lp = lp->next;
if (lp2->line != NULL) {
if (AddLine(dst, lp2->line) == NULL) {
DisposeLineListContents(dst);
return (-1);
}
}
}
return (0);
} /* CopyLineList */
/* Disposes each node of a FileInfoList. Does a few extra things
* so the disposed memory won't be very useful after it is freed.
*/
void
DisposeFileInfoListContents(FileInfoListPtr list)
{
FileInfoPtr lp, lp2;
for (lp = list->first; lp != NULL; ) {
lp2 = lp;
lp = lp->next;
if (lp2->relname != NULL) {
lp2->relname[0] = '\0';
free(lp2->relname);
}
if (lp2->lname != NULL) {
lp2->lname[0] = '\0';
free(lp2->lname);
}
if (lp2->rname != NULL) {
lp2->rname[0] = '\0';
free(lp2->rname);
}
if (lp2->rlinkto != NULL) {
lp2->rlinkto[0] = '\0';
free(lp2->rlinkto);
}
if (lp2->plug != NULL) {
lp2->plug[0] = '\0';
free(lp2->plug);
}
free(lp2);
}
if (list->vec != NULL)
free(list->vec);
/* Same as InitFileInfoList. */
(void) memset(list, 0, sizeof(FileInfoList));
} /* DisposeFileInfoListContents */
void
InitFileInfoList(FileInfoListPtr list)
{
(void) memset(list, 0, sizeof(FileInfoList));
} /* InitFileInfoList */
static int
TimeCmp(const void *a, const void *b)
{
FileInfoPtr *fipa, *fipb;
fipa = (FileInfoPtr *) a;
fipb = (FileInfoPtr *) b;
if ((**fipb).mdtm == (**fipa).mdtm)
return (0);
else if ((**fipb).mdtm < (**fipa).mdtm)
return (-1);
return (1);
} /* TimeCmp */
static int
ReverseTimeCmp(const void *a, const void *b)
{
FileInfoPtr *fipa, *fipb;
fipa = (FileInfoPtr *) a;
fipb = (FileInfoPtr *) b;
if ((**fipa).mdtm == (**fipb).mdtm)
return (0);
else if ((**fipa).mdtm < (**fipb).mdtm)
return (-1);
return (1);
} /* ReverseTimeCmp */
static int
SizeCmp(const void *a, const void *b)
{
FileInfoPtr *fipa, *fipb;
fipa = (FileInfoPtr *) a;
fipb = (FileInfoPtr *) b;
if ((**fipb).size == (**fipa).size)
return (0);
else if ((**fipb).size < (**fipa).size)
return (-1);
return (1);
} /* SizeCmp */
static int
ReverseSizeCmp(const void *a, const void *b)
{
FileInfoPtr *fipa, *fipb;
fipa = (FileInfoPtr *) a;
fipb = (FileInfoPtr *) b;
if ((**fipa).size == (**fipb).size)
return (0);
else if ((**fipa).size < (**fipb).size)
return (-1);
return (1);
} /* ReverseSizeCmp */
static int
ReverseNameCmp(const void *a, const void *b)
{
FileInfoPtr *fipa, *fipb;
fipa = (FileInfoPtr *) a;
fipb = (FileInfoPtr *) b;
#ifdef HAVE_SETLOCALE
return (strcoll((**fipb).relname, (**fipa).relname));
#else
return (strcmp((**fipb).relname, (**fipa).relname));
#endif
} /* ReverseNameCmp */
static int
NameCmp(const void *a, const void *b)
{
FileInfoPtr *fipa, *fipb;
fipa = (FileInfoPtr *) a;
fipb = (FileInfoPtr *) b;
#ifdef HAVE_SETLOCALE
return (strcoll((**fipa).relname, (**fipb).relname));
#else
return (strcmp((**fipa).relname, (**fipb).relname));
#endif
} /* NameCmp */
static int
BreadthFirstCmp(const void *a, const void *b)
{
FileInfoPtr *fipa, *fipb;
char *cp, *cpa, *cpb;
int depth, deptha, depthb;
int c;
fipa = (FileInfoPtr *) a;
fipb = (FileInfoPtr *) b;
cpa = (**fipa).relname;
cpb = (**fipb).relname;
for (cp = cpa, depth = 0;;) {
c = *cp++;
if (c == '\0')
break;
if ((c == '/') || (c == '\\')) {
depth++;
}
}
deptha = depth;
for (cp = cpb, depth = 0;;) {
c = *cp++;
if (c == '\0')
break;
if ((c == '/') || (c == '\\')) {
depth++;
}
}
depthb = depth;
if (deptha < depthb)
return (-1);
else if (deptha > depthb)
return (1);
#ifdef HAVE_SETLOCALE
return (strcoll(cpa, cpb));
#else
return (strcmp(cpa, cpb));
#endif
} /* BreadthFirstCmp */
void
SortFileInfoList(FileInfoListPtr list, int sortKey, int sortOrder)
{
FileInfoVec fiv;
FileInfoPtr fip;
int i, j, n, n2;
fiv = list->vec;
if (fiv == NULL)
return;
if (list->sortKey == sortKey) {
if (list->sortOrder == sortOrder)
return; /* Already sorted they you want. */
/* Reverse the sort. */
n = list->nFileInfos;
if (n > 1) {
n2 = n / 2;
for (i=0; i<n2; i++) {
j = n - i - 1;
fip = fiv[i];
fiv[i] = fiv[j];
fiv[j] = fip;
}
}
list->sortOrder = sortOrder;
} else if ((sortKey == 'n') && (sortOrder == 'a')) {
qsort(fiv, (size_t) list->nFileInfos, sizeof(FileInfoPtr),
NameCmp);
list->sortKey = sortKey;
list->sortOrder = sortOrder;
} else if ((sortKey == 'n') && (sortOrder == 'd')) {
qsort(fiv, (size_t) list->nFileInfos, sizeof(FileInfoPtr),
ReverseNameCmp);
list->sortKey = sortKey;
list->sortOrder = sortOrder;
} else if ((sortKey == 't') && (sortOrder == 'a')) {
qsort(fiv, (size_t) list->nFileInfos, sizeof(FileInfoPtr),
TimeCmp);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -