home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / epmmac2.zip / TREE.E < prev    next >
Text File  |  1996-01-22  |  25KB  |  637 lines

  1. compile if not defined(ERROR__MSG)
  2.    include 'english.e'
  3. const
  4.    EPM     = EVERSION >= 5
  5.    EPM32   = EVERSION >= 6
  6.  
  7. defmain
  8.    'tree' arg(1)
  9. compile endif
  10.  
  11.  
  12. compile if EPM32  -- ACTIONS file?
  13.  compile if not defined(MB_OK)
  14.    include 'stdconst.e'
  15.  compile endif
  16.  
  17. const
  18.    TREE__MSG = 'Tree'           -- Dialog title; also the name of the command
  19.    TREE_PROMPT = 'Display files in a given subdirectory or below'
  20.    TREE2_PROMPT = '.  Arguments may be given as a parameter, or will be prompted for otherwise.'
  21.    TREE_PROMPT__MSG = 'Enter arguments for Tree'
  22.    TREE_DIR__MSG = 'Tree_Dir'   -- Dialog title; also the name of the command
  23.    TREE_DIR_PROMPT = 'Like DIR, but output in TREE format'
  24.    TREE_DIR_PROMPT__MSG = 'Enter arguments for Tree_Dir'
  25. ; Note:  Translations of the following line must stay aligned with the sample
  26. ; separator line below it.  "Full name" can get as wide as necessary.  Stuff in
  27. ; parens must be unchanged, but can be shifted left or right.
  28.    TREES_HEADER = '  Date        Time     FileSize    EA-size  Attr.  Full name... (% = %d%p%f ; %f = %n.%e)'
  29. ;                 '══════════  ════════  ═════════  ═════════  ═════  ════════════'
  30.  
  31. EA_comment 'This defines the TREE and TREE_DIR commands; it can be linked, or TREE can be executed directly.  This is also a toolbar "actions" file.'
  32.  
  33. --------------------- End of text to be translated ----------------------------
  34.  
  35. ; Here is the <file_name>_ACTIONLIST command that adds the action command
  36. ; to the list.
  37.  
  38. defc TREE_actionlist
  39. universal ActionsList_FileID  -- This is the fileid that gets the line(s)
  40.  
  41. insertline '~tree_action~'TREE_PROMPT || TREE2_PROMPT'~TREE~', ActionsList_FileID.last+1, ActionsList_FileID
  42. insertline '~tree_dir_action~'TREE_DIR_PROMPT || TREE2_PROMPT'~TREE~', ActionsList_FileID.last+1, ActionsList_FileID
  43.  
  44. ; This is the command that will be called for the above action.
  45.  
  46. defc tree_action
  47.    parse arg action_letter parms
  48.    if action_letter = 'S' then       -- button Selected
  49.       sayerror 0
  50.       if parms='' then
  51.          'compiler_help_add tree.hlp'     -- Make sure the help file is loaded
  52.          parse value entrybox(TREE__MSG,'/'OK__MSG'/'Cancel__MSG'/'Help__MSG'/',checkini(0, 'TREE_ARG', ''),'',1590,
  53.                 atoi(1) || atoi(32115) || gethwndc(APP_HANDLE) ||
  54.                 TREE_PROMPT__MSG) with button 2 parms \0
  55.          if button <> \1 then
  56.             return
  57.          endif
  58.          call setini('TREE_ARG', parms)
  59.       endif
  60.       'tree' parms
  61.    elseif action_letter = 'I' then   -- button Initialized
  62.       display -8
  63.       sayerror TREE_PROMPT
  64.       display 8
  65.    elseif action_letter = 'H' then   -- button Help
  66.       'compiler_help_add tree.hlp'     -- Make sure the help file is loaded
  67.       'helpmenu 32111'                 -- & invoke it.
  68.    elseif action_letter = 'E' then   -- button End
  69. ;;    sayerror 0
  70.    endif
  71.  
  72. defc tree_dir_action
  73.    parse arg action_letter parms
  74.    if arg(1) = 'S' then       -- button Selected
  75.       sayerror 0
  76.       if parms='' then
  77.          'compiler_help_add tree.hlp'     -- Make sure the help file is loaded
  78.          parse value entrybox(TREE_DIR__MSG,'/'OK__MSG'/'Cancel__MSG'/'Help__MSG'/',checkini(0, 'TREE_DIR_ARG', ''),'',1590,
  79.                 atoi(1) || atoi(32115) || gethwndc(APP_HANDLE) ||
  80.                 TREE_DIR_PROMPT__MSG) with button 2 parms \0
  81.          if button <> \1 then
  82.             return
  83.          endif
  84.          call setini('TREE_DIR_ARG', parms)
  85.       endif
  86.       'tree_dir' parms
  87.    elseif arg(1) = 'I' then   -- button Initialized
  88.       display -8
  89.       sayerror TREE_DIR_PROMPT
  90.       display 8
  91.    elseif arg(1) = 'H' then   -- button Help
  92.       'compiler_help_add tree.hlp'     -- Make sure the help file is loaded
  93.       'helpmenu 32112'                 -- & invoke it.
  94.    elseif arg(1) = 'E' then   -- button End
  95. ;;    sayerror 0
  96.    endif
  97.  
  98. compile endif  -- ACTIONS file
  99.  
  100. const
  101.    DEBUG_TREE = 0
  102.  
  103. defc tree =
  104.    parse arg filename
  105.    call parse_filename(filename, .filename)
  106.    if substr(filename, 1, 1)='"' then
  107.       parse value filename with '"' filename '"'
  108.    endif
  109.    if filename='' then
  110.       filename = '*.*'
  111.    elseif pos(rightstr(filename,1), ':\') then
  112.       filename = filename'*.*'
  113.    endif
  114.    colon = pos(':', filename)
  115.    if not pos('\', filename) & not colon then
  116.       filename = directory()'\'filename
  117.    endif
  118. compile if EPM
  119.    if not verify(filename,'?*','M') then  -- If no wildcards
  120.       if not qfilemode(filename, attrib) then  -- File exists
  121.    compile if EVERSION >= '6.01b'
  122.          if attrib bitand 16 then  -- If x'10' is on then it's a directory
  123.    compile else
  124.          if attrib % 16 - 2 * (attrib % 32) then  -- If x'10' is on then it's a directory
  125.    compile endif
  126.             lp = lastpos('\', filename)
  127.             if not lp then lp=colon; endif
  128.             result = winmessagebox('Tree:  Directory exists:  'filename, 'Select Yes to search' filename'\*'\10'Select No to search' leftstr(filename, lp) 'for files named "'substr(filename, lp+1)'"', MB_YESNOCANCEL + MB_QUERY + MB_MOVEABLE)
  129.             if result=MBID_CANCEL then
  130.                return
  131.             endif
  132.             if result=MBID_YES then
  133.                filename = filename'\*'
  134.             endif
  135.          endif
  136.       endif
  137.    endif
  138. compile endif
  139.    getfileid startid
  140. compile if EPM
  141.    'xcom e /c .tree'
  142. compile else
  143.    'xcom e /q /n .tree'
  144. compile endif
  145.    if rc & rc<>sayerror('New file') then
  146. compile if EPM
  147.       sayerror ERROR__MSG rc BAD_TMP_FILE__MSG sayerrortext(rc)
  148. compile else
  149.       sayerror ERROR__MSG rc BAD_TMP_FILE__MSG
  150. compile endif
  151.       return rc
  152.    endif
  153.    getfileid tree_id
  154. compile if EPM
  155.    'xcom e /c .dirs'
  156. compile else
  157.    'xcom e /q /n /h .dirs'
  158. compile endif
  159.    if rc & rc<>sayerror('New file') then
  160. compile if EPM
  161.       sayerror ERROR__MSG rc BAD_TMP_FILE__MSG sayerrortext(rc)
  162. compile else
  163.       sayerror ERROR__MSG rc BAD_TMP_FILE__MSG
  164. compile endif
  165.       return rc
  166.    endif
  167.    getfileid dirs_fid
  168. compile if EPM
  169.    .visible = 0                                  -- Make hidden
  170. compile endif
  171.    file_count = 0
  172.    total_size = 0
  173.    attribute = 55        -- Want to see all files
  174.    files_truncated = 0
  175. compile if EVERSION < '5.60'
  176.    dirs_truncated = 0
  177. compile endif
  178.    if colon then
  179.       parse value filename with drives ':' filepart
  180.       filename = 'x:'filepart  -- make lp be loop invariant
  181.    else
  182.       drives = ' '         -- Want loop to be executed at least once.
  183.    endif
  184.    lp=lastpos('\', filename)
  185.    if not lp & colon then lp=2; endif
  186.    deleteline 1
  187.    do i=1 to length(drives)
  188.       if colon then
  189.          filename = substr(drives, i, 1)':'filepart
  190.       else
  191.          drives = ' '         -- Want loop to be executed at least once.
  192.       endif
  193.  
  194.       insertline leftstr(filename,lp), 1
  195.       filename = substr(filename, lp+1)
  196.       do while dirs_fid.last
  197.          getline file_path, 1, dirs_fid
  198.          if file_path<>'' & not pos(rightstr(file_path,1), ':\') then
  199.             file_path = file_path'\'
  200.          endif
  201. compile if DEBUG_TREE
  202.          debug_message( 'dirs last =' dirs_fid.last 'file_path = "'file_path'"')
  203. compile endif
  204.          deleteline 1, dirs_fid
  205. compile if EVERSION >= '5.60'
  206.          call tree_searchdir(file_path || filename, attribute, file_count, total_size, 0, tree_id)
  207.          call tree_searchdir(file_path'*.*', 4151, junk, junk, 1, dirs_fid)
  208. compile else
  209.          if -278 = tree_searchdir(file_path || filename, attribute, file_count, total_size, 0, tree_id)
  210.          then
  211.             files_truncated = -278
  212.          endif
  213.          if -278 = tree_searchdir(file_path'*.*', 4112, junk, junk, 1, dirs_fid)
  214.          then
  215.             dirs_truncated = 1
  216.          endif
  217. compile endif
  218.       enddo      -- dirs_fid.last
  219.    enddo       -- drives
  220.    activatefile dirs_fid
  221.    .modify = 0
  222.    .autosave = 0
  223.    'xcom quit'
  224.    activatefile tree_id
  225.    call tree_common_finish(tree_id, file_count, total_size, 'Tree:' arg(1), files_truncated)
  226. compile if EVERSION < '5.60'
  227.    if dirs_truncated then
  228.       refresh
  229.  compile if EPM
  230.       call winmessagebox('Tree incomplete', 'Listing not complete; some directories were truncated.', 16416) -- MB_OK + MB_WARNING + MB_MOVEABLE
  231.  compile else
  232.       messageNwait('Listing not complete; some directories were truncated.')
  233.  compile endif
  234.    endif
  235. compile endif
  236.  
  237. defc tree_dir =
  238.    parse arg filename
  239.    call parse_filename(filename, .filename)
  240.    if substr(filename, 1, 1)='"' then
  241.       parse value filename with '"' filename '"'
  242.    endif
  243.    if filename='' then
  244.       filename = '*.*'
  245.    elseif pos(rightstr(filename,1), ':\') then
  246.       filename = filename'*.*'
  247.    endif
  248.    if not pos('\', filename) & substr(filename,2,1)<>':' then
  249.       filename = directory()'\'filename
  250.    endif
  251.    if not verify(filename,'?*','M') then  -- If no wildcards
  252.       if not qfilemode(filename, attrib) then  -- File exists
  253.    compile if EVERSION >= '6.01b'
  254.          if attrib bitand 16 then  -- If x'10' is on then it's a directory
  255.    compile else
  256.          if attrib % 16 - 2 * (attrib % 32) then  -- If x'10' is on then it's a directory
  257.    compile endif
  258.             filename = filename'\*.*'
  259.          endif
  260.       endif
  261.    endif
  262. compile if EPM
  263.    'xcom e /c .tree'
  264. compile else
  265.    'xcom e /q /n .tree'
  266. compile endif
  267.    if rc & rc<>sayerror('New file') then
  268. compile if EPM
  269.       sayerror ERROR__MSG rc BAD_TMP_FILE__MSG sayerrortext(rc)
  270. compile else
  271.       sayerror ERROR__MSG rc BAD_TMP_FILE__MSG
  272. compile endif
  273.       return rc
  274.    endif
  275.    getfileid tree_id
  276.    file_count = 0
  277.    total_size = 0
  278.    attribute = 55        -- Want to see all files
  279.    res= tree_searchdir(filename, attribute, file_count, total_size, 0, tree_id)
  280.    call tree_common_finish(tree_id, file_count, total_size, 'Tree_Dir:' arg(1), res)
  281.  
  282.  
  283. defproc tree_common_finish(tree_id, file_count, total_size, title)
  284.    if tree_id.modify then
  285. compile if EVERSION < '5.60'
  286.       if arg(5) = -278 then  -- sayerror("Lines truncated")
  287.          replaceline TREES_HEADER'   ('LINES_TRUNCATED__MSG')', 1
  288.       else
  289.          replaceline TREES_HEADER, 1
  290.       endif
  291. compile else
  292.       replaceline TREES_HEADER, 1
  293. compile endif
  294.       insertline '══════════  ════════  ═════════  ═════════  ═════  ════════════', 2
  295.       insertline '          'file_count 'file(s)   'total_size 'bytes used', .last+1
  296. compile if EVERSION >= '5.50'
  297.       .lineg = 3
  298. compile else
  299.       3
  300. compile endif
  301.       .col = 52
  302. compile if EPM
  303.       .titletext = title
  304.       'postme monofont'
  305.       'postme tabs 1 13 23 34 45 52'
  306. compile else
  307.       .filename = '.'title
  308.       .tabs = 1 13 23 34 45 52
  309. compile endif
  310.       sayerror ALT_1_LOAD__MSG
  311.       .modify = 0
  312. compile if EVERSION < '5.60'
  313.       if arg(5) = -278 then  -- sayerror("Lines truncated")
  314.          refresh
  315.  compile if EPM  -- Do a sayerror; it will stay on messageline
  316.          sayerror 'Warning:  Some lines truncated at column 255.'
  317.  compile else  -- must do a messageNwait to be sure it's not erased by a "Tree incomplete" message.
  318.          messageNwait('Warning:  Some lines truncated at column 255.')
  319.  compile endif
  320.       endif
  321. compile endif
  322.    else
  323.       'xcom q'
  324.       sayerror 'No hits.'
  325.    endif
  326.  
  327.  
  328. ; The arguments to Tree_SearchDir are as follows:
  329. ;
  330. ; filename:  The fully-qualified name we're searching for.
  331. ; attribute:  The file attributes we pass to DosFindFirst
  332. ; file_count:  Incremented for each "hit".
  333. ; total_size:  Incremented by the filesize for each "hit".
  334. ; dir_only:  A flag to say if we're looking for directories only (for sweeping the tree).
  335. ; out_fid:  The fileid where the output is to be appended.
  336. ;
  337. defproc tree_searchdir(filename, attribute, var file_count, var total_size, dir_only, out_fid)
  338. compile if DEBUG_TREE
  339.    debug_message( 'tree_searchdir('filename', 'attribute', ..., 'dir_only', 'out_fid '=' out_fid.filename)
  340. compile endif
  341.    wild_prefix=substr(filename,1,lastpos('\', filename))
  342.    if wild_prefix='' & substr(filename, 2, 1)=':' then wild_prefix = leftstr(filename, 2); endif
  343.    parse value filename with filename ',' masks
  344.    truncated = 0  -- Initialize
  345.    do forever  -- Until masks run out
  346.       namez    = filename\0    -- ASCIIZ
  347. compile if EPM
  348.       resultbuf = copies(\0, 300)  -- Might need to allocate a buffer if < EPM 5.60
  349. compile else
  350.       resultbuf = substr('', 1, 300, \0)
  351. compile endif
  352. compile if EVERSION >= 6  -- EPM32:  32-bit version
  353.       dirhandle = \xff\xff\xff\xff  -- Ask system to assign us a handle
  354.       searchcnt = atol(1)   -- Search count; we're only asking for 1 file at a time here.
  355.       result=dynalink32('DOSCALLS',             -- dynamic link library name
  356.                         '#264',                 -- ordinal value for DOS32FINDFIRST
  357.                         address(namez)      ||  -- Filename we're looking for
  358.                         address(dirhandle)  ||  -- Pointer to the handle
  359.                         atol(attribute)     ||  -- Attribute value describing desired files
  360.                         address(resultbuf)  ||  -- string address
  361.                         atol(length(resultbuf)) ||
  362.                         address(searchcnt)  ||  -- Pointer to the count; system updates
  363.                         atol(2), 2)             -- File info level 2 requested
  364. compile else
  365.       dirhandle = \255\255  -- Ask system to assign us a handle
  366.       searchcnt = atoi(1)   -- Search count; we're only asking for 1 file at a time here.
  367.       result=dynalink('DOSCALLS',             -- dynamic link library name
  368.                       '#184',                 -- ordinal value for DOSFINDFIRST2
  369.                       address(namez)      ||  -- Filename we're looking for
  370.                       address(dirhandle)  ||  -- Pointer to the handle
  371.                       atoi(attribute)     ||  -- Attribute value describing desired files
  372.                       address(resultbuf)  ||  -- string address
  373.                       atoi(length(resultbuf)) ||
  374.                       address(searchcnt)  ||  -- Pointer to the count; system updates
  375.                       atoi(2)             ||  -- FileInfoLevel
  376.                       atol(0))                -- reserved
  377. compile endif -- EVERSION >= 6
  378.  
  379. compile if not DEBUG_TREE
  380.       if result & result<>18 then  -- unexpected error, skip remaining masks.
  381. sayerror 'result' result 'from DosFindFirst' filename
  382.          return result
  383.       endif
  384. compile else  -- debug
  385.       if result then
  386.              if result = 2   then msg = 'FILE NOT FOUND'
  387.          elseif result = 3   then msg = 'PATH NOT FOUND'
  388.          elseif result = 6   then msg = 'INVALID HANDLE'
  389.          elseif result = 18  then msg = 'NO MORE FILES'
  390.          elseif result = 26  then msg = 'NOT DOS DISK'
  391.          elseif result = 87  then msg = 'INVALID PARAMETER'
  392.          elseif result = 108 then msg = 'DRIVE LOCKED'
  393.          elseif result = 111 then msg = 'BUFFER OVERFLOW'
  394.          elseif result = 113 then msg = 'NO MORE SEARCH HANDLES'
  395.          elseif result = 206 then msg = 'FILENAME EXCED RANGE'
  396.          endif
  397.          debug_message( 'Error' result '('msg') for "'filename'"')
  398.          if result<>2 & result<>18 then return result; endif
  399.       endif
  400. compile endif
  401.       if not result then
  402.          loop
  403. compile if EVERSION >= 6  -- EPM32:  32-bit version
  404.             filename = substr(resultbuf, 34, asc(substr(resultbuf, 33, 1)))
  405.             fileattrib = ltoa(substr(resultbuf,25,4),10)
  406.             skip = filename='.' | filename='..' -- Not a directory we want!
  407.             filename = wild_prefix || filename
  408.             if dir_only then
  409.                if not (fileattrib//32%16) then  -- Not a directory?
  410.                   skip = 1  -- Check, because apparently LAN drives don't respect "Must have" attributes...
  411.                endif
  412.                if not skip then
  413.                   insertline filename, out_fid.last + 1, out_fid
  414.                endif
  415.             else
  416. compile if DEBUG_TREE
  417.                debug_message('Hit on "'filename'" - out_fid.last =' out_fid.last)
  418. compile endif
  419.                filedate = substr(resultbuf, 13, 4)
  420.                file_size = ltoa(substr(resultbuf,17,4),10)
  421. ;        filealloc = ltoa(substr(resultbuf,21,4),10)
  422.                ea_size = ltoa(substr(resultbuf,29,4),10)
  423. compile else
  424.             filename = substr(resultbuf, 28, asc(substr(resultbuf, 27, 1)))
  425.             skip = filename='.' | filename='..' -- Not a directory we want!
  426.             fileattrib = itoa(substr(resultbuf,21,2),10)
  427.             filename = wild_prefix || filename
  428.             if dir_only then
  429.                if not (fileattrib//32%16) then  -- Not a directory?
  430.                   skip = 1  -- 1.3's DosFindFirst doesn't have "Must have" attributes...
  431.                endif
  432.                if not skip then
  433.        compile if EVERSION < '5.60'
  434.                   if length(wild_prefix) + asc(substr(resultbuf, 27, 1)) > 255 then
  435.                      truncated = 1      -- Don't insert a partial directory
  436.                   else
  437.        compile endif
  438.                      insertline filename, out_fid.last + 1, out_fid
  439.        compile if EVERSION < '5.60'
  440.                   endif
  441.        compile endif
  442.                endif
  443.             else
  444.                filedate = substr(resultbuf, 9, 4)
  445.                file_size = ltoa(substr(resultbuf,13,4),10)
  446. ;        filealloc = ltoa(substr(resultbuf,17,4),10)
  447.                ea_size = ltoa(substr(resultbuf,23,4),10)
  448. compile endif -- EVERSION >= 6
  449.                file_count = file_count + 1
  450.                total_size = total_size + file_size
  451.                date = ltoa(substr(filedate,1,2)\0\0,10); time = ltoa(substr(filedate,3,2)\0\0,10)
  452.                year = date % 512; date = date // 512
  453.                month = date % 32; day = date // 32 % 1     -- %1 to drop fraction.
  454.                date = year+1980'-'rightstr(month,2,0)'-'rightstr(day,2,0)
  455.                hour = time % 2048; time = time // 2048
  456.                min = time % 32; sec = time // 32 * 2 % 1
  457.                time = rightstr(hour,2)':'rightstr(min,2,0)':'rightstr(sec,2,0)
  458.                if ea_size=4 then
  459.                   ea_size=0
  460. compile if EVERSION >= 6
  461.                else
  462.                   ea_size=ea_size%2
  463. compile endif
  464.                endif
  465. compile if EVERSION < '6.01b'
  466.                fileattrib = fileattrib // 64
  467. compile endif
  468.                attr_string = '     '
  469. compile if EVERSION < '6.01b'
  470.                if fileattrib % 32 then
  471. compile else
  472.                if fileattrib bitand 32 then
  473. compile endif
  474.                   attr_string = overlay('A', attr_string, 1)
  475. compile if EVERSION < '6.01b'
  476.                   fileattrib = fileattrib // 32
  477. compile endif
  478.                endif
  479. compile if EVERSION < '6.01b'
  480.                if fileattrib % 16 then
  481. compile else
  482.                if fileattrib bitand 16 then
  483. compile endif
  484.                   attr_string = overlay('D', attr_string, 2)
  485.                   file_size = '<dir>'
  486. compile if EVERSION < '6.01b'
  487.                   fileattrib = fileattrib // 16
  488. compile endif
  489.                endif
  490. compile if EVERSION < '6.01b'
  491.                if fileattrib % 4 then
  492. compile else
  493.                if fileattrib bitand 4 then
  494. compile endif
  495.                   attr_string = overlay('S', attr_string, 3)
  496. compile if EVERSION < '6.01b'
  497.                   fileattrib = fileattrib // 4
  498. compile endif
  499.                endif
  500. compile if EVERSION < '6.01b'
  501.                if fileattrib % 2 then
  502. compile else
  503.                if fileattrib bitand 2 then
  504. compile endif
  505.                   attr_string = overlay('H', attr_string, 4)
  506. compile if EVERSION < '6.01b'
  507.                   fileattrib = fileattrib // 2
  508. compile endif
  509.                endif
  510. compile if EVERSION < '6.01b'
  511.                if fileattrib then
  512. compile else
  513.                if fileattrib bitand 1 then
  514. compile endif
  515.                   attr_string = overlay('R', attr_string, 5)
  516.                endif
  517.                file_size = rightstr(file_size, 10)
  518.                out_line = date'  'time file_size rightstr(ea_size,10)'  'attr_string'  'filename
  519.                insertline out_line, out_fid.last + 1, out_fid
  520. compile if EVERSION < '5.60'
  521.                if length(filename) > 203 then  -- Full filename starts in col 52
  522.                   truncated = 1
  523.                endif
  524. compile endif
  525.             endif  -- dir_only
  526. compile if EVERSION >= 6  -- EPM32:  32-bit version
  527.             result=dynalink32('DOSCALLS',             -- dynamic link library name
  528.                              '#265',                 -- ordinal value for DOS32FINDNEXT
  529.                              dirhandle           ||  -- Directory handle, returned by DosFindFirst(2)
  530.                              address(resultbuf)  ||  -- address of result buffer
  531.                              atol(length(resultbuf)) ||
  532.                              address(searchcnt), 2)  -- Pointer to the count; system updates
  533. compile else
  534.             result=dynalink('DOSCALLS',             -- dynamic link library name
  535.                             '#65',                  -- ordinal value for DOSFINDNEXT
  536.                             dirhandle           ||  -- Directory handle, returned by DosFindFirst(2)
  537.                             address(resultbuf)  ||  -- address of result buffer
  538.                             atoi(length(resultbuf)) ||
  539.                             address(searchcnt) )    -- Pointer to the count; system updates
  540. compile endif -- EVERSION >= 6
  541.             if result then
  542. compile if EVERSION >= 6  -- EPM32:  32-bit version
  543.                call dynalink32('DOSCALLS',             -- dynamic link library name
  544.                                '#263',                 -- ordinal value for DOS32FINDCLOSE
  545.                                dirhandle)              -- Directory handle, returned by DosFindFirst(2)
  546. compile else
  547.                call dynalink('DOSCALLS',             -- dynamic link library name
  548.                              '#63',                  -- ordinal value for DOSFINDCLOSE
  549.                              dirhandle)              -- Directory handle, returned by DosFindFirst(2)
  550. compile endif -- EVERSION >= 6
  551.                if result<>18 then
  552.                   sayerror UNEXPECTED__MSG 'DosFindNext' result
  553.                endif
  554.                leave
  555.             endif
  556.          endloop
  557.       endif  -- result from DosFindFirst
  558.       if masks='' then
  559.          leave
  560.       endif
  561.       parse value masks with mask ',' masks
  562.       filename = wild_prefix || strip(mask)
  563.    enddo
  564. compile if EVERSION < '5.60'
  565.    if truncated then
  566.       return -278  -- sayerror("Lines truncated")
  567.    endif
  568. compile endif
  569.  
  570. compile if DEBUG_TREE
  571. defproc debug_message(msgstring) =
  572.  compile if EPM
  573.    sayerror msgstring
  574.  compile else
  575.    messageNwait(msgstring)
  576.  compile endif
  577. compile endif
  578.  
  579. defc treesort =
  580.    revrse = ''
  581.    startmod = .modify
  582.    arglist = upcase(arg(1))
  583.    getfileid thisfid
  584.    call psave_mark(savemark)
  585.    mt = marktype()
  586.    firstline = 3; lastline = .last-1
  587.    if mt then
  588.       getmark firstl, lastl, firstcol, lastcol, markfileid
  589.       if markfileid=thisfid & firstline<>lastline then
  590.          firstline = firstl; lastline = lastl
  591.       endif
  592.    endif
  593.    do while arglist<>''
  594.       result = 0
  595.       parse value arglist with thisarg arglist
  596.       if     abbrev('/REVERSE', thisarg, 2) then
  597.          revrse = 'R'
  598.       elseif abbrev('/FORWARD', thisarg, 2) then
  599.          revrse = ''
  600.       elseif abbrev('DATE', thisarg, 1) then
  601.          result = sort(firstline, lastline, 1, 20, thisfid, revrse)
  602.       elseif abbrev('TIME', thisarg, 1) then
  603.          result = sort(firstline, lastline, 13, 20, thisfid, revrse)
  604.       elseif abbrev('SIZE', thisarg, 1) then
  605.          result = sort(firstline, lastline, 21, 31, thisfid, revrse)
  606.       elseif abbrev('EASIZE', thisarg, 2) then
  607.          result = sort(firstline, lastline, 32, 42, thisfid, revrse)
  608.       elseif abbrev('FILENAME', thisarg, 1) |
  609.              abbrev('FULLNAME', thisarg, 2) then
  610.          result = sort(firstline, lastline, 52, 260, thisfid, 'CI'revrse)
  611.       elseif abbrev('NAME', thisarg, 1) |
  612.              abbrev('EXTENSION', thisarg, 2) then
  613.          ext = leftstr(thisarg, 1) = 'E'
  614.          do l = firstline to lastline
  615.             line = textline(l)
  616.             p = lastpos('\', line)
  617.             if ext then
  618.                p1 = lastpos('.', line)
  619.                if p1>p then p = p1; endif
  620.             endif
  621.             replaceline substr(line, p+1) || \0 || leftstr(line, p), l
  622.          enddo
  623.          result = sort(firstline, lastline, 1, 260, thisfid, 'CI'revrse)
  624.          do l = firstline to lastline
  625.             parse value textline(l) with p2 \0 p1
  626.             replaceline p1 || p2, l
  627.          enddo
  628.       else
  629.          sayerror sayerrortext(-263) '-' thisarg
  630.       endif
  631.       if result then
  632.          sayerror 'SORT' ERROR_NUMBER__MSG result
  633.       endif
  634.    enddo
  635.    .modify = startmod
  636.    call prestore_mark(savemark)
  637.