This page describes guidelines for writing code for the International Components for Unicode and how to add it to the project.
UBREAKITERATOR_DONE
,
UBIDI_DEFAULT_LTR
, ULESS
.getLength()
.class DateFormatSymbols
.countItems()
- not getItemCount() (even if we do not need to actually count
in the implementation of that member function).U_CAPI int32_t U_EXPORT2 u_formatMessage(...);
In C, this is a pointer, and it must be checked for NULL
.
In C++, this is a reference. In both cases, it must be checked for
an error code already being in there:
U_CAPI const UBiDiLevel * U_EXPORT2 ubidi_getLevels(UBiDi *pBiDi, UErrorCode *pErrorCode) { UTextOffset start, length; if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { return NULL; } else if(pBiDi==NULL || (length=pBiDi->length)<=0) { *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; return NULL; } ... return result; }This prevents the API function from doing anything on data that is not valid in a chain of function calls and relieves the caller from checking the error code after each call.
U_COMMON_IMPLEMENTATION
,
U_I18N_IMPLEMENTATION
, U_COMMON_API
, U_I18N_API
.
See utypes.h
.Platform dependencies are dealt with in the header files that utypes.h
includes. They are platform.h
and its more specific cousins
like pwin32.h
for Windows, which define basic types,
and putil.h
, which defines platform utilities.
umutex.c
),
no ICU source code may have any #ifdef OperatingSystemName
instructions.
u_charDirection()
don't have a module identifier in their prefix.
u_strlen()
.u_charDirection()
, ubidi_setPara()
.UComparisonResult
.#define
d constants and macros , we prepend a
"U_", often "U<module identifier>_" with an underscore to the
uppercase macro name. U_ZERO_ERROR
, U_SUCCESS()
.U_CAPI return-type
U_EXPORT2
to satisfy all compilers' needs.U_CAPI UBiDi * U_EXPORT2 ubidi_open(); U_CAPI UBiDi * U_EXPORT2 ubidi_openSized(UTextOffset maxLength, UTextOffset maxRunCount); U_CAPI void U_EXPORT2 ubidi_close(UBiDi *pBiDi);
cmemory.h
must be used. class U_I18N_API SimpleDateFormat
or like class U_COMMON_API UCharCharacterIterator
.XP_PLUSPLUS
to make sure the compiler does
C++, not __cplusplus
.UErrorCode
is set. This means that either the adoptee is deleted immediately
or its pointer is stored in the new object. The former case is most
common when the constructor or factory function is called and the
UErrorCode
already indicates a failure. In the latter
case, the new object must take care of deleting the adoptee once
it is deleted itself regardless of whether the constructor was successful.new
operator must check the resulting pointer returned by new
and delete any adoptees if it is 0
because the constructor
was not called. (Typically, a UErrorCode
must be set
to U_MEMORY_ALLOCATION_ERROR
.)createInstance()
): The factory
function must set a U_MEMORY_ALLOCATION_ERROR
and delete
any adoptees if it cannot allocate the new object. If the construction
of the object fails otherwise, then the factory function must delete
it - and it in turn must delete its adoptees. As a result, a factory
function always returns either a valid object and a successful UErrorCode
,
or a 0
pointer and a failure UErrorCode
.Calendar* Calendar::createInstance(TimeZone* zone, UErrorCode& errorCode) { if(U_FAILURE(errorCode)) { delete zone; return 0; } // since the Locale isn't specified, use the default locale Calendar* c = new GregorianCalendar(zone, Locale::getDefault(), errorCode); if(c == 0) { errorCode = U_MEMORY_ALLOCATION_ERROR; delete zone; } else if(U_FAILURE(errorCode)) { delete c; c = 0; } return c; }
new
and delete
operators (or the C functions/macros
in cmemory.h
) must be used. In order to add compilable files to ICU, you not only need to add them to the source code control system in the appropriate folder, but also add them to the build environment.
The first step is to choose one of the ICU libraries:
Put the source code files into the folder icu/source/library-name
.
Then add them to the build system:
For most platforms, add the expected .o files to icu/source/library-name/Makefile.in
,
to the OBJECTS
variable.
Add the public header files to the HEADERS
variable.
icu/source/library-name/library-name.dsp
.
If you don't have Visual C++, then try to add the filenames to the project
file manually; it is a text file, and this part should be fairly obvious.You also need to add test code to icu/source/test/cintltest
for C APIs and to icu/source/test/intltest
for C++ APIs.
All the API functions must be called by the test code (100% API coverage), and at least 85% of the implementation code should be exercised by the tests (>=85% code coverage).
log_err()
, log_info()
,
and log_verbose()
APIs from cintltst.h
(which
uses ctest.h
), and check it into the appropriate folder.addTest()
. The function that makes the call to addTest()
ultimately has to be called by addAllTests()
in calltest.c
.
Groups of tests typically have a common addGroup()
function
that calls addTest()
for the test functions in its group,
according to the common part of the test module path.Makefile.in
and the appropriate .dsp
file like for the library code.We are using the following tools to build ICU: