~fluidity-core/fluidity/adjoint

« back to all changes in this revision

Viewing changes to libspud/python/libspud.c

Merge the fluidity_revolve branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#include <Python.h>
2
 
#include <string.h>
3
 
#include "spud.h"
4
 
#include <stdio.h>
5
 
 
6
 
#define MAXLENGTH   2048
7
 
 
8
 
static PyObject *SpudError;
9
 
static PyObject *SpudTypeError;
10
 
static PyObject *SpudKeyError;
11
 
static PyObject *SpudFileError;
12
 
static PyObject *SpudNewKeyWarning;
13
 
static PyObject *SpudAttrSetFailedWarning;
14
 
static PyObject *SpudShapeError;
15
 
static PyObject *SpudRankError;
16
 
 
17
 
void* manager;
18
 
 
19
 
static PyObject *
20
 
error_checking(int outcome, char *functionname)
21
 
{
22
 
    char errormessage [MAXLENGTH];
23
 
 
24
 
    if (outcome == SPUD_KEY_ERROR){
25
 
        snprintf(errormessage, MAXLENGTH, "Error: The specified option is not present \
26
 
                        in the dictionary in %s", functionname);
27
 
        PyErr_SetString(SpudKeyError, errormessage);
28
 
        return NULL;
29
 
    }
30
 
    if (outcome == SPUD_TYPE_ERROR){
31
 
        snprintf(errormessage, MAXLENGTH, "Error: The specified option has a different \
32
 
                        type from that of the option argument provided in %s", functionname);
33
 
        PyErr_SetString(SpudTypeError, errormessage);
34
 
        return NULL;
35
 
    }
36
 
    if (outcome == SPUD_NEW_KEY_WARNING){
37
 
        snprintf(errormessage, MAXLENGTH, "Warning: The option being inserted is not ]  \
38
 
                        already in the dictionary %s", functionname);
39
 
        PyErr_SetString(SpudNewKeyWarning, errormessage);
40
 
        return NULL;
41
 
    }
42
 
    if (outcome == SPUD_FILE_ERROR){
43
 
        snprintf(errormessage, MAXLENGTH, "Error: The specified options file cannot be  \
44
 
                        read or written to as the routine requires in %s", functionname);
45
 
        PyErr_SetString(SpudFileError, errormessage);
46
 
        return NULL;
47
 
    }
48
 
    if (outcome == SPUD_RANK_ERROR){
49
 
        snprintf(errormessage, MAXLENGTH, "Error: The specified option has a different rank from \
50
 
                      that of the option argument provided %s", functionname);
51
 
        PyErr_SetString(SpudRankError, errormessage);
52
 
        return NULL;
53
 
    }
54
 
    if (outcome == SPUD_SHAPE_ERROR){
55
 
        snprintf(errormessage, MAXLENGTH, "Error: The specified option has a different shape from \
56
 
                      that of the option argument provided in %s", functionname);
57
 
        PyErr_SetString(SpudShapeError, errormessage);
58
 
        return NULL;
59
 
    }
60
 
    if (outcome == SPUD_ATTR_SET_FAILED_WARNING){
61
 
        snprintf(errormessage, MAXLENGTH, "Warning: The option being set as an attribute can not be \
62
 
                      set as an attribute in %s", functionname);
63
 
        PyErr_SetString(SpudAttrSetFailedWarning, errormessage);
64
 
        return NULL;
65
 
    }
66
 
    if (outcome == SPUD_NO_ERROR){
67
 
        Py_RETURN_NONE;
68
 
    }
69
 
 
70
 
    PyErr_SetString(SpudError,"Error: error checking failed.");
71
 
    return NULL;
72
 
}
73
 
 
74
 
static PyObject *
75
 
libspud_load_options(PyObject *self, PyObject *args)
76
 
{
77
 
    const char *key;
78
 
    int key_len;
79
 
    int outcomeLoadOptions;
80
 
 
81
 
    if (!PyArg_ParseTuple(args, "s", &key))
82
 
        return NULL;
83
 
    key_len = strlen(key);
84
 
    outcomeLoadOptions = spud_load_options(key,key_len);
85
 
 
86
 
    return error_checking(outcomeLoadOptions, "load options");
87
 
}
88
 
 
89
 
static PyObject*
90
 
libspud_print_options(PyObject *self, PyObject *args)
91
 
{
92
 
    spud_print_options();
93
 
 
94
 
    Py_RETURN_NONE;
95
 
}
96
 
 
97
 
static PyObject*
98
 
libspud_clear_options(PyObject *self, PyObject *args)
99
 
{
100
 
    spud_clear_options();
101
 
 
102
 
    Py_RETURN_NONE;
103
 
}
104
 
 
105
 
static PyObject *
106
 
libspud_get_number_of_children(PyObject *self, PyObject *args)
107
 
{
108
 
    const char *key;
109
 
    int key_len;
110
 
    int child_count;
111
 
    int outcomeGetNumChildren;
112
 
 
113
 
    if (!PyArg_ParseTuple(args, "s", &key))
114
 
        return NULL;
115
 
    key_len = strlen(key);
116
 
    outcomeGetNumChildren = spud_get_number_of_children(key, key_len, &child_count);
117
 
    if (error_checking(outcomeGetNumChildren, "get number of children") == NULL){
118
 
        return NULL;
119
 
    }
120
 
 
121
 
    return Py_BuildValue("i", child_count);
122
 
}
123
 
 
124
 
static PyObject *
125
 
libspud_get_child_name(PyObject *self, PyObject *args)
126
 
{
127
 
    const char *key;
128
 
    int key_len;
129
 
    int index;
130
 
    char child_name [MAXLENGTH];
131
 
    int i;
132
 
    int outcomeGetChildName;
133
 
 
134
 
    for (i = 0; i < MAXLENGTH; i++){
135
 
        child_name[i] = '\0';
136
 
    }
137
 
    if (!PyArg_ParseTuple(args, "si", &key, &index)){
138
 
        return NULL;
139
 
    }
140
 
    key_len = strlen(key);
141
 
    outcomeGetChildName = spud_get_child_name(key, key_len, index, child_name, MAXLENGTH);
142
 
    if (error_checking(outcomeGetChildName, "get child name") == NULL){
143
 
        return NULL;
144
 
    }
145
 
 
146
 
    return Py_BuildValue("s", child_name);
147
 
}
148
 
 
149
 
static PyObject *
150
 
libspud_option_count(PyObject *self, PyObject *args)
151
 
{
152
 
    const char *key;
153
 
    int key_len;
154
 
    int numoptions;
155
 
 
156
 
    if (!PyArg_ParseTuple(args, "s", &key)){
157
 
        return NULL;
158
 
    }
159
 
    key_len = strlen(key);
160
 
    numoptions = spud_option_count(key, key_len);
161
 
 
162
 
    return Py_BuildValue("i", numoptions);
163
 
}
164
 
 
165
 
static PyObject *
166
 
libspud_have_option(PyObject *self, PyObject *args)
167
 
{
168
 
    const char *key;
169
 
    int key_len;
170
 
    int haveoption;
171
 
 
172
 
    if (!PyArg_ParseTuple(args, "s", &key)){
173
 
        return NULL;
174
 
    }
175
 
    key_len = strlen(key);
176
 
    haveoption = spud_have_option(key, key_len);
177
 
 
178
 
    if (haveoption == 0){
179
 
        Py_RETURN_FALSE;
180
 
    }
181
 
    else{
182
 
        Py_RETURN_TRUE;
183
 
    }
184
 
}
185
 
 
186
 
static PyObject *
187
 
libspud_add_option(PyObject *self, PyObject *args)
188
 
{
189
 
    const char *key;
190
 
    int key_len;
191
 
    int outcomeAddOption;
192
 
 
193
 
    if (!PyArg_ParseTuple(args, "s", &key)){
194
 
        return NULL;
195
 
    }
196
 
    key_len = strlen(key);
197
 
    outcomeAddOption = spud_add_option(key, key_len);
198
 
    return error_checking(outcomeAddOption, "add option");
199
 
 
200
 
}
201
 
 
202
 
static PyObject *
203
 
libspud_get_option_type(PyObject *self, PyObject *args)
204
 
{
205
 
    const char *key;
206
 
    int key_len;
207
 
    int type;
208
 
    int outcomeGetOptionType;
209
 
 
210
 
    if (!PyArg_ParseTuple(args, "s", &key)){
211
 
        return NULL;
212
 
    }
213
 
    key_len = strlen(key);
214
 
    outcomeGetOptionType = spud_get_option_type(key, key_len, &type);
215
 
    if (error_checking(outcomeGetOptionType, "get option type") == NULL){
216
 
        return NULL;
217
 
    }
218
 
    if (type == SPUD_DOUBLE){
219
 
        Py_INCREF(&PyFloat_Type);
220
 
        return (PyObject*) &PyFloat_Type;
221
 
    }
222
 
    else if (type == SPUD_INT){
223
 
        Py_INCREF(&PyInt_Type);
224
 
        return (PyObject*) &PyInt_Type;
225
 
    }
226
 
    else if (type == SPUD_NONE){
227
 
        Py_RETURN_NONE;
228
 
    }
229
 
    else if (type == SPUD_STRING){
230
 
        Py_INCREF(&PyString_Type);
231
 
        return (PyObject*) &PyString_Type;
232
 
    }
233
 
 
234
 
    PyErr_SetString(SpudError,"Error: Get option type function failed");
235
 
    return NULL;
236
 
}
237
 
 
238
 
static PyObject *
239
 
libspud_get_option_rank(PyObject *self, PyObject *args)
240
 
{
241
 
    const char *key;
242
 
    int key_len;
243
 
    int rank;
244
 
    int outcomeGetOptionRank;
245
 
 
246
 
    if (!PyArg_ParseTuple(args, "s", &key)){
247
 
        return NULL;
248
 
    }
249
 
    key_len = strlen(key);
250
 
    outcomeGetOptionRank = spud_get_option_rank(key, key_len, &rank);
251
 
    if (error_checking(outcomeGetOptionRank, "get option rank") == NULL){
252
 
        return NULL;
253
 
    }
254
 
 
255
 
    return Py_BuildValue("i", rank);
256
 
}
257
 
 
258
 
static PyObject *
259
 
libspud_get_option_shape(PyObject *self, PyObject *args)
260
 
{
261
 
    const char *key;
262
 
    int key_len;
263
 
    int shape[2];
264
 
    int outcomeGetOptionShape;
265
 
 
266
 
    if (!PyArg_ParseTuple(args, "s", &key)){
267
 
        return NULL;
268
 
    }
269
 
    key_len = strlen(key);
270
 
    outcomeGetOptionShape = spud_get_option_shape(key, key_len, shape);
271
 
    if (error_checking(outcomeGetOptionShape, "get option shape") == NULL){
272
 
        return NULL;
273
 
    }
274
 
 
275
 
    return Py_BuildValue("(i,i)", shape[0],shape[1]);
276
 
}
277
 
 
278
 
static PyObject*
279
 
spud_get_option_aux_list_ints(const char *key, int key_len, int type, int rank, int *shape)
280
 
{   // this function is for getting option when the option is of type a list of ints
281
 
    int outcomeGetOption;
282
 
    int size = shape[0];
283
 
    int val [size];
284
 
    int j;
285
 
 
286
 
    outcomeGetOption = spud_get_option(key, key_len, val);
287
 
    if (error_checking(outcomeGetOption, "get option aux list") == NULL){
288
 
        return NULL;
289
 
    }
290
 
    PyObject* pylist = PyList_New(size);
291
 
    if (pylist == NULL){
292
 
        printf("New list error.");
293
 
        return NULL;
294
 
    }
295
 
    for (j = 0; j < size; j++){
296
 
        PyObject* element = Py_BuildValue("i", val[j]);
297
 
        PyList_SetItem(pylist, j, element);
298
 
    }
299
 
 
300
 
    return pylist;
301
 
}
302
 
 
303
 
static PyObject*
304
 
spud_get_option_aux_list_doubles(const char *key, int key_len, int type, int rank, int *shape)
305
 
{   // this function is for getting option when the option is of type a list of doubles
306
 
    int outcomeGetOption;
307
 
    int size = shape[0];
308
 
    double val [size];
309
 
    int j;
310
 
 
311
 
    outcomeGetOption = spud_get_option(key, key_len, val);
312
 
    if (error_checking(outcomeGetOption, "get option aux list") == NULL){
313
 
        return NULL;
314
 
    }
315
 
    PyObject* pylist = PyList_New(size);
316
 
    if (pylist == NULL){
317
 
        printf("New list error.");
318
 
        return NULL;
319
 
    }
320
 
    for (j = 0; j < size; j++){
321
 
        PyObject* element = Py_BuildValue("f", val[j]);
322
 
        PyList_SetItem(pylist, j, element);
323
 
    }
324
 
 
325
 
    return pylist;
326
 
}
327
 
 
328
 
static PyObject *
329
 
spud_get_option_aux_scalar_or_string(const char *key, int key_len, int type, int rank, int *shape)
330
 
{   // this function is for getting option when the option is of type a scalar or string
331
 
    int outcomeGetOption;
332
 
    if (type == SPUD_DOUBLE){
333
 
        double val;
334
 
        outcomeGetOption = spud_get_option(key, key_len, &val);
335
 
        if (error_checking(outcomeGetOption, "get option aux scalar or string") == NULL){
336
 
            return NULL;
337
 
        }
338
 
        return Py_BuildValue("d", val);
339
 
    }
340
 
    else if (type == SPUD_INT){
341
 
        int val;
342
 
        outcomeGetOption = spud_get_option(key, key_len, &val);
343
 
        if (error_checking(outcomeGetOption, "get option aux scalar or string") == NULL){
344
 
            return NULL;
345
 
        }
346
 
        return Py_BuildValue("i", val);
347
 
    }
348
 
    else if (type == SPUD_STRING) {
349
 
        int size = shape[0];
350
 
        char val[size+1];
351
 
        int i;
352
 
        for (i = 0; i < size+1; i++)
353
 
          val[i] = '\0';
354
 
          
355
 
        outcomeGetOption = spud_get_option(key, key_len, val);
356
 
        if (error_checking(outcomeGetOption, "get option aux scalar or string") == NULL){
357
 
            return NULL;
358
 
        }
359
 
        return Py_BuildValue("s", val);
360
 
    }
361
 
 
362
 
    PyErr_SetString(SpudError,"Error: Get option aux scalar failed");
363
 
    return NULL;
364
 
}
365
 
 
366
 
static PyObject*
367
 
spud_get_option_aux_tensor_doubles(const char *key, int key_len, int type, int rank, int *shape)
368
 
{   // this function is for getting option when the option is of type a tensor o doubles
369
 
    int outcomeGetOption;
370
 
    int rowsize = shape[0];
371
 
    int colsize = shape[1];
372
 
    int size = rowsize*colsize;
373
 
    double val [size];
374
 
    int m;
375
 
    int n;
376
 
    int counter;
377
 
 
378
 
    outcomeGetOption = spud_get_option(key, key_len, val);
379
 
    if (error_checking(outcomeGetOption, "get option aux tensor") == NULL){
380
 
        return NULL;
381
 
    }
382
 
    PyObject* pylist = PyList_New(rowsize);
383
 
    if (pylist == NULL){
384
 
        printf("New list error");
385
 
        return NULL;
386
 
    }
387
 
    counter = 0;
388
 
    for (m = 0; m < rowsize; m++){
389
 
        PyObject* pysublist = PyList_New(colsize);
390
 
        if (pysublist == NULL){
391
 
            printf("New sublist error");
392
 
            return NULL;
393
 
        }
394
 
        for (n = 0; n < colsize; n++){
395
 
            PyObject* element = Py_BuildValue("d", val[counter]);
396
 
            PyList_SetItem(pysublist, n, element);
397
 
            counter++;
398
 
        }
399
 
        PyList_SetItem(pylist, m, pysublist);
400
 
    }
401
 
 
402
 
    return pylist;
403
 
}
404
 
 
405
 
static PyObject*
406
 
spud_get_option_aux_tensor_ints(const char *key, int key_len, int type, int rank, int *shape)
407
 
{   // this function is for getting option when the option is of type a tensor of ints
408
 
    int outcomeGetOption;
409
 
    int rowsize = shape[0];
410
 
    int colsize = shape[1];
411
 
    int size = rowsize*colsize;
412
 
    int val [size];
413
 
    int m;
414
 
    int n;
415
 
    int counter;
416
 
 
417
 
    outcomeGetOption = spud_get_option(key, key_len, val);
418
 
    if (error_checking(outcomeGetOption, "get option aux tensor") == NULL){
419
 
        return NULL;
420
 
    }
421
 
    PyObject* pylist = PyList_New(rowsize);
422
 
    if (pylist == NULL){
423
 
        printf("New list error");
424
 
        return NULL;
425
 
    }
426
 
    counter = 0;
427
 
    for (m = 0; m < rowsize; m++){
428
 
        PyObject* pysublist = PyList_New(colsize);
429
 
        if (pysublist == NULL){
430
 
            printf("New sublist error");
431
 
            return NULL;
432
 
        }
433
 
        for (n = 0; n < colsize; n++){
434
 
            PyObject* element = Py_BuildValue("i", val[counter]);
435
 
            PyList_SetItem(pysublist, n, element);
436
 
            counter++;
437
 
        }
438
 
        PyList_SetItem(pylist, m, pysublist);
439
 
    }
440
 
 
441
 
    return pylist;
442
 
}
443
 
 
444
 
static PyObject *
445
 
libspud_get_option(PyObject *self, PyObject *args)
446
 
{
447
 
    const char *key;
448
 
    int key_len;
449
 
    int type;
450
 
    int rank = 0;
451
 
    int shape[2];
452
 
    int outcomeGetOptionType;
453
 
    int outcomeGetOptionRank;
454
 
    int outcomeGetOptionShape;
455
 
 
456
 
    if(!PyArg_ParseTuple(args, "s", &key)){
457
 
        return NULL;
458
 
    }
459
 
    key_len = strlen(key);
460
 
    outcomeGetOptionRank = spud_get_option_rank(key, key_len, &rank);
461
 
    if (error_checking(outcomeGetOptionRank, "get option") == NULL){
462
 
        return NULL;
463
 
    }
464
 
    outcomeGetOptionType = spud_get_option_type(key, key_len, &type);
465
 
    if (error_checking(outcomeGetOptionType, "get option") == NULL){
466
 
        return NULL;
467
 
    }
468
 
    outcomeGetOptionShape = spud_get_option_shape(key, key_len, shape);
469
 
    if (error_checking(outcomeGetOptionShape, "get option") == NULL){
470
 
        return NULL;
471
 
    }
472
 
    
473
 
    if (rank == -1){ // type error
474
 
        char errormessage [MAXLENGTH];
475
 
        snprintf(errormessage, MAXLENGTH, "Error: The specified option has a different \
476
 
                        type from that of the option argument provided in %s", "get option");
477
 
        PyErr_SetString(SpudTypeError, errormessage);
478
 
        return NULL;
479
 
    }
480
 
    else if (rank == 0){ // scalar
481
 
        return spud_get_option_aux_scalar_or_string(key, key_len, type, rank, shape);
482
 
    }
483
 
    else if (rank == 1){ // list or string
484
 
        if (type == SPUD_INT){  //a list of ints
485
 
            return spud_get_option_aux_list_ints(key, key_len, type, rank, shape);
486
 
        }
487
 
        else if (type == SPUD_DOUBLE){  //a list of doubles
488
 
            return spud_get_option_aux_list_doubles(key, key_len, type, rank, shape);
489
 
        }
490
 
        else if (type == SPUD_STRING){  //string
491
 
            return spud_get_option_aux_scalar_or_string(key, key_len, type, rank, shape);
492
 
        }
493
 
    }
494
 
    else if (rank == 2){ // tensor
495
 
        if (type == SPUD_DOUBLE){  //a tensor of doubles
496
 
            return spud_get_option_aux_tensor_doubles(key, key_len, type, rank, shape);
497
 
        }
498
 
        else if (type == SPUD_INT){  //a tensor of ints
499
 
            return spud_get_option_aux_tensor_ints(key, key_len, type, rank, shape);
500
 
        } 
501
 
    }
502
 
 
503
 
    PyErr_SetString(SpudError,"Error: Get option failed.");
504
 
    return NULL;
505
 
}
506
 
static PyObject*
507
 
set_option_aux_list_ints(PyObject *pylist, const char *key, int key_len, int type, int rank, int *shape)
508
 
{   // this function is for setting option when the second argument is of type a list of ints
509
 
    int j;
510
 
    int psize = PyList_Size(pylist);
511
 
    shape[0] = psize;
512
 
    int val[psize] ;
513
 
    int outcomeSetOption;
514
 
    int element;
515
 
 
516
 
    for (j = 0; j < psize; j++){
517
 
        element = -1;
518
 
        PyObject* pelement = PyList_GetItem(pylist, j);
519
 
        PyArg_Parse(pelement, "i", &element);
520
 
        val[j] = element;
521
 
    }
522
 
    outcomeSetOption = spud_set_option(key, key_len, val, type, rank, shape);
523
 
    if (error_checking(outcomeSetOption, "set option aux list ints") == NULL){
524
 
        return NULL;
525
 
    }
526
 
    Py_RETURN_NONE;
527
 
}
528
 
 
529
 
static PyObject*
530
 
set_option_aux_list_doubles(PyObject *pylist, const char *key, int key_len, int type, int rank, int *shape)
531
 
{   // this function is for setting option when the second argument is of type a list of doubles
532
 
    int j;
533
 
    int psize = PyList_Size(pylist);
534
 
    shape[0] = psize;
535
 
    double val [psize];
536
 
    int outcomeSetOption;
537
 
    double element;
538
 
 
539
 
    for (j = 0; j < psize; j++){
540
 
        element = -1.0;
541
 
        PyObject* pelement = PyList_GetItem(pylist, j);
542
 
        element = PyFloat_AS_DOUBLE(pelement);
543
 
        val[j] = element;
544
 
    }
545
 
    outcomeSetOption = spud_set_option(key, key_len, val, type, rank, shape);
546
 
    if (error_checking(outcomeSetOption, "set option aux list ints") == NULL){
547
 
        return NULL;
548
 
    }
549
 
 
550
 
    Py_RETURN_NONE;
551
 
}
552
 
 
553
 
static PyObject*
554
 
set_option_aux_string(PyObject *pystring, const char *key, int key_len, int type, int rank, int *shape)
555
 
{   // this function is for setting option when the second argument is of type string
556
 
    char *val = PyString_AsString(pystring);
557
 
    int outcomeSetOption = spud_set_option(key, key_len, val, type, rank, shape);
558
 
    return error_checking(outcomeSetOption, "set option aux string");
559
 
}
560
 
 
561
 
static PyObject*
562
 
libspud_set_option_attribute(PyObject *self, PyObject *args)
563
 
{
564
 
    const char*key;
565
 
    int key_len;
566
 
    PyObject* firstArg;
567
 
    PyObject* secondArg;
568
 
    const char*val;
569
 
    int val_len;
570
 
    int outcomeSetOption;
571
 
 
572
 
    firstArg = PyTuple_GetItem(args, 0);
573
 
    secondArg = PyTuple_GetItem(args, 1);
574
 
    PyArg_Parse(firstArg, "s", &key);
575
 
    key_len = strlen(key);
576
 
    PyArg_Parse(secondArg, "s", &val);
577
 
    val_len = strlen(val);
578
 
    outcomeSetOption = spud_set_option_attribute(key, key_len, val, val_len);
579
 
    return error_checking(outcomeSetOption, "set option attribute");
580
 
}
581
 
 
582
 
static PyObject*
583
 
libspud_delete_option(PyObject *self, PyObject *args)
584
 
{
585
 
    const char*key;
586
 
    int key_len;
587
 
    PyObject* firstArg;
588
 
    int outcomeDeleteOption;
589
 
 
590
 
    firstArg = PyTuple_GetItem(args, 0);
591
 
    PyArg_Parse(firstArg, "s", &key);
592
 
    key_len = strlen(key);
593
 
    outcomeDeleteOption = spud_delete_option(key, key_len);
594
 
    return error_checking(outcomeDeleteOption, "delete option");
595
 
}
596
 
 
597
 
static PyObject*
598
 
set_option_aux_tensor_doubles(PyObject *pylist, const char *key, int key_len, int type, int rank, int *shape)
599
 
{   // this function is for setting option when the second argument is of type a tensor of doubles
600
 
    int i;
601
 
    int j;
602
 
    int counter = 0;
603
 
 
604
 
    int outcomeSetOption;
605
 
 
606
 
    int size = shape[0]*shape[1];
607
 
    
608
 
    double element;
609
 
    double val [size];
610
 
    
611
 
    for (i = 0; i < shape[0]; i++){
612
 
        PyObject* pysublist = PyList_GetItem(pylist, i);
613
 
        for (j = 0; j < shape[1]; j++){
614
 
            PyObject* pysublistElement = PyList_GetItem(pysublist, j);
615
 
            element = PyFloat_AS_DOUBLE(pysublistElement);
616
 
            val[counter] = (double) element;
617
 
            counter ++;
618
 
        }
619
 
    }
620
 
 
621
 
    outcomeSetOption = spud_set_option(key, key_len, val, type, rank, shape);
622
 
    return error_checking(outcomeSetOption, "set option aux tensor doubles");
623
 
}
624
 
 
625
 
static PyObject*
626
 
set_option_aux_tensor_ints(PyObject *pylist, const char *key, int key_len, int type, int rank, int *shape)
627
 
{   // this function is for setting option when the second argument is of type a tensor of ints
628
 
    int i;
629
 
    int j;
630
 
    int counter = 0;
631
 
    int size = shape[0]*shape[1];
632
 
    int val [size];
633
 
    int outcomeSetOption;
634
 
 
635
 
    int element;
636
 
 
637
 
    for (i = 0; i < shape[0]; i++){
638
 
        PyObject* pysublist = PyList_GetItem(pylist, i);
639
 
        for (j = 0; j < shape[1]; j++){
640
 
            element = 1;
641
 
            PyObject* pysublistElement = PyList_GetItem(pysublist, j);
642
 
            PyArg_Parse(pysublistElement, "i", &element);
643
 
            val[counter] = element;
644
 
            counter ++;
645
 
        }
646
 
    }
647
 
 
648
 
    outcomeSetOption = spud_set_option(key, key_len, val, type, rank, shape);
649
 
    return error_checking(outcomeSetOption, "set option aux tensor ints");
650
 
}
651
 
 
652
 
static PyObject*
653
 
set_option_aux_scalar(PyObject *pyscalar, const char *key, int key_len, int type, int rank, int *shape)
654
 
{   // this function is for setting option when the second argument is of type scalar
655
 
    int outcomeSetOption = SPUD_NO_ERROR;
656
 
 
657
 
    if (type == SPUD_DOUBLE){ //scalar is double
658
 
        double val;
659
 
        PyArg_Parse(pyscalar, "f", &val);
660
 
        outcomeSetOption = spud_set_option(key, key_len, &val, type, rank, shape);
661
 
    }
662
 
    else if (type == SPUD_INT){
663
 
        int val;
664
 
        PyArg_Parse(pyscalar, "i", &val);
665
 
        outcomeSetOption = spud_set_option(key, key_len, &val, type, rank, shape);
666
 
    }
667
 
 
668
 
    return error_checking(outcomeSetOption, "set option aux scalar");
669
 
}
670
 
 
671
 
 
672
 
static PyObject*
673
 
libspud_set_option(PyObject *self, PyObject *args)
674
 
{
675
 
    const char *key;
676
 
    int key_len;
677
 
    int type=-1;
678
 
    int rank=-1;
679
 
    int shape[2];
680
 
    PyObject* firstArg;
681
 
    PyObject* secondArg;
682
 
    
683
 
    if(PyTuple_GET_SIZE(args)!=2){
684
 
        PyErr_SetString(SpudError,"Error: set_option takes exactly 2 arguments.");
685
 
        return NULL;
686
 
    }
687
 
 
688
 
    firstArg = PyTuple_GetItem(args, 0);
689
 
    secondArg = PyTuple_GetItem(args, 1);
690
 
    PyArg_Parse(firstArg, "s", &key);
691
 
    key_len = strlen(key);
692
 
    
693
 
    if (!spud_have_option(key, key_len)){ //option does not exist yet
694
 
        int outcomeAddOption = spud_add_option(key, key_len);
695
 
        error_checking(outcomeAddOption, "set option");
696
 
    } 
697
 
    
698
 
    if (PyInt_Check(secondArg)){ //just an int
699
 
        type = SPUD_INT;
700
 
        rank = 0;
701
 
        shape[0] = -1;
702
 
        shape[1] = -1;
703
 
            
704
 
    }       
705
 
    else if (PyString_Check(secondArg)){// a string
706
 
        type = SPUD_STRING;
707
 
        rank = 1;
708
 
        shape[0] = PyString_GET_SIZE(secondArg);
709
 
        shape[1] = -1;
710
 
    }
711
 
    else if (PyFloat_Check(secondArg)){// a double
712
 
        type = SPUD_DOUBLE;
713
 
        rank = 0;
714
 
        shape[0] = -1;
715
 
        shape[1] = -1;
716
 
    }
717
 
    else if (PyList_Check(secondArg)){
718
 
        PyObject* listElement = PyList_GetItem(secondArg, 0);
719
 
        if (PyInt_Check(listElement)){ //list of ints
720
 
            type = SPUD_INT;
721
 
            rank = 1;
722
 
            shape[0] = 1;
723
 
            shape[1] = -1;
724
 
        }
725
 
        else if (PyFloat_Check(listElement)){
726
 
            type = SPUD_DOUBLE; //list of doubles
727
 
            rank = 1;
728
 
            shape[0] = 1;
729
 
            shape[1] = -1;
730
 
        }
731
 
        else if (PyList_Check(listElement)){ //list of lists
732
 
            int pylistSize = PyList_GET_SIZE(secondArg);
733
 
            int pysublistSize = PyList_GET_SIZE(listElement);
734
 
            PyObject* sublistElement = PyList_GetItem(listElement, 0);
735
 
            if (PyInt_Check(sublistElement)){ //list of lists of ints
736
 
                type = SPUD_INT;
737
 
            }
738
 
            else if (PyFloat_Check(sublistElement)){//list of lists of doubles
739
 
                type = SPUD_DOUBLE;
740
 
            }            
741
 
            rank = 2;
742
 
            shape[0] = pylistSize;
743
 
            shape[1] = pysublistSize;
744
 
        }
745
 
    }
746
 
    
747
 
    if (rank == 0){ // scalar
748
 
        set_option_aux_scalar(secondArg, key, key_len, type, rank, shape);
749
 
    }
750
 
    else if (rank == 1){ // list or string
751
 
        if (PyString_Check(secondArg)){ // pystring
752
 
            set_option_aux_string(secondArg, key, key_len, type, rank, shape);
753
 
        }
754
 
        else if (type == SPUD_INT) { // list of ints
755
 
            set_option_aux_list_ints(secondArg, key, key_len, type, rank, shape);
756
 
        }    
757
 
        else if (type == SPUD_DOUBLE){ // list of doubles
758
 
            set_option_aux_list_doubles(secondArg, key, key_len, type, rank, shape);
759
 
        } 
760
 
    }
761
 
    else if (rank == 2){ // tensor
762
 
        if (type == SPUD_DOUBLE) { // tensor of doubles
763
 
            set_option_aux_tensor_doubles(secondArg, key, key_len, type, rank, shape);
764
 
        }
765
 
        else if (type == SPUD_INT) { // tensor of ints
766
 
            set_option_aux_tensor_ints(secondArg, key, key_len, type, rank, shape);
767
 
        }
768
 
    }
769
 
 
770
 
    Py_RETURN_NONE;
771
 
}
772
 
 
773
 
static PyObject*
774
 
libspud_write_options(PyObject *self, PyObject *args)
775
 
{
776
 
    PyObject* firstArg;
777
 
    char *filename;
778
 
    int filename_len;
779
 
    int outcomeWriteOptions;
780
 
 
781
 
    firstArg = PyTuple_GetItem(args, 0);
782
 
    PyArg_Parse(firstArg, "s", &filename);
783
 
    filename_len = strlen(filename);
784
 
    outcomeWriteOptions = spud_write_options (filename, filename_len);
785
 
    return error_checking(outcomeWriteOptions, "write options");
786
 
}
787
 
 
788
 
static PyMethodDef libspudMethods[] = {
789
 
    {"load_options",  libspud_load_options, METH_VARARGS,
790
 
     PyDoc_STR("Reads the xml file into the options tree.")},
791
 
    {"print_options",  libspud_print_options, METH_VARARGS,
792
 
     PyDoc_STR("Print the entire options tree to standard output.")},
793
 
    {"clear_options",  libspud_clear_options, METH_VARARGS,
794
 
     PyDoc_STR("Clears the entire options tree.")},
795
 
    {"get_number_of_children",  libspud_get_number_of_children, METH_VARARGS,
796
 
     PyDoc_STR("get number of children under key.")},
797
 
    {"get_child_name",  libspud_get_child_name, METH_VARARGS,
798
 
     PyDoc_STR("Get name of the indexth child of key.")},
799
 
    {"option_count",  libspud_option_count, METH_VARARGS,
800
 
     PyDoc_STR("Return the number of options matching key.")},
801
 
    {"have_option",  libspud_have_option, METH_VARARGS,
802
 
     PyDoc_STR("Checks whether key is present in options dictionary.")},
803
 
    {"get_option_type",  libspud_get_option_type, METH_VARARGS,
804
 
     PyDoc_STR("Returns the type of option specified by key.")},
805
 
    {"get_option_rank",  libspud_get_option_rank, METH_VARARGS,
806
 
     PyDoc_STR("Return the rank of option specified by key.")},
807
 
    {"get_option_shape",  libspud_get_option_shape, METH_VARARGS,
808
 
     PyDoc_STR("Return the shape of option specified by key.")},
809
 
    {"get_option",  libspud_get_option, METH_VARARGS,
810
 
     PyDoc_STR("Retrives option values from the options dictionary.")},
811
 
    {"set_option",  libspud_set_option, METH_VARARGS,
812
 
     PyDoc_STR("Sets options in the options tree.")},
813
 
    {"write_options",  libspud_write_options, METH_VARARGS,
814
 
     PyDoc_STR("Write options tree out to the xml file specified by name.")},
815
 
    {"delete_option",  libspud_delete_option, METH_VARARGS,
816
 
     PyDoc_STR("Delete options at the specified key.")},
817
 
    {"set_option_attribute",  libspud_set_option_attribute, METH_VARARGS,
818
 
     PyDoc_STR("As set_option, but additionally attempts to mark the option at the \
819
 
     specified key as an attribute. Set_option_attribute accepts only string data for val.")},
820
 
    {"add_option",  libspud_add_option, METH_VARARGS,
821
 
     PyDoc_STR("Creates a new option at the supplied key.")},
822
 
    {NULL, NULL, 0, NULL},
823
 
            /* Sentinel */
824
 
};
825
 
 
826
 
PyMODINIT_FUNC
827
 
initlibspud(void)
828
 
{
829
 
    PyObject *m;
830
 
 
831
 
    m = Py_InitModule("libspud", libspudMethods);
832
 
    if (m == NULL)
833
 
        return;
834
 
 
835
 
    SpudError = PyErr_NewException("Spud.error", NULL, NULL);
836
 
    SpudNewKeyWarning = PyErr_NewException("SpudNewKey.warning", NULL, NULL);
837
 
    SpudKeyError = PyErr_NewException("SpudKey.error", NULL, NULL);
838
 
    SpudTypeError = PyErr_NewException("SpudType.error", NULL, NULL);
839
 
    SpudFileError = PyErr_NewException("SpudFile.warning", NULL, NULL);
840
 
    SpudAttrSetFailedWarning = PyErr_NewException("SpudAttrSetFailed.warning", NULL, NULL);
841
 
    SpudShapeError = PyErr_NewException("SpudShape.error", NULL, NULL);
842
 
    SpudRankError = PyErr_NewException("SpudRank.error", NULL, NULL);
843
 
 
844
 
    Py_INCREF(SpudError);
845
 
    Py_INCREF(SpudNewKeyWarning);
846
 
    Py_INCREF(SpudKeyError);
847
 
    Py_INCREF(SpudTypeError);
848
 
    Py_INCREF(SpudFileError);
849
 
    Py_INCREF(SpudRankError);
850
 
    Py_INCREF(SpudShapeError);
851
 
    Py_INCREF(SpudAttrSetFailedWarning);
852
 
 
853
 
    PyModule_AddObject(m, "SpudError", SpudError);
854
 
    PyModule_AddObject(m, "SpudNewKeyWarning", SpudNewKeyWarning);
855
 
    PyModule_AddObject(m, "SpudKeyError", SpudKeyError);
856
 
    PyModule_AddObject(m, "SpudTypeError", SpudTypeError);
857
 
    PyModule_AddObject(m, "SpudFileError", SpudFileError);
858
 
    PyModule_AddObject(m, "SpudAttrSetFailedWarning", SpudAttrSetFailedWarning);
859
 
    PyModule_AddObject(m, "SpudShapeError", SpudShapeError);
860
 
    PyModule_AddObject(m, "SpudRankError", SpudRankError);
861
 
 
862
 
 
863
 
#if PY_MINOR_VERSION > 6
864
 
    manager = PyCapsule_Import("spud_manager._spud_manager", 0);
865
 
    if (manager != NULL) spud_set_manager(manager);
866
 
    else PyErr_Clear();
867
 
#endif
868
 
 
869
 
}
870
 
 
871