mirror of
https://github.com/espressif/openthread.git
synced 2026-06-05 21:14:49 +00:00
[tmf] simplify URI paths array using X-Macro (#12674)
This commit simplfies `thread/uri_paths.cpp` by introducing the `UriEntryMapList` X-Macro. This macro centralizes the mapping between the URI path string, its `kUri*` enum value and its string name representation used in `UriToString()`. By using this macro, we avoid redundant lists and manual template specializations. The `kEntries[]` array, the compile-time assertions validating the sorting of the array, and the `UriToString<>()` template specializations are now all automatically generated from this single list, improving maintainability and reducing the chance of mismatches.
This commit is contained in:
committed by
GitHub
parent
7696e38945
commit
a03011cf73
+74
-148
@@ -51,109 +51,79 @@ struct Entry
|
||||
int Compare(const char *aPath) const { return strcmp(aPath, mPath); }
|
||||
};
|
||||
|
||||
// The list of URI paths (MUST be sorted alphabetically)
|
||||
static constexpr Entry kEntries[] = {
|
||||
{"a/ae"}, // kUriAddressError
|
||||
{"a/an"}, // kUriAddressNotify
|
||||
{"a/aq"}, // kUriAddressQuery
|
||||
{"a/ar"}, // kUriAddressRelease
|
||||
{"a/as"}, // kUriAddressSolicit
|
||||
{"a/sd"}, // kUriServerData
|
||||
{"a/yl"}, // kUriAnycastLocate
|
||||
{"b/ba"}, // kUriBackboneAnswer
|
||||
{"b/bmr"}, // kUriBackboneMlr
|
||||
{"b/bq"}, // kUriBackboneQuery
|
||||
{"c/ab"}, // kUriAnnounceBegin
|
||||
{"c/ag"}, // kUriActiveGet
|
||||
{"c/ar"}, // kUriActiveReplace
|
||||
{"c/as"}, // kUriActiveSet
|
||||
{"c/ca"}, // kUriCommissionerKeepAlive
|
||||
{"c/cg"}, // kUriCommissionerGet
|
||||
{"c/cp"}, // kUriCommissionerPetition
|
||||
{"c/cs"}, // kUriCommissionerSet
|
||||
{"c/dc"}, // kUriDatasetChanged
|
||||
{"c/er"}, // kUriEnergyReport
|
||||
{"c/es"}, // kUriEnergyScan
|
||||
{"c/je"}, // kUriJoinerEntrust
|
||||
{"c/jf"}, // kUriJoinerFinalize
|
||||
{"c/la"}, // kUriLeaderKeepAlive
|
||||
{"c/lp"}, // kUriLeaderPetition
|
||||
{"c/nj"}, // kUriEnrollerJoinerAccept
|
||||
{"c/nk"}, // kUriEnrollerKeepAlive
|
||||
{"c/nl"}, // kUriEnrollerJoinerRelease
|
||||
{"c/nr"}, // kUriEnrollerRegister
|
||||
{"c/ns"}, // kUriEnrollerReportState
|
||||
{"c/pc"}, // kUriPanIdConflict
|
||||
{"c/pg"}, // kUriPendingGet
|
||||
{"c/pq"}, // kUriPanIdQuery
|
||||
{"c/ps"}, // kUriPendingSet
|
||||
{"c/rx"}, // kUriRelayRx
|
||||
{"c/te"}, // kUriTcatEnable
|
||||
{"c/tx"}, // kUriRelayTx
|
||||
{"c/ur"}, // kUriProxyRx
|
||||
{"c/ut"}, // kUriProxyTx
|
||||
{"d/da"}, // kUriDiagnosticGetAnswer
|
||||
{"d/dg"}, // kUriDiagnosticGetRequest
|
||||
{"d/dq"}, // kUriDiagnosticGetQuery
|
||||
{"d/dr"}, // kUriDiagnosticReset
|
||||
{"h/an"}, // kUriHistoryAnswer
|
||||
{"h/qy"}, // kUriHistoryQuery
|
||||
{"n/dn"}, // kUriDuaRegistrationNotify
|
||||
{"n/dr"}, // kUriDuaRegistrationRequest
|
||||
{"n/mr"}, // kUriMlr
|
||||
};
|
||||
#define UriEntryMapList(_) \
|
||||
_("a/ae", kUriAddressError, "AddrError") \
|
||||
_("a/an", kUriAddressNotify, "AddrNotify") \
|
||||
_("a/aq", kUriAddressQuery, "AddrQuery") \
|
||||
_("a/ar", kUriAddressRelease, "AddrRelease") \
|
||||
_("a/as", kUriAddressSolicit, "AddrSolicit") \
|
||||
_("a/sd", kUriServerData, "ServerData") \
|
||||
_("a/yl", kUriAnycastLocate, "AnycastLocate") \
|
||||
_("b/ba", kUriBackboneAnswer, "BbAnswer") \
|
||||
_("b/bmr", kUriBackboneMlr, "BbMlr") \
|
||||
_("b/bq", kUriBackboneQuery, "BbQuery") \
|
||||
_("c/ab", kUriAnnounceBegin, "AnnounceBegin") \
|
||||
_("c/ag", kUriActiveGet, "ActiveGet") \
|
||||
_("c/ar", kUriActiveReplace, "ActiveReplace") \
|
||||
_("c/as", kUriActiveSet, "ActiveSet") \
|
||||
_("c/ca", kUriCommissionerKeepAlive, "CommrKeepAlive") \
|
||||
_("c/cg", kUriCommissionerGet, "CommrGet") \
|
||||
_("c/cp", kUriCommissionerPetition, "CommrPetition") \
|
||||
_("c/cs", kUriCommissionerSet, "CommrSet") \
|
||||
_("c/dc", kUriDatasetChanged, "DatasetChanged") \
|
||||
_("c/er", kUriEnergyReport, "EnergyReport") \
|
||||
_("c/es", kUriEnergyScan, "EnergyScan") \
|
||||
_("c/je", kUriJoinerEntrust, "JoinerEntrust") \
|
||||
_("c/jf", kUriJoinerFinalize, "JoinerFinalize") \
|
||||
_("c/la", kUriLeaderKeepAlive, "LeaderKeepAlive") \
|
||||
_("c/lp", kUriLeaderPetition, "LeaderPetition") \
|
||||
_("c/nj", kUriEnrollerJoinerAccept, "EnrollerJoinerAccept") \
|
||||
_("c/nk", kUriEnrollerKeepAlive, "EnrollerKeepAlive") \
|
||||
_("c/nl", kUriEnrollerJoinerRelease, "EnrollerJoinerRelease") \
|
||||
_("c/nr", kUriEnrollerRegister, "EnrollerRegister") \
|
||||
_("c/ns", kUriEnrollerReportState, "EnrollerReportState") \
|
||||
_("c/pc", kUriPanIdConflict, "PanIdConflict") \
|
||||
_("c/pg", kUriPendingGet, "PendingGet") \
|
||||
_("c/pq", kUriPanIdQuery, "PanIdQuery") \
|
||||
_("c/ps", kUriPendingSet, "PendingSet") \
|
||||
_("c/rx", kUriRelayRx, "RelayRx") \
|
||||
_("c/te", kUriTcatEnable, "TcatEnable") \
|
||||
_("c/tx", kUriRelayTx, "RelayTx") \
|
||||
_("c/ur", kUriProxyRx, "ProxyRx") \
|
||||
_("c/ut", kUriProxyTx, "ProxyTx") \
|
||||
_("d/da", kUriDiagnosticGetAnswer, "DiagGetAnswer") \
|
||||
_("d/dg", kUriDiagnosticGetRequest, "DiagGetRequest") \
|
||||
_("d/dq", kUriDiagnosticGetQuery, "DiagGetQuery") \
|
||||
_("d/dr", kUriDiagnosticReset, "DiagReset") \
|
||||
_("h/an", kUriHistoryAnswer, "HistAnswer") \
|
||||
_("h/qy", kUriHistoryQuery, "HistQuery") \
|
||||
_("n/dn", kUriDuaRegistrationNotify, "DuaRegNotify") \
|
||||
_("n/dr", kUriDuaRegistrationRequest, "DuaRegRequest") \
|
||||
_("n/mr", kUriMlr, "Mlr")
|
||||
|
||||
// We use the X-Macro pattern here. The `UriEntryMapList` macro defines the
|
||||
// mapping between URI path string, its `kUri*` enum and its name string (for
|
||||
// `UriToString`).
|
||||
//
|
||||
// The `UriEntryMapList` macro accepts a single parameter, which is a "visitor"
|
||||
// macro (`_`). The visitor macro is called for each entry in the list. We define
|
||||
// different visitor macros: one to define the `kEntries[]` array, another to
|
||||
// validate the entries in the array (ensuring the URI paths match the enum
|
||||
// values and are sorted properly), and a third to define the `UriToString()`
|
||||
// template specializations.
|
||||
|
||||
#define _EntryArrayElement(kPathString, kUri, kName) {kPathString},
|
||||
|
||||
static constexpr const Entry kEntries[] = {UriEntryMapList(_EntryArrayElement)};
|
||||
|
||||
// The URI entries MUST be sorted based on their path string (e.g. `c/ut`)
|
||||
static_assert(BinarySearch::IsSorted(kEntries), "kEntries is not sorted");
|
||||
|
||||
// Validate that the `kEntries[]` order match the `kUri*` enum constants
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriAddressError].mPath, "a/ae"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriAddressNotify].mPath, "a/an"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriAddressQuery].mPath, "a/aq"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriAddressRelease].mPath, "a/ar"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriAddressSolicit].mPath, "a/as"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriServerData].mPath, "a/sd"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriAnycastLocate].mPath, "a/yl"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriBackboneAnswer].mPath, "b/ba"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriBackboneMlr].mPath, "b/bmr"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriBackboneQuery].mPath, "b/bq"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriAnnounceBegin].mPath, "c/ab"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriActiveGet].mPath, "c/ag"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriActiveReplace].mPath, "c/ar"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriActiveSet].mPath, "c/as"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriCommissionerKeepAlive].mPath, "c/ca"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriCommissionerGet].mPath, "c/cg"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriCommissionerPetition].mPath, "c/cp"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriCommissionerSet].mPath, "c/cs"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriDatasetChanged].mPath, "c/dc"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriEnergyReport].mPath, "c/er"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriEnergyScan].mPath, "c/es"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriJoinerEntrust].mPath, "c/je"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriJoinerFinalize].mPath, "c/jf"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriLeaderKeepAlive].mPath, "c/la"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriLeaderPetition].mPath, "c/lp"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriEnrollerJoinerAccept].mPath, "c/nj"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriEnrollerKeepAlive].mPath, "c/nk"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriEnrollerJoinerRelease].mPath, "c/nl"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriEnrollerRegister].mPath, "c/nr"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriEnrollerReportState].mPath, "c/ns"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriPanIdConflict].mPath, "c/pc"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriPendingGet].mPath, "c/pg"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriPanIdQuery].mPath, "c/pq"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriPendingSet].mPath, "c/ps"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriRelayRx].mPath, "c/rx"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriTcatEnable].mPath, "c/te"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriRelayTx].mPath, "c/tx"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriProxyRx].mPath, "c/ur"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriProxyTx].mPath, "c/ut"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriDiagnosticGetAnswer].mPath, "d/da"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriDiagnosticGetRequest].mPath, "d/dg"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriDiagnosticGetQuery].mPath, "d/dq"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriDiagnosticReset].mPath, "d/dr"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriHistoryAnswer].mPath, "h/an"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriHistoryQuery].mPath, "h/qy"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriDuaRegistrationNotify].mPath, "n/dn"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriDuaRegistrationRequest].mPath, "n/dr"), "kEntries is invalid");
|
||||
static_assert(AreConstStringsEqual(kEntries[kUriMlr].mPath, "n/mr"), "kEntries is invalid");
|
||||
#define _ValidateEntryElement(kPathString, kUri, kName) \
|
||||
static_assert(AreConstStringsEqual(kEntries[kUri].mPath, kPathString), \
|
||||
#kUri " value is incorrect. list is not sorted");
|
||||
|
||||
UriEntryMapList(_ValidateEntryElement)
|
||||
|
||||
} // namespace UriList
|
||||
|
||||
@@ -176,53 +146,9 @@ exit:
|
||||
return uri;
|
||||
}
|
||||
|
||||
template <> const char *UriToString<kUriAddressError>(void) { return "AddressError"; }
|
||||
template <> const char *UriToString<kUriAddressNotify>(void) { return "AddressNotify"; }
|
||||
template <> const char *UriToString<kUriAddressQuery>(void) { return "AddressQuery"; }
|
||||
template <> const char *UriToString<kUriAddressRelease>(void) { return "AddressRelease"; }
|
||||
template <> const char *UriToString<kUriAddressSolicit>(void) { return "AddressSolicit"; }
|
||||
template <> const char *UriToString<kUriServerData>(void) { return "ServerData"; }
|
||||
template <> const char *UriToString<kUriAnycastLocate>(void) { return "AnycastLocate"; }
|
||||
template <> const char *UriToString<kUriBackboneAnswer>(void) { return "BackboneAnswer"; }
|
||||
template <> const char *UriToString<kUriBackboneMlr>(void) { return "BackboneMlr"; }
|
||||
template <> const char *UriToString<kUriBackboneQuery>(void) { return "BackboneQuery"; }
|
||||
template <> const char *UriToString<kUriAnnounceBegin>(void) { return "AnnounceBegin"; }
|
||||
template <> const char *UriToString<kUriActiveGet>(void) { return "ActiveGet"; }
|
||||
template <> const char *UriToString<kUriActiveReplace>(void) { return "ActiveReplace"; }
|
||||
template <> const char *UriToString<kUriActiveSet>(void) { return "ActiveSet"; }
|
||||
template <> const char *UriToString<kUriCommissionerKeepAlive>(void) { return "CommissionerKeepAlive"; }
|
||||
template <> const char *UriToString<kUriCommissionerGet>(void) { return "CommissionerGet"; }
|
||||
template <> const char *UriToString<kUriCommissionerPetition>(void) { return "CommissionerPetition"; }
|
||||
template <> const char *UriToString<kUriCommissionerSet>(void) { return "CommissionerSet"; }
|
||||
template <> const char *UriToString<kUriDatasetChanged>(void) { return "DatasetChanged"; }
|
||||
template <> const char *UriToString<kUriEnergyReport>(void) { return "EnergyReport"; }
|
||||
template <> const char *UriToString<kUriEnergyScan>(void) { return "EnergyScan"; }
|
||||
template <> const char *UriToString<kUriJoinerEntrust>(void) { return "JoinerEntrust"; }
|
||||
template <> const char *UriToString<kUriJoinerFinalize>(void) { return "JoinerFinalize"; }
|
||||
template <> const char *UriToString<kUriLeaderKeepAlive>(void) { return "LeaderKeepAlive"; }
|
||||
template <> const char *UriToString<kUriLeaderPetition>(void) { return "LeaderPetition"; }
|
||||
template <> const char *UriToString<kUriEnrollerJoinerAccept>(void) { return "EnrollerJoinerAccept"; }
|
||||
template <> const char *UriToString<kUriEnrollerKeepAlive>(void) { return "EnrollerKeepAlive"; }
|
||||
template <> const char *UriToString<kUriEnrollerJoinerRelease>(void) { return "EnrollerJoinerRelease"; }
|
||||
template <> const char *UriToString<kUriEnrollerRegister>(void) { return "EnrollerRegister"; }
|
||||
template <> const char *UriToString<kUriEnrollerReportState>(void) { return "EnrollerReportState"; }
|
||||
template <> const char *UriToString<kUriPanIdConflict>(void) { return "PanIdConflict"; }
|
||||
template <> const char *UriToString<kUriPendingGet>(void) { return "PendingGet"; }
|
||||
template <> const char *UriToString<kUriPanIdQuery>(void) { return "PanIdQuery"; }
|
||||
template <> const char *UriToString<kUriPendingSet>(void) { return "PendingSet"; }
|
||||
template <> const char *UriToString<kUriRelayRx>(void) { return "RelayRx"; }
|
||||
template <> const char *UriToString<kUriTcatEnable>(void) { return "TcatEnable"; }
|
||||
template <> const char *UriToString<kUriRelayTx>(void) { return "RelayTx"; }
|
||||
template <> const char *UriToString<kUriProxyRx>(void) { return "ProxyRx"; }
|
||||
template <> const char *UriToString<kUriProxyTx>(void) { return "ProxyTx"; }
|
||||
template <> const char *UriToString<kUriDiagnosticGetAnswer>(void) { return "DiagGetAnswer"; }
|
||||
template <> const char *UriToString<kUriDiagnosticGetRequest>(void) { return "DiagGetRequest"; }
|
||||
template <> const char *UriToString<kUriDiagnosticGetQuery>(void) { return "DiagGetQuery"; }
|
||||
template <> const char *UriToString<kUriDiagnosticReset>(void) { return "DiagReset"; }
|
||||
template <> const char *UriToString<kUriHistoryAnswer>(void) { return "HistAnswer"; }
|
||||
template <> const char *UriToString<kUriHistoryQuery>(void) { return "HistQuery"; }
|
||||
template <> const char *UriToString<kUriDuaRegistrationNotify>(void) { return "DuaRegNotify"; }
|
||||
template <> const char *UriToString<kUriDuaRegistrationRequest>(void) { return "DuaRegRequest"; }
|
||||
template <> const char *UriToString<kUriMlr>(void) { return "Mlr"; }
|
||||
#define _DefineUriToString(kPathString, kUri, kName) \
|
||||
template <> const char *UriToString<kUri>(void) { return kName; }
|
||||
|
||||
UriEntryMapList(_DefineUriToString)
|
||||
|
||||
} // namespace ot
|
||||
|
||||
Reference in New Issue
Block a user