home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 18 REXX / 18-REXX.zip / cmdpk164.zip / sdir.cmd < prev    next >
OS/2 REXX Batch file  |  1997-12-10  |  27KB  |  650 lines

  1. /* sdir.cmd - an improved dir command                          971209 */
  2. /* (c) martin lafaix 1996, 1997                                       */
  3.  
  4. /* 
  5.  * Options
  6.  *
  7.  * /B                         -- full
  8.  * /F                         -- fullPath
  9.  * /W                         -- wide
  10.  *
  11.  * /S                         -- use subdirs too
  12.  *
  13.  * /A[:][-]d[-]h[-]r[-]s[-]a  -- show or hide specified attributes
  14.  *
  15.  * /O[:][-]n[-]e[-]d[-]s[-]g  -- specify sort order
  16.  *
  17.  * /L                         -- lower
  18.  * /V                         -- verbose (new Warp4 feature)
  19.  * /P                         -- pause every screen
  20.  *
  21.  * Environment variables
  22.  *
  23.  * DIRCMD                     -- options list
  24.  *
  25.  * DIRCLR.ATTRIB              -- attrib[,...]:color[;...][;]
  26.  * DIRCLR.DATE                -- [+-=]date[,...]:color[;...][;]
  27.  * DIRCLR.EASIZE              -- [+-=]size[,...]:color[;...][;]
  28.  * DIRCLR.EXT                 -- ext[,...]:color[;...][;]
  29.  * DIRCLR.NAME                -- name[,...]:color[;...][;]
  30.  * DIRCLR.SIZE                -- [+-=]size[,...]:color[;...][;]
  31.  */
  32.  
  33. signal on halt
  34.  
  35. call init
  36.  
  37. parse arg commandLine
  38.  
  39. do while commandLine \= ''
  40.    parse var commandLine left '"' file '"' commandLine
  41.    if left \= '' then call getOptions left
  42.    if file \=='' then call add file
  43. end /* do */
  44.  
  45. if specs.0 = 0 & filespec = 0 then call add '*'
  46. if sub & sortorder \= '' then sortorder = 'P' sortorder
  47.  
  48. do spec = 1 to specs.0
  49.    call emit spec
  50. end /* do */  
  51.  
  52. call terminate
  53.  
  54. exit
  55.  
  56.            
  57. getOptions:
  58.   procedure expose wide full fullPath lower verbose pause specs. attron attroff filespec sortorder sub processingInit invalidOpt lineCount
  59.   do i = 1 to words(arg(1))
  60.      opt = word(arg(1),i)
  61.      if left(opt,1) = '/' then 
  62.         do while opt \= ''                        
  63.            parse var opt '/' xswitch '/' -0 opt
  64.            switch = translate(xswitch)
  65.            select                                         
  66.               when switch = 'W' & \ full & \ fullPath then wide = 1
  67.               when switch = '-W' then wide = 0
  68.               when switch = 'B' & \ wide then full = 1
  69.               when switch = '-B' then full = 0
  70.               when switch = 'F' & \ wide then fullPath = 1
  71.               when switch = '-F' then fullPath = 0
  72.               when switch = 'L' then lower = 1
  73.               when switch = '-L' then lower = 0
  74.               when switch = 'S' then sub = 1
  75.               when switch = '-S' then sub = 0
  76.               when switch = 'V' then verbose = 1
  77.               when switch = '-V' then verbose = 0
  78.               when switch = 'P' then pause = 1
  79.               when switch = '-P' then pause = 0
  80.               when switch = '?' & \ processingInit then do
  81.                     if value('HELP.COMMAND',,'OS2ENVIRONMENT') \= '' then
  82.                        '@call %HELP.COMMAND% SDIR /?'
  83.                     else
  84.                        '@dir /?'                         
  85.                     exit 0                            
  86.                     end                
  87.               when left(switch,1) = 'A' then   
  88.                  if switch = 'A' then          
  89.                     attroff = ''                  
  90.                  else do                          
  91.                     attr = strip(substr(switch,2),,':')
  92.                     attron = ''
  93.                     attroff = ''
  94.                     do while attr \= ''
  95.                        neg = left(attr,1) = '-'
  96.                        if neg then attr = substr(attr,2)
  97.                        if pos(left(attr,1),'HRSAD') > 0 then
  98.                           if neg then
  99.                              attroff = attroff||left(attr,1)
  100.                           else              
  101.                              attron = attron||left(attr,1)
  102.                        else          
  103.                           call invalidOption arg(1), xswitch
  104.                        attr = substr(attr,2)           
  105.                     end /* do */                       
  106.                     end                         
  107.               when left(switch,2) = '-A' then do
  108.                  attroff = 'SH'                    
  109.                  attron = ''                       
  110.                  end                                  
  111.               when left(switch,1) = 'O' then          
  112.                  if switch = 'O' then                 
  113.                     sortorder = 'G N'
  114.                  else do
  115.                     order = strip(substr(switch,2),,':')
  116.                     sortorder = ''
  117.                     do while order \= ''
  118.                        neg = left(order,1) = '-'
  119.                        if neg then order = substr(order,2)
  120.                        if pos(left(order,1),'NESDG') > 0 then
  121.                           if neg then
  122.                              sortorder = sortorder '-'left(order,1)
  123.                           else
  124.                              sortorder = sortorder left(order,1)
  125.                        else
  126.                           call invalidOption arg(1), xswitch
  127.                        order = substr(order,2)
  128.                     end /* do */
  129.                     end
  130.               when left(switch,2) = '-O' then
  131.                  sortorder = ''                
  132.            otherwise                           
  133.               call invalidOption arg(1), xswitch
  134.            end /* select */               
  135.         end
  136.      else
  137.         call add opt
  138.   end
  139.   if sub & full then
  140.     fullPath = 1
  141.   return
  142.   
  143. invalidOption:
  144.   call display SysGetMessage(1003)
  145.   if words(arg(1)) > 1 | pos('/',arg(1),pos('/',arg(1))+1) > 0 then
  146.      call display SysGetMessage(1249,,'/'arg(2))
  147.   if processingInit then do
  148.      invalidOpt = 1
  149.      return                 
  150.      end                    
  151.   else                      
  152.      exit 1             
  153.      
  154. add:                        
  155.   procedure expose specs. filespec          
  156.   filespec = filespec + 1                   
  157.   i = specs.0 + 1                           
  158.   file = arg(1)        
  159.  
  160.   /* 
  161.    * les divers cas sont :
  162.    * 
  163.    * 1- chemin relatif dans l'unité courante
  164.    * 2- chemin absolu dans l'unité courante
  165.    * 3- chemin relatif dans une unité donnée
  166.    * 4- chemin absolu dans une unité donnée
  167.    */
  168.   if substr(file,2,1) \= ':' then               
  169.      file = filespec('d',directory())file                                             
  170.   /*                                                                                  
  171.    * les cas 1- et 2- ont été traités                                                 
  172.    */                 
  173.   if substr(file,3,1) \= '\' then
  174.      file = directory(filespec('d',file))'\'substr(file,3)
  175.   if left(file,1) = '\' then do
  176.      call display SysGetMessage(15)
  177.      return
  178.      end                       
  179.   /*                                                        
  180.    * directory() ajoute un '\' en fin de chaîne si c'est la racine
  181.    */                                                       
  182.   if substr(file,4,1) = '\' then
  183.      file = delstr(file,4,1)                               
  184.   /*                                                       
  185.    * le résultat est-il un répertoire, ou une spécification de fichier ?
  186.    */
  187.   if right(file,1) \= '\' & verify(file,'*?','M') = 0 then
  188.      if stream(file,'c','query exists') = '' & stream(file,'c','query datetime') \= '' then
  189.         file = file'\'                           
  190.                                                  
  191.   specs.i = file                  
  192.   specs.0 = i                         
  193.                                       
  194.   return                              
  195.                                                             
  196. init:                             
  197.   if RxFuncQuery("SysLoadFuncs") then do           
  198.      call RxFuncAdd 'SysLoadFuncs','RexxUtil','SysLoadFuncs'
  199.      call SysLoadFuncs                             
  200.      end                                          
  201.   if RxFuncQuery("VioLoadFuncs") then do   
  202.      call RxFuncAdd 'VioLoadFuncs','REXXVIO','VioLoadFuncs'
  203.      call VioLoadFuncs
  204.      end               
  205.                            
  206.   processingInit = 1
  207.   
  208.   lineCount = 1                                    
  209.                                                    
  210.   filespec = 0            /* no filespec found */
  211.   orgdir = directory()    /* initial directory */
  212.   specs.0 = 0                                                   
  213.   sub = 0                 /* /S */                              
  214.   wide = 0                /* /W */                              
  215.   full = 0                /* not /B */    
  216.   fullPath = 0            /* not /F */                          
  217.   lower = 0               /* /L */                              
  218.   verbose = 0             /* /V */                                     
  219.   pause = 0               /* /P */                                     
  220.   attron = ''             /* attributes required */
  221.   attroff = 'SH'          /* attributes exclued */
  222.   sortorder = ''          /* how to sort */                            
  223.  
  224.   prevdrive = ''     
  225.   prevrep = ''
  226.   prevfile = 0
  227.   partialSize = 0
  228.   partialCount = 0
  229.   totalSize = 0                                    
  230.   totalCount = 0
  231.  
  232.   dirLabel = strip(SysGetMessage(1054)) /* <DIR> */
  233.   parse value SysTextScreenSize() with height width .
  234.   
  235.   ci = DosQueryCtryInfo()                      
  236.   iDate = c2d(substr(ci,9,1))    /* 0 = MDY, 1 = DMY, 2 = YMD */
  237.   iTime = c2d(substr(ci,28,1))   /* 0 = 12 Hour clock, 1 = 24 */
  238.   sThousands = substr(ci,18,1)   /* ',' */
  239.   sDate = substr(ci,22,1)        /* '/' */     
  240.   sTime = substr(ci,24,1)        /* ':' */
  241.                                       
  242.   today = left(date('S'),4)*372+substr(date('S'),5,2)*31+right(date('S'),2)
  243.                                             
  244.   normal = '1b'x'[0m'                       
  245.                                      
  246.   bright = 1                         
  247.   underline = 4                             
  248.   blink = 5                       
  249.                                      
  250.   black = 30                      
  251.   red = 31                                   
  252.   green = 32                                 
  253.   yellow = 33                        
  254.   blue = 34                          
  255.   magenta = 35                               
  256.   cyan = 36                        
  257.   white = 37                         
  258.                                   
  259.   val = value('DIRCLR.ATTRIB',,'OS2ENVIRONMENT')
  260.   do while val \= ''                         
  261.      parse var val list ':' color ';' val
  262.      list = translate(list,' ',',')  
  263.      do i = 1 to words(list)                 
  264.         call value 'dirclr._attrib_._'word(list,i), ansivalue(color)
  265.      end /* do */                    
  266.   end /* do */
  267.   val = value('DIRCLR.EXT',,'OS2ENVIRONMENT')
  268.   do while val \= ''               
  269.      parse var val list ':' color ';' val
  270.      list = translate(list,' ',',')
  271.      do i = 1 to words(list)
  272.         call value 'dirclr._ext_.'word(list,i), ansivalue(color)
  273.      end /* do */                  
  274.   end /* do */                     
  275.   val = value('DIRCLR.NAME',,'OS2ENVIRONMENT')
  276.   do while val \= ''                        
  277.      parse var val list ':' color ';' val   
  278.      list = translate(list,' ',',')
  279.      do i = 1 to words(list)       
  280.         call value 'dirclr._name_.'word(list,i), ansivalue(color)
  281.      end /* do */                     
  282.   end /* do */                        
  283.   val = value('DIRCLR.DATE',,'OS2ENVIRONMENT')
  284.   do while val \= ''                        
  285.      parse var val list ':' color ';' val
  286.      dirclr._date_.newer = -list ansivalue(color)
  287.   end /* do */                                                                                       
  288.                                                                                                      
  289.   val = value('DIRCMD',,'OS2ENVIRONMENT')
  290.   if val \= '' then
  291.      call getOptions val                                                                             
  292.   if invalidOpt = 1 then
  293.      call display SysGetMessage(3154,,'DIRCMD')
  294.                                       
  295.   processingInit = 0
  296.   return
  297.                                       
  298. ansivalue:      
  299.   litcolor = arg(1); ansicolor = ''; on = 0
  300.   do while litcolor \= ''
  301.      parse upper var litcolor item litcolor
  302.      if item = 'ON' then on = 10
  303.      else           
  304.        ansicolor = ansicolor || ';' || value(item)+on
  305.   end /* do */
  306.                                     
  307.   return '1b'x'['strip(ansicolor,'L',';')'m'
  308.                            
  309. emitHeader1:                              
  310.   drive = SysDriveInfo(filespec('d',file))  
  311.   rep = left(file,lastpos('\',file)-1)
  312.   if length(rep) = 2 then rep = rep'\'
  313.                        
  314.   /* displaying standard directory header */
  315.   if drive \= prevdrive then do
  316.      if prevdrive \= '' then call terminate
  317.      call display SysGetMessage(1516,,left(drive,1),word(drive,4))
  318.      call display SysGetMessage(1243,,translate('abcd:efgh',word(DosQueryFSInfo(drive),6),'abcdefgh'))
  319.      end
  320.   return
  321.  
  322. emitHeader2:
  323.   rep = strip(arg(1))
  324.   if length(rep) = 2 then rep = rep'\'
  325.  
  326.   if rep \= prevrep then do
  327.      if partialCount > 0 then
  328.         if verbose then
  329.            call display SysGetMessage(1060,,format(partialCount,9),right(pprint(partialSize),13))'0d0a'x
  330.         else
  331.            call display SysGetMessage(1060,,format(partialCount,9),format(partialSize,10))'0d0a'x
  332.      partialSize = 0
  333.      partialCount = 0
  334.      call display SysGetMessage(1053,,rep)
  335.      end
  336.   else
  337.   if spec \= prevfile then do
  338.      if partialCount > 0 then
  339.         if verbose then
  340.            call display SysGetMessage(1060,,format(partialCount,9),right(pprint(partialSize),13))
  341.         else
  342.            call display SysGetMessage(1060,,format(partialCount,9),format(partialSize,10))
  343.      partialSize = 0
  344.      partialCount = 0
  345.      end
  346.   if LOCALRC \= 0 then do
  347.      if partialCount > 0 then
  348.         call display SysGetMessage(1060,,format(partialCount,9),format(partialSize,10))
  349.      partialSize = 0
  350.      partialCount = 0
  351.      call display SysGetMessage(LOCALRC)
  352.      end
  353.  
  354.   prevdrive = drive
  355.   prevrep = rep
  356.   prevfile = spec
  357.   return
  358.  
  359. /*
  360.  Heap sort the "file." array in ascending order.
  361.  Algorithm from "Numerical Recipes in Fortran", Cambridge University Press
  362. */
  363. sort:
  364.   if file.0 < 2 then
  365.      return
  366.   l = trunc(file.0/2)+1
  367.   ir = file.0
  368.   do forever
  369.      if l>1 then do
  370.         l = l-1  
  371.         tempd = file.l
  372.         end   
  373.      else do  
  374.         tempd = file.ir       
  375.         file.ir = file.1      
  376.         ir = ir - 1
  377.         if ir = 1 then do
  378.            file.1 = tempd         
  379.            return                 
  380.            end                    
  381.         end
  382.      i = l                        
  383.      j = l + l                    
  384.      do while j <= ir        
  385.         if j < ir then do    
  386.            k = j + 1
  387.            if compare(file.j, file.k) then
  388.               j = j + 1       
  389.            end                
  390.         if compare(tempd, file.j) then do
  391.            file.i = file.j
  392.            i = j              
  393.            j = j + j         
  394.            end
  395.         else
  396.            j = ir + 1         
  397.      end /* do */             
  398.      file.i = tempd
  399.   end /* do */
  400.                               
  401. compare: /* arg(1) < arg(2) */
  402.   procedure expose sortorder
  403.   parse upper value arg(1) with date1 size1 . attr1 fullname1
  404.   parse upper value arg(2) with date2 size2 . attr2 fullname2
  405.   name1 = substr(fullname1,lastpos('\',fullname1)+1)
  406.   name2 = substr(fullname2,lastpos('\',fullname2)+1)
  407.   
  408.   do i = 1 to words(sortorder)
  409.      order = word(sortorder,i)                              
  410.      select                                                 
  411.         when order = 'D' then do                            
  412.            if date1 < date2 then return 1
  413.            if date1 > date2 then return 0                   
  414.            end                                              
  415.         when order = '-D' then do                           
  416.            if date1 > date2 then return 1                   
  417.            if date1 < date2 then return 0                   
  418.            end                
  419.         when order = 'S' then do                            
  420.            if size1 < size2 then return 1                   
  421.            if size1 > size2 then return 0                                     
  422.            end                                                                
  423.         when order = '-S' then do                                             
  424.            if size1 > size2 then return 1
  425.            if size1 < size2 then return 0                                     
  426.            end                                                                
  427.         when order = 'N' then do                                              
  428.            if name1 < name2 then return 1
  429.            if name1 > name2 then return 0                                     
  430.            end                                                                
  431.         when order = '-N' then do
  432.            if name1 > name2 then return 1
  433.            if name1 < name2 then return 0
  434.            end                      
  435.         when order = 'E' then do    
  436.            p1 = lastpos('.',name1); if p1 = 0 then ext1 = ''; else ext1 = substr(name1,p1+1)
  437.            p2 = lastpos('.',name2); if p2 = 0 then ext2 = ''; else ext2 = substr(name2,p2+1)
  438.            if ext1 < ext2 then return 1
  439.            if ext1 > ext2 then return 0
  440.            end                                               
  441.         when order = '-E' then do                            
  442.            p1 = lastpos('.',name1); if p1 = 0 then ext1 = ''; else ext1 = substr(name1,p1+1)
  443.            p2 = lastpos('.',name2); if p2 = 0 then ext2 = ''; else ext2 = substr(name2,p2+1)
  444.            if ext1 > ext2 then return 1                      
  445.            if ext1 < ext2 then return 0                                 
  446.            end                                                          
  447.         when order = 'G' then do
  448.            if substr(attr1,2,1) \= substr(attr2,2,1) & substr(attr1,2,1) = 'D' then return 1
  449.            if substr(attr1,2,1) \= substr(attr2,2,1) & substr(attr2,2,1) = 'D' then return 0
  450.            end   
  451.         when order = '-G' then do
  452.            if substr(attr1,2,1) \= substr(attr2,2,1) & substr(attr1,2,1) = '-' then return 1
  453.            if substr(attr1,2,1) \= substr(attr2,2,1) & substr(attr2,2,1) = '-' then return 0
  454.            end                           
  455.         when order = 'P' then do /* only set when sub is 1 */
  456.            if left(fullname1, length(fullname1)-length(name1)) < left(fullname2, length(fullname2)-length(name2)) then return 1
  457.            if left(fullname1, length(fullname1)-length(name1)) > left(fullname2, length(fullname2)-length(name2)) then return 0
  458.            end
  459.      end  /* select */                   
  460.   end /* do */                             
  461.   return 0
  462.                                          
  463. emit:                  
  464.   file = value('specs.'arg(1))
  465.   filename = substr(file,lastpos('\',file)+1)
  466.   
  467.   if \full & \fullPath then call emitHeader1 arg(1)      
  468.                                            
  469.   maxWidth = 0
  470.                                                        
  471.   if attron \= '' & attroff \= '' & verify(attron,attroff,'M') \= 0 then
  472.      file.0 = 0                                          
  473.   else do                                     
  474.      attribute = '*****'
  475.      do i = 1 to length(attron)                          
  476.         attribute = overlay('+',attribute,pos(substr(attron,i,1),'ADHRS'))
  477.      end /* do */
  478.      do i = 1 to length(attroff)                       
  479.         attribute = overlay('-',attribute,pos(substr(attroff,i,1),'ADHRS'))
  480.      end /* do */
  481.                                               
  482.      if sub then
  483.         call DosFileTree file, file., 'TS', attribute
  484.      else
  485.         call DosFileTree file, file., 'T', attribute
  486.      if sortorder \= '' then call sort                                                              
  487.      end
  488.  
  489.   if file.0 = 0 then do               
  490.      LOCALRC = 2
  491.      call emitHeader2 left(file,lastpos('\',file)-1)                                                
  492.      end
  493.   else
  494.      LOCALRC = 0                                                                                    
  495.  
  496.   /* handling relevant files */
  497.   do i = 1 to file.0                  
  498.      parse var file.i year '/' month '/' day '/' hour '/' min size easize attr name
  499.                             
  500.      if full | fullPath then do                               
  501.         if right(name,2) = '\.' | right(name,3) = '\..' then iterate
  502.         end                           
  503.      else             
  504.         call emitHeader2 left(name,lastpos('\',name)-1)   
  505.                                                               
  506.      partialSize = partialSize + size      
  507.      partialCount = partialCount + 1                     
  508.      totalSize = totalSize + size                             
  509.      totalCount = totalCount + 1                          
  510.                                       
  511.      if \ fullPath then
  512.         name = substr(name,lastpos('\',name)+1)                                                     
  513.      else                             
  514.         name = strip(name)                   
  515.      easize = easize % 2                                 
  516.      if easize = 2 then easize = 0   
  517.      if lower then name = translate(name, 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')
  518.      itemLength = length(name)
  519.      if itemLength > maxWidth then maxWidth = itemLength
  520.      if substr(attr,2,1) = 'D' then do
  521.         if wide then
  522.            name = '['name']'
  523.         else                  
  524.            size = dirLabel    
  525.         itemLength = itemLength + 2
  526.         end              
  527.  
  528.      /* highlighting relevent files */       
  529.      dot = lastpos('.',name); oname = name
  530.      do j = 1 to 5            
  531.         if symbol('dirclr._attrib_._'substr(attr,j,1)) = 'VAR' then
  532.            name = value('dirclr._attrib_._'substr(attr,j,1))name
  533.      end /* do */                                  
  534.      if dot > 0 then     
  535.         if symbol('dirclr._ext_'substr(oname,dot)) = 'VAR' then                                                                          
  536.            name = value('dirclr._ext_'substr(oname,dot))name
  537.      if dot = 0 then dot = length(oname)+1                                   
  538.      if symbol('dirclr._name_.'left(oname,dot-1)) = 'VAR' then
  539.         name = value('dirclr._name_.'left(oname,dot-1))name
  540.      if symbol('dirclr._date_.newer') = 'VAR' then                                                                                       
  541.         if today - (year * 372 + month * 31 + day) <= word(dirclr._date_.newer,1) then
  542.            name = subword(dirclr._date_.newer,2)||name                       
  543.      if length(name) \= itemLength then                                                                                                  
  544.         name = name||normal
  545.                                                                              
  546.      if wide then        
  547.         dir.partialCount = itemLength name
  548.      else  
  549.      if full | fullPath then                                                                  
  550.         call display name'0d0a'x
  551.      else do
  552.         year = right(year,2)     
  553.         select  
  554.            when iDate = 0 then fdate = format(month)||sDate||day||sDate||year
  555.            when iDate = 1 then fdate = format(day)||sDate||month||sDate||year
  556.            when iDate = 2 then fdate = year||sDate||month||sDate||day
  557.         end  /* select */        
  558.         if iTime = 1 then
  559.            time = format(hour)||sTime||min' '
  560.         else                     
  561.            if hour < 13 then 
  562.               time = format(hour)||sTime||min'a'
  563.            else
  564.               time = format(hour-12)||sTime||min'p'
  565.         if verbose then
  566.           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
  567.         else
  568.           call display right(fdate,8) right(time,7) right(size,9) right(easize,11)'  'name'0d0a'x
  569.         end
  570.   end /* do */
  571.   
  572.   /* displaying result */
  573.   if wide & partialCount > 0 then do
  574.     itemCount = width % (maxWidth+4)        
  575.     line = ''
  576.     do i = 1 to partialCount
  577.       line = line || subword(dir.i,2)
  578.       if i // itemCount = 0 then do
  579.         call display line'0d0a'x            
  580.         line = ''
  581.         end
  582.       else                                  
  583.         line = line || copies(' ',maxWidth+4-word(dir.i,1))
  584.     end /* do */
  585.     if i // itemCount \= 1 then call display line'0d0a'x
  586.     end                    
  587.  
  588.   if LOCALRC = 0 & \full & \fullPath & spec = specs.0 then do
  589.      if sub then do
  590.         if verbose then
  591.            call display SysGetMessage(1060,,format(partialCount,9),right(pprint(partialSize),13))
  592.         else
  593.            call display SysGetMessage(1060,,format(partialCount,9),format(partialSize,10))
  594.         call display SysGetMessage(3155)
  595.         if verbose then
  596.            call display SysGetMessage(1060,,format(totalCount,9),right(pprint(totalSize),13))
  597.         else 
  598.            call display SysGetMessage(1060,,format(totalCount,9),format(totalSize,10))
  599.         end
  600.      else do
  601.         if verbose then
  602.            call display SysGetMessage(1060,,format(partialCount,9),right(pprint(partialSize),13))
  603.         else
  604.            call display SysGetMessage(1060,,format(partialCount,9),format(partialSize,10))
  605.        end
  606.      end
  607.           
  608.   return                                    
  609.  
  610. terminate:
  611.   /* displaying standard directory footer */
  612.   if LOCALRC = 0 & specs.0 \= 0 & \full & \fullPath then
  613.      if verbose then
  614.         call display SysGetMessage(3156,,right(pprint(word(drive,2)),31))
  615.      else
  616.         call display SysGetMessage(3156,,format(word(drive,2),28))
  617.   
  618.   call directory orgdir
  619.   return
  620.   
  621. pprint:
  622.   procedure expose sThousands
  623.   if \ datatype(arg(1), 'N') then
  624.     return arg(1)
  625.   value = reverse(arg(1))
  626.   newval = ''
  627.   do while value \= ''
  628.      parse var value group =4 value
  629.      newval = newval || sThousands || group
  630.   end /* do */
  631.   return strip(reverse(newval),, sThousands)
  632.  
  633. halt:
  634.   call display SysGetMessage(1048)
  635.   call directory orgdir
  636.   exit
  637.   
  638. display:
  639.   call charout ,arg(1)
  640.   lineCount = lineCount+length(space(translate(arg(1),'             !',,' '),0))
  641.   if pause & lineCount // height = 0 then do
  642.      call charout ,SysGetMessage(1032)
  643.      if pos(SysGetKey('NOECHO'), '00e0'x) > 0 then
  644.         call SysGetKey('NOECHO')
  645.      say
  646.      call charout ,SysGetMessage(3152,,rep)
  647.      lineCount = lineCount+2
  648.      end
  649.   return
  650.