1################################################################################
2##
3##  Version 3.x, Copyright (C) 2004-2013, Marcus Holland-Moritz.
4##  Version 2.x, Copyright (C) 2001, Paul Marquess.
5##  Version 1.x, Copyright (C) 1999, Kenneth Albanowski.
6##
7##  This program is free software; you can redistribute it and/or
8##  modify it under the same terms as Perl itself.
9##
10################################################################################
11
12=provides
13
14__UNDEFINED__
15my_strnlen
16SvUOK
17
18=implementation
19
20__UNDEFINED__  sv_setuv(sv, uv)                     \
21               STMT_START {                         \
22                 UV TeMpUv = uv;                    \
23                 if (TeMpUv <= IV_MAX)              \
24                   sv_setiv(sv, TeMpUv);            \
25                 else                               \
26                   sv_setnv(sv, (double)TeMpUv);    \
27               } STMT_END
28
29__UNDEFINED__  newSVuv(uv)     ((uv) <= IV_MAX ? newSViv((IV)uv) : newSVnv((NV)uv))
30
31#if defined(PERL_USE_GCC_BRACE_GROUPS)
32__UNDEFINED__  sv_2uv(sv)      ({ SV *_sv = (sv); (UV) (SvNOK(_sv) ? SvNV(_sv) : sv_2nv(_sv)); })
33#else
34__UNDEFINED__  sv_2uv(sv)      ((PL_Sv = (sv)), (UV) (SvNOK(PL_Sv) ? SvNV(PL_Sv) : sv_2nv(PL_Sv)))
35#endif
36
37__UNDEFINED__  SvUVX(sv)       ((UV)SvIVX(sv))
38__UNDEFINED__  SvUVXx(sv)      SvUVX(sv)
39__UNDEFINED__  SvUV(sv)        (SvIOK(sv) ? SvUVX(sv) : sv_2uv(sv))
40
41#if defined(PERL_USE_GCC_BRACE_GROUPS)
42__UNDEFINED__  SvUVx(sv)       ({ SV *_sv = (sv)); SvUV(_sv); })
43#else
44__UNDEFINED__  SvUVx(sv)       ((PL_Sv = (sv)), SvUV(PL_Sv))
45#endif
46
47/* Hint: sv_uv
48 * Always use the SvUVx() macro instead of sv_uv().
49 */
50/* Replace sv_uv with SvUVx */
51__UNDEFINED__  sv_uv(sv)       SvUVx(sv)
52
53#if !defined(SvUOK) && defined(SvIOK_UV)
54#  define SvUOK(sv) SvIOK_UV(sv)
55#endif
56
57__UNDEFINED__  XST_mUV(i,v)    (ST(i) = sv_2mortal(newSVuv(v))  )
58__UNDEFINED__  XSRETURN_UV(v)  STMT_START { XST_mUV(0,v);  XSRETURN(1); } STMT_END
59
60__UNDEFINED__  PUSHu(u)        STMT_START { sv_setuv(TARG, (UV)(u)); PUSHTARG;  } STMT_END
61__UNDEFINED__  XPUSHu(u)       STMT_START { sv_setuv(TARG, (UV)(u)); XPUSHTARG; } STMT_END
62
63#if !defined(my_strnlen)
64#if { NEED my_strnlen }
65
66Size_t
67my_strnlen(const char *str, Size_t maxlen)
68{
69    const char *p = str;
70
71    while(maxlen-- && *p)
72        p++;
73
74    return p - str;
75}
76
77#endif
78#endif
79
80=xsinit
81
82#define NEED_my_strnlen
83
84=xsubs
85
86SV *
87sv_setuv(uv)
88        UV uv
89        CODE:
90                RETVAL = newSViv(1);
91                sv_setuv(RETVAL, uv);
92        OUTPUT:
93                RETVAL
94
95SV *
96newSVuv(uv)
97        UV uv
98        CODE:
99                RETVAL = newSVuv(uv);
100        OUTPUT:
101                RETVAL
102
103UV
104sv_2uv(sv)
105        SV *sv
106        CODE:
107                RETVAL = sv_2uv(sv);
108        OUTPUT:
109                RETVAL
110
111UV
112SvUVx(sv)
113        SV *sv
114        CODE:
115                sv--;
116                RETVAL = SvUVx(++sv);
117        OUTPUT:
118                RETVAL
119
120void
121XSRETURN_UV()
122        PPCODE:
123                XSRETURN_UV(42);
124
125void
126PUSHu()
127        PREINIT:
128                dTARG;
129        PPCODE:
130                TARG = sv_newmortal();
131                EXTEND(SP, 1);
132                PUSHu(42);
133                XSRETURN(1);
134
135void
136XPUSHu()
137        PREINIT:
138                dTARG;
139        PPCODE:
140                TARG = sv_newmortal();
141                XPUSHu(43);
142                XSRETURN(1);
143
144STRLEN
145my_strnlen(s, max)
146        char * s
147        STRLEN max
148        CODE:
149            RETVAL= my_strnlen(s, max);
150        OUTPUT:
151            RETVAL
152
153=tests plan => 11
154
155BEGIN { require warnings if ivers($]) > ivers('5.006') }
156
157is(&Devel::PPPort::sv_setuv(42), 42);
158is(&Devel::PPPort::newSVuv(123), 123);
159is(&Devel::PPPort::sv_2uv("4711"), 4711);
160is(&Devel::PPPort::sv_2uv("1735928559"), 1735928559);
161is(&Devel::PPPort::SvUVx("1735928559"), 1735928559);
162is(&Devel::PPPort::SvUVx(1735928559), 1735928559);
163is(&Devel::PPPort::SvUVx(0xdeadbeef), 0xdeadbeef);
164is(&Devel::PPPort::XSRETURN_UV(), 42);
165is(&Devel::PPPort::PUSHu(), 42);
166is(&Devel::PPPort::XPUSHu(), 43);
167is(&Devel::PPPort::my_strnlen("abc\0def", 7), 3);
168