]>
Commit | Line | Data |
---|---|---|
c90f71dd RD |
1 | /******************************************************************************* |
2 | * Simplified Wrapper and Interface Generator (SWIG) | |
3 | * | |
4 | * Author : David Beazley | |
5 | * | |
6 | * Department of Computer Science | |
7 | * University of Chicago | |
8 | * 1100 E 58th Street | |
9 | * Chicago, IL 60637 | |
10 | * beazley@cs.uchicago.edu | |
11 | * | |
12 | * Please read the file LICENSE for the copyright and terms by which SWIG | |
13 | * can be used and distributed. | |
14 | *******************************************************************************/ | |
15 | ||
16 | /* ------------------------------------------------------------------------ | |
17 | $Header$ | |
18 | ||
19 | parms.cxx | |
20 | ||
21 | This file is used to manage function parameters and parameter lists. | |
22 | Rewritten (10/27) to solve a bunch of problems with memory management | |
23 | and proper cleanup of things. | |
24 | ------------------------------------------------------------------------ */ | |
25 | ||
26 | #include "swig.h" | |
27 | ||
28 | // ------------------------------------------------------------------------ | |
29 | // Parm::Parm(DataType *type, char *n) | |
30 | // | |
31 | // Create a new parameter from datatype 'type' and name 'n'. | |
32 | // Copies will be made of type and n, unless they aren't specified. | |
33 | // ------------------------------------------------------------------------ | |
34 | ||
35 | Parm::Parm(DataType *type, char *n) { | |
36 | if (type) { | |
37 | t = new DataType(type); | |
38 | } else { | |
39 | t = 0; | |
40 | } | |
41 | name = copy_string(n); | |
42 | call_type = 0; | |
43 | defvalue = 0; | |
44 | ignore = 0; | |
45 | objc_separator = 0; | |
46 | } | |
47 | ||
48 | // ------------------------------------------------------------------------ | |
49 | // Parm::Parm(Parm *p) | |
50 | // | |
51 | // Make a copy of a parameter | |
52 | // ------------------------------------------------------------------------ | |
53 | ||
54 | Parm::Parm(Parm *p) { | |
55 | if (p->t) t = new DataType(p->t); | |
56 | name = copy_string(p->name); | |
57 | call_type = p->call_type; | |
58 | defvalue = copy_string(p->defvalue); | |
59 | ignore = p->ignore; | |
60 | objc_separator = copy_string(p->objc_separator); | |
61 | } | |
62 | ||
63 | // ------------------------------------------------------------------------ | |
64 | // Parm::~Parm() | |
65 | // | |
66 | // Destroy a parameter | |
67 | // ------------------------------------------------------------------------ | |
68 | ||
69 | Parm::~Parm() { | |
70 | if (t) delete t; | |
71 | if (name) delete name; | |
72 | if (defvalue) delete defvalue; | |
73 | if (objc_separator) delete objc_separator; | |
74 | } | |
75 | ||
76 | /******************************************************************** | |
77 | class ParmList | |
78 | ||
79 | These functions are used to manipulate lists of parameters | |
80 | ********************************************************************/ | |
81 | ||
82 | // ------------------------------------------------------------------ | |
83 | // ParmList::ParmList() | |
84 | // | |
85 | // Create a new (empty) parameter list | |
86 | // ------------------------------------------------------------------ | |
87 | ||
88 | ParmList::ParmList() { | |
89 | ||
90 | nparms = 0; | |
91 | maxparms = MAXPARMS; | |
92 | parms = new Parm *[maxparms]; // Create an array of parms | |
93 | for (int i = 0; i < MAXPARMS; i++) | |
94 | parms[i] = (Parm *) 0; | |
95 | } | |
96 | ||
97 | // ------------------------------------------------------------------ | |
98 | // ParmList::ParmList(ParmList *l) | |
99 | // | |
100 | // Make a copy of parameter list | |
101 | // ------------------------------------------------------------------ | |
102 | ||
103 | ParmList::ParmList(ParmList *l) { | |
104 | int i; | |
105 | ||
106 | if (l) { | |
107 | nparms = l->nparms; | |
108 | maxparms = l->maxparms; | |
109 | parms = new Parm *[maxparms]; | |
110 | ||
111 | for (i = 0; i < maxparms; i++) { | |
112 | if (l->parms[i]) | |
113 | parms[i] = new Parm(l->parms[i]); | |
114 | else | |
115 | parms[i] = 0; | |
116 | } | |
117 | ||
118 | } else { | |
119 | nparms = 0; | |
120 | maxparms = MAXPARMS; | |
121 | parms = new Parm *[maxparms]; // Create an array of parms | |
122 | ||
123 | for (i = 0; i < MAXPARMS; i++) | |
124 | parms[i] = (Parm *) 0; | |
125 | } | |
126 | } | |
127 | ||
128 | // ------------------------------------------------------------------ | |
129 | // ParmList::~ParmList() | |
130 | // | |
131 | // Delete a parameter list | |
132 | // ------------------------------------------------------------------ | |
133 | ||
134 | ParmList::~ParmList() { | |
135 | for (int i = 0; i < maxparms; i++) { | |
136 | if (parms[i]) delete parms[i]; | |
137 | } | |
138 | } | |
139 | ||
140 | ||
141 | // ------------------------------------------------------------------ | |
142 | // void ParmList::moreparms() (PRIVATE) | |
143 | // | |
144 | // Doubles the amount of parameter memory available. | |
145 | // ------------------------------------------------------------------ | |
146 | ||
147 | void ParmList::moreparms() { | |
148 | Parm **newparms; | |
149 | int i; | |
150 | ||
151 | newparms = new Parm *[maxparms*2]; | |
152 | for (i = 0; i < 2*maxparms; i++) | |
153 | newparms[i] = (Parm *) 0; | |
154 | for (i = 0; i < maxparms; i++) { | |
155 | newparms[i] = parms[i]; | |
156 | } | |
157 | maxparms = 2*maxparms; | |
158 | delete parms; | |
159 | parms = newparms; | |
160 | } | |
161 | ||
162 | // ------------------------------------------------------------------ | |
163 | // void ParmList::append(Parm *p) | |
164 | // | |
165 | // Add a new parameter to the end of a parameter list | |
166 | // ------------------------------------------------------------------ | |
167 | ||
168 | void ParmList::append(Parm *p) { | |
169 | ||
170 | if (nparms == maxparms) moreparms(); | |
171 | ||
172 | // Add parm onto the end | |
173 | ||
174 | parms[nparms] = new Parm(p); | |
175 | nparms++; | |
176 | } | |
177 | ||
178 | // ------------------------------------------------------------------ | |
179 | // void ParmList::insert(Parm *p, int pos) | |
180 | // | |
181 | // Inserts a parameter at position pos. Parameters are inserted | |
182 | // *before* any existing parameter at position pos. | |
183 | // ------------------------------------------------------------------ | |
184 | ||
185 | void ParmList::insert(Parm *p, int pos) { | |
186 | ||
187 | // If pos is out of range, we'd better fix it | |
188 | ||
189 | if (pos < 0) pos = 0; | |
190 | if (pos > nparms) pos = nparms; | |
191 | ||
192 | // If insertion is going to need more memory, take care of that now | |
193 | ||
194 | if (nparms >= maxparms) moreparms(); | |
195 | ||
196 | // Now shift all of the existing parms to the right | |
197 | ||
198 | for (int i = nparms; i > pos; i--) { | |
199 | parms[i] = parms[i-1]; | |
200 | } | |
201 | ||
202 | // Set new parameter | |
203 | ||
204 | parms[pos] = new Parm(p); | |
205 | nparms++; | |
206 | ||
207 | } | |
208 | ||
209 | // ------------------------------------------------------------------ | |
210 | // void ParmList::del(int pos) | |
211 | // | |
212 | // Deletes the parameter at position pos. | |
213 | // ------------------------------------------------------------------ | |
214 | ||
215 | void ParmList::del(int pos) { | |
216 | ||
217 | if (nparms <= 0) return; | |
218 | if (pos < 0) pos = 0; | |
219 | if (pos >= nparms) pos = nparms-1; | |
220 | ||
221 | // Delete the parameter (if it exists) | |
222 | ||
223 | if (parms[pos]) delete parms[pos]; | |
224 | ||
225 | // Now slide all of the parameters to the left | |
226 | ||
227 | for (int i = pos; i < nparms-1; i++) { | |
228 | parms[i] = parms[i+1]; | |
229 | } | |
230 | nparms--; | |
231 | ||
232 | } | |
233 | ||
234 | // ------------------------------------------------------------------ | |
235 | // Parm *ParmList::get(int pos) | |
236 | // | |
237 | // Gets the parameter at location pos. Returns 0 if invalid | |
238 | // position. | |
239 | // ------------------------------------------------------------------ | |
240 | ||
241 | Parm *ParmList::get(int pos) { | |
242 | ||
243 | if ((pos < 0) || (pos >= nparms)) return 0; | |
244 | return parms[pos]; | |
245 | } | |
246 | ||
247 | // ------------------------------------------------------------------ | |
248 | // int ParmList::numopt() | |
249 | // | |
250 | // Gets the number of optional arguments. | |
251 | // ------------------------------------------------------------------ | |
252 | int ParmList::numopt() { | |
253 | int n = 0; | |
254 | int state = 0; | |
255 | ||
256 | for (int i = 0; i < nparms; i++) { | |
257 | if (parms[i]->defvalue) { | |
258 | n++; | |
259 | state = 1; | |
260 | } else if (typemap_check("default",typemap_lang,parms[i]->t,parms[i]->name)) { | |
261 | n++; | |
262 | state = 1; | |
263 | } else if (typemap_check("ignore",typemap_lang,parms[i]->t,parms[i]->name)) { | |
264 | n++; | |
265 | } else if (typemap_check("build",typemap_lang,parms[i]->t,parms[i]->name)) { | |
266 | n++; | |
267 | } else { | |
268 | if (state) { | |
269 | fprintf(stderr,"%s : Line %d. Argument %d must have a default value!\n", input_file,line_number,i+1); | |
270 | } | |
271 | } | |
272 | } | |
273 | return n; | |
274 | } | |
275 | ||
276 | // ------------------------------------------------------------------ | |
277 | // int ParmList::numarg() | |
278 | // | |
279 | // Gets the number of arguments | |
280 | // ------------------------------------------------------------------ | |
281 | int ParmList::numarg() { | |
282 | int n = 0; | |
283 | ||
284 | for (int i = 0; i < nparms; i++) { | |
285 | if (!parms[i]->ignore) | |
286 | n++; | |
287 | } | |
288 | return n; | |
289 | } | |
290 | ||
291 | // ------------------------------------------------------------------ | |
292 | // Parm &ParmList::operator[](int n) | |
293 | // | |
294 | // Returns parameter n in the parameter list. May generate | |
295 | // an error if that parameter is out of range. | |
296 | // ------------------------------------------------------------------ | |
297 | ||
298 | Parm &ParmList::operator[](int n) { | |
299 | ||
300 | if ((n < 0) || (n >= nparms)) { | |
301 | fprintf(stderr,"ParmList : Fatal error. subscript out of range in ParmList.operator[]\n"); | |
302 | SWIG_exit(1); | |
303 | } | |
304 | ||
305 | return *parms[n]; | |
306 | } | |
307 | ||
308 | // --------------------------------------------------------------------- | |
309 | // Parm * ParmList::get_first() | |
310 | // | |
311 | // Returns the first item on a parameter list. | |
312 | // --------------------------------------------------------------------- | |
313 | ||
314 | Parm *ParmList::get_first() { | |
315 | current_parm = 0; | |
316 | if (nparms > 0) return parms[current_parm++]; | |
317 | else return (Parm *) 0; | |
318 | } | |
319 | ||
320 | // ---------------------------------------------------------------------- | |
321 | // Parm *ParmList::get_next() | |
322 | // | |
323 | // Returns the next item on the parameter list. | |
324 | // ---------------------------------------------------------------------- | |
325 | ||
326 | Parm * ParmList::get_next() { | |
327 | if (current_parm >= nparms) return 0; | |
328 | else return parms[current_parm++]; | |
329 | } | |
330 | ||
331 | // --------------------------------------------------------------------- | |
332 | // void ParmList::print_types(FILE *f) | |
333 | // | |
334 | // Prints a comma separated list of all of the parameter types. | |
335 | // This is for generating valid C prototypes. Has to do some | |
336 | // manipulation of pointer types depending on how the call_type | |
337 | // variable has been set. | |
338 | // ---------------------------------------------------------------------- | |
339 | ||
340 | void ParmList::print_types(FILE *f) { | |
341 | ||
342 | int is_pointer; | |
343 | int pn; | |
344 | pn = 0; | |
345 | while(pn < nparms) { | |
346 | is_pointer = parms[pn]->t->is_pointer; | |
347 | if (parms[pn]->t->is_reference) { | |
348 | if (parms[pn]->t->is_pointer) { | |
349 | parms[pn]->t->is_pointer--; | |
350 | fprintf(f,"%s&", parms[pn]->t->print_real()); | |
351 | parms[pn]->t->is_pointer++; | |
352 | } else { | |
353 | fprintf(f,"%s&", parms[pn]->t->print_real()); | |
354 | } | |
355 | } else { | |
356 | if (parms[pn]->call_type & CALL_VALUE) parms[pn]->t->is_pointer++; | |
357 | if (parms[pn]->call_type & CALL_REFERENCE) parms[pn]->t->is_pointer--; | |
358 | fprintf(f,"%s", parms[pn]->t->print_real()); | |
359 | parms[pn]->t->is_pointer = is_pointer; | |
360 | } | |
361 | pn++; | |
362 | if (pn < nparms) | |
363 | fprintf(f,","); | |
364 | } | |
365 | } | |
366 | ||
367 | ||
368 | // --------------------------------------------------------------------- | |
369 | // void ParmList::print_types(String &f) | |
370 | // | |
371 | // Generates a comma separated list of function types. Is used in | |
372 | // C++ code generation when generating hash keys and for function overloading. | |
373 | // ---------------------------------------------------------------------- | |
374 | ||
375 | void ParmList::print_types(String &f) { | |
376 | ||
377 | int is_pointer; | |
378 | int pn; | |
379 | pn = 0; | |
380 | while(pn < nparms) { | |
381 | is_pointer = parms[pn]->t->is_pointer; | |
382 | if (parms[pn]->t->is_reference) { | |
383 | if (parms[pn]->t->is_pointer) { | |
384 | parms[pn]->t->is_pointer--; | |
385 | f << parms[pn]->t->print_real() << "&"; | |
386 | parms[pn]->t->is_pointer++; | |
387 | } else { | |
388 | f << parms[pn]->t->print_real() << "&"; | |
389 | } | |
390 | } else { | |
391 | if (parms[pn]->call_type & CALL_VALUE) parms[pn]->t->is_pointer++; | |
392 | if (parms[pn]->call_type & CALL_REFERENCE) parms[pn]->t->is_pointer--; | |
393 | f << parms[pn]->t->print_real(); | |
394 | parms[pn]->t->is_pointer = is_pointer; | |
395 | } | |
396 | pn++; | |
397 | if (pn < nparms) | |
398 | f << ","; | |
399 | } | |
400 | } | |
401 | ||
402 | ||
403 | // --------------------------------------------------------------------- | |
404 | // void ParmList::print_args(FILE *f) | |
405 | // | |
406 | // Prints a comma separated list of all of the parameter arguments. | |
407 | // ---------------------------------------------------------------------- | |
408 | ||
409 | void ParmList::print_args(FILE *f) { | |
410 | ||
411 | int is_pointer; | |
412 | int pn; | |
413 | pn = 0; | |
414 | while(pn < nparms) { | |
415 | is_pointer = parms[pn]->t->is_pointer; | |
416 | if (parms[pn]->t->is_reference) { | |
417 | if (parms[pn]->t->is_pointer) { | |
418 | parms[pn]->t->is_pointer--; | |
419 | fprintf(f,"%s&", parms[pn]->t->print_full()); | |
420 | parms[pn]->t->is_pointer++; | |
421 | } else { | |
422 | fprintf(f,"%s&", parms[pn]->t->print_full()); | |
423 | } | |
424 | } else { | |
425 | if (parms[pn]->call_type & CALL_VALUE) parms[pn]->t->is_pointer++; | |
426 | if (parms[pn]->call_type & CALL_REFERENCE) parms[pn]->t->is_pointer--; | |
427 | fprintf(f,"%s", parms[pn]->t->print_full()); | |
428 | parms[pn]->t->is_pointer = is_pointer; | |
429 | } | |
430 | fprintf(f,"%s",parms[pn]->name); | |
431 | pn++; | |
432 | if (pn < nparms) | |
433 | fprintf(f,","); | |
434 | } | |
435 | } | |
436 | ||
437 | // ------------------------------------------------------------------- | |
438 | // int check_defined() | |
439 | // | |
440 | // Checks to see if all of the datatypes are defined. | |
441 | // ------------------------------------------------------------------- | |
442 | ||
443 | int ParmList::check_defined() { | |
444 | int a = 0; | |
445 | int i; | |
446 | for (i = 0; i < nparms; i++) { | |
447 | if (parms[i]) { | |
448 | a+=parms[i]->t->check_defined(); | |
449 | } | |
450 | } | |
451 | if (a) return 1; | |
452 | else return 0; | |
453 | } | |
454 | ||
455 | ||
456 | // ------------------------------------------------------------------- | |
457 | // void ParmList::sub_parmnames(String &s) | |
458 | // | |
459 | // Given a string, this function substitutes all of the parameter | |
460 | // names with their internal representation. Used in very special | |
461 | // kinds of typemaps. | |
462 | // ------------------------------------------------------------------- | |
463 | ||
464 | void ParmList::sub_parmnames(String &s) { | |
465 | Parm *p; | |
466 | extern char *emit_local(int i); | |
467 | for (int i = 0; i < nparms; i++) { | |
468 | p = get(i); | |
469 | if (strlen(p->name) > 0) { | |
470 | s.replaceid(p->name, emit_local(i)); | |
471 | } | |
472 | } | |
473 | } | |
474 | ||
475 | ||
476 | ||
477 | ||
478 |