1 /******************************************************************************
2 *
3 * Copyright (C) 2006-08, The Gentee Group. All rights reserved.
4 * This file is part of the Gentee open source project - http://www.gentee.com.
5 *
6 * THIS FILE IS PROVIDED UNDER THE TERMS OF THE GENTEE LICENSE ("AGREEMENT").
7 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE CONSTITUTES RECIPIENTS
8 * ACCEPTANCE OF THE AGREEMENT.
9 *
10 * Author: Alexey Krivonogov
11 *
12 ******************************************************************************/
13
14 /*-----------------------------------------------------------------------------
15 * Id: genteeapi L "Gentee API"
16 *
17 * Desc: Gentee API functions for the using of gentee.dll.
18 * Summary: There is an option for software engineers to run programs in Gentee
19 in their own applications. To do that, it is enough to connect the
20 gentee.dll file. It contains several importable functions, which
21 are responsible for compilation and execution of the programs.
22 *
23 * List: *, gentee_call, gentee_compile, gentee_deinit, gentee_getid,
24 gentee_init, gentee_load, gentee_ptr, gentee_set,
25 *#lng/types#, tgentee, compileinfo, toptimize
26 *
27 -----------------------------------------------------------------------------*/
28
29 #include "gentee.h"
30 #include "../common/crc.h"
31 #include "../common/memory.h"
32 #include "../common/file.h"
33 #include "../os/user/defines.h"
34 #include "../bytecode/ge.h"
35
36 gentee _gentee;
37 pcompile _compile;
38
39 /*-----------------------------------------------------------------------------
40 * Id: gentee_deinit F1
41 *
42 * Summary: End of working with gentee.dll. This function should be called when
43 the work with Gentee is finished.
44 *
45 * Return: #lng/retf#
46 *
47 -----------------------------------------------------------------------------*/
48
49 uint STDCALL gentee_deinit( void )
50 {
51 if ( _gentee.tempfile )
52 {
53 str stemp;
54
55 str_init( &stemp );
56 os_dirdeletefull( &_gentee.tempdir );
57 os_fileclose( _gentee.tempfile );
58 str_printf( &stemp, "%s.tmp", str_ptr( &_gentee.tempdir ));
59 os_filedelete( &stemp );
60 str_delete( &stemp );
61 }
62 vm_deinit();
63 str_delete( &_gentee.tempdir );
64 mem_deinit();
65
66 return TRUE;
67 }
68
69 /*-----------------------------------------------------------------------------
70 * Id: gentee_init F
71 *
72 * Summary: Initialization of gentee.dll. This function should be called before
73 beginning to work with Gentee.
74 *
75 * Params: flags - Flags. $$[initflags]
76 *
77 * Return: #lng/retf#
78 *
79 -----------------------------------------------------------------------------*/
80
81 uint STDCALL gentee_init( uint flags )
82 {
83 mem_zero( &_gentee, sizeof( gentee ));
84
85 mem_init();
86 crc_init();
87
88 _gentee.flags = flags;
89 _gentee.print = &os_print;
90 os_init( 0 );
91
92 str_init( &_gentee.tempdir );
93
94 vm_init();
95 _compile = NULL;
96 _gentee.message = &message;
97
98 return TRUE;
99 }
100
101 /*-----------------------------------------------------------------------------
102 * Id: gentee_set F
103 *
104 * Summary: This function specifies some gentee parameters.
105 *
106 * Params: state - The identifier of the parameter.$$[setpars]
107 val - The new value of the parameter.
108 *
109 * Return: #lng/retf#
110 *
111 -----------------------------------------------------------------------------*/
112
113 uint STDCALL gentee_set( uint state, pvoid val )
114 {
115 switch ( state )
116 {
117 case GSET_FLAG:
118 _gentee.flags = ( uint )val;
119 break;
120 case GSET_TEMPDIR:
121 if ( _gentee.tempfile )
122 return 0;
123 str_copyzero( &_gentee.tempdir, ( pubyte )val );
124 break;
125 case GSET_PRINT:
126 _gentee.print = ( printfunc )val;
127 break;
128 case GSET_MESSAGE:
129 _gentee.message = ( messagefunc )val;
130 break;
131 case GSET_EXPORT:
132 _gentee.export = ( exportfunc )val;
133 break;
134 case GSET_DEBUG:
135 _gentee.debug = ( debugfunc )val;
136 break;
137 case GSET_GETCH:
138 _gentee.getch = ( getchfunc )val;
139 break;
140 case GSET_ARGS:
141 _gentee.args = val;
142 break;
143 }
144 return 1;
145 }
146
147 /*-----------------------------------------------------------------------------
148 * Id: gentee_ptr F
149 *
150 * Summary: Get Gentee structures. This function returns pointers to global
151 Gentee structures.
152 *
153 * Params: par - The identifier of the parameter.$$[ptrpars].
154 *
155 * Return: The pointer to according global Gentee structure.
156 *
157 -----------------------------------------------------------------------------*/
158
159 pvoid STDCALL gentee_ptr( uint par )
160 {
161 switch ( par )
162 {
163 case GPTR_GENTEE:
164 return &_gentee;
165 case GPTR_VM:
166 return _pvm;
167 case GPTR_COMPILE:
168 return _compile;
169 }
170 return &_gentee;
171 }
172
173 /*-----------------------------------------------------------------------------
174 * Id: gentee_load F
175 *
176 * Summary: Load and launch the bytecode. This function loads the bytecode from
177 the file or the memory and launch it if it is required. You can
178 create the bytecode with $[gentee_compile] function.
179 *
180 * Params: bytecode - The pointer to the bytecode or the filename of .ge file.
181 flag - Flags. $$[geloadflag]
182 *
183 * Return: The result of the executed bytecode if GLOAD_RUN was defined.
184 *
185 -----------------------------------------------------------------------------*/
186
187 uint STDCALL gentee_load( pubyte bytecode, uint flag )
188 {
189 pubyte cur, curout, oldargs;
190 uint count, result = 0;
191 ubyte stop;
192 buf bcode;
193
194 buf_init( &bcode );
195 if ( flag & GLOAD_ARGS )
196 { // Получаем аргументы из командной строки
197 oldargs = _gentee.args;
198 curout = _gentee.args = mem_alloc( 1024 );
199 cur = GetCommandLine();
200 count = 0;
201 while ( *cur )
202 {
203 while ( *cur == ' ' ) cur++;
204 if ( !*cur ) break;
205
206 if ( *cur == '\"' )
207 {
208 cur++;
209 stop = '\"';
210 }
211 else
212 stop = ' ';
213
214 while ( *cur != stop )
215 {
216 if ( count )
217 {
218 if ( *cur == '\\' && *( cur + 1 )== '\"' )
219 cur++;
220 *curout++ = *cur;
221 }
222 if ( !*++cur ) break;
223 }
224 if ( *cur == stop ) cur++;
225 if ( count++ )
226 *curout++ = 0;
227 }
228 *curout = 0;
229 }
230 if ( flag & GLOAD_FILE )
231 {
232 str filename;
233
234 str_init( &filename );
235 str_copyzero( &filename, bytecode );
236 file2buf( &filename, &bcode, 0 );
237 str_delete( &filename );
238 }
239 else
240 buf_copy( &bcode, bytecode, (( pgehead )bytecode)->size );
241 // print("OK 0\n");
242 ge_load( &bcode );
243
244 if ( flag & GLOAD_RUN )
245 result = vm_execute( 1 );
246
247 if ( flag & GLOAD_ARGS )
248 {
249 mem_free( _gentee.args );
250 _gentee.args = oldargs;
251 }
252 buf_delete( &bcode );
253 return result;
254 }
255
256 /*-----------------------------------------------------------------------------
257 ** Id: gentee_getid F
258 *
259 * Summary: Get the object's identifier by its name.
260 *
261 * Params: name - The name of the object. If you want to find a method then /
262 use '#b(@)' at the beginning of the name. For example, /
263 "#b( @mymethod )". If you want to find an operator then /
264 use '#b(##)' at the beginning of the name. For example, /
265 "#b( #+= )".
266 count - The count of the following parameters. If you want to find /
267 any object with the defined name then specify the following /
268 flag. $$[getidflag]
269 ... - Specify the sequence of the type's identifiers of the /
270 parameters. If the parameter of the function has "#b( of )" /
271 subtype then specify it in the HIWORD of the value.
272 *
273 * Return: Returns object’s identifier or #b(0), if the object was not found.
274 *
275 -----------------------------------------------------------------------------*/
276
277 uint CDECLCALL gentee_getid( pubyte name, uint count, ... )
278 {
279 uint k = 0;
280 uint params[ 32 ];
281 uint bcode, flag;
282 va_list argptr;
283
284 flag = count;
285 count &= 0xFFFFFF;
286
287 if ( flag & GID_ANYOBJ )
288 {
289 phashitem phi;
290 phi = hash_find( &_vm.objname, name );
291 return phi ? *( puint )( phi + 1 ) : 0;
292 }
293 va_start( argptr, count );
294
295 while ( count-- )
296 {
297 params[ k++ ] = va_arg( argptr, uint );
298 if ( params[ k - 1 ] & 0xFFFF0000 )
299 {
300 params[ k ] = params[ k - 1 ] >> 16;
301 params[ k - 1 ] &= 0xFFFF;
302 }
303 else
304 params[ k ] = 0;
305 k++;
306 }
307 va_end( argptr );
308
309 bcode = ( uint )vm_find( name, k >> 1, params );
310 return ( uint )bcode < MSGCOUNT ? 0 : ((pvmfunc)bcode)->vmo.id;
311 }
312
313 //--------------------------------------------------------------------------
Edit