idlc: new parameter -M: write GNU make dependencies

This commit is contained in:
Michael Stahl 2012-01-14 21:16:17 +01:00
parent 67ae80657a
commit b83fd45150
6 changed files with 157 additions and 21 deletions

View file

@ -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);

View file

@ -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()

View file

@ -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];
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);
if ( c != '/' )
outputFileUrl += OString::valueOf('/');
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();
}

View file

@ -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;
}

View file

@ -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";

View file

@ -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)