1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
4 <title>c2lib documentation index</title>
5 <style type="text/css"><!--
10 background-color: #eeeeff;
19 <body bgcolor="#ffffff">
20 <h1>c2lib documentation index</h1>
23 <code>c2lib</code> is a library of basic tools for use by C
24 programmers. It contains features heavily influenced by
25 both Perl's string handling and C++'s Standard Template
30 The primary aims of <code>c2lib</code> are:
34 <li> Be very simple to use.
35 <li> Provide rich abstract data types (ADTs) for C programmers
37 <li> Provide some of the advantages of Perl with only
38 around a factor of 2-3 code-size expansion over Perl itself.
39 <li> Retain most of the efficiency advantages of C.
40 <li> Remain compatible with existing libc functions (particularly
41 existing string and regular expression functions).
42 <li> Clean, fully documented API.
45 <h2>Tutorial and programming examples</h2>
47 <h3>Join a list of strings and print</h3>
50 #include <pool.h>
51 #include <pstring.h>
53 const char *strings[] = { "John", "Paul", "George", "Ringo" };
57 pool pool = global_pool;
58 vector v = pvectora (pool, strings, 4);
59 10 printf ("Introducing the Beatles: %s\n", pjoin (pool, v, ", "));
64 When run, this program prints:
68 Introducing the Beatles: John, Paul, George, Ringo
72 Compare this to the equivalent Perl code:
78 printf "Introducing the Beatles: %s\n",
79 join(", ", "John", "Paul", "George", "Ringo");
83 The <code>pjoin(3)</code> function on line 10 is
84 equivalent to the plain <code>join</code> function
85 in Perl. It takes a list of strings and joins them
86 with a separator string (in this case <code>", "</code>),
87 and creates a new string which is returned and printed.
91 The <code>pvectora(3)</code> function (line 9) takes a normal C
92 array of strings and converts it into a <code>c2lib</code>
93 <code>vector</code>. You will find out more about
94 <code>vector</code>s later.
98 In this case all our allocations are done in a standard
99 pool which is created automatically before <code>main</code> is
100 called and deleted after <code>main</code> returns. This pool is
101 called <code>global_pool(3)</code>. You will find out
102 more about <code>pool</code>s below.
106 Notice that, as with most <code>c2lib</code> programs, there is
107 no need to explicitly deallocate (free) objects once you
108 have finished using them. Almost all of the time, objects
109 are freed automatically for you by the system.
112 <h3>A vector of integers</h3>
115 #include <pool.h>
116 #include <vector.h>
117 #include <pstring.h>
121 pool pool = global_pool;
122 vector v = new_vector (pool, int);
125 for (i = 1; i <= 10; ++i)
126 vector_push_back (v, i);
128 for (i = 0; i < vector_size (v); ++i)
132 vector_get (v, i, elem);
136 printf ("product of integers: %s = %d\n",
137 pjoin (pool, pvitostr (pool, v), " * "),
147 product of integers: 1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 = 3628800
151 The call to <code>new_vector(3)</code> on line 8 creates a new
152 vector object (abstract data type). In this case the vector is
153 allocated in the global pool and you have told it that each
154 element of the vector will be of type <code>int</code>. Vectors
155 are arrays which automatically expand when you push elements
156 onto them. This vector behaves very much like a C++ STL
157 <code>vector<int></code> or a Perl array.
161 On lines 11-12, we push the numbers 1 through to 10 into
162 the vector. The <code>vector_push_back(3)</code> function
163 pushes an element onto the end of the vector. There are
164 also <code>vector_pop_back(3)</code> (removes and returns the
165 last element of a vector), <code>vector_push_front(3)</code>
166 and <code>vector_pop_front(3)</code> operations.
170 Lines 14-20 show the general pattern for iterating over
171 the elements in a vector. The call to <code>vector_get</code>
172 (line 18) returns the <code>i</code>th element of vector <code>v</code>
173 into variable <code>elem</code>.
177 Finally lines 22-24 print out the result. We use the
178 <code>pjoin(3)</code> function again to join the numbers
179 with the string <code>" * "</code> between each pair.
180 Also note the use of the strange <code>pvitostr(3)</code>
181 function. <code>pjoin(3)</code> is expecting a vector
182 of strings (ie. a vector of <code>char *</code>), but
183 we have a vector of <code>int</code>, which is
184 incompatible. The <code>pvitostr(3)</code> function
185 promotes a vector of integers into a vector of strings.
189 The <code>c2lib</code> library stores vectors as arrays and
190 reallocates them using <code>prealloc(3)</code> whenever it
191 needs to expand them. This means that certain operations on
192 vectors are efficient, and some other operations are less
193 efficient. Getting an element of a vector or replacing an
194 element in the middle of a vector are both fast O(1) operations,
195 equivalent to the ordinary C index ([]) operator.
196 <code>vector_push_back(3)</code> and
197 <code>vector_pop_back(3)</code> are also fast. However
198 <code>vector_push_front(3)</code> and
199 <code>vector_pop_front(3)</code> are O(n) operations because
200 they require the library to shift up all the elements in the
201 array by one place. Normally however if your vectors are very
202 short (say, fewer than 100 elements), the speed difference will
203 not be noticable, whereas the productivity gains from using
204 vectors over hand-rolled linked lists or other structures will
205 be large. The <code>vector</code> type also allows you
206 to insert and remove elements in the middle of the array,
207 as shown in the next example below:
211 #include <pool.h>
212 #include <vector.h>
213 #include <pstring.h>
217 pool pool = global_pool;
218 vector v = pvector (pool,
219 "a", "b", "c", "d", "e",
220 10 "f", "g", "h", "i", "j", 0);
223 printf ("Original vector contains: %s\n",
224 pjoin (pool, v, ", "));
226 vector_erase_range (v, 3, 6);
228 printf ("After erasing elements 3-5, vector contains: %s\n",
229 pjoin (pool, v, ", "));
231 vector_insert (v, 3, X);
232 vector_insert (v, 4, X);
233 vector_insert (v, 5, X);
235 25 printf ("After inserting 3 Xs, vector contains: %s\n",
236 pjoin (pool, v, ", "));
239 vector_fill (v, X, 10);
241 printf ("After clearing and inserting 10 Xs, vector contains: %s\n",
242 pjoin (pool, v, ", "));
251 Original vector contains: a, b, c, d, e, f, g, h, i, j
252 After erasing elements 3-5, vector contains: a, b, c, g, h, i, j
253 After inserting 3 Xs, vector contains: a, b, c, X, X, X, g, h, i, j
254 After clearing and inserting 10 Xs, vector contains: X, X, X, X, X, X, X, X, X, X
258 This example demonstrates the following functions:
262 <li> <code>vector_erase_range(3)</code> which is used
263 to erase a range of elements from the middle of
265 <li> <code>vector_insert(3)</code> which is used to
266 insert single elements into a vector.
267 <li> <code>vector_clear(3)</code> which completely
268 clears the vector - removing all elements.
269 <li> <code>vector_fill(3)</code> which fills a vector
270 with identical elements.
274 For more information, see the respective manual pages.
278 You can store just about anything in a vector: strings,
279 pointers, wide integers, complex structures, etc. If you do
280 want to directly store large objects in a vector, you must
281 remember that the vector type actually copies those objects into
282 and out of the vector each time you insert, push, get, pop and
283 so on. For some large structures, you may want to store a
284 pointer instead (in fact with strings you have no choice: you
285 are always storing a pointer in the vector itself).
288 <h3>Strings are just <code>char *</code></h3>
291 <code>c2lib</code> doesn't have a fancy string type.
292 Instead we just use plain old <code>char *</code>. This
293 is possible because pools (see below) mean that we don't
294 need to worry about when to copy or deallocate specific
299 The great benefit of using plain <code>char *</code>
300 for strings is that we can continue to use the
301 familiar libc functions such as <code>strcmp(3)</code>,
302 <code>strcpy(3)</code>, <code>strlen(3)</code>, <code>printf(3)</code>
303 and so on, as in the next example.
307 #include <assert.h>
308 #include <pstring.h>
310 char *given_name = "Richard";
311 5 char *family_name = "Jones";
312 char *email_address = "rich@annexia.org";
316 10 pool pool = global_pool;
321 15 psprintf (pool, "%s %s <%s>", given_name, family_name, email_address);
323 printf ("full email address is: %s\n", email);
325 v = pstrcsplit (pool, email, ' ');
327 printf ("split email into %d components\n", vector_size (v));
329 vector_get (v, 0, s);
330 printf ("first component is: %s\n", s);
331 25 assert (strcmp (s, given_name) == 0);
333 vector_get (v, 1, s);
334 printf ("second component is: %s\n", s);
335 assert (strcmp (s, family_name) == 0);
337 vector_get (v, 2, s);
338 printf ("third component is: %s\n", s);
339 s = pstrdup (pool, s);
341 35 s[strlen(s)-1] = '\0';
342 assert (strcmp (s, email_address) == 0);
351 full email address is: Richard Jones <rich@annexia.org>
352 split email into 3 components
353 first component is: Richard
354 second component is: Jones
355 third component is: <rich@annexia.org>
359 Line 15 demonstrates the <code>psprintf(3)</code> function
360 which is like the ordinary <code>sprintf(3)</code>,
361 but is (a) safe, and (b) allocates the string in the
362 pool provided, ensuring that it will be safely deallocated
367 The <code>pstrcsplit(3)</code> function is similar to the
368 Perl <code>split</code>. It takes a string and splits it
369 into a vector of strings, in this case on the space
370 character. There are also other functions for splitting
371 on a string or on a regular expression.
375 The final part of the code, lines 21-36, prints out
376 the components of the split string. The <code>vector_get(3)</code>
377 function is used to pull the strings out of the vector object.
381 Notice on line 33 that before we remove the beginning
382 and end < ... > from around the email address,
383 we first duplicate the string using <code>pstrdup(3)</code>.
384 In this case it is not strictly necessary to duplicate
385 the string <code>s</code> because we know that
386 <code>pstrcsplit(3)</code> actually allocates new
387 copies of the strings in the vector which it returns.
388 However in general this is good practice because
389 otherwise we would be modifying the contents of the
390 original vector <code>v</code>.
396 Hashes give you all the power of Perl's "%" hashes. In
397 fact the way they work is very similar (but more powerful:
398 unlike Perl's hashes the key does not need to be a string).
402 In <code>c2lib</code> there are three flavors of hash.
403 However they all work in essentially the same way, and
404 all have exactly the same functionality. The reason for
405 having the three flavors is just to work around an obscure
406 problem with the ANSI C specification!
410 The three flavors are:
416 <td> A hash of any non-string type to any non-string type. </td>
420 <td> A hash of <code>char *</code> to <code>char *</code>. </td>
424 <td> A hash of <code>char *</code> to any non-string type. </td>
429 As with vectors, the phrase "any non-string type" can
430 be simple integers or chars, pointers, or complex large
431 structures if you wish.
435 Here is a short program showing you how to use a
436 sash (but note that the same functions are available
437 for all of the other flavors):
441 #include <stdio.h>
442 #include <hash.h>
443 #include <pstring.h>
447 pool pool = global_pool;
448 sash h = new_sash (pool);
450 10 const char *color;
452 sash_insert (h, "banana", "yellow");
453 sash_insert (h, "orange", "orange");
454 sash_insert (h, "apple", "red");
455 15 sash_insert (h, "kiwi", "green");
456 sash_insert (h, "grapefruit", "yellow");
457 sash_insert (h, "pear", "green");
458 sash_insert (h, "tomato", "red");
459 sash_insert (h, "tangerine", "orange");
463 printf ("Please type in the name of a fruit: ");
464 fruit = pgetline (pool, stdin, 0);
466 if (sash_get (h, fruit, color))
467 printf ("The color of that fruit is %s.\n", color);
469 printf ("Sorry, I don't know anything about that fruit.\n");
479 Please type in the name of a fruit: <b>orange</b>
480 The color of that fruit is orange.
481 Please type in the name of a fruit: <b>apple</b>
482 The color of that fruit is red.
483 Please type in the name of a fruit: <b>dragon fruit</b>
484 Sorry, I don't know anything about that fruit.
488 The sash is allocated on line 8 using the <code>new_sash(3)</code>
493 We populate the sash using the simple <code>sash_insert(3)</code>
494 functions (lines 12-19).
498 The <code>sash_get(3)</code> function retrieves a value
499 (<code>color</code>) from
500 the sash using the key given (<code>fruit</code>). It
501 returns true if a value was found, or false if there
506 There are many potentially powerful functions available
507 for manipulating hashes, sashes and shashes (below,
508 <code>*</code> stands for either "h", "s" or "sh"):
512 <li> <code>*ash_exists(3)</code> tells you if a key
513 exists. It is equivalent to the Perl <code>exists</code>
515 <li> <code>*ash_erase(3)</code> removes a key. It
516 is equivalent to the Perl <code>delete</code> function.
517 <li> <code>*ash_keys(3)</code> returns all of the
518 keys of a hash in a vector. It is equivalent to the
519 Perl <code>keys</code> function.
520 <li> <code>*ash_values(3)</code> returns all of the
521 values of a hash in a vector. It is equivalent to the
522 Perl <code>values</code> function.
523 <li> <code>*ash_size(3)</code> counts the number of keys.
526 <h3>Advanced used of pools</h3>
529 So far we have only touched upon pools, and it may not
530 be clear in the examples above why they don't in fact
531 leak memory. There appears to be no deallocation being
532 done, which is quite counter-intuitive to most C programmers!
536 Pools are collections of related objects (where an
537 "object" is some sort of memory allocation).
541 In C you are normally responsible for allocating and
542 deallocating every single object, like so:
554 However in <code>c2lib</code> we first allocate a pool,
555 then use <code>pmalloc(3)</code> and <code>prealloc(3)</code>
556 to allocate lots of related objects in the pool.
557 At the end of the program, all of the objects can be
558 deleted in one go just by calling <code>delete_pool(3)</code>.
562 There is one special pool, called <code>global_pool(3)</code>.
563 This pool is created for you before <code>main</code> is
564 called, and it is deleted for you after <code>main</code>
565 returns (or if <code>exit(3)</code> is called). You don't
566 ever need to worry about deallocating <code>global_pool(3)</code>
567 (in fact, if you try to, your program might core dump).
571 Thus most short programs like the ones above should just
572 allocate all objects in <code>global_pool(3)</code>, and
573 never need to worry about deallocating the objects or
578 For larger programs, and programs that are expected to run for a
579 long time like servers, you will need to learn about pools.
583 Pools are organised in a hierarchy. This means that you often
584 allocate one pool <i>inside</i> another pool. Here is a
591 /* ... use global_pool for allocations here ... */
593 for (;;) /* for each request: */
595 pool pool = new_subpool (global_pool);
597 /* ... process the request using pool ... */
605 <code>pool</code> is created as a subpool of
606 <code>global_pool(3)</code> for the duration of
607 the request. At the end of the request the pool
608 (and therefore all objects inside it) is deallocated.
612 The advantage of creating <code>pool</code> as a
613 subpool of <code>global_pool(3)</code> is that if
614 the request processing code calls <code>exit(3)</code>
615 in the middle of the request, then <code>global_pool(3)</code>
616 will be deallocated in the normal way and as a consequence
617 of this <code>pool</code> will also be properly deallocated.
621 You can also use <code>new_pool(3)</code> to create a
622 completely new top-level pool. There are some rare
623 circumstances when you will need to do this, but
624 generally you should avoid creating pools which are
625 not subpools. If in doubt, always create subpools of
626 <code>global_pool(3)</code> or of the pool immediately
631 Pools don't just store memory allocations. You can attach
632 other types of objects to pools, or trigger functions which
633 are run when the pool is deallocated. <code>pool_register_fd(3)</code>
634 attaches a file descriptor to a pool, meaning that the file
635 descriptor is closed when the pool is deleted (note
636 however that there is no way to unattach a file descriptor
637 from a pool, so don't go and call <code>close(3)</code>
638 on the file descriptor once you've attached it to
639 a pool. <code>pool_register_cleanup_fn(3)</code>
640 registers your own clean-up function which is called
641 when the pool is deleted. Although you should
642 normally use <code>pmalloc(3)</code> and/or
643 <code>prealloc(3)</code> to allocate objects directly
644 in pools, you can also allocate them normally using
645 <code>malloc(3)</code> and attach them to the pool
646 using <code>pool_register_malloc(3)</code>. The object
647 will be freed up automatically when the pool is
652 Pools become very important when writing multi-threaded
653 servers using the <code>pthrlib</code> library. Each
654 thread processes a single request or command. A pool
655 is created for every thread, and is automatically
656 deleted when the thread exits. This assumes of course
657 that threads (and hence requests) are short-lived, which
658 is a reasonable assumption for most HTTP-like services.
661 <h2>Links to manual pages</h2>
664 (These manual pages are not always up to date. For the
665 latest documentation, always consult the manual pages
666 supplied with the latest <code>c2lib</code> package!)
672 <li> <a href="delete_pool.3.html"><code>delete_pool(3)</code></a> </li>
673 <li> <a href="global_pool.3.html"><code>global_pool(3)</code></a> </li>
674 <li> <a href="new_pool.3.html"><code>new_pool(3)</code></a> </li>
675 <li> <a href="new_subpool.3.html"><code>new_subpool(3)</code></a> </li>
676 <li> <a href="pcalloc.3.html"><code>pcalloc(3)</code></a> </li>
677 <li> <a href="pmalloc.3.html"><code>pmalloc(3)</code></a> </li>
678 <li> <a href="pool_get_stats.3.html"><code>pool_get_stats(3)</code></a> </li>
679 <li> <a href="pool_register_cleanup_fn.3.html"><code>pool_register_cleanup_fn(3)</code></a> </li>
680 <li> <a href="pool_register_fd.3.html"><code>pool_register_fd(3)</code></a> </li>
681 <li> <a href="pool_register_malloc.3.html"><code>pool_register_malloc(3)</code></a> </li>
682 <li> <a href="pool_set_bad_malloc_handler.3.html"><code>pool_set_bad_malloc_handler(3)</code></a> </li>
683 <li> <a href="prealloc.3.html"><code>prealloc(3)</code></a> </li>
689 <li> <a href="copy_vector.3.html"><code>copy_vector(3)</code></a> </li>
690 <li> <a href="new_vector.3.html"><code>new_vector(3)</code></a> </li>
691 <li> <a href="vector_allocated.3.html"><code>vector_allocated(3)</code></a> </li>
692 <li> <a href="vector_clear.3.html"><code>vector_clear(3)</code></a> </li>
693 <li> <a href="vector_compare.3.html"><code>vector_compare(3)</code></a> </li>
694 <li> <a href="vector_element_size.3.html"><code>vector_element_size(3)</code></a> </li>
695 <li> <a href="vector_erase.3.html"><code>vector_erase(3)</code></a> </li>
696 <li> <a href="vector_erase_range.3.html"><code>vector_erase_range(3)</code></a> </li>
697 <li> <a href="vector_fill.3.html"><code>vector_fill(3)</code></a> </li>
698 <li> <a href="vector_get.3.html"><code>vector_get(3)</code></a> </li>
699 <li> <a href="vector_get_ptr.3.html"><code>vector_get_ptr(3)</code></a> </li>
700 <li> <a href="vector_grep.3.html"><code>vector_grep(3)</code></a> </li>
701 <li> <a href="vector_grep_pool.3.html"><code>vector_grep_pool(3)</code></a> </li>
702 <li> <a href="vector_insert.3.html"><code>vector_insert(3)</code></a> </li>
703 <li> <a href="vector_insert_array.3.html"><code>vector_insert_array(3)</code></a> </li>
704 <li> <a href="vector_map.3.html"><code>vector_map(3)</code></a> </li>
705 <li> <a href="vector_map_pool.3.html"><code>vector_map_pool(3)</code></a> </li>
706 <li> <a href="vector_pop_back.3.html"><code>vector_pop_back(3)</code></a> </li>
707 <li> <a href="vector_pop_front.3.html"><code>vector_pop_front(3)</code></a> </li>
708 <li> <a href="vector_push_back.3.html"><code>vector_push_back(3)</code></a> </li>
709 <li> <a href="vector_push_front.3.html"><code>vector_push_front(3)</code></a> </li>
710 <li> <a href="vector_reallocate.3.html"><code>vector_reallocate(3)</code></a> </li>
711 <li> <a href="vector_replace.3.html"><code>vector_replace(3)</code></a> </li>
712 <li> <a href="vector_replace_array.3.html"><code>vector_replace_array(3)</code></a> </li>
713 <li> <a href="vector_reverse.3.html"><code>vector_reverse(3)</code></a> </li>
714 <li> <a href="vector_size.3.html"><code>vector_size(3)</code></a> </li>
715 <li> <a href="vector_sort.3.html"><code>vector_sort(3)</code></a> </li>
716 <li> <a href="vector_swap.3.html"><code>vector_swap(3)</code></a> </li>
722 <li> <a href="copy_hash.3.html"><code>copy_hash(3)</code></a> </li>
723 <li> <a href="copy_sash.3.html"><code>copy_sash(3)</code></a> </li>
724 <li> <a href="copy_shash.3.html"><code>copy_shash(3)</code></a> </li>
725 <li> <a href="hash_erase.3.html"><code>hash_erase(3)</code></a> </li>
726 <li> <a href="hash_exists.3.html"><code>hash_exists(3)</code></a> </li>
727 <li> <a href="hash_get.3.html"><code>hash_get(3)</code></a> </li>
728 <li> <a href="hash_get_buckets_allocated.3.html"><code>hash_get_buckets_allocated(3)</code></a> </li>
729 <li> <a href="hash_get_buckets_used.3.html"><code>hash_get_buckets_used(3)</code></a> </li>
730 <li> <a href="hash_get_ptr.3.html"><code>hash_get_ptr(3)</code></a> </li>
731 <li> <a href="hash_insert.3.html"><code>hash_insert(3)</code></a> </li>
732 <li> <a href="hash_keys.3.html"><code>hash_keys(3)</code></a> </li>
733 <li> <a href="hash_keys_in_pool.3.html"><code>hash_keys_in_pool(3)</code></a> </li>
734 <li> <a href="hash_set_buckets_allocated.3.html"><code>hash_set_buckets_allocated(3)</code></a> </li>
735 <li> <a href="hash_size.3.html"><code>hash_size(3)</code></a> </li>
736 <li> <a href="hash_values.3.html"><code>hash_values(3)</code></a> </li>
737 <li> <a href="hash_values_in_pool.3.html"><code>hash_values_in_pool(3)</code></a> </li>
738 <li> <a href="new_hash.3.html"><code>new_hash(3)</code></a> </li>
739 <li> <a href="new_sash.3.html"><code>new_sash(3)</code></a> </li>
740 <li> <a href="new_shash.3.html"><code>new_shash(3)</code></a> </li>
741 <li> <a href="sash_erase.3.html"><code>sash_erase(3)</code></a> </li>
742 <li> <a href="sash_exists.3.html"><code>sash_exists(3)</code></a> </li>
743 <li> <a href="sash_get.3.html"><code>sash_get(3)</code></a> </li>
744 <li> <a href="sash_get_buckets_allocated.3.html"><code>sash_get_buckets_allocated(3)</code></a> </li>
745 <li> <a href="sash_get_buckets_used.3.html"><code>sash_get_buckets_used(3)</code></a> </li>
746 <li> <a href="sash_insert.3.html"><code>sash_insert(3)</code></a> </li>
747 <li> <a href="sash_keys.3.html"><code>sash_keys(3)</code></a> </li>
748 <li> <a href="sash_keys_in_pool.3.html"><code>sash_keys_in_pool(3)</code></a> </li>
749 <li> <a href="sash_set_buckets_allocated.3.html"><code>sash_set_buckets_allocated(3)</code></a> </li>
750 <li> <a href="sash_size.3.html"><code>sash_size(3)</code></a> </li>
751 <li> <a href="sash_values.3.html"><code>sash_values(3)</code></a> </li>
752 <li> <a href="sash_values_in_pool.3.html"><code>sash_values_in_pool(3)</code></a> </li>
753 <li> <a href="shash_erase.3.html"><code>shash_erase(3)</code></a> </li>
754 <li> <a href="shash_exists.3.html"><code>shash_exists(3)</code></a> </li>
755 <li> <a href="shash_get.3.html"><code>shash_get(3)</code></a> </li>
756 <li> <a href="shash_get_buckets_allocated.3.html"><code>shash_get_buckets_allocated(3)</code></a> </li>
757 <li> <a href="shash_get_buckets_used.3.html"><code>shash_get_buckets_used(3)</code></a> </li>
758 <li> <a href="shash_get_ptr.3.html"><code>shash_get_ptr(3)</code></a> </li>
759 <li> <a href="shash_insert.3.html"><code>shash_insert(3)</code></a> </li>
760 <li> <a href="shash_keys.3.html"><code>shash_keys(3)</code></a> </li>
761 <li> <a href="shash_keys_in_pool.3.html"><code>shash_keys_in_pool(3)</code></a> </li>
762 <li> <a href="shash_set_buckets_allocated.3.html"><code>shash_set_buckets_allocated(3)</code></a> </li>
763 <li> <a href="shash_size.3.html"><code>shash_size(3)</code></a> </li>
764 <li> <a href="shash_values.3.html"><code>shash_values(3)</code></a> </li>
765 <li> <a href="shash_values_in_pool.3.html"><code>shash_values_in_pool(3)</code></a> </li>
768 <h3>Strings and miscellaneous</h3>
771 <li> <a href="pchomp.3.html"><code>pchomp(3)</code></a> </li>
772 <li> <a href="pchrs.3.html"><code>pchrs(3)</code></a> </li>
773 <li> <a href="pconcat.3.html"><code>pconcat(3)</code></a> </li>
774 <li> <a href="pdtoa.3.html"><code>pdtoa(3)</code></a> </li>
775 <li> <a href="pgetline.3.html"><code>pgetline(3)</code></a> </li>
776 <li> <a href="pgetlinec.3.html"><code>pgetlinec(3)</code></a> </li>
777 <li> <a href="pgetlinex.3.html"><code>pgetlinex(3)</code></a> </li>
778 <li> <a href="pitoa.3.html"><code>pitoa(3)</code></a> </li>
779 <li> <a href="pjoin.3.html"><code>pjoin(3)</code></a> </li>
780 <li> <a href="pmatch.3.html"><code>pmatch(3)</code></a> </li>
781 <li> <a href="pmatchx.3.html"><code>pmatchx(3)</code></a> </li>
782 <li> <a href="pmemdup.3.html"><code>pmemdup(3)</code></a> </li>
783 <li> <a href="psort.3.html"><code>psort(3)</code></a> </li>
784 <li> <a href="psprintf.3.html"><code>psprintf(3)</code></a> </li>
785 <li> <a href="pstrcat.3.html"><code>pstrcat(3)</code></a> </li>
786 <li> <a href="pstrcsplit.3.html"><code>pstrcsplit(3)</code></a> </li>
787 <li> <a href="pstrdup.3.html"><code>pstrdup(3)</code></a> </li>
788 <li> <a href="pstrlwr.3.html"><code>pstrlwr(3)</code></a> </li>
789 <li> <a href="pstrncat.3.html"><code>pstrncat(3)</code></a> </li>
790 <li> <a href="pstrndup.3.html"><code>pstrndup(3)</code></a> </li>
791 <li> <a href="pstrresplit.3.html"><code>pstrresplit(3)</code></a> </li>
792 <li> <a href="pstrs.3.html"><code>pstrs(3)</code></a> </li>
793 <li> <a href="pstrsplit.3.html"><code>pstrsplit(3)</code></a> </li>
794 <li> <a href="pstrupr.3.html"><code>pstrupr(3)</code></a> </li>
795 <li> <a href="psubst.3.html"><code>psubst(3)</code></a> </li>
796 <li> <a href="psubstr.3.html"><code>psubstr(3)</code></a> </li>
797 <li> <a href="psubstx.3.html"><code>psubstx(3)</code></a> </li>
798 <li> <a href="ptrim.3.html"><code>ptrim(3)</code></a> </li>
799 <li> <a href="ptrimback.3.html"><code>ptrimback(3)</code></a> </li>
800 <li> <a href="ptrimfront.3.html"><code>ptrimfront(3)</code></a> </li>
801 <li> <a href="pvdtostr.3.html"><code>pvdtostr(3)</code></a> </li>
802 <li> <a href="pvector.3.html"><code>pvector(3)</code></a> </li>
803 <li> <a href="pvectora.3.html"><code>pvectora(3)</code></a> </li>
804 <li> <a href="pvitostr.3.html"><code>pvitostr(3)</code></a> </li>
805 <li> <a href="pvsprintf.3.html"><code>pvsprintf(3)</code></a> </li>
806 <li> <a href="pvxtostr.3.html"><code>pvxtostr(3)</code></a> </li>
807 <li> <a href="pxtoa.3.html"><code>pxtoa(3)</code></a> </li>
810 <h3>Matrix and vector math</h3>
813 <li> <a href="collision_moving_sphere_and_face.3.html"><code>collision_moving_sphere_and_face(3)</code></a> </li>
815 <li> <a href="face_translate_along_normal.3.html"><code>face_translate_along_normal(3)</code></a> </li>
816 <li> <a href="identity_matrix.3.html"><code>identity_matrix(3)</code></a> </li>
817 <li> <a href="make_identity_matrix.3.html"><code>make_identity_matrix(3)</code></a> </li>
818 <li> <a href="make_zero_vec.3.html"><code>make_zero_vec(3)</code></a> </li>
819 <li> <a href="new_identity_matrix.3.html"><code>new_identity_matrix(3)</code></a> </li>
820 <li> <a href="new_matrix.3.html"><code>new_matrix(3)</code></a> </li>
821 <li> <a href="new_subvector.3.html"><code>new_subvector(3)</code></a> </li>
822 <li> <a href="new_vec.3.html"><code>new_vec(3)</code></a> </li>
824 <li> <a href="new_zero_vec.3.html"><code>new_zero_vec(3)</code></a> </li>
825 <li> <a href="plane_coefficients.3.html"><code>plane_coefficients(3)</code></a> </li>
826 <li> <a href="plane_translate_along_normal.3.html"><code>plane_translate_along_normal(3)</code></a> </li>
828 <li> <a href="point_distance_to_face.3.html"><code>point_distance_to_face(3)</code></a> </li>
829 <li> <a href="point_distance_to_line.3.html"><code>point_distance_to_line(3)</code></a> </li>
830 <li> <a href="point_distance_to_line_segment.3.html"><code>point_distance_to_line_segment(3)</code></a> </li>
831 <li> <a href="point_distance_to_plane.3.html"><code>point_distance_to_plane(3)</code></a> </li>
832 <li> <a href="point_face_angle_sum.3.html"><code>point_face_angle_sum(3)</code></a> </li>
833 <li> <a href="point_is_inside_plane.3.html"><code>point_is_inside_plane(3)</code></a> </li>
834 <li> <a href="point_lies_in_face.3.html"><code>point_lies_in_face(3)</code></a> </li>
835 <li> <a href="vec_angle_between.3.html"><code>vec_angle_between(3)</code></a> </li>
836 <li> <a href="vec_dot_product.3.html"><code>vec_dot_product(3)</code></a> </li>
837 <li> <a href="vec_magnitude2d.3.html"><code>vec_magnitude2d(3)</code></a> </li>
838 <li> <a href="vec_magnitude.3.html"><code>vec_magnitude(3)</code></a> </li>
839 <li> <a href="vec_magnitude_in_direction.3.html"><code>vec_magnitude_in_direction(3)</code></a> </li>
840 <li> <a href="vec_normalize2d.3.html"><code>vec_normalize2d(3)</code></a> </li>
841 <li> <a href="vec_normalize.3.html"><code>vec_normalize(3)</code></a> </li>
842 <li> <a href="zero_vec.3.html"><code>zero_vec(3)</code></a> </li>
846 <address><a href="mailto:rich@annexia.org">Richard Jones</a></address>
847 <!-- Created: Wed May 1 19:36:16 BST 2002 -->
849 Last modified: Fri May 2 19:42:09 BST 2002