• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
uprintf_cleanup(void)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
u_get_stdout()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
u_printf_write(void * context,const UChar * str,int32_t count)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
u_printf_pad_and_justify(void * context,const u_printf_spec_info * info,const UChar * result,int32_t resultLen)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
u_fprintf(UFILE * f,const char * patternSpecification,...)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
u_printf(const char * patternSpecification,...)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
u_fprintf_u(UFILE * f,const UChar * patternSpecification,...)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
u_printf_u(const UChar * patternSpecification,...)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 */
u_vfprintf(UFILE * f,const char * patternSpecification,va_list ap)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 */
u_vfprintf_u(UFILE * f,const UChar * patternSpecification,va_list ap)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