Merge from vendor branch CVS:
[dragonfly.git] / contrib / sendmail-8.13.4 / libsm / index.html
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
14 Libsm is a library of generally useful C abstractions.
15 Libsm stands alone; it depends on no other sendmail libraries,
16 and the only sendmail header files it depends on are its own,
17 which reside in <tt>../include/sm</tt>.
18
19 <h2> Contents </h2>
20
21 Here 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>&lt;sm/string.h&gt;</tt> instead of <tt>&lt;string.h&gt;</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
86 The official style for function prototypes in libsm header files is
87
88 <blockquote><pre>
89 extern int
90 foo __P((
91         int _firstarg,
92         int _secondarg));
93 </pre></blockquote>
94
95 The <tt>extern</tt> is useless, but required for stylistic reasons.
96 The parameter names are optional; if present they are lowercase
97 and begin with _ to avoid namespace conflicts.
98 Each parameter is written on its own line to avoid very long lines.
99
100 <p>
101 For each structure <tt>struct sm_foo</tt> defined by libsm,
102 there is a typedef:
103
104 <blockquote><pre>
105 typedef struct sm_foo SM_FOO_T;
106 </pre></blockquote>
107
108 and there is a global variable which is defined as follows:
109
110 <blockquote><pre>
111 const char SmFooMagic[] = "sm_foo";
112 </pre></blockquote>
113
114 The first member of each structure defined by libsm is
115
116 <blockquote><pre>
117 const char *sm_magic;
118 </pre></blockquote>
119
120 For all instances of <tt>struct sm_foo</tt>,
121 <tt>sm_magic</tt> contains <tt>SmFooMagic</tt>,
122 which points to a unique character string naming the type.
123 It is used for debugging and run time type checking.
124
125 <p>
126 Each function with a parameter declared <tt>SM_FOO_T *foo</tt>
127 contains the following assertion:
128
129 <blockquote><pre>
130 SM_REQUIRE_ISA(foo, SmFooMagic);
131 </pre></blockquote>
132
133 which is equivalent to
134
135 <blockquote><pre>
136 SM_REQUIRE(foo != NULL && foo-&gt;sm_magic == SmFooMagic);
137 </pre></blockquote>
138
139 When an object of type <tt>SM_FOO_T</tt> is deallocated,
140 the member <tt>sm_magic</tt> is set to <tt>NULL</tt>.
141 That will cause the above assertion to fail if a dangling pointer is used.
142
143 <h2> Additional Design Goals </h2>
144
145 Here 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>&lt;sm/gen.h&gt;</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>