source: trunk/src/kmk/lst.lib/lstConcat.c@ 28

Last change on this file since 28 was 25, checked in by bird, 23 years ago

This commit was generated by cvs2svn to compensate for changes in r24,
which included commits to RCS files with non-trunk default branches.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.7 KB
Line 
1/*
2 * Copyright (c) 1988, 1989, 1990, 1993
3 * The Regents of the University of California. 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, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
36 * $FreeBSD: src/usr.bin/make/lst.lib/lstConcat.c,v 1.7 1999/08/28 01:03:47 peter Exp $
37 */
38
39#ifndef lint
40static char sccsid[] = "@(#)lstConcat.c 8.1 (Berkeley) 6/6/93";
41#endif /* not lint */
42
43/*-
44 * listConcat.c --
45 * Function to concatentate two lists.
46 */
47
48#include "lstInt.h"
49
50/*-
51 *-----------------------------------------------------------------------
52 * Lst_Concat --
53 * Concatenate two lists. New elements are created to hold the data
54 * elements, if specified, but the elements themselves are not copied.
55 * If the elements should be duplicated to avoid confusion with another
56 * list, the Lst_Duplicate function should be called first.
57 * If LST_CONCLINK is specified, the second list is destroyed since
58 * its pointers have been corrupted and the list is no longer useable.
59 *
60 * Results:
61 * SUCCESS if all went well. FAILURE otherwise.
62 *
63 * Side Effects:
64 * New elements are created and appended the the first list.
65 *-----------------------------------------------------------------------
66 */
67ReturnStatus
68Lst_Concat (l1, l2, flags)
69 Lst l1; /* The list to which l2 is to be appended */
70 Lst l2; /* The list to append to l1 */
71 int flags; /* LST_CONCNEW if LstNode's should be duplicated
72 * LST_CONCLINK if should just be relinked */
73{
74 register ListNode ln; /* original LstNode */
75 register ListNode nln; /* new LstNode */
76 register ListNode last; /* the last element in the list. Keeps
77 * bookkeeping until the end */
78 register List list1 = (List)l1;
79 register List list2 = (List)l2;
80
81 if (!LstValid (l1) || !LstValid (l2)) {
82 return (FAILURE);
83 }
84
85 if (flags == LST_CONCLINK) {
86 if (list2->firstPtr != NilListNode) {
87 /*
88 * We set the nextPtr of the
89 * last element of list two to be NIL to make the loop easier and
90 * so we don't need an extra case should the first list turn
91 * out to be non-circular -- the final element will already point
92 * to NIL space and the first element will be untouched if it
93 * existed before and will also point to NIL space if it didn't.
94 */
95 list2->lastPtr->nextPtr = NilListNode;
96 /*
97 * So long as the second list isn't empty, we just link the
98 * first element of the second list to the last element of the
99 * first list. If the first list isn't empty, we then link the
100 * last element of the list to the first element of the second list
101 * The last element of the second list, if it exists, then becomes
102 * the last element of the first list.
103 */
104 list2->firstPtr->prevPtr = list1->lastPtr;
105 if (list1->lastPtr != NilListNode) {
106 list1->lastPtr->nextPtr = list2->firstPtr;
107 } else {
108 list1->firstPtr = list2->firstPtr;
109 }
110 list1->lastPtr = list2->lastPtr;
111 }
112 if (list1->isCirc && list1->firstPtr != NilListNode) {
113 /*
114 * If the first list is supposed to be circular and it is (now)
115 * non-empty, we must make sure it's circular by linking the
116 * first element to the last and vice versa
117 */
118 list1->firstPtr->prevPtr = list1->lastPtr;
119 list1->lastPtr->nextPtr = list1->firstPtr;
120 }
121 free ((Address)l2);
122 } else if (list2->firstPtr != NilListNode) {
123 /*
124 * We set the nextPtr of the last element of list 2 to be nil to make
125 * the loop less difficult. The loop simply goes through the entire
126 * second list creating new LstNodes and filling in the nextPtr, and
127 * prevPtr to fit into l1 and its datum field from the
128 * datum field of the corresponding element in l2. The 'last' node
129 * follows the last of the new nodes along until the entire l2 has
130 * been appended. Only then does the bookkeeping catch up with the
131 * changes. During the first iteration of the loop, if 'last' is nil,
132 * the first list must have been empty so the newly-created node is
133 * made the first node of the list.
134 */
135 list2->lastPtr->nextPtr = NilListNode;
136 for (last = list1->lastPtr, ln = list2->firstPtr;
137 ln != NilListNode;
138 ln = ln->nextPtr)
139 {
140 PAlloc (nln, ListNode);
141 nln->datum = ln->datum;
142 if (last != NilListNode) {
143 last->nextPtr = nln;
144 } else {
145 list1->firstPtr = nln;
146 }
147 nln->prevPtr = last;
148 nln->flags = nln->useCount = 0;
149 last = nln;
150 }
151
152 /*
153 * Finish bookkeeping. The last new element becomes the last element
154 * of list one.
155 */
156 list1->lastPtr = last;
157
158 /*
159 * The circularity of both list one and list two must be corrected
160 * for -- list one because of the new nodes added to it; list two
161 * because of the alteration of list2->lastPtr's nextPtr to ease the
162 * above for loop.
163 */
164 if (list1->isCirc) {
165 list1->lastPtr->nextPtr = list1->firstPtr;
166 list1->firstPtr->prevPtr = list1->lastPtr;
167 } else {
168 last->nextPtr = NilListNode;
169 }
170
171 if (list2->isCirc) {
172 list2->lastPtr->nextPtr = list2->firstPtr;
173 }
174 }
175
176 return (SUCCESS);
177}
178
Note: See TracBrowser for help on using the repository browser.