[comp.lang.rexx] Parsing filenames with blanks inside Rexx

jms@tardis.Tymnet.COM (Joe Smith) (01/08/91)

I asked: "How do you scan a directory that may have filenames with embedded
blanks".  I got help from Francois Rouaix <rouaix@margaux.inria.fr>.
Many REXX string functions take an optional extra argument to specify
the pad character.  Sure enough, showdir() takes a 3rd arg.

The statement "files=showdir(thisdir)" is the same as
"files=showdir(thisdir,'all','20'x)" in that it lists all types of files
in the directory thisdir, and separates the names with blanks ('20'x).
The only character guaranteed not to be part of any filename is '00'x.

/* LISTDIR - List directory and its subdirectories, using relative path names.
   This AREXX script was created because the 'LIST ALL LFORMAT=' command can
   be made to output 1) just the filename, or 2) the absolute path name
   (including volume name), but not 3) path name relative to current directory.
*/

parse arg topdir opts .
if topdir = "" then do
	parse source . . myname .		/* get name of this script   */
	say 'Usage: rx' myname 'directory-name'
	say '  To list all files and subdirectories of "directory-name".'
	say 'Usage: rx >RAM:temp' myname '"" QUICK'
	say '  To list just the filenames only.  "" means current directory.'
	say '  The options FILES and DIRS also produce a QUICK listing.'
	exit
	end
quickflag = abbrev("QUICK",upper(opts),1)	/* no sizes, dates, etc      */
filesonly = abbrev("FILES",upper(opts),1)	/* list files only, QUICK    */
dirsonly  = abbrev("DIRS",upper(opts),1)	/* directorys only, QUICK    */
call addlib('rexxsupport.library',0,-30,0)	/* in case not already added */

if topdir = "''" | topdir = '""' then topdir = ""	/* default directory */
if word(statef(topdir),1) ~= "DIR" then say "Error:" topdir "is not a directory"
else call scandir topdir		/* do recursive directory traversal  */
exit

scandir: procedure expose quickflag filesonly dirsonly
parse arg dir	/* variable 'dir' may contain blanks and lowercase letters   */

slash = "/"
if right(dir,1) = ":" | dir = "" then slash = ""
if dirsonly then file = "dir"; else file = "all"
files = showdir(dir,file,'00'x)	    /* list of files, separated by NULL bytes*/
do while words(files) > 0
  delimiter = pos('00'x,files)				/* locate the NULL   */
  if delimiter = 0 then delimiter = length(files)+1	/* only one name     */
  file = dir||slash||substr(files,1,delimiter-1)	/* first name        */	
  files = substr(files,delimiter+1)			/* all but 1st name  */
  sf = statef(file)		/* note: filename may contain embedded blanks*/
  /* statef returns {DIR|FILE} length blocks protect days mins ticks note... */
  if sf = "" then say "Cannot locate" file
  else do
    if quickflag | filesonly | dirsonly then do
      if word(sf,1) = "FILE"& ~dirsonly  then say file
      if word(sf,1) = "DIR" & ~filesonly then say file
      end
    else do
      f=left(word(sf,1),4)||right(word(sf,2),8)||right(word(sf,3),5)||dat(sf)
      say f file
      if word(sf,8) ~= "" then say ":" subword(sf,8)	/* list the filenote */
      end
    if word(sf,1) = "DIR" then call scandir file	/* process subdir    */
    end
  end
return

dat: procedure	/* returns date/time as " YY/MM/DD HH:MM" */
arg stat
  /* seconds = word(stat,7)%50 */
  minutes = word(stat,6)//60
  if minutes < 10 then minutes = "0"||minutes
  hours = word(stat,6)% 60
  if hours < 10 then hours = "0"||hours
return ' '||date('O',word(stat,5),I)||' '||hours||':'||minutes
/* End of Rexx:ListDir.rexx */
-- 
Joe Smith (408)922-6220 | SMTP: jms@tardis.tymnet.com or jms@gemini.tymnet.com
BT Tymnet Tech Services | UUCP: ...!{ames,pyramid}!oliveb!tymix!tardis!jms
PO Box 49019, MS-C51    | BIX: smithjoe | CA license plate: "POPJ P," (PDP-10)
San Jose, CA 95161-9019 | humorous dislaimer: "My Amiga 3000 speaks for me."

new@ee.udel.edu (Darren New) (01/09/91)

In article <1406@tardis.Tymnet.COM> jms@tardis.Tymnet.COM (Joe Smith) writes:
>The only character guaranteed not to be part of any filename is '00'x.

Not really true.  It is possible to put a \0 in the file name by using
BSTRs instead of C strings.  The only character that cannot be in a
OFS or FFS file name is a slash. Even that could be put in a name
with a disk editor, if nothing else. However, I imagine there would
be problems openning it if nothing else.        -- Darren
-- 
--- Darren New --- Grad Student --- CIS --- Univ. of Delaware ---
----- Network Protocols, Graphics, Programming Languages, 
      Formal Description Techniques (esp. Estelle), Coffee, Amigas -----
              =+=+=+ Let GROPE be an N-tuple where ... +=+=+=