-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 According to Dave Korn on 8/14/2009 5:34 AM: > Still finishing it off and getting it tested, but while that's going, here's > a preview of the path canonicalisation function as I've got it so far; let me > know if I've done any major no-nos please!
> pathcar="s,^/\([^/]*\).*$,\1," > pathcdr="s,^/[^/]*,," > removedotparts="s,/\(\.\(/\|$\)\)\+,/,g" > collapseslashes="s,/\+,/,g" > > # func_normal_abspath path > # Remove doubled-up and trailing slashes, "." path components, > # and cancel out any ".." path components in PATH. Cancelling out .. is wrong for 'symlink/..', when symlink does not necessarily point to a working directory exactly one level down. (True, cygwin does not implement POSIX semantics here, and cancels out foo/.. behind your back rather than properly resolving foo, but this function will need to work on all other systems that do it correctly). > func_normal_abspath_tpath="$1" Double-quoting not necessary here - variable assignment is already in a quoted context, and quotes are only needed to protect metacharacters. > case "$func_normal_abspath_tpath" in Likewise - the case argument is already in a double-quoted context. > "") > # Empty path, that just means $cwd. > func_stripname '' '/' "`pwd`" Can we rely on $PWD instead of forking a process? > func_normal_abspath_result="$func_stripname_result" > return > ;; > /*) > # Absolute path, do nothing. Do we want to cater to DOS style absolute paths? [a-z]:\\ > ;; > *) > # Relative path, prepend $cwd. > func_normal_abspath_tpath="`pwd`/$func_normal_abspath_tpath" Again, double quotes aren't necessary. > ;; > esac > # Cancel out all the simple stuff to save iterations. > func_normal_abspath_tpath="`$ECHO "$func_normal_abspath_tpath" | $SED \ > -e "$removedotparts" -e "$collapseslashes"`" I thought we were trying to move away from $ECHO and instead use the shell functions. And you have a portability no-no, documented in the autoconf manual: a="`""`" is non-portable, but can always be replaced by the portable: a=`""` See why I don't like spurious "" around variable assignments? > # We want the path to end with a slash for ease of parsing, and > # doubled-up slashes won't hurt us here, so just add one on. > func_normal_abspath_tpath="$func_normal_abspath_tpath/" > while :; do > func_normal_abspath_tcomponent="`$ECHO "$func_normal_abspath_tpath" | > $SED \ > -e "$pathcar"`" > func_normal_abspath_tpath="`$ECHO "$func_normal_abspath_tpath" | $SED \ > -e "$pathcdr"`" Nit - I'd break these long lines at |, not after $SED, so that the entire sed command is on a single line. > # Figure out what to do with it > case "$func_normal_abspath_tcomponent" in > "") > # Trailing empty path component, ignore it. > ;; > ..) > # Parent dir; strip last assembled component from result. > func_dirname "$func_normal_abspath_result" > func_normal_abspath_result="$func_dirname_result" > ;; > *) > # Actual path component, append it. > > func_normal_abspath_result="$func_normal_abspath_result/$func_normal_abspath_tcomponent" > ;; > esac > # Processed it all yet? > if test "$func_normal_abspath_tpath" = / ; then > # If we ascended to the root using ".." the result may be empty now. > if test -z "$func_normal_abspath_result" ; then > func_normal_abspath_result=/ > fi > break > fi > done > } - -- Don't work too hard, make some time for fun as well! Eric Blake e...@byu.net -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (Cygwin) Comment: Public key at home.comcast.net/~ericblake/eblake.gpg Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAkqFV58ACgkQ84KuGfSFAYAGLwCeNF5H7L+noHCwyR6MDPwuFnTk zJIAoMC0kyZtLZHd9bx4PX4m/J6pcF/O =y3KX -----END PGP SIGNATURE-----