Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Update SQLite to the latest build from CVS. Add in the FTS3 extension, though it is not yet being used. Additional work toward tickets. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA1: |
f394d845601592086f19411cec9aa25e |
| User & Date: | drh 2007-11-25 16:13:52.000 |
Context
|
2007-11-25
| ||
| 17:13 | Changes to the diff algorithm to put bounds on run-time for very large files with many differences. (This came up on the previous check-in when you try to diff the two versions of sqlite3.c.) ... (check-in: 4c22ae52fd user: drh tags: trunk) | |
| 16:13 | Update SQLite to the latest build from CVS. Add in the FTS3 extension, though it is not yet being used. Additional work toward tickets. ... (check-in: f394d84560 user: drh tags: trunk) | |
|
2007-11-24
| ||
| 23:59 | More work on ticketing. This is a non-working incremental check-in. ... (check-in: a5e4e1ba96 user: drh tags: trunk) | |
Changes
Changes to src/info.c.
| ︙ | ︙ | |||
695 696 697 698 699 700 701 | @ %h(blob_str(&diff)) @ </pre></blockquote> blob_reset(&diff); style_footer(); } /* | < | 695 696 697 698 699 700 701 702 703 704 705 706 707 708 |
@ %h(blob_str(&diff))
@ </pre></blockquote>
blob_reset(&diff);
style_footer();
}
/*
** WEBPAGE: fview
** URL: /fview?name=UUID
**
** Show the complete content of a file identified by UUID
** as preformatted text.
*/
void fview_page(void){
|
| ︙ | ︙ | |||
733 734 735 736 737 738 739 | @ <blockquote><pre> content_get(rid, &content); @ %h(blob_str(&content)) @ </pre></blockquote> blob_reset(&content); style_footer(); } | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 |
@ <blockquote><pre>
content_get(rid, &content);
@ %h(blob_str(&content))
@ </pre></blockquote>
blob_reset(&content);
style_footer();
}
/*
** WEBPAGE: info
** URL: info/UUID
**
** The argument is a UUID which might be a baseline or a file or
** a ticket or something else. It might also be a wiki page name.
** Figure out what the UUID is an jump to it. If there is ambiguity,
** draw a page and let the user select the interpretation.
*/
void info_page(void){
const char *zName;
int rc, nName, cnt;
Stmt q;
zName = P("name");
if( zName==0 ) cgi_redirect("index");
nName = strlen(zName);
if( nName<4 || nName>UUID_SIZE || !validate16(zName, nName) ){
cgi_redirect("index");
}
db_multi_exec(
"CREATE TEMP TABLE refs(type,link);"
"INSERT INTO refs "
" SELECT 'f', rid FROM blob WHERE uuid GLOB '%s*'"
" UNION ALL"
" SELECT 'w', substr(tagname,6) FROM tag"
" WHERE tagname='wiki-%q'"
" UNION ALL"
" SELECT 't', tkt_uuid FROM ticket WHERE tkt_uuid GLOB '%s*';",
zName, zName, zName
);
cnt = db_int(0, "SELECT count(*) FROM refs");
if( cnt==0 ){
style_header("Broken Link");
@ <p>No such object: %h(zName)</p>
style_footer();
return;
}
db_prepare(&q, "SELECT type, link FROM refs");
db_step(&q);
if( cnt==1 ){
int type = *db_column_text(&q, 0);
int rid = db_column_int(&q, 1);
db_finalize(&q);
if( type=='w' ){
wiki_page();
}else if( type=='t' ){
tktview_page();
}else{
cgi_replace_parameter("name", mprintf("%d", rid));
if( db_exists("SELECT 1 FROM mlink WHERE mid=%d", rid) ){
vinfo_page();
}else{
finfo_page();
}
}
return;
}
/* Multiple objects */
style_header("Ambiguous Link");
@ <h2>Ambiguous Link: %h(zName)</h2>
@ <ul>
while( rc==SQLITE_ROW ){
int type = *db_column_text(&q, 0);
if( type=='f' ){
@ <li><p>
object_description(db_column_int(&q, 1), 1);
@ </p></li>
}else if( type=='w' ){
@ <li><p>
@ Wiki page <a href="%s(g.zBaseURL)/wiki?name=%s(zName)">%s(zName)</a>.
@ </li><p>
}else if( type=='t' ){
const char *zUuid = db_column_text(&q, 1);
@ <li><p>
@ Ticket <a href="%s(g.zBaseURL)/tktview?name=%s(zUuid)">%s(zUuid)</a>.
@ </li><p>
}
rc = db_step(&q);
}
@ </ul>
style_footer();
db_finalize(&q);
}
|
Changes to src/main.mk.
| ︙ | ︙ | |||
772 773 774 775 776 777 778 | $(XTCC) -o zip.o -c zip_.c zip.h: makeheaders ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers sqlite3.o: $(SRCDIR)/sqlite3.c | | | 772 773 774 775 776 777 778 779 780 | $(XTCC) -o zip.o -c zip_.c zip.h: makeheaders ./makeheaders add_.c:add.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h construct_.c:construct.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendents_.c:descendents.h diff_.c:diff.h diffcmd_.c:diffcmd.h encode_.c:encode.h file_.c:file.h http_.c:http.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h rss_.c:rss.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h style_.c:style.h subscript_.c:subscript.h sync_.c:sync.h tag_.c:tag.h timeline_.c:timeline.h tkt_.c:tkt.h tktconfig_.c:tktconfig.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h ./VERSION.h touch headers sqlite3.o: $(SRCDIR)/sqlite3.c $(XTCC) -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_PRIVATE= -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_FTS3=1 -c $(SRCDIR)/sqlite3.c -o sqlite3.o |
Changes to src/makemake.tcl.
| ︙ | ︙ | |||
160 161 162 163 164 165 166 |
puts "$s.h:\tmakeheaders"
puts "\t./makeheaders $mhargs\n\ttouch headers\n"
}
puts "sqlite3.o:\t\$(SRCDIR)/sqlite3.c"
set opt {-DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_PRIVATE=}
| | > | 160 161 162 163 164 165 166 167 168 169 |
puts "$s.h:\tmakeheaders"
puts "\t./makeheaders $mhargs\n\ttouch headers\n"
}
puts "sqlite3.o:\t\$(SRCDIR)/sqlite3.c"
set opt {-DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_PRIVATE=}
append opt " -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4"
append opt " -DSQLITE_ENABLE_FTS3=1"
puts "\t\$(XTCC) $opt -c \$(SRCDIR)/sqlite3.c -o sqlite3.o\n"
|
Changes to src/sqlite3.c.
more than 10,000 changes
Changes to src/style.c.
| ︙ | ︙ | |||
74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
/*
** Draw the header.
*/
void style_header(const char *zTitle){
const char *zLogInOut = "Login";
const char *zHeader = db_get("header", (char*)zDefaultHeader);
login_check_credentials();
/* Generate the header up through the main menu */
pInterp = SbS_Create();
SbS_Store(pInterp, "project_name",
db_get("project-name","Unnamed Fossil Project"), 0);
SbS_Store(pInterp, "title", zTitle, 0);
SbS_Store(pInterp, "baseurl", g.zBaseURL, 0);
| > > | 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
/*
** Draw the header.
*/
void style_header(const char *zTitle){
const char *zLogInOut = "Login";
const char *zHeader = db_get("header", (char*)zDefaultHeader);
login_check_credentials();
if( pInterp ) return;
/* Generate the header up through the main menu */
pInterp = SbS_Create();
SbS_Store(pInterp, "project_name",
db_get("project-name","Unnamed Fossil Project"), 0);
SbS_Store(pInterp, "title", zTitle, 0);
SbS_Store(pInterp, "baseurl", g.zBaseURL, 0);
|
| ︙ | ︙ | |||
133 134 135 136 137 138 139 |
g.cgiPanic = 1;
}
/*
** Draw the footer at the bottom of the page.
*/
void style_footer(void){
| > > > | > | 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
g.cgiPanic = 1;
}
/*
** Draw the footer at the bottom of the page.
*/
void style_footer(void){
const char *zFooter;
if( pInterp==0 ) return;
zFooter = db_get("footer", (char*)zDefaultFooter);
@ </div>
SbS_Render(pInterp, zFooter);
SbS_Destroy(pInterp);
pInterp = 0;
}
/* @-comment: // */
/*
** The default page header.
*/
const char zDefaultHeader[] =
|
| ︙ | ︙ |
Changes to src/tkt.c.
| ︙ | ︙ | |||
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
** in sorted order in azField[].
**
** Also allocate space for azValue[] and azAppend[] and initialize
** all the values there to zero.
*/
static void getAllTicketFields(void){
Stmt q;
if( nField>0 ) return;
db_prepare(&q, "PRAGMA table_info(ticket)");
while( db_step(&q)==SQLITE_ROW ){
const char *zField = db_column_text(&q, 1);
if( strncmp(zField,"tkt_",4)==0 ) continue;
if( nField%10==0 ){
azField = realloc(azField, sizeof(azField)*3*(nField+10) );
if( azField==0 ){
fossil_fatal("out of memory");
}
}
azField[nField] = mprintf("%s", zField);
nField++;
}
db_finalize(&q);
qsort(azField, nField, sizeof(azField[0]), nameCmpr);
azAppend = &azField[nField];
| > | > > > | 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
** in sorted order in azField[].
**
** Also allocate space for azValue[] and azAppend[] and initialize
** all the values there to zero.
*/
static void getAllTicketFields(void){
Stmt q;
int i;
if( nField>0 ) return;
db_prepare(&q, "PRAGMA table_info(ticket)");
while( db_step(&q)==SQLITE_ROW ){
const char *zField = db_column_text(&q, 1);
if( strncmp(zField,"tkt_",4)==0 ) continue;
if( nField%10==0 ){
azField = realloc(azField, sizeof(azField)*3*(nField+10) );
if( azField==0 ){
fossil_fatal("out of memory");
}
}
azField[nField] = mprintf("%s", zField);
nField++;
}
db_finalize(&q);
qsort(azField, nField, sizeof(azField[0]), nameCmpr);
azAppend = &azField[nField];
memset(azAppend, 0, sizeof(azAppend[0])*nField);
azValue = &azAppend[nField];
for(i=0; i<nField; i++){
azValue[i] = "";
}
}
/*
** Return the index into azField[] of the given field name.
** Return -1 if zField is not in azField[].
*/
static int fieldId(const char *zField){
|
| ︙ | ︙ | |||
211 212 213 214 215 216 217 |
if( checkTime && db_changes()==0 ){
static int isInit = 0;
if( !isInit ){
db_multi_exec("CREATE TEMP TABLE _pending_ticket(uuid TEXT UNIQUE)");
db_commit_hook(ticket_rebuild_at_commit, 1);
isInit = 1;
}
| | | 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 |
if( checkTime && db_changes()==0 ){
static int isInit = 0;
if( !isInit ){
db_multi_exec("CREATE TEMP TABLE _pending_ticket(uuid TEXT UNIQUE)");
db_commit_hook(ticket_rebuild_at_commit, 1);
isInit = 1;
}
db_multi_exec("INSERT OR IGNORE INTO _pending_ticket "
"VALUES(%Q)", p->zTicketUuid);
}
blob_reset(&sql);
}
/*
** Rebuild an entire entry in the TICKET table
|
| ︙ | ︙ | |||
313 314 315 316 317 318 319 |
initializeVariablesFromDb();
zScript = (char*)SbS_Fetch(pInterp, "tktview_template", -1, &nScript);
zScript = mprintf("%.*s", nScript, zScript);
SbS_Render(pInterp, zScript);
style_footer();
}
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 317 318 319 320 321 322 323 324 325 326 327 328 329 330 |
initializeVariablesFromDb();
zScript = (char*)SbS_Fetch(pInterp, "tktview_template", -1, &nScript);
zScript = mprintf("%.*s", nScript, zScript);
SbS_Render(pInterp, zScript);
style_footer();
}
/*
** Subscript command: STRING FIELD append_field
**
** FIELD is the name of a database column to which we might want
** to append text. STRING is the text to be appended to that
|
| ︙ | ︙ | |||
439 440 441 442 443 444 445 |
|| strlen(azValue[i])!=nValue ){
blob_appendf(&tktchng, "J %s %z\n",
azField[i], fossilize(zValue,nValue));
}
}
}
}
| | | | | | | | | < > > | | > < | 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 |
|| strlen(azValue[i])!=nValue ){
blob_appendf(&tktchng, "J %s %z\n",
azField[i], fossilize(zValue,nValue));
}
}
}
}
if( *(char**)pUuid ){
zUuid = db_text(0,
"SELECT tkt_uuid FROM ticket WHERE tkt_uuid GLOB '%s*'", P("name")
);
}else{
zUuid = db_text(0, "SELECT lower(hex(randomblob(20)))");
}
*(const char**)pUuid = zUuid;
blob_appendf(&tktchng, "K %s\n", zUuid);
blob_appendf(&tktchng, "U %F\n", g.zLogin ? g.zLogin : "");
md5sum_blob(&tktchng, &cksum);
blob_appendf(&tktchng, "Z %b\n", &cksum);
if( strncmp(g.zPath,"debug_",6)==0 ){
@ <hr><pre>
@ %h(blob_str(&tktchng))
@ </pre><hr>
blob_zero(&tktchng);
SbS_Pop(p, 1);
return SBS_OK;
}
rid = content_put(&tktchng, 0, 0);
if( rid==0 ){
fossil_panic("trouble committing ticket: %s", g.zErrMsg);
}
manifest_crosslink(rid, &tktchng);
return SBS_RETURN;
}
/*
** WEBPAGE: tktnew
** WEBPAGE: debug_tktnew
*/
void tktnew_page(void){
char *zScript;
int nScript;
char *zNewUuid = 0;
login_check_credentials();
if( !g.okNewTkt ){ login_needed(); return; }
style_header("New Ticket");
ticket_init();
getAllTicketFields();
initializeVariablesFromCGI();
@ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)">
zScript = (char*)SbS_Fetch(pInterp, "tktnew_template", -1, &nScript);
zScript = mprintf("%.*s", nScript, zScript);
SbS_Store(pInterp, "login", g.zLogin, 0);
SbS_Store(pInterp, "date", db_text(0, "SELECT datetime('now')"), 2);
SbS_AddVerb(pInterp, "submit_ticket", submitTicketCmd, (void*)&zNewUuid);
if( SbS_Render(pInterp, zScript)==SBS_RETURN && zNewUuid ){
cgi_redirect(mprintf("%s/tktview/%s", g.zBaseURL, zNewUuid));
return;
}
@ </form>
style_footer();
}
/*
** WEBPAGE: tktedit
** WEBPAGE: debug_tktedit
*/
void tktedit_page(void){
char *zScript;
int nScript;
int nName;
const char *zName;
int nRec;
login_check_credentials();
if( !g.okApndTkt && !g.okWrTkt ){ login_needed(); return; }
style_header("Edit Ticket");
zName = P("name");
if( zName==0 || (nName = strlen(zName))<4 || nName>UUID_SIZE
|| !validate16(zName,nName) ){
|
| ︙ | ︙ | |||
537 538 539 540 541 542 543 |
style_footer();
return;
}
ticket_init();
getAllTicketFields();
initializeVariablesFromCGI();
initializeVariablesFromDb();
| | | | | | 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 |
style_footer();
return;
}
ticket_init();
getAllTicketFields();
initializeVariablesFromCGI();
initializeVariablesFromDb();
@ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)">
@ <input type="hidden" name="name" value="%s(zName)">
zScript = (char*)SbS_Fetch(pInterp, "tktedit_template", -1, &nScript);
zScript = mprintf("%.*s", nScript, zScript);
SbS_Store(pInterp, "login", g.zLogin, 0);
SbS_Store(pInterp, "date", db_text(0, "SELECT datetime('now')"), 2);
SbS_AddVerb(pInterp, "append_field", appendRemarkCmd, 0);
SbS_AddVerb(pInterp, "submit_ticket", submitTicketCmd, (void*)&zName);
if( SbS_Render(pInterp, zScript)==SBS_RETURN && zName ){
cgi_redirect(mprintf("%s/tktview/%s", g.zBaseURL, zName));
return;
}
@ </form>
style_footer();
}
|
Changes to src/tktconfig.c.
| ︙ | ︙ | |||
169 170 171 172 173 174 175 |
@ # rendered.
@ #
@ {
@ <!-- load database field names not found in CGI with an empty string -->
@ <!-- start a form -->
@ [{
@ {Open} /status set
| | | 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
@ # rendered.
@ #
@ {
@ <!-- load database field names not found in CGI with an empty string -->
@ <!-- start a form -->
@ [{
@ {Open} /status set
@ submit_ticket
@ } /submit exists if]
@ <table cellpadding="5">
@ <tr>
@ <td colspan="2">
@ Enter a one-line summary of the problem:<br>
@ <input type="text" name="title" size="60" value="[{} /title get html]">
@ </td>
|
| ︙ | ︙ | |||
203 204 205 206 207 208 209 | @ </td> @ <td>How debilitating is the problem? How badly does the problem @ effect the operation of the product?</td> @ </tr> @ @ <tr> @ <td align="right">EMail: | | | 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 |
@ </td>
@ <td>How debilitating is the problem? How badly does the problem
@ effect the operation of the product?</td>
@ </tr>
@
@ <tr>
@ <td align="right">EMail:
@ <input type="text" name="contact" value="[{} /contact get html]" size="30">
@ </td>
@ <td>Not publically visible. Used by developers to contact you with
@ questions.</td>
@ </tr>
@
@ <tr>
@ <td colspan="2">
|
| ︙ | ︙ | |||
254 255 256 257 258 259 260 |
@ # CGI parameters.
@ {
@ [
@ login /username get /username set
@ {
@ {
@ username login eq /samename set
| < | | | | 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 |
@ # CGI parameters.
@ {
@ [
@ login /username get /username set
@ {
@ {
@ username login eq /samename set
@ {
@ "\n\n<hr><i>" login " added on " date ":</i><br>\n"
@ cmappnd 6 concat /comment append_field
@ } samename if
@ {
@ "\n\n<hr><i>" login " claiming to be " username " added on " date
@ "</i><br>\n" cmappnd 8 concat /comment append_field
@ } samename not if
@ } 0 {} /cmappnd get length lt if
@ submit_ticket
@ } /submit exists if
@ ]
@ <table cellpadding="5">
|
| ︙ | ︙ |
Changes to src/wikiformat.c.
| ︙ | ︙ | |||
765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 |
*/
static void endAutoParagraph(Renderer *p){
if( p->inAutoParagraph ){
popStackToTag(p, MARKUP_P);
p->inAutoParagraph = 0;
}
}
/*
** Resolve a hyperlink. The argument is the content of the [...]
** in the wiki. Append the URL to the output of the Renderer.
*/
static void resolveHyperlink(const char *zTarget, Renderer *p){
if( strncmp(zTarget, "http:", 5)==0
|| strncmp(zTarget, "https:", 6)==0
|| strncmp(zTarget, "ftp:", 4)==0
|| strncmp(zTarget, "mailto:", 7)==0
){
blob_appendf(p->pOut, zTarget);
}else if( zTarget[0]=='/' ){
blob_appendf(p->pOut, "%s%h", g.zBaseURL, zTarget);
}else if( wiki_name_is_wellformed(zTarget) ){
blob_appendf(p->pOut, "%s/wiki?name=%T", g.zBaseURL, zTarget);
}else{
blob_appendf(p->pOut, "error");
}
}
| > > > > > > > > > > > > > > | 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 |
*/
static void endAutoParagraph(Renderer *p){
if( p->inAutoParagraph ){
popStackToTag(p, MARKUP_P);
p->inAutoParagraph = 0;
}
}
/*
** If the input string corresponds to an existing baseline,
** return true.
*/
static int is_valid_uuid(const char *z){
int n = strlen(z);
int rid;
if( n<4 || n>UUID_SIZE ) return 0;
if( !validate16(z, n) ) return 0;
return 1;
}
/*
** Resolve a hyperlink. The argument is the content of the [...]
** in the wiki. Append the URL to the output of the Renderer.
*/
static void resolveHyperlink(const char *zTarget, Renderer *p){
if( strncmp(zTarget, "http:", 5)==0
|| strncmp(zTarget, "https:", 6)==0
|| strncmp(zTarget, "ftp:", 4)==0
|| strncmp(zTarget, "mailto:", 7)==0
){
blob_appendf(p->pOut, zTarget);
}else if( zTarget[0]=='/' ){
blob_appendf(p->pOut, "%s%h", g.zBaseURL, zTarget);
}else if( is_valid_uuid(zTarget) ){
blob_appendf(p->pOut, "%s/info/%s", g.zBaseURL, zTarget);
}else if( wiki_name_is_wellformed(zTarget) ){
blob_appendf(p->pOut, "%s/wiki?name=%T", g.zBaseURL, zTarget);
}else{
blob_appendf(p->pOut, "error");
}
}
|
| ︙ | ︙ |