File Coverage

Config.xs
Criterion Covered Total %
statement 46 48 95.8
branch 34 42 80.9
condition n/a
subroutine n/a
pod n/a
total 80 90 88.8


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             /* prototypes */
18             SV* _parse_string(SV *sv);
19              
20              
21             /* functions */
22 16           SV* _parse_string(SV *sv) {
23 16           int len = SvCUR(sv);
24 16           char *ptr = (char *) SvPVX_const(sv); /* todo: preserve the const state of the pointer */
25             AV *av;
26             char *start_key, *end_key;
27             char *start_val, *end_val;
28              
29 16           int is_utf8 = SvUTF8(sv);
30              
31 16           av = newAV();
32              
33 16           const char eol = '\n';
34 16           const char sep = ':'; /* customize it later */
35 16           const char comment = '#';
36              
37 16           start_key = ptr;
38 16           end_key = 0;
39 16           start_val = 0;
40 16           end_val = 0;
41              
42 16           int found_eol = 1;
43 16           int found_comment = 0;
44 16           int found_sep = 0;
45              
46             int i;
47 395 100         for ( i = 0; i < len ; ++i, ++ptr ) {
48             //PerlIO_printf( PerlIO_stderr(), "# C %c\n", *ptr );
49             //printf("# char %c\n", *ptr );
50 379 100         if ( ! *ptr ) continue; /* skip \0 */
51              
52             /* skip all characters in a comment block */
53 378 100         if ( found_comment ) {
54 29 100         if ( *ptr == eol )
55 2           found_comment = 0;
56 29           continue;
57             }
58              
59 349 100         if ( found_sep ) {
60 27 100         if ( *ptr == ' ' || *ptr == '\t' )
    50          
61 1           continue;
62 26           found_sep = 0;
63 26           end_val = start_val = ptr;
64             }
65              
66             /* get to the first valuable char of the line */
67 348 100         if ( found_eol ) { /* starting a line */
68             /* spaces at the beginning of a line */
69 37 50         if ( *ptr == ' ' || *ptr == '\t' ) {
    50          
70 0           continue;
71             }
72 37 100         if ( *ptr == comment ) {
73 2           found_comment = 1;
74 2           continue;
75             }
76             /* we have a real character to start the line */
77 35           found_eol = 0;
78 35           start_key = ptr;
79 35           end_key = 0;
80             }
81              
82 346 100         if ( *ptr == sep ) {
83             //printf ("# separator key/value\n" );
84 28 100         if ( !end_key ) {
85 26           end_key = ptr;
86 28           found_sep = 1;
87             }
88 318 100         } else if ( *ptr == eol ) {
89              
90             #define __PARSE_STRING_LINE /* reuse code for the last line */ \
91             end_val = ptr; \
92             found_eol = 1; \
93             \
94             /* check if we got a key */ \
95             if ( end_key > start_key ) { \
96             /* we got a key */ \
97             av_push(av, newSVpvn_flags( start_key, (int) (end_key - start_key), is_utf8 )); \
98             \
99             /* only add the value if we have a key */ \
100             if ( end_val > start_val ) { \
101             av_push(av, newSVpvn_flags( start_val, (int) (end_val - start_val), is_utf8 )); \
102             } else { \
103             av_push(av, &PL_sv_undef); \
104             } \
105             } \
106             /* end of __PARSE_STRING_LINE */
107              
108 29 100         __PARSE_STRING_LINE
    50          
109              
110 29           start_key = 0;
111             }
112              
113             } /* end main for loop for *ptr */
114              
115             /* handle the last entry */
116 16 100         if ( start_key ) {
117 6 50         __PARSE_STRING_LINE
    50          
118             }
119              
120              
121             // av_push(av, newSVpv("END",3));
122             // av_push(av, newSVpv("END",3));
123              
124 16           return (SV*) (newRV_noinc((SV*) av));
125             //return (SV*) sv_2mortal(newRV_noinc((SV*) av));
126             }
127              
128              
129             MODULE = Colon__Config PACKAGE = Colon::Config
130              
131             SV*
132             read(sv)
133             SV *sv;
134             CODE:
135 16 50         if ( sv && SvPOK(sv) ) {
    50          
136 16           RETVAL = _parse_string( sv );
137             } else {
138 0           RETVAL = &PL_sv_undef;
139             }
140             OUTPUT:
141             RETVAL