Fossil SCM

Extend translator to support two- and three-argument printf specifiers, e.g. "%.*s(len)(str)" or "%*.*d(width)(prec)(val)"

andygoth 2020-08-21 22:58 andygoth-forum-refactor
Commit df7b0c31868613c6560463e63c624ffcce54171d81041fc855752ccb6eb6a992
1 file changed +29 -18
+29 -18
--- src/translate.c
+++ src/translate.c
@@ -155,19 +155,24 @@
155155
fprintf(out,"\n");
156156
}else{
157157
fprintf(out,"%*s\"%s%s\"\n",indent, "", zOut, zNewline);
158158
}
159159
}else{
160
- /* Otherwise (if the last non-whitespace was not '=') then generate
161
- ** a cgi_printf() statement whose format is the text following the '@'.
162
- ** Substrings of the form "%C(...)" (where C is any sequence of
163
- ** characters other than \000 and '(') will put "%C" in the
164
- ** format and add the "(...)" as an argument to the cgi_printf call.
160
+ /* Otherwise (if the last non-whitespace was not '=') then generate a
161
+ ** cgi_printf() statement whose format is the text following the '@'.
162
+ ** Substrings of the form "%C(...)" (where C is any sequence of characters
163
+ ** other than \000 and '(') will put "%C" in the format and add the
164
+ ** "(...)" as an argument to the cgi_printf call. Each '*' character
165
+ ** present in C (max two) causes one more "(...)" sequence to be consumed.
166
+ ** For example, "%*.*d(4)(2)(1)" converts to "%*.*d" with arguments "4",
167
+ ** "2", and "1", which will be used as the field width, precision, and
168
+ ** value, respectively, producing a final formatted result of " 01".
165169
*/
166170
const char *zNewline = "\\n";
167171
int indent;
168172
int nC;
173
+ int nParam;
169174
char c;
170175
i++;
171176
if( isspace(zLine[i]) ){ i++; }
172177
indent = i;
173178
for(j=0; zLine[i] && zLine[i]!='\r' && zLine[i]!='\n'; i++){
@@ -177,25 +182,31 @@
177182
break;
178183
}
179184
if( zLine[i]=='"' || zLine[i]=='\\' ){ zOut[j++] = '\\'; }
180185
zOut[j++] = zLine[i];
181186
if( zLine[i]!='%' || zLine[i+1]=='%' || zLine[i+1]==0 ) continue;
182
- for(nC=1; zLine[i+nC] && zLine[i+nC]!='('; nC++){}
187
+ nParam=1;
188
+ for(nC=1; zLine[i+nC] && zLine[i+nC]!='('; nC++){
189
+ if( zLine[i+nC]=='*' && nParam < 3 ) nParam++;
190
+ }
183191
if( zLine[i+nC]!='(' || !isalpha(zLine[i+nC-1]) ) continue;
184192
while( --nC ) zOut[j++] = zLine[++i];
185
- zArg[nArg++] = ',';
186
- k = 0; i++;
187
- while( (c = zLine[i])!=0 ){
188
- zArg[nArg++] = c;
189
- if( c==')' ){
190
- k--;
191
- if( k==0 ) break;
192
- }else if( c=='(' ){
193
- k++;
194
- }
195
- i++;
196
- }
193
+ do{
194
+ zArg[nArg++] = ',';
195
+ k = 0; i++;
196
+ if( zLine[i]!='(' ) break;
197
+ while( (c = zLine[i])!=0 ){
198
+ zArg[nArg++] = c;
199
+ if( c==')' ){
200
+ k--;
201
+ if( k==0 ) break;
202
+ }else if( c=='(' ){
203
+ k++;
204
+ }
205
+ i++;
206
+ }
207
+ }while( --nParam );
197208
}
198209
zOut[j] = 0;
199210
if( !inPrint ){
200211
fprintf(out,"%*scgi_printf(\"%s%s\"",indent-2,"", zOut, zNewline);
201212
inPrint = 1;
202213
--- src/translate.c
+++ src/translate.c
@@ -155,19 +155,24 @@
155 fprintf(out,"\n");
156 }else{
157 fprintf(out,"%*s\"%s%s\"\n",indent, "", zOut, zNewline);
158 }
159 }else{
160 /* Otherwise (if the last non-whitespace was not '=') then generate
161 ** a cgi_printf() statement whose format is the text following the '@'.
162 ** Substrings of the form "%C(...)" (where C is any sequence of
163 ** characters other than \000 and '(') will put "%C" in the
164 ** format and add the "(...)" as an argument to the cgi_printf call.
 
 
 
 
165 */
166 const char *zNewline = "\\n";
167 int indent;
168 int nC;
 
169 char c;
170 i++;
171 if( isspace(zLine[i]) ){ i++; }
172 indent = i;
173 for(j=0; zLine[i] && zLine[i]!='\r' && zLine[i]!='\n'; i++){
@@ -177,25 +182,31 @@
177 break;
178 }
179 if( zLine[i]=='"' || zLine[i]=='\\' ){ zOut[j++] = '\\'; }
180 zOut[j++] = zLine[i];
181 if( zLine[i]!='%' || zLine[i+1]=='%' || zLine[i+1]==0 ) continue;
182 for(nC=1; zLine[i+nC] && zLine[i+nC]!='('; nC++){}
 
 
 
183 if( zLine[i+nC]!='(' || !isalpha(zLine[i+nC-1]) ) continue;
184 while( --nC ) zOut[j++] = zLine[++i];
185 zArg[nArg++] = ',';
186 k = 0; i++;
187 while( (c = zLine[i])!=0 ){
188 zArg[nArg++] = c;
189 if( c==')' ){
190 k--;
191 if( k==0 ) break;
192 }else if( c=='(' ){
193 k++;
194 }
195 i++;
196 }
 
 
 
197 }
198 zOut[j] = 0;
199 if( !inPrint ){
200 fprintf(out,"%*scgi_printf(\"%s%s\"",indent-2,"", zOut, zNewline);
201 inPrint = 1;
202
--- src/translate.c
+++ src/translate.c
@@ -155,19 +155,24 @@
155 fprintf(out,"\n");
156 }else{
157 fprintf(out,"%*s\"%s%s\"\n",indent, "", zOut, zNewline);
158 }
159 }else{
160 /* Otherwise (if the last non-whitespace was not '=') then generate a
161 ** cgi_printf() statement whose format is the text following the '@'.
162 ** Substrings of the form "%C(...)" (where C is any sequence of characters
163 ** other than \000 and '(') will put "%C" in the format and add the
164 ** "(...)" as an argument to the cgi_printf call. Each '*' character
165 ** present in C (max two) causes one more "(...)" sequence to be consumed.
166 ** For example, "%*.*d(4)(2)(1)" converts to "%*.*d" with arguments "4",
167 ** "2", and "1", which will be used as the field width, precision, and
168 ** value, respectively, producing a final formatted result of " 01".
169 */
170 const char *zNewline = "\\n";
171 int indent;
172 int nC;
173 int nParam;
174 char c;
175 i++;
176 if( isspace(zLine[i]) ){ i++; }
177 indent = i;
178 for(j=0; zLine[i] && zLine[i]!='\r' && zLine[i]!='\n'; i++){
@@ -177,25 +182,31 @@
182 break;
183 }
184 if( zLine[i]=='"' || zLine[i]=='\\' ){ zOut[j++] = '\\'; }
185 zOut[j++] = zLine[i];
186 if( zLine[i]!='%' || zLine[i+1]=='%' || zLine[i+1]==0 ) continue;
187 nParam=1;
188 for(nC=1; zLine[i+nC] && zLine[i+nC]!='('; nC++){
189 if( zLine[i+nC]=='*' && nParam < 3 ) nParam++;
190 }
191 if( zLine[i+nC]!='(' || !isalpha(zLine[i+nC-1]) ) continue;
192 while( --nC ) zOut[j++] = zLine[++i];
193 do{
194 zArg[nArg++] = ',';
195 k = 0; i++;
196 if( zLine[i]!='(' ) break;
197 while( (c = zLine[i])!=0 ){
198 zArg[nArg++] = c;
199 if( c==')' ){
200 k--;
201 if( k==0 ) break;
202 }else if( c=='(' ){
203 k++;
204 }
205 i++;
206 }
207 }while( --nParam );
208 }
209 zOut[j] = 0;
210 if( !inPrint ){
211 fprintf(out,"%*scgi_printf(\"%s%s\"",indent-2,"", zOut, zNewline);
212 inPrint = 1;
213

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button