⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 linelist.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* 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 + -