Add Tim Jenness' XS::Typemap for exercizing the standard typemap.
[p5sagit/p5-mst-13.2.git] / ext / XS / Typemap / Typemap.xs
1
2 /*
3    XS code to test the typemap entries
4
5    Copyright (C) 2001 Tim Jenness.
6    All Rights Reserved
7
8 */
9
10 #include "EXTERN.h"   /* std perl include */
11 #include "perl.h"     /* std perl include */
12 #include "XSUB.h"     /* XSUB include */
13
14 /* Prototypes for external functions */
15 FILE * xsfopen( const char * );
16 int xsfclose( FILE * );
17 int xsfprintf( FILE *, const char *);
18
19 /* Type definitions required for the XS typemaps */
20 typedef SV * SVREF; /* T_SVREF */
21 typedef int SysRet; /* T_SYSRET */
22 typedef int Int;    /* T_INT */
23 typedef int intRef; /* T_PTRREF */
24 typedef int intObj; /* T_PTROBJ */
25 typedef int intRefIv; /* T_REF_IV_PTR */
26 typedef int intArray; /* T_ARRAY */
27 typedef short shortOPQ;   /* T_OPAQUE */
28 typedef int intOpq;   /* T_OPAQUEPTR */
29
30 /* Some static memory for the tests */
31 I32 anint;
32 intRef anintref;
33 intObj anintobj;
34 intRefIv anintrefiv;
35 intOpq anintopq;
36
37 /* Helper functions */
38
39 /* T_ARRAY - allocate some memory */
40 intArray * intArrayPtr( int nelem ) {
41     intArray * array;
42     New(0, array, nelem, intArray);
43     return array;
44 }
45
46
47 MODULE = XS::Typemap   PACKAGE = XS::Typemap
48
49 PROTOTYPES: DISABLE
50
51 =head1 TYPEMAPS
52
53 Each C type is represented by an entry in the typemap file that
54 is responsible for converting perl variables (SV, AV, HV and CV) to
55 and from that type.
56
57 =over 4
58
59 =item T_SV
60
61 This simply passes the C representation of the Perl variable (an SV*)
62 in and out of the XS layer. This can be used if the C code wants
63 to deal directly with the Perl variable.
64
65 =cut
66
67 SV *
68 T_SV( sv )
69   SV * sv
70  CODE:
71   /* create a new sv for return that is a copy of the input
72      do not simply copy the pointer since the SV will be marked
73      mortal by the INPUT typemap when it is pushed back onto the stack */
74   RETVAL = sv_mortalcopy( sv );
75   /* increment the refcount since the default INPUT typemap mortalizes
76      by default and we don't want to decrement the ref count twice
77      by mistake */
78   SvREFCNT_inc(RETVAL);
79  OUTPUT:
80   RETVAL
81
82 =item T_SVREF
83
84 Used to pass in and return a reference to an SV.
85
86 =cut
87
88 SVREF
89 T_SVREF( svref )
90   SVREF svref
91  CODE:
92   RETVAL = svref;
93  OUTPUT:
94   RETVAL
95
96 =item T_AVREF
97
98 From the perl level this is a reference to a perl array.
99 From the C level this is a pointer to an AV.
100
101 =cut
102
103 AV *
104 T_AVREF( av )
105   AV * av
106  CODE:
107   RETVAL = av;
108  OUTPUT:
109   RETVAL
110
111 =item T_HVREF
112
113 From the perl level this is a reference to a perl hash.
114 From the C level this is a pointer to a HV.
115
116 =cut
117
118 HV *
119 T_HVREF( hv )
120   HV * hv
121  CODE:
122   RETVAL = hv;
123  OUTPUT:
124   RETVAL
125
126 =item T_CVREF
127
128 From the perl level this is a reference to a perl subroutine
129 (e.g. $sub = sub { 1 };). From the C level this is a pointer
130 to a CV.
131
132 =cut
133
134 CV *
135 T_CVREF( cv )
136   CV * cv
137  CODE:
138   RETVAL = cv;
139  OUTPUT:
140   RETVAL
141
142
143 =item T_SYSRET
144
145 The T_SYSRET typemap is used to process return values from system calls.
146 It is only meaningful when passing values from C to perl (there is
147 no concept of passing a system return value from Perl to C).
148
149 System calls return -1 on error (setting ERRNO with the reason)
150 and (usually) 0 on success. If the return value is -1 this typemap
151 returns C<undef>. If the return value is not -1, this typemap
152 translates a 0 (perl false) to "0 but true" (which
153 is perl true) or returns the value itself, to indicate that the
154 command succeeded.
155
156 The L<POSIX|POSIX> module makes extensive use of this type.
157
158 =cut
159
160 # Test a successful return
161
162 SysRet
163 T_SYSRET_pass()
164  CODE:
165   RETVAL = 0;
166  OUTPUT:
167   RETVAL
168
169 # Test failure
170
171 SysRet
172 T_SYSRET_fail()
173  CODE:
174   RETVAL = -1;
175  OUTPUT:
176   RETVAL
177
178 =item T_UV
179
180 An unsigned integer.
181
182 =cut
183
184 unsigned int
185 T_UV( uv )
186   unsigned int uv
187  CODE:
188   RETVAL = uv;
189  OUTPUT:
190   RETVAL
191
192 =item T_IV
193
194 A signed integer. This is cast to the required  integer type when
195 passed to C and converted to a IV when passed back to Perl.
196
197 =cut
198
199 long
200 T_IV( iv )
201   long iv
202  CODE:
203   RETVAL = iv;
204  OUTPUT:
205   RETVAL
206
207 =item T_INT
208
209 A signed integer. This typemap converts the Perl value to a native
210 integer type (the C<int> type on the current platform). When returning
211 the value to perl it is processed in the same way as for T_IV.
212
213 Its behaviour is identical to using an C<int> type in XS with T_IV.
214
215 =item T_ENUM
216
217 An enum value. Used to transfer an enum component
218 from C. There is no reason to pass an enum value to C since
219 it is stored as an IV inside perl.
220
221 =cut
222
223 # The test should return the value for SVt_PVHV.
224 # 11 at the present time but we can't not rely on this
225 # for testing purposes.
226
227 svtype
228 T_ENUM()
229  CODE:
230   RETVAL = SVt_PVHV;
231  OUTPUT:
232   RETVAL
233
234 =item T_BOOL
235
236 A boolean type. This can be used to pass true and false values to and
237 from C.
238
239 =cut
240
241 bool
242 T_BOOL( in )
243   bool in
244  CODE:
245   RETVAL = in;
246  OUTPUT:
247   RETVAL
248
249 =item T_U_INT
250
251 This is for unsigned integers. It is equivalent to using T_UV
252 but explicitly casts the variable to type C<unsigned int>.
253 The default type for C<unsigned int> is T_UV.
254
255 =item T_SHORT
256
257 Short integers. This is equivalent to T_IV but explicitly casts
258 the return to type C<short>. The default typemap for C<short>
259 is T_IV.
260
261 =item T_U_SHORT
262
263 Unsigned short integers. This is equivalent to T_UV but explicitly
264 casts the return to type C<unsigned short>. The default typemap for
265 C<unsigned short> is T_UV.
266
267 T_U_SHORT is used for type C<U16> in the standard typemap.
268
269 =cut
270
271 U16
272 T_U_SHORT( in )
273   U16 in
274  CODE:
275   RETVAL = in;
276  OUTPUT:
277   RETVAL
278
279
280 =item T_LONG
281
282 Long integers. This is equivalent to T_IV but explicitly casts
283 the return to type C<long>. The default typemap for C<long>
284 is T_IV.
285
286 =item T_U_LONG
287
288 Unsigned long integers. This is equivalent to T_UV but explicitly
289 casts the return to type C<unsigned long>. The default typemap for
290 C<unsigned long> is T_UV.
291
292 T_U_LONG is used for type C<U32> in the standard typemap.
293
294 =cut
295
296 U32
297 T_U_LONG( in )
298   U32 in
299  CODE:
300   RETVAL = in;
301  OUTPUT:
302   RETVAL
303
304 =item T_CHAR
305
306 Single 8-bit characters.
307
308 =cut
309
310 char
311 T_CHAR( in );
312   char in
313  CODE:
314   RETVAL = in;
315  OUTPUT:
316   RETVAL
317
318
319 =item T_U_CHAR
320
321 An unsigned byte.
322
323 =cut
324
325 unsigned char
326 T_U_CHAR( in );
327   unsigned char in
328  CODE:
329   RETVAL = in;
330  OUTPUT:
331   RETVAL
332
333
334 =item T_FLOAT
335
336 A floating point number. This typemap guarantees to return a variable
337 cast to a C<float>.
338
339 =cut
340
341 float
342 T_FLOAT( in )
343   float in
344  CODE:
345   RETVAL = in;
346  OUTPUT:
347   RETVAL
348
349 =item T_NV
350
351 A Perl floating point number. Similar to T_IV and T_UV in that the
352 return type is cast to the requested numeric type rather than
353 to a specific type.
354
355 =cut
356
357 NV
358 T_NV( in )
359   NV in
360  CODE:
361   RETVAL = in;
362  OUTPUT:
363   RETVAL
364
365 =item T_DOUBLE
366
367 A double precision floating point number. This typemap guarantees to
368 return a variable cast to a C<double>.
369
370 =cut
371
372 double
373 T_DOUBLE( in )
374   double in
375  CODE:
376   RETVAL = in;
377  OUTPUT:
378   RETVAL
379
380 =item T_PV
381
382 A string (char *).
383
384 =cut
385
386 char *
387 T_PV( in )
388   char * in
389  CODE:
390   RETVAL = in;
391  OUTPUT:
392   RETVAL
393
394 =item T_PTR
395
396 A memory address (pointer). Typically associated with a C<void *>
397 type.
398
399 =cut
400
401 # Pass in a value. Store the value in some static memory and
402 # then return the pointer
403
404 void *
405 T_PTR_OUT( in )
406   int in;
407  CODE:
408   anint = in;
409   RETVAL = &anint;
410  OUTPUT:
411   RETVAL
412
413 # pass in the pointer and return the value
414
415 int
416 T_PTR_IN( ptr )
417   void * ptr
418  CODE:
419   RETVAL = *(int *)ptr;
420  OUTPUT:
421   RETVAL
422
423 =item T_PTRREF
424
425 Similar to T_PTR except that the pointer is stored in a scalar and the
426 reference to that scalar is returned to the caller. This can be used
427 to hide the actual pointer value from the programmer since it is usually
428 not required directly from within perl.
429
430 The typemap checks that a scalar reference is passed from perl to XS.
431
432 =cut
433
434 # Similar test to T_PTR
435 # Pass in a value. Store the value in some static memory and
436 # then return the pointer
437
438 intRef *
439 T_PTRREF_OUT( in )
440   intRef in;
441  CODE:
442   anintref = in;
443   RETVAL = &anintref;
444  OUTPUT:
445   RETVAL
446
447 # pass in the pointer and return the value
448
449 intRef
450 T_PTRREF_IN( ptr )
451   intRef * ptr
452  CODE:
453   RETVAL = *ptr;
454  OUTPUT:
455   RETVAL
456
457
458
459 =item T_PTROBJ
460
461 Similar to T_PTRREF except that the reference is blessed into a class.
462 This allows the pointer to be used as an object. Most commonly used to
463 deal with C structs. The typemap checks that the perl object passed
464 into the XS routine is of the correct class (or part of a subclass).
465
466 The pointer is blessed into a class that is derived from the name
467 of type of the pointer but with all '*' in the name replaced with
468 'Ptr'.
469
470 =cut
471
472 # Similar test to T_PTRREF
473 # Pass in a value. Store the value in some static memory and
474 # then return the pointer
475
476 intObj *
477 T_PTROBJ_OUT( in )
478   intObj in;
479  CODE:
480   anintobj = in;
481   RETVAL = &anintobj;
482  OUTPUT:
483   RETVAL
484
485 # pass in the pointer and return the value
486
487 MODULE = XS::Typemap  PACKAGE = intObjPtr
488
489 intObj
490 T_PTROBJ_IN( ptr )
491   intObj * ptr
492  CODE:
493   RETVAL = *ptr;
494  OUTPUT:
495   RETVAL
496
497 MODULE = XS::Typemap PACKAGE = XS::Typemap
498
499 =item T_REF_IV_REF
500
501 NOT YET
502
503 =item T_REF_IV_PTR
504
505 Similar to T_PTROBJ in that the pointer is blessed into a scalar object.
506 The difference is that when the object is passed back into XS it must be
507 of the correct type (inheritance is not supported).
508
509 The pointer is blessed into a class that is derived from the name
510 of type of the pointer but with all '*' in the name replaced with
511 'Ptr'.
512
513 =cut
514
515 # Similar test to T_PTROBJ
516 # Pass in a value. Store the value in some static memory and
517 # then return the pointer
518
519 intRefIv *
520 T_REF_IV_PTR_OUT( in )
521   intRefIv in;
522  CODE:
523   anintrefiv = in;
524   RETVAL = &anintrefiv;
525  OUTPUT:
526   RETVAL
527
528 # pass in the pointer and return the value
529
530 MODULE = XS::Typemap  PACKAGE = intRefIvPtr
531
532 intRefIv
533 T_REF_IV_PTR_IN( ptr )
534   intRefIv * ptr
535  CODE:
536   RETVAL = *ptr;
537  OUTPUT:
538   RETVAL
539
540
541 MODULE = XS::Typemap PACKAGE = XS::Typemap
542
543 =item T_PTRDESC
544
545 NOT YET
546
547 =item T_REFREF
548
549 NOT YET
550
551 =item T_REFOBJ
552
553 NOT YET
554
555 =item T_OPAQUEPTR
556
557 This can be used to store a pointer in the string component of the
558 SV. Unlike T_PTR which stores the pointer in an IV that can be
559 printed, here the representation of the pointer is irrelevant and the
560 bytes themselves are just stored in the SV. If the pointer is
561 represented by 4 bytes then those 4 bytes are stored in the SV (and
562 length() will report a value of 4). This makes use of the fact that a
563 perl scalar can store arbritray data in its PV component.
564
565 In principal the unpack() command can be used to convert the pointer
566 to a number.
567
568 =cut
569
570 intOpq *
571 T_OPAQUEPTR_IN( val )
572   intOpq val
573  CODE:
574   anintopq = val;
575   RETVAL = &anintopq;
576  OUTPUT:
577   RETVAL
578
579 intOpq
580 T_OPAQUEPTR_OUT( ptr )
581   intOpq * ptr
582  CODE:
583   RETVAL = *ptr;
584  OUTPUT:
585   RETVAL
586
587 =item T_OPAQUE
588
589 This can be used to store pointers to non-pointer types in an SV. It
590 is similar to T_OPAQUEPTR except that the typemap retrieves the
591 pointer itself rather than assuming that it is to be given a
592 pointer. This approach hides the pointer as a byte stream in the
593 string part of the SV rather than making the actual pointer value
594 available to Perl.
595
596 There is no reason to use T_OPAQUE to pass the data to C. Use
597 T_OPAQUEPTR to do that since once the pointer is stored in the SV
598 T_OPAQUE and T_OPAQUEPTR are identical.
599
600 =cut
601
602 shortOPQ
603 T_OPAQUE_IN( val )
604   int val
605  CODE:
606   RETVAL = (shortOPQ)val;
607  OUTPUT:
608   RETVAL
609
610 =item Implicit array
611
612 xsubpp supports a special syntax for returning
613 packed C arrays to perl. If the XS return type is given as
614
615   array(type, nelem)
616
617 xsubpp will copy the contents of C<nelem * sizeof(type)> bytes from
618 RETVAL to an SV and push it onto the stack. This is only really useful
619 if the number of items to be returned is known at compile time and you
620 don't mind having a string of bytes in your SV.  Use T_ARRAY to push a
621 variable number of arguments onto the return stack (they won't be
622 packed as a single string though).
623
624 This is similar to using T_OPAQUEPTR but can be used to process more than
625 one element.
626
627 =cut
628
629 array(int,3)
630 T_OPAQUE_array( a,b,c)
631   int a
632   int b
633   int c
634  PREINIT:
635   int array[2];
636  CODE:
637   array[0] = a;
638   array[1] = b;
639   array[2] = c;
640   RETVAL = array;
641  OUTPUT:
642   RETVAL
643
644
645 =item T_PACKED
646
647 NOT YET
648
649 =item T_PACKEDARRAY
650
651 NOT YET
652
653 =item T_DATAUNIT
654
655 NOT YET
656
657 =item T_CALLBACK
658
659 NOT YET
660
661 =item T_ARRAY
662
663 This is used to convert the perl argument list to a C array
664 and for pushing the contents of a C array onto the perl
665 argument stack.
666
667 The usual calling signature is
668
669   @out = array_func( @in );
670
671 Any number of arguments can occur in the list before the array but
672 the input and output arrays must be the last elements in the list.
673
674 When used to pass a perl list to C the XS writer must provide a
675 function (named after the array type but with 'Ptr' substituted for
676 '*') to allocate the memory required to hold the list. A pointer
677 should be returned. It is up to the XS writer to free the memory on
678 exit from the function. The variable C<ix_$var> is set to the number
679 of elements in the new array.
680
681 When returning a C array to Perl the XS writer must provide an integer
682 variable called C<size_$var> containing the number of elements in the
683 array. This is used to determine how many elements should be pushed
684 onto the return argument stack. This is not required on input since
685 Perl knows how many arguments are on the stack when the routine is
686 called. Ordinarily this variable would be called C<size_RETVAL>.
687
688 Additionally, the type of each element is determined from the type of
689 the array. If the array uses type C<intArray *> xsubpp will
690 automatically work out that it contains variables of type C<int> and
691 use that typemap entry to perform the copy of each element. All
692 pointer '*' and 'Array' tags are removed from the name to determine
693 the subtype.
694
695 =cut
696
697 # Test passes in an integer array and returns it along with
698 # the number of elements
699 # Pass in a dummy value to test offsetting
700
701 # Problem is that xsubpp does XSRETURN(1) because we arent
702 # using PPCODE. This means that only the first element
703 # is returned. KLUGE this by using CLEANUP to return before the
704 # end.
705
706 intArray *
707 T_ARRAY( dummy, array, ... )
708   int dummy = NO_INIT
709   intArray * array
710  PREINIT:
711   U32 size_RETVAL;
712  CODE:
713   size_RETVAL = ix_array;
714   RETVAL = array;
715  OUTPUT:
716   RETVAL
717  CLEANUP:
718   Safefree(array);
719   XSRETURN(size_RETVAL);
720
721
722 =item T_STDIO
723
724 This is used for passing perl filehandles to and from C using
725 C<FILE *> structures.
726
727 =cut
728
729 FILE *
730 T_STDIO_open( file )
731   const char * file
732  CODE:
733   RETVAL = xsfopen( file );
734  OUTPUT:
735   RETVAL
736
737 SysRet
738 T_STDIO_close( stream )
739   FILE * stream
740  CODE:
741   RETVAL = xsfclose( stream );
742  OUTPUT:
743   RETVAL
744
745 int
746 T_STDIO_print( stream, string )
747   FILE * stream
748   const char * string
749  CODE:
750   RETVAL = xsfprintf( stream, string );
751  OUTPUT:
752   RETVAL
753
754
755 =item T_IN
756
757 NOT YET
758
759 =item T_INOUT
760
761 This is used for passing perl filehandles to and from C using
762 C<PerlIO *> structures. The file handle can used for reading and
763 writing.
764
765 See L<perliol> for more information on the Perl IO abstraction
766 layer. Perl must have been built with C<-Duseperlio>.
767
768 =item T_OUT
769
770 NOT YET
771
772 =back
773
774 =cut
775