mirror of
https://github.com/synthetos/g2.git
synced 2026-09-21 10:35:38 +08:00
Merge branch 'edge' into 4c-recovery
This commit is contained in:
+73
-39
@@ -2,8 +2,8 @@
|
||||
* json_parser.cpp - JSON parser
|
||||
* This file is part of the g2core project
|
||||
*
|
||||
* Copyright (c) 2011 - 2016 Alden S. Hart, Jr.
|
||||
* Copyright (c) 2016 Rob Giseburt
|
||||
* Copyright (c) 2011 - 2019 Alden S. Hart, Jr.
|
||||
* Copyright (c) 2016 - 2019 Rob Giseburt
|
||||
*
|
||||
* This file ("the software") is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License, version 2 as published by the
|
||||
@@ -96,7 +96,7 @@ stat_t json_parser(char *str, bool suppress_response) // suppress_response defau
|
||||
if (suppress_response || (status == STAT_COMPLETE)) { // skip the print if returning from something that already did it.
|
||||
return status;
|
||||
}
|
||||
nv_print_list(status, TEXT_NO_PRINT, JSON_RESPONSE_FORMAT);
|
||||
nv_print_list(status, TEXT_MULTILINE_FORMATTED, JSON_RESPONSE_FORMAT);
|
||||
sr_request_status_report(SR_REQUEST_TIMED); // generate incremental status report to show any changes
|
||||
return STAT_OK;
|
||||
}
|
||||
@@ -107,26 +107,29 @@ void json_parse_for_exec(char *str, bool execute)
|
||||
nvObj_t *nv = nv_reset_exec_nv_list(); // get a fresh nvObj list
|
||||
stat_t status = _json_parser_kernal(nv, str);
|
||||
if ((status == STAT_OK) && (execute)) {
|
||||
// execute the command
|
||||
nv = nv_exec;
|
||||
status = _json_parser_execute(nv);
|
||||
status = _json_parser_execute(nv); // execute the command
|
||||
}
|
||||
}
|
||||
|
||||
static stat_t _json_parser_execute(nvObj_t *nv) {
|
||||
|
||||
do {
|
||||
if (nv->valuetype == TYPE_PARENT) {
|
||||
// anything?
|
||||
} else if (nv->valuetype == TYPE_NULL) { // means GET the value
|
||||
if (nv->valuetype == TYPE_PARENT) { // added as partial fix for Issue #298:
|
||||
// Reading values with nested JSON changes values in inches mode
|
||||
if (strcmp(nv->token, "sr") == 0) { // Hack to execute Set Status Report (SR parent) See end note (*)
|
||||
return (nv_set(nv));
|
||||
}
|
||||
|
||||
} else if (nv->valuetype == TYPE_NULL) { // means run the GET function to get the value
|
||||
ritorno(nv_get(nv)); // ritorno returns w/status on any errors
|
||||
if (nv->valuetype == TYPE_PARENT) { // This will be true if you read a group. Exit now
|
||||
return (STAT_OK);
|
||||
}
|
||||
} else {
|
||||
} else { // otherwise, run the SET function
|
||||
cm_parse_clear(*nv->stringp); // parse Gcode and clear alarms if M30 or M2 is found
|
||||
ritorno(cm_is_alarmed()); // return error status if in alarm, shutdown or panic
|
||||
ritorno(nv_set(nv)); // set value or call a function (e.g. gcode)
|
||||
ritorno(nv_set(nv)); // run the SET function to set value or execute something (e.g. gcode)
|
||||
nv_persist(nv);
|
||||
}
|
||||
if ((nv = nv->nx) == NULL) {
|
||||
@@ -137,6 +140,10 @@ static stat_t _json_parser_execute(nvObj_t *nv) {
|
||||
return (STAT_OK); // only successful commands exit through this point
|
||||
}
|
||||
|
||||
// (*) Note: The JSON / token system is essentially flat, as it was derived from a command-line flat-ASCII approach
|
||||
// If the JSON objects had proper recursive descent handlers that just passed the remaining string (at that level)
|
||||
// off for further processing, we would not need to do this hack. A fix is in the works. For now, this is OK.
|
||||
|
||||
static stat_t _json_parser_kernal(nvObj_t *nv, char *str)
|
||||
{
|
||||
stat_t status;
|
||||
@@ -173,6 +180,7 @@ static stat_t _json_parser_kernal(nvObj_t *nv, char *str)
|
||||
if ((nv_index_is_group(nv->index)) && (nv_group_is_prefixed(nv->token))) {
|
||||
strncpy(group, nv->token, GROUP_LEN); // record the group ID
|
||||
}
|
||||
nv_coerce_types(nv); // adjust types based on type fields in configApp table
|
||||
if ((nv = nv->nx) == NULL) {
|
||||
return (STAT_JSON_TOO_MANY_PAIRS); // Not supposed to encounter a NULL
|
||||
}
|
||||
@@ -288,11 +296,12 @@ static stat_t _get_nv_pair(nvObj_t *nv, char **pstr, int8_t *depth)
|
||||
// nulls (gets)
|
||||
if ((**pstr == 'n') || ((**pstr == '\"') && (*(*pstr+1) == '\"'))) { // process null value
|
||||
nv->valuetype = TYPE_NULL;
|
||||
nv->value = TYPE_NULL;
|
||||
nv->value_int = TYPE_NULL;
|
||||
|
||||
// numbers
|
||||
} else if (isdigit(**pstr) || (**pstr == '-')) { // value is a number
|
||||
nv->value = (float)strtod(*pstr, &tmp); // tmp is the end pointer
|
||||
nv->value_int = atol(*pstr); // get the number as an integer
|
||||
nv->value_flt = (float)strtod(*pstr, &tmp); // get the number as a float - tmp is the end pointer
|
||||
|
||||
if ((tmp == *pstr) || // if start pointer equals end the conversion failed
|
||||
(strchr(terminators, *tmp) == NULL)) { // terminators are the only legal chars at the end of a number
|
||||
@@ -320,7 +329,7 @@ static stat_t _get_nv_pair(nvObj_t *nv, char **pstr, int8_t *depth)
|
||||
// if string begins with 0x it might be data, needs to be at least 3 chars long
|
||||
if( strlen(*pstr)>=3 && (*pstr)[0]=='0' && (*pstr)[1]=='x')
|
||||
{
|
||||
uint32_t *v = (uint32_t*)&nv->value;
|
||||
uint32_t *v = (uint32_t*)&nv->value_flt;
|
||||
*v = strtoul((const char *)*pstr, 0L, 0);
|
||||
nv->valuetype = TYPE_DATA;
|
||||
} else {
|
||||
@@ -330,11 +339,11 @@ static stat_t _get_nv_pair(nvObj_t *nv, char **pstr, int8_t *depth)
|
||||
|
||||
// boolean true/false
|
||||
} else if (**pstr == 't') {
|
||||
nv->valuetype = TYPE_BOOL;
|
||||
nv->value = true;
|
||||
nv->valuetype = TYPE_BOOLEAN;
|
||||
nv->value_int = true;
|
||||
} else if (**pstr == 'f') {
|
||||
nv->valuetype = TYPE_BOOL;
|
||||
nv->value = false;
|
||||
nv->valuetype = TYPE_BOOLEAN;
|
||||
nv->value_int = false;
|
||||
|
||||
// arrays
|
||||
} else if (**pstr == '[') {
|
||||
@@ -422,12 +431,15 @@ uint16_t json_serialize(nvObj_t *nv, char *out_buf, uint16_t size)
|
||||
need_a_comma = false;
|
||||
break;
|
||||
}
|
||||
case (TYPE_FLOAT): { preprocess_float(nv);
|
||||
str += floattoa(str, nv->value, nv->precision);
|
||||
case (TYPE_FLOAT): { convert_outgoing_float(nv);
|
||||
str += floattoa(str, nv->value_flt, nv->precision);
|
||||
break;
|
||||
}
|
||||
case (TYPE_INT): { // str += inttoa(str, (int)nv->value); // doesn't handle negative numbers
|
||||
str += sprintf(str, "%d", (int)nv->value);
|
||||
// case (TYPE_INT): { // str += inttoa(str, (int)nv->value); // doesn't handle negative numbers
|
||||
// str += sprintf(str, "%d", (int)nv->value);
|
||||
// break;
|
||||
// }
|
||||
case (TYPE_INTEGER):{ str += sprintf(str, "%d", (int)nv->value_int);
|
||||
break;
|
||||
}
|
||||
case (TYPE_STRING): { *str++ = '"';
|
||||
@@ -436,7 +448,7 @@ uint16_t json_serialize(nvObj_t *nv, char *out_buf, uint16_t size)
|
||||
*str++ = '"';
|
||||
break;
|
||||
}
|
||||
case (TYPE_BOOL): { if (fp_FALSE(nv->value)) {
|
||||
case (TYPE_BOOLEAN):{ if (nv->value_int) {
|
||||
strcpy(str, "false");
|
||||
str += 5;
|
||||
} else {
|
||||
@@ -445,7 +457,7 @@ uint16_t json_serialize(nvObj_t *nv, char *out_buf, uint16_t size)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (TYPE_DATA): { uint32_t *v = (uint32_t*)&nv->value;
|
||||
case (TYPE_DATA): { uint32_t *v = (uint32_t*)&nv->value_flt;
|
||||
str += sprintf(str, "\"0x%lx\"", *v);
|
||||
break;
|
||||
}
|
||||
@@ -455,6 +467,7 @@ uint16_t json_serialize(nvObj_t *nv, char *out_buf, uint16_t size)
|
||||
strcpy(str++, "]");
|
||||
break;
|
||||
}
|
||||
default: {}
|
||||
}
|
||||
}
|
||||
if (str >= str_max) { return (-1);} // signal buffer overrun
|
||||
@@ -532,7 +545,7 @@ void json_print_response(uint8_t status, const bool only_to_muted /*= false*/)
|
||||
}
|
||||
if (js.json_verbosity == JV_EXCEPTIONS) { // cutout for JV_EXCEPTIONS mode
|
||||
if (status == STAT_OK) {
|
||||
if (cm.machine_state != MACHINE_INITIALIZING) { // always do full echo during startup
|
||||
if (cm->machine_state != MACHINE_INITIALIZING) { // always do full echo during startup
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -544,7 +557,7 @@ void json_print_response(uint8_t status, const bool only_to_muted /*= false*/)
|
||||
nv_reset_nv_list();
|
||||
nv_add_string((const char *)"err", escape_string(cs.bufp, cs.saved_buf));
|
||||
|
||||
} else if ((cm.machine_state != MACHINE_INITIALIZING) || (status == STAT_INITIALIZING)) { // always do full echo during startup
|
||||
} else if ((cm->machine_state != MACHINE_INITIALIZING) || (status == STAT_INITIALIZING)) { // always do full echo during startup
|
||||
uint8_t nv_type;
|
||||
do {
|
||||
if ((nv_type = nv_get_type(nv)) == NV_TYPE_NULL) break;
|
||||
@@ -565,7 +578,7 @@ void json_print_response(uint8_t status, const bool only_to_muted /*= false*/)
|
||||
}
|
||||
|
||||
} else if (nv_type == NV_TYPE_LINENUM) { // kill line number echo if not enabled
|
||||
if ((js.echo_json_linenum == false) || (fp_ZERO(nv->value))) { // do not report line# 0
|
||||
if ((js.echo_json_linenum == false) || (fp_ZERO(nv->value_int))) { // do not report line# 0
|
||||
nv->valuetype = TYPE_EMPTY;
|
||||
}
|
||||
}
|
||||
@@ -615,16 +628,36 @@ void json_print_response(uint8_t status, const bool only_to_muted /*= false*/)
|
||||
***********************************************************************************/
|
||||
|
||||
/*
|
||||
* json_set_jv()
|
||||
* js_get_ej() - get JSON communications mode
|
||||
* js_set_ej() - set JSON communications mode
|
||||
*
|
||||
* This one is a bit different:
|
||||
* - cs.comm_mode is the setting for the *communications mode* (persistent)
|
||||
* - js.json_mode is the actual current mode
|
||||
*
|
||||
* If comm_mode is set to TEXT_MORE (0) or JSON_MODE (1) then json_mode should also be changed
|
||||
* If comm_mode is set to AUTO_MORE (0) then json_mode should not be changed
|
||||
*/
|
||||
|
||||
stat_t json_set_jv(nvObj_t *nv)
|
||||
stat_t js_get_ej(nvObj_t *nv) { return(get_integer(nv, cs.comm_mode)); }
|
||||
stat_t js_set_ej(nvObj_t *nv)
|
||||
{
|
||||
if ((uint8_t)nv->value >= JV_MAX_VALUE) {
|
||||
nv->valuetype = TYPE_NULL;
|
||||
return (STAT_INPUT_EXCEEDS_MAX_VALUE);
|
||||
}
|
||||
js.json_verbosity = (jsonVerbosity)nv->value;
|
||||
ritorno (set_integer(nv, (uint8_t &)cs.comm_mode, TEXT_MODE, AUTO_MODE));
|
||||
if (commMode(nv->value_int) < AUTO_MODE) { // set json_mode to 0 or 1, but don't change it if comm_mode == 2
|
||||
js.json_mode = commMode(nv->value_int);
|
||||
}
|
||||
return (STAT_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* js_get_jv() - get JSON verbosity
|
||||
* js_set_jv() - set JSON verbosity and related flags
|
||||
*/
|
||||
|
||||
stat_t js_get_jv(nvObj_t *nv) { return(get_integer(nv, js.json_verbosity)); }
|
||||
stat_t js_set_jv(nvObj_t *nv)
|
||||
{
|
||||
ritorno (set_integer(nv, (uint8_t &)js.json_verbosity, JV_SILENT, JV_MAX_VALUE));
|
||||
|
||||
js.echo_json_footer = false;
|
||||
js.echo_json_messages = false;
|
||||
@@ -637,11 +670,11 @@ stat_t json_set_jv(nvObj_t *nv)
|
||||
js.echo_json_messages = true;
|
||||
js.echo_json_configs = true;
|
||||
} else {
|
||||
if (nv->value >= JV_FOOTER) js.echo_json_footer = true;
|
||||
if (nv->value >= JV_MESSAGES) js.echo_json_messages = true;
|
||||
if (nv->value >= JV_CONFIGS) js.echo_json_configs = true;
|
||||
if (nv->value >= JV_LINENUM) js.echo_json_linenum = true;
|
||||
if (nv->value >= JV_VERBOSE) js.echo_json_gcode_block = true;
|
||||
if (nv->value_int >= JV_FOOTER) js.echo_json_footer = true;
|
||||
if (nv->value_int >= JV_MESSAGES) js.echo_json_messages = true;
|
||||
if (nv->value_int >= JV_CONFIGS) js.echo_json_configs = true;
|
||||
if (nv->value_int >= JV_LINENUM) js.echo_json_linenum = true;
|
||||
if (nv->value_int >= JV_VERBOSE) js.echo_json_gcode_block = true;
|
||||
}
|
||||
return(STAT_OK);
|
||||
}
|
||||
@@ -649,7 +682,7 @@ stat_t json_set_jv(nvObj_t *nv)
|
||||
/*
|
||||
* json_set_ej() - set JSON communications mode
|
||||
*/
|
||||
|
||||
/*
|
||||
stat_t json_set_ej(nvObj_t *nv)
|
||||
{
|
||||
if (nv->value < TEXT_MODE) {
|
||||
@@ -667,6 +700,7 @@ stat_t json_set_ej(nvObj_t *nv)
|
||||
}
|
||||
return (set_ui8(nv));
|
||||
}
|
||||
*/
|
||||
|
||||
/***********************************************************************************
|
||||
* TEXT MODE SUPPORT
|
||||
|
||||
Reference in New Issue
Block a user