home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 18 REXX / 18-REXX.zip / rexxlb.zip / SAMPLES / FL.CMD < prev    next >
OS/2 REXX Batch file  |  1993-02-05  |  20KB  |  740 lines

  1. /*****************************************************************************/
  2. /*                                                                           */
  3. /* (c) Copyright 1988-1993, Quercus Systems                                  */
  4. /* All rights reserved                                                       */
  5. /*                                                                           */
  6. /* REXXLIB sample program: file manager/command shell                        */
  7. /*                                                                           */
  8. /* This sample is an implementation of a file manager similar to the CMS     */
  9. /* FILELIST utility. It provides extensive illustration of the use of        */
  10. /* RXWINDOW functions to build a text mode full screen interface. Many       */
  11. /* other REXXLIB functions are also used, such as:                           */
  12. /*                                                                           */
  13. /*     arraysort     dosdrive      scrput                                    */
  14. /*     cursor        dosenv        scrread                                   */
  15. /*     cursortype    lower         scrsize                                   */
  16. /*     doscd         parsefn       scrwrite                                  */
  17. /*     dosdir        pcram         sound                                     */
  18. /*     dosdisk       scrclear      upper                                     */
  19. /*                                                                           */
  20. /*****************************************************************************/
  21.  
  22. signal on novalue
  23. call load_rxwindow
  24.  
  25. level = 0
  26. parse value scrsize() with height width .
  27. height = height - 3
  28. ctype = cursortype(32,32)
  29. call main_init
  30. w1 = w_open(2, 1, height, width, attr)
  31. w2 = w_open(height+2, 1, 2, width, 79)
  32. call w_put w2, 1, 1, "=====>"
  33. do i = 1 to 10
  34.     call w_put w2, 2, (i-1)*8 + 1, i//10
  35.     call w_put w2, 2, (i-1)*8 + 2, keyname.i, , attr
  36.     end
  37. call flist arg(1)
  38. call w_close w1
  39. call w_close w2
  40. parse var ctype a b .
  41. call cursortype a, b
  42. call clrscrn
  43. exit
  44.  
  45. /* generate file list */
  46. flist: procedure expose level w1 w2 attr height width ctype dosattr
  47. level = level + 1
  48. call w_put w2, 1, 1, "["level"]"
  49. call initialize
  50. command. = ''
  51. cnum = 1
  52. w0 = w_open(1, 1, 1, width, 79)
  53. filespec = arg(1)
  54. if list_files(filespec) \= 0 then do
  55.     call w_close w0
  56.     return 3
  57.     end
  58. linesize = width
  59. top = 1
  60. current = 1
  61. title = left(left(filespec,40)||right(dosmem()%1024,4)'K memory,'||,
  62.     right(dosdisk('f',fmode)%1024,6)'K disk',69)||'   1 of'right(count,4)
  63. call w_put w0, 1, 1, title
  64. call show
  65.  
  66. /*
  67. current = line number within window
  68. item = number of item highlighted
  69. top = number of item in first line of window
  70. */
  71.  
  72. /* main loop */
  73. command_line = ''
  74. cmdpos = 0
  75. cmdnum = 0
  76. do until quit
  77.     item = top + current - 1
  78.     if item > count then do
  79.         call w_put w1, current, 1, "", 2, attr
  80.         item = count
  81.         if item < top then do
  82.             top = max(1, item - current + 1)
  83.             current = 0
  84.             call show
  85.             end
  86.         current = item - top + 1
  87.         call w_put w1, current, 1, "=>", 2, attr
  88.         end
  89.     call w_put w0, 1, 70, right(item,4)
  90.     cmdstr = command_line
  91.     command_line = w_get(w2, 1, 8, 73, cmdstr, , '00'x, 'f')
  92.     key = _activation_key
  93.     select
  94.         when key = down then do
  95.             if item = count then iterate
  96.             if current = height then do
  97.                 top = top + 1
  98.                 call show
  99.                 end
  100.             else do
  101.                 call w_put w1, current , 1, "", 2, attr
  102.                 current = current + 1
  103.                 item = top + current - 1
  104.                 call w_put w1, current , 1, "=>", 2, attr
  105.                 end
  106.             end
  107.         when key = up then do
  108.             if current = 1 then do
  109.                 if top = 1 then iterate
  110.                 else do
  111.                     top = top - 1
  112.                     call show
  113.                     end
  114.                 end
  115.             else do
  116.                 call w_put w1, current, 1, "", 2, attr
  117.                 current = current - 1
  118.                 item = top + current - 1
  119.                 call w_put w1, current, 1, "=>", 2, attr
  120.                 end
  121.             end
  122.         when key = pgdn then do
  123.             if top + height > count then iterate
  124.             else top = top + height
  125.             if top + current - 1 > count
  126.                 then current = count - top + 1
  127.             call show
  128.             end
  129.         when key = pgup then do
  130.             if item = 1 then iterate
  131.             if top <= height then top = 1
  132.             else top = top - height
  133.             call show
  134.             end
  135.         when key = ctrlpgup then do
  136.             if item = 1 then iterate
  137.             top = 1
  138.             call show
  139.             end
  140.         when key = ctrlpgdn then do
  141.             if count <= height then iterate
  142.             top = count - height + 1
  143.             call show
  144.             end
  145.         when key = esc then command_line = ''
  146.         when key = enter then do
  147.             if command_line = '' then iterate
  148.             if command_line \= cmdstr then do
  149.                 command.cmdnum = command_line
  150.                 cmdpos = cmdnum
  151.                 cmdnum = cmdnum + 1
  152.                 end
  153.             else if cmdnum > 0 then
  154.                 cmdpos = (cmdpos + 1) // cmdnum
  155.             call execute
  156.             end
  157.         when key = pf1 then call help
  158.         when key = pf2 then call shell
  159.         when key = pf3 then leave
  160.         when key = pf4 then do
  161.             command_line = 'kedit'
  162.             call execute
  163.             end
  164.         when key = pf5 then do
  165.             command_line = 'copy / a:'
  166.             call execute
  167.             end
  168.         when key = pf6 then do
  169.             command_line = 'copy / b:'
  170.             call execute
  171.             end
  172.         when key = pf7 then call mark
  173.         when key = pf8 then call refresh
  174.         when key = pf9 then do
  175.             command_line = 'fb'
  176.             call execute
  177.             end
  178.         when key = pf10 then do
  179.             command_line = command.cmdpos
  180.             if cmdpos > 0 then cmdpos = cmdpos - 1
  181.             else if cmdnum > 0 then cmdpos = cmdnum - 1
  182.             end
  183.         when key = alt_pf10 then do
  184.             if cmdnum > 0 then
  185.                 cmdpos = (cmdpos + 1) // cmdnum
  186.             command_line = command.cmdpos
  187.             end
  188.         otherwise nop
  189.         end
  190.     end
  191.  
  192. level = level - 1
  193. call w_close w0
  194. return 0
  195.  
  196. /* show help information */
  197. help: procedure expose attr height width
  198. hw = w_open(1,1,height+3,width,attr)
  199. help.1 = "Function key usage:"
  200. help.2 = ""
  201. help.3 = "   F1 - Help (this screen)"
  202. help.4 = "   F2 - OS/2 command line"
  203. help.5 = "   F3 - Exit from this level"
  204. help.6 = "   F4 - Invoke KEDIT"
  205. help.7 = "   F5 - Copy file(s) to A:"
  206. help.8 = "   F6 - Copy file(s) to B:"
  207. help.9 = "   F7 - Mark/unmark files"
  208. help.10 = "   F8 - Refresh file list"
  209. help.11 = "   F9 - File browser"
  210. help.12 = "   F10 - Recall previous commands"
  211. help.13 = ""
  212. help.14 = "/ - Previous/next file"
  213. help.15 = "PgUp/PgDn - Previous/next page"
  214. help.16 = "Ctrl-PgUp/Ctrl-PgDn - Top/bottom page"
  215. help.17 = ""
  216. help.18 = "Press any key to continue"
  217. do i = 1 to 18
  218.     call w_put hw, i, 1, help.i
  219.     end
  220. call inkey
  221. call w_close hw
  222. return
  223.  
  224. /* invoke dos shell */
  225. shell:
  226. call save_screen
  227. call clrscrn
  228. parse var ctype a b .
  229. call cursortype a, b
  230. address cmd dosenv('comspec')
  231. call restore_screen
  232. call cursortype 32, 32
  233. return
  234.  
  235. /* get a fresh list */
  236. refresh:
  237. call list_files filespec
  238. if result \= 0 then
  239.     return
  240. call show
  241. call w_put w0, 1, 77, right(count,4)
  242. call disk_size
  243. return
  244.  
  245. /* display disk space available */
  246. disk_size:
  247. call w_put w0, 1, 54, right(dosdisk('f',fmode)%1024,6)
  248. return
  249.  
  250. /* mark a file */
  251. mark:
  252. if \mark.item then do
  253.     mark.item = 1
  254.     attr.item = reverse
  255.     marked = marked + 1
  256.     call w_attr w1, current, 3, length(file.item), reverse
  257.     end
  258. else do
  259.     mark.item = 0
  260.     attr.item = attr
  261.     marked = marked - 1
  262.     call w_attr w1, current, 3, length(file.item), attr
  263.     end
  264. return
  265.  
  266. /* execute a command */
  267. execute:
  268. if command_line = '' then return
  269. parse var command_line verb rest
  270. verb = alias(verb)
  271. if verb = 'flist' then do
  272.     call flist rest
  273.     call show
  274.     command_line = ''
  275.     call w_put w2, 1, 1, "["level"]"
  276.     return
  277.     end
  278. else if verb = 'quit' then do
  279.     quit = 1
  280.     return
  281.     end
  282. else if verb = 'run' then do
  283.     command_line = rest
  284.     end
  285. call save_screen
  286. call clrscrn
  287. parse var ctype a b .
  288. call cursortype a, b
  289. prompt = prompt()
  290. signal on halt
  291. if marked = 0 then do
  292.     cmd = substitute(command_line,item)
  293.     say prompt||cmd
  294.     address cmd cmd
  295.     end
  296. else do i = 1 to count
  297.     if \mark.i then iterate
  298.     cmd = substitute(command_line,i)
  299.     say prompt||cmd
  300.     address cmd cmd
  301.     end
  302. after_halt:
  303. say ''
  304. say 'Press any key to continue.'
  305. call cursortype 32, 32
  306. call inkey
  307. call restore_screen
  308. if marked > 0 then do
  309.     marked = 0
  310.     mark. = 0
  311.     attr. = attr
  312.     call show
  313.     end
  314. command_line = ''
  315. return
  316.  
  317. /* handle control break */
  318. /* this should be activated only from the 'execute' routine */
  319. halt:
  320. signal after_halt
  321.  
  322. /* parse command line & perform substitutions */
  323. substitute: procedure expose file. fmode fpath
  324. parse arg verb rest, item
  325. if verb = '/' then do
  326.     parse arg rest, item
  327.     verb = ''
  328.     end
  329. tail = ''
  330. state = 0
  331. subst = 0
  332. parse var file.item fn ft . 13 fsize fdate ftime fp .
  333. do i = 1 to length(rest)
  334.     c = lower(substr(rest,i,1))
  335.     select
  336.         when state = 0 then do
  337.             if c = '/' then state = 1
  338.             else tail = tail||c
  339.             end
  340.         when state = 1 then do
  341.             select
  342.                 when c = 'n' then do
  343.                     tail = tail||fn
  344.                     subst = 1
  345.                     end
  346.                 when c = 't' | c = 'e' then do
  347.                     tail = tail||ft
  348.                     subst = 1
  349.                     end
  350.                 when c = 'd' | c = 'm' then do
  351.                     tail = tail||fmode':'
  352.                     subst = 1
  353.                     end
  354.                 when c = 'p' then do
  355.                     if fp \= '' then do
  356.                         if substr(fp,2,1) = ':' then
  357.                             fp = substr(fp,3)
  358.                         tail = tail||fp
  359.                         end
  360.                     else
  361.                         tail = tail||fpath
  362.                     subst = 1
  363.                     end
  364.                 when c == ' ' then do
  365.                     if \subst then do
  366.                         tail = tail||filename(item)||' '
  367.                         subst = 1
  368.                         end
  369.                     else tail = tail||' '
  370.                     state = 0
  371.                     end
  372.                 when c = 'o' then do
  373.                     subst = 1
  374.                     state = 0
  375.                     end
  376.                 otherwise do
  377.                     tail = tail||c
  378.                     state = 0
  379.                     end
  380.                 end /* inner select */
  381.             end /* do group */
  382.         end /* outer select */
  383.     end /* outer loop */
  384.  
  385. if \subst then do
  386.     fname = filename(item)
  387.     if tail \== '' then
  388.         tail = tail fname
  389.     else
  390.         tail = fname
  391.     end
  392.  
  393. verb = alias(verb)
  394. return verb tail
  395.  
  396. /* compute a file name */
  397. filename: procedure expose file. fmode fpath
  398. arg item
  399. parse var file.item fn ft . 13 fsize fdate ftime fp .
  400. fileid = fn'.'ft
  401. if fp \= '' then
  402.     fileid = fp||fileid
  403. else
  404.     fileid = fmode':'||fpath||fileid
  405. return fileid
  406.  
  407. /* expand the DOS prompt */
  408. prompt: procedure
  409. dos_prompt = dosenv('prompt')
  410. ans = ''
  411. do i = 1 to length(dos_prompt)
  412.     c = substr(dos_prompt,i,1)
  413.     if c \= '$' then do
  414.         ans = ans||c
  415.         iterate
  416.         end
  417.     if i = length(dos_prompt) then do
  418.         ans = ans'$'
  419.         leave
  420.         end
  421.     i = i + 1
  422.     x = substr(dos_prompt,i,1)
  423.     c = lower(x)
  424.     select
  425.         when c = '$' then s = '$'
  426.         when c = 't' then do
  427.             t = time()
  428.             s = substr(t,1,2)//12||substr(t,3,8)
  429.             end
  430.         when c = 'd' then do
  431.             d = date('s')
  432.             s = substr(date('w'),1,3) substr(d,5,2)'-'substr(d,7,2)||,
  433.                 '-'substr(d,1,4)
  434.             end
  435.         when c = 'p' then s = dosdrive()':'doscd()
  436.         when c = 'v' then s = dosversion()
  437.         when c = 'n' then s = dosdrive()
  438.         when c = 'g' then s = '>'
  439.         when c = 'l' then s = '<'
  440.         when c = 'b' then s = '|'
  441.         when c = 'q' then s = '='
  442.         when c = 'h' then s = '08'x
  443.         when c = 'e' then s = '1b'x
  444.         when c = '-' then s = '0d0a'x
  445.         otherwise s = x
  446.         end
  447.     ans = ans||s
  448.     end
  449. return ans
  450.  
  451. /* compute a command alias */
  452. alias:
  453. word = lower(arg(1))
  454. do i = 1 by 1 while symbol('abbr.i.name') = 'VAR'
  455.     if word == substr(abbr.i.name,1,max(length(word),abbr.i.min))
  456.         then return abbr.i.name
  457.     end
  458. return word
  459.  
  460. /* build the list of files */
  461. list_files:
  462. file. = ''
  463. marked = 0
  464. attr. = attr
  465. mark. = 0
  466. parse arg list '(' options
  467. if list = '' then
  468.     list = '*.*'
  469. parsedname = parsefn(list)
  470. if parsedname = '' then do
  471.     call errormsg "Invalid file specification:" list
  472.     return 1
  473.     end
  474. parse value lower(parsefn(list)) with fmode fpath fname ftype
  475. if fmode = '-' then fmode = lower(dosdrive())
  476. if fpath = '-' then fpath = lower(doscd(substr(fmode,1,1)))
  477. if right(fpath,1) \= '\' then
  478.     fpath = fpath||'\'
  479. if fname = '-' then do
  480.     fname = '*'
  481.     ftype = '*'
  482.     end
  483. if ftype = '-' then
  484.     ftype = '*'
  485. filespec = fmode':'fpath||fname'.'ftype
  486.  
  487. /* scan options */
  488. options = upper(options)
  489. tree_option = 0
  490. sort_option = 0
  491. do i = 1 to words(options)
  492.     opt = word(options,i)
  493.     if abbrev('TREE',opt,2) then
  494.         tree_option = 1
  495.     else if abbrev('SORTD',opt,4) | abbrev('SORTA',opt,4) then
  496.         sort_option = 1
  497.     end
  498.  
  499. if \tree_option & dosdir(filespec) = '' then do
  500.     call errormsg "Files not found:" filespec
  501.     return 2
  502.     end
  503.  
  504. if sort_option then
  505.     sort = ''
  506. else do
  507.     if tree_option then
  508.         sort = 'sort path sortd d'
  509.     else
  510.         sort = 'sortd d'
  511.     end
  512.  
  513. call listfile filespec '(' sort options
  514. count = file.0
  515. if rc \= 0 then
  516.     return 1
  517. return 0
  518.  
  519. /* show the list of lists */
  520. show:
  521. call w_clear w1
  522. do i = 1 to height
  523.     index = top + i - 1
  524.     call w_put w1, i, 3, file.index, , attr.index
  525.     if i = current then
  526.         call w_put w1, i, 1, "=>", , attr
  527.     end
  528. return
  529.  
  530. /* show error messages */
  531. errormsg:
  532. hline = height - 1
  533. ew = w_open(4,5,4,60,error_attr)
  534. if ew \= '' then do
  535.     call w_border ew
  536.     call w_put ew, 2, 3, arg(1)
  537.     call w_put ew, 3, 3, 'Press any key to continue.'
  538.     end
  539. else do
  540.     save1 = scrread(hline,1,width,'b')
  541.     save2 = scrread(hline+1,1,width,'b')
  542.     call scrwrite hline, 1, arg(1), width
  543.     call scrwrite hline+1, 1, 'Press any key to continue.'
  544.     end
  545. call sound ,.5
  546. call inkey
  547. if ew \= '' then
  548.     call w_close ew
  549. else do
  550.     call scrput hline, 1, save1, 'b'
  551.     call scrput hline+1, 1, save2, 'b'
  552.     end
  553. return
  554.  
  555. /* simulate listfile command */
  556. listfile: procedure expose file. rc
  557. parse arg names '(' options
  558. if names = '' then
  559.     names = '*.*'
  560. sorts = 0
  561. sort_types = '/name /ext /size /date'
  562. do i = 1 to words(options)
  563.     opt = lower(word(options, i))
  564.     select
  565.         when opt = 'sort' | opt = 'sorta' then do
  566.             if i = words(options) then
  567.                 break
  568.             i = i + 1
  569.             sorts = sorts + 1
  570.             x = pos('/'lower(word(options, i)), sort_types)
  571.             parse var sort_types =(x) '/' sortype .
  572.             sort.sorts = sortype 'a'
  573.             end
  574.         when opt = 'sortd' then do
  575.             if i = words(options) then
  576.                 break
  577.             i = i + 1
  578.             sorts = sorts + 1
  579.             x = pos('/'lower(word(options, i)), sort_types)
  580.             parse var sort_types =(x) '/' sortype .
  581.             sort.sorts = sortype 'd'
  582.             end
  583.         otherwise nop
  584.         end
  585.     end
  586. count = 0
  587. do i = 1 to words(names)
  588.     call filelist word(names, i), 'temp'
  589.     do j = 1 to temp.0
  590.         parse var temp.j dt tm sz at fid
  591.         count = count + 1
  592.         fspec = filespec('n', fid)
  593.         x = lastpos('.', fspec)
  594.         if x = 0 then do
  595.             fn = fspec
  596.             ft = ''
  597.             end
  598.         else do
  599.             fn = left(fspec, x-1)
  600.             ft = substr(fspec, x+1)
  601.             end
  602.         file.count = left(fn, 9) || left(ft, 4) || right(sz, 8) ||,
  603.             '  'dt || '  'tm
  604.         end
  605.     end
  606. file.0 = count
  607.  
  608. /* build an arglist for arraysort */
  609. sortspec = ''
  610. do i = 1 to sorts
  611.     parse var sort.i type direction
  612.     select
  613.         when type = 'date' then
  614.             sortspec = sortspec||'30,2,"'direction'","c",'||,
  615.                                  '24,5,"'direction'","c",'||,
  616.                                  '34,8,"'direction'","c",'
  617.         when type = 'name' then
  618.             sortspec = sortspec||'1,8,"'direction'","c",'||,
  619.                                  '10,3,"'direction'","c",'
  620.         when type = 'ext' then
  621.             sortspec = sortspec||'10,3,"'direction'","c",'||,
  622.                                  '1,8,"'direction'","c",'
  623.         when type = 'size' then
  624.             sortspec = sortspec||'14,8,"'direction'","c",'
  625.         otherwise nop
  626.         end
  627.     end
  628. interpret 'call arraysort "file",1,count,'strip(sortspec,'t',',')
  629. rc = 0
  630. return
  631.  
  632. /* make a list of files, with date, time, size, etc. */
  633. filelist:
  634. parse arg filespec, stem
  635. n = 0
  636. file = dosdir(filespec, 'dtsan', 'hs')
  637. do while file \= ''
  638.     n = n + 1
  639.     call value stem'.n', file
  640.     file = dosdir(, 'dtsan', 'hs')
  641.     end
  642. call value stem'.0', n
  643. return
  644.  
  645. /* initialize data */
  646. initialize:
  647. /* determine current screen attribute */
  648. call cursor 1, 1
  649. old_char = scrread(1,1,1,'b')
  650. call charout , ' '
  651. new_char = scrread(1,1,1,'b')
  652. call scrput 1, 1, old_char, 'b'
  653. dosattr = c2d(substr(old_char,2))
  654.  
  655. quit = 0
  656. esc = '1b'x
  657. border = 14
  658. reverse = 113
  659. error_attr = 79         /* white on red */
  660. enter = '0d'x
  661. up = '0048'x
  662. down = '0050'x
  663. left = '004b'x
  664. right = '004d'x
  665. pgup = '0049'x
  666. pgdn = '0051'x
  667. ctrlpgup = '0084'x
  668. ctrlpgdn = '0076'x
  669. pf1 = '003b'x
  670. pf2 = '003c'x
  671. pf3 = '003d'x
  672. pf4 = '003e'x
  673. pf5 = '003f'x
  674. pf6 = '0040'x
  675. pf7 = '0041'x
  676. pf8 = '0042'x
  677. pf9 = '0043'x
  678. pf10 = '0044'x
  679. alt_pf10 = '0071'x
  680. temp = dosenv('RAMDISK')||'$flist.tmp'
  681.  
  682. /* abbreviations */
  683. abbr.1.name = 'fb'
  684. abbr.1.min = 1
  685. abbr.2.name = 'browse'
  686. abbr.2.min = 1
  687. abbr.3.name = 'kedit'
  688. abbr.3.min = 1
  689. abbr.4.name = 'flist'
  690. abbr.4.min = 2
  691. abbr.5.name = 'quit'
  692. abbr.5.min = 1
  693.  
  694. return
  695.  
  696. /* initialize global variables */
  697. main_init:
  698. esc = '1b'x
  699. attr = 31
  700.  
  701. /* key names */
  702. keyname.1 = 'Help'
  703. keyname.2 = 'Shell'
  704. keyname.3 = 'Exit'
  705. keyname.4 = 'Kedit'
  706. keyname.5 = 'Copy A'
  707. keyname.6 = 'Copy B'
  708. keyname.7 = 'Mark'
  709. keyname.8 = 'Refresh'
  710. keyname.9 =  'FB'
  711. keyname.10 = 'Recall'
  712. return
  713.  
  714. /* save the current screen */
  715. save_screen:
  716. saved_screen = scrread(1,1,(height+3)*width,'b')
  717. return 0
  718.  
  719. /* restore the screen */
  720. restore_screen:
  721. call scrput 1, 1, saved_screen, 'b'
  722. return
  723.  
  724. /* clear the screen */
  725. clrscrn:
  726. call scrclear dosattr
  727. call cursor 1, 1
  728. return
  729.  
  730. /* dosmem - to support os/2 */
  731. dosmem: procedure
  732. return pcram() * 1024
  733.  
  734. /* load rxwindow package if required to */
  735. load_rxwindow: procedure
  736. call rxfuncdrop 'w_register'
  737. call rxfuncadd  'w_register', 'rxwin30', 'rxwindow'
  738. call w_register
  739. return
  740.