Diff
Not logged in

Differences From Artifact [9d380b10d3]:

To Artifact [241148bfc3]:


67
68
69
70
71
72
73
74

75
76
77
78

79
80
81
82
83
84


85
86
87
88
89
90
91
92
93
94
95
96









97
98
99
100
101
102
103

104
105
106
107
108
109

110
111
112
113
114
115
116
117
118
119

120
121
122
123
124
125
126
67
68
69
70
71
72
73

74
75
76
77

78
79
80
81
82


83
84
85
86
87









88
89
90
91
92
93
94
95
96
97
98
99
100
101
102

103
104
105
106
107
108

109
110
111
112
113
114
115
116
117
118

119
120
121
122
123
124
125
126







-
+



-
+




-
-
+
+



-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+






-
+





-
+









-
+







			    TclDateFields *, Tcl_Size, Tcl_Obj *const[],
			    Tcl_WideInt *rangesVal);
static int		ConvertUTCToLocalUsingC(Tcl_Interp *,
			    TclDateFields *, int);
static int		ConvertLocalToUTC(ClockClientData *, Tcl_Interp *,
			    TclDateFields *, Tcl_Obj *timezoneObj, int);
static int		ConvertLocalToUTCUsingTable(Tcl_Interp *,
			    TclDateFields *, int, Tcl_Obj *const[],
			    TclDateFields *, Tcl_Size, Tcl_Obj *const[],
			    Tcl_WideInt *rangesVal);
static int		ConvertLocalToUTCUsingC(Tcl_Interp *,
			    TclDateFields *, int);
static Tcl_ObjCmdProc	ClockConfigureObjCmd;
static Tcl_ObjCmdProc2	ClockConfigureObjCmd;
static void		GetYearWeekDay(TclDateFields *, int);
static void		GetGregorianEraYearDay(TclDateFields *, int);
static void		GetMonthDay(TclDateFields *);
static Tcl_WideInt	WeekdayOnOrBefore(int, Tcl_WideInt);
static Tcl_ObjCmdProc	ClockClicksObjCmd;
static Tcl_ObjCmdProc	ClockConvertlocaltoutcObjCmd;
static Tcl_ObjCmdProc2	ClockClicksObjCmd;
static Tcl_ObjCmdProc2	ClockConvertlocaltoutcObjCmd;
static int		ClockGetDateFields(ClockClientData *,
			    Tcl_Interp *interp, TclDateFields *fields,
			    Tcl_Obj *timezoneObj, int changeover);
static Tcl_ObjCmdProc	ClockGetdatefieldsObjCmd;
static Tcl_ObjCmdProc	ClockGetjuliandayfromerayearmonthdayObjCmd;
static Tcl_ObjCmdProc	ClockGetjuliandayfromerayearweekdayObjCmd;
static Tcl_ObjCmdProc	ClockGetenvObjCmd;
static Tcl_ObjCmdProc	ClockMicrosecondsObjCmd;
static Tcl_ObjCmdProc	ClockMillisecondsObjCmd;
static Tcl_ObjCmdProc	ClockSecondsObjCmd;
static Tcl_ObjCmdProc	ClockFormatObjCmd;
static Tcl_ObjCmdProc	ClockScanObjCmd;
static Tcl_ObjCmdProc2	ClockGetdatefieldsObjCmd;
static Tcl_ObjCmdProc2	ClockGetjuliandayfromerayearmonthdayObjCmd;
static Tcl_ObjCmdProc2	ClockGetjuliandayfromerayearweekdayObjCmd;
static Tcl_ObjCmdProc2	ClockGetenvObjCmd;
static Tcl_ObjCmdProc2	ClockMicrosecondsObjCmd;
static Tcl_ObjCmdProc2	ClockMillisecondsObjCmd;
static Tcl_ObjCmdProc2	ClockSecondsObjCmd;
static Tcl_ObjCmdProc2	ClockFormatObjCmd;
static Tcl_ObjCmdProc2	ClockScanObjCmd;
static int		ClockScanCommit(DateInfo *info,
			    ClockFmtScnCmdArgs *opts);
