~ubuntu-branches/ubuntu/edgy/rpm/edgy

« back to all changes in this revision

Viewing changes to python/poptmodule.c

  • Committer: Bazaar Package Importer
  • Author(s): Joey Hess
  • Date: 2002-01-22 20:56:57 UTC
  • Revision ID: james.westby@ubuntu.com-20020122205657-l74j50mr9z8ofcl5
Tags: upstream-4.0.3
ImportĀ upstreamĀ versionĀ 4.0.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *
 
3
 * 
 
4
 * 
 
5
 */
 
6
 
 
7
#define PY_POPT_VERSION "0.2"
 
8
 
 
9
static const char *rcs_id = "$Id: poptmodule.c,v 1.1.2.4 2001/08/27 18:38:26 jbj Exp $";
 
10
 
 
11
static char *module_doc = "Python bindings for the popt library\n\
 
12
\n\
 
13
The popt library provides useful command-line parsing functions.\n\
 
14
The latest version of the popt library is distributed with rpm\n\
 
15
and is always available from ftp://ftp.rpm.org/pub/rpm/dist";
 
16
 
 
17
#include <Python.h>
 
18
#include <popt.h>
 
19
 
 
20
#define DEBUG 1
 
21
 
 
22
#if defined(DEBUG)
 
23
#define debug(x, y) { printf("%s: %s\n", x, y); }
 
24
#else
 
25
#define debug(x, y) {}
 
26
#endif 
 
27
 
 
28
/* Functins and datatypes needed for the context object */
 
29
typedef struct poptContext_s {
 
30
    PyObject_HEAD;
 
31
    struct poptOption *options;
 
32
    int optionsNo;
 
33
    poptContext ctx;
 
34
    /* The index of the option retrieved with getNextOpt()*/
 
35
    int opt;
 
36
} poptContextObject;
 
37
 
 
38
/* The exception */
 
39
static PyObject *pypoptError;
 
40
 
 
41
/* Misc functions */
 
42
void __printPopt(struct poptOption *opts)
 
43
{
 
44
    printf("+++++++++++\n");
 
45
    printf("Long name: %s\n", opts->longName);
 
46
    printf("Short name: %c\n", opts->shortName);
 
47
    printf("argInfo: %d\n", opts->argInfo);
 
48
    printf("Val: %d\n", opts->val);
 
49
    printf("-----------\n");
 
50
}
 
51
 
 
52
static PyObject * __poptOptionValue2PyObject(const struct poptOption *option)
 
53
{
 
54
    if (option == NULL) {
 
55
        /* This shouldn't really happen */
 
56
        PyErr_BadInternalCall();
 
57
        return NULL;
 
58
    }
 
59
    if (option->arg == NULL) {
 
60
        Py_INCREF(Py_None);
 
61
        return Py_None;
 
62
    }
 
63
    switch(option->argInfo) {
 
64
        case POPT_ARG_INCLUDE_TABLE:
 
65
            /* Do nothing */
 
66
            Py_INCREF(Py_None);
 
67
            return Py_None;
 
68
        case POPT_ARG_STRING: 
 
69
            if (*(char **)(option->arg) == NULL) {
 
70
                Py_INCREF(Py_None);
 
71
                return Py_None;
 
72
            }
 
73
            return PyString_FromString(*(char **)(option->arg));
 
74
            break;
 
75
        case POPT_ARG_DOUBLE:
 
76
            return PyFloat_FromDouble(*(double *)(option->arg));
 
77
            break;
 
78
        case POPT_ARG_LONG:
 
79
            return PyInt_FromLong(*(long *)(option->arg));
 
80
            break;
 
81
        case POPT_ARG_NONE:
 
82
        case POPT_ARG_VAL:
 
83
            return PyInt_FromLong(*(int *)(option->arg));
 
84
            break;
 
85
    }
 
86
    /* This shouldn't really happen */
 
87
    PyErr_BadInternalCall();
 
88
    return NULL;
 
89
}
 
90
 
 
91
static PyObject * ctxReset(poptContextObject *self, PyObject *args)
 
92
{
 
93
    if (!PyArg_ParseTuple(args, ""))
 
94
        return NULL;
 
95
    poptResetContext(self->ctx);
 
96
    self->opt = -1;
 
97
    Py_INCREF(Py_None);
 
98
    return Py_None;
 
99
}
 
