// Get an array of OpenGL fundamental types from a sequence or an object that // implements a compatible buffer. const GLvoid *qpyopengl_value_array(sipErrorState *estate, PyObject *values, GLenum gl_type, PyObject *bindings) { // Handle the trivial None case first. 0 has a special meaning to some // OpenGL calls so we allow it for all. If this becomes a problem then we // can add a new variant of this function that handles None differently. if (values == Py_None) return 0; qpyopengl_dataCache *data_cache = get_cache(bindings); if (!data_cache) { *estate = sipErrorFail; return 0; } // Get an empty wrapper for the array. if (data_cache->uncached) data_cache->uncached->clear(); else data_cache->uncached = new Array; return convert_values(data_cache->uncached, values, gl_type, estate); }
// Get an array of OpenGL fundamental types from a sequence or an object that // implements a compatible buffer. Cache the array so that it persists until a // similar call. const GLvoid *qpyopengl_value_array_cached(sipErrorState *estate, PyObject *values, GLenum gl_type, PyObject *bindings, const char *pkey, GLuint skey) { // Handle the trivial byte offset case first. PyErr_Clear(); void *data = PyLong_AsVoidPtr(values); if (!PyErr_Occurred()) return data; PyErr_Clear(); qpyopengl_dataCache *data_cache = get_cache(bindings); if (!data_cache) { *estate = sipErrorFail; return 0; } if (!data_cache->pcache) data_cache->pcache = new PrimaryCache; // Get an empty wrapper for the array. PrimaryCacheEntry *pce = (*data_cache->pcache)[pkey]; if (!pce) { pce = new PrimaryCacheEntry; data_cache->pcache->insert(pkey, pce); } Array *array; if (skey == 0) { array = &pce->skey_0; } else { if (!pce->skey_n) pce->skey_n = new SecondaryCache; array = (*pce->skey_n)[skey]; if (!array) { array = new Array; pce->skey_n->insert(skey, array); } } array->clear(); return convert_values(array, values, gl_type, estate); }
/*! * \param pparams List of parameters from the selection parser. * \param[in] nparam Number of parameters in \p params. * \param params Array of parameters to parse. * \param root Selection element to which child expressions are added. * \param[in] scanner Scanner data structure. * \returns TRUE if the parameters were parsed successfully, FALSE otherwise. * * Initializes the \p params array based on the parameters in \p pparams. * See the documentation of \c gmx_ana_selparam_t for different options * available for parsing. * * The list \p pparams and any associated values are freed after the parameters * have been processed, no matter is there was an error or not. */ gmx_bool _gmx_sel_parse_params(t_selexpr_param *pparams, int nparam, gmx_ana_selparam_t *params, t_selelem *root, void *scanner) { t_selexpr_param *pparam; gmx_ana_selparam_t *oparam; gmx_bool bOk, rc; int i; /* Check that the value pointers of SPAR_VARNUM parameters are NULL and * that they are not NULL for other parameters */ bOk = TRUE; for (i = 0; i < nparam; ++i) { if (params[i].val.type != POS_VALUE && (params[i].flags & (SPAR_VARNUM | SPAR_ATOMVAL))) { if (params[i].val.u.ptr != NULL) { _gmx_selparser_error("warning: value pointer of parameter '%s' is not NULL\n" " although it should be for SPAR_VARNUM and SPAR_ATOMVAL parameters\n", params[i].name); } if ((params[i].flags & SPAR_VARNUM) && (params[i].flags & SPAR_DYNAMIC) && !params[i].nvalptr) { _gmx_selparser_error("error: nvalptr of parameter '%s' is NULL\n" " but both SPAR_VARNUM and SPAR_DYNAMIC are specified\n", params[i].name); bOk = FALSE; } } else { if (params[i].val.u.ptr == NULL) { _gmx_selparser_error("error: value pointer of parameter '%s' is NULL\n", params[i].name); bOk = FALSE; } } } if (!bOk) { _gmx_selexpr_free_params(pparams); return FALSE; } /* Parse the parameters */ pparam = pparams; i = 0; while (pparam) { /* Find the parameter and make some checks */ if (pparam->name != NULL) { i = -1; oparam = gmx_ana_selparam_find(pparam->name, nparam, params); } else if (i >= 0) { oparam = ¶ms[i]; if (oparam->name != NULL) { oparam = NULL; _gmx_selparser_error("too many NULL parameters provided"); bOk = FALSE; goto next_param; } ++i; } else { _gmx_selparser_error("all NULL parameters should appear in the beginning of the list"); bOk = FALSE; pparam = pparam->next; continue; } if (!oparam) { _gmx_selparser_error("unknown parameter '%s' skipped", pparam->name); bOk = FALSE; goto next_param; } if (oparam->flags & SPAR_SET) { _gmx_selparser_error("parameter '%s' set multiple times, extra values skipped", pparam->name); bOk = FALSE; goto next_param; } oparam->flags |= SPAR_SET; /* Process the values for the parameter */ convert_const_values(pparam->value); if (convert_values(pparam->value, oparam->val.type, scanner) != 0) { _gmx_selparser_error("invalid value for parameter '%s'", pparam->name); bOk = FALSE; goto next_param; } if (oparam->val.type == NO_VALUE) { rc = parse_values_gmx_bool(pparam->name, pparam->nval, pparam->value, oparam); } else if (oparam->flags & SPAR_RANGES) { rc = parse_values_range(pparam->nval, pparam->value, oparam); } else if (oparam->flags & SPAR_VARNUM) { if (pparam->nval == 1 && pparam->value->bExpr) { rc = parse_values_varnum_expr(pparam->nval, pparam->value, oparam, root); } else { rc = parse_values_varnum(pparam->nval, pparam->value, oparam, root); } } else if (oparam->flags & SPAR_ENUMVAL) { rc = parse_values_enum(pparam->nval, pparam->value, oparam); } else { rc = parse_values_std(pparam->nval, pparam->value, oparam, root); } if (!rc) { bOk = FALSE; } /* Advance to the next parameter */ next_param: pparam = pparam->next; } /* Check that all required parameters are present */ for (i = 0; i < nparam; ++i) { if (!(params[i].flags & SPAR_OPTIONAL) && !(params[i].flags & SPAR_SET)) { _gmx_selparser_error("required parameter '%s' not specified", params[i].name); bOk = FALSE; } } _gmx_selexpr_free_params(pparams); return bOk; }