static int		ClockFreeScan(DateInfo *info,
			    Tcl_Obj *strObj, ClockFmtScnCmdArgs *opts);
static int		ClockCalcRelTime(DateInfo *info,
			    ClockFmtScnCmdArgs *opts);
static Tcl_ObjCmdProc	ClockAddObjCmd;
static Tcl_ObjCmdProc2	ClockAddObjCmd;
static int		ClockValidDate(DateInfo *,
			    ClockFmtScnCmdArgs *, int stage);
static struct tm *	ThreadSafeLocalTime(const time_t *);
static size_t		TzsetIfNecessary(void);
static void		ClockDeleteCmdProc(void *);
static Tcl_ObjCmdProc	ClockSafeCatchCmd;
static Tcl_ObjCmdProc2	ClockSafeCatchCmd;
static void		ClockFinalize(void *);
/*
 * Structure containing description of "native" clock commands to create.
 */

struct ClockCommand {
    const char *name;		/* The tail of the command name. The full name
				 * is "::tcl::clock::<name>". When NULL marks
				 * the end of the table. */
    Tcl_ObjCmdProc *objCmdProc;	/* Function that implements the command. This
    Tcl_ObjCmdProc2 *objCmdProc;	/* Function that implements the command. This
				 * will always have the ClockClientData sent
				 * to it, but may well ignore this data. */
    CompileProc *compileProc;	/* The compiler for the command. */
    void *clientData;		/* Any clientData to give the command (if NULL
				 * a reference to ClockClientData will be sent) */
};

253
254
255
256
257
258
259
260

261
262
263
264
265
266

267
268
269
270
271
272
273
253
254
255
256
257
258
259

260
261
262
263
264
265

266
267
268
269
270
271
272
273







-
+





-
+







	void *clientData;

	strcpy(cmdName + TCL_CLOCK_PREFIX_LEN, clockCmdPtr->name);
	if (!(clientData = clockCmdPtr->clientData)) {
	    clientData = data;
	    data->refCount++;
	}
	cmdPtr = (Command *)Tcl_CreateObjCommand(interp, cmdName,
	cmdPtr = (Command *)Tcl_CreateObjCommand2(interp, cmdName,
		clockCmdPtr->objCmdProc, clientData,
		clockCmdPtr->clientData ? NULL : ClockDeleteCmdProc);
	cmdPtr->compileProc = clockCmdPtr->compileProc ?
		clockCmdPtr->compileProc : TclCompileBasicMin0ArgCmd;
    }
    cmdPtr = (Command *) Tcl_CreateObjCommand(interp,
    cmdPtr = (Command *) Tcl_CreateObjCommand2(interp,
	    "::tcl::unsupported::clock::configure",
	    ClockConfigureObjCmd, data, ClockDeleteCmdProc);
    data->refCount++;
    cmdPtr->compileProc = TclCompileBasicMin0ArgCmd;
}

/*
948
949
950
951
952
953
954
955

956
957
958
959
960
961
962
948
949
950
951
952
953
954

955
956
957
958
959
960
961
962







-
+







 *----------------------------------------------------------------------
 */

