| 1 | /* Copyright (C) 2003 Manuel Novoa III |
|---|
| 2 | * |
|---|
| 3 | * This library is free software; you can redistribute it and/or |
|---|
| 4 | * modify it under the terms of the GNU Library General Public |
|---|
| 5 | * License as published by the Free Software Foundation; either |
|---|
| 6 | * version 2 of the License, or (at your option) any later version. |
|---|
| 7 | * |
|---|
| 8 | * This library is distributed in the hope that it will be useful, |
|---|
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|---|
| 11 | * Library General Public License for more details. |
|---|
| 12 | * |
|---|
| 13 | * You should have received a copy of the GNU Library General Public |
|---|
| 14 | * License along with this library; if not, write to the Free |
|---|
| 15 | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
|---|
| 16 | */ |
|---|
| 17 | |
|---|
| 18 | /* ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION! |
|---|
| 19 | * |
|---|
| 20 | * This code is currently under development. Also, I plan to port |
|---|
| 21 | * it to elks which is a 16-bit environment with a fairly limited |
|---|
| 22 | * compiler. Therefore, please refrain from modifying this code |
|---|
| 23 | * and, instead, pass any bug-fixes, etc. to me. Thanks. Manuel |
|---|
| 24 | * |
|---|
| 25 | * ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION! */ |
|---|
| 26 | |
|---|
| 27 | #ifndef _UINTMAXTOSTR_H |
|---|
| 28 | #define _UINTMAXTOSTR_H 1 |
|---|
| 29 | |
|---|
| 30 | #ifdef _FEATURES_H |
|---|
| 31 | # ifndef __USE_ISOC99 |
|---|
| 32 | # error features was included without defining _ISOC99_SOURCE! |
|---|
| 33 | # endif |
|---|
| 34 | #else |
|---|
| 35 | # ifndef _ISOC99_SOURCE |
|---|
| 36 | # define _ISOC99_SOURCE |
|---|
| 37 | # endif |
|---|
| 38 | #endif |
|---|
| 39 | |
|---|
| 40 | #include <features.h> |
|---|
| 41 | #include <limits.h> |
|---|
| 42 | #include <stdint.h> |
|---|
| 43 | |
|---|
| 44 | #if INTMAX_MAX <= 2147483647L |
|---|
| 45 | #define __UIM_BUFLEN 12 /* 10 digits + 1 nul + 1 sign */ |
|---|
| 46 | #elif INTMAX_MAX <= 9223372036854775807LL |
|---|
| 47 | #define __UIM_BUFLEN 22 /* 20 digits + 1 nul + 1 sign */ |
|---|
| 48 | #else |
|---|
| 49 | #error unknown number of digits for intmax_t! |
|---|
| 50 | #endif |
|---|
| 51 | |
|---|
| 52 | #ifdef LLONG_MAX /* --------------- */ |
|---|
| 53 | #if LLONG_MAX <= 2147483647L |
|---|
| 54 | #define __UIM_BUFLEN_LLONG 12 /* 10 digits + 1 nul + 1 sign */ |
|---|
| 55 | #elif LLONG_MAX <= 9223372036854775807LL |
|---|
| 56 | #define __UIM_BUFLEN_LLONG 22 /* 20 digits + 1 nul + 1 sign */ |
|---|
| 57 | #else |
|---|
| 58 | #error unknown number of digits for long long! |
|---|
| 59 | #endif |
|---|
| 60 | #endif /* ULLONG_MAX ----------------------------- */ |
|---|
| 61 | |
|---|
| 62 | #if LONG_MAX <= 2147483647L |
|---|
| 63 | #define __UIM_BUFLEN_LONG 12 /* 10 digits + 1 nul + 1 sign */ |
|---|
| 64 | #elif LONG_MAX <= 9223372036854775807LL |
|---|
| 65 | #define __UIM_BUFLEN_LONG 22 /* 20 digits + 1 nul + 1 sign */ |
|---|
| 66 | #else |
|---|
| 67 | #error unknown number of digits for long! |
|---|
| 68 | #endif |
|---|
| 69 | |
|---|
| 70 | #if INT_MAX <= 32767 |
|---|
| 71 | #define __UIM_BUFLEN_INT 7 /* 10 digits + 1 nul + 1 sign */ |
|---|
| 72 | #elif INT_MAX <= 2147483647L |
|---|
| 73 | #define __UIM_BUFLEN_INT 12 /* 10 digits + 1 nul + 1 sign */ |
|---|
| 74 | #else |
|---|
| 75 | #error unknown number of digits for int! |
|---|
| 76 | #endif |
|---|
| 77 | |
|---|
| 78 | typedef enum { |
|---|
| 79 | __UIM_DECIMAL = 0, |
|---|
| 80 | __UIM_GROUP = ',', /* Base 10 locale-dependent grouping. */ |
|---|
| 81 | __UIM_LOWER = 'a' - 10, |
|---|
| 82 | __UIM_UPPER = 'A' - 10, |
|---|
| 83 | } __UIM_CASE; |
|---|
| 84 | |
|---|
| 85 | /* Convert the int val to a string in base abs(base). val is treated as |
|---|
| 86 | * an unsigned ??? int type if base > 0, and signed if base < 0. This |
|---|
| 87 | * is an internal function with _no_ error checking done unless assert()s |
|---|
| 88 | * are enabled. |
|---|
| 89 | * |
|---|
| 90 | * Note: bufend is a pointer to the END of the buffer passed. |
|---|
| 91 | * Call like this: |
|---|
| 92 | * char buf[SIZE], *p; |
|---|
| 93 | * p = _xltostr(buf + sizeof(buf) - 1, {unsigned int}, 10, __UIM_DECIMAL) |
|---|
| 94 | * p = _xltostr(buf + sizeof(buf) - 1, {int}, -10, __UIM_DECIMAL) |
|---|
| 95 | * |
|---|
| 96 | * WARNING: If base > 10, case _must_be_ either __UIM_LOWER or __UIM_UPPER |
|---|
| 97 | * for lower and upper case alphas respectively. |
|---|
| 98 | * WARNING: If val is really a signed type, make sure base is negative! |
|---|
| 99 | * Otherwise, you could overflow your buffer. |
|---|
| 100 | */ |
|---|
| 101 | extern char *_uintmaxtostr(char * __restrict bufend, uintmax_t uval, |
|---|
| 102 | int base, __UIM_CASE alphacase); |
|---|
| 103 | |
|---|
| 104 | /* TODO -- make this either a (possibly inline) function? */ |
|---|
| 105 | #ifndef __BCC__ |
|---|
| 106 | #define _int10tostr(bufend, intval) \ |
|---|
| 107 | _uintmaxtostr((bufend), (intval), -10, __UIM_DECIMAL) |
|---|
| 108 | #else /* bcc doesn't do prototypes, we need to explicitly cast */ |
|---|
| 109 | #define _int10tostr(bufend, intval) \ |
|---|
| 110 | _uintmaxtostr((bufend), (uintmax_t)(intval), -10, __UIM_DECIMAL) |
|---|
| 111 | #endif |
|---|
| 112 | |
|---|
| 113 | #define __BUFLEN_INT10TOSTR __UIM_BUFLEN_INT |
|---|
| 114 | |
|---|
| 115 | #endif /* _UINTMAXTOSTR_H */ |
|---|