BV: add global action parser

This commit is contained in:
King Kévin 2018-03-17 19:40:44 +01:00
parent 70b166c1cc
commit cd7ca9a872
2 changed files with 70 additions and 0 deletions

View File

@ -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

View File

@ -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));