61589221670b6bfa2bac00fcd045beb79c2881d2
[scilab.git] / scilab / modules / dynamic_link / macros / ilib_gen_gateway.sci
1 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
2 // Copyright (C) INRIA/ENPC
3 // Copyright (C) DIGITEO - 2010 - Allan CORNET
4 //
5 // This file must be used under the terms of the CeCILL.
6 // This source file is licensed as described in the file COPYING, which
7 // you should have received as part of this distribution.  The terms
8 // are also available at
9 // http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
10
11 //=============================================================================
12 // ilib_gen_gateway_cpp used by ilib_build
13 //=============================================================================
14 // generate an interface gateway named name
15 // from table table taking into account
16 // attributes of function i.e mex fmex or scilab interface
17 // if name is a full path just extract the filename
18
19 function gateway_filename = ilib_gen_gateway(name,tables)
20
21     [lhs,rhs] = argn(0);
22     if rhs <> 2 then
23         error(msprintf(gettext("%s: Wrong number of input argument(s).\n"), "ilib_gen_gateway"));
24         return
25     end
26
27     gateway_filename = ["","",""];
28     k = strindex(name,["/","\"]);
29     if k~=[] then
30         path = part(name,1:k($));
31         name = part(name,k($)+1:length(name));
32     else
33         path="";
34     end
35
36     [path_name, file_name, ext_name] = fileparts(name);
37     if ext_name == ".c" then
38         name = path_name + file_name;
39     else
40         name = path_name + file_name + ext_name;
41     end
42
43     if typeof(tables)<>"list" then
44         tables = list(tables);
45     end
46
47     L = length(tables);
48
49     for itable = 1:L
50         // loop on a list of tables
51         if L <> 1 then
52             tname = name +string(itable);
53         else
54             tname = name ;
55         end
56
57         table = tables(itable);
58         [mt,nt] = size(table);
59
60         if (nt == 2) then
61             col = "csci";
62             table = [table, col(ones(mt,1))];
63             nt = 3;
64         end
65
66         if ( nt <> 3 ) then
67             error(msprintf(gettext("%s: Wrong size for input argument #%d: %d expected.\n"),"ilib_gen_gateway",2,3));
68         end
69
70         global cppCompilation;
71         if isempty(cppCompilation) then
72             cppCompilation = %f;
73         end
74
75         [gate,names,cpp] = new_names(table);
76         cppCompilation = cppCompilation | cpp;
77
78         //generate cpp interface file
79         if  cppCompilation then
80             t = [
81             "#include ""context.hxx""";
82             "#include ""cpp_gateway_prototype.hxx""";
83             "#include """ + tname + ".hxx""";
84             "extern ""C""";
85             "{";
86             "#include """ + tname + ".h""";
87             "}";
88             "";
89             "#define MODULE_NAME L""" + tname + """";
90             "";
91             "int " + tname + "(wchar_t* _pwstFuncName)";
92             "{";
93             "    if(wcscmp(_pwstFuncName, L""" + table(:,1) + """) == 0){ " + "symbol::Context::getInstance()->addFunction(types::Function::createFunction(L""" + table(:,1) + """, &" + names(:) + ", MODULE_NAME)); }";
94             "";
95             "    return 1;";
96             "}"];
97         else
98             t = [
99             "#include <wchar.h>";
100             "#include """ + tname + ".hxx""";
101             "extern ""C""";
102             "{";
103             "#include """ + tname + ".h""";
104             "#include ""addfunction.h""";
105             "}";
106             "";
107             "#define MODULE_NAME L""" + tname + """";
108             "";
109             "int " + tname + "(wchar_t* _pwstFuncName)";
110             "{";];
111
112             for kGw = 1:size(names, "*")
113                 if or(table(kGw, 3) == ["cmex" "fmex" "Fmex"]) then
114                     t = [t;
115                     "    if(wcscmp(_pwstFuncName, L""" + table(kGw,1) + """) == 0){ " + "addMexFunction(L""" + table(kGw,1) + """, &" + names(kGw) + ", MODULE_NAME); }"];
116                 else
117                     t = [t;
118                     "    if(wcscmp(_pwstFuncName, L""" + table(kGw,1) + """) == 0){ " + "addCFunction(L""" + table(kGw,1) + """, &" + names(kGw) + ", MODULE_NAME); }"];
119                 end
120             end
121
122             t = [t;
123             "";
124             "    return 1;";
125             "}"];
126         end
127
128         gateway_filename(1) = path + tname + ".cpp";
129         // first check if we have already a gateway
130         [fd, ierr] = mopen(gateway_filename(1), "rt");
131         if ierr == 0 then
132             // file already exists
133             t1 = mgetl(fd);
134             mclose(fd);
135             if or(t1 <> t) then
136                 mputl(t, gateway_filename(1));
137             end
138         else
139             // file does not exist we create it
140             mputl(t, gateway_filename(1)) ;
141         end
142
143         if ilib_verbose() > 1 then
144             disp(t);
145         end
146
147         //prepare .hxx file
148         TNAME = convstr(tname, "u");
149         t = [
150         "#ifndef __" + TNAME + "_GW_HXX__";
151         "#define __" + TNAME + "_GW_HXX__";
152         "";
153         "#ifdef _MSC_VER";
154         "#ifdef " + TNAME + "_GW_EXPORTS";
155         "#define " + TNAME + "_GW_IMPEXP __declspec(dllexport)";
156         "#else";
157         "#define " + TNAME + "_GW_IMPEXP __declspec(dllimport)";
158         "#endif";
159         "#else";
160         "#define " + TNAME + "_GW_IMPEXP";
161         "#endif";
162         "";
163         "#include <cpp_gateway_prototype.hxx>";
164         "";
165         "extern ""C"" " + TNAME + "_GW_IMPEXP int " + tname + "(wchar_t* _pwstFuncName);";
166         "";
167         unique(gate(:, 2));
168         "";
169         "#endif /* __" + TNAME + "_GW_HXX__ */"];
170
171         gateway_filename(2) = path + tname + ".hxx";
172         // first check if we have already a gateway
173         [fd, ierr] = mopen(gateway_filename(2), "rt");
174         if ierr == 0 then
175             // file already exists
176             t1 = mgetl(fd);
177             mclose(fd);
178             if or(t1 <> t) then
179                 mputl(t, gateway_filename(2));
180             end
181         else
182             // file does not exist we create it
183             mputl(t, gateway_filename(2)) ;
184         end
185
186         //prepare .h file
187         TNAME = convstr(tname, "u");
188         t = [
189         "#ifndef __" + TNAME + "_GW_H__";
190         "#define __" + TNAME + "_GW_H__";
191         "";
192         "#include ""c_gateway_prototype.h""";
193         "";
194         unique(gate(:, 1));
195         "";
196         "#endif /* __" + TNAME + "_GW_H__ */"];
197
198         gateway_filename(3) = path + tname + ".h";
199         // first check if we have already a gateway
200         [fd, ierr] = mopen(gateway_filename(3), "rt");
201         if ierr == 0 then
202             // file already exists
203             t1 = mgetl(fd);
204             mclose(fd);
205             if or(t1 <> t) then
206                 mputl(t, gateway_filename(3));
207             end
208         else
209             // file does not exist we create it
210             mputl(t, gateway_filename(3)) ;
211         end
212
213         if ilib_verbose() > 1 then
214             disp(t);
215         end
216     end
217 endfunction
218 //=============================================================================
219 // new_names only used by ilib_gen_gateway
220 //=============================================================================
221 function [gate,names,cppCompilation] = new_names(table)
222     // change names according to types
223     cppCompilation = %f;
224     [mt,nt] = size(table);
225     gate = [""];
226     gate = gate(ones(mt, 2));
227     names = " ";
228     names = names(ones(mt,1));
229     for i = 1:mt
230         select table(i,3)
231         case "cmex" then
232             names(i) = "mex_" + table(i,2);
233             gate(i, 1) = "MEX_GATEWAY_PROTOTYPE(" + names(i) + ");";
234         case "fmex" then
235             names(i) = "C2F(mex" + table(i,2) + ")";
236             gate(i, 1) = "MEX_GATEWAY_PROTOTYPE(" + names(i) + ");";
237         case "Fmex" then
238             names(i) = "C2F(mex" + table(i,2) + ")";
239             gate(i, 1) = "MEX_GATEWAY_PROTOTYPE(" + names(i) + ");";
240         case "csci"  then
241             names(i) = table(i,2);
242             gate(i, 1) = "C_GATEWAY_PROTOTYPE(" + names(i) + ");";
243         case "fsci"  then
244             names(i) = "C2F(" + table(i,2) + ")";
245             gate(i, 1) = "C_GATEWAY_PROTOTYPE(" + names(i) + ");";
246         case "cppsci"  then
247             cppCompilation = %t;
248             names(i) = table(i,2);
249             gate(i, 2) = "CPP_GATEWAY_PROTOTYPE(" + names(i) + ");";
250         case "direct"  then
251             names(i) = table(i,2);
252             gate(i, 1) = "C_GATEWAY_PROTOTYPE(" + names(i) + ");";
253         else
254             error(999,"Wrong interface type " + table(i,3));
255         end
256     end
257 endfunction
258 //=============================================================================