[comp.sys.amiga.tech] Parsing filenames with blanks inside Rexx

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

Enclosed is an excerpt from one of my Arexx scripts:

	scandir:
	arg dir
	files=showdir(dir)
	do while words(files) > 0
		file=subword(files,1,1)
		xx=statef(file)
		say xx	/* this line simplified for this example */
		files=subwork(files,2)
		end
	return

I'm having problem handling filenames that contain embedded blanks.
Other than modifying the showdir() function to put some sort of quotes
around these filenames, I don't see how files like this can be processed.

Is there something I'm missing?  Or is this an unsolvable problem?
-- 
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."

DrBob@cup.portal.com (Robert A Rethemeyer) (01/07/91)

Joe Smith writes...

> I'm having problem handling filenames that contain embedded blanks.
> Other than modifying the showdir() function to put some sort of quotes
> around these filenames, I don't see how files like this can be processed.
>
> Is there something I'm missing?  Or is this an unsolvable problem?

I believe Bill Hawes has already solved this one for you.
The following is taken from the Update.doc file on the
ARexx v1.10 update disk:

   SHOWDIR()
   Usage: SHOWDIR(directory,['All' | 'File' | 'Dir'],[separator])
   The SHOWDIR() function now accepts a separator character as the third
   argument.  Any character, including a null, can be used as a separator,
   so this provides a convenient way to separate filenames with a character
   that can't be used in the filename.
   Examples:
   say showdir('df1:c')         ==> ts tcc rxc tco hi rxset rx rxlib te
   say showdir('df1:c',,';')    ==> ts;tcc;rxc;tco;hi;rxset;rx;rxlib;te

> Joe Smith (408)922-6220 | SMTP: jms@tardis.tymnet.com or jms@gemini.tymnet.co
m

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  Bob Rethemeyer                     // "My Sneaker-Phone keeps kicking my
    DrBob@cup.portal.com   -or-     //   Football-Phone off the hook."
..!sun!portal!cup.portal.com!DrBob //                      - Jay Leno

sutela@polaris.utu.fi (Kari Sutela) (01/07/91)

jms@tardis.Tymnet.COM (Joe Smith) writes:

[omitted the program]

>I'm having problem handling filenames that contain embedded blanks.
>Other than modifying the showdir() function to put some sort of quotes
>around these filenames, I don't see how files like this can be processed.

Basically, showdir() is useless. I always use:

	'list nohead quick | execio stem files'
	do i = 1 to files.0
		/* whatever */
	end

but this requires WShell. You could redirect the output of the list command
to a temporary file.
-- 
Kari Sutela	sutela@polaris.utu.fi

wfh58@leah.albany.edu (William F. Hammond) (01/08/91)

In article <1400@tardis.Tymnet.COM> jms@tardis.Tymnet.COM (Joe Smith) writes:
> . . .
>	files=showdir(dir)
>	do while words(files) > 0
> . . .
>I'm having problem handling filenames that contain embedded blanks.
> . . .
>Joe Smith (408)922-6220 | SMTP: jms@tardis.tymnet.com or jms@gemini.tymnet.com

Aside from using the optional "separator" argument with "showdir", you could
use

   list dir_name lformat "%s%s" | rx rexx_script

where rexx_script looks to STDIN for filenames.  If your shell does not
support '|' -style pipes, there is probably a way to use "PIPE:" instead.

----------------------------------------------------------------------
William F. Hammond                   Dept. of Mathematics & Statistics
518-442-4625                         SUNYA, Albany, NY 12222
hammond@leah.albany.edu              wfh58@albnyvms.bitnet
----------------------------------------------------------------------

yorkw@stable.ecn.purdue.edu (Willis F York) (01/08/91)

wfh58@leah.albany.edu (William F. Hammond) writes:

>In article <1400@tardis.Tymnet.COM> jms@tardis.Tymnet.COM (Joe Smith) writes:
>> . . .
>>	files=showdir(dir)
>>	do while words(files) > 0
>> . . .
>>I'm having problem handling filenames that contain embedded blanks.
>> . . .

Well i missed the original post, but try "adding" a ' (single quote)
at the beggining and end of every file name that gets read into the
rexx program.

ie. i got a program called dofor.rexx and ya'd do a line like

dofor *.iff zhow

it'd get all the files with .iff and do >zhow foo.iff
then wait for zhow to exit,load the next ect....

but if the file name was like : > my picture.iff the thing messed up.

so in the command that gets sent to Wshell i did a like like.

filename.x = "'"|filename.x|"'"  

(I think i got the syntax above wrong...)

C-ya.

Send me more details and i might be able to hep.
.

--
yorkw@ecn.purdue.edu  Willis F York    
----------------------------------------------
Macintosh... Proof that a Person can use a Computer all day and still
not know ANYTHING about computers. 

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 ... +=+=+=

drake@drake.almaden.ibm.com (01/13/91)

In article <41103@nigel.ee.udel.edu> new@ee.udel.edu (Darren New) writes:
>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.  

Current systems might exhibit this behavior, but it is non-portable.
POSIX 1003.1 explicitly states that all characters except slash and 0x00
are valid.


Sam Drake / IBM Almaden Research Center 
Internet:  drake@ibm.com            BITNET:  DRAKE at ALMADEN
Usenet:    ...!uunet!ibmarc!drake   Phone:   (408) 927-1861