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