16f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*
26f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org**********************************************************************
36f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Copyright (C) 1998-2012, International Business Machines Corporation
46f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* and others.  All Rights Reserved.
56f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org**********************************************************************
66f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*
76f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* File date.c
86f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*
96f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Modification History:
106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*
116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   Date        Name        Description
126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*   06/16/99    stephen     Creation.
136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*******************************************************************************
146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/
156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <stdio.h>
176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <string.h>
186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <stdlib.h>
196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/uloc.h"
216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/udat.h"
226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/ucal.h"
236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/ustring.h"
246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/uclean.h"
256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uprint.h"
276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if UCONFIG_NO_FORMATTING
296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint main(int argc, char **argv)
316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  printf("%s: Sorry, UCONFIG_NO_FORMATTING was turned on (see uconfig.h). No formatting can be done. \n", argv[0]);
336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  return 0;
346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#else
366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* Protos */
396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void usage(void);
406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void version(void);
426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void cal(int32_t month, int32_t year,
446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                UBool useLongNames, UErrorCode *status);
456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void get_symbols(const UDateFormat *fmt,
476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        UDateFormatSymbolType type,
486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        UChar *array[],
496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        int32_t arrayLength,
506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        int32_t lowestIndex,
516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        int32_t firstIndex,
526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        UErrorCode *status);
536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void free_symbols(UChar *array[],
556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                         int32_t arrayLength);
566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void get_days(const UDateFormat *fmt,
586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                     UChar *days [], UBool useLongNames,
596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                     int32_t fdow, UErrorCode *status);
606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void free_days(UChar *days[]);
626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void get_months(const UDateFormat *fmt,
646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                       UChar *months [], UBool useLongNames,
656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                       UErrorCode *status);
666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void free_months(UChar *months[]);
686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void indent(int32_t count, FILE *f);
706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void print_days(UChar *days [], FILE *f, UErrorCode *status);
726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void  print_month(UCalendar *c,
746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                         UChar *days [],
756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                         UBool useLongNames, int32_t fdow,
766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                         UErrorCode *status);
776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void  print_year(UCalendar *c,
796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        UChar *days [], UChar *months [],
806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        UBool useLongNames, int32_t fdow,
816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        UErrorCode *status);
826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* The version of cal */
846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define CAL_VERSION "1.0"
856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* Number of days in a week */
876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define DAY_COUNT 7
886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* Number of months in a year (yes, 13) */
906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define MONTH_COUNT 13
916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* Separation between months in year view */
936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define MARGIN_WIDTH 4
946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* Size of stack buffers */
966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define BUF_SIZE 64
976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* Patterm string - "MMM yyyy" */
996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UChar sShortPat [] = { 0x004D, 0x004D, 0x004D, 0x0020,
1006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org0x0079, 0x0079, 0x0079, 0x0079 };
1016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* Pattern string - "MMMM yyyy" */
1026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UChar sLongPat [] = { 0x004D, 0x004D, 0x004D, 0x004D, 0x0020,
1036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org0x0079, 0x0079, 0x0079, 0x0079 };
1046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint
1076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgmain(int argc,
1086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org     char **argv)
1096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
1106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int printUsage = 0;
1116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int printVersion = 0;
1126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UBool useLongNames = 0;
1136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int optInd = 1;
1146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    char *arg;
1156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t month = -1, year = -1;
1166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UErrorCode status = U_ZERO_ERROR;
1176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* parse the options */
1206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(optInd = 1; optInd < argc; ++optInd) {
1216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        arg = argv[optInd];
1226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* version info */
1246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(strcmp(arg, "-v") == 0 || strcmp(arg, "--version") == 0) {
1256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            printVersion = 1;
1266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
1276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* usage info */
1286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        else if(strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0) {
1296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            printUsage = 1;
1306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
1316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* use long day names */
1326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        else if(strcmp(arg, "-l") == 0 || strcmp(arg, "--long") == 0) {
1336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            useLongNames = 1;
1346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
1356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* POSIX.1 says all arguments after -- are not options */
1366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        else if(strcmp(arg, "--") == 0) {
1376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            /* skip the -- */
1386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            ++optInd;
1396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            break;
1406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
1416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* unrecognized option */
1426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        else if(strncmp(arg, "-", strlen("-")) == 0) {
1436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            printf("cal: invalid option -- %s\n", arg+1);
1446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            printUsage = 1;
1456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
1466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* done with options, display cal */
1476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        else {
1486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            break;
1496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
1506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* Get the month and year to display, if specified */
1536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(optInd != argc) {
1546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* Month and year specified */
1566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(argc - optInd == 2) {
1576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            sscanf(argv[optInd], "%d", (int*)&month);
1586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            sscanf(argv[optInd + 1], "%d", (int*)&year);
1596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            /* Make sure the month value is legal */
1616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(month < 0 || month > 12) {
1626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                printf("icucal: Bad value for month -- %d\n", (int)month);
1636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* Display usage */
1656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                printUsage = 1;
1666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
1676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            /* Adjust because months are 0-based */
1696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            --month;
1706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
1716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* Only year specified */
1726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        else {
1736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            sscanf(argv[optInd], "%d", (int*)&year);
1746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
1756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* print usage info */
1786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(printUsage) {
1796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        usage();
1806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return 0;
1816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* print version info */
1846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(printVersion) {
1856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        version();
1866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return 0;
1876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
1886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* print the cal */
1906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    cal(month, year, useLongNames, &status);
1916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* ICU cleanup.  Deallocate any memory ICU may be holding.  */
1936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    u_cleanup();
1946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    return (U_FAILURE(status) ? 1 : 0);
1966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
1976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
1986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* Usage information */
1996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void
2006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgusage()
2016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
2026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    puts("Usage: icucal [OPTIONS] [[MONTH] YEAR]");
2036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    puts("");
2046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    puts("Options:");
2056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    puts("  -h, --help        Print this message and exit.");
2066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    puts("  -v, --version     Print the version number of cal and exit.");
2076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    puts("  -l, --long        Use long names.");
2086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    puts("");
2096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    puts("Arguments (optional):");
2106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    puts("  MONTH             An integer (1-12) indicating the month to display");
2116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    puts("  YEAR              An integer indicating the year to display");
2126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    puts("");
2136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    puts("For an interesting calendar, look at October 1582");
2146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* Version information */
2176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void
2186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgversion()
2196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
2206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    printf("icucal version %s (ICU version %s), created by Stephen F. Booth.\n",
2216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        CAL_VERSION, U_ICU_VERSION);
2226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    puts(U_COPYRIGHT_STRING);
2236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void
2266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgcal(int32_t month,
2276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t year,
2286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UBool useLongNames,
2296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UErrorCode *status)
2306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
2316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UCalendar *c;
2326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UChar *days [DAY_COUNT];
2336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UChar *months [MONTH_COUNT];
2346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t fdow;
2356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(U_FAILURE(*status)) return;
2376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* Create a new calendar */
2396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    c = ucal_open(0, -1, uloc_getDefault(), UCAL_TRADITIONAL, status);
2406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* Determine if we are printing a calendar for one month or for a year */
2426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* Print an entire year */
2446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(month == -1 && year != -1) {
2456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* Set the year */
2476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ucal_set(c, UCAL_YEAR, year);
2486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* Determine the first day of the week */
2506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        fdow = ucal_getAttribute(c, UCAL_FIRST_DAY_OF_WEEK);
2516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* Print the calendar for the year */
2536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        print_year(c, days, months, useLongNames, fdow, status);
2546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* Print only one month */
2576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    else {
2586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* Set the month and the year, if specified */
2606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(month != -1)
2616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            ucal_set(c, UCAL_MONTH, month);
2626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(year != -1)
2636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            ucal_set(c, UCAL_YEAR, year);
2646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* Determine the first day of the week */
2666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        fdow = ucal_getAttribute(c, UCAL_FIRST_DAY_OF_WEEK);
2676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* Print the calendar for the month */
2696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        print_month(c, days, useLongNames, fdow, status);
2706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* Clean up */
2736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    ucal_close(c);
2746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
2756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*
2766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Get a set of DateFormat symbols of a given type.
2776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *
2786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * lowestIndex is the index of the first symbol to fetch.
2796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * (e.g. it will be one to fetch day names, since Sunday is
2806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *  day 1 *not* day 0.)
2816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *
2826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * firstIndex is the index of the symbol to place first in
2836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * the output array. This is used when fetching day names
2846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * in locales where the week doesn't start on Sunday.
2856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */
2866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void get_symbols(const UDateFormat *fmt,
2876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        UDateFormatSymbolType type,
2886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        UChar *array[],
2896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        int32_t arrayLength,
2906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        int32_t lowestIndex,
2916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        int32_t firstIndex,
2926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        UErrorCode *status)
2936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
2946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t count, i;
2956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
2966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if (U_FAILURE(*status)) {
2976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return;
2986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
2996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    count = udat_countSymbols(fmt, type);
3016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(count != arrayLength + lowestIndex) {
3036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return;
3046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(i = 0; i < arrayLength; i++) {
3076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        int32_t idx = (i + firstIndex) % arrayLength;
3086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        int32_t size = 1 + udat_getSymbols(fmt, type, idx + lowestIndex, NULL, 0, status);
3096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        array[idx] = (UChar *) malloc(sizeof(UChar) * size);
3116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        *status = U_ZERO_ERROR;
3136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        udat_getSymbols(fmt, type, idx + lowestIndex, array[idx], size, status);
3146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* Free the symbols allocated by get_symbols(). */
3186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void free_symbols(UChar *array[],
3196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                         int32_t arrayLength)
3206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
3216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t i;
3226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(i = 0; i < arrayLength; i++) {
3246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        free(array[i]);
3256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* Get the day names for the specified locale, in either long or short
3296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgform.  Also, reorder the days so that they are in the proper order
3306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgfor the locale (not all locales begin weeks on Sunday; in France,
3316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgweeks start on Monday) */
3326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void
3336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgget_days(const UDateFormat *fmt,
3346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         UChar *days [],
3356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         UBool useLongNames,
3366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         int32_t fdow,
3376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org         UErrorCode *status)
3386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
3396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UDateFormatSymbolType dayType = (useLongNames ? UDAT_WEEKDAYS : UDAT_SHORT_WEEKDAYS);
3406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(U_FAILURE(*status))
3426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return;
3436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* fdow is 1-based */
3456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    --fdow;
3466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    get_symbols(fmt, dayType, days, DAY_COUNT, 1, fdow, status);
3486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void free_days(UChar *days[])
3516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
3526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    free_symbols(days, DAY_COUNT);
3536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* Get the month names for the specified locale, in either long or
3566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgshort form. */
3576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void
3586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgget_months(const UDateFormat *fmt,
3596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org           UChar *months [],
3606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org           UBool useLongNames,
3616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org           UErrorCode *status)
3626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
3636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UDateFormatSymbolType monthType = (useLongNames ? UDAT_MONTHS : UDAT_SHORT_MONTHS);
3646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(U_FAILURE(*status))
3666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return;
3676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    get_symbols(fmt, monthType, months, MONTH_COUNT - 1, 0, 0, status); /* some locales have 13 months, no idea why */
3696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void free_months(UChar *months[])
3726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
3736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    free_symbols(months, MONTH_COUNT - 1);
3746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* Indent a certain number of spaces */
3776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void
3786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgindent(int32_t count,
3796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org       FILE *f)
3806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
3816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    char c [BUF_SIZE];
3826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(count <= 0)
3846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    {
3856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        return;
3866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(count < BUF_SIZE) {
3896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        memset(c, (int)' ', count);
3906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        fwrite(c, sizeof(char), count, f);
3916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    else {
3936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        int32_t i;
3946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        for(i = 0; i < count; ++i)
3956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            putc(' ', f);
3966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
3976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
3986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
3996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* Print the days */
4006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void
4016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgprint_days(UChar *days [],
4026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org           FILE *f,
4036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org           UErrorCode *status)
4046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
4056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t i;
4066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(U_FAILURE(*status)) return;
4086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* Print the day names */
4106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(i = 0; i < DAY_COUNT; ++i) {
4116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        uprint(days[i], f, status);
4126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        putc(' ', f);
4136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
4156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* Print out a calendar for c's current month */
4176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void
4186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgprint_month(UCalendar *c,
4196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            UChar *days [],
4206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            UBool useLongNames,
4216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            int32_t fdow,
4226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            UErrorCode *status)
4236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
4246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t width, pad, i, day;
4256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t lens [DAY_COUNT];
4266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t firstday, current;
4276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UNumberFormat *nfmt;
4286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UDateFormat *dfmt;
4296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UChar s [BUF_SIZE];
4306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const UChar *pat = (useLongNames ? sLongPat : sShortPat);
4316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t len = (useLongNames ? 9 : 8);
4326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(U_FAILURE(*status)) return;
4346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* ========== Generate the header containing the month and year */
4376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* Open a formatter with a month and year only pattern */
4396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    dfmt = udat_open(UDAT_PATTERN,UDAT_PATTERN,NULL,NULL,0,pat, len,status);
4406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* Format the date */
4426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    udat_format(dfmt, ucal_getMillis(c, status), s, BUF_SIZE, 0, status);
4436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* ========== Get the day names */
4466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    get_days(dfmt, days, useLongNames, fdow, status);
4476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* ========== Print the header */
4496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* Calculate widths for justification */
4516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    width = 6; /* 6 spaces, 1 between each day name */
4526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(i = 0; i < DAY_COUNT; ++i) {
4536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        lens[i] = u_strlen(days[i]);
4546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        width += lens[i];
4556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* Print the header, centered among the day names */
4586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    pad = width - u_strlen(s);
4596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    indent(pad / 2, stdout);
4606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uprint(s, stdout, status);
4616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    putc('\n', stdout);
4626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* ========== Print the day names */
4656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    print_days(days, stdout, status);
4676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    putc('\n', stdout);
4686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* ========== Print the calendar */
4716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* Get the first of the month */
4736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    ucal_set(c, UCAL_DATE, 1);
4746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    firstday = ucal_get(c, UCAL_DAY_OF_WEEK, status);
4756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* The day of the week for the first day of the month is based on
4776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    1-based days of the week, which were also reordered when placed
4786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    in the days array.  Account for this here by offsetting by the
4796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    first day of the week for the locale, which is also 1-based. */
4806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    firstday -= fdow;
4816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* Open the formatter */
4836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    nfmt = unum_open(UNUM_DECIMAL, NULL,0,NULL,NULL, status);
4846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* Indent the correct number of spaces for the first week */
4866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    current = firstday;
4876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(current < 0)
4886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    {
4896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org       current += 7;
4906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
4916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(i = 0; i < current; ++i)
4926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        indent(lens[i] + 1, stdout);
4936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* Finally, print out the days */
4956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    day = ucal_get(c, UCAL_DATE, status);
4966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    do {
4976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
4986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* Format the current day string */
4996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        unum_format(nfmt, day, s, BUF_SIZE, 0, status);
5006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* Calculate the justification and indent */
5026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        pad = lens[current] - u_strlen(s);
5036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        indent(pad, stdout);
5046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* Print the day number out, followed by a space */
5066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        uprint(s, stdout, status);
5076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        putc(' ', stdout);
5086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* Update the current day */
5106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ++current;
5116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        current %= DAY_COUNT;
5126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* If we're at day 0 (first day of the week), insert a newline */
5146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if(current == 0) {
5156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            putc('\n', stdout);
5166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
5176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* Go to the next day */
5196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ucal_add(c, UCAL_DATE, 1, status);
5206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        day = ucal_get(c, UCAL_DATE, status);
5216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    } while(day != 1);
5236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* Output a trailing newline */
5256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    putc('\n', stdout);
5266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* Clean up */
5286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    free_days(days);
5296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    unum_close(nfmt);
5306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    udat_close(dfmt);
5316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
5326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* Print out a calendar for c's current year */
5346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void
5356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgprint_year(UCalendar *c,
5366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org           UChar *days [],
5376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org           UChar *months [],
5386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org           UBool useLongNames,
5396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org           int32_t fdow,
5406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org           UErrorCode *status)
5416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{
5426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t width, pad, i, j;
5436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t lens [DAY_COUNT];
5446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UNumberFormat *nfmt;
5456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UDateFormat *dfmt;
5466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UChar s [BUF_SIZE];
5476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    const UChar pat [] = { 0x0079, 0x0079, 0x0079, 0x0079 };
5486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t len = 4;
5496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    UCalendar  *left_cal, *right_cal;
5506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t left_day, right_day;
5516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t left_firstday, right_firstday, left_current, right_current;
5526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    int32_t left_month, right_month;
5536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    if(U_FAILURE(*status)) return;
5556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* Alias */
5576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    left_cal = c;
5586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* ========== Generate the header containing the year (only) */
5606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* Open a formatter with a month and year only pattern */
5626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    dfmt = udat_open(UDAT_PATTERN,UDAT_PATTERN,NULL,NULL,0,pat, len, status);
5636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* Format the date */
5656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    udat_format(dfmt, ucal_getMillis(left_cal, status), s, BUF_SIZE, 0, status);
5666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* ========== Get the month and day names */
5686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    get_days(dfmt, days, useLongNames, fdow, status);
5696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    get_months(dfmt, months, useLongNames, status);
5706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* ========== Print the header, centered */
5726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* Calculate widths for justification */
5746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    width = 6; /* 6 spaces, 1 between each day name */
5756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(i = 0; i < DAY_COUNT; ++i) {
5766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        lens[i] = u_strlen(days[i]);
5776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        width += lens[i];
5786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    }
5796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* width is the width for 1 calendar; we are displaying in 2 cols
5816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    with MARGIN_WIDTH spaces between months */
5826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* Print the header, centered among the day names */
5846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    pad = 2 * width + MARGIN_WIDTH - u_strlen(s);
5856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    indent(pad / 2, stdout);
5866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    uprint(s, stdout, status);
5876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    putc('\n', stdout);
5886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    putc('\n', stdout);
5896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* Generate a copy of the calendar to use */
5916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    right_cal = ucal_open(0, -1, uloc_getDefault(), UCAL_TRADITIONAL, status);
5926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    ucal_setMillis(right_cal, ucal_getMillis(left_cal, status), status);
5936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* Open the formatter */
5956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    nfmt = unum_open(UNUM_DECIMAL,NULL, 0,NULL,NULL, status);
5966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
5976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    /* ========== Calculate and display the months, two at a time */
5986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org    for(i = 0; i < MONTH_COUNT - 1; i += 2) {
5996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* Print the month names for the two current months */
6016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        pad = width - u_strlen(months[i]);
6026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        indent(pad / 2, stdout);
6036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        uprint(months[i], stdout, status);
6046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        indent(pad / 2 + MARGIN_WIDTH, stdout);
6056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        pad = width - u_strlen(months[i + 1]);
6066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        indent(pad / 2, stdout);
6076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        uprint(months[i + 1], stdout, status);
6086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        putc('\n', stdout);
6096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* Print the day names, twice  */
6116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        print_days(days, stdout, status);
6126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        indent(MARGIN_WIDTH, stdout);
6136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        print_days(days, stdout, status);
6146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        putc('\n', stdout);
6156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* Setup the two calendars */
6176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ucal_set(left_cal, UCAL_MONTH, i);
6186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ucal_set(left_cal, UCAL_DATE, 1);
6196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ucal_set(right_cal, UCAL_MONTH, i + 1);
6206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        ucal_set(right_cal, UCAL_DATE, 1);
6216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        left_firstday = ucal_get(left_cal, UCAL_DAY_OF_WEEK, status);
6236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        right_firstday = ucal_get(right_cal, UCAL_DAY_OF_WEEK, status);
6246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* The day of the week for the first day of the month is based on
6266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        1-based days of the week.  However, the days were reordered
6276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        when placed in the days array.  Account for this here by
6286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        offsetting by the first day of the week for the locale, which
6296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        is also 1-based. */
6306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* We need to mod by DAY_COUNT since fdow can be > firstday.  IE,
6326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        if fdow = 2 = Monday (like in France) and the first day of the
6336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        month is a 1 = Sunday, we want firstday to be 6, not -1 */
6346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        left_firstday += (DAY_COUNT - fdow);
6356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        left_firstday %= DAY_COUNT;
6366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        right_firstday += (DAY_COUNT - fdow);
6386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        right_firstday %= DAY_COUNT;
6396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        left_current = left_firstday;
6416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        right_current = right_firstday;
6426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        left_day = ucal_get(left_cal, UCAL_DATE, status);
6446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        right_day = ucal_get(right_cal, UCAL_DATE, status);
6456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        left_month = ucal_get(left_cal, UCAL_MONTH, status);
6476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        right_month = ucal_get(right_cal, UCAL_MONTH, status);
6486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* Finally, print out the days */
6506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        while(left_month == i || right_month == i + 1) {
6516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* If the left month is finished printing, but the right month
6536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        still has days to be printed, indent the width of the days
6546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            strings and reset the left calendar's current day to 0 */
6556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(left_month != i && right_month == i + 1) {
6566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                indent(width + 1, stdout);
6576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                left_current = 0;
6586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
6596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            while(left_month == i) {
6616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            /* If the day is the first, indent the correct number of
6636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                spaces for the first week */
6646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                if(left_day == 1) {
6656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    for(j = 0; j < left_current; ++j)
6666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        indent(lens[j] + 1, stdout);
6676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
6686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* Format the current day string */
6706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                unum_format(nfmt, left_day, s, BUF_SIZE, 0, status);
6716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* Calculate the justification and indent */
6736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                pad = lens[left_current] - u_strlen(s);
6746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                indent(pad, stdout);
6756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* Print the day number out, followed by a space */
6776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                uprint(s, stdout, status);
6786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                putc(' ', stdout);
6796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* Update the current day */
6816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                ++left_current;
6826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                left_current %= DAY_COUNT;
6836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* Go to the next day */
6856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                ucal_add(left_cal, UCAL_DATE, 1, status);
6866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                left_day = ucal_get(left_cal, UCAL_DATE, status);
6876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* Determine the month */
6896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                left_month = ucal_get(left_cal, UCAL_MONTH, status);
6906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* If we're at day 0 (first day of the week), break and go to
6926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                the next month */
6936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                if(left_current == 0) {
6946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    break;
6956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
6966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            };
6976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
6986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            /* If the current day isn't 0, indent to make up for missing
6996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            days at the end of the month */
7006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            if(left_current != 0) {
7016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                for(j = left_current; j < DAY_COUNT; ++j)
7026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    indent(lens[j] + 1, stdout);
7036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            }
7046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            /* Indent between the two months */
7066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            indent(MARGIN_WIDTH, stdout);
7076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            while(right_month == i + 1) {
7096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            /* If the day is the first, indent the correct number of
7116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                spaces for the first week */
7126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                if(right_day == 1) {
7136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    for(j = 0; j < right_current; ++j)
7146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                        indent(lens[j] + 1, stdout);
7156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
7166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* Format the current day string */
7186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                unum_format(nfmt, right_day, s, BUF_SIZE, 0, status);
7196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* Calculate the justification and indent */
7216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                pad = lens[right_current] - u_strlen(s);
7226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                indent(pad, stdout);
7236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* Print the day number out, followed by a space */
7256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                uprint(s, stdout, status);
7266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                putc(' ', stdout);
7276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* Update the current day */
7296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                ++right_current;
7306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                right_current %= DAY_COUNT;
7316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* Go to the next day */
7336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                ucal_add(right_cal, UCAL_DATE, 1, status);
7346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                right_day = ucal_get(right_cal, UCAL_DATE, status);
7356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* Determine the month */
7376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                right_month = ucal_get(right_cal, UCAL_MONTH, status);
7386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                /* If we're at day 0 (first day of the week), break out */
7406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                if(right_current == 0) {
7416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                    break;
7426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org                }
7436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            };
7456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            /* Output a newline */
7476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org            putc('\n', stdout);
7486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        }
7496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        /* Output a trailing newline */
7516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org        putc('\n', stdout);
7526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  }
7536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  /* Clean up */
7556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  free_months(months);
7566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  free_days(days);
7576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  udat_close(dfmt);
7586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  unum_close(nfmt);
7596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org  ucal_close(right_cal);
7606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}
7616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org
7626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif
763