index.html revision 303975
1<html> 2<head> 3 <title>libsm Overview</title> 4</head> 5<body> 6 7<center> 8 <h1> libsm Overview </h1> 9 <br> $Id: index.html,v 1.14 2001-02-13 21:21:25 gshapiro Exp $ 10</center> 11 12<h2> Introduction </h2> 13 14Libsm is a library of generally useful C abstractions. 15Libsm stands alone; it depends on no other sendmail libraries, 16and the only sendmail header files it depends on are its own, 17which reside in <tt>../include/sm</tt>. 18 19<h2> Contents </h2> 20 21Here is the current set of packages: 22<blockquote> 23 <a href="gen.html"> gen: general definitions </a><br> 24 <a href="debug.html"> debug: debugging and tracing </a><br> 25 <a href="assert.html"> assert: assertion handling and aborts </a><br> 26 <a href="heap.html"> heap: memory allocation </a><br> 27 <a href="exc.html"> exc: exception handling </a><br> 28 <a href="rpool.html"> rpool: resource pools </a><br> 29 <a href="cdefs.html"> cdefs: C language portability macros </a><br> 30 <a href="io.html"> io: buffered i/o </a><br> 31</blockquote> 32 33<h2> Naming Conventions </h2> 34 35 Some of the symbols defined by libsm 36 come from widely used defacto or dejure standards. 37 Examples include <tt>size_t</tt> (from the C 89 standard), 38 <tt>bool</tt> (from the C 99 standard), 39 <tt>strerror</tt> (from Posix), 40 and <tt>__P</tt> (from BSD and Linux). 41 In these cases, we use the standard name rather than 42 inventing a new name. 43 We import the name from the appropriate header file when possible, 44 or define it ourselves when necessary. 45 When you are using one of these abstractions, you must include 46 the appropriate libsm header file. 47 For example, when you are using <tt>strerror</tt>, you must 48 include <tt><sm/string.h></tt> instead of <tt><string.h></tt>. 49 50 <p> 51 When we aren't implementing a standard interface, 52 we use a naming convention that attempts to maximize portability 53 across platforms, and minimize conflicts with other libraries. 54 Except for a few seemingly benign exceptions, 55 all names begin with <tt>SM_</tt>, <tt>Sm</tt> or <tt>sm_</tt>. 56 57 <p> 58 The ISO C, Posix and Unix standards forbid applications 59 from using names beginning with <tt>__</tt> or <tt>_[A-Z]</tt>, 60 and place restrictions on what sorts of names can begin 61 with <tt>_[a-z]</tt>. Such names are reserved for the compiler and 62 the standard libraries. 63 For this reason, we avoid defining any names that begin 64 with <tt>_</tt>. 65 For example, all libsm header file idempotency macros have the form 66 <tt>SM_FOO_H</tt> (no leading <tt>_</tt>). 67 68 <p> 69 Type names begin with <tt>SM_</tt> and end with <tt>_T</tt>. 70 Note that the Posix standard reserves all identifiers ending 71 with <tt>_t</tt>. 72 73 <p> 74 All functions that are capable of raising an exception 75 have names ending in <tt>_x</tt>, and developers are 76 encouraged to use this convention when writing new code. 77 This naming convention may seem unnecessary at first, 78 but it becomes extremely useful during maintenance, 79 when you are attempting to reason about the correctness 80 of a block of code, 81 and when you are trying to track down exception-related bugs 82 in existing code. 83 84<h2> Coding Conventions </h2> 85 86The official style for function prototypes in libsm header files is 87 88<blockquote><pre> 89extern int 90foo __P(( 91 int _firstarg, 92 int _secondarg)); 93</pre></blockquote> 94 95The <tt>extern</tt> is useless, but required for stylistic reasons. 96The parameter names are optional; if present they are lowercase 97and begin with _ to avoid namespace conflicts. 98Each parameter is written on its own line to avoid very long lines. 99 100<p> 101For each structure <tt>struct sm_foo</tt> defined by libsm, 102there is a typedef: 103 104<blockquote><pre> 105typedef struct sm_foo SM_FOO_T; 106</pre></blockquote> 107 108and there is a global variable which is defined as follows: 109 110<blockquote><pre> 111const char SmFooMagic[] = "sm_foo"; 112</pre></blockquote> 113 114The first member of each structure defined by libsm is 115 116<blockquote><pre> 117const char *sm_magic; 118</pre></blockquote> 119 120For all instances of <tt>struct sm_foo</tt>, 121<tt>sm_magic</tt> contains <tt>SmFooMagic</tt>, 122which points to a unique character string naming the type. 123It is used for debugging and run time type checking. 124 125<p> 126Each function with a parameter declared <tt>SM_FOO_T *foo</tt> 127contains the following assertion: 128 129<blockquote><pre> 130SM_REQUIRE_ISA(foo, SmFooMagic); 131</pre></blockquote> 132 133which is equivalent to 134 135<blockquote><pre> 136SM_REQUIRE(foo != NULL && foo->sm_magic == SmFooMagic); 137</pre></blockquote> 138 139When an object of type <tt>SM_FOO_T</tt> is deallocated, 140the member <tt>sm_magic</tt> is set to <tt>NULL</tt>. 141That will cause the above assertion to fail if a dangling pointer is used. 142 143<h2> Additional Design Goals </h2> 144 145Here are some of my design goals: 146<ul> 147 <p> 148<li>The sm library is self contained; it does not depend on any other 149 sendmail libraries or header files. 150 <p> 151<li>The sm library must be compatible with shared libraries, 152 even on platforms with weird implementation restrictions. 153 I assume that a shared library can export global variables; 154 the debug package relies on this assumption. 155 I do not assume that if an application redefines a function defined 156 in a shared library, the shared library will use the version of the 157 function defined in the application in preference to the version 158 that it defines. 159 For this reason, I provide interfaces for registering handler functions 160 in cases where an application might need to override standard behaviour. 161 <p> 162<li>The sm library must be compatible with threads. 163 The debug package presents a small problem: I don't want 164 sm_debug_active to acquire and release a lock. 165 So I assume that 166 there exists an integral type <tt>SM_ATOMIC_INT_T</tt> 167 (see <a href="gen.html"><tt><sm/gen.h></tt></a>) 168 that can be accessed and updated atomically. 169 I assume that locking must be used to guard updates and accesses to 170 any other type, and I have designed the interfaces accordingly. 171</ul> 172 173</body> 174</html> 175