PX4 / PX4-Autopilot

PX4 Autopilot Software
https://px4.io
BSD 3-Clause "New" or "Revised" License
8.37k stars 13.46k forks source link

Support on snprintf like param_find function #19712

Open junwoo091400 opened 2 years ago

junwoo091400 commented 2 years ago

Describe problem solved by the proposed feature

Instead of this:

char buffer[17];
snprintf(buffer, sizeof(buffer), "CA_SP0_ANG%u", i);
_param_handles.swash_plate_servos[i].angle = param_find(buffer);

It would be better to do this: _param_handles.swash_plate_servos[i].angle = param_find("CA_SP0_ANG%u", i);

Since we don't need to keep creating a char buffer[] for every part of the code where a dynamic parameter name is used (which is becoming more prevalent as we are now supporting the YAML based parameter naming, which supports this syntax)

Describe your preferred solution

I would like to add a function param_find that has a static char buffer[] inside, and can take in multiple arguments like the snprintf, so that users don't have to care about the buffer allocation part.

Current branch I am trying to implement this is here : https://github.com/junwoo091400/PX4-Autopilot/commit/e4278aae89b545a38dcf830794e11419d551e527

/**
 * Look up a parameter with a format string and arguments in snprintf fashion
 *
 * @param format    The format of the param string we are searching for
 * @param ...       Arguments that will form the parameter string we are searching for
 *
 * @return      A handle to the parameter, or PARAM_INVALID if the parameter does not exist.
 *          This call will also set the parameter as "used" in the system, which is used
 *          to e.g. show the parameter via the RC interface
 */
param_t param_find(const char *format ...)
{
    static char param_name[17];
    if (snprintf(param_name, sizeof(param_name), format, __VA_ARGS__)) {
        return param_find(param_name);
    }
    return PARAM_INVALID;
}

Problems

I realized that the snprintf like Variable arguments option is only supported by macros (so we can't define param_find as a C++ function here). Therefore I would love to hear if there are some smart ideas on how this function could be implemented.

I am suspecting that it would need to use the macro, and we may create custom param_find functions that can take in 2, 3, 4, ... arguments and define them separately (and assign the char buffer[] inside some sort of parameter namespace? (But param.h & parameters.cpp doesn't belong to any namespace unfortunately).

Any feedback would be appreciated!

Additional context

This idea originated from this discussion: https://github.com/PX4/PX4-Autopilot/pull/19559/files/ef0ad3ef55e49269eaf835382b3bd0a265acaef3#r867456080

Information on Variable Number of Arguments for Macros: https://en.cppreference.com/w/cpp/preprocessor/replace Another one : https://renenyffenegger.ch/notes/development/languages/C-C-plus-plus/preprocessor/macros/__VA_ARGS__/index

Slack message link for this discussion : https://px4.slack.com/archives/C50RWGQMT/p1653407917363029

junwoo091400 commented 1 year ago

Trying to figure out how the snprintf actually works, and whether I can implement this functionality. Main questions are:

Relevant resource: https://www.ijs.si/software/snprintf/