1/* -----------------------------------------------------------------------------
2 * See the LICENSE file for information on copyright, usage and redistribution
3 * of SWIG, and the README file for authors - http://www.swig.org/release.html.
4 *
5 * reference.i
6 *
7 * Accept Perl references as pointers
8 * ----------------------------------------------------------------------------- */
9
10/*
11The following methods make Perl references work like simple C
12pointers.  References can only be used for simple input/output
13values, not C arrays however.  It should also be noted that
14REFERENCES are specific to Perl and not supported in other
15scripting languages at this time.
16
17         int            *REFERENCE
18         short          *REFERENCE
19         long           *REFERENCE
20         unsigned int   *REFERENCE
21         unsigned short *REFERENCE
22         unsigned long  *REFERENCE
23         unsigned char  *REFERENCE
24         float          *REFERENCE
25         double         *REFERENCE
26
27For example, suppose you were trying to wrap the following function :
28
29        void neg(double *x) {
30             *x = -(*x);
31        }
32
33You could wrap it with SWIG as follows :
34
35        %include reference.i
36        void neg(double *REFERENCE);
37
38or you can use the %apply directive :
39
40        %include reference.i
41        %apply double *REFERENCE { double *x };
42        void neg(double *x);
43
44Unlike the INOUT mapping described in typemaps.i, this approach directly
45modifies the value of a Perl reference.  Thus, you could use it
46as follows :
47
48       $x = 3;
49       neg(\$x);
50       print "$x\n";         # Should print out -3.
51
52*/
53
54%typemap(in) double *REFERENCE (double dvalue), double &REFERENCE(double dvalue)
55{
56  SV *tempsv;
57  if (!SvROK($input)) {
58    SWIG_croak("expected a reference");
59  }
60  tempsv = SvRV($input);
61  if ((!SvNOK(tempsv)) && (!SvIOK(tempsv))) {
62	printf("Received %d\n", SvTYPE(tempsv));
63	SWIG_croak("Expected a double reference.");
64  }
65  dvalue = SvNV(tempsv);
66  $1 = &dvalue;
67}
68
69%typemap(in) float *REFERENCE (float dvalue), float &REFERENCE(float dvalue)
70{
71  SV *tempsv;
72  if (!SvROK($input)) {
73    SWIG_croak("expected a reference");
74  }
75  tempsv = SvRV($input);
76  if ((!SvNOK(tempsv)) && (!SvIOK(tempsv))) {
77    SWIG_croak("expected a double reference");
78  }
79  dvalue = (float) SvNV(tempsv);
80  $1 = &dvalue;
81}
82
83%typemap(in) int *REFERENCE (int dvalue), int &REFERENCE (int dvalue)
84{
85  SV *tempsv;
86  if (!SvROK($input)) {
87    SWIG_croak("expected a reference");
88  }
89  tempsv = SvRV($input);
90  if (!SvIOK(tempsv)) {
91    SWIG_croak("expected a integer reference");
92  }
93  dvalue = SvIV(tempsv);
94  $1 = &dvalue;
95}
96
97%typemap(in) short *REFERENCE (short dvalue), short &REFERENCE(short dvalue)
98{
99  SV *tempsv;
100  if (!SvROK($input)) {
101    SWIG_croak("expected a reference");
102  }
103  tempsv = SvRV($input);
104  if (!SvIOK(tempsv)) {
105    SWIG_croak("expected a integer reference");
106  }
107  dvalue = (short) SvIV(tempsv);
108  $1 = &dvalue;
109}
110%typemap(in) long *REFERENCE (long dvalue), long &REFERENCE(long dvalue)
111{
112  SV *tempsv;
113  if (!SvROK($input)) {
114    SWIG_croak("expected a reference");
115  }
116  tempsv = SvRV($input);
117  if (!SvIOK(tempsv)) {
118    SWIG_croak("expected a integer reference");
119  }
120  dvalue = (long) SvIV(tempsv);
121  $1 = &dvalue;
122}
123%typemap(in) unsigned int *REFERENCE (unsigned int dvalue), unsigned int &REFERENCE(unsigned int dvalue)
124{
125  SV *tempsv;
126  if (!SvROK($input)) {
127    SWIG_croak("expected a reference");
128  }
129  tempsv = SvRV($input);
130  if (!SvIOK(tempsv)) {
131    SWIG_croak("expected a integer reference");
132  }
133  dvalue = (unsigned int) SvUV(tempsv);
134  $1 = &dvalue;
135}
136%typemap(in) unsigned short *REFERENCE (unsigned short dvalue), unsigned short &REFERENCE(unsigned short dvalue)
137{
138  SV *tempsv;
139  if (!SvROK($input)) {
140    SWIG_croak("expected a reference");
141  }
142  tempsv = SvRV($input);
143  if (!SvIOK(tempsv)) {
144    SWIG_croak("expected a integer reference");
145  }
146  dvalue = (unsigned short) SvUV(tempsv);
147  $1 = &dvalue;
148}
149%typemap(in) unsigned long *REFERENCE (unsigned long dvalue), unsigned long &REFERENCE(unsigned long dvalue)
150{
151  SV *tempsv;
152  if (!SvROK($input)) {
153    SWIG_croak("expected a reference");
154  }
155  tempsv = SvRV($input);
156  if (!SvIOK(tempsv)) {
157    SWIG_croak("expected a integer reference");
158  }
159  dvalue = (unsigned long) SvUV(tempsv);
160  $1 = &dvalue;
161}
162
163%typemap(in) unsigned char *REFERENCE (unsigned char dvalue), unsigned char &REFERENCE(unsigned char dvalue)
164{
165  SV *tempsv;
166  if (!SvROK($input)) {
167    SWIG_croak("expected a reference");
168  }
169  tempsv = SvRV($input);
170  if (!SvIOK(tempsv)) {
171    SWIG_croak("expected a integer reference");
172  }
173  dvalue = (unsigned char) SvUV(tempsv);
174  $1 = &dvalue;
175}
176
177%typemap(in) signed char *REFERENCE (signed char dvalue), signed char &REFERENCE(signed char dvalue)
178{
179  SV *tempsv;
180  if (!SvROK($input)) {
181    SWIG_croak("expected a reference");
182  }
183  tempsv = SvRV($input);
184  if (!SvIOK(tempsv)) {
185    SWIG_croak("expected a integer reference");
186  }
187  dvalue = (signed char) SvIV(tempsv);
188  $1 = &dvalue;
189}
190
191%typemap(in) bool *REFERENCE (bool dvalue), bool &REFERENCE(bool dvalue)
192{
193  SV *tempsv;
194  if (!SvROK($input)) {
195    SWIG_croak("expected a reference");
196  }
197  tempsv = SvRV($input);
198  if (!SvIOK(tempsv)) {
199    SWIG_croak("expected a integer reference");
200  }
201  dvalue = (bool) SvIV(tempsv);
202  $1 = &dvalue;
203}
204
205%typemap(typecheck) int *REFERENCE, int &REFERENCE,
206                    short *REFERENCE, short &REFERENCE,
207                    long *REFERENCE, long  &REFERENCE,
208                    signed char *REFERENCE, signed char &REFERENCE,
209                    bool *REFERENCE, bool &REFERENCE
210{
211  $1 = SvROK($input) && SvIOK(SvRV($input));
212}
213%typemap(typecheck) double *REFERENCE, double &REFERENCE,
214                    float *REFERENCE, float &REFERENCE
215{
216  $1 = SvROK($input);
217  if($1) {
218    SV *tmpsv = SvRV($input);
219    $1 = SvNOK(tmpsv) || SvIOK(tmpsv);
220  }
221}
222%typemap(typecheck) unsigned int   *REFERENCE, unsigned int &REFERENCE,
223                    unsigned short *REFERENCE, unsigned short &REFERENCE,
224                    unsigned long  *REFERENCE, unsigned long &REFERENCE,
225                    unsigned char  *REFERENCE, unsigned char &REFERENCE
226{
227  $1 = SvROK($input);
228  if($1) {
229    SV *tmpsv = SvRV($input);
230    $1 = SvUOK(tmpsv) || SvIOK(tmpsv);
231  }
232}
233
234%typemap(argout) double *REFERENCE, double &REFERENCE,
235                 float  *REFERENCE, float &REFERENCE
236{
237  SV *tempsv;
238  tempsv = SvRV($arg);
239  if (!$1) SWIG_croak("expected a reference");
240  sv_setnv(tempsv, (double) *$1);
241}
242
243%typemap(argout)       int            *REFERENCE, int &REFERENCE,
244                       short          *REFERENCE, short &REFERENCE,
245                       long           *REFERENCE, long  &REFERENCE,
246                       signed char    *REFERENCE, signed char &REFERENCE,
247                       bool           *REFERENCE, bool &REFERENCE
248{
249  SV *tempsv;
250  tempsv = SvRV($input);
251  if (!$1) SWIG_croak("expected a reference");
252  sv_setiv(tempsv, (IV) *$1);
253}
254
255%typemap(argout)       unsigned int   *REFERENCE, unsigned int &REFERENCE,
256                       unsigned short *REFERENCE, unsigned short &REFERENCE,
257                       unsigned long  *REFERENCE, unsigned long &REFERENCE,
258                       unsigned char  *REFERENCE, unsigned char &REFERENCE
259{
260  SV *tempsv;
261  tempsv = SvRV($input);
262  if (!$1) SWIG_croak("expected a reference");
263  sv_setuv(tempsv, (UV) *$1);
264}
265