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
|
10
|
|
|
|
|
|
SV *_replace_str( SV *sv, SV *map ) { |
47
|
10
|
|
|
|
|
|
char buffer[_REPLACE_BUFFER_SIZE] = { 0 }; |
48
|
10
|
|
|
|
|
|
char *src = SvPVX(sv); |
49
|
10
|
|
|
|
|
|
int len = SvCUR(sv); |
50
|
10
|
|
|
|
|
|
int i = 0; |
51
|
10
|
|
|
|
|
|
char *ptr = src; |
52
|
10
|
|
|
|
|
|
char *str = buffer; /* the new string we are going to use */ |
53
|
|
|
|
|
|
|
char *tmp; /* used to grow */ |
54
|
10
|
|
|
|
|
|
int str_size = _REPLACE_BUFFER_SIZE; /* we start with the buffer */ |
55
|
10
|
|
|
|
|
|
int ix_newstr = 0; |
56
|
|
|
|
|
|
|
AV *mapav; |
57
|
|
|
|
|
|
|
SV *reply; |
58
|
|
|
|
|
|
|
|
59
|
10
|
50
|
|
|
|
|
if ( !map || SvTYPE(map) != SVt_RV || SvTYPE(SvRV(map)) != SVt_PVAV |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
60
|
9
|
0
|
|
|
|
|
|| AvFILL( SvRV(map) ) <= 0 |
|
|
100
|
|
|
|
|
|
61
|
|
|
|
|
|
|
) { |
62
|
2
|
|
|
|
|
|
return newSVpv( src, len ); /* no alteration */ |
63
|
|
|
|
|
|
|
} |
64
|
|
|
|
|
|
|
|
65
|
8
|
|
|
|
|
|
mapav = (AV *)SvRV(map); |
66
|
8
|
|
|
|
|
|
SV **ary = AvARRAY(mapav); |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
|
69
|
380
|
100
|
|
|
|
|
for ( i = 0; i < len; ++i, ++ptr, ++ix_newstr ) { |
70
|
372
|
|
|
|
|
|
char c = *ptr; |
71
|
372
|
|
|
|
|
|
int ix = (int) ( c ); |
72
|
372
|
100
|
|
|
|
|
if ( ix < 0 ) ix = 256 + ix; |
73
|
|
|
|
|
|
|
// need to croak in DEBUG mode if char is invalid |
74
|
|
|
|
|
|
|
|
75
|
372
|
|
|
|
|
|
str[ix_newstr] = c; /* default always performed... */ |
76
|
372
|
50
|
|
|
|
|
if ( ix >= AvFILL(mapav) || !AvARRAY(mapav)[ix] ) { |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
77
|
1
|
|
|
|
|
|
continue; |
78
|
|
|
|
|
|
|
} else { |
79
|
371
|
|
|
|
|
|
SV *entry = AvARRAY(mapav)[ix]; |
80
|
371
|
50
|
|
|
|
|
if ( SvPOK( entry ) ) { |
81
|
371
|
|
|
|
|
|
int slen = SvCUR( entry ); /* length of the string used for replacement */ |
82
|
371
|
50
|
|
|
|
|
if ( slen <= 0 ) { |
83
|
0
|
|
|
|
|
|
continue; |
84
|
|
|
|
|
|
|
} else { |
85
|
371
|
|
|
|
|
|
char *replace = SvPVX( entry ); |
86
|
371
|
|
|
|
|
|
int j = 0; |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
/* Check if we need to expand. */ |
89
|
371
|
100
|
|
|
|
|
if (str_size <= (ix_newstr + slen + 1) ) { /* +1 for \0 */ |
90
|
|
|
|
|
|
|
//printf( "neew to grow %d -> %d\n", str_size, ix_newstr + slen ); |
91
|
4
|
|
|
|
|
|
str_size *= 2; |
92
|
|
|
|
|
|
|
|
93
|
4
|
100
|
|
|
|
|
if ( str == buffer ) { |
94
|
|
|
|
|
|
|
/* our first malloc */ |
95
|
2
|
50
|
|
|
|
|
Newx(str, str_size, char*); |
96
|
2
|
|
|
|
|
|
strncpy( str, buffer, ix_newstr ); |
97
|
|
|
|
|
|
|
} else { |
98
|
|
|
|
|
|
|
/* grow the string */ |
99
|
2
|
|
|
|
|
|
tmp = Perl_realloc( str, str_size ); |
100
|
2
|
50
|
|
|
|
|
if ( !tmp ) Perl_croak(aTHX_ "failed to realloc string" ); |
101
|
2
|
|
|
|
|
|
str = tmp; |
102
|
|
|
|
|
|
|
} |
103
|
|
|
|
|
|
|
} |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
/* replace all characters except the last one, which avoids us to do a --ix_newstr after */ |
106
|
496
|
100
|
|
|
|
|
for ( ; j < slen - 1; ++j ) { |
107
|
125
|
|
|
|
|
|
str[ix_newstr++] = replace[j]; |
108
|
|
|
|
|
|
|
} |
109
|
|
|
|
|
|
|
/* handle the last character */ |
110
|
371
|
|
|
|
|
|
str[ix_newstr] = replace[j]; |
111
|
|
|
|
|
|
|
} |
112
|
|
|
|
|
|
|
} /* end - SvPOK */ |
113
|
|
|
|
|
|
|
} /* end - AvFILL || AvARRAY */ |
114
|
|
|
|
|
|
|
} |
115
|
|
|
|
|
|
|
|
116
|
8
|
|
|
|
|
|
str[ix_newstr] = '\0'; /* add the final trailing \0 character */ |
117
|
8
|
|
|
|
|
|
reply = newSVpvn_flags( str, ix_newstr, SvUTF8(sv) ); |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
/* free our tmp buffer if needed */ |
120
|
8
|
100
|
|
|
|
|
if ( str != buffer ) free(str); |
121
|
|
|
|
|
|
|
|
122
|
10
|
|
|
|
|
|
return reply; |
123
|
|
|
|
|
|
|
} |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
MODULE = Char__Replace PACKAGE = Char::Replace |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
SV* |
128
|
|
|
|
|
|
|
replace(sv, map) |
129
|
|
|
|
|
|
|
SV *sv; |
130
|
|
|
|
|
|
|
SV *map; |
131
|
|
|
|
|
|
|
CODE: |
132
|
13
|
50
|
|
|
|
|
if ( sv && SvPOK(sv) ) { |
|
|
100
|
|
|
|
|
|
133
|
10
|
|
|
|
|
|
RETVAL = _replace_str( sv, map ); |
134
|
|
|
|
|
|
|
} else { |
135
|
3
|
|
|
|
|
|
RETVAL = &PL_sv_undef; |
136
|
|
|
|
|
|
|
} |
137
|
|
|
|
|
|
|
OUTPUT: |
138
|
|
|
|
|
|
|
RETVAL |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
SV* |
141
|
|
|
|
|
|
|
trim(sv) |
142
|
|
|
|
|
|
|
SV *sv; |
143
|
|
|
|
|
|
|
CODE: |
144
|
16
|
50
|
|
|
|
|
if ( sv && SvPOK(sv) ) { |
|
|
100
|
|
|
|
|
|
145
|
13
|
|
|
|
|
|
RETVAL = _trim_sv( sv ); |
146
|
|
|
|
|
|
|
} else { |
147
|
3
|
|
|
|
|
|
RETVAL = &PL_sv_undef; |
148
|
|
|
|
|
|
|
} |
149
|
|
|
|
|
|
|
OUTPUT: |
150
|
|
|
|
|
|
|
RETVAL |