Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add experimental support for string registers #603

Open
wants to merge 34 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
fe9b61a
use read_real_value for return statements, so that the returned value…
skasti Sep 26, 2024
4836af9
if no return-value is read, set _value to 0.0f so that we don't carry…
skasti Sep 26, 2024
b148a09
Initial attempt at adding string registers backend-functionality
skasti Oct 9, 2024
33bfb1a
fix warnings from build
skasti Oct 9, 2024
9b2d7b6
rename from ngc_string_registers to string_registers,
skasti Oct 9, 2024
3b05088
remove debug-messages
skasti Oct 9, 2024
58b66f4
Allow setting string-registers using expression
skasti Oct 9, 2024
6b3f6dd
allow exressions
skasti Oct 9, 2024
efe1a6b
combine ifs
skasti Oct 9, 2024
d4951ff
Do not allow setting string registers to values longer than 40 charac…
skasti Oct 9, 2024
3782260
Substitute characters before creating a string register. This allows …
skasti Oct 9, 2024
be6d916
use ampersand as the special character
skasti Oct 10, 2024
9c95b8f
Update copyright header of string_registers.c
skasti Oct 13, 2024
78d8458
cleaning up some leftovers from params, and renaming to MAX_SR_LENGTH
skasti Oct 13, 2024
e6979fb
some code style changes
skasti Oct 13, 2024
59952af
Ensure string registers are not enabled by default, since this is exp…
skasti Oct 13, 2024
dea24e3
reverting stuf from other branch
skasti Oct 23, 2024
012950c
Use realloc to allocate new memory.
skasti Oct 23, 2024
4102648
Set max-length to 256
skasti Oct 23, 2024
072fdb3
Shift neopixel bit pattern
dresco Oct 25, 2024
f830979
Changed _vminor named parameter to contain build date in YYMMDD forma…
terjeio Oct 27, 2024
2c88911
Added init call for new ESP-AT plugin.
terjeio Oct 30, 2024
fe23364
Removed deprecated stream flags, added stream event for line state (R…
terjeio Nov 7, 2024
e769418
Updated changelog
terjeio Nov 7, 2024
a29ae43
Move substitution to a grbl core handler. Move setting of string regi…
skasti Nov 9, 2024
c4febb7
Merge branch 'master' into string-registers
skasti Nov 9, 2024
ba86b00
move init to the end, so the substitution function is declared first
skasti Nov 9, 2024
cd187dc
Use different function names in the files. use correct parameter type
skasti Nov 9, 2024
ba912fa
convert back to other return values
skasti Nov 13, 2024
8ca467b
Base string_register_id_t on ngc_param_id_t, so that they stay in sync
skasti Nov 13, 2024
d3e8b1d
simplify logic for handling setting string-registers, since it now re…
skasti Nov 13, 2024
b2786db
remove newline before {
skasti Nov 14, 2024
5e58e02
linting document for more consistent code style
skasti Nov 14, 2024
8beb863
linting header-file for consistent code-style
skasti Nov 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions config.h
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,14 @@ Set to \ref On or 1 to enable experimental support for parameters.
#define NGC_PARAMETERS_ENABLE On
#endif

/*! \def STRING_REGISTERS_ENABLE
\brief
Set to \ref On or 1 to enable experimental support for string registers.
*/
#if !defined STRING_REGISTERS_ENABLE || defined __DOXYGEN__
#define STRING_REGISTERS_ENABLE Off
#endif

/*! \def NGC_N_ASSIGN_PARAMETERS_PER_BLOCK
\brief
Maximum number of parameters allowed in a block.
Expand Down
3 changes: 3 additions & 0 deletions core_handlers.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down
18 changes: 14 additions & 4 deletions gcode.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -348,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();
Expand Down Expand Up @@ -599,14 +607,16 @@ char *gc_normalize_block (char *block, status_code_t *status, char **message)
if(message && *message == NULL) {
#if NGC_EXPRESSIONS_ENABLE
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@terjeio Should handling of (DEBUG, and (PRINT, be moved to ngc_flowctrl's onGcodeComment? 🤔

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. Since substitution is done in ngc_expr.c it belongs there, and also because the grbl.on_gcode_comment() event is not able to return a string (and should not be changed to accomodate that).

Your grbl.on_string_substitution() event could be set up at startup to point to a new function in ngc_expr.c, making it overridable. And then your string register handling could (or rather should?) be moved to a plugin, in this repo? grbl.on_string_substitution has to be changed to a more descriptive name if doing so...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aha, maybe I should make a separate PR with just the string substitution-stuff, and move string registers to a plugin-repo? 🤔

Copy link
Contributor

@terjeio terjeio Nov 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The previous comment was somehow posted before I finished, trying again:

Aha, maybe I should make a separate PR with just the string substitution-stuff, and move string registers to a plugin-repo?

I'll update the core, you add a plugin for string registers and string substitution that includes string registers. This since I'll make comment handling completely overridable even for (MSG, ...), in gcode.c:

            case ')':
                if(comment && !gc_state.skip_blocks) {
                    *s1 = '\0';
                    if(!hal.driver_cap.no_gcode_message_handling) {

                        if(message && *message == NULL) {

                            if(grbl.on_process_gcode_comment)
                                *message = grbl.on_process_gcode_comment(comment);

                            if(*message == NULL) {
                                size_t len = s1 - comment - 3;

                                if(!strncasecmp(comment, "MSG,", 4) && (*message = malloc(len))) {

                                    comment += 4;
                                    while(*comment == ' ') {
                                        comment++;
                                        len--;
                                    }
                                    memcpy(*message, comment, len);
                                }
                            }
                        }
                    }
                    if(*comment && *message == NULL && grbl.on_gcode_comment)
                        *status = grbl.on_gcode_comment(comment);
                }
                comment = NULL;
                break;

grbl.on_process_gcode_comment will be defaulted to handle (PRINT, ..) and (DEBUG, ...) when expressions is enabled.
You can choose to do string replacements only and use the default handler for numeric ones, or replace the handler completely. Note that the grbl.on_process_gcode_comment signature does not allow for a status code return - this is deliberate since message comments should never fail with an error.

You may choose where to publish a string register plugin, you can add it to your own repo or make a PR for the misc plugins repo. The Web Builder can build with repos located outside grblHAL, but local builds cannot without manually adding your code to the source tree - at least not without adding it as a submodule which I am reluctant to do.

FYI I have already added string parameter support to ngc_param.c (not yet comitted) in order to handle named o calls, you may build string registers on top of this or add your version to your plugin. It is different from your string register code in that it does not return status codes and it will remove a string parameter on failure to allocate for it. Also, it will not reallocate on changes if the new length is less than the previous, this as an attempt to reduce heap fragmentation.

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
Expand Down
27 changes: 27 additions & 0 deletions ngc_expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "settings.h"
#include "ngc_expr.h"
#include "ngc_params.h"
#include "core_handlers.h"

#define MAX_STACK 7

Expand Down Expand Up @@ -75,6 +76,8 @@ typedef enum {
NGCUnaryOp_Parameter // read setting/setting bit
} ngc_unary_op_t;

static on_string_substitution_ptr on_string_substitution;

/*! \brief Executes the operations: /, MOD, ** (POW), *.

\param lhs pointer to the left hand side operand and result.
Expand Down Expand Up @@ -1061,4 +1064,28 @@ char *ngc_substitute_parameters (char *comment, char **message)
return *message;
}

char* onNgcParameterSubstitution(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 = onNgcParameterSubstitution;
}
}

#endif
3 changes: 1 addition & 2 deletions ngc_expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
25 changes: 14 additions & 11 deletions ngc_flowctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Loading