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