PKUOS - Pintos
Pintos source browser for PKU Operating System course
stdlib.c
Go to the documentation of this file.
1#include <ctype.h>
2#include <debug.h>
3#include <random.h>
4#include <stdlib.h>
5#include <stdbool.h>
6
7/** Converts a string representation of a signed decimal integer
8 in S into an `int', which is returned. */
9int
10atoi (const char *s)
11{
12 bool negative;
13 int value;
14
15 ASSERT (s != NULL);
16
17 /* Skip white space. */
18 while (isspace ((unsigned char) *s))
19 s++;
20
21 /* Parse sign. */
22 negative = false;
23 if (*s == '+')
24 s++;
25 else if (*s == '-')
26 {
27 negative = true;
28 s++;
29 }
30
31 /* Parse digits. We always initially parse the value as
32 negative, and then make it positive later, because the
33 negative range of an int is bigger than the positive range
34 on a 2's complement system. */
35 for (value = 0; isdigit (*s); s++)
36 value = value * 10 - (*s - '0');
37 if (!negative)
38 value = -value;
39
40 return value;
41}
42
43/** Compares A and B by calling the AUX function. */
44static int
45compare_thunk (const void *a, const void *b, void *aux)
46{
47 int (**compare) (const void *, const void *) = aux;
48 return (*compare) (a, b);
49}
50
51/** Sorts ARRAY, which contains CNT elements of SIZE bytes each,
52 using COMPARE. When COMPARE is passed a pair of elements A
53 and B, respectively, it must return a strcmp()-type result,
54 i.e. less than zero if A < B, zero if A == B, greater than
55 zero if A > B. Runs in O(n lg n) time and O(1) space in
56 CNT. */
57void
58qsort (void *array, size_t cnt, size_t size,
59 int (*compare) (const void *, const void *))
60{
61 sort (array, cnt, size, compare_thunk, &compare);
62}
63
64/** Swaps elements with 1-based indexes A_IDX and B_IDX in ARRAY
65 with elements of SIZE bytes each. */
66static void
67do_swap (unsigned char *array, size_t a_idx, size_t b_idx, size_t size)
68{
69 unsigned char *a = array + (a_idx - 1) * size;
70 unsigned char *b = array + (b_idx - 1) * size;
71 size_t i;
72
73 for (i = 0; i < size; i++)
74 {
75 unsigned char t = a[i];
76 a[i] = b[i];
77 b[i] = t;
78 }
79}
80
81/** Compares elements with 1-based indexes A_IDX and B_IDX in
82 ARRAY with elements of SIZE bytes each, using COMPARE to
83 compare elements, passing AUX as auxiliary data, and returns a
84 strcmp()-type result. */
85static int
86do_compare (unsigned char *array, size_t a_idx, size_t b_idx, size_t size,
87 int (*compare) (const void *, const void *, void *aux),
88 void *aux)
89{
90 return compare (array + (a_idx - 1) * size, array + (b_idx - 1) * size, aux);
91}
92
93/** "Float down" the element with 1-based index I in ARRAY of CNT
94 elements of SIZE bytes each, using COMPARE to compare
95 elements, passing AUX as auxiliary data. */
96static void
97heapify (unsigned char *array, size_t i, size_t cnt, size_t size,
98 int (*compare) (const void *, const void *, void *aux),
99 void *aux)
100{
101 for (;;)
102 {
103 /* Set `max' to the index of the largest element among I
104 and its children (if any). */
105 size_t left = 2 * i;
106 size_t right = 2 * i + 1;
107 size_t max = i;
108 if (left <= cnt && do_compare (array, left, max, size, compare, aux) > 0)
109 max = left;
110 if (right <= cnt
111 && do_compare (array, right, max, size, compare, aux) > 0)
112 max = right;
113
114 /* If the maximum value is already in element I, we're
115 done. */
116 if (max == i)
117 break;
118
119 /* Swap and continue down the heap. */
120 do_swap (array, i, max, size);
121 i = max;
122 }
123}
124
125/** Sorts ARRAY, which contains CNT elements of SIZE bytes each,
126 using COMPARE to compare elements, passing AUX as auxiliary
127 data. When COMPARE is passed a pair of elements A and B,
128 respectively, it must return a strcmp()-type result, i.e. less
129 than zero if A < B, zero if A == B, greater than zero if A >
130 B. Runs in O(n lg n) time and O(1) space in CNT. */
131void
132sort (void *array, size_t cnt, size_t size,
133 int (*compare) (const void *, const void *, void *aux),
134 void *aux)
135{
136 size_t i;
137
138 ASSERT (array != NULL || cnt == 0);
139 ASSERT (compare != NULL);
140 ASSERT (size > 0);
141
142 /* Build a heap. */
143 for (i = cnt / 2; i > 0; i--)
144 heapify (array, i, cnt, size, compare, aux);
145
146 /* Sort the heap. */
147 for (i = cnt; i > 1; i--)
148 {
149 do_swap (array, 1, i, size);
150 heapify (array, 1, i - 1, size, compare, aux);
151 }
152}
153
154/** Searches ARRAY, which contains CNT elements of SIZE bytes
155 each, for the given KEY. Returns a match is found, otherwise
156 a null pointer. If there are multiple matches, returns an
157 arbitrary one of them.
158
159 ARRAY must be sorted in order according to COMPARE.
160
161 Uses COMPARE to compare elements. When COMPARE is passed a
162 pair of elements A and B, respectively, it must return a
163 strcmp()-type result, i.e. less than zero if A < B, zero if A
164 == B, greater than zero if A > B. */
165void *
166bsearch (const void *key, const void *array, size_t cnt,
167 size_t size, int (*compare) (const void *, const void *))
168{
169 return binary_search (key, array, cnt, size, compare_thunk, &compare);
170}
171
172/** Searches ARRAY, which contains CNT elements of SIZE bytes
173 each, for the given KEY. Returns a match is found, otherwise
174 a null pointer. If there are multiple matches, returns an
175 arbitrary one of them.
176
177 ARRAY must be sorted in order according to COMPARE.
178
179 Uses COMPARE to compare elements, passing AUX as auxiliary
180 data. When COMPARE is passed a pair of elements A and B,
181 respectively, it must return a strcmp()-type result, i.e. less
182 than zero if A < B, zero if A == B, greater than zero if A >
183 B. */
184void *
185binary_search (const void *key, const void *array, size_t cnt, size_t size,
186 int (*compare) (const void *, const void *, void *aux),
187 void *aux)
188{
189 const unsigned char *first = array;
190 const unsigned char *last = array + size * cnt;
191
192 while (first < last)
193 {
194 size_t range = (last - first) / size;
195 const unsigned char *middle = first + (range / 2) * size;
196 int cmp = compare (key, middle, aux);
197
198 if (cmp < 0)
199 last = middle;
200 else if (cmp > 0)
201 first = middle + size;
202 else
203 return (void *) middle;
204 }
205
206 return NULL;
207}
208
static int isspace(int c)
Definition: ctype.h:12
static int isdigit(int c)
Definition: ctype.h:7
#define ASSERT(CONDITION)
This is outside the header guard so that debug.h may be included multiple times with different settin...
Definition: debug.h:31
static void heapify(unsigned char *array, size_t i, size_t cnt, size_t size, int(*compare)(const void *, const void *, void *aux), void *aux)
"Float down" the element with 1-based index I in ARRAY of CNT elements of SIZE bytes each,...
Definition: stdlib.c:97
void * bsearch(const void *key, const void *array, size_t cnt, size_t size, int(*compare)(const void *, const void *))
Searches ARRAY, which contains CNT elements of SIZE bytes each, for the given KEY.
Definition: stdlib.c:166
int atoi(const char *s)
Converts a string representation of a signed decimal integer in S into an ‘int’, which is returned.
Definition: stdlib.c:10
static void do_swap(unsigned char *array, size_t a_idx, size_t b_idx, size_t size)
Swaps elements with 1-based indexes A_IDX and B_IDX in ARRAY with elements of SIZE bytes each.
Definition: stdlib.c:67
void qsort(void *array, size_t cnt, size_t size, int(*compare)(const void *, const void *))
Sorts ARRAY, which contains CNT elements of SIZE bytes each, using COMPARE.
Definition: stdlib.c:58
void * binary_search(const void *key, const void *array, size_t cnt, size_t size, int(*compare)(const void *, const void *, void *aux), void *aux)
Searches ARRAY, which contains CNT elements of SIZE bytes each, for the given KEY.
Definition: stdlib.c:185
static int compare_thunk(const void *a, const void *b, void *aux)
Compares A and B by calling the AUX function.
Definition: stdlib.c:45
void sort(void *array, size_t cnt, size_t size, int(*compare)(const void *, const void *, void *aux), void *aux)
Sorts ARRAY, which contains CNT elements of SIZE bytes each, using COMPARE to compare elements,...
Definition: stdlib.c:132
static int do_compare(unsigned char *array, size_t a_idx, size_t b_idx, size_t size, int(*compare)(const void *, const void *, void *aux), void *aux)
Compares elements with 1-based indexes A_IDX and B_IDX in ARRAY with elements of SIZE bytes each,...
Definition: stdlib.c:86
static uint8_t s[256]
RC4-based pseudo-random number generator (PRNG).
Definition: random.c:17
#define NULL
Definition: stddef.h:4
A linked list element.
Definition: list.c:23