From: cas Date: Fri, 22 Oct 1999 18:05:40 +0000 (+0000) Subject: Initial revision X-Git-Tag: V6_7_1~176 X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=14ef39e5c0cc00633304a57a4f571f0cdc9abcdd;p=occt-wok.git Initial revision --- diff --git a/src/WOKUnix/FILES b/src/WOKUnix/FILES new file mode 100755 index 0000000..5bcfc1d --- /dev/null +++ b/src/WOKUnix/FILES @@ -0,0 +1,13 @@ +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 diff --git a/src/WOKUnix/INTERNLIB b/src/WOKUnix/INTERNLIB new file mode 100755 index 0000000..209e6e8 --- /dev/null +++ b/src/WOKUnix/INTERNLIB @@ -0,0 +1,7 @@ +WOKUnix +MMgt +TColStd +TCollection +Standard +OSD +WOKTools diff --git a/src/WOKUnix/WOKUnix.cdl b/src/WOKUnix/WOKUnix.cdl new file mode 100755 index 0000000..81ebde5 --- /dev/null +++ b/src/WOKUnix/WOKUnix.cdl @@ -0,0 +1,99 @@ +-- File: WOKUnix.cdl +-- Created: Fri Jan 31 18:34:49 1997 +-- Author: Jean GAUTIER +-- +---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; diff --git a/src/WOKUnix/WOKUnix.cxx b/src/WOKUnix/WOKUnix.cxx new file mode 100755 index 0000000..43cd18e --- /dev/null +++ b/src/WOKUnix/WOKUnix.cxx @@ -0,0 +1,26 @@ + + +#include + +#include +#include + + +Standard_Integer WOKUnix::SystemLastError() +{ + return errno; +} + + +Standard_CString WOKUnix::SystemMessage(const Standard_Integer errCode) +{ + return strerror(errCode); +} + + + +Standard_CString WOKUnix::LastSystemMessage() +{ + return strerror(SystemLastError()); +} + diff --git a/src/WOKUnix/WOKUnix_ASyncStatus.cdl b/src/WOKUnix/WOKUnix_ASyncStatus.cdl new file mode 100755 index 0000000..807281d --- /dev/null +++ b/src/WOKUnix/WOKUnix_ASyncStatus.cdl @@ -0,0 +1,25 @@ +-- File: WOKUnix_ASyncStatus.cdl +-- Created: Thu Jun 8 20:05:09 1995 +-- Author: Jean GAUTIER +-- +---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; diff --git a/src/WOKUnix/WOKUnix_ASyncStatus.cxx b/src/WOKUnix/WOKUnix_ASyncStatus.cxx new file mode 100755 index 0000000..97e45d3 --- /dev/null +++ b/src/WOKUnix/WOKUnix_ASyncStatus.cxx @@ -0,0 +1,86 @@ + +#include +#include +#include + +#include + +//======================================================================= +//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; +} + diff --git a/src/WOKUnix/WOKUnix_AdmFile.cdl b/src/WOKUnix/WOKUnix_AdmFile.cdl new file mode 100755 index 0000000..6845474 --- /dev/null +++ b/src/WOKUnix/WOKUnix_AdmFile.cdl @@ -0,0 +1,40 @@ +-- File: WOKUnix_AdmFile.cdl +-- Created: Wed Jun 21 17:53:44 1995 +-- Author: Jean GAUTIER +-- +---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; diff --git a/src/WOKUnix/WOKUnix_AdmFile.cxx b/src/WOKUnix/WOKUnix_AdmFile.cxx new file mode 100755 index 0000000..b9dbb45 --- /dev/null +++ b/src/WOKUnix/WOKUnix_AdmFile.cxx @@ -0,0 +1,103 @@ + +#include + +#include + +#include + +#include + +#include +#include + +#include + +#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; +} + diff --git a/src/WOKUnix/WOKUnix_Buffer.cdl b/src/WOKUnix/WOKUnix_Buffer.cdl new file mode 100755 index 0000000..f7dbf65 --- /dev/null +++ b/src/WOKUnix/WOKUnix_Buffer.cdl @@ -0,0 +1,43 @@ +-- File: WOKUnix_Buffer.cdl +-- Created: Thu May 4 16:33:47 1995 +-- Author: Jean GAUTIER +-- +---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; diff --git a/src/WOKUnix/WOKUnix_Buffer.cxx b/src/WOKUnix/WOKUnix_Buffer.cxx new file mode 100755 index 0000000..8750cc6 --- /dev/null +++ b/src/WOKUnix/WOKUnix_Buffer.cxx @@ -0,0 +1,181 @@ + +#include + +#include + +#include + +//======================================================================= +//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(iAppend(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(iAppend(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(); +} diff --git a/src/WOKUnix/WOKUnix_CMPLRS.edl b/src/WOKUnix/WOKUnix_CMPLRS.edl new file mode 100755 index 0000000..35a358d --- /dev/null +++ b/src/WOKUnix/WOKUnix_CMPLRS.edl @@ -0,0 +1,14 @@ +-- 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; diff --git a/src/WOKUnix/WOKUnix_CantBlockBuffer.cdl b/src/WOKUnix/WOKUnix_CantBlockBuffer.cdl new file mode 100755 index 0000000..b63d175 --- /dev/null +++ b/src/WOKUnix/WOKUnix_CantBlockBuffer.cdl @@ -0,0 +1,28 @@ +-- File: WOKUnix_CantBlockBuffer.cdl +-- Created: Tue May 9 13:56:16 1995 +-- Author: Jean GAUTIER +-- +---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; diff --git a/src/WOKUnix/WOKUnix_CantBlockBuffer.cxx b/src/WOKUnix/WOKUnix_CantBlockBuffer.cxx new file mode 100755 index 0000000..ff51117 --- /dev/null +++ b/src/WOKUnix/WOKUnix_CantBlockBuffer.cxx @@ -0,0 +1,46 @@ + + +#include + +#include + +//======================================================================= +//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(); +} diff --git a/src/WOKUnix/WOKUnix_Dir.hxx b/src/WOKUnix/WOKUnix_Dir.hxx new file mode 100755 index 0000000..2225f6e --- /dev/null +++ b/src/WOKUnix/WOKUnix_Dir.hxx @@ -0,0 +1,21 @@ +// File: WOKUnix_Dir.hxx +// Author: Jean GAUTIER +// + + +#ifndef WOKUnix_Dir_HeaderFile +#define WOKUnix_Dir_HeaderFile + +#ifndef WNT + +#include + +typedef DIR* WOKUnix_Dir; + +#else + +#error "Type Dir does not exist on WNT" + +#endif + +#endif diff --git a/src/WOKUnix/WOKUnix_DirEnt.hxx b/src/WOKUnix/WOKUnix_DirEnt.hxx new file mode 100755 index 0000000..6ed5002 --- /dev/null +++ b/src/WOKUnix/WOKUnix_DirEnt.hxx @@ -0,0 +1,21 @@ +// File: WOKUnix_Dir.hxx +// Author: Jean GAUTIER +// + + +#ifndef WOKUnix_DirEnt_HeaderFile +#define WOKUnix_DirEnt_HeaderFile + +#ifndef WNT + +#include + +typedef struct dirent* WOKUnix_DirEnt; + +#else + +#error "Type DirEnt does not exist on WNT" + +#endif + +#endif diff --git a/src/WOKUnix/WOKUnix_DumbOutput.cdl b/src/WOKUnix/WOKUnix_DumbOutput.cdl new file mode 100755 index 0000000..6743d6c --- /dev/null +++ b/src/WOKUnix/WOKUnix_DumbOutput.cdl @@ -0,0 +1,36 @@ +-- File: WOKUnix_DumbOutput.cdl +-- Created: Tue May 9 14:02:54 1995 +-- Author: Jean GAUTIER +-- +---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; diff --git a/src/WOKUnix/WOKUnix_DumbOutput.cxx b/src/WOKUnix/WOKUnix_DumbOutput.cxx new file mode 100755 index 0000000..76167b7 --- /dev/null +++ b/src/WOKUnix/WOKUnix_DumbOutput.cxx @@ -0,0 +1,62 @@ + +#include + +//======================================================================= +//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() +{ +} + diff --git a/src/WOKUnix/WOKUnix_DumpScript.cdl b/src/WOKUnix/WOKUnix_DumpScript.cdl new file mode 100755 index 0000000..dd8d9d7 --- /dev/null +++ b/src/WOKUnix/WOKUnix_DumpScript.cdl @@ -0,0 +1,26 @@ +-- File: WOKUnix_DumpScript.cdl +-- Created: Thu Jun 8 20:07:55 1995 +-- Author: Jean GAUTIER +-- +---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; diff --git a/src/WOKUnix/WOKUnix_DumpScript.cxx b/src/WOKUnix/WOKUnix_DumpScript.cxx new file mode 100755 index 0000000..59d477a --- /dev/null +++ b/src/WOKUnix/WOKUnix_DumpScript.cxx @@ -0,0 +1,53 @@ +#include +#include + +//======================================================================= +//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; +} + diff --git a/src/WOKUnix/WOKUnix_FDSet.hxx b/src/WOKUnix/WOKUnix_FDSet.hxx new file mode 100755 index 0000000..e7fedf9 --- /dev/null +++ b/src/WOKUnix/WOKUnix_FDSet.hxx @@ -0,0 +1,25 @@ +// File: WOKUnix_FDSet.hxx +// Created: Tue May 9 15:25:38 1995 +// Author: Jean GAUTIER +// + + +#ifndef WOKUnix_FDSet_HeaderFile +#define WOKUnix_FDSet_HeaderFile + +#ifndef HPUX +#include +#define WOKUnix_FDSet_CAST fd_set * +#endif + +#ifdef HPUX +#include +#include +#include +#define WOKUnix_FDSet_CAST fd_set * +#endif + +typedef struct fd_set WOKUnix_FDSet; + +#endif + diff --git a/src/WOKUnix/WOKUnix_FDescr.cdl b/src/WOKUnix/WOKUnix_FDescr.cdl new file mode 100755 index 0000000..8c9b757 --- /dev/null +++ b/src/WOKUnix/WOKUnix_FDescr.cdl @@ -0,0 +1,48 @@ +-- File: WOKUnix_FDescr.cdl +-- Created: Thu May 4 16:55:43 1995 +-- Author: Jean GAUTIER +-- +---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; diff --git a/src/WOKUnix/WOKUnix_FDescr.cxx b/src/WOKUnix/WOKUnix_FDescr.cxx new file mode 100755 index 0000000..5a71d94 --- /dev/null +++ b/src/WOKUnix/WOKUnix_FDescr.cxx @@ -0,0 +1,396 @@ + +#include +#include +#include +#include + + +#ifdef SOLARIS +#include +#else +#include +#endif +#include + +#include + +#include + +#include +#include +#include + +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; +} + + + + + + diff --git a/src/WOKUnix/WOKUnix_FileBuffer.cdl b/src/WOKUnix/WOKUnix_FileBuffer.cdl new file mode 100755 index 0000000..0e67d55 --- /dev/null +++ b/src/WOKUnix/WOKUnix_FileBuffer.cdl @@ -0,0 +1,34 @@ +-- File: WOKUnix_FileBuffer.cdl +-- Created: Thu May 4 18:27:14 1995 +-- Author: Jean GAUTIER +-- +---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; diff --git a/src/WOKUnix/WOKUnix_FileBuffer.cxx b/src/WOKUnix/WOKUnix_FileBuffer.cxx new file mode 100755 index 0000000..e32b458 --- /dev/null +++ b/src/WOKUnix/WOKUnix_FileBuffer.cxx @@ -0,0 +1,150 @@ + + +#include +#include + + +#include + +#include + +#include + +#include + +// 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(); +} diff --git a/src/WOKUnix/WOKUnix_MaxPipeSize.hxx b/src/WOKUnix/WOKUnix_MaxPipeSize.hxx new file mode 100755 index 0000000..c07d95b --- /dev/null +++ b/src/WOKUnix/WOKUnix_MaxPipeSize.hxx @@ -0,0 +1,27 @@ +// File: WOKUnix_MaxPipeSize.hxx +// Created: Fri May 12 10:09:01 1995 +// Author: Jean GAUTIER +// + + +#ifndef WOKUnix_MaxPipeSize_HeaderFile +#define WOKUnix_MaxPipeSize_HeaderFile + + +#ifdef HPUX +#include +//#define MAX_PIPE_SIZE PIPSIZ +#define MAX_PIPE_SIZE 8190 +#elif IRIX +#include +#define MAX_PIPE_SIZE PIPE_MAX +#elif DECOSF1 +#include +#define MAX_PIPE_SIZE PIPE_BUF +#elif SOLARIS +#include +#define MAX_PIPE_SIZE PIPE_MAX +#endif + + +#endif diff --git a/src/WOKUnix/WOKUnix_MixedOutput.cdl b/src/WOKUnix/WOKUnix_MixedOutput.cdl new file mode 100755 index 0000000..e560b75 --- /dev/null +++ b/src/WOKUnix/WOKUnix_MixedOutput.cdl @@ -0,0 +1,35 @@ +-- File: WOKUnix_MixedOutput.cdl +-- Created: Thu May 4 16:30:11 1995 +-- Author: Jean GAUTIER +-- +---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; + diff --git a/src/WOKUnix/WOKUnix_MixedOutput.cxx b/src/WOKUnix/WOKUnix_MixedOutput.cxx new file mode 100755 index 0000000..a386c53 --- /dev/null +++ b/src/WOKUnix/WOKUnix_MixedOutput.cxx @@ -0,0 +1,86 @@ + +#include + + +#include +#include +#include + +//======================================================================= +//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(); +} + diff --git a/src/WOKUnix/WOKUnix_NoBuffer.cdl b/src/WOKUnix/WOKUnix_NoBuffer.cdl new file mode 100755 index 0000000..e2c3a96 --- /dev/null +++ b/src/WOKUnix/WOKUnix_NoBuffer.cdl @@ -0,0 +1,28 @@ +-- File: WOKUnix_NoBuffer.cdl +-- Created: Thu May 4 18:30:08 1995 +-- Author: Jean GAUTIER +-- +---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; diff --git a/src/WOKUnix/WOKUnix_NoBuffer.cxx b/src/WOKUnix/WOKUnix_NoBuffer.cxx new file mode 100755 index 0000000..f931fb8 --- /dev/null +++ b/src/WOKUnix/WOKUnix_NoBuffer.cxx @@ -0,0 +1,44 @@ +#include + + 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() +{ + +} diff --git a/src/WOKUnix/WOKUnix_OutErrOutput.cdl b/src/WOKUnix/WOKUnix_OutErrOutput.cdl new file mode 100755 index 0000000..6524f11 --- /dev/null +++ b/src/WOKUnix/WOKUnix_OutErrOutput.cdl @@ -0,0 +1,41 @@ +-- File: WOKUnix_OutErrOutput.cdl +-- Created: Tue May 9 13:57:51 1995 +-- Author: Jean GAUTIER +-- +---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; diff --git a/src/WOKUnix/WOKUnix_OutErrOutput.cxx b/src/WOKUnix/WOKUnix_OutErrOutput.cxx new file mode 100755 index 0000000..150b02b --- /dev/null +++ b/src/WOKUnix/WOKUnix_OutErrOutput.cxx @@ -0,0 +1,112 @@ + +#include +#include +#include +#include + + +//======================================================================= +//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(); +} + diff --git a/src/WOKUnix/WOKUnix_Path.cdl b/src/WOKUnix/WOKUnix_Path.cdl new file mode 100755 index 0000000..1e50142 --- /dev/null +++ b/src/WOKUnix/WOKUnix_Path.cdl @@ -0,0 +1,152 @@ +-- File: WOKUnix_Path.cdl +-- Created: Mon May 29 15:09:14 1995 +-- Author: Jean GAUTIER +-- +---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 (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 (.) of path + returns HAsciiString from TCollection; + +fields + mypath : HAsciiString from TCollection; + myacces : Boolean from Standard; + mystats : StatBuf from WOKUnix; +end; + + diff --git a/src/WOKUnix/WOKUnix_Path.cxx b/src/WOKUnix/WOKUnix_Path.cxx new file mode 100755 index 0000000..13765da --- /dev/null +++ b/src/WOKUnix/WOKUnix_Path.cxx @@ -0,0 +1,770 @@ +// File: WOKUnix_Path.cxx +// Created: Tue May 30 09:17:00 1995 +// Author: Jean GAUTIER +// + +#include +#include +#include +#include +#include +#include +#include + +#ifndef PATH_MAX +#define PATH_MAX 1024 +#endif + +#include + +#include + +#include + +#include + +#include + +//======================================================================= +//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; +} + diff --git a/src/WOKUnix/WOKUnix_Path.lxx b/src/WOKUnix/WOKUnix_Path.lxx new file mode 100755 index 0000000..f8afa87 --- /dev/null +++ b/src/WOKUnix/WOKUnix_Path.lxx @@ -0,0 +1,45 @@ +// File: WOKUnix_Path.lxx +// Created: Thu Jul 27 19:46:43 1995 +// Author: Jean GAUTIER +// + +#include + +//======================================================================= +//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; +} diff --git a/src/WOKUnix/WOKUnix_PathIterator.cdl b/src/WOKUnix/WOKUnix_PathIterator.cdl new file mode 100755 index 0000000..5c76fac --- /dev/null +++ b/src/WOKUnix/WOKUnix_PathIterator.cdl @@ -0,0 +1,66 @@ +-- File: WOKUnix_PathIterator.cdl +-- Created: Mon Aug 03 15:37:45 1998 +-- Author: +-- +---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; + + diff --git a/src/WOKUnix/WOKUnix_PathIterator.cxx b/src/WOKUnix/WOKUnix_PathIterator.cxx new file mode 100755 index 0000000..3614f25 --- /dev/null +++ b/src/WOKUnix/WOKUnix_PathIterator.cxx @@ -0,0 +1,187 @@ + + +#include + + +#include +#include + +#include + +#include + +#include +//#include +//#include +#include + + +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(); + } +} + + + diff --git a/src/WOKUnix/WOKUnix_Process.cdl b/src/WOKUnix/WOKUnix_Process.cdl new file mode 100755 index 0000000..9bad083 --- /dev/null +++ b/src/WOKUnix/WOKUnix_Process.cdl @@ -0,0 +1,89 @@ +-- File: WOKUnix_Process.cdl +-- Created: Tue May 9 14:18:26 1995 +-- Author: Jean GAUTIER +-- +---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; + + diff --git a/src/WOKUnix/WOKUnix_Process.cxx b/src/WOKUnix/WOKUnix_Process.cxx new file mode 100755 index 0000000..0308f80 --- /dev/null +++ b/src/WOKUnix/WOKUnix_Process.cxx @@ -0,0 +1,355 @@ + +#ifdef IRIX +#include +#include +#include +#include +#endif + +#ifdef HPUX +#include +#include +#include +#endif + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + + +//======================================================================= +//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; +} diff --git a/src/WOKUnix/WOKUnix_ProcessManager.cdl b/src/WOKUnix/WOKUnix_ProcessManager.cdl new file mode 100755 index 0000000..e1dbde7 --- /dev/null +++ b/src/WOKUnix/WOKUnix_ProcessManager.cdl @@ -0,0 +1,41 @@ +-- File: WOKUnix_ProcessManager.cdl +-- Created: Tue Jun 6 14:02:25 1995 +-- Author: Jean GAUTIER +-- +---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; diff --git a/src/WOKUnix/WOKUnix_ProcessManager.cxx b/src/WOKUnix/WOKUnix_ProcessManager.cxx new file mode 100755 index 0000000..ade5501 --- /dev/null +++ b/src/WOKUnix/WOKUnix_ProcessManager.cxx @@ -0,0 +1,197 @@ + +#include + +#include + +#include + +#include + +#include + +#include + +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; +} diff --git a/src/WOKUnix/WOKUnix_ProcessOutput.cdl b/src/WOKUnix/WOKUnix_ProcessOutput.cdl new file mode 100755 index 0000000..ecedd59 --- /dev/null +++ b/src/WOKUnix/WOKUnix_ProcessOutput.cdl @@ -0,0 +1,27 @@ +-- File: WOKUnix_ProcessOutput.cdl +-- Created: Thu May 4 16:23:17 1995 +-- Author: Jean GAUTIER +-- +---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; diff --git a/src/WOKUnix/WOKUnix_ProcessOutput.cxx b/src/WOKUnix/WOKUnix_ProcessOutput.cxx new file mode 100755 index 0000000..307ab20 --- /dev/null +++ b/src/WOKUnix/WOKUnix_ProcessOutput.cxx @@ -0,0 +1,6 @@ +#include + + WOKUnix_ProcessOutput::WOKUnix_ProcessOutput() +{ +} + diff --git a/src/WOKUnix/WOKUnix_RegExp.cdl b/src/WOKUnix/WOKUnix_RegExp.cdl new file mode 100755 index 0000000..55d5ff4 --- /dev/null +++ b/src/WOKUnix/WOKUnix_RegExp.cdl @@ -0,0 +1,88 @@ +-- File: WOKUnix_RegExp.cdl +-- Created: Fri Aug 2 09:43:37 1996 +-- Author: PLOTNIKOV Eugeny +-- +---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 and + -- its length to perform character translation. + -- Supply NULL for and zero value for + -- if no translation necessary. It is possible to set + -- syntax of the regular expression by meaning + -- 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 which matches + -- the specified pattern starting at index . + -- 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 + -- starting at index . Do not consider matching + -- past the position . + -- 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; diff --git a/src/WOKUnix/WOKUnix_RegExp.cxx b/src/WOKUnix/WOKUnix_RegExp.cxx new file mode 100755 index 0000000..6573d66 --- /dev/null +++ b/src/WOKUnix/WOKUnix_RegExp.cxx @@ -0,0 +1,160 @@ + +#include + +#include + +#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 + diff --git a/src/WOKUnix/WOKUnix_RemoteShell.cdl b/src/WOKUnix/WOKUnix_RemoteShell.cdl new file mode 100755 index 0000000..955839d --- /dev/null +++ b/src/WOKUnix/WOKUnix_RemoteShell.cdl @@ -0,0 +1,45 @@ +-- File: WOKUnix_RemoteShell.cdl +-- Created: Mon Nov 6 14:29:52 1995 +-- Author: Jean GAUTIER +-- +---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; + + + diff --git a/src/WOKUnix/WOKUnix_RemoteShell.cxx b/src/WOKUnix/WOKUnix_RemoteShell.cxx new file mode 100755 index 0000000..ddd5c0c --- /dev/null +++ b/src/WOKUnix/WOKUnix_RemoteShell.cxx @@ -0,0 +1,160 @@ +// File: WOKUnix_RemoteShell.cxx +// Created: Mon Nov 6 14:55:55 1995 +// Author: Jean GAUTIER +// + +#ifdef IRIX +#include +#include +#include +#include +#endif + +#ifdef HPUX +#include +#include +#include +#endif + +#include +#include +#include + +#include +#include +#include +#include + +#include + + +//======================================================================= +//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; +} + + + + + + + + + + diff --git a/src/WOKUnix/WOKUnix_Shell.cdl b/src/WOKUnix/WOKUnix_Shell.cdl new file mode 100755 index 0000000..140d2f5 --- /dev/null +++ b/src/WOKUnix/WOKUnix_Shell.cdl @@ -0,0 +1,81 @@ +-- File: WOKUnix_Shell.cdl +-- Created: Thu Jun 8 17:31:30 1995 +-- Author: Jean GAUTIER +-- +---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; diff --git a/src/WOKUnix/WOKUnix_Shell.cxx b/src/WOKUnix/WOKUnix_Shell.cxx new file mode 100755 index 0000000..6e762c0 --- /dev/null +++ b/src/WOKUnix/WOKUnix_Shell.cxx @@ -0,0 +1,440 @@ + +#ifdef IRIX +#include +#include +#include +#include +#endif + +#ifdef HPUX +#include +#include +#include +#endif + +#include + +#include + +#include +#include +#include +#include +#include + +#include + +#ifndef WOK_IDLE_TRIGGER +#define WOK_IDLE_TRIGGER 1 +#endif + +#ifdef WOK_IDLE_TRIGGER +#include +#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; iNo(), &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; +} + + diff --git a/src/WOKUnix/WOKUnix_ShellManager.cdl b/src/WOKUnix/WOKUnix_ShellManager.cdl new file mode 100755 index 0000000..c08317b --- /dev/null +++ b/src/WOKUnix/WOKUnix_ShellManager.cdl @@ -0,0 +1,36 @@ +-- File: WOKUnix_ShellManager.cdl +-- Created: Thu Apr 4 22:55:35 1996 +-- Author: Jean GAUTIER +-- +---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; + diff --git a/src/WOKUnix/WOKUnix_ShellManager.cxx b/src/WOKUnix/WOKUnix_ShellManager.cxx new file mode 100755 index 0000000..c1d4fa0 --- /dev/null +++ b/src/WOKUnix/WOKUnix_ShellManager.cxx @@ -0,0 +1,100 @@ +// File: WOKUnix_ShellManager.cxx +// Created: Thu Apr 4 23:21:02 1996 +// Author: Jean GAUTIER +// + +#include + +#include +#include +#include +#include + +//======================================================================= +//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; +} + + + + + + + diff --git a/src/WOKUnix/WOKUnix_ShellStatus.cdl b/src/WOKUnix/WOKUnix_ShellStatus.cdl new file mode 100755 index 0000000..4e7f3cf --- /dev/null +++ b/src/WOKUnix/WOKUnix_ShellStatus.cdl @@ -0,0 +1,55 @@ + +-- -- File: WOKUnix_ShellStatus.cdl +-- Created: Thu Jun 8 18:22:21 1995 +-- Author: Jean GAUTIER +-- +---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; + + + + diff --git a/src/WOKUnix/WOKUnix_ShellStatus.cxx b/src/WOKUnix/WOKUnix_ShellStatus.cxx new file mode 100755 index 0000000..48fb864 --- /dev/null +++ b/src/WOKUnix/WOKUnix_ShellStatus.cxx @@ -0,0 +1,131 @@ + +#include + +#include + +//======================================================================= +//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(); +} + + + + diff --git a/src/WOKUnix/WOKUnix_SigHandler.hxx b/src/WOKUnix/WOKUnix_SigHandler.hxx new file mode 100755 index 0000000..aa8dfa3 --- /dev/null +++ b/src/WOKUnix/WOKUnix_SigHandler.hxx @@ -0,0 +1,39 @@ +// File: WOKUnix_SigHandler.hxx +// Created: Wed May 24 18:35:36 1995 +// Author: Jean GAUTIER +// + + +#ifndef WOKUnix_SigHandler_HeaderFile +#define WOKUnix_SigHandler_HeaderFile + + +#ifdef SUN +#include +#endif + +#ifdef SOLARIS +#include +#include + +#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 +#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 diff --git a/src/WOKUnix/WOKUnix_Signal.cdl b/src/WOKUnix/WOKUnix_Signal.cdl new file mode 100755 index 0000000..aed35ea --- /dev/null +++ b/src/WOKUnix/WOKUnix_Signal.cdl @@ -0,0 +1,26 @@ +-- File: WOKUnix_Signal.cdl +-- Created: Wed May 24 17:32:41 1995 +-- Author: Jean GAUTIER +-- +---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; + diff --git a/src/WOKUnix/WOKUnix_Signal.cxx b/src/WOKUnix/WOKUnix_Signal.cxx new file mode 100755 index 0000000..752375b --- /dev/null +++ b/src/WOKUnix/WOKUnix_Signal.cxx @@ -0,0 +1,120 @@ + +#include + + +#include +#include + +#ifndef HPUX +#include +#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; + } +} diff --git a/src/WOKUnix/WOKUnix_StatBuf.hxx b/src/WOKUnix/WOKUnix_StatBuf.hxx new file mode 100755 index 0000000..4270909 --- /dev/null +++ b/src/WOKUnix/WOKUnix_StatBuf.hxx @@ -0,0 +1,22 @@ +// File: WOKUnix_StatBuf.hxx +// Author: Jean GAUTIER +// + + +#ifndef WOKUnix_StatBuf_HeaderFile +#define WOKUnix_StatBuf_HeaderFile + +#ifndef WNT + +#include +#include + +typedef struct stat WOKUnix_StatBuf; + +#else + +#error "Type StatBuf does not exist on WNT" + +#endif + +#endif diff --git a/src/WOKUnix/WOKUnix_SyncStatus.cdl b/src/WOKUnix/WOKUnix_SyncStatus.cdl new file mode 100755 index 0000000..db882f5 --- /dev/null +++ b/src/WOKUnix/WOKUnix_SyncStatus.cdl @@ -0,0 +1,24 @@ +-- File: WOKUnix_SyncStatus.cdl +-- Created: Thu Jun 8 20:07:25 1995 +-- Author: Jean GAUTIER +-- +---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; diff --git a/src/WOKUnix/WOKUnix_SyncStatus.cxx b/src/WOKUnix/WOKUnix_SyncStatus.cxx new file mode 100755 index 0000000..1cf1dfd --- /dev/null +++ b/src/WOKUnix/WOKUnix_SyncStatus.cxx @@ -0,0 +1,67 @@ + + +#include + +#include +#include +#include + + +//======================================================================= +//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)& ) +{ +} + diff --git a/src/WOKUnix/WOKUnix_TimeStat.hxx b/src/WOKUnix/WOKUnix_TimeStat.hxx new file mode 100755 index 0000000..64f1c10 --- /dev/null +++ b/src/WOKUnix/WOKUnix_TimeStat.hxx @@ -0,0 +1,18 @@ +// File: WOKUnix_TimeStat.hxx +// Created: Mon Jun 26 15:46:11 1995 +// Author: Jean GAUTIER +// + + +#ifndef WOKUnix_TimeStat_HeaderFile +#define WOKUnix_TimeStat_HeaderFile + +#include + + +// time time in return of stat system call + +typedef time_t WOKUnix_TimeStat; + + +#endif diff --git a/src/WOKUnix/WOKUnix_Timeval.hxx b/src/WOKUnix/WOKUnix_Timeval.hxx new file mode 100755 index 0000000..6e32290 --- /dev/null +++ b/src/WOKUnix/WOKUnix_Timeval.hxx @@ -0,0 +1,14 @@ +// File: WOKUnix_Timeval.hxx +// Created: Tue May 9 15:24:00 1995 +// Author: Jean GAUTIER +// + + +#ifndef WOKUnix_Timeval_HeaderFile +#define WOKUnix_Timeval_HeaderFile + +#include + +typedef struct timeval WOKUnix_Timeval ; + +#endif diff --git a/src/WOKUnix/WOKUnix_WOKSteps.edl b/src/WOKUnix/WOKUnix_WOKSteps.edl new file mode 100755 index 0000000..81e7c50 --- /dev/null +++ b/src/WOKUnix/WOKUnix_WOKSteps.edl @@ -0,0 +1,21 @@ +-- 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; diff --git a/src/WOKUnix/WOKUnix_regexp.h b/src/WOKUnix/WOKUnix_regexp.h new file mode 100755 index 0000000..a025578 --- /dev/null +++ b/src/WOKUnix/WOKUnix_regexp.h @@ -0,0 +1,283 @@ + +#ifndef __REGEXP_H +# define __REGEXP_H +/***/ +# ifdef WNT +# ifdef UNICODE_API +# ifndef _UNICODE +# define _UNICODE +# endif /* _UNICODE */ +# endif /* UNICODE_API */ +/***/ +# ifndef _INC_TCHAR +# include +# endif /* _INC_TCHAR */ +/***/ +# ifndef _INC_STDLIB +# include +# endif /* _INC_STDLIB */ +/***/ +# ifndef _INC_MALLOC +# include +# endif /* _INC_MALLOC */ +/***/ +# ifndef _INC_LIMITS +# include +# endif /* _INC_LIMITS */ +# ifndef _INC_STRING +# include +# 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 +# include +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 */ diff --git a/src/WOKUnix/WOKUnix_regexp_1.c b/src/WOKUnix/WOKUnix_regexp_1.c new file mode 100755 index 0000000..178fe4f --- /dev/null +++ b/src/WOKUnix/WOKUnix_regexp_1.c @@ -0,0 +1,1735 @@ +/******************************************************************************/ +/* 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 + +#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 + +/***/ +/******************************************************************************/ +/* */ +/* 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, \ turns into a `duplicate' command which */ + /* is followed by the numeric value of 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 */ +/***/ +/******************************************************************************/