ficl: add ficl-4.1.0 scripting engine
[unleashed.git] / usr / src / common / ficl / utility.c
blob3e140a6075a1c51d7a602e583ceefee92f06f44b
1 #include "ficl.h"
3 /*
4 * a l i g n P t r
5 * Aligns the given pointer to FICL_ALIGN address units.
6 * Returns the aligned pointer value.
7 */
8 void *
9 ficlAlignPointer(void *ptr)
11 #if FICL_PLATFORM_ALIGNMENT > 1
12 intptr_t p = (intptr_t)ptr;
14 if (p & (FICL_PLATFORM_ALIGNMENT - 1))
15 ptr = (void *)((p & ~(FICL_PLATFORM_ALIGNMENT - 1)) +
16 FICL_PLATFORM_ALIGNMENT);
17 #endif
18 return (ptr);
22 * s t r r e v
24 char *
25 ficlStringReverse(char *string)
27 int i = strlen(string);
28 char *p1 = string; /* first char of string */
29 char *p2 = string + i - 1; /* last non-NULL char of string */
30 char c;
32 if (i > 1) {
33 while (p1 < p2) {
34 c = *p2;
35 *p2 = *p1;
36 *p1 = c;
37 p1++; p2--;
41 return (string);
45 * d i g i t _ t o _ c h a r
47 static char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
49 char
50 ficlDigitToCharacter(int value)
52 return (digits[value]);
56 * i s P o w e r O f T w o
57 * Tests whether supplied argument is an integer power of 2 (2**n)
58 * where 32 > n > 1, and returns n if so. Otherwise returns zero.
60 int
61 ficlIsPowerOfTwo(ficlUnsigned u)
63 int i = 1;
64 ficlUnsigned t = 2;
66 for (; ((t <= u) && (t != 0)); i++, t <<= 1) {
67 if (u == t)
68 return (i);
71 return (0);
75 * l t o a
77 char *
78 ficlLtoa(ficlInteger value, char *string, int radix)
80 char *cp = string;
81 int sign = ((radix == 10) && (value < 0));
82 int pwr;
84 FICL_ASSERT(NULL, radix > 1);
85 FICL_ASSERT(NULL, radix < 37);
86 FICL_ASSERT(NULL, string);
88 pwr = ficlIsPowerOfTwo((ficlUnsigned)radix);
90 if (sign)
91 value = -value;
93 if (value == 0)
94 *cp++ = '0';
95 else if (pwr != 0) {
96 ficlUnsigned v = (ficlUnsigned) value;
97 ficlUnsigned mask = (ficlUnsigned) ~(-1 << pwr);
98 while (v) {
99 *cp++ = digits[v & mask];
100 v >>= pwr;
102 } else {
103 ficl2UnsignedQR result;
104 ficl2Unsigned v;
105 FICL_UNSIGNED_TO_2UNSIGNED((ficlUnsigned)value, v);
106 while (FICL_2UNSIGNED_NOT_ZERO(v)) {
107 result = ficl2UnsignedDivide(v, (ficlUnsigned)radix);
108 *cp++ = digits[result.remainder];
109 v = result.quotient;
113 if (sign)
114 *cp++ = '-';
116 *cp++ = '\0';
118 return (ficlStringReverse(string));
122 * u l t o a
124 char *
125 ficlUltoa(ficlUnsigned value, char *string, int radix)
127 char *cp = string;
128 ficl2Unsigned ud;
129 ficl2UnsignedQR result;
131 FICL_ASSERT(NULL, radix > 1);
132 FICL_ASSERT(NULL, radix < 37);
133 FICL_ASSERT(NULL, string);
135 if (value == 0)
136 *cp++ = '0';
137 else {
138 FICL_UNSIGNED_TO_2UNSIGNED(value, ud);
139 while (FICL_2UNSIGNED_NOT_ZERO(ud)) {
140 result = ficl2UnsignedDivide(ud, (ficlUnsigned)radix);
141 ud = result.quotient;
142 *cp++ = digits[result.remainder];
146 *cp++ = '\0';
148 return (ficlStringReverse(string));
152 * c a s e F o l d
153 * Case folds a NULL terminated string in place. All characters
154 * get converted to lower case.
156 char *
157 ficlStringCaseFold(char *cp)
159 char *oldCp = cp;
161 while (*cp) {
162 if (isupper((unsigned char)*cp))
163 *cp = (char)tolower((unsigned char)*cp);
164 cp++;
167 return (oldCp);
171 * s t r i n c m p
172 * (jws) simplified the code a bit in hopes of appeasing Purify
175 ficlStrincmp(char *cp1, char *cp2, ficlUnsigned count)
177 int i = 0;
179 for (; 0 < count; ++cp1, ++cp2, --count) {
180 i = tolower((unsigned char)*cp1) - tolower((unsigned char)*cp2);
181 if (i != 0)
182 return (i);
183 else if (*cp1 == '\0')
184 return (0);
186 return (0);
190 * s k i p S p a c e
191 * Given a string pointer, returns a pointer to the first non-space
192 * char of the string, or to the NULL terminator if no such char found.
193 * If the pointer reaches "end" first, stop there. Pass NULL to
194 * suppress this behavior.
196 char *
197 ficlStringSkipSpace(char *cp, char *end)
199 FICL_ASSERT(NULL, cp);
201 while ((cp != end) && isspace((unsigned char)*cp))
202 cp++;
204 return (cp);
207 void
208 ficlCompatibilityTextOutCallback(ficlCallback *callback, char *text,
209 ficlCompatibilityOutputFunction outputFunction)
211 char buffer[256];
212 char *bufferStop = buffer + sizeof (buffer) - 1;
214 if (text == NULL) {
215 outputFunction(callback->vm, NULL, 0 /* false */);
216 return;
219 while (*text) {
220 int newline = 0 /* false */;
221 char *trace = buffer;
222 while ((*text) && (trace < bufferStop)) {
223 switch (*text) {
224 /* throw away \r */
225 case '\r':
226 text++;
227 continue;
228 case '\n':
229 text++;
230 newline = !0 /* true */;
231 break;
232 default:
233 *trace++ = *text++;
234 break;
238 *trace = 0;
239 (outputFunction)(callback->vm, buffer, newline);