📄 siplib.c
字号:
Py_DECREF(sipArgs); return 0; } *argsParsedp = nrargs; Py_DECREF(sipArgs); return 1;}/* * Parse a pair of arguments to a C/C++ function without any side effects. */static int sip_api_parse_pair(int *argsParsedp, PyObject *sipArg0, PyObject *sipArg1, char *fmt, ...){ int valid, nrargs, selfarg; sipWrapper *self; PyObject *args; va_list va; /* Previous sticky errors stop subsequent parses. */ if (*argsParsedp & PARSE_STICKY) return 0; if ((args = PyTuple_New(2)) == NULL) return 0; Py_INCREF(sipArg0); PyTuple_SET_ITEM(args, 0, sipArg0); Py_INCREF(sipArg1); PyTuple_SET_ITEM(args, 1, sipArg1); nrargs = 2; /* * The first pass checks all the types and does conversions that are * cheap and have no side effects. */ va_start(va,fmt); valid = parsePass1(&self,&selfarg,&nrargs,args,fmt,va); va_end(va); if (valid != PARSE_OK) { int pvalid, pnrargs; /* * Use this error if there was no previous error, or if we * have parsed more arguments this time, or if the previous * error was that there were too many arguments. */ pvalid = (*argsParsedp & PARSE_MASK); pnrargs = (*argsParsedp & ~PARSE_MASK); if (pvalid == PARSE_OK || pnrargs < nrargs || (pnrargs == nrargs && pvalid == PARSE_MANY)) *argsParsedp = valid | nrargs; Py_DECREF(args); return 0; } /* * The second pass does any remaining conversions now that we know we * have the right signature. */ va_start(va,fmt); valid = parsePass2(self,selfarg,nrargs,args,fmt,va); va_end(va); if (valid != PARSE_OK) { *argsParsedp = valid | PARSE_STICKY; Py_DECREF(args); return 0; } *argsParsedp = nrargs; Py_DECREF(args); return 1;}/* * First pass of the argument parse, converting those that can be done so * without any side effects. Return PARSE_OK if the arguments matched. */static int parsePass1(sipWrapper **selfp,int *selfargp,int *argsParsedp, PyObject *sipArgs,char *fmt,va_list va){ int valid, compulsory, nrargs, argnr, nrparsed; valid = PARSE_OK; nrargs = *argsParsedp; nrparsed = 0; compulsory = TRUE; argnr = 0; /* * Handle those format characters that deal with the "self" argument. * They will always be the first one. */ *selfp = NULL; *selfargp = FALSE; switch (*fmt++) { case 'B': case 'p': { PyObject *self; sipWrapperType *type; self = *va_arg(va,PyObject **); type = va_arg(va,sipWrapperType *); va_arg(va,void **); if (self == NULL) { if ((valid = getSelfFromArgs(type,sipArgs,argnr,selfp)) != PARSE_OK) break; *selfargp = TRUE; ++nrparsed; ++argnr; } else *selfp = (sipWrapper *)self; break; } case 'C': *selfp = (sipWrapper *)va_arg(va,PyObject *); break; default: --fmt; } /* Now handle the remaining arguments. */ while (valid == PARSE_OK) { char ch; PyObject *arg; PyErr_Clear(); /* See if the following arguments are optional. */ if ((ch = *fmt++) == '|') { compulsory = FALSE; ch = *fmt++; } /* See if we don't expect anything else. */ if (ch == '\0') { /* Invalid if there are still arguments. */ if (argnr < nrargs) valid = PARSE_MANY; break; } /* See if we have run out of arguments. */ if (argnr == nrargs) { /* * It is an error if we are still expecting compulsory * arguments unless the current argume is an ellipsis. */ if (ch != 'W' && ch != '\0' && compulsory) valid = PARSE_FEW; break; } /* Get the next argument. */ arg = PyTuple_GET_ITEM(sipArgs,argnr); ++argnr; switch (ch) { case 'W': /* Ellipsis. */ break; case 's': { /* String or None. */ char **p = va_arg(va,char **); if (arg == Py_None) *p = NULL; else if (PyString_Check(arg)) *p = PyString_AS_STRING(arg); else valid = PARSE_TYPE; break; } case 'U': { /* * Slot name or callable, return the name or * callable. */ char **sname = va_arg(va, char **); PyObject **scall = va_arg(va, PyObject **); *sname = NULL; *scall = NULL; if (PyString_Check(arg)) { char *s = PyString_AS_STRING(arg); if (*s == '1' || *s == '2' || *s == '9') *sname = s; else valid = PARSE_TYPE; } else if (PyCallable_Check(arg)) *scall = arg; else if (arg != Py_None) valid = PARSE_TYPE; break; } case 'S': { /* Slot name, return the name. */ if (PyString_Check(arg)) { char *s = PyString_AS_STRING(arg); if (*s == '1' || *s == '2' || *s == '9') *va_arg(va,char **) = s; else valid = PARSE_TYPE; } else valid = PARSE_TYPE; break; } case 'G': { /* Signal name, return the name. */ if (PyString_Check(arg)) { char *s = PyString_AS_STRING(arg); if (*s == '2' || *s == '9') *va_arg(va,char **) = s; else valid = PARSE_TYPE; } else valid = PARSE_TYPE; break; } case 'J': { /* Class instance. */ if (*fmt == '\0') valid = PARSE_FORMAT; else { int flags = *fmt++ - '0'; sipWrapperType *type; int iflgs = 0; type = va_arg(va,sipWrapperType *); va_arg(va,void **); if (flags & FORMAT_DEREF) iflgs |= SIP_NOT_NONE; if (flags & FORMAT_GET_WRAPPER) va_arg(va,PyObject **); if (flags & FORMAT_NO_CONVERTORS) iflgs |= SIP_NO_CONVERTORS; else va_arg(va, int *); if (!sip_api_can_convert_to_instance(arg, type, iflgs)) valid = PARSE_TYPE; } break; } case 'M': { /* Mapped type instance. */ if (*fmt == '\0') valid = PARSE_FORMAT; else { int flags = *fmt++ - '0'; sipMappedType *mt; int iflgs = 0; mt = va_arg(va, sipMappedType *); va_arg(va, void **); va_arg(va, int *); if (flags & FORMAT_DEREF) iflgs |= SIP_NOT_NONE; if (!sip_api_can_convert_to_mapped_type(arg, mt, iflgs)) valid = PARSE_TYPE; } break; } case 'N': { /* Python object of given type or None. */ PyTypeObject *type = va_arg(va,PyTypeObject *); PyObject **p = va_arg(va,PyObject **); if (arg == Py_None || PyObject_TypeCheck(arg,type)) *p = arg; else valid = PARSE_TYPE; break; } case 'P': { /* * Python object of any type with a * sub-format. */ *va_arg(va,PyObject **) = arg; /* Skip the sub-format. */ if (*fmt++ == '\0') valid = PARSE_FORMAT; break; } case 'T': { /* Python object of given type. */ PyTypeObject *type = va_arg(va,PyTypeObject *); PyObject **p = va_arg(va,PyObject **); if (PyObject_TypeCheck(arg,type)) *p = arg; else valid = PARSE_TYPE; break; } case 'R': { /* Sub-class of QObject. */ if (sipQtSupport == NULL || !PyObject_TypeCheck(arg, (PyTypeObject *)sipQObjectClass)) valid = PARSE_TYPE; else *va_arg(va,PyObject **) = arg; break; } case 'F': { /* Python callable object. */ if (PyCallable_Check(arg)) *va_arg(va,PyObject **) = arg; else valid = PARSE_TYPE; break; } case 'H': { /* Python callable object or None. */ if (arg == Py_None || PyCallable_Check(arg)) *va_arg(va,PyObject **) = arg; else valid = PARSE_TYPE; break; } case 'q': { /* Qt receiver to connect. */ va_arg(va,char *); va_arg(va,void **); va_arg(va,const char **); if (sipQtSupport == NULL || !PyObject_TypeCheck(arg, (PyTypeObject *)sipQObjectClass)) valid = PARSE_TYPE; break; } case 'Q': { /* Qt receiver to disconnect. */ va_arg(va,char *); va_arg(va,void **); va_arg(va,const char **); if (sipQtSupport == NULL || !PyObject_TypeCheck(arg, (PyTypeObject *)sipQObjectClass)) valid = PARSE_TYPE; break; } case 'y': { /* Python slot to connect. */ va_arg(va,char *); va_arg(va,void **); va_arg(va,const char **); if (sipQtSupport == NULL || !PyCallable_Check(arg)) valid = PARSE_TYPE; break; } case 'Y': { /* Python slot to disconnect. */ va_arg(va,char *); va_arg(va,void **); va_arg(va,const char **); if (sipQtSupport == NULL || !PyCallable_Check(arg)) valid = PARSE_TYPE; break; } case 'a': { /* Byte array or None. */ char **p = va_arg(va,char **); int *szp = va_arg(va,int *); if (arg == Py_None) { *p = NULL; *szp = 0; } else if (PyString_Check(arg)) { *p = PyString_AS_STRING(arg); *szp = PyString_GET_SIZE(arg); } else valid = PARSE_TYPE; break; } case 'c': { /* Character. */ if (PyString_Check(arg) && PyString_GET_SIZE(arg) == 1) *va_arg(va,char *) = *PyString_AS_STRING(arg); else valid = PARSE_TYPE; break; } case 'b': { /* Bool. */ int v = PyInt_AsLong(arg); if (PyErr_Occurred()) valid = PARSE_TYPE; else sipSetBool(va_arg(va,void *),v); break; } case 'e': { /* Anonymous enum. */ int v = PyInt_AsLong(arg); if (PyErr_Occurred()) valid = PARSE_TYPE; else *va_arg(va,int *) = v; break; } case 'E': { /* Named enum. */ PyTypeObject *et = va_arg(va, PyTypeObject *); va_arg(va, int *); if (!PyObject_TypeCheck(arg, et)) valid = PARSE_TYPE; } break; case 'i': { /* Integer. */ int v = PyInt_AsLong(arg); if (PyErr_Occurred()) valid = PARSE_TYPE; else *va_arg(va,int *) = v; break; } case 'u': { /* Unsigned integer. */ unsigned v = sip_api_long_as_unsigned_long(arg); if (PyErr_Occurred()) valid = PARSE_TYPE; else *va_arg(va, unsigned *) = v; break; } case 'h': { /* Short integer. */ short v = PyInt_AsLong(arg); if (PyErr_Occurred()) valid = PARSE_TYPE; else *va_arg(va,short *) = v; break; } case 't': { /* Unsigned short integer. */ unsigned short v = sip_api_long_as_unsigned_long(arg); if (PyErr_Occurred()) valid = PARSE_TYPE; else *va_arg(va, unsigned short *) = v; break; } case 'l': { /* Long integer. */ long v = PyLong_AsLong(arg); if (PyErr_Occurred()) valid = PARSE_TYPE; else *va_arg(va,long *) = v;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -