#include <OSD_Process.hxx>
#include <OSD_Path.hxx>
#include <OSD.hxx>
+#include <OSD_File.hxx>
#include <string.h>
#include <tcl.h>
+#ifndef _WIN32
+#include <unistd.h>
+#endif
// for capturing of cout and cerr (dup(), dup2())
-#ifdef _MSC_VER
+#ifdef _WIN32
#include <io.h>
#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
#if ! defined(STDOUT_FILENO)
#define STDOUT_FILENO fileno(stdout)
#define TCL_USES_UTF8
#endif
-//
-// Auxiliary tool to convert strings in command arguments from UTF-8
-// (Tcl internal encoding since Tcl 8.1) to system local encoding,
-// normally extended Ascii as expected by OCC commands
-//
-class TclUTFToLocalStringSentry {
- public:
-
-#ifdef TCL_USES_UTF8
- TclUTFToLocalStringSentry (int argc, const char **argv) :
- nb(0),
- TclArgv(new Tcl_DString[argc]),
- Argv(new char*[argc])
- {
- for (; nb < argc; nb++ ) {
- Tcl_UtfToExternalDString ( NULL, argv[nb], -1, &TclArgv[nb] );
- Argv[nb] = Tcl_DStringValue ( &TclArgv[nb] );
- }
- }
-
- ~TclUTFToLocalStringSentry ()
- {
- delete[] Argv;
- while ( nb-- >0 ) Tcl_DStringFree ( &TclArgv[nb] );
- delete[] TclArgv;
- }
-#else
- TclUTFToLocalStringSentry (int, const char **argv) :
- nb(0),
- TclArgv(NULL),
- Argv((char**)argv)
- {}
-#endif
-
- const char **GetArgv () const { return (const char **)Argv; }
-
- private:
- int nb;
- Tcl_DString *TclArgv;
- char **Argv;
-};
-
// logging helpers
namespace {
void dumpArgs (Standard_OStream& os, int argc, const char *argv[])
cout << flush;
}
- FILE* capture_start (int std_fd, int *save_fd, char*& tmp_name)
+ int capture_start (OSD_File& theTmpFile, int std_fd)
{
- *save_fd = 0;
-
- // open temporary files
- #if defined(_WIN32)
- // use _tempnam() to decrease chances of failure (tmpfile() creates
- // file in root folder and will fail if it is write protected), see #24132
- static const char* tmpdir = getenv("TEMP");
- static char prefix[256] = ""; // prefix for temporary files, initialize once per process using pid
- if (prefix[0] == '\0')
- sprintf (prefix, "drawtmp%d_", (int)OSD_Process().ProcessId());
- tmp_name = _tempnam (tmpdir, prefix);
- FILE* aTmpFile = (tmp_name != NULL ? fopen (tmp_name, "w+b") : tmpfile());
- #else
- tmp_name = NULL;
- FILE* aTmpFile = tmpfile();
- #endif
- int fd_tmp = (aTmpFile != NULL ? fileno (aTmpFile) : -1);
- if (fd_tmp < 0)
+ theTmpFile.BuildTemporary();
+ if (theTmpFile.Failed())
{
cerr << "Error: cannot create temporary file for capturing console output" << endl;
- fclose (aTmpFile);
- return NULL;
+ return -1;
}
// remember current file descriptors of standard stream, and replace it by temporary
- (*save_fd) = dup(std_fd);
- dup2(fd_tmp, std_fd);
- return aTmpFile;
+ return theTmpFile.Capture(std_fd);
}
- void capture_end (FILE* tmp_file, int std_fd, int save_fd, char* tmp_name, Standard_OStream &log, Standard_Boolean doEcho)
+ void capture_end (OSD_File* tmp_file, int std_fd, int save_fd, Standard_OStream &log, Standard_Boolean doEcho)
{
- if (! tmp_file)
+ if (!tmp_file)
return;
// restore normal descriptors of console stream
- dup2 (save_fd, std_fd);
+ #ifdef _WIN32
+ _dup2(save_fd, std_fd);
+ _close(save_fd);
+ #else
+ dup2(save_fd, std_fd);
close(save_fd);
+ #endif
// extract all output and copy it to log and optionally to cout
const int BUFSIZE = 2048;
- char buf[BUFSIZE];
- rewind(tmp_file);
- while (fgets (buf, BUFSIZE, tmp_file) != NULL)
+ TCollection_AsciiString buf;
+ tmp_file->Rewind();
+ while (tmp_file->ReadLine (buf, BUFSIZE) > 0)
{
log << buf;
if (doEcho)
}
// close temporary file
- fclose (tmp_file);
+ tmp_file->Close();
// remove temporary file if this is not done by the system
- if (tmp_name)
- remove (tmp_name);
+ if (tmp_file->Exists())
+ tmp_file->Remove();
}
-};
+
+} // anonymous namespace
// MKV 29.03.05
#if ((TCL_MAJOR_VERSION > 8) || ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4))) && !defined(USE_NON_CONST)
flush_standard_streams();
// capture cout and cerr to log
- char *err_name = NULL, *out_name = NULL;
- FILE * aFile_err = NULL;
- FILE * aFile_out = NULL;
- int fd_err_save = 0;
- int fd_out_save = 0;
+ OSD_File aFile_out, aFile_err;
+ int fd_err_save = -1;
+ int fd_out_save = -1;
if (doLog)
{
- aFile_out = capture_start (STDOUT_FILENO, &fd_out_save, out_name);
- aFile_err = capture_start (STDERR_FILENO, &fd_err_save, err_name);
+ fd_out_save = capture_start (aFile_out, STDOUT_FILENO);
+ fd_err_save = capture_start (aFile_err, STDERR_FILENO);
}
// run command
// get exception if control-break has been pressed
OSD::ControlBreak();
- // OCC63: Convert strings from UTF-8 to local encoding, normally expected by OCC commands
- TclUTFToLocalStringSentry anArgs ( argc, (const char**)argv );
+ // OCC680: Transfer UTF-8 directly to OCC commands without locale usage
- Standard_Integer fres = aCallback->Invoke ( di, argc, anArgs.GetArgv() );
+ Standard_Integer fres = aCallback->Invoke ( di, argc, argv /*anArgs.GetArgv()*/ );
if (fres != 0)
code = TCL_ERROR;
}
- catch (Standard_Failure) {
-
- Handle(Standard_Failure) E = Standard_Failure::Caught();
-
+ catch (Standard_Failure const& anException) {
// fail if Draw_ExitOnCatch is set
// MKV 29.03.05
#if ((TCL_MAJOR_VERSION > 8) || ((TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION >= 4))) && !defined(USE_NON_CONST)
"Draw_ExitOnCatch",TCL_GLOBAL_ONLY);
#endif
- cout << "An exception was caught " << E << endl;
+ cout << "An exception was caught " << anException << endl;
if (cc && Draw::Atoi(cc)) {
-#ifdef WNT
+#ifdef _WIN32
Tcl_Exit(0);
#else
Tcl_Eval(interp,"exit");
// get the error message
Standard_SStream ss;
- ss << "** Exception ** " << E << ends ;
-#ifdef USE_STL_STREAM
+ ss << "** Exception ** " << anException << ends;
Tcl_SetResult(interp,(char*)(ss.str().c_str()),TCL_VOLATILE);
-#else
- Tcl_SetResult(interp,(char*)(ss.str()),TCL_VOLATILE);
-#endif
code = TCL_ERROR;
}
// end capturing cout and cerr
if (doLog)
{
- capture_end (aFile_err, STDERR_FILENO, fd_err_save, err_name, di.Log(), doEcho);
- capture_end (aFile_out, STDOUT_FILENO, fd_out_save, out_name, di.Log(), doEcho);
+ capture_end (&aFile_err, STDERR_FILENO, fd_err_save, di.Log(), doEcho);
+ capture_end (&aFile_out, STDOUT_FILENO, fd_out_save, di.Log(), doEcho);
}
// log command result
aPath.SetNode ("");
TCollection_AsciiString aSrcPath;
aPath.SystemName (aSrcPath);
+ if (aSrcPath.Value(1) == '/')
+ aSrcPath.Remove(1);
Tcl_SetVar2 (myInterp, "Draw_Files", aName, aSrcPath.ToCString(), TCL_GLOBAL_ONLY);
}
Draw_Interpretor& Draw_Interpretor::Append(const Standard_SStream& s)
{
-#ifdef USE_STL_STREAM
return Append (s.str().c_str());
-#else
- // Note: use dirty tricks -- unavoidable with old streams
- TCollection_AsciiString aStr (((Standard_SStream&)AReason).str(), AReason.pcount());
- ((Standard_SStream&)AReason).freeze (false);
- return Append (aStr.ToCString());
-#endif
}
//=======================================================================
Standard_Integer Draw_Interpretor::Eval(const Standard_CString line)
{
- Standard_PCharacter pLine;
- //
- pLine=(Standard_PCharacter)line;
- //
- return Tcl_Eval(myInterp,pLine);
+ return Tcl_Eval(myInterp,line);
}
Standard_Integer Draw_Interpretor::RecordAndEval(const Standard_CString line,
const Standard_Integer flags)
{
- Standard_PCharacter pLine;
- //
- pLine=(Standard_PCharacter)line;
- return Tcl_RecordAndEval(myInterp,pLine,flags);
+ return Tcl_RecordAndEval(myInterp,line,flags);
}
//=======================================================================
Standard_Integer Draw_Interpretor::EvalFile(const Standard_CString fname)
{
- Standard_PCharacter pfname;
- //
- pfname=(Standard_PCharacter)fname;
- return Tcl_EvalFile(myInterp,pfname);
+ return Tcl_EvalFile(myInterp,fname);
}
//=======================================================================
Standard_PCharacter pLine;
//
pLine=(Standard_PCharacter)line;
- return Tcl_CommandComplete(pLine);
+ return Tcl_CommandComplete (pLine) != 0;
}
//=======================================================================
Tcl_Exit(0);
}
catch (Standard_Failure) {
-#ifdef DEB
+#ifdef OCCT_DEBUG
cout <<"Tcl_Exit have an exeption" << endl;
#endif
}
#else
-#ifdef WNT
+#ifdef _WIN32
Tcl_Exit(0);
#endif
#endif