xref: /titanic_52/usr/src/common/ficl/utility.c (revision a1bf3f785ae05c419b339c3a2061f2b18c024f61)
1*a1bf3f78SToomas Soome #include "ficl.h"
2*a1bf3f78SToomas Soome 
3*a1bf3f78SToomas Soome /*
4*a1bf3f78SToomas Soome  * a l i g n P t r
5*a1bf3f78SToomas Soome  * Aligns the given pointer to FICL_ALIGN address units.
6*a1bf3f78SToomas Soome  * Returns the aligned pointer value.
7*a1bf3f78SToomas Soome  */
8*a1bf3f78SToomas Soome void *
9*a1bf3f78SToomas Soome ficlAlignPointer(void *ptr)
10*a1bf3f78SToomas Soome {
11*a1bf3f78SToomas Soome #if FICL_PLATFORM_ALIGNMENT > 1
12*a1bf3f78SToomas Soome 	intptr_t p = (intptr_t)ptr;
13*a1bf3f78SToomas Soome 
14*a1bf3f78SToomas Soome 	if (p & (FICL_PLATFORM_ALIGNMENT - 1))
15*a1bf3f78SToomas Soome 		ptr = (void *)((p & ~(FICL_PLATFORM_ALIGNMENT - 1)) +
16*a1bf3f78SToomas Soome 		    FICL_PLATFORM_ALIGNMENT);
17*a1bf3f78SToomas Soome #endif
18*a1bf3f78SToomas Soome 	return (ptr);
19*a1bf3f78SToomas Soome }
20*a1bf3f78SToomas Soome 
21*a1bf3f78SToomas Soome /*
22*a1bf3f78SToomas Soome  * s t r r e v
23*a1bf3f78SToomas Soome  */
24*a1bf3f78SToomas Soome char *
25*a1bf3f78SToomas Soome ficlStringReverse(char *string)
26*a1bf3f78SToomas Soome {
27*a1bf3f78SToomas Soome 	int i = strlen(string);
28*a1bf3f78SToomas Soome 	char *p1 = string;		/* first char of string */
29*a1bf3f78SToomas Soome 	char *p2 = string + i - 1;	/* last non-NULL char of string */
30*a1bf3f78SToomas Soome 	char c;
31*a1bf3f78SToomas Soome 
32*a1bf3f78SToomas Soome 	if (i > 1) {
33*a1bf3f78SToomas Soome 		while (p1 < p2) {
34*a1bf3f78SToomas Soome 			c = *p2;
35*a1bf3f78SToomas Soome 			*p2 = *p1;
36*a1bf3f78SToomas Soome 			*p1 = c;
37*a1bf3f78SToomas Soome 			p1++; p2--;
38*a1bf3f78SToomas Soome 		}
39*a1bf3f78SToomas Soome 	}
40*a1bf3f78SToomas Soome 
41*a1bf3f78SToomas Soome 	return (string);
42*a1bf3f78SToomas Soome }
43*a1bf3f78SToomas Soome 
44*a1bf3f78SToomas Soome /*
45*a1bf3f78SToomas Soome  * d i g i t _ t o _ c h a r
46*a1bf3f78SToomas Soome  */
47*a1bf3f78SToomas Soome static char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
48*a1bf3f78SToomas Soome 
49*a1bf3f78SToomas Soome char
50*a1bf3f78SToomas Soome ficlDigitToCharacter(int value)
51*a1bf3f78SToomas Soome {
52*a1bf3f78SToomas Soome 	return (digits[value]);
53*a1bf3f78SToomas Soome }
54*a1bf3f78SToomas Soome 
55*a1bf3f78SToomas Soome /*
56*a1bf3f78SToomas Soome  * i s P o w e r O f T w o
57*a1bf3f78SToomas Soome  * Tests whether supplied argument is an integer power of 2 (2**n)
58*a1bf3f78SToomas Soome  * where 32 > n > 1, and returns n if so. Otherwise returns zero.
59*a1bf3f78SToomas Soome  */
60*a1bf3f78SToomas Soome int
61*a1bf3f78SToomas Soome ficlIsPowerOfTwo(ficlUnsigned u)
62*a1bf3f78SToomas Soome {
63*a1bf3f78SToomas Soome 	int i = 1;
64*a1bf3f78SToomas Soome 	ficlUnsigned t = 2;
65*a1bf3f78SToomas Soome 
66*a1bf3f78SToomas Soome 	for (; ((t <= u) && (t != 0)); i++, t <<= 1) {
67*a1bf3f78SToomas Soome 		if (u == t)
68*a1bf3f78SToomas Soome 			return (i);
69*a1bf3f78SToomas Soome 	}
70*a1bf3f78SToomas Soome 
71*a1bf3f78SToomas Soome 	return (0);
72*a1bf3f78SToomas Soome }
73*a1bf3f78SToomas Soome 
74*a1bf3f78SToomas Soome /*
75*a1bf3f78SToomas Soome  * l t o a
76*a1bf3f78SToomas Soome  */
77*a1bf3f78SToomas Soome char *
78*a1bf3f78SToomas Soome ficlLtoa(ficlInteger value, char *string, int radix)
79*a1bf3f78SToomas Soome {
80*a1bf3f78SToomas Soome 	char *cp = string;
81*a1bf3f78SToomas Soome 	int sign = ((radix == 10) && (value < 0));
82*a1bf3f78SToomas Soome 	int pwr;
83*a1bf3f78SToomas Soome 
84*a1bf3f78SToomas Soome 	FICL_ASSERT(NULL, radix > 1);
85*a1bf3f78SToomas Soome 	FICL_ASSERT(NULL, radix < 37);
86*a1bf3f78SToomas Soome 	FICL_ASSERT(NULL, string);
87*a1bf3f78SToomas Soome 
88*a1bf3f78SToomas Soome 	pwr = ficlIsPowerOfTwo((ficlUnsigned)radix);
89*a1bf3f78SToomas Soome 
90*a1bf3f78SToomas Soome 	if (sign)
91*a1bf3f78SToomas Soome 		value = -value;
92*a1bf3f78SToomas Soome 
93*a1bf3f78SToomas Soome 	if (value == 0)
94*a1bf3f78SToomas Soome 		*cp++ = '0';
95*a1bf3f78SToomas Soome 	else if (pwr != 0) {
96*a1bf3f78SToomas Soome 		ficlUnsigned v = (ficlUnsigned) value;
97*a1bf3f78SToomas Soome 		ficlUnsigned mask = (ficlUnsigned) ~(-1 << pwr);
98*a1bf3f78SToomas Soome 		while (v) {
99*a1bf3f78SToomas Soome 			*cp++ = digits[v & mask];
100*a1bf3f78SToomas Soome 			v >>= pwr;
101*a1bf3f78SToomas Soome 		}
102*a1bf3f78SToomas Soome 	} else {
103*a1bf3f78SToomas Soome 		ficl2UnsignedQR result;
104*a1bf3f78SToomas Soome 		ficl2Unsigned v;
105*a1bf3f78SToomas Soome 		FICL_UNSIGNED_TO_2UNSIGNED((ficlUnsigned)value, v);
106*a1bf3f78SToomas Soome 		while (FICL_2UNSIGNED_NOT_ZERO(v)) {
107*a1bf3f78SToomas Soome 			result = ficl2UnsignedDivide(v, (ficlUnsigned)radix);
108*a1bf3f78SToomas Soome 			*cp++ = digits[result.remainder];
109*a1bf3f78SToomas Soome 			v = result.quotient;
110*a1bf3f78SToomas Soome 		}
111*a1bf3f78SToomas Soome 	}
112*a1bf3f78SToomas Soome 
113*a1bf3f78SToomas Soome 	if (sign)
114*a1bf3f78SToomas Soome 		*cp++ = '-';
115*a1bf3f78SToomas Soome 
116*a1bf3f78SToomas Soome 	*cp++ = '\0';
117*a1bf3f78SToomas Soome 
118*a1bf3f78SToomas Soome 	return (ficlStringReverse(string));
119*a1bf3f78SToomas Soome }
120*a1bf3f78SToomas Soome 
121*a1bf3f78SToomas Soome /*
122*a1bf3f78SToomas Soome  * u l t o a
123*a1bf3f78SToomas Soome  */
124*a1bf3f78SToomas Soome char *
125*a1bf3f78SToomas Soome ficlUltoa(ficlUnsigned value, char *string, int radix)
126*a1bf3f78SToomas Soome {
127*a1bf3f78SToomas Soome 	char *cp = string;
128*a1bf3f78SToomas Soome 	ficl2Unsigned ud;
129*a1bf3f78SToomas Soome 	ficl2UnsignedQR result;
130*a1bf3f78SToomas Soome 
131*a1bf3f78SToomas Soome 	FICL_ASSERT(NULL, radix > 1);
132*a1bf3f78SToomas Soome 	FICL_ASSERT(NULL, radix < 37);
133*a1bf3f78SToomas Soome 	FICL_ASSERT(NULL, string);
134*a1bf3f78SToomas Soome 
135*a1bf3f78SToomas Soome 	if (value == 0)
136*a1bf3f78SToomas Soome 		*cp++ = '0';
137*a1bf3f78SToomas Soome 	else {
138*a1bf3f78SToomas Soome 		FICL_UNSIGNED_TO_2UNSIGNED(value, ud);
139*a1bf3f78SToomas Soome 		while (FICL_2UNSIGNED_NOT_ZERO(ud)) {
140*a1bf3f78SToomas Soome 			result = ficl2UnsignedDivide(ud, (ficlUnsigned)radix);
141*a1bf3f78SToomas Soome 			ud = result.quotient;
142*a1bf3f78SToomas Soome 			*cp++ = digits[result.remainder];
143*a1bf3f78SToomas Soome 		}
144*a1bf3f78SToomas Soome 	}
145*a1bf3f78SToomas Soome 
146*a1bf3f78SToomas Soome 	*cp++ = '\0';
147*a1bf3f78SToomas Soome 
148*a1bf3f78SToomas Soome 	return (ficlStringReverse(string));
149*a1bf3f78SToomas Soome }
150*a1bf3f78SToomas Soome 
151*a1bf3f78SToomas Soome /*
152*a1bf3f78SToomas Soome  * c a s e F o l d
153*a1bf3f78SToomas Soome  * Case folds a NULL terminated string in place. All characters
154*a1bf3f78SToomas Soome  * get converted to lower case.
155*a1bf3f78SToomas Soome  */
156*a1bf3f78SToomas Soome char *
157*a1bf3f78SToomas Soome ficlStringCaseFold(char *cp)
158*a1bf3f78SToomas Soome {
159*a1bf3f78SToomas Soome 	char *oldCp = cp;
160*a1bf3f78SToomas Soome 
161*a1bf3f78SToomas Soome 	while (*cp) {
162*a1bf3f78SToomas Soome 		if (isupper((unsigned char)*cp))
163*a1bf3f78SToomas Soome 			*cp = (char)tolower((unsigned char)*cp);
164*a1bf3f78SToomas Soome 		cp++;
165*a1bf3f78SToomas Soome 	}
166*a1bf3f78SToomas Soome 
167*a1bf3f78SToomas Soome 	return (oldCp);
168*a1bf3f78SToomas Soome }
169*a1bf3f78SToomas Soome 
170*a1bf3f78SToomas Soome /*
171*a1bf3f78SToomas Soome  * s t r i n c m p
172*a1bf3f78SToomas Soome  * (jws) simplified the code a bit in hopes of appeasing Purify
173*a1bf3f78SToomas Soome  */
174*a1bf3f78SToomas Soome int
175*a1bf3f78SToomas Soome ficlStrincmp(char *cp1, char *cp2, ficlUnsigned count)
176*a1bf3f78SToomas Soome {
177*a1bf3f78SToomas Soome 	int i = 0;
178*a1bf3f78SToomas Soome 
179*a1bf3f78SToomas Soome 	for (; 0 < count; ++cp1, ++cp2, --count) {
180*a1bf3f78SToomas Soome 		i = tolower((unsigned char)*cp1) - tolower((unsigned char)*cp2);
181*a1bf3f78SToomas Soome 		if (i != 0)
182*a1bf3f78SToomas Soome 			return (i);
183*a1bf3f78SToomas Soome 		else if (*cp1 == '\0')
184*a1bf3f78SToomas Soome 			return (0);
185*a1bf3f78SToomas Soome 	}
186*a1bf3f78SToomas Soome 	return (0);
187*a1bf3f78SToomas Soome }
188*a1bf3f78SToomas Soome 
189*a1bf3f78SToomas Soome /*
190*a1bf3f78SToomas Soome  * s k i p S p a c e
191*a1bf3f78SToomas Soome  * Given a string pointer, returns a pointer to the first non-space
192*a1bf3f78SToomas Soome  * char of the string, or to the NULL terminator if no such char found.
193*a1bf3f78SToomas Soome  * If the pointer reaches "end" first, stop there. Pass NULL to
194*a1bf3f78SToomas Soome  * suppress this behavior.
195*a1bf3f78SToomas Soome  */
196*a1bf3f78SToomas Soome char *
197*a1bf3f78SToomas Soome ficlStringSkipSpace(char *cp, char *end)
198*a1bf3f78SToomas Soome {
199*a1bf3f78SToomas Soome 	FICL_ASSERT(NULL, cp);
200*a1bf3f78SToomas Soome 
201*a1bf3f78SToomas Soome 	while ((cp != end) && isspace((unsigned char)*cp))
202*a1bf3f78SToomas Soome 		cp++;
203*a1bf3f78SToomas Soome 
204*a1bf3f78SToomas Soome 	return (cp);
205*a1bf3f78SToomas Soome }
206*a1bf3f78SToomas Soome 
207*a1bf3f78SToomas Soome void
208*a1bf3f78SToomas Soome ficlCompatibilityTextOutCallback(ficlCallback *callback, char *text,
209*a1bf3f78SToomas Soome     ficlCompatibilityOutputFunction outputFunction)
210*a1bf3f78SToomas Soome {
211*a1bf3f78SToomas Soome 	char buffer[256];
212*a1bf3f78SToomas Soome 	char *bufferStop = buffer + sizeof (buffer) - 1;
213*a1bf3f78SToomas Soome 
214*a1bf3f78SToomas Soome 	if (text == NULL) {
215*a1bf3f78SToomas Soome 		outputFunction(callback->vm, NULL, 0 /* false */);
216*a1bf3f78SToomas Soome 		return;
217*a1bf3f78SToomas Soome 	}
218*a1bf3f78SToomas Soome 
219*a1bf3f78SToomas Soome 	while (*text) {
220*a1bf3f78SToomas Soome 		int newline = 0 /* false */;
221*a1bf3f78SToomas Soome 		char *trace = buffer;
222*a1bf3f78SToomas Soome 		while ((*text) && (trace < bufferStop)) {
223*a1bf3f78SToomas Soome 			switch (*text) {
224*a1bf3f78SToomas Soome 			/* throw away \r */
225*a1bf3f78SToomas Soome 			case '\r':
226*a1bf3f78SToomas Soome 				text++;
227*a1bf3f78SToomas Soome 			continue;
228*a1bf3f78SToomas Soome 			case '\n':
229*a1bf3f78SToomas Soome 				text++;
230*a1bf3f78SToomas Soome 				newline = !0 /* true */;
231*a1bf3f78SToomas Soome 			break;
232*a1bf3f78SToomas Soome 			default:
233*a1bf3f78SToomas Soome 				*trace++ = *text++;
234*a1bf3f78SToomas Soome 			break;
235*a1bf3f78SToomas Soome 			}
236*a1bf3f78SToomas Soome 		}
237*a1bf3f78SToomas Soome 
238*a1bf3f78SToomas Soome 		*trace = 0;
239*a1bf3f78SToomas Soome 		(outputFunction)(callback->vm, buffer, newline);
240*a1bf3f78SToomas Soome 	}
241*a1bf3f78SToomas Soome }
242