Re: ICU4C proposal: Formalizing the ustdio format specifiers

"Mark Davis" <[email protected]>
Newsgroups gmane.comp.lib.icu.general
Message-ID <007201c3470e$28092cb0$7900a8c0@DAVIS1>
> - if the user specifies 'l' with d, i, or u, then do integral
promotion to
>   an int32_t, int32_t, or uint32_t.
> - if the user specifies 'll' with d, i, or u, then do integrat
promotion to
>   an int64_t, int64_t, or uint64_t.

We can't do this in scanf. It's got to be exactly the right type.

Mark
__________________________________
http://www.macchiato.com
►  “Eppur si muove” ◄

----- Original Message ----- 
From: "Robert Buck" <[email protected]>
To: "George Rhoten" <[email protected]>
Cc: <[email protected]>
Sent: Thursday, July 10, 2003 11:03
Subject: RE: ICU4C proposal: Formalizing the ustdio format specifiers


> But...
>
> > -----Original Message-----
> > From: George Rhoten [mailto:[email protected]]
> > Sent: Thursday, July 10, 2003 1:01 PM
> > To: Robert Buck
> > Cc: [email protected]
> > Subject: RE: ICU4C proposal: Formalizing the ustdio format
specifiers
> >
> >
> > 1) Sadly a long isn't always 4 bytes.  It can also be 8 bytes on a
few
> > other platforms (Alpha is one of them).  This is why I'm not
> > using long or
> > long long in the format specification, and I'm only using int*_t
> > types.  I
> > have no plans to support ll or I64.  The reason for this decision
was to
> > follow a similar philosophy of Java where types always have the
same size
> > on all platforms.
>
> The Java philosophy holds little weight to C/C++ programmers, and
again,
> we are talking about a C/C++ based product. Consistency with the C
or C++
> standard bears far more weight with C/C++ programmers. What you are
> proposing
> is essentially to dispense with an official ISO standard in favor of
a non-
> standard (Sun).
>
> Now to say that you prefer to use sized types, as specified by C99,
is
> entirely reasonable. But the C99 _library_ spec is not at all
expressed in
> terms of the sized types. Many places it indicates the language
types to be
> used,
> but not sized types.
>
> How the language types map into sized types is a matter of platform
or
> compiler convention - which is basically what your platform specific
> header files do for those platforms that don't provide stdint.h or
> inttypes.h.
>
> I hardly think it would be too hard to determine what the major
compiler
> mfr's do on each platform with respect to these types and format
specifiers
> (how wide types are, and what format specifiers they map into ),
then
> write the code in such a manner that it emulates what C/C++
developers
> expect. In other words:
>
> - if the user specifies 'l' with d, i, or u, then do integral
promotion to
>   an int32_t, int32_t, or uint32_t.
> - if the user specifies 'll' with d, i, or u, then do integrat
promotion to
>   an int64_t, int64_t, or uint64_t.
> - if the user specifies 'h' with d, i, or u, then cast to a int16_t,
> int16_t, or
>   an uint16_t.
> - if the user specifies 'hh' with d, i, or u, then cast to a int8_t,
int8_t,
> or
>   an uint8_t.
>
> > I figure it would be much easier to say that h means short format,
and l
> > means long format as opposed to 'h means short int and l means
long int.'
>
> That is not at all what the C99 spec says. So why should we
> want to befuddle developers using the ICU library?
> The spec clearly states, and let me quote:
>
> "The length modifiers and their meanings are:
>
> "'hh' Specifies that a following d, i, o, u, x, or X conversion
specifier
> applies to a
> 'signed char' or 'unsigned char' argument (the argument will have
> been promoted according to the integer promotions, but its value
shall be
> converted to 'signed char' or 'unsigned char' before printing); or
that
> a following n conversion specifier applies to a pointer to a signed
char
> argument.
>
> "'h' Specifies that a following d, i, o, u, x, or X conversion
specifier
> applies to a
> 'short int' or 'unsigned short int' argument (the argument will
> have been promoted according to the integer promotions, but its
value shall
> be converted to 'short int' or 'unsigned short int' before
printing);
> or that a following n conversion specifier applies to a pointer to a
short
> int argument."
>
> The first paragraph is paraphrased:  'hh' implies susequent argument
is by
> convention an 8-bit integer, either int8_t or uint8_t.
>
> The second paragraph is paraphrased:  'h' implies susequent argument
is by
> convention an 16-bit integer, either int16_t or uint16_t.
>
> One may deduce/guess then that with the lack of a h or hh optional
modifier,
> with a %i, %d, or %u, that the subsequent argument is a int32_t or
uint32_t.
> Yes, this last point it's not spelled out in huge bold print, but is
> implied.
>
> So as you see, they do not say it "means short format", they clearly
state
> specific types, as in "unsigned short int", or unsigned char".
>
> So what you are proposing is clearly way out on a limb, and
non-standards
> conformant. At least with respect to 'h'.
>
> The 'l' (ell) issue is a bit more vague in the spec, because there
is no
> clear description of what the difference is between 'long int' and
'int' is.
> You get the point. So, in these cases the best you can do for ICU
users is
> to follow platform convention - not terribly difficult to do in the
> formatter
> code. The chart I previously provided indicates some reasonable
defaults.
>
> > If you don't want l (ell) to mean int64_t, I guess I'll hold off
on
> > supporting 64-bit types in ustdio.  This topic can be brought up
again at
> > a later date.
>
> No, I'd like to see both l (ell) and ll (ell-ell) put in. It's not
too much
> more work to do both.
>
> > 2) I'm not using ints.  %S and %C on several platforms means that
wchar_t
> > should be used.  On Windows, this is 16-bits, but %S can also mean
that
> > char * is used instead depending on the API used.  On AIX, it can
> > be 16 or
> > 32-bits depending on the architecture.  On Linux, it's usually
32-bits,
> > but it can also be 16-bits at times.  wchar_t sometimes means
> > that Unicode
> > is used, but sometimes it isn't.  I'm trying to stay away from
using int,
> > long or wchar_t types.  I'd really rather prefer to implement it
> > the way I
> > originally suggested.
>
> I think it is reasonable to say that with most current operating
systems,
> or even most any produced in the past ten years, that an int is
32-bits.
> To base your code upon [u]int32_t for what 'C' regards is a
reasonable
> choice.
> Again, go back to the discussion regarding h vs hh, and l vs ll. The
basis
> of 'h' or 'hh' is an int, which on most reasonable OSs is 32-bits.
Again,
> it's all a matter of being conformant to the letter, or intent, of
the
> standard.
>
> I really couldn't care less about wchar_t, because there are issues
> that surround its use. But my basic objection was the use of _both_
'l'
> and 'h'. There is no precedent to use 'h' with a basis of 'short
int',
> only with an int.
>
> > 3) I was planning on explicitly not supporting %ls and %lc for
> > now. Markus
> > had a great aversion to adding wchar_t support to ustdio right now
> > (http://oss.software.ibm.com/icu/docs/papers/unicode_wchar_t.html)
> > , so I'm
> > reserving it for possible future implementation when someone has
the need
> > or time to implement wchar_t.  It's easier to add it in the
future, but
> > it's very difficult to remove it.
>
> Okay.
>
> >
> > 4) I'll let you submit an RFE on it.  I don't want to formalize
any
> > callbacks yet, but I do see an advantage.  My main goal right now
is to
> > make a ustdio that works.  Many of the callbacks will be changing
> > internally.  Special features like this are beyond what I can do
for 2.8.
>
> We use it in the message formatting and localization facilities.
> It is quite useful.
>
> Bob Buck
>
> >
> > George Rhoten
> > IBM Globalization Center of Competency/ICU  San Jose, CA, USA
> >
>
> > "Robert Buck" <[email protected]>
> > 07/10/2003 07:22 AM
> >         To:     George Rhoten/San Jose/IBM@IBMUS,
> > <[email protected]>
> >         cc:
> >         Subject:        RE: ICU4C proposal: Formalizing the
> > ustdio format specifiers
> > Great. I look forward to the changes. Esp support for %ld.
> >
> > A couple questions though...
> >
> > ##################################################################
> > ##########
> > ##
> > 1.
> >
> > >From what I am reading in the C99 spec before me (Ch 7.19.6.1
article 4
> > and
> > Ch 7.19.6.2 article 11):
> >
> > , the conversion specifier must be present
> > , the length modifer is optional
> > , behavior of a specification using a length modifier by itself is
> > undefined
> >
> > Does your spec suggest that '%l' is equivalent to '%ld' ? If so,
please
> > no.
> >
> > Also, the spec says...
> >
> > ", l (ell) Specifies that a following d, i, o, u, x, or X
conversion
> > specifier
> > applies to a long int or unsigned long int argument; that a
following n
> > conversion specifier applies to a pointer to a long int argument;
that a
> > following c conversion specifier applies to a wint_t argument;
that a
> > following s conversion specifier applies to a pointer to a wchar_t
> > argument; or has no effect on a following a, A, e, E, f, F, g, or
G
> > conversion
> > specifier.
> >
> > ", ll (ell-ell) Specifies that a following d, i, o, u, x, or X
conversion
> > specifier applies to a long long int or unsigned long long int
argument;
> > or that a following n conversion specifier applies to a pointer to
a long
> > long int
> > argument."
> >
> > It would seem to me that, apart from those outlier compilers that
do not
> > support 'long int' or 'long long int', that the 'l' and 'll'
should behave
> > as though the modifer indicates that the subsequent argument is at
most
> > the
> > platform width of 'long int' for 'l', and the platform width of
'long long
> > int'
> > for 'll'. Taking a poll on five OSs, this means these would map
to:
> >
> > type / sizeof   windows-ia32-vc7  linux-ia32  solaris-64  macosx
hpux-11
>
> --------------------------------------------------------------------
------
> > 'long long int'   unsupported          8         8           8
8
> > 'long int'             4               4         4           4
4
> >
> > For win32 it would be reasonable to say that 'll' regards 64-bit
types.
> >
> > I think it would be reasonable to say from evidence that %ld is
used for
> > int32_t,
> > and %lld is used for int64_t. Similarly for corresponding unsigned
> > quantities as well,
> > %lu and %llu. In fact, if you use the '%ld' format on hpux for a
64 bit
> > type,
> > and a value of INT64_MAX, you get an error, which seems to further
support
> > my
> > argument.
> >
> > printf("sizeof long int: %lld\n", INT64_MAX); // yields
> > 9223372036854775807
> > printf("sizeof long int: %ld\n", INT64_MAX); // yields 1001; an
error of
> > course
> >
> > Other platforms that support the spec for 'll' will yield similar
errors.
> >
> > So in summary, %ld is _not_ for int64_t, nor is %lu for uint64_t
according
> > to the spec,
> > or according to practice. Please do not introduce this error to
the ICU
> > api.
> >
> > ##################################################################
> > ##########
> > ##
> > 2.
> >
> > Also, regarding the 'h' modifier and its use with regards to
unicode
> > strings,
> > another alternative would be:
> >
> > > %S  UChar32 *  Null terminated UTF-16 string
> > > %hS UChar *    Null terminated UTF-16 string
> > > %hhS char *    Null terminated UTF-32 string
> >
> > and,
> >
> > > %C UChar32     32-bit Unicode code unit
> > > %hC  UChar     16-bit Unicode code unit
> > > %hhC char      8-bit Unicode code unit
> >
> > The point is that the conversion type for an 'h' modifier is
presumed to
> > be
> > promoted to sizeof int. The int type is more naturally associated
to
> > UChar32 than UChar16. So one could argue that the above is more
> > consistent with the intent of the C99 Spec on the basis that 'h'
is
> > meant to demote a type from an int to a type of short, and 'hh' is
meant
> > to demote an int to a char. Your use of 'h' is inconsistent with
the
> > spec as it demotes a short to a char. See Ch 7.24.2.1 article 7.
> >
> > ##################################################################
> > ##########
> > ##
> > 3.
> >
> > > %ls N/A         (Unimplemented) Reserved for future
implementation
> >
> > Actually %ls is already taken by the C99 Spec, and refers to a
wchar_t *.
> > So please consider dropping this from your spec, but support it
according
> > to platform/compiler conventions, and the C99 spec.
> >
> > > %lc N/A         (Unimplemented) Reserved for future
implementation
> >
> > And in the spec this refers to a wint_t. Same as above.
> >
> > ##################################################################
> > ##########
> > ##
> > 4.
> >
> > A nifty thing we use regularly in MATLAB is function holes. It
essentially
> > does a callback to a function that is allowed to put N characters
into
> > the output buffer. For us it is represented as a naked %U, so
leaving out
> > lots of details:
> >
> > switch (conversion specifier hole type) {
> > case FUNCTION_HOLE_TYPE:
> > {
> > va_list   hole_ap = msg->hole_infos[holeIdx].hole.hole_ap;
> > fn_fmtfcn fmtfcn  = va_arg(hole_ap, fn_fmtfcn);
> > num_chars_written = (fmtfcn)(putsn, dest_buf_or_file_ptr,
&hole_ap);
> > break;
> > }
> > }
> >
> > typedef int (*fn_fmtfcn)(  /* returns the number of chars putsn'd
after
> > processing*/
> > fn_putsn putsn,
> > void *x,             /* destination info, e.g., FILE *, or &buffer
*/
> > va_list *ap);        /* var args list to custom format specifier,
on
> > return
> > this is advanced past the custom format varargs */
> >
> > Would it be possible to augment the icu api to support this sort
of
> > callback?
> >
> > -Bob
> >
> > > -----Original Message-----
> > > From: [email protected]
> > > [mailto:[email protected]]On Behalf Of
George
> > > Rhoten
> > > Sent: Wednesday, July 09, 2003 7:05 PM
> > > To: [email protected]
> > > Subject: ICU4C proposal: Formalizing the ustdio format
specifiers
> > >
> > >
> > > Deadline for comments: July 16, 2003
> > >
> > >
> > > Introduction
> > >
> > > For ICU 2.8 we are making ustdio a fully supported library.
Basically,
> > > this means that I will be fixing many broken things in the
ustdio
> > > library.
> > >  Part of this fixing process is to formalize how the format
> > specification
> > > string works for fscanf, fprintf and related functions.
> > >
> > > As a reminder, the ustdio library has been marked as draft for a
while,
> > > which means that the API may change at any time.  We have also
> > > stated that
> > > ustdio is a broken unsupported library for a long time.  I'd
like to
> > make
> > > the ustdio library more compatible with the ANSI C stdio format
> > > specification.  Backwards compatibility with the old ustdio is
not a
> > goal
> > > of this proposal, since that would involve keeping many bugs
from the
> > old
> > > ustdio around for eternity.
> > >
> > > This is only a partial proposal.  A full proposal would be many
pages
> > > long, and most people wouldn't read it.  So I'm only sending out
> > > a "small"
> > > proposal for part of my ustdio work at this time so that it is
easier to
> > > read (hopefully).  More proposals will appear later on, like on
how some
> > > of the function APIs will look.
> > >
> > >
> > > Actual Proposal
> > >
> > > Here are the format specifications that I plan to use in the new
> > > supported
> > > ustdio library.  These formats apply to u_fscanf, u_fprintf,
u_sscanf,
> > > u_sprintf and all related functions in ustdio.h.
> > >
> > > printf
> > > fmt type        Comment
> > > %E  double      Scientific with an uppercase exponent
> > > %e  double      Scientific with a lowercase exponent
> > > %G  double      Use %E or %f for best format
> > > %g  double      Use %e or %f for best format
> > > %f  double      Simple floating point without the exponent
> > > %X  int32_t     ustdio special uppercase hex radix formatting
> > > %x  int32_t     ustdio special lowercase hex radix formatting
> > > %d  int32_t     Decimal format
> > > %i  int32_t     Same as %d
> > > %n  int32_t     count (write the number of chars written)
> > > %o  int32_t     octal ustdio special octal radix formatting
> > > %u  uint32_t    Decimal format
> > > %p  void *      Prints the pointer value
> > > %s  char *      Use default converter or specified converter
from fopen
> > > %hs char *      Use invariant converter
> > > %ls N/A         (Unimplemented) Reserved for future
implementation
> > > %c  char        Use default converter or specified converter
from fopen
> > > %hc char        Use invariant converter
> > > %lc N/A         (Unimplemented) Reserved for future
implementation
> > > %S  UChar *     Null terminated UTF-16 string
> > > %hS char *      Null terminated UTF-8 string
> > > %lS UChar32 *   Null terminated UTF-32 string
> > > %C  UChar       16-bit Unicode code unit
> > > %hC char        8-bit Unicode code unit
> > > %lC UChar32     32-bit Unicode code unit
> > > %%  N/A         Show a percent sign
> > >
> > > scanf differences from printf
> > > %[] UChar *     Scanset needs to be replaced with ICU
UnicodeSet.
> > >                 Doesn't contain s, S or any other string format.
> > >
> > > Format modifiers
> > > %l    int64_t   long format for %d, %i, %o, %x (usually this
means long
> > > int)
> > > %h    int16_t   short format for %d, %i, %o, %x (usually this
means
> > short
> > > int)
> > > %l    uint64_t  long format for %u (usually this means long int)
> > > %h    uint16_t  short format for %u (usually this means short
int)
> > > %-    N/A       Left justify
> > > %+    N/A       Always show the plus or minus sign. Needs data
for plus
> > > sign.
> > > %     N/A       Instead of a "+" output a blank character for
positive
> > > numbers.
> > > %#    N/A       Precede octal value with 0, hex with 0x and show
the
> > > decimal point for floats.
> > > %num  N/A       Width of input/output. num is an actual number
from 0 to
> > > some large number.
> > > %.num N/A       Significant digits precision. num is an actual
> > > number from
> > > 0
> > >                 to some large number. Currently can only specify
> > precision
> > >                 before or after decimal, and not total
precision.
> > >
> > > printf modifier
> > > %*  int32_t     Next argument after this one specifies the width
(need
> > to
> > > implement)
> > >
> > > scanf modifier
> > > %*  N/A         This field is scanned, but not stored (need to
> > implement)
> > >
> > > Special extensions reserved for future consideration
> > > %P  double      Percent format
> > > %V  double      Spellout format
> > > %b  char *      HP-UX and glibc extension which allows you to
unescape a
> > > string
> > > %B  UChar *     Similar to %b
> > > % $ N/A         positional formatting modifier like in
MessageFormat
> > from
> > > the "Single Unix Specification".
> > >
> > > Formats removed due to other formats or functions.
> > > %T  UDate       Time. Replaced by strftime/strptime.
> > > %D  UDate       Date. Replaced by strftime/strptime.
> > > %K  UChar       Source or target is UChar. Replaced by %C.
> > > %U  UChar *     Source or target is UChar *. Replaced by %S.
> > > %M  double      Currency format. Replaced by strfmon. strpmon
may be
> > > implemented in the future.
> > >
> > >
> > >
> > > Other related changes
> > >
> > > Functions removed
> > > u_getcx()       %b will replace this function in the future
> > >
> > > The char * format specification will now be converted with
> > > u_charsToUChars
> > > instead of the default converter.  If you want to display
non-ASCII
> > > characters, you need to use the functions that use a const UChar
*
> > format
> > > argument.  This is being done because:
> > >
> > > 1) It's much faster
> > > 2) The format specification argument is usually a static char *,
but the
> > > default converter may convert the string differently depending
on the
> > > platform ICU is being run on.  This is generally bad, and that's
why the
> > > UChar * format argument should be used for internationalized
text
> > instead
> > > of the API that takes a char * formatting argument.  The %s
argument
> > will
> > > still use the default converter since the source of the string
is much
> > > more likely to come from an outside source.
> > >
> > >
> > >
> > > Thank you for taking time to read this proposal.
> > >
> > > George Rhoten
> > > IBM Globalization Center of Competency/ICU  San Jose, CA, USA
> > > _______________________________________________
> > > icu mailing list
> > > [email protected]
> > >
http://oss.software.ibm.com/developerworks/oss/mailman/listinfo/icu
> >
> >
>
> _______________________________________________
> icu mailing list
> [email protected]
> http://oss.software.ibm.com/developerworks/oss/mailman/listinfo/icu
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.