Home | History | Annotate | Download | only in cal
      1 /*
      2 **********************************************************************
      3 * Copyright (C) 1998-2009, International Business Machines Corporation
      4 * and others.  All Rights Reserved.
      5 **********************************************************************
      6 *
      7 * File date.c
      8 *
      9 * Modification History:
     10 *
     11 *   Date        Name        Description
     12 *   06/16/99    stephen     Creation.
     13 *******************************************************************************
     14 */
     15 
     16 #include <stdio.h>
     17 #include <string.h>
     18 #include <stdlib.h>
     19 
     20 #include "unicode/uloc.h"
     21 #include "unicode/udat.h"
     22 #include "unicode/ucal.h"
     23 #include "unicode/ustring.h"
     24 #include "unicode/uclean.h"
     25 
     26 #include "uprint.h"
     27 
     28 #if UCONFIG_NO_FORMATTING
     29 
     30 int main(int argc, char **argv)
     31 {
     32   printf("%s: Sorry, UCONFIG_NO_FORMATTING was turned on (see uconfig.h). No formatting can be done. \n", argv[0]);
     33   return 0;
     34 }
     35 #else
     36 
     37 
     38 /* Protos */
     39 static void usage(void);
     40 
     41 static void version(void);
     42 
     43 static void cal(int32_t month, int32_t year,
     44                 UBool useLongNames, UErrorCode *status);
     45 
     46 static void get_symbols(const UDateFormat *fmt,
     47                         UDateFormatSymbolType type,
     48                         UChar *array[],
     49                         int32_t arrayLength,
     50                         int32_t lowestIndex,
     51                         int32_t firstIndex,
     52                         UErrorCode *status);
     53 
     54 static void free_symbols(UChar *array[],
     55                          int32_t arrayLength);
     56 
     57 static void get_days(const UDateFormat *fmt,
     58                      UChar *days [], UBool useLongNames,
     59                      int32_t fdow, UErrorCode *status);
     60 
     61 static void free_days(UChar *days[]);
     62 
     63 static void get_months(const UDateFormat *fmt,
     64                        UChar *months [], UBool useLongNames,
     65                        UErrorCode *status);
     66 
     67 static void free_months(UChar *months[]);
     68 
     69 static void indent(int32_t count, FILE *f);
     70 
     71 static void print_days(UChar *days [], FILE *f, UErrorCode *status);
     72 
     73 static void  print_month(UCalendar *c,
     74                          UChar *days [],
     75                          UBool useLongNames, int32_t fdow,
     76                          UErrorCode *status);
     77 
     78 static void  print_year(UCalendar *c,
     79                         UChar *days [], UChar *months [],
     80                         UBool useLongNames, int32_t fdow,
     81                         UErrorCode *status);
     82 
     83 /* The version of cal */
     84 #define CAL_VERSION "1.0"
     85 
     86 /* Number of days in a week */
     87 #define DAY_COUNT 7
     88 
     89 /* Number of months in a year (yes, 13) */
     90 #define MONTH_COUNT 13
     91 
     92 /* Separation between months in year view */
     93 #define MARGIN_WIDTH 4
     94 
     95 /* Size of stack buffers */
     96 #define BUF_SIZE 64
     97 
     98 /* Patterm string - "MMM yyyy" */
     99 static const UChar sShortPat [] = { 0x004D, 0x004D, 0x004D, 0x0020,
    100 0x0079, 0x0079, 0x0079, 0x0079 };
    101 /* Pattern string - "MMMM yyyy" */
    102 static const UChar sLongPat [] = { 0x004D, 0x004D, 0x004D, 0x004D, 0x0020,
    103 0x0079, 0x0079, 0x0079, 0x0079 };
    104 
    105 
    106 int
    107 main(int argc,
    108      char **argv)
    109 {
    110     int printUsage = 0;
    111     int printVersion = 0;
    112     UBool useLongNames = 0;
    113     int optind = 1;
    114     char *arg;
    115     int32_t month = -1, year = -1;
    116     UErrorCode status = U_ZERO_ERROR;
    117 
    118 
    119     /* parse the options */
    120     for(optind = 1; optind < argc; ++optind) {
    121         arg = argv[optind];
    122 
    123         /* version info */
    124         if(strcmp(arg, "-v") == 0 || strcmp(arg, "--version") == 0) {
    125             printVersion = 1;
    126         }
    127         /* usage info */
    128         else if(strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0) {
    129             printUsage = 1;
    130         }
    131         /* use long day names */
    132         else if(strcmp(arg, "-l") == 0 || strcmp(arg, "--long") == 0) {
    133             useLongNames = 1;
    134         }
    135         /* POSIX.1 says all arguments after -- are not options */
    136         else if(strcmp(arg, "--") == 0) {
    137             /* skip the -- */
    138             ++optind;
    139             break;
    140         }
    141         /* unrecognized option */
    142         else if(strncmp(arg, "-", strlen("-")) == 0) {
    143             printf("cal: invalid option -- %s\n", arg+1);
    144             printUsage = 1;
    145         }
    146         /* done with options, display cal */
    147         else {
    148             break;
    149         }
    150     }
    151 
    152     /* Get the month and year to display, if specified */
    153     if(optind != argc) {
    154 
    155         /* Month and year specified */
    156         if(argc - optind == 2) {
    157             sscanf(argv[optind], "%d", (int*)&month);
    158             sscanf(argv[optind + 1], "%d", (int*)&year);
    159 
    160             /* Make sure the month value is legal */
    161             if(month < 0 || month > 12) {
    162                 printf("icucal: Bad value for month -- %d\n", (int)month);
    163 
    164                 /* Display usage */
    165                 printUsage = 1;
    166             }
    167 
    168             /* Adjust because months are 0-based */
    169             --month;
    170         }
    171         /* Only year specified */
    172         else {
    173             sscanf(argv[optind], "%d", (int*)&year);
    174         }
    175     }
    176 
    177     /* print usage info */
    178     if(printUsage) {
    179         usage();
    180         return 0;
    181     }
    182 
    183     /* print version info */
    184     if(printVersion) {
    185         version();
    186         return 0;
    187     }
    188 
    189     /* print the cal */
    190     cal(month, year, useLongNames, &status);
    191 
    192     /* ICU cleanup.  Deallocate any memory ICU may be holding.  */
    193     u_cleanup();
    194 
    195     return (U_FAILURE(status) ? 1 : 0);
    196 }
    197 
    198 /* Usage information */
    199 static void
    200 usage()
    201 {
    202     puts("Usage: icucal [OPTIONS] [[MONTH] YEAR]");
    203     puts("");
    204     puts("Options:");
    205     puts("  -h, --help        Print this message and exit.");
    206     puts("  -v, --version     Print the version number of cal and exit.");
    207     puts("  -l, --long        Use long names.");
    208     puts("");
    209     puts("Arguments (optional):");
    210     puts("  MONTH             An integer (1-12) indicating the month to display");
    211     puts("  YEAR              An integer indicating the year to display");
    212     puts("");
    213     puts("For an interesting calendar, look at October 1582");
    214 }
    215 
    216 /* Version information */
    217 static void
    218 version()
    219 {
    220     printf("icucal version %s (ICU version %s), created by Stephen F. Booth.\n",
    221         CAL_VERSION, U_ICU_VERSION);
    222     puts(U_COPYRIGHT_STRING);
    223 }
    224 
    225 static void
    226 cal(int32_t month,
    227     int32_t year,
    228     UBool useLongNames,
    229     UErrorCode *status)
    230 {
    231     UCalendar *c;
    232     UChar *days [DAY_COUNT];
    233     UChar *months [MONTH_COUNT];
    234     int32_t fdow;
    235 
    236     if(U_FAILURE(*status)) return;
    237 
    238     /* Create a new calendar */
    239     c = ucal_open(0, -1, uloc_getDefault(), UCAL_TRADITIONAL, status);
    240 
    241     /* Determine if we are printing a calendar for one month or for a year */
    242 
    243     /* Print an entire year */
    244     if(month == -1 && year != -1) {
    245 
    246         /* Set the year */
    247         ucal_set(c, UCAL_YEAR, year);
    248 
    249         /* Determine the first day of the week */
    250         fdow = ucal_getAttribute(c, UCAL_FIRST_DAY_OF_WEEK);
    251 
    252         /* Print the calendar for the year */
    253         print_year(c, days, months, useLongNames, fdow, status);
    254     }
    255 
    256     /* Print only one month */
    257     else {
    258 
    259         /* Set the month and the year, if specified */
    260         if(month != -1)
    261             ucal_set(c, UCAL_MONTH, month);
    262         if(year != -1)
    263             ucal_set(c, UCAL_YEAR, year);
    264 
    265         /* Determine the first day of the week */
    266         fdow = ucal_getAttribute(c, UCAL_FIRST_DAY_OF_WEEK);
    267 
    268         /* Print the calendar for the month */
    269         print_month(c, days, useLongNames, fdow, status);
    270     }
    271 
    272     /* Clean up */
    273     ucal_close(c);
    274 }
    275 /*
    276  * Get a set of DateFormat symbols of a given type.
    277  *
    278  * lowestIndex is the index of the first symbol to fetch.
    279  * (e.g. it will be one to fetch day names, since Sunday is
    280  *  day 1 *not* day 0.)
    281  *
    282  * firstIndex is the index of the symbol to place first in
    283  * the output array. This is used when fetching day names
    284  * in locales where the week doesn't start on Sunday.
    285  */
    286 static void get_symbols(const UDateFormat *fmt,
    287                         UDateFormatSymbolType type,
    288                         UChar *array[],
    289                         int32_t arrayLength,
    290                         int32_t lowestIndex,
    291                         int32_t firstIndex,
    292                         UErrorCode *status)
    293 {
    294     int32_t count, i;
    295 
    296     if (U_FAILURE(*status)) {
    297         return;
    298     }
    299 
    300     count = udat_countSymbols(fmt, type);
    301 
    302     if(count != arrayLength + lowestIndex) {
    303         return;
    304     }
    305 
    306     for(i = 0; i < arrayLength; i++) {
    307         int32_t idx = (i + firstIndex) % arrayLength;
    308         int32_t size = 1 + udat_getSymbols(fmt, type, idx + lowestIndex, NULL, 0, status);
    309 
    310         array[idx] = (UChar *) malloc(sizeof(UChar) * size);
    311 
    312         *status = U_ZERO_ERROR;
    313         udat_getSymbols(fmt, type, idx + lowestIndex, array[idx], size, status);
    314     }
    315 }
    316 
    317 /* Free the symbols allocated by get_symbols(). */
    318 static void free_symbols(UChar *array[],
    319                          int32_t arrayLength)
    320 {
    321     int32_t i;
    322 
    323     for(i = 0; i < arrayLength; i++) {
    324         free(array[i]);
    325     }
    326 }
    327 
    328 /* Get the day names for the specified locale, in either long or short
    329 form.  Also, reorder the days so that they are in the proper order
    330 for the locale (not all locales begin weeks on Sunday; in France,
    331 weeks start on Monday) */
    332 static void
    333 get_days(const UDateFormat *fmt,
    334          UChar *days [],
    335          UBool useLongNames,
    336          int32_t fdow,
    337          UErrorCode *status)
    338 {
    339     UDateFormatSymbolType dayType = (useLongNames ? UDAT_WEEKDAYS : UDAT_SHORT_WEEKDAYS);
    340 
    341     if(U_FAILURE(*status))
    342         return;
    343 
    344     /* fdow is 1-based */
    345     --fdow;
    346 
    347     get_symbols(fmt, dayType, days, DAY_COUNT, 1, fdow, status);
    348 }
    349 
    350 static void free_days(UChar *days[])
    351 {
    352     free_symbols(days, DAY_COUNT);
    353 }
    354 
    355 /* Get the month names for the specified locale, in either long or
    356 short form. */
    357 static void
    358 get_months(const UDateFormat *fmt,
    359            UChar *months [],
    360            UBool useLongNames,
    361            UErrorCode *status)
    362 {
    363     UDateFormatSymbolType monthType = (useLongNames ? UDAT_MONTHS : UDAT_SHORT_MONTHS);
    364 
    365     if(U_FAILURE(*status))
    366         return;
    367 
    368     get_symbols(fmt, monthType, months, MONTH_COUNT - 1, 0, 0, status); /* some locales have 13 months, no idea why */
    369 }
    370 
    371 static void free_months(UChar *months[])
    372 {
    373     free_symbols(months, MONTH_COUNT - 1);
    374 }
    375 
    376 /* Indent a certain number of spaces */
    377 static void
    378 indent(int32_t count,
    379        FILE *f)
    380 {
    381     char c [BUF_SIZE];
    382 
    383     if(count <= 0)
    384     {
    385         return;
    386     }
    387 
    388     if(count < BUF_SIZE) {
    389         memset(c, (int)' ', count);
    390         fwrite(c, sizeof(char), count, f);
    391     }
    392     else {
    393         int32_t i;
    394         for(i = 0; i < count; ++i)
    395             putc(' ', f);
    396     }
    397 }
    398 
    399 /* Print the days */
    400 static void
    401 print_days(UChar *days [],
    402            FILE *f,
    403            UErrorCode *status)
    404 {
    405     int32_t i;
    406 
    407     if(U_FAILURE(*status)) return;
    408 
    409     /* Print the day names */
    410     for(i = 0; i < DAY_COUNT; ++i) {
    411         uprint(days[i], f, status);
    412         putc(' ', f);
    413     }
    414 }
    415 
    416 /* Print out a calendar for c's current month */
    417 static void
    418 print_month(UCalendar *c,
    419             UChar *days [],
    420             UBool useLongNames,
    421             int32_t fdow,
    422             UErrorCode *status)
    423 {
    424     int32_t width, pad, i, day;
    425     int32_t lens [DAY_COUNT];
    426     int32_t firstday, current;
    427     UNumberFormat *nfmt;
    428     UDateFormat *dfmt;
    429     UChar s [BUF_SIZE];
    430     const UChar *pat = (useLongNames ? sLongPat : sShortPat);
    431     int32_t len = (useLongNames ? 9 : 8);
    432 
    433     if(U_FAILURE(*status)) return;
    434 
    435 
    436     /* ========== Generate the header containing the month and year */
    437 
    438     /* Open a formatter with a month and year only pattern */
    439     dfmt = udat_open(UDAT_IGNORE,UDAT_IGNORE,NULL,NULL,0,pat, len,status);
    440 
    441     /* Format the date */
    442     udat_format(dfmt, ucal_getMillis(c, status), s, BUF_SIZE, 0, status);
    443 
    444 
    445     /* ========== Get the day names */
    446     get_days(dfmt, days, useLongNames, fdow, status);
    447 
    448     /* ========== Print the header */
    449 
    450     /* Calculate widths for justification */
    451     width = 6; /* 6 spaces, 1 between each day name */
    452     for(i = 0; i < DAY_COUNT; ++i) {
    453         lens[i] = u_strlen(days[i]);
    454         width += lens[i];
    455     }
    456 
    457     /* Print the header, centered among the day names */
    458     pad = width - u_strlen(s);
    459     indent(pad / 2, stdout);
    460     uprint(s, stdout, status);
    461     putc('\n', stdout);
    462 
    463 
    464     /* ========== Print the day names */
    465 
    466     print_days(days, stdout, status);
    467     putc('\n', stdout);
    468 
    469 
    470     /* ========== Print the calendar */
    471 
    472     /* Get the first of the month */
    473     ucal_set(c, UCAL_DATE, 1);
    474     firstday = ucal_get(c, UCAL_DAY_OF_WEEK, status);
    475 
    476     /* The day of the week for the first day of the month is based on
    477     1-based days of the week, which were also reordered when placed
    478     in the days array.  Account for this here by offsetting by the
    479     first day of the week for the locale, which is also 1-based. */
    480     firstday -= fdow;
    481 
    482     /* Open the formatter */
    483     nfmt = unum_open(UNUM_DECIMAL, NULL,0,NULL,NULL, status);
    484 
    485     /* Indent the correct number of spaces for the first week */
    486     current = firstday;
    487     if(current < 0)
    488     {
    489        current += 7;
    490     }
    491     for(i = 0; i < current; ++i)
    492         indent(lens[i] + 1, stdout);
    493 
    494     /* Finally, print out the days */
    495     day = ucal_get(c, UCAL_DATE, status);
    496     do {
    497 
    498         /* Format the current day string */
    499         unum_format(nfmt, day, s, BUF_SIZE, 0, status);
    500 
    501         /* Calculate the justification and indent */
    502         pad = lens[current] - u_strlen(s);
    503         indent(pad, stdout);
    504 
    505         /* Print the day number out, followed by a space */
    506         uprint(s, stdout, status);
    507         putc(' ', stdout);
    508 
    509         /* Update the current day */
    510         ++current;
    511         current %= DAY_COUNT;
    512 
    513         /* If we're at day 0 (first day of the week), insert a newline */
    514         if(current == 0) {
    515             putc('\n', stdout);
    516         }
    517 
    518         /* Go to the next day */
    519         ucal_add(c, UCAL_DATE, 1, status);
    520         day = ucal_get(c, UCAL_DATE, status);
    521 
    522     } while(day != 1);
    523 
    524     /* Output a trailing newline */
    525     putc('\n', stdout);
    526 
    527     /* Clean up */
    528     free_days(days);
    529     unum_close(nfmt);
    530     udat_close(dfmt);
    531 }
    532 
    533 /* Print out a calendar for c's current year */
    534 static void
    535 print_year(UCalendar *c,
    536            UChar *days [],
    537            UChar *months [],
    538            UBool useLongNames,
    539            int32_t fdow,
    540            UErrorCode *status)
    541 {
    542     int32_t width, pad, i, j;
    543     int32_t lens [DAY_COUNT];
    544     UNumberFormat *nfmt;
    545     UDateFormat *dfmt;
    546     UChar s [BUF_SIZE];
    547     const UChar pat [] = { 0x0079, 0x0079, 0x0079, 0x0079 };
    548     int32_t len = 4;
    549     UCalendar  *left_cal, *right_cal;
    550     int32_t left_day, right_day;
    551     int32_t left_firstday, right_firstday, left_current, right_current;
    552     int32_t left_month, right_month;
    553 
    554     if(U_FAILURE(*status)) return;
    555 
    556     /* Alias */
    557     left_cal = c;
    558 
    559     /* ========== Generate the header containing the year (only) */
    560 
    561     /* Open a formatter with a month and year only pattern */
    562     dfmt = udat_open(UDAT_IGNORE,UDAT_IGNORE,NULL,NULL,0,pat, len, status);
    563 
    564     /* Format the date */
    565     udat_format(dfmt, ucal_getMillis(left_cal, status), s, BUF_SIZE, 0, status);
    566 
    567     /* ========== Get the month and day names */
    568     get_days(dfmt, days, useLongNames, fdow, status);
    569     get_months(dfmt, months, useLongNames, status);
    570 
    571     /* ========== Print the header, centered */
    572 
    573     /* Calculate widths for justification */
    574     width = 6; /* 6 spaces, 1 between each day name */
    575     for(i = 0; i < DAY_COUNT; ++i) {
    576         lens[i] = u_strlen(days[i]);
    577         width += lens[i];
    578     }
    579 
    580     /* width is the width for 1 calendar; we are displaying in 2 cols
    581     with MARGIN_WIDTH spaces between months */
    582 
    583     /* Print the header, centered among the day names */
    584     pad = 2 * width + MARGIN_WIDTH - u_strlen(s);
    585     indent(pad / 2, stdout);
    586     uprint(s, stdout, status);
    587     putc('\n', stdout);
    588     putc('\n', stdout);
    589 
    590     /* Generate a copy of the calendar to use */
    591     right_cal = ucal_open(0, -1, uloc_getDefault(), UCAL_TRADITIONAL, status);
    592     ucal_setMillis(right_cal, ucal_getMillis(left_cal, status), status);
    593 
    594     /* Open the formatter */
    595     nfmt = unum_open(UNUM_DECIMAL,NULL, 0,NULL,NULL, status);
    596 
    597     /* ========== Calculate and display the months, two at a time */
    598     for(i = 0; i < MONTH_COUNT - 1; i += 2) {
    599 
    600         /* Print the month names for the two current months */
    601         pad = width - u_strlen(months[i]);
    602         indent(pad / 2, stdout);
    603         uprint(months[i], stdout, status);
    604         indent(pad / 2 + MARGIN_WIDTH, stdout);
    605         pad = width - u_strlen(months[i + 1]);
    606         indent(pad / 2, stdout);
    607         uprint(months[i + 1], stdout, status);
    608         putc('\n', stdout);
    609 
    610         /* Print the day names, twice  */
    611         print_days(days, stdout, status);
    612         indent(MARGIN_WIDTH, stdout);
    613         print_days(days, stdout, status);
    614         putc('\n', stdout);
    615 
    616         /* Setup the two calendars */
    617         ucal_set(left_cal, UCAL_MONTH, i);
    618         ucal_set(left_cal, UCAL_DATE, 1);
    619         ucal_set(right_cal, UCAL_MONTH, i + 1);
    620         ucal_set(right_cal, UCAL_DATE, 1);
    621 
    622         left_firstday = ucal_get(left_cal, UCAL_DAY_OF_WEEK, status);
    623         right_firstday = ucal_get(right_cal, UCAL_DAY_OF_WEEK, status);
    624 
    625         /* The day of the week for the first day of the month is based on
    626         1-based days of the week.  However, the days were reordered
    627         when placed in the days array.  Account for this here by
    628         offsetting by the first day of the week for the locale, which
    629         is also 1-based. */
    630 
    631         /* We need to mod by DAY_COUNT since fdow can be > firstday.  IE,
    632         if fdow = 2 = Monday (like in France) and the first day of the
    633         month is a 1 = Sunday, we want firstday to be 6, not -1 */
    634         left_firstday += (DAY_COUNT - fdow);
    635         left_firstday %= DAY_COUNT;
    636 
    637         right_firstday += (DAY_COUNT - fdow);
    638         right_firstday %= DAY_COUNT;
    639 
    640         left_current = left_firstday;
    641         right_current = right_firstday;
    642 
    643         left_day = ucal_get(left_cal, UCAL_DATE, status);
    644         right_day = ucal_get(right_cal, UCAL_DATE, status);
    645 
    646         left_month = ucal_get(left_cal, UCAL_MONTH, status);
    647         right_month = ucal_get(right_cal, UCAL_MONTH, status);
    648 
    649         /* Finally, print out the days */
    650         while(left_month == i || right_month == i + 1) {
    651 
    652         /* If the left month is finished printing, but the right month
    653         still has days to be printed, indent the width of the days
    654             strings and reset the left calendar's current day to 0 */
    655             if(left_month != i && right_month == i + 1) {
    656                 indent(width + 1, stdout);
    657                 left_current = 0;
    658             }
    659 
    660             while(left_month == i) {
    661 
    662             /* If the day is the first, indent the correct number of
    663                 spaces for the first week */
    664                 if(left_day == 1) {
    665                     for(j = 0; j < left_current; ++j)
    666                         indent(lens[j] + 1, stdout);
    667                 }
    668 
    669                 /* Format the current day string */
    670                 unum_format(nfmt, left_day, s, BUF_SIZE, 0, status);
    671 
    672                 /* Calculate the justification and indent */
    673                 pad = lens[left_current] - u_strlen(s);
    674                 indent(pad, stdout);
    675 
    676                 /* Print the day number out, followed by a space */
    677                 uprint(s, stdout, status);
    678                 putc(' ', stdout);
    679 
    680                 /* Update the current day */
    681                 ++left_current;
    682                 left_current %= DAY_COUNT;
    683 
    684                 /* Go to the next day */
    685                 ucal_add(left_cal, UCAL_DATE, 1, status);
    686                 left_day = ucal_get(left_cal, UCAL_DATE, status);
    687 
    688                 /* Determine the month */
    689                 left_month = ucal_get(left_cal, UCAL_MONTH, status);
    690 
    691                 /* If we're at day 0 (first day of the week), break and go to
    692                 the next month */
    693                 if(left_current == 0) {
    694                     break;
    695                 }
    696             };
    697 
    698             /* If the current day isn't 0, indent to make up for missing
    699             days at the end of the month */
    700             if(left_current != 0) {
    701                 for(j = left_current; j < DAY_COUNT; ++j)
    702                     indent(lens[j] + 1, stdout);
    703             }
    704 
    705             /* Indent between the two months */
    706             indent(MARGIN_WIDTH, stdout);
    707 
    708             while(right_month == i + 1) {
    709 
    710             /* If the day is the first, indent the correct number of
    711                 spaces for the first week */
    712                 if(right_day == 1) {
    713                     for(j = 0; j < right_current; ++j)
    714                         indent(lens[j] + 1, stdout);
    715                 }
    716 
    717                 /* Format the current day string */
    718                 unum_format(nfmt, right_day, s, BUF_SIZE, 0, status);
    719 
    720                 /* Calculate the justification and indent */
    721                 pad = lens[right_current] - u_strlen(s);
    722                 indent(pad, stdout);
    723 
    724                 /* Print the day number out, followed by a space */
    725                 uprint(s, stdout, status);
    726                 putc(' ', stdout);
    727 
    728                 /* Update the current day */
    729                 ++right_current;
    730                 right_current %= DAY_COUNT;
    731 
    732                 /* Go to the next day */
    733                 ucal_add(right_cal, UCAL_DATE, 1, status);
    734                 right_day = ucal_get(right_cal, UCAL_DATE, status);
    735 
    736                 /* Determine the month */
    737                 right_month = ucal_get(right_cal, UCAL_MONTH, status);
    738 
    739                 /* If we're at day 0 (first day of the week), break out */
    740                 if(right_current == 0) {
    741                     break;
    742                 }
    743 
    744             };
    745 
    746             /* Output a newline */
    747             putc('\n', stdout);
    748         }
    749 
    750         /* Output a trailing newline */
    751         putc('\n', stdout);
    752   }
    753 
    754   /* Clean up */
    755   free_months(months);
    756   free_days(days);
    757   udat_close(dfmt);
    758   unum_close(nfmt);
    759   ucal_close(right_cal);
    760 }
    761 
    762 #endif
    763