Vladimir Kotal wrote:
> UVR wrote:
> > Vladimir Kotal wrote on Wed Jul 09 2008 at 04:54:16 GMT-0700 (PDT):
> >> [snip]
> >>
> >> Thus: What is the recommended "style" for ksh based test suites -
> >> double or single square brackets ? Does ksh93 process the two cases
> >> differently than ksh88 ?

The recommendation is to use double-square brackets (for string/pattern
comparisations, for integer/float variables see below) to avoid the
extra expansion pass required by single-square brackets. Additionally
some operators only work with [[ ]]

> > The Bourne/Korn shell style guide[1] clearly recommends using
> 
> Aha, so we have shell-discuss after all ! Somehow I did not see it
> previously. I am Cc'ing it now.
> 
> > "[[ ... ]]" for ksh and "(( ... ))" for arithmetic expressions,
> > and those would be my recommendation too.  The guide presents
> > 'perf' as the reason for suggestiong the double brackets.
> 
> Based on my investigation the performance improvement with double square
> brackets for simple comparison tests in ksh88 is neglectable. It's
> probably more visible with complicated (logic) expressions.

The reason for the (( )) is simply that "numbers" should be treated with
_arithmetric_ operators and not _string_ operators. Using the string
operators will force the shell always to convert the internal
representation (e.g. |long long| or |long double|) to a string, pass it
via argv to the builtin command and then convert it back to a number for
comparisation. Using the arithmetric operators (where the '$' can be
obmitted) saves this number-string-number conversion cycle completely.

And for floating-point usage the (( )) are more or less mandatory since
otherwise you get rounding errors if you convert from the base2 IEEE
floating-point representation to human-readable strings (which are in
base10) and then back to the base2 IEEE floating-point representation.
Example:
$ ksh93 -c 'float x=0.5 y=0.5 ; x=$(( $x / 19. )) ; (( y=y/19. )) ; (( x
== y )) && print "no rounding error" || print "rounding error"' #
prints
-- snip --
rounding error
-- snip --
... since x=$(( $x / 19. )) will convert the result of $x / 19. into a
base10 string while y=y/19. keeps the internal base2 representation.

The correct way is to replace x=$(( $x / 19. )) with (( x=x / 19. )) ,
e.g.
$ ksh93 -c 'float x=0.5 y=0.5 ; (( x=x / 19. )) ; (( y=y/19. )) ; (( x
== y )) && print "no rounding error" || print "rounding error"' #

integer variables don't have rounding errors but it is at least usefull
from the performance and correctness point of view.

> >> The main question for me is: should I be using double square brackets
> >> for test predicates in nc test suite before I take next step in the
> >> integration process ? (nc test suite is fully ksh based)
> >
> > Do use them, but more importantly, make sure your test suite runs
> > correctly under both ksh88 and ksh93.
> 
> ok, I will rewrite the tests in nc test suite to use double brackets.
> 
> Is there something like kstyle script ? (similar to cstyle used by wx)

Not yet... what I am currently aiming at is something like a "shlint",
e.g. "shell lint" (I don't like the idea of a "cstyle" clone just to
trample on people if their line length exceeds 80 characters (which is
sometimes unavoidable in shell scripts since string literals cannot be
continued via '\' like in C/C++ code)). Right now you can get a similar
(bit less picky) version of it by installing
http://www.opensolaris.org/os/project/ksh93-integration/downloads/2008-07-02/
and then use $ shcomp -n myscript.ksh /dev/null # or $ ksh93 -n
myscript.ksh #

> Also, any idea how to test a test suite against specific ksh version
> without changing /usr/bin/ksh binary on the test system ?

AFAIK this should work:
$ ksh93 -c ' [ "`(printf "%s\n" ${.sh.version}) 2>/dev/null`" != "" ] &&
print "ksh93"' #

----

Bye,
Roland

-- 
  __ .  . __
 (o.\ \/ /.o) roland.mainz at nrubsig.org
  \__\/\/__/  MPEG specialist, C&&JAVA&&Sun&&Unix programmer
  /O /==\ O\  TEL <currently fluctuating>
 (;O/ \/ \O;)

Reply via email to