100
 
 
101
static PyObject * ctxGetNextOpt(poptContextObject *self, PyObject *args)
 
102
{
 
103
    if (!PyArg_ParseTuple(args, ""))
 
104
        return NULL;
 
105
    self->opt = poptGetNextOpt(self->ctx);
 
106
    return PyInt_FromLong(self->opt);
 
107
}
 
108
 
 
109
static PyObject * ctxGetOptArg(poptContextObject *self, PyObject *args)
 
110
{
 
111
    const char *opt;
 
112
    if (!PyArg_ParseTuple(args, ""))
 
113
        return NULL;
 
114
    opt = poptGetOptArg(self->ctx);
 
115
    if (opt == NULL) {
 
116
        Py_INCREF(Py_None);
 
117
        return Py_None;
 
118
    }
 
119
    return PyString_FromString(opt);
 
120
}
 
121
 
 
122
static PyObject * ctxGetArg(poptContextObject *self, PyObject *args)
 
123
{
 
124
    const char *arg;
 
125
    if (!PyArg_ParseTuple(args, ""))
 
126
        return NULL;
 
127
    arg = poptGetArg(self->ctx);
 
128
    if (arg == NULL) {
 
129
        Py_INCREF(Py_None);
 
130
        return Py_None;
 
131
    }
 
132
    return PyString_FromString(arg);
 
133
}
 
134
 
 
135
static PyObject * ctxPeekArg(poptContextObject *self, PyObject *args)
 
136
{
 
137
    const char *arg;
 
138
    if (!PyArg_ParseTuple(args, ""))
 
139
        return NULL;
 
140
    arg = poptPeekArg(self->ctx);
 
141
    if (arg == NULL) {
 
142
        Py_INCREF(Py_None);
 
143
        return Py_None;
 
144
    }
 
145
    return PyString_FromString(arg);
 
146
}
 
147
 
 
148
static PyObject * ctxGetArgs(poptContextObject *self, PyObject *argsFoo)
 
149
{
 
150
    const char **args;
 
151
    PyObject *list;
 
152
    int size, i;
 
153
    if (!PyArg_ParseTuple(argsFoo, ""))
 
154
        return NULL;
 
155
    args = poptGetArgs(self->ctx);
 
156
    if (args == NULL) {
 
157
        Py_INCREF(Py_None);
 
158
        return Py_None;
 
159
    }
 
160
    /* Compute the list size */
 
161
    for (size = 0; args[size]; size++);
 
162
    /* Create the list */
 
163
    list = PyList_New(size);
 
164
    if (list == NULL)
 
165
        return NULL;
 
166
    for (i = 0; i < size; i++) 
 
167
        PyList_SetItem(list, i, PyString_FromString(args[i]));
 
168
    return list;
 
169
}
 
170
 
 
171
static PyObject * ctxBadOption(poptContextObject *self, PyObject *args)
 
172
{
 
173
    int flags = 0;
 
174
    const char *badOption;
 
175
    if (!PyArg_ParseTuple(args, "|i", &flags)) 
 
176
        return NULL;
 
177
    badOption = poptBadOption(self->ctx, flags);
 
178
    if (badOption == NULL) {
 
179
        Py_INCREF(Py_None);
 
180
        return Py_None;
 
181
    }
 
182
    return PyString_FromString(badOption);
 
183
}
 
184
 
 
185
static PyObject * ctxReadDefaultConfig(poptContextObject *self, PyObject *args)
 
186
{
 
187
    int flags = 0;
 
188
    if (!PyArg_ParseTuple(args, "|i", &flags)) 
 
189
        return NULL;
 
190
    return PyInt_FromLong(poptReadDefaultConfig(self->ctx, flags));
 
191
}
 
192
 
 
193
static PyObject * ctxReadConfigFile(poptContextObject *self, PyObject *args)
 
194
{
 
195
    const char *filename;
 
196
    if (!PyArg_ParseTuple(args, "s", &filename))
 
197
        return NULL;
 
198
    return PyInt_FromLong(poptReadConfigFile(self->ctx, filename));
 
199
}
 
200
 
 
201
static PyObject * ctxSetOtherOptionHelp(poptContextObject *self, PyObject *args)
 
