Fossil SCM

Enhance the blob_append(), blob_appendf(), blob_append_char(), and similar interfaces such that if the Blob pointer in the first argument is NULL, the result is written directly to stdout.

drh 2021-09-07 12:51 trunk
Commit 3a561322cafbc337742d50078fa49072d425afd8ba0879413316162260aac483
3 files changed +35 -32 +5 -12 +2 -2
+35 -32
--- src/blob.c
+++ src/blob.c
@@ -275,25 +275,30 @@
275275
pBlob->blobFlags = 0;
276276
pBlob->xRealloc = blobReallocStatic;
277277
}
278278
279279
/*
280
-** Append text or data to the end of a blob.
280
+** Append text or data to the end of a blob. Or, if pBlob==NULL, send
281
+** the text to standard output.
282
+**
283
+** If nData<0 then output all of aData up to the first 0x00 byte.
281284
**
282
-** The blob_append_full() routine is a complete implementation.
283
-** The blob_append() routine only works for cases where nData>0 and
284
-** no resizing is required, and falls back to blob_append_full() if
285
-** either condition is not met, but runs faster in the common case
286
-** where all conditions are met. The use of blob_append() is
287
-** recommended, unless it is known in advance that nData<0.
285
+** Use the blob_append() routine in all application code. The blob_append()
286
+** routine is faster, but blob_append_full() handles all the corner cases.
287
+** The blob_append() routine automatically calls blob_append_full() if
288
+** necessary.
288289
*/
289
-void blob_append_full(Blob *pBlob, const char *aData, int nData){
290
+static void blob_append_full(Blob *pBlob, const char *aData, int nData){
290291
sqlite3_int64 nNew;
291
- assert( aData!=0 || nData==0 );
292
- blob_is_init(pBlob);
292
+ /* assert( aData!=0 || nData==0 ); // omitted for speed */
293
+ /* blob_is_init(pBlob); // omitted for speed */
293294
if( nData<0 ) nData = strlen(aData);
294295
if( nData==0 ) return;
296
+ if( pBlob==0 ){
297
+ fossil_puts(aData, 0, nData);
298
+ return;
299
+ }
295300
nNew = pBlob->nUsed;
296301
nNew += nData;
297302
if( nNew >= pBlob->nAlloc ){
298303
nNew += pBlob->nAlloc;
299304
nNew += 100;
@@ -309,13 +314,12 @@
309314
pBlob->nUsed += nData;
310315
pBlob->aData[pBlob->nUsed] = 0; /* Blobs are always nul-terminated */
311316
}
312317
void blob_append(Blob *pBlob, const char *aData, int nData){
313318
sqlite3_int64 nUsed;
314
- assert( aData!=0 || nData==0 );
315
- /* blob_is_init(pBlob); // omitted for speed */
316
- if( nData<=0 || pBlob->nUsed + nData >= pBlob->nAlloc ){
319
+ /* assert( aData!=0 || nData==0 ); // omitted for speed */
320
+ if( nData<=0 || pBlob==0 || pBlob->nUsed + nData >= pBlob->nAlloc ){
317321
blob_append_full(pBlob, aData, nData);
318322
return;
319323
}
320324
nUsed = pBlob->nUsed;
321325
pBlob->nUsed += nData;
@@ -329,32 +333,34 @@
329333
#if INTERFACE
330334
#define blob_append_string(BLOB,STR) blob_append(BLOB,STR,sizeof(STR)-1)
331335
#endif
332336
333337
/*
334
-** Append a single character to the blob
338
+** Append a single character to the blob. If pBlob is zero then the
339
+** character is written directly to stdout.
335340
*/
336341
void blob_append_char(Blob *pBlob, char c){
337
- if( pBlob->nUsed+1 >= pBlob->nAlloc ){
342
+ if( pBlob==0 || pBlob->nUsed+1 >= pBlob->nAlloc ){
338343
blob_append_full(pBlob, &c, 1);
339344
}else{
340345
pBlob->aData[pBlob->nUsed++] = c;
341346
}
342347
}
343348
344349
/*
345
-** Copy a blob
350
+** Copy a blob. pTo is reinitialized to be a copy of pFrom.
346351
*/
347352
void blob_copy(Blob *pTo, Blob *pFrom){
348353
blob_is_init(pFrom);
349354
blob_zero(pTo);
350355
blob_append(pTo, blob_buffer(pFrom), blob_size(pFrom));
351356
}
352357
353358
/*
354359
** Append the second blob onto the end of the first blob and reset the
355
-** second blob.
360
+** second blob. If the first blob (pTo) is NULL, then the content
361
+** of the second blob is written to stdout.
356362
*/
357363
void blob_append_xfer(Blob *pTo, Blob *pFrom){
358364
blob_append(pTo, blob_buffer(pFrom), blob_size(pFrom));
359365
blob_reset(pFrom);
360366
}
@@ -886,34 +892,31 @@
886892
for(i=0; i<nToken && blob_token(pIn, &aToken[i]); i++){}
887893
return i;
888894
}
889895
890896
/*
891
-** Do printf-style string rendering and append the results to a blob.
897
+** Do printf-style string rendering and append the results to a blob. Or
898
+** if pBlob==0, do printf-style string rendering directly to stdout.
892899
**
893900
** The blob_appendf() version sets the BLOBFLAG_NotSQL bit in Blob.blobFlags
894901
** whereas blob_append_sql() does not.
895902
*/
896903
void blob_appendf(Blob *pBlob, const char *zFormat, ...){
897
- if( pBlob ){
898
- va_list ap;
899
- va_start(ap, zFormat);
900
- vxprintf(pBlob, zFormat, ap);
901
- va_end(ap);
902
- pBlob->blobFlags |= BLOBFLAG_NotSQL;
903
- }
904
+ va_list ap;
905
+ va_start(ap, zFormat);
906
+ vxprintf(pBlob, zFormat, ap);
907
+ va_end(ap);
908
+ if( pBlob ) pBlob->blobFlags |= BLOBFLAG_NotSQL;
904909
}
905910
void blob_append_sql(Blob *pBlob, const char *zFormat, ...){
906
- if( pBlob ){
907
- va_list ap;
908
- va_start(ap, zFormat);
909
- vxprintf(pBlob, zFormat, ap);
910
- va_end(ap);
911
- }
911
+ va_list ap;
912
+ va_start(ap, zFormat);
913
+ vxprintf(pBlob, zFormat, ap);
914
+ va_end(ap);
912915
}
913916
void blob_vappendf(Blob *pBlob, const char *zFormat, va_list ap){
914
- if( pBlob ) vxprintf(pBlob, zFormat, ap);
917
+ vxprintf(pBlob, zFormat, ap);
915918
}
916919
917920
/*
918921
** Initialize a blob to the data on an input channel. Return
919922
** the number of bytes read into the blob. Any prior content
920923
--- src/blob.c
+++ src/blob.c
@@ -275,25 +275,30 @@
275 pBlob->blobFlags = 0;
276 pBlob->xRealloc = blobReallocStatic;
277 }
278
279 /*
280 ** Append text or data to the end of a blob.
 
 
 
281 **
282 ** The blob_append_full() routine is a complete implementation.
283 ** The blob_append() routine only works for cases where nData>0 and
284 ** no resizing is required, and falls back to blob_append_full() if
285 ** either condition is not met, but runs faster in the common case
286 ** where all conditions are met. The use of blob_append() is
287 ** recommended, unless it is known in advance that nData<0.
288 */
289 void blob_append_full(Blob *pBlob, const char *aData, int nData){
290 sqlite3_int64 nNew;
291 assert( aData!=0 || nData==0 );
292 blob_is_init(pBlob);
293 if( nData<0 ) nData = strlen(aData);
294 if( nData==0 ) return;
 
 
 
 
295 nNew = pBlob->nUsed;
296 nNew += nData;
297 if( nNew >= pBlob->nAlloc ){
298 nNew += pBlob->nAlloc;
299 nNew += 100;
@@ -309,13 +314,12 @@
309 pBlob->nUsed += nData;
310 pBlob->aData[pBlob->nUsed] = 0; /* Blobs are always nul-terminated */
311 }
312 void blob_append(Blob *pBlob, const char *aData, int nData){
313 sqlite3_int64 nUsed;
314 assert( aData!=0 || nData==0 );
315 /* blob_is_init(pBlob); // omitted for speed */
316 if( nData<=0 || pBlob->nUsed + nData >= pBlob->nAlloc ){
317 blob_append_full(pBlob, aData, nData);
318 return;
319 }
320 nUsed = pBlob->nUsed;
321 pBlob->nUsed += nData;
@@ -329,32 +333,34 @@
329 #if INTERFACE
330 #define blob_append_string(BLOB,STR) blob_append(BLOB,STR,sizeof(STR)-1)
331 #endif
332
333 /*
334 ** Append a single character to the blob
 
335 */
336 void blob_append_char(Blob *pBlob, char c){
337 if( pBlob->nUsed+1 >= pBlob->nAlloc ){
338 blob_append_full(pBlob, &c, 1);
339 }else{
340 pBlob->aData[pBlob->nUsed++] = c;
341 }
342 }
343
344 /*
345 ** Copy a blob
346 */
347 void blob_copy(Blob *pTo, Blob *pFrom){
348 blob_is_init(pFrom);
349 blob_zero(pTo);
350 blob_append(pTo, blob_buffer(pFrom), blob_size(pFrom));
351 }
352
353 /*
354 ** Append the second blob onto the end of the first blob and reset the
355 ** second blob.
 
356 */
357 void blob_append_xfer(Blob *pTo, Blob *pFrom){
358 blob_append(pTo, blob_buffer(pFrom), blob_size(pFrom));
359 blob_reset(pFrom);
360 }
@@ -886,34 +892,31 @@
886 for(i=0; i<nToken && blob_token(pIn, &aToken[i]); i++){}
887 return i;
888 }
889
890 /*
891 ** Do printf-style string rendering and append the results to a blob.
 
892 **
893 ** The blob_appendf() version sets the BLOBFLAG_NotSQL bit in Blob.blobFlags
894 ** whereas blob_append_sql() does not.
895 */
896 void blob_appendf(Blob *pBlob, const char *zFormat, ...){
897 if( pBlob ){
898 va_list ap;
899 va_start(ap, zFormat);
900 vxprintf(pBlob, zFormat, ap);
901 va_end(ap);
902 pBlob->blobFlags |= BLOBFLAG_NotSQL;
903 }
904 }
905 void blob_append_sql(Blob *pBlob, const char *zFormat, ...){
906 if( pBlob ){
907 va_list ap;
908 va_start(ap, zFormat);
909 vxprintf(pBlob, zFormat, ap);
910 va_end(ap);
911 }
912 }
913 void blob_vappendf(Blob *pBlob, const char *zFormat, va_list ap){
914 if( pBlob ) vxprintf(pBlob, zFormat, ap);
915 }
916
917 /*
918 ** Initialize a blob to the data on an input channel. Return
919 ** the number of bytes read into the blob. Any prior content
920
--- src/blob.c
+++ src/blob.c
@@ -275,25 +275,30 @@
275 pBlob->blobFlags = 0;
276 pBlob->xRealloc = blobReallocStatic;
277 }
278
279 /*
280 ** Append text or data to the end of a blob. Or, if pBlob==NULL, send
281 ** the text to standard output.
282 **
283 ** If nData<0 then output all of aData up to the first 0x00 byte.
284 **
285 ** Use the blob_append() routine in all application code. The blob_append()
286 ** routine is faster, but blob_append_full() handles all the corner cases.
287 ** The blob_append() routine automatically calls blob_append_full() if
288 ** necessary.
 
 
289 */
290 static void blob_append_full(Blob *pBlob, const char *aData, int nData){
291 sqlite3_int64 nNew;
292 /* assert( aData!=0 || nData==0 ); // omitted for speed */
293 /* blob_is_init(pBlob); // omitted for speed */
294 if( nData<0 ) nData = strlen(aData);
295 if( nData==0 ) return;
296 if( pBlob==0 ){
297 fossil_puts(aData, 0, nData);
298 return;
299 }
300 nNew = pBlob->nUsed;
301 nNew += nData;
302 if( nNew >= pBlob->nAlloc ){
303 nNew += pBlob->nAlloc;
304 nNew += 100;
@@ -309,13 +314,12 @@
314 pBlob->nUsed += nData;
315 pBlob->aData[pBlob->nUsed] = 0; /* Blobs are always nul-terminated */
316 }
317 void blob_append(Blob *pBlob, const char *aData, int nData){
318 sqlite3_int64 nUsed;
319 /* assert( aData!=0 || nData==0 ); // omitted for speed */
320 if( nData<=0 || pBlob==0 || pBlob->nUsed + nData >= pBlob->nAlloc ){
 
321 blob_append_full(pBlob, aData, nData);
322 return;
323 }
324 nUsed = pBlob->nUsed;
325 pBlob->nUsed += nData;
@@ -329,32 +333,34 @@
333 #if INTERFACE
334 #define blob_append_string(BLOB,STR) blob_append(BLOB,STR,sizeof(STR)-1)
335 #endif
336
337 /*
338 ** Append a single character to the blob. If pBlob is zero then the
339 ** character is written directly to stdout.
340 */
341 void blob_append_char(Blob *pBlob, char c){
342 if( pBlob==0 || pBlob->nUsed+1 >= pBlob->nAlloc ){
343 blob_append_full(pBlob, &c, 1);
344 }else{
345 pBlob->aData[pBlob->nUsed++] = c;
346 }
347 }
348
349 /*
350 ** Copy a blob. pTo is reinitialized to be a copy of pFrom.
351 */
352 void blob_copy(Blob *pTo, Blob *pFrom){
353 blob_is_init(pFrom);
354 blob_zero(pTo);
355 blob_append(pTo, blob_buffer(pFrom), blob_size(pFrom));
356 }
357
358 /*
359 ** Append the second blob onto the end of the first blob and reset the
360 ** second blob. If the first blob (pTo) is NULL, then the content
361 ** of the second blob is written to stdout.
362 */
363 void blob_append_xfer(Blob *pTo, Blob *pFrom){
364 blob_append(pTo, blob_buffer(pFrom), blob_size(pFrom));
365 blob_reset(pFrom);
366 }
@@ -886,34 +892,31 @@
892 for(i=0; i<nToken && blob_token(pIn, &aToken[i]); i++){}
893 return i;
894 }
895
896 /*
897 ** Do printf-style string rendering and append the results to a blob. Or
898 ** if pBlob==0, do printf-style string rendering directly to stdout.
899 **
900 ** The blob_appendf() version sets the BLOBFLAG_NotSQL bit in Blob.blobFlags
901 ** whereas blob_append_sql() does not.
902 */
903 void blob_appendf(Blob *pBlob, const char *zFormat, ...){
904 va_list ap;
905 va_start(ap, zFormat);
906 vxprintf(pBlob, zFormat, ap);
907 va_end(ap);
908 if( pBlob ) pBlob->blobFlags |= BLOBFLAG_NotSQL;
 
 
909 }
910 void blob_append_sql(Blob *pBlob, const char *zFormat, ...){
911 va_list ap;
912 va_start(ap, zFormat);
913 vxprintf(pBlob, zFormat, ap);
914 va_end(ap);
 
 
915 }
916 void blob_vappendf(Blob *pBlob, const char *zFormat, va_list ap){
917 vxprintf(pBlob, zFormat, ap);
918 }
919
920 /*
921 ** Initialize a blob to the data on an input channel. Return
922 ** the number of bytes read into the blob. Any prior content
923
+5 -12
--- src/printf.c
+++ src/printf.c
@@ -958,13 +958,12 @@
958958
** a file, no translation occurs. Switch output mode to binary to
959959
** properly process line-endings, make sure to switch the mode back to
960960
** text when done.
961961
** No translation ever occurs on unix.
962962
*/
963
-void fossil_puts(const char *z, int toStdErr){
963
+void fossil_puts(const char *z, int toStdErr, int n){
964964
FILE* out = (toStdErr ? stderr : stdout);
965
- int n = (int)strlen(z);
966965
if( n==0 ) return;
967966
assert( toStdErr==0 || toStdErr==1 );
968967
if( toStdErr==0 ) stdoutAtBOL = (z[n-1]=='\n');
969968
#if defined(_WIN32)
970969
if( fossil_utf8_to_console(z, n, toStdErr) >= 0 ){
@@ -984,11 +983,11 @@
984983
** Force the standard output cursor to move to the beginning
985984
** of a line, if it is not there already.
986985
*/
987986
int fossil_force_newline(void){
988987
if( g.cgiOutput==0 && stdoutAtBOL==0 ){
989
- fossil_puts("\n", 0);
988
+ fossil_puts("\n", 0, 1);
990989
return 1;
991990
}
992991
return 0;
993992
}
994993
@@ -1009,25 +1008,19 @@
10091008
va_list ap;
10101009
va_start(ap, zFormat);
10111010
if( g.cgiOutput ){
10121011
cgi_vprintf(zFormat, ap);
10131012
}else{
1014
- Blob b = empty_blob;
1015
- vxprintf(&b, zFormat, ap);
1016
- fossil_puts(blob_str(&b), 0);
1017
- blob_reset(&b);
1013
+ vxprintf(0, zFormat, ap);
10181014
}
10191015
va_end(ap);
10201016
}
10211017
void fossil_vprint(const char *zFormat, va_list ap){
10221018
if( g.cgiOutput ){
10231019
cgi_vprintf(zFormat, ap);
10241020
}else{
1025
- Blob b = empty_blob;
1026
- vxprintf(&b, zFormat, ap);
1027
- fossil_puts(blob_str(&b), 0);
1028
- blob_reset(&b);
1021
+ vxprintf(0, zFormat, ap);
10291022
}
10301023
}
10311024
10321025
/*
10331026
** Print a trace message on standard error.
@@ -1036,11 +1029,11 @@
10361029
va_list ap;
10371030
Blob b;
10381031
va_start(ap, zFormat);
10391032
b = empty_blob;
10401033
vxprintf(&b, zFormat, ap);
1041
- fossil_puts(blob_str(&b), 1);
1034
+ fossil_puts(blob_buffer(&b), 1, blob_size(&b));
10421035
blob_reset(&b);
10431036
va_end(ap);
10441037
}
10451038
10461039
/*
10471040
--- src/printf.c
+++ src/printf.c
@@ -958,13 +958,12 @@
958 ** a file, no translation occurs. Switch output mode to binary to
959 ** properly process line-endings, make sure to switch the mode back to
960 ** text when done.
961 ** No translation ever occurs on unix.
962 */
963 void fossil_puts(const char *z, int toStdErr){
964 FILE* out = (toStdErr ? stderr : stdout);
965 int n = (int)strlen(z);
966 if( n==0 ) return;
967 assert( toStdErr==0 || toStdErr==1 );
968 if( toStdErr==0 ) stdoutAtBOL = (z[n-1]=='\n');
969 #if defined(_WIN32)
970 if( fossil_utf8_to_console(z, n, toStdErr) >= 0 ){
@@ -984,11 +983,11 @@
984 ** Force the standard output cursor to move to the beginning
985 ** of a line, if it is not there already.
986 */
987 int fossil_force_newline(void){
988 if( g.cgiOutput==0 && stdoutAtBOL==0 ){
989 fossil_puts("\n", 0);
990 return 1;
991 }
992 return 0;
993 }
994
@@ -1009,25 +1008,19 @@
1009 va_list ap;
1010 va_start(ap, zFormat);
1011 if( g.cgiOutput ){
1012 cgi_vprintf(zFormat, ap);
1013 }else{
1014 Blob b = empty_blob;
1015 vxprintf(&b, zFormat, ap);
1016 fossil_puts(blob_str(&b), 0);
1017 blob_reset(&b);
1018 }
1019 va_end(ap);
1020 }
1021 void fossil_vprint(const char *zFormat, va_list ap){
1022 if( g.cgiOutput ){
1023 cgi_vprintf(zFormat, ap);
1024 }else{
1025 Blob b = empty_blob;
1026 vxprintf(&b, zFormat, ap);
1027 fossil_puts(blob_str(&b), 0);
1028 blob_reset(&b);
1029 }
1030 }
1031
1032 /*
1033 ** Print a trace message on standard error.
@@ -1036,11 +1029,11 @@
1036 va_list ap;
1037 Blob b;
1038 va_start(ap, zFormat);
1039 b = empty_blob;
1040 vxprintf(&b, zFormat, ap);
1041 fossil_puts(blob_str(&b), 1);
1042 blob_reset(&b);
1043 va_end(ap);
1044 }
1045
1046 /*
1047
--- src/printf.c
+++ src/printf.c
@@ -958,13 +958,12 @@
958 ** a file, no translation occurs. Switch output mode to binary to
959 ** properly process line-endings, make sure to switch the mode back to
960 ** text when done.
961 ** No translation ever occurs on unix.
962 */
963 void fossil_puts(const char *z, int toStdErr, int n){
964 FILE* out = (toStdErr ? stderr : stdout);
 
965 if( n==0 ) return;
966 assert( toStdErr==0 || toStdErr==1 );
967 if( toStdErr==0 ) stdoutAtBOL = (z[n-1]=='\n');
968 #if defined(_WIN32)
969 if( fossil_utf8_to_console(z, n, toStdErr) >= 0 ){
@@ -984,11 +983,11 @@
983 ** Force the standard output cursor to move to the beginning
984 ** of a line, if it is not there already.
985 */
986 int fossil_force_newline(void){
987 if( g.cgiOutput==0 && stdoutAtBOL==0 ){
988 fossil_puts("\n", 0, 1);
989 return 1;
990 }
991 return 0;
992 }
993
@@ -1009,25 +1008,19 @@
1008 va_list ap;
1009 va_start(ap, zFormat);
1010 if( g.cgiOutput ){
1011 cgi_vprintf(zFormat, ap);
1012 }else{
1013 vxprintf(0, zFormat, ap);
 
 
 
1014 }
1015 va_end(ap);
1016 }
1017 void fossil_vprint(const char *zFormat, va_list ap){
1018 if( g.cgiOutput ){
1019 cgi_vprintf(zFormat, ap);
1020 }else{
1021 vxprintf(0, zFormat, ap);
 
 
 
1022 }
1023 }
1024
1025 /*
1026 ** Print a trace message on standard error.
@@ -1036,11 +1029,11 @@
1029 va_list ap;
1030 Blob b;
1031 va_start(ap, zFormat);
1032 b = empty_blob;
1033 vxprintf(&b, zFormat, ap);
1034 fossil_puts(blob_buffer(&b), 1, blob_size(&b));
1035 blob_reset(&b);
1036 va_end(ap);
1037 }
1038
1039 /*
1040
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -2360,11 +2360,11 @@
23602360
for(i=2; i<g.argc; i++){
23612361
blob_read_from_file(&in, g.argv[i], ExtFILE);
23622362
blob_zero(&out);
23632363
htmlTidy(blob_str(&in), &out);
23642364
blob_reset(&in);
2365
- fossil_puts(blob_str(&out), 0);
2365
+ fossil_puts(blob_buffer(&out), 0, blob_size(&out));
23662366
blob_reset(&out);
23672367
}
23682368
}
23692369
23702370
/*
@@ -2487,11 +2487,11 @@
24872487
for(i=2; i<g.argc; i++){
24882488
blob_read_from_file(&in, g.argv[i], ExtFILE);
24892489
blob_zero(&out);
24902490
html_to_plaintext(blob_str(&in), &out);
24912491
blob_reset(&in);
2492
- fossil_puts(blob_str(&out), 0);
2492
+ fossil_puts(blob_buffer(&out), 0, blob_size(&out));
24932493
blob_reset(&out);
24942494
}
24952495
}
24962496
24972497
/****************************************************************************
24982498
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -2360,11 +2360,11 @@
2360 for(i=2; i<g.argc; i++){
2361 blob_read_from_file(&in, g.argv[i], ExtFILE);
2362 blob_zero(&out);
2363 htmlTidy(blob_str(&in), &out);
2364 blob_reset(&in);
2365 fossil_puts(blob_str(&out), 0);
2366 blob_reset(&out);
2367 }
2368 }
2369
2370 /*
@@ -2487,11 +2487,11 @@
2487 for(i=2; i<g.argc; i++){
2488 blob_read_from_file(&in, g.argv[i], ExtFILE);
2489 blob_zero(&out);
2490 html_to_plaintext(blob_str(&in), &out);
2491 blob_reset(&in);
2492 fossil_puts(blob_str(&out), 0);
2493 blob_reset(&out);
2494 }
2495 }
2496
2497 /****************************************************************************
2498
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -2360,11 +2360,11 @@
2360 for(i=2; i<g.argc; i++){
2361 blob_read_from_file(&in, g.argv[i], ExtFILE);
2362 blob_zero(&out);
2363 htmlTidy(blob_str(&in), &out);
2364 blob_reset(&in);
2365 fossil_puts(blob_buffer(&out), 0, blob_size(&out));
2366 blob_reset(&out);
2367 }
2368 }
2369
2370 /*
@@ -2487,11 +2487,11 @@
2487 for(i=2; i<g.argc; i++){
2488 blob_read_from_file(&in, g.argv[i], ExtFILE);
2489 blob_zero(&out);
2490 html_to_plaintext(blob_str(&in), &out);
2491 blob_reset(&in);
2492 fossil_puts(blob_buffer(&out), 0, blob_size(&out));
2493 blob_reset(&out);
2494 }
2495 }
2496
2497 /****************************************************************************
2498

Keyboard Shortcuts

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