source: branches/libc-0.6/src/binutils/libiberty/partition.c

Last change on this file was 610, checked in by bird, 22 years ago

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

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 4.9 KB
Line 
1/* List implementation of a partition of consecutive integers.
2 Copyright (C) 2000, 2001 Free Software Foundation, Inc.
3 Contributed by CodeSourcery, LLC.
4
5 This file is part of GNU CC.
6
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21
22#ifdef HAVE_CONFIG_H
23#include "config.h"
24#endif
25
26#ifdef HAVE_STDLIB_H
27#include <stdlib.h>
28#endif
29
30#ifdef HAVE_STRING_H
31#include <string.h>
32#endif
33
34#include "libiberty.h"
35#include "partition.h"
36
37static int elem_compare PARAMS ((const void *, const void *));
38
39/* Creates a partition of NUM_ELEMENTS elements. Initially each
40 element is in a class by itself. */
41
42partition
43partition_new (num_elements)
44 int num_elements;
45{
46 int e;
47
48 partition part = (partition)
49 xmalloc (sizeof (struct partition_def) +
50 (num_elements - 1) * sizeof (struct partition_elem));
51 part->num_elements = num_elements;
52 for (e = 0; e < num_elements; ++e)
53 {
54 part->elements[e].class_element = e;
55 part->elements[e].next = &(part->elements[e]);
56 part->elements[e].class_count = 1;
57 }
58
59 return part;
60}
61
62/* Freeds a partition. */
63
64void
65partition_delete (part)
66 partition part;
67{
68 free (part);
69}
70
71/* Unites the classes containing ELEM1 and ELEM2 into a single class
72 of partition PART. If ELEM1 and ELEM2 are already in the same
73 class, does nothing. Returns the canonical element of the
74 resulting union class. */
75
76int
77partition_union (part, elem1, elem2)
78 partition part;
79 int elem1;
80 int elem2;
81{
82 struct partition_elem *elements = part->elements;
83 struct partition_elem *e1;
84 struct partition_elem *e2;
85 struct partition_elem *p;
86 struct partition_elem *old_next;
87 /* The canonical element of the resulting union class. */
88 int class_element = elements[elem1].class_element;
89
90 /* If they're already in the same class, do nothing. */
91 if (class_element == elements[elem2].class_element)
92 return class_element;
93
94 /* Make sure ELEM1 is in the larger class of the two. If not, swap
95 them. This way we always scan the shorter list. */
96 if (elements[elem1].class_count < elements[elem2].class_count)
97 {
98 int temp = elem1;
99 elem1 = elem2;
100 elem2 = temp;
101 class_element = elements[elem1].class_element;
102 }
103
104 e1 = &(elements[elem1]);
105 e2 = &(elements[elem2]);
106
107 /* Keep a count of the number of elements in the list. */
108 elements[class_element].class_count
109 += elements[e2->class_element].class_count;
110
111 /* Update the class fields in elem2's class list. */
112 e2->class_element = class_element;
113 for (p = e2->next; p != e2; p = p->next)
114 p->class_element = class_element;
115
116 /* Splice ELEM2's class list into ELEM1's. These are circular
117 lists. */
118 old_next = e1->next;
119 e1->next = e2->next;
120 e2->next = old_next;
121
122 return class_element;
123}
124
125/* Compare elements ELEM1 and ELEM2 from array of integers, given a
126 pointer to each. Used to qsort such an array. */
127
128static int
129elem_compare (elem1, elem2)
130 const void *elem1;
131 const void *elem2;
132{
133 int e1 = * (const int *) elem1;
134 int e2 = * (const int *) elem2;
135 if (e1 < e2)
136 return -1;
137 else if (e1 > e2)
138 return 1;
139 else
140 return 0;
141}
142
143/* Prints PART to the file pointer FP. The elements of each
144 class are sorted. */
145
146void
147partition_print (part, fp)
148 partition part;
149 FILE *fp;
150{
151 char *done;
152 int num_elements = part->num_elements;
153 struct partition_elem *elements = part->elements;
154 int *class_elements;
155 int e;
156
157 /* Flag the elements we've already printed. */
158 done = (char *) xmalloc (num_elements);
159 memset (done, 0, num_elements);
160
161 /* A buffer used to sort elements in a class. */
162 class_elements = (int *) xmalloc (num_elements * sizeof (int));
163
164 fputc ('[', fp);
165 for (e = 0; e < num_elements; ++e)
166 /* If we haven't printed this element, print its entire class. */
167 if (! done[e])
168 {
169 int c = e;
170 int count = elements[elements[e].class_element].class_count;
171 int i;
172
173 /* Collect the elements in this class. */
174 for (i = 0; i < count; ++i) {
175 class_elements[i] = c;
176 done[c] = 1;
177 c = elements[c].next - elements;
178 }
179 /* Sort them. */
180 qsort ((void *) class_elements, count, sizeof (int), elem_compare);
181 /* Print them. */
182 fputc ('(', fp);
183 for (i = 0; i < count; ++i)
184 fprintf (fp, i == 0 ? "%d" : " %d", class_elements[i]);
185 fputc (')', fp);
186 }
187 fputc (']', fp);
188
189 free (done);
190}
191
Note: See TracBrowser for help on using the repository browser.