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

Last change on this file since 19 was 9, checked in by bird, 23 years ago

Initial revision

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.6 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 * @(#)lstConcat.c 8.1 (Berkeley) 6/6/93
37 */
38
39#ifndef lint
40#include <sys/cdefs.h>
41__FBSDID("$FreeBSD: src/usr.bin/make/lst.lib/lstConcat.c,v 1.11 2002/10/09 02:00:22 jmallett Exp $");
42#endif /* not lint */
43
44/*-
45 * listConcat.c --
46 * Function to concatentate two lists.
47 */
48
49#include "lstInt.h"
50
51/*-
52 *-----------------------------------------------------------------------
53 * Lst_Concat --
54 * Concatenate two lists. New elements are created to hold the data
55 * elements, if specified, but the elements themselves are not copied.
56 * If the elements should be duplicated to avoid confusion with another
57 * list, the Lst_Duplicate function should be called first.
58 * If LST_CONCLINK is specified, the second list is destroyed since
59 * its pointers have been corrupted and the list is no longer useable.
60 *
61 * Results:
62 * SUCCESS if all went well. FAILURE otherwise.
63 *
64 * Side Effects:
65 * New elements are created and appended the the first list.
66 *-----------------------------------------------------------------------
67 */
68ReturnStatus
69Lst_Concat (l1, l2, flags)
70 Lst l1; /* The list to which l2 is to be appended */
71 Lst l2; /* The list to append to l1 */
72 int flags; /* LST_CONCNEW if LstNode's should be duplicated
73 * LST_CONCLINK if should just be relinked */
74{
75 register ListNode ln; /* original LstNode */
76 register ListNode nln; /* new LstNode */
77 register ListNode last; /* the last element in the list. Keeps
78 * bookkeeping until the end */
79 register List list1 = (List)l1;
80 register List list2 = (List)l2;
81
82 if (!LstValid (l1) || !LstValid (l2)) {
83 return (FAILURE);
84 }
85
86 if (flags == LST_CONCLINK) {
87 if (list2->firstPtr != NULL) {
88 /*
89 * We set the nextPtr of the
90 * last element of list two to be NULL to make the loop easier and
91 * so we don't need an extra case should the first list turn
92 * out to be non-circular -- the final element will already point
93 * to NULL space and the first element will be untouched if it
94 * existed before and will also point to NULL space if it didn't.
95 */
96 list2->lastPtr->nextPtr = NULL;
97 /*
98 * So long as the second list isn't empty, we just link the
99 * first element of the second list to the last element of the
100 * first list. If the first list isn't empty, we then link the
101 * last element of the list to the first element of the second list
102 * The last element of the second list, if it exists, then becomes
103 * the last element of the first list.
104 */
105 list2->firstPtr->prevPtr = list1->lastPtr;
106 if (list1->lastPtr != NULL) {
107 list1->lastPtr->nextPtr = list2->firstPtr;
108 } else {
109 list1->firstPtr = list2->firstPtr;
110 }
111 list1->lastPtr = list2->lastPtr;
112 }
113 if (list1->isCirc && list1->firstPtr != NULL) {
114 /*
115 * If the first list is supposed to be circular and it is (now)
116 * non-empty, we must make sure it's circular by linking the
117 * first element to the last and vice versa
118 */
119 list1->firstPtr->prevPtr = list1->lastPtr;
120 list1->lastPtr->nextPtr = list1->firstPtr;
121 }
122 free (l2);
123 } else if (list2->firstPtr != NULL) {
124 /*
125 * We set the nextPtr of the last element of list 2 to be NULL to make
126 * the loop less difficult. The loop simply goes through the entire
127 * second list creating new LstNodes and filling in the nextPtr, and
128 * prevPtr to fit into l1 and its datum field from the
129 * datum field of the corresponding element in l2. The 'last' node
130 * follows the last of the new nodes along until the entire l2 has
131 * been appended. Only then does the bookkeeping catch up with the
132 * changes. During the first iteration of the loop, if 'last' is NULL,
133 * the first list must have been empty so the newly-created node is
134 * made the first node of the list.
135 */
136 list2->lastPtr->nextPtr = NULL;
137 for (last = list1->lastPtr, ln = list2->firstPtr;
138 ln != NULL;
139 ln = ln->nextPtr)
140 {
141 PAlloc (nln, ListNode);
142 nln->datum = ln->datum;
143 if (last != NULL) {
144 last->nextPtr = nln;
145 } else {
146 list1->firstPtr = nln;
147 }
148 nln->prevPtr = last;
149 nln->flags = nln->useCount = 0;
150 last = nln;
151 }
152
153 /*
154 * Finish bookkeeping. The last new element becomes the last element
155 * of list one.
156 */
157 list1->lastPtr = last;
158
159 /*
160 * The circularity of both list one and list two must be corrected
161 * for -- list one because of the new nodes added to it; list two
162 * because of the alteration of list2->lastPtr's nextPtr to ease the
163 * above for loop.
164 */
165 if (list1->isCirc) {
166 list1->lastPtr->nextPtr = list1->firstPtr;
167 list1->firstPtr->prevPtr = list1->lastPtr;
168 } else {
169 last->nextPtr = NULL;
170 }
171
172 if (list2->isCirc) {
173 list2->lastPtr->nextPtr = list2->firstPtr;
174 }
175 }
176
177 return (SUCCESS);
178}
179
Note: See TracBrowser for help on using the repository browser.