202
{
 
203
    const char *option;
 
204
    if (!PyArg_ParseTuple(args, "s", &option)) 
 
205
        return NULL;
 
206
    poptSetOtherOptionHelp(self->ctx, option);
 
207
    Py_INCREF(Py_None);
 
208
    return Py_None;
 
209
}
 
210
 
 
211
static PyObject * ctxPrintHelp(poptContextObject *self, PyObject *args)
 
212
{
 
213
    FILE *f;
 
214
    int flags = 0;
 
215
    PyObject *file;
 
216
    if (!PyArg_ParseTuple(args, "|O!i", &PyFile_Type, &file, &flags)) 
 
217
        return NULL;
 
218
    f = PyFile_AsFile(file);
 
219
    if (f == NULL)
 
220
        f = stderr;
 
221
    poptPrintHelp(self->ctx, f, flags);
 
222
    Py_INCREF(Py_None);
 
223
    return Py_None;
 
224
}
 
225
 
 
226
static PyObject * ctxPrintUsage(poptContextObject *self, PyObject *args)
 
227
{
 
228
    FILE *f;
 
229
    int flags = 0;
 
230
    PyObject *file;
 
231
    if (!PyArg_ParseTuple(args, "|O!i", &PyFile_Type, &file, &flags))
 
232
        return NULL;
 
233
        f = PyFile_AsFile(file);
 
234
    if (f == NULL)
 
235
        f = stderr;
 
236
    poptPrintUsage(self->ctx, f, flags);
 
237
    Py_INCREF(Py_None);
 
238
    return Py_None;
 
239
}
 
240
 
 
241
/* XXX addAlias */
 
242
/* XXX stuffArgs */
 
243
/* XXX callbackType */
 
244
 
 
245
/*******************************/
 
246
/* Added ctxGetOptValues */
 
247
/*******************************/
 
248
/* Builds a list of values corresponding to each option */
 
249
static PyObject * ctxGetOptValues(poptContextObject *self, PyObject *args)
 
250
{
 
251
    PyObject *list;
 
252
    int i;
 
253
    if (!PyArg_ParseTuple(args, ""))
 
254
        return NULL;
 
255
    /* Create the list */
 
256
    list = PyList_New(self->optionsNo);
 
257
    if (list == NULL) 
 
258
        return NULL;
 
259
    for (i = 0; i < self->optionsNo; i++) {
 
260
        PyObject *item;
 
261
        item = __poptOptionValue2PyObject(self->options + i);
 
262
        item = __poptOptionValue2PyObject(self->options + i);
 
263
        if (item == NULL)
 
264
            return NULL;
 
265
        PyList_SetItem(list, i, item);
 
266
    }
 
267
    return list;
 
268
}
 
269
 
 
270
static PyObject * ctxGetOptValue(poptContextObject *self, PyObject *args)
 
271
{
 
272
    int i;
 
273
    if (!PyArg_ParseTuple(args, ""))
 
274
        return NULL;
 
275
    if (self->opt < 0) {
 
276
        /* No processing */
 
277
        Py_INCREF(Py_None);
 
278
        return Py_None;
 
279
    }
 
280
    /* Look for the option that returned this value */
 
281
    for (i = 0; i < self->optionsNo; i++)
 
282
        if (self->options[i].val == self->opt) {
 
283
            /* Cool, this is the one */
 
284
            return __poptOptionValue2PyObject(self->options + i);
 
285
        }
 
286
    /* Not found */
 
287
    Py_INCREF(Py_None);
 
288
    return Py_None;
 
289
}
 
290
 
 
291
static struct PyMethodDef ctxMethods[] = {
 
292
    {"reset", (PyCFunction)ctxReset, METH_VARARGS},
 
293
    {"getNextOpt", (PyCFunction)ctxGetNextOpt, METH_VARARGS},
 
294
    {"getOptArg", (PyCFunction)ctxGetOptArg, METH_VARARGS},
 
295
    {"getArg", (PyCFunction)ctxGetArg, METH_VARARGS},
 
296
    {"peekArg", (PyCFunction)ctxPeekArg, METH_VARARGS},
 
297
    {"getArgs", (PyCFunction)ctxGetArgs, METH_VARARGS},
 
298
    {"badOption", (PyCFunction)ctxBadOption, METH_VARARGS},
 
299
    {"readDefaultConfig", (PyCFunction)ctxReadDefaultConfig, METH_VARARGS},
 
300
    {"readConfigFile", (PyCFunction)ctxReadConfigFile, METH_VARARGS},
 
301
    {"setOtherOptionHelp", (PyCFunction)ctxSetOtherOptionHelp, METH_VARARGS},
 
302
    {"printHelp", (PyCFunction)ctxPrintHelp, METH_VARARGS},
 
303
    {"printUsage", (PyCFunction)ctxPrintUsage, METH_VARARGS},
 
304
    /*
 
305
    {"addAlias", (PyCFunction)ctxAddAlias},
 
306
    {"stuffArgs", (PyCFunction)ctxStuffArgs},
 
307
    {"callbackType", (PyCFunction)ctxCallbackType},
 
308
    */
 
309
    {"getOptValues", (PyCFunction)ctxGetOptValues, METH_VARARGS},
 
310
    {"getOptValue", (PyCFunction)ctxGetOptValue, METH_VARARGS},
 
311
    {NULL, NULL}
 
312
};
 
