home *** CD-ROM | disk | FTP | other *** search
- package RISCOS::Filespec;
-
- # Turn filename conversion off, unless parent imports the dummy symbol dont
- # So. If you want to import all the symbols use the tag :all
- # Importing /.*/ will also get 'dont'. You have been warned
-
- # convert, convert_on, convert_off riscosify etc are implemented in riscos.c
-
- require Exporter;
- use Carp;
-
- $VERSION = 0.11;
- @ISA = qw(Exporter);
- @EXPORT = qw();
- # chown chroot fcntl ioctl link lstat readlink symlink
- # Not umask as this doesn't use a filename
- # Not glob as this is performed by a fuction in riscos.c
- # Not stat or any of the file tests as these are performed via a wrapper in
- # riscos.c
-
- my @constants = qw (__RISCOSIFY_MASK __RISCOSIFY_NO_PROCESS
- __RISCOSIFY_DROP_VOWEL __RISCOSIFY_NO_SUFFIX
- __RISCOSIFY_DONT_CHECK_DIR __RISCOSIFY_CHECK_DIR_IS_SUFFIX
- __RISCOSIFY_TRUNCATE_SHIFT __RISCOSIFY_TRUNCATE_MASK
- __RISCOSIFY_DONT_TRUNCATE __RISCOSIFY_LONG_TRUNCATE
- __RISCOSIFY_MEDIUM_TRUNCATE __RISCOSIFY_SHORT_TRUNCATE);
-
- my @filespec = qw(riscosify unixify canonicalise);
-
- my @switch = qw(convert convert_on convert_off);
-
- @EXPORT_OK = (@switch, @filespec, 'convert_set', @filespec, @constants,
- 'dont');
-
- %EXPORT_TAGS = (constants => \@constants, filespec => \@filespec,
- switch => \@switch, control => ['convert_set', @constants],
- all => [@constants, @filespec, @swtich, @convert],
- dont => ['dont']);
-
- @EXPORT_FAIL = ('dont');
-
- my $do = 1;
- # Turn off
- sub export_fail {
- shift @_; # Remove package name
- map {
- if ($_ eq 'dont') {
- undef $do;
- ();
- } else {
- $_;
- }
- } @_
- }
-
- sub import {
- my $self = shift;
- local $Exporter::ExportLevel = 1; # Export into our parent, not us!
- $self->SUPER::import (@_);
- convert_off() if $do; # Turn filename conversion off
- }
-
- # The riscosify magic numbers are in XS
- # XS is fun :)
-
- sub AUTOLOAD {
- my($constname);
- ($constname = $AUTOLOAD) =~ s/.*:://;
- my $val = RISCOS::Filespec::constant($constname);
- croak "Undefined subroutine $AUTOLOAD" unless defined $val;
- eval "sub $AUTOLOAD { $val }";
- goto &$AUTOLOAD;
- }
-
- 1;
- __END__
-
- =head1 NAME
-
- RISCOS::Filespec -- routines to control and perform filename conversion.
-
- =head1 SYNOPSIS
-
- use RISCOS::Filespec; # Turn off Unix filename conversion.
-
- use RISCOS::Filespec /riscosify/;
- @name = riscosify ('miniperlmain.c');
-
- use RISCOS::Filespec /canonicalise/;
- @pwd = canonicalise '@';
- @name = canonicalise \*STDIN;
-
- =head1 DESCRIPTION
-
- By default this S<RISC OS> perl port assumes that all filenames are in "Unix"
- format, and automatically converts to "native" format for all C<open>
- C<rename> I<etc.> operations.
-
- By using C<RISCOS::Filespec> a perl script turns off this conversion, and shows
- that it understands S<RISC OS> file naming conventions. Because UnixLib
- processes command line redirection before perl starts, let alone the script, the
- internal conversion routine is always used for filenames in command line
- redirection.
-
- As well as providing routines to control the name conversion on perl builtins,
- C<RISCOS::Filespec> provides access to the conversion routines to and from
- "Unix" format, and a subroutine to convert filenames and filehandles to
- canonical filenames.
-
- The internal conversion routine to "native" format works as follows:
-
- =over 4
-
- =item *
- Full S<RISC OS> pathnames of the form 'F<ADFS::Bagpuss.$.!Boot>' and 'F<RAM:$>'
- are recognised as such and are passed back unmodified.
-
- =item *
- Pathnames starting 'F</dev/>' are converted to paths - 'F</dev/parallel>' will
- return 'F<parallel:>'.
-
- =item *
- Filenames starting 'C</>' are checked in a special list - this allows 'F</tmp>'
- to be mapped to 'F<<Wimp$ScrapDirE<gt>>'.
-
- =item *
- Pathnames starting with 'C</>' 'C<$>' or 'C<<>' are taken as absolute - if a
- filing system name is found after 'C</>' it is returned to start the name,
- otherwise 'C<$.>' is used.
-
- =item *
- Each 'C</>' delimited section of the pathname is then processed in turn.
- If the section ends in a suffixes in the suffix list it is prefixed as a
- directory name. Other 'C<.>' are converted to 'C</>', 'C<?>' and 'C<#>' map
- to each other, characters illegal in RISCOS filenames are mapped to 'C<_>'.
-
- =back
-
- =head2 Subroutines to control the internal conversion routines
-
- The following routines control filename conversion on "user" filenames supplied
- by the script. Filename conversion for internal filenames in C<use> and
- C<require> statements is B<always> turned on, and is unaffected by the use of
- these functions. [It would be hard to change internal filenames, as the perl
- source code assumes that '/' is a directory separator.]
-
- =over 4
-
- =item convert <new_status>
-
- =item convert
-
- Reports the status of filename conversion prior to the call, returning true if
- filename conversion was turned on, false if turned off. If called with no
- arguments, or an undefined argument, leaves the conversion setting unchanged.
- Otherwise it turns conversion on if the argument is true, off it is false.
-
- =item convert_on
-
- Turns filename conversion on. Returns true if filename conversion was on
- already, false if filename conversion was off.
-
- =item convert_off
-
- Turns filename conversion off. Returns true if filename conversion was B<off>
- already, otherwise returns false.
-
- =item convert_set <flags>
-
- Sets the flags for filename conversion as detailed in the table below.
- convert_set will C<croak> if reserved bits in the flags are not zero - always
- use the C<__RISCOSIFY_*> subroutines provided to construct flag settings.
- convert_set will warn if it is called in array context - use an explicit
- C<scalar> if necessary, as it is proposed to change the return value for an
- array context.
-
- =over 4
-
- =item __RISCOSIFY_NO_PROCESS
-
- If this bit is set then filename conversion is B<off>, and no further action is
- taken. C<riscosify> and C<unixify> return the filename unmodified, perl builtins
- perform no filename conversion.
-
- =item __RISCOSIFY_DONT_TRUNCATE
-
- =item __RISCOSIFY_LONG_TRUNCATE
-
- =item __RISCOSIFY_MEDIUM_TRUNCATE
-
- =item __RISCOSIFY_SHORT_TRUNCATE
-
- Set the length to truncate each filename segment. C<__RISCOSIFY_DONT_TRUNCATE>
- turns truncation off, the default setting. Filing systems such as C<ADFS>
- currently will still truncate filenames to 10 characters, but not truncating
- filenames internally allows perl to work well with filing systems that support
- longer names.
-
- C<__RISCOSIFY_SHORT_TRUNCATE> truncates to B<10> characters - current
- C<FileCore> filing systems such as C<ADFS> and C<SCSIFS> have a 10 character
- limit.
-
- C<__RISCOSIFY_MEDIUM_TRUNCATE> truncates to B<19> characters - SparkFS 1.28 and
- earlier have a bug relating to filename truncation.
-
- C<__RISCOSIFY_LONG_TRUNCATE> truncates to B<55> characters - the maximum length
- name allowed by the C<longfiles> module.
-
- =item __RISCOSIFY_DROP_VOWEL
-
- If the path element is too long, drop vowels before truncating.
- (C<a> C<e> C<i> C<o> C<u> independent of locale setting.)
-
- =item __RISCOSIFY_NO_SUFFIX
-
- Disable 'suffix' checking - UnixLib keeps a list of suffixes that it recognises.
- If a filename ends in a known suffix, it is used as a directory name.
- Hence 'F<foo.bar>' is mapped to 'F<foo/bar>' ('F<bar>' not a recognised suffix)
- whereas 'F<perl.c>' is mapped to 'F<c.perl>' ('F<c>' is by default in the
- recognised list).
-
- Currently the default list is specified by C<Unixfs$sfix> set by the F<!Boot>
- file - removing 'C<pl>' and 'C<pm>' from this list will cause C<use> and
- C<require> to fail unless you rename all files in the library from F<pm.*> to
- F<*.pm>
- [This is feasible, and if a future filecore supports long filenames will become
- the default distribution arrangement.]
-
- By default suffix checking is on, so this bit is unset.
-
- =item __RISCOSIFY_DONT_CHECK_DIR
-
- By default this flag is off. If enabled, and the conversion routine is presented
- with 'F<!Perl/lib/File.pm>' it will check whether a directory
- 'F<!Perl.lib.File>' exists. If it does, it will return 'F<!Perl.lib.File.pm>',
- if it does not it will return 'F<!Perl.lib.File/pm>'.
-
- =item __RISCOSIFY_CHECK_DIR_IS_SUFFIX
-
- By default this flag is off. If enabled it will restrict the match of the above
- test to only match directories that are found in the suffix list. This allows
- a degree of "intuition" when presented with a filename that could be in "Unix"
- or "native" format:
- 'F<c.riscos>' will map to 'F<c.riscos>' assuming the directory 'F<c>' exists.
- 'F<riscos.c>' will map to 'F<c.riscos>'
-
- =item __RISCOSIFY_MASK
-
- Returns the mask of acceptable flag bits.
-
- =back
-
- =item riscosify <filename> [<flags>]
-
- =item riscosify <filehandle> [<flags>]
-
- Converts a filename to "native" format using the same routine as the builtin
- name conversion. If one argument is supplied uses the same flags as the builtin
- conversion routine - hence if C<convert_off> has been called C<riscosify> will
- return the filename unchanged. If two arguments are supplied the second is used
- as the flags to the conversion routine.
- Note that C<riscosify> performs a many to one mapping, I<e.g.>
- 'F<c/pp_hot>' and 'F<pp_hot.c>' both map to 'F<c.pp_hot>'
-
- If passed a filehandle (I<i.e> reference to a typeglob, or an IO object) will
- convert that file handle to the name of the file it refers to, or undefined if
- the handle is not open on disc file. For a filehandle the value of flags doesn't
- affect the conversion, but will be faulted if it contains reserved bits set.
-
- =item unixify <filename> [<flags>]
- =item unixify <filehandle> [<flags>]
-
-
- Converts a filename or filehanedle to "Unix" format (currently this routine is
- roughly C<tr :/.#?:./?#/ if convert_on();> but with knowledge about C</../> and
- filing system special fields. Swapping back of suffixes may be available in
- future. Note that as C<riscosify> performs a many to one mapping, correct
- recovery of the name by C<unixify> is impossible 100% of the time.
-
- =item canonicalise
-
- canonicalises a filename (I<i.e.> converts it to a full pathame, and removes any
- wildcards. If passed a filehandle (I<i.e> reference to a typeglob, or an IO
- object) will convert that file handle to the name of the file it refers to, or
- undefined if the handle is not open on disc file.
-
- With one filename argument C<canonicalise> is effectively
-
- riscosify
- OS_FSControl 37
- unixify
-
- and with one filehandle argument
-
- OS_Args 7
- unixify
-
- If a second argument is given it is used as flags for C<riscosify> and
- C<unixify>. If three arguments are given, the second is the flag for
- C<riscosify>, the third the flag for C<unixify>.
-
- =item RISCOS::Filespec::convert_internal
-
- returns the riscosify flags used by internal opens (I<e.g.> use). This value is
- needed for the throwback module.
-
- =back
-
- =head1 BUGS
-
- Aside from the deficiencies noted above, none known.
-
- =head1 AUTHOR
-
- Nicholas Clark <F<nick@unfortu.net>>
-