diff options
Diffstat (limited to 'trio/html/group___user_defined.html')
-rw-r--r-- | trio/html/group___user_defined.html | 379 |
1 files changed, 379 insertions, 0 deletions
diff --git a/trio/html/group___user_defined.html b/trio/html/group___user_defined.html new file mode 100644 index 00000000..b2507275 --- /dev/null +++ b/trio/html/group___user_defined.html @@ -0,0 +1,379 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<html> +<head> + <meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"> + <title>TRIO</title> + <link href="trio.css" rel="stylesheet" type="text/css"> +</head> +<body> +<!-- Generated by Doxygen 1.2.12 --> +<center> +<a class="qindex" href="index.html">Main Page</a> <a class="qindex" href="modules.html">Modules</a> </center> +<hr><h1>User-defined Formatted Printing Functions.</h1>Functions for using customized formatting specifiers. +<a href="#_details">More...</a><table border=0 cellpadding=0 cellspacing=0> +<tr><td colspan=2><br><h2>Functions</h2></td></tr> +<tr><td nowrap align=right valign=top>trio_pointer_t </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> +<tr><td> </td><td><font size=-1><em>Register new user-defined specifier.</em> <a href="#a0">More...</a><em></em></font><br><br></td></tr> +<tr><td nowrap align=right valign=top>void </td><td valign=bottom><a class="el" href="group___user_defined.html#a1">trio_unregister</a> (trio_pointer_t handle)</td></tr> +<tr><td> </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> +</table> +<hr><a name="_details"></a><h2>Detailed Description</h2> +Functions for using customized formatting specifiers. +<p> +<b>SYNOPSIS</b> +<p> +<div class="fragment"><pre> +cc ... -ltrio -lm + +#include <trio.h> +#include <triop.h> +</pre></div> +<p> +<b>DESCRIPTION</b> +<p> +This documentation is incomplete. +<p> +<b>User-defined</b> <b>Specifier</b> +<p> +The user-defined specifier consists of a start character (\074 = '<'), an optional namespace string followed by a namespace separator (\072 = ':'), a format string, and an end character (\076 = '>'). +<p> +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). +<p> +The format can consist of any character except the end character ('>'), the namespace separator (':'), and the nil character (\000). +<p> +Any modifier can be used together with the user-defined specifier. +<p> +<b>Registering</b> +<p> +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. +<p> +The following example registers a user-define specifier with the "my_namespace" namespace: +<p> +<div class="fragment"><pre> + my_handle = trio_register(my_callback, "my_namespace"); +</pre></div> +<p> +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. +<p> +Passing NULL as the namespace argument results in an anonymous reference. There can be an unlimited number of anonymous references. +<p> +<b>REFERENCES</b> +<p> +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. +<p> +If the namespace is used, then a user-defined pointer must be passed as an argument: +<p> +<div class="fragment"><pre> + trio_printf("<my_namespace:format>\n", my_data); +</pre></div> +<p> +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: +<p> +<div class="fragment"><pre> + trio_printf("<format>\n", my_handle, my_data); +</pre></div> +<p> +The two examples above are equivalent. +<p> +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). +<p> +The format string is optional. It can be used within the callback function with the trio_get_format getter function. +<p> +<b>Anonymous</b> <b>References</b> Anonymous references are specified by passing NULL as the namespace. +<p> +The handle must be passed as an argument followed by a user-defined pointer. No namespace can be specified. +<p> +<div class="fragment"><pre> + anon_handle = trio_register(callback, NULL); + trio_printf("<format>\n", anon_handle, my_data); +</pre></div> +<p> +<b>Restrictions</b> +<p> +<ul> +<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> +<b>CALLBACK</b> <b>FUNCTION</b> +<p> +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 +<p> +<div class="fragment"><pre> + int (*trio_callback_t)(void *ref); +</pre></div> +<p> +See the Example section for full examples. +<p> +<b>PRINTING</b> <b>FUNCTIONS</b> +<p> +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. +<p> +<b>Elementary</b> <b>Printing</b> +<p> +There are a number of function to print elementary data types. +<p> +<ul> +<li> trio_print_int Print a signed integer. For example: <div class="fragment"><pre> + trio_print_int(42); +</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> + trio_print_string("Hello World"); + trio_print_string(trio_get_format()); +</pre></div> <li> trio_print_pointer Print a pointer.</ul> +<b>Formatted</b> <b>Printing</b> +<p> +The functions trio_print_ref, trio_vprint_ref, and trio_printv_ref outputs a formatted string just like its printf equivalents. +<p> +<div class="fragment"><pre> + trio_print_ref(ref, "There are %d towels\n", 42); + trio_print_ref(ref, "%<recursive>\n", recursive_writer, trio_get_argument()); +</pre></div> +<p> +<b>GETTER</b> <b>AND</b> <b>SETTER</b> <b>FUNCTIONS</b> +<p> +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. +<p> +<b>Modifiers</b> +<p> +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 +<p> +<div class="fragment"><pre> + int trio_get_???(void *ref); + void trio_set_???(void *ref, int); +</pre></div> +<p> +where ??? <code>refers</code> to a modifier. For example, to get the width of the user-defined specifier use +<p> +<div class="fragment"><pre> + int width = trio_get_width(ref); +</pre></div> +<p> +<b>Special</b> <b>Data</b> +<p> +Consider the following user-defined specifier, in its two possible referencing presentations. +<p> +<div class="fragment"><pre> + trio_printf("%<format>\n", namespace_writer, argument); + trio_printf("%<namespace:format>\n", argument); +</pre></div> +<p> +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. +<p> +<b>EXAMPLES</b> +<p> +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. +<p> +<b>Time</b> <b>Example</b> +<p> +Print the time in the format "HOUR:MINUTE:SECOND" if "time" is specified inside the user-defined specifier. +<p> +<div class="fragment"><pre> + static int time_writer(void *ref) + { + const char *format; + time_t *data; + char buffer[256]; + + format = trio_get_format(ref); + if ((format) && (strcmp(format, "time") == 0)) { + data = trio_get_argument(ref); + if (data == NULL) + return -1; + strftime(buffer, sizeof(buffer), "%H:%M:%S", localtime(data)); + trio_print_string(ref, buffer); + } + return 0; + } +</pre></div> +<p> +<div class="fragment"><pre> + int main(void) + { + void *handle; + time_t now = time(NULL); + + handle = trio_register(time_print, "my_time"); + + trio_printf("%<time>\n", handle, &now); + trio_printf("%<my_time:time>\n", &now); + + trio_unregister(handle); + return 0; + } +</pre></div> +<p> +<b>Complex</b> <b>Numbers</b> <b>Example</b> +<p> +Consider a complex number consisting of a real part, re, and an imaginary part, im. +<p> +<div class="fragment"><pre> + struct Complex { + double re; + double im; + }; +</pre></div> +<p> +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. +<p> +<div class="fragment"><pre> + static int complex_print(void *ref) + { + struct Complex *data; + const char *format; + + data = (struct Complex *)trio_get_argument(ref); + if (data) { + format = trio_get_format(ref); + + if (trio_get_alternative(ref)) { + double r, theta; + + r = sqrt(pow(data->re, 2) + pow(data->im, 2)); + theta = acos(data->re / r); + trio_print_ref(ref, "%#f exp(i %#f)", r, theta); + + } else { + trio_print_ref(ref, "%#f + i %#f", data->re, data->im); + } + } + return 0; + } +</pre></div> +<p> +<div class="fragment"><pre> + int main(void) + { + void *handle; + + handle = trio_register(complex_print, "complex"); + + /* Normal format. With handle and the with namespace */ + trio_printf("%<>\n", handle, &complex); + trio_printf("%<complex:>\n", &complex); + /* In exponential notation */ + trio_printf("%#<>\n", handle, &complex); + trio_printf("%#<complex:unused data>\n", &complex); + + trio_unregister(handle); + return 0; + } +</pre></div> +<p> +<b>RETURN</b> <b>VALUES</b> +<p> +<a class="el" href="group___user_defined.html#a0">trio_register</a> returns a handle, or NULL if an error occured. +<p> +<b>SEE</b> <b>ALSO</b> +<p> +<a class="el" href="group___printf.html#a0">trio_printf</a> +<p> +<b>NOTES</b> +<p> +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. +<p> +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> + static int enter_region(void *ref) + { + fprintf(stderr, "Enter Region\n"); + return 1; + } + + static int leave_region(void *ref) + { + fprintf(stderr, "Leave Region\n"); + return 1; + } +</pre></div> These two callbacks must be registered before other callbacks are registered. <div class="fragment"><pre> + trio_register(enter_region, ":enter"); + trio_register(leave_region, ":leave"); + + another_handle = trio_register(another_callback, NULL); +</pre></div> <hr><h2>Function Documentation</h2> +<a name="a0" doxytag="trio.c::trio_register"></a><p> +<table width="100%" cellpadding="2" cellspacing="0" border="0"> + <tr> + <td class="md"> + <table cellpadding="0" cellspacing="0" border="0"> + <tr> + <td class="md" nowrap valign="top"> trio_pointer_t trio_register </td> + <td class="md" valign="top">( </td> + <td class="md" nowrap valign="top">trio_callback_t </td> + <td class="mdname" nowrap> <em>callback</em>, </td> + </tr> + <tr> + <td></td> + <td></td> + <td class="md" nowrap>const char * </td> + <td class="mdname" nowrap> <em>name</em></td> + </tr> + <tr> + <td></td> + <td class="md">) </td> + <td class="md" colspan="2"></td> + </tr> + + </table> + </td> + </tr> +</table> +<table cellspacing=5 cellpadding=0 border=0> + <tr> + <td> + + </td> + <td> + +<p> +Register new user-defined specifier. +<p> +<dl compact><dt><b> +Parameters: </b><dd> +<table border=0 cellspacing=2 cellpadding=0> +<tr><td valign=top><em>callback</em> </td><td> +</td></tr> +<tr><td valign=top><em>name</em> </td><td> +</td></tr> +</table> +</dl><dl compact><dt><b> +Returns: </b><dd> +Handle. </dl> </td> + </tr> +</table> +<a name="a1" doxytag="trio.c::trio_unregister"></a><p> +<table width="100%" cellpadding="2" cellspacing="0" border="0"> + <tr> + <td class="md"> + <table cellpadding="0" cellspacing="0" border="0"> + <tr> + <td class="md" nowrap valign="top"> void trio_unregister </td> + <td class="md" valign="top">( </td> + <td class="md" nowrap valign="top">trio_pointer_t </td> + <td class="mdname1" valign="top" nowrap> <em>handle</em> </td> + <td class="md" valign="top">) </td> + <td class="md" nowrap></td> + </tr> + + </table> + </td> + </tr> +</table> +<table cellspacing=5 cellpadding=0 border=0> + <tr> + <td> + + </td> + <td> + +<p> +Unregister an existing user-defined specifier. +<p> +<dl compact><dt><b> +Parameters: </b><dd> +<table border=0 cellspacing=2 cellpadding=0> +<tr><td valign=top><em>handle</em> </td><td> +</td></tr> +</table> +</dl> </td> + </tr> +</table> +<HR> +<center class="copyright">Copyright (C) 2001 Bjørn Reese and Daniel Stenberg.</center> +</body> +</html> |