313
 
 
314
static PyObject * ctxGetAttr(poptContextObject *s, char *name)
 
315
{
 
316
    return Py_FindMethod(ctxMethods, (PyObject *)s, name);
 
317
}
 
318
 
 
319
static void ctxDealloc(poptContextObject *self, PyObject *args)
 
320
{
 
321
    if (self->options != NULL) {
 
322
        int i;
 
323
        for (i = 0; i < self->optionsNo; i++) {
 
324
            struct poptOption *o = self->options + i;
 
325
            if (o->argInfo != POPT_ARG_INCLUDE_TABLE && o->arg)
 
326
                free(o->arg);
 
327
        }
 
328
        free(self->options);
 
329
        self->options = NULL;
 
330
    }
 
331
    poptFreeContext(self->ctx);
 
332
    PyMem_DEL(self);
 
333
}
 
334
 
 
335
static PyTypeObject poptContextType = {
 
336
    PyObject_HEAD_INIT(&PyType_Type)
 
337
    0,                                  /* ob_size */
 
338
    "poptContext",                      /* tp_name */
 
339
    sizeof(poptContextObject),          /* tp_basicsize */
 
340
    0,                                  /* tp_itemsize */
 
341
    (destructor)ctxDealloc,             /* tp_dealloc */
 
342
    (printfunc)NULL,                    /* tp_print */
 
343
    (getattrfunc)ctxGetAttr,            /* tp_getattr */
 
344
    (setattrfunc)NULL,                  /* tp_setattr */
 
345
    (cmpfunc)NULL,                      /* tp_compare */
 
346
    (reprfunc)NULL,                     /* tp_repr */
 
347
    NULL,                               /* tp_as_number */
 
348
    NULL,                               /* tp_as_sequence */
 
349
    NULL                                /* tp_as_mapping */
 
350
};
 
351
 
 
352
/* Functions and datatypes needed for the popt module */
 
353
 
 
354
#define AUTOHELP "autohelp"
 
355
static const struct poptOption __autohelp[] = {
 
356
    POPT_AUTOHELP
 
357
    POPT_TABLEEND
 
358
};
 
359
 
 
360
/* Misc functions */
 
361
int __setPoptOption(PyObject *list, struct poptOption *opt)
 
