Daniel Jacobowitz wrote: > Could you tell me a little bit about unistdio
It's a set of *printf functions for Unicode strings, part of a Unicode string library that I presented here: [1]. Its include file unistdio.h is appended. > and how it interacts with (A) the printf we already have, The interface is very similar to the C99 / POSIX printf; the differences are - the %U directive which accepts a Unicode string argument, even when producing a plain 'char *' string or a Unicode string of different width, - there are also variants which take an ASCII 'char *' format string and produce UTF-16 or UTF-32 results. The code is similar to vasnprintf.h but with different sets of #ifdefs. If both implementations were merged, it would become too much of an #if spaghetti, IMO. > and (B) the printf I spent all weekend working on merging? So far, it's unrelated. snprintfv lets me define my own handler for %U or similar, but I don't see how to produce UTF-16 or UTF-32 strings with snprintfv, and how to take UTF-16 or UTF-32 strings as arguments without dirty casting. > I'm worried that gnulib is developing too > many different ways to do almost the same thing, all slightly different. Well, I'm not particularly happy about 'canonicalize' vs. 'canonicalize-lgpl' or 'xreadlink' vs. 'xreadlink_with_size' either. But the positive side is that we dare to create a different function if it's useful and needed (even if a similar function already exists). And that we still do a good amount of code sharing (look for example how many modules use m4/longdouble.m4 or xstrtol.c). Different approaches must compete sometimes; there is for example no unique optimal way to implement a hash table, therefore it's normal that we have more than one hash table code in gnulib. Let people choose what they need. Bruno [1] http://lists.gnu.org/archive/html/bug-gnulib/2007-01/msg00079.html =============================== unistdio.h =================================== /* Elementary Unicode string functions. Copyright (C) 2002, 2005-2007 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _UNISTDIO_H #define _UNISTDIO_H #include "unitypes.h" /* Get size_t. */ #include <stddef.h> /* Get FILE. */ #include <stdio.h> /* Get va_list. */ #include <stdarg.h> #ifdef __cplusplus extern "C" { #endif /* These work like the printf function family. In the format string: The format directive 'U' takes an UTF-8 string (const uint8_t *). The format directive 'lU' takes an UTF-16 string (const uint16_t *). The format directive 'llU' takes an UTF-32 string (const uint32_t *). The prefix (ulc_, u8_, u16_, u16_) indicates the type of the resulting string. The prefix 'ulc' stands for "locale encoded". An infix 'v' indicates that a va_list is passed instead of multiple arguments. The functions *sprintf have a 'buf' argument that is assumed to be large enough. (DANGEROUS! Overflowing the buffer will crash the program.) The functions *snprintf have a 'buf' argument that is assumed to be 'size' units large. (DANGEROUS! The resulting string might be truncated in the middle of a multibyte character.) The functions *asprintf have a 'resultp' argument. The result will be freshly allocated and stored in *resultp. The functions *asnprintf have a (resultbuf, lengthp) argument pair. If resultbuf is not NULL and the result fits into *lengthp units, it is put in resultbuf, and resultbuf is returned. Otherwise, a freshly allocated string is returned. In both cases, *lengthp is set to the length (number of units) of the returned string. In case of error, NULL is returned and errno is set. */ /* ASCII format string, result in locale dependent encoded 'char *'. */ extern int ulc_sprintf (char *buf, const char *format, ...); extern int ulc_snprintf (char *buf, size_t size, const char *format, ...); extern int ulc_asprintf (char **resultp, const char *format, ...); extern char * ulc_asnprintf (char *resultbuf, size_t *lengthp, const char *format, ...); extern int ulc_vsprintf (char *buf, const char *format, va_list ap); extern int ulc_vsnprintf (char *buf, size_t size, const char *format, va_list ap); extern int ulc_vasprintf (char **resultp, const char *format, va_list ap); extern char * ulc_vasnprintf (char *resultbuf, size_t *lengthp, const char *format, va_list ap); /* ASCII format string, result in UTF-8 format. */ extern int u8_sprintf (uint8_t *buf, const char *format, ...); extern int u8_snprintf (uint8_t *buf, size_t size, const char *format, ...); extern int u8_asprintf (uint8_t **resultp, const char *format, ...); extern uint8_t * u8_asnprintf (uint8_t *resultbuf, size_t *lengthp, const char *format, ...); extern int u8_vsprintf (uint8_t *buf, const char *format, va_list ap); extern int u8_vsnprintf (uint8_t *buf, size_t size, const char *format, va_list ap); extern int u8_vasprintf (uint8_t **resultp, const char *format, va_list ap); extern uint8_t * u8_vasnprintf (uint8_t *resultbuf, size_t *lengthp, const char *format, va_list ap); /* UTF-8 format string, result in UTF-8 format. */ extern int u8_u8_sprintf (uint8_t *buf, const uint8_t *format, ...); extern int u8_u8_snprintf (uint8_t *buf, size_t size, const uint8_t *format, ...); extern int u8_u8_asprintf (uint8_t **resultp, const uint8_t *format, ...); extern uint8_t * u8_u8_asnprintf (uint8_t *resultbuf, size_t *lengthp, const uint8_t *format, ...); extern int u8_u8_vsprintf (uint8_t *buf, const uint8_t *format, va_list ap); extern int u8_u8_vsnprintf (uint8_t *buf, size_t size, const uint8_t *format, va_list ap); extern int u8_u8_vasprintf (uint8_t **resultp, const uint8_t *format, va_list ap); extern uint8_t * u8_u8_vasnprintf (uint8_t *resultbuf, size_t *lengthp, const uint8_t *format, va_list ap); /* ASCII format string, result in UTF-16 format. */ extern int u16_sprintf (uint16_t *buf, const char *format, ...); extern int u16_snprintf (uint16_t *buf, size_t size, const char *format, ...); extern int u16_asprintf (uint16_t **resultp, const char *format, ...); extern uint16_t * u16_asnprintf (uint16_t *resultbuf, size_t *lengthp, const char *format, ...); extern int u16_vsprintf (uint16_t *buf, const char *format, va_list ap); extern int u16_vsnprintf (uint16_t *buf, size_t size, const char *format, va_list ap); extern int u16_vasprintf (uint16_t **resultp, const char *format, va_list ap); extern uint16_t * u16_vasnprintf (uint16_t *resultbuf, size_t *lengthp, const char *format, va_list ap); /* UTF-16 format string, result in UTF-16 format. */ extern int u16_u16_sprintf (uint16_t *buf, const uint16_t *format, ...); extern int u16_u16_snprintf (uint16_t *buf, size_t size, const uint16_t *format, ...); extern int u16_u16_asprintf (uint16_t **resultp, const uint16_t *format, ...); extern uint16_t * u16_u16_asnprintf (uint16_t *resultbuf, size_t *lengthp, const uint16_t *format, ...); extern int u16_u16_vsprintf (uint16_t *buf, const uint16_t *format, va_list ap); extern int u16_u16_vsnprintf (uint16_t *buf, size_t size, const uint16_t *format, va_list ap); extern int u16_u16_vasprintf (uint16_t **resultp, const uint16_t *format, va_list ap); extern uint16_t * u16_u16_vasnprintf (uint16_t *resultbuf, size_t *lengthp, const uint16_t *format, va_list ap); /* ASCII format string, result in UTF-32 format. */ extern int u32_sprintf (uint32_t *buf, const char *format, ...); extern int u32_snprintf (uint32_t *buf, size_t size, const char *format, ...); extern int u32_asprintf (uint32_t **resultp, const char *format, ...); extern uint32_t * u32_asnprintf (uint32_t *resultbuf, size_t *lengthp, const char *format, ...); extern int u32_vsprintf (uint32_t *buf, const char *format, va_list ap); extern int u32_vsnprintf (uint32_t *buf, size_t size, const char *format, va_list ap); extern int u32_vasprintf (uint32_t **resultp, const char *format, va_list ap); extern uint32_t * u32_vasnprintf (uint32_t *resultbuf, size_t *lengthp, const char *format, va_list ap); /* UTF-32 format string, result in UTF-32 format. */ extern int u32_u32_sprintf (uint32_t *buf, const uint32_t *format, ...); extern int u32_u32_snprintf (uint32_t *buf, size_t size, const uint32_t *format, ...); extern int u32_u32_asprintf (uint32_t **resultp, const uint32_t *format, ...); extern uint32_t * u32_u32_asnprintf (uint32_t *resultbuf, size_t *lengthp, const uint32_t *format, ...); extern int u32_u32_vsprintf (uint32_t *buf, const uint32_t *format, va_list ap); extern int u32_u32_vsnprintf (uint32_t *buf, size_t size, const uint32_t *format, va_list ap); extern int u32_u32_vasprintf (uint32_t **resultp, const uint32_t *format, va_list ap); extern uint32_t * u32_u32_vasnprintf (uint32_t *resultbuf, size_t *lengthp, const uint32_t *format, va_list ap); /* ASCII format string, output to FILE in locale dependent encoding. */ extern int ulc_fprintf (FILE *stream, const char *format, ...); extern int ulc_vfprintf (FILE *stream, const char *format, va_list ap); #ifdef __cplusplus } #endif #endif /* _UNISTDIO_H */