Home | History | Annotate | Download | only in intl
      1 /* Formatted output to strings, using POSIX/XSI format strings with positions.
      2    Copyright (C) 2003 Free Software Foundation, Inc.
      3    Written by Bruno Haible <bruno (at) clisp.org>, 2003.
      4 
      5    This program is free software; you can redistribute it and/or modify it
      6    under the terms of the GNU Library General Public License as published
      7    by the Free Software Foundation; either version 2, or (at your option)
      8    any later version.
      9 
     10    This program is distributed in the hope that it will be useful,
     11    but WITHOUT ANY WARRANTY; without even the implied warranty of
     12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13    Library General Public License for more details.
     14 
     15    You should have received a copy of the GNU Library General Public
     16    License along with this program; if not, write to the Free Software
     17    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
     18    USA.  */
     19 
     20 #ifdef HAVE_CONFIG_H
     21 # include <config.h>
     22 #endif
     23 
     24 #ifdef __GNUC__
     25 # define alloca __builtin_alloca
     26 # define HAVE_ALLOCA 1
     27 #else
     28 # ifdef _MSC_VER
     29 #  include <malloc.h>
     30 #  define alloca _alloca
     31 # else
     32 #  if defined HAVE_ALLOCA_H || defined _LIBC
     33 #   include <alloca.h>
     34 #  else
     35 #   ifdef _AIX
     36  #pragma alloca
     37 #   else
     38 #    ifndef alloca
     39 char *alloca ();
     40 #    endif
     41 #   endif
     42 #  endif
     43 # endif
     44 #endif
     45 
     46 #include <stdio.h>
     47 
     48 #if !HAVE_POSIX_PRINTF
     49 
     50 #include <stdlib.h>
     51 #include <string.h>
     52 
     53 /* When building a DLL, we must export some functions.  Note that because
     54    the functions are only defined for binary backward compatibility, we
     55    don't need to use __declspec(dllimport) in any case.  */
     56 #if defined _MSC_VER && BUILDING_DLL
     57 # define DLL_EXPORTED __declspec(dllexport)
     58 #else
     59 # define DLL_EXPORTED
     60 #endif
     61 
     62 #define STATIC static
     63 
     64 /* Define auxiliary functions declared in "printf-args.h".  */
     65 #include "printf-args.c"
     66 
     67 /* Define auxiliary functions declared in "printf-parse.h".  */
     68 #include "printf-parse.c"
     69 
     70 /* Define functions declared in "vasnprintf.h".  */
     71 #define vasnprintf libintl_vasnprintf
     72 #include "vasnprintf.c"
     73 #if 0 /* not needed */
     74 #define asnprintf libintl_asnprintf
     75 #include "asnprintf.c"
     76 #endif
     77 
     78 DLL_EXPORTED
     79 int
     80 libintl_vfprintf (FILE *stream, const char *format, va_list args)
     81 {
     82   if (strchr (format, '$') == NULL)
     83     return vfprintf (stream, format, args);
     84   else
     85     {
     86       size_t length;
     87       char *result = libintl_vasnprintf (NULL, &length, format, args);
     88       int retval = -1;
     89       if (result != NULL)
     90 	{
     91 	  if (fwrite (result, 1, length, stream) == length)
     92 	    retval = length;
     93 	  free (result);
     94 	}
     95       return retval;
     96     }
     97 }
     98 
     99 DLL_EXPORTED
    100 int
    101 libintl_fprintf (FILE *stream, const char *format, ...)
    102 {
    103   va_list args;
    104   int retval;
    105 
    106   va_start (args, format);
    107   retval = libintl_vfprintf (stream, format, args);
    108   va_end (args);
    109   return retval;
    110 }
    111 
    112 DLL_EXPORTED
    113 int
    114 libintl_vprintf (const char *format, va_list args)
    115 {
    116   return libintl_vfprintf (stdout, format, args);
    117 }
    118 
    119 DLL_EXPORTED
    120 int
    121 libintl_printf (const char *format, ...)
    122 {
    123   va_list args;
    124   int retval;
    125 
    126   va_start (args, format);
    127   retval = libintl_vprintf (format, args);
    128   va_end (args);
    129   return retval;
    130 }
    131 
    132 DLL_EXPORTED
    133 int
    134 libintl_vsprintf (char *resultbuf, const char *format, va_list args)
    135 {
    136   if (strchr (format, '$') == NULL)
    137     return vsprintf (resultbuf, format, args);
    138   else
    139     {
    140       size_t length = (size_t) ~0 / (4 * sizeof (char));
    141       char *result = libintl_vasnprintf (resultbuf, &length, format, args);
    142       if (result != resultbuf)
    143 	{
    144 	  free (result);
    145 	  return -1;
    146 	}
    147       else
    148 	return length;
    149     }
    150 }
    151 
    152 DLL_EXPORTED
    153 int
    154 libintl_sprintf (char *resultbuf, const char *format, ...)
    155 {
    156   va_list args;
    157   int retval;
    158 
    159   va_start (args, format);
    160   retval = libintl_vsprintf (resultbuf, format, args);
    161   va_end (args);
    162   return retval;
    163 }
    164 
    165 #if HAVE_SNPRINTF
    166 
    167 # if HAVE_DECL__SNPRINTF
    168    /* Windows.  */
    169 #  define system_vsnprintf _vsnprintf
    170 # else
    171    /* Unix.  */
    172 #  define system_vsnprintf vsnprintf
    173 # endif
    174 
    175 DLL_EXPORTED
    176 int
    177 libintl_vsnprintf (char *resultbuf, size_t length, const char *format, va_list args)
    178 {
    179   if (strchr (format, '$') == NULL)
    180     return system_vsnprintf (resultbuf, length, format, args);
    181   else
    182     {
    183       size_t maxlength = length;
    184       char *result = libintl_vasnprintf (resultbuf, &length, format, args);
    185       if (result != resultbuf)
    186 	{
    187 	  if (maxlength > 0)
    188 	    {
    189 	      if (length < maxlength)
    190 		abort ();
    191 	      memcpy (resultbuf, result, maxlength - 1);
    192 	      resultbuf[maxlength - 1] = '\0';
    193 	    }
    194 	  free (result);
    195 	  return -1;
    196 	}
    197       else
    198 	return length;
    199     }
    200 }
    201 
    202 DLL_EXPORTED
    203 int
    204 libintl_snprintf (char *resultbuf, size_t length, const char *format, ...)
    205 {
    206   va_list args;
    207   int retval;
    208 
    209   va_start (args, format);
    210   retval = libintl_vsnprintf (resultbuf, length, format, args);
    211   va_end (args);
    212   return retval;
    213 }
    214 
    215 #endif
    216 
    217 #if HAVE_ASPRINTF
    218 
    219 DLL_EXPORTED
    220 int
    221 libintl_vasprintf (char **resultp, const char *format, va_list args)
    222 {
    223   size_t length;
    224   char *result = libintl_vasnprintf (NULL, &length, format, args);
    225   if (result == NULL)
    226     return -1;
    227   *resultp = result;
    228   return length;
    229 }
    230 
    231 DLL_EXPORTED
    232 int
    233 libintl_asprintf (char **resultp, const char *format, ...)
    234 {
    235   va_list args;
    236   int retval;
    237 
    238   va_start (args, format);
    239   retval = libintl_vasprintf (resultp, format, args);
    240   va_end (args);
    241   return retval;
    242 }
    243 
    244 #endif
    245 
    246 #if HAVE_FWPRINTF
    247 
    248 #include <wchar.h>
    249 
    250 #define WIDE_CHAR_VERSION 1
    251 
    252 /* Define auxiliary functions declared in "wprintf-parse.h".  */
    253 #include "printf-parse.c"
    254 
    255 /* Define functions declared in "vasnprintf.h".  */
    256 #define vasnwprintf libintl_vasnwprintf
    257 #include "vasnprintf.c"
    258 #if 0 /* not needed */
    259 #define asnwprintf libintl_asnwprintf
    260 #include "asnprintf.c"
    261 #endif
    262 
    263 # if HAVE_DECL__SNWPRINTF
    264    /* Windows.  */
    265 #  define system_vswprintf _vsnwprintf
    266 # else
    267    /* Unix.  */
    268 #  define system_vswprintf vswprintf
    269 # endif
    270 
    271 DLL_EXPORTED
    272 int
    273 libintl_vfwprintf (FILE *stream, const wchar_t *format, va_list args)
    274 {
    275   if (wcschr (format, '$') == NULL)
    276     return vfwprintf (stream, format, args);
    277   else
    278     {
    279       size_t length;
    280       wchar_t *result = libintl_vasnwprintf (NULL, &length, format, args);
    281       int retval = -1;
    282       if (result != NULL)
    283 	{
    284 	  size_t i;
    285 	  for (i = 0; i < length; i++)
    286 	    if (fputwc (result[i], stream) == WEOF)
    287 	      break;
    288 	  if (i == length)
    289 	    retval = length;
    290 	  free (result);
    291 	}
    292       return retval;
    293     }
    294 }
    295 
    296 DLL_EXPORTED
    297 int
    298 libintl_fwprintf (FILE *stream, const wchar_t *format, ...)
    299 {
    300   va_list args;
    301   int retval;
    302 
    303   va_start (args, format);
    304   retval = libintl_vfwprintf (stream, format, args);
    305   va_end (args);
    306   return retval;
    307 }
    308 
    309 DLL_EXPORTED
    310 int
    311 libintl_vwprintf (const wchar_t *format, va_list args)
    312 {
    313   return libintl_vfwprintf (stdout, format, args);
    314 }
    315 
    316 DLL_EXPORTED
    317 int
    318 libintl_wprintf (const wchar_t *format, ...)
    319 {
    320   va_list args;
    321   int retval;
    322 
    323   va_start (args, format);
    324   retval = libintl_vwprintf (format, args);
    325   va_end (args);
    326   return retval;
    327 }
    328 
    329 DLL_EXPORTED
    330 int
    331 libintl_vswprintf (wchar_t *resultbuf, size_t length, const wchar_t *format, va_list args)
    332 {
    333   if (wcschr (format, '$') == NULL)
    334     return system_vswprintf (resultbuf, length, format, args);
    335   else
    336     {
    337       size_t maxlength = length;
    338       wchar_t *result = libintl_vasnwprintf (resultbuf, &length, format, args);
    339       if (result != resultbuf)
    340 	{
    341 	  if (maxlength > 0)
    342 	    {
    343 	      if (length < maxlength)
    344 		abort ();
    345 	      memcpy (resultbuf, result, (maxlength - 1) * sizeof (wchar_t));
    346 	      resultbuf[maxlength - 1] = 0;
    347 	    }
    348 	  free (result);
    349 	  return -1;
    350 	}
    351       else
    352 	return length;
    353     }
    354 }
    355 
    356 DLL_EXPORTED
    357 int
    358 libintl_swprintf (wchar_t *resultbuf, size_t length, const wchar_t *format, ...)
    359 {
    360   va_list args;
    361   int retval;
    362 
    363   va_start (args, format);
    364   retval = libintl_vswprintf (resultbuf, length, format, args);
    365   va_end (args);
    366   return retval;
    367 }
    368 
    369 #endif
    370 
    371 #endif
    372