Flex - File List EXecute - issues a command on a list of files.
* Function: (See the macro flexhelp)
* To run: Type "MACRO FLEX [-options] <"command"> [file masks]" from
* the KEDIT command line. The required argument
* specifies the command to execute. (See the macro flexhelp)
*
* Requires: KEDIT 4.0.
* Version: 1.0 (June 1989)
* Author: Dan McAnarney
*
*? how to handle a filled up ring
*? message in same column if files are on different paths.
* or using ring option and files are different lengths.
*? don't perform function on dir.dir file or dir.rng file
* exit gracefully when lastmsg contains error.
* - check to see if file should be qquit or kept in ring
* - only give message on first error in file list.
* - return to dir file
* exit gracefully when finished
* - put cursor back on command line
* nEEDS TO SKIP INVISIBLE LINES
*
* If argument is '?' or null show help.
*
if (arg(1) = '?') | (arg(1) = '')
then do
'macro flexhelp'
exit
end
*
* Default options:
* all default options are false (0) initially
*
print_width = 3
keep_all_files = 0
save_changed_files = 0
keep_changed_files = 0
dont_keep_message = 0
keep_first_word = 0
dir_append = 0
curr_dir = 0
search_ring = 0
curr_this_dir = 0
*
parameters = arg(1)
curr_pos = 1
*
* Extract command string
* Dec 15, 92 moved above extract options to allow for -'s in command string
*
do
command_start_pos = pos( '"', parameters, curr_pos)
if command_start_pos = 0
then do
'emsg Error: command string does not begin with a double-quote char'
exit
end
curr_pos = command_start_pos + 1
command_end_pos = pos( '"', parameters, curr_pos)
if command_end_pos = 0
then do
*
* may be due to use of linend char to perform multiple commands.
* make a macro to call instead of using the linend char.
*
'emsg Error: command string does not end with a double-quote char'
exit
end
command_str = substr( parameters, command_start_pos+ 1, command_end_pos - command_start_pos-1 )
end
*
* EXTRACT OPTION SWITCHES
*
curr_pos = 1
do forever
switch_pos = pos( '-', parameters, curr_pos)
curr_pos = switch_pos + 1
if switch_pos = 0 then leave
if (switch_pos > command_start_pos ) & (switch_pos < command_end_pos )
then iterate
option = substr( parameters, curr_pos, 1 )
if lower(option) = 'k' then keep_all_files = 1
else if lower(option) = 'r' then search_ring = 1
else if lower(option) = 's' then save_changed_files = 1
* else if lower(option) = 'f' then keep_changed_files = 1
else if lower(option) = 'a' then dir_append = 1
else if lower(option) = 'l' then curr_dir = 1
else if lower(option) = 't' then curr_this_dir = 1
else if lower(option) = 'n' then dont_keep_message = 1
else if lower(option) = 'w' then keep_first_word = 1
else do
'emsg Invalid option:' option
exit
end
end
*
* Extract File mask
*
curr_pos = command_end_pos + 1
if length( parameters) > curr_pos
then do length( parameters) - curr_pos
mask_start_char = substr( parameters, curr_pos, 1 )
if mask_start_char \= ' ' then leave
curr_pos = curr_pos + 1
end
file_mask = substr( parameters, curr_pos, length(parameters) - curr_pos + 1 )
*
* Extract ring information
*
'extract /ring'
if curr_this_dir \= 0
then dir_file_name = fileid.1()
else if search_ring \= 0
then do
dir_file_name = 'dir.rng'
'kedit ' dir_file_name '(nomsg new'
* if the file was already in the ring, clean it out.
* need to fix. Shouldn't process command on the file dir.rng.
'nomsg delete all'
do i = 1 to ring.0
file_name = substr(lower(ring.i), 1, pos(" ", ring.i, 1) )
if file_name ^= dir_file_name
then 'input' file_name
* 'input' file_name
end
end
*
* Make a directory of files to process
*
else do
dir_file_name = 'dir.dir'
if curr_dir
then do
'kedit ' dir_file_name
* need to fix. give an error message if file is empty.
end
else if dir_append
then 'nomsg dira' file_mask
else 'nomsg dir' file_mask
if rc \= 0
then do
'emsg Invalid file mask or no files match mask'
exit
end
end
*
* We have the list of files to process. Begin processing files in the list.
*
* The variable file_counter is used to prevent an infinite loop on a
* command which modifies the dir.dir file ( "dir" or "dira" )
*
do file_counter = 1 to size.1()
':'file_counter
'sos makecurr'
*
* If you look into subdirs it probably will trash your dir.dir file.
* So make it only not skip when user specifies this file
* Plus we now have to do a "dir" instead of a "kedit" on these items.
*
if substr(curline.3(), 17, 5) = '' & ^curr_this_dir
then iterate
*
* edit the file and extract the alteration count to determine if
* the command changes the file.
*
* Jul 17 96 added double quotes around file name to allow for spaces in NT names
*
if substr(curline.3(), 17, 5) = ''
then 'dir"'dirfileid.1()'"'
else 'kedit"'dirfileid.1()'"(nodefext'
'extract /alt/'
*
* Process the command on the file, extracting the last message.
*
*
* need to check. Do we want 'sos execute' instead of 'command'?
*
'command' command_str
return_code = rc
'extract /lastmsg/'
if lower(word( lastmsg.1, 1 )) = 'error'
then do
* need to add and first file
'emsg Error occured executing flex command.' command_str
* 'emsg 'lastmsg.1
'emsg Do you wish to continue? [Y/N]'
'readv key'
if ( lower(readv.2) = 'n' )
then exit
* exit gracefully
end
changed = (alt.1 ^= alt.1() )
if ( changed ^= 0 )
then if ( save_changed_files = 1 )
then 'save'
else 'qquit'
*
* probably have already kept or tossed this file: it looks as if the
* option to use the files in the ring won't keep them in the ring
*
* Keep this file in the ring?
* if we're keeping all files, keep it.
* otherwise check to see if the file was originally in the ring
* before we toss it.
*
if ( search_ring = 0 ) & ( keep_all_files = 0 )
then do
keep_in_ring = 0
do i = 1 to ring.0
* should drop out of loop when found and not check against entire
* ring
if (lower(fileid.1()) = lower(substr(ring.i,1,pos(' ',ring.i))))
then keep_in_ring = 1
end
* need to fix. if we changed the file and keep flag and save flag are
* both false we default to keep ( by not using QQuit). Is this ok?
if \keep_in_ring then 'quit'
end
*
* go back to the directory and add the last message to the file
*
'kedit ' dir_file_name
'sos current'
'sos endchar'
'cursor right'
*
* need two spaces before we append the message
*
if ^dont_keep_message
then if keep_first_word
then 'text ' word( lastmsg.1, 1 )
else 'text ' lastmsg.1
'refresh'
if eof()
then leave
end
*
* display the command issued
*
*Apr 12 91 added cursor cmdline
'cursor cmdline'
'msg command issued on files in list was:' command_str
*'restore'
*
* drop all used variables.
*
drop alt changed command_end_pos command_start_pos command_str curr_dir
drop curr_pos curr_this_dir dir_append file_mask i keep_all_files
drop keep_in_ring lastmsg mask_start_char option
drop parameters print_width return_code ring save_changed_files search_ring
drop switch_pos file_counter dir_file_name dont_keep_message keep_first_word
drop file_name