瀏覽代碼

HPCC-18132 - ESDL support include paths for searching EspInclude files

- Add the -i --includePath options to relevant esdl commands
- Add support in esdl compiler to search included files in the include
  paths

Signed-off-by: mayx <yanrui.ma@lexisnexisrisk.com>
mayx 7 年之前
父節點
當前提交
631590fe2a

+ 3 - 1
tools/esdlcmd-xml/CMakeLists.txt

@@ -26,6 +26,7 @@ project( esdl-xml )
 
 set ( SRCS
          ${CMAKE_CURRENT_SOURCE_DIR}/esdl2xml.cpp
+         ${CMAKE_CURRENT_SOURCE_DIR}/../esdlcmd/esdlcmdutils.cpp
     )
 
 include_directories (
@@ -33,6 +34,7 @@ include_directories (
          ${HPCC_SOURCE_DIR}/system/include
          ${HPCC_SOURCE_DIR}/system/jlib
          ${HPCC_SOURCE_DIR}/tools/esdlcomp
+         ${HPCC_SOURCE_DIR}/tools/esdlcmd
          ${CMAKE_CURRENT_SOURCE_DIR}
     )
 
@@ -49,4 +51,4 @@ endif ( UNIX )
 
 target_link_libraries ( esdl-xml
                         jlib
-                        esdlcomp)
+                        esdlcomp)

+ 15 - 0
tools/esdlcmd-xml/esdl2xml.cpp

@@ -19,9 +19,12 @@
 #include <stdlib.h>
 #include <string.h>
 #include "esdl2xml.hpp"
+#include "jprop.hpp"
+#include "esdlcmdutils.hpp"
 
 char** gArgv = NULL;
 int gArgc = 0;
+StringBuffer includePath;
 
 //------------------------------------------------------
 // usage
@@ -33,6 +36,7 @@ void static usage(const char* programName)
 
     puts("Available options:");
     puts(" -r|--recursive: process all includes");
+    puts(" -I|--include-path <include path>: Locations to look for included esdl files");
     puts(" -v|--verbose:   display information");
     puts(" -?/-h/--help:   show this usage page");
     exit(1);
@@ -56,6 +60,15 @@ void parseCommandLine(int argc, char* argv[], Esdl2Esxdl * cmd)
             {
                 cmd->setRecursive(true);
             }
+            else if (stricmp(argv[i], "-I")==0 || stricmp(argv[i], "--include-path")==0)
+            {
+                if (i < argc - 1)
+                {
+                    if(includePath.length() > 0)
+                        includePath.append(ENVSEPSTR);
+                    includePath.append(argv[++i]);
+                }
+            }
             else if (stricmp(argv[i], "-v")==0 || stricmp(argv[i], "--verbose")==0)
             {
                 cmd->setVerbose(true);
@@ -82,6 +95,8 @@ int main(int argc, char* argv[])
 {
     Owned<Esdl2Esxdl> cmd = new Esdl2Esxdl();
     parseCommandLine(argc, argv, cmd.get());
+    extractEsdlCmdOption(includePath, NULL, "ESDL_INCLUDE_PATH", "esdlIncludePath", NULL, NULL);
+    cmd->setIncluePath(includePath.str());
     cmd->transform(gArgv[1], (char*)gArgv[2]);
 
     delete [] gArgv;

+ 11 - 3
tools/esdlcmd-xml/esdl2xml.hpp

@@ -57,7 +57,7 @@ public:
             //prevent recursive adding of this same content
             added.setValue(source, true);
 
-            ESDLcompiler hc(source, out==NULL, outdir, outputIncludes, includedESDL);
+            ESDLcompiler hc(source, out==NULL, outdir, outputIncludes, includedESDL, includePath);
             hc.Process();
 
             if (optRecursive && hc.includes)
@@ -68,8 +68,8 @@ public:
                 IncludeInfo * ii;
                 for (ii=hc.includes;ii;ii=ii->next)
                 {
-                   subfile.setf("%s%s%s", srcDir.str(), ii->pathstr.str(), ESDL_FILE_EXTENSION);
-                   transform(subfile, outdir, out, outputIncludes, true);
+                    subfile.setf("%s%s%s", srcDir.str(), ii->pathstr.str(), ESDL_FILE_EXTENSION);
+                    transform(subfile, outdir, out, outputIncludes, true);
                 }
             }
 
@@ -83,10 +83,18 @@ public:
             fprintf(stdout, "ESDL definition: %s has already been loaded!\n", source);
     }
 
