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:
Pat Hickey 2012-02-28 15:54:40 -08:00 committed by Pat Hickey
parent 00180e7084
commit 42078f2794
2 changed files with 11 additions and 1 deletions

View File

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

View File

@ -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, "" }