--- /dev/null
+WOKUnix_TimeStat.hxx
+WOKUnix_Timeval.hxx
+WOKUnix_FDSet.hxx
+WOKUnix_SigHandler.hxx
+WOKUnix_MaxPipeSize.hxx
+WOKUnix_regexp.h
+WOKUnix_regexp_1.c
+WOKUnix_WOKSteps.edl
+WOKUnix_CMPLRS.edl
+WOKUnix_StatBuf.hxx
+WOKUnix_Dir.hxx
+WOKUnix_DirEnt.hxx
+INTERNLIB
--- /dev/null
+WOKUnix
+MMgt
+TColStd
+TCollection
+Standard
+OSD
+WOKTools
--- /dev/null
+-- File: WOKUnix.cdl
+-- Created: Fri Jan 31 18:34:49 1997
+-- Author: Jean GAUTIER
+-- <jga@cobrax.paris1.matra-dtv.fr>
+---Copyright: Matra Datavision 1997
+
+
+package WOKUnix
+
+ ---Purpose:
+
+uses
+ EDL,
+ OSD,
+ TCollection,
+ TColStd,
+ SortTools,
+ MMgt,
+ WOKTools
+is
+
+ imported TimeStat;
+ imported Timeval;
+ imported FDSet;
+ imported SigHandler;
+ private imported Dir;
+ private imported DirEnt;
+ private imported StatBuf;
+
+ enumeration Signals is SIGPIPE, SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGKILL, SIGBUS, SIGSEGV, SIGCHILD;
+ enumeration BufferIs is STDOUT, STDERR;
+ enumeration PopenOutputMode is POPEN_MIX_OUT_ERR, POPEN_OUT_ERR;
+ enumeration PopenBufferMode is POPEN_BUFFERED, POPEN_IMMEDIATE, POPEN_ECHOIFBLOCKED;
+ enumeration ShellMode is SynchronousMode, AsynchronousMode, DumpScriptMode;
+
+
+ enumeration Extension is CFile, HFile, CDLFile, ODLFile, IDLFile, CXXFile,
+ HXXFile, IXXFile, JXXFile, LXXFile, GXXFile, INCFile,
+ PXXFile, F77File, CSHFile,
+ DBFile, FDDBFile, DDLFile, HO2File,
+ LibSchemaFile, AppSchemaFile,
+ LexFile, YaccFile, PSWFile, LWSFile, TemplateFile,
+ ObjectFile, MFile, CompressedFile, ArchiveFile, DSOFile, DATFile,
+ LispFile, IconFile, TextFile, TarFile,
+ --- WNT extensions
+ LIBFile, DEFile, RCFile, RESFile, IMPFile, EXPFile,
+ UnknownFile, NoExtFile;
+
+ enumeration RESyntax is RESyntaxAWK, RESyntaxEGREP, RESyntaxGREP, RESyntaxEMACS;
+
+ exception BufferOverflow inherits Failure from Standard;
+ exception ProcessTimeOut inherits Failure from Standard;
+
+ class Signal;
+
+ class AdmFile;
+ class Path;
+ class PathIterator;
+ class FDescr;
+ class RegExp;
+
+ private deferred class Buffer;
+ private class FileBuffer;
+ private class NoBuffer;
+ private class CantBlockBuffer;
+
+ private deferred class ProcessOutput;
+ private class MixedOutput;
+ private class OutErrOutput;
+ private class DumbOutput;
+
+ private class Process;
+ class ProcessManager;
+ class ShellManager;
+
+ private deferred class ShellStatus;
+ private class ASyncStatus;
+ private class SyncStatus;
+ private class DumpScript;
+
+ class Shell;
+ class RemoteShell;
+
+
+ private class SequenceOfProcess
+ instantiates Sequence from TCollection ( Process from WOKUnix);
+
+ private class StackOfDir
+ instantiates Stack from TCollection ( Dir from WOKUnix );
+
+ SystemLastError returns Integer from Standard;
+
+ SystemMessage(i : Integer from Standard)
+ returns CString from Standard;
+
+ LastSystemMessage
+ returns CString from Standard;
+
+end WOKUnix;
--- /dev/null
+
+
+#include <WOKUnix.ixx>
+
+#include <string.h>
+#include <errno.h>
+
+
+Standard_Integer WOKUnix::SystemLastError()
+{
+ return errno;
+}
+
+
+Standard_CString WOKUnix::SystemMessage(const Standard_Integer errCode)
+{
+ return strerror(errCode);
+}
+
+
+
+Standard_CString WOKUnix::LastSystemMessage()
+{
+ return strerror(SystemLastError());
+}
+
--- /dev/null
+-- File: WOKUnix_ASyncStatus.cdl
+-- Created: Thu Jun 8 20:05:09 1995
+-- Author: Jean GAUTIER
+-- <jga@cobrax>
+---Copyright: Matra Datavision 1995
+
+
+private class ASyncStatus from WOKUnix
+inherits ShellStatus from WOKUnix
+
+ ---Purpose:
+
+uses
+ Shell from WOKUnix,
+ AsciiString from TCollection
+is
+ Create returns mutable ASyncStatus from WOKUnix;
+ Create(apath : AsciiString from TCollection)
+ returns mutable ASyncStatus from WOKUnix;
+
+ EndCmd(me:mutable; ashell : Shell from WOKUnix) is redefined;
+ Sync(me:mutable; ashell : Shell from WOKUnix) is redefined;
+ Reset(me:mutable; ashell : Shell from WOKUnix) is redefined;
+
+end ASyncStatus;
--- /dev/null
+
+#include <WOKTools_Messages.hxx>
+#include <TCollection_HAsciiString.hxx>
+#include <TCollection_AsciiString.hxx>
+
+#include <WOKUnix_ASyncStatus.ixx>
+
+//=======================================================================
+//function : WOKUnix_ASyncStatus
+//purpose :
+//=======================================================================
+ WOKUnix_ASyncStatus::WOKUnix_ASyncStatus()
+{
+
+}
+
+//=======================================================================
+//function : WOKUnix_ASyncStatus
+//purpose :
+//=======================================================================
+ WOKUnix_ASyncStatus::WOKUnix_ASyncStatus(const TCollection_AsciiString & apath)
+ :WOKUnix_ShellStatus(apath)
+{
+
+}
+
+//=======================================================================
+//function : EndCmd
+//purpose :
+//=======================================================================
+void WOKUnix_ASyncStatus::EndCmd(const Handle(WOKUnix_Shell)& ashell)
+{
+ static Handle(TCollection_HAsciiString) abuf = new TCollection_HAsciiString("\n@ wok_csh_status += $status\n");
+
+ ashell->WOKUnix_Process::Send(abuf);
+
+#ifdef WOK_VERBOSE
+ VerboseMsg("WOK_PROCESS") << "WOKUnix_ASyncStatus::EndCmd" << "Accumulating Status" << endm;
+#endif
+ return;
+}
+
+//=======================================================================
+//function : Sync
+//purpose :
+//=======================================================================
+void WOKUnix_ASyncStatus::Sync(const Handle(WOKUnix_Shell)& ashell)
+{
+#ifdef USE_SYNCHRO
+ Handle(TCollection_HAsciiString) abuf = new TCollection_HAsciiString(TCollection_AsciiString("\n/tmp/synchro "));
+ abuf->AssignCat(Name());
+ abuf->AssignCat(" $wok_csh_status\n");
+#else
+ Handle(TCollection_HAsciiString) abuf = new TCollection_HAsciiString(TCollection_AsciiString("\necho $wok_csh_status > "));
+
+ abuf->AssignCat(Name());
+ abuf->AssignCat("\n");
+#endif
+
+ ashell->WOKUnix_Process::Send(abuf);
+
+ mystatus = ashell->SyncAndStatus();
+
+#ifdef WOK_VERBOSE
+ VerboseMsg("WOK_PROCESS") << "WOKUnix_ASyncStatus::Sync" << "GotStatus : " << mystatus << endm;
+#endif
+
+ Reset(ashell);
+
+ return;
+}
+
+//=======================================================================
+//function : Reset
+//purpose :
+//=======================================================================
+void WOKUnix_ASyncStatus::Reset(const Handle(WOKUnix_Shell)& ashell)
+{
+ static Handle(TCollection_HAsciiString) abuf = new TCollection_HAsciiString("\nset wok_csh_status = 0\n");
+ ashell->WOKUnix_Process::Send(abuf);
+#ifdef WOK_VERBOSE
+ VerboseMsg("WOK_PROCESS") << "WOKUnix_ASyncStatus::Reset" << "Reset Shell" << endm;
+#endif
+ return;
+}
+
--- /dev/null
+-- File: WOKUnix_AdmFile.cdl
+-- Created: Wed Jun 21 17:53:44 1995
+-- Author: Jean GAUTIER
+-- <jga@cobrax>
+---Copyright: Matra Datavision 1995
+
+class AdmFile from WOKUnix
+
+---Purpose: Reads a file in WOK format :
+--
+-- - lines beginning with # are ignored
+--
+-- - lines ending with \ are continued
+--
+-- - empty lines are ignored
+--
+inherits FDescr from WOKUnix
+uses
+ HAsciiString from TCollection,
+ HSequenceOfHAsciiString from TColStd,
+ Path from WOKUnix
+raises
+ ProgramError
+is
+ Create
+ ---Purpose: empty contructor
+ returns AdmFile from WOKUnix;
+
+ Create(apath : HAsciiString from TCollection)
+ ---Purpose: constructor initialising mypath
+ returns AdmFile from WOKUnix;
+
+ Create(apath : Path from WOKUnix)
+ ---Purpose: constructor initialising mypath
+ returns AdmFile from WOKUnix;
+
+ Read(me : out)
+ ---Purpose: Reads the file
+ returns HSequenceOfHAsciiString from TColStd raises ProgramError;
+end;
--- /dev/null
+
+#include <fstream.h>
+
+#include <WOKUnix_AdmFile.ixx>
+
+#include <WOKTools_Messages.hxx>
+
+#include <TColStd_HSequenceOfHAsciiString.hxx>
+
+#include <TCollection_AsciiString.hxx>
+#include <TCollection_HAsciiString.hxx>
+
+#include <OSD_Protection.hxx>
+
+#define MAX_READBUFFER 1024
+
+//=======================================================================
+//function : WOKUnix_AdmFile
+//purpose :
+//=======================================================================
+WOKUnix_AdmFile::WOKUnix_AdmFile()
+{
+}
+
+//=======================================================================
+//function : WOKUnix_AdmFile
+//purpose :
+//=======================================================================
+WOKUnix_AdmFile::WOKUnix_AdmFile(const Handle(WOKUnix_Path)& apath)
+{
+ SetPath(OSD_Path(apath->Name()->String()));
+}
+
+//=======================================================================
+//function : WOKUnix_AdmFile
+//purpose :
+//=======================================================================
+WOKUnix_AdmFile::WOKUnix_AdmFile(const Handle(TCollection_HAsciiString)& apath)
+{
+ SetPath(OSD_Path(apath->String()));
+}
+
+//=======================================================================
+//function : Read
+//purpose :
+//=======================================================================
+Handle(TColStd_HSequenceOfHAsciiString) WOKUnix_AdmFile::Read()
+{
+ Handle(TColStd_HSequenceOfHAsciiString) aresult = new TColStd_HSequenceOfHAsciiString;
+ Standard_Boolean tobecontinued;
+ Standard_Boolean iscontinued;
+ char buffer[MAX_READBUFFER];
+
+ if(Exists() == Standard_False)
+ {
+ ErrorMsg << "WOKUnix_AdmFile::Read" << "File : " << Name() << "does not exists" << endm;
+ Standard_ProgramError::Raise("WOKUnix_AdmFile::Read : File dos not exists");
+ }
+
+ if(KindOfFile() != OSD_FILE)
+ {
+ ErrorMsg << "WOKUnix_AdmFile::Read" << "File : " << Name() << " is not a plain file" << endm;
+ Standard_ProgramError::Raise("WOKUnix_AdmFile::Read");
+ }
+
+ ifstream astream(Name()->ToCString(), ios::in);
+
+ tobecontinued = Standard_False;
+
+ *buffer = '\0';
+ while(astream.getline(buffer, MAX_READBUFFER))
+ {
+ TCollection_AsciiString linebuf(buffer);
+ linebuf.LeftAdjust();
+
+ if(!linebuf.IsEmpty() && linebuf.Value(1) != '#' )
+ {
+ if(linebuf.Value(linebuf.Length()) == '\\')
+ {
+ linebuf.Trunc(linebuf.Length() - 1);
+ iscontinued = Standard_True;
+ }
+ else
+ {
+ iscontinued = Standard_False;
+ }
+
+ if(tobecontinued) {
+ aresult->Value(aresult->Length())->AssignCat(linebuf.ToCString());
+ }
+ else {
+ aresult->Append(new TCollection_HAsciiString(linebuf.ToCString()));
+ }
+
+ tobecontinued = iscontinued;
+ }
+ else tobecontinued = Standard_False;
+ *buffer = '\0';
+ }
+ astream.close();
+ return aresult;
+}
+
--- /dev/null
+-- File: WOKUnix_Buffer.cdl
+-- Created: Thu May 4 16:33:47 1995
+-- Author: Jean GAUTIER
+-- <jga@cobrax>
+---Copyright: Matra Datavision 1995
+
+private deferred class Buffer from WOKUnix
+inherits TShared from MMgt
+uses
+ BufferIs from WOKUnix,
+ FDescr from WOKUnix,
+ FDSet from WOKUnix,
+ Timeval from WOKUnix,
+ HSequenceOfHAsciiString from TColStd
+
+raises
+ BufferOverflow from WOKUnix,
+ ProcessTimeOut from WOKUnix
+is
+ Initialize(afd : FDescr from WOKUnix; astd : BufferIs from WOKUnix);
+
+ Clear(me : mutable);
+
+ GetFDescr(me) returns FDescr from WOKUnix;
+ SetFDescr(me:mutable; afd : FDescr from WOKUnix);
+
+ BufferIs(me) returns BufferIs from WOKUnix;
+ AssociatedChannel(me) returns FDescr from WOKUnix;
+
+ Select(me; afd : out Integer; atimeout : in out Timeval from WOKUnix; aset : in out FDSet from WOKUnix) is deferred;
+ Acquit(me:mutable; astatus : Integer from Standard; aset : FDSet from WOKUnix) raises ProcessTimeOut from WOKUnix is deferred;
+
+ Echo(me : mutable) returns HSequenceOfHAsciiString from TColStd is virtual;
+ Errors(me : mutable) returns HSequenceOfHAsciiString from TColStd is virtual;
+
+ Write(me : mutable ; afd : in out FDescr from WOKUnix) ;
+
+ Close(me:mutable) is virtual;
+
+fields
+ myfd : FDescr from WOKUnix;
+ mystd : BufferIs from WOKUnix;
+end;
--- /dev/null
+
+#include <WOKUnix_Buffer.ixx>
+
+#include <WOKTools_Messages.hxx>
+
+#include <TCollection_HAsciiString.hxx>
+
+//=======================================================================
+//function : WOKUnix_Buffer
+//purpose :
+//=======================================================================
+WOKUnix_Buffer::WOKUnix_Buffer(const WOKUnix_FDescr& afd, const WOKUnix_BufferIs astd) : myfd(afd), mystd(astd)
+{
+}
+
+//=======================================================================
+//function : Clear
+//purpose :
+//=======================================================================
+void WOKUnix_Buffer::Clear()
+{
+ Standard_Integer nb = myfd.GetNbToRead();
+ while(nb > 0)
+ {
+ TCollection_AsciiString buffer;
+ myfd.Read(buffer, nb);
+ nb = myfd.GetNbToRead();
+ }
+ return;
+}
+
+//=======================================================================
+//function : GetFDescr
+//purpose :
+//=======================================================================
+WOKUnix_FDescr WOKUnix_Buffer::GetFDescr() const
+{
+ return myfd;
+}
+
+//=======================================================================
+//function : SetFDescr
+//purpose :
+//=======================================================================
+void WOKUnix_Buffer::SetFDescr(const WOKUnix_FDescr& afd)
+{
+ myfd = afd;
+}
+
+//=======================================================================
+//function : BufferIs
+//purpose :
+//=======================================================================
+WOKUnix_BufferIs WOKUnix_Buffer::BufferIs() const
+{
+ return mystd;
+}
+
+//=======================================================================
+//function : AssociatedChannel
+//purpose :
+//=======================================================================
+WOKUnix_FDescr WOKUnix_Buffer::AssociatedChannel() const
+{
+ switch(mystd)
+ {
+ case WOKUnix_STDOUT:
+ return WOKUnix_FDescr::Stdout();
+ case WOKUnix_STDERR:
+ return WOKUnix_FDescr::Stderr();
+ default:
+ return WOKUnix_FDescr(-1);
+ }
+}
+
+
+//=======================================================================
+//function : Echo
+//purpose :
+//=======================================================================
+Handle(TColStd_HSequenceOfHAsciiString) WOKUnix_Buffer::Echo()
+{
+ Handle(TColStd_HSequenceOfHAsciiString) aseq = new TColStd_HSequenceOfHAsciiString;
+ Standard_Integer nbtoread = myfd.GetNbToRead();
+ Standard_Integer i=1;
+
+ if(!nbtoread) return aseq;
+
+ TCollection_AsciiString buffer;
+ TCollection_AsciiString astr;
+
+ myfd.Read(buffer, nbtoread);
+
+ Standard_CString aptr = buffer.ToCString();
+ Standard_CString aptr2 = buffer.ToCString();
+
+ i=0;
+ while(i<nbtoread)
+ {
+ if(*aptr2 == '\n')
+ {
+ *aptr2 = '\0';
+ aseq->Append(new TCollection_HAsciiString(aptr));
+ aptr = aptr2;
+ aptr++;
+ }
+ aptr2++;
+ i++;
+ }
+ if(aptr < aptr2)
+ {
+ aseq->Append(new TCollection_HAsciiString(aptr));
+ }
+
+ return aseq;
+}
+
+//=======================================================================
+//function : Errors
+//purpose :
+//=======================================================================
+Handle(TColStd_HSequenceOfHAsciiString) WOKUnix_Buffer::Errors()
+{
+ Handle(TColStd_HSequenceOfHAsciiString) aseq = new TColStd_HSequenceOfHAsciiString;
+ Standard_Integer nbtoread = myfd.GetNbToRead();
+ Standard_Integer i=1;
+ TCollection_AsciiString buffer;
+ TCollection_AsciiString astr;
+
+ myfd.Read(buffer, nbtoread);
+
+ Standard_CString aptr = buffer.ToCString();
+ Standard_CString aptr2 = buffer.ToCString();
+
+ i=0;
+ while(i<nbtoread)
+ {
+ if(*aptr2 == '\n')
+ {
+ *aptr2 = '\0';
+ aseq->Append(new TCollection_HAsciiString(aptr));
+ aptr = aptr2;
+ aptr++;
+ }
+ aptr2++;
+ i++;
+ }
+ if(aptr < aptr2)
+ {
+ aseq->Append(new TCollection_HAsciiString(aptr));
+ }
+
+ return aseq;
+}
+
+//=======================================================================
+//function : Write
+//purpose :
+//=======================================================================
+void WOKUnix_Buffer::Write( WOKUnix_FDescr& afd)
+{
+ Standard_Integer nb = myfd.GetNbToRead();
+
+ if(nb > 0 )
+ {
+ TCollection_AsciiString buffer;
+
+ myfd.Read(buffer, nb);
+ afd.Reset();
+ afd.Write(buffer, nb);
+ }
+}
+
+//=======================================================================
+//function : Close
+//purpose :
+//=======================================================================
+void WOKUnix_Buffer::Close()
+{
+ if(myfd.FileNo() >= 0) myfd.Close();
+}
--- /dev/null
+-- File: WOKUnix_CMPLRS.edl
+-- Author: Prestataire Pascal BABIN
+-- History: Wed Jan 29 14:13:00 1997 Prestataire Pascal BABIN Creation
+-- Copyright: Matra Datavision 1997
+
+@ifnotdefined ( %WOKUnix_CMPLRS_EDL) then
+@set %WOKUnix_CMPLRS_EDL = "";
+
+@if ( %Station == "hp" ) then
+ @string %CMPLRS_C_Options = %CMPLRS_C_Options " -Ae";
+ @string %CMPLRS_CXX_Options = %CMPLRS_CXX_Options " -w +a1";
+@endif;
+
+@endif;
--- /dev/null
+-- File: WOKUnix_CantBlockBuffer.cdl
+-- Created: Tue May 9 13:56:16 1995
+-- Author: Jean GAUTIER
+-- <jga@cobrax>
+---Copyright: Matra Datavision 1995
+
+
+private class CantBlockBuffer from WOKUnix
+inherits Buffer from WOKUnix
+uses
+ BufferIs from WOKUnix,
+ FDescr from WOKUnix,
+ FDSet from WOKUnix,
+ Timeval from WOKUnix
+raises
+ BufferOverflow from WOKUnix,
+ ProcessTimeOut from WOKUnix
+is
+ Create(afd : FDescr from WOKUnix; astd : BufferIs from WOKUnix) returns mutable CantBlockBuffer from WOKUnix;
+
+ Select(me; afd : out Integer; atimeout : in out Timeval from WOKUnix; aset : in out FDSet from WOKUnix) is redefined;
+ Acquit(me:mutable; astatus : Integer from Standard; aset : FDSet from WOKUnix) raises ProcessTimeOut from WOKUnix is redefined;
+
+ Close(me:mutable) is redefined;
+
+fields
+ mybuffer : FDescr from WOKUnix;
+end;
--- /dev/null
+
+
+#include <WOKUnix_CantBlockBuffer.ixx>
+
+#include <WOKUnix_MaxPipeSize.hxx>
+
+//=======================================================================
+//function : WOKUnix_CantBlockBuffer
+//purpose : Constructs a CantBlockBuffer
+//=======================================================================
+WOKUnix_CantBlockBuffer::WOKUnix_CantBlockBuffer(const WOKUnix_FDescr& afd, const WOKUnix_BufferIs astd) : WOKUnix_Buffer(afd, astd)
+{
+}
+
+//=======================================================================
+//function : Select
+//purpose : Performs settings for the select operation
+//=======================================================================
+void WOKUnix_CantBlockBuffer::Select(Standard_Integer& afd, WOKUnix_Timeval& atimeout, WOKUnix_FDSet& aset) const
+{
+ afd = ( (afd) > (GetFDescr().FileNo()) ) ? afd : GetFDescr().FileNo();
+ atimeout.tv_sec = 0;
+ atimeout.tv_usec = 500;
+ return;
+}
+
+//=======================================================================
+//function : Acquit
+//purpose : Performs Acquitement of the select operation
+//=======================================================================
+void WOKUnix_CantBlockBuffer::Acquit(const Standard_Integer astatus, const WOKUnix_FDSet& aset)
+{
+ WOKUnix_FDescr afd = AssociatedChannel();
+ Standard_Integer nbtoread = GetFDescr().GetNbToRead();
+ if(nbtoread >= MAX_PIPE_SIZE)
+ {
+ cerr << "Error : CantBlockBuffer::Acquit : Could be blocked : Echo of " << AssociatedChannel().FileNo() << endl;
+ Write(afd);
+ }
+}
+
+void WOKUnix_CantBlockBuffer::Close()
+{
+ if(mybuffer.FileNo() >= 0) mybuffer.Close();
+ WOKUnix_Buffer::Close();
+}
--- /dev/null
+// File: WOKUnix_Dir.hxx
+// Author: Jean GAUTIER
+// <jga@cobrax>
+
+
+#ifndef WOKUnix_Dir_HeaderFile
+#define WOKUnix_Dir_HeaderFile
+
+#ifndef WNT
+
+#include <dirent.h>
+
+typedef DIR* WOKUnix_Dir;
+
+#else
+
+#error "Type Dir does not exist on WNT"
+
+#endif
+
+#endif
--- /dev/null
+// File: WOKUnix_Dir.hxx
+// Author: Jean GAUTIER
+// <jga@cobrax>
+
+
+#ifndef WOKUnix_DirEnt_HeaderFile
+#define WOKUnix_DirEnt_HeaderFile
+
+#ifndef WNT
+
+#include <dirent.h>
+
+typedef struct dirent* WOKUnix_DirEnt;
+
+#else
+
+#error "Type DirEnt does not exist on WNT"
+
+#endif
+
+#endif
--- /dev/null
+-- File: WOKUnix_DumbOutput.cdl
+-- Created: Tue May 9 14:02:54 1995
+-- Author: Jean GAUTIER
+-- <jga@cobrax>
+---Copyright: Matra Datavision 1995
+
+
+private class DumbOutput from WOKUnix
+inherits ProcessOutput from WOKUnix
+ ---Purpose:
+
+uses
+ Timeval from WOKUnix,
+ FDSet from WOKUnix,
+ FDescr from WOKUnix,
+ Buffer from WOKUnix,
+ HSequenceOfHAsciiString from TColStd
+
+is
+ Create returns mutable DumbOutput from WOKUnix;
+
+ Clear(me) is redefined;
+ Echo(me) returns HSequenceOfHAsciiString from TColStd is redefined;
+ Errors(me) returns HSequenceOfHAsciiString from TColStd is redefined;
+
+ Select(me; afdmax : out Integer from Standard; atimeout : in out Timeval from WOKUnix; aset : out FDSet from WOKUnix) is redefined;
+
+ Acquit(me; selectstatus : Integer; aset : FDSet from WOKUnix) is redefined;
+
+ Close(me:mutable) is redefined;
+
+fields
+ myout : Buffer from WOKUnix;
+ myerr : Buffer from WOKUnix;
+
+end DumbOutput;
--- /dev/null
+
+#include <WOKUnix_DumbOutput.ixx>
+
+//=======================================================================
+//function : WOKUnix_DumbOutput
+//purpose :
+//=======================================================================
+ WOKUnix_DumbOutput::WOKUnix_DumbOutput()
+{
+}
+
+
+//=======================================================================
+//function : Clear
+//purpose :
+//=======================================================================
+void WOKUnix_DumbOutput::Clear() const
+{
+}
+
+//=======================================================================
+//function : Echo
+//purpose :
+//=======================================================================
+Handle(TColStd_HSequenceOfHAsciiString) WOKUnix_DumbOutput::Echo() const
+{
+ return new TColStd_HSequenceOfHAsciiString;
+}
+
+//=======================================================================
+//function : Errors
+//purpose :
+//=======================================================================
+Handle(TColStd_HSequenceOfHAsciiString) WOKUnix_DumbOutput::Errors() const
+{
+ return new TColStd_HSequenceOfHAsciiString;
+}
+
+//=======================================================================
+//function : Select
+//purpose :
+//=======================================================================
+void WOKUnix_DumbOutput::Select(Standard_Integer& afdmax, WOKUnix_Timeval& atimeout, WOKUnix_FDSet& aset) const
+{
+}
+
+//=======================================================================
+//function : Acquit
+//purpose :
+//=======================================================================
+void WOKUnix_DumbOutput::Acquit(const Standard_Integer selectstatus, const WOKUnix_FDSet& aset) const
+{
+}
+
+//=======================================================================
+//function : Close
+//purpose :
+//=======================================================================
+void WOKUnix_DumbOutput::Close()
+{
+}
+
--- /dev/null
+-- File: WOKUnix_DumpScript.cdl
+-- Created: Thu Jun 8 20:07:55 1995
+-- Author: Jean GAUTIER
+-- <jga@cobrax>
+---Copyright: Matra Datavision 1995
+
+
+private class DumpScript from WOKUnix
+inherits ShellStatus from WOKUnix
+ ---Purpose:
+
+uses
+ AsciiString from TCollection,
+ Shell from WOKUnix
+is
+ Create returns mutable DumpScript from WOKUnix;
+ Create(apath : AsciiString from TCollection)
+ returns mutable DumpScript from WOKUnix;
+
+ EndCmd(me:mutable; ashell : Shell from WOKUnix) is redefined;
+ Sync(me:mutable; ashell : Shell from WOKUnix) is redefined;
+ Reset(me:mutable; ashell : Shell from WOKUnix) is redefined;
+
+ Get(me:mutable) returns Integer is redefined;
+
+end DumpScript;
--- /dev/null
+#include <TCollection_AsciiString.hxx>
+#include <WOKUnix_DumpScript.ixx>
+
+//=======================================================================
+//function : WOKUnix_DumpScript
+//purpose :
+//=======================================================================
+ WOKUnix_DumpScript::WOKUnix_DumpScript()
+{
+}
+
+//=======================================================================
+//function : WOKUnix_DumpScript
+//purpose :
+//=======================================================================
+ WOKUnix_DumpScript::WOKUnix_DumpScript(const TCollection_AsciiString & apath)
+ :WOKUnix_ShellStatus(apath)
+{
+}
+
+//=======================================================================
+//function : EndCmd
+//purpose :
+//=======================================================================
+void WOKUnix_DumpScript::EndCmd(const Handle(WOKUnix_Shell)& ashell)
+{
+}
+
+//=======================================================================
+//function : Sync
+//purpose :
+//=======================================================================
+void WOKUnix_DumpScript::Sync(const Handle(WOKUnix_Shell)& ashell)
+{
+}
+
+//=======================================================================
+//function : Reset
+//purpose :
+//=======================================================================
+void WOKUnix_DumpScript::Reset(const Handle(WOKUnix_Shell)& ashell)
+{
+}
+
+//=======================================================================
+//function : Get
+//purpose :
+//=======================================================================
+Standard_Integer WOKUnix_DumpScript::Get()
+{
+ return 0;
+}
+
--- /dev/null
+// File: WOKUnix_FDSet.hxx
+// Created: Tue May 9 15:25:38 1995
+// Author: Jean GAUTIER
+// <jga@cobrax>
+
+
+#ifndef WOKUnix_FDSet_HeaderFile
+#define WOKUnix_FDSet_HeaderFile
+
+#ifndef HPUX
+#include <sys/select.h>
+#define WOKUnix_FDSet_CAST fd_set *
+#endif
+
+#ifdef HPUX
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#define WOKUnix_FDSet_CAST fd_set *
+#endif
+
+typedef struct fd_set WOKUnix_FDSet;
+
+#endif
+
--- /dev/null
+-- File: WOKUnix_FDescr.cdl
+-- Created: Thu May 4 16:55:43 1995
+-- Author: Jean GAUTIER
+-- <jga@cobrax>
+---Copyright: Matra Datavision 1995
+
+class FDescr from WOKUnix
+inherits File from OSD
+uses
+ Path from OSD,
+ HAsciiString from TCollection,
+ AsciiString from TCollection
+
+raises
+ OSDError from OSD
+is
+ Create returns FDescr from WOKUnix;
+ Create( afd : Integer from Standard ) returns FDescr from WOKUnix;
+ Create( afd : Integer from Standard; apath : HAsciiString from TCollection) returns FDescr from WOKUnix;
+ Create( apath : HAsciiString from TCollection) returns FDescr from WOKUnix;
+
+ EmptyAndOpen(me: in out);
+
+ BuildTemporary(me: in out);
+ BuildTemporary(me: in out ; apath : AsciiString from TCollection);
+ BuildNamedPipe(me: in out);
+
+ GetNbToRead(me : in out) returns Integer from Standard;
+ SetUnBuffered(me : in out);
+ SetNonBlock(me : in out);
+ Flush(me : in out);
+ Dup(me : in out);
+ FileNo(me) returns Integer from Standard;
+ GetSize(me:in out) returns Integer from Standard;
+ Name(me) returns HAsciiString from TCollection;
+
+ ReadLine(me:out) returns HAsciiString from TCollection;
+
+ Pipe(myclass; anin : out FDescr from WOKUnix; anout : out FDescr from WOKUnix)
+ raises OSDError from OSD;
+
+ Stdin(myclass) returns FDescr from WOKUnix;
+ Stdout(myclass) returns FDescr from WOKUnix;
+ Stderr(myclass) returns FDescr from WOKUnix;
+
+fields
+ myFILE : Address from Standard;
+end;
--- /dev/null
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+
+#ifdef SOLARIS
+#include <sys/filio.h>
+#else
+#include <sys/ioctl.h>
+#endif
+#include <fcntl.h>
+
+#include <WOKUnix_FDescr.ixx>
+
+#include <WOKTools_Messages.hxx>
+
+#include <OSD_Protection.hxx>
+#include <OSD_OSDError.hxx>
+#include <Standard_ProgramError.hxx>
+
+extern "C" { extern int mknod (const char *, mode_t , dev_t ); }
+
+extern int errno;
+
+const OSD_WhoAmI Iam = OSD_WFile;
+
+//=======================================================================
+//function : WOKUnix_FDescr
+//purpose :
+//=======================================================================
+WOKUnix_FDescr::WOKUnix_FDescr()
+{
+ myFILE=NULL;
+}
+
+//=======================================================================
+//function : WOKUnix_FDescr
+//purpose :
+//=======================================================================
+WOKUnix_FDescr::WOKUnix_FDescr(const Standard_Integer afd) {myFileChannel = afd;myFILE = fdopen(afd, "r");}
+
+//=======================================================================
+//function : WOKUnix_FDescr
+//purpose :
+//=======================================================================
+WOKUnix_FDescr::WOKUnix_FDescr(const Standard_Integer afd, const Handle(TCollection_HAsciiString)& apath)
+{
+ myFileChannel = afd;
+ myFILE = fdopen(afd, "r");
+ SetPath(apath->String());
+}
+
+//=======================================================================
+//function : WOKUnix_FDescr
+//purpose :
+//=======================================================================
+WOKUnix_FDescr::WOKUnix_FDescr(const Handle(TCollection_HAsciiString)& apath)
+{
+ SetPath(apath->String());
+ myFILE = NULL;
+}
+
+//=======================================================================
+//function : EmptyAndOpen
+//purpose :
+//=======================================================================
+void WOKUnix_FDescr::EmptyAndOpen()
+{
+ fclose((FILE *)myFILE);
+ close(myFileChannel);
+ myFileChannel = open(Name()->ToCString(),
+ O_RDWR | O_CREAT | O_TRUNC,
+ S_IRUSR|S_IWUSR|S_IWUSR|S_IRGRP|S_IROTH);
+
+ myFILE = fdopen(myFileChannel, "r");
+}
+
+//=======================================================================
+//function : GetNbToRead
+//purpose :
+//=======================================================================
+Standard_Integer WOKUnix_FDescr::GetNbToRead()
+{
+ Standard_Integer nbtoread = 0;
+ if(ioctl(myFileChannel, FIONREAD, &nbtoread) < 0)
+ {
+ Perror();
+ return -1;
+ }
+ return nbtoread;
+}
+
+//=======================================================================
+//function : SetUnBuffered
+//purpose :
+//=======================================================================
+void WOKUnix_FDescr::SetUnBuffered()
+{
+ if(fcntl(myFileChannel, F_SETFL, O_SYNC) < 0)
+ {
+ Perror();
+ return;
+ }
+ return;
+}
+
+//=======================================================================
+//function : BuildTemporary
+//purpose :
+//=======================================================================
+void WOKUnix_FDescr::BuildTemporary()
+{
+
+ char *name = tmpnam((char*) 0) ;
+
+ TCollection_AsciiString aName ( name ) ;
+ OSD_Path aPath( aName ) ;
+
+ SetPath( aPath ) ;
+
+ Build(OSD_ReadWrite , OSD_Protection());
+ SetUnBuffered();
+
+}
+
+//=======================================================================
+//function : BuildTemporary
+//purpose :
+//=======================================================================
+void WOKUnix_FDescr::BuildTemporary(const TCollection_AsciiString & apath)
+{
+ TCollection_AsciiString astr(apath);
+
+ astr.AssignCat("/WOKXXXXXX");
+
+ char *name = mktemp(astr.ToCString()) ;
+
+ TCollection_AsciiString aName ( name ) ;
+ OSD_Path aPath( aName ) ;
+
+ SetPath( aPath ) ;
+
+ Build(OSD_ReadWrite, OSD_Protection());
+ SetUnBuffered();
+
+}
+
+//=======================================================================
+//function : BuildNamedPipe
+//purpose :
+//=======================================================================
+void WOKUnix_FDescr::BuildNamedPipe()
+{
+ TCollection_AsciiString apath;
+ WOKUnix_FDescr writeend;
+
+ apath = tmpnam(NULL);
+ SetPath(OSD_Path(apath));
+
+ if(mknod(apath.ToCString(), 0700 | S_IFIFO, 0))
+ { perror(apath.ToCString());}
+
+ myFileChannel = open(apath.ToCString(), O_RDONLY | O_NDELAY | O_CREAT);
+ SetUnBuffered();
+
+ // write end of pipe is unbuffered also
+ writeend.SetPath(OSD_Path(Name()->String()));
+ writeend.Open(OSD_WriteOnly, OSD_Protection());
+ writeend.SetUnBuffered();
+
+}
+
+//=======================================================================
+//function : SetNonBlock
+//purpose :
+//=======================================================================
+void WOKUnix_FDescr::SetNonBlock()
+{
+ if(fcntl(myFileChannel, F_SETFL, O_NONBLOCK) < 0)
+ {
+ Perror();
+ return;
+ }
+ return;
+}
+
+//=======================================================================
+//function : Flush
+//purpose :
+//=======================================================================
+void WOKUnix_FDescr::Flush()
+{
+ if(fsync(myFileChannel) < 0)
+ {
+ Perror();
+ }
+ return;
+}
+
+//=======================================================================
+//function : Dup
+//purpose :
+//=======================================================================
+void WOKUnix_FDescr::Dup()
+{
+ dup(myFileChannel);
+}
+
+//=======================================================================
+//function : FileNo
+//purpose :
+//=======================================================================
+Standard_Integer WOKUnix_FDescr::FileNo() const
+{
+ return myFileChannel;
+}
+
+//=======================================================================
+//function : GetSize
+//purpose :
+//=======================================================================
+Standard_Integer WOKUnix_FDescr::GetSize()
+{
+ struct stat buffer;
+ Handle(TCollection_HAsciiString) aname;
+ int status;
+
+ aname = Name();
+
+ if (aname->Length()==0)
+ Standard_ProgramError::Raise("OSD_File::Size : empty file name");
+
+ if(FileNo() == -1)
+ {
+ // si le fichier n;est pas ouvert pas le choix
+ status = stat( aname->ToCString() ,&buffer );
+ }
+ else
+ {
+ // si le fichier n;est pas ouvert pas le choix
+ status = fstat( FileNo() ,&buffer );
+ }
+ if (status == -1)
+ {
+ myError.SetValue (errno, Iam, "Size");
+ return (-1);
+ }
+
+ return ( buffer.st_size );
+
+}
+
+//=======================================================================
+//function : Name
+//purpose :
+//=======================================================================
+Handle(TCollection_HAsciiString) WOKUnix_FDescr::Name() const
+{
+ OSD_Path apath;
+ TCollection_AsciiString astring;
+
+ Path(apath);
+
+ apath.SystemName(astring);
+
+ return new TCollection_HAsciiString(astring);
+}
+
+//=======================================================================
+//function : ReadLine
+//purpose :
+//=======================================================================
+Handle(TCollection_HAsciiString) WOKUnix_FDescr::ReadLine()
+{
+ Handle(TCollection_HAsciiString) astr;
+
+ if(myFILE == NULL)
+ {
+ TCollection_AsciiString abuf;
+ Standard_Integer nbread = 0;
+
+ while(IsAtEnd() == Standard_False)
+ {
+ OSD_File::ReadLine(abuf, 1024, nbread);
+ if(astr.IsNull() && nbread < 1024)
+ {
+ astr = new TCollection_HAsciiString(abuf.ToCString());
+ return astr;
+ }
+ if(astr.IsNull() && nbread == 1024)
+ {
+ astr = new TCollection_HAsciiString(abuf.ToCString());
+ }
+ else if (!astr.IsNull() && nbread < 1024)
+ {
+ astr->AssignCat(abuf.ToCString());
+ return astr;
+ }
+ else // !astr.IsNull() && nbread == 1024
+ {
+ astr->AssignCat(abuf.ToCString());
+ }
+ }
+ }
+ else
+ {
+ TCollection_AsciiString abuf;
+ Standard_Integer nbread = 0;
+
+ while(GetNbToRead() != 0)
+ {
+ fgets(abuf.ToCString(), 1024, (FILE *) myFILE);
+ nbread = strlen(abuf.ToCString());
+ if(astr.IsNull() && nbread < 1024)
+ {
+ astr = new TCollection_HAsciiString(abuf.ToCString());
+ return astr;
+ }
+ if(astr.IsNull() && nbread == 1024)
+ {
+ astr = new TCollection_HAsciiString(abuf.ToCString());
+ }
+ else if (!astr.IsNull() && nbread < 1024)
+ {
+ astr->AssignCat(abuf.ToCString());
+ return astr;
+ }
+ else // !astr.IsNull() && nbread == 1024
+ {
+ astr->AssignCat(abuf.ToCString());
+ }
+ }
+ }
+ return astr;
+}
+
+
+//=======================================================================
+//function : Pipe
+//purpose :
+//=======================================================================
+void WOKUnix_FDescr::Pipe(WOKUnix_FDescr &anin, WOKUnix_FDescr &anout)
+{
+ Standard_Integer in[2];
+
+ if(pipe(in))
+ {
+ OSD_OSDError::Raise("WOKUnix_FDescr::Pipe : pipe system call Failed");
+ }
+
+ anin = WOKUnix_FDescr(in[1]);
+ anout = WOKUnix_FDescr(in[0]);
+
+ return;
+}
+
+//=======================================================================
+//function : Stdin
+//purpose :
+//=======================================================================
+WOKUnix_FDescr WOKUnix_FDescr::Stdin()
+{
+ static WOKUnix_FDescr StdinFD(0, new TCollection_HAsciiString("/dev/null/stdin"));
+
+ return StdinFD;
+}
+
+//=======================================================================
+//function : Stdout
+//purpose :
+//=======================================================================
+WOKUnix_FDescr WOKUnix_FDescr::Stdout()
+{
+ static WOKUnix_FDescr StdoutFD(1, new TCollection_HAsciiString("/dev/null/stdout"));
+
+ return StdoutFD;
+}
+
+//=======================================================================
+//function : Stderr
+//purpose :
+//=======================================================================
+WOKUnix_FDescr WOKUnix_FDescr::Stderr()
+{
+ static WOKUnix_FDescr StderrFD(2, new TCollection_HAsciiString("/dev/null/stderr"));
+
+ return StderrFD;
+}
+
+
+
+
+
+
--- /dev/null
+-- File: WOKUnix_FileBuffer.cdl
+-- Created: Thu May 4 18:27:14 1995
+-- Author: Jean GAUTIER
+-- <jga@cobrax>
+---Copyright: Matra Datavision 1995
+
+private class FileBuffer from WOKUnix
+inherits Buffer from WOKUnix
+uses
+ BufferIs from WOKUnix,
+ FDescr from WOKUnix,
+ FDSet from WOKUnix,
+ Timeval from WOKUnix,
+ HSequenceOfHAsciiString from TColStd
+
+raises
+ BufferOverflow from WOKUnix,
+ ProcessTimeOut from WOKUnix
+is
+ Create(afd : FDescr from WOKUnix; astd : BufferIs from WOKUnix) returns mutable FileBuffer from WOKUnix;
+
+ Select(me; afd : out Integer; atimeout : in out Timeval from WOKUnix; aset : in out FDSet from WOKUnix) is redefined;
+ Acquit(me:mutable; astatus : Integer from Standard; aset : FDSet from WOKUnix) raises ProcessTimeOut from WOKUnix is redefined;
+
+ Echo(me : mutable) returns HSequenceOfHAsciiString from TColStd is redefined;
+ Errors(me : mutable) returns HSequenceOfHAsciiString from TColStd is redefined;
+
+ Dump(me:mutable) raises BufferOverflow from WOKUnix is private;
+
+ Close(me:mutable) is redefined;
+
+fields
+ mybuffer : FDescr from WOKUnix;
+end;
--- /dev/null
+
+
+#include <OSD_Environment.hxx>
+#include <OSD_Path.hxx>
+
+
+#include <WOKTools_Messages.hxx>
+
+#include <WOKUnix_FileBuffer.ixx>
+
+#include <WOKUnix_MaxPipeSize.hxx>
+
+#include <TCollection_HAsciiString.hxx>
+
+// default buffer max size 1Mo : overided by WOK_MAXBUFFEREDSIZE var
+#define MAX_BUFFEREDSIZE 1048576
+
+//=======================================================================
+//function : WOKUnix_FileBuffer
+//purpose : contructs a file buffer with a FDescr
+//=======================================================================
+WOKUnix_FileBuffer::WOKUnix_FileBuffer(const WOKUnix_FDescr& afd, const WOKUnix_BufferIs astd) : WOKUnix_Buffer(afd, astd)
+{
+}
+
+//=======================================================================
+//function : Select
+//purpose : performs select settings
+//=======================================================================
+void WOKUnix_FileBuffer::Select(Standard_Integer& afd, WOKUnix_Timeval& atimeout, WOKUnix_FDSet& aset) const
+{
+ afd = ( (afd) > (GetFDescr().FileNo()) ) ? afd : GetFDescr().FileNo();
+ FD_SET(GetFDescr().FileNo(), &aset);
+ atimeout.tv_sec = 0;
+ atimeout.tv_usec = 500000;
+ return;
+}
+
+
+//=======================================================================
+//function : Errors
+//purpose :
+//=======================================================================
+Handle(TColStd_HSequenceOfHAsciiString) WOKUnix_FileBuffer::Errors()
+{
+ return Echo();
+}
+
+//=======================================================================
+//function : Echo
+//purpose :
+//=======================================================================
+Handle(TColStd_HSequenceOfHAsciiString) WOKUnix_FileBuffer::Echo()
+{
+ if(mybuffer.FileNo() != -1)
+ {
+ Handle(TColStd_HSequenceOfHAsciiString) aseq = new TColStd_HSequenceOfHAsciiString;
+ Standard_Integer nbread;
+
+ mybuffer.Reset();
+
+ mybuffer.Seek( 0, OSD_FromBeginning);
+
+ TCollection_AsciiString abuf;
+
+ while(mybuffer.IsAtEnd() == Standard_False)
+ {
+ aseq->Append(mybuffer.ReadLine());
+ }
+ aseq->Append(WOKUnix_Buffer::Echo());
+
+ mybuffer.Close();
+ mybuffer.Remove();
+
+ return aseq;
+ }
+ else return WOKUnix_Buffer::Echo();
+}
+
+//=======================================================================
+//function : Acquit
+//purpose : Acquits select
+//=======================================================================
+void WOKUnix_FileBuffer::Acquit(const Standard_Integer astatus, const WOKUnix_FDSet& aset)
+{
+ Standard_Integer nbtoread = GetFDescr().GetNbToRead();
+
+#ifdef WOK_VERBOSE
+ VerboseMsg("WOK_PROCESS") << "WOKUnix_FileBuffer::Acquit"
+ << "There is " << nbtoread << " bytes to read on process output" << endm;
+#endif
+
+ if(nbtoread >= MAX_PIPE_SIZE)
+ {
+ Dump();
+ }
+}
+
+
+//=======================================================================
+//function : Dump
+//purpose : Dumps contents of buffer in a FDescr
+//=======================================================================
+void WOKUnix_FileBuffer::Dump()
+{
+ OSD_Environment maxbsize("WOK_MAXBUFFEREDSIZE");
+ TCollection_AsciiString astring;
+ Standard_Integer maxsize;
+
+#ifdef WOK_VERBOSE
+ VerboseMsg("WOK_PROCESS") << "WOKUnix_FileBuffer::Dump"
+ << "Dumping" << endm;
+#endif
+
+ if(mybuffer.FileNo() == -1)
+ {
+ mybuffer.BuildTemporary();
+ }
+ else
+ {
+ astring = maxbsize.Value();
+ if(astring.IsIntegerValue() == Standard_False) maxsize = MAX_BUFFEREDSIZE;
+ else maxsize = astring.IntegerValue();
+
+ if(mybuffer.Size() >= maxsize)
+ {
+ WOKUnix_BufferOverflow::Raise("WOKUnix_FileBuffer::Dump : Buffer Overflow");
+ }
+ }
+ WOKUnix_Buffer::Write(mybuffer);
+#ifdef WOK_VERBOSE
+ VerboseMsg("WOK_PROCESS") << "WOKUnix_FileBuffer::Dump"
+ << "Dumped" << endm;
+#endif
+
+}
+
+//=======================================================================
+//function : Close
+//purpose : Closes
+//=======================================================================
+void WOKUnix_FileBuffer::Close()
+{
+ OSD_Path apath;
+
+ mybuffer.Path(apath);
+
+ if( apath.Name().IsEmpty() != Standard_True && mybuffer.FileNo() >= 0) mybuffer.Close();
+ WOKUnix_Buffer::Close();
+}
--- /dev/null
+// File: WOKUnix_MaxPipeSize.hxx
+// Created: Fri May 12 10:09:01 1995
+// Author: Jean GAUTIER
+// <jga@cobrax>
+
+
+#ifndef WOKUnix_MaxPipeSize_HeaderFile
+#define WOKUnix_MaxPipeSize_HeaderFile
+
+
+#ifdef HPUX
+#include <sys/inode.h>
+//#define MAX_PIPE_SIZE PIPSIZ
+#define MAX_PIPE_SIZE 8190
+#elif IRIX
+#include <limits.h>
+#define MAX_PIPE_SIZE PIPE_MAX
+#elif DECOSF1
+#include <sys/param.h>
+#define MAX_PIPE_SIZE PIPE_BUF
+#elif SOLARIS
+#include <sys/param.h>
+#define MAX_PIPE_SIZE PIPE_MAX
+#endif
+
+
+#endif
--- /dev/null
+-- File: WOKUnix_MixedOutput.cdl
+-- Created: Thu May 4 16:30:11 1995
+-- Author: Jean GAUTIER
+-- <jga@cobrax>
+---Copyright: Matra Datavision 1995
+
+private class MixedOutput from WOKUnix
+inherits ProcessOutput from WOKUnix
+uses
+ Timeval from WOKUnix,
+ FDSet from WOKUnix,
+ FDescr from WOKUnix,
+ Buffer from WOKUnix,
+ PopenBufferMode from WOKUnix,
+ HSequenceOfHAsciiString from TColStd
+is
+ Create returns mutable MixedOutput from WOKUnix;
+ Create(afd : FDescr from WOKUnix; amode : PopenBufferMode from WOKUnix) returns mutable MixedOutput from WOKUnix;
+ Create(anoutput : MixedOutput from WOKUnix; amode : PopenBufferMode from WOKUnix) returns mutable MixedOutput from WOKUnix;
+
+ Clear(me) is redefined;
+ Echo(me) returns HSequenceOfHAsciiString from TColStd is redefined;
+ Errors(me) returns HSequenceOfHAsciiString from TColStd is redefined;
+
+ Select(me; afdmax : out Integer from Standard; atimeout : in out Timeval from WOKUnix; aset : out FDSet from WOKUnix) is redefined;
+
+ Acquit(me; selectstatus : Integer; aset : FDSet from WOKUnix) is redefined;
+
+ Close(me:mutable) is redefined;
+
+fields
+ myout : Buffer from WOKUnix;
+
+end MixedOutput;
+
--- /dev/null
+
+#include <WOKUnix_MixedOutput.ixx>
+
+
+#include <WOKUnix_FileBuffer.hxx>
+#include <WOKUnix_NoBuffer.hxx>
+#include <WOKUnix_CantBlockBuffer.hxx>
+
+//=======================================================================
+//function : WOKUnix_MixedOutput
+//purpose :
+//=======================================================================
+WOKUnix_MixedOutput::WOKUnix_MixedOutput()
+{
+}
+
+//=======================================================================
+//function : WOKUnix_MixedOutput
+//purpose :
+//=======================================================================
+WOKUnix_MixedOutput::WOKUnix_MixedOutput(const WOKUnix_FDescr& afd, const WOKUnix_PopenBufferMode amode)
+{
+ switch(amode)
+ {
+ case WOKUnix_POPEN_BUFFERED:
+ myout = new WOKUnix_FileBuffer(afd, WOKUnix_STDOUT);
+ break;
+ case WOKUnix_POPEN_IMMEDIATE:
+ myout = new WOKUnix_NoBuffer(afd, WOKUnix_STDOUT);
+ break;
+ case WOKUnix_POPEN_ECHOIFBLOCKED:
+ myout = new WOKUnix_CantBlockBuffer(afd, WOKUnix_STDOUT);
+ break;
+ }
+}
+
+//=======================================================================
+//function : Echo
+//purpose :
+//=======================================================================
+Handle(TColStd_HSequenceOfHAsciiString) WOKUnix_MixedOutput::Echo() const
+{
+ return myout->Echo();
+}
+
+void WOKUnix_MixedOutput::Clear() const
+{
+ myout->Clear();
+}
+
+//=======================================================================
+//function : Errors
+//purpose :
+//=======================================================================
+Handle(TColStd_HSequenceOfHAsciiString) WOKUnix_MixedOutput::Errors() const
+{
+ return myout->Errors();
+}
+
+//=======================================================================
+//function : Select
+//purpose :
+//=======================================================================
+void WOKUnix_MixedOutput::Select(Standard_Integer& afdmax, WOKUnix_Timeval& atimeout, WOKUnix_FDSet& aset) const
+{
+ myout->Select(afdmax, atimeout, aset);
+}
+
+//=======================================================================
+//function : Acquit
+//purpose :
+//=======================================================================
+void WOKUnix_MixedOutput::Acquit(const Standard_Integer afd, const WOKUnix_FDSet& aset) const
+{
+ myout->Acquit(afd, aset);
+}
+
+//=======================================================================
+//function : Close
+//purpose :
+//=======================================================================
+void WOKUnix_MixedOutput::Close()
+{
+ myout->Close();
+}
+
--- /dev/null
+-- File: WOKUnix_NoBuffer.cdl
+-- Created: Thu May 4 18:30:08 1995
+-- Author: Jean GAUTIER
+-- <jga@cobrax>
+---Copyright: Matra Datavision 1995
+
+
+private class NoBuffer from WOKUnix
+inherits Buffer from WOKUnix
+uses
+ BufferIs from WOKUnix,
+ FDescr from WOKUnix,
+ FDSet from WOKUnix,
+ Timeval from WOKUnix
+raises
+ BufferOverflow from WOKUnix,
+ ProcessTimeOut from WOKUnix
+is
+ Create(afd : FDescr from WOKUnix; astd : BufferIs from WOKUnix) returns mutable NoBuffer from WOKUnix;
+
+ Select(me; afd : out Integer; atimeout : in out Timeval from WOKUnix; aset : in out FDSet from WOKUnix) is redefined;
+ Acquit(me:mutable; astatus : Integer from Standard; aset : FDSet from WOKUnix) raises ProcessTimeOut from WOKUnix is redefined;
+
+ Close(me:mutable) is redefined;
+
+fields
+ mybuffer : FDescr from WOKUnix;
+end;
--- /dev/null
+#include <WOKUnix_NoBuffer.ixx>
+
+ WOKUnix_NoBuffer::WOKUnix_NoBuffer(const WOKUnix_FDescr& afd, const WOKUnix_BufferIs astd) : WOKUnix_Buffer(afd, astd)
+{
+}
+
+void WOKUnix_NoBuffer::Select(Standard_Integer& afd, WOKUnix_Timeval& atimeout, WOKUnix_FDSet& aset) const
+{
+ afd = ( afd > GetFDescr().FileNo() ) ? afd : GetFDescr().FileNo();
+ if(atimeout.tv_sec < 0)
+ {
+ atimeout.tv_usec = 0;
+ }
+ else
+ {
+ atimeout.tv_sec = 0;
+ atimeout.tv_usec = 0;
+ }
+
+ FD_SET(GetFDescr().FileNo(), &aset);
+ GetFDescr().Flush();
+ return;
+}
+
+void WOKUnix_NoBuffer::Acquit(const Standard_Integer astatus, const WOKUnix_FDSet& aset)
+{
+ WOKUnix_FDescr afd = AssociatedChannel();
+ if(astatus == 0)
+ {
+ WOKUnix_ProcessTimeOut::Raise("NoBuffer::Acquit : time out\n");
+ return;
+ }
+ else
+ {
+ Write(afd);
+ }
+ return;
+}
+
+
+void WOKUnix_NoBuffer::Close()
+{
+
+}
--- /dev/null
+-- File: WOKUnix_OutErrOutput.cdl
+-- Created: Tue May 9 13:57:51 1995
+-- Author: Jean GAUTIER
+-- <jga@cobrax>
+---Copyright: Matra Datavision 1995
+
+
+private class OutErrOutput from WOKUnix
+inherits ProcessOutput from WOKUnix
+
+ ---Purpose:
+
+uses
+ Timeval from WOKUnix,
+ FDSet from WOKUnix,
+ FDescr from WOKUnix,
+ Buffer from WOKUnix,
+ PopenBufferMode from WOKUnix,
+ HSequenceOfHAsciiString from TColStd
+is
+ Create returns mutable OutErrOutput from WOKUnix;
+ Create(aoutfd : FDescr from WOKUnix; aerrfd : FDescr from WOKUnix; amode : PopenBufferMode from WOKUnix)
+ returns mutable OutErrOutput from WOKUnix;
+ Create(anoutput : OutErrOutput from WOKUnix; amode : PopenBufferMode from WOKUnix)
+ returns mutable OutErrOutput from WOKUnix;
+
+ Clear(me) is redefined;
+ Echo(me) returns HSequenceOfHAsciiString from TColStd is redefined;
+ Errors(me) returns HSequenceOfHAsciiString from TColStd is redefined;
+
+
+ Select(me; afdmax : out Integer from Standard; atimeout : in out Timeval from WOKUnix; aset : out FDSet from WOKUnix) is redefined;
+
+ Acquit(me; selectstatus : Integer; aset : FDSet from WOKUnix) is redefined;
+
+ Close(me:mutable) is redefined;
+
+fields
+ myout : Buffer from WOKUnix;
+ myerr : Buffer from WOKUnix;
+end OutErrOutput;
--- /dev/null
+
+#include <WOKUnix_OutErrOutput.ixx>
+#include <WOKUnix_FileBuffer.hxx>
+#include <WOKUnix_NoBuffer.hxx>
+#include <WOKUnix_CantBlockBuffer.hxx>
+
+
+//=======================================================================
+//function : WOKUnix_OutErrOutput
+//purpose :
+//=======================================================================
+WOKUnix_OutErrOutput::WOKUnix_OutErrOutput()
+{
+}
+
+
+//=======================================================================
+//function : WOKUnix_OutErrOutput
+//purpose :
+//=======================================================================
+WOKUnix_OutErrOutput::WOKUnix_OutErrOutput(const WOKUnix_FDescr& aoutfd,
+ const WOKUnix_FDescr& aerrfd,
+ const WOKUnix_PopenBufferMode amode)
+{
+ switch(amode)
+ {
+ case WOKUnix_POPEN_BUFFERED:
+ myout = new WOKUnix_FileBuffer(aoutfd, WOKUnix_STDOUT);
+ myerr = new WOKUnix_FileBuffer(aerrfd, WOKUnix_STDERR);
+ break;
+ case WOKUnix_POPEN_IMMEDIATE:
+ myout = new WOKUnix_NoBuffer(aoutfd, WOKUnix_STDOUT);
+ myerr = new WOKUnix_NoBuffer(aerrfd, WOKUnix_STDERR);
+ break;
+ case WOKUnix_POPEN_ECHOIFBLOCKED:
+ myout = new WOKUnix_CantBlockBuffer(aoutfd, WOKUnix_STDOUT);
+ myerr = new WOKUnix_CantBlockBuffer(aerrfd, WOKUnix_STDERR);
+ break;
+ }
+}
+
+//=======================================================================
+//function : WOKUnix_OutErrOutput
+//purpose :
+//=======================================================================
+WOKUnix_OutErrOutput::WOKUnix_OutErrOutput(const Handle(WOKUnix_OutErrOutput)& anoutput,
+ const WOKUnix_PopenBufferMode amode)
+{
+}
+
+//=======================================================================
+//function : Echo
+//purpose :
+//=======================================================================
+Handle(TColStd_HSequenceOfHAsciiString) WOKUnix_OutErrOutput::Echo() const
+{
+ Handle(TColStd_HSequenceOfHAsciiString) aseq = myout->Echo();
+ aseq->Append(myerr->Echo());
+ return aseq;
+}
+
+//=======================================================================
+//function : Clear
+//purpose :
+//=======================================================================
+void WOKUnix_OutErrOutput::Clear() const
+{
+ myout->Clear();
+ myerr->Clear();
+}
+
+//=======================================================================
+//function : Errors
+//purpose :
+//=======================================================================
+Handle(TColStd_HSequenceOfHAsciiString) WOKUnix_OutErrOutput::Errors() const
+{
+ Handle(TColStd_HSequenceOfHAsciiString) aseq = myout->Errors();
+ aseq->Append(myerr->Errors());
+ return aseq;
+}
+
+//=======================================================================
+//function : Select
+//purpose :
+//=======================================================================
+void WOKUnix_OutErrOutput::Select(Standard_Integer& afdmax, WOKUnix_Timeval& atimeout, WOKUnix_FDSet& aset) const
+{
+ myout->Select(afdmax, atimeout, aset);
+ myerr->Select(afdmax, atimeout, aset);
+}
+
+//=======================================================================
+//function : Acquit
+//purpose :
+//=======================================================================
+void WOKUnix_OutErrOutput::Acquit(const Standard_Integer aselectstatus, const WOKUnix_FDSet& aset) const
+{
+ myout->Acquit(aselectstatus, aset);
+ myerr->Acquit(aselectstatus, aset);
+}
+
+//=======================================================================
+//function : Close
+//purpose :
+//=======================================================================
+void WOKUnix_OutErrOutput::Close()
+{
+ myout->Close();
+ myerr->Close();
+}
+
--- /dev/null
+-- File: WOKUnix_Path.cdl
+-- Created: Mon May 29 15:09:14 1995
+-- Author: Jean GAUTIER
+-- <jga@cobrax>
+---Copyright: Matra Datavision 1995
+
+class Path from WOKUnix
+
+ ---Purpose: Supplee aux insuffisances de OSD_File
+
+inherits TShared from MMgt
+uses
+ HAsciiString from TCollection,
+ FDescr from WOKUnix,
+ TimeStat from WOKUnix,
+ StatBuf from WOKUnix,
+ Extension from WOKUnix
+
+is
+
+ Create returns mutable Path from WOKUnix;
+ ---Purpose: Instantiates Path from WOKUnix
+
+ Create(apath : CString from Standard)
+ returns mutable Path from WOKUnix;
+
+ Create(apath : HAsciiString from TCollection)
+ ---Purpose: Instantiates Path from WOKUnix using an asciistring
+ returns mutable Path from WOKUnix;
+
+ Create(adir,aname : HAsciiString from TCollection)
+ ---Purpose: Instantiates Path from WOKUnix using an directory and
+ -- a name
+ returns mutable Path from WOKUnix;
+
+ Create(adir,aname : CString from Standard)
+ ---Purpose: Instantiates Path from WOKUnix using an directory and
+ -- a name
+ returns mutable Path from WOKUnix;
+
+ CheckStats(me:mutable)
+ ---C++: inline
+ returns Boolean from Standard;
+
+ GetStats(me:mutable)
+ returns Boolean from Standard;
+
+ Name(me)
+ ---C++: return const &
+ ---C++: inline
+ ---Purpose: returns PathName
+ returns HAsciiString from TCollection;
+
+ SetName(me:mutable; apath : HAsciiString from TCollection);
+ ---Purpose: sets path
+
+ BuildFDescr(me)
+ ---Purpose: Builds a WOKUnix_FDescr to manipulate Path
+ returns FDescr from WOKUnix;
+
+ Exists(me) returns Boolean;
+ ---Purpose: Tests existency of path on disk
+
+ CreateDirectory(me:mutable; CreateParents : Boolean from Standard = Standard_False)
+ ---Purpose: Creates path as a directory
+ returns Boolean;
+
+ CreateFile(me:mutable; CreateParents : Boolean from Standard = Standard_False)
+ ---Purpose: Creates path as a file on disk
+ returns Boolean;
+
+ IsSymLink(me:mutable)
+ returns Boolean from Standard;
+
+ IsFile(me:mutable)
+ returns Boolean from Standard;
+
+ IsDirectory(me:mutable)
+ returns Boolean from Standard;
+
+ CreateSymLinkTo(me:mutable; apath : Path from WOKUnix)
+ returns Boolean from Standard;
+
+ RemoveDirectory(me:mutable; RemoveChilds : Boolean from Standard = Standard_False)
+ returns Boolean from Standard;
+
+ RemoveFile(me:mutable)
+ returns Boolean from Standard;
+
+ MoveTo(me:mutable; adestpath : Path from WOKUnix)
+ ---Purpose: Renames file to destpath Failes if mypath and dest
+ -- path are not on the same file system
+ -- mypath is changed to which of adestpath
+ returns Boolean from Standard;
+
+ ReducedPath(me)
+ ---Purpose: reduces Path as much as possible (reads links)
+ returns Path from WOKUnix;
+
+ IsSamePath(me; another : Path from WOKUnix)
+ ---Purpose: Tests is me corresponds to the same
+ -- file as <another> (reads links)
+ returns Boolean from Standard;
+
+ IsSameFile(me; another : Path from WOKUnix)
+ ---Purpose: Teste si deux fichiers ont le meme
+ -- contenu (typiquement utilise a l'extraction)
+ returns Boolean from Standard;
+
+ MDate(me:mutable)
+ ---C++: inline
+ ---Purpose: returns known date of path
+ returns TimeStat from WOKUnix;
+
+ ResetMDate(me:mutable);
+ ---C++: inline
+
+ IsOlder(me:mutable; another : Path from WOKUnix)
+ returns Boolean from Standard;
+ IsNewer(me:mutable; another : Path from WOKUnix)
+ returns Boolean from Standard;
+
+ IsWriteAble(me)
+ returns Boolean from Standard;
+
+ Extension(me)
+ ---Purpose: extracts Extension of file
+ returns Extension from WOKUnix;
+
+ ExtensionName(me)
+ ---Purpose: extracts Extension of file
+ returns HAsciiString from TCollection;
+
+ BaseName(me)
+ ---Purpose: returns the basename of File
+ returns HAsciiString from TCollection;
+
+ DirName(me)
+ ---Purpose: returns the dirname of file
+ returns HAsciiString from TCollection;
+
+ FileName(me)
+ ---Purpose: returns the filename (<BaseName>.<Extension>) of path
+ returns HAsciiString from TCollection;
+
+fields
+ mypath : HAsciiString from TCollection;
+ myacces : Boolean from Standard;
+ mystats : StatBuf from WOKUnix;
+end;
+
+
--- /dev/null
+// File: WOKUnix_Path.cxx
+// Created: Tue May 30 09:17:00 1995
+// Author: Jean GAUTIER
+// <jga@cobrax>
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#ifndef PATH_MAX
+#define PATH_MAX 1024
+#endif
+
+#include <WOKUnix_Path.ixx>
+
+#include <WOKTools_Messages.hxx>
+
+#include <TCollection_AsciiString.hxx>
+
+#include <WOKUnix.hxx>
+
+#include <WOKUnix_PathIterator.hxx>
+
+//=======================================================================
+//function : WOKUnix_Path
+//purpose : Empty Contructor
+//=======================================================================
+WOKUnix_Path::WOKUnix_Path()
+{
+ mystats.st_mtime = -1;
+ myacces = Standard_False;
+}
+
+//=======================================================================
+//function : WOKUnix_Path
+//purpose : Instantiates using a TCollection_AsciiString
+//=======================================================================
+WOKUnix_Path::WOKUnix_Path(const Standard_CString apath)
+{
+ mypath = new TCollection_HAsciiString(apath);
+ mystats.st_mtime = -1;
+ myacces = Standard_False;
+}
+
+//=======================================================================
+//function : WOKUnix_Path
+//purpose : Instantiates using a TCollection_AsciiString
+//=======================================================================
+WOKUnix_Path::WOKUnix_Path(const Handle(TCollection_HAsciiString)& apath)
+{
+ mypath = apath;
+ mystats.st_mtime = -1;
+ myacces = Standard_False;
+}
+
+//=======================================================================
+//function : WOKUnix_Path
+//purpose : Instantiates using a TCollection_AsciiString
+//=======================================================================
+WOKUnix_Path::WOKUnix_Path(const Handle(TCollection_HAsciiString)& adir, const Handle(TCollection_HAsciiString)& aname)
+{
+ Handle(TCollection_HAsciiString) astr = new TCollection_HAsciiString;
+
+ astr->AssignCat(adir);
+ astr->AssignCat("/");
+ astr->AssignCat(aname);
+ mypath = astr;
+ mystats.st_mtime = -1;
+ myacces = Standard_False;
+}
+
+//=======================================================================
+//function : WOKUnix_Path
+//purpose : Instantiates using a TCollection_AsciiString
+//=======================================================================
+WOKUnix_Path::WOKUnix_Path(const Standard_CString adir, const Standard_CString aname)
+{
+ Handle(TCollection_HAsciiString) astr = new TCollection_HAsciiString;
+
+ astr->AssignCat(adir);
+ astr->AssignCat("/");
+ astr->AssignCat(aname);
+ mypath = astr;
+ mystats.st_mtime = -1;
+ myacces = Standard_False;
+}
+
+//=======================================================================
+//function : SetName
+//purpose : set path
+//=======================================================================
+void WOKUnix_Path::SetName(const Handle(TCollection_HAsciiString)& apath)
+{
+ mypath = apath;
+}
+
+//=======================================================================
+//function : BuildFDescr
+//purpose : build WOKUnix_FDescr
+//=======================================================================
+WOKUnix_FDescr WOKUnix_Path::BuildFDescr() const
+{
+ WOKUnix_FDescr afd;
+ OSD_Path apath(mypath->String());
+
+
+ afd.SetPath(apath);
+
+ return afd;
+}
+
+//=======================================================================
+//function : Exists
+//purpose : Test existency of path on FS
+//=======================================================================
+Standard_Boolean WOKUnix_Path::Exists() const
+{
+ if(mypath.IsNull())
+ {
+ return Standard_False;
+ }
+ if(myacces) return Standard_True;
+
+ if(access(mypath->ToCString(), F_OK)) {return Standard_False;}
+
+ return Standard_True;
+}
+
+//=======================================================================
+//function : CreateDirectory
+//purpose : Creates path as a directory
+//=======================================================================
+Standard_Boolean WOKUnix_Path::CreateDirectory(const Standard_Boolean CreateParents)
+{
+ TCollection_AsciiString afullname;
+
+ if(Exists())
+ {
+ // l'inode existe deja
+ if(!IsDirectory())
+ {
+ ErrorMsg << "WOKUnix_Path::CreateDirectory"
+ << mypath << " exists and is not a directory" << endm;
+ return Standard_False;
+ }
+ return Standard_True;
+ }
+
+ Handle(WOKUnix_Path) parent = new WOKUnix_Path(DirName());
+
+ if(parent->Exists())
+ {
+ if(!parent->IsDirectory())
+ {
+ ErrorMsg << "WOKUnix_Path::CreateDirectory"
+ << "Parent Directory " << parent->Name() << " exists and is not a directory" << endm;
+ return Standard_False;
+ }
+
+ if(mkdir(mypath->ToCString(), 0777))
+ {
+ ErrorMsg << "WOKUnix_Path::CreateDirectory"
+ << WOKUnix::LastSystemMessage() << endm;
+ ErrorMsg << "WOKUnix_Path::CreateDirectory"
+ << "Could not create directory : " << mypath << endm;
+ return Standard_False;
+ }
+ return Standard_True;
+ }
+
+ if(CreateParents == Standard_False)
+ {
+ ErrorMsg << "WOKUnix_Path::CreateDirectory"
+ << "Parent Directory " << parent->Name() << " does not exist" << endm;
+ return Standard_False;
+ }
+
+ // j'ai le droit de creer les parents
+ // ADN - attention, creation de path sur un disque invisible (bouclage !)
+ if (!strcmp(parent->Name()->ToCString(),Name()->ToCString())) {
+ return Standard_False;
+ }
+
+ if (parent->CreateDirectory(Standard_True)) {
+ return CreateDirectory(Standard_False);
+ }
+ return Standard_False;
+}
+
+//=======================================================================
+//function : CreateFile
+//purpose : Creates path as a file
+//=======================================================================
+Standard_Boolean WOKUnix_Path::CreateFile(const Standard_Boolean CreateParents)
+{
+ TCollection_AsciiString afullname;
+ Handle(WOKUnix_Path) parent = new WOKUnix_Path;
+
+ if(Exists())
+ {
+ // l'inode existe deja
+ if(!IsFile())
+ {
+ ErrorMsg << "WOKUnix_Path::CreateFile"
+ << mypath << " exists and is not a file" << endm;
+ return Standard_False;
+ }
+ else return Standard_True;
+ }
+
+ //if(apath.IsValid(mypath->ToCString()) == Standard_False)
+ // {
+ // ErrorMsg << "WOKUnix_Path::CreateFile"
+ // << mypath << " is invalid" << endm;
+ // return Standard_False;
+ // }
+
+ parent->SetName(DirName());
+
+ if(parent->Exists())
+ {
+ if(!parent->IsDirectory())
+ {
+ ErrorMsg << "WOKUnix_Path::CreateFile"
+ << "Parent Directory " << parent->Name() << " exists and is not a directory" << endm;
+ return Standard_False;
+ }
+
+ Standard_Integer fd;
+
+ if((fd=creat(mypath->ToCString(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)) < 0)
+ {
+ ErrorMsg << "WOKUnix_Path::CreateFile" << WOKUnix::LastSystemMessage() << endm;
+ ErrorMsg << "WOKUnix_Path::CreateFile" << "Could not create " << mypath << endm;
+ return Standard_False;
+ }
+ close(fd);
+ return Standard_True;
+ }
+ else if(CreateParents == Standard_False)
+ {
+ ErrorMsg << "WOKUnix_Path::CreateFile"
+ << "Parent Directory "
+ << parent->Name()
+ << " does not exist" << endm;
+ return Standard_False;
+ }
+ if (parent->CreateDirectory(Standard_True)) {
+ return CreateFile(Standard_False);
+ }
+ return Standard_False;
+}
+
+//=======================================================================
+//function : IsSymLink
+//purpose :
+//=======================================================================
+Standard_Boolean WOKUnix_Path::IsSymLink()
+{
+ if(mypath.IsNull()) return Standard_False;
+ if(!CheckStats()) return Standard_False;
+
+ struct stat statbuf;
+ if(lstat(mypath->ToCString(), &statbuf))
+ {
+ return Standard_False;
+ }
+ return S_ISLNK(statbuf.st_mode);
+}
+
+//=======================================================================
+//function : IsFile
+//purpose :
+//=======================================================================
+Standard_Boolean WOKUnix_Path::IsFile()
+{
+ if(mypath.IsNull()) return Standard_False;
+ if(!CheckStats()) return Standard_False;
+ return S_ISREG(mystats.st_mode);
+}
+
+//=======================================================================
+//function : IsDirectory
+//purpose :
+//=======================================================================
+Standard_Boolean WOKUnix_Path::IsDirectory()
+{
+ if(mypath.IsNull()) return Standard_False;
+ if(!CheckStats()) return Standard_False;
+
+ return S_ISDIR(mystats.st_mode);
+}
+
+//=======================================================================
+//function : CreateSymLinkTo
+//purpose :
+//=======================================================================
+Standard_Boolean WOKUnix_Path::CreateSymLinkTo(const Handle(WOKUnix_Path)& apath)
+{
+ if(apath.IsNull() || Name().IsNull())
+ {
+ ErrorMsg << "WOKUnix_Path::CreateSymLinkTo"
+ << "Unable to create symlink : Invalid arguments" << endm;
+ return Standard_False;
+ }
+
+ if(symlink(apath->Name()->ToCString(), Name()->ToCString()))
+ {
+ ErrorMsg << "WOKUnix_Path::CreateSymLinkTo"
+ << WOKUnix::LastSystemMessage() << endm;
+ ErrorMsg << "WOKUnix_Path::CreateSymLinkTo"
+ << "Unable to create " << Name() << " -> " << apath->Name() << endm;
+ return Standard_False;
+ }
+ return Standard_True;
+}
+
+//=======================================================================
+//function : RemoveDirectory
+//purpose :
+//=======================================================================
+Standard_Boolean WOKUnix_Path::RemoveDirectory(const Standard_Boolean RemoveChilds)
+{
+ if(Name().IsNull())
+ {
+ ErrorMsg << "WOKUnix_Path::RemoveDirectory"
+ << "Invalid null name" << endm;
+ return Standard_False;
+ }
+
+ if(!RemoveChilds)
+ {
+ if(rmdir(Name()->ToCString()) != 0)
+ {
+ ErrorMsg << "WOKUnix_Path::RemoveDirectory"
+ << WOKUnix::LastSystemMessage() << endm;
+ ErrorMsg << "WOKUnix_Path::RemoveDirectory"
+ << "Could not remove : " << Name() << endm;
+ return Standard_False;
+ }
+ }
+ else
+ {
+ // WOKUtils_PathIterator ....
+ }
+ return Standard_True;
+}
+
+//=======================================================================
+//function : RemoveFile
+//purpose :
+//=======================================================================
+Standard_Boolean WOKUnix_Path::RemoveFile()
+{
+ if(Name().IsNull())
+ {
+ ErrorMsg << "WOKUnix_Path::RemoveFile"
+ << "Invalid null name" << endm;
+ return Standard_False;
+ }
+ if(unlink(Name()->ToCString()))
+ {
+ ErrorMsg << "WOKUnix_Path::RemoveFile"
+ << WOKUnix::LastSystemMessage() << endm;
+ ErrorMsg << "WOKUnix_Path::RemoveFile"
+ << "Failed to Remove : " << Name() << endm;
+ return Standard_False;
+ }
+ return Standard_True;
+}
+
+//=======================================================================
+//function : MoveTo
+//purpose :
+//=======================================================================
+Standard_Boolean WOKUnix_Path::MoveTo(const Handle(WOKUnix_Path)& adestpath)
+{
+ if(rename(mypath->ToCString(), adestpath->Name()->ToCString()))
+ {
+ ErrorMsg << "WOKUnix_Path::MoveTo"
+ << WOKUnix::LastSystemMessage() << endm;
+ ErrorMsg << "WOKUnix_Path::MoveTo"
+ << "Failed to Move " << mypath->ToCString() << " to " << adestpath->Name()->ToCString()<< endm;
+ return Standard_False;
+ }
+ else
+ {
+ mypath = adestpath->Name();
+ return Standard_True;
+ }
+}
+
+//=======================================================================
+//function : ReducedPath
+//purpose :
+//=======================================================================
+Handle(WOKUnix_Path) WOKUnix_Path::ReducedPath() const
+{
+ Handle(WOKUnix_Path) areduced;
+ Handle(TCollection_HAsciiString) astr;
+
+ if(Exists())
+ {
+#if !defined(DECOSF1) && !defined(HPUX)
+
+ char abuffer[PATH_MAX];
+
+ *abuffer = '\0';
+
+ if(realpath(mypath->ToCString(), abuffer) == NULL)
+ {
+ ErrorMsg << "WOKUnix_Path::ReducedPath" << WOKUnix::LastSystemMessage() << endm;
+ return this;
+ }
+
+ astr = new TCollection_HAsciiString(abuffer);
+
+ areduced = new WOKUnix_Path(astr);
+ return areduced;
+#else
+
+ astr = new TCollection_HAsciiString(mypath);
+ areduced = new WOKUnix_Path(astr);
+
+ return areduced;
+
+#endif
+
+ }
+ else
+ {
+ astr = new TCollection_HAsciiString(Name());
+ areduced = new WOKUnix_Path(Name());
+ return areduced;
+ }
+}
+
+//=======================================================================
+//function : IsSamePath
+//purpose :
+//=======================================================================
+Standard_Boolean WOKUnix_Path::IsSamePath(const Handle(WOKUnix_Path)& another) const
+{
+ Handle(WOKUnix_Path) mereduced = ReducedPath();
+ Handle(WOKUnix_Path) otherreduced = another->ReducedPath();
+
+ if(mereduced->Name()->IsSameString(otherreduced->Name())) return Standard_True;
+ return Standard_False;
+}
+
+//=======================================================================
+//function : IsSameFile
+//purpose :
+//=======================================================================
+Standard_Boolean WOKUnix_Path::IsSameFile(const Handle(WOKUnix_Path)& another) const
+{
+ int fd1, fd2;
+ long lg1, lg2;
+ long nb;
+ static char buf1[4096], buf2[4096];
+ struct stat buf_stat;
+
+ if((fd1 = open(Name()->ToCString(), O_RDONLY, 0)) < 0)
+ {
+ ErrorMsg << "WOKUnix_Path::IsSameFile" << WOKUnix::LastSystemMessage() << endm;
+ ErrorMsg << "WOKUnix_Path::IsSameFile" << "Can't open " << Name() << endm;
+ return Standard_False;
+ }
+ if((fd2 = open(another->Name()->ToCString(), O_RDONLY, 0)) < 0)
+ {
+ ErrorMsg << "WOKUnix_Path::IsSameFile" << WOKUnix::LastSystemMessage() << endm;
+ ErrorMsg << "WOKUnix_Path::IsSameFile" << "Can't open " << another->Name() << endm;
+ return Standard_False;
+ }
+
+ /* longueurs differentes ? */
+ if(fstat(fd1, &buf_stat)) {close(fd1); close(fd2); return Standard_False;}
+ lg1 = buf_stat.st_size;
+ if(fstat(fd2, &buf_stat)) {close(fd1); close(fd2); return Standard_False;}
+ lg2 = buf_stat.st_size;
+ if(lg1 != lg2) {close(fd1); close(fd2); return Standard_False;}
+
+ while(lg1 > 0)
+ {
+ if (lg1 > 4096)
+ {nb = 4096; lg1 -= 4096;}
+ else
+ {nb = lg1; lg1 = -1;}
+ if((read(fd1, buf1, nb)) < 0) {close(fd1); close(fd2); return Standard_False;}
+ if((read(fd2, buf2, nb)) < 0) {close(fd1); close(fd2); return Standard_False;}
+ /* fichiers differents */
+ if(memcmp(buf1, buf2, nb)) {close(fd1); close(fd2); return Standard_False;}
+ }
+
+ /* fichiers identiques */
+ close(fd1);
+ close(fd2);
+ return Standard_True;
+}
+
+//=======================================================================
+//function : GetStats
+//purpose : Obtain file stats
+//=======================================================================
+Standard_Boolean WOKUnix_Path::GetStats()
+{
+ if(mystats.st_mtime != -1) return Standard_True;
+
+ if(!Exists()) return Standard_False;
+ else if(stat(mypath->ToCString(), &mystats))
+ {
+ ErrorMsg << "WOKUnix_Path::GetStats"
+ << WOKUnix::LastSystemMessage() << endm;
+ return Standard_False;
+ }
+ else return Standard_True;
+}
+
+//=======================================================================
+//function : IsOlder
+//purpose :
+//=======================================================================
+Standard_Boolean WOKUnix_Path::IsOlder(const Handle(WOKUnix_Path)& another)
+{
+ if(MDate() < another->MDate()) return Standard_True;
+ return Standard_False;
+}
+
+
+//=======================================================================
+//function : IsNewer
+//purpose :
+//=======================================================================
+Standard_Boolean WOKUnix_Path::IsNewer(const Handle(WOKUnix_Path)& another)
+{
+ if(MDate() > another->MDate()) return Standard_True;
+ return Standard_False;
+}
+
+//=======================================================================
+//function : IsWriteAble
+//purpose :
+//=======================================================================
+Standard_Boolean WOKUnix_Path::IsWriteAble() const
+{
+
+ if(mypath.IsNull())
+ {
+ return Standard_False;
+ }
+
+ if(access(mypath->ToCString(), R_OK | W_OK ))
+ {
+ return Standard_False;
+ }
+
+ return Standard_True;
+}
+
+//=======================================================================
+//function : Extension
+//purpose :
+//=======================================================================
+WOKUnix_Extension WOKUnix_Path::Extension() const
+{
+ Standard_CString ptr = strrchr(mypath->ToCString(), '.');
+
+ if(ptr)
+ {
+ ptr++;
+
+ // Specification Files
+ if(!strcmp(ptr, "cdl")) return WOKUnix_CDLFile;
+ if(!strcmp(ptr, "odl")) return WOKUnix_ODLFile;
+ if(!strcmp(ptr, "idl")) return WOKUnix_IDLFile;
+
+ // Includes
+ if(!strcmp(ptr, "hxx")) return WOKUnix_HXXFile;
+ if(!strcmp(ptr, "ixx")) return WOKUnix_IXXFile;
+ if(!strcmp(ptr, "jxx")) return WOKUnix_JXXFile;
+ if(!strcmp(ptr, "lxx")) return WOKUnix_LXXFile;
+ if(!strcmp(ptr, "gxx")) return WOKUnix_GXXFile;
+ if(!strcmp(ptr, "h")) return WOKUnix_HFile;
+ if(!strcmp(ptr, "pxx")) return WOKUnix_PXXFile;
+ if(!strcmp(ptr, "inc")) return WOKUnix_INCFile;
+ if(!strcmp(ptr, "INC")) return WOKUnix_INCFile;
+
+ // DBMS Files
+ if(!strcmp(ptr, "ddl")) return WOKUnix_DDLFile;
+ if(!strcmp(ptr, "DB")) return WOKUnix_DBFile;
+ if(!strcmp(ptr, "FDDB")) return WOKUnix_FDDBFile;
+ if(!strcmp(ptr, "libschema")) return WOKUnix_LibSchemaFile;
+ if(!strcmp(ptr, "asdb")) return WOKUnix_AppSchemaFile;
+ if(!strcmp(ptr, "ho2")) return WOKUnix_HO2File;
+
+ // Code Generators
+ if(!strcmp(ptr, "lex")) return WOKUnix_LexFile;
+ if(!strcmp(ptr, "yacc")) return WOKUnix_YaccFile;
+ if(!strcmp(ptr, "lws")) return WOKUnix_LWSFile;
+ if(!strcmp(ptr, "psw")) return WOKUnix_PSWFile;
+
+ // Compilable
+ if(!strcmp(ptr, "cxx")) return WOKUnix_CXXFile;
+ if(!strcmp(ptr, "C")) return WOKUnix_CXXFile;
+ if(!strcmp(ptr, "c")) return WOKUnix_CFile;
+ if(!strcmp(ptr, "f")) return WOKUnix_F77File;
+
+ // Machine Files
+ if(!strcmp(ptr, "o")) return WOKUnix_ObjectFile;
+ if(!strcmp(ptr, "m")) return WOKUnix_MFile;
+ if(!strcmp(ptr, "a")) return WOKUnix_ArchiveFile;
+
+ if(!strcmp(ptr, "so")) return WOKUnix_DSOFile;
+ if(!strcmp(ptr, "sl")) return WOKUnix_DSOFile;
+
+ // WNT Externsions
+ if(!strcmp(ptr, "lib")) return WOKUnix_LIBFile;
+ if(!strcmp(ptr, "imp")) return WOKUnix_IMPFile;
+ if(!strcmp(ptr, "def")) return WOKUnix_DEFile;
+ if(!strcmp(ptr, "exp")) return WOKUnix_EXPFile;
+
+ if(!strcmp(ptr, "rc")) return WOKUnix_RCFile;
+ if(!strcmp(ptr, "res")) return WOKUnix_RESFile;
+
+ // Miscellaneous
+ if(!strcmp(ptr, "Z")) return WOKUnix_CompressedFile;
+ if(!strcmp(ptr, "gz")) return WOKUnix_CompressedFile;
+ if(!strcmp(ptr, "dat")) return WOKUnix_DATFile;
+ if(!strcmp(ptr, "ll")) return WOKUnix_LispFile;
+ if(!strcmp(ptr, "ccl")) return WOKUnix_LispFile;
+ if(!strcmp(ptr, "xwd")) return WOKUnix_IconFile;
+ if(!strcmp(ptr, "txt")) return WOKUnix_TextFile;
+ if(!strcmp(ptr, "tar")) return WOKUnix_TarFile;
+ if(!strcmp(ptr, "csh")) return WOKUnix_CSHFile;
+
+ if(!strcmp(ptr, "template")) return WOKUnix_TemplateFile;
+ return WOKUnix_UnknownFile;
+ }
+
+ return WOKUnix_NoExtFile;
+}
+
+
+//=======================================================================
+//function : ExtensionName
+//purpose :
+//=======================================================================
+Handle(TCollection_HAsciiString) WOKUnix_Path::ExtensionName() const
+{
+ Standard_Integer pos;
+ Handle(TCollection_HAsciiString) retVal = new TCollection_HAsciiString(mypath);
+
+ pos = retVal->Length();
+ while(pos != 0)
+ {
+ Standard_Character chr = retVal -> Value(pos);
+ if( chr == '.') break;
+ --pos;
+ }
+
+ if(pos)
+ retVal = retVal->SubString(pos, retVal->Length());
+ return retVal;
+}
+
+//=======================================================================
+//function : BaseName
+//purpose :
+//=======================================================================
+Handle(TCollection_HAsciiString) WOKUnix_Path::BaseName() const
+{
+ Standard_Integer pos;
+ Handle(TCollection_HAsciiString) retVal = new TCollection_HAsciiString(mypath);
+
+ pos = retVal->Length();
+
+ while(pos != 0)
+ {
+ Standard_Character chr = retVal -> Value(pos);
+
+ if( chr == '/' ) break;
+ --pos;
+ }
+
+ if(pos)
+ retVal = retVal->SubString(pos+1, retVal->Length());
+
+ pos = retVal->Length();
+ while(pos != 0)
+ {
+ Standard_Character chr = retVal -> Value(pos);
+ if( chr == '.') break;
+ --pos;
+ }
+
+ if(pos)
+ retVal = retVal->SubString(1, pos-1);
+ return retVal;
+}
+
+//=======================================================================
+//function : DirName
+//purpose :
+//=======================================================================
+Handle(TCollection_HAsciiString) WOKUnix_Path::DirName() const
+{
+
+ Standard_Integer pos, len;
+ Standard_Character chr;
+ Standard_Boolean fRetry;
+ Handle(TCollection_HAsciiString) retVal = new TCollection_HAsciiString(mypath);
+
+ fRetry = Standard_False;
+ pos = len = retVal->Length();
+
+ while(pos != 0)
+ {
+ chr = retVal -> Value(pos );
+
+ if( chr == '/' )
+ {
+ if(fRetry || pos != len) break;
+
+ retVal -> Trunc(pos - 1 );
+ fRetry = Standard_True;
+ }
+ --pos;
+ }
+
+ if(pos > 1 )
+ retVal -> Trunc(pos - 1 );
+ return retVal;
+}
+
+//=======================================================================
+//function : DirName
+//purpose :
+//=======================================================================
+Handle(TCollection_HAsciiString) WOKUnix_Path::FileName() const
+{
+ Standard_Integer pos;
+ Handle(TCollection_HAsciiString) retVal = new TCollection_HAsciiString(mypath);
+
+ pos = retVal->Length();
+
+ while(pos != 0)
+ {
+ Standard_Character chr = retVal -> Value(pos);
+
+ if( chr == '/' )
+ {
+ if(pos == retVal->Length())
+ {
+ retVal->Trunc(retVal->Length()-1);
+ }
+ else
+ break;
+ }
+ --pos;
+ }
+
+ if(pos)
+ retVal = retVal->SubString(pos+1, retVal->Length());
+ return retVal;
+}
+
--- /dev/null
+// File: WOKUnix_Path.lxx
+// Created: Thu Jul 27 19:46:43 1995
+// Author: Jean GAUTIER
+// <jga@cobrax>
+
+#include <TCollection_HAsciiString.hxx>
+
+//=======================================================================
+//Author : Jean Gautier (jga)
+//function : Name
+//purpose : returns PathName
+//=======================================================================
+const Handle(TCollection_HAsciiString)& WOKUnix_Path::Name() const
+{
+ return mypath;
+}
+
+Standard_Boolean WOKUnix_Path::CheckStats()
+{
+ if(mystats.st_mtime == -1)
+ return GetStats();
+ else return Standard_True;
+}
+
+//=======================================================================
+//Author : Jean Gautier (jga)
+//function : MDate
+//purpose : returns known date of path
+//=======================================================================
+WOKUnix_TimeStat WOKUnix_Path::MDate()
+{
+ if(mystats.st_mtime == -1)
+ GetStats();
+ return mystats.st_mtime;
+}
+
+//=======================================================================
+//Author : Jean Gautier (jga)
+//function : ResetMDate
+//purpose :
+//=======================================================================
+void WOKUnix_Path::ResetMDate()
+{
+ mystats.st_mtime = -1;
+}
--- /dev/null
+-- File: WOKUnix_PathIterator.cdl
+-- Created: Mon Aug 03 15:37:45 1998
+-- Author:
+-- <jga@GROMINEX>
+---Copyright: Matra Datavision 1998
+
+
+class PathIterator from WOKUnix
+
+
+uses
+ Boolean from Standard,
+ HAsciiString from TCollection,
+ AsciiString from TCollection,
+ StackOfDir from WOKUnix,
+ Dir from WOKUnix,
+ DirEnt from WOKUnix,
+ Path from WOKUnix
+
+is
+
+
+ Create(apath : Path from WOKUnix; recursive : Boolean from Standard = Standard_False; mask : CString from Standard = "*")
+ returns PathIterator from WOKUnix;
+
+ SkipDots(me:out) is private;
+
+ IsDots(myclass; aname : CString from Standard)
+ returns Boolean from Standard is private;
+
+ Push(me:out; apath : Path from WOKUnix; adir : Dir from WOKUnix) is private;
+ Pop(me:out) is private;
+
+ Next(me:out);
+
+
+ PathValue(me)
+ returns Path from WOKUnix;
+
+ LevelValue(me)
+ returns Integer from Standard;
+
+ NameValue(me)
+ returns HAsciiString from TCollection;
+
+ BrowsedPath(me)
+ returns Path from WOKUnix;
+
+ More(me)
+ returns Boolean from Standard;
+
+ Destroy(me:in out);
+ ---C++: alias ~
+
+fields
+
+ mymask : AsciiString from TCollection;
+ mypath : Path from WOKUnix;
+ mydata : DirEnt from WOKUnix;
+ mystack : StackOfDir from WOKUnix;
+ mymore : Boolean from Standard;
+ myrecflag : Boolean from Standard;
+
+end;
+
+
--- /dev/null
+
+
+#include <WOKUnix_PathIterator.ixx>
+
+
+#include <WOKUnix.hxx>
+#include <WOKUnix_Path.hxx>
+
+#include <WOKTools_Messages.hxx>
+
+#include <stream.h>
+
+#include <stdio.h>
+//#include <sys/types.h>
+//#include <sys/stat.h>
+#include <dirent.h>
+
+
+WOKUnix_PathIterator::WOKUnix_PathIterator(const Handle(WOKUnix_Path)& apath, const Standard_Boolean abool, const Standard_CString amask)
+: mypath(apath), myrecflag(abool), mymask(amask)
+{
+ TCollection_HAsciiString mask;
+ mask.AssignCat(apath->Name()->ToCString());
+ mask.AssignCat("/");
+ mask.AssignCat(mymask.ToCString());
+
+
+ WOKUnix_Dir adir = opendir(apath->Name()->ToCString());
+
+ if(!adir)
+ {
+ ErrorMsg << "WOKUnix_PathIterator::WOKUnix_PathIterator"
+ << WOKUnix::LastSystemMessage() << endm;
+ ErrorMsg << "WOKUnix_PathIterator::WOKUnix_PathIterator"
+ << "Could not open directory " << apath->Name() << endm;
+ mymore = Standard_False;
+ return;
+ }
+
+ mystack.Push(adir);
+ mydata = readdir(mystack.Top());
+ mymore = Standard_True;
+
+ SkipDots();
+}
+
+
+Standard_Boolean WOKUnix_PathIterator::IsDots(const Standard_CString astr)
+{
+ if(astr[0] == '.')
+ {
+ if(!astr[1])
+ return Standard_True;
+ else
+ if(astr[1] == '.' )
+ if(!astr[2])
+ return Standard_True;
+ }
+ return Standard_False;
+}
+
+void WOKUnix_PathIterator::SkipDots()
+{
+ if(!mydata) return;
+ while(IsDots((Standard_CString)mydata->d_name) && !mystack.IsEmpty())
+ {
+ mydata = readdir(mystack.Top());
+ if(!mydata)
+ {
+ if(!mystack.IsEmpty())
+ {
+ Pop();
+ if(!mymore) return;
+ }
+ else
+ {
+ mymore = Standard_False;
+ return;
+ }
+ }
+ }
+}
+
+
+void WOKUnix_PathIterator::Push(const Handle(WOKUnix_Path)& apath, const WOKUnix_Dir& data)
+{
+ if(!IsDots(mydata->d_name) && myrecflag)
+ {
+ mypath = apath;
+
+ WOKUnix_Dir nextone = opendir(mypath->Name()->ToCString());
+ mystack.Push(nextone);
+ mydata = readdir(mystack.Top());
+ SkipDots();
+
+ if(!mystack.IsEmpty())
+ {
+ if(!mystack.Top())
+ mymore = Standard_False;
+ else
+ mymore = Standard_True;
+ }
+ else
+ mymore = Standard_False;
+ }
+}
+
+void WOKUnix_PathIterator::Pop()
+{
+ if(!mystack.IsEmpty())
+ {
+ closedir(mystack.Top());
+ mystack.Pop();
+ if(!mystack.IsEmpty())
+ {
+ mydata = readdir(mystack.Top());
+ if(!mydata)
+ {
+ if(mystack.IsEmpty())
+ mymore = Standard_False;
+ else
+ Pop();
+ }
+ else
+ SkipDots();
+ mypath = new WOKUnix_Path(mypath->DirName());
+ }
+ else
+ mymore = Standard_False;
+ }
+}
+
+
+void WOKUnix_PathIterator::Next()
+{
+ Handle(WOKUnix_Path) apath = new WOKUnix_Path(mypath->Name(), new TCollection_HAsciiString(mydata->d_name));
+ if(!IsDots(mydata->d_name) && myrecflag && apath->IsDirectory())
+ Push(apath, mystack.Top());
+ else
+ {
+ mydata = readdir(mystack.Top());
+ if(!mydata)
+ {
+ if(!mystack.IsEmpty())
+ Pop();
+
+ if(mystack.IsEmpty())
+ mymore = Standard_False;
+ }
+ }
+}
+
+Handle(WOKUnix_Path) WOKUnix_PathIterator::PathValue() const
+{
+ if(mydata) return new WOKUnix_Path(mypath->Name(), new TCollection_HAsciiString(mydata->d_name));
+ return Handle(WOKUnix_Path)();
+}
+
+Handle(TCollection_HAsciiString) WOKUnix_PathIterator::NameValue() const
+{
+
+ if(mydata) return new TCollection_HAsciiString(mydata->d_name);
+ return Handle(TCollection_HAsciiString)();
+
+}
+
+Standard_Integer WOKUnix_PathIterator::LevelValue() const
+{
+ return mystack.Depth();
+}
+
+Standard_Boolean WOKUnix_PathIterator::More() const
+{
+ return mymore;
+}
+
+void WOKUnix_PathIterator::Destroy()
+{
+ while(!mystack.IsEmpty())
+ {
+ if(mystack.Top()) closedir(mystack.Top());
+ mystack.Pop();
+ }
+}
+
+
+
--- /dev/null
+-- File: WOKUnix_Process.cdl
+-- Created: Tue May 9 14:18:26 1995
+-- Author: Jean GAUTIER
+-- <jga@cobrax>
+---Copyright: Matra Datavision 1995
+
+
+private class Process from WOKUnix
+inherits TShared from MMgt
+
+
+ ---Purpose:
+
+
+uses
+ HAsciiString from TCollection,
+ ProcessOutput from WOKUnix,
+ Timeval from WOKUnix,
+ FDSet from WOKUnix,
+ ArgTable from WOKTools,
+ FDescr from WOKUnix,
+ PopenOutputMode from WOKUnix,
+ PopenBufferMode from WOKUnix
+raises
+ --ProgramError from Standard,
+ OSDError from OSD
+is
+
+ Create(argcount : Integer; cmdline: ArgTable from WOKTools;
+ anoutputmode : PopenOutputMode from WOKUnix = WOKUnix_POPEN_MIX_OUT_ERR;
+ abuffermode : PopenBufferMode from WOKUnix = WOKUnix_POPEN_BUFFERED;
+ atimeout : Integer from Standard = -1)
+ returns mutable Process;
+
+ Create(cmdline : HAsciiString from TCollection;
+ anoutputmode : PopenOutputMode from WOKUnix = WOKUnix_POPEN_MIX_OUT_ERR;
+ abuffermode : PopenBufferMode from WOKUnix = WOKUnix_POPEN_BUFFERED;
+ atimeout : Integer from Standard = -1)
+ returns mutable Process;
+
+ --Command(me) returns ProgramError from Standard;
+ SetCommand(me:mutable;argcount : Integer; cmdline: ArgTable from WOKTools);
+ --SetCommand(me : mutable; cmdline: ArgTable from WOKTools)
+ -- raises ProgramError from Standard;
+
+ Launch(me : mutable);
+ IsLaunched(me) returns Boolean;
+
+ Pid(me) returns Integer;
+
+ Output(me : mutable)
+ ---C++: return &
+ returns mutable ProcessOutput from WOKUnix
+ is protected;
+
+ Timeout(me) returns Integer from Standard;
+ SetTimeout(me : mutable;atimeout : Integer);
+
+ Select(me; afdmax : out Integer from Standard;
+ atimeout : in out Timeval from WOKUnix;
+ aset : out FDSet from WOKUnix)
+ is protected;
+
+ Acquit(me; selectstatus : Integer from Standard ; aset : FDSet from WOKUnix)
+ is protected;
+
+ SelectAndAcquit(me) is protected;
+
+ Send(me : mutable; astring : HAsciiString from TCollection)
+ raises OSDError from OSD is virtual;
+
+ Kill(me:mutable);
+ Destroy(me:mutable);
+ ---C++: alias ~
+
+
+
+fields
+ myargv : ArgTable from WOKTools;
+ mymode : PopenOutputMode from WOKUnix;
+ mybuffermode : PopenBufferMode from WOKUnix;
+ myinput : FDescr from WOKUnix;
+ myoutput : ProcessOutput from WOKUnix;
+ mylaunched : Boolean from Standard;
+ mytimeout : Integer from Standard;
+ mychildpid : Integer from Standard;
+end Process;
+
+
--- /dev/null
+
+#ifdef IRIX
+#include <unistd.h>
+#include <sys/types.h>
+#include <bstring.h>
+#include <sys/time.h>
+#endif
+
+#ifdef HPUX
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#endif
+
+#include <unistd.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <errno.h>
+
+#include <Standard_ProgramError.hxx>
+
+#include <WOKUnix_Process.ixx>
+#include <WOKUnix_OutErrOutput.hxx>
+#include <WOKUnix_MixedOutput.hxx>
+#include <WOKUnix_Signal.hxx>
+#include <WOKUnix_FDescr.hxx>
+#include <WOKUnix_ProcessManager.hxx>
+#include <WOKTools_Messages.hxx>
+#include <WOKTools_ArgTable.hxx>
+
+
+//=======================================================================
+//function : WOKUnix_Process
+//purpose : constructs a process
+//=======================================================================
+ WOKUnix_Process::WOKUnix_Process(const Standard_Integer argcount,
+ const WOKTools_ArgTable& cmdline,
+ const WOKUnix_PopenOutputMode anoutputmode,
+ const WOKUnix_PopenBufferMode abuffermode,
+ const Standard_Integer atimeout)
+{
+ Standard_Integer i = 0;
+
+ myargv = new char * [argcount];
+
+ while(i < argcount)
+ {
+ myargv[i] =cmdline [i];
+ i++;
+ }
+
+ mymode = anoutputmode;
+ mybuffermode = abuffermode;
+ mylaunched = Standard_False;
+ mytimeout = atimeout;
+
+ WOKUnix_ProcessManager::AddProcess(this);
+}
+
+//=======================================================================
+//function : SetCommand
+//purpose :
+//=======================================================================
+void WOKUnix_Process::SetCommand(const Standard_Integer argcount,
+ const WOKTools_ArgTable& cmdline)
+{
+ Standard_Integer i = 0;
+
+ myargv = new char * [argcount];
+
+ while(i < argcount)
+ {
+ if(cmdline [i])
+ myargv[i] = strdup(cmdline [i]);
+ else
+ myargv[i] = NULL;
+ i++;
+ }
+}
+
+//=======================================================================
+//function : SetTimeout
+//purpose :
+//=======================================================================
+void WOKUnix_Process::SetTimeout(const Standard_Integer atimeout)
+{
+ mytimeout = atimeout;
+}
+
+//=======================================================================
+//function : Launch
+//purpose : launches subprocess (uses fork+exec)
+//=======================================================================
+void WOKUnix_Process::Launch()
+{
+ if (mylaunched) return;
+ else
+ {
+ WOKUnix_FDescr Pin; WOKUnix_FDescr Sin;
+ WOKUnix_FDescr Pout; WOKUnix_FDescr Sout;
+ WOKUnix_FDescr Perr; WOKUnix_FDescr Serr;
+
+ /* ouverture des pipes */
+ WOKUnix_FDescr::Pipe(Pin, Sin);
+ WOKUnix_FDescr::Pipe(Sout, Pout);
+
+ switch(mymode)
+ {
+ case WOKUnix_POPEN_MIX_OUT_ERR:
+ break;
+ case WOKUnix_POPEN_OUT_ERR:
+ WOKUnix_FDescr::Pipe(Serr, Perr);
+ break;
+ default:
+ Standard_ProgramError::Raise("WOKUnix_Process::Launch : Unknown mode");
+ }
+
+ WOKUnix_FDescr Stdin(0); WOKUnix_FDescr Stdout(1); WOKUnix_FDescr Stderr(2);
+
+ /* on cree le processus fils */
+ mychildpid = fork();
+
+ if(mychildpid < 0)
+ {
+ Standard_ProgramError::Raise("WOKUnix_Process::Launch : Could not fork");
+ }
+
+ switch(mychildpid)
+ {
+ case 0:
+ /* dans le fils */
+ /* fermeture des pipes inutiles */
+ /* redirection de stdin, stdout, stderr */
+
+ /* redirection stdin */
+ Stdin.Close();Sin.Dup(); Stdin = WOKUnix_FDescr(0); Sin.Close(); Pin.Close();
+ Stdin.SetUnBuffered();
+ /* redirection stdout */
+ Stdout.Close();Sout.Dup();Stdout = WOKUnix_FDescr(1); Sout.Close(); Pout.Close();
+ Stdout.SetUnBuffered();
+ switch(mymode)
+ {
+ case WOKUnix_POPEN_MIX_OUT_ERR:
+ /* redirection stderr */
+ Stderr.Close(); Stdout.Dup();
+ break;
+ case WOKUnix_POPEN_OUT_ERR:
+ /* redirection stderr */
+ Stderr.Close(); Sout.Dup(); Stdout = WOKUnix_FDescr(2);Sout.Close();Pout.Close();
+ Stderr.SetUnBuffered();
+ break;
+ }
+
+ /* exec de la commande */
+ if(execvp(myargv[0], (char **) myargv))
+ {
+ perror("execvp");
+ exit(1);
+ }
+ break;
+ default:
+ /* dans le pere */
+
+ /* fermeture des pipes inutiles */
+ /* ouverture des fstream su le processus fils */
+ Sin.Close();
+ Pin.SetUnBuffered();
+ Pin.SetNonBlock();
+ myinput=Pin;
+
+ Sout.Close(); Pout.SetUnBuffered();
+ switch(mymode)
+ {
+ case WOKUnix_POPEN_MIX_OUT_ERR:
+ myoutput = new WOKUnix_MixedOutput(Pout, mybuffermode);
+ break;
+ case WOKUnix_POPEN_OUT_ERR:
+ Serr.Close(); Perr.SetUnBuffered();
+ myoutput = new WOKUnix_OutErrOutput(Pout, Perr, mybuffermode);
+ break;
+ }
+ break;
+ }
+
+ WOK_TRACE {
+ VerboseMsg("WOK_PROCESS") << "WOKUnix_Process::Launch" << "Process " << mychildpid << " launched" << endm;
+ }
+
+ mylaunched = Standard_True;
+ return;
+ }
+}
+
+//=======================================================================
+//function : IsLaunched
+//purpose :
+//=======================================================================
+Standard_Boolean WOKUnix_Process::IsLaunched() const
+{
+ return mylaunched;
+}
+
+//=======================================================================
+//function : Pid
+//purpose :
+//=======================================================================
+Standard_Integer WOKUnix_Process::Pid() const
+{
+ return mychildpid;
+}
+
+//=======================================================================
+//function : Output
+//purpose :
+//=======================================================================
+Handle(WOKUnix_ProcessOutput)& WOKUnix_Process::Output()
+{
+ return myoutput;
+}
+
+//=======================================================================
+//function : Timeout
+//purpose :
+//=======================================================================
+Standard_Integer WOKUnix_Process::Timeout() const
+{
+ return mytimeout;
+}
+
+
+//=======================================================================
+//function : Select
+//purpose : select() on the output of subprocess
+//=======================================================================
+void WOKUnix_Process::Select(Standard_Integer& afdmax, WOKUnix_Timeval& atimeout, WOKUnix_FDSet& aset) const
+{
+ myoutput->Select(afdmax, atimeout, aset);
+}
+
+//=======================================================================
+//function : Acquit
+//purpose : select() acquitment
+//=======================================================================
+void WOKUnix_Process::Acquit(const Standard_Integer selectstatus, const WOKUnix_FDSet& aset) const
+{
+ myoutput->Acquit(selectstatus, aset);
+}
+
+//=======================================================================
+//function : SelectAndAcquit
+//purpose : selects and acquit
+//=======================================================================
+void WOKUnix_Process::SelectAndAcquit() const
+{
+ WOKUnix_FDSet readfds;
+ WOKUnix_Timeval s_timeout;
+ Standard_Integer selectstatus;
+ Standard_Integer fdmax = 0;
+
+
+ FD_ZERO(&readfds);
+
+ s_timeout.tv_sec = mytimeout;
+
+ myoutput->Select(fdmax, s_timeout, readfds);
+
+ if((selectstatus=select(fdmax, (WOKUnix_FDSet_CAST)&readfds, NULL, NULL , &s_timeout)) < 0)
+ {
+ perror("select");
+ return ;
+ }
+ myoutput->Acquit(selectstatus, readfds);
+ return ;
+}
+
+//=======================================================================
+//function : Send
+//purpose :
+//=======================================================================
+void WOKUnix_Process::Send(const Handle(TCollection_HAsciiString)& astring)
+{
+ Standard_Integer nbwritten, nbwrite;
+ Standard_CString ptr = astring->ToCString();
+
+ WOK_TRACE {
+ VerboseMsg("WOK_PROCESS") << "WOKUnix_Process::Send"
+ << "Writing : " << astring->ToCString() << "to file id : " << myinput.FileNo() << endm;
+ }
+
+ if(!IsLaunched())
+ {
+ ErrorMsg << "WOKUnix_Process::Send" << "Trying to perform send to dead or unlaunched process" << endm;
+ Standard_ProgramError::Raise("WOKUnix_Process::Send");
+ }
+
+ nbwritten=0;
+
+ while(nbwritten!=astring->Length())
+ {
+ while((nbwrite = write(myinput.FileNo(), ptr, astring->Length()-nbwritten)) == -1)
+ {
+ // write failed ... is
+ if(errno == EAGAIN)
+ {
+ // le write aurait ete bloquant : Acquit
+ // if(Select(shell, NULL)) return 1;
+ // il faut laisser le temps au temps
+
+ WOK_TRACE {
+ VerboseMsg("WOK_PROCESS") << "WOKUnix_Process::Send"
+ << "Write failed : Acquit output" << endm;
+ }
+
+ SelectAndAcquit();
+ sleep(1);
+ }
+ else
+ {
+ // write failed
+ perror("shell input:");
+ OSD_OSDError::Raise("Process::Send : Write to process failed\n");
+ }
+ }
+ ptr += nbwrite;
+ nbwritten += nbwrite;
+ }
+ return;
+}
+
+//=======================================================================
+//function : Kill
+//purpose :
+//=======================================================================
+void WOKUnix_Process::Kill()
+{
+ if(mylaunched == Standard_True)
+ {
+ kill(mychildpid, SIGTERM);
+
+ if(myinput.FileNo() >= 0) myinput.Close();
+ myoutput->Close();
+
+ mylaunched = Standard_False;
+ }
+}
+
+//=======================================================================
+//function : Destroy
+//purpose :
+//=======================================================================
+void WOKUnix_Process::Destroy()
+{
+ Kill();
+ delete myargv;
+}
--- /dev/null
+-- File: WOKUnix_ProcessManager.cdl
+-- Created: Tue Jun 6 14:02:25 1995
+-- Author: Jean GAUTIER
+-- <jga@cobrax>
+---Copyright: Matra Datavision 1995
+
+class ProcessManager from WOKUnix
+uses
+ Process from WOKUnix,
+ SequenceOfProcess from WOKUnix
+is
+
+ Arm(myclass);
+
+ UnArm(myclass);
+
+ Processes(myclass) returns SequenceOfProcess from WOKUnix is private;
+ ---C++: return &
+
+ InteruptHandler(myclass);
+
+ ChildDeathHandler(myclass);
+
+ PipeHandler(myclass);
+
+ KillAll(myclass);
+
+ SetCriticalPid(myclass; apid : Integer);
+
+ AddProcess(myclass; aprocess : Process from WOKUnix) is private;
+
+ RemoveProcess(myclass; aprocess : Process from WOKUnix) is private;
+
+ WaitProcess(myclass; aprocess : Process from WOKUnix) is private;
+
+friends
+
+ class Process from WOKUnix,
+ class ShellManager from WOKUnix
+
+end;
--- /dev/null
+
+#include <sys/wait.h>
+
+#include <OSD_SIGINT.hxx>
+
+#include <WOKUnix_Signal.hxx>
+
+#include <WOKUnix_ProcessManager.ixx>
+
+#include <Standard_ProgramError.hxx>
+
+#include <WOKTools_Messages.hxx>
+
+static Standard_Integer CriticPid = 0;
+
+//=======================================================================
+//function : Arm
+//purpose :
+//=======================================================================
+void WOKUnix_ProcessManager::Arm()
+{
+ WOKUnix_Signal::Arm(WOKUnix_SIGINT, (WOKUnix_SigHandler) WOKUnix_ProcessManager::InteruptHandler);
+ WOKUnix_Signal::Arm(WOKUnix_SIGCHILD, (WOKUnix_SigHandler) WOKUnix_ProcessManager::ChildDeathHandler);
+ WOKUnix_Signal::Arm(WOKUnix_SIGPIPE, (WOKUnix_SigHandler) WOKUnix_ProcessManager::PipeHandler);
+}
+
+
+//=======================================================================
+//function : UnArm
+//purpose :
+//=======================================================================
+void WOKUnix_ProcessManager::UnArm()
+{
+ WOKUnix_Signal::Arm(WOKUnix_SIGINT, (WOKUnix_SigHandler) NULL);
+ WOKUnix_Signal::Arm(WOKUnix_SIGCHILD, (WOKUnix_SigHandler) NULL);
+ WOKUnix_Signal::Arm(WOKUnix_SIGPIPE, (WOKUnix_SigHandler) NULL);
+}
+
+//=======================================================================
+//function : Processes
+//purpose :
+//=======================================================================
+WOKUnix_SequenceOfProcess &WOKUnix_ProcessManager::Processes()
+{
+ static WOKUnix_SequenceOfProcess processes;
+
+ return processes;
+}
+
+//=======================================================================
+//function : InteruptHandler
+//purpose :
+//=======================================================================
+void WOKUnix_ProcessManager::InteruptHandler()
+{
+#ifdef WOK_VERBOSE
+ VerboseMsg("WOK_PROCESS") << "WOKUnix_ProcessManager::InteruptHandler"
+ << "Interupt Signal Launched !!" << endm;
+#endif
+
+ WOKUnix_ProcessManager::KillAll();
+ OSD_SIGINT::Raise("SIGINT 'interrupt' detected.");
+ return;
+}
+
+//=======================================================================
+//function : ChildDeathHandler
+//purpose :
+//=======================================================================
+void WOKUnix_ProcessManager::ChildDeathHandler()
+{
+ int pid, status;
+
+ pid = wait(&status);
+
+ if(pid == CriticPid)
+ {
+ ErrorMsg << "WOKUnix_ProcessManager::ChildDeathHandler"
+ << "Child " << pid << " died" << endm;
+ Standard_ProgramError::Raise("unexpected child shell death");
+ }
+
+ for(Standard_Integer ind = 1; ind <= Processes().Length(); ind ++)
+ {
+ if(Processes().Value(ind)->Pid() == pid)
+ {
+#ifdef WOK_VERBOSE
+ VerboseMsg("WOK_PROCESS") << "WOKUnix_ProcessManager::ChildDeathHandler"
+ << "Process " << pid << " died" << endm;
+#endif
+ Processes().Value(ind)->Kill();
+ Processes().Remove(ind);
+ return;
+ }
+ }
+ return;
+}
+
+//=======================================================================
+//function : PipeHandler
+//purpose :
+//=======================================================================
+void WOKUnix_ProcessManager::PipeHandler()
+{
+#ifdef WOK_VERBOSE
+ VerboseMsg("WOK_PROCESS") << "WOKUnix_ProcessManager::PipeHandler" << "SIGPIPE received" << endm;
+#endif
+ return;
+}
+
+//=======================================================================
+//function : KillAll
+//purpose :
+//=======================================================================
+void WOKUnix_ProcessManager::KillAll()
+{
+#ifdef WOK_VERBOSE
+ VerboseMsg("WOK_PROCESS") << "WOKUnix_ProcessManager::PipeHandler" << "Killing all sub proccesses" << endm;
+#endif
+
+ for(Standard_Integer ind = 1; ind <= Processes().Length(); ind ++)
+ {
+#ifdef WOK_VERBOSE
+ VerboseMsg("WOK_PROCESS") << "WOKUnix_ProcessManager::KillAll"
+ << "Process " << Processes().Value(ind)->Pid() << " requested to die (interrupt)" << endm;
+#endif
+ Processes().Value(ind)->Kill();
+ }
+ Processes().Clear();
+}
+
+//=======================================================================
+//function : SetCriticPid
+//purpose :
+//=======================================================================
+void WOKUnix_ProcessManager::SetCriticalPid(const Standard_Integer pid)
+{
+ CriticPid = pid;
+}
+
+//=======================================================================
+//function : AddProcess
+//purpose :
+//=======================================================================
+void WOKUnix_ProcessManager::AddProcess(const Handle(WOKUnix_Process)& aprocess)
+{
+ Processes().Append(aprocess);
+}
+
+//=======================================================================
+//function : RemoveProcess
+//purpose :
+//=======================================================================
+void WOKUnix_ProcessManager::RemoveProcess(const Handle(WOKUnix_Process)& aprocess)
+{
+
+ for(Standard_Integer ind = 1; ind <= Processes().Length(); ind ++)
+ {
+ if(Processes().Value(ind)->Pid() == aprocess->Pid())
+ {
+ Processes().Remove(ind);
+ break;
+ }
+ }
+}
+
+//=======================================================================
+//function : WaitProcess
+//purpose :
+//=======================================================================
+void WOKUnix_ProcessManager::WaitProcess(const Handle(WOKUnix_Process)& aprocess)
+{
+ Standard_Integer status, pid;
+ // ignore SIGCHILD for a while
+ WOKUnix_Signal::Arm(WOKUnix_SIGCHILD, (WOKUnix_SigHandler)NULL);
+
+
+#ifdef WOK_VERBOSE
+ VerboseMsg("WOK_PROCESS") << "WOKUnix_ProcessManager::WaitProcess"
+ << "Waiting for process " << aprocess->Pid() << " to die" << endm;
+#endif
+
+ pid = waitpid(aprocess->Pid(), &status, 0);
+
+#ifdef WOK_VERBOSE
+ VerboseMsg("WOK_PROCESS") << "WOKUnix_ProcessManager::WaitProcess"
+ << "Process " << aprocess->Pid() << " died" << endm;
+#endif
+
+ if(pid == aprocess->Pid())
+ {
+ WOKUnix_ProcessManager::RemoveProcess(aprocess);
+ }
+
+ WOKUnix_Signal::Arm(WOKUnix_SIGCHILD, (WOKUnix_SigHandler) WOKUnix_ProcessManager::ChildDeathHandler);
+ return;
+}
--- /dev/null
+-- File: WOKUnix_ProcessOutput.cdl
+-- Created: Thu May 4 16:23:17 1995
+-- Author: Jean GAUTIER
+-- <jga@cobrax>
+---Copyright: Matra Datavision 1995
+
+private deferred class ProcessOutput from WOKUnix
+inherits TShared from MMgt
+uses
+ Timeval from WOKUnix,
+ FDSet from WOKUnix,
+ FDescr from WOKUnix,
+ HSequenceOfHAsciiString from TColStd
+is
+ Initialize;
+
+ Clear(me) is deferred;
+ Echo(me) returns HSequenceOfHAsciiString from TColStd is deferred;
+ Errors(me) returns HSequenceOfHAsciiString from TColStd is deferred;
+
+ Select(me; afdmax : out Integer; atimeout : in out Timeval from WOKUnix; aset : out FDSet from WOKUnix) is deferred;
+
+ Acquit(me; selectstatus : Integer; aset : FDSet from WOKUnix) is deferred;
+
+ Close(me:mutable) is deferred;
+
+end;
--- /dev/null
+#include <WOKUnix_ProcessOutput.ixx>
+
+ WOKUnix_ProcessOutput::WOKUnix_ProcessOutput()
+{
+}
+
--- /dev/null
+-- File: WOKUnix_RegExp.cdl
+-- Created: Fri Aug 2 09:43:37 1996
+-- Author: PLOTNIKOV Eugeny
+-- <eugeny@maniax>
+---Copyright: Matra Datavision 1996
+
+class RegExp from WOKUnix inherits TShared from MMgt
+
+ ---Purpose: provides regular expression matching and searching
+
+ uses
+
+ RESyntax from WOKUnix,
+ HAsciiString from TCollection
+
+ raises
+
+ ProgramError from Standard
+
+ is
+
+ Create returns mutable RegExp from WOKUnix;
+ ---Purpose: creates a class instance
+
+ Create (
+ aPattern : HAsciiString from TCollection;
+ aSyntax : RESyntax from WOKUnix = WOKUnix_RESyntaxAWK;
+ aTransTbl : Address from Standard = NULL;
+ aTblLen : Integer from Standard = 0
+ ) returns mutable RegExp from WOKUnix
+ raises ProgramError from Standard;
+ ---Purpose: creates a class instance with given pattern that denotes a set
+ -- of strings. Defines a translation table <aTransTbl> and
+ -- its length <aTblLen> to perform character translation.
+ -- Supply NULL for <aTransTbl> and zero value for <aTblLen>
+ -- if no translation necessary. It is possible to set
+ -- syntax of the regular expression by meaning <aSyntax>
+ -- parameter.
+ ---Warning: raises if syntax of the regular expression given is incorrect
+
+ Destroy ( me : mutable );
+ ---Purpose: destroys all resources attached to the class instanse
+ ---C++: alias ~
+
+ SetPattern (
+ me : mutable;
+ aPattern : HAsciiString from TCollection;
+ aSyntax : RESyntax from WOKUnix = WOKUnix_RESyntaxAWK;
+ aTransTbl : Address from Standard = NULL;
+ aTblLen : Integer from Standard = 0
+ ) raises ProgramError from Standard;
+ ---Purpose: sets a new match pattern and possibly a new pattern syntax
+ ---Warning: raises if the syntax given is incorrect
+
+ Search (
+ me;
+ aString : HAsciiString from TCollection;
+ aStartPos : Integer from Standard = 1
+ ) returns Integer from Standard
+ raises ProgramError from Standard;
+ ---Purpose: searches a sub-string in the <aString> which matches
+ -- the specified pattern starting at index <aStartPos>.
+ -- Returns an index of the match position on success.
+ -- Returns -1 if no match was found.
+ -- Returns -2 if error was occur.
+ ---Warning: raises if no search pattern was set
+
+ Match (
+ me;
+ aString : HAsciiString from TCollection;
+ aStartPos : Integer from Standard = 1;
+ aStopPos : Integer from Standard = 1
+ ) returns Integer from Standard
+ raises ProgramError from Standard;
+ ---Purpose: match the pattern given against the string <aString>
+ -- starting at index <aStartPos>. Do not consider matching
+ -- past the position <aStopPos>.
+ -- Returns the length of the string matched on success.
+ -- Returns -1 if no match was found.
+ -- Returns -2 if error was occur.
+ ---Warning: raises if no search pattern was set
+
+ fields
+
+ myBuffer : Address from Standard;
+ myAlloc : Boolean from Standard;
+
+end RegExp;
--- /dev/null
+
+#include <WOKUnix_RegExp.ixx>
+
+#include <WOKUnix_regexp.h>
+
+#define BUFFER ( ( PRE_PATTERN_BUFFER )myBuffer )
+#define RAISE( str ) Standard_ProgramError :: Raise ( _TEXT( ( str ) ) );
+
+static _TCHAR errBuff[ 128 ];
+
+#ifndef WNT
+# define _tcscpy strcpy
+# define _tcscat strcat
+#endif //WNT
+
+WOKUnix_RegExp :: WOKUnix_RegExp () {
+
+ myBuffer = NULL;
+
+} // end constructor ( 1 )
+
+WOKUnix_RegExp :: WOKUnix_RegExp (
+ const Handle( TCollection_HAsciiString )& aPattern,
+ const WOKUnix_RESyntax aSyntax,
+ const Standard_Address aTransTbl,
+ const Standard_Integer aTblLen
+ ) {
+
+ SetPattern ( aPattern, aSyntax, aTransTbl, aTblLen );
+
+} // end constructro ( 2 )
+
+void WOKUnix_RegExp :: Destroy () {
+
+ if ( myBuffer != NULL ) {
+
+ if ( myAlloc )
+
+ delete [] BUFFER -> translate;
+
+ if ( BUFFER -> fastmap != NULL ) delete [] BUFFER -> fastmap;
+ if ( BUFFER -> buffer != NULL ) free ( ( void* )( BUFFER -> buffer ) );
+
+ delete myBuffer;
+
+ myBuffer = NULL;
+
+ } // end if
+
+} // end WOKUnix_RegExp :: Destroy
+
+void WOKUnix_RegExp :: SetPattern (
+ const Handle( TCollection_HAsciiString )& aPattern,
+ const WOKUnix_RESyntax aSyntax,
+ const Standard_Address aTransTbl,
+ const Standard_Integer aTblLen
+ ) {
+
+ int syntax;
+ _TCHAR* errMsg;
+
+ Destroy ();
+
+ myBuffer = new RE_PATTERN_BUFFER;
+ memset ( BUFFER, 0, sizeof ( RE_PATTERN_BUFFER ) );
+ BUFFER -> fastmap = new _TCHAR[ ( 1 << BYTEWIDTH ) ];
+
+ if ( aTransTbl != NULL ) {
+
+ if ( aTblLen != 0 ) {
+
+ BUFFER -> translate = new Standard_Character[ aTblLen ];
+ memcpy ( BUFFER -> translate, aTransTbl, aTblLen );
+ myAlloc = Standard_True;
+
+ } else {
+
+ BUFFER -> translate = ( _TCHAR* )aTransTbl;
+ myAlloc = Standard_False;
+
+ } // end else
+
+ } // end if
+
+ switch ( aSyntax ) {
+
+ case WOKUnix_RESyntaxAWK:
+ syntax = RE_SYNTAX_AWK;
+ break;
+
+ case WOKUnix_RESyntaxEGREP:
+ syntax = RE_SYNTAX_EGREP;
+ break;
+
+ case WOKUnix_RESyntaxGREP:
+ syntax = RE_SYNTAX_GREP;
+ break;
+
+ case WOKUnix_RESyntaxEMACS:
+ syntax = RE_SYNTAX_EMACS;
+ break;
+
+ default:
+ RAISE( "WOKUnix_RegExp (): incorrect parameter value ( syntax )" );
+
+ } // end switch
+
+ re_set_syntax ( syntax );
+
+ errMsg = re_compile_pattern (
+ aPattern -> ToCString (), aPattern -> Length (), BUFFER
+ );
+
+ if ( errMsg != NULL ) {
+
+ _tcscpy ( errBuff, _TEXT( "WOKUnix_RegExp (): error parsing specified pattern - " ) );
+ _tcscat ( errBuff, errMsg );
+
+ Standard_ProgramError :: Raise ( errBuff );
+
+ } // end if
+
+ re_compile_fastmap ( BUFFER );
+
+} // end WOKUnix_RegExp :: SetPattern
+
+Standard_Integer WOKUnix_RegExp :: Search (
+ const Handle( TCollection_HAsciiString )& aString,
+ const Standard_Integer aStartPos
+ ) const {
+
+ Standard_Integer retVal;
+
+ retVal = re_search (
+ BUFFER, aString -> ToCString (), aString -> Length (),
+ aStartPos - 1, 0, NULL
+ );
+
+ if ( retVal >= 0 ) ++retVal;
+
+ return retVal;
+
+} // end WOKUnix_RegExp :: Search
+
+Standard_Integer WOKUnix_RegExp :: Match (
+ const Handle( TCollection_HAsciiString )& aString,
+ const Standard_Integer aStartPos,
+ const Standard_Integer aStopPos
+ ) const {
+
+ Standard_Integer len = aString -> Length ();
+
+ return re_match_2 (
+ BUFFER, NULL, 0,
+ ( _TUCHAR* )( aString -> ToCString () ), len,
+ aStartPos - 1, NULL, ( aStopPos == 1 ? len : aStopPos - 1 )
+ );
+
+} // end WOKUnix_RegExp :: Match
+
--- /dev/null
+-- File: WOKUnix_RemoteShell.cdl
+-- Created: Mon Nov 6 14:29:52 1995
+-- Author: Jean GAUTIER
+-- <jga@cobrax>
+---Copyright: Matra Datavision 1995
+
+
+class RemoteShell from WOKUnix
+inherits Shell from WOKUnix
+
+ ---Purpose:
+
+uses
+ ShellMode from WOKUnix,
+ PopenOutputMode from WOKUnix,
+ PopenBufferMode from WOKUnix,
+ HAsciiString from TCollection,
+ AsciiString from TCollection
+is
+
+
+ Create(ahost : HAsciiString from TCollection;
+ apath : AsciiString from TCollection;
+ amode : ShellMode from WOKUnix = WOKUnix_AsynchronousMode;
+ outmode : PopenOutputMode from WOKUnix = WOKUnix_POPEN_MIX_OUT_ERR;
+ bufmode : PopenBufferMode from WOKUnix = WOKUnix_POPEN_BUFFERED)
+ returns mutable RemoteShell from WOKUnix;
+
+ SyncAndStatus(me : mutable) returns Integer is redefined;
+
+ SetUser(me:mutable; auser : HAsciiString from TCollection);
+ User(me) returns HAsciiString from TCollection;
+
+ SetPassword(me:mutable; auser : HAsciiString from TCollection);
+ Password(me) returns HAsciiString from TCollection;
+
+fields
+
+ myuser : HAsciiString from TCollection;
+ mypassword : HAsciiString from TCollection;
+
+end RemoteShell;
+
+
+
--- /dev/null
+// File: WOKUnix_RemoteShell.cxx
+// Created: Mon Nov 6 14:55:55 1995
+// Author: Jean GAUTIER
+// <jga@cobrax>
+
+#ifdef IRIX
+#include <unistd.h>
+#include <sys/types.h>
+#include <bstring.h>
+#include <sys/time.h>
+#endif
+
+#ifdef HPUX
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#endif
+
+#include <Standard_ProgramError.hxx>
+#include <WOKTools_Messages.hxx>
+#include <OSD_Protection.hxx>
+
+#include <WOKUnix_ShellStatus.hxx>
+#include <WOKUnix_ProcessManager.hxx>
+#include <TCollection_HAsciiString.hxx>
+#include <TCollection_AsciiString.hxx>
+
+#include <WOKUnix_RemoteShell.ixx>
+
+
+//=======================================================================
+//function : WOKUnix_RemoteShell
+//purpose :
+//=======================================================================
+ WOKUnix_RemoteShell::WOKUnix_RemoteShell(const Handle(TCollection_HAsciiString)& ahost,
+ const TCollection_AsciiString & apath,
+ const WOKUnix_ShellMode amode,
+ const WOKUnix_PopenOutputMode outmode,
+ const WOKUnix_PopenBufferMode bufmode)
+: WOKUnix_Shell(apath, amode, outmode, bufmode)
+{
+
+ char *rshellargv[]={"rsh" , ahost->ToCString(), "exec","/bin/csh", "-fs", NULL};
+ SetCommand(6,rshellargv);
+}
+
+//=======================================================================
+//function : SyncAndStatus
+//purpose :
+//=======================================================================
+ Standard_Integer WOKUnix_RemoteShell::SyncAndStatus()
+{
+ WOKUnix_FDSet readfds;
+ WOKUnix_Timeval s_timeout;
+ Standard_Integer selectstatus;
+ Standard_Integer fdmax;
+
+
+ if(!IsLaunched())
+ {
+ ErrorMsg << "WOKUnix_RemoteShell::SyncAndStatus()" << "Trying to perform sync to dead or unlaunched process" << endm;
+ Standard_ProgramError::Raise("WOKUnix_RemoteShell::SyncAndStatus()");
+ }
+
+ // beginning of the critical section
+ WOKUnix_ProcessManager::SetCriticalPid(Pid());
+
+ while(1)
+ {
+ FD_ZERO(&readfds);
+
+ //FD_SET(mystatus->No(), &readfds);
+
+ fdmax = 0;
+
+ // wait a moment ....
+ Select(fdmax, s_timeout, readfds);
+
+
+ s_timeout.tv_sec = 0;
+ s_timeout.tv_usec = 100000;
+
+ if((selectstatus=select(fdmax, (WOKUnix_FDSet_CAST)&readfds, NULL, NULL ,&s_timeout ) < 0))
+ {
+ perror("select");
+ WOKUnix_ProcessManager::SetCriticalPid(-1);
+ return 1;
+ }
+
+ mystatus->StatusFile().Close();
+ mystatus->StatusFile().Open(OSD_ReadWrite, OSD_Protection());
+ mystatus->StatusFile().Flush();
+
+ if(mystatus->StatusFile().GetSize()) // le status file n'est pas vide
+ {
+ //mystatus->StatusFile().Flush();
+
+ //lire le status file
+ mystatus->GetRemote();
+
+ Acquit(selectstatus, readfds); // Process output acquit
+
+ // vider le status file
+ mystatus->StatusFile().EmptyAndOpen();
+
+ //end of the critical section
+ WOKUnix_ProcessManager::SetCriticalPid(-1);
+ return mystatus->Status();
+ }
+
+ Acquit(selectstatus, readfds); // Process output acquit
+
+ }
+}
+
+//=======================================================================
+//function : SetUser
+//purpose :
+//=======================================================================
+void WOKUnix_RemoteShell::SetUser(const Handle(TCollection_HAsciiString)& auser)
+{
+ myuser = auser;
+}
+
+//=======================================================================
+//function : User
+//purpose :
+//=======================================================================
+Handle(TCollection_HAsciiString) WOKUnix_RemoteShell::User() const
+{
+ return myuser;
+}
+
+//=======================================================================
+//function : SetPassword
+//purpose :
+//=======================================================================
+void WOKUnix_RemoteShell::SetPassword(const Handle(TCollection_HAsciiString)& apassword)
+{
+ mypassword = apassword;
+}
+
+//=======================================================================
+//function : Password
+//purpose :
+//=======================================================================
+Handle(TCollection_HAsciiString) WOKUnix_RemoteShell::Password() const
+{
+ return mypassword;
+}
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+-- File: WOKUnix_Shell.cdl
+-- Created: Thu Jun 8 17:31:30 1995
+-- Author: Jean GAUTIER
+-- <jga@cobrax>
+---Copyright: Matra Datavision 1995
+
+
+class Shell from WOKUnix
+inherits Process from WOKUnix
+
+ ---Purpose:
+
+uses
+ Path from WOKUnix,
+ ShellMode from WOKUnix,
+ ShellStatus from WOKUnix,
+ PopenOutputMode from WOKUnix,
+ PopenBufferMode from WOKUnix,
+ HAsciiString from TCollection,
+ AsciiString from TCollection,
+ HSequenceOfHAsciiString from TColStd
+
+is
+ Create(amode : ShellMode from WOKUnix = WOKUnix_AsynchronousMode;
+ outmode : PopenOutputMode from WOKUnix = WOKUnix_POPEN_MIX_OUT_ERR;
+ bufmode : PopenBufferMode from WOKUnix = WOKUnix_POPEN_BUFFERED)
+ returns mutable Shell from WOKUnix;
+
+ Create(apath : AsciiString from TCollection;
+ amode : ShellMode from WOKUnix = WOKUnix_AsynchronousMode;
+ outmode : PopenOutputMode from WOKUnix = WOKUnix_POPEN_MIX_OUT_ERR;
+ bufmode : PopenBufferMode from WOKUnix = WOKUnix_POPEN_BUFFERED)
+ returns mutable Shell from WOKUnix;
+
+ SetEcho(me:mutable);
+ UnsetEcho(me:mutable);
+ IsEchoed(me)
+ returns Boolean from Standard;
+
+ Echo(me; astr : HAsciiString from TCollection);
+
+ Lock(me:mutable);
+ UnLock(me:mutable);
+ IsLocked(me)
+ returns Boolean from Standard;
+
+ LogInFile(me:mutable; apath : Path from WOKUnix);
+ NoLog(me:mutable);
+ LogFile(me)
+ returns Path from WOKUnix;
+
+ Log(me; astr : HAsciiString from TCollection);
+
+ SetSynchronous(me:mutable);
+ SetASynchronous(me:mutable);
+
+ SyncAndStatus(me : mutable) returns Integer is virtual;
+
+ Status(me) returns Integer;
+
+ Errors(me : mutable) returns HSequenceOfHAsciiString from TColStd;
+ ClearOutput(me : mutable);
+
+ Send(me : mutable; astring : HAsciiString from TCollection) is redefined;
+
+ Execute(me:mutable; astring : HAsciiString from TCollection) returns Integer from Standard;
+ Execute(me:mutable; somestrings : HSequenceOfHAsciiString from TColStd) returns Integer from Standard;
+
+ SetHost(me:mutable; ahost : HAsciiString from TCollection);
+ Host(me) returns HAsciiString from TCollection;
+
+fields
+
+ mystatus : ShellStatus from WOKUnix is protected;
+ mymode : ShellMode from WOKUnix;
+ myname : HAsciiString from TCollection;
+ mylocked : Boolean from Standard;
+ myecho : Boolean from Standard;
+ mylogfile : Path from WOKUnix;
+ myhost : HAsciiString from TCollection;
+end Shell;
--- /dev/null
+
+#ifdef IRIX
+#include <unistd.h>
+#include <sys/types.h>
+#include <bstring.h>
+#include <sys/time.h>
+#endif
+
+#ifdef HPUX
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#endif
+
+#include <fstream.h>
+
+#include <WOKTools_Messages.hxx>
+
+#include <WOKUnix_ASyncStatus.hxx>
+#include <WOKUnix_SyncStatus.hxx>
+#include <WOKUnix_DumpScript.hxx>
+#include <WOKUnix_ProcessOutput.hxx>
+#include <WOKUnix_ProcessManager.hxx>
+
+#include <WOKUnix_Shell.ixx>
+
+#ifndef WOK_IDLE_TRIGGER
+#define WOK_IDLE_TRIGGER 1
+#endif
+
+#ifdef WOK_IDLE_TRIGGER
+#include <WOKUtils_Triggers.hxx>
+#endif
+
+static char *ShellArgv[] = {"/bin/csh", "-f", NULL};
+
+//=======================================================================
+//function : WOKUnix_Shell
+//purpose :
+//=======================================================================
+WOKUnix_Shell::WOKUnix_Shell(const WOKUnix_ShellMode amode,
+ const WOKUnix_PopenOutputMode outmode,
+ const WOKUnix_PopenBufferMode bufmode)
+: WOKUnix_Process(3, ShellArgv, outmode, bufmode, -1), mymode(amode), myecho(Standard_False), mylocked(Standard_False)
+{
+ switch(amode)
+ {
+ case WOKUnix_SynchronousMode:
+ mystatus = new WOKUnix_SyncStatus;
+ break;
+ case WOKUnix_AsynchronousMode:
+ mystatus = new WOKUnix_ASyncStatus;
+ break;
+ case WOKUnix_DumpScriptMode:
+ mystatus = new WOKUnix_DumpScript;
+ break;
+ }
+
+}
+
+//=======================================================================
+//function : WOKUnix_Shell
+//purpose :
+//=======================================================================
+WOKUnix_Shell::WOKUnix_Shell(const TCollection_AsciiString& apath,
+ const WOKUnix_ShellMode amode,
+ const WOKUnix_PopenOutputMode outmode,
+ const WOKUnix_PopenBufferMode bufmode)
+: WOKUnix_Process(3, ShellArgv, outmode, bufmode, -1), mymode(amode), myecho(Standard_False), mylocked(Standard_False)
+{
+ switch(amode)
+ {
+ case WOKUnix_SynchronousMode:
+ mystatus = new WOKUnix_SyncStatus(apath);
+ break;
+ case WOKUnix_AsynchronousMode:
+ mystatus = new WOKUnix_ASyncStatus(apath);
+ break;
+ case WOKUnix_DumpScriptMode:
+ mystatus = new WOKUnix_DumpScript(apath);
+ break;
+ }
+
+}
+
+
+//=======================================================================
+//function : SetSynchronous
+//purpose :
+//=======================================================================
+void WOKUnix_Shell::SetSynchronous()
+{
+ // si deja en synchrone : ne rien faire
+ if(mymode == WOKUnix_SynchronousMode) return;
+ if(IsLaunched() == Standard_True)
+ {
+ // i have to forget what has be done before
+ mystatus->Reset(this);
+
+ // le nouveau est un synchrone
+ mystatus = new WOKUnix_SyncStatus();
+ mystatus->Reset(this);
+ }
+ mymode = WOKUnix_SynchronousMode;
+}
+
+//=======================================================================
+//function : SetEcho
+//purpose :
+//=======================================================================
+void WOKUnix_Shell::SetEcho()
+{
+ myecho = Standard_True;
+}
+
+//=======================================================================
+//function : UnsetEcho
+//purpose :
+//=======================================================================
+void WOKUnix_Shell::UnsetEcho()
+{
+ myecho = Standard_False;
+}
+
+//=======================================================================
+//function : IsEchoed
+//purpose :
+//=======================================================================
+Standard_Boolean WOKUnix_Shell::IsEchoed() const
+{
+ return myecho;
+}
+
+//=======================================================================
+//function : Echo
+//purpose :
+//=======================================================================
+void WOKUnix_Shell::Echo(const Handle(TCollection_HAsciiString)& astr) const
+{
+ if(myecho)
+ {
+ WOKTools_Info shellinfo = InfoMsg;
+ shellinfo.Init();
+ shellinfo.DontPrintHeader();
+ shellinfo.DontPrintContext();
+
+ shellinfo << "WOKUnix_Shell::Echo" << astr << endm;
+ }
+}
+
+//=======================================================================
+//function : Lock
+//purpose :
+//=======================================================================
+void WOKUnix_Shell::Lock()
+{
+ mylocked = Standard_True;
+}
+
+//=======================================================================
+//function : UnLock
+//purpose :
+//=======================================================================
+void WOKUnix_Shell::UnLock()
+{
+ mylocked = Standard_False;
+}
+
+//=======================================================================
+//function : IsLocked
+//purpose :
+//=======================================================================
+Standard_Boolean WOKUnix_Shell::IsLocked() const
+{
+ return mylocked;
+}
+
+//=======================================================================
+//function : LogInFile
+//purpose :
+//=======================================================================
+void WOKUnix_Shell::LogInFile(const Handle(WOKUnix_Path)& apath)
+{
+ if(apath.IsNull()) return;
+
+ if(!apath->Exists())
+ {
+ apath->CreateFile(Standard_True);
+ if(!apath->Exists()) return;
+ }
+
+ mylogfile = apath;
+}
+
+//=======================================================================
+//function : NoLog
+//purpose :
+//=======================================================================
+void WOKUnix_Shell::NoLog()
+{
+ mylogfile.Nullify();
+}
+
+//=======================================================================
+//function : LogFile
+//purpose :
+//=======================================================================
+Handle(WOKUnix_Path) WOKUnix_Shell::LogFile() const
+{
+ return mylogfile;
+}
+
+//=======================================================================
+//function : Log
+//purpose :
+//=======================================================================
+void WOKUnix_Shell::Log(const Handle(TCollection_HAsciiString)& astr) const
+{
+ if(!mylogfile.IsNull())
+ {
+ ofstream logfile(mylogfile->Name()->ToCString(), ios::app);
+ if(!logfile.bad())
+ {
+ logfile << astr->ToCString();
+ logfile.close();
+ }
+ }
+}
+
+//=======================================================================
+//function : SetASynchronous
+//purpose :
+//=======================================================================
+void WOKUnix_Shell::SetASynchronous()
+{
+ // si deja en synchrone : ne rien faire
+ if(mymode == WOKUnix_AsynchronousMode) return;
+ if(IsLaunched() == Standard_True)
+ {
+ // i have to forget what has be done before
+ mystatus->Reset(this);
+
+ // le nouveau est un asynchrone
+ mystatus = new WOKUnix_ASyncStatus();
+ mystatus->Reset(this);
+ }
+ mymode = WOKUnix_AsynchronousMode;
+}
+
+//=======================================================================
+//function : SyncAndStatus
+//purpose :
+//=======================================================================
+ Standard_Integer WOKUnix_Shell::SyncAndStatus()
+{
+ WOKUnix_FDSet readfds;
+ WOKUnix_Timeval s_timeout;
+ WOKUnix_Timeval* p_timeout;
+ Standard_Integer selectstatus;
+ Standard_Integer fdmax;
+
+ WOKUnix_ProcessManager::SetCriticalPid(Pid());
+
+ WOK_TRACE {
+ VerboseMsg("WOK_PROCESS") << "WOKUnix_Shell::SyncAndStatus"
+ << "Entering SyncAndStatus" << endm;
+ }
+
+ while(1)
+ {
+ FD_ZERO(&readfds);
+
+ FD_SET(mystatus->No(), &readfds);
+
+ fdmax = mystatus->No();
+
+ if(Timeout() > 0)
+ {
+ s_timeout.tv_sec = Timeout();
+ p_timeout = &s_timeout;
+ }
+ else
+ {
+ p_timeout = NULL;
+ }
+
+
+ Select(fdmax, s_timeout, readfds); // process output Select
+
+#ifdef WOK_VERBOSE
+ if(VerboseMsg("WOK_PROCESS").IsSet()) {
+ Standard_Integer i;
+
+ if(p_timeout) {
+ VerboseMsg("WOK_PROCESS") << "WOKUnix_Shell::SyncAndStatus"
+ << "Entering select : timeout : " << (const int) s_timeout.tv_sec << "s " << (const int) s_timeout.tv_usec << "ms" << endm;
+ } else {
+ VerboseMsg("WOK_PROCESS") << "WOKUnix_Shell::SyncAndStatus"
+ << "Entering select : infinite wait" << endm;
+ }
+
+
+ for(i=0; i<fdmax; i++) {
+ if(FD_ISSET(i,&readfds)) {
+ VerboseMsg("WOK_PROCESS") << "WOKUnix_Shell::SyncAndStatus" << "FD " << (const int) i << " is setted" << endm;
+ }
+ }
+ }
+
+#endif
+
+ if((selectstatus=select(fdmax, (WOKUnix_FDSet_CAST) &readfds, NULL, NULL , &s_timeout)) < 0)
+ {
+ perror("select");
+ WOKUnix_ProcessManager::SetCriticalPid(-1);
+ return 1;
+ }
+
+#ifdef WOK_IDLE_TRIGGER
+
+ WOKUtils_Trigger idle;
+
+ idle("WOK_DoWhenIdle") << endt;
+
+#endif
+
+ if(FD_ISSET(mystatus->No(), &readfds))
+ {
+ // le status pipe est en select ---> ca m'interesse avant tout
+ mystatus->Get();
+ Acquit(selectstatus, readfds); // Process output acquit
+ WOKUnix_ProcessManager::SetCriticalPid(-1);
+ return mystatus->Status();
+ }
+
+#ifdef WOK_VERBOSE
+ VerboseMsg("WOK_PROCESS") << "WOKUnix_Shell::SyncAndStatus"
+ << "Aquit output" << endm;
+#endif
+
+ Acquit(selectstatus, readfds); // Process output acquit
+ }
+}
+
+//=======================================================================
+//function : Status
+//purpose :
+//=======================================================================
+Standard_Integer WOKUnix_Shell::Status() const
+{
+ return mystatus->Status();
+}
+
+//=======================================================================
+//function : Errors
+//purpose :
+//=======================================================================
+Handle(TColStd_HSequenceOfHAsciiString) WOKUnix_Shell::Errors()
+{
+ return Output()->Errors();
+}
+
+//=======================================================================
+//function : ClearOutput
+//purpose :
+//=======================================================================
+void WOKUnix_Shell::ClearOutput()
+{
+ Output()->Clear();
+}
+
+//=======================================================================
+//function : Send
+//purpose :
+//=======================================================================
+void WOKUnix_Shell::Send(const Handle(TCollection_HAsciiString)& astring)
+{
+ Log(astring);
+ Echo(astring);
+ WOKUnix_Process::Send(astring);
+ return;
+}
+
+//=======================================================================
+//function : Execute
+//purpose :
+//=======================================================================
+Standard_Integer WOKUnix_Shell::Execute(const Handle(TCollection_HAsciiString)& astring)
+{
+ Log(astring);
+ Echo(astring);
+ WOKUnix_Process::Send(astring);
+ mystatus->EndCmd(this);
+ mystatus->Sync(this);
+ return mystatus->Status();
+}
+
+
+//=======================================================================
+//function : Execute
+//purpose :
+//=======================================================================
+Standard_Integer WOKUnix_Shell::Execute(const Handle(TColStd_HSequenceOfHAsciiString)& somestrings)
+{
+ Handle(TCollection_HAsciiString) astring;
+
+ for(Standard_Integer i = 1; i <= somestrings->Length(); i++)
+ {
+ astring = somestrings->Value(i);
+
+ Log(astring);
+ Echo(astring);
+
+ WOKUnix_Process::Send(astring);
+ mystatus->EndCmd(this);
+ }
+ mystatus->Sync(this);
+ return mystatus->Status();
+}
+
+//=======================================================================
+//function : SetHost
+//purpose :
+//=======================================================================
+void WOKUnix_Shell::SetHost(const Handle(TCollection_HAsciiString)& ahost)
+{
+
+ myhost = ahost;
+}
+
+//=======================================================================
+//function : Host
+//purpose :
+//=======================================================================
+Handle(TCollection_HAsciiString) WOKUnix_Shell::Host() const
+{
+ return myhost;
+}
+
+
--- /dev/null
+-- File: WOKUnix_ShellManager.cdl
+-- Created: Thu Apr 4 22:55:35 1996
+-- Author: Jean GAUTIER
+-- <jga@cobrax>
+---Copyright: Matra Datavision 1996
+
+
+class ShellManager from WOKUnix
+
+ ---Purpose:
+
+uses
+
+ Shell from WOKUnix,
+ RemoteShell from WOKUnix,
+ HAsciiString from TCollection,
+ AsciiString from TCollection
+
+is
+
+ GetShell(myclass)
+ ---Purpose: returns one unlocked shell of processes list
+ returns Shell from WOKUnix;
+
+ GetShell(myclass; apid : Integer from Standard)
+ ---Purpose: get a precise shell
+ returns Shell from WOKUnix;
+
+ GetRemoteShell(myclass;
+ ahost : HAsciiString from TCollection;
+ apath : AsciiString from TCollection)
+ ---Purpose: returns a host's unlocked remote shell of processes list
+ returns RemoteShell from WOKUnix;
+
+end ShellManager;
+
--- /dev/null
+// File: WOKUnix_ShellManager.cxx
+// Created: Thu Apr 4 23:21:02 1996
+// Author: Jean GAUTIER
+// <jga@cobrax>
+
+#include <WOKUnix_ShellManager.ixx>
+
+#include <WOKUnix_ProcessManager.hxx>
+#include <WOKUnix_SequenceOfProcess.hxx>
+#include <WOKUnix_Shell.hxx>
+#include <WOKUnix_RemoteShell.hxx>
+
+//=======================================================================
+//function : GetShell
+//purpose :
+//=======================================================================
+Handle(WOKUnix_Shell) WOKUnix_ShellManager::GetShell()
+{
+ Standard_Integer i;
+ WOKUnix_SequenceOfProcess& procseq = WOKUnix_ProcessManager::Processes();
+ Handle(WOKUnix_Shell) ashell;
+
+ for(i=1; i<=procseq.Length(); i++)
+ {
+ ashell = Handle(WOKUnix_Shell)::DownCast(procseq.Value(i));
+ if(!ashell.IsNull())
+ {
+
+ if(!ashell->IsLocked())
+ {
+ return ashell;
+ }
+ }
+ }
+ ashell = new WOKUnix_Shell;
+
+ return ashell;
+}
+
+//=======================================================================
+//function : GetShell
+//purpose :
+//=======================================================================
+Handle(WOKUnix_Shell) WOKUnix_ShellManager::GetShell(const Standard_Integer apid)
+{
+ Standard_Integer i;
+ WOKUnix_SequenceOfProcess& procseq = WOKUnix_ProcessManager::Processes();
+ Handle(WOKUnix_Shell) ashell;
+
+ for(i=1; i<=procseq.Length(); i++)
+ {
+ if(procseq.Value(i)->IsKind(STANDARD_TYPE(WOKUnix_Shell)))
+ {
+ ashell = Handle(WOKUnix_Shell)::DownCast(procseq.Value(i));
+
+ if(!ashell->Pid() == apid)
+ {
+ return ashell;
+ }
+ else ashell.Nullify();
+ }
+ }
+ return ashell;
+}
+
+//=======================================================================
+//function : GetRemoteShell
+//purpose :
+//=======================================================================
+Handle(WOKUnix_RemoteShell) WOKUnix_ShellManager::GetRemoteShell(const Handle(TCollection_HAsciiString) & ahost,
+ const TCollection_AsciiString & apath)
+{
+ Standard_Integer i;
+ WOKUnix_SequenceOfProcess& procseq = WOKUnix_ProcessManager::Processes();
+ Handle(WOKUnix_RemoteShell) aremoteshell;
+
+ for(i=1; i<=procseq.Length(); i++)
+ {
+ if(procseq.Value(i)->IsKind(STANDARD_TYPE(WOKUnix_RemoteShell)))
+ {
+
+ aremoteshell = Handle(WOKUnix_RemoteShell)::DownCast(procseq.Value(i));
+
+ if( (!aremoteshell->IsLocked()) && (!strcmp(aremoteshell->Host()->ToCString(),ahost->ToCString()) ))
+ {
+ return aremoteshell;
+ }
+ }
+ }
+ aremoteshell = new WOKUnix_RemoteShell(ahost,apath);
+
+ return aremoteshell;
+}
+
+
+
+
+
+
+
--- /dev/null
+
+-- -- File: WOKUnix_ShellStatus.cdl
+-- Created: Thu Jun 8 18:22:21 1995
+-- Author: Jean GAUTIER
+-- <jga@cobrax>
+---Copyright: Matra Datavision 1995
+
+
+private deferred class ShellStatus from WOKUnix
+inherits TShared from MMgt
+ ---Purpose:
+
+uses
+ FDescr from WOKUnix,
+ Shell from WOKUnix,
+ HAsciiString from TCollection,
+ AsciiString from TCollection,
+ File from OSD
+
+raises
+
+ ProgramError from Standard
+is
+ Initialize;
+ Initialize(apath : AsciiString from TCollection);
+
+ StatusFile(me:mutable) returns FDescr from WOKUnix;
+ ---C++:return &
+
+
+ No(me) returns Integer is static;
+ Name(me) returns HAsciiString from TCollection is static;
+
+ Status(me) returns Integer is static;
+
+ EndCmd(me:mutable; ashell : Shell from WOKUnix) is deferred;
+ Sync(me:mutable; ashell : Shell from WOKUnix) is deferred;
+ Reset(me:mutable; ashell : Shell from WOKUnix) is deferred;
+
+ Get(me:mutable) returns Integer raises ProgramError from Standard is virtual;
+ GetRemote(me:mutable) returns Integer raises ProgramError from Standard is virtual;
+
+ Destroy(me:mutable)
+ ---C++: alias ~
+ is virtual;
+
+fields
+ mystatus : Integer is protected;
+ myfile : FDescr from WOKUnix;
+
+end ShellStatus;
+
+
+
+
--- /dev/null
+
+#include <WOKUnix_ShellStatus.ixx>
+
+#include <TCollection_AsciiString.hxx>
+
+//=======================================================================
+//function : WOKUnix_ShellStatus
+//purpose :
+//=======================================================================
+ WOKUnix_ShellStatus::WOKUnix_ShellStatus()
+{
+ myfile.BuildNamedPipe();
+}
+
+//=======================================================================
+//function : WOKUnix_ShellStatus
+//purpose :
+//=======================================================================
+ WOKUnix_ShellStatus::WOKUnix_ShellStatus(const TCollection_AsciiString& apath)
+{
+ myfile.BuildTemporary(apath);
+}
+
+//=======================================================================
+//function : StatusFile
+//purpose :
+//=======================================================================
+ WOKUnix_FDescr & WOKUnix_ShellStatus::StatusFile()
+{
+ return myfile;
+}
+
+//=======================================================================
+//function : No
+//purpose :
+//=======================================================================
+Standard_Integer WOKUnix_ShellStatus::No() const
+{
+ return myfile.FileNo();
+}
+
+
+//=======================================================================
+//function : Name
+//purpose :
+//=======================================================================
+Handle(TCollection_HAsciiString) WOKUnix_ShellStatus::Name() const
+{
+ return myfile.Name();
+}
+
+//=======================================================================
+//function : Status
+//purpose :
+//=======================================================================
+Standard_Integer WOKUnix_ShellStatus::Status() const
+{
+ return mystatus;
+}
+
+//=======================================================================
+//function : Get
+//purpose : Reads on a pipe the status of a shell command
+//=======================================================================
+Standard_Integer WOKUnix_ShellStatus::Get()
+{
+ myfile.Flush();
+
+ Standard_Integer nbtoread = myfile.GetNbToRead();
+ if(nbtoread == 0)
+ {
+ Standard_ProgramError::Raise("ShellStatus::Get : Nothing to read on status pipe\n");
+ return 1;
+ }
+
+ TCollection_AsciiString buf;
+
+ myfile.Read(buf, nbtoread);
+ if(nbtoread != buf.Length())
+ {
+ perror(Name()->ToCString());
+ Standard_ProgramError::Raise("ShellStatus::Get : Could not read from status pipe\n");
+ return 1;
+ }
+ buf.Trunc(nbtoread);
+ mystatus = buf.IntegerValue();
+
+ return mystatus;
+}
+//=======================================================================
+//function : GetRemote
+//purpose : Reads in a file the status of a remote shell command
+//=======================================================================
+Standard_Integer WOKUnix_ShellStatus::GetRemote()
+{
+ myfile.Flush();
+
+ Standard_Integer nbtoread = myfile.GetSize();
+ if(nbtoread == 0)
+ {
+ Standard_ProgramError::Raise("ShellStatus::GetRemote : Nothing to read on status file\n");
+ return 1;
+ }
+
+ TCollection_AsciiString buf;
+
+ myfile.Read(buf, nbtoread);
+ if(nbtoread != buf.Length())
+ {
+ perror(Name()->ToCString());
+ Standard_ProgramError::Raise("ShellStatus::GetRemote : Could not read from status file\n");
+ return 1;
+ }
+ buf.Trunc(nbtoread);
+ mystatus = buf.IntegerValue();
+
+ return mystatus;
+}
+
+//=======================================================================
+//function : Destroy
+//purpose :
+//=======================================================================
+void WOKUnix_ShellStatus::Destroy()
+{
+ myfile.Remove();
+}
+
+
+
+
--- /dev/null
+// File: WOKUnix_SigHandler.hxx
+// Created: Wed May 24 18:35:36 1995
+// Author: Jean GAUTIER
+// <jga@cobrax>
+
+
+#ifndef WOKUnix_SigHandler_HeaderFile
+#define WOKUnix_SigHandler_HeaderFile
+
+
+#ifdef SUN
+#include <floatingpoint.h>
+#endif
+
+#ifdef SOLARIS
+#include <floatingpoint.h>
+#include <sys/machsig.h>
+
+#define FPE_FLTDIV_TRAP FPE_FLTDIV
+#define FPE_INTDIV_TRAP FPE_INTDIV
+#define FPE_FLTOVF_TRAP FPE_FLTOVF
+#define FPE_INTOVF_TRAP FPE_INTOVF
+#define FPE_FLTUND_TRAP FPE_FLTUND
+extern "C" {int ieee_handler(char *,char *, sigfpe_handler_type&);};
+#endif
+
+
+#ifdef IRIX
+#include <sys/siginfo.h>
+#define FPE_FLTDIV_TRAP FPE_FLTDIV
+#define FPE_INTDIV_TRAP FPE_INTDIV
+#define FPE_FLTOVF_TRAP FPE_FLTOVF
+#define FPE_INTOVF_TRAP FPE_INTOVF
+#define FPE_FLTUND_TRAP FPE_FLTUND
+#endif
+
+typedef void (* WOKUnix_SigHandler) (int);
+
+#endif
--- /dev/null
+-- File: WOKUnix_Signal.cdl
+-- Created: Wed May 24 17:32:41 1995
+-- Author: Jean GAUTIER
+-- <jga@cobrax>
+---Copyright: Matra Datavision 1995
+
+class Signal from WOKUnix
+uses
+ Signals from WOKUnix,
+ SigHandler from WOKUnix
+is
+ Create returns Signal from WOKUnix;
+ Create(asig : Signals from WOKUnix) returns Signal from WOKUnix;
+
+ Set(me : in out; asig : Signals from WOKUnix);
+
+ Arm(me : in out; ahandler : SigHandler from WOKUnix);
+ Arm(myclass; asig : Signals from WOKUnix; ahandler : SigHandler from WOKUnix);
+
+ GetSig(myclass; asig : Signals from WOKUnix) returns Integer from Standard is private;
+
+fields
+ mysig : Signals from WOKUnix;
+ isarmed : Boolean from Standard;
+end;
+
--- /dev/null
+
+#include <WOKUnix_Signal.ixx>
+
+
+#include <stdlib.h>
+#include <signal.h>
+
+#ifndef HPUX
+#include <siginfo.h>
+#endif
+
+//=======================================================================
+//function : WOKUnix_Signal
+//purpose :
+//=======================================================================
+ WOKUnix_Signal::WOKUnix_Signal()
+{
+ isarmed = Standard_False;
+}
+
+//=======================================================================
+//function : WOKUnix_Signal
+//purpose :
+//=======================================================================
+ WOKUnix_Signal::WOKUnix_Signal(const WOKUnix_Signals asig)
+{
+ mysig = asig;
+ isarmed = Standard_False;
+}
+
+//=======================================================================
+//function : Set
+//purpose :
+//=======================================================================
+void WOKUnix_Signal::Set(const WOKUnix_Signals asig)
+{
+ mysig = asig;
+ isarmed = Standard_False;
+}
+
+//=======================================================================
+//function : Arm
+//purpose :
+//=======================================================================
+void WOKUnix_Signal::Arm(const WOKUnix_SigHandler& ahandler)
+{
+ struct sigaction act, oact;
+ int stat;
+
+ //==== Save the old Signale Handler, and set the new one ===================
+
+ if(ahandler == NULL)
+ {
+ act.sa_handler = (WOKUnix_SigHandler) SIG_DFL;
+ }
+ else
+ {
+ act.sa_handler = (WOKUnix_SigHandler) ahandler;
+ }
+#ifdef SOLARIS
+ act.sa_mask.__sigbits[0] = 0;
+ act.sa_mask.__sigbits[1] = 0;
+ act.sa_mask.__sigbits[2] = 0;
+ act.sa_mask.__sigbits[3] = 0;
+ act.sa_flags = SA_RESTART;
+#elif HPUX
+ act.sa_mask.sigset[0] = 0;
+ act.sa_mask.sigset[1] = 0;
+ act.sa_mask.sigset[2] = 0;
+ act.sa_mask.sigset[3] = 0;
+ act.sa_mask.sigset[4] = 0;
+ act.sa_mask.sigset[5] = 0;
+ act.sa_mask.sigset[6] = 0;
+ act.sa_mask.sigset[7] = 0;
+ act.sa_flags = 0;
+#elif IRIX
+ act.sa_mask.__sigbits[0] = 0;
+ act.sa_mask.__sigbits[1] = 0;
+ act.sa_mask.__sigbits[2] = 0;
+ act.sa_mask.__sigbits[3] = 0;
+ act.sa_flags = 0;
+#else
+ act.sa_mask = 0;
+ act.sa_flags = 0;
+#endif
+
+ //==== Always detected the signal "SIGFPE" =================================
+ stat = sigaction(WOKUnix_Signal::GetSig(mysig),&act,&oact); // ...... floating point exception
+ if (stat) {
+ cerr << "sigaction does not work !!! KO " << endl;
+ perror("sigaction ");
+ }
+}
+
+//=======================================================================
+//function : Arm
+//purpose :
+//=======================================================================
+void WOKUnix_Signal::Arm(const WOKUnix_Signals asig, const WOKUnix_SigHandler& ahandler)
+{
+ WOKUnix_Signal thesig(asig);
+
+ thesig.Arm(ahandler);
+}
+
+int WOKUnix_Signal::GetSig(const WOKUnix_Signals asig)
+{
+ switch (asig)
+ {
+ case WOKUnix_SIGPIPE : return SIGPIPE;
+ case WOKUnix_SIGHUP : return SIGHUP;
+ case WOKUnix_SIGINT : return SIGINT;
+ case WOKUnix_SIGQUIT : return SIGQUIT;
+ case WOKUnix_SIGILL : return SIGILL;
+ case WOKUnix_SIGKILL : return SIGKILL;
+ case WOKUnix_SIGBUS : return SIGBUS;
+ case WOKUnix_SIGSEGV : return SIGSEGV;
+ case WOKUnix_SIGCHILD : return SIGCLD;
+ }
+}
--- /dev/null
+// File: WOKUnix_StatBuf.hxx
+// Author: Jean GAUTIER
+// <jga@cobrax>
+
+
+#ifndef WOKUnix_StatBuf_HeaderFile
+#define WOKUnix_StatBuf_HeaderFile
+
+#ifndef WNT
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+typedef struct stat WOKUnix_StatBuf;
+
+#else
+
+#error "Type StatBuf does not exist on WNT"
+
+#endif
+
+#endif
--- /dev/null
+-- File: WOKUnix_SyncStatus.cdl
+-- Created: Thu Jun 8 20:07:25 1995
+-- Author: Jean GAUTIER
+-- <jga@cobrax>
+---Copyright: Matra Datavision 1995
+
+
+private class SyncStatus from WOKUnix
+inherits ShellStatus from WOKUnix
+ ---Purpose:
+
+uses
+ AsciiString from TCollection,
+ Shell from WOKUnix
+is
+ Create returns mutable SyncStatus from WOKUnix;
+ Create(apath : AsciiString from TCollection)
+ returns mutable SyncStatus from WOKUnix;
+
+ EndCmd(me:mutable; ashell : Shell from WOKUnix) is redefined;
+ Sync(me:mutable; ashell : Shell from WOKUnix) is redefined;
+ Reset(me:mutable; ashell : Shell from WOKUnix) is redefined;
+
+end SyncStatus;
--- /dev/null
+
+
+#include <WOKTools_Messages.hxx>
+
+#include <TCollection_HAsciiString.hxx>
+#include <TCollection_AsciiString.hxx>
+#include <WOKUnix_SyncStatus.ixx>
+
+
+//=======================================================================
+//function : WOKUnix_SyncStatus
+//purpose :
+//=======================================================================
+ WOKUnix_SyncStatus::WOKUnix_SyncStatus()
+{
+}
+
+//=======================================================================
+//function : WOKUnix_SyncStatus
+//purpose :
+//=======================================================================
+ WOKUnix_SyncStatus::WOKUnix_SyncStatus(const TCollection_AsciiString & apath)
+ :WOKUnix_ShellStatus(apath)
+{
+}
+
+//=======================================================================
+//function : EndCmd
+//purpose :
+//=======================================================================
+void WOKUnix_SyncStatus::EndCmd(const Handle(WOKUnix_Shell)& ashell)
+{
+#ifdef USE_SYNCHRO
+ Handle(TCollection_HAsciiString) abuf = new TCollection_HAsciiString("\n/tmp/synchro ");
+ abuf->AssignCat(Name());
+ abuf->AssignCat(" $status\n");
+#else
+ Handle(TCollection_HAsciiString) abuf = new TCollection_HAsciiString("\necho $status > ");
+ abuf->AssignCat(Name());
+ abuf->AssignCat("\n");
+#endif
+ ashell->WOKUnix_Process::Send(abuf);
+
+ mystatus = ashell->SyncAndStatus();
+
+#ifdef WOK_VERBOSE
+ VerboseMsg("WOK_PROCESS") << "WOKUnix_SyncStatus::EndCmd" << "Command ended with status : " << mystatus << endm;
+#endif
+}
+
+//=======================================================================
+//function : Sync
+//purpose :
+//=======================================================================
+void WOKUnix_SyncStatus::Sync(const Handle(WOKUnix_Shell)& )
+{
+
+}
+
+//=======================================================================
+//function : Reset
+//purpose :
+//=======================================================================
+void WOKUnix_SyncStatus::Reset(const Handle(WOKUnix_Shell)& )
+{
+}
+
--- /dev/null
+// File: WOKUnix_TimeStat.hxx
+// Created: Mon Jun 26 15:46:11 1995
+// Author: Jean GAUTIER
+// <jga@cobrax>
+
+
+#ifndef WOKUnix_TimeStat_HeaderFile
+#define WOKUnix_TimeStat_HeaderFile
+
+#include <sys/types.h>
+
+
+// time time in return of stat system call
+
+typedef time_t WOKUnix_TimeStat;
+
+
+#endif
--- /dev/null
+// File: WOKUnix_Timeval.hxx
+// Created: Tue May 9 15:24:00 1995
+// Author: Jean GAUTIER
+// <jga@cobrax>
+
+
+#ifndef WOKUnix_Timeval_HeaderFile
+#define WOKUnix_Timeval_HeaderFile
+
+#include <sys/time.h>
+
+typedef struct timeval WOKUnix_Timeval ;
+
+#endif
--- /dev/null
+-- File: WOKUnix_WOKSteps.edl
+-- Author: Jean GAUTIER
+-- History: Tue Aug 12 17:19:49 1997 Jean GAUTIER Creation
+-- Copyright: Matra Datavision 1997
+
+@ifnotdefined ( %WOKUnix_WOKSteps_EDL) then
+@set %WOKUnix_WOKSteps_EDL = "";
+
+@if ( %Station == "wnt" ) then
+
+ @set %WOKSteps_ObjGroup = "obj.nocompil";
+ @set %WOKSteps_LibGroup = "";
+
+ @set %WOKSteps_obj_nocompil = "WOKStep_Compile";
+
+ @set %WOKSteps_toolkit_ListWith = "obj.nocompil";
+ @set %WOKSteps_toolkit_LinksWith = "obj.nocompil";
+
+@endif;
+
+@endif;
--- /dev/null
+
+#ifndef __REGEXP_H
+# define __REGEXP_H
+/***/
+# ifdef WNT
+# ifdef UNICODE_API
+# ifndef _UNICODE
+# define _UNICODE
+# endif /* _UNICODE */
+# endif /* UNICODE_API */
+/***/
+# ifndef _INC_TCHAR
+# include <tchar.h>
+# endif /* _INC_TCHAR */
+/***/
+# ifndef _INC_STDLIB
+# include <stdlib.h>
+# endif /* _INC_STDLIB */
+/***/
+# ifndef _INC_MALLOC
+# include <malloc.h>
+# endif /* _INC_MALLOC */
+/***/
+# ifndef _INC_LIMITS
+# include <limits.h>
+# endif /* _INC_LIMITS */
+# ifndef _INC_STRING
+# include <string.h>
+# endif /* _INC_STRING */
+/***/
+# ifdef __WOKUnix_DLL
+# define REGEXP_API __declspec( dllexport )
+# else
+# define REGEXP_API __declspec( dllimport )
+# endif /* __OSD_DLL */
+# else
+# define _TEXT( arg ) arg
+# define REGEXP_API
+# include <stdio.h>
+# include <limits.h>
+typedef char _TCHAR;
+typedef char TCHAR;
+typedef unsigned char _TUCHAR;
+# endif /* WNT */
+/***/
+/******************************************************************************/
+/* Definitions for data structures callers pass the regex library. */
+/* Copyright (C) 1985 Free Software Foundation, Inc. */
+/* */
+/* This program is free software; you can redistribute it and/or modify */
+/* it under the terms of the GNU General Public License as published by */
+/* the Free Software Foundation; either version 1, or (at your option) */
+/* any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+/* */
+/* In other words, you are welcome to use, share and improve this program. */
+/* You are forbidden to forbid anyone else to use, share and improve */
+/* what you give them. Help stamp out software-hoarding! */
+/******************************************************************************/
+/******************************************************************************/
+/* Modified by EUG ( MATRA Datavision ) for Windows NT and UNICODE ( 1996 ) */
+/******************************************************************************/
+/***/
+/******************************************************************************/
+/* Define number of parens for which we record the beginnings and ends. */
+/* This affects how much space the `struct re_registers' type takes up. */
+/******************************************************************************/
+#ifndef RE_NREGS
+# define RE_NREGS 10
+#endif
+/***/
+/******************************************************************************/
+/* */
+/* width of a byte in bits */
+/* */
+/******************************************************************************/
+/***/
+#ifdef _UNICODE
+# define BYTEWIDTH ( CHAR_BIT * sizeof ( TCHAR ) )
+# define CHAR_MASK USHRT_MAX
+#else
+# define BYTEWIDTH CHAR_BIT
+# define CHAR_MASK UCHAR_MAX
+#endif /* _UNICODE */
+/***/
+/******************************************************************************/
+/* These bits are used in the obscure_syntax variable to choose among */
+/* alternative regexp syntaxes. */
+/* */
+/* 1 means plain parentheses serve as grouping, and backslash */
+/* parentheses are needed for literal searching. */
+/* 0 means backslash-parentheses are grouping, and plain parentheses */
+/* are for literal searching. */
+/******************************************************************************/
+#define RE_NO_BK_PARENS 1
+/******************************************************************************/
+/* 1 means plain | serves as the "or"-operator, and \| is a literal. */
+/* 0 means \| serves as the "or"-operator, and | is a literal. */
+/******************************************************************************/
+#define RE_NO_BK_VBAR 2
+/******************************************************************************/
+/* 0 means plain + or ? serves as an operator, and \+, \? are literals. */
+/* 1 means \+, \? are operators and plain +, ? are literals. */
+/******************************************************************************/
+#define RE_BK_PLUS_QM 4
+/******************************************************************************/
+/* 1 means | binds tighter than ^ or $. */
+/* 0 means the contrary. */
+/******************************************************************************/
+#define RE_TIGHT_VBAR 8
+/******************************************************************************/
+/* 1 means treat \n as an _OR operator */
+/* 0 means treat it as a normal character */
+/******************************************************************************/
+#define RE_NEWLINE_OR 16
+/******************************************************************************/
+/* 0 means that a special characters (such as *, ^, and $) always have */
+/* their special meaning regardless of the surrounding context. */
+/* 1 means that special characters may act as normal characters in some */
+/* contexts. Specifically, this applies to: */
+/* ^ - only special at the beginning, or after ( or | */
+/* $ - only special at the end, or before ) or | */
+/* *, +, ? - only special when not after the beginning, (, or | */
+/******************************************************************************/
+#define RE_CONTEXT_INDEP_OPS 32
+/******************************************************************************/
+/* Now define combinations of bits for the standard possibilities. */
+/******************************************************************************/
+#define RE_SYNTAX_AWK ( RE_NO_BK_PARENS | RE_NO_BK_VBAR | RE_CONTEXT_INDEP_OPS )
+#define RE_SYNTAX_EGREP ( RE_SYNTAX_AWK | RE_NEWLINE_OR )
+#define RE_SYNTAX_GREP ( RE_BK_PLUS_QM | RE_NEWLINE_OR )
+#define RE_SYNTAX_EMACS 0
+/******************************************************************************/
+/* This data structure is used to represent a compiled pattern. */
+/******************************************************************************/
+typedef struct re_pattern_buffer {
+
+ _TCHAR* buffer; /* Space holding the compiled pattern commands. */
+ int allocated; /* Size of space that buffer points to */
+ int used; /* Length of portion of buffer actually occupied */
+ _TCHAR* fastmap; /* Pointer to fastmap, if any, or zero if none. */
+ /* re_search uses the fastmap, if there is one, */
+ /* to skip quickly over totally implausible characters */
+ _TCHAR* translate; /* Translate table to apply to all characters before */
+ /* comparing. Or zero for no translation. The translation */
+ /* is applied to a pattern when it is compiled and to */
+ /* data when it is matched. */
+ _TCHAR fastmap_accurate; /* Set to zero when a new pattern is stored, */
+ /* set to one when the fastmap is updated from it. */
+ _TCHAR can_be_null; /* Set to one by compiling fastmap */
+ /* if this pattern might match the null string. */
+ /* It does not necessarily match the null string */
+ /* in that case, but if this is zero, it cannot. */
+ /* 2 as value means can match null string */
+ /* but at end of range or before a character */
+ /* listed in the fastmap. */
+
+} RE_PATTERN_BUFFER, *PRE_PATTERN_BUFFER;
+/******************************************************************************/
+/* Structure to store "register" contents data in. */
+/* Pass the address of such a structure as an argument to re_match, etc., */
+/* if you want this information back. */
+/* */
+/* start[i] and end[i] record the string matched by \( ... \) grouping i, */
+/* for i from 1 to RE_NREGS - 1. */
+/* start[0] and end[0] record the entire string matched. */
+/******************************************************************************/
+typedef struct re_registers {
+
+ int start[ RE_NREGS ];
+ int end[ RE_NREGS ];
+
+} RE_REGISTERS, *PRE_REGISTERS;
+/******************************************************************************/
+/* These are the command codes that appear in compiled regular expressions, */
+/* one per byte. Some command codes are followed by argument bytes. */
+/* A command code can specify any interpretation whatever for its arguments. */
+/* Zero-bytes may appear in the compiled regular expression. */
+/******************************************************************************/
+enum regexpcode {
+
+ unused,
+ exactn, /* followed by one byte giving n, and then by n literal bytes */
+ begline, /* fails unless at beginning of line */
+ endline, /* fails unless at end of line */
+ jump, /* followed by two bytes giving relative address to jump to */
+ on_failure_jump, /* followed by two bytes giving relative address of place */
+ /* to resume at in case of failure. */
+ finalize_jump, /* Throw away latest failure point and then jump to address. */
+ maybe_finalize_jump, /* Like jump but finalize if safe to do so. */
+ /* This is used to jump back to the beginning */
+ /* of a repeat. If the command that follows */
+ /* this jump is clearly incompatible with the */
+ /* one at the beginning of the repeat, such that */
+ /* we can be sure that there is no use backtracking */
+ /* out of repetitions already completed, */
+ /* then we finalize. */
+ dummy_failure_jump, /* jump, and push a dummy failure point. */
+ /* This failure point will be thrown away */
+ /* if an attempt is made to use it for a failure. */
+ /* A + construct makes this before the first repeat. */
+ anychar, /* matches any one character */
+ charset, /* matches any one char belonging to specified set. */
+ /* First following byte is # bitmap bytes. */
+ /* Then come bytes for a bit-map saying which chars */
+ /* are in. */
+ /* Bits in each byte are ordered low-bit-first. */
+ /* A character is in the set if its bit is 1. */
+ /* A character too large to have a bit in the map */
+ /* is automatically not in the set */
+ charset_not, /* similar but match any character that is NOT one of */
+ /* those specified */
+ start_memory, /* starts remembering the text that is matched */
+ /* and stores it in a memory register. */
+ /* followed by one byte containing the register number. */
+ /* Register numbers must be in the range 0 through */
+ /* NREGS. */
+ stop_memory, /* stops remembering the text that is matched */
+ /* and stores it in a memory register. */
+ /* followed by one byte containing the register number. */
+ /* Register numbers must be in the range 0 through */
+ /* NREGS. */
+ duplicate, /* match a duplicate of something remembered. */
+ /* Followed by one byte containing the index of the */
+ /* memory register. */
+ before_dot, /* Succeeds if before dot */
+ at_dot, /* Succeeds if at dot */
+ after_dot, /* Succeeds if after dot */
+ begbuf, /* Succeeds if at beginning of buffer */
+ endbuf, /* Succeeds if at end of buffer */
+ wordchar, /* Matches any word-constituent character */
+ notwordchar, /* Matches any char that is not a word-constituent */
+ wordbeg, /* Succeeds if at word beginning */
+ wordend, /* Succeeds if at word end */
+ wordbound, /* Succeeds if at a word boundary */
+ notwordbound, /* Succeeds if not at a word boundary */
+ syntaxspec, /* Matches any character whose syntax is specified. */
+ /* followed by a byte which contains a syntax code, */
+ /* Sword or such like */
+ notsyntaxspec /* Matches any character whose syntax differs from the */
+ /* specified. */
+
+};
+/******************************************************************************/
+/* Function prototypes */
+/******************************************************************************/
+/***/
+# ifdef __cplusplus
+extern "C" {
+# endif /* __cplusplus */
+/***/
+REGEXP_API _TCHAR* re_compile_pattern ( _TCHAR*, int, PRE_PATTERN_BUFFER );
+REGEXP_API void re_compile_fastmap ( PRE_PATTERN_BUFFER );
+REGEXP_API int re_search (
+ PRE_PATTERN_BUFFER, _TCHAR*, int, int, int, PRE_REGISTERS
+ );
+REGEXP_API int re_search_2 (
+ PRE_PATTERN_BUFFER, _TCHAR*, int,_TCHAR*, int, int, int,
+ PRE_REGISTERS, int
+ );
+REGEXP_API int re_match (
+ PRE_PATTERN_BUFFER, _TCHAR*, int, int, PRE_REGISTERS
+ );
+REGEXP_API int re_match_2 (
+ PRE_PATTERN_BUFFER, _TUCHAR*, int, _TUCHAR*, int,
+ int, PRE_REGISTERS, int
+ );
+REGEXP_API int re_set_syntax ( int );
+/***/
+# ifdef __cplusplus
+}
+# endif /* __cplusplus */
+/***/
+/******************************************************************************/
+#endif /* __REGEXP_H */
--- /dev/null
+/******************************************************************************/
+/* Extended regular expression matching and search. */
+/* Copyright (C) 1985 Free Software Foundation, Inc. */
+/* */
+/* This program is free software; you can redistribute it and/or modify */
+/* it under the terms of the GNU General Public License as published by */
+/* the Free Software Foundation; either version 1, or (at your option) */
+/* any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+/* */
+/* In other words, you are welcome to use, share and improve this program. */
+/* You are forbidden to forbid anyone else to use, share and improve */
+/* what you give them. Help stamp out software-hoarding! */
+/******************************************************************************/
+/******************************************************************************/
+/* Modified by EUG ( MATRA Datavision ) for Windows NT and UNICODE ( 1996 ) */
+/******************************************************************************/
+/***/
+
+/* JGA : to compile on Solaris */
+
+#if !defined(HPUX) && !defined (WNT)
+#include <alloca.h>
+
+#else
+/* alloca() non disponible sur HPUX 9.07 */
+# ifdef __cplusplus
+extern "C" {
+# endif
+void *alloca(unsigned int);
+# ifdef __cplusplus
+}
+#endif
+void *alloca(unsigned int size){return (void *)0L;}
+#endif
+
+
+#include <WOKUnix_regexp.h>
+
+/***/
+/******************************************************************************/
+/* */
+/* Define the syntax stuff, so we can do the \<...\> things. */
+/* */
+/******************************************************************************/
+/***/
+#ifndef Sword /* must be non-zero in some of the tests below... */
+# define Sword 1
+#endif /* Sword */
+
+#define SYNTAX( c ) re_syntax_table[ ( c ) ]
+
+TCHAR* re_syntax_table;
+/***/
+/******************************************************************************/
+/* */
+/* Number of failure points to allocate space for initially, */
+/* when matching. If this number is exceeded, more space is allocated, */
+/* so it is not a hard limit. */
+/* */
+/******************************************************************************/
+/***/
+#ifndef NFAILURES
+# define NFAILURES 80
+#endif /* NFAILURES */
+/***/
+#ifndef SIGN_EXTEND_CHAR
+# define SIGN_EXTEND_CHAR( x ) ( x )
+#endif /* SIGN_EXTEND_CHAR */
+/***/
+static int obscure_syntax;
+/***/
+/******************************************************************************/
+/* */
+/* Specify the precise syntax of regexp for compilation. */
+/* This provides for compatibility for various utilities */
+/* which historically have different, incompatible syntaxes. */
+/* */
+/* The argument SYNTAX is a bit-mask containing the two bits */
+/* RE_NO_BK_PARENS and RE_NO_BK_VBAR. */
+/* */
+/******************************************************************************/
+/***/
+int re_set_syntax ( int syntax ) {
+
+ int ret;
+
+ ret = obscure_syntax;
+ obscure_syntax = syntax;
+
+ return ret;
+
+} /* end re_set_syntax */
+/***/
+/******************************************************************************/
+/* */
+/* re_compile_pattern takes a regular-expression string */
+/* and converts it into a buffer full of byte commands for matching. */
+/* */
+/* PATTERN is the address of the pattern string */
+/* SIZE is the length of it. */
+/* BUFP is a struct re_pattern_buffer * which points to the info */
+/* on where to store the byte commands. */
+/* This structure contains a char * which points to the */
+/* actual space, which should have been obtained with malloc. */
+/* re_compile_pattern may use realloc to grow the buffer space. */
+/* */
+/* The number of bytes of commands can be found out by looking in */
+/* the struct re_pattern_buffer that bufp pointed to, */
+/* after re_compile_pattern returns. */
+/* */
+/******************************************************************************/
+/***/
+#define PATPUSH( ch ) ( *b++ = ( _TCHAR )( ch ) )
+
+#define PATFETCH( c ) { if ( p == pend ) goto end_of_pattern; \
+ ( c ) = *( _TUCHAR* )p++; \
+ if ( translate ) ( c ) = translate[ ( c ) ]; \
+ }
+
+#define PATFETCH_RAW( c ) { if ( p == pend ) goto end_of_pattern; \
+ ( c ) = *( _TUCHAR* )p++; \
+ }
+
+#define PATUNFETCH p--
+
+#define EXTEND_BUFFER { _TCHAR* old_buffer = bufp -> buffer; \
+ if ( bufp -> allocated == ( 1 << 16 ) ) \
+ goto too_big; \
+ bufp -> allocated *= 2; \
+ if ( bufp -> allocated > ( 1 << 16 ) ) \
+ bufp -> allocated = ( 1 << 16 ); \
+ if ( !( bufp -> buffer = \
+ ( _TCHAR* )realloc ( \
+ bufp -> buffer, \
+ bufp -> allocated \
+ ) \
+ ) \
+ ) goto memory_exhausted; \
+ c = bufp -> buffer - old_buffer; \
+ b += c; \
+ if ( fixup_jump ) fixup_jump += c; \
+ if ( laststart ) laststart += c; \
+ begalt += c; \
+ if ( pending_exact ) \
+ pending_exact += ( long )c; \
+ }
+
+static void store_jump ( _TCHAR*, _TCHAR, _TCHAR* );
+static void insert_jump ( _TCHAR, _TCHAR*, _TCHAR*, _TCHAR* );
+
+_TCHAR* re_compile_pattern (
+ _TCHAR* pattern, int size, PRE_PATTERN_BUFFER bufp
+ ) {
+
+ _TCHAR* b = bufp -> buffer;
+ _TCHAR* p = pattern;
+ _TCHAR* pend = pattern + size;
+ _TCHAR* p1;
+ _TUCHAR* translate = ( _TUCHAR* )bufp -> translate;
+
+ unsigned long c, c1;
+
+/* address of the count-byte of the most recently inserted "exactn" command. */
+/* This makes it possible to tell whether a new exact-match character */
+/* can be added to that command or requires a new "exactn" command. */
+
+ _TCHAR* pending_exact = NULL;
+
+/* address of the place where a forward-jump should go */
+/* to the end of the containing expression. */
+/* Each alternative of an "or", except the last, ends with a forward-jump */
+/* of this sort. */
+
+ _TCHAR* fixup_jump = NULL;
+
+/* address of start of the most recently finished expression. */
+/* This tells postfix * where to find the start of its operand. */
+
+ _TCHAR* laststart = NULL;
+
+/* In processing a repeat, 1 means zero matches is allowed */
+
+ _TCHAR zero_times_ok;
+
+/* In processing a repeat, 1 means many matches is allowed */
+
+ _TCHAR many_times_ok;
+
+/* address of beginning of regexp, or inside of last \( */
+
+ _TCHAR* begalt = b;
+
+/* Stack of information saved by \( and restored by \). */
+/* Four stack elements are pushed by each \(: */
+/* First, the value of b. */
+/* Second, the value of fixup_jump. */
+/* Third, the value of regnum. */
+/* Fourth, the value of begalt. */
+
+ long stackb[ 40 ];
+ long* stackp = stackb;
+ long* stacke = stackb + 40;
+ long* stackt;
+
+/* Counts \('s as they are encountered. Remembered for the matching \), */
+/* where it becomes the "register number" to put in the stop_memory command */
+
+ int regnum = 1;
+
+ bufp -> fastmap_accurate = 0;
+
+ if ( bufp -> allocated == 0 ) {
+
+ bufp -> allocated = 28;
+
+ if ( bufp -> buffer )
+ /* EXTEND_BUFFER loses when bufp->allocated is 0 */
+ bufp -> buffer = ( _TCHAR* )realloc ( bufp -> buffer, 28 * sizeof ( _TCHAR ) );
+
+ else
+ /* Caller did not allocate a buffer. Do it for him */
+ bufp -> buffer = ( _TCHAR* ) malloc ( 28 * sizeof ( _TCHAR ) );
+
+ if ( !bufp -> buffer ) goto memory_exhausted;
+
+ begalt = b = bufp -> buffer;
+
+ } /* end if */
+
+ while ( p != pend ) {
+
+ if ( ( int )( b - bufp -> buffer ) >
+ ( int )( bufp -> allocated - 10 * sizeof ( _TCHAR ) )
+ )
+
+ EXTEND_BUFFER; /* Note that EXTEND_BUFFER clobbers c */
+
+ PATFETCH( c );
+
+ switch ( c ) {
+
+ case _TEXT( '$' ):
+
+ if ( obscure_syntax & RE_TIGHT_VBAR ) {
+
+ if ( !( obscure_syntax & RE_CONTEXT_INDEP_OPS ) && p != pend ) goto normal_char;
+ /* Make operand of last vbar end before this `$'. */
+ if ( fixup_jump ) store_jump ( fixup_jump, jump, b );
+
+ fixup_jump = NULL;
+ PATPUSH( endline );
+
+ break;
+
+ } /* end if */
+
+ /* $ means succeed if at end of line, but only in special contexts. */
+ /* If randomly in the middle of a pattern, it is a normal character. */
+ if ( p == pend ||
+ *p == _TEXT( '\n' ) ||
+ ( obscure_syntax & RE_CONTEXT_INDEP_OPS ) ||
+ ( obscure_syntax & RE_NO_BK_PARENS ?
+ *p == _TEXT( ')' ) :
+ *p == _TEXT( '\\' ) &&
+ p[ 1 ] == _TEXT( ')' )
+ ) ||
+ ( obscure_syntax & RE_NO_BK_VBAR ?
+ *p == _TEXT( '|' ) :
+ *p == _TEXT( '\\' ) &&
+ p[ 1 ] == _TEXT( '|' )
+ )
+ ) {
+
+ PATPUSH( endline );
+
+ break;
+
+ } /* end if */
+
+ goto normal_char;
+
+ case _TEXT( '^' ):
+ /* ^ means succeed if at beg of line, but only if no preceding pattern. */
+
+ if ( laststart && p[ -2 ] != _TEXT( '\n' ) &&
+ !( obscure_syntax & RE_CONTEXT_INDEP_OPS )
+ ) goto normal_char;
+
+ if ( obscure_syntax & RE_TIGHT_VBAR ) {
+
+ if ( p != pattern + 1 &&
+ !( obscure_syntax & RE_CONTEXT_INDEP_OPS )
+ ) goto normal_char;
+
+ PATPUSH( begline );
+ begalt = b;
+
+
+ } else PATPUSH( begline );
+
+ break;
+
+ case _TEXT( '+' ):
+ case _TEXT( '?' ):
+
+ if ( obscure_syntax & RE_BK_PLUS_QM ) goto normal_char;
+
+handle_plus:
+
+ case _TEXT( '*' ):
+ /* If there is no previous pattern, char not special. */
+
+ if ( !laststart && !( obscure_syntax & RE_CONTEXT_INDEP_OPS ) ) goto normal_char;
+
+ /* If there is a sequence of repetition chars, */
+ /* collapse it down to equivalent to just one. */
+ zero_times_ok = 0;
+ many_times_ok = 0;
+
+ while ( 1 ) {
+
+ zero_times_ok |= c != _TEXT( '+' );
+ many_times_ok |= c != _TEXT( '?' );
+
+ if ( p == pend ) break;
+
+ PATFETCH( c );
+
+ if ( c == _TEXT( '*' ) )
+ ;
+ else if ( !( obscure_syntax & RE_BK_PLUS_QM ) &&
+ ( c == _TEXT( '+' ) || c == _TEXT( '?' ) )
+ );
+ else if ( ( obscure_syntax & RE_BK_PLUS_QM ) && c == _TEXT( '\\' ) ) {
+
+ long c1;
+
+ PATFETCH( c1 );
+
+ if ( !( c1 == _TEXT( '+' ) || c1 == _TEXT( '?' ) ) ) {
+
+ PATUNFETCH;
+ PATUNFETCH;
+
+ break;
+
+ } /* end if */
+
+ c = c1;
+
+ } else {
+
+ PATUNFETCH;
+
+ break;
+
+ } /* end else */
+
+ } /* end while */
+
+ /* Star, etc. applied to an empty pattern is equivalent */
+ /* to an empty pattern. */
+
+ if ( !laststart ) break;
+
+ /* Now we know whether 0 matches is allowed, */
+ /* and whether 2 or more matches is allowed. */
+
+ if ( many_times_ok ) {
+ /* If more than one repetition is allowed, */
+ /* put in a backward jump at the end. */
+
+ store_jump ( b, maybe_finalize_jump, laststart - 3L );
+ b += 3;
+
+ } /* end if */
+
+ insert_jump ( on_failure_jump, laststart, b + 3, b );
+ pending_exact = NULL;
+ b += 3;
+
+ if ( !zero_times_ok ) {
+ /* At least one repetition required: insert before the loop */
+ /* a skip over the initial on-failure-jump instruction */
+
+ insert_jump ( dummy_failure_jump, laststart, laststart + 6L, b );
+ b += 3;
+
+ } /* end if */
+
+ break;
+
+ case _TEXT( '.' ):
+
+ laststart = b;
+ PATPUSH( anychar );
+
+ break;
+
+ case _TEXT( '[' ):
+
+ while ( b - bufp -> buffer >
+ ( int )( bufp->allocated - 3 - ( 1 << BYTEWIDTH ) / BYTEWIDTH )
+ ) /* Note that EXTEND_BUFFER clobbers c */ EXTEND_BUFFER;
+
+ laststart = b;
+
+ if ( *p == _TEXT( '^' ) )
+
+ PATPUSH( charset_not ), p++;
+
+ else
+
+ PATPUSH( charset );
+
+ p1 = p;
+ PATPUSH( ( 1 << BYTEWIDTH ) / BYTEWIDTH );
+ /* Clear the whole map */
+ memset ( b, 0, ( 1 << BYTEWIDTH ) / BYTEWIDTH * sizeof ( TCHAR ) );
+
+ /* Read in characters and ranges, setting map bits */
+ while ( 1 ) {
+
+ PATFETCH( c );
+
+ if ( c == _TEXT( ']' ) && p != p1 + 1 ) break;
+
+ if ( *p == _TEXT( '-' ) && p[ 1 ] != _TEXT( ']' ) ) {
+
+ PATFETCH( c1 );
+ PATFETCH( c1 );
+
+ if ( translate )
+
+ while ( c <= c1 ) {
+
+ _TUCHAR mapped_c = translate[ c ];
+ b[ mapped_c / BYTEWIDTH ] |= 1 << ( mapped_c % BYTEWIDTH );
+ ++c;
+
+ } /* end while */
+
+ else
+
+ while ( c <= c1 ) b[ c / BYTEWIDTH ] |= 1 << ( c % BYTEWIDTH ), c++;
+
+ } else {
+
+ if ( translate ) c = translate[ c ];
+
+ b[ c / BYTEWIDTH ] |= 1 << ( c % BYTEWIDTH );
+
+ } /* end else */
+
+ } /* end while */
+
+ /* Discard any bitmap bytes that are all 0 at the end of the map. */
+ /* Decrement the map-length byte too. */
+ while ( ( int )b[ -1 ] > 0 && b[ b[ -1 ] - 1 ] == 0 ) b[ -1 ]--;
+
+ b += b[ -1 ];
+
+ break;
+
+ case _TEXT( '(' ):
+
+ if ( !( obscure_syntax & RE_NO_BK_PARENS ) )
+ goto normal_char;
+ else
+ goto handle_open;
+
+ case _TEXT( ')' ):
+ if ( !( obscure_syntax & RE_NO_BK_PARENS ) )
+ goto normal_char;
+ else
+ goto handle_close;
+
+ case '\n':
+ if ( !( obscure_syntax & RE_NEWLINE_OR ) )
+ goto normal_char;
+ else
+ goto handle_bar;
+
+ case _TEXT( '|' ):
+ if ( !( obscure_syntax & RE_NO_BK_VBAR ) )
+ goto normal_char;
+ else
+ goto handle_bar;
+
+ case _TEXT( '\\' ):
+
+ if ( p == pend ) goto invalid_pattern;
+
+ PATFETCH_RAW( c );
+
+ switch ( c ) {
+
+ case _TEXT( '(' ):
+
+ if ( obscure_syntax & RE_NO_BK_PARENS ) goto normal_backsl;
+
+handle_open:
+
+ if ( stackp == stacke ) goto nesting_too_deep;
+
+ if ( regnum < RE_NREGS ) {
+
+ PATPUSH( start_memory );
+ PATPUSH( regnum );
+
+ } /* end if */
+
+ *stackp++ = b - bufp -> buffer;
+ *stackp++ = fixup_jump ? fixup_jump - bufp -> buffer + 1L : 0L;
+ *stackp++ = regnum++;
+ *stackp++ = begalt - bufp -> buffer;
+ fixup_jump = NULL;
+ laststart = NULL;
+ begalt = b;
+
+ break;
+
+ case _TEXT( ')' ):
+
+ if ( obscure_syntax & RE_NO_BK_PARENS ) goto normal_backsl;
+
+handle_close:
+
+ if ( stackp == stackb ) goto unmatched_close;
+
+ begalt = *--stackp + bufp -> buffer;
+
+ if ( fixup_jump ) store_jump ( fixup_jump, jump, b );
+
+ if ( stackp[ -1 ] < RE_NREGS ) {
+
+ PATPUSH( stop_memory );
+ PATPUSH( stackp[ -1 ] );
+
+ } /* end if */
+
+ stackp -= 2;
+ fixup_jump = NULL;
+
+ if ( *stackp ) fixup_jump = *stackp + bufp -> buffer - 1L;
+
+ laststart = *--stackp + bufp -> buffer;
+
+ break;
+
+ case _TEXT( '|' ):
+
+ if ( obscure_syntax & RE_NO_BK_VBAR ) goto normal_backsl;
+
+handle_bar:
+
+ insert_jump ( on_failure_jump, begalt, b + 6, b );
+ pending_exact = NULL;
+ b += 3;
+
+ if ( fixup_jump ) store_jump ( fixup_jump, jump, b );
+
+ fixup_jump = b;
+ b += 3;
+ laststart = 0;
+ begalt = b;
+
+ break;
+
+ case _TEXT( 'w' ):
+
+ laststart = b;
+ PATPUSH( wordchar );
+
+ break;
+
+ case _TEXT( 'W' ):
+
+ laststart = b;
+ PATPUSH( notwordchar );
+
+ break;
+
+ case _TEXT( '<' ):
+
+ PATPUSH( wordbeg );
+
+ break;
+
+ case _TEXT( '>' ):
+
+ PATPUSH( wordend );
+
+ break;
+
+ case _TEXT( 'b' ):
+
+ PATPUSH( wordbound );
+
+ break;
+
+ case _TEXT( 'B' ):
+
+ PATPUSH( notwordbound );
+
+ break;
+
+ case _TEXT( '`' ):
+
+ PATPUSH( begbuf );
+
+ break;
+
+ case _TEXT( '\'' ):
+
+ PATPUSH( endbuf );
+
+ break;
+
+ case _TEXT( '1' ):
+ case _TEXT( '2' ):
+ case _TEXT( '3' ):
+ case _TEXT( '4' ):
+ case _TEXT( '5' ):
+ case _TEXT( '6' ):
+ case _TEXT( '7' ):
+ case _TEXT( '8' ):
+ case _TEXT( '9' ):
+
+ c1 = c - _TEXT( '0' );
+
+ if ( ( int )c1 >= regnum ) goto normal_char;
+
+ for ( stackt = stackp - 2; stackt > stackb; stackt -= 4 )
+
+ if ( *stackt == ( long )c1 ) goto normal_char;
+
+ laststart = b;
+ PATPUSH( duplicate );
+ PATPUSH( c1 );
+
+ break;
+
+ case _TEXT( '+' ):
+ case _TEXT( '?' ):
+
+ if ( obscure_syntax & RE_BK_PLUS_QM ) goto handle_plus;
+
+ default:
+
+normal_backsl:
+
+ /* You might think it would be useful for \ to mean */
+ /* not to translate; but if we don't translate it */
+ /* it will never match anything. */
+ if ( translate ) c = translate[ c ];
+
+ goto normal_char;
+
+ } /* end switch */
+
+ break;
+
+ default:
+
+normal_char:
+
+ if ( !pending_exact ||
+ pending_exact + *pending_exact + 1L != b ||
+ *pending_exact == 0177 ||
+ *p == _TEXT( '*' ) ||
+ *p == _TEXT( '^' ) ||
+ ( ( obscure_syntax & RE_BK_PLUS_QM ) ?
+ *p == _TEXT( '\\' ) &&
+ ( p[ 1 ] == _TEXT( '+' ) ||
+ p[ 1] == _TEXT( '?' )
+ ) :
+ ( *p == _TEXT( '+' ) ||
+ *p == _TEXT( '?' )
+ )
+ )
+ ) {
+
+ laststart = b;
+ PATPUSH( exactn );
+ pending_exact = b;
+ PATPUSH( 0 );
+
+ } /* end if */
+
+ PATPUSH( c );
+ ( *pending_exact )++;
+
+ } /* end switch */
+
+ } /* end while */
+
+ if ( fixup_jump ) store_jump ( fixup_jump, jump, b );
+
+ if ( stackp != stackb ) goto unmatched_open;
+
+ bufp -> used = b - bufp -> buffer;
+
+ return NULL;
+
+invalid_pattern: return _TEXT( "invalid regular expression" );
+
+unmatched_open: return _TEXT( "unmatched \\(" );
+
+unmatched_close: return _TEXT( "unmatched \\)" );
+
+end_of_pattern: return _TEXT( "premature end of regular expression" );
+
+nesting_too_deep: return _TEXT( "nesting too deep" );
+
+too_big: return _TEXT( "regular expression too big" );
+
+memory_exhausted: return _TEXT( "Memory exhausted" );
+
+} /* end re_compile_pattern */
+/***/
+/******************************************************************************/
+/* */
+/* Store where `from' points a jump operation to jump to where `to' points. */
+/* `opcode' is the opcode to store. */
+/* */
+/******************************************************************************/
+/***/
+static void store_jump ( _TCHAR* from, _TCHAR opcode, _TCHAR* to ) {
+
+ from[ 0 ] = opcode;
+ from[ 1 ] = ( to - ( from + 3 ) ) & CHAR_MASK;
+ from[ 2 ] = ( to - ( from + 3 ) ) >> BYTEWIDTH;
+
+} /* end store_jump */
+/***/
+/******************************************************************************/
+/* */
+/* Open up space at char FROM, and insert there a jump to TO. */
+/* CURRENT_END gives te end of the storage no in use, */
+/* so we know how much data to copy up. */
+/* OP is the opcode of the jump to insert. */
+/* */
+/* If you call this function, you must zero out pending_exact. */
+/* */
+/******************************************************************************/
+/***/
+static void insert_jump (
+ _TCHAR op, _TCHAR* from, _TCHAR* to, _TCHAR* current_end
+ ) {
+
+ _TCHAR* pto = current_end + 3;
+ _TCHAR* pfrom = current_end;
+
+ while ( pfrom != from ) *--pto = *--pfrom;
+
+ store_jump ( from, op, to );
+
+} /* end insert_jump */
+/***/
+/******************************************************************************/
+/* */
+/* Given a pattern, compute a fastmap from it. */
+/* The fastmap records which of the (1 << BYTEWIDTH) possible characters */
+/* can start a string that matches the pattern. */
+/* This fastmap is used by re_search to skip quickly over totally implausible */
+/* text. */
+/* The caller must supply the address of a (1 << BYTEWIDTH)-byte data area */
+/* as bufp->fastmap. */
+/* The other components of bufp describe the pattern to be used. */
+/* */
+/******************************************************************************/
+/***/
+void re_compile_fastmap ( PRE_PATTERN_BUFFER bufp ) {
+
+ int j, size = bufp -> used;
+
+ _TUCHAR* pattern = (_TUCHAR* )bufp -> buffer;
+ _TUCHAR* p = pattern;
+ _TUCHAR* pend = pattern + size;
+ _TUCHAR* translate = (_TUCHAR* )bufp -> translate;
+ _TCHAR* fastmap = bufp -> fastmap;
+ _TUCHAR* stackb[ NFAILURES ];
+ _TUCHAR** stackp = stackb;
+
+ memset ( fastmap, 0, ( 1 << BYTEWIDTH ) * sizeof ( TCHAR ) );
+ bufp -> fastmap_accurate = 1;
+ bufp -> can_be_null = 0;
+
+ while ( p ) {
+
+ if ( p == pend ) {
+
+ bufp -> can_be_null = 1;
+
+ break;
+
+ } /* end if */
+
+ switch ( ( enum regexpcode )*p++ ) {
+
+ case exactn:
+
+ if ( translate )
+ fastmap[ translate[ p[ 1 ] ] ] = 1;
+ else
+ fastmap[ p[ 1 ] ] = 1;
+
+ break;
+
+ case begline:
+ case before_dot:
+ case at_dot:
+ case after_dot:
+ case begbuf:
+ case endbuf:
+ case wordbound:
+ case notwordbound:
+ case wordbeg:
+ case wordend:
+
+ continue;
+
+ case endline:
+
+ if ( translate )
+ fastmap[ translate[ _TEXT( '\n' ) ] ] = 1;
+ else
+ fastmap[ _TEXT( '\n' ) ] = 1;
+
+ if ( bufp -> can_be_null != 1 )
+ bufp -> can_be_null = 2;
+
+ break;
+
+ case finalize_jump:
+ case maybe_finalize_jump:
+ case jump:
+ case dummy_failure_jump:
+
+ bufp -> can_be_null = 1;
+ j = *p++ & CHAR_MASK;
+ j += SIGN_EXTEND_CHAR( *( char* )p ) << BYTEWIDTH;
+ p += j + 1; /* The 1 compensates for missing ++ above */
+
+ if ( j > 0 ) continue;
+
+ /* Jump backward reached implies we just went through */
+ /* the body of a loop and matched nothing. */
+ /* Opcode jumped to should be an on_failure_jump. */
+ /* Just treat it like an ordinary jump. */
+ /* For a * loop, it has pushed its failure point already; */
+ /* if so, discard that as redundant. */
+ if ( ( enum regexpcode )*p != on_failure_jump ) continue;
+
+ ++p;
+ j = *p++ & CHAR_MASK;
+ j += SIGN_EXTEND_CHAR( *( char* )p ) << BYTEWIDTH;
+ p += j + 1; /* The 1 compensates for missing ++ above */
+
+ if ( stackp != stackb && *stackp == p ) stackp--;
+
+ continue;
+
+ case on_failure_jump:
+
+ j = *p++ & CHAR_MASK;
+ j += SIGN_EXTEND_CHAR( *( char* )p ) << BYTEWIDTH;
+ p++;
+ *++stackp = p + j;
+
+ continue;
+
+ case start_memory:
+ case stop_memory:
+
+ ++p;
+
+ continue;
+
+ case duplicate:
+
+ bufp -> can_be_null = 1;
+ fastmap[ _TEXT( '\n' )] = 1;
+
+ case anychar:
+
+ for ( j = 0; j < ( 1 << BYTEWIDTH ); j++ )
+
+ if ( j != _TEXT( '\n' ) ) fastmap[ j ] = 1;
+
+ if ( bufp -> can_be_null ) return;
+
+ /* Don't return; check the alternative paths */
+ /* so we can set can_be_null if appropriate. */
+ break;
+
+ case wordchar:
+
+ for ( j = 0; j < ( 1 << BYTEWIDTH ); j++ )
+
+ if ( SYNTAX( j ) == Sword ) fastmap[ j ] = 1;
+
+ break;
+
+ case notwordchar:
+
+ for ( j = 0; j < ( 1 << BYTEWIDTH ); j++ )
+
+ if ( SYNTAX( j ) != Sword ) fastmap[ j ] = 1;
+
+ break;
+
+ case charset:
+
+ for ( j = *p++ * BYTEWIDTH - 1; j >= 0; j-- )
+
+ if ( p[ j / BYTEWIDTH ] & ( 1 << ( j % BYTEWIDTH ) ) ) {
+
+ if ( translate )
+ fastmap[ translate[ j ] ] = 1;
+ else
+ fastmap[ j ] = 1;
+
+ } /* end if */
+
+ break;
+
+ case charset_not:
+ /* Chars beyond end of map must be allowed */
+ for ( j = *p * BYTEWIDTH; j < ( 1 << BYTEWIDTH ); j++ )
+
+ if ( translate )
+ fastmap[ translate[ j ] ] = 1;
+ else
+ fastmap[ j ] = 1;
+
+ for ( j = *p++ * BYTEWIDTH - 1; j >= 0; j-- )
+
+ if ( !( p[ j / BYTEWIDTH ] & ( 1 << ( j % BYTEWIDTH ) ) ) ) {
+
+ if ( translate )
+ fastmap[ translate[ j ] ] = 1;
+ else
+ fastmap[ j ] = 1;
+
+ } /* end if */
+
+ break;
+
+ } /* end switch */
+
+ /* Get here means we have successfully found the possible starting */
+ /* characters of one path of the pattern. We need not follow this */
+ /* path any farther. Instead, look at the next alternative remembered */
+ /* in the stack. */
+ if ( stackp != stackb )
+ p = *stackp--;
+ else
+ break;
+
+ } /* end while */
+
+} /* end re_compile_fastmap */
+/***/
+/******************************************************************************/
+/* */
+/* Like re_search_2, below, but only one string is specified. */
+/* */
+/******************************************************************************/
+/***/
+int re_search (
+ PRE_PATTERN_BUFFER pbufp, _TCHAR* string, int size, int startpos,
+ int range, PRE_REGISTERS regs
+ ) {
+
+ return re_search_2 (
+ pbufp, NULL, 0, string, size, startpos, range, regs, size
+ );
+
+} /* end re_search */
+/***/
+/******************************************************************************/
+/* */
+/* Like re_match_2 but tries first a match starting at index STARTPOS, */
+/* then at STARTPOS + 1, and so on. */
+/* RANGE is the number of places to try before giving up. */
+/* If RANGE is negative, the starting positions tried are */
+/* STARTPOS, STARTPOS - 1, etc. */
+/* It is up to the caller to make sure that range is not so large */
+/* as to take the starting position outside of the input strings. */
+/* */
+/* The value returned is the position at which the match was found, */
+/* or -1 if no match was found, */
+/* or -2 if error (such as failure stack overflow). */
+/* */
+/******************************************************************************/
+/***/
+int re_search_2 (
+ PRE_PATTERN_BUFFER pbufp,
+ _TCHAR* string1, int size1, _TCHAR* string2, int size2,
+ int startpos, int range, PRE_REGISTERS regs, int mstop
+ ) {
+
+ _TCHAR* fastmap = pbufp -> fastmap;
+ _TUCHAR* translate = (_TUCHAR* )pbufp -> translate;
+
+ int total = size1 + size2;
+ int val;
+
+ /* Update the fastmap now if not correct already */
+ if ( fastmap && !pbufp -> fastmap_accurate ) re_compile_fastmap ( pbufp );
+
+ /* Don't waste time in a long search for a pattern */
+ /* that says it is anchored. */
+ if ( pbufp -> used > 0 &&
+ ( enum regexpcode )pbufp -> buffer[ 0 ] == begbuf &&
+ range > 0
+ ) {
+
+ if ( startpos > 0 )
+ return -1;
+ else
+ range = 1;
+
+ } /* end if */
+
+ while ( 1 ) {
+
+ /* If a fastmap is supplied, skip quickly over characters */
+ /* that cannot possibly be the start of a match. */
+ /* Note, however, that if the pattern can possibly match */
+ /* the null string, we must test it at each starting point */
+ /* so that we take the first null string we get. */
+ if ( fastmap && startpos < total && pbufp -> can_be_null != 1 ) {
+
+ if ( range > 0 ) {
+
+ int lim = 0;
+ int irange = range;
+
+ _TUCHAR* p;
+
+ if ( startpos < size1 && startpos + range >= size1 )
+
+ lim = range - ( size1 - startpos );
+
+ p = ( ( _TUCHAR * )
+ &( startpos >= size1 ? string2 - size1 : string1 )[ startpos ]
+ );
+
+ if ( translate )
+
+ while ( range > lim && !fastmap[ translate[ *p++ ] ] ) range--;
+
+ else
+
+ while ( range > lim && !fastmap[ *p++ ] ) range--;
+
+ startpos += irange - range;
+
+ } else {
+
+ _TUCHAR c;
+
+ if ( startpos >= size1 )
+ c = string2[ startpos - size1 ];
+ else
+ c = string1[ startpos ];
+
+ c &= CHAR_MASK;
+
+ if ( translate ? !fastmap[ translate[ c ] ] : !fastmap[ c ] ) goto advance;
+
+ } /* end else */
+
+ } /* end if */
+
+ if ( range >= 0 &&
+ startpos == total &&
+ fastmap &&
+ pbufp -> can_be_null == 0
+ ) return -1;
+
+ val = re_match_2 ( pbufp, string1, size1, string2, size2, startpos, regs, mstop );
+
+ /* Propagate error indication if worse than mere failure. */
+ if ( val == -2 ) return -2;
+
+ /* Return position on success. */
+ if ( 0 <= val ) return startpos;
+
+advance:
+
+ if ( !range ) break;
+
+ if ( range > 0 )
+ range--, startpos++;
+ else
+ range++, startpos--;
+
+ } /* end while */
+
+ return -1;
+
+} /* end int re_search_2 */
+/***/
+/******************************************************************************/
+/* */
+/* */
+/******************************************************************************/
+/***/
+int re_match (
+ PRE_PATTERN_BUFFER pbufp, _TCHAR* string, int size, int pos,
+ PRE_REGISTERS regs
+ ) {
+
+ return re_match_2 ( pbufp, NULL, 0, string, size, pos, regs, size );
+
+} /* end re_match */
+/***/
+/******************************************************************************/
+/* */
+/* Maximum size of failure stack. Beyond this, overflow is an error. */
+/* */
+/******************************************************************************/
+/***/
+#define RE_MAX_FAILURES 65536
+/***/
+static int bcmp_translate();
+/***/
+/******************************************************************************/
+/* */
+/* Match the pattern described by PBUFP */
+/* against data which is the virtual concatenation of STRING1 and STRING2. */
+/* SIZE1 and SIZE2 are the sizes of the two data strings. */
+/* Start the match at position POS. */
+/* Do not consider matching past the position MSTOP. */
+/* */
+/* If pbufp->fastmap is nonzero, then it had better be up to date. */
+/* */
+/* The reason that the data to match are specified as two components */
+/* which are to be regarded as concatenated */
+/* is so this function can be used directly on the contents of an Emacs */
+/* buffer. */
+/* */
+/* -1 is returned if there is no match. -2 is returned if there is */
+/* an error (such as match stack overflow). Otherwise the value is the */
+/* length of the substring which was matched. */
+/* */
+/******************************************************************************/
+/***/
+int re_match_2 (
+ PRE_PATTERN_BUFFER pbufp,
+ _TUCHAR* string1, int size1, _TUCHAR* string2, int size2,
+ int pos, PRE_REGISTERS regs, int mstop
+ ) {
+
+ _TUCHAR* p = ( _TUCHAR* )pbufp -> buffer;
+ _TUCHAR* pend = p + pbufp -> used;
+ /* End of first string */
+ _TUCHAR* end1;
+ /* End of second string */
+ _TUCHAR* end2;
+ /* Pointer just past last char to consider matching */
+ _TUCHAR* end_match_1, *end_match_2;
+ _TUCHAR* d, *dend;
+ _TUCHAR* translate = ( _TUCHAR* ) pbufp -> translate;
+
+ int mcnt;
+
+ /* Failure point stack. Each place that can handle a failure */
+ /* further down the line pushes a failure point on this stack. */
+ /* It consists of two char *'s. */
+ /* The first one pushed is where to resume scanning the pattern; */
+ /* the second pushed is where to resume scanning the strings. */
+ /* If the latter is zero, the failure point is a "dummy". */
+ /* If a failure happens and the innermost failure point is dormant, */
+ /* it discards that failure point and tries the next one. */
+
+ _TUCHAR* initial_stack[ 2 * NFAILURES ];
+ _TUCHAR** stackb = initial_stack;
+ _TUCHAR** stackp = stackb, **stacke = &stackb[ 2 * NFAILURES ];
+
+ /* Information on the "contents" of registers. */
+ /* These are pointers into the input strings; they record */
+ /* just what was matched (on this attempt) by some part of the pattern. */
+ /* The start_memory command stores the start of a register's contents */
+ /* and the stop_memory command stores the end. */
+ /* */
+ /* At that point, regstart[regnum] points to the first character in */
+ /* the register, */
+ /* regend[regnum] points to the first character beyond the end of */
+ /* the register, */
+ /* regstart_seg1[regnum] is true iff regstart[regnum] points into string1, */
+ /* and regend_seg1[regnum] is true iff regend[regnum] points into string1. */
+
+ _TUCHAR* regstart[ RE_NREGS ];
+ _TUCHAR* regend[ RE_NREGS ];
+ _TUCHAR regstart_seg1[ RE_NREGS ], regend_seg1[ RE_NREGS ];
+
+ /* Set up pointers to ends of strings. */
+ /* Don't allow the second string to be empty unless both are empty. */
+ if ( !size2 ) {
+
+ string2 = string1;
+ size2 = size1;
+ string1 = NULL;
+ size1 = 0;
+
+ } /* end if */
+
+ end1 = string1 + size1;
+ end2 = string2 + size2;
+
+ /* Compute where to stop matching, within the two strings */
+ if ( mstop <= size1 ) {
+
+ end_match_1 = string1 + mstop;
+ end_match_2 = string2;
+
+ } else {
+
+ end_match_1 = end1;
+ end_match_2 = string2 + mstop - size1;
+
+ } /* end else */
+
+ /* Initialize \) text positions to -1 */
+ /* to mark ones that no \( or \) has been seen for. */
+
+ for ( mcnt = 0; mcnt < sizeof ( regend ) / sizeof( *regend ); mcnt++ )
+
+ regend[ mcnt ] = ( _TUCHAR* )-1;
+
+ /* `p' scans through the pattern as `d' scans through the data. */
+ /* `dend' is the end of the input string that `d' points within. */
+ /* `d' is advanced into the following input string whenever necessary, */
+ /* but this happens before fetching; */
+ /* therefore, at the beginning of the loop, */
+ /* `d' can be pointing at the end of a string, */
+ /* but it cannot equal string2. */
+ if ( pos <= size1 )
+ d = string1 + pos, dend = end_match_1;
+ else
+ d = string2 + pos - size1, dend = end_match_2;
+
+/* Write PREFETCH; just before fetching a character with *d. */
+#define PREFETCH while ( d == dend ) { \
+ if ( dend == end_match_2 ) goto fail; /* end of string2 => failure */ \
+ d = string2; /* end of string1 => advance to string2. */ \
+ dend = end_match_2; \
+ }
+
+ /* This loop loops over pattern commands. */
+ /* It exits by returning from the function if match is complete, */
+ /* or it drops through if match fails at this starting point in the input data. */
+ while ( 1 ) {
+
+ if (p == pend) { /* End of pattern means we have succeeded! */
+
+ if ( regs ) { /* If caller wants register contents data back, convert it to indices */
+
+ regs -> start[ 0 ] = pos;
+
+ if ( dend == end_match_1 )
+ regs -> end[ 0 ] = d - string1;
+ else
+ regs->end[ 0 ] = d - string2 + size1;
+
+ for ( mcnt = 1; mcnt < RE_NREGS; mcnt++ ) {
+
+ if ( regend[ mcnt ] == ( _TUCHAR* )-1 ) {
+
+ regs -> start[ mcnt ] = -1;
+ regs -> end[ mcnt ] = -1;
+
+ continue;
+
+ } /* end if */
+
+ if ( regstart_seg1[ mcnt ] )
+ regs -> start[ mcnt ] = regstart[ mcnt ] - string1;
+ else
+ regs -> start[ mcnt ] = regstart[ mcnt ] - string2 + size1;
+
+ if ( regend_seg1[ mcnt ] )
+ regs -> end[ mcnt ] = regend[ mcnt ] - string1;
+ else
+ regs -> end[ mcnt ] = regend[ mcnt ] - string2 + size1;
+
+ } /* end for */
+
+ } /* end if */
+
+ if ( dend == end_match_1 )
+ return ( d - string1 - pos );
+ else
+ return d - string2 + size1 - pos;
+
+ } /* end if */
+
+ /* Otherwise match next pattern command */
+ switch ( ( enum regexpcode )*p++ ) {
+
+ /* \( is represented by a start_memory, \) by a stop_memory. */
+ /* Both of those commands contain a "register number" argument. */
+ /* The text matched within the \( and \) is recorded under that number. */
+ /* Then, \<digit> turns into a `duplicate' command which */
+ /* is followed by the numeric value of <digit> as the register number. */
+ case start_memory:
+
+ regstart[ *p ] = d;
+ regstart_seg1[ *p++ ] = ( dend == end_match_1 );
+
+ break;
+
+ case stop_memory:
+
+ regend[ *p ] = d;
+ regend_seg1[ *p++ ] = ( dend == end_match_1 );
+
+ break;
+
+ case duplicate: {
+
+ int regno = *p++; /* Get which register to match against */
+ _TUCHAR *d2, *dend2;
+
+ /* Don't allow matching a register that hasn't been used. */
+ /* This isn't fully reliable in the current version, */
+ /* but it is better than crashing. */
+ if ( ( int )regend[ regno ] == -1 ) goto fail;
+
+ d2 = regstart[ regno ];
+ dend2 = ( ( regstart_seg1[ regno ] == regend_seg1[ regno] ) ?
+ regend[regno] :
+ end_match_1
+ );
+
+ while ( 1 ) {
+
+ /* Advance to next segment in register contents, if necessary */
+ while ( d2 == dend2 ) {
+
+ if ( dend2 == end_match_2 ) break;
+ if ( dend2 == regend[ regno ] ) break;
+
+ d2 = string2, dend2 = regend[ regno ]; /* end of string1 => advance to string2. */
+
+ } /* end while
+
+ /* At end of register contents => success */
+ if ( d2 == dend2 ) break;
+
+ /* Advance to next segment in data being matched, if necessary */
+ PREFETCH;
+
+ /* mcnt gets # consecutive chars to compare */
+ mcnt = dend - d;
+
+ if ( mcnt > dend2 - d2 ) mcnt = dend2 - d2;
+
+ /* Compare that many; failure if mismatch, else skip them. */
+ if ( translate ?
+ bcmp_translate ( d, d2, mcnt, translate ) :
+ memcmp ( d, d2, mcnt )
+ ) goto fail;
+
+ d += mcnt, d2 += mcnt;
+
+ } /* end while */
+
+ } /* duplicate */
+
+ break;
+
+ case anychar:
+
+ /* fetch a data character */
+ PREFETCH;
+ /* Match anything but a newline. */
+ if ( ( translate ? translate[ *d++ ] : *d++ ) == _TEXT( '\n' ) ) goto fail;
+
+ break;
+
+ case charset:
+ case charset_not: {
+
+ /* Nonzero for charset_not */
+ int not = 0;
+ int c;
+
+ if ( *( p - 1 ) == ( _TUCHAR ) charset_not ) not = 1;
+
+ /* fetch a data character */
+ PREFETCH;
+
+ if ( translate )
+ c = translate [ *d ];
+ else
+ c = *d;
+
+ if ( c < ( int )( *p * BYTEWIDTH ) &&
+ p[ 1 + c / BYTEWIDTH ] & ( 1 << ( c % BYTEWIDTH ) )
+ ) not = !not;
+
+ p += 1 + *p;
+
+ if ( !not ) goto fail;
+
+ ++d;
+
+ } /* charset & charset_not */
+
+ break;
+
+ case begline:
+
+ if ( d == string1 || d[ -1 ] == _TEXT( '\n' ) ) break;
+
+ goto fail;
+
+ case endline:
+
+ if ( d == end2 ||
+ ( d == end1 ? ( size2 == 0 ||
+ *string2 == _TEXT( '\n' )
+ )
+ : *d == _TEXT( '\n' )
+ )
+ ) break;
+
+ goto fail;
+
+ /* "or" constructs ("|") are handled by starting each alternative */
+ /* with an on_failure_jump that points to the start of the next alternative. */
+ /* Each alternative except the last ends with a jump to the joining point. */
+ /* (Actually, each jump except for the last one really jumps */
+ /* to the following jump, because tensioning the jumps is a hassle.) */
+ /* */
+ /* The start of a stupid repeat has an on_failure_jump that points */
+ /* past the end of the repeat text. */
+ /* This makes a failure point so that, on failure to match a repetition, */
+ /* matching restarts past as many repetitions have been found */
+ /* with no way to fail and look for another one. */
+ /* */
+ /* A smart repeat is similar but loops back to the on_failure_jump */
+ /* so that each repetition makes another failure point. */
+
+ case on_failure_jump:
+
+ if ( stackp == stacke ) {
+
+ _TUCHAR** stackx;
+
+ if ( stacke - stackb > RE_MAX_FAILURES ) return -2;
+
+ stackx = ( _TUCHAR** ) alloca ( 2 * ( stacke - stackb ) * sizeof ( _TCHAR* ) );
+ memcpy ( stackx, stackb, ( stacke - stackb ) * sizeof ( _TCHAR* ) );
+ stackp = stackx + ( stackp - stackb );
+ stacke = stackx + 2 * ( stacke - stackb );
+ stackb = stackx;
+
+ } /* end if */
+
+ mcnt = *p++ & CHAR_MASK;
+ mcnt += SIGN_EXTEND_CHAR( *( _TCHAR* )p ) << BYTEWIDTH;
+ ++p;
+ *stackp++ = mcnt + p;
+ *stackp++ = d;
+
+ break;
+
+ /* The end of a smart repeat has an maybe_finalize_jump back. */
+ /* Change it either to a finalize_jump or an ordinary jump. */
+ case maybe_finalize_jump:
+
+ mcnt = *p++ & CHAR_MASK;
+ mcnt += SIGN_EXTEND_CHAR( *( _TCHAR* )p ) << BYTEWIDTH;
+ ++p;
+
+ /* Compare what follows with the begining of the repeat. */
+ /* If we can establish that there is nothing that they would */
+ /* both match, we can change to finalize_jump */
+ if ( p == pend )
+ p[ -3 ] = ( _TUCHAR )finalize_jump;
+ else if ( *p == ( _TUCHAR )exactn ||
+ *p == ( _TUCHAR )endline
+ ) {
+
+ int c = *p == ( _TUCHAR ) endline ? _TEXT( '\n' ) : p[ 2 ];
+ _TUCHAR* p1 = p + mcnt;
+
+ /* p1[0] ... p1[2] are an on_failure_jump. */
+ /* Examine what follows that */
+ if ( p1[ 3 ] == ( _TUCHAR )exactn && p1[ 5 ] != c )
+ p[ -3 ] = ( _TUCHAR )finalize_jump;
+ else if ( p1[ 3 ] == ( _TUCHAR )charset ||
+ p1[ 3 ] == ( _TUCHAR )charset_not
+ ) {
+
+ int not = p1[ 3 ] == ( _TCHAR )charset_not;
+
+ if ( c < ( int )( p1[ 4 ] * BYTEWIDTH ) &&
+ p1[ 5 + c / BYTEWIDTH ] & ( 1 << ( c % BYTEWIDTH ) )
+ ) not = !not;
+
+ /* not is 1 if c would match */
+ /* That means it is not safe to finalize */
+ if ( !not ) p[ -3 ] = ( _TUCHAR )finalize_jump;
+
+ } /* end if */
+
+ } /* end if */
+
+ p -= 2;
+
+ if ( p[ -1 ] != ( _TUCHAR )finalize_jump ) {
+
+ p[ -1 ] = ( _TUCHAR ) jump;
+ goto nofinalize;
+
+ } /* end if */
+
+ /* The end of a stupid repeat has a finalize-jump */
+ /* back to the start, where another failure point will be made */
+ /* which will point after all the repetitions found so far. */
+
+ case finalize_jump:
+
+ stackp -= 2;
+
+ case jump:
+
+nofinalize:
+
+ mcnt = *p++ & CHAR_MASK;
+ mcnt += SIGN_EXTEND_CHAR( *( _TCHAR* )p ) << BYTEWIDTH;
+ p += mcnt + 1; /* The 1 compensates for missing ++ above */
+
+ break;
+
+ case dummy_failure_jump:
+
+ if ( stackp == stacke ) {
+
+ _TUCHAR** stackx =
+ ( _TUCHAR** ) alloca ( 2 * ( stacke - stackb ) * sizeof ( _TUCHAR* ) );
+
+ memcpy ( stackx, stackb, (stacke - stackb) * sizeof ( _TCHAR* ) );
+ stackp = stackx + ( stackp - stackb );
+ stacke = stackx + 2 * ( stacke - stackb );
+ stackb = stackx;
+
+ } /* end if */
+
+ *stackp++ = 0;
+ *stackp++ = 0;
+
+ goto nofinalize;
+
+ case wordbound:
+
+ if ( d == string1 || /* Points to first char */
+ d == end2 || /* Points to end */
+ ( d == end1 && size2 == 0 ) /* Points to end */
+ ) break;
+
+ if ( ( SYNTAX( d[ -1 ] ) == Sword ) !=
+ ( SYNTAX( d == end1 ? *string2 : *d ) == Sword )
+ ) break;
+
+ goto fail;
+
+ case notwordbound:
+
+ if ( d == string1 || /* Points to first char */
+ d == end2 || /* Points to end */
+ ( d == end1 && size2 == 0 ) /* Points to end */
+ ) goto fail;
+
+ if ( ( SYNTAX( d[ -1 ] ) == Sword ) !=
+ ( SYNTAX( d == end1 ? *string2 : *d ) == Sword )
+ ) goto fail;
+
+ break;
+
+ case wordbeg:
+
+ if ( d == end2 || /* Points to end */
+ ( d == end1 && size2 == 0) || /* Points to end */
+ SYNTAX( *( d == end1 ? string2 : d ) ) != Sword /* Next char not a letter */
+ ) goto fail;
+
+ if ( d == string1 || /* Points to first char */
+ SYNTAX( d[ -1 ] ) != Sword /* prev char not letter */
+ ) break;
+
+ goto fail;
+
+ case wordend:
+
+ if ( d == string1 || /* Points to first char */
+ SYNTAX( d[-1] ) != Sword /* prev char not letter */
+ ) goto fail;
+
+ if ( d == end2 || /* Points to end */
+ (d == end1 && size2 == 0) || /* Points to end */
+ SYNTAX( d == end1 ? *string2 : *d ) != Sword /* Next char not a letter */
+ ) break;
+
+ goto fail;
+
+ case wordchar:
+
+ PREFETCH;
+
+ if ( SYNTAX ( *d++ ) == 0 ) goto fail;
+
+ break;
+
+ case notwordchar:
+
+ PREFETCH;
+
+ if ( SYNTAX ( *d++ ) != 0 ) goto fail;
+
+ break;
+
+ case begbuf:
+
+ if ( d == string1 ) /* Note, d cannot equal string2 */
+ break; /* unless string1 == string2. */
+
+ goto fail;
+
+ case endbuf:
+
+ if ( d == end2 || ( d == end1 && size2 == 0 ) ) break;
+
+ goto fail;
+
+ case exactn:
+ /* Match the next few pattern characters exactly. */
+ /* mcnt is how many characters to match. */
+ mcnt = *p++;
+
+ if ( translate ) {
+
+ do {
+
+ PREFETCH;
+
+ if ( translate[ *d++ ] != *p++ ) goto fail;
+
+ } while ( --mcnt );
+
+ } else {
+
+ do {
+
+ PREFETCH;
+
+ if ( *d++ != *p++ ) goto fail;
+
+ } while ( --mcnt );
+
+ } /* end else */
+
+ break;
+
+ } /* end switch */
+
+ continue; /* Successfully matched one pattern command; keep matching */
+
+ /* Jump here if any matching operation fails. */
+fail:
+
+ if ( stackp != stackb ) { /* A restart point is known. Restart there and pop it. */
+
+ if ( !stackp[ -2 ] ) { /* If innermost failure point is dormant, */
+ /* flush it and keep looking */
+ stackp -= 2;
+
+ goto fail;
+
+ } /* end if */
+
+ d = *--stackp;
+ p = *--stackp;
+
+ if ( d >= string1 && d <= end1 ) dend = end_match_1;
+
+ } else break; /* Matching at this starting point really fails! */
+
+ } /* end while */
+
+ return -1; /* Failure to match */
+
+} /* end re_search_2 */
+/***/
+/******************************************************************************/
+/* */
+/* */
+/******************************************************************************/
+/***/
+static int bcmp_translate (
+ _TUCHAR* s1, _TUCHAR* s2, int len, _TUCHAR* translate
+ ) {
+
+ _TUCHAR *p1 = s1, *p2 = s2;
+
+ while ( len ) {
+
+ if ( translate [ *p1++ ] != translate [ *p2++] ) return 1;
+
+ --len;
+
+ } /* end while */
+
+ return 0;
+
+} /* end bcmp_translate */
+/***/
+/******************************************************************************/