Boost logo

Boost :

From: Karl Nelson (kenelson_at_[hidden])
Date: 2002-02-19 12:15:12


>
> |> > Why not an exception? (My own implementation treats the presence
> |> > of a %2$ without a %1$ as an error.) Of course, he did say X/Open
> |> > compatibility, and in X/Open printf, it is undefined behavior:-).
>
> |> This is a very tough call. How would you know when a exception is
> |> appropraite with a format operator? After all the strings are
> |> coming in from outside source like gettext so if you throw
> |> expections that means virtually every call to format would need to
> |> be wrapped with try/catch. It is no fun having some
> |> internationalization version of your code crash just because the
> |> translator garbled some string, but then is silently displaying the
> |> wrong text much better?
>
> My thoughts exactly. My implementation aborts, but only because
> exceptions weren't generally available when I wrote it. An exception in
> this case allows you to continue, perhaps dropping the translation and
> using the original text.
>
> On another tangent: has anyone considered the possibility of wrapping
> gettext with something that checks that the resulting format is
> compatible with the given one. (In standard terms, this would mean
> wrapping the std::messages::get function to ensure that the returned
> string is compatible with the default.)

No, but it might be a good idea.

> |> Currently it implements throw only if the format string is
> |> uninterpretable. Theoretically, I could make it throw on conversion
> |> to string when requested...
>
> |> Ie.
>
> |> try {
> |> cout << format(gettext("%s %d"), name, count).throw_incomplete();
> |> } catch (io::incomplete_error e) {
> |> cerr << e.what() << endl;
> |> }
>
> |> That way it does not throw on incorrect number of arguments when the
> |> user does not intend it.
>
> Right.
>
> This is a general problem. My own implementation distinguished three
> states, initialization (with the initial parse of the format string),
> insertion of the parameters, and the final conversion (conversion to
> string or output to a stream). The number of parameters seen was
> checked at the final conversion, and any attempt to pass a parameter
> after the final conversion was a fatal error.

Yeah there are definitely 3 classes of error.
  - bad format
  - too many arguments passed to format "expect 3 you just gave 4"
  - too few when conversion is requested.

Since giving a exception is more than likely going to give bad output
(where was I in the cout statement when it threw) And simply
using the bad format would do that, it would sound like it
would be best to just have a format error state in the formatting
class and then throw only when requested.

 
> The obvious use of format is as a temporary, as we've seen in most of
> the examples. But one could argue for other possibilities:
>
> format( "%s %d" ) fmt ;
> for ( int i = 0 ; i < 10 ; ++ i ) {
> cout << fmt.with( s[ i ] ).with( x[ i ] ) << '\n' ;
> }
>
> In this case, the conversion would cause the format object to revert to
> the parameter insertion state. But that would forbid:
>
> format( "%s %d" ) fmt ;
> fmt.with( s ).with( i ) ;
> std::cout << fmt << '\n' ;
> logStream << fmt << '\n' ;

Okay I handled this part very differently. format was the function
to do the .with() and call a rewind.

So
   format_expr fmt("%s %d");
   fmt(s)(i);
   std::cout << fmt << '\n' ;
   logStream << fmt << '\n' ;

works because fmt still has the arguments.

But this wont unless you add a rewind statment or use format()

     format_expr fmt( "%s %d" );
     for ( int i = 0 ; i < 10 ; ++ i ) {
        cout << fmt( s[ i ] )( x[ i ] ) << '\n' ; // too many arguments.
     }

This will
     format_expr fmt( "%s %d" );
     for ( int i = 0 ; i < 10 ; ++ i ) {
        cout << format (fmt, s[ i ], x[ i ] ) << '\n' ;
     }

Alternatively...
     format_expr fmt( "%s %d" );
     for ( int i = 0 ; i < 10 ; ++ i ) {
        cout << fmt( s[ i ]) ( x[ i ] ) << '\n' ;
        fmt.rewind();
     }

--Karl


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk