--- /dev/null
+WOKNT_regexp.h
+WOKNT_regexp_1.c
+WOKNT_TimeStat.hxx
+WOKNT_Shell_1.cxx
+WOKNT_WNT_BREAK.hxx
+WOKNT_ReplIfChWith.c
+WOKNT_ReplIfCh.c
+WOKNT_cmp.c
+WOKNT_CopyIfCh.c
+WOKNT_chmod.cxx
+WOKNT_rm.cxx
+WOKNT_mv.cxx
+WOKNT_cp.cxx
+WOKNT_WOKSteps.edl
+WOKNT_Handle.hxx
+WOKNT_FindData.hxx
+WOKNT_Dword.hxx
--- /dev/null
+-- File: WOKNT.cdl
+-- Created: Mon Jul 22 15:58:28 1996
+-- Author: PLOTNIKOV Eugeny
+-- <eugeny@maniax>
+---Copyright: Matra Datavision 1996
+
+package WOKNT
+
+ ---Purpose: This package defines utility classes for
+ -- WOK++ for Windows NT.
+
+ uses
+
+ MMgt,
+ OSD,
+ TCollection,
+ TColStd,
+ SortTools,
+ EDL,
+ WOKTools
+
+ is
+
+
+ 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, PDBFile, DLLFile, EXEFile,
+ UnknownFile, NoExtFile;
+
+ enumeration RESyntax is RESyntaxAWK, RESyntaxEGREP, RESyntaxGREP, RESyntaxEMACS;
+
+ -----------------------
+ ---Category: classes---
+ -----------------------
+
+ ---class FDescr;
+ class AdmFile;
+ class Path;
+ class PathIterator;
+
+ class Shell;
+ class ShellManager;
+
+ class RegExp;
+
+ private deferred class ShellOutput;
+ private class MixedOutput;
+ private class OutErrOutput;
+
+
+ private class CompareOfString;
+
+ private class StackOfHandle
+ instantiates Stack from TCollection ( Handle from WOKNT );
+
+ private class SequenceOfShell
+ instantiates Sequence from TCollection ( Shell from WOKNT);
+
+
+ private deferred class PrivCompareOfString
+ instantiates Compare from TCollection ( HAsciiString from TCollection );
+
+ private class Array1OfString
+ instantiates Array1 from TCollection ( HAsciiString from TCollection );
+
+ private class QuickSortOfString
+ instantiates QuickSort from SortTools (
+ HAsciiString from TCollection,
+ Array1OfString from WOKNT,
+ CompareOfString from WOKNT );
+
+ private class Array1OfRegExp
+ instantiates Array1 from TCollection ( RegExp from WOKNT );
+
+
+ ------------------------------
+ ---Category: imported types---
+ ------------------------------
+
+ imported TimeStat;
+
+ private imported FindData;
+ private imported Handle;
+ private imported Dword;
+ ----------------------------
+ ---Category: enumerations---
+ ----------------------------
+
+ enumeration ExecutionMode is
+ SynchronousMode, AsynchronousMode;
+
+ enumeration OutputMode is
+ OutErrMixed, OutErrSeparated;
+
+ SystemLastError returns Integer from Standard;
+
+ SystemMessage(i : Integer from Standard)
+ returns CString from Standard;
+
+ LastSystemMessage
+ returns CString from Standard;
+
+end WOKNT;
--- /dev/null
+
+
+
+#ifdef WNT
+
+#include <windows.h>
+
+#ifdef CreateFile
+# undef CreateFile
+#endif // CreateFile
+
+#ifdef CreateDirectory
+# undef CreateDirectory
+#endif // CreateFile
+
+#ifdef RemoveDirectory
+# undef RemoveDirectory
+#endif // CreateFile
+
+#include <WOKNT.hxx>
+
+
+Standard_Integer WOKNT::SystemLastError()
+{
+ return GetLastError();
+}
+
+Standard_CString WOKNT::SystemMessage(const Standard_Integer errCode)
+{
+ static Standard_Character buffer[ 1024 ];
+
+ if(!FormatMessage ( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY,
+ 0, errCode, MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL ),
+ buffer, 2048, NULL))
+ {
+ wsprintf ( buffer, "error code %d", errCode );
+ SetLastError ( errCode );
+ }
+ return buffer;
+}
+Standard_CString WOKNT::LastSystemMessage()
+{
+ return SystemMessage(SystemLastError());
+}
+
+
+
+
+#endif
--- /dev/null
+-- File: WOKNT_AdmFile.cdl
+-- Created: Wed Jul 24 12:59:45 1996
+-- Author: PLOTNIKOV Eugeny
+-- <eugeny@maniax>
+---Copyright: Matra Datavision 1996
+
+class AdmFile from WOKNT inherits File from OSD
+
+ ---Purpose: reads file in WOK format
+ -- - lines beginning by '#' are ignored
+ -- - lines terminating by '\' are continued
+ -- - empty lines are ignored
+
+ uses
+
+ AsciiString from TCollection,
+ HAsciiString from TCollection,
+ HSequenceOfHAsciiString from TColStd,
+ Path from WOKNT
+
+ raises
+
+ ProgramError from Standard
+
+ is
+
+ Create ( aPath : Path from WOKNT ) returns AdmFile from WOKNT;
+ ---Purpose: creates a class instance
+
+ Read ( me : out )
+ returns HSequenceOfHAsciiString from TColStd
+ raises ProgramError from Standard;
+ ---Purpose: reads a file in WOK format
+
+ Name ( me ) returns AsciiString from TCollection;
+end AdmFile;
--- /dev/null
+#define STRICT
+#include <windows.h>
+
+#include <WOKNT_AdmFile.ixx>
+
+#include <WOKTools_Messages.hxx>
+#include <OSD_Protection.hxx>
+
+#define MAX_LINE_LENGTH 1024
+
+#define RAISE() Standard_ProgramError :: Raise ( TEXT( "WOKNT_AdmFile :: Read () failed" ) );
+
+WOKNT_AdmFile :: WOKNT_AdmFile ( const Handle( WOKNT_Path )& aPath ) :
+ OSD_File ( OSD_Path ( aPath -> Name () -> String () ) ) {
+
+} // end constructor
+
+Handle( TColStd_HSequenceOfHAsciiString ) WOKNT_AdmFile :: Read () {
+
+ TCollection_AsciiString str;
+ Handle( TColStd_HSequenceOfHAsciiString ) retVal = new TColStd_HSequenceOfHAsciiString;
+
+ if ( !Exists () ) {
+
+ ErrorMsg << TEXT( "WOKNT_AdmFile :: Read (): " << "file '" ) << Name ().ToCString ()
+ << TEXT( "' does not exists" ) << endm;
+ RAISE();
+
+ } else if ( KindOfFile () != OSD_FILE ) {
+
+ ErrorMsg << TEXT( "WOKNT_AdmFile :: Read (): " << "file '" ) << Name ().ToCString ()
+ << TEXT( "' is not a file" ) << endm;
+ RAISE();
+
+ } else {
+
+ Standard_Boolean fNext = Standard_False;
+ Standard_Boolean isNext;
+ Standard_Integer nRead;
+
+ Open ( OSD_ReadOnly, OSD_Protection () );
+
+ while ( 1 ) {
+
+ ReadLine ( str, MAX_LINE_LENGTH, nRead );
+
+ if ( IsAtEnd () || Failed () ) break;
+
+ str.LeftAdjust ();
+
+ if ( !str.IsEmpty () && str.Value ( 1 ) != TEXT( '#' ) ) {
+
+ if ( str.Value ( str.Length () ) == TEXT( '\\' ) ) {
+
+ str.Trunc ( str.Length () - 1 );
+ isNext = Standard_True;
+
+ } else
+
+ isNext = Standard_False;
+
+ if ( fNext )
+
+ retVal -> Value ( retVal -> Length () ) -> AssignCat ( str.ToCString () );
+
+ else
+
+ retVal -> Append ( new TCollection_HAsciiString ( str.ToCString () ) );
+
+ fNext = isNext;
+
+ } else
+
+ fNext = Standard_False;
+
+ } // end while
+
+ } // end else
+
+ Close ();
+
+ if ( Failed () ) {
+
+ Perror ();
+ RAISE();
+
+ } // end if
+
+ return retVal;
+
+} // end WOKNT_AdmFile :: Read
+
+TCollection_AsciiString WOKNT_AdmFile :: Name () const {
+
+ TCollection_AsciiString retVal;
+ OSD_Path path;
+
+ Path ( path );
+ path.SystemName ( retVal );
+
+ return retVal;
+
+} // end WOKNT_AdmFile :: Name
--- /dev/null
+-- File: WOKNT_CompareOfString.cdl
+-- Created: Wed Jul 31 11:31:03 1996
+-- Author: PLOTNIKOV Eugeny
+-- <eugeny@maniax>
+---Copyright: Matra Datavision 1996
+
+private class CompareOfString from WOKNT inherits
+ PrivCompareOfString from WOKNT
+
+ ---Purpose: defines string comparator class
+
+ uses
+
+ HAsciiString from TCollection
+
+ is
+
+ Create;
+ ---Purpose: creates a class instance
+
+ IsLower ( me; Left, Right : HAsciiString from TCollection )
+ returns Boolean from Standard is redefined;
+ ---Purpose: returns True if <Left> is lower than <Right>
+
+ IsGreater ( me; Left, Right : HAsciiString from TCollection )
+ returns Boolean from Standard is redefined;
+ ---Purpose: returns True if <Left> is greater than <Right>.
+
+ IsEqual ( me; Left, Right : HAsciiString from TCollection )
+ returns Boolean from Standard is redefined;
+ ---Purpose: returns True when <Right> and <Left> are equal.
+
+end CompareOfString;
--- /dev/null
+#include <WOKNT_CompareOfString.ixx>
+
+WOKNT_CompareOfString :: WOKNT_CompareOfString () {
+
+} // end constructor
+
+Standard_Boolean WOKNT_CompareOfString ::
+ IsLower (
+ const Handle( TCollection_HAsciiString )& Left,
+ const Handle( TCollection_HAsciiString )& Right
+ ) const {
+
+ return Left -> IsLess ( Right );
+
+} // end WOKNT_CompareOfString :: IsLower
+
+Standard_Boolean WOKNT_CompareOfString ::
+ IsGreater (
+ const Handle( TCollection_HAsciiString )& Left,
+ const Handle( TCollection_HAsciiString )& Right
+ ) const {
+
+ return Left -> IsGreater ( Right );
+
+} // end WOKNT_CompareOfString :: IsGreater
+
+Standard_Boolean WOKNT_CompareOfString ::
+ IsEqual (
+ const Handle( TCollection_HAsciiString )& Left,
+ const Handle( TCollection_HAsciiString )& Right
+ ) const {
+
+ return Left -> IsSameString ( Right );
+
+} // end WOKNT_CompareOfString :: IsEqual
+
--- /dev/null
+#define STRICT
+#include <windows.h>
+
+extern int wokCMP ( int, char** );
+
+__declspec( dllexport ) int wokCopyIfCh ( int argc, char** argv ) {
+
+ int status;
+ char* newArgs[ 3 ];
+
+ if ( argc != 3 ) return 2;
+
+ newArgs[ 0 ] = "wokCMP";
+ newArgs[ 1 ] = argv[ 1 ];
+ newArgs[ 2 ] = argv[ 2 ];
+
+ status = wokCMP ( 3, newArgs );
+
+ if ( status )
+
+ status = CopyFile ( argv[ 1 ], argv[ 2 ],FALSE ) ? 0 : 2;
+
+ return status;
+
+} /* end main */
--- /dev/null
+// File: WOKNT_Dword.hxx
+// Author: Jean GAUTIER
+// <jga@cobrax>
+
+
+#ifndef WOKNT_Dword_HeaderFile
+#define WOKNT_Dword_HeaderFile
+
+typedef unsigned long WOKNT_Dword;
+
+#endif
--- /dev/null
+// File: WOKUtils_Timeval.hxx
+// Author: Jean GAUTIER
+// <jga@cobrax>
+
+
+#ifndef WOKNT_FindData_HeaderFile
+#define WOKNT_FindData_HeaderFile
+
+#ifdef WNT
+#include <windows.h>
+
+typedef WIN32_FIND_DATA WOKNT_FindData;
+
+#ifdef CreateFile
+# undef CreateFile
+#endif // CreateFile
+
+#ifdef CreateDirectory
+# undef CreateDirectory
+#endif // CreateFile
+
+#ifdef RemoveDirectory
+# undef RemoveDirectory
+#endif // CreateFile
+
+
+
+
+#else
+
+
+typedef int WOKNT_FindData ;
+
+
+#endif
+
+#endif
--- /dev/null
+// File: WOKNT_Handle.hxx
+// Author: Jean GAUTIER
+// <jga@cobrax>
+
+
+#ifndef WOKNT_Handle_HeaderFile
+#define WOKNT_Handle_HeaderFile
+
+#ifdef WNT
+#include <windows.h>
+
+typedef HANDLE WOKNT_Handle ;
+
+#ifdef CreateFile
+# undef CreateFile
+#endif // CreateFile
+
+#ifdef CreateDirectory
+# undef CreateDirectory
+#endif // CreateFile
+
+#ifdef RemoveDirectory
+# undef RemoveDirectory
+#endif // CreateFile
+
+
+#else
+
+
+typedef int WOKNT_Handle ;
+
+
+#endif
+
+#endif
--- /dev/null
+-- File: WOKNT_MixedOutput.cdl
+-- Created: Tue Jul 30 10:19:51 1996
+-- Author: PLOTNIKOV Eugeny
+-- <eugeny@maniax>
+---Copyright: Matra Datavision 1996
+
+private class MixedOutput from WOKNT inherits ShellOutput from WOKNT
+
+ ---Purpose: manages output of sub-process ( creates a pipe ).
+ -- Standard output stream and standard error stream are MIXED.
+
+ uses
+
+ HSequenceOfHAsciiString from TColStd
+
+ is
+
+ Create returns MixedOutput from WOKNT;
+ ---Purpose: creates a class instance
+
+ Cleanup ( me : out ) is redefined virtual;
+ ---Purpose: dummy method to be used in derived class
+ ---C++: alias ~
+
+ OpenStdOut ( me : out ) returns Integer from Standard is redefined static;
+ ---Purpose: creates a pipe for reading a standard output of sub-process
+ -- and returns a pipe handle.
+ ---Warning: returns INVALID_HANDLE_VALUE in case of failure
+
+ CloseStdOut ( me : out ) is redefined static;
+ ---Purpose: closes write end of the 'STDOUT' pipe
+
+ OpenStdErr ( me : out ) returns Integer from Standard is virtual;
+ ---Purpose: creates a pipe for reading a standard error output of sub-process
+ -- and returns a pipe handle
+ ---Warning: this method is simply calling 'OpenStdOut' method
+
+ CloseStdErr ( me : out ) is redefined virtual;
+ ---Purpose: closes write end of the 'STDERR' pipe
+ ---Warning: this method is simply calling 'CloseStdOut' method
+
+ Clear ( me : out ) is redefined virtual;
+ ---Purpose: clears output buffer of sub-process
+
+ Echo ( me : out ) returns HSequenceOfHAsciiString from TColStd is redefined static;
+ ---Purpose: returns standard output of sub-process
+ ---Warning: returns NULL object if there is nothing to read
+
+ Errors ( me : out ) returns HSequenceOfHAsciiString from TColStd is redefined virtual;
+ ---Purpose: returns standard error output of sub-process
+ ---Warning: this method is simply calling 'Echo' method
+
+ SyncStdOut ( me : out ) returns HSequenceOfHAsciiString from TColStd is redefined static;
+ ---Purpose: waits for sub-process termination ( until the write end of pipe
+ -- will be closed ).
+ ---Warning: write end of pipe MUST BE CLOSED by parent process immediately
+ -- after creation of the child process else this method will
+ -- NEVER return. Use ONLY 'CloseStdOut' method for this purpose.
+
+ SyncStdErr ( me : out ) returns HSequenceOfHAsciiString from TColStd is redefined virtual;
+ ---Purpose: same as 'SyncStdOut' method
+ ---Warning: use 'CloseStdErr' method to close write end of pipe
+
+ fields
+
+ myOutHandle : Integer from Standard is protected;
+ myStdOut : HSequenceOfHAsciiString from TColStd is protected;
+
+end MixedOutput;
--- /dev/null
+#define STRICT
+#include <windows.h>
+
+#include <WOKNT_MixedOutput.ixx>
+
+#include <TCollection_HAsciiString.hxx>
+#include <OSD_WNT.h>
+
+#define MAX_LINE_LENGTH 2048
+
+void __fastcall _WOKNT_clear_pipe ( HANDLE );
+DWORD __fastcall _WOKNT_nb_to_read ( HANDLE );
+Handle( TColStd_HSequenceOfHAsciiString ) __fastcall _WOKNT_read_pipe ( OSD_File*, HANDLE );
+void __fastcall _WOKNT_create_pipe (
+ Standard_Integer*, Standard_Integer*
+ );
+
+WOKNT_MixedOutput :: WOKNT_MixedOutput () {
+
+} // end constructor
+
+void WOKNT_MixedOutput :: Cleanup () {
+
+ CloseStdOut ();
+ WOKNT_ShellOutput :: Cleanup ();
+
+} // end WOKNT_MixedOutput :: Cleanup
+
+Standard_Integer WOKNT_MixedOutput :: OpenStdOut () {
+
+ _WOKNT_create_pipe ( &myFileChannel, &myOutHandle );
+ myIO |= ( FLAG_PIPE | FLAG_READ_PIPE );
+
+ return myOutHandle;
+
+} // end WOKNT_MixedOutput :: OpenStdOut
+
+void WOKNT_MixedOutput :: CloseStdOut () {
+
+ if ( ( HANDLE )myOutHandle != INVALID_HANDLE_VALUE ) {
+
+ CloseHandle ( ( HANDLE )myOutHandle );
+ myOutHandle = ( Standard_Integer )INVALID_HANDLE_VALUE;
+
+ } // end if
+
+} // end WOKNT_MixedOutput :: CloseStdOut
+
+Standard_Integer WOKNT_MixedOutput :: OpenStdErr () {
+
+ return ( ( HANDLE )myOutHandle == INVALID_HANDLE_VALUE ) ?
+ OpenStdOut () : myOutHandle;
+
+} // end WOKNT_MixedOutput :: OpenStdErr
+
+void WOKNT_MixedOutput :: CloseStdErr () {
+
+ CloseStdOut ();
+
+} // end WOKNT_MixedOutput :: CloseStdErr
+
+void WOKNT_MixedOutput :: Clear () {
+
+ _WOKNT_clear_pipe ( ( HANDLE )myFileChannel );
+
+} // end WOKNT_MixedOutput :: Clear
+
+Handle( TColStd_HSequenceOfHAsciiString ) WOKNT_MixedOutput :: Echo () {
+
+ return _WOKNT_read_pipe ( this, ( HANDLE )myFileChannel );
+
+} // end WOKNT_MixedOutput :: Echo
+
+Handle( TColStd_HSequenceOfHAsciiString ) WOKNT_MixedOutput :: Errors () {
+
+ return Echo ();
+
+} // end WOKNT_MixedOutput :: Errors
+
+Handle( TColStd_HSequenceOfHAsciiString ) WOKNT_MixedOutput :: SyncStdOut () {
+
+ DWORD dummy;
+ Handle( TColStd_HSequenceOfHAsciiString ) retVal;
+
+ if ( ( HANDLE )myFileChannel != INVALID_HANDLE_VALUE ) {
+
+ while ( ReadFile ( ( HANDLE )myFileChannel, NULL, 0, ( LPDWORD )&dummy, NULL ) ) {
+
+ if ( retVal.IsNull () )
+
+ retVal = new TColStd_HSequenceOfHAsciiString ();
+
+ retVal -> Append ( Echo () );
+
+ } // end while
+
+ CloseStdOut ();
+
+ } // end if
+
+ return retVal;
+
+} // end WOKNT_MixedOutput :: SyncStdOut
+
+Handle( TColStd_HSequenceOfHAsciiString ) WOKNT_MixedOutput :: SyncStdErr () {
+
+ return SyncStdOut ();
+
+} // end WOKNT_MixedOutput :: SyncStdErr
+
+DWORD __fastcall _WOKNT_nb_to_read ( HANDLE hPipe ) {
+
+ DWORD retVal = 0;
+
+ PeekNamedPipe ( hPipe, NULL, 0, NULL, &retVal, NULL );
+
+ return retVal;
+
+} // end _WOKNT_nb_to_read
+
+void __fastcall _WOKNT_clear_pipe ( HANDLE hPipe ) {
+
+ PBYTE buffer = NULL;
+ DWORD dwBytesToRead;
+ DWORD dwBuffSize = 0;
+
+ while ( dwBytesToRead = _WOKNT_nb_to_read ( hPipe ) ) {
+
+ if ( dwBytesToRead > dwBuffSize ) {
+
+ if ( buffer != NULL ) delete [] buffer;
+
+ buffer = new BYTE[ dwBuffSize = dwBytesToRead ];
+
+ } // end if
+
+ ReadFile ( hPipe, buffer, dwBuffSize, &dwBytesToRead, NULL );
+
+ } // end while
+
+ if ( buffer != NULL ) delete [] buffer;
+
+} // end _WOKNT_clear_pipe
+
+Handle( TColStd_HSequenceOfHAsciiString ) __fastcall _WOKNT_read_pipe (
+ OSD_File* aFile, HANDLE hPipe
+ ) {
+
+ DWORD dwBytes;
+ DWORD dwBytesRead = 0;
+ Standard_Integer dummy;
+ TCollection_AsciiString aLine;
+ Handle( TColStd_HSequenceOfHAsciiString ) retVal =
+ new TColStd_HSequenceOfHAsciiString ();
+
+ while ( dwBytes = _WOKNT_nb_to_read ( hPipe ) ) {
+
+ dwBytesRead += dwBytes;
+
+ aFile -> ReadLine ( aLine, MAX_LINE_LENGTH, dummy );
+
+ retVal -> Append ( new TCollection_HAsciiString ( aLine ) );
+
+ } // end while
+
+ if ( dwBytesRead == 0 ) retVal.Nullify ();
+
+ return retVal;
+
+} // end _WOKNT_read_pipe
+
+void __fastcall _WOKNT_create_pipe (
+ Standard_Integer* readPipe, Standard_Integer* writePipe
+ ) {
+
+ SECURITY_ATTRIBUTES sa;
+
+ sa.nLength = sizeof ( SECURITY_DESCRIPTOR ); // structure size
+ sa.lpSecurityDescriptor = NULL; // default protection
+ sa.bInheritHandle = TRUE; // inheritable handle
+
+ if ( !CreatePipe (
+ ( PHANDLE )readPipe, // read end of the pipe
+ ( PHANDLE )writePipe, // write end of the pipe
+ &sa, // protection/inheritance
+ 4096 // buffer size
+ )
+ ) *writePipe = ( Standard_Integer )INVALID_HANDLE_VALUE;
+
+} // end _WOKNT_create_pipe
--- /dev/null
+-- File: WOKNT_OutErrOutput.cdl
+-- Created: Tue Jul 30 10:53:50 1996
+-- Author: PLOTNIKOV Eugeny
+-- <eugeny@maniax>
+---Copyright: Matra Datavision 1996
+
+private class OutErrOutput from WOKNT inherits MixedOutput from WOKNT
+
+ ---Purpose: manages output of sub-process ( creates a pipe ).
+ -- Standard output stream and standard error stream are MIXED.
+
+ uses
+
+ HSequenceOfHAsciiString from TColStd
+
+ is
+
+ Create returns OutErrOutput from WOKNT;
+ ---Purpose: creates a class instance
+
+ Cleanup ( me : out ) is redefined static;
+ ---Purpose: closes read end of the 'STDERR' handle
+ ---C++: alias ~
+
+ OpenStdErr ( me : out ) returns Integer from Standard is redefined static;
+ ---Purpose: creates a pipe for reading a standard error output of sub-process
+ -- and returns a pipe handle
+ ---Warning: returns INVALID_HANDLE_VALUE in case of failure
+
+ CloseStdErr ( me : out ) is redefined static;
+ ---Purpose: closes write end of the 'STDERR' pipe
+
+ Clear ( me : out ) is redefined static;
+ ---Purpose: clears output buffer of sub-process
+
+ Errors ( me : out ) returns HSequenceOfHAsciiString from TColStd is redefined static;
+ ---Purpose: returns standard error output of sub-process
+ ---Warning: returns NULL object if there is nothing to read
+
+ SyncStdErr ( me : out ) returns HSequenceOfHAsciiString from TColStd is redefined static;
+ ---Purpose: waits for sub-process termination ( until the write end of pipe
+ -- will be closed ).
+ ---Warning: write end of pipe MUST BE CLOSED by parent process immediately
+ -- after creation of the child process else this method will
+ -- NEVER return. Use ONLY 'CloseStdErr' method for this purpose.
+
+ fields
+
+ myErrHandleR : Integer from Standard;
+ myErrHandleW : Integer from Standard;
+ myStdErr : HSequenceOfHAsciiString from TColStd;
+
+end OutErrOutput;
--- /dev/null
+#define STRICT
+#include <windows.h>
+
+#include <WOKNT_OutErrOutput.ixx>
+
+#include <OSD_WNT.h>
+
+void __fastcall _WOKNT_clear_pipe ( HANDLE );
+DWORD __fastcall _WOKNT_nb_to_read ( HANDLE );
+Handle( TColStd_HSequenceOfHAsciiString ) __fastcall _WOKNT_read_pipe ( OSD_File*, HANDLE );
+void __fastcall _WOKNT_create_pipe (
+ Standard_Integer*, Standard_Integer*
+ );
+
+WOKNT_OutErrOutput :: WOKNT_OutErrOutput () {
+
+} // end constructor
+
+void WOKNT_OutErrOutput :: Cleanup () {
+
+ CloseStdOut ();
+ CloseStdErr ();
+
+ if ( ( HANDLE )myErrHandleR != INVALID_HANDLE_VALUE ) {
+
+ CloseHandle ( ( HANDLE )myErrHandleR );
+ myErrHandleR = ( Standard_Integer )INVALID_HANDLE_VALUE;
+
+ } // end if
+
+ WOKNT_ShellOutput :: Cleanup ();
+
+} // end WOKNT_OutErrOutput :: Cleanup
+
+Standard_Integer WOKNT_OutErrOutput :: OpenStdErr () {
+
+ _WOKNT_create_pipe ( &myErrHandleR, &myErrHandleW );
+ myIO |= ( FLAG_PIPE | FLAG_READ_PIPE );
+
+ return myErrHandleW;
+
+} // end WOKNT_OutErrOutput :: OpenStdErr
+
+void WOKNT_OutErrOutput :: CloseStdErr () {
+
+ if ( ( HANDLE )myErrHandleW != INVALID_HANDLE_VALUE ) {
+
+ CloseHandle ( ( HANDLE )myErrHandleW );
+ myErrHandleW = ( Standard_Integer )INVALID_HANDLE_VALUE;
+
+ } // end if
+
+} // end WOKNT_OutErrOutput :: CloseStdErr
+
+void WOKNT_OutErrOutput :: Clear () {
+
+ WOKNT_MixedOutput :: Clear ();
+
+ _WOKNT_clear_pipe ( ( HANDLE )myErrHandleR );
+
+} // end WOKNT_OutErrOutput :: Clear
+
+Handle( TColStd_HSequenceOfHAsciiString ) WOKNT_OutErrOutput :: Errors () {
+
+ Handle( TColStd_HSequenceOfHAsciiString ) retVal;
+ Standard_Integer handle;
+
+ handle = myFileChannel;
+ myFileChannel = myErrHandleR;
+
+ retVal = _WOKNT_read_pipe ( this, ( HANDLE )myFileChannel );
+
+ myFileChannel = handle;
+
+ return retVal;
+
+} // end WOKNT_OutErrOutput :: Errors
+
+Handle( TColStd_HSequenceOfHAsciiString ) WOKNT_OutErrOutput :: SyncStdErr () {
+
+ DWORD dummy;
+ Handle( TColStd_HSequenceOfHAsciiString ) retVal;
+
+ if ( ( HANDLE )myErrHandleR != INVALID_HANDLE_VALUE ) {
+
+ while ( ReadFile ( ( HANDLE )myErrHandleR, NULL, 0, ( LPDWORD )&dummy, NULL ) ) {
+
+ if ( retVal.IsNull () )
+
+ retVal = new TColStd_HSequenceOfHAsciiString ();
+
+ retVal -> Append ( Errors () );
+
+ } // end while
+
+ CloseStdErr ();
+ CloseHandle ( ( HANDLE )myErrHandleR );
+
+ } // end if
+
+ return retVal;
+
+} // end WOKNT_OutErrOutput :: SyncStdErr
--- /dev/null
+-- File: WOKNT_Path.cdl
+-- Created: Mon Jul 22 17:17:38 1996
+-- Author: PLOTNIKOV Eugeny
+-- <eugeny@maniax>
+---Copyright: Matra Datavision 1996
+
+class Path from WOKNT
+inherits TShared from MMgt
+
+ uses
+
+ Path from OSD,
+ TimeStat from WOKNT,
+ Extension from WOKNT,
+ Dword from WOKNT,
+ HAsciiString from TCollection
+
+ raises
+
+ OSDError from OSD
+
+ is
+
+ Create returns mutable Path from WOKNT;
+ ---Purpose: creates a class instance
+
+ Create( aPath : HAsciiString from TCollection )
+ returns mutable Path from WOKNT;
+ ---Purpose: creates a class instance
+
+ Create( aDir, aName : HAsciiString from TCollection )
+ returns mutable Path from WOKNT;
+ ---Purpose: creates a class instance
+
+ Create( aDir, aName : CString from Standard )
+ returns mutable Path from WOKNT;
+ ---Purpose: creates a class instance
+
+ CheckAttr(me:mutable) returns Boolean from Standard is private;
+ ---C++: inline
+
+ GetAttr(me:mutable)
+ returns Boolean from Standard is private;
+
+ Exists(me:mutable) returns Boolean from Standard;
+ ---Purpose: tests whether specified entity exists or not
+
+ CreateDirectory(me:mutable; fCreateParents : Boolean from Standard = Standard_False)
+ returns Boolean from Standard;
+ ---Purpose: creates a directory
+
+ CreateFile(me:mutable; fCreateParents : Boolean from Standard = Standard_False)
+ returns Boolean from Standard;
+ ---Purpose: creates a file
+
+ RemoveDirectory(me:mutable; fRemoveChilds : Boolean from Standard = Standard_False)
+ returns Boolean from Standard;
+ ---Purpose: removes a directory
+
+ RemoveFile(me:mutable)
+ returns Boolean from Standard;
+ ---Purpose: removes a file
+
+ MoveTo(me: mutable; aDestPath : Path from WOKNT )
+ returns Boolean from Standard;
+ ---Purpose: moves a file/directory to the new location
+ ---Warning: raises if the operation was failed
+
+ GetMDate(me: mutable ) returns TimeStat from WOKNT;
+ ---Purpose: returns last modification date of the file
+
+ Extension(me) returns Extension from WOKNT;
+ ---Purpose: returns a file extension
+
+ BaseName(me) returns HAsciiString from TCollection;
+ ---Purpose: returns a base name of full file name
+
+ DirName(me) returns HAsciiString from TCollection;
+ ---Purpose: returns path component of full file name
+
+ FileName(me) returns HAsciiString from TCollection;
+ ---Purpose: returns file name ( name.ext )
+
+ Name(me) returns HAsciiString from TCollection;
+ ---Purpose: returns full name
+ ---C++: return const &
+ ---C++: inline
+
+ MDate(me:mutable) returns TimeStat from WOKNT;
+ ---Purpose: returns known modification date of path
+ ---C++: inline
+
+ ResetMDate(me: mutable );
+ ---Purpose: resets modification date
+ ---C++: inline
+
+ IsOlder(me: mutable; aName : Path from WOKNT ) returns Boolean from Standard;
+ ---Purpose: compares last modification time of the file
+
+ IsNewer(me: mutable; aName : Path from WOKNT ) returns Boolean from Standard;
+ ---Purpose: compares last modification time of the file
+
+ IsDirectory(me:mutable)
+ returns Boolean from Standard;
+
+ IsFile(me:mutable) returns Boolean from Standard;
+ ---Purpose: checks whether 'myPath' is a file or not
+
+ IsSymLink(me:mutable) returns Boolean from Standard;
+ ---Purpose: checks whether specified file a symbolic link or not
+
+ ReducedPath(me)
+ returns Path from WOKNT;
+ ---Purpose: reduces Path as much as possible (reads links)
+
+ IsSameFile(me ; aPath : Path from WOKNT) returns Boolean from Standard;
+ ---Purpose:
+
+ IsWriteAble(me:mutable) returns Boolean from Standard;
+
+ ExtensionName(me) returns HAsciiString from TCollection;
+
+
+ fields
+
+ myPath : HAsciiString from TCollection;
+ myDate : TimeStat from WOKNT;
+ myAttr : Dword from WOKNT;
+ myAttrGet : Boolean from Standard;
+end Path;
--- /dev/null
+#define STRICT
+#include <windows.h>
+
+#ifdef THIS
+# undef THIS
+#endif
+
+#ifdef CreateFile
+# undef CreateFile
+#endif
+
+#ifdef CreateDirectory
+# undef CreateDirectory
+#endif
+
+#ifdef RemoveDirectory
+# undef RemoveDirectory
+#endif
+
+#include <WOKNT_Path.ixx>
+
+#include <WOKNT.hxx>
+#include <WOKNT_PathIterator.hxx>
+
+#include <WOKTools_Messages.hxx>
+//#include <OSD_File.hxx>
+//#include <OSD_Directory.hxx>
+//#include <OSD_Protection.hxx>
+
+#ifndef _INC_TCHAR
+# include <tchar.h>
+#endif // _INC_TCHAR
+
+#include <io.h>
+
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <share.h>
+
+extern "C" int wokCMP(int, char** );
+
+//static int _writeable(OSD_SingleProtection );
+
+WOKNT_Path::WOKNT_Path()
+: myAttrGet(Standard_False), myDate(-1)
+{
+}
+
+WOKNT_Path::WOKNT_Path(const Handle(TCollection_HAsciiString)& aPath)
+: myPath(aPath), myDate(-1), myAttrGet(Standard_False)
+{
+ myPath = aPath;
+ myDate = -1;
+}
+
+WOKNT_Path::WOKNT_Path(const Handle(TCollection_HAsciiString)& aDir, const Handle(TCollection_HAsciiString)& aName)
+: myDate(-1), myAttrGet(Standard_False)
+{
+ Handle(TCollection_HAsciiString) str = new TCollection_HAsciiString;
+
+ str->AssignCat(aDir);
+ str->AssignCat(TEXT("/"));
+ str->AssignCat(aName);
+
+ myPath = str;
+}
+
+WOKNT_Path::WOKNT_Path(const Standard_CString aDir, const Standard_CString aName)
+: myDate(-1), myAttrGet(Standard_False)
+{
+ Handle( TCollection_HAsciiString)str = new TCollection_HAsciiString;
+
+ str -> AssignCat(aDir );
+ str -> AssignCat( TEXT( "/") );
+ str -> AssignCat(aName );
+
+ myPath = str;
+}
+
+
+Standard_Boolean WOKNT_Path::GetAttr()
+{
+ if(myAttrGet) return Standard_True;
+ if(myPath.IsNull()) return Standard_False;
+ myAttrGet = Standard_True;
+ if((myAttr = GetFileAttributes( myPath -> ToCString())) != 0xFFFFFFFF)
+ return Standard_True;
+ else
+ return Standard_False;
+}
+
+Standard_Boolean WOKNT_Path::Exists()
+{
+ if(myPath.IsNull()) return Standard_False;
+ CheckAttr();
+ if(myAttr != 0xFFFFFFFF )
+ return Standard_True;
+ else
+ return Standard_False;
+}
+
+Standard_Boolean WOKNT_Path::CreateDirectory(const Standard_Boolean fCreateParents)
+{
+ if(Exists())
+ {
+ if(!IsDirectory())
+ {
+ ErrorMsg << TEXT( "WOKNT_Path::CreateDirectory (): ")<< myPath
+ << TEXT( " exists and is not a directory" )<< endm;
+ return Standard_False;
+ }
+ return Standard_True;
+ }
+
+ Handle(WOKNT_Path) aParent = new WOKNT_Path(DirName());
+
+ if(!aParent->Exists())
+ {
+ if(fCreateParents)
+ {
+ if(!aParent->CreateDirectory(fCreateParents))
+ return Standard_False;
+ }
+ else
+ {
+ ErrorMsg << TEXT( "WOKNT_Path::CreateDirectory")
+ << "Parent directory " << aParent->Name() << TEXT(" does not exist")<< endm;
+ return Standard_False;
+ }
+ }
+ else
+ {
+ if(!aParent->IsDirectory())
+ {
+ ErrorMsg << TEXT( "WOKNT_Path::CreateDirectory")
+ << "Parent " << aParent->Name() << TEXT(" exists and is not a directory")<< endm;
+ return Standard_False;
+ }
+ }
+
+#ifdef UNICODE
+# define CreateDirectory CreateDirectoryW
+#else
+# define CreateDirectory CreateDirectoryA
+#endif
+
+ if(CreateDirectory(myPath->ToCString(), NULL))
+ return Standard_True;
+ return Standard_False;
+
+#ifdef CreateFile
+# undef CreateFile
+#endif // CreateFile
+
+#ifdef CreateDirectory
+# undef CreateDirectory
+#endif // CreateFile
+
+#ifdef RemoveDirectory
+# undef RemoveDirectory
+#endif // CreateFile
+
+}
+
+Standard_Boolean WOKNT_Path::CreateFile(const Standard_Boolean fCreateParents)
+{
+ if(Exists())
+ {
+ if(IsDirectory())
+ {
+ ErrorMsg << TEXT( "WOKNT_Path::CreateFile" )
+ << myPath << TEXT( " exists and is a directory")<< endm;
+ return Standard_False;
+ }
+ return Standard_True;
+ }
+
+ Handle(WOKNT_Path) aParent = new WOKNT_Path(DirName());
+
+ if(aParent->Exists())
+ {
+ if(!aParent->IsDirectory())
+ {
+ ErrorMsg << TEXT( "WOKNT_Path::CreateFile" )
+ << TEXT("Parent diectory ")<< aParent->Name() << TEXT(" exists and is not a directory")<< endm;
+ return Standard_False;
+ }
+ }
+ else
+ {
+ aParent->CreateDirectory(fCreateParents);
+ }
+
+#ifdef UNICODE
+# define CreateFile CreateFileW
+#else
+# define CreateFile CreateFileA
+#endif
+
+ HANDLE theFile = CreateFile(myPath->ToCString(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+
+#ifdef CreateFile
+# undef CreateFile
+#endif // CreateFile
+
+
+ if(theFile == INVALID_HANDLE_VALUE)
+ {
+ ErrorMsg << TEXT( "WOKNT_Path::CreateFile")
+ << TEXT( "Creation of ") << myPath << " failed" << endm;
+ return Standard_False;
+ }
+ else
+ {
+ CloseHandle(theFile);
+ return Standard_True;
+ }
+}
+
+
+Standard_Boolean WOKNT_Path::RemoveDirectory(const Standard_Boolean fRemoveChilds)
+{
+
+ if( myPath.IsNull () )
+ {
+ ErrorMsg << TEXT( "WOKNT_Path ::RemoveDirectory (): " )
+ << TEXT( " invalid directory name(null )")<< endm;
+ return Standard_False;
+ }
+
+ Standard_Boolean isempty = Standard_True;
+
+ if(!fRemoveChilds)
+ {
+ WOKNT_PathIterator anit(this);
+
+ if(anit.More())
+ {
+ ErrorMsg << TEXT( "WOKNT_Path::RemoveDirectory" )
+ << TEXT( "Could not remove ")<< myPath << ": directory is not empty" << endm;
+ return Standard_False;
+ }
+ } else {
+
+ WOKNT_PathIterator anit(this);
+
+ while(anit.More())
+ {
+ Handle(WOKNT_Path) apath = anit.PathValue();
+
+ if(apath->IsDirectory())
+ {
+ if(!apath->RemoveDirectory(Standard_True)) isempty = Standard_False;
+ }
+ else
+ {
+ if(apath->RemoveFile()) isempty = Standard_False;
+ }
+ anit.Next();
+ }
+
+ } // end if
+
+ if(isempty)
+ {
+
+#ifdef UNICODE
+# define RemoveDirectory RemoveDirectoryW
+#else
+# define RemoveDirectory RemoveDirectoryA
+#endif
+ if(!RemoveDirectory(myPath->ToCString()))
+ {
+ ErrorMsg << TEXT( "WOKNT_Path::RemoveDirectory" )
+ << TEXT( "could not remove ") << myPath << ": " << WOKNT::SystemMessage(GetLastError()) << endm;
+ return Standard_False;
+ }
+#ifdef RemoveDirectory
+# undef RemoveDirectory
+#endif
+ }
+ else
+ {
+ ErrorMsg << TEXT( "WOKNT_Path::RemoveDirectory" )
+ << TEXT( "Could not empty ") << myPath << endm;
+ return Standard_False;
+ }
+ return Standard_True;
+}
+
+Standard_Boolean WOKNT_Path::RemoveFile()
+{
+ if( myPath.IsNull())
+ {
+ ErrorMsg << TEXT( "WOKNT_Path::RemoveFile" )
+ << TEXT( "Invalid file name(null )")<< endm;
+ return Standard_False;
+ }
+
+ if(!DeleteFile(myPath->ToCString()))
+ {
+ ErrorMsg << TEXT( "WOKNT::RemoveFile" )
+ << TEXT( "Failed to remove ") << myPath << ": " << WOKNT::SystemMessage(GetLastError()) << endm;
+ return Standard_False;
+ }
+ return Standard_True;
+}
+
+WOKNT_TimeStat WOKNT_Path::GetMDate () {
+
+ int fd;
+ struct _stat buffer;
+ BOOL fOK = FALSE;
+
+ __try {
+
+ if( ( fd = _sopen (
+ myPath -> ToCString (), _O_RDONLY, _SH_DENYNO
+ )
+ )== -1
+ ){
+
+ fOK = TRUE;
+ __leave;
+
+ } // end if
+
+ if( _fstat(fd, &buffer)== -1 )__leave;
+
+ fOK = TRUE;
+
+ } // end __try
+
+ __finally {
+
+ if(fd != -1)close(fd );
+
+ } // end __finally
+
+ if(!fOK )
+
+ OSD_OSDError::Raise( TEXT( "WOKNT_Path::GetMDate () failed") );
+
+ return myDate = buffer.st_mtime;
+
+} // end WOKNT_Path::GetMDate
+
+WOKNT_Extension WOKNT_Path::Extension () const {
+
+ Standard_CString ptr = _tcsrchr( myPath -> ToCString (), TEXT( '.') );
+
+ myPath -> RightAdjust ();
+
+ if(ptr++ != NULL){
+
+ if( _tcscmp( ptr, TEXT( "cdl" ))== 0 )return WOKNT_CDLFile;
+ if( _tcscmp( ptr, TEXT( "odl" ))== 0 )return WOKNT_ODLFile;
+ if( _tcscmp( ptr, TEXT( "idl" ))== 0 )return WOKNT_IDLFile;
+
+ if( _tcscmp( ptr, TEXT( "hxx" ))== 0 )return WOKNT_HXXFile;
+ if( _tcscmp( ptr, TEXT( "ixx" ))== 0 )return WOKNT_IXXFile;
+ if( _tcscmp( ptr, TEXT( "jxx" ))== 0 )return WOKNT_JXXFile;
+ if( _tcscmp( ptr, TEXT( "lxx" ))== 0 )return WOKNT_LXXFile;
+ if( _tcscmp( ptr, TEXT( "gxx" ))== 0 )return WOKNT_GXXFile;
+ if( _tcscmp( ptr, TEXT( "pxx" ))== 0 )return WOKNT_PXXFile;
+ if( _tcscmp( ptr, TEXT( "h" ))== 0 )return WOKNT_HFile;
+ if( _tcscmp( ptr, TEXT( "inc" ))== 0 )return WOKNT_INCFile;
+
+ if( _tcscmp( ptr, TEXT( "template"))== 0 )return WOKNT_TemplateFile;
+
+ if( _tcscmp( ptr, TEXT( "ddl" ))== 0 )return WOKNT_DDLFile;
+ if( _tcscmp( ptr, TEXT( "DB" ))== 0 )return WOKNT_DBFile;
+ if( _tcscmp( ptr, TEXT( "FDDB" ))== 0 )return WOKNT_FDDBFile;
+ if( _tcscmp( ptr, TEXT( "libshema"))== 0 )return WOKNT_LibSchemaFile;
+ if( _tcscmp( ptr, TEXT( "asdb" ))== 0 )return WOKNT_AppSchemaFile;
+ if( _tcscmp( ptr, TEXT( "ho2" ))== 0 )return WOKNT_HO2File;
+
+ if( _tcscmp( ptr, TEXT( "lex" ))== 0 )return WOKNT_LexFile;
+ if( _tcscmp( ptr, TEXT( "yacc" ))== 0 )return WOKNT_YaccFile;
+ if( _tcscmp( ptr, TEXT( "lws" ))== 0 )return WOKNT_LWSFile;
+ if( _tcscmp( ptr, TEXT( "psw" ))== 0 )return WOKNT_PSWFile;
+
+ if( _tcscmp( ptr, TEXT( "cxx" ))== 0 )return WOKNT_CXXFile;
+ if( _tcscmp( ptr, TEXT( "cpp" ))== 0 )return WOKNT_CXXFile;
+ if( _tcscmp( ptr, TEXT( "c" ))== 0 )return WOKNT_CFile;
+ if( _tcscmp( ptr, TEXT( "f" ))== 0 )return WOKNT_F77File;
+
+ if( _tcscmp( ptr, TEXT( "obj" ))== 0 )return WOKNT_ObjectFile;
+ if( _tcscmp( ptr, TEXT( "lib" ))== 0 )return WOKNT_LIBFile;
+ if( _tcscmp( ptr, TEXT( "imp" ))== 0 )return WOKNT_IMPFile;
+ if( _tcscmp( ptr, TEXT( "def" ))== 0 )return WOKNT_DEFile;
+ if( _tcscmp( ptr, TEXT( "pdb" ))== 0 )return WOKNT_PDBFile;
+ if( _tcscmp( ptr, TEXT( "dll" ))== 0 )return WOKNT_DLLFile;
+ if( _tcscmp( ptr, TEXT( "exe" ))== 0 )return WOKNT_EXEFile;
+ if( _tcscmp( ptr, TEXT( "exp" ))== 0 )return WOKNT_EXPFile;
+
+ if( _tcscmp( ptr, TEXT( "rc" ))== 0 )return WOKNT_RCFile;
+ if( _tcscmp( ptr, TEXT( "res" ))== 0 )return WOKNT_RESFile;
+
+ if( _tcscmp( ptr, TEXT( "dat" ))== 0 )return WOKNT_DATFile;
+ if( _tcscmp( ptr, TEXT( "xwd" ))== 0 )return WOKNT_IconFile;
+ if( _tcscmp( ptr, TEXT( "txt" ))== 0 )return WOKNT_TextFile;
+
+
+ if( _tcscmp( ptr, TEXT( "ll" ))== 0 )return WOKNT_LispFile;
+ if( _tcscmp( ptr, TEXT( "m" ))== 0 ) return WOKNT_MFile;
+
+ return WOKNT_UnknownFile;
+
+ } else
+
+ return WOKNT_NoExtFile;
+
+}
+
+Handle(TCollection_HAsciiString) WOKNT_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 == TEXT( '\\') || chr == TEXT( '/')) 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 == TEXT( '.')) break;
+ --pos;
+ }
+
+ if(pos)
+ retVal = retVal->SubString(1, pos-1);
+ return retVal;
+}
+
+Handle(TCollection_HAsciiString) WOKNT_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 == TEXT( '\\')|| chr == TEXT( '/'))
+ {
+ if(fRetry || pos != len) break;
+
+ retVal -> Trunc(pos - 1 );
+ fRetry = Standard_True;
+ }
+ --pos;
+ }
+
+ if(pos > 1 )
+ retVal -> Trunc(pos - 1 );
+ return retVal;
+}
+
+Handle( TCollection_HAsciiString)WOKNT_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 == TEXT( '\\') || chr == TEXT( '/'))
+ {
+ if(pos == retVal->Length())
+ {
+ retVal->Trunc(retVal->Length()-1);
+ }
+ else
+ break;
+ }
+ --pos;
+ }
+
+ if(pos)
+ retVal = retVal->SubString(pos+1, retVal->Length());
+ return retVal;
+}
+
+Handle( TCollection_HAsciiString)WOKNT_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 == TEXT( '.')) break;
+ --pos;
+ }
+
+ if(pos)
+ retVal = retVal->SubString(pos, retVal->Length());
+ return retVal;
+}
+
+Standard_Boolean WOKNT_Path::MoveTo(const Handle(WOKNT_Path)& aDestPath)
+{
+ if(!CheckAttr()) return Standard_False;
+
+ if(!(myAttr&FILE_ATTRIBUTE_DIRECTORY))
+ {
+ if (!MoveFileEx(myPath->ToCString (), aDestPath->Name()->ToCString (), MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED))
+ {
+ ErrorMsg << TEXT("WOKNT_Path::MoveTo")
+ << WOKNT::SystemMessage(GetLastError()) << endm;
+ ErrorMsg << TEXT("WOKNT_Path::MoveTo")
+ << TEXT("Failed to move ") << myPath << " to " << aDestPath->Name() << endm;
+ return Standard_False;
+ }
+ }
+ else
+ {
+ if (!MoveFileEx(myPath->ToCString (), aDestPath->Name()->ToCString (), MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED))
+ {
+ ErrorMsg << TEXT("WOKNT_Path::MoveTo")
+ << WOKNT::SystemMessage(GetLastError()) << endm;
+ ErrorMsg << TEXT("WOKNT_Path::MoveTo")
+ << TEXT("Failed to move ") << myPath << " to " << aDestPath->Name() << endm;
+ return Standard_False;
+ }
+ }
+ return Standard_True;
+}
+
+//=======================================================================
+//function : ReducedPath
+//purpose :
+//=======================================================================
+Handle(WOKNT_Path) WOKNT_Path::ReducedPath() const
+{
+ Handle(WOKNT_Path) areduced;
+ Handle(TCollection_HAsciiString) astr;
+
+ astr = new TCollection_HAsciiString(Name());
+ areduced = new WOKNT_Path(astr);
+ return areduced;
+}
+
+Standard_Boolean WOKNT_Path::IsSymLink ()
+{
+ // stupid question on NT
+ return Standard_False;
+}
+
+Standard_Boolean WOKNT_Path::IsOlder(const Handle(WOKNT_Path)& aName)
+{
+ return aName->MDate() > MDate();
+}
+
+Standard_Boolean WOKNT_Path::IsNewer(const Handle(WOKNT_Path)& aName)
+{
+ return aName -> MDate () < MDate ();
+}
+
+Standard_Boolean WOKNT_Path::IsSameFile(const Handle( WOKNT_Path )& aPath)const {
+
+ Standard_CString newArgs[ 3 ];
+
+ if(myPath.IsNull()) return Standard_False;
+ if(aPath.IsNull()) return Standard_False;
+ if(aPath->Name().IsNull()) return Standard_False;
+
+ newArgs[ 0 ] = "wokCMP";
+ newArgs[ 1 ] = myPath -> ToCString ();
+ newArgs[ 2 ] = aPath -> Name () -> ToCString ();
+
+ return !wokCMP(3, newArgs)? Standard_True : Standard_False;
+
+
+}
+
+Standard_Boolean WOKNT_Path::IsWriteAble () {
+ CheckAttr();
+ if(myAttr == 0xffffffff || myAttr & FILE_ATTRIBUTE_READONLY) return Standard_False;
+ return Standard_True;
+}
+
+Standard_Boolean WOKNT_Path::IsDirectory ()
+{
+ if(!CheckAttr()) return Standard_False;
+ if(myAttr & FILE_ATTRIBUTE_DIRECTORY) return Standard_True;
+ return Standard_False;
+}
+
+Standard_Boolean WOKNT_Path::IsFile ()
+{
+ if(!CheckAttr()) return Standard_False;
+ if(myAttr & FILE_ATTRIBUTE_DIRECTORY) return Standard_False;
+ return Standard_True;
+}
--- /dev/null
+#include <TCollection_HAsciiString.hxx>
+#include <WOKNT_TimeStat.hxx>
+
+inline const Handle(TCollection_HAsciiString)& WOKNT_Path::Name() const
+{
+ return myPath;
+}
+
+inline WOKNT_TimeStat WOKNT_Path :: MDate()
+{
+ if(myDate == -1) GetMDate();
+ return myDate;
+}
+
+inline void WOKNT_Path::ResetMDate()
+{
+ myDate = -1;
+}
+
+inline Standard_Boolean WOKNT_Path::CheckAttr ()
+{
+ if(myAttrGet) return Standard_True;
+ return GetAttr();
+}
--- /dev/null
+-- File: WOKNT_PathIterator.cdl
+-- Created: Mon Aug 03 15:37:45 1998
+-- Author:
+-- <jga@GROMINEX>
+---Copyright: Matra Datavision 1998
+
+
+class PathIterator from WOKNT
+
+
+uses
+ Boolean from Standard,
+ HAsciiString from TCollection,
+ AsciiString from TCollection,
+ FindData from WOKNT,
+ Handle from WOKNT,
+ StackOfHandle from WOKNT,
+ Path from WOKNT
+
+is
+
+
+ Create(apath : Path from WOKNT; recursive : Boolean from Standard = Standard_False; mask : CString from Standard = "*")
+ returns PathIterator from WOKNT;
+
+ SkipDots(me:out) is private;
+
+ Push(me:out; data : FindData from WOKNT; handle : Handle from WOKNT) is private;
+ Pop(me:out) is private;
+
+ IsDots(myclass; aname : CString from Standard)
+ returns Boolean from Standard is private;
+
+ Next(me:out);
+
+
+ PathValue(me)
+ returns Path from WOKNT;
+
+ LevelValue(me)
+ returns Integer from Standard;
+
+ NameValue(me)
+ returns HAsciiString from TCollection;
+
+ BrowsedPath(me)
+ returns Path from WOKNT;
+
+ More(me)
+ returns Boolean from Standard;
+
+ Destroy(me);
+ ---C++: alias operator~
+
+fields
+
+ mymask : AsciiString from TCollection;
+ mypath : Path from WOKNT;
+ mydata : FindData from WOKNT;
+ myStack : StackOfHandle from WOKNT;
+ mymore : Boolean from Standard;
+ myrecflag : Boolean from Standard;
+
+end;
+
--- /dev/null
+
+
+#include <WOKNT_PathIterator.ixx>
+#include <WOKNT_Path.hxx>
+
+#include <WOKTools_Messages.hxx>
+
+#include <stream.h>
+
+WOKNT_PathIterator::WOKNT_PathIterator(const Handle(WOKNT_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());
+
+ myStack.Push(FindFirstFile(mask.ToCString(), &mydata));
+ if(myStack.Top() == INVALID_HANDLE_VALUE )
+ mymore = Standard_False;
+ else
+ mymore = Standard_True;
+
+ SkipDots();
+}
+
+
+Standard_Boolean WOKNT_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 WOKNT_PathIterator::SkipDots()
+{
+ while(IsDots((Standard_CString)mydata.cFileName) && !myStack.IsEmpty())
+ {
+ if(!FindNextFile(myStack.Top(), &mydata))
+ {
+ if(GetLastError() == ERROR_NO_MORE_FILES)
+ {
+ if(!myStack.IsEmpty())
+ Pop();
+ else
+ mymore = Standard_False;
+ }
+ else
+ {
+ ErrorMsg << "WOKNT_PathIterator::Next"
+ << "Error occured in directory lookup : " << (int)GetLastError() << endm;
+ mymore = Standard_False;
+ }
+ }
+ }
+}
+
+
+void WOKNT_PathIterator::Push(const WOKNT_FindData& data, const WOKNT_Handle& handle)
+{
+ if(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY && myrecflag)
+ {
+ if(!IsDots(mydata.cFileName) && myrecflag)
+ {
+ mypath = new WOKNT_Path(mypath->Name(), new TCollection_HAsciiString(mydata.cFileName));
+ TCollection_AsciiString mask;
+ mask = mypath->Name()->String();
+ mask.AssignCat("/");
+ mask.AssignCat(mymask);
+
+ WOKNT_Handle nextone = FindFirstFile(mask.ToCString(), &mydata);
+ myStack.Push(nextone);
+ SkipDots();
+
+ if(!myStack.IsEmpty())
+ {
+ if(myStack.Top() == INVALID_HANDLE_VALUE )
+ mymore = Standard_False;
+ else
+ mymore = Standard_True;
+ }
+ else
+ mymore = Standard_False;
+ }
+ }
+ else
+ {
+ ErrorMsg << "WOKNT_PathIterator::Push"
+ << "Only a directory can be pushed in PathIterator" << endm;
+ }
+}
+
+void WOKNT_PathIterator::Pop()
+{
+ if(!myStack.IsEmpty())
+ {
+ FindClose(myStack.Top());
+ myStack.Pop();
+ if(!myStack.IsEmpty())
+ {
+ if(!FindNextFile(myStack.Top(), &mydata))
+ {
+ if(GetLastError() == ERROR_NO_MORE_FILES)
+ {
+ if(myStack.IsEmpty())
+ mymore = Standard_False;
+ else
+ Pop();
+ }
+ }
+ else
+ SkipDots();
+ mypath = new WOKNT_Path(mypath->DirName());
+ }
+ else
+ mymore = Standard_False;
+ }
+}
+
+
+void WOKNT_PathIterator::Next()
+{
+ if(myStack.Top()!=INVALID_HANDLE_VALUE && mymore)
+ {
+ if(!IsDots(mydata.cFileName) && mydata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY && myrecflag)
+ Push(mydata, myStack.Top());
+ else
+ {
+ if(!FindNextFile(myStack.Top(), &mydata))
+ {
+ if(GetLastError() == ERROR_NO_MORE_FILES)
+ {
+ if(!myStack.IsEmpty())
+ Pop();
+
+ if(myStack.IsEmpty())
+ mymore = Standard_False;
+ }
+ else
+ {
+ ErrorMsg << "WOKNT_PathIterator::Next"
+ << "Error occured in directory lookup : " << (int)GetLastError() << endm;
+ mymore = Standard_False;
+ }
+ }
+ }
+ }
+}
+
+Handle(WOKNT_Path) WOKNT_PathIterator::PathValue() const
+{
+ if(mydata.cFileName) return new WOKNT_Path(mypath->Name(), new TCollection_HAsciiString((char * const)mydata.cFileName));
+ return Handle(WOKNT_Path)();
+}
+
+Handle(TCollection_HAsciiString) WOKNT_PathIterator::NameValue() const
+{
+
+ if(mydata.cFileName) return new TCollection_HAsciiString((char * const)mydata.cFileName);
+ return Handle(TCollection_HAsciiString)();
+
+}
+
+Standard_Integer WOKNT_PathIterator::LevelValue() const
+{
+ return myStack.Depth();
+}
+
+Standard_Boolean WOKNT_PathIterator::More() const
+{
+ return mymore;
+}
+
+void WOKNT_PathIterator::Destroy() const
+{
+ if(myStack.Top() != INVALID_HANDLE_VALUE) FindClose(myStack.Top());
+}
+
--- /dev/null
+-- File: WOKNT_RegExp.cdl
+-- Created: Fri Aug 2 09:43:37 1996
+-- Author: PLOTNIKOV Eugeny
+-- <eugeny@maniax>
+---Copyright: Matra Datavision 1996
+
+class RegExp from WOKNT inherits TShared from MMgt
+
+ ---Purpose: provides regular expression matching and searching
+
+ uses
+
+ RESyntax from WOKNT,
+ HAsciiString from TCollection
+
+ raises
+
+ ProgramError from Standard
+
+ is
+
+ Create returns mutable RegExp from WOKNT;
+ ---Purpose: creates a class instance
+
+ Create (
+ aPattern : HAsciiString from TCollection;
+ aSyntax : RESyntax from WOKNT = WOKNT_RESyntaxAWK;
+ aTransTbl : Address from Standard = NULL;
+ aTblLen : Integer from Standard = 0
+ ) returns mutable RegExp from WOKNT
+ raises ProgramError from Standard;
+ ---Purpose: creates a class instance with given pattern that denotes a set
+ -- of strings. Defines a translation table <aTransTbl> and
+ -- its length <aTblLen> to perform character translation.
+ -- Supply NULL for <aTransTbl> and zero value for <aTblLen>
+ -- if no translation necessary. It is possible to set
+ -- syntax of the regular expression by meaning <aSyntax>
+ -- parameter.
+ ---Warning: raises if syntax of the regular expression given is incorrect
+
+ Destroy ( me : mutable );
+ ---Purpose: destroys all resources attached to the class instanse
+ ---C++: alias ~
+
+ SetPattern (
+ me : mutable;
+ aPattern : HAsciiString from TCollection;
+ aSyntax : RESyntax from WOKNT = WOKNT_RESyntaxAWK;
+ aTransTbl : Address from Standard = NULL;
+ aTblLen : Integer from Standard = 0
+ ) raises ProgramError from Standard;
+ ---Purpose: sets a new match pattern and possibly a new pattern syntax
+ ---Warning: raises if the syntax given is incorrect
+
+ Search (
+ me;
+ aString : HAsciiString from TCollection;
+ aStartPos : Integer from Standard = 1
+ ) returns Integer from Standard
+ raises ProgramError from Standard;
+ ---Purpose: searches a sub-string in the <aString> which matches
+ -- the specified pattern starting at index <aStartPos>.
+ -- Returns an index of the match position on success.
+ -- Returns -1 if no match was found.
+ -- Returns -2 if error was occur.
+ ---Warning: raises if no search pattern was set
+
+ Match (
+ me;
+ aString : HAsciiString from TCollection;
+ aStartPos : Integer from Standard = 1;
+ aStopPos : Integer from Standard = 1
+ ) returns Integer from Standard
+ raises ProgramError from Standard;
+ ---Purpose: match the pattern given against the string <aString>
+ -- starting at index <aStartPos>. Do not consider matching
+ -- past the position <aStopPos>.
+ -- Returns the length of the string matched on success.
+ -- Returns -1 if no match was found.
+ -- Returns -2 if error was occur.
+ ---Warning: raises if no search pattern was set
+
+ fields
+
+ myBuffer : Address from Standard;
+ myAlloc : Boolean from Standard;
+
+end RegExp;
--- /dev/null
+
+#include <WOKNT_RegExp.ixx>
+
+#include <WOKNT_regexp.h>
+
+#define BUFFER ( ( PRE_PATTERN_BUFFER )myBuffer )
+#define RAISE( str ) Standard_ProgramError :: Raise ( _TEXT( ( str ) ) );
+
+static _TCHAR errBuff[ 128 ];
+
+#ifndef WNT
+# define _tcscpy strcpy
+# define _tcscat strcat
+#endif //WNT
+
+WOKNT_RegExp :: WOKNT_RegExp ()
+: myBuffer(NULL), myAlloc(Standard_False)
+{
+} // end constructor ( 1 )
+
+WOKNT_RegExp :: WOKNT_RegExp (
+ const Handle( TCollection_HAsciiString )& aPattern,
+ const WOKNT_RESyntax aSyntax,
+ const Standard_Address aTransTbl,
+ const Standard_Integer aTblLen
+ )
+: myBuffer(NULL), myAlloc(Standard_False)
+{
+ SetPattern ( aPattern, aSyntax, aTransTbl, aTblLen );
+} // end constructro ( 2 )
+
+void WOKNT_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 WOKNT_RegExp :: Destroy
+
+void WOKNT_RegExp :: SetPattern (
+ const Handle( TCollection_HAsciiString )& aPattern,
+ const WOKNT_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 WOKNT_RESyntaxAWK:
+ syntax = RE_SYNTAX_AWK;
+ break;
+
+ case WOKNT_RESyntaxEGREP:
+ syntax = RE_SYNTAX_EGREP;
+ break;
+
+ case WOKNT_RESyntaxGREP:
+ syntax = RE_SYNTAX_GREP;
+ break;
+
+ case WOKNT_RESyntaxEMACS:
+ syntax = RE_SYNTAX_EMACS;
+ break;
+
+ default:
+ RAISE( "WOKNT_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( "WOKNT_RegExp (): error parsing specified pattern - " ) );
+ _tcscat ( errBuff, errMsg );
+
+ Standard_ProgramError :: Raise ( errBuff );
+
+ } // end if
+
+ re_compile_fastmap ( BUFFER );
+
+} // end WOKNT_RegExp :: SetPattern
+
+Standard_Integer WOKNT_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 WOKNT_RegExp :: Search
+
+Standard_Integer WOKNT_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 WOKNT_RegExp :: Match
+
--- /dev/null
+#define STRICT
+#include <process.h>
+#include <windows.h>
+
+extern int wokCMP ( int, char** );
+
+__declspec( dllexport ) int wokReplIfCh ( int argc, char** argv ) {
+
+ int status;
+ char* newArgs[ 3 ];
+
+ if ( argc != 3 ) return 2;
+
+ newArgs[ 0 ] = "wokCMP";
+ newArgs[ 1 ] = argv[ 1 ];
+ newArgs[ 2 ] = argv[ 2 ];
+
+ status = wokCMP ( 3, newArgs );
+
+ if ( status == 1 )
+
+ status = MoveFileEx (
+ argv[ 1 ], argv[ 2 ], MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING
+ ) ? 1 : 2;
+
+ DeleteFile ( argv[ 1 ] ) ? 0 : 2;
+
+ return status;
+
+} /* end main */
--- /dev/null
+#define STRICT
+#include <process.h>
+#include <windows.h>
+
+extern int wokCMP ( int, char** );
+
+__declspec( dllexport ) int wokReplIfChWith ( int argc, char** argv ) {
+
+ int status;
+ char* newArgs[ 3 ];
+
+ if ( argc != 4 ) return 2;
+
+ newArgs[ 0 ] = "wokCMP";
+ newArgs[ 1 ] = argv[ 1 ];
+ newArgs[ 2 ] = argv[ 2 ];
+
+ status = wokCMP ( 3, newArgs );
+
+ if ( status == 1 )
+
+ status = MoveFileEx (
+ argv[ 1 ], argv[ 3 ], MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING
+ ) ? 1 : 2;
+
+ DeleteFile ( argv[ 1 ] ) ? 0 : 2;
+
+ return status;
+
+} /* end main */
--- /dev/null
+-- File: WOKNT_Shell.cdl
+-- Created: Thu Jul 25 12:42:56 1996
+-- Author: PLOTNIKOV Eugeny
+-- <eugeny@maniax>
+---Copyright: Matra Datavision 1996
+
+class Shell from WOKNT inherits TShared from MMgt
+
+ ---Purpose: creates and manages processes
+
+ uses
+
+ ExecutionMode from WOKNT,
+ OutputMode from WOKNT,
+ Path from WOKNT,
+ Array1OfString from WOKNT,
+ HSequenceOfHAsciiString from TColStd,
+ HAsciiString from TCollection
+
+ is
+
+ Create (
+ anExecMode : ExecutionMode from WOKNT = WOKNT_SynchronousMode;
+ anOutMode : OutputMode from WOKNT = WOKNT_OutErrMixed
+ ) returns mutable Shell from WOKNT;
+ ---Purpose: creates a class instance
+
+ Destroy ( me : mutable );
+ ---Purpose: destrouys all resources attached to the Shell
+ ---C++: alias ~
+
+ Launch ( me : mutable );
+ ---Purpose: launches a process
+
+ IsLaunched ( me ) returns Boolean from Standard;
+ ---Purpose: checks whether a process launched or not
+ ---C++: inline
+
+ Kill ( me : mutable );
+ ---Purpose: terminates a process
+
+ Lock ( me : mutable );
+
+ UnLock ( me : mutable );
+
+ IsLocked ( me ) returns Boolean from Standard;
+ ---C++: inline
+
+ Status ( me ) returns Integer from Standard;
+ ---Purpose: returns process's exit status
+ ---C++: inline
+
+ Errors ( me : mutable ) returns HSequenceOfHAsciiString from TColStd;
+ ---Purpose: returns process output
+
+ ClearOutput ( me : mutable );
+ ---Purpose: clears process's output
+
+ Send ( me : mutable; aString : HAsciiString from TCollection );
+ ---Purpose: sends a string to the shell
+
+ Execute ( me : mutable; aCmdLine : HAsciiString from TCollection );
+ ---Purpose: executes a shell command
+
+ SyncAndStatus ( me : mutable ) returns Integer from Standard;
+ ---Purpose: waits for process termination and returns its exit status
+
+ BuiltInCommand (
+ me : mutable;
+ aCmd : in out HAsciiString from TCollection;
+ doParse : Boolean from Standard = Standard_True
+ ) returns Boolean from Standard is protected;
+ ---Purpose: checks whether a specified command built-in or not.
+ -- Also provides primary parsing of the commend line
+ -- ( extraction of the environment variables ).
+
+ BuildEnvironment ( me : mutable; aRebuildFlag : Boolean from Standard = Standard_False )
+ returns Address from Standard is protected;
+ ---Purpose: builds environment block for sub-process
+
+ AddEnvironmentVariable (
+ me : mutable;
+ aName : HAsciiString from TCollection;
+ aValue : HAsciiString from TCollection
+ );
+ ---Purpose: adds environment variable to the shell's environment block
+
+ RemoveEnvironmentVariable (
+ me : mutable;
+ aName : HAsciiString from TCollection
+ );
+ ---Purpose: removes specified variable from the shell's environment block
+
+ EnvironmentVariable ( me; aName : HAsciiString from TCollection )
+ returns HAsciiString from TCollection;
+ ---Purpose: returns a value for a given environment variable
+ ---Warning: returns a null string if specified variable does not exists
+
+ Echo ( me; aStr : HAsciiString from TCollection );
+ ---Purpose: echoes a string
+
+ SetEcho ( me : mutable );
+ ---Purpose: turns echo on
+ ---C++: inline
+
+ UnsetEcho ( me : mutable );
+ ---Purpose: turns echo off
+ ---C++: inline
+
+ Log ( me; aStr : HAsciiString from TCollection );
+ ---Purpose: logs a string to the file
+
+ LogInFile ( me : mutable; aPath : Path from WOKNT );
+ ---Purpose: creates log file and turns on logging to the file
+
+ NoLog ( me : mutable );
+ ---Purpose: turns off logging to file
+
+ fields
+
+ myOutMode : OutputMode from WOKNT;
+ myExecMode : ExecutionMode from WOKNT;
+ myStatus : Integer from Standard;
+ myLocked : Boolean from Standard;
+ myEcho : Boolean from Standard;
+ myExeFlag : Boolean from Standard;
+ myKillFlag : Boolean from Standard;
+ myOutput : Address from Standard;
+ myProcess : Integer from Standard;
+ myCmdLine : HAsciiString from TCollection;
+ myStdOut : HSequenceOfHAsciiString from TColStd;
+ myStdErr : HSequenceOfHAsciiString from TColStd;
+ myEnvironment : HSequenceOfHAsciiString from TColStd;
+ myChannel : Integer from Standard;
+ myDirectory : HAsciiString from TCollection;
+ myLogFile : Path from WOKNT;
+
+ friends
+
+ class ShellManager from WOKNT
+
+end Shell;
--- /dev/null
+#define STRICT
+#include <windows.h>
+#include <tchar.h>
+
+#ifdef CreateFile
+# undef CreateFile
+#endif // CreateFile
+
+#ifdef CreateDirectory
+# undef CreateDirectory
+#endif // CreateFile
+
+#ifdef RemoveDirectory
+# undef RemoveDirectory
+#endif // CreateFile
+
+#include <WOKNT_Shell.ixx>
+
+#include <WOKNT_OutErrOutput.hxx>
+#include <WOKTools_Messages.hxx>
+#include <OSD_Environment.hxx>
+#include <WOKNT_Array1OfString.hxx>
+#include <WOKNT_CompareOfString.hxx>
+#include <WOKNT_QuickSortOfString.hxx>
+
+#include <OSD_Exception_CTRL_BREAK.hxx>
+
+#pragma comment( lib, "user32.lib" )
+
+Standard_CString _WOKNT_get_last_error_text ( void );
+
+Standard_Integer __fastcall _WOKNT_find_environment_variable (
+ const Handle( TColStd_HSequenceOfHAsciiString )&,
+ const Handle( TCollection_HAsciiString )&
+ );
+
+static void _WOKNT_get_env ( Handle( TColStd_HSequenceOfHAsciiString )& );
+
+WOKNT_Shell :: WOKNT_Shell (
+ const WOKNT_ExecutionMode anExecMode,
+ const WOKNT_OutputMode anOutMode
+ ) {
+
+ char aDir[1024];\r
+\r
+ GetCurrentDirectory(1024, aDir);\r
+
+ myDirectory = new TCollection_HAsciiString ( aDir );
+
+ myOutput = ( anOutMode == WOKNT_OutErrMixed ) ?
+ new WOKNT_MixedOutput () :
+ new WOKNT_OutErrOutput ();
+ myCmdLine = new TCollection_HAsciiString ();
+ myProcess = ( Standard_Integer )INVALID_HANDLE_VALUE;
+ myLocked = Standard_False;
+ myExecMode = anExecMode;
+ myOutMode = anOutMode;
+ myEcho = Standard_False;
+
+ _WOKNT_get_env ( myEnvironment );
+
+} // end constructor
+
+void WOKNT_Shell :: Destroy () {
+
+ Kill ();
+
+ delete myOutput;
+
+} // end WOKNT_Shell :: Destroy
+
+void WOKNT_Shell :: Launch () {
+
+} // end WOKNT_Shell :: Launch
+
+void WOKNT_Shell :: Kill () {
+
+ if ( ( HANDLE )myProcess != INVALID_HANDLE_VALUE ) {
+
+ TerminateProcess ( ( HANDLE )myProcess, ( UINT )-1 );
+
+ if ( ( HANDLE )myChannel != INVALID_HANDLE_VALUE ) {
+
+ CloseHandle ( ( HANDLE )myChannel );
+ myChannel = ( Standard_Integer )INVALID_HANDLE_VALUE;
+
+ } // end if
+
+ myKillFlag = Standard_True;
+
+ } // end if
+
+} // end WOKNT_Shell :: Kill
+
+void WOKNT_Shell :: Lock () {
+
+ myLocked = Standard_True;
+
+} // end WOKNT_Shell :: Lock
+
+void WOKNT_Shell :: UnLock () {
+
+ myLocked = Standard_False;
+
+} // end WOKNT_Shell :: UnLock
+
+void WOKNT_Shell :: ClearOutput () {
+
+ ( ( WOKNT_ShellOutput* )myOutput ) -> Clear ();
+
+if ( !myStdOut.IsNull () ) myStdOut.Nullify ();
+if ( !myStdErr.IsNull () ) myStdErr.Nullify ();
+
+} // end WOKNT_Shell :: ClearOutput
+
+void WOKNT_Shell :: Execute ( const Handle( TCollection_HAsciiString )& aCmdLine ) {
+
+ int i, numCmd;
+
+ if ( !myExeFlag ) {
+
+ Echo ( aCmdLine );
+ Log ( aCmdLine );
+
+ } else
+
+
+#ifdef WOK_VERBOSE
+ VerboseMsg("WOK_COMMAND") << "WOKNT_Shell::Execute" << aCmdLine << endm;
+#endif
+
+
+ myExeFlag = Standard_False;
+
+ myKillFlag = Standard_False;
+
+ Handle( TCollection_HAsciiString ) aCommandLine = new TCollection_HAsciiString ();
+
+ if ( !myCmdLine.IsNull () ) aCommandLine = myCmdLine;
+
+ aCommandLine -> AssignCat ( aCmdLine );
+
+ if ( !aCmdLine.IsNull () &&
+ !aCmdLine -> IsEmpty () &&
+ !BuiltInCommand ( aCommandLine ) &&
+ ( HANDLE )myProcess == INVALID_HANDLE_VALUE
+ ) {
+
+ PROCESS_INFORMATION pi;
+ STARTUPINFO si;
+ HANDLE hStdInput;
+ BOOL fRetry;
+ HANDLE hStdOut;
+ HANDLE hStdErr;
+ SECURITY_ATTRIBUTES sa;
+ LPVOID env;
+ Handle( TCollection_HAsciiString ) cmd = new TCollection_HAsciiString (
+ aCommandLine -> String ()
+ );
+
+ sa.nLength = sizeof ( SECURITY_ATTRIBUTES );
+ sa.lpSecurityDescriptor = NULL;
+ sa.bInheritHandle = TRUE;
+
+ if ( !CreatePipe (
+ &hStdInput, ( PHANDLE )&myChannel, &sa, 0
+ )
+ ) {
+
+ hStdInput = INVALID_HANDLE_VALUE;
+ myChannel = ( Standard_Integer )INVALID_HANDLE_VALUE;
+
+ } // end if
+
+ Handle( TColStd_HSequenceOfHAsciiString ) cmdSeq = new TColStd_HSequenceOfHAsciiString ();
+
+ i = 1;
+
+ while ( TRUE ) {
+
+ aCommandLine = cmd -> Token ( _TEXT( "\x01" ), i++ );
+
+ if ( aCommandLine -> IsEmpty () ) break;
+
+ cmdSeq -> Append ( aCommandLine );
+
+ } // end while
+
+ numCmd = cmdSeq -> Length ();
+
+ if ( myStdOut.IsNull () ) myStdOut = new TColStd_HSequenceOfHAsciiString ();
+ if ( myStdErr.IsNull () ) myStdErr = new TColStd_HSequenceOfHAsciiString ();
+
+ env = BuildEnvironment ();
+
+ for ( i = 1; i <= numCmd; ++i ) {
+
+ cmd = new TCollection_HAsciiString ( cmdSeq -> Value ( i ) );
+
+ if (
+ BuiltInCommand ( cmd, Standard_False ) ||
+ cmd -> Value ( 1 ) == TEXT( '@' ) && myStatus
+ ) continue;
+
+ if ( cmd -> Value ( 1 ) == TEXT( '@' ) ) cmd -> Remove ( 1 );
+
+ hStdOut = ( HANDLE )( ( WOKNT_ShellOutput* )myOutput ) -> OpenStdOut ();
+ hStdErr = ( HANDLE )( ( WOKNT_ShellOutput* )myOutput ) -> OpenStdErr ();
+
+ ZeroMemory ( &si, sizeof ( STARTUPINFO ) );
+ si.cb = sizeof ( STARTUPINFO );
+ si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
+ si.wShowWindow = SW_HIDE;
+ si.hStdInput = hStdInput;
+ si.hStdOutput = hStdOut;
+ si.hStdError = hStdErr;
+
+ fRetry = FALSE;
+
+ while ( TRUE ) {
+
+ if ( !CreateProcess (
+ NULL, // image name
+ cmd -> ToCString (), // command line
+ NULL, // security attributes for process ( default )
+ NULL, // security attributes for primary thread ( default )
+ TRUE, // handle inheritance
+ NORMAL_PRIORITY_CLASS, // normal process with no special scheduling needs
+ env, // environment
+ myDirectory -> ToCString (), // current directory
+ &si, // startup information
+ &pi // process information
+ )
+ ) {
+
+ if ( fRetry || GetLastError () != ERROR_FILE_NOT_FOUND ) {
+
+ ErrorMsg << TEXT( "WOKNT_Shell :: Execute (): can not execute " )
+ << TEXT( "'" ) << cmd -> ToCString () << TEXT( "' - " )
+ << _WOKNT_get_last_error_text () << endm;
+
+ myProcess = ( Standard_Integer )INVALID_HANDLE_VALUE;
+ ( ( WOKNT_ShellOutput* )myOutput ) -> Cleanup ();
+ myStatus = -1;
+
+ break;
+
+ } else {
+
+ OSD_Environment comSpec ( TEXT( "ComSpec" ) );
+
+ aCommandLine = cmdSeq -> Value ( i );
+ cmd -> Clear ();
+
+ if ( comSpec.Failed () )
+
+ cmd -> AssignCat ( TEXT( "cmd.exe" ) );
+
+ else
+
+ cmd -> AssignCat( comSpec.Value ().ToCString () );
+
+ cmd -> AssignCat ( TEXT( " /C " ) );
+ cmd -> AssignCat ( aCommandLine -> ToCString () );
+ fRetry = TRUE;
+
+ } // end else
+
+ } else {
+
+ CloseHandle ( pi.hThread );
+ myProcess = ( Standard_Integer )pi.hProcess;
+
+ if ( myExecMode == WOKNT_SynchronousMode ||
+ numCmd > 1 && i < numCmd
+ ) SyncAndStatus ();
+
+ break;
+
+ } // end else
+
+ } // end while
+
+ } // end for
+
+ CloseHandle ( hStdInput );
+ delete [] env;
+
+ } // end if
+
+ if ( myKillFlag && myStatus == -1 )
+
+ OSD_Exception_CTRL_BREAK :: Raise ( TEXT( "*** INTERRUPT ***" ) );
+
+ myCmdLine -> Clear ();
+
+} // end WOKNT_Shell :: Execute
+
+void WOKNT_Shell :: Send ( const Handle(TCollection_HAsciiString)& aString ) {
+
+ Standard_Integer i;
+ DWORD dwBytesWritten;
+
+
+#ifdef WOK_VERBOSE
+ VerboseMsg("WOK_COMMAND") << "WOKNT_Shell::Send" << aString << endm;
+#endif
+
+ myCmdLine -> AssignCat ( aString );
+
+ if ( !myCmdLine.IsNull () &&
+ myCmdLine -> Value ( myCmdLine -> Length () ) == TEXT( '\n' ) &&
+ myCmdLine -> Value ( myCmdLine -> Length () - 1 ) != TEXT( '\\' )
+ ) {
+
+ Echo ( myCmdLine );
+ Log ( myCmdLine );
+
+ myCmdLine -> Trunc ( myCmdLine -> Length () - 1 );
+
+ if ( ( HANDLE )myProcess == INVALID_HANDLE_VALUE ) {
+
+ i = 1;
+ myExeFlag = Standard_True;
+ Handle( TCollection_HAsciiString ) cmd;
+
+ while ( TRUE ) {
+
+ cmd = myCmdLine -> Token ( _TEXT( "\n" ), i++ );
+
+ if ( cmd -> IsEmpty () ) break;
+
+ Execute ( cmd );
+
+ } // end while
+
+ } else
+
+ WriteFile ( // send a string to the sub-process
+ ( HANDLE )myChannel, myCmdLine -> ToCString (), myCmdLine -> Length (),
+ &dwBytesWritten, NULL
+ );
+
+ myCmdLine -> Clear ();
+
+ } // end if
+
+} // end WOKNT_Shell :: Send
+
+Standard_Integer WOKNT_Shell :: SyncAndStatus () {
+
+ Handle( TColStd_HSequenceOfHAsciiString ) stdOut;
+ Handle( TColStd_HSequenceOfHAsciiString ) stdErr;
+
+ if ( ( HANDLE )myProcess != INVALID_HANDLE_VALUE ) {
+
+ ( ( WOKNT_ShellOutput* )myOutput ) -> CloseStdOut ();
+ ( ( WOKNT_ShellOutput* )myOutput ) -> CloseStdErr ();
+
+ if ( myStdOut.IsNull () ) myStdOut = new TColStd_HSequenceOfHAsciiString ();
+ if ( myStdErr.IsNull () ) myStdErr = new TColStd_HSequenceOfHAsciiString ();
+
+ stdOut = ( ( WOKNT_ShellOutput* )myOutput ) -> SyncStdOut ();
+ stdErr = myOutMode == WOKNT_OutErrMixed ?
+ stdOut :
+ ( ( WOKNT_ShellOutput* )myOutput ) -> SyncStdErr ();
+
+ if ( !stdOut.IsNull () ) myStdOut -> Append ( stdOut );
+ if ( !stdErr.IsNull () ) myStdErr -> Append ( stdErr );
+
+ ( ( WOKNT_ShellOutput* )myOutput ) -> Cleanup ();
+
+ WaitForSingleObject ( ( HANDLE )myProcess, INFINITE );
+
+ GetExitCodeProcess ( ( HANDLE )myProcess, ( LPDWORD )&myStatus );
+ CloseHandle ( ( HANDLE )myProcess );
+ CloseHandle ( ( HANDLE )myChannel );
+ myProcess = ( Standard_Integer )INVALID_HANDLE_VALUE;
+ myChannel = ( Standard_Integer )INVALID_HANDLE_VALUE;
+
+ } // end if
+
+ return myStatus;
+
+} // end WOKNT_Shell :: SyncAndStatus
+
+Handle( TColStd_HSequenceOfHAsciiString ) WOKNT_Shell :: Errors () {
+
+ Handle( TColStd_HSequenceOfHAsciiString ) retVal =
+ myStdErr.IsNull () ? ( ( WOKNT_ShellOutput* )myOutput ) -> Errors () : myStdErr;
+
+ return retVal.IsNull () ? new TColStd_HSequenceOfHAsciiString () : retVal;
+
+} // end WOKNT_Shell :: Errors
+
+Standard_Address WOKNT_Shell :: BuildEnvironment (
+ const Standard_Boolean aRebuildFlag
+ ) {
+
+ if ( aRebuildFlag ) {
+
+ myEnvironment.Nullify ();
+
+ _WOKNT_get_env ( myEnvironment );
+
+ return NULL;
+
+ } else {
+
+ int i;
+ Standard_CString retVal;
+ Standard_CString ptr;
+ Standard_Integer len = 0;
+ WOKNT_CompareOfString comp;
+ WOKNT_Array1OfString env ( 1, myEnvironment -> Length () );
+
+ for ( i = 1; i <= myEnvironment -> Length (); ++i ) {
+
+ len += ( lstrlen ( myEnvironment -> Value ( i ) -> ToCString () ) + 1 );
+ env.SetValue ( i, myEnvironment -> Value ( i ) );
+
+ } // end for
+
+ WOKNT_QuickSortOfString :: Sort ( env, comp );
+
+ retVal = ptr = new Standard_Character[ ++len ];
+
+ for ( i = env.Lower (); i <= env.Upper (); ++i ) {
+
+ lstrcpy ( ptr, env.Value ( i ) -> ToCString () );
+ ptr += ( lstrlen ( ptr ) + 1 );
+
+ } // end for
+
+ *ptr = TEXT( '\x00' );
+
+ return retVal;
+
+ } // end else
+
+} // end WOKNT_Shell :: BuildEnvironment
+
+void WOKNT_Shell :: AddEnvironmentVariable (
+ const Handle_TCollection_HAsciiString& aName,
+ const Handle_TCollection_HAsciiString& aValue
+ ) {
+
+ Handle( TCollection_HAsciiString ) str = new TCollection_HAsciiString ();
+
+ str -> AssignCat ( aName -> String ().ToCString () );
+
+ RemoveEnvironmentVariable ( str );
+
+ str -> AssignCat ( TEXT( "=" ) );
+ str -> AssignCat ( aValue );
+ myEnvironment -> Prepend ( str );
+
+} // end WOKNT_Shell :: AddEnvironmentVariable
+
+void WOKNT_Shell :: RemoveEnvironmentVariable (
+ const Handle_TCollection_HAsciiString& aName
+ ) {
+
+ Standard_Integer i;
+
+ if ( i = _WOKNT_find_environment_variable ( myEnvironment, aName ) )
+
+ myEnvironment -> Remove ( i );
+
+} // end WOKNT_Shell :: RemoveEnvironmentVariabl
+
+Handle( TCollection_HAsciiString )
+ WOKNT_Shell :: EnvironmentVariable ( const Handle_TCollection_HAsciiString& aName ) const {
+
+ Standard_Integer i;
+ Handle( TCollection_HAsciiString ) retVal;
+
+ if ( i = _WOKNT_find_environment_variable ( myEnvironment, aName ) )
+
+ retVal = myEnvironment -> Value ( i ) -> Token ( _TEXT( "=" ), 2 );
+
+ return retVal;
+
+} // end WOKNT_Shell :: EnvironmentVariable
+
+void WOKNT_Shell :: Echo ( const Handle_TCollection_HAsciiString& aStr ) const {
+
+ if ( myEcho ) {
+
+ WOKTools_Info shellInfo = InfoMsg;
+
+ shellInfo.Init ();
+ shellInfo.DontPrintHeader ();
+ shellInfo.DontPrintContext ();
+
+ shellInfo << TEXT( "WOKNT_Shell :: Echo ()" ) << aStr << endm;
+
+ } // end if
+
+} // end WOKNT_Shell :: Echo
+
+void WOKNT_Shell :: Log ( const Handle_TCollection_HAsciiString& aStr ) const {
+
+ if ( !myLogFile.IsNull () ) {
+
+ ofstream logFile ( myLogFile -> Name () -> ToCString (), ios :: app );
+
+ if ( logFile.good () ) {
+
+ logFile << aStr -> ToCString ();
+ logFile.close ();
+
+ } // end if
+
+ } // end if
+
+} // end WOKNT_Shell :: Log
+
+void WOKNT_Shell :: LogInFile ( const Handle_WOKNT_Path& aPath ) {
+
+ if ( !aPath.IsNull () ) {
+
+ if ( !aPath -> Exists () ) {
+
+ aPath -> CreateFile ( Standard_True );
+
+ if ( aPath -> Exists () )
+
+ myLogFile = aPath;
+
+ } // end if
+
+ } // end if
+
+} // end WOKNT_Shell :: LogInFile
+
+void WOKNT_Shell :: NoLog () {
+
+ myLogFile.Nullify ();
+
+} // end WOKNT_Shell :: NoLog
+
+Standard_CString _WOKNT_get_last_error_text ( void ) {
+
+ static Standard_Character buffer[ 2048 ];
+
+ DWORD errCode = GetLastError ();
+
+ if ( !FormatMessage (
+ FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY,
+ 0, errCode, MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL ),
+ buffer, 2048, NULL
+ )
+ ) {
+
+ wsprintf ( buffer, TEXT( "error code %d" ), errCode );
+ SetLastError ( errCode );
+
+ } // end if
+
+ return buffer;
+
+} // end _get_last_error_text
+
+Standard_Integer __fastcall _WOKNT_find_environment_variable (
+ const Handle( TColStd_HSequenceOfHAsciiString )& envBlock,
+ const Handle( TCollection_HAsciiString )& envVar
+ ) {
+
+ Standard_Integer retVal = 0;
+
+ Handle( TCollection_HAsciiString ) str = new TCollection_HAsciiString ();
+
+ str -> AssignCat ( envVar -> String ().ToCString () );
+ str -> AssignCat ( TEXT( "=" ) );
+ str -> LeftAdjust ();
+
+ for ( int i = 1; i <= envBlock -> Length (); ++i )
+
+ if ( envBlock -> Value ( i ) -> Search ( str ) == 1 ) {
+
+ retVal = i;
+ break;
+
+ } // end if
+
+ return retVal;
+
+} // end _WOKNT_find_environment_variable
+
+static void _WOKNT_get_env ( Handle( TColStd_HSequenceOfHAsciiString )& seq ) {
+
+ Standard_CString ptr, env;
+
+ seq = new TColStd_HSequenceOfHAsciiString ();
+
+ env = ptr = ( Standard_CString )GetEnvironmentStrings ();
+
+ if ( *ptr != TEXT( '\x00' ) )
+
+ do {
+
+ seq -> Append ( new TCollection_HAsciiString ( ptr ) );
+ ptr += ( lstrlen ( ptr ) + 1 );
+
+ } while ( *ptr != TEXT( '\x00' ) );
+
+ FreeEnvironmentStrings ( env );
+
+} // end _WOKNT_get_env
--- /dev/null
+#include <WOKNT_ShellOutput.hxx>
+
+inline Standard_Boolean WOKNT_Shell :: IsLaunched () const {
+
+ return Standard_True;
+
+} // end WOKNT_Shell :: IsLaunched
+
+inline Standard_Integer WOKNT_Shell :: Status () const {
+
+ return myStatus;
+
+} // end WOKNT_Shell :: Status
+
+inline Standard_Boolean WOKNT_Shell :: IsLocked () const {
+
+ return myLocked;
+
+} // end WOKNT_Shell :: IsLocked
+
+inline void WOKNT_Shell :: SetEcho () {
+
+ myEcho = Standard_True;
+
+} // end WOKNT_Shell :: SetEcho
+
+inline void WOKNT_Shell :: UnsetEcho () {
+
+ myEcho = Standard_False;
+
+} // end WOKNT_Shell :: UnsetEcho
--- /dev/null
+-- File: WOKNT_ShellManager.cdl
+-- Created: Fri Jul 26 17:33:13 1996
+-- Author: PLOTNIKOV Eugeny
+-- <eugeny@maniax>
+---Copyright: Matra Datavision 1996
+
+class ShellManager from WOKNT
+
+ ---Purpose: shell management
+
+ uses
+
+ Shell from WOKNT,
+ SequenceOfShell from WOKNT
+
+ ---raises
+ --- Exception_CTRL_BREAK from OSD
+
+ is
+
+ GetShell ( myclass ) returns Shell from WOKNT;
+ ---Purpose: returns one unlocked shell of processes list
+
+ Arm ( myclass );
+ ---Purpose: sets signal handlers
+
+ UnArm ( myclass );
+ ---Purpose: unsets signal handlers
+
+ KillAll ( myclass );
+ ---Purpose: Terminates all active sub-processes
+
+ Break ( myclass ) ;
+ ---raises OSD_Exception_CTRL_BREAK from OSD;
+ ---Purpose: Checks whethes CTRL-BREAK keystroke was or not.
+ -- if yes then raises
+
+end ShellManager;
--- /dev/null
+#define STRICT
+#include <windows.h>
+#include <tchar.h>
+
+
+#include <OSD_Exception_CTRL_BREAK.hxx>
+
+#include <WOKNT_ShellManager.ixx>
+
+#include <WOKNT_Shell.hxx>
+#include <WOKNT_SequenceOfShell.hxx>
+
+static BOOL s_fCtrlBreak;
+
+static WOKNT_SequenceOfShell shells;
+
+static BOOL CALLBACK interruptHandler ( DWORD );
+
+Handle( WOKNT_Shell ) WOKNT_ShellManager :: GetShell () {
+
+ Standard_Integer i;
+ Handle( WOKNT_Shell ) aShell;
+
+ for ( i = 1; i <= shells.Length (); i++ ) {
+
+ aShell = shells.Value ( i );
+
+ if ( !aShell -> IsLocked () ) {
+
+ aShell -> BuildEnvironment ( Standard_True );
+
+ return aShell;
+
+ } // end if
+
+ } // end for
+
+ aShell = new WOKNT_Shell ();
+
+ shells.Append ( aShell );
+
+ aShell -> BuildEnvironment ( Standard_True );
+
+ return aShell;
+
+} // end WOKNT_ShellManager :: GetShell
+
+void WOKNT_ShellManager :: Arm () {
+
+ s_fCtrlBreak = FALSE;
+ SetConsoleCtrlHandler ( &interruptHandler, TRUE );
+
+} // end WOKNT_ShellManager :: Arm
+
+void WOKNT_ShellManager :: UnArm () {
+
+ SetConsoleCtrlHandler ( &interruptHandler, FALSE );
+
+} // end WOKNT_ShellManager :: UnArm
+
+void WOKNT_ShellManager :: KillAll () {
+
+ for ( Standard_Integer i = 1; i <= shells.Length (); ++i )
+
+ shells.Value ( i ) -> Kill ();
+
+ shells.Clear ();
+
+} // end WOKNT_ShellManager :: KillAll
+
+void WOKNT_ShellManager :: Break () {
+
+ if ( s_fCtrlBreak ) {
+
+ s_fCtrlBreak = FALSE;
+
+ OSD_Exception_CTRL_BREAK :: Raise ( TEXT( "*** INTERRUPT ***" ) );
+
+ } // end if
+
+} // end WOKNT_ShellManager :: Break
+
+static BOOL CALLBACK interruptHandler ( DWORD dwCode ) {
+
+ WOKNT_ShellManager :: KillAll ();
+
+ if ( dwCode == CTRL_C_EVENT || dwCode == CTRL_BREAK_EVENT ) {
+
+ MessageBeep ( MB_ICONEXCLAMATION );
+ return s_fCtrlBreak = TRUE;
+
+ } // end if
+
+ exit ( 254 );
+
+ return TRUE;
+
+} // end interruptHandler
--- /dev/null
+-- File: WOKNT_ShellOutput.cdl
+-- Created: Tue Jul 30 10:10:37 1996
+-- Author: PLOTNIKOV Eugeny
+-- <eugeny@maniax>
+---Copyright: Matra Datavision 1996
+
+private deferred class ShellOutput from WOKNT inherits File from OSD
+
+ ---Purpose: defines root class to manage output of sub-process
+
+ uses
+
+ HSequenceOfHAsciiString from TColStd
+
+ is
+
+ Initialize;
+ ---Purpose: protected constructor
+
+ Cleanup ( me : out ) is virtual;
+ ---Purpose: provides 'cleanup' functionality
+ ---C++: alias ~
+
+ Clear ( me : out ) is deferred;
+ ---Purpose: clears output buffer(s) of sub-process
+
+ Echo ( me : out ) returns HSequenceOfHAsciiString from TColStd is deferred;
+ ---Purpose: returns standard output of sub-process
+
+ Errors ( me : out ) returns HSequenceOfHAsciiString from TColStd is deferred;
+ ---Purpose: returns standard error output of sub-process
+
+ OpenStdOut ( me : out ) returns Integer from Standard is deferred;
+ ---Purpose: creates an I/O object for reading a standard output of sub-process
+ -- and returns this object handle.
+ ---Warning: returns INVALID_HANDLE_VALUE in case of failure
+
+ CloseStdOut ( me : out ) is deferred;
+ ---Purpose: closes an I/O object's handle opened by 'OpenStdOut' method
+
+ OpenStdErr ( me : out ) returns Integer from Standard is deferred;
+ ---Purpose: creates an I/O object for reading a standard error output of sub-process
+ -- and returns this object handle
+ ---Warning: returns INVALID_HANDLE_VALUE in case of failure
+
+ CloseStdErr ( me : out ) is deferred;
+ ---Purpose: closes an I/O object's handle opened by 'OpenStdErr' method
+
+ SyncStdOut ( me : out ) returns HSequenceOfHAsciiString from TColStd is deferred;
+ ---Purpose: waits for sub-process termination
+
+ SyncStdErr ( me : out ) returns HSequenceOfHAsciiString from TColStd is deferred;
+ ---Purpose: same as 'SyncStdOut' method
+
+end ShellOutput;
--- /dev/null
+#define STRICT
+#include <windows.h>
+
+#include <WOKNT_ShellOutput.ixx>
+
+WOKNT_ShellOutput :: WOKNT_ShellOutput () {
+
+} // end constructor
+
+void WOKNT_ShellOutput :: Cleanup () {
+
+ if ( ( HANDLE )myFileChannel != INVALID_HANDLE_VALUE ) Close ();
+
+} // end WOKNT_ShellOutput :: Cleanup
--- /dev/null
+#define STRICT
+#include <windows.h>
+
+#include <WOKNT_Shell.hxx>
+#include <TCollection_HAsciiString.hxx>
+#include <TColStd_HSequenceOfHAsciiString.hxx>
+#include <WOKNT_Array1OfRegExp.hxx>
+#include <WOKTools_Messages.hxx>
+#include <OSD_Environment.hxx>
+#include <OSD_Path.hxx>
+#include <OSD_SharedLibrary.hxx>
+
+#include <regexp.h>
+#include <stdio.h>
+
+typedef int ( *EXT_FUNC ) ( int, TCHAR** );
+
+#define PATTERN_CHAR_STRING 1
+#define PATTERN_ENV_VARIABLE 2
+#define PATTERN_WORD 3
+#define PATTERN_SET_COMMAND 4
+#define PATTERN_SETENV_COMMAND 5
+#define PATTERN_UNSETENV_COMMAND 6
+#define PATTERN_CD_COMMAND 7
+#define PATTERN_CHAR_STRING_1 8
+#define PATTERN_COMMAND_SEPARATOR 9
+#define PATTERN_CONTINUE 10
+
+const Standard_CString patterns[] = {
+
+ _TEXT( "\"(\"\"|[^\"])*\"" ), // character string pattern
+ _TEXT( "%[^%]+%" ), // Windows NT environment variable syntax
+ _TEXT( "*.[^ \t\"%;]*" ), // string quoted by whitespaces, '"' or '%' or ';'
+ _TEXT( "set .+=.*" ), // 'set' command syntax ( 'set var=val' )
+ _TEXT( "setenv .+ .+" ), // 'setenv' command syntax ( 'setenv var val' )
+ _TEXT( "unsetenv .+" ), // 'unsetenv' command syntax ( 'unsetenv ver' )
+ _TEXT( "cd$|cd .+" ), // 'cd' command syntax
+ _TEXT( "'(''|[^\'])*'" ), // character string pattern
+ _TEXT( "[ \t]*;" ), // command separator ( semicolon )
+ _TEXT( "[ \t]*\\\\" ) // continuation line ( backslash )
+
+}; // end patterns
+
+#define NUM_PATTERNS ( sizeof ( patterns ) / sizeof ( Standard_CString ) )
+
+static _TUCHAR caseTrans[ ( 1 << BYTEWIDTH ) ] = { // translation table to perform
+ // character case translation
+ 000, 001, 002, 003, 004, 005, 006, 007,
+ 010, 011, 012, 013, 014, 015, 016, 017,
+ 020, 021, 022, 023, 024, 025, 026, 027,
+ 030, 031, 032, 033, 034, 035, 036, 037,
+ 040, 041, 042, 043, 044, 045, 046, 047,
+ 050, 051, 052, 053, 054, 055, 056, 057,
+ 060, 061, 062, 063, 064, 065, 066, 067,
+ 070, 071, 072, 073, 074, 075, 076, 077,
+ 0100, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
+ 0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117,
+ 0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
+ 0130, 0131, 0132, 0133, 0134, 0135, 0136, 0137,
+ 0140, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
+ 0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117,
+ 0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
+ 0130, 0131, 0132, 0173, 0174, 0175, 0176, 0177,
+ 0200, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
+ 0210, 0211, 0212, 0213, 0214, 0215, 0216, 0217,
+ 0220, 0221, 0222, 0223, 0224, 0225, 0226, 0227,
+ 0230, 0231, 0232, 0233, 0234, 0235, 0236, 0237,
+ 0240, 0241, 0242, 0243, 0244, 0245, 0246, 0247,
+ 0250, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
+ 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
+ 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
+ 0300, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
+ 0310, 0311, 0312, 0313, 0314, 0315, 0316, 0317,
+ 0320, 0321, 0322, 0323, 0324, 0325, 0326, 0327,
+ 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
+ 0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
+ 0350, 0351, 0352, 0353, 0354, 0355, 0356, 0357,
+ 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
+ 0370, 0371, 0372, 0373, 0374, 0375, 0376, 0377
+
+};
+
+static WOKNT_Array1OfRegExp _shellRegExp ( 1, NUM_PATTERNS );
+static OSD_SharedLibrary _extLib;
+static HMODULE _hWOKCXModule;
+
+extern "C" __declspec( dllexport ) int __fastcall __WOKNT_INIT__ (
+ unsigned hInstance, unsigned long reason_for_call
+ ) {
+
+ if ( reason_for_call == DLL_PROCESS_ATTACH ) _hWOKCXModule = ( HMODULE )hInstance;
+
+ return 1;
+
+} // end __WOKNT_INIT__
+
+extern "C" __declspec( dllexport ) int __fastcall __TKWOK_INIT__ (
+ unsigned hInstance, unsigned long reason_for_call
+ ) {
+
+ if ( reason_for_call == DLL_PROCESS_ATTACH ) _hWOKCXModule = ( HMODULE )hInstance;
+
+ return 1;
+
+} // end __TKWOK_INIT__
+
+class _regExpInit { // provides initialisation in case of UNICODE environment
+
+ public:
+
+ _regExpInit () {
+
+ for ( int i = ( 1 << CHAR_BIT ); i < ( 1 << BYTEWIDTH ); ++i )
+
+ caseTrans[ i ] = ( _TUCHAR )i;
+
+ for ( i = 1; i <= NUM_PATTERNS; ++i )
+
+ _shellRegExp.SetValue ( i, new WOKNT_RegExp (
+ new TCollection_HAsciiString ( patterns[ i - 1 ] ),
+ WOKNT_RESyntaxAWK, caseTrans
+ )
+ );
+
+ } // end constructor
+
+}; // end _regExpInit
+
+static _regExpInit initializeShellRegExp;
+
+Standard_Integer __fastcall _WOKNT_find_environment_variable (
+ const Handle( TColStd_HSequenceOfHAsciiString )&,
+ const Handle( TCollection_HAsciiString )&
+ );
+Standard_CString _WOKNT_get_last_error_text ( void );
+Standard_Integer _rm_command ( Standard_CString );
+Standard_Integer _chmod_command ( Standard_CString );
+
+static void __fastcall _WOKNT_strip_string ( Handle( TCollection_HAsciiString )& );
+
+#define MATCH( i ) ( _shellRegExp.Value ( ( i ) ) -> \
+ Match ( tmpStr, 1, len+1 ) \
+ )
+
+#define C_MATCH( i ) ( _shellRegExp.Value ( ( i ) ) -> \
+ Match ( aCmd,1 ,len+1 ) \
+ )
+
+Standard_Boolean WOKNT_Shell :: BuiltInCommand (
+ Handle_TCollection_HAsciiString& aCmd,
+ const Standard_Boolean doParse
+ ) {
+
+ Handle( TCollection_HAsciiString )tmpStr =
+ new TCollection_HAsciiString ( aCmd -> String () );
+ Standard_Integer len;
+ Standard_Integer envIdx;
+ Standard_Integer pos = 1;
+ EXT_FUNC xFunc;
+
+ aCmd -> Clear ();
+ tmpStr -> RightAdjust ();
+ len = tmpStr -> Length ();
+
+ while ( len ) {
+
+ if ( ( pos = MATCH( PATTERN_CHAR_STRING ) ) > 0 ||
+ ( pos = MATCH( PATTERN_CHAR_STRING_1 ) ) > 0
+ ) {
+
+ aCmd -> AssignCat ( tmpStr -> SubString ( 1, pos ) );
+ len -= pos;
+
+ } else if ( ( pos = MATCH( PATTERN_ENV_VARIABLE ) ) > 0 ) {
+
+ envIdx = 0;
+
+ if ( !doParse ) {
+
+ Handle( TCollection_HAsciiString ) envVar = tmpStr -> SubString ( 2, pos - 1 );
+
+ if ( !_tcscmp ( envVar -> ToCString (), _TEXT( "status" ) ) ) {
+
+ TCHAR buff[ 20 ];
+
+ envIdx = 1;
+ aCmd -> AssignCat (
+ new TCollection_HAsciiString ( _ltot ( myStatus, buff, 10 ) )
+ );
+
+ } else if ( envIdx = _WOKNT_find_environment_variable (
+ myEnvironment,
+ tmpStr -> SubString ( 2, pos - 1 )
+ )
+ ) aCmd -> AssignCat (
+ myEnvironment -> Value ( envIdx ) -> Token ( _TEXT( "=" ), 2 )
+ );
+
+ } // end if
+
+ if ( doParse || !envIdx ) aCmd -> AssignCat ( tmpStr -> SubString ( 1, pos ) );
+
+ } else if ( ( pos = MATCH( PATTERN_COMMAND_SEPARATOR ) ) > 0 ) {
+
+ aCmd -> AssignCat ( _TEXT( "\x01" ) );
+
+ } else if ( ( pos = MATCH( PATTERN_CONTINUE ) ) > 0 ) {
+
+ aCmd -> AssignCat ( _TEXT( " " ) );
+
+ } else if ( ( pos = MATCH( PATTERN_WORD ) ) > 0 ) {
+
+ aCmd -> AssignCat ( tmpStr -> SubString ( 1, pos ) );
+
+ } else break;
+
+ tmpStr -> Remove ( 1, pos );
+
+ if ( tmpStr -> Length () > 0 && _istspace ( tmpStr -> Value ( 1 ) ) )
+
+ aCmd -> AssignCat ( _TEXT( " " ) );
+
+ tmpStr -> LeftAdjust ();
+ len = tmpStr -> Length ();
+
+ } // end while
+
+ if ( doParse ) return Standard_False;
+
+ aCmd -> LeftAdjust ();
+ len = aCmd -> Length ();
+
+ if ( C_MATCH( PATTERN_SET_COMMAND ) > 0 ) {
+
+ Standard_Integer valLen;
+ Handle( TCollection_HAsciiString ) name, value;
+
+ name = aCmd -> Token ( _TEXT( "=" ), 1 );
+ value = aCmd -> Token ( _TEXT( "=" ), 2 );
+ valLen = value -> Length ();
+
+ name -> Remove ( 1, 3 );
+ name -> LeftAdjust ();
+
+ if ( !_tcscmp ( name -> ToCString (), _TEXT( "status" ) ) ) {
+
+ if ( !value -> IsEmpty () ) myStatus = _ttoi ( value -> ToCString () );
+
+ return Standard_True;
+
+ } else if ( value -> IsEmpty () ) {
+
+ RemoveEnvironmentVariable ( name );
+
+ } else
+
+ AddEnvironmentVariable ( name, value );
+
+ } else if ( C_MATCH( PATTERN_SETENV_COMMAND ) > 0 ) {
+
+ Handle( TCollection_HAsciiString ) name, value;
+
+ name = aCmd -> Token ( _TEXT( " " ), 2 );
+ value = aCmd -> Token ( _TEXT( " " ), 3 );
+
+ _WOKNT_strip_string ( name );
+ _WOKNT_strip_string ( value );
+
+ AddEnvironmentVariable ( name, value );
+
+ } else if ( C_MATCH( PATTERN_UNSETENV_COMMAND ) > 0 ) {
+
+ Handle( TCollection_HAsciiString ) name = aCmd -> Token ( _TEXT( " " ), 2 );
+
+ _WOKNT_strip_string ( name );
+
+ RemoveEnvironmentVariable ( name );
+
+ } else if ( C_MATCH( PATTERN_CD_COMMAND ) > 0 ) {
+
+ aCmd -> AssignCat ( _TEXT( " " ) );
+
+ Handle ( TCollection_HAsciiString ) newDir = aCmd -> SubString ( 3, aCmd -> Length () );
+
+ newDir -> LeftAdjust ();
+
+ if ( newDir -> IsEmpty () ) {
+
+ Handle( TCollection_HAsciiString ) homeDir = new TCollection_HAsciiString ();
+ OSD_Environment homeDrive ( _TEXT( "HOMEDRIVE" ) );
+ OSD_Environment homePath ( _TEXT( "HOMEPATH" ) );
+
+ homeDir -> AssignCat ( homeDrive.Value ().ToCString () );
+ homeDir -> AssignCat ( homePath.Value ().ToCString () );
+
+ myDirectory = homeDir;
+
+ } else {\r
+ char aDir[1024];\r
+\r
+ GetCurrentDirectory(1024, aDir);\r
+
+ TCollection_AsciiString str = aDir;
+
+ if ( !SetCurrentDirectory ( newDir -> ToCString () ) ) {
+
+ Handle( TCollection_HAsciiString ) errMsg = new TCollection_HAsciiString ();
+
+ errMsg -> Cat ( _TEXT( "'" ) );
+ errMsg -> Cat ( newDir );
+ errMsg -> Cat ( _TEXT( "' - " ) );
+ errMsg -> Cat ( _WOKNT_get_last_error_text () );
+
+ if ( myStdErr.IsNull () ) myStdErr = new TColStd_HSequenceOfHAsciiString ();
+
+ myStdErr -> Append ( errMsg );
+
+ } else {
+
+ SetCurrentDirectory ( str.ToCString () );
+ myDirectory = newDir;
+ } // end else
+
+ } // end else
+
+ } else {
+
+ Standard_Boolean fCond = Standard_False;
+ Standard_Integer cLen;
+ Handle( TCollection_HAsciiString ) command = aCmd -> Token ( " \t", 1 );
+
+ cLen = command -> Length ();
+
+ if ( command -> Value ( 1 ) == _TEXT( '@' ) ) {
+
+ fCond = Standard_True;
+ command -> Remove ( 1 );
+
+ } // end if
+
+ if ( ( xFunc = ( EXT_FUNC )GetProcAddress (
+ _hWOKCXModule, command -> ToCString ()
+ )
+ ) != NULL
+ ) {
+
+ if ( fCond && !myStatus ) return Standard_True;
+
+ TCHAR** argv;
+
+ Handle( TCollection_HAsciiString ) item;
+ Handle( TColStd_HSequenceOfHAsciiString ) args =
+ new TColStd_HSequenceOfHAsciiString ();
+
+ aCmd -> Remove ( 1, cLen );
+ aCmd -> LeftAdjust ();
+
+ args -> Append ( command );
+
+ tmpStr = aCmd;
+ len = tmpStr -> Length ();
+
+ while ( len ) {
+
+ if ( ( pos = MATCH( PATTERN_CHAR_STRING ) ) > 0 ||
+ ( pos = MATCH( PATTERN_CHAR_STRING_1 ) ) > 0
+ ) {
+
+ item = tmpStr -> SubString ( 1, pos );
+ len -= pos;
+
+ _WOKNT_strip_string ( item );
+
+ } else if ( ( pos = MATCH( PATTERN_WORD ) ) > 0 ) {
+
+ item = tmpStr -> SubString ( 1, pos );
+
+ } else break;
+
+ tmpStr -> Remove ( 1, pos );
+ tmpStr -> LeftAdjust ();
+ len = tmpStr -> Length ();
+ args -> Append ( item );
+
+ } // end while
+
+ argv = new TCHAR*[ args -> Length () ];
+
+ for ( int i = 1; i <= args -> Length (); ++i )
+
+ argv[ i - 1 ] = args -> Value ( i ) -> ToCString ();
+
+ myStatus = ( *xFunc ) ( args -> Length (), argv );
+
+ delete [] argv;
+
+ } else
+
+ return Standard_False;
+
+ } // end else
+
+ return Standard_True;
+
+} //end WOKNT_Shell :: BuiltInCommand
+
+static void __fastcall _WOKNT_strip_string ( Handle( TCollection_HAsciiString )& str ) {
+
+ Standard_Integer len = str -> Length ();
+
+ if ( str -> Value ( 1 ) == _TEXT( '"' ) &&
+ str -> Value ( len ) == _TEXT( '"' )
+ ) {
+
+ str -> Remove ( 1 );
+ str -> Remove ( len - 1 );
+
+ while ( ( len = str -> Search ( _TEXT( "\"\"" ) ) )!= -1 )
+
+ str -> Remove ( len );
+
+ } else if ( str -> Value ( 1 ) == _TEXT( '\'' ) &&
+ str -> Value ( len ) == _TEXT( '\'' )
+ ) {
+
+ str -> Remove ( 1 );
+ str -> Remove ( len - 1 );
+
+ while ( ( len = str -> Search ( _TEXT( "\'\'" ) ) )!= -1 )
+
+ str -> Remove ( len );
+
+ } // end else
+
+} // end _WOKNT_strip_string
--- /dev/null
+#ifndef __WOKNT_FILETIME_HXX
+# define __WOKNT_FILETIME_HXX
+
+# ifndef STRICT
+# define STRICT
+# endif // STRICT
+
+# ifndef _INC_TIME
+# include <time.h>
+# endif // _INC_TIME
+
+typedef time_t WOKNT_TimeStat;
+
+#endif // __WOKNT_FILETIME_HXX
--- /dev/null
+#ifndef __WOKNT_WNT_BREAK__HXX
+# define __WOKNT_WNT_BREAK__HXX
+
+# ifdef WNT
+# include <WOKNT_ShellManager.hxx>
+# define _TEST_BREAK() WOKNT_ShellManager :: Break ()
+# endif // WNT
+
+#endif // __WOKNT_WNT_BREAK__HXX
--- /dev/null
+-- File: WOKNT_WOKSteps.edl
+-- Author: Jean GAUTIER
+-- History: Tue Aug 12 17:21:24 1997 Jean GAUTIER Creation
+-- Copyright: Matra Datavision 1997
+
+@ifnotdefined ( %WOKNT_WOKSteps_EDL) then
+@set %WOKNT_WOKSteps_EDL = "";
+
+@if ( %Station != "wnt" ) then
+
+ @set %WOKSteps_ObjGroup = "obj.nocompil";
+ @set %WOKSteps_LibGroup = "";
+
+ @set %WOKSteps_obj_nocompil = "WOKStep_Compile";
+
+ @set %WOKSteps_toolkit_ListWith = "obj.nocompil";
+ @set %WOKSteps_toolkit_LinksWith = "obj.nocompil";
+
+@endif;
+
+@endif;
--- /dev/null
+#define EXPORT
+#include <iostream.h>
+#include <stdlib.h>
+
+#include <OSD_WNT.h>
+#include <OSD_File.hxx>
+#include <OSD_Path.hxx>
+#include <OSD_Protection.hxx>
+
+#define FLAG_SYSTEM 0x01
+#define FLAG_OWNER 0x02
+#define FLAG_GROUP 0x04
+#define FLAG_WORLD 0x08
+
+#define OPER_GRANT 0
+#define OPER_DENY 1
+
+#define PROT_READ 0x01
+#define PROT_WRITE 0x02
+#define PROT_EXECUTE 0x04
+#define PROT_DELETE 0x08
+
+#define I_SYSTEM 0
+#define I_OWNER 1
+#define I_GROUP 2
+#define I_WORLD 3
+
+typedef struct _prt_data {
+
+ BYTE fUser;
+ BYTE fProt;
+ BOOL fGrant;
+ BOOL fRecurse;
+
+ } PRT_DATA, *PPRT_DATA;
+
+typedef BOOL ( *CHMOD_FUNC ) ( LPCTSTR, BOOL, void* );
+
+static BOOL _chmod_func ( LPTSTR, BOOL, void* );
+
+#define USAGE() { cerr << "Usage: wokCHMOD [-R] [sugoa]{+|-}[rwxd] file(s)\n"; return 1; }
+
+static int nFiles;
+
+extern "C" __declspec( dllexport ) wokCHMOD ( int, char** );
+
+int wokCHMOD ( int argc, char** argv ) {
+
+ int i, retVal = 0;
+ char* ptr;
+ PRT_DATA pd = { 0, 0, 0 };
+ BOOL fRecurse;
+ char path[ _MAX_PATH ];
+ char name[ _MAX_FNAME + _MAX_EXT ];
+ char drive[ _MAX_DRIVE ];
+ char dir[ _MAX_DIR ];
+ char fname[ _MAX_FNAME ];
+ char ext[ _MAX_EXT ];
+
+ if ( argc < 3 ) USAGE();
+
+ if ( *argv[ 1 ] == '-' && ( argv[ 1 ][ 1 ] == 'r' || argv[ 1 ][ 1 ] == 'R' ) ) {
+
+ fRecurse = pd.fRecurse = TRUE;
+ ptr = argv[ 2 ];
+ i = 3;
+
+ } else {
+
+ fRecurse = pd.fRecurse = FALSE;
+ ptr = argv[ 1 ];
+ i = 2;
+
+ } // end else
+
+ while ( *ptr != '+' && *ptr != '-' ) {
+
+ if ( *ptr == 0 ) USAGE();
+
+ switch ( *ptr ) {
+
+ case 's':
+ case 'S':
+
+ pd.fUser |= FLAG_SYSTEM;
+
+ break;
+
+ case 'o':
+ case 'O':
+ case 'u':
+ case 'U':
+
+ pd.fUser |= FLAG_OWNER;
+
+ break;
+
+ case 'g':
+ case 'G':
+
+ pd.fUser |= FLAG_GROUP;
+
+ break;
+
+ case 'a':
+ case 'A':
+
+ pd.fUser |= FLAG_WORLD;
+
+ break;
+
+ default:
+
+ USAGE();
+
+ } // end switch
+
+ ++ptr;
+
+ } // end while
+
+ pd.fGrant = ( *ptr++ == '+' ) ? TRUE : FALSE;
+
+ while ( *ptr != 0 ) {
+
+ switch ( *ptr ) {
+
+ case 'r':
+ case 'R':
+
+ pd.fProt |= PROT_READ;
+
+ break;
+
+ case 'w':
+ case 'W':
+
+ pd.fProt |= PROT_WRITE;
+
+ break;
+
+ case 'x':
+ case 'X':
+
+ pd.fProt |= PROT_EXECUTE;
+
+ break;
+
+ case 'd':
+ case 'D':
+
+ pd.fProt |= PROT_DELETE;
+
+ break;
+
+ default:
+
+ USAGE();
+
+ } // end switch
+
+ ++ptr;
+
+ } // end while
+
+ for ( ; i < argc; ++i ) {
+
+ nFiles = 0;
+ _splitpath ( argv[ i ], drive, dir, fname, ext );
+ _makepath ( path, drive, dir, NULL, NULL );
+ _makepath ( name, NULL, NULL, fname, ext );
+
+ if ( !DirWalk ( path, name, ( CHMOD_FUNC )_chmod_func, fRecurse, &pd ) ) retVal = 1;
+
+ if ( nFiles == 0 ) {
+
+ cerr << "wokCHMOD: could not find " << argv[ i ] << endl << flush;
+ retVal = 1;
+
+ } // end if
+
+ } // end for
+
+ return retVal;
+
+} // end main
+
+static BOOL _chmod_func ( LPTSTR fName, BOOL fDir, void* data ) {
+
+ int i, j;
+ OSD_Protection prot;
+ OSD_File file;
+ OSD_SingleProtection pArr[ 4 ];
+ OSD_SingleProtection pDef[ 4 ] = { OSD_R, OSD_W, OSD_X, OSD_D };
+ unsigned char flags[ 4 ] = { 0, 0, 0, 0 };
+ unsigned char prt[ 4 ] = { 0, 0, 0, 0 };
+ PPRT_DATA pData = ( PPRT_DATA )data;
+
+ ++nFiles;
+
+ if ( fDir && !pData -> fRecurse ) return TRUE;
+
+ file.SetPath ( OSD_Path ( fName ) );
+ prot = file.Protection ();
+
+ if ( file.Failed () ) {
+
+ cerr << "wokCHMOD: ";
+ file.Perror ();
+ return FALSE;
+
+ } // end if
+
+ pArr[ I_SYSTEM ] = prot.System ();
+ pArr[ I_OWNER ] = prot.User ();
+ pArr[ I_GROUP ] = prot.Group ();
+ pArr[ I_WORLD ] = prot.World ();
+
+ if ( pData -> fUser & FLAG_SYSTEM ) flags[ I_SYSTEM ] = 1;
+ if ( pData -> fUser & FLAG_OWNER ) flags[ I_OWNER ] = 1;
+ if ( pData -> fUser & FLAG_GROUP ) flags[ I_GROUP ] = 1;
+ if ( pData -> fUser & FLAG_WORLD ) flags[ I_WORLD ] = 1;
+
+ if ( pData -> fProt & PROT_READ ) prt[ 0 ] = 1;
+ if ( pData -> fProt & PROT_WRITE ) prt[ 1 ] = 1;
+ if ( pData -> fProt & PROT_EXECUTE ) prt[ 2 ] = 1;
+ if ( pData -> fProt & PROT_DELETE ) prt[ 3 ] = 1;
+
+ if ( flags[ I_SYSTEM ] == 0 &&
+ flags[ I_OWNER ] == 0 &&
+ flags[ I_GROUP ] == 0 &&
+ flags[ I_WORLD ] == 0
+ ) flags[ I_OWNER ] = 1;
+
+ for ( i = 0; i < 4; ++i )
+
+ for ( j = 0; j < 4; ++j )
+
+ if ( prt[ j ] )
+
+ if ( flags[ i ] )
+
+ if ( !pData -> fGrant )
+
+ prot.Sub ( pArr[ i ], pDef[ j ] );
+
+ else
+
+ prot.Add ( pArr[ i ], pDef[ j ] );
+
+ prot.SetSystem ( pArr[ I_SYSTEM ] );
+ prot.SetUser ( pArr[ I_OWNER ] );
+ prot.SetGroup ( pArr[ I_GROUP ] );
+ prot.SetWorld ( pArr[ I_WORLD ] );
+
+ file.SetProtection ( prot );
+
+ if ( file.Failed () ) {
+
+ cerr << "wokCHMOD: ";
+ file.Perror ();
+ return FALSE;
+
+ } // end if
+
+ return TRUE;
+
+} // end _chmod_func
--- /dev/null
+#define STRICT
+#include <windows.h>
+
+#include <stdlib.h>
+#include <memory.h>
+
+__declspec( dllexport ) int wokCMP ( int argc, char** argv )
+{
+
+ HANDLE hFile1, hFile2;
+ HANDLE hMap1, hMap2;
+ DWORD dwSize1, dwSize2;
+ PVOID pvAddr1, pvAddr2;
+
+ int retVal = 2;
+
+ hFile1 = hFile2 = INVALID_HANDLE_VALUE;
+
+ pvAddr1 = pvAddr2 = hMap1 = hMap2 = NULL;
+
+ if( argc != 3 ) return 2;
+
+ if((hFile1 = CreateFile(argv[ 1 ], /* file name */
+ GENERIC_READ, /* access */
+ FILE_SHARE_READ, /* sharing */
+ NULL, /* security */
+ OPEN_EXISTING, /* disposition */
+ FILE_ATTRIBUTE_NORMAL, /* attributes */
+ NULL /* template */
+ )) == INVALID_HANDLE_VALUE )
+ retVal = 2;
+ else if((hFile2 = CreateFile(argv[ 2 ], /* file name */
+ GENERIC_READ, /* access */
+ FILE_SHARE_READ, /* sharing */
+ NULL, /* security */
+ OPEN_EXISTING, /* disposition */
+ FILE_ATTRIBUTE_NORMAL, /* attributes */
+ NULL /* template */
+ )) == INVALID_HANDLE_VALUE)
+ retVal = 2;
+ else
+ {
+ dwSize1 = GetFileSize ( hFile1, NULL );
+ dwSize2 = GetFileSize ( hFile2, NULL );
+
+ if ( dwSize1 != dwSize2 ) retVal = 1;
+ else if(( hMap1 = CreateFileMapping(hFile1, NULL, PAGE_READONLY, 0, dwSize1, NULL)) == NULL) retVal = 2;
+ else if((hMap2 = CreateFileMapping(hFile2, NULL, PAGE_READONLY, 0, dwSize2, NULL)) == NULL) retVal = 2;
+ else if((pvAddr1 = MapViewOfFile(hMap1, FILE_MAP_READ, 0, 0, dwSize1)) == NULL) retVal = 2;
+ else if((pvAddr2 = MapViewOfFile(hMap2, FILE_MAP_READ, 0, 0, dwSize2)) == NULL) retVal = 2;
+ else
+ retVal = memcmp ( pvAddr1, pvAddr2, dwSize1 );
+
+ if ( retVal ) retVal = 1;
+ }
+
+ if ( pvAddr2 != NULL ) UnmapViewOfFile ( pvAddr2 );
+ if ( pvAddr1 != NULL ) UnmapViewOfFile ( pvAddr1 );
+
+ if ( hMap2 != NULL ) CloseHandle ( hMap2 );
+ if ( hMap1 != NULL ) CloseHandle ( hMap1 );
+
+ if ( hFile2 != INVALID_HANDLE_VALUE ) CloseHandle ( hFile2 );
+ if ( hFile1 != INVALID_HANDLE_VALUE ) CloseHandle ( hFile1 );
+
+ return retVal;
+}
--- /dev/null
+#define STRICT
+#include <windows.h>
+#include <string.h>
+
+#include <OSD_Path.hxx>
+#include <OSD_File.hxx>
+#include <WOKNT_Path.hxx>
+
+#define BUFFER_SIZE 4096
+
+#define USAGE() { cerr << "Usage: wokCP [-pr] source destination\n"; return ( 1 ); }
+
+extern "C" int __declspec( dllexport ) wokCP ( int, char** );
+
+int wokCP( int argc, char** argv )
+{
+ int i, retVal = 1;
+ char* src = NULL, *dst = NULL, *ptr;
+ BOOL fPreserve = FALSE, fRecurse = FALSE;
+
+ DWORD dwBytesRead, dwBytesWritten;
+ BYTE buffer[ BUFFER_SIZE ];
+
+ if ( argc < 3 ) USAGE();
+
+ for( i=1; i<argc; ++i)
+ {
+ if( argv[i][0] == '-' )
+ {
+ ptr=argv[i];
+
+ while( *++ptr != 0 )
+ {
+ switch ( *ptr )
+ {
+ case 'p':
+ case 'P':
+ fPreserve=TRUE;
+ break;
+ case 'r':
+ case 'R':
+ fRecurse=TRUE;
+ break;
+ default:
+ USAGE();
+ }
+ }
+ }
+ else
+ break;
+ }
+
+ if( i==argc ) USAGE();
+
+ src=argv[i++];
+
+ if( i==argc) USAGE();
+
+ dst=argv[i];
+
+ if(lstrcmp(src,dst)==0) return 0;
+
+ if ( src && dst )
+ {
+ Handle(WOKNT_Path) woksrc = new WOKNT_Path(new TCollection_HAsciiString(src));
+ Handle(WOKNT_Path) wokdst = new WOKNT_Path(new TCollection_HAsciiString(dst));
+ Handle(WOKNT_Path) newdst;
+
+ if(woksrc->IsFile() && wokdst->IsDirectory())
+ {
+ newdst = new WOKNT_Path(wokdst->Name()->ToCString(), woksrc->FileName()->ToCString());
+ dst = newdst->Name()->ToCString();
+ }
+
+ if(fRecurse)
+ {
+ OSD_Path pathSrc(src);
+ OSD_Path pathDst(dst);
+
+ OSD_File source( pathSrc );
+
+ source.Copy(pathDst);
+
+ if(source.Failed())
+ source.Perror ();
+ else
+ retVal = 0;
+ }
+ else
+ {
+ if(fPreserve)
+ {
+ if(!CopyFile(src,dst,FALSE))
+ return retVal;
+ retVal = 0;
+ }
+ else
+ {
+ HANDLE hFileSrc, hFileDst;
+
+ hFileSrc = CreateFile ( src, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
+ hFileDst = CreateFile ( dst, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
+
+ if ( hFileSrc == INVALID_HANDLE_VALUE || hFileDst == INVALID_HANDLE_VALUE )
+ return retVal;
+
+ while(TRUE)
+ {
+ if( !ReadFile( hFileSrc, buffer, BUFFER_SIZE, &dwBytesRead, NULL)) return retVal;
+ if( dwBytesRead == 0 ) break;
+
+ if( !WriteFile ( hFileDst, buffer, dwBytesRead, &dwBytesWritten, NULL ) ||
+ dwBytesWritten != dwBytesRead ) return retVal;
+ }
+ CloseHandle ( hFileDst );
+ CloseHandle ( hFileSrc );
+
+ retVal = 0;
+
+ }
+ }
+ }
+ return retVal;
+}
--- /dev/null
+#define EXPORT
+#define STRICT
+#include <windows.h>
+#include <iostream.h>
+
+extern "C" __declspec( dllexport ) int wokMV ( int, char** );
+
+int wokMV ( int argc, char** argv ) {
+
+ if ( argc != 3 ) {
+
+ cerr << "Usage: wokMV src dst\n" << flush;
+ return 1;
+
+ } // end if
+
+ if ( !MoveFileEx ( argv[ 1 ], argv[ 2 ], MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING) ) {
+
+ char buffer[ 2048 ];
+ DWORD dwCode = GetLastError ();
+
+ if ( !FormatMessage (
+ FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY,
+ 0, dwCode, MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL ),
+ buffer, 2048, NULL
+ )
+ ) wsprintf ( buffer, "Error code %d", dwCode );
+
+ cerr << "wokMV: could not move - " << buffer << endl << flush;
+ return 2;
+
+ } // end if
+
+ return 0;
+
+} // end main
--- /dev/null
+
+#ifndef __REGEXP_H
+# define __REGEXP_H
+/***/
+# ifdef WNT
+# ifdef UNICODE_API
+# ifndef _UNICODE
+# define _UNICODE
+# endif /* _UNICODE */
+# endif /* UNICODE_API */
+/***/
+# ifndef _INC_TCHAR
+# include <tchar.h>
+# endif /* _INC_TCHAR */
+/***/
+# ifndef _INC_STDLIB
+# include <stdlib.h>
+# endif /* _INC_STDLIB */
+/***/
+# ifndef _INC_MALLOC
+# include <malloc.h>
+# endif /* _INC_MALLOC */
+/***/
+# ifndef _INC_LIMITS
+# include <limits.h>
+# endif /* _INC_LIMITS */
+# ifndef _INC_STRING
+# include <string.h>
+# endif /* _INC_STRING */
+/***/
+# ifdef __WOKNT_DLL
+# define REGEXP_API __declspec( dllexport )
+# else
+# define REGEXP_API __declspec( dllimport )
+# endif /* __OSD_DLL */
+# else
+# define _TEXT( arg ) arg
+# define REGEXP_API
+# include <stdio.h>
+# include <limits.h>
+typedef char _TCHAR;
+typedef char TCHAR;
+typedef unsigned char _TUCHAR;
+# endif /* WNT */
+/***/
+/******************************************************************************/
+/* Definitions for data structures callers pass the regex library. */
+/* Copyright (C) 1985 Free Software Foundation, Inc. */
+/* */
+/* This program is free software; you can redistribute it and/or modify */
+/* it under the terms of the GNU General Public License as published by */
+/* the Free Software Foundation; either version 1, or (at your option) */
+/* any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+/* */
+/* In other words, you are welcome to use, share and improve this program. */
+/* You are forbidden to forbid anyone else to use, share and improve */
+/* what you give them. Help stamp out software-hoarding! */
+/******************************************************************************/
+/******************************************************************************/
+/* Modified by EUG ( MATRA Datavision ) for Windows NT and UNICODE ( 1996 ) */
+/******************************************************************************/
+/***/
+/******************************************************************************/
+/* Define number of parens for which we record the beginnings and ends. */
+/* This affects how much space the `struct re_registers' type takes up. */
+/******************************************************************************/
+#ifndef RE_NREGS
+# define RE_NREGS 10
+#endif
+/***/
+/******************************************************************************/
+/* */
+/* width of a byte in bits */
+/* */
+/******************************************************************************/
+/***/
+#ifdef _UNICODE
+# define BYTEWIDTH ( CHAR_BIT * sizeof ( TCHAR ) )
+# define CHAR_MASK USHRT_MAX
+#else
+# define BYTEWIDTH CHAR_BIT
+# define CHAR_MASK UCHAR_MAX
+#endif /* _UNICODE */
+/***/
+/******************************************************************************/
+/* These bits are used in the obscure_syntax variable to choose among */
+/* alternative regexp syntaxes. */
+/* */
+/* 1 means plain parentheses serve as grouping, and backslash */
+/* parentheses are needed for literal searching. */
+/* 0 means backslash-parentheses are grouping, and plain parentheses */
+/* are for literal searching. */
+/******************************************************************************/
+#define RE_NO_BK_PARENS 1
+/******************************************************************************/
+/* 1 means plain | serves as the "or"-operator, and \| is a literal. */
+/* 0 means \| serves as the "or"-operator, and | is a literal. */
+/******************************************************************************/
+#define RE_NO_BK_VBAR 2
+/******************************************************************************/
+/* 0 means plain + or ? serves as an operator, and \+, \? are literals. */
+/* 1 means \+, \? are operators and plain +, ? are literals. */
+/******************************************************************************/
+#define RE_BK_PLUS_QM 4
+/******************************************************************************/
+/* 1 means | binds tighter than ^ or $. */
+/* 0 means the contrary. */
+/******************************************************************************/
+#define RE_TIGHT_VBAR 8
+/******************************************************************************/
+/* 1 means treat \n as an _OR operator */
+/* 0 means treat it as a normal character */
+/******************************************************************************/
+#define RE_NEWLINE_OR 16
+/******************************************************************************/
+/* 0 means that a special characters (such as *, ^, and $) always have */
+/* their special meaning regardless of the surrounding context. */
+/* 1 means that special characters may act as normal characters in some */
+/* contexts. Specifically, this applies to: */
+/* ^ - only special at the beginning, or after ( or | */
+/* $ - only special at the end, or before ) or | */
+/* *, +, ? - only special when not after the beginning, (, or | */
+/******************************************************************************/
+#define RE_CONTEXT_INDEP_OPS 32
+/******************************************************************************/
+/* Now define combinations of bits for the standard possibilities. */
+/******************************************************************************/
+#define RE_SYNTAX_AWK ( RE_NO_BK_PARENS | RE_NO_BK_VBAR | RE_CONTEXT_INDEP_OPS )
+#define RE_SYNTAX_EGREP ( RE_SYNTAX_AWK | RE_NEWLINE_OR )
+#define RE_SYNTAX_GREP ( RE_BK_PLUS_QM | RE_NEWLINE_OR )
+#define RE_SYNTAX_EMACS 0
+/******************************************************************************/
+/* This data structure is used to represent a compiled pattern. */
+/******************************************************************************/
+typedef struct re_pattern_buffer {
+
+ _TCHAR* buffer; /* Space holding the compiled pattern commands. */
+ int allocated; /* Size of space that buffer points to */
+ int used; /* Length of portion of buffer actually occupied */
+ _TCHAR* fastmap; /* Pointer to fastmap, if any, or zero if none. */
+ /* re_search uses the fastmap, if there is one, */
+ /* to skip quickly over totally implausible characters */
+ _TCHAR* translate; /* Translate table to apply to all characters before */
+ /* comparing. Or zero for no translation. The translation */
+ /* is applied to a pattern when it is compiled and to */
+ /* data when it is matched. */
+ _TCHAR fastmap_accurate; /* Set to zero when a new pattern is stored, */
+ /* set to one when the fastmap is updated from it. */
+ _TCHAR can_be_null; /* Set to one by compiling fastmap */
+ /* if this pattern might match the null string. */
+ /* It does not necessarily match the null string */
+ /* in that case, but if this is zero, it cannot. */
+ /* 2 as value means can match null string */
+ /* but at end of range or before a character */
+ /* listed in the fastmap. */
+
+} RE_PATTERN_BUFFER, *PRE_PATTERN_BUFFER;
+/******************************************************************************/
+/* Structure to store "register" contents data in. */
+/* Pass the address of such a structure as an argument to re_match, etc., */
+/* if you want this information back. */
+/* */
+/* start[i] and end[i] record the string matched by \( ... \) grouping i, */
+/* for i from 1 to RE_NREGS - 1. */
+/* start[0] and end[0] record the entire string matched. */
+/******************************************************************************/
+typedef struct re_registers {
+
+ int start[ RE_NREGS ];
+ int end[ RE_NREGS ];
+
+} RE_REGISTERS, *PRE_REGISTERS;
+/******************************************************************************/
+/* These are the command codes that appear in compiled regular expressions, */
+/* one per byte. Some command codes are followed by argument bytes. */
+/* A command code can specify any interpretation whatever for its arguments. */
+/* Zero-bytes may appear in the compiled regular expression. */
+/******************************************************************************/
+enum regexpcode {
+
+ unused,
+ exactn, /* followed by one byte giving n, and then by n literal bytes */
+ begline, /* fails unless at beginning of line */
+ endline, /* fails unless at end of line */
+ jump, /* followed by two bytes giving relative address to jump to */
+ on_failure_jump, /* followed by two bytes giving relative address of place */
+ /* to resume at in case of failure. */
+ finalize_jump, /* Throw away latest failure point and then jump to address. */
+ maybe_finalize_jump, /* Like jump but finalize if safe to do so. */
+ /* This is used to jump back to the beginning */
+ /* of a repeat. If the command that follows */
+ /* this jump is clearly incompatible with the */
+ /* one at the beginning of the repeat, such that */
+ /* we can be sure that there is no use backtracking */
+ /* out of repetitions already completed, */
+ /* then we finalize. */
+ dummy_failure_jump, /* jump, and push a dummy failure point. */
+ /* This failure point will be thrown away */
+ /* if an attempt is made to use it for a failure. */
+ /* A + construct makes this before the first repeat. */
+ anychar, /* matches any one character */
+ charset, /* matches any one char belonging to specified set. */
+ /* First following byte is # bitmap bytes. */
+ /* Then come bytes for a bit-map saying which chars */
+ /* are in. */
+ /* Bits in each byte are ordered low-bit-first. */
+ /* A character is in the set if its bit is 1. */
+ /* A character too large to have a bit in the map */
+ /* is automatically not in the set */
+ charset_not, /* similar but match any character that is NOT one of */
+ /* those specified */
+ start_memory, /* starts remembering the text that is matched */
+ /* and stores it in a memory register. */
+ /* followed by one byte containing the register number. */
+ /* Register numbers must be in the range 0 through */
+ /* NREGS. */
+ stop_memory, /* stops remembering the text that is matched */
+ /* and stores it in a memory register. */
+ /* followed by one byte containing the register number. */
+ /* Register numbers must be in the range 0 through */
+ /* NREGS. */
+ duplicate, /* match a duplicate of something remembered. */
+ /* Followed by one byte containing the index of the */
+ /* memory register. */
+ before_dot, /* Succeeds if before dot */
+ at_dot, /* Succeeds if at dot */
+ after_dot, /* Succeeds if after dot */
+ begbuf, /* Succeeds if at beginning of buffer */
+ endbuf, /* Succeeds if at end of buffer */
+ wordchar, /* Matches any word-constituent character */
+ notwordchar, /* Matches any char that is not a word-constituent */
+ wordbeg, /* Succeeds if at word beginning */
+ wordend, /* Succeeds if at word end */
+ wordbound, /* Succeeds if at a word boundary */
+ notwordbound, /* Succeeds if not at a word boundary */
+ syntaxspec, /* Matches any character whose syntax is specified. */
+ /* followed by a byte which contains a syntax code, */
+ /* Sword or such like */
+ notsyntaxspec /* Matches any character whose syntax differs from the */
+ /* specified. */
+
+};
+/******************************************************************************/
+/* Function prototypes */
+/******************************************************************************/
+/***/
+# ifdef __cplusplus
+extern "C" {
+# endif /* __cplusplus */
+/***/
+REGEXP_API _TCHAR* re_compile_pattern ( _TCHAR*, int, PRE_PATTERN_BUFFER );
+REGEXP_API void re_compile_fastmap ( PRE_PATTERN_BUFFER );
+REGEXP_API int re_search (
+ PRE_PATTERN_BUFFER, _TCHAR*, int, int, int, PRE_REGISTERS
+ );
+REGEXP_API int re_search_2 (
+ PRE_PATTERN_BUFFER, _TCHAR*, int,_TCHAR*, int, int, int,
+ PRE_REGISTERS, int
+ );
+REGEXP_API int re_match (
+ PRE_PATTERN_BUFFER, _TCHAR*, int, int, PRE_REGISTERS
+ );
+REGEXP_API int re_match_2 (
+ PRE_PATTERN_BUFFER, _TUCHAR*, int, _TUCHAR*, int,
+ int, PRE_REGISTERS, int
+ );
+REGEXP_API int re_set_syntax ( int );
+/***/
+# ifdef __cplusplus
+}
+# endif /* __cplusplus */
+/***/
+/******************************************************************************/
+#endif /* __REGEXP_H */
--- /dev/null
+/******************************************************************************/
+/* Extended regular expression matching and search. */
+/* Copyright (C) 1985 Free Software Foundation, Inc. */
+/* */
+/* This program is free software; you can redistribute it and/or modify */
+/* it under the terms of the GNU General Public License as published by */
+/* the Free Software Foundation; either version 1, or (at your option) */
+/* any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the Free Software */
+/* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+/* */
+/* In other words, you are welcome to use, share and improve this program. */
+/* You are forbidden to forbid anyone else to use, share and improve */
+/* what you give them. Help stamp out software-hoarding! */
+/******************************************************************************/
+/******************************************************************************/
+/* Modified by EUG ( MATRA Datavision ) for Windows NT and UNICODE ( 1996 ) */
+/******************************************************************************/
+/***/
+
+/* JGA : to compile on Solaris */
+
+#if !defined(HPUX) && !defined (WNT)
+#include <alloca.h>
+
+#else
+/* alloca() non disponible sur HPUX 9.07 */
+# ifdef __cplusplus
+extern "C" {
+# endif
+void *alloca(unsigned int);
+# ifdef __cplusplus
+}
+#endif
+void *alloca(unsigned int size){return (void *)0L;}
+#endif
+
+
+#include <WOKNT_regexp.h>
+
+/***/
+/******************************************************************************/
+/* */
+/* Define the syntax stuff, so we can do the \<...\> things. */
+/* */
+/******************************************************************************/
+/***/
+#ifndef Sword /* must be non-zero in some of the tests below... */
+# define Sword 1
+#endif /* Sword */
+
+#define SYNTAX( c ) re_syntax_table[ ( c ) ]
+
+TCHAR* re_syntax_table;
+/***/
+/******************************************************************************/
+/* */
+/* Number of failure points to allocate space for initially, */
+/* when matching. If this number is exceeded, more space is allocated, */
+/* so it is not a hard limit. */
+/* */
+/******************************************************************************/
+/***/
+#ifndef NFAILURES
+# define NFAILURES 80
+#endif /* NFAILURES */
+/***/
+#ifndef SIGN_EXTEND_CHAR
+# define SIGN_EXTEND_CHAR( x ) ( x )
+#endif /* SIGN_EXTEND_CHAR */
+/***/
+static int obscure_syntax;
+/***/
+/******************************************************************************/
+/* */
+/* Specify the precise syntax of regexp for compilation. */
+/* This provides for compatibility for various utilities */
+/* which historically have different, incompatible syntaxes. */
+/* */
+/* The argument SYNTAX is a bit-mask containing the two bits */
+/* RE_NO_BK_PARENS and RE_NO_BK_VBAR. */
+/* */
+/******************************************************************************/
+/***/
+int re_set_syntax ( int syntax ) {
+
+ int ret;
+
+ ret = obscure_syntax;
+ obscure_syntax = syntax;
+
+ return ret;
+
+} /* end re_set_syntax */
+/***/
+/******************************************************************************/
+/* */
+/* re_compile_pattern takes a regular-expression string */
+/* and converts it into a buffer full of byte commands for matching. */
+/* */
+/* PATTERN is the address of the pattern string */
+/* SIZE is the length of it. */
+/* BUFP is a struct re_pattern_buffer * which points to the info */
+/* on where to store the byte commands. */
+/* This structure contains a char * which points to the */
+/* actual space, which should have been obtained with malloc. */
+/* re_compile_pattern may use realloc to grow the buffer space. */
+/* */
+/* The number of bytes of commands can be found out by looking in */
+/* the struct re_pattern_buffer that bufp pointed to, */
+/* after re_compile_pattern returns. */
+/* */
+/******************************************************************************/
+/***/
+#define PATPUSH( ch ) ( *b++ = ( _TCHAR )( ch ) )
+
+#define PATFETCH( c ) { if ( p == pend ) goto end_of_pattern; \
+ ( c ) = *( _TUCHAR* )p++; \
+ if ( translate ) ( c ) = translate[ ( c ) ]; \
+ }
+
+#define PATFETCH_RAW( c ) { if ( p == pend ) goto end_of_pattern; \
+ ( c ) = *( _TUCHAR* )p++; \
+ }
+
+#define PATUNFETCH p--
+
+#define EXTEND_BUFFER { _TCHAR* old_buffer = bufp -> buffer; \
+ if ( bufp -> allocated == ( 1 << 16 ) ) \
+ goto too_big; \
+ bufp -> allocated *= 2; \
+ if ( bufp -> allocated > ( 1 << 16 ) ) \
+ bufp -> allocated = ( 1 << 16 ); \
+ if ( !( bufp -> buffer = \
+ ( _TCHAR* )realloc ( \
+ bufp -> buffer, \
+ bufp -> allocated \
+ ) \
+ ) \
+ ) goto memory_exhausted; \
+ c = bufp -> buffer - old_buffer; \
+ b += c; \
+ if ( fixup_jump ) fixup_jump += c; \
+ if ( laststart ) laststart += c; \
+ begalt += c; \
+ if ( pending_exact ) \
+ pending_exact += ( long )c; \
+ }
+
+static void store_jump ( _TCHAR*, _TCHAR, _TCHAR* );
+static void insert_jump ( _TCHAR, _TCHAR*, _TCHAR*, _TCHAR* );
+
+_TCHAR* re_compile_pattern (
+ _TCHAR* pattern, int size, PRE_PATTERN_BUFFER bufp
+ ) {
+
+ _TCHAR* b = bufp -> buffer;
+ _TCHAR* p = pattern;
+ _TCHAR* pend = pattern + size;
+ _TCHAR* p1;
+ _TUCHAR* translate = ( _TUCHAR* )bufp -> translate;
+
+ unsigned long c, c1;
+
+/* address of the count-byte of the most recently inserted "exactn" command. */
+/* This makes it possible to tell whether a new exact-match character */
+/* can be added to that command or requires a new "exactn" command. */
+
+ _TCHAR* pending_exact = NULL;
+
+/* address of the place where a forward-jump should go */
+/* to the end of the containing expression. */
+/* Each alternative of an "or", except the last, ends with a forward-jump */
+/* of this sort. */
+
+ _TCHAR* fixup_jump = NULL;
+
+/* address of start of the most recently finished expression. */
+/* This tells postfix * where to find the start of its operand. */
+
+ _TCHAR* laststart = NULL;
+
+/* In processing a repeat, 1 means zero matches is allowed */
+
+ _TCHAR zero_times_ok;
+
+/* In processing a repeat, 1 means many matches is allowed */
+
+ _TCHAR many_times_ok;
+
+/* address of beginning of regexp, or inside of last \( */
+
+ _TCHAR* begalt = b;
+
+/* Stack of information saved by \( and restored by \). */
+/* Four stack elements are pushed by each \(: */
+/* First, the value of b. */
+/* Second, the value of fixup_jump. */
+/* Third, the value of regnum. */
+/* Fourth, the value of begalt. */
+
+ long stackb[ 40 ];
+ long* stackp = stackb;
+ long* stacke = stackb + 40;
+ long* stackt;
+
+/* Counts \('s as they are encountered. Remembered for the matching \), */
+/* where it becomes the "register number" to put in the stop_memory command */
+
+ int regnum = 1;
+
+ bufp -> fastmap_accurate = 0;
+
+ if ( bufp -> allocated == 0 ) {
+
+ bufp -> allocated = 28;
+
+ if ( bufp -> buffer )
+ /* EXTEND_BUFFER loses when bufp->allocated is 0 */
+ bufp -> buffer = ( _TCHAR* )realloc ( bufp -> buffer, 28 * sizeof ( _TCHAR ) );
+
+ else
+ /* Caller did not allocate a buffer. Do it for him */
+ bufp -> buffer = ( _TCHAR* ) malloc ( 28 * sizeof ( _TCHAR ) );
+
+ if ( !bufp -> buffer ) goto memory_exhausted;
+
+ begalt = b = bufp -> buffer;
+
+ } /* end if */
+
+ while ( p != pend ) {
+
+ if ( ( int )( b - bufp -> buffer ) >
+ ( int )( bufp -> allocated - 10 * sizeof ( _TCHAR ) )
+ )
+
+ EXTEND_BUFFER; /* Note that EXTEND_BUFFER clobbers c */
+
+ PATFETCH( c );
+
+ switch ( c ) {
+
+ case _TEXT( '$' ):
+
+ if ( obscure_syntax & RE_TIGHT_VBAR ) {
+
+ if ( !( obscure_syntax & RE_CONTEXT_INDEP_OPS ) && p != pend ) goto normal_char;
+ /* Make operand of last vbar end before this `$'. */
+ if ( fixup_jump ) store_jump ( fixup_jump, jump, b );
+
+ fixup_jump = NULL;
+ PATPUSH( endline );
+
+ break;
+
+ } /* end if */
+
+ /* $ means succeed if at end of line, but only in special contexts. */
+ /* If randomly in the middle of a pattern, it is a normal character. */
+ if ( p == pend ||
+ *p == _TEXT( '\n' ) ||
+ ( obscure_syntax & RE_CONTEXT_INDEP_OPS ) ||
+ ( obscure_syntax & RE_NO_BK_PARENS ?
+ *p == _TEXT( ')' ) :
+ *p == _TEXT( '\\' ) &&
+ p[ 1 ] == _TEXT( ')' )
+ ) ||
+ ( obscure_syntax & RE_NO_BK_VBAR ?
+ *p == _TEXT( '|' ) :
+ *p == _TEXT( '\\' ) &&
+ p[ 1 ] == _TEXT( '|' )
+ )
+ ) {
+
+ PATPUSH( endline );
+
+ break;
+
+ } /* end if */
+
+ goto normal_char;
+
+ case _TEXT( '^' ):
+ /* ^ means succeed if at beg of line, but only if no preceding pattern. */
+
+ if ( laststart && p[ -2 ] != _TEXT( '\n' ) &&
+ !( obscure_syntax & RE_CONTEXT_INDEP_OPS )
+ ) goto normal_char;
+
+ if ( obscure_syntax & RE_TIGHT_VBAR ) {
+
+ if ( p != pattern + 1 &&
+ !( obscure_syntax & RE_CONTEXT_INDEP_OPS )
+ ) goto normal_char;
+
+ PATPUSH( begline );
+ begalt = b;
+
+
+ } else PATPUSH( begline );
+
+ break;
+
+ case _TEXT( '+' ):
+ case _TEXT( '?' ):
+
+ if ( obscure_syntax & RE_BK_PLUS_QM ) goto normal_char;
+
+handle_plus:
+
+ case _TEXT( '*' ):
+ /* If there is no previous pattern, char not special. */
+
+ if ( !laststart && !( obscure_syntax & RE_CONTEXT_INDEP_OPS ) ) goto normal_char;
+
+ /* If there is a sequence of repetition chars, */
+ /* collapse it down to equivalent to just one. */
+ zero_times_ok = 0;
+ many_times_ok = 0;
+
+ while ( 1 ) {
+
+ zero_times_ok |= c != _TEXT( '+' );
+ many_times_ok |= c != _TEXT( '?' );
+
+ if ( p == pend ) break;
+
+ PATFETCH( c );
+
+ if ( c == _TEXT( '*' ) )
+ ;
+ else if ( !( obscure_syntax & RE_BK_PLUS_QM ) &&
+ ( c == _TEXT( '+' ) || c == _TEXT( '?' ) )
+ );
+ else if ( ( obscure_syntax & RE_BK_PLUS_QM ) && c == _TEXT( '\\' ) ) {
+
+ long c1;
+
+ PATFETCH( c1 );
+
+ if ( !( c1 == _TEXT( '+' ) || c1 == _TEXT( '?' ) ) ) {
+
+ PATUNFETCH;
+ PATUNFETCH;
+
+ break;
+
+ } /* end if */
+
+ c = c1;
+
+ } else {
+
+ PATUNFETCH;
+
+ break;
+
+ } /* end else */
+
+ } /* end while */
+
+ /* Star, etc. applied to an empty pattern is equivalent */
+ /* to an empty pattern. */
+
+ if ( !laststart ) break;
+
+ /* Now we know whether 0 matches is allowed, */
+ /* and whether 2 or more matches is allowed. */
+
+ if ( many_times_ok ) {
+ /* If more than one repetition is allowed, */
+ /* put in a backward jump at the end. */
+
+ store_jump ( b, maybe_finalize_jump, laststart - 3L );
+ b += 3;
+
+ } /* end if */
+
+ insert_jump ( on_failure_jump, laststart, b + 3, b );
+ pending_exact = NULL;
+ b += 3;
+
+ if ( !zero_times_ok ) {
+ /* At least one repetition required: insert before the loop */
+ /* a skip over the initial on-failure-jump instruction */
+
+ insert_jump ( dummy_failure_jump, laststart, laststart + 6L, b );
+ b += 3;
+
+ } /* end if */
+
+ break;
+
+ case _TEXT( '.' ):
+
+ laststart = b;
+ PATPUSH( anychar );
+
+ break;
+
+ case _TEXT( '[' ):
+
+ while ( b - bufp -> buffer >
+ ( int )( bufp->allocated - 3 - ( 1 << BYTEWIDTH ) / BYTEWIDTH )
+ ) /* Note that EXTEND_BUFFER clobbers c */ EXTEND_BUFFER;
+
+ laststart = b;
+
+ if ( *p == _TEXT( '^' ) )
+
+ PATPUSH( charset_not ), p++;
+
+ else
+
+ PATPUSH( charset );
+
+ p1 = p;
+ PATPUSH( ( 1 << BYTEWIDTH ) / BYTEWIDTH );
+ /* Clear the whole map */
+ memset ( b, 0, ( 1 << BYTEWIDTH ) / BYTEWIDTH * sizeof ( TCHAR ) );
+
+ /* Read in characters and ranges, setting map bits */
+ while ( 1 ) {
+
+ PATFETCH( c );
+
+ if ( c == _TEXT( ']' ) && p != p1 + 1 ) break;
+
+ if ( *p == _TEXT( '-' ) && p[ 1 ] != _TEXT( ']' ) ) {
+
+ PATFETCH( c1 );
+ PATFETCH( c1 );
+
+ if ( translate )
+
+ while ( c <= c1 ) {
+
+ _TUCHAR mapped_c = translate[ c ];
+ b[ mapped_c / BYTEWIDTH ] |= 1 << ( mapped_c % BYTEWIDTH );
+ ++c;
+
+ } /* end while */
+
+ else
+
+ while ( c <= c1 ) b[ c / BYTEWIDTH ] |= 1 << ( c % BYTEWIDTH ), c++;
+
+ } else {
+
+ if ( translate ) c = translate[ c ];
+
+ b[ c / BYTEWIDTH ] |= 1 << ( c % BYTEWIDTH );
+
+ } /* end else */
+
+ } /* end while */
+
+ /* Discard any bitmap bytes that are all 0 at the end of the map. */
+ /* Decrement the map-length byte too. */
+ while ( ( int )b[ -1 ] > 0 && b[ b[ -1 ] - 1 ] == 0 ) b[ -1 ]--;
+
+ b += b[ -1 ];
+
+ break;
+
+ case _TEXT( '(' ):
+
+ if ( !( obscure_syntax & RE_NO_BK_PARENS ) )
+ goto normal_char;
+ else
+ goto handle_open;
+
+ case _TEXT( ')' ):
+ if ( !( obscure_syntax & RE_NO_BK_PARENS ) )
+ goto normal_char;
+ else
+ goto handle_close;
+
+ case '\n':
+ if ( !( obscure_syntax & RE_NEWLINE_OR ) )
+ goto normal_char;
+ else
+ goto handle_bar;
+
+ case _TEXT( '|' ):
+ if ( !( obscure_syntax & RE_NO_BK_VBAR ) )
+ goto normal_char;
+ else
+ goto handle_bar;
+
+ case _TEXT( '\\' ):
+
+ if ( p == pend ) goto invalid_pattern;
+
+ PATFETCH_RAW( c );
+
+ switch ( c ) {
+
+ case _TEXT( '(' ):
+
+ if ( obscure_syntax & RE_NO_BK_PARENS ) goto normal_backsl;
+
+handle_open:
+
+ if ( stackp == stacke ) goto nesting_too_deep;
+
+ if ( regnum < RE_NREGS ) {
+
+ PATPUSH( start_memory );
+ PATPUSH( regnum );
+
+ } /* end if */
+
+ *stackp++ = b - bufp -> buffer;
+ *stackp++ = fixup_jump ? fixup_jump - bufp -> buffer + 1L : 0L;
+ *stackp++ = regnum++;
+ *stackp++ = begalt - bufp -> buffer;
+ fixup_jump = NULL;
+ laststart = NULL;
+ begalt = b;
+
+ break;
+
+ case _TEXT( ')' ):
+
+ if ( obscure_syntax & RE_NO_BK_PARENS ) goto normal_backsl;
+
+handle_close:
+
+ if ( stackp == stackb ) goto unmatched_close;
+
+ begalt = *--stackp + bufp -> buffer;
+
+ if ( fixup_jump ) store_jump ( fixup_jump, jump, b );
+
+ if ( stackp[ -1 ] < RE_NREGS ) {
+
+ PATPUSH( stop_memory );
+ PATPUSH( stackp[ -1 ] );
+
+ } /* end if */
+
+ stackp -= 2;
+ fixup_jump = NULL;
+
+ if ( *stackp ) fixup_jump = *stackp + bufp -> buffer - 1L;
+
+ laststart = *--stackp + bufp -> buffer;
+
+ break;
+
+ case _TEXT( '|' ):
+
+ if ( obscure_syntax & RE_NO_BK_VBAR ) goto normal_backsl;
+
+handle_bar:
+
+ insert_jump ( on_failure_jump, begalt, b + 6, b );
+ pending_exact = NULL;
+ b += 3;
+
+ if ( fixup_jump ) store_jump ( fixup_jump, jump, b );
+
+ fixup_jump = b;
+ b += 3;
+ laststart = 0;
+ begalt = b;
+
+ break;
+
+ case _TEXT( 'w' ):
+
+ laststart = b;
+ PATPUSH( wordchar );
+
+ break;
+
+ case _TEXT( 'W' ):
+
+ laststart = b;
+ PATPUSH( notwordchar );
+
+ break;
+
+ case _TEXT( '<' ):
+
+ PATPUSH( wordbeg );
+
+ break;
+
+ case _TEXT( '>' ):
+
+ PATPUSH( wordend );
+
+ break;
+
+ case _TEXT( 'b' ):
+
+ PATPUSH( wordbound );
+
+ break;
+
+ case _TEXT( 'B' ):
+
+ PATPUSH( notwordbound );
+
+ break;
+
+ case _TEXT( '`' ):
+
+ PATPUSH( begbuf );
+
+ break;
+
+ case _TEXT( '\'' ):
+
+ PATPUSH( endbuf );
+
+ break;
+
+ case _TEXT( '1' ):
+ case _TEXT( '2' ):
+ case _TEXT( '3' ):
+ case _TEXT( '4' ):
+ case _TEXT( '5' ):
+ case _TEXT( '6' ):
+ case _TEXT( '7' ):
+ case _TEXT( '8' ):
+ case _TEXT( '9' ):
+
+ c1 = c - _TEXT( '0' );
+
+ if ( ( int )c1 >= regnum ) goto normal_char;
+
+ for ( stackt = stackp - 2; stackt > stackb; stackt -= 4 )
+
+ if ( *stackt == ( long )c1 ) goto normal_char;
+
+ laststart = b;
+ PATPUSH( duplicate );
+ PATPUSH( c1 );
+
+ break;
+
+ case _TEXT( '+' ):
+ case _TEXT( '?' ):
+
+ if ( obscure_syntax & RE_BK_PLUS_QM ) goto handle_plus;
+
+ default:
+
+normal_backsl:
+
+ /* You might think it would be useful for \ to mean */
+ /* not to translate; but if we don't translate it */
+ /* it will never match anything. */
+ if ( translate ) c = translate[ c ];
+
+ goto normal_char;
+
+ } /* end switch */
+
+ break;
+
+ default:
+
+normal_char:
+
+ if ( !pending_exact ||
+ pending_exact + *pending_exact + 1L != b ||
+ *pending_exact == 0177 ||
+ *p == _TEXT( '*' ) ||
+ *p == _TEXT( '^' ) ||
+ ( ( obscure_syntax & RE_BK_PLUS_QM ) ?
+ *p == _TEXT( '\\' ) &&
+ ( p[ 1 ] == _TEXT( '+' ) ||
+ p[ 1] == _TEXT( '?' )
+ ) :
+ ( *p == _TEXT( '+' ) ||
+ *p == _TEXT( '?' )
+ )
+ )
+ ) {
+
+ laststart = b;
+ PATPUSH( exactn );
+ pending_exact = b;
+ PATPUSH( 0 );
+
+ } /* end if */
+
+ PATPUSH( c );
+ ( *pending_exact )++;
+
+ } /* end switch */
+
+ } /* end while */
+
+ if ( fixup_jump ) store_jump ( fixup_jump, jump, b );
+
+ if ( stackp != stackb ) goto unmatched_open;
+
+ bufp -> used = b - bufp -> buffer;
+
+ return NULL;
+
+invalid_pattern: return _TEXT( "invalid regular expression" );
+
+unmatched_open: return _TEXT( "unmatched \\(" );
+
+unmatched_close: return _TEXT( "unmatched \\)" );
+
+end_of_pattern: return _TEXT( "premature end of regular expression" );
+
+nesting_too_deep: return _TEXT( "nesting too deep" );
+
+too_big: return _TEXT( "regular expression too big" );
+
+memory_exhausted: return _TEXT( "Memory exhausted" );
+
+} /* end re_compile_pattern */
+/***/
+/******************************************************************************/
+/* */
+/* Store where `from' points a jump operation to jump to where `to' points. */
+/* `opcode' is the opcode to store. */
+/* */
+/******************************************************************************/
+/***/
+static void store_jump ( _TCHAR* from, _TCHAR opcode, _TCHAR* to ) {
+
+ from[ 0 ] = opcode;
+ from[ 1 ] = ( to - ( from + 3 ) ) & CHAR_MASK;
+ from[ 2 ] = ( to - ( from + 3 ) ) >> BYTEWIDTH;
+
+} /* end store_jump */
+/***/
+/******************************************************************************/
+/* */
+/* Open up space at char FROM, and insert there a jump to TO. */
+/* CURRENT_END gives te end of the storage no in use, */
+/* so we know how much data to copy up. */
+/* OP is the opcode of the jump to insert. */
+/* */
+/* If you call this function, you must zero out pending_exact. */
+/* */
+/******************************************************************************/
+/***/
+static void insert_jump (
+ _TCHAR op, _TCHAR* from, _TCHAR* to, _TCHAR* current_end
+ ) {
+
+ _TCHAR* pto = current_end + 3;
+ _TCHAR* pfrom = current_end;
+
+ while ( pfrom != from ) *--pto = *--pfrom;
+
+ store_jump ( from, op, to );
+
+} /* end insert_jump */
+/***/
+/******************************************************************************/
+/* */
+/* Given a pattern, compute a fastmap from it. */
+/* The fastmap records which of the (1 << BYTEWIDTH) possible characters */
+/* can start a string that matches the pattern. */
+/* This fastmap is used by re_search to skip quickly over totally implausible */
+/* text. */
+/* The caller must supply the address of a (1 << BYTEWIDTH)-byte data area */
+/* as bufp->fastmap. */
+/* The other components of bufp describe the pattern to be used. */
+/* */
+/******************************************************************************/
+/***/
+void re_compile_fastmap ( PRE_PATTERN_BUFFER bufp ) {
+
+ int j, size = bufp -> used;
+
+ _TUCHAR* pattern = (_TUCHAR* )bufp -> buffer;
+ _TUCHAR* p = pattern;
+ _TUCHAR* pend = pattern + size;
+ _TUCHAR* translate = (_TUCHAR* )bufp -> translate;
+ _TCHAR* fastmap = bufp -> fastmap;
+ _TUCHAR* stackb[ NFAILURES ];
+ _TUCHAR** stackp = stackb;
+
+ memset ( fastmap, 0, ( 1 << BYTEWIDTH ) * sizeof ( TCHAR ) );
+ bufp -> fastmap_accurate = 1;
+ bufp -> can_be_null = 0;
+
+ while ( p ) {
+
+ if ( p == pend ) {
+
+ bufp -> can_be_null = 1;
+
+ break;
+
+ } /* end if */
+
+ switch ( ( enum regexpcode )*p++ ) {
+
+ case exactn:
+
+ if ( translate )
+ fastmap[ translate[ p[ 1 ] ] ] = 1;
+ else
+ fastmap[ p[ 1 ] ] = 1;
+
+ break;
+
+ case begline:
+ case before_dot:
+ case at_dot:
+ case after_dot:
+ case begbuf:
+ case endbuf:
+ case wordbound:
+ case notwordbound:
+ case wordbeg:
+ case wordend:
+
+ continue;
+
+ case endline:
+
+ if ( translate )
+ fastmap[ translate[ _TEXT( '\n' ) ] ] = 1;
+ else
+ fastmap[ _TEXT( '\n' ) ] = 1;
+
+ if ( bufp -> can_be_null != 1 )
+ bufp -> can_be_null = 2;
+
+ break;
+
+ case finalize_jump:
+ case maybe_finalize_jump:
+ case jump:
+ case dummy_failure_jump:
+
+ bufp -> can_be_null = 1;
+ j = *p++ & CHAR_MASK;
+ j += SIGN_EXTEND_CHAR( *( char* )p ) << BYTEWIDTH;
+ p += j + 1; /* The 1 compensates for missing ++ above */
+
+ if ( j > 0 ) continue;
+
+ /* Jump backward reached implies we just went through */
+ /* the body of a loop and matched nothing. */
+ /* Opcode jumped to should be an on_failure_jump. */
+ /* Just treat it like an ordinary jump. */
+ /* For a * loop, it has pushed its failure point already; */
+ /* if so, discard that as redundant. */
+ if ( ( enum regexpcode )*p != on_failure_jump ) continue;
+
+ ++p;
+ j = *p++ & CHAR_MASK;
+ j += SIGN_EXTEND_CHAR( *( char* )p ) << BYTEWIDTH;
+ p += j + 1; /* The 1 compensates for missing ++ above */
+
+ if ( stackp != stackb && *stackp == p ) stackp--;
+
+ continue;
+
+ case on_failure_jump:
+
+ j = *p++ & CHAR_MASK;
+ j += SIGN_EXTEND_CHAR( *( char* )p ) << BYTEWIDTH;
+ p++;
+ *++stackp = p + j;
+
+ continue;
+
+ case start_memory:
+ case stop_memory:
+
+ ++p;
+
+ continue;
+
+ case duplicate:
+
+ bufp -> can_be_null = 1;
+ fastmap[ _TEXT( '\n' )] = 1;
+
+ case anychar:
+
+ for ( j = 0; j < ( 1 << BYTEWIDTH ); j++ )
+
+ if ( j != _TEXT( '\n' ) ) fastmap[ j ] = 1;
+
+ if ( bufp -> can_be_null ) return;
+
+ /* Don't return; check the alternative paths */
+ /* so we can set can_be_null if appropriate. */
+ break;
+
+ case wordchar:
+
+ for ( j = 0; j < ( 1 << BYTEWIDTH ); j++ )
+
+ if ( SYNTAX( j ) == Sword ) fastmap[ j ] = 1;
+
+ break;
+
+ case notwordchar:
+
+ for ( j = 0; j < ( 1 << BYTEWIDTH ); j++ )
+
+ if ( SYNTAX( j ) != Sword ) fastmap[ j ] = 1;
+
+ break;
+
+ case charset:
+
+ for ( j = *p++ * BYTEWIDTH - 1; j >= 0; j-- )
+
+ if ( p[ j / BYTEWIDTH ] & ( 1 << ( j % BYTEWIDTH ) ) ) {
+
+ if ( translate )
+ fastmap[ translate[ j ] ] = 1;
+ else
+ fastmap[ j ] = 1;
+
+ } /* end if */
+
+ break;
+
+ case charset_not:
+ /* Chars beyond end of map must be allowed */
+ for ( j = *p * BYTEWIDTH; j < ( 1 << BYTEWIDTH ); j++ )
+
+ if ( translate )
+ fastmap[ translate[ j ] ] = 1;
+ else
+ fastmap[ j ] = 1;
+
+ for ( j = *p++ * BYTEWIDTH - 1; j >= 0; j-- )
+
+ if ( !( p[ j / BYTEWIDTH ] & ( 1 << ( j % BYTEWIDTH ) ) ) ) {
+
+ if ( translate )
+ fastmap[ translate[ j ] ] = 1;
+ else
+ fastmap[ j ] = 1;
+
+ } /* end if */
+
+ break;
+
+ } /* end switch */
+
+ /* Get here means we have successfully found the possible starting */
+ /* characters of one path of the pattern. We need not follow this */
+ /* path any farther. Instead, look at the next alternative remembered */
+ /* in the stack. */
+ if ( stackp != stackb )
+ p = *stackp--;
+ else
+ break;
+
+ } /* end while */
+
+} /* end re_compile_fastmap */
+/***/
+/******************************************************************************/
+/* */
+/* Like re_search_2, below, but only one string is specified. */
+/* */
+/******************************************************************************/
+/***/
+int re_search (
+ PRE_PATTERN_BUFFER pbufp, _TCHAR* string, int size, int startpos,
+ int range, PRE_REGISTERS regs
+ ) {
+
+ return re_search_2 (
+ pbufp, NULL, 0, string, size, startpos, range, regs, size
+ );
+
+} /* end re_search */
+/***/
+/******************************************************************************/
+/* */
+/* Like re_match_2 but tries first a match starting at index STARTPOS, */
+/* then at STARTPOS + 1, and so on. */
+/* RANGE is the number of places to try before giving up. */
+/* If RANGE is negative, the starting positions tried are */
+/* STARTPOS, STARTPOS - 1, etc. */
+/* It is up to the caller to make sure that range is not so large */
+/* as to take the starting position outside of the input strings. */
+/* */
+/* The value returned is the position at which the match was found, */
+/* or -1 if no match was found, */
+/* or -2 if error (such as failure stack overflow). */
+/* */
+/******************************************************************************/
+/***/
+int re_search_2 (
+ PRE_PATTERN_BUFFER pbufp,
+ _TCHAR* string1, int size1, _TCHAR* string2, int size2,
+ int startpos, int range, PRE_REGISTERS regs, int mstop
+ ) {
+
+ _TCHAR* fastmap = pbufp -> fastmap;
+ _TUCHAR* translate = (_TUCHAR* )pbufp -> translate;
+
+ int total = size1 + size2;
+ int val;
+
+ /* Update the fastmap now if not correct already */
+ if ( fastmap && !pbufp -> fastmap_accurate ) re_compile_fastmap ( pbufp );
+
+ /* Don't waste time in a long search for a pattern */
+ /* that says it is anchored. */
+ if ( pbufp -> used > 0 &&
+ ( enum regexpcode )pbufp -> buffer[ 0 ] == begbuf &&
+ range > 0
+ ) {
+
+ if ( startpos > 0 )
+ return -1;
+ else
+ range = 1;
+
+ } /* end if */
+
+ while ( 1 ) {
+
+ /* If a fastmap is supplied, skip quickly over characters */
+ /* that cannot possibly be the start of a match. */
+ /* Note, however, that if the pattern can possibly match */
+ /* the null string, we must test it at each starting point */
+ /* so that we take the first null string we get. */
+ if ( fastmap && startpos < total && pbufp -> can_be_null != 1 ) {
+
+ if ( range > 0 ) {
+
+ int lim = 0;
+ int irange = range;
+
+ _TUCHAR* p;
+
+ if ( startpos < size1 && startpos + range >= size1 )
+
+ lim = range - ( size1 - startpos );
+
+ p = ( ( _TUCHAR * )
+ &( startpos >= size1 ? string2 - size1 : string1 )[ startpos ]
+ );
+
+ if ( translate )
+
+ while ( range > lim && !fastmap[ translate[ *p++ ] ] ) range--;
+
+ else
+
+ while ( range > lim && !fastmap[ *p++ ] ) range--;
+
+ startpos += irange - range;
+
+ } else {
+
+ _TUCHAR c;
+
+ if ( startpos >= size1 )
+ c = string2[ startpos - size1 ];
+ else
+ c = string1[ startpos ];
+
+ c &= CHAR_MASK;
+
+ if ( translate ? !fastmap[ translate[ c ] ] : !fastmap[ c ] ) goto advance;
+
+ } /* end else */
+
+ } /* end if */
+
+ if ( range >= 0 &&
+ startpos == total &&
+ fastmap &&
+ pbufp -> can_be_null == 0
+ ) return -1;
+
+ val = re_match_2 ( pbufp, string1, size1, string2, size2, startpos, regs, mstop );
+
+ /* Propagate error indication if worse than mere failure. */
+ if ( val == -2 ) return -2;
+
+ /* Return position on success. */
+ if ( 0 <= val ) return startpos;
+
+advance:
+
+ if ( !range ) break;
+
+ if ( range > 0 )
+ range--, startpos++;
+ else
+ range++, startpos--;
+
+ } /* end while */
+
+ return -1;
+
+} /* end int re_search_2 */
+/***/
+/******************************************************************************/
+/* */
+/* */
+/******************************************************************************/
+/***/
+int re_match (
+ PRE_PATTERN_BUFFER pbufp, _TCHAR* string, int size, int pos,
+ PRE_REGISTERS regs
+ ) {
+
+ return re_match_2 ( pbufp, NULL, 0, string, size, pos, regs, size );
+
+} /* end re_match */
+/***/
+/******************************************************************************/
+/* */
+/* Maximum size of failure stack. Beyond this, overflow is an error. */
+/* */
+/******************************************************************************/
+/***/
+#define RE_MAX_FAILURES 65536
+/***/
+static int bcmp_translate();
+/***/
+/******************************************************************************/
+/* */
+/* Match the pattern described by PBUFP */
+/* against data which is the virtual concatenation of STRING1 and STRING2. */
+/* SIZE1 and SIZE2 are the sizes of the two data strings. */
+/* Start the match at position POS. */
+/* Do not consider matching past the position MSTOP. */
+/* */
+/* If pbufp->fastmap is nonzero, then it had better be up to date. */
+/* */
+/* The reason that the data to match are specified as two components */
+/* which are to be regarded as concatenated */
+/* is so this function can be used directly on the contents of an Emacs */
+/* buffer. */
+/* */
+/* -1 is returned if there is no match. -2 is returned if there is */
+/* an error (such as match stack overflow). Otherwise the value is the */
+/* length of the substring which was matched. */
+/* */
+/******************************************************************************/
+/***/
+int re_match_2 (
+ PRE_PATTERN_BUFFER pbufp,
+ _TUCHAR* string1, int size1, _TUCHAR* string2, int size2,
+ int pos, PRE_REGISTERS regs, int mstop
+ ) {
+
+ _TUCHAR* p = ( _TUCHAR* )pbufp -> buffer;
+ _TUCHAR* pend = p + pbufp -> used;
+ /* End of first string */
+ _TUCHAR* end1;
+ /* End of second string */
+ _TUCHAR* end2;
+ /* Pointer just past last char to consider matching */
+ _TUCHAR* end_match_1, *end_match_2;
+ _TUCHAR* d, *dend;
+ _TUCHAR* translate = ( _TUCHAR* ) pbufp -> translate;
+
+ int mcnt;
+
+ /* Failure point stack. Each place that can handle a failure */
+ /* further down the line pushes a failure point on this stack. */
+ /* It consists of two char *'s. */
+ /* The first one pushed is where to resume scanning the pattern; */
+ /* the second pushed is where to resume scanning the strings. */
+ /* If the latter is zero, the failure point is a "dummy". */
+ /* If a failure happens and the innermost failure point is dormant, */
+ /* it discards that failure point and tries the next one. */
+
+ _TUCHAR* initial_stack[ 2 * NFAILURES ];
+ _TUCHAR** stackb = initial_stack;
+ _TUCHAR** stackp = stackb, **stacke = &stackb[ 2 * NFAILURES ];
+
+ /* Information on the "contents" of registers. */
+ /* These are pointers into the input strings; they record */
+ /* just what was matched (on this attempt) by some part of the pattern. */
+ /* The start_memory command stores the start of a register's contents */
+ /* and the stop_memory command stores the end. */
+ /* */
+ /* At that point, regstart[regnum] points to the first character in */
+ /* the register, */
+ /* regend[regnum] points to the first character beyond the end of */
+ /* the register, */
+ /* regstart_seg1[regnum] is true iff regstart[regnum] points into string1, */
+ /* and regend_seg1[regnum] is true iff regend[regnum] points into string1. */
+
+ _TUCHAR* regstart[ RE_NREGS ];
+ _TUCHAR* regend[ RE_NREGS ];
+ _TUCHAR regstart_seg1[ RE_NREGS ], regend_seg1[ RE_NREGS ];
+
+ /* Set up pointers to ends of strings. */
+ /* Don't allow the second string to be empty unless both are empty. */
+ if ( !size2 ) {
+
+ string2 = string1;
+ size2 = size1;
+ string1 = NULL;
+ size1 = 0;
+
+ } /* end if */
+
+ end1 = string1 + size1;
+ end2 = string2 + size2;
+
+ /* Compute where to stop matching, within the two strings */
+ if ( mstop <= size1 ) {
+
+ end_match_1 = string1 + mstop;
+ end_match_2 = string2;
+
+ } else {
+
+ end_match_1 = end1;
+ end_match_2 = string2 + mstop - size1;
+
+ } /* end else */
+
+ /* Initialize \) text positions to -1 */
+ /* to mark ones that no \( or \) has been seen for. */
+
+ for ( mcnt = 0; mcnt < sizeof ( regend ) / sizeof( *regend ); mcnt++ )
+
+ regend[ mcnt ] = ( _TUCHAR* )-1;
+
+ /* `p' scans through the pattern as `d' scans through the data. */
+ /* `dend' is the end of the input string that `d' points within. */
+ /* `d' is advanced into the following input string whenever necessary, */
+ /* but this happens before fetching; */
+ /* therefore, at the beginning of the loop, */
+ /* `d' can be pointing at the end of a string, */
+ /* but it cannot equal string2. */
+ if ( pos <= size1 )
+ d = string1 + pos, dend = end_match_1;
+ else
+ d = string2 + pos - size1, dend = end_match_2;
+
+/* Write PREFETCH; just before fetching a character with *d. */
+#define PREFETCH while ( d == dend ) { \
+ if ( dend == end_match_2 ) goto fail; /* end of string2 => failure */ \
+ d = string2; /* end of string1 => advance to string2. */ \
+ dend = end_match_2; \
+ }
+
+ /* This loop loops over pattern commands. */
+ /* It exits by returning from the function if match is complete, */
+ /* or it drops through if match fails at this starting point in the input data. */
+ while ( 1 ) {
+
+ if (p == pend) { /* End of pattern means we have succeeded! */
+
+ if ( regs ) { /* If caller wants register contents data back, convert it to indices */
+
+ regs -> start[ 0 ] = pos;
+
+ if ( dend == end_match_1 )
+ regs -> end[ 0 ] = d - string1;
+ else
+ regs->end[ 0 ] = d - string2 + size1;
+
+ for ( mcnt = 1; mcnt < RE_NREGS; mcnt++ ) {
+
+ if ( regend[ mcnt ] == ( _TUCHAR* )-1 ) {
+
+ regs -> start[ mcnt ] = -1;
+ regs -> end[ mcnt ] = -1;
+
+ continue;
+
+ } /* end if */
+
+ if ( regstart_seg1[ mcnt ] )
+ regs -> start[ mcnt ] = regstart[ mcnt ] - string1;
+ else
+ regs -> start[ mcnt ] = regstart[ mcnt ] - string2 + size1;
+
+ if ( regend_seg1[ mcnt ] )
+ regs -> end[ mcnt ] = regend[ mcnt ] - string1;
+ else
+ regs -> end[ mcnt ] = regend[ mcnt ] - string2 + size1;
+
+ } /* end for */
+
+ } /* end if */
+
+ if ( dend == end_match_1 )
+ return ( d - string1 - pos );
+ else
+ return d - string2 + size1 - pos;
+
+ } /* end if */
+
+ /* Otherwise match next pattern command */
+ switch ( ( enum regexpcode )*p++ ) {
+
+ /* \( is represented by a start_memory, \) by a stop_memory. */
+ /* Both of those commands contain a "register number" argument. */
+ /* The text matched within the \( and \) is recorded under that number. */
+ /* Then, \<digit> turns into a `duplicate' command which */
+ /* is followed by the numeric value of <digit> as the register number. */
+ case start_memory:
+
+ regstart[ *p ] = d;
+ regstart_seg1[ *p++ ] = ( dend == end_match_1 );
+
+ break;
+
+ case stop_memory:
+
+ regend[ *p ] = d;
+ regend_seg1[ *p++ ] = ( dend == end_match_1 );
+
+ break;
+
+ case duplicate: {
+
+ int regno = *p++; /* Get which register to match against */
+ _TUCHAR *d2, *dend2;
+
+ /* Don't allow matching a register that hasn't been used. */
+ /* This isn't fully reliable in the current version, */
+ /* but it is better than crashing. */
+ if ( ( int )regend[ regno ] == -1 ) goto fail;
+
+ d2 = regstart[ regno ];
+ dend2 = ( ( regstart_seg1[ regno ] == regend_seg1[ regno] ) ?
+ regend[regno] :
+ end_match_1
+ );
+
+ while ( 1 ) {
+
+ /* Advance to next segment in register contents, if necessary */
+ while ( d2 == dend2 ) {
+
+ if ( dend2 == end_match_2 ) break;
+ if ( dend2 == regend[ regno ] ) break;
+
+ d2 = string2, dend2 = regend[ regno ]; /* end of string1 => advance to string2. */
+
+ } /* end while
+
+ /* At end of register contents => success */
+ if ( d2 == dend2 ) break;
+
+ /* Advance to next segment in data being matched, if necessary */
+ PREFETCH;
+
+ /* mcnt gets # consecutive chars to compare */
+ mcnt = dend - d;
+
+ if ( mcnt > dend2 - d2 ) mcnt = dend2 - d2;
+
+ /* Compare that many; failure if mismatch, else skip them. */
+ if ( translate ?
+ bcmp_translate ( d, d2, mcnt, translate ) :
+ memcmp ( d, d2, mcnt )
+ ) goto fail;
+
+ d += mcnt, d2 += mcnt;
+
+ } /* end while */
+
+ } /* duplicate */
+
+ break;
+
+ case anychar:
+
+ /* fetch a data character */
+ PREFETCH;
+ /* Match anything but a newline. */
+ if ( ( translate ? translate[ *d++ ] : *d++ ) == _TEXT( '\n' ) ) goto fail;
+
+ break;
+
+ case charset:
+ case charset_not: {
+
+ /* Nonzero for charset_not */
+ int not = 0;
+ int c;
+
+ if ( *( p - 1 ) == ( _TUCHAR ) charset_not ) not = 1;
+
+ /* fetch a data character */
+ PREFETCH;
+
+ if ( translate )
+ c = translate [ *d ];
+ else
+ c = *d;
+
+ if ( c < ( int )( *p * BYTEWIDTH ) &&
+ p[ 1 + c / BYTEWIDTH ] & ( 1 << ( c % BYTEWIDTH ) )
+ ) not = !not;
+
+ p += 1 + *p;
+
+ if ( !not ) goto fail;
+
+ ++d;
+
+ } /* charset & charset_not */
+
+ break;
+
+ case begline:
+
+ if ( d == string1 || d[ -1 ] == _TEXT( '\n' ) ) break;
+
+ goto fail;
+
+ case endline:
+
+ if ( d == end2 ||
+ ( d == end1 ? ( size2 == 0 ||
+ *string2 == _TEXT( '\n' )
+ )
+ : *d == _TEXT( '\n' )
+ )
+ ) break;
+
+ goto fail;
+
+ /* "or" constructs ("|") are handled by starting each alternative */
+ /* with an on_failure_jump that points to the start of the next alternative. */
+ /* Each alternative except the last ends with a jump to the joining point. */
+ /* (Actually, each jump except for the last one really jumps */
+ /* to the following jump, because tensioning the jumps is a hassle.) */
+ /* */
+ /* The start of a stupid repeat has an on_failure_jump that points */
+ /* past the end of the repeat text. */
+ /* This makes a failure point so that, on failure to match a repetition, */
+ /* matching restarts past as many repetitions have been found */
+ /* with no way to fail and look for another one. */
+ /* */
+ /* A smart repeat is similar but loops back to the on_failure_jump */
+ /* so that each repetition makes another failure point. */
+
+ case on_failure_jump:
+
+ if ( stackp == stacke ) {
+
+ _TUCHAR** stackx;
+
+ if ( stacke - stackb > RE_MAX_FAILURES ) return -2;
+
+ stackx = ( _TUCHAR** ) alloca ( 2 * ( stacke - stackb ) * sizeof ( _TCHAR* ) );
+ memcpy ( stackx, stackb, ( stacke - stackb ) * sizeof ( _TCHAR* ) );
+ stackp = stackx + ( stackp - stackb );
+ stacke = stackx + 2 * ( stacke - stackb );
+ stackb = stackx;
+
+ } /* end if */
+
+ mcnt = *p++ & CHAR_MASK;
+ mcnt += SIGN_EXTEND_CHAR( *( _TCHAR* )p ) << BYTEWIDTH;
+ ++p;
+ *stackp++ = mcnt + p;
+ *stackp++ = d;
+
+ break;
+
+ /* The end of a smart repeat has an maybe_finalize_jump back. */
+ /* Change it either to a finalize_jump or an ordinary jump. */
+ case maybe_finalize_jump:
+
+ mcnt = *p++ & CHAR_MASK;
+ mcnt += SIGN_EXTEND_CHAR( *( _TCHAR* )p ) << BYTEWIDTH;
+ ++p;
+
+ /* Compare what follows with the begining of the repeat. */
+ /* If we can establish that there is nothing that they would */
+ /* both match, we can change to finalize_jump */
+ if ( p == pend )
+ p[ -3 ] = ( _TUCHAR )finalize_jump;
+ else if ( *p == ( _TUCHAR )exactn ||
+ *p == ( _TUCHAR )endline
+ ) {
+
+ int c = *p == ( _TUCHAR ) endline ? _TEXT( '\n' ) : p[ 2 ];
+ _TUCHAR* p1 = p + mcnt;
+
+ /* p1[0] ... p1[2] are an on_failure_jump. */
+ /* Examine what follows that */
+ if ( p1[ 3 ] == ( _TUCHAR )exactn && p1[ 5 ] != c )
+ p[ -3 ] = ( _TUCHAR )finalize_jump;
+ else if ( p1[ 3 ] == ( _TUCHAR )charset ||
+ p1[ 3 ] == ( _TUCHAR )charset_not
+ ) {
+
+ int not = p1[ 3 ] == ( _TCHAR )charset_not;
+
+ if ( c < ( int )( p1[ 4 ] * BYTEWIDTH ) &&
+ p1[ 5 + c / BYTEWIDTH ] & ( 1 << ( c % BYTEWIDTH ) )
+ ) not = !not;
+
+ /* not is 1 if c would match */
+ /* That means it is not safe to finalize */
+ if ( !not ) p[ -3 ] = ( _TUCHAR )finalize_jump;
+
+ } /* end if */
+
+ } /* end if */
+
+ p -= 2;
+
+ if ( p[ -1 ] != ( _TUCHAR )finalize_jump ) {
+
+ p[ -1 ] = ( _TUCHAR ) jump;
+ goto nofinalize;
+
+ } /* end if */
+
+ /* The end of a stupid repeat has a finalize-jump */
+ /* back to the start, where another failure point will be made */
+ /* which will point after all the repetitions found so far. */
+
+ case finalize_jump:
+
+ stackp -= 2;
+
+ case jump:
+
+nofinalize:
+
+ mcnt = *p++ & CHAR_MASK;
+ mcnt += SIGN_EXTEND_CHAR( *( _TCHAR* )p ) << BYTEWIDTH;
+ p += mcnt + 1; /* The 1 compensates for missing ++ above */
+
+ break;
+
+ case dummy_failure_jump:
+
+ if ( stackp == stacke ) {
+
+ _TUCHAR** stackx =
+ ( _TUCHAR** ) alloca ( 2 * ( stacke - stackb ) * sizeof ( _TUCHAR* ) );
+
+ memcpy ( stackx, stackb, (stacke - stackb) * sizeof ( _TCHAR* ) );
+ stackp = stackx + ( stackp - stackb );
+ stacke = stackx + 2 * ( stacke - stackb );
+ stackb = stackx;
+
+ } /* end if */
+
+ *stackp++ = 0;
+ *stackp++ = 0;
+
+ goto nofinalize;
+
+ case wordbound:
+
+ if ( d == string1 || /* Points to first char */
+ d == end2 || /* Points to end */
+ ( d == end1 && size2 == 0 ) /* Points to end */
+ ) break;
+
+ if ( ( SYNTAX( d[ -1 ] ) == Sword ) !=
+ ( SYNTAX( d == end1 ? *string2 : *d ) == Sword )
+ ) break;
+
+ goto fail;
+
+ case notwordbound:
+
+ if ( d == string1 || /* Points to first char */
+ d == end2 || /* Points to end */
+ ( d == end1 && size2 == 0 ) /* Points to end */
+ ) goto fail;
+
+ if ( ( SYNTAX( d[ -1 ] ) == Sword ) !=
+ ( SYNTAX( d == end1 ? *string2 : *d ) == Sword )
+ ) goto fail;
+
+ break;
+
+ case wordbeg:
+
+ if ( d == end2 || /* Points to end */
+ ( d == end1 && size2 == 0) || /* Points to end */
+ SYNTAX( *( d == end1 ? string2 : d ) ) != Sword /* Next char not a letter */
+ ) goto fail;
+
+ if ( d == string1 || /* Points to first char */
+ SYNTAX( d[ -1 ] ) != Sword /* prev char not letter */
+ ) break;
+
+ goto fail;
+
+ case wordend:
+
+ if ( d == string1 || /* Points to first char */
+ SYNTAX( d[-1] ) != Sword /* prev char not letter */
+ ) goto fail;
+
+ if ( d == end2 || /* Points to end */
+ (d == end1 && size2 == 0) || /* Points to end */
+ SYNTAX( d == end1 ? *string2 : *d ) != Sword /* Next char not a letter */
+ ) break;
+
+ goto fail;
+
+ case wordchar:
+
+ PREFETCH;
+
+ if ( SYNTAX ( *d++ ) == 0 ) goto fail;
+
+ break;
+
+ case notwordchar:
+
+ PREFETCH;
+
+ if ( SYNTAX ( *d++ ) != 0 ) goto fail;
+
+ break;
+
+ case begbuf:
+
+ if ( d == string1 ) /* Note, d cannot equal string2 */
+ break; /* unless string1 == string2. */
+
+ goto fail;
+
+ case endbuf:
+
+ if ( d == end2 || ( d == end1 && size2 == 0 ) ) break;
+
+ goto fail;
+
+ case exactn:
+ /* Match the next few pattern characters exactly. */
+ /* mcnt is how many characters to match. */
+ mcnt = *p++;
+
+ if ( translate ) {
+
+ do {
+
+ PREFETCH;
+
+ if ( translate[ *d++ ] != *p++ ) goto fail;
+
+ } while ( --mcnt );
+
+ } else {
+
+ do {
+
+ PREFETCH;
+
+ if ( *d++ != *p++ ) goto fail;
+
+ } while ( --mcnt );
+
+ } /* end else */
+
+ break;
+
+ } /* end switch */
+
+ continue; /* Successfully matched one pattern command; keep matching */
+
+ /* Jump here if any matching operation fails. */
+fail:
+
+ if ( stackp != stackb ) { /* A restart point is known. Restart there and pop it. */
+
+ if ( !stackp[ -2 ] ) { /* If innermost failure point is dormant, */
+ /* flush it and keep looking */
+ stackp -= 2;
+
+ goto fail;
+
+ } /* end if */
+
+ d = *--stackp;
+ p = *--stackp;
+
+ if ( d >= string1 && d <= end1 ) dend = end_match_1;
+
+ } else break; /* Matching at this starting point really fails! */
+
+ } /* end while */
+
+ return -1; /* Failure to match */
+
+} /* end re_search_2 */
+/***/
+/******************************************************************************/
+/* */
+/* */
+/******************************************************************************/
+/***/
+static int bcmp_translate (
+ _TUCHAR* s1, _TUCHAR* s2, int len, _TUCHAR* translate
+ ) {
+
+ _TUCHAR *p1 = s1, *p2 = s2;
+
+ while ( len ) {
+
+ if ( translate [ *p1++ ] != translate [ *p2++] ) return 1;
+
+ --len;
+
+ } /* end while */
+
+ return 0;
+
+} /* end bcmp_translate */
+/***/
+/******************************************************************************/
--- /dev/null
+#define EXPORT
+#include <iostream.h>
+#include <stdlib.h>
+#include <io.h>
+#include <sys/stat.h>
+
+#include <OSD_WNT.h>
+#include <OSD_File.hxx>
+#include <OSD_Path.hxx>
+#include <OSD_Protection.hxx>
+
+typedef struct _delete_data {
+
+ BOOL forceReadOnly;
+ BOOL fRecurse;
+
+ } DELETE_DATA, *PDELETE_DATA;
+
+typedef BOOL ( *RM_FUNC ) ( LPCTSTR, BOOL, void* );
+
+static BOOL _rm_func ( LPTSTR, BOOL, void* );
+static void _print_error ( LPCTSTR );
+
+static int nFiles;
+
+#define USAGE() { cerr << "Usage: wokRM [-rfq] file(s)\n"; return ( 1 ); }
+
+extern "C" __declspec( dllexport ) int wokRM ( int, char** );
+
+int wokRM ( int argc, char** argv ) {
+
+ int i, retVal = 0;
+ char* ptr;
+ DELETE_DATA dd = { FALSE, FALSE };
+ char buff[ _MAX_PATH ];
+ char path[ _MAX_PATH ];
+ char name[ _MAX_FNAME + _MAX_EXT ];
+ char drive[ _MAX_DRIVE ];
+ char dir[ _MAX_DIR ];
+ char fname[ _MAX_FNAME ];
+ char ext[ _MAX_EXT ];
+ BOOL fQuiet = FALSE;
+
+ if ( argc < 2 ) USAGE();
+
+ for ( i = 1; i < argc; ++i ) {
+
+ if ( argv[ i ][ 0 ] == '-' ) {
+
+ ptr = argv[ i ];
+
+ while ( *++ptr != 0 ) {
+
+ switch ( *ptr ) {
+
+ case 'f':
+ case 'F':
+
+ dd.forceReadOnly = TRUE;
+
+ break;
+
+ case 'r':
+ case 'R':
+
+ dd.fRecurse = TRUE;
+
+ break;
+
+ case 'q':
+ case 'Q':
+
+ fQuiet = TRUE;
+
+ break;
+
+ default:
+
+ USAGE();
+
+ } // end switch
+
+ } // end while
+
+ } else
+
+ break;
+
+ } // end for
+
+ if ( i == argc ) USAGE();
+
+ for ( ; i < argc; ++i ) {
+
+ nFiles = 0;
+
+ strcpy ( buff, argv[ i ] );
+
+ if (
+ GetFileAttributes ( buff ) == FILE_ATTRIBUTE_DIRECTORY &&
+ dd.fRecurse
+ ) strcat ( buff, "/*.*" );
+
+ _splitpath ( buff, drive, dir, fname, ext );
+ _makepath ( path, drive, dir, NULL, NULL );
+ _makepath ( name, NULL, NULL, fname, ext );
+
+ if ( !DirWalk ( path, name, ( RM_FUNC )_rm_func, dd.fRecurse, &dd ) ) retVal = 1;
+
+ if ( nFiles == 0 && !fQuiet ) {
+
+ cerr << "wokRM: could not find " << argv[ i ] << endl << flush;
+ retVal = 1;
+
+ } // end if
+
+ } // end for
+
+ return retVal;
+
+} // end main
+
+static BOOL _rm_func ( LPTSTR fileName, BOOL fDir, void* data ) {
+
+ BOOL fRetry = FALSE;
+ BOOL status;
+ PDELETE_DATA pData = ( PDELETE_DATA )data;
+
+ ++nFiles;
+
+ if ( pData -> forceReadOnly ) _chmod ( fileName, _S_IREAD | _S_IWRITE );
+retry:
+ if ( !fDir )
+
+ status = DeleteFile ( fileName );
+
+ else if ( pData -> fRecurse ) {
+
+ cerr << fileName << endl;
+ status = RemoveDirectory ( fileName );
+
+ }
+
+ if ( !status )
+
+ if ( GetLastError () == ERROR_ACCESS_DENIED &&
+ pData -> forceReadOnly &&
+ !fRetry
+ ) {
+
+ OSD_File aFile;
+ OSD_Protection aProt;
+ OSD_SingleProtection aPrt;
+
+ aFile.SetPath ( OSD_Path ( fileName ) );
+ aProt = aFile.Protection ();
+ aPrt = aProt.User ();
+ aProt.Add ( aPrt, OSD_RWXD );
+ aProt.SetUser ( aPrt );
+ aFile.SetProtection ( aProt );
+ _chmod ( fileName, _S_IREAD | _S_IWRITE );
+
+ fRetry = TRUE;
+
+ goto retry;
+
+ } else
+
+ _print_error ( fileName );
+
+ return status;
+
+} // end _deletreProc
+
+static void _print_error ( LPCTSTR fName ) {
+
+ DWORD errCode;
+ Standard_Character buffer[ 2048 ];
+
+ errCode = GetLastError ();
+
+ if ( !FormatMessage (
+ FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY,
+ 0, errCode, MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL ),
+ buffer, 2048, NULL
+ )
+ ) {
+
+ wsprintf ( buffer, "error code %d", errCode );
+ SetLastError ( errCode );
+
+ } // end if
+
+ cerr << "wokRM: could not remove " << fName << " - " << buffer << endl << flush;
+
+} // end _set_error