Overview
SHA1 Hash: | 285929373757b9813748fd31744b4379dc163dfd |
---|---|
Date: | 2007-11-22 22:55:05 |
User: | drh |
Comment: | Add the %w and %W formatting options for internal printf usage. Use these formatting characters to render wiki. Fix additional problems of unterminated wiki on webpage rendering by using %w. (There are probably more problems yet to be discovered and fixed.) |
Timelines: | ancestors | descendants | both | trunk |
Other Links: | files | ZIP archive | manifest |
Tags And Properties
- branch=trunk inherited from [a28c83647d]
- sym-trunk inherited from [a28c83647d]
Changes
[hide diffs]Modified src/blob.c from [1da99958db] to [e355ed75f1].
@@ -540,31 +540,20 @@ for(i=0; i<nToken && blob_token(pIn, &aToken[i]); i++){} return i; } /* -** This function implements the callback from vxprintf. -** -** This routine add nNewChar characters of text in zNewText to -** the Blob structure pointed to by "arg". -*/ -static void bout(void *arg, const char *zNewText, int nNewChar){ - Blob *pBlob = (Blob*)arg; - blob_append(pBlob, zNewText, nNewChar); -} - -/* ** Do printf-style string rendering and append the results to a blob. */ void blob_appendf(Blob *pBlob, const char *zFormat, ...){ va_list ap; va_start(ap, zFormat); - vxprintf(bout, pBlob, zFormat, ap); + vxprintf(pBlob, zFormat, ap); va_end(ap); } void blob_vappendf(Blob *pBlob, const char *zFormat, va_list ap){ - vxprintf(bout, pBlob, zFormat, ap); + vxprintf(pBlob, zFormat, ap); } /* ** Initalize a blob to the data on an input channel. Return ** the number of bytes read into the blob. Any prior content
Modified src/cgi.c from [470b9d6c4c] to [144475b0ed].
@@ -921,36 +921,26 @@ } cgi_printf("%*s</select>\n", in, ""); } /* -** This function implements the callback from vxprintf. -** -** This routine sends nNewChar characters of text in zNewText to -** CGI reply content buffer. -*/ -static void sout(void *NotUsed, const char *zNewText, int nNewChar){ - cgi_append_content(zNewText, nNewChar); -} - -/* ** This routine works like "printf" except that it has the ** extra formatting capabilities such as %h and %t. */ void cgi_printf(const char *zFormat, ...){ va_list ap; va_start(ap,zFormat); - vxprintf(sout,0,zFormat,ap); + vxprintf(&cgiContent,zFormat,ap); va_end(ap); } /* ** This routine works like "vprintf" except that it has the ** extra formatting capabilities such as %h and %t. */ void cgi_vprintf(const char *zFormat, va_list ap){ - vxprintf(sout,0,zFormat,ap); + vxprintf(&cgiContent,zFormat,ap); } /* ** Send a reply indicating that the HTTP request was malformed @@ -974,11 +964,11 @@ cgi_printf( "<html><body><h1>Internal Server Error</h1>\n" "<plaintext>" ); va_start(ap, zFormat); - vxprintf(sout,0,zFormat,ap); + vxprintf(&cgiContent,zFormat,ap); va_end(ap); cgi_reply(); exit(1); }
Modified src/info.c from [17c99730c3] to [5b0da28053].
@@ -139,11 +139,11 @@ } @ <ul> } @ <li> hyperlink_to_uuid(zUuid); - @ %s(zCom) (by %s(zUser) on %s(zDate)) + @ %w(zCom) (by %s(zUser) on %s(zDate)) if( depth ){ n = showDescendents(cid, depth-1, 0); }else{ n = db_int(0, "SELECT 1 FROM plink WHERE pid=%d", cid); } @@ -190,11 +190,11 @@ } @ <ul> } @ <li> hyperlink_to_uuid(zUuid); - @ %s(zCom) (by %s(zUser) on %s(zDate)) + @ %w(zCom) (by %s(zUser) on %s(zDate)) if( depth ){ showAncestors(cid, depth-1, 0); } } db_finalize(&q); @@ -229,11 +229,11 @@ @ <div class="section-title">Leaves</div> @ <ul> } @ <li> hyperlink_to_uuid(zUuid); - @ %s(zCom) (by %s(zUser) on %s(zDate)) + @ %w(zCom) (by %s(zUser) on %s(zDate)) } db_finalize(&q); if( cnt ){ @ </ul> } @@ -316,11 +316,10 @@ " WHERE blob.rid=%d" " AND event.objid=%d", rid, rid ); if( db_step(&q)==SQLITE_ROW ){ - Blob comment; const char *zUuid = db_column_text(&q, 0); char *zTitle = mprintf("Version: [%.10s]", zUuid); style_header(zTitle); free(zTitle); /*@ <h2>Version %s(zUuid)</h2>*/ @@ -329,14 +328,12 @@ @ <tr><th>Version:</th><td>%s(zUuid)</td></tr> @ <tr><th>Date:</th><td>%s(db_column_text(&q, 1))</td></tr> if( g.okSetup ){ @ <tr><th>Record ID:</th><td>%d(rid)</td></tr> } - @ <tr><th>Original User:</th><td>%s(db_column_text(&q, 2))</td></tr> - @ <tr><th>Original Comment:</th><td> - db_ephemeral_blob(&q, 3, &comment); - wiki_convert(&comment, 0, 0); + @ <tr><th>Original User:</th><td>%h(db_column_text(&q, 2))</td></tr> + @ <tr><th>Original Comment:</th><td>%w(db_column_text(&q,3))</td></tr> @ </td></tr> @ <tr><th>Commands:</th> @ <td> @ <a href="%s(g.zBaseURL)/vdiff/%d(rid)">diff</a> @ | <a href="%s(g.zBaseURL)/zip/%s(zUuid).zip">ZIP archive</a> @@ -602,21 +599,17 @@ ); while( db_step(&q)==SQLITE_ROW ){ const char *zName = db_column_text(&q, 0); const char *zDate = db_column_text(&q, 1); const char *zFuuid = db_column_text(&q, 2); + const char *zCom = db_column_text(&q, 3); const char *zUser = db_column_text(&q, 4); const char *zVers = db_column_text(&q, 5); - Blob comment; @ File <a href="%s(g.zBaseURL)/finfo?name=%T(zName)">%h(zName)</a> @ uuid %s(zFuuid) part of check-in hyperlink_to_uuid(zVers); - blob_zero(&comment); - db_column_blob(&q, 3, &comment); - blob_appendf(&comment, " by %h(zUser) on %s(zDate)"); - wiki_convert(&comment, 0, 0); - blob_reset(&comment); + @ %w(zCom) by %h(zUser) on %s(zDate) cnt++; } db_finalize(&q); db_prepare(&q, "SELECT substr(tagname, 6, 10000), datetime(event.mtime)," @@ -651,18 +644,14 @@ ); while( db_step(&q)==SQLITE_ROW ){ const char *zDate = db_column_text(&q, 0); const char *zUuid = db_column_text(&q, 3); const char *zUser = db_column_text(&q, 1); - Blob comment; + const char *zCom = db_column_text(&q, 2); @ Manifest of version hyperlink_to_uuid(zUuid); - blob_zero(&comment); - db_column_blob(&q, 2, &comment); - blob_appendf(&comment, " by %h(zUser) on %s(zDate)"); - wiki_convert(&comment, 0, 0); - blob_reset(&comment); + @ %w(zCom) by %h(zUser) on %s(zDate) cnt++; } db_finalize(&q); } if( cnt==0 ){
Modified src/printf.c from [63619c9ec6] to [af38cba6b0].
@@ -50,10 +50,12 @@ #define etHTMLIZE 16 /* Make text safe for HTML */ #define etHTTPIZE 17 /* Make text safe for HTTP. "/" encoded as %2f */ #define etURLIZE 18 /* Make text safe for HTTP. "/" not encoded */ #define etFOSSILIZE 19 /* The fossil header encoding format. */ #define etPATH 20 /* Path type */ +#define etWIKISTR 21 /* Wiki text rendered from a char* */ +#define etWIKIBLOB 22 /* Wiki text rendered from a Blob* */ /* ** An "etByte" is an 8-bit unsigned value. */ @@ -93,10 +95,12 @@ { 'z', 0, 6, etDYNSTRING, 0, 0 }, { 'q', 0, 4, etSQLESCAPE, 0, 0 }, { 'Q', 0, 4, etSQLESCAPE2, 0, 0 }, { 'b', 0, 2, etBLOB, 0, 0 }, { 'B', 0, 2, etBLOBSQL, 0, 0 }, + { 'w', 0, 2, etWIKISTR, 0, 0 }, + { 'W', 0, 2, etWIKIBLOB, 0, 0 }, { 'h', 0, 4, etHTMLIZE, 0, 0 }, { 't', 0, 4, etHTTPIZE, 0, 0 }, /* "/" -> "%2F" */ { 'T', 0, 4, etURLIZE, 0, 0 }, /* "/" unchanged */ { 'F', 0, 4, etFOSSILIZE, 0, 0 }, { 'c', 0, 0, etCHARX, 0, 0 }, @@ -171,12 +175,11 @@ ** Note that the order in which automatic variables are declared below ** seems to make a big difference in determining how fast this beast ** will run. */ int vxprintf( - void (*func)(void*,const char*,int), /* Consumer of text */ - void *arg, /* First argument to the consumer */ + Blob *pBlob, /* Append output to this blob */ const char *fmt, /* Format string */ va_list ap /* arguments */ ){ int c; /* Next character in the format string */ char *bufpt; /* Pointer to the conversion buffer */ @@ -210,26 +213,25 @@ etByte flag_dp; /* True if decimal point should be shown */ etByte flag_rtz; /* True if trailing zeros should be removed */ etByte flag_exp; /* True to force display of the exponent */ int nsd; /* Number of significant digits returned */ - func(arg,"",0); count = length = 0; bufpt = 0; for(; (c=(*fmt))!=0; ++fmt){ if( c!='%' ){ int amt; bufpt = (char *)fmt; amt = 1; while( (c=(*++fmt))!='%' && c!=0 ) amt++; - (*func)(arg,bufpt,amt); + blob_append(pBlob,bufpt,amt); count += amt; if( c==0 ) break; } if( (c=(*++fmt))==0 ){ errorflag = 1; - (*func)(arg,"%",1); + blob_append(pBlob,"%",1); count++; break; } /* Find out what flags are present */ flag_leftjustify = flag_plussign = flag_blanksign = @@ -659,16 +661,31 @@ zExtra = bufpt = fossilize(zMem, -1); length = strlen(bufpt); if( precision>=0 && precision<length ) length = precision; break; } + case etWIKISTR: { + char *zWiki = va_arg(ap, char*); + Blob wiki; + blob_init(&wiki, zWiki, -1); + wiki_convert(&wiki, pBlob, WIKI_INLINE); + blob_reset(&wiki); + length = width = 0; + break; + } + case etWIKIBLOB: { + Blob *pWiki = va_arg(ap, Blob*); + wiki_convert(pWiki, pBlob, WIKI_INLINE); + length = width = 0; + break; + } case etERROR: buf[0] = '%'; buf[1] = c; errorflag = 0; idx = 1+(c!=0); - (*func)(arg,"%",idx); + blob_append(pBlob,"%",idx); count += idx; if( c==0 ) fmt--; break; }/* End switch over the format type */ /* @@ -680,30 +697,30 @@ register int nspace; nspace = width-length; if( nspace>0 ){ count += nspace; while( nspace>=etSPACESIZE ){ - (*func)(arg,spaces,etSPACESIZE); + blob_append(pBlob,spaces,etSPACESIZE); nspace -= etSPACESIZE; } - if( nspace>0 ) (*func)(arg,spaces,nspace); + if( nspace>0 ) blob_append(pBlob,spaces,nspace); } } if( length>0 ){ - (*func)(arg,bufpt,length); + blob_append(pBlob,bufpt,length); count += length; } if( flag_leftjustify ){ register int nspace; nspace = width-length; if( nspace>0 ){ count += nspace; while( nspace>=etSPACESIZE ){ - (*func)(arg,spaces,etSPACESIZE); + blob_append(pBlob,spaces,etSPACESIZE); nspace -= etSPACESIZE; } - if( nspace>0 ) (*func)(arg,spaces,nspace); + if( nspace>0 ) blob_append(pBlob,spaces,nspace); } } if( zExtra ){ free(zExtra); }