Complete definition for CompatibilityMatrix
* Add KernelConfigTypedValue to CompatibilityMatrix
to support KV pair in kernel information. config items
in /proc/config.gz are more than just a string; they have
the format:
CONFIG_FOO=y
CONFIG_BAR=""
CONFIG_BAZ=0x99
etc. Compatibility matrix needs to match the value part
as well.
* Added minlts to each kernel entry. This allows
KernelInfo::checkCompatibility to check if the current
LTS version can support the framework.
Test: libvintf_test
Change-Id: I859829dee8fdee0d856c33c1f5836d8c9c94099a
diff --git a/parse_string.cpp b/parse_string.cpp
index d0e655b..abeeb06 100644
--- a/parse_string.cpp
+++ b/parse_string.cpp
@@ -103,8 +103,93 @@
return parseEnum(s, tr, gTransportStrings);
}
-std::ostream &operator<<(std::ostream &os, Transport il) {
- return os << gTransportStrings.at(static_cast<size_t>(il));
+std::ostream &operator<<(std::ostream &os, Transport tr) {
+ return os << gTransportStrings.at(static_cast<size_t>(tr));
+}
+
+bool parse(const std::string &s, KernelConfigType *kc) {
+ return parseEnum(s, kc, gKernelConfigTypeStrings);
+}
+
+std::ostream &operator<<(std::ostream &os, KernelConfigType kc) {
+ return os << gKernelConfigTypeStrings.at(static_cast<size_t>(kc));
+}
+
+bool parse(const std::string &s, Tristate *kc) {
+ return parseEnum(s, kc, gTristateStrings);
+}
+
+std::ostream &operator<<(std::ostream &os, Tristate kc) {
+ return os << gTristateStrings.at(static_cast<size_t>(kc));
+}
+
+std::ostream &operator<<(std::ostream &os, const KernelConfigTypedValue &kctv) {
+ switch (kctv.mType) {
+ case KernelConfigType::STRING:
+ return os << kctv.mStringValue;
+ case KernelConfigType::INTEGER:
+ return os << to_string(kctv.mIntegerValue);
+ case KernelConfigType::RANGE:
+ return os << to_string(kctv.mRangeValue.first) << "-"
+ << to_string(kctv.mRangeValue.second);
+ case KernelConfigType::TRISTATE:
+ return os << to_string(kctv.mTristateValue);
+ }
+}
+
+// Notice that strtoull is used even though KernelConfigIntValue is signed int64_t,
+// because strtoull can accept negative values as well.
+// Notice that according to man strtoul, strtoull can actually accept
+// -2^64 + 1 to 2^64 - 1, with the 65th bit truncated.
+// ParseInt / ParseUint are not used because they do not handle signed hex very well.
+template <typename T>
+bool parseKernelConfigIntHelper(const std::string &s, T *i) {
+ char *end;
+ errno = 0;
+ unsigned long long int ulli = strtoull(s.c_str(), &end, 0 /* base */);
+ // It is implementation defined that what value will be returned by strtoull
+ // in the error case, so we are checking errno directly here.
+ if (errno == 0 && s.c_str() != end && *end == '\0') {
+ *i = static_cast<T>(ulli);
+ return true;
+ }
+ return false;
+}
+
+bool parseKernelConfigInt(const std::string &s, int64_t *i) {
+ return parseKernelConfigIntHelper(s, i);
+}
+
+bool parseKernelConfigInt(const std::string &s, uint64_t *i) {
+ return parseKernelConfigIntHelper(s, i);
+}
+
+bool parseRange(const std::string &s, KernelConfigRangeValue *range) {
+ auto pos = s.find('-');
+ if (pos == std::string::npos) {
+ return false;
+ }
+ return parseKernelConfigInt(s.substr(0, pos), &range->first)
+ && parseKernelConfigInt(s.substr(pos + 1), &range->second);
+}
+
+bool parse(const std::string &s, KernelConfigKey *key) {
+ *key = s;
+ return true;
+}
+
+bool parseKernelConfigValue(const std::string &s, KernelConfigTypedValue *kctv) {
+ switch (kctv->mType) {
+ case KernelConfigType::STRING:
+ kctv->mStringValue = s;
+ return true;
+ case KernelConfigType::INTEGER:
+ return parseKernelConfigInt(s, &kctv->mIntegerValue);
+ case KernelConfigType::RANGE:
+ return parseRange(s, &kctv->mRangeValue);
+ case KernelConfigType::TRISTATE:
+ return parse(s, &kctv->mTristateValue);
+ }
}
bool parse(const std::string &s, Version *ver) {
@@ -155,6 +240,29 @@
return os << vr.minVer() << "-" << vr.maxMinor;
}
+bool parse(const std::string &s, KernelVersion *kernelVersion) {
+ std::vector<std::string> v = SplitString(s, '.');
+ if (v.size() != 3) {
+ return false;
+ }
+ size_t version, major, minor;
+ if (!ParseUint(v[0], &version)) {
+ return false;
+ }
+ if (!ParseUint(v[1], &major)) {
+ return false;
+ }
+ if (!ParseUint(v[2], &minor)) {
+ return false;
+ }
+ *kernelVersion = KernelVersion(version, major, minor);
+ return true;
+}
+
+std::ostream &operator<<(std::ostream &os, const KernelVersion &ver) {
+ return os << ver.version << "." << ver.majorRev << "." << ver.minorRev;
+}
+
bool parse(const std::string &s, ManifestHal *hal) {
std::vector<std::string> v = SplitString(s, '/');
if (v.size() != 5) {
@@ -212,14 +320,6 @@
<< (req.optional ? kOptional : kRequired);
}
-bool parse(const std::string &s, KernelConfig *kc) {
- if (s.find(kConfigPrefix) != 0) {
- return false;
- }
- *kc = s;
- return true;
-}
-
std::string dump(const VendorManifest &vm) {
std::ostringstream oss;
bool first = true;