Fossil SCM
Merge trunk
Commit
4aa351bba8350caf1ad11b11b64f23c2c450216e
Parent
86ab1f468b0929f…
43 files changed
+1
-1
+2
-1
+10
-3
+9
-2
+35
-1
+2
-2
+3
-3
+1
-1
+31
-5
+68
-54
+21
+6
-6
+15
-8
+1
-1
+1
-1
+3
-2
+15
-2
+7
-5
+64
-53
+64
-53
+224
+5
-5
+11
-12
+9
-9
+32
-9
+235
-76
+16
-20
+7
-7
+30
-10
+1
-1
+3
+535
+1
-1
+1
-1
+2
-2
+3
-684
+11
-1
+22
-1
+1
-1
+11
-5
+15
-2
+18
-2
+13
-2
~
VERSION
~
skins/eagle/footer.txt
~
skins/eagle/header.txt
~
skins/enhanced1/header.txt
~
skins/etienne1/css.txt
~
src/branch.c
~
src/browse.c
~
src/cgi.c
~
src/db.c
~
src/finfo.c
~
src/graph.c
~
src/http.c
~
src/http_socket.c
~
src/http_transport.c
~
src/info.c
~
src/main.c
~
src/main.mk
~
src/makemake.tcl
~
src/manifest.c
~
src/manifest.c
~
src/markdown.md
~
src/md5.c
~
src/mkbuiltin.c
~
src/regexp.c
~
src/schema.c
~
src/search.c
~
src/setup.c
~
src/sha1.c
~
src/shell.c
~
src/sqlcmd.c
~
src/stat.c
~
src/statrep.c
~
src/style.c
~
src/tag.c
~
src/th_main.c
~
src/timeline.c
~
src/url.c
~
src/wiki.c
~
win/Makefile.PellesCGMake
~
win/Makefile.dmc
~
win/Makefile.mingw
~
win/Makefile.mingw.mistachkin
~
win/Makefile.msc
M
VERSION
+1
-1
| --- VERSION | ||
| +++ VERSION | ||
| @@ -1,1 +1,1 @@ | ||
| 1 | -1.30 | |
| 1 | +1.31 | |
| 2 | 2 |
| --- VERSION | |
| +++ VERSION | |
| @@ -1,1 +1,1 @@ | |
| 1 | 1.30 |
| 2 |
| --- VERSION | |
| +++ VERSION | |
| @@ -1,1 +1,1 @@ | |
| 1 | 1.31 |
| 2 |
+2
-1
| --- skins/eagle/footer.txt | ||
| +++ skins/eagle/footer.txt | ||
| @@ -11,14 +11,15 @@ | ||
| 11 | 11 | return [string range $version 1 [expr {$length - 2}]] |
| 12 | 12 | } |
| 13 | 13 | set version [getVersion $manifest_version] |
| 14 | 14 | set tclVersion [getTclVersion] |
| 15 | 15 | set fossilUrl https://www.fossil-scm.org |
| 16 | + set fossilDate [string range $manifest_date 0 9]T[string range $manifest_date 11 end] | |
| 16 | 17 | </th1> |
| 17 | 18 | This page was generated in about |
| 18 | 19 | <th1>puts [expr {([utime]+[stime]+1000)/1000*0.001}]</th1>s by |
| 19 | 20 | <a href="$fossilUrl/">Fossil</a> |
| 20 | 21 | version $release_version $tclVersion |
| 21 | 22 | <a href="$fossilUrl/index.html/info/$version">$manifest_version</a> |
| 22 | - <a href="$fossilUrl/index.html/timeline?c=$manifest_date&y=ci">$manifest_date</a> | |
| 23 | + <a href="$fossilUrl/index.html/timeline?c=$fossilDate&y=ci">$manifest_date</a> | |
| 23 | 24 | </div> |
| 24 | 25 | </body></html> |
| 25 | 26 |
| --- skins/eagle/footer.txt | |
| +++ skins/eagle/footer.txt | |
| @@ -11,14 +11,15 @@ | |
| 11 | return [string range $version 1 [expr {$length - 2}]] |
| 12 | } |
| 13 | set version [getVersion $manifest_version] |
| 14 | set tclVersion [getTclVersion] |
| 15 | set fossilUrl https://www.fossil-scm.org |
| 16 | </th1> |
| 17 | This page was generated in about |
| 18 | <th1>puts [expr {([utime]+[stime]+1000)/1000*0.001}]</th1>s by |
| 19 | <a href="$fossilUrl/">Fossil</a> |
| 20 | version $release_version $tclVersion |
| 21 | <a href="$fossilUrl/index.html/info/$version">$manifest_version</a> |
| 22 | <a href="$fossilUrl/index.html/timeline?c=$manifest_date&y=ci">$manifest_date</a> |
| 23 | </div> |
| 24 | </body></html> |
| 25 |
| --- skins/eagle/footer.txt | |
| +++ skins/eagle/footer.txt | |
| @@ -11,14 +11,15 @@ | |
| 11 | return [string range $version 1 [expr {$length - 2}]] |
| 12 | } |
| 13 | set version [getVersion $manifest_version] |
| 14 | set tclVersion [getTclVersion] |
| 15 | set fossilUrl https://www.fossil-scm.org |
| 16 | set fossilDate [string range $manifest_date 0 9]T[string range $manifest_date 11 end] |
| 17 | </th1> |
| 18 | This page was generated in about |
| 19 | <th1>puts [expr {([utime]+[stime]+1000)/1000*0.001}]</th1>s by |
| 20 | <a href="$fossilUrl/">Fossil</a> |
| 21 | version $release_version $tclVersion |
| 22 | <a href="$fossilUrl/index.html/info/$version">$manifest_version</a> |
| 23 | <a href="$fossilUrl/index.html/timeline?c=$fossilDate&y=ci">$manifest_date</a> |
| 24 | </div> |
| 25 | </body></html> |
| 26 |
+10
-3
| --- skins/eagle/header.txt | ||
| +++ skins/eagle/header.txt | ||
| @@ -73,11 +73,11 @@ | ||
| 73 | 73 | <a href="$logourl"> |
| 74 | 74 | <img src="$logo_image_url" border="0" alt="$project_name"> |
| 75 | 75 | </a> |
| 76 | 76 | </div> |
| 77 | 77 | <div class="title">$<title></div> |
| 78 | - <div class="status"><th1> | |
| 78 | + <div class="status"><nobr><th1> | |
| 79 | 79 | if {[info exists login]} { |
| 80 | 80 | puts "Logged in as $login" |
| 81 | 81 | } else { |
| 82 | 82 | puts "Not logged in" |
| 83 | 83 | } |
| @@ -86,12 +86,19 @@ | ||
| 86 | 86 | <script> |
| 87 | 87 | function updateClock(){ |
| 88 | 88 | var e = document.getElementById("clock"); |
| 89 | 89 | if(e){ |
| 90 | 90 | var d = new Date(); |
| 91 | - e.innerHTML=d.toISOString().replace("T"," ").replace(/:\d\d\.\d+Z/,""); | |
| 92 | - setTimeout("updateClock();",(60-d.getSeconds())*1000); | |
| 91 | + function f(n) { | |
| 92 | + return n < 10 ? '0' + n : n; | |
| 93 | + } | |
| 94 | + e.innerHTML = d.getUTCFullYear()+ '-' + | |
| 95 | + f(d.getUTCMonth() + 1) + '-' + | |
| 96 | + f(d.getUTCDate()) + ' ' + | |
| 97 | + f(d.getUTCHours()) + ':' + | |
| 98 | + f(d.getUTCMinutes()); | |
| 99 | + setTimeout("updateClock();",(60-d.getUTCSeconds())*1000); | |
| 93 | 100 | } |
| 94 | 101 | } |
| 95 | 102 | updateClock(); |
| 96 | 103 | </script> |
| 97 | 104 | <div class="mainmenu"> |
| 98 | 105 |
| --- skins/eagle/header.txt | |
| +++ skins/eagle/header.txt | |
| @@ -73,11 +73,11 @@ | |
| 73 | <a href="$logourl"> |
| 74 | <img src="$logo_image_url" border="0" alt="$project_name"> |
| 75 | </a> |
| 76 | </div> |
| 77 | <div class="title">$<title></div> |
| 78 | <div class="status"><th1> |
| 79 | if {[info exists login]} { |
| 80 | puts "Logged in as $login" |
| 81 | } else { |
| 82 | puts "Not logged in" |
| 83 | } |
| @@ -86,12 +86,19 @@ | |
| 86 | <script> |
| 87 | function updateClock(){ |
| 88 | var e = document.getElementById("clock"); |
| 89 | if(e){ |
| 90 | var d = new Date(); |
| 91 | e.innerHTML=d.toISOString().replace("T"," ").replace(/:\d\d\.\d+Z/,""); |
| 92 | setTimeout("updateClock();",(60-d.getSeconds())*1000); |
| 93 | } |
| 94 | } |
| 95 | updateClock(); |
| 96 | </script> |
| 97 | <div class="mainmenu"> |
| 98 |
| --- skins/eagle/header.txt | |
| +++ skins/eagle/header.txt | |
| @@ -73,11 +73,11 @@ | |
| 73 | <a href="$logourl"> |
| 74 | <img src="$logo_image_url" border="0" alt="$project_name"> |
| 75 | </a> |
| 76 | </div> |
| 77 | <div class="title">$<title></div> |
| 78 | <div class="status"><nobr><th1> |
| 79 | if {[info exists login]} { |
| 80 | puts "Logged in as $login" |
| 81 | } else { |
| 82 | puts "Not logged in" |
| 83 | } |
| @@ -86,12 +86,19 @@ | |
| 86 | <script> |
| 87 | function updateClock(){ |
| 88 | var e = document.getElementById("clock"); |
| 89 | if(e){ |
| 90 | var d = new Date(); |
| 91 | function f(n) { |
| 92 | return n < 10 ? '0' + n : n; |
| 93 | } |
| 94 | e.innerHTML = d.getUTCFullYear()+ '-' + |
| 95 | f(d.getUTCMonth() + 1) + '-' + |
| 96 | f(d.getUTCDate()) + ' ' + |
| 97 | f(d.getUTCHours()) + ':' + |
| 98 | f(d.getUTCMinutes()); |
| 99 | setTimeout("updateClock();",(60-d.getUTCSeconds())*1000); |
| 100 | } |
| 101 | } |
| 102 | updateClock(); |
| 103 | </script> |
| 104 | <div class="mainmenu"> |
| 105 |
+9
-2
| --- skins/enhanced1/header.txt | ||
| +++ skins/enhanced1/header.txt | ||
| @@ -86,12 +86,19 @@ | ||
| 86 | 86 | <script> |
| 87 | 87 | function updateClock(){ |
| 88 | 88 | var e = document.getElementById("clock"); |
| 89 | 89 | if(e){ |
| 90 | 90 | var d = new Date(); |
| 91 | - e.innerHTML=d.toISOString().replace("T"," ").replace(/:\d\d\.\d+Z/,""); | |
| 92 | - setTimeout("updateClock();",(60-d.getSeconds())*1000); | |
| 91 | + function f(n) { | |
| 92 | + return n < 10 ? '0' + n : n; | |
| 93 | + } | |
| 94 | + e.innerHTML = d.getUTCFullYear()+ '-' + | |
| 95 | + f(d.getUTCMonth() + 1) + '-' + | |
| 96 | + f(d.getUTCDate()) + ' ' + | |
| 97 | + f(d.getUTCHours()) + ':' + | |
| 98 | + f(d.getUTCMinutes()); | |
| 99 | + setTimeout("updateClock();",(60-d.getUTCSeconds())*1000); | |
| 93 | 100 | } |
| 94 | 101 | } |
| 95 | 102 | updateClock(); |
| 96 | 103 | </script> |
| 97 | 104 | <div class="mainmenu"> |
| 98 | 105 |
| --- skins/enhanced1/header.txt | |
| +++ skins/enhanced1/header.txt | |
| @@ -86,12 +86,19 @@ | |
| 86 | <script> |
| 87 | function updateClock(){ |
| 88 | var e = document.getElementById("clock"); |
| 89 | if(e){ |
| 90 | var d = new Date(); |
| 91 | e.innerHTML=d.toISOString().replace("T"," ").replace(/:\d\d\.\d+Z/,""); |
| 92 | setTimeout("updateClock();",(60-d.getSeconds())*1000); |
| 93 | } |
| 94 | } |
| 95 | updateClock(); |
| 96 | </script> |
| 97 | <div class="mainmenu"> |
| 98 |
| --- skins/enhanced1/header.txt | |
| +++ skins/enhanced1/header.txt | |
| @@ -86,12 +86,19 @@ | |
| 86 | <script> |
| 87 | function updateClock(){ |
| 88 | var e = document.getElementById("clock"); |
| 89 | if(e){ |
| 90 | var d = new Date(); |
| 91 | function f(n) { |
| 92 | return n < 10 ? '0' + n : n; |
| 93 | } |
| 94 | e.innerHTML = d.getUTCFullYear()+ '-' + |
| 95 | f(d.getUTCMonth() + 1) + '-' + |
| 96 | f(d.getUTCDate()) + ' ' + |
| 97 | f(d.getUTCHours()) + ':' + |
| 98 | f(d.getUTCMinutes()); |
| 99 | setTimeout("updateClock();",(60-d.getUTCSeconds())*1000); |
| 100 | } |
| 101 | } |
| 102 | updateClock(); |
| 103 | </script> |
| 104 | <div class="mainmenu"> |
| 105 |
+35
-1
| --- skins/etienne1/css.txt | ||
| +++ skins/etienne1/css.txt | ||
| @@ -30,10 +30,44 @@ | ||
| 30 | 30 | .title h1:after { |
| 31 | 31 | content: " / "; |
| 32 | 32 | color: #777; |
| 33 | 33 | font-weight: normal; |
| 34 | 34 | } |
| 35 | + | |
| 36 | +.content h1 { | |
| 37 | + font-size: 1.25em; | |
| 38 | +} | |
| 39 | +.content h2 { | |
| 40 | + font-size: 1.15em; | |
| 41 | +} | |
| 42 | +.content h2 { | |
| 43 | + font-size: 1.05em; | |
| 44 | + font-weight: bold; | |
| 45 | +} | |
| 46 | + | |
| 47 | +.section { | |
| 48 | + font-size: 1em; | |
| 49 | + font-weight: bold; | |
| 50 | + background-color: #f5f5f5; | |
| 51 | + border: 1px solid #d8d8d8; | |
| 52 | + border-radius: 3px 3px 0 0; | |
| 53 | + padding: 9px 10px 10px; | |
| 54 | + margin: 10px 0; | |
| 55 | +} | |
| 56 | + | |
| 57 | +.sectionmenu { | |
| 58 | + border: 1px solid #d8d8d8; | |
| 59 | + border-radius: 0 0 3px 3px; | |
| 60 | + border-top: 0; | |
| 61 | + margin-top: -10px; | |
| 62 | + margin-bottom: 10px; | |
| 63 | + padding: 10px; | |
| 64 | +} | |
| 65 | +.sectionmenu a { | |
| 66 | + display: inline-block; | |
| 67 | + margin-right: 1em; | |
| 68 | +} | |
| 35 | 69 | |
| 36 | 70 | .status { |
| 37 | 71 | float:right; |
| 38 | 72 | font-size:.7em; |
| 39 | 73 | padding-top:50px; |
| @@ -80,11 +114,11 @@ | ||
| 80 | 114 | border-top-right-radius: 5px; |
| 81 | 115 | } |
| 82 | 116 | |
| 83 | 117 | .content { |
| 84 | 118 | padding-top: 10px; |
| 85 | - font-size:.9em; | |
| 119 | + font-size:.8em; | |
| 86 | 120 | color: #444; |
| 87 | 121 | } |
| 88 | 122 | |
| 89 | 123 | .udiff, .sbsdiff, |
| 90 | 124 | .content blockquote { |
| 91 | 125 |
| --- skins/etienne1/css.txt | |
| +++ skins/etienne1/css.txt | |
| @@ -30,10 +30,44 @@ | |
| 30 | .title h1:after { |
| 31 | content: " / "; |
| 32 | color: #777; |
| 33 | font-weight: normal; |
| 34 | } |
| 35 | |
| 36 | .status { |
| 37 | float:right; |
| 38 | font-size:.7em; |
| 39 | padding-top:50px; |
| @@ -80,11 +114,11 @@ | |
| 80 | border-top-right-radius: 5px; |
| 81 | } |
| 82 | |
| 83 | .content { |
| 84 | padding-top: 10px; |
| 85 | font-size:.9em; |
| 86 | color: #444; |
| 87 | } |
| 88 | |
| 89 | .udiff, .sbsdiff, |
| 90 | .content blockquote { |
| 91 |
| --- skins/etienne1/css.txt | |
| +++ skins/etienne1/css.txt | |
| @@ -30,10 +30,44 @@ | |
| 30 | .title h1:after { |
| 31 | content: " / "; |
| 32 | color: #777; |
| 33 | font-weight: normal; |
| 34 | } |
| 35 | |
| 36 | .content h1 { |
| 37 | font-size: 1.25em; |
| 38 | } |
| 39 | .content h2 { |
| 40 | font-size: 1.15em; |
| 41 | } |
| 42 | .content h2 { |
| 43 | font-size: 1.05em; |
| 44 | font-weight: bold; |
| 45 | } |
| 46 | |
| 47 | .section { |
| 48 | font-size: 1em; |
| 49 | font-weight: bold; |
| 50 | background-color: #f5f5f5; |
| 51 | border: 1px solid #d8d8d8; |
| 52 | border-radius: 3px 3px 0 0; |
| 53 | padding: 9px 10px 10px; |
| 54 | margin: 10px 0; |
| 55 | } |
| 56 | |
| 57 | .sectionmenu { |
| 58 | border: 1px solid #d8d8d8; |
| 59 | border-radius: 0 0 3px 3px; |
| 60 | border-top: 0; |
| 61 | margin-top: -10px; |
| 62 | margin-bottom: 10px; |
| 63 | padding: 10px; |
| 64 | } |
| 65 | .sectionmenu a { |
| 66 | display: inline-block; |
| 67 | margin-right: 1em; |
| 68 | } |
| 69 | |
| 70 | .status { |
| 71 | float:right; |
| 72 | font-size:.7em; |
| 73 | padding-top:50px; |
| @@ -80,11 +114,11 @@ | |
| 114 | border-top-right-radius: 5px; |
| 115 | } |
| 116 | |
| 117 | .content { |
| 118 | padding-top: 10px; |
| 119 | font-size:.8em; |
| 120 | color: #444; |
| 121 | } |
| 122 | |
| 123 | .udiff, .sbsdiff, |
| 124 | .content blockquote { |
| 125 |
+2
-2
| --- src/branch.c | ||
| +++ src/branch.c | ||
| @@ -302,11 +302,11 @@ | ||
| 302 | 302 | fossil_fatal("branch subcommand should be one of: " |
| 303 | 303 | "new list ls"); |
| 304 | 304 | } |
| 305 | 305 | } |
| 306 | 306 | |
| 307 | -static char brlistQuery[] = | |
| 307 | +static const char brlistQuery[] = | |
| 308 | 308 | @ SELECT |
| 309 | 309 | @ tagxref.value, |
| 310 | 310 | @ max(event.mtime), |
| 311 | 311 | @ EXISTS(SELECT 1 FROM tagxref AS tx |
| 312 | 312 | @ WHERE tx.rid=tagxref.rid |
| @@ -343,11 +343,11 @@ | ||
| 343 | 343 | login_check_credentials(); |
| 344 | 344 | if( !g.perm.Read ){ login_needed(); return; } |
| 345 | 345 | style_header("Branches"); |
| 346 | 346 | style_adunit_config(ADUNIT_RIGHT_OK); |
| 347 | 347 | login_anonymous_available(); |
| 348 | - | |
| 348 | + | |
| 349 | 349 | db_prepare(&q, brlistQuery/*works-like:""*/); |
| 350 | 350 | rNow = db_double(0.0, "SELECT julianday('now')"); |
| 351 | 351 | @ <div class="brlist"><table id="branchlisttable"> |
| 352 | 352 | @ <thead><tr> |
| 353 | 353 | @ <th>Branch Name</th> |
| 354 | 354 |
| --- src/branch.c | |
| +++ src/branch.c | |
| @@ -302,11 +302,11 @@ | |
| 302 | fossil_fatal("branch subcommand should be one of: " |
| 303 | "new list ls"); |
| 304 | } |
| 305 | } |
| 306 | |
| 307 | static char brlistQuery[] = |
| 308 | @ SELECT |
| 309 | @ tagxref.value, |
| 310 | @ max(event.mtime), |
| 311 | @ EXISTS(SELECT 1 FROM tagxref AS tx |
| 312 | @ WHERE tx.rid=tagxref.rid |
| @@ -343,11 +343,11 @@ | |
| 343 | login_check_credentials(); |
| 344 | if( !g.perm.Read ){ login_needed(); return; } |
| 345 | style_header("Branches"); |
| 346 | style_adunit_config(ADUNIT_RIGHT_OK); |
| 347 | login_anonymous_available(); |
| 348 | |
| 349 | db_prepare(&q, brlistQuery/*works-like:""*/); |
| 350 | rNow = db_double(0.0, "SELECT julianday('now')"); |
| 351 | @ <div class="brlist"><table id="branchlisttable"> |
| 352 | @ <thead><tr> |
| 353 | @ <th>Branch Name</th> |
| 354 |
| --- src/branch.c | |
| +++ src/branch.c | |
| @@ -302,11 +302,11 @@ | |
| 302 | fossil_fatal("branch subcommand should be one of: " |
| 303 | "new list ls"); |
| 304 | } |
| 305 | } |
| 306 | |
| 307 | static const char brlistQuery[] = |
| 308 | @ SELECT |
| 309 | @ tagxref.value, |
| 310 | @ max(event.mtime), |
| 311 | @ EXISTS(SELECT 1 FROM tagxref AS tx |
| 312 | @ WHERE tx.rid=tagxref.rid |
| @@ -343,11 +343,11 @@ | |
| 343 | login_check_credentials(); |
| 344 | if( !g.perm.Read ){ login_needed(); return; } |
| 345 | style_header("Branches"); |
| 346 | style_adunit_config(ADUNIT_RIGHT_OK); |
| 347 | login_anonymous_available(); |
| 348 | |
| 349 | db_prepare(&q, brlistQuery/*works-like:""*/); |
| 350 | rNow = db_double(0.0, "SELECT julianday('now')"); |
| 351 | @ <div class="brlist"><table id="branchlisttable"> |
| 352 | @ <thead><tr> |
| 353 | @ <th>Branch Name</th> |
| 354 |
+3
-3
| --- src/browse.c | ||
| +++ src/browse.c | ||
| @@ -888,11 +888,11 @@ | ||
| 888 | 888 | |
| 889 | 889 | /* |
| 890 | 890 | ** SQL used to compute the age of all files in checkin :ckin whose |
| 891 | 891 | ** names match :glob |
| 892 | 892 | */ |
| 893 | -static const char zComputeFileAgeSetup[] = | |
| 893 | +static const char zComputeFileAgeSetup[] = | |
| 894 | 894 | @ CREATE TABLE IF NOT EXISTS temp.fileage( |
| 895 | 895 | @ fnid INTEGER PRIMARY KEY, |
| 896 | 896 | @ fid INTEGER, |
| 897 | 897 | @ mid INTEGER, |
| 898 | 898 | @ mtime DATETIME, |
| @@ -899,11 +899,11 @@ | ||
| 899 | 899 | @ pathname TEXT |
| 900 | 900 | @ ); |
| 901 | 901 | @ CREATE VIRTUAL TABLE IF NOT EXISTS temp.foci USING files_of_checkin; |
| 902 | 902 | ; |
| 903 | 903 | |
| 904 | -static const char zComputeFileAgeRun[] = | |
| 904 | +static const char zComputeFileAgeRun[] = | |
| 905 | 905 | @ WITH RECURSIVE |
| 906 | 906 | @ ckin(x) AS (VALUES(:ckin) UNION ALL |
| 907 | 907 | @ SELECT pid FROM ckin, plink WHERE cid=x AND isprim) |
| 908 | 908 | @ INSERT OR IGNORE INTO fileage(fnid, fid, mid, mtime, pathname) |
| 909 | 909 | @ SELECT mlink.fnid, mlink.fid, x, event.mtime, filename.name |
| @@ -1025,11 +1025,11 @@ | ||
| 1025 | 1025 | style_header("File Ages"); |
| 1026 | 1026 | zGlob = P("glob"); |
| 1027 | 1027 | compute_fileage(rid,zGlob); |
| 1028 | 1028 | db_multi_exec("CREATE INDEX fileage_ix1 ON fileage(mid,pathname);"); |
| 1029 | 1029 | |
| 1030 | - @ <h2>Files in | |
| 1030 | + @ <h2>Files in | |
| 1031 | 1031 | @ %z(href("%R/info?name=%T",zUuid))[%S(zUuid)]</a> |
| 1032 | 1032 | if( zGlob && zGlob[0] ){ |
| 1033 | 1033 | @ that match "%h(zGlob)" and |
| 1034 | 1034 | } |
| 1035 | 1035 | @ ordered by check-in time</h2> |
| 1036 | 1036 |
| --- src/browse.c | |
| +++ src/browse.c | |
| @@ -888,11 +888,11 @@ | |
| 888 | |
| 889 | /* |
| 890 | ** SQL used to compute the age of all files in checkin :ckin whose |
| 891 | ** names match :glob |
| 892 | */ |
| 893 | static const char zComputeFileAgeSetup[] = |
| 894 | @ CREATE TABLE IF NOT EXISTS temp.fileage( |
| 895 | @ fnid INTEGER PRIMARY KEY, |
| 896 | @ fid INTEGER, |
| 897 | @ mid INTEGER, |
| 898 | @ mtime DATETIME, |
| @@ -899,11 +899,11 @@ | |
| 899 | @ pathname TEXT |
| 900 | @ ); |
| 901 | @ CREATE VIRTUAL TABLE IF NOT EXISTS temp.foci USING files_of_checkin; |
| 902 | ; |
| 903 | |
| 904 | static const char zComputeFileAgeRun[] = |
| 905 | @ WITH RECURSIVE |
| 906 | @ ckin(x) AS (VALUES(:ckin) UNION ALL |
| 907 | @ SELECT pid FROM ckin, plink WHERE cid=x AND isprim) |
| 908 | @ INSERT OR IGNORE INTO fileage(fnid, fid, mid, mtime, pathname) |
| 909 | @ SELECT mlink.fnid, mlink.fid, x, event.mtime, filename.name |
| @@ -1025,11 +1025,11 @@ | |
| 1025 | style_header("File Ages"); |
| 1026 | zGlob = P("glob"); |
| 1027 | compute_fileage(rid,zGlob); |
| 1028 | db_multi_exec("CREATE INDEX fileage_ix1 ON fileage(mid,pathname);"); |
| 1029 | |
| 1030 | @ <h2>Files in |
| 1031 | @ %z(href("%R/info?name=%T",zUuid))[%S(zUuid)]</a> |
| 1032 | if( zGlob && zGlob[0] ){ |
| 1033 | @ that match "%h(zGlob)" and |
| 1034 | } |
| 1035 | @ ordered by check-in time</h2> |
| 1036 |
| --- src/browse.c | |
| +++ src/browse.c | |
| @@ -888,11 +888,11 @@ | |
| 888 | |
| 889 | /* |
| 890 | ** SQL used to compute the age of all files in checkin :ckin whose |
| 891 | ** names match :glob |
| 892 | */ |
| 893 | static const char zComputeFileAgeSetup[] = |
| 894 | @ CREATE TABLE IF NOT EXISTS temp.fileage( |
| 895 | @ fnid INTEGER PRIMARY KEY, |
| 896 | @ fid INTEGER, |
| 897 | @ mid INTEGER, |
| 898 | @ mtime DATETIME, |
| @@ -899,11 +899,11 @@ | |
| 899 | @ pathname TEXT |
| 900 | @ ); |
| 901 | @ CREATE VIRTUAL TABLE IF NOT EXISTS temp.foci USING files_of_checkin; |
| 902 | ; |
| 903 | |
| 904 | static const char zComputeFileAgeRun[] = |
| 905 | @ WITH RECURSIVE |
| 906 | @ ckin(x) AS (VALUES(:ckin) UNION ALL |
| 907 | @ SELECT pid FROM ckin, plink WHERE cid=x AND isprim) |
| 908 | @ INSERT OR IGNORE INTO fileage(fnid, fid, mid, mtime, pathname) |
| 909 | @ SELECT mlink.fnid, mlink.fid, x, event.mtime, filename.name |
| @@ -1025,11 +1025,11 @@ | |
| 1025 | style_header("File Ages"); |
| 1026 | zGlob = P("glob"); |
| 1027 | compute_fileage(rid,zGlob); |
| 1028 | db_multi_exec("CREATE INDEX fileage_ix1 ON fileage(mid,pathname);"); |
| 1029 | |
| 1030 | @ <h2>Files in |
| 1031 | @ %z(href("%R/info?name=%T",zUuid))[%S(zUuid)]</a> |
| 1032 | if( zGlob && zGlob[0] ){ |
| 1033 | @ that match "%h(zGlob)" and |
| 1034 | } |
| 1035 | @ ordered by check-in time</h2> |
| 1036 |
+1
-1
| --- src/cgi.c | ||
| +++ src/cgi.c | ||
| @@ -1756,11 +1756,11 @@ | ||
| 1756 | 1756 | fd = dup(connection); |
| 1757 | 1757 | if( fd!=0 ) nErr++; |
| 1758 | 1758 | close(1); |
| 1759 | 1759 | fd = dup(connection); |
| 1760 | 1760 | if( fd!=1 ) nErr++; |
| 1761 | - if( !g.fHttpTrace && !g.fSqlTrace ){ | |
| 1761 | + if( !g.fAnyTrace ){ | |
| 1762 | 1762 | close(2); |
| 1763 | 1763 | fd = dup(connection); |
| 1764 | 1764 | if( fd!=2 ) nErr++; |
| 1765 | 1765 | } |
| 1766 | 1766 | close(connection); |
| 1767 | 1767 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -1756,11 +1756,11 @@ | |
| 1756 | fd = dup(connection); |
| 1757 | if( fd!=0 ) nErr++; |
| 1758 | close(1); |
| 1759 | fd = dup(connection); |
| 1760 | if( fd!=1 ) nErr++; |
| 1761 | if( !g.fHttpTrace && !g.fSqlTrace ){ |
| 1762 | close(2); |
| 1763 | fd = dup(connection); |
| 1764 | if( fd!=2 ) nErr++; |
| 1765 | } |
| 1766 | close(connection); |
| 1767 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -1756,11 +1756,11 @@ | |
| 1756 | fd = dup(connection); |
| 1757 | if( fd!=0 ) nErr++; |
| 1758 | close(1); |
| 1759 | fd = dup(connection); |
| 1760 | if( fd!=1 ) nErr++; |
| 1761 | if( !g.fAnyTrace ){ |
| 1762 | close(2); |
| 1763 | fd = dup(connection); |
| 1764 | if( fd!=2 ) nErr++; |
| 1765 | } |
| 1766 | close(connection); |
| 1767 |
M
src/db.c
+31
-5
| --- src/db.c | ||
| +++ src/db.c | ||
| @@ -770,12 +770,12 @@ | ||
| 770 | 770 | void db_sym2rid_function( |
| 771 | 771 | sqlite3_context *context, |
| 772 | 772 | int argc, |
| 773 | 773 | sqlite3_value **argv |
| 774 | 774 | ){ |
| 775 | - char const * arg; | |
| 776 | - char const * type; | |
| 775 | + const char *arg; | |
| 776 | + const char *type; | |
| 777 | 777 | if(1 != argc && 2 != argc){ |
| 778 | 778 | sqlite3_result_error(context, "Expecting one or two arguments", -1); |
| 779 | 779 | return; |
| 780 | 780 | } |
| 781 | 781 | arg = (const char*)sqlite3_value_text(argv[0]); |
| @@ -795,11 +795,11 @@ | ||
| 795 | 795 | } |
| 796 | 796 | } |
| 797 | 797 | } |
| 798 | 798 | |
| 799 | 799 | /* |
| 800 | -** Register the SQL functions that are useful both to the internal | |
| 800 | +** Register the SQL functions that are useful both to the internal | |
| 801 | 801 | ** representation and to the "fossil sql" command. |
| 802 | 802 | */ |
| 803 | 803 | void db_add_aux_functions(sqlite3 *db){ |
| 804 | 804 | sqlite3_create_function(db, "checkin_mtime", 2, SQLITE_UTF8, 0, |
| 805 | 805 | db_checkin_mtime_function, 0, 0); |
| @@ -840,11 +840,11 @@ | ||
| 840 | 840 | ); |
| 841 | 841 | sqlite3_create_function( |
| 842 | 842 | db, "if_selected", 3, SQLITE_UTF8, 0, file_is_selected,0,0 |
| 843 | 843 | ); |
| 844 | 844 | if( g.fSqlTrace ) sqlite3_trace(db, db_sql_trace, 0); |
| 845 | - db_add_aux_functions(db); | |
| 845 | + db_add_aux_functions(db); | |
| 846 | 846 | re_add_sql_func(db); /* The REGEXP operator */ |
| 847 | 847 | foci_register(db); /* The "files_of_checkin" virtual table */ |
| 848 | 848 | sqlite3_exec(db, "PRAGMA foreign_keys=OFF;", 0, 0, 0); |
| 849 | 849 | return db; |
| 850 | 850 | } |
| @@ -1175,10 +1175,37 @@ | ||
| 1175 | 1175 | g.zRepositoryName = mprintf("%s", zDbName); |
| 1176 | 1176 | db_open_or_attach(g.zRepositoryName, "repository", 0); |
| 1177 | 1177 | g.repositoryOpen = 1; |
| 1178 | 1178 | /* Cache "allow-symlinks" option, because we'll need it on every stat call */ |
| 1179 | 1179 | g.allowSymlinks = db_get_boolean("allow-symlinks", 0); |
| 1180 | + g.zAuxSchema = db_get("aux-schema",""); | |
| 1181 | + | |
| 1182 | + /* Verify that the PLINK table has a new column added by the | |
| 1183 | + ** 2014-11-28 schema change. Create it if necessary. This code | |
| 1184 | + ** can be removed in the future, once all users have upgraded to the | |
| 1185 | + ** 2014-11-28 or later schema. | |
| 1186 | + */ | |
| 1187 | + if( !db_table_has_column("repository","plink","baseid") ){ | |
| 1188 | + db_multi_exec( | |
| 1189 | + "ALTER TABLE %s.plink ADD COLUMN baseid;", db_name("repository") | |
| 1190 | + ); | |
| 1191 | + } | |
| 1192 | + | |
| 1193 | + /* Verify that the MLINK table has the newer columns added by the | |
| 1194 | + ** 2015-01-24 schema change. Create them if necessary. This code | |
| 1195 | + ** can be removed in the future, once all users have upgraded to the | |
| 1196 | + ** 2015-01-24 or later schema. | |
| 1197 | + */ | |
| 1198 | + if( !db_table_has_column("repository","mlink","isaux") ){ | |
| 1199 | + db_begin_transaction(); | |
| 1200 | + db_multi_exec( | |
| 1201 | + "ALTER TABLE %s.mlink ADD COLUMN pmid INTEGER DEFAULT 0;" | |
| 1202 | + "ALTER TABLE %s.mlink ADD COLUMN isaux INTEGER DEFAULT 0;", | |
| 1203 | + db_name("repository"), db_name("repository") | |
| 1204 | + ); | |
| 1205 | + db_end_transaction(0); | |
| 1206 | + } | |
| 1180 | 1207 | } |
| 1181 | 1208 | |
| 1182 | 1209 | /* |
| 1183 | 1210 | ** Flags for the db_find_and_open_repository() function. |
| 1184 | 1211 | */ |
| @@ -1242,11 +1269,10 @@ | ||
| 1242 | 1269 | |
| 1243 | 1270 | /* |
| 1244 | 1271 | ** Return TRUE if the schema is out-of-date |
| 1245 | 1272 | */ |
| 1246 | 1273 | int db_schema_is_outofdate(void){ |
| 1247 | - if( g.zAuxSchema==0 ) g.zAuxSchema = db_get("aux-schema",""); | |
| 1248 | 1274 | return strcmp(g.zAuxSchema,AUX_SCHEMA_MIN)<0 |
| 1249 | 1275 | || strcmp(g.zAuxSchema,AUX_SCHEMA_MAX)>0; |
| 1250 | 1276 | } |
| 1251 | 1277 | |
| 1252 | 1278 | /* |
| 1253 | 1279 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -770,12 +770,12 @@ | |
| 770 | void db_sym2rid_function( |
| 771 | sqlite3_context *context, |
| 772 | int argc, |
| 773 | sqlite3_value **argv |
| 774 | ){ |
| 775 | char const * arg; |
| 776 | char const * type; |
| 777 | if(1 != argc && 2 != argc){ |
| 778 | sqlite3_result_error(context, "Expecting one or two arguments", -1); |
| 779 | return; |
| 780 | } |
| 781 | arg = (const char*)sqlite3_value_text(argv[0]); |
| @@ -795,11 +795,11 @@ | |
| 795 | } |
| 796 | } |
| 797 | } |
| 798 | |
| 799 | /* |
| 800 | ** Register the SQL functions that are useful both to the internal |
| 801 | ** representation and to the "fossil sql" command. |
| 802 | */ |
| 803 | void db_add_aux_functions(sqlite3 *db){ |
| 804 | sqlite3_create_function(db, "checkin_mtime", 2, SQLITE_UTF8, 0, |
| 805 | db_checkin_mtime_function, 0, 0); |
| @@ -840,11 +840,11 @@ | |
| 840 | ); |
| 841 | sqlite3_create_function( |
| 842 | db, "if_selected", 3, SQLITE_UTF8, 0, file_is_selected,0,0 |
| 843 | ); |
| 844 | if( g.fSqlTrace ) sqlite3_trace(db, db_sql_trace, 0); |
| 845 | db_add_aux_functions(db); |
| 846 | re_add_sql_func(db); /* The REGEXP operator */ |
| 847 | foci_register(db); /* The "files_of_checkin" virtual table */ |
| 848 | sqlite3_exec(db, "PRAGMA foreign_keys=OFF;", 0, 0, 0); |
| 849 | return db; |
| 850 | } |
| @@ -1175,10 +1175,37 @@ | |
| 1175 | g.zRepositoryName = mprintf("%s", zDbName); |
| 1176 | db_open_or_attach(g.zRepositoryName, "repository", 0); |
| 1177 | g.repositoryOpen = 1; |
| 1178 | /* Cache "allow-symlinks" option, because we'll need it on every stat call */ |
| 1179 | g.allowSymlinks = db_get_boolean("allow-symlinks", 0); |
| 1180 | } |
| 1181 | |
| 1182 | /* |
| 1183 | ** Flags for the db_find_and_open_repository() function. |
| 1184 | */ |
| @@ -1242,11 +1269,10 @@ | |
| 1242 | |
| 1243 | /* |
| 1244 | ** Return TRUE if the schema is out-of-date |
| 1245 | */ |
| 1246 | int db_schema_is_outofdate(void){ |
| 1247 | if( g.zAuxSchema==0 ) g.zAuxSchema = db_get("aux-schema",""); |
| 1248 | return strcmp(g.zAuxSchema,AUX_SCHEMA_MIN)<0 |
| 1249 | || strcmp(g.zAuxSchema,AUX_SCHEMA_MAX)>0; |
| 1250 | } |
| 1251 | |
| 1252 | /* |
| 1253 |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -770,12 +770,12 @@ | |
| 770 | void db_sym2rid_function( |
| 771 | sqlite3_context *context, |
| 772 | int argc, |
| 773 | sqlite3_value **argv |
| 774 | ){ |
| 775 | const char *arg; |
| 776 | const char *type; |
| 777 | if(1 != argc && 2 != argc){ |
| 778 | sqlite3_result_error(context, "Expecting one or two arguments", -1); |
| 779 | return; |
| 780 | } |
| 781 | arg = (const char*)sqlite3_value_text(argv[0]); |
| @@ -795,11 +795,11 @@ | |
| 795 | } |
| 796 | } |
| 797 | } |
| 798 | |
| 799 | /* |
| 800 | ** Register the SQL functions that are useful both to the internal |
| 801 | ** representation and to the "fossil sql" command. |
| 802 | */ |
| 803 | void db_add_aux_functions(sqlite3 *db){ |
| 804 | sqlite3_create_function(db, "checkin_mtime", 2, SQLITE_UTF8, 0, |
| 805 | db_checkin_mtime_function, 0, 0); |
| @@ -840,11 +840,11 @@ | |
| 840 | ); |
| 841 | sqlite3_create_function( |
| 842 | db, "if_selected", 3, SQLITE_UTF8, 0, file_is_selected,0,0 |
| 843 | ); |
| 844 | if( g.fSqlTrace ) sqlite3_trace(db, db_sql_trace, 0); |
| 845 | db_add_aux_functions(db); |
| 846 | re_add_sql_func(db); /* The REGEXP operator */ |
| 847 | foci_register(db); /* The "files_of_checkin" virtual table */ |
| 848 | sqlite3_exec(db, "PRAGMA foreign_keys=OFF;", 0, 0, 0); |
| 849 | return db; |
| 850 | } |
| @@ -1175,10 +1175,37 @@ | |
| 1175 | g.zRepositoryName = mprintf("%s", zDbName); |
| 1176 | db_open_or_attach(g.zRepositoryName, "repository", 0); |
| 1177 | g.repositoryOpen = 1; |
| 1178 | /* Cache "allow-symlinks" option, because we'll need it on every stat call */ |
| 1179 | g.allowSymlinks = db_get_boolean("allow-symlinks", 0); |
| 1180 | g.zAuxSchema = db_get("aux-schema",""); |
| 1181 | |
| 1182 | /* Verify that the PLINK table has a new column added by the |
| 1183 | ** 2014-11-28 schema change. Create it if necessary. This code |
| 1184 | ** can be removed in the future, once all users have upgraded to the |
| 1185 | ** 2014-11-28 or later schema. |
| 1186 | */ |
| 1187 | if( !db_table_has_column("repository","plink","baseid") ){ |
| 1188 | db_multi_exec( |
| 1189 | "ALTER TABLE %s.plink ADD COLUMN baseid;", db_name("repository") |
| 1190 | ); |
| 1191 | } |
| 1192 | |
| 1193 | /* Verify that the MLINK table has the newer columns added by the |
| 1194 | ** 2015-01-24 schema change. Create them if necessary. This code |
| 1195 | ** can be removed in the future, once all users have upgraded to the |
| 1196 | ** 2015-01-24 or later schema. |
| 1197 | */ |
| 1198 | if( !db_table_has_column("repository","mlink","isaux") ){ |
| 1199 | db_begin_transaction(); |
| 1200 | db_multi_exec( |
| 1201 | "ALTER TABLE %s.mlink ADD COLUMN pmid INTEGER DEFAULT 0;" |
| 1202 | "ALTER TABLE %s.mlink ADD COLUMN isaux INTEGER DEFAULT 0;", |
| 1203 | db_name("repository"), db_name("repository") |
| 1204 | ); |
| 1205 | db_end_transaction(0); |
| 1206 | } |
| 1207 | } |
| 1208 | |
| 1209 | /* |
| 1210 | ** Flags for the db_find_and_open_repository() function. |
| 1211 | */ |
| @@ -1242,11 +1269,10 @@ | |
| 1269 | |
| 1270 | /* |
| 1271 | ** Return TRUE if the schema is out-of-date |
| 1272 | */ |
| 1273 | int db_schema_is_outofdate(void){ |
| 1274 | return strcmp(g.zAuxSchema,AUX_SCHEMA_MIN)<0 |
| 1275 | || strcmp(g.zAuxSchema,AUX_SCHEMA_MAX)>0; |
| 1276 | } |
| 1277 | |
| 1278 | /* |
| 1279 |
+68
-54
| --- src/finfo.c | ||
| +++ src/finfo.c | ||
| @@ -284,110 +284,92 @@ | ||
| 284 | 284 | ** b=DATE Only show changes before DATE |
| 285 | 285 | ** n=NUM Show the first NUM changes only |
| 286 | 286 | ** brbg Background color by branch name |
| 287 | 287 | ** ubg Background color by user name |
| 288 | 288 | ** ci=UUID Ancestors of a particular check-in |
| 289 | -** fco=BOOL Show only first occurrence of each version if true (default) | |
| 290 | 289 | */ |
| 291 | 290 | void finfo_page(void){ |
| 292 | 291 | Stmt q; |
| 293 | 292 | const char *zFilename; |
| 294 | 293 | char zPrevDate[20]; |
| 295 | 294 | const char *zA; |
| 296 | 295 | const char *zB; |
| 297 | 296 | int n; |
| 298 | 297 | int baseCheckin; |
| 299 | - | |
| 298 | + int fnid; | |
| 299 | + Bag ancestor; | |
| 300 | 300 | Blob title; |
| 301 | 301 | Blob sql; |
| 302 | 302 | HQuery url; |
| 303 | 303 | GraphContext *pGraph; |
| 304 | 304 | int brBg = P("brbg")!=0; |
| 305 | 305 | int uBg = P("ubg")!=0; |
| 306 | - int firstChngOnly = atoi(PD("fco","1"))!=0; | |
| 307 | 306 | int fDebug = atoi(PD("debug","0")); |
| 307 | + int fShowId = P("showid")!=0; | |
| 308 | 308 | |
| 309 | 309 | login_check_credentials(); |
| 310 | 310 | if( !g.perm.Read ){ login_needed(); return; } |
| 311 | 311 | style_header("File History"); |
| 312 | 312 | login_anonymous_available(); |
| 313 | 313 | url_initialize(&url, "finfo"); |
| 314 | 314 | if( brBg ) url_add_parameter(&url, "brbg", 0); |
| 315 | 315 | if( uBg ) url_add_parameter(&url, "ubg", 0); |
| 316 | 316 | baseCheckin = name_to_rid_www("ci"); |
| 317 | - if( baseCheckin ) firstChngOnly = 1; | |
| 318 | - if( !firstChngOnly ) url_add_parameter(&url, "fco", "0"); | |
| 319 | - | |
| 320 | 317 | zPrevDate[0] = 0; |
| 321 | 318 | zFilename = PD("name",""); |
| 319 | + fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename); | |
| 320 | + if( fnid==0 ){ | |
| 321 | + @ No such file: %h(zFilename) | |
| 322 | + style_footer(); | |
| 323 | + return; | |
| 324 | + } | |
| 325 | + if( baseCheckin ){ | |
| 326 | + int baseFid = db_int(0, | |
| 327 | + "SELECT fid FROM mlink WHERE fnid=%d AND mid=%d", | |
| 328 | + fnid, baseCheckin | |
| 329 | + ); | |
| 330 | + bag_init(&ancestor); | |
| 331 | + if( baseFid ) bag_insert(&ancestor, baseFid); | |
| 332 | + } | |
| 322 | 333 | url_add_parameter(&url, "name", zFilename); |
| 323 | 334 | blob_zero(&sql); |
| 324 | 335 | blob_append_sql(&sql, |
| 325 | 336 | "SELECT" |
| 326 | - " datetime(event.mtime%s)," /* Date of change */ | |
| 337 | + " datetime(min(event.mtime)%s)," /* Date of change */ | |
| 327 | 338 | " coalesce(event.ecomment, event.comment)," /* Check-in comment */ |
| 328 | 339 | " coalesce(event.euser, event.user)," /* User who made chng */ |
| 329 | 340 | " mlink.pid," /* Parent file rid */ |
| 330 | 341 | " mlink.fid," /* File rid */ |
| 331 | 342 | " (SELECT uuid FROM blob WHERE rid=mlink.pid)," /* Parent file uuid */ |
| 332 | 343 | " (SELECT uuid FROM blob WHERE rid=mlink.fid)," /* Current file uuid */ |
| 333 | 344 | " (SELECT uuid FROM blob WHERE rid=mlink.mid)," /* Check-in uuid */ |
| 334 | 345 | " event.bgcolor," /* Background color */ |
| 335 | 346 | " (SELECT value FROM tagxref WHERE tagid=%d AND tagtype>0" |
| 336 | - " AND tagxref.rid=mlink.mid)," /* Tags */ | |
| 347 | + " AND tagxref.rid=mlink.mid)," /* Branchname */ | |
| 337 | 348 | " mlink.mid," /* check-in ID */ |
| 338 | - " mlink.pfnid", /* Previous filename */ | |
| 339 | - timeline_utc(), TAG_BRANCH | |
| 340 | - ); | |
| 341 | - if( firstChngOnly ){ | |
| 342 | -#if 0 | |
| 343 | - blob_append_sql(&sql, ", min(event.mtime)"); | |
| 344 | -#else | |
| 345 | - blob_append_sql(&sql, | |
| 346 | - ", min(CASE (SELECT value FROM tagxref" | |
| 347 | - " WHERE tagtype>0 AND tagid=%d" | |
| 348 | - " AND tagxref.rid=mlink.mid)" | |
| 349 | - " WHEN 'trunk' THEN event.mtime-10000 ELSE event.mtime END)", | |
| 350 | - TAG_BRANCH); | |
| 351 | -#endif | |
| 352 | - } | |
| 353 | - blob_append_sql(&sql, | |
| 349 | + " mlink.pfnid" /* Previous filename */ | |
| 354 | 350 | " FROM mlink, event" |
| 355 | - " WHERE mlink.fnid IN (SELECT fnid FROM filename WHERE name=%Q)" | |
| 351 | + " WHERE mlink.fnid=%d" | |
| 356 | 352 | " AND event.objid=mlink.mid", |
| 357 | - zFilename | |
| 353 | + timeline_utc(), TAG_BRANCH, fnid | |
| 358 | 354 | ); |
| 359 | - if( baseCheckin ){ | |
| 360 | - compute_direct_ancestors(baseCheckin, 10000000); | |
| 361 | - blob_append_sql(&sql," AND mlink.mid IN (SELECT rid FROM ancestor)"); | |
| 362 | - } | |
| 363 | 355 | if( (zA = P("a"))!=0 ){ |
| 364 | 356 | blob_append_sql(&sql, " AND event.mtime>=julianday('%q')", zA); |
| 365 | 357 | url_add_parameter(&url, "a", zA); |
| 366 | 358 | } |
| 367 | 359 | if( (zB = P("b"))!=0 ){ |
| 368 | 360 | blob_append_sql(&sql, " AND event.mtime<=julianday('%q')", zB); |
| 369 | 361 | url_add_parameter(&url, "b", zB); |
| 370 | 362 | } |
| 371 | - if( firstChngOnly ){ | |
| 372 | - blob_append_sql(&sql, " GROUP BY mlink.fid"); | |
| 373 | - } | |
| 374 | - blob_append_sql(&sql," ORDER BY event.mtime DESC /*sort*/"); | |
| 363 | + blob_append_sql(&sql, | |
| 364 | + " GROUP BY mlink.fid" | |
| 365 | + " ORDER BY event.mtime DESC /*sort*/" | |
| 366 | + ); | |
| 375 | 367 | if( (n = atoi(PD("n","0")))>0 ){ |
| 376 | 368 | blob_append_sql(&sql, " LIMIT %d", n); |
| 377 | 369 | url_add_parameter(&url, "n", P("n")); |
| 378 | 370 | } |
| 379 | - if( baseCheckin==0 ){ | |
| 380 | - if( firstChngOnly ){ | |
| 381 | - style_submenu_element("Full", "Show all changes","%s", | |
| 382 | - url_render(&url, "fco", "0", 0, 0)); | |
| 383 | - }else{ | |
| 384 | - style_submenu_element("Simplified", | |
| 385 | - "Show only first use of a change","%s", | |
| 386 | - url_render(&url, "fco", 0, 0, 0)); | |
| 387 | - } | |
| 388 | - } | |
| 389 | 371 | db_prepare(&q, "%s", blob_sql_text(&sql)); |
| 390 | 372 | if( P("showsql")!=0 ){ |
| 391 | 373 | @ <p>SQL: %h(blob_str(&sql))</p> |
| 392 | 374 | } |
| 393 | 375 | blob_reset(&sql); |
| @@ -395,15 +377,18 @@ | ||
| 395 | 377 | if( baseCheckin ){ |
| 396 | 378 | char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", baseCheckin); |
| 397 | 379 | char *zLink = href("%R/info/%s", zUuid); |
| 398 | 380 | blob_appendf(&title, "Ancestors of file "); |
| 399 | 381 | hyperlinked_path(zFilename, &title, zUuid, "tree", ""); |
| 382 | + if( fShowId ) blob_appendf(&title, " (%d)", fnid); | |
| 400 | 383 | blob_appendf(&title, " from check-in %z%S</a>", zLink, zUuid); |
| 384 | + if( fShowId ) blob_appendf(&title, " (%d)", baseCheckin); | |
| 401 | 385 | fossil_free(zUuid); |
| 402 | 386 | }else{ |
| 403 | 387 | blob_appendf(&title, "History of files named "); |
| 404 | 388 | hyperlinked_path(zFilename, &title, 0, "tree", ""); |
| 389 | + if( fShowId ) blob_appendf(&title, " (%d)", fnid); | |
| 405 | 390 | } |
| 406 | 391 | @ <h2>%b(&title)</h2> |
| 407 | 392 | blob_reset(&title); |
| 408 | 393 | pGraph = graph_init(); |
| 409 | 394 | @ <div id="canvas" style="position:relative;width:1px;height:1px;" |
| @@ -422,17 +407,36 @@ | ||
| 422 | 407 | const char *zBr = db_column_text(&q, 9); |
| 423 | 408 | int fmid = db_column_int(&q, 10); |
| 424 | 409 | int pfnid = db_column_int(&q, 11); |
| 425 | 410 | int gidx; |
| 426 | 411 | char zTime[10]; |
| 412 | + int nParent = 0; | |
| 413 | + int aParent[GR_MAX_RAIL]; | |
| 414 | + static Stmt qparent; | |
| 415 | + | |
| 416 | + if( baseCheckin && frid && !bag_find(&ancestor, frid) ) continue; | |
| 417 | + db_static_prepare(&qparent, | |
| 418 | + "SELECT DISTINCT pid FROM mlink" | |
| 419 | + " WHERE fid=:fid AND mid=:mid AND pid>0 AND fnid=:fnid" | |
| 420 | + " ORDER BY isaux /*sort*/" | |
| 421 | + ); | |
| 422 | + db_bind_int(&qparent, ":fid", frid); | |
| 423 | + db_bind_int(&qparent, ":mid", fmid); | |
| 424 | + db_bind_int(&qparent, ":fnid", fnid); | |
| 425 | + while( db_step(&qparent)==SQLITE_ROW && nParent<ArraySize(aParent) ){ | |
| 426 | + aParent[nParent] = db_column_int(&qparent, 0); | |
| 427 | + if( baseCheckin ) bag_insert(&ancestor, aParent[nParent]); | |
| 428 | + nParent++; | |
| 429 | + } | |
| 430 | + db_reset(&qparent); | |
| 427 | 431 | if( zBr==0 ) zBr = "trunk"; |
| 428 | 432 | if( uBg ){ |
| 429 | 433 | zBgClr = hash_color(zUser); |
| 430 | 434 | }else if( brBg || zBgClr==0 || zBgClr[0]==0 ){ |
| 431 | 435 | zBgClr = strcmp(zBr,"trunk")==0 ? "" : hash_color(zBr); |
| 432 | 436 | } |
| 433 | - gidx = graph_add_row(pGraph, frid, fpid>0 ? 1 : 0, &fpid, zBr, zBgClr, | |
| 437 | + gidx = graph_add_row(pGraph, frid, nParent, aParent, zBr, zBgClr, | |
| 434 | 438 | zUuid, 0); |
| 435 | 439 | if( strncmp(zDate, zPrevDate, 10) ){ |
| 436 | 440 | sqlite3_snprintf(sizeof(zPrevDate), zPrevDate, "%.10s", zDate); |
| 437 | 441 | @ <tr><td> |
| 438 | 442 | @ <div class="divider">%s(zPrevDate)</div> |
| @@ -447,19 +451,23 @@ | ||
| 447 | 451 | @ <td class="timelineTableCell" style="background-color: %h(zBgClr);"> |
| 448 | 452 | }else{ |
| 449 | 453 | @ <td class="timelineTableCell"> |
| 450 | 454 | } |
| 451 | 455 | if( zUuid ){ |
| 452 | - if( fpid==0 ){ | |
| 456 | + if( nParent==0 ){ | |
| 453 | 457 | @ <b>Added</b> |
| 454 | 458 | }else if( pfnid ){ |
| 455 | 459 | char *zPrevName = db_text(0, "SELECT name FROM filename WHERE fnid=%d", |
| 456 | 460 | pfnid); |
| 457 | 461 | @ <b>Renamed</b> from |
| 458 | 462 | @ %z(href("%R/finfo?name=%t", zPrevName))%h(zPrevName)</a> |
| 459 | 463 | } |
| 460 | - @ %z(href("%R/artifact/%s",zUuid))[%S(zUuid)]</a> part of check-in | |
| 464 | + @ %z(href("%R/artifact/%s",zUuid))[%S(zUuid)]</a> | |
| 465 | + if( fShowId ){ | |
| 466 | + @ (%d(frid)) | |
| 467 | + } | |
| 468 | + @ part of check-in | |
| 461 | 469 | }else{ |
| 462 | 470 | char *zNewName; |
| 463 | 471 | zNewName = db_text(0, |
| 464 | 472 | "SELECT name FROM filename WHERE fnid = " |
| 465 | 473 | " (SELECT fnid FROM mlink" |
| @@ -473,13 +481,16 @@ | ||
| 473 | 481 | }else{ |
| 474 | 482 | @ <b>Deleted</b> by check-in |
| 475 | 483 | } |
| 476 | 484 | } |
| 477 | 485 | hyperlink_to_uuid(zCkin); |
| 486 | + if( fShowId ){ | |
| 487 | + @ (%d(fmid)) | |
| 488 | + } | |
| 478 | 489 | @ %W(zCom) (user: |
| 479 | 490 | hyperlink_to_user(zUser, zDate, ""); |
| 480 | - @ branch: %h(zBr)) | |
| 491 | + @ branch: %z(href("%R/timeline?t=%T&n=200",zBr))%h(zBr)</a> | |
| 481 | 492 | if( g.perm.Hyperlink && zUuid ){ |
| 482 | 493 | const char *z = zFilename; |
| 483 | 494 | @ %z(href("%R/annotate?filename=%h&checkin=%s",z,zCkin)) |
| 484 | 495 | @ [annotate]</a> |
| 485 | 496 | @ %z(href("%R/blame?filename=%h&checkin=%s",z,zCkin)) |
| @@ -488,23 +499,26 @@ | ||
| 488 | 499 | if( fpid ){ |
| 489 | 500 | @ %z(href("%R/fdiff?sbs=1&v1=%s&v2=%s",zPUuid,zUuid))[diff]</a> |
| 490 | 501 | } |
| 491 | 502 | } |
| 492 | 503 | if( fDebug & FINFO_DEBUG_MLINK ){ |
| 493 | - int srcid = db_int(0, "SELECT srcid FROM delta WHERE rid=%d", frid); | |
| 494 | - int sz = db_int(0, "SELECT length(content) FROM blob WHERE rid=%d", frid); | |
| 495 | - @ <br>fid=%d(frid) pid=%d(fpid) mid=%d(fmid) sz=%d(sz) | |
| 496 | - if( srcid ){ | |
| 497 | - @ srcid=%d(srcid) | |
| 504 | + int ii; | |
| 505 | + @ <br>fid=%d(frid) pid=%d(fpid) mid=%d(fmid) | |
| 506 | + if( nParent>0 ){ | |
| 507 | + @ parents=%d(aParent[0]) | |
| 508 | + for(ii=1; ii<nParent; ii++){ | |
| 509 | + @ %d(aParent[ii]) | |
| 510 | + } | |
| 498 | 511 | } |
| 512 | + @ %z(href("%R/finfo?name=%T&ci=%s&debug=1",zFilename,zCkin))[ancestry]</a> | |
| 499 | 513 | } |
| 500 | 514 | tag_private_status(frid); |
| 501 | 515 | @ </td></tr> |
| 502 | 516 | } |
| 503 | 517 | db_finalize(&q); |
| 504 | 518 | if( pGraph ){ |
| 505 | - graph_finish(pGraph, 0); | |
| 519 | + graph_finish(pGraph, 1); | |
| 506 | 520 | if( pGraph->nErr ){ |
| 507 | 521 | graph_free(pGraph); |
| 508 | 522 | pGraph = 0; |
| 509 | 523 | }else{ |
| 510 | 524 | int w = (pGraph->mxRail+1)*pGraph->iRailPitch + 10; |
| 511 | 525 |
| --- src/finfo.c | |
| +++ src/finfo.c | |
| @@ -284,110 +284,92 @@ | |
| 284 | ** b=DATE Only show changes before DATE |
| 285 | ** n=NUM Show the first NUM changes only |
| 286 | ** brbg Background color by branch name |
| 287 | ** ubg Background color by user name |
| 288 | ** ci=UUID Ancestors of a particular check-in |
| 289 | ** fco=BOOL Show only first occurrence of each version if true (default) |
| 290 | */ |
| 291 | void finfo_page(void){ |
| 292 | Stmt q; |
| 293 | const char *zFilename; |
| 294 | char zPrevDate[20]; |
| 295 | const char *zA; |
| 296 | const char *zB; |
| 297 | int n; |
| 298 | int baseCheckin; |
| 299 | |
| 300 | Blob title; |
| 301 | Blob sql; |
| 302 | HQuery url; |
| 303 | GraphContext *pGraph; |
| 304 | int brBg = P("brbg")!=0; |
| 305 | int uBg = P("ubg")!=0; |
| 306 | int firstChngOnly = atoi(PD("fco","1"))!=0; |
| 307 | int fDebug = atoi(PD("debug","0")); |
| 308 | |
| 309 | login_check_credentials(); |
| 310 | if( !g.perm.Read ){ login_needed(); return; } |
| 311 | style_header("File History"); |
| 312 | login_anonymous_available(); |
| 313 | url_initialize(&url, "finfo"); |
| 314 | if( brBg ) url_add_parameter(&url, "brbg", 0); |
| 315 | if( uBg ) url_add_parameter(&url, "ubg", 0); |
| 316 | baseCheckin = name_to_rid_www("ci"); |
| 317 | if( baseCheckin ) firstChngOnly = 1; |
| 318 | if( !firstChngOnly ) url_add_parameter(&url, "fco", "0"); |
| 319 | |
| 320 | zPrevDate[0] = 0; |
| 321 | zFilename = PD("name",""); |
| 322 | url_add_parameter(&url, "name", zFilename); |
| 323 | blob_zero(&sql); |
| 324 | blob_append_sql(&sql, |
| 325 | "SELECT" |
| 326 | " datetime(event.mtime%s)," /* Date of change */ |
| 327 | " coalesce(event.ecomment, event.comment)," /* Check-in comment */ |
| 328 | " coalesce(event.euser, event.user)," /* User who made chng */ |
| 329 | " mlink.pid," /* Parent file rid */ |
| 330 | " mlink.fid," /* File rid */ |
| 331 | " (SELECT uuid FROM blob WHERE rid=mlink.pid)," /* Parent file uuid */ |
| 332 | " (SELECT uuid FROM blob WHERE rid=mlink.fid)," /* Current file uuid */ |
| 333 | " (SELECT uuid FROM blob WHERE rid=mlink.mid)," /* Check-in uuid */ |
| 334 | " event.bgcolor," /* Background color */ |
| 335 | " (SELECT value FROM tagxref WHERE tagid=%d AND tagtype>0" |
| 336 | " AND tagxref.rid=mlink.mid)," /* Tags */ |
| 337 | " mlink.mid," /* check-in ID */ |
| 338 | " mlink.pfnid", /* Previous filename */ |
| 339 | timeline_utc(), TAG_BRANCH |
| 340 | ); |
| 341 | if( firstChngOnly ){ |
| 342 | #if 0 |
| 343 | blob_append_sql(&sql, ", min(event.mtime)"); |
| 344 | #else |
| 345 | blob_append_sql(&sql, |
| 346 | ", min(CASE (SELECT value FROM tagxref" |
| 347 | " WHERE tagtype>0 AND tagid=%d" |
| 348 | " AND tagxref.rid=mlink.mid)" |
| 349 | " WHEN 'trunk' THEN event.mtime-10000 ELSE event.mtime END)", |
| 350 | TAG_BRANCH); |
| 351 | #endif |
| 352 | } |
| 353 | blob_append_sql(&sql, |
| 354 | " FROM mlink, event" |
| 355 | " WHERE mlink.fnid IN (SELECT fnid FROM filename WHERE name=%Q)" |
| 356 | " AND event.objid=mlink.mid", |
| 357 | zFilename |
| 358 | ); |
| 359 | if( baseCheckin ){ |
| 360 | compute_direct_ancestors(baseCheckin, 10000000); |
| 361 | blob_append_sql(&sql," AND mlink.mid IN (SELECT rid FROM ancestor)"); |
| 362 | } |
| 363 | if( (zA = P("a"))!=0 ){ |
| 364 | blob_append_sql(&sql, " AND event.mtime>=julianday('%q')", zA); |
| 365 | url_add_parameter(&url, "a", zA); |
| 366 | } |
| 367 | if( (zB = P("b"))!=0 ){ |
| 368 | blob_append_sql(&sql, " AND event.mtime<=julianday('%q')", zB); |
| 369 | url_add_parameter(&url, "b", zB); |
| 370 | } |
| 371 | if( firstChngOnly ){ |
| 372 | blob_append_sql(&sql, " GROUP BY mlink.fid"); |
| 373 | } |
| 374 | blob_append_sql(&sql," ORDER BY event.mtime DESC /*sort*/"); |
| 375 | if( (n = atoi(PD("n","0")))>0 ){ |
| 376 | blob_append_sql(&sql, " LIMIT %d", n); |
| 377 | url_add_parameter(&url, "n", P("n")); |
| 378 | } |
| 379 | if( baseCheckin==0 ){ |
| 380 | if( firstChngOnly ){ |
| 381 | style_submenu_element("Full", "Show all changes","%s", |
| 382 | url_render(&url, "fco", "0", 0, 0)); |
| 383 | }else{ |
| 384 | style_submenu_element("Simplified", |
| 385 | "Show only first use of a change","%s", |
| 386 | url_render(&url, "fco", 0, 0, 0)); |
| 387 | } |
| 388 | } |
| 389 | db_prepare(&q, "%s", blob_sql_text(&sql)); |
| 390 | if( P("showsql")!=0 ){ |
| 391 | @ <p>SQL: %h(blob_str(&sql))</p> |
| 392 | } |
| 393 | blob_reset(&sql); |
| @@ -395,15 +377,18 @@ | |
| 395 | if( baseCheckin ){ |
| 396 | char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", baseCheckin); |
| 397 | char *zLink = href("%R/info/%s", zUuid); |
| 398 | blob_appendf(&title, "Ancestors of file "); |
| 399 | hyperlinked_path(zFilename, &title, zUuid, "tree", ""); |
| 400 | blob_appendf(&title, " from check-in %z%S</a>", zLink, zUuid); |
| 401 | fossil_free(zUuid); |
| 402 | }else{ |
| 403 | blob_appendf(&title, "History of files named "); |
| 404 | hyperlinked_path(zFilename, &title, 0, "tree", ""); |
| 405 | } |
| 406 | @ <h2>%b(&title)</h2> |
| 407 | blob_reset(&title); |
| 408 | pGraph = graph_init(); |
| 409 | @ <div id="canvas" style="position:relative;width:1px;height:1px;" |
| @@ -422,17 +407,36 @@ | |
| 422 | const char *zBr = db_column_text(&q, 9); |
| 423 | int fmid = db_column_int(&q, 10); |
| 424 | int pfnid = db_column_int(&q, 11); |
| 425 | int gidx; |
| 426 | char zTime[10]; |
| 427 | if( zBr==0 ) zBr = "trunk"; |
| 428 | if( uBg ){ |
| 429 | zBgClr = hash_color(zUser); |
| 430 | }else if( brBg || zBgClr==0 || zBgClr[0]==0 ){ |
| 431 | zBgClr = strcmp(zBr,"trunk")==0 ? "" : hash_color(zBr); |
| 432 | } |
| 433 | gidx = graph_add_row(pGraph, frid, fpid>0 ? 1 : 0, &fpid, zBr, zBgClr, |
| 434 | zUuid, 0); |
| 435 | if( strncmp(zDate, zPrevDate, 10) ){ |
| 436 | sqlite3_snprintf(sizeof(zPrevDate), zPrevDate, "%.10s", zDate); |
| 437 | @ <tr><td> |
| 438 | @ <div class="divider">%s(zPrevDate)</div> |
| @@ -447,19 +451,23 @@ | |
| 447 | @ <td class="timelineTableCell" style="background-color: %h(zBgClr);"> |
| 448 | }else{ |
| 449 | @ <td class="timelineTableCell"> |
| 450 | } |
| 451 | if( zUuid ){ |
| 452 | if( fpid==0 ){ |
| 453 | @ <b>Added</b> |
| 454 | }else if( pfnid ){ |
| 455 | char *zPrevName = db_text(0, "SELECT name FROM filename WHERE fnid=%d", |
| 456 | pfnid); |
| 457 | @ <b>Renamed</b> from |
| 458 | @ %z(href("%R/finfo?name=%t", zPrevName))%h(zPrevName)</a> |
| 459 | } |
| 460 | @ %z(href("%R/artifact/%s",zUuid))[%S(zUuid)]</a> part of check-in |
| 461 | }else{ |
| 462 | char *zNewName; |
| 463 | zNewName = db_text(0, |
| 464 | "SELECT name FROM filename WHERE fnid = " |
| 465 | " (SELECT fnid FROM mlink" |
| @@ -473,13 +481,16 @@ | |
| 473 | }else{ |
| 474 | @ <b>Deleted</b> by check-in |
| 475 | } |
| 476 | } |
| 477 | hyperlink_to_uuid(zCkin); |
| 478 | @ %W(zCom) (user: |
| 479 | hyperlink_to_user(zUser, zDate, ""); |
| 480 | @ branch: %h(zBr)) |
| 481 | if( g.perm.Hyperlink && zUuid ){ |
| 482 | const char *z = zFilename; |
| 483 | @ %z(href("%R/annotate?filename=%h&checkin=%s",z,zCkin)) |
| 484 | @ [annotate]</a> |
| 485 | @ %z(href("%R/blame?filename=%h&checkin=%s",z,zCkin)) |
| @@ -488,23 +499,26 @@ | |
| 488 | if( fpid ){ |
| 489 | @ %z(href("%R/fdiff?sbs=1&v1=%s&v2=%s",zPUuid,zUuid))[diff]</a> |
| 490 | } |
| 491 | } |
| 492 | if( fDebug & FINFO_DEBUG_MLINK ){ |
| 493 | int srcid = db_int(0, "SELECT srcid FROM delta WHERE rid=%d", frid); |
| 494 | int sz = db_int(0, "SELECT length(content) FROM blob WHERE rid=%d", frid); |
| 495 | @ <br>fid=%d(frid) pid=%d(fpid) mid=%d(fmid) sz=%d(sz) |
| 496 | if( srcid ){ |
| 497 | @ srcid=%d(srcid) |
| 498 | } |
| 499 | } |
| 500 | tag_private_status(frid); |
| 501 | @ </td></tr> |
| 502 | } |
| 503 | db_finalize(&q); |
| 504 | if( pGraph ){ |
| 505 | graph_finish(pGraph, 0); |
| 506 | if( pGraph->nErr ){ |
| 507 | graph_free(pGraph); |
| 508 | pGraph = 0; |
| 509 | }else{ |
| 510 | int w = (pGraph->mxRail+1)*pGraph->iRailPitch + 10; |
| 511 |
| --- src/finfo.c | |
| +++ src/finfo.c | |
| @@ -284,110 +284,92 @@ | |
| 284 | ** b=DATE Only show changes before DATE |
| 285 | ** n=NUM Show the first NUM changes only |
| 286 | ** brbg Background color by branch name |
| 287 | ** ubg Background color by user name |
| 288 | ** ci=UUID Ancestors of a particular check-in |
| 289 | */ |
| 290 | void finfo_page(void){ |
| 291 | Stmt q; |
| 292 | const char *zFilename; |
| 293 | char zPrevDate[20]; |
| 294 | const char *zA; |
| 295 | const char *zB; |
| 296 | int n; |
| 297 | int baseCheckin; |
| 298 | int fnid; |
| 299 | Bag ancestor; |
| 300 | Blob title; |
| 301 | Blob sql; |
| 302 | HQuery url; |
| 303 | GraphContext *pGraph; |
| 304 | int brBg = P("brbg")!=0; |
| 305 | int uBg = P("ubg")!=0; |
| 306 | int fDebug = atoi(PD("debug","0")); |
| 307 | int fShowId = P("showid")!=0; |
| 308 | |
| 309 | login_check_credentials(); |
| 310 | if( !g.perm.Read ){ login_needed(); return; } |
| 311 | style_header("File History"); |
| 312 | login_anonymous_available(); |
| 313 | url_initialize(&url, "finfo"); |
| 314 | if( brBg ) url_add_parameter(&url, "brbg", 0); |
| 315 | if( uBg ) url_add_parameter(&url, "ubg", 0); |
| 316 | baseCheckin = name_to_rid_www("ci"); |
| 317 | zPrevDate[0] = 0; |
| 318 | zFilename = PD("name",""); |
| 319 | fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename); |
| 320 | if( fnid==0 ){ |
| 321 | @ No such file: %h(zFilename) |
| 322 | style_footer(); |
| 323 | return; |
| 324 | } |
| 325 | if( baseCheckin ){ |
| 326 | int baseFid = db_int(0, |
| 327 | "SELECT fid FROM mlink WHERE fnid=%d AND mid=%d", |
| 328 | fnid, baseCheckin |
| 329 | ); |
| 330 | bag_init(&ancestor); |
| 331 | if( baseFid ) bag_insert(&ancestor, baseFid); |
| 332 | } |
| 333 | url_add_parameter(&url, "name", zFilename); |
| 334 | blob_zero(&sql); |
| 335 | blob_append_sql(&sql, |
| 336 | "SELECT" |
| 337 | " datetime(min(event.mtime)%s)," /* Date of change */ |
| 338 | " coalesce(event.ecomment, event.comment)," /* Check-in comment */ |
| 339 | " coalesce(event.euser, event.user)," /* User who made chng */ |
| 340 | " mlink.pid," /* Parent file rid */ |
| 341 | " mlink.fid," /* File rid */ |
| 342 | " (SELECT uuid FROM blob WHERE rid=mlink.pid)," /* Parent file uuid */ |
| 343 | " (SELECT uuid FROM blob WHERE rid=mlink.fid)," /* Current file uuid */ |
| 344 | " (SELECT uuid FROM blob WHERE rid=mlink.mid)," /* Check-in uuid */ |
| 345 | " event.bgcolor," /* Background color */ |
| 346 | " (SELECT value FROM tagxref WHERE tagid=%d AND tagtype>0" |
| 347 | " AND tagxref.rid=mlink.mid)," /* Branchname */ |
| 348 | " mlink.mid," /* check-in ID */ |
| 349 | " mlink.pfnid" /* Previous filename */ |
| 350 | " FROM mlink, event" |
| 351 | " WHERE mlink.fnid=%d" |
| 352 | " AND event.objid=mlink.mid", |
| 353 | timeline_utc(), TAG_BRANCH, fnid |
| 354 | ); |
| 355 | if( (zA = P("a"))!=0 ){ |
| 356 | blob_append_sql(&sql, " AND event.mtime>=julianday('%q')", zA); |
| 357 | url_add_parameter(&url, "a", zA); |
| 358 | } |
| 359 | if( (zB = P("b"))!=0 ){ |
| 360 | blob_append_sql(&sql, " AND event.mtime<=julianday('%q')", zB); |
| 361 | url_add_parameter(&url, "b", zB); |
| 362 | } |
| 363 | blob_append_sql(&sql, |
| 364 | " GROUP BY mlink.fid" |
| 365 | " ORDER BY event.mtime DESC /*sort*/" |
| 366 | ); |
| 367 | if( (n = atoi(PD("n","0")))>0 ){ |
| 368 | blob_append_sql(&sql, " LIMIT %d", n); |
| 369 | url_add_parameter(&url, "n", P("n")); |
| 370 | } |
| 371 | db_prepare(&q, "%s", blob_sql_text(&sql)); |
| 372 | if( P("showsql")!=0 ){ |
| 373 | @ <p>SQL: %h(blob_str(&sql))</p> |
| 374 | } |
| 375 | blob_reset(&sql); |
| @@ -395,15 +377,18 @@ | |
| 377 | if( baseCheckin ){ |
| 378 | char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", baseCheckin); |
| 379 | char *zLink = href("%R/info/%s", zUuid); |
| 380 | blob_appendf(&title, "Ancestors of file "); |
| 381 | hyperlinked_path(zFilename, &title, zUuid, "tree", ""); |
| 382 | if( fShowId ) blob_appendf(&title, " (%d)", fnid); |
| 383 | blob_appendf(&title, " from check-in %z%S</a>", zLink, zUuid); |
| 384 | if( fShowId ) blob_appendf(&title, " (%d)", baseCheckin); |
| 385 | fossil_free(zUuid); |
| 386 | }else{ |
| 387 | blob_appendf(&title, "History of files named "); |
| 388 | hyperlinked_path(zFilename, &title, 0, "tree", ""); |
| 389 | if( fShowId ) blob_appendf(&title, " (%d)", fnid); |
| 390 | } |
| 391 | @ <h2>%b(&title)</h2> |
| 392 | blob_reset(&title); |
| 393 | pGraph = graph_init(); |
| 394 | @ <div id="canvas" style="position:relative;width:1px;height:1px;" |
| @@ -422,17 +407,36 @@ | |
| 407 | const char *zBr = db_column_text(&q, 9); |
| 408 | int fmid = db_column_int(&q, 10); |
| 409 | int pfnid = db_column_int(&q, 11); |
| 410 | int gidx; |
| 411 | char zTime[10]; |
| 412 | int nParent = 0; |
| 413 | int aParent[GR_MAX_RAIL]; |
| 414 | static Stmt qparent; |
| 415 | |
| 416 | if( baseCheckin && frid && !bag_find(&ancestor, frid) ) continue; |
| 417 | db_static_prepare(&qparent, |
| 418 | "SELECT DISTINCT pid FROM mlink" |
| 419 | " WHERE fid=:fid AND mid=:mid AND pid>0 AND fnid=:fnid" |
| 420 | " ORDER BY isaux /*sort*/" |
| 421 | ); |
| 422 | db_bind_int(&qparent, ":fid", frid); |
| 423 | db_bind_int(&qparent, ":mid", fmid); |
| 424 | db_bind_int(&qparent, ":fnid", fnid); |
| 425 | while( db_step(&qparent)==SQLITE_ROW && nParent<ArraySize(aParent) ){ |
| 426 | aParent[nParent] = db_column_int(&qparent, 0); |
| 427 | if( baseCheckin ) bag_insert(&ancestor, aParent[nParent]); |
| 428 | nParent++; |
| 429 | } |
| 430 | db_reset(&qparent); |
| 431 | if( zBr==0 ) zBr = "trunk"; |
| 432 | if( uBg ){ |
| 433 | zBgClr = hash_color(zUser); |
| 434 | }else if( brBg || zBgClr==0 || zBgClr[0]==0 ){ |
| 435 | zBgClr = strcmp(zBr,"trunk")==0 ? "" : hash_color(zBr); |
| 436 | } |
| 437 | gidx = graph_add_row(pGraph, frid, nParent, aParent, zBr, zBgClr, |
| 438 | zUuid, 0); |
| 439 | if( strncmp(zDate, zPrevDate, 10) ){ |
| 440 | sqlite3_snprintf(sizeof(zPrevDate), zPrevDate, "%.10s", zDate); |
| 441 | @ <tr><td> |
| 442 | @ <div class="divider">%s(zPrevDate)</div> |
| @@ -447,19 +451,23 @@ | |
| 451 | @ <td class="timelineTableCell" style="background-color: %h(zBgClr);"> |
| 452 | }else{ |
| 453 | @ <td class="timelineTableCell"> |
| 454 | } |
| 455 | if( zUuid ){ |
| 456 | if( nParent==0 ){ |
| 457 | @ <b>Added</b> |
| 458 | }else if( pfnid ){ |
| 459 | char *zPrevName = db_text(0, "SELECT name FROM filename WHERE fnid=%d", |
| 460 | pfnid); |
| 461 | @ <b>Renamed</b> from |
| 462 | @ %z(href("%R/finfo?name=%t", zPrevName))%h(zPrevName)</a> |
| 463 | } |
| 464 | @ %z(href("%R/artifact/%s",zUuid))[%S(zUuid)]</a> |
| 465 | if( fShowId ){ |
| 466 | @ (%d(frid)) |
| 467 | } |
| 468 | @ part of check-in |
| 469 | }else{ |
| 470 | char *zNewName; |
| 471 | zNewName = db_text(0, |
| 472 | "SELECT name FROM filename WHERE fnid = " |
| 473 | " (SELECT fnid FROM mlink" |
| @@ -473,13 +481,16 @@ | |
| 481 | }else{ |
| 482 | @ <b>Deleted</b> by check-in |
| 483 | } |
| 484 | } |
| 485 | hyperlink_to_uuid(zCkin); |
| 486 | if( fShowId ){ |
| 487 | @ (%d(fmid)) |
| 488 | } |
| 489 | @ %W(zCom) (user: |
| 490 | hyperlink_to_user(zUser, zDate, ""); |
| 491 | @ branch: %z(href("%R/timeline?t=%T&n=200",zBr))%h(zBr)</a> |
| 492 | if( g.perm.Hyperlink && zUuid ){ |
| 493 | const char *z = zFilename; |
| 494 | @ %z(href("%R/annotate?filename=%h&checkin=%s",z,zCkin)) |
| 495 | @ [annotate]</a> |
| 496 | @ %z(href("%R/blame?filename=%h&checkin=%s",z,zCkin)) |
| @@ -488,23 +499,26 @@ | |
| 499 | if( fpid ){ |
| 500 | @ %z(href("%R/fdiff?sbs=1&v1=%s&v2=%s",zPUuid,zUuid))[diff]</a> |
| 501 | } |
| 502 | } |
| 503 | if( fDebug & FINFO_DEBUG_MLINK ){ |
| 504 | int ii; |
| 505 | @ <br>fid=%d(frid) pid=%d(fpid) mid=%d(fmid) |
| 506 | if( nParent>0 ){ |
| 507 | @ parents=%d(aParent[0]) |
| 508 | for(ii=1; ii<nParent; ii++){ |
| 509 | @ %d(aParent[ii]) |
| 510 | } |
| 511 | } |
| 512 | @ %z(href("%R/finfo?name=%T&ci=%s&debug=1",zFilename,zCkin))[ancestry]</a> |
| 513 | } |
| 514 | tag_private_status(frid); |
| 515 | @ </td></tr> |
| 516 | } |
| 517 | db_finalize(&q); |
| 518 | if( pGraph ){ |
| 519 | graph_finish(pGraph, 1); |
| 520 | if( pGraph->nErr ){ |
| 521 | graph_free(pGraph); |
| 522 | pGraph = 0; |
| 523 | }else{ |
| 524 | int w = (pGraph->mxRail+1)*pGraph->iRailPitch + 10; |
| 525 |
+21
| --- src/graph.c | ||
| +++ src/graph.c | ||
| @@ -378,10 +378,31 @@ | ||
| 378 | 378 | i--; |
| 379 | 379 | } |
| 380 | 380 | } |
| 381 | 381 | } |
| 382 | 382 | } |
| 383 | + | |
| 384 | + /* If the primary parent is in a different branch, but there are | |
| 385 | + ** other parents in the same branch, reorder the parents to make | |
| 386 | + ** the parent from the same branch the primary parent. | |
| 387 | + */ | |
| 388 | + for(pRow=p->pFirst; pRow; pRow=pRow->pNext){ | |
| 389 | + if( pRow->isDup ) continue; | |
| 390 | + if( pRow->nParent<2 ) continue; /* Not a fork */ | |
| 391 | + pParent = hashFind(p, pRow->aParent[0]); | |
| 392 | + if( pParent==0 ) continue; /* Parent off-screen */ | |
| 393 | + if( pParent->zBranch==pRow->zBranch ) continue; /* Same branch */ | |
| 394 | + for(i=1; i<pRow->nParent; i++){ | |
| 395 | + pParent = hashFind(p, pRow->aParent[i]); | |
| 396 | + if( pParent && pParent->zBranch==pRow->zBranch ){ | |
| 397 | + int t = pRow->aParent[0]; | |
| 398 | + pRow->aParent[0] = pRow->aParent[i]; | |
| 399 | + pRow->aParent[i] = t; | |
| 400 | + break; | |
| 401 | + } | |
| 402 | + } | |
| 403 | + } | |
| 383 | 404 | |
| 384 | 405 | |
| 385 | 406 | /* Find the pChild pointer for each node. |
| 386 | 407 | ** |
| 387 | 408 | ** The pChild points to the node directly above on the same rail. |
| 388 | 409 |
| --- src/graph.c | |
| +++ src/graph.c | |
| @@ -378,10 +378,31 @@ | |
| 378 | i--; |
| 379 | } |
| 380 | } |
| 381 | } |
| 382 | } |
| 383 | |
| 384 | |
| 385 | /* Find the pChild pointer for each node. |
| 386 | ** |
| 387 | ** The pChild points to the node directly above on the same rail. |
| 388 |
| --- src/graph.c | |
| +++ src/graph.c | |
| @@ -378,10 +378,31 @@ | |
| 378 | i--; |
| 379 | } |
| 380 | } |
| 381 | } |
| 382 | } |
| 383 | |
| 384 | /* If the primary parent is in a different branch, but there are |
| 385 | ** other parents in the same branch, reorder the parents to make |
| 386 | ** the parent from the same branch the primary parent. |
| 387 | */ |
| 388 | for(pRow=p->pFirst; pRow; pRow=pRow->pNext){ |
| 389 | if( pRow->isDup ) continue; |
| 390 | if( pRow->nParent<2 ) continue; /* Not a fork */ |
| 391 | pParent = hashFind(p, pRow->aParent[0]); |
| 392 | if( pParent==0 ) continue; /* Parent off-screen */ |
| 393 | if( pParent->zBranch==pRow->zBranch ) continue; /* Same branch */ |
| 394 | for(i=1; i<pRow->nParent; i++){ |
| 395 | pParent = hashFind(p, pRow->aParent[i]); |
| 396 | if( pParent && pParent->zBranch==pRow->zBranch ){ |
| 397 | int t = pRow->aParent[0]; |
| 398 | pRow->aParent[0] = pRow->aParent[i]; |
| 399 | pRow->aParent[i] = t; |
| 400 | break; |
| 401 | } |
| 402 | } |
| 403 | } |
| 404 | |
| 405 | |
| 406 | /* Find the pChild pointer for each node. |
| 407 | ** |
| 408 | ** The pChild points to the node directly above on the same rail. |
| 409 |
+6
-6
| --- src/http.c | ||
| +++ src/http.c | ||
| @@ -155,11 +155,11 @@ | ||
| 155 | 155 | blob_reset(&x); |
| 156 | 156 | return ( c!='n' && c!='N' ); |
| 157 | 157 | } |
| 158 | 158 | |
| 159 | 159 | /* |
| 160 | -** Get the HTTP Basic Authorization credentials from the user | |
| 160 | +** Get the HTTP Basic Authorization credentials from the user | |
| 161 | 161 | ** when 401 is received. |
| 162 | 162 | */ |
| 163 | 163 | char *prompt_for_httpauth_creds(void){ |
| 164 | 164 | Blob x; |
| 165 | 165 | char *zUser; |
| @@ -266,11 +266,11 @@ | ||
| 266 | 266 | transport_send(&g.url, &hdr); |
| 267 | 267 | transport_send(&g.url, &payload); |
| 268 | 268 | blob_reset(&hdr); |
| 269 | 269 | blob_reset(&payload); |
| 270 | 270 | transport_flip(&g.url); |
| 271 | - | |
| 271 | + | |
| 272 | 272 | /* |
| 273 | 273 | ** Read and interpret the server reply |
| 274 | 274 | */ |
| 275 | 275 | closeConnection = 1; |
| 276 | 276 | iLength = -1; |
| @@ -333,11 +333,11 @@ | ||
| 333 | 333 | for(i=9; zLine[i] && zLine[i]==' '; i++){} |
| 334 | 334 | if( zLine[i]==0 ){ |
| 335 | 335 | fossil_warning("malformed redirect: %s", zLine); |
| 336 | 336 | goto write_err; |
| 337 | 337 | } |
| 338 | - j = strlen(zLine) - 1; | |
| 338 | + j = strlen(zLine) - 1; | |
| 339 | 339 | while( j>4 && fossil_strcmp(&zLine[j-4],"/xfer")==0 ){ |
| 340 | 340 | j -= 4; |
| 341 | 341 | zLine[j] = 0; |
| 342 | 342 | } |
| 343 | 343 | transport_close(&g.url); |
| @@ -349,11 +349,11 @@ | ||
| 349 | 349 | g.zHttpAuth = get_httpauth(); |
| 350 | 350 | return http_exchange(pSend, pReply, useLogin, maxRedirect); |
| 351 | 351 | }else if( fossil_strnicmp(zLine, "content-type: ", 14)==0 ){ |
| 352 | 352 | if( fossil_strnicmp(&zLine[14], "application/x-fossil-debug", -1)==0 ){ |
| 353 | 353 | isCompressed = 0; |
| 354 | - }else if( fossil_strnicmp(&zLine[14], | |
| 354 | + }else if( fossil_strnicmp(&zLine[14], | |
| 355 | 355 | "application/x-fossil-uncompressed", -1)==0 ){ |
| 356 | 356 | isCompressed = 0; |
| 357 | 357 | }else if( fossil_strnicmp(&zLine[14], "application/x-fossil", -1)!=0 ){ |
| 358 | 358 | isError = 1; |
| 359 | 359 | } |
| @@ -411,12 +411,12 @@ | ||
| 411 | 411 | }else{ |
| 412 | 412 | transport_rewind(&g.url); |
| 413 | 413 | } |
| 414 | 414 | return 0; |
| 415 | 415 | |
| 416 | - /* | |
| 416 | + /* | |
| 417 | 417 | ** Jump to here if an error is seen. |
| 418 | 418 | */ |
| 419 | 419 | write_err: |
| 420 | 420 | transport_close(&g.url); |
| 421 | - return 1; | |
| 421 | + return 1; | |
| 422 | 422 | } |
| 423 | 423 |
| --- src/http.c | |
| +++ src/http.c | |
| @@ -155,11 +155,11 @@ | |
| 155 | blob_reset(&x); |
| 156 | return ( c!='n' && c!='N' ); |
| 157 | } |
| 158 | |
| 159 | /* |
| 160 | ** Get the HTTP Basic Authorization credentials from the user |
| 161 | ** when 401 is received. |
| 162 | */ |
| 163 | char *prompt_for_httpauth_creds(void){ |
| 164 | Blob x; |
| 165 | char *zUser; |
| @@ -266,11 +266,11 @@ | |
| 266 | transport_send(&g.url, &hdr); |
| 267 | transport_send(&g.url, &payload); |
| 268 | blob_reset(&hdr); |
| 269 | blob_reset(&payload); |
| 270 | transport_flip(&g.url); |
| 271 | |
| 272 | /* |
| 273 | ** Read and interpret the server reply |
| 274 | */ |
| 275 | closeConnection = 1; |
| 276 | iLength = -1; |
| @@ -333,11 +333,11 @@ | |
| 333 | for(i=9; zLine[i] && zLine[i]==' '; i++){} |
| 334 | if( zLine[i]==0 ){ |
| 335 | fossil_warning("malformed redirect: %s", zLine); |
| 336 | goto write_err; |
| 337 | } |
| 338 | j = strlen(zLine) - 1; |
| 339 | while( j>4 && fossil_strcmp(&zLine[j-4],"/xfer")==0 ){ |
| 340 | j -= 4; |
| 341 | zLine[j] = 0; |
| 342 | } |
| 343 | transport_close(&g.url); |
| @@ -349,11 +349,11 @@ | |
| 349 | g.zHttpAuth = get_httpauth(); |
| 350 | return http_exchange(pSend, pReply, useLogin, maxRedirect); |
| 351 | }else if( fossil_strnicmp(zLine, "content-type: ", 14)==0 ){ |
| 352 | if( fossil_strnicmp(&zLine[14], "application/x-fossil-debug", -1)==0 ){ |
| 353 | isCompressed = 0; |
| 354 | }else if( fossil_strnicmp(&zLine[14], |
| 355 | "application/x-fossil-uncompressed", -1)==0 ){ |
| 356 | isCompressed = 0; |
| 357 | }else if( fossil_strnicmp(&zLine[14], "application/x-fossil", -1)!=0 ){ |
| 358 | isError = 1; |
| 359 | } |
| @@ -411,12 +411,12 @@ | |
| 411 | }else{ |
| 412 | transport_rewind(&g.url); |
| 413 | } |
| 414 | return 0; |
| 415 | |
| 416 | /* |
| 417 | ** Jump to here if an error is seen. |
| 418 | */ |
| 419 | write_err: |
| 420 | transport_close(&g.url); |
| 421 | return 1; |
| 422 | } |
| 423 |
| --- src/http.c | |
| +++ src/http.c | |
| @@ -155,11 +155,11 @@ | |
| 155 | blob_reset(&x); |
| 156 | return ( c!='n' && c!='N' ); |
| 157 | } |
| 158 | |
| 159 | /* |
| 160 | ** Get the HTTP Basic Authorization credentials from the user |
| 161 | ** when 401 is received. |
| 162 | */ |
| 163 | char *prompt_for_httpauth_creds(void){ |
| 164 | Blob x; |
| 165 | char *zUser; |
| @@ -266,11 +266,11 @@ | |
| 266 | transport_send(&g.url, &hdr); |
| 267 | transport_send(&g.url, &payload); |
| 268 | blob_reset(&hdr); |
| 269 | blob_reset(&payload); |
| 270 | transport_flip(&g.url); |
| 271 | |
| 272 | /* |
| 273 | ** Read and interpret the server reply |
| 274 | */ |
| 275 | closeConnection = 1; |
| 276 | iLength = -1; |
| @@ -333,11 +333,11 @@ | |
| 333 | for(i=9; zLine[i] && zLine[i]==' '; i++){} |
| 334 | if( zLine[i]==0 ){ |
| 335 | fossil_warning("malformed redirect: %s", zLine); |
| 336 | goto write_err; |
| 337 | } |
| 338 | j = strlen(zLine) - 1; |
| 339 | while( j>4 && fossil_strcmp(&zLine[j-4],"/xfer")==0 ){ |
| 340 | j -= 4; |
| 341 | zLine[j] = 0; |
| 342 | } |
| 343 | transport_close(&g.url); |
| @@ -349,11 +349,11 @@ | |
| 349 | g.zHttpAuth = get_httpauth(); |
| 350 | return http_exchange(pSend, pReply, useLogin, maxRedirect); |
| 351 | }else if( fossil_strnicmp(zLine, "content-type: ", 14)==0 ){ |
| 352 | if( fossil_strnicmp(&zLine[14], "application/x-fossil-debug", -1)==0 ){ |
| 353 | isCompressed = 0; |
| 354 | }else if( fossil_strnicmp(&zLine[14], |
| 355 | "application/x-fossil-uncompressed", -1)==0 ){ |
| 356 | isCompressed = 0; |
| 357 | }else if( fossil_strnicmp(&zLine[14], "application/x-fossil", -1)!=0 ){ |
| 358 | isError = 1; |
| 359 | } |
| @@ -411,12 +411,12 @@ | |
| 411 | }else{ |
| 412 | transport_rewind(&g.url); |
| 413 | } |
| 414 | return 0; |
| 415 | |
| 416 | /* |
| 417 | ** Jump to here if an error is seen. |
| 418 | */ |
| 419 | write_err: |
| 420 | transport_close(&g.url); |
| 421 | return 1; |
| 422 | } |
| 423 |
+15
-8
| --- src/http_socket.c | ||
| +++ src/http_socket.c | ||
| @@ -223,15 +223,22 @@ | ||
| 223 | 223 | ** so rcvfrom gets populated. For hostnames with more than one IP (or |
| 224 | 224 | ** if overridden in ~/.ssh/config) the rcvfrom may not match the host |
| 225 | 225 | ** to which we connect. |
| 226 | 226 | */ |
| 227 | 227 | void socket_ssh_resolve_addr(UrlData *pUrlData){ |
| 228 | - struct hostent *pHost; /* Used to make best effort for rcvfrom */ | |
| 229 | - struct sockaddr_in addr; | |
| 230 | - | |
| 231 | - memset(&addr, 0, sizeof(addr)); | |
| 232 | - pHost = gethostbyname(pUrlData->name); | |
| 233 | - if( pHost!=0 ){ | |
| 234 | - memcpy(&addr.sin_addr,pHost->h_addr_list[0],pHost->h_length); | |
| 235 | - g.zIpAddr = mprintf("%s", inet_ntoa(addr.sin_addr)); | |
| 228 | + struct addrinfo *ai = 0; | |
| 229 | + struct addrinfo hints; | |
| 230 | + char zRemote[NI_MAXHOST]; | |
| 231 | + hints.ai_family = AF_UNSPEC; | |
| 232 | + hints.ai_socktype = SOCK_STREAM; | |
| 233 | + hints.ai_protocol = IPPROTO_TCP; | |
| 234 | + if( getaddrinfo(pUrlData->name, NULL, &hints, &ai)==0 | |
| 235 | + && ai!=0 | |
| 236 | + && getnameinfo(ai->ai_addr, ai->ai_addrlen, zRemote, | |
| 237 | + sizeof(zRemote), 0, 0, NI_NUMERICHOST)==0 ){ | |
| 238 | + g.zIpAddr = mprintf("%s (%s)", zRemote, pUrlData->name); | |
| 239 | + } | |
| 240 | + if( ai ) freeaddrinfo(ai); | |
| 241 | + if( g.zIpAddr==0 ){ | |
| 242 | + g.zIpAddr = mprintf("%s", pUrlData->name); | |
| 236 | 243 | } |
| 237 | 244 | } |
| 238 | 245 |
| --- src/http_socket.c | |
| +++ src/http_socket.c | |
| @@ -223,15 +223,22 @@ | |
| 223 | ** so rcvfrom gets populated. For hostnames with more than one IP (or |
| 224 | ** if overridden in ~/.ssh/config) the rcvfrom may not match the host |
| 225 | ** to which we connect. |
| 226 | */ |
| 227 | void socket_ssh_resolve_addr(UrlData *pUrlData){ |
| 228 | struct hostent *pHost; /* Used to make best effort for rcvfrom */ |
| 229 | struct sockaddr_in addr; |
| 230 | |
| 231 | memset(&addr, 0, sizeof(addr)); |
| 232 | pHost = gethostbyname(pUrlData->name); |
| 233 | if( pHost!=0 ){ |
| 234 | memcpy(&addr.sin_addr,pHost->h_addr_list[0],pHost->h_length); |
| 235 | g.zIpAddr = mprintf("%s", inet_ntoa(addr.sin_addr)); |
| 236 | } |
| 237 | } |
| 238 |
| --- src/http_socket.c | |
| +++ src/http_socket.c | |
| @@ -223,15 +223,22 @@ | |
| 223 | ** so rcvfrom gets populated. For hostnames with more than one IP (or |
| 224 | ** if overridden in ~/.ssh/config) the rcvfrom may not match the host |
| 225 | ** to which we connect. |
| 226 | */ |
| 227 | void socket_ssh_resolve_addr(UrlData *pUrlData){ |
| 228 | struct addrinfo *ai = 0; |
| 229 | struct addrinfo hints; |
| 230 | char zRemote[NI_MAXHOST]; |
| 231 | hints.ai_family = AF_UNSPEC; |
| 232 | hints.ai_socktype = SOCK_STREAM; |
| 233 | hints.ai_protocol = IPPROTO_TCP; |
| 234 | if( getaddrinfo(pUrlData->name, NULL, &hints, &ai)==0 |
| 235 | && ai!=0 |
| 236 | && getnameinfo(ai->ai_addr, ai->ai_addrlen, zRemote, |
| 237 | sizeof(zRemote), 0, 0, NI_NUMERICHOST)==0 ){ |
| 238 | g.zIpAddr = mprintf("%s (%s)", zRemote, pUrlData->name); |
| 239 | } |
| 240 | if( ai ) freeaddrinfo(ai); |
| 241 | if( g.zIpAddr==0 ){ |
| 242 | g.zIpAddr = mprintf("%s", pUrlData->name); |
| 243 | } |
| 244 | } |
| 245 |
+1
-1
| --- src/http_transport.c | ||
| +++ src/http_transport.c | ||
| @@ -87,11 +87,11 @@ | ||
| 87 | 87 | |
| 88 | 88 | /* |
| 89 | 89 | ** SSH initialization of the transport layer |
| 90 | 90 | */ |
| 91 | 91 | int transport_ssh_open(UrlData *pUrlData){ |
| 92 | - /* For SSH we need to create and run SSH fossil http | |
| 92 | + /* For SSH we need to create and run SSH fossil http | |
| 93 | 93 | ** to talk to the remote machine. |
| 94 | 94 | */ |
| 95 | 95 | const char *zSsh; /* The base SSH command */ |
| 96 | 96 | Blob zCmd; /* The SSH command */ |
| 97 | 97 | char *zHost; /* The host name to contact */ |
| 98 | 98 |
| --- src/http_transport.c | |
| +++ src/http_transport.c | |
| @@ -87,11 +87,11 @@ | |
| 87 | |
| 88 | /* |
| 89 | ** SSH initialization of the transport layer |
| 90 | */ |
| 91 | int transport_ssh_open(UrlData *pUrlData){ |
| 92 | /* For SSH we need to create and run SSH fossil http |
| 93 | ** to talk to the remote machine. |
| 94 | */ |
| 95 | const char *zSsh; /* The base SSH command */ |
| 96 | Blob zCmd; /* The SSH command */ |
| 97 | char *zHost; /* The host name to contact */ |
| 98 |
| --- src/http_transport.c | |
| +++ src/http_transport.c | |
| @@ -87,11 +87,11 @@ | |
| 87 | |
| 88 | /* |
| 89 | ** SSH initialization of the transport layer |
| 90 | */ |
| 91 | int transport_ssh_open(UrlData *pUrlData){ |
| 92 | /* For SSH we need to create and run SSH fossil http |
| 93 | ** to talk to the remote machine. |
| 94 | */ |
| 95 | const char *zSsh; /* The base SSH command */ |
| 96 | Blob zCmd; /* The SSH command */ |
| 97 | char *zHost; /* The host name to contact */ |
| 98 |
+1
-1
| --- src/info.c | ||
| +++ src/info.c | ||
| @@ -714,11 +714,11 @@ | ||
| 714 | 714 | " mperm," |
| 715 | 715 | " (SELECT uuid FROM blob WHERE rid=mlink.pid)," |
| 716 | 716 | " (SELECT uuid FROM blob WHERE rid=mlink.fid)," |
| 717 | 717 | " (SELECT name FROM filename WHERE filename.fnid=mlink.pfnid)" |
| 718 | 718 | " FROM mlink JOIN filename ON filename.fnid=mlink.fnid" |
| 719 | - " WHERE mlink.mid=%d" | |
| 719 | + " WHERE mlink.mid=%d AND NOT mlink.isaux" | |
| 720 | 720 | " AND (mlink.fid>0" |
| 721 | 721 | " OR mlink.fnid NOT IN (SELECT pfnid FROM mlink WHERE mid=%d))" |
| 722 | 722 | " ORDER BY name /*sort*/", |
| 723 | 723 | rid, rid |
| 724 | 724 | ); |
| 725 | 725 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -714,11 +714,11 @@ | |
| 714 | " mperm," |
| 715 | " (SELECT uuid FROM blob WHERE rid=mlink.pid)," |
| 716 | " (SELECT uuid FROM blob WHERE rid=mlink.fid)," |
| 717 | " (SELECT name FROM filename WHERE filename.fnid=mlink.pfnid)" |
| 718 | " FROM mlink JOIN filename ON filename.fnid=mlink.fnid" |
| 719 | " WHERE mlink.mid=%d" |
| 720 | " AND (mlink.fid>0" |
| 721 | " OR mlink.fnid NOT IN (SELECT pfnid FROM mlink WHERE mid=%d))" |
| 722 | " ORDER BY name /*sort*/", |
| 723 | rid, rid |
| 724 | ); |
| 725 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -714,11 +714,11 @@ | |
| 714 | " mperm," |
| 715 | " (SELECT uuid FROM blob WHERE rid=mlink.pid)," |
| 716 | " (SELECT uuid FROM blob WHERE rid=mlink.fid)," |
| 717 | " (SELECT name FROM filename WHERE filename.fnid=mlink.pfnid)" |
| 718 | " FROM mlink JOIN filename ON filename.fnid=mlink.fnid" |
| 719 | " WHERE mlink.mid=%d AND NOT mlink.isaux" |
| 720 | " AND (mlink.fid>0" |
| 721 | " OR mlink.fnid NOT IN (SELECT pfnid FROM mlink WHERE mid=%d))" |
| 722 | " ORDER BY name /*sort*/", |
| 723 | rid, rid |
| 724 | ); |
| 725 |
+3
-2
| --- src/main.c | ||
| +++ src/main.c | ||
| @@ -143,10 +143,11 @@ | ||
| 143 | 143 | int fSqlTrace; /* True if --sqltrace flag is present */ |
| 144 | 144 | int fSqlStats; /* True if --sqltrace or --sqlstats are present */ |
| 145 | 145 | int fSqlPrint; /* True if -sqlprint flag is present */ |
| 146 | 146 | int fQuiet; /* True if -quiet flag is present */ |
| 147 | 147 | int fHttpTrace; /* Trace outbound HTTP requests */ |
| 148 | + int fAnyTrace; /* Any kind of tracing */ | |
| 148 | 149 | char *zHttpAuth; /* HTTP Authorization user:pass information */ |
| 149 | 150 | int fSystemTrace; /* Trace calls to fossil_system(), --systemtrace */ |
| 150 | 151 | int fSshTrace; /* Trace the SSH setup traffic */ |
| 151 | 152 | int fSshClient; /* HTTP client flags for SSH client */ |
| 152 | 153 | char *zSshCmd; /* SSH command string */ |
| @@ -658,15 +659,15 @@ | ||
| 658 | 659 | g.fSystemTrace = find_option("systemtrace", 0, 0)!=0; |
| 659 | 660 | g.fSshTrace = find_option("sshtrace", 0, 0)!=0; |
| 660 | 661 | g.fSshClient = 0; |
| 661 | 662 | g.zSshCmd = 0; |
| 662 | 663 | if( g.fSqlTrace ) g.fSqlStats = 1; |
| 663 | - g.fSqlPrint = find_option("sqlprint", 0, 0)!=0; | |
| 664 | 664 | g.fHttpTrace = find_option("httptrace", 0, 0)!=0; |
| 665 | 665 | #ifdef FOSSIL_ENABLE_TH1_HOOKS |
| 666 | 666 | g.fNoThHook = find_option("no-th-hook", 0, 0)!=0; |
| 667 | 667 | #endif |
| 668 | + g.fAnyTrace = g.fSqlTrace|g.fSystemTrace|g.fSshTrace|g.fHttpTrace; | |
| 668 | 669 | g.zHttpAuth = 0; |
| 669 | 670 | g.zLogin = find_option("user", "U", 1); |
| 670 | 671 | g.zSSLIdentity = find_option("ssl-identity", 0, 1); |
| 671 | 672 | g.zErrlog = find_option("errorlog", 0, 1); |
| 672 | 673 | fossil_init_flags_from_options(); |
| @@ -1873,11 +1874,11 @@ | ||
| 1873 | 1874 | } |
| 1874 | 1875 | if( blob_eq(&key, "debug:") && blob_token(&line, &value) ){ |
| 1875 | 1876 | /* debug: FILENAME |
| 1876 | 1877 | ** |
| 1877 | 1878 | ** Causes output from cgi_debug() and CGIDEBUG(()) calls to go |
| 1878 | - ** into FILENAME. | |
| 1879 | + ** into FILENAME. | |
| 1879 | 1880 | */ |
| 1880 | 1881 | g.fDebug = fossil_fopen(blob_str(&value), "ab"); |
| 1881 | 1882 | blob_reset(&value); |
| 1882 | 1883 | continue; |
| 1883 | 1884 | } |
| 1884 | 1885 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -143,10 +143,11 @@ | |
| 143 | int fSqlTrace; /* True if --sqltrace flag is present */ |
| 144 | int fSqlStats; /* True if --sqltrace or --sqlstats are present */ |
| 145 | int fSqlPrint; /* True if -sqlprint flag is present */ |
| 146 | int fQuiet; /* True if -quiet flag is present */ |
| 147 | int fHttpTrace; /* Trace outbound HTTP requests */ |
| 148 | char *zHttpAuth; /* HTTP Authorization user:pass information */ |
| 149 | int fSystemTrace; /* Trace calls to fossil_system(), --systemtrace */ |
| 150 | int fSshTrace; /* Trace the SSH setup traffic */ |
| 151 | int fSshClient; /* HTTP client flags for SSH client */ |
| 152 | char *zSshCmd; /* SSH command string */ |
| @@ -658,15 +659,15 @@ | |
| 658 | g.fSystemTrace = find_option("systemtrace", 0, 0)!=0; |
| 659 | g.fSshTrace = find_option("sshtrace", 0, 0)!=0; |
| 660 | g.fSshClient = 0; |
| 661 | g.zSshCmd = 0; |
| 662 | if( g.fSqlTrace ) g.fSqlStats = 1; |
| 663 | g.fSqlPrint = find_option("sqlprint", 0, 0)!=0; |
| 664 | g.fHttpTrace = find_option("httptrace", 0, 0)!=0; |
| 665 | #ifdef FOSSIL_ENABLE_TH1_HOOKS |
| 666 | g.fNoThHook = find_option("no-th-hook", 0, 0)!=0; |
| 667 | #endif |
| 668 | g.zHttpAuth = 0; |
| 669 | g.zLogin = find_option("user", "U", 1); |
| 670 | g.zSSLIdentity = find_option("ssl-identity", 0, 1); |
| 671 | g.zErrlog = find_option("errorlog", 0, 1); |
| 672 | fossil_init_flags_from_options(); |
| @@ -1873,11 +1874,11 @@ | |
| 1873 | } |
| 1874 | if( blob_eq(&key, "debug:") && blob_token(&line, &value) ){ |
| 1875 | /* debug: FILENAME |
| 1876 | ** |
| 1877 | ** Causes output from cgi_debug() and CGIDEBUG(()) calls to go |
| 1878 | ** into FILENAME. |
| 1879 | */ |
| 1880 | g.fDebug = fossil_fopen(blob_str(&value), "ab"); |
| 1881 | blob_reset(&value); |
| 1882 | continue; |
| 1883 | } |
| 1884 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -143,10 +143,11 @@ | |
| 143 | int fSqlTrace; /* True if --sqltrace flag is present */ |
| 144 | int fSqlStats; /* True if --sqltrace or --sqlstats are present */ |
| 145 | int fSqlPrint; /* True if -sqlprint flag is present */ |
| 146 | int fQuiet; /* True if -quiet flag is present */ |
| 147 | int fHttpTrace; /* Trace outbound HTTP requests */ |
| 148 | int fAnyTrace; /* Any kind of tracing */ |
| 149 | char *zHttpAuth; /* HTTP Authorization user:pass information */ |
| 150 | int fSystemTrace; /* Trace calls to fossil_system(), --systemtrace */ |
| 151 | int fSshTrace; /* Trace the SSH setup traffic */ |
| 152 | int fSshClient; /* HTTP client flags for SSH client */ |
| 153 | char *zSshCmd; /* SSH command string */ |
| @@ -658,15 +659,15 @@ | |
| 659 | g.fSystemTrace = find_option("systemtrace", 0, 0)!=0; |
| 660 | g.fSshTrace = find_option("sshtrace", 0, 0)!=0; |
| 661 | g.fSshClient = 0; |
| 662 | g.zSshCmd = 0; |
| 663 | if( g.fSqlTrace ) g.fSqlStats = 1; |
| 664 | g.fHttpTrace = find_option("httptrace", 0, 0)!=0; |
| 665 | #ifdef FOSSIL_ENABLE_TH1_HOOKS |
| 666 | g.fNoThHook = find_option("no-th-hook", 0, 0)!=0; |
| 667 | #endif |
| 668 | g.fAnyTrace = g.fSqlTrace|g.fSystemTrace|g.fSshTrace|g.fHttpTrace; |
| 669 | g.zHttpAuth = 0; |
| 670 | g.zLogin = find_option("user", "U", 1); |
| 671 | g.zSSLIdentity = find_option("ssl-identity", 0, 1); |
| 672 | g.zErrlog = find_option("errorlog", 0, 1); |
| 673 | fossil_init_flags_from_options(); |
| @@ -1873,11 +1874,11 @@ | |
| 1874 | } |
| 1875 | if( blob_eq(&key, "debug:") && blob_token(&line, &value) ){ |
| 1876 | /* debug: FILENAME |
| 1877 | ** |
| 1878 | ** Causes output from cgi_debug() and CGIDEBUG(()) calls to go |
| 1879 | ** into FILENAME. |
| 1880 | */ |
| 1881 | g.fDebug = fossil_fopen(blob_str(&value), "ab"); |
| 1882 | blob_reset(&value); |
| 1883 | continue; |
| 1884 | } |
| 1885 |
+15
-2
| --- src/main.mk | ||
| +++ src/main.mk | ||
| @@ -104,10 +104,11 @@ | ||
| 104 | 104 | $(SRCDIR)/sitemap.c \ |
| 105 | 105 | $(SRCDIR)/skins.c \ |
| 106 | 106 | $(SRCDIR)/sqlcmd.c \ |
| 107 | 107 | $(SRCDIR)/stash.c \ |
| 108 | 108 | $(SRCDIR)/stat.c \ |
| 109 | + $(SRCDIR)/statrep.c \ | |
| 109 | 110 | $(SRCDIR)/style.c \ |
| 110 | 111 | $(SRCDIR)/sync.c \ |
| 111 | 112 | $(SRCDIR)/tag.c \ |
| 112 | 113 | $(SRCDIR)/tar.c \ |
| 113 | 114 | $(SRCDIR)/th_main.c \ |
| @@ -155,11 +156,12 @@ | ||
| 155 | 156 | $(SRCDIR)/../skins/plain_gray/footer.txt \ |
| 156 | 157 | $(SRCDIR)/../skins/plain_gray/header.txt \ |
| 157 | 158 | $(SRCDIR)/../skins/rounded1/css.txt \ |
| 158 | 159 | $(SRCDIR)/../skins/rounded1/footer.txt \ |
| 159 | 160 | $(SRCDIR)/../skins/rounded1/header.txt \ |
| 160 | - $(SRCDIR)/diff.tcl | |
| 161 | + $(SRCDIR)/diff.tcl \ | |
| 162 | + $(SRCDIR)/markdown.md | |
| 161 | 163 | |
| 162 | 164 | TRANS_SRC = \ |
| 163 | 165 | $(OBJDIR)/add_.c \ |
| 164 | 166 | $(OBJDIR)/allrepo_.c \ |
| 165 | 167 | $(OBJDIR)/attach_.c \ |
| @@ -250,10 +252,11 @@ | ||
| 250 | 252 | $(OBJDIR)/sitemap_.c \ |
| 251 | 253 | $(OBJDIR)/skins_.c \ |
| 252 | 254 | $(OBJDIR)/sqlcmd_.c \ |
| 253 | 255 | $(OBJDIR)/stash_.c \ |
| 254 | 256 | $(OBJDIR)/stat_.c \ |
| 257 | + $(OBJDIR)/statrep_.c \ | |
| 255 | 258 | $(OBJDIR)/style_.c \ |
| 256 | 259 | $(OBJDIR)/sync_.c \ |
| 257 | 260 | $(OBJDIR)/tag_.c \ |
| 258 | 261 | $(OBJDIR)/tar_.c \ |
| 259 | 262 | $(OBJDIR)/th_main_.c \ |
| @@ -369,10 +372,11 @@ | ||
| 369 | 372 | $(OBJDIR)/sitemap.o \ |
| 370 | 373 | $(OBJDIR)/skins.o \ |
| 371 | 374 | $(OBJDIR)/sqlcmd.o \ |
| 372 | 375 | $(OBJDIR)/stash.o \ |
| 373 | 376 | $(OBJDIR)/stat.o \ |
| 377 | + $(OBJDIR)/statrep.o \ | |
| 374 | 378 | $(OBJDIR)/style.o \ |
| 375 | 379 | $(OBJDIR)/sync.o \ |
| 376 | 380 | $(OBJDIR)/tag.o \ |
| 377 | 381 | $(OBJDIR)/tar.o \ |
| 378 | 382 | $(OBJDIR)/th_main.o \ |
| @@ -502,11 +506,11 @@ | ||
| 502 | 506 | |
| 503 | 507 | $(OBJDIR)/page_index.h: $(TRANS_SRC) $(OBJDIR)/mkindex |
| 504 | 508 | $(OBJDIR)/mkindex $(TRANS_SRC) >$@ |
| 505 | 509 | |
| 506 | 510 | $(OBJDIR)/builtin_data.h: $(OBJDIR)/mkbuiltin $(EXTRA_FILES) |
| 507 | - $(OBJDIR)/mkbuiltin $(EXTRA_FILES) >$@ | |
| 511 | + $(OBJDIR)/mkbuiltin --prefix $(SRCDIR)/ $(EXTRA_FILES) >$@ | |
| 508 | 512 | |
| 509 | 513 | $(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/builtin_data.h $(OBJDIR)/makeheaders $(OBJDIR)/VERSION.h |
| 510 | 514 | $(OBJDIR)/makeheaders $(OBJDIR)/add_.c:$(OBJDIR)/add.h \ |
| 511 | 515 | $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h \ |
| 512 | 516 | $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h \ |
| @@ -597,10 +601,11 @@ | ||
| 597 | 601 | $(OBJDIR)/sitemap_.c:$(OBJDIR)/sitemap.h \ |
| 598 | 602 | $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h \ |
| 599 | 603 | $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h \ |
| 600 | 604 | $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h \ |
| 601 | 605 | $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h \ |
| 606 | + $(OBJDIR)/statrep_.c:$(OBJDIR)/statrep.h \ | |
| 602 | 607 | $(OBJDIR)/style_.c:$(OBJDIR)/style.h \ |
| 603 | 608 | $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h \ |
| 604 | 609 | $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h \ |
| 605 | 610 | $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h \ |
| 606 | 611 | $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h \ |
| @@ -1364,10 +1369,18 @@ | ||
| 1364 | 1369 | |
| 1365 | 1370 | $(OBJDIR)/stat.o: $(OBJDIR)/stat_.c $(OBJDIR)/stat.h $(SRCDIR)/config.h |
| 1366 | 1371 | $(XTCC) -o $(OBJDIR)/stat.o -c $(OBJDIR)/stat_.c |
| 1367 | 1372 | |
| 1368 | 1373 | $(OBJDIR)/stat.h: $(OBJDIR)/headers |
| 1374 | + | |
| 1375 | +$(OBJDIR)/statrep_.c: $(SRCDIR)/statrep.c $(OBJDIR)/translate | |
| 1376 | + $(OBJDIR)/translate $(SRCDIR)/statrep.c >$@ | |
| 1377 | + | |
| 1378 | +$(OBJDIR)/statrep.o: $(OBJDIR)/statrep_.c $(OBJDIR)/statrep.h $(SRCDIR)/config.h | |
| 1379 | + $(XTCC) -o $(OBJDIR)/statrep.o -c $(OBJDIR)/statrep_.c | |
| 1380 | + | |
| 1381 | +$(OBJDIR)/statrep.h: $(OBJDIR)/headers | |
| 1369 | 1382 | |
| 1370 | 1383 | $(OBJDIR)/style_.c: $(SRCDIR)/style.c $(OBJDIR)/translate |
| 1371 | 1384 | $(OBJDIR)/translate $(SRCDIR)/style.c >$@ |
| 1372 | 1385 | |
| 1373 | 1386 | $(OBJDIR)/style.o: $(OBJDIR)/style_.c $(OBJDIR)/style.h $(SRCDIR)/config.h |
| 1374 | 1387 |
| --- src/main.mk | |
| +++ src/main.mk | |
| @@ -104,10 +104,11 @@ | |
| 104 | $(SRCDIR)/sitemap.c \ |
| 105 | $(SRCDIR)/skins.c \ |
| 106 | $(SRCDIR)/sqlcmd.c \ |
| 107 | $(SRCDIR)/stash.c \ |
| 108 | $(SRCDIR)/stat.c \ |
| 109 | $(SRCDIR)/style.c \ |
| 110 | $(SRCDIR)/sync.c \ |
| 111 | $(SRCDIR)/tag.c \ |
| 112 | $(SRCDIR)/tar.c \ |
| 113 | $(SRCDIR)/th_main.c \ |
| @@ -155,11 +156,12 @@ | |
| 155 | $(SRCDIR)/../skins/plain_gray/footer.txt \ |
| 156 | $(SRCDIR)/../skins/plain_gray/header.txt \ |
| 157 | $(SRCDIR)/../skins/rounded1/css.txt \ |
| 158 | $(SRCDIR)/../skins/rounded1/footer.txt \ |
| 159 | $(SRCDIR)/../skins/rounded1/header.txt \ |
| 160 | $(SRCDIR)/diff.tcl |
| 161 | |
| 162 | TRANS_SRC = \ |
| 163 | $(OBJDIR)/add_.c \ |
| 164 | $(OBJDIR)/allrepo_.c \ |
| 165 | $(OBJDIR)/attach_.c \ |
| @@ -250,10 +252,11 @@ | |
| 250 | $(OBJDIR)/sitemap_.c \ |
| 251 | $(OBJDIR)/skins_.c \ |
| 252 | $(OBJDIR)/sqlcmd_.c \ |
| 253 | $(OBJDIR)/stash_.c \ |
| 254 | $(OBJDIR)/stat_.c \ |
| 255 | $(OBJDIR)/style_.c \ |
| 256 | $(OBJDIR)/sync_.c \ |
| 257 | $(OBJDIR)/tag_.c \ |
| 258 | $(OBJDIR)/tar_.c \ |
| 259 | $(OBJDIR)/th_main_.c \ |
| @@ -369,10 +372,11 @@ | |
| 369 | $(OBJDIR)/sitemap.o \ |
| 370 | $(OBJDIR)/skins.o \ |
| 371 | $(OBJDIR)/sqlcmd.o \ |
| 372 | $(OBJDIR)/stash.o \ |
| 373 | $(OBJDIR)/stat.o \ |
| 374 | $(OBJDIR)/style.o \ |
| 375 | $(OBJDIR)/sync.o \ |
| 376 | $(OBJDIR)/tag.o \ |
| 377 | $(OBJDIR)/tar.o \ |
| 378 | $(OBJDIR)/th_main.o \ |
| @@ -502,11 +506,11 @@ | |
| 502 | |
| 503 | $(OBJDIR)/page_index.h: $(TRANS_SRC) $(OBJDIR)/mkindex |
| 504 | $(OBJDIR)/mkindex $(TRANS_SRC) >$@ |
| 505 | |
| 506 | $(OBJDIR)/builtin_data.h: $(OBJDIR)/mkbuiltin $(EXTRA_FILES) |
| 507 | $(OBJDIR)/mkbuiltin $(EXTRA_FILES) >$@ |
| 508 | |
| 509 | $(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/builtin_data.h $(OBJDIR)/makeheaders $(OBJDIR)/VERSION.h |
| 510 | $(OBJDIR)/makeheaders $(OBJDIR)/add_.c:$(OBJDIR)/add.h \ |
| 511 | $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h \ |
| 512 | $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h \ |
| @@ -597,10 +601,11 @@ | |
| 597 | $(OBJDIR)/sitemap_.c:$(OBJDIR)/sitemap.h \ |
| 598 | $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h \ |
| 599 | $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h \ |
| 600 | $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h \ |
| 601 | $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h \ |
| 602 | $(OBJDIR)/style_.c:$(OBJDIR)/style.h \ |
| 603 | $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h \ |
| 604 | $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h \ |
| 605 | $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h \ |
| 606 | $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h \ |
| @@ -1364,10 +1369,18 @@ | |
| 1364 | |
| 1365 | $(OBJDIR)/stat.o: $(OBJDIR)/stat_.c $(OBJDIR)/stat.h $(SRCDIR)/config.h |
| 1366 | $(XTCC) -o $(OBJDIR)/stat.o -c $(OBJDIR)/stat_.c |
| 1367 | |
| 1368 | $(OBJDIR)/stat.h: $(OBJDIR)/headers |
| 1369 | |
| 1370 | $(OBJDIR)/style_.c: $(SRCDIR)/style.c $(OBJDIR)/translate |
| 1371 | $(OBJDIR)/translate $(SRCDIR)/style.c >$@ |
| 1372 | |
| 1373 | $(OBJDIR)/style.o: $(OBJDIR)/style_.c $(OBJDIR)/style.h $(SRCDIR)/config.h |
| 1374 |
| --- src/main.mk | |
| +++ src/main.mk | |
| @@ -104,10 +104,11 @@ | |
| 104 | $(SRCDIR)/sitemap.c \ |
| 105 | $(SRCDIR)/skins.c \ |
| 106 | $(SRCDIR)/sqlcmd.c \ |
| 107 | $(SRCDIR)/stash.c \ |
| 108 | $(SRCDIR)/stat.c \ |
| 109 | $(SRCDIR)/statrep.c \ |
| 110 | $(SRCDIR)/style.c \ |
| 111 | $(SRCDIR)/sync.c \ |
| 112 | $(SRCDIR)/tag.c \ |
| 113 | $(SRCDIR)/tar.c \ |
| 114 | $(SRCDIR)/th_main.c \ |
| @@ -155,11 +156,12 @@ | |
| 156 | $(SRCDIR)/../skins/plain_gray/footer.txt \ |
| 157 | $(SRCDIR)/../skins/plain_gray/header.txt \ |
| 158 | $(SRCDIR)/../skins/rounded1/css.txt \ |
| 159 | $(SRCDIR)/../skins/rounded1/footer.txt \ |
| 160 | $(SRCDIR)/../skins/rounded1/header.txt \ |
| 161 | $(SRCDIR)/diff.tcl \ |
| 162 | $(SRCDIR)/markdown.md |
| 163 | |
| 164 | TRANS_SRC = \ |
| 165 | $(OBJDIR)/add_.c \ |
| 166 | $(OBJDIR)/allrepo_.c \ |
| 167 | $(OBJDIR)/attach_.c \ |
| @@ -250,10 +252,11 @@ | |
| 252 | $(OBJDIR)/sitemap_.c \ |
| 253 | $(OBJDIR)/skins_.c \ |
| 254 | $(OBJDIR)/sqlcmd_.c \ |
| 255 | $(OBJDIR)/stash_.c \ |
| 256 | $(OBJDIR)/stat_.c \ |
| 257 | $(OBJDIR)/statrep_.c \ |
| 258 | $(OBJDIR)/style_.c \ |
| 259 | $(OBJDIR)/sync_.c \ |
| 260 | $(OBJDIR)/tag_.c \ |
| 261 | $(OBJDIR)/tar_.c \ |
| 262 | $(OBJDIR)/th_main_.c \ |
| @@ -369,10 +372,11 @@ | |
| 372 | $(OBJDIR)/sitemap.o \ |
| 373 | $(OBJDIR)/skins.o \ |
| 374 | $(OBJDIR)/sqlcmd.o \ |
| 375 | $(OBJDIR)/stash.o \ |
| 376 | $(OBJDIR)/stat.o \ |
| 377 | $(OBJDIR)/statrep.o \ |
| 378 | $(OBJDIR)/style.o \ |
| 379 | $(OBJDIR)/sync.o \ |
| 380 | $(OBJDIR)/tag.o \ |
| 381 | $(OBJDIR)/tar.o \ |
| 382 | $(OBJDIR)/th_main.o \ |
| @@ -502,11 +506,11 @@ | |
| 506 | |
| 507 | $(OBJDIR)/page_index.h: $(TRANS_SRC) $(OBJDIR)/mkindex |
| 508 | $(OBJDIR)/mkindex $(TRANS_SRC) >$@ |
| 509 | |
| 510 | $(OBJDIR)/builtin_data.h: $(OBJDIR)/mkbuiltin $(EXTRA_FILES) |
| 511 | $(OBJDIR)/mkbuiltin --prefix $(SRCDIR)/ $(EXTRA_FILES) >$@ |
| 512 | |
| 513 | $(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/builtin_data.h $(OBJDIR)/makeheaders $(OBJDIR)/VERSION.h |
| 514 | $(OBJDIR)/makeheaders $(OBJDIR)/add_.c:$(OBJDIR)/add.h \ |
| 515 | $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h \ |
| 516 | $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h \ |
| @@ -597,10 +601,11 @@ | |
| 601 | $(OBJDIR)/sitemap_.c:$(OBJDIR)/sitemap.h \ |
| 602 | $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h \ |
| 603 | $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h \ |
| 604 | $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h \ |
| 605 | $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h \ |
| 606 | $(OBJDIR)/statrep_.c:$(OBJDIR)/statrep.h \ |
| 607 | $(OBJDIR)/style_.c:$(OBJDIR)/style.h \ |
| 608 | $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h \ |
| 609 | $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h \ |
| 610 | $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h \ |
| 611 | $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h \ |
| @@ -1364,10 +1369,18 @@ | |
| 1369 | |
| 1370 | $(OBJDIR)/stat.o: $(OBJDIR)/stat_.c $(OBJDIR)/stat.h $(SRCDIR)/config.h |
| 1371 | $(XTCC) -o $(OBJDIR)/stat.o -c $(OBJDIR)/stat_.c |
| 1372 | |
| 1373 | $(OBJDIR)/stat.h: $(OBJDIR)/headers |
| 1374 | |
| 1375 | $(OBJDIR)/statrep_.c: $(SRCDIR)/statrep.c $(OBJDIR)/translate |
| 1376 | $(OBJDIR)/translate $(SRCDIR)/statrep.c >$@ |
| 1377 | |
| 1378 | $(OBJDIR)/statrep.o: $(OBJDIR)/statrep_.c $(OBJDIR)/statrep.h $(SRCDIR)/config.h |
| 1379 | $(XTCC) -o $(OBJDIR)/statrep.o -c $(OBJDIR)/statrep_.c |
| 1380 | |
| 1381 | $(OBJDIR)/statrep.h: $(OBJDIR)/headers |
| 1382 | |
| 1383 | $(OBJDIR)/style_.c: $(SRCDIR)/style.c $(OBJDIR)/translate |
| 1384 | $(OBJDIR)/translate $(SRCDIR)/style.c >$@ |
| 1385 | |
| 1386 | $(OBJDIR)/style.o: $(OBJDIR)/style_.c $(OBJDIR)/style.h $(SRCDIR)/config.h |
| 1387 |
+7
-5
| --- src/makemake.tcl | ||
| +++ src/makemake.tcl | ||
| @@ -110,10 +110,11 @@ | ||
| 110 | 110 | sitemap |
| 111 | 111 | skins |
| 112 | 112 | sqlcmd |
| 113 | 113 | stash |
| 114 | 114 | stat |
| 115 | + statrep | |
| 115 | 116 | style |
| 116 | 117 | sync |
| 117 | 118 | tag |
| 118 | 119 | tar |
| 119 | 120 | th_main |
| @@ -142,10 +143,11 @@ | ||
| 142 | 143 | |
| 143 | 144 | # Additional resource files that get built into the executable. |
| 144 | 145 | # |
| 145 | 146 | set extra_files { |
| 146 | 147 | diff.tcl |
| 148 | + markdown.md | |
| 147 | 149 | ../skins/*/*.txt |
| 148 | 150 | } |
| 149 | 151 | |
| 150 | 152 | # Options used to compile the included SQLite library. |
| 151 | 153 | # |
| @@ -372,11 +374,11 @@ | ||
| 372 | 374 | set mhargs [string map [list <<<NEXT_LINE>>> \\\n\t] $mhargs] |
| 373 | 375 | writeln "\$(OBJDIR)/page_index.h: \$(TRANS_SRC) \$(OBJDIR)/mkindex" |
| 374 | 376 | writeln "\t\$(OBJDIR)/mkindex \$(TRANS_SRC) >\$@\n" |
| 375 | 377 | |
| 376 | 378 | writeln "\$(OBJDIR)/builtin_data.h: \$(OBJDIR)/mkbuiltin \$(EXTRA_FILES)" |
| 377 | -writeln "\t\$(OBJDIR)/mkbuiltin \$(EXTRA_FILES) >\$@\n" | |
| 379 | +writeln "\t\$(OBJDIR)/mkbuiltin --prefix \$(SRCDIR)/ \$(EXTRA_FILES) >\$@\n" | |
| 378 | 380 | |
| 379 | 381 | writeln "\$(OBJDIR)/headers:\t\$(OBJDIR)/page_index.h \$(OBJDIR)/builtin_data.h \$(OBJDIR)/makeheaders \$(OBJDIR)/VERSION.h" |
| 380 | 382 | writeln "\t\$(OBJDIR)/makeheaders $mhargs" |
| 381 | 383 | writeln "\ttouch \$(OBJDIR)/headers" |
| 382 | 384 | writeln "\$(OBJDIR)/headers: Makefile" |
| @@ -1025,11 +1027,11 @@ | ||
| 1025 | 1027 | append mhargs " \\\n\t\t\$(OBJDIR)/VERSION.h" |
| 1026 | 1028 | writeln "\$(OBJDIR)/page_index.h: \$(TRANS_SRC) \$(MKINDEX)" |
| 1027 | 1029 | writeln "\t\$(MKINDEX) \$(TRANS_SRC) >\$@\n" |
| 1028 | 1030 | |
| 1029 | 1031 | writeln "\$(OBJDIR)/builtin_data.h:\t\$(MKBUILTIN) \$(EXTRA_FILES)" |
| 1030 | -writeln "\t\$(MKBUILTIN) \$(EXTRA_FILES) >\$@\n" | |
| 1032 | +writeln "\t\$(MKBUILTIN) --prefix \$(SRCDIR)/ \$(EXTRA_FILES) >\$@\n" | |
| 1031 | 1033 | |
| 1032 | 1034 | writeln "\$(OBJDIR)/headers:\t\$(OBJDIR)/page_index.h \$(OBJDIR)/builtin_data.h \$(MAKEHEADERS) \$(OBJDIR)/VERSION.h" |
| 1033 | 1035 | writeln "\t\$(MAKEHEADERS) $mhargs" |
| 1034 | 1036 | writeln "\techo Done >\$(OBJDIR)/headers\n" |
| 1035 | 1037 | writeln "\$(OBJDIR)/headers: Makefile\n" |
| @@ -1204,11 +1206,11 @@ | ||
| 1204 | 1206 | |
| 1205 | 1207 | page_index.h: mkindex$E $(SRC) |
| 1206 | 1208 | +$** > $@ |
| 1207 | 1209 | |
| 1208 | 1210 | builtin_data.h: mkbuiltin$E $(EXTRA_FILES) |
| 1209 | - +$** > $@ | |
| 1211 | + mkbuiltin$E --prefix $(SRCDIR)/ $(EXTRA_FILES) > $@ | |
| 1210 | 1212 | |
| 1211 | 1213 | clean: |
| 1212 | 1214 | -del $(OBJDIR)\*.obj |
| 1213 | 1215 | -del *.obj *_.c *.h *.map |
| 1214 | 1216 | |
| @@ -1598,11 +1600,11 @@ | ||
| 1598 | 1600 | |
| 1599 | 1601 | page_index.h: mkindex$E $(SRC) |
| 1600 | 1602 | $** > $@ |
| 1601 | 1603 | |
| 1602 | 1604 | builtin_data.h: mkbuiltin$E $(EXTRA_FILES) |
| 1603 | - $** > $@ | |
| 1605 | + mkbuiltin$E --prefix $(SRCDIR)/ $(EXTRA_FILES) > $@ | |
| 1604 | 1606 | |
| 1605 | 1607 | clean: |
| 1606 | 1608 | -del $(OX)\*.obj |
| 1607 | 1609 | -del *.obj |
| 1608 | 1610 | -del *_.c |
| @@ -1830,11 +1832,11 @@ | ||
| 1830 | 1832 | # generate the index source, containing all web references,.. |
| 1831 | 1833 | page_index.h: $(TRANSLATEDSRC) mkindex.exe |
| 1832 | 1834 | mkindex.exe $(TRANSLATEDSRC) >$@ |
| 1833 | 1835 | |
| 1834 | 1836 | builtin_data.h: $(EXTRA_FILES) mkbuiltin.exe |
| 1835 | - mkbuiltin.exe $(EXTRA_FILES) >$@ | |
| 1837 | + mkbuiltin.exe --prefix $(SRCDIR)/ $(EXTRA_FILES) >$@ | |
| 1836 | 1838 | |
| 1837 | 1839 | # extracting version info from manifest |
| 1838 | 1840 | VERSION.h: version.exe ..\manifest.uuid ..\manifest ..\VERSION |
| 1839 | 1841 | version.exe ..\manifest.uuid ..\manifest ..\VERSION >$@ |
| 1840 | 1842 | |
| 1841 | 1843 |
| --- src/makemake.tcl | |
| +++ src/makemake.tcl | |
| @@ -110,10 +110,11 @@ | |
| 110 | sitemap |
| 111 | skins |
| 112 | sqlcmd |
| 113 | stash |
| 114 | stat |
| 115 | style |
| 116 | sync |
| 117 | tag |
| 118 | tar |
| 119 | th_main |
| @@ -142,10 +143,11 @@ | |
| 142 | |
| 143 | # Additional resource files that get built into the executable. |
| 144 | # |
| 145 | set extra_files { |
| 146 | diff.tcl |
| 147 | ../skins/*/*.txt |
| 148 | } |
| 149 | |
| 150 | # Options used to compile the included SQLite library. |
| 151 | # |
| @@ -372,11 +374,11 @@ | |
| 372 | set mhargs [string map [list <<<NEXT_LINE>>> \\\n\t] $mhargs] |
| 373 | writeln "\$(OBJDIR)/page_index.h: \$(TRANS_SRC) \$(OBJDIR)/mkindex" |
| 374 | writeln "\t\$(OBJDIR)/mkindex \$(TRANS_SRC) >\$@\n" |
| 375 | |
| 376 | writeln "\$(OBJDIR)/builtin_data.h: \$(OBJDIR)/mkbuiltin \$(EXTRA_FILES)" |
| 377 | writeln "\t\$(OBJDIR)/mkbuiltin \$(EXTRA_FILES) >\$@\n" |
| 378 | |
| 379 | writeln "\$(OBJDIR)/headers:\t\$(OBJDIR)/page_index.h \$(OBJDIR)/builtin_data.h \$(OBJDIR)/makeheaders \$(OBJDIR)/VERSION.h" |
| 380 | writeln "\t\$(OBJDIR)/makeheaders $mhargs" |
| 381 | writeln "\ttouch \$(OBJDIR)/headers" |
| 382 | writeln "\$(OBJDIR)/headers: Makefile" |
| @@ -1025,11 +1027,11 @@ | |
| 1025 | append mhargs " \\\n\t\t\$(OBJDIR)/VERSION.h" |
| 1026 | writeln "\$(OBJDIR)/page_index.h: \$(TRANS_SRC) \$(MKINDEX)" |
| 1027 | writeln "\t\$(MKINDEX) \$(TRANS_SRC) >\$@\n" |
| 1028 | |
| 1029 | writeln "\$(OBJDIR)/builtin_data.h:\t\$(MKBUILTIN) \$(EXTRA_FILES)" |
| 1030 | writeln "\t\$(MKBUILTIN) \$(EXTRA_FILES) >\$@\n" |
| 1031 | |
| 1032 | writeln "\$(OBJDIR)/headers:\t\$(OBJDIR)/page_index.h \$(OBJDIR)/builtin_data.h \$(MAKEHEADERS) \$(OBJDIR)/VERSION.h" |
| 1033 | writeln "\t\$(MAKEHEADERS) $mhargs" |
| 1034 | writeln "\techo Done >\$(OBJDIR)/headers\n" |
| 1035 | writeln "\$(OBJDIR)/headers: Makefile\n" |
| @@ -1204,11 +1206,11 @@ | |
| 1204 | |
| 1205 | page_index.h: mkindex$E $(SRC) |
| 1206 | +$** > $@ |
| 1207 | |
| 1208 | builtin_data.h: mkbuiltin$E $(EXTRA_FILES) |
| 1209 | +$** > $@ |
| 1210 | |
| 1211 | clean: |
| 1212 | -del $(OBJDIR)\*.obj |
| 1213 | -del *.obj *_.c *.h *.map |
| 1214 | |
| @@ -1598,11 +1600,11 @@ | |
| 1598 | |
| 1599 | page_index.h: mkindex$E $(SRC) |
| 1600 | $** > $@ |
| 1601 | |
| 1602 | builtin_data.h: mkbuiltin$E $(EXTRA_FILES) |
| 1603 | $** > $@ |
| 1604 | |
| 1605 | clean: |
| 1606 | -del $(OX)\*.obj |
| 1607 | -del *.obj |
| 1608 | -del *_.c |
| @@ -1830,11 +1832,11 @@ | |
| 1830 | # generate the index source, containing all web references,.. |
| 1831 | page_index.h: $(TRANSLATEDSRC) mkindex.exe |
| 1832 | mkindex.exe $(TRANSLATEDSRC) >$@ |
| 1833 | |
| 1834 | builtin_data.h: $(EXTRA_FILES) mkbuiltin.exe |
| 1835 | mkbuiltin.exe $(EXTRA_FILES) >$@ |
| 1836 | |
| 1837 | # extracting version info from manifest |
| 1838 | VERSION.h: version.exe ..\manifest.uuid ..\manifest ..\VERSION |
| 1839 | version.exe ..\manifest.uuid ..\manifest ..\VERSION >$@ |
| 1840 | |
| 1841 |
| --- src/makemake.tcl | |
| +++ src/makemake.tcl | |
| @@ -110,10 +110,11 @@ | |
| 110 | sitemap |
| 111 | skins |
| 112 | sqlcmd |
| 113 | stash |
| 114 | stat |
| 115 | statrep |
| 116 | style |
| 117 | sync |
| 118 | tag |
| 119 | tar |
| 120 | th_main |
| @@ -142,10 +143,11 @@ | |
| 143 | |
| 144 | # Additional resource files that get built into the executable. |
| 145 | # |
| 146 | set extra_files { |
| 147 | diff.tcl |
| 148 | markdown.md |
| 149 | ../skins/*/*.txt |
| 150 | } |
| 151 | |
| 152 | # Options used to compile the included SQLite library. |
| 153 | # |
| @@ -372,11 +374,11 @@ | |
| 374 | set mhargs [string map [list <<<NEXT_LINE>>> \\\n\t] $mhargs] |
| 375 | writeln "\$(OBJDIR)/page_index.h: \$(TRANS_SRC) \$(OBJDIR)/mkindex" |
| 376 | writeln "\t\$(OBJDIR)/mkindex \$(TRANS_SRC) >\$@\n" |
| 377 | |
| 378 | writeln "\$(OBJDIR)/builtin_data.h: \$(OBJDIR)/mkbuiltin \$(EXTRA_FILES)" |
| 379 | writeln "\t\$(OBJDIR)/mkbuiltin --prefix \$(SRCDIR)/ \$(EXTRA_FILES) >\$@\n" |
| 380 | |
| 381 | writeln "\$(OBJDIR)/headers:\t\$(OBJDIR)/page_index.h \$(OBJDIR)/builtin_data.h \$(OBJDIR)/makeheaders \$(OBJDIR)/VERSION.h" |
| 382 | writeln "\t\$(OBJDIR)/makeheaders $mhargs" |
| 383 | writeln "\ttouch \$(OBJDIR)/headers" |
| 384 | writeln "\$(OBJDIR)/headers: Makefile" |
| @@ -1025,11 +1027,11 @@ | |
| 1027 | append mhargs " \\\n\t\t\$(OBJDIR)/VERSION.h" |
| 1028 | writeln "\$(OBJDIR)/page_index.h: \$(TRANS_SRC) \$(MKINDEX)" |
| 1029 | writeln "\t\$(MKINDEX) \$(TRANS_SRC) >\$@\n" |
| 1030 | |
| 1031 | writeln "\$(OBJDIR)/builtin_data.h:\t\$(MKBUILTIN) \$(EXTRA_FILES)" |
| 1032 | writeln "\t\$(MKBUILTIN) --prefix \$(SRCDIR)/ \$(EXTRA_FILES) >\$@\n" |
| 1033 | |
| 1034 | writeln "\$(OBJDIR)/headers:\t\$(OBJDIR)/page_index.h \$(OBJDIR)/builtin_data.h \$(MAKEHEADERS) \$(OBJDIR)/VERSION.h" |
| 1035 | writeln "\t\$(MAKEHEADERS) $mhargs" |
| 1036 | writeln "\techo Done >\$(OBJDIR)/headers\n" |
| 1037 | writeln "\$(OBJDIR)/headers: Makefile\n" |
| @@ -1204,11 +1206,11 @@ | |
| 1206 | |
| 1207 | page_index.h: mkindex$E $(SRC) |
| 1208 | +$** > $@ |
| 1209 | |
| 1210 | builtin_data.h: mkbuiltin$E $(EXTRA_FILES) |
| 1211 | mkbuiltin$E --prefix $(SRCDIR)/ $(EXTRA_FILES) > $@ |
| 1212 | |
| 1213 | clean: |
| 1214 | -del $(OBJDIR)\*.obj |
| 1215 | -del *.obj *_.c *.h *.map |
| 1216 | |
| @@ -1598,11 +1600,11 @@ | |
| 1600 | |
| 1601 | page_index.h: mkindex$E $(SRC) |
| 1602 | $** > $@ |
| 1603 | |
| 1604 | builtin_data.h: mkbuiltin$E $(EXTRA_FILES) |
| 1605 | mkbuiltin$E --prefix $(SRCDIR)/ $(EXTRA_FILES) > $@ |
| 1606 | |
| 1607 | clean: |
| 1608 | -del $(OX)\*.obj |
| 1609 | -del *.obj |
| 1610 | -del *_.c |
| @@ -1830,11 +1832,11 @@ | |
| 1832 | # generate the index source, containing all web references,.. |
| 1833 | page_index.h: $(TRANSLATEDSRC) mkindex.exe |
| 1834 | mkindex.exe $(TRANSLATEDSRC) >$@ |
| 1835 | |
| 1836 | builtin_data.h: $(EXTRA_FILES) mkbuiltin.exe |
| 1837 | mkbuiltin.exe --prefix $(SRCDIR)/ $(EXTRA_FILES) >$@ |
| 1838 | |
| 1839 | # extracting version info from manifest |
| 1840 | VERSION.h: version.exe ..\manifest.uuid ..\manifest ..\VERSION |
| 1841 | version.exe ..\manifest.uuid ..\manifest ..\VERSION >$@ |
| 1842 | |
| 1843 |
+64
-53
| --- src/manifest.c | ||
| +++ src/manifest.c | ||
| @@ -1185,16 +1185,18 @@ | ||
| 1185 | 1185 | /* |
| 1186 | 1186 | ** Add a single entry to the mlink table. Also add the filename to |
| 1187 | 1187 | ** the filename table if it is not there already. |
| 1188 | 1188 | */ |
| 1189 | 1189 | static void add_one_mlink( |
| 1190 | + int pmid, /* The parent manifest */ | |
| 1191 | + const char *zFromUuid, /* UUID for content in parent */ | |
| 1190 | 1192 | int mid, /* The record ID of the manifest */ |
| 1191 | - const char *zFromUuid, /* UUID for the mlink.pid. "" to add file */ | |
| 1192 | - const char *zToUuid, /* UUID for the mlink.fid. "" to delete */ | |
| 1193 | + const char *zToUuid, /* UUID for content in child */ | |
| 1193 | 1194 | const char *zFilename, /* Filename */ |
| 1194 | 1195 | const char *zPrior, /* Previous filename. NULL if unchanged */ |
| 1195 | 1196 | int isPublic, /* True if mid is not a private manifest */ |
| 1197 | + int isPrimary, /* pmid is the primary parent of mid */ | |
| 1196 | 1198 | int mperm /* 1: exec, 2: symlink */ |
| 1197 | 1199 | ){ |
| 1198 | 1200 | int fnid, pfnid, pid, fid; |
| 1199 | 1201 | static Stmt s1; |
| 1200 | 1202 | |
| @@ -1214,19 +1216,21 @@ | ||
| 1214 | 1216 | }else{ |
| 1215 | 1217 | fid = uuid_to_rid(zToUuid, 1); |
| 1216 | 1218 | if( isPublic ) content_make_public(fid); |
| 1217 | 1219 | } |
| 1218 | 1220 | db_static_prepare(&s1, |
| 1219 | - "INSERT INTO mlink(mid,pid,fid,fnid,pfnid,mperm)" | |
| 1220 | - "VALUES(:m,:p,:f,:n,:pfn,:mp)" | |
| 1221 | + "INSERT INTO mlink(mid,fid,pmid,pid,fnid,pfnid,mperm,isaux)" | |
| 1222 | + "VALUES(:m,:f,:pm,:p,:n,:pfn,:mp,:isaux)" | |
| 1221 | 1223 | ); |
| 1222 | 1224 | db_bind_int(&s1, ":m", mid); |
| 1223 | - db_bind_int(&s1, ":p", pid); | |
| 1224 | 1225 | db_bind_int(&s1, ":f", fid); |
| 1226 | + db_bind_int(&s1, ":pm", pmid); | |
| 1227 | + db_bind_int(&s1, ":p", pid); | |
| 1225 | 1228 | db_bind_int(&s1, ":n", fnid); |
| 1226 | 1229 | db_bind_int(&s1, ":pfn", pfnid); |
| 1227 | 1230 | db_bind_int(&s1, ":mp", mperm); |
| 1231 | + db_bind_int(&s1, ":isaux", isPrimary==0); | |
| 1228 | 1232 | db_exec(&s1); |
| 1229 | 1233 | if( pid && fid ){ |
| 1230 | 1234 | content_deltify(pid, fid, 0); |
| 1231 | 1235 | } |
| 1232 | 1236 | } |
| @@ -1340,24 +1344,29 @@ | ||
| 1340 | 1344 | ** |
| 1341 | 1345 | ** Deleted files have mlink.fid=0. |
| 1342 | 1346 | ** Added files have mlink.pid=0. |
| 1343 | 1347 | ** Edited files have both mlink.pid!=0 and mlink.fid!=0 |
| 1344 | 1348 | */ |
| 1345 | -static void add_mlink(int pid, Manifest *pParent, int cid, Manifest *pChild){ | |
| 1349 | +static void add_mlink( | |
| 1350 | + int pmid, Manifest *pParent, /* Parent check-in */ | |
| 1351 | + int mid, Manifest *pChild, /* The child check-in */ | |
| 1352 | + int isPrim /* TRUE if pmid is the primary parent of mid */ | |
| 1353 | +){ | |
| 1346 | 1354 | Blob otherContent; |
| 1347 | 1355 | int otherRid; |
| 1348 | 1356 | int i, rc; |
| 1349 | 1357 | ManifestFile *pChildFile, *pParentFile; |
| 1350 | 1358 | Manifest **ppOther; |
| 1351 | 1359 | static Stmt eq; |
| 1352 | 1360 | int isPublic; /* True if pChild is non-private */ |
| 1353 | 1361 | |
| 1354 | - /* If mlink table entires are already set for cid, then abort early | |
| 1355 | - ** doing no work. | |
| 1362 | + /* If mlink table entires are already exist for the pmid-to-mid transition, | |
| 1363 | + ** then abort early doing no work. | |
| 1356 | 1364 | */ |
| 1357 | - db_static_prepare(&eq, "SELECT 1 FROM mlink WHERE mid=:mid"); | |
| 1358 | - db_bind_int(&eq, ":mid", cid); | |
| 1365 | + db_static_prepare(&eq, "SELECT 1 FROM mlink WHERE mid=:mid AND pmid=:pmid"); | |
| 1366 | + db_bind_int(&eq, ":mid", mid); | |
| 1367 | + db_bind_int(&eq, ":pmid", pmid); | |
| 1359 | 1368 | rc = db_step(&eq); |
| 1360 | 1369 | db_reset(&eq); |
| 1361 | 1370 | if( rc==SQLITE_ROW ) return; |
| 1362 | 1371 | |
| 1363 | 1372 | /* Compute the value of the missing pParent or pChild parameter. |
| @@ -1364,14 +1373,14 @@ | ||
| 1364 | 1373 | ** Fetch the baseline checkins for both. |
| 1365 | 1374 | */ |
| 1366 | 1375 | assert( pParent==0 || pChild==0 ); |
| 1367 | 1376 | if( pParent==0 ){ |
| 1368 | 1377 | ppOther = &pParent; |
| 1369 | - otherRid = pid; | |
| 1378 | + otherRid = pmid; | |
| 1370 | 1379 | }else{ |
| 1371 | 1380 | ppOther = &pChild; |
| 1372 | - otherRid = cid; | |
| 1381 | + otherRid = mid; | |
| 1373 | 1382 | } |
| 1374 | 1383 | if( (*ppOther = manifest_cache_find(otherRid))==0 ){ |
| 1375 | 1384 | content_get(otherRid, &otherContent); |
| 1376 | 1385 | if( blob_size(&otherContent)==0 ) return; |
| 1377 | 1386 | *ppOther = manifest_parse(&otherContent, otherRid, 0); |
| @@ -1379,20 +1388,20 @@ | ||
| 1379 | 1388 | } |
| 1380 | 1389 | if( fetch_baseline(pParent, 0) || fetch_baseline(pChild, 0) ){ |
| 1381 | 1390 | manifest_destroy(*ppOther); |
| 1382 | 1391 | return; |
| 1383 | 1392 | } |
| 1384 | - isPublic = !content_is_private(cid); | |
| 1393 | + isPublic = !content_is_private(mid); | |
| 1385 | 1394 | |
| 1386 | 1395 | /* Try to make the parent manifest a delta from the child, if that |
| 1387 | 1396 | ** is an appropriate thing to do. For a new baseline, make the |
| 1388 | 1397 | ** previous baseline a delta from the current baseline. |
| 1389 | 1398 | */ |
| 1390 | 1399 | if( (pParent->zBaseline==0)==(pChild->zBaseline==0) ){ |
| 1391 | - content_deltify(pid, cid, 0); | |
| 1400 | + content_deltify(pmid, mid, 0); | |
| 1392 | 1401 | }else if( pChild->zBaseline==0 && pParent->zBaseline!=0 ){ |
| 1393 | - content_deltify(pParent->pBaseline->rid, cid, 0); | |
| 1402 | + content_deltify(pParent->pBaseline->rid, mid, 0); | |
| 1394 | 1403 | } |
| 1395 | 1404 | |
| 1396 | 1405 | /* Remember all children less than a few seconds younger than their parent, |
| 1397 | 1406 | ** as we might want to fudge the times for those children. |
| 1398 | 1407 | */ |
| @@ -1412,31 +1421,32 @@ | ||
| 1412 | 1421 | int mperm = manifest_file_mperm(pChildFile); |
| 1413 | 1422 | if( pChildFile->zPrior ){ |
| 1414 | 1423 | pParentFile = manifest_file_seek(pParent, pChildFile->zPrior, 0); |
| 1415 | 1424 | if( pParentFile ){ |
| 1416 | 1425 | /* File with name change */ |
| 1417 | - add_one_mlink(cid, pParentFile->zUuid, pChildFile->zUuid, | |
| 1418 | - pChildFile->zName, pChildFile->zPrior, isPublic, mperm); | |
| 1426 | + add_one_mlink(pmid, pParentFile->zUuid, mid, pChildFile->zUuid, | |
| 1427 | + pChildFile->zName, pChildFile->zPrior, | |
| 1428 | + isPublic, isPrim, mperm); | |
| 1419 | 1429 | }else{ |
| 1420 | 1430 | /* File name changed, but the old name is not found in the parent! |
| 1421 | 1431 | ** Treat this like a new file. */ |
| 1422 | - add_one_mlink(cid, 0, pChildFile->zUuid, pChildFile->zName, 0, | |
| 1423 | - isPublic, mperm); | |
| 1432 | + add_one_mlink(pmid, 0, mid, pChildFile->zUuid, pChildFile->zName, 0, | |
| 1433 | + isPublic, isPrim, mperm); | |
| 1424 | 1434 | } |
| 1425 | 1435 | }else{ |
| 1426 | 1436 | pParentFile = manifest_file_seek(pParent, pChildFile->zName, 0); |
| 1427 | 1437 | if( pParentFile==0 ){ |
| 1428 | 1438 | if( pChildFile->zUuid ){ |
| 1429 | 1439 | /* A new file */ |
| 1430 | - add_one_mlink(cid, 0, pChildFile->zUuid, pChildFile->zName, 0, | |
| 1431 | - isPublic, mperm); | |
| 1440 | + add_one_mlink(pmid, 0, mid, pChildFile->zUuid, pChildFile->zName, 0, | |
| 1441 | + isPublic, isPrim, mperm); | |
| 1432 | 1442 | } |
| 1433 | 1443 | }else if( fossil_strcmp(pChildFile->zUuid, pParentFile->zUuid)!=0 |
| 1434 | 1444 | || manifest_file_mperm(pParentFile)!=mperm ){ |
| 1435 | 1445 | /* Changes in file content or permissions */ |
| 1436 | - add_one_mlink(cid, pParentFile->zUuid, pChildFile->zUuid, | |
| 1437 | - pChildFile->zName, 0, isPublic, mperm); | |
| 1446 | + add_one_mlink(pmid, pParentFile->zUuid, mid, pChildFile->zUuid, | |
| 1447 | + pChildFile->zName, 0, isPublic, isPrim, mperm); | |
| 1438 | 1448 | } |
| 1439 | 1449 | } |
| 1440 | 1450 | } |
| 1441 | 1451 | if( pParent->zBaseline && pChild->zBaseline ){ |
| 1442 | 1452 | /* Both parent and child are delta manifests. Look for files that |
| @@ -1448,22 +1458,22 @@ | ||
| 1448 | 1458 | pChildFile = manifest_file_seek_base(pChild, pParentFile->zName, 0); |
| 1449 | 1459 | if( pChildFile==0 ){ |
| 1450 | 1460 | /* The child file reverts to baseline. Show this as a change */ |
| 1451 | 1461 | pChildFile = manifest_file_seek(pChild, pParentFile->zName, 0); |
| 1452 | 1462 | if( pChildFile ){ |
| 1453 | - add_one_mlink(cid, pParentFile->zUuid, pChildFile->zUuid, | |
| 1454 | - pChildFile->zName, 0, isPublic, | |
| 1463 | + add_one_mlink(pmid, pParentFile->zUuid, mid, pChildFile->zUuid, | |
| 1464 | + pChildFile->zName, 0, isPublic, isPrim, | |
| 1455 | 1465 | manifest_file_mperm(pChildFile)); |
| 1456 | 1466 | } |
| 1457 | 1467 | } |
| 1458 | 1468 | }else{ |
| 1459 | 1469 | pChildFile = manifest_file_seek(pChild, pParentFile->zName, 0); |
| 1460 | 1470 | if( pChildFile ){ |
| 1461 | 1471 | /* File resurrected in the child after having been deleted in |
| 1462 | 1472 | ** the parent. Show this as an added file. */ |
| 1463 | - add_one_mlink(cid, 0, pChildFile->zUuid, pChildFile->zName, 0, | |
| 1464 | - isPublic, manifest_file_mperm(pChildFile)); | |
| 1473 | + add_one_mlink(pmid, 0, mid, pChildFile->zUuid, pChildFile->zName, 0, | |
| 1474 | + isPublic, isPrim, manifest_file_mperm(pChildFile)); | |
| 1465 | 1475 | } |
| 1466 | 1476 | } |
| 1467 | 1477 | } |
| 1468 | 1478 | }else if( pChild->zBaseline==0 ){ |
| 1469 | 1479 | /* pChild is a baseline. Look for files that are present in pParent |
| @@ -1470,12 +1480,12 @@ | ||
| 1470 | 1480 | ** but are missing from pChild and mark them as having been deleted. */ |
| 1471 | 1481 | manifest_file_rewind(pParent); |
| 1472 | 1482 | while( (pParentFile = manifest_file_next(pParent,0))!=0 ){ |
| 1473 | 1483 | pChildFile = manifest_file_seek(pChild, pParentFile->zName, 0); |
| 1474 | 1484 | if( pChildFile==0 && pParentFile->zUuid!=0 ){ |
| 1475 | - add_one_mlink(cid, pParentFile->zUuid, 0, pParentFile->zName, 0, | |
| 1476 | - isPublic, 0); | |
| 1485 | + add_one_mlink(pmid, pParentFile->zUuid, mid, 0, pParentFile->zName, 0, | |
| 1486 | + isPublic, isPrim, 0); | |
| 1477 | 1487 | } |
| 1478 | 1488 | } |
| 1479 | 1489 | } |
| 1480 | 1490 | manifest_cache_insert(*ppOther); |
| 1481 | 1491 | } |
| @@ -1779,45 +1789,46 @@ | ||
| 1779 | 1789 | sqlite3_snprintf(sizeof(zBaseId), zBaseId, "%d", |
| 1780 | 1790 | uuid_to_rid(p->zBaseline,1)); |
| 1781 | 1791 | }else{ |
| 1782 | 1792 | sqlite3_snprintf(sizeof(zBaseId), zBaseId, "NULL"); |
| 1783 | 1793 | } |
| 1784 | - (void)db_schema_is_outofdate(); /* Make sure g.zAuxSchema is initialized */ | |
| 1785 | 1794 | for(i=0; i<p->nParent; i++){ |
| 1786 | 1795 | int pid = uuid_to_rid(p->azParent[i], 1); |
| 1787 | - if( strcmp(g.zAuxSchema,"2014-11-24 20:35")>=0 ){ | |
| 1788 | - /* Support for PLINK.BASEID added on 2014-11-24 */ | |
| 1789 | - db_multi_exec( | |
| 1790 | - "INSERT OR IGNORE INTO plink(pid, cid, isprim, mtime, baseid)" | |
| 1791 | - "VALUES(%d, %d, %d, %.17g, %s)", | |
| 1792 | - pid, rid, i==0, p->rDate, zBaseId/*safe-for-%s*/); | |
| 1793 | - }else{ | |
| 1794 | - /* Continue to work with older schema to avoid an unnecessary | |
| 1795 | - ** rebuild */ | |
| 1796 | - db_multi_exec( | |
| 1797 | - "INSERT OR IGNORE INTO plink(pid, cid, isprim, mtime)" | |
| 1798 | - "VALUES(%d, %d, %d, %.17g)", | |
| 1799 | - pid, rid, i==0, p->rDate); | |
| 1800 | - } | |
| 1801 | - if( i==0 ){ | |
| 1802 | - add_mlink(pid, 0, rid, p); | |
| 1803 | - parentid = pid; | |
| 1804 | - } | |
| 1805 | - } | |
| 1806 | - db_prepare(&q, "SELECT cid FROM plink WHERE pid=%d AND isprim", rid); | |
| 1796 | + db_multi_exec( | |
| 1797 | + "INSERT OR IGNORE INTO plink(pid, cid, isprim, mtime, baseid)" | |
| 1798 | + "VALUES(%d, %d, %d, %.17g, %s)", | |
| 1799 | + pid, rid, i==0, p->rDate, zBaseId/*safe-for-%s*/); | |
| 1800 | + add_mlink(pid, 0, rid, p, i==0); | |
| 1801 | + if( i==0 ) parentid = pid; | |
| 1802 | + } | |
| 1803 | + if( p->nParent>1 ){ | |
| 1804 | + /* Remove incorrect MLINK create-file entries that arise when a | |
| 1805 | + ** file is added by merge. */ | |
| 1806 | + db_multi_exec( | |
| 1807 | + "DELETE FROM mlink" | |
| 1808 | + " WHERE mid=%d" | |
| 1809 | + " AND pid=0" | |
| 1810 | + " AND fnid IN " | |
| 1811 | + " (SELECT fnid FROM mlink WHERE mid=%d GROUP BY fnid" | |
| 1812 | + " HAVING count(*)<%d)", | |
| 1813 | + rid, rid, p->nParent | |
| 1814 | + ); | |
| 1815 | + } | |
| 1816 | + db_prepare(&q, "SELECT cid, isprim FROM plink WHERE pid=%d", rid); | |
| 1807 | 1817 | while( db_step(&q)==SQLITE_ROW ){ |
| 1808 | 1818 | int cid = db_column_int(&q, 0); |
| 1809 | - add_mlink(rid, p, cid, 0); | |
| 1819 | + int isprim = db_column_int(&q, 1); | |
| 1820 | + add_mlink(rid, p, cid, 0, isprim); | |
| 1810 | 1821 | } |
| 1811 | 1822 | db_finalize(&q); |
| 1812 | 1823 | if( p->nParent==0 ){ |
| 1813 | 1824 | /* For root files (files without parents) add mlink entries |
| 1814 | 1825 | ** showing all content as new. */ |
| 1815 | 1826 | int isPublic = !content_is_private(rid); |
| 1816 | 1827 | for(i=0; i<p->nFile; i++){ |
| 1817 | - add_one_mlink(rid, 0, p->aFile[i].zUuid, p->aFile[i].zName, 0, | |
| 1818 | - isPublic, manifest_file_mperm(&p->aFile[i])); | |
| 1828 | + add_one_mlink(0, 0, rid, p->aFile[i].zUuid, p->aFile[i].zName, 0, | |
| 1829 | + isPublic, 1, manifest_file_mperm(&p->aFile[i])); | |
| 1819 | 1830 | } |
| 1820 | 1831 | } |
| 1821 | 1832 | db_multi_exec( |
| 1822 | 1833 | "REPLACE INTO event(type,mtime,objid,user,comment," |
| 1823 | 1834 | "bgcolor,euser,ecomment,omtime)" |
| 1824 | 1835 | |
| 1825 | 1836 | ADDED src/markdown.md |
| --- src/manifest.c | |
| +++ src/manifest.c | |
| @@ -1185,16 +1185,18 @@ | |
| 1185 | /* |
| 1186 | ** Add a single entry to the mlink table. Also add the filename to |
| 1187 | ** the filename table if it is not there already. |
| 1188 | */ |
| 1189 | static void add_one_mlink( |
| 1190 | int mid, /* The record ID of the manifest */ |
| 1191 | const char *zFromUuid, /* UUID for the mlink.pid. "" to add file */ |
| 1192 | const char *zToUuid, /* UUID for the mlink.fid. "" to delete */ |
| 1193 | const char *zFilename, /* Filename */ |
| 1194 | const char *zPrior, /* Previous filename. NULL if unchanged */ |
| 1195 | int isPublic, /* True if mid is not a private manifest */ |
| 1196 | int mperm /* 1: exec, 2: symlink */ |
| 1197 | ){ |
| 1198 | int fnid, pfnid, pid, fid; |
| 1199 | static Stmt s1; |
| 1200 | |
| @@ -1214,19 +1216,21 @@ | |
| 1214 | }else{ |
| 1215 | fid = uuid_to_rid(zToUuid, 1); |
| 1216 | if( isPublic ) content_make_public(fid); |
| 1217 | } |
| 1218 | db_static_prepare(&s1, |
| 1219 | "INSERT INTO mlink(mid,pid,fid,fnid,pfnid,mperm)" |
| 1220 | "VALUES(:m,:p,:f,:n,:pfn,:mp)" |
| 1221 | ); |
| 1222 | db_bind_int(&s1, ":m", mid); |
| 1223 | db_bind_int(&s1, ":p", pid); |
| 1224 | db_bind_int(&s1, ":f", fid); |
| 1225 | db_bind_int(&s1, ":n", fnid); |
| 1226 | db_bind_int(&s1, ":pfn", pfnid); |
| 1227 | db_bind_int(&s1, ":mp", mperm); |
| 1228 | db_exec(&s1); |
| 1229 | if( pid && fid ){ |
| 1230 | content_deltify(pid, fid, 0); |
| 1231 | } |
| 1232 | } |
| @@ -1340,24 +1344,29 @@ | |
| 1340 | ** |
| 1341 | ** Deleted files have mlink.fid=0. |
| 1342 | ** Added files have mlink.pid=0. |
| 1343 | ** Edited files have both mlink.pid!=0 and mlink.fid!=0 |
| 1344 | */ |
| 1345 | static void add_mlink(int pid, Manifest *pParent, int cid, Manifest *pChild){ |
| 1346 | Blob otherContent; |
| 1347 | int otherRid; |
| 1348 | int i, rc; |
| 1349 | ManifestFile *pChildFile, *pParentFile; |
| 1350 | Manifest **ppOther; |
| 1351 | static Stmt eq; |
| 1352 | int isPublic; /* True if pChild is non-private */ |
| 1353 | |
| 1354 | /* If mlink table entires are already set for cid, then abort early |
| 1355 | ** doing no work. |
| 1356 | */ |
| 1357 | db_static_prepare(&eq, "SELECT 1 FROM mlink WHERE mid=:mid"); |
| 1358 | db_bind_int(&eq, ":mid", cid); |
| 1359 | rc = db_step(&eq); |
| 1360 | db_reset(&eq); |
| 1361 | if( rc==SQLITE_ROW ) return; |
| 1362 | |
| 1363 | /* Compute the value of the missing pParent or pChild parameter. |
| @@ -1364,14 +1373,14 @@ | |
| 1364 | ** Fetch the baseline checkins for both. |
| 1365 | */ |
| 1366 | assert( pParent==0 || pChild==0 ); |
| 1367 | if( pParent==0 ){ |
| 1368 | ppOther = &pParent; |
| 1369 | otherRid = pid; |
| 1370 | }else{ |
| 1371 | ppOther = &pChild; |
| 1372 | otherRid = cid; |
| 1373 | } |
| 1374 | if( (*ppOther = manifest_cache_find(otherRid))==0 ){ |
| 1375 | content_get(otherRid, &otherContent); |
| 1376 | if( blob_size(&otherContent)==0 ) return; |
| 1377 | *ppOther = manifest_parse(&otherContent, otherRid, 0); |
| @@ -1379,20 +1388,20 @@ | |
| 1379 | } |
| 1380 | if( fetch_baseline(pParent, 0) || fetch_baseline(pChild, 0) ){ |
| 1381 | manifest_destroy(*ppOther); |
| 1382 | return; |
| 1383 | } |
| 1384 | isPublic = !content_is_private(cid); |
| 1385 | |
| 1386 | /* Try to make the parent manifest a delta from the child, if that |
| 1387 | ** is an appropriate thing to do. For a new baseline, make the |
| 1388 | ** previous baseline a delta from the current baseline. |
| 1389 | */ |
| 1390 | if( (pParent->zBaseline==0)==(pChild->zBaseline==0) ){ |
| 1391 | content_deltify(pid, cid, 0); |
| 1392 | }else if( pChild->zBaseline==0 && pParent->zBaseline!=0 ){ |
| 1393 | content_deltify(pParent->pBaseline->rid, cid, 0); |
| 1394 | } |
| 1395 | |
| 1396 | /* Remember all children less than a few seconds younger than their parent, |
| 1397 | ** as we might want to fudge the times for those children. |
| 1398 | */ |
| @@ -1412,31 +1421,32 @@ | |
| 1412 | int mperm = manifest_file_mperm(pChildFile); |
| 1413 | if( pChildFile->zPrior ){ |
| 1414 | pParentFile = manifest_file_seek(pParent, pChildFile->zPrior, 0); |
| 1415 | if( pParentFile ){ |
| 1416 | /* File with name change */ |
| 1417 | add_one_mlink(cid, pParentFile->zUuid, pChildFile->zUuid, |
| 1418 | pChildFile->zName, pChildFile->zPrior, isPublic, mperm); |
| 1419 | }else{ |
| 1420 | /* File name changed, but the old name is not found in the parent! |
| 1421 | ** Treat this like a new file. */ |
| 1422 | add_one_mlink(cid, 0, pChildFile->zUuid, pChildFile->zName, 0, |
| 1423 | isPublic, mperm); |
| 1424 | } |
| 1425 | }else{ |
| 1426 | pParentFile = manifest_file_seek(pParent, pChildFile->zName, 0); |
| 1427 | if( pParentFile==0 ){ |
| 1428 | if( pChildFile->zUuid ){ |
| 1429 | /* A new file */ |
| 1430 | add_one_mlink(cid, 0, pChildFile->zUuid, pChildFile->zName, 0, |
| 1431 | isPublic, mperm); |
| 1432 | } |
| 1433 | }else if( fossil_strcmp(pChildFile->zUuid, pParentFile->zUuid)!=0 |
| 1434 | || manifest_file_mperm(pParentFile)!=mperm ){ |
| 1435 | /* Changes in file content or permissions */ |
| 1436 | add_one_mlink(cid, pParentFile->zUuid, pChildFile->zUuid, |
| 1437 | pChildFile->zName, 0, isPublic, mperm); |
| 1438 | } |
| 1439 | } |
| 1440 | } |
| 1441 | if( pParent->zBaseline && pChild->zBaseline ){ |
| 1442 | /* Both parent and child are delta manifests. Look for files that |
| @@ -1448,22 +1458,22 @@ | |
| 1448 | pChildFile = manifest_file_seek_base(pChild, pParentFile->zName, 0); |
| 1449 | if( pChildFile==0 ){ |
| 1450 | /* The child file reverts to baseline. Show this as a change */ |
| 1451 | pChildFile = manifest_file_seek(pChild, pParentFile->zName, 0); |
| 1452 | if( pChildFile ){ |
| 1453 | add_one_mlink(cid, pParentFile->zUuid, pChildFile->zUuid, |
| 1454 | pChildFile->zName, 0, isPublic, |
| 1455 | manifest_file_mperm(pChildFile)); |
| 1456 | } |
| 1457 | } |
| 1458 | }else{ |
| 1459 | pChildFile = manifest_file_seek(pChild, pParentFile->zName, 0); |
| 1460 | if( pChildFile ){ |
| 1461 | /* File resurrected in the child after having been deleted in |
| 1462 | ** the parent. Show this as an added file. */ |
| 1463 | add_one_mlink(cid, 0, pChildFile->zUuid, pChildFile->zName, 0, |
| 1464 | isPublic, manifest_file_mperm(pChildFile)); |
| 1465 | } |
| 1466 | } |
| 1467 | } |
| 1468 | }else if( pChild->zBaseline==0 ){ |
| 1469 | /* pChild is a baseline. Look for files that are present in pParent |
| @@ -1470,12 +1480,12 @@ | |
| 1470 | ** but are missing from pChild and mark them as having been deleted. */ |
| 1471 | manifest_file_rewind(pParent); |
| 1472 | while( (pParentFile = manifest_file_next(pParent,0))!=0 ){ |
| 1473 | pChildFile = manifest_file_seek(pChild, pParentFile->zName, 0); |
| 1474 | if( pChildFile==0 && pParentFile->zUuid!=0 ){ |
| 1475 | add_one_mlink(cid, pParentFile->zUuid, 0, pParentFile->zName, 0, |
| 1476 | isPublic, 0); |
| 1477 | } |
| 1478 | } |
| 1479 | } |
| 1480 | manifest_cache_insert(*ppOther); |
| 1481 | } |
| @@ -1779,45 +1789,46 @@ | |
| 1779 | sqlite3_snprintf(sizeof(zBaseId), zBaseId, "%d", |
| 1780 | uuid_to_rid(p->zBaseline,1)); |
| 1781 | }else{ |
| 1782 | sqlite3_snprintf(sizeof(zBaseId), zBaseId, "NULL"); |
| 1783 | } |
| 1784 | (void)db_schema_is_outofdate(); /* Make sure g.zAuxSchema is initialized */ |
| 1785 | for(i=0; i<p->nParent; i++){ |
| 1786 | int pid = uuid_to_rid(p->azParent[i], 1); |
| 1787 | if( strcmp(g.zAuxSchema,"2014-11-24 20:35")>=0 ){ |
| 1788 | /* Support for PLINK.BASEID added on 2014-11-24 */ |
| 1789 | db_multi_exec( |
| 1790 | "INSERT OR IGNORE INTO plink(pid, cid, isprim, mtime, baseid)" |
| 1791 | "VALUES(%d, %d, %d, %.17g, %s)", |
| 1792 | pid, rid, i==0, p->rDate, zBaseId/*safe-for-%s*/); |
| 1793 | }else{ |
| 1794 | /* Continue to work with older schema to avoid an unnecessary |
| 1795 | ** rebuild */ |
| 1796 | db_multi_exec( |
| 1797 | "INSERT OR IGNORE INTO plink(pid, cid, isprim, mtime)" |
| 1798 | "VALUES(%d, %d, %d, %.17g)", |
| 1799 | pid, rid, i==0, p->rDate); |
| 1800 | } |
| 1801 | if( i==0 ){ |
| 1802 | add_mlink(pid, 0, rid, p); |
| 1803 | parentid = pid; |
| 1804 | } |
| 1805 | } |
| 1806 | db_prepare(&q, "SELECT cid FROM plink WHERE pid=%d AND isprim", rid); |
| 1807 | while( db_step(&q)==SQLITE_ROW ){ |
| 1808 | int cid = db_column_int(&q, 0); |
| 1809 | add_mlink(rid, p, cid, 0); |
| 1810 | } |
| 1811 | db_finalize(&q); |
| 1812 | if( p->nParent==0 ){ |
| 1813 | /* For root files (files without parents) add mlink entries |
| 1814 | ** showing all content as new. */ |
| 1815 | int isPublic = !content_is_private(rid); |
| 1816 | for(i=0; i<p->nFile; i++){ |
| 1817 | add_one_mlink(rid, 0, p->aFile[i].zUuid, p->aFile[i].zName, 0, |
| 1818 | isPublic, manifest_file_mperm(&p->aFile[i])); |
| 1819 | } |
| 1820 | } |
| 1821 | db_multi_exec( |
| 1822 | "REPLACE INTO event(type,mtime,objid,user,comment," |
| 1823 | "bgcolor,euser,ecomment,omtime)" |
| 1824 | |
| 1825 | DDED src/markdown.md |
| --- src/manifest.c | |
| +++ src/manifest.c | |
| @@ -1185,16 +1185,18 @@ | |
| 1185 | /* |
| 1186 | ** Add a single entry to the mlink table. Also add the filename to |
| 1187 | ** the filename table if it is not there already. |
| 1188 | */ |
| 1189 | static void add_one_mlink( |
| 1190 | int pmid, /* The parent manifest */ |
| 1191 | const char *zFromUuid, /* UUID for content in parent */ |
| 1192 | int mid, /* The record ID of the manifest */ |
| 1193 | const char *zToUuid, /* UUID for content in child */ |
| 1194 | const char *zFilename, /* Filename */ |
| 1195 | const char *zPrior, /* Previous filename. NULL if unchanged */ |
| 1196 | int isPublic, /* True if mid is not a private manifest */ |
| 1197 | int isPrimary, /* pmid is the primary parent of mid */ |
| 1198 | int mperm /* 1: exec, 2: symlink */ |
| 1199 | ){ |
| 1200 | int fnid, pfnid, pid, fid; |
| 1201 | static Stmt s1; |
| 1202 | |
| @@ -1214,19 +1216,21 @@ | |
| 1216 | }else{ |
| 1217 | fid = uuid_to_rid(zToUuid, 1); |
| 1218 | if( isPublic ) content_make_public(fid); |
| 1219 | } |
| 1220 | db_static_prepare(&s1, |
| 1221 | "INSERT INTO mlink(mid,fid,pmid,pid,fnid,pfnid,mperm,isaux)" |
| 1222 | "VALUES(:m,:f,:pm,:p,:n,:pfn,:mp,:isaux)" |
| 1223 | ); |
| 1224 | db_bind_int(&s1, ":m", mid); |
| 1225 | db_bind_int(&s1, ":f", fid); |
| 1226 | db_bind_int(&s1, ":pm", pmid); |
| 1227 | db_bind_int(&s1, ":p", pid); |
| 1228 | db_bind_int(&s1, ":n", fnid); |
| 1229 | db_bind_int(&s1, ":pfn", pfnid); |
| 1230 | db_bind_int(&s1, ":mp", mperm); |
| 1231 | db_bind_int(&s1, ":isaux", isPrimary==0); |
| 1232 | db_exec(&s1); |
| 1233 | if( pid && fid ){ |
| 1234 | content_deltify(pid, fid, 0); |
| 1235 | } |
| 1236 | } |
| @@ -1340,24 +1344,29 @@ | |
| 1344 | ** |
| 1345 | ** Deleted files have mlink.fid=0. |
| 1346 | ** Added files have mlink.pid=0. |
| 1347 | ** Edited files have both mlink.pid!=0 and mlink.fid!=0 |
| 1348 | */ |
| 1349 | static void add_mlink( |
| 1350 | int pmid, Manifest *pParent, /* Parent check-in */ |
| 1351 | int mid, Manifest *pChild, /* The child check-in */ |
| 1352 | int isPrim /* TRUE if pmid is the primary parent of mid */ |
| 1353 | ){ |
| 1354 | Blob otherContent; |
| 1355 | int otherRid; |
| 1356 | int i, rc; |
| 1357 | ManifestFile *pChildFile, *pParentFile; |
| 1358 | Manifest **ppOther; |
| 1359 | static Stmt eq; |
| 1360 | int isPublic; /* True if pChild is non-private */ |
| 1361 | |
| 1362 | /* If mlink table entires are already exist for the pmid-to-mid transition, |
| 1363 | ** then abort early doing no work. |
| 1364 | */ |
| 1365 | db_static_prepare(&eq, "SELECT 1 FROM mlink WHERE mid=:mid AND pmid=:pmid"); |
| 1366 | db_bind_int(&eq, ":mid", mid); |
| 1367 | db_bind_int(&eq, ":pmid", pmid); |
| 1368 | rc = db_step(&eq); |
| 1369 | db_reset(&eq); |
| 1370 | if( rc==SQLITE_ROW ) return; |
| 1371 | |
| 1372 | /* Compute the value of the missing pParent or pChild parameter. |
| @@ -1364,14 +1373,14 @@ | |
| 1373 | ** Fetch the baseline checkins for both. |
| 1374 | */ |
| 1375 | assert( pParent==0 || pChild==0 ); |
| 1376 | if( pParent==0 ){ |
| 1377 | ppOther = &pParent; |
| 1378 | otherRid = pmid; |
| 1379 | }else{ |
| 1380 | ppOther = &pChild; |
| 1381 | otherRid = mid; |
| 1382 | } |
| 1383 | if( (*ppOther = manifest_cache_find(otherRid))==0 ){ |
| 1384 | content_get(otherRid, &otherContent); |
| 1385 | if( blob_size(&otherContent)==0 ) return; |
| 1386 | *ppOther = manifest_parse(&otherContent, otherRid, 0); |
| @@ -1379,20 +1388,20 @@ | |
| 1388 | } |
| 1389 | if( fetch_baseline(pParent, 0) || fetch_baseline(pChild, 0) ){ |
| 1390 | manifest_destroy(*ppOther); |
| 1391 | return; |
| 1392 | } |
| 1393 | isPublic = !content_is_private(mid); |
| 1394 | |
| 1395 | /* Try to make the parent manifest a delta from the child, if that |
| 1396 | ** is an appropriate thing to do. For a new baseline, make the |
| 1397 | ** previous baseline a delta from the current baseline. |
| 1398 | */ |
| 1399 | if( (pParent->zBaseline==0)==(pChild->zBaseline==0) ){ |
| 1400 | content_deltify(pmid, mid, 0); |
| 1401 | }else if( pChild->zBaseline==0 && pParent->zBaseline!=0 ){ |
| 1402 | content_deltify(pParent->pBaseline->rid, mid, 0); |
| 1403 | } |
| 1404 | |
| 1405 | /* Remember all children less than a few seconds younger than their parent, |
| 1406 | ** as we might want to fudge the times for those children. |
| 1407 | */ |
| @@ -1412,31 +1421,32 @@ | |
| 1421 | int mperm = manifest_file_mperm(pChildFile); |
| 1422 | if( pChildFile->zPrior ){ |
| 1423 | pParentFile = manifest_file_seek(pParent, pChildFile->zPrior, 0); |
| 1424 | if( pParentFile ){ |
| 1425 | /* File with name change */ |
| 1426 | add_one_mlink(pmid, pParentFile->zUuid, mid, pChildFile->zUuid, |
| 1427 | pChildFile->zName, pChildFile->zPrior, |
| 1428 | isPublic, isPrim, mperm); |
| 1429 | }else{ |
| 1430 | /* File name changed, but the old name is not found in the parent! |
| 1431 | ** Treat this like a new file. */ |
| 1432 | add_one_mlink(pmid, 0, mid, pChildFile->zUuid, pChildFile->zName, 0, |
| 1433 | isPublic, isPrim, mperm); |
| 1434 | } |
| 1435 | }else{ |
| 1436 | pParentFile = manifest_file_seek(pParent, pChildFile->zName, 0); |
| 1437 | if( pParentFile==0 ){ |
| 1438 | if( pChildFile->zUuid ){ |
| 1439 | /* A new file */ |
| 1440 | add_one_mlink(pmid, 0, mid, pChildFile->zUuid, pChildFile->zName, 0, |
| 1441 | isPublic, isPrim, mperm); |
| 1442 | } |
| 1443 | }else if( fossil_strcmp(pChildFile->zUuid, pParentFile->zUuid)!=0 |
| 1444 | || manifest_file_mperm(pParentFile)!=mperm ){ |
| 1445 | /* Changes in file content or permissions */ |
| 1446 | add_one_mlink(pmid, pParentFile->zUuid, mid, pChildFile->zUuid, |
| 1447 | pChildFile->zName, 0, isPublic, isPrim, mperm); |
| 1448 | } |
| 1449 | } |
| 1450 | } |
| 1451 | if( pParent->zBaseline && pChild->zBaseline ){ |
| 1452 | /* Both parent and child are delta manifests. Look for files that |
| @@ -1448,22 +1458,22 @@ | |
| 1458 | pChildFile = manifest_file_seek_base(pChild, pParentFile->zName, 0); |
| 1459 | if( pChildFile==0 ){ |
| 1460 | /* The child file reverts to baseline. Show this as a change */ |
| 1461 | pChildFile = manifest_file_seek(pChild, pParentFile->zName, 0); |
| 1462 | if( pChildFile ){ |
| 1463 | add_one_mlink(pmid, pParentFile->zUuid, mid, pChildFile->zUuid, |
| 1464 | pChildFile->zName, 0, isPublic, isPrim, |
| 1465 | manifest_file_mperm(pChildFile)); |
| 1466 | } |
| 1467 | } |
| 1468 | }else{ |
| 1469 | pChildFile = manifest_file_seek(pChild, pParentFile->zName, 0); |
| 1470 | if( pChildFile ){ |
| 1471 | /* File resurrected in the child after having been deleted in |
| 1472 | ** the parent. Show this as an added file. */ |
| 1473 | add_one_mlink(pmid, 0, mid, pChildFile->zUuid, pChildFile->zName, 0, |
| 1474 | isPublic, isPrim, manifest_file_mperm(pChildFile)); |
| 1475 | } |
| 1476 | } |
| 1477 | } |
| 1478 | }else if( pChild->zBaseline==0 ){ |
| 1479 | /* pChild is a baseline. Look for files that are present in pParent |
| @@ -1470,12 +1480,12 @@ | |
| 1480 | ** but are missing from pChild and mark them as having been deleted. */ |
| 1481 | manifest_file_rewind(pParent); |
| 1482 | while( (pParentFile = manifest_file_next(pParent,0))!=0 ){ |
| 1483 | pChildFile = manifest_file_seek(pChild, pParentFile->zName, 0); |
| 1484 | if( pChildFile==0 && pParentFile->zUuid!=0 ){ |
| 1485 | add_one_mlink(pmid, pParentFile->zUuid, mid, 0, pParentFile->zName, 0, |
| 1486 | isPublic, isPrim, 0); |
| 1487 | } |
| 1488 | } |
| 1489 | } |
| 1490 | manifest_cache_insert(*ppOther); |
| 1491 | } |
| @@ -1779,45 +1789,46 @@ | |
| 1789 | sqlite3_snprintf(sizeof(zBaseId), zBaseId, "%d", |
| 1790 | uuid_to_rid(p->zBaseline,1)); |
| 1791 | }else{ |
| 1792 | sqlite3_snprintf(sizeof(zBaseId), zBaseId, "NULL"); |
| 1793 | } |
| 1794 | for(i=0; i<p->nParent; i++){ |
| 1795 | int pid = uuid_to_rid(p->azParent[i], 1); |
| 1796 | db_multi_exec( |
| 1797 | "INSERT OR IGNORE INTO plink(pid, cid, isprim, mtime, baseid)" |
| 1798 | "VALUES(%d, %d, %d, %.17g, %s)", |
| 1799 | pid, rid, i==0, p->rDate, zBaseId/*safe-for-%s*/); |
| 1800 | add_mlink(pid, 0, rid, p, i==0); |
| 1801 | if( i==0 ) parentid = pid; |
| 1802 | } |
| 1803 | if( p->nParent>1 ){ |
| 1804 | /* Remove incorrect MLINK create-file entries that arise when a |
| 1805 | ** file is added by merge. */ |
| 1806 | db_multi_exec( |
| 1807 | "DELETE FROM mlink" |
| 1808 | " WHERE mid=%d" |
| 1809 | " AND pid=0" |
| 1810 | " AND fnid IN " |
| 1811 | " (SELECT fnid FROM mlink WHERE mid=%d GROUP BY fnid" |
| 1812 | " HAVING count(*)<%d)", |
| 1813 | rid, rid, p->nParent |
| 1814 | ); |
| 1815 | } |
| 1816 | db_prepare(&q, "SELECT cid, isprim FROM plink WHERE pid=%d", rid); |
| 1817 | while( db_step(&q)==SQLITE_ROW ){ |
| 1818 | int cid = db_column_int(&q, 0); |
| 1819 | int isprim = db_column_int(&q, 1); |
| 1820 | add_mlink(rid, p, cid, 0, isprim); |
| 1821 | } |
| 1822 | db_finalize(&q); |
| 1823 | if( p->nParent==0 ){ |
| 1824 | /* For root files (files without parents) add mlink entries |
| 1825 | ** showing all content as new. */ |
| 1826 | int isPublic = !content_is_private(rid); |
| 1827 | for(i=0; i<p->nFile; i++){ |
| 1828 | add_one_mlink(0, 0, rid, p->aFile[i].zUuid, p->aFile[i].zName, 0, |
| 1829 | isPublic, 1, manifest_file_mperm(&p->aFile[i])); |
| 1830 | } |
| 1831 | } |
| 1832 | db_multi_exec( |
| 1833 | "REPLACE INTO event(type,mtime,objid,user,comment," |
| 1834 | "bgcolor,euser,ecomment,omtime)" |
| 1835 | |
| 1836 | DDED src/markdown.md |
+64
-53
| --- src/manifest.c | ||
| +++ src/manifest.c | ||
| @@ -1185,16 +1185,18 @@ | ||
| 1185 | 1185 | /* |
| 1186 | 1186 | ** Add a single entry to the mlink table. Also add the filename to |
| 1187 | 1187 | ** the filename table if it is not there already. |
| 1188 | 1188 | */ |
| 1189 | 1189 | static void add_one_mlink( |
| 1190 | + int pmid, /* The parent manifest */ | |
| 1191 | + const char *zFromUuid, /* UUID for content in parent */ | |
| 1190 | 1192 | int mid, /* The record ID of the manifest */ |
| 1191 | - const char *zFromUuid, /* UUID for the mlink.pid. "" to add file */ | |
| 1192 | - const char *zToUuid, /* UUID for the mlink.fid. "" to delete */ | |
| 1193 | + const char *zToUuid, /* UUID for content in child */ | |
| 1193 | 1194 | const char *zFilename, /* Filename */ |
| 1194 | 1195 | const char *zPrior, /* Previous filename. NULL if unchanged */ |
| 1195 | 1196 | int isPublic, /* True if mid is not a private manifest */ |
| 1197 | + int isPrimary, /* pmid is the primary parent of mid */ | |
| 1196 | 1198 | int mperm /* 1: exec, 2: symlink */ |
| 1197 | 1199 | ){ |
| 1198 | 1200 | int fnid, pfnid, pid, fid; |
| 1199 | 1201 | static Stmt s1; |
| 1200 | 1202 | |
| @@ -1214,19 +1216,21 @@ | ||
| 1214 | 1216 | }else{ |
| 1215 | 1217 | fid = uuid_to_rid(zToUuid, 1); |
| 1216 | 1218 | if( isPublic ) content_make_public(fid); |
| 1217 | 1219 | } |
| 1218 | 1220 | db_static_prepare(&s1, |
| 1219 | - "INSERT INTO mlink(mid,pid,fid,fnid,pfnid,mperm)" | |
| 1220 | - "VALUES(:m,:p,:f,:n,:pfn,:mp)" | |
| 1221 | + "INSERT INTO mlink(mid,fid,pmid,pid,fnid,pfnid,mperm,isaux)" | |
| 1222 | + "VALUES(:m,:f,:pm,:p,:n,:pfn,:mp,:isaux)" | |
| 1221 | 1223 | ); |
| 1222 | 1224 | db_bind_int(&s1, ":m", mid); |
| 1223 | - db_bind_int(&s1, ":p", pid); | |
| 1224 | 1225 | db_bind_int(&s1, ":f", fid); |
| 1226 | + db_bind_int(&s1, ":pm", pmid); | |
| 1227 | + db_bind_int(&s1, ":p", pid); | |
| 1225 | 1228 | db_bind_int(&s1, ":n", fnid); |
| 1226 | 1229 | db_bind_int(&s1, ":pfn", pfnid); |
| 1227 | 1230 | db_bind_int(&s1, ":mp", mperm); |
| 1231 | + db_bind_int(&s1, ":isaux", isPrimary==0); | |
| 1228 | 1232 | db_exec(&s1); |
| 1229 | 1233 | if( pid && fid ){ |
| 1230 | 1234 | content_deltify(pid, fid, 0); |
| 1231 | 1235 | } |
| 1232 | 1236 | } |
| @@ -1340,24 +1344,29 @@ | ||
| 1340 | 1344 | ** |
| 1341 | 1345 | ** Deleted files have mlink.fid=0. |
| 1342 | 1346 | ** Added files have mlink.pid=0. |
| 1343 | 1347 | ** Edited files have both mlink.pid!=0 and mlink.fid!=0 |
| 1344 | 1348 | */ |
| 1345 | -static void add_mlink(int pid, Manifest *pParent, int cid, Manifest *pChild){ | |
| 1349 | +static void add_mlink( | |
| 1350 | + int pmid, Manifest *pParent, /* Parent check-in */ | |
| 1351 | + int mid, Manifest *pChild, /* The child check-in */ | |
| 1352 | + int isPrim /* TRUE if pmid is the primary parent of mid */ | |
| 1353 | +){ | |
| 1346 | 1354 | Blob otherContent; |
| 1347 | 1355 | int otherRid; |
| 1348 | 1356 | int i, rc; |
| 1349 | 1357 | ManifestFile *pChildFile, *pParentFile; |
| 1350 | 1358 | Manifest **ppOther; |
| 1351 | 1359 | static Stmt eq; |
| 1352 | 1360 | int isPublic; /* True if pChild is non-private */ |
| 1353 | 1361 | |
| 1354 | - /* If mlink table entires are already set for cid, then abort early | |
| 1355 | - ** doing no work. | |
| 1362 | + /* If mlink table entires are already exist for the pmid-to-mid transition, | |
| 1363 | + ** then abort early doing no work. | |
| 1356 | 1364 | */ |
| 1357 | - db_static_prepare(&eq, "SELECT 1 FROM mlink WHERE mid=:mid"); | |
| 1358 | - db_bind_int(&eq, ":mid", cid); | |
| 1365 | + db_static_prepare(&eq, "SELECT 1 FROM mlink WHERE mid=:mid AND pmid=:pmid"); | |
| 1366 | + db_bind_int(&eq, ":mid", mid); | |
| 1367 | + db_bind_int(&eq, ":pmid", pmid); | |
| 1359 | 1368 | rc = db_step(&eq); |
| 1360 | 1369 | db_reset(&eq); |
| 1361 | 1370 | if( rc==SQLITE_ROW ) return; |
| 1362 | 1371 | |
| 1363 | 1372 | /* Compute the value of the missing pParent or pChild parameter. |
| @@ -1364,14 +1373,14 @@ | ||
| 1364 | 1373 | ** Fetch the baseline checkins for both. |
| 1365 | 1374 | */ |
| 1366 | 1375 | assert( pParent==0 || pChild==0 ); |
| 1367 | 1376 | if( pParent==0 ){ |
| 1368 | 1377 | ppOther = &pParent; |
| 1369 | - otherRid = pid; | |
| 1378 | + otherRid = pmid; | |
| 1370 | 1379 | }else{ |
| 1371 | 1380 | ppOther = &pChild; |
| 1372 | - otherRid = cid; | |
| 1381 | + otherRid = mid; | |
| 1373 | 1382 | } |
| 1374 | 1383 | if( (*ppOther = manifest_cache_find(otherRid))==0 ){ |
| 1375 | 1384 | content_get(otherRid, &otherContent); |
| 1376 | 1385 | if( blob_size(&otherContent)==0 ) return; |
| 1377 | 1386 | *ppOther = manifest_parse(&otherContent, otherRid, 0); |
| @@ -1379,20 +1388,20 @@ | ||
| 1379 | 1388 | } |
| 1380 | 1389 | if( fetch_baseline(pParent, 0) || fetch_baseline(pChild, 0) ){ |
| 1381 | 1390 | manifest_destroy(*ppOther); |
| 1382 | 1391 | return; |
| 1383 | 1392 | } |
| 1384 | - isPublic = !content_is_private(cid); | |
| 1393 | + isPublic = !content_is_private(mid); | |
| 1385 | 1394 | |
| 1386 | 1395 | /* Try to make the parent manifest a delta from the child, if that |
| 1387 | 1396 | ** is an appropriate thing to do. For a new baseline, make the |
| 1388 | 1397 | ** previous baseline a delta from the current baseline. |
| 1389 | 1398 | */ |
| 1390 | 1399 | if( (pParent->zBaseline==0)==(pChild->zBaseline==0) ){ |
| 1391 | - content_deltify(pid, cid, 0); | |
| 1400 | + content_deltify(pmid, mid, 0); | |
| 1392 | 1401 | }else if( pChild->zBaseline==0 && pParent->zBaseline!=0 ){ |
| 1393 | - content_deltify(pParent->pBaseline->rid, cid, 0); | |
| 1402 | + content_deltify(pParent->pBaseline->rid, mid, 0); | |
| 1394 | 1403 | } |
| 1395 | 1404 | |
| 1396 | 1405 | /* Remember all children less than a few seconds younger than their parent, |
| 1397 | 1406 | ** as we might want to fudge the times for those children. |
| 1398 | 1407 | */ |
| @@ -1412,31 +1421,32 @@ | ||
| 1412 | 1421 | int mperm = manifest_file_mperm(pChildFile); |
| 1413 | 1422 | if( pChildFile->zPrior ){ |
| 1414 | 1423 | pParentFile = manifest_file_seek(pParent, pChildFile->zPrior, 0); |
| 1415 | 1424 | if( pParentFile ){ |
| 1416 | 1425 | /* File with name change */ |
| 1417 | - add_one_mlink(cid, pParentFile->zUuid, pChildFile->zUuid, | |
| 1418 | - pChildFile->zName, pChildFile->zPrior, isPublic, mperm); | |
| 1426 | + add_one_mlink(pmid, pParentFile->zUuid, mid, pChildFile->zUuid, | |
| 1427 | + pChildFile->zName, pChildFile->zPrior, | |
| 1428 | + isPublic, isPrim, mperm); | |
| 1419 | 1429 | }else{ |
| 1420 | 1430 | /* File name changed, but the old name is not found in the parent! |
| 1421 | 1431 | ** Treat this like a new file. */ |
| 1422 | - add_one_mlink(cid, 0, pChildFile->zUuid, pChildFile->zName, 0, | |
| 1423 | - isPublic, mperm); | |
| 1432 | + add_one_mlink(pmid, 0, mid, pChildFile->zUuid, pChildFile->zName, 0, | |
| 1433 | + isPublic, isPrim, mperm); | |
| 1424 | 1434 | } |
| 1425 | 1435 | }else{ |
| 1426 | 1436 | pParentFile = manifest_file_seek(pParent, pChildFile->zName, 0); |
| 1427 | 1437 | if( pParentFile==0 ){ |
| 1428 | 1438 | if( pChildFile->zUuid ){ |
| 1429 | 1439 | /* A new file */ |
| 1430 | - add_one_mlink(cid, 0, pChildFile->zUuid, pChildFile->zName, 0, | |
| 1431 | - isPublic, mperm); | |
| 1440 | + add_one_mlink(pmid, 0, mid, pChildFile->zUuid, pChildFile->zName, 0, | |
| 1441 | + isPublic, isPrim, mperm); | |
| 1432 | 1442 | } |
| 1433 | 1443 | }else if( fossil_strcmp(pChildFile->zUuid, pParentFile->zUuid)!=0 |
| 1434 | 1444 | || manifest_file_mperm(pParentFile)!=mperm ){ |
| 1435 | 1445 | /* Changes in file content or permissions */ |
| 1436 | - add_one_mlink(cid, pParentFile->zUuid, pChildFile->zUuid, | |
| 1437 | - pChildFile->zName, 0, isPublic, mperm); | |
| 1446 | + add_one_mlink(pmid, pParentFile->zUuid, mid, pChildFile->zUuid, | |
| 1447 | + pChildFile->zName, 0, isPublic, isPrim, mperm); | |
| 1438 | 1448 | } |
| 1439 | 1449 | } |
| 1440 | 1450 | } |
| 1441 | 1451 | if( pParent->zBaseline && pChild->zBaseline ){ |
| 1442 | 1452 | /* Both parent and child are delta manifests. Look for files that |
| @@ -1448,22 +1458,22 @@ | ||
| 1448 | 1458 | pChildFile = manifest_file_seek_base(pChild, pParentFile->zName, 0); |
| 1449 | 1459 | if( pChildFile==0 ){ |
| 1450 | 1460 | /* The child file reverts to baseline. Show this as a change */ |
| 1451 | 1461 | pChildFile = manifest_file_seek(pChild, pParentFile->zName, 0); |
| 1452 | 1462 | if( pChildFile ){ |
| 1453 | - add_one_mlink(cid, pParentFile->zUuid, pChildFile->zUuid, | |
| 1454 | - pChildFile->zName, 0, isPublic, | |
| 1463 | + add_one_mlink(pmid, pParentFile->zUuid, mid, pChildFile->zUuid, | |
| 1464 | + pChildFile->zName, 0, isPublic, isPrim, | |
| 1455 | 1465 | manifest_file_mperm(pChildFile)); |
| 1456 | 1466 | } |
| 1457 | 1467 | } |
| 1458 | 1468 | }else{ |
| 1459 | 1469 | pChildFile = manifest_file_seek(pChild, pParentFile->zName, 0); |
| 1460 | 1470 | if( pChildFile ){ |
| 1461 | 1471 | /* File resurrected in the child after having been deleted in |
| 1462 | 1472 | ** the parent. Show this as an added file. */ |
| 1463 | - add_one_mlink(cid, 0, pChildFile->zUuid, pChildFile->zName, 0, | |
| 1464 | - isPublic, manifest_file_mperm(pChildFile)); | |
| 1473 | + add_one_mlink(pmid, 0, mid, pChildFile->zUuid, pChildFile->zName, 0, | |
| 1474 | + isPublic, isPrim, manifest_file_mperm(pChildFile)); | |
| 1465 | 1475 | } |
| 1466 | 1476 | } |
| 1467 | 1477 | } |
| 1468 | 1478 | }else if( pChild->zBaseline==0 ){ |
| 1469 | 1479 | /* pChild is a baseline. Look for files that are present in pParent |
| @@ -1470,12 +1480,12 @@ | ||
| 1470 | 1480 | ** but are missing from pChild and mark them as having been deleted. */ |
| 1471 | 1481 | manifest_file_rewind(pParent); |
| 1472 | 1482 | while( (pParentFile = manifest_file_next(pParent,0))!=0 ){ |
| 1473 | 1483 | pChildFile = manifest_file_seek(pChild, pParentFile->zName, 0); |
| 1474 | 1484 | if( pChildFile==0 && pParentFile->zUuid!=0 ){ |
| 1475 | - add_one_mlink(cid, pParentFile->zUuid, 0, pParentFile->zName, 0, | |
| 1476 | - isPublic, 0); | |
| 1485 | + add_one_mlink(pmid, pParentFile->zUuid, mid, 0, pParentFile->zName, 0, | |
| 1486 | + isPublic, isPrim, 0); | |
| 1477 | 1487 | } |
| 1478 | 1488 | } |
| 1479 | 1489 | } |
| 1480 | 1490 | manifest_cache_insert(*ppOther); |
| 1481 | 1491 | } |
| @@ -1779,45 +1789,46 @@ | ||
| 1779 | 1789 | sqlite3_snprintf(sizeof(zBaseId), zBaseId, "%d", |
| 1780 | 1790 | uuid_to_rid(p->zBaseline,1)); |
| 1781 | 1791 | }else{ |
| 1782 | 1792 | sqlite3_snprintf(sizeof(zBaseId), zBaseId, "NULL"); |
| 1783 | 1793 | } |
| 1784 | - (void)db_schema_is_outofdate(); /* Make sure g.zAuxSchema is initialized */ | |
| 1785 | 1794 | for(i=0; i<p->nParent; i++){ |
| 1786 | 1795 | int pid = uuid_to_rid(p->azParent[i], 1); |
| 1787 | - if( strcmp(g.zAuxSchema,"2014-11-24 20:35")>=0 ){ | |
| 1788 | - /* Support for PLINK.BASEID added on 2014-11-24 */ | |
| 1789 | - db_multi_exec( | |
| 1790 | - "INSERT OR IGNORE INTO plink(pid, cid, isprim, mtime, baseid)" | |
| 1791 | - "VALUES(%d, %d, %d, %.17g, %s)", | |
| 1792 | - pid, rid, i==0, p->rDate, zBaseId/*safe-for-%s*/); | |
| 1793 | - }else{ | |
| 1794 | - /* Continue to work with older schema to avoid an unnecessary | |
| 1795 | - ** rebuild */ | |
| 1796 | - db_multi_exec( | |
| 1797 | - "INSERT OR IGNORE INTO plink(pid, cid, isprim, mtime)" | |
| 1798 | - "VALUES(%d, %d, %d, %.17g)", | |
| 1799 | - pid, rid, i==0, p->rDate); | |
| 1800 | - } | |
| 1801 | - if( i==0 ){ | |
| 1802 | - add_mlink(pid, 0, rid, p); | |
| 1803 | - parentid = pid; | |
| 1804 | - } | |
| 1805 | - } | |
| 1806 | - db_prepare(&q, "SELECT cid FROM plink WHERE pid=%d AND isprim", rid); | |
| 1796 | + db_multi_exec( | |
| 1797 | + "INSERT OR IGNORE INTO plink(pid, cid, isprim, mtime, baseid)" | |
| 1798 | + "VALUES(%d, %d, %d, %.17g, %s)", | |
| 1799 | + pid, rid, i==0, p->rDate, zBaseId/*safe-for-%s*/); | |
| 1800 | + add_mlink(pid, 0, rid, p, i==0); | |
| 1801 | + if( i==0 ) parentid = pid; | |
| 1802 | + } | |
| 1803 | + if( p->nParent>1 ){ | |
| 1804 | + /* Remove incorrect MLINK create-file entries that arise when a | |
| 1805 | + ** file is added by merge. */ | |
| 1806 | + db_multi_exec( | |
| 1807 | + "DELETE FROM mlink" | |
| 1808 | + " WHERE mid=%d" | |
| 1809 | + " AND pid=0" | |
| 1810 | + " AND fnid IN " | |
| 1811 | + " (SELECT fnid FROM mlink WHERE mid=%d GROUP BY fnid" | |
| 1812 | + " HAVING count(*)<%d)", | |
| 1813 | + rid, rid, p->nParent | |
| 1814 | + ); | |
| 1815 | + } | |
| 1816 | + db_prepare(&q, "SELECT cid, isprim FROM plink WHERE pid=%d", rid); | |
| 1807 | 1817 | while( db_step(&q)==SQLITE_ROW ){ |
| 1808 | 1818 | int cid = db_column_int(&q, 0); |
| 1809 | - add_mlink(rid, p, cid, 0); | |
| 1819 | + int isprim = db_column_int(&q, 1); | |
| 1820 | + add_mlink(rid, p, cid, 0, isprim); | |
| 1810 | 1821 | } |
| 1811 | 1822 | db_finalize(&q); |
| 1812 | 1823 | if( p->nParent==0 ){ |
| 1813 | 1824 | /* For root files (files without parents) add mlink entries |
| 1814 | 1825 | ** showing all content as new. */ |
| 1815 | 1826 | int isPublic = !content_is_private(rid); |
| 1816 | 1827 | for(i=0; i<p->nFile; i++){ |
| 1817 | - add_one_mlink(rid, 0, p->aFile[i].zUuid, p->aFile[i].zName, 0, | |
| 1818 | - isPublic, manifest_file_mperm(&p->aFile[i])); | |
| 1828 | + add_one_mlink(0, 0, rid, p->aFile[i].zUuid, p->aFile[i].zName, 0, | |
| 1829 | + isPublic, 1, manifest_file_mperm(&p->aFile[i])); | |
| 1819 | 1830 | } |
| 1820 | 1831 | } |
| 1821 | 1832 | db_multi_exec( |
| 1822 | 1833 | "REPLACE INTO event(type,mtime,objid,user,comment," |
| 1823 | 1834 | "bgcolor,euser,ecomment,omtime)" |
| 1824 | 1835 | |
| 1825 | 1836 | ADDED src/markdown.md |
| --- src/manifest.c | |
| +++ src/manifest.c | |
| @@ -1185,16 +1185,18 @@ | |
| 1185 | /* |
| 1186 | ** Add a single entry to the mlink table. Also add the filename to |
| 1187 | ** the filename table if it is not there already. |
| 1188 | */ |
| 1189 | static void add_one_mlink( |
| 1190 | int mid, /* The record ID of the manifest */ |
| 1191 | const char *zFromUuid, /* UUID for the mlink.pid. "" to add file */ |
| 1192 | const char *zToUuid, /* UUID for the mlink.fid. "" to delete */ |
| 1193 | const char *zFilename, /* Filename */ |
| 1194 | const char *zPrior, /* Previous filename. NULL if unchanged */ |
| 1195 | int isPublic, /* True if mid is not a private manifest */ |
| 1196 | int mperm /* 1: exec, 2: symlink */ |
| 1197 | ){ |
| 1198 | int fnid, pfnid, pid, fid; |
| 1199 | static Stmt s1; |
| 1200 | |
| @@ -1214,19 +1216,21 @@ | |
| 1214 | }else{ |
| 1215 | fid = uuid_to_rid(zToUuid, 1); |
| 1216 | if( isPublic ) content_make_public(fid); |
| 1217 | } |
| 1218 | db_static_prepare(&s1, |
| 1219 | "INSERT INTO mlink(mid,pid,fid,fnid,pfnid,mperm)" |
| 1220 | "VALUES(:m,:p,:f,:n,:pfn,:mp)" |
| 1221 | ); |
| 1222 | db_bind_int(&s1, ":m", mid); |
| 1223 | db_bind_int(&s1, ":p", pid); |
| 1224 | db_bind_int(&s1, ":f", fid); |
| 1225 | db_bind_int(&s1, ":n", fnid); |
| 1226 | db_bind_int(&s1, ":pfn", pfnid); |
| 1227 | db_bind_int(&s1, ":mp", mperm); |
| 1228 | db_exec(&s1); |
| 1229 | if( pid && fid ){ |
| 1230 | content_deltify(pid, fid, 0); |
| 1231 | } |
| 1232 | } |
| @@ -1340,24 +1344,29 @@ | |
| 1340 | ** |
| 1341 | ** Deleted files have mlink.fid=0. |
| 1342 | ** Added files have mlink.pid=0. |
| 1343 | ** Edited files have both mlink.pid!=0 and mlink.fid!=0 |
| 1344 | */ |
| 1345 | static void add_mlink(int pid, Manifest *pParent, int cid, Manifest *pChild){ |
| 1346 | Blob otherContent; |
| 1347 | int otherRid; |
| 1348 | int i, rc; |
| 1349 | ManifestFile *pChildFile, *pParentFile; |
| 1350 | Manifest **ppOther; |
| 1351 | static Stmt eq; |
| 1352 | int isPublic; /* True if pChild is non-private */ |
| 1353 | |
| 1354 | /* If mlink table entires are already set for cid, then abort early |
| 1355 | ** doing no work. |
| 1356 | */ |
| 1357 | db_static_prepare(&eq, "SELECT 1 FROM mlink WHERE mid=:mid"); |
| 1358 | db_bind_int(&eq, ":mid", cid); |
| 1359 | rc = db_step(&eq); |
| 1360 | db_reset(&eq); |
| 1361 | if( rc==SQLITE_ROW ) return; |
| 1362 | |
| 1363 | /* Compute the value of the missing pParent or pChild parameter. |
| @@ -1364,14 +1373,14 @@ | |
| 1364 | ** Fetch the baseline checkins for both. |
| 1365 | */ |
| 1366 | assert( pParent==0 || pChild==0 ); |
| 1367 | if( pParent==0 ){ |
| 1368 | ppOther = &pParent; |
| 1369 | otherRid = pid; |
| 1370 | }else{ |
| 1371 | ppOther = &pChild; |
| 1372 | otherRid = cid; |
| 1373 | } |
| 1374 | if( (*ppOther = manifest_cache_find(otherRid))==0 ){ |
| 1375 | content_get(otherRid, &otherContent); |
| 1376 | if( blob_size(&otherContent)==0 ) return; |
| 1377 | *ppOther = manifest_parse(&otherContent, otherRid, 0); |
| @@ -1379,20 +1388,20 @@ | |
| 1379 | } |
| 1380 | if( fetch_baseline(pParent, 0) || fetch_baseline(pChild, 0) ){ |
| 1381 | manifest_destroy(*ppOther); |
| 1382 | return; |
| 1383 | } |
| 1384 | isPublic = !content_is_private(cid); |
| 1385 | |
| 1386 | /* Try to make the parent manifest a delta from the child, if that |
| 1387 | ** is an appropriate thing to do. For a new baseline, make the |
| 1388 | ** previous baseline a delta from the current baseline. |
| 1389 | */ |
| 1390 | if( (pParent->zBaseline==0)==(pChild->zBaseline==0) ){ |
| 1391 | content_deltify(pid, cid, 0); |
| 1392 | }else if( pChild->zBaseline==0 && pParent->zBaseline!=0 ){ |
| 1393 | content_deltify(pParent->pBaseline->rid, cid, 0); |
| 1394 | } |
| 1395 | |
| 1396 | /* Remember all children less than a few seconds younger than their parent, |
| 1397 | ** as we might want to fudge the times for those children. |
| 1398 | */ |
| @@ -1412,31 +1421,32 @@ | |
| 1412 | int mperm = manifest_file_mperm(pChildFile); |
| 1413 | if( pChildFile->zPrior ){ |
| 1414 | pParentFile = manifest_file_seek(pParent, pChildFile->zPrior, 0); |
| 1415 | if( pParentFile ){ |
| 1416 | /* File with name change */ |
| 1417 | add_one_mlink(cid, pParentFile->zUuid, pChildFile->zUuid, |
| 1418 | pChildFile->zName, pChildFile->zPrior, isPublic, mperm); |
| 1419 | }else{ |
| 1420 | /* File name changed, but the old name is not found in the parent! |
| 1421 | ** Treat this like a new file. */ |
| 1422 | add_one_mlink(cid, 0, pChildFile->zUuid, pChildFile->zName, 0, |
| 1423 | isPublic, mperm); |
| 1424 | } |
| 1425 | }else{ |
| 1426 | pParentFile = manifest_file_seek(pParent, pChildFile->zName, 0); |
| 1427 | if( pParentFile==0 ){ |
| 1428 | if( pChildFile->zUuid ){ |
| 1429 | /* A new file */ |
| 1430 | add_one_mlink(cid, 0, pChildFile->zUuid, pChildFile->zName, 0, |
| 1431 | isPublic, mperm); |
| 1432 | } |
| 1433 | }else if( fossil_strcmp(pChildFile->zUuid, pParentFile->zUuid)!=0 |
| 1434 | || manifest_file_mperm(pParentFile)!=mperm ){ |
| 1435 | /* Changes in file content or permissions */ |
| 1436 | add_one_mlink(cid, pParentFile->zUuid, pChildFile->zUuid, |
| 1437 | pChildFile->zName, 0, isPublic, mperm); |
| 1438 | } |
| 1439 | } |
| 1440 | } |
| 1441 | if( pParent->zBaseline && pChild->zBaseline ){ |
| 1442 | /* Both parent and child are delta manifests. Look for files that |
| @@ -1448,22 +1458,22 @@ | |
| 1448 | pChildFile = manifest_file_seek_base(pChild, pParentFile->zName, 0); |
| 1449 | if( pChildFile==0 ){ |
| 1450 | /* The child file reverts to baseline. Show this as a change */ |
| 1451 | pChildFile = manifest_file_seek(pChild, pParentFile->zName, 0); |
| 1452 | if( pChildFile ){ |
| 1453 | add_one_mlink(cid, pParentFile->zUuid, pChildFile->zUuid, |
| 1454 | pChildFile->zName, 0, isPublic, |
| 1455 | manifest_file_mperm(pChildFile)); |
| 1456 | } |
| 1457 | } |
| 1458 | }else{ |
| 1459 | pChildFile = manifest_file_seek(pChild, pParentFile->zName, 0); |
| 1460 | if( pChildFile ){ |
| 1461 | /* File resurrected in the child after having been deleted in |
| 1462 | ** the parent. Show this as an added file. */ |
| 1463 | add_one_mlink(cid, 0, pChildFile->zUuid, pChildFile->zName, 0, |
| 1464 | isPublic, manifest_file_mperm(pChildFile)); |
| 1465 | } |
| 1466 | } |
| 1467 | } |
| 1468 | }else if( pChild->zBaseline==0 ){ |
| 1469 | /* pChild is a baseline. Look for files that are present in pParent |
| @@ -1470,12 +1480,12 @@ | |
| 1470 | ** but are missing from pChild and mark them as having been deleted. */ |
| 1471 | manifest_file_rewind(pParent); |
| 1472 | while( (pParentFile = manifest_file_next(pParent,0))!=0 ){ |
| 1473 | pChildFile = manifest_file_seek(pChild, pParentFile->zName, 0); |
| 1474 | if( pChildFile==0 && pParentFile->zUuid!=0 ){ |
| 1475 | add_one_mlink(cid, pParentFile->zUuid, 0, pParentFile->zName, 0, |
| 1476 | isPublic, 0); |
| 1477 | } |
| 1478 | } |
| 1479 | } |
| 1480 | manifest_cache_insert(*ppOther); |
| 1481 | } |
| @@ -1779,45 +1789,46 @@ | |
| 1779 | sqlite3_snprintf(sizeof(zBaseId), zBaseId, "%d", |
| 1780 | uuid_to_rid(p->zBaseline,1)); |
| 1781 | }else{ |
| 1782 | sqlite3_snprintf(sizeof(zBaseId), zBaseId, "NULL"); |
| 1783 | } |
| 1784 | (void)db_schema_is_outofdate(); /* Make sure g.zAuxSchema is initialized */ |
| 1785 | for(i=0; i<p->nParent; i++){ |
| 1786 | int pid = uuid_to_rid(p->azParent[i], 1); |
| 1787 | if( strcmp(g.zAuxSchema,"2014-11-24 20:35")>=0 ){ |
| 1788 | /* Support for PLINK.BASEID added on 2014-11-24 */ |
| 1789 | db_multi_exec( |
| 1790 | "INSERT OR IGNORE INTO plink(pid, cid, isprim, mtime, baseid)" |
| 1791 | "VALUES(%d, %d, %d, %.17g, %s)", |
| 1792 | pid, rid, i==0, p->rDate, zBaseId/*safe-for-%s*/); |
| 1793 | }else{ |
| 1794 | /* Continue to work with older schema to avoid an unnecessary |
| 1795 | ** rebuild */ |
| 1796 | db_multi_exec( |
| 1797 | "INSERT OR IGNORE INTO plink(pid, cid, isprim, mtime)" |
| 1798 | "VALUES(%d, %d, %d, %.17g)", |
| 1799 | pid, rid, i==0, p->rDate); |
| 1800 | } |
| 1801 | if( i==0 ){ |
| 1802 | add_mlink(pid, 0, rid, p); |
| 1803 | parentid = pid; |
| 1804 | } |
| 1805 | } |
| 1806 | db_prepare(&q, "SELECT cid FROM plink WHERE pid=%d AND isprim", rid); |
| 1807 | while( db_step(&q)==SQLITE_ROW ){ |
| 1808 | int cid = db_column_int(&q, 0); |
| 1809 | add_mlink(rid, p, cid, 0); |
| 1810 | } |
| 1811 | db_finalize(&q); |
| 1812 | if( p->nParent==0 ){ |
| 1813 | /* For root files (files without parents) add mlink entries |
| 1814 | ** showing all content as new. */ |
| 1815 | int isPublic = !content_is_private(rid); |
| 1816 | for(i=0; i<p->nFile; i++){ |
| 1817 | add_one_mlink(rid, 0, p->aFile[i].zUuid, p->aFile[i].zName, 0, |
| 1818 | isPublic, manifest_file_mperm(&p->aFile[i])); |
| 1819 | } |
| 1820 | } |
| 1821 | db_multi_exec( |
| 1822 | "REPLACE INTO event(type,mtime,objid,user,comment," |
| 1823 | "bgcolor,euser,ecomment,omtime)" |
| 1824 | |
| 1825 | DDED src/markdown.md |
| --- src/manifest.c | |
| +++ src/manifest.c | |
| @@ -1185,16 +1185,18 @@ | |
| 1185 | /* |
| 1186 | ** Add a single entry to the mlink table. Also add the filename to |
| 1187 | ** the filename table if it is not there already. |
| 1188 | */ |
| 1189 | static void add_one_mlink( |
| 1190 | int pmid, /* The parent manifest */ |
| 1191 | const char *zFromUuid, /* UUID for content in parent */ |
| 1192 | int mid, /* The record ID of the manifest */ |
| 1193 | const char *zToUuid, /* UUID for content in child */ |
| 1194 | const char *zFilename, /* Filename */ |
| 1195 | const char *zPrior, /* Previous filename. NULL if unchanged */ |
| 1196 | int isPublic, /* True if mid is not a private manifest */ |
| 1197 | int isPrimary, /* pmid is the primary parent of mid */ |
| 1198 | int mperm /* 1: exec, 2: symlink */ |
| 1199 | ){ |
| 1200 | int fnid, pfnid, pid, fid; |
| 1201 | static Stmt s1; |
| 1202 | |
| @@ -1214,19 +1216,21 @@ | |
| 1216 | }else{ |
| 1217 | fid = uuid_to_rid(zToUuid, 1); |
| 1218 | if( isPublic ) content_make_public(fid); |
| 1219 | } |
| 1220 | db_static_prepare(&s1, |
| 1221 | "INSERT INTO mlink(mid,fid,pmid,pid,fnid,pfnid,mperm,isaux)" |
| 1222 | "VALUES(:m,:f,:pm,:p,:n,:pfn,:mp,:isaux)" |
| 1223 | ); |
| 1224 | db_bind_int(&s1, ":m", mid); |
| 1225 | db_bind_int(&s1, ":f", fid); |
| 1226 | db_bind_int(&s1, ":pm", pmid); |
| 1227 | db_bind_int(&s1, ":p", pid); |
| 1228 | db_bind_int(&s1, ":n", fnid); |
| 1229 | db_bind_int(&s1, ":pfn", pfnid); |
| 1230 | db_bind_int(&s1, ":mp", mperm); |
| 1231 | db_bind_int(&s1, ":isaux", isPrimary==0); |
| 1232 | db_exec(&s1); |
| 1233 | if( pid && fid ){ |
| 1234 | content_deltify(pid, fid, 0); |
| 1235 | } |
| 1236 | } |
| @@ -1340,24 +1344,29 @@ | |
| 1344 | ** |
| 1345 | ** Deleted files have mlink.fid=0. |
| 1346 | ** Added files have mlink.pid=0. |
| 1347 | ** Edited files have both mlink.pid!=0 and mlink.fid!=0 |
| 1348 | */ |
| 1349 | static void add_mlink( |
| 1350 | int pmid, Manifest *pParent, /* Parent check-in */ |
| 1351 | int mid, Manifest *pChild, /* The child check-in */ |
| 1352 | int isPrim /* TRUE if pmid is the primary parent of mid */ |
| 1353 | ){ |
| 1354 | Blob otherContent; |
| 1355 | int otherRid; |
| 1356 | int i, rc; |
| 1357 | ManifestFile *pChildFile, *pParentFile; |
| 1358 | Manifest **ppOther; |
| 1359 | static Stmt eq; |
| 1360 | int isPublic; /* True if pChild is non-private */ |
| 1361 | |
| 1362 | /* If mlink table entires are already exist for the pmid-to-mid transition, |
| 1363 | ** then abort early doing no work. |
| 1364 | */ |
| 1365 | db_static_prepare(&eq, "SELECT 1 FROM mlink WHERE mid=:mid AND pmid=:pmid"); |
| 1366 | db_bind_int(&eq, ":mid", mid); |
| 1367 | db_bind_int(&eq, ":pmid", pmid); |
| 1368 | rc = db_step(&eq); |
| 1369 | db_reset(&eq); |
| 1370 | if( rc==SQLITE_ROW ) return; |
| 1371 | |
| 1372 | /* Compute the value of the missing pParent or pChild parameter. |
| @@ -1364,14 +1373,14 @@ | |
| 1373 | ** Fetch the baseline checkins for both. |
| 1374 | */ |
| 1375 | assert( pParent==0 || pChild==0 ); |
| 1376 | if( pParent==0 ){ |
| 1377 | ppOther = &pParent; |
| 1378 | otherRid = pmid; |
| 1379 | }else{ |
| 1380 | ppOther = &pChild; |
| 1381 | otherRid = mid; |
| 1382 | } |
| 1383 | if( (*ppOther = manifest_cache_find(otherRid))==0 ){ |
| 1384 | content_get(otherRid, &otherContent); |
| 1385 | if( blob_size(&otherContent)==0 ) return; |
| 1386 | *ppOther = manifest_parse(&otherContent, otherRid, 0); |
| @@ -1379,20 +1388,20 @@ | |
| 1388 | } |
| 1389 | if( fetch_baseline(pParent, 0) || fetch_baseline(pChild, 0) ){ |
| 1390 | manifest_destroy(*ppOther); |
| 1391 | return; |
| 1392 | } |
| 1393 | isPublic = !content_is_private(mid); |
| 1394 | |
| 1395 | /* Try to make the parent manifest a delta from the child, if that |
| 1396 | ** is an appropriate thing to do. For a new baseline, make the |
| 1397 | ** previous baseline a delta from the current baseline. |
| 1398 | */ |
| 1399 | if( (pParent->zBaseline==0)==(pChild->zBaseline==0) ){ |
| 1400 | content_deltify(pmid, mid, 0); |
| 1401 | }else if( pChild->zBaseline==0 && pParent->zBaseline!=0 ){ |
| 1402 | content_deltify(pParent->pBaseline->rid, mid, 0); |
| 1403 | } |
| 1404 | |
| 1405 | /* Remember all children less than a few seconds younger than their parent, |
| 1406 | ** as we might want to fudge the times for those children. |
| 1407 | */ |
| @@ -1412,31 +1421,32 @@ | |
| 1421 | int mperm = manifest_file_mperm(pChildFile); |
| 1422 | if( pChildFile->zPrior ){ |
| 1423 | pParentFile = manifest_file_seek(pParent, pChildFile->zPrior, 0); |
| 1424 | if( pParentFile ){ |
| 1425 | /* File with name change */ |
| 1426 | add_one_mlink(pmid, pParentFile->zUuid, mid, pChildFile->zUuid, |
| 1427 | pChildFile->zName, pChildFile->zPrior, |
| 1428 | isPublic, isPrim, mperm); |
| 1429 | }else{ |
| 1430 | /* File name changed, but the old name is not found in the parent! |
| 1431 | ** Treat this like a new file. */ |
| 1432 | add_one_mlink(pmid, 0, mid, pChildFile->zUuid, pChildFile->zName, 0, |
| 1433 | isPublic, isPrim, mperm); |
| 1434 | } |
| 1435 | }else{ |
| 1436 | pParentFile = manifest_file_seek(pParent, pChildFile->zName, 0); |
| 1437 | if( pParentFile==0 ){ |
| 1438 | if( pChildFile->zUuid ){ |
| 1439 | /* A new file */ |
| 1440 | add_one_mlink(pmid, 0, mid, pChildFile->zUuid, pChildFile->zName, 0, |
| 1441 | isPublic, isPrim, mperm); |
| 1442 | } |
| 1443 | }else if( fossil_strcmp(pChildFile->zUuid, pParentFile->zUuid)!=0 |
| 1444 | || manifest_file_mperm(pParentFile)!=mperm ){ |
| 1445 | /* Changes in file content or permissions */ |
| 1446 | add_one_mlink(pmid, pParentFile->zUuid, mid, pChildFile->zUuid, |
| 1447 | pChildFile->zName, 0, isPublic, isPrim, mperm); |
| 1448 | } |
| 1449 | } |
| 1450 | } |
| 1451 | if( pParent->zBaseline && pChild->zBaseline ){ |
| 1452 | /* Both parent and child are delta manifests. Look for files that |
| @@ -1448,22 +1458,22 @@ | |
| 1458 | pChildFile = manifest_file_seek_base(pChild, pParentFile->zName, 0); |
| 1459 | if( pChildFile==0 ){ |
| 1460 | /* The child file reverts to baseline. Show this as a change */ |
| 1461 | pChildFile = manifest_file_seek(pChild, pParentFile->zName, 0); |
| 1462 | if( pChildFile ){ |
| 1463 | add_one_mlink(pmid, pParentFile->zUuid, mid, pChildFile->zUuid, |
| 1464 | pChildFile->zName, 0, isPublic, isPrim, |
| 1465 | manifest_file_mperm(pChildFile)); |
| 1466 | } |
| 1467 | } |
| 1468 | }else{ |
| 1469 | pChildFile = manifest_file_seek(pChild, pParentFile->zName, 0); |
| 1470 | if( pChildFile ){ |
| 1471 | /* File resurrected in the child after having been deleted in |
| 1472 | ** the parent. Show this as an added file. */ |
| 1473 | add_one_mlink(pmid, 0, mid, pChildFile->zUuid, pChildFile->zName, 0, |
| 1474 | isPublic, isPrim, manifest_file_mperm(pChildFile)); |
| 1475 | } |
| 1476 | } |
| 1477 | } |
| 1478 | }else if( pChild->zBaseline==0 ){ |
| 1479 | /* pChild is a baseline. Look for files that are present in pParent |
| @@ -1470,12 +1480,12 @@ | |
| 1480 | ** but are missing from pChild and mark them as having been deleted. */ |
| 1481 | manifest_file_rewind(pParent); |
| 1482 | while( (pParentFile = manifest_file_next(pParent,0))!=0 ){ |
| 1483 | pChildFile = manifest_file_seek(pChild, pParentFile->zName, 0); |
| 1484 | if( pChildFile==0 && pParentFile->zUuid!=0 ){ |
| 1485 | add_one_mlink(pmid, pParentFile->zUuid, mid, 0, pParentFile->zName, 0, |
| 1486 | isPublic, isPrim, 0); |
| 1487 | } |
| 1488 | } |
| 1489 | } |
| 1490 | manifest_cache_insert(*ppOther); |
| 1491 | } |
| @@ -1779,45 +1789,46 @@ | |
| 1789 | sqlite3_snprintf(sizeof(zBaseId), zBaseId, "%d", |
| 1790 | uuid_to_rid(p->zBaseline,1)); |
| 1791 | }else{ |
| 1792 | sqlite3_snprintf(sizeof(zBaseId), zBaseId, "NULL"); |
| 1793 | } |
| 1794 | for(i=0; i<p->nParent; i++){ |
| 1795 | int pid = uuid_to_rid(p->azParent[i], 1); |
| 1796 | db_multi_exec( |
| 1797 | "INSERT OR IGNORE INTO plink(pid, cid, isprim, mtime, baseid)" |
| 1798 | "VALUES(%d, %d, %d, %.17g, %s)", |
| 1799 | pid, rid, i==0, p->rDate, zBaseId/*safe-for-%s*/); |
| 1800 | add_mlink(pid, 0, rid, p, i==0); |
| 1801 | if( i==0 ) parentid = pid; |
| 1802 | } |
| 1803 | if( p->nParent>1 ){ |
| 1804 | /* Remove incorrect MLINK create-file entries that arise when a |
| 1805 | ** file is added by merge. */ |
| 1806 | db_multi_exec( |
| 1807 | "DELETE FROM mlink" |
| 1808 | " WHERE mid=%d" |
| 1809 | " AND pid=0" |
| 1810 | " AND fnid IN " |
| 1811 | " (SELECT fnid FROM mlink WHERE mid=%d GROUP BY fnid" |
| 1812 | " HAVING count(*)<%d)", |
| 1813 | rid, rid, p->nParent |
| 1814 | ); |
| 1815 | } |
| 1816 | db_prepare(&q, "SELECT cid, isprim FROM plink WHERE pid=%d", rid); |
| 1817 | while( db_step(&q)==SQLITE_ROW ){ |
| 1818 | int cid = db_column_int(&q, 0); |
| 1819 | int isprim = db_column_int(&q, 1); |
| 1820 | add_mlink(rid, p, cid, 0, isprim); |
| 1821 | } |
| 1822 | db_finalize(&q); |
| 1823 | if( p->nParent==0 ){ |
| 1824 | /* For root files (files without parents) add mlink entries |
| 1825 | ** showing all content as new. */ |
| 1826 | int isPublic = !content_is_private(rid); |
| 1827 | for(i=0; i<p->nFile; i++){ |
| 1828 | add_one_mlink(0, 0, rid, p->aFile[i].zUuid, p->aFile[i].zName, 0, |
| 1829 | isPublic, 1, manifest_file_mperm(&p->aFile[i])); |
| 1830 | } |
| 1831 | } |
| 1832 | db_multi_exec( |
| 1833 | "REPLACE INTO event(type,mtime,objid,user,comment," |
| 1834 | "bgcolor,euser,ecomment,omtime)" |
| 1835 | |
| 1836 | DDED src/markdown.md |
+224
| --- a/src/markdown.md | ||
| +++ b/src/markdown.md | ||
| @@ -0,0 +1,224 @@ | ||
| 1 | +# Markdown formatting rules | |
| 2 | + | |
| 3 | +In addition to its native Wiki formatting syntax, Fossil supports Mark down syntax as specified by | |
| 4 | +[John Gruber's original Markdown implementation](http://daringfireba | |
| 5 | +[syntax description](http://daringfireball.net/projects/markdown/syntax), of which the page you | |
| 6 | +are reading is an extract. | |
| 7 | + | |
| 8 | +This page itself uses Markdown formatting. | |
| 9 | + | |
| 10 | +## Summary | |
| 11 | + | |
| 12 | + - Block elements | |
| 13 | + | |
| 14 | + * A **paragraph** is a group of consecutive lines. Paragraphs are separated by blank lines. | |
| 15 | + | |
| 16 | + * A **Header** is a line of text underlined with equal signs or hyphens, or prefixed by a | |
| 17 | + in s, or prefixed by a | |
| 18 | + number of hash marks. | |
| 19 | + | |
| 20 | + * **Block quotes** are blocks of text prefixed by '>'. | |
| 21 | + | |
| 22 | + * **Ordered list** items are prefixed by a number and a period. **Unordered list** items | |
| 23 | + are prefixed by a hyphen, asterisk or plus sign. Pre | |
| 24 | + | |
| 25 | + * **Code blocks** are formed by lines of text (possibly including empty lines) prefixed by | |
| 26 | + at least 4 spaces or a tab. | |
| 27 | + | |
| 28 | + * A **horizontal rule** is a line consisting of 3 or more asterisks, hyphens or underscores, | |
| 29 | + with optional whitespace between them. | |
| 30 | + | |
| 31 | + - Span elements | |
| 32 | + | |
| 33 | + * 3 types of **links** exist: | |
| 34 | + | |
| 35 | + - **automatic links** are URLs or email addresses enclosed in angle brackets | |
| 36 | + ('<' and '>'), and are displayed as such. | |
| 37 | + | |
| 38 | + - **inline links** consist of the displayed link text in squ | |
| 39 | + followed by the | |
| 40 | + | |
| 41 | + - **reference links** separate _link instance_ from _link definition_. A link instance efinition_. A link instance | |
| 42 | + consists of the displayed link text | |
| 43 | + in square brackets. in square brackets. | |
| 44 | + The corresponding link definition can occur anywhere on the page, and consists | |
| 45 | + of the link definition name in s a colon, whitespace and the | |
| 46 | + link target. | |
| 47 | + | |
| 48 | + * **Emphasis** can be given by wrapping text in one or two asterisks or underscores - use | |
| 49 | + one for HTML `<em>`, and two for `<strong>` emphasis. | |
| 50 | + | |
| 51 | + * A **code span** is text wrapped in backticks ('`'). | |
| 52 | + | |
| 53 | + * **Images** use a syntax much like inline or reference links, # Markdown formatting rules | |
| 54 | + | |
| 55 | +In addition to its native Wiki formatting syntax, Fossil supports Markdown syntax as specified by | |
| 56 | +[John Gruber's original Markdown implementation](http://daringfireball.net/projects/markdown/). | |
| 57 | +For lots of examples - not repeated here - please refer to its | |
| 58 | +[syntax description](http://daringfireball.net/projects/markdown/syntax), of which the page you | |
| 59 | +are reading is an extract. | |
| 60 | + | |
| 61 | +This page itself uses Markdown formatting. | |
| 62 | + | |
| 63 | +## Summary | |
| 64 | + | |
| 65 | + - Block elements | |
| 66 | + | |
| 67 | + * A **paragraph** is a group of consecutive lines. Paragraphs are separated by blank lines. | |
| 68 | + | |
| 69 | + * A **Header** is a line of text underlined with equal signs or hyphens, or prefixed by a | |
| 70 | + number of hash marks. | |
| 71 | + | |
| 72 | + * **Block quotes** are blocks of text prefixed by '>'. | |
| 73 | + | |
| 74 | + * **Ordered list** items are prefixed by a number and a period. **Unordered list** items | |
| 75 | + are prefixed by a hyphen, asterisk or plus sign. Prefix and item text are separated by | |
| 76 | + whitespace. | |
| 77 | + | |
| 78 | + * **Code blocks** are formed by lines of text (possibly including empty lines) prefixed by | |
| 79 | + at least 4 spaces or a tab. | |
| 80 | + | |
| 81 | + * A **horizontal rule** is a line consisting of 3 or more asterisks, hyphens or underscores, | |
| 82 | + with optional whitespace between them. | |
| 83 | + | |
| 84 | + - Span elements | |
| 85 | + | |
| 86 | + * 3 types of **links** exist: | |
| 87 | + | |
| 88 | + - **automatic links** are URLs or email addresses enclosed in angle brackets | |
| 89 | + a * **Emphasis** can be given by wrapping text in one or two asterisks or underscores - use | |
| 90 | + one for HTML `<em>`, and two for `<strong>` emphasis. | |
| 91 | + | |
| 92 | + * A **code span** is text wrapped in backticks ('`'). | |
| 93 | + | |
| 94 | + * **Images** use a syntax much like inline or reference links, but with alt attribute text | |
| 95 | + ('img alt=...') instead of link text, and the first pair of square | |
| 96 | + brackets m prefix; the items will be | |
| 97 | +renumbered during rendering. However, future implementations may | |
| 98 | +for the first item in a list indicates an offset to be used for subsequent items. | |
| 99 | + | |
| 100 | +For list items spanning multiple lines, subsequent lines can be indented using an arbitrary amount | |
| 101 | +of whitespace. | |
| 102 | + | |
| 103 | +List items will be wrapped in HTML `<p>` tags if they are separated by blank lines. | |
| 104 | + | |
| 105 | +A list item may span multiple paragraphs. At least the first line | |
| 106 | +be indented using at least 4 spaces or a tab character. | |
| 107 | + | |
| 108 | +Block quotes within list items must have their '>' delimiters indented using 4 up to 7 spaces. | |
| 109 | + | |
| 110 | +Code blocks within list items need to be indented _twice_, that is, using 8 spaces or 2 tab | |
| 111 | +characters. | |
| 112 | + | |
| 113 | +### Code blocks | |
| 114 | + | |
| 115 | +Lines within a code block are rendered verbatim using HTML `<pre>` and `<code>` tags, except that | |
| 116 | +HTML punctuation characters like '<' and '&' are automatically converted to HTML entities. Thus, | |
| 117 | +there is no need to explicitly escape HTML syntax within a code block. | |
| 118 | + | |
| 119 | +A code block runs until the first non blank line with indent less than 4 spaces or 1 tab character. | |
| 120 | + | |
| 121 | + | |
| 122 | +Regular Markdown syntax is not processed within code blocks. | |
| 123 | + | |
| 124 | +### Links | |
| 125 | + | |
| 126 | +#### Automatic links | |
| 127 | + | |
| 128 | +When rendering automatic links to email addresses, HTML enco | |
| 129 | +prevent some spambots from harvesting. | |
| 130 | + | |
| 131 | +#### Inline links | |
| 132 | + | |
| 133 | +Links to resources on the same server can use relative paths (i.e. can start with a '/'). | |
| 134 | + | |
| 135 | +An optional title for the link (e.g. to have mouseover text in the b rowser) may be given behind | |
| 136 | +the link target but within the parentheses, in single and double quo | |
| 137 | +link target by whitespace. | |
| 138 | +link target by whitespace. | |
| 139 | + | |
| 140 | +# reference link consists of | |
| 141 | +> | |
| 142 | +> - one or more _link instances_ at appropriate locations in the page text | |
| 143 | +> - a single _link definition_ at an arbit | |
| 144 | +> During rendering, each link instance is resolved, and the corresponding definition is | |
| 145 | +> filled in. No separate link definition clauses occu r in the rendered output. | |
| 146 | +> | |
| 147 | +> There are 3 fields involved in link instances and definitions: | |
| 148 | +> | |
| 149 | +> - link text (i.e. the text that is displayed at the resulting link) | |
| 150 | +> - link definition name (i.e. an unique ID binding link instances to link definition) | |
| 151 | +> - link target (a target URL for the link) | |
| 152 | + | |
| 153 | +Multiple link instances may reference the same link definition using its link definition | |
| 154 | +name. | |
| 155 | + | |
| 156 | +Link definition names are case insensitive, and may contain letters, numbers, spaces and | |
| 157 | +punctuation. | |
| 158 | + | |
| 159 | +##### Link instance | |
| 160 | + | |
| 161 | +A space may be inserted between the bracket pairs for link text and link definition name. | |
| 162 | + | |
| 163 | +A link instance can use an _implicit link definition name_ shortcut, in which case the link | |
| 164 | +text is used as the link definition name. The second set of brackets then remains empty, e.g. | |
| 165 | +'[Google][]' ('Google' being used as both link text and link definition name). | |
| 166 | + | |
| 167 | +##### Link definition | |
| 168 | + | |
| 169 | +The first bracket pair containing the link definition name may be indented using up to 3 spaces. | |
| 170 | + | |
| 171 | +The link target may optionally be surrounded by angle brackets ('<' and '>'). | |
| 172 | + | |
| 173 | +A link target may be followed by an optional title (e.g. to have mouseover text in the browser). | |
| 174 | +This title may be enclosed in parentheses, single or double quotes. | |
| 175 | + | |
| 176 | +Link definitions may be split into 2 lines, with the title on the second line, arbitrarily | |
| 177 | +indented. This may be more visually pleasing when using long link targets. | |
| 178 | + | |
| 179 | +### Emphasis | |
| 180 | + | |
| 181 | +The same character(s) used for starting the emphasis must be used to end it; don't mix | |
| 182 | +asterisks and underscores. | |
| 183 | + | |
| 184 | +Emphasis can be used in the middle of a word. That is, there need not be whitespace on either | |
| 185 | +side of emphasis start or end punctuation characters. | |
| 186 | + | |
| 187 | +### Code spans | |
| 188 | + | |
| 189 | +To include a literal backtick character in a code span, use multiple backticks as opening and | |
| 190 | +closing delimiters. | |
| 191 | + | |
| 192 | +Whitespace may exist immediately after the opening delimiter and b Markdown formatting rules | |
| 193 | + | |
| 194 | +In addition to its native Wiki formatting syntax, Fossil supports Markdown syntax as specified by | |
| 195 | +[John Gruber's original Markdown implementation](http://daringfireball.net/projects/markdown/). | |
| 196 | +For lots of examples - not repeated here - please refer to its | |
| 197 | +[syntax description](http://daringfireball.net/projects/markdownr | |
| 198 | +a HTML block level construct (`<div>`, `<table>` etc) must be separated from surrounding | |
| 199 | +context using blank lines, and must both occur at the start of a line. | |
| 200 | + | |
| 201 | +No extra unwanted `<p>` HTML tags are added around HTML block level tags. | |
| 202 | + | |
| 203 | +Markdown formatting within HTML block level tags is not processed; however, formatting within | |
| 204 | +span level tags (e.g. `<mark>`) is processed normally. | |
| 205 | + | |
| 206 | +### Escaping Markdown punctuation | |
| 207 | + | |
| 208 | +The following punctuation characters can be escaped using backslash: | |
| 209 | + | |
| 210 | + - \\ backslash | |
| 211 | + - ` backtick | |
| 212 | + - * asterisk | |
| 213 | + - _ underscore | |
| 214 | + - {} curly braces | |
| 215 | + - [] square brackets | |
| 216 | + - () parentheses | |
| 217 | + - # hash mark | |
| 218 | + - + plus sign | |
| 219 | + - - minus sign (hyphen) | |
| 220 | + - . dot | |
| 221 | + - ! exclamation mark | |
| 222 | + | |
| 223 | +To render a literal backslash, use 2 backslashes ('\\\\'). | |
| 224 | + |
| --- a/src/markdown.md | |
| +++ b/src/markdown.md | |
| @@ -0,0 +1,224 @@ | |
| --- a/src/markdown.md | |
| +++ b/src/markdown.md | |
| @@ -0,0 +1,224 @@ | |
| 1 | # Markdown formatting rules |
| 2 | |
| 3 | In addition to its native Wiki formatting syntax, Fossil supports Mark down syntax as specified by |
| 4 | [John Gruber's original Markdown implementation](http://daringfireba |
| 5 | [syntax description](http://daringfireball.net/projects/markdown/syntax), of which the page you |
| 6 | are reading is an extract. |
| 7 | |
| 8 | This page itself uses Markdown formatting. |
| 9 | |
| 10 | ## Summary |
| 11 | |
| 12 | - Block elements |
| 13 | |
| 14 | * A **paragraph** is a group of consecutive lines. Paragraphs are separated by blank lines. |
| 15 | |
| 16 | * A **Header** is a line of text underlined with equal signs or hyphens, or prefixed by a |
| 17 | in s, or prefixed by a |
| 18 | number of hash marks. |
| 19 | |
| 20 | * **Block quotes** are blocks of text prefixed by '>'. |
| 21 | |
| 22 | * **Ordered list** items are prefixed by a number and a period. **Unordered list** items |
| 23 | are prefixed by a hyphen, asterisk or plus sign. Pre |
| 24 | |
| 25 | * **Code blocks** are formed by lines of text (possibly including empty lines) prefixed by |
| 26 | at least 4 spaces or a tab. |
| 27 | |
| 28 | * A **horizontal rule** is a line consisting of 3 or more asterisks, hyphens or underscores, |
| 29 | with optional whitespace between them. |
| 30 | |
| 31 | - Span elements |
| 32 | |
| 33 | * 3 types of **links** exist: |
| 34 | |
| 35 | - **automatic links** are URLs or email addresses enclosed in angle brackets |
| 36 | ('<' and '>'), and are displayed as such. |
| 37 | |
| 38 | - **inline links** consist of the displayed link text in squ |
| 39 | followed by the |
| 40 | |
| 41 | - **reference links** separate _link instance_ from _link definition_. A link instance efinition_. A link instance |
| 42 | consists of the displayed link text |
| 43 | in square brackets. in square brackets. |
| 44 | The corresponding link definition can occur anywhere on the page, and consists |
| 45 | of the link definition name in s a colon, whitespace and the |
| 46 | link target. |
| 47 | |
| 48 | * **Emphasis** can be given by wrapping text in one or two asterisks or underscores - use |
| 49 | one for HTML `<em>`, and two for `<strong>` emphasis. |
| 50 | |
| 51 | * A **code span** is text wrapped in backticks ('`'). |
| 52 | |
| 53 | * **Images** use a syntax much like inline or reference links, # Markdown formatting rules |
| 54 | |
| 55 | In addition to its native Wiki formatting syntax, Fossil supports Markdown syntax as specified by |
| 56 | [John Gruber's original Markdown implementation](http://daringfireball.net/projects/markdown/). |
| 57 | For lots of examples - not repeated here - please refer to its |
| 58 | [syntax description](http://daringfireball.net/projects/markdown/syntax), of which the page you |
| 59 | are reading is an extract. |
| 60 | |
| 61 | This page itself uses Markdown formatting. |
| 62 | |
| 63 | ## Summary |
| 64 | |
| 65 | - Block elements |
| 66 | |
| 67 | * A **paragraph** is a group of consecutive lines. Paragraphs are separated by blank lines. |
| 68 | |
| 69 | * A **Header** is a line of text underlined with equal signs or hyphens, or prefixed by a |
| 70 | number of hash marks. |
| 71 | |
| 72 | * **Block quotes** are blocks of text prefixed by '>'. |
| 73 | |
| 74 | * **Ordered list** items are prefixed by a number and a period. **Unordered list** items |
| 75 | are prefixed by a hyphen, asterisk or plus sign. Prefix and item text are separated by |
| 76 | whitespace. |
| 77 | |
| 78 | * **Code blocks** are formed by lines of text (possibly including empty lines) prefixed by |
| 79 | at least 4 spaces or a tab. |
| 80 | |
| 81 | * A **horizontal rule** is a line consisting of 3 or more asterisks, hyphens or underscores, |
| 82 | with optional whitespace between them. |
| 83 | |
| 84 | - Span elements |
| 85 | |
| 86 | * 3 types of **links** exist: |
| 87 | |
| 88 | - **automatic links** are URLs or email addresses enclosed in angle brackets |
| 89 | a * **Emphasis** can be given by wrapping text in one or two asterisks or underscores - use |
| 90 | one for HTML `<em>`, and two for `<strong>` emphasis. |
| 91 | |
| 92 | * A **code span** is text wrapped in backticks ('`'). |
| 93 | |
| 94 | * **Images** use a syntax much like inline or reference links, but with alt attribute text |
| 95 | ('img alt=...') instead of link text, and the first pair of square |
| 96 | brackets m prefix; the items will be |
| 97 | renumbered during rendering. However, future implementations may |
| 98 | for the first item in a list indicates an offset to be used for subsequent items. |
| 99 | |
| 100 | For list items spanning multiple lines, subsequent lines can be indented using an arbitrary amount |
| 101 | of whitespace. |
| 102 | |
| 103 | List items will be wrapped in HTML `<p>` tags if they are separated by blank lines. |
| 104 | |
| 105 | A list item may span multiple paragraphs. At least the first line |
| 106 | be indented using at least 4 spaces or a tab character. |
| 107 | |
| 108 | Block quotes within list items must have their '>' delimiters indented using 4 up to 7 spaces. |
| 109 | |
| 110 | Code blocks within list items need to be indented _twice_, that is, using 8 spaces or 2 tab |
| 111 | characters. |
| 112 | |
| 113 | ### Code blocks |
| 114 | |
| 115 | Lines within a code block are rendered verbatim using HTML `<pre>` and `<code>` tags, except that |
| 116 | HTML punctuation characters like '<' and '&' are automatically converted to HTML entities. Thus, |
| 117 | there is no need to explicitly escape HTML syntax within a code block. |
| 118 | |
| 119 | A code block runs until the first non blank line with indent less than 4 spaces or 1 tab character. |
| 120 | |
| 121 | |
| 122 | Regular Markdown syntax is not processed within code blocks. |
| 123 | |
| 124 | ### Links |
| 125 | |
| 126 | #### Automatic links |
| 127 | |
| 128 | When rendering automatic links to email addresses, HTML enco |
| 129 | prevent some spambots from harvesting. |
| 130 | |
| 131 | #### Inline links |
| 132 | |
| 133 | Links to resources on the same server can use relative paths (i.e. can start with a '/'). |
| 134 | |
| 135 | An optional title for the link (e.g. to have mouseover text in the b rowser) may be given behind |
| 136 | the link target but within the parentheses, in single and double quo |
| 137 | link target by whitespace. |
| 138 | link target by whitespace. |
| 139 | |
| 140 | # reference link consists of |
| 141 | > |
| 142 | > - one or more _link instances_ at appropriate locations in the page text |
| 143 | > - a single _link definition_ at an arbit |
| 144 | > During rendering, each link instance is resolved, and the corresponding definition is |
| 145 | > filled in. No separate link definition clauses occu r in the rendered output. |
| 146 | > |
| 147 | > There are 3 fields involved in link instances and definitions: |
| 148 | > |
| 149 | > - link text (i.e. the text that is displayed at the resulting link) |
| 150 | > - link definition name (i.e. an unique ID binding link instances to link definition) |
| 151 | > - link target (a target URL for the link) |
| 152 | |
| 153 | Multiple link instances may reference the same link definition using its link definition |
| 154 | name. |
| 155 | |
| 156 | Link definition names are case insensitive, and may contain letters, numbers, spaces and |
| 157 | punctuation. |
| 158 | |
| 159 | ##### Link instance |
| 160 | |
| 161 | A space may be inserted between the bracket pairs for link text and link definition name. |
| 162 | |
| 163 | A link instance can use an _implicit link definition name_ shortcut, in which case the link |
| 164 | text is used as the link definition name. The second set of brackets then remains empty, e.g. |
| 165 | '[Google][]' ('Google' being used as both link text and link definition name). |
| 166 | |
| 167 | ##### Link definition |
| 168 | |
| 169 | The first bracket pair containing the link definition name may be indented using up to 3 spaces. |
| 170 | |
| 171 | The link target may optionally be surrounded by angle brackets ('<' and '>'). |
| 172 | |
| 173 | A link target may be followed by an optional title (e.g. to have mouseover text in the browser). |
| 174 | This title may be enclosed in parentheses, single or double quotes. |
| 175 | |
| 176 | Link definitions may be split into 2 lines, with the title on the second line, arbitrarily |
| 177 | indented. This may be more visually pleasing when using long link targets. |
| 178 | |
| 179 | ### Emphasis |
| 180 | |
| 181 | The same character(s) used for starting the emphasis must be used to end it; don't mix |
| 182 | asterisks and underscores. |
| 183 | |
| 184 | Emphasis can be used in the middle of a word. That is, there need not be whitespace on either |
| 185 | side of emphasis start or end punctuation characters. |
| 186 | |
| 187 | ### Code spans |
| 188 | |
| 189 | To include a literal backtick character in a code span, use multiple backticks as opening and |
| 190 | closing delimiters. |
| 191 | |
| 192 | Whitespace may exist immediately after the opening delimiter and b Markdown formatting rules |
| 193 | |
| 194 | In addition to its native Wiki formatting syntax, Fossil supports Markdown syntax as specified by |
| 195 | [John Gruber's original Markdown implementation](http://daringfireball.net/projects/markdown/). |
| 196 | For lots of examples - not repeated here - please refer to its |
| 197 | [syntax description](http://daringfireball.net/projects/markdownr |
| 198 | a HTML block level construct (`<div>`, `<table>` etc) must be separated from surrounding |
| 199 | context using blank lines, and must both occur at the start of a line. |
| 200 | |
| 201 | No extra unwanted `<p>` HTML tags are added around HTML block level tags. |
| 202 | |
| 203 | Markdown formatting within HTML block level tags is not processed; however, formatting within |
| 204 | span level tags (e.g. `<mark>`) is processed normally. |
| 205 | |
| 206 | ### Escaping Markdown punctuation |
| 207 | |
| 208 | The following punctuation characters can be escaped using backslash: |
| 209 | |
| 210 | - \\ backslash |
| 211 | - ` backtick |
| 212 | - * asterisk |
| 213 | - _ underscore |
| 214 | - {} curly braces |
| 215 | - [] square brackets |
| 216 | - () parentheses |
| 217 | - # hash mark |
| 218 | - + plus sign |
| 219 | - - minus sign (hyphen) |
| 220 | - . dot |
| 221 | - ! exclamation mark |
| 222 | |
| 223 | To render a literal backslash, use 2 backslashes ('\\\\'). |
| 224 |
+5
-5
| --- src/md5.c | ||
| +++ src/md5.c | ||
| @@ -177,11 +177,11 @@ | ||
| 177 | 177 | |
| 178 | 178 | /* |
| 179 | 179 | * Update context to reflect the concatenation of another buffer full |
| 180 | 180 | * of bytes. |
| 181 | 181 | */ |
| 182 | -static | |
| 182 | +static | |
| 183 | 183 | void MD5Update(MD5Context *pCtx, const unsigned char *buf, unsigned int len){ |
| 184 | 184 | struct Context *ctx = (struct Context *)pCtx; |
| 185 | 185 | uint32 t; |
| 186 | 186 | |
| 187 | 187 | /* Update bitcount */ |
| @@ -224,11 +224,11 @@ | ||
| 224 | 224 | |
| 225 | 225 | memcpy(ctx->in, buf, len); |
| 226 | 226 | } |
| 227 | 227 | |
| 228 | 228 | /* |
| 229 | - * Final wrapup - pad to 64-byte boundary with the bit pattern | |
| 229 | + * Final wrapup - pad to 64-byte boundary with the bit pattern | |
| 230 | 230 | * 1 0* (64-bit count of bits processed, MSB-first) |
| 231 | 231 | */ |
| 232 | 232 | static void MD5Final(unsigned char digest[16], MD5Context *pCtx){ |
| 233 | 233 | struct Context *ctx = (struct Context *)pCtx; |
| 234 | 234 | unsigned count; |
| @@ -274,11 +274,11 @@ | ||
| 274 | 274 | ** "unsigned char digest[16]" in the calling function. The MD5 |
| 275 | 275 | ** digest is stored in the first 16 bytes. zBuf should |
| 276 | 276 | ** be "char zBuf[33]". |
| 277 | 277 | */ |
| 278 | 278 | static void DigestToBase16(unsigned char *digest, char *zBuf){ |
| 279 | - static char const zEncode[] = "0123456789abcdef"; | |
| 279 | + static const char zEncode[] = "0123456789abcdef"; | |
| 280 | 280 | int i, j; |
| 281 | 281 | |
| 282 | 282 | for(j=i=0; i<16; i++){ |
| 283 | 283 | int a = digest[i]; |
| 284 | 284 | zBuf[j++] = zEncode[(a>>4)&0xf]; |
| @@ -343,11 +343,11 @@ | ||
| 343 | 343 | return zResult; |
| 344 | 344 | } |
| 345 | 345 | |
| 346 | 346 | /* |
| 347 | 347 | ** Finish the incremental MD5 checksum. Store the result in blob pOut |
| 348 | -** if pOut!=0. Also return a pointer to the result. | |
| 348 | +** if pOut!=0. Also return a pointer to the result. | |
| 349 | 349 | ** |
| 350 | 350 | ** This resets the incremental checksum preparing for the next round |
| 351 | 351 | ** of computation. The return pointer points to a static buffer that |
| 352 | 352 | ** is overwritten by subsequent calls to this function. |
| 353 | 353 | */ |
| @@ -431,11 +431,11 @@ | ||
| 431 | 431 | */ |
| 432 | 432 | void md5sum_test(void){ |
| 433 | 433 | int i; |
| 434 | 434 | Blob in; |
| 435 | 435 | Blob cksum; |
| 436 | - | |
| 436 | + | |
| 437 | 437 | for(i=2; i<g.argc; i++){ |
| 438 | 438 | blob_init(&cksum, "********** not found ***********", -1); |
| 439 | 439 | if( g.argv[i][0]=='-' && g.argv[i][1]==0 ){ |
| 440 | 440 | blob_read_from_channel(&in, stdin, -1); |
| 441 | 441 | md5sum_blob(&in, &cksum); |
| 442 | 442 |
| --- src/md5.c | |
| +++ src/md5.c | |
| @@ -177,11 +177,11 @@ | |
| 177 | |
| 178 | /* |
| 179 | * Update context to reflect the concatenation of another buffer full |
| 180 | * of bytes. |
| 181 | */ |
| 182 | static |
| 183 | void MD5Update(MD5Context *pCtx, const unsigned char *buf, unsigned int len){ |
| 184 | struct Context *ctx = (struct Context *)pCtx; |
| 185 | uint32 t; |
| 186 | |
| 187 | /* Update bitcount */ |
| @@ -224,11 +224,11 @@ | |
| 224 | |
| 225 | memcpy(ctx->in, buf, len); |
| 226 | } |
| 227 | |
| 228 | /* |
| 229 | * Final wrapup - pad to 64-byte boundary with the bit pattern |
| 230 | * 1 0* (64-bit count of bits processed, MSB-first) |
| 231 | */ |
| 232 | static void MD5Final(unsigned char digest[16], MD5Context *pCtx){ |
| 233 | struct Context *ctx = (struct Context *)pCtx; |
| 234 | unsigned count; |
| @@ -274,11 +274,11 @@ | |
| 274 | ** "unsigned char digest[16]" in the calling function. The MD5 |
| 275 | ** digest is stored in the first 16 bytes. zBuf should |
| 276 | ** be "char zBuf[33]". |
| 277 | */ |
| 278 | static void DigestToBase16(unsigned char *digest, char *zBuf){ |
| 279 | static char const zEncode[] = "0123456789abcdef"; |
| 280 | int i, j; |
| 281 | |
| 282 | for(j=i=0; i<16; i++){ |
| 283 | int a = digest[i]; |
| 284 | zBuf[j++] = zEncode[(a>>4)&0xf]; |
| @@ -343,11 +343,11 @@ | |
| 343 | return zResult; |
| 344 | } |
| 345 | |
| 346 | /* |
| 347 | ** Finish the incremental MD5 checksum. Store the result in blob pOut |
| 348 | ** if pOut!=0. Also return a pointer to the result. |
| 349 | ** |
| 350 | ** This resets the incremental checksum preparing for the next round |
| 351 | ** of computation. The return pointer points to a static buffer that |
| 352 | ** is overwritten by subsequent calls to this function. |
| 353 | */ |
| @@ -431,11 +431,11 @@ | |
| 431 | */ |
| 432 | void md5sum_test(void){ |
| 433 | int i; |
| 434 | Blob in; |
| 435 | Blob cksum; |
| 436 | |
| 437 | for(i=2; i<g.argc; i++){ |
| 438 | blob_init(&cksum, "********** not found ***********", -1); |
| 439 | if( g.argv[i][0]=='-' && g.argv[i][1]==0 ){ |
| 440 | blob_read_from_channel(&in, stdin, -1); |
| 441 | md5sum_blob(&in, &cksum); |
| 442 |
| --- src/md5.c | |
| +++ src/md5.c | |
| @@ -177,11 +177,11 @@ | |
| 177 | |
| 178 | /* |
| 179 | * Update context to reflect the concatenation of another buffer full |
| 180 | * of bytes. |
| 181 | */ |
| 182 | static |
| 183 | void MD5Update(MD5Context *pCtx, const unsigned char *buf, unsigned int len){ |
| 184 | struct Context *ctx = (struct Context *)pCtx; |
| 185 | uint32 t; |
| 186 | |
| 187 | /* Update bitcount */ |
| @@ -224,11 +224,11 @@ | |
| 224 | |
| 225 | memcpy(ctx->in, buf, len); |
| 226 | } |
| 227 | |
| 228 | /* |
| 229 | * Final wrapup - pad to 64-byte boundary with the bit pattern |
| 230 | * 1 0* (64-bit count of bits processed, MSB-first) |
| 231 | */ |
| 232 | static void MD5Final(unsigned char digest[16], MD5Context *pCtx){ |
| 233 | struct Context *ctx = (struct Context *)pCtx; |
| 234 | unsigned count; |
| @@ -274,11 +274,11 @@ | |
| 274 | ** "unsigned char digest[16]" in the calling function. The MD5 |
| 275 | ** digest is stored in the first 16 bytes. zBuf should |
| 276 | ** be "char zBuf[33]". |
| 277 | */ |
| 278 | static void DigestToBase16(unsigned char *digest, char *zBuf){ |
| 279 | static const char zEncode[] = "0123456789abcdef"; |
| 280 | int i, j; |
| 281 | |
| 282 | for(j=i=0; i<16; i++){ |
| 283 | int a = digest[i]; |
| 284 | zBuf[j++] = zEncode[(a>>4)&0xf]; |
| @@ -343,11 +343,11 @@ | |
| 343 | return zResult; |
| 344 | } |
| 345 | |
| 346 | /* |
| 347 | ** Finish the incremental MD5 checksum. Store the result in blob pOut |
| 348 | ** if pOut!=0. Also return a pointer to the result. |
| 349 | ** |
| 350 | ** This resets the incremental checksum preparing for the next round |
| 351 | ** of computation. The return pointer points to a static buffer that |
| 352 | ** is overwritten by subsequent calls to this function. |
| 353 | */ |
| @@ -431,11 +431,11 @@ | |
| 431 | */ |
| 432 | void md5sum_test(void){ |
| 433 | int i; |
| 434 | Blob in; |
| 435 | Blob cksum; |
| 436 | |
| 437 | for(i=2; i<g.argc; i++){ |
| 438 | blob_init(&cksum, "********** not found ***********", -1); |
| 439 | if( g.argv[i][0]=='-' && g.argv[i][1]==0 ){ |
| 440 | blob_read_from_channel(&in, stdin, -1); |
| 441 | md5sum_blob(&in, &cksum); |
| 442 |
+11
-12
| --- src/mkbuiltin.c | ||
| +++ src/mkbuiltin.c | ||
| @@ -80,15 +80,22 @@ | ||
| 80 | 80 | |
| 81 | 81 | int main(int argc, char **argv){ |
| 82 | 82 | int i, sz; |
| 83 | 83 | int j, n; |
| 84 | 84 | Resource *aRes; |
| 85 | - int nRes = argc-1; | |
| 85 | + int nRes; | |
| 86 | 86 | unsigned char *pData; |
| 87 | 87 | int nErr = 0; |
| 88 | 88 | int nSkip; |
| 89 | + int nPrefix = 0; | |
| 89 | 90 | |
| 91 | + if( argc>3 && strcmp(argv[1],"--prefix")==0 ){ | |
| 92 | + nPrefix = (int)strlen(argv[2]); | |
| 93 | + argc -= 2; | |
| 94 | + argv += 2; | |
| 95 | + } | |
| 96 | + nRes = argc - 1; | |
| 90 | 97 | aRes = malloc( nRes*sizeof(aRes[0]) ); |
| 91 | 98 | if( aRes==0 ){ |
| 92 | 99 | fprintf(stderr, "malloc failed\n"); |
| 93 | 100 | return 1; |
| 94 | 101 | } |
| @@ -141,25 +148,17 @@ | ||
| 141 | 148 | printf(" int nByte;\n"); |
| 142 | 149 | printf("};\n"); |
| 143 | 150 | printf("static const BuiltinFileTable aBuiltinFiles[] = {\n"); |
| 144 | 151 | for(i=0; i<nRes; i++){ |
| 145 | 152 | const char *z = aRes[i].zName; |
| 146 | - const char *zTail; | |
| 147 | - int nSlash = 0; | |
| 148 | - zTail = z; | |
| 149 | - while( z && z[0] ){ | |
| 150 | - if( z[0]=='/' || z[0]=='\\' ){ | |
| 151 | - nSlash++; | |
| 152 | - if( nSlash<=2 || z[-1]=='.' ) zTail = &z[1]; | |
| 153 | - } | |
| 154 | - z++; | |
| 155 | - } | |
| 156 | - aRes[i].zName = zTail; | |
| 153 | + if( strlen(z)>=nPrefix ) z += nPrefix; | |
| 154 | + while( z[0]=='.' || z[0]=='/' ){ z++; } | |
| 155 | + aRes[i].zName = z; | |
| 157 | 156 | } |
| 158 | 157 | qsort(aRes, nRes, sizeof(aRes[0]), compareResource); |
| 159 | 158 | for(i=0; i<nRes; i++){ |
| 160 | 159 | printf(" { \"%s\", bidata%d, %d },\n", |
| 161 | 160 | aRes[i].zName, aRes[i].idx, aRes[i].nByte); |
| 162 | 161 | } |
| 163 | 162 | printf("};\n"); |
| 164 | 163 | return nErr; |
| 165 | 164 | } |
| 166 | 165 |
| --- src/mkbuiltin.c | |
| +++ src/mkbuiltin.c | |
| @@ -80,15 +80,22 @@ | |
| 80 | |
| 81 | int main(int argc, char **argv){ |
| 82 | int i, sz; |
| 83 | int j, n; |
| 84 | Resource *aRes; |
| 85 | int nRes = argc-1; |
| 86 | unsigned char *pData; |
| 87 | int nErr = 0; |
| 88 | int nSkip; |
| 89 | |
| 90 | aRes = malloc( nRes*sizeof(aRes[0]) ); |
| 91 | if( aRes==0 ){ |
| 92 | fprintf(stderr, "malloc failed\n"); |
| 93 | return 1; |
| 94 | } |
| @@ -141,25 +148,17 @@ | |
| 141 | printf(" int nByte;\n"); |
| 142 | printf("};\n"); |
| 143 | printf("static const BuiltinFileTable aBuiltinFiles[] = {\n"); |
| 144 | for(i=0; i<nRes; i++){ |
| 145 | const char *z = aRes[i].zName; |
| 146 | const char *zTail; |
| 147 | int nSlash = 0; |
| 148 | zTail = z; |
| 149 | while( z && z[0] ){ |
| 150 | if( z[0]=='/' || z[0]=='\\' ){ |
| 151 | nSlash++; |
| 152 | if( nSlash<=2 || z[-1]=='.' ) zTail = &z[1]; |
| 153 | } |
| 154 | z++; |
| 155 | } |
| 156 | aRes[i].zName = zTail; |
| 157 | } |
| 158 | qsort(aRes, nRes, sizeof(aRes[0]), compareResource); |
| 159 | for(i=0; i<nRes; i++){ |
| 160 | printf(" { \"%s\", bidata%d, %d },\n", |
| 161 | aRes[i].zName, aRes[i].idx, aRes[i].nByte); |
| 162 | } |
| 163 | printf("};\n"); |
| 164 | return nErr; |
| 165 | } |
| 166 |
| --- src/mkbuiltin.c | |
| +++ src/mkbuiltin.c | |
| @@ -80,15 +80,22 @@ | |
| 80 | |
| 81 | int main(int argc, char **argv){ |
| 82 | int i, sz; |
| 83 | int j, n; |
| 84 | Resource *aRes; |
| 85 | int nRes; |
| 86 | unsigned char *pData; |
| 87 | int nErr = 0; |
| 88 | int nSkip; |
| 89 | int nPrefix = 0; |
| 90 | |
| 91 | if( argc>3 && strcmp(argv[1],"--prefix")==0 ){ |
| 92 | nPrefix = (int)strlen(argv[2]); |
| 93 | argc -= 2; |
| 94 | argv += 2; |
| 95 | } |
| 96 | nRes = argc - 1; |
| 97 | aRes = malloc( nRes*sizeof(aRes[0]) ); |
| 98 | if( aRes==0 ){ |
| 99 | fprintf(stderr, "malloc failed\n"); |
| 100 | return 1; |
| 101 | } |
| @@ -141,25 +148,17 @@ | |
| 148 | printf(" int nByte;\n"); |
| 149 | printf("};\n"); |
| 150 | printf("static const BuiltinFileTable aBuiltinFiles[] = {\n"); |
| 151 | for(i=0; i<nRes; i++){ |
| 152 | const char *z = aRes[i].zName; |
| 153 | if( strlen(z)>=nPrefix ) z += nPrefix; |
| 154 | while( z[0]=='.' || z[0]=='/' ){ z++; } |
| 155 | aRes[i].zName = z; |
| 156 | } |
| 157 | qsort(aRes, nRes, sizeof(aRes[0]), compareResource); |
| 158 | for(i=0; i<nRes; i++){ |
| 159 | printf(" { \"%s\", bidata%d, %d },\n", |
| 160 | aRes[i].zName, aRes[i].idx, aRes[i].nByte); |
| 161 | } |
| 162 | printf("};\n"); |
| 163 | return nErr; |
| 164 | } |
| 165 |
+9
-9
| --- src/regexp.c | ||
| +++ src/regexp.c | ||
| @@ -127,11 +127,11 @@ | ||
| 127 | 127 | pSet->aState[pSet->nState++] = newState; |
| 128 | 128 | } |
| 129 | 129 | |
| 130 | 130 | /* Extract the next unicode character from *pzIn and return it. Advance |
| 131 | 131 | ** *pzIn to the first byte past the end of the character returned. To |
| 132 | -** be clear: this routine converts utf8 to unicode. This routine is | |
| 132 | +** be clear: this routine converts utf8 to unicode. This routine is | |
| 133 | 133 | ** optimized for the common case where the next character is a single byte. |
| 134 | 134 | */ |
| 135 | 135 | static unsigned re_next_char(ReInput *p){ |
| 136 | 136 | unsigned c; |
| 137 | 137 | if( p->i>=p->mx ) return 0; |
| @@ -191,16 +191,16 @@ | ||
| 191 | 191 | int rc = 0; |
| 192 | 192 | ReInput in; |
| 193 | 193 | |
| 194 | 194 | in.z = zIn; |
| 195 | 195 | in.i = 0; |
| 196 | - in.mx = nIn>=0 ? nIn : strlen((char const*)zIn); | |
| 196 | + in.mx = nIn>=0 ? nIn : strlen((const char*)zIn); | |
| 197 | 197 | |
| 198 | 198 | /* Look for the initial prefix match, if there is one. */ |
| 199 | 199 | if( pRe->nInit ){ |
| 200 | 200 | unsigned char x = pRe->zInit[0]; |
| 201 | - while( in.i+pRe->nInit<=in.mx | |
| 201 | + while( in.i+pRe->nInit<=in.mx | |
| 202 | 202 | && (zIn[in.i]!=x || |
| 203 | 203 | strncmp((const char*)zIn+in.i, (const char*)pRe->zInit, pRe->nInit)!=0) |
| 204 | 204 | ){ |
| 205 | 205 | in.i++; |
| 206 | 206 | } |
| @@ -303,11 +303,11 @@ | ||
| 303 | 303 | } |
| 304 | 304 | } |
| 305 | 305 | } |
| 306 | 306 | if( pRe->aOp[x]==RE_OP_CC_EXC ) hit = !hit; |
| 307 | 307 | if( hit ) re_add_state(pNext, x+n); |
| 308 | - break; | |
| 308 | + break; | |
| 309 | 309 | } |
| 310 | 310 | } |
| 311 | 311 | } |
| 312 | 312 | } |
| 313 | 313 | for(i=0; i<pNext->nState; i++){ |
| @@ -464,11 +464,11 @@ | ||
| 464 | 464 | const char *zErr; |
| 465 | 465 | while( (c = p->xNextChar(&p->sIn))!=0 ){ |
| 466 | 466 | iStart = p->nState; |
| 467 | 467 | switch( c ){ |
| 468 | 468 | case '|': |
| 469 | - case '$': | |
| 469 | + case '$': | |
| 470 | 470 | case ')': { |
| 471 | 471 | p->sIn.i--; |
| 472 | 472 | return 0; |
| 473 | 473 | } |
| 474 | 474 | case '(': { |
| @@ -480,11 +480,11 @@ | ||
| 480 | 480 | } |
| 481 | 481 | case '.': { |
| 482 | 482 | if( rePeek(p)=='*' ){ |
| 483 | 483 | re_append(p, RE_OP_ANYSTAR, 0); |
| 484 | 484 | p->sIn.i++; |
| 485 | - }else{ | |
| 485 | + }else{ | |
| 486 | 486 | re_append(p, RE_OP_ANY, 0); |
| 487 | 487 | } |
| 488 | 488 | break; |
| 489 | 489 | } |
| 490 | 490 | case '*': { |
| @@ -652,11 +652,11 @@ | ||
| 652 | 652 | } |
| 653 | 653 | |
| 654 | 654 | /* The following is a performance optimization. If the regex begins with |
| 655 | 655 | ** ".*" (if the input regex lacks an initial "^") and afterwards there are |
| 656 | 656 | ** one or more matching characters, enter those matching characters into |
| 657 | - ** zInit[]. The re_match() routine can then search ahead in the input | |
| 657 | + ** zInit[]. The re_match() routine can then search ahead in the input | |
| 658 | 658 | ** string looking for the initial match without having to run the whole |
| 659 | 659 | ** regex engine over the string. Do not worry able trying to match |
| 660 | 660 | ** unicode characters beyond plane 0 - those are very rare and this is |
| 661 | 661 | ** just an optimization. */ |
| 662 | 662 | if( pRe->aOp[0]==RE_OP_ANYSTAR ){ |
| @@ -689,12 +689,12 @@ | ||
| 689 | 689 | ** A REGEXP B |
| 690 | 690 | ** |
| 691 | 691 | ** is implemented as regexp(B,A). |
| 692 | 692 | */ |
| 693 | 693 | static void re_sql_func( |
| 694 | - sqlite3_context *context, | |
| 695 | - int argc, | |
| 694 | + sqlite3_context *context, | |
| 695 | + int argc, | |
| 696 | 696 | sqlite3_value **argv |
| 697 | 697 | ){ |
| 698 | 698 | ReCompiled *pRe; /* Compiled regular expression */ |
| 699 | 699 | const char *zPattern; /* The regular expression */ |
| 700 | 700 | const unsigned char *zStr;/* String being searched */ |
| 701 | 701 |
| --- src/regexp.c | |
| +++ src/regexp.c | |
| @@ -127,11 +127,11 @@ | |
| 127 | pSet->aState[pSet->nState++] = newState; |
| 128 | } |
| 129 | |
| 130 | /* Extract the next unicode character from *pzIn and return it. Advance |
| 131 | ** *pzIn to the first byte past the end of the character returned. To |
| 132 | ** be clear: this routine converts utf8 to unicode. This routine is |
| 133 | ** optimized for the common case where the next character is a single byte. |
| 134 | */ |
| 135 | static unsigned re_next_char(ReInput *p){ |
| 136 | unsigned c; |
| 137 | if( p->i>=p->mx ) return 0; |
| @@ -191,16 +191,16 @@ | |
| 191 | int rc = 0; |
| 192 | ReInput in; |
| 193 | |
| 194 | in.z = zIn; |
| 195 | in.i = 0; |
| 196 | in.mx = nIn>=0 ? nIn : strlen((char const*)zIn); |
| 197 | |
| 198 | /* Look for the initial prefix match, if there is one. */ |
| 199 | if( pRe->nInit ){ |
| 200 | unsigned char x = pRe->zInit[0]; |
| 201 | while( in.i+pRe->nInit<=in.mx |
| 202 | && (zIn[in.i]!=x || |
| 203 | strncmp((const char*)zIn+in.i, (const char*)pRe->zInit, pRe->nInit)!=0) |
| 204 | ){ |
| 205 | in.i++; |
| 206 | } |
| @@ -303,11 +303,11 @@ | |
| 303 | } |
| 304 | } |
| 305 | } |
| 306 | if( pRe->aOp[x]==RE_OP_CC_EXC ) hit = !hit; |
| 307 | if( hit ) re_add_state(pNext, x+n); |
| 308 | break; |
| 309 | } |
| 310 | } |
| 311 | } |
| 312 | } |
| 313 | for(i=0; i<pNext->nState; i++){ |
| @@ -464,11 +464,11 @@ | |
| 464 | const char *zErr; |
| 465 | while( (c = p->xNextChar(&p->sIn))!=0 ){ |
| 466 | iStart = p->nState; |
| 467 | switch( c ){ |
| 468 | case '|': |
| 469 | case '$': |
| 470 | case ')': { |
| 471 | p->sIn.i--; |
| 472 | return 0; |
| 473 | } |
| 474 | case '(': { |
| @@ -480,11 +480,11 @@ | |
| 480 | } |
| 481 | case '.': { |
| 482 | if( rePeek(p)=='*' ){ |
| 483 | re_append(p, RE_OP_ANYSTAR, 0); |
| 484 | p->sIn.i++; |
| 485 | }else{ |
| 486 | re_append(p, RE_OP_ANY, 0); |
| 487 | } |
| 488 | break; |
| 489 | } |
| 490 | case '*': { |
| @@ -652,11 +652,11 @@ | |
| 652 | } |
| 653 | |
| 654 | /* The following is a performance optimization. If the regex begins with |
| 655 | ** ".*" (if the input regex lacks an initial "^") and afterwards there are |
| 656 | ** one or more matching characters, enter those matching characters into |
| 657 | ** zInit[]. The re_match() routine can then search ahead in the input |
| 658 | ** string looking for the initial match without having to run the whole |
| 659 | ** regex engine over the string. Do not worry able trying to match |
| 660 | ** unicode characters beyond plane 0 - those are very rare and this is |
| 661 | ** just an optimization. */ |
| 662 | if( pRe->aOp[0]==RE_OP_ANYSTAR ){ |
| @@ -689,12 +689,12 @@ | |
| 689 | ** A REGEXP B |
| 690 | ** |
| 691 | ** is implemented as regexp(B,A). |
| 692 | */ |
| 693 | static void re_sql_func( |
| 694 | sqlite3_context *context, |
| 695 | int argc, |
| 696 | sqlite3_value **argv |
| 697 | ){ |
| 698 | ReCompiled *pRe; /* Compiled regular expression */ |
| 699 | const char *zPattern; /* The regular expression */ |
| 700 | const unsigned char *zStr;/* String being searched */ |
| 701 |
| --- src/regexp.c | |
| +++ src/regexp.c | |
| @@ -127,11 +127,11 @@ | |
| 127 | pSet->aState[pSet->nState++] = newState; |
| 128 | } |
| 129 | |
| 130 | /* Extract the next unicode character from *pzIn and return it. Advance |
| 131 | ** *pzIn to the first byte past the end of the character returned. To |
| 132 | ** be clear: this routine converts utf8 to unicode. This routine is |
| 133 | ** optimized for the common case where the next character is a single byte. |
| 134 | */ |
| 135 | static unsigned re_next_char(ReInput *p){ |
| 136 | unsigned c; |
| 137 | if( p->i>=p->mx ) return 0; |
| @@ -191,16 +191,16 @@ | |
| 191 | int rc = 0; |
| 192 | ReInput in; |
| 193 | |
| 194 | in.z = zIn; |
| 195 | in.i = 0; |
| 196 | in.mx = nIn>=0 ? nIn : strlen((const char*)zIn); |
| 197 | |
| 198 | /* Look for the initial prefix match, if there is one. */ |
| 199 | if( pRe->nInit ){ |
| 200 | unsigned char x = pRe->zInit[0]; |
| 201 | while( in.i+pRe->nInit<=in.mx |
| 202 | && (zIn[in.i]!=x || |
| 203 | strncmp((const char*)zIn+in.i, (const char*)pRe->zInit, pRe->nInit)!=0) |
| 204 | ){ |
| 205 | in.i++; |
| 206 | } |
| @@ -303,11 +303,11 @@ | |
| 303 | } |
| 304 | } |
| 305 | } |
| 306 | if( pRe->aOp[x]==RE_OP_CC_EXC ) hit = !hit; |
| 307 | if( hit ) re_add_state(pNext, x+n); |
| 308 | break; |
| 309 | } |
| 310 | } |
| 311 | } |
| 312 | } |
| 313 | for(i=0; i<pNext->nState; i++){ |
| @@ -464,11 +464,11 @@ | |
| 464 | const char *zErr; |
| 465 | while( (c = p->xNextChar(&p->sIn))!=0 ){ |
| 466 | iStart = p->nState; |
| 467 | switch( c ){ |
| 468 | case '|': |
| 469 | case '$': |
| 470 | case ')': { |
| 471 | p->sIn.i--; |
| 472 | return 0; |
| 473 | } |
| 474 | case '(': { |
| @@ -480,11 +480,11 @@ | |
| 480 | } |
| 481 | case '.': { |
| 482 | if( rePeek(p)=='*' ){ |
| 483 | re_append(p, RE_OP_ANYSTAR, 0); |
| 484 | p->sIn.i++; |
| 485 | }else{ |
| 486 | re_append(p, RE_OP_ANY, 0); |
| 487 | } |
| 488 | break; |
| 489 | } |
| 490 | case '*': { |
| @@ -652,11 +652,11 @@ | |
| 652 | } |
| 653 | |
| 654 | /* The following is a performance optimization. If the regex begins with |
| 655 | ** ".*" (if the input regex lacks an initial "^") and afterwards there are |
| 656 | ** one or more matching characters, enter those matching characters into |
| 657 | ** zInit[]. The re_match() routine can then search ahead in the input |
| 658 | ** string looking for the initial match without having to run the whole |
| 659 | ** regex engine over the string. Do not worry able trying to match |
| 660 | ** unicode characters beyond plane 0 - those are very rare and this is |
| 661 | ** just an optimization. */ |
| 662 | if( pRe->aOp[0]==RE_OP_ANYSTAR ){ |
| @@ -689,12 +689,12 @@ | |
| 689 | ** A REGEXP B |
| 690 | ** |
| 691 | ** is implemented as regexp(B,A). |
| 692 | */ |
| 693 | static void re_sql_func( |
| 694 | sqlite3_context *context, |
| 695 | int argc, |
| 696 | sqlite3_value **argv |
| 697 | ){ |
| 698 | ReCompiled *pRe; /* Compiled regular expression */ |
| 699 | const char *zPattern; /* The regular expression */ |
| 700 | const unsigned char *zStr;/* String being searched */ |
| 701 |
+32
-9
| --- src/schema.c | ||
| +++ src/schema.c | ||
| @@ -12,11 +12,11 @@ | ||
| 12 | 12 | ** Author contact information: |
| 13 | 13 | ** [email protected] |
| 14 | 14 | ** http://www.hwaci.com/drh/ |
| 15 | 15 | ** |
| 16 | 16 | ******************************************************************************* |
| 17 | -** | |
| 17 | +** | |
| 18 | 18 | ** This file contains string constants that implement the database schema. |
| 19 | 19 | */ |
| 20 | 20 | #include "config.h" |
| 21 | 21 | #include "schema.h" |
| 22 | 22 | |
| @@ -45,11 +45,14 @@ | ||
| 45 | 45 | ** we have to execute special procedures to update the schema. When |
| 46 | 46 | ** the aux schema changes, all we need to do is rebuild the database. |
| 47 | 47 | */ |
| 48 | 48 | #define CONTENT_SCHEMA "2" |
| 49 | 49 | #define AUX_SCHEMA_MIN "2011-04-25 19:50" |
| 50 | -#define AUX_SCHEMA_MAX "2014-11-24 20:35" | |
| 50 | +#define AUX_SCHEMA_MAX "2015-01-24" | |
| 51 | +/* NB: Some features require the latest schema. Warning or error messages | |
| 52 | +** will appear if an older schema is used. However, the older schemas are | |
| 53 | +** adequate for many common functions. */ | |
| 51 | 54 | |
| 52 | 55 | #endif /* INTERFACE */ |
| 53 | 56 | |
| 54 | 57 | |
| 55 | 58 | /* |
| @@ -81,11 +84,11 @@ | ||
| 81 | 84 | @ uuid TEXT UNIQUE NOT NULL, -- SHA1 hash of the content |
| 82 | 85 | @ content BLOB, -- Compressed content of this record |
| 83 | 86 | @ CHECK( length(uuid)==40 AND rid>0 ) |
| 84 | 87 | @ ); |
| 85 | 88 | @ CREATE TABLE delta( |
| 86 | -@ rid INTEGER PRIMARY KEY, -- BLOB that is delta-compressed | |
| 89 | +@ rid INTEGER PRIMARY KEY, -- BLOB that is delta-compressed | |
| 87 | 90 | @ srcid INTEGER NOT NULL REFERENCES blob -- Baseline for delta-compression |
| 88 | 91 | @ ); |
| 89 | 92 | @ CREATE INDEX delta_i1 ON delta(srcid); |
| 90 | 93 | @ |
| 91 | 94 | @ ------------------------------------------------------------------------- |
| @@ -227,21 +230,41 @@ | ||
| 227 | 230 | @ name TEXT UNIQUE -- Name of file page |
| 228 | 231 | @ ); |
| 229 | 232 | @ |
| 230 | 233 | @ -- Linkages between checkins, files created by each checkin, and |
| 231 | 234 | @ -- the names of those files. |
| 235 | +@ -- | |
| 236 | +@ -- Each entry represents a file that changed content from pid to fid | |
| 237 | +@ -- due to the check-in that goes from pmid to mid. fnid is the name | |
| 238 | +@ -- of the file in the mid check-in. If the file was renamed as part | |
| 239 | +@ -- of the mid check-in, then pfnid is the previous filename. | |
| 240 | +@ | |
| 241 | +@ -- There can be multiple entries for (mid,fid) if the mid checkin was | |
| 242 | +@ -- a merge. Entries with isaux==0 are from the primary parent. Merge | |
| 243 | +@ -- parents have isaux set to true. | |
| 244 | +@ -- | |
| 245 | +@ -- Field name mnemonics: | |
| 246 | +@ -- mid = Manifest ID. (Each check-in is stored as a "Manifest") | |
| 247 | +@ -- fid = File ID. | |
| 248 | +@ -- pmid = Parent Manifest ID. | |
| 249 | +@ -- pid = Parent file ID. | |
| 250 | +@ -- fnid = File Name ID. | |
| 251 | +@ -- pfnid = Parent File Name ID. | |
| 252 | +@ -- isaux = pmid IS AUXiliary parent, not primary parent | |
| 232 | 253 | @ -- |
| 233 | 254 | @ -- pid==0 if the file is added by checkin mid. |
| 234 | 255 | @ -- fid==0 if the file is removed by checkin mid. |
| 235 | 256 | @ -- |
| 236 | 257 | @ CREATE TABLE mlink( |
| 237 | -@ mid INTEGER REFERENCES blob, -- Manifest ID where change occurs | |
| 238 | -@ pid INTEGER REFERENCES blob, -- File ID in parent manifest | |
| 239 | -@ fid INTEGER REFERENCES blob, -- Changed file ID in this manifest | |
| 258 | +@ mid INTEGER REFERENCES plink(cid), -- Checkin that contains fid | |
| 259 | +@ fid INTEGER REFERENCES blob, -- New file content. 0 if deleted | |
| 260 | +@ pmid INTEGER REFERENCES plink(cid), -- Checkin that contains pid | |
| 261 | +@ pid INTEGER REFERENCES blob, -- Prev file content. 0 if new | |
| 240 | 262 | @ fnid INTEGER REFERENCES filename, -- Name of the file |
| 241 | 263 | @ pfnid INTEGER REFERENCES filename, -- Previous name. 0 if unchanged |
| 242 | -@ mperm INTEGER -- File permissions. 1==exec | |
| 264 | +@ mperm INTEGER, -- File permissions. 1==exec | |
| 265 | +@ isaux BOOLEAN DEFAULT 0 -- TRUE if pmid is the primary | |
| 243 | 266 | @ ); |
| 244 | 267 | @ CREATE INDEX mlink_i1 ON mlink(mid); |
| 245 | 268 | @ CREATE INDEX mlink_i2 ON mlink(fnid); |
| 246 | 269 | @ CREATE INDEX mlink_i3 ON mlink(fid); |
| 247 | 270 | @ CREATE INDEX mlink_i4 ON mlink(pid); |
| @@ -251,11 +274,11 @@ | ||
| 251 | 274 | @ CREATE TABLE plink( |
| 252 | 275 | @ pid INTEGER REFERENCES blob, -- Parent manifest |
| 253 | 276 | @ cid INTEGER REFERENCES blob, -- Child manifest |
| 254 | 277 | @ isprim BOOLEAN, -- pid is the primary parent of cid |
| 255 | 278 | @ mtime DATETIME, -- the date/time stamp on cid. Julian day. |
| 256 | -@ baseid INTEGER REFERENCES blob, -- Baseline if child is a delta manifest | |
| 279 | +@ baseid INTEGER REFERENCES blob, -- Baseline if cid is a delta manifest. | |
| 257 | 280 | @ UNIQUE(pid, cid) |
| 258 | 281 | @ ); |
| 259 | 282 | @ CREATE INDEX plink_i2 ON plink(cid,pid); |
| 260 | 283 | @ |
| 261 | 284 | @ -- A "leaf" checkin is a checkin that has no children in the same |
| @@ -488,11 +511,11 @@ | ||
| 488 | 511 | @ -- current version of the file is already in the repository. |
| 489 | 512 | @ -- |
| 490 | 513 | @ CREATE TABLE vfile( |
| 491 | 514 | @ id INTEGER PRIMARY KEY, -- ID of the checked out file |
| 492 | 515 | @ vid INTEGER REFERENCES blob, -- The baseline this file is part of. |
| 493 | -@ chnged INT DEFAULT 0, -- 0:unchnged 1:edited 2:m-chng 3:m-add 4:i-chng 5:i-add | |
| 516 | +@ chnged INT DEFAULT 0, -- 0:unchng 1:edit 2:m-chng 3:m-add 4:i-chng 5:i-add | |
| 494 | 517 | @ deleted BOOLEAN DEFAULT 0, -- True if deleted |
| 495 | 518 | @ isexe BOOLEAN, -- True if file should be executable |
| 496 | 519 | @ islink BOOLEAN, -- True if file should be symlink |
| 497 | 520 | @ rid INTEGER, -- Originally from this repository record |
| 498 | 521 | @ mrid INTEGER, -- Based on this record due to a merge |
| 499 | 522 |
| --- src/schema.c | |
| +++ src/schema.c | |
| @@ -12,11 +12,11 @@ | |
| 12 | ** Author contact information: |
| 13 | ** [email protected] |
| 14 | ** http://www.hwaci.com/drh/ |
| 15 | ** |
| 16 | ******************************************************************************* |
| 17 | ** |
| 18 | ** This file contains string constants that implement the database schema. |
| 19 | */ |
| 20 | #include "config.h" |
| 21 | #include "schema.h" |
| 22 | |
| @@ -45,11 +45,14 @@ | |
| 45 | ** we have to execute special procedures to update the schema. When |
| 46 | ** the aux schema changes, all we need to do is rebuild the database. |
| 47 | */ |
| 48 | #define CONTENT_SCHEMA "2" |
| 49 | #define AUX_SCHEMA_MIN "2011-04-25 19:50" |
| 50 | #define AUX_SCHEMA_MAX "2014-11-24 20:35" |
| 51 | |
| 52 | #endif /* INTERFACE */ |
| 53 | |
| 54 | |
| 55 | /* |
| @@ -81,11 +84,11 @@ | |
| 81 | @ uuid TEXT UNIQUE NOT NULL, -- SHA1 hash of the content |
| 82 | @ content BLOB, -- Compressed content of this record |
| 83 | @ CHECK( length(uuid)==40 AND rid>0 ) |
| 84 | @ ); |
| 85 | @ CREATE TABLE delta( |
| 86 | @ rid INTEGER PRIMARY KEY, -- BLOB that is delta-compressed |
| 87 | @ srcid INTEGER NOT NULL REFERENCES blob -- Baseline for delta-compression |
| 88 | @ ); |
| 89 | @ CREATE INDEX delta_i1 ON delta(srcid); |
| 90 | @ |
| 91 | @ ------------------------------------------------------------------------- |
| @@ -227,21 +230,41 @@ | |
| 227 | @ name TEXT UNIQUE -- Name of file page |
| 228 | @ ); |
| 229 | @ |
| 230 | @ -- Linkages between checkins, files created by each checkin, and |
| 231 | @ -- the names of those files. |
| 232 | @ -- |
| 233 | @ -- pid==0 if the file is added by checkin mid. |
| 234 | @ -- fid==0 if the file is removed by checkin mid. |
| 235 | @ -- |
| 236 | @ CREATE TABLE mlink( |
| 237 | @ mid INTEGER REFERENCES blob, -- Manifest ID where change occurs |
| 238 | @ pid INTEGER REFERENCES blob, -- File ID in parent manifest |
| 239 | @ fid INTEGER REFERENCES blob, -- Changed file ID in this manifest |
| 240 | @ fnid INTEGER REFERENCES filename, -- Name of the file |
| 241 | @ pfnid INTEGER REFERENCES filename, -- Previous name. 0 if unchanged |
| 242 | @ mperm INTEGER -- File permissions. 1==exec |
| 243 | @ ); |
| 244 | @ CREATE INDEX mlink_i1 ON mlink(mid); |
| 245 | @ CREATE INDEX mlink_i2 ON mlink(fnid); |
| 246 | @ CREATE INDEX mlink_i3 ON mlink(fid); |
| 247 | @ CREATE INDEX mlink_i4 ON mlink(pid); |
| @@ -251,11 +274,11 @@ | |
| 251 | @ CREATE TABLE plink( |
| 252 | @ pid INTEGER REFERENCES blob, -- Parent manifest |
| 253 | @ cid INTEGER REFERENCES blob, -- Child manifest |
| 254 | @ isprim BOOLEAN, -- pid is the primary parent of cid |
| 255 | @ mtime DATETIME, -- the date/time stamp on cid. Julian day. |
| 256 | @ baseid INTEGER REFERENCES blob, -- Baseline if child is a delta manifest |
| 257 | @ UNIQUE(pid, cid) |
| 258 | @ ); |
| 259 | @ CREATE INDEX plink_i2 ON plink(cid,pid); |
| 260 | @ |
| 261 | @ -- A "leaf" checkin is a checkin that has no children in the same |
| @@ -488,11 +511,11 @@ | |
| 488 | @ -- current version of the file is already in the repository. |
| 489 | @ -- |
| 490 | @ CREATE TABLE vfile( |
| 491 | @ id INTEGER PRIMARY KEY, -- ID of the checked out file |
| 492 | @ vid INTEGER REFERENCES blob, -- The baseline this file is part of. |
| 493 | @ chnged INT DEFAULT 0, -- 0:unchnged 1:edited 2:m-chng 3:m-add 4:i-chng 5:i-add |
| 494 | @ deleted BOOLEAN DEFAULT 0, -- True if deleted |
| 495 | @ isexe BOOLEAN, -- True if file should be executable |
| 496 | @ islink BOOLEAN, -- True if file should be symlink |
| 497 | @ rid INTEGER, -- Originally from this repository record |
| 498 | @ mrid INTEGER, -- Based on this record due to a merge |
| 499 |
| --- src/schema.c | |
| +++ src/schema.c | |
| @@ -12,11 +12,11 @@ | |
| 12 | ** Author contact information: |
| 13 | ** [email protected] |
| 14 | ** http://www.hwaci.com/drh/ |
| 15 | ** |
| 16 | ******************************************************************************* |
| 17 | ** |
| 18 | ** This file contains string constants that implement the database schema. |
| 19 | */ |
| 20 | #include "config.h" |
| 21 | #include "schema.h" |
| 22 | |
| @@ -45,11 +45,14 @@ | |
| 45 | ** we have to execute special procedures to update the schema. When |
| 46 | ** the aux schema changes, all we need to do is rebuild the database. |
| 47 | */ |
| 48 | #define CONTENT_SCHEMA "2" |
| 49 | #define AUX_SCHEMA_MIN "2011-04-25 19:50" |
| 50 | #define AUX_SCHEMA_MAX "2015-01-24" |
| 51 | /* NB: Some features require the latest schema. Warning or error messages |
| 52 | ** will appear if an older schema is used. However, the older schemas are |
| 53 | ** adequate for many common functions. */ |
| 54 | |
| 55 | #endif /* INTERFACE */ |
| 56 | |
| 57 | |
| 58 | /* |
| @@ -81,11 +84,11 @@ | |
| 84 | @ uuid TEXT UNIQUE NOT NULL, -- SHA1 hash of the content |
| 85 | @ content BLOB, -- Compressed content of this record |
| 86 | @ CHECK( length(uuid)==40 AND rid>0 ) |
| 87 | @ ); |
| 88 | @ CREATE TABLE delta( |
| 89 | @ rid INTEGER PRIMARY KEY, -- BLOB that is delta-compressed |
| 90 | @ srcid INTEGER NOT NULL REFERENCES blob -- Baseline for delta-compression |
| 91 | @ ); |
| 92 | @ CREATE INDEX delta_i1 ON delta(srcid); |
| 93 | @ |
| 94 | @ ------------------------------------------------------------------------- |
| @@ -227,21 +230,41 @@ | |
| 230 | @ name TEXT UNIQUE -- Name of file page |
| 231 | @ ); |
| 232 | @ |
| 233 | @ -- Linkages between checkins, files created by each checkin, and |
| 234 | @ -- the names of those files. |
| 235 | @ -- |
| 236 | @ -- Each entry represents a file that changed content from pid to fid |
| 237 | @ -- due to the check-in that goes from pmid to mid. fnid is the name |
| 238 | @ -- of the file in the mid check-in. If the file was renamed as part |
| 239 | @ -- of the mid check-in, then pfnid is the previous filename. |
| 240 | @ |
| 241 | @ -- There can be multiple entries for (mid,fid) if the mid checkin was |
| 242 | @ -- a merge. Entries with isaux==0 are from the primary parent. Merge |
| 243 | @ -- parents have isaux set to true. |
| 244 | @ -- |
| 245 | @ -- Field name mnemonics: |
| 246 | @ -- mid = Manifest ID. (Each check-in is stored as a "Manifest") |
| 247 | @ -- fid = File ID. |
| 248 | @ -- pmid = Parent Manifest ID. |
| 249 | @ -- pid = Parent file ID. |
| 250 | @ -- fnid = File Name ID. |
| 251 | @ -- pfnid = Parent File Name ID. |
| 252 | @ -- isaux = pmid IS AUXiliary parent, not primary parent |
| 253 | @ -- |
| 254 | @ -- pid==0 if the file is added by checkin mid. |
| 255 | @ -- fid==0 if the file is removed by checkin mid. |
| 256 | @ -- |
| 257 | @ CREATE TABLE mlink( |
| 258 | @ mid INTEGER REFERENCES plink(cid), -- Checkin that contains fid |
| 259 | @ fid INTEGER REFERENCES blob, -- New file content. 0 if deleted |
| 260 | @ pmid INTEGER REFERENCES plink(cid), -- Checkin that contains pid |
| 261 | @ pid INTEGER REFERENCES blob, -- Prev file content. 0 if new |
| 262 | @ fnid INTEGER REFERENCES filename, -- Name of the file |
| 263 | @ pfnid INTEGER REFERENCES filename, -- Previous name. 0 if unchanged |
| 264 | @ mperm INTEGER, -- File permissions. 1==exec |
| 265 | @ isaux BOOLEAN DEFAULT 0 -- TRUE if pmid is the primary |
| 266 | @ ); |
| 267 | @ CREATE INDEX mlink_i1 ON mlink(mid); |
| 268 | @ CREATE INDEX mlink_i2 ON mlink(fnid); |
| 269 | @ CREATE INDEX mlink_i3 ON mlink(fid); |
| 270 | @ CREATE INDEX mlink_i4 ON mlink(pid); |
| @@ -251,11 +274,11 @@ | |
| 274 | @ CREATE TABLE plink( |
| 275 | @ pid INTEGER REFERENCES blob, -- Parent manifest |
| 276 | @ cid INTEGER REFERENCES blob, -- Child manifest |
| 277 | @ isprim BOOLEAN, -- pid is the primary parent of cid |
| 278 | @ mtime DATETIME, -- the date/time stamp on cid. Julian day. |
| 279 | @ baseid INTEGER REFERENCES blob, -- Baseline if cid is a delta manifest. |
| 280 | @ UNIQUE(pid, cid) |
| 281 | @ ); |
| 282 | @ CREATE INDEX plink_i2 ON plink(cid,pid); |
| 283 | @ |
| 284 | @ -- A "leaf" checkin is a checkin that has no children in the same |
| @@ -488,11 +511,11 @@ | |
| 511 | @ -- current version of the file is already in the repository. |
| 512 | @ -- |
| 513 | @ CREATE TABLE vfile( |
| 514 | @ id INTEGER PRIMARY KEY, -- ID of the checked out file |
| 515 | @ vid INTEGER REFERENCES blob, -- The baseline this file is part of. |
| 516 | @ chnged INT DEFAULT 0, -- 0:unchng 1:edit 2:m-chng 3:m-add 4:i-chng 5:i-add |
| 517 | @ deleted BOOLEAN DEFAULT 0, -- True if deleted |
| 518 | @ isexe BOOLEAN, -- True if file should be executable |
| 519 | @ islink BOOLEAN, -- True if file should be symlink |
| 520 | @ rid INTEGER, -- Originally from this repository record |
| 521 | @ mrid INTEGER, -- Based on this record due to a merge |
| 522 |
+235
-76
| --- src/search.c | ||
| +++ src/search.c | ||
| @@ -26,54 +26,34 @@ | ||
| 26 | 26 | #include "config.h" |
| 27 | 27 | #include "search.h" |
| 28 | 28 | #include <assert.h> |
| 29 | 29 | |
| 30 | 30 | #if INTERFACE |
| 31 | + | |
| 32 | +/* Maximum number of search terms */ | |
| 33 | +#define SEARCH_MAX_TERM 8 | |
| 34 | + | |
| 31 | 35 | /* |
| 32 | 36 | ** A compiled search pattern |
| 33 | 37 | */ |
| 34 | 38 | struct Search { |
| 35 | 39 | int nTerm; /* Number of search terms */ |
| 36 | 40 | struct srchTerm { /* For each search term */ |
| 37 | 41 | char *z; /* Text */ |
| 38 | 42 | int n; /* length */ |
| 39 | - } a[8]; | |
| 43 | + } a[SEARCH_MAX_TERM]; | |
| 44 | + /* Snippet controls */ | |
| 45 | + char *zMarkBegin; /* Start of a match */ | |
| 46 | + char *zMarkEnd; /* End of a match */ | |
| 47 | + char *zMarkGap; /* A gap between two matches */ | |
| 48 | + unsigned fSrchFlg; /* Flags */ | |
| 40 | 49 | }; |
| 50 | + | |
| 51 | +#define SRCHFLG_HTML 0x0001 /* Escape snippet text for HTML */ | |
| 52 | + | |
| 41 | 53 | #endif |
| 42 | 54 | |
| 43 | -/* | |
| 44 | -** Compile a search pattern | |
| 45 | -*/ | |
| 46 | -Search *search_init(const char *zPattern){ | |
| 47 | - int nPattern = strlen(zPattern); | |
| 48 | - Search *p; | |
| 49 | - char *z; | |
| 50 | - int i; | |
| 51 | - | |
| 52 | - p = fossil_malloc( nPattern + sizeof(*p) + 1); | |
| 53 | - z = (char*)&p[1]; | |
| 54 | - memcpy(z, zPattern, nPattern+1); | |
| 55 | - memset(p, 0, sizeof(*p)); | |
| 56 | - while( *z && p->nTerm<sizeof(p->a)/sizeof(p->a[0]) ){ | |
| 57 | - while( !fossil_isalnum(*z) && *z ){ z++; } | |
| 58 | - if( *z==0 ) break; | |
| 59 | - p->a[p->nTerm].z = z; | |
| 60 | - for(i=1; fossil_isalnum(z[i]) || z[i]=='_'; i++){} | |
| 61 | - p->a[p->nTerm].n = i; | |
| 62 | - z += i; | |
| 63 | - p->nTerm++; | |
| 64 | - } | |
| 65 | - return p; | |
| 66 | -} | |
| 67 | - | |
| 68 | - | |
| 69 | -/* | |
| 70 | -** Destroy a search context. | |
| 71 | -*/ | |
| 72 | -void search_end(Search *p){ | |
| 73 | - free(p); | |
| 74 | -} | |
| 75 | 55 | |
| 76 | 56 | /* |
| 77 | 57 | ** Theses characters constitute a word boundary |
| 78 | 58 | */ |
| 79 | 59 | static const char isBoundary[] = { |
| @@ -92,64 +72,243 @@ | ||
| 92 | 72 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 93 | 73 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 94 | 74 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 95 | 75 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 96 | 76 | }; |
| 77 | +#define ISALNUM(x) (!isBoundary[(x)&0xff]) | |
| 78 | + | |
| 79 | +/* | |
| 80 | +** Compile a search pattern | |
| 81 | +*/ | |
| 82 | +Search *search_init(const char *zPattern){ | |
| 83 | + int nPattern = strlen(zPattern); | |
| 84 | + Search *p; | |
| 85 | + char *z; | |
| 86 | + int i; | |
| 87 | + | |
| 88 | + p = fossil_malloc( nPattern + sizeof(*p) + 1); | |
| 89 | + z = (char*)&p[1]; | |
| 90 | + memcpy(z, zPattern, nPattern+1); | |
| 91 | + memset(p, 0, sizeof(*p)); | |
| 92 | + while( *z && p->nTerm<SEARCH_MAX_TERM ){ | |
| 93 | + while( *z && !ISALNUM(*z) ){ z++; } | |
| 94 | + if( *z==0 ) break; | |
| 95 | + p->a[p->nTerm].z = z; | |
| 96 | + for(i=1; ISALNUM(z[i]); i++){} | |
| 97 | + p->a[p->nTerm].n = i; | |
| 98 | + z += i; | |
| 99 | + p->nTerm++; | |
| 100 | + } | |
| 101 | + return p; | |
| 102 | +} | |
| 103 | + | |
| 104 | + | |
| 105 | +/* | |
| 106 | +** Destroy a search context. | |
| 107 | +*/ | |
| 108 | +void search_end(Search *p){ | |
| 109 | + free(p); | |
| 110 | +} | |
| 111 | + | |
| 112 | +/* | |
| 113 | +** Append n bytes of text to snippet zTxt. Encode the text appropriately. | |
| 114 | +*/ | |
| 115 | +static void snippet_text_append( | |
| 116 | + Search *p, /* The search context */ | |
| 117 | + Blob *pSnip, /* Append to this snippet */ | |
| 118 | + const char *zTxt, /* Text to append */ | |
| 119 | + int n /* How many bytes to append */ | |
| 120 | +){ | |
| 121 | + if( p->fSrchFlg & SRCHFLG_HTML ){ | |
| 122 | + blob_appendf(pSnip, "%.*h", n, zTxt); | |
| 123 | + }else{ | |
| 124 | + blob_append(pSnip, zTxt, n); | |
| 125 | + } | |
| 126 | +} | |
| 97 | 127 | |
| 98 | 128 | /* |
| 99 | -** Compare a search pattern against an input string and return a score. | |
| 129 | +** Compare a search pattern against one or more input strings which | |
| 130 | +** collectively comprise a document. Return a match score. Optionally | |
| 131 | +** also return a "snippet". | |
| 100 | 132 | ** |
| 101 | 133 | ** Scoring: |
| 102 | 134 | ** * All terms must match at least once or the score is zero |
| 103 | -** * 10 bonus points if the first occurrence is an exact match | |
| 104 | -** * 1 additional point for each subsequent match of the same word | |
| 105 | -** * Extra points of two consecutive words of the pattern are consecutive | |
| 135 | +** * One point for each matching term | |
| 136 | +** * Extra points if consecutive words of the pattern are consecutive | |
| 106 | 137 | ** in the document |
| 107 | 138 | */ |
| 108 | -int search_score(Search *p, int nDoc, const char **azDoc){ | |
| 109 | - int iPrev = 999; | |
| 110 | - int score = 10; | |
| 111 | - int iBonus = 0; | |
| 112 | - int i, j, k; | |
| 113 | - const char *zDoc; | |
| 114 | - unsigned char seen[8]; | |
| 115 | - | |
| 116 | - memset(seen, 0, sizeof(seen)); | |
| 117 | - for(k=0; k<nDoc; k++){ | |
| 118 | - zDoc = azDoc[k]; | |
| 139 | +static int search_score( | |
| 140 | + Search *p, /* Search pattern and flags */ | |
| 141 | + int nDoc, /* Number of strings in this document */ | |
| 142 | + const char **azDoc, /* Text of each string */ | |
| 143 | + Blob *pSnip /* If not NULL: Write a snippet here */ | |
| 144 | +){ | |
| 145 | + int score; /* Final score */ | |
| 146 | + int i; /* Offset into current document */ | |
| 147 | + int ii; /* Loop counter */ | |
| 148 | + int j; /* Loop over search terms */ | |
| 149 | + int k; /* Loop over prior terms */ | |
| 150 | + int iWord = 0; /* Current word number */ | |
| 151 | + int iDoc; /* Current document number */ | |
| 152 | + int wantGap = 0; /* True if a zMarkGap is wanted */ | |
| 153 | + const char *zDoc; /* Current document text */ | |
| 154 | + const int CTX = 50; /* Amount of snippet context */ | |
| 155 | + int anMatch[SEARCH_MAX_TERM]; /* Number of terms in best match */ | |
| 156 | + int aiBestDoc[SEARCH_MAX_TERM]; /* Document containing best match */ | |
| 157 | + int aiBestOfst[SEARCH_MAX_TERM]; /* Byte offset to start of best match */ | |
| 158 | + int aiLastDoc[SEARCH_MAX_TERM]; /* Document containing most recent match */ | |
| 159 | + int aiLastOfst[SEARCH_MAX_TERM]; /* Byte offset to the most recent match */ | |
| 160 | + int aiWordIdx[SEARCH_MAX_TERM]; /* Word index of most recent match */ | |
| 161 | + | |
| 162 | + memset(anMatch, 0, sizeof(anMatch)); | |
| 163 | + memset(aiWordIdx, 0xff, sizeof(aiWordIdx)); | |
| 164 | + for(iDoc=0; iDoc<nDoc; iDoc++){ | |
| 165 | + zDoc = azDoc[iDoc]; | |
| 119 | 166 | if( zDoc==0 ) continue; |
| 167 | + iWord++; | |
| 120 | 168 | for(i=0; zDoc[i]; i++){ |
| 121 | - char c = zDoc[i]; | |
| 122 | - if( isBoundary[c&0xff] ) continue; | |
| 169 | + if( !ISALNUM(zDoc[i]) ) continue; | |
| 170 | + iWord++; | |
| 171 | + for(j=0; j<p->nTerm; j++){ | |
| 172 | + int n = p->a[j].n; | |
| 173 | + if( sqlite3_strnicmp(p->a[j].z, &zDoc[i], n)==0 | |
| 174 | + && (!ISALNUM(zDoc[i+n]) || p->a[j].z[n]=='*') | |
| 175 | + ){ | |
| 176 | + aiWordIdx[j] = iWord; | |
| 177 | + aiLastDoc[j] = iDoc; | |
| 178 | + aiLastOfst[j] = i; | |
| 179 | + for(k=1; j-k>=0 && anMatch[j-k] && aiWordIdx[j-k]==iWord-k; k++){} | |
| 180 | + for(ii=0; ii<k; ii++){ | |
| 181 | + if( anMatch[j-ii]<k ){ | |
| 182 | + anMatch[j-ii] = k; | |
| 183 | + aiBestDoc[j-ii] = aiLastDoc[j-ii]; | |
| 184 | + aiBestOfst[j-ii] = aiLastOfst[j-ii]; | |
| 185 | + } | |
| 186 | + } | |
| 187 | + break; | |
| 188 | + } | |
| 189 | + } | |
| 190 | + while( ISALNUM(zDoc[i]) ){ i++; } | |
| 191 | + } | |
| 192 | + } | |
| 193 | + | |
| 194 | + /* Finished search all documents. | |
| 195 | + ** Every term must be seen or else the score is zero | |
| 196 | + */ | |
| 197 | + score = 1; | |
| 198 | + for(j=0; j<p->nTerm; j++) score *= anMatch[j]; | |
| 199 | + if( score==0 || pSnip==0 ) return score; | |
| 200 | + | |
| 201 | + | |
| 202 | + /* Prepare a snippet that describes the matching text. | |
| 203 | + */ | |
| 204 | + blob_init(pSnip, 0, 0); | |
| 205 | + | |
| 206 | + while(1){ | |
| 207 | + int iOfst; | |
| 208 | + int iTail; | |
| 209 | + int iBest; | |
| 210 | + for(ii=0; ii<p->nTerm && anMatch[ii]==0; ii++){} | |
| 211 | + if( ii>=p->nTerm ) break; /* This is where the loop exits */ | |
| 212 | + iBest = ii; | |
| 213 | + iDoc = aiBestDoc[ii]; | |
| 214 | + iOfst = aiBestOfst[ii]; | |
| 215 | + for(; ii<p->nTerm; ii++){ | |
| 216 | + if( anMatch[ii]==0 ) continue; | |
| 217 | + if( aiBestDoc[ii]>iDoc ) continue; | |
| 218 | + if( aiBestOfst[ii]>iOfst ) continue; | |
| 219 | + iDoc = aiBestDoc[ii]; | |
| 220 | + iOfst = aiBestOfst[ii]; | |
| 221 | + iBest = ii; | |
| 222 | + } | |
| 223 | + iTail = iOfst + p->a[iBest].n; | |
| 224 | + anMatch[iBest] = 0; | |
| 225 | + for(ii=0; ii<p->nTerm; ii++){ | |
| 226 | + if( anMatch[ii]==0 ) continue; | |
| 227 | + if( aiBestDoc[ii]!=iDoc ) continue; | |
| 228 | + if( aiBestOfst[ii]<=iTail+CTX*2 ){ | |
| 229 | + if( iTail<aiBestOfst[ii]+p->a[ii].n ){ | |
| 230 | + iTail = aiBestOfst[ii]+p->a[ii].n; | |
| 231 | + } | |
| 232 | + anMatch[ii] = 0; | |
| 233 | + ii = -1; | |
| 234 | + continue; | |
| 235 | + } | |
| 236 | + } | |
| 237 | + zDoc = azDoc[iDoc]; | |
| 238 | + iOfst -= CTX; | |
| 239 | + if( iOfst<0 ) iOfst = 0; | |
| 240 | + while( iOfst>0 && ISALNUM(zDoc[iOfst-1]) ) iOfst--; | |
| 241 | + while( zDoc[iOfst] && !ISALNUM(zDoc[iOfst]) ) iOfst++; | |
| 242 | + for(ii=0; ii<CTX && zDoc[iTail]; ii++, iTail++){} | |
| 243 | + while( ISALNUM(zDoc[iTail]) ) iTail++; | |
| 244 | + if( iOfst>0 || wantGap ) blob_append(pSnip, p->zMarkGap, -1); | |
| 245 | + wantGap = zDoc[iTail]!=0; | |
| 246 | + zDoc += iOfst; | |
| 247 | + iTail -= iOfst; | |
| 248 | + | |
| 249 | + /* Add a snippet segment using characters iOfst..iOfst+iTail from zDoc */ | |
| 250 | + for(i=0; i<iTail; i++){ | |
| 251 | + if( !ISALNUM(zDoc[i]) ) continue; | |
| 123 | 252 | for(j=0; j<p->nTerm; j++){ |
| 124 | 253 | int n = p->a[j].n; |
| 125 | - if( sqlite3_strnicmp(p->a[j].z, &zDoc[i], n)==0 ){ | |
| 126 | - score += 1; | |
| 127 | - if( !seen[j] ){ | |
| 128 | - if( isBoundary[zDoc[i+n]&0xff] ) score += 10; | |
| 129 | - seen[j] = 1; | |
| 130 | - } | |
| 131 | - if( j==iPrev+1 ){ | |
| 132 | - score += iBonus; | |
| 133 | - } | |
| 134 | - i += n-1; | |
| 135 | - iPrev = j; | |
| 136 | - iBonus = 50; | |
| 254 | + if( sqlite3_strnicmp(p->a[j].z, &zDoc[i], n)==0 | |
| 255 | + && (!ISALNUM(zDoc[i+n]) || p->a[j].z[n]=='*') | |
| 256 | + ){ | |
| 257 | + snippet_text_append(p, pSnip, zDoc, i); | |
| 258 | + zDoc += i; | |
| 259 | + iTail -= i; | |
| 260 | + blob_append(pSnip, p->zMarkBegin, -1); | |
| 261 | + if( p->a[j].z[n]=='*' ){ | |
| 262 | + while( ISALNUM(zDoc[n]) ) n++; | |
| 263 | + } | |
| 264 | + snippet_text_append(p, pSnip, zDoc, n); | |
| 265 | + zDoc += n; | |
| 266 | + iTail -= n; | |
| 267 | + blob_append(pSnip, p->zMarkEnd, -1); | |
| 268 | + i = -1; | |
| 137 | 269 | break; |
| 138 | - } | |
| 139 | - } | |
| 140 | - iBonus /= 2; | |
| 141 | - while( !isBoundary[zDoc[i]&0xff] ){ i++; } | |
| 142 | - } | |
| 143 | - } | |
| 144 | - | |
| 145 | - /* Every term must be seen or else the score is zero */ | |
| 146 | - for(j=0; j<p->nTerm; j++){ | |
| 147 | - if( !seen[j] ) return 0; | |
| 148 | - } | |
| 149 | - | |
| 150 | - return score; | |
| 270 | + } /* end-if */ | |
| 271 | + } /* end for(j) */ | |
| 272 | + if( j<p->nTerm ){ | |
| 273 | + while( ISALNUM(zDoc[i]) && i<iTail ){ i++; } | |
| 274 | + } | |
| 275 | + } /* end for(i) */ | |
| 276 | + if( iTail>0 ) snippet_text_append(p, pSnip, zDoc, iTail); | |
| 277 | + } | |
| 278 | + if( wantGap ) blob_append(pSnip, p->zMarkGap, -1); | |
| 279 | + return score; | |
| 280 | +} | |
| 281 | + | |
| 282 | +/* | |
| 283 | +** COMMAND: test-snippet | |
| 284 | +** | |
| 285 | +** Usage: fossil test-snippet SEARCHSTRING FILE1 FILE2 ... | |
| 286 | +*/ | |
| 287 | +void test_snippet_cmd(void){ | |
| 288 | + Search *p; | |
| 289 | + int i; | |
| 290 | + Blob x; | |
| 291 | + Blob snip; | |
| 292 | + int score; | |
| 293 | + char *zDoc; | |
| 294 | + if( g.argc<4 ) usage("SEARCHSTRING FILE1..."); | |
| 295 | + p = search_init(g.argv[2]); | |
| 296 | + p->zMarkBegin = "[["; | |
| 297 | + p->zMarkEnd = "]]"; | |
| 298 | + p->zMarkGap = " ... "; | |
| 299 | + for(i=3; i<g.argc; i++){ | |
| 300 | + blob_read_from_file(&x, g.argv[i]); | |
| 301 | + zDoc = blob_str(&x); | |
| 302 | + score = search_score(p, 1, (const char**)&zDoc, &snip); | |
| 303 | + fossil_print("%s: %d\n", g.argv[i], score); | |
| 304 | + blob_reset(&x); | |
| 305 | + if( score ){ | |
| 306 | + fossil_print("%.78c\n%s\n%.78c\n\n", '=', blob_str(&snip), '='); | |
| 307 | + blob_reset(&snip); | |
| 308 | + } | |
| 309 | + } | |
| 151 | 310 | } |
| 152 | 311 | |
| 153 | 312 | /* |
| 154 | 313 | ** This is an SQLite function that scores its input using |
| 155 | 314 | ** a pre-computed pattern. |
| @@ -164,11 +323,11 @@ | ||
| 164 | 323 | int score; |
| 165 | 324 | int i; |
| 166 | 325 | |
| 167 | 326 | azDoc = fossil_malloc( sizeof(const char*)*(argc+1) ); |
| 168 | 327 | for(i=0; i<argc; i++) azDoc[i] = (const char*)sqlite3_value_text(argv[i]); |
| 169 | - score = search_score(p, argc, azDoc); | |
| 328 | + score = search_score(p, argc, azDoc, 0); | |
| 170 | 329 | fossil_free((void *)azDoc); |
| 171 | 330 | sqlite3_result_int(context, score); |
| 172 | 331 | } |
| 173 | 332 | |
| 174 | 333 | /* |
| 175 | 334 |
| --- src/search.c | |
| +++ src/search.c | |
| @@ -26,54 +26,34 @@ | |
| 26 | #include "config.h" |
| 27 | #include "search.h" |
| 28 | #include <assert.h> |
| 29 | |
| 30 | #if INTERFACE |
| 31 | /* |
| 32 | ** A compiled search pattern |
| 33 | */ |
| 34 | struct Search { |
| 35 | int nTerm; /* Number of search terms */ |
| 36 | struct srchTerm { /* For each search term */ |
| 37 | char *z; /* Text */ |
| 38 | int n; /* length */ |
| 39 | } a[8]; |
| 40 | }; |
| 41 | #endif |
| 42 | |
| 43 | /* |
| 44 | ** Compile a search pattern |
| 45 | */ |
| 46 | Search *search_init(const char *zPattern){ |
| 47 | int nPattern = strlen(zPattern); |
| 48 | Search *p; |
| 49 | char *z; |
| 50 | int i; |
| 51 | |
| 52 | p = fossil_malloc( nPattern + sizeof(*p) + 1); |
| 53 | z = (char*)&p[1]; |
| 54 | memcpy(z, zPattern, nPattern+1); |
| 55 | memset(p, 0, sizeof(*p)); |
| 56 | while( *z && p->nTerm<sizeof(p->a)/sizeof(p->a[0]) ){ |
| 57 | while( !fossil_isalnum(*z) && *z ){ z++; } |
| 58 | if( *z==0 ) break; |
| 59 | p->a[p->nTerm].z = z; |
| 60 | for(i=1; fossil_isalnum(z[i]) || z[i]=='_'; i++){} |
| 61 | p->a[p->nTerm].n = i; |
| 62 | z += i; |
| 63 | p->nTerm++; |
| 64 | } |
| 65 | return p; |
| 66 | } |
| 67 | |
| 68 | |
| 69 | /* |
| 70 | ** Destroy a search context. |
| 71 | */ |
| 72 | void search_end(Search *p){ |
| 73 | free(p); |
| 74 | } |
| 75 | |
| 76 | /* |
| 77 | ** Theses characters constitute a word boundary |
| 78 | */ |
| 79 | static const char isBoundary[] = { |
| @@ -92,64 +72,243 @@ | |
| 92 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 93 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 94 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 95 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 96 | }; |
| 97 | |
| 98 | /* |
| 99 | ** Compare a search pattern against an input string and return a score. |
| 100 | ** |
| 101 | ** Scoring: |
| 102 | ** * All terms must match at least once or the score is zero |
| 103 | ** * 10 bonus points if the first occurrence is an exact match |
| 104 | ** * 1 additional point for each subsequent match of the same word |
| 105 | ** * Extra points of two consecutive words of the pattern are consecutive |
| 106 | ** in the document |
| 107 | */ |
| 108 | int search_score(Search *p, int nDoc, const char **azDoc){ |
| 109 | int iPrev = 999; |
| 110 | int score = 10; |
| 111 | int iBonus = 0; |
| 112 | int i, j, k; |
| 113 | const char *zDoc; |
| 114 | unsigned char seen[8]; |
| 115 | |
| 116 | memset(seen, 0, sizeof(seen)); |
| 117 | for(k=0; k<nDoc; k++){ |
| 118 | zDoc = azDoc[k]; |
| 119 | if( zDoc==0 ) continue; |
| 120 | for(i=0; zDoc[i]; i++){ |
| 121 | char c = zDoc[i]; |
| 122 | if( isBoundary[c&0xff] ) continue; |
| 123 | for(j=0; j<p->nTerm; j++){ |
| 124 | int n = p->a[j].n; |
| 125 | if( sqlite3_strnicmp(p->a[j].z, &zDoc[i], n)==0 ){ |
| 126 | score += 1; |
| 127 | if( !seen[j] ){ |
| 128 | if( isBoundary[zDoc[i+n]&0xff] ) score += 10; |
| 129 | seen[j] = 1; |
| 130 | } |
| 131 | if( j==iPrev+1 ){ |
| 132 | score += iBonus; |
| 133 | } |
| 134 | i += n-1; |
| 135 | iPrev = j; |
| 136 | iBonus = 50; |
| 137 | break; |
| 138 | } |
| 139 | } |
| 140 | iBonus /= 2; |
| 141 | while( !isBoundary[zDoc[i]&0xff] ){ i++; } |
| 142 | } |
| 143 | } |
| 144 | |
| 145 | /* Every term must be seen or else the score is zero */ |
| 146 | for(j=0; j<p->nTerm; j++){ |
| 147 | if( !seen[j] ) return 0; |
| 148 | } |
| 149 | |
| 150 | return score; |
| 151 | } |
| 152 | |
| 153 | /* |
| 154 | ** This is an SQLite function that scores its input using |
| 155 | ** a pre-computed pattern. |
| @@ -164,11 +323,11 @@ | |
| 164 | int score; |
| 165 | int i; |
| 166 | |
| 167 | azDoc = fossil_malloc( sizeof(const char*)*(argc+1) ); |
| 168 | for(i=0; i<argc; i++) azDoc[i] = (const char*)sqlite3_value_text(argv[i]); |
| 169 | score = search_score(p, argc, azDoc); |
| 170 | fossil_free((void *)azDoc); |
| 171 | sqlite3_result_int(context, score); |
| 172 | } |
| 173 | |
| 174 | /* |
| 175 |
| --- src/search.c | |
| +++ src/search.c | |
| @@ -26,54 +26,34 @@ | |
| 26 | #include "config.h" |
| 27 | #include "search.h" |
| 28 | #include <assert.h> |
| 29 | |
| 30 | #if INTERFACE |
| 31 | |
| 32 | /* Maximum number of search terms */ |
| 33 | #define SEARCH_MAX_TERM 8 |
| 34 | |
| 35 | /* |
| 36 | ** A compiled search pattern |
| 37 | */ |
| 38 | struct Search { |
| 39 | int nTerm; /* Number of search terms */ |
| 40 | struct srchTerm { /* For each search term */ |
| 41 | char *z; /* Text */ |
| 42 | int n; /* length */ |
| 43 | } a[SEARCH_MAX_TERM]; |
| 44 | /* Snippet controls */ |
| 45 | char *zMarkBegin; /* Start of a match */ |
| 46 | char *zMarkEnd; /* End of a match */ |
| 47 | char *zMarkGap; /* A gap between two matches */ |
| 48 | unsigned fSrchFlg; /* Flags */ |
| 49 | }; |
| 50 | |
| 51 | #define SRCHFLG_HTML 0x0001 /* Escape snippet text for HTML */ |
| 52 | |
| 53 | #endif |
| 54 | |
| 55 | |
| 56 | /* |
| 57 | ** Theses characters constitute a word boundary |
| 58 | */ |
| 59 | static const char isBoundary[] = { |
| @@ -92,64 +72,243 @@ | |
| 72 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 73 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 74 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 75 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 76 | }; |
| 77 | #define ISALNUM(x) (!isBoundary[(x)&0xff]) |
| 78 | |
| 79 | /* |
| 80 | ** Compile a search pattern |
| 81 | */ |
| 82 | Search *search_init(const char *zPattern){ |
| 83 | int nPattern = strlen(zPattern); |
| 84 | Search *p; |
| 85 | char *z; |
| 86 | int i; |
| 87 | |
| 88 | p = fossil_malloc( nPattern + sizeof(*p) + 1); |
| 89 | z = (char*)&p[1]; |
| 90 | memcpy(z, zPattern, nPattern+1); |
| 91 | memset(p, 0, sizeof(*p)); |
| 92 | while( *z && p->nTerm<SEARCH_MAX_TERM ){ |
| 93 | while( *z && !ISALNUM(*z) ){ z++; } |
| 94 | if( *z==0 ) break; |
| 95 | p->a[p->nTerm].z = z; |
| 96 | for(i=1; ISALNUM(z[i]); i++){} |
| 97 | p->a[p->nTerm].n = i; |
| 98 | z += i; |
| 99 | p->nTerm++; |
| 100 | } |
| 101 | return p; |
| 102 | } |
| 103 | |
| 104 | |
| 105 | /* |
| 106 | ** Destroy a search context. |
| 107 | */ |
| 108 | void search_end(Search *p){ |
| 109 | free(p); |
| 110 | } |
| 111 | |
| 112 | /* |
| 113 | ** Append n bytes of text to snippet zTxt. Encode the text appropriately. |
| 114 | */ |
| 115 | static void snippet_text_append( |
| 116 | Search *p, /* The search context */ |
| 117 | Blob *pSnip, /* Append to this snippet */ |
| 118 | const char *zTxt, /* Text to append */ |
| 119 | int n /* How many bytes to append */ |
| 120 | ){ |
| 121 | if( p->fSrchFlg & SRCHFLG_HTML ){ |
| 122 | blob_appendf(pSnip, "%.*h", n, zTxt); |
| 123 | }else{ |
| 124 | blob_append(pSnip, zTxt, n); |
| 125 | } |
| 126 | } |
| 127 | |
| 128 | /* |
| 129 | ** Compare a search pattern against one or more input strings which |
| 130 | ** collectively comprise a document. Return a match score. Optionally |
| 131 | ** also return a "snippet". |
| 132 | ** |
| 133 | ** Scoring: |
| 134 | ** * All terms must match at least once or the score is zero |
| 135 | ** * One point for each matching term |
| 136 | ** * Extra points if consecutive words of the pattern are consecutive |
| 137 | ** in the document |
| 138 | */ |
| 139 | static int search_score( |
| 140 | Search *p, /* Search pattern and flags */ |
| 141 | int nDoc, /* Number of strings in this document */ |
| 142 | const char **azDoc, /* Text of each string */ |
| 143 | Blob *pSnip /* If not NULL: Write a snippet here */ |
| 144 | ){ |
| 145 | int score; /* Final score */ |
| 146 | int i; /* Offset into current document */ |
| 147 | int ii; /* Loop counter */ |
| 148 | int j; /* Loop over search terms */ |
| 149 | int k; /* Loop over prior terms */ |
| 150 | int iWord = 0; /* Current word number */ |
| 151 | int iDoc; /* Current document number */ |
| 152 | int wantGap = 0; /* True if a zMarkGap is wanted */ |
| 153 | const char *zDoc; /* Current document text */ |
| 154 | const int CTX = 50; /* Amount of snippet context */ |
| 155 | int anMatch[SEARCH_MAX_TERM]; /* Number of terms in best match */ |
| 156 | int aiBestDoc[SEARCH_MAX_TERM]; /* Document containing best match */ |
| 157 | int aiBestOfst[SEARCH_MAX_TERM]; /* Byte offset to start of best match */ |
| 158 | int aiLastDoc[SEARCH_MAX_TERM]; /* Document containing most recent match */ |
| 159 | int aiLastOfst[SEARCH_MAX_TERM]; /* Byte offset to the most recent match */ |
| 160 | int aiWordIdx[SEARCH_MAX_TERM]; /* Word index of most recent match */ |
| 161 | |
| 162 | memset(anMatch, 0, sizeof(anMatch)); |
| 163 | memset(aiWordIdx, 0xff, sizeof(aiWordIdx)); |
| 164 | for(iDoc=0; iDoc<nDoc; iDoc++){ |
| 165 | zDoc = azDoc[iDoc]; |
| 166 | if( zDoc==0 ) continue; |
| 167 | iWord++; |
| 168 | for(i=0; zDoc[i]; i++){ |
| 169 | if( !ISALNUM(zDoc[i]) ) continue; |
| 170 | iWord++; |
| 171 | for(j=0; j<p->nTerm; j++){ |
| 172 | int n = p->a[j].n; |
| 173 | if( sqlite3_strnicmp(p->a[j].z, &zDoc[i], n)==0 |
| 174 | && (!ISALNUM(zDoc[i+n]) || p->a[j].z[n]=='*') |
| 175 | ){ |
| 176 | aiWordIdx[j] = iWord; |
| 177 | aiLastDoc[j] = iDoc; |
| 178 | aiLastOfst[j] = i; |
| 179 | for(k=1; j-k>=0 && anMatch[j-k] && aiWordIdx[j-k]==iWord-k; k++){} |
| 180 | for(ii=0; ii<k; ii++){ |
| 181 | if( anMatch[j-ii]<k ){ |
| 182 | anMatch[j-ii] = k; |
| 183 | aiBestDoc[j-ii] = aiLastDoc[j-ii]; |
| 184 | aiBestOfst[j-ii] = aiLastOfst[j-ii]; |
| 185 | } |
| 186 | } |
| 187 | break; |
| 188 | } |
| 189 | } |
| 190 | while( ISALNUM(zDoc[i]) ){ i++; } |
| 191 | } |
| 192 | } |
| 193 | |
| 194 | /* Finished search all documents. |
| 195 | ** Every term must be seen or else the score is zero |
| 196 | */ |
| 197 | score = 1; |
| 198 | for(j=0; j<p->nTerm; j++) score *= anMatch[j]; |
| 199 | if( score==0 || pSnip==0 ) return score; |
| 200 | |
| 201 | |
| 202 | /* Prepare a snippet that describes the matching text. |
| 203 | */ |
| 204 | blob_init(pSnip, 0, 0); |
| 205 | |
| 206 | while(1){ |
| 207 | int iOfst; |
| 208 | int iTail; |
| 209 | int iBest; |
| 210 | for(ii=0; ii<p->nTerm && anMatch[ii]==0; ii++){} |
| 211 | if( ii>=p->nTerm ) break; /* This is where the loop exits */ |
| 212 | iBest = ii; |
| 213 | iDoc = aiBestDoc[ii]; |
| 214 | iOfst = aiBestOfst[ii]; |
| 215 | for(; ii<p->nTerm; ii++){ |
| 216 | if( anMatch[ii]==0 ) continue; |
| 217 | if( aiBestDoc[ii]>iDoc ) continue; |
| 218 | if( aiBestOfst[ii]>iOfst ) continue; |
| 219 | iDoc = aiBestDoc[ii]; |
| 220 | iOfst = aiBestOfst[ii]; |
| 221 | iBest = ii; |
| 222 | } |
| 223 | iTail = iOfst + p->a[iBest].n; |
| 224 | anMatch[iBest] = 0; |
| 225 | for(ii=0; ii<p->nTerm; ii++){ |
| 226 | if( anMatch[ii]==0 ) continue; |
| 227 | if( aiBestDoc[ii]!=iDoc ) continue; |
| 228 | if( aiBestOfst[ii]<=iTail+CTX*2 ){ |
| 229 | if( iTail<aiBestOfst[ii]+p->a[ii].n ){ |
| 230 | iTail = aiBestOfst[ii]+p->a[ii].n; |
| 231 | } |
| 232 | anMatch[ii] = 0; |
| 233 | ii = -1; |
| 234 | continue; |
| 235 | } |
| 236 | } |
| 237 | zDoc = azDoc[iDoc]; |
| 238 | iOfst -= CTX; |
| 239 | if( iOfst<0 ) iOfst = 0; |
| 240 | while( iOfst>0 && ISALNUM(zDoc[iOfst-1]) ) iOfst--; |
| 241 | while( zDoc[iOfst] && !ISALNUM(zDoc[iOfst]) ) iOfst++; |
| 242 | for(ii=0; ii<CTX && zDoc[iTail]; ii++, iTail++){} |
| 243 | while( ISALNUM(zDoc[iTail]) ) iTail++; |
| 244 | if( iOfst>0 || wantGap ) blob_append(pSnip, p->zMarkGap, -1); |
| 245 | wantGap = zDoc[iTail]!=0; |
| 246 | zDoc += iOfst; |
| 247 | iTail -= iOfst; |
| 248 | |
| 249 | /* Add a snippet segment using characters iOfst..iOfst+iTail from zDoc */ |
| 250 | for(i=0; i<iTail; i++){ |
| 251 | if( !ISALNUM(zDoc[i]) ) continue; |
| 252 | for(j=0; j<p->nTerm; j++){ |
| 253 | int n = p->a[j].n; |
| 254 | if( sqlite3_strnicmp(p->a[j].z, &zDoc[i], n)==0 |
| 255 | && (!ISALNUM(zDoc[i+n]) || p->a[j].z[n]=='*') |
| 256 | ){ |
| 257 | snippet_text_append(p, pSnip, zDoc, i); |
| 258 | zDoc += i; |
| 259 | iTail -= i; |
| 260 | blob_append(pSnip, p->zMarkBegin, -1); |
| 261 | if( p->a[j].z[n]=='*' ){ |
| 262 | while( ISALNUM(zDoc[n]) ) n++; |
| 263 | } |
| 264 | snippet_text_append(p, pSnip, zDoc, n); |
| 265 | zDoc += n; |
| 266 | iTail -= n; |
| 267 | blob_append(pSnip, p->zMarkEnd, -1); |
| 268 | i = -1; |
| 269 | break; |
| 270 | } /* end-if */ |
| 271 | } /* end for(j) */ |
| 272 | if( j<p->nTerm ){ |
| 273 | while( ISALNUM(zDoc[i]) && i<iTail ){ i++; } |
| 274 | } |
| 275 | } /* end for(i) */ |
| 276 | if( iTail>0 ) snippet_text_append(p, pSnip, zDoc, iTail); |
| 277 | } |
| 278 | if( wantGap ) blob_append(pSnip, p->zMarkGap, -1); |
| 279 | return score; |
| 280 | } |
| 281 | |
| 282 | /* |
| 283 | ** COMMAND: test-snippet |
| 284 | ** |
| 285 | ** Usage: fossil test-snippet SEARCHSTRING FILE1 FILE2 ... |
| 286 | */ |
| 287 | void test_snippet_cmd(void){ |
| 288 | Search *p; |
| 289 | int i; |
| 290 | Blob x; |
| 291 | Blob snip; |
| 292 | int score; |
| 293 | char *zDoc; |
| 294 | if( g.argc<4 ) usage("SEARCHSTRING FILE1..."); |
| 295 | p = search_init(g.argv[2]); |
| 296 | p->zMarkBegin = "[["; |
| 297 | p->zMarkEnd = "]]"; |
| 298 | p->zMarkGap = " ... "; |
| 299 | for(i=3; i<g.argc; i++){ |
| 300 | blob_read_from_file(&x, g.argv[i]); |
| 301 | zDoc = blob_str(&x); |
| 302 | score = search_score(p, 1, (const char**)&zDoc, &snip); |
| 303 | fossil_print("%s: %d\n", g.argv[i], score); |
| 304 | blob_reset(&x); |
| 305 | if( score ){ |
| 306 | fossil_print("%.78c\n%s\n%.78c\n\n", '=', blob_str(&snip), '='); |
| 307 | blob_reset(&snip); |
| 308 | } |
| 309 | } |
| 310 | } |
| 311 | |
| 312 | /* |
| 313 | ** This is an SQLite function that scores its input using |
| 314 | ** a pre-computed pattern. |
| @@ -164,11 +323,11 @@ | |
| 323 | int score; |
| 324 | int i; |
| 325 | |
| 326 | azDoc = fossil_malloc( sizeof(const char*)*(argc+1) ); |
| 327 | for(i=0; i<argc; i++) azDoc[i] = (const char*)sqlite3_value_text(argv[i]); |
| 328 | score = search_score(p, argc, azDoc, 0); |
| 329 | fossil_free((void *)azDoc); |
| 330 | sqlite3_result_int(context, score); |
| 331 | } |
| 332 | |
| 333 | /* |
| 334 |
+16
-20
| --- src/setup.c | ||
| +++ src/setup.c | ||
| @@ -813,17 +813,13 @@ | ||
| 813 | 813 | @ <ul> |
| 814 | 814 | @ <li><p> |
| 815 | 815 | @ No login is required for user <span class="usertype">nobody</span>. The |
| 816 | 816 | @ capabilities of the <span class="usertype">nobody</span> user are |
| 817 | 817 | @ inherited by all users, regardless of whether or not they are logged in. |
| 818 | - @ To disable universal access to the repository, make sure no user named | |
| 819 | - @ <span class="usertype">nobody</span> exists or that the | |
| 818 | + @ To disable universal access to the repository, make sure that the | |
| 820 | 819 | @ <span class="usertype">nobody</span> user has no capabilities |
| 821 | 820 | @ enabled. The password for <span class="usertype">nobody</span> is ignored. |
| 822 | - @ To avoid problems with spiders overloading the server, it is recommended | |
| 823 | - @ that the <span class="capability">h</span> (Hyperlinks) capability be | |
| 824 | - @ turned off for the <span class="usertype">nobody</span> user. | |
| 825 | 821 | @ </p></li> |
| 826 | 822 | @ |
| 827 | 823 | @ <li><p> |
| 828 | 824 | @ Login is required for user <span class="usertype">anonymous</span> but the |
| 829 | 825 | @ password is displayed on the login screen beside the password entry box |
| @@ -1525,26 +1521,26 @@ | ||
| 1525 | 1521 | login_needed(); |
| 1526 | 1522 | } |
| 1527 | 1523 | db_begin_transaction(); |
| 1528 | 1524 | if( P("clear")!=0 ){ |
| 1529 | 1525 | db_multi_exec("DELETE FROM config WHERE name='css'"); |
| 1530 | - cgi_replace_parameter("css", builtin_text("skins/default.css")); | |
| 1526 | + cgi_replace_parameter("css", builtin_text("skins/default/css.txt")); | |
| 1531 | 1527 | db_end_transaction(0); |
| 1532 | 1528 | cgi_redirect("setup_editcss"); |
| 1533 | 1529 | } |
| 1534 | 1530 | if( P("submit")!=0 ){ |
| 1535 | 1531 | textarea_attribute(0, 0, 0, "css", "css", |
| 1536 | - builtin_text("skins/default.css"), 0); | |
| 1532 | + builtin_text("skins/default/css.txt"), 0); | |
| 1537 | 1533 | db_end_transaction(0); |
| 1538 | 1534 | cgi_redirect("setup_editcss"); |
| 1539 | 1535 | } |
| 1540 | 1536 | style_header("Edit CSS"); |
| 1541 | 1537 | @ <form action="%s(g.zTop)/setup_editcss" method="post"><div> |
| 1542 | 1538 | login_insert_csrf_secret(); |
| 1543 | 1539 | @ Edit the CSS below:<br /> |
| 1544 | 1540 | textarea_attribute("", 35, 80, "css", "css", |
| 1545 | - builtin_text("skins/default.css"), 0); | |
| 1541 | + builtin_text("skins/default/css.txt"), 0); | |
| 1546 | 1542 | @ <br /> |
| 1547 | 1543 | @ <input type="submit" name="submit" value="Apply Changes" /> |
| 1548 | 1544 | @ <input type="submit" name="clear" value="Revert To Default" /> |
| 1549 | 1545 | @ </div></form> |
| 1550 | 1546 | @ <p><span class="note">Note:</span> Press your browser Reload button after |
| @@ -1570,17 +1566,17 @@ | ||
| 1570 | 1566 | login_needed(); |
| 1571 | 1567 | } |
| 1572 | 1568 | db_begin_transaction(); |
| 1573 | 1569 | if( P("clear")!=0 ){ |
| 1574 | 1570 | db_multi_exec("DELETE FROM config WHERE name='header'"); |
| 1575 | - cgi_replace_parameter("header", builtin_text("skins/default.header")); | |
| 1571 | + cgi_replace_parameter("header", builtin_text("skins/default/header.txt")); | |
| 1576 | 1572 | }else if( P("submit")!=0 ){ |
| 1577 | 1573 | textarea_attribute(0, 0, 0, "header", "header", |
| 1578 | - builtin_text("skins/default.header"), 0); | |
| 1574 | + builtin_text("skins/default/header.txt"), 0); | |
| 1579 | 1575 | }else if( P("fixbase")!=0 ){ |
| 1580 | 1576 | const char *z = db_get("header", |
| 1581 | - (char*)builtin_text("skins/default.header")); | |
| 1577 | + (char*)builtin_text("skins/default/header.txt")); | |
| 1582 | 1578 | char *zHead = strstr(z, "<head>"); |
| 1583 | 1579 | if( strstr(z, "<base href=")==0 && zHead!=0 ){ |
| 1584 | 1580 | char *zNew; |
| 1585 | 1581 | char *zTail = &zHead[6]; |
| 1586 | 1582 | while( fossil_isspace(zTail[0]) ) zTail++; |
| @@ -1606,11 +1602,11 @@ | ||
| 1606 | 1602 | login_insert_csrf_secret(); |
| 1607 | 1603 | @ <p>Edit HTML text with embedded TH1 (a Tcl dialect) that will be used to |
| 1608 | 1604 | @ generate the beginning of every page through start of the main |
| 1609 | 1605 | @ menu.</p> |
| 1610 | 1606 | textarea_attribute("", 35, 80, "header", "header", |
| 1611 | - builtin_text("skins/default.header"), 0); | |
| 1607 | + builtin_text("skins/default/header.txt"), 0); | |
| 1612 | 1608 | @ <br /> |
| 1613 | 1609 | @ <input type="submit" name="submit" value="Apply Changes" /> |
| 1614 | 1610 | @ <input type="submit" name="clear" value="Revert To Default" /> |
| 1615 | 1611 | @ </div></form> |
| 1616 | 1612 | @ <hr /> |
| @@ -1617,11 +1613,11 @@ | ||
| 1617 | 1613 | @ The default header is shown below for reference. Other examples |
| 1618 | 1614 | @ of headers can be seen on the <a href="setup_skin">skins page</a>. |
| 1619 | 1615 | @ See also the <a href="setup_editcss">CSS</a> and |
| 1620 | 1616 | @ <a href="setup_footer">footer</a> editing screens. |
| 1621 | 1617 | @ <blockquote><pre> |
| 1622 | - @ %h(builtin_text("skins/default.header")) | |
| 1618 | + @ %h(builtin_text("skins/default/header.txt")) | |
| 1623 | 1619 | @ </pre></blockquote> |
| 1624 | 1620 | style_footer(); |
| 1625 | 1621 | db_end_transaction(0); |
| 1626 | 1622 | } |
| 1627 | 1623 | |
| @@ -1634,20 +1630,20 @@ | ||
| 1634 | 1630 | login_needed(); |
| 1635 | 1631 | } |
| 1636 | 1632 | db_begin_transaction(); |
| 1637 | 1633 | if( P("clear")!=0 ){ |
| 1638 | 1634 | db_multi_exec("DELETE FROM config WHERE name='footer'"); |
| 1639 | - cgi_replace_parameter("footer", builtin_text("skins/default.footer")); | |
| 1635 | + cgi_replace_parameter("footer", builtin_text("skins/default/footer.txt")); | |
| 1640 | 1636 | } |
| 1641 | 1637 | |
| 1642 | 1638 | style_header("Edit Page Footer"); |
| 1643 | 1639 | @ <form action="%s(g.zTop)/setup_footer" method="post"><div> |
| 1644 | 1640 | login_insert_csrf_secret(); |
| 1645 | 1641 | @ <p>Edit HTML text with embedded TH1 (a Tcl dialect) that will be used to |
| 1646 | 1642 | @ generate the end of every page.</p> |
| 1647 | 1643 | textarea_attribute("", 20, 80, "footer", "footer", |
| 1648 | - builtin_text("skins/default.footer"), 0); | |
| 1644 | + builtin_text("skins/default/footer.txt"), 0); | |
| 1649 | 1645 | @ <br /> |
| 1650 | 1646 | @ <input type="submit" name="submit" value="Apply Changes" /> |
| 1651 | 1647 | @ <input type="submit" name="clear" value="Revert To Default" /> |
| 1652 | 1648 | @ </div></form> |
| 1653 | 1649 | @ <hr /> |
| @@ -1654,11 +1650,11 @@ | ||
| 1654 | 1650 | @ The default footer is shown below for reference. Other examples |
| 1655 | 1651 | @ of footers can be seen on the <a href="setup_skin">skins page</a>. |
| 1656 | 1652 | @ See also the <a href="setup_editcss">CSS</a> and |
| 1657 | 1653 | @ <a href="setup_header">header</a> editing screens. |
| 1658 | 1654 | @ <blockquote><pre> |
| 1659 | - @ %h(builtin_text("skins/default.footer")) | |
| 1655 | + @ %h(builtin_text("skins/default/footer.txt")) | |
| 1660 | 1656 | @ </pre></blockquote> |
| 1661 | 1657 | style_footer(); |
| 1662 | 1658 | db_end_transaction(0); |
| 1663 | 1659 | } |
| 1664 | 1660 | |
| @@ -2142,14 +2138,14 @@ | ||
| 2142 | 2138 | @ <th>User</th> |
| 2143 | 2139 | @ <th>Page</th> |
| 2144 | 2140 | @ <th width="60%%">Message</th> |
| 2145 | 2141 | @ </thead><tbody> |
| 2146 | 2142 | while( SQLITE_ROW == db_step(&stLog) ){ |
| 2147 | - char const * zTime = db_column_text(&stLog, 0); | |
| 2148 | - char const * zUser = db_column_text(&stLog, 1); | |
| 2149 | - char const * zPage = db_column_text(&stLog, 2); | |
| 2150 | - char const * zMessage = db_column_text(&stLog, 3); | |
| 2143 | + const char *zTime = db_column_text(&stLog, 0); | |
| 2144 | + const char *zUser = db_column_text(&stLog, 1); | |
| 2145 | + const char *zPage = db_column_text(&stLog, 2); | |
| 2146 | + const char *zMessage = db_column_text(&stLog, 3); | |
| 2151 | 2147 | @ <tr class="row%d(counter++%2)"> |
| 2152 | 2148 | @ <td class="adminTime">%s(zTime)</td> |
| 2153 | 2149 | @ <td>%s(zUser)</td> |
| 2154 | 2150 | @ <td>%s(zPage)</td> |
| 2155 | 2151 | @ <td>%h(zMessage)</td> |
| 2156 | 2152 |
| --- src/setup.c | |
| +++ src/setup.c | |
| @@ -813,17 +813,13 @@ | |
| 813 | @ <ul> |
| 814 | @ <li><p> |
| 815 | @ No login is required for user <span class="usertype">nobody</span>. The |
| 816 | @ capabilities of the <span class="usertype">nobody</span> user are |
| 817 | @ inherited by all users, regardless of whether or not they are logged in. |
| 818 | @ To disable universal access to the repository, make sure no user named |
| 819 | @ <span class="usertype">nobody</span> exists or that the |
| 820 | @ <span class="usertype">nobody</span> user has no capabilities |
| 821 | @ enabled. The password for <span class="usertype">nobody</span> is ignored. |
| 822 | @ To avoid problems with spiders overloading the server, it is recommended |
| 823 | @ that the <span class="capability">h</span> (Hyperlinks) capability be |
| 824 | @ turned off for the <span class="usertype">nobody</span> user. |
| 825 | @ </p></li> |
| 826 | @ |
| 827 | @ <li><p> |
| 828 | @ Login is required for user <span class="usertype">anonymous</span> but the |
| 829 | @ password is displayed on the login screen beside the password entry box |
| @@ -1525,26 +1521,26 @@ | |
| 1525 | login_needed(); |
| 1526 | } |
| 1527 | db_begin_transaction(); |
| 1528 | if( P("clear")!=0 ){ |
| 1529 | db_multi_exec("DELETE FROM config WHERE name='css'"); |
| 1530 | cgi_replace_parameter("css", builtin_text("skins/default.css")); |
| 1531 | db_end_transaction(0); |
| 1532 | cgi_redirect("setup_editcss"); |
| 1533 | } |
| 1534 | if( P("submit")!=0 ){ |
| 1535 | textarea_attribute(0, 0, 0, "css", "css", |
| 1536 | builtin_text("skins/default.css"), 0); |
| 1537 | db_end_transaction(0); |
| 1538 | cgi_redirect("setup_editcss"); |
| 1539 | } |
| 1540 | style_header("Edit CSS"); |
| 1541 | @ <form action="%s(g.zTop)/setup_editcss" method="post"><div> |
| 1542 | login_insert_csrf_secret(); |
| 1543 | @ Edit the CSS below:<br /> |
| 1544 | textarea_attribute("", 35, 80, "css", "css", |
| 1545 | builtin_text("skins/default.css"), 0); |
| 1546 | @ <br /> |
| 1547 | @ <input type="submit" name="submit" value="Apply Changes" /> |
| 1548 | @ <input type="submit" name="clear" value="Revert To Default" /> |
| 1549 | @ </div></form> |
| 1550 | @ <p><span class="note">Note:</span> Press your browser Reload button after |
| @@ -1570,17 +1566,17 @@ | |
| 1570 | login_needed(); |
| 1571 | } |
| 1572 | db_begin_transaction(); |
| 1573 | if( P("clear")!=0 ){ |
| 1574 | db_multi_exec("DELETE FROM config WHERE name='header'"); |
| 1575 | cgi_replace_parameter("header", builtin_text("skins/default.header")); |
| 1576 | }else if( P("submit")!=0 ){ |
| 1577 | textarea_attribute(0, 0, 0, "header", "header", |
| 1578 | builtin_text("skins/default.header"), 0); |
| 1579 | }else if( P("fixbase")!=0 ){ |
| 1580 | const char *z = db_get("header", |
| 1581 | (char*)builtin_text("skins/default.header")); |
| 1582 | char *zHead = strstr(z, "<head>"); |
| 1583 | if( strstr(z, "<base href=")==0 && zHead!=0 ){ |
| 1584 | char *zNew; |
| 1585 | char *zTail = &zHead[6]; |
| 1586 | while( fossil_isspace(zTail[0]) ) zTail++; |
| @@ -1606,11 +1602,11 @@ | |
| 1606 | login_insert_csrf_secret(); |
| 1607 | @ <p>Edit HTML text with embedded TH1 (a Tcl dialect) that will be used to |
| 1608 | @ generate the beginning of every page through start of the main |
| 1609 | @ menu.</p> |
| 1610 | textarea_attribute("", 35, 80, "header", "header", |
| 1611 | builtin_text("skins/default.header"), 0); |
| 1612 | @ <br /> |
| 1613 | @ <input type="submit" name="submit" value="Apply Changes" /> |
| 1614 | @ <input type="submit" name="clear" value="Revert To Default" /> |
| 1615 | @ </div></form> |
| 1616 | @ <hr /> |
| @@ -1617,11 +1613,11 @@ | |
| 1617 | @ The default header is shown below for reference. Other examples |
| 1618 | @ of headers can be seen on the <a href="setup_skin">skins page</a>. |
| 1619 | @ See also the <a href="setup_editcss">CSS</a> and |
| 1620 | @ <a href="setup_footer">footer</a> editing screens. |
| 1621 | @ <blockquote><pre> |
| 1622 | @ %h(builtin_text("skins/default.header")) |
| 1623 | @ </pre></blockquote> |
| 1624 | style_footer(); |
| 1625 | db_end_transaction(0); |
| 1626 | } |
| 1627 | |
| @@ -1634,20 +1630,20 @@ | |
| 1634 | login_needed(); |
| 1635 | } |
| 1636 | db_begin_transaction(); |
| 1637 | if( P("clear")!=0 ){ |
| 1638 | db_multi_exec("DELETE FROM config WHERE name='footer'"); |
| 1639 | cgi_replace_parameter("footer", builtin_text("skins/default.footer")); |
| 1640 | } |
| 1641 | |
| 1642 | style_header("Edit Page Footer"); |
| 1643 | @ <form action="%s(g.zTop)/setup_footer" method="post"><div> |
| 1644 | login_insert_csrf_secret(); |
| 1645 | @ <p>Edit HTML text with embedded TH1 (a Tcl dialect) that will be used to |
| 1646 | @ generate the end of every page.</p> |
| 1647 | textarea_attribute("", 20, 80, "footer", "footer", |
| 1648 | builtin_text("skins/default.footer"), 0); |
| 1649 | @ <br /> |
| 1650 | @ <input type="submit" name="submit" value="Apply Changes" /> |
| 1651 | @ <input type="submit" name="clear" value="Revert To Default" /> |
| 1652 | @ </div></form> |
| 1653 | @ <hr /> |
| @@ -1654,11 +1650,11 @@ | |
| 1654 | @ The default footer is shown below for reference. Other examples |
| 1655 | @ of footers can be seen on the <a href="setup_skin">skins page</a>. |
| 1656 | @ See also the <a href="setup_editcss">CSS</a> and |
| 1657 | @ <a href="setup_header">header</a> editing screens. |
| 1658 | @ <blockquote><pre> |
| 1659 | @ %h(builtin_text("skins/default.footer")) |
| 1660 | @ </pre></blockquote> |
| 1661 | style_footer(); |
| 1662 | db_end_transaction(0); |
| 1663 | } |
| 1664 | |
| @@ -2142,14 +2138,14 @@ | |
| 2142 | @ <th>User</th> |
| 2143 | @ <th>Page</th> |
| 2144 | @ <th width="60%%">Message</th> |
| 2145 | @ </thead><tbody> |
| 2146 | while( SQLITE_ROW == db_step(&stLog) ){ |
| 2147 | char const * zTime = db_column_text(&stLog, 0); |
| 2148 | char const * zUser = db_column_text(&stLog, 1); |
| 2149 | char const * zPage = db_column_text(&stLog, 2); |
| 2150 | char const * zMessage = db_column_text(&stLog, 3); |
| 2151 | @ <tr class="row%d(counter++%2)"> |
| 2152 | @ <td class="adminTime">%s(zTime)</td> |
| 2153 | @ <td>%s(zUser)</td> |
| 2154 | @ <td>%s(zPage)</td> |
| 2155 | @ <td>%h(zMessage)</td> |
| 2156 |
| --- src/setup.c | |
| +++ src/setup.c | |
| @@ -813,17 +813,13 @@ | |
| 813 | @ <ul> |
| 814 | @ <li><p> |
| 815 | @ No login is required for user <span class="usertype">nobody</span>. The |
| 816 | @ capabilities of the <span class="usertype">nobody</span> user are |
| 817 | @ inherited by all users, regardless of whether or not they are logged in. |
| 818 | @ To disable universal access to the repository, make sure that the |
| 819 | @ <span class="usertype">nobody</span> user has no capabilities |
| 820 | @ enabled. The password for <span class="usertype">nobody</span> is ignored. |
| 821 | @ </p></li> |
| 822 | @ |
| 823 | @ <li><p> |
| 824 | @ Login is required for user <span class="usertype">anonymous</span> but the |
| 825 | @ password is displayed on the login screen beside the password entry box |
| @@ -1525,26 +1521,26 @@ | |
| 1521 | login_needed(); |
| 1522 | } |
| 1523 | db_begin_transaction(); |
| 1524 | if( P("clear")!=0 ){ |
| 1525 | db_multi_exec("DELETE FROM config WHERE name='css'"); |
| 1526 | cgi_replace_parameter("css", builtin_text("skins/default/css.txt")); |
| 1527 | db_end_transaction(0); |
| 1528 | cgi_redirect("setup_editcss"); |
| 1529 | } |
| 1530 | if( P("submit")!=0 ){ |
| 1531 | textarea_attribute(0, 0, 0, "css", "css", |
| 1532 | builtin_text("skins/default/css.txt"), 0); |
| 1533 | db_end_transaction(0); |
| 1534 | cgi_redirect("setup_editcss"); |
| 1535 | } |
| 1536 | style_header("Edit CSS"); |
| 1537 | @ <form action="%s(g.zTop)/setup_editcss" method="post"><div> |
| 1538 | login_insert_csrf_secret(); |
| 1539 | @ Edit the CSS below:<br /> |
| 1540 | textarea_attribute("", 35, 80, "css", "css", |
| 1541 | builtin_text("skins/default/css.txt"), 0); |
| 1542 | @ <br /> |
| 1543 | @ <input type="submit" name="submit" value="Apply Changes" /> |
| 1544 | @ <input type="submit" name="clear" value="Revert To Default" /> |
| 1545 | @ </div></form> |
| 1546 | @ <p><span class="note">Note:</span> Press your browser Reload button after |
| @@ -1570,17 +1566,17 @@ | |
| 1566 | login_needed(); |
| 1567 | } |
| 1568 | db_begin_transaction(); |
| 1569 | if( P("clear")!=0 ){ |
| 1570 | db_multi_exec("DELETE FROM config WHERE name='header'"); |
| 1571 | cgi_replace_parameter("header", builtin_text("skins/default/header.txt")); |
| 1572 | }else if( P("submit")!=0 ){ |
| 1573 | textarea_attribute(0, 0, 0, "header", "header", |
| 1574 | builtin_text("skins/default/header.txt"), 0); |
| 1575 | }else if( P("fixbase")!=0 ){ |
| 1576 | const char *z = db_get("header", |
| 1577 | (char*)builtin_text("skins/default/header.txt")); |
| 1578 | char *zHead = strstr(z, "<head>"); |
| 1579 | if( strstr(z, "<base href=")==0 && zHead!=0 ){ |
| 1580 | char *zNew; |
| 1581 | char *zTail = &zHead[6]; |
| 1582 | while( fossil_isspace(zTail[0]) ) zTail++; |
| @@ -1606,11 +1602,11 @@ | |
| 1602 | login_insert_csrf_secret(); |
| 1603 | @ <p>Edit HTML text with embedded TH1 (a Tcl dialect) that will be used to |
| 1604 | @ generate the beginning of every page through start of the main |
| 1605 | @ menu.</p> |
| 1606 | textarea_attribute("", 35, 80, "header", "header", |
| 1607 | builtin_text("skins/default/header.txt"), 0); |
| 1608 | @ <br /> |
| 1609 | @ <input type="submit" name="submit" value="Apply Changes" /> |
| 1610 | @ <input type="submit" name="clear" value="Revert To Default" /> |
| 1611 | @ </div></form> |
| 1612 | @ <hr /> |
| @@ -1617,11 +1613,11 @@ | |
| 1613 | @ The default header is shown below for reference. Other examples |
| 1614 | @ of headers can be seen on the <a href="setup_skin">skins page</a>. |
| 1615 | @ See also the <a href="setup_editcss">CSS</a> and |
| 1616 | @ <a href="setup_footer">footer</a> editing screens. |
| 1617 | @ <blockquote><pre> |
| 1618 | @ %h(builtin_text("skins/default/header.txt")) |
| 1619 | @ </pre></blockquote> |
| 1620 | style_footer(); |
| 1621 | db_end_transaction(0); |
| 1622 | } |
| 1623 | |
| @@ -1634,20 +1630,20 @@ | |
| 1630 | login_needed(); |
| 1631 | } |
| 1632 | db_begin_transaction(); |
| 1633 | if( P("clear")!=0 ){ |
| 1634 | db_multi_exec("DELETE FROM config WHERE name='footer'"); |
| 1635 | cgi_replace_parameter("footer", builtin_text("skins/default/footer.txt")); |
| 1636 | } |
| 1637 | |
| 1638 | style_header("Edit Page Footer"); |
| 1639 | @ <form action="%s(g.zTop)/setup_footer" method="post"><div> |
| 1640 | login_insert_csrf_secret(); |
| 1641 | @ <p>Edit HTML text with embedded TH1 (a Tcl dialect) that will be used to |
| 1642 | @ generate the end of every page.</p> |
| 1643 | textarea_attribute("", 20, 80, "footer", "footer", |
| 1644 | builtin_text("skins/default/footer.txt"), 0); |
| 1645 | @ <br /> |
| 1646 | @ <input type="submit" name="submit" value="Apply Changes" /> |
| 1647 | @ <input type="submit" name="clear" value="Revert To Default" /> |
| 1648 | @ </div></form> |
| 1649 | @ <hr /> |
| @@ -1654,11 +1650,11 @@ | |
| 1650 | @ The default footer is shown below for reference. Other examples |
| 1651 | @ of footers can be seen on the <a href="setup_skin">skins page</a>. |
| 1652 | @ See also the <a href="setup_editcss">CSS</a> and |
| 1653 | @ <a href="setup_header">header</a> editing screens. |
| 1654 | @ <blockquote><pre> |
| 1655 | @ %h(builtin_text("skins/default/footer.txt")) |
| 1656 | @ </pre></blockquote> |
| 1657 | style_footer(); |
| 1658 | db_end_transaction(0); |
| 1659 | } |
| 1660 | |
| @@ -2142,14 +2138,14 @@ | |
| 2138 | @ <th>User</th> |
| 2139 | @ <th>Page</th> |
| 2140 | @ <th width="60%%">Message</th> |
| 2141 | @ </thead><tbody> |
| 2142 | while( SQLITE_ROW == db_step(&stLog) ){ |
| 2143 | const char *zTime = db_column_text(&stLog, 0); |
| 2144 | const char *zUser = db_column_text(&stLog, 1); |
| 2145 | const char *zPage = db_column_text(&stLog, 2); |
| 2146 | const char *zMessage = db_column_text(&stLog, 3); |
| 2147 | @ <tr class="row%d(counter++%2)"> |
| 2148 | @ <td class="adminTime">%s(zTime)</td> |
| 2149 | @ <td>%s(zUser)</td> |
| 2150 | @ <td>%s(zPage)</td> |
| 2151 | @ <td>%h(zMessage)</td> |
| 2152 |
+7
-7
| --- src/sha1.c | ||
| +++ src/sha1.c | ||
| @@ -64,11 +64,11 @@ | ||
| 64 | 64 | ^block[(i+2)&15]^block[i&15],1)) |
| 65 | 65 | |
| 66 | 66 | /* |
| 67 | 67 | * (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1 |
| 68 | 68 | * |
| 69 | - * Rl0() for little-endian and Rb0() for big-endian. Endianness is | |
| 69 | + * Rl0() for little-endian and Rb0() for big-endian. Endianness is | |
| 70 | 70 | * determined at run-time. |
| 71 | 71 | */ |
| 72 | 72 | #define Rl0(v,w,x,y,z,i) \ |
| 73 | 73 | z+=((w&(x^y))^y)+blk0le(i)+0x5A827999+rol(v,5);w=ror(w,2); |
| 74 | 74 | #define Rb0(v,w,x,y,z,i) \ |
| @@ -217,11 +217,11 @@ | ||
| 217 | 217 | ** "unsigned char digest[20]" in the calling function. The SHA1 |
| 218 | 218 | ** digest is stored in the first 20 bytes. zBuf should |
| 219 | 219 | ** be "char zBuf[41]". |
| 220 | 220 | */ |
| 221 | 221 | static void DigestToBase16(unsigned char *digest, char *zBuf){ |
| 222 | - static char const zEncode[] = "0123456789abcdef"; | |
| 222 | + static const char zEncode[] = "0123456789abcdef"; | |
| 223 | 223 | int ix; |
| 224 | 224 | |
| 225 | 225 | for(ix=0; ix<20; ix++){ |
| 226 | 226 | *zBuf++ = zEncode[(*digest>>4)&0xf]; |
| 227 | 227 | *zBuf++ = zEncode[*digest++ & 0xf]; |
| @@ -258,11 +258,11 @@ | ||
| 258 | 258 | sha1sum_step_text(blob_buffer(p), blob_size(p)); |
| 259 | 259 | } |
| 260 | 260 | |
| 261 | 261 | /* |
| 262 | 262 | ** Finish the incremental SHA1 checksum. Store the result in blob pOut |
| 263 | -** if pOut!=0. Also return a pointer to the result. | |
| 263 | +** if pOut!=0. Also return a pointer to the result. | |
| 264 | 264 | ** |
| 265 | 265 | ** This resets the incremental checksum preparing for the next round |
| 266 | 266 | ** of computation. The return pointer points to a static buffer that |
| 267 | 267 | ** is overwritten by subsequent calls to this function. |
| 268 | 268 | */ |
| @@ -295,11 +295,11 @@ | ||
| 295 | 295 | |
| 296 | 296 | if( file_wd_islink(zFilename) ){ |
| 297 | 297 | /* Instead of file content, return sha1 of link destination path */ |
| 298 | 298 | Blob destinationPath; |
| 299 | 299 | int rc; |
| 300 | - | |
| 300 | + | |
| 301 | 301 | blob_read_link(&destinationPath, zFilename); |
| 302 | 302 | rc = sha1sum_blob(&destinationPath, pCksum); |
| 303 | 303 | blob_reset(&destinationPath); |
| 304 | 304 | return rc; |
| 305 | 305 | } |
| @@ -363,11 +363,11 @@ | ||
| 363 | 363 | return mprintf("%s", zDigest); |
| 364 | 364 | } |
| 365 | 365 | |
| 366 | 366 | /* |
| 367 | 367 | ** Convert a cleartext password for a specific user into a SHA1 hash. |
| 368 | -** | |
| 368 | +** | |
| 369 | 369 | ** The algorithm here is: |
| 370 | 370 | ** |
| 371 | 371 | ** SHA1( project-code + "/" + login + "/" + password ) |
| 372 | 372 | ** |
| 373 | 373 | ** In words: The users login name and password are appended to the |
| @@ -375,11 +375,11 @@ | ||
| 375 | 375 | ** |
| 376 | 376 | ** The result of this function is the shared secret used by a client |
| 377 | 377 | ** to authenticate to a server for the sync protocol. It is also the |
| 378 | 378 | ** value stored in the USER.PW field of the database. By mixing in the |
| 379 | 379 | ** login name and the project id with the hash, different shared secrets |
| 380 | -** are obtained even if two users select the same password, or if a | |
| 380 | +** are obtained even if two users select the same password, or if a | |
| 381 | 381 | ** single user selects the same password for multiple projects. |
| 382 | 382 | */ |
| 383 | 383 | char *sha1_shared_secret( |
| 384 | 384 | const char *zPw, /* The password to encrypt */ |
| 385 | 385 | const char *zLogin, /* Username */ |
| @@ -457,11 +457,11 @@ | ||
| 457 | 457 | */ |
| 458 | 458 | void sha1sum_test(void){ |
| 459 | 459 | int i; |
| 460 | 460 | Blob in; |
| 461 | 461 | Blob cksum; |
| 462 | - | |
| 462 | + | |
| 463 | 463 | for(i=2; i<g.argc; i++){ |
| 464 | 464 | blob_init(&cksum, "************** not found ***************", -1); |
| 465 | 465 | if( g.argv[i][0]=='-' && g.argv[i][1]==0 ){ |
| 466 | 466 | blob_read_from_channel(&in, stdin, -1); |
| 467 | 467 | sha1sum_blob(&in, &cksum); |
| 468 | 468 |
| --- src/sha1.c | |
| +++ src/sha1.c | |
| @@ -64,11 +64,11 @@ | |
| 64 | ^block[(i+2)&15]^block[i&15],1)) |
| 65 | |
| 66 | /* |
| 67 | * (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1 |
| 68 | * |
| 69 | * Rl0() for little-endian and Rb0() for big-endian. Endianness is |
| 70 | * determined at run-time. |
| 71 | */ |
| 72 | #define Rl0(v,w,x,y,z,i) \ |
| 73 | z+=((w&(x^y))^y)+blk0le(i)+0x5A827999+rol(v,5);w=ror(w,2); |
| 74 | #define Rb0(v,w,x,y,z,i) \ |
| @@ -217,11 +217,11 @@ | |
| 217 | ** "unsigned char digest[20]" in the calling function. The SHA1 |
| 218 | ** digest is stored in the first 20 bytes. zBuf should |
| 219 | ** be "char zBuf[41]". |
| 220 | */ |
| 221 | static void DigestToBase16(unsigned char *digest, char *zBuf){ |
| 222 | static char const zEncode[] = "0123456789abcdef"; |
| 223 | int ix; |
| 224 | |
| 225 | for(ix=0; ix<20; ix++){ |
| 226 | *zBuf++ = zEncode[(*digest>>4)&0xf]; |
| 227 | *zBuf++ = zEncode[*digest++ & 0xf]; |
| @@ -258,11 +258,11 @@ | |
| 258 | sha1sum_step_text(blob_buffer(p), blob_size(p)); |
| 259 | } |
| 260 | |
| 261 | /* |
| 262 | ** Finish the incremental SHA1 checksum. Store the result in blob pOut |
| 263 | ** if pOut!=0. Also return a pointer to the result. |
| 264 | ** |
| 265 | ** This resets the incremental checksum preparing for the next round |
| 266 | ** of computation. The return pointer points to a static buffer that |
| 267 | ** is overwritten by subsequent calls to this function. |
| 268 | */ |
| @@ -295,11 +295,11 @@ | |
| 295 | |
| 296 | if( file_wd_islink(zFilename) ){ |
| 297 | /* Instead of file content, return sha1 of link destination path */ |
| 298 | Blob destinationPath; |
| 299 | int rc; |
| 300 | |
| 301 | blob_read_link(&destinationPath, zFilename); |
| 302 | rc = sha1sum_blob(&destinationPath, pCksum); |
| 303 | blob_reset(&destinationPath); |
| 304 | return rc; |
| 305 | } |
| @@ -363,11 +363,11 @@ | |
| 363 | return mprintf("%s", zDigest); |
| 364 | } |
| 365 | |
| 366 | /* |
| 367 | ** Convert a cleartext password for a specific user into a SHA1 hash. |
| 368 | ** |
| 369 | ** The algorithm here is: |
| 370 | ** |
| 371 | ** SHA1( project-code + "/" + login + "/" + password ) |
| 372 | ** |
| 373 | ** In words: The users login name and password are appended to the |
| @@ -375,11 +375,11 @@ | |
| 375 | ** |
| 376 | ** The result of this function is the shared secret used by a client |
| 377 | ** to authenticate to a server for the sync protocol. It is also the |
| 378 | ** value stored in the USER.PW field of the database. By mixing in the |
| 379 | ** login name and the project id with the hash, different shared secrets |
| 380 | ** are obtained even if two users select the same password, or if a |
| 381 | ** single user selects the same password for multiple projects. |
| 382 | */ |
| 383 | char *sha1_shared_secret( |
| 384 | const char *zPw, /* The password to encrypt */ |
| 385 | const char *zLogin, /* Username */ |
| @@ -457,11 +457,11 @@ | |
| 457 | */ |
| 458 | void sha1sum_test(void){ |
| 459 | int i; |
| 460 | Blob in; |
| 461 | Blob cksum; |
| 462 | |
| 463 | for(i=2; i<g.argc; i++){ |
| 464 | blob_init(&cksum, "************** not found ***************", -1); |
| 465 | if( g.argv[i][0]=='-' && g.argv[i][1]==0 ){ |
| 466 | blob_read_from_channel(&in, stdin, -1); |
| 467 | sha1sum_blob(&in, &cksum); |
| 468 |
| --- src/sha1.c | |
| +++ src/sha1.c | |
| @@ -64,11 +64,11 @@ | |
| 64 | ^block[(i+2)&15]^block[i&15],1)) |
| 65 | |
| 66 | /* |
| 67 | * (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1 |
| 68 | * |
| 69 | * Rl0() for little-endian and Rb0() for big-endian. Endianness is |
| 70 | * determined at run-time. |
| 71 | */ |
| 72 | #define Rl0(v,w,x,y,z,i) \ |
| 73 | z+=((w&(x^y))^y)+blk0le(i)+0x5A827999+rol(v,5);w=ror(w,2); |
| 74 | #define Rb0(v,w,x,y,z,i) \ |
| @@ -217,11 +217,11 @@ | |
| 217 | ** "unsigned char digest[20]" in the calling function. The SHA1 |
| 218 | ** digest is stored in the first 20 bytes. zBuf should |
| 219 | ** be "char zBuf[41]". |
| 220 | */ |
| 221 | static void DigestToBase16(unsigned char *digest, char *zBuf){ |
| 222 | static const char zEncode[] = "0123456789abcdef"; |
| 223 | int ix; |
| 224 | |
| 225 | for(ix=0; ix<20; ix++){ |
| 226 | *zBuf++ = zEncode[(*digest>>4)&0xf]; |
| 227 | *zBuf++ = zEncode[*digest++ & 0xf]; |
| @@ -258,11 +258,11 @@ | |
| 258 | sha1sum_step_text(blob_buffer(p), blob_size(p)); |
| 259 | } |
| 260 | |
| 261 | /* |
| 262 | ** Finish the incremental SHA1 checksum. Store the result in blob pOut |
| 263 | ** if pOut!=0. Also return a pointer to the result. |
| 264 | ** |
| 265 | ** This resets the incremental checksum preparing for the next round |
| 266 | ** of computation. The return pointer points to a static buffer that |
| 267 | ** is overwritten by subsequent calls to this function. |
| 268 | */ |
| @@ -295,11 +295,11 @@ | |
| 295 | |
| 296 | if( file_wd_islink(zFilename) ){ |
| 297 | /* Instead of file content, return sha1 of link destination path */ |
| 298 | Blob destinationPath; |
| 299 | int rc; |
| 300 | |
| 301 | blob_read_link(&destinationPath, zFilename); |
| 302 | rc = sha1sum_blob(&destinationPath, pCksum); |
| 303 | blob_reset(&destinationPath); |
| 304 | return rc; |
| 305 | } |
| @@ -363,11 +363,11 @@ | |
| 363 | return mprintf("%s", zDigest); |
| 364 | } |
| 365 | |
| 366 | /* |
| 367 | ** Convert a cleartext password for a specific user into a SHA1 hash. |
| 368 | ** |
| 369 | ** The algorithm here is: |
| 370 | ** |
| 371 | ** SHA1( project-code + "/" + login + "/" + password ) |
| 372 | ** |
| 373 | ** In words: The users login name and password are appended to the |
| @@ -375,11 +375,11 @@ | |
| 375 | ** |
| 376 | ** The result of this function is the shared secret used by a client |
| 377 | ** to authenticate to a server for the sync protocol. It is also the |
| 378 | ** value stored in the USER.PW field of the database. By mixing in the |
| 379 | ** login name and the project id with the hash, different shared secrets |
| 380 | ** are obtained even if two users select the same password, or if a |
| 381 | ** single user selects the same password for multiple projects. |
| 382 | */ |
| 383 | char *sha1_shared_secret( |
| 384 | const char *zPw, /* The password to encrypt */ |
| 385 | const char *zLogin, /* Username */ |
| @@ -457,11 +457,11 @@ | |
| 457 | */ |
| 458 | void sha1sum_test(void){ |
| 459 | int i; |
| 460 | Blob in; |
| 461 | Blob cksum; |
| 462 | |
| 463 | for(i=2; i<g.argc; i++){ |
| 464 | blob_init(&cksum, "************** not found ***************", -1); |
| 465 | if( g.argv[i][0]=='-' && g.argv[i][1]==0 ){ |
| 466 | blob_read_from_channel(&in, stdin, -1); |
| 467 | sha1sum_blob(&in, &cksum); |
| 468 |
+30
-10
| --- src/shell.c | ||
| +++ src/shell.c | ||
| @@ -104,10 +104,30 @@ | ||
| 104 | 104 | /* ctype macros that work with signed characters */ |
| 105 | 105 | #define IsSpace(X) isspace((unsigned char)X) |
| 106 | 106 | #define IsDigit(X) isdigit((unsigned char)X) |
| 107 | 107 | #define ToLower(X) (char)tolower((unsigned char)X) |
| 108 | 108 | |
| 109 | +/* On Windows, we normally run with output mode of TEXT so that \n characters | |
| 110 | +** are automatically translated into \r\n. However, this behavior needs | |
| 111 | +** to be disabled in some cases (ex: when generating CSV output and when | |
| 112 | +** rendering quoted strings that contain \n characters). The following | |
| 113 | +** routines take care of that. | |
| 114 | +*/ | |
| 115 | +#if defined(_WIN32) || defined(WIN32) | |
| 116 | +static void setBinaryMode(FILE *out){ | |
| 117 | + fflush(out); | |
| 118 | + _setmode(_fileno(out), _O_BINARY); | |
| 119 | +} | |
| 120 | +static void setTextMode(FILE *out){ | |
| 121 | + fflush(out); | |
| 122 | + _setmode(_fileno(out), _O_TEXT); | |
| 123 | +} | |
| 124 | +#else | |
| 125 | +# define setBinaryMode(X) | |
| 126 | +# define setTextMode(X) | |
| 127 | +#endif | |
| 128 | + | |
| 109 | 129 | |
| 110 | 130 | /* True if the timer is enabled */ |
| 111 | 131 | static int enableTimer = 0; |
| 112 | 132 | |
| 113 | 133 | /* Return the current wall-clock time */ |
| @@ -582,10 +602,11 @@ | ||
| 582 | 602 | ** Output the given string as a quoted string using SQL quoting conventions. |
| 583 | 603 | */ |
| 584 | 604 | static void output_quoted_string(FILE *out, const char *z){ |
| 585 | 605 | int i; |
| 586 | 606 | int nSingle = 0; |
| 607 | + setBinaryMode(out); | |
| 587 | 608 | for(i=0; z[i]; i++){ |
| 588 | 609 | if( z[i]=='\'' ) nSingle++; |
| 589 | 610 | } |
| 590 | 611 | if( nSingle==0 ){ |
| 591 | 612 | fprintf(out,"'%s'",z); |
| @@ -604,10 +625,11 @@ | ||
| 604 | 625 | break; |
| 605 | 626 | } |
| 606 | 627 | } |
| 607 | 628 | fprintf(out,"'"); |
| 608 | 629 | } |
| 630 | + setTextMode(out); | |
| 609 | 631 | } |
| 610 | 632 | |
| 611 | 633 | /* |
| 612 | 634 | ** Output the given string as a quoted according to C or TCL quoting rules. |
| 613 | 635 | */ |
| @@ -906,14 +928,11 @@ | ||
| 906 | 928 | } |
| 907 | 929 | fprintf(p->out, "%s", p->rowSeparator); |
| 908 | 930 | break; |
| 909 | 931 | } |
| 910 | 932 | case MODE_Csv: { |
| 911 | -#if defined(WIN32) || defined(_WIN32) | |
| 912 | - fflush(p->out); | |
| 913 | - _setmode(_fileno(p->out), _O_BINARY); | |
| 914 | -#endif | |
| 933 | + setBinaryMode(p->out); | |
| 915 | 934 | if( p->cnt++==0 && p->showHeader ){ |
| 916 | 935 | for(i=0; i<nArg; i++){ |
| 917 | 936 | output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1); |
| 918 | 937 | } |
| 919 | 938 | fprintf(p->out, "%s", p->rowSeparator); |
| @@ -922,14 +941,11 @@ | ||
| 922 | 941 | for(i=0; i<nArg; i++){ |
| 923 | 942 | output_csv(p, azArg[i], i<nArg-1); |
| 924 | 943 | } |
| 925 | 944 | fprintf(p->out, "%s", p->rowSeparator); |
| 926 | 945 | } |
| 927 | -#if defined(WIN32) || defined(_WIN32) | |
| 928 | - fflush(p->out); | |
| 929 | - _setmode(_fileno(p->out), _O_TEXT); | |
| 930 | -#endif | |
| 946 | + setTextMode(p->out); | |
| 931 | 947 | break; |
| 932 | 948 | } |
| 933 | 949 | case MODE_Insert: { |
| 934 | 950 | p->cnt++; |
| 935 | 951 | if( azArg==0 ) break; |
| @@ -3322,11 +3338,11 @@ | ||
| 3322 | 3338 | |
| 3323 | 3339 | |
| 3324 | 3340 | #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) |
| 3325 | 3341 | if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){ |
| 3326 | 3342 | extern int sqlite3SelectTrace; |
| 3327 | - sqlite3SelectTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff; | |
| 3343 | + sqlite3SelectTrace = integerValue(azArg[1]); | |
| 3328 | 3344 | }else |
| 3329 | 3345 | #endif |
| 3330 | 3346 | |
| 3331 | 3347 | |
| 3332 | 3348 | #ifdef SQLITE_DEBUG |
| @@ -3528,10 +3544,11 @@ | ||
| 3528 | 3544 | { "reserve", SQLITE_TESTCTRL_RESERVE }, |
| 3529 | 3545 | { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS }, |
| 3530 | 3546 | { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD }, |
| 3531 | 3547 | { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC }, |
| 3532 | 3548 | { "byteorder", SQLITE_TESTCTRL_BYTEORDER }, |
| 3549 | + { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT }, | |
| 3533 | 3550 | }; |
| 3534 | 3551 | int testctrl = -1; |
| 3535 | 3552 | int rc = 0; |
| 3536 | 3553 | int i, n; |
| 3537 | 3554 | open_db(p, 0); |
| @@ -3594,11 +3611,12 @@ | ||
| 3594 | 3611 | } |
| 3595 | 3612 | break; |
| 3596 | 3613 | |
| 3597 | 3614 | /* sqlite3_test_control(int, int) */ |
| 3598 | 3615 | case SQLITE_TESTCTRL_ASSERT: |
| 3599 | - case SQLITE_TESTCTRL_ALWAYS: | |
| 3616 | + case SQLITE_TESTCTRL_ALWAYS: | |
| 3617 | + case SQLITE_TESTCTRL_NEVER_CORRUPT: | |
| 3600 | 3618 | if( nArg==3 ){ |
| 3601 | 3619 | int opt = booleanValue(azArg[2]); |
| 3602 | 3620 | rc = sqlite3_test_control(testctrl, opt); |
| 3603 | 3621 | fprintf(p->out, "%d (0x%08x)\n", rc, rc); |
| 3604 | 3622 | } else { |
| @@ -4185,10 +4203,12 @@ | ||
| 4185 | 4203 | fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n", |
| 4186 | 4204 | sqlite3_sourceid(), SQLITE_SOURCE_ID); |
| 4187 | 4205 | exit(1); |
| 4188 | 4206 | } |
| 4189 | 4207 | #endif |
| 4208 | + setBinaryMode(stdin); | |
| 4209 | + setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */ | |
| 4190 | 4210 | Argv0 = argv[0]; |
| 4191 | 4211 | main_init(&data); |
| 4192 | 4212 | stdin_is_interactive = isatty(0); |
| 4193 | 4213 | |
| 4194 | 4214 | /* Make sure we have a valid signal handler early, before anything |
| 4195 | 4215 |
| --- src/shell.c | |
| +++ src/shell.c | |
| @@ -104,10 +104,30 @@ | |
| 104 | /* ctype macros that work with signed characters */ |
| 105 | #define IsSpace(X) isspace((unsigned char)X) |
| 106 | #define IsDigit(X) isdigit((unsigned char)X) |
| 107 | #define ToLower(X) (char)tolower((unsigned char)X) |
| 108 | |
| 109 | |
| 110 | /* True if the timer is enabled */ |
| 111 | static int enableTimer = 0; |
| 112 | |
| 113 | /* Return the current wall-clock time */ |
| @@ -582,10 +602,11 @@ | |
| 582 | ** Output the given string as a quoted string using SQL quoting conventions. |
| 583 | */ |
| 584 | static void output_quoted_string(FILE *out, const char *z){ |
| 585 | int i; |
| 586 | int nSingle = 0; |
| 587 | for(i=0; z[i]; i++){ |
| 588 | if( z[i]=='\'' ) nSingle++; |
| 589 | } |
| 590 | if( nSingle==0 ){ |
| 591 | fprintf(out,"'%s'",z); |
| @@ -604,10 +625,11 @@ | |
| 604 | break; |
| 605 | } |
| 606 | } |
| 607 | fprintf(out,"'"); |
| 608 | } |
| 609 | } |
| 610 | |
| 611 | /* |
| 612 | ** Output the given string as a quoted according to C or TCL quoting rules. |
| 613 | */ |
| @@ -906,14 +928,11 @@ | |
| 906 | } |
| 907 | fprintf(p->out, "%s", p->rowSeparator); |
| 908 | break; |
| 909 | } |
| 910 | case MODE_Csv: { |
| 911 | #if defined(WIN32) || defined(_WIN32) |
| 912 | fflush(p->out); |
| 913 | _setmode(_fileno(p->out), _O_BINARY); |
| 914 | #endif |
| 915 | if( p->cnt++==0 && p->showHeader ){ |
| 916 | for(i=0; i<nArg; i++){ |
| 917 | output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1); |
| 918 | } |
| 919 | fprintf(p->out, "%s", p->rowSeparator); |
| @@ -922,14 +941,11 @@ | |
| 922 | for(i=0; i<nArg; i++){ |
| 923 | output_csv(p, azArg[i], i<nArg-1); |
| 924 | } |
| 925 | fprintf(p->out, "%s", p->rowSeparator); |
| 926 | } |
| 927 | #if defined(WIN32) || defined(_WIN32) |
| 928 | fflush(p->out); |
| 929 | _setmode(_fileno(p->out), _O_TEXT); |
| 930 | #endif |
| 931 | break; |
| 932 | } |
| 933 | case MODE_Insert: { |
| 934 | p->cnt++; |
| 935 | if( azArg==0 ) break; |
| @@ -3322,11 +3338,11 @@ | |
| 3322 | |
| 3323 | |
| 3324 | #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) |
| 3325 | if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){ |
| 3326 | extern int sqlite3SelectTrace; |
| 3327 | sqlite3SelectTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff; |
| 3328 | }else |
| 3329 | #endif |
| 3330 | |
| 3331 | |
| 3332 | #ifdef SQLITE_DEBUG |
| @@ -3528,10 +3544,11 @@ | |
| 3528 | { "reserve", SQLITE_TESTCTRL_RESERVE }, |
| 3529 | { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS }, |
| 3530 | { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD }, |
| 3531 | { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC }, |
| 3532 | { "byteorder", SQLITE_TESTCTRL_BYTEORDER }, |
| 3533 | }; |
| 3534 | int testctrl = -1; |
| 3535 | int rc = 0; |
| 3536 | int i, n; |
| 3537 | open_db(p, 0); |
| @@ -3594,11 +3611,12 @@ | |
| 3594 | } |
| 3595 | break; |
| 3596 | |
| 3597 | /* sqlite3_test_control(int, int) */ |
| 3598 | case SQLITE_TESTCTRL_ASSERT: |
| 3599 | case SQLITE_TESTCTRL_ALWAYS: |
| 3600 | if( nArg==3 ){ |
| 3601 | int opt = booleanValue(azArg[2]); |
| 3602 | rc = sqlite3_test_control(testctrl, opt); |
| 3603 | fprintf(p->out, "%d (0x%08x)\n", rc, rc); |
| 3604 | } else { |
| @@ -4185,10 +4203,12 @@ | |
| 4185 | fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n", |
| 4186 | sqlite3_sourceid(), SQLITE_SOURCE_ID); |
| 4187 | exit(1); |
| 4188 | } |
| 4189 | #endif |
| 4190 | Argv0 = argv[0]; |
| 4191 | main_init(&data); |
| 4192 | stdin_is_interactive = isatty(0); |
| 4193 | |
| 4194 | /* Make sure we have a valid signal handler early, before anything |
| 4195 |
| --- src/shell.c | |
| +++ src/shell.c | |
| @@ -104,10 +104,30 @@ | |
| 104 | /* ctype macros that work with signed characters */ |
| 105 | #define IsSpace(X) isspace((unsigned char)X) |
| 106 | #define IsDigit(X) isdigit((unsigned char)X) |
| 107 | #define ToLower(X) (char)tolower((unsigned char)X) |
| 108 | |
| 109 | /* On Windows, we normally run with output mode of TEXT so that \n characters |
| 110 | ** are automatically translated into \r\n. However, this behavior needs |
| 111 | ** to be disabled in some cases (ex: when generating CSV output and when |
| 112 | ** rendering quoted strings that contain \n characters). The following |
| 113 | ** routines take care of that. |
| 114 | */ |
| 115 | #if defined(_WIN32) || defined(WIN32) |
| 116 | static void setBinaryMode(FILE *out){ |
| 117 | fflush(out); |
| 118 | _setmode(_fileno(out), _O_BINARY); |
| 119 | } |
| 120 | static void setTextMode(FILE *out){ |
| 121 | fflush(out); |
| 122 | _setmode(_fileno(out), _O_TEXT); |
| 123 | } |
| 124 | #else |
| 125 | # define setBinaryMode(X) |
| 126 | # define setTextMode(X) |
| 127 | #endif |
| 128 | |
| 129 | |
| 130 | /* True if the timer is enabled */ |
| 131 | static int enableTimer = 0; |
| 132 | |
| 133 | /* Return the current wall-clock time */ |
| @@ -582,10 +602,11 @@ | |
| 602 | ** Output the given string as a quoted string using SQL quoting conventions. |
| 603 | */ |
| 604 | static void output_quoted_string(FILE *out, const char *z){ |
| 605 | int i; |
| 606 | int nSingle = 0; |
| 607 | setBinaryMode(out); |
| 608 | for(i=0; z[i]; i++){ |
| 609 | if( z[i]=='\'' ) nSingle++; |
| 610 | } |
| 611 | if( nSingle==0 ){ |
| 612 | fprintf(out,"'%s'",z); |
| @@ -604,10 +625,11 @@ | |
| 625 | break; |
| 626 | } |
| 627 | } |
| 628 | fprintf(out,"'"); |
| 629 | } |
| 630 | setTextMode(out); |
| 631 | } |
| 632 | |
| 633 | /* |
| 634 | ** Output the given string as a quoted according to C or TCL quoting rules. |
| 635 | */ |
| @@ -906,14 +928,11 @@ | |
| 928 | } |
| 929 | fprintf(p->out, "%s", p->rowSeparator); |
| 930 | break; |
| 931 | } |
| 932 | case MODE_Csv: { |
| 933 | setBinaryMode(p->out); |
| 934 | if( p->cnt++==0 && p->showHeader ){ |
| 935 | for(i=0; i<nArg; i++){ |
| 936 | output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1); |
| 937 | } |
| 938 | fprintf(p->out, "%s", p->rowSeparator); |
| @@ -922,14 +941,11 @@ | |
| 941 | for(i=0; i<nArg; i++){ |
| 942 | output_csv(p, azArg[i], i<nArg-1); |
| 943 | } |
| 944 | fprintf(p->out, "%s", p->rowSeparator); |
| 945 | } |
| 946 | setTextMode(p->out); |
| 947 | break; |
| 948 | } |
| 949 | case MODE_Insert: { |
| 950 | p->cnt++; |
| 951 | if( azArg==0 ) break; |
| @@ -3322,11 +3338,11 @@ | |
| 3338 | |
| 3339 | |
| 3340 | #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) |
| 3341 | if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){ |
| 3342 | extern int sqlite3SelectTrace; |
| 3343 | sqlite3SelectTrace = integerValue(azArg[1]); |
| 3344 | }else |
| 3345 | #endif |
| 3346 | |
| 3347 | |
| 3348 | #ifdef SQLITE_DEBUG |
| @@ -3528,10 +3544,11 @@ | |
| 3544 | { "reserve", SQLITE_TESTCTRL_RESERVE }, |
| 3545 | { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS }, |
| 3546 | { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD }, |
| 3547 | { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC }, |
| 3548 | { "byteorder", SQLITE_TESTCTRL_BYTEORDER }, |
| 3549 | { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT }, |
| 3550 | }; |
| 3551 | int testctrl = -1; |
| 3552 | int rc = 0; |
| 3553 | int i, n; |
| 3554 | open_db(p, 0); |
| @@ -3594,11 +3611,12 @@ | |
| 3611 | } |
| 3612 | break; |
| 3613 | |
| 3614 | /* sqlite3_test_control(int, int) */ |
| 3615 | case SQLITE_TESTCTRL_ASSERT: |
| 3616 | case SQLITE_TESTCTRL_ALWAYS: |
| 3617 | case SQLITE_TESTCTRL_NEVER_CORRUPT: |
| 3618 | if( nArg==3 ){ |
| 3619 | int opt = booleanValue(azArg[2]); |
| 3620 | rc = sqlite3_test_control(testctrl, opt); |
| 3621 | fprintf(p->out, "%d (0x%08x)\n", rc, rc); |
| 3622 | } else { |
| @@ -4185,10 +4203,12 @@ | |
| 4203 | fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n", |
| 4204 | sqlite3_sourceid(), SQLITE_SOURCE_ID); |
| 4205 | exit(1); |
| 4206 | } |
| 4207 | #endif |
| 4208 | setBinaryMode(stdin); |
| 4209 | setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */ |
| 4210 | Argv0 = argv[0]; |
| 4211 | main_init(&data); |
| 4212 | stdin_is_interactive = isatty(0); |
| 4213 | |
| 4214 | /* Make sure we have a valid signal handler early, before anything |
| 4215 |
+1
-1
| --- src/sqlcmd.c | ||
| +++ src/sqlcmd.c | ||
| @@ -108,11 +108,11 @@ | ||
| 108 | 108 | sqlite3_result_error(context, "input is not zlib compressed", -1); |
| 109 | 109 | } |
| 110 | 110 | } |
| 111 | 111 | |
| 112 | 112 | /* |
| 113 | -** Add the content(), compress(), and decompress() SQL functions to | |
| 113 | +** Add the content(), compress(), and decompress() SQL functions to | |
| 114 | 114 | ** database connection db. |
| 115 | 115 | */ |
| 116 | 116 | int add_content_sql_commands(sqlite3 *db){ |
| 117 | 117 | sqlite3_create_function(db, "content", 1, SQLITE_UTF8, 0, |
| 118 | 118 | sqlcmd_content, 0, 0); |
| 119 | 119 |
| --- src/sqlcmd.c | |
| +++ src/sqlcmd.c | |
| @@ -108,11 +108,11 @@ | |
| 108 | sqlite3_result_error(context, "input is not zlib compressed", -1); |
| 109 | } |
| 110 | } |
| 111 | |
| 112 | /* |
| 113 | ** Add the content(), compress(), and decompress() SQL functions to |
| 114 | ** database connection db. |
| 115 | */ |
| 116 | int add_content_sql_commands(sqlite3 *db){ |
| 117 | sqlite3_create_function(db, "content", 1, SQLITE_UTF8, 0, |
| 118 | sqlcmd_content, 0, 0); |
| 119 |
| --- src/sqlcmd.c | |
| +++ src/sqlcmd.c | |
| @@ -108,11 +108,11 @@ | |
| 108 | sqlite3_result_error(context, "input is not zlib compressed", -1); |
| 109 | } |
| 110 | } |
| 111 | |
| 112 | /* |
| 113 | ** Add the content(), compress(), and decompress() SQL functions to |
| 114 | ** database connection db. |
| 115 | */ |
| 116 | int add_content_sql_commands(sqlite3 *db){ |
| 117 | sqlite3_create_function(db, "content", 1, SQLITE_UTF8, 0, |
| 118 | sqlcmd_content, 0, 0); |
| 119 |
+3
| --- src/stat.c | ||
| +++ src/stat.c | ||
| @@ -61,10 +61,11 @@ | ||
| 61 | 61 | if( g.perm.Admin ){ |
| 62 | 62 | style_submenu_element("URLs", "URLs and Checkouts", "urllist"); |
| 63 | 63 | style_submenu_element("Schema", "Repository Schema", "repo_schema"); |
| 64 | 64 | style_submenu_element("Web-Cache", "Web-Cache Stats", "cachestat"); |
| 65 | 65 | } |
| 66 | + style_submenu_element("Activity", "Activity Reports", "reports"); | |
| 66 | 67 | @ <table class="label-value"> |
| 67 | 68 | @ <tr><th>Repository Size:</th><td> |
| 68 | 69 | fsize = file_size(g.zRepositoryName); |
| 69 | 70 | bigSizeName(sizeof(zBuf), zBuf, fsize); |
| 70 | 71 | @ %s(zBuf) |
| @@ -133,10 +134,11 @@ | ||
| 133 | 134 | @ %h(MANIFEST_DATE) %h(MANIFEST_VERSION) |
| 134 | 135 | @ (%h(RELEASE_VERSION)) [compiled using %h(COMPILER_NAME)] |
| 135 | 136 | @ </td></tr> |
| 136 | 137 | @ <tr><th>SQLite Version:</th><td>%.19s(sqlite3_sourceid()) |
| 137 | 138 | @ [%.10s(&sqlite3_sourceid()[20])] (%s(sqlite3_libversion()))</td></tr> |
| 139 | + @ <tr><th>Schema Version:</th><td>%h(g.zAuxSchema)</td></tr> | |
| 138 | 140 | @ <tr><th>Repository Rebuilt:</th><td> |
| 139 | 141 | @ %h(db_get_mtime("rebuilt","%Y-%m-%d %H:%M:%S","Never")) |
| 140 | 142 | @ By Fossil %h(db_get("rebuilt","Unknown"))</td></tr> |
| 141 | 143 | @ <tr><th>Database Stats:</th><td> |
| 142 | 144 | zDb = db_name("repository"); |
| @@ -254,10 +256,11 @@ | ||
| 254 | 256 | } |
| 255 | 257 | #if 0 |
| 256 | 258 | /* Server-id is not useful information any more */ |
| 257 | 259 | fossil_print("%*s%s\n", colWidth, "server-id:", db_get("server-code", 0)); |
| 258 | 260 | #endif |
| 261 | + fossil_print("%*s%s\n", colWidth, "schema-version:", g.zAuxSchema); | |
| 259 | 262 | if( !omitVers ){ |
| 260 | 263 | fossil_print("%*s%s %s [%s] (%s)\n", |
| 261 | 264 | colWidth, "fossil-version:", |
| 262 | 265 | MANIFEST_DATE, MANIFEST_VERSION, RELEASE_VERSION, |
| 263 | 266 | COMPILER_NAME); |
| 264 | 267 | |
| 265 | 268 | ADDED src/statrep.c |
| --- src/stat.c | |
| +++ src/stat.c | |
| @@ -61,10 +61,11 @@ | |
| 61 | if( g.perm.Admin ){ |
| 62 | style_submenu_element("URLs", "URLs and Checkouts", "urllist"); |
| 63 | style_submenu_element("Schema", "Repository Schema", "repo_schema"); |
| 64 | style_submenu_element("Web-Cache", "Web-Cache Stats", "cachestat"); |
| 65 | } |
| 66 | @ <table class="label-value"> |
| 67 | @ <tr><th>Repository Size:</th><td> |
| 68 | fsize = file_size(g.zRepositoryName); |
| 69 | bigSizeName(sizeof(zBuf), zBuf, fsize); |
| 70 | @ %s(zBuf) |
| @@ -133,10 +134,11 @@ | |
| 133 | @ %h(MANIFEST_DATE) %h(MANIFEST_VERSION) |
| 134 | @ (%h(RELEASE_VERSION)) [compiled using %h(COMPILER_NAME)] |
| 135 | @ </td></tr> |
| 136 | @ <tr><th>SQLite Version:</th><td>%.19s(sqlite3_sourceid()) |
| 137 | @ [%.10s(&sqlite3_sourceid()[20])] (%s(sqlite3_libversion()))</td></tr> |
| 138 | @ <tr><th>Repository Rebuilt:</th><td> |
| 139 | @ %h(db_get_mtime("rebuilt","%Y-%m-%d %H:%M:%S","Never")) |
| 140 | @ By Fossil %h(db_get("rebuilt","Unknown"))</td></tr> |
| 141 | @ <tr><th>Database Stats:</th><td> |
| 142 | zDb = db_name("repository"); |
| @@ -254,10 +256,11 @@ | |
| 254 | } |
| 255 | #if 0 |
| 256 | /* Server-id is not useful information any more */ |
| 257 | fossil_print("%*s%s\n", colWidth, "server-id:", db_get("server-code", 0)); |
| 258 | #endif |
| 259 | if( !omitVers ){ |
| 260 | fossil_print("%*s%s %s [%s] (%s)\n", |
| 261 | colWidth, "fossil-version:", |
| 262 | MANIFEST_DATE, MANIFEST_VERSION, RELEASE_VERSION, |
| 263 | COMPILER_NAME); |
| 264 | |
| 265 | DDED src/statrep.c |
| --- src/stat.c | |
| +++ src/stat.c | |
| @@ -61,10 +61,11 @@ | |
| 61 | if( g.perm.Admin ){ |
| 62 | style_submenu_element("URLs", "URLs and Checkouts", "urllist"); |
| 63 | style_submenu_element("Schema", "Repository Schema", "repo_schema"); |
| 64 | style_submenu_element("Web-Cache", "Web-Cache Stats", "cachestat"); |
| 65 | } |
| 66 | style_submenu_element("Activity", "Activity Reports", "reports"); |
| 67 | @ <table class="label-value"> |
| 68 | @ <tr><th>Repository Size:</th><td> |
| 69 | fsize = file_size(g.zRepositoryName); |
| 70 | bigSizeName(sizeof(zBuf), zBuf, fsize); |
| 71 | @ %s(zBuf) |
| @@ -133,10 +134,11 @@ | |
| 134 | @ %h(MANIFEST_DATE) %h(MANIFEST_VERSION) |
| 135 | @ (%h(RELEASE_VERSION)) [compiled using %h(COMPILER_NAME)] |
| 136 | @ </td></tr> |
| 137 | @ <tr><th>SQLite Version:</th><td>%.19s(sqlite3_sourceid()) |
| 138 | @ [%.10s(&sqlite3_sourceid()[20])] (%s(sqlite3_libversion()))</td></tr> |
| 139 | @ <tr><th>Schema Version:</th><td>%h(g.zAuxSchema)</td></tr> |
| 140 | @ <tr><th>Repository Rebuilt:</th><td> |
| 141 | @ %h(db_get_mtime("rebuilt","%Y-%m-%d %H:%M:%S","Never")) |
| 142 | @ By Fossil %h(db_get("rebuilt","Unknown"))</td></tr> |
| 143 | @ <tr><th>Database Stats:</th><td> |
| 144 | zDb = db_name("repository"); |
| @@ -254,10 +256,11 @@ | |
| 256 | } |
| 257 | #if 0 |
| 258 | /* Server-id is not useful information any more */ |
| 259 | fossil_print("%*s%s\n", colWidth, "server-id:", db_get("server-code", 0)); |
| 260 | #endif |
| 261 | fossil_print("%*s%s\n", colWidth, "schema-version:", g.zAuxSchema); |
| 262 | if( !omitVers ){ |
| 263 | fossil_print("%*s%s %s [%s] (%s)\n", |
| 264 | colWidth, "fossil-version:", |
| 265 | MANIFEST_DATE, MANIFEST_VERSION, RELEASE_VERSION, |
| 266 | COMPILER_NAME); |
| 267 | |
| 268 | DDED src/statrep.c |
+535
| --- a/src/statrep.c | ||
| +++ b/src/statrep.c | ||
| @@ -0,0 +1,535 @@ | ||
| 1 | +eea"zT | |
| 2 | + ; | |
| 3 | + @ claT | |
| 4 | + ; | |
| 5 | + @ class='lastchngTeble'nameeea"zTuserlist","tT} | |
| 6 | + style_footer(); @ class='lastchngTeble'nameeea"zTuserlist","tT} | |
| 7 | + style_footer(); | |
| 8 | +} | |
| 9 | +svg class="pie-chart"svg class="pie-chart"ArraySizeArraySizeArraySizeeea"zT | |
| 10 | + ; | |
| 11 | + @ class='lastchngTable'nameeea"zTuserlist","tT} | |
| 12 | + style_footer(); | |
| 13 | +} | |
| 14 | +center><svg/centre><hreea"/center><svg/centre><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" | |
| 15 | + "UPDATE piechart SEWHEN 5 THEN 'Friday'" | |
| 16 | + "ELSE 'ERROR' END;"svg class="pie-chart" | |
| 17 | + @ svg class="pie-chart" | |
| 18 | + @ HQuery url;/* URL for various branch linksurl_initialize(&url, "reports"); | |
| 19 | + cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", | |
| 20 | + , "Sunday" | |
| 21 | + }; | |
| 22 | + | |
| 23 | + ;mtime %% 7mtime %% 7MoTuesWednThur5Sunday Generate a submenu element witrep_submenu( | |
| 24 | + HQuery *pUrl,/* Base URLe><hreea<br>?name=Teea"zT | |
| 25 | + ; | |
| 26 | + @ claT | |
| 27 | + ; | |
| 28 | + @ ce><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" | |
| 29 | + "UPDATE piechart SEWHEN 5 THEN 'Friday'" | |
| 30 | + "ELSE 'ERROR' END;"svg class="pie-chart" | |
| 31 | + @ svg class="pie-chart" | |
| 32 | + @ HQuery url;/* URL for various branch linksurl_initialize(&url, "reports"); | |
| 33 | + cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", | |
| 34 | + , "Sunday" | |
| 35 | + }; | |
| 36 | + | |
| 37 | + ;mtime %% 7mtime %% 7MoTuesWednThur5Sunday eea"zT | |
| 38 | + ; | |
| 39 | + @ claT | |
| 40 | + e><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" | |
| 41 | + "UPDATE piechart SEWHEN 5 THEN 'Friday'" | |
| 42 | + "ELSE 'ERROR' END;"svg class="pie-chart" | |
| 43 | + @ svg class="pie-chart" | |
| 44 | + @ HQuery url;/* URL for various branch linksurl_initialize(&url, "reports"); | |
| 45 | + cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", | |
| 46 | + , "Sunday" | |
| 47 | + }; | |
| 48 | + | |
| 49 | + ;mtime %% 7mtime %% 7MoTuesWednThur5Sunday eea"zT | |
| 50 | + ; | |
| 51 | + @e><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" | |
| 52 | + "UPDATE piechart SEWHEN 5 THEN 'Friday'" | |
| 53 | + "ELSE 'ERROR' END;"svg class="pie-chart" | |
| 54 | + @ svg class="pie-chart" | |
| 55 | + @ HQuery url;/* URL for various branch linksurl_initialize(&url, "reports"); | |
| 56 | + cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", | |
| 57 | + , "Sunday" | |
| 58 | + }; | |
| 59 | + | |
| 60 | + ;mtime %% 7mtime %% 7MoTuesWednThur5Sunday eea"zT | |
| 61 | + ; | |
| 62 | + element(zMenuName, zMenuName, "%s url_render(pUrl, zParBy File", ny TypeelpiechartTABLE peea"zT | |
| 63 | + ; | |
| 64 | + @ claT | |
| 65 | + ; | |
| 66 | + @ class='lastchngTeble'nameeea"zTuserlist","tT} | |
| 67 | + style_footer(); @ class='lastchngTeble'nameeea"zTuserlist","tT} | |
| 68 | + style_footer(); | |
| 69 | +} | |
| 70 | +svg class="pie-chart"svg class="pie-chart"ArraySizeArraySizeArraySizeeea"zT | |
| 71 | + ; | |
| 72 | + @ class='lastchngTable'nameeea"zTuserlist","tT} | |
| 73 | + style_footer(); | |
| 74 | +} | |
| 75 | +center><svg/centre><hreea"/center><svg/centre><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" | |
| 76 | + "UPDATE piechart SEWHEN 5 THEN 'Friday'" | |
| 77 | + "ELSE 'ERROR' END;"svg class="pie-chart" | |
| 78 | + @ svg class="pie-chart" | |
| 79 | + @ HQuery url;/* URL for various branch linksurl_initialize(&url, "reports"); | |
| 80 | + cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", | |
| 81 | + , "Sunday" | |
| 82 | + }; | |
| 83 | + | |
| 84 | + ;mtime %% 7mtime %% 7MoTuesWednThur5Sunday Generate a submenu element witrep_submenu( | |
| 85 | + HQuery *pUrl,/* Base URLe><hreea<br>?name=Teea"zT | |
| 86 | + ; | |
| 87 | + @ claT | |
| 88 | + ; | |
| 89 | + @ ce>4) AS yy ORDER BY y DESC", zUserName) ){ | |
| 90 | + azYear = fossil_realloc(azYear, sizeof(char*)*(n+2)); | |
| 91 | + azYear[n] = fossil_strdup(,0)); | |
| 92 | + azYear[n+1] = azYear[n]; | |
| 93 | + if( !isValidYear && fossil_strcmp(zYear,azYear[n])==0 ) zYear = azYear[0];zT | |
| 94 | + ; | |
| 95 | + @ claT | |
| 96 | + ; | |
| 97 | + @ class='lastchngTeble'nameeea"zTuserlist","tT} | |
| 98 | + style_footer(); @ class='lastchngTeble'nameeea"zTuserlist","tT} | |
| 99 | + style_footer(); | |
| 100 | +} | |
| 101 | +svg class="pie-chart"svg class="pie-chart"ArraySizeArraySizeArraySizeeea"zT | |
| 102 | + ; | |
| 103 | + @ class='lastchngTable'nameeea"zTuserlist","tT} | |
| 104 | + style_footer(); | |
| 105 | +} | |
| 106 | +center><svg/centre><hreea"/center><svg/centre><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" | |
| 107 | + "UPDATE piechart SEWHEN 5 THEN 'Friday'" | |
| 108 | + "ELSE 'ERROR' END;"svg class="pie-chart" | |
| 109 | + @ svg class="pie-chart" | |
| 110 | + @ HQuery url;/* RL for eventbranch linksurl_initialize(&url, "reports"); | |
| 111 | + cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", | |
| 112 | + , "Sunday" | |
| 113 | + }; | |
| 114 | + | |
| 115 | + ;mtime %% 7mt/* | |
| 116 | +** A helper for the /reports family of pages which prints out a menu | |
| 117 | +** of links for the various type=XXX flags. zCurrentViewName must be | |
| 118 | +** the name/value of the 'view' parameter which is in effect at the | |
| 119 | +** time this is called. e.g. if called from the 'byuser' view then | |
| 120 | +** zCurrentViewName must be "byuser". Any URL parameters which need to | |
| 121 | +** be added to the generated URLs should be passed in zParam. The | |
| 122 | +** caller is expected to have already encoded any zParam in event_types_menu(c><svg</centre>center><svg</centre> "Thursday", | |
| 123 | + , "Sunday" | |
| 124 | + }; | |
| 125 | + | |
| 126 | + ;mtime %% 7mtime %% 7MoTuesWednThur5Sunday eea"zT | |
| 127 | + ; | |
| 128 | + @e><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" | |
| 129 | + "UPDATE piechart SEWHEN 5 THEN 'Friday'" | |
| 130 | + "ELSE 'ERROR' END;"svg class="pie-chart" | |
| 131 | + @ svg class="pie-chart"uery url;/* URL for various branch linksurl_initialize(&url, "reports"); | |
| 132 | + cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>csnter><svg</centre> "Thursday", | |
| 133 | + , "Sunday" | |
| 134 | + }; | |
| 135 | + | |
| 136 | + ;mtime %% 7mtime %% 7Mg.zTop,MoTuesWednThur5Sunday eea"zT | |
| 137 | + ; | |
| 138 | + element(zMenuName, zMenuNameinsass="pie-chart" | |
| 139 | + @ HQuery url;/*ci'>checkin"2;" | |
| 140 | + "UPDATE piechareea"zT | |
| 141 | + ; | |
| 142 | + @ claT | |
| 143 | + ; | |
| 144 | + even class='lastchngTable'nameeea"zTuserlist","tT} | |
| 145 | + style_footer();e'>event; @ class='lastchngTeble'nameeea"zTuserlist","tT} | |
| 146 | + style_footer(); | |
| 147 | +} | |
| 148 | +svg class="pie-chart"svg class="pie-chart"ArraySizeArraySizeArraySizeeea"zT | |
| 149 | + ; | |
| 150 | + @ class='lastchngTable'nameeea"zTuserlist","tT} | |
| 151 | + style_footer(); | |
| 152 | +} | |
| 153 | +center><svg/centre><hreea"/center><svg/centre><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" | |
| 154 | + "UPDATE piechart SEWHEN 5 THEN 'Friday'" | |
| 155 | + "ELSE 'ERROR' END;"svg class="pie-chart" | |
| 156 | + @ svg class="pie-chart" | |
| 157 | + @ HQuery url;/* URL for various branch linksurl_initialize(&url, "reports"); | |
| 158 | + cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", | |
| 159 | + , "Sunday" | |
| 160 | + }; | |
| 161 | + | |
| 162 | + ;mtime %% 7mtime %% 7MoTuesWednThur5Sunday Generate a submenu element witrep_submenu( | |
| 163 | + HQuery *pUrl,/* Base URLe><hreea<br>?name=Teea"zT | |
| 164 | + ; | |
| 165 | + @ claT | |
| 166 | + ; | |
| 167 | + @ ce><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" | |
| 168 | + "UPDATE piechart SEWHEN 5 THEN 'Friday'" | |
| 169 | + "ELSE 'ERROR' END;"svg class="pie-chart" | |
| 170 | + @ svg class="pie-chart" | |
| 171 | + @ HQuery url;/* URL for various branch linksurl_initialize(&url, "reports"); | |
| 172 | + cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", | |
| 173 | + , "Sunday" | |
| 174 | + }; | |
| 175 | + | |
| 176 | + ;mtime %% 7mtime %% 7MoTuesWednThur5Sunday eea"zT | |
| 177 | + ; | |
| 178 | + @ claT | |
| 179 | + e><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" | |
| 180 | + "UPDATE piechart SEWHEN 5 THEN 'Friday'" | |
| 181 | + "ELSE 'ERROR' END;"svg class="pie-chart" | |
| 182 | + @ svg class="pie-chart" | |
| 183 | + @ HQuery url;/* URL for various branch linksurl_initialize(&url, "reports"); | |
| 184 | + cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", | |
| 185 | + , "Sunday" | |
| 186 | + }; | |
| 187 | + | |
| 188 | + ;mtime %% 7mtime %% 7MoTuesWednThur5Sunday eea"zT | |
| 189 | + ; | |
| 190 | + @e><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" | |
| 191 | + "UPDATE piechart SEWHEN 5 THEN 'Friday'" | |
| 192 | + "ELSE 'ERROR' END;"svg class="pie-chart" | |
| 193 | + @ svg class="pie-chart" | |
| 194 | + @ HQuery url;/* URL for various branch linksurl_initialize(&url, "reports"); | |
| 195 | + cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", | |
| 196 | + , "Sunday" | |
| 197 | + }; | |
| 198 | + | |
| 199 | + ;mtime %% 7mtime %% 7MoTuesWednThur5Sunday eea"zT | |
| 200 | + ; | |
| 201 | + element(zMenuName, zMenuName, "%s url_render(pUrl, zParBy File", ny TypeelpiechartTABLE peea"zT | |
| 202 | + ; | |
| 203 | + @ claT | |
| 204 | + ; | |
| 205 | + @ class='lastchngTeble'nameeea"zTuserlist","tT} | |
| 206 | + style_footer(); @ class='lastchngTeble'nameeea"zTuserlist","tT} | |
| 207 | + style_footer(); | |
| 208 | +} | |
| 209 | +svg class="pie-chart"svg class="pie-chart"ArraySizeArraySizeArraySizeeea"zT | |
| 210 | + ; | |
| 211 | + @ class='lastchngTable'nameeea"zTuserlist","tT} | |
| 212 | + style_footer(); | |
| 213 | +} | |
| 214 | +center><svg/centre><hreea"/center><svg/centre><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" | |
| 215 | + "UPDATE piechart SEWHEN 5 THEN 'Friday'" | |
| 216 | + "ELSE 'ERROR' END;"svg class="pie-chart" | |
| 217 | + @ svg class="pie-chart" | |
| 218 | + @ HQuery url;/* URL for various branch linksurl_initialize(&url, "reports"); | |
| 219 | + cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", | |
| 220 | + , "Sunday" | |
| 221 | + }; | |
| 222 | + | |
| 223 | + ;mtime %% 7mtime %% 7MoTuesWednThur5Sunday Generate a submenu element witrep_submenu( | |
| 224 | + HQuery *pUrl,/* Base URLe><hreea<br>?name=Teea"zT | |
| 225 | + ; | |
| 226 | + @ claT | |
| 227 | + ; | |
| 228 | + @ ce>4) AS yy ORDER BY y DESC", zUserName) ){ | |
| 229 | + azYear = fossil_realloc(azYear, sizeof(char*)*(n+2)); | |
| 230 | + azYear[n] = fossil_strdup(,0)); | |
| 231 | + azYear[n+1] = azYear[n]; | |
| 232 | + if( !isValidYear && fossil_strcmp(zYear,azYear[n])==0 ) zYear = azYear[0];zT | |
| 233 | + ; | |
| 234 | + @ claT | |
| 235 | + ; | |
| 236 | + @ class='lastchngTeble'nameeea"zTuserlist","tT} | |
| 237 | + style_footer(); @ class='lastchngTeble'nameeea"zTuserlist","tT} | |
| 238 | + style_footer(); | |
| 239 | +} | |
| 240 | +svg class="pie-chart"svg class="pie-chart"ArraySizeArraySizeArraySizeeea"zT | |
| 241 | + ; | |
| 242 | + @ class='lastchngTable'nameeea"zTuserlist","tT} | |
| 243 | + style_footer(); | |
| 244 | +} | |
| 245 | +center><svg/centre><hreea"/center><svg/centre><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" | |
| 246 | + "UPDATE piechart SEWHEN 5 THEN 'Friday'" | |
| 247 | + "ELSE 'ERRsR' END;"svg class="pie-chart" | |
| 248 | + @ svg class="pie-chart" | |
| 249 | + @ Hg.zTop,HQuery url;/* RL for various branch linksurl_initialize(&url, "reports"); | |
| 250 | + cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", | |
| 251 | + , "Sunday" | |
| 252 | + }; | |
| 253 | + | |
| 254 | + ;mtime %% 7mt/* | |
| 255 | +** A helper for the /reports family of pages which prints out a menu | |
| 256 | +** of links for the various type=XXX flags. zCurrentViewName must be | |
| 257 | +** the name/value of the 'view' parameter which is in effect at the | |
| 258 | +** time this is called. e.g. if called from the 'byuser' view then | |
| 259 | +** zCurrentViewName must be "byuser". Any URL parameters which need to | |
| 260 | +** be added to the generated URLs should be passed in zParam. The | |
| 261 | +** caller is expected to have already encoded any zParam in event_types_menu(c><svg</centre>center><svg</centre> "Thursday", | |
| 262 | + , "Sunday" | |
| 263 | + }; | |
| 264 | + | |
| 265 | + ;mtime %% 7mtime %% 7MoTuesWednThur5Sunday eea"zT | |
| 266 | + ; | |
| 267 | + @e><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" | |
| 268 | + "UPDATE piechart SEWHEN 5 THEN 'Friday'" | |
| 269 | + "ELSE 'ERROR' END;"svg class="pie-chart" | |
| 270 | + @ svg class="pie-chart"uery url;/* URL for various branch linksurl_initialize(&url, "reports"); | |
| 271 | + cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", | |
| 272 | + , "Sunday" | |
| 273 | + }; | |
| 274 | + | |
| 275 | + ;mtime %% 7mtime %% 7MoTuesWednThur5Sunday eea"zT | |
| 276 | + ; | |
| 277 | + element(zMenuName, zMenuNameinsass="pie-chart" | |
| 278 | + @ HQuery url;/*ci'>checkin"2;" | |
| 279 | + "UPDATE piechareea"zT | |
| 280 | + ; | |
| 281 | + @ claT | |
| 282 | + ; | |
| 283 | + @ class='lastchngTeble'nameeea"zTuserlist","tT} | |
| 284 | + style_footer(); @ class='lastchngTeble'nameeea"zTuserlist","tT} | |
| 285 | + style_footer(); | |
| 286 | +} | |
| 287 | +svg class="pie-chart"svg class="pie-chart"ArraySizeArraySizeArraySizeeea"zT | |
| 288 | + ; | |
| 289 | + @ class='lastchngTable'nameeea"zTuserlist","tT} | |
| 290 | + style_footer(); | |
| 291 | +} | |
| 292 | +center><svg/centre><hreea"/center><svg/centre><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" | |
| 293 | + "UPDATE piechart SEWHEN 5 THEN 'Friday'" | |
| 294 | + "ELSE 'ERROR' END;"svg class="pie-chart" | |
| 295 | + @ svg class="pie-chart" | |
| 296 | + @ HQuery url;/* URL for various branch linksurl_initialize(&url, "reports"); | |
| 297 | + cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", | |
| 298 | + , "Sunday" | |
| 299 | + }; | |
| 300 | + | |
| 301 | + ;mtime %% 7mtime %% 7MoTuesWednThur5Sunday Generate a submenu element witrep_submenu( | |
| 302 | + HQuery *pUrl,/* Base URLe><hreea<br>?name=Teea"zT | |
| 303 | + ; | |
| 304 | + @ claT | |
| 305 | + ; | |
| 306 | + @ ce>4) AS yy ORDER BY y DESC", zUserName) ){ | |
| 307 | + azYear = fossil_realloc(azYear, sizeof(char*)*(n+2)); | |
| 308 | + azYear[n] = fossil_strdup(,0)); | |
| 309 | + azYear[n+1] = azYear[n]; | |
| 310 | + if( !isValidYear && fossil_strcmp(zYear,azYear[n])==0 ) ='lastchngTeble'nameeea"zTuserlist","tT} | |
| 311 | + style_footer(); @ class='lastchngTeble'nameeea"zTuserlist","tT} | |
| 312 | + style_footer(); | |
| 313 | +} | |
| 314 | +svg class="pie-chart"svg class="pie-chart"ArraySizeArraySizeArraySizeeea"zT | |
| 315 | + ; | |
| 316 | + @ class='lastchngTable'nameeea"zTuserlist","tT} | |
| 317 | + style_footer(); | |
| 318 | +} | |
| 319 | +center><svg/centre><hreea"/center><svg/centre><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" | |
| 320 | + "UPDATE piechart SEWHEN 5 THEN 'Friday'" | |
| 321 | + "ELSE 'ERROR' END;"svg class="pie-chart" | |
| 322 | + @ svg class="pie-chart" | |
| 323 | + @ HQuery url;/* URL for various branch linksurl_initialize(&url, "reports"); | |
| 324 | + cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", | |
| 325 | + , "Sunday" | |
| 326 | + }; | |
| 327 | + | |
| 328 | + ;mtime %% 7mtimand not empty | |
| 329 | +** class="pie-chart"slist","tT} | |
| 330 | + style_feeaclass='lastchngTable'nameeea"zTuserlist","tT} | |
| 331 | + style_footer(); | |
| 332 | +} | |
| 333 | +center><svg/centre><hreea"/center><svg/centre><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" | |
| 334 | + "UPDATE piechart SEWHEN 5 THEN 'Friday'" | |
| 335 | + "ELSE 'ERROR' END;"svg class="pie-chart" | |
| 336 | + @ svg class="pie-chart" | |
| 337 | + @ HQuery url;/* URL for various branch linksurl_initialize(&url, "reports");Blob sql-chart" | |
| 338 | + @ HQuery /* SQo_url(&url);url_rese_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", | |
| 339 | + , "Sunday" | |
| 340 | + }; | |
| 341 | + | |
| 342 | + ;mtime %% 7mtime %% 7MoTuesWednThur5Sunday Generate a submenu element witrep_submenu( | |
| 343 | + HQuery *pUrl,/* Base URLe><hreea<br>?name=Teea"zT | |
| 344 | + ; | |
| 345 | + @ claT | |
| 346 | + ; | |
| 347 | + @ ce>4) AS yy ORDER BY y DESC", zUserName) ){ | |
| 348 | + azYear = fossil_realloc(azYear, sizeof(char*)*(n+2)); | |
| 349 | + azYear[n] = fossil_strdup(,0)); | |
| 350 | + azYear[n+1] = azYear[n]; | |
| 351 | + if( !isValidYear && fossil_strcmp(zYear,azYear[n])==0 ) ='lastchngTeble'nameeea"zTuserlist","tT} | |
| 352 | + style_footer(); @ class='lastchngTeble'nameeea"zTuserlist","tT} | |
| 353 | + style_footer(); | |
| 354 | +} | |
| 355 | +svg class="pie-chart"svg class="pie-chart"ArraySizeArraySizeArraySizeeea"zT | |
| 356 | + ; | |
| 357 | + @ class='lastchngTable'nameeea"zTuserlist","tT} | |
| 358 | + unday" | |
| 359 | + } NULL ); | |
| 360 | +header, "s) by yearL for various branchmtime %% 7mtime %% 7MoTuesWedme=TABLE piechart(amt,labelpie); | |
| 361 | + blob_append_sql(&sqlr5Sunday eea"zT | |
| 362 | + ; | |
| 363 | + @e><htimeframe,a"/center><svg/centeea"zincludeMonth if( PB("pie") ){ cgi_query_paramete | |
| 364 | + " ySizeArraySizeArraySizeeea"zT | |
| 365 | + ; | |
| 366 | + @ claT | |
| 367 | + ; | |
| 368 | + @"zT | |
| 369 | + ; | |
| 370 | + @ claT | |
| 371 | + ; | |
| 372 | + @ 'lastchngTeble'name claT | |
| 373 | + ; | |
| 374 | + @ class='lastchngTeble'nameeea"zTuserlist","tT} | |
| 375 | + style_footer(); @ class='lastchngTeble'nameeea"zTuserlist","tT} | |
| 376 | + style_footer();Usereea"zT | |
| 377 | + ; | |
| 378 | + @ claT | |
| 379 | + ; | |
| 380 | + @ class='lastchngTeble'nameeea"zTuserlist","tT} | |
| 381 | + style_footer(); @ class='lastchngTeble'nameeea"zTuserlist","tT} | |
| 382 | + style_footer(); | |
| 383 | +} | |
| 384 | +svg class="pie-chart"svg class="pie-chart"ArraySizeArraySizeArraySizeeea"zT | |
| 385 | + ; | |
| 386 | + @ class='lastchngTable'nameeea"zTuserlist","tT} | |
| 387 | + style_footer(); | |
| 388 | +} | |
| 389 | +center><svg/centre><hreea"/center><svg/centre><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" | |
| 390 | + "UPDATE piechart SEWHEN 5 THEN 'Friday'" | |
| 391 | + "ELSE 'ERROR' END;"svg class="pie-chart" | |
| 392 | + @ svg class="pie-chart" | |
| 393 | + @ HQuery url;/* URL for various branch linksurl_initialize(&url, "reports"); | |
| 394 | + cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", | |
| 395 | + , "Sunday" | |
| 396 | + }; | |
| 397 | + | |
| 398 | + ;mtime %% 7mtime %% 7MoTuesWednThur5Sunday Generate a submenu element witrep_submenu( | |
| 399 | + HQuery *pUrl,/* Base URLe><hreea<br>?name=Teea"zT | |
| 400 | + ; | |
| 401 | + @ claT | |
| 402 | + ; | |
| 403 | + @ ce><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" | |
| 404 | + "UPDATE piechart SEWHEN 5 THEN 'Friday'" | |
| 405 | + "ELSE 'ERROR' END;"svg class="pie-chart" | |
| 406 | + @ svg class="pie-chart" | |
| 407 | + @ HQuery url;/* URL for various branch linksurl_initialize(&url, "reports"); | |
| 408 | + cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", | |
| 409 | + , "Sunday" | |
| 410 | + }; | |
| 411 | + | |
| 412 | + ;mtime %% 7mtime %% 7MoTuesWednThur5Sunday eea"zT | |
| 413 | + ; | |
| 414 | + @ claT | |
| 415 | + e><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" | |
| 416 | + "UPDATE piechart SEWHEN 5 THEN 'Friday'" | |
| 417 | + "ELSE 'ERROR' END;"svg class="pie-chart" | |
| 418 | + @ svg class="pie-chart" | |
| 419 | + @ HQuery url;/* URL for various branch linksurl_initialize(&url, "reports"); | |
| 420 | + cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", | |
| 421 | + , "Sunday" | |
| 422 | + }; | |
| 423 | + | |
| 424 | + ;mtime %% 7mtime %% 7MoTuesWednThur5Sunday eea"zT | |
| 425 | + ; | |
| 426 | + @e><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" | |
| 427 | + "UPDATE piechart SEWHEN 5 THEN 'Friday'" | |
| 428 | + "ELSE 'ERROR' END;"svg class="pie-chart" | |
| 429 | + @ svg class="pie-chart" | |
| 430 | + @ HQuery url;/* URL for various branch linksurl_initialize(&url, "reports"); | |
| 431 | + cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", | |
| 432 | + , "Sunday" | |
| 433 | + }; | |
| 434 | + | |
| 435 | + ;mtime %% 7mtime %% 7MoTuesWednThur5Sunday eea"zT | |
| 436 | + ; | |
| 437 | + element(zMenuName, zMenuName, "%s url_render(pUrl, zParBy File", ny TypeelpiechartTABLE peea"zT | |
| 438 | + ; | |
| 439 | + @ claT | |
| 440 | + ; | |
| 441 | + @ class='lastchngTeble'nameeea"zTuserlist","tT} | |
| 442 | + style_footer(); @ class='lastchngTeble'nameeea"zTuserlist","tT} | |
| 443 | + style_footer(); | |
| 444 | +} | |
| 445 | +svg class="pie-chart"svg class="pie-chart"ArraySizeArraySizeArraySizeeea"zT | |
| 446 | + ; | |
| 447 | + @ class='lastchngTable'nameeea"zTuserlist","tT} | |
| 448 | + style_footer(); | |
| 449 | +} | |
| 450 | +center><svg/centre><hreea"/center><svg/centre><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" | |
| 451 | + "UPDATE piechart SEWHEN 5 THEN 'Friday'" | |
| 452 | + "ELSE 'ERROR' END;"svg class="pie-chart" | |
| 453 | + @ svg class="pie-chart" | |
| 454 | + @ HQuery url;/* URL for various branch linksurl_initialize(&url, "reports"); | |
| 455 | + cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", | |
| 456 | + , "Sunday" | |
| 457 | + }; | |
| 458 | + | |
| 459 | + ;mtime %% 7mtime %% 7MoTuesWednThur5Sunday Generate a submenu element witrep_submenu( | |
| 460 | + HQuery *pUrl,/* Base URLe><hreea<br>?name=Teea"zT | |
| 461 | + ; | |
| 462 | + @ claT | |
| 463 | + ; | |
| 464 | + @ ce>4) AS yy ORDER BY y DESC", zUserName) ){ | |
| 465 | + azYear = fossil_realloc(azYear, sizeof(char*)*(n+2)); | |
| 466 | + azYear[n] = fossil_strdup(,0)); | |
| 467 | + azYear[n+1] = azYear[n]; | |
| 468 | + if( !isValidYear && fossil_strcmp(zYear,azYear[n])==0 ) zYear = azYear[0];zT | |
| 469 | + ; | |
| 470 | + @ claT | |
| 471 | + ; | |
| 472 | + @ class='lastchngTeble'nameeea"zTuserlist","tT} | |
| 473 | + style_footer(); @ class='lastchngTeble'nameeea"zTuserlist","tT} | |
| 474 | + style_footer(); | |
| 475 | +} | |
| 476 | +svg class="pie-chart"svg class="pie-chart"ArraySizeArraySizeArraySizeeea"zT | |
| 477 | + ; | |
| 478 | + @ class='lastchngTable'nameeea"zTuserlist","tT} | |
| 479 | + style_footer(); | |
| 480 | +} | |
| 481 | +center><svg/centre><hreea"/center><svg/centre><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" | |
| 482 | + "UPDATE piechart SEWHEN 5 THEN 'Friday'" | |
| 483 | + "ELSE 'ERROR' END;"svg class="pie-chart" | |
| 484 | + @ svg class="pie-chart" | |
| 485 | + @ HQuery url;/* RL for various branch linksurl_initialize(&url, "reports"); | |
| 486 | + cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", | |
| 487 | + , "Sunday" | |
| 488 | + }; | |
| 489 | + | |
| 490 | + ;mtime %% 7mt/* | |
| 491 | +** A helper for the /reports family of pages which prints out a menu | |
| 492 | +** of links for the various type=XXX flags. zCurrentViewName must be | |
| 493 | +** the name/value of the 'view' parameter which is in effect at the | |
| 494 | +** time this is called. e.g. if called from the 'byuser' view then | |
| 495 | +** zCurrentViewName musa<br>?name=Teea"zT | |
| 496 | + ;g.zTop,; | |
| 497 | + @ claT | |
| 498 | + ; | |
| 499 | + @ ce>4) AS yy ORDER BY y DESC", zUserName) ){ | |
| 500 | + azYear = fossil_realloc(azYear, sizeof(char*)*(n+2)); | |
| 501 | + azYear[n] = fossil_strdup(,0)); | |
| 502 | + azYear[n+1] = azYear[n]; | |
| 503 | + if( !isValidYear && fossil_strcmp(zYear,azYear[n])==0 ) ='lastchngTeble'nameeea"zTuserlist","tT} | |
| 504 | + style_footer(); @ class='lastchngTeble'nameeea"zTuserlist","tT} | |
| 505 | + style_footer(); | |
| 506 | +} | |
| 507 | +svg class="pie-chart"svg class="pie-chart"ArraySizeArraySizeArraySizeeea"zT | |
| 508 | + ; | |
| 509 | + @ class='lastchngTable'nameeea"zTuserlist","tT} | |
| 510 | + style_footer(); | |
| 511 | +} | |
| 512 | +center><svg/centre><hreea"/center><svg/centre><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" | |
| 513 | + "UPDATE piechart SEWHEN 5 THEN 'Friday'" | |
| 514 | + "ELSE 'ERROR' END;"svg class="pie-chart" | |
| 515 | + @ svg class="pie-chart" | |
| 516 | + @ HQuery url;/* URL for various branch linksurl_initialize(&url, "reports"); | |
| 517 | + cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", | |
| 518 | + , "Sunday" | |
| 519 | + }; | |
| 520 | + | |
| 521 | + ;mtime %% 7mtimand not empty | |
| 522 | +** class="pie-chart"slist","tT} | |
| 523 | + style_feeaclass='lastchngTable'nameeea"zTuserlist","tT} | |
| 524 | + style_footer(); | |
| 525 | +} | |
| 526 | +center><svg/centre><hreea"/center><svg/centre><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" | |
| 527 | + "UPDATE piechart SEWHEN 5 THEN 'Friday'" | |
| 528 | + "ELSE 'ERROR' END;"svg class="pie-chart" | |
| 529 | + @ svg class="pie-chart" | |
| 530 | + @ HQuery url;/* URL for various branch linksurl_initialize(&url, "reports");Blob sql-chart" | |
| 531 | + @ HQuery /* SQo_url(&url);url_rese_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", | |
| 532 | + , "Sunday" | |
| 533 | + }; | |
| 534 | + | |
| 535 | + ;mtime %% 7mtime %% 7MoTuesWednThur5Sunday Ge |
| --- a/src/statrep.c | |
| +++ b/src/statrep.c | |
| @@ -0,0 +1,535 @@ | |
| --- a/src/statrep.c | |
| +++ b/src/statrep.c | |
| @@ -0,0 +1,535 @@ | |
| 1 | eea"zT |
| 2 | ; |
| 3 | @ claT |
| 4 | ; |
| 5 | @ class='lastchngTeble'nameeea"zTuserlist","tT} |
| 6 | style_footer(); @ class='lastchngTeble'nameeea"zTuserlist","tT} |
| 7 | style_footer(); |
| 8 | } |
| 9 | svg class="pie-chart"svg class="pie-chart"ArraySizeArraySizeArraySizeeea"zT |
| 10 | ; |
| 11 | @ class='lastchngTable'nameeea"zTuserlist","tT} |
| 12 | style_footer(); |
| 13 | } |
| 14 | center><svg/centre><hreea"/center><svg/centre><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" |
| 15 | "UPDATE piechart SEWHEN 5 THEN 'Friday'" |
| 16 | "ELSE 'ERROR' END;"svg class="pie-chart" |
| 17 | @ svg class="pie-chart" |
| 18 | @ HQuery url;/* URL for various branch linksurl_initialize(&url, "reports"); |
| 19 | cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", |
| 20 | , "Sunday" |
| 21 | }; |
| 22 | |
| 23 | ;mtime %% 7mtime %% 7MoTuesWednThur5Sunday Generate a submenu element witrep_submenu( |
| 24 | HQuery *pUrl,/* Base URLe><hreea<br>?name=Teea"zT |
| 25 | ; |
| 26 | @ claT |
| 27 | ; |
| 28 | @ ce><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" |
| 29 | "UPDATE piechart SEWHEN 5 THEN 'Friday'" |
| 30 | "ELSE 'ERROR' END;"svg class="pie-chart" |
| 31 | @ svg class="pie-chart" |
| 32 | @ HQuery url;/* URL for various branch linksurl_initialize(&url, "reports"); |
| 33 | cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", |
| 34 | , "Sunday" |
| 35 | }; |
| 36 | |
| 37 | ;mtime %% 7mtime %% 7MoTuesWednThur5Sunday eea"zT |
| 38 | ; |
| 39 | @ claT |
| 40 | e><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" |
| 41 | "UPDATE piechart SEWHEN 5 THEN 'Friday'" |
| 42 | "ELSE 'ERROR' END;"svg class="pie-chart" |
| 43 | @ svg class="pie-chart" |
| 44 | @ HQuery url;/* URL for various branch linksurl_initialize(&url, "reports"); |
| 45 | cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", |
| 46 | , "Sunday" |
| 47 | }; |
| 48 | |
| 49 | ;mtime %% 7mtime %% 7MoTuesWednThur5Sunday eea"zT |
| 50 | ; |
| 51 | @e><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" |
| 52 | "UPDATE piechart SEWHEN 5 THEN 'Friday'" |
| 53 | "ELSE 'ERROR' END;"svg class="pie-chart" |
| 54 | @ svg class="pie-chart" |
| 55 | @ HQuery url;/* URL for various branch linksurl_initialize(&url, "reports"); |
| 56 | cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", |
| 57 | , "Sunday" |
| 58 | }; |
| 59 | |
| 60 | ;mtime %% 7mtime %% 7MoTuesWednThur5Sunday eea"zT |
| 61 | ; |
| 62 | element(zMenuName, zMenuName, "%s url_render(pUrl, zParBy File", ny TypeelpiechartTABLE peea"zT |
| 63 | ; |
| 64 | @ claT |
| 65 | ; |
| 66 | @ class='lastchngTeble'nameeea"zTuserlist","tT} |
| 67 | style_footer(); @ class='lastchngTeble'nameeea"zTuserlist","tT} |
| 68 | style_footer(); |
| 69 | } |
| 70 | svg class="pie-chart"svg class="pie-chart"ArraySizeArraySizeArraySizeeea"zT |
| 71 | ; |
| 72 | @ class='lastchngTable'nameeea"zTuserlist","tT} |
| 73 | style_footer(); |
| 74 | } |
| 75 | center><svg/centre><hreea"/center><svg/centre><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" |
| 76 | "UPDATE piechart SEWHEN 5 THEN 'Friday'" |
| 77 | "ELSE 'ERROR' END;"svg class="pie-chart" |
| 78 | @ svg class="pie-chart" |
| 79 | @ HQuery url;/* URL for various branch linksurl_initialize(&url, "reports"); |
| 80 | cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", |
| 81 | , "Sunday" |
| 82 | }; |
| 83 | |
| 84 | ;mtime %% 7mtime %% 7MoTuesWednThur5Sunday Generate a submenu element witrep_submenu( |
| 85 | HQuery *pUrl,/* Base URLe><hreea<br>?name=Teea"zT |
| 86 | ; |
| 87 | @ claT |
| 88 | ; |
| 89 | @ ce>4) AS yy ORDER BY y DESC", zUserName) ){ |
| 90 | azYear = fossil_realloc(azYear, sizeof(char*)*(n+2)); |
| 91 | azYear[n] = fossil_strdup(,0)); |
| 92 | azYear[n+1] = azYear[n]; |
| 93 | if( !isValidYear && fossil_strcmp(zYear,azYear[n])==0 ) zYear = azYear[0];zT |
| 94 | ; |
| 95 | @ claT |
| 96 | ; |
| 97 | @ class='lastchngTeble'nameeea"zTuserlist","tT} |
| 98 | style_footer(); @ class='lastchngTeble'nameeea"zTuserlist","tT} |
| 99 | style_footer(); |
| 100 | } |
| 101 | svg class="pie-chart"svg class="pie-chart"ArraySizeArraySizeArraySizeeea"zT |
| 102 | ; |
| 103 | @ class='lastchngTable'nameeea"zTuserlist","tT} |
| 104 | style_footer(); |
| 105 | } |
| 106 | center><svg/centre><hreea"/center><svg/centre><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" |
| 107 | "UPDATE piechart SEWHEN 5 THEN 'Friday'" |
| 108 | "ELSE 'ERROR' END;"svg class="pie-chart" |
| 109 | @ svg class="pie-chart" |
| 110 | @ HQuery url;/* RL for eventbranch linksurl_initialize(&url, "reports"); |
| 111 | cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", |
| 112 | , "Sunday" |
| 113 | }; |
| 114 | |
| 115 | ;mtime %% 7mt/* |
| 116 | ** A helper for the /reports family of pages which prints out a menu |
| 117 | ** of links for the various type=XXX flags. zCurrentViewName must be |
| 118 | ** the name/value of the 'view' parameter which is in effect at the |
| 119 | ** time this is called. e.g. if called from the 'byuser' view then |
| 120 | ** zCurrentViewName must be "byuser". Any URL parameters which need to |
| 121 | ** be added to the generated URLs should be passed in zParam. The |
| 122 | ** caller is expected to have already encoded any zParam in event_types_menu(c><svg</centre>center><svg</centre> "Thursday", |
| 123 | , "Sunday" |
| 124 | }; |
| 125 | |
| 126 | ;mtime %% 7mtime %% 7MoTuesWednThur5Sunday eea"zT |
| 127 | ; |
| 128 | @e><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" |
| 129 | "UPDATE piechart SEWHEN 5 THEN 'Friday'" |
| 130 | "ELSE 'ERROR' END;"svg class="pie-chart" |
| 131 | @ svg class="pie-chart"uery url;/* URL for various branch linksurl_initialize(&url, "reports"); |
| 132 | cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>csnter><svg</centre> "Thursday", |
| 133 | , "Sunday" |
| 134 | }; |
| 135 | |
| 136 | ;mtime %% 7mtime %% 7Mg.zTop,MoTuesWednThur5Sunday eea"zT |
| 137 | ; |
| 138 | element(zMenuName, zMenuNameinsass="pie-chart" |
| 139 | @ HQuery url;/*ci'>checkin"2;" |
| 140 | "UPDATE piechareea"zT |
| 141 | ; |
| 142 | @ claT |
| 143 | ; |
| 144 | even class='lastchngTable'nameeea"zTuserlist","tT} |
| 145 | style_footer();e'>event; @ class='lastchngTeble'nameeea"zTuserlist","tT} |
| 146 | style_footer(); |
| 147 | } |
| 148 | svg class="pie-chart"svg class="pie-chart"ArraySizeArraySizeArraySizeeea"zT |
| 149 | ; |
| 150 | @ class='lastchngTable'nameeea"zTuserlist","tT} |
| 151 | style_footer(); |
| 152 | } |
| 153 | center><svg/centre><hreea"/center><svg/centre><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" |
| 154 | "UPDATE piechart SEWHEN 5 THEN 'Friday'" |
| 155 | "ELSE 'ERROR' END;"svg class="pie-chart" |
| 156 | @ svg class="pie-chart" |
| 157 | @ HQuery url;/* URL for various branch linksurl_initialize(&url, "reports"); |
| 158 | cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", |
| 159 | , "Sunday" |
| 160 | }; |
| 161 | |
| 162 | ;mtime %% 7mtime %% 7MoTuesWednThur5Sunday Generate a submenu element witrep_submenu( |
| 163 | HQuery *pUrl,/* Base URLe><hreea<br>?name=Teea"zT |
| 164 | ; |
| 165 | @ claT |
| 166 | ; |
| 167 | @ ce><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" |
| 168 | "UPDATE piechart SEWHEN 5 THEN 'Friday'" |
| 169 | "ELSE 'ERROR' END;"svg class="pie-chart" |
| 170 | @ svg class="pie-chart" |
| 171 | @ HQuery url;/* URL for various branch linksurl_initialize(&url, "reports"); |
| 172 | cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", |
| 173 | , "Sunday" |
| 174 | }; |
| 175 | |
| 176 | ;mtime %% 7mtime %% 7MoTuesWednThur5Sunday eea"zT |
| 177 | ; |
| 178 | @ claT |
| 179 | e><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" |
| 180 | "UPDATE piechart SEWHEN 5 THEN 'Friday'" |
| 181 | "ELSE 'ERROR' END;"svg class="pie-chart" |
| 182 | @ svg class="pie-chart" |
| 183 | @ HQuery url;/* URL for various branch linksurl_initialize(&url, "reports"); |
| 184 | cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", |
| 185 | , "Sunday" |
| 186 | }; |
| 187 | |
| 188 | ;mtime %% 7mtime %% 7MoTuesWednThur5Sunday eea"zT |
| 189 | ; |
| 190 | @e><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" |
| 191 | "UPDATE piechart SEWHEN 5 THEN 'Friday'" |
| 192 | "ELSE 'ERROR' END;"svg class="pie-chart" |
| 193 | @ svg class="pie-chart" |
| 194 | @ HQuery url;/* URL for various branch linksurl_initialize(&url, "reports"); |
| 195 | cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", |
| 196 | , "Sunday" |
| 197 | }; |
| 198 | |
| 199 | ;mtime %% 7mtime %% 7MoTuesWednThur5Sunday eea"zT |
| 200 | ; |
| 201 | element(zMenuName, zMenuName, "%s url_render(pUrl, zParBy File", ny TypeelpiechartTABLE peea"zT |
| 202 | ; |
| 203 | @ claT |
| 204 | ; |
| 205 | @ class='lastchngTeble'nameeea"zTuserlist","tT} |
| 206 | style_footer(); @ class='lastchngTeble'nameeea"zTuserlist","tT} |
| 207 | style_footer(); |
| 208 | } |
| 209 | svg class="pie-chart"svg class="pie-chart"ArraySizeArraySizeArraySizeeea"zT |
| 210 | ; |
| 211 | @ class='lastchngTable'nameeea"zTuserlist","tT} |
| 212 | style_footer(); |
| 213 | } |
| 214 | center><svg/centre><hreea"/center><svg/centre><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" |
| 215 | "UPDATE piechart SEWHEN 5 THEN 'Friday'" |
| 216 | "ELSE 'ERROR' END;"svg class="pie-chart" |
| 217 | @ svg class="pie-chart" |
| 218 | @ HQuery url;/* URL for various branch linksurl_initialize(&url, "reports"); |
| 219 | cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", |
| 220 | , "Sunday" |
| 221 | }; |
| 222 | |
| 223 | ;mtime %% 7mtime %% 7MoTuesWednThur5Sunday Generate a submenu element witrep_submenu( |
| 224 | HQuery *pUrl,/* Base URLe><hreea<br>?name=Teea"zT |
| 225 | ; |
| 226 | @ claT |
| 227 | ; |
| 228 | @ ce>4) AS yy ORDER BY y DESC", zUserName) ){ |
| 229 | azYear = fossil_realloc(azYear, sizeof(char*)*(n+2)); |
| 230 | azYear[n] = fossil_strdup(,0)); |
| 231 | azYear[n+1] = azYear[n]; |
| 232 | if( !isValidYear && fossil_strcmp(zYear,azYear[n])==0 ) zYear = azYear[0];zT |
| 233 | ; |
| 234 | @ claT |
| 235 | ; |
| 236 | @ class='lastchngTeble'nameeea"zTuserlist","tT} |
| 237 | style_footer(); @ class='lastchngTeble'nameeea"zTuserlist","tT} |
| 238 | style_footer(); |
| 239 | } |
| 240 | svg class="pie-chart"svg class="pie-chart"ArraySizeArraySizeArraySizeeea"zT |
| 241 | ; |
| 242 | @ class='lastchngTable'nameeea"zTuserlist","tT} |
| 243 | style_footer(); |
| 244 | } |
| 245 | center><svg/centre><hreea"/center><svg/centre><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" |
| 246 | "UPDATE piechart SEWHEN 5 THEN 'Friday'" |
| 247 | "ELSE 'ERRsR' END;"svg class="pie-chart" |
| 248 | @ svg class="pie-chart" |
| 249 | @ Hg.zTop,HQuery url;/* RL for various branch linksurl_initialize(&url, "reports"); |
| 250 | cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", |
| 251 | , "Sunday" |
| 252 | }; |
| 253 | |
| 254 | ;mtime %% 7mt/* |
| 255 | ** A helper for the /reports family of pages which prints out a menu |
| 256 | ** of links for the various type=XXX flags. zCurrentViewName must be |
| 257 | ** the name/value of the 'view' parameter which is in effect at the |
| 258 | ** time this is called. e.g. if called from the 'byuser' view then |
| 259 | ** zCurrentViewName must be "byuser". Any URL parameters which need to |
| 260 | ** be added to the generated URLs should be passed in zParam. The |
| 261 | ** caller is expected to have already encoded any zParam in event_types_menu(c><svg</centre>center><svg</centre> "Thursday", |
| 262 | , "Sunday" |
| 263 | }; |
| 264 | |
| 265 | ;mtime %% 7mtime %% 7MoTuesWednThur5Sunday eea"zT |
| 266 | ; |
| 267 | @e><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" |
| 268 | "UPDATE piechart SEWHEN 5 THEN 'Friday'" |
| 269 | "ELSE 'ERROR' END;"svg class="pie-chart" |
| 270 | @ svg class="pie-chart"uery url;/* URL for various branch linksurl_initialize(&url, "reports"); |
| 271 | cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", |
| 272 | , "Sunday" |
| 273 | }; |
| 274 | |
| 275 | ;mtime %% 7mtime %% 7MoTuesWednThur5Sunday eea"zT |
| 276 | ; |
| 277 | element(zMenuName, zMenuNameinsass="pie-chart" |
| 278 | @ HQuery url;/*ci'>checkin"2;" |
| 279 | "UPDATE piechareea"zT |
| 280 | ; |
| 281 | @ claT |
| 282 | ; |
| 283 | @ class='lastchngTeble'nameeea"zTuserlist","tT} |
| 284 | style_footer(); @ class='lastchngTeble'nameeea"zTuserlist","tT} |
| 285 | style_footer(); |
| 286 | } |
| 287 | svg class="pie-chart"svg class="pie-chart"ArraySizeArraySizeArraySizeeea"zT |
| 288 | ; |
| 289 | @ class='lastchngTable'nameeea"zTuserlist","tT} |
| 290 | style_footer(); |
| 291 | } |
| 292 | center><svg/centre><hreea"/center><svg/centre><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" |
| 293 | "UPDATE piechart SEWHEN 5 THEN 'Friday'" |
| 294 | "ELSE 'ERROR' END;"svg class="pie-chart" |
| 295 | @ svg class="pie-chart" |
| 296 | @ HQuery url;/* URL for various branch linksurl_initialize(&url, "reports"); |
| 297 | cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", |
| 298 | , "Sunday" |
| 299 | }; |
| 300 | |
| 301 | ;mtime %% 7mtime %% 7MoTuesWednThur5Sunday Generate a submenu element witrep_submenu( |
| 302 | HQuery *pUrl,/* Base URLe><hreea<br>?name=Teea"zT |
| 303 | ; |
| 304 | @ claT |
| 305 | ; |
| 306 | @ ce>4) AS yy ORDER BY y DESC", zUserName) ){ |
| 307 | azYear = fossil_realloc(azYear, sizeof(char*)*(n+2)); |
| 308 | azYear[n] = fossil_strdup(,0)); |
| 309 | azYear[n+1] = azYear[n]; |
| 310 | if( !isValidYear && fossil_strcmp(zYear,azYear[n])==0 ) ='lastchngTeble'nameeea"zTuserlist","tT} |
| 311 | style_footer(); @ class='lastchngTeble'nameeea"zTuserlist","tT} |
| 312 | style_footer(); |
| 313 | } |
| 314 | svg class="pie-chart"svg class="pie-chart"ArraySizeArraySizeArraySizeeea"zT |
| 315 | ; |
| 316 | @ class='lastchngTable'nameeea"zTuserlist","tT} |
| 317 | style_footer(); |
| 318 | } |
| 319 | center><svg/centre><hreea"/center><svg/centre><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" |
| 320 | "UPDATE piechart SEWHEN 5 THEN 'Friday'" |
| 321 | "ELSE 'ERROR' END;"svg class="pie-chart" |
| 322 | @ svg class="pie-chart" |
| 323 | @ HQuery url;/* URL for various branch linksurl_initialize(&url, "reports"); |
| 324 | cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", |
| 325 | , "Sunday" |
| 326 | }; |
| 327 | |
| 328 | ;mtime %% 7mtimand not empty |
| 329 | ** class="pie-chart"slist","tT} |
| 330 | style_feeaclass='lastchngTable'nameeea"zTuserlist","tT} |
| 331 | style_footer(); |
| 332 | } |
| 333 | center><svg/centre><hreea"/center><svg/centre><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" |
| 334 | "UPDATE piechart SEWHEN 5 THEN 'Friday'" |
| 335 | "ELSE 'ERROR' END;"svg class="pie-chart" |
| 336 | @ svg class="pie-chart" |
| 337 | @ HQuery url;/* URL for various branch linksurl_initialize(&url, "reports");Blob sql-chart" |
| 338 | @ HQuery /* SQo_url(&url);url_rese_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", |
| 339 | , "Sunday" |
| 340 | }; |
| 341 | |
| 342 | ;mtime %% 7mtime %% 7MoTuesWednThur5Sunday Generate a submenu element witrep_submenu( |
| 343 | HQuery *pUrl,/* Base URLe><hreea<br>?name=Teea"zT |
| 344 | ; |
| 345 | @ claT |
| 346 | ; |
| 347 | @ ce>4) AS yy ORDER BY y DESC", zUserName) ){ |
| 348 | azYear = fossil_realloc(azYear, sizeof(char*)*(n+2)); |
| 349 | azYear[n] = fossil_strdup(,0)); |
| 350 | azYear[n+1] = azYear[n]; |
| 351 | if( !isValidYear && fossil_strcmp(zYear,azYear[n])==0 ) ='lastchngTeble'nameeea"zTuserlist","tT} |
| 352 | style_footer(); @ class='lastchngTeble'nameeea"zTuserlist","tT} |
| 353 | style_footer(); |
| 354 | } |
| 355 | svg class="pie-chart"svg class="pie-chart"ArraySizeArraySizeArraySizeeea"zT |
| 356 | ; |
| 357 | @ class='lastchngTable'nameeea"zTuserlist","tT} |
| 358 | unday" |
| 359 | } NULL ); |
| 360 | header, "s) by yearL for various branchmtime %% 7mtime %% 7MoTuesWedme=TABLE piechart(amt,labelpie); |
| 361 | blob_append_sql(&sqlr5Sunday eea"zT |
| 362 | ; |
| 363 | @e><htimeframe,a"/center><svg/centeea"zincludeMonth if( PB("pie") ){ cgi_query_paramete |
| 364 | " ySizeArraySizeArraySizeeea"zT |
| 365 | ; |
| 366 | @ claT |
| 367 | ; |
| 368 | @"zT |
| 369 | ; |
| 370 | @ claT |
| 371 | ; |
| 372 | @ 'lastchngTeble'name claT |
| 373 | ; |
| 374 | @ class='lastchngTeble'nameeea"zTuserlist","tT} |
| 375 | style_footer(); @ class='lastchngTeble'nameeea"zTuserlist","tT} |
| 376 | style_footer();Usereea"zT |
| 377 | ; |
| 378 | @ claT |
| 379 | ; |
| 380 | @ class='lastchngTeble'nameeea"zTuserlist","tT} |
| 381 | style_footer(); @ class='lastchngTeble'nameeea"zTuserlist","tT} |
| 382 | style_footer(); |
| 383 | } |
| 384 | svg class="pie-chart"svg class="pie-chart"ArraySizeArraySizeArraySizeeea"zT |
| 385 | ; |
| 386 | @ class='lastchngTable'nameeea"zTuserlist","tT} |
| 387 | style_footer(); |
| 388 | } |
| 389 | center><svg/centre><hreea"/center><svg/centre><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" |
| 390 | "UPDATE piechart SEWHEN 5 THEN 'Friday'" |
| 391 | "ELSE 'ERROR' END;"svg class="pie-chart" |
| 392 | @ svg class="pie-chart" |
| 393 | @ HQuery url;/* URL for various branch linksurl_initialize(&url, "reports"); |
| 394 | cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", |
| 395 | , "Sunday" |
| 396 | }; |
| 397 | |
| 398 | ;mtime %% 7mtime %% 7MoTuesWednThur5Sunday Generate a submenu element witrep_submenu( |
| 399 | HQuery *pUrl,/* Base URLe><hreea<br>?name=Teea"zT |
| 400 | ; |
| 401 | @ claT |
| 402 | ; |
| 403 | @ ce><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" |
| 404 | "UPDATE piechart SEWHEN 5 THEN 'Friday'" |
| 405 | "ELSE 'ERROR' END;"svg class="pie-chart" |
| 406 | @ svg class="pie-chart" |
| 407 | @ HQuery url;/* URL for various branch linksurl_initialize(&url, "reports"); |
| 408 | cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", |
| 409 | , "Sunday" |
| 410 | }; |
| 411 | |
| 412 | ;mtime %% 7mtime %% 7MoTuesWednThur5Sunday eea"zT |
| 413 | ; |
| 414 | @ claT |
| 415 | e><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" |
| 416 | "UPDATE piechart SEWHEN 5 THEN 'Friday'" |
| 417 | "ELSE 'ERROR' END;"svg class="pie-chart" |
| 418 | @ svg class="pie-chart" |
| 419 | @ HQuery url;/* URL for various branch linksurl_initialize(&url, "reports"); |
| 420 | cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", |
| 421 | , "Sunday" |
| 422 | }; |
| 423 | |
| 424 | ;mtime %% 7mtime %% 7MoTuesWednThur5Sunday eea"zT |
| 425 | ; |
| 426 | @e><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" |
| 427 | "UPDATE piechart SEWHEN 5 THEN 'Friday'" |
| 428 | "ELSE 'ERROR' END;"svg class="pie-chart" |
| 429 | @ svg class="pie-chart" |
| 430 | @ HQuery url;/* URL for various branch linksurl_initialize(&url, "reports"); |
| 431 | cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", |
| 432 | , "Sunday" |
| 433 | }; |
| 434 | |
| 435 | ;mtime %% 7mtime %% 7MoTuesWednThur5Sunday eea"zT |
| 436 | ; |
| 437 | element(zMenuName, zMenuName, "%s url_render(pUrl, zParBy File", ny TypeelpiechartTABLE peea"zT |
| 438 | ; |
| 439 | @ claT |
| 440 | ; |
| 441 | @ class='lastchngTeble'nameeea"zTuserlist","tT} |
| 442 | style_footer(); @ class='lastchngTeble'nameeea"zTuserlist","tT} |
| 443 | style_footer(); |
| 444 | } |
| 445 | svg class="pie-chart"svg class="pie-chart"ArraySizeArraySizeArraySizeeea"zT |
| 446 | ; |
| 447 | @ class='lastchngTable'nameeea"zTuserlist","tT} |
| 448 | style_footer(); |
| 449 | } |
| 450 | center><svg/centre><hreea"/center><svg/centre><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" |
| 451 | "UPDATE piechart SEWHEN 5 THEN 'Friday'" |
| 452 | "ELSE 'ERROR' END;"svg class="pie-chart" |
| 453 | @ svg class="pie-chart" |
| 454 | @ HQuery url;/* URL for various branch linksurl_initialize(&url, "reports"); |
| 455 | cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", |
| 456 | , "Sunday" |
| 457 | }; |
| 458 | |
| 459 | ;mtime %% 7mtime %% 7MoTuesWednThur5Sunday Generate a submenu element witrep_submenu( |
| 460 | HQuery *pUrl,/* Base URLe><hreea<br>?name=Teea"zT |
| 461 | ; |
| 462 | @ claT |
| 463 | ; |
| 464 | @ ce>4) AS yy ORDER BY y DESC", zUserName) ){ |
| 465 | azYear = fossil_realloc(azYear, sizeof(char*)*(n+2)); |
| 466 | azYear[n] = fossil_strdup(,0)); |
| 467 | azYear[n+1] = azYear[n]; |
| 468 | if( !isValidYear && fossil_strcmp(zYear,azYear[n])==0 ) zYear = azYear[0];zT |
| 469 | ; |
| 470 | @ claT |
| 471 | ; |
| 472 | @ class='lastchngTeble'nameeea"zTuserlist","tT} |
| 473 | style_footer(); @ class='lastchngTeble'nameeea"zTuserlist","tT} |
| 474 | style_footer(); |
| 475 | } |
| 476 | svg class="pie-chart"svg class="pie-chart"ArraySizeArraySizeArraySizeeea"zT |
| 477 | ; |
| 478 | @ class='lastchngTable'nameeea"zTuserlist","tT} |
| 479 | style_footer(); |
| 480 | } |
| 481 | center><svg/centre><hreea"/center><svg/centre><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" |
| 482 | "UPDATE piechart SEWHEN 5 THEN 'Friday'" |
| 483 | "ELSE 'ERROR' END;"svg class="pie-chart" |
| 484 | @ svg class="pie-chart" |
| 485 | @ HQuery url;/* RL for various branch linksurl_initialize(&url, "reports"); |
| 486 | cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", |
| 487 | , "Sunday" |
| 488 | }; |
| 489 | |
| 490 | ;mtime %% 7mt/* |
| 491 | ** A helper for the /reports family of pages which prints out a menu |
| 492 | ** of links for the various type=XXX flags. zCurrentViewName must be |
| 493 | ** the name/value of the 'view' parameter which is in effect at the |
| 494 | ** time this is called. e.g. if called from the 'byuser' view then |
| 495 | ** zCurrentViewName musa<br>?name=Teea"zT |
| 496 | ;g.zTop,; |
| 497 | @ claT |
| 498 | ; |
| 499 | @ ce>4) AS yy ORDER BY y DESC", zUserName) ){ |
| 500 | azYear = fossil_realloc(azYear, sizeof(char*)*(n+2)); |
| 501 | azYear[n] = fossil_strdup(,0)); |
| 502 | azYear[n+1] = azYear[n]; |
| 503 | if( !isValidYear && fossil_strcmp(zYear,azYear[n])==0 ) ='lastchngTeble'nameeea"zTuserlist","tT} |
| 504 | style_footer(); @ class='lastchngTeble'nameeea"zTuserlist","tT} |
| 505 | style_footer(); |
| 506 | } |
| 507 | svg class="pie-chart"svg class="pie-chart"ArraySizeArraySizeArraySizeeea"zT |
| 508 | ; |
| 509 | @ class='lastchngTable'nameeea"zTuserlist","tT} |
| 510 | style_footer(); |
| 511 | } |
| 512 | center><svg/centre><hreea"/center><svg/centre><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" |
| 513 | "UPDATE piechart SEWHEN 5 THEN 'Friday'" |
| 514 | "ELSE 'ERROR' END;"svg class="pie-chart" |
| 515 | @ svg class="pie-chart" |
| 516 | @ HQuery url;/* URL for various branch linksurl_initialize(&url, "reports"); |
| 517 | cgi_query_parameters_to_url(&url);url_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", |
| 518 | , "Sunday" |
| 519 | }; |
| 520 | |
| 521 | ;mtime %% 7mtimand not empty |
| 522 | ** class="pie-chart"slist","tT} |
| 523 | style_feeaclass='lastchngTable'nameeea"zTuserlist","tT} |
| 524 | style_footer(); |
| 525 | } |
| 526 | center><svg/centre><hreea"/center><svg/centre><hreea<br>?name=TABLE piechart(amt,labelpiechartTABLE piechart(amt,labelpiechart)"2;" |
| 527 | "UPDATE piechart SEWHEN 5 THEN 'Friday'" |
| 528 | "ELSE 'ERROR' END;"svg class="pie-chart" |
| 529 | @ svg class="pie-chart" |
| 530 | @ HQuery url;/* URL for various branch linksurl_initialize(&url, "reports");Blob sql-chart" |
| 531 | @ HQuery /* SQo_url(&url);url_rese_reset(&urlcenter><svg</centre>center><svg</centre> "Thursday", |
| 532 | , "Sunday" |
| 533 | }; |
| 534 | |
| 535 | ;mtime %% 7mtime %% 7MoTuesWednThur5Sunday Ge |
+1
-1
| --- src/style.c | ||
| +++ src/style.c | ||
| @@ -354,11 +354,11 @@ | ||
| 354 | 354 | |
| 355 | 355 | #if INTERFACE |
| 356 | 356 | /* Allowed parameters for style_adunit() */ |
| 357 | 357 | #define ADUNIT_OFF 0x0001 /* Do not allow ads on this page */ |
| 358 | 358 | #define ADUNIT_RIGHT_OK 0x0002 /* Right-side vertical ads ok here */ |
| 359 | -#endif | |
| 359 | +#endif | |
| 360 | 360 | |
| 361 | 361 | /* |
| 362 | 362 | ** Various page implementations can invoke this interface to let the |
| 363 | 363 | ** style manager know what kinds of ads are appropriate for this page. |
| 364 | 364 | */ |
| 365 | 365 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -354,11 +354,11 @@ | |
| 354 | |
| 355 | #if INTERFACE |
| 356 | /* Allowed parameters for style_adunit() */ |
| 357 | #define ADUNIT_OFF 0x0001 /* Do not allow ads on this page */ |
| 358 | #define ADUNIT_RIGHT_OK 0x0002 /* Right-side vertical ads ok here */ |
| 359 | #endif |
| 360 | |
| 361 | /* |
| 362 | ** Various page implementations can invoke this interface to let the |
| 363 | ** style manager know what kinds of ads are appropriate for this page. |
| 364 | */ |
| 365 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -354,11 +354,11 @@ | |
| 354 | |
| 355 | #if INTERFACE |
| 356 | /* Allowed parameters for style_adunit() */ |
| 357 | #define ADUNIT_OFF 0x0001 /* Do not allow ads on this page */ |
| 358 | #define ADUNIT_RIGHT_OK 0x0002 /* Right-side vertical ads ok here */ |
| 359 | #endif |
| 360 | |
| 361 | /* |
| 362 | ** Various page implementations can invoke this interface to let the |
| 363 | ** style manager know what kinds of ads are appropriate for this page. |
| 364 | */ |
| 365 |
+1
-1
| --- src/tag.c | ||
| +++ src/tag.c | ||
| @@ -269,11 +269,11 @@ | ||
| 269 | 269 | } |
| 270 | 270 | g.markPrivate = content_is_private(rid); |
| 271 | 271 | zValue = g.argc==5 ? g.argv[4] : 0; |
| 272 | 272 | db_begin_transaction(); |
| 273 | 273 | tag_insert(zTag, tagtype, zValue, -1, 0.0, rid); |
| 274 | - db_end_transaction(0); | |
| 274 | + db_end_transaction(0); | |
| 275 | 275 | } |
| 276 | 276 | |
| 277 | 277 | /* |
| 278 | 278 | ** Add a control record to the repository that either creates |
| 279 | 279 | ** or cancels a tag. |
| 280 | 280 |
| --- src/tag.c | |
| +++ src/tag.c | |
| @@ -269,11 +269,11 @@ | |
| 269 | } |
| 270 | g.markPrivate = content_is_private(rid); |
| 271 | zValue = g.argc==5 ? g.argv[4] : 0; |
| 272 | db_begin_transaction(); |
| 273 | tag_insert(zTag, tagtype, zValue, -1, 0.0, rid); |
| 274 | db_end_transaction(0); |
| 275 | } |
| 276 | |
| 277 | /* |
| 278 | ** Add a control record to the repository that either creates |
| 279 | ** or cancels a tag. |
| 280 |
| --- src/tag.c | |
| +++ src/tag.c | |
| @@ -269,11 +269,11 @@ | |
| 269 | } |
| 270 | g.markPrivate = content_is_private(rid); |
| 271 | zValue = g.argc==5 ? g.argv[4] : 0; |
| 272 | db_begin_transaction(); |
| 273 | tag_insert(zTag, tagtype, zValue, -1, 0.0, rid); |
| 274 | db_end_transaction(0); |
| 275 | } |
| 276 | |
| 277 | /* |
| 278 | ** Add a control record to the repository that either creates |
| 279 | ** or cancels a tag. |
| 280 |
+2
-2
| --- src/th_main.c | ||
| +++ src/th_main.c | ||
| @@ -391,15 +391,15 @@ | ||
| 391 | 391 | int argc, |
| 392 | 392 | const char **argv, |
| 393 | 393 | int *argl |
| 394 | 394 | ){ |
| 395 | 395 | int rc = 0; |
| 396 | - char const * zArg; | |
| 396 | + const char *zArg; | |
| 397 | 397 | if( argc!=2 ){ |
| 398 | 398 | return Th_WrongNumArgs(interp, "hasfeature STRING"); |
| 399 | 399 | } |
| 400 | - zArg = (char const*)argv[1]; | |
| 400 | + zArg = (const char *)argv[1]; | |
| 401 | 401 | if(NULL==zArg){ |
| 402 | 402 | /* placeholder for following ifdefs... */ |
| 403 | 403 | } |
| 404 | 404 | #if defined(FOSSIL_ENABLE_SSL) |
| 405 | 405 | else if( 0 == fossil_strnicmp( zArg, "ssl\0", 4 ) ){ |
| 406 | 406 |
| --- src/th_main.c | |
| +++ src/th_main.c | |
| @@ -391,15 +391,15 @@ | |
| 391 | int argc, |
| 392 | const char **argv, |
| 393 | int *argl |
| 394 | ){ |
| 395 | int rc = 0; |
| 396 | char const * zArg; |
| 397 | if( argc!=2 ){ |
| 398 | return Th_WrongNumArgs(interp, "hasfeature STRING"); |
| 399 | } |
| 400 | zArg = (char const*)argv[1]; |
| 401 | if(NULL==zArg){ |
| 402 | /* placeholder for following ifdefs... */ |
| 403 | } |
| 404 | #if defined(FOSSIL_ENABLE_SSL) |
| 405 | else if( 0 == fossil_strnicmp( zArg, "ssl\0", 4 ) ){ |
| 406 |
| --- src/th_main.c | |
| +++ src/th_main.c | |
| @@ -391,15 +391,15 @@ | |
| 391 | int argc, |
| 392 | const char **argv, |
| 393 | int *argl |
| 394 | ){ |
| 395 | int rc = 0; |
| 396 | const char *zArg; |
| 397 | if( argc!=2 ){ |
| 398 | return Th_WrongNumArgs(interp, "hasfeature STRING"); |
| 399 | } |
| 400 | zArg = (const char *)argv[1]; |
| 401 | if(NULL==zArg){ |
| 402 | /* placeholder for following ifdefs... */ |
| 403 | } |
| 404 | #if defined(FOSSIL_ENABLE_SSL) |
| 405 | else if( 0 == fossil_strnicmp( zArg, "ssl\0", 4 ) ){ |
| 406 |
+3
-684
| --- src/timeline.c | ||
| +++ src/timeline.c | ||
| @@ -360,20 +360,20 @@ | ||
| 360 | 360 | } |
| 361 | 361 | } |
| 362 | 362 | } |
| 363 | 363 | if( zType[0]=='c' && (pGraph || (tmFlags & TIMELINE_BRCOLOR)!=0) ){ |
| 364 | 364 | int nParent = 0; |
| 365 | - int aParent[32]; | |
| 365 | + int aParent[GR_MAX_RAIL]; | |
| 366 | 366 | int gidx; |
| 367 | 367 | static Stmt qparent; |
| 368 | 368 | db_static_prepare(&qparent, |
| 369 | 369 | "SELECT pid FROM plink" |
| 370 | 370 | " WHERE cid=:rid AND pid NOT IN phantom" |
| 371 | 371 | " ORDER BY isprim DESC /*sort*/" |
| 372 | 372 | ); |
| 373 | 373 | db_bind_int(&qparent, ":rid", rid); |
| 374 | - while( db_step(&qparent)==SQLITE_ROW && nParent<32 ){ | |
| 374 | + while( db_step(&qparent)==SQLITE_ROW && nParent<ArraySize(aParent) ){ | |
| 375 | 375 | aParent[nParent++] = db_column_int(&qparent, 0); |
| 376 | 376 | } |
| 377 | 377 | db_reset(&qparent); |
| 378 | 378 | gidx = graph_add_row(pGraph, rid, nParent, aParent, zBr, zBgClr, |
| 379 | 379 | zUuid, isLeaf); |
| @@ -1556,11 +1556,11 @@ | ||
| 1556 | 1556 | } |
| 1557 | 1557 | } |
| 1558 | 1558 | if( P("showsql") ){ |
| 1559 | 1559 | @ <blockquote>%h(blob_sql_text(&sql))</blockquote> |
| 1560 | 1560 | } |
| 1561 | - if( P("showrid") ) tmFlags |= TIMELINE_SHOWRID; | |
| 1561 | + if( P("showid") ) tmFlags |= TIMELINE_SHOWRID; | |
| 1562 | 1562 | blob_zero(&sql); |
| 1563 | 1563 | db_prepare(&q, "SELECT * FROM timeline ORDER BY sortby DESC /*scan*/"); |
| 1564 | 1564 | @ <h2>%b(&desc)</h2> |
| 1565 | 1565 | blob_reset(&desc); |
| 1566 | 1566 | www_print_timeline(&q, tmFlags, zThisUser, zThisTag, 0); |
| @@ -2044,688 +2044,7 @@ | ||
| 2044 | 2044 | const char *zUuid = db_column_text(&q, 0); |
| 2045 | 2045 | @ <li> |
| 2046 | 2046 | @ <a href="%s(g.zTop)/timeline?p=%s(zUuid)&d=%s(zUuid)&unhide">%S(zUuid)</a> |
| 2047 | 2047 | } |
| 2048 | 2048 | db_finalize(&q); |
| 2049 | - style_footer(); | |
| 2050 | -} | |
| 2051 | - | |
| 2052 | - | |
| 2053 | -/* | |
| 2054 | -** Used by stats_report_xxxxx() to remember which type of events | |
| 2055 | -** to show. Populated by stats_report_init_view() and holds the | |
| 2056 | -** return value of that function. | |
| 2057 | -*/ | |
| 2058 | -static int statsReportType = 0; | |
| 2059 | - | |
| 2060 | -/* | |
| 2061 | -** Set by stats_report_init_view() to one of the y=XXXX values | |
| 2062 | -** accepted by /timeline?y=XXXX. | |
| 2063 | -*/ | |
| 2064 | -static const char *statsReportTimelineYFlag = NULL; | |
| 2065 | - | |
| 2066 | -/* | |
| 2067 | -** Creates a TEMP VIEW named v_reports which is a wrapper around the | |
| 2068 | -** EVENT table filtered on event.type. It looks for the request | |
| 2069 | -** parameter 'type' (reminder: we "should" use 'y' for consistency | |
| 2070 | -** with /timeline, but /reports uses 'y' for the year) and expects it | |
| 2071 | -** to contain one of the conventional values from event.type or the | |
| 2072 | -** value "all", which is treated as equivalent to "*". By default (if | |
| 2073 | -** no 'y' is specified), "*" is assumed (that is also the default for | |
| 2074 | -** invalid/unknown filter values). That 'y' filter is the one used for | |
| 2075 | -** the event list. Note that a filter of "*" or "all" is equivalent to | |
| 2076 | -** querying against the full event table. The view, however, adds an | |
| 2077 | -** abstraction level to simplify the implementation code for the | |
| 2078 | -** various /reports pages. | |
| 2079 | -** | |
| 2080 | -** Returns one of: 'c', 'w', 'g', 't', 'e', representing the type of | |
| 2081 | -** filter it applies, or '*' if no filter is applied (i.e. if "all" is | |
| 2082 | -** used). | |
| 2083 | -*/ | |
| 2084 | -static int stats_report_init_view(){ | |
| 2085 | - const char *zType = PD("type","*"); /* analog to /timeline?y=... */ | |
| 2086 | - const char *zRealType = NULL; /* normalized form of zType */ | |
| 2087 | - int rc = 0; /* result code */ | |
| 2088 | - assert( !statsReportType && "Must not be called more than once." ); | |
| 2089 | - switch( (zType && *zType) ? *zType : 0 ){ | |
| 2090 | - case 'c': | |
| 2091 | - case 'C': | |
| 2092 | - zRealType = "ci"; | |
| 2093 | - rc = *zRealType; | |
| 2094 | - break; | |
| 2095 | - case 'e': | |
| 2096 | - case 'E': | |
| 2097 | - zRealType = "e"; | |
| 2098 | - rc = *zRealType; | |
| 2099 | - break; | |
| 2100 | - case 'g': | |
| 2101 | - case 'G': | |
| 2102 | - zRealType = "g"; | |
| 2103 | - rc = *zRealType; | |
| 2104 | - break; | |
| 2105 | - case 't': | |
| 2106 | - case 'T': | |
| 2107 | - zRealType = "t"; | |
| 2108 | - rc = *zRealType; | |
| 2109 | - break; | |
| 2110 | - case 'w': | |
| 2111 | - case 'W': | |
| 2112 | - zRealType = "w"; | |
| 2113 | - rc = *zRealType; | |
| 2114 | - break; | |
| 2115 | - default: | |
| 2116 | - rc = '*'; | |
| 2117 | - break; | |
| 2118 | - } | |
| 2119 | - assert(0 != rc); | |
| 2120 | - if(zRealType){ | |
| 2121 | - statsReportTimelineYFlag = zRealType; | |
| 2122 | - db_multi_exec("CREATE TEMP VIEW v_reports AS " | |
| 2123 | - "SELECT * FROM event WHERE type GLOB %Q", | |
| 2124 | - zRealType); | |
| 2125 | - }else{ | |
| 2126 | - statsReportTimelineYFlag = "a"; | |
| 2127 | - db_multi_exec("CREATE TEMP VIEW v_reports AS " | |
| 2128 | - "SELECT * FROM event"); | |
| 2129 | - } | |
| 2130 | - return statsReportType = rc; | |
| 2131 | -} | |
| 2132 | - | |
| 2133 | -/* | |
| 2134 | -** Returns a string suitable (for a given value of suitable) for | |
| 2135 | -** use in a label with the header of the /reports pages, dependent | |
| 2136 | -** on the 'type' flag. See stats_report_init_view(). | |
| 2137 | -** The returned bytes are static. | |
| 2138 | -*/ | |
| 2139 | -static const char *stats_report_label_for_type(){ | |
| 2140 | - assert( statsReportType && "Must call stats_report_init_view() first." ); | |
| 2141 | - switch( statsReportType ){ | |
| 2142 | - case 'c': | |
| 2143 | - return "checkins"; | |
| 2144 | - case 'e': | |
| 2145 | - return "events"; | |
| 2146 | - case 'w': | |
| 2147 | - return "wiki changes"; | |
| 2148 | - case 't': | |
| 2149 | - return "ticket changes"; | |
| 2150 | - case 'g': | |
| 2151 | - return "tag changes"; | |
| 2152 | - default: | |
| 2153 | - return "all types"; | |
| 2154 | - } | |
| 2155 | -} | |
| 2156 | - | |
| 2157 | -/* | |
| 2158 | -** A helper for the /reports family of pages which prints out a menu | |
| 2159 | -** of links for the various type=XXX flags. zCurrentViewName must be | |
| 2160 | -** the name/value of the 'view' parameter which is in effect at the | |
| 2161 | -** time this is called. e.g. if called from the 'byuser' view then | |
| 2162 | -** zCurrentViewName must be "byuser". Any URL parameters which need to | |
| 2163 | -** be added to the generated URLs should be passed in zParam. The | |
| 2164 | -** caller is expected to have already encoded any zParam in the %T or | |
| 2165 | -** %t encoding. */ | |
| 2166 | -static void stats_report_event_types_menu(const char *zCurrentViewName, | |
| 2167 | - const char *zParam){ | |
| 2168 | - char *zTop; | |
| 2169 | - if(zParam && !*zParam){ | |
| 2170 | - zParam = NULL; | |
| 2171 | - } | |
| 2172 | - zTop = mprintf("%s/reports?view=%s%s%s", g.zTop, zCurrentViewName, | |
| 2173 | - zParam ? "&" : "", zParam); | |
| 2174 | - cgi_printf("<div>"); | |
| 2175 | - cgi_printf("<span>Types:</span> "); | |
| 2176 | - if('*' == statsReportType){ | |
| 2177 | - cgi_printf(" <strong>all</strong>", zTop); | |
| 2178 | - }else{ | |
| 2179 | - cgi_printf(" <a href='%s'>all</a>", zTop); | |
| 2180 | - } | |
| 2181 | - if('c' == statsReportType){ | |
| 2182 | - cgi_printf(" <strong>checkins</strong>", zTop); | |
| 2183 | - }else{ | |
| 2184 | - cgi_printf(" <a href='%s&type=ci'>checkins</a>", zTop); | |
| 2185 | - } | |
| 2186 | - if('e' == statsReportType){ | |
| 2187 | - cgi_printf(" <strong>events</strong>", zTop); | |
| 2188 | - }else{ | |
| 2189 | - cgi_printf(" <a href='%s&type=e'>events</a>", zTop); | |
| 2190 | - } | |
| 2191 | - if( 't' == statsReportType ){ | |
| 2192 | - cgi_printf(" <strong>tickets</strong>", zTop); | |
| 2193 | - }else{ | |
| 2194 | - cgi_printf(" <a href='%s&type=t'>tickets</a>", zTop); | |
| 2195 | - } | |
| 2196 | - if( 'g' == statsReportType ){ | |
| 2197 | - cgi_printf(" <strong>tags</strong>", zTop); | |
| 2198 | - }else{ | |
| 2199 | - cgi_printf(" <a href='%s&type=g'>tags</a>", zTop); | |
| 2200 | - } | |
| 2201 | - if( 'w' == statsReportType ){ | |
| 2202 | - cgi_printf(" <strong>wiki</strong>", zTop); | |
| 2203 | - }else{ | |
| 2204 | - cgi_printf(" <a href='%s&type=w'>wiki</a>", zTop); | |
| 2205 | - } | |
| 2206 | - fossil_free(zTop); | |
| 2207 | - cgi_printf("</div>"); | |
| 2208 | -} | |
| 2209 | - | |
| 2210 | - | |
| 2211 | -/* | |
| 2212 | -** Helper for stats_report_by_month_year(), which generates a list of | |
| 2213 | -** week numbers. zTimeframe should be either a timeframe in the form YYYY | |
| 2214 | -** or YYYY-MM. | |
| 2215 | -*/ | |
| 2216 | -static void stats_report_output_week_links(const char *zTimeframe){ | |
| 2217 | - Stmt stWeek = empty_Stmt; | |
| 2218 | - char yearPart[5] = {0,0,0,0,0}; | |
| 2219 | - memcpy(yearPart, zTimeframe, 4); | |
| 2220 | - db_prepare(&stWeek, | |
| 2221 | - "SELECT DISTINCT strftime('%%W',mtime) AS wk, " | |
| 2222 | - "count(*) AS n, " | |
| 2223 | - "substr(date(mtime),1,%d) AS ym " | |
| 2224 | - "FROM v_reports " | |
| 2225 | - "WHERE ym=%Q AND mtime < current_timestamp " | |
| 2226 | - "GROUP BY wk ORDER BY wk", | |
| 2227 | - strlen(zTimeframe), | |
| 2228 | - zTimeframe); | |
| 2229 | - while( SQLITE_ROW == db_step(&stWeek) ){ | |
| 2230 | - const char *zWeek = db_column_text(&stWeek,0); | |
| 2231 | - const int nCount = db_column_int(&stWeek,1); | |
| 2232 | - cgi_printf("<a href='%s/timeline?" | |
| 2233 | - "yw=%t-%t&n=%d&y=%s'>%s</a>", | |
| 2234 | - g.zTop, yearPart, zWeek, | |
| 2235 | - nCount, statsReportTimelineYFlag, zWeek); | |
| 2236 | - } | |
| 2237 | - db_finalize(&stWeek); | |
| 2238 | -} | |
| 2239 | - | |
| 2240 | -/* | |
| 2241 | -** Implements the "byyear" and "bymonth" reports for /reports. | |
| 2242 | -** If includeMonth is true then it generates the "bymonth" report, | |
| 2243 | -** else the "byyear" report. If zUserName is not NULL and not empty | |
| 2244 | -** then the report is restricted to events created by the named user | |
| 2245 | -** account. | |
| 2246 | -*/ | |
| 2247 | -static void stats_report_by_month_year(char includeMonth, | |
| 2248 | - char includeWeeks, | |
| 2249 | - const char *zUserName){ | |
| 2250 | - Stmt query = empty_Stmt; | |
| 2251 | - int nRowNumber = 0; /* current TR number */ | |
| 2252 | - int nEventTotal = 0; /* Total event count */ | |
| 2253 | - int rowClass = 0; /* counter for alternating | |
| 2254 | - row colors */ | |
| 2255 | - Blob sql = empty_blob; /* SQL */ | |
| 2256 | - const char *zTimeLabel = includeMonth ? "Year/Month" : "Year"; | |
| 2257 | - char zPrevYear[5] = {0}; /* For keeping track of when | |
| 2258 | - we change years while looping */ | |
| 2259 | - int nEventsPerYear = 0; /* Total event count for the | |
| 2260 | - current year */ | |
| 2261 | - char showYearTotal = 0; /* Flag telling us when to show | |
| 2262 | - the per-year event totals */ | |
| 2263 | - Blob header = empty_blob; /* Page header text */ | |
| 2264 | - int nMaxEvents = 1; /* for calculating length of graph | |
| 2265 | - bars. */ | |
| 2266 | - int iterations = 0; /* number of weeks/months we iterate | |
| 2267 | - over */ | |
| 2268 | - stats_report_init_view(); | |
| 2269 | - stats_report_event_types_menu( includeMonth ? "bymonth" : "byyear", NULL ); | |
| 2270 | - blob_appendf(&header, "Timeline Events (%s) by year%s", | |
| 2271 | - stats_report_label_for_type(), | |
| 2272 | - (includeMonth ? "/month" : "")); | |
| 2273 | - blob_append_sql(&sql, | |
| 2274 | - "SELECT substr(date(mtime),1,%d) AS timeframe, " | |
| 2275 | - "count(*) AS eventCount " | |
| 2276 | - "FROM v_reports ", | |
| 2277 | - includeMonth ? 7 : 4); | |
| 2278 | - if(zUserName&&*zUserName){ | |
| 2279 | - blob_append_sql(&sql, " WHERE user=%Q ", zUserName); | |
| 2280 | - blob_appendf(&header," for user %q", zUserName); | |
| 2281 | - } | |
| 2282 | - blob_append(&sql, | |
| 2283 | - " GROUP BY timeframe" | |
| 2284 | - " ORDER BY timeframe DESC", | |
| 2285 | - -1); | |
| 2286 | - db_prepare(&query, "%s", blob_sql_text(&sql)); | |
| 2287 | - blob_reset(&sql); | |
| 2288 | - @ <h1>%b(&header)</h1> | |
| 2289 | - @ <table class='statistics-report-table-events' border='0' cellpadding='2' | |
| 2290 | - @ cellspacing='0' id='statsTable'> | |
| 2291 | - @ <thead> | |
| 2292 | - @ <th>%s(zTimeLabel)</th> | |
| 2293 | - @ <th>Events</th> | |
| 2294 | - @ <th width='90%%'><!-- relative commits graph --></th> | |
| 2295 | - @ </thead><tbody> | |
| 2296 | - blob_reset(&header); | |
| 2297 | - /* | |
| 2298 | - Run the query twice. The first time we calculate the maximum | |
| 2299 | - number of events for a given row. Maybe someone with better SQL | |
| 2300 | - Fu can re-implement this with a single query. | |
| 2301 | - */ | |
| 2302 | - while( SQLITE_ROW == db_step(&query) ){ | |
| 2303 | - const int nCount = db_column_int(&query, 1); | |
| 2304 | - if(nCount>nMaxEvents){ | |
| 2305 | - nMaxEvents = nCount; | |
| 2306 | - } | |
| 2307 | - ++iterations; | |
| 2308 | - } | |
| 2309 | - db_reset(&query); | |
| 2310 | - while( SQLITE_ROW == db_step(&query) ){ | |
| 2311 | - const char *zTimeframe = db_column_text(&query, 0); | |
| 2312 | - const int nCount = db_column_int(&query, 1); | |
| 2313 | - int nSize = nCount | |
| 2314 | - ? (int)(100 * nCount / nMaxEvents) | |
| 2315 | - : 1; | |
| 2316 | - showYearTotal = 0; | |
| 2317 | - if(!nSize) nSize = 1; | |
| 2318 | - if(includeMonth){ | |
| 2319 | - /* For Month/year view, add a separator for each distinct year. */ | |
| 2320 | - if(!*zPrevYear || | |
| 2321 | - (0!=fossil_strncmp(zPrevYear,zTimeframe,4))){ | |
| 2322 | - showYearTotal = *zPrevYear; | |
| 2323 | - if(showYearTotal){ | |
| 2324 | - rowClass = ++nRowNumber % 2; | |
| 2325 | - @ <tr class='row%d(rowClass)'> | |
| 2326 | - @ <td></td> | |
| 2327 | - @ <td colspan='2'>Yearly total: %d(nEventsPerYear)</td> | |
| 2328 | - @</tr> | |
| 2329 | - } | |
| 2330 | - nEventsPerYear = 0; | |
| 2331 | - memcpy(zPrevYear,zTimeframe,4); | |
| 2332 | - rowClass = ++nRowNumber % 2; | |
| 2333 | - @ <tr class='row%d(rowClass)'> | |
| 2334 | - @ <th colspan='3' class='statistics-report-row-year'>%s(zPrevYear)</th> | |
| 2335 | - @ </tr> | |
| 2336 | - } | |
| 2337 | - } | |
| 2338 | - rowClass = ++nRowNumber % 2; | |
| 2339 | - nEventTotal += nCount; | |
| 2340 | - nEventsPerYear += nCount; | |
| 2341 | - @<tr class='row%d(rowClass)'> | |
| 2342 | - @ <td> | |
| 2343 | - if(includeMonth){ | |
| 2344 | - cgi_printf("<a href='%s/timeline?" | |
| 2345 | - "ym=%t&n=%d&y=%s", | |
| 2346 | - g.zTop, zTimeframe, nCount, | |
| 2347 | - statsReportTimelineYFlag ); | |
| 2348 | - /* Reminder: n=nCount is not actually correct for bymonth unless | |
| 2349 | - that was the only user who caused events. | |
| 2350 | - */ | |
| 2351 | - if( zUserName && *zUserName ){ | |
| 2352 | - cgi_printf("&u=%t", zUserName); | |
| 2353 | - } | |
| 2354 | - cgi_printf("' target='_new'>%s</a>",zTimeframe); | |
| 2355 | - }else { | |
| 2356 | - cgi_printf("<a href='?view=byweek&y=%s&type=%c", | |
| 2357 | - zTimeframe, (char)statsReportType); | |
| 2358 | - if(zUserName && *zUserName){ | |
| 2359 | - cgi_printf("&u=%t", zUserName); | |
| 2360 | - } | |
| 2361 | - cgi_printf("'>%s</a>", zTimeframe); | |
| 2362 | - } | |
| 2363 | - @ </td><td>%d(nCount)</td> | |
| 2364 | - @ <td> | |
| 2365 | - @ <div class='statistics-report-graph-line' | |
| 2366 | - @ style='width:%d(nSize)%%;'> </div> | |
| 2367 | - @ </td> | |
| 2368 | - @</tr> | |
| 2369 | - if(includeWeeks){ | |
| 2370 | - /* This part works fine for months but it terribly slow (4.5s on my PC), | |
| 2371 | - so it's only shown for by-year for now. Suggestions/patches for | |
| 2372 | - a better/faster layout are welcomed. */ | |
| 2373 | - @ <tr class='row%d(rowClass)'> | |
| 2374 | - @ <td colspan='2' class='statistics-report-week-number-label'>Week #:</td> | |
| 2375 | - @ <td class='statistics-report-week-of-year-list'> | |
| 2376 | - stats_report_output_week_links(zTimeframe); | |
| 2377 | - @ </td></tr> | |
| 2378 | - } | |
| 2379 | - | |
| 2380 | - /* | |
| 2381 | - Potential improvement: calculate the min/max event counts and | |
| 2382 | - use percent-based graph bars. | |
| 2383 | - */ | |
| 2384 | - } | |
| 2385 | - db_finalize(&query); | |
| 2386 | - if(includeMonth && !showYearTotal && *zPrevYear){ | |
| 2387 | - /* Add final year total separator. */ | |
| 2388 | - rowClass = ++nRowNumber % 2; | |
| 2389 | - @ <tr class='row%d(rowClass)'> | |
| 2390 | - @ <td></td> | |
| 2391 | - @ <td colspan='2'>Yearly total: %d(nEventsPerYear)</td> | |
| 2392 | - @</tr> | |
| 2393 | - } | |
| 2394 | - @ </tbody></table> | |
| 2395 | - if(nEventTotal){ | |
| 2396 | - const char *zAvgLabel = includeMonth ? "month" : "year"; | |
| 2397 | - int nAvg = iterations ? (nEventTotal/iterations) : 0; | |
| 2398 | - @ <br><div>Total events: %d(nEventTotal) | |
| 2399 | - @ <br>Average per active %s(zAvgLabel): %d(nAvg) | |
| 2400 | - @ </div> | |
| 2401 | - } | |
| 2402 | - if( !includeMonth ){ | |
| 2403 | - output_table_sorting_javascript("statsTable","tnx",-1); | |
| 2404 | - } | |
| 2405 | -} | |
| 2406 | - | |
| 2407 | -/* | |
| 2408 | -** Implements the "byuser" view for /reports. | |
| 2409 | -*/ | |
| 2410 | -static void stats_report_by_user(){ | |
| 2411 | - Stmt query = empty_Stmt; | |
| 2412 | - int nRowNumber = 0; /* current TR number */ | |
| 2413 | - int nEventTotal = 0; /* Total event count */ | |
| 2414 | - int rowClass = 0; /* counter for alternating | |
| 2415 | - row colors */ | |
| 2416 | - int nMaxEvents = 1; /* max number of events for | |
| 2417 | - all rows. */ | |
| 2418 | - stats_report_init_view(); | |
| 2419 | - stats_report_event_types_menu("byuser", NULL); | |
| 2420 | - db_prepare(&query, | |
| 2421 | - "SELECT user, " | |
| 2422 | - "COUNT(*) AS eventCount " | |
| 2423 | - "FROM v_reports " | |
| 2424 | - "GROUP BY user ORDER BY eventCount DESC"); | |
| 2425 | - @ <h1>Timeline Events | |
| 2426 | - @ (%s(stats_report_label_for_type())) by User</h1> | |
| 2427 | - @ <table class='statistics-report-table-events' border='0' | |
| 2428 | - @ cellpadding='2' cellspacing='0' id='statsTable'> | |
| 2429 | - @ <thead><tr> | |
| 2430 | - @ <th>User</th> | |
| 2431 | - @ <th>Events</th> | |
| 2432 | - @ <th width='90%%'><!-- relative commits graph --></th> | |
| 2433 | - @ </tr></thead><tbody> | |
| 2434 | - while( SQLITE_ROW == db_step(&query) ){ | |
| 2435 | - const int nCount = db_column_int(&query, 1); | |
| 2436 | - if(nCount>nMaxEvents){ | |
| 2437 | - nMaxEvents = nCount; | |
| 2438 | - } | |
| 2439 | - } | |
| 2440 | - db_reset(&query); | |
| 2441 | - while( SQLITE_ROW == db_step(&query) ){ | |
| 2442 | - const char *zUser = db_column_text(&query, 0); | |
| 2443 | - const int nCount = db_column_int(&query, 1); | |
| 2444 | - int nSize = nCount | |
| 2445 | - ? (int)(100 * nCount / nMaxEvents) | |
| 2446 | - : 0; | |
| 2447 | - if(!nCount) continue /* arguable! Possible? */; | |
| 2448 | - else if(!nSize) nSize = 1; | |
| 2449 | - rowClass = ++nRowNumber % 2; | |
| 2450 | - nEventTotal += nCount; | |
| 2451 | - @<tr class='row%d(rowClass)'> | |
| 2452 | - @ <td> | |
| 2453 | - @ <a href="?view=bymonth&user=%h(zUser)&type=%c((char)statsReportType)">%h(zUser)</a> | |
| 2454 | - @ </td><td data-sortkey='%08x(-nCount)'>%d(nCount)</td> | |
| 2455 | - @ <td> | |
| 2456 | - @ <div class='statistics-report-graph-line' | |
| 2457 | - @ style='width:%d(nSize)%%;'> </div> | |
| 2458 | - @ </td> | |
| 2459 | - @</tr> | |
| 2460 | - /* | |
| 2461 | - Potential improvement: calculate the min/max event counts and | |
| 2462 | - use percent-based graph bars. | |
| 2463 | - */ | |
| 2464 | - } | |
| 2465 | - @ </tbody></table> | |
| 2466 | - db_finalize(&query); | |
| 2467 | - output_table_sorting_javascript("statsTable","tkx",2); | |
| 2468 | -} | |
| 2469 | - | |
| 2470 | -/* | |
| 2471 | -** Implements the "byweekday" view for /reports. | |
| 2472 | -*/ | |
| 2473 | -static void stats_report_day_of_week(){ | |
| 2474 | - Stmt query = empty_Stmt; | |
| 2475 | - int nRowNumber = 0; /* current TR number */ | |
| 2476 | - int nEventTotal = 0; /* Total event count */ | |
| 2477 | - int rowClass = 0; /* counter for alternating | |
| 2478 | - row colors */ | |
| 2479 | - int nMaxEvents = 1; /* max number of events for | |
| 2480 | - all rows. */ | |
| 2481 | - static const char *const daysOfWeek[] = { | |
| 2482 | - "Monday", "Tuesday", "Wednesday", "Thursday", | |
| 2483 | - "Friday", "Saturday", "Sunday" | |
| 2484 | - }; | |
| 2485 | - | |
| 2486 | - stats_report_init_view(); | |
| 2487 | - stats_report_event_types_menu("byweekday", NULL); | |
| 2488 | - db_prepare(&query, | |
| 2489 | - "SELECT cast(mtime %% 7 AS INTEGER) dow, " | |
| 2490 | - "COUNT(*) AS eventCount " | |
| 2491 | - "FROM v_reports " | |
| 2492 | - "GROUP BY dow ORDER BY dow"); | |
| 2493 | - @ <h1>Timeline Events | |
| 2494 | - @ (%s(stats_report_label_for_type())) by Day of the Week</h1> | |
| 2495 | - @ <table class='statistics-report-table-events' border='0' | |
| 2496 | - @ cellpadding='2' cellspacing='0' id='statsTable'> | |
| 2497 | - @ <thead><tr> | |
| 2498 | - @ <th>DoW</th> | |
| 2499 | - @ <th>Day</th> | |
| 2500 | - @ <th>Events</th> | |
| 2501 | - @ <th width='90%%'><!-- relative commits graph --></th> | |
| 2502 | - @ </tr></thead><tbody> | |
| 2503 | - while( SQLITE_ROW == db_step(&query) ){ | |
| 2504 | - const int nCount = db_column_int(&query, 1); | |
| 2505 | - if(nCount>nMaxEvents){ | |
| 2506 | - nMaxEvents = nCount; | |
| 2507 | - } | |
| 2508 | - } | |
| 2509 | - db_reset(&query); | |
| 2510 | - while( SQLITE_ROW == db_step(&query) ){ | |
| 2511 | - const int dayNum =db_column_int(&query, 0); | |
| 2512 | - const int nCount = db_column_int(&query, 1); | |
| 2513 | - int nSize = nCount | |
| 2514 | - ? (int)(100 * nCount / nMaxEvents) | |
| 2515 | - : 0; | |
| 2516 | - if(!nCount) continue /* arguable! Possible? */; | |
| 2517 | - else if(!nSize) nSize = 1; | |
| 2518 | - rowClass = ++nRowNumber % 2; | |
| 2519 | - nEventTotal += nCount; | |
| 2520 | - @<tr class='row%d(rowClass)'> | |
| 2521 | - @ <td>%d(dayNum)</td> | |
| 2522 | - @ <td>%s(daysOfWeek[dayNum])</td> | |
| 2523 | - @ <td>%d(nCount)</td> | |
| 2524 | - @ <td> | |
| 2525 | - @ <div class='statistics-report-graph-line' | |
| 2526 | - @ style='width:%d(nSize)%%;'> </div> | |
| 2527 | - @ </td> | |
| 2528 | - @</tr> | |
| 2529 | - } | |
| 2530 | - @ </tbody></table> | |
| 2531 | - db_finalize(&query); | |
| 2532 | - output_table_sorting_javascript("statsTable","ntnx",1); | |
| 2533 | -} | |
| 2534 | - | |
| 2535 | - | |
| 2536 | -/* | |
| 2537 | -** Helper for stats_report_by_month_year(), which generates a list of | |
| 2538 | -** week numbers. zTimeframe should be either a timeframe in the form YYYY | |
| 2539 | -** or YYYY-MM. | |
| 2540 | -*/ | |
| 2541 | -static void stats_report_year_weeks(const char *zUserName){ | |
| 2542 | - const char *zYear = P("y"); | |
| 2543 | - int nYear = zYear ? strlen(zYear) : 0; | |
| 2544 | - int i = 0; | |
| 2545 | - Stmt qYears = empty_Stmt; | |
| 2546 | - char *zDefaultYear = NULL; | |
| 2547 | - Blob sql = empty_blob; | |
| 2548 | - int nMaxEvents = 1; /* max number of events for | |
| 2549 | - all rows. */ | |
| 2550 | - int iterations = 0; /* # of active time periods. */ | |
| 2551 | - stats_report_init_view(); | |
| 2552 | - if(4==nYear){ | |
| 2553 | - Blob urlParams = empty_blob; | |
| 2554 | - blob_appendf(&urlParams, "y=%T", zYear); | |
| 2555 | - stats_report_event_types_menu("byweek", blob_str(&urlParams)); | |
| 2556 | - blob_reset(&urlParams); | |
| 2557 | - }else{ | |
| 2558 | - stats_report_event_types_menu("byweek", NULL); | |
| 2559 | - } | |
| 2560 | - blob_append(&sql, | |
| 2561 | - "SELECT DISTINCT substr(date(mtime),1,4) AS y " | |
| 2562 | - "FROM v_reports WHERE 1 ", -1); | |
| 2563 | - if(zUserName&&*zUserName){ | |
| 2564 | - blob_append_sql(&sql,"AND user=%Q ", zUserName); | |
| 2565 | - } | |
| 2566 | - blob_append(&sql,"GROUP BY y ORDER BY y", -1); | |
| 2567 | - db_prepare(&qYears, "%s", blob_sql_text(&sql)); | |
| 2568 | - blob_reset(&sql); | |
| 2569 | - cgi_printf("Select year: "); | |
| 2570 | - while( SQLITE_ROW == db_step(&qYears) ){ | |
| 2571 | - const char *zT = db_column_text(&qYears, 0); | |
| 2572 | - if( i++ ){ | |
| 2573 | - cgi_printf(" "); | |
| 2574 | - } | |
| 2575 | - cgi_printf("<a href='?view=byweek&y=%s&type=%c", zT, | |
| 2576 | - (char)statsReportType); | |
| 2577 | - if(zUserName && *zUserName){ | |
| 2578 | - cgi_printf("&user=%t",zUserName); | |
| 2579 | - } | |
| 2580 | - cgi_printf("'>%s</a>",zT); | |
| 2581 | - } | |
| 2582 | - db_finalize(&qYears); | |
| 2583 | - cgi_printf("<br/>"); | |
| 2584 | - if(!zYear || !*zYear){ | |
| 2585 | - zDefaultYear = db_text("????", "SELECT strftime('%%Y')"); | |
| 2586 | - zYear = zDefaultYear; | |
| 2587 | - nYear = 4; | |
| 2588 | - } | |
| 2589 | - if(4 == nYear){ | |
| 2590 | - Stmt stWeek = empty_Stmt; | |
| 2591 | - int rowCount = 0; | |
| 2592 | - int total = 0; | |
| 2593 | - Blob header = empty_blob; | |
| 2594 | - blob_appendf(&header, "Timeline events (%s) for the calendar weeks " | |
| 2595 | - "of %h", stats_report_label_for_type(), | |
| 2596 | - zYear); | |
| 2597 | - blob_append_sql(&sql, | |
| 2598 | - "SELECT DISTINCT strftime('%%W',mtime) AS wk, " | |
| 2599 | - "count(*) AS n " | |
| 2600 | - "FROM v_reports " | |
| 2601 | - "WHERE %Q=substr(date(mtime),1,4) " | |
| 2602 | - "AND mtime < current_timestamp ", | |
| 2603 | - zYear); | |
| 2604 | - if(zUserName&&*zUserName){ | |
| 2605 | - blob_append_sql(&sql, " AND user=%Q ", zUserName); | |
| 2606 | - blob_appendf(&header," for user %h", zUserName); | |
| 2607 | - } | |
| 2608 | - blob_append_sql(&sql, "GROUP BY wk ORDER BY wk DESC"); | |
| 2609 | - cgi_printf("<h1>%h</h1>", blob_str(&header)); | |
| 2610 | - blob_reset(&header); | |
| 2611 | - cgi_printf("<table class='statistics-report-table-events' " | |
| 2612 | - "border='0' cellpadding='2' width='100%%' " | |
| 2613 | - "cellspacing='0' id='statsTable'>"); | |
| 2614 | - cgi_printf("<thead><tr>" | |
| 2615 | - "<th>Week</th>" | |
| 2616 | - "<th>Events</th>" | |
| 2617 | - "<th width='90%%'><!-- relative commits graph --></th>" | |
| 2618 | - "</tr></thead>" | |
| 2619 | - "<tbody>"); | |
| 2620 | - db_prepare(&stWeek, "%s", blob_sql_text(&sql)); | |
| 2621 | - blob_reset(&sql); | |
| 2622 | - while( SQLITE_ROW == db_step(&stWeek) ){ | |
| 2623 | - const int nCount = db_column_int(&stWeek, 1); | |
| 2624 | - if(nCount>nMaxEvents){ | |
| 2625 | - nMaxEvents = nCount; | |
| 2626 | - } | |
| 2627 | - ++iterations; | |
| 2628 | - } | |
| 2629 | - db_reset(&stWeek); | |
| 2630 | - while( SQLITE_ROW == db_step(&stWeek) ){ | |
| 2631 | - const char *zWeek = db_column_text(&stWeek,0); | |
| 2632 | - const int nCount = db_column_int(&stWeek,1); | |
| 2633 | - int nSize = nCount | |
| 2634 | - ? (int)(100 * nCount / nMaxEvents) | |
| 2635 | - : 0; | |
| 2636 | - if(!nSize) nSize = 1; | |
| 2637 | - total += nCount; | |
| 2638 | - cgi_printf("<tr class='row%d'>", ++rowCount % 2 ); | |
| 2639 | - cgi_printf("<td><a href='%s/timeline?yw=%t-%s&n=%d&y=%s", | |
| 2640 | - g.zTop, zYear, zWeek, nCount, | |
| 2641 | - statsReportTimelineYFlag); | |
| 2642 | - if(zUserName && *zUserName){ | |
| 2643 | - cgi_printf("&u=%t",zUserName); | |
| 2644 | - } | |
| 2645 | - cgi_printf("'>%s</a></td>",zWeek); | |
| 2646 | - | |
| 2647 | - cgi_printf("<td>%d</td>",nCount); | |
| 2648 | - cgi_printf("<td>"); | |
| 2649 | - if(nCount){ | |
| 2650 | - cgi_printf("<div class='statistics-report-graph-line'" | |
| 2651 | - "style='width:%d%%;'> </div>", | |
| 2652 | - nSize); | |
| 2653 | - } | |
| 2654 | - cgi_printf("</td></tr>"); | |
| 2655 | - } | |
| 2656 | - db_finalize(&stWeek); | |
| 2657 | - free(zDefaultYear); | |
| 2658 | - cgi_printf("</tbody></table>"); | |
| 2659 | - if(total){ | |
| 2660 | - int nAvg = iterations ? (total/iterations) : 0; | |
| 2661 | - cgi_printf("<br><div>Total events: %d<br>" | |
| 2662 | - "Average per active week: %d</div>", | |
| 2663 | - total, nAvg); | |
| 2664 | - } | |
| 2665 | - output_table_sorting_javascript("statsTable","tnx",-1); | |
| 2666 | - } | |
| 2667 | -} | |
| 2668 | - | |
| 2669 | -/* | |
| 2670 | -** WEBPAGE: reports | |
| 2671 | -** | |
| 2672 | -** Shows activity reports for the repository. | |
| 2673 | -** | |
| 2674 | -** Query Parameters: | |
| 2675 | -** | |
| 2676 | -** view=REPORT_NAME Valid values: bymonth, byyear, byuser | |
| 2677 | -** user=NAME Restricts statistics to the given user | |
| 2678 | -** type=TYPE Restricts the report to a specific event type: | |
| 2679 | -** ci (checkin), w (wiki), t (ticket), g (tag) | |
| 2680 | -** Defaulting to all event types. | |
| 2681 | -** | |
| 2682 | -** The view-specific query parameters include: | |
| 2683 | -** | |
| 2684 | -** view=byweek: | |
| 2685 | -** | |
| 2686 | -** y=YYYY The year to report (default is the server's | |
| 2687 | -** current year). | |
| 2688 | -*/ | |
| 2689 | -void stats_report_page(){ | |
| 2690 | - HQuery url; /* URL for various branch links */ | |
| 2691 | - const char *zView = P("view"); /* Which view/report to show. */ | |
| 2692 | - const char *zUserName = P("user"); | |
| 2693 | - | |
| 2694 | - login_check_credentials(); | |
| 2695 | - if( !g.perm.Read ){ login_needed(); return; } | |
| 2696 | - if(!zUserName) zUserName = P("u"); | |
| 2697 | - url_initialize(&url, "reports"); | |
| 2698 | - if(zUserName && *zUserName){ | |
| 2699 | - url_add_parameter(&url,"user", zUserName); | |
| 2700 | - timeline_submenu(&url, "(Remove User Flag)", "view", zView, "user"); | |
| 2701 | - } | |
| 2702 | - timeline_submenu(&url, "By Year", "view", "byyear", 0); | |
| 2703 | - timeline_submenu(&url, "By Month", "view", "bymonth", 0); | |
| 2704 | - timeline_submenu(&url, "By Week", "view", "byweek", 0); | |
| 2705 | - timeline_submenu(&url, "By Weekday", "view", "byweekday", 0); | |
| 2706 | - timeline_submenu(&url, "By User", "view", "byuser", "user"); | |
| 2707 | - url_reset(&url); | |
| 2708 | - style_header("Activity Reports"); | |
| 2709 | - if(0==fossil_strcmp(zView,"byyear")){ | |
| 2710 | - stats_report_by_month_year(0, 0, zUserName); | |
| 2711 | - }else if(0==fossil_strcmp(zView,"bymonth")){ | |
| 2712 | - stats_report_by_month_year(1, 0, zUserName); | |
| 2713 | - }else if(0==fossil_strcmp(zView,"byweek")){ | |
| 2714 | - stats_report_year_weeks(zUserName); | |
| 2715 | - }else if(0==fossil_strcmp(zView,"byuser")){ | |
| 2716 | - stats_report_by_user(); | |
| 2717 | - }else if(0==fossil_strcmp(zView,"byweekday")){ | |
| 2718 | - stats_report_day_of_week(); | |
| 2719 | - }else{ | |
| 2720 | - @ <h1>Select a report to show:</h1> | |
| 2721 | - @ <ul> | |
| 2722 | - @ <li><a href='?view=byyear'>Events by year</a></li> | |
| 2723 | - @ <li><a href='?view=bymonth'>Events by month</a></li> | |
| 2724 | - @ <li><a href='?view=byweek'>Events by calendar week</a></li> | |
| 2725 | - @ <li><a href='?view=byweekday'>Events by day of the week</a></li> | |
| 2726 | - @ <li><a href='?view=byuser'>Events by user</a></li> | |
| 2727 | - @ </ul> | |
| 2728 | - } | |
| 2729 | - | |
| 2730 | 2049 | style_footer(); |
| 2731 | 2050 | } |
| 2732 | 2051 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -360,20 +360,20 @@ | |
| 360 | } |
| 361 | } |
| 362 | } |
| 363 | if( zType[0]=='c' && (pGraph || (tmFlags & TIMELINE_BRCOLOR)!=0) ){ |
| 364 | int nParent = 0; |
| 365 | int aParent[32]; |
| 366 | int gidx; |
| 367 | static Stmt qparent; |
| 368 | db_static_prepare(&qparent, |
| 369 | "SELECT pid FROM plink" |
| 370 | " WHERE cid=:rid AND pid NOT IN phantom" |
| 371 | " ORDER BY isprim DESC /*sort*/" |
| 372 | ); |
| 373 | db_bind_int(&qparent, ":rid", rid); |
| 374 | while( db_step(&qparent)==SQLITE_ROW && nParent<32 ){ |
| 375 | aParent[nParent++] = db_column_int(&qparent, 0); |
| 376 | } |
| 377 | db_reset(&qparent); |
| 378 | gidx = graph_add_row(pGraph, rid, nParent, aParent, zBr, zBgClr, |
| 379 | zUuid, isLeaf); |
| @@ -1556,11 +1556,11 @@ | |
| 1556 | } |
| 1557 | } |
| 1558 | if( P("showsql") ){ |
| 1559 | @ <blockquote>%h(blob_sql_text(&sql))</blockquote> |
| 1560 | } |
| 1561 | if( P("showrid") ) tmFlags |= TIMELINE_SHOWRID; |
| 1562 | blob_zero(&sql); |
| 1563 | db_prepare(&q, "SELECT * FROM timeline ORDER BY sortby DESC /*scan*/"); |
| 1564 | @ <h2>%b(&desc)</h2> |
| 1565 | blob_reset(&desc); |
| 1566 | www_print_timeline(&q, tmFlags, zThisUser, zThisTag, 0); |
| @@ -2044,688 +2044,7 @@ | |
| 2044 | const char *zUuid = db_column_text(&q, 0); |
| 2045 | @ <li> |
| 2046 | @ <a href="%s(g.zTop)/timeline?p=%s(zUuid)&d=%s(zUuid)&unhide">%S(zUuid)</a> |
| 2047 | } |
| 2048 | db_finalize(&q); |
| 2049 | style_footer(); |
| 2050 | } |
| 2051 | |
| 2052 | |
| 2053 | /* |
| 2054 | ** Used by stats_report_xxxxx() to remember which type of events |
| 2055 | ** to show. Populated by stats_report_init_view() and holds the |
| 2056 | ** return value of that function. |
| 2057 | */ |
| 2058 | static int statsReportType = 0; |
| 2059 | |
| 2060 | /* |
| 2061 | ** Set by stats_report_init_view() to one of the y=XXXX values |
| 2062 | ** accepted by /timeline?y=XXXX. |
| 2063 | */ |
| 2064 | static const char *statsReportTimelineYFlag = NULL; |
| 2065 | |
| 2066 | /* |
| 2067 | ** Creates a TEMP VIEW named v_reports which is a wrapper around the |
| 2068 | ** EVENT table filtered on event.type. It looks for the request |
| 2069 | ** parameter 'type' (reminder: we "should" use 'y' for consistency |
| 2070 | ** with /timeline, but /reports uses 'y' for the year) and expects it |
| 2071 | ** to contain one of the conventional values from event.type or the |
| 2072 | ** value "all", which is treated as equivalent to "*". By default (if |
| 2073 | ** no 'y' is specified), "*" is assumed (that is also the default for |
| 2074 | ** invalid/unknown filter values). That 'y' filter is the one used for |
| 2075 | ** the event list. Note that a filter of "*" or "all" is equivalent to |
| 2076 | ** querying against the full event table. The view, however, adds an |
| 2077 | ** abstraction level to simplify the implementation code for the |
| 2078 | ** various /reports pages. |
| 2079 | ** |
| 2080 | ** Returns one of: 'c', 'w', 'g', 't', 'e', representing the type of |
| 2081 | ** filter it applies, or '*' if no filter is applied (i.e. if "all" is |
| 2082 | ** used). |
| 2083 | */ |
| 2084 | static int stats_report_init_view(){ |
| 2085 | const char *zType = PD("type","*"); /* analog to /timeline?y=... */ |
| 2086 | const char *zRealType = NULL; /* normalized form of zType */ |
| 2087 | int rc = 0; /* result code */ |
| 2088 | assert( !statsReportType && "Must not be called more than once." ); |
| 2089 | switch( (zType && *zType) ? *zType : 0 ){ |
| 2090 | case 'c': |
| 2091 | case 'C': |
| 2092 | zRealType = "ci"; |
| 2093 | rc = *zRealType; |
| 2094 | break; |
| 2095 | case 'e': |
| 2096 | case 'E': |
| 2097 | zRealType = "e"; |
| 2098 | rc = *zRealType; |
| 2099 | break; |
| 2100 | case 'g': |
| 2101 | case 'G': |
| 2102 | zRealType = "g"; |
| 2103 | rc = *zRealType; |
| 2104 | break; |
| 2105 | case 't': |
| 2106 | case 'T': |
| 2107 | zRealType = "t"; |
| 2108 | rc = *zRealType; |
| 2109 | break; |
| 2110 | case 'w': |
| 2111 | case 'W': |
| 2112 | zRealType = "w"; |
| 2113 | rc = *zRealType; |
| 2114 | break; |
| 2115 | default: |
| 2116 | rc = '*'; |
| 2117 | break; |
| 2118 | } |
| 2119 | assert(0 != rc); |
| 2120 | if(zRealType){ |
| 2121 | statsReportTimelineYFlag = zRealType; |
| 2122 | db_multi_exec("CREATE TEMP VIEW v_reports AS " |
| 2123 | "SELECT * FROM event WHERE type GLOB %Q", |
| 2124 | zRealType); |
| 2125 | }else{ |
| 2126 | statsReportTimelineYFlag = "a"; |
| 2127 | db_multi_exec("CREATE TEMP VIEW v_reports AS " |
| 2128 | "SELECT * FROM event"); |
| 2129 | } |
| 2130 | return statsReportType = rc; |
| 2131 | } |
| 2132 | |
| 2133 | /* |
| 2134 | ** Returns a string suitable (for a given value of suitable) for |
| 2135 | ** use in a label with the header of the /reports pages, dependent |
| 2136 | ** on the 'type' flag. See stats_report_init_view(). |
| 2137 | ** The returned bytes are static. |
| 2138 | */ |
| 2139 | static const char *stats_report_label_for_type(){ |
| 2140 | assert( statsReportType && "Must call stats_report_init_view() first." ); |
| 2141 | switch( statsReportType ){ |
| 2142 | case 'c': |
| 2143 | return "checkins"; |
| 2144 | case 'e': |
| 2145 | return "events"; |
| 2146 | case 'w': |
| 2147 | return "wiki changes"; |
| 2148 | case 't': |
| 2149 | return "ticket changes"; |
| 2150 | case 'g': |
| 2151 | return "tag changes"; |
| 2152 | default: |
| 2153 | return "all types"; |
| 2154 | } |
| 2155 | } |
| 2156 | |
| 2157 | /* |
| 2158 | ** A helper for the /reports family of pages which prints out a menu |
| 2159 | ** of links for the various type=XXX flags. zCurrentViewName must be |
| 2160 | ** the name/value of the 'view' parameter which is in effect at the |
| 2161 | ** time this is called. e.g. if called from the 'byuser' view then |
| 2162 | ** zCurrentViewName must be "byuser". Any URL parameters which need to |
| 2163 | ** be added to the generated URLs should be passed in zParam. The |
| 2164 | ** caller is expected to have already encoded any zParam in the %T or |
| 2165 | ** %t encoding. */ |
| 2166 | static void stats_report_event_types_menu(const char *zCurrentViewName, |
| 2167 | const char *zParam){ |
| 2168 | char *zTop; |
| 2169 | if(zParam && !*zParam){ |
| 2170 | zParam = NULL; |
| 2171 | } |
| 2172 | zTop = mprintf("%s/reports?view=%s%s%s", g.zTop, zCurrentViewName, |
| 2173 | zParam ? "&" : "", zParam); |
| 2174 | cgi_printf("<div>"); |
| 2175 | cgi_printf("<span>Types:</span> "); |
| 2176 | if('*' == statsReportType){ |
| 2177 | cgi_printf(" <strong>all</strong>", zTop); |
| 2178 | }else{ |
| 2179 | cgi_printf(" <a href='%s'>all</a>", zTop); |
| 2180 | } |
| 2181 | if('c' == statsReportType){ |
| 2182 | cgi_printf(" <strong>checkins</strong>", zTop); |
| 2183 | }else{ |
| 2184 | cgi_printf(" <a href='%s&type=ci'>checkins</a>", zTop); |
| 2185 | } |
| 2186 | if('e' == statsReportType){ |
| 2187 | cgi_printf(" <strong>events</strong>", zTop); |
| 2188 | }else{ |
| 2189 | cgi_printf(" <a href='%s&type=e'>events</a>", zTop); |
| 2190 | } |
| 2191 | if( 't' == statsReportType ){ |
| 2192 | cgi_printf(" <strong>tickets</strong>", zTop); |
| 2193 | }else{ |
| 2194 | cgi_printf(" <a href='%s&type=t'>tickets</a>", zTop); |
| 2195 | } |
| 2196 | if( 'g' == statsReportType ){ |
| 2197 | cgi_printf(" <strong>tags</strong>", zTop); |
| 2198 | }else{ |
| 2199 | cgi_printf(" <a href='%s&type=g'>tags</a>", zTop); |
| 2200 | } |
| 2201 | if( 'w' == statsReportType ){ |
| 2202 | cgi_printf(" <strong>wiki</strong>", zTop); |
| 2203 | }else{ |
| 2204 | cgi_printf(" <a href='%s&type=w'>wiki</a>", zTop); |
| 2205 | } |
| 2206 | fossil_free(zTop); |
| 2207 | cgi_printf("</div>"); |
| 2208 | } |
| 2209 | |
| 2210 | |
| 2211 | /* |
| 2212 | ** Helper for stats_report_by_month_year(), which generates a list of |
| 2213 | ** week numbers. zTimeframe should be either a timeframe in the form YYYY |
| 2214 | ** or YYYY-MM. |
| 2215 | */ |
| 2216 | static void stats_report_output_week_links(const char *zTimeframe){ |
| 2217 | Stmt stWeek = empty_Stmt; |
| 2218 | char yearPart[5] = {0,0,0,0,0}; |
| 2219 | memcpy(yearPart, zTimeframe, 4); |
| 2220 | db_prepare(&stWeek, |
| 2221 | "SELECT DISTINCT strftime('%%W',mtime) AS wk, " |
| 2222 | "count(*) AS n, " |
| 2223 | "substr(date(mtime),1,%d) AS ym " |
| 2224 | "FROM v_reports " |
| 2225 | "WHERE ym=%Q AND mtime < current_timestamp " |
| 2226 | "GROUP BY wk ORDER BY wk", |
| 2227 | strlen(zTimeframe), |
| 2228 | zTimeframe); |
| 2229 | while( SQLITE_ROW == db_step(&stWeek) ){ |
| 2230 | const char *zWeek = db_column_text(&stWeek,0); |
| 2231 | const int nCount = db_column_int(&stWeek,1); |
| 2232 | cgi_printf("<a href='%s/timeline?" |
| 2233 | "yw=%t-%t&n=%d&y=%s'>%s</a>", |
| 2234 | g.zTop, yearPart, zWeek, |
| 2235 | nCount, statsReportTimelineYFlag, zWeek); |
| 2236 | } |
| 2237 | db_finalize(&stWeek); |
| 2238 | } |
| 2239 | |
| 2240 | /* |
| 2241 | ** Implements the "byyear" and "bymonth" reports for /reports. |
| 2242 | ** If includeMonth is true then it generates the "bymonth" report, |
| 2243 | ** else the "byyear" report. If zUserName is not NULL and not empty |
| 2244 | ** then the report is restricted to events created by the named user |
| 2245 | ** account. |
| 2246 | */ |
| 2247 | static void stats_report_by_month_year(char includeMonth, |
| 2248 | char includeWeeks, |
| 2249 | const char *zUserName){ |
| 2250 | Stmt query = empty_Stmt; |
| 2251 | int nRowNumber = 0; /* current TR number */ |
| 2252 | int nEventTotal = 0; /* Total event count */ |
| 2253 | int rowClass = 0; /* counter for alternating |
| 2254 | row colors */ |
| 2255 | Blob sql = empty_blob; /* SQL */ |
| 2256 | const char *zTimeLabel = includeMonth ? "Year/Month" : "Year"; |
| 2257 | char zPrevYear[5] = {0}; /* For keeping track of when |
| 2258 | we change years while looping */ |
| 2259 | int nEventsPerYear = 0; /* Total event count for the |
| 2260 | current year */ |
| 2261 | char showYearTotal = 0; /* Flag telling us when to show |
| 2262 | the per-year event totals */ |
| 2263 | Blob header = empty_blob; /* Page header text */ |
| 2264 | int nMaxEvents = 1; /* for calculating length of graph |
| 2265 | bars. */ |
| 2266 | int iterations = 0; /* number of weeks/months we iterate |
| 2267 | over */ |
| 2268 | stats_report_init_view(); |
| 2269 | stats_report_event_types_menu( includeMonth ? "bymonth" : "byyear", NULL ); |
| 2270 | blob_appendf(&header, "Timeline Events (%s) by year%s", |
| 2271 | stats_report_label_for_type(), |
| 2272 | (includeMonth ? "/month" : "")); |
| 2273 | blob_append_sql(&sql, |
| 2274 | "SELECT substr(date(mtime),1,%d) AS timeframe, " |
| 2275 | "count(*) AS eventCount " |
| 2276 | "FROM v_reports ", |
| 2277 | includeMonth ? 7 : 4); |
| 2278 | if(zUserName&&*zUserName){ |
| 2279 | blob_append_sql(&sql, " WHERE user=%Q ", zUserName); |
| 2280 | blob_appendf(&header," for user %q", zUserName); |
| 2281 | } |
| 2282 | blob_append(&sql, |
| 2283 | " GROUP BY timeframe" |
| 2284 | " ORDER BY timeframe DESC", |
| 2285 | -1); |
| 2286 | db_prepare(&query, "%s", blob_sql_text(&sql)); |
| 2287 | blob_reset(&sql); |
| 2288 | @ <h1>%b(&header)</h1> |
| 2289 | @ <table class='statistics-report-table-events' border='0' cellpadding='2' |
| 2290 | @ cellspacing='0' id='statsTable'> |
| 2291 | @ <thead> |
| 2292 | @ <th>%s(zTimeLabel)</th> |
| 2293 | @ <th>Events</th> |
| 2294 | @ <th width='90%%'><!-- relative commits graph --></th> |
| 2295 | @ </thead><tbody> |
| 2296 | blob_reset(&header); |
| 2297 | /* |
| 2298 | Run the query twice. The first time we calculate the maximum |
| 2299 | number of events for a given row. Maybe someone with better SQL |
| 2300 | Fu can re-implement this with a single query. |
| 2301 | */ |
| 2302 | while( SQLITE_ROW == db_step(&query) ){ |
| 2303 | const int nCount = db_column_int(&query, 1); |
| 2304 | if(nCount>nMaxEvents){ |
| 2305 | nMaxEvents = nCount; |
| 2306 | } |
| 2307 | ++iterations; |
| 2308 | } |
| 2309 | db_reset(&query); |
| 2310 | while( SQLITE_ROW == db_step(&query) ){ |
| 2311 | const char *zTimeframe = db_column_text(&query, 0); |
| 2312 | const int nCount = db_column_int(&query, 1); |
| 2313 | int nSize = nCount |
| 2314 | ? (int)(100 * nCount / nMaxEvents) |
| 2315 | : 1; |
| 2316 | showYearTotal = 0; |
| 2317 | if(!nSize) nSize = 1; |
| 2318 | if(includeMonth){ |
| 2319 | /* For Month/year view, add a separator for each distinct year. */ |
| 2320 | if(!*zPrevYear || |
| 2321 | (0!=fossil_strncmp(zPrevYear,zTimeframe,4))){ |
| 2322 | showYearTotal = *zPrevYear; |
| 2323 | if(showYearTotal){ |
| 2324 | rowClass = ++nRowNumber % 2; |
| 2325 | @ <tr class='row%d(rowClass)'> |
| 2326 | @ <td></td> |
| 2327 | @ <td colspan='2'>Yearly total: %d(nEventsPerYear)</td> |
| 2328 | @</tr> |
| 2329 | } |
| 2330 | nEventsPerYear = 0; |
| 2331 | memcpy(zPrevYear,zTimeframe,4); |
| 2332 | rowClass = ++nRowNumber % 2; |
| 2333 | @ <tr class='row%d(rowClass)'> |
| 2334 | @ <th colspan='3' class='statistics-report-row-year'>%s(zPrevYear)</th> |
| 2335 | @ </tr> |
| 2336 | } |
| 2337 | } |
| 2338 | rowClass = ++nRowNumber % 2; |
| 2339 | nEventTotal += nCount; |
| 2340 | nEventsPerYear += nCount; |
| 2341 | @<tr class='row%d(rowClass)'> |
| 2342 | @ <td> |
| 2343 | if(includeMonth){ |
| 2344 | cgi_printf("<a href='%s/timeline?" |
| 2345 | "ym=%t&n=%d&y=%s", |
| 2346 | g.zTop, zTimeframe, nCount, |
| 2347 | statsReportTimelineYFlag ); |
| 2348 | /* Reminder: n=nCount is not actually correct for bymonth unless |
| 2349 | that was the only user who caused events. |
| 2350 | */ |
| 2351 | if( zUserName && *zUserName ){ |
| 2352 | cgi_printf("&u=%t", zUserName); |
| 2353 | } |
| 2354 | cgi_printf("' target='_new'>%s</a>",zTimeframe); |
| 2355 | }else { |
| 2356 | cgi_printf("<a href='?view=byweek&y=%s&type=%c", |
| 2357 | zTimeframe, (char)statsReportType); |
| 2358 | if(zUserName && *zUserName){ |
| 2359 | cgi_printf("&u=%t", zUserName); |
| 2360 | } |
| 2361 | cgi_printf("'>%s</a>", zTimeframe); |
| 2362 | } |
| 2363 | @ </td><td>%d(nCount)</td> |
| 2364 | @ <td> |
| 2365 | @ <div class='statistics-report-graph-line' |
| 2366 | @ style='width:%d(nSize)%%;'> </div> |
| 2367 | @ </td> |
| 2368 | @</tr> |
| 2369 | if(includeWeeks){ |
| 2370 | /* This part works fine for months but it terribly slow (4.5s on my PC), |
| 2371 | so it's only shown for by-year for now. Suggestions/patches for |
| 2372 | a better/faster layout are welcomed. */ |
| 2373 | @ <tr class='row%d(rowClass)'> |
| 2374 | @ <td colspan='2' class='statistics-report-week-number-label'>Week #:</td> |
| 2375 | @ <td class='statistics-report-week-of-year-list'> |
| 2376 | stats_report_output_week_links(zTimeframe); |
| 2377 | @ </td></tr> |
| 2378 | } |
| 2379 | |
| 2380 | /* |
| 2381 | Potential improvement: calculate the min/max event counts and |
| 2382 | use percent-based graph bars. |
| 2383 | */ |
| 2384 | } |
| 2385 | db_finalize(&query); |
| 2386 | if(includeMonth && !showYearTotal && *zPrevYear){ |
| 2387 | /* Add final year total separator. */ |
| 2388 | rowClass = ++nRowNumber % 2; |
| 2389 | @ <tr class='row%d(rowClass)'> |
| 2390 | @ <td></td> |
| 2391 | @ <td colspan='2'>Yearly total: %d(nEventsPerYear)</td> |
| 2392 | @</tr> |
| 2393 | } |
| 2394 | @ </tbody></table> |
| 2395 | if(nEventTotal){ |
| 2396 | const char *zAvgLabel = includeMonth ? "month" : "year"; |
| 2397 | int nAvg = iterations ? (nEventTotal/iterations) : 0; |
| 2398 | @ <br><div>Total events: %d(nEventTotal) |
| 2399 | @ <br>Average per active %s(zAvgLabel): %d(nAvg) |
| 2400 | @ </div> |
| 2401 | } |
| 2402 | if( !includeMonth ){ |
| 2403 | output_table_sorting_javascript("statsTable","tnx",-1); |
| 2404 | } |
| 2405 | } |
| 2406 | |
| 2407 | /* |
| 2408 | ** Implements the "byuser" view for /reports. |
| 2409 | */ |
| 2410 | static void stats_report_by_user(){ |
| 2411 | Stmt query = empty_Stmt; |
| 2412 | int nRowNumber = 0; /* current TR number */ |
| 2413 | int nEventTotal = 0; /* Total event count */ |
| 2414 | int rowClass = 0; /* counter for alternating |
| 2415 | row colors */ |
| 2416 | int nMaxEvents = 1; /* max number of events for |
| 2417 | all rows. */ |
| 2418 | stats_report_init_view(); |
| 2419 | stats_report_event_types_menu("byuser", NULL); |
| 2420 | db_prepare(&query, |
| 2421 | "SELECT user, " |
| 2422 | "COUNT(*) AS eventCount " |
| 2423 | "FROM v_reports " |
| 2424 | "GROUP BY user ORDER BY eventCount DESC"); |
| 2425 | @ <h1>Timeline Events |
| 2426 | @ (%s(stats_report_label_for_type())) by User</h1> |
| 2427 | @ <table class='statistics-report-table-events' border='0' |
| 2428 | @ cellpadding='2' cellspacing='0' id='statsTable'> |
| 2429 | @ <thead><tr> |
| 2430 | @ <th>User</th> |
| 2431 | @ <th>Events</th> |
| 2432 | @ <th width='90%%'><!-- relative commits graph --></th> |
| 2433 | @ </tr></thead><tbody> |
| 2434 | while( SQLITE_ROW == db_step(&query) ){ |
| 2435 | const int nCount = db_column_int(&query, 1); |
| 2436 | if(nCount>nMaxEvents){ |
| 2437 | nMaxEvents = nCount; |
| 2438 | } |
| 2439 | } |
| 2440 | db_reset(&query); |
| 2441 | while( SQLITE_ROW == db_step(&query) ){ |
| 2442 | const char *zUser = db_column_text(&query, 0); |
| 2443 | const int nCount = db_column_int(&query, 1); |
| 2444 | int nSize = nCount |
| 2445 | ? (int)(100 * nCount / nMaxEvents) |
| 2446 | : 0; |
| 2447 | if(!nCount) continue /* arguable! Possible? */; |
| 2448 | else if(!nSize) nSize = 1; |
| 2449 | rowClass = ++nRowNumber % 2; |
| 2450 | nEventTotal += nCount; |
| 2451 | @<tr class='row%d(rowClass)'> |
| 2452 | @ <td> |
| 2453 | @ <a href="?view=bymonth&user=%h(zUser)&type=%c((char)statsReportType)">%h(zUser)</a> |
| 2454 | @ </td><td data-sortkey='%08x(-nCount)'>%d(nCount)</td> |
| 2455 | @ <td> |
| 2456 | @ <div class='statistics-report-graph-line' |
| 2457 | @ style='width:%d(nSize)%%;'> </div> |
| 2458 | @ </td> |
| 2459 | @</tr> |
| 2460 | /* |
| 2461 | Potential improvement: calculate the min/max event counts and |
| 2462 | use percent-based graph bars. |
| 2463 | */ |
| 2464 | } |
| 2465 | @ </tbody></table> |
| 2466 | db_finalize(&query); |
| 2467 | output_table_sorting_javascript("statsTable","tkx",2); |
| 2468 | } |
| 2469 | |
| 2470 | /* |
| 2471 | ** Implements the "byweekday" view for /reports. |
| 2472 | */ |
| 2473 | static void stats_report_day_of_week(){ |
| 2474 | Stmt query = empty_Stmt; |
| 2475 | int nRowNumber = 0; /* current TR number */ |
| 2476 | int nEventTotal = 0; /* Total event count */ |
| 2477 | int rowClass = 0; /* counter for alternating |
| 2478 | row colors */ |
| 2479 | int nMaxEvents = 1; /* max number of events for |
| 2480 | all rows. */ |
| 2481 | static const char *const daysOfWeek[] = { |
| 2482 | "Monday", "Tuesday", "Wednesday", "Thursday", |
| 2483 | "Friday", "Saturday", "Sunday" |
| 2484 | }; |
| 2485 | |
| 2486 | stats_report_init_view(); |
| 2487 | stats_report_event_types_menu("byweekday", NULL); |
| 2488 | db_prepare(&query, |
| 2489 | "SELECT cast(mtime %% 7 AS INTEGER) dow, " |
| 2490 | "COUNT(*) AS eventCount " |
| 2491 | "FROM v_reports " |
| 2492 | "GROUP BY dow ORDER BY dow"); |
| 2493 | @ <h1>Timeline Events |
| 2494 | @ (%s(stats_report_label_for_type())) by Day of the Week</h1> |
| 2495 | @ <table class='statistics-report-table-events' border='0' |
| 2496 | @ cellpadding='2' cellspacing='0' id='statsTable'> |
| 2497 | @ <thead><tr> |
| 2498 | @ <th>DoW</th> |
| 2499 | @ <th>Day</th> |
| 2500 | @ <th>Events</th> |
| 2501 | @ <th width='90%%'><!-- relative commits graph --></th> |
| 2502 | @ </tr></thead><tbody> |
| 2503 | while( SQLITE_ROW == db_step(&query) ){ |
| 2504 | const int nCount = db_column_int(&query, 1); |
| 2505 | if(nCount>nMaxEvents){ |
| 2506 | nMaxEvents = nCount; |
| 2507 | } |
| 2508 | } |
| 2509 | db_reset(&query); |
| 2510 | while( SQLITE_ROW == db_step(&query) ){ |
| 2511 | const int dayNum =db_column_int(&query, 0); |
| 2512 | const int nCount = db_column_int(&query, 1); |
| 2513 | int nSize = nCount |
| 2514 | ? (int)(100 * nCount / nMaxEvents) |
| 2515 | : 0; |
| 2516 | if(!nCount) continue /* arguable! Possible? */; |
| 2517 | else if(!nSize) nSize = 1; |
| 2518 | rowClass = ++nRowNumber % 2; |
| 2519 | nEventTotal += nCount; |
| 2520 | @<tr class='row%d(rowClass)'> |
| 2521 | @ <td>%d(dayNum)</td> |
| 2522 | @ <td>%s(daysOfWeek[dayNum])</td> |
| 2523 | @ <td>%d(nCount)</td> |
| 2524 | @ <td> |
| 2525 | @ <div class='statistics-report-graph-line' |
| 2526 | @ style='width:%d(nSize)%%;'> </div> |
| 2527 | @ </td> |
| 2528 | @</tr> |
| 2529 | } |
| 2530 | @ </tbody></table> |
| 2531 | db_finalize(&query); |
| 2532 | output_table_sorting_javascript("statsTable","ntnx",1); |
| 2533 | } |
| 2534 | |
| 2535 | |
| 2536 | /* |
| 2537 | ** Helper for stats_report_by_month_year(), which generates a list of |
| 2538 | ** week numbers. zTimeframe should be either a timeframe in the form YYYY |
| 2539 | ** or YYYY-MM. |
| 2540 | */ |
| 2541 | static void stats_report_year_weeks(const char *zUserName){ |
| 2542 | const char *zYear = P("y"); |
| 2543 | int nYear = zYear ? strlen(zYear) : 0; |
| 2544 | int i = 0; |
| 2545 | Stmt qYears = empty_Stmt; |
| 2546 | char *zDefaultYear = NULL; |
| 2547 | Blob sql = empty_blob; |
| 2548 | int nMaxEvents = 1; /* max number of events for |
| 2549 | all rows. */ |
| 2550 | int iterations = 0; /* # of active time periods. */ |
| 2551 | stats_report_init_view(); |
| 2552 | if(4==nYear){ |
| 2553 | Blob urlParams = empty_blob; |
| 2554 | blob_appendf(&urlParams, "y=%T", zYear); |
| 2555 | stats_report_event_types_menu("byweek", blob_str(&urlParams)); |
| 2556 | blob_reset(&urlParams); |
| 2557 | }else{ |
| 2558 | stats_report_event_types_menu("byweek", NULL); |
| 2559 | } |
| 2560 | blob_append(&sql, |
| 2561 | "SELECT DISTINCT substr(date(mtime),1,4) AS y " |
| 2562 | "FROM v_reports WHERE 1 ", -1); |
| 2563 | if(zUserName&&*zUserName){ |
| 2564 | blob_append_sql(&sql,"AND user=%Q ", zUserName); |
| 2565 | } |
| 2566 | blob_append(&sql,"GROUP BY y ORDER BY y", -1); |
| 2567 | db_prepare(&qYears, "%s", blob_sql_text(&sql)); |
| 2568 | blob_reset(&sql); |
| 2569 | cgi_printf("Select year: "); |
| 2570 | while( SQLITE_ROW == db_step(&qYears) ){ |
| 2571 | const char *zT = db_column_text(&qYears, 0); |
| 2572 | if( i++ ){ |
| 2573 | cgi_printf(" "); |
| 2574 | } |
| 2575 | cgi_printf("<a href='?view=byweek&y=%s&type=%c", zT, |
| 2576 | (char)statsReportType); |
| 2577 | if(zUserName && *zUserName){ |
| 2578 | cgi_printf("&user=%t",zUserName); |
| 2579 | } |
| 2580 | cgi_printf("'>%s</a>",zT); |
| 2581 | } |
| 2582 | db_finalize(&qYears); |
| 2583 | cgi_printf("<br/>"); |
| 2584 | if(!zYear || !*zYear){ |
| 2585 | zDefaultYear = db_text("????", "SELECT strftime('%%Y')"); |
| 2586 | zYear = zDefaultYear; |
| 2587 | nYear = 4; |
| 2588 | } |
| 2589 | if(4 == nYear){ |
| 2590 | Stmt stWeek = empty_Stmt; |
| 2591 | int rowCount = 0; |
| 2592 | int total = 0; |
| 2593 | Blob header = empty_blob; |
| 2594 | blob_appendf(&header, "Timeline events (%s) for the calendar weeks " |
| 2595 | "of %h", stats_report_label_for_type(), |
| 2596 | zYear); |
| 2597 | blob_append_sql(&sql, |
| 2598 | "SELECT DISTINCT strftime('%%W',mtime) AS wk, " |
| 2599 | "count(*) AS n " |
| 2600 | "FROM v_reports " |
| 2601 | "WHERE %Q=substr(date(mtime),1,4) " |
| 2602 | "AND mtime < current_timestamp ", |
| 2603 | zYear); |
| 2604 | if(zUserName&&*zUserName){ |
| 2605 | blob_append_sql(&sql, " AND user=%Q ", zUserName); |
| 2606 | blob_appendf(&header," for user %h", zUserName); |
| 2607 | } |
| 2608 | blob_append_sql(&sql, "GROUP BY wk ORDER BY wk DESC"); |
| 2609 | cgi_printf("<h1>%h</h1>", blob_str(&header)); |
| 2610 | blob_reset(&header); |
| 2611 | cgi_printf("<table class='statistics-report-table-events' " |
| 2612 | "border='0' cellpadding='2' width='100%%' " |
| 2613 | "cellspacing='0' id='statsTable'>"); |
| 2614 | cgi_printf("<thead><tr>" |
| 2615 | "<th>Week</th>" |
| 2616 | "<th>Events</th>" |
| 2617 | "<th width='90%%'><!-- relative commits graph --></th>" |
| 2618 | "</tr></thead>" |
| 2619 | "<tbody>"); |
| 2620 | db_prepare(&stWeek, "%s", blob_sql_text(&sql)); |
| 2621 | blob_reset(&sql); |
| 2622 | while( SQLITE_ROW == db_step(&stWeek) ){ |
| 2623 | const int nCount = db_column_int(&stWeek, 1); |
| 2624 | if(nCount>nMaxEvents){ |
| 2625 | nMaxEvents = nCount; |
| 2626 | } |
| 2627 | ++iterations; |
| 2628 | } |
| 2629 | db_reset(&stWeek); |
| 2630 | while( SQLITE_ROW == db_step(&stWeek) ){ |
| 2631 | const char *zWeek = db_column_text(&stWeek,0); |
| 2632 | const int nCount = db_column_int(&stWeek,1); |
| 2633 | int nSize = nCount |
| 2634 | ? (int)(100 * nCount / nMaxEvents) |
| 2635 | : 0; |
| 2636 | if(!nSize) nSize = 1; |
| 2637 | total += nCount; |
| 2638 | cgi_printf("<tr class='row%d'>", ++rowCount % 2 ); |
| 2639 | cgi_printf("<td><a href='%s/timeline?yw=%t-%s&n=%d&y=%s", |
| 2640 | g.zTop, zYear, zWeek, nCount, |
| 2641 | statsReportTimelineYFlag); |
| 2642 | if(zUserName && *zUserName){ |
| 2643 | cgi_printf("&u=%t",zUserName); |
| 2644 | } |
| 2645 | cgi_printf("'>%s</a></td>",zWeek); |
| 2646 | |
| 2647 | cgi_printf("<td>%d</td>",nCount); |
| 2648 | cgi_printf("<td>"); |
| 2649 | if(nCount){ |
| 2650 | cgi_printf("<div class='statistics-report-graph-line'" |
| 2651 | "style='width:%d%%;'> </div>", |
| 2652 | nSize); |
| 2653 | } |
| 2654 | cgi_printf("</td></tr>"); |
| 2655 | } |
| 2656 | db_finalize(&stWeek); |
| 2657 | free(zDefaultYear); |
| 2658 | cgi_printf("</tbody></table>"); |
| 2659 | if(total){ |
| 2660 | int nAvg = iterations ? (total/iterations) : 0; |
| 2661 | cgi_printf("<br><div>Total events: %d<br>" |
| 2662 | "Average per active week: %d</div>", |
| 2663 | total, nAvg); |
| 2664 | } |
| 2665 | output_table_sorting_javascript("statsTable","tnx",-1); |
| 2666 | } |
| 2667 | } |
| 2668 | |
| 2669 | /* |
| 2670 | ** WEBPAGE: reports |
| 2671 | ** |
| 2672 | ** Shows activity reports for the repository. |
| 2673 | ** |
| 2674 | ** Query Parameters: |
| 2675 | ** |
| 2676 | ** view=REPORT_NAME Valid values: bymonth, byyear, byuser |
| 2677 | ** user=NAME Restricts statistics to the given user |
| 2678 | ** type=TYPE Restricts the report to a specific event type: |
| 2679 | ** ci (checkin), w (wiki), t (ticket), g (tag) |
| 2680 | ** Defaulting to all event types. |
| 2681 | ** |
| 2682 | ** The view-specific query parameters include: |
| 2683 | ** |
| 2684 | ** view=byweek: |
| 2685 | ** |
| 2686 | ** y=YYYY The year to report (default is the server's |
| 2687 | ** current year). |
| 2688 | */ |
| 2689 | void stats_report_page(){ |
| 2690 | HQuery url; /* URL for various branch links */ |
| 2691 | const char *zView = P("view"); /* Which view/report to show. */ |
| 2692 | const char *zUserName = P("user"); |
| 2693 | |
| 2694 | login_check_credentials(); |
| 2695 | if( !g.perm.Read ){ login_needed(); return; } |
| 2696 | if(!zUserName) zUserName = P("u"); |
| 2697 | url_initialize(&url, "reports"); |
| 2698 | if(zUserName && *zUserName){ |
| 2699 | url_add_parameter(&url,"user", zUserName); |
| 2700 | timeline_submenu(&url, "(Remove User Flag)", "view", zView, "user"); |
| 2701 | } |
| 2702 | timeline_submenu(&url, "By Year", "view", "byyear", 0); |
| 2703 | timeline_submenu(&url, "By Month", "view", "bymonth", 0); |
| 2704 | timeline_submenu(&url, "By Week", "view", "byweek", 0); |
| 2705 | timeline_submenu(&url, "By Weekday", "view", "byweekday", 0); |
| 2706 | timeline_submenu(&url, "By User", "view", "byuser", "user"); |
| 2707 | url_reset(&url); |
| 2708 | style_header("Activity Reports"); |
| 2709 | if(0==fossil_strcmp(zView,"byyear")){ |
| 2710 | stats_report_by_month_year(0, 0, zUserName); |
| 2711 | }else if(0==fossil_strcmp(zView,"bymonth")){ |
| 2712 | stats_report_by_month_year(1, 0, zUserName); |
| 2713 | }else if(0==fossil_strcmp(zView,"byweek")){ |
| 2714 | stats_report_year_weeks(zUserName); |
| 2715 | }else if(0==fossil_strcmp(zView,"byuser")){ |
| 2716 | stats_report_by_user(); |
| 2717 | }else if(0==fossil_strcmp(zView,"byweekday")){ |
| 2718 | stats_report_day_of_week(); |
| 2719 | }else{ |
| 2720 | @ <h1>Select a report to show:</h1> |
| 2721 | @ <ul> |
| 2722 | @ <li><a href='?view=byyear'>Events by year</a></li> |
| 2723 | @ <li><a href='?view=bymonth'>Events by month</a></li> |
| 2724 | @ <li><a href='?view=byweek'>Events by calendar week</a></li> |
| 2725 | @ <li><a href='?view=byweekday'>Events by day of the week</a></li> |
| 2726 | @ <li><a href='?view=byuser'>Events by user</a></li> |
| 2727 | @ </ul> |
| 2728 | } |
| 2729 | |
| 2730 | style_footer(); |
| 2731 | } |
| 2732 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -360,20 +360,20 @@ | |
| 360 | } |
| 361 | } |
| 362 | } |
| 363 | if( zType[0]=='c' && (pGraph || (tmFlags & TIMELINE_BRCOLOR)!=0) ){ |
| 364 | int nParent = 0; |
| 365 | int aParent[GR_MAX_RAIL]; |
| 366 | int gidx; |
| 367 | static Stmt qparent; |
| 368 | db_static_prepare(&qparent, |
| 369 | "SELECT pid FROM plink" |
| 370 | " WHERE cid=:rid AND pid NOT IN phantom" |
| 371 | " ORDER BY isprim DESC /*sort*/" |
| 372 | ); |
| 373 | db_bind_int(&qparent, ":rid", rid); |
| 374 | while( db_step(&qparent)==SQLITE_ROW && nParent<ArraySize(aParent) ){ |
| 375 | aParent[nParent++] = db_column_int(&qparent, 0); |
| 376 | } |
| 377 | db_reset(&qparent); |
| 378 | gidx = graph_add_row(pGraph, rid, nParent, aParent, zBr, zBgClr, |
| 379 | zUuid, isLeaf); |
| @@ -1556,11 +1556,11 @@ | |
| 1556 | } |
| 1557 | } |
| 1558 | if( P("showsql") ){ |
| 1559 | @ <blockquote>%h(blob_sql_text(&sql))</blockquote> |
| 1560 | } |
| 1561 | if( P("showid") ) tmFlags |= TIMELINE_SHOWRID; |
| 1562 | blob_zero(&sql); |
| 1563 | db_prepare(&q, "SELECT * FROM timeline ORDER BY sortby DESC /*scan*/"); |
| 1564 | @ <h2>%b(&desc)</h2> |
| 1565 | blob_reset(&desc); |
| 1566 | www_print_timeline(&q, tmFlags, zThisUser, zThisTag, 0); |
| @@ -2044,688 +2044,7 @@ | |
| 2044 | const char *zUuid = db_column_text(&q, 0); |
| 2045 | @ <li> |
| 2046 | @ <a href="%s(g.zTop)/timeline?p=%s(zUuid)&d=%s(zUuid)&unhide">%S(zUuid)</a> |
| 2047 | } |
| 2048 | db_finalize(&q); |
| 2049 | style_footer(); |
| 2050 | } |
| 2051 |
+11
-1
| --- src/url.c | ||
| +++ src/url.c | ||
| @@ -158,12 +158,22 @@ | ||
| 158 | 158 | zLogin = mprintf("%t@", pUrlData->user); |
| 159 | 159 | for(j=i+1; (c=zUrl[j])!=0 && c!='/' && c!=':'; j++){} |
| 160 | 160 | pUrlData->name = mprintf("%.*s", j-i-1, &zUrl[i+1]); |
| 161 | 161 | i = j; |
| 162 | 162 | }else{ |
| 163 | - for(i=iStart; (c=zUrl[i])!=0 && c!='/' && c!=':'; i++){} | |
| 163 | + int inSquare = 0; | |
| 164 | + int n; | |
| 165 | + for(i=iStart; (c=zUrl[i])!=0 && c!='/' && (inSquare || c!=':'); i++){ | |
| 166 | + if( c=='[' ) inSquare = 1; | |
| 167 | + if( c==']' ) inSquare = 0; | |
| 168 | + } | |
| 164 | 169 | pUrlData->name = mprintf("%.*s", i-iStart, &zUrl[iStart]); |
| 170 | + n = strlen(pUrlData->name); | |
| 171 | + if( pUrlData->name[0]=='[' && n>2 && pUrlData->name[n-1]==']' ){ | |
| 172 | + pUrlData->name++; | |
| 173 | + pUrlData->name[n-2] = 0; | |
| 174 | + } | |
| 165 | 175 | zLogin = mprintf(""); |
| 166 | 176 | } |
| 167 | 177 | url_tolower(pUrlData->name); |
| 168 | 178 | if( c==':' ){ |
| 169 | 179 | pUrlData->port = 0; |
| 170 | 180 |
| --- src/url.c | |
| +++ src/url.c | |
| @@ -158,12 +158,22 @@ | |
| 158 | zLogin = mprintf("%t@", pUrlData->user); |
| 159 | for(j=i+1; (c=zUrl[j])!=0 && c!='/' && c!=':'; j++){} |
| 160 | pUrlData->name = mprintf("%.*s", j-i-1, &zUrl[i+1]); |
| 161 | i = j; |
| 162 | }else{ |
| 163 | for(i=iStart; (c=zUrl[i])!=0 && c!='/' && c!=':'; i++){} |
| 164 | pUrlData->name = mprintf("%.*s", i-iStart, &zUrl[iStart]); |
| 165 | zLogin = mprintf(""); |
| 166 | } |
| 167 | url_tolower(pUrlData->name); |
| 168 | if( c==':' ){ |
| 169 | pUrlData->port = 0; |
| 170 |
| --- src/url.c | |
| +++ src/url.c | |
| @@ -158,12 +158,22 @@ | |
| 158 | zLogin = mprintf("%t@", pUrlData->user); |
| 159 | for(j=i+1; (c=zUrl[j])!=0 && c!='/' && c!=':'; j++){} |
| 160 | pUrlData->name = mprintf("%.*s", j-i-1, &zUrl[i+1]); |
| 161 | i = j; |
| 162 | }else{ |
| 163 | int inSquare = 0; |
| 164 | int n; |
| 165 | for(i=iStart; (c=zUrl[i])!=0 && c!='/' && (inSquare || c!=':'); i++){ |
| 166 | if( c=='[' ) inSquare = 1; |
| 167 | if( c==']' ) inSquare = 0; |
| 168 | } |
| 169 | pUrlData->name = mprintf("%.*s", i-iStart, &zUrl[iStart]); |
| 170 | n = strlen(pUrlData->name); |
| 171 | if( pUrlData->name[0]=='[' && n>2 && pUrlData->name[n-1]==']' ){ |
| 172 | pUrlData->name++; |
| 173 | pUrlData->name[n-2] = 0; |
| 174 | } |
| 175 | zLogin = mprintf(""); |
| 176 | } |
| 177 | url_tolower(pUrlData->name); |
| 178 | if( c==':' ){ |
| 179 | pUrlData->port = 0; |
| 180 |
+22
-1
| --- src/wiki.c | ||
| +++ src/wiki.c | ||
| @@ -155,10 +155,30 @@ | ||
| 155 | 155 | @ <pre> |
| 156 | 156 | @ %h(blob_str(pWiki)) |
| 157 | 157 | @ </pre> |
| 158 | 158 | } |
| 159 | 159 | } |
| 160 | + | |
| 161 | +/* | |
| 162 | +** WEBPAGE: md_rules | |
| 163 | +** | |
| 164 | +** Show a summary of the Markdown wiki formatting rules. | |
| 165 | +*/ | |
| 166 | +void markdown_rules_page(void){ | |
| 167 | + Blob x; | |
| 168 | + int fTxt = P("txt")!=0; | |
| 169 | + style_header("Markdown Formatting Rules"); | |
| 170 | + if( fTxt ){ | |
| 171 | + style_submenu_element("Formatted", "Formatted", "%R/md_rules"); | |
| 172 | + }else{ | |
| 173 | + style_submenu_element("Plain-Text", "Plain-Text", "%R/md_rules?txt=1"); | |
| 174 | + } | |
| 175 | + blob_init(&x, builtin_text("markdown.md"), -1); | |
| 176 | + wiki_render_by_mimetype(&x, fTxt ? "text/plain" : "text/x-markdown"); | |
| 177 | + blob_reset(&x); | |
| 178 | + style_footer(); | |
| 179 | +} | |
| 160 | 180 | |
| 161 | 181 | /* |
| 162 | 182 | ** Returns non-zero if moderation is required for wiki changes and wiki |
| 163 | 183 | ** attachments. |
| 164 | 184 | */ |
| @@ -213,11 +233,12 @@ | ||
| 213 | 233 | @ <li> %z(href("%R/wiki?name=%t",zHomePageName)) |
| 214 | 234 | @ %h(zHomePageName)</a> project home page.</li> |
| 215 | 235 | } |
| 216 | 236 | } |
| 217 | 237 | @ <li> %z(href("%R/timeline?y=w"))Recent changes</a> to wiki pages.</li> |
| 218 | - @ <li> %z(href("%R/wiki_rules"))Formatting rules</a> for wiki.</li> | |
| 238 | + @ <li> Formatting rules for %z(href("%R/wiki_rules"))Fossil Wiki</a> and for | |
| 239 | + @ %z(href("%R/md_rules"))Markdown Wiki</a>.</li> | |
| 219 | 240 | @ <li> Use the %z(href("%R/wiki?name=Sandbox"))Sandbox</a> |
| 220 | 241 | @ to experiment.</li> |
| 221 | 242 | if( g.perm.NewWiki ){ |
| 222 | 243 | @ <li> Create a %z(href("%R/wikinew"))new wiki page</a>.</li> |
| 223 | 244 | if( g.perm.Write ){ |
| 224 | 245 |
| --- src/wiki.c | |
| +++ src/wiki.c | |
| @@ -155,10 +155,30 @@ | |
| 155 | @ <pre> |
| 156 | @ %h(blob_str(pWiki)) |
| 157 | @ </pre> |
| 158 | } |
| 159 | } |
| 160 | |
| 161 | /* |
| 162 | ** Returns non-zero if moderation is required for wiki changes and wiki |
| 163 | ** attachments. |
| 164 | */ |
| @@ -213,11 +233,12 @@ | |
| 213 | @ <li> %z(href("%R/wiki?name=%t",zHomePageName)) |
| 214 | @ %h(zHomePageName)</a> project home page.</li> |
| 215 | } |
| 216 | } |
| 217 | @ <li> %z(href("%R/timeline?y=w"))Recent changes</a> to wiki pages.</li> |
| 218 | @ <li> %z(href("%R/wiki_rules"))Formatting rules</a> for wiki.</li> |
| 219 | @ <li> Use the %z(href("%R/wiki?name=Sandbox"))Sandbox</a> |
| 220 | @ to experiment.</li> |
| 221 | if( g.perm.NewWiki ){ |
| 222 | @ <li> Create a %z(href("%R/wikinew"))new wiki page</a>.</li> |
| 223 | if( g.perm.Write ){ |
| 224 |
| --- src/wiki.c | |
| +++ src/wiki.c | |
| @@ -155,10 +155,30 @@ | |
| 155 | @ <pre> |
| 156 | @ %h(blob_str(pWiki)) |
| 157 | @ </pre> |
| 158 | } |
| 159 | } |
| 160 | |
| 161 | /* |
| 162 | ** WEBPAGE: md_rules |
| 163 | ** |
| 164 | ** Show a summary of the Markdown wiki formatting rules. |
| 165 | */ |
| 166 | void markdown_rules_page(void){ |
| 167 | Blob x; |
| 168 | int fTxt = P("txt")!=0; |
| 169 | style_header("Markdown Formatting Rules"); |
| 170 | if( fTxt ){ |
| 171 | style_submenu_element("Formatted", "Formatted", "%R/md_rules"); |
| 172 | }else{ |
| 173 | style_submenu_element("Plain-Text", "Plain-Text", "%R/md_rules?txt=1"); |
| 174 | } |
| 175 | blob_init(&x, builtin_text("markdown.md"), -1); |
| 176 | wiki_render_by_mimetype(&x, fTxt ? "text/plain" : "text/x-markdown"); |
| 177 | blob_reset(&x); |
| 178 | style_footer(); |
| 179 | } |
| 180 | |
| 181 | /* |
| 182 | ** Returns non-zero if moderation is required for wiki changes and wiki |
| 183 | ** attachments. |
| 184 | */ |
| @@ -213,11 +233,12 @@ | |
| 233 | @ <li> %z(href("%R/wiki?name=%t",zHomePageName)) |
| 234 | @ %h(zHomePageName)</a> project home page.</li> |
| 235 | } |
| 236 | } |
| 237 | @ <li> %z(href("%R/timeline?y=w"))Recent changes</a> to wiki pages.</li> |
| 238 | @ <li> Formatting rules for %z(href("%R/wiki_rules"))Fossil Wiki</a> and for |
| 239 | @ %z(href("%R/md_rules"))Markdown Wiki</a>.</li> |
| 240 | @ <li> Use the %z(href("%R/wiki?name=Sandbox"))Sandbox</a> |
| 241 | @ to experiment.</li> |
| 242 | if( g.perm.NewWiki ){ |
| 243 | @ <li> Create a %z(href("%R/wikinew"))new wiki page</a>.</li> |
| 244 | if( g.perm.Write ){ |
| 245 |
+1
-1
| --- win/Makefile.PellesCGMake | ||
| +++ win/Makefile.PellesCGMake | ||
| @@ -141,11 +141,11 @@ | ||
| 141 | 141 | # generate the index source, containing all web references,.. |
| 142 | 142 | page_index.h: $(TRANSLATEDSRC) mkindex.exe |
| 143 | 143 | mkindex.exe $(TRANSLATEDSRC) >$@ |
| 144 | 144 | |
| 145 | 145 | builtin_data.h: $(EXTRA_FILES) mkbuiltin.exe |
| 146 | - mkbuiltin.exe $(EXTRA_FILES) >$@ | |
| 146 | + mkbuiltin.exe --prefix $(SRCDIR)/ $(EXTRA_FILES) >$@ | |
| 147 | 147 | |
| 148 | 148 | # extracting version info from manifest |
| 149 | 149 | VERSION.h: version.exe ..\manifest.uuid ..\manifest ..\VERSION |
| 150 | 150 | version.exe ..\manifest.uuid ..\manifest ..\VERSION >$@ |
| 151 | 151 | |
| 152 | 152 |
| --- win/Makefile.PellesCGMake | |
| +++ win/Makefile.PellesCGMake | |
| @@ -141,11 +141,11 @@ | |
| 141 | # generate the index source, containing all web references,.. |
| 142 | page_index.h: $(TRANSLATEDSRC) mkindex.exe |
| 143 | mkindex.exe $(TRANSLATEDSRC) >$@ |
| 144 | |
| 145 | builtin_data.h: $(EXTRA_FILES) mkbuiltin.exe |
| 146 | mkbuiltin.exe $(EXTRA_FILES) >$@ |
| 147 | |
| 148 | # extracting version info from manifest |
| 149 | VERSION.h: version.exe ..\manifest.uuid ..\manifest ..\VERSION |
| 150 | version.exe ..\manifest.uuid ..\manifest ..\VERSION >$@ |
| 151 | |
| 152 |
| --- win/Makefile.PellesCGMake | |
| +++ win/Makefile.PellesCGMake | |
| @@ -141,11 +141,11 @@ | |
| 141 | # generate the index source, containing all web references,.. |
| 142 | page_index.h: $(TRANSLATEDSRC) mkindex.exe |
| 143 | mkindex.exe $(TRANSLATEDSRC) >$@ |
| 144 | |
| 145 | builtin_data.h: $(EXTRA_FILES) mkbuiltin.exe |
| 146 | mkbuiltin.exe --prefix $(SRCDIR)/ $(EXTRA_FILES) >$@ |
| 147 | |
| 148 | # extracting version info from manifest |
| 149 | VERSION.h: version.exe ..\manifest.uuid ..\manifest ..\VERSION |
| 150 | version.exe ..\manifest.uuid ..\manifest ..\VERSION >$@ |
| 151 | |
| 152 |
+11
-5
| --- win/Makefile.dmc | ||
| +++ win/Makefile.dmc | ||
| @@ -28,13 +28,13 @@ | ||
| 28 | 28 | |
| 29 | 29 | SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_OMIT_DEPRECATED -DSQLITE_ENABLE_EXPLAIN_COMMENTS |
| 30 | 30 | |
| 31 | 31 | SHELL_OPTIONS = -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=fossil_open -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen |
| 32 | 32 | |
| 33 | -SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c builtin_.c bundle_.c cache_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c doc_.c encode_.c event_.c export_.c file_.c finfo_.c foci_.c fusefs_.c glob_.c graph_.c gzip_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c pivot_.c popen_.c pqueue_.c printf_.c publish_.c purge_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c sitemap_.c skins_.c sqlcmd_.c stash_.c stat_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c | |
| 33 | +SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c builtin_.c bundle_.c cache_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c doc_.c encode_.c event_.c export_.c file_.c finfo_.c foci_.c fusefs_.c glob_.c graph_.c gzip_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c pivot_.c popen_.c pqueue_.c printf_.c publish_.c purge_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c sitemap_.c skins_.c sqlcmd_.c stash_.c stat_.c statrep_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c | |
| 34 | 34 | |
| 35 | -OBJ = $(OBJDIR)\add$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\builtin$O $(OBJDIR)\bundle$O $(OBJDIR)\cache$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\foci$O $(OBJDIR)\fusefs$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\publish$O $(OBJDIR)\purge$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\setup$O $(OBJDIR)\sha1$O $(OBJDIR)\shun$O $(OBJDIR)\sitemap$O $(OBJDIR)\skins$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O | |
| 35 | +OBJ = $(OBJDIR)\add$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\builtin$O $(OBJDIR)\bundle$O $(OBJDIR)\cache$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\foci$O $(OBJDIR)\fusefs$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\publish$O $(OBJDIR)\purge$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\setup$O $(OBJDIR)\sha1$O $(OBJDIR)\shun$O $(OBJDIR)\sitemap$O $(OBJDIR)\skins$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\statrep$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O | |
| 36 | 36 | |
| 37 | 37 | |
| 38 | 38 | RC=$(DMDIR)\bin\rcc |
| 39 | 39 | RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__ |
| 40 | 40 | |
| @@ -49,11 +49,11 @@ | ||
| 49 | 49 | |
| 50 | 50 | $(OBJDIR)\fossil.res: $B\win\fossil.rc |
| 51 | 51 | $(RC) $(RCFLAGS) -o$@ $** |
| 52 | 52 | |
| 53 | 53 | $(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res |
| 54 | - +echo add allrepo attach bag bisect blob branch browse builtin bundle cache captcha cgi checkin checkout clearsign clone comformat configure content db delta deltacmd descendants diff diffcmd doc encode event export file finfo foci fusefs glob graph gzip http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf loadctrl login lookslike main manifest markdown markdown_html md5 merge merge3 moderate name path pivot popen pqueue printf publish purge rebuild regexp report rss schema search setup sha1 shun sitemap skins sqlcmd stash stat style sync tag tar th_main timeline tkt tktsetup undo unicode update url user utf8 util verify vfile wiki wikiformat winfile winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@ | |
| 54 | + +echo add allrepo attach bag bisect blob branch browse builtin bundle cache captcha cgi checkin checkout clearsign clone comformat configure content db delta deltacmd descendants diff diffcmd doc encode event export file finfo foci fusefs glob graph gzip http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf loadctrl login lookslike main manifest markdown markdown_html md5 merge merge3 moderate name path pivot popen pqueue printf publish purge rebuild regexp report rss schema search setup sha1 shun sitemap skins sqlcmd stash stat statrep style sync tag tar th_main timeline tkt tktsetup undo unicode update url user utf8 util verify vfile wiki wikiformat winfile winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@ | |
| 55 | 55 | +echo fossil >> $@ |
| 56 | 56 | +echo fossil >> $@ |
| 57 | 57 | +echo $(LIBS) >> $@ |
| 58 | 58 | +echo. >> $@ |
| 59 | 59 | +echo fossil >> $@ |
| @@ -96,11 +96,11 @@ | ||
| 96 | 96 | |
| 97 | 97 | page_index.h: mkindex$E $(SRC) |
| 98 | 98 | +$** > $@ |
| 99 | 99 | |
| 100 | 100 | builtin_data.h: mkbuiltin$E $(EXTRA_FILES) |
| 101 | - +$** > $@ | |
| 101 | + mkbuiltin$E --prefix $(SRCDIR)/ $(EXTRA_FILES) > $@ | |
| 102 | 102 | |
| 103 | 103 | clean: |
| 104 | 104 | -del $(OBJDIR)\*.obj |
| 105 | 105 | -del *.obj *_.c *.h *.map |
| 106 | 106 | |
| @@ -674,10 +674,16 @@ | ||
| 674 | 674 | $(OBJDIR)\stat$O : stat_.c stat.h |
| 675 | 675 | $(TCC) -o$@ -c stat_.c |
| 676 | 676 | |
| 677 | 677 | stat_.c : $(SRCDIR)\stat.c |
| 678 | 678 | +translate$E $** > $@ |
| 679 | + | |
| 680 | +$(OBJDIR)\statrep$O : statrep_.c statrep.h | |
| 681 | + $(TCC) -o$@ -c statrep_.c | |
| 682 | + | |
| 683 | +statrep_.c : $(SRCDIR)\statrep.c | |
| 684 | + +translate$E $** > $@ | |
| 679 | 685 | |
| 680 | 686 | $(OBJDIR)\style$O : style_.c style.h |
| 681 | 687 | $(TCC) -o$@ -c style_.c |
| 682 | 688 | |
| 683 | 689 | style_.c : $(SRCDIR)\style.c |
| @@ -826,7 +832,7 @@ | ||
| 826 | 832 | |
| 827 | 833 | zip_.c : $(SRCDIR)\zip.c |
| 828 | 834 | +translate$E $** > $@ |
| 829 | 835 | |
| 830 | 836 | headers: makeheaders$E page_index.h builtin_data.h VERSION.h |
| 831 | - +makeheaders$E add_.c:add.h allrepo_.c:allrepo.h attach_.c:attach.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h builtin_.c:builtin.h bundle_.c:bundle.h cache_.c:cache.h captcha_.c:captcha.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 configure_.c:configure.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h doc_.c:doc.h encode_.c:encode.h event_.c:event.h export_.c:export.h file_.c:file.h finfo_.c:finfo.h foci_.c:foci.h fusefs_.c:fusefs.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h publish_.c:publish.h purge_.c:purge.h rebuild_.c:rebuild.h regexp_.c:regexp.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h setup_.c:setup.h sha1_.c:sha1.h shun_.c:shun.h sitemap_.c:sitemap.h skins_.c:skins.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h | |
| 837 | + +makeheaders$E add_.c:add.h allrepo_.c:allrepo.h attach_.c:attach.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h builtin_.c:builtin.h bundle_.c:bundle.h cache_.c:cache.h captcha_.c:captcha.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 configure_.c:configure.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h doc_.c:doc.h encode_.c:encode.h event_.c:event.h export_.c:export.h file_.c:file.h finfo_.c:finfo.h foci_.c:foci.h fusefs_.c:fusefs.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h publish_.c:publish.h purge_.c:purge.h rebuild_.c:rebuild.h regexp_.c:regexp.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h setup_.c:setup.h sha1_.c:sha1.h shun_.c:shun.h sitemap_.c:sitemap.h skins_.c:skins.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h statrep_.c:statrep.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h | |
| 832 | 838 | @copy /Y nul: headers |
| 833 | 839 |
| --- win/Makefile.dmc | |
| +++ win/Makefile.dmc | |
| @@ -28,13 +28,13 @@ | |
| 28 | |
| 29 | SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_OMIT_DEPRECATED -DSQLITE_ENABLE_EXPLAIN_COMMENTS |
| 30 | |
| 31 | SHELL_OPTIONS = -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=fossil_open -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen |
| 32 | |
| 33 | SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c builtin_.c bundle_.c cache_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c doc_.c encode_.c event_.c export_.c file_.c finfo_.c foci_.c fusefs_.c glob_.c graph_.c gzip_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c pivot_.c popen_.c pqueue_.c printf_.c publish_.c purge_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c sitemap_.c skins_.c sqlcmd_.c stash_.c stat_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c |
| 34 | |
| 35 | OBJ = $(OBJDIR)\add$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\builtin$O $(OBJDIR)\bundle$O $(OBJDIR)\cache$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\foci$O $(OBJDIR)\fusefs$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\publish$O $(OBJDIR)\purge$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\setup$O $(OBJDIR)\sha1$O $(OBJDIR)\shun$O $(OBJDIR)\sitemap$O $(OBJDIR)\skins$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O |
| 36 | |
| 37 | |
| 38 | RC=$(DMDIR)\bin\rcc |
| 39 | RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__ |
| 40 | |
| @@ -49,11 +49,11 @@ | |
| 49 | |
| 50 | $(OBJDIR)\fossil.res: $B\win\fossil.rc |
| 51 | $(RC) $(RCFLAGS) -o$@ $** |
| 52 | |
| 53 | $(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res |
| 54 | +echo add allrepo attach bag bisect blob branch browse builtin bundle cache captcha cgi checkin checkout clearsign clone comformat configure content db delta deltacmd descendants diff diffcmd doc encode event export file finfo foci fusefs glob graph gzip http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf loadctrl login lookslike main manifest markdown markdown_html md5 merge merge3 moderate name path pivot popen pqueue printf publish purge rebuild regexp report rss schema search setup sha1 shun sitemap skins sqlcmd stash stat style sync tag tar th_main timeline tkt tktsetup undo unicode update url user utf8 util verify vfile wiki wikiformat winfile winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@ |
| 55 | +echo fossil >> $@ |
| 56 | +echo fossil >> $@ |
| 57 | +echo $(LIBS) >> $@ |
| 58 | +echo. >> $@ |
| 59 | +echo fossil >> $@ |
| @@ -96,11 +96,11 @@ | |
| 96 | |
| 97 | page_index.h: mkindex$E $(SRC) |
| 98 | +$** > $@ |
| 99 | |
| 100 | builtin_data.h: mkbuiltin$E $(EXTRA_FILES) |
| 101 | +$** > $@ |
| 102 | |
| 103 | clean: |
| 104 | -del $(OBJDIR)\*.obj |
| 105 | -del *.obj *_.c *.h *.map |
| 106 | |
| @@ -674,10 +674,16 @@ | |
| 674 | $(OBJDIR)\stat$O : stat_.c stat.h |
| 675 | $(TCC) -o$@ -c stat_.c |
| 676 | |
| 677 | stat_.c : $(SRCDIR)\stat.c |
| 678 | +translate$E $** > $@ |
| 679 | |
| 680 | $(OBJDIR)\style$O : style_.c style.h |
| 681 | $(TCC) -o$@ -c style_.c |
| 682 | |
| 683 | style_.c : $(SRCDIR)\style.c |
| @@ -826,7 +832,7 @@ | |
| 826 | |
| 827 | zip_.c : $(SRCDIR)\zip.c |
| 828 | +translate$E $** > $@ |
| 829 | |
| 830 | headers: makeheaders$E page_index.h builtin_data.h VERSION.h |
| 831 | +makeheaders$E add_.c:add.h allrepo_.c:allrepo.h attach_.c:attach.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h builtin_.c:builtin.h bundle_.c:bundle.h cache_.c:cache.h captcha_.c:captcha.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 configure_.c:configure.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h doc_.c:doc.h encode_.c:encode.h event_.c:event.h export_.c:export.h file_.c:file.h finfo_.c:finfo.h foci_.c:foci.h fusefs_.c:fusefs.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h publish_.c:publish.h purge_.c:purge.h rebuild_.c:rebuild.h regexp_.c:regexp.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h setup_.c:setup.h sha1_.c:sha1.h shun_.c:shun.h sitemap_.c:sitemap.h skins_.c:skins.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h |
| 832 | @copy /Y nul: headers |
| 833 |
| --- win/Makefile.dmc | |
| +++ win/Makefile.dmc | |
| @@ -28,13 +28,13 @@ | |
| 28 | |
| 29 | SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_OMIT_DEPRECATED -DSQLITE_ENABLE_EXPLAIN_COMMENTS |
| 30 | |
| 31 | SHELL_OPTIONS = -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=fossil_open -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen |
| 32 | |
| 33 | SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c builtin_.c bundle_.c cache_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c doc_.c encode_.c event_.c export_.c file_.c finfo_.c foci_.c fusefs_.c glob_.c graph_.c gzip_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c pivot_.c popen_.c pqueue_.c printf_.c publish_.c purge_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c sitemap_.c skins_.c sqlcmd_.c stash_.c stat_.c statrep_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c |
| 34 | |
| 35 | OBJ = $(OBJDIR)\add$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\builtin$O $(OBJDIR)\bundle$O $(OBJDIR)\cache$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\foci$O $(OBJDIR)\fusefs$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\publish$O $(OBJDIR)\purge$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\setup$O $(OBJDIR)\sha1$O $(OBJDIR)\shun$O $(OBJDIR)\sitemap$O $(OBJDIR)\skins$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\statrep$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O |
| 36 | |
| 37 | |
| 38 | RC=$(DMDIR)\bin\rcc |
| 39 | RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__ |
| 40 | |
| @@ -49,11 +49,11 @@ | |
| 49 | |
| 50 | $(OBJDIR)\fossil.res: $B\win\fossil.rc |
| 51 | $(RC) $(RCFLAGS) -o$@ $** |
| 52 | |
| 53 | $(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res |
| 54 | +echo add allrepo attach bag bisect blob branch browse builtin bundle cache captcha cgi checkin checkout clearsign clone comformat configure content db delta deltacmd descendants diff diffcmd doc encode event export file finfo foci fusefs glob graph gzip http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf loadctrl login lookslike main manifest markdown markdown_html md5 merge merge3 moderate name path pivot popen pqueue printf publish purge rebuild regexp report rss schema search setup sha1 shun sitemap skins sqlcmd stash stat statrep style sync tag tar th_main timeline tkt tktsetup undo unicode update url user utf8 util verify vfile wiki wikiformat winfile winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@ |
| 55 | +echo fossil >> $@ |
| 56 | +echo fossil >> $@ |
| 57 | +echo $(LIBS) >> $@ |
| 58 | +echo. >> $@ |
| 59 | +echo fossil >> $@ |
| @@ -96,11 +96,11 @@ | |
| 96 | |
| 97 | page_index.h: mkindex$E $(SRC) |
| 98 | +$** > $@ |
| 99 | |
| 100 | builtin_data.h: mkbuiltin$E $(EXTRA_FILES) |
| 101 | mkbuiltin$E --prefix $(SRCDIR)/ $(EXTRA_FILES) > $@ |
| 102 | |
| 103 | clean: |
| 104 | -del $(OBJDIR)\*.obj |
| 105 | -del *.obj *_.c *.h *.map |
| 106 | |
| @@ -674,10 +674,16 @@ | |
| 674 | $(OBJDIR)\stat$O : stat_.c stat.h |
| 675 | $(TCC) -o$@ -c stat_.c |
| 676 | |
| 677 | stat_.c : $(SRCDIR)\stat.c |
| 678 | +translate$E $** > $@ |
| 679 | |
| 680 | $(OBJDIR)\statrep$O : statrep_.c statrep.h |
| 681 | $(TCC) -o$@ -c statrep_.c |
| 682 | |
| 683 | statrep_.c : $(SRCDIR)\statrep.c |
| 684 | +translate$E $** > $@ |
| 685 | |
| 686 | $(OBJDIR)\style$O : style_.c style.h |
| 687 | $(TCC) -o$@ -c style_.c |
| 688 | |
| 689 | style_.c : $(SRCDIR)\style.c |
| @@ -826,7 +832,7 @@ | |
| 832 | |
| 833 | zip_.c : $(SRCDIR)\zip.c |
| 834 | +translate$E $** > $@ |
| 835 | |
| 836 | headers: makeheaders$E page_index.h builtin_data.h VERSION.h |
| 837 | +makeheaders$E add_.c:add.h allrepo_.c:allrepo.h attach_.c:attach.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h builtin_.c:builtin.h bundle_.c:bundle.h cache_.c:cache.h captcha_.c:captcha.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 configure_.c:configure.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h doc_.c:doc.h encode_.c:encode.h event_.c:event.h export_.c:export.h file_.c:file.h finfo_.c:finfo.h foci_.c:foci.h fusefs_.c:fusefs.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h publish_.c:publish.h purge_.c:purge.h rebuild_.c:rebuild.h regexp_.c:regexp.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h setup_.c:setup.h sha1_.c:sha1.h shun_.c:shun.h sitemap_.c:sitemap.h skins_.c:skins.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h statrep_.c:statrep.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h |
| 838 | @copy /Y nul: headers |
| 839 |
+15
-2
| --- win/Makefile.mingw | ||
| +++ win/Makefile.mingw | ||
| @@ -457,10 +457,11 @@ | ||
| 457 | 457 | $(SRCDIR)/sitemap.c \ |
| 458 | 458 | $(SRCDIR)/skins.c \ |
| 459 | 459 | $(SRCDIR)/sqlcmd.c \ |
| 460 | 460 | $(SRCDIR)/stash.c \ |
| 461 | 461 | $(SRCDIR)/stat.c \ |
| 462 | + $(SRCDIR)/statrep.c \ | |
| 462 | 463 | $(SRCDIR)/style.c \ |
| 463 | 464 | $(SRCDIR)/sync.c \ |
| 464 | 465 | $(SRCDIR)/tag.c \ |
| 465 | 466 | $(SRCDIR)/tar.c \ |
| 466 | 467 | $(SRCDIR)/th_main.c \ |
| @@ -508,11 +509,12 @@ | ||
| 508 | 509 | $(SRCDIR)/../skins/plain_gray/footer.txt \ |
| 509 | 510 | $(SRCDIR)/../skins/plain_gray/header.txt \ |
| 510 | 511 | $(SRCDIR)/../skins/rounded1/css.txt \ |
| 511 | 512 | $(SRCDIR)/../skins/rounded1/footer.txt \ |
| 512 | 513 | $(SRCDIR)/../skins/rounded1/header.txt \ |
| 513 | - $(SRCDIR)/diff.tcl | |
| 514 | + $(SRCDIR)/diff.tcl \ | |
| 515 | + $(SRCDIR)/markdown.md | |
| 514 | 516 | |
| 515 | 517 | TRANS_SRC = \ |
| 516 | 518 | $(OBJDIR)/add_.c \ |
| 517 | 519 | $(OBJDIR)/allrepo_.c \ |
| 518 | 520 | $(OBJDIR)/attach_.c \ |
| @@ -603,10 +605,11 @@ | ||
| 603 | 605 | $(OBJDIR)/sitemap_.c \ |
| 604 | 606 | $(OBJDIR)/skins_.c \ |
| 605 | 607 | $(OBJDIR)/sqlcmd_.c \ |
| 606 | 608 | $(OBJDIR)/stash_.c \ |
| 607 | 609 | $(OBJDIR)/stat_.c \ |
| 610 | + $(OBJDIR)/statrep_.c \ | |
| 608 | 611 | $(OBJDIR)/style_.c \ |
| 609 | 612 | $(OBJDIR)/sync_.c \ |
| 610 | 613 | $(OBJDIR)/tag_.c \ |
| 611 | 614 | $(OBJDIR)/tar_.c \ |
| 612 | 615 | $(OBJDIR)/th_main_.c \ |
| @@ -722,10 +725,11 @@ | ||
| 722 | 725 | $(OBJDIR)/sitemap.o \ |
| 723 | 726 | $(OBJDIR)/skins.o \ |
| 724 | 727 | $(OBJDIR)/sqlcmd.o \ |
| 725 | 728 | $(OBJDIR)/stash.o \ |
| 726 | 729 | $(OBJDIR)/stat.o \ |
| 730 | + $(OBJDIR)/statrep.o \ | |
| 727 | 731 | $(OBJDIR)/style.o \ |
| 728 | 732 | $(OBJDIR)/sync.o \ |
| 729 | 733 | $(OBJDIR)/tag.o \ |
| 730 | 734 | $(OBJDIR)/tar.o \ |
| 731 | 735 | $(OBJDIR)/th_main.o \ |
| @@ -939,11 +943,11 @@ | ||
| 939 | 943 | |
| 940 | 944 | $(OBJDIR)/page_index.h: $(TRANS_SRC) $(MKINDEX) |
| 941 | 945 | $(MKINDEX) $(TRANS_SRC) >$@ |
| 942 | 946 | |
| 943 | 947 | $(OBJDIR)/builtin_data.h: $(MKBUILTIN) $(EXTRA_FILES) |
| 944 | - $(MKBUILTIN) $(EXTRA_FILES) >$@ | |
| 948 | + $(MKBUILTIN) --prefix $(SRCDIR)/ $(EXTRA_FILES) >$@ | |
| 945 | 949 | |
| 946 | 950 | $(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/builtin_data.h $(MAKEHEADERS) $(OBJDIR)/VERSION.h |
| 947 | 951 | $(MAKEHEADERS) $(OBJDIR)/add_.c:$(OBJDIR)/add.h \ |
| 948 | 952 | $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h \ |
| 949 | 953 | $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h \ |
| @@ -1034,10 +1038,11 @@ | ||
| 1034 | 1038 | $(OBJDIR)/sitemap_.c:$(OBJDIR)/sitemap.h \ |
| 1035 | 1039 | $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h \ |
| 1036 | 1040 | $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h \ |
| 1037 | 1041 | $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h \ |
| 1038 | 1042 | $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h \ |
| 1043 | + $(OBJDIR)/statrep_.c:$(OBJDIR)/statrep.h \ | |
| 1039 | 1044 | $(OBJDIR)/style_.c:$(OBJDIR)/style.h \ |
| 1040 | 1045 | $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h \ |
| 1041 | 1046 | $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h \ |
| 1042 | 1047 | $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h \ |
| 1043 | 1048 | $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h \ |
| @@ -1803,10 +1808,18 @@ | ||
| 1803 | 1808 | |
| 1804 | 1809 | $(OBJDIR)/stat.o: $(OBJDIR)/stat_.c $(OBJDIR)/stat.h $(SRCDIR)/config.h |
| 1805 | 1810 | $(XTCC) -o $(OBJDIR)/stat.o -c $(OBJDIR)/stat_.c |
| 1806 | 1811 | |
| 1807 | 1812 | $(OBJDIR)/stat.h: $(OBJDIR)/headers |
| 1813 | + | |
| 1814 | +$(OBJDIR)/statrep_.c: $(SRCDIR)/statrep.c $(TRANSLATE) | |
| 1815 | + $(TRANSLATE) $(SRCDIR)/statrep.c >$@ | |
| 1816 | + | |
| 1817 | +$(OBJDIR)/statrep.o: $(OBJDIR)/statrep_.c $(OBJDIR)/statrep.h $(SRCDIR)/config.h | |
| 1818 | + $(XTCC) -o $(OBJDIR)/statrep.o -c $(OBJDIR)/statrep_.c | |
| 1819 | + | |
| 1820 | +$(OBJDIR)/statrep.h: $(OBJDIR)/headers | |
| 1808 | 1821 | |
| 1809 | 1822 | $(OBJDIR)/style_.c: $(SRCDIR)/style.c $(TRANSLATE) |
| 1810 | 1823 | $(TRANSLATE) $(SRCDIR)/style.c >$@ |
| 1811 | 1824 | |
| 1812 | 1825 | $(OBJDIR)/style.o: $(OBJDIR)/style_.c $(OBJDIR)/style.h $(SRCDIR)/config.h |
| 1813 | 1826 |
| --- win/Makefile.mingw | |
| +++ win/Makefile.mingw | |
| @@ -457,10 +457,11 @@ | |
| 457 | $(SRCDIR)/sitemap.c \ |
| 458 | $(SRCDIR)/skins.c \ |
| 459 | $(SRCDIR)/sqlcmd.c \ |
| 460 | $(SRCDIR)/stash.c \ |
| 461 | $(SRCDIR)/stat.c \ |
| 462 | $(SRCDIR)/style.c \ |
| 463 | $(SRCDIR)/sync.c \ |
| 464 | $(SRCDIR)/tag.c \ |
| 465 | $(SRCDIR)/tar.c \ |
| 466 | $(SRCDIR)/th_main.c \ |
| @@ -508,11 +509,12 @@ | |
| 508 | $(SRCDIR)/../skins/plain_gray/footer.txt \ |
| 509 | $(SRCDIR)/../skins/plain_gray/header.txt \ |
| 510 | $(SRCDIR)/../skins/rounded1/css.txt \ |
| 511 | $(SRCDIR)/../skins/rounded1/footer.txt \ |
| 512 | $(SRCDIR)/../skins/rounded1/header.txt \ |
| 513 | $(SRCDIR)/diff.tcl |
| 514 | |
| 515 | TRANS_SRC = \ |
| 516 | $(OBJDIR)/add_.c \ |
| 517 | $(OBJDIR)/allrepo_.c \ |
| 518 | $(OBJDIR)/attach_.c \ |
| @@ -603,10 +605,11 @@ | |
| 603 | $(OBJDIR)/sitemap_.c \ |
| 604 | $(OBJDIR)/skins_.c \ |
| 605 | $(OBJDIR)/sqlcmd_.c \ |
| 606 | $(OBJDIR)/stash_.c \ |
| 607 | $(OBJDIR)/stat_.c \ |
| 608 | $(OBJDIR)/style_.c \ |
| 609 | $(OBJDIR)/sync_.c \ |
| 610 | $(OBJDIR)/tag_.c \ |
| 611 | $(OBJDIR)/tar_.c \ |
| 612 | $(OBJDIR)/th_main_.c \ |
| @@ -722,10 +725,11 @@ | |
| 722 | $(OBJDIR)/sitemap.o \ |
| 723 | $(OBJDIR)/skins.o \ |
| 724 | $(OBJDIR)/sqlcmd.o \ |
| 725 | $(OBJDIR)/stash.o \ |
| 726 | $(OBJDIR)/stat.o \ |
| 727 | $(OBJDIR)/style.o \ |
| 728 | $(OBJDIR)/sync.o \ |
| 729 | $(OBJDIR)/tag.o \ |
| 730 | $(OBJDIR)/tar.o \ |
| 731 | $(OBJDIR)/th_main.o \ |
| @@ -939,11 +943,11 @@ | |
| 939 | |
| 940 | $(OBJDIR)/page_index.h: $(TRANS_SRC) $(MKINDEX) |
| 941 | $(MKINDEX) $(TRANS_SRC) >$@ |
| 942 | |
| 943 | $(OBJDIR)/builtin_data.h: $(MKBUILTIN) $(EXTRA_FILES) |
| 944 | $(MKBUILTIN) $(EXTRA_FILES) >$@ |
| 945 | |
| 946 | $(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/builtin_data.h $(MAKEHEADERS) $(OBJDIR)/VERSION.h |
| 947 | $(MAKEHEADERS) $(OBJDIR)/add_.c:$(OBJDIR)/add.h \ |
| 948 | $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h \ |
| 949 | $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h \ |
| @@ -1034,10 +1038,11 @@ | |
| 1034 | $(OBJDIR)/sitemap_.c:$(OBJDIR)/sitemap.h \ |
| 1035 | $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h \ |
| 1036 | $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h \ |
| 1037 | $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h \ |
| 1038 | $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h \ |
| 1039 | $(OBJDIR)/style_.c:$(OBJDIR)/style.h \ |
| 1040 | $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h \ |
| 1041 | $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h \ |
| 1042 | $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h \ |
| 1043 | $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h \ |
| @@ -1803,10 +1808,18 @@ | |
| 1803 | |
| 1804 | $(OBJDIR)/stat.o: $(OBJDIR)/stat_.c $(OBJDIR)/stat.h $(SRCDIR)/config.h |
| 1805 | $(XTCC) -o $(OBJDIR)/stat.o -c $(OBJDIR)/stat_.c |
| 1806 | |
| 1807 | $(OBJDIR)/stat.h: $(OBJDIR)/headers |
| 1808 | |
| 1809 | $(OBJDIR)/style_.c: $(SRCDIR)/style.c $(TRANSLATE) |
| 1810 | $(TRANSLATE) $(SRCDIR)/style.c >$@ |
| 1811 | |
| 1812 | $(OBJDIR)/style.o: $(OBJDIR)/style_.c $(OBJDIR)/style.h $(SRCDIR)/config.h |
| 1813 |
| --- win/Makefile.mingw | |
| +++ win/Makefile.mingw | |
| @@ -457,10 +457,11 @@ | |
| 457 | $(SRCDIR)/sitemap.c \ |
| 458 | $(SRCDIR)/skins.c \ |
| 459 | $(SRCDIR)/sqlcmd.c \ |
| 460 | $(SRCDIR)/stash.c \ |
| 461 | $(SRCDIR)/stat.c \ |
| 462 | $(SRCDIR)/statrep.c \ |
| 463 | $(SRCDIR)/style.c \ |
| 464 | $(SRCDIR)/sync.c \ |
| 465 | $(SRCDIR)/tag.c \ |
| 466 | $(SRCDIR)/tar.c \ |
| 467 | $(SRCDIR)/th_main.c \ |
| @@ -508,11 +509,12 @@ | |
| 509 | $(SRCDIR)/../skins/plain_gray/footer.txt \ |
| 510 | $(SRCDIR)/../skins/plain_gray/header.txt \ |
| 511 | $(SRCDIR)/../skins/rounded1/css.txt \ |
| 512 | $(SRCDIR)/../skins/rounded1/footer.txt \ |
| 513 | $(SRCDIR)/../skins/rounded1/header.txt \ |
| 514 | $(SRCDIR)/diff.tcl \ |
| 515 | $(SRCDIR)/markdown.md |
| 516 | |
| 517 | TRANS_SRC = \ |
| 518 | $(OBJDIR)/add_.c \ |
| 519 | $(OBJDIR)/allrepo_.c \ |
| 520 | $(OBJDIR)/attach_.c \ |
| @@ -603,10 +605,11 @@ | |
| 605 | $(OBJDIR)/sitemap_.c \ |
| 606 | $(OBJDIR)/skins_.c \ |
| 607 | $(OBJDIR)/sqlcmd_.c \ |
| 608 | $(OBJDIR)/stash_.c \ |
| 609 | $(OBJDIR)/stat_.c \ |
| 610 | $(OBJDIR)/statrep_.c \ |
| 611 | $(OBJDIR)/style_.c \ |
| 612 | $(OBJDIR)/sync_.c \ |
| 613 | $(OBJDIR)/tag_.c \ |
| 614 | $(OBJDIR)/tar_.c \ |
| 615 | $(OBJDIR)/th_main_.c \ |
| @@ -722,10 +725,11 @@ | |
| 725 | $(OBJDIR)/sitemap.o \ |
| 726 | $(OBJDIR)/skins.o \ |
| 727 | $(OBJDIR)/sqlcmd.o \ |
| 728 | $(OBJDIR)/stash.o \ |
| 729 | $(OBJDIR)/stat.o \ |
| 730 | $(OBJDIR)/statrep.o \ |
| 731 | $(OBJDIR)/style.o \ |
| 732 | $(OBJDIR)/sync.o \ |
| 733 | $(OBJDIR)/tag.o \ |
| 734 | $(OBJDIR)/tar.o \ |
| 735 | $(OBJDIR)/th_main.o \ |
| @@ -939,11 +943,11 @@ | |
| 943 | |
| 944 | $(OBJDIR)/page_index.h: $(TRANS_SRC) $(MKINDEX) |
| 945 | $(MKINDEX) $(TRANS_SRC) >$@ |
| 946 | |
| 947 | $(OBJDIR)/builtin_data.h: $(MKBUILTIN) $(EXTRA_FILES) |
| 948 | $(MKBUILTIN) --prefix $(SRCDIR)/ $(EXTRA_FILES) >$@ |
| 949 | |
| 950 | $(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/builtin_data.h $(MAKEHEADERS) $(OBJDIR)/VERSION.h |
| 951 | $(MAKEHEADERS) $(OBJDIR)/add_.c:$(OBJDIR)/add.h \ |
| 952 | $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h \ |
| 953 | $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h \ |
| @@ -1034,10 +1038,11 @@ | |
| 1038 | $(OBJDIR)/sitemap_.c:$(OBJDIR)/sitemap.h \ |
| 1039 | $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h \ |
| 1040 | $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h \ |
| 1041 | $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h \ |
| 1042 | $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h \ |
| 1043 | $(OBJDIR)/statrep_.c:$(OBJDIR)/statrep.h \ |
| 1044 | $(OBJDIR)/style_.c:$(OBJDIR)/style.h \ |
| 1045 | $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h \ |
| 1046 | $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h \ |
| 1047 | $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h \ |
| 1048 | $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h \ |
| @@ -1803,10 +1808,18 @@ | |
| 1808 | |
| 1809 | $(OBJDIR)/stat.o: $(OBJDIR)/stat_.c $(OBJDIR)/stat.h $(SRCDIR)/config.h |
| 1810 | $(XTCC) -o $(OBJDIR)/stat.o -c $(OBJDIR)/stat_.c |
| 1811 | |
| 1812 | $(OBJDIR)/stat.h: $(OBJDIR)/headers |
| 1813 | |
| 1814 | $(OBJDIR)/statrep_.c: $(SRCDIR)/statrep.c $(TRANSLATE) |
| 1815 | $(TRANSLATE) $(SRCDIR)/statrep.c >$@ |
| 1816 | |
| 1817 | $(OBJDIR)/statrep.o: $(OBJDIR)/statrep_.c $(OBJDIR)/statrep.h $(SRCDIR)/config.h |
| 1818 | $(XTCC) -o $(OBJDIR)/statrep.o -c $(OBJDIR)/statrep_.c |
| 1819 | |
| 1820 | $(OBJDIR)/statrep.h: $(OBJDIR)/headers |
| 1821 | |
| 1822 | $(OBJDIR)/style_.c: $(SRCDIR)/style.c $(TRANSLATE) |
| 1823 | $(TRANSLATE) $(SRCDIR)/style.c >$@ |
| 1824 | |
| 1825 | $(OBJDIR)/style.o: $(OBJDIR)/style_.c $(OBJDIR)/style.h $(SRCDIR)/config.h |
| 1826 |
+18
-2
| --- win/Makefile.mingw.mistachkin | ||
| +++ win/Makefile.mingw.mistachkin | ||
| @@ -457,10 +457,11 @@ | ||
| 457 | 457 | $(SRCDIR)/sitemap.c \ |
| 458 | 458 | $(SRCDIR)/skins.c \ |
| 459 | 459 | $(SRCDIR)/sqlcmd.c \ |
| 460 | 460 | $(SRCDIR)/stash.c \ |
| 461 | 461 | $(SRCDIR)/stat.c \ |
| 462 | + $(SRCDIR)/statrep.c \ | |
| 462 | 463 | $(SRCDIR)/style.c \ |
| 463 | 464 | $(SRCDIR)/sync.c \ |
| 464 | 465 | $(SRCDIR)/tag.c \ |
| 465 | 466 | $(SRCDIR)/tar.c \ |
| 466 | 467 | $(SRCDIR)/th_main.c \ |
| @@ -496,20 +497,24 @@ | ||
| 496 | 497 | $(SRCDIR)/../skins/eagle/footer.txt \ |
| 497 | 498 | $(SRCDIR)/../skins/eagle/header.txt \ |
| 498 | 499 | $(SRCDIR)/../skins/enhanced1/css.txt \ |
| 499 | 500 | $(SRCDIR)/../skins/enhanced1/footer.txt \ |
| 500 | 501 | $(SRCDIR)/../skins/enhanced1/header.txt \ |
| 502 | + $(SRCDIR)/../skins/etienne1/css.txt \ | |
| 503 | + $(SRCDIR)/../skins/etienne1/footer.txt \ | |
| 504 | + $(SRCDIR)/../skins/etienne1/header.txt \ | |
| 501 | 505 | $(SRCDIR)/../skins/khaki/css.txt \ |
| 502 | 506 | $(SRCDIR)/../skins/khaki/footer.txt \ |
| 503 | 507 | $(SRCDIR)/../skins/khaki/header.txt \ |
| 504 | 508 | $(SRCDIR)/../skins/plain_gray/css.txt \ |
| 505 | 509 | $(SRCDIR)/../skins/plain_gray/footer.txt \ |
| 506 | 510 | $(SRCDIR)/../skins/plain_gray/header.txt \ |
| 507 | 511 | $(SRCDIR)/../skins/rounded1/css.txt \ |
| 508 | 512 | $(SRCDIR)/../skins/rounded1/footer.txt \ |
| 509 | 513 | $(SRCDIR)/../skins/rounded1/header.txt \ |
| 510 | - $(SRCDIR)/diff.tcl | |
| 514 | + $(SRCDIR)/diff.tcl \ | |
| 515 | + $(SRCDIR)/markdown.md | |
| 511 | 516 | |
| 512 | 517 | TRANS_SRC = \ |
| 513 | 518 | $(OBJDIR)/add_.c \ |
| 514 | 519 | $(OBJDIR)/allrepo_.c \ |
| 515 | 520 | $(OBJDIR)/attach_.c \ |
| @@ -600,10 +605,11 @@ | ||
| 600 | 605 | $(OBJDIR)/sitemap_.c \ |
| 601 | 606 | $(OBJDIR)/skins_.c \ |
| 602 | 607 | $(OBJDIR)/sqlcmd_.c \ |
| 603 | 608 | $(OBJDIR)/stash_.c \ |
| 604 | 609 | $(OBJDIR)/stat_.c \ |
| 610 | + $(OBJDIR)/statrep_.c \ | |
| 605 | 611 | $(OBJDIR)/style_.c \ |
| 606 | 612 | $(OBJDIR)/sync_.c \ |
| 607 | 613 | $(OBJDIR)/tag_.c \ |
| 608 | 614 | $(OBJDIR)/tar_.c \ |
| 609 | 615 | $(OBJDIR)/th_main_.c \ |
| @@ -719,10 +725,11 @@ | ||
| 719 | 725 | $(OBJDIR)/sitemap.o \ |
| 720 | 726 | $(OBJDIR)/skins.o \ |
| 721 | 727 | $(OBJDIR)/sqlcmd.o \ |
| 722 | 728 | $(OBJDIR)/stash.o \ |
| 723 | 729 | $(OBJDIR)/stat.o \ |
| 730 | + $(OBJDIR)/statrep.o \ | |
| 724 | 731 | $(OBJDIR)/style.o \ |
| 725 | 732 | $(OBJDIR)/sync.o \ |
| 726 | 733 | $(OBJDIR)/tag.o \ |
| 727 | 734 | $(OBJDIR)/tar.o \ |
| 728 | 735 | $(OBJDIR)/th_main.o \ |
| @@ -936,11 +943,11 @@ | ||
| 936 | 943 | |
| 937 | 944 | $(OBJDIR)/page_index.h: $(TRANS_SRC) $(MKINDEX) |
| 938 | 945 | $(MKINDEX) $(TRANS_SRC) >$@ |
| 939 | 946 | |
| 940 | 947 | $(OBJDIR)/builtin_data.h: $(MKBUILTIN) $(EXTRA_FILES) |
| 941 | - $(MKBUILTIN) $(EXTRA_FILES) >$@ | |
| 948 | + $(MKBUILTIN) --prefix $(SRCDIR)/ $(EXTRA_FILES) >$@ | |
| 942 | 949 | |
| 943 | 950 | $(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/builtin_data.h $(MAKEHEADERS) $(OBJDIR)/VERSION.h |
| 944 | 951 | $(MAKEHEADERS) $(OBJDIR)/add_.c:$(OBJDIR)/add.h \ |
| 945 | 952 | $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h \ |
| 946 | 953 | $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h \ |
| @@ -1031,10 +1038,11 @@ | ||
| 1031 | 1038 | $(OBJDIR)/sitemap_.c:$(OBJDIR)/sitemap.h \ |
| 1032 | 1039 | $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h \ |
| 1033 | 1040 | $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h \ |
| 1034 | 1041 | $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h \ |
| 1035 | 1042 | $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h \ |
| 1043 | + $(OBJDIR)/statrep_.c:$(OBJDIR)/statrep.h \ | |
| 1036 | 1044 | $(OBJDIR)/style_.c:$(OBJDIR)/style.h \ |
| 1037 | 1045 | $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h \ |
| 1038 | 1046 | $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h \ |
| 1039 | 1047 | $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h \ |
| 1040 | 1048 | $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h \ |
| @@ -1800,10 +1808,18 @@ | ||
| 1800 | 1808 | |
| 1801 | 1809 | $(OBJDIR)/stat.o: $(OBJDIR)/stat_.c $(OBJDIR)/stat.h $(SRCDIR)/config.h |
| 1802 | 1810 | $(XTCC) -o $(OBJDIR)/stat.o -c $(OBJDIR)/stat_.c |
| 1803 | 1811 | |
| 1804 | 1812 | $(OBJDIR)/stat.h: $(OBJDIR)/headers |
| 1813 | + | |
| 1814 | +$(OBJDIR)/statrep_.c: $(SRCDIR)/statrep.c $(TRANSLATE) | |
| 1815 | + $(TRANSLATE) $(SRCDIR)/statrep.c >$@ | |
| 1816 | + | |
| 1817 | +$(OBJDIR)/statrep.o: $(OBJDIR)/statrep_.c $(OBJDIR)/statrep.h $(SRCDIR)/config.h | |
| 1818 | + $(XTCC) -o $(OBJDIR)/statrep.o -c $(OBJDIR)/statrep_.c | |
| 1819 | + | |
| 1820 | +$(OBJDIR)/statrep.h: $(OBJDIR)/headers | |
| 1805 | 1821 | |
| 1806 | 1822 | $(OBJDIR)/style_.c: $(SRCDIR)/style.c $(TRANSLATE) |
| 1807 | 1823 | $(TRANSLATE) $(SRCDIR)/style.c >$@ |
| 1808 | 1824 | |
| 1809 | 1825 | $(OBJDIR)/style.o: $(OBJDIR)/style_.c $(OBJDIR)/style.h $(SRCDIR)/config.h |
| 1810 | 1826 |
| --- win/Makefile.mingw.mistachkin | |
| +++ win/Makefile.mingw.mistachkin | |
| @@ -457,10 +457,11 @@ | |
| 457 | $(SRCDIR)/sitemap.c \ |
| 458 | $(SRCDIR)/skins.c \ |
| 459 | $(SRCDIR)/sqlcmd.c \ |
| 460 | $(SRCDIR)/stash.c \ |
| 461 | $(SRCDIR)/stat.c \ |
| 462 | $(SRCDIR)/style.c \ |
| 463 | $(SRCDIR)/sync.c \ |
| 464 | $(SRCDIR)/tag.c \ |
| 465 | $(SRCDIR)/tar.c \ |
| 466 | $(SRCDIR)/th_main.c \ |
| @@ -496,20 +497,24 @@ | |
| 496 | $(SRCDIR)/../skins/eagle/footer.txt \ |
| 497 | $(SRCDIR)/../skins/eagle/header.txt \ |
| 498 | $(SRCDIR)/../skins/enhanced1/css.txt \ |
| 499 | $(SRCDIR)/../skins/enhanced1/footer.txt \ |
| 500 | $(SRCDIR)/../skins/enhanced1/header.txt \ |
| 501 | $(SRCDIR)/../skins/khaki/css.txt \ |
| 502 | $(SRCDIR)/../skins/khaki/footer.txt \ |
| 503 | $(SRCDIR)/../skins/khaki/header.txt \ |
| 504 | $(SRCDIR)/../skins/plain_gray/css.txt \ |
| 505 | $(SRCDIR)/../skins/plain_gray/footer.txt \ |
| 506 | $(SRCDIR)/../skins/plain_gray/header.txt \ |
| 507 | $(SRCDIR)/../skins/rounded1/css.txt \ |
| 508 | $(SRCDIR)/../skins/rounded1/footer.txt \ |
| 509 | $(SRCDIR)/../skins/rounded1/header.txt \ |
| 510 | $(SRCDIR)/diff.tcl |
| 511 | |
| 512 | TRANS_SRC = \ |
| 513 | $(OBJDIR)/add_.c \ |
| 514 | $(OBJDIR)/allrepo_.c \ |
| 515 | $(OBJDIR)/attach_.c \ |
| @@ -600,10 +605,11 @@ | |
| 600 | $(OBJDIR)/sitemap_.c \ |
| 601 | $(OBJDIR)/skins_.c \ |
| 602 | $(OBJDIR)/sqlcmd_.c \ |
| 603 | $(OBJDIR)/stash_.c \ |
| 604 | $(OBJDIR)/stat_.c \ |
| 605 | $(OBJDIR)/style_.c \ |
| 606 | $(OBJDIR)/sync_.c \ |
| 607 | $(OBJDIR)/tag_.c \ |
| 608 | $(OBJDIR)/tar_.c \ |
| 609 | $(OBJDIR)/th_main_.c \ |
| @@ -719,10 +725,11 @@ | |
| 719 | $(OBJDIR)/sitemap.o \ |
| 720 | $(OBJDIR)/skins.o \ |
| 721 | $(OBJDIR)/sqlcmd.o \ |
| 722 | $(OBJDIR)/stash.o \ |
| 723 | $(OBJDIR)/stat.o \ |
| 724 | $(OBJDIR)/style.o \ |
| 725 | $(OBJDIR)/sync.o \ |
| 726 | $(OBJDIR)/tag.o \ |
| 727 | $(OBJDIR)/tar.o \ |
| 728 | $(OBJDIR)/th_main.o \ |
| @@ -936,11 +943,11 @@ | |
| 936 | |
| 937 | $(OBJDIR)/page_index.h: $(TRANS_SRC) $(MKINDEX) |
| 938 | $(MKINDEX) $(TRANS_SRC) >$@ |
| 939 | |
| 940 | $(OBJDIR)/builtin_data.h: $(MKBUILTIN) $(EXTRA_FILES) |
| 941 | $(MKBUILTIN) $(EXTRA_FILES) >$@ |
| 942 | |
| 943 | $(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/builtin_data.h $(MAKEHEADERS) $(OBJDIR)/VERSION.h |
| 944 | $(MAKEHEADERS) $(OBJDIR)/add_.c:$(OBJDIR)/add.h \ |
| 945 | $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h \ |
| 946 | $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h \ |
| @@ -1031,10 +1038,11 @@ | |
| 1031 | $(OBJDIR)/sitemap_.c:$(OBJDIR)/sitemap.h \ |
| 1032 | $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h \ |
| 1033 | $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h \ |
| 1034 | $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h \ |
| 1035 | $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h \ |
| 1036 | $(OBJDIR)/style_.c:$(OBJDIR)/style.h \ |
| 1037 | $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h \ |
| 1038 | $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h \ |
| 1039 | $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h \ |
| 1040 | $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h \ |
| @@ -1800,10 +1808,18 @@ | |
| 1800 | |
| 1801 | $(OBJDIR)/stat.o: $(OBJDIR)/stat_.c $(OBJDIR)/stat.h $(SRCDIR)/config.h |
| 1802 | $(XTCC) -o $(OBJDIR)/stat.o -c $(OBJDIR)/stat_.c |
| 1803 | |
| 1804 | $(OBJDIR)/stat.h: $(OBJDIR)/headers |
| 1805 | |
| 1806 | $(OBJDIR)/style_.c: $(SRCDIR)/style.c $(TRANSLATE) |
| 1807 | $(TRANSLATE) $(SRCDIR)/style.c >$@ |
| 1808 | |
| 1809 | $(OBJDIR)/style.o: $(OBJDIR)/style_.c $(OBJDIR)/style.h $(SRCDIR)/config.h |
| 1810 |
| --- win/Makefile.mingw.mistachkin | |
| +++ win/Makefile.mingw.mistachkin | |
| @@ -457,10 +457,11 @@ | |
| 457 | $(SRCDIR)/sitemap.c \ |
| 458 | $(SRCDIR)/skins.c \ |
| 459 | $(SRCDIR)/sqlcmd.c \ |
| 460 | $(SRCDIR)/stash.c \ |
| 461 | $(SRCDIR)/stat.c \ |
| 462 | $(SRCDIR)/statrep.c \ |
| 463 | $(SRCDIR)/style.c \ |
| 464 | $(SRCDIR)/sync.c \ |
| 465 | $(SRCDIR)/tag.c \ |
| 466 | $(SRCDIR)/tar.c \ |
| 467 | $(SRCDIR)/th_main.c \ |
| @@ -496,20 +497,24 @@ | |
| 497 | $(SRCDIR)/../skins/eagle/footer.txt \ |
| 498 | $(SRCDIR)/../skins/eagle/header.txt \ |
| 499 | $(SRCDIR)/../skins/enhanced1/css.txt \ |
| 500 | $(SRCDIR)/../skins/enhanced1/footer.txt \ |
| 501 | $(SRCDIR)/../skins/enhanced1/header.txt \ |
| 502 | $(SRCDIR)/../skins/etienne1/css.txt \ |
| 503 | $(SRCDIR)/../skins/etienne1/footer.txt \ |
| 504 | $(SRCDIR)/../skins/etienne1/header.txt \ |
| 505 | $(SRCDIR)/../skins/khaki/css.txt \ |
| 506 | $(SRCDIR)/../skins/khaki/footer.txt \ |
| 507 | $(SRCDIR)/../skins/khaki/header.txt \ |
| 508 | $(SRCDIR)/../skins/plain_gray/css.txt \ |
| 509 | $(SRCDIR)/../skins/plain_gray/footer.txt \ |
| 510 | $(SRCDIR)/../skins/plain_gray/header.txt \ |
| 511 | $(SRCDIR)/../skins/rounded1/css.txt \ |
| 512 | $(SRCDIR)/../skins/rounded1/footer.txt \ |
| 513 | $(SRCDIR)/../skins/rounded1/header.txt \ |
| 514 | $(SRCDIR)/diff.tcl \ |
| 515 | $(SRCDIR)/markdown.md |
| 516 | |
| 517 | TRANS_SRC = \ |
| 518 | $(OBJDIR)/add_.c \ |
| 519 | $(OBJDIR)/allrepo_.c \ |
| 520 | $(OBJDIR)/attach_.c \ |
| @@ -600,10 +605,11 @@ | |
| 605 | $(OBJDIR)/sitemap_.c \ |
| 606 | $(OBJDIR)/skins_.c \ |
| 607 | $(OBJDIR)/sqlcmd_.c \ |
| 608 | $(OBJDIR)/stash_.c \ |
| 609 | $(OBJDIR)/stat_.c \ |
| 610 | $(OBJDIR)/statrep_.c \ |
| 611 | $(OBJDIR)/style_.c \ |
| 612 | $(OBJDIR)/sync_.c \ |
| 613 | $(OBJDIR)/tag_.c \ |
| 614 | $(OBJDIR)/tar_.c \ |
| 615 | $(OBJDIR)/th_main_.c \ |
| @@ -719,10 +725,11 @@ | |
| 725 | $(OBJDIR)/sitemap.o \ |
| 726 | $(OBJDIR)/skins.o \ |
| 727 | $(OBJDIR)/sqlcmd.o \ |
| 728 | $(OBJDIR)/stash.o \ |
| 729 | $(OBJDIR)/stat.o \ |
| 730 | $(OBJDIR)/statrep.o \ |
| 731 | $(OBJDIR)/style.o \ |
| 732 | $(OBJDIR)/sync.o \ |
| 733 | $(OBJDIR)/tag.o \ |
| 734 | $(OBJDIR)/tar.o \ |
| 735 | $(OBJDIR)/th_main.o \ |
| @@ -936,11 +943,11 @@ | |
| 943 | |
| 944 | $(OBJDIR)/page_index.h: $(TRANS_SRC) $(MKINDEX) |
| 945 | $(MKINDEX) $(TRANS_SRC) >$@ |
| 946 | |
| 947 | $(OBJDIR)/builtin_data.h: $(MKBUILTIN) $(EXTRA_FILES) |
| 948 | $(MKBUILTIN) --prefix $(SRCDIR)/ $(EXTRA_FILES) >$@ |
| 949 | |
| 950 | $(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/builtin_data.h $(MAKEHEADERS) $(OBJDIR)/VERSION.h |
| 951 | $(MAKEHEADERS) $(OBJDIR)/add_.c:$(OBJDIR)/add.h \ |
| 952 | $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h \ |
| 953 | $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h \ |
| @@ -1031,10 +1038,11 @@ | |
| 1038 | $(OBJDIR)/sitemap_.c:$(OBJDIR)/sitemap.h \ |
| 1039 | $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h \ |
| 1040 | $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h \ |
| 1041 | $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h \ |
| 1042 | $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h \ |
| 1043 | $(OBJDIR)/statrep_.c:$(OBJDIR)/statrep.h \ |
| 1044 | $(OBJDIR)/style_.c:$(OBJDIR)/style.h \ |
| 1045 | $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h \ |
| 1046 | $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h \ |
| 1047 | $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h \ |
| 1048 | $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h \ |
| @@ -1800,10 +1808,18 @@ | |
| 1808 | |
| 1809 | $(OBJDIR)/stat.o: $(OBJDIR)/stat_.c $(OBJDIR)/stat.h $(SRCDIR)/config.h |
| 1810 | $(XTCC) -o $(OBJDIR)/stat.o -c $(OBJDIR)/stat_.c |
| 1811 | |
| 1812 | $(OBJDIR)/stat.h: $(OBJDIR)/headers |
| 1813 | |
| 1814 | $(OBJDIR)/statrep_.c: $(SRCDIR)/statrep.c $(TRANSLATE) |
| 1815 | $(TRANSLATE) $(SRCDIR)/statrep.c >$@ |
| 1816 | |
| 1817 | $(OBJDIR)/statrep.o: $(OBJDIR)/statrep_.c $(OBJDIR)/statrep.h $(SRCDIR)/config.h |
| 1818 | $(XTCC) -o $(OBJDIR)/statrep.o -c $(OBJDIR)/statrep_.c |
| 1819 | |
| 1820 | $(OBJDIR)/statrep.h: $(OBJDIR)/headers |
| 1821 | |
| 1822 | $(OBJDIR)/style_.c: $(SRCDIR)/style.c $(TRANSLATE) |
| 1823 | $(TRANSLATE) $(SRCDIR)/style.c >$@ |
| 1824 | |
| 1825 | $(OBJDIR)/style.o: $(OBJDIR)/style_.c $(OBJDIR)/style.h $(SRCDIR)/config.h |
| 1826 |
+13
-2
| --- win/Makefile.msc | ||
| +++ win/Makefile.msc | ||
| @@ -296,10 +296,11 @@ | ||
| 296 | 296 | sitemap_.c \ |
| 297 | 297 | skins_.c \ |
| 298 | 298 | sqlcmd_.c \ |
| 299 | 299 | stash_.c \ |
| 300 | 300 | stat_.c \ |
| 301 | + statrep_.c \ | |
| 301 | 302 | style_.c \ |
| 302 | 303 | sync_.c \ |
| 303 | 304 | tag_.c \ |
| 304 | 305 | tar_.c \ |
| 305 | 306 | th_main_.c \ |
| @@ -346,11 +347,12 @@ | ||
| 346 | 347 | $(SRCDIR)\../skins/plain_gray/footer.txt \ |
| 347 | 348 | $(SRCDIR)\../skins/plain_gray/header.txt \ |
| 348 | 349 | $(SRCDIR)\../skins/rounded1/css.txt \ |
| 349 | 350 | $(SRCDIR)\../skins/rounded1/footer.txt \ |
| 350 | 351 | $(SRCDIR)\../skins/rounded1/header.txt \ |
| 351 | - $(SRCDIR)\diff.tcl | |
| 352 | + $(SRCDIR)\diff.tcl \ | |
| 353 | + $(SRCDIR)\markdown.md | |
| 352 | 354 | |
| 353 | 355 | OBJ = $(OX)\add$O \ |
| 354 | 356 | $(OX)\allrepo$O \ |
| 355 | 357 | $(OX)\attach$O \ |
| 356 | 358 | $(OX)\bag$O \ |
| @@ -443,10 +445,11 @@ | ||
| 443 | 445 | $(OX)\skins$O \ |
| 444 | 446 | $(OX)\sqlcmd$O \ |
| 445 | 447 | $(OX)\sqlite3$O \ |
| 446 | 448 | $(OX)\stash$O \ |
| 447 | 449 | $(OX)\stat$O \ |
| 450 | + $(OX)\statrep$O \ | |
| 448 | 451 | $(OX)\style$O \ |
| 449 | 452 | $(OX)\sync$O \ |
| 450 | 453 | $(OX)\tag$O \ |
| 451 | 454 | $(OX)\tar$O \ |
| 452 | 455 | $(OX)\th$O \ |
| @@ -617,10 +620,11 @@ | ||
| 617 | 620 | echo $(OX)\skins.obj >> $@ |
| 618 | 621 | echo $(OX)\sqlcmd.obj >> $@ |
| 619 | 622 | echo $(OX)\sqlite3.obj >> $@ |
| 620 | 623 | echo $(OX)\stash.obj >> $@ |
| 621 | 624 | echo $(OX)\stat.obj >> $@ |
| 625 | + echo $(OX)\statrep.obj >> $@ | |
| 622 | 626 | echo $(OX)\style.obj >> $@ |
| 623 | 627 | echo $(OX)\sync.obj >> $@ |
| 624 | 628 | echo $(OX)\tag.obj >> $@ |
| 625 | 629 | echo $(OX)\tar.obj >> $@ |
| 626 | 630 | echo $(OX)\th.obj >> $@ |
| @@ -698,11 +702,11 @@ | ||
| 698 | 702 | |
| 699 | 703 | page_index.h: mkindex$E $(SRC) |
| 700 | 704 | $** > $@ |
| 701 | 705 | |
| 702 | 706 | builtin_data.h: mkbuiltin$E $(EXTRA_FILES) |
| 703 | - $** > $@ | |
| 707 | + mkbuiltin$E --prefix $(SRCDIR)/ $(EXTRA_FILES) > $@ | |
| 704 | 708 | |
| 705 | 709 | clean: |
| 706 | 710 | -del $(OX)\*.obj |
| 707 | 711 | -del *.obj |
| 708 | 712 | -del *_.c |
| @@ -1295,10 +1299,16 @@ | ||
| 1295 | 1299 | $(OX)\stat$O : stat_.c stat.h |
| 1296 | 1300 | $(TCC) /Fo$@ -c stat_.c |
| 1297 | 1301 | |
| 1298 | 1302 | stat_.c : $(SRCDIR)\stat.c |
| 1299 | 1303 | translate$E $** > $@ |
| 1304 | + | |
| 1305 | +$(OX)\statrep$O : statrep_.c statrep.h | |
| 1306 | + $(TCC) /Fo$@ -c statrep_.c | |
| 1307 | + | |
| 1308 | +statrep_.c : $(SRCDIR)\statrep.c | |
| 1309 | + translate$E $** > $@ | |
| 1300 | 1310 | |
| 1301 | 1311 | $(OX)\style$O : style_.c style.h |
| 1302 | 1312 | $(TCC) /Fo$@ -c style_.c |
| 1303 | 1313 | |
| 1304 | 1314 | style_.c : $(SRCDIR)\style.c |
| @@ -1542,10 +1552,11 @@ | ||
| 1542 | 1552 | sitemap_.c:sitemap.h \ |
| 1543 | 1553 | skins_.c:skins.h \ |
| 1544 | 1554 | sqlcmd_.c:sqlcmd.h \ |
| 1545 | 1555 | stash_.c:stash.h \ |
| 1546 | 1556 | stat_.c:stat.h \ |
| 1557 | + statrep_.c:statrep.h \ | |
| 1547 | 1558 | style_.c:style.h \ |
| 1548 | 1559 | sync_.c:sync.h \ |
| 1549 | 1560 | tag_.c:tag.h \ |
| 1550 | 1561 | tar_.c:tar.h \ |
| 1551 | 1562 | th_main_.c:th_main.h \ |
| 1552 | 1563 |
| --- win/Makefile.msc | |
| +++ win/Makefile.msc | |
| @@ -296,10 +296,11 @@ | |
| 296 | sitemap_.c \ |
| 297 | skins_.c \ |
| 298 | sqlcmd_.c \ |
| 299 | stash_.c \ |
| 300 | stat_.c \ |
| 301 | style_.c \ |
| 302 | sync_.c \ |
| 303 | tag_.c \ |
| 304 | tar_.c \ |
| 305 | th_main_.c \ |
| @@ -346,11 +347,12 @@ | |
| 346 | $(SRCDIR)\../skins/plain_gray/footer.txt \ |
| 347 | $(SRCDIR)\../skins/plain_gray/header.txt \ |
| 348 | $(SRCDIR)\../skins/rounded1/css.txt \ |
| 349 | $(SRCDIR)\../skins/rounded1/footer.txt \ |
| 350 | $(SRCDIR)\../skins/rounded1/header.txt \ |
| 351 | $(SRCDIR)\diff.tcl |
| 352 | |
| 353 | OBJ = $(OX)\add$O \ |
| 354 | $(OX)\allrepo$O \ |
| 355 | $(OX)\attach$O \ |
| 356 | $(OX)\bag$O \ |
| @@ -443,10 +445,11 @@ | |
| 443 | $(OX)\skins$O \ |
| 444 | $(OX)\sqlcmd$O \ |
| 445 | $(OX)\sqlite3$O \ |
| 446 | $(OX)\stash$O \ |
| 447 | $(OX)\stat$O \ |
| 448 | $(OX)\style$O \ |
| 449 | $(OX)\sync$O \ |
| 450 | $(OX)\tag$O \ |
| 451 | $(OX)\tar$O \ |
| 452 | $(OX)\th$O \ |
| @@ -617,10 +620,11 @@ | |
| 617 | echo $(OX)\skins.obj >> $@ |
| 618 | echo $(OX)\sqlcmd.obj >> $@ |
| 619 | echo $(OX)\sqlite3.obj >> $@ |
| 620 | echo $(OX)\stash.obj >> $@ |
| 621 | echo $(OX)\stat.obj >> $@ |
| 622 | echo $(OX)\style.obj >> $@ |
| 623 | echo $(OX)\sync.obj >> $@ |
| 624 | echo $(OX)\tag.obj >> $@ |
| 625 | echo $(OX)\tar.obj >> $@ |
| 626 | echo $(OX)\th.obj >> $@ |
| @@ -698,11 +702,11 @@ | |
| 698 | |
| 699 | page_index.h: mkindex$E $(SRC) |
| 700 | $** > $@ |
| 701 | |
| 702 | builtin_data.h: mkbuiltin$E $(EXTRA_FILES) |
| 703 | $** > $@ |
| 704 | |
| 705 | clean: |
| 706 | -del $(OX)\*.obj |
| 707 | -del *.obj |
| 708 | -del *_.c |
| @@ -1295,10 +1299,16 @@ | |
| 1295 | $(OX)\stat$O : stat_.c stat.h |
| 1296 | $(TCC) /Fo$@ -c stat_.c |
| 1297 | |
| 1298 | stat_.c : $(SRCDIR)\stat.c |
| 1299 | translate$E $** > $@ |
| 1300 | |
| 1301 | $(OX)\style$O : style_.c style.h |
| 1302 | $(TCC) /Fo$@ -c style_.c |
| 1303 | |
| 1304 | style_.c : $(SRCDIR)\style.c |
| @@ -1542,10 +1552,11 @@ | |
| 1542 | sitemap_.c:sitemap.h \ |
| 1543 | skins_.c:skins.h \ |
| 1544 | sqlcmd_.c:sqlcmd.h \ |
| 1545 | stash_.c:stash.h \ |
| 1546 | stat_.c:stat.h \ |
| 1547 | style_.c:style.h \ |
| 1548 | sync_.c:sync.h \ |
| 1549 | tag_.c:tag.h \ |
| 1550 | tar_.c:tar.h \ |
| 1551 | th_main_.c:th_main.h \ |
| 1552 |
| --- win/Makefile.msc | |
| +++ win/Makefile.msc | |
| @@ -296,10 +296,11 @@ | |
| 296 | sitemap_.c \ |
| 297 | skins_.c \ |
| 298 | sqlcmd_.c \ |
| 299 | stash_.c \ |
| 300 | stat_.c \ |
| 301 | statrep_.c \ |
| 302 | style_.c \ |
| 303 | sync_.c \ |
| 304 | tag_.c \ |
| 305 | tar_.c \ |
| 306 | th_main_.c \ |
| @@ -346,11 +347,12 @@ | |
| 347 | $(SRCDIR)\../skins/plain_gray/footer.txt \ |
| 348 | $(SRCDIR)\../skins/plain_gray/header.txt \ |
| 349 | $(SRCDIR)\../skins/rounded1/css.txt \ |
| 350 | $(SRCDIR)\../skins/rounded1/footer.txt \ |
| 351 | $(SRCDIR)\../skins/rounded1/header.txt \ |
| 352 | $(SRCDIR)\diff.tcl \ |
| 353 | $(SRCDIR)\markdown.md |
| 354 | |
| 355 | OBJ = $(OX)\add$O \ |
| 356 | $(OX)\allrepo$O \ |
| 357 | $(OX)\attach$O \ |
| 358 | $(OX)\bag$O \ |
| @@ -443,10 +445,11 @@ | |
| 445 | $(OX)\skins$O \ |
| 446 | $(OX)\sqlcmd$O \ |
| 447 | $(OX)\sqlite3$O \ |
| 448 | $(OX)\stash$O \ |
| 449 | $(OX)\stat$O \ |
| 450 | $(OX)\statrep$O \ |
| 451 | $(OX)\style$O \ |
| 452 | $(OX)\sync$O \ |
| 453 | $(OX)\tag$O \ |
| 454 | $(OX)\tar$O \ |
| 455 | $(OX)\th$O \ |
| @@ -617,10 +620,11 @@ | |
| 620 | echo $(OX)\skins.obj >> $@ |
| 621 | echo $(OX)\sqlcmd.obj >> $@ |
| 622 | echo $(OX)\sqlite3.obj >> $@ |
| 623 | echo $(OX)\stash.obj >> $@ |
| 624 | echo $(OX)\stat.obj >> $@ |
| 625 | echo $(OX)\statrep.obj >> $@ |
| 626 | echo $(OX)\style.obj >> $@ |
| 627 | echo $(OX)\sync.obj >> $@ |
| 628 | echo $(OX)\tag.obj >> $@ |
| 629 | echo $(OX)\tar.obj >> $@ |
| 630 | echo $(OX)\th.obj >> $@ |
| @@ -698,11 +702,11 @@ | |
| 702 | |
| 703 | page_index.h: mkindex$E $(SRC) |
| 704 | $** > $@ |
| 705 | |
| 706 | builtin_data.h: mkbuiltin$E $(EXTRA_FILES) |
| 707 | mkbuiltin$E --prefix $(SRCDIR)/ $(EXTRA_FILES) > $@ |
| 708 | |
| 709 | clean: |
| 710 | -del $(OX)\*.obj |
| 711 | -del *.obj |
| 712 | -del *_.c |
| @@ -1295,10 +1299,16 @@ | |
| 1299 | $(OX)\stat$O : stat_.c stat.h |
| 1300 | $(TCC) /Fo$@ -c stat_.c |
| 1301 | |
| 1302 | stat_.c : $(SRCDIR)\stat.c |
| 1303 | translate$E $** > $@ |
| 1304 | |
| 1305 | $(OX)\statrep$O : statrep_.c statrep.h |
| 1306 | $(TCC) /Fo$@ -c statrep_.c |
| 1307 | |
| 1308 | statrep_.c : $(SRCDIR)\statrep.c |
| 1309 | translate$E $** > $@ |
| 1310 | |
| 1311 | $(OX)\style$O : style_.c style.h |
| 1312 | $(TCC) /Fo$@ -c style_.c |
| 1313 | |
| 1314 | style_.c : $(SRCDIR)\style.c |
| @@ -1542,10 +1552,11 @@ | |
| 1552 | sitemap_.c:sitemap.h \ |
| 1553 | skins_.c:skins.h \ |
| 1554 | sqlcmd_.c:sqlcmd.h \ |
| 1555 | stash_.c:stash.h \ |
| 1556 | stat_.c:stat.h \ |
| 1557 | statrep_.c:statrep.h \ |
| 1558 | style_.c:style.h \ |
| 1559 | sync_.c:sync.h \ |
| 1560 | tag_.c:tag.h \ |
| 1561 | tar_.c:tar.h \ |
| 1562 | th_main_.c:th_main.h \ |
| 1563 |