nonstdio.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /*
  2. * Copyright (C) 1996-2005 Paul Mackerras.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * as published by the Free Software Foundation; either version
  7. * 2 of the License, or (at your option) any later version.
  8. */
  9. #include <linux/string.h>
  10. #include <asm/udbg.h>
  11. #include <asm/time.h>
  12. #include "nonstdio.h"
  13. static bool paginating, paginate_skipping;
  14. static unsigned long paginate_lpp; /* Lines Per Page */
  15. static unsigned long paginate_pos;
  16. void xmon_start_pagination(void)
  17. {
  18. paginating = true;
  19. paginate_skipping = false;
  20. paginate_pos = 0;
  21. }
  22. void xmon_end_pagination(void)
  23. {
  24. paginating = false;
  25. }
  26. void xmon_set_pagination_lpp(unsigned long lpp)
  27. {
  28. paginate_lpp = lpp;
  29. }
  30. static int xmon_readchar(void)
  31. {
  32. if (udbg_getc)
  33. return udbg_getc();
  34. return -1;
  35. }
  36. static int xmon_write(const char *ptr, int nb)
  37. {
  38. int rv = 0;
  39. const char *p = ptr, *q;
  40. const char msg[] = "[Hit a key (a:all, q:truncate, any:next page)]";
  41. if (nb <= 0)
  42. return rv;
  43. if (paginating && paginate_skipping)
  44. return nb;
  45. if (paginate_lpp) {
  46. while (paginating && (q = strchr(p, '\n'))) {
  47. rv += udbg_write(p, q - p + 1);
  48. p = q + 1;
  49. paginate_pos++;
  50. if (paginate_pos >= paginate_lpp) {
  51. udbg_write(msg, strlen(msg));
  52. switch (xmon_readchar()) {
  53. case 'a':
  54. paginating = false;
  55. break;
  56. case 'q':
  57. paginate_skipping = true;
  58. break;
  59. default:
  60. /* nothing */
  61. break;
  62. }
  63. paginate_pos = 0;
  64. udbg_write("\r\n", 2);
  65. if (paginate_skipping)
  66. return nb;
  67. }
  68. }
  69. }
  70. return rv + udbg_write(p, nb - (p - ptr));
  71. }
  72. int xmon_putchar(int c)
  73. {
  74. char ch = c;
  75. if (c == '\n')
  76. xmon_putchar('\r');
  77. return xmon_write(&ch, 1) == 1? c: -1;
  78. }
  79. static char line[256];
  80. static char *lineptr;
  81. static int lineleft;
  82. static int xmon_getchar(void)
  83. {
  84. int c;
  85. if (lineleft == 0) {
  86. lineptr = line;
  87. for (;;) {
  88. c = xmon_readchar();
  89. if (c == -1 || c == 4)
  90. break;
  91. if (c == '\r' || c == '\n') {
  92. *lineptr++ = '\n';
  93. xmon_putchar('\n');
  94. break;
  95. }
  96. switch (c) {
  97. case 0177:
  98. case '\b':
  99. if (lineptr > line) {
  100. xmon_putchar('\b');
  101. xmon_putchar(' ');
  102. xmon_putchar('\b');
  103. --lineptr;
  104. }
  105. break;
  106. case 'U' & 0x1F:
  107. while (lineptr > line) {
  108. xmon_putchar('\b');
  109. xmon_putchar(' ');
  110. xmon_putchar('\b');
  111. --lineptr;
  112. }
  113. break;
  114. default:
  115. if (lineptr >= &line[sizeof(line) - 1])
  116. xmon_putchar('\a');
  117. else {
  118. xmon_putchar(c);
  119. *lineptr++ = c;
  120. }
  121. }
  122. }
  123. lineleft = lineptr - line;
  124. lineptr = line;
  125. }
  126. if (lineleft == 0)
  127. return -1;
  128. --lineleft;
  129. return *lineptr++;
  130. }
  131. char *xmon_gets(char *str, int nb)
  132. {
  133. char *p;
  134. int c;
  135. for (p = str; p < str + nb - 1; ) {
  136. c = xmon_getchar();
  137. if (c == -1) {
  138. if (p == str)
  139. return NULL;
  140. break;
  141. }
  142. *p++ = c;
  143. if (c == '\n')
  144. break;
  145. }
  146. *p = 0;
  147. return str;
  148. }
  149. void xmon_printf(const char *format, ...)
  150. {
  151. va_list args;
  152. static char xmon_outbuf[1024];
  153. int rc, n;
  154. va_start(args, format);
  155. n = vsnprintf(xmon_outbuf, sizeof(xmon_outbuf), format, args);
  156. va_end(args);
  157. rc = xmon_write(xmon_outbuf, n);
  158. if (n && rc == 0) {
  159. /* No udbg hooks, fallback to printk() - dangerous */
  160. printk("%s", xmon_outbuf);
  161. }
  162. }
  163. void xmon_puts(const char *str)
  164. {
  165. xmon_write(str, strlen(str));
  166. }