diff options
author | Michael Stahl <mstahl@redhat.com> | 2012-01-14 21:16:17 +0100 |
---|---|---|
committer | Michael Stahl <mstahl@redhat.com> | 2012-01-14 21:22:12 +0100 |
commit | b83fd45150a411a2f8e8b621e844029d83c12473 (patch) | |
tree | 9fbfd69b324156c94954e868e885de9881a79fdc /idlc | |
parent | 67ae80657a053626df5186983ae6b6f20b90e52e (diff) |
idlc: new parameter -M: write GNU make dependencies
Diffstat (limited to 'idlc')
-rw-r--r-- | idlc/inc/idlc/idlc.hxx | 12 | ||||
-rw-r--r-- | idlc/source/idlc.cxx | 57 | ||||
-rw-r--r-- | idlc/source/idlcmain.cxx | 47 | ||||
-rw-r--r-- | idlc/source/idlcproduce.cxx | 46 | ||||
-rw-r--r-- | idlc/source/options.cxx | 14 | ||||
-rw-r--r-- | idlc/source/scanner.ll | 2 |
6 files changed, 157 insertions, 21 deletions
diff --git a/idlc/inc/idlc/idlc.hxx b/idlc/inc/idlc/idlc.hxx index 8262b26fc095..0bd4c2fd060a 100644 --- a/idlc/inc/idlc/idlc.hxx +++ b/idlc/inc/idlc/idlc.hxx @@ -54,6 +54,9 @@ public: void init(); + bool dumpDeps(::rtl::OString const& rDepFile, + ::rtl::OString const& rTarget); + Options* getOptions() { return m_pOptions; } AstStack* scopes() @@ -65,7 +68,7 @@ public: const ::rtl::OString& getFileName() { return m_fileName; } void setFileName(const ::rtl::OString& fileName) - { m_fileName = fileName; } + { m_fileName = fileName; addInclude(fileName); } const ::rtl::OString& getMainFileName() { return m_mainFileName; } void setMainFileName(const ::rtl::OString& mainFileName) @@ -118,7 +121,7 @@ public: void setParseState(ParseState parseState) { m_parseState = parseState; } - void insertInclude(const ::rtl::OString& inc) + void addInclude(const ::rtl::OString& inc) { m_includes.insert(inc); } StringSet* getIncludes() { return &m_includes; } @@ -149,9 +152,12 @@ private: StringSet m_includes; }; + +typedef ::std::pair< ::rtl::OString const&, ::rtl::OString const& > sPair_t; sal_Int32 compileFile(const ::rtl::OString * pathname); // a null pathname means stdin -sal_Int32 produceFile(const ::rtl::OString& filenameBase); +sal_Int32 produceFile(const ::rtl::OString& filenameBase, + sPair_t const*const pDepFile); // filenameBase is filename without ".idl" void removeIfExists(const ::rtl::OString& pathname); diff --git a/idlc/source/idlc.cxx b/idlc/source/idlc.cxx index c963287f6a5d..449de35a6835 100644 --- a/idlc/source/idlc.cxx +++ b/idlc/source/idlc.cxx @@ -44,7 +44,9 @@ #include "idlc/asttype.hxx" #include "idlc/asttypedef.hxx" -#include "osl/diagnose.h" +#include <osl/diagnose.h> +#include <osl/file.hxx> +#include <osl/thread.h> using namespace ::rtl; @@ -286,6 +288,59 @@ sal_Bool Idlc::isDocValid() return sal_False;; } +static void lcl_writeString(::osl::File & rFile, ::osl::FileBase::RC & o_rRC, + ::rtl::OString const& rString) +{ + sal_uInt64 nWritten(0); + if (::osl::FileBase::E_None == o_rRC) { + o_rRC = rFile.write(rString.getStr(), rString.getLength(), nWritten); + if (static_cast<sal_uInt64>(rString.getLength()) != nWritten) { + o_rRC = ::osl::FileBase::E_INVAL; //? + } + } +} + +struct WriteDep +{ + ::osl::File& m_rFile; + ::osl::FileBase::RC & m_rRC; + explicit WriteDep(::osl::File & rFile, ::osl::FileBase::RC & rRC) + : m_rFile(rFile), m_rRC(rRC) { } + void operator() (::rtl::OString const& rEntry) + { + lcl_writeString(m_rFile, m_rRC, " \\\n "); + lcl_writeString(m_rFile, m_rRC, rEntry); + } +}; + +bool +Idlc::dumpDeps(::rtl::OString const& rDepFile, ::rtl::OString const& rTarget) +{ + ::osl::File depFile( + ::rtl::OStringToOUString(rDepFile, osl_getThreadTextEncoding())); + ::osl::FileBase::RC rc = + depFile.open(osl_File_OpenFlag_Write | osl_File_OpenFlag_Create); + if (::osl::FileBase::E_None != rc) { + return false; + } + lcl_writeString(depFile, rc, rTarget); + if (::osl::FileBase::E_None != rc) { + return false; + } + lcl_writeString(depFile, rc, " :"); + if (::osl::FileBase::E_None != rc) { + return false; + } + m_includes.erase(getRealFileName()); // eeek, that is a temp file... + ::std::for_each(m_includes.begin(), m_includes.end(), + WriteDep(depFile, rc)); + if (::osl::FileBase::E_None != rc) { + return false; + } + rc = depFile.close(); + return ::osl::FileBase::E_None == rc; +} + static Idlc* pStaticIdlc = NULL; Idlc* SAL_CALL idlc() diff --git a/idlc/source/idlcmain.cxx b/idlc/source/idlcmain.cxx index f9faa7eb9739..399fd6f508df 100644 --- a/idlc/source/idlcmain.cxx +++ b/idlc/source/idlcmain.cxx @@ -86,7 +86,7 @@ SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv) if (nErrors > 0) { removeIfExists(outputUrl); } else { - nErrors = produceFile(outputUrl); + nErrors = produceFile(outputUrl, 0); } idlc()->reset(); } @@ -115,26 +115,43 @@ SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv) (*i).getStr()); // prepare output file name - OString outputFileUrl; + OString const strippedFileName( + sysFileName.copy(sysFileName.lastIndexOf(SEPARATOR) + 1)); + OString outputFile; if ( options.isValid("-O") ) { - OString strippedFileName(sysFileName.copy(sysFileName.lastIndexOf(SEPARATOR) + 1)); - outputFileUrl = convertToFileUrl(options.getOption("-O")); - sal_Char c = outputFileUrl.getStr()[outputFileUrl.getLength()-1]; - - if ( c != '/' ) - outputFileUrl += OString::valueOf('/'); + outputFile = (options.getOption("-O")); + if ('/' != outputFile.getStr()[outputFile.getLength()-1]) { + outputFile += OString::valueOf('/'); + } + outputFile += strippedFileName.replaceAt( + strippedFileName.getLength() -3 , 3, "urd"); + } else { + outputFile = + sysFileName.replaceAt(sysFileName.getLength() -3 , 3, "urd"); + } + OString const outputFileUrl = convertToFileUrl(outputFile); - outputFileUrl += strippedFileName.replaceAt(strippedFileName.getLength() -3 , 3, "urd"); - } else - { - outputFileUrl = convertToFileUrl(sysFileName.replaceAt(sysFileName.getLength() -3 , 3, "urd")); + ::rtl::OString depFileUrl; + if (options.isValid("-M")) { + depFileUrl = convertToFileUrl(options.getOption("-M")); + if ('/' != depFileUrl.getStr()[depFileUrl.getLength()-1]) { + depFileUrl += OString::valueOf('/'); + } + depFileUrl += strippedFileName.replaceAt( + strippedFileName.getLength() -3 , 3, "d"); } - if ( nErrors ) + if ( nErrors ) { + if (options.isValid("-M")) { + removeIfExists(depFileUrl); + } removeIfExists(outputFileUrl); - else - nErrors = produceFile(outputFileUrl); + } else { + sPair_t const pair(depFileUrl, outputFile); + nErrors = produceFile(outputFileUrl, + (options.isValid("-M")) ? &pair : 0); + } idlc()->reset(); } diff --git a/idlc/source/idlcproduce.cxx b/idlc/source/idlcproduce.cxx index 04ee34f94b19..f4ca2d998e5d 100644 --- a/idlc/source/idlcproduce.cxx +++ b/idlc/source/idlcproduce.cxx @@ -132,7 +132,8 @@ void removeIfExists(const OString& pathname) unlink(pathname.getStr()); } -sal_Int32 SAL_CALL produceFile(const OString& regFileName) +sal_Int32 SAL_CALL +produceFile(const OString& regFileName, sPair_t const*const pDepFile) { Options* pOptions = idlc()->getOptions(); @@ -145,6 +146,20 @@ sal_Int32 SAL_CALL produceFile(const OString& regFileName) return 1; } + OString depTmpName; + if (pDepFile) + { + depTmpName = pDepFile->first.replaceAt( + regFileName.getLength() -3, 3, "_idlc_"); + if ( !checkOutputPath(depTmpName) ) + { + fprintf(stderr, "%s: could not create path of dep file '%s'.\n", + pOptions->getProgramName().getStr(), pDepFile->first.getStr()); + return 1; + } + removeIfExists(depTmpName); + } + removeIfExists(regTmpName); OString urlRegTmpName = convertToFileUrl(regTmpName); @@ -192,6 +207,18 @@ sal_Int32 SAL_CALL produceFile(const OString& regFileName) return 1; } + if (pDepFile && !idlc()->dumpDeps(depTmpName, pDepFile->second)) + { + fprintf(stderr, "%s: could not write dep file '%s'\n", + pOptions->getProgramName().getStr(), pDepFile->first.getStr()); + removeIfExists(depTmpName); + removeIfExists(pDepFile->first); + removeIfExists(regTmpName); + removeIfExists(regFileName); + cleanPath(); + return 1; + } + removeIfExists(regFileName); if ( File::move(OStringToOUString(regTmpName, osl_getThreadTextEncoding()), @@ -205,6 +232,23 @@ sal_Int32 SAL_CALL produceFile(const OString& regFileName) } removeIfExists(regTmpName); + if (pDepFile) + { + removeIfExists(pDepFile->first); + if ( File::move(OStringToOUString(depTmpName, osl_getThreadTextEncoding()), + OStringToOUString(pDepFile->first, osl_getThreadTextEncoding())) != FileBase::E_None ) { + fprintf(stderr, "%s: cannot rename dep file '%s' to '%s'\n", + idlc()->getOptions()->getProgramName().getStr(), + depTmpName.getStr(), pDepFile->first.getStr()); + removeIfExists(depTmpName); + removeIfExists(pDepFile->first); + removeIfExists(regFileName); + cleanPath(); + return 1; + } + removeIfExists(depTmpName); + } + return 0; } diff --git a/idlc/source/options.cxx b/idlc/source/options.cxx index f6f8c6bb4b6d..b30a4ed07612 100644 --- a/idlc/source/options.cxx +++ b/idlc/source/options.cxx @@ -76,6 +76,7 @@ bool Options::checkArgument (std::vector< std::string > & rArgs, char const * ar switch (arg[1]) { case 'O': + case 'M': case 'I': case 'D': { @@ -214,6 +215,16 @@ bool Options::initOptions(std::vector< std::string > & rArgs) throw(IllegalArgum m_options["-O"] = param; break; } + case 'M': + { + if (!((++first != last) && ((*first)[0] != '-'))) + { + return badOption("invalid", option); + } + OString param((*first).c_str(), (*first).size()); + m_options["-M"] = param; + break; + } case 'I': { if (!((++first != last) && ((*first)[0] != '-'))) @@ -344,6 +355,9 @@ OString Options::prepareHelp() help += " The generated output is a registry file with\n"; help += " the same name as the idl input file (or 'stdin'\n"; help += " for -stdin).\n"; + help += " -M<path> = path specifies the output directory for deps.\n"; + help += " Generate GNU make dependency files with the\n"; + help += " same name as the idl input file.\n"; help += " -I<path> = path specifies a directory where include\n"; help += " files will be searched by the preprocessor.\n"; help += " Multiple directories can be combined with ';'.\n"; diff --git a/idlc/source/scanner.ll b/idlc/source/scanner.ll index 2206297a0ffd..1fdbeab6f574 100644 --- a/idlc/source/scanner.ll +++ b/idlc/source/scanner.ll @@ -215,7 +215,7 @@ static void idlParsePragma(sal_Char* pPragma) sal_Char* offset = begin; while (*offset != ',') offset++; //::rtl::OString include = pragma.copy(index + 8, offset - begin); - idlc()->insertInclude(pragma.copy(index + 8, (sal_Int32)(offset - begin))); + //unused// idlc()->insertInclude(pragma.copy(index + 8, (sal_Int32)(offset - begin))); } static void parseLineAndFile(sal_Char* pBuf) |