home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 18 REXX
/
18-REXX.zip
/
cmdpk164.zip
/
xdir.cmd
< prev
next >
Wrap
OS/2 REXX Batch file
|
1998-01-10
|
26KB
|
800 lines
/* This is CommandPak's xdir command */
/* (w) 1996-98 Martin Lafaix, Ulrich Möller */
/* Options: type xdir -h */
signal on halt
signal on syntax name syntax
signal on failure name syntax
call init
parse arg commandLine
do while commandLine \= ''
parse var commandLine left '"' file '"' commandLine
if left \= '' then call getOptions left
if file \=='' then call add file
end /* do */
if specs.0 = 0 & filespec = 0 then call add '*'
if sub & sortorder \= '' then sortorder = 'P' sortorder
do spec = 1 to specs.0
call emit spec
end /* do */
call terminate
exit
getOptions:
procedure expose nl wpabstract debug stdext ext wide UNIX full fullPath classify lowerc upperc verbose pause specs. attron attroff filespec sortorder sub processingInit invalidOpt lineCount height
if debug then Say "Entering options..."
parse arg opt
do while (opt \= "")
parse value opt with opt1 opt
if debug then do
Say nl||'Now parsing block "'opt1'"'
Say 'Remaining blocks: "'opt'"'
end
if (substr(opt1, 1, 1)="/") then
opt1 = lowercase(opt1)
if (substr(opt1, 1, 1)="-") | (substr(opt1, 1, 1)="/") then do
do optcount = 2 to length(opt1) by 1
switch = substr(opt1, optcount, 1)
if debug then say ' Now examining "'switch'"'
select
when (switch = 'w') & \full & \fullPath then do
wide = 1
UNIX = 0
end
when (switch = 'C') & \full & \fullPath then do
wide = 0
UNIX = 1
end
when (switch = 'F') then do
classify = 1
end
when (switch = 'D') then
debug = 1
when (switch = 'W') then
attron = attron||'W'
when (switch = 'b') | (switch = '1') then do
full = 1
wide = 0
UNIX = 0
end
when switch = 'p' then do
pause = 1
end
when switch = 'f' then do
fullPath = 1
wide = 0
UNIX = 0
end
when (switch = 'l') | (switch = "n") then do
wide = 0
UNIX = 0
ext = stdext
end
when switch = 'L' then lowerc = 1
when switch = 'U' then upperc = 1
when (switch = 's') | (switch = 'R') then sub = 1
when switch = 'd' then do; attron = "D"; attroff = ""; end;
when switch = 't' then sortorder = "D"
when switch = 'S' then sortorder = "S"
when (switch = '?') | (switch = 'h') then do
'call xhelp xdir'
exit 0
end
when switch = 'a' then do
if substr(opt1,3,1) \= ':' then
attroff = ''
else do
attr = translate(strip(substr(opt1,3),,':'))
attron = ''
attroff = ''
do while attr \= ''
if debug then say ' Subparsing attr: "'attr'"'
neg = left(attr,1) = '-'
if neg then attr = substr(attr,2)
if pos(left(attr,1),'HRSADW') > 0 then
if neg then
attroff = attroff||left(attr,1)
else
attron = attron||left(attr,1)
else
call invalidOption arg(1), attr
attr = substr(attr,2)
end /* do */
if debug then say ' Exiting attribs; attron = "'attron'"'
leave
end
end
when switch = 'x' then do
if debug then say ' Entering ext'
ext = ""
wide = 0
UNIX = 0
if (substr(opt1,3,1) \= ':') then
ext = "asel"
else do
ext2 = strip(substr(opt1,3),,':')
do while ext2 \= ''
if debug then say ' Subparsing ext2: "'ext2'" ext: "'ext'"'
if (pos(left(ext2,1),'adtsel') > 0) then
ext = ext||left(ext2,1)
else
call invalidOption arg(1), ext2
ext2 = substr(ext2,2)
end /* do */
if debug then say ' Exiting ext: "'ext'"'
leave
end
end
when (switch = 'o') then do
if substr(opt1,3,1) \= ':' then
sortorder = 'N'
else do
order = translate(strip(substr(opt1,3),,':'))
sortorder = ''
do while order \= ''
if debug then say ' Subparsing order: "'order'"'
neg = left(order,1) = '-'
if neg then order = substr(order,2)
if (pos(left(order,1),'NESDG') > 0) then do
if neg then
sortorder = sortorder '-'left(order,1)
else
sortorder = sortorder left(order,1)
end
else
call invalidOption arg(1), order
order = substr(order,2)
end /* do */
if debug then say ' Exiting order.'
leave
end /* else */
end /*when */
otherwise
call invalidOption arg(1), opt1
end /* select */
end /* do*/
end /* if */
else
call add opt1
if debug then say "Done with block."
end
if sub & full then
fullPath = 1
if debug then say "Exiting options."
return
invalidOption:
call display SysGetMessage(1003)
if words(arg(1)) > 1 | pos('/',arg(1),pos('/',arg(1))+1) > 0 then
call display SysGetMessage(1249,,'/'arg(2))
if processingInit then do
invalidOpt = 1
return
end
else
exit 1
add:
procedure expose specs. filespec
filespec = filespec + 1
i = specs.0 + 1
file = arg(1)
/*
* les divers cas sont :
*
* 1- chemin relatif dans l'unité courante
* 2- chemin absolu dans l'unité courante
* 3- chemin relatif dans une unité donnée
* 4- chemin absolu dans une unité donnée
*/
if substr(file,2,1) \= ':' then
file = filespec('d',directory())file
/*
* les cas 1- et 2- ont été traités
*/
if substr(file,3,1) \= '\' then
file = directory(filespec('d',file))'\'substr(file,3)
if left(file,1) = '\' then do
call display SysGetMessage(15)
return
end
/*
* directory() ajoute un '\' en fin de chaîne si c'est la racine
*/
if substr(file,4,1) = '\' then
file = delstr(file,4,1)
/*
* le résultat est-il un répertoire, ou une spécification de fichier ?
*/
if right(file,1) \= '\' & verify(file,'*?','M') = 0 then
if stream(file,'c','query exists') = '' & stream(file,'c','query datetime') \= '' then
file = file'\'
specs.i = file
specs.0 = i
return
init:
if RxFuncQuery("SysLoadFuncs") then do
call RxFuncAdd 'SysLoadFuncs','RexxUtil','SysLoadFuncs'
call SysLoadFuncs
end
if RxFuncQuery("VioLoadFuncs") then do
call RxFuncAdd 'VioLoadFuncs','REXXVIO','VioLoadFuncs'
call VioLoadFuncs
end
debug = 0
processingInit = 1
lineCount = 1
filespec = 0 /* no filespec found */
orgdir = directory() /* initial directory */
specs.0 = 0
sub = 0 /* /S */
wide = 0 /* /W */
UNIX = 0 /* -C */
full = 0 /* not /B */
fullPath = 0 /* not /F */
stdext = "dtse"
ext = stdext /* for -l: date, time, size, easize, name */
classify = 0 /* not -F (append '/', '*' etc.) */
lowerc = 0 /* -L */
upperc = 0 /* -U */
verbose = 0 /* /V */
pause = 0 /* /P */
attron = '' /* attributes required */
attroff = 'SH' /* attributes exclued */
sortorder = '' /* how to sort */
prevdrive = ''
prevrep = ''
prevfile = 0
partialSize = 0
partialCount = 0
totalSize = 0
totalCount = 0
dirLabel = strip(SysGetMessage(1054)) /* <DIR> */
parse value SysTextScreenSize() with height width .
ci = DosQueryCtryInfo()
iDate = c2d(substr(ci,9,1)) /* 0 = MDY, 1 = DMY, 2 = YMD */
iTime = c2d(substr(ci,28,1)) /* 0 = 12 Hour clock, 1 = 24 */
sThousands = substr(ci,18,1) /* ',' */
sDate = substr(ci,22,1) /* '/' */
sTime = substr(ci,24,1) /* ':' */
today = left(date('S'),4)*372+substr(date('S'),5,2)*31+right(date('S'),2)
normal = '1b'x'[0m'
bright = 1
underline = 4
blink = 5
black = 30
red = 31
green = 32
yellow = 33
blue = 34
magenta = 35
cyan = 36
white = 37
val = value('DIRCLR.ATTRIB',,'OS2ENVIRONMENT')
do while val \= ''
parse var val list ':' color ';' val
list = translate(list,' ',',')
do i = 1 to words(list)
call value 'dirclr._attrib_._'word(list,i), ansivalue(color)
end /* do */
end /* do */
val = value('DIRCLR.EXT',,'OS2ENVIRONMENT')
do while val \= ''
parse var val list ':' color ';' val
list = translate(list,' ',',')
do i = 1 to words(list)
call value 'dirclr._ext_.'word(list,i), ansivalue(color)
end /* do */
end /* do */
val = value('DIRCLR.NAME',,'OS2ENVIRONMENT')
do while val \= ''
parse var val list ':' color ';' val
list = translate(list,' ',',')
do i = 1 to words(list)
call value 'dirclr._name_.'word(list,i), ansivalue(color)
end /* do */
end /* do */
val = value('DIRCLR.DATE',,'OS2ENVIRONMENT')
do while val \= ''
parse var val list ':' color ';' val
dirclr._date_.newer = -list ansivalue(color)
end /* do */
val = value('DIRCLR.WPABSTRACT',,'OS2ENVIRONMENT')
do while val \= ''
parse var val color ';' val
dirclr._wpabstract_ = ansivalue(color)
if debug then say 'dirclr._wpabstract_: "'dirclr._wpabstract_'"'
end /* do */
val = value('XDIR.DIRCMD',,'OS2ENVIRONMENT')
if (val = "") then
val = value('DIRCMD',,'OS2ENVIRONMENT')
if (val \= "") then
call getOptions val
if invalidOpt = 1 then
call display SysGetMessage(3154,,'DIRCMD')
processingInit = 0
return
ansivalue:
litcolor = arg(1); ansicolor = ''; on = 0
do while litcolor \= ''
parse upper var litcolor item litcolor
if item = 'ON' then on = 10
else
ansicolor = ansicolor || ';' || value(item)+on
end /* do */
return '1b'x'['strip(ansicolor,'L',';')'m'
emitHeader1:
drive = SysDriveInfo(filespec('d',file))
rep = left(file,lastpos('\',file)-1)
if length(rep) = 2 then rep = rep'\'
/* displaying standard directory header */
if drive \= prevdrive then do
if prevdrive \= '' then call terminate
call display SysGetMessage(1516,,left(drive,1),word(drive,4))
call display SysGetMessage(1243,,translate('abcd:efgh',word(DosQueryFSInfo(drive),6),'abcdefgh'))
end
return
emitHeader2:
rep = strip(arg(1))
if length(rep) = 2 then rep = rep'\'
if rep \= prevrep then do
if partialCount > 0 then
if verbose then
call display SysGetMessage(1060,,format(partialCount,9),right(pprint(partialSize),13))'0d0a'x
else
call display SysGetMessage(1060,,format(partialCount,9),format(partialSize,10))'0d0a'x
partialSize = 0
partialCount = 0
call display SysGetMessage(1053,,rep)
end
else
if spec \= prevfile then do
if partialCount > 0 then
if verbose then
call display SysGetMessage(1060,,format(partialCount,9),right(pprint(partialSize),13))
else
call display SysGetMessage(1060,,format(partialCount,9),format(partialSize,10))
partialSize = 0
partialCount = 0
end
if LOCALRC \= 0 then do
if partialCount > 0 then
call display SysGetMessage(1060,,format(partialCount,9),format(partialSize,10))
partialSize = 0
partialCount = 0
call display SysGetMessage(LOCALRC)
end
prevdrive = drive
prevrep = rep
prevfile = spec
return
/*
Heap sort the "file." array in ascending order.
Algorithm from "Numerical Recipes in Fortran", Cambridge University Press
*/
sort:
if debug then Say "Entering sort for" file.0 "files"
if file.0 < 2 then
return
l = trunc(file.0/2)+1
ir = file.0
do forever
if l>1 then do
l = l-1
tempd = file.l
end
else do
tempd = file.ir
file.ir = file.1
ir = ir - 1
if ir = 1 then do
file.1 = tempd
return
end
end
i = l
j = l + l
do while j <= ir
if j < ir then do
k = j + 1
if compare(file.j, file.k) then
j = j + 1
end
if compare(tempd, file.j) then do
file.i = file.j
i = j
j = j + j
end
else
j = ir + 1
end /* do */
file.i = tempd
end /* do */
compare: /* arg(1) < arg(2) */
procedure expose sortorder
parse upper value arg(1) with date1 size1 . attr1 fullname1
parse upper value arg(2) with date2 size2 . attr2 fullname2
name1 = substr(fullname1,lastpos('\',fullname1)+1)
name2 = substr(fullname2,lastpos('\',fullname2)+1)
do i = 1 to words(sortorder)
order = word(sortorder,i)
select
when order = 'D' then do
if date1 < date2 then return 1
if date1 > date2 then return 0
end
when order = '-D' then do
if date1 > date2 then return 1
if date1 < date2 then return 0
end
when order = 'S' then do
if size1 < size2 then return 1
if size1 > size2 then return 0
end
when order = '-S' then do
if size1 > size2 then return 1
if size1 < size2 then return 0
end
when order = 'N' then do
if name1 < name2 then return 1
if name1 > name2 then return 0
end
when order = '-N' then do
if name1 > name2 then return 1
if name1 < name2 then return 0
end
when order = 'E' then do
p1 = lastpos('.',name1); if p1 = 0 then ext1 = ''; else ext1 = substr(name1,p1+1)
p2 = lastpos('.',name2); if p2 = 0 then ext2 = ''; else ext2 = substr(name2,p2+1)
if ext1 < ext2 then return 1
if ext1 > ext2 then return 0
end
when order = '-E' then do
p1 = lastpos('.',name1); if p1 = 0 then ext1 = ''; else ext1 = substr(name1,p1+1)
p2 = lastpos('.',name2); if p2 = 0 then ext2 = ''; else ext2 = substr(name2,p2+1)
if ext1 > ext2 then return 1
if ext1 < ext2 then return 0
end
when order = 'G' then do
if substr(attr1,2,1) \= substr(attr2,2,1) & substr(attr1,2,1) = 'D' then return 1
if substr(attr1,2,1) \= substr(attr2,2,1) & substr(attr2,2,1) = 'D' then return 0
end
when order = '-G' then do
if substr(attr1,2,1) \= substr(attr2,2,1) & substr(attr1,2,1) = '-' then return 1
if substr(attr1,2,1) \= substr(attr2,2,1) & substr(attr2,2,1) = '-' then return 0
end
when order = 'P' then do /* only set when sub is 1 */
if left(fullname1, length(fullname1)-length(name1)) < left(fullname2, length(fullname2)-length(name2)) then return 1
if left(fullname1, length(fullname1)-length(name1)) > left(fullname2, length(fullname2)-length(name2)) then return 0
end
otherwise do; end;
end /* select */
end /* do */
return 0
emit:
file = value('specs.'arg(1))
filename = substr(file,lastpos('\',file)+1)
if \full & \fullPath then call emitHeader1 arg(1)
maxWidth = 0
wpabstract = (pos('W', attron) > 0)
attron = strReplace(attron, 'W', '')
if Debug then say 'attron: "'attron'"'
if attron \= '' & attroff \= '' & verify(attron,attroff,'M') \= 0 then
file.0 = 0
else do
attribute = '*****'
do i = 1 to length(attron)
attribute = overlay('+',attribute,pos(substr(attron,i,1),'ADHRSW'))
end /* do */
do i = 1 to length(attroff)
attribute = overlay('-',attribute,pos(substr(attroff,i,1),'ADHRSW'))
end /* do */
if sub then
call DosFileTree file, file., 'TS', attribute
else
call DosFileTree file, file., 'T', attribute
end
if debug then say 'file.0: "'file.0'"'
if (wpabstract) then do
if RxFuncQuery("WPToolsLoadFuncs") then do
call RxFuncAdd 'WPToolsLoadFuncs', 'WPTOOLS', 'WPToolsLoadFuncs'
call WPToolsLoadFuncs
end
if debug then Say "Entering WPAbstract."
rc = WPToolsFolderContent(left(file, length(file)-2), objects.)
ofs = file.0
file.0 = file.0+objects.0
if rc then
do i = 1 to objects.0
rc2=WPToolsQueryObject(objects.i, "szclass", "sztitle", "szsetupstring", "szlocation")
i2=i+ofs
file.i2 = "0000/00/00/00/00 0 0 ----- "||left(file, length(file)-1)||sztitle||'@'
end
end
if file.0 = 0 then do
LOCALRC = 2
call emitHeader2 left(file,lastpos('\',file)-1)
end
else do
LOCALRC = 0
if (sortorder \= '') then call sort
end
/* handling relevant files */
do i = 1 to file.0
parse var file.i year '/' month '/' day '/' hour '/' min size easize attr name
if full | fullPath then do
if right(name,2) = '\.' | right(name,3) = '\..' then iterate
end
else
call emitHeader2 left(name,lastpos('\',name)-1)
partialSize = partialSize + size
partialCount = partialCount + 1
totalSize = totalSize + size
totalCount = totalCount + 1
if \ fullPath then
name = substr(name,lastpos('\',name)+1)
else
name = strip(name)
easize = easize % 2
if easize = 2 then easize = 0
if lowerc then name = lowercase(name)
if upperc then name = translate(name)
itemLength = length(name)
if itemLength > maxWidth then maxWidth = itemLength
if substr(attr,2,1) = 'D' then do
if wide | UNIX then
name = '['name']'
else
size = dirLabel
itemLength = itemLength + 2
end
/* highlighting relevent files */
dot = lastpos('.',name); oname = name
do j = 1 to 5
if symbol('dirclr._attrib_._'substr(attr,j,1)) = 'VAR' then
name = value('dirclr._attrib_._'substr(attr,j,1))name
end /* do */
if dot > 0 then
if symbol('dirclr._ext_'substr(oname,dot)) = 'VAR' then
name = value('dirclr._ext_'substr(oname,dot))name
if dot = 0 then dot = length(oname)+1
if symbol('dirclr._name_.'left(oname,dot-1)) = 'VAR' then
name = value('dirclr._name_.'left(oname,dot-1))name
if symbol('dirclr._date_.newer') = 'VAR' then
if today - (year * 372 + month * 31 + day) <= word(dirclr._date_.newer,1) then
name = subword(dirclr._date_.newer,2)||name
if length(name) \= itemLength then
name = name||normal
if (wpabstract & (pos('@', name) > 0)) then do
if symbol('dirclr._wpabstract_') = 'VAR' then do
name = dirclr._wpabstract_||name||normal
end
end
if classify then do
name_ = translate(name)
if (pos('.EXE', name_)>0) | (pos('.COM', name_)>0) | (pos('.BAT', name_)>0) | (pos('.CMD', name_)>0) then do
name = name||"*"
itemLength = itemLength+1
end
end
if (wide | UNIX) then
dir.partialCount = itemLength name
else if full | fullPath then
call display name'0d0a'x
else do
year = right(year,2)
select
when iDate = 0 then fdate = format(month)||sDate||day||sDate||year
when iDate = 1 then fdate = format(day)||sDate||month||sDate||year
when iDate = 2 then fdate = year||sDate||month||sDate||day
end /* select */
if iTime = 1 then
time = format(hour)||sTime||min' '
else
if hour < 13 then
time = format(hour)||sTime||min'a'
else
time = format(hour-12)||sTime||min'p'
if verbose then
call display right(fdate,8) right(time,6) right(pprint(size),13) right(pprint(easize),6) translate(delstr(attr,2,1), 'arsh', 'ARSH')' 'name'0d0a'x
else do
line = ""
do i_ = 1 to length(ext)
if debug then say attr
if (substr(ext, i_, 1) = "a") then line = line||lowercase(attr)||" "
if (substr(ext, i_, 1) = "d") then line = line||right(fdate, 8)||" "
if (substr(ext, i_, 1) = "t") then line = line||right(time, 7)||" "
if (substr(ext, i_, 1) = "s") then line = line||right(size, 9)||" "
if (substr(ext, i_, 1) = "e") then line = line||right(easize, 11)||" "
end
line = line name
if (pos('l', ext) > 0) then do
rc = SysGetEA(oname, ".LONGNAME", "longname_")
if (rc=0) then do
longname = substr(longname_, 5)
line = line '('||longname||')'
end
end
/* call display right(fdate,8) right(time,7) right(size,9) right(easize,11)' 'name'0d0a'x */
call display line'0d0a'x
end
end
end /* do */
/* displaying result */
if wide & partialCount > 0 then do
itemCount = width % (maxWidth+4)
line = ''
do i = 1 to partialCount
line = line || subword(dir.i,2)
if i // itemCount = 0 then do
call display line'0d0a'x
line = ''
end
else
line = line || copies(' ',maxWidth+4-word(dir.i,1))
end /* do */
if i // itemCount \= 1 then call display line'0d0a'x
end
if (UNIX) then do /* wide format, top to bottom */
spaces = 4
itemsPerLine = (width % (maxWidth+spaces))
lineCount = ((totalCount-1) % itemsPerLine)+1
do i = 1 to lineCount
line = ""
do i2 = 0 to itemsPerLine-1
i3 = i + (i2*lineCount)
if (i3 <= totalCount) then do
line = line || subword(dir.i3,2)
if (maxWidth+spaces-word(dir.i3,1) > 0) & (i2 < itemsPerLine-1) then
line = line || copies(' ',maxWidth+spaces-word(dir.i3,1))
end
end
say line
end /* do */
end /* if */
if LOCALRC = 0 & \full & \fullPath & spec = specs.0 then do
if sub then do
if verbose then
call display SysGetMessage(1060,,format(partialCount,9),right(pprint(partialSize),13))
else
call display SysGetMessage(1060,,format(partialCount,9),format(partialSize,10))
call display SysGetMessage(3155)
if verbose then
call display SysGetMessage(1060,,format(totalCount,9),right(pprint(totalSize),13))
else
call display SysGetMessage(1060,,format(totalCount,9),format(totalSize,10))
end
else do
if verbose then
call display SysGetMessage(1060,,format(partialCount,9),right(pprint(partialSize),13))
else
call display SysGetMessage(1060,,format(partialCount,9),format(partialSize,10))
end
end
return
terminate:
/* displaying standard directory footer */
if LOCALRC = 0 & specs.0 \= 0 & \full & \fullPath then
if verbose then
call display SysGetMessage(3156,,right(pprint(word(drive,2)),31))
else
call display SysGetMessage(3156,,format(word(drive,2),28))
call directory orgdir
return
pprint:
procedure expose sThousands
if \ datatype(arg(1), 'N') then
return arg(1)
value = reverse(arg(1))
newval = ''
do while value \= ''
parse var value group =4 value
newval = newval || sThousands || group
end /* do */
return strip(reverse(newval),, sThousands)
halt:
call directory orgdir
"call xhelp -f abortMsg xdir"
exit
syntax:
cond = condition('C') condition('D')
say '0a0d'x||"Internal error in xdir ("||cond||")."
call directory orgdir
exit
display:
call charout ,arg(1)
if (symbol(lineCount) = "VAR") then do
lineCount = lineCount+length(space(translate(arg(1),' !',,' '),0))
if pause & lineCount // height = 0 then do
call charout ,SysGetMessage(1032)
if pos(SysGetKey('NOECHO'), '00e0'x) > 0 then
call SysGetKey('NOECHO')
say
call charout ,SysGetMessage(3152,,rep)
lineCount = lineCount+2
end
end
return
strReplace:
/* syntax: result = strReplace(str, old, new) */
/* will replace a by b in oldstr */
parse arg str, old, new
p = pos(old, str)
if (p > 0) then
return left(str, p-1)||new||substr(str,p+length(old))
else
return str
lowercase:
return translate(arg(1), 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')