1*b39c5158Smillert /* const2perl.h -- For converting C constants into Perl constant subs
2*b39c5158Smillert * (usually via XS code but can just write Perl code to stdout). */
3*b39c5158Smillert
4*b39c5158Smillert
5*b39c5158Smillert /* #ifndef _INCLUDE_CONST2PERL_H
6*b39c5158Smillert * #define _INCLUDE_CONST2PERL_H 1 */
7*b39c5158Smillert
8*b39c5158Smillert #ifndef CONST2WRITE_PERL /* Default is "const to .xs": */
9*b39c5158Smillert
10*b39c5158Smillert # define newconst( sName, sFmt, xValue, newSV ) \
11*b39c5158Smillert newCONSTSUB( mHvStash, sName, newSV )
12*b39c5158Smillert
13*b39c5158Smillert # define noconst( const ) av_push( mAvExportFail, newSVpv(#const,0) )
14*b39c5158Smillert
15*b39c5158Smillert # define setuv(u) do { \
16*b39c5158Smillert mpSvNew= newSViv(0); sv_setuv(mpSvNew,u); \
17*b39c5158Smillert } while( 0 )
18*b39c5158Smillert
19*b39c5158Smillert #else
20*b39c5158Smillert
21*b39c5158Smillert /* #ifdef __cplusplus
22*b39c5158Smillert * # undef printf
23*b39c5158Smillert * # undef fprintf
24*b39c5158Smillert * # undef stderr
25*b39c5158Smillert * # define stderr (&_iob[2])
26*b39c5158Smillert * # undef iobuf
27*b39c5158Smillert * # undef malloc
28*b39c5158Smillert * #endif */
29*b39c5158Smillert
30*b39c5158Smillert # include <stdio.h> /* Probably already included, but shouldn't hurt */
31*b39c5158Smillert # include <errno.h> /* Possibly already included, but shouldn't hurt */
32*b39c5158Smillert
33*b39c5158Smillert # define newconst( sName, sFmt, xValue, newSV ) \
34*b39c5158Smillert printf( "sub %s () { " sFmt " }\n", sName, xValue )
35*b39c5158Smillert
36*b39c5158Smillert # define noconst( const ) printf( "push @EXPORT_FAIL, '%s';\n", #const )
37*b39c5158Smillert
38*b39c5158Smillert # define setuv(u) /* Nothing */
39*b39c5158Smillert
40*b39c5158Smillert # ifndef IVdf
41*b39c5158Smillert # define IVdf "ld"
42*b39c5158Smillert # endif
43*b39c5158Smillert # ifndef UVuf
44*b39c5158Smillert # define UVuf "lu"
45*b39c5158Smillert # endif
46*b39c5158Smillert # ifndef UVxf
47*b39c5158Smillert # define UVxf "lX"
48*b39c5158Smillert # endif
49*b39c5158Smillert # ifndef NV_DIG
50*b39c5158Smillert # define NV_DIG 15
51*b39c5158Smillert # endif
52*b39c5158Smillert
53*b39c5158Smillert static char *
escquote(const char * sValue)54*b39c5158Smillert escquote( const char *sValue )
55*b39c5158Smillert {
56*b39c5158Smillert Size_t lLen= 1+2*strlen(sValue);
57*b39c5158Smillert char *sEscaped= (char *) malloc( lLen );
58*b39c5158Smillert char *sNext= sEscaped;
59*b39c5158Smillert if( NULL == sEscaped ) {
60*b39c5158Smillert fprintf( stderr, "Can't allocate %"UVuf"-byte buffer (errno=%d)\n",
61*b39c5158Smillert U_V(lLen), _errno );
62*b39c5158Smillert exit( 1 );
63*b39c5158Smillert }
64*b39c5158Smillert while( '\0' != *sValue ) {
65*b39c5158Smillert switch( *sValue ) {
66*b39c5158Smillert case '\'':
67*b39c5158Smillert case '\\':
68*b39c5158Smillert *(sNext++)= '\\';
69*b39c5158Smillert }
70*b39c5158Smillert *(sNext++)= *(sValue++);
71*b39c5158Smillert }
72*b39c5158Smillert *sNext= *sValue;
73*b39c5158Smillert return( sEscaped );
74*b39c5158Smillert }
75*b39c5158Smillert
76*b39c5158Smillert #endif
77*b39c5158Smillert
78*b39c5158Smillert
79*b39c5158Smillert #ifdef __cplusplus
80*b39c5158Smillert
81*b39c5158Smillert class _const2perl {
82*b39c5158Smillert public:
83*b39c5158Smillert char msBuf[64]; /* Must fit sprintf of longest NV */
84*b39c5158Smillert #ifndef CONST2WRITE_PERL
85*b39c5158Smillert HV *mHvStash;
86*b39c5158Smillert AV *mAvExportFail;
87*b39c5158Smillert SV *mpSvNew;
_const2perl(char * sModName)88*b39c5158Smillert _const2perl::_const2perl( char *sModName ) {
89*b39c5158Smillert mHvStash= gv_stashpv( sModName, TRUE );
90*b39c5158Smillert SV **pSv= hv_fetch( mHvStash, "EXPORT_FAIL", 11, TRUE );
91*b39c5158Smillert GV *gv;
92*b39c5158Smillert char *sVarName= (char *) malloc( 15+strlen(sModName) );
93*b39c5158Smillert strcpy( sVarName, sModName );
94*b39c5158Smillert strcat( sVarName, "::EXPORT_FAIL" );
95*b39c5158Smillert gv= gv_fetchpv( sVarName, 1, SVt_PVAV );
96*b39c5158Smillert mAvExportFail= GvAVn( gv );
97*b39c5158Smillert }
98*b39c5158Smillert #else
_const2perl(char * sModName)99*b39c5158Smillert _const2perl::_const2perl( char *sModName ) {
100*b39c5158Smillert ; /* Nothing to do */
101*b39c5158Smillert }
102*b39c5158Smillert #endif /* CONST2WRITE_PERL */
mkconst(char * sName,unsigned long uValue)103*b39c5158Smillert void mkconst( char *sName, unsigned long uValue ) {
104*b39c5158Smillert setuv(uValue);
105*b39c5158Smillert newconst( sName, "0x%"UVxf, uValue, mpSvNew );
106*b39c5158Smillert }
mkconst(char * sName,unsigned int uValue)107*b39c5158Smillert void mkconst( char *sName, unsigned int uValue ) {
108*b39c5158Smillert setuv(uValue);
109*b39c5158Smillert newconst( sName, "0x%"UVxf, uValue, mpSvNew );
110*b39c5158Smillert }
mkconst(char * sName,unsigned short uValue)111*b39c5158Smillert void mkconst( char *sName, unsigned short uValue ) {
112*b39c5158Smillert setuv(uValue);
113*b39c5158Smillert newconst( sName, "0x%"UVxf, uValue, mpSvNew );
114*b39c5158Smillert }
mkconst(char * sName,long iValue)115*b39c5158Smillert void mkconst( char *sName, long iValue ) {
116*b39c5158Smillert newconst( sName, "%"IVdf, iValue, newSViv(iValue) );
117*b39c5158Smillert }
mkconst(char * sName,int iValue)118*b39c5158Smillert void mkconst( char *sName, int iValue ) {
119*b39c5158Smillert newconst( sName, "%"IVdf, iValue, newSViv(iValue) );
120*b39c5158Smillert }
mkconst(char * sName,short iValue)121*b39c5158Smillert void mkconst( char *sName, short iValue ) {
122*b39c5158Smillert newconst( sName, "%"IVdf, iValue, newSViv(iValue) );
123*b39c5158Smillert }
mkconst(char * sName,double nValue)124*b39c5158Smillert void mkconst( char *sName, double nValue ) {
125*b39c5158Smillert newconst( sName, "%s",
126*b39c5158Smillert Gconvert(nValue,NV_DIG,0,msBuf), newSVnv(nValue) );
127*b39c5158Smillert }
mkconst(char * sName,char * sValue)128*b39c5158Smillert void mkconst( char *sName, char *sValue ) {
129*b39c5158Smillert newconst( sName, "'%s'", escquote(sValue), newSVpv(sValue,0) );
130*b39c5158Smillert }
mkconst(char * sName,const void * pValue)131*b39c5158Smillert void mkconst( char *sName, const void *pValue ) {
132*b39c5158Smillert setuv((UV)pValue);
133*b39c5158Smillert newconst( sName, "0x%"UVxf, (UV)(pValue), mpSvNew );
134*b39c5158Smillert }
135*b39c5158Smillert /*#ifdef HAS_QUAD
136*b39c5158Smillert * HAS_QUAD only means pack/unpack deal with them, not that SVs can.
137*b39c5158Smillert * void mkconst( char *sName, Quad_t *qValue ) {
138*b39c5158Smillert * newconst( sName, "0x%"QVxf, qValue, newSVqv(qValue) );
139*b39c5158Smillert * }
140*b39c5158Smillert *#endif / * HAS_QUAD */
141*b39c5158Smillert };
142*b39c5158Smillert
143*b39c5158Smillert #define START_CONSTS( sModName ) _const2perl const2( sModName );
144*b39c5158Smillert #define const2perl( const ) const2.mkconst( #const, const )
145*b39c5158Smillert
146*b39c5158Smillert #else /* __cplusplus */
147*b39c5158Smillert
148*b39c5158Smillert # ifndef CONST2WRITE_PERL
149*b39c5158Smillert # define START_CONSTS( sModName ) \
150*b39c5158Smillert HV *mHvStash= gv_stashpv( sModName, TRUE ); \
151*b39c5158Smillert AV *mAvExportFail; \
152*b39c5158Smillert SV *mpSvNew; \
153*b39c5158Smillert { char *sVarName= malloc( 15+strlen(sModName) ); \
154*b39c5158Smillert GV *gv; \
155*b39c5158Smillert strcpy( sVarName, sModName ); \
156*b39c5158Smillert strcat( sVarName, "::EXPORT_FAIL" ); \
157*b39c5158Smillert gv= gv_fetchpv( sVarName, 1, SVt_PVAV ); \
158*b39c5158Smillert mAvExportFail= GvAVn( gv ); \
159*b39c5158Smillert }
160*b39c5158Smillert # else
161*b39c5158Smillert # define START_CONSTS( sModName ) /* Nothing */
162*b39c5158Smillert # endif
163*b39c5158Smillert
164*b39c5158Smillert #define const2perl( const ) do { \
165*b39c5158Smillert if( const < 0 ) { \
166*b39c5158Smillert newconst( #const, "%"IVdf, const, newSViv((IV)const) ); \
167*b39c5158Smillert } else { \
168*b39c5158Smillert setuv( (UV)const ); \
169*b39c5158Smillert newconst( #const, "0x%"UVxf, const, mpSvNew ); \
170*b39c5158Smillert } \
171*b39c5158Smillert } while( 0 )
172*b39c5158Smillert
173*b39c5158Smillert #endif /* __cplusplus */
174*b39c5158Smillert
175*b39c5158Smillert
176*b39c5158Smillert //Example use:
177*b39c5158Smillert //#include <const2perl.h>
178*b39c5158Smillert // {
179*b39c5158Smillert // START_CONSTS( "Package::Name" ) /* No ";" */
180*b39c5158Smillert //#ifdef $const
181*b39c5158Smillert // const2perl( $const );
182*b39c5158Smillert //#else
183*b39c5158Smillert // noconst( $const );
184*b39c5158Smillert //#endif
185*b39c5158Smillert // }
186*b39c5158Smillert // sub ? { my( $sConstName )= @_;
187*b39c5158Smillert // return $sConstName; # "#ifdef $sConstName"
188*b39c5158Smillert // return FALSE; # Same as above
189*b39c5158Smillert // return "HAS_QUAD"; # "#ifdef HAS_QUAD"
190*b39c5158Smillert // return "#if 5.04 <= VERSION";
191*b39c5158Smillert // return "#if 0";
192*b39c5158Smillert // return 1; # No #ifdef
193*b39c5158Smillert /* #endif / * _INCLUDE_CONST2PERL_H */
194