PageRenderTime 50ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/stand/printf.c

https://github.com/neilss/4.4BSD-Lite
C | 176 lines | 105 code | 10 blank | 61 comment | 17 complexity | 7a0f6a74ecf7e98476e9e44657817cc1 MD5 | raw file
  1. /*-
  2. * Copyright (c) 1993
  3. * The Regents of the University of California. All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * 3. All advertising materials mentioning features or use of this software
  14. * must display the following acknowledgement:
  15. * This product includes software developed by the University of
  16. * California, Berkeley and its contributors.
  17. * 4. Neither the name of the University nor the names of its contributors
  18. * may be used to endorse or promote products derived from this software
  19. * without specific prior written permission.
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31. * SUCH DAMAGE.
  32. *
  33. * @(#)printf.c 8.1 (Berkeley) 6/11/93
  34. */
  35. /*
  36. * Scaled down version of printf(3).
  37. *
  38. * One additional format:
  39. *
  40. * The format %b is supported to decode error registers.
  41. * Its usage is:
  42. *
  43. * printf("reg=%b\n", regval, "<base><arg>*");
  44. *
  45. * where <base> is the output base expressed as a control character, e.g.
  46. * \10 gives octal; \20 gives hex. Each arg is a sequence of characters,
  47. * the first of which gives the bit number to be inspected (origin 1), and
  48. * the next characters (up to a control character, i.e. a character <= 32),
  49. * give the name of the register. Thus:
  50. *
  51. * printf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
  52. *
  53. * would produce output:
  54. *
  55. * reg=3<BITTWO,BITONE>
  56. */
  57. #include <sys/cdefs.h>
  58. #include <sys/types.h>
  59. /*
  60. * Note that stdarg.h and the ANSI style va_start macro is used for both
  61. * ANSI and traditional C compilers.
  62. */
  63. #define KERNEL
  64. #include <machine/stdarg.h>
  65. #undef KERNEL
  66. static void kprintn __P((u_long, int));
  67. void
  68. #if __STDC__
  69. printf(const char *fmt, ...)
  70. #else
  71. printf(fmt /* , va_alist */)
  72. char *fmt;
  73. #endif
  74. {
  75. register char *p;
  76. register int ch, n;
  77. unsigned long ul;
  78. int lflag, set;
  79. va_list ap;
  80. va_start(ap, fmt);
  81. for (;;) {
  82. while ((ch = *fmt++) != '%') {
  83. if (ch == '\0')
  84. return;
  85. putchar(ch);
  86. }
  87. lflag = 0;
  88. reswitch: switch (ch = *fmt++) {
  89. case 'l':
  90. lflag = 1;
  91. goto reswitch;
  92. case 'b':
  93. ul = va_arg(ap, int);
  94. p = va_arg(ap, char *);
  95. kprintn(ul, *p++);
  96. if (!ul)
  97. break;
  98. for (set = 0; n = *p++;) {
  99. if (ul & (1 << (n - 1))) {
  100. putchar(set ? ',' : '<');
  101. for (; (n = *p) > ' '; ++p)
  102. putchar(n);
  103. set = 1;
  104. } else
  105. for (; *p > ' '; ++p);
  106. }
  107. if (set)
  108. putchar('>');
  109. break;
  110. case 'c':
  111. ch = va_arg(ap, int);
  112. putchar(ch & 0x7f);
  113. break;
  114. case 's':
  115. p = va_arg(ap, char *);
  116. while (ch = *p++)
  117. putchar(ch);
  118. break;
  119. case 'd':
  120. ul = lflag ?
  121. va_arg(ap, long) : va_arg(ap, int);
  122. if ((long)ul < 0) {
  123. putchar('-');
  124. ul = -(long)ul;
  125. }
  126. kprintn(ul, 10);
  127. break;
  128. case 'o':
  129. ul = lflag ?
  130. va_arg(ap, u_long) : va_arg(ap, u_int);
  131. kprintn(ul, 8);
  132. break;
  133. case 'u':
  134. ul = lflag ?
  135. va_arg(ap, u_long) : va_arg(ap, u_int);
  136. kprintn(ul, 10);
  137. break;
  138. case 'x':
  139. ul = lflag ?
  140. va_arg(ap, u_long) : va_arg(ap, u_int);
  141. kprintn(ul, 16);
  142. break;
  143. default:
  144. putchar('%');
  145. if (lflag)
  146. putchar('l');
  147. putchar(ch);
  148. }
  149. }
  150. va_end(ap);
  151. }
  152. static void
  153. kprintn(ul, base)
  154. unsigned long ul;
  155. int base;
  156. {
  157. /* hold a long in base 8 */
  158. char *p, buf[(sizeof(long) * NBBY / 3) + 1];
  159. p = buf;
  160. do {
  161. *p++ = "0123456789abcdef"[ul % base];
  162. } while (ul /= base);
  163. do {
  164. putchar(*--p);
  165. } while (p > buf);
  166. }