Topic: Output formatting (was What next...)


Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1997/11/12
Raw View
Christopher Eltschka <celtschk@physik.tu-muenchen.de> writes:

|>  \begin{:-)}
|>  In addition, we could have streambufs for input, which do automatic
|>  preprocessing. That would be really useful for compiler writers.
|>  \end{:-)}

Why the smileys?  I've actually got streambuf's which handle comments
correctly, and it wouldn't be too difficult to extend them to handle
simple macros and include files.  (Function style macros would be
somewhat harder.)

--
James Kanze    +33 (0)1 39 23 84 71    mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
        I'm looking for a job -- Je recherche du travail
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1997/11/13
Raw View
J. Kanze wrote:
>
> Christopher Eltschka <celtschk@physik.tu-muenchen.de> writes:
>
> |>  \begin{:-)}
> |>  In addition, we could have streambufs for input, which do automatic
> |>  preprocessing. That would be really useful for compiler writers.
> |>  \end{:-)}
>
> Why the smileys?  I've actually got streambuf's which handle comments
> correctly, and it wouldn't be too difficult to extend them to handle
> simple macros and include files.  (Function style macros would be
> somewhat harder.)

The smileys are, because the thread was about what should be in the
standard library. In principle, there's nothing wrong with such
streambufs (I even think it would be a better idea than an extra
program for preprocessing, as more information could be passed to
the compiler, for better error messages and debugging info).
But I'm shure this should not be in the standard library.

Maybe there *could* be a general transformation streambuf in the
standard library, which doesn't itself any transformation, but
offers a standard interface for such transformations. This would
include
- automatic forwarding to another streambuf (and a method to
  set/change this streambuf)
- virtual member functions to support pattern matching (that is,
  the matching itself is implemented by derived classes)
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1997/11/14
Raw View
Christopher Eltschka <celtschk@physik.tu-muenchen.de> writes:

|>  Maybe there *could* be a general transformation streambuf in the
|>  standard library, which doesn't itself any transformation, but
|>  offers a standard interface for such transformations. This would
|>  include
|>  - automatic forwarding to another streambuf (and a method to
|>    set/change this streambuf)
|>  - virtual member functions to support pattern matching (that is,
|>    the matching itself is implemented by derived classes)

Interesting.  As mentioned before, I have such a streambuf, using a
template rather than virtual functions for specializing.  And without
the possibility of changing the final streambuf.  (Which is a good idea --
I think I'll add it.  And while I'm at it, maybe go the route of virtual
functions -- the current version requires two functions in the
instantiation class, and most of the time, one of them is empty.)

--
James Kanze    +33 (0)1 39 23 84 71    mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
        I'm looking for a job -- Je recherche du travail
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1997/11/10
Raw View
Paul D. DeRocco wrote:

[...]

> Another thing that I've always found clumsy was the use of
> manipulators to set field widths and output bases. I've always
> preferred something like:
>
>         cout << DecN(v, c);
>
> which would output value v in decimal right-justified in c
> columns, or
>
>         cout << Hex8(x) << " " << Hex2(y) << '\n';
>
> which would output an 8-digit and a 2-digit hex number. The code
> is more compact and readable, in my view.

You can get this, by simply defining functions like

string DecN(double, int);
string Hex8(int);
string Hex2(int);

But to be able to set the output precision _once_ is IMHO a good thing.
I wouldn't like to write Precision(x, 10) every time I output a number,
just because I want all my numbers output 10 digits precision.
Someone writing a hexdump program might think the same about
hex output.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1997/11/10
Raw View
"Paul D. DeRocco" <pderocco@ix.netcom.com> writes:

|>  When I say I'd like line wrap, I mean that I want words that
|>  don't fit on a line to be bumped down to the next line. (An
|>  indentation for wrapped lines is also a useful parameter.) That
|>  involves considerably more code than the above, including a
|>  buffer to accumulate a word into.

Fine.  In this case, of course, the streambuf will be significantly more
complicated.  Perhaps it should handle hyphenation, too, while it is at
it.  And variable width fonts would seem a necessity.  Maybe we should
require a streambuf which does full LaTeX formatting:-).

I know this isn't what you are asking for.  But the problem is, the cut
off for each person will be different, so what do you standardize?

|>  Perhaps people who write Windows code rarely need this, because
|>  they deal with proportionally space fonts. I write lots of
|>  command line utilities that run in text screens that use fixed
|>  space fonts, so column counting, tab expansion, and line wrap
|>  based on simple character counts are all very useful to me.

No doubt.  And as you say, other people will need other things.  On one
hand, I'd like to see a set of filtering streambuf's standardized.  But
on the other, I don't know which ones.

(The custom streambuf that I use the most is one that takes a list of
file names.  If the list is empty, it grabs the streambuf from cin, and
uses it, otherwise, it it creates a filebuf for each name in the list,
and on end of file, goes on to the next.  Not quite the same as the ones
you were requesting, and I'm still just talking about a command line
interface.)

|>  Another thing that I've always found clumsy was the use of
|>  manipulators to set field widths and output bases. I've always
|>  preferred something like:
|>
|>   cout << DecN(v, c);
|>
|>  which would output value v in decimal right-justified in c
|>  columns, or
|>
|>   cout << Hex8(x) << " " << Hex2(y) << '\n';
|>
|>  which would output an 8-digit and a 2-digit hex number. The code
|>  is more compact and readable, in my view.