static int
ClockConfigureObjCmd(
    void *clientData,		/* Client data containing literal pool */
    Tcl_Interp *interp,		/* Tcl interpreter */
    int objc,			/* Parameter count */
    Tcl_Size objc,			/* Parameter count */
    Tcl_Obj *const objv[])	/* Parameter vector */
{
    ClockClientData *dataPtr = (ClockClientData *)clientData;
    static const char *const options[] = {
	"-default-locale",	"-clear",	  "-current-locale",
	"-year-century",  "-century-switch",
	"-min-year", "-max-year", "-max-jdn", "-validate",
1404
1405
1406
1407
1408
1409
1410
1411

1412
1413
1414
1415
1416
1417
1418
1404
1405
1406
1407
1408
1409
1410

1411
1412
1413
1414
1415
1416
1417
1418







-
+







 *----------------------------------------------------------------------
 */

static int
ClockConvertlocaltoutcObjCmd(
    void *clientData,		/* Literal table */
    Tcl_Interp *interp,		/* Tcl interpreter */
    int objc,			/* Parameter count */
    Tcl_Size objc,			/* Parameter count */
    Tcl_Obj *const *objv)	/* Parameter vector */
{
    ClockClientData *dataPtr = (ClockClientData *)clientData;
    Tcl_Obj *secondsObj;
    Tcl_Obj *dict;
    int changeover;
    TclDateFields fields;
1494
1495
1496
1497
1498
1499
1500
1501

1502
1503
1504
1505
1506
1507
1508
1494
1495
1496
1497
1498
1499
1500

1501
1502
1503
1504
1505
1506
1507
1508







-
+







 *----------------------------------------------------------------------
 */

int
ClockGetdatefieldsObjCmd(
    void *clientData,		/* Opaque pointer to literal pool, etc. */
    Tcl_Interp *interp,		/* Tcl interpreter */
    int objc,			/* Parameter count */
    Tcl_Size objc,			/* Parameter count */
    Tcl_Obj *const *objv)	/* Parameter vector */
{
    TclDateFields fields;
    Tcl_Obj *dict;
    ClockClientData *dataPtr = (ClockClientData *)clientData;
    Tcl_Obj *const *lit = dataPtr->literals;
    int changeover;
1688
1689
1690
1691
1692
1693
1694
1695

1696
1697
1698
1699
1700
1701
1702
1688
1689
1690
1691
1692
1693
1694

1695
1696
1697
1698
1699
1700
1701
1702







-
+







    return TclGetIntFromObj(interp, value, storePtr);
}

static int
ClockGetjuliandayfromerayearmonthdayObjCmd(
    void *clientData,		/* Opaque pointer to literal pool, etc. */
    Tcl_Interp *interp,		/* Tcl interpreter */
    int objc,			/* Parameter count */
    Tcl_Size objc,			/* Parameter count */
    Tcl_Obj *const *objv)	/* Parameter vector */
{
    TclDateFields fields;
    Tcl_Obj *dict;
    ClockClientData *data = (ClockClientData *)clientData;
    Tcl_Obj *const *lit = data->literals;
    int changeover;
1774
1775
1776
1777
1778
1779
1780
1781

1782
1783
1784
1785
1786
1787
1788
1774
1775
1776
1777
1778
1779
1780

1781
1782
1783
1784
1785
1786
1787
1788







-
+







 *----------------------------------------------------------------------
 */

static int
ClockGetjuliandayfromerayearweekdayObjCmd(
    void *clientData,		/* Opaque pointer to literal pool, etc. */
    Tcl_Interp *interp,		/* Tcl interpreter */
    int objc,			/* Parameter count */
    Tcl_Size objc,			/* Parameter count */
    Tcl_Obj *const *objv)	/* Parameter vector */
{
    TclDateFields fields;
    Tcl_Obj *dict;
    ClockClientData *data = (ClockClientData *)clientData;
    Tcl_Obj *const *lit = data->literals;
    int changeover;
1994
1995
1996
1997
1998
1999
2000
2001

2002
2003
2004
2005
2006
2007
2008
1994
1995
1996
1997
1998
1999
2000

2001
2002
2003
2004
2005
2006
2007
2008







-
+







 *----------------------------------------------------------------------
 */

static int
ConvertLocalToUTCUsingTable(
    Tcl_Interp *interp,		/* Tcl interpreter */
    TclDateFields *fields,	/* Time to convert, with 'seconds' filled in */
    int rowc,			/* Number of points at which time changes */
    Tcl_Size rowc,			/* Number of points at which time changes */
    Tcl_Obj *const rowv[],	/* Points at which time changes */
    Tcl_WideInt *rangesVal)	/* Return bounds for time period */
{
    Tcl_Obj *row;
    Tcl_Size cellc;
    Tcl_Obj **cellv;
    struct {
2537
2538
2539
2540
2541
2542
2543
2544

2545
2546
2547
2548
2549
2550
2551
2537
2538
2539
2540
2541
2542
2543

2544
2545
2546
2547
2548
2549
2550
2551







-
+







	} else {
	    temp.iso8601Year -= 1;
	}
	GetJulianDayFromEraYearWeekDay(&temp, changeover);
    }

    fields->iso8601Year = temp.iso8601Year;
    dayOfFiscalYear = fields->julianDay - temp.julianDay;
    dayOfFiscalYear = (int)(fields->julianDay - temp.julianDay);
    fields->iso8601Week = (dayOfFiscalYear / 7) + 1;
    fields->dayOfWeek = (dayOfFiscalYear + 1) % 7;
    if (fields->dayOfWeek < 1) { /* Mon .. Sun == 1 .. 7 */
	fields->dayOfWeek += 7;
    }
}

2570
2571
2572
2573
2574
2575
2576
2577
2578


2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594

2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607

2608
2609
2610
2611
2612
2613
2614
2570
2571
2572
2573
2574
2575
2576


2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593

2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606

2607
2608
2609
2610
2611
2612
2613
2614







-
-
+
+















-
+












-
+







static void
GetGregorianEraYearDay(
    TclDateFields *fields,	/* Date fields containing 'julianDay' */
    int changeover)		/* Gregorian transition date */
{
    Tcl_WideInt jday = fields->julianDay;
    Tcl_WideInt day;
    Tcl_WideInt year;
    Tcl_WideInt n;
    int year;
    int n;

    if (jday >= changeover) {
	/*
	 * Gregorian calendar.
	 */

	fields->gregorian = 1;
	year = 1;

	/*
	 * n = Number of 400-year cycles since 1 January, 1 CE in the
	 * proleptic Gregorian calendar. day = remaining days.
	 */

	day = jday - JDAY_1_JAN_1_CE_GREGORIAN;
	n = day / FOUR_CENTURIES;
	n = (int)(day / FOUR_CENTURIES);
	day %= FOUR_CENTURIES;
	if (day < 0) {
	    day += FOUR_CENTURIES;
	    n--;
	}
	year += 400 * n;

	/*
	 * n = number of centuries since the start of (year);
	 * day = remaining days
	 */

	n = day / ONE_CENTURY_GREGORIAN;
	n = (int)(day / ONE_CENTURY_GREGORIAN);
	day %= ONE_CENTURY_GREGORIAN;
	if (n > 3) {
	    /*
	     * 31 December in the last year of a 400-year cycle.
	     */

	    n = 3;
2625
2626
2627
2628
2629
2630
2631
2632

2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644

2645
2646
2647
2648
2649
2650
2651
2625
2626
2627
2628
2629
2630
2631

2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643

2644
2645
2646
2647
2648
2649
2650
2651







-
+











-
+







	day = jday - JDAY_1_JAN_1_CE_JULIAN;
    }

    /*
     * n = number of 4-year cycles; days = remaining days.
     */

    n = day / FOUR_YEARS;
    n = (int)(day / FOUR_YEARS);
    day %= FOUR_YEARS;
    if (day < 0) {
	day += FOUR_YEARS;
	n--;
    }
    year += 4 * n;

    /*
     * n = number of years; days = remaining days.
     */

    n = day / ONE_YEAR;
    n = (int)(day / ONE_YEAR);
    day %= ONE_YEAR;
    if (n > 3) {
	/*
	 * 31 December of a leap year.
	 */

	n = 3;
2660
2661
2662
2663
2664
2665
2666
2667

2668
2669
2670
2671
2672
2673
2674
2660
2661
2662
2663
2664
2665
2666

2667
2668
2669
2670
2671
2672
2673
2674







-
+







    if (year <= 0) {
	fields->isBce = 1;
	fields->year = 1 - year;
    } else {
	fields->isBce = 0;
	fields->year = year;
    }
    fields->dayOfYear = day + 1;
    fields->dayOfYear = (int)day + 1;
}

/*
 *----------------------------------------------------------------------
 *
 * GetMonthDay --
 *
2785
2786
2787
2788
2789
2790
2791
2792
2793


2794
2795
2796
2797
2798
2799
2800
2785
2786
2787
2788
2789
2790
2791


2792
2793
2794
2795
2796
2797
2798
2799
2800







-
-
+
+







 */

void
GetJulianDayFromEraYearMonthDay(
    TclDateFields *fields,	/* Date to convert */
    int changeover)		/* Gregorian transition date as a Julian Day */
{
    Tcl_WideInt year, ym1, ym1o4, ym1o100, ym1o400;
    int month, mm1, q, r;
    Tcl_WideInt ym1, ym1o4, ym1o100, ym1o400;
    int year, month, mm1, q, r;

    if (fields->isBce) {
	year = 1 - fields->year;
    } else {
	year = fields->year;
    }

3015
3016
3017
3018
3019
3020
3021
3022

3023
3024
3025
3026
3027
3028
3029
3015
3016
3017
3018
3019
3020
3021

3022
3023
3024
3025
3026
3027
3028
3029







-
+







 *----------------------------------------------------------------------
 */

int
ClockGetenvObjCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    int objc,
    Tcl_Size objc,
    Tcl_Obj *const objv[])
{
#ifdef _WIN32
    const WCHAR *varName;
    const WCHAR *varValue;
    Tcl_DString ds;
#else
3119
3120
3121
3122
3123
3124
3125
3126

3127
3128
3129
3130
3131
3132
3133
3119
3120
3121
3122
3123
3124
3125

3126
3127
3128
3129
3130
3131
3132
3133







-
+







 *----------------------------------------------------------------------
 */

int
ClockClicksObjCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Tcl interpreter */
    int objc,			/* Parameter count */
    Tcl_Size objc,			/* Parameter count */
    Tcl_Obj *const *objv)	/* Parameter values */
{
    static const char *const clicksSwitches[] = {
	"-milliseconds", "-microseconds", NULL
    };
    enum ClicksSwitch {
	CLICKS_MILLIS, CLICKS_MICROS, CLICKS_NATIVE
3191
3192
3193
3194
3195
3196
3197
3198

3199
3200
3201
3202
3203
3204
3205
3191
3192
3193
3194
3195
3196
3197

3198
3199
3200
3201
3202
3203
3204
3205







-
+







 *----------------------------------------------------------------------
 */

int
ClockMillisecondsObjCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Tcl interpreter */
    int objc,			/* Parameter count */
    Tcl_Size objc,			/* Parameter count */
    Tcl_Obj *const *objv)	/* Parameter values */
{
    Tcl_Time now;
    Tcl_Obj *timeObj;

    if (objc != 1) {
	Tcl_WrongNumArgs(interp, 0, objv, "clock milliseconds");
3230
3231
3232
3233
3234
3235
3236
3237

3238
3239
3240
3241
3242
3243
3244
3230
3231
3232
3233
3234
3235
3236

3237
3238
3239
3240
3241
3242
3243
3244







-
+







 *----------------------------------------------------------------------
 */

int
ClockMicrosecondsObjCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Tcl interpreter */
    int objc,			/* Parameter count */
    Tcl_Size objc,			/* Parameter count */
    Tcl_Obj *const *objv)	/* Parameter values */
{
    if (objc != 1) {
	Tcl_WrongNumArgs(interp, 0, objv, "clock microseconds");
	return TCL_ERROR;
    }
    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(TclpGetMicroseconds()));
3526
3527
3528
3529
3530
3531
3532
3533

3534
3535
3536
3537
3538
3539
3540
3526
3527
3528
3529
3530
3531
3532

3533
3534
3535
3536
3537
3538
3539
3540







-
+







 *----------------------------------------------------------------------
 */

int
ClockFormatObjCmd(
    void *clientData,		/* Client data containing literal pool */
    Tcl_Interp *interp,		/* Tcl interpreter */
    int objc,			/* Parameter count */
    Tcl_Size objc,			/* Parameter count */
    Tcl_Obj *const objv[])	/* Parameter values */
{
    ClockClientData *dataPtr = (ClockClientData *)clientData;
    static const char *syntax = "clock format clockval|now "
	    "?-format string? "
	    "?-gmt boolean? "
	    "?-locale LOCALE? ?-timezone ZONE?";
3595
3596
3597
3598
3599
3600
3601
3602

3603
3604
3605
3606
3607
3608
3609
3595
3596
3597
3598
3599
3600
3601

3602
3603
3604
3605
3606
3607
3608
3609







-
+







 *----------------------------------------------------------------------
 */

int
ClockScanObjCmd(
    void *clientData,		/* Client data containing literal pool */
    Tcl_Interp *interp,		/* Tcl interpreter */
    int objc,			/* Parameter count */
    Tcl_Size objc,			/* Parameter count */
    Tcl_Obj *const objv[])	/* Parameter values */
{
    ClockClientData *dataPtr = (ClockClientData *)clientData;
    static const char *syntax = "clock scan string "
	    "?-base seconds? "
	    "?-format string? "
	    "?-gmt boolean? "
3630
3631
3632
3633
3634
3635
3636
3637

3638
3639
3640
3641
3642
3643
3644
3630
3631
3632
3633
3634
3635
3636

3637
3638
3639
3640
3641
3642
3643
3644







-
+







    ret = ClockParseFmtScnArgs(&opts, &yy.date, objc, objv,
	    CLC_OP_SCN, "-base, -format, -gmt, -locale, -timezone or -validate");
    if (ret != TCL_OK) {
	goto done;
    }

    /* seconds are in localSeconds (relative base date), so reset time here */
    yyHour = yyMinutes = yySeconds = yySecondOfDay = 0;
    yySecondOfDay = yySeconds = yyMinutes = yyHour = 0;
    yyMeridian = MER24;

    /* If free scan */
    if (opts.formatObj == NULL) {
	/* Use compiled version of FreeScan - */

	/* [SB] TODO: Perhaps someday we'll localize the legacy code. Right now,
4083
4084
4085
4086
4087
4088
4089
4090

4091
4092
4093
4094
4095
4096
4097
4083
4084
4085
4086
4087
4088
4089

4090
4091
4092
4093
4094
4095
4096
4097







-
+







     * Assemble date, time, zone into seconds-from-epoch
     */

    if ((info->flags & (CLF_TIME | CLF_HAVEDATE)) == CLF_HAVEDATE) {
	yySecondOfDay = 0;
	info->flags |= CLF_ASSEMBLE_SECONDS;
    } else if (info->flags & CLF_TIME) {
	yySecondOfDay = ToSeconds(yyHour, yyMinutes, yySeconds, yyMeridian);
	yySecondOfDay = ToSeconds(yyHour, yyMinutes, (int)yySeconds, yyMeridian);
	info->flags |= CLF_ASSEMBLE_SECONDS;
    } else if ((info->flags & (CLF_DAYOFWEEK | CLF_HAVEDATE)) == CLF_DAYOFWEEK
	    || (info->flags & CLF_ORDINALMONTH)
	    || ((info->flags & CLF_RELCONV)
	    && (yyRelMonth != 0 || yyRelDay != 0))) {
	yySecondOfDay = 0;
	info->flags |= CLF_ASSEMBLE_SECONDS;
4161
4162
4163
4164
4165
4166
4167
4168

4169
4170
4171
4172
4173
4174
4175
4161
4162
4163
4164
4165
4166
4167

4168
4169
4170
4171
4172
4173
4174
4175







-
+







	    GetGregorianEraYearDay(&yydate, GREGORIAN_CHANGE_DATE);
	    GetMonthDay(&yydate);
	    GetYearWeekDay(&yydate, GREGORIAN_CHANGE_DATE);
	    info->flags &= ~CLF_ASSEMBLE_DATE;
	}

	/* add the requisite number of months */
	yyMonth += yyRelMonth - 1;
	yyMonth += (int)yyRelMonth - 1;
	yyYear += yyMonth / 12;
	m = yyMonth % 12;
	/* compiler fix for signed-mod - wrap y, m = (0, -1) -> (-1, 11) */
	if (m < 0) {
	    m += 12;
	    yyYear--;
	}
4415
4416
4417
4418
4419
4420
4421
4422

4423
4424
4425
4426
4427
4428
4429
4415
4416
4417
4418
4419
4420
4421

4422
4423
4424
4425
4426
4427
4428
4429







-
+







 *----------------------------------------------------------------------
 */

int
ClockAddObjCmd(
    void *clientData,		/* Client data containing literal pool */
    Tcl_Interp *interp,		/* Tcl interpreter */
    int objc,			/* Parameter count */
    Tcl_Size objc,			/* Parameter count */
    Tcl_Obj *const objv[])	/* Parameter values */
{
    static const char *syntax = "clock add clockval|now ?number units?..."
	    "?-gmt boolean? "
	    "?-locale LOCALE? ?-timezone ZONE?";
    ClockClientData *dataPtr = (ClockClientData *)clientData;
    int ret;
4532
4533
4534
4535
4536
4537
4538
4539

4540
4541
4542
4543
4544
4545
4546
4532
4533
4534
4535
4536
4537
4538

4539
4540
4541
4542
4543
4544
4545
4546







-
+







	    break;
	case CLC_ADD_DAYS:
	    yyRelDay += offs;
	    break;
	case CLC_ADD_WEEKDAYS:
	    /* add number of week days (skipping Saturdays and Sundays)
	     * to a relative days value. */
	    offs = ClockWeekdaysOffs(yy.date.dayOfWeek, offs);
	    offs = ClockWeekdaysOffs(yy.date.dayOfWeek, (int)offs);
	    yyRelDay += offs;
	    break;
	case CLC_ADD_HOURS:
	    yyRelSeconds += offs * 60 * 60;
	    break;
	case CLC_ADD_MINUTES:
	    yyRelSeconds += offs * 60;
4598
4599
4600
4601
4602
4603
4604
4605

4606
4607
4608
4609
4610
4611
4612
4598
4599
4600
4601
4602
4603
4604

4605
4606
4607
4608
4609
4610
4611
4612







-
+







 *----------------------------------------------------------------------
 */

int
ClockSecondsObjCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Tcl interpreter */
    int objc,			/* Parameter count */
    Tcl_Size objc,			/* Parameter count */
    Tcl_Obj *const *objv)	/* Parameter values */
{
    Tcl_Time now;
    Tcl_Obj *timeObj;

    if (objc != 1) {
	Tcl_WrongNumArgs(interp, 0, objv, "clock seconds");
4630
4631
4632
4633
4634
4635
4636
4637

4638
4639
4640
4641
4642
4643
4644
4630
4631
4632
4633
4634
4635
4636

4637
4638
4639
4640
4641
4642
4643
4644







-
+







 *
 *----------------------------------------------------------------------
 */
int
ClockSafeCatchCmd(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,
    int objc,
    Tcl_Size objc,
    Tcl_Obj *const objv[])
{
    typedef struct {
	int status;		/* return code status */
	int flags;		/* Each remaining field saves the */
	int returnLevel;	/* corresponding field of the Interp */
	int returnCode;		/* struct. These fields taken together are */