| <html> |
| <head> |
| <title>SWIG Engineering Manual</title> |
| </head> |
| <body bgcolor="#ffffff"> |
| <center> |
| <h1>SWIG Engineering Manual</h1> |
| |
| <b>David Beazley <br> |
| Department of Computer Science <br> |
| University of Chicago <br> |
| Chicago, IL 60637 <br> |
| beazley@cs.uchicago.edu <br> |
| </b> |
| </center> |
| |
| <p> |
| <b>$Header$</b> |
| |
| <p> |
| (Note : This is a work in progress.) |
| |
| <h2>Table of Contents</h2> |
| <ul> |
| <li><a name="i1" href="#1">1. Introduction</a> |
| <li><a name="i2" href="#2">2. Programming Languages and Libraries</a> |
| <li><a name="i3" href="#3">3. The Source Directory and Module Names</a> |
| <li><a name="i4" href="#4">4. Include Files</a> |
| <li><a name="i5" href="#5">5. File Structure</a> |
| <li><a name="i6" href="#6">6. Bottom-Up Design</a> |
| <li><a name="i7" href="#7">7. Functions</a> |
| <li><a name="i8" href="#8">8. Naming Conventions</a> |
| <li><a name="i9" href="#9">9. Visibility</a> |
| <li><a name="i10" href="#10">10. Miscellaneous Coding Guidelines</a> |
| <li><a name="i11" href="#11">11. CVS Tagging Conventions</a> |
| </ul> |
| |
| <a name="1" href="#i1"> |
| <h2>1. Introduction</h2> |
| </a> |
| |
| The purpose of this document is to describe various coding conventions |
| and organizational aspects for SWIG developers. The idea for this |
| document is largely borrowed from John Ousterhout's Tcl/Tk Engineering |
| Manual. It is not my intent to overly managerial about matters--rather I'm |
| hoping to make life a little less chaotic for everyone. |
| |
| <p> |
| First a little background: SWIG was started in 1995 as a one-person |
| project and continued in this mode of operation until about 1998. |
| Most of this development was driven by ideas submitted by early SWIG |
| users as opposed to being motivated by a grand design. As a result, |
| the code ended up being a pretty horrible C++ coding disaster. A |
| mostly working disaster perhaps, but a disaster nonetheless. |
| |
| <p> |
| With that said, the primary goal of future SWIG development is to |
| reengineer the original system, fix most of its inherent design flaws, |
| and to produce what I hope will become a highly extensible and modular |
| interface compiler framework. To this do this, there are a few |
| critical areas of work. First, I want to restructure SWIG as a |
| collection of loosely coupled modules written in either ANSI C or an |
| scripting language. Second, I want the system to be minimalistic in |
| its use of data structures and interconnections. The primary reason |
| for this is that the fewer data structures there are, the less users |
| will have to remember. This will also make the system more accessible |
| to non-experts. Finally, I want to reevaluate the whole idea of a |
| SWIG module is and expand the definition to include just about |
| anything from parsers, preprocessors, optimizers, interface editors, |
| and code generators. |
| |
| <p> |
| The rest of this document outlines a few general rules of how code |
| should be developed within the SWIG project. These rules are |
| primarily drawn from my own experience developing software and |
| observing the practices of other successful projects. |
| |
| <a name="2" href="#i2"> |
| <h2>2. Programming Languages and Libraries </h2> |
| </a> |
| |
| All SWIG modules must be written in either ANSI C or one of the |
| scripting languages for which SWIG can generate an interface (e.g., |
| Perl, Python, or Tcl). <B>C++ is NOT an acceptable alternative and |
| will not be utilized for any future development due to the fact that |
| it is too complicated, too dogmatic, too problematic, and that Dave |
| would rather take a bullet to the head than write one more line of |
| code in this most decidedly unpleasant language. </B> Rare exceptions |
| to this rule may be made if there is a justifiable need to interface |
| an existing piece of software written in C++ into the SWIG module |
| system. Anyone who finds this rule to be unreasonable is more than |
| welcome to go write their own wrapper generator--so there. |
| |
| <p> |
| Module writers should make every attempt to use only those functions |
| described in the POSIX.1 standard. This includes most of the |
| functions contained the Kernighan and Ritchie C programming book. Use |
| of operating system dependent functionality such as socket libraries |
| should always be included inside a conditional compilation block so |
| that it can be omitted on problematic platforms. If you are unsure |
| about a library call, check the man page or contact Dave. |
| |
| <a name="3" href="#i3"> |
| <h2>3. The Source Directory and Module Names</h2> |
| </a> |
| |
| All SWIG modules are contained within the "Source" directory. Within |
| this directory, each module is placed into its own subdirectory. The |
| name of this subdirectory should exactly match the name of the module. |
| For example, if you are creating a module called "Tcl", all of your |
| files should be placed in a directory "Tcl". |
| |
| <p> |
| When choosing a module name, please pick a name that is not |
| currently in use. As a general convention, the first letter of a |
| module name is capitalized such as "Perl". Alternatives such as |
| "perl" or "PERL" should be avoided. In certain instances, the first |
| two letters may be capitalized as in "CParse." The exact usage of |
| this is somewhat inconsistent and isn't terribly important--just make |
| sure the first letter is capitalized. Also, module names should not |
| start with numbers, include underscores or any other special |
| non-alphanumeric characters. |
| |
| <a name="4" href="#i4"> |
| <h2>4. Include Files </h2> |
| </a> |
| |
| All modules should include a header file that defines the public interface. |
| The name of this header file should be of the form "swigmodule.h" where |
| "module" is the name of your module. For example, if you created a |
| module "Perl", the header file should be named "swigperl.h". This scheme |
| should prevent header-file naming conflicts both within SWIG and when linking |
| parts of SWIG to the outside world. |
| |
| <p> |
| All header files should include a short description, author information, copyright message, |
| CVS version, include guards, and be C++ aware. For example: |
| |
| <blockquote> |
| <pre> |
| /* ------------------------------------------------------------------------- |
| * swigperl.h |
| * |
| * All of the externally visible functions in the Perl module. |
| * |
| * Author(s) : David Beazley (beazley@cs.uchicago.edu) |
| * |
| * Copyright (C) 1999-2000, The University of Chicago. |
| * See the file LICENSE for information on usage and redistribution. |
| * |
| * $Header$ |
| * ------------------------------------------------------------------------- */ |
| |
| #ifndef _SWIGPERL_H |
| #define _SWIGPERL_H 1 |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| /* Your declarations here */ |
| ... |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| #endif /* _SWIGPERL_H */ |
| </pre> |
| </blockquote> |
| |
| |
| <p> |
| To minimize compilation time, please include as few other header files as possible. |
| |
| <a name="5" href="#i5"> |
| <h2>5. File Structure </h2> |
| </a> |
| |
| Each file in a module should be given a filename that is all lowercase letters |
| such as "parser.c", not "Parser.c" or "PARSER.c". Please note that filenames |
| are case-insensitive on Windows so this convention will prevent you from inadvertantly |
| creating two files that differ in case-only. |
| |
| <p> |
| Each file should include a short abstract, author information, copyright information, and |
| a CVS revision tag like this: |
| |
| <blockquote> |
| <pre> |
| /* ----------------------------------------------------------------------------- |
| * include.c |
| * |
| * This file implements the functions used to locate and include files in |
| * the SWIG library. Functions for maintaining the library search path are |
| * also located here. |
| * |
| * Author(s) : David Beazley (beazley@cs.uchicago.edu) |
| * |
| * Copyright (C) 1999-2000, The University of Chicago. |
| * See the file LICENSE for information on usage and redistribution. |
| * ----------------------------------------------------------------------------- */ |
| |
| static char cvsroot[] = "$Header$"; |
| |
| #include "swig.h" |
| |
| /* Declarations */ |
| typedef struct { |
| int x, y; |
| } Foo; |
| |
| ... |
| |
| /* Private Declarations (used only in this file) */ |
| static int avariable; |
| |
| ... |
| |
| /* Functions */ |
| ... |
| |
| </pre> |
| </blockquote> |
| |
| The CVS revision tag should be placed into a static string as shown |
| above. This adds the revision information to the SWIG executable and |
| makes it possible to extract version information from a raw binary |
| (sometimes useful in debugging). |
| |
| <p> |
| As a general rule, files start to get unmanagable once they exceed |
| about 2000 lines. Files larger than this should be broken up into |
| multiple files. Similarly, you should avoid the temptation to create |
| many small files as this increases compilation time and makes the |
| directory structure too complicated. |
| |
| <a name="6" href="#i6"> |
| <h2>6. Bottom-Up Design </h2> |
| </a> |
| |
| Within each source file, the preferred organization is to use what is |
| known as "bottom-up" design. Under this scheme, lower-level functions |
| appear first and the highest level function appears last. The easy |
| way to remember is that the "main" function of your module should |
| always appear last in the source file. For example: |
| |
| <blockquote> |
| <pre> |
| /* Simple bottom-up program */ |
| #include <stdio.h> |
| |
| int foo(int x, int y) { |
| /* Implement foo */ |
| ... |
| } |
| |
| int bar() { |
| ... |
| foo(i,j); |
| ... |
| } |
| |
| ... |
| int main(int argc, char **argv) { |
| ... |
| bar(); |
| ... |
| } |
| </pre> |
| </blockquote> |
| |
| This choice of design is somewhat arbitrary however it has a number of |
| benefits particular to C. In particular, a bottom-up design generally |
| eliminates the need to include forward references--resulting in |
| cleaner code and fewer compilation errors. |
| |
| <a name="7" href="#i7"> |
| <h2>7. Functions</h2> |
| </a> |
| |
| All functions should have a function header that gives the function name |
| and a short description like this: |
| |
| <blockquote> |
| <pre> |
| /* ------------------------------------------------------------------------- |
| * Swig_add_directory() |
| * |
| * Adds a directory to the SWIG search path. |
| * ------------------------------------------------------------------------- */ |
| |
| void |
| Swig_add_directory(DOH *dirname) { |
| ... |
| |
| } |
| </pre> |
| </blockquote> |
| |
| In the function declaration, the return type and any specifiers |
| (extern or static) should appear on a separate line followed by the |
| function name and arguments as shown above. The left curly brace |
| should appear on the same line as the function name. |
| |
| <p> |
| Function declarations should <b>NOT</b> use the pre-ANSI function |
| declaration syntax. The ANSI standard has been around long enough for |
| this to be a non-issue. |
| |
| <a name="8" href="#i8"> |
| <h2>8. Naming Conventions</h2> |
| </a> |
| |
| The following conventions are used to name various objects throughout SWIG. |
| |
| <h4>Functions</h4> |
| |
| Functions should consist of the module name and the function name separated by an underscore like this: |
| |
| <blockquote> |
| <pre> |
| Preprocessor_define() |
| Swig_add_directory() |
| </pre> |
| </blockquote> |
| |
| In general, the module name should match the name of the module |
| subdirectory and the function name should be in all lowercase with |
| words separated by underscores. |
| |
| <h4>Structures and Types</h4> |
| |
| If your module defines new structures, the structure name should include the name of the |
| module and the name of the structure appended together like this: |
| |
| <blockquote> |
| <pre> |
| typedef struct SwigScanner { |
| ... |
| } SwigScanner; |
| |
| typedef struct LParseType { |
| ... |
| } LParseType; |
| </pre> |
| </blockquote> |
| |
| In this case, both the name of the module and the type should be capitalized. Also, whenever |
| possible, you should use the "typedef struct Name { ... } Name" form when defining new |
| data structures. |
| |
| <h4>Global Variables</h4> |
| |
| Global variables should be avoided if at all possible. However, if you must use a global |
| variable, please prepend the module name and use the same naming scheme as for functions. |
| |
| <h4>Constants</h4> |
| |
| Constants should be created using #define and should be in all caps like this: |
| |
| <blockquote> |
| <pre> |
| #define SWIG_TOKEN_LPAREN 1 |
| </pre> |
| </blockquote> |
| |
| Separate words in a constant should be separated by underscores as with functions. |
| |
| <h4>Structure members</h4> |
| |
| Structure members should be in all lower-case and follow the same word-separation convention |
| as for function names. However, the module name does not have to be included. |
| For example: |
| |
| <blockquote> |
| <pre> |
| typedef struct SwigScanner { |
| DOH *text; /* Current token value */ |
| DOH *scanobjs; /* Objects being scanned */ |
| DOH *str; /* Current object being scanned */ |
| char *idstart; /* Optional identifier start characters */ |
| int next_token; /* Next token to be returned */ |
| int start_line; /* Starting line of certain declarations */ |
| int yylen; /* Length of text pushed into text */ |
| DOH *file; /* Current file name */ |
| } SwigScanner; |
| </pre> |
| </blockquote> |
| |
| <h4>Static Functions and Variables </h4> |
| |
| Static declarations are free to use any naming convention that is appropriate. However, most |
| existing parts of SWIG use lower-case names and follow the same convention as described for functions. |
| |
| <a name="9" href="#i9"> |
| <h2>9. Visibility</h2> |
| </a> |
| |
| Modules should keep the following rules in mind when exposing their internals: |
| |
| <ul> |
| <li>Only publicly accessible functions should be included in the module header file. |
| <li>All non-static declarations must be prepended with some form of the module name |
| to avoid potential linker namespace conflicts with other modules. |
| <li>Modules should not expose global variables or use global variables in their |
| public interface. |
| <li>Similarly, modules should discourage the direct manipulation of data contained |
| within data structures in favor of using function calls instead. For example, |
| instead of providing a user with a structure like this: |
| |
| <blockquote> |
| <pre> |
| typedef struct Foo { |
| int line; |
| } Foo; |
| </pre> |
| </blockquote> |
| |
| It is better to hide the implementation of Foo and provide an |
| function-call interface like this: |
| |
| <blockquote> |
| <pre> |
| typedef struct Foo Foo; |
| extern int Foo_getline(Foo *f); |
| extern void Foo_setline(Foo *f, int line); |
| </pre> |
| </blockquote> |
| |
| Although this results in worse performance, there are many practical |
| reasons for doing this. The most important reason is that it allows |
| you to change the internal representation of Foo without breaking all |
| of the other modules or having to recompile the entire universe after |
| making your changes. |
| |
| </ul> |
| |
| <a name="10" href="#i10"> |
| <h2>10. Miscellaneous Coding Guidelines</h2> |
| </a> |
| |
| <ul> |
| <li> Do not use the ternary ?: operator. It is unnecessarily error prone, |
| hard for people to read, and hard to maintain code that uses it. |
| [I don't agree w/ this guideline. ?: operator can be abused |
| just like everything else, but it can also be used cleanly. In some styles of |
| programming, it is the best tool for the job. --ttn] |
| </ul> |
| |
| <a name="11" href="#i11"> |
| <h2>11. CVS Tagging Conventions</h2> |
| </a> |
| |
| Use <tt>cvs tag</tt> to declare some set of file revisions as related in some |
| symbolic way. This eases reference, retrieval and manipulation of these files |
| later. At the moment (2001/01/16 14:02:53), the conventions are very simple; |
| let's hope they stay that way! |
| |
| <p> |
| There are two types of tags, internal (aka personal) and external. |
| Internal tags are used by SWIG developers primarily, whereas external |
| tags are used when communicating with people w/ anonymous cvs access. |
| <ul> |
| <li> Internal tags should start with the developer name and a hyphen. |
| <li> External tags should start with "v-". |
| </ul> |
| |
| That's all there is to it. Some example tags: |
| |
| <ul> |
| <li> ttn-pre-xml-patch |
| <li> ttn-post-xml-patch |
| <li> ttn-going-on-vacation-so-dutifully-tagging-now |
| <li> v-1-3-a37-fixes-bug-2432 |
| <li> v-1-3-a37-fixes-bug-2433 |
| <li> v-1-3-a37-fixes-bug-2432-again |
| <li> v-1-3-a37-release |
| </ul> |
| |
| <hr> |
| Copyright (C) 1999-2001 |
| <a href="mailto:swig-dev@cs.uchicago.edu">SWIG Development Team</a> |
| </body> |
| </html> |