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