root/trunk/infrastructure/pyd/def.d

Revision 120, 4.2 kB (checked in by KirkMcDonald, 1 year ago)

* Pyd now requires D 2.003 or later.
* Pyd now compiles with D 2.003.
* Resolved long-standing string-copying annoyance (thanks to const).

Line 
1 /*
2 Copyright 2006, 2007 Kirk McDonald
3
4 Permission is hereby granted, free of charge, to any person obtaining a copy of
5 this software and associated documentation files (the "Software"), to deal in
6 the Software without restriction, including without limitation the rights to
7 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
8 of the Software, and to permit persons to whom the Software is furnished to do
9 so, subject to the following conditions:
10
11 The above copyright notice and this permission notice shall be included in all
12 copies or substantial portions of the Software.
13
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 SOFTWARE.
21 */
22 module pyd.def;
23
24 import python;
25
26 import pyd.func_wrap;
27 import pyd.lib_abstract :
28     symbolnameof,
29     minArgs
30 ;
31 //import meta.Default;
32 //import meta.Nameof;
33
34 private PyMethodDef module_global_methods[] = [
35     { null, null, 0, null }
36 ];
37
38 private PyMethodDef[][string] module_methods;
39 private PyObject*[string] pyd_modules;
40
41 private void ready_module_methods(string modulename) {
42     PyMethodDef empty;
43     if (!(modulename in module_methods)) {
44         module_methods[modulename] = (PyMethodDef[]).init;
45         module_methods[modulename] ~= empty;
46     }
47 }
48
49 PyObject* Pyd_Module_p(string modulename="") {
50     PyObject** m = modulename in pyd_modules;
51     if (m is null) return null;
52     else return *m;
53 }
54
55 /**
56  * Wraps a D function, making it callable from Python.
57  *
58  * Params:
59  *      name = The name of the function as it will appear in Python.
60  *      fn   = The function to wrap.
61  *      MIN_ARGS = The minimum number of arguments this function can accept.
62  *                 For use with functions with default arguments. Defaults to
63  *                 the maximum number of arguments this function supports.
64  *      fn_t = The function type of the function to wrap. This must be
65  *             specified if more than one function shares the same name,
66  *             otherwise the first one defined lexically will be used.
67  *
68  * Examples:
69  *$(D_CODE import pyd.pyd;
70  *char[] foo(int i) {
71  *    if (i > 10) {
72  *        return "It's greater than 10!";
73  *    } else {
74  *        return "It's less than 10!";
75  *    }
76  *}
77  *extern (C)
78  *export void inittestdll() {
79  *    _def!("foo", foo);
80  *    module_init("testdll");
81  *})
82  * And in Python:
83  *$(D_CODE >>> import testdll
84  *>>> print testdll.foo(20)
85  *It's greater than 10!)
86  */
87 void def(alias fn, string name = symbolnameof!(fn), fn_t=typeof(&fn), uint MIN_ARGS = minArgs!(fn, fn_t)) (string docstring="") {
88     def!("", fn, name, fn_t, MIN_ARGS)(docstring);
89 }
90
91 void def(string modulename, alias fn, string name = symbolnameof!(fn), fn_t=typeof(&fn), uint MIN_ARGS = minArgs!(fn, fn_t)) (string docstring) {
92     pragma(msg, "def: " ~ name);
93     PyMethodDef empty;
94     ready_module_methods(modulename);
95     PyMethodDef[]* list = &module_methods[modulename];
96
97     (*list)[length-1].ml_name = (name ~ \0).ptr;
98     (*list)[length-1].ml_meth = &function_wrap!(fn, MIN_ARGS, fn_t).func;
99     (*list)[length-1].ml_flags = METH_VARARGS;
100     (*list)[length-1].ml_doc = (docstring ~ \0).ptr;
101     (*list) ~= empty;
102 }
103
104 string pyd_module_name;
105
106 /**
107  * Module initialization function. Should be called after the last call to def.
108  */
109 PyObject* module_init(string docstring="") {
110     //_loadPythonSupport();
111     string name = pyd_module_name;
112     ready_module_methods("");
113     pyd_modules[""] = Py_InitModule3((name ~ \0).ptr, module_methods[""].ptr, (docstring ~ \0).ptr);
114     return pyd_modules[""];
115 }
116
117 /**
118  * Module initialization function. Should be called after the last call to def.
119  */
120 PyObject* add_module(string name, string docstring="") {
121     ready_module_methods(name);
122     pyd_modules[name] = Py_InitModule3((name ~ \0).ptr, module_methods[name].ptr, (docstring ~ \0).ptr);
123     return pyd_modules[name];
124 }
Note: See TracBrowser for help on using the browser.