From 25ac3dab2d72eb1b685293faf2045c4faeaf95d1 Mon Sep 17 00:00:00 2001 From: Hannes Diethelm Date: Wed, 3 Jun 2026 11:41:50 +0200 Subject: [PATCH 1/5] Revert "motion: avoid duplicate terminal outputs for RTAPI_MSG_ERROR messages" This reverts commit 47324a78687b6edf667129e5b261883ba6e8927e. --- src/emc/motion/motion.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/emc/motion/motion.c b/src/emc/motion/motion.c index 97054ec3f1d..26ec530ddac 100644 --- a/src/emc/motion/motion.c +++ b/src/emc/motion/motion.c @@ -218,7 +218,7 @@ static void emc_message_handler(msg_level_t level, const char *fmt, va_list ap) va_copy(apc, ap); // cppcheck-suppress va_list_usedBeforeStarted if(level == RTAPI_MSG_ERR) emcmotErrorPutfv(emcmotError, fmt, apc); - else if(old_handler) old_handler(level, fmt, ap); + if(old_handler) old_handler(level, fmt, ap); // cppcheck-suppress va_list_usedBeforeStarted va_end(apc); } From e0d88b89f91c3c536090482a4e6f8df70220ac94 Mon Sep 17 00:00:00 2001 From: Hannes Diethelm Date: Wed, 3 Jun 2026 11:42:48 +0200 Subject: [PATCH 2/5] Revert "Fix printing hm2_modbus messages at startup." This reverts commit 65e2269723875ae369d094c654abb871c0236cb1. --- src/hal/drivers/mesa-hostmot2/hm2_modbus.c | 69 ++++++++++------------ 1 file changed, 31 insertions(+), 38 deletions(-) diff --git a/src/hal/drivers/mesa-hostmot2/hm2_modbus.c b/src/hal/drivers/mesa-hostmot2/hm2_modbus.c index e5a975e37b3..21c675020d2 100644 --- a/src/hal/drivers/mesa-hostmot2/hm2_modbus.c +++ b/src/hal/drivers/mesa-hostmot2/hm2_modbus.c @@ -149,7 +149,6 @@ static inline unsigned mtypesize(unsigned mtype) { #define MSG_INFO(fmt...) do { rtapi_print_msg(RTAPI_MSG_INFO, fmt); } while(0) #define MSG_ERR(fmt...) do { rtapi_print_msg(RTAPI_MSG_ERR, fmt); } while(0) #define MSG_WARN(fmt...) do { rtapi_print_msg(RTAPI_MSG_WARN, fmt); } while(0) -#define MSG_PRINT(fmt...) do { rtapi_print(fmt); } while(0) // State-machine states enum { @@ -2712,19 +2711,17 @@ int rtapi_app_main(void) int retval; // Only touch the message level if requested - if(!debug) - MSG_PRINT(COMP_NAME": warning: Setting debug to 0 (zero) prevents error messages from being printed\n"); if(debug >= 0) rtapi_set_msg_level(debug); if(!ports[0]) { - MSG_PRINT(COMP_NAME": error: The component requires at least one valid pktuart port, eg ports=\"hm2_5i25.0.pktuart.7\"\n"); + MSG_ERR(COMP_NAME": The component requires at least one valid pktuart port, eg ports=\"hm2_5i25.0.pktuart.7\"\n"); return -EINVAL; } comp_id = hal_init(COMP_NAME); if(comp_id < 0) { - MSG_PRINT(COMP_NAME": error: hal_init() failed\n"); + MSG_ERR(COMP_NAME": hal_init() failed\n"); return comp_id; } @@ -2732,7 +2729,7 @@ int rtapi_app_main(void) for(mb.ninsts = 0; mb.ninsts < MAX_PORTS && ports[mb.ninsts]; mb.ninsts++) {} // Allocate memory for the instances if(!(mb.insts = (hm2_modbus_inst_t *)rtapi_kzalloc(mb.ninsts * sizeof(*mb.insts), RTAPI_GFP_KERNEL))) { - MSG_PRINT(COMP_NAME": error: Allocate instance memory failed\n"); + MSG_ERR(COMP_NAME": Allocate instance memory failed\n"); hal_exit(comp_id); return -ENOMEM; } @@ -2745,15 +2742,13 @@ int rtapi_app_main(void) rtapi_strlcpy(inst->uart, ports[i], sizeof(inst->uart)-1); if(!mbccbs[i]) { - MSG_PRINT("%s: error: Missing mbccb file path for instance %d in 'mbccbs' argument\n", inst->name, i); + MSG_ERR("%s: error: Missing mbccb file path for instance %d in 'mbccbs' argument\n", inst->name, i); retval = -EINVAL; goto errout; } -/* if('/' != mbccbs[i][0]) { - MSG_PRINT("%s: warning: The 'mbccb' file path '%s' for instance %d in 'mbccbs' argument is not absolute\n", inst->name, mbccbs[i], i); + MSG_WARN("%s: warning: The 'mbccb' file path '%s' for instance %d in 'mbccbs' argument is not absolute\n", inst->name, mbccbs[i], i); } -*/ if((retval = load_mbccb(inst, mbccbs[i])) < 0) { // Messages printed in load function @@ -2764,17 +2759,17 @@ int rtapi_app_main(void) // Allocate HAL memory if(!(inst->hal = (hm2_modbus_hal_t *)hal_malloc(sizeof(*inst->hal)))) { - MSG_PRINT("%s: error: Failed to allocate HAL memory\n", inst->name); + MSG_ERR("%s: error: Failed to allocate HAL memory\n", inst->name); retval = -ENOMEM; goto errout; } if(!(inst->hal->pins = (mbt_pin_hal_t *)hal_malloc(inst->npins * sizeof(*inst->hal->pins)))) { - MSG_PRINT("%s: error: Failed to allocate HAL pins memory\n", inst->name); + MSG_ERR("%s: error: Failed to allocate HAL pins memory\n", inst->name); retval = -ENOMEM; goto errout; } if(!(inst->hal->cmds = (mbt_cmd_hal_t *)hal_malloc(inst->ncmds * sizeof(*inst->hal->cmds)))) { - MSG_PRINT("%s: error: Failed to allocate HAL cmds memory\n", inst->name); + MSG_ERR("%s: error: Failed to allocate HAL cmds memory\n", inst->name); retval = -ENOMEM; goto errout; } @@ -2782,7 +2777,7 @@ int rtapi_app_main(void) if(inst->ninit > 0) { // Allocate inits memory if(!(inst->_init = rtapi_kzalloc(inst->ninit * sizeof(*inst->_init), RTAPI_GFP_KERNEL))) { - MSG_PRINT("%s: error: Failed to allocate init commands memory\n", inst->name); + MSG_ERR("%s: error: Failed to allocate init commands memory\n", inst->name); retval = -ENOMEM; goto errout; } @@ -2790,7 +2785,7 @@ int rtapi_app_main(void) // Allocate commands memory if(!(inst->_cmds = rtapi_kzalloc(inst->ncmds * sizeof(*inst->_cmds), RTAPI_GFP_KERNEL))) { - MSG_PRINT("%s: error: Failed to allocate commands memory\n", inst->name); + MSG_ERR("%s: error: Failed to allocate commands memory\n", inst->name); retval = -ENOMEM; goto errout; } @@ -2811,14 +2806,14 @@ int rtapi_app_main(void) // Export the HAL process function if((retval = hal_export_functf(process, inst, 1, 0, comp_id, COMP_NAME".%d.process", i)) < 0) { - MSG_PRINT("%s: error: Function export failed\n", inst->name); + MSG_ERR("%s: error: Function export failed\n", inst->name); goto errout; } #define CHECK(x) do { \ retval = (x); \ if(retval < 0) { \ - MSG_PRINT("%s: error: Failed to create pin or parameter\n", inst->name); \ + MSG_ERR("%s: error: Failed to create pin or parameter\n", inst->name); \ goto errout; \ } \ } while(0) @@ -2880,8 +2875,7 @@ int rtapi_app_main(void) inst->cfg_tx.flags |= HM2_PKTUART_CONFIG_DRIVEEN | HM2_PKTUART_CONFIG_DRIVEAUTO; if((retval = hm2_pktuart_get_version(inst->uart)) < 0) { - MSG_PRINT("%s: error: Cannot get PktUART version (error=%d)\n", inst->name, retval); - MSG_PRINT("%s: error: probable cause: port '%s' does not exist (typo?)\n", inst->name, inst->uart); + MSG_ERR("%s: error: Cannot get PktUART version (error=%d)\n", inst->name, retval); goto errout; } inst->rxversion = (retval >> 4) & 0x0f; @@ -2892,28 +2886,28 @@ int rtapi_app_main(void) // timing measurement. if(inst->rxversion < 3 || inst->txversion < 3) { if(inst->rxversion < 2 || inst->txversion < 2) { - MSG_PRINT("%s: error: The driver does not support PktUART versions before 2 (Rx=%u Tx=%u), aborting.\n", + MSG_ERR("%s: error: The driver does not support PktUART versions before 2 (Rx=%u Tx=%u), aborting.\n", inst->name, inst->rxversion, inst->txversion); goto errout; } - MSG_PRINT("%s: warning: PktUART version is less than 3 (Rx=%u Tx=%u). Please consider upgrading.\n", + MSG_WARN("%s: warning: PktUART version is less than 3 (Rx=%u Tx=%u). Please consider upgrading.\n", inst->name, inst->rxversion, inst->txversion); if(stopbits > 1) { - MSG_PRINT("%s: warning: Old PktUART cannot set two stop-bits. Setting to one.\n", inst->name); + MSG_WARN("%s: warning: Old PktUART cannot set two stop-bits. Setting to one.\n", inst->name); stopbits = 1; } if(inst->txversion < 3 && inst->cfg_tx.ifdelay > 0xff) { - MSG_PRINT("%s: warning: Old PktUART cannot set txdelay to 0x%04x. Clamping to 0xff.\n", + MSG_WARN("%s: warning: Old PktUART cannot set txdelay to 0x%04x. Clamping to 0xff.\n", inst->name, inst->cfg_tx.ifdelay); inst->cfg_tx.ifdelay = 0xff; } if(inst->rxversion < 3 && inst->cfg_rx.ifdelay > 0xff) { - MSG_PRINT("%s: warning: Old PktUART cannot set rxdelay to 0x%04x. Clamping to 0xff.\n", + MSG_WARN("%s: warning: Old PktUART cannot set rxdelay to 0x%04x. Clamping to 0xff.\n", inst->name, inst->cfg_rx.ifdelay); inst->cfg_rx.ifdelay = 0xff; } if(inst->rxversion < 3 && inst->mbccb->icdelay != 0) { - MSG_PRINT("%s: warning: Old PktUART cannot set icdelay, disabling.\n", inst->name); + MSG_WARN("%s: warning: Old PktUART cannot set icdelay, disabling.\n", inst->name); inst->mbccb->icdelay = 0; } } @@ -2921,21 +2915,20 @@ int rtapi_app_main(void) setup_icdelay(inst, inst->mbccb->baudrate, parity, stopbits, inst->mbccb->icdelay); #ifdef DEBUG - MSG_PRINT("%s: inst->name : %s\n", inst->name, inst->name); - MSG_PRINT("%s: inst->uart : %s\n", inst->name, inst->uart); - MSG_PRINT("%s: inst->mbccbsize: %zd\n", inst->name, inst->mbccbsize); - MSG_PRINT("%s: inst->ninit : %u\n", inst->name, inst->ninit); - MSG_PRINT("%s: inst->ncmds : %u\n", inst->name, inst->ncmds); - MSG_PRINT("%s: inst->npins : %u\n", inst->name, inst->npins); - MSG_PRINT("%s: inst->icdelay : %u\n", inst->name, inst->maxicharbits); - MSG_PRINT("%s: inst->rxdelay : %u\n", inst->name, inst->cfg_rx.ifdelay); - MSG_PRINT("%s: inst->txdelay : %u\n", inst->name, inst->cfg_tx.ifdelay); - MSG_PRINT("%s: inst->drvdelay : %u\n", inst->name, inst->cfg_tx.drivedelay); + MSG_INFO("%s: inst->name : %s\n", inst->name, inst->name); + MSG_INFO("%s: inst->uart : %s\n", inst->name, inst->uart); + MSG_INFO("%s: inst->mbccbsize: %zd\n", inst->name, inst->mbccbsize); + MSG_INFO("%s: inst->ninit : %u\n", inst->name, inst->ninit); + MSG_INFO("%s: inst->ncmds : %u\n", inst->name, inst->ncmds); + MSG_INFO("%s: inst->npins : %u\n", inst->name, inst->npins); + MSG_INFO("%s: inst->icdelay : %u\n", inst->name, inst->maxicharbits); + MSG_INFO("%s: inst->rxdelay : %u\n", inst->name, inst->cfg_rx.ifdelay); + MSG_INFO("%s: inst->txdelay : %u\n", inst->name, inst->cfg_tx.ifdelay); + MSG_INFO("%s: inst->drvdelay : %u\n", inst->name, inst->cfg_tx.drivedelay); #endif - MSG_PRINT("%s: PktUART serial port '%s' configured to 8%c%c@%d\n", + MSG_INFO("%s: PktUART serial configured to 8%c%c@%d\n", inst->name, - inst->uart, parity ? (parity == 2 ? 'E' : 'O') : 'N', stopbits > 1 ? '2' : '1', inst->cfg_rx.baudrate); @@ -3124,7 +3117,7 @@ int rtapi_app_main(void) inst->cfg_rx.flags |= HM2_PKTUART_CONFIG_FLUSH; inst->cfg_tx.flags |= HM2_PKTUART_CONFIG_FLUSH; if((retval = hm2_pktuart_config(inst->uart, &inst->cfg_rx, &inst->cfg_tx, 0)) < 0) { - MSG_PRINT("%s: error: PktUART setup problem: error=%d\n", inst->name, retval); + MSG_ERR("%s: error: PktUART setup problem: error=%d\n", inst->name, retval); goto errout; } inst->cfg_rx.flags &= ~HM2_PKTUART_CONFIG_FLUSH; From a39cb499ac418419245e4db4797586cf6d2103ad Mon Sep 17 00:00:00 2001 From: Hannes Diethelm Date: Wed, 3 Jun 2026 12:36:14 +0200 Subject: [PATCH 3/5] Reapply some changes in hm2_modbus.c --- src/hal/drivers/mesa-hostmot2/hm2_modbus.c | 45 ++++++++++++---------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/src/hal/drivers/mesa-hostmot2/hm2_modbus.c b/src/hal/drivers/mesa-hostmot2/hm2_modbus.c index 21c675020d2..39f8c5b23e1 100644 --- a/src/hal/drivers/mesa-hostmot2/hm2_modbus.c +++ b/src/hal/drivers/mesa-hostmot2/hm2_modbus.c @@ -149,6 +149,7 @@ static inline unsigned mtypesize(unsigned mtype) { #define MSG_INFO(fmt...) do { rtapi_print_msg(RTAPI_MSG_INFO, fmt); } while(0) #define MSG_ERR(fmt...) do { rtapi_print_msg(RTAPI_MSG_ERR, fmt); } while(0) #define MSG_WARN(fmt...) do { rtapi_print_msg(RTAPI_MSG_WARN, fmt); } while(0) +#define MSG_PRINT(fmt...) do { rtapi_print(fmt); } while(0) // State-machine states enum { @@ -2711,17 +2712,19 @@ int rtapi_app_main(void) int retval; // Only touch the message level if requested + if(!debug) + MSG_ERR(COMP_NAME": warning: Setting debug to 0 (zero) prevents error messages from being printed\n"); if(debug >= 0) rtapi_set_msg_level(debug); if(!ports[0]) { - MSG_ERR(COMP_NAME": The component requires at least one valid pktuart port, eg ports=\"hm2_5i25.0.pktuart.7\"\n"); + MSG_ERR(COMP_NAME": error: The component requires at least one valid pktuart port, eg ports=\"hm2_5i25.0.pktuart.7\"\n"); return -EINVAL; } comp_id = hal_init(COMP_NAME); if(comp_id < 0) { - MSG_ERR(COMP_NAME": hal_init() failed\n"); + MSG_ERR(COMP_NAME": error: hal_init() failed\n"); return comp_id; } @@ -2729,7 +2732,7 @@ int rtapi_app_main(void) for(mb.ninsts = 0; mb.ninsts < MAX_PORTS && ports[mb.ninsts]; mb.ninsts++) {} // Allocate memory for the instances if(!(mb.insts = (hm2_modbus_inst_t *)rtapi_kzalloc(mb.ninsts * sizeof(*mb.insts), RTAPI_GFP_KERNEL))) { - MSG_ERR(COMP_NAME": Allocate instance memory failed\n"); + MSG_ERR(COMP_NAME": error: Allocate instance memory failed\n"); hal_exit(comp_id); return -ENOMEM; } @@ -2747,7 +2750,7 @@ int rtapi_app_main(void) goto errout; } if('/' != mbccbs[i][0]) { - MSG_WARN("%s: warning: The 'mbccb' file path '%s' for instance %d in 'mbccbs' argument is not absolute\n", inst->name, mbccbs[i], i); + MSG_ERR("%s: warning: The 'mbccb' file path '%s' for instance %d in 'mbccbs' argument is not absolute\n", inst->name, mbccbs[i], i); } if((retval = load_mbccb(inst, mbccbs[i])) < 0) { @@ -2876,6 +2879,7 @@ int rtapi_app_main(void) if((retval = hm2_pktuart_get_version(inst->uart)) < 0) { MSG_ERR("%s: error: Cannot get PktUART version (error=%d)\n", inst->name, retval); + MSG_ERR("%s: error: probable cause: port '%s' does not exist (typo?)\n", inst->name, inst->uart); goto errout; } inst->rxversion = (retval >> 4) & 0x0f; @@ -2890,24 +2894,24 @@ int rtapi_app_main(void) inst->name, inst->rxversion, inst->txversion); goto errout; } - MSG_WARN("%s: warning: PktUART version is less than 3 (Rx=%u Tx=%u). Please consider upgrading.\n", + MSG_ERR("%s: warning: PktUART version is less than 3 (Rx=%u Tx=%u). Please consider upgrading.\n", inst->name, inst->rxversion, inst->txversion); if(stopbits > 1) { - MSG_WARN("%s: warning: Old PktUART cannot set two stop-bits. Setting to one.\n", inst->name); + MSG_ERR("%s: warning: Old PktUART cannot set two stop-bits. Setting to one.\n", inst->name); stopbits = 1; } if(inst->txversion < 3 && inst->cfg_tx.ifdelay > 0xff) { - MSG_WARN("%s: warning: Old PktUART cannot set txdelay to 0x%04x. Clamping to 0xff.\n", + MSG_ERR("%s: warning: Old PktUART cannot set txdelay to 0x%04x. Clamping to 0xff.\n", inst->name, inst->cfg_tx.ifdelay); inst->cfg_tx.ifdelay = 0xff; } if(inst->rxversion < 3 && inst->cfg_rx.ifdelay > 0xff) { - MSG_WARN("%s: warning: Old PktUART cannot set rxdelay to 0x%04x. Clamping to 0xff.\n", + MSG_ERR("%s: warning: Old PktUART cannot set rxdelay to 0x%04x. Clamping to 0xff.\n", inst->name, inst->cfg_rx.ifdelay); inst->cfg_rx.ifdelay = 0xff; } if(inst->rxversion < 3 && inst->mbccb->icdelay != 0) { - MSG_WARN("%s: warning: Old PktUART cannot set icdelay, disabling.\n", inst->name); + MSG_ERR("%s: warning: Old PktUART cannot set icdelay, disabling.\n", inst->name); inst->mbccb->icdelay = 0; } } @@ -2915,20 +2919,21 @@ int rtapi_app_main(void) setup_icdelay(inst, inst->mbccb->baudrate, parity, stopbits, inst->mbccb->icdelay); #ifdef DEBUG - MSG_INFO("%s: inst->name : %s\n", inst->name, inst->name); - MSG_INFO("%s: inst->uart : %s\n", inst->name, inst->uart); - MSG_INFO("%s: inst->mbccbsize: %zd\n", inst->name, inst->mbccbsize); - MSG_INFO("%s: inst->ninit : %u\n", inst->name, inst->ninit); - MSG_INFO("%s: inst->ncmds : %u\n", inst->name, inst->ncmds); - MSG_INFO("%s: inst->npins : %u\n", inst->name, inst->npins); - MSG_INFO("%s: inst->icdelay : %u\n", inst->name, inst->maxicharbits); - MSG_INFO("%s: inst->rxdelay : %u\n", inst->name, inst->cfg_rx.ifdelay); - MSG_INFO("%s: inst->txdelay : %u\n", inst->name, inst->cfg_tx.ifdelay); - MSG_INFO("%s: inst->drvdelay : %u\n", inst->name, inst->cfg_tx.drivedelay); + MSG_PRINT("%s: inst->name : %s\n", inst->name, inst->name); + MSG_PRINT("%s: inst->uart : %s\n", inst->name, inst->uart); + MSG_PRINT("%s: inst->mbccbsize: %zd\n", inst->name, inst->mbccbsize); + MSG_PRINT("%s: inst->ninit : %u\n", inst->name, inst->ninit); + MSG_PRINT("%s: inst->ncmds : %u\n", inst->name, inst->ncmds); + MSG_PRINT("%s: inst->npins : %u\n", inst->name, inst->npins); + MSG_PRINT("%s: inst->icdelay : %u\n", inst->name, inst->maxicharbits); + MSG_PRINT("%s: inst->rxdelay : %u\n", inst->name, inst->cfg_rx.ifdelay); + MSG_PRINT("%s: inst->txdelay : %u\n", inst->name, inst->cfg_tx.ifdelay); + MSG_PRINT("%s: inst->drvdelay : %u\n", inst->name, inst->cfg_tx.drivedelay); #endif - MSG_INFO("%s: PktUART serial configured to 8%c%c@%d\n", + MSG_PRINT("%s: PktUART serial port '%s' configured to 8%c%c@%d\n", inst->name, + inst->uart, parity ? (parity == 2 ? 'E' : 'O') : 'N', stopbits > 1 ? '2' : '1', inst->cfg_rx.baudrate); From 4de2e5aa8ca1adb18aba2ebc9ef3797344896a78 Mon Sep 17 00:00:00 2001 From: Hannes Diethelm Date: Wed, 3 Jun 2026 11:48:13 +0200 Subject: [PATCH 4/5] Fix error messages are not shown The last two reverts fix the issue. This commit describes why there is no good workaround against showing errors twice. --- src/emc/motion/motion.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/emc/motion/motion.c b/src/emc/motion/motion.c index 26ec530ddac..0c868455bff 100644 --- a/src/emc/motion/motion.c +++ b/src/emc/motion/motion.c @@ -217,8 +217,23 @@ static void emc_message_handler(msg_level_t level, const char *fmt, va_list ap) // cppcheck-suppress va_list_usedBeforeStarted va_copy(apc, ap); // cppcheck-suppress va_list_usedBeforeStarted - if(level == RTAPI_MSG_ERR) emcmotErrorPutfv(emcmotError, fmt, apc); - if(old_handler) old_handler(level, fmt, ap); + + //Report errors trough emcmotError() so they are shown + //in the gui and also on the console in the configured language. + if(level == RTAPI_MSG_ERR){ + emcmotErrorPutfv(emcmotError, fmt, apc); + } + + //Report everything trough the old_handler which is typically + //the rtapi handler. These messages are shown on the console. + //This has the nasty side effect that error messages are shown twice. + //However, there is no good solution. If the milltask fails + //or stalls due to any reason, this results in the most important + //errors not visible any more if old_handler() is not invoked. + if(old_handler){ + old_handler(level, fmt, ap); + } + // cppcheck-suppress va_list_usedBeforeStarted va_end(apc); } From c3c06c6de67eebec154679c99f94b85f5acae52e Mon Sep 17 00:00:00 2001 From: Hannes Diethelm Date: Wed, 3 Jun 2026 13:23:14 +0200 Subject: [PATCH 5/5] Fix error messages are shown twice Instead of inhibiting old_handler() we always use old_handler() for console in real time context and inhibit print to console for messages passed from realtime to milltask. --- src/emc/motion/motion.c | 40 +++++++++++++++++++++++++++++------- src/emc/motion/stashf.c | 4 ++++ src/emc/motion/usrmotintf.cc | 1 + src/emc/task/taskintf.cc | 12 ++++++++--- 4 files changed, 47 insertions(+), 10 deletions(-) diff --git a/src/emc/motion/motion.c b/src/emc/motion/motion.c index 0c868455bff..5abecad7395 100644 --- a/src/emc/motion/motion.c +++ b/src/emc/motion/motion.c @@ -196,40 +196,66 @@ void emcmot_config_change(void) } } +static rtapi_msg_handler_t old_handler = NULL; + void reportError(const char *fmt, ...) { va_list args; va_start(args, fmt); + + //Report trough emcmotError() so they are shown + //in the gui in the configured language. emcmotErrorPutfv(emcmotError, fmt, args); + va_end(args); + + + //Report trough the old_handler which is typically + //the rtapi handler. These messages are shown on the console. + if(old_handler){ + //We must add a \n due to reportError() strings normally + //don't have a newline at the end but rtapi_print() strings + //need one. + char fmt_tmp[EMCMOT_ERROR_LEN]; + size_t fmt_len = strlen(fmt); + //Manually check string length and truncate if it is to long + if(fmt_len < EMCMOT_ERROR_LEN-1){ + memcpy(fmt_tmp, fmt, fmt_len); + fmt_tmp[fmt_len+0] = '\n'; + fmt_tmp[fmt_len+1] = '\0'; + }else{ + memcpy(fmt_tmp, fmt, EMCMOT_ERROR_LEN-2); + fmt_tmp[EMCMOT_ERROR_LEN-2] = '\n'; + fmt_tmp[EMCMOT_ERROR_LEN-1] = '\0'; + } + + va_start(args, fmt); + old_handler(RTAPI_MSG_ERR, fmt_tmp, args); + va_end(args); + } } #ifndef va_copy #define va_copy(dest, src) ((dest)=(src)) #endif -static rtapi_msg_handler_t old_handler = NULL; static void emc_message_handler(msg_level_t level, const char *fmt, va_list ap) { va_list apc; // False positive. Cppcheck does not seem to know the properties of va_copy() // cppcheck-suppress va_list_usedBeforeStarted va_copy(apc, ap); - // cppcheck-suppress va_list_usedBeforeStarted //Report errors trough emcmotError() so they are shown - //in the gui and also on the console in the configured language. + //in the gui in the configured language. if(level == RTAPI_MSG_ERR){ + // cppcheck-suppress va_list_usedBeforeStarted emcmotErrorPutfv(emcmotError, fmt, apc); } //Report everything trough the old_handler which is typically //the rtapi handler. These messages are shown on the console. - //This has the nasty side effect that error messages are shown twice. - //However, there is no good solution. If the milltask fails - //or stalls due to any reason, this results in the most important - //errors not visible any more if old_handler() is not invoked. if(old_handler){ old_handler(level, fmt, ap); } diff --git a/src/emc/motion/stashf.c b/src/emc/motion/stashf.c index 60df930374a..fcc16dcf9c3 100644 --- a/src/emc/motion/stashf.c +++ b/src/emc/motion/stashf.c @@ -119,6 +119,10 @@ extern int rtapi_snprintf(char *, unsigned long, const char *, ...); #else #define PRINT(...) snprintf(buf, n, ## __VA_ARGS__) #endif + +//The *printdbuf() functions translate the fmt +//and %s args using libintl to the user's language + #define EXTRA buf += result; n -= result; if(n<0) n = 0; int snprintdbuf(char *buf, int n, struct dbuf_iter *o) { #include "stashf_wrap.h" diff --git a/src/emc/motion/usrmotintf.cc b/src/emc/motion/usrmotintf.cc index 1585f394a28..c5fe96b3987 100644 --- a/src/emc/motion/usrmotintf.cc +++ b/src/emc/motion/usrmotintf.cc @@ -215,6 +215,7 @@ int usrmotReadEmcmotError(char *e) struct dbuf_iter di; dbuf_iter_init(&di, &d); + /* snprintdbuf() translates the language of the message */ result = snprintdbuf(e, EMCMOT_ERROR_LEN, &di); if(result < 0) return result; return 0; diff --git a/src/emc/task/taskintf.cc b/src/emc/task/taskintf.cc index 7aaee75fe73..3d2344e3e57 100644 --- a/src/emc/task/taskintf.cc +++ b/src/emc/task/taskintf.cc @@ -2072,10 +2072,16 @@ int emcMotionUpdate(EMC_MOTION_STAT * stat) } // read the emcmot error if (0 != usrmotReadEmcmotError(errorString)) { - // no error, so ignore + // no error, so ignore } else { - // an error to report - emcOperatorError("%s", errorString); + // an error to report + // Disable stdout print due to this error is from motion + // and already printed to stdout + // emcOperatorError() also forwards the error to the gui + RCS_PRINT_DESTINATION_TYPE prev_dest = get_rcs_print_destination(); + set_rcs_print_destination(RCS_PRINT_TO_NULL); + emcOperatorError("%s", errorString); + set_rcs_print_destination(prev_dest); } // save the heartbeat and command number locally,