]> git.saurik.com Git - wxWidgets.git/blob - wxPython/wxSWIG/SWIG/parms.cxx
Since I have made several changes to SWIG over the years to accomodate
[wxWidgets.git] / wxPython / wxSWIG / SWIG / parms.cxx
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