Remove hardcoded package paths and prefixes

No longer assume that a package prefix is "android.hardware" and that
the directory mapping to that package prefix is "$TOP/hardware/interfaces".
Instead, provide this informatoin via a command-line option (-r) as follows:

hidl-gen -o /tmp \
    -r android.hardware:hardware/interfaces \
    android.hardware.nfc@1.0::INfc

Multiple -r options can be provided, for example:

hidl-gen -o /tmp \
    -r android.hardware:$TOP/hardware/interfaces \
    -r vendor.qcom.hardware:vendor/qcom/interfaces \
    android.hardware.nfc@1.0::INfc

The auto-generated files are emitted in the output path (-o option, /tmp
in the example above) and nested under a directory structure based on
the package root.  Thus, for android.hardware.nfc@1.0::INfc, given -r
android.hardware:hardware/interfaces, we identify android.hardware as
the package root, which gets mapped to the path fragment
"android/hardware", causing auto-generated files to go under
/tmp/android/hardware/nfc/V1_0/

Signed-off-by: Iliyan Malchev <malchev@google.com>
diff --git a/main.cpp b/main.cpp
index 6592b68..4059202 100644
--- a/main.cpp
+++ b/main.cpp
@@ -4,21 +4,33 @@
 
 #include <android-base/logging.h>
 #include <stdio.h>
+#include <string>
 #include <unistd.h>
+#include <vector>
 
 using namespace android;
 
 static void usage(const char *me) {
-    fprintf(stderr, "usage: %s -o output-path fqname ...\n", me);
+    fprintf(stderr,
+            "usage: %s -o output-path (-r interface-root)+ fqname+\n",
+            me);
+
+    fprintf(stderr, "         -o output path\n");
+
+    fprintf(stderr,
+            "         -r package:path root "
+            "(e.g., android.hardware:hardware/interfaces)\n");
 }
 
 int main(int argc, char **argv) {
     std::string outputDir;
+    std::vector<std::string> packageRootPaths;
+    std::vector<std::string> packageRoots;
 
     const char *me = argv[0];
 
     int res;
-    while ((res = getopt(argc, argv, "ho:")) >= 0) {
+    while ((res = getopt(argc, argv, "ho:r:")) >= 0) {
         switch (res) {
             case 'o':
             {
@@ -26,6 +38,19 @@
                 break;
             }
 
+            case 'r':
+            {
+                std::string val(optarg);
+                auto index = val.find_first_of(':');
+                CHECK(index != std::string::npos);
+
+                auto package = val.substr(0, index);
+                auto path = val.substr(index + 1);
+                packageRootPaths.push_back(path);
+                packageRoots.push_back(package);
+                break;
+            }
+
             case '?':
             case 'h':
             default:
@@ -40,6 +65,20 @@
     argc -= optind;
     argv += optind;
 
+    if (packageRootPaths.empty()) {
+        // Pick reasonable defaults.
+
+        packageRoots.push_back("android.hardware");
+
+        const char *TOP = getenv("TOP");
+        CHECK(TOP != NULL);
+
+        std::string path = TOP;
+        path.append("/hardware/interfaces");
+
+        packageRootPaths.push_back(path);
+    }
+
     // Valid options are now in argv[0] .. argv[argc - 1].
 
     if (outputDir.empty()) {
@@ -52,16 +91,7 @@
         }
     }
 
-    const char *TOP = getenv("TOP");
-    if (TOP == NULL) {
-        LOG(ERROR) << "Your environment does not define $TOP.";
-        return 1;
-    }
-
-    std::string interfacesPath = TOP;
-    interfacesPath.append("/hardware/interfaces/");
-
-    Coordinator coordinator(interfacesPath);
+    Coordinator coordinator(packageRootPaths, packageRoots);
 
     for (int i = 0; i < argc; ++i) {
         FQName fqName(argv[i]);