+    void setIncluePath(const char* path)
+    {
+        if (path && *path)
+            includePath.set(path);
+    }
+
 protected:
     bool      optRecursive;
     bool      optVerbose;
 
+    StringAttr includePath;
+
     AddedHash added;
 };
 

+ 1 - 0
tools/esdlcmd/CMakeLists.txt

@@ -36,6 +36,7 @@ set ( SRCS
          ${CMAKE_CURRENT_SOURCE_DIR}/esdl2ecl.cpp
          ${CMAKE_CURRENT_SOURCE_DIR}/esdlcmd_monitor.cpp
          ${CMAKE_CURRENT_SOURCE_DIR}/esdl-publish.cpp
+         ${CMAKE_CURRENT_SOURCE_DIR}/esdlcmdutils.cpp
          ${ESPSCM_GENERATED_DIR}/ws_esdlconfig_esp.cpp
     )
 

+ 25 - 3
tools/esdlcmd/esdl-publish.cpp

@@ -21,7 +21,7 @@
 
 #include "esdlcmd_core.hpp"
 #include "build-config.h"
-
+#include "esdlcmdutils.hpp"
 
 class EsdlPublishCmdCommon : public EsdlCmdCommon
 {
@@ -122,8 +122,7 @@ public:
         Owned<IClientPublishESDLDefinitionRequest> request = esdlConfigClient->createPublishESDLDefinitionRequest();
 
         StringBuffer esxml;
-        esdlHelper->getServiceESXDL(optSource.get(), optESDLService.get(), esxml, 0, NULL, (DEPFLAG_INCLUDE_TYPES & ~DEPFLAG_INCLUDE_METHOD));
-
+        esdlHelper->getServiceESXDL(optSource.get(), optESDLService.get(), esxml, 0, NULL, (DEPFLAG_INCLUDE_TYPES & ~DEPFLAG_INCLUDE_METHOD), optIncludePath.str());
         if (esxml.length()==0)
         {
             fprintf(stderr,"\nESDL Definition for service %s could not be loaded from: %s\n", optESDLService.get(), optSource.get());
@@ -160,6 +159,7 @@ public:
                 "   <servicename>               The ESDL defined ESP service to publish, optional if ESDL definition contains a single service definition\n"
                 "Options (use option flag followed by appropriate value):\n"
                 "   --overwrite                 Overwrite the latest version of this ESDL Definition\n"
+                ESDLOPT_INCLUDE_PATH_USAGE
                 );
 
         EsdlPublishCmdCommon::usage();
@@ -222,13 +222,35 @@ public:
        return true;
     }
 
+    bool parseCommandLineOption(ArgvIterator &iter)
+    {
+        StringAttr oneOption;
+        if (iter.matchOption(oneOption, ESDLOPT_INCLUDE_PATH) || iter.matchOption(oneOption, ESDLOPT_INCLUDE_PATH_S))
+        {
+            if(optIncludePath.length() > 0)
+                optIncludePath.append(ENVSEPSTR);
+            optIncludePath.append(oneOption.get());
+            return true;
+        }
+
+        if (EsdlPublishCmdCommon::parseCommandLineOption(iter))
+            return true;
+
+        return false;
+    }
+
     bool finalizeOptions(IProperties *globals)
     {
+        extractEsdlCmdOption(optIncludePath, globals, ESDLOPT_INCLUDE_PATH_ENV, ESDLOPT_INCLUDE_PATH_INI, NULL, NULL);
+
         if (optSource.isEmpty())
             throw MakeStringException( 0, "Source ESDL definition file (ecm|esdl|xml) must be provided" );
 
         return EsdlPublishCmdCommon::finalizeOptions(globals);
     }
+
+private:
+    StringBuffer optIncludePath;
 };
 
 class EsdlBindServiceCmd : public EsdlPublishCmdCommon

+ 13 - 4
tools/esdlcmd/esdl2ecl.cpp

@@ -86,7 +86,7 @@ public:
         return qname;
     }
 
