modified: SpatialOmicsCoord.py
[GalaxyCodeBases.git] / c_cpp / etc / calc / lib_util.c
blobf5beabb14d5c3895abe16b1959f42ca8d5996f61
1 /*
2 * lib_util - calc library utility routines
4 * Copyright (C) 1999-2006 Landon Curt Noll
6 * Calc is open software; you can redistribute it and/or modify it under
7 * the terms of the version 2.1 of the GNU Lesser General Public License
8 * as published by the Free Software Foundation.
10 * Calc is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
13 * Public License for more details.
15 * A copy of version 2.1 of the GNU Lesser General Public License is
16 * distributed with calc under the filename COPYING-LGPL. You should have
17 * received a copy with calc; if not, write to Free Software Foundation, Inc.
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 * @(#) $Revision: 30.1 $
21 * @(#) $Id: lib_util.c,v 30.1 2007/03/16 11:09:46 chongo Exp $
22 * @(#) $Source: /usr/local/src/bin/calc/RCS/lib_util.c,v $
24 * Under source code control: 1997/04/19 21:38:30
25 * File existed as early as: 1997
27 * chongo <was here> /\oo/\ http://www.isthe.com/chongo/
28 * Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
32 * These routines are here to support users of libcalc.a. These routines
33 * are not directly used by calc itself, however.
37 #include "zmath.h"
38 #include "lib_util.h"
42 * lowhex2bin - quick low order ASCII hex to binary conversion
44 * We just use mod 16 for non-hex ASCII chars. We use just mod 128
45 * for non-ASCII to ASCII conversion.
47 * | 00 nul | 01 soh | 02 stx | 03 etx | 04 eot | 05 enq | 06 ack | 07 bel |
48 * | 08 bs | 09 ht | 0a nl | 0b vt | 0c np | 0d cr | 0e so | 0f si |
49 * | 10 dle | 11 dc1 | 12 dc2 | 13 dc3 | 14 dc4 | 15 nak | 16 syn | 17 etb |
50 * | 18 can | 19 em | 1a sub | 1b esc | 1c fs | 1d gs | 1e rs | 1f us |
51 * | 20 sp | 21 ! | 22 " | 23 # | 24 $ | 25 % | 26 & | 27 ' |
52 * | 28 ( | 29 ) | 2a * | 2b + | 2c , | 2d - | 2e . | 2f / |
53 * | 30 0 | 31 1 | 32 2 | 33 3 | 34 4 | 35 5 | 36 6 | 37 7 |
54 * | 38 8 | 39 9 | 3a : | 3b ; | 3c < | 3d = | 3e > | 3f ? |
55 * | 40 @ | 41 A | 42 B | 43 C | 44 D | 45 E | 46 F | 47 G |
56 * | 48 H | 49 I | 4a J | 4b K | 4c L | 4d M | 4e N | 4f O |
57 * | 50 P | 51 Q | 52 R | 53 S | 54 T | 55 U | 56 V | 57 W |
58 * | 58 X | 59 Y | 5a Z | 5b [ | 5c \ | 5d ] | 5e ^ | 5f _ |
59 * | 60 ` | 61 a | 62 b | 63 c | 64 d | 65 e | 66 f | 67 g |
60 * | 68 h | 69 i | 6a j | 6b k | 6c l | 6d m | 6e n | 6f o |
61 * | 70 p | 71 q | 72 r | 73 s | 74 t | 75 u | 76 v | 77 w |
62 * | 78 x | 79 y | 7a z | 7b { | 7c | | 7d } | 7e ~ | 7f del |
64 int lowhex2bin[256] = {
65 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
66 0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf, /* 0 */
67 0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf, /* 1 */
68 0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf, /* 2 */
69 0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf, /* 3 */
70 0x0,0xa,0xb,0xc,0xd,0xe,0xf,0x7,0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf, /* 4 */
71 0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf, /* 5 */
72 0x0,0xa,0xb,0xc,0xd,0xe,0xf,0x7,0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf, /* 6 */
73 0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf, /* 7 */
74 0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf, /* 8 */
75 0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf, /* 9 */
76 0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf, /* a */
77 0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf, /* b */
78 0x0,0xa,0xb,0xc,0xd,0xe,0xf,0x7,0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf, /* c */
79 0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf, /* d */
80 0x0,0xa,0xb,0xc,0xd,0xe,0xf,0x7,0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf, /* e */
81 0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf /* f */
86 * hex2bin - macro to convert two ASCII hex chars into binary value
88 * given:
89 * high - high order hex ASCII char
90 * low - low order hex ASCII char
92 * returns:
93 * numeric equivalent to 0x{high}{low} as an int
95 #define hex2bin(high,low) \
96 (lowhex2bin[(int)((char)(high))]<<4 | lowhex2bin[((int)(char)(low))])
99 * lowbin2hex - quick low order binary conversion to ASCII hex
101 char lowbin2hex[256] = {
102 '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f',
103 '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f',
104 '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f',
105 '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f',
106 '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f',
107 '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f',
108 '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f',
109 '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f',
110 '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f',
111 '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f',
112 '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f',
113 '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f',
114 '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f',
115 '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f',
116 '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f',
117 '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'
122 * convstr2z - convert a string into a ZVALUE
124 * NOTE: No attempt is make to deal with byte order.
126 * given:
127 * str string to convert
129 * returns:
130 * ZVALUE
132 ZVALUE
133 convstr2z(char *str)
135 HALF *v; /* storage for string as HALFs */
136 ZVALUE ret; /* return value */
137 size_t len; /* length in HALFs of our string rounded up */
140 * firewall
142 if (str == NULL || *str == '\0') {
143 /* NULL or empty strings return 0 */
144 return _zero_;
148 * allocate HALF strorage
150 len = (strlen(str)+sizeof(HALF)-1)/sizeof(HALF);
151 v = (HALF *)malloc(len * sizeof(HALF));
152 if (v == NULL) {
153 math_error("convstr2z bad malloc");
154 /*NOTREACHED*/
156 v[len-1] = 0; /* deal with possible partial end of string HALF */
159 * initialize HALF array with string value
161 memcpy((void *)v, (void *)str, strlen(str));
164 * setup the rest of the ZVALUE
166 ret.v = v;
167 ret.len = len;
168 ret.sign = 0;
169 ztrim(&ret);
172 * return our result
174 return ret;
179 * convhex2z - convert hex string to ZVALUE
181 * usage:
182 * str hex ASCII string with optional leading 0x
184 * returns:
185 * ZVALUE
187 ZVALUE
188 convhex2z(char *hex)
190 HALF *v; /* storage for string as HALFs */
191 HALF *hp; /* HALF pointer */
192 char *sp; /* string pointer */
193 ZVALUE ret; /* return value */
194 int len; /* length in HALFs of our string rounded up */
195 size_t slen; /* hex string length */
196 int i;
199 * firewall
201 if (hex == NULL || hex[0] == '\0') {
202 /* NULL or empty strings return 0 */
203 return _zero_;
207 * skip leading 0X or 0x if needed
209 if (hex[0] == '0' && (hex[1] == 'x' || hex[1] == 'X')) {
210 hex += 2;
212 if (hex[0] == '\0') {
213 /* just 0X or 0x returns 0 */
214 return _zero_;
218 * allocate HALF strorage
220 slen = strlen(hex);
221 len = ((slen*4)+BASEB-1)/BASEB;
222 v = (HALF *)malloc(len * sizeof(HALF));
223 if (v == NULL) {
224 math_error("convhex2z bad malloc");
225 /*NOTREACHED*/
227 v[len-1] = 0; /* deal with possible partial end of string HALF */
230 * deal with the upper partial HALF value
232 hp = v+len-1;
233 sp = hex;
234 if ((slen % (BASEB/4)) != 0) {
236 /* deal with a odd length hex string first */
237 if (slen % 2 == 1) {
238 *hp = hex2bin('0', *sp++);
239 --slen;
241 /* even length - top top hex char to process */
242 } else {
243 *hp = 0;
245 /* slen is even now */
247 /* eat two hex chars at a time until the HALF is full */
248 for (; (slen % (BASEB/4)) != 0; slen -= 2, sp += 2) {
249 *hp = ((*hp<<8) | hex2bin(sp[0], sp[1]));
252 /* move on to the next HALF */
253 --hp;
255 /* slen is now a multiple of BASEB/4 */
258 * deal with full HALFs
260 for (; slen > 0; slen -= (BASEB/4), --hp) {
262 /* clear HALF */
263 *hp = 0;
265 /* eat two hex chars at a time until the HALF is full */
266 for (i=0; i < (BASEB/4); i += 2) {
267 *hp = ((*hp<<8) | hex2bin(sp[i], sp[i+1]));
272 * setup the rest of the ZVALUE
274 ret.v = v;
275 ret.len = len;
276 ret.sign = 0;
277 ztrim(&ret);
280 * return our result
282 return ret;
287 * convz2hex - convert ZVALUE to hex string
289 * We will ignore the sign of the value.
291 * usage:
292 * z ZVALUE
294 * returns:
295 * str hex ASCII malloced string (without a leading 0x)
297 char *
298 convz2hex(ZVALUE z)
300 char *ret; /* string to return */
301 int slen; /* string length (not counting \0) */
302 HALF half; /* HALF value to convert */
303 int seen_nz; /* 0 => we have not seen a non-zero hex char (yet) */
304 char *p;
305 int i;
306 int j;
309 * firewall
311 if (z.v == NULL || ziszero(z)) {
312 /* malloc and return "0" */
313 ret = (char *)malloc(sizeof("0"));
314 if (ret == NULL) {
315 math_error("convz2hex bad malloc of 0 value");
316 /*NOTREACHED*/
318 ret[0] = '0';
319 ret[1] = '\0';
320 return ret;
324 * malloc string storage
326 slen = (z.len * BASEB/4);
327 ret = (char *)calloc(slen+1+1, sizeof(char));
328 if (ret == NULL) {
329 math_error("convz2hex bad malloc of string");
330 /*NOTREACHED*/
334 * load in hex ASCII chars for each HALF
336 * We will not write leading '0' hex chars into the string.
338 seen_nz = 0;
339 for (p=ret, i=z.len-1; i >= 0; --i) {
342 * load in ASCII hex by ASCII hex
344 for (half=z.v[i], j=BASEB-4; j >= 0; j-=4) {
345 if (seen_nz) {
346 /* we saw a non-zero, just load the rest */
347 *p++ = lowbin2hex[(half >> j) & 0xff];
348 } else {
349 /* all zeros so far */
350 *p = lowbin2hex[(half >> j) & 0xff];
351 if (*p != '0') {
352 /* we found our first non-zero char */
353 ++p;
354 seen_nz = 1;
359 if (seen_nz) {
360 *p = '\0';
361 } else {
362 /* saw nothing but 0's, so just return 0 */
363 *ret = '0';
364 *(ret+1) = '\0';
368 * return the new string
370 return ret;