// SPDX-License-Identifier: GPL-3.0-only #include "msgPrintControl.h" #include msgPrintControlKey::msgPrintControlKey(char *controller, int axisNo, const char *functionName, int line, size_t maxRepetitions) { controller_ = controller; axisNo_ = axisNo; line_ = line; functionName_ = functionName; maxRepetitions_ = maxRepetitions; } void msgPrintControlKey::format(char *buffer, size_t bufferSize) { snprintf(buffer, bufferSize, "controller %s, axis %d, function %s, line %d", controller_.c_str(), axisNo_, functionName_, line_); } // ============================================================================= bool msgPrintControl::shouldBePrinted(msgPrintControlKey &key, bool wantToPrint, asynUser *pasynUser) { // Reset the suffix suffix_[0] = 0; if (wantToPrint) { /* We want to print the message associated with key -> Check if the number of allowed repetitions is exceeded. If true, inform the user that further output is suppressed. */ if (map_.find(key) != map_.end()) { size_t repetitions = map_[key]; if (repetitions < key.maxRepetitions_) { // Number of allowed repetitions not exceeded -> Printing the // message is ok. map_[key] = repetitions + 1; return true; } else if (repetitions == key.maxRepetitions_) { // Reached number of allowed repetitions -> Printing the message // is ok, but further trys are rejected. char formattedKey[100] = {0}; key.format(formattedKey, sizeof(formattedKey)); snprintf(suffix_, sizeof(suffix_), " Further repetition of this error message (key " "\"%s\") is suppressed.", formattedKey); map_[key] = repetitions + 1; return true; } else { // Exceeded number of allowed repetitions -> Do not print the // message return false; } } else { // Message is not yet in map -> create an entry so it is watched in // the future. map_[key] = 1; return true; } } else { /* We do not want to print the message associated with key -> If the key is part of the map, set the counter back to zero. */ if (map_.find(key) != map_.end()) { if (map_[key] != 0) { if (pasynUser != nullptr) { char formattedKey[100] = {0}; key.format(formattedKey, sizeof(formattedKey)); asynPrint( pasynUser, ASYN_TRACE_ERROR, "Controller \"%s\", axis %d => %s, line %d\nError " "associated with key \"%s\" has been resolved.\n", key.controller_.c_str(), key.axisNo_, key.functionName_, key.line_, formattedKey); } map_[key] = 0; } } return false; } } bool msgPrintControl::shouldBePrinted(char *portName, int axisNo, const char *functionName, int line, bool wantToPrint, asynUser *pasynUser, size_t maxRepetitions) { msgPrintControlKey key = msgPrintControlKey(portName, axisNo, functionName, __LINE__); return shouldBePrinted(key, wantToPrint, pasynUser); } void msgPrintControl::resetCount(msgPrintControlKey &key, asynUser *pasynUser) { if (map_.find(key) != map_.end()) { if (map_[key] != 0) { if (pasynUser != nullptr) { char formattedKey[100] = {0}; key.format(formattedKey, sizeof(formattedKey)); asynPrint(pasynUser, ASYN_TRACE_ERROR, "Controller \"%s\", axis %d => %s, line %d\nError " "associated with key \"%s\" has been resolved.\n", key.controller_.c_str(), key.axisNo_, key.functionName_, key.line_, formattedKey); } map_[key] = 0; } } } char *msgPrintControl::getSuffix() { return suffix_; }