Guest User

Untitled

a guest
Jul 20th, 2018
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.43 KB | None | 0 0
  1. #define OUT
  2. #define IN
  3.  
  4. #define is_digit(c) ((c) >= '0' && (c) <= '9')
  5.  
  6. int m_printn(OUT char *str, IN int maxlen, IN int len, IN unsigned int n,
  7. IN int base, IN int size, IN int flags, IN int precision)
  8. {
  9. char tmp[36], sign = '\0';
  10. char *digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  11. int i = 0;
  12. signed int signed_n = (signed int) n;
  13.  
  14. /* Preprocess the flags. */
  15.  
  16. if (flags & TF_SMALL)
  17. digits = "0123456789abcdefghijklmnopqrstuvwxyz";
  18.  
  19. if (!(flags & TF_UNSIGNED) && signed_n < 0) {
  20. sign = '-';
  21. n = -signed_n;
  22. } else if (flags & TF_EXP_SIGN) {
  23. sign = '+';
  24. }
  25.  
  26. if (sign)
  27. size--;
  28.  
  29. if (flags & TF_ALTERNATE)
  30. if (base == 8) {
  31. if (len < maxlen)
  32. str[len++] = '0';
  33. else
  34. len++;
  35. } else if (base == 16) {
  36. if (len < maxlen)
  37. str[len++] = '0';
  38. else
  39. len++;
  40. if (len < maxlen)
  41. str[len++] = 'x';
  42. else
  43. len++;
  44. }
  45.  
  46. /* Find the number in reverse. */
  47. if (n == 0)
  48. tmp[i++] = '0';
  49. else
  50. while (n != 0) {
  51. tmp[i++] = digits[n%base];
  52. n /= base;
  53. }
  54.  
  55. /* Pad the number with zeros or spaces. */
  56. if (!(flags & TF_LEFT))
  57. while (size-- > i) {
  58. if (flags & TF_ZEROPAD)
  59. if (len < maxlen)
  60. str[len++] = '0';
  61. else
  62. len++;
  63. else
  64. if (len < maxlen)
  65. str[len++] = ' ';
  66. else
  67. len++;
  68. }
  69.  
  70. if (sign)
  71. str[len++] = sign;
  72.  
  73. /* Write any zeros to satisfy the precision. */
  74. while (i < precision--)
  75. if (len < maxlen)
  76. str[len++] = '0';
  77. else
  78. len++;
  79.  
  80. /* Write the number. */
  81. while (i-- != 0) {
  82. size--;
  83. if (len < maxlen)
  84. str[len++] = tmp[i];
  85. else
  86. len++;
  87. }
  88.  
  89. /* Left align the numbers. */
  90. if (flags & TF_LEFT)
  91. while (size-- > 0) {
  92. if (len < maxlen)
  93. str[len++] = ' ';
  94. else
  95. len++;
  96. }
  97.  
  98. return len;
  99. }
  100.  
  101. int printf(IN const char *fmt, ...)
  102. {
  103. /* TODO: Make printf use memory management. */
  104. #if 0
  105. char *str;
  106. #endif
  107. char str[1024];
  108. va_list args;
  109. int len, i = 0;
  110.  
  111. #if 0
  112. va_start(args, fmt);
  113. len = vsnprintf(NULL, 0, fmt, args);
  114. va_end(args);
  115.  
  116. str = malloc(len+1);
  117.  
  118. va_start(args, fmt);
  119. len = vsnprintf(str, len+1, fmt, args);
  120. va_end(args);
  121. #endif
  122.  
  123. va_start(args, fmt);
  124. len = vsnprintf(str, 1024, fmt, args);
  125. va_end(args);
  126.  
  127. /* Display string here. */
  128.  
  129. #if 0
  130. free(str);
  131. #endif
  132.  
  133. return i;
  134. }
  135.  
  136. int sprintf(OUT char *str, IN const char *fmt, ...)
  137. {
  138. va_list args;
  139. int i;
  140.  
  141. va_start(args, fmt);
  142. i = vsnprintf(str, 0, fmt, args);
  143. va_end(args);
  144.  
  145. va_start(args, fmt);
  146. i = vsnprintf(str, i+1, fmt, args);
  147. va_end(args);
  148.  
  149. return i;
  150. }
  151.  
  152. int snprintf(OUT char *str, IN size_t size, IN const char *fmt, ...)
  153. {
  154. va_list args;
  155. int i;
  156.  
  157. va_start(args, fmt);
  158. i = vsnprintf(str, size, fmt, args);
  159. va_end(args);
  160. return i;
  161. }
  162.  
  163. int vprintf(IN const char *fmt, va_list ap)
  164. {
  165. /* TODO: Make vprintf use memory management. */
  166. #if 0
  167. char *str;
  168. #endif
  169. char str[1024];
  170. va_list args;
  171. int len, i = 0;
  172.  
  173. #if 0
  174. len = vsnprintf(NULL, 0, fmt, ap);
  175. str = malloc(len+1);
  176. len = vsnprintf(str, len+1, fmt, ap);
  177. #endif
  178.  
  179. len = vsnprintf(str, 1024, fmt, ap);
  180.  
  181. /* Display string here. */
  182.  
  183. #if 0
  184. free(str);
  185. #endif
  186.  
  187. return i;
  188. }
  189.  
  190. int vsprintf(OUT char *str, IN const char *fmt, va_list ap)
  191. {
  192. int i;
  193.  
  194. i = vsnprintf(str, 0, fmt, ap);
  195. i = vsnprintf(str, i+1, fmt, ap);
  196. return i;
  197. }
  198.  
  199. int vsnprintf(OUT char *str, IN size_t size, IN const char *fmt,
  200. IN va_list ap)
  201. {
  202. int len = 0;
  203. const char *p;
  204. int flags, fieldwidth, precision, i;
  205. const char *sval;
  206.  
  207. /* Leave room for the null byte. */
  208. if (size != 0)
  209. size--;
  210.  
  211. for (p = fmt; *p; p++) {
  212. if (*p != '%') {
  213. if (len < size)
  214. str[len++] = *p;
  215. else
  216. len++;
  217. continue;
  218. }
  219.  
  220. /* Find any flags. */
  221. flags = 0;
  222. reset:
  223. switch (*++p) {
  224. case '#':
  225. flags |= TF_ALTERNATE;
  226. goto reset;
  227. case '0':
  228. flags |= TF_ZEROPAD;
  229. goto reset;
  230. case '-':
  231. flags |= TF_LEFT;
  232. goto reset;
  233. case ' ':
  234. flags |= TF_SPACE;
  235. goto reset;
  236. case '+':
  237. flags |= TF_EXP_SIGN;
  238. goto reset;
  239. }
  240.  
  241. /* Find the field width. */
  242. fieldwidth = 0;
  243. while (is_digit(*p)) {
  244. if (fieldwidth > 0)
  245. fieldwidth *= 10;
  246. fieldwidth += (*p++-0x30);
  247. }
  248.  
  249. /* Find the precision. */
  250. precision = -1;
  251. if (*p == '.') {
  252. *p++;
  253. precision = 0;
  254. if (*p == '*') {
  255. precision = va_arg(ap, int);
  256. p++;
  257. }
  258. while (is_digit(*p)) {
  259. if (precision > 0)
  260. precision *= 10;
  261. precision += (*p++-0x30);
  262. }
  263. }
  264.  
  265. /* Find the length modifier. */
  266. if (*p == 'l' || *p == 'h' || *p == 'L') {
  267. p++;
  268. }
  269.  
  270. flags |= TF_UNSIGNED;
  271. /* Find the conversion. */
  272. switch (*p) {
  273. case 'i':
  274. case 'd':
  275. flags &= ~TF_UNSIGNED;
  276. len = m_printn(str, size, len,
  277. va_arg(ap, int), 10,
  278. fieldwidth, flags, precision);
  279. break;
  280. case 'o':
  281. len = m_printn(str, size, len,
  282. va_arg(ap, unsigned int), 8,
  283. fieldwidth, flags, precision);
  284. break;
  285. case 'u':
  286. len = m_printn(str, size, len,
  287. va_arg(ap, unsigned int), 10,
  288. fieldwidth, flags, precision);
  289. break;
  290. case 'x':
  291. len = m_printn(str, size, len,
  292. va_arg(ap, unsigned int), 16,
  293. fieldwidth, flags|TF_SMALL, precision);
  294. break;
  295. case 'X':
  296. len = m_printn(str, size, len,
  297. va_arg(ap, unsigned int), 16,
  298. fieldwidth, flags, precision);
  299. break;
  300. case 'c':
  301. i = 0;
  302. if (!(flags & TF_LEFT))
  303. while (i++ < fieldwidth)
  304. if (len < size)
  305. str[len++] = ' ';
  306. else
  307. len++;
  308. if (len < size) {
  309. str[len++] =
  310. (unsigned char) va_arg(ap, int);
  311. } else {
  312. len++;
  313. va_arg(ap, void);
  314. }
  315. while (i++ < fieldwidth)
  316. if (len < size)
  317. str[len++] = ' ';
  318. else
  319. len++;
  320. break;
  321. case 's':
  322. sval = va_arg(ap, const char*);
  323. /* Change to -2 so that 0-1 doesn't cause the
  324. * loop to keep going. */
  325. if (precision == -1)
  326. precision = -2;
  327. while (*sval
  328. && (precision-->0 || precision <= -2))
  329. if (len < size) {
  330. str[len++] = *sval++;
  331. } else {
  332. sval++;
  333. len++;
  334. }
  335. break;
  336. case '%':
  337. if (len < size)
  338. str[len++] = '%';
  339. else
  340. len++;
  341. break;
  342. default:
  343. if (len < size)
  344. str[len++] = *p;
  345. else
  346. len++;
  347. }
  348. }
  349.  
  350. /* And now we magically have room for one more byte. */
  351. if (size != 0)
  352. size++;
  353.  
  354. if (len < size)
  355. str[len] = '\0';
  356. else
  357. if (size != 0)
  358. str[size] = '\0';
  359. return len;
  360. }
Add Comment
Please, Sign In to add comment