Fossil SCM

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

Keyboard Shortcuts

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