Fix build by adding all (hopefully) the missing includes.
[WebKit-https.git] / JavaScriptCore / kjs / DateConstructor.cpp
1 /*
2  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
3  *  Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
4  *
5  *  This library is free software; you can redistribute it and/or
6  *  modify it under the terms of the GNU Lesser General Public
7  *  License as published by the Free Software Foundation; either
8  *  version 2 of the License, or (at your option) any later version.
9  *
10  *  This library is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  *  Lesser General Public License for more details.
14  *
15  *  You should have received a copy of the GNU Lesser General Public
16  *  License along with this library; if not, write to the Free Software
17  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
18  *  USA
19  *
20  */
21
22 #include "config.h"
23 #include "DateConstructor.h"
24
25 #include "DateMath.h"
26 #include "DatePrototype.h"
27 #include "JSFunction.h"
28 #include "JSGlobalObject.h"
29 #include "JSString.h"
30 #include "ObjectPrototype.h"
31 #include "DateInstance.h"
32 #include <math.h>
33 #include <time.h>
34 #include <wtf/MathExtras.h>
35
36 #if HAVE(SYS_TIME_H)
37 #include <sys/time.h>
38 #endif
39
40 #if HAVE(SYS_TIMEB_H)
41 #include <sys/timeb.h>
42 #endif
43
44 namespace KJS {
45
46 // TODO: MakeTime (15.9.11.1) etc. ?
47
48 static JSValue* dateParse(ExecState*, JSObject*, JSValue*, const ArgList&);
49 static JSValue* dateNow(ExecState*, JSObject*, JSValue*, const ArgList&);
50 static JSValue* dateUTC(ExecState*, JSObject*, JSValue*, const ArgList&);
51
52 DateConstructor::DateConstructor(ExecState* exec, FunctionPrototype* funcProto, DatePrototype* dateProto)
53   : InternalFunction(funcProto, Identifier(exec, dateProto->classInfo()->className))
54 {
55   putDirect(exec->propertyNames().prototype, dateProto, DontEnum|DontDelete|ReadOnly);
56   putDirectFunction(new (exec) PrototypeFunction(exec, funcProto, 1, exec->propertyNames().parse, dateParse), DontEnum);
57   putDirectFunction(new (exec) PrototypeFunction(exec, funcProto, 7, exec->propertyNames().UTC, dateUTC), DontEnum);
58   putDirectFunction(new (exec) PrototypeFunction(exec, funcProto, 0, exec->propertyNames().now, dateNow), DontEnum);
59   putDirect(exec, exec->propertyNames().length, 7, ReadOnly | DontEnum | DontDelete);
60 }
61
62 // ECMA 15.9.3
63 static JSObject* constructDate(ExecState* exec, JSObject*, const ArgList& args)
64 {
65   int numArgs = args.size();
66
67   double value;
68
69   if (numArgs == 0) { // new Date() ECMA 15.9.3.3
70     value = getCurrentUTCTime();
71   } else if (numArgs == 1) {
72     if (args[0]->isObject(&DateInstance::info))
73       value = static_cast<DateInstance*>(args[0])->internalNumber();
74     else {
75       JSValue* primitive = args[0]->toPrimitive(exec);
76       if (primitive->isString())
77         value = parseDate(primitive->getString());
78       else
79         value = primitive->toNumber(exec);
80     }
81   } else {
82     if (isnan(args[0]->toNumber(exec))
83         || isnan(args[1]->toNumber(exec))
84         || (numArgs >= 3 && isnan(args[2]->toNumber(exec)))
85         || (numArgs >= 4 && isnan(args[3]->toNumber(exec)))
86         || (numArgs >= 5 && isnan(args[4]->toNumber(exec)))
87         || (numArgs >= 6 && isnan(args[5]->toNumber(exec)))
88         || (numArgs >= 7 && isnan(args[6]->toNumber(exec)))) {
89       value = NaN;
90     } else {
91       GregorianDateTime t;
92       int year = args[0]->toInt32(exec);
93       t.year = (year >= 0 && year <= 99) ? year : year - 1900;
94       t.month = args[1]->toInt32(exec);
95       t.monthDay = (numArgs >= 3) ? args[2]->toInt32(exec) : 1;
96       t.hour = args[3]->toInt32(exec);
97       t.minute = args[4]->toInt32(exec);
98       t.second = args[5]->toInt32(exec);
99       t.isDST = -1;
100       double ms = (numArgs >= 7) ? args[6]->toNumber(exec) : 0;
101       value = gregorianDateTimeToMS(t, ms, false);
102     }
103   }
104   
105   DateInstance* ret = new (exec) DateInstance(exec->lexicalGlobalObject()->datePrototype());
106   ret->setInternalValue(jsNumber(exec, timeClip(value)));
107   return ret;
108 }
109
110 ConstructType DateConstructor::getConstructData(ConstructData& constructData)
111 {
112     constructData.native.function = constructDate;
113     return ConstructTypeNative;
114 }
115
116 // ECMA 15.9.2
117 static JSValue* callDate(ExecState* exec, JSObject*, JSValue*, const ArgList&)
118 {
119     time_t localTime = time(0);
120     tm localTM;
121     getLocalTime(&localTime, &localTM);
122     GregorianDateTime ts(localTM);
123     return jsString(exec, formatDate(ts) + " " + formatTime(ts, false));
124 }
125
126 CallType DateConstructor::getCallData(CallData& callData)
127 {
128     callData.native.function = callDate;
129     return CallTypeNative;
130 }
131
132 static JSValue* dateParse(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
133 {
134     return jsNumber(exec, parseDate(args[0]->toString(exec)));
135 }
136
137 static JSValue* dateNow(ExecState* exec, JSObject*, JSValue*, const ArgList&)
138 {
139     return jsNumber(exec, getCurrentUTCTime());
140 }
141
142 static JSValue* dateUTC(ExecState* exec, JSObject*, JSValue*, const ArgList& args)
143 {
144     int n = args.size();
145     if (isnan(args[0]->toNumber(exec))
146             || isnan(args[1]->toNumber(exec))
147             || (n >= 3 && isnan(args[2]->toNumber(exec)))
148             || (n >= 4 && isnan(args[3]->toNumber(exec)))
149             || (n >= 5 && isnan(args[4]->toNumber(exec)))
150             || (n >= 6 && isnan(args[5]->toNumber(exec)))
151             || (n >= 7 && isnan(args[6]->toNumber(exec)))) {
152         return jsNaN(exec);
153     }
154
155     GregorianDateTime t;
156     int year = args[0]->toInt32(exec);
157     t.year = (year >= 0 && year <= 99) ? year : year - 1900;
158     t.month = args[1]->toInt32(exec);
159     t.monthDay = (n >= 3) ? args[2]->toInt32(exec) : 1;
160     t.hour = args[3]->toInt32(exec);
161     t.minute = args[4]->toInt32(exec);
162     t.second = args[5]->toInt32(exec);
163     double ms = (n >= 7) ? args[6]->toNumber(exec) : 0;
164     return jsNumber(exec, gregorianDateTimeToMS(t, ms, true));
165 }
166
167 } // namespace KJS