*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/list.c,v 1.25 1999/07/17 20:17:06 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/list.c,v 1.26 1999/08/14 19:29:35 tgl Exp $
*
* NOTES
* XXX a few of the following functions are duplicated to handle
return retval;
}
+/*
+ * 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;
+}
+
/*
* lcons
*
* nconc
*
* Concat l2 on to the end of l1
+ *
+ * NB: l1 is destructively changed! Use nconc(listCopy(l1), l2)
+ * if you need to make a merged list without touching the original lists.
*/
List *
nconc(List *l1, List *l2)
if (l1 == l2)
elog(ERROR, "tryout to nconc a list to itself");
- for (temp = l1; lnext(temp) != NULL; temp = lnext(temp))
+ for (temp = l1; lnext(temp) != NIL; temp = lnext(temp))
;
lnext(temp) = l2;
return l1; /* list1 is now list1+list2 */
}
-
-#ifdef NOT_USED
-List *
-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
*
n--;
}
lfirst(l) = elem;
- return;
}
/*
* freeList
*
* Free the List nodes of a list
+ * The pointed-to nodes, if any, are NOT freed.
+ * This works for integer lists too.
+ *
*/
void
freeList(List *list)
}
}
-#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
+ * Returns t if two lists contain the same elements
+ * (but unlike equal(), they need not be in the same order)
+ *
*
- * XXX only good for IntList -ay
+ * XXX should be called samei() --- only good for IntList -ay
*/
bool
same(List *l1, List *l2)
{
- List *temp = NIL;
+ List *temp;
- if (l1 == NULL)
- return l2 == NULL;
- if (l2 == NULL)
- return l1 == NULL;
+ if (l1 == NIL)
+ return l2 == NIL;
+ if (l2 == NIL)
+ return l1 == NIL;
if (length(l1) == length(l2))
{
foreach(temp, l1)
}
+/*
+ * Generate the union of two lists,
+ * ie, l1 plus all members of l2 that are not already in l1.
+ *
+ * NOTE: if there are duplicates in l1 they will still be duplicate in the
+ * result; but duplicates in l2 are discarded.
+ *
+ * The result is a fresh List, but it points to the same member nodes
+ * as were in the inputs.
+ */
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 */
+ List *retval = listCopy(l1);
+ List *i;
- foreach(i, l1)
+ foreach(i, l2)
{
- foreach(j, l2)
- {
- if (!equal(lfirst(i), lfirst(j)))
- {
- retval = lappend(retval, lfirst(i));
- break;
- }
- }
+ if (! member(lfirst(i), retval))
+ retval = lappend(retval, lfirst(i));
}
- 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 */
+ List *retval = listCopy(l1);
+ List *i;
- foreach(i, l1)
+ foreach(i, l2)
{
- foreach(j, l2)
- {
- if (lfirsti(i) != lfirsti(j))
- {
- retval = lappendi(retval, lfirsti(i));
- break;
- }
- }
+ if (! intMember(lfirsti(i), retval))
+ retval = lappendi(retval, lfirsti(i));
}
- foreach(i, l2)
- retval = lappendi(retval, lfirsti(i));
-
return retval;
}
/*
* member()
- * - nondestructive, returns t iff l1 is a member of the list
- * l2
+ * nondestructive, returns t iff l1 is a member of the list l2
*/
bool
member(void *l1, List *l2)
List *i;
foreach(i, l2)
+ {
if (equal((Node *) l1, (Node *) lfirst(i)))
- return true;
+ return true;
+ }
return false;
}
List *i;
foreach(i, l2)
+ {
if (l1 == lfirsti(i))
- return true;
+ return true;
+ }
return false;
}
/*
- * lremove -
- * only does pointer comparisons. Removes 'elem' from the the linked list.
+ * lremove
+ * Removes 'elem' from the the linked list.
+ * This version matches 'elem' using simple pointer comparison.
+ * See also LispRemove.
*/
List *
lremove(void *elem, List *list)
break;
prev = l;
}
- if (l != NULL)
+ if (l != NIL)
{
if (prev == NIL)
- result = lnext(list);
+ result = lnext(l);
else
lnext(prev) = lnext(l);
}
/*
* LispRemove
+ * Removes 'elem' from the the linked list.
+ * This version matches 'elem' using equal().
+ * (If there is more than one equal list member, the first is removed.)
+ * See also lremove.
*/
List *
LispRemove(void *elem, List *list)
{
- List *temp = NIL;
+ List *l;
List *prev = NIL;
+ List *result = list;
- if (equal(elem, lfirst(list)))
- return lnext(list);
-
- temp = lnext(list);
- prev = list;
- while (temp != NIL)
+ foreach(l, list)
{
- if (equal(elem, lfirst(temp)))
- {
- lnext(prev) = lnext(temp);
+ if (equal(elem, lfirst(l)))
break;
- }
- temp = lnext(temp);
- prev = lnext(prev);
+ prev = l;
+ }
+ if (l != NIL)
+ {
+ if (prev == NIL)
+ result = lnext(l);
+ else
+ lnext(prev) = lnext(l);
}
- return list;
+ return result;
}
#ifdef NOT_USED
+
List *
intLispRemove(int elem, List *list)
{
- List *temp = NIL;
+ List *l;
List *prev = NIL;
+ List *result = list;
- if (elem == lfirsti(list))
- return lnext(list);
-
- temp = lnext(list);
- prev = list;
- while (temp != NIL)
+ foreach(l, list)
{
- if (elem == lfirsti(temp))
- {
- lnext(prev) = lnext(temp);
+ if (elem == lfirsti(l))
break;
- }
- temp = lnext(temp);
- prev = lnext(prev);
+ prev = l;
+ }
+ if (l != NIL)
+ {
+ if (prev == NIL)
+ result = lnext(l);
+ else
+ lnext(prev) = lnext(l);
}
- return list;
+ return result;
}
#endif
* set_difference
*
* Return l1 without the elements in l2.
+ *
+ * The result is a fresh List, but it points to the same member nodes
+ * as were in l1.
*/
List *
set_difference(List *l1, List *l2)
{
- List *temp1 = NIL;
List *result = NIL;
+ List *i;
if (l2 == NIL)
- return l1;
+ return listCopy(l1); /* slightly faster path for empty l2 */
- foreach(temp1, l1)
+ foreach(i, l1)
{
- if (!member(lfirst(temp1), l2))
- result = lappend(result, lfirst(temp1));
+ if (! member(lfirst(i), l2))
+ result = lappend(result, lfirst(i));
}
return result;
}
List *
set_differencei(List *l1, List *l2)
{
- List *temp1 = NIL;
List *result = NIL;
+ List *i;
if (l2 == NIL)
- return l1;
+ return listCopy(l1); /* slightly faster path for empty l2 */
- foreach(temp1, l1)
+ foreach(i, l1)
{
- if (!intMember(lfirsti(temp1), l2))
- result = lappendi(result, lfirsti(temp1));
+ if (! intMember(lfirsti(i), l2))
+ result = lappendi(result, lfirsti(i));
}
return result;
}