Fossil SCM
Merge the json branch into trunk. Json is disabled by default for now. Use the --json option to configure, or set FOSSIL_ENABLE_JSON in the makefile to turn json processing on.
Commit
796dcfe0728bb2bc865db84e50432f0205d1d2fd
Parent
bf1ebbe1f647710…
47 files changed
+38
+2
+208
+140
+1
+300
+476
+70
+3
+5
+5
+2
+27
+10
-6
+3
-1
+142
-17
+645
+9
+39
-5
+39
-5
+59
+4
+11
+69
+27
+41
+31
+1
+1
+20
+125
+57
+207
-77
+209
-42
+209
-42
+117
-2
+117
-2
+60
-4
+60
-4
+5
-1
+4
+22
-20
+2
-4
+24
-7
+86
-4
+116
-2
+94
-3
~
ajax/README
~
ajax/cgi-bin/fossil-json.cgi.example
~
ajax/i-test/rhino-shell.js
~
ajax/i-test/rhino-test.js
~
ajax/index.html
~
ajax/js/fossil-ajaj.js
~
ajax/js/json2.js
~
ajax/js/whajaj.js
~
ajax/wiki-editor.html
~
auto.def
~
auto.def
~
src/Makefile
~
src/blob.c
~
src/branch.c
~
src/captcha.c
~
src/cgi.c
~
src/cson_amalgamation.c
~
src/cson_amalgamation.h
~
src/db.c
~
src/db.c
~
src/json.c
~
src/json_artifact.c
~
src/json_branch.c
~
src/json_detail.h
~
src/json_diff.c
~
src/json_login.c
~
src/json_query.c
~
src/json_report.c
~
src/json_tag.c
~
src/json_timeline.c
~
src/json_user.c
~
src/json_wiki.c
~
src/login.c
~
src/main.c
~
src/main.c
~
src/main.mk
~
src/main.mk
~
src/makemake.tcl
~
src/makemake.tcl
~
src/name.c
~
src/report.c
~
src/timeline.c
~
src/tkt.c
~
src/wiki.c
~
win/Makefile.dmc
~
win/Makefile.mingw
~
win/Makefile.msc
+38
| --- a/ajax/README | ||
| +++ b/ajax/README | ||
| @@ -0,0 +1,38 @@ | ||
| 1 | +This is the README for how to set up the Fossil/JSON test web page | |
| 2 | +under Apache on Unix systems. This is only intended only for | |
| 3 | +Fossil/JSON developers/tinkerers: | |
| 4 | + | |
| 5 | +First, copy cgi-bin/fossil-json.cgi.example to | |
| 6 | +cgi-bin/fossil-json.cgi. Edit it and correct the paths to the fossil | |
| 7 | +binary and the repo you want to serve. Make it executable. | |
| 8 | + | |
| 9 | +MAKE SURE that the fossil repo you use is world-writable OR that your | |
| 10 | +Web/CGI server is set up to run as the user ID of the owner of the | |
| 11 | +fossil file. ALSO: the DIRECTORY CONTAINING the repo file must be | |
| 12 | +writable by the CGI process. | |
| 13 | + | |
| 14 | +Next, set up an apache vhost entry. Mine looks like: | |
| 15 | + | |
| 16 | +<VirtualHost *:80> | |
| 17 | + ServerAlias fjson | |
| 18 | + ScriptAlias /cgi-bin/ /home/stephan/cvs/fossil/fossil-json/ajax/cgi-bin/ | |
| 19 | + DocumentRoot /home/stephan/cvs/fossil/fossil-json/ajax | |
| 20 | +</VirtualHost> | |
| 21 | + | |
| 22 | +Now add your preferred vhost name (fjson in the above example) to /etc/hosts: | |
| 23 | + | |
| 24 | + 127.0.0.1 ...other aliases... fjson | |
| 25 | + | |
| 26 | +Restart your Apache. | |
| 27 | + | |
| 28 | +Now visit: http://fjson/ | |
| 29 | + | |
| 30 | +that will show the test/demo page. If it doesn't, edit index.html and | |
| 31 | +make sure that: | |
| 32 | + | |
| 33 | + WhAjaj.Connector.options.ajax.url = ...; | |
| 34 | + | |
| 35 | +points to your CGI script. In theory you can also do this over fossil | |
| 36 | +standalone server mode, but i haven't yet tested that particular test | |
| 37 | +page in that mode. | |
| 38 | + |
| --- a/ajax/README | |
| +++ b/ajax/README | |
| @@ -0,0 +1,38 @@ | |
| --- a/ajax/README | |
| +++ b/ajax/README | |
| @@ -0,0 +1,38 @@ | |
| 1 | This is the README for how to set up the Fossil/JSON test web page |
| 2 | under Apache on Unix systems. This is only intended only for |
| 3 | Fossil/JSON developers/tinkerers: |
| 4 | |
| 5 | First, copy cgi-bin/fossil-json.cgi.example to |
| 6 | cgi-bin/fossil-json.cgi. Edit it and correct the paths to the fossil |
| 7 | binary and the repo you want to serve. Make it executable. |
| 8 | |
| 9 | MAKE SURE that the fossil repo you use is world-writable OR that your |
| 10 | Web/CGI server is set up to run as the user ID of the owner of the |
| 11 | fossil file. ALSO: the DIRECTORY CONTAINING the repo file must be |
| 12 | writable by the CGI process. |
| 13 | |
| 14 | Next, set up an apache vhost entry. Mine looks like: |
| 15 | |
| 16 | <VirtualHost *:80> |
| 17 | ServerAlias fjson |
| 18 | ScriptAlias /cgi-bin/ /home/stephan/cvs/fossil/fossil-json/ajax/cgi-bin/ |
| 19 | DocumentRoot /home/stephan/cvs/fossil/fossil-json/ajax |
| 20 | </VirtualHost> |
| 21 | |
| 22 | Now add your preferred vhost name (fjson in the above example) to /etc/hosts: |
| 23 | |
| 24 | 127.0.0.1 ...other aliases... fjson |
| 25 | |
| 26 | Restart your Apache. |
| 27 | |
| 28 | Now visit: http://fjson/ |
| 29 | |
| 30 | that will show the test/demo page. If it doesn't, edit index.html and |
| 31 | make sure that: |
| 32 | |
| 33 | WhAjaj.Connector.options.ajax.url = ...; |
| 34 | |
| 35 | points to your CGI script. In theory you can also do this over fossil |
| 36 | standalone server mode, but i haven't yet tested that particular test |
| 37 | page in that mode. |
| 38 |
| --- a/ajax/cgi-bin/fossil-json.cgi.example | ||
| +++ b/ajax/cgi-bin/fossil-json.cgi.example | ||
| @@ -0,0 +1,2 @@ | ||
| 1 | +#!/path/to/fossil/binary | |
| 2 | +repository: /path/to/repo.fsl |
| --- a/ajax/cgi-bin/fossil-json.cgi.example | |
| +++ b/ajax/cgi-bin/fossil-json.cgi.example | |
| @@ -0,0 +1,2 @@ | |
| --- a/ajax/cgi-bin/fossil-json.cgi.example | |
| +++ b/ajax/cgi-bin/fossil-json.cgi.example | |
| @@ -0,0 +1,2 @@ | |
| 1 | #!/path/to/fossil/binary |
| 2 | repository: /path/to/repo.fsl |
+208
| --- a/ajax/i-test/rhino-shell.js | ||
| +++ b/ajax/i-test/rhino-shell.js | ||
| @@ -0,0 +1,208 @@ | ||
| 1 | +var FShell = { | |
| 2 | + serverUrl: | |
| 3 | + 'http://localhost:8080' | |
| 4 | + //'http://fjson/cgi-bin/fossil-json.cgi' | |
| 5 | + //'http://192.168.1.62:8080' | |
| 6 | + //'http://fossil.wanderinghorse.net/repos/fossil-json-java/index.cgi' | |
| 7 | + , | |
| 8 | + verbose:false, | |
| 9 | + prompt:"fossil shell > ", | |
| 10 | + wiki:{}, | |
| 11 | + consol:java.lang.System.console(), | |
| 12 | + v:function(msg){ | |
| 13 | + if(this.verbose){ | |
| 14 | + print("VERBOSE: "+msg); | |
| 15 | + } | |
| 16 | + } | |
| 17 | +}; | |
| 18 | +(function bootstrap() { | |
| 19 | + var srcdir = '../js/'; | |
| 20 | + var includes = [srcdir+'json2.js', | |
| 21 | + srcdir+'whajaj.js', | |
| 22 | + srcdir+'fossil-ajaj.js' | |
| 23 | + ]; | |
| 24 | + for( var i in includes ) { | |
| 25 | + load(includes[i]); | |
| 26 | + } | |
| 27 | + WhAjaj.Connector.prototype.sendImpl = WhAjaj.Connector.sendImpls.rhino; | |
| 28 | + FShell.fossil = new FossilAjaj({ | |
| 29 | + asynchronous:false, /* rhino-based impl doesn't support async. */ | |
| 30 | + timeout:10000, | |
| 31 | + url:FShell.serverUrl | |
| 32 | + }); | |
| 33 | + print("Server: "+FShell.serverUrl); | |
| 34 | + var cb = FShell.fossil.ajaj.callbacks; | |
| 35 | + cb.beforeSend = function(req,opt){ | |
| 36 | + if(!FShell.verbose) return; | |
| 37 | + print("SENDING REQUEST: AJAJ options="+JSON.stringify(opt)); | |
| 38 | + if(req) print("Request envelope="+WhAjaj.stringify(req)); | |
| 39 | + }; | |
| 40 | + cb.afterSend = function(req,opt){ | |
| 41 | + //if(!FShell.verbose) return; | |
| 42 | + //print("REQUEST RETURNED: opt="+JSON.stringify(opt)); | |
| 43 | + //if(req) print("Request="+WhAjaj.stringify(req)); | |
| 44 | + }; | |
| 45 | + cb.onError = function(req,opt){ | |
| 46 | + //if(!FShell.verbose) return; | |
| 47 | + print("ERROR: "+WhAjaj.stringify(opt)); | |
| 48 | + }; | |
| 49 | + cb.onResponse = function(resp,req){ | |
| 50 | + if(!FShell.verbose) return; | |
| 51 | + if(resp && resp.resultCode){ | |
| 52 | + print("Response contains error info: "+resp.resultCode+": "+resp.resultText); | |
| 53 | + } | |
| 54 | + print("GOT RESPONSE: "+(('string'===typeof resp) ? resp : WhAjaj.stringify(resp))); | |
| 55 | + }; | |
| 56 | + FShell.fossil.HAI({ | |
| 57 | + onResponse:function(resp,opt){ | |
| 58 | + assertResponseOK(resp); | |
| 59 | + } | |
| 60 | + }); | |
| 61 | +})(); | |
| 62 | + | |
| 63 | +/** | |
| 64 | + Throws an exception of cond is a falsy value. | |
| 65 | +*/ | |
| 66 | +function assert(cond, descr){ | |
| 67 | + descr = descr || "Undescribed condition."; | |
| 68 | + if(!cond){ | |
| 69 | + throw new Error("Assertion failed: "+descr); | |
| 70 | + }else{ | |
| 71 | + //print("Assertion OK: "+descr); | |
| 72 | + } | |
| 73 | +} | |
| 74 | + | |
| 75 | +/** | |
| 76 | + Convenience form of FShell.fossil.sendCommand(command,payload,ajajOpt). | |
| 77 | +*/ | |
| 78 | +function send(command,payload, ajajOpt){ | |
| 79 | + FShell.fossil.sendCommand(command,payload,ajajOpt); | |
| 80 | +} | |
| 81 | + | |
| 82 | +/** | |
| 83 | + Asserts that resp is-a Object, resp.fossil is-a string, and | |
| 84 | + !resp.resultCode. | |
| 85 | +*/ | |
| 86 | +function assertResponseOK(resp){ | |
| 87 | + assert('object' === typeof resp,'Response is-a object.'); | |
| 88 | + assert( 'string' === typeof resp.fossil, 'Response contains fossil property.'); | |
| 89 | + assert( !resp.resultCode, 'resp.resultCode='+resp.resultCode); | |
| 90 | +} | |
| 91 | +/** | |
| 92 | + Asserts that resp is-a Object, resp.fossil is-a string, and | |
| 93 | + resp.resultCode is a truthy value. If expectCode is set then | |
| 94 | + it also asserts that (resp.resultCode=='FOSSIL-'+expectCode). | |
| 95 | +*/ | |
| 96 | +function assertResponseError(resp,expectCode){ | |
| 97 | + assert('object' === typeof resp,'Response is-a object.'); | |
| 98 | + assert( 'string' === typeof resp.fossil, 'Response contains fossil property.'); | |
| 99 | + assert( resp.resultCode, 'resp.resultCode='+resp.resultCode); | |
| 100 | + if(expectCode){ | |
| 101 | + assert( 'FOSSIL-'+expectCode == resp.resultCode, 'Expecting result code '+expectCode ); | |
| 102 | + } | |
| 103 | +} | |
| 104 | + | |
| 105 | +FShell.readline = (typeof readline === 'function') ? (readline) : (function() { | |
| 106 | + importPackage(java.io); | |
| 107 | + importPackage(java.lang); | |
| 108 | + var stdin = new BufferedReader(new InputStreamReader(System['in'])); | |
| 109 | + var self = this; | |
| 110 | + return function(prompt) { | |
| 111 | + if(prompt) print(prompt); | |
| 112 | + var x = stdin.readLine(); | |
| 113 | + return null===x ? x : String(x) /*convert to JS string!*/; | |
| 114 | + }; | |
| 115 | +}()); | |
| 116 | + | |
| 117 | +FShell.dispatchLine = function(line){ | |
| 118 | + var av = line.split(' '); // FIXME: to shell-like tokenization. Too tired! | |
| 119 | + var cmd = av[0]; | |
| 120 | + var key, h; | |
| 121 | + if('/' == cmd[0]) key = '/'; | |
| 122 | + else key = this.commandAliases[cmd]; | |
| 123 | + if(!key) key = cmd; | |
| 124 | + h = this.commandHandlers[key]; | |
| 125 | + if(!h){ | |
| 126 | + print("Command not known: "+cmd +" ("+key+")"); | |
| 127 | + }else if(!WhAjaj.isFunction(h)){ | |
| 128 | + print("Not a function: "+key); | |
| 129 | + } | |
| 130 | + else{ | |
| 131 | + print("Sending ["+key+"] command... "); | |
| 132 | + try{h(av);} | |
| 133 | + catch(e){ print("EXCEPTION: "+e); } | |
| 134 | + } | |
| 135 | +}; | |
| 136 | + | |
| 137 | +FShell.onResponseDefault = function(callback){ | |
| 138 | + return function(resp,req){ | |
| 139 | + assertResponseOK(resp); | |
| 140 | + print("Payload: "+(resp.payload ? WhAjaj.stringify(resp.payload) : "none")); | |
| 141 | + if(WhAjaj.isFunction(callback)){ | |
| 142 | + callback(resp,req); | |
| 143 | + } | |
| 144 | + }; | |
| 145 | +}; | |
| 146 | +FShell.commandHandlers = { | |
| 147 | + "?":function(args){ | |
| 148 | + var k; | |
| 149 | + print("Available commands...\n"); | |
| 150 | + var o = FShell.commandHandlers; | |
| 151 | + for(k in o){ | |
| 152 | + if(! o.hasOwnProperty(k)) continue; | |
| 153 | + print("\t"+k); | |
| 154 | + } | |
| 155 | + }, | |
| 156 | + "/":function(args){ | |
| 157 | + FShell.fossil.sendCommand('/json'+args[0],undefined,{ | |
| 158 | + beforeSend:function(req,opt){ | |
| 159 | + print("Sending to: "+opt.url); | |
| 160 | + }, | |
| 161 | + onResponse:FShell.onResponseDefault() | |
| 162 | + }); | |
| 163 | + }, | |
| 164 | + "eval":function(args){ | |
| 165 | + eval(args.join(' ')); | |
| 166 | + }, | |
| 167 | + "login":function(args){ | |
| 168 | + FShell.fossil.login(args[1], args[2], { | |
| 169 | + onResponse:FShell.onResponseDefault() | |
| 170 | + }); | |
| 171 | + }, | |
| 172 | + "whoami":function(args){ | |
| 173 | + FShell.fossil.whoami({ | |
| 174 | + onResponse:FShell.onResponseDefault() | |
| 175 | + }); | |
| 176 | + }, | |
| 177 | + "HAI":function(args){ | |
| 178 | + FShell.fossil.HAI({ | |
| 179 | + onResponse:FShell.onResponseDefault() | |
| 180 | + }); | |
| 181 | + } | |
| 182 | + | |
| 183 | +}; | |
| 184 | +FShell.commandAliases = { | |
| 185 | + "li":"login", | |
| 186 | + "lo":"logout", | |
| 187 | + "who":"whoami", | |
| 188 | + "hi":"HAI", | |
| 189 | + "tci":"/timeline/ci?limit=3" | |
| 190 | +}; | |
| 191 | +FShell.mainLoop = function(){ | |
| 192 | + var line; | |
| 193 | + var check = /\S/; | |
| 194 | + //var isJavaNull = /java\.lang\.null/; | |
| 195 | + //print(typeof java.lang['null']); | |
| 196 | + while( null != (line=this.readline(this.prompt)) ){ | |
| 197 | + if(null===line) break /*EOF*/; | |
| 198 | + else if( "" === line ) continue; | |
| 199 | + //print("Got line: "+line); | |
| 200 | + else if(!check.test(line)) continue; | |
| 201 | + print('typeof line = '+typeof line); | |
| 202 | + this.dispatchLine(line); | |
| 203 | + print(""); | |
| 204 | + } | |
| 205 | + print("Bye!"); | |
| 206 | +}; | |
| 207 | + | |
| 208 | +FShell.mainLoop(); |
| --- a/ajax/i-test/rhino-shell.js | |
| +++ b/ajax/i-test/rhino-shell.js | |
| @@ -0,0 +1,208 @@ | |
| --- a/ajax/i-test/rhino-shell.js | |
| +++ b/ajax/i-test/rhino-shell.js | |
| @@ -0,0 +1,208 @@ | |
| 1 | var FShell = { |
| 2 | serverUrl: |
| 3 | 'http://localhost:8080' |
| 4 | //'http://fjson/cgi-bin/fossil-json.cgi' |
| 5 | //'http://192.168.1.62:8080' |
| 6 | //'http://fossil.wanderinghorse.net/repos/fossil-json-java/index.cgi' |
| 7 | , |
| 8 | verbose:false, |
| 9 | prompt:"fossil shell > ", |
| 10 | wiki:{}, |
| 11 | consol:java.lang.System.console(), |
| 12 | v:function(msg){ |
| 13 | if(this.verbose){ |
| 14 | print("VERBOSE: "+msg); |
| 15 | } |
| 16 | } |
| 17 | }; |
| 18 | (function bootstrap() { |
| 19 | var srcdir = '../js/'; |
| 20 | var includes = [srcdir+'json2.js', |
| 21 | srcdir+'whajaj.js', |
| 22 | srcdir+'fossil-ajaj.js' |
| 23 | ]; |
| 24 | for( var i in includes ) { |
| 25 | load(includes[i]); |
| 26 | } |
| 27 | WhAjaj.Connector.prototype.sendImpl = WhAjaj.Connector.sendImpls.rhino; |
| 28 | FShell.fossil = new FossilAjaj({ |
| 29 | asynchronous:false, /* rhino-based impl doesn't support async. */ |
| 30 | timeout:10000, |
| 31 | url:FShell.serverUrl |
| 32 | }); |
| 33 | print("Server: "+FShell.serverUrl); |
| 34 | var cb = FShell.fossil.ajaj.callbacks; |
| 35 | cb.beforeSend = function(req,opt){ |
| 36 | if(!FShell.verbose) return; |
| 37 | print("SENDING REQUEST: AJAJ options="+JSON.stringify(opt)); |
| 38 | if(req) print("Request envelope="+WhAjaj.stringify(req)); |
| 39 | }; |
| 40 | cb.afterSend = function(req,opt){ |
| 41 | //if(!FShell.verbose) return; |
| 42 | //print("REQUEST RETURNED: opt="+JSON.stringify(opt)); |
| 43 | //if(req) print("Request="+WhAjaj.stringify(req)); |
| 44 | }; |
| 45 | cb.onError = function(req,opt){ |
| 46 | //if(!FShell.verbose) return; |
| 47 | print("ERROR: "+WhAjaj.stringify(opt)); |
| 48 | }; |
| 49 | cb.onResponse = function(resp,req){ |
| 50 | if(!FShell.verbose) return; |
| 51 | if(resp && resp.resultCode){ |
| 52 | print("Response contains error info: "+resp.resultCode+": "+resp.resultText); |
| 53 | } |
| 54 | print("GOT RESPONSE: "+(('string'===typeof resp) ? resp : WhAjaj.stringify(resp))); |
| 55 | }; |
| 56 | FShell.fossil.HAI({ |
| 57 | onResponse:function(resp,opt){ |
| 58 | assertResponseOK(resp); |
| 59 | } |
| 60 | }); |
| 61 | })(); |
| 62 | |
| 63 | /** |
| 64 | Throws an exception of cond is a falsy value. |
| 65 | */ |
| 66 | function assert(cond, descr){ |
| 67 | descr = descr || "Undescribed condition."; |
| 68 | if(!cond){ |
| 69 | throw new Error("Assertion failed: "+descr); |
| 70 | }else{ |
| 71 | //print("Assertion OK: "+descr); |
| 72 | } |
| 73 | } |
| 74 | |
| 75 | /** |
| 76 | Convenience form of FShell.fossil.sendCommand(command,payload,ajajOpt). |
| 77 | */ |
| 78 | function send(command,payload, ajajOpt){ |
| 79 | FShell.fossil.sendCommand(command,payload,ajajOpt); |
| 80 | } |
| 81 | |
| 82 | /** |
| 83 | Asserts that resp is-a Object, resp.fossil is-a string, and |
| 84 | !resp.resultCode. |
| 85 | */ |
| 86 | function assertResponseOK(resp){ |
| 87 | assert('object' === typeof resp,'Response is-a object.'); |
| 88 | assert( 'string' === typeof resp.fossil, 'Response contains fossil property.'); |
| 89 | assert( !resp.resultCode, 'resp.resultCode='+resp.resultCode); |
| 90 | } |
| 91 | /** |
| 92 | Asserts that resp is-a Object, resp.fossil is-a string, and |
| 93 | resp.resultCode is a truthy value. If expectCode is set then |
| 94 | it also asserts that (resp.resultCode=='FOSSIL-'+expectCode). |
| 95 | */ |
| 96 | function assertResponseError(resp,expectCode){ |
| 97 | assert('object' === typeof resp,'Response is-a object.'); |
| 98 | assert( 'string' === typeof resp.fossil, 'Response contains fossil property.'); |
| 99 | assert( resp.resultCode, 'resp.resultCode='+resp.resultCode); |
| 100 | if(expectCode){ |
| 101 | assert( 'FOSSIL-'+expectCode == resp.resultCode, 'Expecting result code '+expectCode ); |
| 102 | } |
| 103 | } |
| 104 | |
| 105 | FShell.readline = (typeof readline === 'function') ? (readline) : (function() { |
| 106 | importPackage(java.io); |
| 107 | importPackage(java.lang); |
| 108 | var stdin = new BufferedReader(new InputStreamReader(System['in'])); |
| 109 | var self = this; |
| 110 | return function(prompt) { |
| 111 | if(prompt) print(prompt); |
| 112 | var x = stdin.readLine(); |
| 113 | return null===x ? x : String(x) /*convert to JS string!*/; |
| 114 | }; |
| 115 | }()); |
| 116 | |
| 117 | FShell.dispatchLine = function(line){ |
| 118 | var av = line.split(' '); // FIXME: to shell-like tokenization. Too tired! |
| 119 | var cmd = av[0]; |
| 120 | var key, h; |
| 121 | if('/' == cmd[0]) key = '/'; |
| 122 | else key = this.commandAliases[cmd]; |
| 123 | if(!key) key = cmd; |
| 124 | h = this.commandHandlers[key]; |
| 125 | if(!h){ |
| 126 | print("Command not known: "+cmd +" ("+key+")"); |
| 127 | }else if(!WhAjaj.isFunction(h)){ |
| 128 | print("Not a function: "+key); |
| 129 | } |
| 130 | else{ |
| 131 | print("Sending ["+key+"] command... "); |
| 132 | try{h(av);} |
| 133 | catch(e){ print("EXCEPTION: "+e); } |
| 134 | } |
| 135 | }; |
| 136 | |
| 137 | FShell.onResponseDefault = function(callback){ |
| 138 | return function(resp,req){ |
| 139 | assertResponseOK(resp); |
| 140 | print("Payload: "+(resp.payload ? WhAjaj.stringify(resp.payload) : "none")); |
| 141 | if(WhAjaj.isFunction(callback)){ |
| 142 | callback(resp,req); |
| 143 | } |
| 144 | }; |
| 145 | }; |
| 146 | FShell.commandHandlers = { |
| 147 | "?":function(args){ |
| 148 | var k; |
| 149 | print("Available commands...\n"); |
| 150 | var o = FShell.commandHandlers; |
| 151 | for(k in o){ |
| 152 | if(! o.hasOwnProperty(k)) continue; |
| 153 | print("\t"+k); |
| 154 | } |
| 155 | }, |
| 156 | "/":function(args){ |
| 157 | FShell.fossil.sendCommand('/json'+args[0],undefined,{ |
| 158 | beforeSend:function(req,opt){ |
| 159 | print("Sending to: "+opt.url); |
| 160 | }, |
| 161 | onResponse:FShell.onResponseDefault() |
| 162 | }); |
| 163 | }, |
| 164 | "eval":function(args){ |
| 165 | eval(args.join(' ')); |
| 166 | }, |
| 167 | "login":function(args){ |
| 168 | FShell.fossil.login(args[1], args[2], { |
| 169 | onResponse:FShell.onResponseDefault() |
| 170 | }); |
| 171 | }, |
| 172 | "whoami":function(args){ |
| 173 | FShell.fossil.whoami({ |
| 174 | onResponse:FShell.onResponseDefault() |
| 175 | }); |
| 176 | }, |
| 177 | "HAI":function(args){ |
| 178 | FShell.fossil.HAI({ |
| 179 | onResponse:FShell.onResponseDefault() |
| 180 | }); |
| 181 | } |
| 182 | |
| 183 | }; |
| 184 | FShell.commandAliases = { |
| 185 | "li":"login", |
| 186 | "lo":"logout", |
| 187 | "who":"whoami", |
| 188 | "hi":"HAI", |
| 189 | "tci":"/timeline/ci?limit=3" |
| 190 | }; |
| 191 | FShell.mainLoop = function(){ |
| 192 | var line; |
| 193 | var check = /\S/; |
| 194 | //var isJavaNull = /java\.lang\.null/; |
| 195 | //print(typeof java.lang['null']); |
| 196 | while( null != (line=this.readline(this.prompt)) ){ |
| 197 | if(null===line) break /*EOF*/; |
| 198 | else if( "" === line ) continue; |
| 199 | //print("Got line: "+line); |
| 200 | else if(!check.test(line)) continue; |
| 201 | print('typeof line = '+typeof line); |
| 202 | this.dispatchLine(line); |
| 203 | print(""); |
| 204 | } |
| 205 | print("Bye!"); |
| 206 | }; |
| 207 | |
| 208 | FShell.mainLoop(); |
+140
| --- a/ajax/i-test/rhino-test.js | ||
| +++ b/ajax/i-test/rhino-test.js | ||
| @@ -0,0 +1,140 @@ | ||
| 1 | +//osb.flush(cription = 'Log out anonp://fjson/cgi-bin/fossil-json.cgi' | |
| 2 | + //'http://192.168.1.62:8080' | |
| 3 | + //'http://fossil.wanderinghorse.net/repos/fossil-json-java/index.fals' | |
| 4 | + , | |
| 5 | + verbose:true, | |
| 6 | + fossilBinary:'fossil', | |
| 7 | + wiki:{} | |
| 8 | +}var Ter = new java.io.OutputStreamWriter(outsartifactfossil-json.cgi' | |
| 9 | + //'http://192.168.1.62:8080' | |
| 10 | + //'http://fossil.wanderinghorse.net/repos/fossil-json-java/index.cgi' | |
| 11 | + , | |
| 12 | + verbose:true, | |
| 13 | + fossilBinary:'fossil', | |
| 14 | + wiki:{} | |
| 15 | +}; | |
| 16 | +(function bootstrap() { | |
| 17 | + var srcdir = '../js/'; | |
| 18 | + var includes = [srcdir+'json2.js', | |
| 19 | + srcdir+'whajaj.js', | |
| 20 | + srcdir+'fossil-ajaj.js' | |
| 21 | + ]; | |
| 22 | + for( var i in includes ) { | |
| 23 | + load(includes[i]); | |
| 24 | + } | |
| 25 | + WhAjaj.Connector.prototype.sendImpl =ttp://192.168.1.62:8080' | |
| 26 | + //'http://fossil.wanderinghorse.net/repos/fossil-json-java/index.cgi' | |
| 27 | + , | |
| 28 | + verbose:true, | |
| 29 | + fossilBinary:'fossil', | |
| 30 | + wiki:{} | |
| 31 | +}; | |
| 32 | +(function bootstrap() { | |
| 33 | + var srcdir = '../js/'; | |
| 34 | + var includes = [srcdir+'json2.js', | |
| 35 | + srcdir+'whajaj.js', | |
| 36 | + srcdir+'fossil-ajaj.js' | |
| 37 | + ]; | |
| 38 | + for( var i in includes ) { | |
| 39 | + load(includes[i]); | |
| 40 | + } | |
| 41 | + WhAjaj.Connector.prototype.sendImpl = WhAjaj.Connector.sendImpls.rhino; | |
| 42 | + TestApp.fossil = new FossilAjaj({ | |
| 43 | + asynchronous:false, /* rhino-based impl doesn't support async or timeout. */ | |
| 44 | + timeout:0, | |
| 45 | + url:TestApp.serverUrl, | |
| 46 | + fossilBinary:TestApp.fossilBinary | |
| 47 | + }); | |
| 48 | + var cb = TestApp.fossil.ajaj.callbacks; | |
| 49 | + cb.beforeSend = function(req,opt){ | |
| 50 | + if(!TestApp.verbose) return; | |
| 51 | + print("SENDING REQUEST: AJAJ options="+JSON.stringify(opt)); | |
| 52 | + if(req) print("Request envelope="+WhAjaj.stringify(req)); | |
| 53 | + }; | |
| 54 | + cb.afterSend = function(req,opt){ | |
| 55 | + //if(!TestApp.verbose) return; | |
| 56 | + //print("REQUEST RETURNED: opt="+JSON.stringify(opt)); | |
| 57 | + //if(req) print("Request="+WhAjaj.stringify(req)); | |
| 58 | + }; | |
| 59 | + cb.onError = function(req,opt){ | |
| 60 | + if(!TestApp.verbose) return; | |
| 61 | + print("ERROR: "+WhAjaj.stringify(opt)); | |
| 62 | + }; | |
| 63 | + cb.onResponse = function(resp,req){ | |
| 64 | + if(!TestApp.verbose) return; | |
| 65 | + print("GOT RESPONSE: "+(('string'===typeof resp) ? resp : WhAjaj.stringify(resp))); | |
| 66 | + }; | |
| 67 | + | |
| 68 | +})(); | |
| 69 | + | |
| 70 | +/** | |
| 71 | + Throws an exception of cond is a falsy value. | |
| 72 | +*/ | |
| 73 | +function assert(cond, descr){ | |
| 74 | + descr = descr || "Undescribed condition."; | |
| 75 | + if(!cond){ | |
| 76 | + print("Assertion FAILED: "+descr); | |
| 77 | + throw new Error("Assertion failed: "+descr); | |
| 78 | + // aarrgghh. Exceptions are of course swallowed by | |
| 79 | + // the AJAX layer, to keep from killing a browser's | |
| 80 | + // script environment. | |
| 81 | + }else{ | |
| 82 | + if(TestAplls func() in a try/catch block and throws an exception if | |
| 83 | + func() does NOT throw. | |
| 84 | +*/ | |
| 85 | +function assertThrows(func, descr){ | |
| 86 | + descr = descr || "Undescribed condition failed."; | |
| 87 | + var ex; | |
| 88 | + try{ | |
| 89 | + func(); | |
| 90 | + }catch(e){ | |
| 91 | + ex = e; | |
| 92 | + } | |
| 93 | + if(!ex){ | |
| 94 | + throw new Error("Function did not throw (as expected): "+descr); | |
| 95 | + }else{ | |
| 96 | + if(TestApp.ver | |
| 97 | +} | |
| 98 | +testIAmNobody.description = 'Ensure that current user is "nobody".'; | |
| 99 | + | |
| 100 | + | |
| 101 | +function testAnonymousLogin(){ | |
| 102 | + //'http://fossi onRe/192.168.1.62:8080' | |
| 103 | + //'http://fossil.wanderinghorse.net/repos/fossil-json-java/index.cgi' | |
| 104 | + , | |
| 105 | + verbose:true, | |
| 106 | + fossilBinary:'fossil', | |
| 107 | + wiki:{} | |
| 108 | +}; | |
| 109 | +(function bootstrap() { | |
| 110 | + var srcdir = '../js/'; | |
| 111 | + var includes = [srcdir+'json2.js', | |
| 112 | + srcdir+'whajaj.js', | |
| 113 | + srcdir+'fossil-ajaj.js' | |
| 114 | + ]; | |
| 115 | + for( var i in includes ) { | |
| 116 | + load(includes[i]); | |
| 117 | + } | |
| 118 | + WhAjaj.Connector.prototype.sendImpl =ttp://192.168.1.62:8080' | |
| 119 | + //'http://fossil.wanderinghorse.net/repos/fossil-json-java/index.cgi' | |
| 120 | + , | |
| 121 | + verbose:true, | |
| 122 | + fossilBinary:'fossil', | |
| 123 | + wiki:{} | |
| 124 | +}; | |
| 125 | +(function bootstrap() { | |
| 126 | + var srcdir = '../js/'; | |
| 127 | + var includes = [srcdir+'json2.j//.js' | |
| 128 | + srcdir+'whajaj.js', | |
| 129 | + ]; | |
| 130 | + for( var i in includes ) { | |
| 131 | + load(includes[i]); | |
| 132 | + } | |
| 133 | + WhAjaj.Connector.prototype.sendImpl = WhAjaj.Connector.sendImpls.rhino; | |
| 134 | + TestApp.fossil = new FossilAjaj({ | |
| 135 | + asynchronous:false, /* rhino-based impl doesn't support async or timeout. */ | |
| 136 | + timeout:0, | |
| 137 | + url:TestApp.serverUrl, | |
| 138 | + fossilBinary:TestApp.fossilBinary | |
| 139 | + }); | |
| 140 | + var cb = TestApp.fossil.ajaj.callbac |
| --- a/ajax/i-test/rhino-test.js | |
| +++ b/ajax/i-test/rhino-test.js | |
| @@ -0,0 +1,140 @@ | |
| --- a/ajax/i-test/rhino-test.js | |
| +++ b/ajax/i-test/rhino-test.js | |
| @@ -0,0 +1,140 @@ | |
| 1 | //osb.flush(cription = 'Log out anonp://fjson/cgi-bin/fossil-json.cgi' |
| 2 | //'http://192.168.1.62:8080' |
| 3 | //'http://fossil.wanderinghorse.net/repos/fossil-json-java/index.fals' |
| 4 | , |
| 5 | verbose:true, |
| 6 | fossilBinary:'fossil', |
| 7 | wiki:{} |
| 8 | }var Ter = new java.io.OutputStreamWriter(outsartifactfossil-json.cgi' |
| 9 | //'http://192.168.1.62:8080' |
| 10 | //'http://fossil.wanderinghorse.net/repos/fossil-json-java/index.cgi' |
| 11 | , |
| 12 | verbose:true, |
| 13 | fossilBinary:'fossil', |
| 14 | wiki:{} |
| 15 | }; |
| 16 | (function bootstrap() { |
| 17 | var srcdir = '../js/'; |
| 18 | var includes = [srcdir+'json2.js', |
| 19 | srcdir+'whajaj.js', |
| 20 | srcdir+'fossil-ajaj.js' |
| 21 | ]; |
| 22 | for( var i in includes ) { |
| 23 | load(includes[i]); |
| 24 | } |
| 25 | WhAjaj.Connector.prototype.sendImpl =ttp://192.168.1.62:8080' |
| 26 | //'http://fossil.wanderinghorse.net/repos/fossil-json-java/index.cgi' |
| 27 | , |
| 28 | verbose:true, |
| 29 | fossilBinary:'fossil', |
| 30 | wiki:{} |
| 31 | }; |
| 32 | (function bootstrap() { |
| 33 | var srcdir = '../js/'; |
| 34 | var includes = [srcdir+'json2.js', |
| 35 | srcdir+'whajaj.js', |
| 36 | srcdir+'fossil-ajaj.js' |
| 37 | ]; |
| 38 | for( var i in includes ) { |
| 39 | load(includes[i]); |
| 40 | } |
| 41 | WhAjaj.Connector.prototype.sendImpl = WhAjaj.Connector.sendImpls.rhino; |
| 42 | TestApp.fossil = new FossilAjaj({ |
| 43 | asynchronous:false, /* rhino-based impl doesn't support async or timeout. */ |
| 44 | timeout:0, |
| 45 | url:TestApp.serverUrl, |
| 46 | fossilBinary:TestApp.fossilBinary |
| 47 | }); |
| 48 | var cb = TestApp.fossil.ajaj.callbacks; |
| 49 | cb.beforeSend = function(req,opt){ |
| 50 | if(!TestApp.verbose) return; |
| 51 | print("SENDING REQUEST: AJAJ options="+JSON.stringify(opt)); |
| 52 | if(req) print("Request envelope="+WhAjaj.stringify(req)); |
| 53 | }; |
| 54 | cb.afterSend = function(req,opt){ |
| 55 | //if(!TestApp.verbose) return; |
| 56 | //print("REQUEST RETURNED: opt="+JSON.stringify(opt)); |
| 57 | //if(req) print("Request="+WhAjaj.stringify(req)); |
| 58 | }; |
| 59 | cb.onError = function(req,opt){ |
| 60 | if(!TestApp.verbose) return; |
| 61 | print("ERROR: "+WhAjaj.stringify(opt)); |
| 62 | }; |
| 63 | cb.onResponse = function(resp,req){ |
| 64 | if(!TestApp.verbose) return; |
| 65 | print("GOT RESPONSE: "+(('string'===typeof resp) ? resp : WhAjaj.stringify(resp))); |
| 66 | }; |
| 67 | |
| 68 | })(); |
| 69 | |
| 70 | /** |
| 71 | Throws an exception of cond is a falsy value. |
| 72 | */ |
| 73 | function assert(cond, descr){ |
| 74 | descr = descr || "Undescribed condition."; |
| 75 | if(!cond){ |
| 76 | print("Assertion FAILED: "+descr); |
| 77 | throw new Error("Assertion failed: "+descr); |
| 78 | // aarrgghh. Exceptions are of course swallowed by |
| 79 | // the AJAX layer, to keep from killing a browser's |
| 80 | // script environment. |
| 81 | }else{ |
| 82 | if(TestAplls func() in a try/catch block and throws an exception if |
| 83 | func() does NOT throw. |
| 84 | */ |
| 85 | function assertThrows(func, descr){ |
| 86 | descr = descr || "Undescribed condition failed."; |
| 87 | var ex; |
| 88 | try{ |
| 89 | func(); |
| 90 | }catch(e){ |
| 91 | ex = e; |
| 92 | } |
| 93 | if(!ex){ |
| 94 | throw new Error("Function did not throw (as expected): "+descr); |
| 95 | }else{ |
| 96 | if(TestApp.ver |
| 97 | } |
| 98 | testIAmNobody.description = 'Ensure that current user is "nobody".'; |
| 99 | |
| 100 | |
| 101 | function testAnonymousLogin(){ |
| 102 | //'http://fossi onRe/192.168.1.62:8080' |
| 103 | //'http://fossil.wanderinghorse.net/repos/fossil-json-java/index.cgi' |
| 104 | , |
| 105 | verbose:true, |
| 106 | fossilBinary:'fossil', |
| 107 | wiki:{} |
| 108 | }; |
| 109 | (function bootstrap() { |
| 110 | var srcdir = '../js/'; |
| 111 | var includes = [srcdir+'json2.js', |
| 112 | srcdir+'whajaj.js', |
| 113 | srcdir+'fossil-ajaj.js' |
| 114 | ]; |
| 115 | for( var i in includes ) { |
| 116 | load(includes[i]); |
| 117 | } |
| 118 | WhAjaj.Connector.prototype.sendImpl =ttp://192.168.1.62:8080' |
| 119 | //'http://fossil.wanderinghorse.net/repos/fossil-json-java/index.cgi' |
| 120 | , |
| 121 | verbose:true, |
| 122 | fossilBinary:'fossil', |
| 123 | wiki:{} |
| 124 | }; |
| 125 | (function bootstrap() { |
| 126 | var srcdir = '../js/'; |
| 127 | var includes = [srcdir+'json2.j//.js' |
| 128 | srcdir+'whajaj.js', |
| 129 | ]; |
| 130 | for( var i in includes ) { |
| 131 | load(includes[i]); |
| 132 | } |
| 133 | WhAjaj.Connector.prototype.sendImpl = WhAjaj.Connector.sendImpls.rhino; |
| 134 | TestApp.fossil = new FossilAjaj({ |
| 135 | asynchronous:false, /* rhino-based impl doesn't support async or timeout. */ |
| 136 | timeout:0, |
| 137 | url:TestApp.serverUrl, |
| 138 | fossilBinary:TestApp.fossilBinary |
| 139 | }); |
| 140 | var cb = TestApp.fossil.ajaj.callbac |
+1
| --- a/ajax/index.html | ||
| +++ b/ajax/index.html | ||
| @@ -0,0 +1 @@ | ||
| 1 | +<!get Fossil4.2 |
| --- a/ajax/index.html | |
| +++ b/ajax/index.html | |
| @@ -0,0 +1 @@ | |
| --- a/ajax/index.html | |
| +++ b/ajax/index.html | |
| @@ -0,0 +1 @@ | |
| 1 | <!get Fossil4.2 |
+300
| --- a/ajax/js/fossil-ajaj.js | ||
| +++ b/ajax/js/fossil-ajaj.js | ||
| @@ -0,0 +1,300 @@ | ||
| 1 | +/** | |
| 2 | + This file contains a WhAjaj extension for use with Fossil/JSON. | |
| 3 | + | |
| 4 | + Author: Stephan Beal ([email protected]) | |
| 5 | + | |
| 6 | + License: Public Domain | |
| 7 | +*/ | |
| 8 | + | |
| 9 | +/** | |
| 10 | + Constructor for a new Fossil AJAJ client. ajajOpt may be an optional | |
| 11 | + object suitable for passing to the WhAja j.Connector() constructor. | |
| 12 | + | |
| 13 | + On returning, this.ajaj is-a WhAjaj.C onnector instance which can | |
| 14 | + be used to send requests to the back- end (though the convenience | |
| 15 | + functions of this class are the prefe rred way to do it). Clients | |
| 16 | + are encouraged to use FossilAjaj.sendComm | |
| 17 | + of the underlying WhAjaj.Connector API, since this class' API | |
| 18 | + contains Fossil-specific request-calling handling (e.g. of authentication | |
| 19 | + info) whereas WhAjaj is more generic. | |
| 20 | +*/ | |
| 21 | +function FossilAjaj(ajajOpt) | |
| 22 | +{ | |
| 23 | + this.ajaj = new WhAjaj.Connector(ajajOpt); | |
| 24 | + return this; | |
| 25 | +} | |
| 26 | + | |
| 27 | +FossilAjaj.prototype.generateRequestId = function() { | |
| 28 | + return this.ajaj.generateRequestId(); | |
| 29 | +}; | |
| 30 | + | |
| 31 | +/** | |
| 32 | + Proxy for this.ajaj.sendRequest(). | |
| 33 | +*/ | |
| 34 | +FossilAjaj.prototype.sendRequest = function(req,opt) { | |
| 35 | + return this.ajaj.sendRequest(req,opt); | |
| 36 | +}; | |
| 37 | + | |
| 38 | +/** | |
| 39 | + Sends a command to the fossil back-end. Command should be the | |
| 40 | + path part of the URL, e.g. /json/stat, payload is a request-specific | |
| 41 | + value type (may often be null/undefined). ajajOpt is an optional object | |
| 42 | + holding WhAjaj.sendReq uest()-compatible options. | |
| 43 | + | |
| 44 | + This function constructs a Fossil/JSON request envelo. | |
| 45 | + var self = this; | |
| 46 | + ajains a WhAjaj extension for use with Fossil/JSON. | |
| 47 | + | |
| 48 | + Author: Stephan Beal ([email protected]) | |
| 49 | + | |
| 50 | + License: Public Domain | |
| 51 | +*/ | |
| 52 | + | |
| 53 | +/** | |
| 54 | + Constructor for a new Fossil AJAJ client. ajajOpt may be an optional | |
| 55 | + object suitable for passing to the WhAja j.Connector() constructor. | |
| 56 | + | |
| 57 | + On returning, this.ajaj is-a WhAjaj.C onnector instance which can | |
| 58 | + be used to send requests to the back- end (though the convenience | |
| 59 | + functions of this class are the prefe rred way to do it). Clients | |
| 60 | + are encouraged to use FossilAjaj.sendComm | |
| 61 | + of the underlying WhAjaj.Connector API, since this class' API | |
| 62 | + contains Fossil-specific request-calling handling (e.g. of authentication | |
| 63 | + info) whereas WhAjaj is more generic. | |
| 64 | +*/ | |
| 65 | +function FossilAjaj(ajajOpt) | |
| 66 | +{ | |
| 67 | + this.ajaj = new WhAjaj.Connector(ajajOpt); | |
| 68 | + return this; | |
| 69 | +} | |
| 70 | + | |
| 71 | +FossilAjaj.prototype.generateRequestId = function() { | |
| 72 | + return this.ajaj.generateRequestId(); | |
| 73 | +}; | |
| 74 | + | |
| 75 | +/** | |
| 76 | + Proxy for this.ajaj.sendRequest(). | |
| 77 | +*/ | |
| 78 | +FossilAjaj.prototype.sendRequest = function(req,opt) { | |
| 79 | + return this.ajaj.sendRequest(req,opt); | |
| 80 | +}; | |
| 81 | + | |
| 82 | +/** | |
| 83 | + Sends a command to the fossil back-end. Command should be the | |
| 84 | + path part of the URL, e.g. /json/stat, payload is a request-specific | |
| 85 | + value type (may often be null/undefined). ajajOpt is an optional object | |
| 86 | + holding WhAjaj.sendReq uest()-compatible options. | |
| 87 | + | |
| 88 | + This function constructs a Fossil/JSON request envelope based | |
| 89 | + on the given arguments and adds this.auth.authToken and a requestId | |
| 90 | + to it. | |
| 91 | +*/ | |
| 92 | +FossilAjaj.prototype.sendCommand = function(command, payload, ajajOpt) { | |
| 93 | + var req; | |
| 94 | + ajajOpt = ajajOpt || {}; | |
| 95 | + if(payload || (this.auth && this.auth.authToken) || ajajOpt.jsonp) { | |
| 96 | + req = { | |
| 97 | + payload:payload, | |
| 98 | + requestId:('function' === typeof this.generateRequestId) ? this.generateRequestId() : undefined, | |
| 99 | + authToken:(this.auth ? this.auth.authToken : undefined), | |
| 100 | + jsonp:('string' === typeof ajajOpt.jsonp) ? ajajOpt.jsonp : undefined | |
| 101 | + }; | |
| 102 | + } | |
| 103 | + ajajOpt.method = req ? 'POST' : 'GET'; | |
| 104 | + // just for debuggering: ajajOpt.method = 'POST'; if(!req) req={}; | |
| 105 | + if(command) ajajOpt.url = this.ajaj.derivedOption('url',ajajOpt) + command; | |
| 106 | + this.ajaj.sendRequest(req,ajajOpt); | |
| 107 | +}; | |
| 108 | + | |
| 109 | +/** | |
| 110 | + Sends a login request to the back-end. | |
| 111 | + | |
| 112 | + ajajOpt is | |
| 113 | + to sendCommand(). | |
| 114 | + | |
| 115 | + g. of authentication | |
| 116 | + info) whereas WhAjaj is more generic. | |
| 117 | +*/ | |
| 118 | +function Foss ilAjaj(ajajOpt) | |
| 119 | +{ | |
| 120 | + this.ajaj = new WhAjaj.Connector(ajajOpt); | |
| 121 | + return this; | |
| 122 | +} | |
| 123 | + | |
| 124 | +FossilAjaj.prototype.generateRequestId = function() { | |
| 125 | + return this.ajaj.generateRequestId(); | |
| 126 | +}; | |
| 127 | + | |
| 128 | +/** | |
| 129 | + Proxy for this.ajaj.sendRequest(). | |
| 130 | +*/ | |
| 131 | +FossilAjaj.prototype.sendRequest = function(req,opt) { | |
| 132 | + return this.ajaj.sendRequest(req,opt); | |
| 133 | +}; | |
| 134 | + | |
| 135 | +/** | |
| 136 | + Sends a command to the fossil back-end. Command should be the | |
| 137 | + path part of the URL, e.g. /json/stat, payload is a request sing | |
| 138 | + to sendCommand(). | |
| 139 | + | |
| 140 | + ten be null/undefined). ajajOpt is an optional object | |
| 141 | + holding WhAjaj.sendRequest()-compatible options. | |
| 142 | + | |
| 143 | + This function constructs a Fossil/JSON request envelope based | |
| 144 | + on the given arguments and adds this.auth.authToken and a requestId | |
| 145 | + to it. | |
| 146 | +*/ | |
| 147 | +FossilAjaj.prototype.sendCommand = function(command, payload, ajajOpt) { | |
| 148 | + var req; | |
| 149 | + ajajOpt = ajajOpt || {}; | |
| 150 | + if(payload || (this.auth && this.auth.authToken) || ajajOpt.jsonp) { | |
| 151 | + req = { | |
| 152 | + payload:payload, | |
| 153 | + requestId:('function' === typeof this.generateRequestId) ? this.generateRequestId() : undefined, | |
| 154 | + authToken:(this.auth ? this.auth.authToken : undefined), | |
| 155 | + jsonp:('string' === typeof ajajOpt.jsonp) ? ajajOpt.jsonp : undefined | |
| 156 | + }; | |
| 157 | + } | |
| 158 | + ajajOpt.method = req ? 'POST' : 'GET'; | |
| 159 | + // just for debuggering: ajajOpt.method = 'POST'; if(!req) req={}; | |
| 160 | + if(command) ajajOpt.url = this.ajaj.derivedOption('url',ajajOpt) + command; | |
| 161 | + this.ajaj.sendRequest(req,ajajOpt); | |
| 162 | +}; | |
| 163 | + | |
| 164 | +/** | |
| 165 | + Sends a login request to the back-end. | |
| 166 | + | |
| 167 | + ajajOpt is an optional configuration object suitable for passing | |
| 168 | + to sendCommand(). | |
| 169 | + | |
| 170 | + After the response returns, this.auth will be | |
| 171 | + set to the response payload. | |
| 172 | + | |
| 173 | + If name === 'anonymous' (the default if none is passed in) then this | |
| 174 | + function ignores the pw argument and must make two requests - the first | |
| 175 | + one gets the captcha code and the second one submits it. | |
| 176 | + ajajOpt.onResponse() (if set) is only called for the actual login | |
| 177 | + response (the 2nd one), as opposed to being called for both requests. | |
| 178 | + However, this.ajaj.callbacks.onResponse() _is_ called for both (because | |
| 179 | + it happens at a lower level). | |
| 180 | + | |
| 181 | + If this object has an onLogin() function it is called (with | |
| 182 | + no arguments) before the onResponse() handler of the login is called | |
| 183 | + (that is the 2nd request for anonymous logins) and any exceptions | |
| 184 | + it throws are ignored. | |
| 185 | + | |
| 186 | +*/ | |
| 187 | +FossilAj | |
| 188 | + to sendCommand(). | |
| 189 | + sing | |
| 190 | + to sendCommand(). | |
| 191 | + | |
| 192 | + If this object has an/** | |
| 193 | + This file contains a WhAjaj extension for use with Fossil/JSON. | |
| 194 | + | |
| 195 | + Author: Stephan Beal ([email protected]) | |
| 196 | + | |
| 197 | + License: Public Domain | |
| 198 | +*/ | |
| 199 | + | |
| 200 | +/** | |
| 201 | + Constructor for a new Fossil AJAJ client. ajajOpt may be an optional | |
| 202 | + object suitable for passing to the WhAja j.Connector() constructor. | |
| 203 | + | |
| 204 | + On returning, this.ajaj is-a WhAjaj.C onnector instance which can | |
| 205 | + be used to send requests to the back- end (though the convenience | |
| 206 | + functions of this class are the prefe rred way to do it). Clients | |
| 207 | + are encouraged to use FossilAjaj.sendComm | |
| 208 | + of the underlying WhAjaj.Connector API, since this class' API | |
| 209 | + contains Fossil-specific request-calling handling (e.g. of authentication | |
| 210 | + info) whereas WhAjaj is more generic. | |
| 211 | +*/ | |
| 212 | +function FossilAjaj(ajajOpt) | |
| 213 | +{ | |
| 214 | + this.ajaj = new WhAjaj.Connector(ajajOpt); | |
| 215 | + return this; | |
| 216 | +} | |
| 217 | + | |
| 218 | +FossilAjaj.prototype.generateRequestId = function() { | |
| 219 | + return this.ajaj.generateRequestId(); | |
| 220 | +}; | |
| 221 | + | |
| 222 | +/** | |
| 223 | + Proxy for this.ajaj.sendRequest(). | |
| 224 | +*/ | |
| 225 | +FossilAjaj.prototype.sendRequest = function(req,opt) { | |
| 226 | + return this.ajaj.sendRequest(req,opt); | |
| 227 | +}; | |
| 228 | + | |
| 229 | +/** | |
| 230 | + Sends a command to the fossil back-end. Command should be the | |
| 231 | + path part of the URL, e.g. /json/stat, payload is a request-specific | |
| 232 | + value type (may often be null/undefined). ajajOpt is an optional object | |
| 233 | + holding WhAjaj.sendReq uest()-compatible options. | |
| 234 | + | |
| 235 | + This function constructs a Fossil/JSON request envelope based | |
| 236 | + on the given arguments and adds this.auth.authToken and a requestId | |
| 237 | + to it. | |
| 238 | +*/ | |
| 239 | +FossilAjaj.prototype.sendCommand = function(command, payload, ajajOpt) { | |
| 240 | + var req; | |
| 241 | + ajajOpt = ajajOpt || {}; | |
| 242 | + if(payload || (this.auth && this.auth.authToken) || ajajOpt.jsonp) { | |
| 243 | + req = { | |
| 244 | + payload:payload, | |
| 245 | + requestId:('function' === typeof this.generateRequestId) ? this.generateRequestId() : undefined, | |
| 246 | + authToken:(this.auth ? this.auth.authToken : undefined), | |
| 247 | + jsonp:('string' === typeof ajajOpt.jsonp) ? ajajOpt.jsonp : undefined | |
| 248 | + }; | |
| 249 | + } | |
| 250 | + ajajOpt.method = req ? 'POST' : 'GET'; | |
| 251 | + // just for debuggering: ajajOpt.method = 'POST'; if(!req) req={}; | |
| 252 | + if(command) ajajOpt.url = this.ajaj.derivedOption('url',ajajOpt) + command; | |
| 253 | + this.ajaj.sendRequest(req,ajajOpt); | |
| 254 | +}; | |
| 255 | + | |
| 256 | +/** | |
| 257 | + Sends a login request to the back-end. | |
| 258 | + | |
| 259 | + ajajOpt is | |
| 260 | + to sendCommand(). | |
| 261 | + | |
| 262 | + g. of authentication | |
| 263 | + info) whereas WhAjaj is more generic. | |
| 264 | +*/ | |
| 265 | +function Foss ilAjaj(ajajOpt) | |
| 266 | +{ | |
| 267 | + this.ajaj = new WhAjaj.Connector(ajajOpt); | |
| 268 | + return this; | |
| 269 | +} | |
| 270 | + | |
| 271 | +FossilAjaj.prototype.generateRequestId = function() { | |
| 272 | + return this.ajaj.generateRequestId(); | |
| 273 | +}; | |
| 274 | + | |
| 275 | +/** | |
| 276 | + Proxy for this.ajaj.sendRequest(). | |
| 277 | +*/ | |
| 278 | +FossilAjaj.prototype.sendRequest = function(req,opt) { | |
| 279 | + return this.ajaj.sendRequest(req,opt); | |
| 280 | +}; | |
| 281 | + | |
| 282 | +/** | |
| 283 | + Sends a command to the fossil back-end. Command should be the | |
| 284 | + path part of the URL, e.g. /json/stat, payload is a request sing | |
| 285 | + to sendCommand(). | |
| 286 | + | |
| 287 | + ten be null/undefined). ajajOpt is an optional object | |
| 288 | + holding WhAjaj.sendRequest()-compatible options. | |
| 289 | + | |
| 290 | + This function constructs a Fossil/JSON request envelope based | |
| 291 | + on the given arguments and adds this.auth.authToken and a requestId | |
| 292 | + to it. | |
| 293 | +*/ | |
| 294 | +FossilAjaj.prototype.sendCommand = function(command, payload, ajajOpt) { | |
| 295 | + var req; | |
| 296 | + ajajOpt = ajajOpt || {}; | |
| 297 | + if(payload || (this.auth && this.auth.authToken) || ajajOpt.jsonp) { | |
| 298 | + req = { | |
| 299 | + payload:payload, | |
| 300 | + |
| --- a/ajax/js/fossil-ajaj.js | |
| +++ b/ajax/js/fossil-ajaj.js | |
| @@ -0,0 +1,300 @@ | |
| --- a/ajax/js/fossil-ajaj.js | |
| +++ b/ajax/js/fossil-ajaj.js | |
| @@ -0,0 +1,300 @@ | |
| 1 | /** |
| 2 | This file contains a WhAjaj extension for use with Fossil/JSON. |
| 3 | |
| 4 | Author: Stephan Beal ([email protected]) |
| 5 | |
| 6 | License: Public Domain |
| 7 | */ |
| 8 | |
| 9 | /** |
| 10 | Constructor for a new Fossil AJAJ client. ajajOpt may be an optional |
| 11 | object suitable for passing to the WhAja j.Connector() constructor. |
| 12 | |
| 13 | On returning, this.ajaj is-a WhAjaj.C onnector instance which can |
| 14 | be used to send requests to the back- end (though the convenience |
| 15 | functions of this class are the prefe rred way to do it). Clients |
| 16 | are encouraged to use FossilAjaj.sendComm |
| 17 | of the underlying WhAjaj.Connector API, since this class' API |
| 18 | contains Fossil-specific request-calling handling (e.g. of authentication |
| 19 | info) whereas WhAjaj is more generic. |
| 20 | */ |
| 21 | function FossilAjaj(ajajOpt) |
| 22 | { |
| 23 | this.ajaj = new WhAjaj.Connector(ajajOpt); |
| 24 | return this; |
| 25 | } |
| 26 | |
| 27 | FossilAjaj.prototype.generateRequestId = function() { |
| 28 | return this.ajaj.generateRequestId(); |
| 29 | }; |
| 30 | |
| 31 | /** |
| 32 | Proxy for this.ajaj.sendRequest(). |
| 33 | */ |
| 34 | FossilAjaj.prototype.sendRequest = function(req,opt) { |
| 35 | return this.ajaj.sendRequest(req,opt); |
| 36 | }; |
| 37 | |
| 38 | /** |
| 39 | Sends a command to the fossil back-end. Command should be the |
| 40 | path part of the URL, e.g. /json/stat, payload is a request-specific |
| 41 | value type (may often be null/undefined). ajajOpt is an optional object |
| 42 | holding WhAjaj.sendReq uest()-compatible options. |
| 43 | |
| 44 | This function constructs a Fossil/JSON request envelo. |
| 45 | var self = this; |
| 46 | ajains a WhAjaj extension for use with Fossil/JSON. |
| 47 | |
| 48 | Author: Stephan Beal ([email protected]) |
| 49 | |
| 50 | License: Public Domain |
| 51 | */ |
| 52 | |
| 53 | /** |
| 54 | Constructor for a new Fossil AJAJ client. ajajOpt may be an optional |
| 55 | object suitable for passing to the WhAja j.Connector() constructor. |
| 56 | |
| 57 | On returning, this.ajaj is-a WhAjaj.C onnector instance which can |
| 58 | be used to send requests to the back- end (though the convenience |
| 59 | functions of this class are the prefe rred way to do it). Clients |
| 60 | are encouraged to use FossilAjaj.sendComm |
| 61 | of the underlying WhAjaj.Connector API, since this class' API |
| 62 | contains Fossil-specific request-calling handling (e.g. of authentication |
| 63 | info) whereas WhAjaj is more generic. |
| 64 | */ |
| 65 | function FossilAjaj(ajajOpt) |
| 66 | { |
| 67 | this.ajaj = new WhAjaj.Connector(ajajOpt); |
| 68 | return this; |
| 69 | } |
| 70 | |
| 71 | FossilAjaj.prototype.generateRequestId = function() { |
| 72 | return this.ajaj.generateRequestId(); |
| 73 | }; |
| 74 | |
| 75 | /** |
| 76 | Proxy for this.ajaj.sendRequest(). |
| 77 | */ |
| 78 | FossilAjaj.prototype.sendRequest = function(req,opt) { |
| 79 | return this.ajaj.sendRequest(req,opt); |
| 80 | }; |
| 81 | |
| 82 | /** |
| 83 | Sends a command to the fossil back-end. Command should be the |
| 84 | path part of the URL, e.g. /json/stat, payload is a request-specific |
| 85 | value type (may often be null/undefined). ajajOpt is an optional object |
| 86 | holding WhAjaj.sendReq uest()-compatible options. |
| 87 | |
| 88 | This function constructs a Fossil/JSON request envelope based |
| 89 | on the given arguments and adds this.auth.authToken and a requestId |
| 90 | to it. |
| 91 | */ |
| 92 | FossilAjaj.prototype.sendCommand = function(command, payload, ajajOpt) { |
| 93 | var req; |
| 94 | ajajOpt = ajajOpt || {}; |
| 95 | if(payload || (this.auth && this.auth.authToken) || ajajOpt.jsonp) { |
| 96 | req = { |
| 97 | payload:payload, |
| 98 | requestId:('function' === typeof this.generateRequestId) ? this.generateRequestId() : undefined, |
| 99 | authToken:(this.auth ? this.auth.authToken : undefined), |
| 100 | jsonp:('string' === typeof ajajOpt.jsonp) ? ajajOpt.jsonp : undefined |
| 101 | }; |
| 102 | } |
| 103 | ajajOpt.method = req ? 'POST' : 'GET'; |
| 104 | // just for debuggering: ajajOpt.method = 'POST'; if(!req) req={}; |
| 105 | if(command) ajajOpt.url = this.ajaj.derivedOption('url',ajajOpt) + command; |
| 106 | this.ajaj.sendRequest(req,ajajOpt); |
| 107 | }; |
| 108 | |
| 109 | /** |
| 110 | Sends a login request to the back-end. |
| 111 | |
| 112 | ajajOpt is |
| 113 | to sendCommand(). |
| 114 | |
| 115 | g. of authentication |
| 116 | info) whereas WhAjaj is more generic. |
| 117 | */ |
| 118 | function Foss ilAjaj(ajajOpt) |
| 119 | { |
| 120 | this.ajaj = new WhAjaj.Connector(ajajOpt); |
| 121 | return this; |
| 122 | } |
| 123 | |
| 124 | FossilAjaj.prototype.generateRequestId = function() { |
| 125 | return this.ajaj.generateRequestId(); |
| 126 | }; |
| 127 | |
| 128 | /** |
| 129 | Proxy for this.ajaj.sendRequest(). |
| 130 | */ |
| 131 | FossilAjaj.prototype.sendRequest = function(req,opt) { |
| 132 | return this.ajaj.sendRequest(req,opt); |
| 133 | }; |
| 134 | |
| 135 | /** |
| 136 | Sends a command to the fossil back-end. Command should be the |
| 137 | path part of the URL, e.g. /json/stat, payload is a request sing |
| 138 | to sendCommand(). |
| 139 | |
| 140 | ten be null/undefined). ajajOpt is an optional object |
| 141 | holding WhAjaj.sendRequest()-compatible options. |
| 142 | |
| 143 | This function constructs a Fossil/JSON request envelope based |
| 144 | on the given arguments and adds this.auth.authToken and a requestId |
| 145 | to it. |
| 146 | */ |
| 147 | FossilAjaj.prototype.sendCommand = function(command, payload, ajajOpt) { |
| 148 | var req; |
| 149 | ajajOpt = ajajOpt || {}; |
| 150 | if(payload || (this.auth && this.auth.authToken) || ajajOpt.jsonp) { |
| 151 | req = { |
| 152 | payload:payload, |
| 153 | requestId:('function' === typeof this.generateRequestId) ? this.generateRequestId() : undefined, |
| 154 | authToken:(this.auth ? this.auth.authToken : undefined), |
| 155 | jsonp:('string' === typeof ajajOpt.jsonp) ? ajajOpt.jsonp : undefined |
| 156 | }; |
| 157 | } |
| 158 | ajajOpt.method = req ? 'POST' : 'GET'; |
| 159 | // just for debuggering: ajajOpt.method = 'POST'; if(!req) req={}; |
| 160 | if(command) ajajOpt.url = this.ajaj.derivedOption('url',ajajOpt) + command; |
| 161 | this.ajaj.sendRequest(req,ajajOpt); |
| 162 | }; |
| 163 | |
| 164 | /** |
| 165 | Sends a login request to the back-end. |
| 166 | |
| 167 | ajajOpt is an optional configuration object suitable for passing |
| 168 | to sendCommand(). |
| 169 | |
| 170 | After the response returns, this.auth will be |
| 171 | set to the response payload. |
| 172 | |
| 173 | If name === 'anonymous' (the default if none is passed in) then this |
| 174 | function ignores the pw argument and must make two requests - the first |
| 175 | one gets the captcha code and the second one submits it. |
| 176 | ajajOpt.onResponse() (if set) is only called for the actual login |
| 177 | response (the 2nd one), as opposed to being called for both requests. |
| 178 | However, this.ajaj.callbacks.onResponse() _is_ called for both (because |
| 179 | it happens at a lower level). |
| 180 | |
| 181 | If this object has an onLogin() function it is called (with |
| 182 | no arguments) before the onResponse() handler of the login is called |
| 183 | (that is the 2nd request for anonymous logins) and any exceptions |
| 184 | it throws are ignored. |
| 185 | |
| 186 | */ |
| 187 | FossilAj |
| 188 | to sendCommand(). |
| 189 | sing |
| 190 | to sendCommand(). |
| 191 | |
| 192 | If this object has an/** |
| 193 | This file contains a WhAjaj extension for use with Fossil/JSON. |
| 194 | |
| 195 | Author: Stephan Beal ([email protected]) |
| 196 | |
| 197 | License: Public Domain |
| 198 | */ |
| 199 | |
| 200 | /** |
| 201 | Constructor for a new Fossil AJAJ client. ajajOpt may be an optional |
| 202 | object suitable for passing to the WhAja j.Connector() constructor. |
| 203 | |
| 204 | On returning, this.ajaj is-a WhAjaj.C onnector instance which can |
| 205 | be used to send requests to the back- end (though the convenience |
| 206 | functions of this class are the prefe rred way to do it). Clients |
| 207 | are encouraged to use FossilAjaj.sendComm |
| 208 | of the underlying WhAjaj.Connector API, since this class' API |
| 209 | contains Fossil-specific request-calling handling (e.g. of authentication |
| 210 | info) whereas WhAjaj is more generic. |
| 211 | */ |
| 212 | function FossilAjaj(ajajOpt) |
| 213 | { |
| 214 | this.ajaj = new WhAjaj.Connector(ajajOpt); |
| 215 | return this; |
| 216 | } |
| 217 | |
| 218 | FossilAjaj.prototype.generateRequestId = function() { |
| 219 | return this.ajaj.generateRequestId(); |
| 220 | }; |
| 221 | |
| 222 | /** |
| 223 | Proxy for this.ajaj.sendRequest(). |
| 224 | */ |
| 225 | FossilAjaj.prototype.sendRequest = function(req,opt) { |
| 226 | return this.ajaj.sendRequest(req,opt); |
| 227 | }; |
| 228 | |
| 229 | /** |
| 230 | Sends a command to the fossil back-end. Command should be the |
| 231 | path part of the URL, e.g. /json/stat, payload is a request-specific |
| 232 | value type (may often be null/undefined). ajajOpt is an optional object |
| 233 | holding WhAjaj.sendReq uest()-compatible options. |
| 234 | |
| 235 | This function constructs a Fossil/JSON request envelope based |
| 236 | on the given arguments and adds this.auth.authToken and a requestId |
| 237 | to it. |
| 238 | */ |
| 239 | FossilAjaj.prototype.sendCommand = function(command, payload, ajajOpt) { |
| 240 | var req; |
| 241 | ajajOpt = ajajOpt || {}; |
| 242 | if(payload || (this.auth && this.auth.authToken) || ajajOpt.jsonp) { |
| 243 | req = { |
| 244 | payload:payload, |
| 245 | requestId:('function' === typeof this.generateRequestId) ? this.generateRequestId() : undefined, |
| 246 | authToken:(this.auth ? this.auth.authToken : undefined), |
| 247 | jsonp:('string' === typeof ajajOpt.jsonp) ? ajajOpt.jsonp : undefined |
| 248 | }; |
| 249 | } |
| 250 | ajajOpt.method = req ? 'POST' : 'GET'; |
| 251 | // just for debuggering: ajajOpt.method = 'POST'; if(!req) req={}; |
| 252 | if(command) ajajOpt.url = this.ajaj.derivedOption('url',ajajOpt) + command; |
| 253 | this.ajaj.sendRequest(req,ajajOpt); |
| 254 | }; |
| 255 | |
| 256 | /** |
| 257 | Sends a login request to the back-end. |
| 258 | |
| 259 | ajajOpt is |
| 260 | to sendCommand(). |
| 261 | |
| 262 | g. of authentication |
| 263 | info) whereas WhAjaj is more generic. |
| 264 | */ |
| 265 | function Foss ilAjaj(ajajOpt) |
| 266 | { |
| 267 | this.ajaj = new WhAjaj.Connector(ajajOpt); |
| 268 | return this; |
| 269 | } |
| 270 | |
| 271 | FossilAjaj.prototype.generateRequestId = function() { |
| 272 | return this.ajaj.generateRequestId(); |
| 273 | }; |
| 274 | |
| 275 | /** |
| 276 | Proxy for this.ajaj.sendRequest(). |
| 277 | */ |
| 278 | FossilAjaj.prototype.sendRequest = function(req,opt) { |
| 279 | return this.ajaj.sendRequest(req,opt); |
| 280 | }; |
| 281 | |
| 282 | /** |
| 283 | Sends a command to the fossil back-end. Command should be the |
| 284 | path part of the URL, e.g. /json/stat, payload is a request sing |
| 285 | to sendCommand(). |
| 286 | |
| 287 | ten be null/undefined). ajajOpt is an optional object |
| 288 | holding WhAjaj.sendRequest()-compatible options. |
| 289 | |
| 290 | This function constructs a Fossil/JSON request envelope based |
| 291 | on the given arguments and adds this.auth.authToken and a requestId |
| 292 | to it. |
| 293 | */ |
| 294 | FossilAjaj.prototype.sendCommand = function(command, payload, ajajOpt) { |
| 295 | var req; |
| 296 | ajajOpt = ajajOpt || {}; |
| 297 | if(payload || (this.auth && this.auth.authToken) || ajajOpt.jsonp) { |
| 298 | req = { |
| 299 | payload:payload, |
| 300 |
+476
| --- a/ajax/js/json2.js | ||
| +++ b/ajax/js/json2.js | ||
| @@ -0,0 +1,476 @@ | ||
| 1 | +/* | |
| 2 | + http://www.JSON.org/json2.js | |
| 3 | + 2009-06-29 | |
| 4 | + | |
| 5 | + Public Domain. | |
| 6 | + | |
| 7 | + NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. | |
| 8 | + | |
| 9 | + See http://www.JSON.org/js.html | |
| 10 | + | |
| 11 | + This file creates a global JSON object containing two methods: stringify | |
| 12 | + and parse. | |
| 13 | + | |
| 14 | + JSON.stringify(value, replacer, space) | |
| 15 | + value any JavaScript value, usually an object or array. | |
| 16 | + | |
| 17 | + replacer an optional parameter that determines how object | |
| 18 | + values are stringified for objects. It can be a | |
| 19 | + function or an array of strings. | |
| 20 | + | |
| 21 | + space an optional parameter that specifies the indentation | |
| 22 | + of nested structures. If it is omitted, the text will | |
| 23 | + be packed without extra whitespace. If it is a number, | |
| 24 | + it will specify the number of spaces to indent at each | |
| 25 | + level. If it is a string (such as '\t' or ' '), | |
| 26 | + it contains the characters used to indent at each level. | |
| 27 | + | |
| 28 | + This method produces a JSON text from a JavaScript value. | |
| 29 | + | |
| 30 | + When an object value is found, if the object contains a toJSON | |
| 31 | + method, its toJSON method will be called and the result will be | |
| 32 | + stringified. A toJSON method does not serialize: it returns the | |
| 33 | + value represented by the name/value pair that should be serialized, | |
| 34 | + or undefined if nothing should be serialized. The toJSON method | |
| 35 | + will be passed the key associated with the value, and this will be | |
| 36 | + bound to the object holding the key. | |
| 37 | + | |
| 38 | + For example, this would serialize Dates as ISO strings. | |
| 39 | + | |
| 40 | + Date.prototype.toJSON = function (key) { | |
| 41 | + function f(n) { | |
| 42 | + // Format integers to have at least two digits. | |
| 43 | + return n < 10 ? '0' + n : n; | |
| 44 | + } | |
| 45 | + | |
| 46 | + return this.getUTCFullYear() + '-' + | |
| 47 | + f(this.getUTCMonth() + 1) + '-' + | |
| 48 | + f(this.getUTCDate()) + 'T' + | |
| 49 | + f(this.getUTCHours()) + ':' + | |
| 50 | + f(this.getUTCMinutes()) + ':' + | |
| 51 | + f(this.getUTCSeconds()) + 'Z'; | |
| 52 | + }; | |
| 53 | + | |
| 54 | + You can provide an optional replacer method. It will be passed the | |
| 55 | + key and value of each member, with this bound to the containing | |
| 56 | + object. The value that is returned from your method will be | |
| 57 | + serialized. If your method returns undefined, then the member will | |
| 58 | + be excluded from the serialization. | |
| 59 | + | |
| 60 | + If the replacer parameter is an array of strings, then it will be | |
| 61 | + used to select the members to be serialized. It filters the results | |
| 62 | + such that only members with keys listed in the replacer array are | |
| 63 | + stringified. | |
| 64 | + | |
| 65 | + Values that do not have JSON representations, such as undefined or | |
| 66 | + functions, will not be serialized. Such values in objects will be | |
| 67 | + dropped; in arrays they will be replaced with null. You can use | |
| 68 | + a replacer function to replace those with JSON values. | |
| 69 | + JSON.stringify(undefined) returns undefined. | |
| 70 | + | |
| 71 | + The optional space parameter produces a stringification of the | |
| 72 | + value that is filled with line breaks and indentation to make it | |
| 73 | + easier to read. | |
| 74 | + | |
| 75 | + If the space parameter is a non-empty string, then that string will | |
| 76 | + be used for indentation. If the space parameter is a number, then | |
| 77 | + the indentation will be that many spaces. | |
| 78 | + | |
| 79 | + Example: | |
| 80 | + | |
| 81 | + text = JSON.stringify(['e', {pluribus: 'unum'}]); | |
| 82 | + // text is '["e",{"pluribus":"unum"}]' | |
| 83 | + | |
| 84 | + | |
| 85 | + text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t'); | |
| 86 | + // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' | |
| 87 | + | |
| 88 | + text = JSON.stringify([new Date()], function (key, value) { | |
| 89 | + return this[key] instanceof Date ? | |
| 90 | + 'Date(' + this[key] + ')' : value; | |
| 91 | + }); | |
| 92 | + // text is '["Date(---current time---)"]' | |
| 93 | + | |
| 94 | + | |
| 95 | + JSON.parse(text, reviver) | |
| 96 | + This method parses a JSON text to produce an object or array. | |
| 97 | + It can throw a SyntaxError exception. | |
| 98 | + | |
| 99 | + The optional reviver parameter is a function that can filter and | |
| 100 | + transform the results. It receives each of the keys and values, | |
| 101 | + and its return value is used instead of the original value. | |
| 102 | + If it returns what it received, then the structure is not modified. | |
| 103 | + If it returns undefined then the member is deleted. | |
| 104 | + | |
| 105 | + Example: | |
| 106 | + | |
| 107 | + // Parse the text. Values that look like ISO date strings will | |
| 108 | + // be converted to Date objects. | |
| 109 | + | |
| 110 | + myData = JSON.parse(text, function (key, value) { | |
| 111 | + var a; | |
| 112 | + if (typeof value === 'string') { | |
| 113 | + a = | |
| 114 | +/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); | |
| 115 | + if (a) { | |
| 116 | + return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], | |
| 117 | + +a[5], +a[6])); | |
| 118 | + } | |
| 119 | + } | |
| 120 | + return value; | |
| 121 | + }); | |
| 122 | + | |
| 123 | + myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) { | |
| 124 | + var d; | |
| 125 | + if (typeof value === 'string' && | |
| 126 | + value.slice(0, 5) === 'Date(' && | |
| 127 | + value.slice(-1) === ')') { | |
| 128 | + d = new Date(value.slice(5, -1)); | |
| 129 | + if (d) { | |
| 130 | + return d; | |
| 131 | + } | |
| 132 | + } | |
| 133 | + return value; | |
| 134 | + }); | |
| 135 | + | |
| 136 | + | |
| 137 | + This is a reference implementation. You are free to copy, modify, or | |
| 138 | + redistribute. | |
| 139 | + | |
| 140 | + This code should be minified before deployment. | |
| 141 | + See http://javascript.crockford.com/jsmin.html | |
| 142 | + | |
| 143 | + USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO | |
| 144 | + NOT CONTROL. | |
| 145 | +*/ | |
| 146 | + | |
| 147 | +/*jslint evil: true */ | |
| 148 | + | |
| 149 | +/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply, | |
| 150 | + call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, | |
| 151 | + getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, | |
| 152 | + lastIndex, length, parse, prototype, push, replace, slice, stringify, | |
| 153 | + test, toJSON, toString, valueOf | |
| 154 | +*/ | |
| 155 | + | |
| 156 | +// Create a JSON object only if one does not already exist. We create the | |
| 157 | +// methods in a closure to avoid creating global variables. | |
| 158 | + | |
| 159 | +var JSON = JSON || {}; | |
| 160 | + | |
| 161 | +(function () { | |
| 162 | + | |
| 163 | + function f(n) { | |
| 164 | + // Format integers to have at least two digits. | |
| 165 | + return n < 10 ? '0' + n : n; | |
| 166 | + } | |
| 167 | + | |
| 168 | + if (typeof Date.prototype.toJSON !== 'function') { | |
| 169 | + | |
| 170 | + Date.prototype.toJSON = function (key) { | |
| 171 | + | |
| 172 | + return isFinite(this.valueOf()) ? | |
| 173 | + this.getUTCFullYear() + '-' + | |
| 174 | + f(this.getUTCMonth() + 1) + '-' + | |
| 175 | + f(this.getUTCDate()) + 'T' + | |
| 176 | + f(this.getUTCHours()) + ':' + | |
| 177 | + f(this.getUTCMinutes()) + ':' + | |
| 178 | + f(this.getUTCSeconds()) + 'Z' : null; | |
| 179 | + }; | |
| 180 | + | |
| 181 | + String.prototype.toJSON = | |
| 182 | + Number.prototype.toJSON = | |
| 183 | + Boolean.prototype.toJSON = function (key) { | |
| 184 | + return this.valueOf(); | |
| 185 | + }; | |
| 186 | + } | |
| 187 | + | |
| 188 | + var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, | |
| 189 | + escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, | |
| 190 | + gap, | |
| 191 | + indent, | |
| 192 | + meta = { // table of character substitutions | |
| 193 | + '\b': '\\b', | |
| 194 | + '\t': '\\t', | |
| 195 | + '\n': '\\n', | |
| 196 | + '\f': '\\f', | |
| 197 | + '\r': '\\r', | |
| 198 | + '"' : '\\"', | |
| 199 | + '\\': '\\\\' | |
| 200 | + }, | |
| 201 | + rep; | |
| 202 | + | |
| 203 | + | |
| 204 | + function quote(string) { | |
| 205 | + | |
| 206 | +// If the string contains no control characters, no quote characters, and no | |
| 207 | +// backslash characters, then we can safely slap some quotes around it. | |
| 208 | +// Otherwise we must also replace the offending characters with safe escape | |
| 209 | +// sequences. | |
| 210 | + | |
| 211 | + escapable.lastIndex = 0; | |
| 212 | + return escapable.test(string) ? | |
| 213 | + '"' + string.replace(escapable, function (a) { | |
| 214 | + var c = meta[a]; | |
| 215 | + return typeof c === 'string' ? c : | |
| 216 | + '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); | |
| 217 | + }) + '"' : | |
| 218 | + '"' + string + '"'; | |
| 219 | + } | |
| 220 | + | |
| 221 | + | |
| 222 | + function str(key, holder) { | |
| 223 | + | |
| 224 | +// Produce a string from holder[key]. | |
| 225 | + | |
| 226 | + var i, // The loop counter. | |
| 227 | + k, // The member key. | |
| 228 | + v, // The member value. | |
| 229 | + length, | |
| 230 | + mind = gap, | |
| 231 | + partial, | |
| 232 | + value = holder[key]; | |
| 233 | + | |
| 234 | +// If the value has a toJSON method, call it to obtain a replacement value. | |
| 235 | + | |
| 236 | + if (value && typeof value === 'object' && | |
| 237 | + typeof value.toJSON === 'function') { | |
| 238 | + value = value.toJSON(key); | |
| 239 | + } | |
| 240 | + | |
| 241 | +// If we were called with a replacer function, then call the replacer to | |
| 242 | +// obtain a replacement value. | |
| 243 | + | |
| 244 | + if (typeof rep === 'function') { | |
| 245 | + value = rep.call(holder, key, value); | |
| 246 | + } | |
| 247 | + | |
| 248 | +// What happens next depends on the value's type. | |
| 249 | + | |
| 250 | + switch (typeof value) { | |
| 251 | + case 'string': | |
| 252 | + return quote(value); | |
| 253 | + | |
| 254 | + case 'number': | |
| 255 | + | |
| 256 | +// JSON numbers must be finite. Encode non-finite numbers as null. | |
| 257 | + | |
| 258 | + return isFinite(value) ? String(value) : 'null'; | |
| 259 | + | |
| 260 | + case 'boolean': | |
| 261 | + case 'null': | |
| 262 | + | |
| 263 | +// If the value is a boolean or null, convert it to a string. Note: | |
| 264 | +// typeof null does not produce 'null'. The case is included here in | |
| 265 | +// the remote chance that this gets fixed someday. | |
| 266 | + | |
| 267 | + return String(value); | |
| 268 | + | |
| 269 | +// If the type is 'object', we might be dealing with an object or an array or | |
| 270 | +// null. | |
| 271 | + | |
| 272 | + case 'object': | |
| 273 | + | |
| 274 | +// Due to a specification blunder in ECMAScript, typeof null is 'object', | |
| 275 | +// so watch out for that case. | |
| 276 | + | |
| 277 | + if (!value) { | |
| 278 | + return 'null'; | |
| 279 | + } | |
| 280 | + | |
| 281 | +// Make an array to hold the partial results of stringifying this object value. | |
| 282 | + | |
| 283 | + gap += indent; | |
| 284 | + partial = []; | |
| 285 | + | |
| 286 | +// Is the value an array? | |
| 287 | + | |
| 288 | + if (Object.prototype.toString.apply(value) === '[object Array]') { | |
| 289 | + | |
| 290 | +// The value is an array. Stringify every element. Use null as a placeholder | |
| 291 | +// for non-JSON values. | |
| 292 | + | |
| 293 | + length = value.length; | |
| 294 | + for (i = 0; i < length; i += 1) { | |
| 295 | + partial[i] = str(i, value) || 'null'; | |
| 296 | + } | |
| 297 | + | |
| 298 | +// Join all of the elements together, separated with commas, and wrap them in | |
| 299 | +// brackets. | |
| 300 | + | |
| 301 | + v = partial.length === 0 ? '[]' : | |
| 302 | + gap ? '[\n' + gap + | |
| 303 | + partial.join(',\n' + gap) + '\n' + | |
| 304 | + mind + ']' : | |
| 305 | + '[' + partial.join(',') + ']'; | |
| 306 | + gap = mind; | |
| 307 | + return v; | |
| 308 | + } | |
| 309 | + | |
| 310 | +// If the replacer is an array, use it to select the members to be stringified. | |
| 311 | + | |
| 312 | + if (rep && typeof rep === 'object') { | |
| 313 | + length = rep.length; | |
| 314 | + for (i = 0; i < length; i += 1) { | |
| 315 | + k = rep[i]; | |
| 316 | + if (typeof k === 'string') { | |
| 317 | + v = str(k, value); | |
| 318 | + if (v) { | |
| 319 | + partial.push(quote(k) + (gap ? ': ' : ':') + v); | |
| 320 | + } | |
| 321 | + } | |
| 322 | + } | |
| 323 | + } else { | |
| 324 | + | |
| 325 | +// Otherwise, iterate through all of the keys in the object. | |
| 326 | + | |
| 327 | + for (k in value) { | |
| 328 | + if (Object.hasOwnProperty.call(value, k)) { | |
| 329 | + v = str(k, value); | |
| 330 | + if (v) { | |
| 331 | + partial.push(quote(k) + (gap ? ': ' : ':') + v); | |
| 332 | + } | |
| 333 | + } | |
| 334 | + } | |
| 335 | + } | |
| 336 | + | |
| 337 | +// Join all of the member texts together, separated with commas, | |
| 338 | +// and wrap them in braces. | |
| 339 | + | |
| 340 | + v = partial.length === 0 ? '{}' : | |
| 341 | + gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + | |
| 342 | + mind + '}' : '{' + partial.join(',') + '}'; | |
| 343 | + gap = mind; | |
| 344 | + return v; | |
| 345 | + } | |
| 346 | + } | |
| 347 | + | |
| 348 | +// If the JSON object does not yet have a stringify method, give it one. | |
| 349 | + | |
| 350 | + if (typeof JSON.stringify !== 'function') { | |
| 351 | + JSON.stringify = function (value, replacer, space) { | |
| 352 | + | |
| 353 | +// The stringify method takes a value and an optional replacer, and an optional | |
| 354 | +// space parameter, and returns a JSON text. The replacer can be a function | |
| 355 | +// that can replace values, or an array of strings that will select the keys. | |
| 356 | +// A default replacer method can be provided. Use of the space parameter can | |
| 357 | +// produce text that is more easily readable. | |
| 358 | + | |
| 359 | + var i; | |
| 360 | + gap = ''; | |
| 361 | + indent = ''; | |
| 362 | + | |
| 363 | +// If the space parameter is a number, make an indent string containing that | |
| 364 | +// many spaces. | |
| 365 | + | |
| 366 | + if (typeof space === 'number') { | |
| 367 | + for (i = 0; i < space; i += 1) { | |
| 368 | + indent += ' '; | |
| 369 | + } | |
| 370 | + | |
| 371 | +// If the space parameter is a string, it will be used as the indent string. | |
| 372 | + | |
| 373 | + } else if (typeof space === 'string') { | |
| 374 | + indent = space; | |
| 375 | + } | |
| 376 | + | |
| 377 | +// If there is a replacer, it must be a function or an array. | |
| 378 | +// Otherwise, throw an error. | |
| 379 | + | |
| 380 | + rep = replacer; | |
| 381 | + if (replacer && typeof replacer !== 'function' && | |
| 382 | + (typeof replacer !== 'object' || | |
| 383 | + typeof replacer.length !== 'number')) { | |
| 384 | + throw new Error('JSON.stringify'); | |
| 385 | + } | |
| 386 | + | |
| 387 | +// Make a fake root object containing our value under the key of ''. | |
| 388 | +// Return the result of stringifying the value. | |
| 389 | + | |
| 390 | + return str('', {'': value}); | |
| 391 | + }; | |
| 392 | + } | |
| 393 | + | |
| 394 | + | |
| 395 | +// If the JSON object does not yet have a parse method, give it one. | |
| 396 | + | |
| 397 | + if (typeof JSON.parse !== 'function') { | |
| 398 | + JSON.parse = function (text, reviver) { | |
| 399 | + | |
| 400 | +// The parse method takes a text and an optional reviver function, and returns | |
| 401 | +// a JavaScript value if the text is a valid JSON text. | |
| 402 | + | |
| 403 | + var j; | |
| 404 | + | |
| 405 | + function walk(holder, key) { | |
| 406 | + | |
| 407 | +// The walk method is used to recursively walk the resulting structure so | |
| 408 | +// that modifications can be made. | |
| 409 | + | |
| 410 | + var k, v, value = holder[key]; | |
| 411 | + if (value && typeof value === 'object') { | |
| 412 | + for (k in value) { | |
| 413 | + if (Object.hasOwnProperty.call(value, k)) { | |
| 414 | + v = walk(value, k); | |
| 415 | + if (v !== undefined) { | |
| 416 | + value[k] = v; | |
| 417 | + } else { | |
| 418 | + delete value[k]; | |
| 419 | + } | |
| 420 | + } | |
| 421 | + } | |
| 422 | + } | |
| 423 | + return reviver.call(holder, key, value); | |
| 424 | + } | |
| 425 | + | |
| 426 | + | |
| 427 | +// Parsing happens in four stages. In the first stage, we replace certain | |
| 428 | +// Unicode characters with escape sequences. JavaScript handles many characters | |
| 429 | +// incorrectly, either silently deleting them, or treating them as line endings. | |
| 430 | + | |
| 431 | + cx.lastIndex = 0; | |
| 432 | + if (cx.test(text)) { | |
| 433 | + text = text.replace(cx, function (a) { | |
| 434 | + return '\\u' + | |
| 435 | + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); | |
| 436 | + }); | |
| 437 | + } | |
| 438 | + | |
| 439 | +// In the second stage, we run the text against regular expressions that look | |
| 440 | +// for non-JSON patterns. We are especially concerned with '()' and 'new' | |
| 441 | +// because they can cause invocation, and '=' because it can cause mutation. | |
| 442 | +// But just to be safe, we want to reject all unexpected forms. | |
| 443 | + | |
| 444 | +// We split the second stage into 4 regexp operations in order to work around | |
| 445 | +// crippling inefficiencies in IE's and Safari's regexp engines. First we | |
| 446 | +// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we | |
| 447 | +// replace all simple value tokens with ']' characters. Third, we delete all | |
| 448 | +// open brackets that follow a colon or comma or that begin the text. Finally, | |
| 449 | +// we look to see that the remaining characters are only whitespace or ']' or | |
| 450 | +// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. | |
| 451 | + | |
| 452 | + if (/^[\],:{}\s]*$/. | |
| 453 | +test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@'). | |
| 454 | +replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']'). | |
| 455 | +replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { | |
| 456 | + | |
| 457 | +// In the third stage we use the eval function to compile the text into a | |
| 458 | +// JavaScript structure. The '{' operator is subject to a syntactic ambiguity | |
| 459 | +// in JavaScript: it can begin a block or an object literal. We wrap the text | |
| 460 | +// in parens to eliminate the ambiguity. | |
| 461 | + | |
| 462 | + j = eval('(' + text + ')'); | |
| 463 | + | |
| 464 | +// In the optional fourth stage, we recursively walk the new structure, passing | |
| 465 | +// each name/value pair to a reviver function for possible transformation. | |
| 466 | + | |
| 467 | + return typeof reviver === 'function' ? | |
| 468 | + walk({'': j}, '') : j; | |
| 469 | + } | |
| 470 | + | |
| 471 | +// If the text is not JSON parseable, then a SyntaxError is thrown. | |
| 472 | + | |
| 473 | + throw new SyntaxError('JSON.parse'); | |
| 474 | + }; | |
| 475 | + } | |
| 476 | +}()); |
| --- a/ajax/js/json2.js | |
| +++ b/ajax/js/json2.js | |
| @@ -0,0 +1,476 @@ | |
| --- a/ajax/js/json2.js | |
| +++ b/ajax/js/json2.js | |
| @@ -0,0 +1,476 @@ | |
| 1 | /* |
| 2 | http://www.JSON.org/json2.js |
| 3 | 2009-06-29 |
| 4 | |
| 5 | Public Domain. |
| 6 | |
| 7 | NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. |
| 8 | |
| 9 | See http://www.JSON.org/js.html |
| 10 | |
| 11 | This file creates a global JSON object containing two methods: stringify |
| 12 | and parse. |
| 13 | |
| 14 | JSON.stringify(value, replacer, space) |
| 15 | value any JavaScript value, usually an object or array. |
| 16 | |
| 17 | replacer an optional parameter that determines how object |
| 18 | values are stringified for objects. It can be a |
| 19 | function or an array of strings. |
| 20 | |
| 21 | space an optional parameter that specifies the indentation |
| 22 | of nested structures. If it is omitted, the text will |
| 23 | be packed without extra whitespace. If it is a number, |
| 24 | it will specify the number of spaces to indent at each |
| 25 | level. If it is a string (such as '\t' or ' '), |
| 26 | it contains the characters used to indent at each level. |
| 27 | |
| 28 | This method produces a JSON text from a JavaScript value. |
| 29 | |
| 30 | When an object value is found, if the object contains a toJSON |
| 31 | method, its toJSON method will be called and the result will be |
| 32 | stringified. A toJSON method does not serialize: it returns the |
| 33 | value represented by the name/value pair that should be serialized, |
| 34 | or undefined if nothing should be serialized. The toJSON method |
| 35 | will be passed the key associated with the value, and this will be |
| 36 | bound to the object holding the key. |
| 37 | |
| 38 | For example, this would serialize Dates as ISO strings. |
| 39 | |
| 40 | Date.prototype.toJSON = function (key) { |
| 41 | function f(n) { |
| 42 | // Format integers to have at least two digits. |
| 43 | return n < 10 ? '0' + n : n; |
| 44 | } |
| 45 | |
| 46 | return this.getUTCFullYear() + '-' + |
| 47 | f(this.getUTCMonth() + 1) + '-' + |
| 48 | f(this.getUTCDate()) + 'T' + |
| 49 | f(this.getUTCHours()) + ':' + |
| 50 | f(this.getUTCMinutes()) + ':' + |
| 51 | f(this.getUTCSeconds()) + 'Z'; |
| 52 | }; |
| 53 | |
| 54 | You can provide an optional replacer method. It will be passed the |
| 55 | key and value of each member, with this bound to the containing |
| 56 | object. The value that is returned from your method will be |
| 57 | serialized. If your method returns undefined, then the member will |
| 58 | be excluded from the serialization. |
| 59 | |
| 60 | If the replacer parameter is an array of strings, then it will be |
| 61 | used to select the members to be serialized. It filters the results |
| 62 | such that only members with keys listed in the replacer array are |
| 63 | stringified. |
| 64 | |
| 65 | Values that do not have JSON representations, such as undefined or |
| 66 | functions, will not be serialized. Such values in objects will be |
| 67 | dropped; in arrays they will be replaced with null. You can use |
| 68 | a replacer function to replace those with JSON values. |
| 69 | JSON.stringify(undefined) returns undefined. |
| 70 | |
| 71 | The optional space parameter produces a stringification of the |
| 72 | value that is filled with line breaks and indentation to make it |
| 73 | easier to read. |
| 74 | |
| 75 | If the space parameter is a non-empty string, then that string will |
| 76 | be used for indentation. If the space parameter is a number, then |
| 77 | the indentation will be that many spaces. |
| 78 | |
| 79 | Example: |
| 80 | |
| 81 | text = JSON.stringify(['e', {pluribus: 'unum'}]); |
| 82 | // text is '["e",{"pluribus":"unum"}]' |
| 83 | |
| 84 | |
| 85 | text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t'); |
| 86 | // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' |
| 87 | |
| 88 | text = JSON.stringify([new Date()], function (key, value) { |
| 89 | return this[key] instanceof Date ? |
| 90 | 'Date(' + this[key] + ')' : value; |
| 91 | }); |
| 92 | // text is '["Date(---current time---)"]' |
| 93 | |
| 94 | |
| 95 | JSON.parse(text, reviver) |
| 96 | This method parses a JSON text to produce an object or array. |
| 97 | It can throw a SyntaxError exception. |
| 98 | |
| 99 | The optional reviver parameter is a function that can filter and |
| 100 | transform the results. It receives each of the keys and values, |
| 101 | and its return value is used instead of the original value. |
| 102 | If it returns what it received, then the structure is not modified. |
| 103 | If it returns undefined then the member is deleted. |
| 104 | |
| 105 | Example: |
| 106 | |
| 107 | // Parse the text. Values that look like ISO date strings will |
| 108 | // be converted to Date objects. |
| 109 | |
| 110 | myData = JSON.parse(text, function (key, value) { |
| 111 | var a; |
| 112 | if (typeof value === 'string') { |
| 113 | a = |
| 114 | /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); |
| 115 | if (a) { |
| 116 | return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], |
| 117 | +a[5], +a[6])); |
| 118 | } |
| 119 | } |
| 120 | return value; |
| 121 | }); |
| 122 | |
| 123 | myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) { |
| 124 | var d; |
| 125 | if (typeof value === 'string' && |
| 126 | value.slice(0, 5) === 'Date(' && |
| 127 | value.slice(-1) === ')') { |
| 128 | d = new Date(value.slice(5, -1)); |
| 129 | if (d) { |
| 130 | return d; |
| 131 | } |
| 132 | } |
| 133 | return value; |
| 134 | }); |
| 135 | |
| 136 | |
| 137 | This is a reference implementation. You are free to copy, modify, or |
| 138 | redistribute. |
| 139 | |
| 140 | This code should be minified before deployment. |
| 141 | See http://javascript.crockford.com/jsmin.html |
| 142 | |
| 143 | USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO |
| 144 | NOT CONTROL. |
| 145 | */ |
| 146 | |
| 147 | /*jslint evil: true */ |
| 148 | |
| 149 | /*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply, |
| 150 | call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, |
| 151 | getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, |
| 152 | lastIndex, length, parse, prototype, push, replace, slice, stringify, |
| 153 | test, toJSON, toString, valueOf |
| 154 | */ |
| 155 | |
| 156 | // Create a JSON object only if one does not already exist. We create the |
| 157 | // methods in a closure to avoid creating global variables. |
| 158 | |
| 159 | var JSON = JSON || {}; |
| 160 | |
| 161 | (function () { |
| 162 | |
| 163 | function f(n) { |
| 164 | // Format integers to have at least two digits. |
| 165 | return n < 10 ? '0' + n : n; |
| 166 | } |
| 167 | |
| 168 | if (typeof Date.prototype.toJSON !== 'function') { |
| 169 | |
| 170 | Date.prototype.toJSON = function (key) { |
| 171 | |
| 172 | return isFinite(this.valueOf()) ? |
| 173 | this.getUTCFullYear() + '-' + |
| 174 | f(this.getUTCMonth() + 1) + '-' + |
| 175 | f(this.getUTCDate()) + 'T' + |
| 176 | f(this.getUTCHours()) + ':' + |
| 177 | f(this.getUTCMinutes()) + ':' + |
| 178 | f(this.getUTCSeconds()) + 'Z' : null; |
| 179 | }; |
| 180 | |
| 181 | String.prototype.toJSON = |
| 182 | Number.prototype.toJSON = |
| 183 | Boolean.prototype.toJSON = function (key) { |
| 184 | return this.valueOf(); |
| 185 | }; |
| 186 | } |
| 187 | |
| 188 | var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, |
| 189 | escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, |
| 190 | gap, |
| 191 | indent, |
| 192 | meta = { // table of character substitutions |
| 193 | '\b': '\\b', |
| 194 | '\t': '\\t', |
| 195 | '\n': '\\n', |
| 196 | '\f': '\\f', |
| 197 | '\r': '\\r', |
| 198 | '"' : '\\"', |
| 199 | '\\': '\\\\' |
| 200 | }, |
| 201 | rep; |
| 202 | |
| 203 | |
| 204 | function quote(string) { |
| 205 | |
| 206 | // If the string contains no control characters, no quote characters, and no |
| 207 | // backslash characters, then we can safely slap some quotes around it. |
| 208 | // Otherwise we must also replace the offending characters with safe escape |
| 209 | // sequences. |
| 210 | |
| 211 | escapable.lastIndex = 0; |
| 212 | return escapable.test(string) ? |
| 213 | '"' + string.replace(escapable, function (a) { |
| 214 | var c = meta[a]; |
| 215 | return typeof c === 'string' ? c : |
| 216 | '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); |
| 217 | }) + '"' : |
| 218 | '"' + string + '"'; |
| 219 | } |
| 220 | |
| 221 | |
| 222 | function str(key, holder) { |
| 223 | |
| 224 | // Produce a string from holder[key]. |
| 225 | |
| 226 | var i, // The loop counter. |
| 227 | k, // The member key. |
| 228 | v, // The member value. |
| 229 | length, |
| 230 | mind = gap, |
| 231 | partial, |
| 232 | value = holder[key]; |
| 233 | |
| 234 | // If the value has a toJSON method, call it to obtain a replacement value. |
| 235 | |
| 236 | if (value && typeof value === 'object' && |
| 237 | typeof value.toJSON === 'function') { |
| 238 | value = value.toJSON(key); |
| 239 | } |
| 240 | |
| 241 | // If we were called with a replacer function, then call the replacer to |
| 242 | // obtain a replacement value. |
| 243 | |
| 244 | if (typeof rep === 'function') { |
| 245 | value = rep.call(holder, key, value); |
| 246 | } |
| 247 | |
| 248 | // What happens next depends on the value's type. |
| 249 | |
| 250 | switch (typeof value) { |
| 251 | case 'string': |
| 252 | return quote(value); |
| 253 | |
| 254 | case 'number': |
| 255 | |
| 256 | // JSON numbers must be finite. Encode non-finite numbers as null. |
| 257 | |
| 258 | return isFinite(value) ? String(value) : 'null'; |
| 259 | |
| 260 | case 'boolean': |
| 261 | case 'null': |
| 262 | |
| 263 | // If the value is a boolean or null, convert it to a string. Note: |
| 264 | // typeof null does not produce 'null'. The case is included here in |
| 265 | // the remote chance that this gets fixed someday. |
| 266 | |
| 267 | return String(value); |
| 268 | |
| 269 | // If the type is 'object', we might be dealing with an object or an array or |
| 270 | // null. |
| 271 | |
| 272 | case 'object': |
| 273 | |
| 274 | // Due to a specification blunder in ECMAScript, typeof null is 'object', |
| 275 | // so watch out for that case. |
| 276 | |
| 277 | if (!value) { |
| 278 | return 'null'; |
| 279 | } |
| 280 | |
| 281 | // Make an array to hold the partial results of stringifying this object value. |
| 282 | |
| 283 | gap += indent; |
| 284 | partial = []; |
| 285 | |
| 286 | // Is the value an array? |
| 287 | |
| 288 | if (Object.prototype.toString.apply(value) === '[object Array]') { |
| 289 | |
| 290 | // The value is an array. Stringify every element. Use null as a placeholder |
| 291 | // for non-JSON values. |
| 292 | |
| 293 | length = value.length; |
| 294 | for (i = 0; i < length; i += 1) { |
| 295 | partial[i] = str(i, value) || 'null'; |
| 296 | } |
| 297 | |
| 298 | // Join all of the elements together, separated with commas, and wrap them in |
| 299 | // brackets. |
| 300 | |
| 301 | v = partial.length === 0 ? '[]' : |
| 302 | gap ? '[\n' + gap + |
| 303 | partial.join(',\n' + gap) + '\n' + |
| 304 | mind + ']' : |
| 305 | '[' + partial.join(',') + ']'; |
| 306 | gap = mind; |
| 307 | return v; |
| 308 | } |
| 309 | |
| 310 | // If the replacer is an array, use it to select the members to be stringified. |
| 311 | |
| 312 | if (rep && typeof rep === 'object') { |
| 313 | length = rep.length; |
| 314 | for (i = 0; i < length; i += 1) { |
| 315 | k = rep[i]; |
| 316 | if (typeof k === 'string') { |
| 317 | v = str(k, value); |
| 318 | if (v) { |
| 319 | partial.push(quote(k) + (gap ? ': ' : ':') + v); |
| 320 | } |
| 321 | } |
| 322 | } |
| 323 | } else { |
| 324 | |
| 325 | // Otherwise, iterate through all of the keys in the object. |
| 326 | |
| 327 | for (k in value) { |
| 328 | if (Object.hasOwnProperty.call(value, k)) { |
| 329 | v = str(k, value); |
| 330 | if (v) { |
| 331 | partial.push(quote(k) + (gap ? ': ' : ':') + v); |
| 332 | } |
| 333 | } |
| 334 | } |
| 335 | } |
| 336 | |
| 337 | // Join all of the member texts together, separated with commas, |
| 338 | // and wrap them in braces. |
| 339 | |
| 340 | v = partial.length === 0 ? '{}' : |
| 341 | gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + |
| 342 | mind + '}' : '{' + partial.join(',') + '}'; |
| 343 | gap = mind; |
| 344 | return v; |
| 345 | } |
| 346 | } |
| 347 | |
| 348 | // If the JSON object does not yet have a stringify method, give it one. |
| 349 | |
| 350 | if (typeof JSON.stringify !== 'function') { |
| 351 | JSON.stringify = function (value, replacer, space) { |
| 352 | |
| 353 | // The stringify method takes a value and an optional replacer, and an optional |
| 354 | // space parameter, and returns a JSON text. The replacer can be a function |
| 355 | // that can replace values, or an array of strings that will select the keys. |
| 356 | // A default replacer method can be provided. Use of the space parameter can |
| 357 | // produce text that is more easily readable. |
| 358 | |
| 359 | var i; |
| 360 | gap = ''; |
| 361 | indent = ''; |
| 362 | |
| 363 | // If the space parameter is a number, make an indent string containing that |
| 364 | // many spaces. |
| 365 | |
| 366 | if (typeof space === 'number') { |
| 367 | for (i = 0; i < space; i += 1) { |
| 368 | indent += ' '; |
| 369 | } |
| 370 | |
| 371 | // If the space parameter is a string, it will be used as the indent string. |
| 372 | |
| 373 | } else if (typeof space === 'string') { |
| 374 | indent = space; |
| 375 | } |
| 376 | |
| 377 | // If there is a replacer, it must be a function or an array. |
| 378 | // Otherwise, throw an error. |
| 379 | |
| 380 | rep = replacer; |
| 381 | if (replacer && typeof replacer !== 'function' && |
| 382 | (typeof replacer !== 'object' || |
| 383 | typeof replacer.length !== 'number')) { |
| 384 | throw new Error('JSON.stringify'); |
| 385 | } |
| 386 | |
| 387 | // Make a fake root object containing our value under the key of ''. |
| 388 | // Return the result of stringifying the value. |
| 389 | |
| 390 | return str('', {'': value}); |
| 391 | }; |
| 392 | } |
| 393 | |
| 394 | |
| 395 | // If the JSON object does not yet have a parse method, give it one. |
| 396 | |
| 397 | if (typeof JSON.parse !== 'function') { |
| 398 | JSON.parse = function (text, reviver) { |
| 399 | |
| 400 | // The parse method takes a text and an optional reviver function, and returns |
| 401 | // a JavaScript value if the text is a valid JSON text. |
| 402 | |
| 403 | var j; |
| 404 | |
| 405 | function walk(holder, key) { |
| 406 | |
| 407 | // The walk method is used to recursively walk the resulting structure so |
| 408 | // that modifications can be made. |
| 409 | |
| 410 | var k, v, value = holder[key]; |
| 411 | if (value && typeof value === 'object') { |
| 412 | for (k in value) { |
| 413 | if (Object.hasOwnProperty.call(value, k)) { |
| 414 | v = walk(value, k); |
| 415 | if (v !== undefined) { |
| 416 | value[k] = v; |
| 417 | } else { |
| 418 | delete value[k]; |
| 419 | } |
| 420 | } |
| 421 | } |
| 422 | } |
| 423 | return reviver.call(holder, key, value); |
| 424 | } |
| 425 | |
| 426 | |
| 427 | // Parsing happens in four stages. In the first stage, we replace certain |
| 428 | // Unicode characters with escape sequences. JavaScript handles many characters |
| 429 | // incorrectly, either silently deleting them, or treating them as line endings. |
| 430 | |
| 431 | cx.lastIndex = 0; |
| 432 | if (cx.test(text)) { |
| 433 | text = text.replace(cx, function (a) { |
| 434 | return '\\u' + |
| 435 | ('0000' + a.charCodeAt(0).toString(16)).slice(-4); |
| 436 | }); |
| 437 | } |
| 438 | |
| 439 | // In the second stage, we run the text against regular expressions that look |
| 440 | // for non-JSON patterns. We are especially concerned with '()' and 'new' |
| 441 | // because they can cause invocation, and '=' because it can cause mutation. |
| 442 | // But just to be safe, we want to reject all unexpected forms. |
| 443 | |
| 444 | // We split the second stage into 4 regexp operations in order to work around |
| 445 | // crippling inefficiencies in IE's and Safari's regexp engines. First we |
| 446 | // replace the JSON backslash pairs with '@' (a non-JSON character). Second, we |
| 447 | // replace all simple value tokens with ']' characters. Third, we delete all |
| 448 | // open brackets that follow a colon or comma or that begin the text. Finally, |
| 449 | // we look to see that the remaining characters are only whitespace or ']' or |
| 450 | // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. |
| 451 | |
| 452 | if (/^[\],:{}\s]*$/. |
| 453 | test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@'). |
| 454 | replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']'). |
| 455 | replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { |
| 456 | |
| 457 | // In the third stage we use the eval function to compile the text into a |
| 458 | // JavaScript structure. The '{' operator is subject to a syntactic ambiguity |
| 459 | // in JavaScript: it can begin a block or an object literal. We wrap the text |
| 460 | // in parens to eliminate the ambiguity. |
| 461 | |
| 462 | j = eval('(' + text + ')'); |
| 463 | |
| 464 | // In the optional fourth stage, we recursively walk the new structure, passing |
| 465 | // each name/value pair to a reviver function for possible transformation. |
| 466 | |
| 467 | return typeof reviver === 'function' ? |
| 468 | walk({'': j}, '') : j; |
| 469 | } |
| 470 | |
| 471 | // If the text is not JSON parseable, then a SyntaxError is thrown. |
| 472 | |
| 473 | throw new SyntaxError('JSON.parse'); |
| 474 | }; |
| 475 | } |
| 476 | }()); |
+70
| --- a/ajax/js/whajaj.js | ||
| +++ b/ajax/js/whajaj.js | ||
| @@ -0,0 +1,70 @@ | ||
| 1 | +/** | |
| 2 | + This file provides a JS interface into the core functionality of | |
| 3 | + JSON-centric back-ends. It sends GET or JSON POST requests to | |
| 4 | + a back-end and expects JSON responses. The exact semantics of | |
| 5 | + the underlying back-end and overlying front-end are not its concern, | |
| 6 | + and it leaves the interpretation of the data up to the client/server | |
| 7 | + insofar as possible. | |
| 8 | + | |
| 9 | + All functionality is part of a class named WhAjaj, and that class | |
| 10 | + acts as namespace for this framework. | |
| 11 | + | |
| 12 | + Author: Stephan Beal (http://wanderinghorse.net/home/stephan/) | |
| 13 | + | |
| 14 | + License: Public Domain | |
| 15 | + | |
| 16 | + This framework is directly derived from code originally found in | |
| 17 | + http://code.google.com/ | |
| 18 | + http://whiki.wanderinghorse.net, where it contained quite a bit | |
| 19 | + of application-specific logic. It was eventually (the 3rd time i | |
| 20 | + needed it) split off into its own library to simplify inclusion | |
| 21 | + into my many mini-projects. | |
| 22 | +*/ | |
| 23 | + | |
| 24 | + | |
| 25 | +/** | |
| 26 | + The WhAjaj function is primarily a namespace, and not intended | |
| 27 | + to called or instantiated via the 'new' operator. | |
| 28 | +*/ | |
| 29 | +function WhAjaj() | |
| 30 | +{ | |
| 31 | +} | |
| 32 | + | |
| 33 | +/** Returns a millisecew Date()).getTime(); | |
| 34 | +}; | |
| 35 | + | |
| 36 | +/** Returns a Unix Epoch timestamp (in seconds) in integer format. | |
| 37 | + | |
| 38 | + Reminder to self: (1.1 %1.2) evaluate | |
| 39 | + in JS, and thus this implementation is less thundefinedation is less than optimal. | |
| 40 | +*/ | |
| 41 | +WhAjaj.unixTimestamp = function() | |
| 42 | +{ | |
| 43 | + var ts = (new Date()).getTime(); | |
| 44 | + return parseInt( ""+((ts / 1000) % ts) ); | |
| 45 | +}; | |
| 46 | + | |
| 47 | +/** | |
| 48 | + Returns true if v is-a Array instance. | |
| 49 | +*/ | |
| 50 | +WhAja {name:name, password:pw** | |
| 51 | + This file provides a JS interface into the core functionality of | |
| 52 | + JSON-centric back-ends. It sends GET or JSON POST requests to | |
| 53 | + a back-end and expecJ the very first | |
| 54 | + and see where i | |
| 55 | + break my other | |
| 56 | + th that | |
| 57 | + string). The initiatingest object is | |
| 58 | + can normally specific expects JSON responses. The exact semantics of | |
| 59 | + the underlying back-end and overlying front-/** | |
| 60 | + This file prov callbacks (set in | |
| 61 | +( require it in some | |
| 62 | + which | |
| 63 | + * | |
| 64 | + This file prov interface into the | |
| 65 | + indicates an | |
| 66 | + to produces | |
| 67 | + a back-end a/** | |
| 68 | + This f | |
| 69 | + //if( json ) json = json.replace(/ö/g,"\\u00f6") /* ONLY FOR A SPECIFIC TEST */; | |
| 70 | + |
| --- a/ajax/js/whajaj.js | |
| +++ b/ajax/js/whajaj.js | |
| @@ -0,0 +1,70 @@ | |
| --- a/ajax/js/whajaj.js | |
| +++ b/ajax/js/whajaj.js | |
| @@ -0,0 +1,70 @@ | |
| 1 | /** |
| 2 | This file provides a JS interface into the core functionality of |
| 3 | JSON-centric back-ends. It sends GET or JSON POST requests to |
| 4 | a back-end and expects JSON responses. The exact semantics of |
| 5 | the underlying back-end and overlying front-end are not its concern, |
| 6 | and it leaves the interpretation of the data up to the client/server |
| 7 | insofar as possible. |
| 8 | |
| 9 | All functionality is part of a class named WhAjaj, and that class |
| 10 | acts as namespace for this framework. |
| 11 | |
| 12 | Author: Stephan Beal (http://wanderinghorse.net/home/stephan/) |
| 13 | |
| 14 | License: Public Domain |
| 15 | |
| 16 | This framework is directly derived from code originally found in |
| 17 | http://code.google.com/ |
| 18 | http://whiki.wanderinghorse.net, where it contained quite a bit |
| 19 | of application-specific logic. It was eventually (the 3rd time i |
| 20 | needed it) split off into its own library to simplify inclusion |
| 21 | into my many mini-projects. |
| 22 | */ |
| 23 | |
| 24 | |
| 25 | /** |
| 26 | The WhAjaj function is primarily a namespace, and not intended |
| 27 | to called or instantiated via the 'new' operator. |
| 28 | */ |
| 29 | function WhAjaj() |
| 30 | { |
| 31 | } |
| 32 | |
| 33 | /** Returns a millisecew Date()).getTime(); |
| 34 | }; |
| 35 | |
| 36 | /** Returns a Unix Epoch timestamp (in seconds) in integer format. |
| 37 | |
| 38 | Reminder to self: (1.1 %1.2) evaluate |
| 39 | in JS, and thus this implementation is less thundefinedation is less than optimal. |
| 40 | */ |
| 41 | WhAjaj.unixTimestamp = function() |
| 42 | { |
| 43 | var ts = (new Date()).getTime(); |
| 44 | return parseInt( ""+((ts / 1000) % ts) ); |
| 45 | }; |
| 46 | |
| 47 | /** |
| 48 | Returns true if v is-a Array instance. |
| 49 | */ |
| 50 | WhAja {name:name, password:pw** |
| 51 | This file provides a JS interface into the core functionality of |
| 52 | JSON-centric back-ends. It sends GET or JSON POST requests to |
| 53 | a back-end and expecJ the very first |
| 54 | and see where i |
| 55 | break my other |
| 56 | th that |
| 57 | string). The initiatingest object is |
| 58 | can normally specific expects JSON responses. The exact semantics of |
| 59 | the underlying back-end and overlying front-/** |
| 60 | This file prov callbacks (set in |
| 61 | ( require it in some |
| 62 | which |
| 63 | * |
| 64 | This file prov interface into the |
| 65 | indicates an |
| 66 | to produces |
| 67 | a back-end a/** |
| 68 | This f |
| 69 | //if( json ) json = json.replace(/ö/g,"\\u00f6") /* ONLY FOR A SPECIFIC TEST */; |
| 70 |
| --- a/ajax/wiki-editor.html | ||
| +++ b/ajax/wiki-editor.html | ||
| @@ -0,0 +1,3 @@ | ||
| 1 | +<!DOCTYPE html PUBLIC "-//W3C | |
| 2 | + /DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | |
| 3 | +<html xmlns="http://www.w3.org/1999/xhtml" xml:l |
| --- a/ajax/wiki-editor.html | |
| +++ b/ajax/wiki-editor.html | |
| @@ -0,0 +1,3 @@ | |
| --- a/ajax/wiki-editor.html | |
| +++ b/ajax/wiki-editor.html | |
| @@ -0,0 +1,3 @@ | |
| 1 | <!DOCTYPE html PUBLIC "-//W3C |
| 2 | /DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> |
| 3 | <html xmlns="http://www.w3.org/1999/xhtml" xml:l |
M
auto.def
+5
| --- auto.def | ||
| +++ auto.def | ||
| @@ -9,10 +9,11 @@ | ||
| 9 | 9 | with-tcl:path => {Enable Tcl integration, with Tcl in the specified path} |
| 10 | 10 | internal-sqlite=1 => {Don't use the internal sqlite, use the system one} |
| 11 | 11 | static=0 => {Link a static executable} |
| 12 | 12 | lineedit=1 => {Disable line editing} |
| 13 | 13 | fossil-debug=0 => {Build with fossil debugging enabled} |
| 14 | + json=0 => {Build with fossil JSON API enabled} | |
| 14 | 15 | } |
| 15 | 16 | |
| 16 | 17 | # sqlite wants these types if possible |
| 17 | 18 | cc-with {-includes {stdint.h inttypes.h}} { |
| 18 | 19 | cc-check-types uint32_t uint16_t int16_t uint8_t |
| @@ -62,10 +63,14 @@ | ||
| 62 | 63 | } |
| 63 | 64 | |
| 64 | 65 | if {[opt-bool fossil-debug]} { |
| 65 | 66 | define-append EXTRA_CFLAGS -DFOSSIL_DEBUG |
| 66 | 67 | } |
| 68 | + | |
| 69 | +if {[opt-bool json]} { | |
| 70 | + define-append EXTRA_CFLAGS -DFOSSIL_ENABLE_JSON | |
| 71 | +} | |
| 67 | 72 | |
| 68 | 73 | if {[opt-bool static]} { |
| 69 | 74 | # XXX: This will not work on all systems. |
| 70 | 75 | define-append EXTRA_LDFLAGS -static |
| 71 | 76 | } |
| 72 | 77 | |
| 73 | 78 | ADDED src/Makefile |
| --- auto.def | |
| +++ auto.def | |
| @@ -9,10 +9,11 @@ | |
| 9 | with-tcl:path => {Enable Tcl integration, with Tcl in the specified path} |
| 10 | internal-sqlite=1 => {Don't use the internal sqlite, use the system one} |
| 11 | static=0 => {Link a static executable} |
| 12 | lineedit=1 => {Disable line editing} |
| 13 | fossil-debug=0 => {Build with fossil debugging enabled} |
| 14 | } |
| 15 | |
| 16 | # sqlite wants these types if possible |
| 17 | cc-with {-includes {stdint.h inttypes.h}} { |
| 18 | cc-check-types uint32_t uint16_t int16_t uint8_t |
| @@ -62,10 +63,14 @@ | |
| 62 | } |
| 63 | |
| 64 | if {[opt-bool fossil-debug]} { |
| 65 | define-append EXTRA_CFLAGS -DFOSSIL_DEBUG |
| 66 | } |
| 67 | |
| 68 | if {[opt-bool static]} { |
| 69 | # XXX: This will not work on all systems. |
| 70 | define-append EXTRA_LDFLAGS -static |
| 71 | } |
| 72 | |
| 73 | DDED src/Makefile |
| --- auto.def | |
| +++ auto.def | |
| @@ -9,10 +9,11 @@ | |
| 9 | with-tcl:path => {Enable Tcl integration, with Tcl in the specified path} |
| 10 | internal-sqlite=1 => {Don't use the internal sqlite, use the system one} |
| 11 | static=0 => {Link a static executable} |
| 12 | lineedit=1 => {Disable line editing} |
| 13 | fossil-debug=0 => {Build with fossil debugging enabled} |
| 14 | json=0 => {Build with fossil JSON API enabled} |
| 15 | } |
| 16 | |
| 17 | # sqlite wants these types if possible |
| 18 | cc-with {-includes {stdint.h inttypes.h}} { |
| 19 | cc-check-types uint32_t uint16_t int16_t uint8_t |
| @@ -62,10 +63,14 @@ | |
| 63 | } |
| 64 | |
| 65 | if {[opt-bool fossil-debug]} { |
| 66 | define-append EXTRA_CFLAGS -DFOSSIL_DEBUG |
| 67 | } |
| 68 | |
| 69 | if {[opt-bool json]} { |
| 70 | define-append EXTRA_CFLAGS -DFOSSIL_ENABLE_JSON |
| 71 | } |
| 72 | |
| 73 | if {[opt-bool static]} { |
| 74 | # XXX: This will not work on all systems. |
| 75 | define-append EXTRA_LDFLAGS -static |
| 76 | } |
| 77 | |
| 78 | DDED src/Makefile |
M
auto.def
+5
| --- auto.def | ||
| +++ auto.def | ||
| @@ -9,10 +9,11 @@ | ||
| 9 | 9 | with-tcl:path => {Enable Tcl integration, with Tcl in the specified path} |
| 10 | 10 | internal-sqlite=1 => {Don't use the internal sqlite, use the system one} |
| 11 | 11 | static=0 => {Link a static executable} |
| 12 | 12 | lineedit=1 => {Disable line editing} |
| 13 | 13 | fossil-debug=0 => {Build with fossil debugging enabled} |
| 14 | + json=0 => {Build with fossil JSON API enabled} | |
| 14 | 15 | } |
| 15 | 16 | |
| 16 | 17 | # sqlite wants these types if possible |
| 17 | 18 | cc-with {-includes {stdint.h inttypes.h}} { |
| 18 | 19 | cc-check-types uint32_t uint16_t int16_t uint8_t |
| @@ -62,10 +63,14 @@ | ||
| 62 | 63 | } |
| 63 | 64 | |
| 64 | 65 | if {[opt-bool fossil-debug]} { |
| 65 | 66 | define-append EXTRA_CFLAGS -DFOSSIL_DEBUG |
| 66 | 67 | } |
| 68 | + | |
| 69 | +if {[opt-bool json]} { | |
| 70 | + define-append EXTRA_CFLAGS -DFOSSIL_ENABLE_JSON | |
| 71 | +} | |
| 67 | 72 | |
| 68 | 73 | if {[opt-bool static]} { |
| 69 | 74 | # XXX: This will not work on all systems. |
| 70 | 75 | define-append EXTRA_LDFLAGS -static |
| 71 | 76 | } |
| 72 | 77 | |
| 73 | 78 | ADDED src/Makefile |
| --- auto.def | |
| +++ auto.def | |
| @@ -9,10 +9,11 @@ | |
| 9 | with-tcl:path => {Enable Tcl integration, with Tcl in the specified path} |
| 10 | internal-sqlite=1 => {Don't use the internal sqlite, use the system one} |
| 11 | static=0 => {Link a static executable} |
| 12 | lineedit=1 => {Disable line editing} |
| 13 | fossil-debug=0 => {Build with fossil debugging enabled} |
| 14 | } |
| 15 | |
| 16 | # sqlite wants these types if possible |
| 17 | cc-with {-includes {stdint.h inttypes.h}} { |
| 18 | cc-check-types uint32_t uint16_t int16_t uint8_t |
| @@ -62,10 +63,14 @@ | |
| 62 | } |
| 63 | |
| 64 | if {[opt-bool fossil-debug]} { |
| 65 | define-append EXTRA_CFLAGS -DFOSSIL_DEBUG |
| 66 | } |
| 67 | |
| 68 | if {[opt-bool static]} { |
| 69 | # XXX: This will not work on all systems. |
| 70 | define-append EXTRA_LDFLAGS -static |
| 71 | } |
| 72 | |
| 73 | DDED src/Makefile |
| --- auto.def | |
| +++ auto.def | |
| @@ -9,10 +9,11 @@ | |
| 9 | with-tcl:path => {Enable Tcl integration, with Tcl in the specified path} |
| 10 | internal-sqlite=1 => {Don't use the internal sqlite, use the system one} |
| 11 | static=0 => {Link a static executable} |
| 12 | lineedit=1 => {Disable line editing} |
| 13 | fossil-debug=0 => {Build with fossil debugging enabled} |
| 14 | json=0 => {Build with fossil JSON API enabled} |
| 15 | } |
| 16 | |
| 17 | # sqlite wants these types if possible |
| 18 | cc-with {-includes {stdint.h inttypes.h}} { |
| 19 | cc-check-types uint32_t uint16_t int16_t uint8_t |
| @@ -62,10 +63,14 @@ | |
| 63 | } |
| 64 | |
| 65 | if {[opt-bool fossil-debug]} { |
| 66 | define-append EXTRA_CFLAGS -DFOSSIL_DEBUG |
| 67 | } |
| 68 | |
| 69 | if {[opt-bool json]} { |
| 70 | define-append EXTRA_CFLAGS -DFOSSIL_ENABLE_JSON |
| 71 | } |
| 72 | |
| 73 | if {[opt-bool static]} { |
| 74 | # XXX: This will not work on all systems. |
| 75 | define-append EXTRA_LDFLAGS -static |
| 76 | } |
| 77 | |
| 78 | DDED src/Makefile |
+2
| --- a/src/Makefile | ||
| +++ b/src/Makefile | ||
| @@ -0,0 +1,2 @@ | ||
| 1 | +all: | |
| 2 | + $(MAKE) -C .. |
| --- a/src/Makefile | |
| +++ b/src/Makefile | |
| @@ -0,0 +1,2 @@ | |
| --- a/src/Makefile | |
| +++ b/src/Makefile | |
| @@ -0,0 +1,2 @@ | |
| 1 | all: |
| 2 | $(MAKE) -C .. |
+27
| --- src/blob.c | ||
| +++ src/blob.c | ||
| @@ -1051,5 +1051,32 @@ | ||
| 1051 | 1051 | return; |
| 1052 | 1052 | } |
| 1053 | 1053 | } |
| 1054 | 1054 | blob_append(pBlob, zIn, -1); |
| 1055 | 1055 | } |
| 1056 | + | |
| 1057 | +/* | |
| 1058 | +** A read(2)-like impl for the Blob class. Reads (copies) up to nLen | |
| 1059 | +** bytes from pIn, starting at position pIn->iCursor, and copies them | |
| 1060 | +** to pDest (which must be valid memory at least nLen bytes long). | |
| 1061 | +** | |
| 1062 | +** Returns the number of bytes read/copied, which may be less than | |
| 1063 | +** nLen (if end-of-blob is encountered). | |
| 1064 | +** | |
| 1065 | +** Updates pIn's cursor. | |
| 1066 | +** | |
| 1067 | +** Returns 0 if pIn contains no data. | |
| 1068 | +*/ | |
| 1069 | +unsigned int blob_read(Blob *pIn, void * pDest, unsigned int nLen ){ | |
| 1070 | + if( !pIn->aData || (pIn->iCursor >= pIn->nUsed) ){ | |
| 1071 | + return 0; | |
| 1072 | + } else if( (pIn->iCursor + nLen) > (unsigned int)pIn->nUsed ){ | |
| 1073 | + nLen = (unsigned int) (pIn->nUsed - pIn->iCursor); | |
| 1074 | + } | |
| 1075 | + assert( pIn->nUsed > pIn->iCursor ); | |
| 1076 | + assert( (pIn->iCursor+nLen) <= pIn->nUsed ); | |
| 1077 | + if( nLen ){ | |
| 1078 | + memcpy( pDest, pIn->aData, nLen ); | |
| 1079 | + pIn->iCursor += nLen; | |
| 1080 | + } | |
| 1081 | + return nLen; | |
| 1082 | +} | |
| 1056 | 1083 |
| --- src/blob.c | |
| +++ src/blob.c | |
| @@ -1051,5 +1051,32 @@ | |
| 1051 | return; |
| 1052 | } |
| 1053 | } |
| 1054 | blob_append(pBlob, zIn, -1); |
| 1055 | } |
| 1056 |
| --- src/blob.c | |
| +++ src/blob.c | |
| @@ -1051,5 +1051,32 @@ | |
| 1051 | return; |
| 1052 | } |
| 1053 | } |
| 1054 | blob_append(pBlob, zIn, -1); |
| 1055 | } |
| 1056 | |
| 1057 | /* |
| 1058 | ** A read(2)-like impl for the Blob class. Reads (copies) up to nLen |
| 1059 | ** bytes from pIn, starting at position pIn->iCursor, and copies them |
| 1060 | ** to pDest (which must be valid memory at least nLen bytes long). |
| 1061 | ** |
| 1062 | ** Returns the number of bytes read/copied, which may be less than |
| 1063 | ** nLen (if end-of-blob is encountered). |
| 1064 | ** |
| 1065 | ** Updates pIn's cursor. |
| 1066 | ** |
| 1067 | ** Returns 0 if pIn contains no data. |
| 1068 | */ |
| 1069 | unsigned int blob_read(Blob *pIn, void * pDest, unsigned int nLen ){ |
| 1070 | if( !pIn->aData || (pIn->iCursor >= pIn->nUsed) ){ |
| 1071 | return 0; |
| 1072 | } else if( (pIn->iCursor + nLen) > (unsigned int)pIn->nUsed ){ |
| 1073 | nLen = (unsigned int) (pIn->nUsed - pIn->iCursor); |
| 1074 | } |
| 1075 | assert( pIn->nUsed > pIn->iCursor ); |
| 1076 | assert( (pIn->iCursor+nLen) <= pIn->nUsed ); |
| 1077 | if( nLen ){ |
| 1078 | memcpy( pDest, pIn->aData, nLen ); |
| 1079 | pIn->iCursor += nLen; |
| 1080 | } |
| 1081 | return nLen; |
| 1082 | } |
| 1083 |
+10
-6
| --- src/branch.c | ||
| +++ src/branch.c | ||
| @@ -178,14 +178,18 @@ | ||
| 178 | 178 | /* Do an autosync push, if requested */ |
| 179 | 179 | if( !isPrivate ) autosync(AUTOSYNC_PUSH); |
| 180 | 180 | } |
| 181 | 181 | |
| 182 | 182 | /* |
| 183 | -** Prepare a query that will list all branches. | |
| 183 | +** Prepare a query that will list branches. | |
| 184 | +** | |
| 185 | +** If (which<0) then the query pulls only closed branches. If | |
| 186 | +** (which>0) then the query pulls all (closed and opened) | |
| 187 | +** branches. Else the query pulls currently-opened branches. | |
| 184 | 188 | */ |
| 185 | -static void prepareBranchQuery(Stmt *pQuery, int showAll, int showClosed){ | |
| 186 | - if( showClosed ){ | |
| 189 | +void branch_prepare_list_query(Stmt *pQuery, int which ){ | |
| 190 | + if( which < 0 ){ | |
| 187 | 191 | db_prepare(pQuery, |
| 188 | 192 | "SELECT value FROM tagxref" |
| 189 | 193 | " WHERE tagid=%d AND value NOT NULL " |
| 190 | 194 | "EXCEPT " |
| 191 | 195 | "SELECT value FROM tagxref" |
| @@ -193,11 +197,11 @@ | ||
| 193 | 197 | " AND rid IN leaf" |
| 194 | 198 | " AND NOT %z" |
| 195 | 199 | " ORDER BY value COLLATE nocase /*sort*/", |
| 196 | 200 | TAG_BRANCH, TAG_BRANCH, leaf_is_closed_sql("tagxref.rid") |
| 197 | 201 | ); |
| 198 | - }else if( showAll ){ | |
| 202 | + }else if( which>0 ){ | |
| 199 | 203 | db_prepare(pQuery, |
| 200 | 204 | "SELECT DISTINCT value FROM tagxref" |
| 201 | 205 | " WHERE tagid=%d AND value NOT NULL" |
| 202 | 206 | " AND rid IN leaf" |
| 203 | 207 | " ORDER BY value COLLATE nocase /*sort*/", |
| @@ -260,11 +264,11 @@ | ||
| 260 | 264 | if( g.localOpen ){ |
| 261 | 265 | vid = db_lget_int("checkout", 0); |
| 262 | 266 | zCurrent = db_text(0, "SELECT value FROM tagxref" |
| 263 | 267 | " WHERE rid=%d AND tagid=%d", vid, TAG_BRANCH); |
| 264 | 268 | } |
| 265 | - prepareBranchQuery(&q, showAll, showClosed); | |
| 269 | + branch_prepare_list_query(&q, showAll?1:(showClosed?-1:0)); | |
| 266 | 270 | while( db_step(&q)==SQLITE_ROW ){ |
| 267 | 271 | const char *zBr = db_column_text(&q, 0); |
| 268 | 272 | int isCur = zCurrent!=0 && fossil_strcmp(zCurrent,zBr)==0; |
| 269 | 273 | fossil_print("%s%s\n", (isCur ? "* " : " "), zBr); |
| 270 | 274 | } |
| @@ -327,11 +331,11 @@ | ||
| 327 | 331 | @ Closed branches are fixed and do not change (unless they are first |
| 328 | 332 | @ reopened)</li> |
| 329 | 333 | @ </ol> |
| 330 | 334 | style_sidebox_end(); |
| 331 | 335 | |
| 332 | - prepareBranchQuery(&q, showAll, showClosed); | |
| 336 | + branch_prepare_list_query(&q, showAll?1:(showClosed?-1:0)); | |
| 333 | 337 | cnt = 0; |
| 334 | 338 | while( db_step(&q)==SQLITE_ROW ){ |
| 335 | 339 | const char *zBr = db_column_text(&q, 0); |
| 336 | 340 | if( cnt==0 ){ |
| 337 | 341 | if( colorTest ){ |
| 338 | 342 |
| --- src/branch.c | |
| +++ src/branch.c | |
| @@ -178,14 +178,18 @@ | |
| 178 | /* Do an autosync push, if requested */ |
| 179 | if( !isPrivate ) autosync(AUTOSYNC_PUSH); |
| 180 | } |
| 181 | |
| 182 | /* |
| 183 | ** Prepare a query that will list all branches. |
| 184 | */ |
| 185 | static void prepareBranchQuery(Stmt *pQuery, int showAll, int showClosed){ |
| 186 | if( showClosed ){ |
| 187 | db_prepare(pQuery, |
| 188 | "SELECT value FROM tagxref" |
| 189 | " WHERE tagid=%d AND value NOT NULL " |
| 190 | "EXCEPT " |
| 191 | "SELECT value FROM tagxref" |
| @@ -193,11 +197,11 @@ | |
| 193 | " AND rid IN leaf" |
| 194 | " AND NOT %z" |
| 195 | " ORDER BY value COLLATE nocase /*sort*/", |
| 196 | TAG_BRANCH, TAG_BRANCH, leaf_is_closed_sql("tagxref.rid") |
| 197 | ); |
| 198 | }else if( showAll ){ |
| 199 | db_prepare(pQuery, |
| 200 | "SELECT DISTINCT value FROM tagxref" |
| 201 | " WHERE tagid=%d AND value NOT NULL" |
| 202 | " AND rid IN leaf" |
| 203 | " ORDER BY value COLLATE nocase /*sort*/", |
| @@ -260,11 +264,11 @@ | |
| 260 | if( g.localOpen ){ |
| 261 | vid = db_lget_int("checkout", 0); |
| 262 | zCurrent = db_text(0, "SELECT value FROM tagxref" |
| 263 | " WHERE rid=%d AND tagid=%d", vid, TAG_BRANCH); |
| 264 | } |
| 265 | prepareBranchQuery(&q, showAll, showClosed); |
| 266 | while( db_step(&q)==SQLITE_ROW ){ |
| 267 | const char *zBr = db_column_text(&q, 0); |
| 268 | int isCur = zCurrent!=0 && fossil_strcmp(zCurrent,zBr)==0; |
| 269 | fossil_print("%s%s\n", (isCur ? "* " : " "), zBr); |
| 270 | } |
| @@ -327,11 +331,11 @@ | |
| 327 | @ Closed branches are fixed and do not change (unless they are first |
| 328 | @ reopened)</li> |
| 329 | @ </ol> |
| 330 | style_sidebox_end(); |
| 331 | |
| 332 | prepareBranchQuery(&q, showAll, showClosed); |
| 333 | cnt = 0; |
| 334 | while( db_step(&q)==SQLITE_ROW ){ |
| 335 | const char *zBr = db_column_text(&q, 0); |
| 336 | if( cnt==0 ){ |
| 337 | if( colorTest ){ |
| 338 |
| --- src/branch.c | |
| +++ src/branch.c | |
| @@ -178,14 +178,18 @@ | |
| 178 | /* Do an autosync push, if requested */ |
| 179 | if( !isPrivate ) autosync(AUTOSYNC_PUSH); |
| 180 | } |
| 181 | |
| 182 | /* |
| 183 | ** Prepare a query that will list branches. |
| 184 | ** |
| 185 | ** If (which<0) then the query pulls only closed branches. If |
| 186 | ** (which>0) then the query pulls all (closed and opened) |
| 187 | ** branches. Else the query pulls currently-opened branches. |
| 188 | */ |
| 189 | void branch_prepare_list_query(Stmt *pQuery, int which ){ |
| 190 | if( which < 0 ){ |
| 191 | db_prepare(pQuery, |
| 192 | "SELECT value FROM tagxref" |
| 193 | " WHERE tagid=%d AND value NOT NULL " |
| 194 | "EXCEPT " |
| 195 | "SELECT value FROM tagxref" |
| @@ -193,11 +197,11 @@ | |
| 197 | " AND rid IN leaf" |
| 198 | " AND NOT %z" |
| 199 | " ORDER BY value COLLATE nocase /*sort*/", |
| 200 | TAG_BRANCH, TAG_BRANCH, leaf_is_closed_sql("tagxref.rid") |
| 201 | ); |
| 202 | }else if( which>0 ){ |
| 203 | db_prepare(pQuery, |
| 204 | "SELECT DISTINCT value FROM tagxref" |
| 205 | " WHERE tagid=%d AND value NOT NULL" |
| 206 | " AND rid IN leaf" |
| 207 | " ORDER BY value COLLATE nocase /*sort*/", |
| @@ -260,11 +264,11 @@ | |
| 264 | if( g.localOpen ){ |
| 265 | vid = db_lget_int("checkout", 0); |
| 266 | zCurrent = db_text(0, "SELECT value FROM tagxref" |
| 267 | " WHERE rid=%d AND tagid=%d", vid, TAG_BRANCH); |
| 268 | } |
| 269 | branch_prepare_list_query(&q, showAll?1:(showClosed?-1:0)); |
| 270 | while( db_step(&q)==SQLITE_ROW ){ |
| 271 | const char *zBr = db_column_text(&q, 0); |
| 272 | int isCur = zCurrent!=0 && fossil_strcmp(zCurrent,zBr)==0; |
| 273 | fossil_print("%s%s\n", (isCur ? "* " : " "), zBr); |
| 274 | } |
| @@ -327,11 +331,11 @@ | |
| 331 | @ Closed branches are fixed and do not change (unless they are first |
| 332 | @ reopened)</li> |
| 333 | @ </ol> |
| 334 | style_sidebox_end(); |
| 335 | |
| 336 | branch_prepare_list_query(&q, showAll?1:(showClosed?-1:0)); |
| 337 | cnt = 0; |
| 338 | while( db_step(&q)==SQLITE_ROW ){ |
| 339 | const char *zBr = db_column_text(&q, 0); |
| 340 | if( cnt==0 ){ |
| 341 | if( colorTest ){ |
| 342 |
+3
-1
| --- src/captcha.c | ||
| +++ src/captcha.c | ||
| @@ -412,12 +412,14 @@ | ||
| 412 | 412 | return x; |
| 413 | 413 | } |
| 414 | 414 | |
| 415 | 415 | /* |
| 416 | 416 | ** Translate a captcha seed value into the captcha password string. |
| 417 | +** The returned string is static and overwritten on each call to | |
| 418 | +** this function. | |
| 417 | 419 | */ |
| 418 | -char *captcha_decode(unsigned int seed){ | |
| 420 | +char const *captcha_decode(unsigned int seed){ | |
| 419 | 421 | const char *zSecret; |
| 420 | 422 | const char *z; |
| 421 | 423 | Blob b; |
| 422 | 424 | static char zRes[20]; |
| 423 | 425 | |
| 424 | 426 |
| --- src/captcha.c | |
| +++ src/captcha.c | |
| @@ -412,12 +412,14 @@ | |
| 412 | return x; |
| 413 | } |
| 414 | |
| 415 | /* |
| 416 | ** Translate a captcha seed value into the captcha password string. |
| 417 | */ |
| 418 | char *captcha_decode(unsigned int seed){ |
| 419 | const char *zSecret; |
| 420 | const char *z; |
| 421 | Blob b; |
| 422 | static char zRes[20]; |
| 423 | |
| 424 |
| --- src/captcha.c | |
| +++ src/captcha.c | |
| @@ -412,12 +412,14 @@ | |
| 412 | return x; |
| 413 | } |
| 414 | |
| 415 | /* |
| 416 | ** Translate a captcha seed value into the captcha password string. |
| 417 | ** The returned string is static and overwritten on each call to |
| 418 | ** this function. |
| 419 | */ |
| 420 | char const *captcha_decode(unsigned int seed){ |
| 421 | const char *zSecret; |
| 422 | const char *z; |
| 423 | Blob b; |
| 424 | static char zRes[20]; |
| 425 | |
| 426 |
+142
-17
| --- src/cgi.c | ||
| +++ src/cgi.c | ||
| @@ -508,10 +508,13 @@ | ||
| 508 | 508 | zValue = ""; |
| 509 | 509 | } |
| 510 | 510 | if( fossil_islower(zName[0]) ){ |
| 511 | 511 | cgi_set_parameter_nocopy(zName, zValue); |
| 512 | 512 | } |
| 513 | +#ifdef FOSSIL_ENABLE_JSON | |
| 514 | + json_setenv( zName, cson_value_new_string(zValue,strlen(zValue)) ); | |
| 515 | +#endif /* FOSSIL_ENABLE_JSON */ | |
| 513 | 516 | } |
| 514 | 517 | } |
| 515 | 518 | |
| 516 | 519 | /* |
| 517 | 520 | ** *pz is a string that consists of multiple lines of text. This |
| @@ -680,10 +683,88 @@ | ||
| 680 | 683 | } |
| 681 | 684 | } |
| 682 | 685 | } |
| 683 | 686 | } |
| 684 | 687 | } |
| 688 | + | |
| 689 | + | |
| 690 | +#ifdef FOSSIL_ENABLE_JSON | |
| 691 | +/* | |
| 692 | +** Internal helper for cson_data_source_FILE_n(). | |
| 693 | +*/ | |
| 694 | +typedef struct CgiPostReadState_ { | |
| 695 | + FILE * fh; | |
| 696 | + unsigned int len; | |
| 697 | + unsigned int pos; | |
| 698 | +} CgiPostReadState; | |
| 699 | + | |
| 700 | +/* | |
| 701 | +** cson_data_source_f() impl which reads only up to | |
| 702 | +** a specified amount of data from its input FILE. | |
| 703 | +** state MUST be a full populated (CgiPostReadState*). | |
| 704 | +*/ | |
| 705 | +static int cson_data_source_FILE_n( void * state, | |
| 706 | + void * dest, | |
| 707 | + unsigned int * n ){ | |
| 708 | + if( ! state || !dest || !n ) return cson_rc.ArgError; | |
| 709 | + else { | |
| 710 | + CgiPostReadState * st = (CgiPostReadState *)state; | |
| 711 | + if( st->pos >= st->len ){ | |
| 712 | + *n = 0; | |
| 713 | + return 0; | |
| 714 | + } else if( !*n || ((st->pos + *n) > st->len) ){ | |
| 715 | + return cson_rc.RangeError; | |
| 716 | + }else{ | |
| 717 | + unsigned int rsz = (unsigned int)fread( dest, 1, *n, st->fh ); | |
| 718 | + if( ! rsz ){ | |
| 719 | + *n = rsz; | |
| 720 | + return feof(st->fh) ? 0 : cson_rc.IOError; | |
| 721 | + }else{ | |
| 722 | + *n = rsz; | |
| 723 | + st->pos += *n; | |
| 724 | + return 0; | |
| 725 | + } | |
| 726 | + } | |
| 727 | + } | |
| 728 | +} | |
| 729 | + | |
| 730 | +/* | |
| 731 | +** Reads a JSON object from the first contentLen bytes of zIn. On | |
| 732 | +** g.json.post is updated to hold the content. On error a | |
| 733 | +** FSL_JSON_E_INVALID_REQUEST response is output and fossil_exit() is | |
| 734 | +** called (in HTTP mode exit code 0 is used). | |
| 735 | +** | |
| 736 | +** If contentLen is 0 then the whole file is read. | |
| 737 | +*/ | |
| 738 | +void cgi_parse_POST_JSON( FILE * zIn, unsigned int contentLen ){ | |
| 739 | + cson_value * jv = NULL; | |
| 740 | + int rc; | |
| 741 | + CgiPostReadState state; | |
| 742 | + state.fh = zIn; | |
| 743 | + state.len = contentLen; | |
| 744 | + state.pos = 0; | |
| 745 | + rc = cson_parse( &jv, | |
| 746 | + contentLen ? cson_data_source_FILE_n : cson_data_source_FILE, | |
| 747 | + contentLen ? (void *)&state : (void *)zIn, NULL, NULL ); | |
| 748 | + if(rc){ | |
| 749 | + goto invalidRequest; | |
| 750 | + }else{ | |
| 751 | + json_gc_add( "POST.JSON", jv ); | |
| 752 | + g.json.post.v = jv; | |
| 753 | + g.json.post.o = cson_value_get_object( jv ); | |
| 754 | + if( !g.json.post.o ){ /* we don't support non-Object (Array) requests */ | |
| 755 | + goto invalidRequest; | |
| 756 | + } | |
| 757 | + } | |
| 758 | + return; | |
| 759 | + invalidRequest: | |
| 760 | + cgi_set_content_type(json_guess_content_type()); | |
| 761 | + json_err( FSL_JSON_E_INVALID_REQUEST, NULL, 1 ); | |
| 762 | + fossil_exit( g.isHTTP ? 0 : 1); | |
| 763 | +} | |
| 764 | +#endif /* FOSSIL_ENABLE_JSON */ | |
| 765 | + | |
| 685 | 766 | |
| 686 | 767 | /* |
| 687 | 768 | ** Initialize the query parameter database. Information is pulled from |
| 688 | 769 | ** the QUERY_STRING environment variable (if it exists), from standard |
| 689 | 770 | ** input if there is POST data, and from HTTP_COOKIE. |
| @@ -690,19 +771,32 @@ | ||
| 690 | 771 | */ |
| 691 | 772 | void cgi_init(void){ |
| 692 | 773 | char *z; |
| 693 | 774 | const char *zType; |
| 694 | 775 | int len; |
| 776 | +#ifdef FOSSIL_ENABLE_JSON | |
| 777 | + json_main_bootstrap(); | |
| 778 | +#endif | |
| 779 | + g.isHTTP = 1; | |
| 695 | 780 | cgi_destination(CGI_BODY); |
| 781 | + | |
| 782 | + z = (char*)P("HTTP_COOKIE"); | |
| 783 | + if( z ){ | |
| 784 | + z = mprintf("%s",z); | |
| 785 | + add_param_list(z, ';'); | |
| 786 | + } | |
| 787 | + | |
| 696 | 788 | z = (char*)P("QUERY_STRING"); |
| 697 | 789 | if( z ){ |
| 698 | 790 | z = mprintf("%s",z); |
| 699 | 791 | add_param_list(z, '&'); |
| 700 | 792 | } |
| 701 | 793 | |
| 702 | 794 | z = (char*)P("REMOTE_ADDR"); |
| 703 | - if( z ) g.zIpAddr = mprintf("%s", z); | |
| 795 | + if( z ){ | |
| 796 | + g.zIpAddr = mprintf("%s", z); | |
| 797 | + } | |
| 704 | 798 | |
| 705 | 799 | len = atoi(PD("CONTENT_LENGTH", "0")); |
| 706 | 800 | g.zContentType = zType = P("CONTENT_TYPE"); |
| 707 | 801 | if( len>0 && zType ){ |
| 708 | 802 | blob_zero(&g.cgiIn); |
| @@ -722,17 +816,36 @@ | ||
| 722 | 816 | }else if( fossil_strcmp(zType, "application/x-fossil-debug")==0 ){ |
| 723 | 817 | blob_read_from_channel(&g.cgiIn, g.httpIn, len); |
| 724 | 818 | }else if( fossil_strcmp(zType, "application/x-fossil-uncompressed")==0 ){ |
| 725 | 819 | blob_read_from_channel(&g.cgiIn, g.httpIn, len); |
| 726 | 820 | } |
| 821 | +#ifdef FOSSIL_ENABLE_JSON | |
| 822 | + else if( fossil_strcmp(zType, "application/json") | |
| 823 | + || fossil_strcmp(zType,"text/plain")/*assume this MIGHT be JSON*/ | |
| 824 | + || fossil_strcmp(zType,"application/javascript")){ | |
| 825 | + g.json.isJsonMode = 1; | |
| 826 | + cgi_parse_POST_JSON(g.httpIn, (unsigned int)len); | |
| 827 | + /* FIXMEs: | |
| 828 | + | |
| 829 | + - See if fossil really needs g.cgiIn to be set for this purpose | |
| 830 | + (i don't think it does). If it does then fill g.cgiIn and | |
| 831 | + refactor to parse the JSON from there. | |
| 832 | + | |
| 833 | + - After parsing POST JSON, copy the "first layer" of keys/values | |
| 834 | + to cgi_setenv(), honoring the upper-case distinction used | |
| 835 | + in add_param_list(). However... | |
| 836 | + | |
| 837 | + - If we do that then we might get a disconnect in precedence of | |
| 838 | + GET/POST arguments. i prefer for GET entries to take precedence | |
| 839 | + over like-named POST entries, but in order for that to happen we | |
| 840 | + need to process QUERY_STRING _after_ reading the POST data. | |
| 841 | + */ | |
| 842 | + cgi_set_content_type(json_guess_content_type()); | |
| 843 | + } | |
| 844 | +#endif /* FOSSIL_ENABLE_JSON */ | |
| 727 | 845 | } |
| 728 | 846 | |
| 729 | - z = (char*)P("HTTP_COOKIE"); | |
| 730 | - if( z ){ | |
| 731 | - z = mprintf("%s",z); | |
| 732 | - add_param_list(z, ';'); | |
| 733 | - } | |
| 734 | 847 | } |
| 735 | 848 | |
| 736 | 849 | /* |
| 737 | 850 | ** This is the comparison function used to sort the aParamQP[] array of |
| 738 | 851 | ** query parameters and cookies. |
| @@ -942,20 +1055,33 @@ | ||
| 942 | 1055 | ** Panic and die while processing a webpage. |
| 943 | 1056 | */ |
| 944 | 1057 | NORETURN void cgi_panic(const char *zFormat, ...){ |
| 945 | 1058 | va_list ap; |
| 946 | 1059 | cgi_reset_content(); |
| 947 | - cgi_set_status(500, "Internal Server Error"); | |
| 948 | - cgi_printf( | |
| 949 | - "<html><body><h1>Internal Server Error</h1>\n" | |
| 950 | - "<plaintext>" | |
| 951 | - ); | |
| 952 | - va_start(ap, zFormat); | |
| 953 | - vxprintf(pContent,zFormat,ap); | |
| 954 | - va_end(ap); | |
| 955 | - cgi_reply(); | |
| 956 | - fossil_exit(1); | |
| 1060 | +#ifdef FOSSIL_ENABLE_JSON | |
| 1061 | + if( g.json.isJsonMode ){ | |
| 1062 | + char * zMsg; | |
| 1063 | + va_start(ap, zFormat); | |
| 1064 | + zMsg = vmprintf(zFormat,ap); | |
| 1065 | + va_end(ap); | |
| 1066 | + json_err( FSL_JSON_E_PANIC, zMsg, 1 ); | |
| 1067 | + free(zMsg); | |
| 1068 | + fossil_exit( g.isHTTP ? 0 : 1 ); | |
| 1069 | + }else | |
| 1070 | +#endif /* FOSSIL_ENABLE_JSON */ | |
| 1071 | + { | |
| 1072 | + cgi_set_status(500, "Internal Server Error"); | |
| 1073 | + cgi_printf( | |
| 1074 | + "<html><body><h1>Internal Server Error</h1>\n" | |
| 1075 | + "<plaintext>" | |
| 1076 | + ); | |
| 1077 | + va_start(ap, zFormat); | |
| 1078 | + vxprintf(pContent,zFormat,ap); | |
| 1079 | + va_end(ap); | |
| 1080 | + cgi_reply(); | |
| 1081 | + fossil_exit(1); | |
| 1082 | + } | |
| 957 | 1083 | } |
| 958 | 1084 | |
| 959 | 1085 | /* |
| 960 | 1086 | ** Remove the first space-delimited token from a string and return |
| 961 | 1087 | ** a pointer to it. Add a NULL to the string to terminate the token. |
| @@ -992,11 +1118,10 @@ | ||
| 992 | 1118 | char *z, *zToken; |
| 993 | 1119 | int i; |
| 994 | 1120 | struct sockaddr_in remoteName; |
| 995 | 1121 | socklen_t size = sizeof(struct sockaddr_in); |
| 996 | 1122 | char zLine[2000]; /* A single line of input. */ |
| 997 | - | |
| 998 | 1123 | g.fullHttpReply = 1; |
| 999 | 1124 | if( fgets(zLine, sizeof(zLine),g.httpIn)==0 ){ |
| 1000 | 1125 | malformed_request(); |
| 1001 | 1126 | } |
| 1002 | 1127 | zToken = extract_token(zLine, &z); |
| 1003 | 1128 | |
| 1004 | 1129 | ADDED src/cson_amalgamation.c |
| 1005 | 1130 | ADDED src/cson_amalgamation.h |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -508,10 +508,13 @@ | |
| 508 | zValue = ""; |
| 509 | } |
| 510 | if( fossil_islower(zName[0]) ){ |
| 511 | cgi_set_parameter_nocopy(zName, zValue); |
| 512 | } |
| 513 | } |
| 514 | } |
| 515 | |
| 516 | /* |
| 517 | ** *pz is a string that consists of multiple lines of text. This |
| @@ -680,10 +683,88 @@ | |
| 680 | } |
| 681 | } |
| 682 | } |
| 683 | } |
| 684 | } |
| 685 | |
| 686 | /* |
| 687 | ** Initialize the query parameter database. Information is pulled from |
| 688 | ** the QUERY_STRING environment variable (if it exists), from standard |
| 689 | ** input if there is POST data, and from HTTP_COOKIE. |
| @@ -690,19 +771,32 @@ | |
| 690 | */ |
| 691 | void cgi_init(void){ |
| 692 | char *z; |
| 693 | const char *zType; |
| 694 | int len; |
| 695 | cgi_destination(CGI_BODY); |
| 696 | z = (char*)P("QUERY_STRING"); |
| 697 | if( z ){ |
| 698 | z = mprintf("%s",z); |
| 699 | add_param_list(z, '&'); |
| 700 | } |
| 701 | |
| 702 | z = (char*)P("REMOTE_ADDR"); |
| 703 | if( z ) g.zIpAddr = mprintf("%s", z); |
| 704 | |
| 705 | len = atoi(PD("CONTENT_LENGTH", "0")); |
| 706 | g.zContentType = zType = P("CONTENT_TYPE"); |
| 707 | if( len>0 && zType ){ |
| 708 | blob_zero(&g.cgiIn); |
| @@ -722,17 +816,36 @@ | |
| 722 | }else if( fossil_strcmp(zType, "application/x-fossil-debug")==0 ){ |
| 723 | blob_read_from_channel(&g.cgiIn, g.httpIn, len); |
| 724 | }else if( fossil_strcmp(zType, "application/x-fossil-uncompressed")==0 ){ |
| 725 | blob_read_from_channel(&g.cgiIn, g.httpIn, len); |
| 726 | } |
| 727 | } |
| 728 | |
| 729 | z = (char*)P("HTTP_COOKIE"); |
| 730 | if( z ){ |
| 731 | z = mprintf("%s",z); |
| 732 | add_param_list(z, ';'); |
| 733 | } |
| 734 | } |
| 735 | |
| 736 | /* |
| 737 | ** This is the comparison function used to sort the aParamQP[] array of |
| 738 | ** query parameters and cookies. |
| @@ -942,20 +1055,33 @@ | |
| 942 | ** Panic and die while processing a webpage. |
| 943 | */ |
| 944 | NORETURN void cgi_panic(const char *zFormat, ...){ |
| 945 | va_list ap; |
| 946 | cgi_reset_content(); |
| 947 | cgi_set_status(500, "Internal Server Error"); |
| 948 | cgi_printf( |
| 949 | "<html><body><h1>Internal Server Error</h1>\n" |
| 950 | "<plaintext>" |
| 951 | ); |
| 952 | va_start(ap, zFormat); |
| 953 | vxprintf(pContent,zFormat,ap); |
| 954 | va_end(ap); |
| 955 | cgi_reply(); |
| 956 | fossil_exit(1); |
| 957 | } |
| 958 | |
| 959 | /* |
| 960 | ** Remove the first space-delimited token from a string and return |
| 961 | ** a pointer to it. Add a NULL to the string to terminate the token. |
| @@ -992,11 +1118,10 @@ | |
| 992 | char *z, *zToken; |
| 993 | int i; |
| 994 | struct sockaddr_in remoteName; |
| 995 | socklen_t size = sizeof(struct sockaddr_in); |
| 996 | char zLine[2000]; /* A single line of input. */ |
| 997 | |
| 998 | g.fullHttpReply = 1; |
| 999 | if( fgets(zLine, sizeof(zLine),g.httpIn)==0 ){ |
| 1000 | malformed_request(); |
| 1001 | } |
| 1002 | zToken = extract_token(zLine, &z); |
| 1003 | |
| 1004 | DDED src/cson_amalgamation.c |
| 1005 | DDED src/cson_amalgamation.h |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -508,10 +508,13 @@ | |
| 508 | zValue = ""; |
| 509 | } |
| 510 | if( fossil_islower(zName[0]) ){ |
| 511 | cgi_set_parameter_nocopy(zName, zValue); |
| 512 | } |
| 513 | #ifdef FOSSIL_ENABLE_JSON |
| 514 | json_setenv( zName, cson_value_new_string(zValue,strlen(zValue)) ); |
| 515 | #endif /* FOSSIL_ENABLE_JSON */ |
| 516 | } |
| 517 | } |
| 518 | |
| 519 | /* |
| 520 | ** *pz is a string that consists of multiple lines of text. This |
| @@ -680,10 +683,88 @@ | |
| 683 | } |
| 684 | } |
| 685 | } |
| 686 | } |
| 687 | } |
| 688 | |
| 689 | |
| 690 | #ifdef FOSSIL_ENABLE_JSON |
| 691 | /* |
| 692 | ** Internal helper for cson_data_source_FILE_n(). |
| 693 | */ |
| 694 | typedef struct CgiPostReadState_ { |
| 695 | FILE * fh; |
| 696 | unsigned int len; |
| 697 | unsigned int pos; |
| 698 | } CgiPostReadState; |
| 699 | |
| 700 | /* |
| 701 | ** cson_data_source_f() impl which reads only up to |
| 702 | ** a specified amount of data from its input FILE. |
| 703 | ** state MUST be a full populated (CgiPostReadState*). |
| 704 | */ |
| 705 | static int cson_data_source_FILE_n( void * state, |
| 706 | void * dest, |
| 707 | unsigned int * n ){ |
| 708 | if( ! state || !dest || !n ) return cson_rc.ArgError; |
| 709 | else { |
| 710 | CgiPostReadState * st = (CgiPostReadState *)state; |
| 711 | if( st->pos >= st->len ){ |
| 712 | *n = 0; |
| 713 | return 0; |
| 714 | } else if( !*n || ((st->pos + *n) > st->len) ){ |
| 715 | return cson_rc.RangeError; |
| 716 | }else{ |
| 717 | unsigned int rsz = (unsigned int)fread( dest, 1, *n, st->fh ); |
| 718 | if( ! rsz ){ |
| 719 | *n = rsz; |
| 720 | return feof(st->fh) ? 0 : cson_rc.IOError; |
| 721 | }else{ |
| 722 | *n = rsz; |
| 723 | st->pos += *n; |
| 724 | return 0; |
| 725 | } |
| 726 | } |
| 727 | } |
| 728 | } |
| 729 | |
| 730 | /* |
| 731 | ** Reads a JSON object from the first contentLen bytes of zIn. On |
| 732 | ** g.json.post is updated to hold the content. On error a |
| 733 | ** FSL_JSON_E_INVALID_REQUEST response is output and fossil_exit() is |
| 734 | ** called (in HTTP mode exit code 0 is used). |
| 735 | ** |
| 736 | ** If contentLen is 0 then the whole file is read. |
| 737 | */ |
| 738 | void cgi_parse_POST_JSON( FILE * zIn, unsigned int contentLen ){ |
| 739 | cson_value * jv = NULL; |
| 740 | int rc; |
| 741 | CgiPostReadState state; |
| 742 | state.fh = zIn; |
| 743 | state.len = contentLen; |
| 744 | state.pos = 0; |
| 745 | rc = cson_parse( &jv, |
| 746 | contentLen ? cson_data_source_FILE_n : cson_data_source_FILE, |
| 747 | contentLen ? (void *)&state : (void *)zIn, NULL, NULL ); |
| 748 | if(rc){ |
| 749 | goto invalidRequest; |
| 750 | }else{ |
| 751 | json_gc_add( "POST.JSON", jv ); |
| 752 | g.json.post.v = jv; |
| 753 | g.json.post.o = cson_value_get_object( jv ); |
| 754 | if( !g.json.post.o ){ /* we don't support non-Object (Array) requests */ |
| 755 | goto invalidRequest; |
| 756 | } |
| 757 | } |
| 758 | return; |
| 759 | invalidRequest: |
| 760 | cgi_set_content_type(json_guess_content_type()); |
| 761 | json_err( FSL_JSON_E_INVALID_REQUEST, NULL, 1 ); |
| 762 | fossil_exit( g.isHTTP ? 0 : 1); |
| 763 | } |
| 764 | #endif /* FOSSIL_ENABLE_JSON */ |
| 765 | |
| 766 | |
| 767 | /* |
| 768 | ** Initialize the query parameter database. Information is pulled from |
| 769 | ** the QUERY_STRING environment variable (if it exists), from standard |
| 770 | ** input if there is POST data, and from HTTP_COOKIE. |
| @@ -690,19 +771,32 @@ | |
| 771 | */ |
| 772 | void cgi_init(void){ |
| 773 | char *z; |
| 774 | const char *zType; |
| 775 | int len; |
| 776 | #ifdef FOSSIL_ENABLE_JSON |
| 777 | json_main_bootstrap(); |
| 778 | #endif |
| 779 | g.isHTTP = 1; |
| 780 | cgi_destination(CGI_BODY); |
| 781 | |
| 782 | z = (char*)P("HTTP_COOKIE"); |
| 783 | if( z ){ |
| 784 | z = mprintf("%s",z); |
| 785 | add_param_list(z, ';'); |
| 786 | } |
| 787 | |
| 788 | z = (char*)P("QUERY_STRING"); |
| 789 | if( z ){ |
| 790 | z = mprintf("%s",z); |
| 791 | add_param_list(z, '&'); |
| 792 | } |
| 793 | |
| 794 | z = (char*)P("REMOTE_ADDR"); |
| 795 | if( z ){ |
| 796 | g.zIpAddr = mprintf("%s", z); |
| 797 | } |
| 798 | |
| 799 | len = atoi(PD("CONTENT_LENGTH", "0")); |
| 800 | g.zContentType = zType = P("CONTENT_TYPE"); |
| 801 | if( len>0 && zType ){ |
| 802 | blob_zero(&g.cgiIn); |
| @@ -722,17 +816,36 @@ | |
| 816 | }else if( fossil_strcmp(zType, "application/x-fossil-debug")==0 ){ |
| 817 | blob_read_from_channel(&g.cgiIn, g.httpIn, len); |
| 818 | }else if( fossil_strcmp(zType, "application/x-fossil-uncompressed")==0 ){ |
| 819 | blob_read_from_channel(&g.cgiIn, g.httpIn, len); |
| 820 | } |
| 821 | #ifdef FOSSIL_ENABLE_JSON |
| 822 | else if( fossil_strcmp(zType, "application/json") |
| 823 | || fossil_strcmp(zType,"text/plain")/*assume this MIGHT be JSON*/ |
| 824 | || fossil_strcmp(zType,"application/javascript")){ |
| 825 | g.json.isJsonMode = 1; |
| 826 | cgi_parse_POST_JSON(g.httpIn, (unsigned int)len); |
| 827 | /* FIXMEs: |
| 828 | |
| 829 | - See if fossil really needs g.cgiIn to be set for this purpose |
| 830 | (i don't think it does). If it does then fill g.cgiIn and |
| 831 | refactor to parse the JSON from there. |
| 832 | |
| 833 | - After parsing POST JSON, copy the "first layer" of keys/values |
| 834 | to cgi_setenv(), honoring the upper-case distinction used |
| 835 | in add_param_list(). However... |
| 836 | |
| 837 | - If we do that then we might get a disconnect in precedence of |
| 838 | GET/POST arguments. i prefer for GET entries to take precedence |
| 839 | over like-named POST entries, but in order for that to happen we |
| 840 | need to process QUERY_STRING _after_ reading the POST data. |
| 841 | */ |
| 842 | cgi_set_content_type(json_guess_content_type()); |
| 843 | } |
| 844 | #endif /* FOSSIL_ENABLE_JSON */ |
| 845 | } |
| 846 | |
| 847 | } |
| 848 | |
| 849 | /* |
| 850 | ** This is the comparison function used to sort the aParamQP[] array of |
| 851 | ** query parameters and cookies. |
| @@ -942,20 +1055,33 @@ | |
| 1055 | ** Panic and die while processing a webpage. |
| 1056 | */ |
| 1057 | NORETURN void cgi_panic(const char *zFormat, ...){ |
| 1058 | va_list ap; |
| 1059 | cgi_reset_content(); |
| 1060 | #ifdef FOSSIL_ENABLE_JSON |
| 1061 | if( g.json.isJsonMode ){ |
| 1062 | char * zMsg; |
| 1063 | va_start(ap, zFormat); |
| 1064 | zMsg = vmprintf(zFormat,ap); |
| 1065 | va_end(ap); |
| 1066 | json_err( FSL_JSON_E_PANIC, zMsg, 1 ); |
| 1067 | free(zMsg); |
| 1068 | fossil_exit( g.isHTTP ? 0 : 1 ); |
| 1069 | }else |
| 1070 | #endif /* FOSSIL_ENABLE_JSON */ |
| 1071 | { |
| 1072 | cgi_set_status(500, "Internal Server Error"); |
| 1073 | cgi_printf( |
| 1074 | "<html><body><h1>Internal Server Error</h1>\n" |
| 1075 | "<plaintext>" |
| 1076 | ); |
| 1077 | va_start(ap, zFormat); |
| 1078 | vxprintf(pContent,zFormat,ap); |
| 1079 | va_end(ap); |
| 1080 | cgi_reply(); |
| 1081 | fossil_exit(1); |
| 1082 | } |
| 1083 | } |
| 1084 | |
| 1085 | /* |
| 1086 | ** Remove the first space-delimited token from a string and return |
| 1087 | ** a pointer to it. Add a NULL to the string to terminate the token. |
| @@ -992,11 +1118,10 @@ | |
| 1118 | char *z, *zToken; |
| 1119 | int i; |
| 1120 | struct sockaddr_in remoteName; |
| 1121 | socklen_t size = sizeof(struct sockaddr_in); |
| 1122 | char zLine[2000]; /* A single line of input. */ |
| 1123 | g.fullHttpReply = 1; |
| 1124 | if( fgets(zLine, sizeof(zLine),g.httpIn)==0 ){ |
| 1125 | malformed_request(); |
| 1126 | } |
| 1127 | zToken = extract_token(zLine, &z); |
| 1128 | |
| 1129 | DDED src/cson_amalgamation.c |
| 1130 | DDED src/cson_amalgamation.h |
+645
| --- a/src/cson_amalgamation.c | ||
| +++ b/src/cson_amalgamation.c | ||
| @@ -0,0 +1,645 @@ | ||
| 1 | + use | |
| 2 | + the the defaul | |
| 3 | +o 2008-05-20 * C2 | |
| 4 | + MODE_KEY = 3, break; | |
| 5 | +/* LICENSE | |
| 6 | + | |
| 7 | +CopyCENSE | |
| 8 | + | |
| 9 | +Copy | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | +pack.c */ | |
| 16 | +#V)->value)m/* FIXME: if sizeof(void*) > then store | |
| 17 | + the int value directly in the v). The curbytes(!!!) on 64-bit builds.in | |
| 18 | + use | |
| 19 | + the defaul | |
| 20 | +o 2008-05-20 * C2 | |
| 21 | + MODE_KEY = 3, break; | |
| 22 | +/* LICENSE | |
| 23 | + | |
| 24 | +CopyCENSE | |
| 25 | + | |
| 26 | +Copy | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | +pack.c */ | |
| 33 | +if( use | |
| 34 | + the clone_shared(ul | |
| 35 | +o 2008-05-20 2008-05-20 * sharedshared use | |
| 36 | + ('0'<=*arg) && ('9'>=*arg)){ use | |
| 37 | + the def use | |
| 38 | + the defaul | |
| 39 | +o 2008-05-20 * C2 | |
| 40 | + MODE_KEY = 3, break; | |
| 41 | +/* LICENSE | |
| 42 | + | |
| 43 | +CopyCENSE | |
| 44 | + | |
| 45 | +Copy | |
| 46 | + | |
| 47 | + use | |
| 48 | + } | |
| 49 | + | |
| 50 | + use | |
| 51 | + the defaul | |
| 52 | +o 2008-05-20 * C2 | |
| 53 | + MODE_KEY = 3, break; | |
| 54 | +/* LICENSE | |
| 55 | + | |
| 56 | +CopyCENSE | |
| 57 | + | |
| 58 | +Copy | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | +pack.c */ | |
| 65 | +? cson_guess_arg_type(pos: use | |
| 66 | + the defaul | |
| 67 | +0 != (rc= use | |
| 68 | + the defaul | |
| 69 | +o 2008-05-20 * C2 | |
| 70 | + MODE_KEY = 3, break; | |
| 71 | +/* LICENSE | |
| 72 | + | |
| 73 | +CopyCENSE | |
| 74 | + | |
| 75 | +Copy | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | +pack.c */ | |
| 82 | + defaul | |
| 83 | +o 2008-05-20 * C2 | |
| 84 | + MODE_KEY = 3, break; | |
| 85 | +/* LICENSE | |
| 86 | + | |
| 87 | +CopyCENSE | |
| 88 | + | |
| 89 | +Copy | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | +pack.c */ | |
| 96 | +#V)->value)m/* FIXME: if sizeof(void*) > then store | |
| 97 | + the int value directly in the v). The curbytes(!!!) on 64-bit builds.in | |
| 98 | + use | |
| 99 | + the defaul | |
| 100 | +o 2008-05-20 * C2 | |
| 101 | + MODE_KEY = 3, break; | |
| 102 | +/* LICENSE | |
| 103 | + | |
| 104 | +CopyCENSE | |
| 105 | + | |
| 106 | +Copy | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | +pack.c */ | |
| 113 | +if( use | |
| 114 | + the clone_shared(ul | |
| 115 | +o 2008-05-20 2008-05-20 * sharedshared use | |
| 116 | + ('0'<=*arg) && ('9'>=*arg)){ use | |
| 117 | + the def use | |
| 118 | + the defaul | |
| 119 | +o 2008-05-20 * C2 | |
| 120 | + MODE_KEY = 3, break; | |
| 121 | +/* LICENSE | |
| 122 | + | |
| 123 | +CopyCENSE | |
| 124 | + | |
| 125 | +Copy | |
| 126 | + | |
| 127 | + use | |
| 128 | + } | |
| 129 | + | |
| 130 | + use | |
| 131 | + the defaul | |
| 132 | +o 2008-05-20 * C2 | |
| 133 | + MODE_KEY = 3, break; | |
| 134 | +/* LICENSE | |
| 135 | + | |
| 136 | +CopyCENSE | |
| 137 | + | |
| 138 | +Copy | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | +pack.c */ | |
| 145 | +? cson_guess_arg_type(pos: use | |
| 146 | + the defaul | |
| 147 | +0 != (rc= use | |
| 148 | + the defaul | |
| 149 | +o 2008-05-20 * C2 | |
| 150 | + MODE_KEY = 3, break; | |
| 151 | +/* LICENSE | |
| 152 | + | |
| 153 | +CopyCENSE | |
| 154 | + | |
| 155 | +Copy | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | +pack.c */ | |
| 162 | +0_guess_arg_type(pos: use | |
| 163 | + t use | |
| 164 | + MODE_KEY = 3, use | |
| 165 | + ; | |
| 166 | + p->c 0 == rc ) use | |
| 167 | + }ARRAY_END:( ch}/* | |
| 168 | + refcount the keys! We first need a setter which takes | |
| 169 | + 8@JnB,b:a cson_string or cson_value key type. | |
| 170 | +K@OzU,D:cson_value * K@I20,G@FK0,H@cX0,3:keyK@Xhl,J@_4E,S@YGA,E:( kvp->value )H@NM0,X@YHA,G@cDG,G@PEl,W@O4l,_@YNG,L@blG,M@Yfi,C:CSON_STR(keyH@bp0,1B@YIj,G@cDG,G@PEl,W@O4l,_@YNG,L@blG,G@8RG,TX@YOR,5:constb@YpW,z@YrX,G@cDG,1I_@Ysq,_@Nql,J@SPy,4NC@_BU,28lZAF; defined(_WIN32) | |
| 171 | +# pop ) ownership of it to the | |
| 172 | + caller. It must eventually be destroyed, by the caller or its | |
| 173 | + owning or transfering | |
| 174 | + | |
| 175 | +void/** | |
| 176 | + This special-case impl is needed because the underlying | |
| 177 | + (generic) list operations do not know how to populate | |
| 178 | + new entries | |
| 179 | + */ use | |
| 180 | + the =*arg)){ use | |
| 181 | + the def use | |
| 182 | + the defaul | |
| 183 | +o 2008-05-20 * C2 | |
| 184 | + MODE_KEY = 3, break; | |
| 185 | +/* LICENSE | |
| 186 | + | |
| 187 | +CopyCENSE | |
| 188 | + | |
| 189 | +Copy | |
| 190 | + | |
| 191 | + use | |
| 192 | + } | |
| 193 | + | |
| 194 | + use | |
| 195 | + the defaul | |
| 196 | +o 2008-05-20 * C2 | |
| 197 | + MODE_KEY = 3, break; | |
| 198 | +/* LICENSE | |
| 199 | + | |
| 200 | +CopyCENSE | |
| 201 | + | |
| 202 | +Copy | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | +pack.c */ | |
| 209 | +? cson_guess_arg_type(pos: use | |
| 210 | + the defaul | |
| 211 | +0 != (rc= use | |
| 212 | + the defaul | |
| 213 | +o 2008-05-20 * C2 | |
| 214 | + MODE_KEY = 3, break; | |
| 215 | +/* LICENSE | |
| 216 | + | |
| 217 | +CopyCENSE | |
| 218 | + | |
| 219 | +Copy | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | +pack.c */ | |
| 226 | +0_guess_arg_type(pos: use | |
| 227 | + t use | |
| 228 | + MODE_KEY = 3, use | |
| 229 | + ; | |
| 230 | + p->c 0 == rc ) use | |
| 231 | + }Aary use | |
| 232 | + the the defaul | |
| 233 | +o 2008-05-20 * C2 | |
| 234 | + MODE_KEY = 3, break; | |
| 235 | +/* LICENSE | |
| 236 | + | |
| 237 | +CopyCENSE | |
| 238 | + | |
| 239 | +Copy | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | +pack.c */ | |
| 246 | +#V)->value)m/* FIXME: if sizeof(void*) > then store | |
| 247 | + the int value directly in the v). The curbytes(!!!) on 64-bit builds.in | |
| 248 | + use | |
| 249 | + the defaul | |
| 250 | +o 2008-05-20 * C2 | |
| 251 | + MODE_KEY = 3, break; | |
| 252 | +/* LICENSE | |
| 253 | + | |
| 254 | +CopyCENSE | |
| 255 | + | |
| 256 | +Copy | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | +pack.c */ | |
| 263 | +if( use | |
| 264 | + the clone_shared(ul | |
| 265 | +o 2008-05-20 2008-05-20 * sharedshared use | |
| 266 | + ('0'<=*arg) && ('9'>=*arg)){ use | |
| 267 | + the def use | |
| 268 | + the defaul | |
| 269 | +o 2008-05-20 * C2 | |
| 270 | + MODE_KEY = 3, break; | |
| 271 | +/* LICENSE | |
| 272 | + | |
| 273 | +CopyCENSE | |
| 274 | + | |
| 275 | +Copy | |
| 276 | + | |
| 277 | + use | |
| 278 | + } | |
| 279 | + | |
| 280 | + use | |
| 281 | + the defaul | |
| 282 | +o 2008-05-20 * C2 | |
| 283 | + MODE_KEY = 3, break; | |
| 284 | +/* LICENSE | |
| 285 | + | |
| 286 | +CopyCENSE | |
| 287 | + | |
| 288 | +Copy | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | +pack.c */ | |
| 295 | +? cson_guess_arg_type(pos: use | |
| 296 | + the defaul | |
| 297 | +0 != (rc= use | |
| 298 | + the defaul | |
| 299 | +o 2008-05-20 * C2 | |
| 300 | + MODE_KEY = 3, break; | |
| 301 | +/* LICENSE | |
| 302 | + | |
| 303 | +CopyCENSE | |
| 304 | + | |
| 305 | +Copy | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | +pack.c */ | |
| 312 | + defaul | |
| 313 | +o 2008-05-20 * C2 | |
| 314 | + MODE_KEY = 3, break; | |
| 315 | +/* LICENSE | |
| 316 | + | |
| 317 | +CopyCENSE | |
| 318 | + | |
| 319 | +Copy | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | +pack.c */ | |
| 326 | +#V)->value)m/* FIXME: if sizeof(void*) > then store | |
| 327 | + the int value directly in the v). The curbytes(!!!) on 64-bit builds.in | |
| 328 | + use | |
| 329 | + the defaul | |
| 330 | +o 2008-05-20 * C2 | |
| 331 | + MODE_KEY = 3, break; | |
| 332 | +/* LICENSE | |
| 333 | + | |
| 334 | +CopyCENSE | |
| 335 | + | |
| 336 | +Copy | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | +pack.c */ | |
| 343 | +if( use | |
| 344 | + the clone_shared(ul | |
| 345 | +o 2008-05-20 2008-05-20 * sharedshared use | |
| 346 | + ('0'<=*arg) && ('9'>=*arg)){ use | |
| 347 | + the def use | |
| 348 | + the defaul | |
| 349 | +o 2008-05-20 * C2 | |
| 350 | + MODE_KEY = 3, break; | |
| 351 | +/* LICENSE | |
| 352 | + | |
| 353 | +CopyCENSE | |
| 354 | + | |
| 355 | +Copy | |
| 356 | + | |
| 357 | + use | |
| 358 | + } | |
| 359 | + | |
| 360 | + use | |
| 361 | + the defaul | |
| 362 | +o 2008-05-20 * C2 | |
| 363 | + MODE_KEY = 3, break; | |
| 364 | +/* LICENSE | |
| 365 | + | |
| 366 | +CopyCENSE | |
| 367 | + | |
| 368 | +Copy | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | +pack.c */ | |
| 375 | +? cson_guess_arg_type(pos: use | |
| 376 | + the defaul | |
| 377 | +0 != (rc= use | |
| 378 | + the defaul | |
| 379 | +o 2008-05-20 * C2 | |
| 380 | + MODE_KEY = 3, break; | |
| 381 | +/* LICENSE | |
| 382 | + | |
| 383 | +CopyCENSE | |
| 384 | + | |
| 385 | +Copy | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | +pack.c */ | |
| 392 | +0_guess_arg_type(pos: use | |
| 393 | + t use | |
| 394 | + MODE_KEY = 3, use | |
| 395 | + ; | |
| 396 | + p->c 0 == rc ) use | |
| 397 | + }ARRAY_END:( ch}/* | |
| 398 | + refcount the keys! We first need a setter which takes | |
| 399 | + 8@JnB,b:a cson_string or cson_value key type. | |
| 400 | +K@OzU,D:cson_value * K@I20,G@FK0,H@cX0,3:keyK@Xhl,J@_4E,S@YGA,E:( kvp->value )H@NM0,X@YHA,G@cDG,G@PEl,W@O4l,_@YNG,L@blG,M@Yfi,C:CSON_STR(keyH@bp0,1B@YIj,G@cDG,G@PEl,W@O4l,_@YNG,L@blG,G@8RG,TX@YOR,5:constb@YpW,z@YrX,G@cDG,1I_@Ysq,_@Nql,J@SPy,4NC@_BU,28lZAF; defined(_WIN32) | |
| 401 | +# pop ) ownership of it to the | |
| 402 | + caller. It must eventually be destroyed, by the caller or its | |
| 403 | + owning or transfering | |
| 404 | + | |
| 405 | +void/** | |
| 406 | + This special-case impl is needed because the underlying | |
| 407 | + (generic) list operations do not know how to populate | |
| 408 | + new entries | |
| 409 | + */ use | |
| 410 | + the =*arg)){ use | |
| 411 | + the def use | |
| 412 | + the defaul | |
| 413 | +o 2008-05-20 * C2 | |
| 414 | + MODE_KEY = 3, break; | |
| 415 | +/* LICENSE | |
| 416 | + | |
| 417 | +CopyCENSE | |
| 418 | + | |
| 419 | +Copy | |
| 420 | + | |
| 421 | + use | |
| 422 | + } | |
| 423 | + | |
| 424 | + use | |
| 425 | + the defaul | |
| 426 | +o 2008-05-20 * C2 | |
| 427 | + MODE_KEY = 3, break; | |
| 428 | +/* LICENSE | |
| 429 | + | |
| 430 | +CopyCENSE | |
| 431 | + | |
| 432 | +Copy | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | +pack.c */ | |
| 439 | +? cson_guess_arg_type(pos: use | |
| 440 | + the defaul | |
| 441 | +0 != (rc= use | |
| 442 | + the defaul | |
| 443 | +o 2008-05-20 * C2 | |
| 444 | + MODE_KEY = 3, break; | |
| 445 | +/* LICENSE | |
| 446 | + | |
| 447 | +CopyCENSE | |
| 448 | + | |
| 449 | +Copy | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | +pack.c */ | |
| 456 | +0_guess_arg_type(pos: use | |
| 457 | + t use | |
| 458 | + MODE_KEY = 3, use | |
| 459 | + ; | |
| 460 | + p->c 0 == rc ) use | |
| 461 | + }Aarye | |
| 462 | + } | |
| 463 | + | |
| 464 | + use | |
| 465 | + the defaul | |
| 466 | +o 2008-05-20 * C2 | |
| 467 | + MODE_KEY = 3, break; | |
| 468 | +/* LICENSE | |
| 469 | + | |
| 470 | +CopyCENSE | |
| 471 | + | |
| 472 | +Copy | |
| 473 | + | |
| 474 | + | |
| 475 | + | |
| 476 | + | |
| 477 | + | |
| 478 | +pack.c */ | |
| 479 | +? cson_guess_arg_type(pos: use | |
| 480 | + the defaul | |
| 481 | +0 != (rc= use | |
| 482 | + the defaul | |
| 483 | +o 2008-05-20 * C2 | |
| 484 | + MODE_KEY = 3, break; | |
| 485 | +/* LICENSE | |
| 486 | + | |
| 487 | +CopyCENSE | |
| 488 | + | |
| 489 | +Copy | |
| 490 | + | |
| 491 | + | |
| 492 | + | |
| 493 | + | |
| 494 | + | |
| 495 | +pack.c */ | |
| 496 | + defaul | |
| 497 | +o 2008-05-20 * C2 | |
| 498 | + MODE_KEY = 3, break; | |
| 499 | +/* LICENSE | |
| 500 | + | |
| 501 | +CopyCENSE | |
| 502 | + | |
| 503 | +Copy | |
| 504 | + | |
| 505 | + | |
| 506 | + | |
| 507 | + | |
| 508 | + | |
| 509 | +pack.c */ | |
| 510 | +#V)->value)m/* FIXME: if sizeof(void*) > then store | |
| 511 | + the int value directly in the v). The curbytes(!!!) on 64-bit builds.in | |
| 512 | + use | |
| 513 | + the defaul | |
| 514 | +o 2008-05-20 * C2 | |
| 515 | + MODE_KEY = 3, break; | |
| 516 | +/* LICENSE | |
| 517 | + | |
| 518 | +CopyCENSE | |
| 519 | + | |
| 520 | +Copy | |
| 521 | + | |
| 522 | + | |
| 523 | + | |
| 524 | + | |
| 525 | + | |
| 526 | +pack.c */ | |
| 527 | +if( use | |
| 528 | + the clone_shared(ul | |
| 529 | +o 2008-05-20 2008-05-20 * sharedshared use | |
| 530 | + ('0'<=*arg) && ('9'>=*arg)){ use | |
| 531 | + the def use | |
| 532 | + the defaul | |
| 533 | +o 2008-05-20 * C2 | |
| 534 | + MODE_KEY = 3, break; | |
| 535 | +/* LICENSE | |
| 536 | + | |
| 537 | +CopyCENSE | |
| 538 | + | |
| 539 | +Copy | |
| 540 | + | |
| 541 | + use | |
| 542 | + } | |
| 543 | + | |
| 544 | + use | |
| 545 | + the defaul | |
| 546 | +o 2008-05-20 * C2 | |
| 547 | + MODE_KEY = 3, break; | |
| 548 | +/* LICENSE | |
| 549 | + | |
| 550 | +CopyCENSE | |
| 551 | + | |
| 552 | +Copy | |
| 553 | + | |
| 554 | + | |
| 555 | + | |
| 556 | + | |
| 557 | + | |
| 558 | +pack.c */ | |
| 559 | +? cson_guess_arg_type(pos: use | |
| 560 | + the defaul | |
| 561 | +0 != (rc= use | |
| 562 | + the defaul | |
| 563 | +o 2008-05-20 * C2 | |
| 564 | + MODE_KEY = 3, break; | |
| 565 | +/* LICENSE | |
| 566 | + | |
| 567 | +CopyCENSE | |
| 568 | + | |
| 569 | +Copy | |
| 570 | + | |
| 571 | + | |
| 572 | + | |
| 573 | + | |
| 574 | + | |
| 575 | +pack.c */ | |
| 576 | +0_guess_arg_type(pos: use | |
| 577 | + t use | |
| 578 | + MODE_KEY = 3, use | |
| 579 | + ; | |
| 580 | + p->c 0 == rc ) use | |
| 581 | + }ARRAY_END:( ch}/* | |
| 582 | + refcount the keys! We first need a setter which takes | |
| 583 | + 8@JnB,b:a cson_string or cson_value key type. | |
| 584 | +K@OzU,D:cson_value * K@I20,G@FK0,H@cX0,3:keyK@Xhl,J@_4E,S@YGA,E:( kvp->value )H@NM0,X@YHA,G@cDG,G@PEl,W@O4l,_@YNG,L@blG,M@Yfi,C:CSON_STR(keyH@bp0,1B@YIj,G@cDG,G@PEl,W@O4l,_@YNG,L@blG,G@8RG,TX@YOR,5:constb@YpW,z@YrX,G@cDG,1I_@Ysq,_@Nql,J@SPy,4NC@_BU,28lZAF; defined(_WIN32) | |
| 585 | +# pop ) ownership of it to the | |
| 586 | + caller. It must eventually be destroyed, by the caller or its | |
| 587 | + owning or transfering | |
| 588 | + | |
| 589 | +void/** | |
| 590 | + This special-case impl is needed because the underlying | |
| 591 | + (generic) list operations do not know how to populate | |
| 592 | + new entries | |
| 593 | + */ use | |
| 594 | + the =*arg)){ use | |
| 595 | + the def use | |
| 596 | + the defaul | |
| 597 | +o 2008-05-20 * C2 | |
| 598 | + MODE_KEY = 3, break; | |
| 599 | +/* LICENSE | |
| 600 | + | |
| 601 | +CopyCENSE | |
| 602 | + | |
| 603 | +Copy | |
| 604 | + | |
| 605 | + use | |
| 606 | + } | |
| 607 | + | |
| 608 | + use | |
| 609 | + the defaul | |
| 610 | +o 2008-05-20 * C2 | |
| 611 | + MODE_KEY = 3, break; | |
| 612 | +/* LICENSE | |
| 613 | + | |
| 614 | +CopyCENSE | |
| 615 | + | |
| 616 | +Copy | |
| 617 | + | |
| 618 | + | |
| 619 | + | |
| 620 | + | |
| 621 | + | |
| 622 | +pack.c */ | |
| 623 | +? cson_guess_arg_type(pos: use | |
| 624 | + the defaul | |
| 625 | +0 != (rc= use | |
| 626 | + the defaul | |
| 627 | +o 2008-05-20 * C2 | |
| 628 | + MODE_KEY = 3, break; | |
| 629 | +/* LICENSE | |
| 630 | + | |
| 631 | +CopyCENSE | |
| 632 | + | |
| 633 | +Copy | |
| 634 | + | |
| 635 | + | |
| 636 | + | |
| 637 | + | |
| 638 | + | |
| 639 | +pack.c */ | |
| 640 | +0_guess_arg_type(pos: use | |
| 641 | + t use | |
| 642 | + MODE_KEY = 3, use | |
| 643 | + ; | |
| 644 | + p->c 0 == rc ) use | |
| 645 | + }Aary |
| --- a/src/cson_amalgamation.c | |
| +++ b/src/cson_amalgamation.c | |
| @@ -0,0 +1,645 @@ | |
| --- a/src/cson_amalgamation.c | |
| +++ b/src/cson_amalgamation.c | |
| @@ -0,0 +1,645 @@ | |
| 1 | use |
| 2 | the the defaul |
| 3 | o 2008-05-20 * C2 |
| 4 | MODE_KEY = 3, break; |
| 5 | /* LICENSE |
| 6 | |
| 7 | CopyCENSE |
| 8 | |
| 9 | Copy |
| 10 | |
| 11 | |
| 12 | |
| 13 | |
| 14 | |
| 15 | pack.c */ |
| 16 | #V)->value)m/* FIXME: if sizeof(void*) > then store |
| 17 | the int value directly in the v). The curbytes(!!!) on 64-bit builds.in |
| 18 | use |
| 19 | the defaul |
| 20 | o 2008-05-20 * C2 |
| 21 | MODE_KEY = 3, break; |
| 22 | /* LICENSE |
| 23 | |
| 24 | CopyCENSE |
| 25 | |
| 26 | Copy |
| 27 | |
| 28 | |
| 29 | |
| 30 | |
| 31 | |
| 32 | pack.c */ |
| 33 | if( use |
| 34 | the clone_shared(ul |
| 35 | o 2008-05-20 2008-05-20 * sharedshared use |
| 36 | ('0'<=*arg) && ('9'>=*arg)){ use |
| 37 | the def use |
| 38 | the defaul |
| 39 | o 2008-05-20 * C2 |
| 40 | MODE_KEY = 3, break; |
| 41 | /* LICENSE |
| 42 | |
| 43 | CopyCENSE |
| 44 | |
| 45 | Copy |
| 46 | |
| 47 | use |
| 48 | } |
| 49 | |
| 50 | use |
| 51 | the defaul |
| 52 | o 2008-05-20 * C2 |
| 53 | MODE_KEY = 3, break; |
| 54 | /* LICENSE |
| 55 | |
| 56 | CopyCENSE |
| 57 | |
| 58 | Copy |
| 59 | |
| 60 | |
| 61 | |
| 62 | |
| 63 | |
| 64 | pack.c */ |
| 65 | ? cson_guess_arg_type(pos: use |
| 66 | the defaul |
| 67 | 0 != (rc= use |
| 68 | the defaul |
| 69 | o 2008-05-20 * C2 |
| 70 | MODE_KEY = 3, break; |
| 71 | /* LICENSE |
| 72 | |
| 73 | CopyCENSE |
| 74 | |
| 75 | Copy |
| 76 | |
| 77 | |
| 78 | |
| 79 | |
| 80 | |
| 81 | pack.c */ |
| 82 | defaul |
| 83 | o 2008-05-20 * C2 |
| 84 | MODE_KEY = 3, break; |
| 85 | /* LICENSE |
| 86 | |
| 87 | CopyCENSE |
| 88 | |
| 89 | Copy |
| 90 | |
| 91 | |
| 92 | |
| 93 | |
| 94 | |
| 95 | pack.c */ |
| 96 | #V)->value)m/* FIXME: if sizeof(void*) > then store |
| 97 | the int value directly in the v). The curbytes(!!!) on 64-bit builds.in |
| 98 | use |
| 99 | the defaul |
| 100 | o 2008-05-20 * C2 |
| 101 | MODE_KEY = 3, break; |
| 102 | /* LICENSE |
| 103 | |
| 104 | CopyCENSE |
| 105 | |
| 106 | Copy |
| 107 | |
| 108 | |
| 109 | |
| 110 | |
| 111 | |
| 112 | pack.c */ |
| 113 | if( use |
| 114 | the clone_shared(ul |
| 115 | o 2008-05-20 2008-05-20 * sharedshared use |
| 116 | ('0'<=*arg) && ('9'>=*arg)){ use |
| 117 | the def use |
| 118 | the defaul |
| 119 | o 2008-05-20 * C2 |
| 120 | MODE_KEY = 3, break; |
| 121 | /* LICENSE |
| 122 | |
| 123 | CopyCENSE |
| 124 | |
| 125 | Copy |
| 126 | |
| 127 | use |
| 128 | } |
| 129 | |
| 130 | use |
| 131 | the defaul |
| 132 | o 2008-05-20 * C2 |
| 133 | MODE_KEY = 3, break; |
| 134 | /* LICENSE |
| 135 | |
| 136 | CopyCENSE |
| 137 | |
| 138 | Copy |
| 139 | |
| 140 | |
| 141 | |
| 142 | |
| 143 | |
| 144 | pack.c */ |
| 145 | ? cson_guess_arg_type(pos: use |
| 146 | the defaul |
| 147 | 0 != (rc= use |
| 148 | the defaul |
| 149 | o 2008-05-20 * C2 |
| 150 | MODE_KEY = 3, break; |
| 151 | /* LICENSE |
| 152 | |
| 153 | CopyCENSE |
| 154 | |
| 155 | Copy |
| 156 | |
| 157 | |
| 158 | |
| 159 | |
| 160 | |
| 161 | pack.c */ |
| 162 | 0_guess_arg_type(pos: use |
| 163 | t use |
| 164 | MODE_KEY = 3, use |
| 165 | ; |
| 166 | p->c 0 == rc ) use |
| 167 | }ARRAY_END:( ch}/* |
| 168 | refcount the keys! We first need a setter which takes |
| 169 | 8@JnB,b:a cson_string or cson_value key type. |
| 170 | K@OzU,D:cson_value * K@I20,G@FK0,H@cX0,3:keyK@Xhl,J@_4E,S@YGA,E:( kvp->value )H@NM0,X@YHA,G@cDG,G@PEl,W@O4l,_@YNG,L@blG,M@Yfi,C:CSON_STR(keyH@bp0,1B@YIj,G@cDG,G@PEl,W@O4l,_@YNG,L@blG,G@8RG,TX@YOR,5:constb@YpW,z@YrX,G@cDG,1I_@Ysq,_@Nql,J@SPy,4NC@_BU,28lZAF; defined(_WIN32) |
| 171 | # pop ) ownership of it to the |
| 172 | caller. It must eventually be destroyed, by the caller or its |
| 173 | owning or transfering |
| 174 | |
| 175 | void/** |
| 176 | This special-case impl is needed because the underlying |
| 177 | (generic) list operations do not know how to populate |
| 178 | new entries |
| 179 | */ use |
| 180 | the =*arg)){ use |
| 181 | the def use |
| 182 | the defaul |
| 183 | o 2008-05-20 * C2 |
| 184 | MODE_KEY = 3, break; |
| 185 | /* LICENSE |
| 186 | |
| 187 | CopyCENSE |
| 188 | |
| 189 | Copy |
| 190 | |
| 191 | use |
| 192 | } |
| 193 | |
| 194 | use |
| 195 | the defaul |
| 196 | o 2008-05-20 * C2 |
| 197 | MODE_KEY = 3, break; |
| 198 | /* LICENSE |
| 199 | |
| 200 | CopyCENSE |
| 201 | |
| 202 | Copy |
| 203 | |
| 204 | |
| 205 | |
| 206 | |
| 207 | |
| 208 | pack.c */ |
| 209 | ? cson_guess_arg_type(pos: use |
| 210 | the defaul |
| 211 | 0 != (rc= use |
| 212 | the defaul |
| 213 | o 2008-05-20 * C2 |
| 214 | MODE_KEY = 3, break; |
| 215 | /* LICENSE |
| 216 | |
| 217 | CopyCENSE |
| 218 | |
| 219 | Copy |
| 220 | |
| 221 | |
| 222 | |
| 223 | |
| 224 | |
| 225 | pack.c */ |
| 226 | 0_guess_arg_type(pos: use |
| 227 | t use |
| 228 | MODE_KEY = 3, use |
| 229 | ; |
| 230 | p->c 0 == rc ) use |
| 231 | }Aary use |
| 232 | the the defaul |
| 233 | o 2008-05-20 * C2 |
| 234 | MODE_KEY = 3, break; |
| 235 | /* LICENSE |
| 236 | |
| 237 | CopyCENSE |
| 238 | |
| 239 | Copy |
| 240 | |
| 241 | |
| 242 | |
| 243 | |
| 244 | |
| 245 | pack.c */ |
| 246 | #V)->value)m/* FIXME: if sizeof(void*) > then store |
| 247 | the int value directly in the v). The curbytes(!!!) on 64-bit builds.in |
| 248 | use |
| 249 | the defaul |
| 250 | o 2008-05-20 * C2 |
| 251 | MODE_KEY = 3, break; |
| 252 | /* LICENSE |
| 253 | |
| 254 | CopyCENSE |
| 255 | |
| 256 | Copy |
| 257 | |
| 258 | |
| 259 | |
| 260 | |
| 261 | |
| 262 | pack.c */ |
| 263 | if( use |
| 264 | the clone_shared(ul |
| 265 | o 2008-05-20 2008-05-20 * sharedshared use |
| 266 | ('0'<=*arg) && ('9'>=*arg)){ use |
| 267 | the def use |
| 268 | the defaul |
| 269 | o 2008-05-20 * C2 |
| 270 | MODE_KEY = 3, break; |
| 271 | /* LICENSE |
| 272 | |
| 273 | CopyCENSE |
| 274 | |
| 275 | Copy |
| 276 | |
| 277 | use |
| 278 | } |
| 279 | |
| 280 | use |
| 281 | the defaul |
| 282 | o 2008-05-20 * C2 |
| 283 | MODE_KEY = 3, break; |
| 284 | /* LICENSE |
| 285 | |
| 286 | CopyCENSE |
| 287 | |
| 288 | Copy |
| 289 | |
| 290 | |
| 291 | |
| 292 | |
| 293 | |
| 294 | pack.c */ |
| 295 | ? cson_guess_arg_type(pos: use |
| 296 | the defaul |
| 297 | 0 != (rc= use |
| 298 | the defaul |
| 299 | o 2008-05-20 * C2 |
| 300 | MODE_KEY = 3, break; |
| 301 | /* LICENSE |
| 302 | |
| 303 | CopyCENSE |
| 304 | |
| 305 | Copy |
| 306 | |
| 307 | |
| 308 | |
| 309 | |
| 310 | |
| 311 | pack.c */ |
| 312 | defaul |
| 313 | o 2008-05-20 * C2 |
| 314 | MODE_KEY = 3, break; |
| 315 | /* LICENSE |
| 316 | |
| 317 | CopyCENSE |
| 318 | |
| 319 | Copy |
| 320 | |
| 321 | |
| 322 | |
| 323 | |
| 324 | |
| 325 | pack.c */ |
| 326 | #V)->value)m/* FIXME: if sizeof(void*) > then store |
| 327 | the int value directly in the v). The curbytes(!!!) on 64-bit builds.in |
| 328 | use |
| 329 | the defaul |
| 330 | o 2008-05-20 * C2 |
| 331 | MODE_KEY = 3, break; |
| 332 | /* LICENSE |
| 333 | |
| 334 | CopyCENSE |
| 335 | |
| 336 | Copy |
| 337 | |
| 338 | |
| 339 | |
| 340 | |
| 341 | |
| 342 | pack.c */ |
| 343 | if( use |
| 344 | the clone_shared(ul |
| 345 | o 2008-05-20 2008-05-20 * sharedshared use |
| 346 | ('0'<=*arg) && ('9'>=*arg)){ use |
| 347 | the def use |
| 348 | the defaul |
| 349 | o 2008-05-20 * C2 |
| 350 | MODE_KEY = 3, break; |
| 351 | /* LICENSE |
| 352 | |
| 353 | CopyCENSE |
| 354 | |
| 355 | Copy |
| 356 | |
| 357 | use |
| 358 | } |
| 359 | |
| 360 | use |
| 361 | the defaul |
| 362 | o 2008-05-20 * C2 |
| 363 | MODE_KEY = 3, break; |
| 364 | /* LICENSE |
| 365 | |
| 366 | CopyCENSE |
| 367 | |
| 368 | Copy |
| 369 | |
| 370 | |
| 371 | |
| 372 | |
| 373 | |
| 374 | pack.c */ |
| 375 | ? cson_guess_arg_type(pos: use |
| 376 | the defaul |
| 377 | 0 != (rc= use |
| 378 | the defaul |
| 379 | o 2008-05-20 * C2 |
| 380 | MODE_KEY = 3, break; |
| 381 | /* LICENSE |
| 382 | |
| 383 | CopyCENSE |
| 384 | |
| 385 | Copy |
| 386 | |
| 387 | |
| 388 | |
| 389 | |
| 390 | |
| 391 | pack.c */ |
| 392 | 0_guess_arg_type(pos: use |
| 393 | t use |
| 394 | MODE_KEY = 3, use |
| 395 | ; |
| 396 | p->c 0 == rc ) use |
| 397 | }ARRAY_END:( ch}/* |
| 398 | refcount the keys! We first need a setter which takes |
| 399 | 8@JnB,b:a cson_string or cson_value key type. |
| 400 | K@OzU,D:cson_value * K@I20,G@FK0,H@cX0,3:keyK@Xhl,J@_4E,S@YGA,E:( kvp->value )H@NM0,X@YHA,G@cDG,G@PEl,W@O4l,_@YNG,L@blG,M@Yfi,C:CSON_STR(keyH@bp0,1B@YIj,G@cDG,G@PEl,W@O4l,_@YNG,L@blG,G@8RG,TX@YOR,5:constb@YpW,z@YrX,G@cDG,1I_@Ysq,_@Nql,J@SPy,4NC@_BU,28lZAF; defined(_WIN32) |
| 401 | # pop ) ownership of it to the |
| 402 | caller. It must eventually be destroyed, by the caller or its |
| 403 | owning or transfering |
| 404 | |
| 405 | void/** |
| 406 | This special-case impl is needed because the underlying |
| 407 | (generic) list operations do not know how to populate |
| 408 | new entries |
| 409 | */ use |
| 410 | the =*arg)){ use |
| 411 | the def use |
| 412 | the defaul |
| 413 | o 2008-05-20 * C2 |
| 414 | MODE_KEY = 3, break; |
| 415 | /* LICENSE |
| 416 | |
| 417 | CopyCENSE |
| 418 | |
| 419 | Copy |
| 420 | |
| 421 | use |
| 422 | } |
| 423 | |
| 424 | use |
| 425 | the defaul |
| 426 | o 2008-05-20 * C2 |
| 427 | MODE_KEY = 3, break; |
| 428 | /* LICENSE |
| 429 | |
| 430 | CopyCENSE |
| 431 | |
| 432 | Copy |
| 433 | |
| 434 | |
| 435 | |
| 436 | |
| 437 | |
| 438 | pack.c */ |
| 439 | ? cson_guess_arg_type(pos: use |
| 440 | the defaul |
| 441 | 0 != (rc= use |
| 442 | the defaul |
| 443 | o 2008-05-20 * C2 |
| 444 | MODE_KEY = 3, break; |
| 445 | /* LICENSE |
| 446 | |
| 447 | CopyCENSE |
| 448 | |
| 449 | Copy |
| 450 | |
| 451 | |
| 452 | |
| 453 | |
| 454 | |
| 455 | pack.c */ |
| 456 | 0_guess_arg_type(pos: use |
| 457 | t use |
| 458 | MODE_KEY = 3, use |
| 459 | ; |
| 460 | p->c 0 == rc ) use |
| 461 | }Aarye |
| 462 | } |
| 463 | |
| 464 | use |
| 465 | the defaul |
| 466 | o 2008-05-20 * C2 |
| 467 | MODE_KEY = 3, break; |
| 468 | /* LICENSE |
| 469 | |
| 470 | CopyCENSE |
| 471 | |
| 472 | Copy |
| 473 | |
| 474 | |
| 475 | |
| 476 | |
| 477 | |
| 478 | pack.c */ |
| 479 | ? cson_guess_arg_type(pos: use |
| 480 | the defaul |
| 481 | 0 != (rc= use |
| 482 | the defaul |
| 483 | o 2008-05-20 * C2 |
| 484 | MODE_KEY = 3, break; |
| 485 | /* LICENSE |
| 486 | |
| 487 | CopyCENSE |
| 488 | |
| 489 | Copy |
| 490 | |
| 491 | |
| 492 | |
| 493 | |
| 494 | |
| 495 | pack.c */ |
| 496 | defaul |
| 497 | o 2008-05-20 * C2 |
| 498 | MODE_KEY = 3, break; |
| 499 | /* LICENSE |
| 500 | |
| 501 | CopyCENSE |
| 502 | |
| 503 | Copy |
| 504 | |
| 505 | |
| 506 | |
| 507 | |
| 508 | |
| 509 | pack.c */ |
| 510 | #V)->value)m/* FIXME: if sizeof(void*) > then store |
| 511 | the int value directly in the v). The curbytes(!!!) on 64-bit builds.in |
| 512 | use |
| 513 | the defaul |
| 514 | o 2008-05-20 * C2 |
| 515 | MODE_KEY = 3, break; |
| 516 | /* LICENSE |
| 517 | |
| 518 | CopyCENSE |
| 519 | |
| 520 | Copy |
| 521 | |
| 522 | |
| 523 | |
| 524 | |
| 525 | |
| 526 | pack.c */ |
| 527 | if( use |
| 528 | the clone_shared(ul |
| 529 | o 2008-05-20 2008-05-20 * sharedshared use |
| 530 | ('0'<=*arg) && ('9'>=*arg)){ use |
| 531 | the def use |
| 532 | the defaul |
| 533 | o 2008-05-20 * C2 |
| 534 | MODE_KEY = 3, break; |
| 535 | /* LICENSE |
| 536 | |
| 537 | CopyCENSE |
| 538 | |
| 539 | Copy |
| 540 | |
| 541 | use |
| 542 | } |
| 543 | |
| 544 | use |
| 545 | the defaul |
| 546 | o 2008-05-20 * C2 |
| 547 | MODE_KEY = 3, break; |
| 548 | /* LICENSE |
| 549 | |
| 550 | CopyCENSE |
| 551 | |
| 552 | Copy |
| 553 | |
| 554 | |
| 555 | |
| 556 | |
| 557 | |
| 558 | pack.c */ |
| 559 | ? cson_guess_arg_type(pos: use |
| 560 | the defaul |
| 561 | 0 != (rc= use |
| 562 | the defaul |
| 563 | o 2008-05-20 * C2 |
| 564 | MODE_KEY = 3, break; |
| 565 | /* LICENSE |
| 566 | |
| 567 | CopyCENSE |
| 568 | |
| 569 | Copy |
| 570 | |
| 571 | |
| 572 | |
| 573 | |
| 574 | |
| 575 | pack.c */ |
| 576 | 0_guess_arg_type(pos: use |
| 577 | t use |
| 578 | MODE_KEY = 3, use |
| 579 | ; |
| 580 | p->c 0 == rc ) use |
| 581 | }ARRAY_END:( ch}/* |
| 582 | refcount the keys! We first need a setter which takes |
| 583 | 8@JnB,b:a cson_string or cson_value key type. |
| 584 | K@OzU,D:cson_value * K@I20,G@FK0,H@cX0,3:keyK@Xhl,J@_4E,S@YGA,E:( kvp->value )H@NM0,X@YHA,G@cDG,G@PEl,W@O4l,_@YNG,L@blG,M@Yfi,C:CSON_STR(keyH@bp0,1B@YIj,G@cDG,G@PEl,W@O4l,_@YNG,L@blG,G@8RG,TX@YOR,5:constb@YpW,z@YrX,G@cDG,1I_@Ysq,_@Nql,J@SPy,4NC@_BU,28lZAF; defined(_WIN32) |
| 585 | # pop ) ownership of it to the |
| 586 | caller. It must eventually be destroyed, by the caller or its |
| 587 | owning or transfering |
| 588 | |
| 589 | void/** |
| 590 | This special-case impl is needed because the underlying |
| 591 | (generic) list operations do not know how to populate |
| 592 | new entries |
| 593 | */ use |
| 594 | the =*arg)){ use |
| 595 | the def use |
| 596 | the defaul |
| 597 | o 2008-05-20 * C2 |
| 598 | MODE_KEY = 3, break; |
| 599 | /* LICENSE |
| 600 | |
| 601 | CopyCENSE |
| 602 | |
| 603 | Copy |
| 604 | |
| 605 | use |
| 606 | } |
| 607 | |
| 608 | use |
| 609 | the defaul |
| 610 | o 2008-05-20 * C2 |
| 611 | MODE_KEY = 3, break; |
| 612 | /* LICENSE |
| 613 | |
| 614 | CopyCENSE |
| 615 | |
| 616 | Copy |
| 617 | |
| 618 | |
| 619 | |
| 620 | |
| 621 | |
| 622 | pack.c */ |
| 623 | ? cson_guess_arg_type(pos: use |
| 624 | the defaul |
| 625 | 0 != (rc= use |
| 626 | the defaul |
| 627 | o 2008-05-20 * C2 |
| 628 | MODE_KEY = 3, break; |
| 629 | /* LICENSE |
| 630 | |
| 631 | CopyCENSE |
| 632 | |
| 633 | Copy |
| 634 | |
| 635 | |
| 636 | |
| 637 | |
| 638 | |
| 639 | pack.c */ |
| 640 | 0_guess_arg_type(pos: use |
| 641 | t use |
| 642 | MODE_KEY = 3, use |
| 643 | ; |
| 644 | p->c 0 == rc ) use |
| 645 | }Aary |
| --- a/src/cson_amalgamation.h | ||
| +++ b/src/cson_amalgamation.h | ||
| @@ -0,0 +1,9 @@ | ||
| 1 | +#ifdef FOSSIL_ENABLEconst | |
| 2 | + #ifdef returned | |
| 3 | + #ifde.value * recursively if it is | |
| 4 | + and multiple times within a | |
| 5 | + full cost. We | |
| 6 | + have no what visited | |
| 7 | + we | |
| 8 | + count | |
| 9 | + for#ifdef FOSSIL_ENABLEFOSSIL_ENABLE |
| --- a/src/cson_amalgamation.h | |
| +++ b/src/cson_amalgamation.h | |
| @@ -0,0 +1,9 @@ | |
| --- a/src/cson_amalgamation.h | |
| +++ b/src/cson_amalgamation.h | |
| @@ -0,0 +1,9 @@ | |
| 1 | #ifdef FOSSIL_ENABLEconst |
| 2 | #ifdef returned |
| 3 | #ifde.value * recursively if it is |
| 4 | and multiple times within a |
| 5 | full cost. We |
| 6 | have no what visited |
| 7 | we |
| 8 | count |
| 9 | for#ifdef FOSSIL_ENABLEFOSSIL_ENABLE |
M
src/db.c
+39
-5
| --- src/db.c | ||
| +++ src/db.c | ||
| @@ -48,40 +48,59 @@ | ||
| 48 | 48 | Blob sql; /* The SQL for this statement */ |
| 49 | 49 | sqlite3_stmt *pStmt; /* The results of sqlite3_prepare() */ |
| 50 | 50 | Stmt *pNext, *pPrev; /* List of all unfinalized statements */ |
| 51 | 51 | int nStep; /* Number of sqlite3_step() calls */ |
| 52 | 52 | }; |
| 53 | + | |
| 54 | +/* | |
| 55 | +** Copy this to initialize a Stmt object to a clean/empty state. This | |
| 56 | +** is useful to help avoid assertions when performing cleanup in some | |
| 57 | +** error handling cases. | |
| 58 | +*/ | |
| 59 | +#define empty_Stmt_m {BLOB_INITIALIZER,NULL, NULL, NULL, 0} | |
| 53 | 60 | #endif /* INTERFACE */ |
| 61 | +const struct Stmt empty_Stmt = empty_Stmt_m; | |
| 54 | 62 | |
| 55 | 63 | /* |
| 56 | 64 | ** Call this routine when a database error occurs. |
| 57 | 65 | */ |
| 58 | 66 | static void db_err(const char *zFormat, ...){ |
| 59 | 67 | va_list ap; |
| 60 | 68 | char *z; |
| 69 | + int rc = 1; | |
| 61 | 70 | static const char zRebuildMsg[] = |
| 62 | 71 | "If you have recently updated your fossil executable, you might\n" |
| 63 | 72 | "need to run \"fossil all rebuild\" to bring the repository\n" |
| 64 | 73 | "schemas up to date.\n"; |
| 65 | 74 | va_start(ap, zFormat); |
| 66 | 75 | z = vmprintf(zFormat, ap); |
| 67 | 76 | va_end(ap); |
| 77 | +#ifdef FOSSIL_ENABLE_JSON | |
| 78 | + if( g.json.isJsonMode ){ | |
| 79 | + json_err( 0, z, 1 ); | |
| 80 | + if( g.isHTTP ){ | |
| 81 | + rc = 0 /* avoid HTTP 500 */; | |
| 82 | + } | |
| 83 | + } | |
| 84 | + else | |
| 85 | +#endif /* FOSSIL_ENABLE_JSON */ | |
| 68 | 86 | if( g.xferPanic ){ |
| 69 | 87 | cgi_reset_content(); |
| 70 | 88 | @ error Database\serror:\s%F(z) |
| 71 | - cgi_reply(); | |
| 89 | + cgi_reply(); | |
| 72 | 90 | } |
| 73 | - if( g.cgiOutput ){ | |
| 91 | + else if( g.cgiOutput ){ | |
| 74 | 92 | g.cgiOutput = 0; |
| 75 | 93 | cgi_printf("<h1>Database Error</h1>\n" |
| 76 | 94 | "<pre>%h</pre><p>%s</p>", z, zRebuildMsg); |
| 77 | 95 | cgi_reply(); |
| 78 | 96 | }else{ |
| 79 | 97 | fprintf(stderr, "%s: %s\n\n%s", fossil_nameofexe(), z, zRebuildMsg); |
| 80 | 98 | } |
| 99 | + free(z); | |
| 81 | 100 | db_force_rollback(); |
| 82 | - fossil_exit(1); | |
| 101 | + fossil_exit(rc); | |
| 83 | 102 | } |
| 84 | 103 | |
| 85 | 104 | static int nBegin = 0; /* Nesting depth of BEGIN */ |
| 86 | 105 | static int doRollback = 0; /* True to force a rollback */ |
| 87 | 106 | static int nCommitHook = 0; /* Number of commit hooks */ |
| @@ -561,11 +580,11 @@ | ||
| 561 | 580 | ** Execute a query. Return the first column of the first row |
| 562 | 581 | ** of the result set as a string. Space to hold the string is |
| 563 | 582 | ** obtained from malloc(). If the result set is empty, return |
| 564 | 583 | ** zDefault instead. |
| 565 | 584 | */ |
| 566 | -char *db_text(char *zDefault, const char *zSql, ...){ | |
| 585 | +char *db_text(char const *zDefault, const char *zSql, ...){ | |
| 567 | 586 | va_list ap; |
| 568 | 587 | Stmt s; |
| 569 | 588 | char *z; |
| 570 | 589 | va_start(ap, zSql); |
| 571 | 590 | db_vprepare(&s, 0, zSql, ap); |
| @@ -863,15 +882,24 @@ | ||
| 863 | 882 | db_err("unable to find the name of a repository database"); |
| 864 | 883 | } |
| 865 | 884 | } |
| 866 | 885 | if( file_access(zDbName, R_OK) || file_size(zDbName)<1024 ){ |
| 867 | 886 | if( file_access(zDbName, 0) ){ |
| 887 | +#ifdef FOSSIL_ENABLE_JSON | |
| 888 | + g.json.resultCode = FSL_JSON_E_DB_NOT_FOUND; | |
| 889 | +#endif | |
| 868 | 890 | fossil_panic("repository does not exist or" |
| 869 | 891 | " is in an unreadable directory: %s", zDbName); |
| 870 | 892 | }else if( file_access(zDbName, R_OK) ){ |
| 893 | +#ifdef FOSSIL_ENABLE_JSON | |
| 894 | + g.json.resultCode = FSL_JSON_E_DENIED; | |
| 895 | +#endif | |
| 871 | 896 | fossil_panic("read permission denied for repository %s", zDbName); |
| 872 | 897 | }else{ |
| 898 | +#ifdef FOSSIL_ENABLE_JSON | |
| 899 | + g.json.resultCode = FSL_JSON_E_DB_NOT_VALID; | |
| 900 | +#endif | |
| 873 | 901 | fossil_panic("not a valid repository: %s", zDbName); |
| 874 | 902 | } |
| 875 | 903 | } |
| 876 | 904 | db_open_or_attach(zDbName, "repository"); |
| 877 | 905 | g.repositoryOpen = 1; |
| @@ -902,11 +930,11 @@ | ||
| 902 | 930 | } |
| 903 | 931 | if( zRep==0 ){ |
| 904 | 932 | if( db_open_local()==0 ){ |
| 905 | 933 | goto rep_not_found; |
| 906 | 934 | } |
| 907 | - zRep = db_lget("repository", 0); | |
| 935 | + zRep = db_lget("repository", 0)/*leak here*/; | |
| 908 | 936 | if( zRep==0 ){ |
| 909 | 937 | goto rep_not_found; |
| 910 | 938 | } |
| 911 | 939 | } |
| 912 | 940 | db_open_repository(zRep); |
| @@ -914,10 +942,13 @@ | ||
| 914 | 942 | if( (bFlags & OPEN_ANY_SCHEMA)==0 ) db_verify_schema(); |
| 915 | 943 | return; |
| 916 | 944 | } |
| 917 | 945 | rep_not_found: |
| 918 | 946 | if( (bFlags & OPEN_OK_NOT_FOUND)==0 ){ |
| 947 | +#ifdef FOSSIL_ENABLE_JSON | |
| 948 | + g.json.resultCode = FSL_JSON_E_DB_NOT_FOUND; | |
| 949 | +#endif | |
| 919 | 950 | fossil_fatal("use --repository or -R to specify the repository database"); |
| 920 | 951 | } |
| 921 | 952 | } |
| 922 | 953 | |
| 923 | 954 | /* |
| @@ -944,10 +975,13 @@ | ||
| 944 | 975 | ** Verify that the repository schema is correct. If it is not correct, |
| 945 | 976 | ** issue a fatal error and die. |
| 946 | 977 | */ |
| 947 | 978 | void db_verify_schema(void){ |
| 948 | 979 | if( db_schema_is_outofdate() ){ |
| 980 | +#ifdef FOSSIL_ENABLE_JSON | |
| 981 | + g.json.resultCode = FSL_JSON_E_DB_NEEDS_REBUILD; | |
| 982 | +#endif | |
| 949 | 983 | fossil_warning("incorrect repository schema version"); |
| 950 | 984 | fossil_warning("your repository has schema version \"%s\" " |
| 951 | 985 | "but this binary expects version \"%s\"", |
| 952 | 986 | db_get("aux-schema",0), AUX_SCHEMA); |
| 953 | 987 | fossil_fatal("run \"fossil rebuild\" to fix this problem"); |
| 954 | 988 | |
| 955 | 989 | ADDED src/json.c |
| 956 | 990 | ADDED src/json_artifact.c |
| 957 | 991 | ADDED src/json_branch.c |
| 958 | 992 | ADDED src/json_detail.h |
| 959 | 993 | ADDED src/json_diff.c |
| 960 | 994 | ADDED src/json_login.c |
| 961 | 995 | ADDED src/json_query.c |
| 962 | 996 | ADDED src/json_report.c |
| 963 | 997 | ADDED src/json_tag.c |
| 964 | 998 | ADDED src/json_timeline.c |
| 965 | 999 | ADDED src/json_user.c |
| 966 | 1000 | ADDED src/json_wiki.c |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -48,40 +48,59 @@ | |
| 48 | Blob sql; /* The SQL for this statement */ |
| 49 | sqlite3_stmt *pStmt; /* The results of sqlite3_prepare() */ |
| 50 | Stmt *pNext, *pPrev; /* List of all unfinalized statements */ |
| 51 | int nStep; /* Number of sqlite3_step() calls */ |
| 52 | }; |
| 53 | #endif /* INTERFACE */ |
| 54 | |
| 55 | /* |
| 56 | ** Call this routine when a database error occurs. |
| 57 | */ |
| 58 | static void db_err(const char *zFormat, ...){ |
| 59 | va_list ap; |
| 60 | char *z; |
| 61 | static const char zRebuildMsg[] = |
| 62 | "If you have recently updated your fossil executable, you might\n" |
| 63 | "need to run \"fossil all rebuild\" to bring the repository\n" |
| 64 | "schemas up to date.\n"; |
| 65 | va_start(ap, zFormat); |
| 66 | z = vmprintf(zFormat, ap); |
| 67 | va_end(ap); |
| 68 | if( g.xferPanic ){ |
| 69 | cgi_reset_content(); |
| 70 | @ error Database\serror:\s%F(z) |
| 71 | cgi_reply(); |
| 72 | } |
| 73 | if( g.cgiOutput ){ |
| 74 | g.cgiOutput = 0; |
| 75 | cgi_printf("<h1>Database Error</h1>\n" |
| 76 | "<pre>%h</pre><p>%s</p>", z, zRebuildMsg); |
| 77 | cgi_reply(); |
| 78 | }else{ |
| 79 | fprintf(stderr, "%s: %s\n\n%s", fossil_nameofexe(), z, zRebuildMsg); |
| 80 | } |
| 81 | db_force_rollback(); |
| 82 | fossil_exit(1); |
| 83 | } |
| 84 | |
| 85 | static int nBegin = 0; /* Nesting depth of BEGIN */ |
| 86 | static int doRollback = 0; /* True to force a rollback */ |
| 87 | static int nCommitHook = 0; /* Number of commit hooks */ |
| @@ -561,11 +580,11 @@ | |
| 561 | ** Execute a query. Return the first column of the first row |
| 562 | ** of the result set as a string. Space to hold the string is |
| 563 | ** obtained from malloc(). If the result set is empty, return |
| 564 | ** zDefault instead. |
| 565 | */ |
| 566 | char *db_text(char *zDefault, const char *zSql, ...){ |
| 567 | va_list ap; |
| 568 | Stmt s; |
| 569 | char *z; |
| 570 | va_start(ap, zSql); |
| 571 | db_vprepare(&s, 0, zSql, ap); |
| @@ -863,15 +882,24 @@ | |
| 863 | db_err("unable to find the name of a repository database"); |
| 864 | } |
| 865 | } |
| 866 | if( file_access(zDbName, R_OK) || file_size(zDbName)<1024 ){ |
| 867 | if( file_access(zDbName, 0) ){ |
| 868 | fossil_panic("repository does not exist or" |
| 869 | " is in an unreadable directory: %s", zDbName); |
| 870 | }else if( file_access(zDbName, R_OK) ){ |
| 871 | fossil_panic("read permission denied for repository %s", zDbName); |
| 872 | }else{ |
| 873 | fossil_panic("not a valid repository: %s", zDbName); |
| 874 | } |
| 875 | } |
| 876 | db_open_or_attach(zDbName, "repository"); |
| 877 | g.repositoryOpen = 1; |
| @@ -902,11 +930,11 @@ | |
| 902 | } |
| 903 | if( zRep==0 ){ |
| 904 | if( db_open_local()==0 ){ |
| 905 | goto rep_not_found; |
| 906 | } |
| 907 | zRep = db_lget("repository", 0); |
| 908 | if( zRep==0 ){ |
| 909 | goto rep_not_found; |
| 910 | } |
| 911 | } |
| 912 | db_open_repository(zRep); |
| @@ -914,10 +942,13 @@ | |
| 914 | if( (bFlags & OPEN_ANY_SCHEMA)==0 ) db_verify_schema(); |
| 915 | return; |
| 916 | } |
| 917 | rep_not_found: |
| 918 | if( (bFlags & OPEN_OK_NOT_FOUND)==0 ){ |
| 919 | fossil_fatal("use --repository or -R to specify the repository database"); |
| 920 | } |
| 921 | } |
| 922 | |
| 923 | /* |
| @@ -944,10 +975,13 @@ | |
| 944 | ** Verify that the repository schema is correct. If it is not correct, |
| 945 | ** issue a fatal error and die. |
| 946 | */ |
| 947 | void db_verify_schema(void){ |
| 948 | if( db_schema_is_outofdate() ){ |
| 949 | fossil_warning("incorrect repository schema version"); |
| 950 | fossil_warning("your repository has schema version \"%s\" " |
| 951 | "but this binary expects version \"%s\"", |
| 952 | db_get("aux-schema",0), AUX_SCHEMA); |
| 953 | fossil_fatal("run \"fossil rebuild\" to fix this problem"); |
| 954 | |
| 955 | DDED src/json.c |
| 956 | DDED src/json_artifact.c |
| 957 | DDED src/json_branch.c |
| 958 | DDED src/json_detail.h |
| 959 | DDED src/json_diff.c |
| 960 | DDED src/json_login.c |
| 961 | DDED src/json_query.c |
| 962 | DDED src/json_report.c |
| 963 | DDED src/json_tag.c |
| 964 | DDED src/json_timeline.c |
| 965 | DDED src/json_user.c |
| 966 | DDED src/json_wiki.c |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -48,40 +48,59 @@ | |
| 48 | Blob sql; /* The SQL for this statement */ |
| 49 | sqlite3_stmt *pStmt; /* The results of sqlite3_prepare() */ |
| 50 | Stmt *pNext, *pPrev; /* List of all unfinalized statements */ |
| 51 | int nStep; /* Number of sqlite3_step() calls */ |
| 52 | }; |
| 53 | |
| 54 | /* |
| 55 | ** Copy this to initialize a Stmt object to a clean/empty state. This |
| 56 | ** is useful to help avoid assertions when performing cleanup in some |
| 57 | ** error handling cases. |
| 58 | */ |
| 59 | #define empty_Stmt_m {BLOB_INITIALIZER,NULL, NULL, NULL, 0} |
| 60 | #endif /* INTERFACE */ |
| 61 | const struct Stmt empty_Stmt = empty_Stmt_m; |
| 62 | |
| 63 | /* |
| 64 | ** Call this routine when a database error occurs. |
| 65 | */ |
| 66 | static void db_err(const char *zFormat, ...){ |
| 67 | va_list ap; |
| 68 | char *z; |
| 69 | int rc = 1; |
| 70 | static const char zRebuildMsg[] = |
| 71 | "If you have recently updated your fossil executable, you might\n" |
| 72 | "need to run \"fossil all rebuild\" to bring the repository\n" |
| 73 | "schemas up to date.\n"; |
| 74 | va_start(ap, zFormat); |
| 75 | z = vmprintf(zFormat, ap); |
| 76 | va_end(ap); |
| 77 | #ifdef FOSSIL_ENABLE_JSON |
| 78 | if( g.json.isJsonMode ){ |
| 79 | json_err( 0, z, 1 ); |
| 80 | if( g.isHTTP ){ |
| 81 | rc = 0 /* avoid HTTP 500 */; |
| 82 | } |
| 83 | } |
| 84 | else |
| 85 | #endif /* FOSSIL_ENABLE_JSON */ |
| 86 | if( g.xferPanic ){ |
| 87 | cgi_reset_content(); |
| 88 | @ error Database\serror:\s%F(z) |
| 89 | cgi_reply(); |
| 90 | } |
| 91 | else if( g.cgiOutput ){ |
| 92 | g.cgiOutput = 0; |
| 93 | cgi_printf("<h1>Database Error</h1>\n" |
| 94 | "<pre>%h</pre><p>%s</p>", z, zRebuildMsg); |
| 95 | cgi_reply(); |
| 96 | }else{ |
| 97 | fprintf(stderr, "%s: %s\n\n%s", fossil_nameofexe(), z, zRebuildMsg); |
| 98 | } |
| 99 | free(z); |
| 100 | db_force_rollback(); |
| 101 | fossil_exit(rc); |
| 102 | } |
| 103 | |
| 104 | static int nBegin = 0; /* Nesting depth of BEGIN */ |
| 105 | static int doRollback = 0; /* True to force a rollback */ |
| 106 | static int nCommitHook = 0; /* Number of commit hooks */ |
| @@ -561,11 +580,11 @@ | |
| 580 | ** Execute a query. Return the first column of the first row |
| 581 | ** of the result set as a string. Space to hold the string is |
| 582 | ** obtained from malloc(). If the result set is empty, return |
| 583 | ** zDefault instead. |
| 584 | */ |
| 585 | char *db_text(char const *zDefault, const char *zSql, ...){ |
| 586 | va_list ap; |
| 587 | Stmt s; |
| 588 | char *z; |
| 589 | va_start(ap, zSql); |
| 590 | db_vprepare(&s, 0, zSql, ap); |
| @@ -863,15 +882,24 @@ | |
| 882 | db_err("unable to find the name of a repository database"); |
| 883 | } |
| 884 | } |
| 885 | if( file_access(zDbName, R_OK) || file_size(zDbName)<1024 ){ |
| 886 | if( file_access(zDbName, 0) ){ |
| 887 | #ifdef FOSSIL_ENABLE_JSON |
| 888 | g.json.resultCode = FSL_JSON_E_DB_NOT_FOUND; |
| 889 | #endif |
| 890 | fossil_panic("repository does not exist or" |
| 891 | " is in an unreadable directory: %s", zDbName); |
| 892 | }else if( file_access(zDbName, R_OK) ){ |
| 893 | #ifdef FOSSIL_ENABLE_JSON |
| 894 | g.json.resultCode = FSL_JSON_E_DENIED; |
| 895 | #endif |
| 896 | fossil_panic("read permission denied for repository %s", zDbName); |
| 897 | }else{ |
| 898 | #ifdef FOSSIL_ENABLE_JSON |
| 899 | g.json.resultCode = FSL_JSON_E_DB_NOT_VALID; |
| 900 | #endif |
| 901 | fossil_panic("not a valid repository: %s", zDbName); |
| 902 | } |
| 903 | } |
| 904 | db_open_or_attach(zDbName, "repository"); |
| 905 | g.repositoryOpen = 1; |
| @@ -902,11 +930,11 @@ | |
| 930 | } |
| 931 | if( zRep==0 ){ |
| 932 | if( db_open_local()==0 ){ |
| 933 | goto rep_not_found; |
| 934 | } |
| 935 | zRep = db_lget("repository", 0)/*leak here*/; |
| 936 | if( zRep==0 ){ |
| 937 | goto rep_not_found; |
| 938 | } |
| 939 | } |
| 940 | db_open_repository(zRep); |
| @@ -914,10 +942,13 @@ | |
| 942 | if( (bFlags & OPEN_ANY_SCHEMA)==0 ) db_verify_schema(); |
| 943 | return; |
| 944 | } |
| 945 | rep_not_found: |
| 946 | if( (bFlags & OPEN_OK_NOT_FOUND)==0 ){ |
| 947 | #ifdef FOSSIL_ENABLE_JSON |
| 948 | g.json.resultCode = FSL_JSON_E_DB_NOT_FOUND; |
| 949 | #endif |
| 950 | fossil_fatal("use --repository or -R to specify the repository database"); |
| 951 | } |
| 952 | } |
| 953 | |
| 954 | /* |
| @@ -944,10 +975,13 @@ | |
| 975 | ** Verify that the repository schema is correct. If it is not correct, |
| 976 | ** issue a fatal error and die. |
| 977 | */ |
| 978 | void db_verify_schema(void){ |
| 979 | if( db_schema_is_outofdate() ){ |
| 980 | #ifdef FOSSIL_ENABLE_JSON |
| 981 | g.json.resultCode = FSL_JSON_E_DB_NEEDS_REBUILD; |
| 982 | #endif |
| 983 | fossil_warning("incorrect repository schema version"); |
| 984 | fossil_warning("your repository has schema version \"%s\" " |
| 985 | "but this binary expects version \"%s\"", |
| 986 | db_get("aux-schema",0), AUX_SCHEMA); |
| 987 | fossil_fatal("run \"fossil rebuild\" to fix this problem"); |
| 988 | |
| 989 | DDED src/json.c |
| 990 | DDED src/json_artifact.c |
| 991 | DDED src/json_branch.c |
| 992 | DDED src/json_detail.h |
| 993 | DDED src/json_diff.c |
| 994 | DDED src/json_login.c |
| 995 | DDED src/json_query.c |
| 996 | DDED src/json_report.c |
| 997 | DDED src/json_tag.c |
| 998 | DDED src/json_timeline.c |
| 999 | DDED src/json_user.c |
| 1000 | DDED src/json_wiki.c |
M
src/db.c
+39
-5
| --- src/db.c | ||
| +++ src/db.c | ||
| @@ -48,40 +48,59 @@ | ||
| 48 | 48 | Blob sql; /* The SQL for this statement */ |
| 49 | 49 | sqlite3_stmt *pStmt; /* The results of sqlite3_prepare() */ |
| 50 | 50 | Stmt *pNext, *pPrev; /* List of all unfinalized statements */ |
| 51 | 51 | int nStep; /* Number of sqlite3_step() calls */ |
| 52 | 52 | }; |
| 53 | + | |
| 54 | +/* | |
| 55 | +** Copy this to initialize a Stmt object to a clean/empty state. This | |
| 56 | +** is useful to help avoid assertions when performing cleanup in some | |
| 57 | +** error handling cases. | |
| 58 | +*/ | |
| 59 | +#define empty_Stmt_m {BLOB_INITIALIZER,NULL, NULL, NULL, 0} | |
| 53 | 60 | #endif /* INTERFACE */ |
| 61 | +const struct Stmt empty_Stmt = empty_Stmt_m; | |
| 54 | 62 | |
| 55 | 63 | /* |
| 56 | 64 | ** Call this routine when a database error occurs. |
| 57 | 65 | */ |
| 58 | 66 | static void db_err(const char *zFormat, ...){ |
| 59 | 67 | va_list ap; |
| 60 | 68 | char *z; |
| 69 | + int rc = 1; | |
| 61 | 70 | static const char zRebuildMsg[] = |
| 62 | 71 | "If you have recently updated your fossil executable, you might\n" |
| 63 | 72 | "need to run \"fossil all rebuild\" to bring the repository\n" |
| 64 | 73 | "schemas up to date.\n"; |
| 65 | 74 | va_start(ap, zFormat); |
| 66 | 75 | z = vmprintf(zFormat, ap); |
| 67 | 76 | va_end(ap); |
| 77 | +#ifdef FOSSIL_ENABLE_JSON | |
| 78 | + if( g.json.isJsonMode ){ | |
| 79 | + json_err( 0, z, 1 ); | |
| 80 | + if( g.isHTTP ){ | |
| 81 | + rc = 0 /* avoid HTTP 500 */; | |
| 82 | + } | |
| 83 | + } | |
| 84 | + else | |
| 85 | +#endif /* FOSSIL_ENABLE_JSON */ | |
| 68 | 86 | if( g.xferPanic ){ |
| 69 | 87 | cgi_reset_content(); |
| 70 | 88 | @ error Database\serror:\s%F(z) |
| 71 | - cgi_reply(); | |
| 89 | + cgi_reply(); | |
| 72 | 90 | } |
| 73 | - if( g.cgiOutput ){ | |
| 91 | + else if( g.cgiOutput ){ | |
| 74 | 92 | g.cgiOutput = 0; |
| 75 | 93 | cgi_printf("<h1>Database Error</h1>\n" |
| 76 | 94 | "<pre>%h</pre><p>%s</p>", z, zRebuildMsg); |
| 77 | 95 | cgi_reply(); |
| 78 | 96 | }else{ |
| 79 | 97 | fprintf(stderr, "%s: %s\n\n%s", fossil_nameofexe(), z, zRebuildMsg); |
| 80 | 98 | } |
| 99 | + free(z); | |
| 81 | 100 | db_force_rollback(); |
| 82 | - fossil_exit(1); | |
| 101 | + fossil_exit(rc); | |
| 83 | 102 | } |
| 84 | 103 | |
| 85 | 104 | static int nBegin = 0; /* Nesting depth of BEGIN */ |
| 86 | 105 | static int doRollback = 0; /* True to force a rollback */ |
| 87 | 106 | static int nCommitHook = 0; /* Number of commit hooks */ |
| @@ -561,11 +580,11 @@ | ||
| 561 | 580 | ** Execute a query. Return the first column of the first row |
| 562 | 581 | ** of the result set as a string. Space to hold the string is |
| 563 | 582 | ** obtained from malloc(). If the result set is empty, return |
| 564 | 583 | ** zDefault instead. |
| 565 | 584 | */ |
| 566 | -char *db_text(char *zDefault, const char *zSql, ...){ | |
| 585 | +char *db_text(char const *zDefault, const char *zSql, ...){ | |
| 567 | 586 | va_list ap; |
| 568 | 587 | Stmt s; |
| 569 | 588 | char *z; |
| 570 | 589 | va_start(ap, zSql); |
| 571 | 590 | db_vprepare(&s, 0, zSql, ap); |
| @@ -863,15 +882,24 @@ | ||
| 863 | 882 | db_err("unable to find the name of a repository database"); |
| 864 | 883 | } |
| 865 | 884 | } |
| 866 | 885 | if( file_access(zDbName, R_OK) || file_size(zDbName)<1024 ){ |
| 867 | 886 | if( file_access(zDbName, 0) ){ |
| 887 | +#ifdef FOSSIL_ENABLE_JSON | |
| 888 | + g.json.resultCode = FSL_JSON_E_DB_NOT_FOUND; | |
| 889 | +#endif | |
| 868 | 890 | fossil_panic("repository does not exist or" |
| 869 | 891 | " is in an unreadable directory: %s", zDbName); |
| 870 | 892 | }else if( file_access(zDbName, R_OK) ){ |
| 893 | +#ifdef FOSSIL_ENABLE_JSON | |
| 894 | + g.json.resultCode = FSL_JSON_E_DENIED; | |
| 895 | +#endif | |
| 871 | 896 | fossil_panic("read permission denied for repository %s", zDbName); |
| 872 | 897 | }else{ |
| 898 | +#ifdef FOSSIL_ENABLE_JSON | |
| 899 | + g.json.resultCode = FSL_JSON_E_DB_NOT_VALID; | |
| 900 | +#endif | |
| 873 | 901 | fossil_panic("not a valid repository: %s", zDbName); |
| 874 | 902 | } |
| 875 | 903 | } |
| 876 | 904 | db_open_or_attach(zDbName, "repository"); |
| 877 | 905 | g.repositoryOpen = 1; |
| @@ -902,11 +930,11 @@ | ||
| 902 | 930 | } |
| 903 | 931 | if( zRep==0 ){ |
| 904 | 932 | if( db_open_local()==0 ){ |
| 905 | 933 | goto rep_not_found; |
| 906 | 934 | } |
| 907 | - zRep = db_lget("repository", 0); | |
| 935 | + zRep = db_lget("repository", 0)/*leak here*/; | |
| 908 | 936 | if( zRep==0 ){ |
| 909 | 937 | goto rep_not_found; |
| 910 | 938 | } |
| 911 | 939 | } |
| 912 | 940 | db_open_repository(zRep); |
| @@ -914,10 +942,13 @@ | ||
| 914 | 942 | if( (bFlags & OPEN_ANY_SCHEMA)==0 ) db_verify_schema(); |
| 915 | 943 | return; |
| 916 | 944 | } |
| 917 | 945 | rep_not_found: |
| 918 | 946 | if( (bFlags & OPEN_OK_NOT_FOUND)==0 ){ |
| 947 | +#ifdef FOSSIL_ENABLE_JSON | |
| 948 | + g.json.resultCode = FSL_JSON_E_DB_NOT_FOUND; | |
| 949 | +#endif | |
| 919 | 950 | fossil_fatal("use --repository or -R to specify the repository database"); |
| 920 | 951 | } |
| 921 | 952 | } |
| 922 | 953 | |
| 923 | 954 | /* |
| @@ -944,10 +975,13 @@ | ||
| 944 | 975 | ** Verify that the repository schema is correct. If it is not correct, |
| 945 | 976 | ** issue a fatal error and die. |
| 946 | 977 | */ |
| 947 | 978 | void db_verify_schema(void){ |
| 948 | 979 | if( db_schema_is_outofdate() ){ |
| 980 | +#ifdef FOSSIL_ENABLE_JSON | |
| 981 | + g.json.resultCode = FSL_JSON_E_DB_NEEDS_REBUILD; | |
| 982 | +#endif | |
| 949 | 983 | fossil_warning("incorrect repository schema version"); |
| 950 | 984 | fossil_warning("your repository has schema version \"%s\" " |
| 951 | 985 | "but this binary expects version \"%s\"", |
| 952 | 986 | db_get("aux-schema",0), AUX_SCHEMA); |
| 953 | 987 | fossil_fatal("run \"fossil rebuild\" to fix this problem"); |
| 954 | 988 | |
| 955 | 989 | ADDED src/json.c |
| 956 | 990 | ADDED src/json_artifact.c |
| 957 | 991 | ADDED src/json_branch.c |
| 958 | 992 | ADDED src/json_detail.h |
| 959 | 993 | ADDED src/json_diff.c |
| 960 | 994 | ADDED src/json_login.c |
| 961 | 995 | ADDED src/json_query.c |
| 962 | 996 | ADDED src/json_report.c |
| 963 | 997 | ADDED src/json_tag.c |
| 964 | 998 | ADDED src/json_timeline.c |
| 965 | 999 | ADDED src/json_user.c |
| 966 | 1000 | ADDED src/json_wiki.c |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -48,40 +48,59 @@ | |
| 48 | Blob sql; /* The SQL for this statement */ |
| 49 | sqlite3_stmt *pStmt; /* The results of sqlite3_prepare() */ |
| 50 | Stmt *pNext, *pPrev; /* List of all unfinalized statements */ |
| 51 | int nStep; /* Number of sqlite3_step() calls */ |
| 52 | }; |
| 53 | #endif /* INTERFACE */ |
| 54 | |
| 55 | /* |
| 56 | ** Call this routine when a database error occurs. |
| 57 | */ |
| 58 | static void db_err(const char *zFormat, ...){ |
| 59 | va_list ap; |
| 60 | char *z; |
| 61 | static const char zRebuildMsg[] = |
| 62 | "If you have recently updated your fossil executable, you might\n" |
| 63 | "need to run \"fossil all rebuild\" to bring the repository\n" |
| 64 | "schemas up to date.\n"; |
| 65 | va_start(ap, zFormat); |
| 66 | z = vmprintf(zFormat, ap); |
| 67 | va_end(ap); |
| 68 | if( g.xferPanic ){ |
| 69 | cgi_reset_content(); |
| 70 | @ error Database\serror:\s%F(z) |
| 71 | cgi_reply(); |
| 72 | } |
| 73 | if( g.cgiOutput ){ |
| 74 | g.cgiOutput = 0; |
| 75 | cgi_printf("<h1>Database Error</h1>\n" |
| 76 | "<pre>%h</pre><p>%s</p>", z, zRebuildMsg); |
| 77 | cgi_reply(); |
| 78 | }else{ |
| 79 | fprintf(stderr, "%s: %s\n\n%s", fossil_nameofexe(), z, zRebuildMsg); |
| 80 | } |
| 81 | db_force_rollback(); |
| 82 | fossil_exit(1); |
| 83 | } |
| 84 | |
| 85 | static int nBegin = 0; /* Nesting depth of BEGIN */ |
| 86 | static int doRollback = 0; /* True to force a rollback */ |
| 87 | static int nCommitHook = 0; /* Number of commit hooks */ |
| @@ -561,11 +580,11 @@ | |
| 561 | ** Execute a query. Return the first column of the first row |
| 562 | ** of the result set as a string. Space to hold the string is |
| 563 | ** obtained from malloc(). If the result set is empty, return |
| 564 | ** zDefault instead. |
| 565 | */ |
| 566 | char *db_text(char *zDefault, const char *zSql, ...){ |
| 567 | va_list ap; |
| 568 | Stmt s; |
| 569 | char *z; |
| 570 | va_start(ap, zSql); |
| 571 | db_vprepare(&s, 0, zSql, ap); |
| @@ -863,15 +882,24 @@ | |
| 863 | db_err("unable to find the name of a repository database"); |
| 864 | } |
| 865 | } |
| 866 | if( file_access(zDbName, R_OK) || file_size(zDbName)<1024 ){ |
| 867 | if( file_access(zDbName, 0) ){ |
| 868 | fossil_panic("repository does not exist or" |
| 869 | " is in an unreadable directory: %s", zDbName); |
| 870 | }else if( file_access(zDbName, R_OK) ){ |
| 871 | fossil_panic("read permission denied for repository %s", zDbName); |
| 872 | }else{ |
| 873 | fossil_panic("not a valid repository: %s", zDbName); |
| 874 | } |
| 875 | } |
| 876 | db_open_or_attach(zDbName, "repository"); |
| 877 | g.repositoryOpen = 1; |
| @@ -902,11 +930,11 @@ | |
| 902 | } |
| 903 | if( zRep==0 ){ |
| 904 | if( db_open_local()==0 ){ |
| 905 | goto rep_not_found; |
| 906 | } |
| 907 | zRep = db_lget("repository", 0); |
| 908 | if( zRep==0 ){ |
| 909 | goto rep_not_found; |
| 910 | } |
| 911 | } |
| 912 | db_open_repository(zRep); |
| @@ -914,10 +942,13 @@ | |
| 914 | if( (bFlags & OPEN_ANY_SCHEMA)==0 ) db_verify_schema(); |
| 915 | return; |
| 916 | } |
| 917 | rep_not_found: |
| 918 | if( (bFlags & OPEN_OK_NOT_FOUND)==0 ){ |
| 919 | fossil_fatal("use --repository or -R to specify the repository database"); |
| 920 | } |
| 921 | } |
| 922 | |
| 923 | /* |
| @@ -944,10 +975,13 @@ | |
| 944 | ** Verify that the repository schema is correct. If it is not correct, |
| 945 | ** issue a fatal error and die. |
| 946 | */ |
| 947 | void db_verify_schema(void){ |
| 948 | if( db_schema_is_outofdate() ){ |
| 949 | fossil_warning("incorrect repository schema version"); |
| 950 | fossil_warning("your repository has schema version \"%s\" " |
| 951 | "but this binary expects version \"%s\"", |
| 952 | db_get("aux-schema",0), AUX_SCHEMA); |
| 953 | fossil_fatal("run \"fossil rebuild\" to fix this problem"); |
| 954 | |
| 955 | DDED src/json.c |
| 956 | DDED src/json_artifact.c |
| 957 | DDED src/json_branch.c |
| 958 | DDED src/json_detail.h |
| 959 | DDED src/json_diff.c |
| 960 | DDED src/json_login.c |
| 961 | DDED src/json_query.c |
| 962 | DDED src/json_report.c |
| 963 | DDED src/json_tag.c |
| 964 | DDED src/json_timeline.c |
| 965 | DDED src/json_user.c |
| 966 | DDED src/json_wiki.c |
| --- src/db.c | |
| +++ src/db.c | |
| @@ -48,40 +48,59 @@ | |
| 48 | Blob sql; /* The SQL for this statement */ |
| 49 | sqlite3_stmt *pStmt; /* The results of sqlite3_prepare() */ |
| 50 | Stmt *pNext, *pPrev; /* List of all unfinalized statements */ |
| 51 | int nStep; /* Number of sqlite3_step() calls */ |
| 52 | }; |
| 53 | |
| 54 | /* |
| 55 | ** Copy this to initialize a Stmt object to a clean/empty state. This |
| 56 | ** is useful to help avoid assertions when performing cleanup in some |
| 57 | ** error handling cases. |
| 58 | */ |
| 59 | #define empty_Stmt_m {BLOB_INITIALIZER,NULL, NULL, NULL, 0} |
| 60 | #endif /* INTERFACE */ |
| 61 | const struct Stmt empty_Stmt = empty_Stmt_m; |
| 62 | |
| 63 | /* |
| 64 | ** Call this routine when a database error occurs. |
| 65 | */ |
| 66 | static void db_err(const char *zFormat, ...){ |
| 67 | va_list ap; |
| 68 | char *z; |
| 69 | int rc = 1; |
| 70 | static const char zRebuildMsg[] = |
| 71 | "If you have recently updated your fossil executable, you might\n" |
| 72 | "need to run \"fossil all rebuild\" to bring the repository\n" |
| 73 | "schemas up to date.\n"; |
| 74 | va_start(ap, zFormat); |
| 75 | z = vmprintf(zFormat, ap); |
| 76 | va_end(ap); |
| 77 | #ifdef FOSSIL_ENABLE_JSON |
| 78 | if( g.json.isJsonMode ){ |
| 79 | json_err( 0, z, 1 ); |
| 80 | if( g.isHTTP ){ |
| 81 | rc = 0 /* avoid HTTP 500 */; |
| 82 | } |
| 83 | } |
| 84 | else |
| 85 | #endif /* FOSSIL_ENABLE_JSON */ |
| 86 | if( g.xferPanic ){ |
| 87 | cgi_reset_content(); |
| 88 | @ error Database\serror:\s%F(z) |
| 89 | cgi_reply(); |
| 90 | } |
| 91 | else if( g.cgiOutput ){ |
| 92 | g.cgiOutput = 0; |
| 93 | cgi_printf("<h1>Database Error</h1>\n" |
| 94 | "<pre>%h</pre><p>%s</p>", z, zRebuildMsg); |
| 95 | cgi_reply(); |
| 96 | }else{ |
| 97 | fprintf(stderr, "%s: %s\n\n%s", fossil_nameofexe(), z, zRebuildMsg); |
| 98 | } |
| 99 | free(z); |
| 100 | db_force_rollback(); |
| 101 | fossil_exit(rc); |
| 102 | } |
| 103 | |
| 104 | static int nBegin = 0; /* Nesting depth of BEGIN */ |
| 105 | static int doRollback = 0; /* True to force a rollback */ |
| 106 | static int nCommitHook = 0; /* Number of commit hooks */ |
| @@ -561,11 +580,11 @@ | |
| 580 | ** Execute a query. Return the first column of the first row |
| 581 | ** of the result set as a string. Space to hold the string is |
| 582 | ** obtained from malloc(). If the result set is empty, return |
| 583 | ** zDefault instead. |
| 584 | */ |
| 585 | char *db_text(char const *zDefault, const char *zSql, ...){ |
| 586 | va_list ap; |
| 587 | Stmt s; |
| 588 | char *z; |
| 589 | va_start(ap, zSql); |
| 590 | db_vprepare(&s, 0, zSql, ap); |
| @@ -863,15 +882,24 @@ | |
| 882 | db_err("unable to find the name of a repository database"); |
| 883 | } |
| 884 | } |
| 885 | if( file_access(zDbName, R_OK) || file_size(zDbName)<1024 ){ |
| 886 | if( file_access(zDbName, 0) ){ |
| 887 | #ifdef FOSSIL_ENABLE_JSON |
| 888 | g.json.resultCode = FSL_JSON_E_DB_NOT_FOUND; |
| 889 | #endif |
| 890 | fossil_panic("repository does not exist or" |
| 891 | " is in an unreadable directory: %s", zDbName); |
| 892 | }else if( file_access(zDbName, R_OK) ){ |
| 893 | #ifdef FOSSIL_ENABLE_JSON |
| 894 | g.json.resultCode = FSL_JSON_E_DENIED; |
| 895 | #endif |
| 896 | fossil_panic("read permission denied for repository %s", zDbName); |
| 897 | }else{ |
| 898 | #ifdef FOSSIL_ENABLE_JSON |
| 899 | g.json.resultCode = FSL_JSON_E_DB_NOT_VALID; |
| 900 | #endif |
| 901 | fossil_panic("not a valid repository: %s", zDbName); |
| 902 | } |
| 903 | } |
| 904 | db_open_or_attach(zDbName, "repository"); |
| 905 | g.repositoryOpen = 1; |
| @@ -902,11 +930,11 @@ | |
| 930 | } |
| 931 | if( zRep==0 ){ |
| 932 | if( db_open_local()==0 ){ |
| 933 | goto rep_not_found; |
| 934 | } |
| 935 | zRep = db_lget("repository", 0)/*leak here*/; |
| 936 | if( zRep==0 ){ |
| 937 | goto rep_not_found; |
| 938 | } |
| 939 | } |
| 940 | db_open_repository(zRep); |
| @@ -914,10 +942,13 @@ | |
| 942 | if( (bFlags & OPEN_ANY_SCHEMA)==0 ) db_verify_schema(); |
| 943 | return; |
| 944 | } |
| 945 | rep_not_found: |
| 946 | if( (bFlags & OPEN_OK_NOT_FOUND)==0 ){ |
| 947 | #ifdef FOSSIL_ENABLE_JSON |
| 948 | g.json.resultCode = FSL_JSON_E_DB_NOT_FOUND; |
| 949 | #endif |
| 950 | fossil_fatal("use --repository or -R to specify the repository database"); |
| 951 | } |
| 952 | } |
| 953 | |
| 954 | /* |
| @@ -944,10 +975,13 @@ | |
| 975 | ** Verify that the repository schema is correct. If it is not correct, |
| 976 | ** issue a fatal error and die. |
| 977 | */ |
| 978 | void db_verify_schema(void){ |
| 979 | if( db_schema_is_outofdate() ){ |
| 980 | #ifdef FOSSIL_ENABLE_JSON |
| 981 | g.json.resultCode = FSL_JSON_E_DB_NEEDS_REBUILD; |
| 982 | #endif |
| 983 | fossil_warning("incorrect repository schema version"); |
| 984 | fossil_warning("your repository has schema version \"%s\" " |
| 985 | "but this binary expects version \"%s\"", |
| 986 | db_get("aux-schema",0), AUX_SCHEMA); |
| 987 | fossil_fatal("run \"fossil rebuild\" to fix this problem"); |
| 988 | |
| 989 | DDED src/json.c |
| 990 | DDED src/json_artifact.c |
| 991 | DDED src/json_branch.c |
| 992 | DDED src/json_detail.h |
| 993 | DDED src/json_diff.c |
| 994 | DDED src/json_login.c |
| 995 | DDED src/json_query.c |
| 996 | DDED src/json_report.c |
| 997 | DDED src/json_tag.c |
| 998 | DDED src/json_timeline.c |
| 999 | DDED src/json_user.c |
| 1000 | DDED src/json_wiki.c |
+59
| --- a/src/json.c | ||
| +++ b/src/json.c | ||
| @@ -0,0 +1,59 @@ | ||
| 1 | + or succis to mFor notes regardinghas_timer(fetch} | |
| 2 | + if/* Timer code taken from sqlite3's shell.c, modified slightly. | |
| 3 | + FIXME: move the timer into the fossil core API so that we can | |
| 4 | + start the timer early on in the app init phase. Right now we're | |
| 5 | + just timing the json ops themselves. | |
| 6 | +*/ | |
| 7 | +#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(__RTP__) && !defined(_WRS_KERNEL) | |
| 8 | +#include <sys/time.h> | |
| 9 | +#include <sys/resource.h> | |
| 10 | + | |
| 11 | +/* Saved resourcthe beginning of an operation */ | |
| 12 | +static struct rusage sBegin; | |
| 13 | + | |
| 14 | +/* | |
| 15 | +** Begin timing an operationbeginTimer(void){ | |
| 16 | + getrusage(R USAGE_SELF, &sBegin); | |
| 17 | +} | |
| 18 | + | |
| 19 | +/* Return the difference of two time_structs in milliseconds */ | |
| 20 | +static double timeDiff(struct timeval *pStart, struct timeval *pEnd){ | |
| 21 | + return ((pEnd->tv_usec - pStart->tv_usec)*0.001 + | |
| 22 | + (double)((pEnd->tv_sec - pStart->tv_sec)*1000.0)); | |
| 23 | +} | |
| 24 | + | |
| 25 | +/* | |
| 26 | +** Print the timing results. | |
| 27 | +*/ | |
| 28 | +statiDiff(&sBegin.ru_utiu_stime, &sEnd.ru_stime)); | |
| 29 | +#endif | |
| 30 | + return timeDiff(&sBegin.ru_utime, &sEnd.ru_utimc double endTimer(void){ | |
| 31 | + struct rusage sEnd; | |
| 32 | + getrusage(RUSAGE_SELF, &sEnd); | |
| 33 | +#if 0 | |
| 34 | + printf("CPU Time: user %f sys %f\n", | |
| 35 | + timeDiff(&sBegincmr notes regardinghas_timer(fetch} | |
| 36 | + if/* Timer code taken from sqlite3's shell.c, modifinghas_timer(fetch} | |
| 37 | + if/* Timer!cmd || !*cmdcmroot);root); | |
| 38 | + } | |
| 39 | +0, 0);cm1> 0 /*HTTP1 payload /* | |
| 40 | +** Internal helpers to manipulate a byte array as a bitset. The B | |
| 41 | +** argument must be-a array at least (BIT/8+1) bytes long. | |
| 42 | +** The BIT argument is the bit number to query/set/clear/toggle. | |
| 43 | +*/ | |
| 44 | +#define BITSET_BYTEFOR(B,BIT) ((B)[ BIT / 8 ]) | |
| 45 | +#define BITSET_SET(B,BIT) ((BITSET_BYTEFOR(B,BIT) |= (0x01 << (BIT%8))),0x01) | |
| 46 | +#define BITSET_UNSET(B,BIT) ((BITSET_BYTEFOR(B,BIT) &= ~(0x01 << (BIT%8))),0x00) | |
| 47 | +#define BITSET_GET(B,BIT) ((BITSET_BYTEFOR(B,BIT) & (0x01 << (BIT%8))) ? 0x01 : 0x00) | |
| 48 | +#define BITSET_TOGGLE(B,BIT) (BITSET_GET(B,BIT) ? (BITSET_UNSET(B,BIT)) : (BITSET_SET(B,BIT)))*/*/ | |
| 49 | + | |
| 50 | +#undef BITSET_BYTEFOR | |
| 51 | +#undef BITSET_SET | |
| 52 | +#undef BITSET_UNSET | |
| 53 | +#undef BITS*/ | |
| 54 | +tmp =string(MANIFEST, else it | |
| 55 | +**char const *e json ops themselves. | |
| 56 | +*/ | |
| 57 | +#if !defined(_WIN32) && !defined(WIN32) & or s111/*FIXME: work in CLI mode*/ function | |
| 58 | +** returns | |
| 59 | +** |
| --- a/src/json.c | |
| +++ b/src/json.c | |
| @@ -0,0 +1,59 @@ | |
| --- a/src/json.c | |
| +++ b/src/json.c | |
| @@ -0,0 +1,59 @@ | |
| 1 | or succis to mFor notes regardinghas_timer(fetch} |
| 2 | if/* Timer code taken from sqlite3's shell.c, modified slightly. |
| 3 | FIXME: move the timer into the fossil core API so that we can |
| 4 | start the timer early on in the app init phase. Right now we're |
| 5 | just timing the json ops themselves. |
| 6 | */ |
| 7 | #if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(__RTP__) && !defined(_WRS_KERNEL) |
| 8 | #include <sys/time.h> |
| 9 | #include <sys/resource.h> |
| 10 | |
| 11 | /* Saved resourcthe beginning of an operation */ |
| 12 | static struct rusage sBegin; |
| 13 | |
| 14 | /* |
| 15 | ** Begin timing an operationbeginTimer(void){ |
| 16 | getrusage(R USAGE_SELF, &sBegin); |
| 17 | } |
| 18 | |
| 19 | /* Return the difference of two time_structs in milliseconds */ |
| 20 | static double timeDiff(struct timeval *pStart, struct timeval *pEnd){ |
| 21 | return ((pEnd->tv_usec - pStart->tv_usec)*0.001 + |
| 22 | (double)((pEnd->tv_sec - pStart->tv_sec)*1000.0)); |
| 23 | } |
| 24 | |
| 25 | /* |
| 26 | ** Print the timing results. |
| 27 | */ |
| 28 | statiDiff(&sBegin.ru_utiu_stime, &sEnd.ru_stime)); |
| 29 | #endif |
| 30 | return timeDiff(&sBegin.ru_utime, &sEnd.ru_utimc double endTimer(void){ |
| 31 | struct rusage sEnd; |
| 32 | getrusage(RUSAGE_SELF, &sEnd); |
| 33 | #if 0 |
| 34 | printf("CPU Time: user %f sys %f\n", |
| 35 | timeDiff(&sBegincmr notes regardinghas_timer(fetch} |
| 36 | if/* Timer code taken from sqlite3's shell.c, modifinghas_timer(fetch} |
| 37 | if/* Timer!cmd || !*cmdcmroot);root); |
| 38 | } |
| 39 | 0, 0);cm1> 0 /*HTTP1 payload /* |
| 40 | ** Internal helpers to manipulate a byte array as a bitset. The B |
| 41 | ** argument must be-a array at least (BIT/8+1) bytes long. |
| 42 | ** The BIT argument is the bit number to query/set/clear/toggle. |
| 43 | */ |
| 44 | #define BITSET_BYTEFOR(B,BIT) ((B)[ BIT / 8 ]) |
| 45 | #define BITSET_SET(B,BIT) ((BITSET_BYTEFOR(B,BIT) |= (0x01 << (BIT%8))),0x01) |
| 46 | #define BITSET_UNSET(B,BIT) ((BITSET_BYTEFOR(B,BIT) &= ~(0x01 << (BIT%8))),0x00) |
| 47 | #define BITSET_GET(B,BIT) ((BITSET_BYTEFOR(B,BIT) & (0x01 << (BIT%8))) ? 0x01 : 0x00) |
| 48 | #define BITSET_TOGGLE(B,BIT) (BITSET_GET(B,BIT) ? (BITSET_UNSET(B,BIT)) : (BITSET_SET(B,BIT)))*/*/ |
| 49 | |
| 50 | #undef BITSET_BYTEFOR |
| 51 | #undef BITSET_SET |
| 52 | #undef BITSET_UNSET |
| 53 | #undef BITS*/ |
| 54 | tmp =string(MANIFEST, else it |
| 55 | **char const *e json ops themselves. |
| 56 | */ |
| 57 | #if !defined(_WIN32) && !defined(WIN32) & or s111/*FIXME: work in CLI mode*/ function |
| 58 | ** returns |
| 59 | ** |
+4
| --- a/src/json_artifact.c | ||
| +++ b/src/json_artifact.c | ||
| @@ -0,0 +1,4 @@ | ||
| 1 | +(2 g.perm.His#if 0 | |
| 2 | + /*see next #if block below*/ | |
| 3 | + cson_string * tagKey = NULL; | |
| 4 | + cson_vaexten |
| --- a/src/json_artifact.c | |
| +++ b/src/json_artifact.c | |
| @@ -0,0 +1,4 @@ | |
| --- a/src/json_artifact.c | |
| +++ b/src/json_artifact.c | |
| @@ -0,0 +1,4 @@ | |
| 1 | (2 g.perm.His#if 0 |
| 2 | /*see next #if block below*/ |
| 3 | cson_string * tagKey = NULL; |
| 4 | cson_vaexten |
+11
| --- a/src/json_branch.c | ||
| +++ b/src/json_branch.c | ||
| @@ -0,0 +1,11 @@ | ||
| 1 | +#ifdef FOSSIL_ENABLE_JSON | |
| 2 | +/* | |
| 3 | +** Copyright (c) 2011 D. Richard Hipp | |
| 4 | +** | |
| 5 | +** This program is free software; you can redistribute it and/or | |
| 6 | +** modify it \nPLQwhich = 0which = -1which = 1which = 0whichxfer_run_common_script(panicpanic("%s\n==0unable to install new manifest"#ifdef FOSSIL_ENABLE_JSON | |
| 7 | +/* | |
| 8 | +** Copyright (c) 2011 D. Richard Hipp | |
| 9 | +** | |
| 10 | +** This program is free software; you can redistribute it and/or | |
| 11 | +** modify it \nPLQwhich = 0which = -1which = 1which = 0whichxfer_run_common_script(panicpanic("%s\n444AUTO3 |
| --- a/src/json_branch.c | |
| +++ b/src/json_branch.c | |
| @@ -0,0 +1,11 @@ | |
| --- a/src/json_branch.c | |
| +++ b/src/json_branch.c | |
| @@ -0,0 +1,11 @@ | |
| 1 | #ifdef FOSSIL_ENABLE_JSON |
| 2 | /* |
| 3 | ** Copyright (c) 2011 D. Richard Hipp |
| 4 | ** |
| 5 | ** This program is free software; you can redistribute it and/or |
| 6 | ** modify it \nPLQwhich = 0which = -1which = 1which = 0whichxfer_run_common_script(panicpanic("%s\n==0unable to install new manifest"#ifdef FOSSIL_ENABLE_JSON |
| 7 | /* |
| 8 | ** Copyright (c) 2011 D. Richard Hipp |
| 9 | ** |
| 10 | ** This program is free software; you can redistribute it and/or |
| 11 | ** modify it \nPLQwhich = 0which = -1which = 1which = 0whichxfer_run_common_script(panicpanic("%s\n444AUTO3 |
+69
| --- a/src/json_detail.h | ||
| +++ b/src/json_detail.h | ||
| @@ -0,0 +1,69 @@ | ||
| 1 | +#ifdef FOSSIL_ENABLE_JSON | |
| 2 | +#if !defined(FOSSIL_JSON_DETAIL_H_INCLUDED) | |
| 3 | +#define FOSSIL_JSON_DETAIL_(c)ifdef FOSSIL_ENABLE_JSON | |
| 4 | +#if !defined(FOSSIL_JSON_DETAIL_H_INCLUDED) | |
| 5 | +#define FOSSIL_JSON_DETAIL_H_INCLUDED | |
| 6 | +/* | |
| 7 | +** Copyright (c) 2011 D. Richard Hipp | |
| 8 | +** | |
| 9 | +** This program is free software; you can redistribute it and/or | |
| 10 | +** modify it under the terms of the Simplified BSD License (also | |
| 11 | +** known as the "2-Clause License" or "FreeBSD License".) | |
| 12 | +** | |
| 13 | +** This program is distributed in the hope that it will be useful, | |
| 14 | +** but without any warranty; without even the implied warranty of | |
| 15 | +** merchantability or fitness for a particular purpose. | |
| 16 | +** | |
| 17 | +** Author contact in | |
| 18 | +#define FOSSIL_JSON_API_VERSION "20120713" | |
| 19 | + | |
| 20 | +/* | |
| 21 | +** Impl details for the JSON API which need to be shared | |
| 22 | +** across multiple C files. | |
| 23 | +*/ | |
| 24 | + | |
| 25 | +/* | |
| 26 | +** The "official" list of Fossil/JSON error codes. Their values might | |
| 27 | +** very well change during initial development but after their first | |
| 28 | +** public release they must stay stable. | |
| 29 | +** | |
| 30 | +** Values must be in the range 1000..9999 for error codes and 1..999 | |
| 31 | +** for warning codes. | |
| 32 | +** | |
| 33 | +** Numbers evenly dividable by 100 are "categories", and error codes | |
| 34 | +** for a given | |
| 35 | +um FossilJsonCodes , | |
| 36 | +FSL_JSON_W_STRING_TO_ARRAY_FAILED /*+4*/, | |
| 37 | +FSL_JSON_W_TAG_NOT_FOUND /*+5*/, | |
| 38 | + | |
| 39 | +FSL_JSON_W_END = 1000, | |
| 40 | +FSL_JSON_E_GENERIC = 1000, | |
| 41 | +FSL_JSON_E_GENERIC_SUB1 = FSL_JSON_E_GENERIC + 10#ifdef FOSSIL_ENABLE_JSON | |
| 42 | +#if !defined(FOSSIL_JSON_DETAIL_H_INCLUDED) | |
| 43 | +#define FOSSIL_JSON_DETAIL_H_INCLUDED | |
| 44 | +/* | |
| 45 | +** Copyright (c) 2011 D. Richard Hipp | |
| 46 | +** | |
| 47 | +** This program is free software; you can redistribute it and/or | |
| 48 | +** modify it under the terms of the Simplified BSD License (also | |
| 49 | +** known as the "2-Clause License" or "FreeBSD License".) | |
| 50 | +** | |
| 51 | +** This program is distributed in the hope that it will be useful, | |
| 52 | +** but without any warranty; without even the implied warranty of | |
| 53 | +** merchantability or fitness for a particular purpose. | |
| 54 | +** | |
| 55 | +** Author contact information: | |
| 56 | +** [email protected] | |
| 57 | +** http://wnclude "cson_amalgamation.h" | |
| 58 | + | |
| 59 | +/** | |
| 60 | + FOSSIL_JSON_API_VERSION holds the date (YYYYMMDD) of the latest | |
| 61 | + "significant" change to the JSON API (a change in an interface or | |
| 62 | + new funcierer then | |
| 63 | +#endif/*FOSSIL_JSON_DETAIL_(c)ifdef FImplements the /json/wiki fwiki(); | |
| 64 | + | |
| 65 | +/* | |
| 66 | +** Implements /json/timeline/wiki and /json/wiki/timelinetimeline_wiki(); | |
| 67 | + | |
| 68 | +/* | |
| 69 | +** Implements /json/timeline family of functionstimeline( |
| --- a/src/json_detail.h | |
| +++ b/src/json_detail.h | |
| @@ -0,0 +1,69 @@ | |
| --- a/src/json_detail.h | |
| +++ b/src/json_detail.h | |
| @@ -0,0 +1,69 @@ | |
| 1 | #ifdef FOSSIL_ENABLE_JSON |
| 2 | #if !defined(FOSSIL_JSON_DETAIL_H_INCLUDED) |
| 3 | #define FOSSIL_JSON_DETAIL_(c)ifdef FOSSIL_ENABLE_JSON |
| 4 | #if !defined(FOSSIL_JSON_DETAIL_H_INCLUDED) |
| 5 | #define FOSSIL_JSON_DETAIL_H_INCLUDED |
| 6 | /* |
| 7 | ** Copyright (c) 2011 D. Richard Hipp |
| 8 | ** |
| 9 | ** This program is free software; you can redistribute it and/or |
| 10 | ** modify it under the terms of the Simplified BSD License (also |
| 11 | ** known as the "2-Clause License" or "FreeBSD License".) |
| 12 | ** |
| 13 | ** This program is distributed in the hope that it will be useful, |
| 14 | ** but without any warranty; without even the implied warranty of |
| 15 | ** merchantability or fitness for a particular purpose. |
| 16 | ** |
| 17 | ** Author contact in |
| 18 | #define FOSSIL_JSON_API_VERSION "20120713" |
| 19 | |
| 20 | /* |
| 21 | ** Impl details for the JSON API which need to be shared |
| 22 | ** across multiple C files. |
| 23 | */ |
| 24 | |
| 25 | /* |
| 26 | ** The "official" list of Fossil/JSON error codes. Their values might |
| 27 | ** very well change during initial development but after their first |
| 28 | ** public release they must stay stable. |
| 29 | ** |
| 30 | ** Values must be in the range 1000..9999 for error codes and 1..999 |
| 31 | ** for warning codes. |
| 32 | ** |
| 33 | ** Numbers evenly dividable by 100 are "categories", and error codes |
| 34 | ** for a given |
| 35 | um FossilJsonCodes , |
| 36 | FSL_JSON_W_STRING_TO_ARRAY_FAILED /*+4*/, |
| 37 | FSL_JSON_W_TAG_NOT_FOUND /*+5*/, |
| 38 | |
| 39 | FSL_JSON_W_END = 1000, |
| 40 | FSL_JSON_E_GENERIC = 1000, |
| 41 | FSL_JSON_E_GENERIC_SUB1 = FSL_JSON_E_GENERIC + 10#ifdef FOSSIL_ENABLE_JSON |
| 42 | #if !defined(FOSSIL_JSON_DETAIL_H_INCLUDED) |
| 43 | #define FOSSIL_JSON_DETAIL_H_INCLUDED |
| 44 | /* |
| 45 | ** Copyright (c) 2011 D. Richard Hipp |
| 46 | ** |
| 47 | ** This program is free software; you can redistribute it and/or |
| 48 | ** modify it under the terms of the Simplified BSD License (also |
| 49 | ** known as the "2-Clause License" or "FreeBSD License".) |
| 50 | ** |
| 51 | ** This program is distributed in the hope that it will be useful, |
| 52 | ** but without any warranty; without even the implied warranty of |
| 53 | ** merchantability or fitness for a particular purpose. |
| 54 | ** |
| 55 | ** Author contact information: |
| 56 | ** [email protected] |
| 57 | ** http://wnclude "cson_amalgamation.h" |
| 58 | |
| 59 | /** |
| 60 | FOSSIL_JSON_API_VERSION holds the date (YYYYMMDD) of the latest |
| 61 | "significant" change to the JSON API (a change in an interface or |
| 62 | new funcierer then |
| 63 | #endif/*FOSSIL_JSON_DETAIL_(c)ifdef FImplements the /json/wiki fwiki(); |
| 64 | |
| 65 | /* |
| 66 | ** Implements /json/timeline/wiki and /json/wiki/timelinetimeline_wiki(); |
| 67 | |
| 68 | /* |
| 69 | ** Implements /json/timeline family of functionstimeline( |
+27
| --- a/src/json_diff.c | ||
| +++ b/src/json_diff.c | ||
| @@ -0,0 +1,27 @@ | ||
| 1 | +; | |
| 2 | + DiffConfig (c)g; | |
| 3 | + Blob from = empty_blob, to = empty_blob, out = empty_blob; | |
| 4 | + cson_value * rc = NULL; | |
| 5 | + int flags = (fSbsDIFF_CONTEXT_MASK & nContext) | |
| 6 | + |bs ? DIFF_SIDEBYSIDE : 0) | |
| 7 | + | (fHtml ? DIFF_HTML : 0); | |
| 8 | + fromid = name_to_typed_rid(zFrom, "*"); | |
| 9 | + if(fromid<=0){ | |
| 10 | + json_set_err(FSL_JSON_E_UNRESOLVED_UUID, | |
| 11 | + "Could not resolve 'from' ID."); | |
| 12 | + return NULL; | |
| 13 | + } | |
| 14 | + toid = name_to_typed_rid(zTo, "*"); | |
| 15 | + if(toid<=0){ | |
| 16 | + json_set_err(FSL_JSON_E_UNRESOLVED_UUID, | |
| 17 | + "Could not resolve 'to' ID."); | |
| 18 | + return NULL; | |
| 19 | + } | |
| 20 | + content_get(fromid, &from_diff(&from, &to, &out, &DCf0, flags&from, &to, &out, &DCfg); | |
| 21 | + blob_reset(&from); | |
| 22 | + blob_reset(&to); | |
| 23 | + outLen = blob_size(&out); | |
| 24 | + if(outLen>=0){ | |
| 25 | + rc = cson_value_new_string(blob_buffer(&out), | |
| 26 | + flags, | |
| 27 | + flagsv = char const * zType = "ci" |
| --- a/src/json_diff.c | |
| +++ b/src/json_diff.c | |
| @@ -0,0 +1,27 @@ | |
| --- a/src/json_diff.c | |
| +++ b/src/json_diff.c | |
| @@ -0,0 +1,27 @@ | |
| 1 | ; |
| 2 | DiffConfig (c)g; |
| 3 | Blob from = empty_blob, to = empty_blob, out = empty_blob; |
| 4 | cson_value * rc = NULL; |
| 5 | int flags = (fSbsDIFF_CONTEXT_MASK & nContext) |
| 6 | |bs ? DIFF_SIDEBYSIDE : 0) |
| 7 | | (fHtml ? DIFF_HTML : 0); |
| 8 | fromid = name_to_typed_rid(zFrom, "*"); |
| 9 | if(fromid<=0){ |
| 10 | json_set_err(FSL_JSON_E_UNRESOLVED_UUID, |
| 11 | "Could not resolve 'from' ID."); |
| 12 | return NULL; |
| 13 | } |
| 14 | toid = name_to_typed_rid(zTo, "*"); |
| 15 | if(toid<=0){ |
| 16 | json_set_err(FSL_JSON_E_UNRESOLVED_UUID, |
| 17 | "Could not resolve 'to' ID."); |
| 18 | return NULL; |
| 19 | } |
| 20 | content_get(fromid, &from_diff(&from, &to, &out, &DCf0, flags&from, &to, &out, &DCfg); |
| 21 | blob_reset(&from); |
| 22 | blob_reset(&to); |
| 23 | outLen = blob_size(&out); |
| 24 | if(outLen>=0){ |
| 25 | rc = cson_value_new_string(blob_buffer(&out), |
| 26 | flags, |
| 27 | flagsv = char const * zType = "ci" |
+41
| --- a/src/json_login.c | ||
| +++ b/src/json_login.c | ||
| @@ -0,0 +1,41 @@ | ||
| 1 | +); | |
| 2 | + } | |
| 3 | + payloadjson_new_string(cap)son_object_set(po, "authToken"ookie is | |
| 4 | + set because anon does not get a db entry like normal users | |
| 5 | + do. Anonymous cookies currently have a hard-coded lifetime in | |
| 6 | + login_set_anon_cookie() (currently 6 hours), which we "should | |
| 7 | + arguably" change to use the time configured for non-anonymous | |
| 8 | + users (see login_set_user_cookie() for details). | |
| 9 | + *NULL, / | |
| 10 | + rrn payload; | |
| 11 | + } | |
| 12 | +} | |
| 13 | + | |
| 14 | +/* | |
| 15 | +** Impl of ); | |
| 16 | + }p"p"/"pasted by this. | |
| 17 | + */ | |
| 18 | + cprintf(th forms work. The | |
| 19 | + "p"/"pasted by this. | |
| 20 | + */ | |
| 21 | + char const * name = cson_value_get_cstr(json_req_payload_get("name")); | |
| 22 | + char const * pw = NULL; | |
| 23 | + char const * anonSeed = NULL; | |
| 24 | + cson_value * payload = NULL; | |
| 25 | + int uid = 0; | |
| 26 | + /* reminder to self: Fossil internally (for the sake of /wiki) | |
| 27 | + interprets paths in the form /foo/bar/baz such that P("name") == | |
| 28 | + "bar/baz". T AILED_NOSEED | |
| 29 | + d | |
| 30 | + thus we do some rather elaborate name=... checking. | |
| 31 | + */ | |
| 32 | + pw = cson_value_get_cstr(json_req_payload_get("password")); | |
| 33 | + if( !pw ){ | |
| 34 | + pw = PD("p",NULL); | |
| 35 | + if( !pw ){ | |
| 36 | + pw = PD("pass | |
| 37 | + interprets | |
| 38 | + | |
| 39 | + P("name") == | |
| 40 | + name/password checking, and thus we check for the | |
| 41 | + password first |
| --- a/src/json_login.c | |
| +++ b/src/json_login.c | |
| @@ -0,0 +1,41 @@ | |
| --- a/src/json_login.c | |
| +++ b/src/json_login.c | |
| @@ -0,0 +1,41 @@ | |
| 1 | ); |
| 2 | } |
| 3 | payloadjson_new_string(cap)son_object_set(po, "authToken"ookie is |
| 4 | set because anon does not get a db entry like normal users |
| 5 | do. Anonymous cookies currently have a hard-coded lifetime in |
| 6 | login_set_anon_cookie() (currently 6 hours), which we "should |
| 7 | arguably" change to use the time configured for non-anonymous |
| 8 | users (see login_set_user_cookie() for details). |
| 9 | *NULL, / |
| 10 | rrn payload; |
| 11 | } |
| 12 | } |
| 13 | |
| 14 | /* |
| 15 | ** Impl of ); |
| 16 | }p"p"/"pasted by this. |
| 17 | */ |
| 18 | cprintf(th forms work. The |
| 19 | "p"/"pasted by this. |
| 20 | */ |
| 21 | char const * name = cson_value_get_cstr(json_req_payload_get("name")); |
| 22 | char const * pw = NULL; |
| 23 | char const * anonSeed = NULL; |
| 24 | cson_value * payload = NULL; |
| 25 | int uid = 0; |
| 26 | /* reminder to self: Fossil internally (for the sake of /wiki) |
| 27 | interprets paths in the form /foo/bar/baz such that P("name") == |
| 28 | "bar/baz". T AILED_NOSEED |
| 29 | d |
| 30 | thus we do some rather elaborate name=... checking. |
| 31 | */ |
| 32 | pw = cson_value_get_cstr(json_req_payload_get("password")); |
| 33 | if( !pw ){ |
| 34 | pw = PD("p",NULL); |
| 35 | if( !pw ){ |
| 36 | pw = PD("pass |
| 37 | interprets |
| 38 | |
| 39 | P("name") == |
| 40 | name/password checking, and thus we check for the |
| 41 | password first |
+31
| --- a/src/json_query.c | ||
| +++ b/src/json_query.c | ||
| @@ -0,0 +1,31 @@ | ||
| 1 | +#ifdef FOSSIL_E(c)LE_JSON | |
| 2 | +/* | |
| 3 | +** Copyright (c) 2011 D. Richard Hipp | |
| 4 | +** | |
| 5 | +** This program is free software; you can redistribute it and/or | |
| 6 | +** modify it under the terms of the Simplified BSD License (also | |
| 7 | +** known as the "2-Clause License" or "FreeBSD License".) | |
| 8 | +** | |
| 9 | +** This program is distributed in the hope that it will be useful, | |
| 10 | +** but without any warranty; without even the implied warranty of | |
| 11 | +** merchantability or fitness for a particular purpose. | |
| 12 | +** | |
| 13 | +** Author contact information: | |
| 14 | +** [email protected] | |
| 15 | +** http://www.hwaci.com/drh/ | |
| 16 | +** | |
| 17 | +*/ | |
| 18 | + | |
| 19 | +#include "config.h" | |
| 20 | +#include "json_query.h" | |
| 21 | + | |
| 22 | +#if INTERFACE | |
| 23 | +#include "json_detail.h" | |
| 24 | +#endif | |
| 25 | + | |
| 26 | + | |
| 27 | +/* | |
| 28 | +** Implementation of the /json/query page. | |
| 29 | +** | |
| 30 | +** Requires admin privileges. Intended primarily to assist me in | |
| 31 | +** coming up with JSON output str4433 |
| --- a/src/json_query.c | |
| +++ b/src/json_query.c | |
| @@ -0,0 +1,31 @@ | |
| --- a/src/json_query.c | |
| +++ b/src/json_query.c | |
| @@ -0,0 +1,31 @@ | |
| 1 | #ifdef FOSSIL_E(c)LE_JSON |
| 2 | /* |
| 3 | ** Copyright (c) 2011 D. Richard Hipp |
| 4 | ** |
| 5 | ** This program is free software; you can redistribute it and/or |
| 6 | ** modify it under the terms of the Simplified BSD License (also |
| 7 | ** known as the "2-Clause License" or "FreeBSD License".) |
| 8 | ** |
| 9 | ** This program is distributed in the hope that it will be useful, |
| 10 | ** but without any warranty; without even the implied warranty of |
| 11 | ** merchantability or fitness for a particular purpose. |
| 12 | ** |
| 13 | ** Author contact information: |
| 14 | ** [email protected] |
| 15 | ** http://www.hwaci.com/drh/ |
| 16 | ** |
| 17 | */ |
| 18 | |
| 19 | #include "config.h" |
| 20 | #include "json_query.h" |
| 21 | |
| 22 | #if INTERFACE |
| 23 | #include "json_detail.h" |
| 24 | #endif |
| 25 | |
| 26 | |
| 27 | /* |
| 28 | ** Implementation of the /json/query page. |
| 29 | ** |
| 30 | ** Requires admin privileges. Intended primarily to assist me in |
| 31 | ** coming up with JSON output str4433 |
+1
| --- a/src/json_report.c | ||
| +++ b/src/json_report.c | ||
| @@ -0,0 +1 @@ | ||
| 1 | +3333mtime, |
| --- a/src/json_report.c | |
| +++ b/src/json_report.c | |
| @@ -0,0 +1 @@ | |
| --- a/src/json_report.c | |
| +++ b/src/json_report.c | |
| @@ -0,0 +1 @@ | |
| 1 | 3333mtime, |
+1
| --- a/src/json_tag.c | ||
| +++ b/src/json_tag.c | ||
| @@ -0,0 +1 @@ | ||
| 1 | +int constmtime |
| --- a/src/json_tag.c | |
| +++ b/src/json_tag.c | |
| @@ -0,0 +1 @@ | |
| --- a/src/json_tag.c | |
| +++ b/src/json_tag.c | |
| @@ -0,0 +1 @@ | |
| 1 | int constmtime |
+20
| --- a/src/json_timeline.c | ||
| +++ b/src/json_timeline.c | ||
| @@ -0,0 +1,20 @@ | ||
| 1 | + * CopzSqlcson_( * CopzSqlcson_(c) json_timeli);yV); | |
| 2 | +r check = ); | |
| 3 | +/* | |
| 4 | +** Mapping of /json/timeline/XXX commands/paths to callbacks. | |
| 5 | +*/ | |
| 6 | +static con forms are only enabled in CLI mode, to avoid | |
| 7 | + that we end up with HTTP clients using 3 different names | |
| 8 | + for the same requests. | |
| 9 | +*/ | |
| 10 | +{"branch", json_timeline_branch, 0}, | |
| 11 | +{"checkin", json_timelinecci, -1}, | |
| 12 | +{"tticket, -1}, | |
| 13 | +{"ticketticket, 0}, | |
| 14 | +{"w-1Read ){ | |
| 15 | + /* IMO this falls more under the category of g.perm.History, but | |
| 16 | + i'm following timpl hereo) json_timeli | |
| 17 | + goto end; | |
| 18 | +); | |
| 19 | + | |
| 20 | + end:char warnStringToArray |
| --- a/src/json_timeline.c | |
| +++ b/src/json_timeline.c | |
| @@ -0,0 +1,20 @@ | |
| --- a/src/json_timeline.c | |
| +++ b/src/json_timeline.c | |
| @@ -0,0 +1,20 @@ | |
| 1 | * CopzSqlcson_( * CopzSqlcson_(c) json_timeli);yV); |
| 2 | r check = ); |
| 3 | /* |
| 4 | ** Mapping of /json/timeline/XXX commands/paths to callbacks. |
| 5 | */ |
| 6 | static con forms are only enabled in CLI mode, to avoid |
| 7 | that we end up with HTTP clients using 3 different names |
| 8 | for the same requests. |
| 9 | */ |
| 10 | {"branch", json_timeline_branch, 0}, |
| 11 | {"checkin", json_timelinecci, -1}, |
| 12 | {"tticket, -1}, |
| 13 | {"ticketticket, 0}, |
| 14 | {"w-1Read ){ |
| 15 | /* IMO this falls more under the category of g.perm.History, but |
| 16 | i'm following timpl hereo) json_timeli |
| 17 | goto end; |
| 18 | ); |
| 19 | |
| 20 | end:char warnStringToArray |
+125
| --- a/src/json_user.c | ||
| +++ b/src/json_user.c | ||
| @@ -0,0 +1,125 @@ | ||
| 1 | + !g.perm.Setup)(c) json_set_err(FSL_JSON_E_DENIED, | |
| 2 | + "Requires 'a' or son_find_option_cstr2("namto json_load_user_by_name(), but expects a user ID. Returns | |
| 3 | +** NULL if noL if no user founson_value * tmpVcommand_arg( g.isHTTP && (!pUser || !*pUser) ){ | |
| 4 | + pUser = json_getenv_cstr("name") | |
| 5 | + /* ACHTUNG: fossil apparently internally sets name=user/get/XYZ | |
| 6 | +if we pass the name as part of the path, which is why we check | |
| 7 | + with json_command_path() before trying to get("name"). | |
| 8 | + */; | |
| 9 | + }) st(LK,NULL,NULL); password"); | |
| 10 | + PROP("in#if 0create(); | |
| 11 | + | |
| 12 | +#endifcreate", json_page_nyi, 0},e_find_option_cstr2("_find_option_cstr2(" !g.perm.Setup)(c) jsos 'a' or son_find_option_cstr2("namto json_load_user_by_name(), but expec !g.perm.Setup)(c) !g.perm.Setup)(c) ge with json_command_path(ge. | |
| 13 | + */; | |
| 14 | + }) st(LK,NULL,NULL); ption_cstr2("namto json_load_user_by_name(), but expec !g.perm.Setup)(c) !g.perm.Setup)(c) _find_option_cstr2(" !g.perm.Setup)(c) json_set_}_find_option_cstr2("){_find_option_cstr2("namto json_load_user_by_name(), but expects a !g.perm.Setup)(c) json_set_err(FSL_JSON_E_DENIED, | |
| 15 | + } char * zPWHash = NULL++gotFields !g.perm.Setup)(c) json_set_err(FSL_JSON_E_DENIED, | |
| 16 | + "Requires 'a' or son_find_option_cstr2("namto json_load_user_by_name(), but expects a user ID. Returns | |
| 17 | +** NULL if noL if no user founson_value * tmpVcommand_arg( g.isHTTP && (!pUser || !*pUser) ){ | |
| 18 | + pUser = json_getenv_cstr("name") | |
| 19 | + /* ACHTUNG: fossil apparently internally sets name=user/get/XYZ | |
| 20 | +if we pass the name as part of the path, which is why we check | |
| 21 | + with json_command_path() before trying to get("name"). | |
| 22 | + */; | |
| 23 | + }) st(LK,NULL,NULL); password"); | |
| 24 | + PROP("in#if 0create(); | |
| 25 | + | |
| 26 | +#endifcreate", json_page_nyi, 0},e_find_option_cstr2("_find_option_cstr2(" !g.perm.Setup)(c) jsos ge with json_command_path(ge. | |
| 27 | + */; | |
| 28 | + }) st(LK,NULL,NULL); ption_cstr2("namto json_load_user_by_name(), but expec !g.perm.Setup)(c) turns | |
| 29 | +** NULL if noL if no user f user founson_value * tmACHTUNG: fossil apparentloption_cstr2("namto json_load_user_by_name(), but expects a !g.perm.Setup)(c) json_set_err(FSL_JSON_E_DENIED, | |
| 30 | + } char * zPWHash = NULL++gotFields !g.perm.Setup)(c) json_set_err(FSL_JSON_E_DENIED, | |
| 31 | + "Requires 'a' or son_find_option_cstr2("namto json_load_user_by_name(), but expects a user ID. Returns | |
| 32 | +** NULL if noL if no user founson_value * tmpVcommand_arg( g.isHTTP && (!pUser || !*pUser) ){ | |
| 33 | + pUser = json_getenv_cstr("name") | |
| 34 | + /* ACHTUNG: fossil apparently internally sets ){ | |
| 35 | + pUser = json_getenv_cstr("name") | |
| 36 | + !&& zNameNew && (zName != zNameNew) | |
| 37 | + && (0!=strcmp(zNameNew,zName))){ | |
| 38 | + _err(FSL_JSON_E_D login=%Q", zNameNew){name");g.perm.Setup)(c) json_set_ | |
| 39 | +** | |
| 40 | +** TODpUserperm.Setup)(c) payV_by_name(), but if(!payV){ | |
| 41 | + er | |
| 42 | + which thFSL_JSON_E_UNKNOWN,"Could not_option_cstr2(" !g.per user founson_value * tmpVcommanderm.Setup)(c) ge w get("name"). | |
| 43 | + */; | |
| 44 | + }) st(LK,NULL,NULL); password"); | |
| 45 | + PROP("in#if 0create(); | |
| 46 | + | |
| 47 | +#endifcreate", json_page_nyi, 0},e_find_option_cstr2("_find_option_cstr2(" !g.perm.Setup)(c) jsos 'a' or son_find_option_cstr2("namto json_load_user_by_name(), but expec !g.perm.Setup)(c) !g.perm.Setup)(c) _find_option_cstr2(" !g.perm.Setup)(c) t expects a user ID. Returns | |
| 48 | +** NULL if noL if no user founson_value * tmpVcommand_arg( g.isHTTP && (!pUser || !*pUser) ){ | |
| 49 | + pUser = json_getenv_cstr("name") | |
| 50 | + !&& zNameNew && (zName != zNameNew) | |
| 51 | + && (0!=strcmp(zNameNew,zName))){ | |
| 52 | + _err(FSL_JSON_E_D login=%Q", zNameNew){name");g.perm.Setup)(c) json_set_ | |
| 53 | +** | |
| 54 | +** TODOs: | |
| 55 | +** | |
| 56 | +** - Admin non-Setup users cannot change the information for Setup | |
| 57 | +** users_cstr2("namto json_load_user_by_name(), but expects a user ID. Returns | |
| 58 | +** NULL if noL if no usercons. Returns | |
| 59 | +** NULL if noL if no user founson_value * tmpVcommand_arg( g.isHTTP && (!pUser || !*pUser) ){ | |
| 60 | + pUser = json_getenv_cstr("name") | |
| 61 | + /* ACHTUNG: fossil apparently internally sets name=user/get/XYZ | |
| 62 | +if we pass the name as part of the path, which is why we check | |
| 63 | + with json_command_path() before trying to gOrig "Requires 'a' or son_find_option_cstr2("namto json_load_user_by_name(), but expects a user ID. Returns | |
| 64 | +** NULL if noL if no user founson_value * tmpVcommand_arg( g.isHTTP && (!pUser || !*pUser) ){ | |
| 65 | + pUser = json_getenv_cstr("name") | |
| 66 | + /* ACHTUNG: fossil apparently internally sets name=user/get/XYZ | |
| 67 | +if we pass the name as part of the path, which is why we check | |
| 68 | + with json_command_path() before trying to get("name"). | |
| 69 | + */; | |
| 70 | + }) st(LK,NULL,NULL); password"); | |
| 71 | + PROP("in#if 0create(); | |
| 72 | + | |
| 73 | +#endifcreate", json_page_nyi, 0},e_find_option_cstr2("_find_option_cstr2(" !g.perm.Setup)(c) jsos 'a' or son_find_option_cstr2("namto json_load_user_by_name(), but expec !g.perm.Setup)(c) !g.perm.Setup)(c) ge with json_command_path(ge. | |
| 74 | + */; | |
| 75 | + }) st(LK,NULL,NULL); ption_cstr2("namto json_load_user_by_name(), but expec !g.perm.Setup)(c) !g.perm.Setup)(c) _find_option_cstr2(" !g.perm.Setup)(c) json_set_}_find_option_cstr2("){_find_option_cstr2("namto json_load_user_by_name(), but expects a !g.perm.Setup)(c) json_set_err(FSL_JSON_E_DENIED, | |
| 76 | + } char * zPWHash = NULL++gotFields !g.perm.Setup)(c) json_set_err(FSL_JSON_E_DENIED, | |
| 77 | + "Requires 'a' or son_find_option_cstr2("namto json_load_user_by_name(), but expects a user ID. Returns | |
| 78 | +** NULL if noL if no user founson_value * tmpVcommand_arg( g.isHTTP && (!pUser || !*pUser) ){ | |
| 79 | + pUser = json_getenv_cstr("name") | |
| 80 | + /* ACHTUNG: fossil apparently internally sets name=user/get/XYZ | |
| 81 | +if we pass the name as part of the path, which is why we check | |
| 82 | + with json_command_path() before trying to get("name"). | |
| 83 | + */; | |
| 84 | + }) st(LK,NULL,NULL); password"); | |
| 85 | + PROP("in#if 0create(); | |
| 86 | + | |
| 87 | +#endifcreate", json_page_nyi, 0},e_find_option_cstr2("_find_option_cstr2(" !g.perm.Setup)(c) jsos ge with json_command_path(ge. | |
| 88 | + */; | |
| 89 | + }) st(LK,NULL,NULL); ption_cstr2("namto json_load_user_by_name(), but expec !g.perm.Setup)(c) turns | |
| 90 | +** NULL if noL if no user f user founson_value * tmACHTUNG: fossil apparentloption_cstr2("namto json_load_user_by_name(), but expects a !g.perm.Setup)(c) json_set_err(FSL_JSON_E_DENIED, | |
| 91 | + } char * zPWHash = NULL++gotFields !g.perm.Setup)(c) json_set_err(FSL_JSON_E_DENIED, | |
| 92 | + !g.perm.Setup)(c) json_s admin user to modify a setup user | |
| 93 | + unless the admin is also a setup user. setup.c uses | |
| 94 | + that logic. There is a corner case for a NEW Setup user | |
| 95 | + which the admin is just!g.perm.Setup)(c) jsoup)(c) json_set_err(t_}_find_option_cstr2("){_find_option_cstr2("namto json_load_user_by_name(!g.perm.Setup)(c) jsos 'a' or pUser = json_ge json_load_user_by_name(), but expec !g.perm.Setup)(c) !g.perm.Setup)(c) _find_option_cstr2(" !g.perm.Setup)(c) json_set_}_find_option_cstr2("){_find_o _find_option_cstr2(" !g.perm.SetuUSER | |
| 96 | + if( zPW ){uid=%d", uid);blob_reset(&sql* | |
| 97 | +** TODOs: | |
| 98 | +** | |
| 99 | +** - Return something useful in the payload (at least the id of the | |
| 100 | +**m.Setup)(c) jsos 'a' or son_find_option_cstr2("namto json_/* | |
| 101 | + TODO: do not allow an admin user to modify a setup user | |
| 102 | + unless the admin is also a setup user. setup.c uses | |
| 103 | + that logic. There is a corner case for a NEW Setup user | |
| 104 | + which the admin is just!g.perm.Setup)(c) jsoup)(c) json_set_err(t_}_find_option_cstr2("){_find_option_cstr2("namto json_load_user_by_name(_option_cstr2("namto j_option_cstr2("){_find_option_cstr2("namto json_load_user_by_name(), but expects a !g.perm.Setup)(c) json_set_err(FSL_JSON_E_DENIED, | |
| 105 | + } char * zPWHash = NULL++gotFields !g.perm.Setup)(c) json_set_err(FSL_JSON_E_DENIED, | |
| 106 | + "Requires 'a' or son){ | |
| 107 | + /* Only change the name if the uid is explicitly set and name | |
| 108 | + would alue * tmpVcommand_arg( g.isHTTP && (!pUser || !*pUser) ){ | |
| 109 | + pUser = json_geteion_cstr2("){_find_option_cstr2("n { | |
| 110 | + er | |
| 111 | + which the admin is jACHTUNG: fossil apparently i ACHTUNG: fossil apparently internally sets name=user/get/XYZ | |
| 112 | +if goto errorand_path} name as part of the path, which is why we check | |
| 113 | + with json_command_path() before trying to get("name"). | |
| 114 | + */; | |
| 115 | + }) st(LK,NULL,NULL); password"); | |
| 116 | + PROP("in#if 0create(); | |
| 117 | + | |
| 118 | +#endifcreate", json_page_nyi, 0},e_find_option_cstr2("_find_option_cstr2(" !g.perm.Setup)(c) jsos 'a' or son_find_option_cstr2("namto json_load_user_by_name(), but expec !g.perm.Setup)(c) !g.perm.Setup)(c) _find_option_cstr2(" !g.perm.Setup)(c) json_set_}_find_opm.SetuUSER | |
| 119 | + if( zPW ){uid=%d", uid);blob_reset(&sql* | |
| 120 | +** TODOs: | |
| 121 | +** | |
| 122 | +** - Return something useful in the payload (at least the id of the | |
| 123 | +**m.Setup)(c) jsos 'a' or son_find_option_cstr2("namto json_/* | |
| 124 | + TODO: do not allow an admin user to modify a setup user | |
| 125 | + unl |
| --- a/src/json_user.c | |
| +++ b/src/json_user.c | |
| @@ -0,0 +1,125 @@ | |
| --- a/src/json_user.c | |
| +++ b/src/json_user.c | |
| @@ -0,0 +1,125 @@ | |
| 1 | !g.perm.Setup)(c) json_set_err(FSL_JSON_E_DENIED, |
| 2 | "Requires 'a' or son_find_option_cstr2("namto json_load_user_by_name(), but expects a user ID. Returns |
| 3 | ** NULL if noL if no user founson_value * tmpVcommand_arg( g.isHTTP && (!pUser || !*pUser) ){ |
| 4 | pUser = json_getenv_cstr("name") |
| 5 | /* ACHTUNG: fossil apparently internally sets name=user/get/XYZ |
| 6 | if we pass the name as part of the path, which is why we check |
| 7 | with json_command_path() before trying to get("name"). |
| 8 | */; |
| 9 | }) st(LK,NULL,NULL); password"); |
| 10 | PROP("in#if 0create(); |
| 11 | |
| 12 | #endifcreate", json_page_nyi, 0},e_find_option_cstr2("_find_option_cstr2(" !g.perm.Setup)(c) jsos 'a' or son_find_option_cstr2("namto json_load_user_by_name(), but expec !g.perm.Setup)(c) !g.perm.Setup)(c) ge with json_command_path(ge. |
| 13 | */; |
| 14 | }) st(LK,NULL,NULL); ption_cstr2("namto json_load_user_by_name(), but expec !g.perm.Setup)(c) !g.perm.Setup)(c) _find_option_cstr2(" !g.perm.Setup)(c) json_set_}_find_option_cstr2("){_find_option_cstr2("namto json_load_user_by_name(), but expects a !g.perm.Setup)(c) json_set_err(FSL_JSON_E_DENIED, |
| 15 | } char * zPWHash = NULL++gotFields !g.perm.Setup)(c) json_set_err(FSL_JSON_E_DENIED, |
| 16 | "Requires 'a' or son_find_option_cstr2("namto json_load_user_by_name(), but expects a user ID. Returns |
| 17 | ** NULL if noL if no user founson_value * tmpVcommand_arg( g.isHTTP && (!pUser || !*pUser) ){ |
| 18 | pUser = json_getenv_cstr("name") |
| 19 | /* ACHTUNG: fossil apparently internally sets name=user/get/XYZ |
| 20 | if we pass the name as part of the path, which is why we check |
| 21 | with json_command_path() before trying to get("name"). |
| 22 | */; |
| 23 | }) st(LK,NULL,NULL); password"); |
| 24 | PROP("in#if 0create(); |
| 25 | |
| 26 | #endifcreate", json_page_nyi, 0},e_find_option_cstr2("_find_option_cstr2(" !g.perm.Setup)(c) jsos ge with json_command_path(ge. |
| 27 | */; |
| 28 | }) st(LK,NULL,NULL); ption_cstr2("namto json_load_user_by_name(), but expec !g.perm.Setup)(c) turns |
| 29 | ** NULL if noL if no user f user founson_value * tmACHTUNG: fossil apparentloption_cstr2("namto json_load_user_by_name(), but expects a !g.perm.Setup)(c) json_set_err(FSL_JSON_E_DENIED, |
| 30 | } char * zPWHash = NULL++gotFields !g.perm.Setup)(c) json_set_err(FSL_JSON_E_DENIED, |
| 31 | "Requires 'a' or son_find_option_cstr2("namto json_load_user_by_name(), but expects a user ID. Returns |
| 32 | ** NULL if noL if no user founson_value * tmpVcommand_arg( g.isHTTP && (!pUser || !*pUser) ){ |
| 33 | pUser = json_getenv_cstr("name") |
| 34 | /* ACHTUNG: fossil apparently internally sets ){ |
| 35 | pUser = json_getenv_cstr("name") |
| 36 | !&& zNameNew && (zName != zNameNew) |
| 37 | && (0!=strcmp(zNameNew,zName))){ |
| 38 | _err(FSL_JSON_E_D login=%Q", zNameNew){name");g.perm.Setup)(c) json_set_ |
| 39 | ** |
| 40 | ** TODpUserperm.Setup)(c) payV_by_name(), but if(!payV){ |
| 41 | er |
| 42 | which thFSL_JSON_E_UNKNOWN,"Could not_option_cstr2(" !g.per user founson_value * tmpVcommanderm.Setup)(c) ge w get("name"). |
| 43 | */; |
| 44 | }) st(LK,NULL,NULL); password"); |
| 45 | PROP("in#if 0create(); |
| 46 | |
| 47 | #endifcreate", json_page_nyi, 0},e_find_option_cstr2("_find_option_cstr2(" !g.perm.Setup)(c) jsos 'a' or son_find_option_cstr2("namto json_load_user_by_name(), but expec !g.perm.Setup)(c) !g.perm.Setup)(c) _find_option_cstr2(" !g.perm.Setup)(c) t expects a user ID. Returns |
| 48 | ** NULL if noL if no user founson_value * tmpVcommand_arg( g.isHTTP && (!pUser || !*pUser) ){ |
| 49 | pUser = json_getenv_cstr("name") |
| 50 | !&& zNameNew && (zName != zNameNew) |
| 51 | && (0!=strcmp(zNameNew,zName))){ |
| 52 | _err(FSL_JSON_E_D login=%Q", zNameNew){name");g.perm.Setup)(c) json_set_ |
| 53 | ** |
| 54 | ** TODOs: |
| 55 | ** |
| 56 | ** - Admin non-Setup users cannot change the information for Setup |
| 57 | ** users_cstr2("namto json_load_user_by_name(), but expects a user ID. Returns |
| 58 | ** NULL if noL if no usercons. Returns |
| 59 | ** NULL if noL if no user founson_value * tmpVcommand_arg( g.isHTTP && (!pUser || !*pUser) ){ |
| 60 | pUser = json_getenv_cstr("name") |
| 61 | /* ACHTUNG: fossil apparently internally sets name=user/get/XYZ |
| 62 | if we pass the name as part of the path, which is why we check |
| 63 | with json_command_path() before trying to gOrig "Requires 'a' or son_find_option_cstr2("namto json_load_user_by_name(), but expects a user ID. Returns |
| 64 | ** NULL if noL if no user founson_value * tmpVcommand_arg( g.isHTTP && (!pUser || !*pUser) ){ |
| 65 | pUser = json_getenv_cstr("name") |
| 66 | /* ACHTUNG: fossil apparently internally sets name=user/get/XYZ |
| 67 | if we pass the name as part of the path, which is why we check |
| 68 | with json_command_path() before trying to get("name"). |
| 69 | */; |
| 70 | }) st(LK,NULL,NULL); password"); |
| 71 | PROP("in#if 0create(); |
| 72 | |
| 73 | #endifcreate", json_page_nyi, 0},e_find_option_cstr2("_find_option_cstr2(" !g.perm.Setup)(c) jsos 'a' or son_find_option_cstr2("namto json_load_user_by_name(), but expec !g.perm.Setup)(c) !g.perm.Setup)(c) ge with json_command_path(ge. |
| 74 | */; |
| 75 | }) st(LK,NULL,NULL); ption_cstr2("namto json_load_user_by_name(), but expec !g.perm.Setup)(c) !g.perm.Setup)(c) _find_option_cstr2(" !g.perm.Setup)(c) json_set_}_find_option_cstr2("){_find_option_cstr2("namto json_load_user_by_name(), but expects a !g.perm.Setup)(c) json_set_err(FSL_JSON_E_DENIED, |
| 76 | } char * zPWHash = NULL++gotFields !g.perm.Setup)(c) json_set_err(FSL_JSON_E_DENIED, |
| 77 | "Requires 'a' or son_find_option_cstr2("namto json_load_user_by_name(), but expects a user ID. Returns |
| 78 | ** NULL if noL if no user founson_value * tmpVcommand_arg( g.isHTTP && (!pUser || !*pUser) ){ |
| 79 | pUser = json_getenv_cstr("name") |
| 80 | /* ACHTUNG: fossil apparently internally sets name=user/get/XYZ |
| 81 | if we pass the name as part of the path, which is why we check |
| 82 | with json_command_path() before trying to get("name"). |
| 83 | */; |
| 84 | }) st(LK,NULL,NULL); password"); |
| 85 | PROP("in#if 0create(); |
| 86 | |
| 87 | #endifcreate", json_page_nyi, 0},e_find_option_cstr2("_find_option_cstr2(" !g.perm.Setup)(c) jsos ge with json_command_path(ge. |
| 88 | */; |
| 89 | }) st(LK,NULL,NULL); ption_cstr2("namto json_load_user_by_name(), but expec !g.perm.Setup)(c) turns |
| 90 | ** NULL if noL if no user f user founson_value * tmACHTUNG: fossil apparentloption_cstr2("namto json_load_user_by_name(), but expects a !g.perm.Setup)(c) json_set_err(FSL_JSON_E_DENIED, |
| 91 | } char * zPWHash = NULL++gotFields !g.perm.Setup)(c) json_set_err(FSL_JSON_E_DENIED, |
| 92 | !g.perm.Setup)(c) json_s admin user to modify a setup user |
| 93 | unless the admin is also a setup user. setup.c uses |
| 94 | that logic. There is a corner case for a NEW Setup user |
| 95 | which the admin is just!g.perm.Setup)(c) jsoup)(c) json_set_err(t_}_find_option_cstr2("){_find_option_cstr2("namto json_load_user_by_name(!g.perm.Setup)(c) jsos 'a' or pUser = json_ge json_load_user_by_name(), but expec !g.perm.Setup)(c) !g.perm.Setup)(c) _find_option_cstr2(" !g.perm.Setup)(c) json_set_}_find_option_cstr2("){_find_o _find_option_cstr2(" !g.perm.SetuUSER |
| 96 | if( zPW ){uid=%d", uid);blob_reset(&sql* |
| 97 | ** TODOs: |
| 98 | ** |
| 99 | ** - Return something useful in the payload (at least the id of the |
| 100 | **m.Setup)(c) jsos 'a' or son_find_option_cstr2("namto json_/* |
| 101 | TODO: do not allow an admin user to modify a setup user |
| 102 | unless the admin is also a setup user. setup.c uses |
| 103 | that logic. There is a corner case for a NEW Setup user |
| 104 | which the admin is just!g.perm.Setup)(c) jsoup)(c) json_set_err(t_}_find_option_cstr2("){_find_option_cstr2("namto json_load_user_by_name(_option_cstr2("namto j_option_cstr2("){_find_option_cstr2("namto json_load_user_by_name(), but expects a !g.perm.Setup)(c) json_set_err(FSL_JSON_E_DENIED, |
| 105 | } char * zPWHash = NULL++gotFields !g.perm.Setup)(c) json_set_err(FSL_JSON_E_DENIED, |
| 106 | "Requires 'a' or son){ |
| 107 | /* Only change the name if the uid is explicitly set and name |
| 108 | would alue * tmpVcommand_arg( g.isHTTP && (!pUser || !*pUser) ){ |
| 109 | pUser = json_geteion_cstr2("){_find_option_cstr2("n { |
| 110 | er |
| 111 | which the admin is jACHTUNG: fossil apparently i ACHTUNG: fossil apparently internally sets name=user/get/XYZ |
| 112 | if goto errorand_path} name as part of the path, which is why we check |
| 113 | with json_command_path() before trying to get("name"). |
| 114 | */; |
| 115 | }) st(LK,NULL,NULL); password"); |
| 116 | PROP("in#if 0create(); |
| 117 | |
| 118 | #endifcreate", json_page_nyi, 0},e_find_option_cstr2("_find_option_cstr2(" !g.perm.Setup)(c) jsos 'a' or son_find_option_cstr2("namto json_load_user_by_name(), but expec !g.perm.Setup)(c) !g.perm.Setup)(c) _find_option_cstr2(" !g.perm.Setup)(c) json_set_}_find_opm.SetuUSER |
| 119 | if( zPW ){uid=%d", uid);blob_reset(&sql* |
| 120 | ** TODOs: |
| 121 | ** |
| 122 | ** - Return something useful in the payload (at least the id of the |
| 123 | **m.Setup)(c) jsos 'a' or son_find_option_cstr2("namto json_/* |
| 124 | TODO: do not allow an admin user to modify a setup user |
| 125 | unl |
+57
| --- a/src/json_wiki.c | ||
| +++ b/src/json_wiki.c | ||
| @@ -0,0 +1,57 @@ | ||
| 1 | +laLoads the given wiki page an representation | |
| 2 | +**la is positive tru is HTML-ized | |
| 3 | +** negative then no | |
| 4 | +** is not returned | |
| 5 | +** | |
| 6 | +**Manifest *pWiki = 0; | |
| 7 | + char * zUuid = NULL; | |
| 8 | + Stmt q; | |
| 9 | + db_prepare(&q, | |
| 10 | +,(SQLITE_ROW != db_step(&q)) ){ | |
| 11 | + id = db_column_int(&q,0); | |
| 12 | + zUuiconst * zBody = NULLnegative then no | |
| 13 | +*laLoads the given wik = -1; | |
| 14 | + Stmt q;!=0 ){ | |
| 15 | + } | |
| 16 | + | |
| 17 | + { | |
| 18 | + unsigned int lenlen = strlen(zBody); | |
| 19 | +e page is saved | |
| 20 | + again before the next line finishes, payV could be the results | |
| 21 | + nameVcontentVemptyContentpayV = NULL; | |
| 22 | + doParse | |
| 23 | +** is using fossil's | |
| 24 | +**else it is not parseddoParseed | |
| 25 | +** negative then no | |
| 26 | +** is not returned | |
| 27 | +** | |
| 28 | +**Manifest *pWiki = 0; | |
| 29 | + char * zUuidlaLoads the given wiki page an representation | |
| 30 | +**la is positive tru is HTML-ized | |
| 31 | +** negative then no | |
| 32 | +** is not returned | |
| 33 | +** | |
| 34 | +**Manifest *pWiki = 0; | |
| 35 | + char * zUuid = NULL; | |
| 36 | + Stmt q; | |
| 37 | + db_prepare(&q, | |
| 38 | +,(SQLITE_ROW != db_step(&q)) ){ | |
| 39 | + id = db_column_int(&q,0); | |
| 40 | + zUuiconst * zBody = NULLnegative then no | |
| 41 | +*laLoads the given wik = -1; | |
| 42 | + Stmt q;!=0 ){ | |
| 43 | + } | |
| 44 | + | |
| 45 | + { | |
| 46 | + unsigned int lenlen = strlen(zBody); | |
| 47 | +e page is saved | |
| 48 | + again before the next line finishes, payV could be the results | |
| 49 | + nameVcontentVemptyContentpayV = NULL; | |
| 50 | +if( doParse ){ | |
| 51 | + len = strlen(zBody); | |
| 52 | +}else{ | |
| 53 | +doParsedoParsedoParse){ | |
| 54 | + zFormat = "raw"; | |
| 55 | + } | |
| 56 | + if( 'r' != *zFormat ){ | |
| 57 | + zFormat = "html"'h'==*z |
| --- a/src/json_wiki.c | |
| +++ b/src/json_wiki.c | |
| @@ -0,0 +1,57 @@ | |
| --- a/src/json_wiki.c | |
| +++ b/src/json_wiki.c | |
| @@ -0,0 +1,57 @@ | |
| 1 | laLoads the given wiki page an representation |
| 2 | **la is positive tru is HTML-ized |
| 3 | ** negative then no |
| 4 | ** is not returned |
| 5 | ** |
| 6 | **Manifest *pWiki = 0; |
| 7 | char * zUuid = NULL; |
| 8 | Stmt q; |
| 9 | db_prepare(&q, |
| 10 | ,(SQLITE_ROW != db_step(&q)) ){ |
| 11 | id = db_column_int(&q,0); |
| 12 | zUuiconst * zBody = NULLnegative then no |
| 13 | *laLoads the given wik = -1; |
| 14 | Stmt q;!=0 ){ |
| 15 | } |
| 16 | |
| 17 | { |
| 18 | unsigned int lenlen = strlen(zBody); |
| 19 | e page is saved |
| 20 | again before the next line finishes, payV could be the results |
| 21 | nameVcontentVemptyContentpayV = NULL; |
| 22 | doParse |
| 23 | ** is using fossil's |
| 24 | **else it is not parseddoParseed |
| 25 | ** negative then no |
| 26 | ** is not returned |
| 27 | ** |
| 28 | **Manifest *pWiki = 0; |
| 29 | char * zUuidlaLoads the given wiki page an representation |
| 30 | **la is positive tru is HTML-ized |
| 31 | ** negative then no |
| 32 | ** is not returned |
| 33 | ** |
| 34 | **Manifest *pWiki = 0; |
| 35 | char * zUuid = NULL; |
| 36 | Stmt q; |
| 37 | db_prepare(&q, |
| 38 | ,(SQLITE_ROW != db_step(&q)) ){ |
| 39 | id = db_column_int(&q,0); |
| 40 | zUuiconst * zBody = NULLnegative then no |
| 41 | *laLoads the given wik = -1; |
| 42 | Stmt q;!=0 ){ |
| 43 | } |
| 44 | |
| 45 | { |
| 46 | unsigned int lenlen = strlen(zBody); |
| 47 | e page is saved |
| 48 | again before the next line finishes, payV could be the results |
| 49 | nameVcontentVemptyContentpayV = NULL; |
| 50 | if( doParse ){ |
| 51 | len = strlen(zBody); |
| 52 | }else{ |
| 53 | doParsedoParsedoParse){ |
| 54 | zFormat = "raw"; |
| 55 | } |
| 56 | if( 'r' != *zFormat ){ |
| 57 | zFormat = "html"'h'==*z |
+207
-77
| --- src/login.c | ||
| +++ src/login.c | ||
| @@ -84,11 +84,11 @@ | ||
| 84 | 84 | ** |
| 85 | 85 | ** The login cookie name is always of the form: fossil-XXXXXXXXXXXXXXXX |
| 86 | 86 | ** where the Xs are the first 16 characters of the login-group-code or |
| 87 | 87 | ** of the project-code if we are not a member of any login-group. |
| 88 | 88 | */ |
| 89 | -static char *login_cookie_name(void){ | |
| 89 | +char *login_cookie_name(void){ | |
| 90 | 90 | static char *zCookieName = 0; |
| 91 | 91 | if( zCookieName==0 ){ |
| 92 | 92 | zCookieName = db_text(0, |
| 93 | 93 | "SELECT 'fossil-' || substr(value,1,16)" |
| 94 | 94 | " FROM config" |
| @@ -146,24 +146,26 @@ | ||
| 146 | 146 | |
| 147 | 147 | |
| 148 | 148 | /* |
| 149 | 149 | ** Check to see if the anonymous login is valid. If it is valid, return |
| 150 | 150 | ** the userid of the anonymous user. |
| 151 | +** | |
| 152 | +** The zCS parameter is the "captcha seed" used for a specific | |
| 153 | +** anonymous login request. | |
| 151 | 154 | */ |
| 152 | -static int isValidAnonymousLogin( | |
| 155 | +int login_is_valid_anonymous( | |
| 153 | 156 | const char *zUsername, /* The username. Must be "anonymous" */ |
| 154 | - const char *zPassword /* The supplied password */ | |
| 157 | + const char *zPassword, /* The supplied password */ | |
| 158 | + const char *zCS /* The captcha seed value */ | |
| 155 | 159 | ){ |
| 156 | - const char *zCS; /* The captcha seed value */ | |
| 157 | 160 | const char *zPw; /* The correct password shown in the captcha */ |
| 158 | 161 | int uid; /* The user ID of anonymous */ |
| 159 | 162 | |
| 160 | 163 | if( zUsername==0 ) return 0; |
| 161 | - if( zPassword==0 ) return 0; | |
| 162 | - if( fossil_strcmp(zUsername,"anonymous")!=0 ) return 0; | |
| 163 | - zCS = P("cs"); /* The "cs" parameter is the "captcha seed" */ | |
| 164 | - if( zCS==0 ) return 0; | |
| 164 | + else if( zPassword==0 ) return 0; | |
| 165 | + else if( zCS==0 ) return 0; | |
| 166 | + else if( fossil_strcmp(zUsername,"anonymous")!=0 ) return 0; | |
| 165 | 167 | zPw = captcha_decode((unsigned int)atoi(zCS)); |
| 166 | 168 | if( fossil_stricmp(zPw, zPassword)!=0 ) return 0; |
| 167 | 169 | uid = db_int(0, "SELECT uid FROM user WHERE login='anonymous'" |
| 168 | 170 | " AND length(pw)>0 AND length(cap)>0"); |
| 169 | 171 | return uid; |
| @@ -197,10 +199,163 @@ | ||
| 197 | 199 | "INSERT INTO accesslog(uname,ipaddr,success,mtime)" |
| 198 | 200 | "VALUES(%Q,%Q,%d,julianday('now'));", |
| 199 | 201 | zUsername, zIpAddr, bSuccess |
| 200 | 202 | ); |
| 201 | 203 | } |
| 204 | + | |
| 205 | +/* | |
| 206 | +** Searches for the user ID matching the given name and password. | |
| 207 | +** On success it returns a positive value. On error it returns 0. | |
| 208 | +** On serious (DB-level) error it will probably exit. | |
| 209 | +** | |
| 210 | +** zPassword may be either the plain-text form or the encrypted | |
| 211 | +** form of the user's password. | |
| 212 | +*/ | |
| 213 | +int login_search_uid(char const *zUsername, char const *zPasswd){ | |
| 214 | + char * zSha1Pw = sha1_shared_secret(zPasswd, zUsername, 0); | |
| 215 | + int const uid = | |
| 216 | + db_int(0, | |
| 217 | + "SELECT uid FROM user" | |
| 218 | + " WHERE login=%Q" | |
| 219 | + " AND length(cap)>0 AND length(pw)>0" | |
| 220 | + " AND login NOT IN ('anonymous','nobody','developer','reader')" | |
| 221 | + " AND (pw=%Q OR pw=%Q)", | |
| 222 | + zUsername, zPasswd, zSha1Pw | |
| 223 | + ); | |
| 224 | + free(zSha1Pw); | |
| 225 | + return uid; | |
| 226 | +} | |
| 227 | + | |
| 228 | +/* | |
| 229 | +** Generates a login cookie value for a non-anonymous user. | |
| 230 | +** | |
| 231 | +** The zHash parameter must be a random value which must be | |
| 232 | +** subsequently stored in user.cookie for later validation. | |
| 233 | +** | |
| 234 | +** The returned memory should be free()d after use. | |
| 235 | +*/ | |
| 236 | +char * login_gen_user_cookie_value(char const *zUsername, char const * zHash){ | |
| 237 | + char * zProjCode = db_get("project-code",NULL); | |
| 238 | + char *zCode = abbreviated_project_code(zProjCode); | |
| 239 | + free(zProjCode); | |
| 240 | + assert((zUsername && *zUsername) && "Invalid user data."); | |
| 241 | + return mprintf("%s/%z/%s", zHash, zCode, zUsername); | |
| 242 | +} | |
| 243 | + | |
| 244 | +/* | |
| 245 | +** Generates a login cookie for NON-ANONYMOUS users. Note that this | |
| 246 | +** function "could" figure out the uid by itself but it currently | |
| 247 | +** doesn't because the code which calls this already has the uid. | |
| 248 | +** | |
| 249 | +** This function also updates the user.cookie, user.ipaddr, | |
| 250 | +** and user.cexpire fields for the given user. | |
| 251 | +** | |
| 252 | +** If zDest is not NULL then the generated cookie is copied to | |
| 253 | +** *zDdest and ownership is transfered to the caller (who should | |
| 254 | +** eventually pass it to free()). | |
| 255 | +*/ | |
| 256 | +void login_set_user_cookie( | |
| 257 | + char const * zUsername, /* User's name */ | |
| 258 | + int uid, /* User's ID */ | |
| 259 | + char ** zDest /* Optional: store generated cookie value. */ | |
| 260 | +){ | |
| 261 | + const char *zCookieName = login_cookie_name(); | |
| 262 | + const char *zExpire = db_get("cookie-expire","8766"); | |
| 263 | + int expires = atoi(zExpire)*3600; | |
| 264 | + char *zHash; | |
| 265 | + char *zCookie; | |
| 266 | + char const * zIpAddr = PD("REMOTE_ADDR","nil"); /* Complete IP address for logging */ | |
| 267 | + char * zRemoteAddr = ipPrefix(zIpAddr); /* Abbreviated IP address */ | |
| 268 | + assert((zUsername && *zUsername) && (uid > 0) && "Invalid user data."); | |
| 269 | + zHash = db_text(0, "SELECT hex(randomblob(25))"); | |
| 270 | + zCookie = login_gen_user_cookie_value(zUsername, zHash); | |
| 271 | + cgi_set_cookie(zCookieName, zCookie, login_cookie_path(), expires); | |
| 272 | + record_login_attempt(zUsername, zIpAddr, 1); | |
| 273 | + db_multi_exec( | |
| 274 | + "UPDATE user SET cookie=%Q, ipaddr=%Q, " | |
| 275 | + " cexpire=julianday('now')+%d/86400.0 WHERE uid=%d", | |
| 276 | + zHash, zRemoteAddr, expires, uid | |
| 277 | + ); | |
| 278 | + free(zRemoteAddr); | |
| 279 | + free(zHash); | |
| 280 | + if( zDest ){ | |
| 281 | + *zDest = zCookie; | |
| 282 | + }else{ | |
| 283 | + free(zCookie); | |
| 284 | + } | |
| 285 | +} | |
| 286 | + | |
| 287 | +/* Sets a cookie for an anonymous user login, which looks like this: | |
| 288 | +** | |
| 289 | +** HASH/TIME/anonymous | |
| 290 | +** | |
| 291 | +** Where HASH is the sha1sum of TIME/IPADDR/SECRET, in which IPADDR | |
| 292 | +** is the abbreviated IP address and SECRET is captcha-secret. | |
| 293 | +** | |
| 294 | +** If either zIpAddr or zRemoteAddr are NULL then REMOTE_ADDR | |
| 295 | +** is used. | |
| 296 | +** | |
| 297 | +** If zCookieDest is not NULL then the generated cookie is assigned to | |
| 298 | +** *zCookieDest and the caller must eventually free() it. | |
| 299 | +*/ | |
| 300 | +void login_set_anon_cookie(char const * zIpAddr, char ** zCookieDest ){ | |
| 301 | + char const *zNow; /* Current time (julian day number) */ | |
| 302 | + char *zCookie; /* The login cookie */ | |
| 303 | + char const *zCookieName; /* Name of the login cookie */ | |
| 304 | + Blob b; /* Blob used during cookie construction */ | |
| 305 | + char * zRemoteAddr; /* Abbreviated IP address */ | |
| 306 | + if(!zIpAddr){ | |
| 307 | + zIpAddr = PD("REMOTE_ADDR","nil"); | |
| 308 | + } | |
| 309 | + zRemoteAddr = ipPrefix(zIpAddr); | |
| 310 | + zCookieName = login_cookie_name(); | |
| 311 | + zNow = db_text("0", "SELECT julianday('now')"); | |
| 312 | + assert( zCookieName && zRemoteAddr && zIpAddr && zNow ); | |
| 313 | + blob_init(&b, zNow, -1); | |
| 314 | + blob_appendf(&b, "/%s/%s", zRemoteAddr, db_get("captcha-secret","")); | |
| 315 | + sha1sum_blob(&b, &b); | |
| 316 | + zCookie = mprintf("%s/%s/anonymous", blob_buffer(&b), zNow); | |
| 317 | + blob_reset(&b); | |
| 318 | + cgi_set_cookie(zCookieName, zCookie, login_cookie_path(), 6*3600); | |
| 319 | + if( zCookieDest ){ | |
| 320 | + *zCookieDest = zCookie; | |
| 321 | + }else{ | |
| 322 | + free(zCookie); | |
| 323 | + } | |
| 324 | + | |
| 325 | +} | |
| 326 | + | |
| 327 | +/* | |
| 328 | +** "Unsets" the login cookie (insofar as cookies can be unset) and | |
| 329 | +** clears the current user's (g.userUid) login information from the | |
| 330 | +** user table. Sets: user.cookie, user.ipaddr, user.cexpire. | |
| 331 | +** | |
| 332 | +** We could/should arguably clear out g.userUid and g.perm here, but | |
| 333 | +** we don't currently do not. | |
| 334 | +** | |
| 335 | +** This is a no-op if g.userUid is 0. | |
| 336 | +*/ | |
| 337 | +void login_clear_login_data(){ | |
| 338 | + if(!g.userUid){ | |
| 339 | + return; | |
| 340 | + }else{ | |
| 341 | + char const * cookie = login_cookie_name(); | |
| 342 | + /* To logout, change the cookie value to an empty string */ | |
| 343 | + cgi_set_cookie(cookie, "", | |
| 344 | + login_cookie_path(), -86400); | |
| 345 | + db_multi_exec("UPDATE user SET cookie=NULL, ipaddr=NULL, " | |
| 346 | + " cexpire=0 WHERE uid=%d" | |
| 347 | + " AND login NOT IN ('anonymous','nobody'," | |
| 348 | + " 'developer','reader')", g.userUid); | |
| 349 | + cgi_replace_parameter(cookie, NULL) | |
| 350 | + /* At the time of this writing, cgi_replace_parameter() was | |
| 351 | + ** "NULL-value-safe", and i'm hoping the NULL doesn't cause any | |
| 352 | + ** downstream problems here. We could alternately use "" here. | |
| 353 | + */ | |
| 354 | + ; | |
| 355 | + } | |
| 356 | +} | |
| 202 | 357 | |
| 203 | 358 | /* |
| 204 | 359 | ** Look at the HTTP_USER_AGENT parameter and try to determine if the user agent |
| 205 | 360 | ** is a manually operated browser or a bot. When in doubt, assume a bot. Return |
| 206 | 361 | ** true if we believe the agent is a real person. |
| @@ -281,22 +436,19 @@ | ||
| 281 | 436 | int anonFlag; |
| 282 | 437 | char *zErrMsg = ""; |
| 283 | 438 | int uid; /* User id loged in user */ |
| 284 | 439 | char *zSha1Pw; |
| 285 | 440 | const char *zIpAddr; /* IP address of requestor */ |
| 286 | - char *zRemoteAddr; /* Abbreviated IP address of requestor */ | |
| 287 | 441 | |
| 288 | 442 | login_check_credentials(); |
| 289 | 443 | sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0, |
| 290 | 444 | constant_time_cmp_function, 0, 0); |
| 291 | 445 | zUsername = P("u"); |
| 292 | 446 | zPasswd = P("p"); |
| 293 | 447 | anonFlag = P("anon")!=0; |
| 294 | 448 | if( P("out")!=0 ){ |
| 295 | - /* To logout, change the cookie value to an empty string */ | |
| 296 | - const char *zCookieName = login_cookie_name(); | |
| 297 | - cgi_set_cookie(zCookieName, "", login_cookie_path(), -86400); | |
| 449 | + login_clear_login_data(); | |
| 298 | 450 | redirect_to_g(); |
| 299 | 451 | } |
| 300 | 452 | if( g.perm.Password && zPasswd |
| 301 | 453 | && (zNew1 = P("n1"))!=0 && (zNew2 = P("n2"))!=0 |
| 302 | 454 | ){ |
| @@ -344,50 +496,20 @@ | ||
| 344 | 496 | return; |
| 345 | 497 | } |
| 346 | 498 | } |
| 347 | 499 | } |
| 348 | 500 | zIpAddr = PD("REMOTE_ADDR","nil"); /* Complete IP address for logging */ |
| 349 | - zRemoteAddr = ipPrefix(zIpAddr); /* Abbreviated IP address */ | |
| 350 | - uid = isValidAnonymousLogin(zUsername, zPasswd); | |
| 501 | + uid = login_is_valid_anonymous(zUsername, zPasswd, P("cs")); | |
| 351 | 502 | if( uid>0 ){ |
| 352 | - /* Successful login as anonymous. Set a cookie that looks like | |
| 353 | - ** this: | |
| 354 | - ** | |
| 355 | - ** HASH/TIME/anonymous | |
| 356 | - ** | |
| 357 | - ** Where HASH is the sha1sum of TIME/IPADDR/SECRET, in which IPADDR | |
| 358 | - ** is the abbreviated IP address and SECRET is captcha-secret. | |
| 359 | - */ | |
| 360 | - char *zNow; /* Current time (julian day number) */ | |
| 361 | - char *zCookie; /* The login cookie */ | |
| 362 | - const char *zCookieName; /* Name of the login cookie */ | |
| 363 | - Blob b; /* Blob used during cookie construction */ | |
| 364 | - | |
| 365 | - zCookieName = login_cookie_name(); | |
| 366 | - zNow = db_text("0", "SELECT julianday('now')"); | |
| 367 | - blob_init(&b, zNow, -1); | |
| 368 | - blob_appendf(&b, "/%s/%s", zRemoteAddr, db_get("captcha-secret","")); | |
| 369 | - sha1sum_blob(&b, &b); | |
| 370 | - zCookie = sqlite3_mprintf("%s/%s/anonymous", blob_buffer(&b), zNow); | |
| 371 | - blob_reset(&b); | |
| 372 | - free(zNow); | |
| 373 | - cgi_set_cookie(zCookieName, zCookie, login_cookie_path(), 6*3600); | |
| 503 | + login_set_anon_cookie(zIpAddr, NULL); | |
| 374 | 504 | record_login_attempt("anonymous", zIpAddr, 1); |
| 375 | 505 | redirect_to_g(); |
| 376 | 506 | } |
| 377 | 507 | if( zUsername!=0 && zPasswd!=0 && zPasswd[0]!=0 ){ |
| 378 | 508 | /* Attempting to log in as a user other than anonymous. |
| 379 | 509 | */ |
| 380 | - zSha1Pw = sha1_shared_secret(zPasswd, zUsername, 0); | |
| 381 | - uid = db_int(0, | |
| 382 | - "SELECT uid FROM user" | |
| 383 | - " WHERE login=%Q" | |
| 384 | - " AND length(cap)>0 AND length(pw)>0" | |
| 385 | - " AND login NOT IN ('anonymous','nobody','developer','reader')" | |
| 386 | - " AND (constant_time_cmp(pw,%Q)=0 OR constant_time_cmp(pw,%Q)=0)", | |
| 387 | - zUsername, zSha1Pw, zPasswd | |
| 388 | - ); | |
| 510 | + uid = login_search_uid(zUsername, zPasswd); | |
| 389 | 511 | if( uid<=0 ){ |
| 390 | 512 | sleep(1); |
| 391 | 513 | zErrMsg = |
| 392 | 514 | @ <p><span class="loginError"> |
| 393 | 515 | @ You entered an unknown user or an incorrect password. |
| @@ -400,26 +522,11 @@ | ||
| 400 | 522 | ** HASH/PROJECT/LOGIN |
| 401 | 523 | ** |
| 402 | 524 | ** where HASH is a random hex number, PROJECT is either project |
| 403 | 525 | ** code prefix, and LOGIN is the user name. |
| 404 | 526 | */ |
| 405 | - char *zCookie; | |
| 406 | - const char *zCookieName = login_cookie_name(); | |
| 407 | - const char *zExpire = db_get("cookie-expire","8766"); | |
| 408 | - int expires = atoi(zExpire)*3600; | |
| 409 | - char *zCode = abbreviated_project_code(db_get("project-code","")); | |
| 410 | - char *zHash; | |
| 411 | - | |
| 412 | - zHash = db_text(0, "SELECT hex(randomblob(25))"); | |
| 413 | - zCookie = mprintf("%s/%s/%s", zHash, zCode, zUsername); | |
| 414 | - cgi_set_cookie(zCookieName, zCookie, login_cookie_path(), expires); | |
| 415 | - record_login_attempt(zUsername, zIpAddr, 1); | |
| 416 | - db_multi_exec( | |
| 417 | - "UPDATE user SET cookie=%Q, ipaddr=%Q, " | |
| 418 | - " cexpire=julianday('now')+%d/86400.0 WHERE uid=%d", | |
| 419 | - zHash, zRemoteAddr, expires, uid | |
| 420 | - ); | |
| 527 | + login_set_user_cookie(zUsername, uid, NULL); | |
| 421 | 528 | redirect_to_g(); |
| 422 | 529 | } |
| 423 | 530 | } |
| 424 | 531 | style_header("Login/Logout"); |
| 425 | 532 | @ %s(zErrMsg) |
| @@ -586,12 +693,16 @@ | ||
| 586 | 693 | fossil_free(zOtherRepo); |
| 587 | 694 | return nXfer; |
| 588 | 695 | } |
| 589 | 696 | |
| 590 | 697 | /* |
| 591 | -** Lookup the uid for a user with zLogin and zCookie and zRemoteAddr. | |
| 592 | -** Return 0 if not found. | |
| 698 | +** Lookup the uid for a non-built-in user with zLogin and zCookie and | |
| 699 | +** zRemoteAddr. Return 0 if not found. | |
| 700 | +** | |
| 701 | +** Note that this only searches for logged-in entries with matching | |
| 702 | +** zCookie (db: user.cookie) and zRemoteAddr (db: user.ipaddr) | |
| 703 | +** entries. | |
| 593 | 704 | */ |
| 594 | 705 | static int login_find_user( |
| 595 | 706 | const char *zLogin, /* User name */ |
| 596 | 707 | const char *zCookie, /* Login cookie value */ |
| 597 | 708 | const char *zRemoteAddr /* Abbreviated IP address for valid login */ |
| @@ -613,16 +724,14 @@ | ||
| 613 | 724 | ); |
| 614 | 725 | return uid; |
| 615 | 726 | } |
| 616 | 727 | |
| 617 | 728 | /* |
| 618 | -** This routine examines the login cookie to see if it exists and | |
| 619 | -** and is valid. If the login cookie checks out, it then sets | |
| 620 | -** global variables appropriately. Global variables set include | |
| 621 | -** g.userUid and g.zLogin and of the g.perm.Read family of permission | |
| 622 | -** booleans. | |
| 623 | -** | |
| 729 | +** This routine examines the login cookie to see if it exists and and | |
| 730 | +** is valid. If the login cookie checks out, it then sets global | |
| 731 | +** variables appropriately. Global variables set include g.userUid | |
| 732 | +** and g.zLogin and the g.perm family of permission booleans. | |
| 624 | 733 | */ |
| 625 | 734 | void login_check_credentials(void){ |
| 626 | 735 | int uid = 0; /* User id */ |
| 627 | 736 | const char *zCookie; /* Text of the login cookie */ |
| 628 | 737 | const char *zIpAddr; /* Raw IP address of the requestor */ |
| @@ -710,11 +819,11 @@ | ||
| 710 | 819 | } |
| 711 | 820 | sqlite3_snprintf(sizeof(g.zCsrfToken), g.zCsrfToken, "%.10s", zHash); |
| 712 | 821 | } |
| 713 | 822 | |
| 714 | 823 | /* If no user found and the REMOTE_USER environment variable is set, |
| 715 | - ** the accept the value of REMOTE_USER as the user. | |
| 824 | + ** then accept the value of REMOTE_USER as the user. | |
| 716 | 825 | */ |
| 717 | 826 | if( uid==0 ){ |
| 718 | 827 | const char *zRemoteUser = P("REMOTE_USER"); |
| 719 | 828 | if( zRemoteUser && db_get_boolean("remote_user_ok",0) ){ |
| 720 | 829 | uid = db_int(0, "SELECT uid FROM user WHERE login=%Q" |
| @@ -760,11 +869,11 @@ | ||
| 760 | 869 | if( fossil_strcmp(g.zLogin,"nobody")==0 ){ |
| 761 | 870 | g.zLogin = 0; |
| 762 | 871 | } |
| 763 | 872 | |
| 764 | 873 | /* Set the capabilities */ |
| 765 | - login_set_capabilities(zCap, 0); | |
| 874 | + login_replace_capabilities(zCap, 0); | |
| 766 | 875 | login_set_anon_nobody_capabilities(); |
| 767 | 876 | if( zCap[0] && !g.perm.History && db_get_boolean("auto-enable-hyperlinks",1) |
| 768 | 877 | && isHuman(P("HTTP_USER_AGENT")) ){ |
| 769 | 878 | g.perm.History = 1; |
| 770 | 879 | } |
| @@ -793,22 +902,25 @@ | ||
| 793 | 902 | login_anon_once = 0; |
| 794 | 903 | } |
| 795 | 904 | } |
| 796 | 905 | |
| 797 | 906 | /* |
| 798 | -** Flags passed into the 2nd argument of login_set_capabilities(). | |
| 907 | +** Flags passed into the 2nd argument of login_set/replace_capabilities(). | |
| 799 | 908 | */ |
| 800 | 909 | #if INTERFACE |
| 801 | 910 | #define LOGIN_IGNORE_U 0x01 /* Ignore "u" */ |
| 802 | 911 | #define LOGIN_IGNORE_V 0x01 /* Ignore "v" */ |
| 803 | 912 | #endif |
| 804 | 913 | |
| 805 | 914 | /* |
| 806 | -** Set the global capability flags based on a capability string. | |
| 915 | +** Adds all capability flags in zCap to g.perm. | |
| 807 | 916 | */ |
| 808 | 917 | void login_set_capabilities(const char *zCap, unsigned flags){ |
| 809 | 918 | int i; |
| 919 | + if(NULL==zCap){ | |
| 920 | + return; | |
| 921 | + } | |
| 810 | 922 | for(i=0; zCap[i]; i++){ |
| 811 | 923 | switch( zCap[i] ){ |
| 812 | 924 | case 's': g.perm.Setup = 1; /* Fall thru into Admin */ |
| 813 | 925 | case 'a': g.perm.Admin = g.perm.RdTkt = g.perm.WrTkt = g.perm.Zip = |
| 814 | 926 | g.perm.RdWiki = g.perm.WrWiki = g.perm.NewWiki = |
| @@ -862,10 +974,18 @@ | ||
| 862 | 974 | break; |
| 863 | 975 | } |
| 864 | 976 | } |
| 865 | 977 | } |
| 866 | 978 | } |
| 979 | + | |
| 980 | +/* | |
| 981 | +** Zeroes out g.perm and calls login_set_capabilities(zCap,flags). | |
| 982 | +*/ | |
| 983 | +void login_replace_capabilities(const char *zCap, unsigned flags){ | |
| 984 | + memset(&g.perm, 0, sizeof(g.perm)); | |
| 985 | + return login_set_capabilities(zCap, flags); | |
| 986 | +} | |
| 867 | 987 | |
| 868 | 988 | /* |
| 869 | 989 | ** If the current login lacks any of the capabilities listed in |
| 870 | 990 | ** the input, then return 0. If all capabilities are present, then |
| 871 | 991 | ** return 1. |
| @@ -940,14 +1060,24 @@ | ||
| 940 | 1060 | /* |
| 941 | 1061 | ** Call this routine when the credential check fails. It causes |
| 942 | 1062 | ** a redirect to the "login" page. |
| 943 | 1063 | */ |
| 944 | 1064 | void login_needed(void){ |
| 945 | - const char *zUrl = PD("REQUEST_URI", "index"); | |
| 946 | - cgi_redirect(mprintf("login?g=%T", zUrl)); | |
| 947 | - /* NOTREACHED */ | |
| 948 | - assert(0); | |
| 1065 | +#ifdef FOSSIL_ENABLE_JSON | |
| 1066 | + if(g.json.isJsonMode){ | |
| 1067 | + json_err( FSL_JSON_E_DENIED, NULL, 1 ); | |
| 1068 | + fossil_exit(0); | |
| 1069 | + /* NOTREACHED */ | |
| 1070 | + assert(0); | |
| 1071 | + }else | |
| 1072 | +#endif /* FOSSIL_ENABLE_JSON */ | |
| 1073 | + { | |
| 1074 | + const char *zUrl = PD("REQUEST_URI", "index"); | |
| 1075 | + cgi_redirect(mprintf("login?g=%T", zUrl)); | |
| 1076 | + /* NOTREACHED */ | |
| 1077 | + assert(0); | |
| 1078 | + } | |
| 949 | 1079 | } |
| 950 | 1080 | |
| 951 | 1081 | /* |
| 952 | 1082 | ** Call this routine if the user lacks okHistory permission. If |
| 953 | 1083 | ** the anonymous user has okHistory permission, then paint a mesage |
| 954 | 1084 |
| --- src/login.c | |
| +++ src/login.c | |
| @@ -84,11 +84,11 @@ | |
| 84 | ** |
| 85 | ** The login cookie name is always of the form: fossil-XXXXXXXXXXXXXXXX |
| 86 | ** where the Xs are the first 16 characters of the login-group-code or |
| 87 | ** of the project-code if we are not a member of any login-group. |
| 88 | */ |
| 89 | static char *login_cookie_name(void){ |
| 90 | static char *zCookieName = 0; |
| 91 | if( zCookieName==0 ){ |
| 92 | zCookieName = db_text(0, |
| 93 | "SELECT 'fossil-' || substr(value,1,16)" |
| 94 | " FROM config" |
| @@ -146,24 +146,26 @@ | |
| 146 | |
| 147 | |
| 148 | /* |
| 149 | ** Check to see if the anonymous login is valid. If it is valid, return |
| 150 | ** the userid of the anonymous user. |
| 151 | */ |
| 152 | static int isValidAnonymousLogin( |
| 153 | const char *zUsername, /* The username. Must be "anonymous" */ |
| 154 | const char *zPassword /* The supplied password */ |
| 155 | ){ |
| 156 | const char *zCS; /* The captcha seed value */ |
| 157 | const char *zPw; /* The correct password shown in the captcha */ |
| 158 | int uid; /* The user ID of anonymous */ |
| 159 | |
| 160 | if( zUsername==0 ) return 0; |
| 161 | if( zPassword==0 ) return 0; |
| 162 | if( fossil_strcmp(zUsername,"anonymous")!=0 ) return 0; |
| 163 | zCS = P("cs"); /* The "cs" parameter is the "captcha seed" */ |
| 164 | if( zCS==0 ) return 0; |
| 165 | zPw = captcha_decode((unsigned int)atoi(zCS)); |
| 166 | if( fossil_stricmp(zPw, zPassword)!=0 ) return 0; |
| 167 | uid = db_int(0, "SELECT uid FROM user WHERE login='anonymous'" |
| 168 | " AND length(pw)>0 AND length(cap)>0"); |
| 169 | return uid; |
| @@ -197,10 +199,163 @@ | |
| 197 | "INSERT INTO accesslog(uname,ipaddr,success,mtime)" |
| 198 | "VALUES(%Q,%Q,%d,julianday('now'));", |
| 199 | zUsername, zIpAddr, bSuccess |
| 200 | ); |
| 201 | } |
| 202 | |
| 203 | /* |
| 204 | ** Look at the HTTP_USER_AGENT parameter and try to determine if the user agent |
| 205 | ** is a manually operated browser or a bot. When in doubt, assume a bot. Return |
| 206 | ** true if we believe the agent is a real person. |
| @@ -281,22 +436,19 @@ | |
| 281 | int anonFlag; |
| 282 | char *zErrMsg = ""; |
| 283 | int uid; /* User id loged in user */ |
| 284 | char *zSha1Pw; |
| 285 | const char *zIpAddr; /* IP address of requestor */ |
| 286 | char *zRemoteAddr; /* Abbreviated IP address of requestor */ |
| 287 | |
| 288 | login_check_credentials(); |
| 289 | sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0, |
| 290 | constant_time_cmp_function, 0, 0); |
| 291 | zUsername = P("u"); |
| 292 | zPasswd = P("p"); |
| 293 | anonFlag = P("anon")!=0; |
| 294 | if( P("out")!=0 ){ |
| 295 | /* To logout, change the cookie value to an empty string */ |
| 296 | const char *zCookieName = login_cookie_name(); |
| 297 | cgi_set_cookie(zCookieName, "", login_cookie_path(), -86400); |
| 298 | redirect_to_g(); |
| 299 | } |
| 300 | if( g.perm.Password && zPasswd |
| 301 | && (zNew1 = P("n1"))!=0 && (zNew2 = P("n2"))!=0 |
| 302 | ){ |
| @@ -344,50 +496,20 @@ | |
| 344 | return; |
| 345 | } |
| 346 | } |
| 347 | } |
| 348 | zIpAddr = PD("REMOTE_ADDR","nil"); /* Complete IP address for logging */ |
| 349 | zRemoteAddr = ipPrefix(zIpAddr); /* Abbreviated IP address */ |
| 350 | uid = isValidAnonymousLogin(zUsername, zPasswd); |
| 351 | if( uid>0 ){ |
| 352 | /* Successful login as anonymous. Set a cookie that looks like |
| 353 | ** this: |
| 354 | ** |
| 355 | ** HASH/TIME/anonymous |
| 356 | ** |
| 357 | ** Where HASH is the sha1sum of TIME/IPADDR/SECRET, in which IPADDR |
| 358 | ** is the abbreviated IP address and SECRET is captcha-secret. |
| 359 | */ |
| 360 | char *zNow; /* Current time (julian day number) */ |
| 361 | char *zCookie; /* The login cookie */ |
| 362 | const char *zCookieName; /* Name of the login cookie */ |
| 363 | Blob b; /* Blob used during cookie construction */ |
| 364 | |
| 365 | zCookieName = login_cookie_name(); |
| 366 | zNow = db_text("0", "SELECT julianday('now')"); |
| 367 | blob_init(&b, zNow, -1); |
| 368 | blob_appendf(&b, "/%s/%s", zRemoteAddr, db_get("captcha-secret","")); |
| 369 | sha1sum_blob(&b, &b); |
| 370 | zCookie = sqlite3_mprintf("%s/%s/anonymous", blob_buffer(&b), zNow); |
| 371 | blob_reset(&b); |
| 372 | free(zNow); |
| 373 | cgi_set_cookie(zCookieName, zCookie, login_cookie_path(), 6*3600); |
| 374 | record_login_attempt("anonymous", zIpAddr, 1); |
| 375 | redirect_to_g(); |
| 376 | } |
| 377 | if( zUsername!=0 && zPasswd!=0 && zPasswd[0]!=0 ){ |
| 378 | /* Attempting to log in as a user other than anonymous. |
| 379 | */ |
| 380 | zSha1Pw = sha1_shared_secret(zPasswd, zUsername, 0); |
| 381 | uid = db_int(0, |
| 382 | "SELECT uid FROM user" |
| 383 | " WHERE login=%Q" |
| 384 | " AND length(cap)>0 AND length(pw)>0" |
| 385 | " AND login NOT IN ('anonymous','nobody','developer','reader')" |
| 386 | " AND (constant_time_cmp(pw,%Q)=0 OR constant_time_cmp(pw,%Q)=0)", |
| 387 | zUsername, zSha1Pw, zPasswd |
| 388 | ); |
| 389 | if( uid<=0 ){ |
| 390 | sleep(1); |
| 391 | zErrMsg = |
| 392 | @ <p><span class="loginError"> |
| 393 | @ You entered an unknown user or an incorrect password. |
| @@ -400,26 +522,11 @@ | |
| 400 | ** HASH/PROJECT/LOGIN |
| 401 | ** |
| 402 | ** where HASH is a random hex number, PROJECT is either project |
| 403 | ** code prefix, and LOGIN is the user name. |
| 404 | */ |
| 405 | char *zCookie; |
| 406 | const char *zCookieName = login_cookie_name(); |
| 407 | const char *zExpire = db_get("cookie-expire","8766"); |
| 408 | int expires = atoi(zExpire)*3600; |
| 409 | char *zCode = abbreviated_project_code(db_get("project-code","")); |
| 410 | char *zHash; |
| 411 | |
| 412 | zHash = db_text(0, "SELECT hex(randomblob(25))"); |
| 413 | zCookie = mprintf("%s/%s/%s", zHash, zCode, zUsername); |
| 414 | cgi_set_cookie(zCookieName, zCookie, login_cookie_path(), expires); |
| 415 | record_login_attempt(zUsername, zIpAddr, 1); |
| 416 | db_multi_exec( |
| 417 | "UPDATE user SET cookie=%Q, ipaddr=%Q, " |
| 418 | " cexpire=julianday('now')+%d/86400.0 WHERE uid=%d", |
| 419 | zHash, zRemoteAddr, expires, uid |
| 420 | ); |
| 421 | redirect_to_g(); |
| 422 | } |
| 423 | } |
| 424 | style_header("Login/Logout"); |
| 425 | @ %s(zErrMsg) |
| @@ -586,12 +693,16 @@ | |
| 586 | fossil_free(zOtherRepo); |
| 587 | return nXfer; |
| 588 | } |
| 589 | |
| 590 | /* |
| 591 | ** Lookup the uid for a user with zLogin and zCookie and zRemoteAddr. |
| 592 | ** Return 0 if not found. |
| 593 | */ |
| 594 | static int login_find_user( |
| 595 | const char *zLogin, /* User name */ |
| 596 | const char *zCookie, /* Login cookie value */ |
| 597 | const char *zRemoteAddr /* Abbreviated IP address for valid login */ |
| @@ -613,16 +724,14 @@ | |
| 613 | ); |
| 614 | return uid; |
| 615 | } |
| 616 | |
| 617 | /* |
| 618 | ** This routine examines the login cookie to see if it exists and |
| 619 | ** and is valid. If the login cookie checks out, it then sets |
| 620 | ** global variables appropriately. Global variables set include |
| 621 | ** g.userUid and g.zLogin and of the g.perm.Read family of permission |
| 622 | ** booleans. |
| 623 | ** |
| 624 | */ |
| 625 | void login_check_credentials(void){ |
| 626 | int uid = 0; /* User id */ |
| 627 | const char *zCookie; /* Text of the login cookie */ |
| 628 | const char *zIpAddr; /* Raw IP address of the requestor */ |
| @@ -710,11 +819,11 @@ | |
| 710 | } |
| 711 | sqlite3_snprintf(sizeof(g.zCsrfToken), g.zCsrfToken, "%.10s", zHash); |
| 712 | } |
| 713 | |
| 714 | /* If no user found and the REMOTE_USER environment variable is set, |
| 715 | ** the accept the value of REMOTE_USER as the user. |
| 716 | */ |
| 717 | if( uid==0 ){ |
| 718 | const char *zRemoteUser = P("REMOTE_USER"); |
| 719 | if( zRemoteUser && db_get_boolean("remote_user_ok",0) ){ |
| 720 | uid = db_int(0, "SELECT uid FROM user WHERE login=%Q" |
| @@ -760,11 +869,11 @@ | |
| 760 | if( fossil_strcmp(g.zLogin,"nobody")==0 ){ |
| 761 | g.zLogin = 0; |
| 762 | } |
| 763 | |
| 764 | /* Set the capabilities */ |
| 765 | login_set_capabilities(zCap, 0); |
| 766 | login_set_anon_nobody_capabilities(); |
| 767 | if( zCap[0] && !g.perm.History && db_get_boolean("auto-enable-hyperlinks",1) |
| 768 | && isHuman(P("HTTP_USER_AGENT")) ){ |
| 769 | g.perm.History = 1; |
| 770 | } |
| @@ -793,22 +902,25 @@ | |
| 793 | login_anon_once = 0; |
| 794 | } |
| 795 | } |
| 796 | |
| 797 | /* |
| 798 | ** Flags passed into the 2nd argument of login_set_capabilities(). |
| 799 | */ |
| 800 | #if INTERFACE |
| 801 | #define LOGIN_IGNORE_U 0x01 /* Ignore "u" */ |
| 802 | #define LOGIN_IGNORE_V 0x01 /* Ignore "v" */ |
| 803 | #endif |
| 804 | |
| 805 | /* |
| 806 | ** Set the global capability flags based on a capability string. |
| 807 | */ |
| 808 | void login_set_capabilities(const char *zCap, unsigned flags){ |
| 809 | int i; |
| 810 | for(i=0; zCap[i]; i++){ |
| 811 | switch( zCap[i] ){ |
| 812 | case 's': g.perm.Setup = 1; /* Fall thru into Admin */ |
| 813 | case 'a': g.perm.Admin = g.perm.RdTkt = g.perm.WrTkt = g.perm.Zip = |
| 814 | g.perm.RdWiki = g.perm.WrWiki = g.perm.NewWiki = |
| @@ -862,10 +974,18 @@ | |
| 862 | break; |
| 863 | } |
| 864 | } |
| 865 | } |
| 866 | } |
| 867 | |
| 868 | /* |
| 869 | ** If the current login lacks any of the capabilities listed in |
| 870 | ** the input, then return 0. If all capabilities are present, then |
| 871 | ** return 1. |
| @@ -940,14 +1060,24 @@ | |
| 940 | /* |
| 941 | ** Call this routine when the credential check fails. It causes |
| 942 | ** a redirect to the "login" page. |
| 943 | */ |
| 944 | void login_needed(void){ |
| 945 | const char *zUrl = PD("REQUEST_URI", "index"); |
| 946 | cgi_redirect(mprintf("login?g=%T", zUrl)); |
| 947 | /* NOTREACHED */ |
| 948 | assert(0); |
| 949 | } |
| 950 | |
| 951 | /* |
| 952 | ** Call this routine if the user lacks okHistory permission. If |
| 953 | ** the anonymous user has okHistory permission, then paint a mesage |
| 954 |
| --- src/login.c | |
| +++ src/login.c | |
| @@ -84,11 +84,11 @@ | |
| 84 | ** |
| 85 | ** The login cookie name is always of the form: fossil-XXXXXXXXXXXXXXXX |
| 86 | ** where the Xs are the first 16 characters of the login-group-code or |
| 87 | ** of the project-code if we are not a member of any login-group. |
| 88 | */ |
| 89 | char *login_cookie_name(void){ |
| 90 | static char *zCookieName = 0; |
| 91 | if( zCookieName==0 ){ |
| 92 | zCookieName = db_text(0, |
| 93 | "SELECT 'fossil-' || substr(value,1,16)" |
| 94 | " FROM config" |
| @@ -146,24 +146,26 @@ | |
| 146 | |
| 147 | |
| 148 | /* |
| 149 | ** Check to see if the anonymous login is valid. If it is valid, return |
| 150 | ** the userid of the anonymous user. |
| 151 | ** |
| 152 | ** The zCS parameter is the "captcha seed" used for a specific |
| 153 | ** anonymous login request. |
| 154 | */ |
| 155 | int login_is_valid_anonymous( |
| 156 | const char *zUsername, /* The username. Must be "anonymous" */ |
| 157 | const char *zPassword, /* The supplied password */ |
| 158 | const char *zCS /* The captcha seed value */ |
| 159 | ){ |
| 160 | const char *zPw; /* The correct password shown in the captcha */ |
| 161 | int uid; /* The user ID of anonymous */ |
| 162 | |
| 163 | if( zUsername==0 ) return 0; |
| 164 | else if( zPassword==0 ) return 0; |
| 165 | else if( zCS==0 ) return 0; |
| 166 | else if( fossil_strcmp(zUsername,"anonymous")!=0 ) return 0; |
| 167 | zPw = captcha_decode((unsigned int)atoi(zCS)); |
| 168 | if( fossil_stricmp(zPw, zPassword)!=0 ) return 0; |
| 169 | uid = db_int(0, "SELECT uid FROM user WHERE login='anonymous'" |
| 170 | " AND length(pw)>0 AND length(cap)>0"); |
| 171 | return uid; |
| @@ -197,10 +199,163 @@ | |
| 199 | "INSERT INTO accesslog(uname,ipaddr,success,mtime)" |
| 200 | "VALUES(%Q,%Q,%d,julianday('now'));", |
| 201 | zUsername, zIpAddr, bSuccess |
| 202 | ); |
| 203 | } |
| 204 | |
| 205 | /* |
| 206 | ** Searches for the user ID matching the given name and password. |
| 207 | ** On success it returns a positive value. On error it returns 0. |
| 208 | ** On serious (DB-level) error it will probably exit. |
| 209 | ** |
| 210 | ** zPassword may be either the plain-text form or the encrypted |
| 211 | ** form of the user's password. |
| 212 | */ |
| 213 | int login_search_uid(char const *zUsername, char const *zPasswd){ |
| 214 | char * zSha1Pw = sha1_shared_secret(zPasswd, zUsername, 0); |
| 215 | int const uid = |
| 216 | db_int(0, |
| 217 | "SELECT uid FROM user" |
| 218 | " WHERE login=%Q" |
| 219 | " AND length(cap)>0 AND length(pw)>0" |
| 220 | " AND login NOT IN ('anonymous','nobody','developer','reader')" |
| 221 | " AND (pw=%Q OR pw=%Q)", |
| 222 | zUsername, zPasswd, zSha1Pw |
| 223 | ); |
| 224 | free(zSha1Pw); |
| 225 | return uid; |
| 226 | } |
| 227 | |
| 228 | /* |
| 229 | ** Generates a login cookie value for a non-anonymous user. |
| 230 | ** |
| 231 | ** The zHash parameter must be a random value which must be |
| 232 | ** subsequently stored in user.cookie for later validation. |
| 233 | ** |
| 234 | ** The returned memory should be free()d after use. |
| 235 | */ |
| 236 | char * login_gen_user_cookie_value(char const *zUsername, char const * zHash){ |
| 237 | char * zProjCode = db_get("project-code",NULL); |
| 238 | char *zCode = abbreviated_project_code(zProjCode); |
| 239 | free(zProjCode); |
| 240 | assert((zUsername && *zUsername) && "Invalid user data."); |
| 241 | return mprintf("%s/%z/%s", zHash, zCode, zUsername); |
| 242 | } |
| 243 | |
| 244 | /* |
| 245 | ** Generates a login cookie for NON-ANONYMOUS users. Note that this |
| 246 | ** function "could" figure out the uid by itself but it currently |
| 247 | ** doesn't because the code which calls this already has the uid. |
| 248 | ** |
| 249 | ** This function also updates the user.cookie, user.ipaddr, |
| 250 | ** and user.cexpire fields for the given user. |
| 251 | ** |
| 252 | ** If zDest is not NULL then the generated cookie is copied to |
| 253 | ** *zDdest and ownership is transfered to the caller (who should |
| 254 | ** eventually pass it to free()). |
| 255 | */ |
| 256 | void login_set_user_cookie( |
| 257 | char const * zUsername, /* User's name */ |
| 258 | int uid, /* User's ID */ |
| 259 | char ** zDest /* Optional: store generated cookie value. */ |
| 260 | ){ |
| 261 | const char *zCookieName = login_cookie_name(); |
| 262 | const char *zExpire = db_get("cookie-expire","8766"); |
| 263 | int expires = atoi(zExpire)*3600; |
| 264 | char *zHash; |
| 265 | char *zCookie; |
| 266 | char const * zIpAddr = PD("REMOTE_ADDR","nil"); /* Complete IP address for logging */ |
| 267 | char * zRemoteAddr = ipPrefix(zIpAddr); /* Abbreviated IP address */ |
| 268 | assert((zUsername && *zUsername) && (uid > 0) && "Invalid user data."); |
| 269 | zHash = db_text(0, "SELECT hex(randomblob(25))"); |
| 270 | zCookie = login_gen_user_cookie_value(zUsername, zHash); |
| 271 | cgi_set_cookie(zCookieName, zCookie, login_cookie_path(), expires); |
| 272 | record_login_attempt(zUsername, zIpAddr, 1); |
| 273 | db_multi_exec( |
| 274 | "UPDATE user SET cookie=%Q, ipaddr=%Q, " |
| 275 | " cexpire=julianday('now')+%d/86400.0 WHERE uid=%d", |
| 276 | zHash, zRemoteAddr, expires, uid |
| 277 | ); |
| 278 | free(zRemoteAddr); |
| 279 | free(zHash); |
| 280 | if( zDest ){ |
| 281 | *zDest = zCookie; |
| 282 | }else{ |
| 283 | free(zCookie); |
| 284 | } |
| 285 | } |
| 286 | |
| 287 | /* Sets a cookie for an anonymous user login, which looks like this: |
| 288 | ** |
| 289 | ** HASH/TIME/anonymous |
| 290 | ** |
| 291 | ** Where HASH is the sha1sum of TIME/IPADDR/SECRET, in which IPADDR |
| 292 | ** is the abbreviated IP address and SECRET is captcha-secret. |
| 293 | ** |
| 294 | ** If either zIpAddr or zRemoteAddr are NULL then REMOTE_ADDR |
| 295 | ** is used. |
| 296 | ** |
| 297 | ** If zCookieDest is not NULL then the generated cookie is assigned to |
| 298 | ** *zCookieDest and the caller must eventually free() it. |
| 299 | */ |
| 300 | void login_set_anon_cookie(char const * zIpAddr, char ** zCookieDest ){ |
| 301 | char const *zNow; /* Current time (julian day number) */ |
| 302 | char *zCookie; /* The login cookie */ |
| 303 | char const *zCookieName; /* Name of the login cookie */ |
| 304 | Blob b; /* Blob used during cookie construction */ |
| 305 | char * zRemoteAddr; /* Abbreviated IP address */ |
| 306 | if(!zIpAddr){ |
| 307 | zIpAddr = PD("REMOTE_ADDR","nil"); |
| 308 | } |
| 309 | zRemoteAddr = ipPrefix(zIpAddr); |
| 310 | zCookieName = login_cookie_name(); |
| 311 | zNow = db_text("0", "SELECT julianday('now')"); |
| 312 | assert( zCookieName && zRemoteAddr && zIpAddr && zNow ); |
| 313 | blob_init(&b, zNow, -1); |
| 314 | blob_appendf(&b, "/%s/%s", zRemoteAddr, db_get("captcha-secret","")); |
| 315 | sha1sum_blob(&b, &b); |
| 316 | zCookie = mprintf("%s/%s/anonymous", blob_buffer(&b), zNow); |
| 317 | blob_reset(&b); |
| 318 | cgi_set_cookie(zCookieName, zCookie, login_cookie_path(), 6*3600); |
| 319 | if( zCookieDest ){ |
| 320 | *zCookieDest = zCookie; |
| 321 | }else{ |
| 322 | free(zCookie); |
| 323 | } |
| 324 | |
| 325 | } |
| 326 | |
| 327 | /* |
| 328 | ** "Unsets" the login cookie (insofar as cookies can be unset) and |
| 329 | ** clears the current user's (g.userUid) login information from the |
| 330 | ** user table. Sets: user.cookie, user.ipaddr, user.cexpire. |
| 331 | ** |
| 332 | ** We could/should arguably clear out g.userUid and g.perm here, but |
| 333 | ** we don't currently do not. |
| 334 | ** |
| 335 | ** This is a no-op if g.userUid is 0. |
| 336 | */ |
| 337 | void login_clear_login_data(){ |
| 338 | if(!g.userUid){ |
| 339 | return; |
| 340 | }else{ |
| 341 | char const * cookie = login_cookie_name(); |
| 342 | /* To logout, change the cookie value to an empty string */ |
| 343 | cgi_set_cookie(cookie, "", |
| 344 | login_cookie_path(), -86400); |
| 345 | db_multi_exec("UPDATE user SET cookie=NULL, ipaddr=NULL, " |
| 346 | " cexpire=0 WHERE uid=%d" |
| 347 | " AND login NOT IN ('anonymous','nobody'," |
| 348 | " 'developer','reader')", g.userUid); |
| 349 | cgi_replace_parameter(cookie, NULL) |
| 350 | /* At the time of this writing, cgi_replace_parameter() was |
| 351 | ** "NULL-value-safe", and i'm hoping the NULL doesn't cause any |
| 352 | ** downstream problems here. We could alternately use "" here. |
| 353 | */ |
| 354 | ; |
| 355 | } |
| 356 | } |
| 357 | |
| 358 | /* |
| 359 | ** Look at the HTTP_USER_AGENT parameter and try to determine if the user agent |
| 360 | ** is a manually operated browser or a bot. When in doubt, assume a bot. Return |
| 361 | ** true if we believe the agent is a real person. |
| @@ -281,22 +436,19 @@ | |
| 436 | int anonFlag; |
| 437 | char *zErrMsg = ""; |
| 438 | int uid; /* User id loged in user */ |
| 439 | char *zSha1Pw; |
| 440 | const char *zIpAddr; /* IP address of requestor */ |
| 441 | |
| 442 | login_check_credentials(); |
| 443 | sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0, |
| 444 | constant_time_cmp_function, 0, 0); |
| 445 | zUsername = P("u"); |
| 446 | zPasswd = P("p"); |
| 447 | anonFlag = P("anon")!=0; |
| 448 | if( P("out")!=0 ){ |
| 449 | login_clear_login_data(); |
| 450 | redirect_to_g(); |
| 451 | } |
| 452 | if( g.perm.Password && zPasswd |
| 453 | && (zNew1 = P("n1"))!=0 && (zNew2 = P("n2"))!=0 |
| 454 | ){ |
| @@ -344,50 +496,20 @@ | |
| 496 | return; |
| 497 | } |
| 498 | } |
| 499 | } |
| 500 | zIpAddr = PD("REMOTE_ADDR","nil"); /* Complete IP address for logging */ |
| 501 | uid = login_is_valid_anonymous(zUsername, zPasswd, P("cs")); |
| 502 | if( uid>0 ){ |
| 503 | login_set_anon_cookie(zIpAddr, NULL); |
| 504 | record_login_attempt("anonymous", zIpAddr, 1); |
| 505 | redirect_to_g(); |
| 506 | } |
| 507 | if( zUsername!=0 && zPasswd!=0 && zPasswd[0]!=0 ){ |
| 508 | /* Attempting to log in as a user other than anonymous. |
| 509 | */ |
| 510 | uid = login_search_uid(zUsername, zPasswd); |
| 511 | if( uid<=0 ){ |
| 512 | sleep(1); |
| 513 | zErrMsg = |
| 514 | @ <p><span class="loginError"> |
| 515 | @ You entered an unknown user or an incorrect password. |
| @@ -400,26 +522,11 @@ | |
| 522 | ** HASH/PROJECT/LOGIN |
| 523 | ** |
| 524 | ** where HASH is a random hex number, PROJECT is either project |
| 525 | ** code prefix, and LOGIN is the user name. |
| 526 | */ |
| 527 | login_set_user_cookie(zUsername, uid, NULL); |
| 528 | redirect_to_g(); |
| 529 | } |
| 530 | } |
| 531 | style_header("Login/Logout"); |
| 532 | @ %s(zErrMsg) |
| @@ -586,12 +693,16 @@ | |
| 693 | fossil_free(zOtherRepo); |
| 694 | return nXfer; |
| 695 | } |
| 696 | |
| 697 | /* |
| 698 | ** Lookup the uid for a non-built-in user with zLogin and zCookie and |
| 699 | ** zRemoteAddr. Return 0 if not found. |
| 700 | ** |
| 701 | ** Note that this only searches for logged-in entries with matching |
| 702 | ** zCookie (db: user.cookie) and zRemoteAddr (db: user.ipaddr) |
| 703 | ** entries. |
| 704 | */ |
| 705 | static int login_find_user( |
| 706 | const char *zLogin, /* User name */ |
| 707 | const char *zCookie, /* Login cookie value */ |
| 708 | const char *zRemoteAddr /* Abbreviated IP address for valid login */ |
| @@ -613,16 +724,14 @@ | |
| 724 | ); |
| 725 | return uid; |
| 726 | } |
| 727 | |
| 728 | /* |
| 729 | ** This routine examines the login cookie to see if it exists and and |
| 730 | ** is valid. If the login cookie checks out, it then sets global |
| 731 | ** variables appropriately. Global variables set include g.userUid |
| 732 | ** and g.zLogin and the g.perm family of permission booleans. |
| 733 | */ |
| 734 | void login_check_credentials(void){ |
| 735 | int uid = 0; /* User id */ |
| 736 | const char *zCookie; /* Text of the login cookie */ |
| 737 | const char *zIpAddr; /* Raw IP address of the requestor */ |
| @@ -710,11 +819,11 @@ | |
| 819 | } |
| 820 | sqlite3_snprintf(sizeof(g.zCsrfToken), g.zCsrfToken, "%.10s", zHash); |
| 821 | } |
| 822 | |
| 823 | /* If no user found and the REMOTE_USER environment variable is set, |
| 824 | ** then accept the value of REMOTE_USER as the user. |
| 825 | */ |
| 826 | if( uid==0 ){ |
| 827 | const char *zRemoteUser = P("REMOTE_USER"); |
| 828 | if( zRemoteUser && db_get_boolean("remote_user_ok",0) ){ |
| 829 | uid = db_int(0, "SELECT uid FROM user WHERE login=%Q" |
| @@ -760,11 +869,11 @@ | |
| 869 | if( fossil_strcmp(g.zLogin,"nobody")==0 ){ |
| 870 | g.zLogin = 0; |
| 871 | } |
| 872 | |
| 873 | /* Set the capabilities */ |
| 874 | login_replace_capabilities(zCap, 0); |
| 875 | login_set_anon_nobody_capabilities(); |
| 876 | if( zCap[0] && !g.perm.History && db_get_boolean("auto-enable-hyperlinks",1) |
| 877 | && isHuman(P("HTTP_USER_AGENT")) ){ |
| 878 | g.perm.History = 1; |
| 879 | } |
| @@ -793,22 +902,25 @@ | |
| 902 | login_anon_once = 0; |
| 903 | } |
| 904 | } |
| 905 | |
| 906 | /* |
| 907 | ** Flags passed into the 2nd argument of login_set/replace_capabilities(). |
| 908 | */ |
| 909 | #if INTERFACE |
| 910 | #define LOGIN_IGNORE_U 0x01 /* Ignore "u" */ |
| 911 | #define LOGIN_IGNORE_V 0x01 /* Ignore "v" */ |
| 912 | #endif |
| 913 | |
| 914 | /* |
| 915 | ** Adds all capability flags in zCap to g.perm. |
| 916 | */ |
| 917 | void login_set_capabilities(const char *zCap, unsigned flags){ |
| 918 | int i; |
| 919 | if(NULL==zCap){ |
| 920 | return; |
| 921 | } |
| 922 | for(i=0; zCap[i]; i++){ |
| 923 | switch( zCap[i] ){ |
| 924 | case 's': g.perm.Setup = 1; /* Fall thru into Admin */ |
| 925 | case 'a': g.perm.Admin = g.perm.RdTkt = g.perm.WrTkt = g.perm.Zip = |
| 926 | g.perm.RdWiki = g.perm.WrWiki = g.perm.NewWiki = |
| @@ -862,10 +974,18 @@ | |
| 974 | break; |
| 975 | } |
| 976 | } |
| 977 | } |
| 978 | } |
| 979 | |
| 980 | /* |
| 981 | ** Zeroes out g.perm and calls login_set_capabilities(zCap,flags). |
| 982 | */ |
| 983 | void login_replace_capabilities(const char *zCap, unsigned flags){ |
| 984 | memset(&g.perm, 0, sizeof(g.perm)); |
| 985 | return login_set_capabilities(zCap, flags); |
| 986 | } |
| 987 | |
| 988 | /* |
| 989 | ** If the current login lacks any of the capabilities listed in |
| 990 | ** the input, then return 0. If all capabilities are present, then |
| 991 | ** return 1. |
| @@ -940,14 +1060,24 @@ | |
| 1060 | /* |
| 1061 | ** Call this routine when the credential check fails. It causes |
| 1062 | ** a redirect to the "login" page. |
| 1063 | */ |
| 1064 | void login_needed(void){ |
| 1065 | #ifdef FOSSIL_ENABLE_JSON |
| 1066 | if(g.json.isJsonMode){ |
| 1067 | json_err( FSL_JSON_E_DENIED, NULL, 1 ); |
| 1068 | fossil_exit(0); |
| 1069 | /* NOTREACHED */ |
| 1070 | assert(0); |
| 1071 | }else |
| 1072 | #endif /* FOSSIL_ENABLE_JSON */ |
| 1073 | { |
| 1074 | const char *zUrl = PD("REQUEST_URI", "index"); |
| 1075 | cgi_redirect(mprintf("login?g=%T", zUrl)); |
| 1076 | /* NOTREACHED */ |
| 1077 | assert(0); |
| 1078 | } |
| 1079 | } |
| 1080 | |
| 1081 | /* |
| 1082 | ** Call this routine if the user lacks okHistory permission. If |
| 1083 | ** the anonymous user has okHistory permission, then paint a mesage |
| 1084 |
+209
-42
| --- src/main.c | ||
| +++ src/main.c | ||
| @@ -23,14 +23,17 @@ | ||
| 23 | 23 | #include <string.h> |
| 24 | 24 | #include <time.h> |
| 25 | 25 | #include <fcntl.h> |
| 26 | 26 | #include <sys/types.h> |
| 27 | 27 | #include <sys/stat.h> |
| 28 | - | |
| 28 | +#include <stdlib.h> /* atexit() */ | |
| 29 | 29 | |
| 30 | 30 | #if INTERFACE |
| 31 | - | |
| 31 | +#ifdef FOSSIL_ENABLE_JSON | |
| 32 | +# include "cson_amalgamation.h" /* JSON API. Needed inside the INTERFACE block! */ | |
| 33 | +# include "json_detail.h" | |
| 34 | +#endif | |
| 32 | 35 | #ifdef FOSSIL_ENABLE_TCL |
| 33 | 36 | #include "tcl.h" |
| 34 | 37 | #endif |
| 35 | 38 | |
| 36 | 39 | /* |
| @@ -132,10 +135,11 @@ | ||
| 132 | 135 | int xlinkClusterOnly; /* Set when cloning. Only process clusters */ |
| 133 | 136 | int fTimeFormat; /* 1 for UTC. 2 for localtime. 0 not yet selected */ |
| 134 | 137 | int *aCommitFile; /* Array of files to be committed */ |
| 135 | 138 | int markPrivate; /* All new artifacts are private if true */ |
| 136 | 139 | int clockSkewSeen; /* True if clocks on client and server out of sync */ |
| 140 | + int isHTTP; /* True if running in server/CGI modes, else assume CLI. */ | |
| 137 | 141 | |
| 138 | 142 | int urlIsFile; /* True if a "file:" url */ |
| 139 | 143 | int urlIsHttps; /* True if a "https:" url */ |
| 140 | 144 | int urlIsSsh; /* True if an "ssh:" url */ |
| 141 | 145 | char *urlName; /* Hostname for http: or filename for file: */ |
| @@ -148,11 +152,11 @@ | ||
| 148 | 152 | char *urlPasswd; /* Password for http: */ |
| 149 | 153 | char *urlCanonical; /* Canonical representation of the URL */ |
| 150 | 154 | char *urlProxyAuth; /* Proxy-Authorizer: string */ |
| 151 | 155 | char *urlFossil; /* The path of the ?fossil=path suffix on ssh: */ |
| 152 | 156 | int dontKeepUrl; /* Do not persist the URL */ |
| 153 | - | |
| 157 | + | |
| 154 | 158 | const char *zLogin; /* Login name. "" if not logged in. */ |
| 155 | 159 | const char *zSSLIdentity; /* Value of --ssl-identity option, filename of SSL client identity */ |
| 156 | 160 | int useLocalauth; /* No login required if from 127.0.0.1 */ |
| 157 | 161 | int noPswd; /* Logged in without password (on 127.0.0.1) */ |
| 158 | 162 | int userUid; /* Integer user id */ |
| @@ -188,10 +192,66 @@ | ||
| 188 | 192 | const char *azAuxVal[MX_AUX]; /* Value of each aux() or option() value */ |
| 189 | 193 | const char **azAuxOpt[MX_AUX]; /* Options of each option() value */ |
| 190 | 194 | int anAuxCols[MX_AUX]; /* Number of columns for option() values */ |
| 191 | 195 | |
| 192 | 196 | int allowSymlinks; /* Cached "allow-symlinks" option */ |
| 197 | + | |
| 198 | +#ifdef FOSSIL_ENABLE_JSON | |
| 199 | + struct FossilJsonBits { | |
| 200 | + int isJsonMode; /* True if running in JSON mode, else | |
| 201 | + false. This changes how errors are | |
| 202 | + reported. In JSON mode we try to | |
| 203 | + always output JSON-form error | |
| 204 | + responses and always exit() with | |
| 205 | + code 0 to avoid an HTTP 500 error. | |
| 206 | + */ | |
| 207 | + int resultCode; /* used for passing back specific codes from /json callbacks. */ | |
| 208 | + int errorDetailParanoia; /* 0=full error codes, 1=%10, 2=%100, 3=%1000 */ | |
| 209 | + cson_output_opt outOpt; /* formatting options for JSON mode. */ | |
| 210 | + cson_value * authToken; /* authentication token */ | |
| 211 | + char const * jsonp; /* Name of JSONP function wrapper. */ | |
| 212 | + unsigned char dispatchDepth /* Tells JSON command dispatching | |
| 213 | + which argument we are currently | |
| 214 | + working on. For this purpose, arg#0 | |
| 215 | + is the "json" path/CLI arg. | |
| 216 | + */; | |
| 217 | + struct { /* "garbage collector" */ | |
| 218 | + cson_value * v; | |
| 219 | + cson_array * a; | |
| 220 | + } gc; | |
| 221 | + struct { /* JSON POST data. */ | |
| 222 | + cson_value * v; | |
| 223 | + cson_array * a; | |
| 224 | + int offset; /* Tells us which PATH_INFO/CLI args | |
| 225 | + part holds the "json" command, so | |
| 226 | + that we can account for sub-repos | |
| 227 | + and path prefixes. This is handled | |
| 228 | + differently for CLI and CGI modes. | |
| 229 | + */ | |
| 230 | + char const * commandStr /*"command" request param.*/; | |
| 231 | + } cmd; | |
| 232 | + struct { /* JSON POST data. */ | |
| 233 | + cson_value * v; | |
| 234 | + cson_object * o; | |
| 235 | + } post; | |
| 236 | + struct { /* GET/COOKIE params in JSON mode. | |
| 237 | + FIXME (stephan): verify that this is | |
| 238 | + still used and remove if it is not. | |
| 239 | + */ | |
| 240 | + cson_value * v; | |
| 241 | + cson_object * o; | |
| 242 | + } param; | |
| 243 | + struct { | |
| 244 | + cson_value * v; | |
| 245 | + cson_object * o; | |
| 246 | + } reqPayload; /* request payload object (if any) */ | |
| 247 | + struct { /* response warnings */ | |
| 248 | + cson_value * v; | |
| 249 | + cson_array * a; | |
| 250 | + } warnings; | |
| 251 | + } json; | |
| 252 | +#endif /* FOSSIL_ENABLE_JSON */ | |
| 193 | 253 | }; |
| 194 | 254 | |
| 195 | 255 | /* |
| 196 | 256 | ** Macro for debugging: |
| 197 | 257 | */ |
| @@ -252,10 +312,25 @@ | ||
| 252 | 312 | *pIndex = m; |
| 253 | 313 | return 0; |
| 254 | 314 | } |
| 255 | 315 | return 1+(cnt>1); |
| 256 | 316 | } |
| 317 | + | |
| 318 | +/* | |
| 319 | +** atexit() handler which frees up "some" of the resources | |
| 320 | +** used by fossil. | |
| 321 | +*/ | |
| 322 | +void fossil_atexit() { | |
| 323 | +#ifdef FOSSIL_ENABLE_JSON | |
| 324 | + cson_value_free(g.json.gc.v); | |
| 325 | + memset(&g.json, 0, sizeof(g.json)); | |
| 326 | +#endif | |
| 327 | + free(g.zErrMsg); | |
| 328 | + if(g.db){ | |
| 329 | + db_close(0); | |
| 330 | + } | |
| 331 | +} | |
| 257 | 332 | |
| 258 | 333 | /* |
| 259 | 334 | ** Search g.argv for arguments "--args FILENAME". If found, then |
| 260 | 335 | ** (1) remove the two arguments from g.argv |
| 261 | 336 | ** (2) Read the file FILENAME |
| @@ -343,28 +418,44 @@ | ||
| 343 | 418 | g.tcl.argv = argv; |
| 344 | 419 | g.tcl.interp = 0; |
| 345 | 420 | #endif |
| 346 | 421 | |
| 347 | 422 | sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0); |
| 423 | + memset(&g, 0, sizeof(g)); | |
| 348 | 424 | g.now = time(0); |
| 349 | 425 | g.argc = argc; |
| 350 | 426 | g.argv = argv; |
| 427 | +#ifdef FOSSIL_ENABLE_JSON | |
| 428 | +#if defined(NDEBUG) | |
| 429 | + g.json.errorDetailParanoia = 2 /* FIXME: make configurable | |
| 430 | + One problem we have here is that this | |
| 431 | + code is needed before the db is opened, | |
| 432 | + so we can't sql for it.*/; | |
| 433 | +#else | |
| 434 | + g.json.errorDetailParanoia = 0; | |
| 435 | +#endif | |
| 436 | + g.json.outOpt = cson_output_opt_empty; | |
| 437 | + g.json.outOpt.addNewline = 1; | |
| 438 | + g.json.outOpt.indentation = 1 /* in CGI/server mode this can be configured */; | |
| 439 | +#endif /* FOSSIL_ENABLE_JSON */ | |
| 351 | 440 | expand_args_option(); |
| 352 | 441 | argc = g.argc; |
| 353 | 442 | argv = g.argv; |
| 354 | 443 | for(i=0; i<argc; i++) g.argv[i] = fossil_mbcs_to_utf8(argv[i]); |
| 355 | 444 | if( getenv("GATEWAY_INTERFACE")!=0 && !find_option("nocgi", 0, 0)){ |
| 356 | 445 | zCmdName = "cgi"; |
| 446 | + g.isHTTP = 1; | |
| 357 | 447 | }else if( argc<2 ){ |
| 358 | 448 | fossil_print( |
| 359 | 449 | "Usage: %s COMMAND ...\n" |
| 360 | 450 | " or: %s help -- for a list of common commands\n" |
| 361 | 451 | " or: %s help COMMMAND -- for help with the named command\n" |
| 362 | 452 | " or: %s commands -- for a list of all commands\n", |
| 363 | 453 | argv[0], argv[0], argv[0], argv[0]); |
| 364 | 454 | fossil_exit(1); |
| 365 | 455 | }else{ |
| 456 | + g.isHTTP = 0; | |
| 366 | 457 | g.fQuiet = find_option("quiet", 0, 0)!=0; |
| 367 | 458 | g.fSqlTrace = find_option("sqltrace", 0, 0)!=0; |
| 368 | 459 | g.fSqlStats = find_option("sqlstats", 0, 0)!=0; |
| 369 | 460 | g.fSystemTrace = find_option("systemtrace", 0, 0)!=0; |
| 370 | 461 | if( g.fSqlTrace ) g.fSqlStats = 1; |
| @@ -405,10 +496,11 @@ | ||
| 405 | 496 | "%s: could be any of:%s\n" |
| 406 | 497 | "%s: use \"help\" for more information\n", |
| 407 | 498 | argv[0], zCmdName, argv[0], blob_str(&couldbe), argv[0]); |
| 408 | 499 | fossil_exit(1); |
| 409 | 500 | } |
| 501 | + atexit( fossil_atexit ); | |
| 410 | 502 | aCommand[idx].xFunc(); |
| 411 | 503 | fossil_exit(0); |
| 412 | 504 | /*NOT_REACHED*/ |
| 413 | 505 | return 0; |
| 414 | 506 | } |
| @@ -444,43 +536,70 @@ | ||
| 444 | 536 | ** routines never return. |
| 445 | 537 | */ |
| 446 | 538 | NORETURN void fossil_panic(const char *zFormat, ...){ |
| 447 | 539 | char *z; |
| 448 | 540 | va_list ap; |
| 541 | + int rc = 1; | |
| 449 | 542 | static int once = 1; |
| 450 | 543 | mainInFatalError = 1; |
| 451 | 544 | va_start(ap, zFormat); |
| 452 | 545 | z = vmprintf(zFormat, ap); |
| 453 | 546 | va_end(ap); |
| 454 | - if( g.cgiOutput && once ){ | |
| 455 | - once = 0; | |
| 456 | - cgi_printf("<p class=\"generalError\">%h</p>", z); | |
| 457 | - cgi_reply(); | |
| 458 | - }else{ | |
| 459 | - char *zOut = mprintf("%s: %s\n", fossil_nameofexe(), z); | |
| 460 | - fossil_puts(zOut, 1); | |
| 461 | - } | |
| 547 | +#ifdef FOSSIL_ENABLE_JSON | |
| 548 | + if( g.json.isJsonMode ){ | |
| 549 | + json_err( 0, z, 1 ); | |
| 550 | + if( g.isHTTP ){ | |
| 551 | + rc = 0 /* avoid HTTP 500 */; | |
| 552 | + } | |
| 553 | + } | |
| 554 | + else | |
| 555 | +#endif | |
| 556 | + { | |
| 557 | + if( g.cgiOutput && once ){ | |
| 558 | + once = 0; | |
| 559 | + cgi_printf("<p class=\"generalError\">%h</p>", z); | |
| 560 | + cgi_reply(); | |
| 561 | + }else{ | |
| 562 | + char *zOut = mprintf("%s: %s\n", fossil_nameofexe(), z); | |
| 563 | + fossil_puts(zOut, 1); | |
| 564 | + } | |
| 565 | + } | |
| 566 | + free(z); | |
| 462 | 567 | db_force_rollback(); |
| 463 | - fossil_exit(1); | |
| 568 | + fossil_exit(rc); | |
| 464 | 569 | } |
| 570 | + | |
| 465 | 571 | NORETURN void fossil_fatal(const char *zFormat, ...){ |
| 466 | 572 | char *z; |
| 573 | + int rc = 1; | |
| 467 | 574 | va_list ap; |
| 468 | 575 | mainInFatalError = 1; |
| 469 | 576 | va_start(ap, zFormat); |
| 470 | 577 | z = vmprintf(zFormat, ap); |
| 471 | 578 | va_end(ap); |
| 472 | - if( g.cgiOutput ){ | |
| 473 | - g.cgiOutput = 0; | |
| 474 | - cgi_printf("<p class=\"generalError\">%h</p>", z); | |
| 475 | - cgi_reply(); | |
| 476 | - }else{ | |
| 477 | - char *zOut = mprintf("\r%s: %s\n", fossil_nameofexe(), z); | |
| 478 | - fossil_puts(zOut, 1); | |
| 479 | - } | |
| 579 | +#ifdef FOSSIL_ENABLE_JSON | |
| 580 | + if( g.json.isJsonMode ){ | |
| 581 | + json_err( g.json.resultCode, z, 1 ); | |
| 582 | + if( g.isHTTP ){ | |
| 583 | + rc = 0 /* avoid HTTP 500 */; | |
| 584 | + } | |
| 585 | + } | |
| 586 | + else | |
| 587 | +#endif | |
| 588 | + { | |
| 589 | + if( g.cgiOutput ){ | |
| 590 | + g.cgiOutput = 0; | |
| 591 | + cgi_printf("<p class=\"generalError\">%h</p>", z); | |
| 592 | + cgi_reply(); | |
| 593 | + }else{ | |
| 594 | + char *zOut = mprintf("\r%s: %s\n", fossil_nameofexe(), z); | |
| 595 | + fossil_puts(zOut, 1); | |
| 596 | + } | |
| 597 | + } | |
| 598 | + free(z); | |
| 480 | 599 | db_force_rollback(); |
| 481 | - fossil_exit(1); | |
| 600 | + fossil_exit(rc); | |
| 482 | 601 | } |
| 483 | 602 | |
| 484 | 603 | /* This routine works like fossil_fatal() except that if called |
| 485 | 604 | ** recursively, the recursive call is a no-op. |
| 486 | 605 | ** |
| @@ -491,25 +610,37 @@ | ||
| 491 | 610 | ** be prepared for this routine to return. |
| 492 | 611 | */ |
| 493 | 612 | void fossil_fatal_recursive(const char *zFormat, ...){ |
| 494 | 613 | char *z; |
| 495 | 614 | va_list ap; |
| 615 | + int rc = 1; | |
| 496 | 616 | if( mainInFatalError ) return; |
| 497 | 617 | mainInFatalError = 1; |
| 498 | 618 | va_start(ap, zFormat); |
| 499 | 619 | z = vmprintf(zFormat, ap); |
| 500 | 620 | va_end(ap); |
| 501 | - if( g.cgiOutput ){ | |
| 502 | - g.cgiOutput = 0; | |
| 503 | - cgi_printf("<p class=\"generalError\">%h</p>", z); | |
| 504 | - cgi_reply(); | |
| 505 | - }else{ | |
| 506 | - char *zOut = mprintf("\r%s: %s\n", fossil_nameofexe(), z); | |
| 507 | - fossil_puts(zOut, 1); | |
| 621 | +#ifdef FOSSIL_ENABLE_JSON | |
| 622 | + if( g.json.isJsonMode ){ | |
| 623 | + json_err( g.json.resultCode, z, 1 ); | |
| 624 | + if( g.isHTTP ){ | |
| 625 | + rc = 0 /* avoid HTTP 500 */; | |
| 626 | + } | |
| 627 | + } else | |
| 628 | +#endif | |
| 629 | + { | |
| 630 | + if( g.cgiOutput ){ | |
| 631 | + g.cgiOutput = 0; | |
| 632 | + cgi_printf("<p class=\"generalError\">%h</p>", z); | |
| 633 | + cgi_reply(); | |
| 634 | + }else{ | |
| 635 | + char *zOut = mprintf("\r%s: %s\n", fossil_nameofexe(), z); | |
| 636 | + fossil_puts(zOut, 1); | |
| 637 | + free(zOut); | |
| 638 | + } | |
| 508 | 639 | } |
| 509 | 640 | db_force_rollback(); |
| 510 | - fossil_exit(1); | |
| 641 | + fossil_exit(rc); | |
| 511 | 642 | } |
| 512 | 643 | |
| 513 | 644 | |
| 514 | 645 | /* Print a warning message */ |
| 515 | 646 | void fossil_warning(const char *zFormat, ...){ |
| @@ -516,17 +647,25 @@ | ||
| 516 | 647 | char *z; |
| 517 | 648 | va_list ap; |
| 518 | 649 | va_start(ap, zFormat); |
| 519 | 650 | z = vmprintf(zFormat, ap); |
| 520 | 651 | va_end(ap); |
| 521 | - if( g.cgiOutput ){ | |
| 522 | - cgi_printf("<p class=\"generalError\">%h</p>", z); | |
| 523 | - }else{ | |
| 524 | - char *zOut = mprintf("\r%s: %s\n", fossil_nameofexe(), z); | |
| 525 | - fossil_puts(zOut, 1); | |
| 526 | - free(zOut); | |
| 652 | +#ifdef FOSSIL_ENABLE_JSON | |
| 653 | + if(g.json.isJsonMode){ | |
| 654 | + json_warn( FSL_JSON_W_UNKNOWN, z ); | |
| 655 | + }else | |
| 656 | +#endif | |
| 657 | + { | |
| 658 | + if( g.cgiOutput ){ | |
| 659 | + cgi_printf("<p class=\"generalError\">%h</p>", z); | |
| 660 | + }else{ | |
| 661 | + char *zOut = mprintf("\r%s: %s\n", fossil_nameofexe(), z); | |
| 662 | + fossil_puts(zOut, 1); | |
| 663 | + free(zOut); | |
| 664 | + } | |
| 527 | 665 | } |
| 666 | + free(z); | |
| 528 | 667 | } |
| 529 | 668 | |
| 530 | 669 | /* |
| 531 | 670 | ** Malloc and free routines that cannot fail |
| 532 | 671 | */ |
| @@ -1065,10 +1204,16 @@ | ||
| 1065 | 1204 | |
| 1066 | 1205 | if( szFile<1024 ){ |
| 1067 | 1206 | if( zNotFound ){ |
| 1068 | 1207 | cgi_redirect(zNotFound); |
| 1069 | 1208 | }else{ |
| 1209 | +#ifdef FOSSIL_ENABLE_JSON | |
| 1210 | + if(g.json.isJsonMode){ | |
| 1211 | + json_err(FSL_JSON_E_RESOURCE_NOT_FOUND,NULL,1); | |
| 1212 | + return; | |
| 1213 | + } | |
| 1214 | +#endif | |
| 1070 | 1215 | @ <h1>Not Found</h1> |
| 1071 | 1216 | cgi_set_status(404, "not found"); |
| 1072 | 1217 | cgi_reply(); |
| 1073 | 1218 | } |
| 1074 | 1219 | return; |
| @@ -1096,11 +1241,17 @@ | ||
| 1096 | 1241 | zPathInfo = "/xfer"; |
| 1097 | 1242 | } |
| 1098 | 1243 | set_base_url(); |
| 1099 | 1244 | if( zPathInfo==0 || zPathInfo[0]==0 |
| 1100 | 1245 | || (zPathInfo[0]=='/' && zPathInfo[1]==0) ){ |
| 1101 | - fossil_redirect_home(); | |
| 1246 | +#ifdef FOSSIL_ENABLE_JSON | |
| 1247 | + if(g.json.isJsonMode){ | |
| 1248 | + json_err(FSL_JSON_E_RESOURCE_NOT_FOUND,NULL,1); | |
| 1249 | + fossil_exit(0); | |
| 1250 | + } | |
| 1251 | +#endif | |
| 1252 | + fossil_redirect_home() /*does not return*/; | |
| 1102 | 1253 | }else{ |
| 1103 | 1254 | zPath = mprintf("%s", zPathInfo); |
| 1104 | 1255 | } |
| 1105 | 1256 | |
| 1106 | 1257 | /* Make g.zPath point to the first element of the path. Make |
| @@ -1157,10 +1308,12 @@ | ||
| 1157 | 1308 | break; |
| 1158 | 1309 | } |
| 1159 | 1310 | if( g.zExtra ){ |
| 1160 | 1311 | /* CGI parameters get this treatment elsewhere, but places like getfile |
| 1161 | 1312 | ** will use g.zExtra directly. |
| 1313 | + ** Reminder: the login mechanism uses 'name' differently, and may | |
| 1314 | + ** eventually have a problem/collision with this. | |
| 1162 | 1315 | */ |
| 1163 | 1316 | dehttpize(g.zExtra); |
| 1164 | 1317 | cgi_set_parameter_nocopy("name", g.zExtra); |
| 1165 | 1318 | } |
| 1166 | 1319 | |
| @@ -1167,17 +1320,31 @@ | ||
| 1167 | 1320 | /* Locate the method specified by the path and execute the function |
| 1168 | 1321 | ** that implements that method. |
| 1169 | 1322 | */ |
| 1170 | 1323 | if( name_search(g.zPath, aWebpage, count(aWebpage), &idx) && |
| 1171 | 1324 | name_search("not_found", aWebpage, count(aWebpage), &idx) ){ |
| 1172 | - cgi_set_status(404,"Not Found"); | |
| 1173 | - @ <h1>Not Found</h1> | |
| 1174 | - @ <p>Page not found: %h(g.zPath)</p> | |
| 1325 | +#ifdef FOSSIL_ENABLE_JSON | |
| 1326 | + if(g.json.isJsonMode){ | |
| 1327 | + json_err(FSL_JSON_E_RESOURCE_NOT_FOUND,NULL,0); | |
| 1328 | + }else | |
| 1329 | +#endif | |
| 1330 | + { | |
| 1331 | + cgi_set_status(404,"Not Found"); | |
| 1332 | + @ <h1>Not Found</h1> | |
| 1333 | + @ <p>Page not found: %h(g.zPath)</p> | |
| 1334 | + } | |
| 1175 | 1335 | }else if( aWebpage[idx].xFunc!=page_xfer && db_schema_is_outofdate() ){ |
| 1176 | - @ <h1>Server Configuration Error</h1> | |
| 1177 | - @ <p>The database schema on the server is out-of-date. Please ask | |
| 1178 | - @ the administrator to run <b>fossil rebuild</b>.</p> | |
| 1336 | +#ifdef FOSSIL_ENABLE_JSON | |
| 1337 | + if(g.json.isJsonMode){ | |
| 1338 | + json_err(FSL_JSON_E_DB_NEEDS_REBUILD,NULL,0); | |
| 1339 | + }else | |
| 1340 | +#endif | |
| 1341 | + { | |
| 1342 | + @ <h1>Server Configuration Error</h1> | |
| 1343 | + @ <p>The database schema on the server is out-of-date. Please ask | |
| 1344 | + @ the administrator to run <b>fossil rebuild</b>.</p> | |
| 1345 | + } | |
| 1179 | 1346 | }else{ |
| 1180 | 1347 | aWebpage[idx].xFunc(); |
| 1181 | 1348 | } |
| 1182 | 1349 | |
| 1183 | 1350 | /* Return the result. |
| 1184 | 1351 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -23,14 +23,17 @@ | |
| 23 | #include <string.h> |
| 24 | #include <time.h> |
| 25 | #include <fcntl.h> |
| 26 | #include <sys/types.h> |
| 27 | #include <sys/stat.h> |
| 28 | |
| 29 | |
| 30 | #if INTERFACE |
| 31 | |
| 32 | #ifdef FOSSIL_ENABLE_TCL |
| 33 | #include "tcl.h" |
| 34 | #endif |
| 35 | |
| 36 | /* |
| @@ -132,10 +135,11 @@ | |
| 132 | int xlinkClusterOnly; /* Set when cloning. Only process clusters */ |
| 133 | int fTimeFormat; /* 1 for UTC. 2 for localtime. 0 not yet selected */ |
| 134 | int *aCommitFile; /* Array of files to be committed */ |
| 135 | int markPrivate; /* All new artifacts are private if true */ |
| 136 | int clockSkewSeen; /* True if clocks on client and server out of sync */ |
| 137 | |
| 138 | int urlIsFile; /* True if a "file:" url */ |
| 139 | int urlIsHttps; /* True if a "https:" url */ |
| 140 | int urlIsSsh; /* True if an "ssh:" url */ |
| 141 | char *urlName; /* Hostname for http: or filename for file: */ |
| @@ -148,11 +152,11 @@ | |
| 148 | char *urlPasswd; /* Password for http: */ |
| 149 | char *urlCanonical; /* Canonical representation of the URL */ |
| 150 | char *urlProxyAuth; /* Proxy-Authorizer: string */ |
| 151 | char *urlFossil; /* The path of the ?fossil=path suffix on ssh: */ |
| 152 | int dontKeepUrl; /* Do not persist the URL */ |
| 153 | |
| 154 | const char *zLogin; /* Login name. "" if not logged in. */ |
| 155 | const char *zSSLIdentity; /* Value of --ssl-identity option, filename of SSL client identity */ |
| 156 | int useLocalauth; /* No login required if from 127.0.0.1 */ |
| 157 | int noPswd; /* Logged in without password (on 127.0.0.1) */ |
| 158 | int userUid; /* Integer user id */ |
| @@ -188,10 +192,66 @@ | |
| 188 | const char *azAuxVal[MX_AUX]; /* Value of each aux() or option() value */ |
| 189 | const char **azAuxOpt[MX_AUX]; /* Options of each option() value */ |
| 190 | int anAuxCols[MX_AUX]; /* Number of columns for option() values */ |
| 191 | |
| 192 | int allowSymlinks; /* Cached "allow-symlinks" option */ |
| 193 | }; |
| 194 | |
| 195 | /* |
| 196 | ** Macro for debugging: |
| 197 | */ |
| @@ -252,10 +312,25 @@ | |
| 252 | *pIndex = m; |
| 253 | return 0; |
| 254 | } |
| 255 | return 1+(cnt>1); |
| 256 | } |
| 257 | |
| 258 | /* |
| 259 | ** Search g.argv for arguments "--args FILENAME". If found, then |
| 260 | ** (1) remove the two arguments from g.argv |
| 261 | ** (2) Read the file FILENAME |
| @@ -343,28 +418,44 @@ | |
| 343 | g.tcl.argv = argv; |
| 344 | g.tcl.interp = 0; |
| 345 | #endif |
| 346 | |
| 347 | sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0); |
| 348 | g.now = time(0); |
| 349 | g.argc = argc; |
| 350 | g.argv = argv; |
| 351 | expand_args_option(); |
| 352 | argc = g.argc; |
| 353 | argv = g.argv; |
| 354 | for(i=0; i<argc; i++) g.argv[i] = fossil_mbcs_to_utf8(argv[i]); |
| 355 | if( getenv("GATEWAY_INTERFACE")!=0 && !find_option("nocgi", 0, 0)){ |
| 356 | zCmdName = "cgi"; |
| 357 | }else if( argc<2 ){ |
| 358 | fossil_print( |
| 359 | "Usage: %s COMMAND ...\n" |
| 360 | " or: %s help -- for a list of common commands\n" |
| 361 | " or: %s help COMMMAND -- for help with the named command\n" |
| 362 | " or: %s commands -- for a list of all commands\n", |
| 363 | argv[0], argv[0], argv[0], argv[0]); |
| 364 | fossil_exit(1); |
| 365 | }else{ |
| 366 | g.fQuiet = find_option("quiet", 0, 0)!=0; |
| 367 | g.fSqlTrace = find_option("sqltrace", 0, 0)!=0; |
| 368 | g.fSqlStats = find_option("sqlstats", 0, 0)!=0; |
| 369 | g.fSystemTrace = find_option("systemtrace", 0, 0)!=0; |
| 370 | if( g.fSqlTrace ) g.fSqlStats = 1; |
| @@ -405,10 +496,11 @@ | |
| 405 | "%s: could be any of:%s\n" |
| 406 | "%s: use \"help\" for more information\n", |
| 407 | argv[0], zCmdName, argv[0], blob_str(&couldbe), argv[0]); |
| 408 | fossil_exit(1); |
| 409 | } |
| 410 | aCommand[idx].xFunc(); |
| 411 | fossil_exit(0); |
| 412 | /*NOT_REACHED*/ |
| 413 | return 0; |
| 414 | } |
| @@ -444,43 +536,70 @@ | |
| 444 | ** routines never return. |
| 445 | */ |
| 446 | NORETURN void fossil_panic(const char *zFormat, ...){ |
| 447 | char *z; |
| 448 | va_list ap; |
| 449 | static int once = 1; |
| 450 | mainInFatalError = 1; |
| 451 | va_start(ap, zFormat); |
| 452 | z = vmprintf(zFormat, ap); |
| 453 | va_end(ap); |
| 454 | if( g.cgiOutput && once ){ |
| 455 | once = 0; |
| 456 | cgi_printf("<p class=\"generalError\">%h</p>", z); |
| 457 | cgi_reply(); |
| 458 | }else{ |
| 459 | char *zOut = mprintf("%s: %s\n", fossil_nameofexe(), z); |
| 460 | fossil_puts(zOut, 1); |
| 461 | } |
| 462 | db_force_rollback(); |
| 463 | fossil_exit(1); |
| 464 | } |
| 465 | NORETURN void fossil_fatal(const char *zFormat, ...){ |
| 466 | char *z; |
| 467 | va_list ap; |
| 468 | mainInFatalError = 1; |
| 469 | va_start(ap, zFormat); |
| 470 | z = vmprintf(zFormat, ap); |
| 471 | va_end(ap); |
| 472 | if( g.cgiOutput ){ |
| 473 | g.cgiOutput = 0; |
| 474 | cgi_printf("<p class=\"generalError\">%h</p>", z); |
| 475 | cgi_reply(); |
| 476 | }else{ |
| 477 | char *zOut = mprintf("\r%s: %s\n", fossil_nameofexe(), z); |
| 478 | fossil_puts(zOut, 1); |
| 479 | } |
| 480 | db_force_rollback(); |
| 481 | fossil_exit(1); |
| 482 | } |
| 483 | |
| 484 | /* This routine works like fossil_fatal() except that if called |
| 485 | ** recursively, the recursive call is a no-op. |
| 486 | ** |
| @@ -491,25 +610,37 @@ | |
| 491 | ** be prepared for this routine to return. |
| 492 | */ |
| 493 | void fossil_fatal_recursive(const char *zFormat, ...){ |
| 494 | char *z; |
| 495 | va_list ap; |
| 496 | if( mainInFatalError ) return; |
| 497 | mainInFatalError = 1; |
| 498 | va_start(ap, zFormat); |
| 499 | z = vmprintf(zFormat, ap); |
| 500 | va_end(ap); |
| 501 | if( g.cgiOutput ){ |
| 502 | g.cgiOutput = 0; |
| 503 | cgi_printf("<p class=\"generalError\">%h</p>", z); |
| 504 | cgi_reply(); |
| 505 | }else{ |
| 506 | char *zOut = mprintf("\r%s: %s\n", fossil_nameofexe(), z); |
| 507 | fossil_puts(zOut, 1); |
| 508 | } |
| 509 | db_force_rollback(); |
| 510 | fossil_exit(1); |
| 511 | } |
| 512 | |
| 513 | |
| 514 | /* Print a warning message */ |
| 515 | void fossil_warning(const char *zFormat, ...){ |
| @@ -516,17 +647,25 @@ | |
| 516 | char *z; |
| 517 | va_list ap; |
| 518 | va_start(ap, zFormat); |
| 519 | z = vmprintf(zFormat, ap); |
| 520 | va_end(ap); |
| 521 | if( g.cgiOutput ){ |
| 522 | cgi_printf("<p class=\"generalError\">%h</p>", z); |
| 523 | }else{ |
| 524 | char *zOut = mprintf("\r%s: %s\n", fossil_nameofexe(), z); |
| 525 | fossil_puts(zOut, 1); |
| 526 | free(zOut); |
| 527 | } |
| 528 | } |
| 529 | |
| 530 | /* |
| 531 | ** Malloc and free routines that cannot fail |
| 532 | */ |
| @@ -1065,10 +1204,16 @@ | |
| 1065 | |
| 1066 | if( szFile<1024 ){ |
| 1067 | if( zNotFound ){ |
| 1068 | cgi_redirect(zNotFound); |
| 1069 | }else{ |
| 1070 | @ <h1>Not Found</h1> |
| 1071 | cgi_set_status(404, "not found"); |
| 1072 | cgi_reply(); |
| 1073 | } |
| 1074 | return; |
| @@ -1096,11 +1241,17 @@ | |
| 1096 | zPathInfo = "/xfer"; |
| 1097 | } |
| 1098 | set_base_url(); |
| 1099 | if( zPathInfo==0 || zPathInfo[0]==0 |
| 1100 | || (zPathInfo[0]=='/' && zPathInfo[1]==0) ){ |
| 1101 | fossil_redirect_home(); |
| 1102 | }else{ |
| 1103 | zPath = mprintf("%s", zPathInfo); |
| 1104 | } |
| 1105 | |
| 1106 | /* Make g.zPath point to the first element of the path. Make |
| @@ -1157,10 +1308,12 @@ | |
| 1157 | break; |
| 1158 | } |
| 1159 | if( g.zExtra ){ |
| 1160 | /* CGI parameters get this treatment elsewhere, but places like getfile |
| 1161 | ** will use g.zExtra directly. |
| 1162 | */ |
| 1163 | dehttpize(g.zExtra); |
| 1164 | cgi_set_parameter_nocopy("name", g.zExtra); |
| 1165 | } |
| 1166 | |
| @@ -1167,17 +1320,31 @@ | |
| 1167 | /* Locate the method specified by the path and execute the function |
| 1168 | ** that implements that method. |
| 1169 | */ |
| 1170 | if( name_search(g.zPath, aWebpage, count(aWebpage), &idx) && |
| 1171 | name_search("not_found", aWebpage, count(aWebpage), &idx) ){ |
| 1172 | cgi_set_status(404,"Not Found"); |
| 1173 | @ <h1>Not Found</h1> |
| 1174 | @ <p>Page not found: %h(g.zPath)</p> |
| 1175 | }else if( aWebpage[idx].xFunc!=page_xfer && db_schema_is_outofdate() ){ |
| 1176 | @ <h1>Server Configuration Error</h1> |
| 1177 | @ <p>The database schema on the server is out-of-date. Please ask |
| 1178 | @ the administrator to run <b>fossil rebuild</b>.</p> |
| 1179 | }else{ |
| 1180 | aWebpage[idx].xFunc(); |
| 1181 | } |
| 1182 | |
| 1183 | /* Return the result. |
| 1184 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -23,14 +23,17 @@ | |
| 23 | #include <string.h> |
| 24 | #include <time.h> |
| 25 | #include <fcntl.h> |
| 26 | #include <sys/types.h> |
| 27 | #include <sys/stat.h> |
| 28 | #include <stdlib.h> /* atexit() */ |
| 29 | |
| 30 | #if INTERFACE |
| 31 | #ifdef FOSSIL_ENABLE_JSON |
| 32 | # include "cson_amalgamation.h" /* JSON API. Needed inside the INTERFACE block! */ |
| 33 | # include "json_detail.h" |
| 34 | #endif |
| 35 | #ifdef FOSSIL_ENABLE_TCL |
| 36 | #include "tcl.h" |
| 37 | #endif |
| 38 | |
| 39 | /* |
| @@ -132,10 +135,11 @@ | |
| 135 | int xlinkClusterOnly; /* Set when cloning. Only process clusters */ |
| 136 | int fTimeFormat; /* 1 for UTC. 2 for localtime. 0 not yet selected */ |
| 137 | int *aCommitFile; /* Array of files to be committed */ |
| 138 | int markPrivate; /* All new artifacts are private if true */ |
| 139 | int clockSkewSeen; /* True if clocks on client and server out of sync */ |
| 140 | int isHTTP; /* True if running in server/CGI modes, else assume CLI. */ |
| 141 | |
| 142 | int urlIsFile; /* True if a "file:" url */ |
| 143 | int urlIsHttps; /* True if a "https:" url */ |
| 144 | int urlIsSsh; /* True if an "ssh:" url */ |
| 145 | char *urlName; /* Hostname for http: or filename for file: */ |
| @@ -148,11 +152,11 @@ | |
| 152 | char *urlPasswd; /* Password for http: */ |
| 153 | char *urlCanonical; /* Canonical representation of the URL */ |
| 154 | char *urlProxyAuth; /* Proxy-Authorizer: string */ |
| 155 | char *urlFossil; /* The path of the ?fossil=path suffix on ssh: */ |
| 156 | int dontKeepUrl; /* Do not persist the URL */ |
| 157 | |
| 158 | const char *zLogin; /* Login name. "" if not logged in. */ |
| 159 | const char *zSSLIdentity; /* Value of --ssl-identity option, filename of SSL client identity */ |
| 160 | int useLocalauth; /* No login required if from 127.0.0.1 */ |
| 161 | int noPswd; /* Logged in without password (on 127.0.0.1) */ |
| 162 | int userUid; /* Integer user id */ |
| @@ -188,10 +192,66 @@ | |
| 192 | const char *azAuxVal[MX_AUX]; /* Value of each aux() or option() value */ |
| 193 | const char **azAuxOpt[MX_AUX]; /* Options of each option() value */ |
| 194 | int anAuxCols[MX_AUX]; /* Number of columns for option() values */ |
| 195 | |
| 196 | int allowSymlinks; /* Cached "allow-symlinks" option */ |
| 197 | |
| 198 | #ifdef FOSSIL_ENABLE_JSON |
| 199 | struct FossilJsonBits { |
| 200 | int isJsonMode; /* True if running in JSON mode, else |
| 201 | false. This changes how errors are |
| 202 | reported. In JSON mode we try to |
| 203 | always output JSON-form error |
| 204 | responses and always exit() with |
| 205 | code 0 to avoid an HTTP 500 error. |
| 206 | */ |
| 207 | int resultCode; /* used for passing back specific codes from /json callbacks. */ |
| 208 | int errorDetailParanoia; /* 0=full error codes, 1=%10, 2=%100, 3=%1000 */ |
| 209 | cson_output_opt outOpt; /* formatting options for JSON mode. */ |
| 210 | cson_value * authToken; /* authentication token */ |
| 211 | char const * jsonp; /* Name of JSONP function wrapper. */ |
| 212 | unsigned char dispatchDepth /* Tells JSON command dispatching |
| 213 | which argument we are currently |
| 214 | working on. For this purpose, arg#0 |
| 215 | is the "json" path/CLI arg. |
| 216 | */; |
| 217 | struct { /* "garbage collector" */ |
| 218 | cson_value * v; |
| 219 | cson_array * a; |
| 220 | } gc; |
| 221 | struct { /* JSON POST data. */ |
| 222 | cson_value * v; |
| 223 | cson_array * a; |
| 224 | int offset; /* Tells us which PATH_INFO/CLI args |
| 225 | part holds the "json" command, so |
| 226 | that we can account for sub-repos |
| 227 | and path prefixes. This is handled |
| 228 | differently for CLI and CGI modes. |
| 229 | */ |
| 230 | char const * commandStr /*"command" request param.*/; |
| 231 | } cmd; |
| 232 | struct { /* JSON POST data. */ |
| 233 | cson_value * v; |
| 234 | cson_object * o; |
| 235 | } post; |
| 236 | struct { /* GET/COOKIE params in JSON mode. |
| 237 | FIXME (stephan): verify that this is |
| 238 | still used and remove if it is not. |
| 239 | */ |
| 240 | cson_value * v; |
| 241 | cson_object * o; |
| 242 | } param; |
| 243 | struct { |
| 244 | cson_value * v; |
| 245 | cson_object * o; |
| 246 | } reqPayload; /* request payload object (if any) */ |
| 247 | struct { /* response warnings */ |
| 248 | cson_value * v; |
| 249 | cson_array * a; |
| 250 | } warnings; |
| 251 | } json; |
| 252 | #endif /* FOSSIL_ENABLE_JSON */ |
| 253 | }; |
| 254 | |
| 255 | /* |
| 256 | ** Macro for debugging: |
| 257 | */ |
| @@ -252,10 +312,25 @@ | |
| 312 | *pIndex = m; |
| 313 | return 0; |
| 314 | } |
| 315 | return 1+(cnt>1); |
| 316 | } |
| 317 | |
| 318 | /* |
| 319 | ** atexit() handler which frees up "some" of the resources |
| 320 | ** used by fossil. |
| 321 | */ |
| 322 | void fossil_atexit() { |
| 323 | #ifdef FOSSIL_ENABLE_JSON |
| 324 | cson_value_free(g.json.gc.v); |
| 325 | memset(&g.json, 0, sizeof(g.json)); |
| 326 | #endif |
| 327 | free(g.zErrMsg); |
| 328 | if(g.db){ |
| 329 | db_close(0); |
| 330 | } |
| 331 | } |
| 332 | |
| 333 | /* |
| 334 | ** Search g.argv for arguments "--args FILENAME". If found, then |
| 335 | ** (1) remove the two arguments from g.argv |
| 336 | ** (2) Read the file FILENAME |
| @@ -343,28 +418,44 @@ | |
| 418 | g.tcl.argv = argv; |
| 419 | g.tcl.interp = 0; |
| 420 | #endif |
| 421 | |
| 422 | sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0); |
| 423 | memset(&g, 0, sizeof(g)); |
| 424 | g.now = time(0); |
| 425 | g.argc = argc; |
| 426 | g.argv = argv; |
| 427 | #ifdef FOSSIL_ENABLE_JSON |
| 428 | #if defined(NDEBUG) |
| 429 | g.json.errorDetailParanoia = 2 /* FIXME: make configurable |
| 430 | One problem we have here is that this |
| 431 | code is needed before the db is opened, |
| 432 | so we can't sql for it.*/; |
| 433 | #else |
| 434 | g.json.errorDetailParanoia = 0; |
| 435 | #endif |
| 436 | g.json.outOpt = cson_output_opt_empty; |
| 437 | g.json.outOpt.addNewline = 1; |
| 438 | g.json.outOpt.indentation = 1 /* in CGI/server mode this can be configured */; |
| 439 | #endif /* FOSSIL_ENABLE_JSON */ |
| 440 | expand_args_option(); |
| 441 | argc = g.argc; |
| 442 | argv = g.argv; |
| 443 | for(i=0; i<argc; i++) g.argv[i] = fossil_mbcs_to_utf8(argv[i]); |
| 444 | if( getenv("GATEWAY_INTERFACE")!=0 && !find_option("nocgi", 0, 0)){ |
| 445 | zCmdName = "cgi"; |
| 446 | g.isHTTP = 1; |
| 447 | }else if( argc<2 ){ |
| 448 | fossil_print( |
| 449 | "Usage: %s COMMAND ...\n" |
| 450 | " or: %s help -- for a list of common commands\n" |
| 451 | " or: %s help COMMMAND -- for help with the named command\n" |
| 452 | " or: %s commands -- for a list of all commands\n", |
| 453 | argv[0], argv[0], argv[0], argv[0]); |
| 454 | fossil_exit(1); |
| 455 | }else{ |
| 456 | g.isHTTP = 0; |
| 457 | g.fQuiet = find_option("quiet", 0, 0)!=0; |
| 458 | g.fSqlTrace = find_option("sqltrace", 0, 0)!=0; |
| 459 | g.fSqlStats = find_option("sqlstats", 0, 0)!=0; |
| 460 | g.fSystemTrace = find_option("systemtrace", 0, 0)!=0; |
| 461 | if( g.fSqlTrace ) g.fSqlStats = 1; |
| @@ -405,10 +496,11 @@ | |
| 496 | "%s: could be any of:%s\n" |
| 497 | "%s: use \"help\" for more information\n", |
| 498 | argv[0], zCmdName, argv[0], blob_str(&couldbe), argv[0]); |
| 499 | fossil_exit(1); |
| 500 | } |
| 501 | atexit( fossil_atexit ); |
| 502 | aCommand[idx].xFunc(); |
| 503 | fossil_exit(0); |
| 504 | /*NOT_REACHED*/ |
| 505 | return 0; |
| 506 | } |
| @@ -444,43 +536,70 @@ | |
| 536 | ** routines never return. |
| 537 | */ |
| 538 | NORETURN void fossil_panic(const char *zFormat, ...){ |
| 539 | char *z; |
| 540 | va_list ap; |
| 541 | int rc = 1; |
| 542 | static int once = 1; |
| 543 | mainInFatalError = 1; |
| 544 | va_start(ap, zFormat); |
| 545 | z = vmprintf(zFormat, ap); |
| 546 | va_end(ap); |
| 547 | #ifdef FOSSIL_ENABLE_JSON |
| 548 | if( g.json.isJsonMode ){ |
| 549 | json_err( 0, z, 1 ); |
| 550 | if( g.isHTTP ){ |
| 551 | rc = 0 /* avoid HTTP 500 */; |
| 552 | } |
| 553 | } |
| 554 | else |
| 555 | #endif |
| 556 | { |
| 557 | if( g.cgiOutput && once ){ |
| 558 | once = 0; |
| 559 | cgi_printf("<p class=\"generalError\">%h</p>", z); |
| 560 | cgi_reply(); |
| 561 | }else{ |
| 562 | char *zOut = mprintf("%s: %s\n", fossil_nameofexe(), z); |
| 563 | fossil_puts(zOut, 1); |
| 564 | } |
| 565 | } |
| 566 | free(z); |
| 567 | db_force_rollback(); |
| 568 | fossil_exit(rc); |
| 569 | } |
| 570 | |
| 571 | NORETURN void fossil_fatal(const char *zFormat, ...){ |
| 572 | char *z; |
| 573 | int rc = 1; |
| 574 | va_list ap; |
| 575 | mainInFatalError = 1; |
| 576 | va_start(ap, zFormat); |
| 577 | z = vmprintf(zFormat, ap); |
| 578 | va_end(ap); |
| 579 | #ifdef FOSSIL_ENABLE_JSON |
| 580 | if( g.json.isJsonMode ){ |
| 581 | json_err( g.json.resultCode, z, 1 ); |
| 582 | if( g.isHTTP ){ |
| 583 | rc = 0 /* avoid HTTP 500 */; |
| 584 | } |
| 585 | } |
| 586 | else |
| 587 | #endif |
| 588 | { |
| 589 | if( g.cgiOutput ){ |
| 590 | g.cgiOutput = 0; |
| 591 | cgi_printf("<p class=\"generalError\">%h</p>", z); |
| 592 | cgi_reply(); |
| 593 | }else{ |
| 594 | char *zOut = mprintf("\r%s: %s\n", fossil_nameofexe(), z); |
| 595 | fossil_puts(zOut, 1); |
| 596 | } |
| 597 | } |
| 598 | free(z); |
| 599 | db_force_rollback(); |
| 600 | fossil_exit(rc); |
| 601 | } |
| 602 | |
| 603 | /* This routine works like fossil_fatal() except that if called |
| 604 | ** recursively, the recursive call is a no-op. |
| 605 | ** |
| @@ -491,25 +610,37 @@ | |
| 610 | ** be prepared for this routine to return. |
| 611 | */ |
| 612 | void fossil_fatal_recursive(const char *zFormat, ...){ |
| 613 | char *z; |
| 614 | va_list ap; |
| 615 | int rc = 1; |
| 616 | if( mainInFatalError ) return; |
| 617 | mainInFatalError = 1; |
| 618 | va_start(ap, zFormat); |
| 619 | z = vmprintf(zFormat, ap); |
| 620 | va_end(ap); |
| 621 | #ifdef FOSSIL_ENABLE_JSON |
| 622 | if( g.json.isJsonMode ){ |
| 623 | json_err( g.json.resultCode, z, 1 ); |
| 624 | if( g.isHTTP ){ |
| 625 | rc = 0 /* avoid HTTP 500 */; |
| 626 | } |
| 627 | } else |
| 628 | #endif |
| 629 | { |
| 630 | if( g.cgiOutput ){ |
| 631 | g.cgiOutput = 0; |
| 632 | cgi_printf("<p class=\"generalError\">%h</p>", z); |
| 633 | cgi_reply(); |
| 634 | }else{ |
| 635 | char *zOut = mprintf("\r%s: %s\n", fossil_nameofexe(), z); |
| 636 | fossil_puts(zOut, 1); |
| 637 | free(zOut); |
| 638 | } |
| 639 | } |
| 640 | db_force_rollback(); |
| 641 | fossil_exit(rc); |
| 642 | } |
| 643 | |
| 644 | |
| 645 | /* Print a warning message */ |
| 646 | void fossil_warning(const char *zFormat, ...){ |
| @@ -516,17 +647,25 @@ | |
| 647 | char *z; |
| 648 | va_list ap; |
| 649 | va_start(ap, zFormat); |
| 650 | z = vmprintf(zFormat, ap); |
| 651 | va_end(ap); |
| 652 | #ifdef FOSSIL_ENABLE_JSON |
| 653 | if(g.json.isJsonMode){ |
| 654 | json_warn( FSL_JSON_W_UNKNOWN, z ); |
| 655 | }else |
| 656 | #endif |
| 657 | { |
| 658 | if( g.cgiOutput ){ |
| 659 | cgi_printf("<p class=\"generalError\">%h</p>", z); |
| 660 | }else{ |
| 661 | char *zOut = mprintf("\r%s: %s\n", fossil_nameofexe(), z); |
| 662 | fossil_puts(zOut, 1); |
| 663 | free(zOut); |
| 664 | } |
| 665 | } |
| 666 | free(z); |
| 667 | } |
| 668 | |
| 669 | /* |
| 670 | ** Malloc and free routines that cannot fail |
| 671 | */ |
| @@ -1065,10 +1204,16 @@ | |
| 1204 | |
| 1205 | if( szFile<1024 ){ |
| 1206 | if( zNotFound ){ |
| 1207 | cgi_redirect(zNotFound); |
| 1208 | }else{ |
| 1209 | #ifdef FOSSIL_ENABLE_JSON |
| 1210 | if(g.json.isJsonMode){ |
| 1211 | json_err(FSL_JSON_E_RESOURCE_NOT_FOUND,NULL,1); |
| 1212 | return; |
| 1213 | } |
| 1214 | #endif |
| 1215 | @ <h1>Not Found</h1> |
| 1216 | cgi_set_status(404, "not found"); |
| 1217 | cgi_reply(); |
| 1218 | } |
| 1219 | return; |
| @@ -1096,11 +1241,17 @@ | |
| 1241 | zPathInfo = "/xfer"; |
| 1242 | } |
| 1243 | set_base_url(); |
| 1244 | if( zPathInfo==0 || zPathInfo[0]==0 |
| 1245 | || (zPathInfo[0]=='/' && zPathInfo[1]==0) ){ |
| 1246 | #ifdef FOSSIL_ENABLE_JSON |
| 1247 | if(g.json.isJsonMode){ |
| 1248 | json_err(FSL_JSON_E_RESOURCE_NOT_FOUND,NULL,1); |
| 1249 | fossil_exit(0); |
| 1250 | } |
| 1251 | #endif |
| 1252 | fossil_redirect_home() /*does not return*/; |
| 1253 | }else{ |
| 1254 | zPath = mprintf("%s", zPathInfo); |
| 1255 | } |
| 1256 | |
| 1257 | /* Make g.zPath point to the first element of the path. Make |
| @@ -1157,10 +1308,12 @@ | |
| 1308 | break; |
| 1309 | } |
| 1310 | if( g.zExtra ){ |
| 1311 | /* CGI parameters get this treatment elsewhere, but places like getfile |
| 1312 | ** will use g.zExtra directly. |
| 1313 | ** Reminder: the login mechanism uses 'name' differently, and may |
| 1314 | ** eventually have a problem/collision with this. |
| 1315 | */ |
| 1316 | dehttpize(g.zExtra); |
| 1317 | cgi_set_parameter_nocopy("name", g.zExtra); |
| 1318 | } |
| 1319 | |
| @@ -1167,17 +1320,31 @@ | |
| 1320 | /* Locate the method specified by the path and execute the function |
| 1321 | ** that implements that method. |
| 1322 | */ |
| 1323 | if( name_search(g.zPath, aWebpage, count(aWebpage), &idx) && |
| 1324 | name_search("not_found", aWebpage, count(aWebpage), &idx) ){ |
| 1325 | #ifdef FOSSIL_ENABLE_JSON |
| 1326 | if(g.json.isJsonMode){ |
| 1327 | json_err(FSL_JSON_E_RESOURCE_NOT_FOUND,NULL,0); |
| 1328 | }else |
| 1329 | #endif |
| 1330 | { |
| 1331 | cgi_set_status(404,"Not Found"); |
| 1332 | @ <h1>Not Found</h1> |
| 1333 | @ <p>Page not found: %h(g.zPath)</p> |
| 1334 | } |
| 1335 | }else if( aWebpage[idx].xFunc!=page_xfer && db_schema_is_outofdate() ){ |
| 1336 | #ifdef FOSSIL_ENABLE_JSON |
| 1337 | if(g.json.isJsonMode){ |
| 1338 | json_err(FSL_JSON_E_DB_NEEDS_REBUILD,NULL,0); |
| 1339 | }else |
| 1340 | #endif |
| 1341 | { |
| 1342 | @ <h1>Server Configuration Error</h1> |
| 1343 | @ <p>The database schema on the server is out-of-date. Please ask |
| 1344 | @ the administrator to run <b>fossil rebuild</b>.</p> |
| 1345 | } |
| 1346 | }else{ |
| 1347 | aWebpage[idx].xFunc(); |
| 1348 | } |
| 1349 | |
| 1350 | /* Return the result. |
| 1351 |
+209
-42
| --- src/main.c | ||
| +++ src/main.c | ||
| @@ -23,14 +23,17 @@ | ||
| 23 | 23 | #include <string.h> |
| 24 | 24 | #include <time.h> |
| 25 | 25 | #include <fcntl.h> |
| 26 | 26 | #include <sys/types.h> |
| 27 | 27 | #include <sys/stat.h> |
| 28 | - | |
| 28 | +#include <stdlib.h> /* atexit() */ | |
| 29 | 29 | |
| 30 | 30 | #if INTERFACE |
| 31 | - | |
| 31 | +#ifdef FOSSIL_ENABLE_JSON | |
| 32 | +# include "cson_amalgamation.h" /* JSON API. Needed inside the INTERFACE block! */ | |
| 33 | +# include "json_detail.h" | |
| 34 | +#endif | |
| 32 | 35 | #ifdef FOSSIL_ENABLE_TCL |
| 33 | 36 | #include "tcl.h" |
| 34 | 37 | #endif |
| 35 | 38 | |
| 36 | 39 | /* |
| @@ -132,10 +135,11 @@ | ||
| 132 | 135 | int xlinkClusterOnly; /* Set when cloning. Only process clusters */ |
| 133 | 136 | int fTimeFormat; /* 1 for UTC. 2 for localtime. 0 not yet selected */ |
| 134 | 137 | int *aCommitFile; /* Array of files to be committed */ |
| 135 | 138 | int markPrivate; /* All new artifacts are private if true */ |
| 136 | 139 | int clockSkewSeen; /* True if clocks on client and server out of sync */ |
| 140 | + int isHTTP; /* True if running in server/CGI modes, else assume CLI. */ | |
| 137 | 141 | |
| 138 | 142 | int urlIsFile; /* True if a "file:" url */ |
| 139 | 143 | int urlIsHttps; /* True if a "https:" url */ |
| 140 | 144 | int urlIsSsh; /* True if an "ssh:" url */ |
| 141 | 145 | char *urlName; /* Hostname for http: or filename for file: */ |
| @@ -148,11 +152,11 @@ | ||
| 148 | 152 | char *urlPasswd; /* Password for http: */ |
| 149 | 153 | char *urlCanonical; /* Canonical representation of the URL */ |
| 150 | 154 | char *urlProxyAuth; /* Proxy-Authorizer: string */ |
| 151 | 155 | char *urlFossil; /* The path of the ?fossil=path suffix on ssh: */ |
| 152 | 156 | int dontKeepUrl; /* Do not persist the URL */ |
| 153 | - | |
| 157 | + | |
| 154 | 158 | const char *zLogin; /* Login name. "" if not logged in. */ |
| 155 | 159 | const char *zSSLIdentity; /* Value of --ssl-identity option, filename of SSL client identity */ |
| 156 | 160 | int useLocalauth; /* No login required if from 127.0.0.1 */ |
| 157 | 161 | int noPswd; /* Logged in without password (on 127.0.0.1) */ |
| 158 | 162 | int userUid; /* Integer user id */ |
| @@ -188,10 +192,66 @@ | ||
| 188 | 192 | const char *azAuxVal[MX_AUX]; /* Value of each aux() or option() value */ |
| 189 | 193 | const char **azAuxOpt[MX_AUX]; /* Options of each option() value */ |
| 190 | 194 | int anAuxCols[MX_AUX]; /* Number of columns for option() values */ |
| 191 | 195 | |
| 192 | 196 | int allowSymlinks; /* Cached "allow-symlinks" option */ |
| 197 | + | |
| 198 | +#ifdef FOSSIL_ENABLE_JSON | |
| 199 | + struct FossilJsonBits { | |
| 200 | + int isJsonMode; /* True if running in JSON mode, else | |
| 201 | + false. This changes how errors are | |
| 202 | + reported. In JSON mode we try to | |
| 203 | + always output JSON-form error | |
| 204 | + responses and always exit() with | |
| 205 | + code 0 to avoid an HTTP 500 error. | |
| 206 | + */ | |
| 207 | + int resultCode; /* used for passing back specific codes from /json callbacks. */ | |
| 208 | + int errorDetailParanoia; /* 0=full error codes, 1=%10, 2=%100, 3=%1000 */ | |
| 209 | + cson_output_opt outOpt; /* formatting options for JSON mode. */ | |
| 210 | + cson_value * authToken; /* authentication token */ | |
| 211 | + char const * jsonp; /* Name of JSONP function wrapper. */ | |
| 212 | + unsigned char dispatchDepth /* Tells JSON command dispatching | |
| 213 | + which argument we are currently | |
| 214 | + working on. For this purpose, arg#0 | |
| 215 | + is the "json" path/CLI arg. | |
| 216 | + */; | |
| 217 | + struct { /* "garbage collector" */ | |
| 218 | + cson_value * v; | |
| 219 | + cson_array * a; | |
| 220 | + } gc; | |
| 221 | + struct { /* JSON POST data. */ | |
| 222 | + cson_value * v; | |
| 223 | + cson_array * a; | |
| 224 | + int offset; /* Tells us which PATH_INFO/CLI args | |
| 225 | + part holds the "json" command, so | |
| 226 | + that we can account for sub-repos | |
| 227 | + and path prefixes. This is handled | |
| 228 | + differently for CLI and CGI modes. | |
| 229 | + */ | |
| 230 | + char const * commandStr /*"command" request param.*/; | |
| 231 | + } cmd; | |
| 232 | + struct { /* JSON POST data. */ | |
| 233 | + cson_value * v; | |
| 234 | + cson_object * o; | |
| 235 | + } post; | |
| 236 | + struct { /* GET/COOKIE params in JSON mode. | |
| 237 | + FIXME (stephan): verify that this is | |
| 238 | + still used and remove if it is not. | |
| 239 | + */ | |
| 240 | + cson_value * v; | |
| 241 | + cson_object * o; | |
| 242 | + } param; | |
| 243 | + struct { | |
| 244 | + cson_value * v; | |
| 245 | + cson_object * o; | |
| 246 | + } reqPayload; /* request payload object (if any) */ | |
| 247 | + struct { /* response warnings */ | |
| 248 | + cson_value * v; | |
| 249 | + cson_array * a; | |
| 250 | + } warnings; | |
| 251 | + } json; | |
| 252 | +#endif /* FOSSIL_ENABLE_JSON */ | |
| 193 | 253 | }; |
| 194 | 254 | |
| 195 | 255 | /* |
| 196 | 256 | ** Macro for debugging: |
| 197 | 257 | */ |
| @@ -252,10 +312,25 @@ | ||
| 252 | 312 | *pIndex = m; |
| 253 | 313 | return 0; |
| 254 | 314 | } |
| 255 | 315 | return 1+(cnt>1); |
| 256 | 316 | } |
| 317 | + | |
| 318 | +/* | |
| 319 | +** atexit() handler which frees up "some" of the resources | |
| 320 | +** used by fossil. | |
| 321 | +*/ | |
| 322 | +void fossil_atexit() { | |
| 323 | +#ifdef FOSSIL_ENABLE_JSON | |
| 324 | + cson_value_free(g.json.gc.v); | |
| 325 | + memset(&g.json, 0, sizeof(g.json)); | |
| 326 | +#endif | |
| 327 | + free(g.zErrMsg); | |
| 328 | + if(g.db){ | |
| 329 | + db_close(0); | |
| 330 | + } | |
| 331 | +} | |
| 257 | 332 | |
| 258 | 333 | /* |
| 259 | 334 | ** Search g.argv for arguments "--args FILENAME". If found, then |
| 260 | 335 | ** (1) remove the two arguments from g.argv |
| 261 | 336 | ** (2) Read the file FILENAME |
| @@ -343,28 +418,44 @@ | ||
| 343 | 418 | g.tcl.argv = argv; |
| 344 | 419 | g.tcl.interp = 0; |
| 345 | 420 | #endif |
| 346 | 421 | |
| 347 | 422 | sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0); |
| 423 | + memset(&g, 0, sizeof(g)); | |
| 348 | 424 | g.now = time(0); |
| 349 | 425 | g.argc = argc; |
| 350 | 426 | g.argv = argv; |
| 427 | +#ifdef FOSSIL_ENABLE_JSON | |
| 428 | +#if defined(NDEBUG) | |
| 429 | + g.json.errorDetailParanoia = 2 /* FIXME: make configurable | |
| 430 | + One problem we have here is that this | |
| 431 | + code is needed before the db is opened, | |
| 432 | + so we can't sql for it.*/; | |
| 433 | +#else | |
| 434 | + g.json.errorDetailParanoia = 0; | |
| 435 | +#endif | |
| 436 | + g.json.outOpt = cson_output_opt_empty; | |
| 437 | + g.json.outOpt.addNewline = 1; | |
| 438 | + g.json.outOpt.indentation = 1 /* in CGI/server mode this can be configured */; | |
| 439 | +#endif /* FOSSIL_ENABLE_JSON */ | |
| 351 | 440 | expand_args_option(); |
| 352 | 441 | argc = g.argc; |
| 353 | 442 | argv = g.argv; |
| 354 | 443 | for(i=0; i<argc; i++) g.argv[i] = fossil_mbcs_to_utf8(argv[i]); |
| 355 | 444 | if( getenv("GATEWAY_INTERFACE")!=0 && !find_option("nocgi", 0, 0)){ |
| 356 | 445 | zCmdName = "cgi"; |
| 446 | + g.isHTTP = 1; | |
| 357 | 447 | }else if( argc<2 ){ |
| 358 | 448 | fossil_print( |
| 359 | 449 | "Usage: %s COMMAND ...\n" |
| 360 | 450 | " or: %s help -- for a list of common commands\n" |
| 361 | 451 | " or: %s help COMMMAND -- for help with the named command\n" |
| 362 | 452 | " or: %s commands -- for a list of all commands\n", |
| 363 | 453 | argv[0], argv[0], argv[0], argv[0]); |
| 364 | 454 | fossil_exit(1); |
| 365 | 455 | }else{ |
| 456 | + g.isHTTP = 0; | |
| 366 | 457 | g.fQuiet = find_option("quiet", 0, 0)!=0; |
| 367 | 458 | g.fSqlTrace = find_option("sqltrace", 0, 0)!=0; |
| 368 | 459 | g.fSqlStats = find_option("sqlstats", 0, 0)!=0; |
| 369 | 460 | g.fSystemTrace = find_option("systemtrace", 0, 0)!=0; |
| 370 | 461 | if( g.fSqlTrace ) g.fSqlStats = 1; |
| @@ -405,10 +496,11 @@ | ||
| 405 | 496 | "%s: could be any of:%s\n" |
| 406 | 497 | "%s: use \"help\" for more information\n", |
| 407 | 498 | argv[0], zCmdName, argv[0], blob_str(&couldbe), argv[0]); |
| 408 | 499 | fossil_exit(1); |
| 409 | 500 | } |
| 501 | + atexit( fossil_atexit ); | |
| 410 | 502 | aCommand[idx].xFunc(); |
| 411 | 503 | fossil_exit(0); |
| 412 | 504 | /*NOT_REACHED*/ |
| 413 | 505 | return 0; |
| 414 | 506 | } |
| @@ -444,43 +536,70 @@ | ||
| 444 | 536 | ** routines never return. |
| 445 | 537 | */ |
| 446 | 538 | NORETURN void fossil_panic(const char *zFormat, ...){ |
| 447 | 539 | char *z; |
| 448 | 540 | va_list ap; |
| 541 | + int rc = 1; | |
| 449 | 542 | static int once = 1; |
| 450 | 543 | mainInFatalError = 1; |
| 451 | 544 | va_start(ap, zFormat); |
| 452 | 545 | z = vmprintf(zFormat, ap); |
| 453 | 546 | va_end(ap); |
| 454 | - if( g.cgiOutput && once ){ | |
| 455 | - once = 0; | |
| 456 | - cgi_printf("<p class=\"generalError\">%h</p>", z); | |
| 457 | - cgi_reply(); | |
| 458 | - }else{ | |
| 459 | - char *zOut = mprintf("%s: %s\n", fossil_nameofexe(), z); | |
| 460 | - fossil_puts(zOut, 1); | |
| 461 | - } | |
| 547 | +#ifdef FOSSIL_ENABLE_JSON | |
| 548 | + if( g.json.isJsonMode ){ | |
| 549 | + json_err( 0, z, 1 ); | |
| 550 | + if( g.isHTTP ){ | |
| 551 | + rc = 0 /* avoid HTTP 500 */; | |
| 552 | + } | |
| 553 | + } | |
| 554 | + else | |
| 555 | +#endif | |
| 556 | + { | |
| 557 | + if( g.cgiOutput && once ){ | |
| 558 | + once = 0; | |
| 559 | + cgi_printf("<p class=\"generalError\">%h</p>", z); | |
| 560 | + cgi_reply(); | |
| 561 | + }else{ | |
| 562 | + char *zOut = mprintf("%s: %s\n", fossil_nameofexe(), z); | |
| 563 | + fossil_puts(zOut, 1); | |
| 564 | + } | |
| 565 | + } | |
| 566 | + free(z); | |
| 462 | 567 | db_force_rollback(); |
| 463 | - fossil_exit(1); | |
| 568 | + fossil_exit(rc); | |
| 464 | 569 | } |
| 570 | + | |
| 465 | 571 | NORETURN void fossil_fatal(const char *zFormat, ...){ |
| 466 | 572 | char *z; |
| 573 | + int rc = 1; | |
| 467 | 574 | va_list ap; |
| 468 | 575 | mainInFatalError = 1; |
| 469 | 576 | va_start(ap, zFormat); |
| 470 | 577 | z = vmprintf(zFormat, ap); |
| 471 | 578 | va_end(ap); |
| 472 | - if( g.cgiOutput ){ | |
| 473 | - g.cgiOutput = 0; | |
| 474 | - cgi_printf("<p class=\"generalError\">%h</p>", z); | |
| 475 | - cgi_reply(); | |
| 476 | - }else{ | |
| 477 | - char *zOut = mprintf("\r%s: %s\n", fossil_nameofexe(), z); | |
| 478 | - fossil_puts(zOut, 1); | |
| 479 | - } | |
| 579 | +#ifdef FOSSIL_ENABLE_JSON | |
| 580 | + if( g.json.isJsonMode ){ | |
| 581 | + json_err( g.json.resultCode, z, 1 ); | |
| 582 | + if( g.isHTTP ){ | |
| 583 | + rc = 0 /* avoid HTTP 500 */; | |
| 584 | + } | |
| 585 | + } | |
| 586 | + else | |
| 587 | +#endif | |
| 588 | + { | |
| 589 | + if( g.cgiOutput ){ | |
| 590 | + g.cgiOutput = 0; | |
| 591 | + cgi_printf("<p class=\"generalError\">%h</p>", z); | |
| 592 | + cgi_reply(); | |
| 593 | + }else{ | |
| 594 | + char *zOut = mprintf("\r%s: %s\n", fossil_nameofexe(), z); | |
| 595 | + fossil_puts(zOut, 1); | |
| 596 | + } | |
| 597 | + } | |
| 598 | + free(z); | |
| 480 | 599 | db_force_rollback(); |
| 481 | - fossil_exit(1); | |
| 600 | + fossil_exit(rc); | |
| 482 | 601 | } |
| 483 | 602 | |
| 484 | 603 | /* This routine works like fossil_fatal() except that if called |
| 485 | 604 | ** recursively, the recursive call is a no-op. |
| 486 | 605 | ** |
| @@ -491,25 +610,37 @@ | ||
| 491 | 610 | ** be prepared for this routine to return. |
| 492 | 611 | */ |
| 493 | 612 | void fossil_fatal_recursive(const char *zFormat, ...){ |
| 494 | 613 | char *z; |
| 495 | 614 | va_list ap; |
| 615 | + int rc = 1; | |
| 496 | 616 | if( mainInFatalError ) return; |
| 497 | 617 | mainInFatalError = 1; |
| 498 | 618 | va_start(ap, zFormat); |
| 499 | 619 | z = vmprintf(zFormat, ap); |
| 500 | 620 | va_end(ap); |
| 501 | - if( g.cgiOutput ){ | |
| 502 | - g.cgiOutput = 0; | |
| 503 | - cgi_printf("<p class=\"generalError\">%h</p>", z); | |
| 504 | - cgi_reply(); | |
| 505 | - }else{ | |
| 506 | - char *zOut = mprintf("\r%s: %s\n", fossil_nameofexe(), z); | |
| 507 | - fossil_puts(zOut, 1); | |
| 621 | +#ifdef FOSSIL_ENABLE_JSON | |
| 622 | + if( g.json.isJsonMode ){ | |
| 623 | + json_err( g.json.resultCode, z, 1 ); | |
| 624 | + if( g.isHTTP ){ | |
| 625 | + rc = 0 /* avoid HTTP 500 */; | |
| 626 | + } | |
| 627 | + } else | |
| 628 | +#endif | |
| 629 | + { | |
| 630 | + if( g.cgiOutput ){ | |
| 631 | + g.cgiOutput = 0; | |
| 632 | + cgi_printf("<p class=\"generalError\">%h</p>", z); | |
| 633 | + cgi_reply(); | |
| 634 | + }else{ | |
| 635 | + char *zOut = mprintf("\r%s: %s\n", fossil_nameofexe(), z); | |
| 636 | + fossil_puts(zOut, 1); | |
| 637 | + free(zOut); | |
| 638 | + } | |
| 508 | 639 | } |
| 509 | 640 | db_force_rollback(); |
| 510 | - fossil_exit(1); | |
| 641 | + fossil_exit(rc); | |
| 511 | 642 | } |
| 512 | 643 | |
| 513 | 644 | |
| 514 | 645 | /* Print a warning message */ |
| 515 | 646 | void fossil_warning(const char *zFormat, ...){ |
| @@ -516,17 +647,25 @@ | ||
| 516 | 647 | char *z; |
| 517 | 648 | va_list ap; |
| 518 | 649 | va_start(ap, zFormat); |
| 519 | 650 | z = vmprintf(zFormat, ap); |
| 520 | 651 | va_end(ap); |
| 521 | - if( g.cgiOutput ){ | |
| 522 | - cgi_printf("<p class=\"generalError\">%h</p>", z); | |
| 523 | - }else{ | |
| 524 | - char *zOut = mprintf("\r%s: %s\n", fossil_nameofexe(), z); | |
| 525 | - fossil_puts(zOut, 1); | |
| 526 | - free(zOut); | |
| 652 | +#ifdef FOSSIL_ENABLE_JSON | |
| 653 | + if(g.json.isJsonMode){ | |
| 654 | + json_warn( FSL_JSON_W_UNKNOWN, z ); | |
| 655 | + }else | |
| 656 | +#endif | |
| 657 | + { | |
| 658 | + if( g.cgiOutput ){ | |
| 659 | + cgi_printf("<p class=\"generalError\">%h</p>", z); | |
| 660 | + }else{ | |
| 661 | + char *zOut = mprintf("\r%s: %s\n", fossil_nameofexe(), z); | |
| 662 | + fossil_puts(zOut, 1); | |
| 663 | + free(zOut); | |
| 664 | + } | |
| 527 | 665 | } |
| 666 | + free(z); | |
| 528 | 667 | } |
| 529 | 668 | |
| 530 | 669 | /* |
| 531 | 670 | ** Malloc and free routines that cannot fail |
| 532 | 671 | */ |
| @@ -1065,10 +1204,16 @@ | ||
| 1065 | 1204 | |
| 1066 | 1205 | if( szFile<1024 ){ |
| 1067 | 1206 | if( zNotFound ){ |
| 1068 | 1207 | cgi_redirect(zNotFound); |
| 1069 | 1208 | }else{ |
| 1209 | +#ifdef FOSSIL_ENABLE_JSON | |
| 1210 | + if(g.json.isJsonMode){ | |
| 1211 | + json_err(FSL_JSON_E_RESOURCE_NOT_FOUND,NULL,1); | |
| 1212 | + return; | |
| 1213 | + } | |
| 1214 | +#endif | |
| 1070 | 1215 | @ <h1>Not Found</h1> |
| 1071 | 1216 | cgi_set_status(404, "not found"); |
| 1072 | 1217 | cgi_reply(); |
| 1073 | 1218 | } |
| 1074 | 1219 | return; |
| @@ -1096,11 +1241,17 @@ | ||
| 1096 | 1241 | zPathInfo = "/xfer"; |
| 1097 | 1242 | } |
| 1098 | 1243 | set_base_url(); |
| 1099 | 1244 | if( zPathInfo==0 || zPathInfo[0]==0 |
| 1100 | 1245 | || (zPathInfo[0]=='/' && zPathInfo[1]==0) ){ |
| 1101 | - fossil_redirect_home(); | |
| 1246 | +#ifdef FOSSIL_ENABLE_JSON | |
| 1247 | + if(g.json.isJsonMode){ | |
| 1248 | + json_err(FSL_JSON_E_RESOURCE_NOT_FOUND,NULL,1); | |
| 1249 | + fossil_exit(0); | |
| 1250 | + } | |
| 1251 | +#endif | |
| 1252 | + fossil_redirect_home() /*does not return*/; | |
| 1102 | 1253 | }else{ |
| 1103 | 1254 | zPath = mprintf("%s", zPathInfo); |
| 1104 | 1255 | } |
| 1105 | 1256 | |
| 1106 | 1257 | /* Make g.zPath point to the first element of the path. Make |
| @@ -1157,10 +1308,12 @@ | ||
| 1157 | 1308 | break; |
| 1158 | 1309 | } |
| 1159 | 1310 | if( g.zExtra ){ |
| 1160 | 1311 | /* CGI parameters get this treatment elsewhere, but places like getfile |
| 1161 | 1312 | ** will use g.zExtra directly. |
| 1313 | + ** Reminder: the login mechanism uses 'name' differently, and may | |
| 1314 | + ** eventually have a problem/collision with this. | |
| 1162 | 1315 | */ |
| 1163 | 1316 | dehttpize(g.zExtra); |
| 1164 | 1317 | cgi_set_parameter_nocopy("name", g.zExtra); |
| 1165 | 1318 | } |
| 1166 | 1319 | |
| @@ -1167,17 +1320,31 @@ | ||
| 1167 | 1320 | /* Locate the method specified by the path and execute the function |
| 1168 | 1321 | ** that implements that method. |
| 1169 | 1322 | */ |
| 1170 | 1323 | if( name_search(g.zPath, aWebpage, count(aWebpage), &idx) && |
| 1171 | 1324 | name_search("not_found", aWebpage, count(aWebpage), &idx) ){ |
| 1172 | - cgi_set_status(404,"Not Found"); | |
| 1173 | - @ <h1>Not Found</h1> | |
| 1174 | - @ <p>Page not found: %h(g.zPath)</p> | |
| 1325 | +#ifdef FOSSIL_ENABLE_JSON | |
| 1326 | + if(g.json.isJsonMode){ | |
| 1327 | + json_err(FSL_JSON_E_RESOURCE_NOT_FOUND,NULL,0); | |
| 1328 | + }else | |
| 1329 | +#endif | |
| 1330 | + { | |
| 1331 | + cgi_set_status(404,"Not Found"); | |
| 1332 | + @ <h1>Not Found</h1> | |
| 1333 | + @ <p>Page not found: %h(g.zPath)</p> | |
| 1334 | + } | |
| 1175 | 1335 | }else if( aWebpage[idx].xFunc!=page_xfer && db_schema_is_outofdate() ){ |
| 1176 | - @ <h1>Server Configuration Error</h1> | |
| 1177 | - @ <p>The database schema on the server is out-of-date. Please ask | |
| 1178 | - @ the administrator to run <b>fossil rebuild</b>.</p> | |
| 1336 | +#ifdef FOSSIL_ENABLE_JSON | |
| 1337 | + if(g.json.isJsonMode){ | |
| 1338 | + json_err(FSL_JSON_E_DB_NEEDS_REBUILD,NULL,0); | |
| 1339 | + }else | |
| 1340 | +#endif | |
| 1341 | + { | |
| 1342 | + @ <h1>Server Configuration Error</h1> | |
| 1343 | + @ <p>The database schema on the server is out-of-date. Please ask | |
| 1344 | + @ the administrator to run <b>fossil rebuild</b>.</p> | |
| 1345 | + } | |
| 1179 | 1346 | }else{ |
| 1180 | 1347 | aWebpage[idx].xFunc(); |
| 1181 | 1348 | } |
| 1182 | 1349 | |
| 1183 | 1350 | /* Return the result. |
| 1184 | 1351 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -23,14 +23,17 @@ | |
| 23 | #include <string.h> |
| 24 | #include <time.h> |
| 25 | #include <fcntl.h> |
| 26 | #include <sys/types.h> |
| 27 | #include <sys/stat.h> |
| 28 | |
| 29 | |
| 30 | #if INTERFACE |
| 31 | |
| 32 | #ifdef FOSSIL_ENABLE_TCL |
| 33 | #include "tcl.h" |
| 34 | #endif |
| 35 | |
| 36 | /* |
| @@ -132,10 +135,11 @@ | |
| 132 | int xlinkClusterOnly; /* Set when cloning. Only process clusters */ |
| 133 | int fTimeFormat; /* 1 for UTC. 2 for localtime. 0 not yet selected */ |
| 134 | int *aCommitFile; /* Array of files to be committed */ |
| 135 | int markPrivate; /* All new artifacts are private if true */ |
| 136 | int clockSkewSeen; /* True if clocks on client and server out of sync */ |
| 137 | |
| 138 | int urlIsFile; /* True if a "file:" url */ |
| 139 | int urlIsHttps; /* True if a "https:" url */ |
| 140 | int urlIsSsh; /* True if an "ssh:" url */ |
| 141 | char *urlName; /* Hostname for http: or filename for file: */ |
| @@ -148,11 +152,11 @@ | |
| 148 | char *urlPasswd; /* Password for http: */ |
| 149 | char *urlCanonical; /* Canonical representation of the URL */ |
| 150 | char *urlProxyAuth; /* Proxy-Authorizer: string */ |
| 151 | char *urlFossil; /* The path of the ?fossil=path suffix on ssh: */ |
| 152 | int dontKeepUrl; /* Do not persist the URL */ |
| 153 | |
| 154 | const char *zLogin; /* Login name. "" if not logged in. */ |
| 155 | const char *zSSLIdentity; /* Value of --ssl-identity option, filename of SSL client identity */ |
| 156 | int useLocalauth; /* No login required if from 127.0.0.1 */ |
| 157 | int noPswd; /* Logged in without password (on 127.0.0.1) */ |
| 158 | int userUid; /* Integer user id */ |
| @@ -188,10 +192,66 @@ | |
| 188 | const char *azAuxVal[MX_AUX]; /* Value of each aux() or option() value */ |
| 189 | const char **azAuxOpt[MX_AUX]; /* Options of each option() value */ |
| 190 | int anAuxCols[MX_AUX]; /* Number of columns for option() values */ |
| 191 | |
| 192 | int allowSymlinks; /* Cached "allow-symlinks" option */ |
| 193 | }; |
| 194 | |
| 195 | /* |
| 196 | ** Macro for debugging: |
| 197 | */ |
| @@ -252,10 +312,25 @@ | |
| 252 | *pIndex = m; |
| 253 | return 0; |
| 254 | } |
| 255 | return 1+(cnt>1); |
| 256 | } |
| 257 | |
| 258 | /* |
| 259 | ** Search g.argv for arguments "--args FILENAME". If found, then |
| 260 | ** (1) remove the two arguments from g.argv |
| 261 | ** (2) Read the file FILENAME |
| @@ -343,28 +418,44 @@ | |
| 343 | g.tcl.argv = argv; |
| 344 | g.tcl.interp = 0; |
| 345 | #endif |
| 346 | |
| 347 | sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0); |
| 348 | g.now = time(0); |
| 349 | g.argc = argc; |
| 350 | g.argv = argv; |
| 351 | expand_args_option(); |
| 352 | argc = g.argc; |
| 353 | argv = g.argv; |
| 354 | for(i=0; i<argc; i++) g.argv[i] = fossil_mbcs_to_utf8(argv[i]); |
| 355 | if( getenv("GATEWAY_INTERFACE")!=0 && !find_option("nocgi", 0, 0)){ |
| 356 | zCmdName = "cgi"; |
| 357 | }else if( argc<2 ){ |
| 358 | fossil_print( |
| 359 | "Usage: %s COMMAND ...\n" |
| 360 | " or: %s help -- for a list of common commands\n" |
| 361 | " or: %s help COMMMAND -- for help with the named command\n" |
| 362 | " or: %s commands -- for a list of all commands\n", |
| 363 | argv[0], argv[0], argv[0], argv[0]); |
| 364 | fossil_exit(1); |
| 365 | }else{ |
| 366 | g.fQuiet = find_option("quiet", 0, 0)!=0; |
| 367 | g.fSqlTrace = find_option("sqltrace", 0, 0)!=0; |
| 368 | g.fSqlStats = find_option("sqlstats", 0, 0)!=0; |
| 369 | g.fSystemTrace = find_option("systemtrace", 0, 0)!=0; |
| 370 | if( g.fSqlTrace ) g.fSqlStats = 1; |
| @@ -405,10 +496,11 @@ | |
| 405 | "%s: could be any of:%s\n" |
| 406 | "%s: use \"help\" for more information\n", |
| 407 | argv[0], zCmdName, argv[0], blob_str(&couldbe), argv[0]); |
| 408 | fossil_exit(1); |
| 409 | } |
| 410 | aCommand[idx].xFunc(); |
| 411 | fossil_exit(0); |
| 412 | /*NOT_REACHED*/ |
| 413 | return 0; |
| 414 | } |
| @@ -444,43 +536,70 @@ | |
| 444 | ** routines never return. |
| 445 | */ |
| 446 | NORETURN void fossil_panic(const char *zFormat, ...){ |
| 447 | char *z; |
| 448 | va_list ap; |
| 449 | static int once = 1; |
| 450 | mainInFatalError = 1; |
| 451 | va_start(ap, zFormat); |
| 452 | z = vmprintf(zFormat, ap); |
| 453 | va_end(ap); |
| 454 | if( g.cgiOutput && once ){ |
| 455 | once = 0; |
| 456 | cgi_printf("<p class=\"generalError\">%h</p>", z); |
| 457 | cgi_reply(); |
| 458 | }else{ |
| 459 | char *zOut = mprintf("%s: %s\n", fossil_nameofexe(), z); |
| 460 | fossil_puts(zOut, 1); |
| 461 | } |
| 462 | db_force_rollback(); |
| 463 | fossil_exit(1); |
| 464 | } |
| 465 | NORETURN void fossil_fatal(const char *zFormat, ...){ |
| 466 | char *z; |
| 467 | va_list ap; |
| 468 | mainInFatalError = 1; |
| 469 | va_start(ap, zFormat); |
| 470 | z = vmprintf(zFormat, ap); |
| 471 | va_end(ap); |
| 472 | if( g.cgiOutput ){ |
| 473 | g.cgiOutput = 0; |
| 474 | cgi_printf("<p class=\"generalError\">%h</p>", z); |
| 475 | cgi_reply(); |
| 476 | }else{ |
| 477 | char *zOut = mprintf("\r%s: %s\n", fossil_nameofexe(), z); |
| 478 | fossil_puts(zOut, 1); |
| 479 | } |
| 480 | db_force_rollback(); |
| 481 | fossil_exit(1); |
| 482 | } |
| 483 | |
| 484 | /* This routine works like fossil_fatal() except that if called |
| 485 | ** recursively, the recursive call is a no-op. |
| 486 | ** |
| @@ -491,25 +610,37 @@ | |
| 491 | ** be prepared for this routine to return. |
| 492 | */ |
| 493 | void fossil_fatal_recursive(const char *zFormat, ...){ |
| 494 | char *z; |
| 495 | va_list ap; |
| 496 | if( mainInFatalError ) return; |
| 497 | mainInFatalError = 1; |
| 498 | va_start(ap, zFormat); |
| 499 | z = vmprintf(zFormat, ap); |
| 500 | va_end(ap); |
| 501 | if( g.cgiOutput ){ |
| 502 | g.cgiOutput = 0; |
| 503 | cgi_printf("<p class=\"generalError\">%h</p>", z); |
| 504 | cgi_reply(); |
| 505 | }else{ |
| 506 | char *zOut = mprintf("\r%s: %s\n", fossil_nameofexe(), z); |
| 507 | fossil_puts(zOut, 1); |
| 508 | } |
| 509 | db_force_rollback(); |
| 510 | fossil_exit(1); |
| 511 | } |
| 512 | |
| 513 | |
| 514 | /* Print a warning message */ |
| 515 | void fossil_warning(const char *zFormat, ...){ |
| @@ -516,17 +647,25 @@ | |
| 516 | char *z; |
| 517 | va_list ap; |
| 518 | va_start(ap, zFormat); |
| 519 | z = vmprintf(zFormat, ap); |
| 520 | va_end(ap); |
| 521 | if( g.cgiOutput ){ |
| 522 | cgi_printf("<p class=\"generalError\">%h</p>", z); |
| 523 | }else{ |
| 524 | char *zOut = mprintf("\r%s: %s\n", fossil_nameofexe(), z); |
| 525 | fossil_puts(zOut, 1); |
| 526 | free(zOut); |
| 527 | } |
| 528 | } |
| 529 | |
| 530 | /* |
| 531 | ** Malloc and free routines that cannot fail |
| 532 | */ |
| @@ -1065,10 +1204,16 @@ | |
| 1065 | |
| 1066 | if( szFile<1024 ){ |
| 1067 | if( zNotFound ){ |
| 1068 | cgi_redirect(zNotFound); |
| 1069 | }else{ |
| 1070 | @ <h1>Not Found</h1> |
| 1071 | cgi_set_status(404, "not found"); |
| 1072 | cgi_reply(); |
| 1073 | } |
| 1074 | return; |
| @@ -1096,11 +1241,17 @@ | |
| 1096 | zPathInfo = "/xfer"; |
| 1097 | } |
| 1098 | set_base_url(); |
| 1099 | if( zPathInfo==0 || zPathInfo[0]==0 |
| 1100 | || (zPathInfo[0]=='/' && zPathInfo[1]==0) ){ |
| 1101 | fossil_redirect_home(); |
| 1102 | }else{ |
| 1103 | zPath = mprintf("%s", zPathInfo); |
| 1104 | } |
| 1105 | |
| 1106 | /* Make g.zPath point to the first element of the path. Make |
| @@ -1157,10 +1308,12 @@ | |
| 1157 | break; |
| 1158 | } |
| 1159 | if( g.zExtra ){ |
| 1160 | /* CGI parameters get this treatment elsewhere, but places like getfile |
| 1161 | ** will use g.zExtra directly. |
| 1162 | */ |
| 1163 | dehttpize(g.zExtra); |
| 1164 | cgi_set_parameter_nocopy("name", g.zExtra); |
| 1165 | } |
| 1166 | |
| @@ -1167,17 +1320,31 @@ | |
| 1167 | /* Locate the method specified by the path and execute the function |
| 1168 | ** that implements that method. |
| 1169 | */ |
| 1170 | if( name_search(g.zPath, aWebpage, count(aWebpage), &idx) && |
| 1171 | name_search("not_found", aWebpage, count(aWebpage), &idx) ){ |
| 1172 | cgi_set_status(404,"Not Found"); |
| 1173 | @ <h1>Not Found</h1> |
| 1174 | @ <p>Page not found: %h(g.zPath)</p> |
| 1175 | }else if( aWebpage[idx].xFunc!=page_xfer && db_schema_is_outofdate() ){ |
| 1176 | @ <h1>Server Configuration Error</h1> |
| 1177 | @ <p>The database schema on the server is out-of-date. Please ask |
| 1178 | @ the administrator to run <b>fossil rebuild</b>.</p> |
| 1179 | }else{ |
| 1180 | aWebpage[idx].xFunc(); |
| 1181 | } |
| 1182 | |
| 1183 | /* Return the result. |
| 1184 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -23,14 +23,17 @@ | |
| 23 | #include <string.h> |
| 24 | #include <time.h> |
| 25 | #include <fcntl.h> |
| 26 | #include <sys/types.h> |
| 27 | #include <sys/stat.h> |
| 28 | #include <stdlib.h> /* atexit() */ |
| 29 | |
| 30 | #if INTERFACE |
| 31 | #ifdef FOSSIL_ENABLE_JSON |
| 32 | # include "cson_amalgamation.h" /* JSON API. Needed inside the INTERFACE block! */ |
| 33 | # include "json_detail.h" |
| 34 | #endif |
| 35 | #ifdef FOSSIL_ENABLE_TCL |
| 36 | #include "tcl.h" |
| 37 | #endif |
| 38 | |
| 39 | /* |
| @@ -132,10 +135,11 @@ | |
| 135 | int xlinkClusterOnly; /* Set when cloning. Only process clusters */ |
| 136 | int fTimeFormat; /* 1 for UTC. 2 for localtime. 0 not yet selected */ |
| 137 | int *aCommitFile; /* Array of files to be committed */ |
| 138 | int markPrivate; /* All new artifacts are private if true */ |
| 139 | int clockSkewSeen; /* True if clocks on client and server out of sync */ |
| 140 | int isHTTP; /* True if running in server/CGI modes, else assume CLI. */ |
| 141 | |
| 142 | int urlIsFile; /* True if a "file:" url */ |
| 143 | int urlIsHttps; /* True if a "https:" url */ |
| 144 | int urlIsSsh; /* True if an "ssh:" url */ |
| 145 | char *urlName; /* Hostname for http: or filename for file: */ |
| @@ -148,11 +152,11 @@ | |
| 152 | char *urlPasswd; /* Password for http: */ |
| 153 | char *urlCanonical; /* Canonical representation of the URL */ |
| 154 | char *urlProxyAuth; /* Proxy-Authorizer: string */ |
| 155 | char *urlFossil; /* The path of the ?fossil=path suffix on ssh: */ |
| 156 | int dontKeepUrl; /* Do not persist the URL */ |
| 157 | |
| 158 | const char *zLogin; /* Login name. "" if not logged in. */ |
| 159 | const char *zSSLIdentity; /* Value of --ssl-identity option, filename of SSL client identity */ |
| 160 | int useLocalauth; /* No login required if from 127.0.0.1 */ |
| 161 | int noPswd; /* Logged in without password (on 127.0.0.1) */ |
| 162 | int userUid; /* Integer user id */ |
| @@ -188,10 +192,66 @@ | |
| 192 | const char *azAuxVal[MX_AUX]; /* Value of each aux() or option() value */ |
| 193 | const char **azAuxOpt[MX_AUX]; /* Options of each option() value */ |
| 194 | int anAuxCols[MX_AUX]; /* Number of columns for option() values */ |
| 195 | |
| 196 | int allowSymlinks; /* Cached "allow-symlinks" option */ |
| 197 | |
| 198 | #ifdef FOSSIL_ENABLE_JSON |
| 199 | struct FossilJsonBits { |
| 200 | int isJsonMode; /* True if running in JSON mode, else |
| 201 | false. This changes how errors are |
| 202 | reported. In JSON mode we try to |
| 203 | always output JSON-form error |
| 204 | responses and always exit() with |
| 205 | code 0 to avoid an HTTP 500 error. |
| 206 | */ |
| 207 | int resultCode; /* used for passing back specific codes from /json callbacks. */ |
| 208 | int errorDetailParanoia; /* 0=full error codes, 1=%10, 2=%100, 3=%1000 */ |
| 209 | cson_output_opt outOpt; /* formatting options for JSON mode. */ |
| 210 | cson_value * authToken; /* authentication token */ |
| 211 | char const * jsonp; /* Name of JSONP function wrapper. */ |
| 212 | unsigned char dispatchDepth /* Tells JSON command dispatching |
| 213 | which argument we are currently |
| 214 | working on. For this purpose, arg#0 |
| 215 | is the "json" path/CLI arg. |
| 216 | */; |
| 217 | struct { /* "garbage collector" */ |
| 218 | cson_value * v; |
| 219 | cson_array * a; |
| 220 | } gc; |
| 221 | struct { /* JSON POST data. */ |
| 222 | cson_value * v; |
| 223 | cson_array * a; |
| 224 | int offset; /* Tells us which PATH_INFO/CLI args |
| 225 | part holds the "json" command, so |
| 226 | that we can account for sub-repos |
| 227 | and path prefixes. This is handled |
| 228 | differently for CLI and CGI modes. |
| 229 | */ |
| 230 | char const * commandStr /*"command" request param.*/; |
| 231 | } cmd; |
| 232 | struct { /* JSON POST data. */ |
| 233 | cson_value * v; |
| 234 | cson_object * o; |
| 235 | } post; |
| 236 | struct { /* GET/COOKIE params in JSON mode. |
| 237 | FIXME (stephan): verify that this is |
| 238 | still used and remove if it is not. |
| 239 | */ |
| 240 | cson_value * v; |
| 241 | cson_object * o; |
| 242 | } param; |
| 243 | struct { |
| 244 | cson_value * v; |
| 245 | cson_object * o; |
| 246 | } reqPayload; /* request payload object (if any) */ |
| 247 | struct { /* response warnings */ |
| 248 | cson_value * v; |
| 249 | cson_array * a; |
| 250 | } warnings; |
| 251 | } json; |
| 252 | #endif /* FOSSIL_ENABLE_JSON */ |
| 253 | }; |
| 254 | |
| 255 | /* |
| 256 | ** Macro for debugging: |
| 257 | */ |
| @@ -252,10 +312,25 @@ | |
| 312 | *pIndex = m; |
| 313 | return 0; |
| 314 | } |
| 315 | return 1+(cnt>1); |
| 316 | } |
| 317 | |
| 318 | /* |
| 319 | ** atexit() handler which frees up "some" of the resources |
| 320 | ** used by fossil. |
| 321 | */ |
| 322 | void fossil_atexit() { |
| 323 | #ifdef FOSSIL_ENABLE_JSON |
| 324 | cson_value_free(g.json.gc.v); |
| 325 | memset(&g.json, 0, sizeof(g.json)); |
| 326 | #endif |
| 327 | free(g.zErrMsg); |
| 328 | if(g.db){ |
| 329 | db_close(0); |
| 330 | } |
| 331 | } |
| 332 | |
| 333 | /* |
| 334 | ** Search g.argv for arguments "--args FILENAME". If found, then |
| 335 | ** (1) remove the two arguments from g.argv |
| 336 | ** (2) Read the file FILENAME |
| @@ -343,28 +418,44 @@ | |
| 418 | g.tcl.argv = argv; |
| 419 | g.tcl.interp = 0; |
| 420 | #endif |
| 421 | |
| 422 | sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0); |
| 423 | memset(&g, 0, sizeof(g)); |
| 424 | g.now = time(0); |
| 425 | g.argc = argc; |
| 426 | g.argv = argv; |
| 427 | #ifdef FOSSIL_ENABLE_JSON |
| 428 | #if defined(NDEBUG) |
| 429 | g.json.errorDetailParanoia = 2 /* FIXME: make configurable |
| 430 | One problem we have here is that this |
| 431 | code is needed before the db is opened, |
| 432 | so we can't sql for it.*/; |
| 433 | #else |
| 434 | g.json.errorDetailParanoia = 0; |
| 435 | #endif |
| 436 | g.json.outOpt = cson_output_opt_empty; |
| 437 | g.json.outOpt.addNewline = 1; |
| 438 | g.json.outOpt.indentation = 1 /* in CGI/server mode this can be configured */; |
| 439 | #endif /* FOSSIL_ENABLE_JSON */ |
| 440 | expand_args_option(); |
| 441 | argc = g.argc; |
| 442 | argv = g.argv; |
| 443 | for(i=0; i<argc; i++) g.argv[i] = fossil_mbcs_to_utf8(argv[i]); |
| 444 | if( getenv("GATEWAY_INTERFACE")!=0 && !find_option("nocgi", 0, 0)){ |
| 445 | zCmdName = "cgi"; |
| 446 | g.isHTTP = 1; |
| 447 | }else if( argc<2 ){ |
| 448 | fossil_print( |
| 449 | "Usage: %s COMMAND ...\n" |
| 450 | " or: %s help -- for a list of common commands\n" |
| 451 | " or: %s help COMMMAND -- for help with the named command\n" |
| 452 | " or: %s commands -- for a list of all commands\n", |
| 453 | argv[0], argv[0], argv[0], argv[0]); |
| 454 | fossil_exit(1); |
| 455 | }else{ |
| 456 | g.isHTTP = 0; |
| 457 | g.fQuiet = find_option("quiet", 0, 0)!=0; |
| 458 | g.fSqlTrace = find_option("sqltrace", 0, 0)!=0; |
| 459 | g.fSqlStats = find_option("sqlstats", 0, 0)!=0; |
| 460 | g.fSystemTrace = find_option("systemtrace", 0, 0)!=0; |
| 461 | if( g.fSqlTrace ) g.fSqlStats = 1; |
| @@ -405,10 +496,11 @@ | |
| 496 | "%s: could be any of:%s\n" |
| 497 | "%s: use \"help\" for more information\n", |
| 498 | argv[0], zCmdName, argv[0], blob_str(&couldbe), argv[0]); |
| 499 | fossil_exit(1); |
| 500 | } |
| 501 | atexit( fossil_atexit ); |
| 502 | aCommand[idx].xFunc(); |
| 503 | fossil_exit(0); |
| 504 | /*NOT_REACHED*/ |
| 505 | return 0; |
| 506 | } |
| @@ -444,43 +536,70 @@ | |
| 536 | ** routines never return. |
| 537 | */ |
| 538 | NORETURN void fossil_panic(const char *zFormat, ...){ |
| 539 | char *z; |
| 540 | va_list ap; |
| 541 | int rc = 1; |
| 542 | static int once = 1; |
| 543 | mainInFatalError = 1; |
| 544 | va_start(ap, zFormat); |
| 545 | z = vmprintf(zFormat, ap); |
| 546 | va_end(ap); |
| 547 | #ifdef FOSSIL_ENABLE_JSON |
| 548 | if( g.json.isJsonMode ){ |
| 549 | json_err( 0, z, 1 ); |
| 550 | if( g.isHTTP ){ |
| 551 | rc = 0 /* avoid HTTP 500 */; |
| 552 | } |
| 553 | } |
| 554 | else |
| 555 | #endif |
| 556 | { |
| 557 | if( g.cgiOutput && once ){ |
| 558 | once = 0; |
| 559 | cgi_printf("<p class=\"generalError\">%h</p>", z); |
| 560 | cgi_reply(); |
| 561 | }else{ |
| 562 | char *zOut = mprintf("%s: %s\n", fossil_nameofexe(), z); |
| 563 | fossil_puts(zOut, 1); |
| 564 | } |
| 565 | } |
| 566 | free(z); |
| 567 | db_force_rollback(); |
| 568 | fossil_exit(rc); |
| 569 | } |
| 570 | |
| 571 | NORETURN void fossil_fatal(const char *zFormat, ...){ |
| 572 | char *z; |
| 573 | int rc = 1; |
| 574 | va_list ap; |
| 575 | mainInFatalError = 1; |
| 576 | va_start(ap, zFormat); |
| 577 | z = vmprintf(zFormat, ap); |
| 578 | va_end(ap); |
| 579 | #ifdef FOSSIL_ENABLE_JSON |
| 580 | if( g.json.isJsonMode ){ |
| 581 | json_err( g.json.resultCode, z, 1 ); |
| 582 | if( g.isHTTP ){ |
| 583 | rc = 0 /* avoid HTTP 500 */; |
| 584 | } |
| 585 | } |
| 586 | else |
| 587 | #endif |
| 588 | { |
| 589 | if( g.cgiOutput ){ |
| 590 | g.cgiOutput = 0; |
| 591 | cgi_printf("<p class=\"generalError\">%h</p>", z); |
| 592 | cgi_reply(); |
| 593 | }else{ |
| 594 | char *zOut = mprintf("\r%s: %s\n", fossil_nameofexe(), z); |
| 595 | fossil_puts(zOut, 1); |
| 596 | } |
| 597 | } |
| 598 | free(z); |
| 599 | db_force_rollback(); |
| 600 | fossil_exit(rc); |
| 601 | } |
| 602 | |
| 603 | /* This routine works like fossil_fatal() except that if called |
| 604 | ** recursively, the recursive call is a no-op. |
| 605 | ** |
| @@ -491,25 +610,37 @@ | |
| 610 | ** be prepared for this routine to return. |
| 611 | */ |
| 612 | void fossil_fatal_recursive(const char *zFormat, ...){ |
| 613 | char *z; |
| 614 | va_list ap; |
| 615 | int rc = 1; |
| 616 | if( mainInFatalError ) return; |
| 617 | mainInFatalError = 1; |
| 618 | va_start(ap, zFormat); |
| 619 | z = vmprintf(zFormat, ap); |
| 620 | va_end(ap); |
| 621 | #ifdef FOSSIL_ENABLE_JSON |
| 622 | if( g.json.isJsonMode ){ |
| 623 | json_err( g.json.resultCode, z, 1 ); |
| 624 | if( g.isHTTP ){ |
| 625 | rc = 0 /* avoid HTTP 500 */; |
| 626 | } |
| 627 | } else |
| 628 | #endif |
| 629 | { |
| 630 | if( g.cgiOutput ){ |
| 631 | g.cgiOutput = 0; |
| 632 | cgi_printf("<p class=\"generalError\">%h</p>", z); |
| 633 | cgi_reply(); |
| 634 | }else{ |
| 635 | char *zOut = mprintf("\r%s: %s\n", fossil_nameofexe(), z); |
| 636 | fossil_puts(zOut, 1); |
| 637 | free(zOut); |
| 638 | } |
| 639 | } |
| 640 | db_force_rollback(); |
| 641 | fossil_exit(rc); |
| 642 | } |
| 643 | |
| 644 | |
| 645 | /* Print a warning message */ |
| 646 | void fossil_warning(const char *zFormat, ...){ |
| @@ -516,17 +647,25 @@ | |
| 647 | char *z; |
| 648 | va_list ap; |
| 649 | va_start(ap, zFormat); |
| 650 | z = vmprintf(zFormat, ap); |
| 651 | va_end(ap); |
| 652 | #ifdef FOSSIL_ENABLE_JSON |
| 653 | if(g.json.isJsonMode){ |
| 654 | json_warn( FSL_JSON_W_UNKNOWN, z ); |
| 655 | }else |
| 656 | #endif |
| 657 | { |
| 658 | if( g.cgiOutput ){ |
| 659 | cgi_printf("<p class=\"generalError\">%h</p>", z); |
| 660 | }else{ |
| 661 | char *zOut = mprintf("\r%s: %s\n", fossil_nameofexe(), z); |
| 662 | fossil_puts(zOut, 1); |
| 663 | free(zOut); |
| 664 | } |
| 665 | } |
| 666 | free(z); |
| 667 | } |
| 668 | |
| 669 | /* |
| 670 | ** Malloc and free routines that cannot fail |
| 671 | */ |
| @@ -1065,10 +1204,16 @@ | |
| 1204 | |
| 1205 | if( szFile<1024 ){ |
| 1206 | if( zNotFound ){ |
| 1207 | cgi_redirect(zNotFound); |
| 1208 | }else{ |
| 1209 | #ifdef FOSSIL_ENABLE_JSON |
| 1210 | if(g.json.isJsonMode){ |
| 1211 | json_err(FSL_JSON_E_RESOURCE_NOT_FOUND,NULL,1); |
| 1212 | return; |
| 1213 | } |
| 1214 | #endif |
| 1215 | @ <h1>Not Found</h1> |
| 1216 | cgi_set_status(404, "not found"); |
| 1217 | cgi_reply(); |
| 1218 | } |
| 1219 | return; |
| @@ -1096,11 +1241,17 @@ | |
| 1241 | zPathInfo = "/xfer"; |
| 1242 | } |
| 1243 | set_base_url(); |
| 1244 | if( zPathInfo==0 || zPathInfo[0]==0 |
| 1245 | || (zPathInfo[0]=='/' && zPathInfo[1]==0) ){ |
| 1246 | #ifdef FOSSIL_ENABLE_JSON |
| 1247 | if(g.json.isJsonMode){ |
| 1248 | json_err(FSL_JSON_E_RESOURCE_NOT_FOUND,NULL,1); |
| 1249 | fossil_exit(0); |
| 1250 | } |
| 1251 | #endif |
| 1252 | fossil_redirect_home() /*does not return*/; |
| 1253 | }else{ |
| 1254 | zPath = mprintf("%s", zPathInfo); |
| 1255 | } |
| 1256 | |
| 1257 | /* Make g.zPath point to the first element of the path. Make |
| @@ -1157,10 +1308,12 @@ | |
| 1308 | break; |
| 1309 | } |
| 1310 | if( g.zExtra ){ |
| 1311 | /* CGI parameters get this treatment elsewhere, but places like getfile |
| 1312 | ** will use g.zExtra directly. |
| 1313 | ** Reminder: the login mechanism uses 'name' differently, and may |
| 1314 | ** eventually have a problem/collision with this. |
| 1315 | */ |
| 1316 | dehttpize(g.zExtra); |
| 1317 | cgi_set_parameter_nocopy("name", g.zExtra); |
| 1318 | } |
| 1319 | |
| @@ -1167,17 +1320,31 @@ | |
| 1320 | /* Locate the method specified by the path and execute the function |
| 1321 | ** that implements that method. |
| 1322 | */ |
| 1323 | if( name_search(g.zPath, aWebpage, count(aWebpage), &idx) && |
| 1324 | name_search("not_found", aWebpage, count(aWebpage), &idx) ){ |
| 1325 | #ifdef FOSSIL_ENABLE_JSON |
| 1326 | if(g.json.isJsonMode){ |
| 1327 | json_err(FSL_JSON_E_RESOURCE_NOT_FOUND,NULL,0); |
| 1328 | }else |
| 1329 | #endif |
| 1330 | { |
| 1331 | cgi_set_status(404,"Not Found"); |
| 1332 | @ <h1>Not Found</h1> |
| 1333 | @ <p>Page not found: %h(g.zPath)</p> |
| 1334 | } |
| 1335 | }else if( aWebpage[idx].xFunc!=page_xfer && db_schema_is_outofdate() ){ |
| 1336 | #ifdef FOSSIL_ENABLE_JSON |
| 1337 | if(g.json.isJsonMode){ |
| 1338 | json_err(FSL_JSON_E_DB_NEEDS_REBUILD,NULL,0); |
| 1339 | }else |
| 1340 | #endif |
| 1341 | { |
| 1342 | @ <h1>Server Configuration Error</h1> |
| 1343 | @ <p>The database schema on the server is out-of-date. Please ask |
| 1344 | @ the administrator to run <b>fossil rebuild</b>.</p> |
| 1345 | } |
| 1346 | }else{ |
| 1347 | aWebpage[idx].xFunc(); |
| 1348 | } |
| 1349 | |
| 1350 | /* Return the result. |
| 1351 |
+117
-2
| --- src/main.mk | ||
| +++ src/main.mk | ||
| @@ -47,10 +47,21 @@ | ||
| 47 | 47 | $(SRCDIR)/http_socket.c \ |
| 48 | 48 | $(SRCDIR)/http_ssl.c \ |
| 49 | 49 | $(SRCDIR)/http_transport.c \ |
| 50 | 50 | $(SRCDIR)/import.c \ |
| 51 | 51 | $(SRCDIR)/info.c \ |
| 52 | + $(SRCDIR)/json.c \ | |
| 53 | + $(SRCDIR)/json_artifact.c \ | |
| 54 | + $(SRCDIR)/json_branch.c \ | |
| 55 | + $(SRCDIR)/json_diff.c \ | |
| 56 | + $(SRCDIR)/json_login.c \ | |
| 57 | + $(SRCDIR)/json_query.c \ | |
| 58 | + $(SRCDIR)/json_report.c \ | |
| 59 | + $(SRCDIR)/json_tag.c \ | |
| 60 | + $(SRCDIR)/json_timeline.c \ | |
| 61 | + $(SRCDIR)/json_user.c \ | |
| 62 | + $(SRCDIR)/json_wiki.c \ | |
| 52 | 63 | $(SRCDIR)/leaf.c \ |
| 53 | 64 | $(SRCDIR)/login.c \ |
| 54 | 65 | $(SRCDIR)/main.c \ |
| 55 | 66 | $(SRCDIR)/manifest.c \ |
| 56 | 67 | $(SRCDIR)/md5.c \ |
| @@ -131,10 +142,21 @@ | ||
| 131 | 142 | $(OBJDIR)/http_socket_.c \ |
| 132 | 143 | $(OBJDIR)/http_ssl_.c \ |
| 133 | 144 | $(OBJDIR)/http_transport_.c \ |
| 134 | 145 | $(OBJDIR)/import_.c \ |
| 135 | 146 | $(OBJDIR)/info_.c \ |
| 147 | + $(OBJDIR)/json_.c \ | |
| 148 | + $(OBJDIR)/json_artifact_.c \ | |
| 149 | + $(OBJDIR)/json_branch_.c \ | |
| 150 | + $(OBJDIR)/json_diff_.c \ | |
| 151 | + $(OBJDIR)/json_login_.c \ | |
| 152 | + $(OBJDIR)/json_query_.c \ | |
| 153 | + $(OBJDIR)/json_report_.c \ | |
| 154 | + $(OBJDIR)/json_tag_.c \ | |
| 155 | + $(OBJDIR)/json_timeline_.c \ | |
| 156 | + $(OBJDIR)/json_user_.c \ | |
| 157 | + $(OBJDIR)/json_wiki_.c \ | |
| 136 | 158 | $(OBJDIR)/leaf_.c \ |
| 137 | 159 | $(OBJDIR)/login_.c \ |
| 138 | 160 | $(OBJDIR)/main_.c \ |
| 139 | 161 | $(OBJDIR)/manifest_.c \ |
| 140 | 162 | $(OBJDIR)/md5_.c \ |
| @@ -215,10 +237,21 @@ | ||
| 215 | 237 | $(OBJDIR)/http_socket.o \ |
| 216 | 238 | $(OBJDIR)/http_ssl.o \ |
| 217 | 239 | $(OBJDIR)/http_transport.o \ |
| 218 | 240 | $(OBJDIR)/import.o \ |
| 219 | 241 | $(OBJDIR)/info.o \ |
| 242 | + $(OBJDIR)/json.o \ | |
| 243 | + $(OBJDIR)/json_artifact.o \ | |
| 244 | + $(OBJDIR)/json_branch.o \ | |
| 245 | + $(OBJDIR)/json_diff.o \ | |
| 246 | + $(OBJDIR)/json_login.o \ | |
| 247 | + $(OBJDIR)/json_query.o \ | |
| 248 | + $(OBJDIR)/json_report.o \ | |
| 249 | + $(OBJDIR)/json_tag.o \ | |
| 250 | + $(OBJDIR)/json_timeline.o \ | |
| 251 | + $(OBJDIR)/json_user.o \ | |
| 252 | + $(OBJDIR)/json_wiki.o \ | |
| 220 | 253 | $(OBJDIR)/leaf.o \ |
| 221 | 254 | $(OBJDIR)/login.o \ |
| 222 | 255 | $(OBJDIR)/main.o \ |
| 223 | 256 | $(OBJDIR)/manifest.o \ |
| 224 | 257 | $(OBJDIR)/md5.o \ |
| @@ -305,11 +338,11 @@ | ||
| 305 | 338 | |
| 306 | 339 | TCL_OBJ.1 = |
| 307 | 340 | TCL_OBJ.0 = $(OBJDIR)/th_tcl.o |
| 308 | 341 | TCL_OBJ. = $(TCL_OBJ.0) |
| 309 | 342 | |
| 310 | -EXTRAOBJ = $(SQLITE3_OBJ.$(USE_SYSTEM_SQLITE)) $(OBJDIR)/shell.o $(OBJDIR)/th.o $(OBJDIR)/th_lang.o $(TCL_OBJ.$(FOSSIL_ENABLE_TCL)) | |
| 343 | +EXTRAOBJ = $(SQLITE3_OBJ.$(USE_SYSTEM_SQLITE)) $(OBJDIR)/shell.o $(OBJDIR)/th.o $(OBJDIR)/th_lang.o $(TCL_OBJ.$(FOSSIL_ENABLE_TCL)) $(OBJDIR)/cson_amalgamation.o | |
| 311 | 344 | |
| 312 | 345 | $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) |
| 313 | 346 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) |
| 314 | 347 | |
| 315 | 348 | # This rule prevents make from using its default rules to try build |
| @@ -323,13 +356,14 @@ | ||
| 323 | 356 | |
| 324 | 357 | |
| 325 | 358 | $(OBJDIR)/page_index.h: $(TRANS_SRC) $(OBJDIR)/mkindex |
| 326 | 359 | $(OBJDIR)/mkindex $(TRANS_SRC) >$@ |
| 327 | 360 | $(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/makeheaders $(OBJDIR)/VERSION.h |
| 328 | - $(OBJDIR)/makeheaders $(OBJDIR)/add_.c:$(OBJDIR)/add.h $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h $(OBJDIR)/clearsign_.c:$(OBJDIR)/clearsign.h $(OBJDIR)/clone_.c:$(OBJDIR)/clone.h $(OBJDIR)/comformat_.c:$(OBJDIR)/comformat.h $(OBJDIR)/configure_.c:$(OBJDIR)/configure.h $(OBJDIR)/content_.c:$(OBJDIR)/content.h $(OBJDIR)/db_.c:$(OBJDIR)/db.h $(OBJDIR)/delta_.c:$(OBJDIR)/delta.h $(OBJDIR)/deltacmd_.c:$(OBJDIR)/deltacmd.h $(OBJDIR)/descendants_.c:$(OBJDIR)/descendants.h $(OBJDIR)/diff_.c:$(OBJDIR)/diff.h $(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h $(OBJDIR)/doc_.c:$(OBJDIR)/doc.h $(OBJDIR)/encode_.c:$(OBJDIR)/encode.h $(OBJDIR)/event_.c:$(OBJDIR)/event.h $(OBJDIR)/export_.c:$(OBJDIR)/export.h $(OBJDIR)/file_.c:$(OBJDIR)/file.h $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h $(OBJDIR)/glob_.c:$(OBJDIR)/glob.h $(OBJDIR)/graph_.c:$(OBJDIR)/graph.h $(OBJDIR)/gzip_.c:$(OBJDIR)/gzip.h $(OBJDIR)/http_.c:$(OBJDIR)/http.h $(OBJDIR)/http_socket_.c:$(OBJDIR)/http_socket.h $(OBJDIR)/http_ssl_.c:$(OBJDIR)/http_ssl.h $(OBJDIR)/http_transport_.c:$(OBJDIR)/http_transport.h $(OBJDIR)/import_.c:$(OBJDIR)/import.h $(OBJDIR)/info_.c:$(OBJDIR)/info.h $(OBJDIR)/leaf_.c:$(OBJDIR)/leaf.h $(OBJDIR)/login_.c:$(OBJDIR)/login.h $(OBJDIR)/main_.c:$(OBJDIR)/main.h $(OBJDIR)/manifest_.c:$(OBJDIR)/manifest.h $(OBJDIR)/md5_.c:$(OBJDIR)/md5.h $(OBJDIR)/merge_.c:$(OBJDIR)/merge.h $(OBJDIR)/merge3_.c:$(OBJDIR)/merge3.h $(OBJDIR)/name_.c:$(OBJDIR)/name.h $(OBJDIR)/path_.c:$(OBJDIR)/path.h $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h $(OBJDIR)/report_.c:$(OBJDIR)/report.h $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h $(OBJDIR)/search_.c:$(OBJDIR)/search.h $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h $(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h $(OBJDIR)/shun_.c:$(OBJDIR)/shun.h $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h $(OBJDIR)/style_.c:$(OBJDIR)/style.h $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h $(OBJDIR)/update_.c:$(OBJDIR)/update.h $(OBJDIR)/url_.c:$(OBJDIR)/url.h $(OBJDIR)/user_.c:$(OBJDIR)/user.h $(OBJDIR)/verify_.c:$(OBJDIR)/verify.h $(OBJDIR)/vfile_.c:$(OBJDIR)/vfile.h $(OBJDIR)/wiki_.c:$(OBJDIR)/wiki.h $(OBJDIR)/wikiformat_.c:$(OBJDIR)/wikiformat.h $(OBJDIR)/winhttp_.c:$(OBJDIR)/winhttp.h $(OBJDIR)/xfer_.c:$(OBJDIR)/xfer.h $(OBJDIR)/zip_.c:$(OBJDIR)/zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h $(OBJDIR)/VERSION.h | |
| 361 | + $(OBJDIR)/makeheaders $(OBJDIR)/add_.c:$(OBJDIR)/add.h $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h $(OBJDIR)/clearsign_.c:$(OBJDIR)/clearsign.h $(OBJDIR)/clone_.c:$(OBJDIR)/clone.h $(OBJDIR)/comformat_.c:$(OBJDIR)/comformat.h $(OBJDIR)/configure_.c:$(OBJDIR)/configure.h $(OBJDIR)/content_.c:$(OBJDIR)/content.h $(OBJDIR)/db_.c:$(OBJDIR)/db.h $(OBJDIR)/delta_.c:$(OBJDIR)/delta.h $(OBJDIR)/deltacmd_.c:$(OBJDIR)/deltacmd.h $(OBJDIR)/descendants_.c:$(OBJDIR)/descendants.h $(OBJDIR)/diff_.c:$(OBJDIR)/diff.h $(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h $(OBJDIR)/doc_.c:$(OBJDIR)/doc.h $(OBJDIR)/encode_.c:$(OBJDIR)/encode.h $(OBJDIR)/event_.c:$(OBJDIR)/event.h $(OBJDIR)/export_.c:$(OBJDIR)/export.h $(OBJDIR)/file_.c:$(OBJDIR)/file.h $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h $(OBJDIR)/glob_.c:$(OBJDIR)/glob.h $(OBJDIR)/graph_.c:$(OBJDIR)/graph.h $(OBJDIR)/gzip_.c:$(OBJDIR)/gzip.h $(OBJDIR)/http_.c:$(OBJDIR)/http.h $(OBJDIR)/http_socket_.c:$(OBJDIR)/http_socket.h $(OBJDIR)/http_ssl_.c:$(OBJDIR)/http_ssl.h $(OBJDIR)/http_transport_.c:$(OBJDIR)/http_transport.h $(OBJDIR)/import_.c:$(OBJDIR)/import.h $(OBJDIR)/info_.c:$(OBJDIR)/info.h $(OBJDIR)/json_.c:$(OBJDIR)/json.h $(OBJDIR)/json_artifact_.c:$(OBJDIR)/json_artifact.h $(OBJDIR)/json_branch_.c:$(OBJDIR)/json_branch.h $(OBJDIR)/json_diff_.c:$(OBJDIR)/json_diff.h $(OBJDIR)/json_login_.c:$(OBJDIR)/json_login.h $(OBJDIR)/json_query_.c:$(OBJDIR)/json_query.h $(OBJDIR)/json_report_.c:$(OBJDIR)/json_report.h $(OBJDIR)/json_tag_.c:$(OBJDIR)/json_tag.h $(OBJDIR)/json_timeline_.c:$(OBJDIR)/json_timeline.h $(OBJDIR)/json_user_.c:$(OBJDIR)/json_user.h $(OBJDIR)/json_wiki_.c:$(OBJDIR)/json_wiki.h $(OBJDIR)/leaf_.c:$(OBJDIR)/leaf.h $(OBJDIR)/login_.c:$(OBJDIR)/login.h $(OBJDIR)/main_.c:$(OBJDIR)/main.h $(OBJDIR)/manifest_.c:$(OBJDIR)/manifest.h $(OBJDIR)/md5_.c:$(OBJDIR)/md5.h $(OBJDIR)/merge_.c:$(OBJDIR)/merge.h $(OBJDIR)/merge3_.c:$(OBJDIR)/merge3.h $(OBJDIR)/name_.c:$(OBJDIR)/name.h $(OBJDIR)/path_.c:$(OBJDIR)/path.h $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h $(OBJDIR)/report_.c:$(OBJDIR)/report.h $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h $(OBJDIR)/search_.c:$(OBJDIR)/search.h $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h $(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h $(OBJDIR)/shun_.c:$(OBJDIR)/shun.h $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h $(OBJDIR)/style_.c:$(OBJDIR)/style.h $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h $(OBJDIR)/update_.c:$(OBJDIR)/update.h $(OBJDIR)/url_.c:$(OBJDIR)/url.h $(OBJDIR)/user_.c:$(OBJDIR)/user.h $(OBJDIR)/verify_.c:$(OBJDIR)/verify.h $(OBJDIR)/vfile_.c:$(OBJDIR)/vfile.h $(OBJDIR)/wiki_.c:$(OBJDIR)/wiki.h $(OBJDIR)/wikiformat_.c:$(OBJDIR)/wikiformat.h $(OBJDIR)/winhttp_.c:$(OBJDIR)/winhttp.h $(OBJDIR)/xfer_.c:$(OBJDIR)/xfer.h $(OBJDIR)/zip_.c:$(OBJDIR)/zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h $(OBJDIR)/VERSION.h | |
| 329 | 362 | touch $(OBJDIR)/headers |
| 330 | 363 | $(OBJDIR)/headers: Makefile |
| 364 | +$(OBJDIR)/json.o $(OBJDIR)/json_artifact.o $(OBJDIR)/json_branch.o $(OBJDIR)/json_diff.o $(OBJDIR)/json_login.o $(OBJDIR)/json_query.o $(OBJDIR)/json_report.o $(OBJDIR)/json_tag.o $(OBJDIR)/json_timeline.o $(OBJDIR)/json_user.o $(OBJDIR)/json_wiki.o : $(SRCDIR)/json_detail.h | |
| 331 | 365 | Makefile: |
| 332 | 366 | $(OBJDIR)/add_.c: $(SRCDIR)/add.c $(OBJDIR)/translate |
| 333 | 367 | $(OBJDIR)/translate $(SRCDIR)/add.c >$(OBJDIR)/add_.c |
| 334 | 368 | |
| 335 | 369 | $(OBJDIR)/add.o: $(OBJDIR)/add_.c $(OBJDIR)/add.h $(SRCDIR)/config.h |
| @@ -593,10 +627,87 @@ | ||
| 593 | 627 | |
| 594 | 628 | $(OBJDIR)/info.o: $(OBJDIR)/info_.c $(OBJDIR)/info.h $(SRCDIR)/config.h |
| 595 | 629 | $(XTCC) -o $(OBJDIR)/info.o -c $(OBJDIR)/info_.c |
| 596 | 630 | |
| 597 | 631 | $(OBJDIR)/info.h: $(OBJDIR)/headers |
| 632 | +$(OBJDIR)/json_.c: $(SRCDIR)/json.c $(OBJDIR)/translate | |
| 633 | + $(OBJDIR)/translate $(SRCDIR)/json.c >$(OBJDIR)/json_.c | |
| 634 | + | |
| 635 | +$(OBJDIR)/json.o: $(OBJDIR)/json_.c $(OBJDIR)/json.h $(SRCDIR)/config.h | |
| 636 | + $(XTCC) -o $(OBJDIR)/json.o -c $(OBJDIR)/json_.c | |
| 637 | + | |
| 638 | +$(OBJDIR)/json.h: $(OBJDIR)/headers | |
| 639 | +$(OBJDIR)/json_artifact_.c: $(SRCDIR)/json_artifact.c $(OBJDIR)/translate | |
| 640 | + $(OBJDIR)/translate $(SRCDIR)/json_artifact.c >$(OBJDIR)/json_artifact_.c | |
| 641 | + | |
| 642 | +$(OBJDIR)/json_artifact.o: $(OBJDIR)/json_artifact_.c $(OBJDIR)/json_artifact.h $(SRCDIR)/config.h | |
| 643 | + $(XTCC) -o $(OBJDIR)/json_artifact.o -c $(OBJDIR)/json_artifact_.c | |
| 644 | + | |
| 645 | +$(OBJDIR)/json_artifact.h: $(OBJDIR)/headers | |
| 646 | +$(OBJDIR)/json_branch_.c: $(SRCDIR)/json_branch.c $(OBJDIR)/translate | |
| 647 | + $(OBJDIR)/translate $(SRCDIR)/json_branch.c >$(OBJDIR)/json_branch_.c | |
| 648 | + | |
| 649 | +$(OBJDIR)/json_branch.o: $(OBJDIR)/json_branch_.c $(OBJDIR)/json_branch.h $(SRCDIR)/config.h | |
| 650 | + $(XTCC) -o $(OBJDIR)/json_branch.o -c $(OBJDIR)/json_branch_.c | |
| 651 | + | |
| 652 | +$(OBJDIR)/json_branch.h: $(OBJDIR)/headers | |
| 653 | +$(OBJDIR)/json_diff_.c: $(SRCDIR)/json_diff.c $(OBJDIR)/translate | |
| 654 | + $(OBJDIR)/translate $(SRCDIR)/json_diff.c >$(OBJDIR)/json_diff_.c | |
| 655 | + | |
| 656 | +$(OBJDIR)/json_diff.o: $(OBJDIR)/json_diff_.c $(OBJDIR)/json_diff.h $(SRCDIR)/config.h | |
| 657 | + $(XTCC) -o $(OBJDIR)/json_diff.o -c $(OBJDIR)/json_diff_.c | |
| 658 | + | |
| 659 | +$(OBJDIR)/json_diff.h: $(OBJDIR)/headers | |
| 660 | +$(OBJDIR)/json_login_.c: $(SRCDIR)/json_login.c $(OBJDIR)/translate | |
| 661 | + $(OBJDIR)/translate $(SRCDIR)/json_login.c >$(OBJDIR)/json_login_.c | |
| 662 | + | |
| 663 | +$(OBJDIR)/json_login.o: $(OBJDIR)/json_login_.c $(OBJDIR)/json_login.h $(SRCDIR)/config.h | |
| 664 | + $(XTCC) -o $(OBJDIR)/json_login.o -c $(OBJDIR)/json_login_.c | |
| 665 | + | |
| 666 | +$(OBJDIR)/json_login.h: $(OBJDIR)/headers | |
| 667 | +$(OBJDIR)/json_query_.c: $(SRCDIR)/json_query.c $(OBJDIR)/translate | |
| 668 | + $(OBJDIR)/translate $(SRCDIR)/json_query.c >$(OBJDIR)/json_query_.c | |
| 669 | + | |
| 670 | +$(OBJDIR)/json_query.o: $(OBJDIR)/json_query_.c $(OBJDIR)/json_query.h $(SRCDIR)/config.h | |
| 671 | + $(XTCC) -o $(OBJDIR)/json_query.o -c $(OBJDIR)/json_query_.c | |
| 672 | + | |
| 673 | +$(OBJDIR)/json_query.h: $(OBJDIR)/headers | |
| 674 | +$(OBJDIR)/json_report_.c: $(SRCDIR)/json_report.c $(OBJDIR)/translate | |
| 675 | + $(OBJDIR)/translate $(SRCDIR)/json_report.c >$(OBJDIR)/json_report_.c | |
| 676 | + | |
| 677 | +$(OBJDIR)/json_report.o: $(OBJDIR)/json_report_.c $(OBJDIR)/json_report.h $(SRCDIR)/config.h | |
| 678 | + $(XTCC) -o $(OBJDIR)/json_report.o -c $(OBJDIR)/json_report_.c | |
| 679 | + | |
| 680 | +$(OBJDIR)/json_report.h: $(OBJDIR)/headers | |
| 681 | +$(OBJDIR)/json_tag_.c: $(SRCDIR)/json_tag.c $(OBJDIR)/translate | |
| 682 | + $(OBJDIR)/translate $(SRCDIR)/json_tag.c >$(OBJDIR)/json_tag_.c | |
| 683 | + | |
| 684 | +$(OBJDIR)/json_tag.o: $(OBJDIR)/json_tag_.c $(OBJDIR)/json_tag.h $(SRCDIR)/config.h | |
| 685 | + $(XTCC) -o $(OBJDIR)/json_tag.o -c $(OBJDIR)/json_tag_.c | |
| 686 | + | |
| 687 | +$(OBJDIR)/json_tag.h: $(OBJDIR)/headers | |
| 688 | +$(OBJDIR)/json_timeline_.c: $(SRCDIR)/json_timeline.c $(OBJDIR)/translate | |
| 689 | + $(OBJDIR)/translate $(SRCDIR)/json_timeline.c >$(OBJDIR)/json_timeline_.c | |
| 690 | + | |
| 691 | +$(OBJDIR)/json_timeline.o: $(OBJDIR)/json_timeline_.c $(OBJDIR)/json_timeline.h $(SRCDIR)/config.h | |
| 692 | + $(XTCC) -o $(OBJDIR)/json_timeline.o -c $(OBJDIR)/json_timeline_.c | |
| 693 | + | |
| 694 | +$(OBJDIR)/json_timeline.h: $(OBJDIR)/headers | |
| 695 | +$(OBJDIR)/json_user_.c: $(SRCDIR)/json_user.c $(OBJDIR)/translate | |
| 696 | + $(OBJDIR)/translate $(SRCDIR)/json_user.c >$(OBJDIR)/json_user_.c | |
| 697 | + | |
| 698 | +$(OBJDIR)/json_user.o: $(OBJDIR)/json_user_.c $(OBJDIR)/json_user.h $(SRCDIR)/config.h | |
| 699 | + $(XTCC) -o $(OBJDIR)/json_user.o -c $(OBJDIR)/json_user_.c | |
| 700 | + | |
| 701 | +$(OBJDIR)/json_user.h: $(OBJDIR)/headers | |
| 702 | +$(OBJDIR)/json_wiki_.c: $(SRCDIR)/json_wiki.c $(OBJDIR)/translate | |
| 703 | + $(OBJDIR)/translate $(SRCDIR)/json_wiki.c >$(OBJDIR)/json_wiki_.c | |
| 704 | + | |
| 705 | +$(OBJDIR)/json_wiki.o: $(OBJDIR)/json_wiki_.c $(OBJDIR)/json_wiki.h $(SRCDIR)/config.h | |
| 706 | + $(XTCC) -o $(OBJDIR)/json_wiki.o -c $(OBJDIR)/json_wiki_.c | |
| 707 | + | |
| 708 | +$(OBJDIR)/json_wiki.h: $(OBJDIR)/headers | |
| 598 | 709 | $(OBJDIR)/leaf_.c: $(SRCDIR)/leaf.c $(OBJDIR)/translate |
| 599 | 710 | $(OBJDIR)/translate $(SRCDIR)/leaf.c >$(OBJDIR)/leaf_.c |
| 600 | 711 | |
| 601 | 712 | $(OBJDIR)/leaf.o: $(OBJDIR)/leaf_.c $(OBJDIR)/leaf.h $(SRCDIR)/config.h |
| 602 | 713 | $(XTCC) -o $(OBJDIR)/leaf.o -c $(OBJDIR)/leaf_.c |
| @@ -916,5 +1027,9 @@ | ||
| 916 | 1027 | $(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th_lang.c -o $(OBJDIR)/th_lang.o |
| 917 | 1028 | |
| 918 | 1029 | $(OBJDIR)/th_tcl.o: $(SRCDIR)/th_tcl.c |
| 919 | 1030 | $(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th_tcl.c -o $(OBJDIR)/th_tcl.o |
| 920 | 1031 | |
| 1032 | + | |
| 1033 | +$(OBJDIR)/cson_amalgamation.o: $(SRCDIR)/cson_amalgamation.c | |
| 1034 | + $(XTCC) -I$(SRCDIR) -c $(SRCDIR)/cson_amalgamation.c -o $(OBJDIR)/cson_amalgamation.o -DCSON_FOSSIL_MODE | |
| 1035 | + | |
| 921 | 1036 |
| --- src/main.mk | |
| +++ src/main.mk | |
| @@ -47,10 +47,21 @@ | |
| 47 | $(SRCDIR)/http_socket.c \ |
| 48 | $(SRCDIR)/http_ssl.c \ |
| 49 | $(SRCDIR)/http_transport.c \ |
| 50 | $(SRCDIR)/import.c \ |
| 51 | $(SRCDIR)/info.c \ |
| 52 | $(SRCDIR)/leaf.c \ |
| 53 | $(SRCDIR)/login.c \ |
| 54 | $(SRCDIR)/main.c \ |
| 55 | $(SRCDIR)/manifest.c \ |
| 56 | $(SRCDIR)/md5.c \ |
| @@ -131,10 +142,21 @@ | |
| 131 | $(OBJDIR)/http_socket_.c \ |
| 132 | $(OBJDIR)/http_ssl_.c \ |
| 133 | $(OBJDIR)/http_transport_.c \ |
| 134 | $(OBJDIR)/import_.c \ |
| 135 | $(OBJDIR)/info_.c \ |
| 136 | $(OBJDIR)/leaf_.c \ |
| 137 | $(OBJDIR)/login_.c \ |
| 138 | $(OBJDIR)/main_.c \ |
| 139 | $(OBJDIR)/manifest_.c \ |
| 140 | $(OBJDIR)/md5_.c \ |
| @@ -215,10 +237,21 @@ | |
| 215 | $(OBJDIR)/http_socket.o \ |
| 216 | $(OBJDIR)/http_ssl.o \ |
| 217 | $(OBJDIR)/http_transport.o \ |
| 218 | $(OBJDIR)/import.o \ |
| 219 | $(OBJDIR)/info.o \ |
| 220 | $(OBJDIR)/leaf.o \ |
| 221 | $(OBJDIR)/login.o \ |
| 222 | $(OBJDIR)/main.o \ |
| 223 | $(OBJDIR)/manifest.o \ |
| 224 | $(OBJDIR)/md5.o \ |
| @@ -305,11 +338,11 @@ | |
| 305 | |
| 306 | TCL_OBJ.1 = |
| 307 | TCL_OBJ.0 = $(OBJDIR)/th_tcl.o |
| 308 | TCL_OBJ. = $(TCL_OBJ.0) |
| 309 | |
| 310 | EXTRAOBJ = $(SQLITE3_OBJ.$(USE_SYSTEM_SQLITE)) $(OBJDIR)/shell.o $(OBJDIR)/th.o $(OBJDIR)/th_lang.o $(TCL_OBJ.$(FOSSIL_ENABLE_TCL)) |
| 311 | |
| 312 | $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) |
| 313 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) |
| 314 | |
| 315 | # This rule prevents make from using its default rules to try build |
| @@ -323,13 +356,14 @@ | |
| 323 | |
| 324 | |
| 325 | $(OBJDIR)/page_index.h: $(TRANS_SRC) $(OBJDIR)/mkindex |
| 326 | $(OBJDIR)/mkindex $(TRANS_SRC) >$@ |
| 327 | $(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/makeheaders $(OBJDIR)/VERSION.h |
| 328 | $(OBJDIR)/makeheaders $(OBJDIR)/add_.c:$(OBJDIR)/add.h $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h $(OBJDIR)/clearsign_.c:$(OBJDIR)/clearsign.h $(OBJDIR)/clone_.c:$(OBJDIR)/clone.h $(OBJDIR)/comformat_.c:$(OBJDIR)/comformat.h $(OBJDIR)/configure_.c:$(OBJDIR)/configure.h $(OBJDIR)/content_.c:$(OBJDIR)/content.h $(OBJDIR)/db_.c:$(OBJDIR)/db.h $(OBJDIR)/delta_.c:$(OBJDIR)/delta.h $(OBJDIR)/deltacmd_.c:$(OBJDIR)/deltacmd.h $(OBJDIR)/descendants_.c:$(OBJDIR)/descendants.h $(OBJDIR)/diff_.c:$(OBJDIR)/diff.h $(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h $(OBJDIR)/doc_.c:$(OBJDIR)/doc.h $(OBJDIR)/encode_.c:$(OBJDIR)/encode.h $(OBJDIR)/event_.c:$(OBJDIR)/event.h $(OBJDIR)/export_.c:$(OBJDIR)/export.h $(OBJDIR)/file_.c:$(OBJDIR)/file.h $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h $(OBJDIR)/glob_.c:$(OBJDIR)/glob.h $(OBJDIR)/graph_.c:$(OBJDIR)/graph.h $(OBJDIR)/gzip_.c:$(OBJDIR)/gzip.h $(OBJDIR)/http_.c:$(OBJDIR)/http.h $(OBJDIR)/http_socket_.c:$(OBJDIR)/http_socket.h $(OBJDIR)/http_ssl_.c:$(OBJDIR)/http_ssl.h $(OBJDIR)/http_transport_.c:$(OBJDIR)/http_transport.h $(OBJDIR)/import_.c:$(OBJDIR)/import.h $(OBJDIR)/info_.c:$(OBJDIR)/info.h $(OBJDIR)/leaf_.c:$(OBJDIR)/leaf.h $(OBJDIR)/login_.c:$(OBJDIR)/login.h $(OBJDIR)/main_.c:$(OBJDIR)/main.h $(OBJDIR)/manifest_.c:$(OBJDIR)/manifest.h $(OBJDIR)/md5_.c:$(OBJDIR)/md5.h $(OBJDIR)/merge_.c:$(OBJDIR)/merge.h $(OBJDIR)/merge3_.c:$(OBJDIR)/merge3.h $(OBJDIR)/name_.c:$(OBJDIR)/name.h $(OBJDIR)/path_.c:$(OBJDIR)/path.h $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h $(OBJDIR)/report_.c:$(OBJDIR)/report.h $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h $(OBJDIR)/search_.c:$(OBJDIR)/search.h $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h $(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h $(OBJDIR)/shun_.c:$(OBJDIR)/shun.h $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h $(OBJDIR)/style_.c:$(OBJDIR)/style.h $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h $(OBJDIR)/update_.c:$(OBJDIR)/update.h $(OBJDIR)/url_.c:$(OBJDIR)/url.h $(OBJDIR)/user_.c:$(OBJDIR)/user.h $(OBJDIR)/verify_.c:$(OBJDIR)/verify.h $(OBJDIR)/vfile_.c:$(OBJDIR)/vfile.h $(OBJDIR)/wiki_.c:$(OBJDIR)/wiki.h $(OBJDIR)/wikiformat_.c:$(OBJDIR)/wikiformat.h $(OBJDIR)/winhttp_.c:$(OBJDIR)/winhttp.h $(OBJDIR)/xfer_.c:$(OBJDIR)/xfer.h $(OBJDIR)/zip_.c:$(OBJDIR)/zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h $(OBJDIR)/VERSION.h |
| 329 | touch $(OBJDIR)/headers |
| 330 | $(OBJDIR)/headers: Makefile |
| 331 | Makefile: |
| 332 | $(OBJDIR)/add_.c: $(SRCDIR)/add.c $(OBJDIR)/translate |
| 333 | $(OBJDIR)/translate $(SRCDIR)/add.c >$(OBJDIR)/add_.c |
| 334 | |
| 335 | $(OBJDIR)/add.o: $(OBJDIR)/add_.c $(OBJDIR)/add.h $(SRCDIR)/config.h |
| @@ -593,10 +627,87 @@ | |
| 593 | |
| 594 | $(OBJDIR)/info.o: $(OBJDIR)/info_.c $(OBJDIR)/info.h $(SRCDIR)/config.h |
| 595 | $(XTCC) -o $(OBJDIR)/info.o -c $(OBJDIR)/info_.c |
| 596 | |
| 597 | $(OBJDIR)/info.h: $(OBJDIR)/headers |
| 598 | $(OBJDIR)/leaf_.c: $(SRCDIR)/leaf.c $(OBJDIR)/translate |
| 599 | $(OBJDIR)/translate $(SRCDIR)/leaf.c >$(OBJDIR)/leaf_.c |
| 600 | |
| 601 | $(OBJDIR)/leaf.o: $(OBJDIR)/leaf_.c $(OBJDIR)/leaf.h $(SRCDIR)/config.h |
| 602 | $(XTCC) -o $(OBJDIR)/leaf.o -c $(OBJDIR)/leaf_.c |
| @@ -916,5 +1027,9 @@ | |
| 916 | $(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th_lang.c -o $(OBJDIR)/th_lang.o |
| 917 | |
| 918 | $(OBJDIR)/th_tcl.o: $(SRCDIR)/th_tcl.c |
| 919 | $(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th_tcl.c -o $(OBJDIR)/th_tcl.o |
| 920 | |
| 921 |
| --- src/main.mk | |
| +++ src/main.mk | |
| @@ -47,10 +47,21 @@ | |
| 47 | $(SRCDIR)/http_socket.c \ |
| 48 | $(SRCDIR)/http_ssl.c \ |
| 49 | $(SRCDIR)/http_transport.c \ |
| 50 | $(SRCDIR)/import.c \ |
| 51 | $(SRCDIR)/info.c \ |
| 52 | $(SRCDIR)/json.c \ |
| 53 | $(SRCDIR)/json_artifact.c \ |
| 54 | $(SRCDIR)/json_branch.c \ |
| 55 | $(SRCDIR)/json_diff.c \ |
| 56 | $(SRCDIR)/json_login.c \ |
| 57 | $(SRCDIR)/json_query.c \ |
| 58 | $(SRCDIR)/json_report.c \ |
| 59 | $(SRCDIR)/json_tag.c \ |
| 60 | $(SRCDIR)/json_timeline.c \ |
| 61 | $(SRCDIR)/json_user.c \ |
| 62 | $(SRCDIR)/json_wiki.c \ |
| 63 | $(SRCDIR)/leaf.c \ |
| 64 | $(SRCDIR)/login.c \ |
| 65 | $(SRCDIR)/main.c \ |
| 66 | $(SRCDIR)/manifest.c \ |
| 67 | $(SRCDIR)/md5.c \ |
| @@ -131,10 +142,21 @@ | |
| 142 | $(OBJDIR)/http_socket_.c \ |
| 143 | $(OBJDIR)/http_ssl_.c \ |
| 144 | $(OBJDIR)/http_transport_.c \ |
| 145 | $(OBJDIR)/import_.c \ |
| 146 | $(OBJDIR)/info_.c \ |
| 147 | $(OBJDIR)/json_.c \ |
| 148 | $(OBJDIR)/json_artifact_.c \ |
| 149 | $(OBJDIR)/json_branch_.c \ |
| 150 | $(OBJDIR)/json_diff_.c \ |
| 151 | $(OBJDIR)/json_login_.c \ |
| 152 | $(OBJDIR)/json_query_.c \ |
| 153 | $(OBJDIR)/json_report_.c \ |
| 154 | $(OBJDIR)/json_tag_.c \ |
| 155 | $(OBJDIR)/json_timeline_.c \ |
| 156 | $(OBJDIR)/json_user_.c \ |
| 157 | $(OBJDIR)/json_wiki_.c \ |
| 158 | $(OBJDIR)/leaf_.c \ |
| 159 | $(OBJDIR)/login_.c \ |
| 160 | $(OBJDIR)/main_.c \ |
| 161 | $(OBJDIR)/manifest_.c \ |
| 162 | $(OBJDIR)/md5_.c \ |
| @@ -215,10 +237,21 @@ | |
| 237 | $(OBJDIR)/http_socket.o \ |
| 238 | $(OBJDIR)/http_ssl.o \ |
| 239 | $(OBJDIR)/http_transport.o \ |
| 240 | $(OBJDIR)/import.o \ |
| 241 | $(OBJDIR)/info.o \ |
| 242 | $(OBJDIR)/json.o \ |
| 243 | $(OBJDIR)/json_artifact.o \ |
| 244 | $(OBJDIR)/json_branch.o \ |
| 245 | $(OBJDIR)/json_diff.o \ |
| 246 | $(OBJDIR)/json_login.o \ |
| 247 | $(OBJDIR)/json_query.o \ |
| 248 | $(OBJDIR)/json_report.o \ |
| 249 | $(OBJDIR)/json_tag.o \ |
| 250 | $(OBJDIR)/json_timeline.o \ |
| 251 | $(OBJDIR)/json_user.o \ |
| 252 | $(OBJDIR)/json_wiki.o \ |
| 253 | $(OBJDIR)/leaf.o \ |
| 254 | $(OBJDIR)/login.o \ |
| 255 | $(OBJDIR)/main.o \ |
| 256 | $(OBJDIR)/manifest.o \ |
| 257 | $(OBJDIR)/md5.o \ |
| @@ -305,11 +338,11 @@ | |
| 338 | |
| 339 | TCL_OBJ.1 = |
| 340 | TCL_OBJ.0 = $(OBJDIR)/th_tcl.o |
| 341 | TCL_OBJ. = $(TCL_OBJ.0) |
| 342 | |
| 343 | EXTRAOBJ = $(SQLITE3_OBJ.$(USE_SYSTEM_SQLITE)) $(OBJDIR)/shell.o $(OBJDIR)/th.o $(OBJDIR)/th_lang.o $(TCL_OBJ.$(FOSSIL_ENABLE_TCL)) $(OBJDIR)/cson_amalgamation.o |
| 344 | |
| 345 | $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) |
| 346 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) |
| 347 | |
| 348 | # This rule prevents make from using its default rules to try build |
| @@ -323,13 +356,14 @@ | |
| 356 | |
| 357 | |
| 358 | $(OBJDIR)/page_index.h: $(TRANS_SRC) $(OBJDIR)/mkindex |
| 359 | $(OBJDIR)/mkindex $(TRANS_SRC) >$@ |
| 360 | $(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/makeheaders $(OBJDIR)/VERSION.h |
| 361 | $(OBJDIR)/makeheaders $(OBJDIR)/add_.c:$(OBJDIR)/add.h $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h $(OBJDIR)/clearsign_.c:$(OBJDIR)/clearsign.h $(OBJDIR)/clone_.c:$(OBJDIR)/clone.h $(OBJDIR)/comformat_.c:$(OBJDIR)/comformat.h $(OBJDIR)/configure_.c:$(OBJDIR)/configure.h $(OBJDIR)/content_.c:$(OBJDIR)/content.h $(OBJDIR)/db_.c:$(OBJDIR)/db.h $(OBJDIR)/delta_.c:$(OBJDIR)/delta.h $(OBJDIR)/deltacmd_.c:$(OBJDIR)/deltacmd.h $(OBJDIR)/descendants_.c:$(OBJDIR)/descendants.h $(OBJDIR)/diff_.c:$(OBJDIR)/diff.h $(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h $(OBJDIR)/doc_.c:$(OBJDIR)/doc.h $(OBJDIR)/encode_.c:$(OBJDIR)/encode.h $(OBJDIR)/event_.c:$(OBJDIR)/event.h $(OBJDIR)/export_.c:$(OBJDIR)/export.h $(OBJDIR)/file_.c:$(OBJDIR)/file.h $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h $(OBJDIR)/glob_.c:$(OBJDIR)/glob.h $(OBJDIR)/graph_.c:$(OBJDIR)/graph.h $(OBJDIR)/gzip_.c:$(OBJDIR)/gzip.h $(OBJDIR)/http_.c:$(OBJDIR)/http.h $(OBJDIR)/http_socket_.c:$(OBJDIR)/http_socket.h $(OBJDIR)/http_ssl_.c:$(OBJDIR)/http_ssl.h $(OBJDIR)/http_transport_.c:$(OBJDIR)/http_transport.h $(OBJDIR)/import_.c:$(OBJDIR)/import.h $(OBJDIR)/info_.c:$(OBJDIR)/info.h $(OBJDIR)/json_.c:$(OBJDIR)/json.h $(OBJDIR)/json_artifact_.c:$(OBJDIR)/json_artifact.h $(OBJDIR)/json_branch_.c:$(OBJDIR)/json_branch.h $(OBJDIR)/json_diff_.c:$(OBJDIR)/json_diff.h $(OBJDIR)/json_login_.c:$(OBJDIR)/json_login.h $(OBJDIR)/json_query_.c:$(OBJDIR)/json_query.h $(OBJDIR)/json_report_.c:$(OBJDIR)/json_report.h $(OBJDIR)/json_tag_.c:$(OBJDIR)/json_tag.h $(OBJDIR)/json_timeline_.c:$(OBJDIR)/json_timeline.h $(OBJDIR)/json_user_.c:$(OBJDIR)/json_user.h $(OBJDIR)/json_wiki_.c:$(OBJDIR)/json_wiki.h $(OBJDIR)/leaf_.c:$(OBJDIR)/leaf.h $(OBJDIR)/login_.c:$(OBJDIR)/login.h $(OBJDIR)/main_.c:$(OBJDIR)/main.h $(OBJDIR)/manifest_.c:$(OBJDIR)/manifest.h $(OBJDIR)/md5_.c:$(OBJDIR)/md5.h $(OBJDIR)/merge_.c:$(OBJDIR)/merge.h $(OBJDIR)/merge3_.c:$(OBJDIR)/merge3.h $(OBJDIR)/name_.c:$(OBJDIR)/name.h $(OBJDIR)/path_.c:$(OBJDIR)/path.h $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h $(OBJDIR)/report_.c:$(OBJDIR)/report.h $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h $(OBJDIR)/search_.c:$(OBJDIR)/search.h $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h $(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h $(OBJDIR)/shun_.c:$(OBJDIR)/shun.h $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h $(OBJDIR)/style_.c:$(OBJDIR)/style.h $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h $(OBJDIR)/update_.c:$(OBJDIR)/update.h $(OBJDIR)/url_.c:$(OBJDIR)/url.h $(OBJDIR)/user_.c:$(OBJDIR)/user.h $(OBJDIR)/verify_.c:$(OBJDIR)/verify.h $(OBJDIR)/vfile_.c:$(OBJDIR)/vfile.h $(OBJDIR)/wiki_.c:$(OBJDIR)/wiki.h $(OBJDIR)/wikiformat_.c:$(OBJDIR)/wikiformat.h $(OBJDIR)/winhttp_.c:$(OBJDIR)/winhttp.h $(OBJDIR)/xfer_.c:$(OBJDIR)/xfer.h $(OBJDIR)/zip_.c:$(OBJDIR)/zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h $(OBJDIR)/VERSION.h |
| 362 | touch $(OBJDIR)/headers |
| 363 | $(OBJDIR)/headers: Makefile |
| 364 | $(OBJDIR)/json.o $(OBJDIR)/json_artifact.o $(OBJDIR)/json_branch.o $(OBJDIR)/json_diff.o $(OBJDIR)/json_login.o $(OBJDIR)/json_query.o $(OBJDIR)/json_report.o $(OBJDIR)/json_tag.o $(OBJDIR)/json_timeline.o $(OBJDIR)/json_user.o $(OBJDIR)/json_wiki.o : $(SRCDIR)/json_detail.h |
| 365 | Makefile: |
| 366 | $(OBJDIR)/add_.c: $(SRCDIR)/add.c $(OBJDIR)/translate |
| 367 | $(OBJDIR)/translate $(SRCDIR)/add.c >$(OBJDIR)/add_.c |
| 368 | |
| 369 | $(OBJDIR)/add.o: $(OBJDIR)/add_.c $(OBJDIR)/add.h $(SRCDIR)/config.h |
| @@ -593,10 +627,87 @@ | |
| 627 | |
| 628 | $(OBJDIR)/info.o: $(OBJDIR)/info_.c $(OBJDIR)/info.h $(SRCDIR)/config.h |
| 629 | $(XTCC) -o $(OBJDIR)/info.o -c $(OBJDIR)/info_.c |
| 630 | |
| 631 | $(OBJDIR)/info.h: $(OBJDIR)/headers |
| 632 | $(OBJDIR)/json_.c: $(SRCDIR)/json.c $(OBJDIR)/translate |
| 633 | $(OBJDIR)/translate $(SRCDIR)/json.c >$(OBJDIR)/json_.c |
| 634 | |
| 635 | $(OBJDIR)/json.o: $(OBJDIR)/json_.c $(OBJDIR)/json.h $(SRCDIR)/config.h |
| 636 | $(XTCC) -o $(OBJDIR)/json.o -c $(OBJDIR)/json_.c |
| 637 | |
| 638 | $(OBJDIR)/json.h: $(OBJDIR)/headers |
| 639 | $(OBJDIR)/json_artifact_.c: $(SRCDIR)/json_artifact.c $(OBJDIR)/translate |
| 640 | $(OBJDIR)/translate $(SRCDIR)/json_artifact.c >$(OBJDIR)/json_artifact_.c |
| 641 | |
| 642 | $(OBJDIR)/json_artifact.o: $(OBJDIR)/json_artifact_.c $(OBJDIR)/json_artifact.h $(SRCDIR)/config.h |
| 643 | $(XTCC) -o $(OBJDIR)/json_artifact.o -c $(OBJDIR)/json_artifact_.c |
| 644 | |
| 645 | $(OBJDIR)/json_artifact.h: $(OBJDIR)/headers |
| 646 | $(OBJDIR)/json_branch_.c: $(SRCDIR)/json_branch.c $(OBJDIR)/translate |
| 647 | $(OBJDIR)/translate $(SRCDIR)/json_branch.c >$(OBJDIR)/json_branch_.c |
| 648 | |
| 649 | $(OBJDIR)/json_branch.o: $(OBJDIR)/json_branch_.c $(OBJDIR)/json_branch.h $(SRCDIR)/config.h |
| 650 | $(XTCC) -o $(OBJDIR)/json_branch.o -c $(OBJDIR)/json_branch_.c |
| 651 | |
| 652 | $(OBJDIR)/json_branch.h: $(OBJDIR)/headers |
| 653 | $(OBJDIR)/json_diff_.c: $(SRCDIR)/json_diff.c $(OBJDIR)/translate |
| 654 | $(OBJDIR)/translate $(SRCDIR)/json_diff.c >$(OBJDIR)/json_diff_.c |
| 655 | |
| 656 | $(OBJDIR)/json_diff.o: $(OBJDIR)/json_diff_.c $(OBJDIR)/json_diff.h $(SRCDIR)/config.h |
| 657 | $(XTCC) -o $(OBJDIR)/json_diff.o -c $(OBJDIR)/json_diff_.c |
| 658 | |
| 659 | $(OBJDIR)/json_diff.h: $(OBJDIR)/headers |
| 660 | $(OBJDIR)/json_login_.c: $(SRCDIR)/json_login.c $(OBJDIR)/translate |
| 661 | $(OBJDIR)/translate $(SRCDIR)/json_login.c >$(OBJDIR)/json_login_.c |
| 662 | |
| 663 | $(OBJDIR)/json_login.o: $(OBJDIR)/json_login_.c $(OBJDIR)/json_login.h $(SRCDIR)/config.h |
| 664 | $(XTCC) -o $(OBJDIR)/json_login.o -c $(OBJDIR)/json_login_.c |
| 665 | |
| 666 | $(OBJDIR)/json_login.h: $(OBJDIR)/headers |
| 667 | $(OBJDIR)/json_query_.c: $(SRCDIR)/json_query.c $(OBJDIR)/translate |
| 668 | $(OBJDIR)/translate $(SRCDIR)/json_query.c >$(OBJDIR)/json_query_.c |
| 669 | |
| 670 | $(OBJDIR)/json_query.o: $(OBJDIR)/json_query_.c $(OBJDIR)/json_query.h $(SRCDIR)/config.h |
| 671 | $(XTCC) -o $(OBJDIR)/json_query.o -c $(OBJDIR)/json_query_.c |
| 672 | |
| 673 | $(OBJDIR)/json_query.h: $(OBJDIR)/headers |
| 674 | $(OBJDIR)/json_report_.c: $(SRCDIR)/json_report.c $(OBJDIR)/translate |
| 675 | $(OBJDIR)/translate $(SRCDIR)/json_report.c >$(OBJDIR)/json_report_.c |
| 676 | |
| 677 | $(OBJDIR)/json_report.o: $(OBJDIR)/json_report_.c $(OBJDIR)/json_report.h $(SRCDIR)/config.h |
| 678 | $(XTCC) -o $(OBJDIR)/json_report.o -c $(OBJDIR)/json_report_.c |
| 679 | |
| 680 | $(OBJDIR)/json_report.h: $(OBJDIR)/headers |
| 681 | $(OBJDIR)/json_tag_.c: $(SRCDIR)/json_tag.c $(OBJDIR)/translate |
| 682 | $(OBJDIR)/translate $(SRCDIR)/json_tag.c >$(OBJDIR)/json_tag_.c |
| 683 | |
| 684 | $(OBJDIR)/json_tag.o: $(OBJDIR)/json_tag_.c $(OBJDIR)/json_tag.h $(SRCDIR)/config.h |
| 685 | $(XTCC) -o $(OBJDIR)/json_tag.o -c $(OBJDIR)/json_tag_.c |
| 686 | |
| 687 | $(OBJDIR)/json_tag.h: $(OBJDIR)/headers |
| 688 | $(OBJDIR)/json_timeline_.c: $(SRCDIR)/json_timeline.c $(OBJDIR)/translate |
| 689 | $(OBJDIR)/translate $(SRCDIR)/json_timeline.c >$(OBJDIR)/json_timeline_.c |
| 690 | |
| 691 | $(OBJDIR)/json_timeline.o: $(OBJDIR)/json_timeline_.c $(OBJDIR)/json_timeline.h $(SRCDIR)/config.h |
| 692 | $(XTCC) -o $(OBJDIR)/json_timeline.o -c $(OBJDIR)/json_timeline_.c |
| 693 | |
| 694 | $(OBJDIR)/json_timeline.h: $(OBJDIR)/headers |
| 695 | $(OBJDIR)/json_user_.c: $(SRCDIR)/json_user.c $(OBJDIR)/translate |
| 696 | $(OBJDIR)/translate $(SRCDIR)/json_user.c >$(OBJDIR)/json_user_.c |
| 697 | |
| 698 | $(OBJDIR)/json_user.o: $(OBJDIR)/json_user_.c $(OBJDIR)/json_user.h $(SRCDIR)/config.h |
| 699 | $(XTCC) -o $(OBJDIR)/json_user.o -c $(OBJDIR)/json_user_.c |
| 700 | |
| 701 | $(OBJDIR)/json_user.h: $(OBJDIR)/headers |
| 702 | $(OBJDIR)/json_wiki_.c: $(SRCDIR)/json_wiki.c $(OBJDIR)/translate |
| 703 | $(OBJDIR)/translate $(SRCDIR)/json_wiki.c >$(OBJDIR)/json_wiki_.c |
| 704 | |
| 705 | $(OBJDIR)/json_wiki.o: $(OBJDIR)/json_wiki_.c $(OBJDIR)/json_wiki.h $(SRCDIR)/config.h |
| 706 | $(XTCC) -o $(OBJDIR)/json_wiki.o -c $(OBJDIR)/json_wiki_.c |
| 707 | |
| 708 | $(OBJDIR)/json_wiki.h: $(OBJDIR)/headers |
| 709 | $(OBJDIR)/leaf_.c: $(SRCDIR)/leaf.c $(OBJDIR)/translate |
| 710 | $(OBJDIR)/translate $(SRCDIR)/leaf.c >$(OBJDIR)/leaf_.c |
| 711 | |
| 712 | $(OBJDIR)/leaf.o: $(OBJDIR)/leaf_.c $(OBJDIR)/leaf.h $(SRCDIR)/config.h |
| 713 | $(XTCC) -o $(OBJDIR)/leaf.o -c $(OBJDIR)/leaf_.c |
| @@ -916,5 +1027,9 @@ | |
| 1027 | $(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th_lang.c -o $(OBJDIR)/th_lang.o |
| 1028 | |
| 1029 | $(OBJDIR)/th_tcl.o: $(SRCDIR)/th_tcl.c |
| 1030 | $(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th_tcl.c -o $(OBJDIR)/th_tcl.o |
| 1031 | |
| 1032 | |
| 1033 | $(OBJDIR)/cson_amalgamation.o: $(SRCDIR)/cson_amalgamation.c |
| 1034 | $(XTCC) -I$(SRCDIR) -c $(SRCDIR)/cson_amalgamation.c -o $(OBJDIR)/cson_amalgamation.o -DCSON_FOSSIL_MODE |
| 1035 | |
| 1036 |
+117
-2
| --- src/main.mk | ||
| +++ src/main.mk | ||
| @@ -47,10 +47,21 @@ | ||
| 47 | 47 | $(SRCDIR)/http_socket.c \ |
| 48 | 48 | $(SRCDIR)/http_ssl.c \ |
| 49 | 49 | $(SRCDIR)/http_transport.c \ |
| 50 | 50 | $(SRCDIR)/import.c \ |
| 51 | 51 | $(SRCDIR)/info.c \ |
| 52 | + $(SRCDIR)/json.c \ | |
| 53 | + $(SRCDIR)/json_artifact.c \ | |
| 54 | + $(SRCDIR)/json_branch.c \ | |
| 55 | + $(SRCDIR)/json_diff.c \ | |
| 56 | + $(SRCDIR)/json_login.c \ | |
| 57 | + $(SRCDIR)/json_query.c \ | |
| 58 | + $(SRCDIR)/json_report.c \ | |
| 59 | + $(SRCDIR)/json_tag.c \ | |
| 60 | + $(SRCDIR)/json_timeline.c \ | |
| 61 | + $(SRCDIR)/json_user.c \ | |
| 62 | + $(SRCDIR)/json_wiki.c \ | |
| 52 | 63 | $(SRCDIR)/leaf.c \ |
| 53 | 64 | $(SRCDIR)/login.c \ |
| 54 | 65 | $(SRCDIR)/main.c \ |
| 55 | 66 | $(SRCDIR)/manifest.c \ |
| 56 | 67 | $(SRCDIR)/md5.c \ |
| @@ -131,10 +142,21 @@ | ||
| 131 | 142 | $(OBJDIR)/http_socket_.c \ |
| 132 | 143 | $(OBJDIR)/http_ssl_.c \ |
| 133 | 144 | $(OBJDIR)/http_transport_.c \ |
| 134 | 145 | $(OBJDIR)/import_.c \ |
| 135 | 146 | $(OBJDIR)/info_.c \ |
| 147 | + $(OBJDIR)/json_.c \ | |
| 148 | + $(OBJDIR)/json_artifact_.c \ | |
| 149 | + $(OBJDIR)/json_branch_.c \ | |
| 150 | + $(OBJDIR)/json_diff_.c \ | |
| 151 | + $(OBJDIR)/json_login_.c \ | |
| 152 | + $(OBJDIR)/json_query_.c \ | |
| 153 | + $(OBJDIR)/json_report_.c \ | |
| 154 | + $(OBJDIR)/json_tag_.c \ | |
| 155 | + $(OBJDIR)/json_timeline_.c \ | |
| 156 | + $(OBJDIR)/json_user_.c \ | |
| 157 | + $(OBJDIR)/json_wiki_.c \ | |
| 136 | 158 | $(OBJDIR)/leaf_.c \ |
| 137 | 159 | $(OBJDIR)/login_.c \ |
| 138 | 160 | $(OBJDIR)/main_.c \ |
| 139 | 161 | $(OBJDIR)/manifest_.c \ |
| 140 | 162 | $(OBJDIR)/md5_.c \ |
| @@ -215,10 +237,21 @@ | ||
| 215 | 237 | $(OBJDIR)/http_socket.o \ |
| 216 | 238 | $(OBJDIR)/http_ssl.o \ |
| 217 | 239 | $(OBJDIR)/http_transport.o \ |
| 218 | 240 | $(OBJDIR)/import.o \ |
| 219 | 241 | $(OBJDIR)/info.o \ |
| 242 | + $(OBJDIR)/json.o \ | |
| 243 | + $(OBJDIR)/json_artifact.o \ | |
| 244 | + $(OBJDIR)/json_branch.o \ | |
| 245 | + $(OBJDIR)/json_diff.o \ | |
| 246 | + $(OBJDIR)/json_login.o \ | |
| 247 | + $(OBJDIR)/json_query.o \ | |
| 248 | + $(OBJDIR)/json_report.o \ | |
| 249 | + $(OBJDIR)/json_tag.o \ | |
| 250 | + $(OBJDIR)/json_timeline.o \ | |
| 251 | + $(OBJDIR)/json_user.o \ | |
| 252 | + $(OBJDIR)/json_wiki.o \ | |
| 220 | 253 | $(OBJDIR)/leaf.o \ |
| 221 | 254 | $(OBJDIR)/login.o \ |
| 222 | 255 | $(OBJDIR)/main.o \ |
| 223 | 256 | $(OBJDIR)/manifest.o \ |
| 224 | 257 | $(OBJDIR)/md5.o \ |
| @@ -305,11 +338,11 @@ | ||
| 305 | 338 | |
| 306 | 339 | TCL_OBJ.1 = |
| 307 | 340 | TCL_OBJ.0 = $(OBJDIR)/th_tcl.o |
| 308 | 341 | TCL_OBJ. = $(TCL_OBJ.0) |
| 309 | 342 | |
| 310 | -EXTRAOBJ = $(SQLITE3_OBJ.$(USE_SYSTEM_SQLITE)) $(OBJDIR)/shell.o $(OBJDIR)/th.o $(OBJDIR)/th_lang.o $(TCL_OBJ.$(FOSSIL_ENABLE_TCL)) | |
| 343 | +EXTRAOBJ = $(SQLITE3_OBJ.$(USE_SYSTEM_SQLITE)) $(OBJDIR)/shell.o $(OBJDIR)/th.o $(OBJDIR)/th_lang.o $(TCL_OBJ.$(FOSSIL_ENABLE_TCL)) $(OBJDIR)/cson_amalgamation.o | |
| 311 | 344 | |
| 312 | 345 | $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) |
| 313 | 346 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) |
| 314 | 347 | |
| 315 | 348 | # This rule prevents make from using its default rules to try build |
| @@ -323,13 +356,14 @@ | ||
| 323 | 356 | |
| 324 | 357 | |
| 325 | 358 | $(OBJDIR)/page_index.h: $(TRANS_SRC) $(OBJDIR)/mkindex |
| 326 | 359 | $(OBJDIR)/mkindex $(TRANS_SRC) >$@ |
| 327 | 360 | $(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/makeheaders $(OBJDIR)/VERSION.h |
| 328 | - $(OBJDIR)/makeheaders $(OBJDIR)/add_.c:$(OBJDIR)/add.h $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h $(OBJDIR)/clearsign_.c:$(OBJDIR)/clearsign.h $(OBJDIR)/clone_.c:$(OBJDIR)/clone.h $(OBJDIR)/comformat_.c:$(OBJDIR)/comformat.h $(OBJDIR)/configure_.c:$(OBJDIR)/configure.h $(OBJDIR)/content_.c:$(OBJDIR)/content.h $(OBJDIR)/db_.c:$(OBJDIR)/db.h $(OBJDIR)/delta_.c:$(OBJDIR)/delta.h $(OBJDIR)/deltacmd_.c:$(OBJDIR)/deltacmd.h $(OBJDIR)/descendants_.c:$(OBJDIR)/descendants.h $(OBJDIR)/diff_.c:$(OBJDIR)/diff.h $(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h $(OBJDIR)/doc_.c:$(OBJDIR)/doc.h $(OBJDIR)/encode_.c:$(OBJDIR)/encode.h $(OBJDIR)/event_.c:$(OBJDIR)/event.h $(OBJDIR)/export_.c:$(OBJDIR)/export.h $(OBJDIR)/file_.c:$(OBJDIR)/file.h $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h $(OBJDIR)/glob_.c:$(OBJDIR)/glob.h $(OBJDIR)/graph_.c:$(OBJDIR)/graph.h $(OBJDIR)/gzip_.c:$(OBJDIR)/gzip.h $(OBJDIR)/http_.c:$(OBJDIR)/http.h $(OBJDIR)/http_socket_.c:$(OBJDIR)/http_socket.h $(OBJDIR)/http_ssl_.c:$(OBJDIR)/http_ssl.h $(OBJDIR)/http_transport_.c:$(OBJDIR)/http_transport.h $(OBJDIR)/import_.c:$(OBJDIR)/import.h $(OBJDIR)/info_.c:$(OBJDIR)/info.h $(OBJDIR)/leaf_.c:$(OBJDIR)/leaf.h $(OBJDIR)/login_.c:$(OBJDIR)/login.h $(OBJDIR)/main_.c:$(OBJDIR)/main.h $(OBJDIR)/manifest_.c:$(OBJDIR)/manifest.h $(OBJDIR)/md5_.c:$(OBJDIR)/md5.h $(OBJDIR)/merge_.c:$(OBJDIR)/merge.h $(OBJDIR)/merge3_.c:$(OBJDIR)/merge3.h $(OBJDIR)/name_.c:$(OBJDIR)/name.h $(OBJDIR)/path_.c:$(OBJDIR)/path.h $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h $(OBJDIR)/report_.c:$(OBJDIR)/report.h $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h $(OBJDIR)/search_.c:$(OBJDIR)/search.h $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h $(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h $(OBJDIR)/shun_.c:$(OBJDIR)/shun.h $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h $(OBJDIR)/style_.c:$(OBJDIR)/style.h $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h $(OBJDIR)/update_.c:$(OBJDIR)/update.h $(OBJDIR)/url_.c:$(OBJDIR)/url.h $(OBJDIR)/user_.c:$(OBJDIR)/user.h $(OBJDIR)/verify_.c:$(OBJDIR)/verify.h $(OBJDIR)/vfile_.c:$(OBJDIR)/vfile.h $(OBJDIR)/wiki_.c:$(OBJDIR)/wiki.h $(OBJDIR)/wikiformat_.c:$(OBJDIR)/wikiformat.h $(OBJDIR)/winhttp_.c:$(OBJDIR)/winhttp.h $(OBJDIR)/xfer_.c:$(OBJDIR)/xfer.h $(OBJDIR)/zip_.c:$(OBJDIR)/zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h $(OBJDIR)/VERSION.h | |
| 361 | + $(OBJDIR)/makeheaders $(OBJDIR)/add_.c:$(OBJDIR)/add.h $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h $(OBJDIR)/clearsign_.c:$(OBJDIR)/clearsign.h $(OBJDIR)/clone_.c:$(OBJDIR)/clone.h $(OBJDIR)/comformat_.c:$(OBJDIR)/comformat.h $(OBJDIR)/configure_.c:$(OBJDIR)/configure.h $(OBJDIR)/content_.c:$(OBJDIR)/content.h $(OBJDIR)/db_.c:$(OBJDIR)/db.h $(OBJDIR)/delta_.c:$(OBJDIR)/delta.h $(OBJDIR)/deltacmd_.c:$(OBJDIR)/deltacmd.h $(OBJDIR)/descendants_.c:$(OBJDIR)/descendants.h $(OBJDIR)/diff_.c:$(OBJDIR)/diff.h $(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h $(OBJDIR)/doc_.c:$(OBJDIR)/doc.h $(OBJDIR)/encode_.c:$(OBJDIR)/encode.h $(OBJDIR)/event_.c:$(OBJDIR)/event.h $(OBJDIR)/export_.c:$(OBJDIR)/export.h $(OBJDIR)/file_.c:$(OBJDIR)/file.h $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h $(OBJDIR)/glob_.c:$(OBJDIR)/glob.h $(OBJDIR)/graph_.c:$(OBJDIR)/graph.h $(OBJDIR)/gzip_.c:$(OBJDIR)/gzip.h $(OBJDIR)/http_.c:$(OBJDIR)/http.h $(OBJDIR)/http_socket_.c:$(OBJDIR)/http_socket.h $(OBJDIR)/http_ssl_.c:$(OBJDIR)/http_ssl.h $(OBJDIR)/http_transport_.c:$(OBJDIR)/http_transport.h $(OBJDIR)/import_.c:$(OBJDIR)/import.h $(OBJDIR)/info_.c:$(OBJDIR)/info.h $(OBJDIR)/json_.c:$(OBJDIR)/json.h $(OBJDIR)/json_artifact_.c:$(OBJDIR)/json_artifact.h $(OBJDIR)/json_branch_.c:$(OBJDIR)/json_branch.h $(OBJDIR)/json_diff_.c:$(OBJDIR)/json_diff.h $(OBJDIR)/json_login_.c:$(OBJDIR)/json_login.h $(OBJDIR)/json_query_.c:$(OBJDIR)/json_query.h $(OBJDIR)/json_report_.c:$(OBJDIR)/json_report.h $(OBJDIR)/json_tag_.c:$(OBJDIR)/json_tag.h $(OBJDIR)/json_timeline_.c:$(OBJDIR)/json_timeline.h $(OBJDIR)/json_user_.c:$(OBJDIR)/json_user.h $(OBJDIR)/json_wiki_.c:$(OBJDIR)/json_wiki.h $(OBJDIR)/leaf_.c:$(OBJDIR)/leaf.h $(OBJDIR)/login_.c:$(OBJDIR)/login.h $(OBJDIR)/main_.c:$(OBJDIR)/main.h $(OBJDIR)/manifest_.c:$(OBJDIR)/manifest.h $(OBJDIR)/md5_.c:$(OBJDIR)/md5.h $(OBJDIR)/merge_.c:$(OBJDIR)/merge.h $(OBJDIR)/merge3_.c:$(OBJDIR)/merge3.h $(OBJDIR)/name_.c:$(OBJDIR)/name.h $(OBJDIR)/path_.c:$(OBJDIR)/path.h $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h $(OBJDIR)/report_.c:$(OBJDIR)/report.h $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h $(OBJDIR)/search_.c:$(OBJDIR)/search.h $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h $(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h $(OBJDIR)/shun_.c:$(OBJDIR)/shun.h $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h $(OBJDIR)/style_.c:$(OBJDIR)/style.h $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h $(OBJDIR)/update_.c:$(OBJDIR)/update.h $(OBJDIR)/url_.c:$(OBJDIR)/url.h $(OBJDIR)/user_.c:$(OBJDIR)/user.h $(OBJDIR)/verify_.c:$(OBJDIR)/verify.h $(OBJDIR)/vfile_.c:$(OBJDIR)/vfile.h $(OBJDIR)/wiki_.c:$(OBJDIR)/wiki.h $(OBJDIR)/wikiformat_.c:$(OBJDIR)/wikiformat.h $(OBJDIR)/winhttp_.c:$(OBJDIR)/winhttp.h $(OBJDIR)/xfer_.c:$(OBJDIR)/xfer.h $(OBJDIR)/zip_.c:$(OBJDIR)/zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h $(OBJDIR)/VERSION.h | |
| 329 | 362 | touch $(OBJDIR)/headers |
| 330 | 363 | $(OBJDIR)/headers: Makefile |
| 364 | +$(OBJDIR)/json.o $(OBJDIR)/json_artifact.o $(OBJDIR)/json_branch.o $(OBJDIR)/json_diff.o $(OBJDIR)/json_login.o $(OBJDIR)/json_query.o $(OBJDIR)/json_report.o $(OBJDIR)/json_tag.o $(OBJDIR)/json_timeline.o $(OBJDIR)/json_user.o $(OBJDIR)/json_wiki.o : $(SRCDIR)/json_detail.h | |
| 331 | 365 | Makefile: |
| 332 | 366 | $(OBJDIR)/add_.c: $(SRCDIR)/add.c $(OBJDIR)/translate |
| 333 | 367 | $(OBJDIR)/translate $(SRCDIR)/add.c >$(OBJDIR)/add_.c |
| 334 | 368 | |
| 335 | 369 | $(OBJDIR)/add.o: $(OBJDIR)/add_.c $(OBJDIR)/add.h $(SRCDIR)/config.h |
| @@ -593,10 +627,87 @@ | ||
| 593 | 627 | |
| 594 | 628 | $(OBJDIR)/info.o: $(OBJDIR)/info_.c $(OBJDIR)/info.h $(SRCDIR)/config.h |
| 595 | 629 | $(XTCC) -o $(OBJDIR)/info.o -c $(OBJDIR)/info_.c |
| 596 | 630 | |
| 597 | 631 | $(OBJDIR)/info.h: $(OBJDIR)/headers |
| 632 | +$(OBJDIR)/json_.c: $(SRCDIR)/json.c $(OBJDIR)/translate | |
| 633 | + $(OBJDIR)/translate $(SRCDIR)/json.c >$(OBJDIR)/json_.c | |
| 634 | + | |
| 635 | +$(OBJDIR)/json.o: $(OBJDIR)/json_.c $(OBJDIR)/json.h $(SRCDIR)/config.h | |
| 636 | + $(XTCC) -o $(OBJDIR)/json.o -c $(OBJDIR)/json_.c | |
| 637 | + | |
| 638 | +$(OBJDIR)/json.h: $(OBJDIR)/headers | |
| 639 | +$(OBJDIR)/json_artifact_.c: $(SRCDIR)/json_artifact.c $(OBJDIR)/translate | |
| 640 | + $(OBJDIR)/translate $(SRCDIR)/json_artifact.c >$(OBJDIR)/json_artifact_.c | |
| 641 | + | |
| 642 | +$(OBJDIR)/json_artifact.o: $(OBJDIR)/json_artifact_.c $(OBJDIR)/json_artifact.h $(SRCDIR)/config.h | |
| 643 | + $(XTCC) -o $(OBJDIR)/json_artifact.o -c $(OBJDIR)/json_artifact_.c | |
| 644 | + | |
| 645 | +$(OBJDIR)/json_artifact.h: $(OBJDIR)/headers | |
| 646 | +$(OBJDIR)/json_branch_.c: $(SRCDIR)/json_branch.c $(OBJDIR)/translate | |
| 647 | + $(OBJDIR)/translate $(SRCDIR)/json_branch.c >$(OBJDIR)/json_branch_.c | |
| 648 | + | |
| 649 | +$(OBJDIR)/json_branch.o: $(OBJDIR)/json_branch_.c $(OBJDIR)/json_branch.h $(SRCDIR)/config.h | |
| 650 | + $(XTCC) -o $(OBJDIR)/json_branch.o -c $(OBJDIR)/json_branch_.c | |
| 651 | + | |
| 652 | +$(OBJDIR)/json_branch.h: $(OBJDIR)/headers | |
| 653 | +$(OBJDIR)/json_diff_.c: $(SRCDIR)/json_diff.c $(OBJDIR)/translate | |
| 654 | + $(OBJDIR)/translate $(SRCDIR)/json_diff.c >$(OBJDIR)/json_diff_.c | |
| 655 | + | |
| 656 | +$(OBJDIR)/json_diff.o: $(OBJDIR)/json_diff_.c $(OBJDIR)/json_diff.h $(SRCDIR)/config.h | |
| 657 | + $(XTCC) -o $(OBJDIR)/json_diff.o -c $(OBJDIR)/json_diff_.c | |
| 658 | + | |
| 659 | +$(OBJDIR)/json_diff.h: $(OBJDIR)/headers | |
| 660 | +$(OBJDIR)/json_login_.c: $(SRCDIR)/json_login.c $(OBJDIR)/translate | |
| 661 | + $(OBJDIR)/translate $(SRCDIR)/json_login.c >$(OBJDIR)/json_login_.c | |
| 662 | + | |
| 663 | +$(OBJDIR)/json_login.o: $(OBJDIR)/json_login_.c $(OBJDIR)/json_login.h $(SRCDIR)/config.h | |
| 664 | + $(XTCC) -o $(OBJDIR)/json_login.o -c $(OBJDIR)/json_login_.c | |
| 665 | + | |
| 666 | +$(OBJDIR)/json_login.h: $(OBJDIR)/headers | |
| 667 | +$(OBJDIR)/json_query_.c: $(SRCDIR)/json_query.c $(OBJDIR)/translate | |
| 668 | + $(OBJDIR)/translate $(SRCDIR)/json_query.c >$(OBJDIR)/json_query_.c | |
| 669 | + | |
| 670 | +$(OBJDIR)/json_query.o: $(OBJDIR)/json_query_.c $(OBJDIR)/json_query.h $(SRCDIR)/config.h | |
| 671 | + $(XTCC) -o $(OBJDIR)/json_query.o -c $(OBJDIR)/json_query_.c | |
| 672 | + | |
| 673 | +$(OBJDIR)/json_query.h: $(OBJDIR)/headers | |
| 674 | +$(OBJDIR)/json_report_.c: $(SRCDIR)/json_report.c $(OBJDIR)/translate | |
| 675 | + $(OBJDIR)/translate $(SRCDIR)/json_report.c >$(OBJDIR)/json_report_.c | |
| 676 | + | |
| 677 | +$(OBJDIR)/json_report.o: $(OBJDIR)/json_report_.c $(OBJDIR)/json_report.h $(SRCDIR)/config.h | |
| 678 | + $(XTCC) -o $(OBJDIR)/json_report.o -c $(OBJDIR)/json_report_.c | |
| 679 | + | |
| 680 | +$(OBJDIR)/json_report.h: $(OBJDIR)/headers | |
| 681 | +$(OBJDIR)/json_tag_.c: $(SRCDIR)/json_tag.c $(OBJDIR)/translate | |
| 682 | + $(OBJDIR)/translate $(SRCDIR)/json_tag.c >$(OBJDIR)/json_tag_.c | |
| 683 | + | |
| 684 | +$(OBJDIR)/json_tag.o: $(OBJDIR)/json_tag_.c $(OBJDIR)/json_tag.h $(SRCDIR)/config.h | |
| 685 | + $(XTCC) -o $(OBJDIR)/json_tag.o -c $(OBJDIR)/json_tag_.c | |
| 686 | + | |
| 687 | +$(OBJDIR)/json_tag.h: $(OBJDIR)/headers | |
| 688 | +$(OBJDIR)/json_timeline_.c: $(SRCDIR)/json_timeline.c $(OBJDIR)/translate | |
| 689 | + $(OBJDIR)/translate $(SRCDIR)/json_timeline.c >$(OBJDIR)/json_timeline_.c | |
| 690 | + | |
| 691 | +$(OBJDIR)/json_timeline.o: $(OBJDIR)/json_timeline_.c $(OBJDIR)/json_timeline.h $(SRCDIR)/config.h | |
| 692 | + $(XTCC) -o $(OBJDIR)/json_timeline.o -c $(OBJDIR)/json_timeline_.c | |
| 693 | + | |
| 694 | +$(OBJDIR)/json_timeline.h: $(OBJDIR)/headers | |
| 695 | +$(OBJDIR)/json_user_.c: $(SRCDIR)/json_user.c $(OBJDIR)/translate | |
| 696 | + $(OBJDIR)/translate $(SRCDIR)/json_user.c >$(OBJDIR)/json_user_.c | |
| 697 | + | |
| 698 | +$(OBJDIR)/json_user.o: $(OBJDIR)/json_user_.c $(OBJDIR)/json_user.h $(SRCDIR)/config.h | |
| 699 | + $(XTCC) -o $(OBJDIR)/json_user.o -c $(OBJDIR)/json_user_.c | |
| 700 | + | |
| 701 | +$(OBJDIR)/json_user.h: $(OBJDIR)/headers | |
| 702 | +$(OBJDIR)/json_wiki_.c: $(SRCDIR)/json_wiki.c $(OBJDIR)/translate | |
| 703 | + $(OBJDIR)/translate $(SRCDIR)/json_wiki.c >$(OBJDIR)/json_wiki_.c | |
| 704 | + | |
| 705 | +$(OBJDIR)/json_wiki.o: $(OBJDIR)/json_wiki_.c $(OBJDIR)/json_wiki.h $(SRCDIR)/config.h | |
| 706 | + $(XTCC) -o $(OBJDIR)/json_wiki.o -c $(OBJDIR)/json_wiki_.c | |
| 707 | + | |
| 708 | +$(OBJDIR)/json_wiki.h: $(OBJDIR)/headers | |
| 598 | 709 | $(OBJDIR)/leaf_.c: $(SRCDIR)/leaf.c $(OBJDIR)/translate |
| 599 | 710 | $(OBJDIR)/translate $(SRCDIR)/leaf.c >$(OBJDIR)/leaf_.c |
| 600 | 711 | |
| 601 | 712 | $(OBJDIR)/leaf.o: $(OBJDIR)/leaf_.c $(OBJDIR)/leaf.h $(SRCDIR)/config.h |
| 602 | 713 | $(XTCC) -o $(OBJDIR)/leaf.o -c $(OBJDIR)/leaf_.c |
| @@ -916,5 +1027,9 @@ | ||
| 916 | 1027 | $(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th_lang.c -o $(OBJDIR)/th_lang.o |
| 917 | 1028 | |
| 918 | 1029 | $(OBJDIR)/th_tcl.o: $(SRCDIR)/th_tcl.c |
| 919 | 1030 | $(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th_tcl.c -o $(OBJDIR)/th_tcl.o |
| 920 | 1031 | |
| 1032 | + | |
| 1033 | +$(OBJDIR)/cson_amalgamation.o: $(SRCDIR)/cson_amalgamation.c | |
| 1034 | + $(XTCC) -I$(SRCDIR) -c $(SRCDIR)/cson_amalgamation.c -o $(OBJDIR)/cson_amalgamation.o -DCSON_FOSSIL_MODE | |
| 1035 | + | |
| 921 | 1036 |
| --- src/main.mk | |
| +++ src/main.mk | |
| @@ -47,10 +47,21 @@ | |
| 47 | $(SRCDIR)/http_socket.c \ |
| 48 | $(SRCDIR)/http_ssl.c \ |
| 49 | $(SRCDIR)/http_transport.c \ |
| 50 | $(SRCDIR)/import.c \ |
| 51 | $(SRCDIR)/info.c \ |
| 52 | $(SRCDIR)/leaf.c \ |
| 53 | $(SRCDIR)/login.c \ |
| 54 | $(SRCDIR)/main.c \ |
| 55 | $(SRCDIR)/manifest.c \ |
| 56 | $(SRCDIR)/md5.c \ |
| @@ -131,10 +142,21 @@ | |
| 131 | $(OBJDIR)/http_socket_.c \ |
| 132 | $(OBJDIR)/http_ssl_.c \ |
| 133 | $(OBJDIR)/http_transport_.c \ |
| 134 | $(OBJDIR)/import_.c \ |
| 135 | $(OBJDIR)/info_.c \ |
| 136 | $(OBJDIR)/leaf_.c \ |
| 137 | $(OBJDIR)/login_.c \ |
| 138 | $(OBJDIR)/main_.c \ |
| 139 | $(OBJDIR)/manifest_.c \ |
| 140 | $(OBJDIR)/md5_.c \ |
| @@ -215,10 +237,21 @@ | |
| 215 | $(OBJDIR)/http_socket.o \ |
| 216 | $(OBJDIR)/http_ssl.o \ |
| 217 | $(OBJDIR)/http_transport.o \ |
| 218 | $(OBJDIR)/import.o \ |
| 219 | $(OBJDIR)/info.o \ |
| 220 | $(OBJDIR)/leaf.o \ |
| 221 | $(OBJDIR)/login.o \ |
| 222 | $(OBJDIR)/main.o \ |
| 223 | $(OBJDIR)/manifest.o \ |
| 224 | $(OBJDIR)/md5.o \ |
| @@ -305,11 +338,11 @@ | |
| 305 | |
| 306 | TCL_OBJ.1 = |
| 307 | TCL_OBJ.0 = $(OBJDIR)/th_tcl.o |
| 308 | TCL_OBJ. = $(TCL_OBJ.0) |
| 309 | |
| 310 | EXTRAOBJ = $(SQLITE3_OBJ.$(USE_SYSTEM_SQLITE)) $(OBJDIR)/shell.o $(OBJDIR)/th.o $(OBJDIR)/th_lang.o $(TCL_OBJ.$(FOSSIL_ENABLE_TCL)) |
| 311 | |
| 312 | $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) |
| 313 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) |
| 314 | |
| 315 | # This rule prevents make from using its default rules to try build |
| @@ -323,13 +356,14 @@ | |
| 323 | |
| 324 | |
| 325 | $(OBJDIR)/page_index.h: $(TRANS_SRC) $(OBJDIR)/mkindex |
| 326 | $(OBJDIR)/mkindex $(TRANS_SRC) >$@ |
| 327 | $(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/makeheaders $(OBJDIR)/VERSION.h |
| 328 | $(OBJDIR)/makeheaders $(OBJDIR)/add_.c:$(OBJDIR)/add.h $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h $(OBJDIR)/clearsign_.c:$(OBJDIR)/clearsign.h $(OBJDIR)/clone_.c:$(OBJDIR)/clone.h $(OBJDIR)/comformat_.c:$(OBJDIR)/comformat.h $(OBJDIR)/configure_.c:$(OBJDIR)/configure.h $(OBJDIR)/content_.c:$(OBJDIR)/content.h $(OBJDIR)/db_.c:$(OBJDIR)/db.h $(OBJDIR)/delta_.c:$(OBJDIR)/delta.h $(OBJDIR)/deltacmd_.c:$(OBJDIR)/deltacmd.h $(OBJDIR)/descendants_.c:$(OBJDIR)/descendants.h $(OBJDIR)/diff_.c:$(OBJDIR)/diff.h $(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h $(OBJDIR)/doc_.c:$(OBJDIR)/doc.h $(OBJDIR)/encode_.c:$(OBJDIR)/encode.h $(OBJDIR)/event_.c:$(OBJDIR)/event.h $(OBJDIR)/export_.c:$(OBJDIR)/export.h $(OBJDIR)/file_.c:$(OBJDIR)/file.h $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h $(OBJDIR)/glob_.c:$(OBJDIR)/glob.h $(OBJDIR)/graph_.c:$(OBJDIR)/graph.h $(OBJDIR)/gzip_.c:$(OBJDIR)/gzip.h $(OBJDIR)/http_.c:$(OBJDIR)/http.h $(OBJDIR)/http_socket_.c:$(OBJDIR)/http_socket.h $(OBJDIR)/http_ssl_.c:$(OBJDIR)/http_ssl.h $(OBJDIR)/http_transport_.c:$(OBJDIR)/http_transport.h $(OBJDIR)/import_.c:$(OBJDIR)/import.h $(OBJDIR)/info_.c:$(OBJDIR)/info.h $(OBJDIR)/leaf_.c:$(OBJDIR)/leaf.h $(OBJDIR)/login_.c:$(OBJDIR)/login.h $(OBJDIR)/main_.c:$(OBJDIR)/main.h $(OBJDIR)/manifest_.c:$(OBJDIR)/manifest.h $(OBJDIR)/md5_.c:$(OBJDIR)/md5.h $(OBJDIR)/merge_.c:$(OBJDIR)/merge.h $(OBJDIR)/merge3_.c:$(OBJDIR)/merge3.h $(OBJDIR)/name_.c:$(OBJDIR)/name.h $(OBJDIR)/path_.c:$(OBJDIR)/path.h $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h $(OBJDIR)/report_.c:$(OBJDIR)/report.h $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h $(OBJDIR)/search_.c:$(OBJDIR)/search.h $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h $(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h $(OBJDIR)/shun_.c:$(OBJDIR)/shun.h $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h $(OBJDIR)/style_.c:$(OBJDIR)/style.h $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h $(OBJDIR)/update_.c:$(OBJDIR)/update.h $(OBJDIR)/url_.c:$(OBJDIR)/url.h $(OBJDIR)/user_.c:$(OBJDIR)/user.h $(OBJDIR)/verify_.c:$(OBJDIR)/verify.h $(OBJDIR)/vfile_.c:$(OBJDIR)/vfile.h $(OBJDIR)/wiki_.c:$(OBJDIR)/wiki.h $(OBJDIR)/wikiformat_.c:$(OBJDIR)/wikiformat.h $(OBJDIR)/winhttp_.c:$(OBJDIR)/winhttp.h $(OBJDIR)/xfer_.c:$(OBJDIR)/xfer.h $(OBJDIR)/zip_.c:$(OBJDIR)/zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h $(OBJDIR)/VERSION.h |
| 329 | touch $(OBJDIR)/headers |
| 330 | $(OBJDIR)/headers: Makefile |
| 331 | Makefile: |
| 332 | $(OBJDIR)/add_.c: $(SRCDIR)/add.c $(OBJDIR)/translate |
| 333 | $(OBJDIR)/translate $(SRCDIR)/add.c >$(OBJDIR)/add_.c |
| 334 | |
| 335 | $(OBJDIR)/add.o: $(OBJDIR)/add_.c $(OBJDIR)/add.h $(SRCDIR)/config.h |
| @@ -593,10 +627,87 @@ | |
| 593 | |
| 594 | $(OBJDIR)/info.o: $(OBJDIR)/info_.c $(OBJDIR)/info.h $(SRCDIR)/config.h |
| 595 | $(XTCC) -o $(OBJDIR)/info.o -c $(OBJDIR)/info_.c |
| 596 | |
| 597 | $(OBJDIR)/info.h: $(OBJDIR)/headers |
| 598 | $(OBJDIR)/leaf_.c: $(SRCDIR)/leaf.c $(OBJDIR)/translate |
| 599 | $(OBJDIR)/translate $(SRCDIR)/leaf.c >$(OBJDIR)/leaf_.c |
| 600 | |
| 601 | $(OBJDIR)/leaf.o: $(OBJDIR)/leaf_.c $(OBJDIR)/leaf.h $(SRCDIR)/config.h |
| 602 | $(XTCC) -o $(OBJDIR)/leaf.o -c $(OBJDIR)/leaf_.c |
| @@ -916,5 +1027,9 @@ | |
| 916 | $(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th_lang.c -o $(OBJDIR)/th_lang.o |
| 917 | |
| 918 | $(OBJDIR)/th_tcl.o: $(SRCDIR)/th_tcl.c |
| 919 | $(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th_tcl.c -o $(OBJDIR)/th_tcl.o |
| 920 | |
| 921 |
| --- src/main.mk | |
| +++ src/main.mk | |
| @@ -47,10 +47,21 @@ | |
| 47 | $(SRCDIR)/http_socket.c \ |
| 48 | $(SRCDIR)/http_ssl.c \ |
| 49 | $(SRCDIR)/http_transport.c \ |
| 50 | $(SRCDIR)/import.c \ |
| 51 | $(SRCDIR)/info.c \ |
| 52 | $(SRCDIR)/json.c \ |
| 53 | $(SRCDIR)/json_artifact.c \ |
| 54 | $(SRCDIR)/json_branch.c \ |
| 55 | $(SRCDIR)/json_diff.c \ |
| 56 | $(SRCDIR)/json_login.c \ |
| 57 | $(SRCDIR)/json_query.c \ |
| 58 | $(SRCDIR)/json_report.c \ |
| 59 | $(SRCDIR)/json_tag.c \ |
| 60 | $(SRCDIR)/json_timeline.c \ |
| 61 | $(SRCDIR)/json_user.c \ |
| 62 | $(SRCDIR)/json_wiki.c \ |
| 63 | $(SRCDIR)/leaf.c \ |
| 64 | $(SRCDIR)/login.c \ |
| 65 | $(SRCDIR)/main.c \ |
| 66 | $(SRCDIR)/manifest.c \ |
| 67 | $(SRCDIR)/md5.c \ |
| @@ -131,10 +142,21 @@ | |
| 142 | $(OBJDIR)/http_socket_.c \ |
| 143 | $(OBJDIR)/http_ssl_.c \ |
| 144 | $(OBJDIR)/http_transport_.c \ |
| 145 | $(OBJDIR)/import_.c \ |
| 146 | $(OBJDIR)/info_.c \ |
| 147 | $(OBJDIR)/json_.c \ |
| 148 | $(OBJDIR)/json_artifact_.c \ |
| 149 | $(OBJDIR)/json_branch_.c \ |
| 150 | $(OBJDIR)/json_diff_.c \ |
| 151 | $(OBJDIR)/json_login_.c \ |
| 152 | $(OBJDIR)/json_query_.c \ |
| 153 | $(OBJDIR)/json_report_.c \ |
| 154 | $(OBJDIR)/json_tag_.c \ |
| 155 | $(OBJDIR)/json_timeline_.c \ |
| 156 | $(OBJDIR)/json_user_.c \ |
| 157 | $(OBJDIR)/json_wiki_.c \ |
| 158 | $(OBJDIR)/leaf_.c \ |
| 159 | $(OBJDIR)/login_.c \ |
| 160 | $(OBJDIR)/main_.c \ |
| 161 | $(OBJDIR)/manifest_.c \ |
| 162 | $(OBJDIR)/md5_.c \ |
| @@ -215,10 +237,21 @@ | |
| 237 | $(OBJDIR)/http_socket.o \ |
| 238 | $(OBJDIR)/http_ssl.o \ |
| 239 | $(OBJDIR)/http_transport.o \ |
| 240 | $(OBJDIR)/import.o \ |
| 241 | $(OBJDIR)/info.o \ |
| 242 | $(OBJDIR)/json.o \ |
| 243 | $(OBJDIR)/json_artifact.o \ |
| 244 | $(OBJDIR)/json_branch.o \ |
| 245 | $(OBJDIR)/json_diff.o \ |
| 246 | $(OBJDIR)/json_login.o \ |
| 247 | $(OBJDIR)/json_query.o \ |
| 248 | $(OBJDIR)/json_report.o \ |
| 249 | $(OBJDIR)/json_tag.o \ |
| 250 | $(OBJDIR)/json_timeline.o \ |
| 251 | $(OBJDIR)/json_user.o \ |
| 252 | $(OBJDIR)/json_wiki.o \ |
| 253 | $(OBJDIR)/leaf.o \ |
| 254 | $(OBJDIR)/login.o \ |
| 255 | $(OBJDIR)/main.o \ |
| 256 | $(OBJDIR)/manifest.o \ |
| 257 | $(OBJDIR)/md5.o \ |
| @@ -305,11 +338,11 @@ | |
| 338 | |
| 339 | TCL_OBJ.1 = |
| 340 | TCL_OBJ.0 = $(OBJDIR)/th_tcl.o |
| 341 | TCL_OBJ. = $(TCL_OBJ.0) |
| 342 | |
| 343 | EXTRAOBJ = $(SQLITE3_OBJ.$(USE_SYSTEM_SQLITE)) $(OBJDIR)/shell.o $(OBJDIR)/th.o $(OBJDIR)/th_lang.o $(TCL_OBJ.$(FOSSIL_ENABLE_TCL)) $(OBJDIR)/cson_amalgamation.o |
| 344 | |
| 345 | $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) |
| 346 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) |
| 347 | |
| 348 | # This rule prevents make from using its default rules to try build |
| @@ -323,13 +356,14 @@ | |
| 356 | |
| 357 | |
| 358 | $(OBJDIR)/page_index.h: $(TRANS_SRC) $(OBJDIR)/mkindex |
| 359 | $(OBJDIR)/mkindex $(TRANS_SRC) >$@ |
| 360 | $(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/makeheaders $(OBJDIR)/VERSION.h |
| 361 | $(OBJDIR)/makeheaders $(OBJDIR)/add_.c:$(OBJDIR)/add.h $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h $(OBJDIR)/clearsign_.c:$(OBJDIR)/clearsign.h $(OBJDIR)/clone_.c:$(OBJDIR)/clone.h $(OBJDIR)/comformat_.c:$(OBJDIR)/comformat.h $(OBJDIR)/configure_.c:$(OBJDIR)/configure.h $(OBJDIR)/content_.c:$(OBJDIR)/content.h $(OBJDIR)/db_.c:$(OBJDIR)/db.h $(OBJDIR)/delta_.c:$(OBJDIR)/delta.h $(OBJDIR)/deltacmd_.c:$(OBJDIR)/deltacmd.h $(OBJDIR)/descendants_.c:$(OBJDIR)/descendants.h $(OBJDIR)/diff_.c:$(OBJDIR)/diff.h $(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h $(OBJDIR)/doc_.c:$(OBJDIR)/doc.h $(OBJDIR)/encode_.c:$(OBJDIR)/encode.h $(OBJDIR)/event_.c:$(OBJDIR)/event.h $(OBJDIR)/export_.c:$(OBJDIR)/export.h $(OBJDIR)/file_.c:$(OBJDIR)/file.h $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h $(OBJDIR)/glob_.c:$(OBJDIR)/glob.h $(OBJDIR)/graph_.c:$(OBJDIR)/graph.h $(OBJDIR)/gzip_.c:$(OBJDIR)/gzip.h $(OBJDIR)/http_.c:$(OBJDIR)/http.h $(OBJDIR)/http_socket_.c:$(OBJDIR)/http_socket.h $(OBJDIR)/http_ssl_.c:$(OBJDIR)/http_ssl.h $(OBJDIR)/http_transport_.c:$(OBJDIR)/http_transport.h $(OBJDIR)/import_.c:$(OBJDIR)/import.h $(OBJDIR)/info_.c:$(OBJDIR)/info.h $(OBJDIR)/json_.c:$(OBJDIR)/json.h $(OBJDIR)/json_artifact_.c:$(OBJDIR)/json_artifact.h $(OBJDIR)/json_branch_.c:$(OBJDIR)/json_branch.h $(OBJDIR)/json_diff_.c:$(OBJDIR)/json_diff.h $(OBJDIR)/json_login_.c:$(OBJDIR)/json_login.h $(OBJDIR)/json_query_.c:$(OBJDIR)/json_query.h $(OBJDIR)/json_report_.c:$(OBJDIR)/json_report.h $(OBJDIR)/json_tag_.c:$(OBJDIR)/json_tag.h $(OBJDIR)/json_timeline_.c:$(OBJDIR)/json_timeline.h $(OBJDIR)/json_user_.c:$(OBJDIR)/json_user.h $(OBJDIR)/json_wiki_.c:$(OBJDIR)/json_wiki.h $(OBJDIR)/leaf_.c:$(OBJDIR)/leaf.h $(OBJDIR)/login_.c:$(OBJDIR)/login.h $(OBJDIR)/main_.c:$(OBJDIR)/main.h $(OBJDIR)/manifest_.c:$(OBJDIR)/manifest.h $(OBJDIR)/md5_.c:$(OBJDIR)/md5.h $(OBJDIR)/merge_.c:$(OBJDIR)/merge.h $(OBJDIR)/merge3_.c:$(OBJDIR)/merge3.h $(OBJDIR)/name_.c:$(OBJDIR)/name.h $(OBJDIR)/path_.c:$(OBJDIR)/path.h $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h $(OBJDIR)/report_.c:$(OBJDIR)/report.h $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h $(OBJDIR)/search_.c:$(OBJDIR)/search.h $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h $(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h $(OBJDIR)/shun_.c:$(OBJDIR)/shun.h $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h $(OBJDIR)/style_.c:$(OBJDIR)/style.h $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h $(OBJDIR)/update_.c:$(OBJDIR)/update.h $(OBJDIR)/url_.c:$(OBJDIR)/url.h $(OBJDIR)/user_.c:$(OBJDIR)/user.h $(OBJDIR)/verify_.c:$(OBJDIR)/verify.h $(OBJDIR)/vfile_.c:$(OBJDIR)/vfile.h $(OBJDIR)/wiki_.c:$(OBJDIR)/wiki.h $(OBJDIR)/wikiformat_.c:$(OBJDIR)/wikiformat.h $(OBJDIR)/winhttp_.c:$(OBJDIR)/winhttp.h $(OBJDIR)/xfer_.c:$(OBJDIR)/xfer.h $(OBJDIR)/zip_.c:$(OBJDIR)/zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h $(OBJDIR)/VERSION.h |
| 362 | touch $(OBJDIR)/headers |
| 363 | $(OBJDIR)/headers: Makefile |
| 364 | $(OBJDIR)/json.o $(OBJDIR)/json_artifact.o $(OBJDIR)/json_branch.o $(OBJDIR)/json_diff.o $(OBJDIR)/json_login.o $(OBJDIR)/json_query.o $(OBJDIR)/json_report.o $(OBJDIR)/json_tag.o $(OBJDIR)/json_timeline.o $(OBJDIR)/json_user.o $(OBJDIR)/json_wiki.o : $(SRCDIR)/json_detail.h |
| 365 | Makefile: |
| 366 | $(OBJDIR)/add_.c: $(SRCDIR)/add.c $(OBJDIR)/translate |
| 367 | $(OBJDIR)/translate $(SRCDIR)/add.c >$(OBJDIR)/add_.c |
| 368 | |
| 369 | $(OBJDIR)/add.o: $(OBJDIR)/add_.c $(OBJDIR)/add.h $(SRCDIR)/config.h |
| @@ -593,10 +627,87 @@ | |
| 627 | |
| 628 | $(OBJDIR)/info.o: $(OBJDIR)/info_.c $(OBJDIR)/info.h $(SRCDIR)/config.h |
| 629 | $(XTCC) -o $(OBJDIR)/info.o -c $(OBJDIR)/info_.c |
| 630 | |
| 631 | $(OBJDIR)/info.h: $(OBJDIR)/headers |
| 632 | $(OBJDIR)/json_.c: $(SRCDIR)/json.c $(OBJDIR)/translate |
| 633 | $(OBJDIR)/translate $(SRCDIR)/json.c >$(OBJDIR)/json_.c |
| 634 | |
| 635 | $(OBJDIR)/json.o: $(OBJDIR)/json_.c $(OBJDIR)/json.h $(SRCDIR)/config.h |
| 636 | $(XTCC) -o $(OBJDIR)/json.o -c $(OBJDIR)/json_.c |
| 637 | |
| 638 | $(OBJDIR)/json.h: $(OBJDIR)/headers |
| 639 | $(OBJDIR)/json_artifact_.c: $(SRCDIR)/json_artifact.c $(OBJDIR)/translate |
| 640 | $(OBJDIR)/translate $(SRCDIR)/json_artifact.c >$(OBJDIR)/json_artifact_.c |
| 641 | |
| 642 | $(OBJDIR)/json_artifact.o: $(OBJDIR)/json_artifact_.c $(OBJDIR)/json_artifact.h $(SRCDIR)/config.h |
| 643 | $(XTCC) -o $(OBJDIR)/json_artifact.o -c $(OBJDIR)/json_artifact_.c |
| 644 | |
| 645 | $(OBJDIR)/json_artifact.h: $(OBJDIR)/headers |
| 646 | $(OBJDIR)/json_branch_.c: $(SRCDIR)/json_branch.c $(OBJDIR)/translate |
| 647 | $(OBJDIR)/translate $(SRCDIR)/json_branch.c >$(OBJDIR)/json_branch_.c |
| 648 | |
| 649 | $(OBJDIR)/json_branch.o: $(OBJDIR)/json_branch_.c $(OBJDIR)/json_branch.h $(SRCDIR)/config.h |
| 650 | $(XTCC) -o $(OBJDIR)/json_branch.o -c $(OBJDIR)/json_branch_.c |
| 651 | |
| 652 | $(OBJDIR)/json_branch.h: $(OBJDIR)/headers |
| 653 | $(OBJDIR)/json_diff_.c: $(SRCDIR)/json_diff.c $(OBJDIR)/translate |
| 654 | $(OBJDIR)/translate $(SRCDIR)/json_diff.c >$(OBJDIR)/json_diff_.c |
| 655 | |
| 656 | $(OBJDIR)/json_diff.o: $(OBJDIR)/json_diff_.c $(OBJDIR)/json_diff.h $(SRCDIR)/config.h |
| 657 | $(XTCC) -o $(OBJDIR)/json_diff.o -c $(OBJDIR)/json_diff_.c |
| 658 | |
| 659 | $(OBJDIR)/json_diff.h: $(OBJDIR)/headers |
| 660 | $(OBJDIR)/json_login_.c: $(SRCDIR)/json_login.c $(OBJDIR)/translate |
| 661 | $(OBJDIR)/translate $(SRCDIR)/json_login.c >$(OBJDIR)/json_login_.c |
| 662 | |
| 663 | $(OBJDIR)/json_login.o: $(OBJDIR)/json_login_.c $(OBJDIR)/json_login.h $(SRCDIR)/config.h |
| 664 | $(XTCC) -o $(OBJDIR)/json_login.o -c $(OBJDIR)/json_login_.c |
| 665 | |
| 666 | $(OBJDIR)/json_login.h: $(OBJDIR)/headers |
| 667 | $(OBJDIR)/json_query_.c: $(SRCDIR)/json_query.c $(OBJDIR)/translate |
| 668 | $(OBJDIR)/translate $(SRCDIR)/json_query.c >$(OBJDIR)/json_query_.c |
| 669 | |
| 670 | $(OBJDIR)/json_query.o: $(OBJDIR)/json_query_.c $(OBJDIR)/json_query.h $(SRCDIR)/config.h |
| 671 | $(XTCC) -o $(OBJDIR)/json_query.o -c $(OBJDIR)/json_query_.c |
| 672 | |
| 673 | $(OBJDIR)/json_query.h: $(OBJDIR)/headers |
| 674 | $(OBJDIR)/json_report_.c: $(SRCDIR)/json_report.c $(OBJDIR)/translate |
| 675 | $(OBJDIR)/translate $(SRCDIR)/json_report.c >$(OBJDIR)/json_report_.c |
| 676 | |
| 677 | $(OBJDIR)/json_report.o: $(OBJDIR)/json_report_.c $(OBJDIR)/json_report.h $(SRCDIR)/config.h |
| 678 | $(XTCC) -o $(OBJDIR)/json_report.o -c $(OBJDIR)/json_report_.c |
| 679 | |
| 680 | $(OBJDIR)/json_report.h: $(OBJDIR)/headers |
| 681 | $(OBJDIR)/json_tag_.c: $(SRCDIR)/json_tag.c $(OBJDIR)/translate |
| 682 | $(OBJDIR)/translate $(SRCDIR)/json_tag.c >$(OBJDIR)/json_tag_.c |
| 683 | |
| 684 | $(OBJDIR)/json_tag.o: $(OBJDIR)/json_tag_.c $(OBJDIR)/json_tag.h $(SRCDIR)/config.h |
| 685 | $(XTCC) -o $(OBJDIR)/json_tag.o -c $(OBJDIR)/json_tag_.c |
| 686 | |
| 687 | $(OBJDIR)/json_tag.h: $(OBJDIR)/headers |
| 688 | $(OBJDIR)/json_timeline_.c: $(SRCDIR)/json_timeline.c $(OBJDIR)/translate |
| 689 | $(OBJDIR)/translate $(SRCDIR)/json_timeline.c >$(OBJDIR)/json_timeline_.c |
| 690 | |
| 691 | $(OBJDIR)/json_timeline.o: $(OBJDIR)/json_timeline_.c $(OBJDIR)/json_timeline.h $(SRCDIR)/config.h |
| 692 | $(XTCC) -o $(OBJDIR)/json_timeline.o -c $(OBJDIR)/json_timeline_.c |
| 693 | |
| 694 | $(OBJDIR)/json_timeline.h: $(OBJDIR)/headers |
| 695 | $(OBJDIR)/json_user_.c: $(SRCDIR)/json_user.c $(OBJDIR)/translate |
| 696 | $(OBJDIR)/translate $(SRCDIR)/json_user.c >$(OBJDIR)/json_user_.c |
| 697 | |
| 698 | $(OBJDIR)/json_user.o: $(OBJDIR)/json_user_.c $(OBJDIR)/json_user.h $(SRCDIR)/config.h |
| 699 | $(XTCC) -o $(OBJDIR)/json_user.o -c $(OBJDIR)/json_user_.c |
| 700 | |
| 701 | $(OBJDIR)/json_user.h: $(OBJDIR)/headers |
| 702 | $(OBJDIR)/json_wiki_.c: $(SRCDIR)/json_wiki.c $(OBJDIR)/translate |
| 703 | $(OBJDIR)/translate $(SRCDIR)/json_wiki.c >$(OBJDIR)/json_wiki_.c |
| 704 | |
| 705 | $(OBJDIR)/json_wiki.o: $(OBJDIR)/json_wiki_.c $(OBJDIR)/json_wiki.h $(SRCDIR)/config.h |
| 706 | $(XTCC) -o $(OBJDIR)/json_wiki.o -c $(OBJDIR)/json_wiki_.c |
| 707 | |
| 708 | $(OBJDIR)/json_wiki.h: $(OBJDIR)/headers |
| 709 | $(OBJDIR)/leaf_.c: $(SRCDIR)/leaf.c $(OBJDIR)/translate |
| 710 | $(OBJDIR)/translate $(SRCDIR)/leaf.c >$(OBJDIR)/leaf_.c |
| 711 | |
| 712 | $(OBJDIR)/leaf.o: $(OBJDIR)/leaf_.c $(OBJDIR)/leaf.h $(SRCDIR)/config.h |
| 713 | $(XTCC) -o $(OBJDIR)/leaf.o -c $(OBJDIR)/leaf_.c |
| @@ -916,5 +1027,9 @@ | |
| 1027 | $(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th_lang.c -o $(OBJDIR)/th_lang.o |
| 1028 | |
| 1029 | $(OBJDIR)/th_tcl.o: $(SRCDIR)/th_tcl.c |
| 1030 | $(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th_tcl.c -o $(OBJDIR)/th_tcl.o |
| 1031 | |
| 1032 | |
| 1033 | $(OBJDIR)/cson_amalgamation.o: $(SRCDIR)/cson_amalgamation.c |
| 1034 | $(XTCC) -I$(SRCDIR) -c $(SRCDIR)/cson_amalgamation.c -o $(OBJDIR)/cson_amalgamation.o -DCSON_FOSSIL_MODE |
| 1035 | |
| 1036 |
+60
-4
| --- src/makemake.tcl | ||
| +++ src/makemake.tcl | ||
| @@ -53,10 +53,21 @@ | ||
| 53 | 53 | http |
| 54 | 54 | http_socket |
| 55 | 55 | http_transport |
| 56 | 56 | import |
| 57 | 57 | info |
| 58 | + json | |
| 59 | + json_artifact | |
| 60 | + json_branch | |
| 61 | + json_diff | |
| 62 | + json_login | |
| 63 | + json_query | |
| 64 | + json_report | |
| 65 | + json_tag | |
| 66 | + json_timeline | |
| 67 | + json_user | |
| 68 | + json_wiki | |
| 58 | 69 | leaf |
| 59 | 70 | login |
| 60 | 71 | main |
| 61 | 72 | manifest |
| 62 | 73 | md5 |
| @@ -207,11 +218,12 @@ | ||
| 207 | 218 | EXTRAOBJ = \ |
| 208 | 219 | $(SQLITE3_OBJ.$(USE_SYSTEM_SQLITE)) \ |
| 209 | 220 | $(OBJDIR)/shell.o \ |
| 210 | 221 | $(OBJDIR)/th.o \ |
| 211 | 222 | $(OBJDIR)/th_lang.o \ |
| 212 | - $(TCL_OBJ.$(FOSSIL_ENABLE_TCL)) | |
| 223 | + $(TCL_OBJ.$(FOSSIL_ENABLE_TCL)) \ | |
| 224 | + $(OBJDIR)/cson_amalgamation.o | |
| 213 | 225 | |
| 214 | 226 | $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) |
| 215 | 227 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) |
| 216 | 228 | |
| 217 | 229 | # This rule prevents make from using its default rules to try build |
| @@ -230,17 +242,19 @@ | ||
| 230 | 242 | append mhargs " \$(OBJDIR)/${s}_.c:\$(OBJDIR)/$s.h" |
| 231 | 243 | set extra_h($s) {} |
| 232 | 244 | } |
| 233 | 245 | append mhargs " \$(SRCDIR)/sqlite3.h" |
| 234 | 246 | append mhargs " \$(SRCDIR)/th.h" |
| 247 | +#append mhargs " \$(SRCDIR)/cson_amalgamation.h" | |
| 235 | 248 | append mhargs " \$(OBJDIR)/VERSION.h" |
| 236 | 249 | writeln "\$(OBJDIR)/page_index.h: \$(TRANS_SRC) \$(OBJDIR)/mkindex" |
| 237 | 250 | writeln "\t\$(OBJDIR)/mkindex \$(TRANS_SRC) >$@" |
| 238 | 251 | writeln "\$(OBJDIR)/headers:\t\$(OBJDIR)/page_index.h \$(OBJDIR)/makeheaders \$(OBJDIR)/VERSION.h" |
| 239 | 252 | writeln "\t\$(OBJDIR)/makeheaders $mhargs" |
| 240 | 253 | writeln "\ttouch \$(OBJDIR)/headers" |
| 241 | 254 | writeln "\$(OBJDIR)/headers: Makefile" |
| 255 | +writeln "\$(OBJDIR)/json.o \$(OBJDIR)/json_artifact.o \$(OBJDIR)/json_branch.o \$(OBJDIR)/json_diff.o \$(OBJDIR)/json_login.o \$(OBJDIR)/json_query.o \$(OBJDIR)/json_report.o \$(OBJDIR)/json_tag.o \$(OBJDIR)/json_timeline.o \$(OBJDIR)/json_user.o \$(OBJDIR)/json_wiki.o : \$(SRCDIR)/json_detail.h" | |
| 242 | 256 | writeln "Makefile:" |
| 243 | 257 | set extra_h(main) \$(OBJDIR)/page_index.h |
| 244 | 258 | |
| 245 | 259 | foreach s [lsort $src] { |
| 246 | 260 | writeln "\$(OBJDIR)/${s}_.c:\t\$(SRCDIR)/$s.c \$(OBJDIR)/translate" |
| @@ -272,10 +286,16 @@ | ||
| 272 | 286 | writeln "\$(OBJDIR)/th_lang.o:\t\$(SRCDIR)/th_lang.c" |
| 273 | 287 | writeln "\t\$(XTCC) -I\$(SRCDIR) -c \$(SRCDIR)/th_lang.c -o \$(OBJDIR)/th_lang.o\n" |
| 274 | 288 | |
| 275 | 289 | writeln "\$(OBJDIR)/th_tcl.o:\t\$(SRCDIR)/th_tcl.c" |
| 276 | 290 | writeln "\t\$(XTCC) -I\$(SRCDIR) -c \$(SRCDIR)/th_tcl.c -o \$(OBJDIR)/th_tcl.o\n" |
| 291 | + | |
| 292 | +set opt {} | |
| 293 | +writeln { | |
| 294 | +$(OBJDIR)/cson_amalgamation.o: $(SRCDIR)/cson_amalgamation.c | |
| 295 | + $(XTCC) -I$(SRCDIR) -c $(SRCDIR)/cson_amalgamation.c -o $(OBJDIR)/cson_amalgamation.o -DCSON_FOSSIL_MODE | |
| 296 | +} | |
| 277 | 297 | |
| 278 | 298 | close $output_file |
| 279 | 299 | # |
| 280 | 300 | # End of the main.mk output |
| 281 | 301 | ############################################################################## |
| @@ -420,11 +440,12 @@ | ||
| 420 | 440 | |
| 421 | 441 | EXTRAOBJ = \ |
| 422 | 442 | $(OBJDIR)/sqlite3.o \ |
| 423 | 443 | $(OBJDIR)/shell.o \ |
| 424 | 444 | $(OBJDIR)/th.o \ |
| 425 | - $(OBJDIR)/th_lang.o | |
| 445 | + $(OBJDIR)/th_lang.o \ | |
| 446 | + $(OBJDIR)/cson_amalgamation.o | |
| 426 | 447 | |
| 427 | 448 | $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) $(OBJDIR)/icon.o |
| 428 | 449 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/icon.o |
| 429 | 450 | |
| 430 | 451 | # This rule prevents make from using its default rules to try build |
| @@ -474,10 +495,15 @@ | ||
| 474 | 495 | |
| 475 | 496 | writeln "\$(OBJDIR)/sqlite3.o:\t\$(SRCDIR)/sqlite3.c" |
| 476 | 497 | set opt $SQLITE_OPTIONS |
| 477 | 498 | writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/sqlite3.c -o \$(OBJDIR)/sqlite3.o\n" |
| 478 | 499 | |
| 500 | +set opt {} | |
| 501 | +writeln "\$(OBJDIR)/cson_amalgamation.o:\t\$(SRCDIR)/cson_amalgamation.c" | |
| 502 | +writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/cson_amalgamation.c -o \$(OBJDIR)/cson_amalgamation.o -DCSON_FOSSIL_MODE\n" | |
| 503 | +writeln "\$(OBJDIR)/json.o \$(OBJDIR)/json_artifact.o \$(OBJDIR)/json_branch.o \$(OBJDIR)/json_diff.o \$(OBJDIR)/json_login.o \$(OBJDIR)/json_query.o \$(OBJDIR)/json_report.o \$(OBJDIR)/json_tag.o \$(OBJDIR)/json_timeline.o \$(OBJDIR)/json_user.o \$(OBJDIR)/json_wiki.o : \$(SRCDIR)/json_detail.h" | |
| 504 | + | |
| 479 | 505 | writeln "\$(OBJDIR)/shell.o:\t\$(SRCDIR)/shell.c \$(SRCDIR)/sqlite3.h" |
| 480 | 506 | set opt {-Dmain=sqlite3_shell} |
| 481 | 507 | append opt " -DSQLITE_OMIT_LOAD_EXTENSION=1" |
| 482 | 508 | writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/shell.c -o \$(OBJDIR)/shell.o\n" |
| 483 | 509 | |
| @@ -585,10 +611,13 @@ | ||
| 585 | 611 | $(OBJDIR)\th$O : $(SRCDIR)\th.c |
| 586 | 612 | $(TCC) -o$@ -c $** |
| 587 | 613 | |
| 588 | 614 | $(OBJDIR)\th_lang$O : $(SRCDIR)\th_lang.c |
| 589 | 615 | $(TCC) -o$@ -c $** |
| 616 | + | |
| 617 | +$(OBJDIR)\cson_amalgamation.h : $(SRCDIR)\cson_amalgamation.h | |
| 618 | + cp $@ $@ | |
| 590 | 619 | |
| 591 | 620 | VERSION.h : version$E $B\manifest.uuid $B\manifest $B\VERSION |
| 592 | 621 | +$** > $@ |
| 593 | 622 | |
| 594 | 623 | page_index.h: mkindex$E $(SRC) |
| @@ -598,10 +627,23 @@ | ||
| 598 | 627 | -del $(OBJDIR)\*.obj |
| 599 | 628 | -del *.obj *_.c *.h *.map |
| 600 | 629 | |
| 601 | 630 | realclean: |
| 602 | 631 | -del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E |
| 632 | + | |
| 633 | +$(OBJDIR)\json$O : $(SRCDIR)\json_detail.h | |
| 634 | +$(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h | |
| 635 | +$(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h | |
| 636 | +$(OBJDIR)\json_diff$O : $(SRCDIR)\json_detail.h | |
| 637 | +$(OBJDIR)\json_login$O : $(SRCDIR)\json_detail.h | |
| 638 | +$(OBJDIR)\json_query$O : $(SRCDIR)\json_detail.h | |
| 639 | +$(OBJDIR)\json_report$O : $(SRCDIR)\json_detail.h | |
| 640 | +$(OBJDIR)\json_tag$O : $(SRCDIR)\json_detail.h | |
| 641 | +$(OBJDIR)\json_timeline$O : $(SRCDIR)\json_detail.h | |
| 642 | +$(OBJDIR)\json_user$O : $(SRCDIR)\json_detail.h | |
| 643 | +$(OBJDIR)\json_wiki$O : $(SRCDIR)\json_detail.h | |
| 644 | + | |
| 603 | 645 | |
| 604 | 646 | } |
| 605 | 647 | foreach s [lsort $src] { |
| 606 | 648 | writeln "\$(OBJDIR)\\$s\$O : ${s}_.c ${s}.h" |
| 607 | 649 | writeln "\t\$(TCC) -o\$@ -c ${s}_.c\n" |
| @@ -611,11 +653,11 @@ | ||
| 611 | 653 | |
| 612 | 654 | writeln -nonewline "headers: makeheaders\$E page_index.h VERSION.h\n\t +makeheaders\$E " |
| 613 | 655 | foreach s [lsort $src] { |
| 614 | 656 | writeln -nonewline "${s}_.c:$s.h " |
| 615 | 657 | } |
| 616 | -writeln "\$(SRCDIR)\\sqlite3.h \$(SRCDIR)\\th.h VERSION.h" | |
| 658 | +writeln "\$(SRCDIR)\\sqlite3.h \$(SRCDIR)\\th.h VERSION.h \$(SRCDIR)\\cson_amalgamation.h" | |
| 617 | 659 | writeln "\t@copy /Y nul: headers" |
| 618 | 660 | |
| 619 | 661 | close $output_file |
| 620 | 662 | # |
| 621 | 663 | # End of the win/Makefile.dmc output |
| @@ -725,10 +767,12 @@ | ||
| 725 | 767 | $(OX)\th_lang$O : $(SRCDIR)\th_lang.c |
| 726 | 768 | $(TCC) /Fo$@ -c $** |
| 727 | 769 | |
| 728 | 770 | VERSION.h : mkversion$E $B\manifest.uuid $B\manifest $B\VERSION |
| 729 | 771 | $** > $@ |
| 772 | +$(OBJDIR)\cson_amalgamation.h : $(SRCDIR)\cson_amalgamation.h | |
| 773 | + cp $(SRCDIR)\cson_amalgamation.h $@ | |
| 730 | 774 | |
| 731 | 775 | page_index.h: mkindex$E $(SRC) |
| 732 | 776 | $** > $@ |
| 733 | 777 | |
| 734 | 778 | clean: |
| @@ -737,10 +781,22 @@ | ||
| 737 | 781 | -del headers linkopts |
| 738 | 782 | |
| 739 | 783 | realclean: |
| 740 | 784 | -del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E |
| 741 | 785 | |
| 786 | +$(OBJDIR)\json$O : $(SRCDIR)\json_detail.h | |
| 787 | +$(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h | |
| 788 | +$(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h | |
| 789 | +$(OBJDIR)\json_diff$O : $(SRCDIR)\json_detail.h | |
| 790 | +$(OBJDIR)\json_login$O : $(SRCDIR)\json_detail.h | |
| 791 | +$(OBJDIR)\json_query$O : $(SRCDIR)\json_detail.h | |
| 792 | +$(OBJDIR)\json_report$O : $(SRCDIR)\json_detail.h | |
| 793 | +$(OBJDIR)\json_tag$O : $(SRCDIR)\json_detail.h | |
| 794 | +$(OBJDIR)\json_timeline$O : $(SRCDIR)\json_detail.h | |
| 795 | +$(OBJDIR)\json_user$O : $(SRCDIR)\json_detail.h | |
| 796 | +$(OBJDIR)\json_wiki$O : $(SRCDIR)\json_detail.h | |
| 797 | + | |
| 742 | 798 | } |
| 743 | 799 | foreach s [lsort $src] { |
| 744 | 800 | writeln "\$(OX)\\$s\$O : ${s}_.c ${s}.h" |
| 745 | 801 | writeln "\t\$(TCC) /Fo\$@ -c ${s}_.c\n" |
| 746 | 802 | writeln "${s}_.c : \$(SRCDIR)\\$s.c" |
| @@ -749,11 +805,11 @@ | ||
| 749 | 805 | |
| 750 | 806 | writeln -nonewline "headers: makeheaders\$E page_index.h VERSION.h\n\tmakeheaders\$E " |
| 751 | 807 | foreach s [lsort $src] { |
| 752 | 808 | writeln -nonewline "${s}_.c:$s.h " |
| 753 | 809 | } |
| 754 | -writeln "\$(SRCDIR)\\sqlite3.h \$(SRCDIR)\\th.h VERSION.h" | |
| 810 | +writeln "\$(SRCDIR)\\sqlite3.h \$(SRCDIR)\\th.h VERSION.h \$(SRCDIR)\\cson_amalgamation.h" | |
| 755 | 811 | writeln "\t@copy /Y nul: headers" |
| 756 | 812 | |
| 757 | 813 | |
| 758 | 814 | close $output_file |
| 759 | 815 | # |
| 760 | 816 |
| --- src/makemake.tcl | |
| +++ src/makemake.tcl | |
| @@ -53,10 +53,21 @@ | |
| 53 | http |
| 54 | http_socket |
| 55 | http_transport |
| 56 | import |
| 57 | info |
| 58 | leaf |
| 59 | login |
| 60 | main |
| 61 | manifest |
| 62 | md5 |
| @@ -207,11 +218,12 @@ | |
| 207 | EXTRAOBJ = \ |
| 208 | $(SQLITE3_OBJ.$(USE_SYSTEM_SQLITE)) \ |
| 209 | $(OBJDIR)/shell.o \ |
| 210 | $(OBJDIR)/th.o \ |
| 211 | $(OBJDIR)/th_lang.o \ |
| 212 | $(TCL_OBJ.$(FOSSIL_ENABLE_TCL)) |
| 213 | |
| 214 | $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) |
| 215 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) |
| 216 | |
| 217 | # This rule prevents make from using its default rules to try build |
| @@ -230,17 +242,19 @@ | |
| 230 | append mhargs " \$(OBJDIR)/${s}_.c:\$(OBJDIR)/$s.h" |
| 231 | set extra_h($s) {} |
| 232 | } |
| 233 | append mhargs " \$(SRCDIR)/sqlite3.h" |
| 234 | append mhargs " \$(SRCDIR)/th.h" |
| 235 | append mhargs " \$(OBJDIR)/VERSION.h" |
| 236 | writeln "\$(OBJDIR)/page_index.h: \$(TRANS_SRC) \$(OBJDIR)/mkindex" |
| 237 | writeln "\t\$(OBJDIR)/mkindex \$(TRANS_SRC) >$@" |
| 238 | writeln "\$(OBJDIR)/headers:\t\$(OBJDIR)/page_index.h \$(OBJDIR)/makeheaders \$(OBJDIR)/VERSION.h" |
| 239 | writeln "\t\$(OBJDIR)/makeheaders $mhargs" |
| 240 | writeln "\ttouch \$(OBJDIR)/headers" |
| 241 | writeln "\$(OBJDIR)/headers: Makefile" |
| 242 | writeln "Makefile:" |
| 243 | set extra_h(main) \$(OBJDIR)/page_index.h |
| 244 | |
| 245 | foreach s [lsort $src] { |
| 246 | writeln "\$(OBJDIR)/${s}_.c:\t\$(SRCDIR)/$s.c \$(OBJDIR)/translate" |
| @@ -272,10 +286,16 @@ | |
| 272 | writeln "\$(OBJDIR)/th_lang.o:\t\$(SRCDIR)/th_lang.c" |
| 273 | writeln "\t\$(XTCC) -I\$(SRCDIR) -c \$(SRCDIR)/th_lang.c -o \$(OBJDIR)/th_lang.o\n" |
| 274 | |
| 275 | writeln "\$(OBJDIR)/th_tcl.o:\t\$(SRCDIR)/th_tcl.c" |
| 276 | writeln "\t\$(XTCC) -I\$(SRCDIR) -c \$(SRCDIR)/th_tcl.c -o \$(OBJDIR)/th_tcl.o\n" |
| 277 | |
| 278 | close $output_file |
| 279 | # |
| 280 | # End of the main.mk output |
| 281 | ############################################################################## |
| @@ -420,11 +440,12 @@ | |
| 420 | |
| 421 | EXTRAOBJ = \ |
| 422 | $(OBJDIR)/sqlite3.o \ |
| 423 | $(OBJDIR)/shell.o \ |
| 424 | $(OBJDIR)/th.o \ |
| 425 | $(OBJDIR)/th_lang.o |
| 426 | |
| 427 | $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) $(OBJDIR)/icon.o |
| 428 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/icon.o |
| 429 | |
| 430 | # This rule prevents make from using its default rules to try build |
| @@ -474,10 +495,15 @@ | |
| 474 | |
| 475 | writeln "\$(OBJDIR)/sqlite3.o:\t\$(SRCDIR)/sqlite3.c" |
| 476 | set opt $SQLITE_OPTIONS |
| 477 | writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/sqlite3.c -o \$(OBJDIR)/sqlite3.o\n" |
| 478 | |
| 479 | writeln "\$(OBJDIR)/shell.o:\t\$(SRCDIR)/shell.c \$(SRCDIR)/sqlite3.h" |
| 480 | set opt {-Dmain=sqlite3_shell} |
| 481 | append opt " -DSQLITE_OMIT_LOAD_EXTENSION=1" |
| 482 | writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/shell.c -o \$(OBJDIR)/shell.o\n" |
| 483 | |
| @@ -585,10 +611,13 @@ | |
| 585 | $(OBJDIR)\th$O : $(SRCDIR)\th.c |
| 586 | $(TCC) -o$@ -c $** |
| 587 | |
| 588 | $(OBJDIR)\th_lang$O : $(SRCDIR)\th_lang.c |
| 589 | $(TCC) -o$@ -c $** |
| 590 | |
| 591 | VERSION.h : version$E $B\manifest.uuid $B\manifest $B\VERSION |
| 592 | +$** > $@ |
| 593 | |
| 594 | page_index.h: mkindex$E $(SRC) |
| @@ -598,10 +627,23 @@ | |
| 598 | -del $(OBJDIR)\*.obj |
| 599 | -del *.obj *_.c *.h *.map |
| 600 | |
| 601 | realclean: |
| 602 | -del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E |
| 603 | |
| 604 | } |
| 605 | foreach s [lsort $src] { |
| 606 | writeln "\$(OBJDIR)\\$s\$O : ${s}_.c ${s}.h" |
| 607 | writeln "\t\$(TCC) -o\$@ -c ${s}_.c\n" |
| @@ -611,11 +653,11 @@ | |
| 611 | |
| 612 | writeln -nonewline "headers: makeheaders\$E page_index.h VERSION.h\n\t +makeheaders\$E " |
| 613 | foreach s [lsort $src] { |
| 614 | writeln -nonewline "${s}_.c:$s.h " |
| 615 | } |
| 616 | writeln "\$(SRCDIR)\\sqlite3.h \$(SRCDIR)\\th.h VERSION.h" |
| 617 | writeln "\t@copy /Y nul: headers" |
| 618 | |
| 619 | close $output_file |
| 620 | # |
| 621 | # End of the win/Makefile.dmc output |
| @@ -725,10 +767,12 @@ | |
| 725 | $(OX)\th_lang$O : $(SRCDIR)\th_lang.c |
| 726 | $(TCC) /Fo$@ -c $** |
| 727 | |
| 728 | VERSION.h : mkversion$E $B\manifest.uuid $B\manifest $B\VERSION |
| 729 | $** > $@ |
| 730 | |
| 731 | page_index.h: mkindex$E $(SRC) |
| 732 | $** > $@ |
| 733 | |
| 734 | clean: |
| @@ -737,10 +781,22 @@ | |
| 737 | -del headers linkopts |
| 738 | |
| 739 | realclean: |
| 740 | -del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E |
| 741 | |
| 742 | } |
| 743 | foreach s [lsort $src] { |
| 744 | writeln "\$(OX)\\$s\$O : ${s}_.c ${s}.h" |
| 745 | writeln "\t\$(TCC) /Fo\$@ -c ${s}_.c\n" |
| 746 | writeln "${s}_.c : \$(SRCDIR)\\$s.c" |
| @@ -749,11 +805,11 @@ | |
| 749 | |
| 750 | writeln -nonewline "headers: makeheaders\$E page_index.h VERSION.h\n\tmakeheaders\$E " |
| 751 | foreach s [lsort $src] { |
| 752 | writeln -nonewline "${s}_.c:$s.h " |
| 753 | } |
| 754 | writeln "\$(SRCDIR)\\sqlite3.h \$(SRCDIR)\\th.h VERSION.h" |
| 755 | writeln "\t@copy /Y nul: headers" |
| 756 | |
| 757 | |
| 758 | close $output_file |
| 759 | # |
| 760 |
| --- src/makemake.tcl | |
| +++ src/makemake.tcl | |
| @@ -53,10 +53,21 @@ | |
| 53 | http |
| 54 | http_socket |
| 55 | http_transport |
| 56 | import |
| 57 | info |
| 58 | json |
| 59 | json_artifact |
| 60 | json_branch |
| 61 | json_diff |
| 62 | json_login |
| 63 | json_query |
| 64 | json_report |
| 65 | json_tag |
| 66 | json_timeline |
| 67 | json_user |
| 68 | json_wiki |
| 69 | leaf |
| 70 | login |
| 71 | main |
| 72 | manifest |
| 73 | md5 |
| @@ -207,11 +218,12 @@ | |
| 218 | EXTRAOBJ = \ |
| 219 | $(SQLITE3_OBJ.$(USE_SYSTEM_SQLITE)) \ |
| 220 | $(OBJDIR)/shell.o \ |
| 221 | $(OBJDIR)/th.o \ |
| 222 | $(OBJDIR)/th_lang.o \ |
| 223 | $(TCL_OBJ.$(FOSSIL_ENABLE_TCL)) \ |
| 224 | $(OBJDIR)/cson_amalgamation.o |
| 225 | |
| 226 | $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) |
| 227 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) |
| 228 | |
| 229 | # This rule prevents make from using its default rules to try build |
| @@ -230,17 +242,19 @@ | |
| 242 | append mhargs " \$(OBJDIR)/${s}_.c:\$(OBJDIR)/$s.h" |
| 243 | set extra_h($s) {} |
| 244 | } |
| 245 | append mhargs " \$(SRCDIR)/sqlite3.h" |
| 246 | append mhargs " \$(SRCDIR)/th.h" |
| 247 | #append mhargs " \$(SRCDIR)/cson_amalgamation.h" |
| 248 | append mhargs " \$(OBJDIR)/VERSION.h" |
| 249 | writeln "\$(OBJDIR)/page_index.h: \$(TRANS_SRC) \$(OBJDIR)/mkindex" |
| 250 | writeln "\t\$(OBJDIR)/mkindex \$(TRANS_SRC) >$@" |
| 251 | writeln "\$(OBJDIR)/headers:\t\$(OBJDIR)/page_index.h \$(OBJDIR)/makeheaders \$(OBJDIR)/VERSION.h" |
| 252 | writeln "\t\$(OBJDIR)/makeheaders $mhargs" |
| 253 | writeln "\ttouch \$(OBJDIR)/headers" |
| 254 | writeln "\$(OBJDIR)/headers: Makefile" |
| 255 | writeln "\$(OBJDIR)/json.o \$(OBJDIR)/json_artifact.o \$(OBJDIR)/json_branch.o \$(OBJDIR)/json_diff.o \$(OBJDIR)/json_login.o \$(OBJDIR)/json_query.o \$(OBJDIR)/json_report.o \$(OBJDIR)/json_tag.o \$(OBJDIR)/json_timeline.o \$(OBJDIR)/json_user.o \$(OBJDIR)/json_wiki.o : \$(SRCDIR)/json_detail.h" |
| 256 | writeln "Makefile:" |
| 257 | set extra_h(main) \$(OBJDIR)/page_index.h |
| 258 | |
| 259 | foreach s [lsort $src] { |
| 260 | writeln "\$(OBJDIR)/${s}_.c:\t\$(SRCDIR)/$s.c \$(OBJDIR)/translate" |
| @@ -272,10 +286,16 @@ | |
| 286 | writeln "\$(OBJDIR)/th_lang.o:\t\$(SRCDIR)/th_lang.c" |
| 287 | writeln "\t\$(XTCC) -I\$(SRCDIR) -c \$(SRCDIR)/th_lang.c -o \$(OBJDIR)/th_lang.o\n" |
| 288 | |
| 289 | writeln "\$(OBJDIR)/th_tcl.o:\t\$(SRCDIR)/th_tcl.c" |
| 290 | writeln "\t\$(XTCC) -I\$(SRCDIR) -c \$(SRCDIR)/th_tcl.c -o \$(OBJDIR)/th_tcl.o\n" |
| 291 | |
| 292 | set opt {} |
| 293 | writeln { |
| 294 | $(OBJDIR)/cson_amalgamation.o: $(SRCDIR)/cson_amalgamation.c |
| 295 | $(XTCC) -I$(SRCDIR) -c $(SRCDIR)/cson_amalgamation.c -o $(OBJDIR)/cson_amalgamation.o -DCSON_FOSSIL_MODE |
| 296 | } |
| 297 | |
| 298 | close $output_file |
| 299 | # |
| 300 | # End of the main.mk output |
| 301 | ############################################################################## |
| @@ -420,11 +440,12 @@ | |
| 440 | |
| 441 | EXTRAOBJ = \ |
| 442 | $(OBJDIR)/sqlite3.o \ |
| 443 | $(OBJDIR)/shell.o \ |
| 444 | $(OBJDIR)/th.o \ |
| 445 | $(OBJDIR)/th_lang.o \ |
| 446 | $(OBJDIR)/cson_amalgamation.o |
| 447 | |
| 448 | $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) $(OBJDIR)/icon.o |
| 449 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/icon.o |
| 450 | |
| 451 | # This rule prevents make from using its default rules to try build |
| @@ -474,10 +495,15 @@ | |
| 495 | |
| 496 | writeln "\$(OBJDIR)/sqlite3.o:\t\$(SRCDIR)/sqlite3.c" |
| 497 | set opt $SQLITE_OPTIONS |
| 498 | writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/sqlite3.c -o \$(OBJDIR)/sqlite3.o\n" |
| 499 | |
| 500 | set opt {} |
| 501 | writeln "\$(OBJDIR)/cson_amalgamation.o:\t\$(SRCDIR)/cson_amalgamation.c" |
| 502 | writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/cson_amalgamation.c -o \$(OBJDIR)/cson_amalgamation.o -DCSON_FOSSIL_MODE\n" |
| 503 | writeln "\$(OBJDIR)/json.o \$(OBJDIR)/json_artifact.o \$(OBJDIR)/json_branch.o \$(OBJDIR)/json_diff.o \$(OBJDIR)/json_login.o \$(OBJDIR)/json_query.o \$(OBJDIR)/json_report.o \$(OBJDIR)/json_tag.o \$(OBJDIR)/json_timeline.o \$(OBJDIR)/json_user.o \$(OBJDIR)/json_wiki.o : \$(SRCDIR)/json_detail.h" |
| 504 | |
| 505 | writeln "\$(OBJDIR)/shell.o:\t\$(SRCDIR)/shell.c \$(SRCDIR)/sqlite3.h" |
| 506 | set opt {-Dmain=sqlite3_shell} |
| 507 | append opt " -DSQLITE_OMIT_LOAD_EXTENSION=1" |
| 508 | writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/shell.c -o \$(OBJDIR)/shell.o\n" |
| 509 | |
| @@ -585,10 +611,13 @@ | |
| 611 | $(OBJDIR)\th$O : $(SRCDIR)\th.c |
| 612 | $(TCC) -o$@ -c $** |
| 613 | |
| 614 | $(OBJDIR)\th_lang$O : $(SRCDIR)\th_lang.c |
| 615 | $(TCC) -o$@ -c $** |
| 616 | |
| 617 | $(OBJDIR)\cson_amalgamation.h : $(SRCDIR)\cson_amalgamation.h |
| 618 | cp $@ $@ |
| 619 | |
| 620 | VERSION.h : version$E $B\manifest.uuid $B\manifest $B\VERSION |
| 621 | +$** > $@ |
| 622 | |
| 623 | page_index.h: mkindex$E $(SRC) |
| @@ -598,10 +627,23 @@ | |
| 627 | -del $(OBJDIR)\*.obj |
| 628 | -del *.obj *_.c *.h *.map |
| 629 | |
| 630 | realclean: |
| 631 | -del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E |
| 632 | |
| 633 | $(OBJDIR)\json$O : $(SRCDIR)\json_detail.h |
| 634 | $(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h |
| 635 | $(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h |
| 636 | $(OBJDIR)\json_diff$O : $(SRCDIR)\json_detail.h |
| 637 | $(OBJDIR)\json_login$O : $(SRCDIR)\json_detail.h |
| 638 | $(OBJDIR)\json_query$O : $(SRCDIR)\json_detail.h |
| 639 | $(OBJDIR)\json_report$O : $(SRCDIR)\json_detail.h |
| 640 | $(OBJDIR)\json_tag$O : $(SRCDIR)\json_detail.h |
| 641 | $(OBJDIR)\json_timeline$O : $(SRCDIR)\json_detail.h |
| 642 | $(OBJDIR)\json_user$O : $(SRCDIR)\json_detail.h |
| 643 | $(OBJDIR)\json_wiki$O : $(SRCDIR)\json_detail.h |
| 644 | |
| 645 | |
| 646 | } |
| 647 | foreach s [lsort $src] { |
| 648 | writeln "\$(OBJDIR)\\$s\$O : ${s}_.c ${s}.h" |
| 649 | writeln "\t\$(TCC) -o\$@ -c ${s}_.c\n" |
| @@ -611,11 +653,11 @@ | |
| 653 | |
| 654 | writeln -nonewline "headers: makeheaders\$E page_index.h VERSION.h\n\t +makeheaders\$E " |
| 655 | foreach s [lsort $src] { |
| 656 | writeln -nonewline "${s}_.c:$s.h " |
| 657 | } |
| 658 | writeln "\$(SRCDIR)\\sqlite3.h \$(SRCDIR)\\th.h VERSION.h \$(SRCDIR)\\cson_amalgamation.h" |
| 659 | writeln "\t@copy /Y nul: headers" |
| 660 | |
| 661 | close $output_file |
| 662 | # |
| 663 | # End of the win/Makefile.dmc output |
| @@ -725,10 +767,12 @@ | |
| 767 | $(OX)\th_lang$O : $(SRCDIR)\th_lang.c |
| 768 | $(TCC) /Fo$@ -c $** |
| 769 | |
| 770 | VERSION.h : mkversion$E $B\manifest.uuid $B\manifest $B\VERSION |
| 771 | $** > $@ |
| 772 | $(OBJDIR)\cson_amalgamation.h : $(SRCDIR)\cson_amalgamation.h |
| 773 | cp $(SRCDIR)\cson_amalgamation.h $@ |
| 774 | |
| 775 | page_index.h: mkindex$E $(SRC) |
| 776 | $** > $@ |
| 777 | |
| 778 | clean: |
| @@ -737,10 +781,22 @@ | |
| 781 | -del headers linkopts |
| 782 | |
| 783 | realclean: |
| 784 | -del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E |
| 785 | |
| 786 | $(OBJDIR)\json$O : $(SRCDIR)\json_detail.h |
| 787 | $(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h |
| 788 | $(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h |
| 789 | $(OBJDIR)\json_diff$O : $(SRCDIR)\json_detail.h |
| 790 | $(OBJDIR)\json_login$O : $(SRCDIR)\json_detail.h |
| 791 | $(OBJDIR)\json_query$O : $(SRCDIR)\json_detail.h |
| 792 | $(OBJDIR)\json_report$O : $(SRCDIR)\json_detail.h |
| 793 | $(OBJDIR)\json_tag$O : $(SRCDIR)\json_detail.h |
| 794 | $(OBJDIR)\json_timeline$O : $(SRCDIR)\json_detail.h |
| 795 | $(OBJDIR)\json_user$O : $(SRCDIR)\json_detail.h |
| 796 | $(OBJDIR)\json_wiki$O : $(SRCDIR)\json_detail.h |
| 797 | |
| 798 | } |
| 799 | foreach s [lsort $src] { |
| 800 | writeln "\$(OX)\\$s\$O : ${s}_.c ${s}.h" |
| 801 | writeln "\t\$(TCC) /Fo\$@ -c ${s}_.c\n" |
| 802 | writeln "${s}_.c : \$(SRCDIR)\\$s.c" |
| @@ -749,11 +805,11 @@ | |
| 805 | |
| 806 | writeln -nonewline "headers: makeheaders\$E page_index.h VERSION.h\n\tmakeheaders\$E " |
| 807 | foreach s [lsort $src] { |
| 808 | writeln -nonewline "${s}_.c:$s.h " |
| 809 | } |
| 810 | writeln "\$(SRCDIR)\\sqlite3.h \$(SRCDIR)\\th.h VERSION.h \$(SRCDIR)\\cson_amalgamation.h" |
| 811 | writeln "\t@copy /Y nul: headers" |
| 812 | |
| 813 | |
| 814 | close $output_file |
| 815 | # |
| 816 |
+60
-4
| --- src/makemake.tcl | ||
| +++ src/makemake.tcl | ||
| @@ -53,10 +53,21 @@ | ||
| 53 | 53 | http |
| 54 | 54 | http_socket |
| 55 | 55 | http_transport |
| 56 | 56 | import |
| 57 | 57 | info |
| 58 | + json | |
| 59 | + json_artifact | |
| 60 | + json_branch | |
| 61 | + json_diff | |
| 62 | + json_login | |
| 63 | + json_query | |
| 64 | + json_report | |
| 65 | + json_tag | |
| 66 | + json_timeline | |
| 67 | + json_user | |
| 68 | + json_wiki | |
| 58 | 69 | leaf |
| 59 | 70 | login |
| 60 | 71 | main |
| 61 | 72 | manifest |
| 62 | 73 | md5 |
| @@ -207,11 +218,12 @@ | ||
| 207 | 218 | EXTRAOBJ = \ |
| 208 | 219 | $(SQLITE3_OBJ.$(USE_SYSTEM_SQLITE)) \ |
| 209 | 220 | $(OBJDIR)/shell.o \ |
| 210 | 221 | $(OBJDIR)/th.o \ |
| 211 | 222 | $(OBJDIR)/th_lang.o \ |
| 212 | - $(TCL_OBJ.$(FOSSIL_ENABLE_TCL)) | |
| 223 | + $(TCL_OBJ.$(FOSSIL_ENABLE_TCL)) \ | |
| 224 | + $(OBJDIR)/cson_amalgamation.o | |
| 213 | 225 | |
| 214 | 226 | $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) |
| 215 | 227 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) |
| 216 | 228 | |
| 217 | 229 | # This rule prevents make from using its default rules to try build |
| @@ -230,17 +242,19 @@ | ||
| 230 | 242 | append mhargs " \$(OBJDIR)/${s}_.c:\$(OBJDIR)/$s.h" |
| 231 | 243 | set extra_h($s) {} |
| 232 | 244 | } |
| 233 | 245 | append mhargs " \$(SRCDIR)/sqlite3.h" |
| 234 | 246 | append mhargs " \$(SRCDIR)/th.h" |
| 247 | +#append mhargs " \$(SRCDIR)/cson_amalgamation.h" | |
| 235 | 248 | append mhargs " \$(OBJDIR)/VERSION.h" |
| 236 | 249 | writeln "\$(OBJDIR)/page_index.h: \$(TRANS_SRC) \$(OBJDIR)/mkindex" |
| 237 | 250 | writeln "\t\$(OBJDIR)/mkindex \$(TRANS_SRC) >$@" |
| 238 | 251 | writeln "\$(OBJDIR)/headers:\t\$(OBJDIR)/page_index.h \$(OBJDIR)/makeheaders \$(OBJDIR)/VERSION.h" |
| 239 | 252 | writeln "\t\$(OBJDIR)/makeheaders $mhargs" |
| 240 | 253 | writeln "\ttouch \$(OBJDIR)/headers" |
| 241 | 254 | writeln "\$(OBJDIR)/headers: Makefile" |
| 255 | +writeln "\$(OBJDIR)/json.o \$(OBJDIR)/json_artifact.o \$(OBJDIR)/json_branch.o \$(OBJDIR)/json_diff.o \$(OBJDIR)/json_login.o \$(OBJDIR)/json_query.o \$(OBJDIR)/json_report.o \$(OBJDIR)/json_tag.o \$(OBJDIR)/json_timeline.o \$(OBJDIR)/json_user.o \$(OBJDIR)/json_wiki.o : \$(SRCDIR)/json_detail.h" | |
| 242 | 256 | writeln "Makefile:" |
| 243 | 257 | set extra_h(main) \$(OBJDIR)/page_index.h |
| 244 | 258 | |
| 245 | 259 | foreach s [lsort $src] { |
| 246 | 260 | writeln "\$(OBJDIR)/${s}_.c:\t\$(SRCDIR)/$s.c \$(OBJDIR)/translate" |
| @@ -272,10 +286,16 @@ | ||
| 272 | 286 | writeln "\$(OBJDIR)/th_lang.o:\t\$(SRCDIR)/th_lang.c" |
| 273 | 287 | writeln "\t\$(XTCC) -I\$(SRCDIR) -c \$(SRCDIR)/th_lang.c -o \$(OBJDIR)/th_lang.o\n" |
| 274 | 288 | |
| 275 | 289 | writeln "\$(OBJDIR)/th_tcl.o:\t\$(SRCDIR)/th_tcl.c" |
| 276 | 290 | writeln "\t\$(XTCC) -I\$(SRCDIR) -c \$(SRCDIR)/th_tcl.c -o \$(OBJDIR)/th_tcl.o\n" |
| 291 | + | |
| 292 | +set opt {} | |
| 293 | +writeln { | |
| 294 | +$(OBJDIR)/cson_amalgamation.o: $(SRCDIR)/cson_amalgamation.c | |
| 295 | + $(XTCC) -I$(SRCDIR) -c $(SRCDIR)/cson_amalgamation.c -o $(OBJDIR)/cson_amalgamation.o -DCSON_FOSSIL_MODE | |
| 296 | +} | |
| 277 | 297 | |
| 278 | 298 | close $output_file |
| 279 | 299 | # |
| 280 | 300 | # End of the main.mk output |
| 281 | 301 | ############################################################################## |
| @@ -420,11 +440,12 @@ | ||
| 420 | 440 | |
| 421 | 441 | EXTRAOBJ = \ |
| 422 | 442 | $(OBJDIR)/sqlite3.o \ |
| 423 | 443 | $(OBJDIR)/shell.o \ |
| 424 | 444 | $(OBJDIR)/th.o \ |
| 425 | - $(OBJDIR)/th_lang.o | |
| 445 | + $(OBJDIR)/th_lang.o \ | |
| 446 | + $(OBJDIR)/cson_amalgamation.o | |
| 426 | 447 | |
| 427 | 448 | $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) $(OBJDIR)/icon.o |
| 428 | 449 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/icon.o |
| 429 | 450 | |
| 430 | 451 | # This rule prevents make from using its default rules to try build |
| @@ -474,10 +495,15 @@ | ||
| 474 | 495 | |
| 475 | 496 | writeln "\$(OBJDIR)/sqlite3.o:\t\$(SRCDIR)/sqlite3.c" |
| 476 | 497 | set opt $SQLITE_OPTIONS |
| 477 | 498 | writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/sqlite3.c -o \$(OBJDIR)/sqlite3.o\n" |
| 478 | 499 | |
| 500 | +set opt {} | |
| 501 | +writeln "\$(OBJDIR)/cson_amalgamation.o:\t\$(SRCDIR)/cson_amalgamation.c" | |
| 502 | +writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/cson_amalgamation.c -o \$(OBJDIR)/cson_amalgamation.o -DCSON_FOSSIL_MODE\n" | |
| 503 | +writeln "\$(OBJDIR)/json.o \$(OBJDIR)/json_artifact.o \$(OBJDIR)/json_branch.o \$(OBJDIR)/json_diff.o \$(OBJDIR)/json_login.o \$(OBJDIR)/json_query.o \$(OBJDIR)/json_report.o \$(OBJDIR)/json_tag.o \$(OBJDIR)/json_timeline.o \$(OBJDIR)/json_user.o \$(OBJDIR)/json_wiki.o : \$(SRCDIR)/json_detail.h" | |
| 504 | + | |
| 479 | 505 | writeln "\$(OBJDIR)/shell.o:\t\$(SRCDIR)/shell.c \$(SRCDIR)/sqlite3.h" |
| 480 | 506 | set opt {-Dmain=sqlite3_shell} |
| 481 | 507 | append opt " -DSQLITE_OMIT_LOAD_EXTENSION=1" |
| 482 | 508 | writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/shell.c -o \$(OBJDIR)/shell.o\n" |
| 483 | 509 | |
| @@ -585,10 +611,13 @@ | ||
| 585 | 611 | $(OBJDIR)\th$O : $(SRCDIR)\th.c |
| 586 | 612 | $(TCC) -o$@ -c $** |
| 587 | 613 | |
| 588 | 614 | $(OBJDIR)\th_lang$O : $(SRCDIR)\th_lang.c |
| 589 | 615 | $(TCC) -o$@ -c $** |
| 616 | + | |
| 617 | +$(OBJDIR)\cson_amalgamation.h : $(SRCDIR)\cson_amalgamation.h | |
| 618 | + cp $@ $@ | |
| 590 | 619 | |
| 591 | 620 | VERSION.h : version$E $B\manifest.uuid $B\manifest $B\VERSION |
| 592 | 621 | +$** > $@ |
| 593 | 622 | |
| 594 | 623 | page_index.h: mkindex$E $(SRC) |
| @@ -598,10 +627,23 @@ | ||
| 598 | 627 | -del $(OBJDIR)\*.obj |
| 599 | 628 | -del *.obj *_.c *.h *.map |
| 600 | 629 | |
| 601 | 630 | realclean: |
| 602 | 631 | -del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E |
| 632 | + | |
| 633 | +$(OBJDIR)\json$O : $(SRCDIR)\json_detail.h | |
| 634 | +$(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h | |
| 635 | +$(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h | |
| 636 | +$(OBJDIR)\json_diff$O : $(SRCDIR)\json_detail.h | |
| 637 | +$(OBJDIR)\json_login$O : $(SRCDIR)\json_detail.h | |
| 638 | +$(OBJDIR)\json_query$O : $(SRCDIR)\json_detail.h | |
| 639 | +$(OBJDIR)\json_report$O : $(SRCDIR)\json_detail.h | |
| 640 | +$(OBJDIR)\json_tag$O : $(SRCDIR)\json_detail.h | |
| 641 | +$(OBJDIR)\json_timeline$O : $(SRCDIR)\json_detail.h | |
| 642 | +$(OBJDIR)\json_user$O : $(SRCDIR)\json_detail.h | |
| 643 | +$(OBJDIR)\json_wiki$O : $(SRCDIR)\json_detail.h | |
| 644 | + | |
| 603 | 645 | |
| 604 | 646 | } |
| 605 | 647 | foreach s [lsort $src] { |
| 606 | 648 | writeln "\$(OBJDIR)\\$s\$O : ${s}_.c ${s}.h" |
| 607 | 649 | writeln "\t\$(TCC) -o\$@ -c ${s}_.c\n" |
| @@ -611,11 +653,11 @@ | ||
| 611 | 653 | |
| 612 | 654 | writeln -nonewline "headers: makeheaders\$E page_index.h VERSION.h\n\t +makeheaders\$E " |
| 613 | 655 | foreach s [lsort $src] { |
| 614 | 656 | writeln -nonewline "${s}_.c:$s.h " |
| 615 | 657 | } |
| 616 | -writeln "\$(SRCDIR)\\sqlite3.h \$(SRCDIR)\\th.h VERSION.h" | |
| 658 | +writeln "\$(SRCDIR)\\sqlite3.h \$(SRCDIR)\\th.h VERSION.h \$(SRCDIR)\\cson_amalgamation.h" | |
| 617 | 659 | writeln "\t@copy /Y nul: headers" |
| 618 | 660 | |
| 619 | 661 | close $output_file |
| 620 | 662 | # |
| 621 | 663 | # End of the win/Makefile.dmc output |
| @@ -725,10 +767,12 @@ | ||
| 725 | 767 | $(OX)\th_lang$O : $(SRCDIR)\th_lang.c |
| 726 | 768 | $(TCC) /Fo$@ -c $** |
| 727 | 769 | |
| 728 | 770 | VERSION.h : mkversion$E $B\manifest.uuid $B\manifest $B\VERSION |
| 729 | 771 | $** > $@ |
| 772 | +$(OBJDIR)\cson_amalgamation.h : $(SRCDIR)\cson_amalgamation.h | |
| 773 | + cp $(SRCDIR)\cson_amalgamation.h $@ | |
| 730 | 774 | |
| 731 | 775 | page_index.h: mkindex$E $(SRC) |
| 732 | 776 | $** > $@ |
| 733 | 777 | |
| 734 | 778 | clean: |
| @@ -737,10 +781,22 @@ | ||
| 737 | 781 | -del headers linkopts |
| 738 | 782 | |
| 739 | 783 | realclean: |
| 740 | 784 | -del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E |
| 741 | 785 | |
| 786 | +$(OBJDIR)\json$O : $(SRCDIR)\json_detail.h | |
| 787 | +$(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h | |
| 788 | +$(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h | |
| 789 | +$(OBJDIR)\json_diff$O : $(SRCDIR)\json_detail.h | |
| 790 | +$(OBJDIR)\json_login$O : $(SRCDIR)\json_detail.h | |
| 791 | +$(OBJDIR)\json_query$O : $(SRCDIR)\json_detail.h | |
| 792 | +$(OBJDIR)\json_report$O : $(SRCDIR)\json_detail.h | |
| 793 | +$(OBJDIR)\json_tag$O : $(SRCDIR)\json_detail.h | |
| 794 | +$(OBJDIR)\json_timeline$O : $(SRCDIR)\json_detail.h | |
| 795 | +$(OBJDIR)\json_user$O : $(SRCDIR)\json_detail.h | |
| 796 | +$(OBJDIR)\json_wiki$O : $(SRCDIR)\json_detail.h | |
| 797 | + | |
| 742 | 798 | } |
| 743 | 799 | foreach s [lsort $src] { |
| 744 | 800 | writeln "\$(OX)\\$s\$O : ${s}_.c ${s}.h" |
| 745 | 801 | writeln "\t\$(TCC) /Fo\$@ -c ${s}_.c\n" |
| 746 | 802 | writeln "${s}_.c : \$(SRCDIR)\\$s.c" |
| @@ -749,11 +805,11 @@ | ||
| 749 | 805 | |
| 750 | 806 | writeln -nonewline "headers: makeheaders\$E page_index.h VERSION.h\n\tmakeheaders\$E " |
| 751 | 807 | foreach s [lsort $src] { |
| 752 | 808 | writeln -nonewline "${s}_.c:$s.h " |
| 753 | 809 | } |
| 754 | -writeln "\$(SRCDIR)\\sqlite3.h \$(SRCDIR)\\th.h VERSION.h" | |
| 810 | +writeln "\$(SRCDIR)\\sqlite3.h \$(SRCDIR)\\th.h VERSION.h \$(SRCDIR)\\cson_amalgamation.h" | |
| 755 | 811 | writeln "\t@copy /Y nul: headers" |
| 756 | 812 | |
| 757 | 813 | |
| 758 | 814 | close $output_file |
| 759 | 815 | # |
| 760 | 816 |
| --- src/makemake.tcl | |
| +++ src/makemake.tcl | |
| @@ -53,10 +53,21 @@ | |
| 53 | http |
| 54 | http_socket |
| 55 | http_transport |
| 56 | import |
| 57 | info |
| 58 | leaf |
| 59 | login |
| 60 | main |
| 61 | manifest |
| 62 | md5 |
| @@ -207,11 +218,12 @@ | |
| 207 | EXTRAOBJ = \ |
| 208 | $(SQLITE3_OBJ.$(USE_SYSTEM_SQLITE)) \ |
| 209 | $(OBJDIR)/shell.o \ |
| 210 | $(OBJDIR)/th.o \ |
| 211 | $(OBJDIR)/th_lang.o \ |
| 212 | $(TCL_OBJ.$(FOSSIL_ENABLE_TCL)) |
| 213 | |
| 214 | $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) |
| 215 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) |
| 216 | |
| 217 | # This rule prevents make from using its default rules to try build |
| @@ -230,17 +242,19 @@ | |
| 230 | append mhargs " \$(OBJDIR)/${s}_.c:\$(OBJDIR)/$s.h" |
| 231 | set extra_h($s) {} |
| 232 | } |
| 233 | append mhargs " \$(SRCDIR)/sqlite3.h" |
| 234 | append mhargs " \$(SRCDIR)/th.h" |
| 235 | append mhargs " \$(OBJDIR)/VERSION.h" |
| 236 | writeln "\$(OBJDIR)/page_index.h: \$(TRANS_SRC) \$(OBJDIR)/mkindex" |
| 237 | writeln "\t\$(OBJDIR)/mkindex \$(TRANS_SRC) >$@" |
| 238 | writeln "\$(OBJDIR)/headers:\t\$(OBJDIR)/page_index.h \$(OBJDIR)/makeheaders \$(OBJDIR)/VERSION.h" |
| 239 | writeln "\t\$(OBJDIR)/makeheaders $mhargs" |
| 240 | writeln "\ttouch \$(OBJDIR)/headers" |
| 241 | writeln "\$(OBJDIR)/headers: Makefile" |
| 242 | writeln "Makefile:" |
| 243 | set extra_h(main) \$(OBJDIR)/page_index.h |
| 244 | |
| 245 | foreach s [lsort $src] { |
| 246 | writeln "\$(OBJDIR)/${s}_.c:\t\$(SRCDIR)/$s.c \$(OBJDIR)/translate" |
| @@ -272,10 +286,16 @@ | |
| 272 | writeln "\$(OBJDIR)/th_lang.o:\t\$(SRCDIR)/th_lang.c" |
| 273 | writeln "\t\$(XTCC) -I\$(SRCDIR) -c \$(SRCDIR)/th_lang.c -o \$(OBJDIR)/th_lang.o\n" |
| 274 | |
| 275 | writeln "\$(OBJDIR)/th_tcl.o:\t\$(SRCDIR)/th_tcl.c" |
| 276 | writeln "\t\$(XTCC) -I\$(SRCDIR) -c \$(SRCDIR)/th_tcl.c -o \$(OBJDIR)/th_tcl.o\n" |
| 277 | |
| 278 | close $output_file |
| 279 | # |
| 280 | # End of the main.mk output |
| 281 | ############################################################################## |
| @@ -420,11 +440,12 @@ | |
| 420 | |
| 421 | EXTRAOBJ = \ |
| 422 | $(OBJDIR)/sqlite3.o \ |
| 423 | $(OBJDIR)/shell.o \ |
| 424 | $(OBJDIR)/th.o \ |
| 425 | $(OBJDIR)/th_lang.o |
| 426 | |
| 427 | $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) $(OBJDIR)/icon.o |
| 428 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/icon.o |
| 429 | |
| 430 | # This rule prevents make from using its default rules to try build |
| @@ -474,10 +495,15 @@ | |
| 474 | |
| 475 | writeln "\$(OBJDIR)/sqlite3.o:\t\$(SRCDIR)/sqlite3.c" |
| 476 | set opt $SQLITE_OPTIONS |
| 477 | writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/sqlite3.c -o \$(OBJDIR)/sqlite3.o\n" |
| 478 | |
| 479 | writeln "\$(OBJDIR)/shell.o:\t\$(SRCDIR)/shell.c \$(SRCDIR)/sqlite3.h" |
| 480 | set opt {-Dmain=sqlite3_shell} |
| 481 | append opt " -DSQLITE_OMIT_LOAD_EXTENSION=1" |
| 482 | writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/shell.c -o \$(OBJDIR)/shell.o\n" |
| 483 | |
| @@ -585,10 +611,13 @@ | |
| 585 | $(OBJDIR)\th$O : $(SRCDIR)\th.c |
| 586 | $(TCC) -o$@ -c $** |
| 587 | |
| 588 | $(OBJDIR)\th_lang$O : $(SRCDIR)\th_lang.c |
| 589 | $(TCC) -o$@ -c $** |
| 590 | |
| 591 | VERSION.h : version$E $B\manifest.uuid $B\manifest $B\VERSION |
| 592 | +$** > $@ |
| 593 | |
| 594 | page_index.h: mkindex$E $(SRC) |
| @@ -598,10 +627,23 @@ | |
| 598 | -del $(OBJDIR)\*.obj |
| 599 | -del *.obj *_.c *.h *.map |
| 600 | |
| 601 | realclean: |
| 602 | -del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E |
| 603 | |
| 604 | } |
| 605 | foreach s [lsort $src] { |
| 606 | writeln "\$(OBJDIR)\\$s\$O : ${s}_.c ${s}.h" |
| 607 | writeln "\t\$(TCC) -o\$@ -c ${s}_.c\n" |
| @@ -611,11 +653,11 @@ | |
| 611 | |
| 612 | writeln -nonewline "headers: makeheaders\$E page_index.h VERSION.h\n\t +makeheaders\$E " |
| 613 | foreach s [lsort $src] { |
| 614 | writeln -nonewline "${s}_.c:$s.h " |
| 615 | } |
| 616 | writeln "\$(SRCDIR)\\sqlite3.h \$(SRCDIR)\\th.h VERSION.h" |
| 617 | writeln "\t@copy /Y nul: headers" |
| 618 | |
| 619 | close $output_file |
| 620 | # |
| 621 | # End of the win/Makefile.dmc output |
| @@ -725,10 +767,12 @@ | |
| 725 | $(OX)\th_lang$O : $(SRCDIR)\th_lang.c |
| 726 | $(TCC) /Fo$@ -c $** |
| 727 | |
| 728 | VERSION.h : mkversion$E $B\manifest.uuid $B\manifest $B\VERSION |
| 729 | $** > $@ |
| 730 | |
| 731 | page_index.h: mkindex$E $(SRC) |
| 732 | $** > $@ |
| 733 | |
| 734 | clean: |
| @@ -737,10 +781,22 @@ | |
| 737 | -del headers linkopts |
| 738 | |
| 739 | realclean: |
| 740 | -del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E |
| 741 | |
| 742 | } |
| 743 | foreach s [lsort $src] { |
| 744 | writeln "\$(OX)\\$s\$O : ${s}_.c ${s}.h" |
| 745 | writeln "\t\$(TCC) /Fo\$@ -c ${s}_.c\n" |
| 746 | writeln "${s}_.c : \$(SRCDIR)\\$s.c" |
| @@ -749,11 +805,11 @@ | |
| 749 | |
| 750 | writeln -nonewline "headers: makeheaders\$E page_index.h VERSION.h\n\tmakeheaders\$E " |
| 751 | foreach s [lsort $src] { |
| 752 | writeln -nonewline "${s}_.c:$s.h " |
| 753 | } |
| 754 | writeln "\$(SRCDIR)\\sqlite3.h \$(SRCDIR)\\th.h VERSION.h" |
| 755 | writeln "\t@copy /Y nul: headers" |
| 756 | |
| 757 | |
| 758 | close $output_file |
| 759 | # |
| 760 |
| --- src/makemake.tcl | |
| +++ src/makemake.tcl | |
| @@ -53,10 +53,21 @@ | |
| 53 | http |
| 54 | http_socket |
| 55 | http_transport |
| 56 | import |
| 57 | info |
| 58 | json |
| 59 | json_artifact |
| 60 | json_branch |
| 61 | json_diff |
| 62 | json_login |
| 63 | json_query |
| 64 | json_report |
| 65 | json_tag |
| 66 | json_timeline |
| 67 | json_user |
| 68 | json_wiki |
| 69 | leaf |
| 70 | login |
| 71 | main |
| 72 | manifest |
| 73 | md5 |
| @@ -207,11 +218,12 @@ | |
| 218 | EXTRAOBJ = \ |
| 219 | $(SQLITE3_OBJ.$(USE_SYSTEM_SQLITE)) \ |
| 220 | $(OBJDIR)/shell.o \ |
| 221 | $(OBJDIR)/th.o \ |
| 222 | $(OBJDIR)/th_lang.o \ |
| 223 | $(TCL_OBJ.$(FOSSIL_ENABLE_TCL)) \ |
| 224 | $(OBJDIR)/cson_amalgamation.o |
| 225 | |
| 226 | $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) |
| 227 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) |
| 228 | |
| 229 | # This rule prevents make from using its default rules to try build |
| @@ -230,17 +242,19 @@ | |
| 242 | append mhargs " \$(OBJDIR)/${s}_.c:\$(OBJDIR)/$s.h" |
| 243 | set extra_h($s) {} |
| 244 | } |
| 245 | append mhargs " \$(SRCDIR)/sqlite3.h" |
| 246 | append mhargs " \$(SRCDIR)/th.h" |
| 247 | #append mhargs " \$(SRCDIR)/cson_amalgamation.h" |
| 248 | append mhargs " \$(OBJDIR)/VERSION.h" |
| 249 | writeln "\$(OBJDIR)/page_index.h: \$(TRANS_SRC) \$(OBJDIR)/mkindex" |
| 250 | writeln "\t\$(OBJDIR)/mkindex \$(TRANS_SRC) >$@" |
| 251 | writeln "\$(OBJDIR)/headers:\t\$(OBJDIR)/page_index.h \$(OBJDIR)/makeheaders \$(OBJDIR)/VERSION.h" |
| 252 | writeln "\t\$(OBJDIR)/makeheaders $mhargs" |
| 253 | writeln "\ttouch \$(OBJDIR)/headers" |
| 254 | writeln "\$(OBJDIR)/headers: Makefile" |
| 255 | writeln "\$(OBJDIR)/json.o \$(OBJDIR)/json_artifact.o \$(OBJDIR)/json_branch.o \$(OBJDIR)/json_diff.o \$(OBJDIR)/json_login.o \$(OBJDIR)/json_query.o \$(OBJDIR)/json_report.o \$(OBJDIR)/json_tag.o \$(OBJDIR)/json_timeline.o \$(OBJDIR)/json_user.o \$(OBJDIR)/json_wiki.o : \$(SRCDIR)/json_detail.h" |
| 256 | writeln "Makefile:" |
| 257 | set extra_h(main) \$(OBJDIR)/page_index.h |
| 258 | |
| 259 | foreach s [lsort $src] { |
| 260 | writeln "\$(OBJDIR)/${s}_.c:\t\$(SRCDIR)/$s.c \$(OBJDIR)/translate" |
| @@ -272,10 +286,16 @@ | |
| 286 | writeln "\$(OBJDIR)/th_lang.o:\t\$(SRCDIR)/th_lang.c" |
| 287 | writeln "\t\$(XTCC) -I\$(SRCDIR) -c \$(SRCDIR)/th_lang.c -o \$(OBJDIR)/th_lang.o\n" |
| 288 | |
| 289 | writeln "\$(OBJDIR)/th_tcl.o:\t\$(SRCDIR)/th_tcl.c" |
| 290 | writeln "\t\$(XTCC) -I\$(SRCDIR) -c \$(SRCDIR)/th_tcl.c -o \$(OBJDIR)/th_tcl.o\n" |
| 291 | |
| 292 | set opt {} |
| 293 | writeln { |
| 294 | $(OBJDIR)/cson_amalgamation.o: $(SRCDIR)/cson_amalgamation.c |
| 295 | $(XTCC) -I$(SRCDIR) -c $(SRCDIR)/cson_amalgamation.c -o $(OBJDIR)/cson_amalgamation.o -DCSON_FOSSIL_MODE |
| 296 | } |
| 297 | |
| 298 | close $output_file |
| 299 | # |
| 300 | # End of the main.mk output |
| 301 | ############################################################################## |
| @@ -420,11 +440,12 @@ | |
| 440 | |
| 441 | EXTRAOBJ = \ |
| 442 | $(OBJDIR)/sqlite3.o \ |
| 443 | $(OBJDIR)/shell.o \ |
| 444 | $(OBJDIR)/th.o \ |
| 445 | $(OBJDIR)/th_lang.o \ |
| 446 | $(OBJDIR)/cson_amalgamation.o |
| 447 | |
| 448 | $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) $(OBJDIR)/icon.o |
| 449 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/icon.o |
| 450 | |
| 451 | # This rule prevents make from using its default rules to try build |
| @@ -474,10 +495,15 @@ | |
| 495 | |
| 496 | writeln "\$(OBJDIR)/sqlite3.o:\t\$(SRCDIR)/sqlite3.c" |
| 497 | set opt $SQLITE_OPTIONS |
| 498 | writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/sqlite3.c -o \$(OBJDIR)/sqlite3.o\n" |
| 499 | |
| 500 | set opt {} |
| 501 | writeln "\$(OBJDIR)/cson_amalgamation.o:\t\$(SRCDIR)/cson_amalgamation.c" |
| 502 | writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/cson_amalgamation.c -o \$(OBJDIR)/cson_amalgamation.o -DCSON_FOSSIL_MODE\n" |
| 503 | writeln "\$(OBJDIR)/json.o \$(OBJDIR)/json_artifact.o \$(OBJDIR)/json_branch.o \$(OBJDIR)/json_diff.o \$(OBJDIR)/json_login.o \$(OBJDIR)/json_query.o \$(OBJDIR)/json_report.o \$(OBJDIR)/json_tag.o \$(OBJDIR)/json_timeline.o \$(OBJDIR)/json_user.o \$(OBJDIR)/json_wiki.o : \$(SRCDIR)/json_detail.h" |
| 504 | |
| 505 | writeln "\$(OBJDIR)/shell.o:\t\$(SRCDIR)/shell.c \$(SRCDIR)/sqlite3.h" |
| 506 | set opt {-Dmain=sqlite3_shell} |
| 507 | append opt " -DSQLITE_OMIT_LOAD_EXTENSION=1" |
| 508 | writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/shell.c -o \$(OBJDIR)/shell.o\n" |
| 509 | |
| @@ -585,10 +611,13 @@ | |
| 611 | $(OBJDIR)\th$O : $(SRCDIR)\th.c |
| 612 | $(TCC) -o$@ -c $** |
| 613 | |
| 614 | $(OBJDIR)\th_lang$O : $(SRCDIR)\th_lang.c |
| 615 | $(TCC) -o$@ -c $** |
| 616 | |
| 617 | $(OBJDIR)\cson_amalgamation.h : $(SRCDIR)\cson_amalgamation.h |
| 618 | cp $@ $@ |
| 619 | |
| 620 | VERSION.h : version$E $B\manifest.uuid $B\manifest $B\VERSION |
| 621 | +$** > $@ |
| 622 | |
| 623 | page_index.h: mkindex$E $(SRC) |
| @@ -598,10 +627,23 @@ | |
| 627 | -del $(OBJDIR)\*.obj |
| 628 | -del *.obj *_.c *.h *.map |
| 629 | |
| 630 | realclean: |
| 631 | -del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E |
| 632 | |
| 633 | $(OBJDIR)\json$O : $(SRCDIR)\json_detail.h |
| 634 | $(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h |
| 635 | $(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h |
| 636 | $(OBJDIR)\json_diff$O : $(SRCDIR)\json_detail.h |
| 637 | $(OBJDIR)\json_login$O : $(SRCDIR)\json_detail.h |
| 638 | $(OBJDIR)\json_query$O : $(SRCDIR)\json_detail.h |
| 639 | $(OBJDIR)\json_report$O : $(SRCDIR)\json_detail.h |
| 640 | $(OBJDIR)\json_tag$O : $(SRCDIR)\json_detail.h |
| 641 | $(OBJDIR)\json_timeline$O : $(SRCDIR)\json_detail.h |
| 642 | $(OBJDIR)\json_user$O : $(SRCDIR)\json_detail.h |
| 643 | $(OBJDIR)\json_wiki$O : $(SRCDIR)\json_detail.h |
| 644 | |
| 645 | |
| 646 | } |
| 647 | foreach s [lsort $src] { |
| 648 | writeln "\$(OBJDIR)\\$s\$O : ${s}_.c ${s}.h" |
| 649 | writeln "\t\$(TCC) -o\$@ -c ${s}_.c\n" |
| @@ -611,11 +653,11 @@ | |
| 653 | |
| 654 | writeln -nonewline "headers: makeheaders\$E page_index.h VERSION.h\n\t +makeheaders\$E " |
| 655 | foreach s [lsort $src] { |
| 656 | writeln -nonewline "${s}_.c:$s.h " |
| 657 | } |
| 658 | writeln "\$(SRCDIR)\\sqlite3.h \$(SRCDIR)\\th.h VERSION.h \$(SRCDIR)\\cson_amalgamation.h" |
| 659 | writeln "\t@copy /Y nul: headers" |
| 660 | |
| 661 | close $output_file |
| 662 | # |
| 663 | # End of the win/Makefile.dmc output |
| @@ -725,10 +767,12 @@ | |
| 767 | $(OX)\th_lang$O : $(SRCDIR)\th_lang.c |
| 768 | $(TCC) /Fo$@ -c $** |
| 769 | |
| 770 | VERSION.h : mkversion$E $B\manifest.uuid $B\manifest $B\VERSION |
| 771 | $** > $@ |
| 772 | $(OBJDIR)\cson_amalgamation.h : $(SRCDIR)\cson_amalgamation.h |
| 773 | cp $(SRCDIR)\cson_amalgamation.h $@ |
| 774 | |
| 775 | page_index.h: mkindex$E $(SRC) |
| 776 | $** > $@ |
| 777 | |
| 778 | clean: |
| @@ -737,10 +781,22 @@ | |
| 781 | -del headers linkopts |
| 782 | |
| 783 | realclean: |
| 784 | -del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E |
| 785 | |
| 786 | $(OBJDIR)\json$O : $(SRCDIR)\json_detail.h |
| 787 | $(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h |
| 788 | $(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h |
| 789 | $(OBJDIR)\json_diff$O : $(SRCDIR)\json_detail.h |
| 790 | $(OBJDIR)\json_login$O : $(SRCDIR)\json_detail.h |
| 791 | $(OBJDIR)\json_query$O : $(SRCDIR)\json_detail.h |
| 792 | $(OBJDIR)\json_report$O : $(SRCDIR)\json_detail.h |
| 793 | $(OBJDIR)\json_tag$O : $(SRCDIR)\json_detail.h |
| 794 | $(OBJDIR)\json_timeline$O : $(SRCDIR)\json_detail.h |
| 795 | $(OBJDIR)\json_user$O : $(SRCDIR)\json_detail.h |
| 796 | $(OBJDIR)\json_wiki$O : $(SRCDIR)\json_detail.h |
| 797 | |
| 798 | } |
| 799 | foreach s [lsort $src] { |
| 800 | writeln "\$(OX)\\$s\$O : ${s}_.c ${s}.h" |
| 801 | writeln "\t\$(TCC) /Fo\$@ -c ${s}_.c\n" |
| 802 | writeln "${s}_.c : \$(SRCDIR)\\$s.c" |
| @@ -749,11 +805,11 @@ | |
| 805 | |
| 806 | writeln -nonewline "headers: makeheaders\$E page_index.h VERSION.h\n\tmakeheaders\$E " |
| 807 | foreach s [lsort $src] { |
| 808 | writeln -nonewline "${s}_.c:$s.h " |
| 809 | } |
| 810 | writeln "\$(SRCDIR)\\sqlite3.h \$(SRCDIR)\\th.h VERSION.h \$(SRCDIR)\\cson_amalgamation.h" |
| 811 | writeln "\t@copy /Y nul: headers" |
| 812 | |
| 813 | |
| 814 | close $output_file |
| 815 | # |
| 816 |
+5
-1
| --- src/name.c | ||
| +++ src/name.c | ||
| @@ -366,11 +366,15 @@ | ||
| 366 | 366 | ** shows all possibilities and do not return. |
| 367 | 367 | */ |
| 368 | 368 | int name_to_rid_www(const char *zParamName){ |
| 369 | 369 | int rid; |
| 370 | 370 | const char *zName = P(zParamName); |
| 371 | - | |
| 371 | +#ifdef FOSSIL_ENABLE_JSON | |
| 372 | + if(!zName && fossil_has_json()){ | |
| 373 | + zName = json_find_option_cstr(zParamName,NULL,NULL); | |
| 374 | + } | |
| 375 | +#endif | |
| 372 | 376 | if( zName==0 || zName[0]==0 ) return 0; |
| 373 | 377 | rid = symbolic_name_to_rid(zName, "*"); |
| 374 | 378 | if( rid<0 ){ |
| 375 | 379 | cgi_redirectf("%s/ambiguous/%T?src=%t", g.zTop, zName, g.zPath); |
| 376 | 380 | rid = 0; |
| 377 | 381 |
| --- src/name.c | |
| +++ src/name.c | |
| @@ -366,11 +366,15 @@ | |
| 366 | ** shows all possibilities and do not return. |
| 367 | */ |
| 368 | int name_to_rid_www(const char *zParamName){ |
| 369 | int rid; |
| 370 | const char *zName = P(zParamName); |
| 371 | |
| 372 | if( zName==0 || zName[0]==0 ) return 0; |
| 373 | rid = symbolic_name_to_rid(zName, "*"); |
| 374 | if( rid<0 ){ |
| 375 | cgi_redirectf("%s/ambiguous/%T?src=%t", g.zTop, zName, g.zPath); |
| 376 | rid = 0; |
| 377 |
| --- src/name.c | |
| +++ src/name.c | |
| @@ -366,11 +366,15 @@ | |
| 366 | ** shows all possibilities and do not return. |
| 367 | */ |
| 368 | int name_to_rid_www(const char *zParamName){ |
| 369 | int rid; |
| 370 | const char *zName = P(zParamName); |
| 371 | #ifdef FOSSIL_ENABLE_JSON |
| 372 | if(!zName && fossil_has_json()){ |
| 373 | zName = json_find_option_cstr(zParamName,NULL,NULL); |
| 374 | } |
| 375 | #endif |
| 376 | if( zName==0 || zName[0]==0 ) return 0; |
| 377 | rid = symbolic_name_to_rid(zName, "*"); |
| 378 | if( rid<0 ){ |
| 379 | cgi_redirectf("%s/ambiguous/%T?src=%t", g.zTop, zName, g.zPath); |
| 380 | rid = 0; |
| 381 |
+4
| --- src/report.c | ||
| +++ src/report.c | ||
| @@ -19,10 +19,13 @@ | ||
| 19 | 19 | */ |
| 20 | 20 | #include "config.h" |
| 21 | 21 | #include <time.h> |
| 22 | 22 | #include "report.h" |
| 23 | 23 | #include <assert.h> |
| 24 | +#ifdef FOSSIL_ENABLE_JSON | |
| 25 | +# include "cson_amalgamation.h" | |
| 26 | +#endif | |
| 24 | 27 | |
| 25 | 28 | /* Forward references to static routines */ |
| 26 | 29 | static void report_format_hints(void); |
| 27 | 30 | |
| 28 | 31 | /* |
| @@ -1138,5 +1141,6 @@ | ||
| 1138 | 1141 | report_unrestrict_sql(); |
| 1139 | 1142 | if( zFilter ){ |
| 1140 | 1143 | free(zSql); |
| 1141 | 1144 | } |
| 1142 | 1145 | } |
| 1146 | + | |
| 1143 | 1147 |
| --- src/report.c | |
| +++ src/report.c | |
| @@ -19,10 +19,13 @@ | |
| 19 | */ |
| 20 | #include "config.h" |
| 21 | #include <time.h> |
| 22 | #include "report.h" |
| 23 | #include <assert.h> |
| 24 | |
| 25 | /* Forward references to static routines */ |
| 26 | static void report_format_hints(void); |
| 27 | |
| 28 | /* |
| @@ -1138,5 +1141,6 @@ | |
| 1138 | report_unrestrict_sql(); |
| 1139 | if( zFilter ){ |
| 1140 | free(zSql); |
| 1141 | } |
| 1142 | } |
| 1143 |
| --- src/report.c | |
| +++ src/report.c | |
| @@ -19,10 +19,13 @@ | |
| 19 | */ |
| 20 | #include "config.h" |
| 21 | #include <time.h> |
| 22 | #include "report.h" |
| 23 | #include <assert.h> |
| 24 | #ifdef FOSSIL_ENABLE_JSON |
| 25 | # include "cson_amalgamation.h" |
| 26 | #endif |
| 27 | |
| 28 | /* Forward references to static routines */ |
| 29 | static void report_format_hints(void); |
| 30 | |
| 31 | /* |
| @@ -1138,5 +1141,6 @@ | |
| 1141 | report_unrestrict_sql(); |
| 1142 | if( zFilter ){ |
| 1143 | free(zSql); |
| 1144 | } |
| 1145 | } |
| 1146 | |
| 1147 |
+22
-20
| --- src/timeline.c | ||
| +++ src/timeline.c | ||
| @@ -20,10 +20,13 @@ | ||
| 20 | 20 | */ |
| 21 | 21 | #include <string.h> |
| 22 | 22 | #include <time.h> |
| 23 | 23 | #include "config.h" |
| 24 | 24 | #include "timeline.h" |
| 25 | +#ifdef FOSSIL_ENABLE_JSON | |
| 26 | +# include "cson_amalgamation.h" | |
| 27 | +#endif | |
| 25 | 28 | |
| 26 | 29 | /* |
| 27 | 30 | ** Shorten a UUID so that is the minimum length needed to contain |
| 28 | 31 | ** at least one digit in the range 'a'..'f'. The minimum length is 10. |
| 29 | 32 | */ |
| @@ -768,24 +771,24 @@ | ||
| 768 | 771 | */ |
| 769 | 772 | const char *timeline_query_for_www(void){ |
| 770 | 773 | static char *zBase = 0; |
| 771 | 774 | static const char zBaseSql[] = |
| 772 | 775 | @ SELECT |
| 773 | - @ blob.rid, | |
| 774 | - @ uuid, | |
| 776 | + @ blob.rid AS blobRid, | |
| 777 | + @ uuid AS uuid, | |
| 775 | 778 | @ datetime(event.mtime,'localtime') AS timestamp, |
| 776 | - @ coalesce(ecomment, comment), | |
| 777 | - @ coalesce(euser, user), | |
| 778 | - @ blob.rid IN leaf, | |
| 779 | - @ bgcolor, | |
| 780 | - @ event.type, | |
| 779 | + @ coalesce(ecomment, comment) AS comment, | |
| 780 | + @ coalesce(euser, user) AS user, | |
| 781 | + @ blob.rid IN leaf AS leaf, | |
| 782 | + @ bgcolor AS bgColor, | |
| 783 | + @ event.type AS eventType, | |
| 781 | 784 | @ (SELECT group_concat(substr(tagname,5), ', ') FROM tag, tagxref |
| 782 | 785 | @ WHERE tagname GLOB 'sym-*' AND tag.tagid=tagxref.tagid |
| 783 | - @ AND tagxref.rid=blob.rid AND tagxref.tagtype>0), | |
| 784 | - @ tagid, | |
| 785 | - @ brief, | |
| 786 | - @ event.mtime | |
| 786 | + @ AND tagxref.rid=blob.rid AND tagxref.tagtype>0) AS tags, | |
| 787 | + @ tagid AS tagid, | |
| 788 | + @ brief AS brief, | |
| 789 | + @ event.mtime AS mtime | |
| 787 | 790 | @ FROM event JOIN blob |
| 788 | 791 | @ WHERE blob.rid=event.objid |
| 789 | 792 | ; |
| 790 | 793 | if( zBase==0 ){ |
| 791 | 794 | zBase = mprintf(zBaseSql, TAG_BRANCH, TAG_BRANCH); |
| @@ -1381,24 +1384,24 @@ | ||
| 1381 | 1384 | ** a timeline query for display on a TTY. |
| 1382 | 1385 | */ |
| 1383 | 1386 | const char *timeline_query_for_tty(void){ |
| 1384 | 1387 | static const char zBaseSql[] = |
| 1385 | 1388 | @ SELECT |
| 1386 | - @ blob.rid, | |
| 1389 | + @ blob.rid AS rid, | |
| 1387 | 1390 | @ uuid, |
| 1388 | - @ datetime(event.mtime,'localtime'), | |
| 1391 | + @ datetime(event.mtime,'localtime') AS mDateTime, | |
| 1389 | 1392 | @ coalesce(ecomment,comment) |
| 1390 | 1393 | @ || ' (user: ' || coalesce(euser,user,'?') |
| 1391 | 1394 | @ || (SELECT case when length(x)>0 then ' tags: ' || x else '' end |
| 1392 | 1395 | @ FROM (SELECT group_concat(substr(tagname,5), ', ') AS x |
| 1393 | 1396 | @ FROM tag, tagxref |
| 1394 | 1397 | @ WHERE tagname GLOB 'sym-*' AND tag.tagid=tagxref.tagid |
| 1395 | 1398 | @ AND tagxref.rid=blob.rid AND tagxref.tagtype>0)) |
| 1396 | - @ || ')', | |
| 1397 | - @ (SELECT count(*) FROM plink WHERE pid=blob.rid AND isprim), | |
| 1398 | - @ (SELECT count(*) FROM plink WHERE cid=blob.rid), | |
| 1399 | - @ event.mtime | |
| 1399 | + @ || ')' as comment, | |
| 1400 | + @ (SELECT count(*) FROM plink WHERE pid=blob.rid AND isprim) AS primPlinkCount, | |
| 1401 | + @ (SELECT count(*) FROM plink WHERE cid=blob.rid) AS plinkCount, | |
| 1402 | + @ event.mtime AS mtime | |
| 1400 | 1403 | @ FROM event, blob |
| 1401 | 1404 | @ WHERE blob.rid=event.objid |
| 1402 | 1405 | ; |
| 1403 | 1406 | return zBaseSql; |
| 1404 | 1407 | } |
| @@ -1441,12 +1444,12 @@ | ||
| 1441 | 1444 | ** |
| 1442 | 1445 | ** w = wiki commits only |
| 1443 | 1446 | ** ci = file commits only |
| 1444 | 1447 | ** t = tickets only |
| 1445 | 1448 | ** |
| 1446 | -** The optional showfiles argument if specified prints the list of | |
| 1447 | -** files changed in a checkin after the checkin comment | |
| 1449 | +** The optional showfiles argument, if specified, prints the list of | |
| 1450 | +** files changed in a checkin after the checkin comment. | |
| 1448 | 1451 | ** |
| 1449 | 1452 | */ |
| 1450 | 1453 | void timeline_cmd(void){ |
| 1451 | 1454 | Stmt q; |
| 1452 | 1455 | int n, k; |
| @@ -1540,11 +1543,10 @@ | ||
| 1540 | 1543 | blob_appendf(&sql, " AND blob.rid IN ok"); |
| 1541 | 1544 | } |
| 1542 | 1545 | if( zType && (zType[0]!='a') ){ |
| 1543 | 1546 | blob_appendf(&sql, " AND event.type=%Q ", zType); |
| 1544 | 1547 | } |
| 1545 | - | |
| 1546 | 1548 | blob_appendf(&sql, " ORDER BY event.mtime DESC"); |
| 1547 | 1549 | db_prepare(&q, blob_str(&sql)); |
| 1548 | 1550 | blob_reset(&sql); |
| 1549 | 1551 | print_timeline(&q, n, showfilesFlag); |
| 1550 | 1552 | db_finalize(&q); |
| 1551 | 1553 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -20,10 +20,13 @@ | |
| 20 | */ |
| 21 | #include <string.h> |
| 22 | #include <time.h> |
| 23 | #include "config.h" |
| 24 | #include "timeline.h" |
| 25 | |
| 26 | /* |
| 27 | ** Shorten a UUID so that is the minimum length needed to contain |
| 28 | ** at least one digit in the range 'a'..'f'. The minimum length is 10. |
| 29 | */ |
| @@ -768,24 +771,24 @@ | |
| 768 | */ |
| 769 | const char *timeline_query_for_www(void){ |
| 770 | static char *zBase = 0; |
| 771 | static const char zBaseSql[] = |
| 772 | @ SELECT |
| 773 | @ blob.rid, |
| 774 | @ uuid, |
| 775 | @ datetime(event.mtime,'localtime') AS timestamp, |
| 776 | @ coalesce(ecomment, comment), |
| 777 | @ coalesce(euser, user), |
| 778 | @ blob.rid IN leaf, |
| 779 | @ bgcolor, |
| 780 | @ event.type, |
| 781 | @ (SELECT group_concat(substr(tagname,5), ', ') FROM tag, tagxref |
| 782 | @ WHERE tagname GLOB 'sym-*' AND tag.tagid=tagxref.tagid |
| 783 | @ AND tagxref.rid=blob.rid AND tagxref.tagtype>0), |
| 784 | @ tagid, |
| 785 | @ brief, |
| 786 | @ event.mtime |
| 787 | @ FROM event JOIN blob |
| 788 | @ WHERE blob.rid=event.objid |
| 789 | ; |
| 790 | if( zBase==0 ){ |
| 791 | zBase = mprintf(zBaseSql, TAG_BRANCH, TAG_BRANCH); |
| @@ -1381,24 +1384,24 @@ | |
| 1381 | ** a timeline query for display on a TTY. |
| 1382 | */ |
| 1383 | const char *timeline_query_for_tty(void){ |
| 1384 | static const char zBaseSql[] = |
| 1385 | @ SELECT |
| 1386 | @ blob.rid, |
| 1387 | @ uuid, |
| 1388 | @ datetime(event.mtime,'localtime'), |
| 1389 | @ coalesce(ecomment,comment) |
| 1390 | @ || ' (user: ' || coalesce(euser,user,'?') |
| 1391 | @ || (SELECT case when length(x)>0 then ' tags: ' || x else '' end |
| 1392 | @ FROM (SELECT group_concat(substr(tagname,5), ', ') AS x |
| 1393 | @ FROM tag, tagxref |
| 1394 | @ WHERE tagname GLOB 'sym-*' AND tag.tagid=tagxref.tagid |
| 1395 | @ AND tagxref.rid=blob.rid AND tagxref.tagtype>0)) |
| 1396 | @ || ')', |
| 1397 | @ (SELECT count(*) FROM plink WHERE pid=blob.rid AND isprim), |
| 1398 | @ (SELECT count(*) FROM plink WHERE cid=blob.rid), |
| 1399 | @ event.mtime |
| 1400 | @ FROM event, blob |
| 1401 | @ WHERE blob.rid=event.objid |
| 1402 | ; |
| 1403 | return zBaseSql; |
| 1404 | } |
| @@ -1441,12 +1444,12 @@ | |
| 1441 | ** |
| 1442 | ** w = wiki commits only |
| 1443 | ** ci = file commits only |
| 1444 | ** t = tickets only |
| 1445 | ** |
| 1446 | ** The optional showfiles argument if specified prints the list of |
| 1447 | ** files changed in a checkin after the checkin comment |
| 1448 | ** |
| 1449 | */ |
| 1450 | void timeline_cmd(void){ |
| 1451 | Stmt q; |
| 1452 | int n, k; |
| @@ -1540,11 +1543,10 @@ | |
| 1540 | blob_appendf(&sql, " AND blob.rid IN ok"); |
| 1541 | } |
| 1542 | if( zType && (zType[0]!='a') ){ |
| 1543 | blob_appendf(&sql, " AND event.type=%Q ", zType); |
| 1544 | } |
| 1545 | |
| 1546 | blob_appendf(&sql, " ORDER BY event.mtime DESC"); |
| 1547 | db_prepare(&q, blob_str(&sql)); |
| 1548 | blob_reset(&sql); |
| 1549 | print_timeline(&q, n, showfilesFlag); |
| 1550 | db_finalize(&q); |
| 1551 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -20,10 +20,13 @@ | |
| 20 | */ |
| 21 | #include <string.h> |
| 22 | #include <time.h> |
| 23 | #include "config.h" |
| 24 | #include "timeline.h" |
| 25 | #ifdef FOSSIL_ENABLE_JSON |
| 26 | # include "cson_amalgamation.h" |
| 27 | #endif |
| 28 | |
| 29 | /* |
| 30 | ** Shorten a UUID so that is the minimum length needed to contain |
| 31 | ** at least one digit in the range 'a'..'f'. The minimum length is 10. |
| 32 | */ |
| @@ -768,24 +771,24 @@ | |
| 771 | */ |
| 772 | const char *timeline_query_for_www(void){ |
| 773 | static char *zBase = 0; |
| 774 | static const char zBaseSql[] = |
| 775 | @ SELECT |
| 776 | @ blob.rid AS blobRid, |
| 777 | @ uuid AS uuid, |
| 778 | @ datetime(event.mtime,'localtime') AS timestamp, |
| 779 | @ coalesce(ecomment, comment) AS comment, |
| 780 | @ coalesce(euser, user) AS user, |
| 781 | @ blob.rid IN leaf AS leaf, |
| 782 | @ bgcolor AS bgColor, |
| 783 | @ event.type AS eventType, |
| 784 | @ (SELECT group_concat(substr(tagname,5), ', ') FROM tag, tagxref |
| 785 | @ WHERE tagname GLOB 'sym-*' AND tag.tagid=tagxref.tagid |
| 786 | @ AND tagxref.rid=blob.rid AND tagxref.tagtype>0) AS tags, |
| 787 | @ tagid AS tagid, |
| 788 | @ brief AS brief, |
| 789 | @ event.mtime AS mtime |
| 790 | @ FROM event JOIN blob |
| 791 | @ WHERE blob.rid=event.objid |
| 792 | ; |
| 793 | if( zBase==0 ){ |
| 794 | zBase = mprintf(zBaseSql, TAG_BRANCH, TAG_BRANCH); |
| @@ -1381,24 +1384,24 @@ | |
| 1384 | ** a timeline query for display on a TTY. |
| 1385 | */ |
| 1386 | const char *timeline_query_for_tty(void){ |
| 1387 | static const char zBaseSql[] = |
| 1388 | @ SELECT |
| 1389 | @ blob.rid AS rid, |
| 1390 | @ uuid, |
| 1391 | @ datetime(event.mtime,'localtime') AS mDateTime, |
| 1392 | @ coalesce(ecomment,comment) |
| 1393 | @ || ' (user: ' || coalesce(euser,user,'?') |
| 1394 | @ || (SELECT case when length(x)>0 then ' tags: ' || x else '' end |
| 1395 | @ FROM (SELECT group_concat(substr(tagname,5), ', ') AS x |
| 1396 | @ FROM tag, tagxref |
| 1397 | @ WHERE tagname GLOB 'sym-*' AND tag.tagid=tagxref.tagid |
| 1398 | @ AND tagxref.rid=blob.rid AND tagxref.tagtype>0)) |
| 1399 | @ || ')' as comment, |
| 1400 | @ (SELECT count(*) FROM plink WHERE pid=blob.rid AND isprim) AS primPlinkCount, |
| 1401 | @ (SELECT count(*) FROM plink WHERE cid=blob.rid) AS plinkCount, |
| 1402 | @ event.mtime AS mtime |
| 1403 | @ FROM event, blob |
| 1404 | @ WHERE blob.rid=event.objid |
| 1405 | ; |
| 1406 | return zBaseSql; |
| 1407 | } |
| @@ -1441,12 +1444,12 @@ | |
| 1444 | ** |
| 1445 | ** w = wiki commits only |
| 1446 | ** ci = file commits only |
| 1447 | ** t = tickets only |
| 1448 | ** |
| 1449 | ** The optional showfiles argument, if specified, prints the list of |
| 1450 | ** files changed in a checkin after the checkin comment. |
| 1451 | ** |
| 1452 | */ |
| 1453 | void timeline_cmd(void){ |
| 1454 | Stmt q; |
| 1455 | int n, k; |
| @@ -1540,11 +1543,10 @@ | |
| 1543 | blob_appendf(&sql, " AND blob.rid IN ok"); |
| 1544 | } |
| 1545 | if( zType && (zType[0]!='a') ){ |
| 1546 | blob_appendf(&sql, " AND event.type=%Q ", zType); |
| 1547 | } |
| 1548 | blob_appendf(&sql, " ORDER BY event.mtime DESC"); |
| 1549 | db_prepare(&q, blob_str(&sql)); |
| 1550 | blob_reset(&sql); |
| 1551 | print_timeline(&q, n, showfilesFlag); |
| 1552 | db_finalize(&q); |
| 1553 |
+2
-4
| --- src/tkt.c | ||
| +++ src/tkt.c | ||
| @@ -853,10 +853,11 @@ | ||
| 853 | 853 | ** |
| 854 | 854 | ** Run the ticket report, identified by the report format title |
| 855 | 855 | ** used in the gui. The data is written as flat file on stdout, |
| 856 | 856 | ** using "," as separator. The separator "," can be changed using |
| 857 | 857 | ** the -l or --limit option. |
| 858 | +** | |
| 858 | 859 | ** If TICKETFILTER is given on the commandline, the query is |
| 859 | 860 | ** limited with a new WHERE-condition. |
| 860 | 861 | ** example: Report lists a column # with the uuid |
| 861 | 862 | ** TICKETFILTER may be [#]='uuuuuuuuu' |
| 862 | 863 | ** example: Report only lists rows with status not open |
| @@ -863,11 +864,11 @@ | ||
| 863 | 864 | ** TICKETFILTER: status != 'open' |
| 864 | 865 | ** If the option -q|--quote is used, the tickets are encoded by |
| 865 | 866 | ** quoting special chars(space -> \\s, tab -> \\t, newline -> \\n, |
| 866 | 867 | ** cr -> \\r, formfeed -> \\f, vtab -> \\v, nul -> \\0, \\ -> \\\\). |
| 867 | 868 | ** Otherwise, the simplified encoding as on the show report raw |
| 868 | -** page in the gui is used. | |
| 869 | +** page in the gui is used. This has no effect in JSON mode. | |
| 869 | 870 | ** |
| 870 | 871 | ** Instead of the report title its possible to use the report |
| 871 | 872 | ** number. Using the special report number 0 list all columns, |
| 872 | 873 | ** defined in the ticket table. |
| 873 | 874 | ** |
| @@ -957,22 +958,19 @@ | ||
| 957 | 958 | usage("show REPORTNR"); |
| 958 | 959 | }else{ |
| 959 | 960 | const char *zRep = 0; |
| 960 | 961 | const char *zSep = 0; |
| 961 | 962 | const char *zFilterUuid = 0; |
| 962 | - | |
| 963 | 963 | zSep = find_option("limit","l",1); |
| 964 | 964 | zRep = g.argv[3]; |
| 965 | 965 | if( !strcmp(zRep,"0") ){ |
| 966 | 966 | zRep = 0; |
| 967 | 967 | } |
| 968 | 968 | if( g.argc>4 ){ |
| 969 | 969 | zFilterUuid = g.argv[4]; |
| 970 | 970 | } |
| 971 | - | |
| 972 | 971 | rptshow( zRep, zSep, zFilterUuid, tktEncoding ); |
| 973 | - | |
| 974 | 972 | } |
| 975 | 973 | }else{ |
| 976 | 974 | /* add a new ticket or update an existing ticket */ |
| 977 | 975 | enum { set,add,history,err } eCmd = err; |
| 978 | 976 | int i = 0; |
| 979 | 977 |
| --- src/tkt.c | |
| +++ src/tkt.c | |
| @@ -853,10 +853,11 @@ | |
| 853 | ** |
| 854 | ** Run the ticket report, identified by the report format title |
| 855 | ** used in the gui. The data is written as flat file on stdout, |
| 856 | ** using "," as separator. The separator "," can be changed using |
| 857 | ** the -l or --limit option. |
| 858 | ** If TICKETFILTER is given on the commandline, the query is |
| 859 | ** limited with a new WHERE-condition. |
| 860 | ** example: Report lists a column # with the uuid |
| 861 | ** TICKETFILTER may be [#]='uuuuuuuuu' |
| 862 | ** example: Report only lists rows with status not open |
| @@ -863,11 +864,11 @@ | |
| 863 | ** TICKETFILTER: status != 'open' |
| 864 | ** If the option -q|--quote is used, the tickets are encoded by |
| 865 | ** quoting special chars(space -> \\s, tab -> \\t, newline -> \\n, |
| 866 | ** cr -> \\r, formfeed -> \\f, vtab -> \\v, nul -> \\0, \\ -> \\\\). |
| 867 | ** Otherwise, the simplified encoding as on the show report raw |
| 868 | ** page in the gui is used. |
| 869 | ** |
| 870 | ** Instead of the report title its possible to use the report |
| 871 | ** number. Using the special report number 0 list all columns, |
| 872 | ** defined in the ticket table. |
| 873 | ** |
| @@ -957,22 +958,19 @@ | |
| 957 | usage("show REPORTNR"); |
| 958 | }else{ |
| 959 | const char *zRep = 0; |
| 960 | const char *zSep = 0; |
| 961 | const char *zFilterUuid = 0; |
| 962 | |
| 963 | zSep = find_option("limit","l",1); |
| 964 | zRep = g.argv[3]; |
| 965 | if( !strcmp(zRep,"0") ){ |
| 966 | zRep = 0; |
| 967 | } |
| 968 | if( g.argc>4 ){ |
| 969 | zFilterUuid = g.argv[4]; |
| 970 | } |
| 971 | |
| 972 | rptshow( zRep, zSep, zFilterUuid, tktEncoding ); |
| 973 | |
| 974 | } |
| 975 | }else{ |
| 976 | /* add a new ticket or update an existing ticket */ |
| 977 | enum { set,add,history,err } eCmd = err; |
| 978 | int i = 0; |
| 979 |
| --- src/tkt.c | |
| +++ src/tkt.c | |
| @@ -853,10 +853,11 @@ | |
| 853 | ** |
| 854 | ** Run the ticket report, identified by the report format title |
| 855 | ** used in the gui. The data is written as flat file on stdout, |
| 856 | ** using "," as separator. The separator "," can be changed using |
| 857 | ** the -l or --limit option. |
| 858 | ** |
| 859 | ** If TICKETFILTER is given on the commandline, the query is |
| 860 | ** limited with a new WHERE-condition. |
| 861 | ** example: Report lists a column # with the uuid |
| 862 | ** TICKETFILTER may be [#]='uuuuuuuuu' |
| 863 | ** example: Report only lists rows with status not open |
| @@ -863,11 +864,11 @@ | |
| 864 | ** TICKETFILTER: status != 'open' |
| 865 | ** If the option -q|--quote is used, the tickets are encoded by |
| 866 | ** quoting special chars(space -> \\s, tab -> \\t, newline -> \\n, |
| 867 | ** cr -> \\r, formfeed -> \\f, vtab -> \\v, nul -> \\0, \\ -> \\\\). |
| 868 | ** Otherwise, the simplified encoding as on the show report raw |
| 869 | ** page in the gui is used. This has no effect in JSON mode. |
| 870 | ** |
| 871 | ** Instead of the report title its possible to use the report |
| 872 | ** number. Using the special report number 0 list all columns, |
| 873 | ** defined in the ticket table. |
| 874 | ** |
| @@ -957,22 +958,19 @@ | |
| 958 | usage("show REPORTNR"); |
| 959 | }else{ |
| 960 | const char *zRep = 0; |
| 961 | const char *zSep = 0; |
| 962 | const char *zFilterUuid = 0; |
| 963 | zSep = find_option("limit","l",1); |
| 964 | zRep = g.argv[3]; |
| 965 | if( !strcmp(zRep,"0") ){ |
| 966 | zRep = 0; |
| 967 | } |
| 968 | if( g.argc>4 ){ |
| 969 | zFilterUuid = g.argv[4]; |
| 970 | } |
| 971 | rptshow( zRep, zSep, zFilterUuid, tktEncoding ); |
| 972 | } |
| 973 | }else{ |
| 974 | /* add a new ticket or update an existing ticket */ |
| 975 | enum { set,add,history,err } eCmd = err; |
| 976 | int i = 0; |
| 977 |
+24
-7
| --- src/wiki.c | ||
| +++ src/wiki.c | ||
| @@ -630,10 +630,27 @@ | ||
| 630 | 630 | manifest_destroy(pW1); |
| 631 | 631 | manifest_destroy(pW2); |
| 632 | 632 | style_footer(); |
| 633 | 633 | } |
| 634 | 634 | |
| 635 | +/* | |
| 636 | +** prepare()s pStmt with a query requesting: | |
| 637 | +** | |
| 638 | +** - wiki page name | |
| 639 | +** - tagxref (whatever that really is!) | |
| 640 | +** | |
| 641 | +** Used by wcontent_page() and the JSON wiki code. | |
| 642 | +*/ | |
| 643 | +void wiki_prepare_page_list( Stmt * pStmt ){ | |
| 644 | + db_prepare(pStmt, | |
| 645 | + "SELECT" | |
| 646 | + " substr(tagname, 6) as name," | |
| 647 | + " (SELECT value FROM tagxref WHERE tagid=tag.tagid ORDER BY mtime DESC) as tagXref" | |
| 648 | + " FROM tag WHERE tagname GLOB 'wiki-*'" | |
| 649 | + " ORDER BY lower(tagname) /*sort*/" | |
| 650 | + ); | |
| 651 | +} | |
| 635 | 652 | /* |
| 636 | 653 | ** WEBPAGE: wcontent |
| 637 | 654 | ** |
| 638 | 655 | ** all=1 Show deleted pages |
| 639 | 656 | ** |
| @@ -650,17 +667,11 @@ | ||
| 650 | 667 | style_submenu_element("Active", "Only Active Pages", "%s/wcontent", g.zTop); |
| 651 | 668 | }else{ |
| 652 | 669 | style_submenu_element("All", "All", "%s/wcontent?all=1", g.zTop); |
| 653 | 670 | } |
| 654 | 671 | @ <ul> |
| 655 | - db_prepare(&q, | |
| 656 | - "SELECT" | |
| 657 | - " substr(tagname, 6)," | |
| 658 | - " (SELECT value FROM tagxref WHERE tagid=tag.tagid ORDER BY mtime DESC)" | |
| 659 | - " FROM tag WHERE tagname GLOB 'wiki-*'" | |
| 660 | - " ORDER BY lower(tagname) /*sort*/" | |
| 661 | - ); | |
| 672 | + wiki_prepare_page_list(&q); | |
| 662 | 673 | while( db_step(&q)==SQLITE_ROW ){ |
| 663 | 674 | const char *zName = db_column_text(&q, 0); |
| 664 | 675 | int size = db_column_int(&q, 1); |
| 665 | 676 | if( size>0 ){ |
| 666 | 677 | @ <li><a href="%s(g.zTop)/wiki?name=%T(zName)">%h(zName)</a></li> |
| @@ -790,13 +801,19 @@ | ||
| 790 | 801 | " WHERE x.tagid=t.tagid AND t.tagname='wiki-%q'" |
| 791 | 802 | " ORDER BY x.mtime DESC LIMIT 1", |
| 792 | 803 | zPageName |
| 793 | 804 | ); |
| 794 | 805 | if( rid==0 && !isNew ){ |
| 806 | +#ifdef FOSSIL_ENABLE_JSON | |
| 807 | + g.json.resultCode = FSL_JSON_E_RESOURCE_NOT_FOUND; | |
| 808 | +#endif | |
| 795 | 809 | fossil_fatal("no such wiki page: %s", zPageName); |
| 796 | 810 | } |
| 797 | 811 | if( rid!=0 && isNew ){ |
| 812 | +#ifdef FOSSIL_ENABLE_JSON | |
| 813 | + g.json.resultCode = FSL_JSON_E_RESOURCE_ALREADY_EXISTS; | |
| 814 | +#endif | |
| 798 | 815 | fossil_fatal("wiki page %s already exists", zPageName); |
| 799 | 816 | } |
| 800 | 817 | |
| 801 | 818 | blob_zero(&wiki); |
| 802 | 819 | zDate = date_in_standard_format("now"); |
| 803 | 820 |
| --- src/wiki.c | |
| +++ src/wiki.c | |
| @@ -630,10 +630,27 @@ | |
| 630 | manifest_destroy(pW1); |
| 631 | manifest_destroy(pW2); |
| 632 | style_footer(); |
| 633 | } |
| 634 | |
| 635 | /* |
| 636 | ** WEBPAGE: wcontent |
| 637 | ** |
| 638 | ** all=1 Show deleted pages |
| 639 | ** |
| @@ -650,17 +667,11 @@ | |
| 650 | style_submenu_element("Active", "Only Active Pages", "%s/wcontent", g.zTop); |
| 651 | }else{ |
| 652 | style_submenu_element("All", "All", "%s/wcontent?all=1", g.zTop); |
| 653 | } |
| 654 | @ <ul> |
| 655 | db_prepare(&q, |
| 656 | "SELECT" |
| 657 | " substr(tagname, 6)," |
| 658 | " (SELECT value FROM tagxref WHERE tagid=tag.tagid ORDER BY mtime DESC)" |
| 659 | " FROM tag WHERE tagname GLOB 'wiki-*'" |
| 660 | " ORDER BY lower(tagname) /*sort*/" |
| 661 | ); |
| 662 | while( db_step(&q)==SQLITE_ROW ){ |
| 663 | const char *zName = db_column_text(&q, 0); |
| 664 | int size = db_column_int(&q, 1); |
| 665 | if( size>0 ){ |
| 666 | @ <li><a href="%s(g.zTop)/wiki?name=%T(zName)">%h(zName)</a></li> |
| @@ -790,13 +801,19 @@ | |
| 790 | " WHERE x.tagid=t.tagid AND t.tagname='wiki-%q'" |
| 791 | " ORDER BY x.mtime DESC LIMIT 1", |
| 792 | zPageName |
| 793 | ); |
| 794 | if( rid==0 && !isNew ){ |
| 795 | fossil_fatal("no such wiki page: %s", zPageName); |
| 796 | } |
| 797 | if( rid!=0 && isNew ){ |
| 798 | fossil_fatal("wiki page %s already exists", zPageName); |
| 799 | } |
| 800 | |
| 801 | blob_zero(&wiki); |
| 802 | zDate = date_in_standard_format("now"); |
| 803 |
| --- src/wiki.c | |
| +++ src/wiki.c | |
| @@ -630,10 +630,27 @@ | |
| 630 | manifest_destroy(pW1); |
| 631 | manifest_destroy(pW2); |
| 632 | style_footer(); |
| 633 | } |
| 634 | |
| 635 | /* |
| 636 | ** prepare()s pStmt with a query requesting: |
| 637 | ** |
| 638 | ** - wiki page name |
| 639 | ** - tagxref (whatever that really is!) |
| 640 | ** |
| 641 | ** Used by wcontent_page() and the JSON wiki code. |
| 642 | */ |
| 643 | void wiki_prepare_page_list( Stmt * pStmt ){ |
| 644 | db_prepare(pStmt, |
| 645 | "SELECT" |
| 646 | " substr(tagname, 6) as name," |
| 647 | " (SELECT value FROM tagxref WHERE tagid=tag.tagid ORDER BY mtime DESC) as tagXref" |
| 648 | " FROM tag WHERE tagname GLOB 'wiki-*'" |
| 649 | " ORDER BY lower(tagname) /*sort*/" |
| 650 | ); |
| 651 | } |
| 652 | /* |
| 653 | ** WEBPAGE: wcontent |
| 654 | ** |
| 655 | ** all=1 Show deleted pages |
| 656 | ** |
| @@ -650,17 +667,11 @@ | |
| 667 | style_submenu_element("Active", "Only Active Pages", "%s/wcontent", g.zTop); |
| 668 | }else{ |
| 669 | style_submenu_element("All", "All", "%s/wcontent?all=1", g.zTop); |
| 670 | } |
| 671 | @ <ul> |
| 672 | wiki_prepare_page_list(&q); |
| 673 | while( db_step(&q)==SQLITE_ROW ){ |
| 674 | const char *zName = db_column_text(&q, 0); |
| 675 | int size = db_column_int(&q, 1); |
| 676 | if( size>0 ){ |
| 677 | @ <li><a href="%s(g.zTop)/wiki?name=%T(zName)">%h(zName)</a></li> |
| @@ -790,13 +801,19 @@ | |
| 801 | " WHERE x.tagid=t.tagid AND t.tagname='wiki-%q'" |
| 802 | " ORDER BY x.mtime DESC LIMIT 1", |
| 803 | zPageName |
| 804 | ); |
| 805 | if( rid==0 && !isNew ){ |
| 806 | #ifdef FOSSIL_ENABLE_JSON |
| 807 | g.json.resultCode = FSL_JSON_E_RESOURCE_NOT_FOUND; |
| 808 | #endif |
| 809 | fossil_fatal("no such wiki page: %s", zPageName); |
| 810 | } |
| 811 | if( rid!=0 && isNew ){ |
| 812 | #ifdef FOSSIL_ENABLE_JSON |
| 813 | g.json.resultCode = FSL_JSON_E_RESOURCE_ALREADY_EXISTS; |
| 814 | #endif |
| 815 | fossil_fatal("wiki page %s already exists", zPageName); |
| 816 | } |
| 817 | |
| 818 | blob_zero(&wiki); |
| 819 | zDate = date_in_standard_format("now"); |
| 820 |
+86
-4
| --- win/Makefile.dmc | ||
| +++ win/Makefile.dmc | ||
| @@ -22,13 +22,13 @@ | ||
| 22 | 22 | TCC = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL) |
| 23 | 23 | LIBS = $(DMDIR)\extra\lib\ zlib wsock32 |
| 24 | 24 | |
| 25 | 25 | SQLITE_OPTIONS = -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_STAT3 -Dlocaltime=fossil_localtime -DSQLITE_ENABLE_LOCKING_STYLE=0 |
| 26 | 26 | |
| 27 | -SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.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 glob_.c graph_.c gzip_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c leaf_.c login_.c main_.c manifest_.c md5_.c merge_.c merge3_.c name_.c path_.c pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.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 update_.c url_.c user_.c verify_.c vfile_.c wiki_.c wikiformat_.c winhttp_.c xfer_.c zip_.c | |
| 27 | +SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.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 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_diff_.c json_login_.c json_query_.c json_report_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c login_.c main_.c manifest_.c md5_.c merge_.c merge3_.c name_.c path_.c pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.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 update_.c url_.c user_.c verify_.c vfile_.c wiki_.c wikiformat_.c winhttp_.c xfer_.c zip_.c | |
| 28 | 28 | |
| 29 | -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)\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)\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)\leaf$O $(OBJDIR)\login$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\rebuild$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\setup$O $(OBJDIR)\sha1$O $(OBJDIR)\shun$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)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winhttp$O $(OBJDIR)\xfer$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O | |
| 29 | +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)\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)\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_diff$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\login$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\rebuild$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\setup$O $(OBJDIR)\sha1$O $(OBJDIR)\shun$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)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winhttp$O $(OBJDIR)\xfer$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O | |
| 30 | 30 | |
| 31 | 31 | |
| 32 | 32 | RC=$(DMDIR)\bin\rcc |
| 33 | 33 | RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__ |
| 34 | 34 | |
| @@ -42,11 +42,11 @@ | ||
| 42 | 42 | |
| 43 | 43 | $(OBJDIR)\fossil.res: $B\win\fossil.rc |
| 44 | 44 | $(RC) $(RCFLAGS) -o$@ $** |
| 45 | 45 | |
| 46 | 46 | $(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res |
| 47 | - +echo add allrepo attach bag bisect blob branch browse captcha cgi checkin checkout clearsign clone comformat configure content db delta deltacmd descendants diff diffcmd doc encode event export file finfo glob graph gzip http http_socket http_ssl http_transport import info leaf login main manifest md5 merge merge3 name path pivot popen pqueue printf rebuild report rss schema search setup sha1 shun skins sqlcmd stash stat style sync tag tar th_main timeline tkt tktsetup undo update url user verify vfile wiki wikiformat winhttp xfer zip shell sqlite3 th th_lang > $@ | |
| 47 | + +echo add allrepo attach bag bisect blob branch browse captcha cgi checkin checkout clearsign clone comformat configure content db delta deltacmd descendants diff diffcmd doc encode event export file finfo glob graph gzip http http_socket http_ssl http_transport import info json json_artifact json_branch json_diff json_login json_query json_report json_tag json_timeline json_user json_wiki leaf login main manifest md5 merge merge3 name path pivot popen pqueue printf rebuild report rss schema search setup sha1 shun skins sqlcmd stash stat style sync tag tar th_main timeline tkt tktsetup undo update url user verify vfile wiki wikiformat winhttp xfer zip shell sqlite3 th th_lang > $@ | |
| 48 | 48 | +echo fossil >> $@ |
| 49 | 49 | +echo fossil >> $@ |
| 50 | 50 | +echo $(LIBS) >> $@ |
| 51 | 51 | +echo. >> $@ |
| 52 | 52 | +echo fossil >> $@ |
| @@ -72,10 +72,13 @@ | ||
| 72 | 72 | $(OBJDIR)\th$O : $(SRCDIR)\th.c |
| 73 | 73 | $(TCC) -o$@ -c $** |
| 74 | 74 | |
| 75 | 75 | $(OBJDIR)\th_lang$O : $(SRCDIR)\th_lang.c |
| 76 | 76 | $(TCC) -o$@ -c $** |
| 77 | + | |
| 78 | +$(OBJDIR)\cson_amalgamation.h : $(SRCDIR)\cson_amalgamation.h | |
| 79 | + cp $@ $@ | |
| 77 | 80 | |
| 78 | 81 | VERSION.h : version$E $B\manifest.uuid $B\manifest $B\VERSION |
| 79 | 82 | +$** > $@ |
| 80 | 83 | |
| 81 | 84 | page_index.h: mkindex$E $(SRC) |
| @@ -85,10 +88,23 @@ | ||
| 85 | 88 | -del $(OBJDIR)\*.obj |
| 86 | 89 | -del *.obj *_.c *.h *.map |
| 87 | 90 | |
| 88 | 91 | realclean: |
| 89 | 92 | -del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E |
| 93 | + | |
| 94 | +$(OBJDIR)\json$O : $(SRCDIR)\json_detail.h | |
| 95 | +$(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h | |
| 96 | +$(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h | |
| 97 | +$(OBJDIR)\json_diff$O : $(SRCDIR)\json_detail.h | |
| 98 | +$(OBJDIR)\json_login$O : $(SRCDIR)\json_detail.h | |
| 99 | +$(OBJDIR)\json_query$O : $(SRCDIR)\json_detail.h | |
| 100 | +$(OBJDIR)\json_report$O : $(SRCDIR)\json_detail.h | |
| 101 | +$(OBJDIR)\json_tag$O : $(SRCDIR)\json_detail.h | |
| 102 | +$(OBJDIR)\json_timeline$O : $(SRCDIR)\json_detail.h | |
| 103 | +$(OBJDIR)\json_user$O : $(SRCDIR)\json_detail.h | |
| 104 | +$(OBJDIR)\json_wiki$O : $(SRCDIR)\json_detail.h | |
| 105 | + | |
| 90 | 106 | |
| 91 | 107 | |
| 92 | 108 | $(OBJDIR)\add$O : add_.c add.h |
| 93 | 109 | $(TCC) -o$@ -c add_.c |
| 94 | 110 | |
| @@ -314,10 +330,76 @@ | ||
| 314 | 330 | $(OBJDIR)\info$O : info_.c info.h |
| 315 | 331 | $(TCC) -o$@ -c info_.c |
| 316 | 332 | |
| 317 | 333 | info_.c : $(SRCDIR)\info.c |
| 318 | 334 | +translate$E $** > $@ |
| 335 | + | |
| 336 | +$(OBJDIR)\json$O : json_.c json.h | |
| 337 | + $(TCC) -o$@ -c json_.c | |
| 338 | + | |
| 339 | +json_.c : $(SRCDIR)\json.c | |
| 340 | + +translate$E $** > $@ | |
| 341 | + | |
| 342 | +$(OBJDIR)\json_artifact$O : json_artifact_.c json_artifact.h | |
| 343 | + $(TCC) -o$@ -c json_artifact_.c | |
| 344 | + | |
| 345 | +json_artifact_.c : $(SRCDIR)\json_artifact.c | |
| 346 | + +translate$E $** > $@ | |
| 347 | + | |
| 348 | +$(OBJDIR)\json_branch$O : json_branch_.c json_branch.h | |
| 349 | + $(TCC) -o$@ -c json_branch_.c | |
| 350 | + | |
| 351 | +json_branch_.c : $(SRCDIR)\json_branch.c | |
| 352 | + +translate$E $** > $@ | |
| 353 | + | |
| 354 | +$(OBJDIR)\json_diff$O : json_diff_.c json_diff.h | |
| 355 | + $(TCC) -o$@ -c json_diff_.c | |
| 356 | + | |
| 357 | +json_diff_.c : $(SRCDIR)\json_diff.c | |
| 358 | + +translate$E $** > $@ | |
| 359 | + | |
| 360 | +$(OBJDIR)\json_login$O : json_login_.c json_login.h | |
| 361 | + $(TCC) -o$@ -c json_login_.c | |
| 362 | + | |
| 363 | +json_login_.c : $(SRCDIR)\json_login.c | |
| 364 | + +translate$E $** > $@ | |
| 365 | + | |
| 366 | +$(OBJDIR)\json_query$O : json_query_.c json_query.h | |
| 367 | + $(TCC) -o$@ -c json_query_.c | |
| 368 | + | |
| 369 | +json_query_.c : $(SRCDIR)\json_query.c | |
| 370 | + +translate$E $** > $@ | |
| 371 | + | |
| 372 | +$(OBJDIR)\json_report$O : json_report_.c json_report.h | |
| 373 | + $(TCC) -o$@ -c json_report_.c | |
| 374 | + | |
| 375 | +json_report_.c : $(SRCDIR)\json_report.c | |
| 376 | + +translate$E $** > $@ | |
| 377 | + | |
| 378 | +$(OBJDIR)\json_tag$O : json_tag_.c json_tag.h | |
| 379 | + $(TCC) -o$@ -c json_tag_.c | |
| 380 | + | |
| 381 | +json_tag_.c : $(SRCDIR)\json_tag.c | |
| 382 | + +translate$E $** > $@ | |
| 383 | + | |
| 384 | +$(OBJDIR)\json_timeline$O : json_timeline_.c json_timeline.h | |
| 385 | + $(TCC) -o$@ -c json_timeline_.c | |
| 386 | + | |
| 387 | +json_timeline_.c : $(SRCDIR)\json_timeline.c | |
| 388 | + +translate$E $** > $@ | |
| 389 | + | |
| 390 | +$(OBJDIR)\json_user$O : json_user_.c json_user.h | |
| 391 | + $(TCC) -o$@ -c json_user_.c | |
| 392 | + | |
| 393 | +json_user_.c : $(SRCDIR)\json_user.c | |
| 394 | + +translate$E $** > $@ | |
| 395 | + | |
| 396 | +$(OBJDIR)\json_wiki$O : json_wiki_.c json_wiki.h | |
| 397 | + $(TCC) -o$@ -c json_wiki_.c | |
| 398 | + | |
| 399 | +json_wiki_.c : $(SRCDIR)\json_wiki.c | |
| 400 | + +translate$E $** > $@ | |
| 319 | 401 | |
| 320 | 402 | $(OBJDIR)\leaf$O : leaf_.c leaf.h |
| 321 | 403 | $(TCC) -o$@ -c leaf_.c |
| 322 | 404 | |
| 323 | 405 | leaf_.c : $(SRCDIR)\leaf.c |
| @@ -580,7 +662,7 @@ | ||
| 580 | 662 | |
| 581 | 663 | zip_.c : $(SRCDIR)\zip.c |
| 582 | 664 | +translate$E $** > $@ |
| 583 | 665 | |
| 584 | 666 | headers: makeheaders$E page_index.h VERSION.h |
| 585 | - +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 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 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 leaf_.c:leaf.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h path_.c:path.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.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 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 update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winhttp_.c:winhttp.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h | |
| 667 | + +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 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 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_diff_.c:json_diff.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.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 login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h path_.c:path.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.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 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 update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winhttp_.c:winhttp.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h | |
| 586 | 668 | @copy /Y nul: headers |
| 587 | 669 |
| --- win/Makefile.dmc | |
| +++ win/Makefile.dmc | |
| @@ -22,13 +22,13 @@ | |
| 22 | TCC = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL) |
| 23 | LIBS = $(DMDIR)\extra\lib\ zlib wsock32 |
| 24 | |
| 25 | SQLITE_OPTIONS = -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_STAT3 -Dlocaltime=fossil_localtime -DSQLITE_ENABLE_LOCKING_STYLE=0 |
| 26 | |
| 27 | SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.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 glob_.c graph_.c gzip_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c leaf_.c login_.c main_.c manifest_.c md5_.c merge_.c merge3_.c name_.c path_.c pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.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 update_.c url_.c user_.c verify_.c vfile_.c wiki_.c wikiformat_.c winhttp_.c xfer_.c zip_.c |
| 28 | |
| 29 | 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)\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)\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)\leaf$O $(OBJDIR)\login$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\rebuild$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\setup$O $(OBJDIR)\sha1$O $(OBJDIR)\shun$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)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winhttp$O $(OBJDIR)\xfer$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O |
| 30 | |
| 31 | |
| 32 | RC=$(DMDIR)\bin\rcc |
| 33 | RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__ |
| 34 | |
| @@ -42,11 +42,11 @@ | |
| 42 | |
| 43 | $(OBJDIR)\fossil.res: $B\win\fossil.rc |
| 44 | $(RC) $(RCFLAGS) -o$@ $** |
| 45 | |
| 46 | $(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res |
| 47 | +echo add allrepo attach bag bisect blob branch browse captcha cgi checkin checkout clearsign clone comformat configure content db delta deltacmd descendants diff diffcmd doc encode event export file finfo glob graph gzip http http_socket http_ssl http_transport import info leaf login main manifest md5 merge merge3 name path pivot popen pqueue printf rebuild report rss schema search setup sha1 shun skins sqlcmd stash stat style sync tag tar th_main timeline tkt tktsetup undo update url user verify vfile wiki wikiformat winhttp xfer zip shell sqlite3 th th_lang > $@ |
| 48 | +echo fossil >> $@ |
| 49 | +echo fossil >> $@ |
| 50 | +echo $(LIBS) >> $@ |
| 51 | +echo. >> $@ |
| 52 | +echo fossil >> $@ |
| @@ -72,10 +72,13 @@ | |
| 72 | $(OBJDIR)\th$O : $(SRCDIR)\th.c |
| 73 | $(TCC) -o$@ -c $** |
| 74 | |
| 75 | $(OBJDIR)\th_lang$O : $(SRCDIR)\th_lang.c |
| 76 | $(TCC) -o$@ -c $** |
| 77 | |
| 78 | VERSION.h : version$E $B\manifest.uuid $B\manifest $B\VERSION |
| 79 | +$** > $@ |
| 80 | |
| 81 | page_index.h: mkindex$E $(SRC) |
| @@ -85,10 +88,23 @@ | |
| 85 | -del $(OBJDIR)\*.obj |
| 86 | -del *.obj *_.c *.h *.map |
| 87 | |
| 88 | realclean: |
| 89 | -del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E |
| 90 | |
| 91 | |
| 92 | $(OBJDIR)\add$O : add_.c add.h |
| 93 | $(TCC) -o$@ -c add_.c |
| 94 | |
| @@ -314,10 +330,76 @@ | |
| 314 | $(OBJDIR)\info$O : info_.c info.h |
| 315 | $(TCC) -o$@ -c info_.c |
| 316 | |
| 317 | info_.c : $(SRCDIR)\info.c |
| 318 | +translate$E $** > $@ |
| 319 | |
| 320 | $(OBJDIR)\leaf$O : leaf_.c leaf.h |
| 321 | $(TCC) -o$@ -c leaf_.c |
| 322 | |
| 323 | leaf_.c : $(SRCDIR)\leaf.c |
| @@ -580,7 +662,7 @@ | |
| 580 | |
| 581 | zip_.c : $(SRCDIR)\zip.c |
| 582 | +translate$E $** > $@ |
| 583 | |
| 584 | headers: makeheaders$E page_index.h VERSION.h |
| 585 | +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 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 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 leaf_.c:leaf.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h path_.c:path.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.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 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 update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winhttp_.c:winhttp.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h |
| 586 | @copy /Y nul: headers |
| 587 |
| --- win/Makefile.dmc | |
| +++ win/Makefile.dmc | |
| @@ -22,13 +22,13 @@ | |
| 22 | TCC = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL) |
| 23 | LIBS = $(DMDIR)\extra\lib\ zlib wsock32 |
| 24 | |
| 25 | SQLITE_OPTIONS = -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_STAT3 -Dlocaltime=fossil_localtime -DSQLITE_ENABLE_LOCKING_STYLE=0 |
| 26 | |
| 27 | SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.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 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_diff_.c json_login_.c json_query_.c json_report_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c login_.c main_.c manifest_.c md5_.c merge_.c merge3_.c name_.c path_.c pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.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 update_.c url_.c user_.c verify_.c vfile_.c wiki_.c wikiformat_.c winhttp_.c xfer_.c zip_.c |
| 28 | |
| 29 | 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)\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)\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_diff$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\login$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\rebuild$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\setup$O $(OBJDIR)\sha1$O $(OBJDIR)\shun$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)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winhttp$O $(OBJDIR)\xfer$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O |
| 30 | |
| 31 | |
| 32 | RC=$(DMDIR)\bin\rcc |
| 33 | RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__ |
| 34 | |
| @@ -42,11 +42,11 @@ | |
| 42 | |
| 43 | $(OBJDIR)\fossil.res: $B\win\fossil.rc |
| 44 | $(RC) $(RCFLAGS) -o$@ $** |
| 45 | |
| 46 | $(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res |
| 47 | +echo add allrepo attach bag bisect blob branch browse captcha cgi checkin checkout clearsign clone comformat configure content db delta deltacmd descendants diff diffcmd doc encode event export file finfo glob graph gzip http http_socket http_ssl http_transport import info json json_artifact json_branch json_diff json_login json_query json_report json_tag json_timeline json_user json_wiki leaf login main manifest md5 merge merge3 name path pivot popen pqueue printf rebuild report rss schema search setup sha1 shun skins sqlcmd stash stat style sync tag tar th_main timeline tkt tktsetup undo update url user verify vfile wiki wikiformat winhttp xfer zip shell sqlite3 th th_lang > $@ |
| 48 | +echo fossil >> $@ |
| 49 | +echo fossil >> $@ |
| 50 | +echo $(LIBS) >> $@ |
| 51 | +echo. >> $@ |
| 52 | +echo fossil >> $@ |
| @@ -72,10 +72,13 @@ | |
| 72 | $(OBJDIR)\th$O : $(SRCDIR)\th.c |
| 73 | $(TCC) -o$@ -c $** |
| 74 | |
| 75 | $(OBJDIR)\th_lang$O : $(SRCDIR)\th_lang.c |
| 76 | $(TCC) -o$@ -c $** |
| 77 | |
| 78 | $(OBJDIR)\cson_amalgamation.h : $(SRCDIR)\cson_amalgamation.h |
| 79 | cp $@ $@ |
| 80 | |
| 81 | VERSION.h : version$E $B\manifest.uuid $B\manifest $B\VERSION |
| 82 | +$** > $@ |
| 83 | |
| 84 | page_index.h: mkindex$E $(SRC) |
| @@ -85,10 +88,23 @@ | |
| 88 | -del $(OBJDIR)\*.obj |
| 89 | -del *.obj *_.c *.h *.map |
| 90 | |
| 91 | realclean: |
| 92 | -del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E |
| 93 | |
| 94 | $(OBJDIR)\json$O : $(SRCDIR)\json_detail.h |
| 95 | $(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h |
| 96 | $(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h |
| 97 | $(OBJDIR)\json_diff$O : $(SRCDIR)\json_detail.h |
| 98 | $(OBJDIR)\json_login$O : $(SRCDIR)\json_detail.h |
| 99 | $(OBJDIR)\json_query$O : $(SRCDIR)\json_detail.h |
| 100 | $(OBJDIR)\json_report$O : $(SRCDIR)\json_detail.h |
| 101 | $(OBJDIR)\json_tag$O : $(SRCDIR)\json_detail.h |
| 102 | $(OBJDIR)\json_timeline$O : $(SRCDIR)\json_detail.h |
| 103 | $(OBJDIR)\json_user$O : $(SRCDIR)\json_detail.h |
| 104 | $(OBJDIR)\json_wiki$O : $(SRCDIR)\json_detail.h |
| 105 | |
| 106 | |
| 107 | |
| 108 | $(OBJDIR)\add$O : add_.c add.h |
| 109 | $(TCC) -o$@ -c add_.c |
| 110 | |
| @@ -314,10 +330,76 @@ | |
| 330 | $(OBJDIR)\info$O : info_.c info.h |
| 331 | $(TCC) -o$@ -c info_.c |
| 332 | |
| 333 | info_.c : $(SRCDIR)\info.c |
| 334 | +translate$E $** > $@ |
| 335 | |
| 336 | $(OBJDIR)\json$O : json_.c json.h |
| 337 | $(TCC) -o$@ -c json_.c |
| 338 | |
| 339 | json_.c : $(SRCDIR)\json.c |
| 340 | +translate$E $** > $@ |
| 341 | |
| 342 | $(OBJDIR)\json_artifact$O : json_artifact_.c json_artifact.h |
| 343 | $(TCC) -o$@ -c json_artifact_.c |
| 344 | |
| 345 | json_artifact_.c : $(SRCDIR)\json_artifact.c |
| 346 | +translate$E $** > $@ |
| 347 | |
| 348 | $(OBJDIR)\json_branch$O : json_branch_.c json_branch.h |
| 349 | $(TCC) -o$@ -c json_branch_.c |
| 350 | |
| 351 | json_branch_.c : $(SRCDIR)\json_branch.c |
| 352 | +translate$E $** > $@ |
| 353 | |
| 354 | $(OBJDIR)\json_diff$O : json_diff_.c json_diff.h |
| 355 | $(TCC) -o$@ -c json_diff_.c |
| 356 | |
| 357 | json_diff_.c : $(SRCDIR)\json_diff.c |
| 358 | +translate$E $** > $@ |
| 359 | |
| 360 | $(OBJDIR)\json_login$O : json_login_.c json_login.h |
| 361 | $(TCC) -o$@ -c json_login_.c |
| 362 | |
| 363 | json_login_.c : $(SRCDIR)\json_login.c |
| 364 | +translate$E $** > $@ |
| 365 | |
| 366 | $(OBJDIR)\json_query$O : json_query_.c json_query.h |
| 367 | $(TCC) -o$@ -c json_query_.c |
| 368 | |
| 369 | json_query_.c : $(SRCDIR)\json_query.c |
| 370 | +translate$E $** > $@ |
| 371 | |
| 372 | $(OBJDIR)\json_report$O : json_report_.c json_report.h |
| 373 | $(TCC) -o$@ -c json_report_.c |
| 374 | |
| 375 | json_report_.c : $(SRCDIR)\json_report.c |
| 376 | +translate$E $** > $@ |
| 377 | |
| 378 | $(OBJDIR)\json_tag$O : json_tag_.c json_tag.h |
| 379 | $(TCC) -o$@ -c json_tag_.c |
| 380 | |
| 381 | json_tag_.c : $(SRCDIR)\json_tag.c |
| 382 | +translate$E $** > $@ |
| 383 | |
| 384 | $(OBJDIR)\json_timeline$O : json_timeline_.c json_timeline.h |
| 385 | $(TCC) -o$@ -c json_timeline_.c |
| 386 | |
| 387 | json_timeline_.c : $(SRCDIR)\json_timeline.c |
| 388 | +translate$E $** > $@ |
| 389 | |
| 390 | $(OBJDIR)\json_user$O : json_user_.c json_user.h |
| 391 | $(TCC) -o$@ -c json_user_.c |
| 392 | |
| 393 | json_user_.c : $(SRCDIR)\json_user.c |
| 394 | +translate$E $** > $@ |
| 395 | |
| 396 | $(OBJDIR)\json_wiki$O : json_wiki_.c json_wiki.h |
| 397 | $(TCC) -o$@ -c json_wiki_.c |
| 398 | |
| 399 | json_wiki_.c : $(SRCDIR)\json_wiki.c |
| 400 | +translate$E $** > $@ |
| 401 | |
| 402 | $(OBJDIR)\leaf$O : leaf_.c leaf.h |
| 403 | $(TCC) -o$@ -c leaf_.c |
| 404 | |
| 405 | leaf_.c : $(SRCDIR)\leaf.c |
| @@ -580,7 +662,7 @@ | |
| 662 | |
| 663 | zip_.c : $(SRCDIR)\zip.c |
| 664 | +translate$E $** > $@ |
| 665 | |
| 666 | headers: makeheaders$E page_index.h VERSION.h |
| 667 | +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 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 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_diff_.c:json_diff.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.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 login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h path_.c:path.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.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 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 update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winhttp_.c:winhttp.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h |
| 668 | @copy /Y nul: headers |
| 669 |
+116
-2
| --- win/Makefile.mingw | ||
| +++ win/Makefile.mingw | ||
| @@ -110,10 +110,21 @@ | ||
| 110 | 110 | $(SRCDIR)/http_socket.c \ |
| 111 | 111 | $(SRCDIR)/http_ssl.c \ |
| 112 | 112 | $(SRCDIR)/http_transport.c \ |
| 113 | 113 | $(SRCDIR)/import.c \ |
| 114 | 114 | $(SRCDIR)/info.c \ |
| 115 | + $(SRCDIR)/json.c \ | |
| 116 | + $(SRCDIR)/json_artifact.c \ | |
| 117 | + $(SRCDIR)/json_branch.c \ | |
| 118 | + $(SRCDIR)/json_diff.c \ | |
| 119 | + $(SRCDIR)/json_login.c \ | |
| 120 | + $(SRCDIR)/json_query.c \ | |
| 121 | + $(SRCDIR)/json_report.c \ | |
| 122 | + $(SRCDIR)/json_tag.c \ | |
| 123 | + $(SRCDIR)/json_timeline.c \ | |
| 124 | + $(SRCDIR)/json_user.c \ | |
| 125 | + $(SRCDIR)/json_wiki.c \ | |
| 115 | 126 | $(SRCDIR)/leaf.c \ |
| 116 | 127 | $(SRCDIR)/login.c \ |
| 117 | 128 | $(SRCDIR)/main.c \ |
| 118 | 129 | $(SRCDIR)/manifest.c \ |
| 119 | 130 | $(SRCDIR)/md5.c \ |
| @@ -194,10 +205,21 @@ | ||
| 194 | 205 | $(OBJDIR)/http_socket_.c \ |
| 195 | 206 | $(OBJDIR)/http_ssl_.c \ |
| 196 | 207 | $(OBJDIR)/http_transport_.c \ |
| 197 | 208 | $(OBJDIR)/import_.c \ |
| 198 | 209 | $(OBJDIR)/info_.c \ |
| 210 | + $(OBJDIR)/json_.c \ | |
| 211 | + $(OBJDIR)/json_artifact_.c \ | |
| 212 | + $(OBJDIR)/json_branch_.c \ | |
| 213 | + $(OBJDIR)/json_diff_.c \ | |
| 214 | + $(OBJDIR)/json_login_.c \ | |
| 215 | + $(OBJDIR)/json_query_.c \ | |
| 216 | + $(OBJDIR)/json_report_.c \ | |
| 217 | + $(OBJDIR)/json_tag_.c \ | |
| 218 | + $(OBJDIR)/json_timeline_.c \ | |
| 219 | + $(OBJDIR)/json_user_.c \ | |
| 220 | + $(OBJDIR)/json_wiki_.c \ | |
| 199 | 221 | $(OBJDIR)/leaf_.c \ |
| 200 | 222 | $(OBJDIR)/login_.c \ |
| 201 | 223 | $(OBJDIR)/main_.c \ |
| 202 | 224 | $(OBJDIR)/manifest_.c \ |
| 203 | 225 | $(OBJDIR)/md5_.c \ |
| @@ -278,10 +300,21 @@ | ||
| 278 | 300 | $(OBJDIR)/http_socket.o \ |
| 279 | 301 | $(OBJDIR)/http_ssl.o \ |
| 280 | 302 | $(OBJDIR)/http_transport.o \ |
| 281 | 303 | $(OBJDIR)/import.o \ |
| 282 | 304 | $(OBJDIR)/info.o \ |
| 305 | + $(OBJDIR)/json.o \ | |
| 306 | + $(OBJDIR)/json_artifact.o \ | |
| 307 | + $(OBJDIR)/json_branch.o \ | |
| 308 | + $(OBJDIR)/json_diff.o \ | |
| 309 | + $(OBJDIR)/json_login.o \ | |
| 310 | + $(OBJDIR)/json_query.o \ | |
| 311 | + $(OBJDIR)/json_report.o \ | |
| 312 | + $(OBJDIR)/json_tag.o \ | |
| 313 | + $(OBJDIR)/json_timeline.o \ | |
| 314 | + $(OBJDIR)/json_user.o \ | |
| 315 | + $(OBJDIR)/json_wiki.o \ | |
| 283 | 316 | $(OBJDIR)/leaf.o \ |
| 284 | 317 | $(OBJDIR)/login.o \ |
| 285 | 318 | $(OBJDIR)/main.o \ |
| 286 | 319 | $(OBJDIR)/manifest.o \ |
| 287 | 320 | $(OBJDIR)/md5.o \ |
| @@ -363,11 +396,11 @@ | ||
| 363 | 396 | $(TCLSH) test/tester.tcl $(APPNAME) |
| 364 | 397 | |
| 365 | 398 | $(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(VERSION) |
| 366 | 399 | $(VERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h |
| 367 | 400 | |
| 368 | -EXTRAOBJ = $(OBJDIR)/sqlite3.o $(OBJDIR)/shell.o $(OBJDIR)/th.o $(OBJDIR)/th_lang.o | |
| 401 | +EXTRAOBJ = $(OBJDIR)/sqlite3.o $(OBJDIR)/shell.o $(OBJDIR)/th.o $(OBJDIR)/th_lang.o $(OBJDIR)/cson_amalgamation.o | |
| 369 | 402 | |
| 370 | 403 | $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) $(OBJDIR)/icon.o |
| 371 | 404 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/icon.o |
| 372 | 405 | |
| 373 | 406 | # This rule prevents make from using its default rules to try build |
| @@ -388,11 +421,11 @@ | ||
| 388 | 421 | |
| 389 | 422 | |
| 390 | 423 | $(OBJDIR)/page_index.h: $(TRANS_SRC) $(OBJDIR)/mkindex |
| 391 | 424 | $(MKINDEX) $(TRANS_SRC) >$@ |
| 392 | 425 | $(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/makeheaders $(OBJDIR)/VERSION.h |
| 393 | - $(MAKEHEADERS) $(OBJDIR)/add_.c:$(OBJDIR)/add.h $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h $(OBJDIR)/clearsign_.c:$(OBJDIR)/clearsign.h $(OBJDIR)/clone_.c:$(OBJDIR)/clone.h $(OBJDIR)/comformat_.c:$(OBJDIR)/comformat.h $(OBJDIR)/configure_.c:$(OBJDIR)/configure.h $(OBJDIR)/content_.c:$(OBJDIR)/content.h $(OBJDIR)/db_.c:$(OBJDIR)/db.h $(OBJDIR)/delta_.c:$(OBJDIR)/delta.h $(OBJDIR)/deltacmd_.c:$(OBJDIR)/deltacmd.h $(OBJDIR)/descendants_.c:$(OBJDIR)/descendants.h $(OBJDIR)/diff_.c:$(OBJDIR)/diff.h $(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h $(OBJDIR)/doc_.c:$(OBJDIR)/doc.h $(OBJDIR)/encode_.c:$(OBJDIR)/encode.h $(OBJDIR)/event_.c:$(OBJDIR)/event.h $(OBJDIR)/export_.c:$(OBJDIR)/export.h $(OBJDIR)/file_.c:$(OBJDIR)/file.h $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h $(OBJDIR)/glob_.c:$(OBJDIR)/glob.h $(OBJDIR)/graph_.c:$(OBJDIR)/graph.h $(OBJDIR)/gzip_.c:$(OBJDIR)/gzip.h $(OBJDIR)/http_.c:$(OBJDIR)/http.h $(OBJDIR)/http_socket_.c:$(OBJDIR)/http_socket.h $(OBJDIR)/http_ssl_.c:$(OBJDIR)/http_ssl.h $(OBJDIR)/http_transport_.c:$(OBJDIR)/http_transport.h $(OBJDIR)/import_.c:$(OBJDIR)/import.h $(OBJDIR)/info_.c:$(OBJDIR)/info.h $(OBJDIR)/leaf_.c:$(OBJDIR)/leaf.h $(OBJDIR)/login_.c:$(OBJDIR)/login.h $(OBJDIR)/main_.c:$(OBJDIR)/main.h $(OBJDIR)/manifest_.c:$(OBJDIR)/manifest.h $(OBJDIR)/md5_.c:$(OBJDIR)/md5.h $(OBJDIR)/merge_.c:$(OBJDIR)/merge.h $(OBJDIR)/merge3_.c:$(OBJDIR)/merge3.h $(OBJDIR)/name_.c:$(OBJDIR)/name.h $(OBJDIR)/path_.c:$(OBJDIR)/path.h $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h $(OBJDIR)/report_.c:$(OBJDIR)/report.h $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h $(OBJDIR)/search_.c:$(OBJDIR)/search.h $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h $(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h $(OBJDIR)/shun_.c:$(OBJDIR)/shun.h $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h $(OBJDIR)/style_.c:$(OBJDIR)/style.h $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h $(OBJDIR)/update_.c:$(OBJDIR)/update.h $(OBJDIR)/url_.c:$(OBJDIR)/url.h $(OBJDIR)/user_.c:$(OBJDIR)/user.h $(OBJDIR)/verify_.c:$(OBJDIR)/verify.h $(OBJDIR)/vfile_.c:$(OBJDIR)/vfile.h $(OBJDIR)/wiki_.c:$(OBJDIR)/wiki.h $(OBJDIR)/wikiformat_.c:$(OBJDIR)/wikiformat.h $(OBJDIR)/winhttp_.c:$(OBJDIR)/winhttp.h $(OBJDIR)/xfer_.c:$(OBJDIR)/xfer.h $(OBJDIR)/zip_.c:$(OBJDIR)/zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h $(OBJDIR)/VERSION.h | |
| 426 | + $(MAKEHEADERS) $(OBJDIR)/add_.c:$(OBJDIR)/add.h $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h $(OBJDIR)/clearsign_.c:$(OBJDIR)/clearsign.h $(OBJDIR)/clone_.c:$(OBJDIR)/clone.h $(OBJDIR)/comformat_.c:$(OBJDIR)/comformat.h $(OBJDIR)/configure_.c:$(OBJDIR)/configure.h $(OBJDIR)/content_.c:$(OBJDIR)/content.h $(OBJDIR)/db_.c:$(OBJDIR)/db.h $(OBJDIR)/delta_.c:$(OBJDIR)/delta.h $(OBJDIR)/deltacmd_.c:$(OBJDIR)/deltacmd.h $(OBJDIR)/descendants_.c:$(OBJDIR)/descendants.h $(OBJDIR)/diff_.c:$(OBJDIR)/diff.h $(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h $(OBJDIR)/doc_.c:$(OBJDIR)/doc.h $(OBJDIR)/encode_.c:$(OBJDIR)/encode.h $(OBJDIR)/event_.c:$(OBJDIR)/event.h $(OBJDIR)/export_.c:$(OBJDIR)/export.h $(OBJDIR)/file_.c:$(OBJDIR)/file.h $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h $(OBJDIR)/glob_.c:$(OBJDIR)/glob.h $(OBJDIR)/graph_.c:$(OBJDIR)/graph.h $(OBJDIR)/gzip_.c:$(OBJDIR)/gzip.h $(OBJDIR)/http_.c:$(OBJDIR)/http.h $(OBJDIR)/http_socket_.c:$(OBJDIR)/http_socket.h $(OBJDIR)/http_ssl_.c:$(OBJDIR)/http_ssl.h $(OBJDIR)/http_transport_.c:$(OBJDIR)/http_transport.h $(OBJDIR)/import_.c:$(OBJDIR)/import.h $(OBJDIR)/info_.c:$(OBJDIR)/info.h $(OBJDIR)/json_.c:$(OBJDIR)/json.h $(OBJDIR)/json_artifact_.c:$(OBJDIR)/json_artifact.h $(OBJDIR)/json_branch_.c:$(OBJDIR)/json_branch.h $(OBJDIR)/json_diff_.c:$(OBJDIR)/json_diff.h $(OBJDIR)/json_login_.c:$(OBJDIR)/json_login.h $(OBJDIR)/json_query_.c:$(OBJDIR)/json_query.h $(OBJDIR)/json_report_.c:$(OBJDIR)/json_report.h $(OBJDIR)/json_tag_.c:$(OBJDIR)/json_tag.h $(OBJDIR)/json_timeline_.c:$(OBJDIR)/json_timeline.h $(OBJDIR)/json_user_.c:$(OBJDIR)/json_user.h $(OBJDIR)/json_wiki_.c:$(OBJDIR)/json_wiki.h $(OBJDIR)/leaf_.c:$(OBJDIR)/leaf.h $(OBJDIR)/login_.c:$(OBJDIR)/login.h $(OBJDIR)/main_.c:$(OBJDIR)/main.h $(OBJDIR)/manifest_.c:$(OBJDIR)/manifest.h $(OBJDIR)/md5_.c:$(OBJDIR)/md5.h $(OBJDIR)/merge_.c:$(OBJDIR)/merge.h $(OBJDIR)/merge3_.c:$(OBJDIR)/merge3.h $(OBJDIR)/name_.c:$(OBJDIR)/name.h $(OBJDIR)/path_.c:$(OBJDIR)/path.h $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h $(OBJDIR)/report_.c:$(OBJDIR)/report.h $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h $(OBJDIR)/search_.c:$(OBJDIR)/search.h $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h $(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h $(OBJDIR)/shun_.c:$(OBJDIR)/shun.h $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h $(OBJDIR)/style_.c:$(OBJDIR)/style.h $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h $(OBJDIR)/update_.c:$(OBJDIR)/update.h $(OBJDIR)/url_.c:$(OBJDIR)/url.h $(OBJDIR)/user_.c:$(OBJDIR)/user.h $(OBJDIR)/verify_.c:$(OBJDIR)/verify.h $(OBJDIR)/vfile_.c:$(OBJDIR)/vfile.h $(OBJDIR)/wiki_.c:$(OBJDIR)/wiki.h $(OBJDIR)/wikiformat_.c:$(OBJDIR)/wikiformat.h $(OBJDIR)/winhttp_.c:$(OBJDIR)/winhttp.h $(OBJDIR)/xfer_.c:$(OBJDIR)/xfer.h $(OBJDIR)/zip_.c:$(OBJDIR)/zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h $(OBJDIR)/VERSION.h | |
| 394 | 427 | echo Done >$(OBJDIR)/headers |
| 395 | 428 | |
| 396 | 429 | $(OBJDIR)/headers: Makefile |
| 397 | 430 | Makefile: |
| 398 | 431 | $(OBJDIR)/add_.c: $(SRCDIR)/add.c $(OBJDIR)/translate |
| @@ -659,10 +692,87 @@ | ||
| 659 | 692 | |
| 660 | 693 | $(OBJDIR)/info.o: $(OBJDIR)/info_.c $(OBJDIR)/info.h $(SRCDIR)/config.h |
| 661 | 694 | $(XTCC) -o $(OBJDIR)/info.o -c $(OBJDIR)/info_.c |
| 662 | 695 | |
| 663 | 696 | info.h: $(OBJDIR)/headers |
| 697 | +$(OBJDIR)/json_.c: $(SRCDIR)/json.c $(OBJDIR)/translate | |
| 698 | + $(TRANSLATE) $(SRCDIR)/json.c >$(OBJDIR)/json_.c | |
| 699 | + | |
| 700 | +$(OBJDIR)/json.o: $(OBJDIR)/json_.c $(OBJDIR)/json.h $(SRCDIR)/config.h | |
| 701 | + $(XTCC) -o $(OBJDIR)/json.o -c $(OBJDIR)/json_.c | |
| 702 | + | |
| 703 | +json.h: $(OBJDIR)/headers | |
| 704 | +$(OBJDIR)/json_artifact_.c: $(SRCDIR)/json_artifact.c $(OBJDIR)/translate | |
| 705 | + $(TRANSLATE) $(SRCDIR)/json_artifact.c >$(OBJDIR)/json_artifact_.c | |
| 706 | + | |
| 707 | +$(OBJDIR)/json_artifact.o: $(OBJDIR)/json_artifact_.c $(OBJDIR)/json_artifact.h $(SRCDIR)/config.h | |
| 708 | + $(XTCC) -o $(OBJDIR)/json_artifact.o -c $(OBJDIR)/json_artifact_.c | |
| 709 | + | |
| 710 | +json_artifact.h: $(OBJDIR)/headers | |
| 711 | +$(OBJDIR)/json_branch_.c: $(SRCDIR)/json_branch.c $(OBJDIR)/translate | |
| 712 | + $(TRANSLATE) $(SRCDIR)/json_branch.c >$(OBJDIR)/json_branch_.c | |
| 713 | + | |
| 714 | +$(OBJDIR)/json_branch.o: $(OBJDIR)/json_branch_.c $(OBJDIR)/json_branch.h $(SRCDIR)/config.h | |
| 715 | + $(XTCC) -o $(OBJDIR)/json_branch.o -c $(OBJDIR)/json_branch_.c | |
| 716 | + | |
| 717 | +json_branch.h: $(OBJDIR)/headers | |
| 718 | +$(OBJDIR)/json_diff_.c: $(SRCDIR)/json_diff.c $(OBJDIR)/translate | |
| 719 | + $(TRANSLATE) $(SRCDIR)/json_diff.c >$(OBJDIR)/json_diff_.c | |
| 720 | + | |
| 721 | +$(OBJDIR)/json_diff.o: $(OBJDIR)/json_diff_.c $(OBJDIR)/json_diff.h $(SRCDIR)/config.h | |
| 722 | + $(XTCC) -o $(OBJDIR)/json_diff.o -c $(OBJDIR)/json_diff_.c | |
| 723 | + | |
| 724 | +json_diff.h: $(OBJDIR)/headers | |
| 725 | +$(OBJDIR)/json_login_.c: $(SRCDIR)/json_login.c $(OBJDIR)/translate | |
| 726 | + $(TRANSLATE) $(SRCDIR)/json_login.c >$(OBJDIR)/json_login_.c | |
| 727 | + | |
| 728 | +$(OBJDIR)/json_login.o: $(OBJDIR)/json_login_.c $(OBJDIR)/json_login.h $(SRCDIR)/config.h | |
| 729 | + $(XTCC) -o $(OBJDIR)/json_login.o -c $(OBJDIR)/json_login_.c | |
| 730 | + | |
| 731 | +json_login.h: $(OBJDIR)/headers | |
| 732 | +$(OBJDIR)/json_query_.c: $(SRCDIR)/json_query.c $(OBJDIR)/translate | |
| 733 | + $(TRANSLATE) $(SRCDIR)/json_query.c >$(OBJDIR)/json_query_.c | |
| 734 | + | |
| 735 | +$(OBJDIR)/json_query.o: $(OBJDIR)/json_query_.c $(OBJDIR)/json_query.h $(SRCDIR)/config.h | |
| 736 | + $(XTCC) -o $(OBJDIR)/json_query.o -c $(OBJDIR)/json_query_.c | |
| 737 | + | |
| 738 | +json_query.h: $(OBJDIR)/headers | |
| 739 | +$(OBJDIR)/json_report_.c: $(SRCDIR)/json_report.c $(OBJDIR)/translate | |
| 740 | + $(TRANSLATE) $(SRCDIR)/json_report.c >$(OBJDIR)/json_report_.c | |
| 741 | + | |
| 742 | +$(OBJDIR)/json_report.o: $(OBJDIR)/json_report_.c $(OBJDIR)/json_report.h $(SRCDIR)/config.h | |
| 743 | + $(XTCC) -o $(OBJDIR)/json_report.o -c $(OBJDIR)/json_report_.c | |
| 744 | + | |
| 745 | +json_report.h: $(OBJDIR)/headers | |
| 746 | +$(OBJDIR)/json_tag_.c: $(SRCDIR)/json_tag.c $(OBJDIR)/translate | |
| 747 | + $(TRANSLATE) $(SRCDIR)/json_tag.c >$(OBJDIR)/json_tag_.c | |
| 748 | + | |
| 749 | +$(OBJDIR)/json_tag.o: $(OBJDIR)/json_tag_.c $(OBJDIR)/json_tag.h $(SRCDIR)/config.h | |
| 750 | + $(XTCC) -o $(OBJDIR)/json_tag.o -c $(OBJDIR)/json_tag_.c | |
| 751 | + | |
| 752 | +json_tag.h: $(OBJDIR)/headers | |
| 753 | +$(OBJDIR)/json_timeline_.c: $(SRCDIR)/json_timeline.c $(OBJDIR)/translate | |
| 754 | + $(TRANSLATE) $(SRCDIR)/json_timeline.c >$(OBJDIR)/json_timeline_.c | |
| 755 | + | |
| 756 | +$(OBJDIR)/json_timeline.o: $(OBJDIR)/json_timeline_.c $(OBJDIR)/json_timeline.h $(SRCDIR)/config.h | |
| 757 | + $(XTCC) -o $(OBJDIR)/json_timeline.o -c $(OBJDIR)/json_timeline_.c | |
| 758 | + | |
| 759 | +json_timeline.h: $(OBJDIR)/headers | |
| 760 | +$(OBJDIR)/json_user_.c: $(SRCDIR)/json_user.c $(OBJDIR)/translate | |
| 761 | + $(TRANSLATE) $(SRCDIR)/json_user.c >$(OBJDIR)/json_user_.c | |
| 762 | + | |
| 763 | +$(OBJDIR)/json_user.o: $(OBJDIR)/json_user_.c $(OBJDIR)/json_user.h $(SRCDIR)/config.h | |
| 764 | + $(XTCC) -o $(OBJDIR)/json_user.o -c $(OBJDIR)/json_user_.c | |
| 765 | + | |
| 766 | +json_user.h: $(OBJDIR)/headers | |
| 767 | +$(OBJDIR)/json_wiki_.c: $(SRCDIR)/json_wiki.c $(OBJDIR)/translate | |
| 768 | + $(TRANSLATE) $(SRCDIR)/json_wiki.c >$(OBJDIR)/json_wiki_.c | |
| 769 | + | |
| 770 | +$(OBJDIR)/json_wiki.o: $(OBJDIR)/json_wiki_.c $(OBJDIR)/json_wiki.h $(SRCDIR)/config.h | |
| 771 | + $(XTCC) -o $(OBJDIR)/json_wiki.o -c $(OBJDIR)/json_wiki_.c | |
| 772 | + | |
| 773 | +json_wiki.h: $(OBJDIR)/headers | |
| 664 | 774 | $(OBJDIR)/leaf_.c: $(SRCDIR)/leaf.c $(OBJDIR)/translate |
| 665 | 775 | $(TRANSLATE) $(SRCDIR)/leaf.c >$(OBJDIR)/leaf_.c |
| 666 | 776 | |
| 667 | 777 | $(OBJDIR)/leaf.o: $(OBJDIR)/leaf_.c $(OBJDIR)/leaf.h $(SRCDIR)/config.h |
| 668 | 778 | $(XTCC) -o $(OBJDIR)/leaf.o -c $(OBJDIR)/leaf_.c |
| @@ -970,14 +1080,18 @@ | ||
| 970 | 1080 | |
| 971 | 1081 | zip.h: $(OBJDIR)/headers |
| 972 | 1082 | $(OBJDIR)/sqlite3.o: $(SRCDIR)/sqlite3.c |
| 973 | 1083 | $(XTCC) -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_STAT3 -Dlocaltime=fossil_localtime -DSQLITE_ENABLE_LOCKING_STYLE=0 -c $(SRCDIR)/sqlite3.c -o $(OBJDIR)/sqlite3.o |
| 974 | 1084 | |
| 1085 | +$(OBJDIR)/cson_amalgamation.o: $(SRCDIR)/cson_amalgamation.c | |
| 1086 | + $(XTCC) -c $(SRCDIR)/cson_amalgamation.c -o $(OBJDIR)/cson_amalgamation.o -DCSON_FOSSIL_MODE | |
| 1087 | + | |
| 1088 | +$(OBJDIR)/json.o $(OBJDIR)/json_artifact.o $(OBJDIR)/json_branch.o $(OBJDIR)/json_diff.o $(OBJDIR)/json_login.o $(OBJDIR)/json_query.o $(OBJDIR)/json_report.o $(OBJDIR)/json_tag.o $(OBJDIR)/json_timeline.o $(OBJDIR)/json_user.o $(OBJDIR)/json_wiki.o : $(SRCDIR)/json_detail.h | |
| 975 | 1089 | $(OBJDIR)/shell.o: $(SRCDIR)/shell.c $(SRCDIR)/sqlite3.h |
| 976 | 1090 | $(XTCC) -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -c $(SRCDIR)/shell.c -o $(OBJDIR)/shell.o |
| 977 | 1091 | |
| 978 | 1092 | $(OBJDIR)/th.o: $(SRCDIR)/th.c |
| 979 | 1093 | $(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th.c -o $(OBJDIR)/th.o |
| 980 | 1094 | |
| 981 | 1095 | $(OBJDIR)/th_lang.o: $(SRCDIR)/th_lang.c |
| 982 | 1096 | $(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th_lang.c -o $(OBJDIR)/th_lang.o |
| 983 | 1097 | |
| 984 | 1098 |
| --- win/Makefile.mingw | |
| +++ win/Makefile.mingw | |
| @@ -110,10 +110,21 @@ | |
| 110 | $(SRCDIR)/http_socket.c \ |
| 111 | $(SRCDIR)/http_ssl.c \ |
| 112 | $(SRCDIR)/http_transport.c \ |
| 113 | $(SRCDIR)/import.c \ |
| 114 | $(SRCDIR)/info.c \ |
| 115 | $(SRCDIR)/leaf.c \ |
| 116 | $(SRCDIR)/login.c \ |
| 117 | $(SRCDIR)/main.c \ |
| 118 | $(SRCDIR)/manifest.c \ |
| 119 | $(SRCDIR)/md5.c \ |
| @@ -194,10 +205,21 @@ | |
| 194 | $(OBJDIR)/http_socket_.c \ |
| 195 | $(OBJDIR)/http_ssl_.c \ |
| 196 | $(OBJDIR)/http_transport_.c \ |
| 197 | $(OBJDIR)/import_.c \ |
| 198 | $(OBJDIR)/info_.c \ |
| 199 | $(OBJDIR)/leaf_.c \ |
| 200 | $(OBJDIR)/login_.c \ |
| 201 | $(OBJDIR)/main_.c \ |
| 202 | $(OBJDIR)/manifest_.c \ |
| 203 | $(OBJDIR)/md5_.c \ |
| @@ -278,10 +300,21 @@ | |
| 278 | $(OBJDIR)/http_socket.o \ |
| 279 | $(OBJDIR)/http_ssl.o \ |
| 280 | $(OBJDIR)/http_transport.o \ |
| 281 | $(OBJDIR)/import.o \ |
| 282 | $(OBJDIR)/info.o \ |
| 283 | $(OBJDIR)/leaf.o \ |
| 284 | $(OBJDIR)/login.o \ |
| 285 | $(OBJDIR)/main.o \ |
| 286 | $(OBJDIR)/manifest.o \ |
| 287 | $(OBJDIR)/md5.o \ |
| @@ -363,11 +396,11 @@ | |
| 363 | $(TCLSH) test/tester.tcl $(APPNAME) |
| 364 | |
| 365 | $(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(VERSION) |
| 366 | $(VERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h |
| 367 | |
| 368 | EXTRAOBJ = $(OBJDIR)/sqlite3.o $(OBJDIR)/shell.o $(OBJDIR)/th.o $(OBJDIR)/th_lang.o |
| 369 | |
| 370 | $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) $(OBJDIR)/icon.o |
| 371 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/icon.o |
| 372 | |
| 373 | # This rule prevents make from using its default rules to try build |
| @@ -388,11 +421,11 @@ | |
| 388 | |
| 389 | |
| 390 | $(OBJDIR)/page_index.h: $(TRANS_SRC) $(OBJDIR)/mkindex |
| 391 | $(MKINDEX) $(TRANS_SRC) >$@ |
| 392 | $(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/makeheaders $(OBJDIR)/VERSION.h |
| 393 | $(MAKEHEADERS) $(OBJDIR)/add_.c:$(OBJDIR)/add.h $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h $(OBJDIR)/clearsign_.c:$(OBJDIR)/clearsign.h $(OBJDIR)/clone_.c:$(OBJDIR)/clone.h $(OBJDIR)/comformat_.c:$(OBJDIR)/comformat.h $(OBJDIR)/configure_.c:$(OBJDIR)/configure.h $(OBJDIR)/content_.c:$(OBJDIR)/content.h $(OBJDIR)/db_.c:$(OBJDIR)/db.h $(OBJDIR)/delta_.c:$(OBJDIR)/delta.h $(OBJDIR)/deltacmd_.c:$(OBJDIR)/deltacmd.h $(OBJDIR)/descendants_.c:$(OBJDIR)/descendants.h $(OBJDIR)/diff_.c:$(OBJDIR)/diff.h $(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h $(OBJDIR)/doc_.c:$(OBJDIR)/doc.h $(OBJDIR)/encode_.c:$(OBJDIR)/encode.h $(OBJDIR)/event_.c:$(OBJDIR)/event.h $(OBJDIR)/export_.c:$(OBJDIR)/export.h $(OBJDIR)/file_.c:$(OBJDIR)/file.h $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h $(OBJDIR)/glob_.c:$(OBJDIR)/glob.h $(OBJDIR)/graph_.c:$(OBJDIR)/graph.h $(OBJDIR)/gzip_.c:$(OBJDIR)/gzip.h $(OBJDIR)/http_.c:$(OBJDIR)/http.h $(OBJDIR)/http_socket_.c:$(OBJDIR)/http_socket.h $(OBJDIR)/http_ssl_.c:$(OBJDIR)/http_ssl.h $(OBJDIR)/http_transport_.c:$(OBJDIR)/http_transport.h $(OBJDIR)/import_.c:$(OBJDIR)/import.h $(OBJDIR)/info_.c:$(OBJDIR)/info.h $(OBJDIR)/leaf_.c:$(OBJDIR)/leaf.h $(OBJDIR)/login_.c:$(OBJDIR)/login.h $(OBJDIR)/main_.c:$(OBJDIR)/main.h $(OBJDIR)/manifest_.c:$(OBJDIR)/manifest.h $(OBJDIR)/md5_.c:$(OBJDIR)/md5.h $(OBJDIR)/merge_.c:$(OBJDIR)/merge.h $(OBJDIR)/merge3_.c:$(OBJDIR)/merge3.h $(OBJDIR)/name_.c:$(OBJDIR)/name.h $(OBJDIR)/path_.c:$(OBJDIR)/path.h $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h $(OBJDIR)/report_.c:$(OBJDIR)/report.h $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h $(OBJDIR)/search_.c:$(OBJDIR)/search.h $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h $(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h $(OBJDIR)/shun_.c:$(OBJDIR)/shun.h $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h $(OBJDIR)/style_.c:$(OBJDIR)/style.h $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h $(OBJDIR)/update_.c:$(OBJDIR)/update.h $(OBJDIR)/url_.c:$(OBJDIR)/url.h $(OBJDIR)/user_.c:$(OBJDIR)/user.h $(OBJDIR)/verify_.c:$(OBJDIR)/verify.h $(OBJDIR)/vfile_.c:$(OBJDIR)/vfile.h $(OBJDIR)/wiki_.c:$(OBJDIR)/wiki.h $(OBJDIR)/wikiformat_.c:$(OBJDIR)/wikiformat.h $(OBJDIR)/winhttp_.c:$(OBJDIR)/winhttp.h $(OBJDIR)/xfer_.c:$(OBJDIR)/xfer.h $(OBJDIR)/zip_.c:$(OBJDIR)/zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h $(OBJDIR)/VERSION.h |
| 394 | echo Done >$(OBJDIR)/headers |
| 395 | |
| 396 | $(OBJDIR)/headers: Makefile |
| 397 | Makefile: |
| 398 | $(OBJDIR)/add_.c: $(SRCDIR)/add.c $(OBJDIR)/translate |
| @@ -659,10 +692,87 @@ | |
| 659 | |
| 660 | $(OBJDIR)/info.o: $(OBJDIR)/info_.c $(OBJDIR)/info.h $(SRCDIR)/config.h |
| 661 | $(XTCC) -o $(OBJDIR)/info.o -c $(OBJDIR)/info_.c |
| 662 | |
| 663 | info.h: $(OBJDIR)/headers |
| 664 | $(OBJDIR)/leaf_.c: $(SRCDIR)/leaf.c $(OBJDIR)/translate |
| 665 | $(TRANSLATE) $(SRCDIR)/leaf.c >$(OBJDIR)/leaf_.c |
| 666 | |
| 667 | $(OBJDIR)/leaf.o: $(OBJDIR)/leaf_.c $(OBJDIR)/leaf.h $(SRCDIR)/config.h |
| 668 | $(XTCC) -o $(OBJDIR)/leaf.o -c $(OBJDIR)/leaf_.c |
| @@ -970,14 +1080,18 @@ | |
| 970 | |
| 971 | zip.h: $(OBJDIR)/headers |
| 972 | $(OBJDIR)/sqlite3.o: $(SRCDIR)/sqlite3.c |
| 973 | $(XTCC) -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_STAT3 -Dlocaltime=fossil_localtime -DSQLITE_ENABLE_LOCKING_STYLE=0 -c $(SRCDIR)/sqlite3.c -o $(OBJDIR)/sqlite3.o |
| 974 | |
| 975 | $(OBJDIR)/shell.o: $(SRCDIR)/shell.c $(SRCDIR)/sqlite3.h |
| 976 | $(XTCC) -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -c $(SRCDIR)/shell.c -o $(OBJDIR)/shell.o |
| 977 | |
| 978 | $(OBJDIR)/th.o: $(SRCDIR)/th.c |
| 979 | $(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th.c -o $(OBJDIR)/th.o |
| 980 | |
| 981 | $(OBJDIR)/th_lang.o: $(SRCDIR)/th_lang.c |
| 982 | $(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th_lang.c -o $(OBJDIR)/th_lang.o |
| 983 | |
| 984 |
| --- win/Makefile.mingw | |
| +++ win/Makefile.mingw | |
| @@ -110,10 +110,21 @@ | |
| 110 | $(SRCDIR)/http_socket.c \ |
| 111 | $(SRCDIR)/http_ssl.c \ |
| 112 | $(SRCDIR)/http_transport.c \ |
| 113 | $(SRCDIR)/import.c \ |
| 114 | $(SRCDIR)/info.c \ |
| 115 | $(SRCDIR)/json.c \ |
| 116 | $(SRCDIR)/json_artifact.c \ |
| 117 | $(SRCDIR)/json_branch.c \ |
| 118 | $(SRCDIR)/json_diff.c \ |
| 119 | $(SRCDIR)/json_login.c \ |
| 120 | $(SRCDIR)/json_query.c \ |
| 121 | $(SRCDIR)/json_report.c \ |
| 122 | $(SRCDIR)/json_tag.c \ |
| 123 | $(SRCDIR)/json_timeline.c \ |
| 124 | $(SRCDIR)/json_user.c \ |
| 125 | $(SRCDIR)/json_wiki.c \ |
| 126 | $(SRCDIR)/leaf.c \ |
| 127 | $(SRCDIR)/login.c \ |
| 128 | $(SRCDIR)/main.c \ |
| 129 | $(SRCDIR)/manifest.c \ |
| 130 | $(SRCDIR)/md5.c \ |
| @@ -194,10 +205,21 @@ | |
| 205 | $(OBJDIR)/http_socket_.c \ |
| 206 | $(OBJDIR)/http_ssl_.c \ |
| 207 | $(OBJDIR)/http_transport_.c \ |
| 208 | $(OBJDIR)/import_.c \ |
| 209 | $(OBJDIR)/info_.c \ |
| 210 | $(OBJDIR)/json_.c \ |
| 211 | $(OBJDIR)/json_artifact_.c \ |
| 212 | $(OBJDIR)/json_branch_.c \ |
| 213 | $(OBJDIR)/json_diff_.c \ |
| 214 | $(OBJDIR)/json_login_.c \ |
| 215 | $(OBJDIR)/json_query_.c \ |
| 216 | $(OBJDIR)/json_report_.c \ |
| 217 | $(OBJDIR)/json_tag_.c \ |
| 218 | $(OBJDIR)/json_timeline_.c \ |
| 219 | $(OBJDIR)/json_user_.c \ |
| 220 | $(OBJDIR)/json_wiki_.c \ |
| 221 | $(OBJDIR)/leaf_.c \ |
| 222 | $(OBJDIR)/login_.c \ |
| 223 | $(OBJDIR)/main_.c \ |
| 224 | $(OBJDIR)/manifest_.c \ |
| 225 | $(OBJDIR)/md5_.c \ |
| @@ -278,10 +300,21 @@ | |
| 300 | $(OBJDIR)/http_socket.o \ |
| 301 | $(OBJDIR)/http_ssl.o \ |
| 302 | $(OBJDIR)/http_transport.o \ |
| 303 | $(OBJDIR)/import.o \ |
| 304 | $(OBJDIR)/info.o \ |
| 305 | $(OBJDIR)/json.o \ |
| 306 | $(OBJDIR)/json_artifact.o \ |
| 307 | $(OBJDIR)/json_branch.o \ |
| 308 | $(OBJDIR)/json_diff.o \ |
| 309 | $(OBJDIR)/json_login.o \ |
| 310 | $(OBJDIR)/json_query.o \ |
| 311 | $(OBJDIR)/json_report.o \ |
| 312 | $(OBJDIR)/json_tag.o \ |
| 313 | $(OBJDIR)/json_timeline.o \ |
| 314 | $(OBJDIR)/json_user.o \ |
| 315 | $(OBJDIR)/json_wiki.o \ |
| 316 | $(OBJDIR)/leaf.o \ |
| 317 | $(OBJDIR)/login.o \ |
| 318 | $(OBJDIR)/main.o \ |
| 319 | $(OBJDIR)/manifest.o \ |
| 320 | $(OBJDIR)/md5.o \ |
| @@ -363,11 +396,11 @@ | |
| 396 | $(TCLSH) test/tester.tcl $(APPNAME) |
| 397 | |
| 398 | $(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(VERSION) |
| 399 | $(VERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h |
| 400 | |
| 401 | EXTRAOBJ = $(OBJDIR)/sqlite3.o $(OBJDIR)/shell.o $(OBJDIR)/th.o $(OBJDIR)/th_lang.o $(OBJDIR)/cson_amalgamation.o |
| 402 | |
| 403 | $(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) $(OBJDIR)/icon.o |
| 404 | $(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/icon.o |
| 405 | |
| 406 | # This rule prevents make from using its default rules to try build |
| @@ -388,11 +421,11 @@ | |
| 421 | |
| 422 | |
| 423 | $(OBJDIR)/page_index.h: $(TRANS_SRC) $(OBJDIR)/mkindex |
| 424 | $(MKINDEX) $(TRANS_SRC) >$@ |
| 425 | $(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/makeheaders $(OBJDIR)/VERSION.h |
| 426 | $(MAKEHEADERS) $(OBJDIR)/add_.c:$(OBJDIR)/add.h $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h $(OBJDIR)/clearsign_.c:$(OBJDIR)/clearsign.h $(OBJDIR)/clone_.c:$(OBJDIR)/clone.h $(OBJDIR)/comformat_.c:$(OBJDIR)/comformat.h $(OBJDIR)/configure_.c:$(OBJDIR)/configure.h $(OBJDIR)/content_.c:$(OBJDIR)/content.h $(OBJDIR)/db_.c:$(OBJDIR)/db.h $(OBJDIR)/delta_.c:$(OBJDIR)/delta.h $(OBJDIR)/deltacmd_.c:$(OBJDIR)/deltacmd.h $(OBJDIR)/descendants_.c:$(OBJDIR)/descendants.h $(OBJDIR)/diff_.c:$(OBJDIR)/diff.h $(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h $(OBJDIR)/doc_.c:$(OBJDIR)/doc.h $(OBJDIR)/encode_.c:$(OBJDIR)/encode.h $(OBJDIR)/event_.c:$(OBJDIR)/event.h $(OBJDIR)/export_.c:$(OBJDIR)/export.h $(OBJDIR)/file_.c:$(OBJDIR)/file.h $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h $(OBJDIR)/glob_.c:$(OBJDIR)/glob.h $(OBJDIR)/graph_.c:$(OBJDIR)/graph.h $(OBJDIR)/gzip_.c:$(OBJDIR)/gzip.h $(OBJDIR)/http_.c:$(OBJDIR)/http.h $(OBJDIR)/http_socket_.c:$(OBJDIR)/http_socket.h $(OBJDIR)/http_ssl_.c:$(OBJDIR)/http_ssl.h $(OBJDIR)/http_transport_.c:$(OBJDIR)/http_transport.h $(OBJDIR)/import_.c:$(OBJDIR)/import.h $(OBJDIR)/info_.c:$(OBJDIR)/info.h $(OBJDIR)/json_.c:$(OBJDIR)/json.h $(OBJDIR)/json_artifact_.c:$(OBJDIR)/json_artifact.h $(OBJDIR)/json_branch_.c:$(OBJDIR)/json_branch.h $(OBJDIR)/json_diff_.c:$(OBJDIR)/json_diff.h $(OBJDIR)/json_login_.c:$(OBJDIR)/json_login.h $(OBJDIR)/json_query_.c:$(OBJDIR)/json_query.h $(OBJDIR)/json_report_.c:$(OBJDIR)/json_report.h $(OBJDIR)/json_tag_.c:$(OBJDIR)/json_tag.h $(OBJDIR)/json_timeline_.c:$(OBJDIR)/json_timeline.h $(OBJDIR)/json_user_.c:$(OBJDIR)/json_user.h $(OBJDIR)/json_wiki_.c:$(OBJDIR)/json_wiki.h $(OBJDIR)/leaf_.c:$(OBJDIR)/leaf.h $(OBJDIR)/login_.c:$(OBJDIR)/login.h $(OBJDIR)/main_.c:$(OBJDIR)/main.h $(OBJDIR)/manifest_.c:$(OBJDIR)/manifest.h $(OBJDIR)/md5_.c:$(OBJDIR)/md5.h $(OBJDIR)/merge_.c:$(OBJDIR)/merge.h $(OBJDIR)/merge3_.c:$(OBJDIR)/merge3.h $(OBJDIR)/name_.c:$(OBJDIR)/name.h $(OBJDIR)/path_.c:$(OBJDIR)/path.h $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h $(OBJDIR)/report_.c:$(OBJDIR)/report.h $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h $(OBJDIR)/search_.c:$(OBJDIR)/search.h $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h $(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h $(OBJDIR)/shun_.c:$(OBJDIR)/shun.h $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h $(OBJDIR)/style_.c:$(OBJDIR)/style.h $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h $(OBJDIR)/update_.c:$(OBJDIR)/update.h $(OBJDIR)/url_.c:$(OBJDIR)/url.h $(OBJDIR)/user_.c:$(OBJDIR)/user.h $(OBJDIR)/verify_.c:$(OBJDIR)/verify.h $(OBJDIR)/vfile_.c:$(OBJDIR)/vfile.h $(OBJDIR)/wiki_.c:$(OBJDIR)/wiki.h $(OBJDIR)/wikiformat_.c:$(OBJDIR)/wikiformat.h $(OBJDIR)/winhttp_.c:$(OBJDIR)/winhttp.h $(OBJDIR)/xfer_.c:$(OBJDIR)/xfer.h $(OBJDIR)/zip_.c:$(OBJDIR)/zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h $(OBJDIR)/VERSION.h |
| 427 | echo Done >$(OBJDIR)/headers |
| 428 | |
| 429 | $(OBJDIR)/headers: Makefile |
| 430 | Makefile: |
| 431 | $(OBJDIR)/add_.c: $(SRCDIR)/add.c $(OBJDIR)/translate |
| @@ -659,10 +692,87 @@ | |
| 692 | |
| 693 | $(OBJDIR)/info.o: $(OBJDIR)/info_.c $(OBJDIR)/info.h $(SRCDIR)/config.h |
| 694 | $(XTCC) -o $(OBJDIR)/info.o -c $(OBJDIR)/info_.c |
| 695 | |
| 696 | info.h: $(OBJDIR)/headers |
| 697 | $(OBJDIR)/json_.c: $(SRCDIR)/json.c $(OBJDIR)/translate |
| 698 | $(TRANSLATE) $(SRCDIR)/json.c >$(OBJDIR)/json_.c |
| 699 | |
| 700 | $(OBJDIR)/json.o: $(OBJDIR)/json_.c $(OBJDIR)/json.h $(SRCDIR)/config.h |
| 701 | $(XTCC) -o $(OBJDIR)/json.o -c $(OBJDIR)/json_.c |
| 702 | |
| 703 | json.h: $(OBJDIR)/headers |
| 704 | $(OBJDIR)/json_artifact_.c: $(SRCDIR)/json_artifact.c $(OBJDIR)/translate |
| 705 | $(TRANSLATE) $(SRCDIR)/json_artifact.c >$(OBJDIR)/json_artifact_.c |
| 706 | |
| 707 | $(OBJDIR)/json_artifact.o: $(OBJDIR)/json_artifact_.c $(OBJDIR)/json_artifact.h $(SRCDIR)/config.h |
| 708 | $(XTCC) -o $(OBJDIR)/json_artifact.o -c $(OBJDIR)/json_artifact_.c |
| 709 | |
| 710 | json_artifact.h: $(OBJDIR)/headers |
| 711 | $(OBJDIR)/json_branch_.c: $(SRCDIR)/json_branch.c $(OBJDIR)/translate |
| 712 | $(TRANSLATE) $(SRCDIR)/json_branch.c >$(OBJDIR)/json_branch_.c |
| 713 | |
| 714 | $(OBJDIR)/json_branch.o: $(OBJDIR)/json_branch_.c $(OBJDIR)/json_branch.h $(SRCDIR)/config.h |
| 715 | $(XTCC) -o $(OBJDIR)/json_branch.o -c $(OBJDIR)/json_branch_.c |
| 716 | |
| 717 | json_branch.h: $(OBJDIR)/headers |
| 718 | $(OBJDIR)/json_diff_.c: $(SRCDIR)/json_diff.c $(OBJDIR)/translate |
| 719 | $(TRANSLATE) $(SRCDIR)/json_diff.c >$(OBJDIR)/json_diff_.c |
| 720 | |
| 721 | $(OBJDIR)/json_diff.o: $(OBJDIR)/json_diff_.c $(OBJDIR)/json_diff.h $(SRCDIR)/config.h |
| 722 | $(XTCC) -o $(OBJDIR)/json_diff.o -c $(OBJDIR)/json_diff_.c |
| 723 | |
| 724 | json_diff.h: $(OBJDIR)/headers |
| 725 | $(OBJDIR)/json_login_.c: $(SRCDIR)/json_login.c $(OBJDIR)/translate |
| 726 | $(TRANSLATE) $(SRCDIR)/json_login.c >$(OBJDIR)/json_login_.c |
| 727 | |
| 728 | $(OBJDIR)/json_login.o: $(OBJDIR)/json_login_.c $(OBJDIR)/json_login.h $(SRCDIR)/config.h |
| 729 | $(XTCC) -o $(OBJDIR)/json_login.o -c $(OBJDIR)/json_login_.c |
| 730 | |
| 731 | json_login.h: $(OBJDIR)/headers |
| 732 | $(OBJDIR)/json_query_.c: $(SRCDIR)/json_query.c $(OBJDIR)/translate |
| 733 | $(TRANSLATE) $(SRCDIR)/json_query.c >$(OBJDIR)/json_query_.c |
| 734 | |
| 735 | $(OBJDIR)/json_query.o: $(OBJDIR)/json_query_.c $(OBJDIR)/json_query.h $(SRCDIR)/config.h |
| 736 | $(XTCC) -o $(OBJDIR)/json_query.o -c $(OBJDIR)/json_query_.c |
| 737 | |
| 738 | json_query.h: $(OBJDIR)/headers |
| 739 | $(OBJDIR)/json_report_.c: $(SRCDIR)/json_report.c $(OBJDIR)/translate |
| 740 | $(TRANSLATE) $(SRCDIR)/json_report.c >$(OBJDIR)/json_report_.c |
| 741 | |
| 742 | $(OBJDIR)/json_report.o: $(OBJDIR)/json_report_.c $(OBJDIR)/json_report.h $(SRCDIR)/config.h |
| 743 | $(XTCC) -o $(OBJDIR)/json_report.o -c $(OBJDIR)/json_report_.c |
| 744 | |
| 745 | json_report.h: $(OBJDIR)/headers |
| 746 | $(OBJDIR)/json_tag_.c: $(SRCDIR)/json_tag.c $(OBJDIR)/translate |
| 747 | $(TRANSLATE) $(SRCDIR)/json_tag.c >$(OBJDIR)/json_tag_.c |
| 748 | |
| 749 | $(OBJDIR)/json_tag.o: $(OBJDIR)/json_tag_.c $(OBJDIR)/json_tag.h $(SRCDIR)/config.h |
| 750 | $(XTCC) -o $(OBJDIR)/json_tag.o -c $(OBJDIR)/json_tag_.c |
| 751 | |
| 752 | json_tag.h: $(OBJDIR)/headers |
| 753 | $(OBJDIR)/json_timeline_.c: $(SRCDIR)/json_timeline.c $(OBJDIR)/translate |
| 754 | $(TRANSLATE) $(SRCDIR)/json_timeline.c >$(OBJDIR)/json_timeline_.c |
| 755 | |
| 756 | $(OBJDIR)/json_timeline.o: $(OBJDIR)/json_timeline_.c $(OBJDIR)/json_timeline.h $(SRCDIR)/config.h |
| 757 | $(XTCC) -o $(OBJDIR)/json_timeline.o -c $(OBJDIR)/json_timeline_.c |
| 758 | |
| 759 | json_timeline.h: $(OBJDIR)/headers |
| 760 | $(OBJDIR)/json_user_.c: $(SRCDIR)/json_user.c $(OBJDIR)/translate |
| 761 | $(TRANSLATE) $(SRCDIR)/json_user.c >$(OBJDIR)/json_user_.c |
| 762 | |
| 763 | $(OBJDIR)/json_user.o: $(OBJDIR)/json_user_.c $(OBJDIR)/json_user.h $(SRCDIR)/config.h |
| 764 | $(XTCC) -o $(OBJDIR)/json_user.o -c $(OBJDIR)/json_user_.c |
| 765 | |
| 766 | json_user.h: $(OBJDIR)/headers |
| 767 | $(OBJDIR)/json_wiki_.c: $(SRCDIR)/json_wiki.c $(OBJDIR)/translate |
| 768 | $(TRANSLATE) $(SRCDIR)/json_wiki.c >$(OBJDIR)/json_wiki_.c |
| 769 | |
| 770 | $(OBJDIR)/json_wiki.o: $(OBJDIR)/json_wiki_.c $(OBJDIR)/json_wiki.h $(SRCDIR)/config.h |
| 771 | $(XTCC) -o $(OBJDIR)/json_wiki.o -c $(OBJDIR)/json_wiki_.c |
| 772 | |
| 773 | json_wiki.h: $(OBJDIR)/headers |
| 774 | $(OBJDIR)/leaf_.c: $(SRCDIR)/leaf.c $(OBJDIR)/translate |
| 775 | $(TRANSLATE) $(SRCDIR)/leaf.c >$(OBJDIR)/leaf_.c |
| 776 | |
| 777 | $(OBJDIR)/leaf.o: $(OBJDIR)/leaf_.c $(OBJDIR)/leaf.h $(SRCDIR)/config.h |
| 778 | $(XTCC) -o $(OBJDIR)/leaf.o -c $(OBJDIR)/leaf_.c |
| @@ -970,14 +1080,18 @@ | |
| 1080 | |
| 1081 | zip.h: $(OBJDIR)/headers |
| 1082 | $(OBJDIR)/sqlite3.o: $(SRCDIR)/sqlite3.c |
| 1083 | $(XTCC) -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_STAT3 -Dlocaltime=fossil_localtime -DSQLITE_ENABLE_LOCKING_STYLE=0 -c $(SRCDIR)/sqlite3.c -o $(OBJDIR)/sqlite3.o |
| 1084 | |
| 1085 | $(OBJDIR)/cson_amalgamation.o: $(SRCDIR)/cson_amalgamation.c |
| 1086 | $(XTCC) -c $(SRCDIR)/cson_amalgamation.c -o $(OBJDIR)/cson_amalgamation.o -DCSON_FOSSIL_MODE |
| 1087 | |
| 1088 | $(OBJDIR)/json.o $(OBJDIR)/json_artifact.o $(OBJDIR)/json_branch.o $(OBJDIR)/json_diff.o $(OBJDIR)/json_login.o $(OBJDIR)/json_query.o $(OBJDIR)/json_report.o $(OBJDIR)/json_tag.o $(OBJDIR)/json_timeline.o $(OBJDIR)/json_user.o $(OBJDIR)/json_wiki.o : $(SRCDIR)/json_detail.h |
| 1089 | $(OBJDIR)/shell.o: $(SRCDIR)/shell.c $(SRCDIR)/sqlite3.h |
| 1090 | $(XTCC) -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -c $(SRCDIR)/shell.c -o $(OBJDIR)/shell.o |
| 1091 | |
| 1092 | $(OBJDIR)/th.o: $(SRCDIR)/th.c |
| 1093 | $(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th.c -o $(OBJDIR)/th.o |
| 1094 | |
| 1095 | $(OBJDIR)/th_lang.o: $(SRCDIR)/th_lang.c |
| 1096 | $(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th_lang.c -o $(OBJDIR)/th_lang.o |
| 1097 | |
| 1098 |
+94
-3
| --- win/Makefile.msc | ||
| +++ win/Makefile.msc | ||
| @@ -36,13 +36,13 @@ | ||
| 36 | 36 | LIBS = $(ZLIB) ws2_32.lib advapi32.lib $(SSLLIB) |
| 37 | 37 | LIBDIR = -LIBPATH:$(MSCDIR)\extra\lib -LIBPATH:$(ZLIBDIR) |
| 38 | 38 | |
| 39 | 39 | SQLITE_OPTIONS = /DSQLITE_OMIT_LOAD_EXTENSION=1 /DSQLITE_THREADSAFE=0 /DSQLITE_DEFAULT_FILE_FORMAT=4 /DSQLITE_ENABLE_STAT3 /Dlocaltime=fossil_localtime /DSQLITE_ENABLE_LOCKING_STYLE=0 |
| 40 | 40 | |
| 41 | -SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.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 glob_.c graph_.c gzip_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c leaf_.c login_.c main_.c manifest_.c md5_.c merge_.c merge3_.c name_.c path_.c pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.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 update_.c url_.c user_.c verify_.c vfile_.c wiki_.c wikiformat_.c winhttp_.c xfer_.c zip_.c | |
| 41 | +SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.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 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_diff_.c json_login_.c json_query_.c json_report_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c login_.c main_.c manifest_.c md5_.c merge_.c merge3_.c name_.c path_.c pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.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 update_.c url_.c user_.c verify_.c vfile_.c wiki_.c wikiformat_.c winhttp_.c xfer_.c zip_.c | |
| 42 | 42 | |
| 43 | -OBJ = $(OX)\add$O $(OX)\allrepo$O $(OX)\attach$O $(OX)\bag$O $(OX)\bisect$O $(OX)\blob$O $(OX)\branch$O $(OX)\browse$O $(OX)\captcha$O $(OX)\cgi$O $(OX)\checkin$O $(OX)\checkout$O $(OX)\clearsign$O $(OX)\clone$O $(OX)\comformat$O $(OX)\configure$O $(OX)\content$O $(OX)\db$O $(OX)\delta$O $(OX)\deltacmd$O $(OX)\descendants$O $(OX)\diff$O $(OX)\diffcmd$O $(OX)\doc$O $(OX)\encode$O $(OX)\event$O $(OX)\export$O $(OX)\file$O $(OX)\finfo$O $(OX)\glob$O $(OX)\graph$O $(OX)\gzip$O $(OX)\http$O $(OX)\http_socket$O $(OX)\http_ssl$O $(OX)\http_transport$O $(OX)\import$O $(OX)\info$O $(OX)\leaf$O $(OX)\login$O $(OX)\main$O $(OX)\manifest$O $(OX)\md5$O $(OX)\merge$O $(OX)\merge3$O $(OX)\name$O $(OX)\path$O $(OX)\pivot$O $(OX)\popen$O $(OX)\pqueue$O $(OX)\printf$O $(OX)\rebuild$O $(OX)\report$O $(OX)\rss$O $(OX)\schema$O $(OX)\search$O $(OX)\setup$O $(OX)\sha1$O $(OX)\shun$O $(OX)\skins$O $(OX)\sqlcmd$O $(OX)\stash$O $(OX)\stat$O $(OX)\style$O $(OX)\sync$O $(OX)\tag$O $(OX)\tar$O $(OX)\th_main$O $(OX)\timeline$O $(OX)\tkt$O $(OX)\tktsetup$O $(OX)\undo$O $(OX)\update$O $(OX)\url$O $(OX)\user$O $(OX)\verify$O $(OX)\vfile$O $(OX)\wiki$O $(OX)\wikiformat$O $(OX)\winhttp$O $(OX)\xfer$O $(OX)\zip$O $(OX)\shell$O $(OX)\sqlite3$O $(OX)\th$O $(OX)\th_lang$O | |
| 43 | +OBJ = $(OX)\add$O $(OX)\allrepo$O $(OX)\attach$O $(OX)\bag$O $(OX)\bisect$O $(OX)\blob$O $(OX)\branch$O $(OX)\browse$O $(OX)\captcha$O $(OX)\cgi$O $(OX)\checkin$O $(OX)\checkout$O $(OX)\clearsign$O $(OX)\clone$O $(OX)\comformat$O $(OX)\configure$O $(OX)\content$O $(OX)\db$O $(OX)\delta$O $(OX)\deltacmd$O $(OX)\descendants$O $(OX)\diff$O $(OX)\diffcmd$O $(OX)\doc$O $(OX)\encode$O $(OX)\event$O $(OX)\export$O $(OX)\file$O $(OX)\finfo$O $(OX)\glob$O $(OX)\graph$O $(OX)\gzip$O $(OX)\http$O $(OX)\http_socket$O $(OX)\http_ssl$O $(OX)\http_transport$O $(OX)\import$O $(OX)\info$O $(OX)\json$O $(OX)\json_artifact$O $(OX)\json_branch$O $(OX)\json_diff$O $(OX)\json_login$O $(OX)\json_query$O $(OX)\json_report$O $(OX)\json_tag$O $(OX)\json_timeline$O $(OX)\json_user$O $(OX)\json_wiki$O $(OX)\leaf$O $(OX)\login$O $(OX)\main$O $(OX)\manifest$O $(OX)\md5$O $(OX)\merge$O $(OX)\merge3$O $(OX)\name$O $(OX)\path$O $(OX)\pivot$O $(OX)\popen$O $(OX)\pqueue$O $(OX)\printf$O $(OX)\rebuild$O $(OX)\report$O $(OX)\rss$O $(OX)\schema$O $(OX)\search$O $(OX)\setup$O $(OX)\sha1$O $(OX)\shun$O $(OX)\skins$O $(OX)\sqlcmd$O $(OX)\stash$O $(OX)\stat$O $(OX)\style$O $(OX)\sync$O $(OX)\tag$O $(OX)\tar$O $(OX)\th_main$O $(OX)\timeline$O $(OX)\tkt$O $(OX)\tktsetup$O $(OX)\undo$O $(OX)\update$O $(OX)\url$O $(OX)\user$O $(OX)\verify$O $(OX)\vfile$O $(OX)\wiki$O $(OX)\wikiformat$O $(OX)\winhttp$O $(OX)\xfer$O $(OX)\zip$O $(OX)\shell$O $(OX)\sqlite3$O $(OX)\th$O $(OX)\th_lang$O | |
| 44 | 44 | |
| 45 | 45 | |
| 46 | 46 | APPNAME = $(OX)\fossil$(E) |
| 47 | 47 | |
| 48 | 48 | all: $(OX) $(APPNAME) |
| @@ -88,10 +88,21 @@ | ||
| 88 | 88 | echo $(OX)\http_socket.obj >> $@ |
| 89 | 89 | echo $(OX)\http_ssl.obj >> $@ |
| 90 | 90 | echo $(OX)\http_transport.obj >> $@ |
| 91 | 91 | echo $(OX)\import.obj >> $@ |
| 92 | 92 | echo $(OX)\info.obj >> $@ |
| 93 | + echo $(OX)\json.obj >> $@ | |
| 94 | + echo $(OX)\json_artifact.obj >> $@ | |
| 95 | + echo $(OX)\json_branch.obj >> $@ | |
| 96 | + echo $(OX)\json_diff.obj >> $@ | |
| 97 | + echo $(OX)\json_login.obj >> $@ | |
| 98 | + echo $(OX)\json_query.obj >> $@ | |
| 99 | + echo $(OX)\json_report.obj >> $@ | |
| 100 | + echo $(OX)\json_tag.obj >> $@ | |
| 101 | + echo $(OX)\json_timeline.obj >> $@ | |
| 102 | + echo $(OX)\json_user.obj >> $@ | |
| 103 | + echo $(OX)\json_wiki.obj >> $@ | |
| 93 | 104 | echo $(OX)\leaf.obj >> $@ |
| 94 | 105 | echo $(OX)\login.obj >> $@ |
| 95 | 106 | echo $(OX)\main.obj >> $@ |
| 96 | 107 | echo $(OX)\manifest.obj >> $@ |
| 97 | 108 | echo $(OX)\md5.obj >> $@ |
| @@ -170,10 +181,12 @@ | ||
| 170 | 181 | $(OX)\th_lang$O : $(SRCDIR)\th_lang.c |
| 171 | 182 | $(TCC) /Fo$@ -c $** |
| 172 | 183 | |
| 173 | 184 | VERSION.h : mkversion$E $B\manifest.uuid $B\manifest $B\VERSION |
| 174 | 185 | $** > $@ |
| 186 | +$(OBJDIR)\cson_amalgamation.h : $(SRCDIR)\cson_amalgamation.h | |
| 187 | + cp $(SRCDIR)\cson_amalgamation.h $@ | |
| 175 | 188 | |
| 176 | 189 | page_index.h: mkindex$E $(SRC) |
| 177 | 190 | $** > $@ |
| 178 | 191 | |
| 179 | 192 | clean: |
| @@ -182,10 +195,22 @@ | ||
| 182 | 195 | -del headers linkopts |
| 183 | 196 | |
| 184 | 197 | realclean: |
| 185 | 198 | -del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E |
| 186 | 199 | |
| 200 | +$(OBJDIR)\json$O : $(SRCDIR)\json_detail.h | |
| 201 | +$(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h | |
| 202 | +$(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h | |
| 203 | +$(OBJDIR)\json_diff$O : $(SRCDIR)\json_detail.h | |
| 204 | +$(OBJDIR)\json_login$O : $(SRCDIR)\json_detail.h | |
| 205 | +$(OBJDIR)\json_query$O : $(SRCDIR)\json_detail.h | |
| 206 | +$(OBJDIR)\json_report$O : $(SRCDIR)\json_detail.h | |
| 207 | +$(OBJDIR)\json_tag$O : $(SRCDIR)\json_detail.h | |
| 208 | +$(OBJDIR)\json_timeline$O : $(SRCDIR)\json_detail.h | |
| 209 | +$(OBJDIR)\json_user$O : $(SRCDIR)\json_detail.h | |
| 210 | +$(OBJDIR)\json_wiki$O : $(SRCDIR)\json_detail.h | |
| 211 | + | |
| 187 | 212 | |
| 188 | 213 | $(OX)\add$O : add_.c add.h |
| 189 | 214 | $(TCC) /Fo$@ -c add_.c |
| 190 | 215 | |
| 191 | 216 | add_.c : $(SRCDIR)\add.c |
| @@ -410,10 +435,76 @@ | ||
| 410 | 435 | $(OX)\info$O : info_.c info.h |
| 411 | 436 | $(TCC) /Fo$@ -c info_.c |
| 412 | 437 | |
| 413 | 438 | info_.c : $(SRCDIR)\info.c |
| 414 | 439 | translate$E $** > $@ |
| 440 | + | |
| 441 | +$(OX)\json$O : json_.c json.h | |
| 442 | + $(TCC) /Fo$@ -c json_.c | |
| 443 | + | |
| 444 | +json_.c : $(SRCDIR)\json.c | |
| 445 | + translate$E $** > $@ | |
| 446 | + | |
| 447 | +$(OX)\json_artifact$O : json_artifact_.c json_artifact.h | |
| 448 | + $(TCC) /Fo$@ -c json_artifact_.c | |
| 449 | + | |
| 450 | +json_artifact_.c : $(SRCDIR)\json_artifact.c | |
| 451 | + translate$E $** > $@ | |
| 452 | + | |
| 453 | +$(OX)\json_branch$O : json_branch_.c json_branch.h | |
| 454 | + $(TCC) /Fo$@ -c json_branch_.c | |
| 455 | + | |
| 456 | +json_branch_.c : $(SRCDIR)\json_branch.c | |
| 457 | + translate$E $** > $@ | |
| 458 | + | |
| 459 | +$(OX)\json_diff$O : json_diff_.c json_diff.h | |
| 460 | + $(TCC) /Fo$@ -c json_diff_.c | |
| 461 | + | |
| 462 | +json_diff_.c : $(SRCDIR)\json_diff.c | |
| 463 | + translate$E $** > $@ | |
| 464 | + | |
| 465 | +$(OX)\json_login$O : json_login_.c json_login.h | |
| 466 | + $(TCC) /Fo$@ -c json_login_.c | |
| 467 | + | |
| 468 | +json_login_.c : $(SRCDIR)\json_login.c | |
| 469 | + translate$E $** > $@ | |
| 470 | + | |
| 471 | +$(OX)\json_query$O : json_query_.c json_query.h | |
| 472 | + $(TCC) /Fo$@ -c json_query_.c | |
| 473 | + | |
| 474 | +json_query_.c : $(SRCDIR)\json_query.c | |
| 475 | + translate$E $** > $@ | |
| 476 | + | |
| 477 | +$(OX)\json_report$O : json_report_.c json_report.h | |
| 478 | + $(TCC) /Fo$@ -c json_report_.c | |
| 479 | + | |
| 480 | +json_report_.c : $(SRCDIR)\json_report.c | |
| 481 | + translate$E $** > $@ | |
| 482 | + | |
| 483 | +$(OX)\json_tag$O : json_tag_.c json_tag.h | |
| 484 | + $(TCC) /Fo$@ -c json_tag_.c | |
| 485 | + | |
| 486 | +json_tag_.c : $(SRCDIR)\json_tag.c | |
| 487 | + translate$E $** > $@ | |
| 488 | + | |
| 489 | +$(OX)\json_timeline$O : json_timeline_.c json_timeline.h | |
| 490 | + $(TCC) /Fo$@ -c json_timeline_.c | |
| 491 | + | |
| 492 | +json_timeline_.c : $(SRCDIR)\json_timeline.c | |
| 493 | + translate$E $** > $@ | |
| 494 | + | |
| 495 | +$(OX)\json_user$O : json_user_.c json_user.h | |
| 496 | + $(TCC) /Fo$@ -c json_user_.c | |
| 497 | + | |
| 498 | +json_user_.c : $(SRCDIR)\json_user.c | |
| 499 | + translate$E $** > $@ | |
| 500 | + | |
| 501 | +$(OX)\json_wiki$O : json_wiki_.c json_wiki.h | |
| 502 | + $(TCC) /Fo$@ -c json_wiki_.c | |
| 503 | + | |
| 504 | +json_wiki_.c : $(SRCDIR)\json_wiki.c | |
| 505 | + translate$E $** > $@ | |
| 415 | 506 | |
| 416 | 507 | $(OX)\leaf$O : leaf_.c leaf.h |
| 417 | 508 | $(TCC) /Fo$@ -c leaf_.c |
| 418 | 509 | |
| 419 | 510 | leaf_.c : $(SRCDIR)\leaf.c |
| @@ -676,7 +767,7 @@ | ||
| 676 | 767 | |
| 677 | 768 | zip_.c : $(SRCDIR)\zip.c |
| 678 | 769 | translate$E $** > $@ |
| 679 | 770 | |
| 680 | 771 | headers: makeheaders$E page_index.h VERSION.h |
| 681 | - 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 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 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 leaf_.c:leaf.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h path_.c:path.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.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 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 update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winhttp_.c:winhttp.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h | |
| 772 | + 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 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 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_diff_.c:json_diff.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.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 login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h path_.c:path.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.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 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 update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winhttp_.c:winhttp.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h | |
| 682 | 773 | @copy /Y nul: headers |
| 683 | 774 |
| --- win/Makefile.msc | |
| +++ win/Makefile.msc | |
| @@ -36,13 +36,13 @@ | |
| 36 | LIBS = $(ZLIB) ws2_32.lib advapi32.lib $(SSLLIB) |
| 37 | LIBDIR = -LIBPATH:$(MSCDIR)\extra\lib -LIBPATH:$(ZLIBDIR) |
| 38 | |
| 39 | SQLITE_OPTIONS = /DSQLITE_OMIT_LOAD_EXTENSION=1 /DSQLITE_THREADSAFE=0 /DSQLITE_DEFAULT_FILE_FORMAT=4 /DSQLITE_ENABLE_STAT3 /Dlocaltime=fossil_localtime /DSQLITE_ENABLE_LOCKING_STYLE=0 |
| 40 | |
| 41 | SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.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 glob_.c graph_.c gzip_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c leaf_.c login_.c main_.c manifest_.c md5_.c merge_.c merge3_.c name_.c path_.c pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.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 update_.c url_.c user_.c verify_.c vfile_.c wiki_.c wikiformat_.c winhttp_.c xfer_.c zip_.c |
| 42 | |
| 43 | OBJ = $(OX)\add$O $(OX)\allrepo$O $(OX)\attach$O $(OX)\bag$O $(OX)\bisect$O $(OX)\blob$O $(OX)\branch$O $(OX)\browse$O $(OX)\captcha$O $(OX)\cgi$O $(OX)\checkin$O $(OX)\checkout$O $(OX)\clearsign$O $(OX)\clone$O $(OX)\comformat$O $(OX)\configure$O $(OX)\content$O $(OX)\db$O $(OX)\delta$O $(OX)\deltacmd$O $(OX)\descendants$O $(OX)\diff$O $(OX)\diffcmd$O $(OX)\doc$O $(OX)\encode$O $(OX)\event$O $(OX)\export$O $(OX)\file$O $(OX)\finfo$O $(OX)\glob$O $(OX)\graph$O $(OX)\gzip$O $(OX)\http$O $(OX)\http_socket$O $(OX)\http_ssl$O $(OX)\http_transport$O $(OX)\import$O $(OX)\info$O $(OX)\leaf$O $(OX)\login$O $(OX)\main$O $(OX)\manifest$O $(OX)\md5$O $(OX)\merge$O $(OX)\merge3$O $(OX)\name$O $(OX)\path$O $(OX)\pivot$O $(OX)\popen$O $(OX)\pqueue$O $(OX)\printf$O $(OX)\rebuild$O $(OX)\report$O $(OX)\rss$O $(OX)\schema$O $(OX)\search$O $(OX)\setup$O $(OX)\sha1$O $(OX)\shun$O $(OX)\skins$O $(OX)\sqlcmd$O $(OX)\stash$O $(OX)\stat$O $(OX)\style$O $(OX)\sync$O $(OX)\tag$O $(OX)\tar$O $(OX)\th_main$O $(OX)\timeline$O $(OX)\tkt$O $(OX)\tktsetup$O $(OX)\undo$O $(OX)\update$O $(OX)\url$O $(OX)\user$O $(OX)\verify$O $(OX)\vfile$O $(OX)\wiki$O $(OX)\wikiformat$O $(OX)\winhttp$O $(OX)\xfer$O $(OX)\zip$O $(OX)\shell$O $(OX)\sqlite3$O $(OX)\th$O $(OX)\th_lang$O |
| 44 | |
| 45 | |
| 46 | APPNAME = $(OX)\fossil$(E) |
| 47 | |
| 48 | all: $(OX) $(APPNAME) |
| @@ -88,10 +88,21 @@ | |
| 88 | echo $(OX)\http_socket.obj >> $@ |
| 89 | echo $(OX)\http_ssl.obj >> $@ |
| 90 | echo $(OX)\http_transport.obj >> $@ |
| 91 | echo $(OX)\import.obj >> $@ |
| 92 | echo $(OX)\info.obj >> $@ |
| 93 | echo $(OX)\leaf.obj >> $@ |
| 94 | echo $(OX)\login.obj >> $@ |
| 95 | echo $(OX)\main.obj >> $@ |
| 96 | echo $(OX)\manifest.obj >> $@ |
| 97 | echo $(OX)\md5.obj >> $@ |
| @@ -170,10 +181,12 @@ | |
| 170 | $(OX)\th_lang$O : $(SRCDIR)\th_lang.c |
| 171 | $(TCC) /Fo$@ -c $** |
| 172 | |
| 173 | VERSION.h : mkversion$E $B\manifest.uuid $B\manifest $B\VERSION |
| 174 | $** > $@ |
| 175 | |
| 176 | page_index.h: mkindex$E $(SRC) |
| 177 | $** > $@ |
| 178 | |
| 179 | clean: |
| @@ -182,10 +195,22 @@ | |
| 182 | -del headers linkopts |
| 183 | |
| 184 | realclean: |
| 185 | -del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E |
| 186 | |
| 187 | |
| 188 | $(OX)\add$O : add_.c add.h |
| 189 | $(TCC) /Fo$@ -c add_.c |
| 190 | |
| 191 | add_.c : $(SRCDIR)\add.c |
| @@ -410,10 +435,76 @@ | |
| 410 | $(OX)\info$O : info_.c info.h |
| 411 | $(TCC) /Fo$@ -c info_.c |
| 412 | |
| 413 | info_.c : $(SRCDIR)\info.c |
| 414 | translate$E $** > $@ |
| 415 | |
| 416 | $(OX)\leaf$O : leaf_.c leaf.h |
| 417 | $(TCC) /Fo$@ -c leaf_.c |
| 418 | |
| 419 | leaf_.c : $(SRCDIR)\leaf.c |
| @@ -676,7 +767,7 @@ | |
| 676 | |
| 677 | zip_.c : $(SRCDIR)\zip.c |
| 678 | translate$E $** > $@ |
| 679 | |
| 680 | headers: makeheaders$E page_index.h VERSION.h |
| 681 | 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 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 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 leaf_.c:leaf.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h path_.c:path.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.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 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 update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winhttp_.c:winhttp.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h |
| 682 | @copy /Y nul: headers |
| 683 |
| --- win/Makefile.msc | |
| +++ win/Makefile.msc | |
| @@ -36,13 +36,13 @@ | |
| 36 | LIBS = $(ZLIB) ws2_32.lib advapi32.lib $(SSLLIB) |
| 37 | LIBDIR = -LIBPATH:$(MSCDIR)\extra\lib -LIBPATH:$(ZLIBDIR) |
| 38 | |
| 39 | SQLITE_OPTIONS = /DSQLITE_OMIT_LOAD_EXTENSION=1 /DSQLITE_THREADSAFE=0 /DSQLITE_DEFAULT_FILE_FORMAT=4 /DSQLITE_ENABLE_STAT3 /Dlocaltime=fossil_localtime /DSQLITE_ENABLE_LOCKING_STYLE=0 |
| 40 | |
| 41 | SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.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 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_diff_.c json_login_.c json_query_.c json_report_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c login_.c main_.c manifest_.c md5_.c merge_.c merge3_.c name_.c path_.c pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.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 update_.c url_.c user_.c verify_.c vfile_.c wiki_.c wikiformat_.c winhttp_.c xfer_.c zip_.c |
| 42 | |
| 43 | OBJ = $(OX)\add$O $(OX)\allrepo$O $(OX)\attach$O $(OX)\bag$O $(OX)\bisect$O $(OX)\blob$O $(OX)\branch$O $(OX)\browse$O $(OX)\captcha$O $(OX)\cgi$O $(OX)\checkin$O $(OX)\checkout$O $(OX)\clearsign$O $(OX)\clone$O $(OX)\comformat$O $(OX)\configure$O $(OX)\content$O $(OX)\db$O $(OX)\delta$O $(OX)\deltacmd$O $(OX)\descendants$O $(OX)\diff$O $(OX)\diffcmd$O $(OX)\doc$O $(OX)\encode$O $(OX)\event$O $(OX)\export$O $(OX)\file$O $(OX)\finfo$O $(OX)\glob$O $(OX)\graph$O $(OX)\gzip$O $(OX)\http$O $(OX)\http_socket$O $(OX)\http_ssl$O $(OX)\http_transport$O $(OX)\import$O $(OX)\info$O $(OX)\json$O $(OX)\json_artifact$O $(OX)\json_branch$O $(OX)\json_diff$O $(OX)\json_login$O $(OX)\json_query$O $(OX)\json_report$O $(OX)\json_tag$O $(OX)\json_timeline$O $(OX)\json_user$O $(OX)\json_wiki$O $(OX)\leaf$O $(OX)\login$O $(OX)\main$O $(OX)\manifest$O $(OX)\md5$O $(OX)\merge$O $(OX)\merge3$O $(OX)\name$O $(OX)\path$O $(OX)\pivot$O $(OX)\popen$O $(OX)\pqueue$O $(OX)\printf$O $(OX)\rebuild$O $(OX)\report$O $(OX)\rss$O $(OX)\schema$O $(OX)\search$O $(OX)\setup$O $(OX)\sha1$O $(OX)\shun$O $(OX)\skins$O $(OX)\sqlcmd$O $(OX)\stash$O $(OX)\stat$O $(OX)\style$O $(OX)\sync$O $(OX)\tag$O $(OX)\tar$O $(OX)\th_main$O $(OX)\timeline$O $(OX)\tkt$O $(OX)\tktsetup$O $(OX)\undo$O $(OX)\update$O $(OX)\url$O $(OX)\user$O $(OX)\verify$O $(OX)\vfile$O $(OX)\wiki$O $(OX)\wikiformat$O $(OX)\winhttp$O $(OX)\xfer$O $(OX)\zip$O $(OX)\shell$O $(OX)\sqlite3$O $(OX)\th$O $(OX)\th_lang$O |
| 44 | |
| 45 | |
| 46 | APPNAME = $(OX)\fossil$(E) |
| 47 | |
| 48 | all: $(OX) $(APPNAME) |
| @@ -88,10 +88,21 @@ | |
| 88 | echo $(OX)\http_socket.obj >> $@ |
| 89 | echo $(OX)\http_ssl.obj >> $@ |
| 90 | echo $(OX)\http_transport.obj >> $@ |
| 91 | echo $(OX)\import.obj >> $@ |
| 92 | echo $(OX)\info.obj >> $@ |
| 93 | echo $(OX)\json.obj >> $@ |
| 94 | echo $(OX)\json_artifact.obj >> $@ |
| 95 | echo $(OX)\json_branch.obj >> $@ |
| 96 | echo $(OX)\json_diff.obj >> $@ |
| 97 | echo $(OX)\json_login.obj >> $@ |
| 98 | echo $(OX)\json_query.obj >> $@ |
| 99 | echo $(OX)\json_report.obj >> $@ |
| 100 | echo $(OX)\json_tag.obj >> $@ |
| 101 | echo $(OX)\json_timeline.obj >> $@ |
| 102 | echo $(OX)\json_user.obj >> $@ |
| 103 | echo $(OX)\json_wiki.obj >> $@ |
| 104 | echo $(OX)\leaf.obj >> $@ |
| 105 | echo $(OX)\login.obj >> $@ |
| 106 | echo $(OX)\main.obj >> $@ |
| 107 | echo $(OX)\manifest.obj >> $@ |
| 108 | echo $(OX)\md5.obj >> $@ |
| @@ -170,10 +181,12 @@ | |
| 181 | $(OX)\th_lang$O : $(SRCDIR)\th_lang.c |
| 182 | $(TCC) /Fo$@ -c $** |
| 183 | |
| 184 | VERSION.h : mkversion$E $B\manifest.uuid $B\manifest $B\VERSION |
| 185 | $** > $@ |
| 186 | $(OBJDIR)\cson_amalgamation.h : $(SRCDIR)\cson_amalgamation.h |
| 187 | cp $(SRCDIR)\cson_amalgamation.h $@ |
| 188 | |
| 189 | page_index.h: mkindex$E $(SRC) |
| 190 | $** > $@ |
| 191 | |
| 192 | clean: |
| @@ -182,10 +195,22 @@ | |
| 195 | -del headers linkopts |
| 196 | |
| 197 | realclean: |
| 198 | -del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E |
| 199 | |
| 200 | $(OBJDIR)\json$O : $(SRCDIR)\json_detail.h |
| 201 | $(OBJDIR)\json_artifact$O : $(SRCDIR)\json_detail.h |
| 202 | $(OBJDIR)\json_branch$O : $(SRCDIR)\json_detail.h |
| 203 | $(OBJDIR)\json_diff$O : $(SRCDIR)\json_detail.h |
| 204 | $(OBJDIR)\json_login$O : $(SRCDIR)\json_detail.h |
| 205 | $(OBJDIR)\json_query$O : $(SRCDIR)\json_detail.h |
| 206 | $(OBJDIR)\json_report$O : $(SRCDIR)\json_detail.h |
| 207 | $(OBJDIR)\json_tag$O : $(SRCDIR)\json_detail.h |
| 208 | $(OBJDIR)\json_timeline$O : $(SRCDIR)\json_detail.h |
| 209 | $(OBJDIR)\json_user$O : $(SRCDIR)\json_detail.h |
| 210 | $(OBJDIR)\json_wiki$O : $(SRCDIR)\json_detail.h |
| 211 | |
| 212 | |
| 213 | $(OX)\add$O : add_.c add.h |
| 214 | $(TCC) /Fo$@ -c add_.c |
| 215 | |
| 216 | add_.c : $(SRCDIR)\add.c |
| @@ -410,10 +435,76 @@ | |
| 435 | $(OX)\info$O : info_.c info.h |
| 436 | $(TCC) /Fo$@ -c info_.c |
| 437 | |
| 438 | info_.c : $(SRCDIR)\info.c |
| 439 | translate$E $** > $@ |
| 440 | |
| 441 | $(OX)\json$O : json_.c json.h |
| 442 | $(TCC) /Fo$@ -c json_.c |
| 443 | |
| 444 | json_.c : $(SRCDIR)\json.c |
| 445 | translate$E $** > $@ |
| 446 | |
| 447 | $(OX)\json_artifact$O : json_artifact_.c json_artifact.h |
| 448 | $(TCC) /Fo$@ -c json_artifact_.c |
| 449 | |
| 450 | json_artifact_.c : $(SRCDIR)\json_artifact.c |
| 451 | translate$E $** > $@ |
| 452 | |
| 453 | $(OX)\json_branch$O : json_branch_.c json_branch.h |
| 454 | $(TCC) /Fo$@ -c json_branch_.c |
| 455 | |
| 456 | json_branch_.c : $(SRCDIR)\json_branch.c |
| 457 | translate$E $** > $@ |
| 458 | |
| 459 | $(OX)\json_diff$O : json_diff_.c json_diff.h |
| 460 | $(TCC) /Fo$@ -c json_diff_.c |
| 461 | |
| 462 | json_diff_.c : $(SRCDIR)\json_diff.c |
| 463 | translate$E $** > $@ |
| 464 | |
| 465 | $(OX)\json_login$O : json_login_.c json_login.h |
| 466 | $(TCC) /Fo$@ -c json_login_.c |
| 467 | |
| 468 | json_login_.c : $(SRCDIR)\json_login.c |
| 469 | translate$E $** > $@ |
| 470 | |
| 471 | $(OX)\json_query$O : json_query_.c json_query.h |
| 472 | $(TCC) /Fo$@ -c json_query_.c |
| 473 | |
| 474 | json_query_.c : $(SRCDIR)\json_query.c |
| 475 | translate$E $** > $@ |
| 476 | |
| 477 | $(OX)\json_report$O : json_report_.c json_report.h |
| 478 | $(TCC) /Fo$@ -c json_report_.c |
| 479 | |
| 480 | json_report_.c : $(SRCDIR)\json_report.c |
| 481 | translate$E $** > $@ |
| 482 | |
| 483 | $(OX)\json_tag$O : json_tag_.c json_tag.h |
| 484 | $(TCC) /Fo$@ -c json_tag_.c |
| 485 | |
| 486 | json_tag_.c : $(SRCDIR)\json_tag.c |
| 487 | translate$E $** > $@ |
| 488 | |
| 489 | $(OX)\json_timeline$O : json_timeline_.c json_timeline.h |
| 490 | $(TCC) /Fo$@ -c json_timeline_.c |
| 491 | |
| 492 | json_timeline_.c : $(SRCDIR)\json_timeline.c |
| 493 | translate$E $** > $@ |
| 494 | |
| 495 | $(OX)\json_user$O : json_user_.c json_user.h |
| 496 | $(TCC) /Fo$@ -c json_user_.c |
| 497 | |
| 498 | json_user_.c : $(SRCDIR)\json_user.c |
| 499 | translate$E $** > $@ |
| 500 | |
| 501 | $(OX)\json_wiki$O : json_wiki_.c json_wiki.h |
| 502 | $(TCC) /Fo$@ -c json_wiki_.c |
| 503 | |
| 504 | json_wiki_.c : $(SRCDIR)\json_wiki.c |
| 505 | translate$E $** > $@ |
| 506 | |
| 507 | $(OX)\leaf$O : leaf_.c leaf.h |
| 508 | $(TCC) /Fo$@ -c leaf_.c |
| 509 | |
| 510 | leaf_.c : $(SRCDIR)\leaf.c |
| @@ -676,7 +767,7 @@ | |
| 767 | |
| 768 | zip_.c : $(SRCDIR)\zip.c |
| 769 | translate$E $** > $@ |
| 770 | |
| 771 | headers: makeheaders$E page_index.h VERSION.h |
| 772 | 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 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 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_diff_.c:json_diff.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.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 login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h path_.c:path.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.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 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 update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winhttp_.c:winhttp.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h |
| 773 | @copy /Y nul: headers |
| 774 |