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.

drh 2011-11-04 20:57 trunk merge
Commit 796dcfe0728bb2bc865db84e50432f0205d1d2fd
+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
--- 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();
--- 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
--- 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
--- 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
--- 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 '&nbsp;'),
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 '&nbsp;'),
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/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
+5
--- auto.def
+++ auto.def
@@ -9,10 +9,11 @@
99
with-tcl:path => {Enable Tcl integration, with Tcl in the specified path}
1010
internal-sqlite=1 => {Don't use the internal sqlite, use the system one}
1111
static=0 => {Link a static executable}
1212
lineedit=1 => {Disable line editing}
1313
fossil-debug=0 => {Build with fossil debugging enabled}
14
+ json=0 => {Build with fossil JSON API enabled}
1415
}
1516
1617
# sqlite wants these types if possible
1718
cc-with {-includes {stdint.h inttypes.h}} {
1819
cc-check-types uint32_t uint16_t int16_t uint8_t
@@ -62,10 +63,14 @@
6263
}
6364
6465
if {[opt-bool fossil-debug]} {
6566
define-append EXTRA_CFLAGS -DFOSSIL_DEBUG
6667
}
68
+
69
+if {[opt-bool json]} {
70
+ define-append EXTRA_CFLAGS -DFOSSIL_ENABLE_JSON
71
+}
6772
6873
if {[opt-bool static]} {
6974
# XXX: This will not work on all systems.
7075
define-append EXTRA_LDFLAGS -static
7176
}
7277
7378
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
+5
--- auto.def
+++ auto.def
@@ -9,10 +9,11 @@
99
with-tcl:path => {Enable Tcl integration, with Tcl in the specified path}
1010
internal-sqlite=1 => {Don't use the internal sqlite, use the system one}
1111
static=0 => {Link a static executable}
1212
lineedit=1 => {Disable line editing}
1313
fossil-debug=0 => {Build with fossil debugging enabled}
14
+ json=0 => {Build with fossil JSON API enabled}
1415
}
1516
1617
# sqlite wants these types if possible
1718
cc-with {-includes {stdint.h inttypes.h}} {
1819
cc-check-types uint32_t uint16_t int16_t uint8_t
@@ -62,10 +63,14 @@
6263
}
6364
6465
if {[opt-bool fossil-debug]} {
6566
define-append EXTRA_CFLAGS -DFOSSIL_DEBUG
6667
}
68
+
69
+if {[opt-bool json]} {
70
+ define-append EXTRA_CFLAGS -DFOSSIL_ENABLE_JSON
71
+}
6772
6873
if {[opt-bool static]} {
6974
# XXX: This will not work on all systems.
7075
define-append EXTRA_LDFLAGS -static
7176
}
7277
7378
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
--- 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 @@
10511051
return;
10521052
}
10531053
}
10541054
blob_append(pBlob, zIn, -1);
10551055
}
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
+}
10561083
--- 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 @@
178178
/* Do an autosync push, if requested */
179179
if( !isPrivate ) autosync(AUTOSYNC_PUSH);
180180
}
181181
182182
/*
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.
184188
*/
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 ){
187191
db_prepare(pQuery,
188192
"SELECT value FROM tagxref"
189193
" WHERE tagid=%d AND value NOT NULL "
190194
"EXCEPT "
191195
"SELECT value FROM tagxref"
@@ -193,11 +197,11 @@
193197
" AND rid IN leaf"
194198
" AND NOT %z"
195199
" ORDER BY value COLLATE nocase /*sort*/",
196200
TAG_BRANCH, TAG_BRANCH, leaf_is_closed_sql("tagxref.rid")
197201
);
198
- }else if( showAll ){
202
+ }else if( which>0 ){
199203
db_prepare(pQuery,
200204
"SELECT DISTINCT value FROM tagxref"
201205
" WHERE tagid=%d AND value NOT NULL"
202206
" AND rid IN leaf"
203207
" ORDER BY value COLLATE nocase /*sort*/",
@@ -260,11 +264,11 @@
260264
if( g.localOpen ){
261265
vid = db_lget_int("checkout", 0);
262266
zCurrent = db_text(0, "SELECT value FROM tagxref"
263267
" WHERE rid=%d AND tagid=%d", vid, TAG_BRANCH);
264268
}
265
- prepareBranchQuery(&q, showAll, showClosed);
269
+ branch_prepare_list_query(&q, showAll?1:(showClosed?-1:0));
266270
while( db_step(&q)==SQLITE_ROW ){
267271
const char *zBr = db_column_text(&q, 0);
268272
int isCur = zCurrent!=0 && fossil_strcmp(zCurrent,zBr)==0;
269273
fossil_print("%s%s\n", (isCur ? "* " : " "), zBr);
270274
}
@@ -327,11 +331,11 @@
327331
@ Closed branches are fixed and do not change (unless they are first
328332
@ reopened)</li>
329333
@ </ol>
330334
style_sidebox_end();
331335
332
- prepareBranchQuery(&q, showAll, showClosed);
336
+ branch_prepare_list_query(&q, showAll?1:(showClosed?-1:0));
333337
cnt = 0;
334338
while( db_step(&q)==SQLITE_ROW ){
335339
const char *zBr = db_column_text(&q, 0);
336340
if( cnt==0 ){
337341
if( colorTest ){
338342
--- 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 @@
412412
return x;
413413
}
414414
415415
/*
416416
** 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.
417419
*/
418
-char *captcha_decode(unsigned int seed){
420
+char const *captcha_decode(unsigned int seed){
419421
const char *zSecret;
420422
const char *z;
421423
Blob b;
422424
static char zRes[20];
423425
424426
--- 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 @@
508508
zValue = "";
509509
}
510510
if( fossil_islower(zName[0]) ){
511511
cgi_set_parameter_nocopy(zName, zValue);
512512
}
513
+#ifdef FOSSIL_ENABLE_JSON
514
+ json_setenv( zName, cson_value_new_string(zValue,strlen(zValue)) );
515
+#endif /* FOSSIL_ENABLE_JSON */
513516
}
514517
}
515518
516519
/*
517520
** *pz is a string that consists of multiple lines of text. This
@@ -680,10 +683,88 @@
680683
}
681684
}
682685
}
683686
}
684687
}
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
+
685766
686767
/*
687768
** Initialize the query parameter database. Information is pulled from
688769
** the QUERY_STRING environment variable (if it exists), from standard
689770
** input if there is POST data, and from HTTP_COOKIE.
@@ -690,19 +771,32 @@
690771
*/
691772
void cgi_init(void){
692773
char *z;
693774
const char *zType;
694775
int len;
776
+#ifdef FOSSIL_ENABLE_JSON
777
+ json_main_bootstrap();
778
+#endif
779
+ g.isHTTP = 1;
695780
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
+
696788
z = (char*)P("QUERY_STRING");
697789
if( z ){
698790
z = mprintf("%s",z);
699791
add_param_list(z, '&');
700792
}
701793
702794
z = (char*)P("REMOTE_ADDR");
703
- if( z ) g.zIpAddr = mprintf("%s", z);
795
+ if( z ){
796
+ g.zIpAddr = mprintf("%s", z);
797
+ }
704798
705799
len = atoi(PD("CONTENT_LENGTH", "0"));
706800
g.zContentType = zType = P("CONTENT_TYPE");
707801
if( len>0 && zType ){
708802
blob_zero(&g.cgiIn);
@@ -722,17 +816,36 @@
722816
}else if( fossil_strcmp(zType, "application/x-fossil-debug")==0 ){
723817
blob_read_from_channel(&g.cgiIn, g.httpIn, len);
724818
}else if( fossil_strcmp(zType, "application/x-fossil-uncompressed")==0 ){
725819
blob_read_from_channel(&g.cgiIn, g.httpIn, len);
726820
}
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 */
727845
}
728846
729
- z = (char*)P("HTTP_COOKIE");
730
- if( z ){
731
- z = mprintf("%s",z);
732
- add_param_list(z, ';');
733
- }
734847
}
735848
736849
/*
737850
** This is the comparison function used to sort the aParamQP[] array of
738851
** query parameters and cookies.
@@ -942,20 +1055,33 @@
9421055
** Panic and die while processing a webpage.
9431056
*/
9441057
NORETURN void cgi_panic(const char *zFormat, ...){
9451058
va_list ap;
9461059
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
+ }
9571083
}
9581084
9591085
/*
9601086
** Remove the first space-delimited token from a string and return
9611087
** a pointer to it. Add a NULL to the string to terminate the token.
@@ -992,11 +1118,10 @@
9921118
char *z, *zToken;
9931119
int i;
9941120
struct sockaddr_in remoteName;
9951121
socklen_t size = sizeof(struct sockaddr_in);
9961122
char zLine[2000]; /* A single line of input. */
997
-
9981123
g.fullHttpReply = 1;
9991124
if( fgets(zLine, sizeof(zLine),g.httpIn)==0 ){
10001125
malformed_request();
10011126
}
10021127
zToken = extract_token(zLine, &z);
10031128
10041129
ADDED src/cson_amalgamation.c
10051130
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
--- 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
+39 -5
--- src/db.c
+++ src/db.c
@@ -48,40 +48,59 @@
4848
Blob sql; /* The SQL for this statement */
4949
sqlite3_stmt *pStmt; /* The results of sqlite3_prepare() */
5050
Stmt *pNext, *pPrev; /* List of all unfinalized statements */
5151
int nStep; /* Number of sqlite3_step() calls */
5252
};
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}
5360
#endif /* INTERFACE */
61
+const struct Stmt empty_Stmt = empty_Stmt_m;
5462
5563
/*
5664
** Call this routine when a database error occurs.
5765
*/
5866
static void db_err(const char *zFormat, ...){
5967
va_list ap;
6068
char *z;
69
+ int rc = 1;
6170
static const char zRebuildMsg[] =
6271
"If you have recently updated your fossil executable, you might\n"
6372
"need to run \"fossil all rebuild\" to bring the repository\n"
6473
"schemas up to date.\n";
6574
va_start(ap, zFormat);
6675
z = vmprintf(zFormat, ap);
6776
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 */
6886
if( g.xferPanic ){
6987
cgi_reset_content();
7088
@ error Database\serror:\s%F(z)
71
- cgi_reply();
89
+ cgi_reply();
7290
}
73
- if( g.cgiOutput ){
91
+ else if( g.cgiOutput ){
7492
g.cgiOutput = 0;
7593
cgi_printf("<h1>Database Error</h1>\n"
7694
"<pre>%h</pre><p>%s</p>", z, zRebuildMsg);
7795
cgi_reply();
7896
}else{
7997
fprintf(stderr, "%s: %s\n\n%s", fossil_nameofexe(), z, zRebuildMsg);
8098
}
99
+ free(z);
81100
db_force_rollback();
82
- fossil_exit(1);
101
+ fossil_exit(rc);
83102
}
84103
85104
static int nBegin = 0; /* Nesting depth of BEGIN */
86105
static int doRollback = 0; /* True to force a rollback */
87106
static int nCommitHook = 0; /* Number of commit hooks */
@@ -561,11 +580,11 @@
561580
** Execute a query. Return the first column of the first row
562581
** of the result set as a string. Space to hold the string is
563582
** obtained from malloc(). If the result set is empty, return
564583
** zDefault instead.
565584
*/
566
-char *db_text(char *zDefault, const char *zSql, ...){
585
+char *db_text(char const *zDefault, const char *zSql, ...){
567586
va_list ap;
568587
Stmt s;
569588
char *z;
570589
va_start(ap, zSql);
571590
db_vprepare(&s, 0, zSql, ap);
@@ -863,15 +882,24 @@
863882
db_err("unable to find the name of a repository database");
864883
}
865884
}
866885
if( file_access(zDbName, R_OK) || file_size(zDbName)<1024 ){
867886
if( file_access(zDbName, 0) ){
887
+#ifdef FOSSIL_ENABLE_JSON
888
+ g.json.resultCode = FSL_JSON_E_DB_NOT_FOUND;
889
+#endif
868890
fossil_panic("repository does not exist or"
869891
" is in an unreadable directory: %s", zDbName);
870892
}else if( file_access(zDbName, R_OK) ){
893
+#ifdef FOSSIL_ENABLE_JSON
894
+ g.json.resultCode = FSL_JSON_E_DENIED;
895
+#endif
871896
fossil_panic("read permission denied for repository %s", zDbName);
872897
}else{
898
+#ifdef FOSSIL_ENABLE_JSON
899
+ g.json.resultCode = FSL_JSON_E_DB_NOT_VALID;
900
+#endif
873901
fossil_panic("not a valid repository: %s", zDbName);
874902
}
875903
}
876904
db_open_or_attach(zDbName, "repository");
877905
g.repositoryOpen = 1;
@@ -902,11 +930,11 @@
902930
}
903931
if( zRep==0 ){
904932
if( db_open_local()==0 ){
905933
goto rep_not_found;
906934
}
907
- zRep = db_lget("repository", 0);
935
+ zRep = db_lget("repository", 0)/*leak here*/;
908936
if( zRep==0 ){
909937
goto rep_not_found;
910938
}
911939
}
912940
db_open_repository(zRep);
@@ -914,10 +942,13 @@
914942
if( (bFlags & OPEN_ANY_SCHEMA)==0 ) db_verify_schema();
915943
return;
916944
}
917945
rep_not_found:
918946
if( (bFlags & OPEN_OK_NOT_FOUND)==0 ){
947
+#ifdef FOSSIL_ENABLE_JSON
948
+ g.json.resultCode = FSL_JSON_E_DB_NOT_FOUND;
949
+#endif
919950
fossil_fatal("use --repository or -R to specify the repository database");
920951
}
921952
}
922953
923954
/*
@@ -944,10 +975,13 @@
944975
** Verify that the repository schema is correct. If it is not correct,
945976
** issue a fatal error and die.
946977
*/
947978
void db_verify_schema(void){
948979
if( db_schema_is_outofdate() ){
980
+#ifdef FOSSIL_ENABLE_JSON
981
+ g.json.resultCode = FSL_JSON_E_DB_NEEDS_REBUILD;
982
+#endif
949983
fossil_warning("incorrect repository schema version");
950984
fossil_warning("your repository has schema version \"%s\" "
951985
"but this binary expects version \"%s\"",
952986
db_get("aux-schema",0), AUX_SCHEMA);
953987
fossil_fatal("run \"fossil rebuild\" to fix this problem");
954988
955989
ADDED src/json.c
956990
ADDED src/json_artifact.c
957991
ADDED src/json_branch.c
958992
ADDED src/json_detail.h
959993
ADDED src/json_diff.c
960994
ADDED src/json_login.c
961995
ADDED src/json_query.c
962996
ADDED src/json_report.c
963997
ADDED src/json_tag.c
964998
ADDED src/json_timeline.c
965999
ADDED src/json_user.c
9661000
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
+39 -5
--- src/db.c
+++ src/db.c
@@ -48,40 +48,59 @@
4848
Blob sql; /* The SQL for this statement */
4949
sqlite3_stmt *pStmt; /* The results of sqlite3_prepare() */
5050
Stmt *pNext, *pPrev; /* List of all unfinalized statements */
5151
int nStep; /* Number of sqlite3_step() calls */
5252
};
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}
5360
#endif /* INTERFACE */
61
+const struct Stmt empty_Stmt = empty_Stmt_m;
5462
5563
/*
5664
** Call this routine when a database error occurs.
5765
*/
5866
static void db_err(const char *zFormat, ...){
5967
va_list ap;
6068
char *z;
69
+ int rc = 1;
6170
static const char zRebuildMsg[] =
6271
"If you have recently updated your fossil executable, you might\n"
6372
"need to run \"fossil all rebuild\" to bring the repository\n"
6473
"schemas up to date.\n";
6574
va_start(ap, zFormat);
6675
z = vmprintf(zFormat, ap);
6776
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 */
6886
if( g.xferPanic ){
6987
cgi_reset_content();
7088
@ error Database\serror:\s%F(z)
71
- cgi_reply();
89
+ cgi_reply();
7290
}
73
- if( g.cgiOutput ){
91
+ else if( g.cgiOutput ){
7492
g.cgiOutput = 0;
7593
cgi_printf("<h1>Database Error</h1>\n"
7694
"<pre>%h</pre><p>%s</p>", z, zRebuildMsg);
7795
cgi_reply();
7896
}else{
7997
fprintf(stderr, "%s: %s\n\n%s", fossil_nameofexe(), z, zRebuildMsg);
8098
}
99
+ free(z);
81100
db_force_rollback();
82
- fossil_exit(1);
101
+ fossil_exit(rc);
83102
}
84103
85104
static int nBegin = 0; /* Nesting depth of BEGIN */
86105
static int doRollback = 0; /* True to force a rollback */
87106
static int nCommitHook = 0; /* Number of commit hooks */
@@ -561,11 +580,11 @@
561580
** Execute a query. Return the first column of the first row
562581
** of the result set as a string. Space to hold the string is
563582
** obtained from malloc(). If the result set is empty, return
564583
** zDefault instead.
565584
*/
566
-char *db_text(char *zDefault, const char *zSql, ...){
585
+char *db_text(char const *zDefault, const char *zSql, ...){
567586
va_list ap;
568587
Stmt s;
569588
char *z;
570589
va_start(ap, zSql);
571590
db_vprepare(&s, 0, zSql, ap);
@@ -863,15 +882,24 @@
863882
db_err("unable to find the name of a repository database");
864883
}
865884
}
866885
if( file_access(zDbName, R_OK) || file_size(zDbName)<1024 ){
867886
if( file_access(zDbName, 0) ){
887
+#ifdef FOSSIL_ENABLE_JSON
888
+ g.json.resultCode = FSL_JSON_E_DB_NOT_FOUND;
889
+#endif
868890
fossil_panic("repository does not exist or"
869891
" is in an unreadable directory: %s", zDbName);
870892
}else if( file_access(zDbName, R_OK) ){
893
+#ifdef FOSSIL_ENABLE_JSON
894
+ g.json.resultCode = FSL_JSON_E_DENIED;
895
+#endif
871896
fossil_panic("read permission denied for repository %s", zDbName);
872897
}else{
898
+#ifdef FOSSIL_ENABLE_JSON
899
+ g.json.resultCode = FSL_JSON_E_DB_NOT_VALID;
900
+#endif
873901
fossil_panic("not a valid repository: %s", zDbName);
874902
}
875903
}
876904
db_open_or_attach(zDbName, "repository");
877905
g.repositoryOpen = 1;
@@ -902,11 +930,11 @@
902930
}
903931
if( zRep==0 ){
904932
if( db_open_local()==0 ){
905933
goto rep_not_found;
906934
}
907
- zRep = db_lget("repository", 0);
935
+ zRep = db_lget("repository", 0)/*leak here*/;
908936
if( zRep==0 ){
909937
goto rep_not_found;
910938
}
911939
}
912940
db_open_repository(zRep);
@@ -914,10 +942,13 @@
914942
if( (bFlags & OPEN_ANY_SCHEMA)==0 ) db_verify_schema();
915943
return;
916944
}
917945
rep_not_found:
918946
if( (bFlags & OPEN_OK_NOT_FOUND)==0 ){
947
+#ifdef FOSSIL_ENABLE_JSON
948
+ g.json.resultCode = FSL_JSON_E_DB_NOT_FOUND;
949
+#endif
919950
fossil_fatal("use --repository or -R to specify the repository database");
920951
}
921952
}
922953
923954
/*
@@ -944,10 +975,13 @@
944975
** Verify that the repository schema is correct. If it is not correct,
945976
** issue a fatal error and die.
946977
*/
947978
void db_verify_schema(void){
948979
if( db_schema_is_outofdate() ){
980
+#ifdef FOSSIL_ENABLE_JSON
981
+ g.json.resultCode = FSL_JSON_E_DB_NEEDS_REBUILD;
982
+#endif
949983
fossil_warning("incorrect repository schema version");
950984
fossil_warning("your repository has schema version \"%s\" "
951985
"but this binary expects version \"%s\"",
952986
db_get("aux-schema",0), AUX_SCHEMA);
953987
fossil_fatal("run \"fossil rebuild\" to fix this problem");
954988
955989
ADDED src/json.c
956990
ADDED src/json_artifact.c
957991
ADDED src/json_branch.c
958992
ADDED src/json_detail.h
959993
ADDED src/json_diff.c
960994
ADDED src/json_login.c
961995
ADDED src/json_query.c
962996
ADDED src/json_report.c
963997
ADDED src/json_tag.c
964998
ADDED src/json_timeline.c
965999
ADDED src/json_user.c
9661000
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 **
--- 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
--- 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
--- 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(
--- 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"
--- 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
--- 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
--- 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,
--- 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
--- 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
--- 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
--- 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 @@
8484
**
8585
** The login cookie name is always of the form: fossil-XXXXXXXXXXXXXXXX
8686
** where the Xs are the first 16 characters of the login-group-code or
8787
** of the project-code if we are not a member of any login-group.
8888
*/
89
-static char *login_cookie_name(void){
89
+char *login_cookie_name(void){
9090
static char *zCookieName = 0;
9191
if( zCookieName==0 ){
9292
zCookieName = db_text(0,
9393
"SELECT 'fossil-' || substr(value,1,16)"
9494
" FROM config"
@@ -146,24 +146,26 @@
146146
147147
148148
/*
149149
** Check to see if the anonymous login is valid. If it is valid, return
150150
** the userid of the anonymous user.
151
+**
152
+** The zCS parameter is the "captcha seed" used for a specific
153
+** anonymous login request.
151154
*/
152
-static int isValidAnonymousLogin(
155
+int login_is_valid_anonymous(
153156
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 */
155159
){
156
- const char *zCS; /* The captcha seed value */
157160
const char *zPw; /* The correct password shown in the captcha */
158161
int uid; /* The user ID of anonymous */
159162
160163
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;
165167
zPw = captcha_decode((unsigned int)atoi(zCS));
166168
if( fossil_stricmp(zPw, zPassword)!=0 ) return 0;
167169
uid = db_int(0, "SELECT uid FROM user WHERE login='anonymous'"
168170
" AND length(pw)>0 AND length(cap)>0");
169171
return uid;
@@ -197,10 +199,163 @@
197199
"INSERT INTO accesslog(uname,ipaddr,success,mtime)"
198200
"VALUES(%Q,%Q,%d,julianday('now'));",
199201
zUsername, zIpAddr, bSuccess
200202
);
201203
}
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
+}
202357
203358
/*
204359
** Look at the HTTP_USER_AGENT parameter and try to determine if the user agent
205360
** is a manually operated browser or a bot. When in doubt, assume a bot. Return
206361
** true if we believe the agent is a real person.
@@ -281,22 +436,19 @@
281436
int anonFlag;
282437
char *zErrMsg = "";
283438
int uid; /* User id loged in user */
284439
char *zSha1Pw;
285440
const char *zIpAddr; /* IP address of requestor */
286
- char *zRemoteAddr; /* Abbreviated IP address of requestor */
287441
288442
login_check_credentials();
289443
sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0,
290444
constant_time_cmp_function, 0, 0);
291445
zUsername = P("u");
292446
zPasswd = P("p");
293447
anonFlag = P("anon")!=0;
294448
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();
298450
redirect_to_g();
299451
}
300452
if( g.perm.Password && zPasswd
301453
&& (zNew1 = P("n1"))!=0 && (zNew2 = P("n2"))!=0
302454
){
@@ -344,50 +496,20 @@
344496
return;
345497
}
346498
}
347499
}
348500
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"));
351502
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);
374504
record_login_attempt("anonymous", zIpAddr, 1);
375505
redirect_to_g();
376506
}
377507
if( zUsername!=0 && zPasswd!=0 && zPasswd[0]!=0 ){
378508
/* Attempting to log in as a user other than anonymous.
379509
*/
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);
389511
if( uid<=0 ){
390512
sleep(1);
391513
zErrMsg =
392514
@ <p><span class="loginError">
393515
@ You entered an unknown user or an incorrect password.
@@ -400,26 +522,11 @@
400522
** HASH/PROJECT/LOGIN
401523
**
402524
** where HASH is a random hex number, PROJECT is either project
403525
** code prefix, and LOGIN is the user name.
404526
*/
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);
421528
redirect_to_g();
422529
}
423530
}
424531
style_header("Login/Logout");
425532
@ %s(zErrMsg)
@@ -586,12 +693,16 @@
586693
fossil_free(zOtherRepo);
587694
return nXfer;
588695
}
589696
590697
/*
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.
593704
*/
594705
static int login_find_user(
595706
const char *zLogin, /* User name */
596707
const char *zCookie, /* Login cookie value */
597708
const char *zRemoteAddr /* Abbreviated IP address for valid login */
@@ -613,16 +724,14 @@
613724
);
614725
return uid;
615726
}
616727
617728
/*
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.
624733
*/
625734
void login_check_credentials(void){
626735
int uid = 0; /* User id */
627736
const char *zCookie; /* Text of the login cookie */
628737
const char *zIpAddr; /* Raw IP address of the requestor */
@@ -710,11 +819,11 @@
710819
}
711820
sqlite3_snprintf(sizeof(g.zCsrfToken), g.zCsrfToken, "%.10s", zHash);
712821
}
713822
714823
/* 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.
716825
*/
717826
if( uid==0 ){
718827
const char *zRemoteUser = P("REMOTE_USER");
719828
if( zRemoteUser && db_get_boolean("remote_user_ok",0) ){
720829
uid = db_int(0, "SELECT uid FROM user WHERE login=%Q"
@@ -760,11 +869,11 @@
760869
if( fossil_strcmp(g.zLogin,"nobody")==0 ){
761870
g.zLogin = 0;
762871
}
763872
764873
/* Set the capabilities */
765
- login_set_capabilities(zCap, 0);
874
+ login_replace_capabilities(zCap, 0);
766875
login_set_anon_nobody_capabilities();
767876
if( zCap[0] && !g.perm.History && db_get_boolean("auto-enable-hyperlinks",1)
768877
&& isHuman(P("HTTP_USER_AGENT")) ){
769878
g.perm.History = 1;
770879
}
@@ -793,22 +902,25 @@
793902
login_anon_once = 0;
794903
}
795904
}
796905
797906
/*
798
-** Flags passed into the 2nd argument of login_set_capabilities().
907
+** Flags passed into the 2nd argument of login_set/replace_capabilities().
799908
*/
800909
#if INTERFACE
801910
#define LOGIN_IGNORE_U 0x01 /* Ignore "u" */
802911
#define LOGIN_IGNORE_V 0x01 /* Ignore "v" */
803912
#endif
804913
805914
/*
806
-** Set the global capability flags based on a capability string.
915
+** Adds all capability flags in zCap to g.perm.
807916
*/
808917
void login_set_capabilities(const char *zCap, unsigned flags){
809918
int i;
919
+ if(NULL==zCap){
920
+ return;
921
+ }
810922
for(i=0; zCap[i]; i++){
811923
switch( zCap[i] ){
812924
case 's': g.perm.Setup = 1; /* Fall thru into Admin */
813925
case 'a': g.perm.Admin = g.perm.RdTkt = g.perm.WrTkt = g.perm.Zip =
814926
g.perm.RdWiki = g.perm.WrWiki = g.perm.NewWiki =
@@ -862,10 +974,18 @@
862974
break;
863975
}
864976
}
865977
}
866978
}
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
+}
867987
868988
/*
869989
** If the current login lacks any of the capabilities listed in
870990
** the input, then return 0. If all capabilities are present, then
871991
** return 1.
@@ -940,14 +1060,24 @@
9401060
/*
9411061
** Call this routine when the credential check fails. It causes
9421062
** a redirect to the "login" page.
9431063
*/
9441064
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
+ }
9491079
}
9501080
9511081
/*
9521082
** Call this routine if the user lacks okHistory permission. If
9531083
** the anonymous user has okHistory permission, then paint a mesage
9541084
--- 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 @@
2323
#include <string.h>
2424
#include <time.h>
2525
#include <fcntl.h>
2626
#include <sys/types.h>
2727
#include <sys/stat.h>
28
-
28
+#include <stdlib.h> /* atexit() */
2929
3030
#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
3235
#ifdef FOSSIL_ENABLE_TCL
3336
#include "tcl.h"
3437
#endif
3538
3639
/*
@@ -132,10 +135,11 @@
132135
int xlinkClusterOnly; /* Set when cloning. Only process clusters */
133136
int fTimeFormat; /* 1 for UTC. 2 for localtime. 0 not yet selected */
134137
int *aCommitFile; /* Array of files to be committed */
135138
int markPrivate; /* All new artifacts are private if true */
136139
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. */
137141
138142
int urlIsFile; /* True if a "file:" url */
139143
int urlIsHttps; /* True if a "https:" url */
140144
int urlIsSsh; /* True if an "ssh:" url */
141145
char *urlName; /* Hostname for http: or filename for file: */
@@ -148,11 +152,11 @@
148152
char *urlPasswd; /* Password for http: */
149153
char *urlCanonical; /* Canonical representation of the URL */
150154
char *urlProxyAuth; /* Proxy-Authorizer: string */
151155
char *urlFossil; /* The path of the ?fossil=path suffix on ssh: */
152156
int dontKeepUrl; /* Do not persist the URL */
153
-
157
+
154158
const char *zLogin; /* Login name. "" if not logged in. */
155159
const char *zSSLIdentity; /* Value of --ssl-identity option, filename of SSL client identity */
156160
int useLocalauth; /* No login required if from 127.0.0.1 */
157161
int noPswd; /* Logged in without password (on 127.0.0.1) */
158162
int userUid; /* Integer user id */
@@ -188,10 +192,66 @@
188192
const char *azAuxVal[MX_AUX]; /* Value of each aux() or option() value */
189193
const char **azAuxOpt[MX_AUX]; /* Options of each option() value */
190194
int anAuxCols[MX_AUX]; /* Number of columns for option() values */
191195
192196
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 */
193253
};
194254
195255
/*
196256
** Macro for debugging:
197257
*/
@@ -252,10 +312,25 @@
252312
*pIndex = m;
253313
return 0;
254314
}
255315
return 1+(cnt>1);
256316
}
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
+}
257332
258333
/*
259334
** Search g.argv for arguments "--args FILENAME". If found, then
260335
** (1) remove the two arguments from g.argv
261336
** (2) Read the file FILENAME
@@ -343,28 +418,44 @@
343418
g.tcl.argv = argv;
344419
g.tcl.interp = 0;
345420
#endif
346421
347422
sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0);
423
+ memset(&g, 0, sizeof(g));
348424
g.now = time(0);
349425
g.argc = argc;
350426
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 */
351440
expand_args_option();
352441
argc = g.argc;
353442
argv = g.argv;
354443
for(i=0; i<argc; i++) g.argv[i] = fossil_mbcs_to_utf8(argv[i]);
355444
if( getenv("GATEWAY_INTERFACE")!=0 && !find_option("nocgi", 0, 0)){
356445
zCmdName = "cgi";
446
+ g.isHTTP = 1;
357447
}else if( argc<2 ){
358448
fossil_print(
359449
"Usage: %s COMMAND ...\n"
360450
" or: %s help -- for a list of common commands\n"
361451
" or: %s help COMMMAND -- for help with the named command\n"
362452
" or: %s commands -- for a list of all commands\n",
363453
argv[0], argv[0], argv[0], argv[0]);
364454
fossil_exit(1);
365455
}else{
456
+ g.isHTTP = 0;
366457
g.fQuiet = find_option("quiet", 0, 0)!=0;
367458
g.fSqlTrace = find_option("sqltrace", 0, 0)!=0;
368459
g.fSqlStats = find_option("sqlstats", 0, 0)!=0;
369460
g.fSystemTrace = find_option("systemtrace", 0, 0)!=0;
370461
if( g.fSqlTrace ) g.fSqlStats = 1;
@@ -405,10 +496,11 @@
405496
"%s: could be any of:%s\n"
406497
"%s: use \"help\" for more information\n",
407498
argv[0], zCmdName, argv[0], blob_str(&couldbe), argv[0]);
408499
fossil_exit(1);
409500
}
501
+ atexit( fossil_atexit );
410502
aCommand[idx].xFunc();
411503
fossil_exit(0);
412504
/*NOT_REACHED*/
413505
return 0;
414506
}
@@ -444,43 +536,70 @@
444536
** routines never return.
445537
*/
446538
NORETURN void fossil_panic(const char *zFormat, ...){
447539
char *z;
448540
va_list ap;
541
+ int rc = 1;
449542
static int once = 1;
450543
mainInFatalError = 1;
451544
va_start(ap, zFormat);
452545
z = vmprintf(zFormat, ap);
453546
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);
462567
db_force_rollback();
463
- fossil_exit(1);
568
+ fossil_exit(rc);
464569
}
570
+
465571
NORETURN void fossil_fatal(const char *zFormat, ...){
466572
char *z;
573
+ int rc = 1;
467574
va_list ap;
468575
mainInFatalError = 1;
469576
va_start(ap, zFormat);
470577
z = vmprintf(zFormat, ap);
471578
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);
480599
db_force_rollback();
481
- fossil_exit(1);
600
+ fossil_exit(rc);
482601
}
483602
484603
/* This routine works like fossil_fatal() except that if called
485604
** recursively, the recursive call is a no-op.
486605
**
@@ -491,25 +610,37 @@
491610
** be prepared for this routine to return.
492611
*/
493612
void fossil_fatal_recursive(const char *zFormat, ...){
494613
char *z;
495614
va_list ap;
615
+ int rc = 1;
496616
if( mainInFatalError ) return;
497617
mainInFatalError = 1;
498618
va_start(ap, zFormat);
499619
z = vmprintf(zFormat, ap);
500620
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
+ }
508639
}
509640
db_force_rollback();
510
- fossil_exit(1);
641
+ fossil_exit(rc);
511642
}
512643
513644
514645
/* Print a warning message */
515646
void fossil_warning(const char *zFormat, ...){
@@ -516,17 +647,25 @@
516647
char *z;
517648
va_list ap;
518649
va_start(ap, zFormat);
519650
z = vmprintf(zFormat, ap);
520651
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
+ }
527665
}
666
+ free(z);
528667
}
529668
530669
/*
531670
** Malloc and free routines that cannot fail
532671
*/
@@ -1065,10 +1204,16 @@
10651204
10661205
if( szFile<1024 ){
10671206
if( zNotFound ){
10681207
cgi_redirect(zNotFound);
10691208
}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
10701215
@ <h1>Not Found</h1>
10711216
cgi_set_status(404, "not found");
10721217
cgi_reply();
10731218
}
10741219
return;
@@ -1096,11 +1241,17 @@
10961241
zPathInfo = "/xfer";
10971242
}
10981243
set_base_url();
10991244
if( zPathInfo==0 || zPathInfo[0]==0
11001245
|| (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*/;
11021253
}else{
11031254
zPath = mprintf("%s", zPathInfo);
11041255
}
11051256
11061257
/* Make g.zPath point to the first element of the path. Make
@@ -1157,10 +1308,12 @@
11571308
break;
11581309
}
11591310
if( g.zExtra ){
11601311
/* CGI parameters get this treatment elsewhere, but places like getfile
11611312
** will use g.zExtra directly.
1313
+ ** Reminder: the login mechanism uses 'name' differently, and may
1314
+ ** eventually have a problem/collision with this.
11621315
*/
11631316
dehttpize(g.zExtra);
11641317
cgi_set_parameter_nocopy("name", g.zExtra);
11651318
}
11661319
@@ -1167,17 +1320,31 @@
11671320
/* Locate the method specified by the path and execute the function
11681321
** that implements that method.
11691322
*/
11701323
if( name_search(g.zPath, aWebpage, count(aWebpage), &idx) &&
11711324
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
+ }
11751335
}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
+ }
11791346
}else{
11801347
aWebpage[idx].xFunc();
11811348
}
11821349
11831350
/* Return the result.
11841351
--- 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 @@
2323
#include <string.h>
2424
#include <time.h>
2525
#include <fcntl.h>
2626
#include <sys/types.h>
2727
#include <sys/stat.h>
28
-
28
+#include <stdlib.h> /* atexit() */
2929
3030
#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
3235
#ifdef FOSSIL_ENABLE_TCL
3336
#include "tcl.h"
3437
#endif
3538
3639
/*
@@ -132,10 +135,11 @@
132135
int xlinkClusterOnly; /* Set when cloning. Only process clusters */
133136
int fTimeFormat; /* 1 for UTC. 2 for localtime. 0 not yet selected */
134137
int *aCommitFile; /* Array of files to be committed */
135138
int markPrivate; /* All new artifacts are private if true */
136139
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. */
137141
138142
int urlIsFile; /* True if a "file:" url */
139143
int urlIsHttps; /* True if a "https:" url */
140144
int urlIsSsh; /* True if an "ssh:" url */
141145
char *urlName; /* Hostname for http: or filename for file: */
@@ -148,11 +152,11 @@
148152
char *urlPasswd; /* Password for http: */
149153
char *urlCanonical; /* Canonical representation of the URL */
150154
char *urlProxyAuth; /* Proxy-Authorizer: string */
151155
char *urlFossil; /* The path of the ?fossil=path suffix on ssh: */
152156
int dontKeepUrl; /* Do not persist the URL */
153
-
157
+
154158
const char *zLogin; /* Login name. "" if not logged in. */
155159
const char *zSSLIdentity; /* Value of --ssl-identity option, filename of SSL client identity */
156160
int useLocalauth; /* No login required if from 127.0.0.1 */
157161
int noPswd; /* Logged in without password (on 127.0.0.1) */
158162
int userUid; /* Integer user id */
@@ -188,10 +192,66 @@
188192
const char *azAuxVal[MX_AUX]; /* Value of each aux() or option() value */
189193
const char **azAuxOpt[MX_AUX]; /* Options of each option() value */
190194
int anAuxCols[MX_AUX]; /* Number of columns for option() values */
191195
192196
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 */
193253
};
194254
195255
/*
196256
** Macro for debugging:
197257
*/
@@ -252,10 +312,25 @@
252312
*pIndex = m;
253313
return 0;
254314
}
255315
return 1+(cnt>1);
256316
}
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
+}
257332
258333
/*
259334
** Search g.argv for arguments "--args FILENAME". If found, then
260335
** (1) remove the two arguments from g.argv
261336
** (2) Read the file FILENAME
@@ -343,28 +418,44 @@
343418
g.tcl.argv = argv;
344419
g.tcl.interp = 0;
345420
#endif
346421
347422
sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0);
423
+ memset(&g, 0, sizeof(g));
348424
g.now = time(0);
349425
g.argc = argc;
350426
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 */
351440
expand_args_option();
352441
argc = g.argc;
353442
argv = g.argv;
354443
for(i=0; i<argc; i++) g.argv[i] = fossil_mbcs_to_utf8(argv[i]);
355444
if( getenv("GATEWAY_INTERFACE")!=0 && !find_option("nocgi", 0, 0)){
356445
zCmdName = "cgi";
446
+ g.isHTTP = 1;
357447
}else if( argc<2 ){
358448
fossil_print(
359449
"Usage: %s COMMAND ...\n"
360450
" or: %s help -- for a list of common commands\n"
361451
" or: %s help COMMMAND -- for help with the named command\n"
362452
" or: %s commands -- for a list of all commands\n",
363453
argv[0], argv[0], argv[0], argv[0]);
364454
fossil_exit(1);
365455
}else{
456
+ g.isHTTP = 0;
366457
g.fQuiet = find_option("quiet", 0, 0)!=0;
367458
g.fSqlTrace = find_option("sqltrace", 0, 0)!=0;
368459
g.fSqlStats = find_option("sqlstats", 0, 0)!=0;
369460
g.fSystemTrace = find_option("systemtrace", 0, 0)!=0;
370461
if( g.fSqlTrace ) g.fSqlStats = 1;
@@ -405,10 +496,11 @@
405496
"%s: could be any of:%s\n"
406497
"%s: use \"help\" for more information\n",
407498
argv[0], zCmdName, argv[0], blob_str(&couldbe), argv[0]);
408499
fossil_exit(1);
409500
}
501
+ atexit( fossil_atexit );
410502
aCommand[idx].xFunc();
411503
fossil_exit(0);
412504
/*NOT_REACHED*/
413505
return 0;
414506
}
@@ -444,43 +536,70 @@
444536
** routines never return.
445537
*/
446538
NORETURN void fossil_panic(const char *zFormat, ...){
447539
char *z;
448540
va_list ap;
541
+ int rc = 1;
449542
static int once = 1;
450543
mainInFatalError = 1;
451544
va_start(ap, zFormat);
452545
z = vmprintf(zFormat, ap);
453546
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);
462567
db_force_rollback();
463
- fossil_exit(1);
568
+ fossil_exit(rc);
464569
}
570
+
465571
NORETURN void fossil_fatal(const char *zFormat, ...){
466572
char *z;
573
+ int rc = 1;
467574
va_list ap;
468575
mainInFatalError = 1;
469576
va_start(ap, zFormat);
470577
z = vmprintf(zFormat, ap);
471578
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);
480599
db_force_rollback();
481
- fossil_exit(1);
600
+ fossil_exit(rc);
482601
}
483602
484603
/* This routine works like fossil_fatal() except that if called
485604
** recursively, the recursive call is a no-op.
486605
**
@@ -491,25 +610,37 @@
491610
** be prepared for this routine to return.
492611
*/
493612
void fossil_fatal_recursive(const char *zFormat, ...){
494613
char *z;
495614
va_list ap;
615
+ int rc = 1;
496616
if( mainInFatalError ) return;
497617
mainInFatalError = 1;
498618
va_start(ap, zFormat);
499619
z = vmprintf(zFormat, ap);
500620
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
+ }
508639
}
509640
db_force_rollback();
510
- fossil_exit(1);
641
+ fossil_exit(rc);
511642
}
512643
513644
514645
/* Print a warning message */
515646
void fossil_warning(const char *zFormat, ...){
@@ -516,17 +647,25 @@
516647
char *z;
517648
va_list ap;
518649
va_start(ap, zFormat);
519650
z = vmprintf(zFormat, ap);
520651
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
+ }
527665
}
666
+ free(z);
528667
}
529668
530669
/*
531670
** Malloc and free routines that cannot fail
532671
*/
@@ -1065,10 +1204,16 @@
10651204
10661205
if( szFile<1024 ){
10671206
if( zNotFound ){
10681207
cgi_redirect(zNotFound);
10691208
}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
10701215
@ <h1>Not Found</h1>
10711216
cgi_set_status(404, "not found");
10721217
cgi_reply();
10731218
}
10741219
return;
@@ -1096,11 +1241,17 @@
10961241
zPathInfo = "/xfer";
10971242
}
10981243
set_base_url();
10991244
if( zPathInfo==0 || zPathInfo[0]==0
11001245
|| (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*/;
11021253
}else{
11031254
zPath = mprintf("%s", zPathInfo);
11041255
}
11051256
11061257
/* Make g.zPath point to the first element of the path. Make
@@ -1157,10 +1308,12 @@
11571308
break;
11581309
}
11591310
if( g.zExtra ){
11601311
/* CGI parameters get this treatment elsewhere, but places like getfile
11611312
** will use g.zExtra directly.
1313
+ ** Reminder: the login mechanism uses 'name' differently, and may
1314
+ ** eventually have a problem/collision with this.
11621315
*/
11631316
dehttpize(g.zExtra);
11641317
cgi_set_parameter_nocopy("name", g.zExtra);
11651318
}
11661319
@@ -1167,17 +1320,31 @@
11671320
/* Locate the method specified by the path and execute the function
11681321
** that implements that method.
11691322
*/
11701323
if( name_search(g.zPath, aWebpage, count(aWebpage), &idx) &&
11711324
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
+ }
11751335
}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
+ }
11791346
}else{
11801347
aWebpage[idx].xFunc();
11811348
}
11821349
11831350
/* Return the result.
11841351
--- 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 @@
4747
$(SRCDIR)/http_socket.c \
4848
$(SRCDIR)/http_ssl.c \
4949
$(SRCDIR)/http_transport.c \
5050
$(SRCDIR)/import.c \
5151
$(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 \
5263
$(SRCDIR)/leaf.c \
5364
$(SRCDIR)/login.c \
5465
$(SRCDIR)/main.c \
5566
$(SRCDIR)/manifest.c \
5667
$(SRCDIR)/md5.c \
@@ -131,10 +142,21 @@
131142
$(OBJDIR)/http_socket_.c \
132143
$(OBJDIR)/http_ssl_.c \
133144
$(OBJDIR)/http_transport_.c \
134145
$(OBJDIR)/import_.c \
135146
$(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 \
136158
$(OBJDIR)/leaf_.c \
137159
$(OBJDIR)/login_.c \
138160
$(OBJDIR)/main_.c \
139161
$(OBJDIR)/manifest_.c \
140162
$(OBJDIR)/md5_.c \
@@ -215,10 +237,21 @@
215237
$(OBJDIR)/http_socket.o \
216238
$(OBJDIR)/http_ssl.o \
217239
$(OBJDIR)/http_transport.o \
218240
$(OBJDIR)/import.o \
219241
$(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 \
220253
$(OBJDIR)/leaf.o \
221254
$(OBJDIR)/login.o \
222255
$(OBJDIR)/main.o \
223256
$(OBJDIR)/manifest.o \
224257
$(OBJDIR)/md5.o \
@@ -305,11 +338,11 @@
305338
306339
TCL_OBJ.1 =
307340
TCL_OBJ.0 = $(OBJDIR)/th_tcl.o
308341
TCL_OBJ. = $(TCL_OBJ.0)
309342
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
311344
312345
$(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ)
313346
$(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB)
314347
315348
# This rule prevents make from using its default rules to try build
@@ -323,13 +356,14 @@
323356
324357
325358
$(OBJDIR)/page_index.h: $(TRANS_SRC) $(OBJDIR)/mkindex
326359
$(OBJDIR)/mkindex $(TRANS_SRC) >$@
327360
$(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
329362
touch $(OBJDIR)/headers
330363
$(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
331365
Makefile:
332366
$(OBJDIR)/add_.c: $(SRCDIR)/add.c $(OBJDIR)/translate
333367
$(OBJDIR)/translate $(SRCDIR)/add.c >$(OBJDIR)/add_.c
334368
335369
$(OBJDIR)/add.o: $(OBJDIR)/add_.c $(OBJDIR)/add.h $(SRCDIR)/config.h
@@ -593,10 +627,87 @@
593627
594628
$(OBJDIR)/info.o: $(OBJDIR)/info_.c $(OBJDIR)/info.h $(SRCDIR)/config.h
595629
$(XTCC) -o $(OBJDIR)/info.o -c $(OBJDIR)/info_.c
596630
597631
$(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
598709
$(OBJDIR)/leaf_.c: $(SRCDIR)/leaf.c $(OBJDIR)/translate
599710
$(OBJDIR)/translate $(SRCDIR)/leaf.c >$(OBJDIR)/leaf_.c
600711
601712
$(OBJDIR)/leaf.o: $(OBJDIR)/leaf_.c $(OBJDIR)/leaf.h $(SRCDIR)/config.h
602713
$(XTCC) -o $(OBJDIR)/leaf.o -c $(OBJDIR)/leaf_.c
@@ -916,5 +1027,9 @@
9161027
$(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th_lang.c -o $(OBJDIR)/th_lang.o
9171028
9181029
$(OBJDIR)/th_tcl.o: $(SRCDIR)/th_tcl.c
9191030
$(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th_tcl.c -o $(OBJDIR)/th_tcl.o
9201031
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
+
9211036
--- 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 @@
4747
$(SRCDIR)/http_socket.c \
4848
$(SRCDIR)/http_ssl.c \
4949
$(SRCDIR)/http_transport.c \
5050
$(SRCDIR)/import.c \
5151
$(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 \
5263
$(SRCDIR)/leaf.c \
5364
$(SRCDIR)/login.c \
5465
$(SRCDIR)/main.c \
5566
$(SRCDIR)/manifest.c \
5667
$(SRCDIR)/md5.c \
@@ -131,10 +142,21 @@
131142
$(OBJDIR)/http_socket_.c \
132143
$(OBJDIR)/http_ssl_.c \
133144
$(OBJDIR)/http_transport_.c \
134145
$(OBJDIR)/import_.c \
135146
$(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 \
136158
$(OBJDIR)/leaf_.c \
137159
$(OBJDIR)/login_.c \
138160
$(OBJDIR)/main_.c \
139161
$(OBJDIR)/manifest_.c \
140162
$(OBJDIR)/md5_.c \
@@ -215,10 +237,21 @@
215237
$(OBJDIR)/http_socket.o \
216238
$(OBJDIR)/http_ssl.o \
217239
$(OBJDIR)/http_transport.o \
218240
$(OBJDIR)/import.o \
219241
$(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 \
220253
$(OBJDIR)/leaf.o \
221254
$(OBJDIR)/login.o \
222255
$(OBJDIR)/main.o \
223256
$(OBJDIR)/manifest.o \
224257
$(OBJDIR)/md5.o \
@@ -305,11 +338,11 @@
305338
306339
TCL_OBJ.1 =
307340
TCL_OBJ.0 = $(OBJDIR)/th_tcl.o
308341
TCL_OBJ. = $(TCL_OBJ.0)
309342
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
311344
312345
$(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ)
313346
$(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB)
314347
315348
# This rule prevents make from using its default rules to try build
@@ -323,13 +356,14 @@
323356
324357
325358
$(OBJDIR)/page_index.h: $(TRANS_SRC) $(OBJDIR)/mkindex
326359
$(OBJDIR)/mkindex $(TRANS_SRC) >$@
327360
$(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
329362
touch $(OBJDIR)/headers
330363
$(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
331365
Makefile:
332366
$(OBJDIR)/add_.c: $(SRCDIR)/add.c $(OBJDIR)/translate
333367
$(OBJDIR)/translate $(SRCDIR)/add.c >$(OBJDIR)/add_.c
334368
335369
$(OBJDIR)/add.o: $(OBJDIR)/add_.c $(OBJDIR)/add.h $(SRCDIR)/config.h
@@ -593,10 +627,87 @@
593627
594628
$(OBJDIR)/info.o: $(OBJDIR)/info_.c $(OBJDIR)/info.h $(SRCDIR)/config.h
595629
$(XTCC) -o $(OBJDIR)/info.o -c $(OBJDIR)/info_.c
596630
597631
$(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
598709
$(OBJDIR)/leaf_.c: $(SRCDIR)/leaf.c $(OBJDIR)/translate
599710
$(OBJDIR)/translate $(SRCDIR)/leaf.c >$(OBJDIR)/leaf_.c
600711
601712
$(OBJDIR)/leaf.o: $(OBJDIR)/leaf_.c $(OBJDIR)/leaf.h $(SRCDIR)/config.h
602713
$(XTCC) -o $(OBJDIR)/leaf.o -c $(OBJDIR)/leaf_.c
@@ -916,5 +1027,9 @@
9161027
$(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th_lang.c -o $(OBJDIR)/th_lang.o
9171028
9181029
$(OBJDIR)/th_tcl.o: $(SRCDIR)/th_tcl.c
9191030
$(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th_tcl.c -o $(OBJDIR)/th_tcl.o
9201031
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
+
9211036
--- 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 @@
5353
http
5454
http_socket
5555
http_transport
5656
import
5757
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
5869
leaf
5970
login
6071
main
6172
manifest
6273
md5
@@ -207,11 +218,12 @@
207218
EXTRAOBJ = \
208219
$(SQLITE3_OBJ.$(USE_SYSTEM_SQLITE)) \
209220
$(OBJDIR)/shell.o \
210221
$(OBJDIR)/th.o \
211222
$(OBJDIR)/th_lang.o \
212
- $(TCL_OBJ.$(FOSSIL_ENABLE_TCL))
223
+ $(TCL_OBJ.$(FOSSIL_ENABLE_TCL)) \
224
+ $(OBJDIR)/cson_amalgamation.o
213225
214226
$(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ)
215227
$(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB)
216228
217229
# This rule prevents make from using its default rules to try build
@@ -230,17 +242,19 @@
230242
append mhargs " \$(OBJDIR)/${s}_.c:\$(OBJDIR)/$s.h"
231243
set extra_h($s) {}
232244
}
233245
append mhargs " \$(SRCDIR)/sqlite3.h"
234246
append mhargs " \$(SRCDIR)/th.h"
247
+#append mhargs " \$(SRCDIR)/cson_amalgamation.h"
235248
append mhargs " \$(OBJDIR)/VERSION.h"
236249
writeln "\$(OBJDIR)/page_index.h: \$(TRANS_SRC) \$(OBJDIR)/mkindex"
237250
writeln "\t\$(OBJDIR)/mkindex \$(TRANS_SRC) >$@"
238251
writeln "\$(OBJDIR)/headers:\t\$(OBJDIR)/page_index.h \$(OBJDIR)/makeheaders \$(OBJDIR)/VERSION.h"
239252
writeln "\t\$(OBJDIR)/makeheaders $mhargs"
240253
writeln "\ttouch \$(OBJDIR)/headers"
241254
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"
242256
writeln "Makefile:"
243257
set extra_h(main) \$(OBJDIR)/page_index.h
244258
245259
foreach s [lsort $src] {
246260
writeln "\$(OBJDIR)/${s}_.c:\t\$(SRCDIR)/$s.c \$(OBJDIR)/translate"
@@ -272,10 +286,16 @@
272286
writeln "\$(OBJDIR)/th_lang.o:\t\$(SRCDIR)/th_lang.c"
273287
writeln "\t\$(XTCC) -I\$(SRCDIR) -c \$(SRCDIR)/th_lang.c -o \$(OBJDIR)/th_lang.o\n"
274288
275289
writeln "\$(OBJDIR)/th_tcl.o:\t\$(SRCDIR)/th_tcl.c"
276290
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
+}
277297
278298
close $output_file
279299
#
280300
# End of the main.mk output
281301
##############################################################################
@@ -420,11 +440,12 @@
420440
421441
EXTRAOBJ = \
422442
$(OBJDIR)/sqlite3.o \
423443
$(OBJDIR)/shell.o \
424444
$(OBJDIR)/th.o \
425
- $(OBJDIR)/th_lang.o
445
+ $(OBJDIR)/th_lang.o \
446
+ $(OBJDIR)/cson_amalgamation.o
426447
427448
$(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) $(OBJDIR)/icon.o
428449
$(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/icon.o
429450
430451
# This rule prevents make from using its default rules to try build
@@ -474,10 +495,15 @@
474495
475496
writeln "\$(OBJDIR)/sqlite3.o:\t\$(SRCDIR)/sqlite3.c"
476497
set opt $SQLITE_OPTIONS
477498
writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/sqlite3.c -o \$(OBJDIR)/sqlite3.o\n"
478499
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
+
479505
writeln "\$(OBJDIR)/shell.o:\t\$(SRCDIR)/shell.c \$(SRCDIR)/sqlite3.h"
480506
set opt {-Dmain=sqlite3_shell}
481507
append opt " -DSQLITE_OMIT_LOAD_EXTENSION=1"
482508
writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/shell.c -o \$(OBJDIR)/shell.o\n"
483509
@@ -585,10 +611,13 @@
585611
$(OBJDIR)\th$O : $(SRCDIR)\th.c
586612
$(TCC) -o$@ -c $**
587613
588614
$(OBJDIR)\th_lang$O : $(SRCDIR)\th_lang.c
589615
$(TCC) -o$@ -c $**
616
+
617
+$(OBJDIR)\cson_amalgamation.h : $(SRCDIR)\cson_amalgamation.h
618
+ cp $@ $@
590619
591620
VERSION.h : version$E $B\manifest.uuid $B\manifest $B\VERSION
592621
+$** > $@
593622
594623
page_index.h: mkindex$E $(SRC)
@@ -598,10 +627,23 @@
598627
-del $(OBJDIR)\*.obj
599628
-del *.obj *_.c *.h *.map
600629
601630
realclean:
602631
-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
+
603645
604646
}
605647
foreach s [lsort $src] {
606648
writeln "\$(OBJDIR)\\$s\$O : ${s}_.c ${s}.h"
607649
writeln "\t\$(TCC) -o\$@ -c ${s}_.c\n"
@@ -611,11 +653,11 @@
611653
612654
writeln -nonewline "headers: makeheaders\$E page_index.h VERSION.h\n\t +makeheaders\$E "
613655
foreach s [lsort $src] {
614656
writeln -nonewline "${s}_.c:$s.h "
615657
}
616
-writeln "\$(SRCDIR)\\sqlite3.h \$(SRCDIR)\\th.h VERSION.h"
658
+writeln "\$(SRCDIR)\\sqlite3.h \$(SRCDIR)\\th.h VERSION.h \$(SRCDIR)\\cson_amalgamation.h"
617659
writeln "\t@copy /Y nul: headers"
618660
619661
close $output_file
620662
#
621663
# End of the win/Makefile.dmc output
@@ -725,10 +767,12 @@
725767
$(OX)\th_lang$O : $(SRCDIR)\th_lang.c
726768
$(TCC) /Fo$@ -c $**
727769
728770
VERSION.h : mkversion$E $B\manifest.uuid $B\manifest $B\VERSION
729771
$** > $@
772
+$(OBJDIR)\cson_amalgamation.h : $(SRCDIR)\cson_amalgamation.h
773
+ cp $(SRCDIR)\cson_amalgamation.h $@
730774
731775
page_index.h: mkindex$E $(SRC)
732776
$** > $@
733777
734778
clean:
@@ -737,10 +781,22 @@
737781
-del headers linkopts
738782
739783
realclean:
740784
-del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E
741785
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
+
742798
}
743799
foreach s [lsort $src] {
744800
writeln "\$(OX)\\$s\$O : ${s}_.c ${s}.h"
745801
writeln "\t\$(TCC) /Fo\$@ -c ${s}_.c\n"
746802
writeln "${s}_.c : \$(SRCDIR)\\$s.c"
@@ -749,11 +805,11 @@
749805
750806
writeln -nonewline "headers: makeheaders\$E page_index.h VERSION.h\n\tmakeheaders\$E "
751807
foreach s [lsort $src] {
752808
writeln -nonewline "${s}_.c:$s.h "
753809
}
754
-writeln "\$(SRCDIR)\\sqlite3.h \$(SRCDIR)\\th.h VERSION.h"
810
+writeln "\$(SRCDIR)\\sqlite3.h \$(SRCDIR)\\th.h VERSION.h \$(SRCDIR)\\cson_amalgamation.h"
755811
writeln "\t@copy /Y nul: headers"
756812
757813
758814
close $output_file
759815
#
760816
--- 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 @@
5353
http
5454
http_socket
5555
http_transport
5656
import
5757
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
5869
leaf
5970
login
6071
main
6172
manifest
6273
md5
@@ -207,11 +218,12 @@
207218
EXTRAOBJ = \
208219
$(SQLITE3_OBJ.$(USE_SYSTEM_SQLITE)) \
209220
$(OBJDIR)/shell.o \
210221
$(OBJDIR)/th.o \
211222
$(OBJDIR)/th_lang.o \
212
- $(TCL_OBJ.$(FOSSIL_ENABLE_TCL))
223
+ $(TCL_OBJ.$(FOSSIL_ENABLE_TCL)) \
224
+ $(OBJDIR)/cson_amalgamation.o
213225
214226
$(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ)
215227
$(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB)
216228
217229
# This rule prevents make from using its default rules to try build
@@ -230,17 +242,19 @@
230242
append mhargs " \$(OBJDIR)/${s}_.c:\$(OBJDIR)/$s.h"
231243
set extra_h($s) {}
232244
}
233245
append mhargs " \$(SRCDIR)/sqlite3.h"
234246
append mhargs " \$(SRCDIR)/th.h"
247
+#append mhargs " \$(SRCDIR)/cson_amalgamation.h"
235248
append mhargs " \$(OBJDIR)/VERSION.h"
236249
writeln "\$(OBJDIR)/page_index.h: \$(TRANS_SRC) \$(OBJDIR)/mkindex"
237250
writeln "\t\$(OBJDIR)/mkindex \$(TRANS_SRC) >$@"
238251
writeln "\$(OBJDIR)/headers:\t\$(OBJDIR)/page_index.h \$(OBJDIR)/makeheaders \$(OBJDIR)/VERSION.h"
239252
writeln "\t\$(OBJDIR)/makeheaders $mhargs"
240253
writeln "\ttouch \$(OBJDIR)/headers"
241254
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"
242256
writeln "Makefile:"
243257
set extra_h(main) \$(OBJDIR)/page_index.h
244258
245259
foreach s [lsort $src] {
246260
writeln "\$(OBJDIR)/${s}_.c:\t\$(SRCDIR)/$s.c \$(OBJDIR)/translate"
@@ -272,10 +286,16 @@
272286
writeln "\$(OBJDIR)/th_lang.o:\t\$(SRCDIR)/th_lang.c"
273287
writeln "\t\$(XTCC) -I\$(SRCDIR) -c \$(SRCDIR)/th_lang.c -o \$(OBJDIR)/th_lang.o\n"
274288
275289
writeln "\$(OBJDIR)/th_tcl.o:\t\$(SRCDIR)/th_tcl.c"
276290
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
+}
277297
278298
close $output_file
279299
#
280300
# End of the main.mk output
281301
##############################################################################
@@ -420,11 +440,12 @@
420440
421441
EXTRAOBJ = \
422442
$(OBJDIR)/sqlite3.o \
423443
$(OBJDIR)/shell.o \
424444
$(OBJDIR)/th.o \
425
- $(OBJDIR)/th_lang.o
445
+ $(OBJDIR)/th_lang.o \
446
+ $(OBJDIR)/cson_amalgamation.o
426447
427448
$(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) $(OBJDIR)/icon.o
428449
$(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/icon.o
429450
430451
# This rule prevents make from using its default rules to try build
@@ -474,10 +495,15 @@
474495
475496
writeln "\$(OBJDIR)/sqlite3.o:\t\$(SRCDIR)/sqlite3.c"
476497
set opt $SQLITE_OPTIONS
477498
writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/sqlite3.c -o \$(OBJDIR)/sqlite3.o\n"
478499
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
+
479505
writeln "\$(OBJDIR)/shell.o:\t\$(SRCDIR)/shell.c \$(SRCDIR)/sqlite3.h"
480506
set opt {-Dmain=sqlite3_shell}
481507
append opt " -DSQLITE_OMIT_LOAD_EXTENSION=1"
482508
writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/shell.c -o \$(OBJDIR)/shell.o\n"
483509
@@ -585,10 +611,13 @@
585611
$(OBJDIR)\th$O : $(SRCDIR)\th.c
586612
$(TCC) -o$@ -c $**
587613
588614
$(OBJDIR)\th_lang$O : $(SRCDIR)\th_lang.c
589615
$(TCC) -o$@ -c $**
616
+
617
+$(OBJDIR)\cson_amalgamation.h : $(SRCDIR)\cson_amalgamation.h
618
+ cp $@ $@
590619
591620
VERSION.h : version$E $B\manifest.uuid $B\manifest $B\VERSION
592621
+$** > $@
593622
594623
page_index.h: mkindex$E $(SRC)
@@ -598,10 +627,23 @@
598627
-del $(OBJDIR)\*.obj
599628
-del *.obj *_.c *.h *.map
600629
601630
realclean:
602631
-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
+
603645
604646
}
605647
foreach s [lsort $src] {
606648
writeln "\$(OBJDIR)\\$s\$O : ${s}_.c ${s}.h"
607649
writeln "\t\$(TCC) -o\$@ -c ${s}_.c\n"
@@ -611,11 +653,11 @@
611653
612654
writeln -nonewline "headers: makeheaders\$E page_index.h VERSION.h\n\t +makeheaders\$E "
613655
foreach s [lsort $src] {
614656
writeln -nonewline "${s}_.c:$s.h "
615657
}
616
-writeln "\$(SRCDIR)\\sqlite3.h \$(SRCDIR)\\th.h VERSION.h"
658
+writeln "\$(SRCDIR)\\sqlite3.h \$(SRCDIR)\\th.h VERSION.h \$(SRCDIR)\\cson_amalgamation.h"
617659
writeln "\t@copy /Y nul: headers"
618660
619661
close $output_file
620662
#
621663
# End of the win/Makefile.dmc output
@@ -725,10 +767,12 @@
725767
$(OX)\th_lang$O : $(SRCDIR)\th_lang.c
726768
$(TCC) /Fo$@ -c $**
727769
728770
VERSION.h : mkversion$E $B\manifest.uuid $B\manifest $B\VERSION
729771
$** > $@
772
+$(OBJDIR)\cson_amalgamation.h : $(SRCDIR)\cson_amalgamation.h
773
+ cp $(SRCDIR)\cson_amalgamation.h $@
730774
731775
page_index.h: mkindex$E $(SRC)
732776
$** > $@
733777
734778
clean:
@@ -737,10 +781,22 @@
737781
-del headers linkopts
738782
739783
realclean:
740784
-del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E
741785
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
+
742798
}
743799
foreach s [lsort $src] {
744800
writeln "\$(OX)\\$s\$O : ${s}_.c ${s}.h"
745801
writeln "\t\$(TCC) /Fo\$@ -c ${s}_.c\n"
746802
writeln "${s}_.c : \$(SRCDIR)\\$s.c"
@@ -749,11 +805,11 @@
749805
750806
writeln -nonewline "headers: makeheaders\$E page_index.h VERSION.h\n\tmakeheaders\$E "
751807
foreach s [lsort $src] {
752808
writeln -nonewline "${s}_.c:$s.h "
753809
}
754
-writeln "\$(SRCDIR)\\sqlite3.h \$(SRCDIR)\\th.h VERSION.h"
810
+writeln "\$(SRCDIR)\\sqlite3.h \$(SRCDIR)\\th.h VERSION.h \$(SRCDIR)\\cson_amalgamation.h"
755811
writeln "\t@copy /Y nul: headers"
756812
757813
758814
close $output_file
759815
#
760816
--- 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 @@
366366
** shows all possibilities and do not return.
367367
*/
368368
int name_to_rid_www(const char *zParamName){
369369
int rid;
370370
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
372376
if( zName==0 || zName[0]==0 ) return 0;
373377
rid = symbolic_name_to_rid(zName, "*");
374378
if( rid<0 ){
375379
cgi_redirectf("%s/ambiguous/%T?src=%t", g.zTop, zName, g.zPath);
376380
rid = 0;
377381
--- 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
--- src/report.c
+++ src/report.c
@@ -19,10 +19,13 @@
1919
*/
2020
#include "config.h"
2121
#include <time.h>
2222
#include "report.h"
2323
#include <assert.h>
24
+#ifdef FOSSIL_ENABLE_JSON
25
+# include "cson_amalgamation.h"
26
+#endif
2427
2528
/* Forward references to static routines */
2629
static void report_format_hints(void);
2730
2831
/*
@@ -1138,5 +1141,6 @@
11381141
report_unrestrict_sql();
11391142
if( zFilter ){
11401143
free(zSql);
11411144
}
11421145
}
1146
+
11431147
--- 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 @@
2020
*/
2121
#include <string.h>
2222
#include <time.h>
2323
#include "config.h"
2424
#include "timeline.h"
25
+#ifdef FOSSIL_ENABLE_JSON
26
+# include "cson_amalgamation.h"
27
+#endif
2528
2629
/*
2730
** Shorten a UUID so that is the minimum length needed to contain
2831
** at least one digit in the range 'a'..'f'. The minimum length is 10.
2932
*/
@@ -768,24 +771,24 @@
768771
*/
769772
const char *timeline_query_for_www(void){
770773
static char *zBase = 0;
771774
static const char zBaseSql[] =
772775
@ SELECT
773
- @ blob.rid,
774
- @ uuid,
776
+ @ blob.rid AS blobRid,
777
+ @ uuid AS uuid,
775778
@ 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,
781784
@ (SELECT group_concat(substr(tagname,5), ', ') FROM tag, tagxref
782785
@ 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
787790
@ FROM event JOIN blob
788791
@ WHERE blob.rid=event.objid
789792
;
790793
if( zBase==0 ){
791794
zBase = mprintf(zBaseSql, TAG_BRANCH, TAG_BRANCH);
@@ -1381,24 +1384,24 @@
13811384
** a timeline query for display on a TTY.
13821385
*/
13831386
const char *timeline_query_for_tty(void){
13841387
static const char zBaseSql[] =
13851388
@ SELECT
1386
- @ blob.rid,
1389
+ @ blob.rid AS rid,
13871390
@ uuid,
1388
- @ datetime(event.mtime,'localtime'),
1391
+ @ datetime(event.mtime,'localtime') AS mDateTime,
13891392
@ coalesce(ecomment,comment)
13901393
@ || ' (user: ' || coalesce(euser,user,'?')
13911394
@ || (SELECT case when length(x)>0 then ' tags: ' || x else '' end
13921395
@ FROM (SELECT group_concat(substr(tagname,5), ', ') AS x
13931396
@ FROM tag, tagxref
13941397
@ WHERE tagname GLOB 'sym-*' AND tag.tagid=tagxref.tagid
13951398
@ 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
14001403
@ FROM event, blob
14011404
@ WHERE blob.rid=event.objid
14021405
;
14031406
return zBaseSql;
14041407
}
@@ -1441,12 +1444,12 @@
14411444
**
14421445
** w = wiki commits only
14431446
** ci = file commits only
14441447
** t = tickets only
14451448
**
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.
14481451
**
14491452
*/
14501453
void timeline_cmd(void){
14511454
Stmt q;
14521455
int n, k;
@@ -1540,11 +1543,10 @@
15401543
blob_appendf(&sql, " AND blob.rid IN ok");
15411544
}
15421545
if( zType && (zType[0]!='a') ){
15431546
blob_appendf(&sql, " AND event.type=%Q ", zType);
15441547
}
1545
-
15461548
blob_appendf(&sql, " ORDER BY event.mtime DESC");
15471549
db_prepare(&q, blob_str(&sql));
15481550
blob_reset(&sql);
15491551
print_timeline(&q, n, showfilesFlag);
15501552
db_finalize(&q);
15511553
--- 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 @@
853853
**
854854
** Run the ticket report, identified by the report format title
855855
** used in the gui. The data is written as flat file on stdout,
856856
** using "," as separator. The separator "," can be changed using
857857
** the -l or --limit option.
858
+**
858859
** If TICKETFILTER is given on the commandline, the query is
859860
** limited with a new WHERE-condition.
860861
** example: Report lists a column # with the uuid
861862
** TICKETFILTER may be [#]='uuuuuuuuu'
862863
** example: Report only lists rows with status not open
@@ -863,11 +864,11 @@
863864
** TICKETFILTER: status != 'open'
864865
** If the option -q|--quote is used, the tickets are encoded by
865866
** quoting special chars(space -> \\s, tab -> \\t, newline -> \\n,
866867
** cr -> \\r, formfeed -> \\f, vtab -> \\v, nul -> \\0, \\ -> \\\\).
867868
** 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.
869870
**
870871
** Instead of the report title its possible to use the report
871872
** number. Using the special report number 0 list all columns,
872873
** defined in the ticket table.
873874
**
@@ -957,22 +958,19 @@
957958
usage("show REPORTNR");
958959
}else{
959960
const char *zRep = 0;
960961
const char *zSep = 0;
961962
const char *zFilterUuid = 0;
962
-
963963
zSep = find_option("limit","l",1);
964964
zRep = g.argv[3];
965965
if( !strcmp(zRep,"0") ){
966966
zRep = 0;
967967
}
968968
if( g.argc>4 ){
969969
zFilterUuid = g.argv[4];
970970
}
971
-
972971
rptshow( zRep, zSep, zFilterUuid, tktEncoding );
973
-
974972
}
975973
}else{
976974
/* add a new ticket or update an existing ticket */
977975
enum { set,add,history,err } eCmd = err;
978976
int i = 0;
979977
--- 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 @@
630630
manifest_destroy(pW1);
631631
manifest_destroy(pW2);
632632
style_footer();
633633
}
634634
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
+}
635652
/*
636653
** WEBPAGE: wcontent
637654
**
638655
** all=1 Show deleted pages
639656
**
@@ -650,17 +667,11 @@
650667
style_submenu_element("Active", "Only Active Pages", "%s/wcontent", g.zTop);
651668
}else{
652669
style_submenu_element("All", "All", "%s/wcontent?all=1", g.zTop);
653670
}
654671
@ <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);
662673
while( db_step(&q)==SQLITE_ROW ){
663674
const char *zName = db_column_text(&q, 0);
664675
int size = db_column_int(&q, 1);
665676
if( size>0 ){
666677
@ <li><a href="%s(g.zTop)/wiki?name=%T(zName)">%h(zName)</a></li>
@@ -790,13 +801,19 @@
790801
" WHERE x.tagid=t.tagid AND t.tagname='wiki-%q'"
791802
" ORDER BY x.mtime DESC LIMIT 1",
792803
zPageName
793804
);
794805
if( rid==0 && !isNew ){
806
+#ifdef FOSSIL_ENABLE_JSON
807
+ g.json.resultCode = FSL_JSON_E_RESOURCE_NOT_FOUND;
808
+#endif
795809
fossil_fatal("no such wiki page: %s", zPageName);
796810
}
797811
if( rid!=0 && isNew ){
812
+#ifdef FOSSIL_ENABLE_JSON
813
+ g.json.resultCode = FSL_JSON_E_RESOURCE_ALREADY_EXISTS;
814
+#endif
798815
fossil_fatal("wiki page %s already exists", zPageName);
799816
}
800817
801818
blob_zero(&wiki);
802819
zDate = date_in_standard_format("now");
803820
--- 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 @@
2222
TCC = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL)
2323
LIBS = $(DMDIR)\extra\lib\ zlib wsock32
2424
2525
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
2626
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
2828
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
3030
3131
3232
RC=$(DMDIR)\bin\rcc
3333
RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__
3434
@@ -42,11 +42,11 @@
4242
4343
$(OBJDIR)\fossil.res: $B\win\fossil.rc
4444
$(RC) $(RCFLAGS) -o$@ $**
4545
4646
$(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 > $@
4848
+echo fossil >> $@
4949
+echo fossil >> $@
5050
+echo $(LIBS) >> $@
5151
+echo. >> $@
5252
+echo fossil >> $@
@@ -72,10 +72,13 @@
7272
$(OBJDIR)\th$O : $(SRCDIR)\th.c
7373
$(TCC) -o$@ -c $**
7474
7575
$(OBJDIR)\th_lang$O : $(SRCDIR)\th_lang.c
7676
$(TCC) -o$@ -c $**
77
+
78
+$(OBJDIR)\cson_amalgamation.h : $(SRCDIR)\cson_amalgamation.h
79
+ cp $@ $@
7780
7881
VERSION.h : version$E $B\manifest.uuid $B\manifest $B\VERSION
7982
+$** > $@
8083
8184
page_index.h: mkindex$E $(SRC)
@@ -85,10 +88,23 @@
8588
-del $(OBJDIR)\*.obj
8689
-del *.obj *_.c *.h *.map
8790
8891
realclean:
8992
-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
+
90106
91107
92108
$(OBJDIR)\add$O : add_.c add.h
93109
$(TCC) -o$@ -c add_.c
94110
@@ -314,10 +330,76 @@
314330
$(OBJDIR)\info$O : info_.c info.h
315331
$(TCC) -o$@ -c info_.c
316332
317333
info_.c : $(SRCDIR)\info.c
318334
+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 $** > $@
319401
320402
$(OBJDIR)\leaf$O : leaf_.c leaf.h
321403
$(TCC) -o$@ -c leaf_.c
322404
323405
leaf_.c : $(SRCDIR)\leaf.c
@@ -580,7 +662,7 @@
580662
581663
zip_.c : $(SRCDIR)\zip.c
582664
+translate$E $** > $@
583665
584666
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
586668
@copy /Y nul: headers
587669
--- 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 @@
110110
$(SRCDIR)/http_socket.c \
111111
$(SRCDIR)/http_ssl.c \
112112
$(SRCDIR)/http_transport.c \
113113
$(SRCDIR)/import.c \
114114
$(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 \
115126
$(SRCDIR)/leaf.c \
116127
$(SRCDIR)/login.c \
117128
$(SRCDIR)/main.c \
118129
$(SRCDIR)/manifest.c \
119130
$(SRCDIR)/md5.c \
@@ -194,10 +205,21 @@
194205
$(OBJDIR)/http_socket_.c \
195206
$(OBJDIR)/http_ssl_.c \
196207
$(OBJDIR)/http_transport_.c \
197208
$(OBJDIR)/import_.c \
198209
$(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 \
199221
$(OBJDIR)/leaf_.c \
200222
$(OBJDIR)/login_.c \
201223
$(OBJDIR)/main_.c \
202224
$(OBJDIR)/manifest_.c \
203225
$(OBJDIR)/md5_.c \
@@ -278,10 +300,21 @@
278300
$(OBJDIR)/http_socket.o \
279301
$(OBJDIR)/http_ssl.o \
280302
$(OBJDIR)/http_transport.o \
281303
$(OBJDIR)/import.o \
282304
$(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 \
283316
$(OBJDIR)/leaf.o \
284317
$(OBJDIR)/login.o \
285318
$(OBJDIR)/main.o \
286319
$(OBJDIR)/manifest.o \
287320
$(OBJDIR)/md5.o \
@@ -363,11 +396,11 @@
363396
$(TCLSH) test/tester.tcl $(APPNAME)
364397
365398
$(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(VERSION)
366399
$(VERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h
367400
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
369402
370403
$(APPNAME): $(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) $(OBJDIR)/icon.o
371404
$(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/icon.o
372405
373406
# This rule prevents make from using its default rules to try build
@@ -388,11 +421,11 @@
388421
389422
390423
$(OBJDIR)/page_index.h: $(TRANS_SRC) $(OBJDIR)/mkindex
391424
$(MKINDEX) $(TRANS_SRC) >$@
392425
$(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
394427
echo Done >$(OBJDIR)/headers
395428
396429
$(OBJDIR)/headers: Makefile
397430
Makefile:
398431
$(OBJDIR)/add_.c: $(SRCDIR)/add.c $(OBJDIR)/translate
@@ -659,10 +692,87 @@
659692
660693
$(OBJDIR)/info.o: $(OBJDIR)/info_.c $(OBJDIR)/info.h $(SRCDIR)/config.h
661694
$(XTCC) -o $(OBJDIR)/info.o -c $(OBJDIR)/info_.c
662695
663696
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
664774
$(OBJDIR)/leaf_.c: $(SRCDIR)/leaf.c $(OBJDIR)/translate
665775
$(TRANSLATE) $(SRCDIR)/leaf.c >$(OBJDIR)/leaf_.c
666776
667777
$(OBJDIR)/leaf.o: $(OBJDIR)/leaf_.c $(OBJDIR)/leaf.h $(SRCDIR)/config.h
668778
$(XTCC) -o $(OBJDIR)/leaf.o -c $(OBJDIR)/leaf_.c
@@ -970,14 +1080,18 @@
9701080
9711081
zip.h: $(OBJDIR)/headers
9721082
$(OBJDIR)/sqlite3.o: $(SRCDIR)/sqlite3.c
9731083
$(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
9741084
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
9751089
$(OBJDIR)/shell.o: $(SRCDIR)/shell.c $(SRCDIR)/sqlite3.h
9761090
$(XTCC) -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -c $(SRCDIR)/shell.c -o $(OBJDIR)/shell.o
9771091
9781092
$(OBJDIR)/th.o: $(SRCDIR)/th.c
9791093
$(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th.c -o $(OBJDIR)/th.o
9801094
9811095
$(OBJDIR)/th_lang.o: $(SRCDIR)/th_lang.c
9821096
$(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th_lang.c -o $(OBJDIR)/th_lang.o
9831097
9841098
--- 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 @@
3636
LIBS = $(ZLIB) ws2_32.lib advapi32.lib $(SSLLIB)
3737
LIBDIR = -LIBPATH:$(MSCDIR)\extra\lib -LIBPATH:$(ZLIBDIR)
3838
3939
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
4040
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
4242
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
4444
4545
4646
APPNAME = $(OX)\fossil$(E)
4747
4848
all: $(OX) $(APPNAME)
@@ -88,10 +88,21 @@
8888
echo $(OX)\http_socket.obj >> $@
8989
echo $(OX)\http_ssl.obj >> $@
9090
echo $(OX)\http_transport.obj >> $@
9191
echo $(OX)\import.obj >> $@
9292
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 >> $@
93104
echo $(OX)\leaf.obj >> $@
94105
echo $(OX)\login.obj >> $@
95106
echo $(OX)\main.obj >> $@
96107
echo $(OX)\manifest.obj >> $@
97108
echo $(OX)\md5.obj >> $@
@@ -170,10 +181,12 @@
170181
$(OX)\th_lang$O : $(SRCDIR)\th_lang.c
171182
$(TCC) /Fo$@ -c $**
172183
173184
VERSION.h : mkversion$E $B\manifest.uuid $B\manifest $B\VERSION
174185
$** > $@
186
+$(OBJDIR)\cson_amalgamation.h : $(SRCDIR)\cson_amalgamation.h
187
+ cp $(SRCDIR)\cson_amalgamation.h $@
175188
176189
page_index.h: mkindex$E $(SRC)
177190
$** > $@
178191
179192
clean:
@@ -182,10 +195,22 @@
182195
-del headers linkopts
183196
184197
realclean:
185198
-del $(APPNAME) translate$E mkindex$E makeheaders$E mkversion$E
186199
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
+
187212
188213
$(OX)\add$O : add_.c add.h
189214
$(TCC) /Fo$@ -c add_.c
190215
191216
add_.c : $(SRCDIR)\add.c
@@ -410,10 +435,76 @@
410435
$(OX)\info$O : info_.c info.h
411436
$(TCC) /Fo$@ -c info_.c
412437
413438
info_.c : $(SRCDIR)\info.c
414439
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 $** > $@
415506
416507
$(OX)\leaf$O : leaf_.c leaf.h
417508
$(TCC) /Fo$@ -c leaf_.c
418509
419510
leaf_.c : $(SRCDIR)\leaf.c
@@ -676,7 +767,7 @@
676767
677768
zip_.c : $(SRCDIR)\zip.c
678769
translate$E $** > $@
679770
680771
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
682773
@copy /Y nul: headers
683774
--- 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

Keyboard Shortcuts

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