552 lines
16 KiB
C
Vendored
552 lines
16 KiB
C
Vendored
/*
|
|
* tclDate.h --
|
|
*
|
|
* This header file handles common usage of clock primitives
|
|
* between tclDate.c (yacc), tclClock.c and tclClockFmt.c.
|
|
*
|
|
* Copyright (c) 2014 Serg G. Brester (aka sebres)
|
|
*
|
|
* See the file "license.terms" for information on usage and redistribution
|
|
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
|
*/
|
|
|
|
#ifndef _TCLCLOCK_H
|
|
#define _TCLCLOCK_H
|
|
|
|
/*
|
|
* Constants
|
|
*/
|
|
|
|
#define JULIAN_DAY_POSIX_EPOCH 2440588
|
|
#define GREGORIAN_CHANGE_DATE 2361222
|
|
#define SECONDS_PER_DAY 86400
|
|
#define JULIAN_SEC_POSIX_EPOCH (((Tcl_WideInt) JULIAN_DAY_POSIX_EPOCH) \
|
|
* SECONDS_PER_DAY)
|
|
#define FOUR_CENTURIES 146097 /* days */
|
|
#define JDAY_1_JAN_1_CE_JULIAN 1721424
|
|
#define JDAY_1_JAN_1_CE_GREGORIAN 1721426
|
|
#define ONE_CENTURY_GREGORIAN 36524 /* days */
|
|
#define FOUR_YEARS 1461 /* days */
|
|
#define ONE_YEAR 365 /* days */
|
|
|
|
#define RODDENBERRY 1946 /* Another epoch (Hi, Jeff!) */
|
|
|
|
enum DateInfoFlags {
|
|
CLF_OPTIONAL = 1 << 0, /* token is non mandatory */
|
|
CLF_POSIXSEC = 1 << 1,
|
|
CLF_LOCALSEC = 1 << 2,
|
|
CLF_JULIANDAY = 1 << 3,
|
|
CLF_TIME = 1 << 4,
|
|
CLF_ZONE = 1 << 5,
|
|
CLF_CENTURY = 1 << 6,
|
|
CLF_DAYOFMONTH = 1 << 7,
|
|
CLF_DAYOFYEAR = 1 << 8,
|
|
CLF_MONTH = 1 << 9,
|
|
CLF_YEAR = 1 << 10,
|
|
CLF_DAYOFWEEK = 1 << 11,
|
|
CLF_ISO8601YEAR = 1 << 12,
|
|
CLF_ISO8601WEEK = 1 << 13,
|
|
CLF_ISO8601CENTURY = 1 << 14,
|
|
|
|
CLF_SIGNED = 1 << 15,
|
|
|
|
/* Compounds */
|
|
|
|
CLF_HAVEDATE = (CLF_DAYOFMONTH | CLF_MONTH | CLF_YEAR),
|
|
CLF_DATE = (CLF_JULIANDAY | CLF_DAYOFMONTH | CLF_DAYOFYEAR
|
|
| CLF_MONTH | CLF_YEAR | CLF_ISO8601YEAR
|
|
| CLF_DAYOFWEEK | CLF_ISO8601WEEK),
|
|
|
|
/*
|
|
* Extra flags used outside of scan/format-tokens too (int, not a short).
|
|
*/
|
|
|
|
CLF_RELCONV = 1 << 17,
|
|
CLF_ORDINALMONTH = 1 << 18,
|
|
CLF_TREK = 1 << 19,
|
|
|
|
/* On demand (lazy) assemble flags */
|
|
|
|
CLF_ASSEMBLE_DATE = 1 << 28,/* assemble year, month, etc. using julianDay */
|
|
CLF_ASSEMBLE_JULIANDAY = 1 << 29,
|
|
/* assemble julianDay using year, month, etc. */
|
|
CLF_ASSEMBLE_SECONDS = 1 << 30
|
|
/* assemble localSeconds (and seconds at end) */
|
|
};
|
|
|
|
#define TCL_MIN_SECONDS -0x00F0000000000000LL
|
|
#define TCL_MAX_SECONDS 0x00F0000000000000LL
|
|
#define TCL_INV_SECONDS (TCL_MIN_SECONDS - 1)
|
|
|
|
/*
|
|
* Enumeration of the string literals used in [clock]
|
|
*/
|
|
|
|
typedef enum {
|
|
LIT__NIL,
|
|
LIT__DEFAULT_FORMAT,
|
|
LIT_SYSTEM, LIT_CURRENT, LIT_C,
|
|
LIT_BCE, LIT_CE,
|
|
LIT_DAYOFMONTH, LIT_DAYOFWEEK, LIT_DAYOFYEAR,
|
|
LIT_ERA, LIT_GMT, LIT_GREGORIAN,
|
|
LIT_INTEGER_VALUE_TOO_LARGE,
|
|
LIT_ISO8601WEEK, LIT_ISO8601YEAR,
|
|
LIT_JULIANDAY, LIT_LOCALSECONDS,
|
|
LIT_MONTH,
|
|
LIT_SECONDS, LIT_TZNAME, LIT_TZOFFSET,
|
|
LIT_YEAR,
|
|
LIT_TZDATA,
|
|
LIT_GETSYSTEMTIMEZONE,
|
|
LIT_SETUPTIMEZONE,
|
|
LIT_MCGET,
|
|
LIT_GETSYSTEMLOCALE, LIT_GETCURRENTLOCALE,
|
|
LIT_LOCALIZE_FORMAT,
|
|
LIT__END
|
|
} ClockLiteral;
|
|
|
|
#define CLOCK_LITERAL_ARRAY(litarr) static const char *const litarr[] = { \
|
|
"", \
|
|
"%a %b %d %H:%M:%S %Z %Y", \
|
|
"system", "current", "C", \
|
|
"BCE", "CE", \
|
|
"dayOfMonth", "dayOfWeek", "dayOfYear", \
|
|
"era", ":GMT", "gregorian", \
|
|
"integer value too large to represent", \
|
|
"iso8601Week", "iso8601Year", \
|
|
"julianDay", "localSeconds", \
|
|
"month", \
|
|
"seconds", "tzName", "tzOffset", \
|
|
"year", \
|
|
"::tcl::clock::TZData", \
|
|
"::tcl::clock::GetSystemTimeZone", \
|
|
"::tcl::clock::SetupTimeZone", \
|
|
"::tcl::clock::mcget", \
|
|
"::tcl::clock::GetSystemLocale", "::tcl::clock::mclocale", \
|
|
"::tcl::clock::LocalizeFormat" \
|
|
}
|
|
|
|
/*
|
|
* Enumeration of the msgcat literals used in [clock]
|
|
*/
|
|
|
|
typedef enum {
|
|
MCLIT__NIL, /* placeholder */
|
|
MCLIT_MONTHS_FULL, MCLIT_MONTHS_ABBREV, MCLIT_MONTHS_COMB,
|
|
MCLIT_DAYS_OF_WEEK_FULL, MCLIT_DAYS_OF_WEEK_ABBREV, MCLIT_DAYS_OF_WEEK_COMB,
|
|
MCLIT_AM, MCLIT_PM,
|
|
MCLIT_LOCALE_ERAS,
|
|
MCLIT_BCE, MCLIT_CE,
|
|
MCLIT_BCE2, MCLIT_CE2,
|
|
MCLIT_BCE3, MCLIT_CE3,
|
|
MCLIT_LOCALE_NUMERALS,
|
|
MCLIT__END
|
|
} ClockMsgCtLiteral;
|
|
|
|
#define CLOCK_LOCALE_LITERAL_ARRAY(litarr, pref) static const char *const litarr[] = { \
|
|
pref "", \
|
|
pref "MONTHS_FULL", pref "MONTHS_ABBREV", pref "MONTHS_COMB", \
|
|
pref "DAYS_OF_WEEK_FULL", pref "DAYS_OF_WEEK_ABBREV", pref "DAYS_OF_WEEK_COMB", \
|
|
pref "AM", pref "PM", \
|
|
pref "LOCALE_ERAS", \
|
|
pref "BCE", pref "CE", \
|
|
pref "b.c.e.", pref "c.e.", \
|
|
pref "b.c.", pref "a.d.", \
|
|
pref "LOCALE_NUMERALS", \
|
|
}
|
|
|
|
/*
|
|
* Structure containing the fields used in [clock format] and [clock scan]
|
|
*/
|
|
|
|
enum TclDateFieldsFlags {
|
|
CLF_BCE = (1 << 1), /* set if BCE */
|
|
CLF_BGREG = (1 << 2), /* set if the date is before Gregorian (Julian yet) */
|
|
CLF_CTZ = (1 << 4) /* (special) revalidate TZ epoch next time used */
|
|
};
|
|
|
|
typedef struct {
|
|
/* Cacheable fields: */
|
|
|
|
Tcl_WideInt seconds; /* Time expressed in seconds from the Posix
|
|
* epoch */
|
|
Tcl_WideInt localSeconds; /* Local time expressed in nominal seconds
|
|
* from the Posix epoch */
|
|
int tzOffset; /* Time zone offset in seconds east of
|
|
* Greenwich */
|
|
Tcl_WideInt julianDay; /* Julian Day Number in local time zone */
|
|
int year; /* Year of the era */
|
|
int dayOfYear; /* Day of the year (1 January == 1) */
|
|
int month; /* Month number */
|
|
int dayOfMonth; /* Day of the month */
|
|
int iso8601Year; /* ISO8601 week-based year */
|
|
int iso8601Week; /* ISO8601 week number */
|
|
int dayOfWeek; /* Day of the week */
|
|
int hour; /* Hours of day (in-between time only calculation) */
|
|
int minutes; /* Minutes of hour (in-between time only calculation) */
|
|
Tcl_WideInt secondOfMin; /* Seconds of minute (in-between time only calculation) */
|
|
Tcl_WideInt secondOfDay; /* Seconds of day (in-between time only calculation) */
|
|
|
|
int flags; /* 0 or some of TclDateFieldsFlags */
|
|
|
|
/* Non cacheable fields: */
|
|
|
|
Tcl_Obj *tzName; /* Name (or corresponding DST-abbreviation) of the
|
|
* time zone, if set the refCount is incremented */
|
|
} TclDateFields;
|
|
|
|
#define ClockCacheableDateFieldsSize \
|
|
offsetof(TclDateFields, tzName)
|
|
|
|
/*
|
|
* Meridian: am, pm, or 24-hour style.
|
|
*/
|
|
|
|
typedef enum {
|
|
MERam, MERpm, MER24
|
|
} MERIDIAN;
|
|
|
|
/*
|
|
* Structure contains return parsed fields.
|
|
*/
|
|
|
|
typedef struct DateInfo {
|
|
const char *dateStart;
|
|
const char *dateInput;
|
|
const char *dateEnd;
|
|
|
|
TclDateFields date;
|
|
|
|
int flags; /* Signals parts of date/time get found */
|
|
int errFlags; /* Signals error (part of date/time found twice) */
|
|
|
|
MERIDIAN dateMeridian;
|
|
|
|
int dateTimezone;
|
|
int dateDSTmode;
|
|
|
|
Tcl_WideInt dateRelMonth;
|
|
Tcl_WideInt dateRelDay;
|
|
Tcl_WideInt dateRelSeconds;
|
|
|
|
int dateMonthOrdinalIncr;
|
|
int dateMonthOrdinal;
|
|
|
|
int dateDayOrdinal;
|
|
|
|
Tcl_WideInt *dateRelPointer;
|
|
|
|
int dateSpaceCount;
|
|
int dateDigitCount;
|
|
|
|
int dateCentury;
|
|
|
|
Tcl_Obj *messages; /* Error messages */
|
|
const char* separatrix; /* String separating messages */
|
|
} DateInfo;
|
|
|
|
#define yydate (info->date) /* Date fields used for converting */
|
|
|
|
#define yyDay (info->date.dayOfMonth)
|
|
#define yyMonth (info->date.month)
|
|
#define yyYear (info->date.year)
|
|
|
|
#define yyHour (info->date.hour)
|
|
#define yyMinutes (info->date.minutes)
|
|
#define yySeconds (info->date.secondOfMin)
|
|
#define yySecondOfDay (info->date.secondOfDay)
|
|
|
|
#define yyDSTmode (info->dateDSTmode)
|
|
#define yyDayOrdinal (info->dateDayOrdinal)
|
|
#define yyDayOfWeek (info->date.dayOfWeek)
|
|
#define yyMonthOrdinalIncr (info->dateMonthOrdinalIncr)
|
|
#define yyMonthOrdinal (info->dateMonthOrdinal)
|
|
#define yyTimezone (info->dateTimezone)
|
|
#define yyMeridian (info->dateMeridian)
|
|
#define yyRelMonth (info->dateRelMonth)
|
|
#define yyRelDay (info->dateRelDay)
|
|
#define yyRelSeconds (info->dateRelSeconds)
|
|
#define yyRelPointer (info->dateRelPointer)
|
|
#define yyInput (info->dateInput)
|
|
#define yyDigitCount (info->dateDigitCount)
|
|
#define yySpaceCount (info->dateSpaceCount)
|
|
|
|
static inline void
|
|
ClockInitDateInfo(
|
|
DateInfo *info)
|
|
{
|
|
memset(info, 0, sizeof(DateInfo));
|
|
}
|
|
|
|
/*
|
|
* Structure containing the command arguments supplied to [clock format] and [clock scan]
|
|
*/
|
|
|
|
enum ClockFmtScnCmdArgsFlags {
|
|
CLF_VALIDATE_S1 = (1 << 0),
|
|
CLF_VALIDATE_S2 = (1 << 1),
|
|
CLF_VALIDATE = (CLF_VALIDATE_S1|CLF_VALIDATE_S2),
|
|
CLF_EXTENDED = (1 << 4),
|
|
CLF_STRICT = (1 << 8),
|
|
CLF_LOCALE_USED = (1 << 15)
|
|
};
|
|
|
|
/* Last-period cache for fast UTC to local and backwards conversion */
|
|
typedef struct ClockLastTZOffs {
|
|
/* keys */
|
|
Tcl_Obj *timezoneObj;
|
|
int changeover;
|
|
Tcl_WideInt localSeconds;
|
|
Tcl_WideInt rangesVal[2]; /* Bounds for cached time zone offset */
|
|
/* values */
|
|
int tzOffset;
|
|
Tcl_Obj *tzName; /* Name (abbreviation) of this area in TZ */
|
|
} ClockLastTZOffs;
|
|
|
|
/*
|
|
* Structure containing the client data for [clock]
|
|
*/
|
|
|
|
typedef struct ClockClientData {
|
|
size_t refCount; /* Number of live references. */
|
|
Tcl_Obj **literals; /* Pool of object literals (common, locale independent). */
|
|
Tcl_Obj **mcLiterals; /* Msgcat object literals with mc-keys for search with locale. */
|
|
Tcl_Obj **mcLitIdxs; /* Msgcat object indices prefixed with _IDX_,
|
|
* used for quick dictionary search */
|
|
Tcl_Obj *mcDicts; /* Msgcat collection, contains weak pointers to locale
|
|
* catalogs, and owns it references (onetime referenced) */
|
|
|
|
/* Cache for current clock parameters, imparted via "configure" */
|
|
size_t lastTZEpoch;
|
|
int currentYearCentury;
|
|
int yearOfCenturySwitch;
|
|
int validMinYear;
|
|
int validMaxYear;
|
|
double maxJDN;
|
|
|
|
Tcl_Obj *systemTimeZone;
|
|
Tcl_Obj *systemSetupTZData;
|
|
Tcl_Obj *gmtSetupTimeZoneUnnorm;
|
|
Tcl_Obj *gmtSetupTimeZone;
|
|
Tcl_Obj *gmtSetupTZData;
|
|
Tcl_Obj *gmtTZName;
|
|
Tcl_Obj *lastSetupTimeZoneUnnorm;
|
|
Tcl_Obj *lastSetupTimeZone;
|
|
Tcl_Obj *lastSetupTZData;
|
|
Tcl_Obj *prevSetupTimeZoneUnnorm;
|
|
Tcl_Obj *prevSetupTimeZone;
|
|
Tcl_Obj *prevSetupTZData;
|
|
|
|
Tcl_Obj *defaultLocale;
|
|
Tcl_Obj *defaultLocaleDict;
|
|
Tcl_Obj *currentLocale;
|
|
Tcl_Obj *currentLocaleDict;
|
|
Tcl_Obj *lastUsedLocaleUnnorm;
|
|
Tcl_Obj *lastUsedLocale;
|
|
Tcl_Obj *lastUsedLocaleDict;
|
|
Tcl_Obj *prevUsedLocaleUnnorm;
|
|
Tcl_Obj *prevUsedLocale;
|
|
Tcl_Obj *prevUsedLocaleDict;
|
|
|
|
/* Cache for last base (last-second fast convert if base/tz not changed) */
|
|
struct {
|
|
Tcl_Obj *timezoneObj;
|
|
TclDateFields date;
|
|
} lastBase;
|
|
|
|
/* Last-period cache for fast UTC to Local and backwards conversion */
|
|
ClockLastTZOffs lastTZOffsCache[2];
|
|
|
|
int defFlags; /* Default flags (from configure), ATM
|
|
* only CLF_VALIDATE supported */
|
|
} ClockClientData;
|
|
|
|
typedef struct ClockFmtScnCmdArgs {
|
|
ClockClientData *dataPtr; /* Pointer to literal pool, etc. */
|
|
Tcl_Interp *interp; /* Tcl interpreter */
|
|
Tcl_Obj *formatObj; /* Format */
|
|
Tcl_Obj *localeObj; /* Name of the locale where the time will be expressed. */
|
|
Tcl_Obj *timezoneObj; /* Default time zone in which the time will be expressed */
|
|
Tcl_Obj *baseObj; /* Base (scan and add) or clockValue (format) */
|
|
int flags; /* Flags control scanning */
|
|
Tcl_Obj *mcDictObj; /* Current dictionary of tcl::clock package for given localeObj*/
|
|
} ClockFmtScnCmdArgs;
|
|
|
|
#define ClockDefaultYearCentury 2000
|
|
#define ClockDefaultCenturySwitch 38
|
|
|
|
/*
|
|
* Clock scan and format facilities.
|
|
*/
|
|
|
|
#ifndef TCL_MEM_DEBUG
|
|
# define CLOCK_FMT_SCN_STORAGE_GC_SIZE 32
|
|
#else
|
|
# define CLOCK_FMT_SCN_STORAGE_GC_SIZE 0
|
|
#endif
|
|
|
|
#define CLOCK_MIN_TOK_CHAIN_BLOCK_SIZE 2
|
|
|
|
typedef struct ClockScanToken ClockScanToken;
|
|
|
|
typedef int (ClockScanTokenProc)(ClockFmtScnCmdArgs *opts,
|
|
DateInfo *info, const ClockScanToken *tok);
|
|
|
|
typedef enum {
|
|
CTOKT_INT = 1, CTOKT_WIDE, CTOKT_PARSER, CTOKT_SPACE, CTOKT_WORD, CTOKT_CHAR,
|
|
CFMTT_PROC
|
|
} CLCKTOK_TYPE;
|
|
|
|
typedef struct ClockScanTokenMap {
|
|
unsigned short type;
|
|
unsigned short flags;
|
|
unsigned short clearFlags;
|
|
unsigned short minSize;
|
|
unsigned short maxSize;
|
|
unsigned short offs;
|
|
ClockScanTokenProc *parser;
|
|
const void *data;
|
|
} ClockScanTokenMap;
|
|
|
|
struct ClockScanToken {
|
|
const ClockScanTokenMap *map;
|
|
struct {
|
|
const char *start;
|
|
const char *end;
|
|
} tokWord;
|
|
unsigned short endDistance;
|
|
unsigned short lookAhMin;
|
|
unsigned short lookAhMax;
|
|
unsigned short lookAhTok;
|
|
};
|
|
|
|
#define MIN_FMT_RESULT_BLOCK_ALLOC 80
|
|
#define MIN_FMT_RESULT_BLOCK_DELTA 0
|
|
/* Maximal permitted threshold (buffer size > result size) in percent,
|
|
* to directly return the buffer without reallocate */
|
|
#define MAX_FMT_RESULT_THRESHOLD 2
|
|
|
|
typedef struct DateFormat {
|
|
char *resMem;
|
|
char *resEnd;
|
|
char *output;
|
|
TclDateFields date;
|
|
Tcl_Obj *localeEra;
|
|
} DateFormat;
|
|
|
|
enum ClockFormatTokenMapFlags {
|
|
CLFMT_INCR = (1 << 3),
|
|
CLFMT_DECR = (1 << 4),
|
|
CLFMT_CALC = (1 << 5),
|
|
CLFMT_LOCALE_INDX = (1 << 8)
|
|
};
|
|
|
|
typedef struct ClockFormatToken ClockFormatToken;
|
|
|
|
typedef int (ClockFormatTokenProc)(ClockFmtScnCmdArgs *opts,
|
|
DateFormat *dateFmt, ClockFormatToken *tok, int *val);
|
|
|
|
typedef struct ClockFormatTokenMap {
|
|
unsigned short type;
|
|
const char *tostr;
|
|
unsigned short width;
|
|
unsigned short flags;
|
|
unsigned short divider;
|
|
unsigned short divmod;
|
|
unsigned short offs;
|
|
ClockFormatTokenProc *fmtproc;
|
|
void *data;
|
|
} ClockFormatTokenMap;
|
|
|
|
struct ClockFormatToken {
|
|
const ClockFormatTokenMap *map;
|
|
struct {
|
|
const char *start;
|
|
const char *end;
|
|
} tokWord;
|
|
};
|
|
|
|
typedef struct ClockFmtScnStorage ClockFmtScnStorage;
|
|
|
|
struct ClockFmtScnStorage {
|
|
int objRefCount; /* Reference count shared across threads */
|
|
ClockScanToken *scnTok;
|
|
unsigned scnTokC;
|
|
unsigned scnSpaceCount; /* Count of mandatory spaces used in format */
|
|
ClockFormatToken *fmtTok;
|
|
unsigned fmtTokC;
|
|
#if CLOCK_FMT_SCN_STORAGE_GC_SIZE > 0
|
|
ClockFmtScnStorage *nextPtr;
|
|
ClockFmtScnStorage *prevPtr;
|
|
#endif
|
|
size_t fmtMinAlloc;
|
|
#if 0
|
|
Tcl_HashEntry hashEntry /* ClockFmtScnStorage is a derivate of Tcl_HashEntry,
|
|
* stored by offset +sizeof(self) */
|
|
#endif
|
|
};
|
|
|
|
/*
|
|
* Clock macros.
|
|
*/
|
|
|
|
/*
|
|
* Extracts Julian day and seconds of the day from posix seconds (tm).
|
|
*/
|
|
#define ClockExtractJDAndSODFromSeconds(jd, sod, tm) \
|
|
do { \
|
|
jd = (tm + JULIAN_SEC_POSIX_EPOCH); \
|
|
if (jd >= SECONDS_PER_DAY || jd <= -SECONDS_PER_DAY) { \
|
|
jd /= SECONDS_PER_DAY; \
|
|
sod = (int)(tm % SECONDS_PER_DAY); \
|
|
} else { \
|
|
sod = (int)jd, jd = 0; \
|
|
} \
|
|
if (sod < 0) { \
|
|
sod += SECONDS_PER_DAY; \
|
|
/* JD is affected, if switched into negative (avoid 24 hours difference) */ \
|
|
if (jd <= 0) { \
|
|
jd--; \
|
|
} \
|
|
} \
|
|
} while(0)
|
|
|
|
/*
|
|
* Prototypes of module functions.
|
|
*/
|
|
|
|
MODULE_SCOPE int TclToSeconds(int Hours, int Minutes,
|
|
int Seconds, MERIDIAN Meridian);
|
|
MODULE_SCOPE int TclIsGregorianLeapYear(TclDateFields *);
|
|
MODULE_SCOPE void TclGetJulianDayFromEraYearDay(
|
|
TclDateFields *fields, int changeover);
|
|
MODULE_SCOPE int TclConvertUTCToLocal(ClockClientData *dataPtr, Tcl_Interp *,
|
|
TclDateFields *, Tcl_Obj *timezoneObj, int);
|
|
MODULE_SCOPE Tcl_Obj * TclClockLookupLastTransition(Tcl_Interp *, Tcl_WideInt,
|
|
Tcl_Size, Tcl_Obj *const *, Tcl_WideInt *rangesVal);
|
|
MODULE_SCOPE int TclClockFreeScan(Tcl_Interp *interp, DateInfo *info);
|
|
|
|
/* tclClock.c module declarations */
|
|
|
|
MODULE_SCOPE Tcl_Obj * TclClockSetupTimeZone(ClockClientData *dataPtr,
|
|
Tcl_Interp *interp, Tcl_Obj *timezoneObj);
|
|
MODULE_SCOPE Tcl_Obj * TclClockMCDict(ClockFmtScnCmdArgs *opts);
|
|
MODULE_SCOPE Tcl_Obj * TclClockMCGet(ClockFmtScnCmdArgs *opts, int mcKey);
|
|
MODULE_SCOPE Tcl_Obj * TclClockMCGetIdx(ClockFmtScnCmdArgs *opts, int mcKey);
|
|
MODULE_SCOPE int TclClockMCSetIdx(ClockFmtScnCmdArgs *opts, int mcKey,
|
|
Tcl_Obj *valObj);
|
|
|
|
/* tclClockFmt.c module declarations */
|
|
|
|
MODULE_SCOPE char * TclItoAw(char *buf, int val, char padchar, unsigned short width);
|
|
MODULE_SCOPE int TclAtoWIe(Tcl_WideInt *out, const char *p, const char *e, int sign);
|
|
|
|
MODULE_SCOPE ClockFmtScnStorage *Tcl_GetClockFrmScnFromObj(Tcl_Interp *interp,
|
|
Tcl_Obj *objPtr);
|
|
MODULE_SCOPE int TclClockScan(DateInfo *info, Tcl_Obj *strObj,
|
|
ClockFmtScnCmdArgs *opts);
|
|
MODULE_SCOPE int TclClockFormat(DateFormat *dateFmt,
|
|
ClockFmtScnCmdArgs *opts);
|
|
MODULE_SCOPE void TclClockFrmScnClearCaches(void);
|
|
MODULE_SCOPE void TclClockFrmScnFinalize();
|
|
|
|
#endif /* _TCLCLOCK_H */
|