src/server/util/strreplace.c

changeset 661
a4e1ba59b733
parent 660
f00d03835dd9
equal deleted inserted replaced
660:f00d03835dd9 661:a4e1ba59b733
28 28
29 #include "strreplace.h" 29 #include "strreplace.h"
30 30
31 #include <string.h> 31 #include <string.h>
32 #include <stdlib.h> 32 #include <stdlib.h>
33 #include <unistd.h>
33 #include <ctype.h> 34 #include <ctype.h>
34 35
35 #include <cx/buffer.h> 36 #include <cx/buffer.h>
36 37
37 38
38 39
39 StringTemplate* string_template_compile(const CxAllocator *a, cxstring tpl) { 40 StringTemplate* string_template_compile(const CxAllocator *a, cxstring tpl) {
40 StringTemplateSegment *end = NULL; // segment list end 41 StringTemplateSegment *end = NULL; // segment list end
41 int var = FALSE; 42 int var = false;
42 int error = FALSE; 43 int error = false;
43 44
44 CxBuffer buf; // tmp buffer 45 CxBuffer buf; // tmp buffer
45 if(cxBufferInit(&buf, NULL, NULL, 128, CX_BUFFER_AUTO_EXTEND|CX_BUFFER_FREE_CONTENTS)) { 46 if(cxBufferInit(&buf, NULL, NULL, 128, CX_BUFFER_AUTO_EXTEND|CX_BUFFER_FREE_CONTENTS)) {
46 return NULL; 47 return NULL;
47 } 48 }
56 57
57 StringTemplateSegment *seg = NULL; 58 StringTemplateSegment *seg = NULL;
58 59
59 for(size_t i=0;i<tpl.length;i++) { 60 for(size_t i=0;i<tpl.length;i++) {
60 char c = tpl.ptr[i]; 61 char c = tpl.ptr[i];
61 int add_char = FALSE; // add current char to the buffer 62 int add_char = false; // add current char to the buffer
62 int finish_seg = FALSE; // copy buffer to segment string and start new segment 63 int finish_seg = false; // copy buffer to segment string and start new segment
63 64
64 if(!seg) { 65 if(!seg) {
65 // start new segment 66 // start new segment
66 seg = cxMalloc(a, sizeof(StringTemplateSegment)); 67 seg = cxMalloc(a, sizeof(StringTemplateSegment));
67 if(seg) { 68 if(seg) {
75 } else { 76 } else {
76 t->segments = seg; 77 t->segments = seg;
77 } 78 }
78 end = seg; 79 end = seg;
79 } else { 80 } else {
80 error = TRUE; 81 error = true;
81 break; 82 break;
82 } 83 }
83 } 84 }
84 85
85 if(var) { 86 if(var) {
86 // current segment is a var 87 // current segment is a var
87 if(c == '}') { 88 if(c == '}') {
88 var = FALSE; 89 var = false;
89 finish_seg = TRUE; 90 finish_seg = true;
90 } else if(c == '{') { 91 } else if(c == '{') {
91 // noop 92 // noop
92 } else if(!isalnum(c)) { 93 } else if(!isalnum(c)) {
93 var = FALSE; 94 var = false;
94 finish_seg = TRUE; 95 finish_seg = true;
95 i--; 96 i--;
96 } else { 97 } else {
97 add_char = TRUE; 98 add_char = true;
98 } 99 }
99 } else { 100 } else {
100 if(c == '$') { 101 if(c == '$') {
101 if(i+1<tpl.length && tpl.ptr[i+1] == '$') { 102 if(i+1<tpl.length && tpl.ptr[i+1] == '$') {
102 // $$ -> $ 103 // $$ -> $
103 i++; 104 i++;
104 add_char = TRUE; 105 add_char = true;
105 } else { 106 } else {
106 var = TRUE; 107 var = true;
107 if(buf.pos == 0) { 108 if(buf.pos == 0) {
108 // reuse current segment 109 // reuse current segment
109 seg->type = STRING_SEGMENT_VAR_PLACEHOLDER; 110 seg->type = STRING_SEGMENT_VAR_PLACEHOLDER;
110 } else { 111 } else {
111 // create new segment 112 // create new segment
112 finish_seg = TRUE; 113 finish_seg = true;
113 } 114 }
114 } 115 }
115 } else { 116 } else {
116 add_char = TRUE; 117 add_char = true;
117 } 118 }
118 } 119 }
119 120
120 if(add_char) { 121 if(add_char) {
121 if(cxBufferPut(&buf, c) != c) { 122 if(cxBufferPut(&buf, c) != c) {
122 error = TRUE; 123 error = true;
123 break; 124 break;
124 } 125 }
125 } else if(finish_seg) { 126 } else if(finish_seg) {
126 // copy buffer content 127 // copy buffer content
127 cxmutstr seg_str = cx_strdup_a(a, cx_strn(buf.space, buf.pos)); 128 cxmutstr seg_str = cx_strdup_a(a, cx_strn(buf.space, buf.pos));
128 if(!seg_str.ptr) { 129 if(!seg_str.ptr) {
129 error = TRUE; 130 error = true;
130 break; 131 break;
131 } 132 }
132 seg->str = seg_str; 133 seg->str = seg_str;
133 if(seg->type == STRING_SEGMENT_VAR_PLACEHOLDER) { 134 if(seg->type == STRING_SEGMENT_VAR_PLACEHOLDER) {
134 // is the var segment an integer reference? 135 // is the var segment an integer reference?
143 144
144 // finish last segment 145 // finish last segment
145 if(seg) { 146 if(seg) {
146 cxmutstr seg_str = cx_strdup_a(a, cx_strn(buf.space, buf.pos)); 147 cxmutstr seg_str = cx_strdup_a(a, cx_strn(buf.space, buf.pos));
147 if(!seg_str.ptr) { 148 if(!seg_str.ptr) {
148 error = TRUE; 149 error = true;
149 } else { 150 } else {
150 seg->str = seg_str; 151 seg->str = seg_str;
151 if(seg->type == STRING_SEGMENT_VAR_PLACEHOLDER) { 152 if(seg->type == STRING_SEGMENT_VAR_PLACEHOLDER) {
152 if(!cx_strtoi(seg_str, &seg->num, 10)) { 153 if(!cx_strtoi(seg_str, &seg->num, 10)) {
153 seg->type = STRING_SEGMENT_NUM_PLACEHOLDER; 154 seg->type = STRING_SEGMENT_NUM_PLACEHOLDER;
194 } 195 }
195 w += r; 196 w += r;
196 } 197 }
197 } else if(varfunc) { 198 } else if(varfunc) {
198 // convert var segment to value 199 // convert var segment to value
199 WSBool free_str = FALSE; 200 bool free_str = false;
200 cxmutstr str = varfunc(a, seg, userdata, &free_str); 201 cxmutstr str = varfunc(a, seg, userdata, &free_str);
201 if(str.length > 0) { 202 if(str.length > 0) {
202 size_t r = writef(str.ptr, 1, str.length, stream); 203 size_t r = writef(str.ptr, 1, str.length, stream);
203 if(r != str.length) { 204 if(r != str.length) {
204 return -1; 205 return -1;

mercurial