mirror of https://github.com/ArduPilot/ardupilot
AP_Param: Make nested group recursion disableable by macro
* Eliminates recursive calls inside AP_Param. This is important to Pat @ Galois, but not the project in general. Recursion depth on these functions is bounded structurally using existing nested group constructors (can't create loops in finite space) and checked at init time
This commit is contained in:
parent
00180e7084
commit
42078f2794
|
@ -118,6 +118,7 @@ bool AP_Param::check_group_info(const struct AP_Param::GroupInfo *group_info,
|
||||||
for (uint8_t i=0;
|
for (uint8_t i=0;
|
||||||
(type=PGM_UINT8(&group_info[i].type)) != AP_PARAM_NONE;
|
(type=PGM_UINT8(&group_info[i].type)) != AP_PARAM_NONE;
|
||||||
i++) {
|
i++) {
|
||||||
|
#ifdef AP_NESTED_GROUPS_ENABLED
|
||||||
if (type == AP_PARAM_GROUP) {
|
if (type == AP_PARAM_GROUP) {
|
||||||
// a nested group
|
// a nested group
|
||||||
const struct GroupInfo *ginfo = (const struct GroupInfo *)PGM_POINTER(&group_info[i].group_info);
|
const struct GroupInfo *ginfo = (const struct GroupInfo *)PGM_POINTER(&group_info[i].group_info);
|
||||||
|
@ -131,6 +132,7 @@ bool AP_Param::check_group_info(const struct AP_Param::GroupInfo *group_info,
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
#endif // AP_NESTED_GROUPS_ENABLED
|
||||||
uint8_t idx = PGM_UINT8(&group_info[i].idx);
|
uint8_t idx = PGM_UINT8(&group_info[i].idx);
|
||||||
if (idx >= (1<<_group_level_shift)) {
|
if (idx >= (1<<_group_level_shift)) {
|
||||||
// passed limit on table size
|
// passed limit on table size
|
||||||
|
@ -234,6 +236,7 @@ const struct AP_Param::Info *AP_Param::find_by_header_group(struct Param_header
|
||||||
for (uint8_t i=0;
|
for (uint8_t i=0;
|
||||||
(type=PGM_UINT8(&group_info[i].type)) != AP_PARAM_NONE;
|
(type=PGM_UINT8(&group_info[i].type)) != AP_PARAM_NONE;
|
||||||
i++) {
|
i++) {
|
||||||
|
#ifdef AP_NESTED_GROUPS_ENABLED
|
||||||
if (type == AP_PARAM_GROUP) {
|
if (type == AP_PARAM_GROUP) {
|
||||||
// a nested group
|
// a nested group
|
||||||
if (group_shift + _group_level_shift >= _group_bits) {
|
if (group_shift + _group_level_shift >= _group_bits) {
|
||||||
|
@ -250,6 +253,7 @@ const struct AP_Param::Info *AP_Param::find_by_header_group(struct Param_header
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
#endif // AP_NESTED_GROUPS_ENABLED
|
||||||
if (GROUP_ID(group_info, group_base, i, group_shift) == phdr.group_element) {
|
if (GROUP_ID(group_info, group_base, i, group_shift) == phdr.group_element) {
|
||||||
// found a group element
|
// found a group element
|
||||||
*ptr = (void*)(PGM_POINTER(&_var_info[vindex].ptr) + PGM_UINT16(&group_info[i].offset));
|
*ptr = (void*)(PGM_POINTER(&_var_info[vindex].ptr) + PGM_UINT16(&group_info[i].offset));
|
||||||
|
@ -298,6 +302,7 @@ const struct AP_Param::Info *AP_Param::find_var_info_group(const struct GroupInf
|
||||||
(type=PGM_UINT8(&group_info[i].type)) != AP_PARAM_NONE;
|
(type=PGM_UINT8(&group_info[i].type)) != AP_PARAM_NONE;
|
||||||
i++) {
|
i++) {
|
||||||
uintptr_t ofs = PGM_POINTER(&group_info[i].offset);
|
uintptr_t ofs = PGM_POINTER(&group_info[i].offset);
|
||||||
|
#ifdef AP_NESTED_GROUPS_ENABLED
|
||||||
if (type == AP_PARAM_GROUP) {
|
if (type == AP_PARAM_GROUP) {
|
||||||
const struct GroupInfo *ginfo = (const struct GroupInfo *)PGM_POINTER(&group_info[i].group_info);
|
const struct GroupInfo *ginfo = (const struct GroupInfo *)PGM_POINTER(&group_info[i].group_info);
|
||||||
// a nested group
|
// a nested group
|
||||||
|
@ -316,7 +321,9 @@ const struct AP_Param::Info *AP_Param::find_var_info_group(const struct GroupInf
|
||||||
if (info != NULL) {
|
if (info != NULL) {
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
} else if ((uintptr_t)this == base + ofs) {
|
} else // Forgive the poor formatting - if continues below.
|
||||||
|
#endif // AP_NESTED_GROUPS_ENABLED
|
||||||
|
if ((uintptr_t)this == base + ofs) {
|
||||||
*group_element = GROUP_ID(group_info, group_base, i, group_shift);
|
*group_element = GROUP_ID(group_info, group_base, i, group_shift);
|
||||||
*group_ret = &group_info[i];
|
*group_ret = &group_info[i];
|
||||||
*idx = 0;
|
*idx = 0;
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <avr/eeprom.h>
|
#include <avr/eeprom.h>
|
||||||
|
|
||||||
#define AP_MAX_NAME_SIZE 15
|
#define AP_MAX_NAME_SIZE 15
|
||||||
|
#define AP_NESTED_GROUPS_ENABLED
|
||||||
|
|
||||||
// a varient of offsetof() to work around C++ restrictions.
|
// a varient of offsetof() to work around C++ restrictions.
|
||||||
// this can only be used when the offset of a variable in a object
|
// this can only be used when the offset of a variable in a object
|
||||||
|
@ -33,7 +34,9 @@
|
||||||
#define AP_GROUPINFO(name, idx, class, element) { AP_CLASSTYPE(class, element), idx, name, AP_VAROFFSET(class, element) }
|
#define AP_GROUPINFO(name, idx, class, element) { AP_CLASSTYPE(class, element), idx, name, AP_VAROFFSET(class, element) }
|
||||||
|
|
||||||
// declare a nested group entry in a group var_info
|
// declare a nested group entry in a group var_info
|
||||||
|
#ifdef AP_NESTED_GROUPS_ENABLED
|
||||||
#define AP_NESTEDGROUPINFO(class, idx) { AP_PARAM_GROUP, idx, "", 0, class::var_info }
|
#define AP_NESTEDGROUPINFO(class, idx) { AP_PARAM_GROUP, idx, "", 0, class::var_info }
|
||||||
|
#endif
|
||||||
|
|
||||||
#define AP_GROUPEND { AP_PARAM_NONE, 0xFF, "" }
|
#define AP_GROUPEND { AP_PARAM_NONE, 0xFF, "" }
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue