Fossil SCM

Add the "help" command and the "clean" command. More work is needed on the text for various help messages.

drh 2007-08-18 02:45 trunk
Commit c9fdb846fb169e3789256688942b56e5c4fa390f
+4 -1
--- src/add.c
+++ src/add.c
@@ -30,12 +30,13 @@
3030
3131
3232
/*
3333
** COMMAND: add
3434
**
35
+** Usage: %fossil add FILE...
3536
** Add one or more files to the current checkout such that these files
36
-** will be added to the repository at the next checkin.
37
+** will be inserted into the repository at the next commit.
3738
*/
3839
void add_cmd(void){
3940
int i;
4041
int vid;
4142
@@ -80,10 +81,12 @@
8081
8182
/*
8283
** COMMAND: rm
8384
** COMMAND: del
8485
**
86
+** Usage: %fossil rm FILE...
87
+** or: %fossil del FILE...
8588
** Remove one or more files from the tree.
8689
*/
8790
void del_cmd(void){
8891
int i;
8992
int vid;
9093
--- src/add.c
+++ src/add.c
@@ -30,12 +30,13 @@
30
31
32 /*
33 ** COMMAND: add
34 **
 
35 ** Add one or more files to the current checkout such that these files
36 ** will be added to the repository at the next checkin.
37 */
38 void add_cmd(void){
39 int i;
40 int vid;
41
@@ -80,10 +81,12 @@
80
81 /*
82 ** COMMAND: rm
83 ** COMMAND: del
84 **
 
 
85 ** Remove one or more files from the tree.
86 */
87 void del_cmd(void){
88 int i;
89 int vid;
90
--- src/add.c
+++ src/add.c
@@ -30,12 +30,13 @@
30
31
32 /*
33 ** COMMAND: add
34 **
35 ** Usage: %fossil add FILE...
36 ** Add one or more files to the current checkout such that these files
37 ** will be inserted into the repository at the next commit.
38 */
39 void add_cmd(void){
40 int i;
41 int vid;
42
@@ -80,10 +81,12 @@
81
82 /*
83 ** COMMAND: rm
84 ** COMMAND: del
85 **
86 ** Usage: %fossil rm FILE...
87 ** or: %fossil del FILE...
88 ** Remove one or more files from the tree.
89 */
90 void del_cmd(void){
91 int i;
92 int vid;
93
+43 -12
--- src/checkin.c
+++ src/checkin.c
@@ -70,11 +70,13 @@
7070
}
7171
7272
/*
7373
** COMMAND: changes
7474
**
75
-** Report on the current status of all files.
75
+** Usage: %fossil changes
76
+** Report on the edit status of all files in the current checkout.
77
+** See also the "status" and "extra" commands.
7678
*/
7779
void changes_cmd(void){
7880
Blob report;
7981
int vid;
8082
db_must_be_within_tree();
@@ -85,10 +87,12 @@
8587
blob_write_to_file(&report, "-");
8688
}
8789
8890
/*
8991
** COMMAND: status
92
+** Usage: %fossil status
93
+** Report on the status of the current checkout.
9094
*/
9195
void status_cmd(void){
9296
int vid;
9397
db_must_be_within_tree();
9498
/* 012345678901234 */
@@ -102,12 +106,12 @@
102106
changes_cmd();
103107
}
104108
105109
/*
106110
** COMMAND: ls
107
-**
108
-** Show all files currently in the repository
111
+** Usage: %fossil ls
112
+** Show the names of all files in the current checkout
109113
*/
110114
void ls_cmd(void){
111115
int vid;
112116
Stmt q;
113117
@@ -134,32 +138,56 @@
134138
db_finalize(&q);
135139
}
136140
137141
/*
138142
** COMMAND: extra
139
-**
143
+** Usage: %fossil extra
140144
** Print a list of all files in the source tree that are not part of
141
-** the project
145
+** the current checkout. See also the "clean" command.
142146
*/
143147
void extra_cmd(void){
144148
Blob path;
145149
Stmt q;
146150
db_must_be_within_tree();
147151
db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY)");
148152
chdir(g.zLocalRoot);
149153
blob_zero(&path);
150154
vfile_scan(0, &path);
151
- db_multi_exec("DELETE FROM sfile WHERE x='FOSSIL'");
152155
db_prepare(&q,
153156
"SELECT x FROM sfile"
154157
" WHERE x NOT IN ('manifest','_FOSSIL_')"
155158
" ORDER BY 1");
156159
while( db_step(&q)==SQLITE_ROW ){
157160
printf("%s\n", db_column_text(&q, 0));
158161
}
159162
db_finalize(&q);
160163
}
164
+
165
+/*
166
+** COMMAND: clean
167
+** Usage: %fossil clean
168
+** Delete all "extra" files in the source tree. "Extra" files are
169
+** files that are not officially part of the checkout. See also
170
+** the "extra" command.
171
+*/
172
+void clean_cmd(void){
173
+ Blob path;
174
+ Stmt q;
175
+ db_must_be_within_tree();
176
+ db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY)");
177
+ chdir(g.zLocalRoot);
178
+ blob_zero(&path);
179
+ vfile_scan(0, &path);
180
+ db_prepare(&q,
181
+ "SELECT %Q || x FROM sfile"
182
+ " WHERE x NOT IN ('manifest','_FOSSIL_')"
183
+ " ORDER BY 1", g.zLocalRoot);
184
+ while( db_step(&q)==SQLITE_ROW ){
185
+ unlink(db_column_text(&q, 0));
186
+ }
187
+ db_finalize(&q);
188
+}
161189
162190
/*
163191
** Prepare a commit comment. Let the user modify it using the
164192
** editor specified in the global_config table or either
165193
** the VISUAL or EDITOR environment variable.
@@ -191,10 +219,11 @@
191219
}
192220
zFile = db_text(0, "SELECT '%qci-comment-' || hex(randomblob(6)) || '.txt'",
193221
g.zLocalRoot);
194222
blob_write_to_file(&text, zFile);
195223
zCmd = mprintf("%s %s", zEditor, zFile);
224
+ printf("%s\n", zCmd);
196225
if( system(zCmd) ){
197226
fossil_panic("editor aborted");
198227
}
199228
blob_reset(&text);
200229
blob_read_from_file(&text, zFile);
@@ -255,17 +284,19 @@
255284
}
256285
257286
/*
258287
** COMMAND: commit
259288
**
260
-** Create a new version containing all of the changes in the current
261
-** checkout. A commit is a three step process:
289
+** Usage: %fossil commit ?-m COMMENT? ?--nosign? ?FILE...?
262290
**
263
-** 1) Add the new content to the blob table,
264
-** 2) Create and add the new manifest to the blob table,
265
-** 3) Update the vfile table,
266
-** 4) Run checks to make sure everything is still internally consistent.
291
+** Create a new version containing all of the changes in the current
292
+** checkout. You will be prompted to enter a check-in comment unless
293
+** the "-m" option is used to specify a command line. You will be
294
+** prompted for your GPG passphrase in order to sign the new manifest
295
+** unless the "--nosign" options is used. All files that have
296
+** changed will be committed unless some subset of files is specified
297
+** on the command line.
267298
*/
268299
void commit_cmd(void){
269300
int rc;
270301
int vid, nrid, nvid;
271302
Blob comment;
272303
--- src/checkin.c
+++ src/checkin.c
@@ -70,11 +70,13 @@
70 }
71
72 /*
73 ** COMMAND: changes
74 **
75 ** Report on the current status of all files.
 
 
76 */
77 void changes_cmd(void){
78 Blob report;
79 int vid;
80 db_must_be_within_tree();
@@ -85,10 +87,12 @@
85 blob_write_to_file(&report, "-");
86 }
87
88 /*
89 ** COMMAND: status
 
 
90 */
91 void status_cmd(void){
92 int vid;
93 db_must_be_within_tree();
94 /* 012345678901234 */
@@ -102,12 +106,12 @@
102 changes_cmd();
103 }
104
105 /*
106 ** COMMAND: ls
107 **
108 ** Show all files currently in the repository
109 */
110 void ls_cmd(void){
111 int vid;
112 Stmt q;
113
@@ -134,32 +138,56 @@
134 db_finalize(&q);
135 }
136
137 /*
138 ** COMMAND: extra
139 **
140 ** Print a list of all files in the source tree that are not part of
141 ** the project
142 */
143 void extra_cmd(void){
144 Blob path;
145 Stmt q;
146 db_must_be_within_tree();
147 db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY)");
148 chdir(g.zLocalRoot);
149 blob_zero(&path);
150 vfile_scan(0, &path);
151 db_multi_exec("DELETE FROM sfile WHERE x='FOSSIL'");
152 db_prepare(&q,
153 "SELECT x FROM sfile"
154 " WHERE x NOT IN ('manifest','_FOSSIL_')"
155 " ORDER BY 1");
156 while( db_step(&q)==SQLITE_ROW ){
157 printf("%s\n", db_column_text(&q, 0));
158 }
159 db_finalize(&q);
160 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
161
162 /*
163 ** Prepare a commit comment. Let the user modify it using the
164 ** editor specified in the global_config table or either
165 ** the VISUAL or EDITOR environment variable.
@@ -191,10 +219,11 @@
191 }
192 zFile = db_text(0, "SELECT '%qci-comment-' || hex(randomblob(6)) || '.txt'",
193 g.zLocalRoot);
194 blob_write_to_file(&text, zFile);
195 zCmd = mprintf("%s %s", zEditor, zFile);
 
196 if( system(zCmd) ){
197 fossil_panic("editor aborted");
198 }
199 blob_reset(&text);
200 blob_read_from_file(&text, zFile);
@@ -255,17 +284,19 @@
255 }
256
257 /*
258 ** COMMAND: commit
259 **
260 ** Create a new version containing all of the changes in the current
261 ** checkout. A commit is a three step process:
262 **
263 ** 1) Add the new content to the blob table,
264 ** 2) Create and add the new manifest to the blob table,
265 ** 3) Update the vfile table,
266 ** 4) Run checks to make sure everything is still internally consistent.
 
 
 
267 */
268 void commit_cmd(void){
269 int rc;
270 int vid, nrid, nvid;
271 Blob comment;
272
--- src/checkin.c
+++ src/checkin.c
@@ -70,11 +70,13 @@
70 }
71
72 /*
73 ** COMMAND: changes
74 **
75 ** Usage: %fossil changes
76 ** Report on the edit status of all files in the current checkout.
77 ** See also the "status" and "extra" commands.
78 */
79 void changes_cmd(void){
80 Blob report;
81 int vid;
82 db_must_be_within_tree();
@@ -85,10 +87,12 @@
87 blob_write_to_file(&report, "-");
88 }
89
90 /*
91 ** COMMAND: status
92 ** Usage: %fossil status
93 ** Report on the status of the current checkout.
94 */
95 void status_cmd(void){
96 int vid;
97 db_must_be_within_tree();
98 /* 012345678901234 */
@@ -102,12 +106,12 @@
106 changes_cmd();
107 }
108
109 /*
110 ** COMMAND: ls
111 ** Usage: %fossil ls
112 ** Show the names of all files in the current checkout
113 */
114 void ls_cmd(void){
115 int vid;
116 Stmt q;
117
@@ -134,32 +138,56 @@
138 db_finalize(&q);
139 }
140
141 /*
142 ** COMMAND: extra
143 ** Usage: %fossil extra
144 ** Print a list of all files in the source tree that are not part of
145 ** the current checkout. See also the "clean" command.
146 */
147 void extra_cmd(void){
148 Blob path;
149 Stmt q;
150 db_must_be_within_tree();
151 db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY)");
152 chdir(g.zLocalRoot);
153 blob_zero(&path);
154 vfile_scan(0, &path);
 
155 db_prepare(&q,
156 "SELECT x FROM sfile"
157 " WHERE x NOT IN ('manifest','_FOSSIL_')"
158 " ORDER BY 1");
159 while( db_step(&q)==SQLITE_ROW ){
160 printf("%s\n", db_column_text(&q, 0));
161 }
162 db_finalize(&q);
163 }
164
165 /*
166 ** COMMAND: clean
167 ** Usage: %fossil clean
168 ** Delete all "extra" files in the source tree. "Extra" files are
169 ** files that are not officially part of the checkout. See also
170 ** the "extra" command.
171 */
172 void clean_cmd(void){
173 Blob path;
174 Stmt q;
175 db_must_be_within_tree();
176 db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY)");
177 chdir(g.zLocalRoot);
178 blob_zero(&path);
179 vfile_scan(0, &path);
180 db_prepare(&q,
181 "SELECT %Q || x FROM sfile"
182 " WHERE x NOT IN ('manifest','_FOSSIL_')"
183 " ORDER BY 1", g.zLocalRoot);
184 while( db_step(&q)==SQLITE_ROW ){
185 unlink(db_column_text(&q, 0));
186 }
187 db_finalize(&q);
188 }
189
190 /*
191 ** Prepare a commit comment. Let the user modify it using the
192 ** editor specified in the global_config table or either
193 ** the VISUAL or EDITOR environment variable.
@@ -191,10 +219,11 @@
219 }
220 zFile = db_text(0, "SELECT '%qci-comment-' || hex(randomblob(6)) || '.txt'",
221 g.zLocalRoot);
222 blob_write_to_file(&text, zFile);
223 zCmd = mprintf("%s %s", zEditor, zFile);
224 printf("%s\n", zCmd);
225 if( system(zCmd) ){
226 fossil_panic("editor aborted");
227 }
228 blob_reset(&text);
229 blob_read_from_file(&text, zFile);
@@ -255,17 +284,19 @@
284 }
285
286 /*
287 ** COMMAND: commit
288 **
289 ** Usage: %fossil commit ?-m COMMENT? ?--nosign? ?FILE...?
 
290 **
291 ** Create a new version containing all of the changes in the current
292 ** checkout. You will be prompted to enter a check-in comment unless
293 ** the "-m" option is used to specify a command line. You will be
294 ** prompted for your GPG passphrase in order to sign the new manifest
295 ** unless the "--nosign" options is used. All files that have
296 ** changed will be committed unless some subset of files is specified
297 ** on the command line.
298 */
299 void commit_cmd(void){
300 int rc;
301 int vid, nrid, nvid;
302 Blob comment;
303
+7 -1
--- src/checkout.c
+++ src/checkout.c
@@ -109,11 +109,16 @@
109109
}
110110
111111
/*
112112
** COMMAND: checkout
113113
**
114
-** Check out a version specified on the command-line.
114
+** Usage: %fossil checkout VERSION ?-f|--force?
115
+** Check out a version specified on the command-line. This command
116
+** will not overwrite edited files in the current checkout unless
117
+** the --force option appears on the command-line.
118
+**
119
+** See also the "update" command.
115120
*/
116121
void checkout_cmd(void){
117122
int forceFlag;
118123
int noWrite;
119124
int vid, prior;
@@ -159,10 +164,11 @@
159164
}
160165
161166
/*
162167
** COMMAND: close
163168
**
169
+** Usage: %fossil close ?-f|--force?
164170
** The opposite of "open". Close the current database connection.
165171
** Require a -f or --force flag if there are unsaved changed in the
166172
** current check-out.
167173
*/
168174
void close_cmd(void){
169175
--- src/checkout.c
+++ src/checkout.c
@@ -109,11 +109,16 @@
109 }
110
111 /*
112 ** COMMAND: checkout
113 **
114 ** Check out a version specified on the command-line.
 
 
 
 
 
115 */
116 void checkout_cmd(void){
117 int forceFlag;
118 int noWrite;
119 int vid, prior;
@@ -159,10 +164,11 @@
159 }
160
161 /*
162 ** COMMAND: close
163 **
 
164 ** The opposite of "open". Close the current database connection.
165 ** Require a -f or --force flag if there are unsaved changed in the
166 ** current check-out.
167 */
168 void close_cmd(void){
169
--- src/checkout.c
+++ src/checkout.c
@@ -109,11 +109,16 @@
109 }
110
111 /*
112 ** COMMAND: checkout
113 **
114 ** Usage: %fossil checkout VERSION ?-f|--force?
115 ** Check out a version specified on the command-line. This command
116 ** will not overwrite edited files in the current checkout unless
117 ** the --force option appears on the command-line.
118 **
119 ** See also the "update" command.
120 */
121 void checkout_cmd(void){
122 int forceFlag;
123 int noWrite;
124 int vid, prior;
@@ -159,10 +164,11 @@
164 }
165
166 /*
167 ** COMMAND: close
168 **
169 ** Usage: %fossil close ?-f|--force?
170 ** The opposite of "open". Close the current database connection.
171 ** Require a -f or --force flag if there are unsaved changed in the
172 ** current check-out.
173 */
174 void close_cmd(void){
175
+3 -2
--- src/clone.c
+++ src/clone.c
@@ -30,13 +30,14 @@
3030
3131
3232
/*
3333
** COMMAND: clone
3434
**
35
-** Make a clone of a repository in the local directory
35
+** Usage: %fossil clone URL FILENAME
3636
**
37
-** fossil clone FILE-OR-URL NEWDATABASE
37
+** Make a clone of a repository specified by URL in the local
38
+** file named FILENAME.
3839
*/
3940
void clone_cmd(void){
4041
if( g.argc!=4 ){
4142
usage("FILE-OR-URL NEW-REPOSITORY");
4243
}
4344
--- src/clone.c
+++ src/clone.c
@@ -30,13 +30,14 @@
30
31
32 /*
33 ** COMMAND: clone
34 **
35 ** Make a clone of a repository in the local directory
36 **
37 ** fossil clone FILE-OR-URL NEWDATABASE
 
38 */
39 void clone_cmd(void){
40 if( g.argc!=4 ){
41 usage("FILE-OR-URL NEW-REPOSITORY");
42 }
43
--- src/clone.c
+++ src/clone.c
@@ -30,13 +30,14 @@
30
31
32 /*
33 ** COMMAND: clone
34 **
35 ** Usage: %fossil clone URL FILENAME
36 **
37 ** Make a clone of a repository specified by URL in the local
38 ** file named FILENAME.
39 */
40 void clone_cmd(void){
41 if( g.argc!=4 ){
42 usage("FILE-OR-URL NEW-REPOSITORY");
43 }
44
+10 -5
--- src/db.c
+++ src/db.c
@@ -103,12 +103,11 @@
103103
/*
104104
** Prepare or reprepare the sqlite3 statement from the raw SQL text.
105105
*/
106106
static void reprepare(Stmt *pStmt){
107107
sqlite3_stmt *pNew;
108
- int rc;
109
- if( (rc = sqlite3_prepare(g.db, blob_buffer(&pStmt->sql), -1, &pNew, 0))!=0 ){
108
+ if( sqlite3_prepare(g.db, blob_buffer(&pStmt->sql), -1, &pNew, 0)!=0 ){
110109
db_err("%s\n%s", blob_str(&pStmt->sql), sqlite3_errmsg(g.db));
111110
}
112111
if( pStmt->pStmt ){
113112
sqlite3_transfer_bindings(pStmt->pStmt, pNew);
114113
sqlite3_finalize(pStmt->pStmt);
@@ -191,11 +190,11 @@
191190
/*
192191
** Step the SQL statement. Return either SQLITE_ROW or an error code
193192
** or SQLITE_OK if the statement finishes successfully.
194193
*/
195194
int db_step(Stmt *pStmt){
196
- int rc;
195
+ int rc = SQLITE_OK;
197196
int limit = 3;
198197
while( limit-- ){
199198
rc = sqlite3_step(pStmt->pStmt);
200199
if( rc==SQLITE_ERROR ){
201200
rc = sqlite3_reset(pStmt->pStmt);
@@ -647,11 +646,14 @@
647646
648647
649648
/*
650649
** COMMAND: new
651650
**
652
-** Create a new repository
651
+** Usage: %fossil new FILENAME
652
+** Create a repository for a new project in the file named FILENAME.
653
+** This command is distinct from "clone". The "clone" command makes
654
+** a copy of an existing project. This command starts a new project.
653655
*/
654656
void create_repository_cmd(void){
655657
char *zDate;
656658
char *zUser;
657659
Blob hash;
@@ -821,11 +823,14 @@
821823
}
822824
823825
/*
824826
** COMMAND: open
825827
**
826
-** Create a new local repository.
828
+** Usage: open FILENAME
829
+** Open a connection to the local repository in FILENAME. A checkout
830
+** for the repository is created with its root at the working directory.
831
+** See also the "close" command.
827832
*/
828833
void cmd_open(void){
829834
Blob path;
830835
if( g.argc!=3 ){
831836
usage("REPOSITORY-FILENAME");
832837
--- src/db.c
+++ src/db.c
@@ -103,12 +103,11 @@
103 /*
104 ** Prepare or reprepare the sqlite3 statement from the raw SQL text.
105 */
106 static void reprepare(Stmt *pStmt){
107 sqlite3_stmt *pNew;
108 int rc;
109 if( (rc = sqlite3_prepare(g.db, blob_buffer(&pStmt->sql), -1, &pNew, 0))!=0 ){
110 db_err("%s\n%s", blob_str(&pStmt->sql), sqlite3_errmsg(g.db));
111 }
112 if( pStmt->pStmt ){
113 sqlite3_transfer_bindings(pStmt->pStmt, pNew);
114 sqlite3_finalize(pStmt->pStmt);
@@ -191,11 +190,11 @@
191 /*
192 ** Step the SQL statement. Return either SQLITE_ROW or an error code
193 ** or SQLITE_OK if the statement finishes successfully.
194 */
195 int db_step(Stmt *pStmt){
196 int rc;
197 int limit = 3;
198 while( limit-- ){
199 rc = sqlite3_step(pStmt->pStmt);
200 if( rc==SQLITE_ERROR ){
201 rc = sqlite3_reset(pStmt->pStmt);
@@ -647,11 +646,14 @@
647
648
649 /*
650 ** COMMAND: new
651 **
652 ** Create a new repository
 
 
 
653 */
654 void create_repository_cmd(void){
655 char *zDate;
656 char *zUser;
657 Blob hash;
@@ -821,11 +823,14 @@
821 }
822
823 /*
824 ** COMMAND: open
825 **
826 ** Create a new local repository.
 
 
 
827 */
828 void cmd_open(void){
829 Blob path;
830 if( g.argc!=3 ){
831 usage("REPOSITORY-FILENAME");
832
--- src/db.c
+++ src/db.c
@@ -103,12 +103,11 @@
103 /*
104 ** Prepare or reprepare the sqlite3 statement from the raw SQL text.
105 */
106 static void reprepare(Stmt *pStmt){
107 sqlite3_stmt *pNew;
108 if( sqlite3_prepare(g.db, blob_buffer(&pStmt->sql), -1, &pNew, 0)!=0 ){
 
109 db_err("%s\n%s", blob_str(&pStmt->sql), sqlite3_errmsg(g.db));
110 }
111 if( pStmt->pStmt ){
112 sqlite3_transfer_bindings(pStmt->pStmt, pNew);
113 sqlite3_finalize(pStmt->pStmt);
@@ -191,11 +190,11 @@
190 /*
191 ** Step the SQL statement. Return either SQLITE_ROW or an error code
192 ** or SQLITE_OK if the statement finishes successfully.
193 */
194 int db_step(Stmt *pStmt){
195 int rc = SQLITE_OK;
196 int limit = 3;
197 while( limit-- ){
198 rc = sqlite3_step(pStmt->pStmt);
199 if( rc==SQLITE_ERROR ){
200 rc = sqlite3_reset(pStmt->pStmt);
@@ -647,11 +646,14 @@
646
647
648 /*
649 ** COMMAND: new
650 **
651 ** Usage: %fossil new FILENAME
652 ** Create a repository for a new project in the file named FILENAME.
653 ** This command is distinct from "clone". The "clone" command makes
654 ** a copy of an existing project. This command starts a new project.
655 */
656 void create_repository_cmd(void){
657 char *zDate;
658 char *zUser;
659 Blob hash;
@@ -821,11 +823,14 @@
823 }
824
825 /*
826 ** COMMAND: open
827 **
828 ** Usage: open FILENAME
829 ** Open a connection to the local repository in FILENAME. A checkout
830 ** for the repository is created with its root at the working directory.
831 ** See also the "close" command.
832 */
833 void cmd_open(void){
834 Blob path;
835 if( g.argc!=3 ){
836 usage("REPOSITORY-FILENAME");
837
--- src/descendents.c
+++ src/descendents.c
@@ -65,10 +65,11 @@
6565
}
6666
6767
/*
6868
** COMMAND: leaves
6969
**
70
+** Usage: %fossil leaves ?UUID?
7071
** Find all leaf descendents of the current version or of the
7172
** specified version.
7273
*/
7374
void leaves_cmd(void){
7475
Stmt q;
@@ -94,23 +95,17 @@
9495
}
9596
9697
/*
9798
** COMMAND: branches
9899
**
100
+** Usage: %fossil branches
99101
** Find leaves of all branches.
100102
*/
101103
void branches_cmd(void){
102104
Stmt q;
103
- int base;
104105
105106
db_must_be_within_tree();
106
- if( g.argc==2 ){
107
- base = db_lget_int("checkout", 0);
108
- }else{
109
- base = name_to_rid(g.argv[2]);
110
- }
111
- if( base==0 ) return;
112107
db_prepare(&q,
113108
"SELECT blob.uuid, datetime(event.mtime,'localtime'), event.comment"
114109
" FROM blob, event"
115110
" WHERE blob.rid IN"
116111
" (SELECT cid FROM plink EXCEPT SELECT pid FROM plink)"
117112
--- src/descendents.c
+++ src/descendents.c
@@ -65,10 +65,11 @@
65 }
66
67 /*
68 ** COMMAND: leaves
69 **
 
70 ** Find all leaf descendents of the current version or of the
71 ** specified version.
72 */
73 void leaves_cmd(void){
74 Stmt q;
@@ -94,23 +95,17 @@
94 }
95
96 /*
97 ** COMMAND: branches
98 **
 
99 ** Find leaves of all branches.
100 */
101 void branches_cmd(void){
102 Stmt q;
103 int base;
104
105 db_must_be_within_tree();
106 if( g.argc==2 ){
107 base = db_lget_int("checkout", 0);
108 }else{
109 base = name_to_rid(g.argv[2]);
110 }
111 if( base==0 ) return;
112 db_prepare(&q,
113 "SELECT blob.uuid, datetime(event.mtime,'localtime'), event.comment"
114 " FROM blob, event"
115 " WHERE blob.rid IN"
116 " (SELECT cid FROM plink EXCEPT SELECT pid FROM plink)"
117
--- src/descendents.c
+++ src/descendents.c
@@ -65,10 +65,11 @@
65 }
66
67 /*
68 ** COMMAND: leaves
69 **
70 ** Usage: %fossil leaves ?UUID?
71 ** Find all leaf descendents of the current version or of the
72 ** specified version.
73 */
74 void leaves_cmd(void){
75 Stmt q;
@@ -94,23 +95,17 @@
95 }
96
97 /*
98 ** COMMAND: branches
99 **
100 ** Usage: %fossil branches
101 ** Find leaves of all branches.
102 */
103 void branches_cmd(void){
104 Stmt q;
 
105
106 db_must_be_within_tree();
 
 
 
 
 
 
107 db_prepare(&q,
108 "SELECT blob.uuid, datetime(event.mtime,'localtime'), event.comment"
109 " FROM blob, event"
110 " WHERE blob.rid IN"
111 " (SELECT cid FROM plink EXCEPT SELECT pid FROM plink)"
112
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -45,10 +45,15 @@
4545
4646
4747
/*
4848
** COMMAND: diff
4949
** COMMAND: tkdiff
50
+**
51
+** Usage: %fossil diff|tkdiff FILE...
52
+** Show the difference between the current version of a file (as it
53
+** exists on disk) and that same file as it was checked out. Use
54
+** either "diff -u" or "tkdiff".
5055
*/
5156
void diff_cmd(void){
5257
const char *zFile;
5358
Blob cmd;
5459
Blob fname;
5560
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -45,10 +45,15 @@
45
46
47 /*
48 ** COMMAND: diff
49 ** COMMAND: tkdiff
 
 
 
 
 
50 */
51 void diff_cmd(void){
52 const char *zFile;
53 Blob cmd;
54 Blob fname;
55
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -45,10 +45,15 @@
45
46
47 /*
48 ** COMMAND: diff
49 ** COMMAND: tkdiff
50 **
51 ** Usage: %fossil diff|tkdiff FILE...
52 ** Show the difference between the current version of a file (as it
53 ** exists on disk) and that same file as it was checked out. Use
54 ** either "diff -u" or "tkdiff".
55 */
56 void diff_cmd(void){
57 const char *zFile;
58 Blob cmd;
59 Blob fname;
60
+53 -14
--- src/main.c
+++ src/main.c
@@ -135,11 +135,11 @@
135135
*/
136136
static int name_search(
137137
const char *zName, /* The name we are looking for */
138138
const NameMap *aMap, /* Search in this array */
139139
int nMap, /* Number of slots in aMap[] */
140
- void (**pxFunc)(void) /* Write pointer to handler function here */
140
+ int *pIndex /* OUT: The index in aMap[] of the match */
141141
){
142142
int upr, lwr, cnt, m, i;
143143
int n = strlen(zName);
144144
lwr = 0;
145145
upr = nMap-1;
@@ -146,11 +146,11 @@
146146
while( lwr<=upr ){
147147
int mid, c;
148148
mid = (upr+lwr)/2;
149149
c = strcmp(zName, aMap[mid].zName);
150150
if( c==0 ){
151
- *pxFunc = aMap[mid].xFunc;
151
+ *pIndex = mid;
152152
return 0;
153153
}else if( c<0 ){
154154
upr = mid - 1;
155155
}else{
156156
lwr = mid + 1;
@@ -162,11 +162,11 @@
162162
m = i;
163163
cnt++;
164164
}
165165
}
166166
if( cnt==1 ){
167
- *pxFunc = aMap[m].xFunc;
167
+ *pIndex = m;
168168
return 0;
169169
}
170170
return 1+(cnt>1);
171171
}
172172
@@ -174,11 +174,11 @@
174174
/*
175175
** This procedure runs first.
176176
*/
177177
int main(int argc, char **argv){
178178
const char *zCmdName;
179
- void (*xFunc)(void);
179
+ int idx;
180180
int rc;
181181
182182
g.now = time(0);
183183
g.argc = argc;
184184
g.argv = argv;
@@ -192,11 +192,11 @@
192192
g.fSqlPrint = find_option("sqlprint", 0, 0)!=0;
193193
g.fHttpTrace = find_option("httptrace", 0, 0)!=0;
194194
g.zLogin = find_option("user", "U", 1);
195195
zCmdName = argv[1];
196196
}
197
- rc = name_search(zCmdName, aCommand, count(aCommand), &xFunc);
197
+ rc = name_search(zCmdName, aCommand, count(aCommand), &idx);
198198
if( rc==1 ){
199199
fprintf(stderr,"%s: unknown command: %s\n"
200200
"%s: use \"commands\" or \"test-commands\" for help\n",
201201
argv[0], zCmdName, argv[0]);
202202
return 1;
@@ -204,11 +204,11 @@
204204
fprintf(stderr,"%s: ambiguous command prefix: %s\n"
205205
"%s: use \"commands\" or \"test-commands\" for help\n",
206206
argv[0], zCmdName, argv[0]);
207207
return 1;
208208
}
209
- xFunc();
209
+ aCommand[idx].xFunc();
210210
return 0;
211211
}
212212
213213
/*
214214
** Print an error message, rollback all databases, and quit.
@@ -340,39 +340,78 @@
340340
}
341341
342342
/*
343343
** COMMAND: commands
344344
**
345
-** List all commands whose name does not start with "test-"
345
+** Usage: %fossil commands
346
+** List all supported commands.
346347
*/
347348
void cmd_cmd_list(void){
348349
int i, nCmd;
349350
const char *aCmd[count(aCommand)];
350351
for(i=nCmd=0; i<count(aCommand); i++){
351352
if( strncmp(aCommand[i].zName,"test",4)==0 ) continue;
352
- if( strcmp(aCommand[i].zName, g.argv[1])==0 ) continue;
353
+ /* if( strcmp(aCommand[i].zName, g.argv[1])==0 ) continue; */
353354
aCmd[nCmd++] = aCommand[i].zName;
354355
}
355356
multi_column_list(aCmd, nCmd);
356357
}
357358
358359
/*
359360
** COMMAND: test-commands
360361
**
361
-** List all commands whose name begins with "test"
362
+** Usage: %fossil test-commands
363
+** List all commands used for testing and debugging.
362364
*/
363365
void cmd_test_cmd_list(void){
364366
int i, nCmd;
365367
const char *aCmd[count(aCommand)];
366368
for(i=nCmd=0; i<count(aCommand); i++){
367369
if( strncmp(aCommand[i].zName,"test",4)!=0 ) continue;
368
- if( strcmp(aCommand[i].zName, g.argv[1])==0 ) continue;
370
+ /* if( strcmp(aCommand[i].zName, g.argv[1])==0 ) continue; */
369371
aCmd[nCmd++] = aCommand[i].zName;
370372
}
371373
multi_column_list(aCmd, nCmd);
372374
}
373375
376
+
377
+/*
378
+** COMMAND: help
379
+**
380
+** Usage: %fossil help COMMAND
381
+** Display information on how to use COMMAND
382
+*/
383
+void help_cmd(void){
384
+ int rc, idx;
385
+ const char *z;
386
+ if( g.argc!=3 ){
387
+ printf("Usage: %s help <command>.\nAvailable commands:\n", g.argv[0]);
388
+ cmd_cmd_list();
389
+ return;
390
+ }
391
+ rc = name_search(g.argv[2], aCommand, count(aCommand), &idx);
392
+ if( rc==1 ){
393
+ fossil_fatal("unknown command: %s", g.argv[2]);
394
+ }else if( rc==2 ){
395
+ fossil_fatal("ambiguous command prefix: %s", g.argv[2]);
396
+ }
397
+ z = aCmdHelp[idx];
398
+ if( z==0 ){
399
+ fossil_fatal("no help available for the %s command",
400
+ aCommand[idx].zName);
401
+ }
402
+ while( *z ){
403
+ if( *z=='%' && strncmp(z, "%fossil", 7)==0 ){
404
+ printf("%s", g.argv[0]);
405
+ z += 7;
406
+ }else{
407
+ putchar(*z);
408
+ z++;
409
+ }
410
+ }
411
+ putchar('\n');
412
+}
374413
375414
/*
376415
** RSS feeds need to reference absolute URLs so we need to calculate
377416
** the base URL onto which we add components. This is basically
378417
** cgi_redirect() stripped down and always returning an absolute URL.
@@ -412,11 +451,11 @@
412451
** environment variable.
413452
*/
414453
static void process_one_web_page(void){
415454
const char *zPathInfo;
416455
char *zPath;
417
- void (*xFunc)(void);
456
+ int idx;
418457
int i, j;
419458
420459
/* Find the page that the user has requested, construct and deliver that
421460
** page.
422461
*/
@@ -463,17 +502,17 @@
463502
}
464503
465504
/* Locate the method specified by the path and execute the function
466505
** that implements that method.
467506
*/
468
- if( name_search(g.zPath, aWebpage, count(aWebpage), &xFunc) &&
469
- name_search("not_found", aWebpage, count(aWebpage), &xFunc) ){
507
+ if( name_search(g.zPath, aWebpage, count(aWebpage), &idx) &&
508
+ name_search("not_found", aWebpage, count(aWebpage), &idx) ){
470509
cgi_set_status(404,"Not Found");
471510
@ <h1>Not Found</h1>
472511
@ <p>Page not found: %h(g.zPath)</p>
473512
}else{
474
- xFunc();
513
+ aWebpage[idx].xFunc();
475514
}
476515
477516
/* Return the result.
478517
*/
479518
cgi_reply();
480519
--- src/main.c
+++ src/main.c
@@ -135,11 +135,11 @@
135 */
136 static int name_search(
137 const char *zName, /* The name we are looking for */
138 const NameMap *aMap, /* Search in this array */
139 int nMap, /* Number of slots in aMap[] */
140 void (**pxFunc)(void) /* Write pointer to handler function here */
141 ){
142 int upr, lwr, cnt, m, i;
143 int n = strlen(zName);
144 lwr = 0;
145 upr = nMap-1;
@@ -146,11 +146,11 @@
146 while( lwr<=upr ){
147 int mid, c;
148 mid = (upr+lwr)/2;
149 c = strcmp(zName, aMap[mid].zName);
150 if( c==0 ){
151 *pxFunc = aMap[mid].xFunc;
152 return 0;
153 }else if( c<0 ){
154 upr = mid - 1;
155 }else{
156 lwr = mid + 1;
@@ -162,11 +162,11 @@
162 m = i;
163 cnt++;
164 }
165 }
166 if( cnt==1 ){
167 *pxFunc = aMap[m].xFunc;
168 return 0;
169 }
170 return 1+(cnt>1);
171 }
172
@@ -174,11 +174,11 @@
174 /*
175 ** This procedure runs first.
176 */
177 int main(int argc, char **argv){
178 const char *zCmdName;
179 void (*xFunc)(void);
180 int rc;
181
182 g.now = time(0);
183 g.argc = argc;
184 g.argv = argv;
@@ -192,11 +192,11 @@
192 g.fSqlPrint = find_option("sqlprint", 0, 0)!=0;
193 g.fHttpTrace = find_option("httptrace", 0, 0)!=0;
194 g.zLogin = find_option("user", "U", 1);
195 zCmdName = argv[1];
196 }
197 rc = name_search(zCmdName, aCommand, count(aCommand), &xFunc);
198 if( rc==1 ){
199 fprintf(stderr,"%s: unknown command: %s\n"
200 "%s: use \"commands\" or \"test-commands\" for help\n",
201 argv[0], zCmdName, argv[0]);
202 return 1;
@@ -204,11 +204,11 @@
204 fprintf(stderr,"%s: ambiguous command prefix: %s\n"
205 "%s: use \"commands\" or \"test-commands\" for help\n",
206 argv[0], zCmdName, argv[0]);
207 return 1;
208 }
209 xFunc();
210 return 0;
211 }
212
213 /*
214 ** Print an error message, rollback all databases, and quit.
@@ -340,39 +340,78 @@
340 }
341
342 /*
343 ** COMMAND: commands
344 **
345 ** List all commands whose name does not start with "test-"
 
346 */
347 void cmd_cmd_list(void){
348 int i, nCmd;
349 const char *aCmd[count(aCommand)];
350 for(i=nCmd=0; i<count(aCommand); i++){
351 if( strncmp(aCommand[i].zName,"test",4)==0 ) continue;
352 if( strcmp(aCommand[i].zName, g.argv[1])==0 ) continue;
353 aCmd[nCmd++] = aCommand[i].zName;
354 }
355 multi_column_list(aCmd, nCmd);
356 }
357
358 /*
359 ** COMMAND: test-commands
360 **
361 ** List all commands whose name begins with "test"
 
362 */
363 void cmd_test_cmd_list(void){
364 int i, nCmd;
365 const char *aCmd[count(aCommand)];
366 for(i=nCmd=0; i<count(aCommand); i++){
367 if( strncmp(aCommand[i].zName,"test",4)!=0 ) continue;
368 if( strcmp(aCommand[i].zName, g.argv[1])==0 ) continue;
369 aCmd[nCmd++] = aCommand[i].zName;
370 }
371 multi_column_list(aCmd, nCmd);
372 }
373
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
374
375 /*
376 ** RSS feeds need to reference absolute URLs so we need to calculate
377 ** the base URL onto which we add components. This is basically
378 ** cgi_redirect() stripped down and always returning an absolute URL.
@@ -412,11 +451,11 @@
412 ** environment variable.
413 */
414 static void process_one_web_page(void){
415 const char *zPathInfo;
416 char *zPath;
417 void (*xFunc)(void);
418 int i, j;
419
420 /* Find the page that the user has requested, construct and deliver that
421 ** page.
422 */
@@ -463,17 +502,17 @@
463 }
464
465 /* Locate the method specified by the path and execute the function
466 ** that implements that method.
467 */
468 if( name_search(g.zPath, aWebpage, count(aWebpage), &xFunc) &&
469 name_search("not_found", aWebpage, count(aWebpage), &xFunc) ){
470 cgi_set_status(404,"Not Found");
471 @ <h1>Not Found</h1>
472 @ <p>Page not found: %h(g.zPath)</p>
473 }else{
474 xFunc();
475 }
476
477 /* Return the result.
478 */
479 cgi_reply();
480
--- src/main.c
+++ src/main.c
@@ -135,11 +135,11 @@
135 */
136 static int name_search(
137 const char *zName, /* The name we are looking for */
138 const NameMap *aMap, /* Search in this array */
139 int nMap, /* Number of slots in aMap[] */
140 int *pIndex /* OUT: The index in aMap[] of the match */
141 ){
142 int upr, lwr, cnt, m, i;
143 int n = strlen(zName);
144 lwr = 0;
145 upr = nMap-1;
@@ -146,11 +146,11 @@
146 while( lwr<=upr ){
147 int mid, c;
148 mid = (upr+lwr)/2;
149 c = strcmp(zName, aMap[mid].zName);
150 if( c==0 ){
151 *pIndex = mid;
152 return 0;
153 }else if( c<0 ){
154 upr = mid - 1;
155 }else{
156 lwr = mid + 1;
@@ -162,11 +162,11 @@
162 m = i;
163 cnt++;
164 }
165 }
166 if( cnt==1 ){
167 *pIndex = m;
168 return 0;
169 }
170 return 1+(cnt>1);
171 }
172
@@ -174,11 +174,11 @@
174 /*
175 ** This procedure runs first.
176 */
177 int main(int argc, char **argv){
178 const char *zCmdName;
179 int idx;
180 int rc;
181
182 g.now = time(0);
183 g.argc = argc;
184 g.argv = argv;
@@ -192,11 +192,11 @@
192 g.fSqlPrint = find_option("sqlprint", 0, 0)!=0;
193 g.fHttpTrace = find_option("httptrace", 0, 0)!=0;
194 g.zLogin = find_option("user", "U", 1);
195 zCmdName = argv[1];
196 }
197 rc = name_search(zCmdName, aCommand, count(aCommand), &idx);
198 if( rc==1 ){
199 fprintf(stderr,"%s: unknown command: %s\n"
200 "%s: use \"commands\" or \"test-commands\" for help\n",
201 argv[0], zCmdName, argv[0]);
202 return 1;
@@ -204,11 +204,11 @@
204 fprintf(stderr,"%s: ambiguous command prefix: %s\n"
205 "%s: use \"commands\" or \"test-commands\" for help\n",
206 argv[0], zCmdName, argv[0]);
207 return 1;
208 }
209 aCommand[idx].xFunc();
210 return 0;
211 }
212
213 /*
214 ** Print an error message, rollback all databases, and quit.
@@ -340,39 +340,78 @@
340 }
341
342 /*
343 ** COMMAND: commands
344 **
345 ** Usage: %fossil commands
346 ** List all supported commands.
347 */
348 void cmd_cmd_list(void){
349 int i, nCmd;
350 const char *aCmd[count(aCommand)];
351 for(i=nCmd=0; i<count(aCommand); i++){
352 if( strncmp(aCommand[i].zName,"test",4)==0 ) continue;
353 /* if( strcmp(aCommand[i].zName, g.argv[1])==0 ) continue; */
354 aCmd[nCmd++] = aCommand[i].zName;
355 }
356 multi_column_list(aCmd, nCmd);
357 }
358
359 /*
360 ** COMMAND: test-commands
361 **
362 ** Usage: %fossil test-commands
363 ** List all commands used for testing and debugging.
364 */
365 void cmd_test_cmd_list(void){
366 int i, nCmd;
367 const char *aCmd[count(aCommand)];
368 for(i=nCmd=0; i<count(aCommand); i++){
369 if( strncmp(aCommand[i].zName,"test",4)!=0 ) continue;
370 /* if( strcmp(aCommand[i].zName, g.argv[1])==0 ) continue; */
371 aCmd[nCmd++] = aCommand[i].zName;
372 }
373 multi_column_list(aCmd, nCmd);
374 }
375
376
377 /*
378 ** COMMAND: help
379 **
380 ** Usage: %fossil help COMMAND
381 ** Display information on how to use COMMAND
382 */
383 void help_cmd(void){
384 int rc, idx;
385 const char *z;
386 if( g.argc!=3 ){
387 printf("Usage: %s help <command>.\nAvailable commands:\n", g.argv[0]);
388 cmd_cmd_list();
389 return;
390 }
391 rc = name_search(g.argv[2], aCommand, count(aCommand), &idx);
392 if( rc==1 ){
393 fossil_fatal("unknown command: %s", g.argv[2]);
394 }else if( rc==2 ){
395 fossil_fatal("ambiguous command prefix: %s", g.argv[2]);
396 }
397 z = aCmdHelp[idx];
398 if( z==0 ){
399 fossil_fatal("no help available for the %s command",
400 aCommand[idx].zName);
401 }
402 while( *z ){
403 if( *z=='%' && strncmp(z, "%fossil", 7)==0 ){
404 printf("%s", g.argv[0]);
405 z += 7;
406 }else{
407 putchar(*z);
408 z++;
409 }
410 }
411 putchar('\n');
412 }
413
414 /*
415 ** RSS feeds need to reference absolute URLs so we need to calculate
416 ** the base URL onto which we add components. This is basically
417 ** cgi_redirect() stripped down and always returning an absolute URL.
@@ -412,11 +451,11 @@
451 ** environment variable.
452 */
453 static void process_one_web_page(void){
454 const char *zPathInfo;
455 char *zPath;
456 int idx;
457 int i, j;
458
459 /* Find the page that the user has requested, construct and deliver that
460 ** page.
461 */
@@ -463,17 +502,17 @@
502 }
503
504 /* Locate the method specified by the path and execute the function
505 ** that implements that method.
506 */
507 if( name_search(g.zPath, aWebpage, count(aWebpage), &idx) &&
508 name_search("not_found", aWebpage, count(aWebpage), &idx) ){
509 cgi_set_status(404,"Not Found");
510 @ <h1>Not Found</h1>
511 @ <p>Page not found: %h(g.zPath)</p>
512 }else{
513 aWebpage[idx].xFunc();
514 }
515
516 /* Return the result.
517 */
518 cgi_reply();
519
+69 -2
--- src/mkindex.c
+++ src/mkindex.c
@@ -55,22 +55,34 @@
5555
*/
5656
typedef struct Entry {
5757
int eType;
5858
char *zFunc;
5959
char *zPath;
60
+ char *zHelp;
6061
} Entry;
6162
6263
/*
6364
** Maximum number of entries
6465
*/
6566
#define N_ENTRY 500
6667
68
+/*
69
+** Maximum size of a help message
70
+*/
71
+#define MX_HELP 10000
72
+
6773
/*
6874
** Table of entries
6975
*/
7076
Entry aEntry[N_ENTRY];
7177
78
+/*
79
+** Current help message accumulator
80
+*/
81
+char zHelp[MX_HELP];
82
+int nHelp;
83
+
7284
/*
7385
** How many entries are used
7486
*/
7587
int nUsed;
7688
int nFixed;
@@ -120,12 +132,24 @@
120132
121133
/*
122134
** Scan a line for a function that implements a web page or command.
123135
*/
124136
void scan_for_func(char *zLine){
125
- int i,j,k;
137
+ int i,j,k;
138
+ char *z;
126139
if( nUsed<=nFixed ) return;
140
+ if( strncmp(zLine, "**", 2)==0 && isspace(zLine[2])
141
+ && strlen(zLine)<sizeof(zHelp)-nHelp-1 && nUsed>nFixed ){
142
+ if( zLine[2]=='\n' ){
143
+ zHelp[nHelp++] = '\n';
144
+ }else{
145
+ if( strncmp(&zLine[3], "Usage: ", 6)==0 ) nHelp = 0;
146
+ strcpy(&zHelp[nHelp], &zLine[3]);
147
+ nHelp += strlen(&zHelp[nHelp]);
148
+ }
149
+ return;
150
+ }
127151
for(i=0; isspace(zLine[i]); i++){}
128152
if( zLine[i]==0 ) return;
129153
if( strncmp(&zLine[i],"void",4)!=0 ){
130154
if( zLine[i]!='*' ) goto page_skip;
131155
return;
@@ -133,17 +157,28 @@
133157
i += 4;
134158
if( !isspace(zLine[i]) ) goto page_skip;
135159
while( isspace(zLine[i]) ){ i++; }
136160
for(j=0; isalnum(zLine[i+j]) || zLine[i+j]=='_'; j++){}
137161
if( j==0 ) goto page_skip;
162
+ for(k=nHelp-1; k>=0 && isspace(zHelp[k]); k--){}
163
+ nHelp = k+1;
164
+ zHelp[nHelp] = 0;
165
+ for(k=0; k<nHelp && isspace(zHelp[k]); k++){}
166
+ if( k<nHelp ){
167
+ z = string_dup(&zHelp[k], nHelp-k);
168
+ }else{
169
+ z = 0;
170
+ }
138171
for(k=nFixed; k<nUsed; k++){
139172
aEntry[k].zFunc = string_dup(&zLine[i], j);
173
+ aEntry[k].zHelp = z;
140174
}
141175
i+=j;
142176
while( isspace(zLine[i]) ){ i++; }
143177
if( zLine[i]!='(' ) goto page_skip;
144178
nFixed = nUsed;
179
+ nHelp = 0;
145180
return;
146181
147182
page_skip:
148183
for(i=nFixed; i<nUsed; i++){
149184
fprintf(stderr,"%s:%d: skipping page \"%s\"\n",
@@ -168,10 +203,11 @@
168203
/*
169204
** Build the binary search table.
170205
*/
171206
void build_table(void){
172207
int i;
208
+ int nType0;
173209
174210
qsort(aEntry, nFixed, sizeof(aEntry[0]), e_compare);
175211
for(i=0; i<nFixed; i++){
176212
printf("extern void %s(void);\n", aEntry[i].zFunc);
177213
}
@@ -188,18 +224,49 @@
188224
aEntry[i].zPath, (int)(25-strlen(aEntry[i].zPath)), "",
189225
aEntry[i].zFunc
190226
);
191227
}
192228
printf("};\n");
229
+ nType0 = i;
193230
printf(
194231
"static const NameMap aCommand[] = {\n"
195232
);
196
- for(; i<nFixed && aEntry[i].eType==1; i++){
233
+ for(i=nType0; i<nFixed && aEntry[i].eType==1; i++){
197234
printf(" { \"%s\",%*s %s },\n",
198235
aEntry[i].zPath, (int)(25-strlen(aEntry[i].zPath)), "",
199236
aEntry[i].zFunc
200237
);
238
+ }
239
+ printf("};\n");
240
+ for(i=nType0; i<nFixed; i++){
241
+ char *z = aEntry[i].zHelp;
242
+ if( z && z[0] ){
243
+ printf("static const char zHelp_%s[] = \n", aEntry[i].zFunc);
244
+ printf(" \"");
245
+ while( *z ){
246
+ if( *z=='\n' ){
247
+ printf("\\n\"\n \"");
248
+ }else if( *z=='"' ){
249
+ printf("\\\"");
250
+ }else{
251
+ putchar(*z);
252
+ }
253
+ z++;
254
+ }
255
+ printf("\";\n");
256
+ aEntry[i].zHelp[0] = 0;
257
+ }
258
+ }
259
+ printf(
260
+ "static const char * const aCmdHelp[] = {\n"
261
+ );
262
+ for(i=nType0; i<nFixed; i++){
263
+ if( aEntry[i].zHelp==0 ){
264
+ printf(" 0,\n");
265
+ }else{
266
+ printf(" zHelp_%s,\n", aEntry[i].zFunc);
267
+ }
201268
}
202269
printf("};\n");
203270
}
204271
205272
/*
206273
--- src/mkindex.c
+++ src/mkindex.c
@@ -55,22 +55,34 @@
55 */
56 typedef struct Entry {
57 int eType;
58 char *zFunc;
59 char *zPath;
 
60 } Entry;
61
62 /*
63 ** Maximum number of entries
64 */
65 #define N_ENTRY 500
66
 
 
 
 
 
67 /*
68 ** Table of entries
69 */
70 Entry aEntry[N_ENTRY];
71
 
 
 
 
 
 
72 /*
73 ** How many entries are used
74 */
75 int nUsed;
76 int nFixed;
@@ -120,12 +132,24 @@
120
121 /*
122 ** Scan a line for a function that implements a web page or command.
123 */
124 void scan_for_func(char *zLine){
125 int i,j,k;
 
126 if( nUsed<=nFixed ) return;
 
 
 
 
 
 
 
 
 
 
 
127 for(i=0; isspace(zLine[i]); i++){}
128 if( zLine[i]==0 ) return;
129 if( strncmp(&zLine[i],"void",4)!=0 ){
130 if( zLine[i]!='*' ) goto page_skip;
131 return;
@@ -133,17 +157,28 @@
133 i += 4;
134 if( !isspace(zLine[i]) ) goto page_skip;
135 while( isspace(zLine[i]) ){ i++; }
136 for(j=0; isalnum(zLine[i+j]) || zLine[i+j]=='_'; j++){}
137 if( j==0 ) goto page_skip;
 
 
 
 
 
 
 
 
 
138 for(k=nFixed; k<nUsed; k++){
139 aEntry[k].zFunc = string_dup(&zLine[i], j);
 
140 }
141 i+=j;
142 while( isspace(zLine[i]) ){ i++; }
143 if( zLine[i]!='(' ) goto page_skip;
144 nFixed = nUsed;
 
145 return;
146
147 page_skip:
148 for(i=nFixed; i<nUsed; i++){
149 fprintf(stderr,"%s:%d: skipping page \"%s\"\n",
@@ -168,10 +203,11 @@
168 /*
169 ** Build the binary search table.
170 */
171 void build_table(void){
172 int i;
 
173
174 qsort(aEntry, nFixed, sizeof(aEntry[0]), e_compare);
175 for(i=0; i<nFixed; i++){
176 printf("extern void %s(void);\n", aEntry[i].zFunc);
177 }
@@ -188,18 +224,49 @@
188 aEntry[i].zPath, (int)(25-strlen(aEntry[i].zPath)), "",
189 aEntry[i].zFunc
190 );
191 }
192 printf("};\n");
 
193 printf(
194 "static const NameMap aCommand[] = {\n"
195 );
196 for(; i<nFixed && aEntry[i].eType==1; i++){
197 printf(" { \"%s\",%*s %s },\n",
198 aEntry[i].zPath, (int)(25-strlen(aEntry[i].zPath)), "",
199 aEntry[i].zFunc
200 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
201 }
202 printf("};\n");
203 }
204
205 /*
206
--- src/mkindex.c
+++ src/mkindex.c
@@ -55,22 +55,34 @@
55 */
56 typedef struct Entry {
57 int eType;
58 char *zFunc;
59 char *zPath;
60 char *zHelp;
61 } Entry;
62
63 /*
64 ** Maximum number of entries
65 */
66 #define N_ENTRY 500
67
68 /*
69 ** Maximum size of a help message
70 */
71 #define MX_HELP 10000
72
73 /*
74 ** Table of entries
75 */
76 Entry aEntry[N_ENTRY];
77
78 /*
79 ** Current help message accumulator
80 */
81 char zHelp[MX_HELP];
82 int nHelp;
83
84 /*
85 ** How many entries are used
86 */
87 int nUsed;
88 int nFixed;
@@ -120,12 +132,24 @@
132
133 /*
134 ** Scan a line for a function that implements a web page or command.
135 */
136 void scan_for_func(char *zLine){
137 int i,j,k;
138 char *z;
139 if( nUsed<=nFixed ) return;
140 if( strncmp(zLine, "**", 2)==0 && isspace(zLine[2])
141 && strlen(zLine)<sizeof(zHelp)-nHelp-1 && nUsed>nFixed ){
142 if( zLine[2]=='\n' ){
143 zHelp[nHelp++] = '\n';
144 }else{
145 if( strncmp(&zLine[3], "Usage: ", 6)==0 ) nHelp = 0;
146 strcpy(&zHelp[nHelp], &zLine[3]);
147 nHelp += strlen(&zHelp[nHelp]);
148 }
149 return;
150 }
151 for(i=0; isspace(zLine[i]); i++){}
152 if( zLine[i]==0 ) return;
153 if( strncmp(&zLine[i],"void",4)!=0 ){
154 if( zLine[i]!='*' ) goto page_skip;
155 return;
@@ -133,17 +157,28 @@
157 i += 4;
158 if( !isspace(zLine[i]) ) goto page_skip;
159 while( isspace(zLine[i]) ){ i++; }
160 for(j=0; isalnum(zLine[i+j]) || zLine[i+j]=='_'; j++){}
161 if( j==0 ) goto page_skip;
162 for(k=nHelp-1; k>=0 && isspace(zHelp[k]); k--){}
163 nHelp = k+1;
164 zHelp[nHelp] = 0;
165 for(k=0; k<nHelp && isspace(zHelp[k]); k++){}
166 if( k<nHelp ){
167 z = string_dup(&zHelp[k], nHelp-k);
168 }else{
169 z = 0;
170 }
171 for(k=nFixed; k<nUsed; k++){
172 aEntry[k].zFunc = string_dup(&zLine[i], j);
173 aEntry[k].zHelp = z;
174 }
175 i+=j;
176 while( isspace(zLine[i]) ){ i++; }
177 if( zLine[i]!='(' ) goto page_skip;
178 nFixed = nUsed;
179 nHelp = 0;
180 return;
181
182 page_skip:
183 for(i=nFixed; i<nUsed; i++){
184 fprintf(stderr,"%s:%d: skipping page \"%s\"\n",
@@ -168,10 +203,11 @@
203 /*
204 ** Build the binary search table.
205 */
206 void build_table(void){
207 int i;
208 int nType0;
209
210 qsort(aEntry, nFixed, sizeof(aEntry[0]), e_compare);
211 for(i=0; i<nFixed; i++){
212 printf("extern void %s(void);\n", aEntry[i].zFunc);
213 }
@@ -188,18 +224,49 @@
224 aEntry[i].zPath, (int)(25-strlen(aEntry[i].zPath)), "",
225 aEntry[i].zFunc
226 );
227 }
228 printf("};\n");
229 nType0 = i;
230 printf(
231 "static const NameMap aCommand[] = {\n"
232 );
233 for(i=nType0; i<nFixed && aEntry[i].eType==1; i++){
234 printf(" { \"%s\",%*s %s },\n",
235 aEntry[i].zPath, (int)(25-strlen(aEntry[i].zPath)), "",
236 aEntry[i].zFunc
237 );
238 }
239 printf("};\n");
240 for(i=nType0; i<nFixed; i++){
241 char *z = aEntry[i].zHelp;
242 if( z && z[0] ){
243 printf("static const char zHelp_%s[] = \n", aEntry[i].zFunc);
244 printf(" \"");
245 while( *z ){
246 if( *z=='\n' ){
247 printf("\\n\"\n \"");
248 }else if( *z=='"' ){
249 printf("\\\"");
250 }else{
251 putchar(*z);
252 }
253 z++;
254 }
255 printf("\";\n");
256 aEntry[i].zHelp[0] = 0;
257 }
258 }
259 printf(
260 "static const char * const aCmdHelp[] = {\n"
261 );
262 for(i=nType0; i<nFixed; i++){
263 if( aEntry[i].zHelp==0 ){
264 printf(" 0,\n");
265 }else{
266 printf(" zHelp_%s,\n", aEntry[i].zFunc);
267 }
268 }
269 printf("};\n");
270 }
271
272 /*
273

Keyboard Shortcuts

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