1/* -*- Mode: c++ -*- 2 * $Id: xotclUtil.c,v 1.3 2006/02/18 22:17:33 neumann Exp $ 3 * 4 * Extended Object Tcl (XOTcl) 5 * 6 * Copyright (C) 1999-2008 Gustaf Neumann, Uwe Zdun 7 * 8 * 9 * xotclUtil.c -- 10 * 11 * Utility functions 12 * 13 */ 14 15#include "xotclInt.h" 16 17char * 18XOTcl_ltoa(char *buf, long i, int *len) /* fast version of sprintf(buf,"%ld",l); */ { 19 int nr_written, negative; 20 char tmp[LONG_AS_STRING], *pointer = &tmp[1], *string, *p; 21 *tmp = 0; 22 23 if (i<0) { 24 i = -i; 25 negative = nr_written = 1; 26 } else 27 nr_written = negative = 0; 28 29 do { 30 nr_written++; 31 *pointer++ = i%10 + '0'; 32 i/=10; 33 } while (i); 34 35 p = string = buf; 36 if (negative) 37 *p++ = '-'; 38 39 while ((*p++ = *--pointer)); /* copy number (reversed) from tmp to buf */ 40 if (len) *len = nr_written; 41 return string; 42} 43 44 45static char *alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 46static int blockIncrement = 8; 47/* 48static char *alphabet = "ab"; 49static int blockIncrement = 2; 50*/ 51static unsigned char chartable[255] = {0}; 52 53 54char * 55XOTclStringIncr(XOTclStringIncrStruct *iss) { 56 char newch, *currentChar; 57 58 currentChar = iss->buffer + iss->bufSize - 2; 59 newch = *(alphabet + chartable[(unsigned)*currentChar]); 60 61 while (1) { 62 if (newch) { /* no overflow */ 63 *currentChar = newch; 64 break; 65 } else { /* overflow */ 66 *currentChar = *alphabet; /* use first char from alphabet */ 67 currentChar--; 68 assert(currentChar >= iss->buffer); 69 70 newch = *(alphabet + chartable[(unsigned)*currentChar]); 71 if (currentChar < iss->start) { 72 iss->length++; 73 if (currentChar == iss->buffer) { 74 size_t newBufSize = iss->bufSize + blockIncrement; 75 char *newBuffer = ckalloc(newBufSize); 76 currentChar = newBuffer+blockIncrement; 77 /*memset(newBuffer, 0, blockIncrement);*/ 78 memcpy(currentChar, iss->buffer, iss->bufSize); 79 *currentChar = newch; 80 iss->start = currentChar; 81 ckfree(iss->buffer); 82 iss->buffer = newBuffer; 83 iss->bufSize = newBufSize; 84 } else { 85 iss->start = currentChar; 86 } 87 } 88 } 89 } 90 assert(iss->buffer[iss->bufSize-1] == 0); 91 assert(iss->buffer[iss->bufSize-2] != 0); 92 assert(iss->length < iss->bufSize); 93 assert(iss->start + iss->length + 1 == iss->buffer + iss->bufSize); 94 95 return iss->start; 96} 97 98 99void 100XOTclStringIncrInit(XOTclStringIncrStruct *iss) { 101 char *p; 102 int i = 0; 103 const size_t bufSize = blockIncrement>2 ? blockIncrement : 2; 104 105 for (p=alphabet; *p; p++) { 106 chartable[(int)*p] = ++i; 107 } 108 109 iss->buffer = ckalloc(bufSize); 110 memset(iss->buffer, 0, bufSize); 111 iss->start = iss->buffer + bufSize-2; 112 iss->bufSize = bufSize; 113 iss->length = 1; 114 /* 115 for (i=1; i<50; i++) { 116 XOTclStringIncr(iss); 117 fprintf(stderr, "string '%s' (%d)\n", iss->start, iss->length); 118 } 119 */ 120} 121 122void 123XOTclStringIncrFree(XOTclStringIncrStruct *iss) { 124 ckfree(iss->buffer); 125} 126