1 /* -----------------------------------------------------------------------------
2  * This file is part of SWIG, which is licensed as a whole under version 3
3  * (or any later version) of the GNU General Public License. Some additional
4  * terms also apply to certain portions of SWIG. The full details of the SWIG
5  * license and copyrights can be found in the LICENSE and COPYRIGHT files
6  * included with the SWIG source code as distributed by the SWIG developers
7  * and at http://www.swig.org/legal.html.
8  *
9  * parms.c
10  *
11  * Parameter list class.
12  * ----------------------------------------------------------------------------- */
13 
14 #include "swig.h"
15 
16 /* ------------------------------------------------------------------------
17  * NewParm()
18  *
19  * Create a new parameter from datatype 'type' and name 'name' copying
20  * the file and line number from the Node from_node.
21  * ------------------------------------------------------------------------ */
22 
NewParm(SwigType * type,const_String_or_char_ptr name,Node * from_node)23 Parm *NewParm(SwigType *type, const_String_or_char_ptr name, Node *from_node) {
24   Parm *p = NewParmWithoutFileLineInfo(type, name);
25   Setfile(p, Getfile(from_node));
26   Setline(p, Getline(from_node));
27   return p;
28 }
29 
30 /* ------------------------------------------------------------------------
31  * NewParmWithoutFileLineInfo()
32  *
33  * Create a new parameter from datatype 'type' and name 'name' without any
34  * file / line numbering information.
35  * ------------------------------------------------------------------------ */
36 
NewParmWithoutFileLineInfo(SwigType * type,const_String_or_char_ptr name)37 Parm *NewParmWithoutFileLineInfo(SwigType *type, const_String_or_char_ptr name) {
38   Parm *p = NewHash();
39   set_nodeType(p, "parm");
40   if (type) {
41     SwigType *ntype = Copy(type);
42     Setattr(p, "type", ntype);
43     Delete(ntype);
44   }
45   Setattr(p, "name", name);
46   return p;
47 }
48 
49 /* ------------------------------------------------------------------------
50  * NewParmNode()
51  *
52  * Create a new parameter from datatype 'type' and name and symbol table as
53  * well as file and line number from the 'from_node'.
54  * The resulting Parm will be similar to a Node used for typemap lookups.
55  * ------------------------------------------------------------------------ */
56 
NewParmNode(SwigType * type,Node * from_node)57 Parm *NewParmNode(SwigType *type, Node *from_node) {
58   Parm *p = NewParm(type, Getattr(from_node, "name"), from_node);
59   Setattr(p, "sym:symtab", Getattr(from_node, "sym:symtab"));
60   return p;
61 }
62 
63 /* ------------------------------------------------------------------------
64  * CopyParm()
65  * ------------------------------------------------------------------------ */
66 
CopyParm(Parm * p)67 Parm *CopyParm(Parm *p) {
68   Parm *np = NewHash();
69   Iterator ki;
70   for (ki = First(p); ki.key; ki = Next(ki)) {
71     if (DohIsString(ki.item)) {
72       DOH *c = Copy(ki.item);
73       Setattr(np,ki.key,c);
74       Delete(c);
75     }
76   }
77   Setfile(np, Getfile(p));
78   Setline(np, Getline(p));
79   return np;
80 }
81 
82 /* ------------------------------------------------------------------
83  * CopyParmListMax()
84  * CopyParmList()
85  * ------------------------------------------------------------------ */
86 
CopyParmListMax(ParmList * p,int count)87 ParmList *CopyParmListMax(ParmList *p, int count) {
88   Parm *np;
89   Parm *pp = 0;
90   Parm *fp = 0;
91 
92   if (!p)
93     return 0;
94 
95   while (p) {
96     if (count == 0) break;
97     np = CopyParm(p);
98     if (pp) {
99       set_nextSibling(pp, np);
100       Delete(np);
101     } else {
102       fp = np;
103     }
104     pp = np;
105     p = nextSibling(p);
106     count--;
107   }
108   return fp;
109 }
110 
CopyParmList(ParmList * p)111 ParmList *CopyParmList(ParmList *p) {
112   return CopyParmListMax(p,-1);
113 }
114 
115 /* -----------------------------------------------------------------------------
116  * int ParmList_numrequired().  Return number of required arguments
117  * ----------------------------------------------------------------------------- */
118 
ParmList_numrequired(ParmList * p)119 int ParmList_numrequired(ParmList *p) {
120   int i = 0;
121   while (p) {
122     SwigType *t = Getattr(p, "type");
123     String *value = Getattr(p, "value");
124     if (value)
125       return i;
126     if (!(SwigType_type(t) == T_VOID))
127       i++;
128     else
129       break;
130     p = nextSibling(p);
131   }
132   return i;
133 }
134 
135 /* -----------------------------------------------------------------------------
136  * int ParmList_len()
137  * ----------------------------------------------------------------------------- */
138 
ParmList_len(ParmList * p)139 int ParmList_len(ParmList *p) {
140   int i = 0;
141   while (p) {
142     i++;
143     p = nextSibling(p);
144   }
145   return i;
146 }
147 
148 /* ---------------------------------------------------------------------
149  * get_empty_type()
150  * ---------------------------------------------------------------------- */
151 
get_empty_type()152 static SwigType *get_empty_type() {
153   return NewStringEmpty();
154 }
155 
156 /* ---------------------------------------------------------------------
157  * ParmList_str()
158  *
159  * Generates a string of parameters
160  * ---------------------------------------------------------------------- */
161 
ParmList_str(ParmList * p)162 String *ParmList_str(ParmList *p) {
163   String *out = NewStringEmpty();
164   while (p) {
165     String *type = Getattr(p, "type");
166     String *pstr = SwigType_str(type ? type : get_empty_type(), Getattr(p, "name"));
167     Append(out, pstr);
168     p = nextSibling(p);
169     if (p) {
170       Append(out, ",");
171     }
172     Delete(pstr);
173   }
174   return out;
175 }
176 
177 /* ---------------------------------------------------------------------
178  * ParmList_str_defaultargs()
179  *
180  * Generates a string of parameters including default arguments
181  * ---------------------------------------------------------------------- */
182 
ParmList_str_defaultargs(ParmList * p)183 String *ParmList_str_defaultargs(ParmList *p) {
184   String *out = NewStringEmpty();
185   while (p) {
186     String *value = Getattr(p, "value");
187     String *type = Getattr(p, "type");
188     String *pstr = SwigType_str(type ? type : get_empty_type(), Getattr(p, "name"));
189     Append(out, pstr);
190     if (value) {
191       Printf(out, "=%s", value);
192     }
193     p = nextSibling(p);
194     if (p) {
195       Append(out, ",");
196     }
197     Delete(pstr);
198   }
199   return out;
200 }
201 
202 /* -----------------------------------------------------------------------------
203  * ParmList_str_multibrackets()
204  *
205  * Generates a string of parameters including default arguments adding brackets
206  * if more than one parameter
207  * ----------------------------------------------------------------------------- */
208 
ParmList_str_multibrackets(ParmList * p)209 String *ParmList_str_multibrackets(ParmList *p) {
210   String *out;
211   String *parm_str = ParmList_str_defaultargs(p);
212   if (ParmList_len(p) > 1)
213     out = NewStringf("(%s)", parm_str);
214   else
215     out = NewStringf("%s", parm_str);
216   Delete(parm_str);
217   return out;
218 }
219 
220 /* ---------------------------------------------------------------------
221  * ParmList_protostr()
222  *
223  * Generate a prototype string.
224  * ---------------------------------------------------------------------- */
225 
ParmList_protostr(ParmList * p)226 String *ParmList_protostr(ParmList *p) {
227   String *out = NewStringEmpty();
228   while (p) {
229     String *type = Getattr(p, "type");
230     String *pstr = SwigType_str(type ? type : get_empty_type(), 0);
231     Append(out, pstr);
232     p = nextSibling(p);
233     if (p) {
234       Append(out, ",");
235     }
236     Delete(pstr);
237   }
238   return out;
239 }
240 
241 /* ---------------------------------------------------------------------
242  * ParmList_has_defaultargs()
243  *
244  * Returns 1 if the parameter list passed in is has one or more default
245  * arguments. Otherwise returns 0.
246  * ---------------------------------------------------------------------- */
247 
ParmList_has_defaultargs(ParmList * p)248 int ParmList_has_defaultargs(ParmList *p) {
249   while (p) {
250     if (Getattr(p, "value")) {
251       return 1;
252     }
253     p = nextSibling(p);
254   }
255   return 0;
256 }
257 
258 /* ---------------------------------------------------------------------
259  * ParmList_has_varargs()
260  *
261  * Returns 1 if the parameter list passed in has varargs.
262  * Otherwise returns 0.
263  * ---------------------------------------------------------------------- */
264 
ParmList_has_varargs(ParmList * p)265 int ParmList_has_varargs(ParmList *p) {
266   Parm *lp = 0;
267   while (p) {
268     lp = p;
269     p = nextSibling(p);
270   }
271   return lp ? SwigType_isvarargs(Getattr(lp, "type")) : 0;
272 }
273