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