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;)