-    void loadFile(const char *srcpath, const char *srcfile, const char *srcext="", IProperties *versions=NULL, bool loadincludes=false, bool isIncludedESDL=false, bool rollUp=false)
+    void loadFile(const char *srcpath, const char *srcfile, const char *srcext="", IProperties *versions=NULL, bool loadincludes=false, bool isIncludedESDL=false, bool rollUp=false, const char* includePath=NULL)
     {
         if (!srcfile || !*srcfile)
             throw MakeStringException(-1, "EsdlInclude no file name");
@@ -104,7 +104,7 @@ public:
             {
                 fileName.append(srcext);
                 StringBuffer esxml;
-                EsdlCmdHelper::convertECMtoESXDL(fileName.str(), srcfile, esxml, loadincludes && rollUp, true, true, isIncludedESDL);
+                EsdlCmdHelper::convertECMtoESXDL(fileName.str(), srcfile, esxml, loadincludes && rollUp, true, true, isIncludedESDL, includePath);
                 src = createPTreeFromXMLString(esxml, 0);
             }
             else if (!srcext || !*srcext || stricmp(srcext, XML_FILE_EXTENSION)==0)
@@ -176,7 +176,7 @@ public:
                 ForEachItemIn(idx, add_includes)
                 {
                     const char *file=add_includes.item(idx);
-                    loadFile(srcpath, file, srcext, versions, loadincludes, true, false);
+                    loadFile(srcpath, file, srcext, versions, loadincludes, true, false, includePath);
                 }
             }
         }
@@ -244,6 +244,14 @@ public:
                 continue;
             if (iter.matchOption(optECLHeaderBlock, ESDL_OPTION_ECL_HEADER_BLOCK))
                 continue;
+            StringAttr oneOption;
+            if (iter.matchOption(oneOption, ESDLOPT_INCLUDE_PATH) || iter.matchOption(oneOption, ESDLOPT_INCLUDE_PATH_S))
+            {
+                if(optIncludePath.length() > 0)
+                    optIncludePath.append(ENVSEPSTR);
+                optIncludePath.append(oneOption.get());
+                continue;
+            }
             if (matchCommandLineOption(iter, true)!=EsdlCmdOptionMatch)
                 return false;
         }
@@ -292,7 +300,7 @@ public:
 
         unsigned start = msTick();
         EsdlIndexedPropertyTrees trees;
-        trees.loadFile(srcPath.str(), srcName.str(), srcExt.str(), NULL, optProcessIncludes, false, optRollUpEclToSingleFile);
+        trees.loadFile(srcPath.str(), srcName.str(), srcExt.str(), NULL, optProcessIncludes, false, optRollUpEclToSingleFile, optIncludePath.str());
         DBGLOG("Time taken to load ESDL files %u", msTick() - start);
 
         StringBuffer idxxml("<types><type name=\"StringArrayItem\" src=\"share\"/>");
@@ -381,6 +389,7 @@ public:
                 "      --ecl-imports         Comma-delimited import list to be attached to output ECL\n"
                 "                            each entry generates a corresponding import *.<entry>\n"
                 "      --ecl-header          Text included in target header (must be valid ECL) \n"
+                "   " ESDLOPT_INCLUDE_PATH_USAGE
                 ,stdout);
     }
 

+ 12 - 2
tools/esdlcmd/esdlcmd_common.cpp

@@ -21,6 +21,7 @@
 #include "jargv.hpp"
 #include "junicode.hpp"
 #include "build-config.h"
+#include "esdlcmdutils.hpp"
 
 #include "esdlcmd_common.hpp"
 
@@ -132,7 +133,7 @@ bool EsdlConvertCmd::parseCommandLineOptions(ArgvIterator &iter)
     for (; !iter.done(); iter.next())
     {
         if (parseCommandLineOption(iter))
-            return true;
+            continue;
 
         if (matchCommandLineOption(iter, true)!=EsdlCmdOptionMatch)
             return false;
@@ -147,7 +148,14 @@ bool EsdlConvertCmd::parseCommandLineOption(ArgvIterator &iter)
         return true;
     if (iter.matchOption(optOutDirPath, ESDL_CONVERT_OUTDIR))
         return true;
-
+    StringAttr oneOption;
+    if (iter.matchOption(oneOption, ESDLOPT_INCLUDE_PATH) || iter.matchOption(oneOption, ESDLOPT_INCLUDE_PATH_S))
+    {
+        if(optIncludePath.length() > 0)
+            optIncludePath.append(ENVSEPSTR);
+        optIncludePath.append(oneOption.get());
+        return true;
+    }
     return false;
 }
 
