Home | History | Annotate | Download | only in coll
      1 /********************************************************************
      2  * COPYRIGHT:
      3  * Copyright (C) 2002-2006 IBM, Inc.   All Rights Reserved.
      4  *
      5  ********************************************************************/
      6 
      7 /**
      8  * This program demos string collation
      9  */
     10 
     11 const char gHelpString[] =
     12     "usage: coll [options*] -source source_string -target target_string\n"
     13     "-help            Display this message.\n"
     14     "-locale name     ICU locale to use.  Default is en_US\n"
     15     "-rules rule      Collation rules file (overrides locale)\n"
     16     "-french          French accent ordering\n"
     17     "-norm            Normalizing mode on\n"
     18     "-shifted         Shifted mode\n"
     19     "-lower           Lower case first\n"
     20     "-upper           Upper case first\n"
     21     "-case            Enable separate case level\n"
     22     "-level n         Sort level, 1 to 5, for Primary, Secndary, Tertiary, Quaternary, Identical\n"
     23 	"-source string   Source string for comparison\n"
     24 	"-target string   Target string for comparison\n"
     25     "Example coll -rules \\u0026b\\u003ca -source a -target b\n"
     26 	"The format \\uXXXX is supported for the rules and comparison strings\n"
     27 	;
     28 
     29 #include <stdio.h>
     30 #include <string.h>
     31 #include <stdlib.h>
     32 
     33 #include <unicode/utypes.h>
     34 #include <unicode/ucol.h>
     35 #include <unicode/ustring.h>
     36 
     37 /**
     38  * Command line option variables
     39  *    These global variables are set according to the options specified
     40  *    on the command line by the user.
     41  */
     42 char * opt_locale     = "en_US";
     43 char * opt_rules      = 0;
     44 UBool  opt_help       = FALSE;
     45 UBool  opt_norm       = FALSE;
     46 UBool  opt_french     = FALSE;
     47 UBool  opt_shifted    = FALSE;
     48 UBool  opt_lower      = FALSE;
     49 UBool  opt_upper      = FALSE;
     50 UBool  opt_case       = FALSE;
     51 int    opt_level      = 0;
     52 char * opt_source     = "abc";
     53 char * opt_target     = "abd";
     54 UCollator * collator  = 0;
     55 
     56 /**
     57  * Definitions for the command line options
     58  */
     59 struct OptSpec {
     60     const char *name;
     61     enum {FLAG, NUM, STRING} type;
     62     void *pVar;
     63 };
     64 
     65 OptSpec opts[] = {
     66     {"-locale",      OptSpec::STRING, &opt_locale},
     67     {"-rules",       OptSpec::STRING, &opt_rules},
     68 	{"-source",      OptSpec::STRING, &opt_source},
     69     {"-target",      OptSpec::STRING, &opt_target},
     70     {"-norm",        OptSpec::FLAG,   &opt_norm},
     71     {"-french",      OptSpec::FLAG,   &opt_french},
     72     {"-shifted",     OptSpec::FLAG,   &opt_shifted},
     73     {"-lower",       OptSpec::FLAG,   &opt_lower},
     74     {"-upper",       OptSpec::FLAG,   &opt_upper},
     75     {"-case",        OptSpec::FLAG,   &opt_case},
     76     {"-level",       OptSpec::NUM,    &opt_level},
     77     {"-help",        OptSpec::FLAG,   &opt_help},
     78     {"-?",           OptSpec::FLAG,   &opt_help},
     79     {0, OptSpec::FLAG, 0}
     80 };
     81 
     82 /**
     83  * processOptions()  Function to read the command line options.
     84  */
     85 UBool processOptions(int argc, const char **argv, OptSpec opts[])
     86 {
     87     for (int argNum = 1; argNum < argc; argNum ++) {
     88         const char *pArgName = argv[argNum];
     89         OptSpec *pOpt;
     90         for (pOpt = opts;  pOpt->name != 0; pOpt ++) {
     91             if (strcmp(pOpt->name, pArgName) == 0) {
     92                 switch (pOpt->type) {
     93                 case OptSpec::FLAG:
     94                     *(UBool *)(pOpt->pVar) = TRUE;
     95                     break;
     96                 case OptSpec::STRING:
     97                     argNum ++;
     98                     if (argNum >= argc) {
     99                         fprintf(stderr, "value expected for \"%s\" option.\n",
    100 							    pOpt->name);
    101                         return FALSE;
    102                     }
    103                     *(const char **)(pOpt->pVar) = argv[argNum];
    104                     break;
    105                 case OptSpec::NUM:
    106                     argNum ++;
    107                     if (argNum >= argc) {
    108                         fprintf(stderr, "value expected for \"%s\" option.\n",
    109 							    pOpt->name);
    110                         return FALSE;
    111                     }
    112                     char *endp;
    113                     int i = strtol(argv[argNum], &endp, 0);
    114                     if (endp == argv[argNum]) {
    115                         fprintf(stderr,
    116 							    "integer value expected for \"%s\" option.\n",
    117 								pOpt->name);
    118                         return FALSE;
    119                     }
    120                     *(int *)(pOpt->pVar) = i;
    121                 }
    122                 break;
    123             }
    124         }
    125         if (pOpt->name == 0)
    126         {
    127             fprintf(stderr, "Unrecognized option \"%s\"\n", pArgName);
    128             return FALSE;
    129         }
    130     }
    131 	return TRUE;
    132 }
    133 
    134 /**
    135  * ICU string comparison
    136  */
    137 int strcmp()
    138 {
    139 	UChar source[100];
    140 	UChar target[100];
    141 	u_unescape(opt_source, source, 100);
    142 	u_unescape(opt_target, target, 100);
    143     UCollationResult result = ucol_strcoll(collator, source, -1, target, -1);
    144     if (result == UCOL_LESS) {
    145 		return -1;
    146 	}
    147     else if (result == UCOL_GREATER) {
    148 		return 1;
    149 	}
    150 	return 0;
    151 }
    152 
    153 /**
    154  * Creates a collator
    155  */
    156 UBool processCollator()
    157 {
    158 	// Set up an ICU collator
    159     UErrorCode status = U_ZERO_ERROR;
    160 	UChar rules[100];
    161 
    162     if (opt_rules != 0) {
    163 		u_unescape(opt_rules, rules, 100);
    164         collator = ucol_openRules(rules, -1, UCOL_OFF, UCOL_TERTIARY,
    165 			                  NULL, &status);
    166     }
    167     else {
    168         collator = ucol_open(opt_locale, &status);
    169     }
    170 	if (U_FAILURE(status)) {
    171         fprintf(stderr, "Collator creation failed.: %d\n", status);
    172         return FALSE;
    173     }
    174     if (status == U_USING_DEFAULT_WARNING) {
    175         fprintf(stderr, "Warning, U_USING_DEFAULT_WARNING for %s\n",
    176 			    opt_locale);
    177     }
    178     if (status == U_USING_FALLBACK_WARNING) {
    179         fprintf(stderr, "Warning, U_USING_FALLBACK_ERROR for %s\n",
    180 			    opt_locale);
    181     }
    182     if (opt_norm) {
    183         ucol_setAttribute(collator, UCOL_NORMALIZATION_MODE, UCOL_ON, &status);
    184     }
    185     if (opt_french) {
    186         ucol_setAttribute(collator, UCOL_FRENCH_COLLATION, UCOL_ON, &status);
    187     }
    188     if (opt_lower) {
    189         ucol_setAttribute(collator, UCOL_CASE_FIRST, UCOL_LOWER_FIRST,
    190 			              &status);
    191     }
    192     if (opt_upper) {
    193         ucol_setAttribute(collator, UCOL_CASE_FIRST, UCOL_UPPER_FIRST,
    194 			              &status);
    195     }
    196     if (opt_case) {
    197         ucol_setAttribute(collator, UCOL_CASE_LEVEL, UCOL_ON, &status);
    198     }
    199     if (opt_shifted) {
    200         ucol_setAttribute(collator, UCOL_ALTERNATE_HANDLING, UCOL_SHIFTED,
    201 			              &status);
    202     }
    203     if (opt_level != 0) {
    204         switch (opt_level) {
    205         case 1:
    206             ucol_setAttribute(collator, UCOL_STRENGTH, UCOL_PRIMARY, &status);
    207             break;
    208         case 2:
    209             ucol_setAttribute(collator, UCOL_STRENGTH, UCOL_SECONDARY,
    210 				              &status);
    211             break;
    212         case 3:
    213             ucol_setAttribute(collator, UCOL_STRENGTH, UCOL_TERTIARY, &status);
    214             break;
    215         case 4:
    216             ucol_setAttribute(collator, UCOL_STRENGTH, UCOL_QUATERNARY,
    217 				              &status);
    218             break;
    219         case 5:
    220             ucol_setAttribute(collator, UCOL_STRENGTH, UCOL_IDENTICAL,
    221 				              &status);
    222             break;
    223         default:
    224             fprintf(stderr, "-level param must be between 1 and 5\n");
    225             return FALSE;
    226         }
    227     }
    228     if (U_FAILURE(status)) {
    229         fprintf(stderr, "Collator attribute setting failed.: %d\n", status);
    230         return FALSE;
    231     }
    232 	return TRUE;
    233 }
    234 
    235 /**
    236  * Main   --  process command line, read in and pre-process the test file,
    237  *            call other functions to do the actual tests.
    238  */
    239 int main(int argc, const char** argv)
    240 {
    241     if (processOptions(argc, argv, opts) != TRUE || opt_help) {
    242         printf(gHelpString);
    243         return -1;
    244     }
    245 
    246     if (processCollator() != TRUE) {
    247 		fprintf(stderr, "Error creating collator for comparison\n");
    248 		return -1;
    249 	}
    250 
    251 	fprintf(stdout, "Comparing source=%s and target=%s\n", opt_source,
    252 			opt_target);
    253 	int result = strcmp();
    254 	if (result == 0) {
    255 		fprintf(stdout, "source is equals to target\n");
    256 	}
    257 	else if (result < 0) {
    258 		fprintf(stdout, "source is less than target\n");
    259 	}
    260 	else {
    261 		fprintf(stdout, "source is greater than target\n");
    262 	}
    263 
    264 	ucol_close(collator);
    265 	return 0;
    266 }
    267