|
796dcfe…
|
drh
|
1 |
#ifdef FOSSIL_ENABLE_JSON |
|
796dcfe…
|
drh
|
2 |
/* |
|
c19f34c…
|
drh
|
3 |
** Copyright (c) 2011 D. Richard Hipp |
|
796dcfe…
|
drh
|
4 |
** |
|
796dcfe…
|
drh
|
5 |
** This program is free software; you can redistribute it and/or |
|
796dcfe…
|
drh
|
6 |
** modify it under the terms of the Simplified BSD License (also |
|
796dcfe…
|
drh
|
7 |
** known as the "2-Clause License" or "FreeBSD License".) |
|
796dcfe…
|
drh
|
8 |
** |
|
796dcfe…
|
drh
|
9 |
** This program is distributed in the hope that it will be useful, |
|
796dcfe…
|
drh
|
10 |
** but without any warranty; without even the implied warranty of |
|
796dcfe…
|
drh
|
11 |
** merchantability or fitness for a particular purpose. |
|
796dcfe…
|
drh
|
12 |
** |
|
796dcfe…
|
drh
|
13 |
** Author contact information: |
|
796dcfe…
|
drh
|
14 |
** [email protected] |
|
796dcfe…
|
drh
|
15 |
** http://www.hwaci.com/drh/ |
|
796dcfe…
|
drh
|
16 |
** |
|
796dcfe…
|
drh
|
17 |
*/ |
|
796dcfe…
|
drh
|
18 |
|
|
796dcfe…
|
drh
|
19 |
#include "config.h" |
|
796dcfe…
|
drh
|
20 |
#include "json_diff.h" |
|
796dcfe…
|
drh
|
21 |
|
|
796dcfe…
|
drh
|
22 |
#if INTERFACE |
|
796dcfe…
|
drh
|
23 |
#include "json_detail.h" |
|
796dcfe…
|
drh
|
24 |
#endif |
|
796dcfe…
|
drh
|
25 |
|
|
796dcfe…
|
drh
|
26 |
|
|
796dcfe…
|
drh
|
27 |
|
|
796dcfe…
|
drh
|
28 |
/* |
|
796dcfe…
|
drh
|
29 |
** Generates a diff between two versions (zFrom and zTo), using nContext |
|
796dcfe…
|
drh
|
30 |
** content lines in the output. On success, returns a new JSON String |
|
796dcfe…
|
drh
|
31 |
** object. On error it sets g.json's error state and returns NULL. |
|
796dcfe…
|
drh
|
32 |
** |
|
796dcfe…
|
drh
|
33 |
** If fSbs is true (non-0) them side-by-side diffs are used. |
|
a15214e…
|
stephan
|
34 |
** |
|
a15214e…
|
stephan
|
35 |
** If fHtml is true then HTML markup is added to the diff. |
|
796dcfe…
|
drh
|
36 |
*/ |
|
796dcfe…
|
drh
|
37 |
cson_value * json_generate_diff(const char *zFrom, const char *zTo, |
|
a15214e…
|
stephan
|
38 |
int nContext, char fSbs, |
|
a15214e…
|
stephan
|
39 |
char fHtml){ |
|
796dcfe…
|
drh
|
40 |
int fromid; |
|
796dcfe…
|
drh
|
41 |
int toid; |
|
796dcfe…
|
drh
|
42 |
int outLen; |
|
1347a1d…
|
drh
|
43 |
DiffConfig DCfg; |
|
796dcfe…
|
drh
|
44 |
Blob from = empty_blob, to = empty_blob, out = empty_blob; |
|
796dcfe…
|
drh
|
45 |
cson_value * rc = NULL; |
|
0c496d8…
|
stephan
|
46 |
int flags = (fSbs ? DIFF_SIDEBYSIDE : 0) |
|
a15214e…
|
stephan
|
47 |
| (fHtml ? DIFF_HTML : 0); |
|
796dcfe…
|
drh
|
48 |
fromid = name_to_typed_rid(zFrom, "*"); |
|
796dcfe…
|
drh
|
49 |
if(fromid<=0){ |
|
796dcfe…
|
drh
|
50 |
json_set_err(FSL_JSON_E_UNRESOLVED_UUID, |
|
796dcfe…
|
drh
|
51 |
"Could not resolve 'from' ID."); |
|
796dcfe…
|
drh
|
52 |
return NULL; |
|
796dcfe…
|
drh
|
53 |
} |
|
796dcfe…
|
drh
|
54 |
toid = name_to_typed_rid(zTo, "*"); |
|
796dcfe…
|
drh
|
55 |
if(toid<=0){ |
|
796dcfe…
|
drh
|
56 |
json_set_err(FSL_JSON_E_UNRESOLVED_UUID, |
|
796dcfe…
|
drh
|
57 |
"Could not resolve 'to' ID."); |
|
796dcfe…
|
drh
|
58 |
return NULL; |
|
796dcfe…
|
drh
|
59 |
} |
|
796dcfe…
|
drh
|
60 |
content_get(fromid, &from); |
|
796dcfe…
|
drh
|
61 |
content_get(toid, &to); |
|
796dcfe…
|
drh
|
62 |
blob_zero(&out); |
|
1347a1d…
|
drh
|
63 |
diff_config_init(&DCfg, flags); |
|
1347a1d…
|
drh
|
64 |
text_diff(&from, &to, &out, &DCfg); |
|
796dcfe…
|
drh
|
65 |
blob_reset(&from); |
|
796dcfe…
|
drh
|
66 |
blob_reset(&to); |
|
796dcfe…
|
drh
|
67 |
outLen = blob_size(&out); |
|
efbecda…
|
stephan
|
68 |
if(outLen>=0){ |
|
efbecda…
|
stephan
|
69 |
rc = cson_value_new_string(blob_buffer(&out), |
|
efbecda…
|
stephan
|
70 |
(unsigned int)blob_size(&out)); |
|
796dcfe…
|
drh
|
71 |
} |
|
796dcfe…
|
drh
|
72 |
blob_reset(&out); |
|
796dcfe…
|
drh
|
73 |
return rc; |
|
796dcfe…
|
drh
|
74 |
} |
|
796dcfe…
|
drh
|
75 |
|
|
796dcfe…
|
drh
|
76 |
/* |
|
796dcfe…
|
drh
|
77 |
** Implementation of the /json/diff page. |
|
796dcfe…
|
drh
|
78 |
** |
|
796dcfe…
|
drh
|
79 |
** Arguments: |
|
796dcfe…
|
drh
|
80 |
** |
|
796dcfe…
|
drh
|
81 |
** v1=1st version to diff |
|
796dcfe…
|
drh
|
82 |
** v2=2nd version to diff |
|
796dcfe…
|
drh
|
83 |
** |
|
796dcfe…
|
drh
|
84 |
** Can come from GET, POST.payload, CLI -v1/-v2 or as positional |
|
796dcfe…
|
drh
|
85 |
** parameters following the command name (in HTTP and CLI modes). |
|
796dcfe…
|
drh
|
86 |
** |
|
796dcfe…
|
drh
|
87 |
*/ |
|
a80f274…
|
stephan
|
88 |
cson_value * json_page_diff(void){ |
|
796dcfe…
|
drh
|
89 |
cson_object * pay = NULL; |
|
796dcfe…
|
drh
|
90 |
cson_value * v = NULL; |
|
796dcfe…
|
drh
|
91 |
char const * zFrom; |
|
796dcfe…
|
drh
|
92 |
char const * zTo; |
|
796dcfe…
|
drh
|
93 |
int nContext = 0; |
|
796dcfe…
|
drh
|
94 |
char doSBS; |
|
a15214e…
|
stephan
|
95 |
char doHtml; |
|
796dcfe…
|
drh
|
96 |
if(!g.perm.Read){ |
|
796dcfe…
|
drh
|
97 |
json_set_err(FSL_JSON_E_DENIED, |
|
796dcfe…
|
drh
|
98 |
"Requires 'o' permissions."); |
|
796dcfe…
|
drh
|
99 |
return NULL; |
|
796dcfe…
|
drh
|
100 |
} |
|
796dcfe…
|
drh
|
101 |
zFrom = json_find_option_cstr("v1",NULL,NULL); |
|
796dcfe…
|
drh
|
102 |
if(!zFrom){ |
|
796dcfe…
|
drh
|
103 |
zFrom = json_command_arg(2); |
|
796dcfe…
|
drh
|
104 |
} |
|
796dcfe…
|
drh
|
105 |
if(!zFrom){ |
|
796dcfe…
|
drh
|
106 |
json_set_err(FSL_JSON_E_MISSING_ARGS, |
|
796dcfe…
|
drh
|
107 |
"Required 'v1' parameter is missing."); |
|
796dcfe…
|
drh
|
108 |
return NULL; |
|
796dcfe…
|
drh
|
109 |
} |
|
796dcfe…
|
drh
|
110 |
zTo = json_find_option_cstr("v2",NULL,NULL); |
|
796dcfe…
|
drh
|
111 |
if(!zTo){ |
|
796dcfe…
|
drh
|
112 |
zTo = json_command_arg(3); |
|
796dcfe…
|
drh
|
113 |
} |
|
796dcfe…
|
drh
|
114 |
if(!zTo){ |
|
796dcfe…
|
drh
|
115 |
json_set_err(FSL_JSON_E_MISSING_ARGS, |
|
796dcfe…
|
drh
|
116 |
"Required 'v2' parameter is missing."); |
|
796dcfe…
|
drh
|
117 |
return NULL; |
|
796dcfe…
|
drh
|
118 |
} |
|
796dcfe…
|
drh
|
119 |
nContext = json_find_option_int("context",NULL,"c",5); |
|
796dcfe…
|
drh
|
120 |
doSBS = json_find_option_bool("sbs",NULL,"y",0); |
|
a15214e…
|
stephan
|
121 |
doHtml = json_find_option_bool("html",NULL,"h",0); |
|
a15214e…
|
stephan
|
122 |
v = json_generate_diff(zFrom, zTo, nContext, doSBS, doHtml); |
|
796dcfe…
|
drh
|
123 |
if(!v){ |
|
796dcfe…
|
drh
|
124 |
if(!g.json.resultCode){ |
|
796dcfe…
|
drh
|
125 |
json_set_err(FSL_JSON_E_UNKNOWN, |
|
796dcfe…
|
drh
|
126 |
"Generating diff failed for unknown reason."); |
|
796dcfe…
|
drh
|
127 |
} |
|
796dcfe…
|
drh
|
128 |
return NULL; |
|
796dcfe…
|
drh
|
129 |
} |
|
796dcfe…
|
drh
|
130 |
pay = cson_new_object(); |
|
796dcfe…
|
drh
|
131 |
cson_object_set(pay, "from", json_new_string(zFrom)); |
|
796dcfe…
|
drh
|
132 |
cson_object_set(pay, "to", json_new_string(zTo)); |
|
796dcfe…
|
drh
|
133 |
cson_object_set(pay, "diff", v); |
|
796dcfe…
|
drh
|
134 |
v = 0; |
|
bf9669f…
|
andygoth
|
135 |
|
|
796dcfe…
|
drh
|
136 |
return pay ? cson_object_value(pay) : NULL; |
|
796dcfe…
|
drh
|
137 |
} |
|
796dcfe…
|
drh
|
138 |
|
|
796dcfe…
|
drh
|
139 |
#endif /* FOSSIL_ENABLE_JSON */ |