362
{
 
363
    int listSize;
 
364
    PyObject *o;
 
365
    const char *s;
 
366
    int objsize;
 
367
    /* Look for autohelp stuff first */
 
368
    if (PyString_Check(list)) {
 
369
        if (!strcmp(AUTOHELP, PyString_AsString(list))) {
 
370
            /* Autohelp */
 
371
            *opt = __autohelp[0];
 
372
            return 1;
 
373
        }
 
374
        PyErr_SetString(pypoptError, "Expected list or autohelp");
 
375
        return 0;
 
376
    }
 
377
    if (!PyList_Check(list)) {
 
378
        PyErr_SetString(pypoptError, "List expected");
 
379
        return 0;
 
380
    }
 
381
    listSize = PyList_Size(list);
 
382
    if (listSize < 3) {
 
383
        PyErr_SetString(pypoptError, "List is too short");
 
384
        return 0;
 
385
    }
 
386
    
 
387
    /* longName */
 
388
    o = PyList_GetItem(list, 0);
 
389
    /* Sanity check */
 
390
    if (o == Py_None)
 
391
        opt->longName = NULL;
 
392
    else {
 
393
        if (!PyString_Check(o)) {
 
394
            PyErr_SetString(pypoptError, "Long name should be a string");
 
395
            return 0;
 
396
        } 
 
397
        opt->longName = PyString_AsString(o);
 
398
    }
 
399
    
 
400
    /* shortName */
 
401
    o = PyList_GetItem(list, 1);
 
402
    /* Sanity check */
 
403
    if (o == Py_None)
 
404
        opt->shortName = '\0';
 
405
    else {
 
406
        if (!PyString_Check(o)) {
 
407
            PyErr_SetString(pypoptError, "Short name should be a string");
 
408
            return 0;
 
409
        }
 
410
        s = PyString_AsString(o);
 
411
        /* If s is the empty string, we set the short name to '\0', which is
 
412
         * the expected behaviour */
 
413
        opt->shortName = s[0];
 
414
    }
 
415
 
 
416
    /* Make sure they have specified at least one of the long name or short
 
417
     * name; we don't allow for table inclusions and callbacks for now, even
 
418
     * if it would be nice to have them. The table inclusion is broken anyway
 
419
     * unless I find a good way to pass the second table as a reference; I
 
420
     * would normally have to pass it thru the arg field, but I don't pass
 
421
     * that in the python table */
 
422
    if (opt->longName == NULL && opt->shortName == '\0') {
 
423
        PyErr_SetString(pypoptError, "At least one of the short name and long name must be specified");
 
424
        return 0;
 
425
    }
 
426
    
 
427
    /* argInfo */
 
428
    o = PyList_GetItem(list, 2);
 
429
    /* Sanity check */
 
430
    if (!PyInt_Check(o)) {
 
431
        PyErr_SetString(pypoptError, "argInfo is not an int");
 
432
        return 0;
 
433
    }
 
434
    opt->argInfo = PyInt_AsLong(o);
 
435
    
 
436
    /* Initialize the rest of the arguments with safe defaults */
 
437
    switch(opt->argInfo) {
 
438
        case POPT_ARG_STRING:
 
439
            objsize = sizeof(char *);
 
440
            break;
 
441
        case POPT_ARG_DOUBLE:
 
442
            objsize = sizeof(double);
 
443
            break;
 
444
        case POPT_ARG_NONE:
 
445
        case POPT_ARG_VAL:
 
446
            objsize = sizeof(int);
 
447
            break;
 
448
        case POPT_ARG_LONG:
 
449
            objsize = sizeof(long);
 
450
            break;
 
451
        default:
 
452
            PyErr_SetString(pypoptError, "Wrong value for argInfo");
 
453
            return 0;
 
454
    }
 
455
    opt->arg = (void *)malloc(objsize);
 
456
    if (opt->arg == NULL) {
 
457
        PyErr_NoMemory();
 
458
        return 0;
 
459
    }
 
460
    memset(opt->arg, '\0', objsize);
 
461
    opt->val = 0;
 
462
    opt->descrip = NULL;
 
463
    opt->argDescrip = NULL;
 
464
    /* If nothing left, end the stuff here */
 
465
    if (listSize == 3)
 
466
        return 1;
 
467
    
 
468
    /* val */
 
469
    o = PyList_GetItem(list, 3);
 
470
    /* Sanity check */
 
471
    if (o == Py_None)
 
472
        opt->val = 0;
 
473
    else {
 
474
        if (!PyInt_Check(o)) {
 
475
            PyErr_SetString(pypoptError, "Val should be int or None");
 
476
            return 0;
 
477
        }
 
478
        opt->val = PyInt_AsLong(o);
 
479
    }
 
480
    /* If nothing left, end the stuff here */
 
481
    if (listSize == 4)
 
482
        return 1;
 
483
 
 
484
    /* descrip */
 
485
    o = PyList_GetItem(list, 4);
 
486
    /* Sanity check */
 
487
    if (!PyString_Check(o) && o != Py_None) {
 
488
        PyErr_SetString(pypoptError, "Invalid value passed for the description");
 
489
        return 0;
 
490
    }
 
491
    if (o == Py_None)
 
492
        opt->descrip = NULL;
 
493
    else
 
494
        opt->descrip = PyString_AsString(o);
 
495
    /* If nothing left, end the stuff here */
 
496
    if (listSize == 5)
 
497
        return 1;
 
498
 
 
499
    /* argDescrip */
 
500
    o = PyList_GetItem(list, 5);
 
501
    /* Sanity check */
 
502
    if (!PyString_Check(o) && o != Py_None) {
 
503
        PyErr_SetString(pypoptError, "Invalid value passed for the argument description");
 
504
        return 0;
 
505
    }
 
506
    if (o == Py_None)
 
507
        opt->argDescrip = NULL;
 
508
    else
 
509
        opt->argDescrip = PyString_AsString(o);
 
510
    return 1;
 
511
}
 
