From fe9b61a61fa6fb03adbbdb7729fe2d43c7821d55 Mon Sep 17 00:00:00 2001 From: skasti Date: Thu, 26 Sep 2024 07:14:24 +0200 Subject: [PATCH 01/33] use read_real_value for return statements, so that the returned value does not need to be in [] --- ngc_flowctrl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ngc_flowctrl.c b/ngc_flowctrl.c index eba578c5..19886383 100644 --- a/ngc_flowctrl.c +++ b/ngc_flowctrl.c @@ -689,7 +689,7 @@ status_code_t ngc_flowctrl (uint32_t o_label, char *line, uint_fast8_t *pos, boo else if((g65_return = !!grbl.on_macro_return)) ngc_flowctrl_unwind_stack(stack[stack_idx].file); - if(ngc_eval_expression(line, pos, &value) == Status_OK) { + if(read_real_value(line, pos, &value) == Status_OK) { ngc_named_param_set("_value", value); ngc_named_param_set("_value_returned", 1.0f); } else From 4836af90fe58d5d62265bfa8b2f74ad24b2718c0 Mon Sep 17 00:00:00 2001 From: skasti Date: Thu, 26 Sep 2024 07:20:39 +0200 Subject: [PATCH 02/33] if no return-value is read, set _value to 0.0f so that we don't carry previous returns --- ngc_flowctrl.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ngc_flowctrl.c b/ngc_flowctrl.c index 19886383..5ba30ee7 100644 --- a/ngc_flowctrl.c +++ b/ngc_flowctrl.c @@ -692,8 +692,10 @@ status_code_t ngc_flowctrl (uint32_t o_label, char *line, uint_fast8_t *pos, boo if(read_real_value(line, pos, &value) == Status_OK) { ngc_named_param_set("_value", value); ngc_named_param_set("_value_returned", 1.0f); - } else + } else { + ngc_named_param_set("_value", 0.0f); ngc_named_param_set("_value_returned", 0.0f); + } if(g65_return) grbl.on_macro_return(); From b148a09315a321dbb457b5962659c0e9efaf4e9d Mon Sep 17 00:00:00 2001 From: skasti Date: Wed, 9 Oct 2024 11:03:01 +0200 Subject: [PATCH 03/33] Initial attempt at adding string registers backend-functionality --- config.h | 8 +++ ngc_string_registers.c | 117 +++++++++++++++++++++++++++++++++++++++++ ngc_string_registers.h | 36 +++++++++++++ 3 files changed, 161 insertions(+) create mode 100644 ngc_string_registers.c create mode 100644 ngc_string_registers.h diff --git a/config.h b/config.h index 984fc733..1bb05fab 100644 --- a/config.h +++ b/config.h @@ -529,6 +529,14 @@ Set to \ref On or 1 to enable experimental support for parameters. #define NGC_PARAMETERS_ENABLE On #endif +/*! \def NGC_STRING_REGISTERS_ENABLE +\brief +Set to \ref On or 1 to enable experimental support for string registers. +*/ +#if !defined NGC_STRING_REGISTERS_ENABLE || defined __DOXYGEN__ +#define NGC_STRING_REGISTERS_ENABLE On +#endif + /*! \def NGC_N_ASSIGN_PARAMETERS_PER_BLOCK \brief Maximum number of parameters allowed in a block. diff --git a/ngc_string_registers.c b/ngc_string_registers.c new file mode 100644 index 00000000..48532cd0 --- /dev/null +++ b/ngc_string_registers.c @@ -0,0 +1,117 @@ +/* + ngc_params.c - get/set NGC parameter value by id or name + + Part of grblHAL + + Copyright (c) 2021-2024 Terje Io + + grblHAL is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + grblHAL is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with grblHAL. If not, see . +*/ + +/* + All predefined parameters defined in NIST RS274NGC version 3 (ref section 3.2.1) are implemented. + Most additional predefined parameters defined by LinuxCNC (ref section 5.2.3.1) are implemented. +*/ + +#include "hal.h" + +#if NGC_STRING_REGISTERS_ENABLE + +#include +#include +#include +#include +#include + +#include "system.h" +#include "settings.h" +#include "ngc_params.h" +#include "ngc_string_registers.h" + + + +typedef float (*ngc_param_get_ptr)(ngc_param_id_t id); +typedef float (*ngc_named_param_get_ptr)(void); + +#ifndef NGC_MAX_SR_LENGTH +#define NGC_MAX_SR_LENGTH 50 +#endif +typedef struct ngc_string_register { + ngc_string_register_id_t id; + char value[NGC_MAX_SR_LENGTH + 1]; + struct ngc_string_register *next; +} ngc_string_register_t; + + +static ngc_string_register_t *ngc_string_registers = NULL; + +ngc_string_register_t *find_string_register (ngc_string_register_id_t id) { + ngc_string_register_t *current_register = ngc_string_registers; + while(current_register) { + if(current_register->id == id) { + return current_register; + } else { + current_register = current_register->next; + } + } + + return NULL; +} + +ngc_string_register_t *find_string_register_with_last (ngc_string_register_id_t id, ngc_string_register_t **last_register) { + ngc_string_register_t *current_register = ngc_string_registers; + while(current_register) { + if(current_register->id == id) { + return current_register; + } else { + *last_register = current_register; + current_register = current_register->next; + } + } + + return NULL; +} + +bool ngc_string_register_get (ngc_string_register_id_t id, char **value) { + ngc_string_register_t *string_register = find_string_register(id); + if (string_register != NULL) { + *value = &string_register->value; + return true; + } + + return false; +} + +bool ngc_string_register_exists (ngc_string_register_id_t id) { + return find_string_register(id) != NULL; +} + +bool ngc_string_register_set (ngc_param_id_t id, char *value) { + ngc_string_register_t *last_register = NULL; + ngc_string_register_t *string_register = find_string_register_with_last(id, &last_register); + if (string_register != NULL) { + strcpy(string_register->value, value); + return true; + } else if (string_register = malloc(sizeof(ngc_string_register_t))) { + string_register->id = id; + strcpy(string_register->value, value); + string_register->next = NULL; + last_register->next = string_register; + return true; + } + + return false; +} + +#endif // NGC_STRING_REGISTERS_ENABLE diff --git a/ngc_string_registers.h b/ngc_string_registers.h new file mode 100644 index 00000000..cd065fd3 --- /dev/null +++ b/ngc_string_registers.h @@ -0,0 +1,36 @@ +/* + ngc_string_registers.h - get/set NGC string register value by id + + Part of grblHAL + + Copyright (c) 2024-2025 Stig-Rune Skansgård + + grblHAL is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + grblHAL is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with grblHAL. If not, see . +*/ + +#ifndef _NGC_STRING_REGISTERS_H_ +#define _NGC_STRING_REGISTERS_H_ + +#include "gcode.h" + + + +typedef uint16_t ngc_string_register_id_t; + +uint8_t ngc_float_decimals (void); +bool ngc_string_register_get (ngc_string_register_id_t id, char **value); +bool ngc_string_register_set (ngc_string_register_id_t id, char *value); +bool ngc_string_register_exists (ngc_string_register_id_t id); + +#endif // _NGC_STRING_REGISTERS_H_ From 33bfb1ad41cf3b9acb0fc72a2770f77bab1d4e36 Mon Sep 17 00:00:00 2001 From: skasti Date: Wed, 9 Oct 2024 11:14:29 +0200 Subject: [PATCH 04/33] fix warnings from build --- ngc_string_registers.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ngc_string_registers.c b/ngc_string_registers.c index 48532cd0..d7a8a54f 100644 --- a/ngc_string_registers.c +++ b/ngc_string_registers.c @@ -86,7 +86,7 @@ ngc_string_register_t *find_string_register_with_last (ngc_string_register_id_t bool ngc_string_register_get (ngc_string_register_id_t id, char **value) { ngc_string_register_t *string_register = find_string_register(id); if (string_register != NULL) { - *value = &string_register->value; + *value = &string_register->value[0]; return true; } @@ -103,7 +103,7 @@ bool ngc_string_register_set (ngc_param_id_t id, char *value) { if (string_register != NULL) { strcpy(string_register->value, value); return true; - } else if (string_register = malloc(sizeof(ngc_string_register_t))) { + } else if ((string_register = malloc(sizeof(ngc_string_register_t)))) { string_register->id = id; strcpy(string_register->value, value); string_register->next = NULL; From 9b2d7b6813f39e1035b353d435b4e074649f2599 Mon Sep 17 00:00:00 2001 From: skasti Date: Wed, 9 Oct 2024 12:47:10 +0200 Subject: [PATCH 05/33] rename from ngc_string_registers to string_registers, as I am unsure if the ngc_-prefix should be there on this --- config.h | 6 +- gcode.c | 35 ++++++++++- ngc_expr.c | 41 ++++++++++++ ngc_string_registers.c => string_registers.c | 65 ++++++++++---------- ngc_string_registers.h => string_registers.h | 17 +++-- 5 files changed, 118 insertions(+), 46 deletions(-) rename ngc_string_registers.c => string_registers.c (59%) rename ngc_string_registers.h => string_registers.h (61%) diff --git a/config.h b/config.h index 1bb05fab..e39e5c7e 100644 --- a/config.h +++ b/config.h @@ -529,12 +529,12 @@ Set to \ref On or 1 to enable experimental support for parameters. #define NGC_PARAMETERS_ENABLE On #endif -/*! \def NGC_STRING_REGISTERS_ENABLE +/*! \def STRING_REGISTERS_ENABLE \brief Set to \ref On or 1 to enable experimental support for string registers. */ -#if !defined NGC_STRING_REGISTERS_ENABLE || defined __DOXYGEN__ -#define NGC_STRING_REGISTERS_ENABLE On +#if !defined STRING_REGISTERS_ENABLE || defined __DOXYGEN__ +#define STRING_REGISTERS_ENABLE On #endif /*! \def NGC_N_ASSIGN_PARAMETERS_PER_BLOCK diff --git a/gcode.c b/gcode.c index 9b29cfdc..90a69f3e 100644 --- a/gcode.c +++ b/gcode.c @@ -43,6 +43,10 @@ #endif #endif +#if STRING_REGISTERS_ENABLE +#include "string_registers.h" +#endif + // NOTE: Max line number is defined by the g-code standard to be 99999. It seems to be an // arbitrary value, and some GUIs may require more. So we increased it based on a max safe // value when converting a float (7.2 digit precision) to an integer. @@ -573,6 +577,14 @@ char *gc_normalize_block (char *block, char **message) if(*block == '/') block++; +#if STRING_REGISTERS_ENABLE + // If the block starts with '@' it means it is setting a string register value, + // and we should not normalize it + if(*block == '@') { + return block; + } +#endif + s1 = s2 = block; while((c = *s1) != '\0') { @@ -923,8 +935,29 @@ status_code_t gc_execute_block (char *block) FAIL(Status_GcodeUnsupportedCommand); // [For now...] #endif } - } +#if STRING_REGISTERS_ENABLE + } else if (letter == '@') { + if(gc_state.skip_blocks) + return Status_OK; + float register_id; + if (!read_float(block, &char_counter, ®ister_id)) { + FAIL(Status_BadNumberFormat); // [Expected register id] + } + if (block[char_counter++] != '=') { + FAIL(Status_BadNumberFormat); // [Expected equal sign] + } + + if (!string_register_set((string_register_id_t)register_id, &block[char_counter++])) { + FAIL(Status_ExpressionInvalidArgument); // [Invalid value after '='] + } + + // setting a string-register consumes the rest of this block + break; + } +#else + } +#endif if((gc_block.words.mask & o_label.mask) && (gc_block.words.mask & ~o_label.mask) == 0) { char_counter--; return ngc_flowctrl(gc_block.values.o, block, &char_counter, &gc_state.skip_blocks); diff --git a/ngc_expr.c b/ngc_expr.c index 16ce6997..e0a49abc 100644 --- a/ngc_expr.c +++ b/ngc_expr.c @@ -31,6 +31,11 @@ #include "ngc_expr.h" #include "ngc_params.h" +#if STRING_REGISTERS_ENABLE +#include "string_registers.h" +#include "messages.h" +#endif + #define MAX_STACK 7 typedef enum { @@ -947,6 +952,9 @@ char *ngc_substitute_parameters (char *comment, char **message) size_t len = 0; float value; char *s, c; +#if STRING_REGISTERS_ENABLE + char *strValue; +#endif uint_fast8_t char_counter = 0; int8_t parse_format = 0; uint8_t decimals = ngc_float_decimals(); // LinuxCNC is 1 (or l?) @@ -970,6 +978,22 @@ char *ngc_substitute_parameters (char *comment, char **message) len += strlen(decimals ? ftoa(value, decimals) : trim_float(ftoa(value, decimals))); else len += 3; // "N/A" +#if STRING_REGISTERS_ENABLE + } else if (c == '@') { + report_message("finding string register value length", Message_Debug); + if(read_parameter(comment, &char_counter, &value) == Status_OK) { + if (string_register_get((string_register_id_t)value, &strValue)) { + len += strlen(strValue); + report_message("found string register value length", Message_Debug); + } else { + len += 3; // "N/A" + report_message("did not find string register value length", Message_Debug); + } + } else { + len += 3; // "N/A" + report_message("unable to parse string register id", Message_Warning); + } +#endif } else len++; } @@ -1002,6 +1026,23 @@ char *ngc_substitute_parameters (char *comment, char **message) else strcat(s, "N/A"); s = strchr(s, '\0'); +#if STRING_REGISTERS_ENABLE + } else if (c == '@') { + report_message("finding string register value", Message_Debug); + if(read_parameter(comment, &char_counter, &value) == Status_OK) { + if (string_register_get((string_register_id_t)value, &strValue)) { + strcat(s, strValue); + report_message("found string register value", Message_Debug); + } else { + strcat(s, "N/A"); + report_message("did not find string register value", Message_Debug); + } + } else { + strcat(s, "N/A"); + report_message("unable to parse string register id", Message_Warning); + } + s = strchr(s, '\0'); +#endif } else { *s++ = c; *s = '\0'; diff --git a/ngc_string_registers.c b/string_registers.c similarity index 59% rename from ngc_string_registers.c rename to string_registers.c index d7a8a54f..bceac083 100644 --- a/ngc_string_registers.c +++ b/string_registers.c @@ -26,7 +26,7 @@ #include "hal.h" -#if NGC_STRING_REGISTERS_ENABLE +#if STRING_REGISTERS_ENABLE #include #include @@ -37,7 +37,7 @@ #include "system.h" #include "settings.h" #include "ngc_params.h" -#include "ngc_string_registers.h" +#include "string_registers.h" @@ -47,71 +47,70 @@ typedef float (*ngc_named_param_get_ptr)(void); #ifndef NGC_MAX_SR_LENGTH #define NGC_MAX_SR_LENGTH 50 #endif -typedef struct ngc_string_register { - ngc_string_register_id_t id; +typedef struct string_register { + string_register_id_t id; char value[NGC_MAX_SR_LENGTH + 1]; - struct ngc_string_register *next; -} ngc_string_register_t; + struct string_register *next; +} string_register_t; -static ngc_string_register_t *ngc_string_registers = NULL; +static string_register_t *string_registers = NULL; -ngc_string_register_t *find_string_register (ngc_string_register_id_t id) { - ngc_string_register_t *current_register = ngc_string_registers; - while(current_register) { +string_register_t *find_string_register_with_last (string_register_id_t id, string_register_t **last_register) { + string_register_t *current_register = string_registers; + int i = 0; + while(current_register != NULL) { if(current_register->id == id) { return current_register; - } else { + } else if (i++ < 1000) { + *last_register = current_register; current_register = current_register->next; + } else { + report_message("index out of bounds", Message_Warning); + return NULL; } } return NULL; } -ngc_string_register_t *find_string_register_with_last (ngc_string_register_id_t id, ngc_string_register_t **last_register) { - ngc_string_register_t *current_register = ngc_string_registers; - while(current_register) { - if(current_register->id == id) { - return current_register; - } else { - *last_register = current_register; - current_register = current_register->next; - } - } - - return NULL; +string_register_t *find_string_register (string_register_id_t id) { + string_register_t *last = NULL; + return find_string_register_with_last(id, &last); } -bool ngc_string_register_get (ngc_string_register_id_t id, char **value) { - ngc_string_register_t *string_register = find_string_register(id); +bool string_register_get (string_register_id_t id, char **value) { + string_register_t *string_register = find_string_register(id); if (string_register != NULL) { *value = &string_register->value[0]; return true; } - return false; } -bool ngc_string_register_exists (ngc_string_register_id_t id) { +bool string_register_exists (string_register_id_t id) { return find_string_register(id) != NULL; } -bool ngc_string_register_set (ngc_param_id_t id, char *value) { - ngc_string_register_t *last_register = NULL; - ngc_string_register_t *string_register = find_string_register_with_last(id, &last_register); +bool string_register_set (ngc_param_id_t id, char *value) { + string_register_t *last_register = NULL; + string_register_t *string_register = find_string_register_with_last(id, &last_register); if (string_register != NULL) { strcpy(string_register->value, value); return true; - } else if ((string_register = malloc(sizeof(ngc_string_register_t)))) { + } else if ((string_register = malloc(sizeof(string_register_t)))) { string_register->id = id; strcpy(string_register->value, value); string_register->next = NULL; - last_register->next = string_register; + if (last_register != NULL) { + last_register->next = string_register; + } else { + string_registers = string_register; + } return true; } return false; } -#endif // NGC_STRING_REGISTERS_ENABLE +#endif // STRING_REGISTERS_ENABLE diff --git a/ngc_string_registers.h b/string_registers.h similarity index 61% rename from ngc_string_registers.h rename to string_registers.h index cd065fd3..00ddd6de 100644 --- a/ngc_string_registers.h +++ b/string_registers.h @@ -1,5 +1,5 @@ /* - ngc_string_registers.h - get/set NGC string register value by id + string_registers.h - get/set NGC string register value by id Part of grblHAL @@ -19,18 +19,17 @@ along with grblHAL. If not, see . */ -#ifndef _NGC_STRING_REGISTERS_H_ -#define _NGC_STRING_REGISTERS_H_ +#ifndef _STRING_REGISTERS_H_ +#define _STRING_REGISTERS_H_ #include "gcode.h" -typedef uint16_t ngc_string_register_id_t; +typedef uint16_t string_register_id_t; -uint8_t ngc_float_decimals (void); -bool ngc_string_register_get (ngc_string_register_id_t id, char **value); -bool ngc_string_register_set (ngc_string_register_id_t id, char *value); -bool ngc_string_register_exists (ngc_string_register_id_t id); +bool string_register_get (string_register_id_t id, char **value); +bool string_register_set (string_register_id_t id, char *value); +bool string_register_exists (string_register_id_t id); -#endif // _NGC_STRING_REGISTERS_H_ +#endif // _STRING_REGISTERS_H_ From 3b05088a7856a234b17556c7cf4e1ad4dfe63ec6 Mon Sep 17 00:00:00 2001 From: skasti Date: Wed, 9 Oct 2024 13:03:29 +0200 Subject: [PATCH 06/33] remove debug-messages --- ngc_expr.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/ngc_expr.c b/ngc_expr.c index e0a49abc..c8949aea 100644 --- a/ngc_expr.c +++ b/ngc_expr.c @@ -980,14 +980,11 @@ char *ngc_substitute_parameters (char *comment, char **message) len += 3; // "N/A" #if STRING_REGISTERS_ENABLE } else if (c == '@') { - report_message("finding string register value length", Message_Debug); if(read_parameter(comment, &char_counter, &value) == Status_OK) { if (string_register_get((string_register_id_t)value, &strValue)) { len += strlen(strValue); - report_message("found string register value length", Message_Debug); } else { len += 3; // "N/A" - report_message("did not find string register value length", Message_Debug); } } else { len += 3; // "N/A" @@ -1028,14 +1025,11 @@ char *ngc_substitute_parameters (char *comment, char **message) s = strchr(s, '\0'); #if STRING_REGISTERS_ENABLE } else if (c == '@') { - report_message("finding string register value", Message_Debug); if(read_parameter(comment, &char_counter, &value) == Status_OK) { if (string_register_get((string_register_id_t)value, &strValue)) { strcat(s, strValue); - report_message("found string register value", Message_Debug); } else { strcat(s, "N/A"); - report_message("did not find string register value", Message_Debug); } } else { strcat(s, "N/A"); From 58b66f4932b246aa476b9d74c3bea605f6050446 Mon Sep 17 00:00:00 2001 From: skasti Date: Wed, 9 Oct 2024 14:38:45 +0200 Subject: [PATCH 07/33] Allow setting string-registers using expression --- gcode.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/gcode.c b/gcode.c index 90a69f3e..8e56b205 100644 --- a/gcode.c +++ b/gcode.c @@ -940,8 +940,14 @@ status_code_t gc_execute_block (char *block) if(gc_state.skip_blocks) return Status_OK; float register_id; - if (!read_float(block, &char_counter, ®ister_id)) { - FAIL(Status_BadNumberFormat); // [Expected register id] + if (block[char_counter] == '[') { + if (!ngc_eval_expression(block, &char_counter, ®ister_id)) { + FAIL(Status_ExpressionSyntaxError); // [Invalid expression syntax] + } + } else { + if (!read_float(block, &char_counter, ®ister_id)) { + FAIL(Status_BadNumberFormat); // [Expected register id] + } } if (block[char_counter++] != '=') { From 6b3f6dd7b168420c9eacb8645a7e27b5b1be364e Mon Sep 17 00:00:00 2001 From: skasti Date: Wed, 9 Oct 2024 15:02:28 +0200 Subject: [PATCH 08/33] allow exressions --- gcode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcode.c b/gcode.c index 8e56b205..bc46aaf6 100644 --- a/gcode.c +++ b/gcode.c @@ -941,7 +941,7 @@ status_code_t gc_execute_block (char *block) return Status_OK; float register_id; if (block[char_counter] == '[') { - if (!ngc_eval_expression(block, &char_counter, ®ister_id)) { + if (ngc_eval_expression(block, &char_counter, ®ister_id) != Status_OK) { FAIL(Status_ExpressionSyntaxError); // [Invalid expression syntax] } } else { From efe1a6b02b29396002302091371639b8316dadc8 Mon Sep 17 00:00:00 2001 From: skasti Date: Wed, 9 Oct 2024 15:07:13 +0200 Subject: [PATCH 09/33] combine ifs --- gcode.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/gcode.c b/gcode.c index bc46aaf6..120a17c7 100644 --- a/gcode.c +++ b/gcode.c @@ -944,10 +944,8 @@ status_code_t gc_execute_block (char *block) if (ngc_eval_expression(block, &char_counter, ®ister_id) != Status_OK) { FAIL(Status_ExpressionSyntaxError); // [Invalid expression syntax] } - } else { - if (!read_float(block, &char_counter, ®ister_id)) { - FAIL(Status_BadNumberFormat); // [Expected register id] - } + } else if (!read_float(block, &char_counter, ®ister_id)) { + FAIL(Status_BadNumberFormat); // [Expected register id] } if (block[char_counter++] != '=') { From d4951fff9eec2401c36033c92d8c065444588513 Mon Sep 17 00:00:00 2001 From: skasti Date: Wed, 9 Oct 2024 15:24:57 +0200 Subject: [PATCH 10/33] Do not allow setting string registers to values longer than 40 characters --- string_registers.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/string_registers.c b/string_registers.c index bceac083..563528ee 100644 --- a/string_registers.c +++ b/string_registers.c @@ -93,6 +93,11 @@ bool string_register_exists (string_register_id_t id) { } bool string_register_set (ngc_param_id_t id, char *value) { + if (strlen(value) > NGC_MAX_SR_LENGTH) { + report_message("String register values cannot be longer than 40 characters", Message_Warning); + return false; + } + string_register_t *last_register = NULL; string_register_t *string_register = find_string_register_with_last(id, &last_register); if (string_register != NULL) { From 37822600f1b438547d327fe84ad2e07868868bb8 Mon Sep 17 00:00:00 2001 From: skasti Date: Wed, 9 Oct 2024 22:33:54 +0200 Subject: [PATCH 11/33] Substitute characters before creating a string register. This allows creating texts with values from parameters etc --- gcode.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/gcode.c b/gcode.c index 120a17c7..14355631 100644 --- a/gcode.c +++ b/gcode.c @@ -952,8 +952,15 @@ status_code_t gc_execute_block (char *block) FAIL(Status_BadNumberFormat); // [Expected equal sign] } - if (!string_register_set((string_register_id_t)register_id, &block[char_counter++])) { + char *strValue; + substitute_parameters(&block[char_counter++], &strValue); + report_message(strValue, Message_Debug); + + if (!string_register_set((string_register_id_t)register_id, strValue)) { + free(strValue); FAIL(Status_ExpressionInvalidArgument); // [Invalid value after '='] + } else { + free(strValue); } // setting a string-register consumes the rest of this block From be6d916208945ccda8f2dae2423665b8b20463af Mon Sep 17 00:00:00 2001 From: skasti Date: Thu, 10 Oct 2024 14:17:49 +0200 Subject: [PATCH 12/33] use ampersand as the special character --- gcode.c | 6 +++--- ngc_expr.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gcode.c b/gcode.c index 14355631..f007fc0e 100644 --- a/gcode.c +++ b/gcode.c @@ -578,9 +578,9 @@ char *gc_normalize_block (char *block, char **message) block++; #if STRING_REGISTERS_ENABLE - // If the block starts with '@' it means it is setting a string register value, + // If the block starts with '&' it means it is setting a string register value, // and we should not normalize it - if(*block == '@') { + if(*block == '&') { return block; } #endif @@ -936,7 +936,7 @@ status_code_t gc_execute_block (char *block) #endif } #if STRING_REGISTERS_ENABLE - } else if (letter == '@') { + } else if (letter == '&') { if(gc_state.skip_blocks) return Status_OK; float register_id; diff --git a/ngc_expr.c b/ngc_expr.c index c8949aea..583fdf80 100644 --- a/ngc_expr.c +++ b/ngc_expr.c @@ -979,7 +979,7 @@ char *ngc_substitute_parameters (char *comment, char **message) else len += 3; // "N/A" #if STRING_REGISTERS_ENABLE - } else if (c == '@') { + } else if (c == '&') { if(read_parameter(comment, &char_counter, &value) == Status_OK) { if (string_register_get((string_register_id_t)value, &strValue)) { len += strlen(strValue); @@ -1024,7 +1024,7 @@ char *ngc_substitute_parameters (char *comment, char **message) strcat(s, "N/A"); s = strchr(s, '\0'); #if STRING_REGISTERS_ENABLE - } else if (c == '@') { + } else if (c == '&') { if(read_parameter(comment, &char_counter, &value) == Status_OK) { if (string_register_get((string_register_id_t)value, &strValue)) { strcat(s, strValue); From 9c95b8f91b4a2ebb861e7bce8d4049a224c491ad Mon Sep 17 00:00:00 2001 From: skasti Date: Sun, 13 Oct 2024 12:52:19 +0200 Subject: [PATCH 13/33] Update copyright header of string_registers.c --- string_registers.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/string_registers.c b/string_registers.c index 563528ee..61be5004 100644 --- a/string_registers.c +++ b/string_registers.c @@ -1,9 +1,9 @@ /* - ngc_params.c - get/set NGC parameter value by id or name + string_registers.c - get/set string register value by id or name Part of grblHAL - Copyright (c) 2021-2024 Terje Io + Copyright (c) 2024-2025 Stig-Rune Skansgård grblHAL is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -19,11 +19,6 @@ along with grblHAL. If not, see . */ -/* - All predefined parameters defined in NIST RS274NGC version 3 (ref section 3.2.1) are implemented. - Most additional predefined parameters defined by LinuxCNC (ref section 5.2.3.1) are implemented. -*/ - #include "hal.h" #if STRING_REGISTERS_ENABLE From 78d8458c3e1a48d8f069078ce5365af3b7c8cb48 Mon Sep 17 00:00:00 2001 From: skasti Date: Sun, 13 Oct 2024 17:49:28 +0200 Subject: [PATCH 14/33] cleaning up some leftovers from params, and renaming to MAX_SR_LENGTH --- string_registers.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/string_registers.c b/string_registers.c index 61be5004..ef787066 100644 --- a/string_registers.c +++ b/string_registers.c @@ -34,17 +34,12 @@ #include "ngc_params.h" #include "string_registers.h" - - -typedef float (*ngc_param_get_ptr)(ngc_param_id_t id); -typedef float (*ngc_named_param_get_ptr)(void); - -#ifndef NGC_MAX_SR_LENGTH -#define NGC_MAX_SR_LENGTH 50 +#ifndef MAX_SR_LENGTH +#define MAX_SR_LENGTH 50 #endif typedef struct string_register { string_register_id_t id; - char value[NGC_MAX_SR_LENGTH + 1]; + char value[MAX_SR_LENGTH + 1]; struct string_register *next; } string_register_t; @@ -88,7 +83,7 @@ bool string_register_exists (string_register_id_t id) { } bool string_register_set (ngc_param_id_t id, char *value) { - if (strlen(value) > NGC_MAX_SR_LENGTH) { + if (strlen(value) > MAX_SR_LENGTH) { report_message("String register values cannot be longer than 40 characters", Message_Warning); return false; } From e6979fbaa90bc3fa8568797dc68cee210e50ba36 Mon Sep 17 00:00:00 2001 From: skasti Date: Sun, 13 Oct 2024 17:54:13 +0200 Subject: [PATCH 15/33] some code style changes --- string_registers.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/string_registers.c b/string_registers.c index ef787066..63a9cf8b 100644 --- a/string_registers.c +++ b/string_registers.c @@ -43,15 +43,17 @@ typedef struct string_register { struct string_register *next; } string_register_t; - static string_register_t *string_registers = NULL; string_register_t *find_string_register_with_last (string_register_id_t id, string_register_t **last_register) { string_register_t *current_register = string_registers; int i = 0; + while(current_register != NULL) { + if(current_register->id == id) { return current_register; + } else if (i++ < 1000) { *last_register = current_register; current_register = current_register->next; @@ -71,10 +73,12 @@ string_register_t *find_string_register (string_register_id_t id) { bool string_register_get (string_register_id_t id, char **value) { string_register_t *string_register = find_string_register(id); + if (string_register != NULL) { *value = &string_register->value[0]; return true; } + return false; } @@ -90,18 +94,22 @@ bool string_register_set (ngc_param_id_t id, char *value) { string_register_t *last_register = NULL; string_register_t *string_register = find_string_register_with_last(id, &last_register); + if (string_register != NULL) { strcpy(string_register->value, value); return true; + } else if ((string_register = malloc(sizeof(string_register_t)))) { string_register->id = id; strcpy(string_register->value, value); string_register->next = NULL; + if (last_register != NULL) { last_register->next = string_register; } else { string_registers = string_register; } + return true; } From 59952afb55a8309addb34c066e1139a78455bc6b Mon Sep 17 00:00:00 2001 From: skasti Date: Sun, 13 Oct 2024 17:55:17 +0200 Subject: [PATCH 16/33] Ensure string registers are not enabled by default, since this is experimental --- config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.h b/config.h index e39e5c7e..64f6da4b 100644 --- a/config.h +++ b/config.h @@ -534,7 +534,7 @@ Set to \ref On or 1 to enable experimental support for parameters. Set to \ref On or 1 to enable experimental support for string registers. */ #if !defined STRING_REGISTERS_ENABLE || defined __DOXYGEN__ -#define STRING_REGISTERS_ENABLE On +#define STRING_REGISTERS_ENABLE Off #endif /*! \def NGC_N_ASSIGN_PARAMETERS_PER_BLOCK From dea24e376c18214840c972296af1dcad61f938e3 Mon Sep 17 00:00:00 2001 From: skasti Date: Wed, 23 Oct 2024 19:20:14 +0200 Subject: [PATCH 17/33] reverting stuf from other branch --- ngc_flowctrl.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/ngc_flowctrl.c b/ngc_flowctrl.c index 5ba30ee7..eba578c5 100644 --- a/ngc_flowctrl.c +++ b/ngc_flowctrl.c @@ -689,13 +689,11 @@ status_code_t ngc_flowctrl (uint32_t o_label, char *line, uint_fast8_t *pos, boo else if((g65_return = !!grbl.on_macro_return)) ngc_flowctrl_unwind_stack(stack[stack_idx].file); - if(read_real_value(line, pos, &value) == Status_OK) { + if(ngc_eval_expression(line, pos, &value) == Status_OK) { ngc_named_param_set("_value", value); ngc_named_param_set("_value_returned", 1.0f); - } else { - ngc_named_param_set("_value", 0.0f); + } else ngc_named_param_set("_value_returned", 0.0f); - } if(g65_return) grbl.on_macro_return(); From 012950c950226873709cef2b4fae3646f28f2c78 Mon Sep 17 00:00:00 2001 From: skasti Date: Wed, 23 Oct 2024 19:43:50 +0200 Subject: [PATCH 18/33] Use realloc to allocate new memory. --- string_registers.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/string_registers.c b/string_registers.c index 63a9cf8b..7d54ef06 100644 --- a/string_registers.c +++ b/string_registers.c @@ -39,8 +39,8 @@ #endif typedef struct string_register { string_register_id_t id; - char value[MAX_SR_LENGTH + 1]; struct string_register *next; + char value[1]; } string_register_t; static string_register_t *string_registers = NULL; @@ -50,16 +50,11 @@ string_register_t *find_string_register_with_last (string_register_id_t id, stri int i = 0; while(current_register != NULL) { - if(current_register->id == id) { return current_register; - - } else if (i++ < 1000) { + } else { *last_register = current_register; current_register = current_register->next; - } else { - report_message("index out of bounds", Message_Warning); - return NULL; } } @@ -87,7 +82,8 @@ bool string_register_exists (string_register_id_t id) { } bool string_register_set (ngc_param_id_t id, char *value) { - if (strlen(value) > MAX_SR_LENGTH) { + size_t length = strlen(value); + if (length > MAX_SR_LENGTH) { report_message("String register values cannot be longer than 40 characters", Message_Warning); return false; } @@ -95,15 +91,22 @@ bool string_register_set (ngc_param_id_t id, char *value) { string_register_t *last_register = NULL; string_register_t *string_register = find_string_register_with_last(id, &last_register); - if (string_register != NULL) { - strcpy(string_register->value, value); - return true; + bool isNew = string_register == NULL; + + // if a string register is found, we realloc it to fit the new value. If not, + // calling realloc with a null pointer should result in allocating new memory. + if ((string_register = realloc(string_register, sizeof(string_register_t) + length))) { + // Since realloc copies (or preserves) the old object, + // we only need to write id and next if this is actually a new register + if (isNew) { + string_register->id = id; + string_register->next = NULL; + } - } else if ((string_register = malloc(sizeof(string_register_t)))) { - string_register->id = id; strcpy(string_register->value, value); - string_register->next = NULL; + // Update the next-pointer of the last register before this one. + // If none exists, update the string_registers-pointer. if (last_register != NULL) { last_register->next = string_register; } else { From 4102648915cbddc6e1c5b93bfa670ee931de8b49 Mon Sep 17 00:00:00 2001 From: skasti Date: Wed, 23 Oct 2024 19:44:42 +0200 Subject: [PATCH 19/33] Set max-length to 256 --- string_registers.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/string_registers.c b/string_registers.c index 7d54ef06..ae276d95 100644 --- a/string_registers.c +++ b/string_registers.c @@ -35,7 +35,8 @@ #include "string_registers.h" #ifndef MAX_SR_LENGTH -#define MAX_SR_LENGTH 50 +// 256 is max block-length in gcode, so probably reasonable +#define MAX_SR_LENGTH 256 #endif typedef struct string_register { string_register_id_t id; From 072fdb33b04dec2c456a8c7a626108646ddde393 Mon Sep 17 00:00:00 2001 From: Jon Escombe Date: Fri, 25 Oct 2024 12:08:16 +0100 Subject: [PATCH 20/33] Shift neopixel bit pattern On some processors, MOSI can be driven to the output level before the clock is enabled. If the first bit is a 1, this can result in a longer pulse that is interpreted as a high level by neopixels. This fix maintains the same inter-bit timings, but ensures the first bit is always 0. (The last bit is already always zero due to padding for reset timing requirements). --- rgb.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/rgb.h b/rgb.h index 8bd7cceb..fb867219 100644 --- a/rgb.h +++ b/rgb.h @@ -131,11 +131,11 @@ static inline void rgb_3bpp_pack (uint8_t *led, rgb_color_t color, rgb_color_ma do { R <<= 3; - R |= color.R & bitmask ? 0b110 : 0b100; + R |= color.R & bitmask ? 0b011 : 0b010; G <<= 3; - G |= color.G & bitmask ? 0b110 : 0b100; + G |= color.G & bitmask ? 0b011 : 0b010; B <<= 3; - B |= color.B & bitmask ? 0b110 : 0b100; + B |= color.B & bitmask ? 0b011 : 0b010; } while(bitmask >>= 1); if(mask.G) { @@ -179,13 +179,13 @@ static inline rgb_color_t rgb_3bpp_unpack (uint8_t *led, uint8_t intensity) B |= *led; do { - if((R & 0b110) == 0b110) + if((R & 0b011) == 0b011) color.R |= bitmask; R >>= 3; - if((G & 0b110) == 0b110) + if((G & 0b011) == 0b011) color.G |= bitmask; G >>= 3; - if((B & 0b110) == 0b110) + if((B & 0b011) == 0b011) color.B |= bitmask; B >>= 3; } while(bitmask <<= 1); From f830979a42e36bb280c29221fb19a6d282a0407b Mon Sep 17 00:00:00 2001 From: Terje Io Date: Sun, 27 Oct 2024 07:27:25 +0700 Subject: [PATCH 21/33] Changed _vminor named parameter to contain build date in YYMMDD format, previously value was 0. Added support for LinuxCNC style (ABORT,) comment, requires expressions enabled. Terminates gcode program, outputs message and returns error 253. Added PRM[] and PRM[,] functions to expressions, returns $-setting value or value of bit in integer type setting. "hardened" flow control code, fixed bug in repeat...continue handling. Changed signature of grbl.on_gcode_comment event, now returns status code. --- README.md | 2 +- changelog.md | 33 +++++++++++++++++++++++++++++--- core_handlers.h | 2 +- errors.c | 13 +++++++------ errors.h | 18 ++++++++--------- gcode.c | 25 ++++++++++++------------ gcode.h | 2 +- grbl.h | 2 +- messages.h | 1 + ngc_expr.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++- ngc_flowctrl.c | 33 +++++++++++++++++++++++++++++--- ngc_params.c | 2 +- nvs_buffer.c | 21 ++++++++++++++------ report.c | 4 ++++ system.c | 12 +++++++----- 15 files changed, 171 insertions(+), 50 deletions(-) diff --git a/README.md b/README.md index 99c77e3d..e1f79c26 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ It has been written to complement grblHAL and has features such as proper keyboa --- -Latest build date is 20241023, see the [changelog](changelog.md) for details. +Latest build date is 20241025, see the [changelog](changelog.md) for details. __NOTE:__ Build 20240222 has moved the probe input to the ioPorts pool of inputs and will be allocated from it when configured. The change is major and _potentially dangerous_, it may damage your probe, so please _verify correct operation_ after installing this, or later, builds. diff --git a/changelog.md b/changelog.md index 82354cde..4b1d6e9c 100644 --- a/changelog.md +++ b/changelog.md @@ -1,22 +1,49 @@ ## grblHAL changelog +Build 20241025 + +Core: + +* Changed `_vminor` named parameter to return build date in YYMMDD format, previously value was 0. + +* Added support for LinuxCNC style `(ABORT,)` comment, requires expressions enabled. +Terminates gcode program, outputs message and returns error 253. + +* Added `PRM[]` and `PRM[,]` functions to expressions, returns $-setting value or value of bit in integer type setting. + +* "hardened" flow control code, fixed bug in `repeat...continue` handling. + +* Changed signature of `grbl.on_gcode_comment` event, now returns status code. + +Drivers: + +* STM32F4xx: fixed typos. + +* Some: added note to _platformio.ino_ file. + +Plugins: + +* SD Card, macros: fixed G65P1 settings read macro when reading some indexed settings. + +--- + Build 20241023 Core: * Fixed some odd bugs in NGC flow control, prepared for file based named O-call subroutines. -* Fixed incorrect comment string passed to passed to `grbl.on_gcode_comment` event. +* Fixed incorrect comment string passed to `grbl.on_gcode_comment` event. * Added generic redirector for temporarily changing input stream to read from a file. Supports nesting. Drivers: -*ESP32: fix for overriding UART0 pins, reverted and fixed tests for ESP32-S3 conditional code. +* ESP32: fix for overriding UART0 pins, reverted and fixed tests for ESP32-S3 conditional code. Plugins: -* File system macros: updated to use new input stream redirector, allows nesting of `G65` calls +* SD Card, macros: updated to use new input stream redirector, allows nesting of `G65` calls \(max 5 levels depending on available memory\). __NOTE:__ Not extensively tested, feedback required. * SD card: updated to work alongside new file redirector. diff --git a/core_handlers.h b/core_handlers.h index 4238145a..e4e138bd 100644 --- a/core_handlers.h +++ b/core_handlers.h @@ -118,7 +118,7 @@ typedef void (*on_reset_ptr)(void); typedef void (*on_jog_cancel_ptr)(sys_state_t state); typedef bool (*on_spindle_select_ptr)(spindle_ptrs_t *spindle); typedef void (*on_spindle_selected_ptr)(spindle_ptrs_t *spindle); -typedef void (*on_gcode_message_ptr)(char *msg); +typedef status_code_t (*on_gcode_message_ptr)(char *msg); typedef void (*on_rt_reports_added_ptr)(report_tracking_flags_t report); typedef const char *(*on_set_axis_setting_unit_ptr)(setting_id_t setting_id, uint_fast8_t axis_idx); typedef status_code_t (*on_file_open_ptr)(const char *fname, vfs_file_t *handle, bool stream); diff --git a/errors.c b/errors.c index 4e9ab08d..56a33359 100644 --- a/errors.c +++ b/errors.c @@ -3,22 +3,22 @@ Part of grblHAL - Copyright (c) 2017-2023 Terje Io + Copyright (c) 2017-2024 Terje Io Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC Copyright (c) 2009-2011 Simen Svale Skogsrud - Grbl is free software: you can redistribute it and/or modify + grblHAL is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Grbl is distributed in the hope that it will be useful, + grblHAL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with Grbl. If not, see . + along with grblHAL. If not, see . */ #include @@ -102,8 +102,9 @@ PROGMEM static const status_detail_t status_detail[] = { { Status_FlowControlNotExecutingMacro, "Flow statement only allowed in filesystem macro." }, { Status_FlowControlSyntaxError, "Unknown flow statement." }, { Status_FlowControlStackOverflow, "Stack overflow while executing flow statement." }, - { Status_FlowControlOutOfMemory, "Out of memory while executing flow statement." } + { Status_FlowControlOutOfMemory, "Out of memory while executing flow statement." }, #endif + { Status_UserException, "User defined error occured." } #endif // NO_SETTINGS_DESCRIPTIONS }; diff --git a/errors.h b/errors.h index 79299bbb..78aba0ce 100644 --- a/errors.h +++ b/errors.h @@ -3,22 +3,22 @@ Part of grblHAL - Copyright (c) 2017-2023 Terje Io + Copyright (c) 2017-2024 Terje Io Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC Copyright (c) 2009-2011 Simen Svale Skogsrud - Grbl is free software: you can redistribute it and/or modify + grblHAL is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Grbl is distributed in the hope that it will be useful, + grblHAL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with Grbl. If not, see . + along with grblHAL. If not, see . */ #ifndef _ERRORS_H_ @@ -26,7 +26,7 @@ #include -// Define Grbl status codes. Valid values (0-255) +// Define grblHAL status codes. Valid values (0-255) typedef enum { Status_OK = 0, Status_ExpectedCommandLetter = 1, @@ -112,10 +112,10 @@ typedef enum { Status_FlowControlSyntaxError = 81, Status_FlowControlStackOverflow = 82, Status_FlowControlOutOfMemory = 83, - + Status_StatusMax = Status_FlowControlOutOfMemory, + Status_UserException = 253, Status_Handled, // For internal use only - Status_Unhandled, // For internal use only - Status_StatusMax = Status_Unhandled + Status_Unhandled // For internal use only } __attribute__ ((__packed__)) status_code_t; typedef struct { diff --git a/gcode.c b/gcode.c index f007fc0e..02a8df6a 100644 --- a/gcode.c +++ b/gcode.c @@ -561,7 +561,7 @@ bool gc_modal_state_restore (gc_modal_t *copy) // If the driver handles message comments then the first is extracted and returned in a dynamically // allocated memory block, the caller must free this after the message has been processed. -char *gc_normalize_block (char *block, char **message) +char *gc_normalize_block (char *block, status_code_t *status, char **message) { char c, *s1, *s2, *comment = NULL; @@ -620,12 +620,8 @@ char *gc_normalize_block (char *block, char **message) comment += 6; ngc_substitute_parameters(comment, message); *comment = '\0'; // Do not generate grbl.on_gcode_comment event! - } else if(!strncasecmp(comment, "MSG,", 4)) { - comment += 4; - ngc_substitute_parameters(comment, message); - } - } -#else + } else { +#endif size_t len = s1 - comment - 3; if(!strncasecmp(comment, "MSG,", 4) && (*message = malloc(len))) { @@ -637,12 +633,13 @@ char *gc_normalize_block (char *block, char **message) } memcpy(*message, comment, len); } - } +#if NGC_EXPRESSIONS_ENABLE + } #endif + } } - if(*comment && *message == NULL && grbl.on_gcode_comment) - grbl.on_gcode_comment(comment); + *status = grbl.on_gcode_comment(comment); } comment = NULL; break; @@ -785,6 +782,7 @@ status_code_t gc_execute_block (char *block) #endif char *message = NULL; + status_code_t status = Status_OK; struct { float f; uint32_t o; @@ -792,12 +790,15 @@ status_code_t gc_execute_block (char *block) tool_id_t t; } single_meaning_value = {0}; - block = gc_normalize_block(block, &message); + block = gc_normalize_block(block, &status, &message); + + if(status != Status_OK) + FAIL(status); if(block[0] == '\0') { if(message) gc_output_message(message); - return Status_OK; + return status; } // Determine if the line is a program start/end marker. diff --git a/gcode.h b/gcode.h index ec551ba8..3564dc5e 100644 --- a/gcode.h +++ b/gcode.h @@ -655,7 +655,7 @@ typedef struct { // Initialize the parser void gc_init (void); -char *gc_normalize_block (char *block, char **message); +char *gc_normalize_block (char *block, status_code_t *status, char **message); // Execute one block of rs275/ngc/g-code status_code_t gc_execute_block (char *block); diff --git a/grbl.h b/grbl.h index ae698824..7453baec 100644 --- a/grbl.h +++ b/grbl.h @@ -42,7 +42,7 @@ #else #define GRBL_VERSION "1.1f" #endif -#define GRBL_BUILD 20241023 +#define GRBL_BUILD 20241025 #define GRBL_URL "https://github.com/grblHAL" diff --git a/messages.h b/messages.h index 3983fedb..353579df 100644 --- a/messages.h +++ b/messages.h @@ -54,6 +54,7 @@ typedef enum { Message_Plain = 0, Message_Info, Message_Warning, + Message_Error, Message_Debug } message_type_t; diff --git a/ngc_expr.c b/ngc_expr.c index 583fdf80..6343ac99 100644 --- a/ngc_expr.c +++ b/ngc_expr.c @@ -28,6 +28,7 @@ #include #include "errors.h" +#include "settings.h" #include "ngc_expr.h" #include "ngc_params.h" @@ -75,7 +76,8 @@ typedef enum { NGCUnaryOp_SIN, NGCUnaryOp_SQRT, NGCUnaryOp_TAN, - NGCUnaryOp_Exists + NGCUnaryOp_Exists, + NGCUnaryOp_Parameter // read setting/setting bit } ngc_unary_op_t; /*! \brief Executes the operations: /, MOD, ** (POW), *. @@ -569,6 +571,14 @@ static status_code_t read_operation_unary (char *line, uint_fast8_t *pos, ngc_un status = Status_ExpressionUknownOp; break; + case 'P': + if(!strncmp(line + *pos, "RM", 2)) { + *operation = NGCUnaryOp_Parameter; + *pos += 2; + } else + status = Status_ExpressionUknownOp; + break; + default: status = Status_ExpressionUknownOp; } @@ -727,6 +737,45 @@ static status_code_t read_unary (char *line, uint_fast8_t *pos, float *value) } else status = Status_ExpressionSyntaxError; + } else if(operation == NGCUnaryOp_Parameter) { + + // get setting value or bit in value + + bool get_bit; + int32_t setting_id, bitnum; + const setting_detail_t *setting; + + (*pos)++; + if((status = ngc_read_integer_value(line, pos, &setting_id)) == Status_OK) { + + if((get_bit = line[*pos] == ',')) { + (*pos)++; + if((status = ngc_read_integer_value(line, pos, &bitnum)) != Status_OK) + return status; + if(bitnum < 0 || bitnum > 31) + return Status_ExpressionArgumentOutOfRange; + } + + if(line[*pos] != ']') + return Status_ExpressionSyntaxError; // Left bracket missing after slash with ATAN; + + (*pos)++; + + if((setting = setting_get_details((setting_id_t)setting_id, NULL))) { + + uint_fast8_t offset = setting_id - setting->id; + + if(setting->datatype == Format_Decimal) + *value = setting_get_float_value(setting, offset); + else if(setting_is_integer(setting) || setting_is_list(setting)) { + *value = (float)setting_get_int_value(setting, offset); + if(get_bit) + *value = (((uint32_t)*value >> bitnum) & 0x1) ? 1.0f : 0.0f; + } else + status = Status_ExpressionArgumentOutOfRange; + } else + status = Status_ExpressionArgumentOutOfRange; + } } else if((status = ngc_eval_expression(line, pos, value)) == Status_OK) { if(operation == NGCUnaryOp_ATAN) status = read_atan(line, pos, value); diff --git a/ngc_flowctrl.c b/ngc_flowctrl.c index eba578c5..749b8a75 100644 --- a/ngc_flowctrl.c +++ b/ngc_flowctrl.c @@ -84,6 +84,7 @@ static volatile int_fast8_t stack_idx = -1; static bool skip_sub = false; static ngc_sub_t *subs = NULL, *exec_sub = NULL; static ngc_stack_entry_t stack[NGC_STACK_DEPTH] = {0}; +static on_gcode_message_ptr on_gcode_comment; static status_code_t read_command (char *line, uint_fast8_t *pos, ngc_cmd_t *operation) { @@ -294,8 +295,34 @@ void ngc_flowctrl_unwind_stack (vfs_file_t *file) stack_pull(); } +static status_code_t onGcodeComment (char *comment) +{ + uint_fast8_t pos = 6; + status_code_t status = Status_OK; + + if(!strncasecmp(comment, "ABORT,", 6)) { + char *buf = NULL; + if(ngc_substitute_parameters(comment + pos, &buf)) { + report_message(buf, Message_Error); + free(buf); + } + status = Status_UserException; + } else if(on_gcode_comment) + status = on_gcode_comment(comment); + + return status; +} + void ngc_flowctrl_init (void) { + static bool init_ok = false; + + if(!init_ok) { + init_ok = true; + on_gcode_comment = grbl.on_gcode_comment; + grbl.on_gcode_comment = onGcodeComment; + } + clear_subs(NULL); while(stack_idx >= 0) stack_pull(); @@ -523,7 +550,7 @@ status_code_t ngc_flowctrl (uint32_t o_label, char *line, uint_fast8_t *pos, boo if(stack[stack_idx].repeats && --stack[stack_idx].repeats) vfs_seek(stack[stack_idx].file, stack[stack_idx].file_pos); else - stack_pull(); + stack[stack_idx].skip = true; break; case NGCFlowCtrl_Do: @@ -606,7 +633,7 @@ status_code_t ngc_flowctrl (uint32_t o_label, char *line, uint_fast8_t *pos, boo if(!skipping) { - ngc_sub_t *sub = subs; + ngc_sub_t *sub; if(o_label > NGC_MAX_PARAM_ID) { #if 0 @@ -631,7 +658,7 @@ status_code_t ngc_flowctrl (uint32_t o_label, char *line, uint_fast8_t *pos, boo status = Status_FlowControlOutOfMemory; // file not found... } #endif - } else do { + } else if((sub = subs)) do { if(sub->o_label == o_label && sub->file == hal.stream.file) break; } while((sub = sub->next)); diff --git a/ngc_params.c b/ngc_params.c index f5b96974..1ce15279 100644 --- a/ngc_params.c +++ b/ngc_params.c @@ -414,7 +414,7 @@ float ngc_named_param_get_by_id (ncg_name_param_id_t id) break; case NGCParam_vminor: - value = 0.0f; // TODO: derive from version letter? + value = (float)(GRBL_BUILD - 20000000); break; case NGCParam_line: diff --git a/nvs_buffer.c b/nvs_buffer.c index 45e04366..e0c10e70 100644 --- a/nvs_buffer.c +++ b/nvs_buffer.c @@ -39,7 +39,7 @@ static uint8_t *nvsbuffer = NULL; static nvs_io_t physical_nvs; static bool dirty; - +uint32_t nvs_size_max = NVS_SIZE; settings_dirty_t settings_dirty; typedef struct { @@ -54,7 +54,6 @@ typedef struct { #define NVS_GROUP_STARTUP 3 #define NVS_GROUP_BUILD 4 - #define PARAMETER_ADDR(n) (NVS_ADDR_PARAMETERS + n * (sizeof(coord_data_t) + NVS_CRC_BYTES)) #define STARTLINE_ADDR(n) (NVS_ADDR_STARTUP_BLOCK + n * (sizeof(stored_line_t) + NVS_CRC_BYTES)) #if N_TOOLS @@ -215,10 +214,20 @@ static nvs_transfer_result_t memcpy_from_ram (uint8_t *destination, uint32_t sou // Try to allocate RAM from heap for buffer/emulation. bool nvs_buffer_alloc (void) { - assert(NVS_SIZE >= GRBL_NVS_SIZE); + static uint32_t nvs_size = NVS_SIZE; + + if(hal.nvs.size_max > nvs_size) { + nvs_size_max = min(4096, hal.nvs.size_max); // Limit to 4K for now + if(nvsbuffer) + free(nvsbuffer); + } - if((nvsbuffer = malloc(NVS_SIZE))) - memset(nvsbuffer, 0xFF, NVS_SIZE); + assert(nvs_size_max >= GRBL_NVS_SIZE); + + if((nvsbuffer = malloc(nvs_size_max))) { + nvs_size = nvs_size_max; + memset(nvsbuffer, 0xFF, nvs_size_max); + } return nvsbuffer != NULL; } @@ -294,7 +303,7 @@ nvs_address_t nvs_alloc (size_t size) } size += NVS_CRC_BYTES; // add room for checksum. - if(hal.nvs.driver_area.size + size < (NVS_SIZE - GRBL_NVS_SIZE)) { + if(hal.nvs.driver_area.size + size < (nvs_size_max - GRBL_NVS_SIZE)) { mem_address = (uint8_t *)((uint32_t)(mem_address - 1) | 0x03) + 1; // Align to word boundary addr = mem_address - nvsbuffer; mem_address += size; diff --git a/report.c b/report.c index 3f615a4c..d105292c 100644 --- a/report.c +++ b/report.c @@ -270,6 +270,10 @@ void report_message (const char *msg, message_type_t type) hal.stream.write("Warning: "); break; + case Message_Error: + hal.stream.write("Error: "); + break; + case Message_Debug: hal.stream.write("Debug: "); break; diff --git a/system.c b/system.c index aa28eabc..c8366b3b 100644 --- a/system.c +++ b/system.c @@ -683,12 +683,14 @@ static status_code_t set_startup_line (sys_state_t state, char *args, uint_fast8 status_code_t retval = Status_OK; - args = gc_normalize_block(args, NULL); + args = gc_normalize_block(args, &retval, NULL); - if(strlen(args) >= (sizeof(stored_line_t) - 1)) - retval = Status_Overflow; - else if ((retval = gc_execute_block(args)) == Status_OK) // Execute gcode block to ensure block is valid. - settings_write_startup_line(lnr, args); + if(retval == Status_OK) { + if(strlen(args) >= (sizeof(stored_line_t) - 1)) + retval = Status_Overflow; + else if ((retval = gc_execute_block(args)) == Status_OK) // Execute gcode block to ensure block is valid. + settings_write_startup_line(lnr, args); + } return retval; } From 2c889116bebbb56ba4b7078fdb29484c2091833f Mon Sep 17 00:00:00 2001 From: Terje Io Date: Wed, 30 Oct 2024 13:34:44 +0700 Subject: [PATCH 22/33] Added init call for new ESP-AT plugin. --- changelog.md | 18 +++++++++++++++++- plugins_init.h | 5 +++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index 4b1d6e9c..cb0346a8 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,19 @@ ## grblHAL changelog +20241030 + +Core: + +* Added init call for new ESP-AT plugin. + +Plugins: + +* Motors: fixed incorrect settings reference. Ref. [discussion #107](https://github.com/grblHAL/ESP32/discussions/107). + +* Misc. plugins, esp_at: added experimental support for Telnet over WiFi via an ESP32 running [ESP-AT](https://docs.espressif.com/projects/esp-at/en/latest/esp32/Get_Started/index.html). + +--- + Build 20241025 Core: @@ -17,13 +31,15 @@ Terminates gcode program, outputs message and returns error 253. Drivers: +* ESP32, RP2040: changed NVS storage for settings in flash from 2 to 4KB. + * STM32F4xx: fixed typos. * Some: added note to _platformio.ino_ file. Plugins: -* SD Card, macros: fixed G65P1 settings read macro when reading some indexed settings. +* SD Card, macros: fixed G65P1 settings read macro, failed when reading some indexed settings. --- diff --git a/plugins_init.h b/plugins_init.h index 8521056e..74690afb 100644 --- a/plugins_init.h +++ b/plugins_init.h @@ -73,6 +73,11 @@ bluetooth_init(); #endif +#if ESP_AT_ENABLE + extern void esp_at_init (void); + esp_at_init(); +#endif + #if KEYPAD_ENABLE extern bool keypad_init (void); keypad_init(); From fe2336440d6089bb014efdf7c70f04910c05b3f6 Mon Sep 17 00:00:00 2001 From: Terje Io Date: Thu, 7 Nov 2024 20:44:16 +0100 Subject: [PATCH 23/33] Removed deprecated stream flags, added stream event for line state (RTS, DTR) changes - initially for USB streams. --- README.md | 2 +- changelog.md | 20 ++++++++++++++++++++ grbl.h | 2 +- stream.c | 1 - stream.h | 27 +++++++++++++++++++++------ 5 files changed, 43 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index e1f79c26..b288b619 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ It has been written to complement grblHAL and has features such as proper keyboa --- -Latest build date is 20241025, see the [changelog](changelog.md) for details. +Latest build date is 20241107, see the [changelog](changelog.md) for details. __NOTE:__ Build 20240222 has moved the probe input to the ioPorts pool of inputs and will be allocated from it when configured. The change is major and _potentially dangerous_, it may damage your probe, so please _verify correct operation_ after installing this, or later, builds. diff --git a/changelog.md b/changelog.md index cb0346a8..ba8195be 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,25 @@ ## grblHAL changelog +20241107 + +Core: + +* Removed deprecated stream flags, added stream event for line state \(RTS, DTR\) changes - initially for USB streams. + +Drivers: + +* Many: updated for removal of deprecated stream flags in the core. + +* STM32 drivers: added support for line state changed event. + +Plugins: + +* Trinamic: fix for incorrect min/max stepper current validation for TMC2130 and TMC2209. Ref. STM32F4xx [issue #197](https://github.com/grblHAL/STM32F4xx/issues/197). + +* Networking: updated WebSocket daemon for removal of deprecated stream flags in the core. + +--- + 20241030 Core: diff --git a/grbl.h b/grbl.h index 7453baec..76ddacab 100644 --- a/grbl.h +++ b/grbl.h @@ -42,7 +42,7 @@ #else #define GRBL_VERSION "1.1f" #endif -#define GRBL_BUILD 20241025 +#define GRBL_BUILD 20241107 #define GRBL_URL "https://github.com/grblHAL" diff --git a/stream.c b/stream.c index 96faf709..0152e43e 100644 --- a/stream.c +++ b/stream.c @@ -63,7 +63,6 @@ static const io_stream_properties_t null_stream = { .instance = 0, .flags.claimable = On, .flags.claimed = Off, - .flags.connected = On, .flags.can_set_baud = On, .claim = stream_null_init }; diff --git a/stream.h b/stream.h index 8a3983f1..9e81619a 100644 --- a/stream.h +++ b/stream.h @@ -3,7 +3,7 @@ Part of grblHAL - Copyright (c) 2019-2023 Terje Io + Copyright (c) 2019-2024 Terje Io grblHAL is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -91,6 +91,15 @@ typedef enum { StreamType_Null } stream_type_t; +typedef union { + uint8_t value; + struct { + uint8_t dtr :1, + rts :1, + unused :6; + }; +} serial_linestate_t; + /*! \brief Pointer to function for getting stream connected status. \returns \a true connected, \a false otherwise. */ @@ -201,26 +210,31 @@ for handing feed-holds, overrides, soft resets etc. */ typedef bool (*disable_rx_stream_ptr)(bool disable); +/*! \brief Pointer to function for handling line state changed events. + +\param \a serial_linestate_t enum. +*/ +typedef void (*on_linestate_changed_ptr)(serial_linestate_t state); + typedef union { uint8_t value; struct { - uint8_t connected :1, //!< deprecated - claimable :1, + uint8_t claimable :1, claimed :1, can_set_baud :1, rx_only :1, modbus_ready :1, rts_handshake :1, - unused :1; + unused :2; }; } io_stream_flags_t; typedef union { uint8_t value; struct { - uint8_t connected :1, - webui_connected :1, + uint8_t webui_connected :1, is_usb :1, + linestate_event :1, //!< Set when driver supports on_linestate_changed event. unused :5; }; } io_stream_state_t; @@ -247,6 +261,7 @@ typedef struct { get_stream_buffer_count_ptr get_tx_buffer_count; //!< Optional handler for getting number of characters in the output buffer(s). Count shall include any unsent characters in any transmit FIFO and/or transmit register. Required for Modbus support. flush_stream_buffer_ptr reset_write_buffer; //!< Optional handler for flushing the output buffer. Any transmit FIFO shall be flushed as well. Required for Modbus support. set_baud_rate_ptr set_baud_rate; //!< Optional handler for setting the stream baud rate. Required for Modbus support, recommended for Bluetooth support. + on_linestate_changed_ptr on_linestate_changed; //!< Optional handler to be called when line state changes. Set by client. vfs_file_t *file; //!< File handle, non-null if streaming from a file. } io_stream_t; From e769418b1b5fa1fe45cd5c95d605fdecd3f78843 Mon Sep 17 00:00:00 2001 From: Terje Io Date: Thu, 7 Nov 2024 21:04:25 +0100 Subject: [PATCH 24/33] Updated changelog --- changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index ba8195be..47ef8a2b 100644 --- a/changelog.md +++ b/changelog.md @@ -1,6 +1,6 @@ ## grblHAL changelog -20241107 +Build 20241107 Core: From a29ae437b656dcf90bbcff7c07791304fd46882d Mon Sep 17 00:00:00 2001 From: skasti Date: Sat, 9 Nov 2024 15:55:11 +0100 Subject: [PATCH 25/33] Move substitution to a grbl core handler. Move setting of string registers to onGcodeComment --- core_handlers.h | 3 + gcode.c | 56 +++---------- ngc_expr.c | 62 +++++++------- ngc_expr.h | 3 +- ngc_flowctrl.c | 25 +++--- string_registers.c | 195 ++++++++++++++++++++++++++++++++++++++++++--- string_registers.h | 11 ++- 7 files changed, 251 insertions(+), 104 deletions(-) diff --git a/core_handlers.h b/core_handlers.h index e4e138bd..656f3c94 100644 --- a/core_handlers.h +++ b/core_handlers.h @@ -133,6 +133,8 @@ typedef bool (*write_tool_data_ptr)(tool_data_t *tool_data); typedef bool (*read_tool_data_ptr)(tool_id_t tool_id, tool_data_t *tool_data); typedef bool (*clear_tool_data_ptr)(void); +typedef char* (*on_string_substitution_ptr)(char* input, char** output); + typedef struct { uint32_t n_tools; tool_data_t *tool; //!< Array of tool data, size _must_ be n_tools + 1 @@ -244,6 +246,7 @@ typedef struct { on_set_axis_setting_unit_ptr on_set_axis_setting_unit; on_gcode_message_ptr on_gcode_message; //!< Called on output of message parsed from gcode. NOTE: string pointed to is freed after this call. on_gcode_message_ptr on_gcode_comment; //!< Called when a plain gcode comment has been parsed. + on_string_substitution_ptr on_string_substitution; //!< Called when something wants to process a string for param substitution or similar. on_tool_selected_ptr on_tool_selected; //!< Called prior to executing M6 or after executing M61. on_tool_changed_ptr on_tool_changed; //!< Called after executing M6 or M61. on_toolchange_ack_ptr on_toolchange_ack; //!< Called from interrupt context. diff --git a/gcode.c b/gcode.c index 02a8df6a..c2a641a9 100644 --- a/gcode.c +++ b/gcode.c @@ -352,6 +352,10 @@ void gc_init (void) #if NGC_EXPRESSIONS_ENABLE ngc_flowctrl_init(); + #if STRING_REGISTERS_ENABLE + string_registers_init(); + #endif + ngc_expr_init(); #endif #if NGC_PARAMETERS_ENABLE ngc_modal_state_invalidate(); @@ -577,14 +581,6 @@ char *gc_normalize_block (char *block, status_code_t *status, char **message) if(*block == '/') block++; -#if STRING_REGISTERS_ENABLE - // If the block starts with '&' it means it is setting a string register value, - // and we should not normalize it - if(*block == '&') { - return block; - } -#endif - s1 = s2 = block; while((c = *s1) != '\0') { @@ -611,14 +607,16 @@ char *gc_normalize_block (char *block, status_code_t *status, char **message) if(message && *message == NULL) { #if NGC_EXPRESSIONS_ENABLE if(!strncasecmp(comment, "DEBUG,", 6)) { // Debug message string substitution - if(settings.flags.ngc_debug_out) { + if(settings.flags.ngc_debug_out && grbl.on_string_substitution) { comment += 6; - ngc_substitute_parameters(comment, message); + grbl.on_string_substitution(comment, message); } *comment = '\0'; // Do not generate grbl.on_gcode_comment event! } else if(!strncasecmp(comment, "PRINT,", 6)) { // Print message string substitution - comment += 6; - ngc_substitute_parameters(comment, message); + if(grbl.on_string_substitution) { + comment += 6; + grbl.on_string_substitution(comment, message); + } *comment = '\0'; // Do not generate grbl.on_gcode_comment event! } else { #endif @@ -936,40 +934,8 @@ status_code_t gc_execute_block (char *block) FAIL(Status_GcodeUnsupportedCommand); // [For now...] #endif } -#if STRING_REGISTERS_ENABLE - } else if (letter == '&') { - if(gc_state.skip_blocks) - return Status_OK; - float register_id; - if (block[char_counter] == '[') { - if (ngc_eval_expression(block, &char_counter, ®ister_id) != Status_OK) { - FAIL(Status_ExpressionSyntaxError); // [Invalid expression syntax] - } - } else if (!read_float(block, &char_counter, ®ister_id)) { - FAIL(Status_BadNumberFormat); // [Expected register id] - } - - if (block[char_counter++] != '=') { - FAIL(Status_BadNumberFormat); // [Expected equal sign] - } - - char *strValue; - substitute_parameters(&block[char_counter++], &strValue); - report_message(strValue, Message_Debug); - - if (!string_register_set((string_register_id_t)register_id, strValue)) { - free(strValue); - FAIL(Status_ExpressionInvalidArgument); // [Invalid value after '='] - } else { - free(strValue); - } - - // setting a string-register consumes the rest of this block - break; - } -#else } -#endif + if((gc_block.words.mask & o_label.mask) && (gc_block.words.mask & ~o_label.mask) == 0) { char_counter--; return ngc_flowctrl(gc_block.values.o, block, &char_counter, &gc_state.skip_blocks); diff --git a/ngc_expr.c b/ngc_expr.c index 6343ac99..db6ddad8 100644 --- a/ngc_expr.c +++ b/ngc_expr.c @@ -31,11 +31,7 @@ #include "settings.h" #include "ngc_expr.h" #include "ngc_params.h" - -#if STRING_REGISTERS_ENABLE -#include "string_registers.h" -#include "messages.h" -#endif +#include "core_handlers.h" #define MAX_STACK 7 @@ -80,6 +76,32 @@ typedef enum { NGCUnaryOp_Parameter // read setting/setting bit } ngc_unary_op_t; +static on_string_substitution_ptr on_string_substitution; + +char* onStringSubstitution(char *input, char **output) { + char* result; + if (on_string_substitution) { + char *intermediate; + on_string_substitution(input, &intermediate); + result = ngc_substitute_parameters(intermediate, output); + free(intermediate); + } else { + result = ngc_substitute_parameters(input, output); + } + + return result; +} + +void ngc_expr_init(void) { + static bool init_ok = false; + + if(!init_ok) { + init_ok = true; + on_string_substitution = grbl.on_string_substitution; + grbl.on_string_substitution = onStringSubstitution; + } +} + /*! \brief Executes the operations: /, MOD, ** (POW), *. \param lhs pointer to the left hand side operand and result. @@ -1001,9 +1023,6 @@ char *ngc_substitute_parameters (char *comment, char **message) size_t len = 0; float value; char *s, c; -#if STRING_REGISTERS_ENABLE - char *strValue; -#endif uint_fast8_t char_counter = 0; int8_t parse_format = 0; uint8_t decimals = ngc_float_decimals(); // LinuxCNC is 1 (or l?) @@ -1027,19 +1046,6 @@ char *ngc_substitute_parameters (char *comment, char **message) len += strlen(decimals ? ftoa(value, decimals) : trim_float(ftoa(value, decimals))); else len += 3; // "N/A" -#if STRING_REGISTERS_ENABLE - } else if (c == '&') { - if(read_parameter(comment, &char_counter, &value) == Status_OK) { - if (string_register_get((string_register_id_t)value, &strValue)) { - len += strlen(strValue); - } else { - len += 3; // "N/A" - } - } else { - len += 3; // "N/A" - report_message("unable to parse string register id", Message_Warning); - } -#endif } else len++; } @@ -1072,20 +1078,6 @@ char *ngc_substitute_parameters (char *comment, char **message) else strcat(s, "N/A"); s = strchr(s, '\0'); -#if STRING_REGISTERS_ENABLE - } else if (c == '&') { - if(read_parameter(comment, &char_counter, &value) == Status_OK) { - if (string_register_get((string_register_id_t)value, &strValue)) { - strcat(s, strValue); - } else { - strcat(s, "N/A"); - } - } else { - strcat(s, "N/A"); - report_message("unable to parse string register id", Message_Warning); - } - s = strchr(s, '\0'); -#endif } else { *s++ = c; *s = '\0'; diff --git a/ngc_expr.h b/ngc_expr.h index d57678a0..9156cd82 100644 --- a/ngc_expr.h +++ b/ngc_expr.h @@ -9,7 +9,6 @@ status_code_t ngc_read_integer_value(char *line, uint_fast8_t *pos, int32_t *val status_code_t ngc_read_integer_unsigned (char *line, uint_fast8_t *pos, uint32_t *value); status_code_t ngc_read_parameter (char *line, uint_fast8_t *pos, float *value, bool check); status_code_t ngc_eval_expression (char *line, uint_fast8_t *pos, float *value); -/**/ -char *ngc_substitute_parameters (char *comment, char **message); +void ngc_expr_init(void); #endif diff --git a/ngc_flowctrl.c b/ngc_flowctrl.c index 749b8a75..c71be536 100644 --- a/ngc_flowctrl.c +++ b/ngc_flowctrl.c @@ -297,20 +297,23 @@ void ngc_flowctrl_unwind_stack (vfs_file_t *file) static status_code_t onGcodeComment (char *comment) { - uint_fast8_t pos = 6; - status_code_t status = Status_OK; - if(!strncasecmp(comment, "ABORT,", 6)) { - char *buf = NULL; - if(ngc_substitute_parameters(comment + pos, &buf)) { - report_message(buf, Message_Error); - free(buf); + uint_fast8_t pos = 6; + if (grbl.on_string_substitution) { + char *buf = NULL; + if (grbl.on_string_substitution(comment + pos, &buf)) { + report_message(buf, Message_Error); + free(buf); + } + } else { + report_message(comment + pos, Message_Error); } - status = Status_UserException; - } else if(on_gcode_comment) - status = on_gcode_comment(comment); + return Status_UserException; + } else if(on_gcode_comment) { + return on_gcode_comment(comment); + } - return status; + return Status_OK; } void ngc_flowctrl_init (void) diff --git a/string_registers.c b/string_registers.c index ae276d95..a2bcacef 100644 --- a/string_registers.c +++ b/string_registers.c @@ -32,12 +32,17 @@ #include "system.h" #include "settings.h" #include "ngc_params.h" +#include "ngc_expr.h" #include "string_registers.h" #ifndef MAX_SR_LENGTH // 256 is max block-length in gcode, so probably reasonable #define MAX_SR_LENGTH 256 #endif + +static on_gcode_message_ptr on_gcode_comment; +static on_string_substitution_ptr on_string_substitution; + typedef struct string_register { string_register_id_t id; struct string_register *next; @@ -48,7 +53,6 @@ static string_register_t *string_registers = NULL; string_register_t *find_string_register_with_last (string_register_id_t id, string_register_t **last_register) { string_register_t *current_register = string_registers; - int i = 0; while(current_register != NULL) { if(current_register->id == id) { @@ -67,26 +71,25 @@ string_register_t *find_string_register (string_register_id_t id) { return find_string_register_with_last(id, &last); } -bool string_register_get (string_register_id_t id, char **value) { +string_register_result_t string_register_get (string_register_id_t id, char **value) { string_register_t *string_register = find_string_register(id); if (string_register != NULL) { *value = &string_register->value[0]; - return true; + return SR_OK; } - return false; + return SR_NOT_FOUND; } bool string_register_exists (string_register_id_t id) { return find_string_register(id) != NULL; } -bool string_register_set (ngc_param_id_t id, char *value) { +string_register_result_t string_register_set (ngc_param_id_t id, char *value) { size_t length = strlen(value); if (length > MAX_SR_LENGTH) { - report_message("String register values cannot be longer than 40 characters", Message_Warning); - return false; + return SR_VALUE_TOO_LONG; } string_register_t *last_register = NULL; @@ -114,10 +117,184 @@ bool string_register_set (ngc_param_id_t id, char *value) { string_registers = string_register; } - return true; + return SR_OK; + } + + return SR_FAILED; +} + +status_code_t read_register_id(char* comment, uint_fast8_t* char_counter, string_register_id_t* value) { + float register_id; + if (comment[*char_counter] == '[') { + if (ngc_eval_expression(comment, char_counter, ®ister_id) != Status_OK) { + return Status_ExpressionSyntaxError; // [Invalid expression syntax] + } + } else if (!read_float(comment, char_counter, ®ister_id)) { + return Status_BadNumberFormat; // [Expected register id] } - return false; + *value = (string_register_id_t)register_id; + return Status_OK; +} + +/*! \brief Substitute references to string-registers in a string with their values. + +_NOTE:_ The returned string must be freed by the caller. + +\param comment pointer to the original comment string. +\param message pointer to a char pointer to receive the resulting string. +*/ +char *sr_substitute_parameters (char *comment, char **message) +{ + size_t len = 0; + string_register_id_t registerId; + char *s, c; + uint_fast8_t char_counter = 0; + + // Trim leading spaces + while(*comment == ' ') + comment++; + + // Calculate length of substituted string + while((c = comment[char_counter++])) { + if (c == '&') { + if(read_register_id(comment, &char_counter, ®isterId) == Status_OK) { + char *strValue; + if (string_register_get(registerId, &strValue) == SR_OK) { + len += strlen(strValue); + free(strValue); + } else { + len += 3; // "N/A" + } + } else { + len += 3; // "N/A" + report_message("unable to parse string register id", Message_Warning); + } + } else + len++; + } + + // Perform substitution + if((s = *message = malloc(len + 1))) { + *s = '\0'; + char_counter = 0; + + while((c = comment[char_counter++])) { + if (c == '&') { + if(read_register_id(comment, &char_counter, ®isterId) == Status_OK) { + char *strValue; + if (string_register_get(registerId, &strValue) == SR_OK) { + strcat(s, strValue); + free(strValue); + } else { + strcat(s, "N/A"); + } + } else { + strcat(s, "N/A"); + report_message("unable to parse string register id", Message_Warning); + } + s = strchr(s, '\0'); + } else { + *s++ = c; + *s = '\0'; + } + } + } + + return *message; +} + +status_code_t superOnGcodeComment(char* comment) { + if(on_gcode_comment) { + return on_gcode_comment(comment); + } else { + return Status_OK; + } +} + +static status_code_t onGcodeComment (char *comment) +{ + uint_fast8_t char_counter = 0; + if (comment[char_counter++] == '&') { + if(gc_state.skip_blocks) + return Status_OK; + + string_register_id_t registerId; + if (read_register_id(comment, &char_counter, ®isterId) != Status_OK) + { + return Status_ExpressionSyntaxError; // [Expected equal sign] + } + + if (comment[char_counter] != '=') { + return Status_ExpressionSyntaxError; // [Expected equal sign] + } + + bool shouldFree = false; + char *strValue; + string_register_result_t srResult; + if (grbl.on_string_substitution) { + shouldFree = true; + grbl.on_string_substitution(&comment[char_counter++], &strValue); + srResult = string_register_set(registerId, strValue); + } else { + strValue = &comment[char_counter++]; + srResult = string_register_set(registerId, strValue); + } + + switch (srResult) + { + case SR_FAILED: + report_message(strValue, Message_Debug); + report_message("Unable to set string register", Message_Error); + if (shouldFree) { + free(strValue); + } + return Status_Unhandled; // [Some error setting new value] + case SR_VALUE_TOO_LONG: + report_message(strValue, Message_Debug); + report_message("Unable to set string register: New value too long", Message_Error); + if (shouldFree) { + free(strValue); + } + return Status_ExpressionInvalidArgument; // [Invalid value after '='] + default: + if (shouldFree) { + free(strValue); + } + break; + } + + return Status_OK; + } + + return superOnGcodeComment(comment); +} + +char* onStringSubstitution(char *input, char **output) { + char* result; + if (on_string_substitution) { + char *intermediate; + on_string_substitution(input, &intermediate); + result = sr_substitute_parameters(intermediate, output); + free(intermediate); + } else { + result = sr_substitute_parameters(input, output); + } + + return result; +} + +void string_registers_init (void) +{ + static bool init_ok = false; + + if(!init_ok) { + init_ok = true; + on_gcode_comment = grbl.on_gcode_comment; + grbl.on_gcode_comment = onGcodeComment; + on_string_substitution = grbl.on_string_substitution; + grbl.on_string_substitution = onStringSubstitution; + } } #endif // STRING_REGISTERS_ENABLE diff --git a/string_registers.h b/string_registers.h index 00ddd6de..0132b375 100644 --- a/string_registers.h +++ b/string_registers.h @@ -25,11 +25,18 @@ #include "gcode.h" +typedef enum { + SR_OK, + SR_VALUE_TOO_LONG, + SR_NOT_FOUND, + SR_FAILED +} string_register_result_t; typedef uint16_t string_register_id_t; -bool string_register_get (string_register_id_t id, char **value); -bool string_register_set (string_register_id_t id, char *value); +string_register_result_t string_register_get (string_register_id_t id, char **value); +string_register_result_t string_register_set (string_register_id_t id, char *value); bool string_register_exists (string_register_id_t id); +void string_registers_init(void); #endif // _STRING_REGISTERS_H_ From ba86b00eb5b9930baddb88075a2675dd7ae32f60 Mon Sep 17 00:00:00 2001 From: skasti Date: Sat, 9 Nov 2024 16:06:31 +0100 Subject: [PATCH 26/33] move init to the end, so the substitution function is declared first --- ngc_expr.c | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/ngc_expr.c b/ngc_expr.c index db6ddad8..21379dfd 100644 --- a/ngc_expr.c +++ b/ngc_expr.c @@ -78,30 +78,6 @@ typedef enum { static on_string_substitution_ptr on_string_substitution; -char* onStringSubstitution(char *input, char **output) { - char* result; - if (on_string_substitution) { - char *intermediate; - on_string_substitution(input, &intermediate); - result = ngc_substitute_parameters(intermediate, output); - free(intermediate); - } else { - result = ngc_substitute_parameters(input, output); - } - - return result; -} - -void ngc_expr_init(void) { - static bool init_ok = false; - - if(!init_ok) { - init_ok = true; - on_string_substitution = grbl.on_string_substitution; - grbl.on_string_substitution = onStringSubstitution; - } -} - /*! \brief Executes the operations: /, MOD, ** (POW), *. \param lhs pointer to the left hand side operand and result. @@ -1088,4 +1064,28 @@ char *ngc_substitute_parameters (char *comment, char **message) return *message; } +char* onStringSubstitution(char *input, char **output) { + char* result; + if (on_string_substitution) { + char *intermediate; + on_string_substitution(input, &intermediate); + result = ngc_substitute_parameters(intermediate, output); + free(intermediate); + } else { + result = ngc_substitute_parameters(input, output); + } + + return result; +} + +void ngc_expr_init(void) { + static bool init_ok = false; + + if(!init_ok) { + init_ok = true; + on_string_substitution = grbl.on_string_substitution; + grbl.on_string_substitution = onStringSubstitution; + } +} + #endif From cd187dc60dd08921873c6d436981a88cebd0a140 Mon Sep 17 00:00:00 2001 From: skasti Date: Sat, 9 Nov 2024 18:08:13 +0100 Subject: [PATCH 27/33] Use different function names in the files. use correct parameter type --- ngc_expr.c | 4 ++-- string_registers.c | 19 ++++++++----------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/ngc_expr.c b/ngc_expr.c index 21379dfd..75030b09 100644 --- a/ngc_expr.c +++ b/ngc_expr.c @@ -1064,7 +1064,7 @@ char *ngc_substitute_parameters (char *comment, char **message) return *message; } -char* onStringSubstitution(char *input, char **output) { +char* onNgcParameterSubstitution(char *input, char **output) { char* result; if (on_string_substitution) { char *intermediate; @@ -1084,7 +1084,7 @@ void ngc_expr_init(void) { if(!init_ok) { init_ok = true; on_string_substitution = grbl.on_string_substitution; - grbl.on_string_substitution = onStringSubstitution; + grbl.on_string_substitution = onNgcParameterSubstitution; } } diff --git a/string_registers.c b/string_registers.c index a2bcacef..0419dbf2 100644 --- a/string_registers.c +++ b/string_registers.c @@ -86,7 +86,7 @@ bool string_register_exists (string_register_id_t id) { return find_string_register(id) != NULL; } -string_register_result_t string_register_set (ngc_param_id_t id, char *value) { +string_register_result_t string_register_set (string_register_id_t id, char *value) { size_t length = strlen(value); if (length > MAX_SR_LENGTH) { return SR_VALUE_TOO_LONG; @@ -108,7 +108,6 @@ string_register_result_t string_register_set (ngc_param_id_t id, char *value) { } strcpy(string_register->value, value); - // Update the next-pointer of the last register before this one. // If none exists, update the string_registers-pointer. if (last_register != NULL) { @@ -162,7 +161,6 @@ char *sr_substitute_parameters (char *comment, char **message) char *strValue; if (string_register_get(registerId, &strValue) == SR_OK) { len += strlen(strValue); - free(strValue); } else { len += 3; // "N/A" } @@ -185,7 +183,6 @@ char *sr_substitute_parameters (char *comment, char **message) char *strValue; if (string_register_get(registerId, &strValue) == SR_OK) { strcat(s, strValue); - free(strValue); } else { strcat(s, "N/A"); } @@ -212,7 +209,7 @@ status_code_t superOnGcodeComment(char* comment) { } } -static status_code_t onGcodeComment (char *comment) +static status_code_t onStringRegisterGcodeComment (char *comment) { uint_fast8_t char_counter = 0; if (comment[char_counter++] == '&') { @@ -225,7 +222,7 @@ static status_code_t onGcodeComment (char *comment) return Status_ExpressionSyntaxError; // [Expected equal sign] } - if (comment[char_counter] != '=') { + if (comment[char_counter++] != '=') { return Status_ExpressionSyntaxError; // [Expected equal sign] } @@ -234,10 +231,10 @@ static status_code_t onGcodeComment (char *comment) string_register_result_t srResult; if (grbl.on_string_substitution) { shouldFree = true; - grbl.on_string_substitution(&comment[char_counter++], &strValue); + grbl.on_string_substitution(comment + char_counter, &strValue); srResult = string_register_set(registerId, strValue); } else { - strValue = &comment[char_counter++]; + strValue = comment + char_counter; srResult = string_register_set(registerId, strValue); } @@ -270,7 +267,7 @@ static status_code_t onGcodeComment (char *comment) return superOnGcodeComment(comment); } -char* onStringSubstitution(char *input, char **output) { +char* onStringRegisterSubstitution(char *input, char **output) { char* result; if (on_string_substitution) { char *intermediate; @@ -291,9 +288,9 @@ void string_registers_init (void) if(!init_ok) { init_ok = true; on_gcode_comment = grbl.on_gcode_comment; - grbl.on_gcode_comment = onGcodeComment; + grbl.on_gcode_comment = onStringRegisterGcodeComment; on_string_substitution = grbl.on_string_substitution; - grbl.on_string_substitution = onStringSubstitution; + grbl.on_string_substitution = onStringRegisterSubstitution; } } From ba912fad2bd3df8bdd813b17bf54f94d28494a3e Mon Sep 17 00:00:00 2001 From: skasti Date: Wed, 13 Nov 2024 19:51:36 +0100 Subject: [PATCH 28/33] convert back to other return values --- string_registers.c | 24 ++++++++++++------------ string_registers.h | 12 ++---------- 2 files changed, 14 insertions(+), 22 deletions(-) diff --git a/string_registers.c b/string_registers.c index 0419dbf2..eb054105 100644 --- a/string_registers.c +++ b/string_registers.c @@ -71,25 +71,25 @@ string_register_t *find_string_register (string_register_id_t id) { return find_string_register_with_last(id, &last); } -string_register_result_t string_register_get (string_register_id_t id, char **value) { +bool string_register_get (string_register_id_t id, char **value) { string_register_t *string_register = find_string_register(id); if (string_register != NULL) { *value = &string_register->value[0]; - return SR_OK; + return true; } - return SR_NOT_FOUND; + return false; } bool string_register_exists (string_register_id_t id) { return find_string_register(id) != NULL; } -string_register_result_t string_register_set (string_register_id_t id, char *value) { +status_code_t string_register_set (string_register_id_t id, char *value) { size_t length = strlen(value); if (length > MAX_SR_LENGTH) { - return SR_VALUE_TOO_LONG; + return Status_ExpressionArgumentOutOfRange; } string_register_t *last_register = NULL; @@ -116,10 +116,10 @@ string_register_result_t string_register_set (string_register_id_t id, char *val string_registers = string_register; } - return SR_OK; + return Status_OK; } - return SR_FAILED; + return Status_FlowControlOutOfMemory; } status_code_t read_register_id(char* comment, uint_fast8_t* char_counter, string_register_id_t* value) { @@ -159,7 +159,7 @@ char *sr_substitute_parameters (char *comment, char **message) if (c == '&') { if(read_register_id(comment, &char_counter, ®isterId) == Status_OK) { char *strValue; - if (string_register_get(registerId, &strValue) == SR_OK) { + if (string_register_get(registerId, &strValue)) { len += strlen(strValue); } else { len += 3; // "N/A" @@ -181,7 +181,7 @@ char *sr_substitute_parameters (char *comment, char **message) if (c == '&') { if(read_register_id(comment, &char_counter, ®isterId) == Status_OK) { char *strValue; - if (string_register_get(registerId, &strValue) == SR_OK) { + if (string_register_get(registerId, &strValue)) { strcat(s, strValue); } else { strcat(s, "N/A"); @@ -228,7 +228,7 @@ static status_code_t onStringRegisterGcodeComment (char *comment) bool shouldFree = false; char *strValue; - string_register_result_t srResult; + status_code_t srResult; if (grbl.on_string_substitution) { shouldFree = true; grbl.on_string_substitution(comment + char_counter, &strValue); @@ -240,14 +240,14 @@ static status_code_t onStringRegisterGcodeComment (char *comment) switch (srResult) { - case SR_FAILED: + case Status_FlowControlOutOfMemory: report_message(strValue, Message_Debug); report_message("Unable to set string register", Message_Error); if (shouldFree) { free(strValue); } return Status_Unhandled; // [Some error setting new value] - case SR_VALUE_TOO_LONG: + case Status_ExpressionArgumentOutOfRange: report_message(strValue, Message_Debug); report_message("Unable to set string register: New value too long", Message_Error); if (shouldFree) { diff --git a/string_registers.h b/string_registers.h index 0132b375..12f2aa14 100644 --- a/string_registers.h +++ b/string_registers.h @@ -24,18 +24,10 @@ #include "gcode.h" - -typedef enum { - SR_OK, - SR_VALUE_TOO_LONG, - SR_NOT_FOUND, - SR_FAILED -} string_register_result_t; - typedef uint16_t string_register_id_t; -string_register_result_t string_register_get (string_register_id_t id, char **value); -string_register_result_t string_register_set (string_register_id_t id, char *value); +bool string_register_get (string_register_id_t id, char **value); +status_code_t string_register_set (string_register_id_t id, char *value); bool string_register_exists (string_register_id_t id); void string_registers_init(void); From 8ca467bd6a5f7edb58192fef3898534156ec318f Mon Sep 17 00:00:00 2001 From: skasti Date: Wed, 13 Nov 2024 19:52:55 +0100 Subject: [PATCH 29/33] Base string_register_id_t on ngc_param_id_t, so that they stay in sync --- string_registers.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/string_registers.h b/string_registers.h index 12f2aa14..1e18ca62 100644 --- a/string_registers.h +++ b/string_registers.h @@ -24,7 +24,7 @@ #include "gcode.h" -typedef uint16_t string_register_id_t; +typedef ngc_param_id_t string_register_id_t; bool string_register_get (string_register_id_t id, char **value); status_code_t string_register_set (string_register_id_t id, char *value); From d3e8b1d30c5961ae9c8090b517b6a3e6728aecdb Mon Sep 17 00:00:00 2001 From: skasti Date: Wed, 13 Nov 2024 19:59:03 +0100 Subject: [PATCH 30/33] simplify logic for handling setting string-registers, since it now returns status-codes itself --- string_registers.c | 37 +++++-------------------------------- 1 file changed, 5 insertions(+), 32 deletions(-) diff --git a/string_registers.c b/string_registers.c index eb054105..d57b1063 100644 --- a/string_registers.c +++ b/string_registers.c @@ -226,42 +226,15 @@ static status_code_t onStringRegisterGcodeComment (char *comment) return Status_ExpressionSyntaxError; // [Expected equal sign] } - bool shouldFree = false; - char *strValue; - status_code_t srResult; if (grbl.on_string_substitution) { - shouldFree = true; + char *strValue; grbl.on_string_substitution(comment + char_counter, &strValue); - srResult = string_register_set(registerId, strValue); + status_code_t srResult = string_register_set(registerId, strValue); + free(strValue); + return srResult; } else { - strValue = comment + char_counter; - srResult = string_register_set(registerId, strValue); + return string_register_set(registerId, comment + char_counter); } - - switch (srResult) - { - case Status_FlowControlOutOfMemory: - report_message(strValue, Message_Debug); - report_message("Unable to set string register", Message_Error); - if (shouldFree) { - free(strValue); - } - return Status_Unhandled; // [Some error setting new value] - case Status_ExpressionArgumentOutOfRange: - report_message(strValue, Message_Debug); - report_message("Unable to set string register: New value too long", Message_Error); - if (shouldFree) { - free(strValue); - } - return Status_ExpressionInvalidArgument; // [Invalid value after '='] - default: - if (shouldFree) { - free(strValue); - } - break; - } - - return Status_OK; } return superOnGcodeComment(comment); From b2786db09c4f74579071fb415f5996f64984c276 Mon Sep 17 00:00:00 2001 From: skasti Date: Thu, 14 Nov 2024 07:52:36 +0100 Subject: [PATCH 31/33] remove newline before { --- string_registers.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/string_registers.c b/string_registers.c index d57b1063..68cce4a0 100644 --- a/string_registers.c +++ b/string_registers.c @@ -217,8 +217,7 @@ static status_code_t onStringRegisterGcodeComment (char *comment) return Status_OK; string_register_id_t registerId; - if (read_register_id(comment, &char_counter, ®isterId) != Status_OK) - { + if (read_register_id(comment, &char_counter, ®isterId) != Status_OK) { return Status_ExpressionSyntaxError; // [Expected equal sign] } From 5e58e02ac09d79c5d732174ed8b328585d02a985 Mon Sep 17 00:00:00 2001 From: skasti Date: Thu, 14 Nov 2024 08:04:32 +0100 Subject: [PATCH 32/33] linting document for more consistent code style --- string_registers.c | 75 ++++++++++++++++++++++------------------------ 1 file changed, 36 insertions(+), 39 deletions(-) diff --git a/string_registers.c b/string_registers.c index 68cce4a0..591ccb90 100644 --- a/string_registers.c +++ b/string_registers.c @@ -45,17 +45,17 @@ static on_string_substitution_ptr on_string_substitution; typedef struct string_register { string_register_id_t id; - struct string_register *next; + struct string_register* next; char value[1]; } string_register_t; -static string_register_t *string_registers = NULL; +static string_register_t* string_registers = NULL; -string_register_t *find_string_register_with_last (string_register_id_t id, string_register_t **last_register) { - string_register_t *current_register = string_registers; +string_register_t* find_string_register_with_last(string_register_id_t id, string_register_t** last_register) { + string_register_t* current_register = string_registers; - while(current_register != NULL) { - if(current_register->id == id) { + while (current_register != NULL) { + if (current_register->id == id) { return current_register; } else { *last_register = current_register; @@ -66,13 +66,13 @@ string_register_t *find_string_register_with_last (string_register_id_t id, stri return NULL; } -string_register_t *find_string_register (string_register_id_t id) { - string_register_t *last = NULL; +string_register_t* find_string_register(string_register_id_t id) { + string_register_t* last = NULL; return find_string_register_with_last(id, &last); } -bool string_register_get (string_register_id_t id, char **value) { - string_register_t *string_register = find_string_register(id); +bool string_register_get(string_register_id_t id, char** value) { + string_register_t* string_register = find_string_register(id); if (string_register != NULL) { *value = &string_register->value[0]; @@ -82,18 +82,18 @@ bool string_register_get (string_register_id_t id, char **value) { return false; } -bool string_register_exists (string_register_id_t id) { +bool string_register_exists(string_register_id_t id) { return find_string_register(id) != NULL; } -status_code_t string_register_set (string_register_id_t id, char *value) { +status_code_t string_register_set(string_register_id_t id, char* value) { size_t length = strlen(value); if (length > MAX_SR_LENGTH) { return Status_ExpressionArgumentOutOfRange; } - string_register_t *last_register = NULL; - string_register_t *string_register = find_string_register_with_last(id, &last_register); + string_register_t* last_register = NULL; + string_register_t* string_register = find_string_register_with_last(id, &last_register); bool isNew = string_register == NULL; @@ -126,10 +126,10 @@ status_code_t read_register_id(char* comment, uint_fast8_t* char_counter, string float register_id; if (comment[*char_counter] == '[') { if (ngc_eval_expression(comment, char_counter, ®ister_id) != Status_OK) { - return Status_ExpressionSyntaxError; // [Invalid expression syntax] + return Status_ExpressionSyntaxError; // [Invalid expression syntax] } } else if (!read_float(comment, char_counter, ®ister_id)) { - return Status_BadNumberFormat; // [Expected register id] + return Status_BadNumberFormat; // [Expected register id] } *value = (string_register_id_t)register_id; @@ -143,22 +143,21 @@ _NOTE:_ The returned string must be freed by the caller. \param comment pointer to the original comment string. \param message pointer to a char pointer to receive the resulting string. */ -char *sr_substitute_parameters (char *comment, char **message) -{ +char* sr_substitute_parameters(char* comment, char** message) { size_t len = 0; string_register_id_t registerId; - char *s, c; + char* s, c; uint_fast8_t char_counter = 0; // Trim leading spaces - while(*comment == ' ') + while (*comment == ' ') comment++; // Calculate length of substituted string - while((c = comment[char_counter++])) { + while ((c = comment[char_counter++])) { if (c == '&') { - if(read_register_id(comment, &char_counter, ®isterId) == Status_OK) { - char *strValue; + if (read_register_id(comment, &char_counter, ®isterId) == Status_OK) { + char* strValue; if (string_register_get(registerId, &strValue)) { len += strlen(strValue); } else { @@ -173,14 +172,14 @@ char *sr_substitute_parameters (char *comment, char **message) } // Perform substitution - if((s = *message = malloc(len + 1))) { + if ((s = *message = malloc(len + 1))) { *s = '\0'; char_counter = 0; - while((c = comment[char_counter++])) { + while ((c = comment[char_counter++])) { if (c == '&') { - if(read_register_id(comment, &char_counter, ®isterId) == Status_OK) { - char *strValue; + if (read_register_id(comment, &char_counter, ®isterId) == Status_OK) { + char* strValue; if (string_register_get(registerId, &strValue)) { strcat(s, strValue); } else { @@ -202,31 +201,30 @@ char *sr_substitute_parameters (char *comment, char **message) } status_code_t superOnGcodeComment(char* comment) { - if(on_gcode_comment) { + if (on_gcode_comment) { return on_gcode_comment(comment); } else { return Status_OK; } } -static status_code_t onStringRegisterGcodeComment (char *comment) -{ +static status_code_t onStringRegisterGcodeComment(char* comment) { uint_fast8_t char_counter = 0; if (comment[char_counter++] == '&') { - if(gc_state.skip_blocks) + if (gc_state.skip_blocks) return Status_OK; string_register_id_t registerId; if (read_register_id(comment, &char_counter, ®isterId) != Status_OK) { - return Status_ExpressionSyntaxError; // [Expected equal sign] + return Status_ExpressionSyntaxError; // [Expected equal sign] } if (comment[char_counter++] != '=') { - return Status_ExpressionSyntaxError; // [Expected equal sign] + return Status_ExpressionSyntaxError; // [Expected equal sign] } if (grbl.on_string_substitution) { - char *strValue; + char* strValue; grbl.on_string_substitution(comment + char_counter, &strValue); status_code_t srResult = string_register_set(registerId, strValue); free(strValue); @@ -239,10 +237,10 @@ static status_code_t onStringRegisterGcodeComment (char *comment) return superOnGcodeComment(comment); } -char* onStringRegisterSubstitution(char *input, char **output) { +char* onStringRegisterSubstitution(char* input, char** output) { char* result; if (on_string_substitution) { - char *intermediate; + char* intermediate; on_string_substitution(input, &intermediate); result = sr_substitute_parameters(intermediate, output); free(intermediate); @@ -253,11 +251,10 @@ char* onStringRegisterSubstitution(char *input, char **output) { return result; } -void string_registers_init (void) -{ +void string_registers_init(void) { static bool init_ok = false; - if(!init_ok) { + if (!init_ok) { init_ok = true; on_gcode_comment = grbl.on_gcode_comment; grbl.on_gcode_comment = onStringRegisterGcodeComment; From 8beb863ef345e47433292936099d0fd4b0724f14 Mon Sep 17 00:00:00 2001 From: skasti Date: Thu, 14 Nov 2024 08:05:20 +0100 Subject: [PATCH 33/33] linting header-file for consistent code-style --- string_registers.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/string_registers.h b/string_registers.h index 1e18ca62..61266b3b 100644 --- a/string_registers.h +++ b/string_registers.h @@ -26,9 +26,9 @@ typedef ngc_param_id_t string_register_id_t; -bool string_register_get (string_register_id_t id, char **value); -status_code_t string_register_set (string_register_id_t id, char *value); -bool string_register_exists (string_register_id_t id); +bool string_register_get(string_register_id_t id, char** value); +status_code_t string_register_set(string_register_id_t id, char* value); +bool string_register_exists(string_register_id_t id); void string_registers_init(void); #endif // _STRING_REGISTERS_H_