/** * @brief Reads a whole line from the input channel. * @note Input chars are echoed on the same stream object with the * following exceptions: * - DEL and BS are echoed as BS-SPACE-BS. * - CR is echoed as CR-LF. * - 0x4 is echoed as "^D". * - Other values below 0x20 are not echoed. * . * * @param[in] chp pointer to a @p BaseSequentialStream object * @param[in] line pointer to the line buffer * @param[in] size buffer maximum length * @return The operation status. * @retval true the channel was reset or CTRL-D pressed. * @retval false operation successful. * * @api */ bool shellGetLine(BaseSequentialStream *chp, char *line, unsigned size) { char *p = line; while (true) { char c; if (streamRead(chp, (uint8_t *)&c, 1) == 0) return true; if (c == 4) { chprintf(chp, "^D"); return true; } if ((c == 8) || (c == 127)) { if (p != line) { streamPut(chp, c); streamPut(chp, 0x20); streamPut(chp, c); p--; } continue; } if (c == '\r') { chprintf(chp, "\r\n"); *p = 0; return false; } if (c < 0x20) continue; if (p < line + size - 1) { streamPut(chp, c); *p++ = (char)c; } } }
/** * @brief Prints a decimal unsigned number. * * @param[in] n the number to be printed * * @api */ void test_printn(uint32_t n) { char buf[16], *p; if (!n) streamPut(test_chp, '0'); else { p = buf; while (n) *p++ = (n % 10) + '0', n /= 10; while (p > buf) streamPut(test_chp, *--p); } }
static void print_line(void) { unsigned i; for (i = 0; i < 76; i++) streamPut(test_chp, '-'); streamWrite(test_chp, (const uint8_t *)"\r\n", 2); }
/** * @brief System formatted output function. * @details This function implements a minimal @p vprintf()-like functionality * with output on a @p BaseSequentialStream. * The general parameters format is: %[-][width|*][.precision|*][l|L]p. * The following parameter types (p) are supported: * - <b>x</b> hexadecimal integer. * - <b>X</b> hexadecimal long. * - <b>o</b> octal integer. * - <b>O</b> octal long. * - <b>d</b> decimal signed integer. * - <b>D</b> decimal signed long. * - <b>u</b> decimal unsigned integer. * - <b>U</b> decimal unsigned long. * - <b>c</b> character. * - <b>s</b> string. * . * * @param[in] chp pointer to a @p BaseSequentialStream implementing object * @param[in] fmt formatting string * @param[in] ap list of parameters * @return The number of bytes that would have been * written to @p chp if no stream error occurs * * @api */ int chvprintf(BaseSequentialStream *chp, const char *fmt, va_list ap) { char *p, *s, c, filler; int i, precision, width; int n = 0; bool is_long, left_align; long l; #if CHPRINTF_USE_FLOAT float f; char tmpbuf[2*MAX_FILLER + 1]; #else char tmpbuf[MAX_FILLER + 1]; #endif while (true) { c = *fmt++; if (c == 0) return n; if (c != '%') { streamPut(chp, (uint8_t)c); n++; continue; } p = tmpbuf; s = tmpbuf; left_align = FALSE; if (*fmt == '-') { fmt++; left_align = TRUE; } filler = ' '; if (*fmt == '0') { fmt++; filler = '0'; } width = 0; while (TRUE) { c = *fmt++; if (c >= '0' && c <= '9') c -= '0'; else if (c == '*') c = va_arg(ap, int); else break; width = width * 10 + c; } precision = 0; if (c == '.') { while (TRUE) { c = *fmt++; if (c >= '0' && c <= '9') c -= '0'; else if (c == '*') c = va_arg(ap, int); else break; precision *= 10; precision += c; } }
/** * @brief Reads a whole line from the input channel. * @note Input chars are echoed on the same stream object with the * following exceptions: * - DEL and BS are echoed as BS-SPACE-BS. * - CR is echoed as CR-LF. * - 0x4 is echoed as "^D". * - Other values below 0x20 are not echoed. * . * * @param[in] chp pointer to a @p BaseSequentialStream object * @param[in] line pointer to the line buffer * @param[in] size buffer maximum length * @return The operation status. * @retval true the channel was reset or CTRL-D pressed. * @retval false operation successful. * * @api */ bool shellGetLine(BaseSequentialStream *chp, char *line, unsigned size) { char *p = line; while (true) { char c; if (streamRead(chp, (uint8_t *)&c, 1) == 0) return true; #if (SHELL_CMD_EXIT_ENABLED == TRUE) && !defined(_CHIBIOS_NIL_) if (c == 4) { chprintf(chp, "^D"); return true; } #endif if ((c == 8) || (c == 127)) { if (p != line) { streamPut(chp, c); streamPut(chp, 0x20); streamPut(chp, c); p--; } continue; } if (c == '\r') { chprintf(chp, "\r\n"); *p = 0; return false; } if (c < 0x20) continue; if (p < line + size - 1) { streamPut(chp, c); *p++ = (char)c; } } }
/** * @brief Reads a whole line from the input channel. * @note Input chars are echoed on the same stream object with the * following exceptions: * - DEL and BS are echoed as BS-SPACE-BS. * - CR is echoed as CR-LF. * - 0x4 is echoed as "^D". * - Other values below 0x20 are not echoed. * . * * @param[in] scfg pointer to a @p ShellConfig object * @param[in] line pointer to the line buffer * @param[in] size buffer maximum length * @param[in] shp pointer to a @p ShellHistory object or NULL * @return The operation status. * @retval true the channel was reset or CTRL-D pressed. * @retval false operation successful. * * @api */ bool shellGetLine(ShellConfig *scfg, char *line, unsigned size, ShellHistory *shp) { char *p = line; BaseSequentialStream *chp = scfg->sc_channel; #if SHELL_USE_ESC_SEQ == TRUE bool escape = false; bool bracket = false; #endif #if SHELL_USE_HISTORY != TRUE (void) shp; #endif while (true) { char c; if (streamRead(chp, (uint8_t *)&c, 1) == 0) return true; #if SHELL_USE_ESC_SEQ == TRUE if (c == 27) { escape = true; continue; } if (escape) { escape = false; if (c == '[') { escape = true; bracket = true; continue; } if (bracket) { bracket = false; #if SHELL_USE_HISTORY == TRUE if (c == 'A') { int len = get_history(shp, line, SHELL_HIST_DIR_BK); if (len > 0) { _shell_reset_cur(chp); _shell_clr_line(chp); chprintf(chp, "%s", line); p = line + len; } continue; } if (c == 'B') { int len = get_history(shp, line, SHELL_HIST_DIR_FW); if (len == 0) *line = 0; if (len >= 0) { _shell_reset_cur(chp); _shell_clr_line(chp); chprintf(chp, "%s", line); p = line + len; } continue; } #endif } continue; } #endif #if (SHELL_CMD_EXIT_ENABLED == TRUE) && !defined(_CHIBIOS_NIL_) if (c == 4) { chprintf(chp, "^D"); return true; } #endif if ((c == 8) || (c == 127)) { if (p != line) { streamPut(chp, 0x08); streamPut(chp, 0x20); streamPut(chp, 0x08); p--; } continue; } if (c == '\r') { chprintf(chp, SHELL_NEWLINE_STR); #if SHELL_USE_HISTORY == TRUE save_history(shp, line, p - line); #endif *p = 0; return false; } #if SHELL_USE_COMPLETION == TRUE if (c == '\t') { if (p < line + size - 1) { *p = 0; get_completions(scfg, line); int len = process_completions(scfg, line, p - line, size); if (len > 0) { write_completions(scfg, line, p - line); p = line + len; } } continue; } #endif #if SHELL_USE_HISTORY == TRUE if (c == 14) { int len = get_history(shp, line, SHELL_HIST_DIR_FW); if (len == 0) *line = 0; if (len >= 0) { _shell_reset_cur(chp); _shell_clr_line(chp); chprintf(chp, "%s", line); p = line + len; } continue; } if (c == 16) { int len = get_history(shp, line, SHELL_HIST_DIR_BK); if (len > 0) { _shell_reset_cur(chp); _shell_clr_line(chp); chprintf(chp, "%s", line); p = line + len; } continue; } #endif if (c < 0x20) continue; if (p < line + size - 1) { streamPut(chp, c); *p++ = (char)c; } } }
StringBuilderImpl<Allocator>& operator<<(StringBuilderImpl<Allocator>& os, Nanoseconds ns) { return streamPut(os, ns); }
StringBuilderImpl<Allocator>& operator<<(StringBuilderImpl<Allocator>& os, Milliseconds ms) { return streamPut(os, ms); }
static void print_tokens(void) { char *cp = test_tokens_buffer; while (cp < test_tokp) streamPut(test_chp, *cp++); }
std::ostream& operator<<(std::ostream& os, Seconds s) { return streamPut(os, s); }
std::ostream& operator<<(std::ostream& os, Milliseconds ms) { return streamPut(os, ms); }
std::ostream& operator<<(std::ostream& os, Microseconds us) { return streamPut(os, us); }
std::ostream& operator<<(std::ostream& os, Nanoseconds ns) { return streamPut(os, ns); }
StringBuilderImpl<Allocator>& operator<<(StringBuilderImpl<Allocator>& os, Hours h) { return streamPut(os, h); }
StringBuilderImpl<Allocator>& operator<<(StringBuilderImpl<Allocator>& os, Minutes m) { return streamPut(os, m); }
StringBuilderImpl<Allocator>& operator<<(StringBuilderImpl<Allocator>& os, Seconds s) { return streamPut(os, s); }
/** * @brief Prints a line without final end-of-line. * * @param[in] msgp the message * * @api */ void test_print(const char *msgp) { while (*msgp) streamPut(test_chp, *msgp++); }
std::ostream& operator<<(std::ostream& os, Minutes m) { return streamPut(os, m); }
std::ostream& operator<<(std::ostream& os, Hours h) { return streamPut(os, h); }
StringBuilderImpl<Allocator>& operator<<(StringBuilderImpl<Allocator>& os, Microseconds us) { return streamPut(os, us); }