@@ -163,6 +171,8 @@ esdlCmdOptionMatchIndicator EsdlConvertCmd::matchCommandLineOption(ArgvIterator
 
 bool EsdlConvertCmd::finalizeOptions(IProperties *globals)
 {
+    extractEsdlCmdOption(optIncludePath, globals, ESDLOPT_INCLUDE_PATH_ENV, ESDLOPT_INCLUDE_PATH_INI, NULL, NULL);
+
     if (optSource.isEmpty())
     {
         fprintf(stderr, "\nError: Source esdl parameter required\n");

+ 12 - 6
tools/esdlcmd/esdlcmd_common.hpp

@@ -103,7 +103,11 @@ typedef IEsdlCommand *(*EsdlCommandFactory)(const char *cmdname);
 #define ESDL_OPTION_ECL_INCLUDE_LIST    "--ecl-imports"
 #define ESDL_OPTION_ECL_HEADER_BLOCK    "--ecl-header"
 
-
+#define ESDLOPT_INCLUDE_PATH            "--include-path"
+#define ESDLOPT_INCLUDE_PATH_S          "-I"
+#define ESDLOPT_INCLUDE_PATH_ENV        "ESDL_INCLUDE_PATH"
+#define ESDLOPT_INCLUDE_PATH_INI        "esdlIncludePath"
+#define ESDLOPT_INCLUDE_PATH_USAGE      "   -I, --include-path <include path>    Locations to look for included esdl files\n"
 bool matchVariableOption(ArgvIterator &iter, const char prefix, IArrayOf<IEspNamedValue> &values);
 
 enum esdlCmdOptionMatchIndicator
@@ -155,7 +159,7 @@ public:
         return new EsdlCmdHelper();
     }
 
-    void loadDefinition(const char * sourceFileName, const char * serviceName, double version)
+    void loadDefinition(const char * sourceFileName, const char * serviceName, double version, const char* includePath)
     {
         if (!esdlDef.get())
             esdlDef.set(createEsdlDefinition());
@@ -168,7 +172,7 @@ public:
             if (stricmp(extension.str(),LEGACY_FILE_EXTENSION)==0 || stricmp(extension.str(),ESDL_FILE_EXTENSION)==0)
             {
                 StringBuffer esxml;
-                EsdlCmdHelper::convertECMtoESXDL(sourceFileName, filename.str(), esxml, true, verbose, false, true);
+                EsdlCmdHelper::convertECMtoESXDL(sourceFileName, filename.str(), esxml, true, verbose, false, true, includePath);
                 if (!serviceName || !*serviceName)
                 {
                     Owned<IPropertyTree> esdldeftree = createPTreeFromXMLString(esxml);
@@ -195,9 +199,9 @@ public:
         }
     }
 
-    void getServiceESXDL(const char * sourceFileName, const char * serviceName, StringBuffer & xmlOut, double version, IProperties *opts=NULL, unsigned flags=0)
+    void getServiceESXDL(const char * sourceFileName, const char * serviceName, StringBuffer & xmlOut, double version, IProperties *opts=NULL, unsigned flags=0, const char* includePath=NULL)
     {
-        loadDefinition(sourceFileName, serviceName, version);
+        loadDefinition(sourceFileName, serviceName, version, includePath);
 
         if (esdlDef)
         {
@@ -214,12 +218,13 @@ public:
         }
     }
 
-    static void convertECMtoESXDL(const char * filepath, const char * esxdlname, StringBuffer & esxml, bool recursive, bool verbose, bool outputincludes, bool isIncludedESDL)
+    static void convertECMtoESXDL(const char * filepath, const char * esxdlname, StringBuffer & esxml, bool recursive, bool verbose, bool outputincludes, bool isIncludedESDL, const char* includePath)
     {
         if (verbose)
             fprintf(stdout,"Converting ESDL file %s to XML\n", filepath);
 
         Owned<Esdl2Esxdl> cmd = new Esdl2Esxdl(recursive, verbose);
+        cmd->setIncluePath(includePath);
         esxml.setf( "<esxdl name=\"%s\">", esxdlname);
         cmd->transform(filepath, "", &esxml, outputincludes, isIncludedESDL); //output to buffer
         esxml.append("</esxdl>");
@@ -310,6 +315,7 @@ public:
 public:
     StringAttr optSource;
     StringAttr optOutDirPath;
+    StringBuffer optIncludePath;
 };
 
 class EsdlHelperConvertCmd : public EsdlConvertCmd

+ 7 - 1
tools/esdlcmd/esdlcmd_core.cpp

@@ -109,6 +109,9 @@ public:
             return true;
         if (iter.matchFlag(optNoArrayOf, ESDLOPT_NO_ARRAYOF))
             return true;
+        StringAttr oneOption;
+        if (iter.matchOption(oneOption, ESDLOPT_INCLUDE_PATH) || iter.matchOption(oneOption, ESDLOPT_INCLUDE_PATH_S))
+            return false;  //Return false to negate allowing the include path options from parent class
 
         if (EsdlConvertCmd::parseCommandLineOption(iter))
             return true;
@@ -689,6 +692,8 @@ public:
 
     virtual bool finalizeOptions(IProperties *globals)
     {
+        extractEsdlCmdOption(optIncludePath, globals, ESDLOPT_INCLUDE_PATH_ENV, ESDLOPT_INCLUDE_PATH_INI, NULL, NULL);
+
         if (optSource.isEmpty())
         {
             usage();
@@ -729,7 +734,7 @@ public:
 
     virtual int processCMD()
     {
-        cmdHelper.loadDefinition(optSource, optService, 0);
+        cmdHelper.loadDefinition(optSource, optService, 0, optIncludePath);
         Owned<IEsdlDefObjectIterator> structs = cmdHelper.esdlDef->getDependencies( optService, optMethod, ESDLOPTLIST_DELIMITER, 0, NULL, optFlags );
 
         if(!optPreprocessOutputDir.isEmpty())
@@ -765,6 +770,7 @@ public:
         puts("  --show-inheritance : Turns off the collapse feature. Collapsing optimizes the XML output to strip out structures" );
         puts("                        only used for inheritance, and collapses their elements into their child. That simplifies the" );
         puts("                        stylesheet. By default this option is on.");
+        puts(ESDLOPT_INCLUDE_PATH_USAGE);
     }
 
     virtual void usage()

+ 9 - 2
tools/esdlcmd/esdlcmd_monitor.cpp

@@ -27,6 +27,7 @@
 #include "esdl2ecl.cpp"
 #include "esdl-publish.cpp"
 #include "xsdparser.hpp"
+#include "esdlcmdutils.hpp"
 
 bool isUTF16Bom(const char *check)
 {
@@ -136,6 +137,8 @@ public:
 
     virtual bool finalizeOptions(IProperties *globals)
     {
+        extractEsdlCmdOption(optIncludePath, globals, ESDLOPT_INCLUDE_PATH_ENV, ESDLOPT_INCLUDE_PATH_INI, NULL, NULL);
+
         if (optSource.isEmpty())
         {
             usage();
@@ -279,12 +282,13 @@ public:
         puts("  <serviceName>    Name of the ESDL Service to generate the template for." );
         puts("  <methodName>     Name of the ESDL method to generate the template for." );
 
+        puts(ESDLOPT_INCLUDE_PATH_USAGE);
         EsdlConvertCmd::usage();
     }
 
     virtual void loadServiceDef()
     {
-        cmdHelper.loadDefinition(optSource, optService, 0);
+        cmdHelper.loadDefinition(optSource, optService, 0, optIncludePath);
     }
 
 public:
@@ -345,6 +349,8 @@ public:
 
     virtual bool finalizeOptions(IProperties *globals)
     {
+        extractEsdlCmdOption(optIncludePath, globals, ESDLOPT_INCLUDE_PATH_ENV, ESDLOPT_INCLUDE_PATH_INI, NULL, NULL);
+
         if (optSource.isEmpty())
         {
             usage();
@@ -950,7 +956,7 @@ public:
 
     virtual int processCMD()
     {
-        cmdHelper.loadDefinition(optSource, optService, 0);
+        cmdHelper.loadDefinition(optSource, optService, 0, optIncludePath);
 
         Owned<IEsdlDefObjectIterator> responseEsdl = cmdHelper.esdlDef->getDependencies(optService, optMethod, 0, nullptr, DEPFLAG_INCLUDE_RESPONSE | DEPFLAG_INCLUDE_METHOD | DEPFLAG_ECL_ONLY);
         Owned<IEsdlDefObjectIterator> requestEsdl = cmdHelper.esdlDef->getDependencies(optService, optMethod, 0, nullptr, DEPFLAG_INCLUDE_REQUEST | DEPFLAG_ECL_ONLY);
@@ -1124,6 +1130,7 @@ public:
         puts("  <diffTemplate>   The template that specifies the differencing and monitoring rules usedto generate the result");
         puts("                   differencing and monitoring ECL code for the given service method.\n" );
 
+        puts(ESDLOPT_INCLUDE_PATH_USAGE);
         EsdlConvertCmd::usage();
     }
 

+ 1 - 0
tools/esdlcmd/esdlcmd_shell.cpp

@@ -186,6 +186,7 @@ void EsdlCMDShell::usage()
            "   ecl               Generate ECL from ESDL definition.\n"
            "   xsd               Generate XSD from ESDL definition.\n"
            "   wsdl              Generate WSDL from ESDL definition.\n"
+           "   java              Generate Java code from ESDL definition.\n"
            "   publish           Publish ESDL Definition for ESP use.\n"
            "   list-definitions  List all ESDL definitions.\n"
            "   get-definition    Get ESDL definition.\n"

+ 40 - 0
tools/esdlcmd/esdlcmdutils.cpp

@@ -0,0 +1,40 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#include "esdlcmdutils.hpp"
+
+bool extractEsdlCmdOption(StringBuffer & option, IProperties * globals, const char * envName, const char * propertyName, const char * defaultPrefix, const char * defaultSuffix)
+{
+    if (option.length())        // check if already specified via a command line option
+        return true;
+    if (propertyName && globals && globals->getProp(propertyName, option))
+        return true;
+    if (envName && *envName)
+    {
+        const char * env = getenv(envName);
+        if (env)
+        {
+            option.append(env);
+            return true;
+        }
+    }
+    if (defaultPrefix)
+        option.append(defaultPrefix);
+    if (defaultSuffix)
+        option.append(defaultSuffix);
+    return false;
+}

+ 26 - 0
tools/esdlcmd/esdlcmdutils.hpp

@@ -0,0 +1,26 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+#ifndef __ESDLCMDUTILS_HPP__
+#define __ESDLCMDUTILS_HPP__
+
+#include "jlib.hpp"
+#include "jprop.hpp"
+
+bool extractEsdlCmdOption(StringBuffer & option, IProperties * globals, const char * envName, const char * propertyName, const char * defaultPrefix, const char * defaultSuffix);
+
+#endif

+ 0 - 1
tools/esdlcomp/esdl_utils.cpp

@@ -166,4 +166,3 @@ int es_createFile(const char* src, const char* tail, const char* ext)
     free(path);
     return h;
 }
-

+ 59 - 10
tools/esdlcomp/esdlcomp.cpp

@@ -1093,7 +1093,7 @@ char* getTargetBase(const char* outDir, const char* src)
         return strdup(src);
 }
 
-ESDLcompiler::ESDLcompiler(const char * sourceFile, bool generatefile, const char *outDir, bool outputIncludes_, bool isIncludedEsdl)
+ESDLcompiler::ESDLcompiler(const char * sourceFile, bool generatefile, const char *outDir, bool outputIncludes_, bool isIncludedEsdl, const char* includePath_)
 {
     outputIncludes = outputIncludes_;
     modules = NULL;
@@ -1109,6 +1109,9 @@ ESDLcompiler::ESDLcompiler(const char * sourceFile, bool generatefile, const cha
     StringBuffer prot;
     splitFilename(sourceFile, &prot, &srcDir, &name, &ext);
 
+    if (includePath_ && *includePath_)
+        includeDirs.appendList(includePath_, ENVSEPSTR);
+
     filename = strdup(sourceFile);
 
     yyin = fopen(sourceFile, "rt");
@@ -1116,15 +1119,10 @@ ESDLcompiler::ESDLcompiler(const char * sourceFile, bool generatefile, const cha
     {
         if (isIncludedEsdl)
         {
-            StringBuffer alternateExtFilename;
-            alternateExtFilename.setf("%s%s%s", (prot.length()>0) ? prot.str() : "", srcDir.str(), name.str());
-
-            if (stricmp(ext.str(), ESDL_FILE_EXTENSION)==0)
-                alternateExtFilename.append(LEGACY_FILE_EXTENSION);
-            else
-                alternateExtFilename.append(ESDL_FILE_EXTENSION);
-
-            yyin = fopen(alternateExtFilename.str(), "rt");
+            StringBuffer locatedFilePath;
+            bool located = locateIncludedFile(locatedFilePath, prot.str(), srcDir.str(), name.str(), ext.str());
+            if( located)
+                yyin = fopen(locatedFilePath.str(), "rt");
             if (!yyin)
             {
                 fprintf(stderr, "Fatal Error: Could not load included ESDL grammar %s\n", filename);
@@ -1154,6 +1152,57 @@ ESDLcompiler::ESDLcompiler(const char * sourceFile, bool generatefile, const cha
     }
 }
 
+bool ESDLcompiler::locateIncludedFile(StringBuffer& filepath, const char* prot, const char* srcDir, const char* fname, const char* ext)
+{
+    StringBuffer alternateExtFilename;
+    alternateExtFilename.setf("%s%s%s", (prot && *prot) ? prot : "", srcDir, fname);
+
+    const char* alt_ext;
+    if (stricmp(ext, LEGACY_FILE_EXTENSION)==0)
+        alt_ext = ESDL_FILE_EXTENSION;
+    else
+        alt_ext = LEGACY_FILE_EXTENSION;
+    alternateExtFilename.append(alt_ext);
+
+    OwnedIFile fileInSrcDir = createIFile(alternateExtFilename.str());
+    if (fileInSrcDir->exists())
+    {
+        filepath.set(alternateExtFilename.str());
+        return true;
+    }
+
+    ForEachItemIn(x, includeDirs)
+    {
+        const char* dir = includeDirs.item(x);
+        if (dir && *dir)
+        {
+            StringBuffer pathInInclude(dir);
+            pathInInclude.trim();
+            if (pathInInclude.charAt(pathInInclude.length() - 1) != PATHSEPCHAR)
+                pathInInclude.append(PATHSEPCHAR);
+            pathInInclude.append(fname);
+            VStringBuffer pathInIncludeFull("%s%s", pathInInclude.str(), ext);
+            OwnedIFile fileInInclude = createIFile(pathInIncludeFull.str());
+            if (fileInInclude->exists())
+            {
+                filepath.set(pathInIncludeFull.str());
+                return true;
+            }
+            pathInIncludeFull.setf("%s%s", pathInInclude.str(), alt_ext);
+            OwnedIFile altFileInInclude = createIFile(pathInIncludeFull.str());
+            if (altFileInInclude->exists())
+            {
+                filepath.set(pathInIncludeFull.str());
+                return true;
+            }
+        }
+    }
+
+    filepath.clear();
+    return false;
+}
+
+
 ESDLcompiler::~ESDLcompiler()
 {
     free(packagename);

+ 3 - 1
tools/esdlcomp/esdlcomp.h

@@ -1360,7 +1360,7 @@ public:
 class esdlcomp_decl ESDLcompiler
 {
 public:
-    ESDLcompiler(const char * sourceFile, bool generatefile, const char * outDir, bool outputIncludes, bool includedEsdl);
+    ESDLcompiler(const char * sourceFile, bool generatefile, const char * outDir, bool outputIncludes, bool includedEsdl, const char* includePath);
     ~ESDLcompiler();
 
     void Process();
@@ -1390,6 +1390,8 @@ private:
     char* packagename;
     StringBuffer srcDir;
     StringBuffer esxdlcontent;
+    StringArray includeDirs;
+    bool locateIncludedFile(StringBuffer& filepath, const char* prot, const char* srcDir, const char* fname, const char* ext);
 
 public:
     static CriticalSection m_critSect;