1// This file is part of SmallBASIC
2//
3// RTL API (Parameter's API)
4//
5// This program is distributed under the terms of the GPL v2.0 or later
6// Download the GNU Public License (GPL) from www.gnu.org
7//
8// Copyright(C) 2000 Nicholas Christopoulos
9
10/**
11 * @defgroup par Parameters
12 */
13
14#if !defined(_sb_proc_h)
15#define _sb_proc_h
16
17#include "common/sys.h"
18#include "common/str.h"
19#include "common/kw.h"
20#include "common/var.h"
21#include "common/device.h"
22#include "common/blib.h"
23#include "common/sberr.h"
24#include "common/smbas.h"
25
26/*
27 * known also, as 'output' or 'method' for pv_* functions
28 */
29#define PV_CONSOLE 0
30#define PV_FILE 1
31#define PV_LOG 2
32#define PV_STRING 3
33#define PV_NET 4
34
35#if defined(__cplusplus)
36extern "C" {
37#endif
38
39#define pfree(a) { if ((a)) free((a)); }
40/**< simple macro for free() @ingroup par */
41#define pfree2(a,b) { pfree((a)); pfree((b)); }
42/**< simple macro for free() 2 ptrs @ingroup par */
43#define pfree3(a,b,c) { pfree2((a),(b)); pfree((c)); }
44/**< simple macro for free() 3 ptrs @ingroup par */
45
46/**
47 * @ingroup exec
48 *
49 * proceed to a recursive execution-loop
50 *
51 * @note avoid to use it
52 */
53void bc_loop(int isf);
54
55/**
56 * @ingroup exec
57 *
58 * evaluate the next expression (starting from current instruction).
59 * put the result on 'result' variable.
60 *
61 * @param result the variable to store the result.
62 */
63void eval(var_t *result);
64
65/**
66 * @ingroup exec
67 *
68 * write a string by using a specific method
69 *
70 * @note avoid to use it
71 */
72void pv_write(char *str, int method, intptr_t handle);
73
74/**
75 * @ingroup exec
76 *
77 * write a variable-contents by using a specific method
78 *
79 * @note avoid to use it
80 */
81void pv_writevar(var_t *var, int method, intptr_t handle);
82
83/**
84 * @ingroup exec
85 *
86 * prints a variable's contents in console
87 *
88 * @param var is the variable
89 */
90void print_var(var_t *var);
91
92/**
93 * @ingroup exec
94 *
95 * writes a variable's contents in a file
96 *
97 * @param var is the variable
98 * @param handle is the file-handle
99 */
100void fprint_var(intptr_t handle, var_t *var);
101
102/**
103 * @ingroup exec
104 *
105 * prints a variable's contents to log-file
106 *
107 * @param var is the variable
108 */
109void logprint_var(var_t *var);
110
111/*
112 * Parameter's API
113 *
114 * Use these functions
115 */
116
117/**
118 * @ingroup par
119 * @typedef par_t
120 * Parameter structure, used in 'partables'
121 */
122typedef struct {
123 var_t *var; /**< a var_t pointer; the data */
124
125 byte prev_sep; /**< previous separator (default '\0') */
126 byte next_sep; /**< next separator (default '\0') */
127
128 byte flags; /**< 0x1 = its a 'byval' and the 'var' must be released */
129} par_t;
130
131/* par_t flags */
132#define PAR_BYVAL 1
133/**< pat_t::flags, parameter was an expression
134 (var = the temporary copy of the result) @ingroup par */
135
136/**
137 * @ingroup par
138 *
139 * get next parameter as any-value (variable).
140 * moves IP to the next position.
141 *
142 * @param var the variable to copy the data
143 */
144void par_getvar(var_t *var);
145
146/**
147 * @ingroup par
148 *
149 * get next parameter as variable's pointer.
150 * moves IP to the next position.
151 *
152 * @return the var_t pointer
153 */
154var_t *par_getvar_ptr(void);
155
156/**
157 * @ingroup par
158 *
159 * get next parameter as string-var_t
160 * moves IP to the next position.
161 *
162 * @param var the variable to copy the data
163 */
164void par_getstr(var_t *var);
165
166/**
167 * @ingroup par
168 *
169 * get next parameter as integer
170 * moves IP to the next position.
171 *
172 * @return the integer
173 */
174var_int_t par_getint(void);
175
176/**
177 * @ingroup par
178 *
179 * get next parameter as double
180 * moves IP to the next position.
181 *
182 * @return the number
183 */
184var_num_t par_getnum(void);
185
186#define par_getreal() par_getnum()
187
188/**
189 * @ingroup par
190 *
191 * get next parameter as integer
192 *
193 * @return the integer
194 */
195var_int_t par_next_int(int sep);
196
197/**
198 * @ingroup par
199 *
200 * get next parameter as string
201 *
202 * @return the string var
203 */
204var_t *par_next_str(var_t *arg, int sep);
205
206/**
207 * @ingroup par
208 *
209 * get next parameter as integer
210 * moves IP to the next position.
211 *
212 * @return the integer
213 */
214var_int_t par_getval(var_int_t def);
215
216/**
217 * @ingroup par
218 *
219 * no-error if the next byte is a separator.
220 * moves IP to the next position.
221 *
222 * @return the separator
223 */
224int par_getsep(void);
225
226/**
227 * @ingroup par
228 *
229 * no-error if the next byte is the separator ','.
230 * moves IP to the next position.
231 */
232void par_getcomma(void);
233
234/**
235 * @ingroup par
236 *
237 * no-error if the next byte is the separator '#'.
238 * moves IP to the next position.
239 */
240void par_getsharp(void);
241
242/**
243 * @ingroup par
244 *
245 * no-error if the next byte is the separator ';'.
246 * moves IP to the next position.
247 */
248void par_getsemicolon(void);
249
250/**
251 * @ingroup par
252 *
253 * get next parameter as variable-pointer of an array.
254 * moves IP to the next position.
255 *
256 * @return the var_t pointer
257 */
258var_t *par_getvarray(void);
259
260/**
261 * @ingroup par
262 *
263 * skip parameter.
264 * moves IP to the next position.
265 */
266void par_skip(void);
267
268/**
269 * @ingroup par
270 *
271 * builds a parameter table
272 *
273 * ptable_pp = pointer to an ptable
274 * valid_sep = valid separators (,;)
275 *
276 * returns the number of the parameters, OR, -1 on error
277 *
278 * YOU MUST FREE THAT TABLE BY USING par_freepartable()
279 * IF THERE IS AN ERROR THE CALL TO par_freepartable IS NOT NEEDED
280 *
281 * moves IP to the next position.
282 *
283 * @param ptable_pp pointer to a par_t table
284 * @param valid_sep the valid parameter separators
285 * @return on success the number of the parameters; otherwise -1
286 * @see par_freepartable, par_massget
287 */
288int par_getpartable(par_t **ptable_pp, const char *valid_sep);
289
290/**
291 * @ingroup par
292 *
293 * frees a parameters-table
294 *
295 * @param ptable_pp pointer to a par_t table
296 * @param pcount the number of the parameters
297 * @see par_getpartable, par_massget
298 */
299void par_freepartable(par_t **ptable_pp, int pcount);
300
301/**
302 * @ingroup par
303 *
304 * parsing parameters with scanf-style. returns the parameter-count or -1 (error)
305 *
306 * this is the preferred method for any command except statements.
307 *
308 <pre>
309 * Format:
310 * --------
311 * capital character = the parameter is required
312 * small character = optional parameter
313 *
314 * I = integer (int32_t )
315 * F = double (double*)
316 * S = string (char* )
317 * P = variable's ptr (var_t* )
318 </pre>
319 *
320 * <b>Example</b>
321 *
322 @code
323 int32_t i1, i2 = -1; // -1 is the default value for i2
324 char *s1 = NULL; // NULL is the default value for s1
325 var_t *v = NULL; // NULL is the default value for v
326
327 // the first integer is required, the second is optional
328 // the string is optional too
329 pc = par_massget("Iisp", &i1, &i2, &s1, &v);
330
331 if ( pc != -1 ) { // no error; also, you can use prog_error because par_massget() will call rt_raise() on error
332 printf("required integer = %d\n", i1);
333
334 // if there is no optional parameters, the default value will be returned
335 if ( i2 != -1 ) printf("optional integer found = %d\n", i2);
336 if ( s1 ) printf("optional string found = %s\n", s1);
337 if ( v ) { printf("optional variable's ptr found"); v_free(v); }
338 }
339
340 pfree2(s1, v);
341 @endcode
342 *
343 * moves IP to the next position.
344 *
345 * @param fmt the par_massget's format
346 * @param ... the format's parameters
347 * @return on success the parameter-count; otherwise -1
348 */
349int par_massget(const char *fmt, ...);
350
351/**
352 * @ingroup par
353 *
354 * execute a user's expression (using one variable).
355 * the result will be stored in 'var'.
356 *
357 * @note the keyword USE
358 *
359 * @param var the variable (the X)
360 * @param ip the expression's address
361 */
362void exec_usefunc(var_t *var, bcip_t ip);
363
364/**
365 * @ingroup par
366 *
367 * execute a user's expression (using two variables).
368 * the result will be stored in 'var1'.
369 *
370 * @note the keyword USE
371 *
372 * @param var1 the variable (the X)
373 * @param var2 the variable (the Y)
374 * @param ip the expression's address
375 */
376void exec_usefunc2(var_t *var1, var_t *var2, bcip_t ip);
377
378/**
379 * @ingroup par
380 *
381 * retrieve a 2D point (double).
382 * moves IP to the next position.
383 *
384 * @return a pt_t point structure
385 */
386pt_t par_getpt(void);
387
388/**
389 * @ingroup par
390 *
391 * retrieve a 2D polyline (double).
392 * moves IP to the next position.
393 *
394 * @param poly pointer to a table of real-points
395 * @return on success the number of points; otherwise 0
396 */
397int par_getpoly(pt_t **poly);
398
399/**
400 * @ingroup par
401 *
402 * retrieve a 2D point (integer).
403 * moves IP to the next position.
404 *
405 * @return a ipt_t point structure
406 */
407ipt_t par_getipt(void);
408
409/**
410 * @ingroup par
411 *
412 * retrieve a 2D polyline (integers).
413 * moves IP to the next position.
414 *
415 * @param poly pointer to a table of integer-points
416 * @return on success the number of points; otherwise 0
417 */
418int par_getipoly(ipt_t **poly);
419
420#if defined(__cplusplus)
421 }
422#endif
423#endif
424