return (0);
}
+/*----- Option parser -----------------------------------------------------*/
+
+struct optextra {
+ PyObject *tag;
+ PyObject *attr;
+};
+
+typedef struct {
+ PyObject_HEAD
+ mdwopt_data opt;
+ char **argv, *stringdata;
+ char *shortopt;
+ struct option *longopt;
+} mdwopt_pyobj;
+static PyTypeObject *mdwopt_pytype;
+#define MDWOPT_PYCHECK(o) PyObject_TypeCheck((o), mdwopt_pytype)
+#define MDWOPT_OPT(o) (&((mdwopt_pyobj *)(o))->opt)
+#define MDWOPT_ARGV(o) (((mdwopt_pyobj *)(o))->argv)
+#define MDWOPT_SHORT(o) (((mdwopt_pyobj *)(o))->shortopt)
+#define MDWOPT_LONG(o) (((mdwopt_pyobj *)(o))->longopt)
+
+#define IXTAG(ix) (((ix)&0xff) | (((ix)&~0xff) << 1))
+#define TAGIX(tag) (((tag)&0xff) | (((tag)&~0x1ff) >> 1))
+
+static PyObject *mdwopt_pynew(PyTypeObject *cls, PyObject *arg, PyObject *kw)
+{
+ DA_DECL(obj_v, PyObject *);
+ DA_DECL(opt_v, struct option);
+ DA_DECL(size_v, size_t);
+
+ PyObject *argvobj = 0, *longoptobj = 0;
+ PyObject *it = 0, *t = 0, *u = 0;
+ char *p; size_t sz;
+ Py_ssize_t n;
+ mdwopt_pyobj *me = 0;
+ char *shortopt;
+ unsigned flags = 0;
+ int f;
+ opt_v opts = DA_INIT;
+ obj_v tags = DA_INIT;
+ size_v off = DA_INIT;
+ dstr strbuf = DSTR_INIT;
+ size_t narg;
+ static const char *const kwlist[] =
+ { "argv", "shortopt", "longopt", "flags", 0 };
+
+ if (!PyArg_ParseTupleAndKeywords(arg, kw, "|OsOO&:new", KWLIST,
+ &argvobj,
+ &shortopt,
+ &longoptobj,
+ convuint, &flags))
+ goto end;
+ if (!argvobj) {
+ argvobj = PySys_GetObject("argv");
+ if (!argvobj) SYSERR("sys.argv missing");
+ }
+
+ it = PyObject_GetIter(argvobj); if (!it) goto end;
+ for (;;) {
+ t = PyIter_Next(it); if (!t) break;
+ if (!TEXT_CHECK(t)) TYERR("argv should be a sequence of strings");
+ TEXT_PTRLEN(t, p, sz);
+ DA_PUSH(&off, strbuf.len);
+ DPUTM(&strbuf, p, sz + 1);
+ Py_DECREF(t); t = 0;
+ }
+ if (PyErr_Occurred()) goto end;
+ narg = DA_LEN(&off);
+ Py_DECREF(it); it = 0;
+
+ it = PyObject_GetIter(longoptobj); if (!it) goto end;
+ for (;;) {
+ t = PyIter_Next(it); if (!t) break;
+ n = PySequence_Size(t); if (n < 0) goto end;
+ if (n < 2 || n > 4)
+ VALERR("long-options entry should be "
+ "(OPT, TAG, [FLAGS = 0, [ATTR = None]])");
+
+ u = PySequence_GetItem(t, 0); if (!u) goto end;
+ if (!TEXT_CHECK(u)) TYERR("option name should be a string");
+ TEXT_PTRLEN(u, p, sz);
+ DA_PUSH(&off, strbuf.len);
+ DPUTM(&strbuf, p, sz + 1);
+ Py_DECREF(u); u = 0;
+
+ u = PySequence_GetItem(t, 1); if (!u) goto end;
+ DA_PUSH(&tags, u); u = 0;
+
+ if (n < 3)
+ f = 0;
+ else {
+ u = PySequence_GetItem(t, 0); if (!u) goto end;
+ if (getint(u, &f)) goto end;
+ Py_DECREF(u); u = 0;
+ }
+
+
+
+end:
+ return (PyObject *)me;
+}
+
+static void mdwopt_pydealloc(PyObject *me)
+{
+ mdwopt_pyobj *m = (mdwopt_pyobj *)me;
+
+ xfree(m->stringdata);
+ xfree(m->longopt);
+ FREEOBJ(me);
+}
+
+static const PyMemberDef mdwopt_pymembers[] = {
+#define MEMBERSTRUCT mdwopt_pyobj
+#undef MEMBERSTRUCT
+ { 0 }
+};
+
+static const PyGetSetDef mdwopt_pygetset[] = {
+#define GETSETNAME(op, name) mo##op##_##name
+#undef GETSETNAME
+ { 0 }
+};
+
+static const PyMethodDef mdwopt_pymethods[] = {
+#define METHNAME(name) mometh_##name
+#undef METHNAME
+ { 0 }
+};
+
+static const PyTypeObject mdwopt_pytype_skel = {
+ PyVarObject_HEAD_INIT(0, 0) /* Header */
+ "MdwOpt", /* @tp_name@ */
+ sizeof(mdwopt_pyobj), /* @tp_basicsize@ */
+ 0, /* @tp_itemsize@ */
+
+ mdwopt_pydealloc, /* @tp_dealloc@ */
+ 0, /* @tp_print@ */
+ 0, /* @tp_getattr@ */
+ 0, /* @tp_setattr@ */
+ 0, /* @tp_compare@ */
+ 0, /* @tp_repr@ */
+ 0, /* @tp_as_number@ */
+ 0, /* @tp_as_sequence@ */
+ 0, /* @tp_as_mapping@ */
+ 0, /* @tp_hash@ */
+ 0, /* @tp_call@ */
+ 0, /* @tp_str@ */
+ 0, /* @tp_getattro@ */
+ 0, /* @tp_setattro@ */
+ 0, /* @tp_as_buffer@ */
+ Py_TPFLAGS_DEFAULT | /* @tp_flags@ */
+ Py_TPFLAGS_BASETYPE,
+
+ /* @tp_doc@ */
+ "MdwOpt([argv = SEQ], [shortopt = STR], [longopt = SEQ], [flags = 0])",
+
+ 0, /* @tp_traverse@ */
+ 0, /* @tp_clear@ */
+ 0, /* @tp_richcompare@ */
+ 0, /* @tp_weaklistoffset@ */
+ 0, /* @tp_iter@ */
+ 0, /* @tp_iternext@ */
+ PYMETHODS(mdwopt), /* @tp_methods@ */
+ PYMEMBERS(mdwopt), /* @tp_members@ */
+ PYGETSET(mdwopt), /* @tp_getset@ */
+ 0, /* @tp_base@ */
+ 0, /* @tp_dict@ */
+ 0, /* @tp_descr_get@ */
+ 0, /* @tp_descr_set@ */
+ 0, /* @tp_dictoffset@ */
+ 0, /* @tp_init@ */
+ PyType_GenericAlloc, /* @tp_alloc@ */
+ mdwopt_pynew, /* @tp_new@ */
+ 0, /* @tp_free@ */
+ 0 /* @tp_is_gc@ */
+};
+
/*----- Main code ---------------------------------------------------------*/
static const PyMethodDef methods[] = {
void ui_pyinit(void)
{
+ INITTYPE(mdwopt, root);
addmethods(methods);
}
void ui_pyinsert(PyObject *mod)
{
+ INSERT("MdwOpt", mdwopt_pytype);
}
int ui_pyready(void) { return (set_program_name()); }