home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 18 REXX
/
18-REXX.zip
/
rxexp1.zip
/
install.cmd
Wrap
OS/2 REXX Batch file
|
1995-02-11
|
47KB
|
1,156 lines
/* ------------------------------------------------------------------ */
/* Contents: Some useful REXX functions */
/* */
/* Author: Bernd Schemmer */
/* Baeckerweg 48 */
/* 60316 Frankfurt am Main */
/* Germany */
/* CIS: 100104,613 */
/* */
/* Last Update: 11.02.1995 */
/* */
/* Distribution: Freeware, no warranty, use this functions on your */
/* own risk but please give credit were credit is due. */
/* Report all bugs and suggestions to the author. */
/* */
/* Notes: See comments below for documentation. */
/* ------------------------------------------------------------------ */
/* -------------------------- INSTALL CODE -------------------------- */
authornotice = '/* --------- written by Bernd Schemmer, CIS: 100104,613 ------------- */'
newFileLine = '/* ' || copies( '=', 66 ) || ' */'
/* install some error handlers */
SIGNAL ON HALT Name InstallEnd
SIGNAL ON NOVALUE
call charOut, 'Install the examples in the current directory (Y/n)? Y' || '08'x
userResponse = translate( left( strip( lineIn() ),1 ) )
if userResponse <> 'N' then
do
parse source . . installProgram
installCode = CharIn( installProgram, 1, Chars( InstallProgram ) )
if length( InstallCode ) <> 0 then
do
exampleEnd = 1
curExampleNo = 0
outputFileName = ''
do until exampleEnd = 0
exampleStart = pos( newFileLine, installCode, exampleEnd )
curExampleNo = curExampleNo + 1
exampleEnd = pos( newFileLine, installCode, exampleStart+1 )
outputFileName = 'EXP' || curExampleNo || '.CMD'
call CharOut , ' Creating the file "' || outputFileName || '" ...'
if stream( outputFileName, 'c', 'QUERY EXIST' ) <> '' then
'@del ' outputfileName '2>NUL 1>NUL'
call LineOut outputFileName, newFileLine
call LineOut outputFileName, authorNotice
if exampleEnd = 0 then
call CharOut outputFileName, substr( installCode ,,
exampleStart )
else
call CharOut outputFileName, substr( installCode ,,
exampleStart,,
exampleEnd - exampleStart )
call LineOut outputFileName
call lineOut , 'done.'
end /* do forever */
call lineOut , curExampleNo || ' example files written.'
end /* if length( installCode ) <> 0 then */
end /* if userResponse <> 'N' then */
InstallEnd:
exit 0
/* ---------------------- END OF INSTALL CODE ----------------------- */
/* ================================================================== */
/* check if this program is executed from within the macrospace */
if InMacroSpace() = 1 then
say "This program is executed from within the macro space"
else
say "This program is NOT executed from within the macro space"
RETURN
/* ------------------------------------------------------------------ */
/* function: check if the program is in the macrospace */
/* */
/* call: InMacroSpace */
/* */
/* returns: 1 - yes */
/* 0 - no */
/* */
InMacroSpace: PROCEDURE
SIGNAL ON SYNTAX NAME NotInMacroSpace
inMacroSpace = 1
dummy = sourceLine( 1 )
inMacroSpace = 0
NotInMacroSpace:
if inMacroSpace = 1 then
do
/* program seems to be in the macro space */
/* do a second check to be sure */
parse source . . thisFile
if fileSpec( "drive", thisFile ) <> '' then
inMacroSpace = 0 /* Oops, we are not in the macro space */
end /* if inMacroSpace = 1 */
RETURN inMacroSpace
/* ================================================================== */
/* sample code to test if a drive is ready */
do forever
call lineOut , "Enter the name of the drive to test " ,
"(RETURN to end): "
thisDrive = strip( lineIn() )
if thisDrive = "" then
leave
if DriveReady( thisDrive ) = 1 then
say "The drive <" || thisDrive || "> is ready."
else
say "The drive <" || thisDrive || "> is not ready."
end /* do forever */
exit 0
/* ------------------------------------------------------------------ */
/* function: test if a drive is ready */
/* */
/* call: DriveReady( testDrive ) */
/* */
/* where: testdrive - Name of the drive to test (e.g. "A:") */
/* */
/* returns: 1 - drive is ready */
/* 0 - drive is not ready */
/* */
DriveReady: PROCEDURE
parse arg driveToTest ":" .
thisRC = 0
/* install a temporary error handler to check */
/* if the drive ready */
SIGNAL ON NOTREADY Name DriveReadyEnd
call stream driveToTest || ":\*", "D"
thisRC = 1
DriveReadyEnd:
RETURN thisRC
/* ================================================================== */
/* sample code to test if a directory exist with restoring all */
/* directorys */
do forever
call lineOut , "Enter the name of the directory to test " ,
"(RETURN to end): "
thisDir = strip( lineIn() )
if thisDir = "" then
leave
if DirExist( thisDir ) <> "" then
say "The directory <" || thisDir || "> exist."
else
say "The directory <" || thisDir || "> does not exist."
end /* do forever */
exit 0
/* ------------------------------------------------------------------ */
/* function: test if a directory exist */
/* */
/* call: DirExist( testDir ) */
/* */
/* where: testDir - name of the directory to test */
/* */
/* returns: full name of the directory or "" if the directory */
/* don't exist */
/* */
DirExist: PROCEDURE
parse arg testDir .
/* init the return code */
thisRC = ""
/* install a temporary error handler to check */
/* if the drive with the directory to test is */
/* ready */
SIGNAL ON NOTREADY NAME DirDoesNotExist
call stream testDir || "\*", "D"
/* save the current directory of the current */
/* drive */
curDir = directory()
/* save the current directory of the drive */
/* with the directory to test */
curDir1 = directory( fileSpec( "drive", testDir ) )
/* test if the directory exist */
thisRC = directory( testDir )
/* restore the current directory of the drive */
/* with the directory to test */
call directory curDir1
/* restore the current directory of the current */
/* drive */
call directory curDir
DirDoesNotExist:
return thisRC
/* ================================================================== */
/* code sequence to get the no. of a sourceline at runtime */
/* Note that this code also functions in compiled REXX programs */
/* and in REXX programs loaded in the macro space. */
/* Usage example: */
/* You can use this technique in your programs to write an error */
/* handler which ignores errors in some lines but not in all. */
/** DO NOT CHANGE, ADD OR DELETE ONE OF THE FOLLOWING FOUR LINES! **/
SIGNAL I!.__CallUserProc1
I!.__CallUserProc1:
LineNo = sigl+2 /* no. of THIS line */
say "This is the line no. " || LineNo+1 || " of the source code."
/** DO NOT CHANGE, ADD OR DELETE ONE OF THE PRECEEDING FOUR LINES! **/
/* ================================================================== */
/* check if a name is the name of a file or the name of a device */
say 'Enter the name of a file or device:'
testFileName = lineIN()
if stream( testFileName, "c", "QUERY EXIST" ) <> "" then
if stream( testFileName, "c", "QUERY DATETIME" ) = "" then
say TestFileName || " is a device!"
else
say TestFileName || " is a file!"
else
say TestFileName || " does not exist!"
/* ================================================================== */
/* routine(s) to search a file in the directorys saved in an */
/* environment variable (e.g. "PATH") */
/* example call */
do forever
say "Enter a filename ("""" to abort):"
searchFile = strip( lineIn() )
if searchFile = '' then
leave
say "Result of SearchDataFile(" || searchFile || ") is: "
say " """ || SearchDataFile( searchFile ) || """"
say "Result of SearchProgram(" || searchFile || ") is: "
say " """ || SearchProgram( searchFile ) || """"
end /* do forever */
exit 0
/* ------------------------------------------------------------------ */
/* function: Search a file in the current directory and in the */
/* directorys saved in an environment variable */
/* (e.g. PATH, DPATH, ... ) */
/* */
/* call: SearchFile( fileName, varName {,environment}) */
/* */
/* where: fileName - name of the file to search */
/* varName - name of the environment variable containing */
/* the directorys to search */
/* environment - environment with the environment Variable */
/* (Def.: OS2ENVIRONMENT) */
/* */
/* returns: full name of the file or "" if not found */
/* */
SearchFile: PROCEDURE
parse arg fileName , envVar, environment
resultStr = ""
if fileName <> "" & envVar <> "" then
do
if environment = '' then
environment = "OS2ENVIRONMENT"
searchDirs = ".;" || value( envVar, , environment )
do forever
parse var searchDirs curSearchDir ";" searchDirs
curSearchDir = strip( curSearchDir )
if curSearchDir = "" then
iterate
if right( curSearchDir, 1 ) <> "\" & ,
right( curSearchDir, 1 ) <> ":" then
curSearchDir = curSearchDir || "\"
resultStr = stream( curSearchDir || fileName, "c", "QUERY EXIST" )
if resultStr <> "" then
leave
if SearchDirs = "" then
leave
end /* do forverver */
end /* if fileName <> "" & ... */
RETURN resultStr
/* ------------------------------------------------------------------ */
/* function: Search a file in the current directory and in the */
/* directorys saved in the environment variable PATH */
/* */
/* call: SearchProgram( progName {,environment}) */
/* */
/* where: progName - name of the program to search */
/* environment - environment with the environment Variable */
/* (Def.: OS2ENVIRONMENT) */
/* */
/* returns: full name of the program or "" if not found */
/* */
SearchProgram: PROCEDURE
parse arg progName , environment
resultStr = ""
if progName <> "" then
resultStr = SearchFile( progName, "PATH", environment )
RETURN resultStr
/* ------------------------------------------------------------------ */
/* function: Search a datafile in the current directory and in the */
/* directorys saved in the environment variable DPATH */
/* */
/* call: SearchProgram( datafileName {,environment}) */
/* */
/* where: datafileName - name of the datafile to search */
/* environment - environment with the environment Variable */
/* (Def.: OS2ENVIRONMENT) */
/* */
/* returns: full name of the datafile or "" if not found */
/* */
SearchDataFile: PROCEDURE
parse arg dataFileName , environment
resultStr = ""
if dataFileName <> "" then
resultStr = SearchFile( datafileName, "DPATH", environment )
RETURN resultStr
/* ================================================================== */
/* example for working on a directory tree without loading the dll */
/* REXXUTIL */
say 'Reading the directory tree of drive C: ...'
/* put a list of all directorys in the queue */
/* (use /FIFO to get the directorys in the */
/* right sequence) */
"@dir /s/f /Ad C:\ 2>NUL | RXQUEUE /FIFO"
say 'Copying the directorys into a stem ...'
foundedDirs.0 = 0
/* put the names of all founded directorys */
/* in a stem variable for further processing */
do while queued() <> 0
curDir = strip( lineIn( "QUEUE:" ) )
if curDir <> "" & ,
right( CurDir, 2 ) <> "\." & ,
right( CurDir, 3 ) <> "\.." then
do
j = foundedDirs.0 + 1
foundedDirs.j = curDir
foundedDirs.0 = j
end /* if curDir <> "" then */
end /* do while queued <> 0 */
do j = 1 to foundedDirs.0
say 'Directory no. ' || j || ' is: ' || foundedDirs.j
end /* do j = foundedDirs.0 */
/* ================================================================== */
/* example for simulating the BASIC input command */
/* example call ... */
thisString = input( "Enter a string: " )
say "You entered '" || thisString || "'."
exit
/* ------------------------------------------------------------------ */
/* function: simulate the BASIC command INPUT */
/* */
/* call: input( prompt ) */
/* */
/* where: prompt - prompt for the input */
/* */
/* returns: entered string */
/* */
input:
parse arg prompt
call charOut , prompt
RETURN lineIn()
/* ================================================================== */
/* example for a simple yes/no question without loading the dll */
/* REXXUTIL */
'@cls' /* this technique won't work in the */
/* last line of the display! */
/* example call ... */
thisKey = AskUser( "YN" "Enter Y or N: " )
say "You entered '" || thisKey || "'."
exit 0
/* ------------------------------------------------------------------ */
/* AskUser - get input from the user */
/* */
/* Usage: AskUser akeys prompt */
/* */
/* where: */
/* akeys - allowed keys (all keys are translated to */
/* uppercase) */
/* prompt - prompt for the ask */
/* */
/* Returns: the pressed key in uppercase */
/* */
/* note: This routine uses ESC sequences to position the cursor */
/* This routine only works, if you do not use the */
/* last line of the screen for the prompt! */
/* */
AskUser: PROCEDURE
parse arg aKeys prompt
aKeys = translate( akeys )
call charout , prompt
thisKey = " "
do UNTIL pos( thisKey , aKeys ) <> 0
call charOut ,"1B"x || "[s" || "1B"x || "[K"
thisKey = translate( charIn() )
call CharOut , "1B"x || "[u"
/* delete the CR/LF sequence from */
/* the keyboard buffer! */
dummy = lineIn()
end /* do until ... */
/* do a linefeed */
say ""
RETURN thisKey
/* ================================================================== */
/* example for an in progress output */
/* note: This code uses ESC sequences to position the cursor */
progressChar="\"
do until lines( "C:\OS2\INSTALL\DATABASE.TXt" ) = 0
/* get next cmd from input channel */
/* this is an example to do something */
curLine = LINEIN( "C:\OS2\INSTALL\DATABASE.TXT" )
/* show progress indicator */
if progressChar="\" then
progressChar="/"
else
progressChar="\"
/* use ESC sequences to position */
/* the cursor */
call charOut , "1B"x || "[s Reading " || progressChar || "1B"x || "[u"
/* ... */
end /* do until lines() = 0 */
/* do a linefeed */
say ""
exit 0
/* ================================================================== */
/* example code to show how to use a directory name to get an unique */
/* name */
uniqueName = ""
do i = 1 to 999 until rc = 0
uniqueName = "C:\TEMP\unique." || i
/* try to create a directory */
/* OS/2 checks that only ONE process */
/* can create the directory! */
"@md " uniqueName "1>NUL 2>NUL"
end /* do i = 1 to 999 */
if rc == 0 then
say "The unique name is" uniqueName
else
say "No unique name found!"
/* do something */
/* ... */
/* free the name */
"@rd " uniqueName "1>NUL 2>NUL"
exit 0
/* ================================================================== */
/* example code to show how to use a queue name to get an unique */
/* name */
/* create a queue with an unique name */
uniqueName = rxqueue( "create" )
say "The unique name is" uniqueName
/* do something */
/* ... */
/* free the name */
call rxqueue "Delete", uniqueName
exit 0
/* ================================================================== */
/* example code to show how to use a directory name as semaphor in */
/* REXX */
semName = "C:\TEMP\MYSEM"
/* test and set the semaphor */
do until rc = 0
/* note: in a real program you should */
/* also check for a timeout! */
"@md " semName "1>NUL 2>NUL"
end /* do until rc = 0 */
/* semaphor set -- now it's our turn */
/* to do something */
/* ... */
/* free the semaphor */
"@rd " semName "1>NUL 2>NUL"
exit 0
/* ================================================================== */
/* example code to show how to use a queue name as semaphor in */
/* REXX */
semName = "MYSEM"
/* test and set the semaphor */
do until uniqueName == semName
/* note: in a real program you should */
/* also check for a timeout! */
uniqueName = rxqueue( "create", semName )
if uniqueName <> semName then
do
/* queue already exists -- delete the */
/* new created queue! */
call rxqueue "delete", uniqueName
end /* if uniqueName <> semName then */
end /* do until uniqueName == semName */
/* semaphor set -- now it's our turn */
/* to do something */
/* ... */
/* free the semaphor */
call rxqueue 'Delete', semName
exit 0
/* ================================================================== */
/* sample code to show how to get the filesystem (FAT, HPFS, CDFS */
/* or LAN) of a drive */
/* Tested with OS/2 v2.99 WARP BETA 2 (english) and OS/2 Version 3 */
/* Warp (german) */
/* drives to check */
possibleDrives = "CDEFGHI"
do i = 1 to length( possibleDrives )
curdrive = substr( possibleDrives,i,1 )
/* use an unknown parameter for */
/* CHKDSK to suppress all actions */
/* (except the print of the */
/* filesystem) */
"@chkdsk " curDrive || ": /dfadfaf 2>NUL | rxqueue 2>NUL"
do while queued() <> 0
curLine = lineIN( "QUEUE:" )
if abbrev( curLine, "Dateisystemtyp für den Datenträger ist:" ) | ,
abbrev( curLine, "The type of file system for the disk is" ) then
do
curFileSystem = word( curLine, words( curLine ) )
if right( curFileSystem,1 ) == "." then
curFileSystem = dbrright( curFileSystem,1 )
say "The filesystem of drive " || curDrive || ": is " curFileSystem
end /* if abbrev( ... */
end /* do while queued() <> 0 */
end /* do i = 1 to ... */
/* ================================================================== */
/* example code to check if a file exists. This function also checks, */
/* if the name is already used by a directory or a device (e.g. CON) */
do until fileName = ""
call charOut, "Enter a filename to check: "
fileName = lineIN()
say "The result of FileExist(" || fileName || ") is: " || ,
FileExist( fileName )
end /* do until iLIne = "" */
exit 0
/* ------------------------------------------------------------------ */
/* function: check if a file exists */
/* */
/* call: FileExist fileToTest */
/* */
/* where: fileToTest - name of the file to test */
/* */
/* returns: -2 - invalid parameter */
/* -1 - can not detect (e.g. the drive is not ready) */
/* 0 - neither a file, a device nor a directory with this */
/* name exist */
/* 1 - the file exist */
/* 2 - a device driver with the name exists */
/* 3 - a directory with the name exists */
/* */
FileExist: PROCEDURE
parse arg fileName .
/* install temporary error handler */
SIGNAL ON NOTREADY NAME FileExistError
SIGNAL ON FAILURE NAME FileExistError
SIGNAL ON ERROR NAME FileExistError
thisRC = -2 /* rc = -2 ->> invalid parameter */
/* check the parameter */
if strip( fileName ) <> "" then
do
thisRC = -1 /* rc = -1 ->> can not detect the result */
/* check if the drive with the file is ready */
call stream fileName
/* turn of some error handling so we can */
/* determine if the given name is the name of */
/* a device (for example "LPT1") */
SIGNAL OFF NOTREADY
if stream( fileName, "c", "QUERY EXIST" ) <> "" then
do
/* seems that the file exists -- check if */
/* it is a device */
if stream( fileName, "c", "QUERY DATETIME" ) == "" then
thisRC = 2 /* rc = 2 ->> this is a device name */
else
thisRC = 1 /* rc = 1 ->> this is a file name */
end /* if stream( ... */
else
do
/* seems that the file does not exist -- */
/* check if a directory with the name for the */
/* file exist */
/* save the current directory of the current */
/* drive */
thisDir = directory()
/* save the current directory of the drive */
/* with the file to check */
tempDir = directory( fileSpec( "Drive", fileName ) )
if directory( fileName ) <> "" then
thisRC = 3 /* rc = 3 ->> a dir with this name exist */
else
thisRC = 0 /* rc = 0 ->> neither a file, a device nor a */
/* dir with this name exist */
/* restore the current directory of the drive */
/* with the directory to check */
call directory tempDir
/* restore the current directory of the */
/* current drive */
call directory thisDir
end /* else */
end /* if strip( fileName ) <> "" then */
FileExistError:
RETURN thisRC
/* ================================================================== */
/* sample code to extend the FILESPEC function with code to extract */
/* the extension of a filename */
do until myInput = ""
say "Enter the parameter for FILESPEC(option, fileName): "
myInput = strip( lineIn() )
if myInput <> "" then
do
parse var myInput myOption "," myFileName
say "The result of FILESPEC( " myOption "," myFileName ") is: "
say "<" || fileSpec( myOption, myFileName ) || ">"
end /* if myInput <> "" then */
end /* do until myInput = "" */
exit 0
/* ------------------------------------------------------------------ */
/* function: extended FILESPEC function */
/* */
/* call: FileSpec option,filename */
/* */
/* where: option */
/* - E{xtension} */
/* return the extension of the file */
/* All other values for "option" are processed by the */
/* original FILESPEC function. */
/* filename */
/* - name of the file */
/* */
/* returns: if option = E{xtension}: */
/* the extension of the filename or "" if none */
/* else */
/* the return code of the original FILESPEC function */
/* or "SYNTAX ERROR" if called with invalid parameter(s) */
/* */
/* notes: To call the original FILESPEC function direct use */
/* myResult = "FILESPEC"( option, filename ) */
/* */
FileSpec: PROCEDURE
parse arg option, fileName
/* init the return code */
thisRC = "SYNTAX ERROR"
/* install a local error handler */
SIGNAL ON SYNTAX NAME FileSpecError
option = translate( strip( option ) )
/* check the option code */
if abbrev( "EXTENSION", option ) = 1 then
do
/* process the new added option code */
i = lastPos( ".", fileName )
if i > lastPos( "\", fileName ) then
thisRC = substr( fileName, i+1 )
else
thisRC = ""
end
else /* call the original FILESPEC function */
thisRC = "FILESPEC"( option, fileName )
FileSpecError:
RETURN thisRC
/* ================================================================== */
say 'See source file for functions.'
/* ------------------------------------------------------------------ */
/* function: create a directory(tree) */
/* */
/* call: CreateDirectory dirToCreate */
/* */
/* where: dirToCreate - directory to create */
/* */
/* */
/* returns: 0 - okay */
/* else OS Error */
/* */
CreateDirectory: PROCEDURE
parse arg dirToCreate
/* file or device for messages */
prog.__LogAll = "2>NUL 1>NUL"
/* init the return code */
thisRC = -1
/* check if the drive is ready */
SIGNAL ON NOTREADY Name CreateDirectoryError
call stream fileSpec( "drive", dirToCreate ) || "\*"
thisRC = 0
/* save the current directory(s) */
curDir = directory()
curDir1 = directory( fileSpec( "drive", dirToCreate ) )
newDir = translate( dirToCreate, "\", "/" )
i = pos( ":", dirToCreate )
if i <> 0 then
do
parse var dirToCreate lwForTheDir ":" dirToCreate
if directory( lwForTheDir || ":\" ) = "" then
thisRC = 1
end /* if i <> 0 then */
if thisRC = 0 then
do
if right( dirToCreate, 1 ) <> "\" then
dirToCreate = dirToCreate || "\"
do until dirToCreate = "" | thisRC <> 0
parse var dirToCreate newSubDir "\" dirToCreate
dirToCreate = strip( dirToCreate )
if directory( newSubDir ) = "" then
do
"@md " newSubDir prog.__LogAll
if rc = 2 | rc = 1 then
do
if stream( newSubDir , "c", "QUERY EXIST" ) <> "" then
thisRC = rc
end /* if rc = 2 | rc = 1 */
else
thisRC = rc
if thisRC = 0 then
call directory newSubDir
end /* if directory( newSubDir ) = "" then */
end /* do until dirToCreate = "" | thisRC <> 0 */
end /* if thisRC = 0 then */
/* restore the current directory(s) */
call directory curDir1
call directory curDir
CreateDirectoryError:
RETURN thisRC
/* ------------------------------------------------------------------ */
/* function: delete all files in a directory and in all it's */
/* sub directorys! */
/* */
/* call: DeleteDirectory dirToDelete */
/* */
/* where: dirToDelete - directory to delete */
/* */
/* returns: 0 - okay */
/* -1 - drive not ready */
/* */
DeleteDirectory: PROCEDURE
parse arg dirToDelete
/* file or device for messages */
prog.__LogAll = "2>NUL 1>NUL"
/* init the return code */
thisRC = -1
/* check if the drive is ready */
SIGNAL ON NOTREADY Name DeleteDirectoryError
call stream fileSpec( "drive", dirToDelete ) || "\*"
/* put a list of all subdirectorys in the */
/* queue */
"@dir /s/f /Ad " dirToDelete "2>NUL | RXQUEUE /lifo "
do while queued() <> 0
dirToDel = lineIn( "QUEUE:" )
if dirTodel <> "" & right( dirToDel,2 ) <> "\." & ,
right( dirToDel,3 ) <> "\.." then
do
"@attrib -r -s -h " dirToDel || "\*.*" prog.__LogAll
"@(echo Y & echo J ) | del " dirToDel || "\*.*" prog.__LogAll
if dirToDel <> dirToDelete then
"@rd " dirToDel prog.__LogAll
end /* if dirToDel <> "" then */
end /* do while queued <> 0 */
"@attrib -r -s -h " dirToDelete || "\*.*" prog.__LogAll
"@(echo Y & echo J) | del " dirToDelete || "\*.*" prog.__LogAll
"@rd " dirToDelete prog.__logAll
thisRC = 0
DeleteDirectoryError:
RETURN thisRC
/* ================================================================== */
/* example code to navigate a program by monitoring its output and */
/* sending the neccessary keystrokes to it. */
/* */
/* Notes: The program to navigate must use STDIN for its input and */
/* STDOUT and/or STDERR for its output. */
/* */
/* Some OS/2 commands write all or parts of their output to */
/* STDERR if STDOUT is redirected to a file or into a pipe! */
/* Some OS/2 commands do NOT write a CR/LF after a prompt for */
/* an input. This is for example true for the FORMAT program. */
/* To get around this, we always wait for the line preceding */
/* the prompts from the FORMAT program (see below). */
/* */
/* */
/* In this example we use "FORMAT A: /q" */
/* */
/* Save this code in a file with the name "TEST.CMD" and call it with */
/* TEST <RETURN> */
/* */
/* Tested with OS/2 WARP Version 3 (german) and OS/2 WARP BETA 2 */
/* Version 2.99 (english) */
/* */
/* */
/* get the name of our program */
parse source . . prog.__Name
/* output device for our messages (we can not */
/* use STDOUT for the messages!!! */
prog.__outputDevice = "STDERR:"
/* get the parameter to check if this is the */
/* first, second or third call */
parse arg prog.__Parameter .
select
/*************************** third process ****************************/
/* --- put the output of the format command into the queue (FIFO) --- */
when prog.__Parameter == "$$THIRD$$" then
do
thisLine = ""
/* this process ends after writing the last */
/* output message of FORMAT into the queue */
/* message 1273 = "Eine weitere Diskette formatieren (J/N)?" GER */
/* "Format another diskette (Y/N)? USA */
lastFormatMsg = SysGetMessage( 1273 )
do until pos( lastFormatMsg, thisLine ) <> 0
if lines() <> 0 then
do
/* read the output of the FORMAT program ... */
thisLine = lineIN()
/* ... and write it into the REXX queue */
queue thisLine
end /* if lines() <> 0 then */
end /* do until pos( lastFormatMsg, ... */
/* put the end marker for process 2 into the */
/* queue */
queue "***END***"
end /* when */
/*************************** second process ***************************/
/* --- monitor the output of the FORMAT command and write the --- */
/* neccessary input for the FORMAT command to STDOUT */
when prog.__Parameter == "$$SECOND$$" then
do
/* init the variables with the messages */
/* indicating that FORMAT needs some input */
/* message 1507 = "Dateisystemtyp für den Datenträger ist: " GER */
/* "The type of file system for the disk is " USA */
firstAskForInput = substr( SysGetMessage( 1507 ), 1, 25 )
/* message 1288 = "Namen für den Datenträger (max. ... " GER */
/* "Enter up to 11 characters for the ..." USA */
secondAskForInput = substr( SysGetMessage( 1288 ), 1, 45 )
/* message 1306 = "%1 verfügbare Zuordnungseinheiten ... " GER */
/* "%1 available allocation units on disk." USA */
thirdAskForInput = substr( SysGetMessage( 1306 ), 3, 20 )
outputOK = 0
/* just for fun: Show an "in progress" message */
call charOut prog.__OutputDevice , "Formating "
do until OutputOK == 1
call charOut prog.__OutputDevice, "\" || "08"X || "/" || "08"x
/* wait until output of the FORMAT command is */
/* available */
if queued() == 0 then
iterate
/* monitor the output from the FORMAT command */
curFormatLine = strip( lineIn( "QUEUE:" ) )
/* check if the FORMAT command ended */
if curFormatLine = "***END***" then
OutputOk = 1
select
when pos( FirstAskForInput, curFormatLine ) <> 0 then
do
/* FORMAT needs some input to begin the */
/* format -- so give it a CR/LF */
call lineOut , ""
end /* when */
when pos( SecondAskForInput, curFormatLine ) <> 0 then
do
/* FORMAT needs some input for the volume */
/* label -- so give it the label */
call lineOut , "Test"
end /* when */
when pos( thirdAskForInput, curFormatLine ) <> 0 then
do
/* FORMAT needs to know if it should format */
/* another diskette -- tell it that we won't */
/* format another diskette */
call lineOut, "N"
end /* when */
otherwise
do
/* do nothing */
end /* otherwise */
end /* select */
end /* do until OutputOK == 1 */
/* end the in progress message */
call lineOut prog.__OutputDevice, "... done."
end /* when */
/***************************** first call *****************************/
/* --- execute the FORMAT command --- */
otherwise
do
"@cls"
call lineOut prog.__OutputDevice, ""
call lineOut prog.__OutputDevice,,
"Example for navigating a program " || ,
"by monitoring the output"
call lineOut prog.__outputDevice,,
"Here we call FORMAT A: /Q to show how it works."
call lineOut prog.__OutputDevice, ""
if queued() <> 0 then
do
/* flush the REXX queue */
do while queued() <> 0
tempLine = lineIn( "QUEUE:" )
end /* do while queued() <> 0 */
end /* if queued() <> 0 then */
/* load the neccessary functions from the DLL */
/* REXXUTIL */
call LoadREXXUtil
/* wait until theres a diskette in drive A: */
call InsertDiskDialog
/* execute the FORMAT command with the input */
/* coming from a second copy of this program */
/* and the output written to a REXX queue by */
/* a third copy of this program */
"@cmd /c " prog.__Name "$$SECOND$$ | " || , /* second process */
" format A: /q | " || , /* FORMAT command */
prog.__Name "$$THIRD$$" /* third process */
end /* otherwise */
end /* select */
EXIT 0
/* ****************************************************************** */
/* sub routines */
/* ------------------------------------------------------------------ */
/* routine to wait until a diskette is in drive A: */
/* ------------------------------------------------------------------ */
InsertDiskDialog: PROCEDURE
InsertDiskDialogAgain:
/* install a local error handler to check if */
/* the drive A: is ready */
SIGNAL ON NOTREADY Name InsertDiskDialogAgain
call lineOut , "Insert a disk to FORMAT into drive A: " || ,
"and press enter"
tempLine = lineIn()
call stream "A:\*"
RETURN
/* ------------------------------------------------------------------ */
/* routine to load the neccessary functions from REXXUTIL */
/* ------------------------------------------------------------------ */
LoadREXXUtil: PROCEDURE
call rxFuncAdd "SysGetMessage", "REXXUTIL", "SysGetMessage"
/* install a local error handler to check if */
/* the DLL was loaded */
SIGNAL ON SYNTAX NAME LoadRexxUtilError
t = SysGetMessage( 1 )
RETURN
LoadREXXUtilError:
call lineOut, "Error: Can not load the DLL REXXUTIL!"
EXIT 255