summaryrefslogtreecommitdiff
path: root/cpp/src/Slice/Preprocessor.cpp
diff options
context:
space:
mode:
authorDwayne Boone <dwayne@zeroc.com>2008-01-09 10:46:08 -0330
committerDwayne Boone <dwayne@zeroc.com>2008-01-09 10:46:08 -0330
commitf24e7084d5ebce8689e02d5f322d175d4108cf00 (patch)
treec484017689764bed48fa846be070d168ff469d64 /cpp/src/Slice/Preprocessor.cpp
parentFinished fixes for bug 2132 (diff)
downloadice-f24e7084d5ebce8689e02d5f322d175d4108cf00.tar.bz2
ice-f24e7084d5ebce8689e02d5f322d175d4108cf00.tar.xz
ice-f24e7084d5ebce8689e02d5f322d175d4108cf00.zip
Use mcpp instead of icecpp
Diffstat (limited to 'cpp/src/Slice/Preprocessor.cpp')
-rw-r--r--cpp/src/Slice/Preprocessor.cpp354
1 files changed, 209 insertions, 145 deletions
diff --git a/cpp/src/Slice/Preprocessor.cpp b/cpp/src/Slice/Preprocessor.cpp
index 863e7f61d65..9129296ac8d 100644
--- a/cpp/src/Slice/Preprocessor.cpp
+++ b/cpp/src/Slice/Preprocessor.cpp
@@ -7,22 +7,42 @@
//
// **********************************************************************
+#include <IceUtil/DisableWarnings.h>
#include <Slice/Preprocessor.h>
+#include <Slice/Util.h>
#include <IceUtil/StringUtil.h>
+#include <IceUtil/UUID.h>
+#include <IceUtil/Unicode.h>
#include <algorithm>
#include <fstream>
#include <sys/types.h>
#include <sys/stat.h>
#ifndef _WIN32
-
# include <sys/wait.h>
#endif
using namespace std;
using namespace Slice;
-Slice::Preprocessor::Preprocessor(const string& path, const string& fileName, const string& args) :
+//
+// mcpp defines
+//
+namespace Slice
+{
+
+enum Outdest
+{
+ Out=0, Err=1, Dbg=2, Num_Outdest=3
+};
+
+};
+
+extern "C" int mcpp_lib_main(int argc, char** argv);
+extern "C" void mcpp_use_mem_buffers(int tf);
+extern "C" char* mcpp_get_mem_buffer(Outdest od);
+
+Slice::Preprocessor::Preprocessor(const string& path, const string& fileName, const vector<string>& args) :
_path(path),
_fileName(fileName),
_args(args),
@@ -86,7 +106,7 @@ Slice::Preprocessor::normalizeIncludePath(const string& path)
result.erase(result.size() - 1);
}
- return "\"" + result + "\"";
+ return result;
}
FILE*
@@ -97,70 +117,203 @@ Slice::Preprocessor::preprocess(bool keepComments)
return 0;
}
- string cmd = searchIceCpp();
-
- if(cmd.empty())
+ //
+ // Build arguments list.
+ //
+ vector<string> args = _args;
+ if(keepComments)
{
- return 0;
+ args.push_back("-C");
}
+ args.push_back(_fileName);
- if(keepComments)
+ char** argv = new char*[args.size() + 1];
+ argv[0] = "mcpp";
+ for(unsigned int i = 0; i < args.size(); ++i)
{
- cmd += " -C";
+ argv[i + 1] = (char*) args[i].c_str();
}
- cmd += " " + _args + " \"" + _fileName + "\"";
+ //
+ // Call mcpp using memory buffer.
+ //
+ mcpp_use_mem_buffers(1);
+ mcpp_lib_main(args.size() + 1, argv);
+ delete argv;
//
- // Open a pipe for reading to redirect icecpp output to _cppHandle.
+ // Write output to temporary file. Print errors to stderr.
//
+ string result;
+ char* buf = mcpp_get_mem_buffer(Out);
+
+ _cppFile = ".preprocess." + IceUtil::generateUUID();
#ifdef _WIN32
- _cppHandle = _popen(cmd.c_str(), "r");
+ _cppHandle = ::_wfopen(IceUtil::stringToWstring(_cppFile).c_str(), IceUtil::stringToWstring("w+").c_str());
#else
- _cppHandle = popen(cmd.c_str(), "r");
+ _cppHandle = ::fopen(_cppFile.c_str(), "w+");
#endif
+ if(buf)
+ {
+ ::fwrite(buf, strlen(buf), 1, _cppHandle);
+ }
+ ::rewind(_cppHandle);
+
+ char* err = mcpp_get_mem_buffer(Err);
+ if(err)
+ {
+ ::fputs(err, stderr);
+ }
+
+ mcpp_use_mem_buffers(0);
+
return _cppHandle;
}
void
-Slice::Preprocessor::printMakefileDependencies(Language lang)
+Slice::Preprocessor::printMakefileDependencies(Language lang, const vector<string>& includePaths)
{
if(!checkInputFile())
{
return;
}
- string cmd = searchIceCpp();
-
- if(cmd.empty())
+ //
+ // Build arguments list.
+ //
+ vector<string> args = _args;
+ args.push_back("-M");
+ args.push_back(_fileName);
+
+ char** argv = new char*[args.size() + 1];
+ for(unsigned int i = 0; i < args.size(); ++i)
{
- return;
+ argv[i + 1] = (char*) args[i].c_str();
}
- cmd += " -M " + _args + " \"" + _fileName + "\"";
+ //
+ // Call mcpp using memory buffer.
+ //
+ mcpp_use_mem_buffers(1);
+ mcpp_lib_main(args.size() + 1, argv);
+ delete argv;
+
+ //
+ // Get mcpp output/errors.
+ //
+ string unprocessed;
+ char* buf = mcpp_get_mem_buffer(Out);
+ if(buf)
+ {
+ unprocessed = string(buf);
+ }
+
+ char* err = mcpp_get_mem_buffer(Err);
+ if(err)
+ {
+ ::fputs(err, stderr);
+ }
+ mcpp_use_mem_buffers(0);
+
+ //
+ // We now need to massage then result to get desire output.
+ // First make it a single line.
+ //
+ string::size_type pos;
+ while((pos = unprocessed.find("\\\n")) != string::npos)
+ {
+ unprocessed.replace(pos, 2, "");
+ }
+ //
+ // Get the main output file name.
+ //
#ifdef _WIN32
- FILE* cppHandle = _popen(cmd.c_str(), "r");
+ string suffix = ".obj:";
#else
- FILE* cppHandle = popen(cmd.c_str(), "r");
+ string suffix = ".o:";
#endif
+ pos = unprocessed.find(suffix) + suffix.size();
+ string result = unprocessed.substr(0, pos);
+
+ //
+ // Process each dependency.
+ //
+ string::size_type end;
+ while((end = unprocessed.find(".ice", pos)) != string::npos)
+ {
+ end += 4;
+ string file = unprocessed.substr(pos, end - pos);
+
+ //
+ // Strip white space from the file name.
+ //
+ int b = file.find_first_not_of(" \t");
+ int e = file.find_last_not_of(" \t");
+ file = file.substr(b, e - b + 1);
+
+ //
+ // Normalize paths if not relative path.
+ //
+ if(isAbsolute(file))
+ {
+ string newFile = file;
+ string cwd = getCwd();
+ for(vector<string>::const_iterator p = includePaths.begin(); p != includePaths.end(); ++p)
+ {
+ string includePath = *p;
+ if(!isAbsolute(includePath))
+ {
+ includePath = cwd + "/" + includePath;
+ }
+ includePath = normalizePath(includePath, false);
+
+ if(file.compare(0, includePath.length(), includePath) == 0)
+ {
+ string s = *p + file.substr(includePath.length());
+ if(isAbsolute(newFile) || s.size() < newFile.size())
+ {
+ newFile = s;
+ }
+ }
+ }
+ file = newFile;
+ }
+
+ //
+ // Escape spaces in the file name.
+ //
+ string::size_type space = 0;
+ while((space = file.find(" ", space)) != string::npos)
+ {
+ file.replace(space, 1, "\\ ");
+ space += 2;
+ }
+
+ //
+ // Add to result
+ //
+ result += " \\\n " + file;
+ pos = end;
+ }
+ result += "\n";
/*
* icecpp emits dependencies in any of the following formats, depending on the
* length of the filenames:
*
- * x.cpp: /path/x.ice /path/y.ice
+ * x.o[bj]: /path/x.ice /path/y.ice
*
- * x.cpp: /path/x.ice \
+ * x.o[bj]: /path/x.ice \
* /path/y.ice
*
- * x.cpp: /path/x.ice /path/y.ice \
+ * x.o[bj]: /path/x.ice /path/y.ice \
* /path/z.ice
*
- * x.cpp: \
+ * x.o[bj]: \
* /path/x.ice
*
- * x.cpp: \
+ * x.o[bj]: \
* /path/x.ice \
* /path/y.ice
*
@@ -172,10 +325,13 @@ Slice::Preprocessor::printMakefileDependencies(Language lang)
{
case CPlusPlus:
{
- char buf[1024];
- while(fgets(buf, static_cast<int>(sizeof(buf)), cppHandle) != NULL)
+ //
+ // Change .o[bj] suffix to .cpp suffix.
+ //
+ string::size_type pos;
+ while((pos = result.find(suffix)) != string::npos)
{
- fputs(buf, stdout);
+ result.replace(pos, suffix.size() - 1, ".cpp");
}
break;
}
@@ -185,37 +341,28 @@ Slice::Preprocessor::printMakefileDependencies(Language lang)
// We want to shift the files left one position, so that
// "x.cpp: x.ice y.ice" becomes "x.ice: y.ice".
//
- // Since the pipe input can be returned a line at a time, we collect
- // all of the output into one string before manipulating it.
- //
- string deps;
- char buf[1024];
- while(fgets(buf, static_cast<int>(sizeof(buf)), cppHandle) != NULL)
- {
- deps.append(buf, strlen(buf));
- }
//
// Remove the first file.
//
- string::size_type start = deps.find(".cpp:");
+ string::size_type start = result.find(suffix);
assert(start != string::npos);
- start = deps.find_first_not_of(" \t\r\n\\", start + 5); // Skip to beginning of next file.
+ start = result.find_first_not_of(" \t\r\n\\", start + suffix.size()); // Skip to beginning of next file.
assert(start != string::npos);
- deps.erase(0, start);
+ result.erase(0, start);
//
// Find end of next file.
//
string::size_type pos = 0;
- while((pos = deps.find_first_of(" :\t\r\n\\", pos + 1)) != string::npos)
+ while((pos = result.find_first_of(" :\t\r\n\\", pos + 1)) != string::npos)
{
- if(deps[pos] == ':')
+ if(result[pos] == ':')
{
- deps.insert(pos, 1, '\\'); // Escape colons.
+ result.insert(pos, 1, '\\'); // Escape colons.
++pos;
}
- else if(deps[pos] == '\\') // Ignore escaped characters.
+ else if(result[pos] == '\\') // Ignore escaped characters.
{
++pos;
}
@@ -227,75 +374,23 @@ Slice::Preprocessor::printMakefileDependencies(Language lang)
if(pos == string::npos)
{
- deps.append(":");
+ result.append(":");
}
else
{
- deps.insert(pos, 1, ':');
+ result.insert(pos, 1, ':');
}
-
- fputs(deps.c_str(), stdout);
break;
}
case CSharp:
{
//
- // Change .cpp suffix to .cs suffix.
+ // Change .o[bj] suffix to .cs suffix.
//
- char buf[1024];
- while(fgets(buf, static_cast<int>(sizeof(buf)), cppHandle) != NULL)
+ string::size_type pos;
+ while((pos = result.find(suffix)) != string::npos)
{
- char* dot;
- char* colon = strchr(buf, ':');
- if(colon != NULL)
- {
- *colon = '\0';
- dot = strrchr(buf, '.');
- *colon = ':';
- if(dot != NULL)
- {
- if(strncmp(dot, ".cpp:", 5) == 0)
- {
- *dot = '\0';
- fputs(buf, stdout);
- fputs(".cs", stdout);
- fputs(colon, stdout);
- continue;
- }
- }
- }
- fputs(buf, stdout);
- }
- break;
- }
- case VisualBasic:
- {
- //
- // Change .cpp suffix to .vb suffix.
- //
- char buf[1024];
- while(fgets(buf, static_cast<int>(sizeof(buf)), cppHandle) != NULL)
- {
- char* dot;
- char* colon = strchr(buf, ':');
- if(colon != NULL)
- {
- *colon = '\0';
- dot = strrchr(buf, '.');
- *colon = ':';
- if(dot != NULL)
- {
- if(strncmp(dot, ".cpp:", 5) == 0)
- {
- *dot = '\0';
- fputs(buf, stdout);
- fputs(".vb", stdout);
- fputs(colon, stdout);
- continue;
- }
- }
- }
- fputs(buf, stdout);
+ result.replace(pos, suffix.size() - 1, ".cpp");
}
break;
}
@@ -305,6 +400,11 @@ Slice::Preprocessor::printMakefileDependencies(Language lang)
break;
}
}
+
+ //
+ // Output result
+ //
+ fputs(result.c_str(), stdout);
}
bool
@@ -312,22 +412,18 @@ Slice::Preprocessor::close()
{
assert(_cppHandle);
-#ifndef _WIN32
- int status = pclose(_cppHandle);
- _cppHandle = 0;
-
- if(WIFEXITED(status) && WEXITSTATUS(status) != 0)
- {
- return false;
- }
-#else
- int status = _pclose(_cppHandle);
+ int status = fclose(_cppHandle);
_cppHandle = 0;
if(status != 0)
{
return false;
}
+
+#ifdef _WIN32
+ _unlink(_cppFile.c_str());
+#else
+ unlink(_cppFile.c_str());
#endif
return true;
@@ -360,35 +456,3 @@ Slice::Preprocessor::checkInputFile()
return true;
}
-
-string
-Slice::Preprocessor::searchIceCpp()
-{
-#ifndef _WIN32
- const char* icecpp = "icecpp";
-#else
- const char* icecpp = "icecpp.exe";
-#endif
-
- string::size_type pos = _path.find_last_of("/\\");
- if(pos != string::npos)
- {
- string path = _path.substr(0, pos + 1);
- path += icecpp;
-
- struct stat st;
- if(stat(path.c_str(), &st) == 0)
- {
-#ifndef _WIN32
- if(st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))
-#else
- if(st.st_mode & (S_IEXEC))
-#endif
- {
- return path;
- }
- }
- }
-
- return icecpp;
-}