197 lines
7.4 KiB
C
197 lines
7.4 KiB
C
|
/**************************************************************************
|
||
|
*
|
||
|
* Copyright (C) 2001, International Business Machines
|
||
|
* Corporation and others. All Rights Reserved.
|
||
|
*
|
||
|
***************************************************************************
|
||
|
*
|
||
|
* ufortune - An ICU resources sample program
|
||
|
*
|
||
|
* Demonstrates
|
||
|
* Defining resources for use by an application
|
||
|
* Compiling and packaging them into a dll
|
||
|
* Referencing the resource-containing dll from application code
|
||
|
* Loading resource data using ICU's API
|
||
|
*
|
||
|
* Created Nov. 7, 2001 by Andy Heninger
|
||
|
*
|
||
|
* ufortune is a variant of the Unix "fortune" command, with
|
||
|
* ICU resources that contain the fortune-cookie sayings.
|
||
|
* Using resources allows fortunes in different languages to
|
||
|
* be selected based on locale.
|
||
|
*/
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
#include <time.h>
|
||
|
|
||
|
#include "unicode/udata.h" /* ICU API for data handling. */
|
||
|
#include "unicode/ures.h" /* ICU API for resource loading */
|
||
|
#include "unicode/ustdio.h" /* ICU API for reading & writing Unicode data */
|
||
|
/* to files, possibly including character */
|
||
|
/* set conversions. */
|
||
|
#include "unicode/ustring.h"
|
||
|
|
||
|
/*
|
||
|
* Resource Data Reference. The data is packaged as a dll (or .so or
|
||
|
* whatever, depending on the platform) that exports a data
|
||
|
* symbol. The application (that's us) references that symbol,
|
||
|
* here, and will pass the data address to ICU, which will then
|
||
|
* be able to fetch resources from the data.
|
||
|
*/
|
||
|
extern const void U_IMPORT *fortune_resources_dat;
|
||
|
void u_write(const UChar *what, int len);
|
||
|
|
||
|
|
||
|
/*
|
||
|
* main() This one function is all of the application code.
|
||
|
*/
|
||
|
int main(int argc, char **argv)
|
||
|
{
|
||
|
UBool displayUsage = FALSE; /* Set true if command line err or help */
|
||
|
/* option was requested. */
|
||
|
UBool verbose = FALSE; /* Set true if -v command line option. */
|
||
|
char *optionError = NULL; /* If command line contains an unrecognized */
|
||
|
/* option, this will point to it. */
|
||
|
char *locale=NULL; /* Locale name. Null for system default, */
|
||
|
/* otherwise set from command line. */
|
||
|
const char * programName = argv[0]; /* Program invocation name. */
|
||
|
|
||
|
|
||
|
UFILE *u_stdout; /* Unicode stdout file. */
|
||
|
UErrorCode err = U_ZERO_ERROR; /* Error return, used for most ICU */
|
||
|
/* functions. */
|
||
|
|
||
|
UResourceBundle *myResources; /* ICU Resource "handles" */
|
||
|
UResourceBundle *fortunes_r;
|
||
|
|
||
|
int32_t numFortunes; /* Number of fortune strings available. */
|
||
|
int i;
|
||
|
|
||
|
const UChar *resString; /* Points to strings fetched from Resources. */
|
||
|
int32_t len;
|
||
|
|
||
|
|
||
|
/* Process command line options.
|
||
|
* -l locale specify a locale
|
||
|
* -v verbose mode. Display extra messages.
|
||
|
* -? or --help display a usage line
|
||
|
*/
|
||
|
for (i=1; i<argc; i++) {
|
||
|
if (strcmp(argv[i], "-l") ==0) {
|
||
|
if (++i < argc) {
|
||
|
locale = argv[i];
|
||
|
}
|
||
|
continue;
|
||
|
}
|
||
|
if (strcmp(argv[i], "-v") == 0) {
|
||
|
verbose = TRUE;
|
||
|
continue;}
|
||
|
if (strcmp(argv[i], "-?") == 0 ||
|
||
|
strcmp(argv[i], "--help") == 0) {
|
||
|
displayUsage = TRUE;
|
||
|
continue;}
|
||
|
optionError = argv[i];
|
||
|
displayUsage = TRUE;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
/* ICU's ustdio package provides a convenient way to write Unicode
|
||
|
* data to stdout. The string data that we get from resources
|
||
|
* will be UChar * strings, which ustdio can handle nicely.
|
||
|
*/
|
||
|
u_stdout = u_finit(stdout, NULL /*locale*/, NULL /*codepage */);
|
||
|
if (verbose) {
|
||
|
u_fprintf(u_stdout, "%s: checking output via ustdio.\n", programName);
|
||
|
}
|
||
|
|
||
|
/* Tell ICU where our resource data is located in memory.
|
||
|
* The data lives in the Fortune_Resources dll, and we just
|
||
|
* pass the address of an exported symbol from that library
|
||
|
* to ICU.
|
||
|
*/
|
||
|
udata_setAppData("fortune_resources", &fortune_resources_dat, &err);
|
||
|
if (U_FAILURE(err)) {
|
||
|
fprintf(stderr, "%s: ures_open failed with error \"%s\"\n", programName, u_errorName(err));
|
||
|
exit(-1);
|
||
|
}
|
||
|
|
||
|
/* Open our resources.
|
||
|
*/
|
||
|
myResources = ures_open("fortune_resources", locale, &err);
|
||
|
if (U_FAILURE(err)) {
|
||
|
fprintf(stderr, "%s: ures_open failed with error \"%s\"\n", programName, u_errorName(err));
|
||
|
exit(-1);
|
||
|
}
|
||
|
if (verbose) {
|
||
|
u_fprintf(u_stdout, "status from ures_open(\"fortune_resources\", %s) is %s\n",
|
||
|
locale? locale: " ", u_errorName(err));
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Display any command line option usage errors and/or the
|
||
|
* usage help message. These messages come from our resource bundle.
|
||
|
*/
|
||
|
if (optionError != NULL) {
|
||
|
const UChar *msg = ures_getStringByKey(myResources, "optionMessage", &len, &err);
|
||
|
if (U_FAILURE(err)) {
|
||
|
fprintf(stderr, "%s: ures_getStringByKey(\"optionMessage\") failed, %s\n",
|
||
|
programName, u_errorName(err));
|
||
|
exit(-1);
|
||
|
}
|
||
|
u_file_write(msg, len, u_stdout); /* msg is UChar *, from resource */
|
||
|
u_fprintf(u_stdout, " %s\n", optionError); /* optionError is char *, from argv */
|
||
|
}
|
||
|
|
||
|
if (displayUsage) {
|
||
|
const UChar *usage;
|
||
|
int returnValue=0;
|
||
|
|
||
|
usage = ures_getStringByKey(myResources, "usage", &len, &err);
|
||
|
if (U_FAILURE(err)) {
|
||
|
fprintf(stderr, "%s: ures_getStringByKey(\"usage\") failed, %s\n", programName, u_errorName(err));
|
||
|
exit(-1);
|
||
|
}
|
||
|
u_file_write(usage, len, u_stdout);
|
||
|
if (optionError != NULL) {returnValue = -1;}
|
||
|
return returnValue;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Open the "fortunes" resources from within the already open resources
|
||
|
*/
|
||
|
fortunes_r = ures_getByKey(myResources, "fortunes", NULL, &err);
|
||
|
if (U_FAILURE(err)) {
|
||
|
fprintf(stderr, "%s: ures_getByKey(\"fortunes\") failed, %s\n", programName, u_errorName(err));
|
||
|
exit(-1);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* Pick up and display a random fortune
|
||
|
*
|
||
|
*/
|
||
|
numFortunes = ures_countArrayItems(myResources, "fortunes", &err);
|
||
|
if (U_FAILURE(err)) {
|
||
|
fprintf(stderr, "%s: ures_countArrayItems(\"fortunes\") failed, %s\n", programName, u_errorName(err));
|
||
|
exit(-1);
|
||
|
}
|
||
|
if (numFortunes <= 0) {
|
||
|
fprintf(stderr, "%s: no fortunes found.\n");
|
||
|
exit(-1);
|
||
|
}
|
||
|
|
||
|
i = time(NULL) % numFortunes; /* Use time to pick a somewhat-random fortune. */
|
||
|
resString = ures_getStringByIndex(fortunes_r, i, &len, &err);
|
||
|
if (U_FAILURE(err)) {
|
||
|
fprintf(stderr, "%s: ures_getStringByIndex(%d) failed, %s\n", programName, i, u_errorName(err));
|
||
|
exit(-1);
|
||
|
}
|
||
|
|
||
|
u_file_write(resString, len, u_stdout);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|