512
 
 
513
struct poptOption * __getPoptOptions(PyObject *list, int *count)
 
514
{
 
515
    int listSize, item, totalmem;
 
516
    struct poptOption *opts;
 
517
    struct poptOption sentinel = POPT_TABLEEND;
 
518
    if (!PyList_Check(list)) {
 
519
        PyErr_SetString(pypoptError, "List expected");
 
520
        return NULL;
 
521
    }
 
522
    listSize = PyList_Size(list);
 
523
    /* Malloc exactly the size of the list */
 
524
    totalmem = (1 + listSize) * sizeof(struct poptOption);
 
525
    opts = (struct poptOption *)malloc(totalmem);
 
526
    if (opts == NULL) {
 
527
        PyErr_NoMemory();
 
528
        return NULL;
 
529
    }
 
530
    memset(opts, '\0', totalmem);
 
531
    for (item = 0; item < listSize; item++) {
 
532
        int ret;
 
533
        /* Retrieve the item */
 
534
        PyObject *o = PyList_GetItem(list, item);
 
535
        ret = __setPoptOption(o, opts + item);
 
536
        if (ret == 0) {
 
537
            /* Presumably we pass the error from the previous level */
 
538
            return NULL;
 
539
        }
 
540
        //__printPopt(opts + item);
 
541
    }
 
542
    /* Sentinel */
 
543
    opts[listSize] = sentinel;
 
544
    *count = listSize;
 
545
    return opts;
 
546
}
 
547
 
 
548
char ** __getArgv(PyObject *list, int *argc)
 
549
{
 
550
    int listSize, item, totalmem;
 
551
    char **argv;
 
552
    listSize = PyList_Size(list);
 
553
    /* Malloc exactly the size of the list */
 
554
    totalmem = (1 + listSize) * sizeof(char *);
 
555
    argv = (char **)malloc(totalmem);
 
556
    if (argv == NULL) {
 
557
        PyErr_NoMemory();
 
558
        return NULL;
 
559
    }
 
560
    memset(argv, '\0', totalmem);
 
561
    for (item = 0; item < listSize; item++) {
 
562
        /* Retrieve the item */
 
563
        PyObject *o = PyList_GetItem(list, item);
 
564
        if (!PyString_Check(o)) {
 
565
            PyErr_SetString(pypoptError, "Expected a string as value for the argument");
 
566
            return NULL;
 
567
        }
 
568
        argv[item] = PyString_AsString(o);
 
569
        //debug("getArgv", argv[item]);
 
570
    }
 
571
    /* Sentinel */
 
572
    argv[listSize] = NULL;
 
573
    *argc = listSize;
 
574
    return argv;
 
575
}
 
576
 
 
577
 
 
578
static PyObject * getContext(PyObject *self, PyObject *args)
 
579
{
 
580
    const char *name;
 
581
    PyObject *a, *o;
 
582
    char **argv;
 
583
    int argc, count, flags = 0;
 
584
    struct poptOption *opts;
 
585
    poptContextObject *c;
 
586
    /* We should receive name, argv and a list */
 
587
    if (!PyArg_ParseTuple(args, "zO!O!|i", &name, &PyList_Type, &a, 
 
588
        &PyList_Type, &o, &flags))
 
589
        return NULL;
 
590
    /* Parse argv */
 
591
    argv = __getArgv(a, &argc);
 
592
    if (argv == NULL)
 
593
        return NULL;
 
594
    /* Parse argv */
 
595
    /* Parse opts */
 
596
    opts = __getPoptOptions(o, &count);
 
597
    if (opts == NULL)
 
598
        /* Presumably they've set the exception at a previous level */
 
599
        return NULL;
 
600
    /* Parse argv */
 
601
    c = PyObject_NEW(poptContextObject, &poptContextType);
 
602
    c->options = opts;
 
603
    c->optionsNo = count;
 
604
    c->opt = -1;
 
605
    c->ctx = poptGetContext(name, argc, (const char **)argv, opts, flags);
 
606
    return (PyObject *)c;
 
607
}
 
