Path: csiph.com!x330-a1.tempe.blueboxinc.net!usenet.pasdenom.info!weretis.net!feeder4.news.weretis.net!nuzba.szn.dk!pnx.dk!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail From: Rainer Weikusat Newsgroups: comp.unix.shell,comp.unix.programmer,comp.programming.contests Subject: Re: The First Pure Shell Contest (PUSH): relativepath Date: Mon, 22 Aug 2011 21:15:03 +0100 Lines: 167 Message-ID: <87ty99kxtk.fsf@sapphire.mobileactivedefense.com> References: <9b7kg7F3njU1@mid.individual.net> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: individual.net P5IxWrtYP5EYpbEZS/SZcwycLfBfQs12olE39ngSWWm78w8MM= Cancel-Lock: sha1:a3z7GzOzlEqdR8ZxsqQcWej/J8o= sha1:be20yRa3cNZfvE6DsQw2HQxMsc0= User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.2 (gnu/linux) Xref: x330-a1.tempe.blueboxinc.net comp.unix.shell:1792 comp.unix.programmer:1178 comp.programming.contests:25 Jens Schweikhardt writes: > The First Pure Shell Contest (PUSH) > > == Motivation == > > The shell is not known for powerful string processing. For sake of completeness. NB: I do not claim that this would be good for anything except that it survives the unit_test() function. Also, it is not supposed to be 'competitive'. ----------------------------- # Name split() { eval "case \"\$$1\" in ?*/*) $3=\${$1#/} $2=\${$3%%/*} $3=\${$3#*/} return 0 ;; /*) $3=\${$1#/} ;; *) $3=\"\$$1\" esac $2=''" } error() { echo "<$1> not absolute or canonical" } valid() { rc=1 test "${1#/}" != "$1" && { rc='' case "$1" in *//*) rc=1 ;; *?/) rc=1 ;; */./*) rc=1 ;; */../*) rc=1 ;; */..) rc=1 ;; */.) rc=1 ;; esac } test -z "$rc" && return 0 result=`error "$1"` return 1 } one_up() { result="../$result" } one_down() { eval "result=\"\$result\$$1/\"" } walk() { w="$1" split w fw rw while test -n "$fw"; do $2 fw w="$rw" split w fw rw done $2 rw return 0 } relativepath() { d0="$1" valid "$d0" || return 1 d1="$2" valid "$d1" || return 1 split d0 fa ra split d1 fb rb while test -n "$fa" -a "$fa" = "$fb"; do a="$ra" split a fa ra b="$rb" split b fb rb done result='' if test -n "$fa"; then a="$ra" if test -n "$fb" -o "$fa" != "$rb" then a="/$fa/$a" test -n "$rb" && { b="$rb" test -n "$fb" && b="/$fb/$b" walk "$b" one_down } fi walk "$a" one_up elif test -n "$fb"; then b="$rb" if test "$ra" != "$fb"; then b="/$fb/$b" test -n "$ra" && one_up fi walk "$b" one_down else test "$ra" = "$rb" && { result=. return 0 } result="$rb" test "$d0" != / && result="../$result" fi result="${result%/}" return 0 }