int16_t parse_cmd_goto(char *cmd, char *output, uint16_t len) { uint8_t gotoline = 0; char line[ECMD_INPUTBUF_LENGTH]; if (current_script.handle == NULL) { return ECMD_FINAL(snprintf_P(output, len, PSTR("no script"))); } sscanf_P(cmd, PSTR("%hhu"), &gotoline); SCRIPTDEBUG("current %u goto line %u\n", current_script.linenumber, gotoline); if (gotoline < current_script.linenumber) { SCRIPTDEBUG("seek to 0\n"); vfs_fseek(current_script.handle, 0, SEEK_SET); current_script.linenumber = 0; current_script.filepointer = 0; } while ((current_script.linenumber != gotoline) && (current_script.linenumber < ECMD_SCRIPT_MAXLINES)) { SCRIPTDEBUG("seeking: current %i goto line %i\n", current_script.linenumber, gotoline); if (readline(line) == 0) { SCRIPTDEBUG("leaving\n"); break; } } return ECMD_FINAL_OK; }
int16_t parse_cmd_call(char *cmd, char *output, uint16_t len) { char filename[10]; char line[ECMD_INPUTBUF_LENGTH]; uint8_t lsize = 0; uint8_t run = 0; vfs_size_t filesize; sscanf_P(cmd, PSTR("%s"), &filename); // should check for ".es" extention! current_script.handle = vfs_open(filename); if (current_script.handle == NULL) { SCRIPTDEBUG("%s not found\n", filename); return ECMD_FINAL(1); } filesize = vfs_size(current_script.handle); SCRIPTDEBUG("start %s from %i bytes\n", filename, filesize); current_script.linenumber = 0; current_script.filepointer = 0; // open file as long it is open, we have not reached max lines and // not the end of the file as we know it while ((current_script.handle != NULL) && (run++ < ECMD_SCRIPT_MAXLINES) && (filesize > current_script.filepointer)) { lsize = readline(line); SCRIPTDEBUG("(linenr:%i, pos:%i, bufsize:%i)\n", current_script.linenumber, current_script.filepointer, lsize); SCRIPTDEBUG("exec: %s\n", line); if (lsize != 0) { ecmd_parse_command(line, output, len); } } SCRIPTDEBUG("end\n"); parse_cmd_exit(cmd, output, len); return ECMD_FINAL_OK; }
int16_t parse_cmd_wait(char *cmd, char *output, uint16_t len) { uint16_t delay; sscanf_P(cmd, PSTR("%u"), &delay); SCRIPTDEBUG("wait %ims\n", delay); _delay_ms(delay); return ECMD_FINAL_OK; }
// read a line from script static uint8_t readline(char *buf) { vfs_size_t len = vfs_fgets(current_script.handle, buf, current_script.filepointer); SCRIPTDEBUG("readline: %s\n", buf); if (len == -1 || len >= ECMD_INPUTBUF_LENGTH) { return 0; } current_script.filepointer += len + 1; current_script.linenumber++; return (uint8_t) len; }
// read a line from file "handle", stored in "line", starting at "pos" static vfs_size_t vfs_fgets(struct vfs_file_handle_t *handle, char *line, vfs_size_t pos) { vfs_fseek(handle, pos, SEEK_SET); vfs_size_t readlen = vfs_read(handle, line, ECMD_INPUTBUF_LENGTH - 1); line[ECMD_INPUTBUF_LENGTH - 1] = 0; SCRIPTDEBUG("fgets (%i) : %s\n", readlen, line); vfs_size_t i = 0; while (i < readlen && line[i] != 0x0a) { i++; } line[i] = 0; return i; // size until linebreak }
int16_t ecmd_script_init_run(void) { #ifdef ECMD_SCRIPT_AUTOSTART_SUPPORT if (ecmd_script_autorun_done == 1) { return ECMD_FINAL_OK; } ecmd_script_autorun_done = 1; char cmd[] = CONF_ECMD_SCRIPT_AUTOSTART_NAME; char output[ECMD_SCRIPT_VARIABLE_LENGTH]; SCRIPTDEBUG("auto run: %s\n", cmd); return parse_cmd_call(cmd, output, sizeof(cmd)); #else return ECMD_FINAL_OK; #endif }
int16_t parse_cmd_if(char *cmd, char *output, uint16_t len) { char cmpcmd[ECMD_SCRIPT_COMPARATOR_LENGTH]; char comparator[3]; char konst[ECMD_SCRIPT_COMPARATOR_LENGTH]; // char cmd[]= "if ( whm != 00:01 ) then exit"; uint8_t success = 0; // default false sscanf_P(cmd, PSTR("( %s %s %s ) then "), &cmpcmd, &comparator, &konst); char *ecmd = strstr_P(cmd, PSTR("then")); if (ecmd == NULL) { SCRIPTDEBUG("cmd not found\n"); return ECMD_FINAL(1); } ecmd += 5; SCRIPTDEBUG("ecmd: %s\n", ecmd); SCRIPTDEBUG("cmpcmd: %s\n", cmpcmd); SCRIPTDEBUG("comparator: %s\n", comparator); SCRIPTDEBUG("konst: %s\n", konst); // if cmpcmd starts with % it is a variable if (cmpcmd[0] == '%') { uint8_t varpos = cmpcmd[1] - '0'; // get variable and set it to output strcpy(output, vars[varpos].value); } else { // if not, it is a command // execute cmp! and check output if (!ecmd_parse_command(cmpcmd, output, len)) { SCRIPTDEBUG("compare wrong\n"); return ECMD_FINAL(1); } } SCRIPTDEBUG("cmp '%s' %s '%s'\n", output, comparator, konst); // check comparator if (strcmp(comparator, STR_EQUALS) == 0) { SCRIPTDEBUG("try " STR_EQUALS "\n"); success = (strcmp(output, konst) == 0); } else if (strcmp(comparator, STR_NOTEQUALS) == 0) { SCRIPTDEBUG("try " STR_NOTEQUALS "\n"); success = (strcmp(output, konst) != 0); } else { uint16_t outputvalue = atoi(output); uint16_t konstvalue = atoi(konst); // debug_printf("cmp atoi: %i %s %i\n", outputvalue, comparator, konstvalue); if (strcmp(comparator, OK) == 0) { SCRIPTDEBUG("try " OK "\n"); success = outputvalue; } else if (strcmp(comparator, NOT) == 0) { SCRIPTDEBUG("try " NOT "\n"); success = (outputvalue != 0); } else if (strcmp(comparator, EQUALS) == 0) { SCRIPTDEBUG("try " EQUALS "\n"); success = (outputvalue == konstvalue); } else if (strcmp(comparator, NOTEQUALS) == 0) { SCRIPTDEBUG("try " NOTEQUALS "\n"); success = (outputvalue != konstvalue); } else if (strcmp(comparator, GREATER) == 0) { SCRIPTDEBUG("try " GREATER "\n"); success = (outputvalue > konstvalue); } else if (strcmp(comparator, LOWER) == 0) { SCRIPTDEBUG("try " LOWER "\n"); success = (outputvalue < konstvalue); } else if (strcmp(comparator, GREATEREQUALS) == 0) { SCRIPTDEBUG("try " GREATEREQUALS "\n"); success = (outputvalue >= konstvalue); } else if (strcmp(comparator, LOWEREQUALS) == 0) { SCRIPTDEBUG("try " LOWEREQUALS "\n"); success = (outputvalue <= konstvalue); } else { // debug_printf("unknown comparator: %s\n", comparator); return ECMD_FINAL(3); } } // if compare ok, execute command after then if (success) { SCRIPTDEBUG("OK, do: %s\n", ecmd); if (ecmd_parse_command(ecmd, output, len)) { SCRIPTDEBUG("done: %s\n", output); return ECMD_FINAL(snprintf_P(output, len, PSTR("%s"), output)); } return ECMD_FINAL(2); } SCRIPTDEBUG("success was: %i\n", success); return ECMD_FINAL(1); }