eb550f248772060364783489a39fb9d70cd7ec3a
[scilab.git] / scilab / modules / dynamic_link / src / c / addinter.c
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) INRIA/ENPC
4  * Copyright (C) 2008 - INRIA - Allan CORNET
5  *
6  * This file must be used under the terms of the CeCILL.
7  * This source file is licensed as described in the file COPYING, which
8  * you should have received as part of this distribution.  The terms
9  * are also available at
10  * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
11  *
12  */
13
14 /*-----------------------------------------------------------------------------------*/
15 #include <string.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #ifdef _MSC_VER
19 #include <windows.h>
20 #endif
21
22 #include "core_math.h"
23 #include "dynamic_link.h"
24 #include "men_Sutils.h"
25 #include "addinter.h"
26
27 #include "do_error_number.h"
28 #include "stack-c.h"
29 #include "MALLOC.h" /* MALLOC */
30 #include "sciprint.h"
31 #include "Funtab.h"
32 #include "warningmode.h"
33 #include "GetenvB.h"
34 #include "localization.h"
35 #include "Scierror.h"
36 #ifdef _MSC_VER
37 #include "ExceptionMessage.h"
38 #endif
39
40 /* size of interface name */
41 /* scilab limitation to nlgh characters (24)*/
42 #define INTERFSIZE nlgh + 1
43 /*-----------------------------------------------------------------------------------*/
44 typedef struct
45 {
46     char name[INTERFSIZE]; /** name of interface **/
47     void (*func)();        /** entrypoint for the interface **/
48     int Nshared; /** id of the shared library **/
49     BOOL ok;    /** flag set to TRUE if entrypoint can be used **/
50 } InterfaceElement;
51 /*-----------------------------------------------------------------------------------*/
52 InterfaceElement *DynInterf = NULL;
53 static int MaxInterfaces = MAXDYNINTERF;
54 /*-----------------------------------------------------------------------------------*/
55 static int LastInterf = 0;
56 static void initializeInterfaces(void);
57 static BOOL reallocDynInterf(void);
58 /*-----------------------------------------------------------------------------------*/
59 int AddInterfaceToScilab(char *filenamelib, char *spname, char **fcts, int sizefcts)
60 {
61     int IdLib = -1; /* Id of library */
62     int idinput = -1; /* Id of a function */
63     int ierr1 = 0;
64     int one = 1;
65     char **subname = NULL;
66     int ierr = 0;
67     int i = 0;
68     int inum = 0;
69     int k1 = 0;
70
71     initializeLink();
72     initializeInterfaces();
73
74     /** Try to unlink the interface if it was previously linked **/
75
76     for ( i = 0 ; i < LastInterf ; i++)
77     {
78         if (strcmp(spname, DynInterf[i].name) == 0)
79         {
80             unlinksharedlib(&DynInterf[i].Nshared);
81             break;
82         }
83     }
84
85     /** Try to find a free position in the interface table : inum **/
86     inum = -1;
87     for ( i = 0 ; i < LastInterf ; i++)
88     {
89         if ( DynInterf[i].ok == 0 )
90         {
91             inum = i;
92         }
93     }
94
95     inum = ( inum == -1 ) ? LastInterf : inum ;
96
97     /** Linking Files and add entry point name iname */
98
99     if ( inum >=  MaxInterfaces )
100     {
101         /* Try to resize DynInterf */
102         if ( ( !reallocDynInterf() ) || ( inum >=  MaxInterfaces ) )
103         {
104             return -1;
105         }
106     }
107
108     subname = (char **)MALLOC(sizeof (char*));
109     subname[0] = spname;
110
111     /* link then search  */
112     /* Trying with the fortran symbol */
113     IdLib =  scilabLink(idinput, filenamelib, subname, one, TRUE, &ierr1);
114     if (ierr1 != 0)
115     {
116         /* Haven't been able to find the symbol. Try C symbol */
117         IdLib =  scilabLink(idinput, filenamelib, subname, one, FALSE, &ierr1);
118     }
119
120     subname[0] = NULL;
121     if (subname)
122     {
123         FREE(subname);
124         subname = NULL;
125     }
126
127     if ( IdLib < 0 )
128     {
129         return IdLib;
130     }
131
132     /** store the linked function in the interface function table DynInterf **/
133     DynInterf[inum].Nshared = IdLib;
134
135     if ( SearchInDynLinks(spname, &DynInterf[inum].func) < 0 )
136     {
137         /* Maximum number of dynamic interfaces */
138         return -6;
139     }
140     else
141     {
142         strncpy(DynInterf[inum].name, spname, INTERFSIZE);
143         DynInterf[inum].ok = TRUE;
144     }
145     if ( inum == LastInterf )
146     {
147         LastInterf++;
148     }
149
150     k1 = inum + 1;
151     for (i = 0; i < sizefcts; i++)
152     {
153         int id[nsiz], zero = 0, three = 3, fptr = 0, fptr1 = 0, four = 4;
154
155         /* find a previous functions with same name */
156         C2F(cvname)(id, fcts[i], &zero, (unsigned long)strlen(fcts[i]));
157         fptr1 = fptr = (DynInterfStart + k1) * 1000 + (i + 1);
158         /* clear previous def set fptr1 to 0*/
159         C2F(funtab)(id, &fptr1, &four, "NULL_NAME", 0);
160         /* reinstall */
161         C2F(funtab)(id, &fptr, &three, fcts[i], (unsigned long)strlen(fcts[i]));
162     }
163
164     return ierr;
165 }
166 /*-----------------------------------------------------------------------------------*/
167 static void initializeInterfaces(void)
168 {
169     static int first_entry_interfaces = 0;
170
171     if ( first_entry_interfaces == 0)
172     {
173         if (DynInterf == NULL)
174         {
175             DynInterf = (InterfaceElement*)MALLOC(sizeof(InterfaceElement) * MaxInterfaces);
176             if (DynInterf)
177             {
178                 int i = 0;
179                 for ( i = 0 ; i < MaxInterfaces ; i++)
180                 {
181                     strcpy(DynInterf[i].name, "");
182                     DynInterf[i].func = NULL;
183
184                     DynInterf[i].Nshared = -1;
185                     DynInterf[i].ok = FALSE;
186                 }
187             }
188         }
189         first_entry_interfaces++;
190     }
191 }
192 /*-----------------------------------------------------------------------------------*/
193 /*********************************
194 * used in unlinksharedlib(i)
195 *********************************/
196 void RemoveInterf(int id)
197 {
198     int i = 0;
199     for ( i = 0 ; i < LastInterf ; i++ )
200     {
201         if ( DynInterf[i].Nshared == id )
202         {
203             DynInterf[i].ok = FALSE;
204             break;
205         }
206     }
207 }
208 /*-----------------------------------------------------------------------------------*/
209 /************************************************
210 * Used when one want to call a function added
211 * with addinterf the dynamic interface number
212 * is given by *k - (DynInterfStart+1)
213 ************************************************/
214 void C2F(userlk)(int *k)
215 {
216     int k1 = *k - (DynInterfStart + 1) ;
217
218     int imes = 9999;
219     if ( k1 >= LastInterf || k1 < 0 )
220     {
221         if (getWarningMode())
222         {
223             Scierror(999, _("Error: Not a valid internal routine number %d.\n"), *k);
224         }
225         SciError(imes);
226         return;
227     }
228
229     if ( DynInterf[k1].ok == 1 )
230     {
231 #ifdef _MSC_VER
232 #ifndef _DEBUG
233         _try
234         {
235             (*DynInterf[k1].func)();
236         }
237         _except (EXCEPTION_EXECUTE_HANDLER)
238         {
239             ExceptionMessage(GetExceptionCode(), DynInterf[k1].name);
240         }
241 #else
242         (*DynInterf[k1].func)();
243 #endif
244 #else
245         (*DynInterf[k1].func)();
246 #endif
247     }
248     else
249     {
250         if (getWarningMode())
251         {
252             sciprint(_("Interface %s not linked.\n"), DynInterf[k1].name);
253         }
254         SciError(imes);
255         return;
256     }
257 }
258 /*-----------------------------------------------------------------------------------*/
259 static BOOL reallocDynInterf(void)
260 {
261     /* increase table of interfaces by 2 */
262     int newMaxInterfaces = MaxInterfaces * 2;
263
264     if (newMaxInterfaces < ENTRYMAX)
265     {
266         if (DynInterf)
267         {
268             int i = 0;
269             InterfaceElement *newDynInterf = NULL;
270
271             newDynInterf = (InterfaceElement*)REALLOC(DynInterf, sizeof(InterfaceElement) * newMaxInterfaces);
272             if (newDynInterf == NULL)
273             {
274                 return FALSE;
275             }
276
277             DynInterf = newDynInterf;
278
279             for ( i = MaxInterfaces ; i < newMaxInterfaces ; i++)
280             {
281                 strcpy(DynInterf[i].name, "");
282                 DynInterf[i].func = NULL;
283                 DynInterf[i].Nshared = -1;
284                 DynInterf[i].ok = FALSE;
285             }
286             MaxInterfaces = newMaxInterfaces;
287             return TRUE;
288         }
289         else
290         {
291             return FALSE;
292         }
293     }
294     return FALSE;
295 }
296 /*-----------------------------------------------------------------------------------*/