Fossil SCM

Add the TH1 'dir' command, with docs and tests.

mistachkin 2015-08-27 04:38 trunk merge
Commit f4ceace8f574c0350948c7d630af8923fa8d7103
+9 -4
--- src/doc.c
+++ src/doc.c
@@ -522,14 +522,16 @@
522522
** for looking at what a file will look like using the /doc webpage after
523523
** it gets checked in.
524524
**
525525
** The file extension is used to decide how to render the file.
526526
**
527
-** If FILE ends in "/" then names "FILE/index.html", "FILE/index.wiki",
528
-** and "FILE/index.md" are tried in that order. If none of those are found,
529
-** then FILE is completely replaced by "404.md" and tried. If that is
530
-** not found, then a default 404 screen is generated.
527
+** If FILE ends in "/" then the names "FILE/index.html", "FILE/index.wiki",
528
+** and "FILE/index.md" are tried in that order. If the binary was compiled
529
+** with TH1 embedded documentation support and the "th1-docs" setting is
530
+** enabled, the name "FILE/index.th1" is also tried. If none of those are
531
+** found, then FILE is completely replaced by "404.md" and tried. If that
532
+** is not found, then a default 404 screen is generated.
531533
*/
532534
void doc_page(void){
533535
const char *zName; /* Argument to the /doc page */
534536
const char *zOrigName = "?"; /* Original document name */
535537
const char *zMime; /* Document MIME type */
@@ -540,10 +542,13 @@
540542
Blob filebody; /* Content of the documentation file */
541543
Blob title; /* Document title */
542544
int nMiss = (-1); /* Failed attempts to find the document */
543545
static const char *const azSuffix[] = {
544546
"index.html", "index.wiki", "index.md"
547
+#ifdef FOSSIL_ENABLE_TH1_DOCS
548
+ , "index.th1"
549
+#endif
545550
};
546551
547552
login_check_credentials();
548553
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
549554
blob_init(&title, 0, 0);
550555
--- src/doc.c
+++ src/doc.c
@@ -522,14 +522,16 @@
522 ** for looking at what a file will look like using the /doc webpage after
523 ** it gets checked in.
524 **
525 ** The file extension is used to decide how to render the file.
526 **
527 ** If FILE ends in "/" then names "FILE/index.html", "FILE/index.wiki",
528 ** and "FILE/index.md" are tried in that order. If none of those are found,
529 ** then FILE is completely replaced by "404.md" and tried. If that is
530 ** not found, then a default 404 screen is generated.
 
 
531 */
532 void doc_page(void){
533 const char *zName; /* Argument to the /doc page */
534 const char *zOrigName = "?"; /* Original document name */
535 const char *zMime; /* Document MIME type */
@@ -540,10 +542,13 @@
540 Blob filebody; /* Content of the documentation file */
541 Blob title; /* Document title */
542 int nMiss = (-1); /* Failed attempts to find the document */
543 static const char *const azSuffix[] = {
544 "index.html", "index.wiki", "index.md"
 
 
 
545 };
546
547 login_check_credentials();
548 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
549 blob_init(&title, 0, 0);
550
--- src/doc.c
+++ src/doc.c
@@ -522,14 +522,16 @@
522 ** for looking at what a file will look like using the /doc webpage after
523 ** it gets checked in.
524 **
525 ** The file extension is used to decide how to render the file.
526 **
527 ** If FILE ends in "/" then the names "FILE/index.html", "FILE/index.wiki",
528 ** and "FILE/index.md" are tried in that order. If the binary was compiled
529 ** with TH1 embedded documentation support and the "th1-docs" setting is
530 ** enabled, the name "FILE/index.th1" is also tried. If none of those are
531 ** found, then FILE is completely replaced by "404.md" and tried. If that
532 ** is not found, then a default 404 screen is generated.
533 */
534 void doc_page(void){
535 const char *zName; /* Argument to the /doc page */
536 const char *zOrigName = "?"; /* Original document name */
537 const char *zMime; /* Document MIME type */
@@ -540,10 +542,13 @@
542 Blob filebody; /* Content of the documentation file */
543 Blob title; /* Document title */
544 int nMiss = (-1); /* Failed attempts to find the document */
545 static const char *const azSuffix[] = {
546 "index.html", "index.wiki", "index.md"
547 #ifdef FOSSIL_ENABLE_TH1_DOCS
548 , "index.th1"
549 #endif
550 };
551
552 login_check_credentials();
553 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
554 blob_init(&title, 0, 0);
555
--- src/th_main.c
+++ src/th_main.c
@@ -142,10 +142,103 @@
142142
fossil_print("\n------------------ BEGIN TRACE LOG ------------------\n");
143143
fossil_print("%s", blob_str(&g.thLog));
144144
fossil_print("\n------------------- END TRACE LOG -------------------\n");
145145
}
146146
}
147
+
148
+/*
149
+** - adopted from ls_cmd_rev in checkin.c
150
+** - adopted commands/error handling for usage within th1
151
+** - interface adopted to allow result creation as TH1 List
152
+**
153
+** Takes a checkin identifier in zRev and an optiona glob pattern in zGLOB
154
+** as parameter returns a TH list in pzList,pnList with filenames matching
155
+** glob pattern with the checking
156
+*/
157
+static void dir_cmd_rev(
158
+ Th_Interp *interp,
159
+ char **pzList,
160
+ int *pnList,
161
+ const char *zRev, /* Revision string given */
162
+ const char *zGlob, /* Glob pattern given */
163
+ int bDetails
164
+){
165
+ Stmt q;
166
+ char *zOrderBy = "pathname COLLATE nocase";
167
+ int rid;
168
+
169
+ rid = th1_name_to_typed_rid(interp, zRev, "ci");
170
+ compute_fileage(rid, zGlob);
171
+ db_prepare(&q,
172
+ "SELECT datetime(fileage.mtime, 'localtime'), fileage.pathname,\n"
173
+ " blob.size\n"
174
+ " FROM fileage, blob\n"
175
+ " WHERE blob.rid=fileage.fid \n"
176
+ " ORDER BY %s;", zOrderBy /*safe-for-%s*/
177
+ );
178
+ while( db_step(&q)==SQLITE_ROW ){
179
+ const char *zFile = db_column_text(&q, 1);
180
+ if( bDetails ){
181
+ const char *zTime = db_column_text(&q, 0);
182
+ int size = db_column_int(&q, 2);
183
+ char zSize[50];
184
+ char *zSubList = 0;
185
+ int nSubList = 0;
186
+ sqlite3_snprintf(sizeof(zSize), zSize, "%d", size);
187
+ Th_ListAppend(interp, &zSubList, &nSubList, zFile, -1);
188
+ Th_ListAppend(interp, &zSubList, &nSubList, zSize, -1);
189
+ Th_ListAppend(interp, &zSubList, &nSubList, zTime, -1);
190
+ Th_ListAppend(interp, pzList, pnList, zSubList, -1);
191
+ Th_Free(interp, zSubList);
192
+ }else{
193
+ Th_ListAppend(interp, pzList, pnList, zFile, -1);
194
+ }
195
+ }
196
+ db_finalize(&q);
197
+}
198
+
199
+/*
200
+** TH1 command: dir CHECKIN ?GLOB? ?DETAILS?
201
+**
202
+** Returns a list containing all files in CHECKIN. If GLOB is given only
203
+** the files matching the pattern GLOB within CHECKIN will be returned.
204
+** If DETAILS is non-zero, the result will be a list-of-lists, with each
205
+** element containing at least three elements: the file name, the file
206
+** size (in bytes), and the file last modification time (relative to the
207
+** time zone configured for the repository).
208
+*/
209
+static int dirCmd(
210
+ Th_Interp *interp,
211
+ void *ctx,
212
+ int argc,
213
+ const char **argv,
214
+ int *argl
215
+){
216
+ const char *zGlob = 0;
217
+ int bDetails = 0;
218
+
219
+ if( argc<2 || argc>4 ){
220
+ return Th_WrongNumArgs(interp, "dir CHECKIN ?GLOB? ?DETAILS?");
221
+ }
222
+ if( argc>=3 ){
223
+ zGlob = argv[2];
224
+ }
225
+ if( argc>=4 && Th_ToInt(interp, argv[3], argl[3], &bDetails) ){
226
+ return TH_ERROR;
227
+ }
228
+ if( Th_IsRepositoryOpen() ){
229
+ char *zList = 0;
230
+ int nList = 0;
231
+ dir_cmd_rev(interp, &zList, &nList, argv[1], zGlob, bDetails);
232
+ Th_SetResult(interp, zList, nList);
233
+ Th_Free(interp, zList);
234
+ return TH_OK;
235
+ }else{
236
+ Th_SetResult(interp, "repository unavailable", -1);
237
+ return TH_ERROR;
238
+ }
239
+}
147240
148241
/*
149242
** TH1 command: httpize STRING
150243
**
151244
** Escape all characters of STRING which have special meaning in URI
@@ -1632,10 +1725,11 @@
16321725
{"artifact", artifactCmd, 0},
16331726
{"checkout", checkoutCmd, 0},
16341727
{"combobox", comboboxCmd, 0},
16351728
{"date", dateCmd, 0},
16361729
{"decorate", wikiCmd, (void*)&aFlags[2]},
1730
+ {"dir", dirCmd, 0},
16371731
{"enable_output", enableOutputCmd, 0},
16381732
{"getParameter", getParameterCmd, 0},
16391733
{"glob_match", globMatchCmd, 0},
16401734
{"globalState", globalStateCmd, 0},
16411735
{"httpize", httpizeCmd, 0},
16421736
16431737
ADDED test/th1-repo.test
--- src/th_main.c
+++ src/th_main.c
@@ -142,10 +142,103 @@
142 fossil_print("\n------------------ BEGIN TRACE LOG ------------------\n");
143 fossil_print("%s", blob_str(&g.thLog));
144 fossil_print("\n------------------- END TRACE LOG -------------------\n");
145 }
146 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
148 /*
149 ** TH1 command: httpize STRING
150 **
151 ** Escape all characters of STRING which have special meaning in URI
@@ -1632,10 +1725,11 @@
1632 {"artifact", artifactCmd, 0},
1633 {"checkout", checkoutCmd, 0},
1634 {"combobox", comboboxCmd, 0},
1635 {"date", dateCmd, 0},
1636 {"decorate", wikiCmd, (void*)&aFlags[2]},
 
1637 {"enable_output", enableOutputCmd, 0},
1638 {"getParameter", getParameterCmd, 0},
1639 {"glob_match", globMatchCmd, 0},
1640 {"globalState", globalStateCmd, 0},
1641 {"httpize", httpizeCmd, 0},
1642
1643 DDED test/th1-repo.test
--- src/th_main.c
+++ src/th_main.c
@@ -142,10 +142,103 @@
142 fossil_print("\n------------------ BEGIN TRACE LOG ------------------\n");
143 fossil_print("%s", blob_str(&g.thLog));
144 fossil_print("\n------------------- END TRACE LOG -------------------\n");
145 }
146 }
147
148 /*
149 ** - adopted from ls_cmd_rev in checkin.c
150 ** - adopted commands/error handling for usage within th1
151 ** - interface adopted to allow result creation as TH1 List
152 **
153 ** Takes a checkin identifier in zRev and an optiona glob pattern in zGLOB
154 ** as parameter returns a TH list in pzList,pnList with filenames matching
155 ** glob pattern with the checking
156 */
157 static void dir_cmd_rev(
158 Th_Interp *interp,
159 char **pzList,
160 int *pnList,
161 const char *zRev, /* Revision string given */
162 const char *zGlob, /* Glob pattern given */
163 int bDetails
164 ){
165 Stmt q;
166 char *zOrderBy = "pathname COLLATE nocase";
167 int rid;
168
169 rid = th1_name_to_typed_rid(interp, zRev, "ci");
170 compute_fileage(rid, zGlob);
171 db_prepare(&q,
172 "SELECT datetime(fileage.mtime, 'localtime'), fileage.pathname,\n"
173 " blob.size\n"
174 " FROM fileage, blob\n"
175 " WHERE blob.rid=fileage.fid \n"
176 " ORDER BY %s;", zOrderBy /*safe-for-%s*/
177 );
178 while( db_step(&q)==SQLITE_ROW ){
179 const char *zFile = db_column_text(&q, 1);
180 if( bDetails ){
181 const char *zTime = db_column_text(&q, 0);
182 int size = db_column_int(&q, 2);
183 char zSize[50];
184 char *zSubList = 0;
185 int nSubList = 0;
186 sqlite3_snprintf(sizeof(zSize), zSize, "%d", size);
187 Th_ListAppend(interp, &zSubList, &nSubList, zFile, -1);
188 Th_ListAppend(interp, &zSubList, &nSubList, zSize, -1);
189 Th_ListAppend(interp, &zSubList, &nSubList, zTime, -1);
190 Th_ListAppend(interp, pzList, pnList, zSubList, -1);
191 Th_Free(interp, zSubList);
192 }else{
193 Th_ListAppend(interp, pzList, pnList, zFile, -1);
194 }
195 }
196 db_finalize(&q);
197 }
198
199 /*
200 ** TH1 command: dir CHECKIN ?GLOB? ?DETAILS?
201 **
202 ** Returns a list containing all files in CHECKIN. If GLOB is given only
203 ** the files matching the pattern GLOB within CHECKIN will be returned.
204 ** If DETAILS is non-zero, the result will be a list-of-lists, with each
205 ** element containing at least three elements: the file name, the file
206 ** size (in bytes), and the file last modification time (relative to the
207 ** time zone configured for the repository).
208 */
209 static int dirCmd(
210 Th_Interp *interp,
211 void *ctx,
212 int argc,
213 const char **argv,
214 int *argl
215 ){
216 const char *zGlob = 0;
217 int bDetails = 0;
218
219 if( argc<2 || argc>4 ){
220 return Th_WrongNumArgs(interp, "dir CHECKIN ?GLOB? ?DETAILS?");
221 }
222 if( argc>=3 ){
223 zGlob = argv[2];
224 }
225 if( argc>=4 && Th_ToInt(interp, argv[3], argl[3], &bDetails) ){
226 return TH_ERROR;
227 }
228 if( Th_IsRepositoryOpen() ){
229 char *zList = 0;
230 int nList = 0;
231 dir_cmd_rev(interp, &zList, &nList, argv[1], zGlob, bDetails);
232 Th_SetResult(interp, zList, nList);
233 Th_Free(interp, zList);
234 return TH_OK;
235 }else{
236 Th_SetResult(interp, "repository unavailable", -1);
237 return TH_ERROR;
238 }
239 }
240
241 /*
242 ** TH1 command: httpize STRING
243 **
244 ** Escape all characters of STRING which have special meaning in URI
@@ -1632,10 +1725,11 @@
1725 {"artifact", artifactCmd, 0},
1726 {"checkout", checkoutCmd, 0},
1727 {"combobox", comboboxCmd, 0},
1728 {"date", dateCmd, 0},
1729 {"decorate", wikiCmd, (void*)&aFlags[2]},
1730 {"dir", dirCmd, 0},
1731 {"enable_output", enableOutputCmd, 0},
1732 {"getParameter", getParameterCmd, 0},
1733 {"glob_match", globMatchCmd, 0},
1734 {"globalState", globalStateCmd, 0},
1735 {"httpize", httpizeCmd, 0},
1736
1737 DDED test/th1-repo.test
--- a/test/th1-repo.test
+++ b/test/th1-repo.test
@@ -0,0 +1,39 @@
1
+#
2
+# Copyright (c) 2011 D. Richard Hipp
3
+# Copyright (c) 2015 Ch. Drexler
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
+# Chris Drexler <[email protected]>
18
+#
19
+############################################################################
20
+#
21
+# TH1 tests that macatch {exec $::fossilexe info} res
22
+if {![regexp {use --repository} $res]} {
23
+ puts stderr "Cannot run this test within an open checkout"
24
+ return
25
+}
26
+
27
+
28
+# Setup: Add Files and Commit #
29
+########################################
30
+
31
+test_setup; set rootDir [firepo_init (c) 2011 D. Richard Hipp
32
+# Copyright (c) 2015 Ch. Drexler
33
+#
34
+# This program is free software; you can redistribute it and/or
35
+# modify it under the terms of the Simplified BSD License (also
36
+# known as the "2-Clause License" or "FreeBSD License".)
37
+#
38
+# This program is distributed in the hope that it will be useful,
39
+# but without any warranty; without even th
--- a/test/th1-repo.test
+++ b/test/th1-repo.test
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/test/th1-repo.test
+++ b/test/th1-repo.test
@@ -0,0 +1,39 @@
1 #
2 # Copyright (c) 2011 D. Richard Hipp
3 # Copyright (c) 2015 Ch. Drexler
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 # Chris Drexler <[email protected]>
18 #
19 ############################################################################
20 #
21 # TH1 tests that macatch {exec $::fossilexe info} res
22 if {![regexp {use --repository} $res]} {
23 puts stderr "Cannot run this test within an open checkout"
24 return
25 }
26
27
28 # Setup: Add Files and Commit #
29 ########################################
30
31 test_setup; set rootDir [firepo_init (c) 2011 D. Richard Hipp
32 # Copyright (c) 2015 Ch. Drexler
33 #
34 # This program is free software; you can redistribute it and/or
35 # modify it under the terms of the Simplified BSD License (also
36 # known as the "2-Clause License" or "FreeBSD License".)
37 #
38 # This program is distributed in the hope that it will be useful,
39 # but without any warranty; without even th
+1 -1
--- test/th1.test
+++ test/th1.test
@@ -861,11 +861,11 @@
861861
# NOTE: This test may fail if the command names do not always come
862862
# out in a deterministic order from TH1.
863863
#
864864
fossil test-th-eval "info commands"
865865
test th1-info-commands-1 {$RESULT eq {linecount htmlize date stime\
866
-enable_output uplevel http expr glob_match utime styleFooter catch if\
866
+enable_output uplevel dir http expr glob_match utime styleFooter catch if\
867867
tclReady searchable reinitialize combobox lindex query html anoncap randhex\
868868
llength for set break regexp markdown styleHeader puts return checkout\
869869
decorate artifact trace wiki proc hascap globalState continue getParameter\
870870
hasfeature setting lsearch breakpoint upvar render repository string unset\
871871
setParameter list error info rename anycap httpize}}
872872
--- test/th1.test
+++ test/th1.test
@@ -861,11 +861,11 @@
861 # NOTE: This test may fail if the command names do not always come
862 # out in a deterministic order from TH1.
863 #
864 fossil test-th-eval "info commands"
865 test th1-info-commands-1 {$RESULT eq {linecount htmlize date stime\
866 enable_output uplevel http expr glob_match utime styleFooter catch if\
867 tclReady searchable reinitialize combobox lindex query html anoncap randhex\
868 llength for set break regexp markdown styleHeader puts return checkout\
869 decorate artifact trace wiki proc hascap globalState continue getParameter\
870 hasfeature setting lsearch breakpoint upvar render repository string unset\
871 setParameter list error info rename anycap httpize}}
872
--- test/th1.test
+++ test/th1.test
@@ -861,11 +861,11 @@
861 # NOTE: This test may fail if the command names do not always come
862 # out in a deterministic order from TH1.
863 #
864 fossil test-th-eval "info commands"
865 test th1-info-commands-1 {$RESULT eq {linecount htmlize date stime\
866 enable_output uplevel dir http expr glob_match utime styleFooter catch if\
867 tclReady searchable reinitialize combobox lindex query html anoncap randhex\
868 llength for set break regexp markdown styleHeader puts return checkout\
869 decorate artifact trace wiki proc hascap globalState continue getParameter\
870 hasfeature setting lsearch breakpoint upvar render repository string unset\
871 setParameter list error info rename anycap httpize}}
872
+13
--- www/th1.md
+++ www/th1.md
@@ -129,10 +129,11 @@
129129
* artifact
130130
* checkout
131131
* combobox
132132
* date
133133
* decorate
134
+ * dir
134135
* enable_output
135136
* getParameter
136137
* glob_match
137138
* globalState
138139
* hascap
@@ -234,10 +235,22 @@
234235
* decorate STRING
235236
236237
Renders STRING as wiki content; however, only links are handled. No
237238
other markup is processed.
238239
240
+<a name="dir"></a>TH1 dir Command
241
+-------------------------------------------
242
+
243
+ * dir CHECKIN ?GLOB?
244
+
245
+Returns a list containing all files in CHECKIN. If GLOB is given only
246
+the files matching the pattern GLOB within CHECKIN will be returned.
247
+If DETAILS is non-zero, the result will be a list-of-lists, with each
248
+element containing at least three elements: the file name, the file
249
+size (in bytes), and the file last modification time (relative to the
250
+time zone configured for the repository).
251
+
239252
<a name="enable_output"></a>TH1 enable_output Command
240253
-----------------------------------------------------
241254
242255
* enable_output BOOLEAN
243256
244257
--- www/th1.md
+++ www/th1.md
@@ -129,10 +129,11 @@
129 * artifact
130 * checkout
131 * combobox
132 * date
133 * decorate
 
134 * enable_output
135 * getParameter
136 * glob_match
137 * globalState
138 * hascap
@@ -234,10 +235,22 @@
234 * decorate STRING
235
236 Renders STRING as wiki content; however, only links are handled. No
237 other markup is processed.
238
 
 
 
 
 
 
 
 
 
 
 
 
239 <a name="enable_output"></a>TH1 enable_output Command
240 -----------------------------------------------------
241
242 * enable_output BOOLEAN
243
244
--- www/th1.md
+++ www/th1.md
@@ -129,10 +129,11 @@
129 * artifact
130 * checkout
131 * combobox
132 * date
133 * decorate
134 * dir
135 * enable_output
136 * getParameter
137 * glob_match
138 * globalState
139 * hascap
@@ -234,10 +235,22 @@
235 * decorate STRING
236
237 Renders STRING as wiki content; however, only links are handled. No
238 other markup is processed.
239
240 <a name="dir"></a>TH1 dir Command
241 -------------------------------------------
242
243 * dir CHECKIN ?GLOB?
244
245 Returns a list containing all files in CHECKIN. If GLOB is given only
246 the files matching the pattern GLOB within CHECKIN will be returned.
247 If DETAILS is non-zero, the result will be a list-of-lists, with each
248 element containing at least three elements: the file name, the file
249 size (in bytes), and the file last modification time (relative to the
250 time zone configured for the repository).
251
252 <a name="enable_output"></a>TH1 enable_output Command
253 -----------------------------------------------------
254
255 * enable_output BOOLEAN
256
257

Keyboard Shortcuts

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