diff options
Diffstat (limited to 'www/adding_code.wiki')
| -rw-r--r-- | www/adding_code.wiki | 228 |
1 files changed, 228 insertions, 0 deletions
diff --git a/www/adding_code.wiki b/www/adding_code.wiki new file mode 100644 index 0000000..1192907 --- /dev/null +++ b/www/adding_code.wiki @@ -0,0 +1,228 @@ +<title>Adding Features To Fossil</title> + +<h2>1.0 Introduction</h2> + +This article provides a brief overview of how to write new C-code code that +extends or enhances the core Fossil binary. + +New features can be added to a Fossil server using +[./serverext.wiki|external CGI programs], +but that is not what this article is about. +This article focuses on how to make changes +to Fossil itself. + +<h2>2.0 Programming Language</h2> + +Fossil is written in C-89. There are specific [./style.wiki | style guidelines] +that are required for any new code that will be accepted into the Fossil core. +But, of course, if you are writing an extension just for yourself, you can +use any programming style you want. + +The source code for Fossil is not sent directly into the C compiler. +There are three separate code [./makefile.wiki#preprocessing|preprocessors] +that run over the code first. + + 1. The <b>mkindex</b> preprocessor scans all regular source files looking + for special comments that contain "help" text and which identify routines + that implement specific commands or which generate particular web pages. + + 2. The <b>makeheaders</b> preprocessor generates all the ".h" files + automatically. Fossil programmers write ".c" files only and let the + makeheaders preprocessor create the ".h" files. + + 3. The <b>translate</b> preprocessor converts source code lines that + begin with "@" into string literals, or into print statements that + generate web page output, depending on context. + +The [./makefile.wiki|Makefile] for Fossil takes care of running these +preprocessors with all the right arguments and in the right order. So it is +not necessary to understand the details of how these preprocessors work. +(Though, the sources for all three preprocessors are included in the source +tree and are well commented, if you want to dig deeper.) It is only necessary +to know that these preprocessors exist and hence will affect the way you +write code. + +<h2>3.0 Adding New Source Code Files</h2> + +New source code files are added in the "src/" subdirectory of the Fossil +source tree. Suppose one wants to add a new source code file named +"xyzzy.c". The first step is to add this file to the various makefiles. +Do so by editing the file tools/makemake.tcl and adding "xyzzy" (without +the final ".c") to the list of source modules at the top of that script. +Save the result and then run the makemake.tcl script using a TCL +interpreter. The command to run the makemake.tcl script is: + +<verbatim> +tclsh makemake.tcl +</verbatim> + +The working directory must be src/ when the command above is run. +Note that TCL is not normally required to build Fossil, but +it is required for this step. If you do not have a TCL interpreter on +your system already, they are easy to install. A popular choice is the +[http://www.activestate.com/activetcl|Active Tcl] installation from +ActiveState. + +After the makefiles have been updated, create the xyzzy.c source file +from the following template: + +<verbatim> +/* +** Copyright boilerplate goes here. +***************************************************** +** High-level description of what this module goes +** here. +*/ +#include "config.h" +#include "xyzzy.h" + +#if INTERFACE +/* Exported object (structure) definitions or #defines +** go here */ +#endif /* INTERFACE */ + +/* New code goes here */ +</verbatim> + +Note in particular the <b>#include "xyzzy.h"</b> line near the top. +The "xyzzy.h" file is automatically generated by makeheaders. Every +normal Fossil source file must have a #include at the top that imports +its private header file. (Some source files, such as "sqlite3.c" are +exceptions to this rule. Don't worry about those exceptions. The +files you write will require this #include line.) + +The "#if INTERFACE ... #endif" section is optional and is only needed +if there are structure definitions or typedefs or macros that need to +be used by other source code files. The makeheaders preprocessor +uses definitions in the INTERFACE section to help it generate header +files. See [../tools/makeheaders.html | makeheaders.html] for additional +information. + +After creating a template file such as shown above, and after updating +the makefiles, you should be able to recompile Fossil and have it include +your new source file, even before your source file contains any code. +It is recommended that you try this. + +Be sure to [/help/add|fossil add] your new source file to the self-hosting +Fossil repository and then [/help/commit|commit] your changes! + +<h2 id="newcmd">4.0 Creating A New Command</h2> + +By "commands" we mean the keywords that follow "fossil" when invoking +Fossil from the command-line. So, for example, in + +<verbatim> +fossil diff xyzzy.c +</verbatim> + +The "command" is "diff". Commands may optionally be followed by +arguments and/or options. To create new commands in Fossil, add code +(either to an existing source file, or to a new source file created as +described above) according to the following template: + +<verbatim> +/* +** COMMAND: xyzzy +** +** Help text goes here. Backslashes must be escaped. +*/ +void xyzzy_cmd(void){ + /* Implement the command here */ + fossil_print("Hello, World!\n"); +} +</verbatim> + +The example above creates a new command named "xyzzy" that prints the +message "Hello, World!" on the console. This command is a normal command +that will show up in the list of command from [/help/help|fossil help]. +If you add an asterisk to the end of the command name, like this: + +<verbatim> +** COMMAND: xyzzy* +</verbatim> + +Then the command will only show up if you add the "--all" option to +[/help/help|fossil help]. Or, if the command name starts with +"test" then the command will be considered experimental and will only +show up when the --test option is used with [/help/help|fossil help]. + +The example above is a fully functioning Fossil command. You can add +the text shown to an existing Fossil source file, recompiling then test +it out by typing: + +<verbatim> +./fossil xyzzy +./fossil help xyzzy +./fossil xyzzy --help +</verbatim> + +The name of the C function that implements the command can be anything +you like (as long as it does not collide with some other symbol in the +Fossil code) but it is traditional to name the function +"<i>commandname</i><b>_cmd</b>", as is done in the example. + +You could also use "printf()" instead of "fossil_print()" to generate +the output text, if desired. But "fossil_print()" is recommended as +it has extra logic to insert \r characters at the right times on +Windows systems. + +Once you have the command running, you can then start adding code to +make it do useful things. There are lots of utility functions in +Fossil for parsing command-line options and for +opening and accessing and manipulating the repository and +the working check-out. Study implementations of existing commands +to get an idea of how things are done. You can easily find the implementations +of existing commands by searching for "COMMAND: <i>name</i>" in the +files of the "src/" directory. + +<h2 id="newpage">5.0 Creating A New Web Page</h2> + +As with commands, new webpages can be added simply by inserting a function +that generates the webpage together with a special header comment. A +template follows: + +<verbatim> +/* +** WEBPAGE: helloworld +*/ +void helloworld_page(void){ + style_header("Hello World!"); + @ <p>Hello, World!</p> + style_footer(); +} +</verbatim> + +Add the code above to a new or existing Fossil source code file, then +recompile fossil and run [/help/ui|fossil ui] then enter +"http://localhost:8080/helloworld" in your web browser and the routine +above will generate a web page that says "Hello World." +It really is that simple. + +The special "WEBPAGE:" comment is picked up by the "mkindex" preprocessor +and used to generate a table that maps the "helloworld" webpage name +into a pointer to the "helloworld_page()" function. The function that +implements a webpage can be named anything you like (as long as it does +not collide with another name) but the traditional name is +"<i>pagename</i><b>_page</b>". + +HTML pages begin with a call to style_header() and end with the call to +style_footer(). Content is generated by the "@" lines that are translated +(by the "translate" preprocessor) into printf-like code that generates the +content of the webpage. Different techniques are used to generate +non-HTML content. In the unlikely event that you need to generate +non-HTML content, look at existing webpage implementations +(ex: "logo" or "style.css") to see how that is done. + +There are lots of other things that a real web-page implementation will +need to do, such as verifying user credentials, parsing query parameters, +and interacting with the repository. But now that you have the general +idea of how webpages are implemented, you can look at the many other +webpage implementations already built into Fossil to see how all that +works. + +<h2>6.0 See Also</h2> + + * [./makefile.wiki|The Fossil Build Process] + * [./tech_overview.wiki|A Technical Overview Of Fossil] + * [./contribute.wiki|Contributing To The Fossil Project] + * [./serverext.wiki|Adding CGI Extensions To A Fossil Server] |
