-#ifdef __SHARC__
-#pragma nosharc
-#endif
-
-#include <ros/error.h>
+#include <error.h>
#include <stdio.h>
+#include <assert.h>
+#include <atomic.h>
-#define BUFLEN 1024
-// zra: used only by monitor.c.
-static char RACY (RO NT buf)[BUFLEN];
-
-char *
-readline(const char *prompt)
+int readline(char *buf, size_t buf_l, const char *prompt, ...)
{
- int i, c, echoing;
+ static spinlock_t readline_lock = SPINLOCK_INITIALIZER_IRQSAVE;
+ int i, c, echoing, retval;
+ va_list ap;
+ spin_lock_irqsave(&readline_lock);
+ va_start(ap, prompt);
if (prompt != NULL)
- cprintf("%s", prompt);
+ vcprintf(prompt, ap);
+ va_end(ap);
i = 0;
echoing = iscons(0);
while (1) {
c = getchar();
if (c < 0) {
- cprintf("read error: %e\n", c);
- return NULL;
- } else if (c >= ' ' && i < BUFLEN-1) {
+ printk("read error: %d\n", c);
+ retval = i;
+ break;
+ } else if (c == '\b' || c == 0x7f) {
+ if (i > 0) {
+ if (echoing)
+ cputchar(c);
+ i--;
+ }
+ continue;
+ } else if (c == '\n' || c == '\r') {
+ /* sending a \n regardless, since the serial port gives us a \r for
+ * carriage returns. (probably won't get a \r anymore) */
if (echoing)
- cputchar(c);
+ cputchar('\n');
+ assert(i <= buf_l - 1); /* never write to buf_l - 1 til the end */
buf[i++] = c;
- } else if (c == '\b' && i > 0) {
+ retval = i;
+ break;
+ } else if (c >= ' ' && i < buf_l - 1) {
if (echoing)
cputchar(c);
- i--;
- } else if (c == '\n' || c == '\r') {
- if (echoing)
- cputchar(c);
- buf[i] = 0;
- return buf;
+ buf[i++] = c;
}
}
+ spin_unlock_irqsave(&readline_lock);
+ return retval;
}