AssembleVintf.cpp revision 9aa6370fa16fa1c04a15677d1c22401fa94dc4e7
14d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong/*
24d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong * Copyright (C) 2017 The Android Open Source Project
34d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong *
44d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong * Licensed under the Apache License, Version 2.0 (the "License");
54d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong * you may not use this file except in compliance with the License.
64d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong * You may obtain a copy of the License at
74d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong *
84d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong *      http://www.apache.org/licenses/LICENSE-2.0
94d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong *
104d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong * Unless required by applicable law or agreed to in writing, software
114d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong * distributed under the License is distributed on an "AS IS" BASIS,
124d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong * See the License for the specific language governing permissions and
144d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong * limitations under the License.
154d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong */
164d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong
179aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong#include <getopt.h>
184d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong#include <stdlib.h>
194d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong#include <unistd.h>
204d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong
214d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong#include <fstream>
224d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong#include <iostream>
234d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong#include <unordered_map>
244d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong#include <sstream>
254d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong#include <string>
264d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong
274d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong#include <vintf/parse_string.h>
284d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong#include <vintf/parse_xml.h>
294d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong
304d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hongnamespace android {
314d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hongnamespace vintf {
324d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong
334d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong/**
344d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong * Slurps the device manifest file and add build time flag to it.
354d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong */
364d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hongclass AssembleVintf {
374d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hongpublic:
384d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong    template<typename T>
394d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong    static bool getFlag(const std::string& key, T* value) {
404d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong        const char *envValue = getenv(key.c_str());
414d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong        if (envValue == NULL) {
424d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong            std::cerr << "Required " << key << " flag." << std::endl;
434d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong            return false;
444d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong        }
454d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong
464d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong        if (!parse(envValue, value)) {
474d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong            std::cerr << "Cannot parse " << envValue << "." << std::endl;
484d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong            return false;
494d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong        }
504d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong        return true;
514d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong    }
524d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong
534650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong    static std::string read(std::basic_istream<char>& is) {
544650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong        std::stringstream ss;
554650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong        ss << is.rdbuf();
564650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong        return ss.str();
574650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong    }
584650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong
599aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong    std::basic_ostream<char>& out() const {
609aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong        return mOutFileRef == nullptr ? std::cout : *mOutFileRef;
619aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong    }
629aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong
639aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong    bool assembleHalManifest(HalManifest* halManifest) {
644650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong        std::string error;
654d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong
669aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong        if (halManifest->mType == SchemaType::DEVICE) {
679aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong            if (!getFlag("BOARD_SEPOLICY_VERS", &halManifest->device.mSepolicyVersion)) {
689aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                return false;
694d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong            }
709aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong        }
714d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong
729aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong        if (mOutputMatrix) {
739aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong            CompatibilityMatrix generatedMatrix = halManifest->generateCompatibleMatrix();
749aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong            if (!halManifest->checkCompatibility(generatedMatrix, &error)) {
759aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                std::cerr << "FATAL ERROR: cannot generate a compatible matrix: " << error
769aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                          << std::endl;
77a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong            }
789aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong            out() << "<!-- \n"
799aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                     "    Autogenerated skeleton compatibility matrix. \n"
809aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                     "    Use with caution. Modify it to suit your needs.\n"
819aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                     "    All HALs are set to optional.\n"
829aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                     "    Many entries other than HALs are zero-filled and\n"
839aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                     "    require human attention. \n"
849aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                     "-->\n"
859aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                  << gCompatibilityMatrixConverter(generatedMatrix);
869aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong        } else {
879aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong            out() << gHalManifestConverter(*halManifest);
889aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong        }
899aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong        out().flush();
909aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong
919aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong        if (mCheckFile.is_open()) {
929aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong            CompatibilityMatrix checkMatrix;
939aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong            if (!gCompatibilityMatrixConverter(&checkMatrix, read(mCheckFile))) {
949aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                std::cerr << "Cannot parse check file as a compatibility matrix: "
959aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                          << gCompatibilityMatrixConverter.lastError() << std::endl;
969aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                return false;
974650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong            }
989aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong            if (!halManifest->checkCompatibility(checkMatrix, &error)) {
999aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                std::cerr << "Not compatible: " << error << std::endl;
1009aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                return false;
1019aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong            }
1029aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong        }
1034650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong
1049aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong        return true;
1059aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong    }
1069aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong
1079aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong    bool assembleCompatibilityMatrix(CompatibilityMatrix* matrix) {
1089aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong        std::string error;
1099aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong
1109aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong        KernelSepolicyVersion kernelSepolicyVers;
1119aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong        Version sepolicyVers;
1129aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong        if (matrix->mType == SchemaType::FRAMEWORK) {
1139aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong            if (!getFlag("BOARD_SEPOLICY_VERS", &sepolicyVers)) {
1149aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                return false;
1159aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong            }
1169aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong            if (!getFlag("POLICYVERS", &kernelSepolicyVers)) {
1179aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                return false;
1189aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong            }
1199aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong            matrix->framework.mSepolicy =
1209aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                Sepolicy(kernelSepolicyVers, {{sepolicyVers.majorVer, sepolicyVers.minorVer}});
121a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong        }
1229aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong        out() << gCompatibilityMatrixConverter(*matrix);
1239aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong        out().flush();
124a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong
1259aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong        if (mCheckFile.is_open()) {
1269aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong            HalManifest checkManifest;
1279aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong            if (!gHalManifestConverter(&checkManifest, read(mCheckFile))) {
1289aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                std::cerr << "Cannot parse check file as a HAL manifest: "
1299aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                          << gHalManifestConverter.lastError() << std::endl;
1309aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                return false;
1311e5a054a0c3790364428dbfbe8625836a3087776Yifan Hong            }
1329aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong            if (!checkManifest.checkCompatibility(*matrix, &error)) {
1339aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                std::cerr << "Not compatible: " << error << std::endl;
1349aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                return false;
1359aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong            }
1369aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong        }
1379aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong
1389aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong        return true;
1399aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong    }
1409aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong
1419aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong    bool assemble() {
1429aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong        if (!mInFile.is_open()) {
1439aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong            std::cerr << "Missing input file." << std::endl;
1449aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong            return false;
1459aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong        }
1469aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong
1479aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong        std::string fileContent = read(mInFile);
1489aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong
1499aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong        HalManifest halManifest;
1509aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong        if (gHalManifestConverter(&halManifest, fileContent)) {
1519aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong            if (assembleHalManifest(&halManifest)) {
1529aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                return true;
1534650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong            }
1549aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong        }
1554650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong
1569aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong        CompatibilityMatrix matrix;
1579aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong        if (gCompatibilityMatrixConverter(&matrix, fileContent)) {
1589aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong            if (assembleCompatibilityMatrix(&matrix)) {
1599aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                return true;
1609aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong            }
161959ee1bf8b922980542f72ce9ad1929fc7d8b55cYifan Hong        }
1624d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong
163959ee1bf8b922980542f72ce9ad1929fc7d8b55cYifan Hong        std::cerr << "Input file has unknown format." << std::endl
164959ee1bf8b922980542f72ce9ad1929fc7d8b55cYifan Hong                  << "Error when attempting to convert to manifest: "
165959ee1bf8b922980542f72ce9ad1929fc7d8b55cYifan Hong                  << gHalManifestConverter.lastError() << std::endl
166959ee1bf8b922980542f72ce9ad1929fc7d8b55cYifan Hong                  << "Error when attempting to convert to compatibility matrix: "
167959ee1bf8b922980542f72ce9ad1929fc7d8b55cYifan Hong                  << gCompatibilityMatrixConverter.lastError() << std::endl;
168959ee1bf8b922980542f72ce9ad1929fc7d8b55cYifan Hong        return false;
1694d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong    }
1709aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong
1719aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong    bool openOutFile(const char* path) {
1729aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong        mOutFileRef = std::make_unique<std::ofstream>();
1739aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong        mOutFileRef->open(path);
1749aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong        return mOutFileRef->is_open();
1759aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong    }
1769aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong
1779aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong    bool openInFile(const char* path) {
1789aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong        mInFile.open(path);
1799aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong        return mInFile.is_open();
1809aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong    }
1819aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong
1829aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong    bool openCheckFile(const char* path) {
1839aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong        mCheckFile.open(path);
1849aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong        return mCheckFile.is_open();
1859aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong    }
1869aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong
1879aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong    void setOutputMatrix() { mOutputMatrix = true; }
1889aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong
1899aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong   private:
1909aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong    std::ifstream mInFile;
1919aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong    std::unique_ptr<std::ofstream> mOutFileRef;
1929aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong    std::ifstream mCheckFile;
1939aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong    bool mOutputMatrix = false;
1944d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong};
1954d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong
1964d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong}  // namespace vintf
1974d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong}  // namespace android
1984d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong
1994d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hongvoid help() {
2009aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong    std::cerr << "assemble_vintf: Checks if a given manifest / matrix file is valid and \n"
2019aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                 "    fill in build-time flags into the given file.\n"
2029aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                 "assemble_vintf -h\n"
2039aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                 "               Display this help text.\n"
2049aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                 "assemble_vintf -i <input file> [-o <output file>] [-m] [-c [<check file>]]\n"
2059aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                 "               [--kernel=<version>:<android-base.cfg>]\n"
2069aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                 "               Fill in build-time flags into the given file.\n"
2079aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                 "    -i <input file>\n"
2089aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                 "               Input file. Format is automatically detected.\n"
2099aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                 "    -o <output file>\n"
2109aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                 "               Optional output file. If not specified, write to stdout.\n"
2119aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                 "    -m\n"
2129aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                 "               a compatible compatibility matrix is\n"
2139aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                 "               generated instead; for example, given a device manifest,\n"
2149aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                 "               a framework compatibility matrix is generated. This flag\n"
2159aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                 "               is ignored when input is a compatibility matrix.\n"
2169aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                 "    -c [<check file>]\n"
2179aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                 "               After writing the output file, check compatibility between\n"
2189aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                 "               output file and check file.\n"
2199aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                 "               If -c is set but the check file is not specified, a warning\n"
2209aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                 "               message is written to stderr. Return 0.\n"
2219aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                 "               If the check file is specified but is not compatible, an error\n"
2229aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                 "               message is written to stderr. Return 1.\n";
2234d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong}
2244d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong
2254d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hongint main(int argc, char **argv) {
2269aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong    const struct option longopts[] = {{0, 0, 0, 0}};
2279aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong
2284650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong    std::string inFilePath;
2299aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong    ::android::vintf::AssembleVintf assembleVintf;
2304d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong    int res;
2319aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong    int optind;
2329aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong    while ((res = getopt_long(argc, argv, "hi:o:mc:", longopts, &optind)) >= 0) {
2334d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong        switch (res) {
2344d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong            case 'i': {
2354650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong                inFilePath = optarg;
2369aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                if (!assembleVintf.openInFile(optarg)) {
2374d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong                    std::cerr << "Failed to open " << optarg << std::endl;
2384d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong                    return 1;
2394d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong                }
2404d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong            } break;
2414d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong
2424d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong            case 'o': {
2439aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                if (!assembleVintf.openOutFile(optarg)) {
2444d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong                    std::cerr << "Failed to open " << optarg << std::endl;
2454d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong                    return 1;
2464d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong                }
2474d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong            } break;
2484d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong
249a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong            case 'm': {
2509aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                assembleVintf.setOutputMatrix();
251a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong            } break;
252a59d2567783cad6f675d2fc1f2fcce4bce3e34e3Yifan Hong
2534650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong            case 'c': {
2544650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong                if (strlen(optarg) != 0) {
2559aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong                    if (!assembleVintf.openCheckFile(optarg)) {
2564650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong                        std::cerr << "Failed to open " << optarg << std::endl;
2574650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong                        return 1;
2584650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong                    }
2594650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong                } else {
2604650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong                    std::cerr << "WARNING: no compatibility check is done on "
2614650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong                              << inFilePath << std::endl;
2624650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong                }
2634650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong            } break;
2644650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong
2654d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong            case 'h':
2664d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong            default: {
2674d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong                help();
2684d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong                return 1;
2694d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong            } break;
2704d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong        }
2714d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong    }
2724d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong
2739aa6370fa16fa1c04a15677d1c22401fa94dc4e7Yifan Hong    bool success = assembleVintf.assemble();
2744650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong
2754650ad8e0353ee4404a85300937f66a8c92d7f98Yifan Hong    return success ? 0 : 1;
2764d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong}
2774d18bcc9a3de245edb20c2469718f8442c758d97Yifan Hong
278