Refactored assemble_vintf.cpp
for better readability.
Test: builds (assemble_vintf is run to
check framework/device compatibility matrix / manfiests.
Change-Id: I48d80137c1cf886326ccf83e0406bd80eac8452b
diff --git a/assemble_vintf.cpp b/assemble_vintf.cpp
index f6df2d3..fb96359 100644
--- a/assemble_vintf.cpp
+++ b/assemble_vintf.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <getopt.h>
#include <stdlib.h>
#include <unistd.h>
@@ -55,89 +56,108 @@
return ss.str();
}
- static bool assemble(std::basic_istream<char>& inFile,
- std::basic_ostream<char>& outFile,
- std::ifstream& checkFile,
- bool outputMatrix) {
+ std::basic_ostream<char>& out() const {
+ return mOutFileRef == nullptr ? std::cout : *mOutFileRef;
+ }
+
+ bool assembleHalManifest(HalManifest* halManifest) {
std::string error;
- std::string fileContent = read(inFile);
+
+ if (halManifest->mType == SchemaType::DEVICE) {
+ if (!getFlag("BOARD_SEPOLICY_VERS", &halManifest->device.mSepolicyVersion)) {
+ return false;
+ }
+ }
+
+ if (mOutputMatrix) {
+ CompatibilityMatrix generatedMatrix = halManifest->generateCompatibleMatrix();
+ if (!halManifest->checkCompatibility(generatedMatrix, &error)) {
+ std::cerr << "FATAL ERROR: cannot generate a compatible matrix: " << error
+ << std::endl;
+ }
+ out() << "<!-- \n"
+ " Autogenerated skeleton compatibility matrix. \n"
+ " Use with caution. Modify it to suit your needs.\n"
+ " All HALs are set to optional.\n"
+ " Many entries other than HALs are zero-filled and\n"
+ " require human attention. \n"
+ "-->\n"
+ << gCompatibilityMatrixConverter(generatedMatrix);
+ } else {
+ out() << gHalManifestConverter(*halManifest);
+ }
+ out().flush();
+
+ if (mCheckFile.is_open()) {
+ CompatibilityMatrix checkMatrix;
+ if (!gCompatibilityMatrixConverter(&checkMatrix, read(mCheckFile))) {
+ std::cerr << "Cannot parse check file as a compatibility matrix: "
+ << gCompatibilityMatrixConverter.lastError() << std::endl;
+ return false;
+ }
+ if (!halManifest->checkCompatibility(checkMatrix, &error)) {
+ std::cerr << "Not compatible: " << error << std::endl;
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ bool assembleCompatibilityMatrix(CompatibilityMatrix* matrix) {
+ std::string error;
+
+ KernelSepolicyVersion kernelSepolicyVers;
+ Version sepolicyVers;
+ if (matrix->mType == SchemaType::FRAMEWORK) {
+ if (!getFlag("BOARD_SEPOLICY_VERS", &sepolicyVers)) {
+ return false;
+ }
+ if (!getFlag("POLICYVERS", &kernelSepolicyVers)) {
+ return false;
+ }
+ matrix->framework.mSepolicy =
+ Sepolicy(kernelSepolicyVers, {{sepolicyVers.majorVer, sepolicyVers.minorVer}});
+ }
+ out() << gCompatibilityMatrixConverter(*matrix);
+ out().flush();
+
+ if (mCheckFile.is_open()) {
+ HalManifest checkManifest;
+ if (!gHalManifestConverter(&checkManifest, read(mCheckFile))) {
+ std::cerr << "Cannot parse check file as a HAL manifest: "
+ << gHalManifestConverter.lastError() << std::endl;
+ return false;
+ }
+ if (!checkManifest.checkCompatibility(*matrix, &error)) {
+ std::cerr << "Not compatible: " << error << std::endl;
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ bool assemble() {
+ if (!mInFile.is_open()) {
+ std::cerr << "Missing input file." << std::endl;
+ return false;
+ }
+
+ std::string fileContent = read(mInFile);
HalManifest halManifest;
if (gHalManifestConverter(&halManifest, fileContent)) {
- if (halManifest.mType == SchemaType::DEVICE) {
- if (!getFlag("BOARD_SEPOLICY_VERS", &halManifest.device.mSepolicyVersion)) {
- return false;
- }
+ if (assembleHalManifest(&halManifest)) {
+ return true;
}
-
- if (outputMatrix) {
- CompatibilityMatrix generatedMatrix = halManifest.generateCompatibleMatrix();
- if (!halManifest.checkCompatibility(generatedMatrix, &error)) {
- std::cerr << "FATAL ERROR: cannot generate a compatible matrix: "
- << error << std::endl;
- }
- outFile << "<!-- \n"
- " Autogenerated skeleton compatibility matrix. \n"
- " Use with caution. Modify it to suit your needs.\n"
- " All HALs are set to optional.\n"
- " Many entries other than HALs are zero-filled and\n"
- " require human attention. \n"
- "-->\n"
- << gCompatibilityMatrixConverter(generatedMatrix);
- } else {
- outFile << gHalManifestConverter(halManifest);
- }
- outFile.flush();
-
- if (checkFile.is_open()) {
- CompatibilityMatrix checkMatrix;
- if (!gCompatibilityMatrixConverter(&checkMatrix, read(checkFile))) {
- std::cerr << "Cannot parse check file as a compatibility matrix: "
- << gCompatibilityMatrixConverter.lastError()
- << std::endl;
- return false;
- }
- if (!halManifest.checkCompatibility(checkMatrix, &error)) {
- std::cerr << "Not compatible: " << error << std::endl;
- return false;
- }
- }
-
- return true;
}
CompatibilityMatrix matrix;
if (gCompatibilityMatrixConverter(&matrix, fileContent)) {
- KernelSepolicyVersion kernelSepolicyVers;
- Version sepolicyVers;
- if (matrix.mType == SchemaType::FRAMEWORK) {
- if (!getFlag("BOARD_SEPOLICY_VERS", &sepolicyVers)) {
- return false;
- }
- if (!getFlag("POLICYVERS", &kernelSepolicyVers)) {
- return false;
- }
- matrix.framework.mSepolicy = Sepolicy(kernelSepolicyVers,
- {{sepolicyVers.majorVer,sepolicyVers.minorVer}});
+ if (assembleCompatibilityMatrix(&matrix)) {
+ return true;
}
- outFile << gCompatibilityMatrixConverter(matrix);
- outFile.flush();
-
- if (checkFile.is_open()) {
- HalManifest checkManifest;
- if (!gHalManifestConverter(&checkManifest, read(checkFile))) {
- std::cerr << "Cannot parse check file as a HAL manifest: "
- << gHalManifestConverter.lastError()
- << std::endl;
- return false;
- }
- if (!checkManifest.checkCompatibility(matrix, &error)) {
- std::cerr << "Not compatible: " << error << std::endl;
- return false;
- }
- }
-
- return true;
}
std::cerr << "Input file has unknown format." << std::endl
@@ -147,73 +167,92 @@
<< gCompatibilityMatrixConverter.lastError() << std::endl;
return false;
}
+
+ bool openOutFile(const char* path) {
+ mOutFileRef = std::make_unique<std::ofstream>();
+ mOutFileRef->open(path);
+ return mOutFileRef->is_open();
+ }
+
+ bool openInFile(const char* path) {
+ mInFile.open(path);
+ return mInFile.is_open();
+ }
+
+ bool openCheckFile(const char* path) {
+ mCheckFile.open(path);
+ return mCheckFile.is_open();
+ }
+
+ void setOutputMatrix() { mOutputMatrix = true; }
+
+ private:
+ std::ifstream mInFile;
+ std::unique_ptr<std::ofstream> mOutFileRef;
+ std::ifstream mCheckFile;
+ bool mOutputMatrix = false;
};
} // namespace vintf
} // namespace android
void help() {
- std::cerr <<
-"assemble_vintf: Checks if a given manifest / matrix file is valid and \n"
-" fill in build-time flags into the given file.\n"
-"assemble_vintf -h\n"
-" Display this help text.\n"
-"assemble_vintf -i <input file> [-o <output file>] [-m] [-c [<check file>]]\n"
-" Fill in build-time flags into the given file.\n"
-" -i <input file>\n"
-" Input file. Format is automatically detected.\n"
-" -o <input file>\n"
-" Optional output file. If not specified, write to stdout.\n"
-" -m\n"
-" a compatible compatibility matrix is\n"
-" generated instead; for example, given a device manifest,\n"
-" a framework compatibility matrix is generated. This flag\n"
-" is ignored when input is a compatibility matrix.\n"
-" -c [<check file>]\n"
-" After writing the output file, check compatibility between\n"
-" output file and check file.\n"
-" If -c is set but the check file is not specified, a warning\n"
-" message is written to stderr. Return 0.\n"
-" If the check file is specified but is not compatible, an error\n"
-" message is written to stderr. Return 1.\n";
+ std::cerr << "assemble_vintf: Checks if a given manifest / matrix file is valid and \n"
+ " fill in build-time flags into the given file.\n"
+ "assemble_vintf -h\n"
+ " Display this help text.\n"
+ "assemble_vintf -i <input file> [-o <output file>] [-m] [-c [<check file>]]\n"
+ " [--kernel=<version>:<android-base.cfg>]\n"
+ " Fill in build-time flags into the given file.\n"
+ " -i <input file>\n"
+ " Input file. Format is automatically detected.\n"
+ " -o <output file>\n"
+ " Optional output file. If not specified, write to stdout.\n"
+ " -m\n"
+ " a compatible compatibility matrix is\n"
+ " generated instead; for example, given a device manifest,\n"
+ " a framework compatibility matrix is generated. This flag\n"
+ " is ignored when input is a compatibility matrix.\n"
+ " -c [<check file>]\n"
+ " After writing the output file, check compatibility between\n"
+ " output file and check file.\n"
+ " If -c is set but the check file is not specified, a warning\n"
+ " message is written to stderr. Return 0.\n"
+ " If the check file is specified but is not compatible, an error\n"
+ " message is written to stderr. Return 1.\n";
}
int main(int argc, char **argv) {
- std::ifstream inFile;
- std::ofstream outFile;
- std::ifstream checkFile;
- std::ostream* outFileRef = &std::cout;
- bool outputMatrix = false;
+ const struct option longopts[] = {{0, 0, 0, 0}};
+
std::string inFilePath;
+ ::android::vintf::AssembleVintf assembleVintf;
int res;
- while((res = getopt(argc, argv, "hi:o:mc:")) >= 0) {
+ int optind;
+ while ((res = getopt_long(argc, argv, "hi:o:mc:", longopts, &optind)) >= 0) {
switch (res) {
case 'i': {
inFilePath = optarg;
- inFile.open(optarg);
- if (!inFile.is_open()) {
+ if (!assembleVintf.openInFile(optarg)) {
std::cerr << "Failed to open " << optarg << std::endl;
return 1;
}
} break;
case 'o': {
- outFile.open(optarg);
- if (!outFile.is_open()) {
+ if (!assembleVintf.openOutFile(optarg)) {
std::cerr << "Failed to open " << optarg << std::endl;
return 1;
}
- outFileRef = &outFile;
} break;
case 'm': {
- outputMatrix = true;
+ assembleVintf.setOutputMatrix();
} break;
case 'c': {
if (strlen(optarg) != 0) {
- checkFile.open(optarg);
- if (!checkFile.is_open()) {
+ if (!assembleVintf.openCheckFile(optarg)) {
std::cerr << "Failed to open " << optarg << std::endl;
return 1;
}
@@ -231,15 +270,7 @@
}
}
- if (!inFile.is_open()) {
- std::cerr << "Missing input file" << std::endl;
- help();
- return 1;
- }
-
- bool success = ::android::vintf::AssembleVintf::assemble(
- inFile, *outFileRef, checkFile, outputMatrix);
-
+ bool success = assembleVintf.assemble();
return success ? 0 : 1;
}