diff src/if_py_both.h @ 5610:2ace11abcfb5 v7.4.152

updated for version 7.4.152 Problem: Python: Cannot iterate over options. Solution: Add options iterator. (ZyX)
author Bram Moolenaar <bram@vim.org>
date Tue, 14 Jan 2014 16:55:00 +0100
parents ec02e1474bc2
children 30e300c0b2c1
line wrap: on
line diff
--- a/src/if_py_both.h
+++ b/src/if_py_both.h
@@ -2949,10 +2949,10 @@ typedef int (*checkfun)(void *);
 typedef struct
 {
     PyObject_HEAD
-    int opt_type;
-    void *from;
-    checkfun Check;
-    PyObject *fromObj;
+    int		opt_type;
+    void	*from;
+    checkfun	Check;
+    PyObject	*fromObj;
 } OptionsObject;
 
     static int
@@ -3072,6 +3072,69 @@ OptionsItem(OptionsObject *self, PyObjec
 }
 
     static int
+OptionsContains(OptionsObject *self, PyObject *keyObject)
+{
+    char_u	*key;
+    PyObject	*todecref;
+
+    if (!(key = StringToChars(keyObject, &todecref)))
+	return -1;
+
+    if (*key == NUL)
+    {
+	Py_XDECREF(todecref);
+	return 0;
+    }
+
+    if (get_option_value_strict(key, NULL, NULL, self->opt_type, NULL))
+    {
+	Py_XDECREF(todecref);
+	return 1;
+    }
+    else
+    {
+	Py_XDECREF(todecref);
+	return 0;
+    }
+}
+
+typedef struct
+{
+    void	*lastoption;
+    int		opt_type;
+} optiterinfo_T;
+
+    static PyObject *
+OptionsIterNext(optiterinfo_T **oii)
+{
+    char_u	*name;
+
+    if ((name = option_iter_next(&((*oii)->lastoption), (*oii)->opt_type)))
+	return PyString_FromString((char *)name);
+
+    return NULL;
+}
+
+    static PyObject *
+OptionsIter(OptionsObject *self)
+{
+    optiterinfo_T	*oii;
+
+    if (!(oii = PyMem_New(optiterinfo_T, 1)))
+    {
+	PyErr_NoMemory();
+	return NULL;
+    }
+
+    oii->opt_type = self->opt_type;
+    oii->lastoption = NULL;
+
+    return IterNew(oii,
+	    (destructorfun) PyMem_Free, (nextfun) OptionsIterNext,
+	    NULL, NULL);
+}
+
+    static int
 set_option_value_err(char_u *key, int numval, char_u *stringval, int opt_flags)
 {
     char_u	*errmsg;
@@ -3231,6 +3294,19 @@ OptionsAssItem(OptionsObject *self, PyOb
     return ret;
 }
 
+static PySequenceMethods OptionsAsSeq = {
+    0,					/* sq_length */
+    0,					/* sq_concat */
+    0,					/* sq_repeat */
+    0,					/* sq_item */
+    0,					/* sq_slice */
+    0,					/* sq_ass_item */
+    0,					/* sq_ass_slice */
+    (objobjproc) OptionsContains,	/* sq_contains */
+    0,					/* sq_inplace_concat */
+    0,					/* sq_inplace_repeat */
+};
+
 static PyMappingMethods OptionsAsMapping = {
     (lenfunc)       NULL,
     (binaryfunc)    OptionsItem,
@@ -6121,8 +6197,10 @@ init_structs(void)
     vim_memset(&OptionsType, 0, sizeof(OptionsType));
     OptionsType.tp_name = "vim.options";
     OptionsType.tp_basicsize = sizeof(OptionsObject);
+    OptionsType.tp_as_sequence = &OptionsAsSeq;
     OptionsType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
     OptionsType.tp_doc = "object for manipulating options";
+    OptionsType.tp_iter = (getiterfunc)OptionsIter;
     OptionsType.tp_as_mapping = &OptionsAsMapping;
     OptionsType.tp_dealloc = (destructor)OptionsDestructor;
     OptionsType.tp_traverse = (traverseproc)OptionsTraverse;