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