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