Back to index

lightning-sunbird  0.9+nobinonly
LocaleSelfTest.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Pierre Phaneuf <pp@ludusdesign.com>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either of the GNU General Public License Version 2 or later (the "GPL"),
00027  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038  
00039 #include <stdio.h>
00040 #include <stdlib.h>
00041 #include "nsISupports.h"
00042 #include "nsIComponentManager.h"
00043 #include "nsILocale.h"
00044 #include "nsILocaleFactory.h"
00045 #include "nsLocaleCID.h"
00046 #if defined(XP_MAC) || defined(XP_MACOSX)
00047 #include "nsIMacLocale.h"
00048 #include <TextEncodingConverter.h>
00049 #elif defined(XP_WIN) || defined(XP_OS2)
00050 #include "nsIWin32Locale.h"
00051 #else
00052 #include "nsIPosixLocale.h"
00053 #endif
00054 #include "nsCollationCID.h"
00055 #include "nsICollation.h"
00056 #include "nsDateTimeFormatCID.h"
00057 #include "nsIDateTimeFormat.h"
00058 #include "nsReadableUtils.h"
00059 
00060 #ifdef XP_MAC
00061 #define LOCALE_DLL_NAME "NSLOCALE_DLL"
00062 #define UCONV_DLL       "UCONV_DLL"
00063 #define UCVLATIN_DLL    "UCVLATIN_DLL"
00064 #define UNICHARUTIL_DLL_NAME "UNICHARUTIL_DLL"
00065 #elif defined(XP_WIN) || defined(XP_OS2)
00066 #define LOCALE_DLL_NAME "NSLOCALE.DLL"
00067 #define UCONV_DLL       "uconv.dll"
00068 #define UCVLATIN_DLL    "ucvlatin.dll"
00069 #define UNICHARUTIL_DLL_NAME "unicharutil.dll"
00070 #else
00071 #define LOCALE_DLL_NAME "libnslocale"MOZ_DLL_SUFFIX
00072 #define UCONV_DLL       "libuconv"MOZ_DLL_SUFFIX
00073 #define UCVLATIN_DLL    "libucvlatin"MOZ_DLL_SUFFIX
00074 #define UNICHARUTIL_DLL_NAME "libunicharutil"MOZ_DLL_SUFFIX
00075 #endif
00076 
00077 
00078 
00079 // Collation
00080 //
00081 static NS_DEFINE_CID(kCollationFactoryCID, NS_COLLATIONFACTORY_CID);
00082 // Date and Time
00083 //
00084 static NS_DEFINE_CID(kDateTimeFormatCID, NS_DATETIMEFORMAT_CID);
00085 // locale
00086 //
00087 static NS_DEFINE_CID(kLocaleFactoryCID, NS_LOCALEFACTORY_CID);
00088 // platform specific
00089 //
00090 #if defined(XP_MAC) || defined(XP_MACOSX)
00091 static NS_DEFINE_IID(kMacLocaleFactoryCID, NS_MACLOCALEFACTORY_CID);
00092 static NS_DEFINE_IID(kIMacLocaleIID, NS_MACLOCALE_CID);
00093 #elif defined(XP_WIN) || defined(XP_OS2)
00094 static NS_DEFINE_CID(kWin32LocaleFactoryCID, NS_WIN32LOCALEFACTORY_CID);
00095 static NS_DEFINE_IID(kIWin32LocaleIID, NS_IWIN32LOCALE_IID);
00096 #else
00097 static NS_DEFINE_IID(kPosixLocaleFactoryCID, NS_POSIXLOCALEFACTORY_CID);
00098 static NS_DEFINE_IID(kIPosixLocaleIID, NS_IPOSIXLOCALE_IID);
00099 #endif
00100 
00101 // global variable
00102 static PRBool g_verbose = PR_FALSE;
00103 static FILE *g_outfp = NULL;
00104 static char g_usage[] = " usage:\n-date\tdate time format test\n-col\tcollation test\n-sort\tsort test\n\
00105 -f file\tsort data file\n-o out file\tsort result file\n-case\tcase sensitive sort\n-locale\tlocale\n-v\tverbose\n";
00106 
00107 // Create a collation key, the memory is allocated using new which need to be deleted by a caller.
00108 //
00109 static nsresult CreateCollationKey(nsICollation *t, PRInt32 strength, 
00110                                    nsString& stringIn, PRUint8 **aKey, PRUint32 *keyLength)
00111 {
00112   nsresult res;
00113   
00114   // create a raw collation key
00115   res = t->GetSortKeyLen(strength, stringIn, keyLength);
00116   if(NS_FAILED(res)) {
00117     printf("\tFailed!! return value != NS_OK\n");
00118   }
00119   *aKey = (PRUint8 *) new PRUint8[*keyLength];
00120   if (NULL == *aKey) {
00121     printf("\tFailed!! memory allocation failed.\n");
00122   }
00123   res = t->CreateRawSortKey(strength, stringIn, *aKey, keyLength);
00124   if(NS_FAILED(res)) {
00125     printf("\tFailed!! return value != NS_OK\n");
00126   }
00127 
00128   // create a key in nsString
00129   nsString aKeyString;
00130   res = t->CreateSortKey(strength, stringIn, aKeyString);
00131   if(NS_FAILED(res)) {
00132     printf("\tFailed!! return value != NS_OK\n");
00133   }
00134 
00135   // compare the generated key
00136   nsString tempString;
00137   tempString.SetString((PRUnichar *) *aKey, *keyLength / sizeof(PRUnichar));
00138   NS_ASSERTION(aKeyString == tempString, "created key mismatch");
00139 
00140   return res;
00141 }
00142 
00143 static void DebugDump(nsString& aString) {
00144 #ifdef WIN32
00145   char s[512];
00146   int len = WideCharToMultiByte(GetACP(), 0,
00147                                 (LPCWSTR ) aString.get(),  aString.Length(),
00148                                 s, 512, NULL,  NULL);
00149   s[len] = '\0';
00150   fflush(stdout);
00151   printf("%s\n", s);
00152 #elif defined(XP_MAC) || defined(XP_MACOSX)
00153        // Use TEC (Text Encoding Conversion Manager)
00154   TextEncoding outEncoding;
00155   TECObjectRef anEncodingConverter;
00156   ByteCount oInputRead, oOutputLen;
00157   char oOutputStr[512];
00158   OSStatus err = 0;
00159   err = UpgradeScriptInfoToTextEncoding   (smSystemScript/*smCurrentScript*/, kTextLanguageDontCare, kTextRegionDontCare, NULL, &outEncoding);
00160   err = TECCreateConverter(&anEncodingConverter, kTextEncodingUnicodeV2_0, outEncoding);
00161   err = TECConvertText(anEncodingConverter,
00162                        (ConstTextPtr) aString.get(), aString.Length() * sizeof(PRUnichar), &oInputRead,
00163                        (TextPtr) oOutputStr, 512, &oOutputLen);
00164   err = TECDisposeConverter(anEncodingConverter);
00165   
00166   oOutputStr[oOutputLen] = '\0';
00167   fflush(NULL);
00168   printf("%s\n", oOutputStr);
00169 #else
00170   for (int i = 0; i < aString.Length(); i++) {
00171     putchar((char) aString[i]);
00172   }
00173   printf("\n");
00174 #endif
00175 }
00176 
00177 // Test all functions in nsICollation.
00178 //
00179 static void TestCollation(nsILocale *locale)
00180 {
00181 //   nsString locale("en-US");
00182    nsICollationFactory *f = NULL;
00183    nsICollation *t = NULL;
00184    nsresult res;
00185 
00186    printf("==============================\n");
00187    printf("Start nsICollation Test \n");
00188    printf("==============================\n");
00189    
00190    res = CallCreateInstance(kCollationFactoryCID, &f);
00191            
00192    printf("Test 1 - CreateInstance():\n");
00193    if(NS_FAILED(res) || ( f == NULL ) ) {
00194      printf("\t1st CreateInstance failed\n");
00195    } else {
00196      f->Release();
00197    }
00198 
00199    res = CallCreateInstance(kCollationFactoryCID, &f);
00200    if(NS_FAILED(res) || ( f == NULL ) ) {
00201      printf("\t2nd CreateInstance failed\n");
00202    }
00203 
00204    res = f->CreateCollation(locale, &t);
00205            
00206    if(NS_FAILED(res) || ( t == NULL ) ) {
00207      printf("\tCreateCollation failed\n");
00208    } else {
00209      nsString string1("abcde");
00210      nsString string2("ABCDE");
00211      nsString string3("xyz");
00212      nsString string4("abc");
00213      PRUint32 keyLength1, keyLength2, keyLength3;
00214      PRUint8 *aKey1, *aKey2, *aKey3;
00215      PRUint32 i;
00216      PRInt32 result;
00217 
00218       printf("String data used:\n");
00219       printf("string1: ");
00220       DebugDump(string1);
00221       printf("string2: ");
00222       DebugDump(string2);
00223       printf("string3: ");
00224       DebugDump(string3);
00225       printf("string4: ");
00226       DebugDump(string4);
00227 
00228       printf("Test 2 - CompareString():\n");
00229       res = t->CompareString(nsICollation::kCollationCaseInSensitive, string1, string2, &result);
00230       if(NS_FAILED(res)) {
00231         printf("\tFailed!! return value != NS_OK\n");
00232       }
00233       printf("case insensitive comparison (string1 vs string2): %d\n", result);
00234 
00235       res = t->CompareString(nsICollation::kCollationCaseSensitive, string1, string2, &result);
00236       if(NS_FAILED(res)) {
00237         printf("\tFailed!! return value != NS_OK\n");
00238       }
00239       printf("case sensitive comparison (string1 vs string2): %d\n", result);
00240 
00241       printf("Test 3 - GetSortKeyLen():\n");
00242       res = t->GetSortKeyLen(nsICollation::kCollationCaseSensitive, string2, &keyLength1);
00243       if(NS_FAILED(res)) {
00244         printf("\tFailed!! return value != NS_OK\n");
00245       }
00246       printf("keyLength: %d\n", keyLength1);
00247 
00248       printf("Test 4 - CreateRawSortKey():\n");
00249       aKey1 = (PRUint8 *) new PRUint8[keyLength1];
00250       if (NULL == aKey1) {
00251         printf("\tFailed!! memory allocation failed.\n");
00252       }
00253       res = t->CreateRawSortKey(nsICollation::kCollationCaseSensitive, string2, aKey1, &keyLength1);
00254       if(NS_FAILED(res)) {
00255         printf("\tFailed!! return value != NS_OK\n");
00256       }
00257       printf("case sensitive key creation:\n");
00258       printf("keyLength: %d\n", keyLength1);
00259       DebugDump(string2);
00260 
00261       fflush(NULL);
00262       for (i = 0; i < keyLength1; i++) {
00263         printf("%.2x ", aKey1[i]);
00264         //printf("key[" << i << "]: " << aKey1[i] << " ");
00265       }
00266       printf("\n");
00267 
00268       res = CreateCollationKey(t, nsICollation::kCollationCaseInSensitive, string2, &aKey2, &keyLength2);
00269       if(NS_FAILED(res)) {
00270         printf("\tFailed!! return value != NS_OK\n");
00271       }
00272       printf("case insensitive key creation:\n");
00273       printf("keyLength: %d\n", keyLength2);
00274       DebugDump(string2);
00275 
00276       fflush(NULL);
00277       for (i = 0; i < keyLength2; i++) {
00278        printf("%.2x ", aKey2[i]);
00279        //printf("key[" << i << "]: " << aKey2[i] << " ");
00280       }
00281       printf("\n");
00282 
00283       printf("Test 5 - CompareRawSortKey():\n");
00284       res = CreateCollationKey(t, nsICollation::kCollationCaseSensitive, string1, &aKey3, &keyLength3);
00285       if(NS_FAILED(res)) {
00286         printf("\tFailed!! return value != NS_OK\n");
00287       }
00288 
00289       res = t->CompareRawSortKey(aKey1, keyLength1, aKey3, keyLength3, &result);
00290       if(NS_FAILED(res)) {
00291         printf("\tFailed!! return value != NS_OK\n");
00292       }
00293       printf("case sensitive comparison (string1 vs string2): %d\n", result);
00294       res = t->CompareRawSortKey(aKey3, keyLength3, aKey1, keyLength1, &result);
00295       if(NS_FAILED(res)) {
00296         printf("\tFailed!! return value != NS_OK\n");
00297       }
00298       printf("case sensitive comparison (string2 vs string1): %d\n", result);
00299 
00300       res = t->CompareRawSortKey(aKey2, keyLength2, aKey3, keyLength3, &result);
00301       if(NS_FAILED(res)) {
00302         printf("\tFailed!! return value != NS_OK\n");
00303       }
00304       printf("case insensitive comparison (string1 vs string2): %d\n", result);
00305 
00306       if (NULL != aKey1)
00307         delete[] aKey1; 
00308       if (NULL != aKey2)
00309         delete[] aKey2; 
00310       if (NULL != aKey3)
00311         delete[] aKey3; 
00312 
00313       res = CreateCollationKey(t, nsICollation::kCollationCaseSensitive, string1, &aKey1, &keyLength1);
00314       if(NS_FAILED(res)) {
00315         printf("\tFailed!! return value != NS_OK\n");
00316       }
00317       res = CreateCollationKey(t, nsICollation::kCollationCaseSensitive, string3, &aKey2, &keyLength2);
00318       if(NS_FAILED(res)) {
00319         printf("\tFailed!! return value != NS_OK\n");
00320       }
00321       res = CreateCollationKey(t, nsICollation::kCollationCaseSensitive, string4, &aKey3, &keyLength3);
00322       if(NS_FAILED(res)) {
00323         printf("\tFailed!! return value != NS_OK\n");
00324       }
00325       res = t->CompareRawSortKey(aKey1, keyLength1, aKey2, keyLength2, &result);
00326       if(NS_FAILED(res)) {
00327         printf("\tFailed!! return value != NS_OK\n");
00328       }
00329       printf("case sensitive comparison (string1 vs string3): %d\n", result);
00330       res = t->CompareRawSortKey(aKey1, keyLength1, aKey3, keyLength3, &result);
00331       if(NS_FAILED(res)) {
00332         printf("\tFailed!! return value != NS_OK\n");
00333       }
00334       printf("case sensitive comparison (string1 vs string4): %d\n", result);
00335 
00336       if (NULL != aKey1)
00337         delete[] aKey1; 
00338       if (NULL != aKey2)
00339         delete[] aKey2; 
00340       if (NULL != aKey3)
00341         delete[] aKey3; 
00342 
00343      res = t->Release();
00344 
00345      res = f->Release();
00346    }
00347    printf("==============================\n");
00348    printf("Finish nsICollation Test \n");
00349    printf("==============================\n");
00350 
00351 }
00352 
00353 // Sort test using qsort
00354 //
00355 
00356 static nsICollation *g_collationInst = NULL;
00357 static PRInt32 g_CollationStrength= nsICollation::kCollationCaseInSensitive;
00358 
00359 
00360 static void TestSortPrint1(nsString *string_array, int len)
00361 {
00362   for (int i = 0; i < len; i++) {
00363     //string_array[i].DebugDump(cout);
00364     DebugDump(string_array[i]);
00365   }
00366   printf("\n");
00367 }
00368 
00369 static void TestSortPrintToFile(nsString *string_array, int len)
00370 {
00371   for (int i = 0; i < len; i++) {
00372 #ifdef WIN32
00373     char cstr[512];
00374     int len = WideCharToMultiByte(GetACP(), 0,
00375                                   (LPCWSTR ) string_array[i].get(),  string_array[i].Length(),
00376                                   cstr, 512, NULL,  NULL);
00377     cstr[len] = '\0';
00378     fprintf(g_outfp, "%s\n", cstr);
00379 #else
00380     fprintf(g_outfp, "%s\n",
00381             NS_LossyConvertUCS2ToASCII(string_array[i]).get());
00382 #endif
00383   }
00384   fprintf(g_outfp, "\n");
00385 }
00386 
00387 static void DebugPrintCompResult(const nsString& string1, const nsString& string2, int result)
00388 {
00389 #ifdef WIN32
00390   char s[512];
00391   int len = WideCharToMultiByte(GetACP(), 0,
00392                                 (LPCWSTR ) string1.get(),  string1.Length(),
00393                                 s, 512, NULL,  NULL);
00394   s[len] = '\0';
00395   printf("%s ", s);
00396 
00397     switch ((int)result) {
00398     case 0:
00399       printf("==");
00400       break;
00401     case 1:
00402       printf(">");
00403       break;
00404     case -1:
00405       printf("<");
00406       break;
00407     }
00408 
00409   len = WideCharToMultiByte(GetACP(), 0,
00410                             (LPCWSTR ) string2.get(),  string2.Length(),
00411                             s, 512, NULL,  NULL);
00412   s[len] = '\0';
00413   printf(" %s\n", s);
00414 #else
00415     // Warning: casting to char*
00416     printf(NS_LossyConvertUCS2toASCII(string1).get() << ' ');
00417 
00418     switch ((int)result) {
00419     case 0:
00420       printf("==");
00421       break;
00422     case 1:
00423       printf('>');
00424       break;
00425     case -1:
00426       printf('<');
00427       break;
00428     }
00429     printf(' ' << NS_LossyConvertUCS2toASCII(string2).get() << '\n');
00430 #endif
00431 }
00432 
00433 static int compare1( const void *arg1, const void *arg2 )
00434 {
00435   nsString string1, string2;
00436   PRInt32 result,result2;
00437   nsresult res;
00438 
00439   string1 = *(nsString *) arg1;
00440   string2 = *(nsString *) arg2;
00441 
00442   res = g_collationInst->CompareString(g_CollationStrength, string1, string2, &result2);
00443 
00444   nsString key1,key2;
00445   res = g_collationInst->CreateSortKey(g_CollationStrength, string1, key1);
00446   NS_ASSERTION(NS_SUCCEEDED(res), "CreateSortKey");
00447   res = g_collationInst->CreateSortKey(g_CollationStrength, string2, key2);
00448   NS_ASSERTION(NS_SUCCEEDED(res), "CreateSortKey");
00449 
00450   // dump collation keys
00451   if (g_verbose) {
00452     int i;
00453     for (i = 0; i < key1.Length(); i++) 
00454       printf("%.2x", key1[i]);
00455     printf(" ");
00456     for (i = 0; i < key2.Length(); i++) 
00457       printf("%.2x", key2[i]);
00458     printf("\n");
00459   }
00460 
00461   res = g_collationInst->CompareSortKey(key1, key2, &result);
00462   NS_ASSERTION(NS_SUCCEEDED(res), "CreateSortKey");
00463   NS_ASSERTION(NS_SUCCEEDED((PRBool)(result == result2)), "result unmatch");
00464   if (g_verbose) {
00465     DebugPrintCompResult(string1, string2, result);
00466   }
00467 
00468   return (int) result;
00469 }
00470 
00471 
00472 typedef struct {
00473   PRUint8   *aKey;
00474   PRUint32  aLength;
00475 } collation_rec;
00476 
00477 static int compare2( const void *arg1, const void *arg2 )
00478 {
00479   collation_rec *keyrec1, *keyrec2;
00480   PRInt32 result;
00481   nsresult res;
00482 
00483   keyrec1 = (collation_rec *) arg1;
00484   keyrec2 = (collation_rec *) arg2;
00485 
00486   res = g_collationInst->CompareRawSortKey(keyrec1->aKey, keyrec1->aLength, 
00487                                         keyrec2->aKey, keyrec2->aLength, &result);
00488 
00489   return (int) result;
00490 }
00491 
00492 static void TestSortPrint2(collation_rec *key_array, int len)
00493 {
00494   PRUint32 aLength;
00495   PRUint8 *aKey;
00496 
00497   fflush(NULL);
00498   for (int i = 0; i < len; i++) {
00499     aLength = key_array[i].aLength;
00500     aKey = key_array[i].aKey;
00501     for (int j = 0; j < (int)aLength; j++) {
00502       printf("%.2x ", aKey[j]);
00503     }
00504     printf("\n");
00505   }
00506   printf("\n");
00507 }
00508 
00509 // Sort test by reading data from a file.
00510 //
00511 static void SortTestFile(nsICollation* collationInst, FILE* fp)
00512 {
00513   nsString string_array[256]; 
00514   char buf[512];
00515   int i = 0;
00516 
00517   // read lines and put them to nsStrings
00518   while (fgets(buf, 512, fp)) {
00519     if (*buf == '\n' || *buf == '\r')
00520       continue;
00521     // trim LF CR
00522     char *cp = buf + (strlen(buf) - 1);
00523     while (*cp) {
00524       if (*cp == '\n' || *cp == '\r')
00525         *cp = '\0';
00526       else
00527         break;
00528       cp--;
00529     }
00530 #ifdef WIN32
00531     wchar_t wcs[512];
00532     int len = MultiByteToWideChar(GetACP(), 0, buf, strlen(buf), wcs, 512);
00533     wcs[len] = L'\0';
00534     string_array[i].SetString((PRUnichar *)wcs);
00535 #else
00536     string_array[i].SetString(buf);
00537 #endif
00538     i++;
00539   }  
00540   printf("print string before sort\n");
00541   TestSortPrint1(string_array, i);
00542 
00543   g_collationInst = collationInst;
00544   qsort( (void *)string_array, i, sizeof(nsString), compare1 );
00545 
00546   printf("print string after sort\n");
00547   (g_outfp == NULL) ? TestSortPrint1(string_array, i) : TestSortPrintToFile(string_array, i);
00548 }
00549 
00550 // Use nsICollation for qsort.
00551 //
00552 static void TestSort(nsILocale *locale, PRInt32 collationStrength, FILE *fp)
00553 {
00554   nsresult res;
00555   nsICollationFactory *factoryInst;
00556   nsICollation *collationInst;
00557   PRInt32 strength;
00558   collation_rec key_array[5];
00559   PRUint8 *aKey;
00560   PRUint32 aLength;
00561   //nsString locale("en-US");
00562   nsString string1("AAC");
00563   nsString string2("aac");
00564   nsString string3("AAC");
00565   nsString string4("aac");
00566   nsString string5("AAC");
00567   nsString string_array[5];
00568 
00569   printf("==============================\n");
00570   printf("Start sort Test \n");
00571   printf("==============================\n");
00572 
00573   res = CallCreateInstance(kCollationFactoryCID, &factoryInst);
00574   if(NS_FAILED(res)) {
00575     printf("\tFailed!! return value != NS_OK\n");
00576   }
00577 
00578   res = factoryInst->CreateCollation(locale, &collationInst);
00579   if(NS_FAILED(res)) {
00580     printf("\tFailed!! return value != NS_OK\n");
00581   }
00582 
00583   // set collation strength
00584   g_CollationStrength = collationStrength;
00585   strength = g_CollationStrength;
00586 
00587   if (fp != NULL) {
00588     res = NS_ADDREF(collationInst);
00589     SortTestFile(collationInst, fp);
00590     NS_RELEASE(collationInst);
00591     return;
00592   }
00593 
00594   printf("==============================\n");
00595   printf("Sort Test by comparestring.\n");
00596   printf("==============================\n");
00597   string_array[0] = string1;
00598   string_array[1] = string2;
00599   string_array[2] = string3;
00600   string_array[3] = string4;
00601   string_array[4] = string5;
00602 
00603   printf("print string before sort\n");
00604   TestSortPrint1(string_array, 5);
00605 
00606   g_collationInst = collationInst;
00607   res = collationInst->AddRef();
00608   qsort( (void *)string_array, 5, sizeof(nsString), compare1 );
00609   res = collationInst->Release();
00610 
00611   printf("print string after sort\n");
00612   TestSortPrint1(string_array, 5);
00613 
00614   printf("==============================\n");
00615   printf("Sort Test by collation key.\n");
00616   printf("==============================\n");
00617 
00618 
00619   res = CreateCollationKey(collationInst, strength, string1, &aKey, &aLength);
00620   if(NS_FAILED(res)) {
00621     printf("\tFailed!! return value != NS_OK\n");
00622   }
00623   key_array[0].aKey = aKey;
00624   key_array[0].aLength = aLength;
00625 
00626   res = CreateCollationKey(collationInst, strength, string2, &aKey, &aLength);
00627   if(NS_FAILED(res)) {
00628     printf("\tFailed!! return value != NS_OK\n");
00629   }
00630   key_array[1].aKey = aKey;
00631   key_array[1].aLength = aLength;
00632 
00633   res = CreateCollationKey(collationInst, strength, string3, &aKey, &aLength);
00634   if(NS_FAILED(res)) {
00635     printf("\tFailed!! return value != NS_OK\n");
00636   }
00637   key_array[2].aKey = aKey;
00638   key_array[2].aLength = aLength;
00639 
00640   res = CreateCollationKey(collationInst, strength, string4, &aKey, &aLength);
00641   if(NS_FAILED(res)) {
00642     printf("\tFailed!! return value != NS_OK\n");
00643   }
00644   key_array[3].aKey = aKey;
00645   key_array[3].aLength = aLength;
00646 
00647   res = CreateCollationKey(collationInst, strength, string5, &aKey, &aLength);
00648   if(NS_FAILED(res)) {
00649     printf("\tFailed!! return value != NS_OK\n");
00650   }
00651   key_array[4].aKey = aKey;
00652   key_array[4].aLength = aLength;
00653 
00654   printf("print key before sort\n");
00655   TestSortPrint2(key_array, 5);
00656 
00657   g_collationInst = collationInst;
00658   res = collationInst->AddRef();
00659   qsort( (void *)key_array, 5, sizeof(collation_rec), compare2 );
00660   res = collationInst->Release();
00661 
00662   printf("print key after sort\n");
00663   TestSortPrint2(key_array, 5);
00664 
00665 
00666   res = collationInst->Release();
00667 
00668   res = factoryInst->Release();
00669 
00670   for (int i = 0; i < 5; i++) {
00671     delete [] key_array[i].aKey;
00672   }
00673 
00674   printf("==============================\n");
00675   printf("Finish sort Test \n");
00676   printf("==============================\n");
00677 }
00678 
00679 // Test all functions in nsIDateTimeFormat.
00680 //
00681 static void TestDateTimeFormat(nsILocale *locale)
00682 {
00683   nsresult res;
00684 
00685   printf("==============================\n");
00686   printf("Start nsIScriptableDateFormat Test \n");
00687   printf("==============================\n");
00688 
00689   nsIScriptableDateFormat *aScriptableDateFormat;
00690   res = CallCreateInstance(kDateTimeFormatCID, &aScriptableDateFormat);
00691   if(NS_FAILED(res) || ( aScriptableDateFormat == NULL ) ) {
00692     printf("\tnsIScriptableDateFormat CreateInstance failed\n");
00693   }
00694 
00695   PRUnichar *aUnichar;
00696   nsString aString;
00697   PRUnichar aLocaleUnichar[1];
00698   *aLocaleUnichar = 0;
00699   res = aScriptableDateFormat->FormatDateTime(aLocaleUnichar, kDateFormatShort, kTimeFormatSeconds,
00700                         1999, 
00701                         7, 
00702                         31, 
00703                         8, 
00704                         21, 
00705                         58,
00706                         &aUnichar);
00707   aString.SetString(aUnichar);
00708   DebugDump(aString);
00709 
00710   res = aScriptableDateFormat->FormatDate(aLocaleUnichar, kDateFormatLong,
00711                         1970, 
00712                         4, 
00713                         20, 
00714                         &aUnichar);
00715   aString.SetString(aUnichar);
00716   DebugDump(aString);
00717 
00718   res = aScriptableDateFormat->FormatTime(aLocaleUnichar, kTimeFormatSecondsForce24Hour,
00719                         13, 
00720                         59, 
00721                         31,
00722                         &aUnichar);
00723   aString.SetString(aUnichar);
00724   DebugDump(aString);
00725 
00726   aScriptableDateFormat->Release();
00727 
00728   printf("==============================\n");
00729   printf("Start nsIDateTimeFormat Test \n");
00730   printf("==============================\n");
00731 
00732   nsIDateTimeFormat *t = NULL;
00733   res = CallCreateInstance(kDateTimeFormatCID, &t);
00734        
00735   printf("Test 1 - CreateInstance():\n");
00736   if(NS_FAILED(res) || ( t == NULL ) ) {
00737     printf("\t1st CreateInstance failed\n");
00738   } else {
00739     t->Release();
00740   }
00741 
00742   res = CallCreateInstance(kDateTimeFormatCID, &t);
00743        
00744   if(NS_FAILED(res) || ( t == NULL ) ) {
00745     printf("\t2nd CreateInstance failed\n");
00746   } else {
00747   }
00748 
00749 
00750   nsAutoString dateString;
00751 //  nsString locale("en-GB");
00752   time_t  timetTime;
00753 
00754 
00755   printf("Test 2 - FormatTime():\n");
00756   time( &timetTime );
00757   res = t->FormatTime(locale, kDateFormatShort, kTimeFormatSeconds, timetTime, dateString);
00758   DebugDump(dateString);
00759 
00760   printf("Test 3 - FormatTMTime():\n");
00761   time_t ltime;
00762   time( &ltime );
00763 
00764   // try (almost) all format combination
00765   res = t->FormatTMTime(locale, kDateFormatNone, kTimeFormatNone, localtime( &ltime ), dateString);
00766   printf("kDateFormatNone, kTimeFormatNone:\n");
00767   DebugDump(dateString);
00768   res = t->FormatTMTime(locale, kDateFormatNone, kTimeFormatSeconds, localtime( &ltime ), dateString);
00769   printf("kDateFormatNone, kTimeFormatSeconds:\n");
00770   DebugDump(dateString);
00771   res = t->FormatTMTime(locale, kDateFormatNone, kTimeFormatNoSeconds, localtime( &ltime ), dateString);
00772   printf("kDateFormatNone, kTimeFormatNoSeconds:\n");
00773   DebugDump(dateString);
00774   res = t->FormatTMTime(locale, kDateFormatLong, kTimeFormatNone, localtime( &ltime ), dateString);
00775   printf("kDateFormatLong, kTimeFormatNone:\n");
00776   DebugDump(dateString);
00777   res = t->FormatTMTime(locale, kDateFormatLong, kTimeFormatSeconds, localtime( &ltime ), dateString);
00778   printf("kDateFormatLong, kTimeFormatSeconds:\n");
00779   DebugDump(dateString);
00780   res = t->FormatTMTime(locale, kDateFormatLong, kTimeFormatNoSeconds, localtime( &ltime ), dateString);
00781   printf("kDateFormatLong, kTimeFormatNoSeconds:\n");
00782   DebugDump(dateString);
00783   res = t->FormatTMTime(locale, kDateFormatShort, kTimeFormatNone, localtime( &ltime ), dateString);
00784   printf("kDateFormatShort, kTimeFormatNone:\n");
00785   DebugDump(dateString);
00786   res = t->FormatTMTime(locale, kDateFormatShort, kTimeFormatSeconds, localtime( &ltime ), dateString);
00787   printf("kDateFormatShort, kTimeFormatSeconds:\n");
00788   DebugDump(dateString);
00789   res = t->FormatTMTime(locale, kDateFormatShort, kTimeFormatNoSeconds, localtime( &ltime ), dateString);
00790   printf("kDateFormatShort, kTimeFormatNoSeconds:\n");
00791   DebugDump(dateString);
00792   res = t->FormatTMTime(locale, kDateFormatYearMonth, kTimeFormatNone, localtime( &ltime ), dateString);
00793   printf("kDateFormatYearMonth, kTimeFormatNone:\n");
00794   DebugDump(dateString);
00795   res = t->FormatTMTime(locale, kDateFormatYearMonth, kTimeFormatSeconds, localtime( &ltime ), dateString);
00796   printf("kDateFormatYearMonth, kTimeFormatSeconds:\n");
00797   DebugDump(dateString);
00798   res = t->FormatTMTime(locale, kDateFormatYearMonth, kTimeFormatNoSeconds, localtime( &ltime ), dateString);
00799   printf("kDateFormatYearMonth, kTimeFormatNoSeconds:\n");
00800   DebugDump(dateString);
00801   res = t->FormatTMTime(locale, kDateFormatWeekday, kTimeFormatNone, localtime( &ltime ), dateString);
00802   printf("kDateFormatWeekday, kTimeFormatNone:\n");
00803   DebugDump(dateString);
00804   res = t->FormatTMTime(locale, kDateFormatWeekday, kTimeFormatSeconds, localtime( &ltime ), dateString);
00805   printf("kDateFormatWeekday, kTimeFormatSeconds:\n");
00806   DebugDump(dateString);
00807   res = t->FormatTMTime(locale, kDateFormatWeekday, kTimeFormatNoSeconds, localtime( &ltime ), dateString);
00808   printf("kDateFormatWeekday, kTimeFormatNoSeconds:\n");
00809   DebugDump(dateString);
00810   res = t->FormatTMTime(locale, kDateFormatWeekday, kTimeFormatSecondsForce24Hour, localtime( &ltime ), dateString);
00811   printf("kDateFormatWeekday, kTimeFormatSecondsForce24Hour:\n");
00812   DebugDump(dateString);
00813   res = t->FormatTMTime(locale, kDateFormatWeekday, kTimeFormatNoSecondsForce24Hour, localtime( &ltime ), dateString);
00814   printf("kDateFormatWeekday, kTimeFormatNoSecondsForce24Hour:\n");
00815   DebugDump(dateString);
00816 
00817   res = t->Release();
00818   
00819   printf("==============================\n");
00820   printf("Finish nsIDateTimeFormat Test \n");
00821   printf("==============================\n");
00822 }
00823 
00824 static nsresult NewLocale(const nsString* localeName, nsILocale** locale)
00825 {
00826   nsresult res;
00827 
00828   nsCOMPtr<nsILocaleFactory> localeFactory = do_GetClassObject(kLocaleFactoryCID, &res);
00829   if (NS_FAILED(res) || localeFactory == nsnull) printf("FindFactory nsILocaleFactory failed\n");
00830 
00831   res = localeFactory->NewLocale(localeName, locale);
00832   if (NS_FAILED(res) || locale == nsnull) printf("NewLocale failed\n");
00833 
00834   return res;
00835 }
00836 
00837 static void Test_nsLocale()
00838 {
00839 #if defined(XP_MAC) || defined(XP_MACOSX)
00840   nsAutoString localeName;
00841   nsCOMPtr<nsIMacLocale> macLocale;
00842   short script, lang;
00843   nsresult res;
00844 
00845   nsCOMPtr<nsIMacLocale> win32Locale = do_CreateInstance(kMacLocaleFactoryCID);
00846   if (macLocale) {
00847     localeName.AssignLiteral("en-US");
00848     res = macLocale->GetPlatformLocale(localeName, &script, &lang);
00849     printf("script for en-US is 0\n");
00850     printf("result: script = %d lang = %d\n", script, lang);
00851 
00852     localeName.AssignLiteral("en-GB");
00853     res = macLocale->GetPlatformLocale(localeName, &script, &lang);
00854     printf("script for en-GB is 0\n");
00855     printf("result: script = %d lang = %d\n", script, lang);
00856 
00857     localeName.AssignLiteral("fr-FR");
00858     res = macLocale->GetPlatformLocale(localeName, &script, &lang);
00859     printf("script for fr-FR is 0\n");
00860     printf("result: script = %d lang = %d\n", script, lang);
00861 
00862     localeName.AssignLiteral("de-DE");
00863     res = macLocale->GetPlatformLocale(localeName, &script, &lang);
00864     printf("script for de-DE is 0\n");
00865     printf("result: script = %d lang = %d\n", script, lang);
00866 
00867     localeName.AssignLiteral("ja-JP");
00868     res = macLocale->GetPlatformLocale(localeName, &script, &lang);
00869     printf("script for ja-JP is 1\n");
00870     printf("result: script = %d lang = %d\n", script, lang);
00871   }
00872 #elif defined(XP_WIN) || defined(XP_OS2)
00873   nsAutoString localeName;
00874   LCID lcid;
00875   nsresult res;
00876 
00877   nsCOMPtr<nsIWin32Locale> win32Locale = do_CreateInstance(kWin32LocaleFactoryCID);
00878   if (win32Locale) {
00879     localeName.AssignLiteral("en-US");
00880     res = win32Locale->GetPlatformLocale(localeName, &lcid);
00881     printf("LCID for en-US is 1033\n");
00882     printf("result: locale = %s LCID = 0x%0.4x %d\n", NS_LossyConvertUCS2toASCII(localeName).get(), lcid, lcid);
00883 
00884     localeName.AssignLiteral("en-GB");
00885     res = win32Locale->GetPlatformLocale(localeName, &lcid);
00886     printf("LCID for en-GB is 2057\n");
00887     printf("result: locale = %s LCID = 0x%0.4x %d\n", NS_LossyConvertUCS2toASCII(localeName).get(), lcid, lcid);
00888 
00889     localeName.AssignLiteral("fr-FR");
00890     res = win32Locale->GetPlatformLocale(localeName, &lcid);
00891     printf("LCID for fr-FR is 1036\n");
00892     printf("result: locale = %s LCID = 0x%0.4x %d\n", NS_LossyConvertUCS2toASCII(localeName).get(), lcid, lcid);
00893 
00894     localeName.AssignLiteral("de-DE");
00895     res = win32Locale->GetPlatformLocale(localeName, &lcid);
00896     printf("LCID for de-DE is 1031\n");
00897     printf("result: locale = %s LCID = 0x%0.4x %d\n", NS_LossyConvertUCS2toASCII(localeName).get(), lcid, lcid);
00898 
00899     localeName.AssignLiteral("ja-JP");
00900     res = win32Locale->GetPlatformLocale(localeName, &lcid);
00901     printf("LCID for ja-JP is 1041\n");
00902     printf("result: locale = %s LCID = 0x%0.4x %d\n", NS_LossyConvertUCS2toASCII(localeName).get(), lcid, lcid);
00903 
00904   }
00905 #else
00906   nsAutoString localeName;
00907   char locale[32];
00908   size_t length = 32;
00909   nsresult res;
00910 
00911   nsCOMPtr<nsIPosixLocale> posixLocale = do_CreateInstance(kPosixLocaleFactoryCID);
00912   if (posixLocale) {
00913     localeName.AssignLiteral("en-US");
00914     res = posixLocale->GetPlatformLocale(localeName, locale, length);
00915     printf("result: locale = %s POSIX = %s\n", NS_LossyConvertUCS2toASCII(localeName).get(), locale);
00916 
00917     localeName.AssignLiteral("en-GB");
00918     res = posixLocale->GetPlatformLocale(localeName, locale, length);
00919     printf("result: locale = %s POSIX = %s\n", NS_LossyConvertUCS2toASCII(localeName).get(), locale);
00920 
00921     localeName.AssignLiteral("fr-FR");
00922     res = posixLocale->GetPlatformLocale(localeName, locale, length);
00923     printf("result: locale = %s POSIX = %s\n", NS_LossyConvertUCS2toASCII(localeName).get(), locale);
00924 
00925     localeName.AssignLiteral("de-DE");
00926     res = posixLocale->GetPlatformLocale(localeName, locale, length);
00927     printf("result: locale = %s POSIX = %s\n", NS_LossyConvertUCS2toASCII(localeName).get(), locale);
00928 
00929     localeName.AssignLiteral("ja-JP");
00930     res = posixLocale->GetPlatformLocale(localeName, locale, length);
00931     printf("result: locale = %s POSIX = %s\n", NS_LossyConvertUCS2toASCII(localeName).get(), locale);
00932 
00933   }
00934   else {
00935     printf("Fail: CreateInstance PosixLocale\n");
00936   }
00937 #endif
00938 }
00939 
00940 static char* get_option(int argc, char** argv, char* arg)
00941 {
00942   for (int i = 0; i < argc; i++) {
00943     if (!strcmp(argv[i], arg)) {
00944       NS_ASSERTION((i <= argc && argv[i+1]), "option not specified");
00945       return argv[i+1];
00946     }
00947   }
00948   return NULL;
00949 }
00950 static char* find_option(int argc, char** argv, char* arg)
00951 {
00952   for (int i = 0; i < argc; i++) {
00953     if (!strcmp(argv[i], arg)) {
00954       return argv[i];
00955     }
00956   }
00957   return NULL;
00958 }
00959 
00960 #ifdef XP_MAC
00961 #define kMaxArgs 16
00962 static char g_arg_array[kMaxArgs][256];
00963 static int make_args(char **argv)
00964 {
00965   int argc = 0;
00966   char *token;
00967   char s[256];
00968   char seps[] = " ,\t";
00969        
00970   strcpy(g_arg_array[argc], "LocaleSelfTest");
00971   argc++;
00972 
00973   printf("%s\ntype option(s) then hit return\n", g_usage);
00974   if (gets(s)) {
00975     token = strtok(s, seps);
00976     while (token != NULL && argc < kMaxArgs) {
00977       strcpy(g_arg_array[argc], token);
00978       argv[argc] = g_arg_array[argc];
00979       argc++;
00980       token = strtok(NULL, seps);
00981     }
00982          printf("\noptions specified: ");
00983 
00984     for (int i = 0; i < argc; i++) {
00985       printf("%s ", argv[i]);
00986     }
00987     printf("\n");
00988   }
00989   
00990   return argc;
00991 }
00992 #endif//XP_MAC
00993 
00994 int main(int argc, char** argv) {
00995 #ifdef XP_MAC
00996   char *mac_argv[kMaxArgs];
00997   argc = make_args(mac_argv);
00998   argv = mac_argv;
00999 #endif//XP_MAC
01000   nsCOMPtr<nsILocale> locale;
01001   nsresult res; 
01002 
01003        nsCOMPtr<nsILocaleFactory>  localeFactory = do_GetClassObject(kLocaleFactoryCID, &res);
01004   if (NS_FAILED(res) || localeFactory == nsnull) printf("FindFactory nsILocaleFactory failed\n");
01005 
01006   res = localeFactory->GetApplicationLocale(getter_AddRefs(locale));
01007   if (NS_FAILED(res) || locale == nsnull) printf("GetApplicationLocale failed\n");
01008   
01009   // --------------------------------------------
01010     PRInt32 strength = nsICollation::kCollationCaseInSensitive;
01011     FILE *fp = NULL;
01012 
01013   if (argc == 1) {
01014     TestCollation(locale);
01015     TestSort(locale, nsICollation::kCollationCaseInSensitive, NULL);
01016     TestDateTimeFormat(locale);
01017   }
01018   else {
01019     char *s;
01020     s = find_option(argc, argv, "-h");
01021     if (s) {
01022       printf(argv[0] << g_usage);
01023       return 0;
01024     }
01025     s = find_option(argc, argv, "-v");
01026     if (s) {
01027       g_verbose = PR_TRUE;
01028       //test for locale
01029       Test_nsLocale();
01030     }
01031     s = get_option(argc, argv, "-f");
01032     if (s) {
01033       fp = fopen(s, "r");
01034     }
01035     s = get_option(argc, argv, "-o");
01036     if (s) {
01037       g_outfp = fopen(s, "w");
01038     }
01039     s = find_option(argc, argv, "-case");
01040     if (s) {
01041       strength = nsICollation::kCollationCaseSensitive;
01042     }
01043     s = get_option(argc, argv, "-locale");
01044     if (s) {
01045       nsString localeName(s);
01046       res = NewLocale(localeName, getter_AddRefs(locale));  // reset the locale
01047     }
01048 
01049     // print locale string
01050     nsAutoString localeStr;
01051     locale->GetCategory(NS_LITERAL_STRING("NSILOCALE_COLLATE"), localeStr);
01052     printf("locale setting for collation is ");
01053     DebugDump(localeStr);
01054     locale->GetCategory(NS_LITERAL_STRING("NSILOCALE_TIME"), localeStr);
01055     printf("locale setting for time is ");
01056     DebugDump(localeStr);
01057 
01058     while (argc--) {
01059       if (!strcmp(argv[argc], "-col"))
01060         TestCollation(locale);
01061       else if (!strcmp(argv[argc], "-sort"))
01062         TestSort(locale, strength, fp);
01063       else if (!strcmp(argv[argc], "-date"))
01064         TestDateTimeFormat(locale);
01065     }
01066     if (fp != NULL) {
01067       fclose(fp);
01068     }
01069     if (g_outfp != NULL) {
01070       fclose(g_outfp);
01071     }
01072   }
01073 
01074   // --------------------------------------------
01075 
01076   printf("Finish All The Test Cases\n");
01077 
01078   return 0;
01079 }