Home | History | Annotate | Download | only in io
      1 /*
      2 ******************************************************************************
      3 *
      4 *   Copyright (C) 1998-2012, International Business Machines
      5 *   Corporation and others.  All Rights Reserved.
      6 *
      7 ******************************************************************************
      8 *
      9 * File uprintf.c
     10 *
     11 * Modification History:
     12 *
     13 *   Date        Name        Description
     14 *   11/19/98    stephen     Creation.
     15 *   03/12/99    stephen     Modified for new C API.
     16 *                           Added conversion from default codepage.
     17 *   08/07/2003  george      Reunify printf implementations
     18 ******************************************************************************
     19 */
     20 
     21 #include "unicode/utypes.h"
     22 
     23 #if !UCONFIG_NO_FORMATTING
     24 
     25 #include "unicode/ustdio.h"
     26 #include "unicode/ustring.h"
     27 #include "unicode/unum.h"
     28 #include "unicode/udat.h"
     29 #include "unicode/putil.h"
     30 
     31 #include "uprintf.h"
     32 #include "ufile.h"
     33 #include "ucln_io.h"
     34 #include "locbund.h"
     35 
     36 #include "cmemory.h"
     37 
     38 static UFILE *gStdOut = NULL;
     39 
     40 static UBool U_CALLCONV uprintf_cleanup(void)
     41 {
     42     if (gStdOut != NULL) {
     43         u_fclose(gStdOut);
     44         gStdOut = NULL;
     45     }
     46     return TRUE;
     47 }
     48 
     49 U_CAPI UFILE * U_EXPORT2
     50 u_get_stdout()
     51 {
     52     if (gStdOut == NULL) {
     53         gStdOut = u_finit(stdout, NULL, NULL);
     54         ucln_io_registerCleanup(UCLN_IO_PRINTF, &uprintf_cleanup);
     55     }
     56     return gStdOut;
     57 }
     58 
     59 static int32_t U_EXPORT2
     60 u_printf_write(void          *context,
     61                const UChar   *str,
     62                int32_t       count)
     63 {
     64     return u_file_write(str, count, (UFILE *)context);
     65 }
     66 
     67 static int32_t
     68 u_printf_pad_and_justify(void                        *context,
     69                          const u_printf_spec_info    *info,
     70                          const UChar                 *result,
     71                          int32_t                     resultLen)
     72 {
     73     UFILE   *output = (UFILE *)context;
     74     int32_t written, i;
     75 
     76     /* pad and justify, if needed */
     77     if(info->fWidth != -1 && resultLen < info->fWidth) {
     78         /* left justify */
     79         if(info->fLeft) {
     80             written = u_file_write(result, resultLen, output);
     81             for(i = 0; i < info->fWidth - resultLen; ++i) {
     82                 written += u_file_write(&info->fPadChar, 1, output);
     83             }
     84         }
     85         /* right justify */
     86         else {
     87             written = 0;
     88             for(i = 0; i < info->fWidth - resultLen; ++i) {
     89                 written += u_file_write(&info->fPadChar, 1, output);
     90             }
     91             written += u_file_write(result, resultLen, output);
     92         }
     93     }
     94     /* just write the formatted output */
     95     else {
     96         written = u_file_write(result, resultLen, output);
     97     }
     98 
     99     return written;
    100 }
    101 
    102 U_CAPI int32_t U_EXPORT2
    103 u_fprintf(    UFILE        *f,
    104           const char    *patternSpecification,
    105           ... )
    106 {
    107     va_list ap;
    108     int32_t count;
    109 
    110     va_start(ap, patternSpecification);
    111     count = u_vfprintf(f, patternSpecification, ap);
    112     va_end(ap);
    113 
    114     return count;
    115 }
    116 
    117 U_CAPI int32_t U_EXPORT2
    118 u_printf(const char *patternSpecification,
    119          ...)
    120 {
    121     va_list ap;
    122     int32_t count;
    123     va_start(ap, patternSpecification);
    124     count = u_vfprintf(u_get_stdout(), patternSpecification, ap);
    125     va_end(ap);
    126     return count;
    127 }
    128 
    129 U_CAPI int32_t U_EXPORT2
    130 u_fprintf_u(    UFILE        *f,
    131             const UChar    *patternSpecification,
    132             ... )
    133 {
    134     va_list ap;
    135     int32_t count;
    136 
    137     va_start(ap, patternSpecification);
    138     count = u_vfprintf_u(f, patternSpecification, ap);
    139     va_end(ap);
    140 
    141     return count;
    142 }
    143 
    144 U_CAPI int32_t U_EXPORT2
    145 u_printf_u(const UChar *patternSpecification,
    146            ...)
    147 {
    148     va_list ap;
    149     int32_t count;
    150     va_start(ap, patternSpecification);
    151     count = u_vfprintf_u(u_get_stdout(), patternSpecification, ap);
    152     va_end(ap);
    153     return count;
    154 }
    155 
    156 U_CAPI int32_t  U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
    157 u_vfprintf(    UFILE        *f,
    158            const char    *patternSpecification,
    159            va_list        ap)
    160 {
    161     int32_t count;
    162     UChar *pattern;
    163     UChar buffer[UFMT_DEFAULT_BUFFER_SIZE];
    164     int32_t size = (int32_t)strlen(patternSpecification) + 1;
    165 
    166     /* convert from the default codepage to Unicode */
    167     if (size >= MAX_UCHAR_BUFFER_SIZE(buffer)) {
    168         pattern = (UChar *)uprv_malloc(size * sizeof(UChar));
    169         if(pattern == 0) {
    170             return 0;
    171         }
    172     }
    173     else {
    174         pattern = buffer;
    175     }
    176     u_charsToUChars(patternSpecification, pattern, size);
    177 
    178     /* do the work */
    179     count = u_vfprintf_u(f, pattern, ap);
    180 
    181     /* clean up */
    182     if (pattern != buffer) {
    183         uprv_free(pattern);
    184     }
    185 
    186     return count;
    187 }
    188 
    189 static const u_printf_stream_handler g_stream_handler = {
    190     u_printf_write,
    191     u_printf_pad_and_justify
    192 };
    193 
    194 U_CAPI int32_t  U_EXPORT2 /* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
    195 u_vfprintf_u(    UFILE        *f,
    196              const UChar    *patternSpecification,
    197              va_list        ap)
    198 {
    199     int32_t          written = 0;   /* haven't written anything yet */
    200 
    201     /* parse and print the whole format string */
    202     u_printf_parse(&g_stream_handler, patternSpecification, f, NULL, &f->str.fBundle, &written, ap);
    203 
    204     /* return # of UChars written */
    205     return written;
    206 }
    207 
    208 #endif /* #if !UCONFIG_NO_FORMATTING */
    209 
    210