PropWare  3.0.0.229
C++ objects and CMake build system for Parallax Propeller
scanner.h
Go to the documentation of this file.
1 
26 #pragma once
27 
28 #include <PropWare/PropWare.h>
32 
33 extern "C" {
34 extern const char *_scanf_getl (const char *str, int *dst, int base, unsigned width, int isSigned);
35 extern const char *_scanf_getf (const char *str, float *dst);
36 }
37 
38 namespace PropWare {
39 
43 class Scanner {
44  public:
50  } ErrorCode;
51 
52  public:
53  static const char DEFAULT_DELIMITER = '\n';
54  static const char WHITESPACE_CHARS[];
55 
56  public:
64  Scanner (ScanCapable &scanCapable, const Printer *printer = NULL)
65  : m_scanCapable(&scanCapable),
66  m_printer(printer) {
67  }
68 
72  char get_char () {
73  const char c = this->m_scanCapable->get_char();
74  if (NULL != this->m_printer)
75  this->m_printer->put_char(c);
76  return c;
77  }
78 
91  ErrorCode gets (char string[], int32_t length, const char delimiter = DEFAULT_DELIMITER) {
92  char *buf = string;
93  while (0 < --length) {
94  char ch = this->m_scanCapable->get_char();
95 
96  if (ch == 8 || ch == 127) {
97  if (buf > string) {
98  if (NULL != this->m_printer)
99  this->m_printer->puts("\010 \010");
100  ++length;
101  --buf;
102  }
103  length += 1;
104  continue;
105  }
106 
107  if (NULL != this->m_printer) {
108  this->m_printer->put_char(ch);
109 
110  if ('\n' == delimiter && '\r' == ch)
111  this->m_printer->put_char('\n');
112  }
113 
114  if (!ch || delimiter == ch || ('\n' == delimiter && '\r' == ch))
115  break;
116  else
117  *(buf++) = ch;
118  }
119  *buf = 0;
120 
121  return NO_ERROR;
122  }
123 
136  ErrorCode get_token (char string[], int32_t length, const char *delimiters = WHITESPACE_CHARS) {
137  char *buf = string;
138  while (0 < --length) {
139  const char ch = this->m_scanCapable->get_char();
140 
141  if (ch == 8 || ch == 127) {
142  if (buf > string) {
143  if (NULL != this->m_printer)
144  this->m_printer->puts("\010 \010");
145  ++length;
146  --buf;
147  }
148  length += 1;
149  continue;
150  }
151 
152  if (NULL != this->m_printer) {
153  this->m_printer->put_char(ch);
154  }
155 
156  if (!ch || strchr(delimiters, ch))
157  break;
158  else
159  *(buf++) = ch;
160  }
161  *buf = 0;
162 
163  return NO_ERROR;
164  }
165 
173  template<typename T>
175  this->get(c);
176  return *this;
177  }
178 
186  const ErrorCode get (char &c) {
187  ErrorCode err;
188  char userInput[2];
189  check_errors(this->get_token(userInput, sizeof(userInput)));
190  if ('\0' == c)
191  return BAD_INPUT;
192  else {
193  c = userInput[0];
194  return NO_ERROR;
195  }
196  }
197 
201  const ErrorCode get (uint8_t &x) {
202  ErrorCode err;
203  char userInput[32];
204  check_errors(this->get_token(userInput, sizeof(userInput)));
205  int tmp;
206  if (0 == _scanf_getl(userInput, &tmp, 10, 11, false))
207  return BAD_INPUT;
208  else {
209  x = static_cast<uint8_t>(tmp);
210  return NO_ERROR;
211  }
212  }
213 
214  template<size_t N>
215  const ErrorCode get (char (&buffer)[N]) {
216  return this->gets(buffer, N);
217  }
218 
222  const ErrorCode get (uint16_t &x) {
223  ErrorCode err;
224  char userInput[32];
225  check_errors(this->get_token(userInput, sizeof(userInput)));
226  int tmp;
227  if (0 == _scanf_getl(userInput, &tmp, 10, 11, false))
228  return BAD_INPUT;
229  else {
230  x = static_cast<uint16_t>(tmp);
231  return NO_ERROR;
232  }
233  }
234 
238  const ErrorCode get (int16_t &x) {
239  ErrorCode err;
240  char userInput[32];
241 
242  check_errors(this->get_token(userInput, sizeof(userInput)));
243  int tmp;
244  if (0 == _scanf_getl(userInput, &tmp, 10, 11, false))
245  return BAD_INPUT;
246  else {
247  x = static_cast<int16_t>(tmp);
248  return NO_ERROR;
249  }
250  }
251 
255  const ErrorCode get (uint32_t &x) {
256  ErrorCode err;
257  char userInput[32];
258  check_errors(this->get_token(userInput, sizeof(userInput)));
259  if (0 == _scanf_getl(userInput, (int *) &x, 10, 11, false))
260  return BAD_INPUT;
261  else
262  return NO_ERROR;
263  }
264 
268  const ErrorCode get (int32_t &x) {
269  ErrorCode err;
270  char userInput[32];
271  check_errors(this->get_token(userInput, sizeof(userInput)));
272  if (0 == _scanf_getl(userInput, &x, 10, 11, false))
273  return BAD_INPUT;
274  else
275  return NO_ERROR;
276  }
277 
281  const ErrorCode get (float &f) {
282  ErrorCode err;
283  char userInput[32];
284  check_errors(this->get_token(userInput, sizeof(userInput)));
285  if (0 == _scanf_getf(userInput, &f))
286  return BAD_INPUT;
287  else
288  return NO_ERROR;
289  }
290 
311  void input_prompt (const char prompt[], const char failureResponse[], char userInput[],
312  const size_t bufferLength, const Comparator<char> &comparator) {
313  do {
314  this->m_printer->puts(prompt);
315  this->gets(userInput, bufferLength);
316 
317  if (comparator.valid(userInput))
318  return;
319  else
320  this->m_printer->puts(failureResponse);
321  } while (1);
322  }
323 
343  template<typename T>
344  void input_prompt (const char prompt[], const char failureResponse[], T *userInput,
345  const Comparator<T> &comparator) {
346  const T original = *userInput;
347  ErrorCode err;
348  do {
349  this->m_printer->puts(prompt);
350  err = this->get(*userInput);
351  if (NO_ERROR == err && comparator.valid(userInput))
352  return;
353 
354  this->m_printer->puts(failureResponse);
355  *userInput = original;
356  } while (1);
357  }
358 
359  private:
360  ScanCapable *m_scanCapable;
361  const Printer *m_printer;
362 };
363 
364 }
365 
366 #ifndef __PROPELLER_COG__
367 extern PropWare::Scanner pwIn;
368 #endif
PropWare::Scanner::get
const ErrorCode get(char &c)
Extract formatted input.
Definition: scanner.h:186
PropWare::Scanner::END_ERROR
@ END_ERROR
Definition: scanner.h:49
printer.h
PropWare::Scanner::input_prompt
void input_prompt(const char prompt[], const char failureResponse[], T *userInput, const Comparator< T > &comparator)
Prompt the user for input and store the value only if it is sanitized.
Definition: scanner.h:344
PropWare::Scanner
Interface for all classes capable of scanning.
Definition: scanner.h:43
PropWare::ScanCapable::get_char
virtual char get_char()=0
Read and return a single character. Whether the method is blocking or not depends entirely on the imp...
PropWare::Scanner::get
const ErrorCode get(int16_t &x)
Definition: scanner.h:238
PropWare::ScanCapable
Interface for all classes capable of printing.
Definition: scancapable.h:38
PropWare::Scanner::ErrorCode
ErrorCode
Definition: scanner.h:45
PropWare::Scanner::Scanner
Scanner(ScanCapable &scanCapable, const Printer *printer=NULL)
Construct a Scanner instance and control whether or not received characters are echoed back via the *...
Definition: scanner.h:64
PropWare::Scanner::get
const ErrorCode get(float &f)
Definition: scanner.h:281
PropWare::Scanner::get_char
char get_char()
Definition: scanner.h:72
PropWare::Comparator::valid
virtual bool valid(const T *lhs) const =0
Determines if the given argument is valid.
PropWare::Scanner::BEG_ERROR
@ BEG_ERROR
Definition: scanner.h:47
PropWare::Scanner::input_prompt
void input_prompt(const char prompt[], const char failureResponse[], char userInput[], const size_t bufferLength, const Comparator< char > &comparator)
Prompt the user for input and store the value only if it is sanitized.
Definition: scanner.h:311
PropWare.h
PropWare::Scanner::get
const ErrorCode get(uint16_t &x)
Definition: scanner.h:222
string
void string(char *str)
Display a character string on the oLED display.
Definition: oled_string.c:7
x
int x
Definition: 07 Box and Lines.c:13
PropWare::Scanner::gets
ErrorCode gets(char string[], int32_t length, const char delimiter=DEFAULT_DELIMITER)
Read words from the bus until the delimiter is received.
Definition: scanner.h:91
PropWare::Scanner::get
const ErrorCode get(uint32_t &x)
Definition: scanner.h:255
PropWare::Scanner::get
const ErrorCode get(int32_t &x)
Definition: scanner.h:268
PropWare::Scanner::operator>>
Scanner & operator>>(T &c)
Extract formatted input.
Definition: scanner.h:174
comparator.h
PropWare::Scanner::get_token
ErrorCode get_token(char string[], int32_t length, const char *delimiters=WHITESPACE_CHARS)
Read characters from the bus until the any one of the given delimiters is received.
Definition: scanner.h:136
PropWare::Comparator< char >
PropWare::Scanner::NO_ERROR
@ NO_ERROR
Definition: scanner.h:46
PropWare::Scanner::WHITESPACE_CHARS
static const char WHITESPACE_CHARS[]
Set of all standard whitespace.
Definition: scanner.h:54
PropWare::Printer::puts
void puts(const char string[]) const
Send a null-terminated character array.
Definition: printer.h:188
PropWare::Scanner::get
const ErrorCode get(uint8_t &x)
Definition: scanner.h:201
PropWare::Printer
Container class that has formatting methods for human-readable output. This class can be constructed ...
Definition: printer.h:76
PropWare
Generic definitions and functions for the Parallax Propeller.
Definition: runnable.h:33
PropWare::Printer::put_char
void put_char(const char c) const
Print a single character.
Definition: printer.h:175
PropWare::Scanner::BAD_INPUT
@ BAD_INPUT
Definition: scanner.h:48
scancapable.h