ICU-587 ICU Workshop exercises check in
X-SVN-Rev: 2419
This commit is contained in:
parent
7be213493b
commit
08647fc996
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -76,6 +76,7 @@ icu4c/source/data/brkitr/wordBE.brk -text
|
|||||||
icu4c/source/data/brkitr/wordLE.brk -text
|
icu4c/source/data/brkitr/wordLE.brk -text
|
||||||
icu4c/source/data/brkitr/word_thBE.brk -text
|
icu4c/source/data/brkitr/word_thBE.brk -text
|
||||||
icu4c/source/data/brkitr/word_thLE.brk -text
|
icu4c/source/data/brkitr/word_thLE.brk -text
|
||||||
|
icu4c/source/samples/translit/U0080.pdf -text
|
||||||
icu4c/source/samples/ucnv/data01.ut8 -text
|
icu4c/source/samples/ucnv/data01.ut8 -text
|
||||||
icu4c/source/test/testdata/en_US.uni -text
|
icu4c/source/test/testdata/en_US.uni -text
|
||||||
icu4c/source/test/testdata/importtest.bin -text
|
icu4c/source/test/testdata/importtest.bin -text
|
||||||
|
107
icu4c/source/samples/datefmt/README.TXT
Normal file
107
icu4c/source/samples/datefmt/README.TXT
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
This is an exercise for the ICU Workshop (September 2000).
|
||||||
|
|
||||||
|
Day 2: September 12th 2000
|
||||||
|
Pre-requsit:
|
||||||
|
1. All the hardware and software requirements from Day 1.
|
||||||
|
2. Attended or fully understand Day 1 material.
|
||||||
|
3. Read through the ICU user's guide at
|
||||||
|
http://oss.software.ibm.com/icu/userguide/.
|
||||||
|
|
||||||
|
#Date/Time/Number Formatting Support
|
||||||
|
9:30am - 10:30am
|
||||||
|
Alan Liu
|
||||||
|
|
||||||
|
Topics:
|
||||||
|
1. What is the date/time support in ICU?
|
||||||
|
2. What is the timezone support in ICU?
|
||||||
|
3. What kind of formatting and parsing support is available in ICU, i.e.
|
||||||
|
NumberFormat, DateFormat, MessageFormat?
|
||||||
|
|
||||||
|
|
||||||
|
INSTRUCTIONS
|
||||||
|
------------
|
||||||
|
|
||||||
|
This exercise was developed and tested on ICU release 1.6.0, Win32,
|
||||||
|
Microsoft Visual C++ 6.0. It should work on other ICU releases and
|
||||||
|
other platforms as well, but the user will have to develop makefiles.
|
||||||
|
|
||||||
|
To install: Create a folder "datefmt" at:
|
||||||
|
|
||||||
|
<icu>/source/samples/datefmt
|
||||||
|
|
||||||
|
Within it, place the files:
|
||||||
|
|
||||||
|
datefmt.dsp
|
||||||
|
datefmt.dsw
|
||||||
|
main.cpp
|
||||||
|
util.cpp
|
||||||
|
util.h
|
||||||
|
|
||||||
|
Open the file "datefmt.dsw" in Microsoft Visual C++.
|
||||||
|
|
||||||
|
|
||||||
|
PROBLEMS
|
||||||
|
--------
|
||||||
|
|
||||||
|
Problem 0:
|
||||||
|
|
||||||
|
Set up the program, build it, and run it. To start with, the
|
||||||
|
program prints out a list of languages.
|
||||||
|
|
||||||
|
Problem 1: Basic Date Formatting (Easy)
|
||||||
|
|
||||||
|
Create a calendar, and use it to get the UDate for June 4, 1999,
|
||||||
|
0:00 GMT (or any date of your choosing). You will have to create a
|
||||||
|
TimeZone (use the createZone() function already defined in main.cpp)
|
||||||
|
and a Calendar object, and make the calendar use the time zone.
|
||||||
|
|
||||||
|
Once you have the UDate, create a DateFormat object in each of the
|
||||||
|
languages in the LANGUAGE array, and display the date in that
|
||||||
|
language. Use the DateFormat::createDateInstance() method to create
|
||||||
|
the date formatter.
|
||||||
|
|
||||||
|
Problem 2: Date Formatting, Specific Time Zone (Medium)
|
||||||
|
|
||||||
|
To really localize a time display, one can also specify the time
|
||||||
|
zone in which the time should be displayed. For each language,
|
||||||
|
also create different time zones from the TIMEZONE list.
|
||||||
|
|
||||||
|
To format a date with a specific calendar and zone, you must deal with
|
||||||
|
three objects: a DateFormat, a Calendar, and a TimeZone. Each object
|
||||||
|
must be linked to another in correct sequence: The Calendar must use
|
||||||
|
the TimeZone, and the DateFormat must use the Calendar.
|
||||||
|
|
||||||
|
DateFormat =uses=> Calendar =uses=> TimeZone
|
||||||
|
|
||||||
|
Use either setFoo() or adoptFoo() methods, depending on where you
|
||||||
|
want to have ownership.
|
||||||
|
|
||||||
|
NOTE: It's not always desirable to change the time to a local time
|
||||||
|
zone before display. For instance, if some even occurs at 0:00 GMT
|
||||||
|
on the first of the month, it's probably clearer to just state that.
|
||||||
|
Stating that it occurs at 5:00 PM PDT on the day before in the
|
||||||
|
summer, and 4:00 PM PST on the day before in the winter will just
|
||||||
|
confuse the issue.
|
||||||
|
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
-----
|
||||||
|
|
||||||
|
To see a list of system TimeZone IDs, use the TimeZone::create-
|
||||||
|
AvailableIDs() methods. Alternatively, look at the file
|
||||||
|
icu/docs/tz.htm. This has a hyperlinked list of current system zones.
|
||||||
|
|
||||||
|
|
||||||
|
ANSWERS
|
||||||
|
-------
|
||||||
|
|
||||||
|
The exercise includes answers. These are in the "answers" directory,
|
||||||
|
and are numbered 1, 2, etc.
|
||||||
|
|
||||||
|
If you get stuck and you want to move to the next step, copy the
|
||||||
|
answers file into the main directory in order to proceed. E.g.,
|
||||||
|
"main_1.cpp" contains the original "main.cpp" file. "main_2.cpp"
|
||||||
|
contains the "main.cpp" file after problem 1. Etc.
|
||||||
|
|
||||||
|
|
||||||
|
Have fun!
|
58
icu4c/source/samples/datefmt/answers/main_1.cpp
Normal file
58
icu4c/source/samples/datefmt/answers/main_1.cpp
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
#include "unicode/unistr.h"
|
||||||
|
#include "unicode/calendar.h"
|
||||||
|
#include "unicode/datefmt.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the ID supplied to TimeZone is not a valid system ID,
|
||||||
|
* TimeZone::createTimeZone() will return a GMT zone object. In order
|
||||||
|
* to detect this error, we check the ID of the returned zone against
|
||||||
|
* the ID we requested. If they don't match, we fail with an error.
|
||||||
|
*/
|
||||||
|
TimeZone* createZone(const UnicodeString& id) {
|
||||||
|
UnicodeString str;
|
||||||
|
TimeZone* zone = TimeZone::createTimeZone(id);
|
||||||
|
if (zone->getID(str) != id) {
|
||||||
|
delete zone;
|
||||||
|
printf("Error: TimeZone::createTimeZone(");
|
||||||
|
uprintf(id);
|
||||||
|
printf(") returned zone with ID ");
|
||||||
|
uprintf(str);
|
||||||
|
printf("\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
return zone;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
|
UnicodeString str;
|
||||||
|
|
||||||
|
// The languages in which we will display the date
|
||||||
|
static char* LANGUAGE[] = {
|
||||||
|
"en", "de", "fr"
|
||||||
|
};
|
||||||
|
static const int32_t N_LANGUAGE = sizeof(LANGUAGE)/sizeof(LANGUAGE[0]);
|
||||||
|
|
||||||
|
// The time zones in which we will display the time
|
||||||
|
static char* TIMEZONE[] = {
|
||||||
|
"America/Los_Angeles",
|
||||||
|
"America/New_York",
|
||||||
|
"Europe/Paris",
|
||||||
|
"Europe/Berlin"
|
||||||
|
};
|
||||||
|
static const int32_t N_TIMEZONE = sizeof(TIMEZONE)/sizeof(TIMEZONE[0]);
|
||||||
|
|
||||||
|
for (int32_t i=0; i<N_LANGUAGE; ++i) {
|
||||||
|
Locale loc(LANGUAGE[i]);
|
||||||
|
|
||||||
|
// Display the formatted date string
|
||||||
|
printf("Date (%s)\n", LANGUAGE[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Exiting successfully\n");
|
||||||
|
return 0;
|
||||||
|
}
|
81
icu4c/source/samples/datefmt/answers/main_2.cpp
Normal file
81
icu4c/source/samples/datefmt/answers/main_2.cpp
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
#include "unicode/unistr.h"
|
||||||
|
#include "unicode/calendar.h"
|
||||||
|
#include "unicode/datefmt.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the ID supplied to TimeZone is not a valid system ID,
|
||||||
|
* TimeZone::createTimeZone() will return a GMT zone object. In order
|
||||||
|
* to detect this error, we check the ID of the returned zone against
|
||||||
|
* the ID we requested. If they don't match, we fail with an error.
|
||||||
|
*/
|
||||||
|
TimeZone* createZone(const UnicodeString& id) {
|
||||||
|
UnicodeString str;
|
||||||
|
TimeZone* zone = TimeZone::createTimeZone(id);
|
||||||
|
if (zone->getID(str) != id) {
|
||||||
|
delete zone;
|
||||||
|
printf("Error: TimeZone::createTimeZone(");
|
||||||
|
uprintf(id);
|
||||||
|
printf(") returned zone with ID ");
|
||||||
|
uprintf(str);
|
||||||
|
printf("\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
return zone;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
|
Calendar *cal;
|
||||||
|
TimeZone *zone;
|
||||||
|
DateFormat *fmt;
|
||||||
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
|
UnicodeString str;
|
||||||
|
UDate date;
|
||||||
|
|
||||||
|
// The languages in which we will display the date
|
||||||
|
static char* LANGUAGE[] = {
|
||||||
|
"en", "de", "fr"
|
||||||
|
};
|
||||||
|
static const int32_t N_LANGUAGE = sizeof(LANGUAGE)/sizeof(LANGUAGE[0]);
|
||||||
|
|
||||||
|
// The time zones in which we will display the time
|
||||||
|
static char* TIMEZONE[] = {
|
||||||
|
"America/Los_Angeles",
|
||||||
|
"America/New_York",
|
||||||
|
"Europe/Paris",
|
||||||
|
"Europe/Berlin"
|
||||||
|
};
|
||||||
|
static const int32_t N_TIMEZONE = sizeof(TIMEZONE)/sizeof(TIMEZONE[0]);
|
||||||
|
|
||||||
|
// Create a calendar
|
||||||
|
cal = Calendar::createInstance(status);
|
||||||
|
check(status, "Calendar::createInstance");
|
||||||
|
zone = createZone("GMT"); // Create a GMT zone
|
||||||
|
cal->adoptTimeZone(zone);
|
||||||
|
cal->clear();
|
||||||
|
cal->set(1999, Calendar::JUNE, 4);
|
||||||
|
date = cal->getTime(status);
|
||||||
|
check(status, "Calendar::getTime");
|
||||||
|
|
||||||
|
for (int32_t i=0; i<N_LANGUAGE; ++i) {
|
||||||
|
Locale loc(LANGUAGE[i]);
|
||||||
|
|
||||||
|
// Create a formatter for DATE
|
||||||
|
fmt = DateFormat::createDateInstance(DateFormat::kFull, loc);
|
||||||
|
|
||||||
|
// Format the date
|
||||||
|
str.remove();
|
||||||
|
fmt->format(date, str, status);
|
||||||
|
|
||||||
|
// Display the formatted date string
|
||||||
|
printf("Date (%s): ", LANGUAGE[i]);
|
||||||
|
uprintf(escape(str));
|
||||||
|
printf("\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Exiting successfully\n");
|
||||||
|
return 0;
|
||||||
|
}
|
90
icu4c/source/samples/datefmt/answers/main_3.cpp
Normal file
90
icu4c/source/samples/datefmt/answers/main_3.cpp
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
#include "unicode/unistr.h"
|
||||||
|
#include "unicode/calendar.h"
|
||||||
|
#include "unicode/datefmt.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the ID supplied to TimeZone is not a valid system ID,
|
||||||
|
* TimeZone::createTimeZone() will return a GMT zone object. In order
|
||||||
|
* to detect this error, we check the ID of the returned zone against
|
||||||
|
* the ID we requested. If they don't match, we fail with an error.
|
||||||
|
*/
|
||||||
|
TimeZone* createZone(const UnicodeString& id) {
|
||||||
|
UnicodeString str;
|
||||||
|
TimeZone* zone = TimeZone::createTimeZone(id);
|
||||||
|
if (zone->getID(str) != id) {
|
||||||
|
delete zone;
|
||||||
|
printf("Error: TimeZone::createTimeZone(");
|
||||||
|
uprintf(id);
|
||||||
|
printf(") returned zone with ID ");
|
||||||
|
uprintf(str);
|
||||||
|
printf("\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
return zone;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
|
Calendar *cal;
|
||||||
|
TimeZone *zone;
|
||||||
|
DateFormat *fmt;
|
||||||
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
|
UnicodeString str;
|
||||||
|
UDate date;
|
||||||
|
|
||||||
|
// The languages in which we will display the date
|
||||||
|
static char* LANGUAGE[] = {
|
||||||
|
"en", "de", "fr"
|
||||||
|
};
|
||||||
|
static const int32_t N_LANGUAGE = sizeof(LANGUAGE)/sizeof(LANGUAGE[0]);
|
||||||
|
|
||||||
|
// The time zones in which we will display the time
|
||||||
|
static char* TIMEZONE[] = {
|
||||||
|
"America/Los_Angeles",
|
||||||
|
"America/New_York",
|
||||||
|
"Europe/Paris",
|
||||||
|
"Europe/Berlin"
|
||||||
|
};
|
||||||
|
static const int32_t N_TIMEZONE = sizeof(TIMEZONE)/sizeof(TIMEZONE[0]);
|
||||||
|
|
||||||
|
// Create a calendar
|
||||||
|
cal = Calendar::createInstance(status);
|
||||||
|
check(status, "Calendar::createInstance");
|
||||||
|
zone = createZone("GMT"); // Create a GMT zone
|
||||||
|
cal->adoptTimeZone(zone);
|
||||||
|
cal->clear();
|
||||||
|
cal->set(1999, Calendar::JUNE, 4);
|
||||||
|
date = cal->getTime(status);
|
||||||
|
check(status, "Calendar::getTime");
|
||||||
|
|
||||||
|
for (int32_t i=0; i<N_LANGUAGE; ++i) {
|
||||||
|
Locale loc(LANGUAGE[i]);
|
||||||
|
|
||||||
|
// Create a formatter for DATE and TIME
|
||||||
|
fmt = DateFormat::createDateTimeInstance(
|
||||||
|
DateFormat::kFull, DateFormat::kFull, loc);
|
||||||
|
|
||||||
|
for (int32_t j=0; j<N_TIMEZONE; ++j) {
|
||||||
|
|
||||||
|
cal->adoptTimeZone(createZone(TIMEZONE[j]));
|
||||||
|
fmt->setCalendar(*cal);
|
||||||
|
|
||||||
|
// Format the date
|
||||||
|
str.remove();
|
||||||
|
fmt->format(date, str, status);
|
||||||
|
|
||||||
|
// Display the formatted date string
|
||||||
|
printf("Date (%s, %s): ", LANGUAGE[i], TIMEZONE[j]);
|
||||||
|
uprintf(escape(str));
|
||||||
|
printf("\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
delete fmt;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Exiting successfully\n");
|
||||||
|
return 0;
|
||||||
|
}
|
106
icu4c/source/samples/datefmt/datefmt.dsp
Normal file
106
icu4c/source/samples/datefmt/datefmt.dsp
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
# Microsoft Developer Studio Project File - Name="datefmt" - Package Owner=<4>
|
||||||
|
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||||
|
# ** DO NOT EDIT **
|
||||||
|
|
||||||
|
# TARGTYPE "Win32 (x86) Console Application" 0x0103
|
||||||
|
|
||||||
|
CFG=datefmt - Win32 Debug
|
||||||
|
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||||
|
!MESSAGE use the Export Makefile command and run
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE NMAKE /f "datefmt.mak".
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE You can specify a configuration when running NMAKE
|
||||||
|
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE NMAKE /f "datefmt.mak" CFG="datefmt - Win32 Debug"
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE Possible choices for configuration are:
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE "datefmt - Win32 Release" (based on "Win32 (x86) Console Application")
|
||||||
|
!MESSAGE "datefmt - Win32 Debug" (based on "Win32 (x86) Console Application")
|
||||||
|
!MESSAGE
|
||||||
|
|
||||||
|
# Begin Project
|
||||||
|
# PROP AllowPerConfigDependencies 0
|
||||||
|
# PROP Scc_ProjName ""
|
||||||
|
# PROP Scc_LocalPath ""
|
||||||
|
CPP=cl.exe
|
||||||
|
RSC=rc.exe
|
||||||
|
|
||||||
|
!IF "$(CFG)" == "datefmt - Win32 Release"
|
||||||
|
|
||||||
|
# PROP BASE Use_MFC 0
|
||||||
|
# PROP BASE Use_Debug_Libraries 0
|
||||||
|
# PROP BASE Output_Dir "Release"
|
||||||
|
# PROP BASE Intermediate_Dir "Release"
|
||||||
|
# PROP BASE Target_Dir ""
|
||||||
|
# PROP Use_MFC 0
|
||||||
|
# PROP Use_Debug_Libraries 0
|
||||||
|
# PROP Output_Dir "Release"
|
||||||
|
# PROP Intermediate_Dir "Release"
|
||||||
|
# PROP Ignore_Export_Lib 0
|
||||||
|
# PROP Target_Dir ""
|
||||||
|
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||||
|
# ADD CPP /nologo /W3 /GX /O2 /I "..\..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||||
|
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||||
|
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||||
|
BSC32=bscmake.exe
|
||||||
|
# ADD BASE BSC32 /nologo
|
||||||
|
# ADD BSC32 /nologo
|
||||||
|
LINK32=link.exe
|
||||||
|
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||||
|
# ADD LINK32 icuuc.lib icui18n.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\lib\Release"
|
||||||
|
|
||||||
|
!ELSEIF "$(CFG)" == "datefmt - Win32 Debug"
|
||||||
|
|
||||||
|
# PROP BASE Use_MFC 0
|
||||||
|
# PROP BASE Use_Debug_Libraries 1
|
||||||
|
# PROP BASE Output_Dir "Debug"
|
||||||
|
# PROP BASE Intermediate_Dir "Debug"
|
||||||
|
# PROP BASE Target_Dir ""
|
||||||
|
# PROP Use_MFC 0
|
||||||
|
# PROP Use_Debug_Libraries 1
|
||||||
|
# PROP Output_Dir "Debug"
|
||||||
|
# PROP Intermediate_Dir "Debug"
|
||||||
|
# PROP Ignore_Export_Lib 0
|
||||||
|
# PROP Target_Dir ""
|
||||||
|
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||||
|
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||||
|
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||||
|
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||||
|
BSC32=bscmake.exe
|
||||||
|
# ADD BASE BSC32 /nologo
|
||||||
|
# ADD BSC32 /nologo
|
||||||
|
LINK32=link.exe
|
||||||
|
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||||
|
# ADD LINK32 icuuc.lib icui18n.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\lib\Debug"
|
||||||
|
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# Begin Target
|
||||||
|
|
||||||
|
# Name "datefmt - Win32 Release"
|
||||||
|
# Name "datefmt - Win32 Debug"
|
||||||
|
# Begin Group "Source Files"
|
||||||
|
|
||||||
|
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\main.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\util.cpp
|
||||||
|
# End Source File
|
||||||
|
# End Group
|
||||||
|
# Begin Group "Header Files"
|
||||||
|
|
||||||
|
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||||
|
# End Group
|
||||||
|
# Begin Group "Resource Files"
|
||||||
|
|
||||||
|
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||||
|
# End Group
|
||||||
|
# End Target
|
||||||
|
# End Project
|
29
icu4c/source/samples/datefmt/datefmt.dsw
Normal file
29
icu4c/source/samples/datefmt/datefmt.dsw
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||||
|
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
Project: "datefmt"=.\datefmt.dsp - Package Owner=<4>
|
||||||
|
|
||||||
|
Package=<5>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
Package=<4>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
Global:
|
||||||
|
|
||||||
|
Package=<5>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
Package=<3>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
58
icu4c/source/samples/datefmt/main.cpp
Normal file
58
icu4c/source/samples/datefmt/main.cpp
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
#include "unicode/unistr.h"
|
||||||
|
#include "unicode/calendar.h"
|
||||||
|
#include "unicode/datefmt.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the ID supplied to TimeZone is not a valid system ID,
|
||||||
|
* TimeZone::createTimeZone() will return a GMT zone object. In order
|
||||||
|
* to detect this error, we check the ID of the returned zone against
|
||||||
|
* the ID we requested. If they don't match, we fail with an error.
|
||||||
|
*/
|
||||||
|
TimeZone* createZone(const UnicodeString& id) {
|
||||||
|
UnicodeString str;
|
||||||
|
TimeZone* zone = TimeZone::createTimeZone(id);
|
||||||
|
if (zone->getID(str) != id) {
|
||||||
|
delete zone;
|
||||||
|
printf("Error: TimeZone::createTimeZone(");
|
||||||
|
uprintf(id);
|
||||||
|
printf(") returned zone with ID ");
|
||||||
|
uprintf(str);
|
||||||
|
printf("\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
return zone;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
|
UnicodeString str;
|
||||||
|
|
||||||
|
// The languages in which we will display the date
|
||||||
|
static char* LANGUAGE[] = {
|
||||||
|
"en", "de", "fr"
|
||||||
|
};
|
||||||
|
static const int32_t N_LANGUAGE = sizeof(LANGUAGE)/sizeof(LANGUAGE[0]);
|
||||||
|
|
||||||
|
// The time zones in which we will display the time
|
||||||
|
static char* TIMEZONE[] = {
|
||||||
|
"America/Los_Angeles",
|
||||||
|
"America/New_York",
|
||||||
|
"Europe/Paris",
|
||||||
|
"Europe/Berlin"
|
||||||
|
};
|
||||||
|
static const int32_t N_TIMEZONE = sizeof(TIMEZONE)/sizeof(TIMEZONE[0]);
|
||||||
|
|
||||||
|
for (int32_t i=0; i<N_LANGUAGE; ++i) {
|
||||||
|
Locale loc(LANGUAGE[i]);
|
||||||
|
|
||||||
|
// Display the formatted date string
|
||||||
|
printf("Date (%s)\n", LANGUAGE[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Exiting successfully\n");
|
||||||
|
return 0;
|
||||||
|
}
|
57
icu4c/source/samples/datefmt/util.cpp
Normal file
57
icu4c/source/samples/datefmt/util.cpp
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#include "unicode/unistr.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
// Verify that a UErrorCode is successful; exit(1) if not
|
||||||
|
void check(UErrorCode& status, const char* msg) {
|
||||||
|
if (U_FAILURE(status)) {
|
||||||
|
printf("ERROR: %s (%s)\n", u_errorName(status), msg);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
// printf("Ok: %s\n", msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append a hex string to the target
|
||||||
|
static UnicodeString& appendHex(uint32_t number,
|
||||||
|
int8_t digits,
|
||||||
|
UnicodeString& target) {
|
||||||
|
static const UnicodeString DIGIT_STRING("0123456789ABCDEF");
|
||||||
|
while (digits > 0) {
|
||||||
|
target += DIGIT_STRING[(number >> ((--digits) * 4)) & 0xF];
|
||||||
|
}
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace nonprintable characters with unicode escapes
|
||||||
|
UnicodeString escape(const UnicodeString &source) {
|
||||||
|
int32_t i;
|
||||||
|
UnicodeString target;
|
||||||
|
target += "\"";
|
||||||
|
for (i=0; i<source.length(); ++i) {
|
||||||
|
UChar ch = source[i];
|
||||||
|
if (ch < 0x09 || (ch > 0x0A && ch < 0x20) || ch > 0x7E) {
|
||||||
|
target += "\\u";
|
||||||
|
appendHex(ch, 4, target);
|
||||||
|
} else {
|
||||||
|
target += ch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
target += "\"";
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print the given string to stdout
|
||||||
|
void uprintf(const UnicodeString &str) {
|
||||||
|
char *buf = 0;
|
||||||
|
int32_t len = str.length();
|
||||||
|
// int32_t bufLen = str.extract(0, len, buf); // Preflight
|
||||||
|
/* Preflighting seems to be broken now, so assume 1-1 conversion,
|
||||||
|
plus some slop. */
|
||||||
|
int32_t bufLen = len + 16;
|
||||||
|
int32_t actualLen;
|
||||||
|
buf = new char[bufLen + 1];
|
||||||
|
actualLen = str.extract(0, len, buf/*, bufLen*/); // Default codepage conversion
|
||||||
|
buf[actualLen] = 0;
|
||||||
|
printf("%s", buf);
|
||||||
|
delete buf;
|
||||||
|
}
|
10
icu4c/source/samples/datefmt/util.h
Normal file
10
icu4c/source/samples/datefmt/util.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#include "unicode/unistr.h"
|
||||||
|
|
||||||
|
// Verify that a UErrorCode is successful; exit(1) if not
|
||||||
|
void check(UErrorCode& status, const char* msg);
|
||||||
|
|
||||||
|
// Replace nonprintable characters with unicode escapes
|
||||||
|
UnicodeString escape(const UnicodeString &source);
|
||||||
|
|
||||||
|
// Print the given string to stdout
|
||||||
|
void uprintf(const UnicodeString &str);
|
90
icu4c/source/samples/msgfmt/README.TXT
Normal file
90
icu4c/source/samples/msgfmt/README.TXT
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
This is an exercise for the ICU Workshop (September 2000).
|
||||||
|
|
||||||
|
Day 2: September 12th 2000
|
||||||
|
Pre-requsit:
|
||||||
|
1. All the hardware and software requirements from Day 1.
|
||||||
|
2. Attended or fully understand Day 1 material.
|
||||||
|
3. Read through the ICU user's guide at
|
||||||
|
http://oss.software.ibm.com/icu/userguide/.
|
||||||
|
|
||||||
|
#Date/Time/Number Formatting Support
|
||||||
|
9:30am - 10:30am
|
||||||
|
Alan Liu
|
||||||
|
|
||||||
|
Topics:
|
||||||
|
1. What is the date/time support in ICU?
|
||||||
|
2. What is the timezone support in ICU?
|
||||||
|
3. What kind of formatting and parsing support is available in ICU, i.e.
|
||||||
|
NumberFormat, DateFormat, MessageFormat?
|
||||||
|
|
||||||
|
|
||||||
|
INSTRUCTIONS
|
||||||
|
------------
|
||||||
|
|
||||||
|
This exercise was developed and tested on ICU release 1.6.0, Win32,
|
||||||
|
Microsoft Visual C++ 6.0. It should work on other ICU releases and
|
||||||
|
other platforms as well, but the user will have to develop makefiles.
|
||||||
|
|
||||||
|
To install: Create a folder "datefmt" at:
|
||||||
|
|
||||||
|
<icu>/source/samples/msgfmt
|
||||||
|
|
||||||
|
Within it, place the files:
|
||||||
|
|
||||||
|
msgfmt.dsp
|
||||||
|
msgfmt.dsw
|
||||||
|
main.cpp
|
||||||
|
util.cpp
|
||||||
|
util.h
|
||||||
|
|
||||||
|
Open the file "msgfmt.dsw" in Microsoft Visual C++.
|
||||||
|
|
||||||
|
|
||||||
|
PROBLEMS
|
||||||
|
--------
|
||||||
|
|
||||||
|
Problem 0:
|
||||||
|
|
||||||
|
Set up the program, build it, and run it. To start with, the
|
||||||
|
program prints out the word "Message".
|
||||||
|
|
||||||
|
Problem 1: Basic Message Formatting (Easy)
|
||||||
|
|
||||||
|
Use a MessageFormat to create a message that prints out "Received
|
||||||
|
<n> argument(s) on <d>.", where n is the number of command line
|
||||||
|
arguments (use argc-1), and d is the date (use Calendar::getNow()).
|
||||||
|
|
||||||
|
HINT: Your message pattern should have a "number" element and a
|
||||||
|
"date" element, and you will need to use Formattable.
|
||||||
|
|
||||||
|
Problem 2: ChoiceFormat (Medium)
|
||||||
|
|
||||||
|
We can do better than "argument(s)". Instead, we can display more
|
||||||
|
idiomatic strings, such as "no arguments", "one argument", "two
|
||||||
|
arguments", and for higher values, we can use a number format.
|
||||||
|
|
||||||
|
This kind of value-based switching is done using a ChoiceFormat.
|
||||||
|
However, you seldom needs to create a ChoiceFormat by itself.
|
||||||
|
Instead, most of the time you will supply the ChoiceFormat pattern
|
||||||
|
within a MessageFormat pattern.
|
||||||
|
|
||||||
|
Use a ChoiceFormat pattern within the MessageFormat pattern, instead
|
||||||
|
of the "number" element, to display more idiomatic strings.
|
||||||
|
|
||||||
|
EXTRA: Embed a number element within the choice element to handle
|
||||||
|
values greater than two.
|
||||||
|
|
||||||
|
|
||||||
|
ANSWERS
|
||||||
|
-------
|
||||||
|
|
||||||
|
The exercise includes answers. These are in the "answers" directory,
|
||||||
|
and are numbered 1, 2, etc.
|
||||||
|
|
||||||
|
If you get stuck and you want to move to the next step, copy the
|
||||||
|
answers file into the main directory in order to proceed. E.g.,
|
||||||
|
"main_1.cpp" contains the original "main.cpp" file. "main_2.cpp"
|
||||||
|
contains the "main.cpp" file after problem 1. Etc.
|
||||||
|
|
||||||
|
|
||||||
|
Have fun!
|
18
icu4c/source/samples/msgfmt/answers/main_1.cpp
Normal file
18
icu4c/source/samples/msgfmt/answers/main_1.cpp
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#include "unicode/unistr.h"
|
||||||
|
#include "unicode/msgfmt.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
|
UnicodeString str;
|
||||||
|
|
||||||
|
printf("Message: ");
|
||||||
|
uprintf(str);
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
printf("Exiting successfully\n");
|
||||||
|
return 0;
|
||||||
|
}
|
40
icu4c/source/samples/msgfmt/answers/main_2.cpp
Normal file
40
icu4c/source/samples/msgfmt/answers/main_2.cpp
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#include "unicode/unistr.h"
|
||||||
|
#include "unicode/msgfmt.h"
|
||||||
|
#include "unicode/calendar.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
// The message format pattern. It takes a single argument, an integer,
|
||||||
|
// and formats it as "no", "one", or a number, using a NumberFormat.
|
||||||
|
static UnicodeString PATTERN(
|
||||||
|
"Received {0,choice,0#no|1#one|1& {0,number,integer}} arguments"
|
||||||
|
" on {1,date,long}."
|
||||||
|
);
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
|
UnicodeString str;
|
||||||
|
FieldPosition pos;
|
||||||
|
|
||||||
|
// Create a message format
|
||||||
|
MessageFormat msg(PATTERN, status);
|
||||||
|
check(status, "MessageFormat::ct");
|
||||||
|
|
||||||
|
// Create the argument list
|
||||||
|
Formattable msgArgs[2];
|
||||||
|
msgArgs[0].setLong(argc-1);
|
||||||
|
msgArgs[1].setDate(Calendar::getNow());
|
||||||
|
|
||||||
|
// Format the arguments
|
||||||
|
msg.format(msgArgs, 2, str, pos, status);
|
||||||
|
check(status, "MessageFormat::format");
|
||||||
|
|
||||||
|
printf("Message: ");
|
||||||
|
uprintf(str);
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
printf("Exiting successfully\n");
|
||||||
|
return 0;
|
||||||
|
}
|
40
icu4c/source/samples/msgfmt/answers/main_3.cpp
Normal file
40
icu4c/source/samples/msgfmt/answers/main_3.cpp
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#include "unicode/unistr.h"
|
||||||
|
#include "unicode/msgfmt.h"
|
||||||
|
#include "unicode/calendar.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
// The message format pattern. It takes a single argument, an integer,
|
||||||
|
// and formats it as "no", "one", or a number, using a NumberFormat.
|
||||||
|
static UnicodeString PATTERN(
|
||||||
|
"Received {0,choice,0#no arguments|1#one argument|2#{0,number,integer} arguments}"
|
||||||
|
" on {1,date,long}."
|
||||||
|
);
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
|
UnicodeString str;
|
||||||
|
FieldPosition pos;
|
||||||
|
|
||||||
|
// Create a message format
|
||||||
|
MessageFormat msg(PATTERN, status);
|
||||||
|
check(status, "MessageFormat::ct");
|
||||||
|
|
||||||
|
// Create the argument list
|
||||||
|
Formattable msgArgs[2];
|
||||||
|
msgArgs[0].setLong(argc-1);
|
||||||
|
msgArgs[1].setDate(Calendar::getNow());
|
||||||
|
|
||||||
|
// Format the arguments
|
||||||
|
msg.format(msgArgs, 2, str, pos, status);
|
||||||
|
check(status, "MessageFormat::format");
|
||||||
|
|
||||||
|
printf("Message: ");
|
||||||
|
uprintf(str);
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
printf("Exiting successfully\n");
|
||||||
|
return 0;
|
||||||
|
}
|
18
icu4c/source/samples/msgfmt/main.cpp
Normal file
18
icu4c/source/samples/msgfmt/main.cpp
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#include "unicode/unistr.h"
|
||||||
|
#include "unicode/msgfmt.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
|
UnicodeString str;
|
||||||
|
|
||||||
|
printf("Message: ");
|
||||||
|
uprintf(str);
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
printf("Exiting successfully\n");
|
||||||
|
return 0;
|
||||||
|
}
|
104
icu4c/source/samples/msgfmt/msgfmt.dsp
Normal file
104
icu4c/source/samples/msgfmt/msgfmt.dsp
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
# Microsoft Developer Studio Project File - Name="msgfmt" - Package Owner=<4>
|
||||||
|
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||||
|
# ** DO NOT EDIT **
|
||||||
|
|
||||||
|
# TARGTYPE "Win32 (x86) Console Application" 0x0103
|
||||||
|
|
||||||
|
CFG=msgfmt - Win32 Debug
|
||||||
|
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||||
|
!MESSAGE use the Export Makefile command and run
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE NMAKE /f "msgfmt.mak".
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE You can specify a configuration when running NMAKE
|
||||||
|
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE NMAKE /f "msgfmt.mak" CFG="msgfmt - Win32 Debug"
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE Possible choices for configuration are:
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE "msgfmt - Win32 Release" (based on "Win32 (x86) Console Application")
|
||||||
|
!MESSAGE "msgfmt - Win32 Debug" (based on "Win32 (x86) Console Application")
|
||||||
|
!MESSAGE
|
||||||
|
|
||||||
|
# Begin Project
|
||||||
|
# PROP AllowPerConfigDependencies 0
|
||||||
|
# PROP Scc_ProjName ""
|
||||||
|
# PROP Scc_LocalPath ""
|
||||||
|
CPP=cl.exe
|
||||||
|
RSC=rc.exe
|
||||||
|
|
||||||
|
!IF "$(CFG)" == "msgfmt - Win32 Release"
|
||||||
|
|
||||||
|
# PROP BASE Use_MFC 0
|
||||||
|
# PROP BASE Use_Debug_Libraries 0
|
||||||
|
# PROP BASE Output_Dir "Release"
|
||||||
|
# PROP BASE Intermediate_Dir "Release"
|
||||||
|
# PROP BASE Target_Dir ""
|
||||||
|
# PROP Use_MFC 0
|
||||||
|
# PROP Use_Debug_Libraries 0
|
||||||
|
# PROP Output_Dir "Release"
|
||||||
|
# PROP Intermediate_Dir "Release"
|
||||||
|
# PROP Target_Dir ""
|
||||||
|
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||||
|
# ADD CPP /nologo /W3 /GX /O2 /I "..\..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||||
|
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||||
|
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||||
|
BSC32=bscmake.exe
|
||||||
|
# ADD BASE BSC32 /nologo
|
||||||
|
# ADD BSC32 /nologo
|
||||||
|
LINK32=link.exe
|
||||||
|
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||||
|
# ADD LINK32 icuuc.lib icui18n.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\lib\Release"
|
||||||
|
|
||||||
|
!ELSEIF "$(CFG)" == "msgfmt - Win32 Debug"
|
||||||
|
|
||||||
|
# PROP BASE Use_MFC 0
|
||||||
|
# PROP BASE Use_Debug_Libraries 1
|
||||||
|
# PROP BASE Output_Dir "Debug"
|
||||||
|
# PROP BASE Intermediate_Dir "Debug"
|
||||||
|
# PROP BASE Target_Dir ""
|
||||||
|
# PROP Use_MFC 0
|
||||||
|
# PROP Use_Debug_Libraries 1
|
||||||
|
# PROP Output_Dir "Debug"
|
||||||
|
# PROP Intermediate_Dir "Debug"
|
||||||
|
# PROP Target_Dir ""
|
||||||
|
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||||
|
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||||
|
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||||
|
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||||
|
BSC32=bscmake.exe
|
||||||
|
# ADD BASE BSC32 /nologo
|
||||||
|
# ADD BSC32 /nologo
|
||||||
|
LINK32=link.exe
|
||||||
|
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||||
|
# ADD LINK32 icuuc.lib icui18n.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\lib\Debug"
|
||||||
|
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# Begin Target
|
||||||
|
|
||||||
|
# Name "msgfmt - Win32 Release"
|
||||||
|
# Name "msgfmt - Win32 Debug"
|
||||||
|
# Begin Group "Source Files"
|
||||||
|
|
||||||
|
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\main.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\util.cpp
|
||||||
|
# End Source File
|
||||||
|
# End Group
|
||||||
|
# Begin Group "Header Files"
|
||||||
|
|
||||||
|
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||||
|
# End Group
|
||||||
|
# Begin Group "Resource Files"
|
||||||
|
|
||||||
|
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||||
|
# End Group
|
||||||
|
# End Target
|
||||||
|
# End Project
|
29
icu4c/source/samples/msgfmt/msgfmt.dsw
Normal file
29
icu4c/source/samples/msgfmt/msgfmt.dsw
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||||
|
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
Project: "msgfmt"=.\msgfmt.dsp - Package Owner=<4>
|
||||||
|
|
||||||
|
Package=<5>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
Package=<4>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
Global:
|
||||||
|
|
||||||
|
Package=<5>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
Package=<3>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
57
icu4c/source/samples/msgfmt/util.cpp
Normal file
57
icu4c/source/samples/msgfmt/util.cpp
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#include "unicode/unistr.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
// Verify that a UErrorCode is successful; exit(1) if not
|
||||||
|
void check(UErrorCode& status, const char* msg) {
|
||||||
|
if (U_FAILURE(status)) {
|
||||||
|
printf("ERROR: %s (%s)\n", u_errorName(status), msg);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
// printf("Ok: %s\n", msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append a hex string to the target
|
||||||
|
static UnicodeString& appendHex(uint32_t number,
|
||||||
|
int8_t digits,
|
||||||
|
UnicodeString& target) {
|
||||||
|
static const UnicodeString DIGIT_STRING("0123456789ABCDEF");
|
||||||
|
while (digits > 0) {
|
||||||
|
target += DIGIT_STRING[(number >> ((--digits) * 4)) & 0xF];
|
||||||
|
}
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace nonprintable characters with unicode escapes
|
||||||
|
UnicodeString escape(const UnicodeString &source) {
|
||||||
|
int32_t i;
|
||||||
|
UnicodeString target;
|
||||||
|
target += "\"";
|
||||||
|
for (i=0; i<source.length(); ++i) {
|
||||||
|
UChar ch = source[i];
|
||||||
|
if (ch < 0x09 || (ch > 0x0A && ch < 0x20) || ch > 0x7E) {
|
||||||
|
target += "\\u";
|
||||||
|
appendHex(ch, 4, target);
|
||||||
|
} else {
|
||||||
|
target += ch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
target += "\"";
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print the given string to stdout
|
||||||
|
void uprintf(const UnicodeString &str) {
|
||||||
|
char *buf = 0;
|
||||||
|
int32_t len = str.length();
|
||||||
|
// int32_t bufLen = str.extract(0, len, buf); // Preflight
|
||||||
|
/* Preflighting seems to be broken now, so assume 1-1 conversion,
|
||||||
|
plus some slop. */
|
||||||
|
int32_t bufLen = len + 16;
|
||||||
|
int32_t actualLen;
|
||||||
|
buf = new char[bufLen + 1];
|
||||||
|
actualLen = str.extract(0, len, buf/*, bufLen*/); // Default codepage conversion
|
||||||
|
buf[actualLen] = 0;
|
||||||
|
printf("%s", buf);
|
||||||
|
delete buf;
|
||||||
|
}
|
10
icu4c/source/samples/msgfmt/util.h
Normal file
10
icu4c/source/samples/msgfmt/util.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#include "unicode/unistr.h"
|
||||||
|
|
||||||
|
// Verify that a UErrorCode is successful; exit(1) if not
|
||||||
|
void check(UErrorCode& status, const char* msg);
|
||||||
|
|
||||||
|
// Replace nonprintable characters with unicode escapes
|
||||||
|
UnicodeString escape(const UnicodeString &source);
|
||||||
|
|
||||||
|
// Print the given string to stdout
|
||||||
|
void uprintf(const UnicodeString &str);
|
104
icu4c/source/samples/translit/README.TXT
Normal file
104
icu4c/source/samples/translit/README.TXT
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
This is an exercise for the ICU Workshop (September 2000).
|
||||||
|
|
||||||
|
Day 2: September 12th 2000
|
||||||
|
Pre-requisite:
|
||||||
|
1. All the hardware and software requirements from Day 1.
|
||||||
|
2. Attended or fully understand Day 1 material.
|
||||||
|
3. Read through the ICU user's guide at
|
||||||
|
http://oss.software.ibm.com/icu/userguide/.
|
||||||
|
|
||||||
|
#Transformation Support
|
||||||
|
10:45am - 12:00pm
|
||||||
|
Alan Liu
|
||||||
|
|
||||||
|
Topics:
|
||||||
|
1. What is the Unicode normalization?
|
||||||
|
2. What kind of case mapping support is available in ICU?
|
||||||
|
3. What is Transliteration and how do I use a Transliterator on a document?
|
||||||
|
4. How do I add my own Transliterator?
|
||||||
|
|
||||||
|
|
||||||
|
INSTRUCTIONS
|
||||||
|
------------
|
||||||
|
|
||||||
|
This exercise was developed and tested on ICU release 1.6.0, Win32,
|
||||||
|
Microsoft Visual C++ 6.0. It should work on other ICU releases and
|
||||||
|
other platforms as well, but the user will have to develop makefiles.
|
||||||
|
|
||||||
|
To install: Create a folder "translit" at:
|
||||||
|
|
||||||
|
<icu>/source/samples/translit
|
||||||
|
|
||||||
|
Within it, place the files:
|
||||||
|
|
||||||
|
translit.dsp
|
||||||
|
translit.dsw
|
||||||
|
main.cpp
|
||||||
|
util.cpp
|
||||||
|
util.h
|
||||||
|
|
||||||
|
Open the file "translit.dsw" in Microsoft Visual C++.
|
||||||
|
|
||||||
|
|
||||||
|
PROBLEMS
|
||||||
|
--------
|
||||||
|
|
||||||
|
Problem 0:
|
||||||
|
|
||||||
|
To start with, the program prints out a series of dates formatted in
|
||||||
|
Greek. Set up the program, build it, and run it.
|
||||||
|
|
||||||
|
Problem 1: Basic Transliterator (Easy)
|
||||||
|
|
||||||
|
The Greek text shows up almost entirely as Unicode escapes. These
|
||||||
|
are unreadable on a US machine. Use an existing system
|
||||||
|
transliterator to transliterate the Greek text to Latin so it can be
|
||||||
|
phonetically read on a US machine. If you don't know the names of
|
||||||
|
the system transliterators, use Transliterator::getAvailableID() and
|
||||||
|
Transliterator::countAvailableIDs(), or look directly in the index
|
||||||
|
table icu/data/translit_index.txt.
|
||||||
|
|
||||||
|
Problem 2: RuleBasedTransliterator (Medium)
|
||||||
|
|
||||||
|
Some of the text is still unreadable and shows up as Unicode escape
|
||||||
|
sequences. Create a RuleBasedTransliterator to change the
|
||||||
|
unreadable characters to close ASCII equivalents. For example, the
|
||||||
|
rule "\u00C0 > A;" will change an 'A' with a grave accent to a plain
|
||||||
|
'A'.
|
||||||
|
|
||||||
|
To save typing, use UnicodeSets to handle ranges of characters.
|
||||||
|
|
||||||
|
See the included file "U0080.pdf" for a table of the U+00C0 to U+00FF
|
||||||
|
Unicode block.
|
||||||
|
|
||||||
|
Problem 3: Transliterator subclassing; Normalizer (Difficult)
|
||||||
|
|
||||||
|
The rule-based approach is flexible and, in most cases, the best
|
||||||
|
choice for creating a new transliterator. Sometimes, however, a
|
||||||
|
more elegant algorithmic solution is available. Instead of typing
|
||||||
|
in a list of rules, you can write C++ code to accomplish the desired
|
||||||
|
transliteration.
|
||||||
|
|
||||||
|
Use a Normalizer to remove accents from characters. You will need
|
||||||
|
to convert each character to a sequence of base and combining
|
||||||
|
characters by applying a canonical denormalization transformation.
|
||||||
|
Then discard the combining characters (the accents etc.) leaving the
|
||||||
|
base character. Wrap this all up in a subclass of the
|
||||||
|
Transliterator class that overrides the pure virtual
|
||||||
|
handleTransliterate() method.
|
||||||
|
|
||||||
|
|
||||||
|
ANSWERS
|
||||||
|
-------
|
||||||
|
|
||||||
|
The exercise includes answers. These are in the "answers" directory,
|
||||||
|
and are numbered 1, 2, etc. In some cases new files that the user
|
||||||
|
needs to create are included in the answers directory.
|
||||||
|
|
||||||
|
If you get stuck and you want to move to the next step, copy the
|
||||||
|
answers file into the main directory in order to proceed. E.g.,
|
||||||
|
"main_1.cpp" contains the original "main.cpp" file. "main_2.cpp"
|
||||||
|
contains the "main.cpp" file after problem 1. Etc.
|
||||||
|
|
||||||
|
|
||||||
|
Have fun!
|
BIN
icu4c/source/samples/translit/U0080.pdf
Normal file
BIN
icu4c/source/samples/translit/U0080.pdf
Normal file
Binary file not shown.
64
icu4c/source/samples/translit/answers/main_1.cpp
Normal file
64
icu4c/source/samples/translit/answers/main_1.cpp
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
#include "unicode/translit.h"
|
||||||
|
#include "unicode/rbt.h"
|
||||||
|
#include "unicode/unistr.h"
|
||||||
|
#include "unicode/calendar.h"
|
||||||
|
#include "unicode/datefmt.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "util.h"
|
||||||
|
#include "unaccent.h"
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
|
Calendar *cal;
|
||||||
|
DateFormat *fmt;
|
||||||
|
DateFormat *defFmt;
|
||||||
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
|
Locale greece("el", "GR");
|
||||||
|
UnicodeString str, str2;
|
||||||
|
|
||||||
|
// Create a calendar in the Greek locale
|
||||||
|
cal = Calendar::createInstance(greece, status);
|
||||||
|
check(status, "Calendar::createInstance");
|
||||||
|
|
||||||
|
// Create a formatter
|
||||||
|
fmt = DateFormat::createDateInstance(DateFormat::kFull, greece);
|
||||||
|
fmt->setCalendar(*cal);
|
||||||
|
|
||||||
|
// Create a default formatter
|
||||||
|
defFmt = DateFormat::createDateInstance(DateFormat::kFull);
|
||||||
|
defFmt->setCalendar(*cal);
|
||||||
|
|
||||||
|
// Loop over various months
|
||||||
|
for (int32_t month = Calendar::JANUARY;
|
||||||
|
month <= Calendar::DECEMBER;
|
||||||
|
++month) {
|
||||||
|
|
||||||
|
// Set the calendar to a date
|
||||||
|
cal->clear();
|
||||||
|
cal->set(1999, month, 4);
|
||||||
|
|
||||||
|
// Format the date in default locale
|
||||||
|
str.remove();
|
||||||
|
defFmt->format(cal->getTime(status), str, status);
|
||||||
|
check(status, "DateFormat::format");
|
||||||
|
printf("Date: ");
|
||||||
|
uprintf(escape(str));
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
// Format the date for Greece
|
||||||
|
str.remove();
|
||||||
|
fmt->format(cal->getTime(status), str, status);
|
||||||
|
check(status, "DateFormat::format");
|
||||||
|
printf("Greek formatted date: ");
|
||||||
|
uprintf(escape(str));
|
||||||
|
printf("\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
delete fmt;
|
||||||
|
delete cal;
|
||||||
|
|
||||||
|
printf("Exiting successfully\n");
|
||||||
|
return 0;
|
||||||
|
}
|
79
icu4c/source/samples/translit/answers/main_2.cpp
Normal file
79
icu4c/source/samples/translit/answers/main_2.cpp
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
#include "unicode/translit.h"
|
||||||
|
#include "unicode/rbt.h"
|
||||||
|
#include "unicode/unistr.h"
|
||||||
|
#include "unicode/calendar.h"
|
||||||
|
#include "unicode/datefmt.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "util.h"
|
||||||
|
#include "unaccent.h"
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
|
Calendar *cal;
|
||||||
|
DateFormat *fmt;
|
||||||
|
DateFormat *defFmt;
|
||||||
|
Transliterator *greek_latin;
|
||||||
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
|
Locale greece("el", "GR");
|
||||||
|
UnicodeString str, str2;
|
||||||
|
|
||||||
|
// Create a calendar in the Greek locale
|
||||||
|
cal = Calendar::createInstance(greece, status);
|
||||||
|
check(status, "Calendar::createInstance");
|
||||||
|
|
||||||
|
// Create a formatter
|
||||||
|
fmt = DateFormat::createDateInstance(DateFormat::kFull, greece);
|
||||||
|
fmt->setCalendar(*cal);
|
||||||
|
|
||||||
|
// Create a default formatter
|
||||||
|
defFmt = DateFormat::createDateInstance(DateFormat::kFull);
|
||||||
|
defFmt->setCalendar(*cal);
|
||||||
|
|
||||||
|
// Create a Greek-Latin Transliterator
|
||||||
|
greek_latin = Transliterator::createInstance("Greek-Latin");
|
||||||
|
if (greek_latin == 0) {
|
||||||
|
printf("ERROR: Transliterator::createInstance() failed\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loop over various months
|
||||||
|
for (int32_t month = Calendar::JANUARY;
|
||||||
|
month <= Calendar::DECEMBER;
|
||||||
|
++month) {
|
||||||
|
|
||||||
|
// Set the calendar to a date
|
||||||
|
cal->clear();
|
||||||
|
cal->set(1999, month, 4);
|
||||||
|
|
||||||
|
// Format the date in default locale
|
||||||
|
str.remove();
|
||||||
|
defFmt->format(cal->getTime(status), str, status);
|
||||||
|
check(status, "DateFormat::format");
|
||||||
|
printf("Date: ");
|
||||||
|
uprintf(escape(str));
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
// Format the date for Greece
|
||||||
|
str.remove();
|
||||||
|
fmt->format(cal->getTime(status), str, status);
|
||||||
|
check(status, "DateFormat::format");
|
||||||
|
printf("Greek formatted date: ");
|
||||||
|
uprintf(escape(str));
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
// Transliterate result
|
||||||
|
greek_latin->transliterate(str);
|
||||||
|
printf("Transliterated via Greek-Latin: ");
|
||||||
|
uprintf(escape(str));
|
||||||
|
printf("\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
delete fmt;
|
||||||
|
delete cal;
|
||||||
|
delete greek_latin;
|
||||||
|
|
||||||
|
printf("Exiting successfully\n");
|
||||||
|
return 0;
|
||||||
|
}
|
106
icu4c/source/samples/translit/answers/main_3.cpp
Normal file
106
icu4c/source/samples/translit/answers/main_3.cpp
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
#include "unicode/translit.h"
|
||||||
|
#include "unicode/rbt.h"
|
||||||
|
#include "unicode/unistr.h"
|
||||||
|
#include "unicode/calendar.h"
|
||||||
|
#include "unicode/datefmt.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "util.h"
|
||||||
|
#include "unaccent.h"
|
||||||
|
|
||||||
|
// RuleBasedTransliterator rules to remove accents from characters
|
||||||
|
// so they can be displayed as ASCIIx
|
||||||
|
UnicodeString UNACCENT_RULES(
|
||||||
|
"[\\u00C0-\\u00C5] > A;"
|
||||||
|
"[\\u00C8-\\u00CB] > E;"
|
||||||
|
"[\\u00CC-\\u00CF] > I;"
|
||||||
|
"[\\u00E0-\\u00E5] > a;"
|
||||||
|
"[\\u00E8-\\u00EB] > e;"
|
||||||
|
"[\\u00EC-\\u00EF] > i;"
|
||||||
|
);
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
|
Calendar *cal;
|
||||||
|
DateFormat *fmt;
|
||||||
|
DateFormat *defFmt;
|
||||||
|
Transliterator *greek_latin;
|
||||||
|
Transliterator *rbtUnaccent;
|
||||||
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
|
Locale greece("el", "GR");
|
||||||
|
UnicodeString str, str2;
|
||||||
|
|
||||||
|
// Create a calendar in the Greek locale
|
||||||
|
cal = Calendar::createInstance(greece, status);
|
||||||
|
check(status, "Calendar::createInstance");
|
||||||
|
|
||||||
|
// Create a formatter
|
||||||
|
fmt = DateFormat::createDateInstance(DateFormat::kFull, greece);
|
||||||
|
fmt->setCalendar(*cal);
|
||||||
|
|
||||||
|
// Create a default formatter
|
||||||
|
defFmt = DateFormat::createDateInstance(DateFormat::kFull);
|
||||||
|
defFmt->setCalendar(*cal);
|
||||||
|
|
||||||
|
// Create a Greek-Latin Transliterator
|
||||||
|
greek_latin = Transliterator::createInstance("Greek-Latin");
|
||||||
|
if (greek_latin == 0) {
|
||||||
|
printf("ERROR: Transliterator::createInstance() failed\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a custom Transliterator
|
||||||
|
rbtUnaccent = new RuleBasedTransliterator("RBTUnaccent",
|
||||||
|
UNACCENT_RULES,
|
||||||
|
UTRANS_FORWARD,
|
||||||
|
status);
|
||||||
|
check(status, "RuleBasedTransliterator::ct");
|
||||||
|
|
||||||
|
// Loop over various months
|
||||||
|
for (int32_t month = Calendar::JANUARY;
|
||||||
|
month <= Calendar::DECEMBER;
|
||||||
|
++month) {
|
||||||
|
|
||||||
|
// Set the calendar to a date
|
||||||
|
cal->clear();
|
||||||
|
cal->set(1999, month, 4);
|
||||||
|
|
||||||
|
// Format the date in default locale
|
||||||
|
str.remove();
|
||||||
|
defFmt->format(cal->getTime(status), str, status);
|
||||||
|
check(status, "DateFormat::format");
|
||||||
|
printf("Date: ");
|
||||||
|
uprintf(escape(str));
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
// Format the date for Greece
|
||||||
|
str.remove();
|
||||||
|
fmt->format(cal->getTime(status), str, status);
|
||||||
|
check(status, "DateFormat::format");
|
||||||
|
printf("Greek formatted date: ");
|
||||||
|
uprintf(escape(str));
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
// Transliterate result
|
||||||
|
greek_latin->transliterate(str);
|
||||||
|
printf("Transliterated via Greek-Latin: ");
|
||||||
|
uprintf(escape(str));
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
// Transliterate result
|
||||||
|
str2 = str;
|
||||||
|
rbtUnaccent->transliterate(str);
|
||||||
|
printf("Transliterated via RBT unaccent: ");
|
||||||
|
uprintf(escape(str));
|
||||||
|
printf("\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
delete fmt;
|
||||||
|
delete cal;
|
||||||
|
delete greek_latin;
|
||||||
|
delete rbtUnaccent;
|
||||||
|
|
||||||
|
printf("Exiting successfully\n");
|
||||||
|
return 0;
|
||||||
|
}
|
116
icu4c/source/samples/translit/answers/main_4.cpp
Normal file
116
icu4c/source/samples/translit/answers/main_4.cpp
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
#include "unicode/translit.h"
|
||||||
|
#include "unicode/rbt.h"
|
||||||
|
#include "unicode/unistr.h"
|
||||||
|
#include "unicode/calendar.h"
|
||||||
|
#include "unicode/datefmt.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "util.h"
|
||||||
|
#include "unaccent.h"
|
||||||
|
|
||||||
|
// RuleBasedTransliterator rules to remove accents from characters
|
||||||
|
// so they can be displayed as ASCIIx
|
||||||
|
UnicodeString UNACCENT_RULES(
|
||||||
|
"[\\u00C0-\\u00C5] > A;"
|
||||||
|
"[\\u00C8-\\u00CB] > E;"
|
||||||
|
"[\\u00CC-\\u00CF] > I;"
|
||||||
|
"[\\u00E0-\\u00E5] > a;"
|
||||||
|
"[\\u00E8-\\u00EB] > e;"
|
||||||
|
"[\\u00EC-\\u00EF] > i;"
|
||||||
|
);
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
|
Calendar *cal;
|
||||||
|
DateFormat *fmt;
|
||||||
|
DateFormat *defFmt;
|
||||||
|
Transliterator *greek_latin;
|
||||||
|
Transliterator *rbtUnaccent;
|
||||||
|
Transliterator *unaccent;
|
||||||
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
|
Locale greece("el", "GR");
|
||||||
|
UnicodeString str, str2;
|
||||||
|
|
||||||
|
// Create a calendar in the Greek locale
|
||||||
|
cal = Calendar::createInstance(greece, status);
|
||||||
|
check(status, "Calendar::createInstance");
|
||||||
|
|
||||||
|
// Create a formatter
|
||||||
|
fmt = DateFormat::createDateInstance(DateFormat::kFull, greece);
|
||||||
|
fmt->setCalendar(*cal);
|
||||||
|
|
||||||
|
// Create a default formatter
|
||||||
|
defFmt = DateFormat::createDateInstance(DateFormat::kFull);
|
||||||
|
defFmt->setCalendar(*cal);
|
||||||
|
|
||||||
|
// Create a Greek-Latin Transliterator
|
||||||
|
greek_latin = Transliterator::createInstance("Greek-Latin");
|
||||||
|
if (greek_latin == 0) {
|
||||||
|
printf("ERROR: Transliterator::createInstance() failed\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a custom Transliterator
|
||||||
|
rbtUnaccent = new RuleBasedTransliterator("RBTUnaccent",
|
||||||
|
UNACCENT_RULES,
|
||||||
|
UTRANS_FORWARD,
|
||||||
|
status);
|
||||||
|
check(status, "RuleBasedTransliterator::ct");
|
||||||
|
|
||||||
|
// Create a custom Transliterator
|
||||||
|
unaccent = new UnaccentTransliterator();
|
||||||
|
|
||||||
|
// Loop over various months
|
||||||
|
for (int32_t month = Calendar::JANUARY;
|
||||||
|
month <= Calendar::DECEMBER;
|
||||||
|
++month) {
|
||||||
|
|
||||||
|
// Set the calendar to a date
|
||||||
|
cal->clear();
|
||||||
|
cal->set(1999, month, 4);
|
||||||
|
|
||||||
|
// Format the date in default locale
|
||||||
|
str.remove();
|
||||||
|
defFmt->format(cal->getTime(status), str, status);
|
||||||
|
check(status, "DateFormat::format");
|
||||||
|
printf("Date: ");
|
||||||
|
uprintf(escape(str));
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
// Format the date for Greece
|
||||||
|
str.remove();
|
||||||
|
fmt->format(cal->getTime(status), str, status);
|
||||||
|
check(status, "DateFormat::format");
|
||||||
|
printf("Greek formatted date: ");
|
||||||
|
uprintf(escape(str));
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
// Transliterate result
|
||||||
|
greek_latin->transliterate(str);
|
||||||
|
printf("Transliterated via Greek-Latin: ");
|
||||||
|
uprintf(escape(str));
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
// Transliterate result
|
||||||
|
str2 = str;
|
||||||
|
rbtUnaccent->transliterate(str);
|
||||||
|
printf("Transliterated via RBT unaccent: ");
|
||||||
|
uprintf(escape(str));
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
unaccent->transliterate(str2);
|
||||||
|
printf("Transliterated via normalizer unaccent: ");
|
||||||
|
uprintf(escape(str2));
|
||||||
|
printf("\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
delete fmt;
|
||||||
|
delete cal;
|
||||||
|
delete greek_latin;
|
||||||
|
delete unaccent;
|
||||||
|
delete rbtUnaccent;
|
||||||
|
|
||||||
|
printf("Exiting successfully\n");
|
||||||
|
return 0;
|
||||||
|
}
|
49
icu4c/source/samples/translit/answers/unaccent.cpp
Normal file
49
icu4c/source/samples/translit/answers/unaccent.cpp
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
|
||||||
|
#include "unaccent.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
UnaccentTransliterator::UnaccentTransliterator() :
|
||||||
|
normalizer("", Normalizer::DECOMP),
|
||||||
|
Transliterator("Unaccent", 0) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
UnaccentTransliterator::~UnaccentTransliterator() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove accents from a character using Normalizer.
|
||||||
|
*/
|
||||||
|
UChar UnaccentTransliterator::unaccent(UChar c) const {
|
||||||
|
UnicodeString str(c);
|
||||||
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
|
UnaccentTransliterator* t = (UnaccentTransliterator*)this;
|
||||||
|
|
||||||
|
t->normalizer.setText(str, status);
|
||||||
|
if (U_FAILURE(status)) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
return (UChar) t->normalizer.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implement Transliterator API
|
||||||
|
*/
|
||||||
|
void UnaccentTransliterator::handleTransliterate(Replaceable& text,
|
||||||
|
UTransPosition& index,
|
||||||
|
UBool incremental) const {
|
||||||
|
UnicodeString str("a");
|
||||||
|
while (index.start < index.limit) {
|
||||||
|
UChar c = text.charAt(index.start);
|
||||||
|
UChar d = unaccent(c);
|
||||||
|
if (c != d) {
|
||||||
|
str.setCharAt(0, d);
|
||||||
|
text.handleReplaceBetween(index.start, index.start+1, str);
|
||||||
|
}
|
||||||
|
index.start++;
|
||||||
|
}
|
||||||
|
}
|
36
icu4c/source/samples/translit/answers/unaccent.h
Normal file
36
icu4c/source/samples/translit/answers/unaccent.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
|
||||||
|
#include "unicode/translit.h"
|
||||||
|
#include "unicode/normlzr.h"
|
||||||
|
|
||||||
|
class UnaccentTransliterator : public Transliterator {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
UnaccentTransliterator();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~UnaccentTransliterator();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implement Transliterator API
|
||||||
|
*/
|
||||||
|
virtual void handleTransliterate(Replaceable& text,
|
||||||
|
UTransPosition& index,
|
||||||
|
UBool incremental) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unaccent a single character using normalizer.
|
||||||
|
*/
|
||||||
|
UChar unaccent(UChar c) const;
|
||||||
|
|
||||||
|
Normalizer normalizer;
|
||||||
|
};
|
64
icu4c/source/samples/translit/main.cpp
Normal file
64
icu4c/source/samples/translit/main.cpp
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
#include "unicode/translit.h"
|
||||||
|
#include "unicode/rbt.h"
|
||||||
|
#include "unicode/unistr.h"
|
||||||
|
#include "unicode/calendar.h"
|
||||||
|
#include "unicode/datefmt.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "util.h"
|
||||||
|
#include "unaccent.h"
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
|
Calendar *cal;
|
||||||
|
DateFormat *fmt;
|
||||||
|
DateFormat *defFmt;
|
||||||
|
UErrorCode status = U_ZERO_ERROR;
|
||||||
|
Locale greece("el", "GR");
|
||||||
|
UnicodeString str, str2;
|
||||||
|
|
||||||
|
// Create a calendar in the Greek locale
|
||||||
|
cal = Calendar::createInstance(greece, status);
|
||||||
|
check(status, "Calendar::createInstance");
|
||||||
|
|
||||||
|
// Create a formatter
|
||||||
|
fmt = DateFormat::createDateInstance(DateFormat::kFull, greece);
|
||||||
|
fmt->setCalendar(*cal);
|
||||||
|
|
||||||
|
// Create a default formatter
|
||||||
|
defFmt = DateFormat::createDateInstance(DateFormat::kFull);
|
||||||
|
defFmt->setCalendar(*cal);
|
||||||
|
|
||||||
|
// Loop over various months
|
||||||
|
for (int32_t month = Calendar::JANUARY;
|
||||||
|
month <= Calendar::DECEMBER;
|
||||||
|
++month) {
|
||||||
|
|
||||||
|
// Set the calendar to a date
|
||||||
|
cal->clear();
|
||||||
|
cal->set(1999, month, 4);
|
||||||
|
|
||||||
|
// Format the date in default locale
|
||||||
|
str.remove();
|
||||||
|
defFmt->format(cal->getTime(status), str, status);
|
||||||
|
check(status, "DateFormat::format");
|
||||||
|
printf("Date: ");
|
||||||
|
uprintf(escape(str));
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
// Format the date for Greece
|
||||||
|
str.remove();
|
||||||
|
fmt->format(cal->getTime(status), str, status);
|
||||||
|
check(status, "DateFormat::format");
|
||||||
|
printf("Greek formatted date: ");
|
||||||
|
uprintf(escape(str));
|
||||||
|
printf("\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
delete fmt;
|
||||||
|
delete cal;
|
||||||
|
|
||||||
|
printf("Exiting successfully\n");
|
||||||
|
return 0;
|
||||||
|
}
|
106
icu4c/source/samples/translit/translit.dsp
Normal file
106
icu4c/source/samples/translit/translit.dsp
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
# Microsoft Developer Studio Project File - Name="translit" - Package Owner=<4>
|
||||||
|
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||||
|
# ** DO NOT EDIT **
|
||||||
|
|
||||||
|
# TARGTYPE "Win32 (x86) Console Application" 0x0103
|
||||||
|
|
||||||
|
CFG=translit - Win32 Debug
|
||||||
|
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||||
|
!MESSAGE use the Export Makefile command and run
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE NMAKE /f "translit.mak".
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE You can specify a configuration when running NMAKE
|
||||||
|
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE NMAKE /f "translit.mak" CFG="translit - Win32 Debug"
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE Possible choices for configuration are:
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE "translit - Win32 Release" (based on "Win32 (x86) Console Application")
|
||||||
|
!MESSAGE "translit - Win32 Debug" (based on "Win32 (x86) Console Application")
|
||||||
|
!MESSAGE
|
||||||
|
|
||||||
|
# Begin Project
|
||||||
|
# PROP AllowPerConfigDependencies 0
|
||||||
|
# PROP Scc_ProjName ""
|
||||||
|
# PROP Scc_LocalPath ""
|
||||||
|
CPP=cl.exe
|
||||||
|
RSC=rc.exe
|
||||||
|
|
||||||
|
!IF "$(CFG)" == "translit - Win32 Release"
|
||||||
|
|
||||||
|
# PROP BASE Use_MFC 0
|
||||||
|
# PROP BASE Use_Debug_Libraries 0
|
||||||
|
# PROP BASE Output_Dir "Release"
|
||||||
|
# PROP BASE Intermediate_Dir "Release"
|
||||||
|
# PROP BASE Target_Dir ""
|
||||||
|
# PROP Use_MFC 0
|
||||||
|
# PROP Use_Debug_Libraries 0
|
||||||
|
# PROP Output_Dir "Release"
|
||||||
|
# PROP Intermediate_Dir "Release"
|
||||||
|
# PROP Ignore_Export_Lib 0
|
||||||
|
# PROP Target_Dir ""
|
||||||
|
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||||
|
# ADD CPP /nologo /W3 /GX /O2 /I "..\..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||||
|
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||||
|
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||||
|
BSC32=bscmake.exe
|
||||||
|
# ADD BASE BSC32 /nologo
|
||||||
|
# ADD BSC32 /nologo
|
||||||
|
LINK32=link.exe
|
||||||
|
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||||
|
# ADD LINK32 icuuc.lib icui18n.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\lib\Release"
|
||||||
|
|
||||||
|
!ELSEIF "$(CFG)" == "translit - Win32 Debug"
|
||||||
|
|
||||||
|
# PROP BASE Use_MFC 0
|
||||||
|
# PROP BASE Use_Debug_Libraries 1
|
||||||
|
# PROP BASE Output_Dir "Debug"
|
||||||
|
# PROP BASE Intermediate_Dir "Debug"
|
||||||
|
# PROP BASE Target_Dir ""
|
||||||
|
# PROP Use_MFC 0
|
||||||
|
# PROP Use_Debug_Libraries 1
|
||||||
|
# PROP Output_Dir "Debug"
|
||||||
|
# PROP Intermediate_Dir "Debug"
|
||||||
|
# PROP Ignore_Export_Lib 0
|
||||||
|
# PROP Target_Dir ""
|
||||||
|
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||||
|
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||||
|
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||||
|
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||||
|
BSC32=bscmake.exe
|
||||||
|
# ADD BASE BSC32 /nologo
|
||||||
|
# ADD BSC32 /nologo
|
||||||
|
LINK32=link.exe
|
||||||
|
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||||
|
# ADD LINK32 icuuc.lib icui18n.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\lib\Debug"
|
||||||
|
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# Begin Target
|
||||||
|
|
||||||
|
# Name "translit - Win32 Release"
|
||||||
|
# Name "translit - Win32 Debug"
|
||||||
|
# Begin Group "Source Files"
|
||||||
|
|
||||||
|
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\main.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\util.cpp
|
||||||
|
# End Source File
|
||||||
|
# End Group
|
||||||
|
# Begin Group "Header Files"
|
||||||
|
|
||||||
|
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||||
|
# End Group
|
||||||
|
# Begin Group "Resource Files"
|
||||||
|
|
||||||
|
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||||
|
# End Group
|
||||||
|
# End Target
|
||||||
|
# End Project
|
29
icu4c/source/samples/translit/translit.dsw
Normal file
29
icu4c/source/samples/translit/translit.dsw
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||||
|
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
Project: "translit"=.\translit.dsp - Package Owner=<4>
|
||||||
|
|
||||||
|
Package=<5>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
Package=<4>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
Global:
|
||||||
|
|
||||||
|
Package=<5>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
Package=<3>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
57
icu4c/source/samples/translit/util.cpp
Normal file
57
icu4c/source/samples/translit/util.cpp
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#include "unicode/unistr.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
// Verify that a UErrorCode is successful; exit(1) if not
|
||||||
|
void check(UErrorCode& status, const char* msg) {
|
||||||
|
if (U_FAILURE(status)) {
|
||||||
|
printf("ERROR: %s (%s)\n", u_errorName(status), msg);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
// printf("Ok: %s\n", msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append a hex string to the target
|
||||||
|
static UnicodeString& appendHex(uint32_t number,
|
||||||
|
int8_t digits,
|
||||||
|
UnicodeString& target) {
|
||||||
|
static const UnicodeString DIGIT_STRING("0123456789ABCDEF");
|
||||||
|
while (digits > 0) {
|
||||||
|
target += DIGIT_STRING[(number >> ((--digits) * 4)) & 0xF];
|
||||||
|
}
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace nonprintable characters with unicode escapes
|
||||||
|
UnicodeString escape(const UnicodeString &source) {
|
||||||
|
int32_t i;
|
||||||
|
UnicodeString target;
|
||||||
|
target += "\"";
|
||||||
|
for (i=0; i<source.length(); ++i) {
|
||||||
|
UChar ch = source[i];
|
||||||
|
if (ch < 0x09 || (ch > 0x0A && ch < 0x20) || ch > 0x7E) {
|
||||||
|
target += "\\u";
|
||||||
|
appendHex(ch, 4, target);
|
||||||
|
} else {
|
||||||
|
target += ch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
target += "\"";
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print the given string to stdout
|
||||||
|
void uprintf(const UnicodeString &str) {
|
||||||
|
char *buf = 0;
|
||||||
|
int32_t len = str.length();
|
||||||
|
// int32_t bufLen = str.extract(0, len, buf); // Preflight
|
||||||
|
/* Preflighting seems to be broken now, so assume 1-1 conversion,
|
||||||
|
plus some slop. */
|
||||||
|
int32_t bufLen = len + 16;
|
||||||
|
int32_t actualLen;
|
||||||
|
buf = new char[bufLen + 1];
|
||||||
|
actualLen = str.extract(0, len, buf/*, bufLen*/); // Default codepage conversion
|
||||||
|
buf[actualLen] = 0;
|
||||||
|
printf("%s", buf);
|
||||||
|
delete buf;
|
||||||
|
}
|
10
icu4c/source/samples/translit/util.h
Normal file
10
icu4c/source/samples/translit/util.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#include "unicode/unistr.h"
|
||||||
|
|
||||||
|
// Verify that a UErrorCode is successful; exit(1) if not
|
||||||
|
void check(UErrorCode& status, const char* msg);
|
||||||
|
|
||||||
|
// Replace nonprintable characters with unicode escapes
|
||||||
|
UnicodeString escape(const UnicodeString &source);
|
||||||
|
|
||||||
|
// Print the given string to stdout
|
||||||
|
void uprintf(const UnicodeString &str);
|
Loading…
Reference in New Issue
Block a user