1
Developer's Corner / [FBSL] Environment class - for scripting support
« on: October 05, 2006, 03:13 PM »
Hello,
A great FBSL fan (Ferdinand Piatnik) has developped a very nice tool with it.
This is a 'shell' program like that does a lot of nice things.
Here is the whole description + source code + zipped attachement.
I propose class env as a tool to use with FBSL programs in BAT files.
When instance of class env is created it processes the FBSL program command parameters.
Features are:
options - parameters which begin with with "-" are treated as options.
First character after "-" is saved as option identification, the reminder of parameted is saved as option argument.
Options are processed until non option parameter is found.
fileset expansion - parameters which contain "*" or "?" joker characters are considered as fileset definition
and are expanded to list of files.
Joker characters are allowed anywhere in directory path(except for drive specification)
standard input redirection - parameter which starts with "<" defines STDIN file.
Parameter must be enclosed in quotes(") because of standard DOS(cmd.exe) processing.
standard output redirection - parameter which starts with ">" defines STDOUT file.
When parameter starts with >> then standard output is appended to specified file.
Parameter must be enclosed in quotes(") because of standard DOS(cmd.exe) processing.
These features are not enabled by default.
The Initialize method has three parameters:
%flags - sum of following flags is recognized at this time (-1 covers any present or future options):
env.C_OPT - option proccessing is enabled
env.C_FILES - fileset proccessing is enabled
env.C_STDIO - standard input/output proccessing is enabled
env.C_ESC - escaping of any proccessing is enabled(by prefixing parameter by character "/")
%fAllow - specifies file attributes which are allowed for files to be returned in fileset (when fileset expansion is enabled)
Default value is FILE_ATTRIBUTE_ARCHIVE+FILE_ATTRIBUTE_READONLY
%dAllow- specifies file attributes which are allowed for directories to be examined (when fileset expansion is enabled)
Default values is FILE_ATTRIBUTE_DIRECTORY+FILE_ATTRIBUTE_READONLY
Class env exposes following constants:
C_STDIO = 1 'allow redirection of STDIN, STDOUT
C_FILES = 2 'expand parameters with * and ?
C_ESC = 4 'parameters starting with \ are not processed(\ is trimmed off)
C_OPT = 8 'leading parameters starting with - are processed as options
Methods:
Method getFiles - returns array of files
Parameters:
$fname - file search string - it may contain "*" and "?" characters
$dir (default="") - directory string prepended to search string - must end with "\" ,
"*" and "?" characters are not allowed/processed
%fAllow (default=FILE_ATTRIBUTE_ARCHIVE+FILE_ATTRIBUTE_READONLY)
specifies file attributes which are allowed for files to be returned in fileset
%dAllow(default=FILE_ATTRIBUTE_DIRECTORY+FILE_ATTRIBUTE_READONLY)
specifies file attributes which are allowed for directories to be examined
Method redirectStdIn - specifies standard input file. True is returned if redirection succedes, false otherwise.
Parameter:
$p_fileName (default="")- specifies STDIN file. When "" then default STDIN is restored.
Method redirectStdOut - specifies standard output file. True is returned if redirection succedes, false otherwise.
Parameters:
$p_fileName (default="")- specifies STDOUT file.When "" then default STDOUT is restored.
$p_mode (default="w") - specifies write mode. When "w" text is written to new file. If "a" is specified, then text is appended to existing file.
Method printError writes text to FBSL console even if STDOUT is redirected.
Parameters:
$p_message - text to be written
$p_CRLF - (default=CRLF) - text to be appended to p_message
I could not find problems on my computer.
There is a bug/problem with use of _dup2 function for STDIN, but workaround with use of fflush corrected problems.
In Attachment there are files:
env.inc - env class definition
envDemo.fbs - demo FBSL script - called by demo.bat
demo.bat - BAT script to demonstrate uses of env class. If I knew how, I would make it better.
The Class code :
A great FBSL fan (Ferdinand Piatnik) has developped a very nice tool with it.
This is a 'shell' program like that does a lot of nice things.
Here is the whole description + source code + zipped attachement.
I propose class env as a tool to use with FBSL programs in BAT files.
When instance of class env is created it processes the FBSL program command parameters.
Features are:
options - parameters which begin with with "-" are treated as options.
First character after "-" is saved as option identification, the reminder of parameted is saved as option argument.
Options are processed until non option parameter is found.
fileset expansion - parameters which contain "*" or "?" joker characters are considered as fileset definition
and are expanded to list of files.
Joker characters are allowed anywhere in directory path(except for drive specification)
standard input redirection - parameter which starts with "<" defines STDIN file.
Parameter must be enclosed in quotes(") because of standard DOS(cmd.exe) processing.
standard output redirection - parameter which starts with ">" defines STDOUT file.
When parameter starts with >> then standard output is appended to specified file.
Parameter must be enclosed in quotes(") because of standard DOS(cmd.exe) processing.
These features are not enabled by default.
The Initialize method has three parameters:
%flags - sum of following flags is recognized at this time (-1 covers any present or future options):
env.C_OPT - option proccessing is enabled
env.C_FILES - fileset proccessing is enabled
env.C_STDIO - standard input/output proccessing is enabled
env.C_ESC - escaping of any proccessing is enabled(by prefixing parameter by character "/")
%fAllow - specifies file attributes which are allowed for files to be returned in fileset (when fileset expansion is enabled)
Default value is FILE_ATTRIBUTE_ARCHIVE+FILE_ATTRIBUTE_READONLY
%dAllow- specifies file attributes which are allowed for directories to be examined (when fileset expansion is enabled)
Default values is FILE_ATTRIBUTE_DIRECTORY+FILE_ATTRIBUTE_READONLY
Class env exposes following constants:
C_STDIO = 1 'allow redirection of STDIN, STDOUT
C_FILES = 2 'expand parameters with * and ?
C_ESC = 4 'parameters starting with \ are not processed(\ is trimmed off)
C_OPT = 8 'leading parameters starting with - are processed as options
Methods:
Method getFiles - returns array of files
Parameters:
$fname - file search string - it may contain "*" and "?" characters
$dir (default="") - directory string prepended to search string - must end with "\" ,
"*" and "?" characters are not allowed/processed
%fAllow (default=FILE_ATTRIBUTE_ARCHIVE+FILE_ATTRIBUTE_READONLY)
specifies file attributes which are allowed for files to be returned in fileset
%dAllow(default=FILE_ATTRIBUTE_DIRECTORY+FILE_ATTRIBUTE_READONLY)
specifies file attributes which are allowed for directories to be examined
Method redirectStdIn - specifies standard input file. True is returned if redirection succedes, false otherwise.
Parameter:
$p_fileName (default="")- specifies STDIN file. When "" then default STDIN is restored.
Method redirectStdOut - specifies standard output file. True is returned if redirection succedes, false otherwise.
Parameters:
$p_fileName (default="")- specifies STDOUT file.When "" then default STDOUT is restored.
$p_mode (default="w") - specifies write mode. When "w" text is written to new file. If "a" is specified, then text is appended to existing file.
Method printError writes text to FBSL console even if STDOUT is redirected.
Parameters:
$p_message - text to be written
$p_CRLF - (default=CRLF) - text to be appended to p_message
I could not find problems on my computer.
There is a bug/problem with use of _dup2 function for STDIN, but workaround with use of fflush corrected problems.
In Attachment there are files:
env.inc - env class definition
envDemo.fbs - demo FBSL script - called by demo.bat
demo.bat - BAT script to demonstrate uses of env class. If I knew how, I would make it better.
The Class code :
Code: Text [Select]
- Class env
- #DllDeclare crtdll(_dup As myDup, _dup2 As myDup2, _fileno As myFileNo, fopen As myFopen, fflush As myFflush)
- #DllDeclare kernel32(GetStdHandle, WriteConsole)
- 'http://msdn2.microsoft.com/en-us/library/8syseb29.aspx
- '
- Private
- Shared %d_stdIn = 0, %d_dupStdIn, %d_newStdIn = 0, %d_stdOut = 0, %d_dupStdOut, %d_newStdOut = 0
- Shared %d_errHandle = 0
- '
- Function redirect_($p_fileName, $p_mode, %p_old, %p_dup, %p_new)
- Const FAIL = -1
- Const NONE = 0
- Dim %d_tmp, d_handle
- If p_mode = "r" Then
- d_handle = STDIN
- Else
- d_handle = STDOUT
- End If
- If p_old = 0 Then 'get file descriptor and its duplicate
- p_old = myFileNo(d_handle)
- p_dup = myDup(p_old)
- End If
- If p_fileName = "" Then ' restore old
- If p_new <> 0 Then
- myFflush(d_handle)
- If myDup2(p_dup, p_old) = -1 Then
- Return(FALSE)
- End If
- p_new = 0
- End If
- Else
- %d_tmp = myFopen(p_fileName, p_mode) ' open new file
- If d_tmp = NONE Then Return(FALSE) 'failed to open file
- %d_tmp = myFileno(d_tmp) ' get file descriptor from file pointer
- If %d_tmp = FAIL Then ' 'failed to get file descriptor
- Return(FALSE)
- Else
- If myDup2(d_tmp, p_old) = FAIL Then Return(FALSE) 'failure
- p_new = d_tmp
- End If
- End If
- Return(TRUE)
- End Function
- Method Initialize(%flags = 0, _
- %fAllow = FILE_ATTRIBUTE_ARCHIVE + FILE_ATTRIBUTE_READONLY, _
- %dAllow = FILE_ATTRIBUTE_DIRECTORY + FILE_ATTRIBUTE_READONLY)
- Dim %f_stdio = flags BAnd C_STDIO
- Dim %f_files = flags BAnd C_FILES
- Dim %f_esc = flags BAnd C_ESC
- Dim %f_opt = flags BAnd C_OPT
- Dim %i, $v, %ok, $fin = "", $fout = "", $mode = ""
- argv[] = Command(1 - STANDALONE)
- For i = 2 - STANDALONE To CommandCount() - 1
- ok = TRUE
- v = Command(i)
- If f_esc Then
- If v{1} = "/" Then
- ok = FALSE
- f_opt = FALSE
- argv[] = Mid(v, 2)
- End If
- End If
- If ok Then
- If f_opt Then
- If v{1} = "-" Then
- If Mid(v, 2, 1) <> "" Then
- options = options & Mid(v, 2, 1)
- optv[] = Mid(v, 3)
- End If
- ok = FALSE
- Else
- f_opt = FALSE
- End If
- End If
- End If
- If ok Then
- If f_stdio Then
- If v{1} = ">" Then
- ok = FALSE
- If v{2} = ">" Then
- fout = Mid(v, 3)
- mode = "a"
- Else
- fout = Mid(v, 2)
- mode = "w"
- End If
- ElseIf v{1} = "<" Then
- ok = FALSE
- fin = Mid(v, 2)
- End If
- End If
- End If
- If ok Then
- If f_files Then
- If Instr(v, "*") Or Instr(v, "?") Then
- argv = Array_Merge(argv, getFiles(v, "", fAllow, dAllow))
- ok = FALSE
- End If
- End If
- End If
- If ok Then
- argv[] = v
- End If
- Next
- argc = Count(argv)
- If fin <> "" Then redirectStdIn(fin)
- If fout <> "" Then redirectStdOut(fout, mode)
- End Method
- '
- Public
- Dim options = "", optv[], argv[], %argc = 0
- Begin Const
- C_STDIO = 1 'allow redirection of STDIN,STDOUT
- C_FILES = 2 'expand parameters with * and ?
- C_ESC = 4 'parameters starting with \ are not processed(\ is trimmed off)
- C_OPT = 8 'leading parameters starting with - are processed as options
- End Const
- Method getFiles($fname, $dir = "", _
- %fAllow = FILE_ATTRIBUTE_ARCHIVE + FILE_ATTRIBUTE_READONLY, _
- %dAllow = FILE_ATTRIBUTE_DIRECTORY + FILE_ATTRIBUTE_READONLY)
- #DllDeclare crtdll("_findfirst" As myFFirst, "_findnext" As myFNext, "_findclose" As myFClose)
- 'http://msdn2.microsoft.com/en-us/library/kda16keh.aspx
- 'fname - path string with optional * and ? joker characters at any position
- 'dir - optional base directory - no joker characters allowed (must end with \)
- Dim arr[]
- Dim %p, %pJoker, %pRest = 0
- Dim $path = dir, $search = fname, $rest, $f
- Dim %fMask = BNot fAllow, %dMask = BNot dAllow
- Dim %fStat, %fHandle, %attr, %searchHandle, $fileInfo * MAX_PATH + 41
- 'are there any joker characters?
- pJoker = Instr(search, "*")
- p = Instr(search, "?")
- If p And p < pJoker Then pJoker = p
- '
- If pJoker Then 'jokers exist in search
- p = InstrRev(search, "\", pJoker)
- If p Then
- path = dir & Left(search, p) 'set new base directory
- search = Mid(search, p + 1)
- End If
- pRest = Instr(search, "\") 'is joker for directory?
- If pRest Then 'directory with joker characters
- rest = Mid(search, pRest + 1)
- search = Left(search, pRest - 1)
- End If
- End If
- fHandle = myFFirst(path & search, @fileInfo)
- fStat = fHandle
- While fStat <> -1
- 'f =TO_LPSTR( @fileInfo+20)
- If f{1} <> "." Then
- attr = GetMem(fileInfo, 0, %4)
- If pRest Then
- If Not (attr BAnd dMask) And (attr BAnd FILE_ATTRIBUTE_DIRECTORY) Then arr = Array_Merge(arr, getFiles(rest, path & To_Lpstr(@fileInfo + 20) & "\", fAllow, dAllow))
- Else
- If Not (attr BAnd fMask) Then arr[] = path & To_Lpstr(@fileInfo + 20)
- End If
- End If
- fStat = myFnext(fHandle, @fileInfo)
- Wend
- If fHandle <> -1 Then myFClose(fHandle)
- Return arr
- End Method
- Method printError($p_message, p_CRLF = CRLF)
- Dim %d_len, d_buf = $p_message & p_CRLF
- If d_errHandle = 0 Then d_errHandle = GetStdHandle(STD_ERROR_HANDLE)
- WriteConsole(d_errHandle, @d_buf, StrLen(d_buf), @d_len, 0)
- End Method
- Method redirectStdIn($p_fileName = "")
- Return(redirect_(p_fileName, "r", d_stdIn, d_dupStdIn, d_newStdIn))
- End Method
- Method redirectStdOut($p_fileName = "", $p_mode = "w")
- Return(redirect_(p_fileName, p_mode, d_stdOut, d_dupStdOut, d_newStdOut))
- End Method
- End Class