BV: add global action parser
This commit is contained in:
parent
70b166c1cc
commit
cd7ca9a872
|
@ -21,6 +21,7 @@
|
|||
|
||||
/* standard libraries */
|
||||
#include <stdint.h> // standard integer types
|
||||
#include <stdlib.h> // standard utilities
|
||||
#include <string.h> // string utilities
|
||||
#include <math.h> // math utilities
|
||||
|
||||
|
@ -406,6 +407,66 @@ void busvoodoo_led_red(uint16_t ms)
|
|||
timer_enable_counter(TIM(BUSVOODOO_LED_TIMER)); // re-enable timer
|
||||
}
|
||||
|
||||
bool busvoodoo_global_actions(char* actions, bool perform, bool (*action_handler)(const char* action, uint32_t repetition, bool perform))
|
||||
{
|
||||
char* action_start = actions; // start of the current action
|
||||
bool last_action = false; // is the current action the last one
|
||||
while ('\0'!=*action_start && !last_action) {
|
||||
// find end of action
|
||||
char* action_end = action_start+1;
|
||||
if ('"'==*action_start || '\''==*action_start) { // start of string
|
||||
while ('\0'!=*action_end && *action_end!=*action_start) {
|
||||
action_end++;
|
||||
}
|
||||
if (*action_end!=*action_start) { // action not ended correctly
|
||||
return false;
|
||||
}
|
||||
action_end++; // go the end of action
|
||||
} else { // just look for a separation
|
||||
while ('\0'!=*action_end && ':'!=*action_end && ' '!=*action_end && ','!=*action_end) {
|
||||
action_end++;
|
||||
}
|
||||
}
|
||||
// find start of next action
|
||||
char *separation = action_end; // position of separation to next action
|
||||
while ('\0'!=*separation && ' '!=*separation && ','!=*separation) { // find separation or end
|
||||
separation++;
|
||||
}
|
||||
if ('\0'==*separation) {
|
||||
last_action = true; // remember we reached the end of the string
|
||||
} else {
|
||||
*separation = '\0'; // end the action to form a string
|
||||
}
|
||||
// get multiplier
|
||||
uint32_t multiplier = 1; // the number of times the action should be performed
|
||||
if (separation>action_end) { // there is something after the action
|
||||
if (':'==*action_end) { // multiplier sign found
|
||||
if (separation==action_end+1) { // no digit present
|
||||
return false; // malformed action
|
||||
}
|
||||
for (char* digit=action_end+1; digit<separation; digit++) { // check if all the characters are digits
|
||||
if (*digit<'0' || *digit>'9') { // not a digit
|
||||
return false; // malformed string
|
||||
}
|
||||
}
|
||||
multiplier = strtol(action_end+1, NULL, 10); // parse multiplier number
|
||||
} else { // unknown sign after action
|
||||
return false; // malformed action
|
||||
}
|
||||
}
|
||||
// perform action
|
||||
*action_end = '\0'; // end action string
|
||||
if (!(*action_handler)(action_start, multiplier, perform)) { // perform action
|
||||
return false; // action if malformed
|
||||
}
|
||||
// go to next action
|
||||
if (!last_action) {
|
||||
action_start = separation+1;
|
||||
}
|
||||
}
|
||||
return true; // all went well
|
||||
}
|
||||
|
||||
/* command handlers */
|
||||
|
||||
/** switch 3V3 and 5V power rails on/off
|
||||
|
|
|
@ -179,3 +179,12 @@ void busvoodoo_led_blue(uint16_t ms);
|
|||
* @param[in] ms duration in ms (0-32768)
|
||||
*/
|
||||
void busvoodoo_led_red(uint16_t ms);
|
||||
/** parse and perform actions
|
||||
* @note performing action is a common command in mode and this function helps parsing them
|
||||
* @param[io] actions actions to perform
|
||||
* @param[in] perform the action (true) or just check it (false)
|
||||
* @param[in] action_handler function handling the individual actions
|
||||
* @return true if the actions have been performed, false if any of them is malformed
|
||||
* @note while parsing the actions the string will be modified
|
||||
*/
|
||||
bool busvoodoo_global_actions(char* actions, bool perform, bool (*action_handler)(const char* action, uint32_t repetition, bool perform));
|
||||
|
|
Loading…
Reference in New Issue