608
 
 
609
struct _pyIntConstant {
 
610
    char *name;
 
611
    const int value;
 
612
};
 
613
 
 
614
static PyObject * _strerror(PyObject *self, PyObject *args)
 
615
{
 
616
    int error;
 
617
    if (!PyArg_ParseTuple(args, "i", &error)) {
 
618
        return NULL;
 
619
    }
 
620
    return PyString_FromString(poptStrerror(error));
 
621
}
 
622
 
 
623
/* Methods for the popt module */
 
624
static struct PyMethodDef poptModuleMethods[] = {
 
625
    {"getContext", (PyCFunction)getContext, METH_VARARGS, NULL},
 
626
    {"strerror", (PyCFunction)_strerror, METH_VARARGS, NULL},
 
627
    {NULL, NULL}
 
628
};
 
629
 
 
630
#define ADD_INT(NAME) {#NAME, NAME}
 
631
static const struct _pyIntConstant intConstants[] = {
 
632
    /* Arg info */
 
633
    ADD_INT(POPT_ARG_NONE),
 
634
    ADD_INT(POPT_ARG_STRING),
 
635
    {"POPT_ARG_INT", POPT_ARG_LONG},
 
636
    ADD_INT(POPT_ARG_VAL),
 
637
    {"POPT_ARG_FLOAT", POPT_ARG_DOUBLE},
 
638
 
 
639
    ADD_INT(POPT_ARGFLAG_OR),
 
640
    ADD_INT(POPT_ARGFLAG_AND),
 
641
    ADD_INT(POPT_ARGFLAG_XOR),
 
642
    ADD_INT(POPT_ARGFLAG_NOT),
 
643
    ADD_INT(POPT_ARGFLAG_ONEDASH),
 
644
    ADD_INT(POPT_ARGFLAG_DOC_HIDDEN),
 
645
    ADD_INT(POPT_ARGFLAG_OPTIONAL),
 
646
    /* Context flags*/
 
647
    ADD_INT(POPT_CONTEXT_NO_EXEC),
 
648
    ADD_INT(POPT_CONTEXT_KEEP_FIRST),
 
649
    ADD_INT(POPT_CONTEXT_POSIXMEHARDER),
 
650
    /* Errors */
 
651
    ADD_INT(POPT_ERROR_NOARG),
 
652
    ADD_INT(POPT_ERROR_BADOPT),
 
653
    ADD_INT(POPT_ERROR_OPTSTOODEEP),
 
654
    ADD_INT(POPT_ERROR_BADQUOTE),
 
655
    ADD_INT(POPT_ERROR_BADNUMBER),
 
656
    ADD_INT(POPT_ERROR_OVERFLOW),
 
657
    ADD_INT(POPT_ERROR_ERRNO),
 
658
    /* Misc */
 
659
    ADD_INT(POPT_BADOPTION_NOALIAS),
 
660
    {NULL}
 
661
};
 
662
 
 
663
void initpopt()
 
664
{
 
665
    PyObject *dict, *module;
 
666
    const struct _pyIntConstant *c;
 
667
    module = Py_InitModule3("popt", poptModuleMethods, module_doc);
 
668
    /* Init the constants */
 
669
    dict = PyModule_GetDict(module);
 
670
    PyDict_SetItemString(dict, "__version__", 
 
671
        PyString_FromString(PY_POPT_VERSION));
 
672
    PyDict_SetItemString(dict, "cvsid", PyString_FromString(rcs_id));
 
673
    for (c = intConstants; c->name; c++) {
 
674
        PyObject *val = PyInt_FromLong(c->value);
 
675
        PyDict_SetItemString(dict, c->name, val);
 
676
        Py_DECREF(val);
 
677
    }
 
678
    /* Add the autohelp stuff */
 
679
    {
 
680
        PyObject *val = PyString_FromString(AUTOHELP);
 
681
        PyDict_SetItemString(dict, "POPT_AUTOHELP", val);
 
682
        Py_DECREF(val);
 
683
    }
 
684
    /* The exception */
 
685
    pypoptError = PyErr_NewException("popt.error", NULL, NULL);
 
686
    PyDict_SetItemString(dict, "error", pypoptError);
 
687
}
 
688