This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Provide my_strnlen()
[perl5.git] / dist / Devel-PPPort / parts / inc / uv
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__
15 my_strnlen
16 SvUOK
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 __UNDEFINED__  sv_2uv(sv)      ((PL_Sv = (sv)), (UV) (SvNOK(PL_Sv) ? SvNV(PL_Sv) : sv_2nv(PL_Sv)))
32 __UNDEFINED__  SvUVX(sv)       ((UV)SvIVX(sv))
33 __UNDEFINED__  SvUVXx(sv)      SvUVX(sv)
34 __UNDEFINED__  SvUV(sv)        (SvIOK(sv) ? SvUVX(sv) : sv_2uv(sv))
35 __UNDEFINED__  SvUVx(sv)       ((PL_Sv = (sv)), SvUV(PL_Sv))
36
37 /* Hint: sv_uv
38  * Always use the SvUVx() macro instead of sv_uv().
39  */
40 __UNDEFINED__  sv_uv(sv)       SvUVx(sv)
41
42 #if !defined(SvUOK) && defined(SvIOK_UV)
43 #  define SvUOK(sv) SvIOK_UV(sv)
44 #endif
45
46 __UNDEFINED__  XST_mUV(i,v)    (ST(i) = sv_2mortal(newSVuv(v))  )
47 __UNDEFINED__  XSRETURN_UV(v)  STMT_START { XST_mUV(0,v);  XSRETURN(1); } STMT_END
48
49 __UNDEFINED__  PUSHu(u)        STMT_START { sv_setuv(TARG, (UV)(u)); PUSHTARG;  } STMT_END
50 __UNDEFINED__  XPUSHu(u)       STMT_START { sv_setuv(TARG, (UV)(u)); XPUSHTARG; } STMT_END
51
52 #if defined UTF8SKIP
53 __UNDEFINED__  UTF8_SAFE_SKIP(s, e)  (__ASSERT_((e) >= (s))                     \
54                                       ((e) - (s)) <= 0                          \
55                                       ? 0                                       \
56                                       : (((e) - (s)) >= UTF8SKIP(s))            \
57                                          ? ((e) - (s))                          \
58                                          : UTF8SKIP(s))
59 #endif
60
61 #if !defined(my_strnlen)
62 #if { NEED my_strnlen }
63
64 STRLEN
65 my_strnlen(const char *str, Size_t maxlen)
66 {
67     const char *p = str;
68
69     while(maxlen-- && *p)
70         p++;
71
72     return p - str;
73 }
74
75 #endif
76 #endif
77
78 =xsinit
79
80 #define NEED_my_strnlen
81
82 =xsubs
83
84 SV *
85 sv_setuv(uv)
86         UV uv
87         CODE:
88                 RETVAL = newSViv(1);
89                 sv_setuv(RETVAL, uv);
90         OUTPUT:
91                 RETVAL
92
93 SV *
94 newSVuv(uv)
95         UV uv
96         CODE:
97                 RETVAL = newSVuv(uv);
98         OUTPUT:
99                 RETVAL
100
101 UV
102 sv_2uv(sv)
103         SV *sv
104         CODE:
105                 RETVAL = sv_2uv(sv);
106         OUTPUT:
107                 RETVAL
108
109 UV
110 SvUVx(sv)
111         SV *sv
112         CODE:
113                 sv--;
114                 RETVAL = SvUVx(++sv);
115         OUTPUT:
116                 RETVAL
117
118 void
119 XSRETURN_UV()
120         PPCODE:
121                 XSRETURN_UV(42);
122
123 void
124 PUSHu()
125         PREINIT:
126                 dTARG;
127         PPCODE:
128                 TARG = sv_newmortal();
129                 EXTEND(SP, 1);
130                 PUSHu(42);
131                 XSRETURN(1);
132
133 void
134 XPUSHu()
135         PREINIT:
136                 dTARG;
137         PPCODE:
138                 TARG = sv_newmortal();
139                 XPUSHu(43);
140                 XSRETURN(1);
141
142 STRLEN
143 UTF8_SAFE_SKIP(s, adjustment)
144         unsigned char * s
145         int adjustment
146         CODE:
147             /* Instead of passing in an 'e' ptr, use the real end, adjusted */
148             RETVAL = UTF8_SAFE_SKIP(s, s + UTF8SKIP(s) + adjustment);
149         OUTPUT:
150             RETVAL
151
152 STRLEN
153 my_strnlen(s, max)
154         char * s
155         STRLEN max
156         CODE:
157             RETVAL= my_strnlen(s, max);
158         OUTPUT:
159             RETVAL
160
161 =tests plan => 13
162
163 ok(&Devel::PPPort::sv_setuv(42), 42);
164 ok(&Devel::PPPort::newSVuv(123), 123);
165 ok(&Devel::PPPort::sv_2uv("4711"), 4711);
166 ok(&Devel::PPPort::sv_2uv("1735928559"), 1735928559);
167 ok(&Devel::PPPort::SvUVx("1735928559"), 1735928559);
168 ok(&Devel::PPPort::SvUVx(1735928559), 1735928559);
169 ok(&Devel::PPPort::SvUVx(0xdeadbeef), 0xdeadbeef);
170 ok(&Devel::PPPort::XSRETURN_UV(), 42);
171 ok(&Devel::PPPort::PUSHu(), 42);
172 ok(&Devel::PPPort::XPUSHu(), 43);
173 ok(&Devel::PPPort::UTF8_SAFE_SKIP("A", 0), 1);
174 ok(&Devel::PPPort::UTF8_SAFE_SKIP("A", -1), 0);
175 ok(&Devel::PPPort::my_strnlen("abc\0def", 7), 3);