#include <TCollection_AsciiString.hxx>
#include <TCollection_ExtendedString.hxx>
+#include <OSD_Process.hxx>
+#include <OSD_Path.hxx>
+#include <OSD.hxx>
#include <string.h>
#include <tcl.h>
delete[] TclArgv;
}
#else
- TclUTFToLocalStringSentry (int, const char **argv) : Argv((char**)argv) {}
+ TclUTFToLocalStringSentry (int, const char **argv) :
+ nb(0),
+ TclArgv(NULL),
+ Argv((char**)argv)
+ {}
#endif
const char **GetArgv () const { return (const char **)Argv; }
cout << flush;
}
- FILE* capture_start (int std_fd, int *save_fd)
+ FILE* capture_start (int std_fd, int *save_fd, char*& tmp_name)
{
- (*save_fd) = 0;
+ *save_fd = 0;
// open temporary files
- FILE * aTmpFile = tmpfile();
- int fd_tmp = fileno(aTmpFile);
-
- if (fd_tmp <0)
+ #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)
{
cerr << "Error: cannot create temporary file for capturing console output" << endl;
fclose (aTmpFile);
return aTmpFile;
}
- void capture_end (FILE* tmp_file, int std_fd, int save_fd, Standard_OStream &log, Standard_Boolean doEcho)
+ void capture_end (FILE* tmp_file, int std_fd, int save_fd, char* tmp_name, Standard_OStream &log, Standard_Boolean doEcho)
{
+ if (! tmp_file)
+ return;
+
// restore normal descriptors of console stream
dup2 (save_fd, std_fd);
close(save_fd);
// close temporary file
fclose (tmp_file);
+
+ // remove temporary file if this is not done by the system
+ if (tmp_name)
+ remove (tmp_name);
}
};
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;
if (doLog)
{
- aFile_out = capture_start (STDOUT_FILENO, &fd_out_save);
- aFile_err = capture_start (STDERR_FILENO, &fd_err_save);
+ aFile_out = capture_start (STDOUT_FILENO, &fd_out_save, out_name);
+ aFile_err = capture_start (STDERR_FILENO, &fd_err_save, err_name);
}
// run command
try {
OCC_CATCH_SIGNALS
+ // 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 );
cout << "An exception was caught " << E << endl;
- if (cc && atoi(cc)) {
+ if (cc && Draw::Atoi(cc)) {
#ifdef WNT
Tcl_Exit(0);
#else
// end capturing cout and cerr
if (doLog)
{
- capture_end (aFile_err, STDERR_FILENO, fd_err_save, di.Log(), doEcho);
- capture_end (aFile_out, STDOUT_FILENO, fd_out_save, di.Log(), doEcho);
+ 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);
}
// log command result
if (myInterp==NULL) Init();
CData* C = new CData(f,this);
- Standard_Size length, num_slashes, ii, jj, kk;
Tcl_CreateCommand(myInterp,pN,CommandCmd, (ClientData) C, CommandDelete);
// add the help
Tcl_SetVar2(myInterp,"Draw_Helps",pN,pHelp,TCL_GLOBAL_ONLY);
Tcl_SetVar2(myInterp,"Draw_Groups",pGroup,pN,
TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
- length = strlen(pFileName) ;
- char * a_string =
- new char[length + 1] ;
- jj = 0 ;
- num_slashes = 0 ;
- ii = length ;
- while (num_slashes < 3 && ii >= 0) {
- if (file_name[ii] == '/') {
- num_slashes += 1 ;
- }
- ii -= 1 ;
- }
- jj = 0 ;
- for (kk = ii+2 , jj =0 ; kk < length ; kk++) {
- a_string[jj] = file_name[kk] ;
- jj += 1 ;
- }
- a_string[jj] = '\0' ;
-
- Tcl_SetVar2(myInterp,"Draw_Files",pN,a_string,TCL_GLOBAL_ONLY);
-
- delete [] a_string;
+ // add path to source file (keep not more than two last subdirectories)
+ OSD_Path aPath (pFileName);
+ Standard_Integer nbTrek = aPath.TrekLength();
+ for (Standard_Integer i = 2; i < nbTrek; i++)
+ aPath.RemoveATrek (1);
+ aPath.SetDisk("");
+ aPath.SetNode("");
+ TCollection_AsciiString aSrcPath;
+ aPath.SystemName (aSrcPath);
+ Tcl_SetVar2(myInterp,"Draw_Files",pN,aSrcPath.ToCString(),TCL_GLOBAL_ONLY);
}
Draw_Interpretor& Draw_Interpretor::Append(const Standard_Integer i)
{
char c[100];
- sprintf(c,"%d",i);
+ Sprintf(c,"%d",i);
Tcl_AppendResult(myInterp,c,(Standard_CString)0);
return *this;
}
Draw_Interpretor& Draw_Interpretor::Append(const Standard_Real r)
{
char s[100];
- sprintf(s,"%.17g",r);
+ Sprintf(s,"%.17g",r);
Tcl_AppendResult(myInterp,s,(Standard_CString)0);
return *this;
}