1 /* -*- mode: c ; c-file-style: "canonware-c-style" -*-
2 ******************************************************************************
3 *
4 * Copyright (C) 1996-2005 Jason Evans <jasone@canonware.com>.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice(s), this list of conditions and the following disclaimer
12 * unmodified other than the allowable addition of one or more
13 * copyright notices.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice(s), this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
17 * distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
26 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
28 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
29 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 ******************************************************************************
32 *
33 * Version: Onyx 5.1.2
34 *
35 ******************************************************************************/
36
37 #define CW_NXO_C_
38
39 #include "../include/libonyx/libonyx.h"
40 #include "../include/libonyx/nx_l.h"
41 #include "../include/libonyx/nxa_l.h"
42 #include "../include/libonyx/nxo_l.h"
43
44 /* nxo. */
45 int32_t
nxo_compare(const cw_nxo_t * a_a,const cw_nxo_t * a_b)46 nxo_compare(const cw_nxo_t *a_a, const cw_nxo_t *a_b)
47 {
48 int32_t retval;
49
50 switch (nxo_type_get(a_a))
51 {
52 case NXOT_ARRAY:
53 #ifdef CW_OOP
54 case NXOT_CLASS:
55 #endif
56 #ifdef CW_THREADS
57 case NXOT_CONDITION:
58 #endif
59 case NXOT_DICT:
60 case NXOT_FILE:
61 #ifdef CW_HANDLE
62 case NXOT_HANDLE:
63 #endif
64 #ifdef CW_OOP
65 case NXOT_INSTANCE:
66 #endif
67 #ifdef CW_THREADS
68 case NXOT_MUTEX:
69 #endif
70 #ifdef CW_REGEX
71 case NXOT_REGEX:
72 case NXOT_REGSUB:
73 #endif
74 case NXOT_STACK:
75 case NXOT_THREAD:
76 {
77 if (nxo_type_get(a_a) == nxo_type_get(a_b)
78 && a_a->o.nxoe == a_b->o.nxoe)
79 {
80 retval = 0;
81 }
82 else
83 {
84 retval = 1;
85 }
86 break;
87 }
88 case NXOT_OPERATOR:
89 {
90 if (nxo_type_get(a_b) == NXOT_OPERATOR
91 && a_a->o.oper.f == a_b->o.oper.f)
92 {
93 retval = 0;
94 }
95 else
96 {
97 retval = 1;
98 }
99 break;
100 }
101 case NXOT_NAME:
102 case NXOT_STRING:
103 {
104 const char *str_a, *str_b;
105 uint32_t len_a, len_b;
106 #ifdef CW_THREADS
107 bool lock_a, lock_b;
108 #endif
109
110 if (nxo_type_get(a_a) == NXOT_NAME)
111 {
112 str_a = nxo_name_str_get(a_a);
113 len_a = nxo_name_len_get(a_a);
114 #ifdef CW_THREADS
115 lock_a = false;
116 #endif
117 }
118 else
119 {
120 str_a = nxo_string_get(a_a);
121 len_a = nxo_string_len_get(a_a);
122 #ifdef CW_THREADS
123 lock_a = true;
124 #endif
125 }
126
127 if (nxo_type_get(a_b) == NXOT_NAME)
128 {
129 str_b = nxo_name_str_get(a_b);
130 len_b = nxo_name_len_get(a_b);
131 #ifdef CW_THREADS
132 lock_b = false;
133 #endif
134 }
135 else if (nxo_type_get(a_b) == NXOT_STRING)
136 {
137 str_b = nxo_string_get(a_b);
138 len_b = nxo_string_len_get(a_b);
139 #ifdef CW_THREADS
140 lock_b = true;
141 #endif
142 }
143 else
144 {
145 retval = 2;
146 break;
147 }
148
149 #ifdef CW_THREADS
150 if (lock_a)
151 {
152 nxo_string_lock((cw_nxo_t *) a_a);
153 }
154 if (lock_b)
155 {
156 nxo_string_lock((cw_nxo_t *) a_b);
157 }
158 #endif
159 if (len_a == len_b)
160 {
161 retval = strncmp(str_a, str_b, len_a);
162 }
163 else if (len_a < len_b)
164 {
165 retval = strncmp(str_a, str_b, len_a);
166 if (retval == 0)
167 {
168 retval = -1;
169 }
170 }
171 else
172 {
173 retval = strncmp(str_a, str_b, len_b);
174 if (retval == 0)
175 {
176 retval = 1;
177 }
178 }
179 #ifdef CW_THREADS
180 if (lock_b)
181 {
182 nxo_string_unlock((cw_nxo_t *) a_b);
183 }
184 if (lock_a)
185 {
186 nxo_string_unlock((cw_nxo_t *) a_a);
187 }
188 #endif
189 break;
190 }
191 case NXOT_BOOLEAN:
192 {
193 if (nxo_type_get(a_b) != NXOT_BOOLEAN)
194 {
195 retval = 2;
196 break;
197 }
198
199 if (a_a->o.boolean.val == a_b->o.boolean.val)
200 {
201 retval = 0;
202 }
203 else
204 {
205 retval = 1;
206 }
207 break;
208 }
209 case NXOT_INTEGER:
210 {
211 switch (nxo_type_get(a_b))
212 {
213 case NXOT_INTEGER:
214 {
215 if (a_a->o.integer.i < a_b->o.integer.i)
216 {
217 retval = -1;
218 }
219 else if (a_a->o.integer.i == a_b->o.integer.i)
220 {
221 retval = 0;
222 }
223 else
224 {
225 retval = 1;
226 }
227 break;
228 }
229 #ifdef CW_REAL
230 case NXOT_REAL:
231 {
232 if (((cw_nxor_t) a_a->o.integer.i) < a_b->o.real.r)
233 {
234 retval = -1;
235 }
236 else if (((cw_nxor_t) a_a->o.integer.i) == a_b->o.real.r)
237 {
238 retval = 0;
239 }
240 else
241 {
242 retval = 1;
243 }
244 break;
245 }
246 #endif
247 default:
248 {
249 retval = 2;
250 break;
251 }
252 }
253 break;
254 }
255 #ifdef CW_REAL
256 case NXOT_REAL:
257 {
258 switch (nxo_type_get(a_b))
259 {
260 case NXOT_INTEGER:
261 {
262 if (a_a->o.real.r < ((cw_nxor_t) a_b->o.integer.i))
263 {
264 retval = -1;
265 }
266 else if (a_a->o.real.r == ((cw_nxor_t) a_b->o.integer.i))
267 {
268 retval = 0;
269 }
270 else
271 {
272 retval = 1;
273 }
274 break;
275 }
276 case NXOT_REAL:
277 {
278 if (a_a->o.real.r < a_b->o.real.r)
279 {
280 retval = -1;
281 }
282 else if (a_a->o.real.r == a_b->o.real.r)
283 {
284 retval = 0;
285 }
286 else
287 {
288 retval = 1;
289 }
290 break;
291 }
292 default:
293 {
294 retval = 2;
295 break;
296 }
297 }
298 break;
299 }
300 #endif
301 case NXOT_FINO:
302 case NXOT_MARK:
303 case NXOT_NULL:
304 case NXOT_PMARK:
305 {
306 if (nxo_type_get(a_a) == nxo_type_get(a_b))
307 {
308 retval = 0;
309 }
310 else
311 {
312 retval = 2;
313 }
314 break;
315 }
316 default:
317 {
318 cw_not_reached();
319 }
320 }
321
322 return retval;
323 }
324
325 cw_nxoe_t *
nxo_nxoe_get(const cw_nxo_t * a_nxo)326 nxo_nxoe_get(const cw_nxo_t *a_nxo)
327 {
328 cw_nxoe_t *retval;
329
330 cw_check_ptr(a_nxo);
331 cw_assert(a_nxo->magic == CW_NXO_MAGIC || nxo_type_get(a_nxo) == NXOT_NO);
332
333 switch (nxo_type_get(a_nxo))
334 {
335 case NXOT_ARRAY:
336 #ifdef CW_OOP
337 case NXOT_CLASS:
338 #endif
339 #ifdef CW_THREADS
340 case NXOT_CONDITION:
341 #endif
342 case NXOT_DICT:
343 case NXOT_FILE:
344 #ifdef CW_HANDLE
345 case NXOT_HANDLE:
346 #endif
347 #ifdef CW_OOP
348 case NXOT_INSTANCE:
349 #endif
350 #ifdef CW_THREADS
351 case NXOT_MUTEX:
352 #endif
353 case NXOT_NAME:
354 #ifdef CW_REGEX
355 case NXOT_REGEX:
356 case NXOT_REGSUB:
357 #endif
358 case NXOT_STACK:
359 case NXOT_STRING:
360 case NXOT_THREAD:
361 {
362 retval = a_nxo->o.nxoe;
363 break;
364 }
365 default:
366 {
367 retval = NULL;
368 }
369 }
370
371 return retval;
372 }
373
374 #ifdef CW_THREADS
375 bool
nxo_ilocked(cw_nxo_t * a_nxo)376 nxo_ilocked(cw_nxo_t *a_nxo)
377 {
378 bool retval;
379
380 cw_check_ptr(a_nxo);
381 cw_dassert(a_nxo->magic == CW_NXO_MAGIC);
382
383 #ifdef CW_DBG
384 switch (nxo_type_get(a_nxo))
385 {
386 case NXOT_ARRAY:
387 case NXOT_DICT:
388 case NXOT_FILE:
389 case NXOT_STACK:
390 case NXOT_STRING:
391 {
392 retval = a_nxo->o.nxoe->locking;
393 break;
394 }
395 default:
396 {
397 cw_not_reached();
398 }
399 }
400 #else
401 retval = a_nxo->o.nxoe->locking;
402 #endif
403
404 return retval;
405 }
406 #endif
407
408 /* nxoe. */
409 /* Can be called at any time during nxoe_* initialization. */
410 void
nxoe_l_new(cw_nxoe_t * a_nxoe,cw_nxot_t a_type,bool a_locking)411 nxoe_l_new(cw_nxoe_t *a_nxoe, cw_nxot_t a_type, bool a_locking)
412 {
413 /* Initialize the common section. */
414 memset(a_nxoe, 0, sizeof(cw_nxoe_t));
415
416 qr_new(a_nxoe, link);
417 a_nxoe->type = a_type;
418 #ifdef CW_THREADS
419 a_nxoe->locking = a_locking;
420 #endif
421 #ifdef CW_DBG
422 a_nxoe->magic = CW_NXOE_MAGIC;
423 #endif
424 }
425