Fossil SCM

Added -- support to wiki create/commit/export. Refactored/simplified how fetching of a dash-as-stdin/stdout argument is done from command-side code.

stephan 2019-09-27 14:32 UTC double-dash-flag
Commit dba4fd9b69c5d8c7cb24d6874dcbcc826c5306b69fa303423fe4b3d01b768d52
3 files changed +43 -2 +18 -10 +17 -11
+43 -2
--- src/main.c
+++ src/main.c
@@ -141,10 +141,13 @@
141141
};
142142
#endif
143143
144144
struct Global {
145145
int argc; char **argv; /* Command-line arguments to the program */
146
+ int argDashDashIndex; /* Index of the "--" flag in g.argv, if provided
147
+ ** (else 0). Not valid until verify_all_options()
148
+ ** or verify_all_options2() is called. */;
146149
char *nameOfExe; /* Full path of executable. */
147150
const char *zErrlog; /* Log errors to this file, if not NULL */
148151
int isConst; /* True if the output is unchanging & cacheable */
149152
const char *zVfsName; /* The VFS to use for database connections */
150153
sqlite3 *db; /* The connection to the databases */
@@ -1046,28 +1049,29 @@
10461049
** encountered.
10471050
**
10481051
** Returns false (0) if fAllowDoubleDash is false or if "--" is not
10491052
** encountered. If fAllowDoubleDash is true and "--" is encountered,
10501053
** the argument index (in g.argv) at which "--" was encountered (and
1051
-** removed) is returned.
1054
+** removed) is returned (that value will always be greater than 0).
10521055
**
10531056
** Sidebar: the question of whether fAllowDoubleDash should be true or
10541057
** false would seem to boil down to: does the calling routine
10551058
** expect/allow arbitrary file/page/branch/whatever name arguments
10561059
** after its required arguments?
10571060
*/
10581061
static int verify_all_options_impl(int fAllowDoubleDash){
10591062
int i;
1063
+ g.argDashDashIndex = 0;
10601064
for(i=1; i<g.argc; i++){
10611065
const char * arg = g.argv[i];
10621066
if( arg[0]=='-' ){
10631067
if( arg[1]=='-' && arg[2]==0 ){
10641068
if(fAllowDoubleDash){
10651069
/* Remove "--" from the list and assume any following
10661070
** arguments are file names. */
10671071
remove_from_argv(i, 1);
1068
- return i;
1072
+ return g.argDashDashIndex = i;
10691073
}else{
10701074
fossil_fatal("The -- flag is not allowed here.");
10711075
}
10721076
}else if( arg[1]!=0 ){
10731077
fossil_fatal(
@@ -1095,10 +1099,47 @@
10951099
** flag and returns true (non-0) if that flag was encountered/consumed.
10961100
*/
10971101
int verify_all_options2(void){
10981102
return verify_all_options_impl(1);
10991103
}
1104
+
1105
+/*
1106
+** Expects nArgPos to be a valid index of g.argv. If nArgPos is a
1107
+** string with the value "-" and g.argDashDashIndex is greater than 0
1108
+** and <= nArgPos then the value "-" gets transformed to "./-". In all
1109
+** other cases, the value of g.argv[nArgPos] is returned as-is.
1110
+**
1111
+** The intention is that this function be called by commands which
1112
+** accept a filename argument for which "-" is interpreted as stdin or
1113
+** stdout. If the "--" flag was found BEFORE that filename flag then
1114
+** "-" is transformed such that it will be seen as a file named "./-"
1115
+** rather than "-" (stdin or stdout, depending on the context). Returns
1116
+** a string from g.argv or the static string "./-", so its lifetime is
1117
+** effectively that of the app.
1118
+*/
1119
+const char * get_dash_filename_arg(int nArgPos){
1120
+ const char * zName;
1121
+ assert(nArgPos < g.argc);
1122
+ zName = g.argv[nArgPos];
1123
+ if(zName!=0
1124
+ && g.argDashDashIndex>0 && g.argDashDashIndex<=nArgPos
1125
+ && fossil_strcmp("-",zName)==0){
1126
+ zName = "./-";
1127
+ }
1128
+ return zName;
1129
+};
1130
+
1131
+/*
1132
+ ** Only for debugging during "--"-related refactoring. To be deleted
1133
+ ** before merging with trunk.
1134
+ */
1135
+void dump_g_argv(){
1136
+ int i;
1137
+ for( i = 0; i < g.argc; ++i ){
1138
+ fossil_print("\tg.argv[%d] = %s\n", i, g.argv[i]);
1139
+ }
1140
+}
11001141
11011142
/*
11021143
** This function returns a human readable version string.
11031144
*/
11041145
const char *get_version(){
11051146
--- src/main.c
+++ src/main.c
@@ -141,10 +141,13 @@
141 };
142 #endif
143
144 struct Global {
145 int argc; char **argv; /* Command-line arguments to the program */
 
 
 
146 char *nameOfExe; /* Full path of executable. */
147 const char *zErrlog; /* Log errors to this file, if not NULL */
148 int isConst; /* True if the output is unchanging & cacheable */
149 const char *zVfsName; /* The VFS to use for database connections */
150 sqlite3 *db; /* The connection to the databases */
@@ -1046,28 +1049,29 @@
1046 ** encountered.
1047 **
1048 ** Returns false (0) if fAllowDoubleDash is false or if "--" is not
1049 ** encountered. If fAllowDoubleDash is true and "--" is encountered,
1050 ** the argument index (in g.argv) at which "--" was encountered (and
1051 ** removed) is returned.
1052 **
1053 ** Sidebar: the question of whether fAllowDoubleDash should be true or
1054 ** false would seem to boil down to: does the calling routine
1055 ** expect/allow arbitrary file/page/branch/whatever name arguments
1056 ** after its required arguments?
1057 */
1058 static int verify_all_options_impl(int fAllowDoubleDash){
1059 int i;
 
1060 for(i=1; i<g.argc; i++){
1061 const char * arg = g.argv[i];
1062 if( arg[0]=='-' ){
1063 if( arg[1]=='-' && arg[2]==0 ){
1064 if(fAllowDoubleDash){
1065 /* Remove "--" from the list and assume any following
1066 ** arguments are file names. */
1067 remove_from_argv(i, 1);
1068 return i;
1069 }else{
1070 fossil_fatal("The -- flag is not allowed here.");
1071 }
1072 }else if( arg[1]!=0 ){
1073 fossil_fatal(
@@ -1095,10 +1099,47 @@
1095 ** flag and returns true (non-0) if that flag was encountered/consumed.
1096 */
1097 int verify_all_options2(void){
1098 return verify_all_options_impl(1);
1099 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1100
1101 /*
1102 ** This function returns a human readable version string.
1103 */
1104 const char *get_version(){
1105
--- src/main.c
+++ src/main.c
@@ -141,10 +141,13 @@
141 };
142 #endif
143
144 struct Global {
145 int argc; char **argv; /* Command-line arguments to the program */
146 int argDashDashIndex; /* Index of the "--" flag in g.argv, if provided
147 ** (else 0). Not valid until verify_all_options()
148 ** or verify_all_options2() is called. */;
149 char *nameOfExe; /* Full path of executable. */
150 const char *zErrlog; /* Log errors to this file, if not NULL */
151 int isConst; /* True if the output is unchanging & cacheable */
152 const char *zVfsName; /* The VFS to use for database connections */
153 sqlite3 *db; /* The connection to the databases */
@@ -1046,28 +1049,29 @@
1049 ** encountered.
1050 **
1051 ** Returns false (0) if fAllowDoubleDash is false or if "--" is not
1052 ** encountered. If fAllowDoubleDash is true and "--" is encountered,
1053 ** the argument index (in g.argv) at which "--" was encountered (and
1054 ** removed) is returned (that value will always be greater than 0).
1055 **
1056 ** Sidebar: the question of whether fAllowDoubleDash should be true or
1057 ** false would seem to boil down to: does the calling routine
1058 ** expect/allow arbitrary file/page/branch/whatever name arguments
1059 ** after its required arguments?
1060 */
1061 static int verify_all_options_impl(int fAllowDoubleDash){
1062 int i;
1063 g.argDashDashIndex = 0;
1064 for(i=1; i<g.argc; i++){
1065 const char * arg = g.argv[i];
1066 if( arg[0]=='-' ){
1067 if( arg[1]=='-' && arg[2]==0 ){
1068 if(fAllowDoubleDash){
1069 /* Remove "--" from the list and assume any following
1070 ** arguments are file names. */
1071 remove_from_argv(i, 1);
1072 return g.argDashDashIndex = i;
1073 }else{
1074 fossil_fatal("The -- flag is not allowed here.");
1075 }
1076 }else if( arg[1]!=0 ){
1077 fossil_fatal(
@@ -1095,10 +1099,47 @@
1099 ** flag and returns true (non-0) if that flag was encountered/consumed.
1100 */
1101 int verify_all_options2(void){
1102 return verify_all_options_impl(1);
1103 }
1104
1105 /*
1106 ** Expects nArgPos to be a valid index of g.argv. If nArgPos is a
1107 ** string with the value "-" and g.argDashDashIndex is greater than 0
1108 ** and <= nArgPos then the value "-" gets transformed to "./-". In all
1109 ** other cases, the value of g.argv[nArgPos] is returned as-is.
1110 **
1111 ** The intention is that this function be called by commands which
1112 ** accept a filename argument for which "-" is interpreted as stdin or
1113 ** stdout. If the "--" flag was found BEFORE that filename flag then
1114 ** "-" is transformed such that it will be seen as a file named "./-"
1115 ** rather than "-" (stdin or stdout, depending on the context). Returns
1116 ** a string from g.argv or the static string "./-", so its lifetime is
1117 ** effectively that of the app.
1118 */
1119 const char * get_dash_filename_arg(int nArgPos){
1120 const char * zName;
1121 assert(nArgPos < g.argc);
1122 zName = g.argv[nArgPos];
1123 if(zName!=0
1124 && g.argDashDashIndex>0 && g.argDashDashIndex<=nArgPos
1125 && fossil_strcmp("-",zName)==0){
1126 zName = "./-";
1127 }
1128 return zName;
1129 };
1130
1131 /*
1132 ** Only for debugging during "--"-related refactoring. To be deleted
1133 ** before merging with trunk.
1134 */
1135 void dump_g_argv(){
1136 int i;
1137 for( i = 0; i < g.argc; ++i ){
1138 fossil_print("\tg.argv[%d] = %s\n", i, g.argv[i]);
1139 }
1140 }
1141
1142 /*
1143 ** This function returns a human readable version string.
1144 */
1145 const char *get_version(){
1146
+18 -10
--- src/unversioned.c
+++ src/unversioned.c
@@ -296,14 +296,13 @@
296296
const char *zIn;
297297
const char *zAs;
298298
const char *zFileArg;
299299
Blob file;
300300
int i;
301
- int fDoubleDash; /* True if "--" flag is provided */
302301
zAs = find_option("as",0,1);
303
- fDoubleDash = verify_all_options2();
304
- if( zAs && g.argc!=4 ) usage("add DISKFILE --as UVFILE");
302
+ verify_all_options2();
303
+ if( zAs && g.argc!=4 ) usage("add --as UVFILE [--] DISKFILE");
305304
db_begin_transaction();
306305
content_rcvid_init("#!fossil unversioned add");
307306
for(i=3; i<g.argc; i++){
308307
zIn = zAs ? zAs : g.argv[i];
309308
if( zIn[0]==0 ){
@@ -317,15 +316,11 @@
317316
}
318317
if( zError ){
319318
fossil_fatal("unversioned filenames may not %s: %Q", zError, zIn);
320319
}
321320
blob_init(&file,0,0);
322
- zFileArg = g.argv[i];
323
- if(fDoubleDash>0 && fDoubleDash<=i
324
- && fossil_strcmp("-",zFileArg)==0){
325
- zFileArg = "./-" /* do not treat "-" as stdin! */;
326
- }
321
+ zFileArg = get_dash_filename_arg(i);
327322
blob_read_from_file(&file, zFileArg, ExtFILE);
328323
unversioned_write(zIn, &file, mtime);
329324
blob_reset(&file);
330325
}
331326
db_end_transaction(0);
@@ -382,16 +377,29 @@
382377
unversioned_write(zUVFile, &content, mtime);
383378
db_end_transaction(0);
384379
blob_reset(&content);
385380
}else if( memcmp(zCmd, "export", nCmd)==0 ){
386381
Blob content;
382
+ const char * zOutfile;
387383
verify_all_options2();
388
- if( g.argc!=5 ) usage("export UVFILE OUTPUT");
384
+ if( g.argc!=5 ) usage("export [--] UVFILE OUTPUT");
389385
if( unversioned_content(g.argv[3], &content) ){
390386
fossil_fatal("no such uv-file: %Q", g.argv[3]);
391387
}
392
- blob_write_to_file(&content, g.argv[4]);
388
+ /*
389
+ ** Pathological(?) corner case:
390
+ **
391
+ ** export -- --UVFILE -
392
+ **
393
+ ** We have no way of applying -- to just the UVFILE name but not
394
+ ** the output file name, so the above would output the uv file
395
+ ** literally named --UVFILE to a file literally named -. The only
396
+ ** alternative is that we never apply -- to the output file name,
397
+ ** which seems likely to cause yet more confusion.
398
+ */
399
+ zOutfile = get_dash_filename_arg(4);
400
+ blob_write_to_file(&content, zOutfile);
393401
blob_reset(&content);
394402
}else if( memcmp(zCmd, "hash", nCmd)==0 ){ /* undocumented */
395403
/* Show the hash value used during uv sync */
396404
int debugFlag = find_option("debug",0,0)!=0;
397405
fossil_print("%s\n", unversioned_content_hash(debugFlag));
398406
--- src/unversioned.c
+++ src/unversioned.c
@@ -296,14 +296,13 @@
296 const char *zIn;
297 const char *zAs;
298 const char *zFileArg;
299 Blob file;
300 int i;
301 int fDoubleDash; /* True if "--" flag is provided */
302 zAs = find_option("as",0,1);
303 fDoubleDash = verify_all_options2();
304 if( zAs && g.argc!=4 ) usage("add DISKFILE --as UVFILE");
305 db_begin_transaction();
306 content_rcvid_init("#!fossil unversioned add");
307 for(i=3; i<g.argc; i++){
308 zIn = zAs ? zAs : g.argv[i];
309 if( zIn[0]==0 ){
@@ -317,15 +316,11 @@
317 }
318 if( zError ){
319 fossil_fatal("unversioned filenames may not %s: %Q", zError, zIn);
320 }
321 blob_init(&file,0,0);
322 zFileArg = g.argv[i];
323 if(fDoubleDash>0 && fDoubleDash<=i
324 && fossil_strcmp("-",zFileArg)==0){
325 zFileArg = "./-" /* do not treat "-" as stdin! */;
326 }
327 blob_read_from_file(&file, zFileArg, ExtFILE);
328 unversioned_write(zIn, &file, mtime);
329 blob_reset(&file);
330 }
331 db_end_transaction(0);
@@ -382,16 +377,29 @@
382 unversioned_write(zUVFile, &content, mtime);
383 db_end_transaction(0);
384 blob_reset(&content);
385 }else if( memcmp(zCmd, "export", nCmd)==0 ){
386 Blob content;
 
387 verify_all_options2();
388 if( g.argc!=5 ) usage("export UVFILE OUTPUT");
389 if( unversioned_content(g.argv[3], &content) ){
390 fossil_fatal("no such uv-file: %Q", g.argv[3]);
391 }
392 blob_write_to_file(&content, g.argv[4]);
 
 
 
 
 
 
 
 
 
 
 
 
393 blob_reset(&content);
394 }else if( memcmp(zCmd, "hash", nCmd)==0 ){ /* undocumented */
395 /* Show the hash value used during uv sync */
396 int debugFlag = find_option("debug",0,0)!=0;
397 fossil_print("%s\n", unversioned_content_hash(debugFlag));
398
--- src/unversioned.c
+++ src/unversioned.c
@@ -296,14 +296,13 @@
296 const char *zIn;
297 const char *zAs;
298 const char *zFileArg;
299 Blob file;
300 int i;
 
301 zAs = find_option("as",0,1);
302 verify_all_options2();
303 if( zAs && g.argc!=4 ) usage("add --as UVFILE [--] DISKFILE");
304 db_begin_transaction();
305 content_rcvid_init("#!fossil unversioned add");
306 for(i=3; i<g.argc; i++){
307 zIn = zAs ? zAs : g.argv[i];
308 if( zIn[0]==0 ){
@@ -317,15 +316,11 @@
316 }
317 if( zError ){
318 fossil_fatal("unversioned filenames may not %s: %Q", zError, zIn);
319 }
320 blob_init(&file,0,0);
321 zFileArg = get_dash_filename_arg(i);
 
 
 
 
322 blob_read_from_file(&file, zFileArg, ExtFILE);
323 unversioned_write(zIn, &file, mtime);
324 blob_reset(&file);
325 }
326 db_end_transaction(0);
@@ -382,16 +377,29 @@
377 unversioned_write(zUVFile, &content, mtime);
378 db_end_transaction(0);
379 blob_reset(&content);
380 }else if( memcmp(zCmd, "export", nCmd)==0 ){
381 Blob content;
382 const char * zOutfile;
383 verify_all_options2();
384 if( g.argc!=5 ) usage("export [--] UVFILE OUTPUT");
385 if( unversioned_content(g.argv[3], &content) ){
386 fossil_fatal("no such uv-file: %Q", g.argv[3]);
387 }
388 /*
389 ** Pathological(?) corner case:
390 **
391 ** export -- --UVFILE -
392 **
393 ** We have no way of applying -- to just the UVFILE name but not
394 ** the output file name, so the above would output the uv file
395 ** literally named --UVFILE to a file literally named -. The only
396 ** alternative is that we never apply -- to the output file name,
397 ** which seems likely to cause yet more confusion.
398 */
399 zOutfile = get_dash_filename_arg(4);
400 blob_write_to_file(&content, zOutfile);
401 blob_reset(&content);
402 }else if( memcmp(zCmd, "hash", nCmd)==0 ){ /* undocumented */
403 /* Show the hash value used during uv sync */
404 int debugFlag = find_option("debug",0,0)!=0;
405 fossil_print("%s\n", unversioned_content_hash(debugFlag));
406
+17 -11
--- src/wiki.c
+++ src/wiki.c
@@ -1364,12 +1364,12 @@
13641364
**
13651365
** Usage: %fossil wiki (export|create|commit|list) WikiName
13661366
**
13671367
** Run various subcommands to work with wiki entries or tech notes.
13681368
**
1369
-** %fossil wiki export PAGENAME ?FILE?
1370
-** %fossil wiki export ?FILE? -t|--technote DATETIME|TECHNOTE-ID
1369
+** %fossil wiki export PAGENAME [--] ?FILE?
1370
+** %fossil wiki export -t|--technote DATETIME|TECHNOTE-ID [--] ?FILE?
13711371
**
13721372
** Sends the latest version of either a wiki page or of a tech note
13731373
** to the given file or standard output.
13741374
** If PAGENAME is provided, the wiki page will be output. For
13751375
** a tech note either DATETIME or TECHNOTE-ID must be specified. If
@@ -1425,10 +1425,15 @@
14251425
** year-month-day form, it may be truncated, the "T" may be replaced by
14261426
** a space, and it may also name a timezone offset from UTC as "-HH:MM"
14271427
** (westward) or "+HH:MM" (eastward). Either no timezone suffix or "Z"
14281428
** means UTC.
14291429
**
1430
+** Options:
1431
+** -- For commands which support this, it means to treat
1432
+** all subsequent arguments as file names even if they
1433
+** start with a "-".
1434
+**
14301435
*/
14311436
void wiki_cmd(void){
14321437
int n;
14331438
db_find_and_open_repository(0, 0);
14341439
if( g.argc<3 ){
@@ -1436,25 +1441,24 @@
14361441
}
14371442
n = strlen(g.argv[2]);
14381443
if( n==0 ){
14391444
goto wiki_cmd_usage;
14401445
}
1441
-
14421446
if( strncmp(g.argv[2],"export",n)==0 ){
14431447
const char *zPageName; /* Name of the wiki page to export */
14441448
const char *zFile; /* Name of the output file (0=stdout) */
14451449
const char *zETime; /* The name of the technote to export */
14461450
int rid; /* Artifact ID of the wiki page */
14471451
int i; /* Loop counter */
14481452
char *zBody = 0; /* Wiki page content */
14491453
Blob body; /* Wiki page content */
14501454
Manifest *pWiki = 0; /* Parsed wiki page content */
1451
-
14521455
zETime = find_option("technote","t",1);
1456
+ verify_all_options2();
14531457
if( !zETime ){
14541458
if( (g.argc!=4) && (g.argc!=5) ){
1455
- usage("export PAGENAME ?FILE?");
1459
+ usage("export PAGENAME [--] ?FILE?");
14561460
}
14571461
zPageName = g.argv[3];
14581462
rid = db_int(0, "SELECT x.rid FROM tag t, tagxref x"
14591463
" WHERE x.tagid=t.tagid AND t.tagname='wiki-%q'"
14601464
" ORDER BY x.mtime DESC LIMIT 1",
@@ -1464,14 +1468,14 @@
14641468
zBody = pWiki->zWiki;
14651469
}
14661470
if( zBody==0 ){
14671471
fossil_fatal("wiki page [%s] not found",zPageName);
14681472
}
1469
- zFile = (g.argc==4) ? "-" : g.argv[4];
1473
+ zFile = g.argc==4 ? "-" : get_dash_filename_arg(4);
14701474
}else{
14711475
if( (g.argc!=3) && (g.argc!=4) ){
1472
- usage("export ?FILE? --technote DATETIME|TECHNOTE-ID");
1476
+ usage("export --technote DATETIME|TECHNOTE-ID [--] ?FILE?");
14731477
}
14741478
rid = wiki_technote_to_rid(zETime);
14751479
if ( rid==-1 ){
14761480
fossil_fatal("ambiguous tech note id: %s", zETime);
14771481
}
@@ -1479,11 +1483,11 @@
14791483
zBody = pWiki->zWiki;
14801484
}
14811485
if( zBody==0 ){
14821486
fossil_fatal("technote [%s] not found",zETime);
14831487
}
1484
- zFile = (g.argc==3) ? "-" : g.argv[3];
1488
+ zFile = g.argc==3 ? "-" : get_dash_filename_arg(3);
14851489
}
14861490
for(i=strlen(zBody); i>0 && fossil_isspace(zBody[i-1]); i--){}
14871491
zBody[i] = 0;
14881492
blob_init(&body, zBody, -1);
14891493
blob_append(&body, "\n", 1);
@@ -1499,20 +1503,22 @@
14991503
Manifest *pWiki = 0; /* Parsed wiki page content */
15001504
const char *zMimeType = find_option("mimetype", "M", 1);
15011505
const char *zETime = find_option("technote", "t", 1);
15021506
const char *zTags = find_option("technote-tags", NULL, 1);
15031507
const char *zClr = find_option("technote-bgcolor", NULL, 1);
1508
+ verify_all_options2();
15041509
if( g.argc!=4 && g.argc!=5 ){
1505
- usage("commit|create PAGENAME ?FILE? [--mimetype TEXT-FORMAT]"
1510
+ usage("commit|create PAGENAME [--mimetype TEXT-FORMAT]"
15061511
" [--technote DATETIME] [--technote-tags TAGS]"
1507
- " [--technote-bgcolor COLOR]");
1512
+ " [--technote-bgcolor COLOR] [--] ?FILE?");
15081513
}
15091514
zPageName = g.argv[3];
15101515
if( g.argc==4 ){
15111516
blob_read_from_channel(&content, stdin, -1);
15121517
}else{
1513
- blob_read_from_file(&content, g.argv[4], ExtFILE);
1518
+ const char * zFilename = get_dash_filename_arg(4);
1519
+ blob_read_from_file(&content, zFilename, ExtFILE);
15141520
}
15151521
if( !zMimeType || !*zMimeType ){
15161522
/* Try to deduce the mime type based on the prior version. */
15171523
if ( !zETime ){
15181524
rid = db_int(0, "SELECT x.rid FROM tag t, tagxref x"
15191525
--- src/wiki.c
+++ src/wiki.c
@@ -1364,12 +1364,12 @@
1364 **
1365 ** Usage: %fossil wiki (export|create|commit|list) WikiName
1366 **
1367 ** Run various subcommands to work with wiki entries or tech notes.
1368 **
1369 ** %fossil wiki export PAGENAME ?FILE?
1370 ** %fossil wiki export ?FILE? -t|--technote DATETIME|TECHNOTE-ID
1371 **
1372 ** Sends the latest version of either a wiki page or of a tech note
1373 ** to the given file or standard output.
1374 ** If PAGENAME is provided, the wiki page will be output. For
1375 ** a tech note either DATETIME or TECHNOTE-ID must be specified. If
@@ -1425,10 +1425,15 @@
1425 ** year-month-day form, it may be truncated, the "T" may be replaced by
1426 ** a space, and it may also name a timezone offset from UTC as "-HH:MM"
1427 ** (westward) or "+HH:MM" (eastward). Either no timezone suffix or "Z"
1428 ** means UTC.
1429 **
 
 
 
 
 
1430 */
1431 void wiki_cmd(void){
1432 int n;
1433 db_find_and_open_repository(0, 0);
1434 if( g.argc<3 ){
@@ -1436,25 +1441,24 @@
1436 }
1437 n = strlen(g.argv[2]);
1438 if( n==0 ){
1439 goto wiki_cmd_usage;
1440 }
1441
1442 if( strncmp(g.argv[2],"export",n)==0 ){
1443 const char *zPageName; /* Name of the wiki page to export */
1444 const char *zFile; /* Name of the output file (0=stdout) */
1445 const char *zETime; /* The name of the technote to export */
1446 int rid; /* Artifact ID of the wiki page */
1447 int i; /* Loop counter */
1448 char *zBody = 0; /* Wiki page content */
1449 Blob body; /* Wiki page content */
1450 Manifest *pWiki = 0; /* Parsed wiki page content */
1451
1452 zETime = find_option("technote","t",1);
 
1453 if( !zETime ){
1454 if( (g.argc!=4) && (g.argc!=5) ){
1455 usage("export PAGENAME ?FILE?");
1456 }
1457 zPageName = g.argv[3];
1458 rid = db_int(0, "SELECT x.rid FROM tag t, tagxref x"
1459 " WHERE x.tagid=t.tagid AND t.tagname='wiki-%q'"
1460 " ORDER BY x.mtime DESC LIMIT 1",
@@ -1464,14 +1468,14 @@
1464 zBody = pWiki->zWiki;
1465 }
1466 if( zBody==0 ){
1467 fossil_fatal("wiki page [%s] not found",zPageName);
1468 }
1469 zFile = (g.argc==4) ? "-" : g.argv[4];
1470 }else{
1471 if( (g.argc!=3) && (g.argc!=4) ){
1472 usage("export ?FILE? --technote DATETIME|TECHNOTE-ID");
1473 }
1474 rid = wiki_technote_to_rid(zETime);
1475 if ( rid==-1 ){
1476 fossil_fatal("ambiguous tech note id: %s", zETime);
1477 }
@@ -1479,11 +1483,11 @@
1479 zBody = pWiki->zWiki;
1480 }
1481 if( zBody==0 ){
1482 fossil_fatal("technote [%s] not found",zETime);
1483 }
1484 zFile = (g.argc==3) ? "-" : g.argv[3];
1485 }
1486 for(i=strlen(zBody); i>0 && fossil_isspace(zBody[i-1]); i--){}
1487 zBody[i] = 0;
1488 blob_init(&body, zBody, -1);
1489 blob_append(&body, "\n", 1);
@@ -1499,20 +1503,22 @@
1499 Manifest *pWiki = 0; /* Parsed wiki page content */
1500 const char *zMimeType = find_option("mimetype", "M", 1);
1501 const char *zETime = find_option("technote", "t", 1);
1502 const char *zTags = find_option("technote-tags", NULL, 1);
1503 const char *zClr = find_option("technote-bgcolor", NULL, 1);
 
1504 if( g.argc!=4 && g.argc!=5 ){
1505 usage("commit|create PAGENAME ?FILE? [--mimetype TEXT-FORMAT]"
1506 " [--technote DATETIME] [--technote-tags TAGS]"
1507 " [--technote-bgcolor COLOR]");
1508 }
1509 zPageName = g.argv[3];
1510 if( g.argc==4 ){
1511 blob_read_from_channel(&content, stdin, -1);
1512 }else{
1513 blob_read_from_file(&content, g.argv[4], ExtFILE);
 
1514 }
1515 if( !zMimeType || !*zMimeType ){
1516 /* Try to deduce the mime type based on the prior version. */
1517 if ( !zETime ){
1518 rid = db_int(0, "SELECT x.rid FROM tag t, tagxref x"
1519
--- src/wiki.c
+++ src/wiki.c
@@ -1364,12 +1364,12 @@
1364 **
1365 ** Usage: %fossil wiki (export|create|commit|list) WikiName
1366 **
1367 ** Run various subcommands to work with wiki entries or tech notes.
1368 **
1369 ** %fossil wiki export PAGENAME [--] ?FILE?
1370 ** %fossil wiki export -t|--technote DATETIME|TECHNOTE-ID [--] ?FILE?
1371 **
1372 ** Sends the latest version of either a wiki page or of a tech note
1373 ** to the given file or standard output.
1374 ** If PAGENAME is provided, the wiki page will be output. For
1375 ** a tech note either DATETIME or TECHNOTE-ID must be specified. If
@@ -1425,10 +1425,15 @@
1425 ** year-month-day form, it may be truncated, the "T" may be replaced by
1426 ** a space, and it may also name a timezone offset from UTC as "-HH:MM"
1427 ** (westward) or "+HH:MM" (eastward). Either no timezone suffix or "Z"
1428 ** means UTC.
1429 **
1430 ** Options:
1431 ** -- For commands which support this, it means to treat
1432 ** all subsequent arguments as file names even if they
1433 ** start with a "-".
1434 **
1435 */
1436 void wiki_cmd(void){
1437 int n;
1438 db_find_and_open_repository(0, 0);
1439 if( g.argc<3 ){
@@ -1436,25 +1441,24 @@
1441 }
1442 n = strlen(g.argv[2]);
1443 if( n==0 ){
1444 goto wiki_cmd_usage;
1445 }
 
1446 if( strncmp(g.argv[2],"export",n)==0 ){
1447 const char *zPageName; /* Name of the wiki page to export */
1448 const char *zFile; /* Name of the output file (0=stdout) */
1449 const char *zETime; /* The name of the technote to export */
1450 int rid; /* Artifact ID of the wiki page */
1451 int i; /* Loop counter */
1452 char *zBody = 0; /* Wiki page content */
1453 Blob body; /* Wiki page content */
1454 Manifest *pWiki = 0; /* Parsed wiki page content */
 
1455 zETime = find_option("technote","t",1);
1456 verify_all_options2();
1457 if( !zETime ){
1458 if( (g.argc!=4) && (g.argc!=5) ){
1459 usage("export PAGENAME [--] ?FILE?");
1460 }
1461 zPageName = g.argv[3];
1462 rid = db_int(0, "SELECT x.rid FROM tag t, tagxref x"
1463 " WHERE x.tagid=t.tagid AND t.tagname='wiki-%q'"
1464 " ORDER BY x.mtime DESC LIMIT 1",
@@ -1464,14 +1468,14 @@
1468 zBody = pWiki->zWiki;
1469 }
1470 if( zBody==0 ){
1471 fossil_fatal("wiki page [%s] not found",zPageName);
1472 }
1473 zFile = g.argc==4 ? "-" : get_dash_filename_arg(4);
1474 }else{
1475 if( (g.argc!=3) && (g.argc!=4) ){
1476 usage("export --technote DATETIME|TECHNOTE-ID [--] ?FILE?");
1477 }
1478 rid = wiki_technote_to_rid(zETime);
1479 if ( rid==-1 ){
1480 fossil_fatal("ambiguous tech note id: %s", zETime);
1481 }
@@ -1479,11 +1483,11 @@
1483 zBody = pWiki->zWiki;
1484 }
1485 if( zBody==0 ){
1486 fossil_fatal("technote [%s] not found",zETime);
1487 }
1488 zFile = g.argc==3 ? "-" : get_dash_filename_arg(3);
1489 }
1490 for(i=strlen(zBody); i>0 && fossil_isspace(zBody[i-1]); i--){}
1491 zBody[i] = 0;
1492 blob_init(&body, zBody, -1);
1493 blob_append(&body, "\n", 1);
@@ -1499,20 +1503,22 @@
1503 Manifest *pWiki = 0; /* Parsed wiki page content */
1504 const char *zMimeType = find_option("mimetype", "M", 1);
1505 const char *zETime = find_option("technote", "t", 1);
1506 const char *zTags = find_option("technote-tags", NULL, 1);
1507 const char *zClr = find_option("technote-bgcolor", NULL, 1);
1508 verify_all_options2();
1509 if( g.argc!=4 && g.argc!=5 ){
1510 usage("commit|create PAGENAME [--mimetype TEXT-FORMAT]"
1511 " [--technote DATETIME] [--technote-tags TAGS]"
1512 " [--technote-bgcolor COLOR] [--] ?FILE?");
1513 }
1514 zPageName = g.argv[3];
1515 if( g.argc==4 ){
1516 blob_read_from_channel(&content, stdin, -1);
1517 }else{
1518 const char * zFilename = get_dash_filename_arg(4);
1519 blob_read_from_file(&content, zFilename, ExtFILE);
1520 }
1521 if( !zMimeType || !*zMimeType ){
1522 /* Try to deduce the mime type based on the prior version. */
1523 if ( !zETime ){
1524 rid = db_int(0, "SELECT x.rid FROM tag t, tagxref x"
1525

Keyboard Shortcuts

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