line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
/* |
2
|
|
|
|
|
|
|
* |
3
|
|
|
|
|
|
|
* Copyright (c) 2018, cPanel, LLC. |
4
|
|
|
|
|
|
|
* All rights reserved. |
5
|
|
|
|
|
|
|
* http://cpanel.net |
6
|
|
|
|
|
|
|
* |
7
|
|
|
|
|
|
|
* This is free software; you can redistribute it and/or modify it under the |
8
|
|
|
|
|
|
|
* same terms as Perl itself. |
9
|
|
|
|
|
|
|
* |
10
|
|
|
|
|
|
|
*/ |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
#include |
13
|
|
|
|
|
|
|
#include |
14
|
|
|
|
|
|
|
#include |
15
|
|
|
|
|
|
|
#include |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
#define _REPLACE_BUFFER_SIZE 64 |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
#define IS_SPACE(c) c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == '\f' |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
SV *_replace_str( SV *sv, SV *map ); |
22
|
|
|
|
|
|
|
SV *_trim_sv( SV *sv ); |
23
|
|
|
|
|
|
|
|
24
|
13
|
|
|
|
|
|
SV *_trim_sv( SV *sv ) { |
25
|
|
|
|
|
|
|
|
26
|
13
|
|
|
|
|
|
int len = SvCUR(sv); |
27
|
13
|
|
|
|
|
|
char *str = SvPVX(sv);; |
28
|
13
|
|
|
|
|
|
char *end = str + len - 1; |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
// Skip whitespace at front... |
31
|
32
|
100
|
|
|
|
|
while ( IS_SPACE( (unsigned char) *str) ) { |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
32
|
19
|
|
|
|
|
|
++str; |
33
|
19
|
|
|
|
|
|
--len; |
34
|
|
|
|
|
|
|
} |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
// Trim at end... |
37
|
32
|
50
|
|
|
|
|
while (end > str && isspace( (unsigned char) *end) ) { |
|
|
100
|
|
|
|
|
|
38
|
19
|
|
|
|
|
|
*end--;// = 0; |
39
|
19
|
|
|
|
|
|
--len; |
40
|
|
|
|
|
|
|
} |
41
|
|
|
|
|
|
|
|
42
|
13
|
|
|
|
|
|
return newSVpvn_flags( str, len, SvUTF8(sv) ); |
43
|
|
|
|
|
|
|
} |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
|
46
|
14
|
|
|
|
|
|
SV *_replace_str( SV *sv, SV *map ) { |
47
|
14
|
|
|
|
|
|
char buffer[_REPLACE_BUFFER_SIZE] = { 0 }; |
48
|
14
|
|
|
|
|
|
char *src = SvPVX(sv); |
49
|
14
|
|
|
|
|
|
int len = SvCUR(sv); |
50
|
14
|
|
|
|
|
|
int i = 0; |
51
|
14
|
|
|
|
|
|
char *ptr = src; |
52
|
14
|
|
|
|
|
|
char *str = buffer; /* the new string we are going to use */ |
53
|
|
|
|
|
|
|
char *tmp; /* used to grow */ |
54
|
14
|
|
|
|
|
|
int str_size = _REPLACE_BUFFER_SIZE; /* we start with the buffer */ |
55
|
14
|
|
|
|
|
|
int ix_newstr = 0; |
56
|
|
|
|
|
|
|
AV *mapav; |
57
|
|
|
|
|
|
|
SV *reply; |
58
|
|
|
|
|
|
|
|
59
|
14
|
50
|
|
|
|
|
if ( !map || SvTYPE(map) != SVt_RV || SvTYPE(SvRV(map)) != SVt_PVAV |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
60
|
13
|
0
|
|
|
|
|
|| AvFILL( SvRV(map) ) <= 0 |
|
|
100
|
|
|
|
|
|
61
|
|
|
|
|
|
|
) { |
62
|
2
|
|
|
|
|
|
return newSVpv( src, len ); /* no alteration */ |
63
|
|
|
|
|
|
|
} |
64
|
|
|
|
|
|
|
|
65
|
12
|
|
|
|
|
|
mapav = (AV *)SvRV(map); |
66
|
12
|
|
|
|
|
|
SV **ary = AvARRAY(mapav); |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
|
69
|
690
|
100
|
|
|
|
|
for ( i = 0; i < len; ++i, ++ptr, ++ix_newstr ) { |
70
|
678
|
|
|
|
|
|
char c = *ptr; |
71
|
678
|
|
|
|
|
|
int ix = (int) ( c ); |
72
|
678
|
100
|
|
|
|
|
if ( ix < 0 ) ix = 256 + ix; |
73
|
|
|
|
|
|
|
// need to croak in DEBUG mode if char is invalid |
74
|
|
|
|
|
|
|
|
75
|
678
|
|
|
|
|
|
str[ix_newstr] = c; /* default always performed... */ |
76
|
678
|
50
|
|
|
|
|
if ( ix >= AvFILL(mapav) |
|
|
100
|
|
|
|
|
|
77
|
677
|
50
|
|
|
|
|
|| !AvARRAY(mapav)[ix] |
78
|
|
|
|
|
|
|
) { |
79
|
1
|
|
|
|
|
|
continue; |
80
|
|
|
|
|
|
|
} else { |
81
|
677
|
|
|
|
|
|
SV *entry = AvARRAY(mapav)[ix]; |
82
|
677
|
50
|
|
|
|
|
if ( SvPOK( entry ) ) { |
83
|
677
|
|
|
|
|
|
int slen = SvCUR( entry ); /* length of the string used for replacement */ |
84
|
677
|
50
|
|
|
|
|
if ( slen <= 0 ) { |
85
|
0
|
|
|
|
|
|
continue; |
86
|
|
|
|
|
|
|
} else { |
87
|
677
|
|
|
|
|
|
char *replace = SvPVX( entry ); |
88
|
|
|
|
|
|
|
int j; |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
/* Check if we need to expand. */ |
91
|
677
|
100
|
|
|
|
|
if (str_size <= (ix_newstr + slen + 1) ) { /* +1 for \0 */ |
92
|
|
|
|
|
|
|
//printf( "#### need to grow %d -> %d\n", str_size, ix_newstr + slen ); |
93
|
7
|
|
|
|
|
|
str_size *= 2; |
94
|
|
|
|
|
|
|
|
95
|
7
|
100
|
|
|
|
|
if ( str == buffer ) { |
96
|
|
|
|
|
|
|
/* our first malloc */ |
97
|
4
|
50
|
|
|
|
|
Newx(str, str_size, char*); |
98
|
4
|
|
|
|
|
|
memcpy( str, buffer, _REPLACE_BUFFER_SIZE ); /* strncpy stops after the first \0 */ |
99
|
|
|
|
|
|
|
} else { |
100
|
|
|
|
|
|
|
/* grow the string */ |
101
|
3
|
|
|
|
|
|
tmp = Perl_realloc( str, str_size ); |
102
|
3
|
50
|
|
|
|
|
if ( !tmp ) Perl_croak(aTHX_ "failed to realloc string" ); |
103
|
3
|
|
|
|
|
|
str = tmp; |
104
|
|
|
|
|
|
|
} |
105
|
|
|
|
|
|
|
} |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
/* replace all characters except the last one, which avoids us to do a --ix_newstr after */ |
108
|
802
|
100
|
|
|
|
|
for ( j = 0 ; j < slen - 1; ++j ) { |
109
|
125
|
|
|
|
|
|
str[ix_newstr++] = replace[j]; |
110
|
|
|
|
|
|
|
} |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
/* handle the last character */ |
113
|
677
|
|
|
|
|
|
str[ix_newstr] = replace[j]; |
114
|
|
|
|
|
|
|
} |
115
|
|
|
|
|
|
|
} /* end - SvPOK */ |
116
|
|
|
|
|
|
|
} /* end - AvFILL || AvARRAY */ |
117
|
|
|
|
|
|
|
} |
118
|
|
|
|
|
|
|
|
119
|
12
|
|
|
|
|
|
str[ix_newstr] = '\0'; /* add the final trailing \0 character */ |
120
|
|
|
|
|
|
|
|
121
|
12
|
|
|
|
|
|
reply = newSVpvn_flags( str, ix_newstr, SvUTF8(sv) ); |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
/* free our tmp buffer if needed */ |
124
|
12
|
100
|
|
|
|
|
if ( str != buffer ) free(str); |
125
|
|
|
|
|
|
|
|
126
|
14
|
|
|
|
|
|
return reply; |
127
|
|
|
|
|
|
|
} |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
MODULE = Char__Replace PACKAGE = Char::Replace |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
SV* |
132
|
|
|
|
|
|
|
replace(sv, map) |
133
|
|
|
|
|
|
|
SV *sv; |
134
|
|
|
|
|
|
|
SV *map; |
135
|
|
|
|
|
|
|
CODE: |
136
|
17
|
50
|
|
|
|
|
if ( sv && SvPOK(sv) ) { |
|
|
100
|
|
|
|
|
|
137
|
14
|
|
|
|
|
|
RETVAL = _replace_str( sv, map ); |
138
|
|
|
|
|
|
|
} else { |
139
|
3
|
|
|
|
|
|
RETVAL = &PL_sv_undef; |
140
|
|
|
|
|
|
|
} |
141
|
|
|
|
|
|
|
OUTPUT: |
142
|
|
|
|
|
|
|
RETVAL |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
SV* |
145
|
|
|
|
|
|
|
trim(sv) |
146
|
|
|
|
|
|
|
SV *sv; |
147
|
|
|
|
|
|
|
CODE: |
148
|
16
|
50
|
|
|
|
|
if ( sv && SvPOK(sv) ) { |
|
|
100
|
|
|
|
|
|
149
|
13
|
|
|
|
|
|
RETVAL = _trim_sv( sv ); |
150
|
|
|
|
|
|
|
} else { |
151
|
3
|
|
|
|
|
|
RETVAL = &PL_sv_undef; |
152
|
|
|
|
|
|
|
} |
153
|
|
|
|
|
|
|
OUTPUT: |
154
|
|
|
|
|
|
|
RETVAL |