nonstdio.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  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/time.h>
  11. #include "nonstdio.h"
  12. int xmon_putchar(int c)
  13. {
  14. char ch = c;
  15. if (c == '\n')
  16. xmon_putchar('\r');
  17. return xmon_write(&ch, 1) == 1? c: -1;
  18. }
  19. static char line[256];
  20. static char *lineptr;
  21. static int lineleft;
  22. int xmon_expect(const char *str, unsigned long timeout)
  23. {
  24. int c;
  25. unsigned long t0;
  26. /* assume 25MHz default timebase if tb_ticks_per_sec not set yet */
  27. timeout *= tb_ticks_per_sec? tb_ticks_per_sec: 25000000;
  28. t0 = get_tbl();
  29. do {
  30. lineptr = line;
  31. for (;;) {
  32. c = xmon_read_poll();
  33. if (c == -1) {
  34. if (get_tbl() - t0 > timeout)
  35. return 0;
  36. continue;
  37. }
  38. if (c == '\n')
  39. break;
  40. if (c != '\r' && lineptr < &line[sizeof(line) - 1])
  41. *lineptr++ = c;
  42. }
  43. *lineptr = 0;
  44. } while (strstr(line, str) == NULL);
  45. return 1;
  46. }
  47. int xmon_getchar(void)
  48. {
  49. int c;
  50. if (lineleft == 0) {
  51. lineptr = line;
  52. for (;;) {
  53. c = xmon_readchar();
  54. if (c == -1 || c == 4)
  55. break;
  56. if (c == '\r' || c == '\n') {
  57. *lineptr++ = '\n';
  58. xmon_putchar('\n');
  59. break;
  60. }
  61. switch (c) {
  62. case 0177:
  63. case '\b':
  64. if (lineptr > line) {
  65. xmon_putchar('\b');
  66. xmon_putchar(' ');
  67. xmon_putchar('\b');
  68. --lineptr;
  69. }
  70. break;
  71. case 'U' & 0x1F:
  72. while (lineptr > line) {
  73. xmon_putchar('\b');
  74. xmon_putchar(' ');
  75. xmon_putchar('\b');
  76. --lineptr;
  77. }
  78. break;
  79. default:
  80. if (lineptr >= &line[sizeof(line) - 1])
  81. xmon_putchar('\a');
  82. else {
  83. xmon_putchar(c);
  84. *lineptr++ = c;
  85. }
  86. }
  87. }
  88. lineleft = lineptr - line;
  89. lineptr = line;
  90. }
  91. if (lineleft == 0)
  92. return -1;
  93. --lineleft;
  94. return *lineptr++;
  95. }
  96. char *xmon_gets(char *str, int nb)
  97. {
  98. char *p;
  99. int c;
  100. for (p = str; p < str + nb - 1; ) {
  101. c = xmon_getchar();
  102. if (c == -1) {
  103. if (p == str)
  104. return NULL;
  105. break;
  106. }
  107. *p++ = c;
  108. if (c == '\n')
  109. break;
  110. }
  111. *p = 0;
  112. return str;
  113. }
  114. void xmon_printf(const char *format, ...)
  115. {
  116. va_list args;
  117. int n;
  118. static char xmon_outbuf[1024];
  119. va_start(args, format);
  120. n = vsnprintf(xmon_outbuf, sizeof(xmon_outbuf), format, args);
  121. va_end(args);
  122. xmon_write(xmon_outbuf, n);
  123. }
  124. void xmon_puts(const char *str)
  125. {
  126. xmon_write(str, strlen(str));
  127. }