]> Pileus Git - ~andy/fetchmail/blob - trio/html/group___user_defined.html
Credit Sunil with the --nosoftbounce patch.
[~andy/fetchmail] / trio / html / group___user_defined.html
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
2 <html>
3 <head>
4  <meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
5  <title>TRIO</title>
6  <link href="trio.css" rel="stylesheet" type="text/css">
7 </head>
8 <body>
9 <!-- Generated by Doxygen 1.2.12 -->
10 <center>
11 <a class="qindex" href="index.html">Main Page</a> &nbsp; <a class="qindex" href="modules.html">Modules</a> &nbsp; </center>
12 <hr><h1>User-defined Formatted Printing Functions.</h1>Functions for using customized formatting specifiers. 
13 <a href="#_details">More...</a><table border=0 cellpadding=0 cellspacing=0>
14 <tr><td colspan=2><br><h2>Functions</h2></td></tr>
15 <tr><td nowrap align=right valign=top>trio_pointer_t&nbsp;</td><td valign=bottom><a class="el" href="group___user_defined.html#a0">trio_register</a> (trio_callback_t callback, const char *name)</td></tr>
16 <tr><td>&nbsp;</td><td><font size=-1><em>Register new user-defined specifier.</em> <a href="#a0">More...</a><em></em></font><br><br></td></tr>
17 <tr><td nowrap align=right valign=top>void&nbsp;</td><td valign=bottom><a class="el" href="group___user_defined.html#a1">trio_unregister</a> (trio_pointer_t handle)</td></tr>
18 <tr><td>&nbsp;</td><td><font size=-1><em>Unregister an existing user-defined specifier.</em> <a href="#a1">More...</a><em></em></font><br><br></td></tr>
19 </table>
20 <hr><a name="_details"></a><h2>Detailed Description</h2>
21 Functions for using customized formatting specifiers.
22 <p>
23 <b>SYNOPSIS</b>
24 <p>
25 <div class="fragment"><pre>
26 cc ... -ltrio -lm
27
28 #include &lt;trio.h&gt;
29 #include &lt;triop.h&gt;
30 </pre></div>
31 <p>
32 <b>DESCRIPTION</b>
33 <p>
34 This documentation is incomplete.
35 <p>
36 <b>User-defined</b> <b>Specifier</b>
37 <p>
38 The user-defined specifier consists of a start character (\074 = '&lt;'), an optional namespace string followed by a namespace separator (\072 = ':'), a format string, and an end character (\076 = '&gt;').
39 <p>
40 The namespace string can consist of alphanumeric characters, and is used to define a named reference (see below). The namespace is case-sensitive. If no namespace is specified, then we use an unnamed reference (see below).
41 <p>
42 The format can consist of any character except the end character ('&gt;'), the namespace separator (':'), and the nil character (\000).
43 <p>
44 Any modifier can be used together with the user-defined specifier.
45 <p>
46 <b>Registering</b>
47 <p>
48 A user-defined specifier must be registered before it can be used. Unregistered user-defined specifiers are ignored. The <a class="el" href="group___user_defined.html#a0">trio_register</a> function is used to register a user-defined specifier. It takes two argument, a callback function and a namespace, and it returns a handle. The handle must be used to unregister the specifier later.
49 <p>
50 The following example registers a user-define specifier with the "my_namespace" namespace:
51 <p>
52 <div class="fragment"><pre>
53   my_handle = trio_register(my_callback, "my_namespace");
54 </pre></div>
55 <p>
56 There can only be one user-defined specifier with a given namespace. There can be an unlimited number (subject to maximum length of the namespace) of different user-defined specifiers.
57 <p>
58 Passing NULL as the namespace argument results in an anonymous reference. There can be an unlimited number of anonymous references.
59 <p>
60 <b>REFERENCES</b>
61 <p>
62 There are two ways that a registered callback can be called. Either the user-defined specifier must contain the registered namespace in the format string, or the handle is passed as an argument to the formatted printing function.
63 <p>
64 If the namespace is used, then a user-defined pointer must be passed as an argument:
65 <p>
66 <div class="fragment"><pre>
67   trio_printf("&lt;my_namespace:format&gt;\n", my_data);
68 </pre></div>
69 <p>
70 If the handle is used, then the user-defined specifier must not contain a namespace. Instead the handle must be passed as an argument, followed by a user-defined pointer:
71 <p>
72 <div class="fragment"><pre>
73   trio_printf("&lt;format&gt;\n", my_handle, my_data);
74 </pre></div>
75 <p>
76 The two examples above are equivalent.
77 <p>
78 There must be exactly one user-defined pointer per user-defined specifier. This pointer can be used within the callback function with the trio_get_argument getter function (see below).
79 <p>
80 The format string is optional. It can be used within the callback function with the trio_get_format getter function.
81 <p>
82 <b>Anonymous</b> <b>References</b> Anonymous references are specified by passing NULL as the namespace.
83 <p>
84 The handle must be passed as an argument followed by a user-defined pointer. No namespace can be specified.
85 <p>
86 <div class="fragment"><pre>
87   anon_handle = trio_register(callback, NULL);
88   trio_printf("&lt;format&gt;\n", anon_handle, my_data);
89 </pre></div>
90 <p>
91 <b>Restrictions</b>
92 <p>
93 <ul>
94 <li> The length of the namespace string cannot exceed 63 characters. <li> The length of the user-defined format string cannot exceed 255 characters. <li> User-defined formatting cannot re-define existing specifiers. This restriction was imposed because the existing formatting specifiers have a well-defined behaviour, and any re-definition would apply globally to an application (imagine a third-party library changing the behaviour of a specifier that is crusial to your application).</ul>
95 <b>CALLBACK</b> <b>FUNCTION</b>
96 <p>
97 The callback function will be called if a matching user-defined specifier is found within the formatting string. The callback function takes one input parameter, an opaque reference which is needed by the private functions. It returns an <code>int</code>, which is currently ignored. The prototype is
98 <p>
99 <div class="fragment"><pre>
100   int (*trio_callback_t)(void *ref);
101 </pre></div>
102 <p>
103 See the Example section for full examples.
104 <p>
105 <b>PRINTING</b> <b>FUNCTIONS</b>
106 <p>
107 The following printing functions must only be used inside a callback function. These functions will print to the same output medium as the printf function which invoked the callback function. For example, if the user-defined specifier is used in an sprintf function, then these print functions will output their result to the same string.
108 <p>
109 <b>Elementary</b> <b>Printing</b>
110 <p>
111 There are a number of function to print elementary data types.
112 <p>
113 <ul>
114 <li> trio_print_int Print a signed integer. For example: <div class="fragment"><pre>
115   trio_print_int(42);
116 </pre></div> <li> trio_print_uint Print an unsigned integer. <li> trio_print_double Print a floating-point number. <li> trio_print_string Print a string. For example: <div class="fragment"><pre>
117   trio_print_string("Hello World");
118   trio_print_string(trio_get_format());
119 </pre></div> <li> trio_print_pointer Print a pointer.</ul>
120 <b>Formatted</b> <b>Printing</b>
121 <p>
122 The functions trio_print_ref, trio_vprint_ref, and trio_printv_ref outputs a formatted string just like its printf equivalents.
123 <p>
124 <div class="fragment"><pre>
125   trio_print_ref(ref, "There are %d towels\n", 42);
126   trio_print_ref(ref, "%&lt;recursive&gt;\n", recursive_writer, trio_get_argument());
127 </pre></div>
128 <p>
129 <b>GETTER</b> <b>AND</b> <b>SETTER</b> <b>FUNCTIONS</b>
130 <p>
131 The following getter and setter functions must only be used inside a callback function. They can either operate on the modifiers or on special data.
132 <p>
133 <b>Modifiers</b>
134 <p>
135 The value of a modifier, or a boolean indication of its presence or absence, can be found or set with the getter and setter functions. The generic prototypes of the these getter and setter functions are
136 <p>
137 <div class="fragment"><pre>
138   int  trio_get_???(void *ref);
139   void trio_set_???(void *ref, int);
140 </pre></div>
141 <p>
142 where ??? <code>refers</code> to a modifier. For example, to get the width of the user-defined specifier use
143 <p>
144 <div class="fragment"><pre>
145   int width = trio_get_width(ref);
146 </pre></div>
147 <p>
148 <b>Special</b> <b>Data</b>
149 <p>
150 Consider the following user-defined specifier, in its two possible referencing presentations.
151 <p>
152 <div class="fragment"><pre>
153   trio_printf("%&lt;format&gt;\n", namespace_writer, argument);
154   trio_printf("%&lt;namespace:format&gt;\n", argument);
155 </pre></div>
156 <p>
157 trio_get_format will get the <code>format</code> string, and trio_get_argument} will get the <code>argument</code> parameter. There are no associated setter functions.
158 <p>
159 <b>EXAMPLES</b>
160 <p>
161 The following examples show various types of user-defined specifiers. Although each specifier is demonstrated in isolation, they can all co-exist within the same application.
162 <p>
163 <b>Time</b> <b>Example</b>
164 <p>
165 Print the time in the format "HOUR:MINUTE:SECOND" if "time" is specified inside the user-defined specifier.
166 <p>
167 <div class="fragment"><pre>
168   static int time_writer(void *ref)
169   {
170     const char *format;
171     time_t *data;
172     char buffer[256];
173
174     format = trio_get_format(ref);
175     if ((format) &amp;&amp; (strcmp(format, "time") == 0)) {
176       data = trio_get_argument(ref);
177       if (data == NULL)
178         return -1;
179       strftime(buffer, sizeof(buffer), "%H:%M:%S", localtime(data));
180       trio_print_string(ref, buffer);
181     }
182     return 0;
183   }
184 </pre></div>
185 <p>
186 <div class="fragment"><pre>
187   int main(void)
188   {
189     void *handle;
190     time_t now = time(NULL);
191
192     handle = trio_register(time_print, "my_time");
193
194     trio_printf("%&lt;time&gt;\n", handle, &amp;now);
195     trio_printf("%&lt;my_time:time&gt;\n", &amp;now);
196
197     trio_unregister(handle);
198     return 0;
199   }
200 </pre></div>
201 <p>
202 <b>Complex</b> <b>Numbers</b> <b>Example</b>
203 <p>
204 Consider a complex number consisting of a real part, re, and an imaginary part, im.
205 <p>
206 <div class="fragment"><pre>
207   struct Complex {
208     double re;
209     double im;
210   };
211 </pre></div>
212 <p>
213 This example can print such a complex number in one of two formats. The default format is "re + i im". If the alternative modifier is used, then the format is "r exp(i theta)", where r is the length of the complex vector (re, im) and theta is its angle.
214 <p>
215 <div class="fragment"><pre>
216   static int complex_print(void *ref)
217   {
218     struct Complex *data;
219     const char *format;
220
221     data = (struct Complex *)trio_get_argument(ref);
222     if (data) {
223       format = trio_get_format(ref);
224
225       if (trio_get_alternative(ref)) {
226         double r, theta;
227
228         r = sqrt(pow(data-&gt;re, 2) + pow(data-&gt;im, 2));
229         theta = acos(data-&gt;re / r);
230         trio_print_ref(ref, "%#f exp(i %#f)", r, theta);
231
232       } else {
233         trio_print_ref(ref, "%#f + i %#f", data-&gt;re, data-&gt;im);
234       }
235     }
236     return 0;
237   }
238 </pre></div>
239 <p>
240 <div class="fragment"><pre>
241   int main(void)
242   {
243     void *handle;
244
245     handle = trio_register(complex_print, "complex");
246
247     /* Normal format. With handle and the with namespace */
248     trio_printf("%&lt;&gt;\n", handle, &amp;complex);
249     trio_printf("%&lt;complex:&gt;\n", &amp;complex);
250     /* In exponential notation */
251     trio_printf("%#&lt;&gt;\n", handle, &amp;complex);
252     trio_printf("%#&lt;complex:unused data&gt;\n", &amp;complex);
253
254     trio_unregister(handle);
255     return 0;
256   }
257 </pre></div>
258 <p>
259 <b>RETURN</b> <b>VALUES</b>
260 <p>
261 <a class="el" href="group___user_defined.html#a0">trio_register</a> returns a handle, or NULL if an error occured.
262 <p>
263 <b>SEE</b> <b>ALSO</b>
264 <p>
265 <a class="el" href="group___printf.html#a0">trio_printf</a>
266 <p>
267 <b>NOTES</b>
268 <p>
269 User-defined specifiers, <a class="el" href="group___user_defined.html#a0">trio_register</a>, and <a class="el" href="group___user_defined.html#a1">trio_unregister</a> are not thread-safe. In multi-threaded applications they must be guarded by mutexes. Trio provides two special callback functions, called ":enter" and ":leave", which are invoked every time a thread-unsafe operation is attempted. As the thread model is determined by the application, these callback functions must be implemented by the application.
270 <p>
271 The following callback functions are for demonstration-purposes only. Replace their bodies with locking and unlocking of a mutex to achieve thread-safety. <div class="fragment"><pre>
272   static int enter_region(void *ref)
273   {
274     fprintf(stderr, "Enter Region\n");
275     return 1;
276   }
277
278   static int leave_region(void *ref)
279   {
280     fprintf(stderr, "Leave Region\n");
281     return 1;
282   }
283 </pre></div> These two callbacks must be registered before other callbacks are registered. <div class="fragment"><pre>
284   trio_register(enter_region, ":enter");
285   trio_register(leave_region, ":leave");
286
287   another_handle = trio_register(another_callback, NULL);
288 </pre></div> <hr><h2>Function Documentation</h2>
289 <a name="a0" doxytag="trio.c::trio_register"></a><p>
290 <table width="100%" cellpadding="2" cellspacing="0" border="0">
291   <tr>
292     <td class="md">
293       <table cellpadding="0" cellspacing="0" border="0">
294         <tr>
295           <td class="md" nowrap valign="top"> trio_pointer_t trio_register </td>
296           <td class="md" valign="top">(&nbsp;</td>
297           <td class="md" nowrap valign="top">trio_callback_t&nbsp;</td>
298           <td class="mdname" nowrap>&nbsp; <em>callback</em>, </td>
299         </tr>
300         <tr>
301           <td></td>
302           <td></td>
303           <td class="md" nowrap>const char *&nbsp;</td>
304           <td class="mdname" nowrap>&nbsp; <em>name</em></td>
305         </tr>
306         <tr>
307           <td></td>
308           <td class="md">)&nbsp;</td>
309           <td class="md" colspan="2"></td>
310         </tr>
311
312       </table>
313     </td>
314   </tr>
315 </table>
316 <table cellspacing=5 cellpadding=0 border=0>
317   <tr>
318     <td>
319       &nbsp;
320     </td>
321     <td>
322
323 <p>
324 Register new user-defined specifier.
325 <p>
326 <dl compact><dt><b>
327 Parameters: </b><dd>
328 <table border=0 cellspacing=2 cellpadding=0>
329 <tr><td valign=top><em>callback</em>&nbsp;</td><td>
330 </td></tr>
331 <tr><td valign=top><em>name</em>&nbsp;</td><td>
332 </td></tr>
333 </table>
334 </dl><dl compact><dt><b>
335 Returns: </b><dd>
336 Handle. </dl>    </td>
337   </tr>
338 </table>
339 <a name="a1" doxytag="trio.c::trio_unregister"></a><p>
340 <table width="100%" cellpadding="2" cellspacing="0" border="0">
341   <tr>
342     <td class="md">
343       <table cellpadding="0" cellspacing="0" border="0">
344         <tr>
345           <td class="md" nowrap valign="top"> void trio_unregister </td>
346           <td class="md" valign="top">(&nbsp;</td>
347           <td class="md" nowrap valign="top">trio_pointer_t&nbsp;</td>
348           <td class="mdname1" valign="top" nowrap>&nbsp; <em>handle</em>          </td>
349           <td class="md" valign="top">)&nbsp;</td>
350           <td class="md" nowrap></td>
351         </tr>
352
353       </table>
354     </td>
355   </tr>
356 </table>
357 <table cellspacing=5 cellpadding=0 border=0>
358   <tr>
359     <td>
360       &nbsp;
361     </td>
362     <td>
363
364 <p>
365 Unregister an existing user-defined specifier.
366 <p>
367 <dl compact><dt><b>
368 Parameters: </b><dd>
369 <table border=0 cellspacing=2 cellpadding=0>
370 <tr><td valign=top><em>handle</em>&nbsp;</td><td>
371 </td></tr>
372 </table>
373 </dl>    </td>
374   </tr>
375 </table>
376 <HR>
377 <center class="copyright">Copyright (C) 2001 Bj&oslash;rn Reese and Daniel Stenberg.</center>
378 </body>
379 </html>