1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /********************************************************************
5 * Copyright (c) 1997-2011, International Business Machines Corporation and
6 * others. All Rights Reserved.
7 * Copyright (C) 2010 , Yahoo! Inc.
8 ********************************************************************
12 * tab size: 8 (not used)
17 * 08/5/2001 Ram Added C wrappers for C++ API.
18 ********************************************************************/
23 #include "unicode/utypes.h"
25 #if !UCONFIG_NO_FORMATTING
27 #include "unicode/localpointer.h"
28 #include "unicode/uloc.h"
29 #include "unicode/parseerr.h"
34 * \brief C API: MessageFormat
36 * <h2>MessageFormat C API </h2>
38 * <p>MessageFormat prepares strings for display to users,
39 * with optional arguments (variables/placeholders).
40 * The arguments can occur in any order, which is necessary for translation
41 * into languages with different grammars.
43 * <p>The opaque UMessageFormat type is a thin C wrapper around
44 * a C++ MessageFormat. It is constructed from a <em>pattern</em> string
45 * with arguments in {curly braces} which will be replaced by formatted values.
47 * <p>Currently, the C API supports only numbered arguments.
49 * <p>For details about the pattern syntax and behavior,
50 * especially about the ASCII apostrophe vs. the
51 * real apostrophe (single quote) character \htmlonly’\endhtmlonly (U+2019),
52 * see the C++ MessageFormat class documentation.
54 * <p>Here are some examples of C API usage:
58 * UChar *result, *tzID, *str;
60 * int32_t resultLengthOut, resultlength;
64 * UErrorCode status = U_ZERO_ERROR;
66 * str=(UChar*)malloc(sizeof(UChar) * (strlen("disturbance in force") +1));
67 * u_uastrcpy(str, "disturbance in force");
68 * tzID=(UChar*)malloc(sizeof(UChar) * 4);
69 * u_uastrcpy(tzID, "PST");
70 * cal=ucal_open(tzID, u_strlen(tzID), "en_US", UCAL_TRADITIONAL, &status);
71 * ucal_setDateTime(cal, 1999, UCAL_MARCH, 18, 0, 0, 0, &status);
72 * d1=ucal_getMillis(cal, &status);
73 * u_uastrcpy(pattern, "On {0, date, long}, there was a {1} on planet {2,number,integer}");
75 * resultLengthOut=u_formatMessage( "en_US", pattern, u_strlen(pattern), NULL, resultlength, &status, d1, str, 7);
76 * if(status==U_BUFFER_OVERFLOW_ERROR){
77 * status=U_ZERO_ERROR;
78 * resultlength=resultLengthOut+1;
79 * result=(UChar*)realloc(result, sizeof(UChar) * resultlength);
80 * u_formatMessage( "en_US", pattern, u_strlen(pattern), result, resultlength, &status, d1, str, 7);
82 * printf("%s\n", austrdup(result) );//austrdup( a function used to convert UChar* to char*)
83 * //output>: "On March 18, 1999, there was a disturbance in force on planet 7
86 * Typically, the message format will come from resources, and the
87 * arguments will be dynamically set at runtime.
93 * UErrorCode status = U_ZERO_ERROR;
96 * int32_t resultlength, resultLengthOut, i;
97 * double testArgs= { 100.0, 1.0, 0.0};
99 * str=(UChar*)malloc(sizeof(UChar) * 10);
100 * u_uastrcpy(str, "MyDisk");
101 * u_uastrcpy(pattern, "The disk {1} contains {0,choice,0#no files|1#one file|1<{0,number,integer} files}");
102 * for(i=0; i<3; i++){
104 * resultLengthOut=u_formatMessage( "en_US", pattern, u_strlen(pattern), NULL, resultlength, &status, testArgs[i], str);
105 * if(status==U_BUFFER_OVERFLOW_ERROR){
106 * status=U_ZERO_ERROR;
107 * resultlength=resultLengthOut+1;
108 * result=(UChar*)malloc(sizeof(UChar) * resultlength);
109 * u_formatMessage( "en_US", pattern, u_strlen(pattern), result, resultlength, &status, testArgs[i], str);
111 * printf("%s\n", austrdup(result) ); //austrdup( a function used to convert UChar* to char*)
114 * // output, with different testArgs:
115 * // output: The disk "MyDisk" contains 100 files.
116 * // output: The disk "MyDisk" contains one file.
117 * // output: The disk "MyDisk" contains no files.
127 * UErrorCode status = U_ZERO_ERROR;
129 * UChar pattern[100];
130 * UChar expected[100];
131 * int32_t resultlength,resultLengthOut;
133 * str=(UChar*)malloc(sizeof(UChar) * 25);
134 * u_uastrcpy(str, "Kirti");
135 * str1=(UChar*)malloc(sizeof(UChar) * 25);
136 * u_uastrcpy(str1, "female");
137 * log_verbose("Testing message format with Select test #1\n:");
138 * u_uastrcpy(pattern, "{0} est {1, select, female {all\\u00E9e} other {all\\u00E9}} \\u00E0 Paris.");
139 * u_uastrcpy(expected, "Kirti est all\\u00E9e \\u00E0 Paris.");
141 * resultLengthOut=u_formatMessage( "fr", pattern, u_strlen(pattern), NULL, resultlength, &status, str , str1);
142 * if(status==U_BUFFER_OVERFLOW_ERROR)
144 * status=U_ZERO_ERROR;
145 * resultlength=resultLengthOut+1;
146 * result=(UChar*)malloc(sizeof(UChar) * resultlength);
147 * u_formatMessage( "fr", pattern, u_strlen(pattern), result, resultlength, &status, str , str1);
148 * if(u_strcmp(result, expected)==0)
149 * log_verbose("PASS: MessagFormat successful on Select test#1\n");
151 * log_err("FAIL: Error in MessageFormat on Select test#1\n GOT %s EXPECTED %s\n", austrdup(result),
152 * austrdup(expected) );
161 * Format a message for a locale.
162 * This function may perform re-ordering of the arguments depending on the
163 * locale. For all numeric arguments, double is assumed unless the type is
164 * explicitly integer. All choice format arguments must be of type double.
165 * @param locale The locale for which the message will be formatted
166 * @param pattern The pattern specifying the message's format
167 * @param patternLength The length of pattern
168 * @param result A pointer to a buffer to receive the formatted message.
169 * @param resultLength The maximum size of result.
170 * @param status A pointer to an UErrorCode to receive any errors
171 * @param ... A variable-length argument list containing the arguments specified
173 * @return The total buffer size needed; if greater than resultLength, the
174 * output was truncated.
175 * @see u_parseMessage
178 U_STABLE
int32_t U_EXPORT2
179 u_formatMessage(const char *locale
,
180 const UChar
*pattern
,
181 int32_t patternLength
,
183 int32_t resultLength
,
188 * Format a message for a locale.
189 * This function may perform re-ordering of the arguments depending on the
190 * locale. For all numeric arguments, double is assumed unless the type is
191 * explicitly integer. All choice format arguments must be of type double.
192 * @param locale The locale for which the message will be formatted
193 * @param pattern The pattern specifying the message's format
194 * @param patternLength The length of pattern
195 * @param result A pointer to a buffer to receive the formatted message.
196 * @param resultLength The maximum size of result.
197 * @param ap A variable-length argument list containing the arguments specified
198 * @param status A pointer to an UErrorCode to receive any errors
200 * @return The total buffer size needed; if greater than resultLength, the
201 * output was truncated.
202 * @see u_parseMessage
205 U_STABLE
int32_t U_EXPORT2
206 u_vformatMessage( const char *locale
,
207 const UChar
*pattern
,
208 int32_t patternLength
,
210 int32_t resultLength
,
216 * For numeric arguments, this function will always use doubles. Integer types
217 * should not be passed.
218 * This function is not able to parse all output from {@link #u_formatMessage }.
219 * @param locale The locale for which the message is formatted
220 * @param pattern The pattern specifying the message's format
221 * @param patternLength The length of pattern
222 * @param source The text to parse.
223 * @param sourceLength The length of source, or -1 if null-terminated.
224 * @param status A pointer to an UErrorCode to receive any errors
225 * @param ... A variable-length argument list containing the arguments
226 * specified in pattern.
227 * @see u_formatMessage
230 U_STABLE
void U_EXPORT2
231 u_parseMessage( const char *locale
,
232 const UChar
*pattern
,
233 int32_t patternLength
,
235 int32_t sourceLength
,
241 * For numeric arguments, this function will always use doubles. Integer types
242 * should not be passed.
243 * This function is not able to parse all output from {@link #u_formatMessage }.
244 * @param locale The locale for which the message is formatted
245 * @param pattern The pattern specifying the message's format
246 * @param patternLength The length of pattern
247 * @param source The text to parse.
248 * @param sourceLength The length of source, or -1 if null-terminated.
249 * @param ap A variable-length argument list containing the arguments
250 * @param status A pointer to an UErrorCode to receive any errors
251 * specified in pattern.
252 * @see u_formatMessage
255 U_STABLE
void U_EXPORT2
256 u_vparseMessage(const char *locale
,
257 const UChar
*pattern
,
258 int32_t patternLength
,
260 int32_t sourceLength
,
265 * Format a message for a locale.
266 * This function may perform re-ordering of the arguments depending on the
267 * locale. For all numeric arguments, double is assumed unless the type is
268 * explicitly integer. All choice format arguments must be of type double.
269 * @param locale The locale for which the message will be formatted
270 * @param pattern The pattern specifying the message's format
271 * @param patternLength The length of pattern
272 * @param result A pointer to a buffer to receive the formatted message.
273 * @param resultLength The maximum size of result.
274 * @param status A pointer to an UErrorCode to receive any errors
275 * @param ... A variable-length argument list containing the arguments specified
277 * @param parseError A pointer to UParseError to receive information about errors
278 * occurred during parsing.
279 * @return The total buffer size needed; if greater than resultLength, the
280 * output was truncated.
281 * @see u_parseMessage
284 U_STABLE
int32_t U_EXPORT2
285 u_formatMessageWithError( const char *locale
,
286 const UChar
*pattern
,
287 int32_t patternLength
,
289 int32_t resultLength
,
290 UParseError
*parseError
,
295 * Format a message for a locale.
296 * This function may perform re-ordering of the arguments depending on the
297 * locale. For all numeric arguments, double is assumed unless the type is
298 * explicitly integer. All choice format arguments must be of type double.
299 * @param locale The locale for which the message will be formatted
300 * @param pattern The pattern specifying the message's format
301 * @param patternLength The length of pattern
302 * @param result A pointer to a buffer to receive the formatted message.
303 * @param resultLength The maximum size of result.
304 * @param parseError A pointer to UParseError to receive information about errors
305 * occurred during parsing.
306 * @param ap A variable-length argument list containing the arguments specified
307 * @param status A pointer to an UErrorCode to receive any errors
309 * @return The total buffer size needed; if greater than resultLength, the
310 * output was truncated.
313 U_STABLE
int32_t U_EXPORT2
314 u_vformatMessageWithError( const char *locale
,
315 const UChar
*pattern
,
316 int32_t patternLength
,
318 int32_t resultLength
,
319 UParseError
* parseError
,
325 * For numeric arguments, this function will always use doubles. Integer types
326 * should not be passed.
327 * This function is not able to parse all output from {@link #u_formatMessage }.
328 * @param locale The locale for which the message is formatted
329 * @param pattern The pattern specifying the message's format
330 * @param patternLength The length of pattern
331 * @param source The text to parse.
332 * @param sourceLength The length of source, or -1 if null-terminated.
333 * @param parseError A pointer to UParseError to receive information about errors
334 * occurred during parsing.
335 * @param status A pointer to an UErrorCode to receive any errors
336 * @param ... A variable-length argument list containing the arguments
337 * specified in pattern.
338 * @see u_formatMessage
341 U_STABLE
void U_EXPORT2
342 u_parseMessageWithError(const char *locale
,
343 const UChar
*pattern
,
344 int32_t patternLength
,
346 int32_t sourceLength
,
347 UParseError
*parseError
,
353 * For numeric arguments, this function will always use doubles. Integer types
354 * should not be passed.
355 * This function is not able to parse all output from {@link #u_formatMessage }.
356 * @param locale The locale for which the message is formatted
357 * @param pattern The pattern specifying the message's format
358 * @param patternLength The length of pattern
359 * @param source The text to parse.
360 * @param sourceLength The length of source, or -1 if null-terminated.
361 * @param ap A variable-length argument list containing the arguments
362 * @param parseError A pointer to UParseError to receive information about errors
363 * occurred during parsing.
364 * @param status A pointer to an UErrorCode to receive any errors
365 * specified in pattern.
366 * @see u_formatMessage
369 U_STABLE
void U_EXPORT2
370 u_vparseMessageWithError(const char *locale
,
371 const UChar
*pattern
,
372 int32_t patternLength
,
374 int32_t sourceLength
,
376 UParseError
*parseError
,
379 /*----------------------- New experimental API --------------------------- */
381 * The message format object
384 typedef void* UMessageFormat
;
388 * Open a message formatter with given pattern and for the given locale.
389 * @param pattern A pattern specifying the format to use.
390 * @param patternLength Length of the pattern to use
391 * @param locale The locale for which the messages are formatted.
392 * @param parseError A pointer to UParseError struct to receive any errors
393 * occured during parsing. Can be NULL.
394 * @param status A pointer to an UErrorCode to receive any errors.
395 * @return A pointer to a UMessageFormat to use for formatting
396 * messages, or 0 if an error occurred.
399 U_STABLE UMessageFormat
* U_EXPORT2
400 umsg_open( const UChar
*pattern
,
401 int32_t patternLength
,
403 UParseError
*parseError
,
407 * Close a UMessageFormat.
408 * Once closed, a UMessageFormat may no longer be used.
409 * @param format The formatter to close.
412 U_STABLE
void U_EXPORT2
413 umsg_close(UMessageFormat
* format
);
415 #if U_SHOW_CPLUSPLUS_API
420 * \class LocalUMessageFormatPointer
421 * "Smart pointer" class, closes a UMessageFormat via umsg_close().
422 * For most methods see the LocalPointerBase base class.
424 * @see LocalPointerBase
428 U_DEFINE_LOCAL_OPEN_POINTER(LocalUMessageFormatPointer
, UMessageFormat
, umsg_close
);
432 #endif // U_SHOW_CPLUSPLUS_API
435 * Open a copy of a UMessageFormat.
436 * This function performs a deep copy.
437 * @param fmt The formatter to copy
438 * @param status A pointer to an UErrorCode to receive any errors.
439 * @return A pointer to a UDateFormat identical to fmt.
442 U_STABLE UMessageFormat U_EXPORT2
443 umsg_clone(const UMessageFormat
*fmt
,
447 * Sets the locale. This locale is used for fetching default number or date
448 * format information.
449 * @param fmt The formatter to set
450 * @param locale The locale the formatter should use.
453 U_STABLE
void U_EXPORT2
454 umsg_setLocale(UMessageFormat
*fmt
,
458 * Gets the locale. This locale is used for fetching default number or date
459 * format information.
460 * @param fmt The formatter to querry
461 * @return the locale.
464 U_STABLE
const char* U_EXPORT2
465 umsg_getLocale(const UMessageFormat
*fmt
);
469 * @param fmt The formatter to use
470 * @param pattern The pattern to be applied.
471 * @param patternLength Length of the pattern to use
472 * @param parseError Struct to receive information on position
473 * of error if an error is encountered.Can be NULL.
474 * @param status Output param set to success/failure code on
475 * exit. If the pattern is invalid, this will be
476 * set to a failure result.
479 U_STABLE
void U_EXPORT2
480 umsg_applyPattern( UMessageFormat
*fmt
,
481 const UChar
* pattern
,
482 int32_t patternLength
,
483 UParseError
* parseError
,
488 * @param fmt The formatter to use
489 * @param result A pointer to a buffer to receive the pattern.
490 * @param resultLength The maximum size of result.
491 * @param status Output param set to success/failure code on
492 * exit. If the pattern is invalid, this will be
493 * set to a failure result.
494 * @return the pattern of the format
497 U_STABLE
int32_t U_EXPORT2
498 umsg_toPattern(const UMessageFormat
*fmt
,
500 int32_t resultLength
,
504 * Format a message for a locale.
505 * This function may perform re-ordering of the arguments depending on the
506 * locale. For all numeric arguments, double is assumed unless the type is
507 * explicitly integer. All choice format arguments must be of type double.
508 * @param fmt The formatter to use
509 * @param result A pointer to a buffer to receive the formatted message.
510 * @param resultLength The maximum size of result.
511 * @param status A pointer to an UErrorCode to receive any errors
512 * @param ... A variable-length argument list containing the arguments
513 * specified in pattern.
514 * @return The total buffer size needed; if greater than resultLength,
515 * the output was truncated.
518 U_STABLE
int32_t U_EXPORT2
519 umsg_format( const UMessageFormat
*fmt
,
521 int32_t resultLength
,
526 * Format a message for a locale.
527 * This function may perform re-ordering of the arguments depending on the
528 * locale. For all numeric arguments, double is assumed unless the type is
529 * explicitly integer. All choice format arguments must be of type double.
530 * @param fmt The formatter to use
531 * @param result A pointer to a buffer to receive the formatted message.
532 * @param resultLength The maximum size of result.
533 * @param ap A variable-length argument list containing the arguments
534 * @param status A pointer to an UErrorCode to receive any errors
535 * specified in pattern.
536 * @return The total buffer size needed; if greater than resultLength,
537 * the output was truncated.
540 U_STABLE
int32_t U_EXPORT2
541 umsg_vformat( const UMessageFormat
*fmt
,
543 int32_t resultLength
,
549 * For numeric arguments, this function will always use doubles. Integer types
550 * should not be passed.
551 * This function is not able to parse all output from {@link #umsg_format }.
552 * @param fmt The formatter to use
553 * @param source The text to parse.
554 * @param sourceLength The length of source, or -1 if null-terminated.
555 * @param count Output param to receive number of elements returned.
556 * @param status A pointer to an UErrorCode to receive any errors
557 * @param ... A variable-length argument list containing the arguments
558 * specified in pattern.
561 U_STABLE
void U_EXPORT2
562 umsg_parse( const UMessageFormat
*fmt
,
564 int32_t sourceLength
,
571 * For numeric arguments, this function will always use doubles. Integer types
572 * should not be passed.
573 * This function is not able to parse all output from {@link #umsg_format }.
574 * @param fmt The formatter to use
575 * @param source The text to parse.
576 * @param sourceLength The length of source, or -1 if null-terminated.
577 * @param count Output param to receive number of elements returned.
578 * @param ap A variable-length argument list containing the arguments
579 * @param status A pointer to an UErrorCode to receive any errors
580 * specified in pattern.
581 * @see u_formatMessage
584 U_STABLE
void U_EXPORT2
585 umsg_vparse(const UMessageFormat
*fmt
,
587 int32_t sourceLength
,
594 * Convert an 'apostrophe-friendly' pattern into a standard
595 * pattern. Standard patterns treat all apostrophes as
596 * quotes, which is problematic in some languages, e.g.
597 * French, where apostrophe is commonly used. This utility
598 * assumes that only an unpaired apostrophe immediately before
599 * a brace is a true quote. Other unpaired apostrophes are paired,
600 * and the resulting standard pattern string is returned.
602 * <p><b>Note</b> it is not guaranteed that the returned pattern
603 * is indeed a valid pattern. The only effect is to convert
604 * between patterns having different quoting semantics.
606 * @param pattern the 'apostrophe-friendly' patttern to convert
607 * @param patternLength the length of pattern, or -1 if unknown and pattern is null-terminated
608 * @param dest the buffer for the result, or NULL if preflight only
609 * @param destCapacity the length of the buffer, or 0 if preflighting
610 * @param ec the error code
611 * @return the length of the resulting text, not including trailing null
612 * if buffer has room for the trailing null, it is provided, otherwise
616 U_STABLE
int32_t U_EXPORT2
617 umsg_autoQuoteApostrophe(const UChar
* pattern
,
618 int32_t patternLength
,
620 int32_t destCapacity
,
623 #endif /* #if !UCONFIG_NO_FORMATTING */