Merge remote-tracking branch 'origin/master' into windows
[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 """ + tname + """";
93             "";
94             "int " + tname + "(const char* _pstFuncName)";
95             "{";
96             "    if(strcmp(_pstFuncName, """ + table(:,1) + """) == 0){ " + "symbol::Context::getInstance()->addFunction(types::Function::createFunction(""" + table(:,1) + """, &" + names(:) + ", MODULE_NAME)); }";
97             "";
98             "    return 1;";
99             "}"];
100         else
101             t = [
102             "#include """ + tname + ".hxx""";
103             "extern ""C""";
104             "{";
105             "#include """ + tname + ".h""";
106             "#include ""addfunction.h""";
107             "}";
108             "";
109             "#define MODULE_NAME """ + tname + """";
110             "";
111             "int " + tname + "(char* _pstFuncName)";
112             "{";];
113
114             for kGw = 1:size(names, "*")
115                 if or(table(kGw, 3) == ["cmex" "fmex" "Fmex"]) then
116                     t = [t;
117                     "    if(strcmp(_pstFuncName, """ + table(kGw,1) + """) == 0){ " + "addMexFunction(""" + table(kGw,1) + """, &" + names(kGw) + ", MODULE_NAME); }"];
118                 elseif table(kGw, 3) == "csci6" then
119                     t = [t;
120                     "    if(strcmp(_pstFuncName, """ + table(kGw,1) + """) == 0){ " + "addCFunction(""" + table(kGw,1) + """, &" + names(kGw) + ", MODULE_NAME); }"];
121                 else
122                     t = [t;
123                     "    if(strcmp(_pstFuncName, """ + table(kGw,1) + """) == 0){ " + "addCStackFunction(""" + table(kGw,1) + """, &" + names(kGw) + ", MODULE_NAME); }"];
124                 end
125             end
126
127             t = [t;
128             "";
129             "    return 1;";
130             "}"];
131         end
132
133         gateway_filename(1) = path + tname + ".cpp";
134         // first check if we have already a gateway
135         [fd, ierr] = mopen(gateway_filename(1), "rt");
136         if ierr == 0 then
137             // file already exists
138             t1 = mgetl(fd);
139             mclose(fd);
140             if or(t1 <> t) then
141                 mputl(t, gateway_filename(1));
142             end
143         else
144             // file does not exist we create it
145             mputl(t, gateway_filename(1)) ;
146         end
147
148         if ilib_verbose() > 1 then
149             disp(t);
150         end
151
152         //prepare .hxx file
153         TNAME = convstr(tname, "u");
154         t = [
155         "#ifndef __" + TNAME + "_GW_HXX__";
156         "#define __" + TNAME + "_GW_HXX__";
157         "";
158         "#ifdef _MSC_VER";
159         "#ifdef " + TNAME + "_GW_EXPORTS";
160         "#define " + TNAME + "_GW_IMPEXP __declspec(dllexport)";
161         "#else";
162         "#define " + TNAME + "_GW_IMPEXP __declspec(dllimport)";
163         "#endif";
164         "#else";
165         "#define " + TNAME + "_GW_IMPEXP";
166         "#endif";
167         "";
168         "extern ""C"" " + TNAME + "_GW_IMPEXP int " + tname + "(const char* _pstFuncName);";
169         "";
170         unique(gate(:, 2));
171         "";
172         "#endif /* __" + TNAME + "_GW_HXX__ */"];
173
174         gateway_filename(2) = path + tname + ".hxx";
175         // first check if we have already a gateway
176         [fd, ierr] = mopen(gateway_filename(2), "rt");
177         if ierr == 0 then
178             // file already exists
179             t1 = mgetl(fd);
180             mclose(fd);
181             if or(t1 <> t) then
182                 mputl(t, gateway_filename(2));
183             end
184         else
185             // file does not exist we create it
186             mputl(t, gateway_filename(2)) ;
187         end
188
189         //prepare .h file
190         TNAME = convstr(tname, "u");
191         t = [
192         "#ifndef __" + TNAME + "_GW_H__";
193         "#define __" + TNAME + "_GW_H__";
194         "";
195         "#include ""c_gateway_prototype.h""";
196         "";
197         unique(gate(:, 1));
198         "";
199         "#endif /* __" + TNAME + "_GW_H__ */"];
200
201         gateway_filename(3) = path + tname + ".h";
202         // first check if we have already a gateway
203         [fd, ierr] = mopen(gateway_filename(3), "rt");
204         if ierr == 0 then
205             // file already exists
206             t1 = mgetl(fd);
207             mclose(fd);
208             if or(t1 <> t) then
209                 mputl(t, gateway_filename(3));
210             end
211         else
212             // file does not exist we create it
213             mputl(t, gateway_filename(3)) ;
214         end
215
216         if ilib_verbose() > 1 then
217             disp(t);
218         end
219     end
220 endfunction
221 //=============================================================================
222 // new_names only used by ilib_gen_gateway
223 //=============================================================================
224 function [gate,names,cppCompilation] = new_names(table)
225     // change names according to types
226     cppCompilation = %f;
227     [mt,nt] = size(table);
228     gate = [""];
229     gate = gate(ones(mt, 2));
230     names = " ";
231     names = names(ones(mt,1));
232     for i = 1:mt
233         select table(i,3)
234         case "cmex" then
235             names(i) = "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 "Fmex" then
241             names(i) = "C2F(mex" + table(i,2) + ")";
242             gate(i, 1) = "MEX_GATEWAY_PROTOTYPE(" + names(i) + ");";
243         case "csci"  then
244             names(i) = table(i,2);
245             gate(i, 1) = "STACK_GATEWAY_PROTOTYPE(" + names(i) + ");";
246         case "csci6"  then
247             names(i) = table(i,2);
248             gate(i, 1) = "C_GATEWAY_PROTOTYPE(" + names(i) + ");";
249         case "fsci"  then
250             names(i) = "C2F(" + table(i,2) + ")";
251             gate(i, 1) = "STACK_GATEWAY_PROTOTYPE(" + names(i) + ");";
252         case "cppsci"  then
253             cppCompilation = %t;
254             names(i) = table(i,2);
255             gate(i, 2) = "CPP_GATEWAY_PROTOTYPE(" + names(i) + ");";
256         case "cppsciopt"  then
257             cppCompilation = %t;
258             names(i) = table(i,2);
259             gate(i, 2) = "CPP_OPT_GATEWAY_PROTOTYPE(" + names(i) + ");";
260         case "direct"  then
261             names(i) = table(i,2);
262             gate(i, 1) = "STACK_GATEWAY_PROTOTYPE(" + names(i) + ");";
263         else
264             error(999,"Wrong interface type " + table(i,3));
265         end
266     end
267 endfunction
268 //=============================================================================