home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 5 Edit
/
05-Edit.zip
/
epm603b.zip
/
EPMSMP.ZIP
/
CMPTREE.E
< prev
next >
Wrap
Text File
|
1995-01-09
|
15KB
|
323 lines
/* This compares 2 directories and presents a list of all
files in the first which are different or missing in the second. I use
it to keep stuff in synch. E.g., if I bring home a new set of macros,
I do a 'cmptree a:\e_macros f:\e_macros' to see which files have
changed, then do an 'epairs' (see next append) to edit the pairs of
differing files. Finally, EPM 6.01's EPMCOMP lets me do a fast
comparison of the files to see what's been changed (and to ensure I
don't overwrite modifications I made at home with others I made at
work). Note: this only compares directories, not trees. The name is
because it presents the result in the same format as EPM's TREE command. */
-- CMPTREE.E, by Larry Margolis - MARGOLI at YKTVMV
compile if not defined(ERROR__MSG)
include 'english.e'
compile endif
compile if not defined(MB_OK)
include 'stdconst.e'
compile endif
const
TREES_HEADER = ' Date Time FileSize EA-size Attr. Full name...'
defmain
'cmptree' arg(1)
defc cmptree =
parse arg filespec1 filespec2 junk
if filespec1='' | junk<>'' then
sayerror 'Invalid parameters - takes 2 directory specs.'
return
endif
if filespec2='' then
filespec2=filespec1
filespec1='a:'
endif
if substr(filespec1,2)=':\' then filespec1=leftstr(filespec1,2); endif
if rightstr(filespec1,1)<>'\' & not verify(filespec1,'*?','M') then
filespec1=filespec1'\*.*'
endif
l1prefix=leftstr(filespec1, lastpos('\',filespec1))
if rightstr(filespec2,1)<>'\' then filespec2=filespec2'\'; endif
getfileid startid
compile if EPM
'xcom e /c .tree'
compile else
'xcom e /q /n .tree'
compile endif
if rc & rc<>sayerror('New file') then
compile if EPM
sayerror ERROR__MSG rc BAD_TMP_FILE__MSG sayerrortext(rc)
compile else
sayerror ERROR__MSG rc BAD_TMP_FILE__MSG
compile endif
return rc
endif
getfileid tree_id
file_count = 0
pair_count = 0
attribute = 55 -- Want to see all files
files_truncated = 0
res = tree_searchdir(filespec1, attribute, file_count, pair_count, tree_id, filespec2)
if tree_id.modify then
compile if EVERSION < '5.60'
if res = -278 then -- sayerror("Lines truncated")
replaceline TREES_HEADER' ('LINES_TRUNCATED__MSG')', 1
else
replaceline TREES_HEADER, 1
endif
compile else
replaceline TREES_HEADER, 1
compile endif
insertline '══════════ ════════ ═════════ ═════════ ═════ ════════════', 2
insertline ' 'file_count 'file(s), 'pair_count 'pairs', .last+1
compile if EVERSION >= '5.50'
.lineg = 3
compile else
3
compile endif
.col = 52
compile if EPM
.titletext = 'CmpTree:' arg(1)
'postme monofont'
'postme tabs 1 13 23 34 45 52'
compile else
.filename = '.CmpTree:' arg(1)
.tabs = 1 13 23 34 45 52
compile endif
sayerror ALT_1_LOAD__MSG
.modify = 0
compile if EVERSION < '5.60'
if res = -278 then -- sayerror("Lines truncated")
refresh
compile if EPM -- Do a sayerror; it will stay on messageline
sayerror 'Warning: Some lines truncated at column 255.'
compile else -- must do a messageNwait to be sure it's not erased by a "Tree incomplete" message.
messageNwait('Warning: Some lines truncated at column 255.')
compile endif
endif
compile endif
else
'xcom q'
sayerror 'No new files.'
endif
; The arguments to Tree_SearchDir are as follows:
;
; filename: The fully-qualified name we're searching for.
; attribute: The file attributes we pass to DosFindFirst
; file_count: Incremented for each "hit".
; pair_count: Incremented for each "hit" on *both* directories.
; out_fid: The fileid where the output is to be appended.
; filespec2: The path prefix of the directory we're comparing with.
;
defproc tree_searchdir(filename, attribute, var file_count, var pair_count, out_fid, filespec2)
wild_prefix=substr(filename,1,lastpos('\', filename))
if wild_prefix='' & substr(filename, 2, 1)=':' then wild_prefix = leftstr(filename, 2); endif
truncated = 0 -- Initialize
namez = filename\0 -- ASCIIZ
compile if EPM
resultbuf = copies(\0, 300) -- Might need to allocate a buffer if < EPM 5.60
compile else
resultbuf = substr('', 1, 300, \0)
compile endif
resultbuf2 = resultbuf
compile if EVERSION >= 6 -- EPM32: 32-bit version
dirhandle = \xff\xff\xff\xff -- Ask system to assign us a handle
searchcnt = atol(1) -- Search count; we're only asking for 1 file at a time here.
result=dynalink32('DOSCALLS', -- dynamic link library name
'#264', -- ordinal value for DOS32FINDFIRST
address(namez) || -- Filename we're looking for
address(dirhandle) || -- Pointer to the handle
atol(attribute) || -- Attribute value describing desired files
address(resultbuf) || -- string address
atol(length(resultbuf)) ||
address(searchcnt) || -- Pointer to the count; system updates
atol(2), 2) -- File info level 2 requested
compile else
dirhandle = \255\255 -- Ask system to assign us a handle
searchcnt = atoi(1) -- Search count; we're only asking for 1 file at a time here.
result=dynalink('DOSCALLS', -- dynamic link library name
'#184', -- ordinal value for DOSFINDFIRST2
address(namez) || -- Filename we're looking for
address(dirhandle) || -- Pointer to the handle
atoi(attribute) || -- Attribute value describing desired files
address(resultbuf) || -- string address
atoi(length(resultbuf)) ||
address(searchcnt) || -- Pointer to the count; system updates
atoi(2) || -- FileInfoLevel
atol(0)) -- reserved
compile endif -- EVERSION >= 6
if result & result<>18 then -- unexpected error
sayerror 'result' result 'from DosFindFirst' filename
return result
endif
if not result then
loop
compile if EVERSION >= 6 -- EPM32: 32-bit version
filename = substr(resultbuf, 34, asc(substr(resultbuf, 33, 1)))
skip = filename='.' | filename='..'
if not skip then
tmphandle = atol(1)
searchcnt = atol(1) -- Search count; we're only asking for 1 file at a time here.
filename2=filespec2 || filename
namez=filename2 || \0
result2=dynalink32('DOSCALLS', -- dynamic link library name
'#264', -- ordinal value for DOS32FINDFIRST
address(namez) || -- Filename we're looking for
address(tmphandle) || -- Pointer to the handle
atol(55) || -- Attribute value describing desired files
address(resultbuf2) || -- string address
atol(length(resultbuf2)) ||
address(searchcnt) || -- Pointer to the count; system updates
atol(2), 2) -- File info level 2 requested
if not result2 & -- Good return code
substr(resultbuf, 13,4) = substr(resultbuf2, 13,4) & -- Dates the same
substr(resultbuf, 17,4) = substr(resultbuf2, 17,4) -- Sizes the same
then
skip = 1
endif
endif
compile else
filename = substr(resultbuf, 28, asc(substr(resultbuf, 27, 1)))
skip = filename='.' | filename='..'
if not skip then
tmphandle = atoi(1)
searchcnt = atoi(1) -- Search count; we're only asking for 1 file at a time here.
filename2=filespec2 || filename
namez=filename2 || \0
result2=dynalink('DOSCALLS', -- dynamic link library name
'#184', -- ordinal value for DOSFINDFIRST2
address(namez) || -- Filename we're looking for
address(tmphandle) || -- Pointer to the handle
atoi(55) || -- Attribute value describing desired files
address(resultbuf2) || -- string address
atoi(length(resultbuf2)) ||
address(searchcnt) || -- Pointer to the count; system updates
atoi(2) || -- FileInfoLevel
atol(0)) -- reserved
if not result2 & -- Good return code
substr(resultbuf, 9,4) = substr(resultbuf2, 9,4) & -- Dates the same
substr(resultbuf, 13,4) = substr(resultbuf2, 13,4) -- Sizes the same
then
skip = 1
endif
endif
compile endif -- EVERSION >= 6
if not skip then
filename = wild_prefix || filename
file_count = file_count + 1 + (result2=0)
call format_record(resultbuf, filename, out_fid)
if not result2 then
pair_count = pair_count + 1
call format_record(resultbuf2, filename2, out_fid)
compile if EVERSION < '5.60'
if length(filename2) > 203 then -- Full filename starts in col 52
truncated = 1
endif
compile endif
endif
compile if EVERSION < '5.60'
if length(filename) > 203 then -- Full filename starts in col 52
truncated = 1
endif
compile endif
endif
compile if EVERSION >= 6 -- EPM32: 32-bit version
result=dynalink32('DOSCALLS', -- dynamic link library name
'#265', -- ordinal value for DOS32FINDNEXT
dirhandle || -- Directory handle, returned by DosFindFirst(2)
address(resultbuf) || -- address of result buffer
atol(length(resultbuf)) ||
address(searchcnt), 2) -- Pointer to the count; system updates
compile else
result=dynalink('DOSCALLS', -- dynamic link library name
'#65', -- ordinal value for DOSFINDNEXT
dirhandle || -- Directory handle, returned by DosFindFirst(2)
address(resultbuf) || -- address of result buffer
atoi(length(resultbuf)) ||
address(searchcnt) ) -- Pointer to the count; system updates
compile endif -- EVERSION >= 6
if result then
compile if EVERSION >= 6 -- EPM32: 32-bit version
call dynalink32('DOSCALLS', -- dynamic link library name
'#263', -- ordinal value for DOS32FINDCLOSE
dirhandle) -- Directory handle, returned by DosFindFirst(2)
compile else
call dynalink('DOSCALLS', -- dynamic link library name
'#63', -- ordinal value for DOSFINDCLOSE
dirhandle) -- Directory handle, returned by DosFindFirst(2)
compile endif -- EVERSION >= 6
if result<>18 then
sayerror 'Unexpected error' result 'from DosFindNext'
endif
leave
endif
endloop
endif -- result from DosFindFirst
compile if EVERSION < '5.60'
if truncated then
return -278 -- sayerror("Lines truncated")
endif
compile endif
defproc format_record(resultbuf, filename, out_fid)
compile if EVERSION >= 6 -- EPM32: 32-bit version
fileattrib = ltoa(substr(resultbuf,25,4),10)
filedate = substr(resultbuf, 13, 4)
file_size = ltoa(substr(resultbuf,17,4),10)
; filealloc = ltoa(substr(resultbuf,21,4),10)
ea_size = ltoa(substr(resultbuf,29,4),10)
compile else
fileattrib = itoa(substr(resultbuf,21,2),10)
filedate = substr(resultbuf, 9, 4)
file_size = ltoa(substr(resultbuf,13,4),10)
; filealloc = ltoa(substr(resultbuf,17,4),10)
ea_size = ltoa(substr(resultbuf,23,4),10)
compile endif -- EVERSION >= 6
date = ltoa(substr(filedate,1,2)\0\0,10); time = ltoa(substr(filedate,3,2)\0\0,10)
year = date % 512; date = date // 512
month = date % 32; day = date // 32 % 1 -- %1 to drop fraction.
date = year+1980'-'rightstr(month,2,0)'-'rightstr(day,2,0)
hour = time % 2048; time = time // 2048
min = time % 32; sec = time // 32 * 2 % 1
time = rightstr(hour,2)':'rightstr(min,2,0)':'rightstr(sec,2,0)
if ea_size=4 then
ea_size=0
compile if EVERSION >= 6
else
ea_size=ea_size%2
compile endif
endif
fileattrib = fileattrib // 64
attr_string = ' '
if fileattrib % 32 then
attr_string = overlay('A', attr_string, 1)
fileattrib = fileattrib // 32
endif
if fileattrib % 16 then
attr_string = overlay('D', attr_string, 2)
file_size = '<dir>'
fileattrib = fileattrib // 16
endif
if fileattrib % 4 then
attr_string = overlay('S', attr_string, 3)
fileattrib = fileattrib // 4
endif
if fileattrib % 2 then
attr_string = overlay('H', attr_string, 4)
fileattrib = fileattrib // 2
endif
if fileattrib then
attr_string = overlay('R', attr_string, 5)
endif
file_size = rightstr(file_size, 10)
out_line = date' 'time file_size rightstr(ea_size,10)' 'attr_string' 'filename
insertline out_line, out_fid.last + 1, out_fid