Back to index

tetex-bin  3.0
printf.c
Go to the documentation of this file.
00001 /* Formatted output to strings, using POSIX/XSI format strings with positions.
00002    Copyright (C) 2003 Free Software Foundation, Inc.
00003    Written by Bruno Haible <bruno@clisp.org>, 2003.
00004 
00005    This program is free software; you can redistribute it and/or modify it
00006    under the terms of the GNU Library General Public License as published
00007    by the Free Software Foundation; either version 2, or (at your option)
00008    any later version.
00009 
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public
00016    License along with this program; if not, write to the Free Software
00017    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
00018    USA.  */
00019 
00020 #ifdef HAVE_CONFIG_H
00021 # include <config.h>
00022 #endif
00023 
00024 #ifdef __GNUC__
00025 # define alloca __builtin_alloca
00026 # define HAVE_ALLOCA 1
00027 #else
00028 # ifdef _MSC_VER
00029 #  include <malloc.h>
00030 #  define alloca _alloca
00031 # else
00032 #  if defined HAVE_ALLOCA_H || defined _LIBC
00033 #   include <alloca.h>
00034 #  else
00035 #   ifdef _AIX
00036  #pragma alloca
00037 #   else
00038 #    ifndef alloca
00039 char *alloca ();
00040 #    endif
00041 #   endif
00042 #  endif
00043 # endif
00044 #endif
00045 
00046 #include <stdio.h>
00047 
00048 #if !HAVE_POSIX_PRINTF
00049 
00050 #include <stdlib.h>
00051 #include <string.h>
00052 
00053 /* When building a DLL, we must export some functions.  Note that because
00054    the functions are only defined for binary backward compatibility, we
00055    don't need to use __declspec(dllimport) in any case.  */
00056 #if defined _MSC_VER && BUILDING_DLL
00057 # define DLL_EXPORTED __declspec(dllexport)
00058 #else
00059 # define DLL_EXPORTED
00060 #endif
00061 
00062 #define STATIC static
00063 
00064 /* Define auxiliary functions declared in "printf-args.h".  */
00065 #include "printf-args.c"
00066 
00067 /* Define auxiliary functions declared in "printf-parse.h".  */
00068 #include "printf-parse.c"
00069 
00070 /* Define functions declared in "vasnprintf.h".  */
00071 #define vasnprintf libintl_vasnprintf
00072 #include "vasnprintf.c"
00073 #if 0 /* not needed */
00074 #define asnprintf libintl_asnprintf
00075 #include "asnprintf.c"
00076 #endif
00077 
00078 DLL_EXPORTED
00079 int
00080 libintl_vfprintf (FILE *stream, const char *format, va_list args)
00081 {
00082   if (strchr (format, '$') == NULL)
00083     return vfprintf (stream, format, args);
00084   else
00085     {
00086       size_t length;
00087       char *result = libintl_vasnprintf (NULL, &length, format, args);
00088       int retval = -1;
00089       if (result != NULL)
00090        {
00091          if (fwrite (result, 1, length, stream) == length)
00092            retval = length;
00093          free (result);
00094        }
00095       return retval;
00096     }
00097 }
00098 
00099 DLL_EXPORTED
00100 int
00101 libintl_fprintf (FILE *stream, const char *format, ...)
00102 {
00103   va_list args;
00104   int retval;
00105 
00106   va_start (args, format);
00107   retval = libintl_vfprintf (stream, format, args);
00108   va_end (args);
00109   return retval;
00110 }
00111 
00112 DLL_EXPORTED
00113 int
00114 libintl_vprintf (const char *format, va_list args)
00115 {
00116   return libintl_vfprintf (stdout, format, args);
00117 }
00118 
00119 DLL_EXPORTED
00120 int
00121 libintl_printf (const char *format, ...)
00122 {
00123   va_list args;
00124   int retval;
00125 
00126   va_start (args, format);
00127   retval = libintl_vprintf (format, args);
00128   va_end (args);
00129   return retval;
00130 }
00131 
00132 DLL_EXPORTED
00133 int
00134 libintl_vsprintf (char *resultbuf, const char *format, va_list args)
00135 {
00136   if (strchr (format, '$') == NULL)
00137     return vsprintf (resultbuf, format, args);
00138   else
00139     {
00140       size_t length = (size_t) ~0 / (4 * sizeof (char));
00141       char *result = libintl_vasnprintf (resultbuf, &length, format, args);
00142       if (result != resultbuf)
00143        {
00144          free (result);
00145          return -1;
00146        }
00147       else
00148        return length;
00149     }
00150 }
00151 
00152 DLL_EXPORTED
00153 int
00154 libintl_sprintf (char *resultbuf, const char *format, ...)
00155 {
00156   va_list args;
00157   int retval;
00158 
00159   va_start (args, format);
00160   retval = libintl_vsprintf (resultbuf, format, args);
00161   va_end (args);
00162   return retval;
00163 }
00164 
00165 #if HAVE_SNPRINTF
00166 
00167 # if HAVE_DECL__SNPRINTF
00168    /* Windows.  */
00169 #  define system_vsnprintf _vsnprintf
00170 # else
00171    /* Unix.  */
00172 #  define system_vsnprintf vsnprintf
00173 # endif
00174 
00175 DLL_EXPORTED
00176 int
00177 libintl_vsnprintf (char *resultbuf, size_t length, const char *format, va_list args)
00178 {
00179   if (strchr (format, '$') == NULL)
00180     return system_vsnprintf (resultbuf, length, format, args);
00181   else
00182     {
00183       size_t maxlength = length;
00184       char *result = libintl_vasnprintf (resultbuf, &length, format, args);
00185       if (result != resultbuf)
00186        {
00187          if (maxlength > 0)
00188            {
00189              if (length < maxlength)
00190               abort ();
00191              memcpy (resultbuf, result, maxlength - 1);
00192              resultbuf[maxlength - 1] = '\0';
00193            }
00194          free (result);
00195          return -1;
00196        }
00197       else
00198        return length;
00199     }
00200 }
00201 
00202 DLL_EXPORTED
00203 int
00204 libintl_snprintf (char *resultbuf, size_t length, const char *format, ...)
00205 {
00206   va_list args;
00207   int retval;
00208 
00209   va_start (args, format);
00210   retval = libintl_vsnprintf (resultbuf, length, format, args);
00211   va_end (args);
00212   return retval;
00213 }
00214 
00215 #endif
00216 
00217 #if HAVE_ASPRINTF
00218 
00219 DLL_EXPORTED
00220 int
00221 libintl_vasprintf (char **resultp, const char *format, va_list args)
00222 {
00223   size_t length;
00224   char *result = libintl_vasnprintf (NULL, &length, format, args);
00225   if (result == NULL)
00226     return -1;
00227   *resultp = result;
00228   return length;
00229 }
00230 
00231 DLL_EXPORTED
00232 int
00233 libintl_asprintf (char **resultp, const char *format, ...)
00234 {
00235   va_list args;
00236   int retval;
00237 
00238   va_start (args, format);
00239   retval = libintl_vasprintf (resultp, format, args);
00240   va_end (args);
00241   return retval;
00242 }
00243 
00244 #endif
00245 
00246 #if HAVE_FWPRINTF
00247 
00248 #include <wchar.h>
00249 
00250 #define WIDE_CHAR_VERSION 1
00251 
00252 /* Define auxiliary functions declared in "wprintf-parse.h".  */
00253 #include "printf-parse.c"
00254 
00255 /* Define functions declared in "vasnprintf.h".  */
00256 #define vasnwprintf libintl_vasnwprintf
00257 #include "vasnprintf.c"
00258 #if 0 /* not needed */
00259 #define asnwprintf libintl_asnwprintf
00260 #include "asnprintf.c"
00261 #endif
00262 
00263 # if HAVE_DECL__SNWPRINTF
00264    /* Windows.  */
00265 #  define system_vswprintf _vsnwprintf
00266 # else
00267    /* Unix.  */
00268 #  define system_vswprintf vswprintf
00269 # endif
00270 
00271 DLL_EXPORTED
00272 int
00273 libintl_vfwprintf (FILE *stream, const wchar_t *format, va_list args)
00274 {
00275   if (wcschr (format, '$') == NULL)
00276     return vfwprintf (stream, format, args);
00277   else
00278     {
00279       size_t length;
00280       wchar_t *result = libintl_vasnwprintf (NULL, &length, format, args);
00281       int retval = -1;
00282       if (result != NULL)
00283        {
00284          size_t i;
00285          for (i = 0; i < length; i++)
00286            if (fputwc (result[i], stream) == WEOF)
00287              break;
00288          if (i == length)
00289            retval = length;
00290          free (result);
00291        }
00292       return retval;
00293     }
00294 }
00295 
00296 DLL_EXPORTED
00297 int
00298 libintl_fwprintf (FILE *stream, const wchar_t *format, ...)
00299 {
00300   va_list args;
00301   int retval;
00302 
00303   va_start (args, format);
00304   retval = libintl_vfwprintf (stream, format, args);
00305   va_end (args);
00306   return retval;
00307 }
00308 
00309 DLL_EXPORTED
00310 int
00311 libintl_vwprintf (const wchar_t *format, va_list args)
00312 {
00313   return libintl_vfwprintf (stdout, format, args);
00314 }
00315 
00316 DLL_EXPORTED
00317 int
00318 libintl_wprintf (const wchar_t *format, ...)
00319 {
00320   va_list args;
00321   int retval;
00322 
00323   va_start (args, format);
00324   retval = libintl_vwprintf (format, args);
00325   va_end (args);
00326   return retval;
00327 }
00328 
00329 DLL_EXPORTED
00330 int
00331 libintl_vswprintf (wchar_t *resultbuf, size_t length, const wchar_t *format, va_list args)
00332 {
00333   if (wcschr (format, '$') == NULL)
00334     return system_vswprintf (resultbuf, length, format, args);
00335   else
00336     {
00337       size_t maxlength = length;
00338       wchar_t *result = libintl_vasnwprintf (resultbuf, &length, format, args);
00339       if (result != resultbuf)
00340        {
00341          if (maxlength > 0)
00342            {
00343              if (length < maxlength)
00344               abort ();
00345              memcpy (resultbuf, result, (maxlength - 1) * sizeof (wchar_t));
00346              resultbuf[maxlength - 1] = 0;
00347            }
00348          free (result);
00349          return -1;
00350        }
00351       else
00352        return length;
00353     }
00354 }
00355 
00356 DLL_EXPORTED
00357 int
00358 libintl_swprintf (wchar_t *resultbuf, size_t length, const wchar_t *format, ...)
00359 {
00360   va_list args;
00361   int retval;
00362 
00363   va_start (args, format);
00364   retval = libintl_vswprintf (resultbuf, length, format, args);
00365   va_end (args);
00366   return retval;
00367 }
00368 
00369 #endif
00370 
00371 #endif