File Coverage

Config.xs
Criterion Covered Total %
statement 44 46 95.6
branch 34 42 80.9
condition n/a
subroutine n/a
pod n/a
total 78 88 88.6


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