1/*
2 * Manual wrapper for varadic functions for CFCalendar.
3 *
4 * These functions have a non-printf format string. Because all variadic
5 * arguments are integers and the number of arguments is trivially derived
6 * from the format string these implementations are fairly trivial.
7 */
8
9static PyObject*
10mod_CFCalendarAddComponents(
11	PyObject* self __attribute__((__unused__)),
12	PyObject* args)
13{
14	CFCalendarRef calendar;
15	CFAbsoluteTime at;
16	CFOptionFlags flags;
17	char* componentDesc;
18	int params[10];
19	Boolean result;
20	int r;
21
22	if (PyTuple_Size(args) < 4) {
23		PyErr_Format(PyExc_TypeError,
24			"Expecting at least 4 arguments, got %"
25			PY_FORMAT_SIZE_T "d", PyTuple_Size(args));
26		return NULL;
27	}
28
29	r = PyObjC_PythonToObjC(@encode(CFCalendarRef),
30		PyTuple_GetItem(args, 0), &calendar);
31	if (r == -1) {
32		return NULL;
33	}
34
35	r = PyObjC_PythonToObjC(@encode(CFAbsoluteTime),
36		PyTuple_GetItem(args, 1), &at);
37	if (r == -1) {
38		return NULL;
39	}
40
41	r = PyObjC_PythonToObjC(@encode(CFOptionFlags),
42		PyTuple_GetItem(args, 2), &flags);
43	if (r == -1) {
44		return NULL;
45	}
46
47	r = PyObjC_PythonToObjC(@encode(char*),
48		PyTuple_GetItem(args, 3), &componentDesc);
49	if (r == -1) {
50		return NULL;
51	}
52
53	if (PyTuple_Size(args) != 4 + strlen(componentDesc)) {
54		PyErr_Format(PyExc_TypeError,
55			"Expecting %" PY_FORMAT_SIZE_T "d arguments, got %"
56			PY_FORMAT_SIZE_T "d", 4 + strlen(componentDesc),
57			PyTuple_Size(args));
58		return NULL;
59	}
60	if (PyTuple_Size(args) > 4 + 10) {
61		PyErr_SetString(PyExc_TypeError,
62			"At most 10 characters supported in componentDesc");
63		return NULL;
64	}
65
66	Py_ssize_t i, len;
67
68	len = strlen(componentDesc);
69	for (i = 0; i < len; i++) {
70		r = PyObjC_PythonToObjC(@encode(int),
71			PyTuple_GetItem(args, 4 + i), params + i);
72		if (r == -1) {
73			return NULL;
74		}
75	}
76
77	result = FALSE;
78	PyObjC_DURING
79		result = CFCalendarAddComponents(
80			calendar, &at, flags, componentDesc,
81			params[0], params[1], params[2], params[3],
82			params[4], params[5], params[6], params[7],
83			params[8], params[9]);
84
85	PyObjC_HANDLER
86		PyObjCErr_FromObjC(localException);
87
88	PyObjC_ENDHANDLER
89
90	if (PyErr_Occurred()) {
91		return NULL;
92	}
93
94	PyObject* b = PyBool_FromLong(result);
95	if (b  == NULL) {
96		return NULL;
97	}
98	PyObject* a = PyObjC_ObjCToPython(@encode(CFAbsoluteTime), &at);
99	if (a == NULL) {
100		Py_DECREF(b);
101		return NULL;
102	}
103
104	return Py_BuildValue("NN", b, a);
105}
106
107
108static PyObject*
109mod_CFCalendarComposeAbsoluteTime(
110	PyObject* self __attribute__((__unused__)),
111	PyObject* args)
112{
113	CFCalendarRef calendar;
114	CFAbsoluteTime at;
115	char* componentDesc;
116	int params[10];
117	Boolean result;
118	int r;
119
120	if (PyTuple_Size(args) < 3) {
121		PyErr_Format(PyExc_TypeError,
122			"Expecting at least 3 arguments, got %"
123			PY_FORMAT_SIZE_T "d", PyTuple_Size(args));
124		return NULL;
125	}
126
127	r = PyObjC_PythonToObjC(@encode(CFCalendarRef),
128		PyTuple_GetItem(args, 0), &calendar);
129	if (r == -1) {
130		return NULL;
131	}
132
133	if (PyTuple_GetItem(args, 1) != Py_None) {
134		PyErr_SetString(PyExc_TypeError, "placeholder for 'at' must be None");
135		return NULL;
136	}
137
138	r = PyObjC_PythonToObjC(@encode(char*),
139		PyTuple_GetItem(args, 2), &componentDesc);
140	if (r == -1) {
141		return NULL;
142	}
143
144	if (PyTuple_Size(args) != 3 + strlen(componentDesc)) {
145		PyErr_Format(PyExc_TypeError,
146			"Expecting %" PY_FORMAT_SIZE_T "d arguments, got %"
147			PY_FORMAT_SIZE_T "d", 3 + strlen(componentDesc),
148			PyTuple_Size(args));
149		return NULL;
150	}
151	if (PyTuple_Size(args) > 3 + 10) {
152		PyErr_SetString(PyExc_TypeError,
153			"At most 10 characters supported in componentDesc");
154		return NULL;
155	}
156
157	Py_ssize_t i, len;
158
159	len = strlen(componentDesc);
160	for (i = 0; i < len; i++) {
161		r = PyObjC_PythonToObjC(@encode(int),
162			PyTuple_GetItem(args, 3 + i), params + i);
163		if (r == -1) {
164			return NULL;
165		}
166	}
167
168	result = FALSE;
169	PyObjC_DURING
170		result = CFCalendarComposeAbsoluteTime(
171			calendar, &at, componentDesc,
172			params[0], params[1], params[2], params[3],
173			params[4], params[5], params[6], params[7],
174			params[8], params[9]);
175
176	PyObjC_HANDLER
177		PyObjCErr_FromObjC(localException);
178
179	PyObjC_ENDHANDLER
180
181	if (PyErr_Occurred()) {
182		return NULL;
183	}
184
185	PyObject* b = PyBool_FromLong(result);
186	if (b  == NULL) {
187		return NULL;
188	}
189	PyObject* a = PyObjC_ObjCToPython(@encode(CFAbsoluteTime), &at);
190	if (a == NULL) {
191		Py_DECREF(b);
192		return NULL;
193	}
194
195	return Py_BuildValue("NN", b, a);
196}
197
198static PyObject*
199mod_CFCalendarDecomposeAbsoluteTime(
200	PyObject* self __attribute__((__unused__)),
201	PyObject* args)
202{
203	CFCalendarRef calendar;
204	CFAbsoluteTime at;
205	char* componentDesc;
206	int params[10];
207	Boolean result;
208	int r;
209
210	if (PyTuple_Size(args) < 3) {
211		PyErr_Format(PyExc_TypeError,
212			"Expecting at least 3 arguments, got %"
213			PY_FORMAT_SIZE_T "d", PyTuple_Size(args));
214		return NULL;
215	}
216
217	r = PyObjC_PythonToObjC(@encode(CFCalendarRef),
218		PyTuple_GetItem(args, 0), &calendar);
219	if (r == -1) {
220		return NULL;
221	}
222
223	r = PyObjC_PythonToObjC(@encode(CFAbsoluteTime),
224		PyTuple_GetItem(args, 1), &at);
225	if (r == -1) {
226		return NULL;
227	}
228
229	r = PyObjC_PythonToObjC(@encode(char*),
230		PyTuple_GetItem(args, 2), &componentDesc);
231	if (r == -1) {
232		return NULL;
233	}
234
235	if (strlen(componentDesc) > 10) {
236		PyErr_SetString(PyExc_TypeError,
237			"At most 10 characters supported in componentDesc");
238		return NULL;
239	}
240
241	if (PyTuple_Size(args) != 3) {
242		if (PyTuple_Size(args) != 3 + strlen(componentDesc)) {
243			PyErr_Format(PyExc_TypeError,
244				"Expecting %" PY_FORMAT_SIZE_T "d arguments, got %"
245				PY_FORMAT_SIZE_T "d", 3 + strlen(componentDesc),
246				PyTuple_Size(args));
247			return NULL;
248		}
249
250		Py_ssize_t i, len;
251
252		len = strlen(componentDesc);
253		for (i = 0; i < len; i++) {
254			if (PyTuple_GetItem(args, 3 + i) != Py_None) {
255				PyErr_SetString(PyExc_ValueError,
256					"Bad placeholder value");
257				return NULL;
258			}
259		}
260	}
261
262	result = FALSE;
263	PyObjC_DURING
264		result = CFCalendarDecomposeAbsoluteTime(
265			calendar, at, componentDesc,
266			&params[0], &params[1], &params[2], &params[3],
267			&params[4], &params[5], &params[6], &params[7],
268			&params[8], &params[9]);
269
270	PyObjC_HANDLER
271		PyObjCErr_FromObjC(localException);
272
273	PyObjC_ENDHANDLER
274
275	if (PyErr_Occurred()) {
276		return NULL;
277	}
278
279	PyObject *rv = PyTuple_New(1 + strlen(componentDesc));
280	if (rv == NULL) {
281		return NULL;
282	}
283
284	PyObject* b = PyBool_FromLong(result);
285	if (b  == NULL) {
286		return NULL;
287	}
288	PyTuple_SetItem(rv, 0, b);
289
290	Py_ssize_t i, len;
291	len = strlen(componentDesc);
292	for (i = 0; i < len; i++) {
293		PyObject* v = PyInt_FromLong(params[i]);
294		if (v == NULL) {
295			Py_DECREF(rv);
296			return NULL;
297		}
298		PyTuple_SetItem(rv, i+1, v);
299	}
300	return rv;
301}
302
303
304static PyObject*
305mod_CFCalendarGetComponentDifference(
306	PyObject* self __attribute__((__unused__)),
307	PyObject* args)
308{
309	CFCalendarRef calendar;
310	CFAbsoluteTime startingAt;
311	CFAbsoluteTime resultAt;
312	CFOptionFlags options;
313	char* componentDesc;
314	int params[10];
315	Boolean result;
316	int r;
317
318	if (PyTuple_Size(args) < 5) {
319		PyErr_Format(PyExc_TypeError,
320			"Expecting at least 5 arguments, got %"
321			PY_FORMAT_SIZE_T "d", PyTuple_Size(args));
322		return NULL;
323	}
324
325	r = PyObjC_PythonToObjC(@encode(CFCalendarRef),
326		PyTuple_GetItem(args, 0), &calendar);
327	if (r == -1) {
328		return NULL;
329	}
330
331	r = PyObjC_PythonToObjC(@encode(CFAbsoluteTime),
332		PyTuple_GetItem(args, 1), &startingAt);
333	if (r == -1) {
334		return NULL;
335	}
336
337	r = PyObjC_PythonToObjC(@encode(CFAbsoluteTime),
338		PyTuple_GetItem(args, 2), &resultAt);
339	if (r == -1) {
340		return NULL;
341	}
342
343	r = PyObjC_PythonToObjC(@encode(CFOptionFlags),
344		PyTuple_GetItem(args, 3), &options);
345	if (r == -1) {
346		return NULL;
347	}
348
349	r = PyObjC_PythonToObjC(@encode(char*),
350		PyTuple_GetItem(args, 4), &componentDesc);
351	if (r == -1) {
352		return NULL;
353	}
354
355	if (strlen(componentDesc) > 10) {
356		PyErr_SetString(PyExc_TypeError,
357			"At most 10 characters supported in componentDesc");
358		return NULL;
359	}
360
361	if (PyTuple_Size(args) != 5) {
362		if (PyTuple_Size(args) != 5 + strlen(componentDesc)) {
363			PyErr_Format(PyExc_TypeError,
364				"Expecting %" PY_FORMAT_SIZE_T "d arguments, got %"
365				PY_FORMAT_SIZE_T "d", 3 + strlen(componentDesc),
366				PyTuple_Size(args));
367			return NULL;
368		}
369
370		Py_ssize_t i, len;
371
372		len = strlen(componentDesc);
373		for (i = 0; i < len; i++) {
374			if (PyTuple_GetItem(args, 5 + i) != Py_None) {
375				PyErr_SetString(PyExc_ValueError,
376					"Bad placeholder value");
377				return NULL;
378			}
379		}
380	}
381
382	result = FALSE;
383	PyObjC_DURING
384		result = CFCalendarGetComponentDifference(
385			calendar, startingAt, resultAt, options,
386			componentDesc,
387			&params[0], &params[1], &params[2], &params[3],
388			&params[4], &params[5], &params[6], &params[7],
389			&params[8], &params[9]);
390
391	PyObjC_HANDLER
392		PyObjCErr_FromObjC(localException);
393
394	PyObjC_ENDHANDLER
395
396	if (PyErr_Occurred()) {
397		return NULL;
398	}
399
400	PyObject *rv = PyTuple_New(1 + strlen(componentDesc));
401	if (rv == NULL) {
402		return NULL;
403	}
404
405	PyObject* b = PyBool_FromLong(result);
406	if (b  == NULL) {
407		return NULL;
408	}
409	PyTuple_SetItem(rv, 0, b);
410
411	Py_ssize_t i, len;
412	len = strlen(componentDesc);
413	for (i = 0; i < len; i++) {
414		PyObject* v = PyInt_FromLong(params[i]);
415		if (v == NULL) {
416			Py_DECREF(rv);
417			return NULL;
418		}
419		PyTuple_SetItem(rv, i+1, v);
420	}
421	return rv;
422}
423
424#define COREFOUNDATION_CALENDAR_METHODS \
425        {	\
426		"CFCalendarAddComponents",	\
427		(PyCFunction)mod_CFCalendarAddComponents,	\
428		METH_VARARGS,	\
429		NULL	\
430	},	\
431        {	\
432		"CFCalendarComposeAbsoluteTime",	\
433		(PyCFunction)mod_CFCalendarComposeAbsoluteTime,	\
434		METH_VARARGS,	\
435		NULL	\
436	},	\
437        {	\
438		"CFCalendarDecomposeAbsoluteTime",	\
439		(PyCFunction)mod_CFCalendarDecomposeAbsoluteTime,	\
440		METH_VARARGS,	\
441		NULL	\
442	},	\
443        {	\
444		"CFCalendarGetComponentDifference",	\
445		(PyCFunction)mod_CFCalendarGetComponentDifference,	\
446		METH_VARARGS,	\
447		NULL	\
448	},
449