|
|
1.1 root 1: /*
2: * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
3: * All rights reserved.
4: *
5: * This code is derived from software contributed to Berkeley by
6: * Adam de Boor.
7: *
8: * Redistribution and use in source and binary forms are permitted
9: * provided that: (1) source distributions retain this entire copyright
10: * notice and comment, and (2) distributions including binaries display
11: * the following acknowledgement: ``This product includes software
12: * developed by the University of California, Berkeley and its contributors''
13: * in the documentation or other materials provided with the distribution
14: * and in all advertising materials mentioning features or use of this
15: * software. Neither the name of the University nor the names of its
16: * contributors may be used to endorse or promote products derived
17: * from this software without specific prior written permission.
18: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
19: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
20: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21: */
22:
23: #ifndef lint
24: static char sccsid[] = "@(#)lstConcat.c 5.3 (Berkeley) 6/1/90";
25: #endif /* not lint */
26:
27: /*-
28: * listConcat.c --
29: * Function to concatentate two lists.
30: */
31:
32: #include "lstInt.h"
33:
34: /*-
35: *-----------------------------------------------------------------------
36: * Lst_Concat --
37: * Concatenate two lists. New elements are created to hold the data
38: * elements, if specified, but the elements themselves are not copied.
39: * If the elements should be duplicated to avoid confusion with another
40: * list, the Lst_Duplicate function should be called first.
41: * If LST_CONCLINK is specified, the second list is destroyed since
42: * its pointers have been corrupted and the list is no longer useable.
43: *
44: * Results:
45: * SUCCESS if all went well. FAILURE otherwise.
46: *
47: * Side Effects:
48: * New elements are created and appended the the first list.
49: *-----------------------------------------------------------------------
50: */
51: ReturnStatus
52: Lst_Concat (l1, l2, flags)
53: Lst l1; /* The list to which l2 is to be appended */
54: Lst l2; /* The list to append to l1 */
55: int flags; /* LST_CONCNEW if LstNode's should be duplicated
56: * LST_CONCLINK if should just be relinked */
57: {
58: register ListNode ln; /* original LstNode */
59: register ListNode nln; /* new LstNode */
60: register ListNode last; /* the last element in the list. Keeps
61: * bookkeeping until the end */
62: register List list1 = (List)l1;
63: register List list2 = (List)l2;
64:
65: if (!LstValid (l1) || !LstValid (l2)) {
66: return (FAILURE);
67: }
68:
69: if (flags == LST_CONCLINK) {
70: if (list2->firstPtr != NilListNode) {
71: /*
72: * We set the nextPtr of the
73: * last element of list two to be NIL to make the loop easier and
74: * so we don't need an extra case should the first list turn
75: * out to be non-circular -- the final element will already point
76: * to NIL space and the first element will be untouched if it
77: * existed before and will also point to NIL space if it didn't.
78: */
79: list2->lastPtr->nextPtr = NilListNode;
80: /*
81: * So long as the second list isn't empty, we just link the
82: * first element of the second list to the last element of the
83: * first list. If the first list isn't empty, we then link the
84: * last element of the list to the first element of the second list
85: * The last element of the second list, if it exists, then becomes
86: * the last element of the first list.
87: */
88: list2->firstPtr->prevPtr = list1->lastPtr;
89: if (list1->lastPtr != NilListNode) {
90: list1->lastPtr->nextPtr = list2->firstPtr;
91: }
92: list1->lastPtr = list2->lastPtr;
93: }
94: if (list1->isCirc && list1->firstPtr != NilListNode) {
95: /*
96: * If the first list is supposed to be circular and it is (now)
97: * non-empty, we must make sure it's circular by linking the
98: * first element to the last and vice versa
99: */
100: list1->firstPtr->prevPtr = list1->lastPtr;
101: list1->lastPtr->nextPtr = list1->firstPtr;
102: }
103: free ((Address)l2);
104: } else if (list2->firstPtr != NilListNode) {
105: /*
106: * We set the nextPtr of the last element of list 2 to be nil to make
107: * the loop less difficult. The loop simply goes through the entire
108: * second list creating new LstNodes and filling in the nextPtr, and
109: * prevPtr to fit into l1 and its datum field from the
110: * datum field of the corresponding element in l2. The 'last' node
111: * follows the last of the new nodes along until the entire l2 has
112: * been appended. Only then does the bookkeeping catch up with the
113: * changes. During the first iteration of the loop, if 'last' is nil,
114: * the first list must have been empty so the newly-created node is
115: * made the first node of the list.
116: */
117: list2->lastPtr->nextPtr = NilListNode;
118: for (last = list1->lastPtr, ln = list2->firstPtr;
119: ln != NilListNode;
120: ln = ln->nextPtr)
121: {
122: PAlloc (nln, ListNode);
123: nln->datum = ln->datum;
124: if (last != NilListNode) {
125: last->nextPtr = nln;
126: } else {
127: list1->firstPtr = nln;
128: }
129: nln->prevPtr = last;
130: nln->flags = nln->useCount = 0;
131: last = nln;
132: }
133:
134: /*
135: * Finish bookkeeping. The last new element becomes the last element
136: * of list one.
137: */
138: list1->lastPtr = last;
139:
140: /*
141: * The circularity of both list one and list two must be corrected
142: * for -- list one because of the new nodes added to it; list two
143: * because of the alteration of list2->lastPtr's nextPtr to ease the
144: * above for loop.
145: */
146: if (list1->isCirc) {
147: list1->lastPtr->nextPtr = list1->firstPtr;
148: list1->firstPtr->prevPtr = list1->lastPtr;
149: } else {
150: last->nextPtr = NilListNode;
151: }
152:
153: if (list2->isCirc) {
154: list2->lastPtr->nextPtr = list2->firstPtr;
155: }
156: }
157:
158: return (SUCCESS);
159: }
160:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.