Fossil SCM

fossil-scm / www / adding_code.wiki
1
<title>Adding Features To Fossil</title>
2
3
<h2>1.0 Introduction</h2>
4
5
This article provides a brief overview of how to write new C-code code that
6
extends or enhances the core Fossil binary.
7
8
New features can be added to a Fossil server using
9
[./serverext.wiki|external CGI programs],
10
but that is not what this article is about.
11
This article focuses on how to make changes
12
to Fossil itself.
13
14
<h2>2.0 Programming Language</h2>
15
16
Fossil is written in C-89. There are specific [./style.wiki | style guidelines]
17
that are required for any new code that will be accepted into the Fossil core.
18
But, of course, if you are writing an extension just for yourself, you can
19
use any programming style you want.
20
21
The source code for Fossil is not sent directly into the C compiler.
22
There are three separate code [./makefile.wiki#preprocessing|preprocessors]
23
that run over the code first.
24
25
1. The <b>mkindex</b> preprocessor scans all regular source files looking
26
for special comments that contain "help" text and which identify routines
27
that implement specific commands or which generate particular web pages.
28
29
2. The <b>makeheaders</b> preprocessor generates all the ".h" files
30
automatically. Fossil programmers write ".c" files only and let the
31
makeheaders preprocessor create the ".h" files.
32
33
3. The <b>translate</b> preprocessor converts source code lines that
34
begin with "@" into string literals, or into print statements that
35
generate web page output, depending on context.
36
37
The [./makefile.wiki|Makefile] for Fossil takes care of running these
38
preprocessors with all the right arguments and in the right order. So it is
39
not necessary to understand the details of how these preprocessors work.
40
(Though, the sources for all three preprocessors are included in the source
41
tree and are well commented, if you want to dig deeper.) It is only necessary
42
to know that these preprocessors exist and hence will affect the way you
43
write code.
44
45
<h2>3.0 Adding New Source Code Files</h2>
46
47
New source code files are added in the "src/" subdirectory of the Fossil
48
source tree. Suppose one wants to add a new source code file named
49
"xyzzy.c". The first step is to add this file to the various makefiles.
50
Do so by editing the file tools/makemake.tcl and adding "xyzzy" (without
51
the final ".c") to the list of source modules at the top of that script.
52
Save the result and then run the makemake.tcl script using a TCL
53
interpreter. The command to run the makemake.tcl script is:
54
55
<verbatim>
56
tclsh makemake.tcl
57
</verbatim>
58
59
The working directory must be src/ when the command above is run.
60
Note that TCL is not normally required to build Fossil, but
61
it is required for this step. If you do not have a TCL interpreter on
62
your system already, they are easy to install. A popular choice is the
63
[http://www.activestate.com/activetcl|Active Tcl] installation from
64
ActiveState.
65
66
After the makefiles have been updated, create the xyzzy.c source file
67
from the following template:
68
69
<verbatim>
70
/*
71
** Copyright boilerplate goes here.
72
*****************************************************
73
** High-level description of what this module goes
74
** here.
75
*/
76
#include "config.h"
77
#include "xyzzy.h"
78
79
#if INTERFACE
80
/* Exported object (structure) definitions or #defines
81
** go here */
82
#endif /* INTERFACE */
83
84
/* New code goes here */
85
</verbatim>
86
87
Note in particular the <b>#include "xyzzy.h"</b> line near the top.
88
The "xyzzy.h" file is automatically generated by makeheaders. Every
89
normal Fossil source file must have a #include at the top that imports
90
its private header file. (Some source files, such as "sqlite3.c" are
91
exceptions to this rule. Don't worry about those exceptions. The
92
files you write will require this #include line.)
93
94
The "#if INTERFACE ... #endif" section is optional and is only needed
95
if there are structure definitions or typedefs or macros that need to
96
be used by other source code files. The makeheaders preprocessor
97
uses definitions in the INTERFACE section to help it generate header
98
files. See [../tools/makeheaders.html | makeheaders.html] for additional
99
information.
100
101
After creating a template file such as shown above, and after updating
102
the makefiles, you should be able to recompile Fossil and have it include
103
your new source file, even before your source file contains any code.
104
It is recommended that you try this.
105
106
Be sure to [/help/add|fossil add] your new source file to the self-hosting
107
Fossil repository and then [/help/commit|commit] your changes!
108
109
<h2 id="newcmd">4.0 Creating A New Command</h2>
110
111
By "commands" we mean the keywords that follow "fossil" when invoking
112
Fossil from the command-line. So, for example, in
113
114
<verbatim>
115
fossil diff xyzzy.c
116
</verbatim>
117
118
The "command" is "diff". Commands may optionally be followed by
119
arguments and/or options. To create new commands in Fossil, add code
120
(either to an existing source file, or to a new source file created as
121
described above) according to the following template:
122
123
<verbatim>
124
/*
125
** COMMAND: xyzzy
126
**
127
** Help text goes here. Backslashes must be escaped.
128
*/
129
void xyzzy_cmd(void){
130
/* Implement the command here */
131
fossil_print("Hello, World!\n");
132
}
133
</verbatim>
134
135
The example above creates a new command named "xyzzy" that prints the
136
message "Hello, World!" on the console. This command is a normal command
137
that will show up in the list of command from [/help/help|fossil help].
138
If you add an asterisk to the end of the command name, like this:
139
140
<verbatim>
141
** COMMAND: xyzzy*
142
</verbatim>
143
144
Then the command will only show up if you add the "--all" option to
145
[/help/help|fossil help]. Or, if the command name starts with
146
"test" then the command will be considered experimental and will only
147
show up when the --test option is used with [/help/help|fossil help].
148
149
The example above is a fully functioning Fossil command. You can add
150
the text shown to an existing Fossil source file, recompiling then test
151
it out by typing:
152
153
<verbatim>
154
./fossil xyzzy
155
./fossil help xyzzy
156
./fossil xyzzy --help
157
</verbatim>
158
159
The name of the C function that implements the command can be anything
160
you like (as long as it does not collide with some other symbol in the
161
Fossil code) but it is traditional to name the function
162
"<i>commandname</i><b>_cmd</b>", as is done in the example.
163
164
You could also use "printf()" instead of "fossil_print()" to generate
165
the output text, if desired. But "fossil_print()" is recommended as
166
it has extra logic to insert \r characters at the right times on
167
Windows systems.
168
169
Once you have the command running, you can then start adding code to
170
make it do useful things. There are lots of utility functions in
171
Fossil for parsing command-line options and for
172
opening and accessing and manipulating the repository and
173
the working check-out. Study implementations of existing commands
174
to get an idea of how things are done. You can easily find the implementations
175
of existing commands by searching for "COMMAND: <i>name</i>" in the
176
files of the "src/" directory.
177
178
<h2 id="newpage">5.0 Creating A New Web Page</h2>
179
180
As with commands, new webpages can be added simply by inserting a function
181
that generates the webpage together with a special header comment. A
182
template follows:
183
184
<verbatim>
185
/*
186
** WEBPAGE: helloworld
187
*/
188
void helloworld_page(void){
189
style_header("Hello World!");
190
@ <p>Hello, World!</p>
191
style_footer();
192
}
193
</verbatim>
194
195
Add the code above to a new or existing Fossil source code file, then
196
recompile fossil and run [/help/ui|fossil ui] then enter
197
"http://localhost:8080/helloworld" in your web browser and the routine
198
above will generate a web page that says "Hello World."
199
It really is that simple.
200
201
The special "WEBPAGE:" comment is picked up by the "mkindex" preprocessor
202
and used to generate a table that maps the "helloworld" webpage name
203
into a pointer to the "helloworld_page()" function. The function that
204
implements a webpage can be named anything you like (as long as it does
205
not collide with another name) but the traditional name is
206
"<i>pagename</i><b>_page</b>".
207
208
HTML pages begin with a call to style_header() and end with the call to
209
style_footer(). Content is generated by the "@" lines that are translated
210
(by the "translate" preprocessor) into printf-like code that generates the
211
content of the webpage. Different techniques are used to generate
212
non-HTML content. In the unlikely event that you need to generate
213
non-HTML content, look at existing webpage implementations
214
(ex: "logo" or "style.css") to see how that is done.
215
216
There are lots of other things that a real web-page implementation will
217
need to do, such as verifying user credentials, parsing query parameters,
218
and interacting with the repository. But now that you have the general
219
idea of how webpages are implemented, you can look at the many other
220
webpage implementations already built into Fossil to see how all that
221
works.
222
223
<h2>6.0 See Also</h2>
224
225
* [./makefile.wiki|The Fossil Build Process]
226
* [./tech_overview.wiki|A Technical Overview Of Fossil]
227
* [./contribute.wiki|Contributing To The Fossil Project]
228
* [./serverext.wiki|Adding CGI Extensions To A Fossil Server]
229

Keyboard Shortcuts

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