This is just a small part of a global problem.  I use a formatter class,
with a printf like format string, for this sort of stuff.  It has a
feature that I consider essential: it supports the X/Open positional
argument extension to printf.

--
James Kanze    +33 (0)1 39 23 84 71    mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
        I'm looking for a job -- Je recherche du travail
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1997/11/11
Raw View
J. Kanze wrote:
>
> "Paul D. DeRocco" <pderocco@ix.netcom.com> writes:
>
> |>  When I say I'd like line wrap, I mean that I want words that
> |>  don't fit on a line to be bumped down to the next line. (An
> |>  indentation for wrapped lines is also a useful parameter.) That
> |>  involves considerably more code than the above, including a
> |>  buffer to accumulate a word into.
>
> Fine.  In this case, of course, the streambuf will be significantly more
> complicated.  Perhaps it should handle hyphenation, too, while it is at
> it.  And variable width fonts would seem a necessity.  Maybe we should
> require a streambuf which does full LaTeX formatting:-).
>
> I know this isn't what you are asking for.  But the problem is, the cut
> off for each person will be different, so what do you standardize?
>

\begin{:-)}
Well, if we are going so far, why not going further?
We could make a streambuf that automatically disassembles. That is, you
put the byte stream in, and get the asm code out.
In addition, we could have streambufs for input, which do automatic
preprocessing. That would be really useful for compiler writers.
\end{:-)}

OTOH, some standard functions for variable size fonts would really be
nice.
Say, the following definitions:

__font
  implementation defined type, intended to describe a font.

__stdfont
  implementation defined constant of type __font.

int textwidth(const char* const strg, __font fnt=__stdfont);
  gives the width of the character string strg in font fnt, in
implementation
  defined units.

size_t truncpos(const char* const strg, int width, __font
fnt=__stdfont);
  gives the first character which will exceed width in font __fnt.
  If all characters fit into width, it returns strlen(strg);

A simple conforming implementation would f.ex. be:

  typedef int __font;
  __font const __stdfont=0;
  int textwidth(const char* const strg, __font fnt=__stdfont)
    { return strlen(strg); }
  size_t truncpos(const char* const strg, int width, __font
fnt=__stdfont)
    { size_t max=strlen(strg); return (width>max)? max : width; }

The unit used here is the character, of course. This definition would be
useful for fixed fonts only; but for some implementations it's suitable,
and being useful is a quality of implementation issue anyway.

[...]
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1997/11/07
Raw View
J. Kanze wrote:
>
> So what should these streambuf's do?  It's trivial (well almost, once
> you understand the undocumented subtilities of streambuf) to implement
> for each specific case.  I even have a template which encapsulates all
> of the boilerplating -- I can typically knock up a new filtering
> streambuf to do things like this in about 10-15 lines of code.
>
> As an example, the code for a line wrapping inserter:
>
>         class LineWrappingInserter
>         {
>         public:
>                 LineWrappingInserter( int pos = 80 )
>                         :   myLineLength( pos )
>                         ,   myColumnNo( 0 )
>                 {
>                 }
>                 int                 insert( streambuf* sb , int ch )
>                 {
>                         int                 result( 0 ) ;
>                         if ( ch == '\n' )
>                                 myColumnNo = 0 ;
>                         else
>                         {
>                                 if ( myColumnNo >= myLineLength )
>                                         result = insert( sb , '\n' ) ;
>                                 ++ myColumnNo ;
>                         }
>                         if ( result != EOF )
>                                 result = sb->sputc( ch ) ;
>                         return result ;
>                 }
>                 void                finalize( streambuf* sb )
>                 {
>                         if ( myColumnNo != 0 )
>                                 sb->sputc( '\n' ) ;
>                 }
>         private:
>                 int                 myLineLength ;
>                 int                 myColumnNo ;
>         } ;
>
> and it's use:
>
>     FilteringOstream< LineWrappingInserter >
>                         output( cout.rdbuf() ) ;
>     while ( cin.peek() != EOF )
>         output.put( (char)cin.get() ) ;
>
> It took about a quarter of an hour to write and test -- is something
> this simple and this specialized really appropriate for standardization?

When I say I'd like line wrap, I mean that I want words that
don't fit on a line to be bumped down to the next line. (An
indentation for wrapped lines is also a useful parameter.) That
involves considerably more code than the above, including a
buffer to accumulate a word into.

Perhaps people who write Windows code rarely need this, because
they deal with proportionally space fonts. I write lots of
command line utilities that run in text screens that use fixed
space fonts, so column counting, tab expansion, and line wrap
based on simple character counts are all very useful to me.

Another thing that I've always found clumsy was the use of
manipulators to set field widths and output bases. I've always
preferred something like:

 cout << DecN(v, c);

which would output value v in decimal right-justified in c
columns, or

 cout << Hex8(x) << " " << Hex2(y) << '\n';

which would output an 8-digit and a 2-digit hex number. The code
is more compact and readable, in my view.

--

Ciao,
Paul
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]