printfDi.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. #include <string.h>
  2. #include "ft_printf_internal.h"
  3. int numberLen(long long number, int alphabetLen, int alternativeForm, char decimalCount)
  4. {
  5. int result = 1;
  6. if (number < 0)
  7. {
  8. number *= -1;
  9. ++result;
  10. }
  11. while (number > alphabetLen)
  12. {
  13. number /= alphabetLen;
  14. result++;
  15. }
  16. if (alternativeForm && alphabetLen == 8)
  17. result++;
  18. if (alternativeForm && alphabetLen == 16)
  19. result += 2;
  20. return result + decimalCount;
  21. }
  22. int doPrintPosNumber(struct printf_data* data, struct printf_format_params* format, char buf[24], int pos)
  23. {
  24. int result = 0;
  25. int sysCallRet;
  26. while (pos >= 0)
  27. {
  28. if (format->flags & PRINTF_FLAG_THD_GROUP && (pos %3) == 2)
  29. {
  30. sysCallRet = printfWrite(data, "'", 1);
  31. if (sysCallRet < 0)
  32. return sysCallRet;
  33. result += sysCallRet;
  34. }
  35. sysCallRet = printfWrite(data, &buf[pos], 1);
  36. if (sysCallRet < 0)
  37. return sysCallRet;
  38. result += sysCallRet;
  39. --pos;
  40. }
  41. return result;
  42. }
  43. int pad(struct printf_data* data, struct printf_format_params* format, int written)
  44. {
  45. int numberSize = written;
  46. int result = 0;
  47. int sysCallRet;
  48. char padWith = ' ';
  49. if (format->width > numberSize)
  50. {
  51. numberSize = format->width - numberSize;
  52. if (format->flags & PRINTF_FLAG_ZERO_PAD)
  53. padWith = '0';
  54. while (numberSize > 0)
  55. {
  56. sysCallRet = printfWrite(data, &padWith, 1);
  57. if (sysCallRet < 0)
  58. return sysCallRet;
  59. result += sysCallRet;
  60. --numberSize;
  61. }
  62. }
  63. return result;
  64. }
  65. int printPosNumber(struct printf_data* data, struct printf_format_params* format, long long posNumber, int written, const char* alphabet, char decimalCount)
  66. {
  67. char buf[32];
  68. int sysCallRet;
  69. int pos = -1;
  70. int result = 0;
  71. int alphabetLen = strlen(alphabet);
  72. if (format->flags & PRINTF_FLAG_ZERO_PAD)
  73. {
  74. sysCallRet = pad(data, format, written + numberLen(posNumber, alphabetLen, format->flags & PRINTF_FLAG_ALTERNATE_FORM, decimalCount));
  75. if (sysCallRet < 0)
  76. return sysCallRet;
  77. result += sysCallRet;
  78. }
  79. if (!posNumber)
  80. return result + printfWrite(data, &alphabet[0], 1);
  81. while (posNumber > 0)
  82. {
  83. ++pos;
  84. buf[pos] = alphabet[posNumber % alphabetLen];
  85. posNumber /= alphabetLen;
  86. }
  87. return result + doPrintPosNumber(data, format, buf, pos);
  88. }
  89. int signPad(struct printf_data* data, struct printf_format_params* format, char isPositiveNumber, int alphabetLen)
  90. {
  91. int result = 0;
  92. int sysCallRet;
  93. if (format->flags & PRINTF_FLAG_SIGNED_SIGN && isPositiveNumber)
  94. {
  95. sysCallRet = printfWrite(data, "+", 1);
  96. if (sysCallRet < 0)
  97. return sysCallRet;
  98. result += sysCallRet;
  99. }
  100. if (format->flags & PRINTF_FLAG_ALTERNATE_FORM)
  101. {
  102. char* alternate;
  103. if (alphabetLen == 8)
  104. alternate = "0";
  105. else if (alphabetLen == 16 && format->typeName == printf_x)
  106. alternate = "0x";
  107. else if (alphabetLen == 16 && format->typeName == printf_X)
  108. alternate = "0X";
  109. sysCallRet = printfWrite(data, alternate, strlen(alternate));
  110. if (sysCallRet < 0)
  111. return sysCallRet;
  112. result += sysCallRet;
  113. }
  114. if (!isPositiveNumber)
  115. {
  116. sysCallRet = printfWrite(data, "-", 1);
  117. if (sysCallRet < 0)
  118. return sysCallRet;
  119. result += sysCallRet;
  120. }
  121. return result;
  122. }
  123. int printfDiPrepend(struct printf_data* data, struct printf_format_params* format, long long number, int alphabetLen, char decimalCount)
  124. {
  125. int result = 0;
  126. int sysCallRet;
  127. if (!(format->flags & PRINTF_FLAG_SIGNED_SIGN) && (format->flags & PRINTF_FLAG_SIGNED_PAD) && number >=0)
  128. {
  129. sysCallRet = printfWrite(data, " ", 1);
  130. if (sysCallRet < 0)
  131. return sysCallRet;
  132. result += sysCallRet;
  133. }
  134. if (!(format->flags & PRINTF_FLAG_LEFT_PADDING) && !(format->flags & PRINTF_FLAG_ZERO_PAD))
  135. {
  136. int _numberLen = numberLen(number, alphabetLen, format->flags & PRINTF_FLAG_ALTERNATE_FORM, decimalCount);
  137. sysCallRet = pad(data, format, result + _numberLen);
  138. if (sysCallRet < 0)
  139. return sysCallRet;
  140. result += sysCallRet;
  141. }
  142. sysCallRet = signPad(data, format, number >= 0, alphabetLen);
  143. if (sysCallRet < 0)
  144. return sysCallRet;
  145. return result + sysCallRet;
  146. }
  147. int printfNumber(struct printf_data* data, struct printf_format_params* format, long long int number, char decimalLength, const char* alphabet)
  148. {
  149. int result = 0;
  150. int sysCallRet;
  151. sysCallRet = printfDiPrepend(data, format, number, strlen(alphabet), decimalLength);
  152. if (sysCallRet < 0)
  153. return sysCallRet;
  154. result += sysCallRet;
  155. if (number < 0)
  156. number *= -1;
  157. sysCallRet = printPosNumber(data, format, number, result, alphabet, decimalLength);
  158. if (sysCallRet < 0)
  159. return sysCallRet;
  160. result += sysCallRet;
  161. if (decimalLength == 0 && (format->flags & PRINTF_FLAG_LEFT_PADDING) && !(format->flags & PRINTF_FLAG_ZERO_PAD))
  162. {
  163. sysCallRet = pad(data, format, result);
  164. if (sysCallRet < 0)
  165. return sysCallRet;
  166. result += sysCallRet;
  167. }
  168. return result;
  169. }
  170. /*
  171. *
  172. * The int argument is converted to signed decimal notation.
  173. * The precision, if any, gives the minimum number of digits that must appear;
  174. * if the converted value requires fewer digits, it is padded on the left with zeros.
  175. * The default precision is 1.
  176. * When 0 is printed with an explicit precision 0, the output is empty.
  177. *
  178. **/
  179. int printf_di(struct printf_data* data, struct printf_format_params* format, va_list args)
  180. {
  181. return printfNumber(data, format, va_arg(args, int), 0, DEC_ALPHABET);
  182. }