Fossil SCM
JSON CLI mode now accepts --indent|-I N to set JSON indention level (uses cson_output_opt::indentation semantics). Default for CLI mode is 1 (0 for HTTP mode).
Commit
30e4ebaa199af338c86f50421935f02e74dc129a
Parent
033e2eb1dfabdf2…
2 files changed
+1
-1
+50
-33
+1
-1
| --- ajax/index.html | ||
| +++ ajax/index.html | ||
| @@ -148,11 +148,11 @@ | ||
| 148 | 148 | TheApp.startAjaxNotif(); |
| 149 | 149 | }; |
| 150 | 150 | opt.afterSend = function(req,opt) { |
| 151 | 151 | TheApp.timer.end(); |
| 152 | 152 | TheApp.endAjaxNotif(); |
| 153 | - TheApp.jqe.timer.text( "(Round-trip time: "+TheApp.timer.duration+'ms)' ); | |
| 153 | + TheApp.jqe.timer.text( "(Round-trip time (incl. JS overhead): "+TheApp.timer.duration+'ms)' ); | |
| 154 | 154 | }; |
| 155 | 155 | opt.onResponse = function(resp,req) { |
| 156 | 156 | var val; |
| 157 | 157 | try { |
| 158 | 158 | val = WhAjaj.stringify(resp); |
| 159 | 159 |
| --- ajax/index.html | |
| +++ ajax/index.html | |
| @@ -148,11 +148,11 @@ | |
| 148 | TheApp.startAjaxNotif(); |
| 149 | }; |
| 150 | opt.afterSend = function(req,opt) { |
| 151 | TheApp.timer.end(); |
| 152 | TheApp.endAjaxNotif(); |
| 153 | TheApp.jqe.timer.text( "(Round-trip time: "+TheApp.timer.duration+'ms)' ); |
| 154 | }; |
| 155 | opt.onResponse = function(resp,req) { |
| 156 | var val; |
| 157 | try { |
| 158 | val = WhAjaj.stringify(resp); |
| 159 |
| --- ajax/index.html | |
| +++ ajax/index.html | |
| @@ -148,11 +148,11 @@ | |
| 148 | TheApp.startAjaxNotif(); |
| 149 | }; |
| 150 | opt.afterSend = function(req,opt) { |
| 151 | TheApp.timer.end(); |
| 152 | TheApp.endAjaxNotif(); |
| 153 | TheApp.jqe.timer.text( "(Round-trip time (incl. JS overhead): "+TheApp.timer.duration+'ms)' ); |
| 154 | }; |
| 155 | opt.onResponse = function(resp,req) { |
| 156 | var val; |
| 157 | try { |
| 158 | val = WhAjaj.stringify(resp); |
| 159 |
+50
-33
| --- src/json.c | ||
| +++ src/json.c | ||
| @@ -391,18 +391,35 @@ | ||
| 391 | 391 | if(rc){ |
| 392 | 392 | return rc; |
| 393 | 393 | }else{ |
| 394 | 394 | char const * cv = PD(zKey,NULL); |
| 395 | 395 | if(!cv){ |
| 396 | + /* reminder to self: in CLI mode i'd like to try | |
| 397 | + find_option(zKey,NULL,XYZ) here, but we don't have a sane | |
| 398 | + default for the XYZ param here. | |
| 399 | + */ | |
| 396 | 400 | cv = getenv(zKey); |
| 397 | 401 | } |
| 398 | 402 | if(cv){/*transform it to JSON for later use.*/ |
| 399 | - /* TODO: use sscanf() to figure out if it's an int, | |
| 403 | + /* use sscanf() to figure out if it's an int, | |
| 400 | 404 | and transform it to JSON int if it is. |
| 401 | 405 | */ |
| 402 | - rc = cson_value_new_string(cv,strlen(cv)); | |
| 403 | - json_setenv( zKey, rc ); | |
| 406 | + int intVal = -1; | |
| 407 | + char endOfIntCheck; | |
| 408 | + int const scanRc = sscanf(cv,"%d%c",&intVal, &endOfIntCheck) | |
| 409 | + /* The %c bit there is to make sure that we don't accept 123x | |
| 410 | + as a number. sscanf() returns the number of tokens | |
| 411 | + successfully parsed, so an RC of 1 will be correct for "123" | |
| 412 | + but "123x" will have RC==2. | |
| 413 | + */ | |
| 414 | + ; | |
| 415 | + if(1==scanRc){ | |
| 416 | + json_setenv( zKey, cson_value_new_integer(intVal) ); | |
| 417 | + }else{ | |
| 418 | + rc = cson_value_new_string(cv,strlen(cv)); | |
| 419 | + json_setenv( zKey, rc ); | |
| 420 | + } | |
| 404 | 421 | return rc; |
| 405 | 422 | } |
| 406 | 423 | } |
| 407 | 424 | return NULL; |
| 408 | 425 | } |
| @@ -934,20 +951,20 @@ | ||
| 934 | 951 | */; |
| 935 | 952 | } |
| 936 | 953 | |
| 937 | 954 | {/* set up JSON output formatting options. */ |
| 938 | 955 | unsigned char indent = g.isHTTP ? 0 : 1; |
| 939 | - cson_value const * indentV = json_getenv("indent"); | |
| 940 | - if(indentV){ | |
| 941 | - if(cson_value_is_string(indentV)){ | |
| 942 | - int const n = atoi(cson_string_cstr(cson_value_get_string(indentV))); | |
| 956 | + char const * indentStr = NULL; | |
| 957 | + if( g.isHTTP ){ | |
| 958 | + indent = (unsigned char)json_getenv_int("indent",(int)indent); | |
| 959 | + }else{/*CLI mode*/ | |
| 960 | + indentStr = find_option("indent","I",1); | |
| 961 | + if(indentStr){ | |
| 962 | + int const n = atoi(indentStr); | |
| 943 | 963 | indent = (n>0) |
| 944 | 964 | ? (unsigned char)n |
| 945 | 965 | : 0; |
| 946 | - }else if(cson_value_is_number(indentV)){ | |
| 947 | - cson_int_t const n = cson_value_get_integer(indentV); | |
| 948 | - indent = (n>0) ? (unsigned char)n : 0; | |
| 949 | 966 | } |
| 950 | 967 | } |
| 951 | 968 | g.json.outOpt.indentation = indent; |
| 952 | 969 | g.json.outOpt.addNewline = g.isHTTP |
| 953 | 970 | ? 0 |
| @@ -1357,33 +1374,33 @@ | ||
| 1357 | 1374 | } |
| 1358 | 1375 | db_finalize(&q); |
| 1359 | 1376 | cson_object_set( obj, "permissionFlags", sub ); |
| 1360 | 1377 | obj = cson_value_get_object(sub); |
| 1361 | 1378 | |
| 1362 | -#define ADD(X) cson_object_set(obj, #X, cson_value_new_bool(g.perm.X)) | |
| 1363 | - ADD(Setup); | |
| 1364 | - ADD(Admin); | |
| 1365 | - ADD(Delete); | |
| 1366 | - ADD(Password); | |
| 1367 | - ADD(Query); | |
| 1368 | - ADD(Write); | |
| 1369 | - ADD(Read); | |
| 1370 | - ADD(History); | |
| 1371 | - ADD(Clone); | |
| 1372 | - ADD(RdWiki); | |
| 1373 | - ADD(NewWiki); | |
| 1374 | - ADD(ApndWiki); | |
| 1375 | - ADD(WrWiki); | |
| 1376 | - ADD(RdTkt); | |
| 1377 | - ADD(NewTkt); | |
| 1378 | - ADD(ApndTkt); | |
| 1379 | - ADD(WrTkt); | |
| 1380 | - ADD(Attach); | |
| 1381 | - ADD(TktFmt); | |
| 1382 | - ADD(RdAddr); | |
| 1383 | - ADD(Zip); | |
| 1384 | - ADD(Private); | |
| 1379 | +#define ADD(X,K) cson_object_set(obj, K, cson_value_new_bool(g.perm.X)) | |
| 1380 | + ADD(Setup,"setup"); | |
| 1381 | + ADD(Admin,"admin"); | |
| 1382 | + ADD(Delete,"delete"); | |
| 1383 | + ADD(Password,"password"); | |
| 1384 | + ADD(Query,"query"); /* don't think this one is actually used */ | |
| 1385 | + ADD(Write,"checkin"); | |
| 1386 | + ADD(Read,"checkout"); | |
| 1387 | + ADD(History,"history"); | |
| 1388 | + ADD(Clone,"clone"); | |
| 1389 | + ADD(RdWiki,"readWiki"); | |
| 1390 | + ADD(NewWiki,"createWiki"); | |
| 1391 | + ADD(ApndWiki,"appendWiki"); | |
| 1392 | + ADD(WrWiki,"editWiki"); | |
| 1393 | + ADD(RdTkt,"readTicket"); | |
| 1394 | + ADD(NewTkt,"createTicket"); | |
| 1395 | + ADD(ApndTkt,"appendTicket"); | |
| 1396 | + ADD(WrTkt,"editTicket"); | |
| 1397 | + ADD(Attach,"attachFile"); | |
| 1398 | + ADD(TktFmt,"createTicketReport"); | |
| 1399 | + ADD(RdAddr,"readPrivate"); | |
| 1400 | + ADD(Zip,"zip"); | |
| 1401 | + ADD(Private,"xferPrivate"); | |
| 1385 | 1402 | #undef ADD |
| 1386 | 1403 | return payload; |
| 1387 | 1404 | } |
| 1388 | 1405 | |
| 1389 | 1406 | /* |
| 1390 | 1407 |
| --- src/json.c | |
| +++ src/json.c | |
| @@ -391,18 +391,35 @@ | |
| 391 | if(rc){ |
| 392 | return rc; |
| 393 | }else{ |
| 394 | char const * cv = PD(zKey,NULL); |
| 395 | if(!cv){ |
| 396 | cv = getenv(zKey); |
| 397 | } |
| 398 | if(cv){/*transform it to JSON for later use.*/ |
| 399 | /* TODO: use sscanf() to figure out if it's an int, |
| 400 | and transform it to JSON int if it is. |
| 401 | */ |
| 402 | rc = cson_value_new_string(cv,strlen(cv)); |
| 403 | json_setenv( zKey, rc ); |
| 404 | return rc; |
| 405 | } |
| 406 | } |
| 407 | return NULL; |
| 408 | } |
| @@ -934,20 +951,20 @@ | |
| 934 | */; |
| 935 | } |
| 936 | |
| 937 | {/* set up JSON output formatting options. */ |
| 938 | unsigned char indent = g.isHTTP ? 0 : 1; |
| 939 | cson_value const * indentV = json_getenv("indent"); |
| 940 | if(indentV){ |
| 941 | if(cson_value_is_string(indentV)){ |
| 942 | int const n = atoi(cson_string_cstr(cson_value_get_string(indentV))); |
| 943 | indent = (n>0) |
| 944 | ? (unsigned char)n |
| 945 | : 0; |
| 946 | }else if(cson_value_is_number(indentV)){ |
| 947 | cson_int_t const n = cson_value_get_integer(indentV); |
| 948 | indent = (n>0) ? (unsigned char)n : 0; |
| 949 | } |
| 950 | } |
| 951 | g.json.outOpt.indentation = indent; |
| 952 | g.json.outOpt.addNewline = g.isHTTP |
| 953 | ? 0 |
| @@ -1357,33 +1374,33 @@ | |
| 1357 | } |
| 1358 | db_finalize(&q); |
| 1359 | cson_object_set( obj, "permissionFlags", sub ); |
| 1360 | obj = cson_value_get_object(sub); |
| 1361 | |
| 1362 | #define ADD(X) cson_object_set(obj, #X, cson_value_new_bool(g.perm.X)) |
| 1363 | ADD(Setup); |
| 1364 | ADD(Admin); |
| 1365 | ADD(Delete); |
| 1366 | ADD(Password); |
| 1367 | ADD(Query); |
| 1368 | ADD(Write); |
| 1369 | ADD(Read); |
| 1370 | ADD(History); |
| 1371 | ADD(Clone); |
| 1372 | ADD(RdWiki); |
| 1373 | ADD(NewWiki); |
| 1374 | ADD(ApndWiki); |
| 1375 | ADD(WrWiki); |
| 1376 | ADD(RdTkt); |
| 1377 | ADD(NewTkt); |
| 1378 | ADD(ApndTkt); |
| 1379 | ADD(WrTkt); |
| 1380 | ADD(Attach); |
| 1381 | ADD(TktFmt); |
| 1382 | ADD(RdAddr); |
| 1383 | ADD(Zip); |
| 1384 | ADD(Private); |
| 1385 | #undef ADD |
| 1386 | return payload; |
| 1387 | } |
| 1388 | |
| 1389 | /* |
| 1390 |
| --- src/json.c | |
| +++ src/json.c | |
| @@ -391,18 +391,35 @@ | |
| 391 | if(rc){ |
| 392 | return rc; |
| 393 | }else{ |
| 394 | char const * cv = PD(zKey,NULL); |
| 395 | if(!cv){ |
| 396 | /* reminder to self: in CLI mode i'd like to try |
| 397 | find_option(zKey,NULL,XYZ) here, but we don't have a sane |
| 398 | default for the XYZ param here. |
| 399 | */ |
| 400 | cv = getenv(zKey); |
| 401 | } |
| 402 | if(cv){/*transform it to JSON for later use.*/ |
| 403 | /* use sscanf() to figure out if it's an int, |
| 404 | and transform it to JSON int if it is. |
| 405 | */ |
| 406 | int intVal = -1; |
| 407 | char endOfIntCheck; |
| 408 | int const scanRc = sscanf(cv,"%d%c",&intVal, &endOfIntCheck) |
| 409 | /* The %c bit there is to make sure that we don't accept 123x |
| 410 | as a number. sscanf() returns the number of tokens |
| 411 | successfully parsed, so an RC of 1 will be correct for "123" |
| 412 | but "123x" will have RC==2. |
| 413 | */ |
| 414 | ; |
| 415 | if(1==scanRc){ |
| 416 | json_setenv( zKey, cson_value_new_integer(intVal) ); |
| 417 | }else{ |
| 418 | rc = cson_value_new_string(cv,strlen(cv)); |
| 419 | json_setenv( zKey, rc ); |
| 420 | } |
| 421 | return rc; |
| 422 | } |
| 423 | } |
| 424 | return NULL; |
| 425 | } |
| @@ -934,20 +951,20 @@ | |
| 951 | */; |
| 952 | } |
| 953 | |
| 954 | {/* set up JSON output formatting options. */ |
| 955 | unsigned char indent = g.isHTTP ? 0 : 1; |
| 956 | char const * indentStr = NULL; |
| 957 | if( g.isHTTP ){ |
| 958 | indent = (unsigned char)json_getenv_int("indent",(int)indent); |
| 959 | }else{/*CLI mode*/ |
| 960 | indentStr = find_option("indent","I",1); |
| 961 | if(indentStr){ |
| 962 | int const n = atoi(indentStr); |
| 963 | indent = (n>0) |
| 964 | ? (unsigned char)n |
| 965 | : 0; |
| 966 | } |
| 967 | } |
| 968 | g.json.outOpt.indentation = indent; |
| 969 | g.json.outOpt.addNewline = g.isHTTP |
| 970 | ? 0 |
| @@ -1357,33 +1374,33 @@ | |
| 1374 | } |
| 1375 | db_finalize(&q); |
| 1376 | cson_object_set( obj, "permissionFlags", sub ); |
| 1377 | obj = cson_value_get_object(sub); |
| 1378 | |
| 1379 | #define ADD(X,K) cson_object_set(obj, K, cson_value_new_bool(g.perm.X)) |
| 1380 | ADD(Setup,"setup"); |
| 1381 | ADD(Admin,"admin"); |
| 1382 | ADD(Delete,"delete"); |
| 1383 | ADD(Password,"password"); |
| 1384 | ADD(Query,"query"); /* don't think this one is actually used */ |
| 1385 | ADD(Write,"checkin"); |
| 1386 | ADD(Read,"checkout"); |
| 1387 | ADD(History,"history"); |
| 1388 | ADD(Clone,"clone"); |
| 1389 | ADD(RdWiki,"readWiki"); |
| 1390 | ADD(NewWiki,"createWiki"); |
| 1391 | ADD(ApndWiki,"appendWiki"); |
| 1392 | ADD(WrWiki,"editWiki"); |
| 1393 | ADD(RdTkt,"readTicket"); |
| 1394 | ADD(NewTkt,"createTicket"); |
| 1395 | ADD(ApndTkt,"appendTicket"); |
| 1396 | ADD(WrTkt,"editTicket"); |
| 1397 | ADD(Attach,"attachFile"); |
| 1398 | ADD(TktFmt,"createTicketReport"); |
| 1399 | ADD(RdAddr,"readPrivate"); |
| 1400 | ADD(Zip,"zip"); |
| 1401 | ADD(Private,"xferPrivate"); |
| 1402 | #undef ADD |
| 1403 | return payload; |
| 1404 | } |
| 1405 | |
| 1406 | /* |
| 1407 |