|
|
|
|
@ -2314,37 +2314,48 @@ static void shell_init_connection(void){
|
|
|
|
|
|
|
|
|
|
bool global_abort = false;
|
|
|
|
|
|
|
|
|
|
static const VNAShellCommand *VNAShell_parceLine(char *line){
|
|
|
|
|
// Parse and execute line
|
|
|
|
|
char *lp = line, *ep;
|
|
|
|
|
shell_nargs = 0;
|
|
|
|
|
shell_args[0] = line; // shell_args[0] is used in error message, must be initialized
|
|
|
|
|
// DEBUG_LOG(0, lp); // debug console log
|
|
|
|
|
while (*lp != 0) {
|
|
|
|
|
// Skipping white space and tabs at string begin.
|
|
|
|
|
while (*lp == ' ' || *lp == '\t') lp++;
|
|
|
|
|
// If an argument starts with a double quote then its delimiter is another quote, else
|
|
|
|
|
// delimiter is white space.
|
|
|
|
|
ep = (*lp == '"') ? strpbrk(++lp, "\"") : strpbrk(lp, " \t");
|
|
|
|
|
// Store in args string
|
|
|
|
|
shell_args[shell_nargs++] = lp;
|
|
|
|
|
// Stop, end of input string
|
|
|
|
|
if ((lp = ep) == NULL) break;
|
|
|
|
|
// Argument limits check
|
|
|
|
|
if (shell_nargs > VNA_SHELL_MAX_ARGUMENTS) {
|
|
|
|
|
shell_printf("too many arguments, max " define_to_STR(VNA_SHELL_MAX_ARGUMENTS) "" VNA_SHELL_NEWLINE_STR);
|
|
|
|
|
return NULL;
|
|
|
|
|
static inline char* vna_strpbrk(char *s1, const char *s2) {
|
|
|
|
|
do {
|
|
|
|
|
const char *s = s2;
|
|
|
|
|
do {
|
|
|
|
|
if (*s == *s1) return s1;
|
|
|
|
|
s++;
|
|
|
|
|
} while (*s);
|
|
|
|
|
s1++;
|
|
|
|
|
} while(*s1);
|
|
|
|
|
return s1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Split line by arguments, return arguments count
|
|
|
|
|
*/
|
|
|
|
|
int parse_line(char *line, char* args[], int max_cnt) {
|
|
|
|
|
char *lp = line, c;
|
|
|
|
|
const char *brk;
|
|
|
|
|
uint16_t nargs = 0;
|
|
|
|
|
while ((c = *lp) != 0) { // While not end
|
|
|
|
|
if (c != ' ' && c != '\t') { // Skipping white space and tabs.
|
|
|
|
|
if (c == '"') {lp++; brk = "\""; } // string end is next quote or end
|
|
|
|
|
else { brk = " \t";} // string end is tab or space or end
|
|
|
|
|
if (nargs < max_cnt) args[nargs] = lp; // Put pointer in args buffer (if possible)
|
|
|
|
|
nargs++; // Substring count
|
|
|
|
|
lp = vna_strpbrk(lp, brk); // search end
|
|
|
|
|
if (*lp == 0) break; // Stop, end of input string
|
|
|
|
|
*lp = 0; // Set zero at the end of substring
|
|
|
|
|
}
|
|
|
|
|
// Set zero at the end of string and continue check
|
|
|
|
|
*lp++ = 0;
|
|
|
|
|
lp++;
|
|
|
|
|
}
|
|
|
|
|
if (shell_nargs){
|
|
|
|
|
if (shell_args[0][0] == '.') {
|
|
|
|
|
global_abort = true;
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
global_abort = false;
|
|
|
|
|
return nargs;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const VNAShellCommand *VNAShell_parceLine(char *line){
|
|
|
|
|
// Parse and execute line
|
|
|
|
|
shell_nargs = parse_line(line, shell_args, ARRAY_COUNT(shell_args));
|
|
|
|
|
if (shell_nargs > ARRAY_COUNT(shell_args)) {
|
|
|
|
|
shell_printf("too many arguments, max " define_to_STR(VNA_SHELL_MAX_ARGUMENTS) "" VNA_SHELL_NEWLINE_STR);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
if (shell_nargs > 0) {
|
|
|
|
|
const VNAShellCommand *scp;
|
|
|
|
|
for (scp = commands; scp->sc_name != NULL; scp++)
|
|
|
|
|
if (get_str_index(scp->sc_name, shell_args[0]) == 0)
|
|
|
|
|
@ -2417,6 +2428,15 @@ static void VNAShell_executeLine(char *line)
|
|
|
|
|
shell_printf("%s?" VNA_SHELL_NEWLINE_STR, shell_args[0]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void shell_executeCMDLine(char *line) {
|
|
|
|
|
// Disable shell output (not allow shell_printf write, but not block other output!!)
|
|
|
|
|
shell_stream = NULL;
|
|
|
|
|
const VNAShellCommand *scp = VNAShell_parceLine(line);
|
|
|
|
|
if (scp && (scp->flags & CMD_RUN_IN_LOAD))
|
|
|
|
|
scp->sc_function(shell_nargs - 1, &shell_args[1]);
|
|
|
|
|
PREPARE_STREAM;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef __SD_CARD_LOAD__
|
|
|
|
|
#ifndef __USE_SD_CARD__
|
|
|
|
|
#error "Need enable SD card support __USE_SD_CARD__ in nanovna.h, for use ENABLE_SD_CARD_CMD"
|
|
|
|
|
|