tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

y2k.c (33951B)


      1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* This Source Code Form is subject to the terms of the Mozilla Public
      3 * License, v. 2.0. If a copy of the MPL was not distributed with this
      4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      5 
      6 /*
      7 * file: y2k.c
      8 * description: Test for y2k compliance for NSPR.
      9 *
     10 * Sep 1999. lth. Added "Sun" specified dates to the test data.
     11 */
     12 /***********************************************************************
     13 ** Includes
     14 ***********************************************************************/
     15 /* Used to get the command line option */
     16 #include "plgetopt.h"
     17 
     18 #include "prinit.h"
     19 #include "prtime.h"
     20 #include "prprf.h"
     21 #include "prlog.h"
     22 
     23 #include <stdio.h>
     24 #include <stdlib.h>
     25 #include <string.h>
     26 
     27 #define PRINT_DETAILS
     28 
     29 int failed_already = 0;
     30 PRBool debug_mode = PR_FALSE;
     31 
     32 static char* dayOfWeek[] = {"Sun", "Mon", "Tue", "Wed",
     33                            "Thu", "Fri", "Sat", "???"};
     34 static char* month[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
     35                        "Aug", "Sep", "Oct", "Nov", "Dec", "???"};
     36 
     37 PRLogModuleInfo* lm;
     38 
     39 static void PrintExplodedTime(const PRExplodedTime* et) {
     40  PRInt32 totalOffset;
     41  PRInt32 hourOffset, minOffset;
     42  const char* sign;
     43 
     44  /* Print day of the week, month, day, hour, minute, and second */
     45  printf("%s %s %2ld %02ld:%02ld:%02ld ", dayOfWeek[et->tm_wday],
     46         month[et->tm_month], et->tm_mday, et->tm_hour, et->tm_min, et->tm_sec);
     47 
     48  /* Print year */
     49  printf("%hd ", et->tm_year);
     50 
     51  /* Print time zone */
     52  totalOffset = et->tm_params.tp_gmt_offset + et->tm_params.tp_dst_offset;
     53  if (totalOffset == 0) {
     54    printf("UTC ");
     55  } else {
     56    sign = "+";
     57    if (totalOffset < 0) {
     58      totalOffset = -totalOffset;
     59      sign = "-";
     60    }
     61    hourOffset = totalOffset / 3600;
     62    minOffset = (totalOffset % 3600) / 60;
     63    printf("%s%02ld%02ld ", sign, hourOffset, minOffset);
     64  }
     65 #ifdef PRINT_DETAILS
     66  printf("{%d, %d, %d, %d, %d, %d, %d, %d, %d, { %d, %d}}\n", et->tm_usec,
     67         et->tm_sec, et->tm_min, et->tm_hour, et->tm_mday, et->tm_month,
     68         et->tm_year, et->tm_wday, et->tm_yday, et->tm_params.tp_gmt_offset,
     69         et->tm_params.tp_dst_offset);
     70 #endif
     71 }
     72 
     73 static int ExplodedTimeIsEqual(const PRExplodedTime* et1,
     74                               const PRExplodedTime* et2) {
     75  if (et1->tm_usec == et2->tm_usec && et1->tm_sec == et2->tm_sec &&
     76      et1->tm_min == et2->tm_min && et1->tm_hour == et2->tm_hour &&
     77      et1->tm_mday == et2->tm_mday && et1->tm_month == et2->tm_month &&
     78      et1->tm_year == et2->tm_year && et1->tm_wday == et2->tm_wday &&
     79      et1->tm_yday == et2->tm_yday &&
     80      et1->tm_params.tp_gmt_offset == et2->tm_params.tp_gmt_offset &&
     81      et1->tm_params.tp_dst_offset == et2->tm_params.tp_dst_offset) {
     82    return 1;
     83  } else {
     84    return 0;
     85  }
     86 }
     87 
     88 /*
     89 * TEST 1: TestExplodeImplodeTime
     90 * Description:
     91 * For each given timestamp T (a PRTime value), call PR_ExplodeTime
     92 * with GMT, US Pacific, and local time parameters.  Compare the
     93 * resulting calendar (exploded) time values with the expected
     94 * values.
     95 *
     96 * Note: the expected local time values depend on the local time
     97 * zone.  The local time values stored in this test are for the US
     98 * Pacific Time Zone.  If you are running this test in a different
     99 * time zone, you need to modify the values in the localt array.
    100 * An example is provided below.
    101 *
    102 * Call PR_ImplodeTime for each of the exploded values and compare
    103 * the resulting PRTime values with the original input.
    104 *
    105 * This test is run for the values of time T corresponding to the
    106 * following dates:
    107 * - 12/31/99 - before 2000
    108 * - 01/01/00 - after 2000
    109 * - Leap year - Feb 29, 2000
    110 * - March 1st, 2001 (after 1 year)
    111 * - March 1st, 2005 (after second leap year)
    112 * - 09/09/99 (used by some programs as an end of file marker)
    113 *
    114 * Call PR_Now, convert to calendar time using PR_ExplodeTime and
    115 * manually check the result for correctness. The time should match
    116 * the system clock.
    117 *
    118 * Tested functions: PR_Now, PR_ExplodeTime, PR_ImplodeTime,
    119 * PR_LocalTimeParameters, PR_GMTParameters.
    120 */
    121 
    122 static PRTime prt[] = {
    123    LL_INIT(220405, 2133125120), /* 946634400000000 */
    124    LL_INIT(220425, 2633779200), /* 946720800000000 */
    125    LL_INIT(221612, 2107598848), /* 951818400000000 */
    126    LL_INIT(228975, 663398400),  /* 983440800000000 */
    127    LL_INIT(258365, 1974568960), /* 1109671200000000 */
    128    LL_INIT(218132, 1393788928), /* 936871200000000 */
    129    /* Sun's dates follow */
    130    LL_INIT(213062, 4077979648), /* Dec 31 1998 10:00:00 */
    131    LL_INIT(218152, 1894443008), /* Sep 10 1999 10:00:00 */
    132    LL_INIT(221592, 1606944768), /* Feb 28 2000 10:00:00 */
    133    LL_INIT(227768, 688924672),  /* Dec 31 2000 10:00:00 */
    134    LL_INIT(227788, 1189578752), /* Jan 1  2001 10:00:00 */
    135 };
    136 
    137 static PRExplodedTime gmt[] = {
    138    {0, 0, 0, 10, 31, 11, 1999, 5, 364, {0, 0}}, /* 1999/12/31 10:00:00 GMT */
    139    {0, 0, 0, 10, 1, 0, 2000, 6, 0, {0, 0}},     /* 2000/01/01 10:00:00 GMT */
    140    {0, 0, 0, 10, 29, 1, 2000, 2, 59, {0, 0}},   /* 2000/02/29 10:00:00 GMT */
    141    {0, 0, 0, 10, 1, 2, 2001, 4, 59, {0, 0}},    /* 2001/3/1 10:00:00 GMT */
    142    {0, 0, 0, 10, 1, 2, 2005, 2, 59, {0, 0}},    /* 2005/3/1 10:00:00 GMT */
    143    {0, 0, 0, 10, 9, 8, 1999, 4, 251, {0, 0}},   /* 1999/9/9 10:00:00 GMT */
    144    /* Sun's dates follow */
    145    {0, 0, 0, 10, 31, 11, 1998, 4, 364, {0, 0}}, /* 12/31/1998 10:00:00 GMT */
    146    {0, 0, 0, 10, 10, 8, 1999, 5, 252, {0, 0}},  /* 9/10/1999 10:00:00 GMT */
    147    {0, 0, 0, 10, 28, 1, 2000, 1, 58, {0, 0}},   /* 2/28/2000 10:00:00 GMT */
    148    {0, 0, 0, 10, 31, 11, 2000, 0, 365, {0, 0}}, /* 12/31/2000 10:00:00 GMT */
    149    {0, 0, 0, 10, 1, 0, 2001, 1, 0, {0, 0}}      /* 1/1/2001 10:00:00 GMT */
    150 };
    151 
    152 static PRExplodedTime uspt[] = {
    153    {0, 0, 0, 2, 31, 11, 1999, 5, 364, {-28800, 0}}, /* 1999/12/31 2:00:00 PST
    154                                                      */
    155    {0, 0, 0, 2, 1, 0, 2000, 6, 0, {-28800, 0}},   /* 2000/01/01 2:00:00 PST */
    156    {0, 0, 0, 2, 29, 1, 2000, 2, 59, {-28800, 0}}, /* 2000/02/29 2:00:00 PST */
    157    {0, 0, 0, 2, 1, 2, 2001, 4, 59, {-28800, 0}},  /* 2001/3/1 2:00:00 PST */
    158    {0, 0, 0, 2, 1, 2, 2005, 2, 59, {-28800, 0}},  /* 2005/3/1 2:00:00 PST */
    159    {0, 0, 0, 3, 9, 8, 1999, 4, 251, {-28800, 3600}}, /* 1999/9/9 3:00:00 PDT */
    160    /* Sun's dates follow */
    161    {0, 0, 0, 2, 31, 11, 1998, 4, 364, {-28800, 0}}, /* 12/31/1998 00:00:00 GMT
    162                                                      */
    163    {0, 0, 0, 3, 10, 8, 1999, 5, 252, {-28800, 3600}}, /* 9/10/1999 00:00:00 GMT
    164                                                        */
    165    {0, 0, 0, 2, 28, 1, 2000, 1, 58, {-28800, 0}}, /* 2/28/2000 00:00:00 GMT */
    166    {0, 0, 0, 2, 31, 11, 2000, 0, 365, {-28800, 0}}, /* 12/31/2000 00:00:00 GMT
    167                                                      */
    168    {0, 0, 0, 2, 1, 0, 2001, 1, 0, {-28800, 0}}      /* 1/1/2001 00:00:00 GMT */
    169 };
    170 
    171 /*
    172 * This test assumes that we are in US Pacific Time Zone.
    173 * If you are running this test in a different time zone,
    174 * you need to modify the localt array and fill in the
    175 * expected results.  The localt array for US Eastern Time
    176 * Zone is provided as an example.
    177 */
    178 static PRExplodedTime localt[] = {
    179    {0, 0, 0, 2, 31, 11, 1999, 5, 364, {-28800, 0}}, /* 1999/12/31 2:00:00 PST
    180                                                      */
    181    {0, 0, 0, 2, 1, 0, 2000, 6, 0, {-28800, 0}},   /* 2000/01/01 2:00:00 PST */
    182    {0, 0, 0, 2, 29, 1, 2000, 2, 59, {-28800, 0}}, /* 2000/02/29 2:00:00 PST */
    183    {0, 0, 0, 2, 1, 2, 2001, 4, 59, {-28800, 0}},  /* 2001/3/1 2:00:00 PST */
    184    {0, 0, 0, 2, 1, 2, 2005, 2, 59, {-28800, 0}},  /* 2005/3/1 2:00:00 PST */
    185    {0, 0, 0, 3, 9, 8, 1999, 4, 251, {-28800, 3600}}, /* 1999/9/9 3:00:00 PDT */
    186    /* Sun's dates follow */
    187    {0, 0, 0, 2, 31, 11, 1998, 4, 364, {-28800, 0}}, /* 12/31/1998 00:00:00 GMT
    188                                                      */
    189    {0, 0, 0, 3, 10, 8, 1999, 5, 252, {-28800, 3600}}, /* 9/10/1999 00:00:00 GMT
    190                                                        */
    191    {0, 0, 0, 2, 28, 1, 2000, 1, 58, {-28800, 0}}, /* 2/28/2000 00:00:00 GMT */
    192    {0, 0, 0, 2, 31, 11, 2000, 0, 365, {-28800, 0}}, /* 12/31/2000 00:00:00 GMT
    193                                                      */
    194    {0, 0, 0, 2, 1, 0, 2001, 1, 0, {-28800, 0}}      /* 1/1/2001 00:00:00 GMT */
    195 };
    196 
    197 #ifdef US_EASTERN_TIME
    198 static PRExplodedTime localt[] = {
    199    {0, 0, 0, 5, 31, 11, 1999, 5, 364, {-18000, 0}}, /* 1999/12/31 2:00:00 EST
    200                                                      */
    201    {0, 0, 0, 5, 1, 0, 2000, 6, 0, {-18000, 0}},   /* 2000/01/01 2:00:00 EST */
    202    {0, 0, 0, 5, 29, 1, 2000, 2, 59, {-18000, 0}}, /* 2000/02/29 2:00:00 EST */
    203    {0, 0, 0, 5, 1, 2, 2001, 4, 59, {-18000, 0}},  /* 2001/3/1 2:00:00 EST */
    204    {0, 0, 0, 5, 1, 2, 2005, 2, 59, {-18000, 0}},  /* 2005/3/1 2:00:00 EST */
    205    {0, 0, 0, 6, 9, 8, 1999, 4, 251, {-18000, 3600}}, /* 1999/9/9 3:00:00 EDT */
    206    /* Sun's dates follow */
    207    {0, 0, 0, 5, 31, 11, 1998, 4, 364, {-18000 0}},   /* 12/31/1998 00:00:00 GMT
    208                                                       */
    209    {0, 0, 0, 6, 10, 8, 1999, 5, 252, {-18000 3600}}, /* 9/10/1999 00:00:00 GMT
    210                                                       */
    211    {0, 0, 0, 5, 28, 1, 2000, 1, 58, {-18000 0}},   /* 2/28/2000 00:00:00 GMT */
    212    {0, 0, 0, 5, 31, 11, 2000, 0, 365, {-18000 0}}, /* 12/31/2000 00:00:00 GMT
    213                                                     */
    214    {0, 0, 0, 5, 1, 0, 2001, 1, 0, {-18000 0}}      /* 1/1/2001 00:00:00 GMT */
    215 };
    216 #endif
    217 
    218 static PRStatus TestExplodeImplodeTime(void) {
    219  PRTime prt_tmp;
    220  PRTime now;
    221  int idx;
    222  int array_size = sizeof(prt) / sizeof(PRTime);
    223  PRExplodedTime et_tmp;
    224  char buf[1024];
    225 
    226  for (idx = 0; idx < array_size; idx++) {
    227    PR_snprintf(buf, sizeof(buf), "%lld", prt[idx]);
    228    if (debug_mode) {
    229      printf("Time stamp %s\n", buf);
    230    }
    231    PR_ExplodeTime(prt[idx], PR_GMTParameters, &et_tmp);
    232    if (!ExplodedTimeIsEqual(&et_tmp, &gmt[idx])) {
    233      fprintf(stderr, "GMT not equal\n");
    234      PrintExplodedTime(&et_tmp);
    235      PrintExplodedTime(&gmt[idx]);
    236      exit(1);
    237    }
    238    prt_tmp = PR_ImplodeTime(&et_tmp);
    239    if (LL_NE(prt_tmp, prt[idx])) {
    240      fprintf(stderr, "PRTime not equal\n");
    241      exit(1);
    242    }
    243    if (debug_mode) {
    244      printf("GMT: ");
    245      PrintExplodedTime(&et_tmp);
    246      printf("\n");
    247    }
    248 
    249    PR_ExplodeTime(prt[idx], PR_USPacificTimeParameters, &et_tmp);
    250    if (!ExplodedTimeIsEqual(&et_tmp, &uspt[idx])) {
    251      fprintf(stderr, "US Pacific Time not equal\n");
    252      PrintExplodedTime(&et_tmp);
    253      PrintExplodedTime(&uspt[idx]);
    254      exit(1);
    255    }
    256    prt_tmp = PR_ImplodeTime(&et_tmp);
    257    if (LL_NE(prt_tmp, prt[idx])) {
    258      fprintf(stderr, "PRTime not equal\n");
    259      exit(1);
    260    }
    261    if (debug_mode) {
    262      printf("US Pacific Time: ");
    263      PrintExplodedTime(&et_tmp);
    264      printf("\n");
    265    }
    266 
    267    PR_ExplodeTime(prt[idx], PR_LocalTimeParameters, &et_tmp);
    268    if (!ExplodedTimeIsEqual(&et_tmp, &localt[idx])) {
    269      fprintf(stderr, "not equal\n");
    270      PrintExplodedTime(&et_tmp);
    271      PrintExplodedTime(&localt[idx]);
    272      exit(1);
    273    }
    274    prt_tmp = PR_ImplodeTime(&et_tmp);
    275    if (LL_NE(prt_tmp, prt[idx])) {
    276      fprintf(stderr, "not equal\n");
    277      exit(1);
    278    }
    279    if (debug_mode) {
    280      printf("Local time:");
    281      PrintExplodedTime(&et_tmp);
    282      printf("\n\n");
    283    }
    284  }
    285 
    286  now = PR_Now();
    287  PR_ExplodeTime(now, PR_GMTParameters, &et_tmp);
    288  printf("Current GMT is ");
    289  PrintExplodedTime(&et_tmp);
    290  printf("\n");
    291  prt_tmp = PR_ImplodeTime(&et_tmp);
    292  if (LL_NE(prt_tmp, now)) {
    293    fprintf(stderr, "not equal\n");
    294    exit(1);
    295  }
    296  PR_ExplodeTime(now, PR_USPacificTimeParameters, &et_tmp);
    297  printf("Current US Pacific Time is ");
    298  PrintExplodedTime(&et_tmp);
    299  printf("\n");
    300  prt_tmp = PR_ImplodeTime(&et_tmp);
    301  if (LL_NE(prt_tmp, now)) {
    302    fprintf(stderr, "not equal\n");
    303    exit(1);
    304  }
    305  PR_ExplodeTime(now, PR_LocalTimeParameters, &et_tmp);
    306  printf("Current local time is ");
    307  PrintExplodedTime(&et_tmp);
    308  printf("\n");
    309  prt_tmp = PR_ImplodeTime(&et_tmp);
    310  if (LL_NE(prt_tmp, now)) {
    311    fprintf(stderr, "not equal\n");
    312    exit(1);
    313  }
    314  printf("Please verify the results\n\n");
    315 
    316  if (debug_mode) {
    317    printf("Test 1 passed\n");
    318  }
    319  return PR_SUCCESS;
    320 }
    321 /* End of Test 1: TestExplodeImplodeTime */
    322 
    323 /*
    324 * Test 2: Normalize Time
    325 */
    326 
    327 /*
    328 * time increment for addition to PRExplodeTime
    329 */
    330 typedef struct time_increment {
    331  PRInt32 ti_usec;
    332  PRInt32 ti_sec;
    333  PRInt32 ti_min;
    334  PRInt32 ti_hour;
    335 } time_increment_t;
    336 
    337 /*
    338 * Data for testing PR_Normalize
    339 *      Add the increment to base_time, normalize it to GMT and US Pacific
    340 *      Time zone.
    341 */
    342 typedef struct normalize_test_data {
    343  PRExplodedTime base_time;
    344  time_increment_t increment;
    345  PRExplodedTime expected_gmt_time;
    346  PRExplodedTime expected_uspt_time;
    347 } normalize_test_data_t;
    348 
    349 /*
    350 * Test data -  the base time values cover dates of interest including y2k - 1,
    351 *              y2k + 1, y2k leap year, y2k leap date + 1year,
    352 *              y2k leap date + 4 years
    353 */
    354 normalize_test_data_t normalize_test_array[] = {
    355    /*usec sec min hour  mday  mo  year  wday yday {gmtoff, dstoff }*/
    356 
    357    /* Fri 12/31/1999 19:32:48 PST */
    358    {
    359        {0, 48, 32, 19, 31, 11, 1999, 5, 364, {-28800, 0}},
    360        {0, 0, 30, 20},
    361        {0, 48, 2, 0, 2, 0, 2000, 0, 1, {0, 0}}, /*Sun Jan 2 00:02:48 UTC 2000*/
    362        {0, 48, 2, 16, 1, 0, 2000, 6, 0, {-28800, 0}}, /* Sat Jan 1 16:02:48
    363                                                        PST 2000*/
    364    },
    365    /* Fri 99-12-31 23:59:02 GMT */
    366    {
    367        {0, 2, 59, 23, 31, 11, 1999, 5, 364, {0, 0}},
    368        {0, 0, 45, 0},
    369        {0, 2, 44, 0, 1, 0, 2000, 6, 0, {0, 0}}, /* Sat Jan 1 00:44:02 UTC
    370                                                    2000*/
    371        {0, 2, 44, 16, 31, 11, 1999, 5, 364, {-28800, 0}} /*Fri Dec 31 16:44:02
    372                                                        PST 1999*/
    373    },
    374    /* 99-12-25 12:00:00 GMT */
    375    {
    376        {0, 0, 0, 12, 25, 11, 1999, 6, 358, {0, 0}},
    377        {0, 0, 0, 364 * 24},
    378        {0, 0, 0, 12, 23, 11, 2000, 6, 357, {0, 0}},    /*Sat Dec 23 12:00:00
    379                                                       2000 UTC*/
    380        {0, 0, 0, 4, 23, 11, 2000, 6, 357, {-28800, 0}} /*Sat Dec 23 04:00:00
    381                                                        2000 -0800*/
    382    },
    383    /* 00-01-1 00:00:00 PST */
    384    {
    385        {0, 0, 0, 0, 1, 0, 2000, 6, 0, {-28800, 0}},
    386        {0, 0, 0, 48},
    387        {0, 0, 0, 8, 3, 0, 2000, 1, 2, {0, 0}}, /*Mon Jan  3 08:00:00 2000 UTC*/
    388        {0, 0, 0, 0, 3, 0, 2000, 1, 2, {-28800, 0}} /*Mon Jan  3 00:00:00 2000
    389                                                                -0800*/
    390    },
    391    /* 00-01-10 12:00:00 PST */
    392    {
    393        {0, 0, 0, 12, 10, 0, 2000, 1, 9, {-28800, 0}},
    394        {0, 0, 0, 364 * 5 * 24},
    395        {0, 0, 0, 20, 3, 0, 2005, 1, 2, {0, 0}}, /*Mon Jan  3 20:00:00 2005 UTC
    396                                                  */
    397        {0, 0, 0, 12, 3, 0, 2005, 1, 2, {-28800, 0}} /*Mon Jan  3 12:00:00
    398                                                        2005 -0800*/
    399    },
    400    /* 00-02-28 15:39 GMT */
    401    {
    402        {0, 0, 39, 15, 28, 1, 2000, 1, 58, {0, 0}},
    403        {0, 0, 0, 24},
    404        {0, 0, 39, 15, 29, 1, 2000, 2, 59, {0, 0}}, /*Tue Feb 29 15:39:00 2000
    405                                                       UTC*/
    406        {0, 0, 39, 7, 29, 1, 2000, 2, 59, {-28800, 0}} /*Tue Feb 29 07:39:00
    407                                                        2000 -0800*/
    408    },
    409    /* 01-03-01 12:00 PST */
    410    {
    411        {0, 0, 0, 12, 3, 0, 2001, 3, 2, {-28800, 0}}, /*Wed Jan 3 12:00:00
    412                                                    -0800 2001*/
    413        {0, 30, 30, 45},
    414        {0, 30, 30, 17, 5, 0, 2001, 5, 4, {0, 0}},    /*Fri Jan  5 17:30:30 2001
    415                                                      UTC*/
    416        {0, 30, 30, 9, 5, 0, 2001, 5, 4, {-28800, 0}} /*Fri Jan  5 09:30:30
    417                                                       2001 -0800*/
    418    },
    419    /* 2004-04-26 12:00 GMT */
    420    {
    421        {0, 0, 0, 20, 3, 0, 2001, 3, 2, {0, 0}},
    422        {0, 0, 30, 0},
    423        {0, 0, 30, 20, 3, 0, 2001, 3, 2, {0, 0}},     /*Wed Jan  3 20:30:00 2001
    424                                                         UTC*/
    425        {0, 0, 30, 12, 3, 0, 2001, 3, 2, {-28800, 0}} /*Wed Jan  3 12:30:00
    426                                                        2001 -0800*/
    427    },
    428    /* 99-09-09 00:00 GMT */
    429    {
    430        {0, 0, 0, 0, 9, 8, 1999, 4, 251, {0, 0}},
    431        {0, 0, 0, 12},
    432        {0, 0, 0, 12, 9, 8, 1999, 4, 251, {0, 0}}, /*Thu Sep  9 12:00:00 1999
    433                                                      UTC*/
    434        {0, 0, 0, 5, 9, 8, 1999, 4, 251, {-28800, 3600}} /*Thu Sep  9 05:00:00
    435                                                        1999 -0700*/
    436    }};
    437 
    438 void add_time_increment(PRExplodedTime* et1, time_increment_t* it) {
    439  et1->tm_usec += it->ti_usec;
    440  et1->tm_sec += it->ti_sec;
    441  et1->tm_min += it->ti_min;
    442  et1->tm_hour += it->ti_hour;
    443 }
    444 
    445 /*
    446 ** TestNormalizeTime() -- Test PR_NormalizeTime()
    447 **      For each data item, add the time increment to the base_time and then
    448 **      normalize it for GMT and local time zones. This test assumes that
    449 **      the local time zone is the Pacific Time Zone. The normalized values
    450 **      should match the expected values in the data item.
    451 **
    452 */
    453 PRStatus TestNormalizeTime(void) {
    454  int idx, count;
    455  normalize_test_data_t* itemp;
    456  time_increment_t* itp;
    457 
    458  count = sizeof(normalize_test_array) / sizeof(normalize_test_array[0]);
    459  for (idx = 0; idx < count; idx++) {
    460    itemp = &normalize_test_array[idx];
    461    if (debug_mode) {
    462      printf("%2d. %15s", idx + 1, "Base time: ");
    463      PrintExplodedTime(&itemp->base_time);
    464      printf("\n");
    465    }
    466    itp = &itemp->increment;
    467    if (debug_mode) {
    468      printf("%20s %2d hrs %2d min %3d sec\n", "Add", itp->ti_hour, itp->ti_min,
    469             itp->ti_sec);
    470    }
    471    add_time_increment(&itemp->base_time, &itemp->increment);
    472    PR_NormalizeTime(&itemp->base_time, PR_LocalTimeParameters);
    473    if (debug_mode) {
    474      printf("%19s", "PST time: ");
    475      PrintExplodedTime(&itemp->base_time);
    476      printf("\n");
    477    }
    478    if (!ExplodedTimeIsEqual(&itemp->base_time, &itemp->expected_uspt_time)) {
    479      printf("PR_NormalizeTime failed\n");
    480      if (debug_mode) {
    481        PrintExplodedTime(&itemp->expected_uspt_time);
    482      }
    483      return PR_FAILURE;
    484    }
    485    PR_NormalizeTime(&itemp->base_time, PR_GMTParameters);
    486    if (debug_mode) {
    487      printf("%19s", "GMT time: ");
    488      PrintExplodedTime(&itemp->base_time);
    489      printf("\n");
    490    }
    491 
    492    if (!ExplodedTimeIsEqual(&itemp->base_time, &itemp->expected_gmt_time)) {
    493      printf("PR_NormalizeTime failed\n");
    494      return PR_FAILURE;
    495    }
    496  }
    497  return PR_SUCCESS;
    498 }
    499 
    500 /*
    501 ** ParseTest. Structure defining a string time and a matching exploded time
    502 **
    503 */
    504 typedef struct ParseTest {
    505  char* sDate;       /* string to be converted using PR_ParseTimeString() */
    506  PRExplodedTime et; /* expected result of the conversion */
    507 } ParseTest;
    508 
    509 static ParseTest parseArray[] = {
    510    /*                                  |<----- expected result
    511       ------------------------------------------->| */
    512    /* "string to test"                   usec     sec min hour   day  mo  year
    513       wday julian {gmtoff, dstoff }*/
    514    {"Thursday 1 Jan 1970 00:00:00",
    515     {000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0}}},
    516    {"1 Jan 1970 00:00:00",
    517     {000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0}}},
    518    {"1-Jan-1970 00:00:00",
    519     {000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0}}},
    520    {"01-Jan-1970 00:00:00",
    521     {000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0}}},
    522    {"January 1, 1970", {000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0}}},
    523    {"January 1, 1970 00:00",
    524     {000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0}}},
    525    {"January 01, 1970 00:00",
    526     {000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0}}},
    527    {"January 01 1970 00:00",
    528     {000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0}}},
    529    {"January 01 1970 00:00:00",
    530     {000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0}}},
    531    {"01-01-1970", {000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0}}},
    532    {"01/01/1970", {000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0}}},
    533    {"01/01/70", {000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0}}},
    534    {"01/01/70 00:00:00", {000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0}}},
    535    {"70/01/01 00:00:00", {000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0}}},
    536    {"70/1/1 00:00:", {000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0}}},
    537    {"00:00 Thursday, January 1, 1970",
    538     {000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0}}},
    539    {"1-Jan-70 00:00:00", {000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0}}},
    540    {"70-01-01 00:00:00", {000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0}}},
    541    {"70/01/01 00:00:00", {000000, 00, 00, 00, 1, 0, 1970, 4, 0, {-28800, 0}}},
    542 
    543    /* 31-Dec-1969 */
    544    {"Wed 31 Dec 1969 00:00:00",
    545     {000000, 00, 00, 00, 31, 11, 1969, 3, 364, {-28800, 0}}},
    546    {"31 Dec 1969 00:00:00",
    547     {000000, 00, 00, 00, 31, 11, 1969, 3, 364, {-28800, 0}}},
    548    {"12/31/69    00:00:00",
    549     {000000, 00, 00, 00, 31, 11, 2069, 2, 364, {-28800, 0}}},
    550    {"12/31/1969  00:00:00",
    551     {000000, 00, 00, 00, 31, 11, 1969, 3, 364, {-28800, 0}}},
    552    {"12-31-69    00:00:00",
    553     {000000, 00, 00, 00, 31, 11, 2069, 2, 364, {-28800, 0}}},
    554    {"12-31-1969  00:00:00",
    555     {000000, 00, 00, 00, 31, 11, 1969, 3, 364, {-28800, 0}}},
    556    {"69-12-31    00:00:00",
    557     {000000, 00, 00, 00, 31, 11, 2069, 2, 364, {-28800, 0}}},
    558    {"69/12/31    00:00:00",
    559     {000000, 00, 00, 00, 31, 11, 2069, 2, 364, {-28800, 0}}},
    560 
    561    /* "Sun". 31-Dec-1998 (?) */
    562    {"Thu 31 Dec 1998 00:00:00",
    563     {00000, 00, 00, 00, 31, 11, 1998, 4, 364, {-28800, 0}}},
    564    {"12/31/98    00:00:00",
    565     {00000, 00, 00, 00, 31, 11, 1998, 4, 364, {-28800, 0}}},
    566    {"12/31/1998  00:00:00",
    567     {00000, 00, 00, 00, 31, 11, 1998, 4, 364, {-28800, 0}}},
    568    {"12-31-98    00:00:00",
    569     {00000, 00, 00, 00, 31, 11, 1998, 4, 364, {-28800, 0}}},
    570    {"12-31-1998  00:00:00",
    571     {00000, 00, 00, 00, 31, 11, 1998, 4, 364, {-28800, 0}}},
    572    {"98-12-31    00:00:00",
    573     {00000, 00, 00, 00, 31, 11, 1998, 4, 364, {-28800, 0}}},
    574    {"98/12/31    00:00:00",
    575     {00000, 00, 00, 00, 31, 11, 1998, 4, 364, {-28800, 0}}},
    576 
    577    /* 09-Sep-1999. Interesting because of its use as an eof marker? */
    578    {"09 Sep 1999 00:00:00",
    579     {000000, 00, 00, 00, 9, 8, 1999, 4, 251, {-28800, 3600}}},
    580    {"9/9/99      00:00:00",
    581     {000000, 00, 00, 00, 9, 8, 1999, 4, 251, {-28800, 3600}}},
    582    {"9/9/1999    00:00:00",
    583     {000000, 00, 00, 00, 9, 8, 1999, 4, 251, {-28800, 3600}}},
    584    {"9-9-99      00:00:00",
    585     {000000, 00, 00, 00, 9, 8, 1999, 4, 251, {-28800, 3600}}},
    586    {"9-9-1999    00:00:00",
    587     {000000, 00, 00, 00, 9, 8, 1999, 4, 251, {-28800, 3600}}},
    588    {"09-09-99    00:00:00",
    589     {000000, 00, 00, 00, 9, 8, 1999, 4, 251, {-28800, 3600}}},
    590    {"09-09-1999  00:00:00",
    591     {000000, 00, 00, 00, 9, 8, 1999, 4, 251, {-28800, 3600}}},
    592    {"99-09-09    00:00:00",
    593     {000000, 00, 00, 00, 9, 8, 1999, 4, 251, {-28800, 3600}}},
    594 
    595    /* "Sun". 10-Sep-1999. Because Sun said so. */
    596    {"10 Sep 1999 00:00:00",
    597     {000000, 00, 00, 00, 10, 8, 1999, 5, 252, {-28800, 3600}}},
    598    {"9/10/99     00:00:00",
    599     {000000, 00, 00, 00, 10, 8, 1999, 5, 252, {-28800, 3600}}},
    600    {"9/10/1999   00:00:00",
    601     {000000, 00, 00, 00, 10, 8, 1999, 5, 252, {-28800, 3600}}},
    602    {"9-10-99     00:00:00",
    603     {000000, 00, 00, 00, 10, 8, 1999, 5, 252, {-28800, 3600}}},
    604    {"9-10-1999   00:00:00",
    605     {000000, 00, 00, 00, 10, 8, 1999, 5, 252, {-28800, 3600}}},
    606    {"09-10-99    00:00:00",
    607     {000000, 00, 00, 00, 10, 8, 1999, 5, 252, {-28800, 3600}}},
    608    {"09-10-1999  00:00:00",
    609     {000000, 00, 00, 00, 10, 8, 1999, 5, 252, {-28800, 3600}}},
    610    {"99-09-10    00:00:00",
    611     {000000, 00, 00, 00, 10, 8, 1999, 5, 252, {-28800, 3600}}},
    612 
    613    /* 31-Dec-1999 */
    614    {"31 Dec 1999 00:00:00",
    615     {000000, 00, 00, 00, 31, 11, 1999, 5, 364, {-28800, 0}}},
    616    {"12/31/99    00:00:00",
    617     {000000, 00, 00, 00, 31, 11, 1999, 5, 364, {-28800, 0}}},
    618    {"12/31/1999  00:00:00",
    619     {000000, 00, 00, 00, 31, 11, 1999, 5, 364, {-28800, 0}}},
    620    {"12-31-99    00:00:00",
    621     {000000, 00, 00, 00, 31, 11, 1999, 5, 364, {-28800, 0}}},
    622    {"12-31-1999  00:00:00",
    623     {000000, 00, 00, 00, 31, 11, 1999, 5, 364, {-28800, 0}}},
    624    {"99-12-31    00:00:00",
    625     {000000, 00, 00, 00, 31, 11, 1999, 5, 364, {-28800, 0}}},
    626    {"99/12/31    00:00:00",
    627     {000000, 00, 00, 00, 31, 11, 1999, 5, 364, {-28800, 0}}},
    628 
    629    /* 01-Jan-2000 */
    630    {"01 Jan 2000 00:00:00",
    631     {000000, 00, 00, 00, 1, 0, 2000, 6, 0, {-28800, 0}}},
    632    {"1/1/00      00:00:00",
    633     {000000, 00, 00, 00, 1, 0, 2000, 6, 0, {-28800, 0}}},
    634    {"1/1/2000    00:00:00",
    635     {000000, 00, 00, 00, 1, 0, 2000, 6, 0, {-28800, 0}}},
    636    {"1-1-00      00:00:00",
    637     {000000, 00, 00, 00, 1, 0, 2000, 6, 0, {-28800, 0}}},
    638    {"1-1-2000    00:00:00",
    639     {000000, 00, 00, 00, 1, 0, 2000, 6, 0, {-28800, 0}}},
    640    {"01-01-00    00:00:00",
    641     {000000, 00, 00, 00, 1, 0, 2000, 6, 0, {-28800, 0}}},
    642    {"Saturday 01-01-2000  00:00:00",
    643     {000000, 00, 00, 00, 1, 0, 2000, 6, 0, {-28800, 0}}},
    644 
    645    /* "Sun". 28-Feb-2000 */
    646    {"28 Feb 2000 00:00:00",
    647     {000000, 00, 00, 00, 28, 1, 2000, 1, 58, {-28800, 0}}},
    648    {"2/28/00     00:00:00",
    649     {000000, 00, 00, 00, 28, 1, 2000, 1, 58, {-28800, 0}}},
    650    {"2/28/2000   00:00:00",
    651     {000000, 00, 00, 00, 28, 1, 2000, 1, 58, {-28800, 0}}},
    652    {"2-28-00     00:00:00",
    653     {000000, 00, 00, 00, 28, 1, 2000, 1, 58, {-28800, 0}}},
    654    {"2-28-2000   00:00:00",
    655     {000000, 00, 00, 00, 28, 1, 2000, 1, 58, {-28800, 0}}},
    656    {"02-28-00    00:00:00",
    657     {000000, 00, 00, 00, 28, 1, 2000, 1, 58, {-28800, 0}}},
    658    {"02-28-2000  00:00:00",
    659     {000000, 00, 00, 00, 28, 1, 2000, 1, 58, {-28800, 0}}},
    660 
    661    /* 29-Feb-2000 */
    662    {"29 Feb 2000 00:00:00",
    663     {000000, 00, 00, 00, 29, 1, 2000, 2, 59, {-28800, 0}}},
    664    {"2/29/00     00:00:00",
    665     {000000, 00, 00, 00, 29, 1, 2000, 2, 59, {-28800, 0}}},
    666    {"2/29/2000   00:00:00",
    667     {000000, 00, 00, 00, 29, 1, 2000, 2, 59, {-28800, 0}}},
    668    {"2-29-00     00:00:00",
    669     {000000, 00, 00, 00, 29, 1, 2000, 2, 59, {-28800, 0}}},
    670    {"2-29-2000   00:00:00",
    671     {000000, 00, 00, 00, 29, 1, 2000, 2, 59, {-28800, 0}}},
    672    {"02-29-00    00:00:00",
    673     {000000, 00, 00, 00, 29, 1, 2000, 2, 59, {-28800, 0}}},
    674    {"02-29-2000  00:00:00",
    675     {000000, 00, 00, 00, 29, 1, 2000, 2, 59, {-28800, 0}}},
    676 
    677    /* 01-Mar-2000 */
    678    {"01 Mar 2000 00:00:00",
    679     {000000, 00, 00, 00, 1, 2, 2000, 3, 60, {-28800, 0}}},
    680    {"3/1/00      00:00:00",
    681     {000000, 00, 00, 00, 1, 2, 2000, 3, 60, {-28800, 0}}},
    682    {"3/1/2000    00:00:00",
    683     {000000, 00, 00, 00, 1, 2, 2000, 3, 60, {-28800, 0}}},
    684    {"3-1-00      00:00:00",
    685     {000000, 00, 00, 00, 1, 2, 2000, 3, 60, {-28800, 0}}},
    686    {"03-01-00    00:00:00",
    687     {000000, 00, 00, 00, 1, 2, 2000, 3, 60, {-28800, 0}}},
    688    {"03-01-2000  00:00:00",
    689     {000000, 00, 00, 00, 1, 2, 2000, 3, 60, {-28800, 0}}},
    690 
    691    /* "Sun". 31-Dec-2000 */
    692    {"31 Dec 2000 00:00:00",
    693     {000000, 00, 00, 00, 31, 11, 2000, 0, 365, {-28800, 0}}},
    694    {"12/31/00    00:00:00",
    695     {000000, 00, 00, 00, 31, 11, 2000, 0, 365, {-28800, 0}}},
    696    {"12/31/2000  00:00:00",
    697     {000000, 00, 00, 00, 31, 11, 2000, 0, 365, {-28800, 0}}},
    698    {"12-31-00    00:00:00",
    699     {000000, 00, 00, 00, 31, 11, 2000, 0, 365, {-28800, 0}}},
    700    {"12-31-2000  00:00:00",
    701     {000000, 00, 00, 00, 31, 11, 2000, 0, 365, {-28800, 0}}},
    702    {"00-12-31    00:00:00",
    703     {000000, 00, 00, 00, 31, 11, 2000, 0, 365, {-28800, 0}}},
    704    {"00/12/31    00:00:00",
    705     {000000, 00, 00, 00, 31, 11, 2000, 0, 365, {-28800, 0}}},
    706 
    707    /* "Sun". 01-Jan-2001 */
    708    {"01 Jan 2001 00:00:00",
    709     {000000, 00, 00, 00, 1, 0, 2001, 1, 0, {-28800, 0}}},
    710    {"1/1/01      00:00:00",
    711     {000000, 00, 00, 00, 1, 0, 2001, 1, 0, {-28800, 0}}},
    712    {"1/1/2001    00:00:00",
    713     {000000, 00, 00, 00, 1, 0, 2001, 1, 0, {-28800, 0}}},
    714    {"1-1-01      00:00:00",
    715     {000000, 00, 00, 00, 1, 0, 2001, 1, 0, {-28800, 0}}},
    716    {"1-1-2001    00:00:00",
    717     {000000, 00, 00, 00, 1, 0, 2001, 1, 0, {-28800, 0}}},
    718    {"01-01-01    00:00:00",
    719     {000000, 00, 00, 00, 1, 0, 2001, 1, 0, {-28800, 0}}},
    720    {"Saturday 01-01-2001  00:00:00",
    721     {000000, 00, 00, 00, 1, 0, 2001, 1, 0, {-28800, 0}}},
    722 
    723    /* 01-Mar-2001 */
    724    {"01 Mar 2001 00:00:00",
    725     {000000, 00, 00, 00, 1, 2, 2001, 4, 59, {-28800, 0}}},
    726    {"3/1/01      00:00:00",
    727     {000000, 00, 00, 00, 1, 2, 2001, 4, 59, {-28800, 0}}},
    728    {"3/1/2001    00:00:00",
    729     {000000, 00, 00, 00, 1, 2, 2001, 4, 59, {-28800, 0}}},
    730    {"3-1-01      00:00:00",
    731     {000000, 00, 00, 00, 1, 2, 2001, 4, 59, {-28800, 0}}},
    732    {"3-1-2001    00:00:00",
    733     {000000, 00, 00, 00, 1, 2, 2001, 4, 59, {-28800, 0}}},
    734    {"03-01-01    00:00:00",
    735     {000000, 00, 00, 00, 1, 2, 2001, 4, 59, {-28800, 0}}},
    736    {"03-01-2001  00:00:00",
    737     {000000, 00, 00, 00, 1, 2, 2001, 4, 59, {-28800, 0}}},
    738 
    739    /* 29-Feb-2004 */
    740    {"29 Feb 2004 00:00:00",
    741     {000000, 00, 00, 00, 29, 1, 2004, 0, 59, {-28800, 0}}},
    742    {"2/29/04     00:00:00",
    743     {000000, 00, 00, 00, 29, 1, 2004, 0, 59, {-28800, 0}}},
    744    {"2/29/2004   00:00:00",
    745     {000000, 00, 00, 00, 29, 1, 2004, 0, 59, {-28800, 0}}},
    746    {"2-29-04     00:00:00",
    747     {000000, 00, 00, 00, 29, 1, 2004, 0, 59, {-28800, 0}}},
    748    {"2-29-2004   00:00:00",
    749     {000000, 00, 00, 00, 29, 1, 2004, 0, 59, {-28800, 0}}},
    750 
    751    /* 01-Mar-2004 */
    752    {"01 Mar 2004 00:00:00",
    753     {000000, 00, 00, 00, 1, 2, 2004, 1, 60, {-28800, 0}}},
    754    {"3/1/04      00:00:00",
    755     {000000, 00, 00, 00, 1, 2, 2004, 1, 60, {-28800, 0}}},
    756    {"3/1/2004    00:00:00",
    757     {000000, 00, 00, 00, 1, 2, 2004, 1, 60, {-28800, 0}}},
    758    {"3-1-04      00:00:00",
    759     {000000, 00, 00, 00, 1, 2, 2004, 1, 60, {-28800, 0}}},
    760    {"3-1-2004    00:00:00",
    761     {000000, 00, 00, 00, 1, 2, 2004, 1, 60, {-28800, 0}}},
    762    {"03-01-04    00:00:00",
    763     {000000, 00, 00, 00, 1, 2, 2004, 1, 60, {-28800, 0}}},
    764    {"03-01-2004  00:00:00",
    765     {000000, 00, 00, 00, 1, 2, 2004, 1, 60, {-28800, 0}}},
    766 
    767    /* 01-Mar-2005 */
    768    {"01 Mar 2005 00:00:00",
    769     {000000, 00, 00, 00, 1, 2, 2005, 2, 59, {-28800, 0}}},
    770    {"3/1/05      00:00:00",
    771     {000000, 00, 00, 00, 1, 2, 2005, 2, 59, {-28800, 0}}},
    772    {"3/1/2005    00:00:00",
    773     {000000, 00, 00, 00, 1, 2, 2005, 2, 59, {-28800, 0}}},
    774    {"3-1-05      00:00:00",
    775     {000000, 00, 00, 00, 1, 2, 2005, 2, 59, {-28800, 0}}},
    776    {"3-1-2005    00:00:00",
    777     {000000, 00, 00, 00, 1, 2, 2005, 2, 59, {-28800, 0}}},
    778    {"03-01-05    00:00:00",
    779     {000000, 00, 00, 00, 1, 2, 2005, 2, 59, {-28800, 0}}},
    780    {"03-01-2005  00:00:00",
    781     {000000, 00, 00, 00, 1, 2, 2005, 2, 59, {-28800, 0}}},
    782 
    783    /* last element. string must be null */
    784    {NULL}}; /* end array of ParseTest */
    785 
    786 /*
    787 ** TestParseTime() -- Test PR_ParseTimeString() for y2k compliance
    788 **
    789 ** TestParseTime() loops thru the array parseArray. For each element in
    790 ** the array, he calls PR_ParseTimeString() with sDate as the conversion
    791 ** argument. The result (ct) is then converted to a PRExplodedTime structure
    792 ** and compared with the exploded time value (parseArray[n].et) in the
    793 ** array element; if equal, the element passes the test.
    794 **
    795 ** The array parseArray[] contains entries that are interesting to the
    796 ** y2k problem.
    797 **
    798 **
    799 */
    800 static PRStatus TestParseTime(void) {
    801  ParseTest* ptp = parseArray;
    802  PRTime ct;
    803  PRExplodedTime cet;
    804  char* sp = ptp->sDate;
    805  PRStatus rc;
    806  PRStatus rv = PR_SUCCESS;
    807 
    808  while (sp != NULL) {
    809    rc = PR_ParseTimeString(sp, PR_FALSE, &ct);
    810    if (PR_FAILURE == rc) {
    811      printf("TestParseTime(): PR_ParseTimeString() failed to convert: %s\n",
    812             sp);
    813      rv = PR_FAILURE;
    814      failed_already = 1;
    815    } else {
    816      PR_ExplodeTime(ct, PR_LocalTimeParameters, &cet);
    817 
    818      if (!ExplodedTimeIsEqual(&cet, &ptp->et)) {
    819        printf("TestParseTime(): Exploded time compare failed: %s\n", sp);
    820        if (debug_mode) {
    821          PrintExplodedTime(&cet);
    822          printf("\n");
    823          PrintExplodedTime(&ptp->et);
    824          printf("\n");
    825        }
    826 
    827        rv = PR_FAILURE;
    828        failed_already = 1;
    829      }
    830    }
    831 
    832    /* point to next element in array, keep going */
    833    ptp++;
    834    sp = ptp->sDate;
    835  } /* end while() */
    836 
    837  return (rv);
    838 } /* end TestParseTime() */
    839 
    840 int main(int argc, char** argv) {
    841  /* The command line argument: -d is used to determine if the test is being run
    842  in debug mode. The regress tool requires only one line output:PASS or FAIL.
    843  All of the printfs associated with this test has been handled with a if
    844  (debug_mode) test. Usage: test_name -d
    845  */
    846  PLOptStatus os;
    847  PLOptState* opt;
    848 
    849  opt = PL_CreateOptState(argc, argv, "d");
    850  while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) {
    851    if (PL_OPT_BAD == os) {
    852      continue;
    853    }
    854    switch (opt->option) {
    855      case 'd': /* debug mode */
    856        debug_mode = PR_TRUE;
    857        break;
    858      default:
    859        break;
    860    }
    861  }
    862  PL_DestroyOptState(opt);
    863 
    864  /* main test */
    865 
    866  PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
    867  lm = PR_NewLogModule("test");
    868 
    869  if (PR_FAILURE == TestExplodeImplodeTime()) {
    870    PR_LOG(lm, PR_LOG_ERROR, ("TestExplodeImplodeTime() failed"));
    871  } else {
    872    printf("Test 1: Calendar Time Test passed\n");
    873  }
    874 
    875  if (PR_FAILURE == TestNormalizeTime()) {
    876    PR_LOG(lm, PR_LOG_ERROR, ("TestNormalizeTime() failed"));
    877  } else {
    878    printf("Test 2: Normalize Time Test passed\n");
    879  }
    880 
    881  if (PR_FAILURE == TestParseTime()) {
    882    PR_LOG(lm, PR_LOG_ERROR, ("TestParseTime() failed"));
    883  } else {
    884    printf("Test 3: Parse Time Test passed\n");
    885  }
    886 
    887  if (failed_already) {
    888    return 1;
    889  } else {
    890    return 0;
    891  }
    892 } /* end main() y2k.c */