287 lines
7.1 KiB
C
287 lines
7.1 KiB
C
#include <stdlib.h>
|
|
#include <ctype.h>
|
|
|
|
const char base_chars[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
|
|
void uitoa (unsigned int value, char *string, int radix)
|
|
{
|
|
if (radix == 1 || radix>36) return;
|
|
|
|
// Variables
|
|
int len; *string = '0';
|
|
unsigned int temp = value;
|
|
|
|
// Calculate string length needed
|
|
for (len = 0; temp > 0; len++) temp /= radix;
|
|
if (len == 0) len = 2;
|
|
|
|
// Last character is NULL
|
|
string[len] = 0;
|
|
|
|
// Write characters
|
|
for (len--; len >=0; len-- ) {
|
|
string[len] = base_chars[value%radix];
|
|
value/=radix;
|
|
}
|
|
}
|
|
|
|
void ultoa (unsigned long value, char *string, int radix)
|
|
{
|
|
if (radix == 1 || radix>36) return;
|
|
|
|
// Variables
|
|
int len; *string = '0';
|
|
unsigned long temp = value;
|
|
|
|
// Calculate string length needed
|
|
for (len = 0; temp > 0; len++) temp /= radix;
|
|
if (len == 0) len = 2;
|
|
|
|
// Last character is NULL
|
|
string[len] = 0;
|
|
|
|
// Write characters
|
|
for (len--; len >=0; len-- ) {
|
|
string[len] = base_chars[value%radix];
|
|
value/=radix;
|
|
}
|
|
}
|
|
|
|
void itoa (signed int value, char *string, int radix)
|
|
{
|
|
if (radix == 1 || radix>36) return;
|
|
|
|
// Variables
|
|
int len = 0; *string = '0';
|
|
unsigned int copy = value;
|
|
|
|
// If number is < 0
|
|
if (value < 0) {
|
|
if (radix == 10) {
|
|
len++; copy = abs(value);
|
|
}
|
|
else copy = (unsigned) value; // If base is not 10, set high bit
|
|
}
|
|
|
|
// Calculate string length needed
|
|
unsigned int temp = copy;
|
|
for (; temp > 0; len++) temp /= radix;
|
|
if (len == 0) len = 2;
|
|
|
|
// Last character is NULL
|
|
string[len] = 0;
|
|
|
|
// Write characters
|
|
for (len--; len >= 0; len-- ) {
|
|
string[len] = base_chars[copy%radix];
|
|
copy/=radix;
|
|
}
|
|
|
|
// Add minus sign
|
|
if (value < 0 && radix == 10) string[0] = '-';
|
|
}
|
|
|
|
void ltoa (signed long value, char *string, int radix)
|
|
{
|
|
if (radix == 1 || radix>36) return;
|
|
|
|
// Variables
|
|
int len = 0; *string = '0';
|
|
unsigned long copy = value;
|
|
|
|
// If number is < 0
|
|
if (value < 0) {
|
|
if (radix == 10) {
|
|
len++; copy = abs(value);
|
|
}
|
|
else copy = (unsigned) value; // If base is not 10, set high bit
|
|
}
|
|
|
|
// Calculate string length needed
|
|
unsigned long temp = copy;
|
|
for (; temp > 0; len++) temp /= radix;
|
|
if (len == 0) len = 2;
|
|
|
|
// Last character is NULL
|
|
string[len] = 0;
|
|
|
|
// Write characters
|
|
for (len--; len >= 0; len-- ) {
|
|
string[len] = base_chars[copy%radix];
|
|
copy/=radix;
|
|
}
|
|
|
|
// Add minus sign
|
|
if (value < 0 && radix == 10) string[0] = '-';
|
|
}
|
|
|
|
int atoi (const char* string)
|
|
{
|
|
int ret = 0;
|
|
unsigned char sign = 0;
|
|
|
|
for (;!isdigit((unsigned char)*string); string++) {
|
|
if (*string == NULL) return 0;
|
|
else if (*string == '-' && isdigit(*(string+1)))
|
|
sign = 1;
|
|
}
|
|
|
|
for (;isdigit(*string); string++)
|
|
ret = ret*10 + (*string - '0');
|
|
|
|
if (sign) ret*=-1;
|
|
|
|
return ret;
|
|
}
|
|
|
|
long atol (const char* string)
|
|
{
|
|
long int ret = 0;
|
|
unsigned char sign = 0;
|
|
|
|
for (;!isdigit(*string); string++) {
|
|
if (*string == NULL) return 0;
|
|
else if (*string == '-' && *(string+1) > '0' && *(string+1) < '9')
|
|
sign = 1;
|
|
}
|
|
|
|
for (;isdigit(*string); string++)
|
|
ret = ret*10 + (*string - '0');
|
|
|
|
if (sign) ret*=-1;
|
|
|
|
return ret;
|
|
}
|
|
|
|
unsigned int atox (const char* string)
|
|
{
|
|
unsigned ret = 0;
|
|
unsigned temp;
|
|
|
|
for (;!isxdigit(*string); string++)
|
|
if (*string == 0) return 0;
|
|
|
|
for (;isxdigit(*string); string++) {
|
|
if (isdigit(*string)) temp = (unsigned)*string - '0';
|
|
else if (isupper(*string)) temp = 10 + (unsigned)(*string) - 'A';
|
|
else temp = 10 + (unsigned)(*string) - 'a';
|
|
ret = ret*0x10 + temp;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
void* bsearch (const void* key, const void* base, unsigned nelem, unsigned width, int (*fcmp)(const void*, const void*))
|
|
{
|
|
int beg = 0, end = nelem, mid, result;
|
|
unsigned addr;
|
|
|
|
while (beg != end && beg != end-1) {
|
|
mid = (beg + end) / 2;
|
|
addr = (unsigned)base + (mid * width);
|
|
result = (*fcmp)(key, (void*) addr);
|
|
|
|
if (result == 0) return (void*) addr;
|
|
else if (result > 0) beg = mid;
|
|
else end = mid;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void* lfind (const void* key, const void* base, unsigned nelem, unsigned width, int (*fcmp)(const void*, const void*))
|
|
{
|
|
int result = 1, i = 0;
|
|
|
|
while (result != 0 && i != nelem) {
|
|
base = (void*)((unsigned)base + width);
|
|
result = (*fcmp)(key, base);
|
|
i++;
|
|
}
|
|
|
|
if (result == 0) return (void*) base;
|
|
return 0;
|
|
}
|
|
|
|
div_t div (int numerator, int denominator)
|
|
{
|
|
div_t ret;
|
|
ret.quot = numerator / denominator;
|
|
ret.rem = numerator % denominator;
|
|
return ret;
|
|
}
|
|
|
|
ldiv_t ldiv (long numerator, long denominator)
|
|
{
|
|
ldiv_t ret;
|
|
ret.quot = numerator / denominator;
|
|
ret.rem = numerator % denominator;
|
|
return ret;
|
|
}
|
|
|
|
inline void __qassign (void *dest, void *source, unsigned width)
|
|
{
|
|
unsigned char* dst = (unsigned char*)dest;
|
|
unsigned char* src = (unsigned char*)source;
|
|
int i;
|
|
|
|
for (i = 0; i < width; i++, dst++, src++)
|
|
*dst = *src;
|
|
|
|
}
|
|
|
|
void __qsort(void* base, unsigned width, int (*fcmp)(const void*, const void*), int beg, int end)
|
|
{
|
|
unsigned char piv_str[width];
|
|
unsigned char tmp_str[width];
|
|
void* piv = (void*) piv_str; void* tmp = (void*) tmp_str;
|
|
|
|
int l,r,p;
|
|
|
|
while (beg<end) // This while loop will avoid the second recursive call
|
|
{
|
|
l = beg; p = (beg+end)/2; r = end;
|
|
|
|
__qassign(piv, (void*) ((unsigned)base + (width * p)), width);
|
|
//piv = (void*) ((unsigned)base + (width * p));
|
|
|
|
while (1)
|
|
{
|
|
while ( (l<=r) && ( (*fcmp)( (void*) ((unsigned)base + (width * l)) ,piv) <= 0 ) ) l++;
|
|
while ( (l<=r) && ( (*fcmp)( (void*) ((unsigned)base + (width * r)) ,piv) > 0 ) ) r--;
|
|
|
|
if (l>r) break;
|
|
|
|
__qassign (tmp, (void*) ((unsigned)base + (width * l)), width);
|
|
__qassign ((void*) ((unsigned)base + (width * l)), (void*) ((unsigned)base + (width * r)), width);
|
|
__qassign ((void*) ((unsigned)base + (width * r)), tmp, width);
|
|
//tmp=base[l]; base[l]=base[r]; base[r]=tmp;
|
|
|
|
if (p==r) p=l;
|
|
|
|
l++; r--;
|
|
}
|
|
|
|
__qassign((void*) ((unsigned)base + (width * p)), (void*) ((unsigned)base + (width * r)), width);
|
|
__qassign((void*) ((unsigned)base + (width * r)), piv, width);
|
|
//base[p]=base[r]; base[r]=piv;
|
|
r--;
|
|
|
|
// Recursion on the shorter side & loop (with new indexes) on the longer
|
|
if ((r-beg)<(end-l))
|
|
{
|
|
__qsort(base, width, *fcmp, beg, r);
|
|
beg=l;
|
|
}
|
|
else
|
|
{
|
|
__qsort(base, width, *fcmp, l, end);
|
|
end=r;
|
|
}
|
|
}
|
|
}
|
|
|
|
void qsort (void* base, unsigned nelem, unsigned width, int (*fcmp)(const void*, const void*))
|
|
{
|
|
__qsort(base, width, *fcmp, 0, nelem-1);
|
|
}
|
|
|