sprintf.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. /*
  2. * Copyright (C) 1997 Robey Pointer
  3. * Copyright (C) 1999 - 2002 Eggheads Development Team
  4. * Copyright (C) 2002 - 2008 Bryan Drewery
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version 2
  9. * of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  19. */
  20. /* sprintf.c
  21. *
  22. */
  23. #include "common.h"
  24. #include "sprintf.h"
  25. #include "base64.h"
  26. #include <stdarg.h>
  27. static char buf_convert[20] = "";
  28. static char *int_to_string(const long val, const unsigned int base)
  29. {
  30. buf_convert[sizeof(buf_convert) - 1] = 0;
  31. if (!val) {
  32. buf_convert[sizeof(buf_convert) - 2] = '0';
  33. return buf_convert + sizeof(buf_convert) - 2;
  34. }
  35. bool negative = 0;
  36. long uval = val;
  37. if (val < 0) {
  38. negative = 1;
  39. uval = -val;
  40. }
  41. int place = sizeof(buf_convert) - 1;
  42. while (uval && place >= 0) {
  43. buf_convert[--place] = '0' + uval % base;
  44. uval /= base;
  45. }
  46. if (negative)
  47. buf_convert[--place] = '-';
  48. return buf_convert + place;
  49. }
  50. static char *unsigned_int_to_string(unsigned long val, const unsigned int base, bool caps = false)
  51. {
  52. buf_convert[sizeof(buf_convert) - 1] = 0;
  53. if (!val) {
  54. buf_convert[sizeof(buf_convert) - 2] = '0';
  55. return buf_convert + sizeof(buf_convert) - 2;
  56. }
  57. int place = sizeof(buf_convert) - 1;
  58. while (val && place >= 0) {
  59. buf_convert[--place] = (caps ? "0123456789ABCDEF" : "0123456789abcdef")[val % base];
  60. val /= base;
  61. }
  62. return buf_convert + place;
  63. }
  64. size_t simple_vsnprintf(char *buf, size_t size, const char *format, va_list va)
  65. {
  66. char *s = NULL;
  67. char *fp = (char *) format;
  68. size_t c = 0;
  69. unsigned long i = 0;
  70. bool islong = 0, caps = false;
  71. while (*fp && c < size - 1) {
  72. if (*fp == '%') {
  73. re_eval_with_modifier:
  74. ++fp;
  75. switch (*fp) {
  76. case 'z':
  77. case 'l':
  78. islong = 1;
  79. goto re_eval_with_modifier;
  80. case '^': //STRING
  81. caps = true;
  82. goto re_eval_with_modifier;
  83. case 's': //string
  84. s = va_arg(va, char *);
  85. break;
  86. case 'd': //int
  87. case 'i':
  88. if (islong) {
  89. i = va_arg(va, long);
  90. islong = 0;
  91. } else
  92. i = va_arg(va, int);
  93. s = int_to_string(i, 10);
  94. break;
  95. case 'D': //stupid eggdrop base64
  96. i = va_arg(va, int);
  97. s = int_to_base64((unsigned int) i);
  98. break;
  99. case 'u': //unsigned
  100. if (islong) {
  101. i = va_arg(va, unsigned long);
  102. islong = 0;
  103. } else
  104. i = va_arg(va, unsigned int);
  105. s = unsigned_int_to_string(i, 10);
  106. break;
  107. case 'X': //HEX
  108. caps = true;
  109. case 'x': //hex
  110. if (islong) {
  111. i = va_arg(va, unsigned long);
  112. islong = 0;
  113. } else
  114. i = va_arg(va, unsigned int);
  115. s = unsigned_int_to_string(i, 16, caps);
  116. caps = false;
  117. break;
  118. case '%': //%
  119. buf[c++] = *fp++;
  120. continue;
  121. case 'c': //char
  122. buf[c++] = (char) va_arg(va, int);
  123. fp++;
  124. continue;
  125. default:
  126. continue;
  127. }
  128. if (s) {
  129. if (caps) {
  130. while (*s && c < size - 1)
  131. buf[c++] = toupper(*s++);
  132. caps = false;
  133. } else {
  134. while (*s && c < size - 1)
  135. buf[c++] = *s++;
  136. }
  137. }
  138. fp++;
  139. } else
  140. buf[c++] = *fp++;
  141. }
  142. buf[c] = '\0';
  143. return c;
  144. }
  145. size_t simple_vsprintf(char *buf, const char *format, va_list va)
  146. {
  147. return simple_vsnprintf(buf, VSPRINTF_MAXSIZE, format, va);
  148. }
  149. size_t simple_snprintf2 (char *buf, size_t size, const char *format, ...)
  150. {
  151. size_t ret = 0;
  152. va_list va;
  153. va_start(va, format);
  154. ret = simple_vsnprintf(buf, size, format, va);
  155. va_end(va);
  156. return ret;
  157. }
  158. size_t simple_sprintf (char *buf, const char *format, ...)
  159. {
  160. size_t ret = 0;
  161. va_list va;
  162. va_start(va, format);
  163. ret = simple_vsprintf(buf, format, va);
  164. va_end(va);
  165. return ret;
  166. }
  167. size_t simple_snprintf (char *buf, size_t size, const char *format, ...)
  168. {
  169. size_t ret = 0;
  170. va_list va;
  171. va_start(va, format);
  172. ret = simple_vsnprintf(buf, size, format, va);
  173. va_end(va);
  174. return ret;
  175. }