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

📄 list.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
字号:
/*------------------------------------------------------------------------- * * list.c *	  various list handling routines * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION *	  $Header: /usr/local/cvsroot/pgsql/src/backend/nodes/list.c,v 1.21 1999/05/25 16:09:08 momjian Exp $ * * NOTES *	  XXX a few of the following functions are duplicated to handle *		  List of pointers and List of integers separately. Some day, *		  someone should unify them.			- ay 11/2/94 *	  This file needs cleanup. * * HISTORY *	  AUTHOR			DATE			MAJOR EVENT *	  Andrew Yu			Oct, 1994		file creation * *------------------------------------------------------------------------- */#include <stdarg.h>#include "postgres.h"#include "nodes/pg_list.h"#include "nodes/parsenodes.h"#include "utils/builtins.h"		/* for namecpy */#include "utils/elog.h"#include "utils/palloc.h"/* *	makeList * *	Take varargs, terminated by -1, and make a List */List *makeList(void *elem,...){	va_list		args;	List	   *retval = NIL;	List	   *temp = NIL;	List	   *tempcons = NIL;	va_start(args, elem);	temp = elem;	while (temp != (void *) -1)	{		temp = lcons(temp, NIL);		if (tempcons == NIL)			retval = temp;		else			lnext(tempcons) = temp;		tempcons = temp;		temp = va_arg(args, void *);	}	va_end(args);	return retval;}/* *	lcons * *	Add obj to the front of list, or make a new list if 'list' is NIL */List *lcons(void *obj, List *list){	List	   *l = makeNode(List);	lfirst(l) = obj;	lnext(l) = list;	return l;}/* *	lconsi * *	Same as lcons, but for integer data */List *lconsi(int datum, List *list){	List	   *l = makeNode(List);	lfirsti(l) = datum;	lnext(l) = list;	return l;}/* *	lappend * *	Add obj to the end of list, or make a new list if 'list' is NIL * * MORE EXPENSIVE THAN lcons */List *lappend(List *list, void *obj){	return nconc(list, lcons(obj, NIL));}/* *	lappendi * *	Same as lappend, but for integers */List *lappendi(List *list, int datum){	return nconc(list, lconsi(datum, NIL));}/* *	nconc * *	Concat l2 on to the end of l1 */List *nconc(List *l1, List *l2){	List	   *temp;	if (l1 == NIL)		return l2;	if (l2 == NIL)		return l1;	if (l1 == l2)		elog(ERROR, "tryout to nconc a list to itself");	for (temp = l1; lnext(temp) != NULL; temp = lnext(temp))		;	lnext(temp) = l2;	return l1;					/* list1 is now list1+list2  */}#ifdef NOT_USEDList *nreverse(List *list){	List	   *rlist = NIL;	List	   *p = NIL;	if (list == NULL)		return NIL;	if (length(list) == 1)		return list;	for (p = list; p != NULL; p = lnext(p))		rlist = lcons(lfirst(p), rlist);	lfirst(list) = lfirst(rlist);	lnext(list) = lnext(rlist);	return list;}#endif/* *	makeInteger */Value *makeInteger(long i){	Value	   *v = makeNode(Value);	v->type = T_Integer;	v->val.ival = i;	return v;}/* *	makeFloat */Value *makeFloat(double d){	Value	   *v = makeNode(Value);	v->type = T_Float;	v->val.dval = d;	return v;}/* *	makeString */Value *makeString(char *str){	Value	   *v = makeNode(Value);	v->type = T_String;	v->val.str = str;	return v;}/* *	nth * *	Get the n'th element of the list.  First element is 0th. */void *nth(int n, List *l){	/* XXX assume list is long enough */	while (n > 0)	{		l = lnext(l);		n--;	}	return lfirst(l);}/* *	nthi * *	Same as nthi, but for integers */intnthi(int n, List *l){	/* XXX assume list is long enough */	while (n > 0)	{		l = lnext(l);		n--;	}	return lfirsti(l);}/* this is here solely for rt_store. Get rid of me some day! */voidset_nth(List *l, int n, void *elem){	/* XXX assume list is long enough */	while (n > 0)	{		l = lnext(l);		n--;	}	lfirst(l) = elem;	return;}/* *	length * *	Get the length of l */intlength(List *l){	int			i = 0;	while (l != NIL)	{		l = lnext(l);		i++;	}	return i;}/* *	freeList * *	Free the List nodes of a list */voidfreeList(List *list){	while (list != NIL)	{		List	   *l = list;		list = lnext(list);		pfree(l);	}}#ifdef NOT_USED/* * below are for backwards compatibility */List *append(List *l1, List *l2){	List	   *newlist,			   *newlist2,			   *p;	if (l1 == NIL)		return copyObject(l2);	newlist = copyObject(l1);	newlist2 = copyObject(l2);	for (p = newlist; lnext(p) != NIL; p = lnext(p))		;	lnext(p) = newlist2;	return newlist;}#endif#ifdef NOT_USED/* * below are for backwards compatibility */List *intAppend(List *l1, List *l2){	List	   *newlist,			   *newlist2,			   *p;	if (l1 == NIL)		return listCopy(l2);	newlist = listCopy(l1);	newlist2 = listCopy(l2);	for (p = newlist; lnext(p) != NIL; p = lnext(p))		;	lnext(p) = newlist2;	return newlist;}#endif/* *		same * *		Returns t if two lists contain the same elements. *		 now defined in lispdep.c * * XXX only good for IntList	-ay */boolsame(List *l1, List *l2){	List	   *temp = NIL;	if (l1 == NULL)		return l2 == NULL;	if (l2 == NULL)		return l1 == NULL;	if (length(l1) == length(l2))	{		foreach(temp, l1)		{			if (!intMember(lfirsti(temp), l2))				return false;		}		return true;	}	return false;}List *LispUnion(List *l1, List *l2){	List	   *retval = NIL;	List	   *i = NIL;	List	   *j = NIL;	if (l1 == NIL)		return l2;				/* XXX - should be copy of l2 */	if (l2 == NIL)		return l1;				/* XXX - should be copy of l1 */	foreach(i, l1)	{		foreach(j, l2)		{			if (!equal(lfirst(i), lfirst(j)))			{				retval = lappend(retval, lfirst(i));				break;			}		}	}	foreach(i, l2)		retval = lappend(retval, lfirst(i));	return retval;}List *LispUnioni(List *l1, List *l2){	List	   *retval = NIL;	List	   *i = NIL;	List	   *j = NIL;	if (l1 == NIL)		return l2;				/* XXX - should be copy of l2 */	if (l2 == NIL)		return l1;				/* XXX - should be copy of l1 */	foreach(i, l1)	{		foreach(j, l2)		{			if (lfirsti(i) != lfirsti(j))			{				retval = lappendi(retval, lfirsti(i));				break;			}		}	}	foreach(i, l2)		retval = lappendi(retval, lfirsti(i));	return retval;}/* * member() * - nondestructive, returns t iff l1 is a member of the list *	 l2 */boolmember(void *l1, List *l2){	List	   *i;	foreach(i, l2)		if (equal((Node *) l1, (Node *) lfirst(i)))		return true;	return false;}boolintMember(int l1, List *l2){	List	   *i;	foreach(i, l2)		if (l1 == lfirsti(i))		return true;	return false;}/* * lremove - *	  only does pointer comparisons. Removes 'elem' from the the linked list. */List *lremove(void *elem, List *list){	List	   *l;	List	   *prev = NIL;	List	   *result = list;	foreach(l, list)	{		if (elem == lfirst(l))			break;		prev = l;	}	if (l != NULL)	{		if (prev == NIL)			result = lnext(list);		else			lnext(prev) = lnext(l);	}	return result;}/* *	LispRemove */List *LispRemove(void *elem, List *list){	List	   *temp = NIL;	List	   *prev = NIL;	if (equal(elem, lfirst(list)))		return lnext(list);	temp = lnext(list);	prev = list;	while (temp != NIL)	{		if (equal(elem, lfirst(temp)))		{			lnext(prev) = lnext(temp);			break;		}		temp = lnext(temp);		prev = lnext(prev);	}	return list;}#ifdef NOT_USEDList *intLispRemove(int elem, List *list){	List	   *temp = NIL;	List	   *prev = NIL;	if (elem == lfirsti(list))		return lnext(list);	temp = lnext(list);	prev = list;	while (temp != NIL)	{		if (elem == lfirsti(temp))		{			lnext(prev) = lnext(temp);			break;		}		temp = lnext(temp);		prev = lnext(prev);	}	return list;}#endif/* *	set_difference * *	Return l1 without the elements in l2. */List *set_difference(List *l1, List *l2){	List	   *temp1 = NIL;	List	   *result = NIL;	if (l2 == NIL)		return l1;	foreach(temp1, l1)	{		if (!member(lfirst(temp1), l2))			result = lappend(result, lfirst(temp1));	}	return result;}/* *	set_differencei * *	Same as set_difference, but for integers */List *set_differencei(List *l1, List *l2){	List	   *temp1 = NIL;	List	   *result = NIL;	if (l2 == NIL)		return l1;	foreach(temp1, l1)	{		if (!intMember(lfirsti(temp1), l2))			result = lappendi(result, lfirsti(temp1));	}	return result;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -