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/generateCpp.cpp b/generateCpp.cpp
index 39aa867..f259258 100644
--- a/generateCpp.cpp
+++ b/generateCpp.cpp
@@ -6,7 +6,9 @@
 #include "Method.h"
 #include "Scope.h"
 
+#include <algorithm>
 #include <android-base/logging.h>
+#include <string>
 #include <sys/stat.h>
 #include <vector>
 
@@ -118,13 +120,26 @@
     }
 }
 
+// Given an FQName of "android.hardware.nfc@1.0::INfc", return
+// "android/hardware/".
+static std::string ConvertPackageRootToPath(
+        const Coordinator *coordinator, const FQName &fqName) {
+    std::string packageRoot = coordinator->getPackageRoot(fqName);
+
+    if (*(packageRoot.end()--) != '.') {
+        packageRoot += '.';
+    }
+
+    std::replace(packageRoot.begin(), packageRoot.end(), '.', '/');
+
+    return packageRoot; // now converted to a path
+}
+
 status_t AST::generateInterfaceHeader(const std::string &outputPath) const {
-    const std::string packagePath =
-        mCoordinator->getPackagePath(mPackage, true /* relative */);
 
     std::string path = outputPath;
-    path.append("android/hardware/");
-    path.append(packagePath);
+    path.append(ConvertPackageRootToPath(mCoordinator, mPackage));
+    path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
 
     std::string ifaceName;
     bool isInterface = true;
@@ -308,15 +323,12 @@
         return OK;
     }
 
-    const std::string packagePath =
-        mCoordinator->getPackagePath(mPackage, true /* relative */);
-
     // cut off the leading 'I'.
     const std::string baseName = ifaceName.substr(1);
 
     std::string path = outputPath;
-    path.append("android/hardware/");
-    path.append(packagePath);
+    path.append(ConvertPackageRootToPath(mCoordinator, mPackage));
+    path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
     path.append("Bn");
     path.append(baseName);
     path.append(".h");
@@ -386,15 +398,12 @@
         return OK;
     }
 
-    const std::string packagePath =
-        mCoordinator->getPackagePath(mPackage, true /* relative */);
-
     // cut off the leading 'I'.
     const std::string baseName = ifaceName.substr(1);
 
     std::string path = outputPath;
-    path.append("android/hardware/");
-    path.append(packagePath);
+    path.append(ConvertPackageRootToPath(mCoordinator, mPackage));
+    path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
     path.append("Bp");
     path.append(baseName);
     path.append(".h");
@@ -489,12 +498,10 @@
 }
 
 status_t AST::generateAllSource(const std::string &outputPath) const {
-    const std::string packagePath =
-        mCoordinator->getPackagePath(mPackage, true /* relative */);
 
     std::string path = outputPath;
-    path.append("android/hardware/");
-    path.append(packagePath);
+    path.append(ConvertPackageRootToPath(mCoordinator, mPackage));
+    path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
 
     std::string ifaceName;
     std::string baseName;