Add to git. master
authorRichard W.M. Jones <rjones@redhat.com>
Fri, 25 Apr 2014 10:38:47 +0000 (11:38 +0100)
committerRichard W.M. Jones <rjones@redhat.com>
Fri, 25 Apr 2014 10:38:47 +0000 (11:38 +0100)
187 files changed:
.cvsignore [new file with mode: 0644]
COPYING.LIB [new file with mode: 0644]
INSTALL [new file with mode: 0644]
Makefile+ [new file with mode: 0644]
README [new file with mode: 0644]
README.Solaris [new file with mode: 0644]
configure [new file with mode: 0755]
doc/Makefile [new file with mode: 0644]
doc/collision_moving_sphere_and_face.3.html [new file with mode: 0644]
doc/copy_hash.3.html [new file with mode: 0644]
doc/copy_sash.3.html [new file with mode: 0644]
doc/copy_shash.3.html [new file with mode: 0644]
doc/copy_vector.3.html [new file with mode: 0644]
doc/delete_pool.3.html [new file with mode: 0644]
doc/eg_join.c [new file with mode: 0644]
doc/eg_sash.c [new file with mode: 0644]
doc/eg_string.c [new file with mode: 0644]
doc/eg_vectorint.c [new file with mode: 0644]
doc/eg_vectorint2.c [new file with mode: 0644]
doc/face_translate_along_normal.3.html [new file with mode: 0644]
doc/global_pool.3.html [new file with mode: 0644]
doc/hash_erase.3.html [new file with mode: 0644]
doc/hash_exists.3.html [new file with mode: 0644]
doc/hash_get.3.html [new file with mode: 0644]
doc/hash_get_buckets_allocated.3.html [new file with mode: 0644]
doc/hash_get_buckets_used.3.html [new file with mode: 0644]
doc/hash_get_ptr.3.html [new file with mode: 0644]
doc/hash_insert.3.html [new file with mode: 0644]
doc/hash_keys.3.html [new file with mode: 0644]
doc/hash_keys_in_pool.3.html [new file with mode: 0644]
doc/hash_set_buckets_allocated.3.html [new file with mode: 0644]
doc/hash_size.3.html [new file with mode: 0644]
doc/hash_values.3.html [new file with mode: 0644]
doc/hash_values_in_pool.3.html [new file with mode: 0644]
doc/identity_matrix.3.html [new file with mode: 0644]
doc/index.html [new file with mode: 0644]
doc/make_identity_matrix.3.html [new file with mode: 0644]
doc/make_zero_vec.3.html [new file with mode: 0644]
doc/new_hash.3.html [new file with mode: 0644]
doc/new_identity_matrix.3.html [new file with mode: 0644]
doc/new_matrix.3.html [new file with mode: 0644]
doc/new_pool.3.html [new file with mode: 0644]
doc/new_sash.3.html [new file with mode: 0644]
doc/new_shash.3.html [new file with mode: 0644]
doc/new_subpool.3.html [new file with mode: 0644]
doc/new_subvector.3.html [new file with mode: 0644]
doc/new_vec.3.html [new file with mode: 0644]
doc/new_vector.3.html [new file with mode: 0644]
doc/new_zero_vec.3.html [new file with mode: 0644]
doc/pcalloc.3.html [new file with mode: 0644]
doc/pchomp.3.html [new file with mode: 0644]
doc/pchrs.3.html [new file with mode: 0644]
doc/pconcat.3.html [new file with mode: 0644]
doc/pdtoa.3.html [new file with mode: 0644]
doc/pgetline.3.html [new file with mode: 0644]
doc/pgetlinec.3.html [new file with mode: 0644]
doc/pgetlinex.3.html [new file with mode: 0644]
doc/pitoa.3.html [new file with mode: 0644]
doc/pjoin.3.html [new file with mode: 0644]
doc/plane_coefficients.3.html [new file with mode: 0644]
doc/plane_translate_along_normal.3.html [new file with mode: 0644]
doc/pmalloc.3.html [new file with mode: 0644]
doc/pmatch.3.html [new file with mode: 0644]
doc/pmatchx.3.html [new file with mode: 0644]
doc/pmemdup.3.html [new file with mode: 0644]
doc/point_distance_to_face.3.html [new file with mode: 0644]
doc/point_distance_to_line.3.html [new file with mode: 0644]
doc/point_distance_to_line_segment.3.html [new file with mode: 0644]
doc/point_distance_to_plane.3.html [new file with mode: 0644]
doc/point_face_angle_sum.3.html [new file with mode: 0644]
doc/point_is_inside_plane.3.html [new file with mode: 0644]
doc/point_lies_in_face.3.html [new file with mode: 0644]
doc/pool_get_stats.3.html [new file with mode: 0644]
doc/pool_register_cleanup_fn.3.html [new file with mode: 0644]
doc/pool_register_fd.3.html [new file with mode: 0644]
doc/pool_register_malloc.3.html [new file with mode: 0644]
doc/pool_set_bad_malloc_handler.3.html [new file with mode: 0644]
doc/prealloc.3.html [new file with mode: 0644]
doc/psort.3.html [new file with mode: 0644]
doc/psprintf.3.html [new file with mode: 0644]
doc/pstrcat.3.html [new file with mode: 0644]
doc/pstrcsplit.3.html [new file with mode: 0644]
doc/pstrdup.3.html [new file with mode: 0644]
doc/pstrlwr.3.html [new file with mode: 0644]
doc/pstrncat.3.html [new file with mode: 0644]
doc/pstrndup.3.html [new file with mode: 0644]
doc/pstrresplit.3.html [new file with mode: 0644]
doc/pstrs.3.html [new file with mode: 0644]
doc/pstrsplit.3.html [new file with mode: 0644]
doc/pstrupr.3.html [new file with mode: 0644]
doc/psubst.3.html [new file with mode: 0644]
doc/psubstr.3.html [new file with mode: 0644]
doc/psubstx.3.html [new file with mode: 0644]
doc/ptrim.3.html [new file with mode: 0644]
doc/ptrimback.3.html [new file with mode: 0644]
doc/ptrimfront.3.html [new file with mode: 0644]
doc/pvdtostr.3.html [new file with mode: 0644]
doc/pvector.3.html [new file with mode: 0644]
doc/pvectora.3.html [new file with mode: 0644]
doc/pvitostr.3.html [new file with mode: 0644]
doc/pvsprintf.3.html [new file with mode: 0644]
doc/pvxtostr.3.html [new file with mode: 0644]
doc/pxtoa.3.html [new file with mode: 0644]
doc/sash_erase.3.html [new file with mode: 0644]
doc/sash_exists.3.html [new file with mode: 0644]
doc/sash_get.3.html [new file with mode: 0644]
doc/sash_get_buckets_allocated.3.html [new file with mode: 0644]
doc/sash_get_buckets_used.3.html [new file with mode: 0644]
doc/sash_insert.3.html [new file with mode: 0644]
doc/sash_keys.3.html [new file with mode: 0644]
doc/sash_keys_in_pool.3.html [new file with mode: 0644]
doc/sash_set_buckets_allocated.3.html [new file with mode: 0644]
doc/sash_size.3.html [new file with mode: 0644]
doc/sash_values.3.html [new file with mode: 0644]
doc/sash_values_in_pool.3.html [new file with mode: 0644]
doc/shash_erase.3.html [new file with mode: 0644]
doc/shash_exists.3.html [new file with mode: 0644]
doc/shash_get.3.html [new file with mode: 0644]
doc/shash_get_buckets_allocated.3.html [new file with mode: 0644]
doc/shash_get_buckets_used.3.html [new file with mode: 0644]
doc/shash_get_ptr.3.html [new file with mode: 0644]
doc/shash_insert.3.html [new file with mode: 0644]
doc/shash_keys.3.html [new file with mode: 0644]
doc/shash_keys_in_pool.3.html [new file with mode: 0644]
doc/shash_set_buckets_allocated.3.html [new file with mode: 0644]
doc/shash_size.3.html [new file with mode: 0644]
doc/shash_values.3.html [new file with mode: 0644]
doc/shash_values_in_pool.3.html [new file with mode: 0644]
doc/vec_angle_between.3.html [new file with mode: 0644]
doc/vec_dot_product.3.html [new file with mode: 0644]
doc/vec_magnitude.3.html [new file with mode: 0644]
doc/vec_magnitude2d.3.html [new file with mode: 0644]
doc/vec_magnitude_in_direction.3.html [new file with mode: 0644]
doc/vec_normalize.3.html [new file with mode: 0644]
doc/vec_normalize2d.3.html [new file with mode: 0644]
doc/vector_allocated.3.html [new file with mode: 0644]
doc/vector_clear.3.html [new file with mode: 0644]
doc/vector_compare.3.html [new file with mode: 0644]
doc/vector_element_size.3.html [new file with mode: 0644]
doc/vector_erase.3.html [new file with mode: 0644]
doc/vector_erase_range.3.html [new file with mode: 0644]
doc/vector_fill.3.html [new file with mode: 0644]
doc/vector_get.3.html [new file with mode: 0644]
doc/vector_get_ptr.3.html [new file with mode: 0644]
doc/vector_grep.3.html [new file with mode: 0644]
doc/vector_grep_pool.3.html [new file with mode: 0644]
doc/vector_insert.3.html [new file with mode: 0644]
doc/vector_insert_array.3.html [new file with mode: 0644]
doc/vector_map.3.html [new file with mode: 0644]
doc/vector_map_pool.3.html [new file with mode: 0644]
doc/vector_pop_back.3.html [new file with mode: 0644]
doc/vector_pop_front.3.html [new file with mode: 0644]
doc/vector_push_back.3.html [new file with mode: 0644]
doc/vector_push_front.3.html [new file with mode: 0644]
doc/vector_reallocate.3.html [new file with mode: 0644]
doc/vector_replace.3.html [new file with mode: 0644]
doc/vector_replace_array.3.html [new file with mode: 0644]
doc/vector_reverse.3.html [new file with mode: 0644]
doc/vector_size.3.html [new file with mode: 0644]
doc/vector_sort.3.html [new file with mode: 0644]
doc/vector_swap.3.html [new file with mode: 0644]
doc/zero_vec.3.html [new file with mode: 0644]
hash.c [new file with mode: 0644]
hash.h [new file with mode: 0644]
matvec.c [new file with mode: 0644]
matvec.h [new file with mode: 0644]
pool.c [new file with mode: 0644]
pool.h [new file with mode: 0644]
pre.c [new file with mode: 0644]
pre.h [new file with mode: 0644]
pstring.c [new file with mode: 0644]
pstring.h [new file with mode: 0644]
test_hash.c [new file with mode: 0644]
test_matvec.c [new file with mode: 0644]
test_pool.c [new file with mode: 0644]
test_pre.c [new file with mode: 0644]
test_pstring.c [new file with mode: 0644]
test_sash.c [new file with mode: 0644]
test_shash.c [new file with mode: 0644]
test_tree.c [new file with mode: 0644]
test_vector.c [new file with mode: 0644]
trace/.cvsignore [new file with mode: 0644]
trace/curallocs.pl [new file with mode: 0755]
tree.c [new file with mode: 0644]
tree.h [new file with mode: 0644]
vector.c [new file with mode: 0644]
vector.h [new file with mode: 0644]

diff --git a/.cvsignore b/.cvsignore
new file mode 100644 (file)
index 0000000..1964f99
--- /dev/null
@@ -0,0 +1 @@
+build-*
\ No newline at end of file
diff --git a/COPYING.LIB b/COPYING.LIB
new file mode 100644 (file)
index 0000000..eb685a5
--- /dev/null
@@ -0,0 +1,481 @@
+                 GNU LIBRARY GENERAL PUBLIC LICENSE
+                      Version 2, June 1991
+
+ Copyright (C) 1991 Free Software Foundation, Inc.
+                    675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL.  It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Library General Public License, applies to some
+specially designated Free Software Foundation software, and to any
+other libraries whose authors decide to use it.  You can use it for
+your libraries, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if
+you distribute copies of the library, or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link a program with the library, you must provide
+complete object files to the recipients so that they can relink them
+with the library, after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  Our method of protecting your rights has two steps: (1) copyright
+the library, and (2) offer you this license which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  Also, for each distributor's protection, we want to make certain
+that everyone understands that there is no warranty for this free
+library.  If the library is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original
+version, so that any problems introduced by others will not reflect on
+the original authors' reputations.
+\f
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that companies distributing free
+software will individually obtain patent licenses, thus in effect
+transforming the program into proprietary software.  To prevent this,
+we have made it clear that any patent must be licensed for everyone's
+free use or not licensed at all.
+
+  Most GNU software, including some libraries, is covered by the ordinary
+GNU General Public License, which was designed for utility programs.  This
+license, the GNU Library General Public License, applies to certain
+designated libraries.  This license is quite different from the ordinary
+one; be sure to read it in full, and don't assume that anything in it is
+the same as in the ordinary license.
+
+  The reason we have a separate public license for some libraries is that
+they blur the distinction we usually make between modifying or adding to a
+program and simply using it.  Linking a program with a library, without
+changing the library, is in some sense simply using the library, and is
+analogous to running a utility program or application program.  However, in
+a textual and legal sense, the linked executable is a combined work, a
+derivative of the original library, and the ordinary General Public License
+treats it as such.
+
+  Because of this blurred distinction, using the ordinary General
+Public License for libraries did not effectively promote software
+sharing, because most developers did not use the libraries.  We
+concluded that weaker conditions might promote sharing better.
+
+  However, unrestricted linking of non-free programs would deprive the
+users of those programs of all benefit from the free status of the
+libraries themselves.  This Library General Public License is intended to
+permit developers of non-free programs to use free libraries, while
+preserving your freedom as a user of such programs to change the free
+libraries that are incorporated in them.  (We have not seen how to achieve
+this as regards changes in header files, but we have achieved it as regards
+changes in the actual functions of the Library.)  The hope is that this
+will lead to faster development of free libraries.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, while the latter only
+works together with the library.
+
+  Note that it is possible for a library to be covered by the ordinary
+General Public License rather than by this special one.
+\f
+                 GNU LIBRARY GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library which
+contains a notice placed by the copyright holder or other authorized
+party saying it may be distributed under the terms of this Library
+General Public License (also called "this License").  Each licensee is
+addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+\f
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+\f
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+  6. As an exception to the Sections above, you may also compile or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    c) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    d) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the source code distributed need not include anything that is normally
+distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+\f
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Library General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                           NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                    END OF TERMS AND CONDITIONS
+\f
+     Appendix: How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/INSTALL b/INSTALL
new file mode 100644 (file)
index 0000000..4710da2
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,30 @@
+Required packages
+-----------------
+
+Before installing c2lib, you need to make sure you have the following
+packages installed:
+
+cdoc           http://www.annexia.org/freeware/cdoc/
+make+          http://www.annexia.org/freeware/makeplus/
+pcre           http://www.pcre.org/
+
+Building and installing
+-----------------------
+
+./configure  [--prefix=/usr --sysconfdir=/etc]
+make+
+make+ test
+make+ install
+
+See the make+ documentation for additional targets (eg. building RPMs).
+
+Problems
+--------
+
+If the build fails, please examine the following files for clues:
+
+build-*/config.h
+build-*/config.mk
+build-*/config.log
+
+If you discover a bug, please contact the package author.
diff --git a/Makefile+ b/Makefile+
new file mode 100644 (file)
index 0000000..82f2b14
--- /dev/null
+++ b/Makefile+
@@ -0,0 +1,411 @@
+# -*- Makefile -*-
+#
+# This is a make+ file. Make+ is a set of scripts which enhance GNU
+# make and let you build RPMs, and other package types with just one
+# control file.  To build this package you will need to download make+
+# from this site: http://www.annexia.org/freeware/makeplus/
+
+PACKAGE                := c2lib
+VERSION_MAJOR  := 1
+VERSION_MINOR  := 4.2
+VERSION                := $(VERSION_MAJOR).$(VERSION_MINOR)
+
+SUMMARY                := A library of useful functions for C.
+COPYRIGHT      := GNU LGPL (see http://www.gnu.org/)
+AUTHOR         := Richard Jones <rich@annexia.org>
+
+define DESCRIPTION
+c2lib is a library of useful functions which augment those found in
+the standard libc. It contains a pool allocator, many string
+functions, STL-like vector and hash types and miscellaneous utilities.
+endef
+
+RPM_REQUIRES   := pcre >= 3.9
+RPM_GROUP      := Development/Libraries
+
+CFLAGS         += -Wall -Werror -g -O2 -D_GNU_SOURCE
+ifneq ($(shell uname), SunOS)
+# Avoid a warning about reordering system include paths.
+CFLAGS         += $(shell pcre-config --cflags)
+endif
+LIBS           += $(shell pcre-config --libs) -lm
+
+OBJS   := hash.o matvec.o pool.o pre.o pstring.o tree.o vector.o
+LOBJS  := $(OBJS:.o=.lo)
+HEADERS        := $(srcdir)/hash.h $(srcdir)/matvec.h \
+       $(srcdir)/pool.h $(srcdir)/pre.h $(srcdir)/pstring.h \
+       $(srcdir)/tree.h $(srcdir)/vector.h
+
+all:   static dynamic manpages syms
+
+# Configure the system.
+
+configure:
+       $(MP_CONFIGURE_START)
+       $(MP_REQUIRE_PROG) pcre-config
+       $(MP_CHECK_HEADERS) alloca.h assert.h ctype.h fcntl.h string.h unistd.h
+       $(MP_CHECK_FUNCS) vasprintf
+       $(MP_CONFIGURE_END)
+
+# Build the static library.
+
+static:        libc2lib.a
+
+libc2lib.a: $(OBJS)
+       $(MP_LINK_STATIC) $@ $^
+
+# Build the dynamic library.
+
+dynamic: libc2lib.so
+
+libc2lib.so: $(LOBJS)
+       $(MP_LINK_DYNAMIC) $@ $^ $(LIBS)
+
+# Build the manual pages.
+
+manpages: $(srcdir)/*.h
+       if cdoc; then \
+               rm -f *.3; \
+               cdoc \
+                       --author '$(AUTHOR)' \
+                       --license '$(COPYRIGHT)' \
+                       --version '$(PACKAGE)-$(VERSION)' \
+                       $^; \
+       fi
+
+# Build the symbols table.
+
+syms: libc2lib.syms
+
+libc2lib.syms: libc2lib.so
+       nm $< | sort | grep -i '^[0-9a-f]' | awk '{print $$1 " " $$3}' > $@
+
+# Test.
+
+test: test_hash test_matvec test_pool test_pre test_pstring test_sash \
+       test_shash test_tree test_vector
+       LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH $(MP_RUN_TESTS) $^
+
+test_hash: test_hash.o
+       $(CC) $(CFLAGS) $^ -o $@ -L. -lc2lib $(LIBS)
+test_matvec: test_matvec.o
+       $(CC) $(CFLAGS) $^ -o $@ -L. -lc2lib $(LIBS)
+test_pool: test_pool.o
+       $(CC) $(CFLAGS) $^ -o $@ $(LIBS)
+test_pre: test_pre.o
+       $(CC) $(CFLAGS) $^ -o $@ -L. -lc2lib $(LIBS)
+test_pstring: test_pstring.o
+       $(CC) $(CFLAGS) $^ -o $@ -L. -lc2lib $(LIBS)
+test_sash: test_sash.o
+       $(CC) $(CFLAGS) $^ -o $@ -L. -lc2lib $(LIBS)
+test_shash: test_shash.o
+       $(CC) $(CFLAGS) $^ -o $@ -L. -lc2lib $(LIBS)
+test_tree: test_tree.o
+       $(CC) $(CFLAGS) $^ -o $@ -L. -lc2lib $(LIBS)
+test_vector: test_vector.o
+       $(CC) $(CFLAGS) $^ -o $@ -L. -lc2lib $(LIBS)
+
+# Install.
+
+install:
+       install -d $(DESTDIR)$(libdir)
+       install -d $(DESTDIR)$(pkgincludedir)
+       install -d $(DESTDIR)$(man3dir)
+       install -d $(DESTDIR)$(datadir)/rws/symtabs/
+
+       $(MP_INSTALL_STATIC_LIB) libc2lib.a
+       $(MP_INSTALL_DYNAMIC_LIB) libc2lib.so
+       install -m 0644 $(HEADERS) $(DESTDIR)$(pkgincludedir)
+       install -m 0644 *.3        $(DESTDIR)$(man3dir)
+       install -m 0644 *.syms     $(DESTDIR)$(datadir)/rws/symtabs/
+
+force:
+
+define WEBSITE
+<% include page_header.msp %>
+
+    <h1>c2lib - a Perl/STL-like library of basics for C</h1>
+
+    <p>
+      c2lib is a library of basic tools for use by C
+      programmers. It contains features heavily influenced
+      by both Perl's string handling and C++'s Standard
+      Template Library (STL). The library has been designed
+      to be very easy to use and is fully documented in
+      manual pages.
+    </p>
+
+    <p>
+      <a href="doc/">There is extensive documentation and
+       a tutorial here.</a>
+    </p>
+
+    <h1>Download</h1>
+
+    <table border="1">
+      <tr>
+       <th> File </th>
+       <th> Format </th>
+       <th> Contents </th>
+      </tr>
+      <tr>
+       <td> <a href="$(PACKAGE)-$(VERSION).tar.gz">$(PACKAGE)-$(VERSION).tar.gz</a> </td>
+       <td> tar.gz </td>
+       <td> Latest source distribution </td>
+      </tr>
+      <tr>
+       <td> <a href="$(PACKAGE)-$(VERSION)-1.i686.rpm">$(PACKAGE)-$(VERSION)-1.i686.rpm</a> </td>
+       <td> i686 binary RPM </td>
+       <td> Binary development libraries, header files, man pages
+         for Red Hat Linux </td>
+      </tr>
+      <tr>
+       <td> <a href="$(PACKAGE)-$(VERSION)-1.src.rpm">$(PACKAGE)-$(VERSION)-1.src.rpm</a> </td>
+       <td> source RPM </td>
+       <td> Source files for Red Hat Linux </td>
+      </tr>
+    </table>
+
+    <p>
+     Dependencies:
+    </p>
+
+    <ul>
+      <li> You will need to install the <a href="http://www.pcre.org/">Perl
+         Compatible Regular Expressions (PCRE)</a> library.
+      <li> Since 1.3.0, c2lib requires the <a href="../makeplus/">make+</a>
+         build system.
+      <li> To rebuild the manual pages which come with the
+       package, you will also need to download
+       <a href="../cdoc/">cdoc</a>.
+    </ul>
+
+    <p>
+      <a href="/cgi-bin/autopatch.pl?dir=c2lib">Patches between versions
+       ...</a>
+    </p>
+
+    <h1>News</h1>
+
+<p>
+<b>Sat Mar 1 2003:</b>
+Created README and INSTALL files (thanks to David Chappell). Updated
+<code>Makefile+</code> to work with the new version of make+.
+<strong>NB: The RPMs were built on Debian and may not work on Red Hat
+Linux.</strong> </p>
+
+<p>
+<b>Sat Feb  8 17:00:47 GMT 2003:</b>
+Ported to Solaris, OpenBSD and FreeBSD (thanks to
+<a href="http://www.azazel.net/">Jeremy Sowden</a>
+and <a href="http://www.mondaymorning.org/">Richard Baker</a>
+for help and equipment). Don't link c2lib itself into the
+<code>test_pool</code> program. Link test programs correctly
+with <code>pcre</code>.
+</p>
+
+<p>
+<strong>Attn:</strong> Solaris
+has a library called <code>libc2</code>. I have had to rename this
+library to <code>libc2lib</code>, so you will need to link your
+programs against <code>-lc2lib</code>. I have also moved the
+header files into the <code>c2lib/<code> subdirectory of
+includedir, so you may need to specify <code>-I/usr/include/c2lib</code>
+when building.
+</p>
+
+<p>
+<b>Sat Dec  7 17:18:02 GMT 2002:</b> Updated to use the
+<a href="../makeplus/">make+</a> build system.
+</p>
+
+<p>
+<b>Mon Nov 25 09:31:37 GMT 2002:</b> Added symbols file for full
+symbol resolution in monolith.
+</p>
+
+  <p>
+    <b>Sun Nov 17 23:31:32 GMT 2002:</b> Debian packages. Added MSP files.
+    <code>pmalloc</code> now initialises memory to <code>0xefefefef</code>
+    so we can catch uninitialised memory problems. Further fixes
+    to compile on RH 7.3. Added <code>vector_push_back_vector</code> etc.
+  </p>
+
+    <p>
+      <b>Tue Oct 15 23:40:42 BST 2002:</b> Multiple bug fixes.
+    </p>
+
+    <p>
+      <b>Sun Oct 13 12:55:08 BST 2002:</b> Added <code>pmap</code>
+      and <code>pgrep</code> functions.
+    </p>
+
+    <p>
+      <b>Tue Oct 8 16:18:02 BST 2002:</b> Fix issues with building on
+      Red Hat Linux 7.3 (thanks to Adam Monsen). The supplied
+      RPM should now install on Red Hat Linux systems.
+    </p>
+
+    <p>
+      <b>Sun Oct  6 18:07:39 BST 2002:</b> Completely rewrote
+      the <code>pstr*split</code> functions so they produce the
+      same results as the Perl equivalents in all the corner
+      cases. Added <code>pstr*split2</code> functions (see
+      the manual pages).
+    </p>
+
+    <p>
+      <b>Sun Oct  6 13:00:39 BST 2002:</b> Added a <code>tree</code>
+      type (required by monolith). Removed the old <code>pmatch*</code> and
+      <code>psubst*</code> functions. These were badly thought
+      out and implemented. Replaced with <code>precomp</code>,
+      <code>prematch</code>, <code>presubst</code> functions
+      which are wrappers around the <a href="http://www.pcre.org/">Perl
+       Compatible Regular Expressions (PCRE)</a> library.
+      <code>pstrresplit</code> has also changed to use PCRE.
+    </p>
+
+    <p>
+      <b>Sat Sep  7 15:24:32 BST 2002:</b> Packages are
+      now available as i686 binary RPMs and source RPMs.
+    </p>
+
+    <h1>Old news and old versions</h1>
+
+    <p>
+      <b>Fri May  2 19:49:25 BST 2002</b>
+    </p>
+
+    <p>
+      <a href="c2lib-1.2.14.tar.gz">c2lib-1.2.14.tar.gz</a> released.
+      Added an extensive tutorial and online manual pages.
+    </p>
+
+    <p>
+      <b>Thu Jun 21 23:12:26 BST 2001</b>
+    </p>
+
+    <p>
+      <a href="c2lib-1.2.12.tar.gz">c2lib-1.2.12.tar.gz</a> released.
+      Fixed <code>psort</code> function and updated documentation.
+    </p>
+
+    <p>
+      <b>Fri Jun 15 15:40:35 BST 2001</b>
+    </p>
+
+    <p>
+      <a href="c2lib-1.2.11.tar.gz">c2lib-1.2.11.tar.gz</a> released.
+      Profiling support. Added <code>pstrncat</code>,
+      <code>psubst</code> and <code>psubstx</code> functions.
+      Fixed a memory leak and did rigorous memory leak
+      checking -- I\'m pretty sure there are none left now.
+      Removed arbitrary limit on number of substring
+      matches in <code>pmatch</code> function.
+      Documentation updates.
+    </p>
+
+    <p>
+      <b>Mon Apr  9 17:18:38 BST 2001</b>
+    </p>
+
+    <p>
+      <a href="c2lib-1.2.8.tar.gz">c2lib-1.2.8.tar.gz</a> released.
+      Documentation fixes.
+    </p>
+
+    <p>
+      <b>Wed Mar 28 14:25:42 BST 2001</b>
+    </p>
+
+    <p>
+      <a href="c2lib-1.2.7.tar.gz">c2lib-1.2.7.tar.gz</a> released.
+      Fixed a problem with calling <code>isspace</code> on
+      Solaris (thanks to Tomonori Manome again).
+    </p>
+
+    <p>
+      <b>Mon Mar 26 12:59:15 BST 2001</b>
+    </p>
+
+    <p>
+      <a href="c2lib-1.2.6.tar.gz">c2lib-1.2.6.tar.gz</a> released.
+      <code>pstrresplit</code> fixed.
+      <code>pvector</code> and <code>pvectora</code> functions
+      added: use these to quickly build vectors from lists of strings.
+      <code>ptrimfront</code>, <code>ptrimback</code> and <code>ptrim</code>
+      functions added for trimming whitespace from strings.
+      <code>pgetline*</code> and <code>pmatch*</code> functions
+      added which make it trivial to read in configuration files.
+      <code>new_subvector</code> added for creating sub-vectors
+      of existing vectors.
+      Some minor const-correctness changes.
+      Documentation updates.
+      Test suite updates.
+    </p>
+
+    <p>
+      <b>Mon Mar 19 11:40:34 GMT 2001</b>
+    </p>
+
+    <p>
+      <a href="c2lib-1.2.3.tar.gz">c2lib-1.2.3.tar.gz</a> released.
+      This adds the <i>shash</i> type: a mapping of strings
+      to anything (another specialized hash).
+      Port to Solaris/Intel and Solaris/Sparc (thanks to
+      Tomonori Manome for this).
+    </p>
+
+    <p>
+      <b>Mon Mar 12 12:12:49 GMT 2001</b>
+    </p>
+
+    <p>
+      <a href="c2lib-1.2.1.tar.gz">c2lib-1.2.1.tar.gz</a> released.
+      This fixes a bug in the way the library was calling
+      <code>pstrcat</code>. Upgrading is highly recommended.
+    </p>
+
+    <p>
+      <b>Fri Mar  9 17:26:45 GMT 2001</b>
+    </p>
+
+    <p>
+      <a href="c2lib-1.2.0.tar.gz">c2lib-1.2.0.tar.gz</a> released.
+      The pool allocator has been completely rewritten for this
+      release, and is much more efficient.
+    </p>
+
+    <p>
+      <b>Wed Mar  7 14:56:43 GMT 2001</b>
+    </p>
+
+    <p>
+      <a href="c2lib-1.1.12.tar.gz">c2lib-1.1.12.tar.gz</a> released.
+      Added <code>pchrs</code> and <code>pstrs</code> string
+      functions. Added <code>pvsprintf</code>. Changed
+      <code>psprintf</code> to make it much more memory efficient
+      (it uses <code>vasprintf(3)</code> if available).
+      Const-correctness fixes.
+    </p>
+
+    <p>
+      <b>Fri Feb 16 17:46:41 GMT 2001</b>
+    </p>
+
+    <p>
+      <a href="c2lib-1.1.10.tar.gz">c2lib-1.1.10.tar.gz</a> released.
+      All functions are documented in manual pages.
+    </p>
+
+<% include page_footer.msp %>
+endef
+
+upload_website:
+       scp $(PACKAGE)-$(VERSION).tar.gz $(PACKAGE)-$(VERSION)-1.*.rpm \
+       $(PACKAGE)-$(VERSION).bin.tar.gz \
+       10.0.0.248:annexia.org/freeware/$(PACKAGE)/
+       scp index.html \
+       10.0.0.248:annexia.org/freeware/$(PACKAGE)/index.msp
+
+.PHONY:        static dynamic manpages syms
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..bb9105d
--- /dev/null
+++ b/README
@@ -0,0 +1,6 @@
+This is c2lib from http://www.annexia.org/freeware/c2lib/
+  
+c2lib is a library of basic tools for use by C programmers. It contains
+features heavily influenced by both Perl's string handling and C++'s
+Standard Template Library (STL). The library has been designed to be very
+easy to use and is fully documented in manual pages.
diff --git a/README.Solaris b/README.Solaris
new file mode 100644 (file)
index 0000000..ddb7726
--- /dev/null
@@ -0,0 +1 @@
+Ported to Solaris 9 by RWMJ on 2003/02/02.
\ No newline at end of file
diff --git a/configure b/configure
new file mode 100755 (executable)
index 0000000..04d9db0
--- /dev/null
+++ b/configure
@@ -0,0 +1,66 @@
+#!/bin/sh -
+#
+# This is make+. Make+ is a set of scripts which enhance GNU make and
+# let you build RPMs, and other packages types with just one control
+# file. Read more at http://www.annexia.org/freeware/makeplus/
+#
+# The original author is Richard W.M. Jones <rich@annexia.org>.
+#
+# This software has been explicitly placed in the PUBLIC DOMAIN.  You
+# do not need any sort of license or agreement to use or copy this
+# software. You may also copyright this software yourself, and/or
+# relicense it under any terms you want, at any time and at no cost.
+# This allows you (among other things) to include this software with
+# other packages so that the user does not need to download and
+# install make+ separately.
+
+mp_options=""
+
+usage ()
+{
+    cat <<EOF
+./configure [--options]
+
+Installation directory options:
+  --prefix=PREFIX       Installation prefix [default: /usr/local]
+  --sysconfdir=SYSCONF  Installation prefix for configuration files
+                         [default: PREFIX/etc]
+  --localstatedir=STATE Installation prefix for writable files
+                         [default: PREFIX/var]
+
+Help options:
+  --help                Display this help and exit.
+  --print-mp-cmd        Display the make+ command and exit (use as final arg)
+EOF
+    exit 1
+}
+
+while [ $# -gt 0 ]; do
+    opt=$1 ; shift
+
+    case "$opt" in
+       --help)
+           usage
+           ;;
+       --print-mp-cmd)
+           echo "rm -f build-\*/config.mk"
+           echo "make+ $mp_options configure"
+           exit 0
+           ;;
+       --*prefix|--*dir)
+           opt=`echo $opt | sed 's/^--//'`
+           arg=$1 ; shift
+           mp_options="$mp_options $opt=$arg"
+           ;;
+       --*prefix=*|--*dir=*)
+           opt=`echo $opt | sed 's/^--//'`
+           mp_options="$mp_options $opt"
+           ;;
+       *)
+           mp_options="$mp_options $opt"
+           ;;
+    esac
+done
+
+rm -f build-*/config.mk
+make+ $mp_options configure
diff --git a/doc/Makefile b/doc/Makefile
new file mode 100644 (file)
index 0000000..cf76ffd
--- /dev/null
@@ -0,0 +1,11 @@
+ROFF   = groff -man -Thtml -U
+
+all:
+       @echo "Try the following target: man_pages"
+
+man_pages:
+       ln -s . man3
+       cp ../*.3 .
+       for f in *.3; echo $$f; do $(ROFF) $$f > $$f.html; done
+       rm *.3 man3
+       @echo "Now you need to import the HTML files into index.html"
diff --git a/doc/collision_moving_sphere_and_face.3.html b/doc/collision_moving_sphere_and_face.3.html
new file mode 100644 (file)
index 0000000..aa34dfb
--- /dev/null
@@ -0,0 +1,105 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>collision_moving_sphere_and_face</title>
+</head>
+<body>
+
+<h1 align=center>collision_moving_sphere_and_face</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#RETURNS">RETURNS</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:56:38 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+collision_moving_sphere_and_face - detect collision between a moving sphere and a fixed face</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;matvec.h&gt;
+
+int collision_moving_sphere_and_face (const float *p0, const float *p1, float radius, const float *points, int nr_points, const float *plane, float *collision_point);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+This function detects collisions between a sphere which is
+moving at constant speed along a linear path and a fixed
+bounded convex polygon (&quot;face&quot;).</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The centre of the sphere moves from point <b>p0</b> to point
+<b>p1</b>. The sphere has radius <b>radius</b>.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The face is described by the list of bounding points, and
+the plane coefficients of the plane of the face (you may
+pass <b>plane</b> as <b>NULL</b> in which case the function
+works out the plane coefficients for you, although this is
+generally less efficient).</td></table>
+<a name="RETURNS"></a>
+<h2>RETURNS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+If there was a collision, this function returns true and
+sets the collision point in <b>collision_point</b>. Note
+that the collision point is the position of the centre of
+the sphere at the point of collision, NOT the place where
+the sphere touches the face. If there was no collision, this
+function returns false.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/copy_hash.3.html b/doc/copy_hash.3.html
new file mode 100644 (file)
index 0000000..68eb9fb
--- /dev/null
@@ -0,0 +1,74 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>copy_hash</title>
+</head>
+<body>
+
+<h1 align=center>copy_hash</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:56:40 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+copy_hash - copy a hash</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+hash copy_hash (pool, hash);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Copy a hash into a new pool. This function copies the keys
+and values, but if keys and values are pointers, then it
+does not perform a 'deep' copy.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/copy_sash.3.html b/doc/copy_sash.3.html
new file mode 100644 (file)
index 0000000..34af6c0
--- /dev/null
@@ -0,0 +1,74 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>copy_sash</title>
+</head>
+<body>
+
+<h1 align=center>copy_sash</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:56:41 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+copy_sash - copy a sash</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+sash copy_sash (pool, sash);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Copy a sash into a new pool. This function copies the keys
+and values, but if keys and values are pointers, then it
+does not perform a 'deep' copy.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/copy_shash.3.html b/doc/copy_shash.3.html
new file mode 100644 (file)
index 0000000..cb8c430
--- /dev/null
@@ -0,0 +1,74 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>copy_shash</title>
+</head>
+<body>
+
+<h1 align=center>copy_shash</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:56:42 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+copy_shash - copy a shash</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+shash copy_shash (pool, shash);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Copy a shash into a new pool. This function copies the keys
+and values, but if keys and values are pointers, then it
+does not perform a 'deep' copy.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/copy_vector.3.html b/doc/copy_vector.3.html
new file mode 100644 (file)
index 0000000..e96798e
--- /dev/null
@@ -0,0 +1,85 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>copy_vector</title>
+</head>
+<body>
+
+<h1 align=center>copy_vector</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:56:43 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+copy_vector, new_subvector - copy a vector</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;vector.h&gt;
+
+vector copy_vector (pool, vector v);
+vector new_subvector (pool, vector v, int i, int j);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Copy a vector <b>v</b> into pool <b>pool</b>. If the vector
+contains pointers, then this function will not copy the
+pointed-to data as well: you will need to copy this yourself
+if appropriate.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>new_subvector</b> creates a copy of part of an existing
+vector. The new vector contains the <b>j-i</b> elements of
+the old vector starting at element number <b>i</b> and
+finishing at element number <b>j-1</b>.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/delete_pool.3.html b/doc/delete_pool.3.html
new file mode 100644 (file)
index 0000000..86f8412
--- /dev/null
@@ -0,0 +1,74 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>delete_pool</title>
+</head>
+<body>
+
+<h1 align=center>delete_pool</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:56:44 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+delete_pool - delete a pool</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pool.h&gt;
+
+void delete_pool (pool);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Delete a pool or subpool. This also deletes any subpools
+that the pool may own (and recursively subpools of those
+subpools, etc.)</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/eg_join.c b/doc/eg_join.c
new file mode 100644 (file)
index 0000000..5592193
--- /dev/null
@@ -0,0 +1,11 @@
+#include <pool.h>
+#include <pstring.h>
+
+const char *strings[] = { "John", "Paul", "George", "Ringo" };
+
+main ()
+{
+  pool pool = global_pool;
+  vector v = pvectora (pool, strings, 4);
+  printf ("Introducing the Beatles: %s\n", pjoin (pool, v, ", "));
+}
diff --git a/doc/eg_sash.c b/doc/eg_sash.c
new file mode 100644 (file)
index 0000000..0bddc9d
--- /dev/null
@@ -0,0 +1,31 @@
+#include <stdio.h>
+#include <hash.h>
+#include <pstring.h>
+
+main ()
+{
+  pool pool = global_pool;
+  sash h = new_sash (pool);
+  char *fruit;
+  const char *color;
+
+  sash_insert (h, "banana", "yellow");
+  sash_insert (h, "orange", "orange");
+  sash_insert (h, "apple", "red");
+  sash_insert (h, "kiwi", "green");
+  sash_insert (h, "grapefruit", "yellow");
+  sash_insert (h, "pear", "green");
+  sash_insert (h, "tomato", "red");
+  sash_insert (h, "tangerine", "orange");
+
+  for (;;)
+    {
+      printf ("Please type in the name of a fruit: ");
+      fruit = pgetline (pool, stdin, 0);
+
+      if (sash_get (h, fruit, color))
+       printf ("The color of that fruit is %s.\n", color);
+      else
+       printf ("Sorry, I don't know anything about that fruit.\n");
+    }
+}
diff --git a/doc/eg_string.c b/doc/eg_string.c
new file mode 100644 (file)
index 0000000..5a18995
--- /dev/null
@@ -0,0 +1,37 @@
+#include <assert.h>
+#include <pstring.h>
+
+char *given_name = "Richard";
+char *family_name = "Jones";
+char *email_address = "rich@annexia.org";
+
+main ()
+{
+  pool pool = global_pool;
+  char *email, *s;
+  vector v;
+
+  email =
+    psprintf (pool, "%s %s <%s>", given_name, family_name, email_address);
+
+  printf ("full email address is: %s\n", email);
+
+  v = pstrcsplit (pool, email, ' ');
+
+  printf ("split email into %d components\n", vector_size (v));
+
+  vector_get (v, 0, s);
+  printf ("first component is: %s\n", s);
+  assert (strcmp (s, given_name) == 0);
+
+  vector_get (v, 1, s);
+  printf ("second component is: %s\n", s);
+  assert (strcmp (s, family_name) == 0);
+
+  vector_get (v, 2, s);
+  printf ("third component is: %s\n", s);
+  s = pstrdup (pool, s);
+  s++;
+  s[strlen(s)-1] = '\0';
+  assert (strcmp (s, email_address) == 0);
+}
diff --git a/doc/eg_vectorint.c b/doc/eg_vectorint.c
new file mode 100644 (file)
index 0000000..d279d9e
--- /dev/null
@@ -0,0 +1,25 @@
+#include <pool.h>
+#include <vector.h>
+#include <pstring.h>
+
+main ()
+{
+  pool pool = global_pool;
+  vector v = new_vector (pool, int);
+  int i, prod = 1;
+
+  for (i = 1; i <= 10; ++i)
+    vector_push_back (v, i);
+
+  for (i = 0; i < vector_size (v); ++i)
+    {
+      int elem;
+
+      vector_get (v, i, elem);
+      prod *= elem;
+    }
+
+  printf ("product of integers: %s = %d\n",
+         pjoin (pool, pvitostr (pool, v), " * "),
+         prod);
+}
diff --git a/doc/eg_vectorint2.c b/doc/eg_vectorint2.c
new file mode 100644 (file)
index 0000000..e8b96b8
--- /dev/null
@@ -0,0 +1,33 @@
+#include <pool.h>
+#include <vector.h>
+#include <pstring.h>
+
+main ()
+{
+  pool pool = global_pool;
+  vector v = pvector (pool,
+                     "a", "b", "c", "d", "e",
+                     "f", "g", "h", "i", "j", 0);
+  const char *X = "X";
+
+  printf ("Original vector contains: %s\n",
+         pjoin (pool, v, ", "));
+
+  vector_erase_range (v, 3, 6);
+
+  printf ("After erasing elements 3-5, vector contains: %s\n",
+         pjoin (pool, v, ", "));
+
+  vector_insert (v, 3, X);
+  vector_insert (v, 4, X);
+  vector_insert (v, 5, X);
+
+  printf ("After inserting 3 Xs, vector contains: %s\n",
+         pjoin (pool, v, ", "));
+
+  vector_clear (v);
+  vector_fill (v, X, 10);
+
+  printf ("After clearing and inserting 10 Xs, vector contains: %s\n",
+         pjoin (pool, v, ", "));
+}
diff --git a/doc/face_translate_along_normal.3.html b/doc/face_translate_along_normal.3.html
new file mode 100644 (file)
index 0000000..c589481
--- /dev/null
@@ -0,0 +1,94 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>plane_translate_along_normal</title>
+</head>
+<body>
+
+<h1 align=center>plane_translate_along_normal</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+<a href="#SEE ALSO">SEE ALSO</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:56:45 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+plane_translate_along_normal, face_translate_along_normal - translate a plane or face some distance in the direction of the normal</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;matvec.h&gt;
+
+void plane_translate_along_normal (const float *plane, float distance, float *new_plane);
+void face_translate_along_normal (const float *points, int nr_points, const float *plane, float distance, float *new_points, float *new_plane);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Given an existing <b>plane</b> (expressed as plane
+coefficients), produce a new plane <b>new_plane</b> which
+has been translated by <b>distance</b> units along the
+direction of the normal. The new plane is also returned as
+plane coefficients.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>face_translate_along_normal</b> is similar, except that
+it also translates a list of points by the same
+distance.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<a name="SEE ALSO"></a>
+<h2>SEE ALSO</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>plane_coefficients(3)</b>.</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/global_pool.3.html b/doc/global_pool.3.html
new file mode 100644 (file)
index 0000000..c845c55
--- /dev/null
@@ -0,0 +1,76 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>global_pool</title>
+</head>
+<body>
+
+<h1 align=center>global_pool</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:56:46 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+global_pool - the global pool for global allocations</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pool.h&gt;
+
+pool global_pool;
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+This is the global pool which is allocated before
+<b>main()</b> is called and deleted automatically upon
+program exit. Items allocated on this pool cannot be deleted
+until the program ends, and so it is a good idea not to
+allocate short-lived items here.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/hash_erase.3.html b/doc/hash_erase.3.html
new file mode 100644 (file)
index 0000000..a364f56
--- /dev/null
@@ -0,0 +1,74 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>hash_erase</title>
+</head>
+<body>
+
+<h1 align=center>hash_erase</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:56:47 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+hash_erase, _hash_erase - erase a key from a hash</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+#define hash_erase(h,key) _hash_erase((h),&amp;(key))
+int _hash_erase (hash, const void *key);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Erase <b>key</b> from the hash. If an element was erased,
+this returns true, else this returns false.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/hash_exists.3.html b/doc/hash_exists.3.html
new file mode 100644 (file)
index 0000000..b22537f
--- /dev/null
@@ -0,0 +1,97 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>hash_get</title>
+</head>
+<body>
+
+<h1 align=center>hash_get</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:56:48 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+hash_get, _hash_get, hash_get_ptr, _hash_get_ptr, hash_exists - look up in a hash</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+#define hash_get(h,key,value) _hash_get ((h), &amp;(key), &amp;(value))
+int _hash_get (hash, const void *key, void *value);
+#define hash_get_ptr(h,key,ptr) _hash_get_ptr ((h), &amp;(key), &amp;(ptr))
+int _hash_get_ptr (hash, const void *key, void **ptr);
+#define hash_exists(h,key) _hash_get_ptr ((h), &amp;(key), 0)
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Get the <b>value</b> associated with key <b>key</b> and
+return true. If there is no <b>value</b> associated with
+<b>key</b>, this returns false and <b>value</b> is left
+unchanged.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The <b>*_ptr</b> variants return a pointer rather than
+copying out the entire value object. The pointer is
+typically only valid for a short period of time.
+Particularly if you insert or remove elements from the hash,
+this pointer may become invalid.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>hash_exists</b> simply tests whether or not <b>key</b>
+exists in the hash. If so, it returns true, otherwise
+false.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/hash_get.3.html b/doc/hash_get.3.html
new file mode 100644 (file)
index 0000000..6f6ce73
--- /dev/null
@@ -0,0 +1,97 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>hash_get</title>
+</head>
+<body>
+
+<h1 align=center>hash_get</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:56:49 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+hash_get, _hash_get, hash_get_ptr, _hash_get_ptr, hash_exists - look up in a hash</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+#define hash_get(h,key,value) _hash_get ((h), &amp;(key), &amp;(value))
+int _hash_get (hash, const void *key, void *value);
+#define hash_get_ptr(h,key,ptr) _hash_get_ptr ((h), &amp;(key), &amp;(ptr))
+int _hash_get_ptr (hash, const void *key, void **ptr);
+#define hash_exists(h,key) _hash_get_ptr ((h), &amp;(key), 0)
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Get the <b>value</b> associated with key <b>key</b> and
+return true. If there is no <b>value</b> associated with
+<b>key</b>, this returns false and <b>value</b> is left
+unchanged.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The <b>*_ptr</b> variants return a pointer rather than
+copying out the entire value object. The pointer is
+typically only valid for a short period of time.
+Particularly if you insert or remove elements from the hash,
+this pointer may become invalid.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>hash_exists</b> simply tests whether or not <b>key</b>
+exists in the hash. If so, it returns true, otherwise
+false.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/hash_get_buckets_allocated.3.html b/doc/hash_get_buckets_allocated.3.html
new file mode 100644 (file)
index 0000000..aa3003a
--- /dev/null
@@ -0,0 +1,76 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>hash_get_buckets_used</title>
+</head>
+<body>
+
+<h1 align=center>hash_get_buckets_used</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:56:50 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+hash_get_buckets_used, hash_get_buckets_allocated - return the number of buckets in a hash</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+int hash_get_buckets_used (hash);
+int hash_get_buckets_allocated (hash);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Return the number of hash buckets used and allocated. The
+number of buckets allocated is always a power of 2. See also
+<b>hash_set_buckets_allocated</b> to change the number used
+in the hash.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/hash_get_buckets_used.3.html b/doc/hash_get_buckets_used.3.html
new file mode 100644 (file)
index 0000000..d6bd884
--- /dev/null
@@ -0,0 +1,76 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>hash_get_buckets_used</title>
+</head>
+<body>
+
+<h1 align=center>hash_get_buckets_used</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:56:51 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+hash_get_buckets_used, hash_get_buckets_allocated - return the number of buckets in a hash</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+int hash_get_buckets_used (hash);
+int hash_get_buckets_allocated (hash);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Return the number of hash buckets used and allocated. The
+number of buckets allocated is always a power of 2. See also
+<b>hash_set_buckets_allocated</b> to change the number used
+in the hash.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/hash_get_ptr.3.html b/doc/hash_get_ptr.3.html
new file mode 100644 (file)
index 0000000..18881e4
--- /dev/null
@@ -0,0 +1,97 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>hash_get</title>
+</head>
+<body>
+
+<h1 align=center>hash_get</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:56:52 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+hash_get, _hash_get, hash_get_ptr, _hash_get_ptr, hash_exists - look up in a hash</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+#define hash_get(h,key,value) _hash_get ((h), &amp;(key), &amp;(value))
+int _hash_get (hash, const void *key, void *value);
+#define hash_get_ptr(h,key,ptr) _hash_get_ptr ((h), &amp;(key), &amp;(ptr))
+int _hash_get_ptr (hash, const void *key, void **ptr);
+#define hash_exists(h,key) _hash_get_ptr ((h), &amp;(key), 0)
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Get the <b>value</b> associated with key <b>key</b> and
+return true. If there is no <b>value</b> associated with
+<b>key</b>, this returns false and <b>value</b> is left
+unchanged.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The <b>*_ptr</b> variants return a pointer rather than
+copying out the entire value object. The pointer is
+typically only valid for a short period of time.
+Particularly if you insert or remove elements from the hash,
+this pointer may become invalid.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>hash_exists</b> simply tests whether or not <b>key</b>
+exists in the hash. If so, it returns true, otherwise
+false.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/hash_insert.3.html b/doc/hash_insert.3.html
new file mode 100644 (file)
index 0000000..9fc4042
--- /dev/null
@@ -0,0 +1,77 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>hash_insert</title>
+</head>
+<body>
+
+<h1 align=center>hash_insert</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:56:53 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+hash_insert, _hash_insert - insert a (key, value) pair into a hash</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+#define hash_insert(h,key,value) _hash_insert((h),&amp;(key),&amp;(value))
+int _hash_insert (hash, const void *key, const void *value);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Insert an element (<b>key</b>, <b>value</b>) into the hash.
+If <b>key</b> already exists in the hash, then the existing
+value is replaced by <b>value</b> and the function returns
+true. If there was no previous <b>key</b> in the hash then
+this function returns false.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/hash_keys.3.html b/doc/hash_keys.3.html
new file mode 100644 (file)
index 0000000..b0ee4e7
--- /dev/null
@@ -0,0 +1,78 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>hash_keys</title>
+</head>
+<body>
+
+<h1 align=center>hash_keys</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:56:54 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+hash_keys, hash_keys_in_pool, hash_values, hash_values_in_pool - return a vector of the keys or values in a hash</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+vector hash_keys (hash);
+vector hash_keys_in_pool (hash, pool);
+vector hash_values (hash);
+vector hash_values_in_pool (hash, pool);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Return a vector containing all the keys or values of hash.
+The <b>*_in_pool</b> variants allow you to allocate the
+vector in another pool (the default is to allocate the
+vector in the same pool as the hash).</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/hash_keys_in_pool.3.html b/doc/hash_keys_in_pool.3.html
new file mode 100644 (file)
index 0000000..dde4dcb
--- /dev/null
@@ -0,0 +1,78 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>hash_keys</title>
+</head>
+<body>
+
+<h1 align=center>hash_keys</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:56:56 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+hash_keys, hash_keys_in_pool, hash_values, hash_values_in_pool - return a vector of the keys or values in a hash</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+vector hash_keys (hash);
+vector hash_keys_in_pool (hash, pool);
+vector hash_values (hash);
+vector hash_values_in_pool (hash, pool);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Return a vector containing all the keys or values of hash.
+The <b>*_in_pool</b> variants allow you to allocate the
+vector in another pool (the default is to allocate the
+vector in the same pool as the hash).</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/hash_set_buckets_allocated.3.html b/doc/hash_set_buckets_allocated.3.html
new file mode 100644 (file)
index 0000000..eed8862
--- /dev/null
@@ -0,0 +1,76 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>hash_set_buckets_allocated</title>
+</head>
+<body>
+
+<h1 align=center>hash_set_buckets_allocated</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:56:57 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+hash_set_buckets_allocated - set the number of buckets</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+void hash_set_buckets_allocated (hash, int);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Set the number of buckets allocated. You may ONLY do this
+when you have just created the hash and before you have
+inserted any elements. Otherwise the results are undefined
+(and probably bad). The number of buckets MUST be a power of
+2.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/hash_size.3.html b/doc/hash_size.3.html
new file mode 100644 (file)
index 0000000..2348617
--- /dev/null
@@ -0,0 +1,73 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>hash_size</title>
+</head>
+<body>
+
+<h1 align=center>hash_size</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:56:58 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+hash_size - return the number of (key, value) pairs in a hash</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+int hash_size (hash);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Count the number of (key, value) pairs in the
+hash.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/hash_values.3.html b/doc/hash_values.3.html
new file mode 100644 (file)
index 0000000..52392d2
--- /dev/null
@@ -0,0 +1,78 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>hash_keys</title>
+</head>
+<body>
+
+<h1 align=center>hash_keys</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:56:59 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+hash_keys, hash_keys_in_pool, hash_values, hash_values_in_pool - return a vector of the keys or values in a hash</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+vector hash_keys (hash);
+vector hash_keys_in_pool (hash, pool);
+vector hash_values (hash);
+vector hash_values_in_pool (hash, pool);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Return a vector containing all the keys or values of hash.
+The <b>*_in_pool</b> variants allow you to allocate the
+vector in another pool (the default is to allocate the
+vector in the same pool as the hash).</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/hash_values_in_pool.3.html b/doc/hash_values_in_pool.3.html
new file mode 100644 (file)
index 0000000..19d71b8
--- /dev/null
@@ -0,0 +1,78 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>hash_keys</title>
+</head>
+<body>
+
+<h1 align=center>hash_keys</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:00 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+hash_keys, hash_keys_in_pool, hash_values, hash_values_in_pool - return a vector of the keys or values in a hash</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+vector hash_keys (hash);
+vector hash_keys_in_pool (hash, pool);
+vector hash_values (hash);
+vector hash_values_in_pool (hash, pool);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Return a vector containing all the keys or values of hash.
+The <b>*_in_pool</b> variants allow you to allocate the
+vector in another pool (the default is to allocate the
+vector in the same pool as the hash).</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/identity_matrix.3.html b/doc/identity_matrix.3.html
new file mode 100644 (file)
index 0000000..f194699
--- /dev/null
@@ -0,0 +1,105 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>identity_matrix</title>
+</head>
+<body>
+
+<h1 align=center>identity_matrix</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+<a href="#SEE ALSO">SEE ALSO</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:01 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+identity_matrix, zero_vec, new_identity_matrix, new_zero_vec, make_identity_matrix, make_zero_vec - identity matrix and zero vector</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;matvec.h&gt;
+
+float identity_matrix[16];
+float zero_vec[4];
+float *new_identity_matrix (pool);
+float *new_zero_vec (pool);
+#define make_identity_matrix(m) memcpy (m, identity_matrix, sizeof(float)*16);
+#define make_zero_vec(v) memcpy (v, zero_vec, sizeof (float) * 4);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The <b>identity_matrix</b> variable contains a read-only
+copy of the identity matrix. The <b>zero_vec</b> variable
+contains a read-only copy of the zero vector.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Use <b>new_identity_matrix</b> to allocate a new identity
+matrix variable in <b>pool</b>. Use <b>new_zero_vec</b> to
+similarly allocate a new zero vector.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Use <b>make_identity_matrix</b> to copy the identity matrix
+over an existing matrix <b>m</b>. Use <b>make_zero_vec</b>
+to similarly copy the zero vector over an existing vector
+<b>v</b>.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<a name="SEE ALSO"></a>
+<h2>SEE ALSO</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>new_matrix(3)</b>, <b>new_vec(3)</b>.</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/index.html b/doc/index.html
new file mode 100644 (file)
index 0000000..4c3113c
--- /dev/null
@@ -0,0 +1,852 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+  <head>
+    <title>c2lib documentation index</title>
+    <style type="text/css"><!--
+      h1 {
+      text-align: center;
+      }
+      pre {
+      background-color: #eeeeff;
+      }
+      code {
+      color: green;
+      font-weight: bold;
+      }
+      --></style>
+  </head>
+
+  <body bgcolor="#ffffff">
+    <h1>c2lib documentation index</h1>
+
+    <p>
+      <code>c2lib</code> is a library of basic tools for use by C
+      programmers. It contains features heavily influenced by
+      both Perl's string handling and C++'s Standard Template
+      Library (STL).
+    </p>
+
+    <p>
+      The primary aims of <code>c2lib</code> are:
+    </p>
+
+    <ul>
+      <li> Be very simple to use.
+      <li> Provide rich abstract data types (ADTs) for C programmers
+       to use.
+      <li> Provide some of the advantages of Perl with only
+       around a factor of 2-3 code-size expansion over Perl itself.
+      <li> Retain most of the efficiency advantages of C.
+      <li> Remain compatible with existing libc functions (particularly
+       existing string and regular expression functions).
+      <li> Clean, fully documented API.
+    </ul>
+
+    <h2>Tutorial and programming examples</h2>
+
+    <h3>Join a list of strings and print</h3>
+
+<pre>
+   #include &lt;pool.h&gt;
+   #include &lt;pstring.h&gt;
+  
+   const char *strings[] = { "John", "Paul", "George", "Ringo" };
+5 
+   main ()
+   {
+     pool pool = global_pool;
+     vector v = pvectora (pool, strings, 4);
+10   printf ("Introducing the Beatles: %s\n", pjoin (pool, v, ", "));
+   }
+</pre>
+
+    <p>
+      When run, this program prints:
+    </p>
+
+<pre>
+Introducing the Beatles: John, Paul, George, Ringo
+</pre>
+
+    <p>
+      Compare this to the equivalent Perl code:
+    </p>
+
+<pre>
+#!/usr/bin/perl
+
+printf "Introducing the Beatles: %s\n",
+    join(", ", "John", "Paul", "George", "Ringo");
+</pre>
+
+    <p>
+      The <code>pjoin(3)</code> function on line 10 is
+      equivalent to the plain <code>join</code> function
+      in Perl. It takes a list of strings and joins them
+      with a separator string (in this case <code>", "</code>),
+      and creates a new string which is returned and printed.
+    </p>
+
+    <p>
+      The <code>pvectora(3)</code> function (line 9) takes a normal C
+      array of strings and converts it into a <code>c2lib</code>
+      <code>vector</code>. You will find out more about
+      <code>vector</code>s later.
+    </p>
+
+    <p>
+      In this case all our allocations are done in a standard
+      pool which is created automatically before <code>main</code> is
+      called and deleted after <code>main</code> returns. This pool is
+      called <code>global_pool(3)</code>. You will find out
+      more about <code>pool</code>s below.
+    </p>
+
+    <p>
+      Notice that, as with most <code>c2lib</code> programs, there is
+      no need to explicitly deallocate (free) objects once you
+      have finished using them. Almost all of the time, objects
+      are freed automatically for you by the system.
+    </p>
+
+    <h3>A vector of integers</h3>
+
+<pre>
+   #include &lt;pool.h&gt;
+   #include &lt;vector.h&gt;
+   #include &lt;pstring.h&gt;
+   
+5  main ()
+   {
+     pool pool = global_pool;
+     vector v = new_vector (pool, int);
+     int i, prod = 1;
+10 
+     for (i = 1; i &lt;= 10; ++i)
+       vector_push_back (v, i);
+   
+     for (i = 0; i &lt; vector_size (v); ++i)
+15     {
+         int elem;
+   
+         vector_get (v, i, elem);
+         prod *= elem;
+20     }
+   
+     printf ("product of integers: %s = %d\n",
+            pjoin (pool, pvitostr (pool, v), " * "),
+            prod);
+25 }
+</pre>
+
+    <p>
+      When run:
+    </p>
+
+<pre>
+product of integers: 1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 = 3628800
+</pre>
+
+    <p>
+      The call to <code>new_vector(3)</code> on line 8 creates a new
+      vector object (abstract data type). In this case the vector is
+      allocated in the global pool and you have told it that each
+      element of the vector will be of type <code>int</code>. Vectors
+      are arrays which automatically expand when you push elements
+      onto them. This vector behaves very much like a C++ STL
+      <code>vector&lt;int&gt;</code> or a Perl array.
+    </p>
+
+    <p>
+      On lines 11-12, we push the numbers 1 through to 10 into
+      the vector. The <code>vector_push_back(3)</code> function
+      pushes an element onto the end of the vector. There are
+      also <code>vector_pop_back(3)</code> (removes and returns the
+      last element of a vector), <code>vector_push_front(3)</code>
+      and <code>vector_pop_front(3)</code> operations.
+    </p>
+
+    <p>
+      Lines 14-20 show the general pattern for iterating over
+      the elements in a vector. The call to <code>vector_get</code>
+      (line 18) returns the <code>i</code>th element of vector <code>v</code>
+      into variable <code>elem</code>.
+    </p>
+
+    <p>
+      Finally lines 22-24 print out the result. We use the
+      <code>pjoin(3)</code> function again to join the numbers
+      with the string <code>" * "</code> between each pair.
+      Also note the use of the strange <code>pvitostr(3)</code>
+      function. <code>pjoin(3)</code> is expecting a vector
+      of strings (ie. a vector of <code>char *</code>), but
+      we have a vector of <code>int</code>, which is
+      incompatible. The <code>pvitostr(3)</code> function
+      promotes a vector of integers into a vector of strings.
+    </p>
+
+    <p>
+      The <code>c2lib</code> library stores vectors as arrays and
+      reallocates them using <code>prealloc(3)</code> whenever it
+      needs to expand them. This means that certain operations on
+      vectors are efficient, and some other operations are less
+      efficient. Getting an element of a vector or replacing an
+      element in the middle of a vector are both fast O(1) operations,
+      equivalent to the ordinary C index ([]) operator.
+      <code>vector_push_back(3)</code> and
+      <code>vector_pop_back(3)</code> are also fast.  However
+      <code>vector_push_front(3)</code> and
+      <code>vector_pop_front(3)</code> are O(n) operations because
+      they require the library to shift up all the elements in the
+      array by one place. Normally however if your vectors are very
+      short (say, fewer than 100 elements), the speed difference will
+      not be noticable, whereas the productivity gains from using
+      vectors over hand-rolled linked lists or other structures will
+      be large. The <code>vector</code> type also allows you
+      to insert and remove elements in the middle of the array,
+      as shown in the next example below:
+    </p>
+
+<pre>
+   #include &lt;pool.h&gt;
+   #include &lt;vector.h&gt;
+   #include &lt;pstring.h&gt;
+   
+5  main ()
+   {
+     pool pool = global_pool;
+     vector v = pvector (pool,
+                        "a", "b", "c", "d", "e",
+10                      "f", "g", "h", "i", "j", 0);
+     const char *X = "X";
+   
+     printf ("Original vector contains: %s\n",
+         pjoin (pool, v, ", "));
+15 
+     vector_erase_range (v, 3, 6);
+   
+     printf ("After erasing elements 3-5, vector contains: %s\n",
+            pjoin (pool, v, ", "));
+20 
+     vector_insert (v, 3, X);
+     vector_insert (v, 4, X);
+     vector_insert (v, 5, X);
+   
+25   printf ("After inserting 3 Xs, vector contains: %s\n",
+            pjoin (pool, v, ", "));
+
+     vector_clear (v);
+     vector_fill (v, X, 10);
+30 
+     printf ("After clearing and inserting 10 Xs, vector contains: %s\n",
+            pjoin (pool, v, ", "));
+   }
+</pre>
+
+    <p>
+      When run:
+    </p>
+
+<pre>
+Original vector contains: a, b, c, d, e, f, g, h, i, j
+After erasing elements 3-5, vector contains: a, b, c, g, h, i, j
+After inserting 3 Xs, vector contains: a, b, c, X, X, X, g, h, i, j
+After clearing and inserting 10 Xs, vector contains: X, X, X, X, X, X, X, X, X, X
+</pre>
+
+    <p>
+      This example demonstrates the following functions:
+    </p>
+
+    <ul>
+      <li> <code>vector_erase_range(3)</code> which is used
+       to erase a range of elements from the middle of
+       a vector.
+      <li> <code>vector_insert(3)</code> which is used to
+       insert single elements into a vector.
+      <li> <code>vector_clear(3)</code> which completely
+       clears the vector - removing all elements.
+      <li> <code>vector_fill(3)</code> which fills a vector
+       with identical elements.
+    </ul>
+
+    <p>
+      For more information, see the respective manual pages.
+    </p>
+
+    <p>
+      You can store just about anything in a vector: strings,
+      pointers, wide integers, complex structures, etc.  If you do
+      want to directly store large objects in a vector, you must
+      remember that the vector type actually copies those objects into
+      and out of the vector each time you insert, push, get, pop and
+      so on. For some large structures, you may want to store a
+      pointer instead (in fact with strings you have no choice: you
+      are always storing a pointer in the vector itself).
+    </p>
+
+    <h3>Strings are just <code>char *</code></h3>
+
+    <p>
+      <code>c2lib</code> doesn't have a fancy string type.
+      Instead we just use plain old <code>char *</code>. This
+      is possible because pools (see below) mean that we don't
+      need to worry about when to copy or deallocate specific
+      objects.
+    </p>
+
+    <p>
+      The great benefit of using plain <code>char *</code>
+      for strings is that we can continue to use the
+      familiar libc functions such as <code>strcmp(3)</code>,
+      <code>strcpy(3)</code>, <code>strlen(3)</code>, <code>printf(3)</code>
+      and so on, as in the next example.
+    </p>
+
+<pre>
+   #include &lt;assert.h&gt;
+   #include &lt;pstring.h&gt;
+   
+   char *given_name = "Richard";
+5  char *family_name = "Jones";
+   char *email_address = "rich@annexia.org";
+   
+   main ()
+   {
+10   pool pool = global_pool;
+     char *email, *s;
+     vector v;
+   
+     email =
+15     psprintf (pool, "%s %s &lt;%s&gt;", given_name, family_name, email_address);
+   
+     printf ("full email address is: %s\n", email);
+   
+     v = pstrcsplit (pool, email, ' ');
+20 
+     printf ("split email into %d components\n", vector_size (v));
+   
+     vector_get (v, 0, s);
+     printf ("first component is: %s\n", s);
+25   assert (strcmp (s, given_name) == 0);
+   
+     vector_get (v, 1, s);
+     printf ("second component is: %s\n", s);
+     assert (strcmp (s, family_name) == 0);
+30 
+     vector_get (v, 2, s);
+     printf ("third component is: %s\n", s);
+     s = pstrdup (pool, s);
+     s++;
+35   s[strlen(s)-1] = '\0';
+     assert (strcmp (s, email_address) == 0);
+   }
+</pre>
+
+    <p>
+      When run:
+    </p>
+
+<pre>
+full email address is: Richard Jones &lt;rich@annexia.org&gt;
+split email into 3 components
+first component is: Richard
+second component is: Jones
+third component is: &lt;rich@annexia.org&gt;
+</pre>
+
+    <p>
+      Line 15 demonstrates the <code>psprintf(3)</code> function
+      which is like the ordinary <code>sprintf(3)</code>,
+      but is (a) safe, and (b) allocates the string in the
+      pool provided, ensuring that it will be safely deallocated
+      later.
+    </p>
+
+    <p>
+      The <code>pstrcsplit(3)</code> function is similar to the
+      Perl <code>split</code>. It takes a string and splits it
+      into a vector of strings, in this case on the space
+      character. There are also other functions for splitting
+      on a string or on a regular expression.
+    </p>
+
+    <p>
+      The final part of the code, lines 21-36, prints out
+      the components of the split string. The <code>vector_get(3)</code>
+      function is used to pull the strings out of the vector object.
+    </p>
+
+    <p>
+      Notice on line 33 that before we remove the beginning
+      and end &lt; ... &gt; from around the email address,
+      we first duplicate the string using <code>pstrdup(3)</code>.
+      In this case it is not strictly necessary to duplicate
+      the string <code>s</code> because we know that
+      <code>pstrcsplit(3)</code> actually allocates new
+      copies of the strings in the vector which it returns.
+      However in general this is good practice because
+      otherwise we would be modifying the contents of the
+      original vector <code>v</code>.
+    </p>
+
+    <h3>Hashes</h3>
+
+    <p>
+      Hashes give you all the power of Perl's "%" hashes. In
+      fact the way they work is very similar (but more powerful:
+      unlike Perl's hashes the key does not need to be a string).
+    </p>
+
+    <p>
+      In <code>c2lib</code> there are three flavors of hash.
+      However they all work in essentially the same way, and
+      all have exactly the same functionality. The reason for
+      having the three flavors is just to work around an obscure
+      problem with the ANSI C specification!
+    </p>
+
+    <p>
+      The three flavors are:
+    </p>
+
+    <table>
+      <tr>
+       <th> hash </th>
+       <td> A hash of any non-string type to any non-string type. </td>
+      </tr>
+      <tr>
+       <th> sash </th>
+       <td> A hash of <code>char *</code> to <code>char *</code>. </td>
+      </tr>
+      <tr>
+       <th> shash </th>
+       <td> A hash of <code>char *</code> to any non-string type. </td>
+      </tr>
+    </table>
+
+    <p>
+      As with vectors, the phrase "any non-string type" can
+      be simple integers or chars, pointers, or complex large
+      structures if you wish.
+    </p>
+
+    <p>
+      Here is a short program showing you how to use a
+      sash (but note that the same functions are available
+      for all of the other flavors):
+    </p>
+
+<pre>
+   #include &lt;stdio.h&gt;
+   #include &lt;hash.h&gt;
+   #include &lt;pstring.h&gt;
+   
+5  main ()
+   {
+     pool pool = global_pool;
+     sash h = new_sash (pool);
+     char *fruit;
+10   const char *color;
+   
+     sash_insert (h, "banana", "yellow");
+     sash_insert (h, "orange", "orange");
+     sash_insert (h, "apple", "red");
+15   sash_insert (h, "kiwi", "green");
+     sash_insert (h, "grapefruit", "yellow");
+     sash_insert (h, "pear", "green");
+     sash_insert (h, "tomato", "red");
+     sash_insert (h, "tangerine", "orange");
+20 
+     for (;;)
+       {
+         printf ("Please type in the name of a fruit: ");
+         fruit = pgetline (pool, stdin, 0);
+25 
+         if (sash_get (h, fruit, color))
+       printf ("The color of that fruit is %s.\n", color);
+         else
+       printf ("Sorry, I don't know anything about that fruit.\n");
+30     }
+   }
+</pre>
+
+    <p>
+      When run:
+    </p>
+
+<pre>
+Please type in the name of a fruit: <b>orange</b>
+The color of that fruit is orange.
+Please type in the name of a fruit: <b>apple</b>
+The color of that fruit is red.
+Please type in the name of a fruit: <b>dragon fruit</b>
+Sorry, I don't know anything about that fruit.
+</pre>
+
+    <p>
+      The sash is allocated on line 8 using the <code>new_sash(3)</code>
+      function.
+    </p>
+
+    <p>
+      We populate the sash using the simple <code>sash_insert(3)</code>
+      functions (lines 12-19).
+    </p>
+
+    <p>
+      The <code>sash_get(3)</code> function retrieves a value
+      (<code>color</code>) from
+      the sash using the key given (<code>fruit</code>). It
+      returns true if a value was found, or false if there
+      was no matching key.
+    </p>
+
+    <p>
+      There are many potentially powerful functions available
+      for manipulating hashes, sashes and shashes (below,
+      <code>*</code> stands for either "h", "s" or "sh"):
+    </p>
+
+    <ul>
+      <li> <code>*ash_exists(3)</code> tells you if a key
+       exists. It is equivalent to the Perl <code>exists</code>
+       function.
+      <li> <code>*ash_erase(3)</code> removes a key. It
+       is equivalent to the Perl <code>delete</code> function.
+      <li> <code>*ash_keys(3)</code> returns all of the
+       keys of a hash in a vector. It is equivalent to the
+       Perl <code>keys</code> function.
+      <li> <code>*ash_values(3)</code> returns all of the
+       values of a hash in a vector. It is equivalent to the
+       Perl <code>values</code> function.
+      <li> <code>*ash_size(3)</code> counts the number of keys.
+    </ul>
+
+    <h3>Advanced used of pools</h3>
+
+    <p>
+      So far we have only touched upon pools, and it may not
+      be clear in the examples above why they don't in fact
+      leak memory. There appears to be no deallocation being
+      done, which is quite counter-intuitive to most C programmers!
+    </p>
+
+    <p>
+      Pools are collections of related objects (where an
+      "object" is some sort of memory allocation).
+    </p>
+
+    <p>
+      In C you are normally responsible for allocating and
+      deallocating every single object, like so:
+    </p>
+
+<pre>
+p = malloc (size);
+
+/* ... use p ... */
+
+free (p);
+</pre>
+
+    <p>
+      However in <code>c2lib</code> we first allocate a pool,
+      then use <code>pmalloc(3)</code> and <code>prealloc(3)</code>
+      to allocate lots of related objects in the pool.
+      At the end of the program, all of the objects can be
+      deleted in one go just by calling <code>delete_pool(3)</code>.
+    </p>
+
+    <p>
+      There is one special pool, called <code>global_pool(3)</code>.
+      This pool is created for you before <code>main</code> is
+      called, and it is deleted for you after <code>main</code>
+      returns (or if <code>exit(3)</code> is called). You don't
+      ever need to worry about deallocating <code>global_pool(3)</code>
+      (in fact, if you try to, your program might core dump).
+    </p>
+
+    <p>
+      Thus most short programs like the ones above should just
+      allocate all objects in <code>global_pool(3)</code>, and
+      never need to worry about deallocating the objects or
+      the pool.
+    </p>
+
+    <p>
+      For larger programs, and programs that are expected to run for a
+      long time like servers, you will need to learn about pools.
+    </p>
+
+    <p>
+      Pools are organised in a hierarchy. This means that you often
+      allocate one pool <i>inside</i> another pool. Here is a
+      common pattern:
+    </p>
+
+<pre>
+main ()
+{
+  /* ... use global_pool for allocations here ... */
+
+  for (;;) /* for each request: */
+    {
+      pool pool = new_subpool (global_pool);
+
+      /* ... process the request using pool ... */
+
+      delete_pool (pool);
+    }
+}
+</pre>
+
+    <p>
+      <code>pool</code> is created as a subpool of
+      <code>global_pool(3)</code> for the duration of
+      the request. At the end of the request the pool
+      (and therefore all objects inside it) is deallocated.
+    </p>
+
+    <p>
+      The advantage of creating <code>pool</code> as a
+      subpool of <code>global_pool(3)</code> is that if
+      the request processing code calls <code>exit(3)</code>
+      in the middle of the request, then <code>global_pool(3)</code>
+      will be deallocated in the normal way and as a consequence
+      of this <code>pool</code> will also be properly deallocated.
+    </p>
+
+    <p>
+      You can also use <code>new_pool(3)</code> to create a
+      completely new top-level pool. There are some rare
+      circumstances when you will need to do this, but
+      generally you should avoid creating pools which are
+      not subpools. If in doubt, always create subpools of
+      <code>global_pool(3)</code> or of the pool immediately
+      "above" you.
+    </p>
+
+    <p>
+      Pools don't just store memory allocations. You can attach
+      other types of objects to pools, or trigger functions which
+      are run when the pool is deallocated. <code>pool_register_fd(3)</code>
+      attaches a file descriptor to a pool, meaning that the file
+      descriptor is closed when the pool is deleted (note
+      however that there is no way to unattach a file descriptor
+      from a pool, so don't go and call <code>close(3)</code>
+      on the file descriptor once you've attached it to
+      a pool. <code>pool_register_cleanup_fn(3)</code>
+      registers your own clean-up function which is called
+      when the pool is deleted. Although you should
+      normally use <code>pmalloc(3)</code> and/or
+      <code>prealloc(3)</code> to allocate objects directly
+      in pools, you can also allocate them normally using
+      <code>malloc(3)</code> and attach them to the pool
+      using <code>pool_register_malloc(3)</code>. The object
+      will be freed up automatically when the pool is
+      deallocated.
+    </p>
+
+    <p>
+      Pools become very important when writing multi-threaded
+      servers using the <code>pthrlib</code> library. Each
+      thread processes a single request or command. A pool
+      is created for every thread, and is automatically
+      deleted when the thread exits. This assumes of course
+      that threads (and hence requests) are short-lived, which
+      is a reasonable assumption for most HTTP-like services.
+    </p>
+
+    <h2>Links to manual pages</h2>
+
+    <p>
+      (These manual pages are not always up to date. For the
+      latest documentation, always consult the manual pages
+      supplied with the latest <code>c2lib</code> package!)
+    </p>
+
+    <h3>Pools</h3>
+
+    <ul>
+      <li> <a href="delete_pool.3.html"><code>delete_pool(3)</code></a> </li>
+      <li> <a href="global_pool.3.html"><code>global_pool(3)</code></a> </li>
+      <li> <a href="new_pool.3.html"><code>new_pool(3)</code></a> </li>
+      <li> <a href="new_subpool.3.html"><code>new_subpool(3)</code></a> </li>
+      <li> <a href="pcalloc.3.html"><code>pcalloc(3)</code></a> </li>
+      <li> <a href="pmalloc.3.html"><code>pmalloc(3)</code></a> </li>
+      <li> <a href="pool_get_stats.3.html"><code>pool_get_stats(3)</code></a> </li>
+      <li> <a href="pool_register_cleanup_fn.3.html"><code>pool_register_cleanup_fn(3)</code></a> </li>
+      <li> <a href="pool_register_fd.3.html"><code>pool_register_fd(3)</code></a> </li>
+      <li> <a href="pool_register_malloc.3.html"><code>pool_register_malloc(3)</code></a> </li>
+      <li> <a href="pool_set_bad_malloc_handler.3.html"><code>pool_set_bad_malloc_handler(3)</code></a> </li>
+      <li> <a href="prealloc.3.html"><code>prealloc(3)</code></a> </li>
+    </ul>
+
+    <h3>Vectors</h3>
+
+    <ul>
+      <li> <a href="copy_vector.3.html"><code>copy_vector(3)</code></a> </li>
+      <li> <a href="new_vector.3.html"><code>new_vector(3)</code></a> </li>
+      <li> <a href="vector_allocated.3.html"><code>vector_allocated(3)</code></a> </li>
+      <li> <a href="vector_clear.3.html"><code>vector_clear(3)</code></a> </li>
+      <li> <a href="vector_compare.3.html"><code>vector_compare(3)</code></a> </li>
+      <li> <a href="vector_element_size.3.html"><code>vector_element_size(3)</code></a> </li>
+      <li> <a href="vector_erase.3.html"><code>vector_erase(3)</code></a> </li>
+      <li> <a href="vector_erase_range.3.html"><code>vector_erase_range(3)</code></a> </li>
+      <li> <a href="vector_fill.3.html"><code>vector_fill(3)</code></a> </li>
+      <li> <a href="vector_get.3.html"><code>vector_get(3)</code></a> </li>
+      <li> <a href="vector_get_ptr.3.html"><code>vector_get_ptr(3)</code></a> </li>
+      <li> <a href="vector_grep.3.html"><code>vector_grep(3)</code></a> </li>
+      <li> <a href="vector_grep_pool.3.html"><code>vector_grep_pool(3)</code></a> </li>
+      <li> <a href="vector_insert.3.html"><code>vector_insert(3)</code></a> </li>
+      <li> <a href="vector_insert_array.3.html"><code>vector_insert_array(3)</code></a> </li>
+      <li> <a href="vector_map.3.html"><code>vector_map(3)</code></a> </li>
+      <li> <a href="vector_map_pool.3.html"><code>vector_map_pool(3)</code></a> </li>
+      <li> <a href="vector_pop_back.3.html"><code>vector_pop_back(3)</code></a> </li>
+      <li> <a href="vector_pop_front.3.html"><code>vector_pop_front(3)</code></a> </li>
+      <li> <a href="vector_push_back.3.html"><code>vector_push_back(3)</code></a> </li>
+      <li> <a href="vector_push_front.3.html"><code>vector_push_front(3)</code></a> </li>
+      <li> <a href="vector_reallocate.3.html"><code>vector_reallocate(3)</code></a> </li>
+      <li> <a href="vector_replace.3.html"><code>vector_replace(3)</code></a> </li>
+      <li> <a href="vector_replace_array.3.html"><code>vector_replace_array(3)</code></a> </li>
+      <li> <a href="vector_reverse.3.html"><code>vector_reverse(3)</code></a> </li>
+      <li> <a href="vector_size.3.html"><code>vector_size(3)</code></a> </li>
+      <li> <a href="vector_sort.3.html"><code>vector_sort(3)</code></a> </li>
+      <li> <a href="vector_swap.3.html"><code>vector_swap(3)</code></a> </li>
+    </ul>
+
+    <h3>Hashes</h3>
+
+    <ul>
+      <li> <a href="copy_hash.3.html"><code>copy_hash(3)</code></a> </li>
+      <li> <a href="copy_sash.3.html"><code>copy_sash(3)</code></a> </li>
+      <li> <a href="copy_shash.3.html"><code>copy_shash(3)</code></a> </li>
+      <li> <a href="hash_erase.3.html"><code>hash_erase(3)</code></a> </li>
+      <li> <a href="hash_exists.3.html"><code>hash_exists(3)</code></a> </li>
+      <li> <a href="hash_get.3.html"><code>hash_get(3)</code></a> </li>
+      <li> <a href="hash_get_buckets_allocated.3.html"><code>hash_get_buckets_allocated(3)</code></a> </li>
+      <li> <a href="hash_get_buckets_used.3.html"><code>hash_get_buckets_used(3)</code></a> </li>
+      <li> <a href="hash_get_ptr.3.html"><code>hash_get_ptr(3)</code></a> </li>
+      <li> <a href="hash_insert.3.html"><code>hash_insert(3)</code></a> </li>
+      <li> <a href="hash_keys.3.html"><code>hash_keys(3)</code></a> </li>
+      <li> <a href="hash_keys_in_pool.3.html"><code>hash_keys_in_pool(3)</code></a> </li>
+      <li> <a href="hash_set_buckets_allocated.3.html"><code>hash_set_buckets_allocated(3)</code></a> </li>
+      <li> <a href="hash_size.3.html"><code>hash_size(3)</code></a> </li>
+      <li> <a href="hash_values.3.html"><code>hash_values(3)</code></a> </li>
+      <li> <a href="hash_values_in_pool.3.html"><code>hash_values_in_pool(3)</code></a> </li>
+      <li> <a href="new_hash.3.html"><code>new_hash(3)</code></a> </li>
+      <li> <a href="new_sash.3.html"><code>new_sash(3)</code></a> </li>
+      <li> <a href="new_shash.3.html"><code>new_shash(3)</code></a> </li>
+      <li> <a href="sash_erase.3.html"><code>sash_erase(3)</code></a> </li>
+      <li> <a href="sash_exists.3.html"><code>sash_exists(3)</code></a> </li>
+      <li> <a href="sash_get.3.html"><code>sash_get(3)</code></a> </li>
+      <li> <a href="sash_get_buckets_allocated.3.html"><code>sash_get_buckets_allocated(3)</code></a> </li>
+      <li> <a href="sash_get_buckets_used.3.html"><code>sash_get_buckets_used(3)</code></a> </li>
+      <li> <a href="sash_insert.3.html"><code>sash_insert(3)</code></a> </li>
+      <li> <a href="sash_keys.3.html"><code>sash_keys(3)</code></a> </li>
+      <li> <a href="sash_keys_in_pool.3.html"><code>sash_keys_in_pool(3)</code></a> </li>
+      <li> <a href="sash_set_buckets_allocated.3.html"><code>sash_set_buckets_allocated(3)</code></a> </li>
+      <li> <a href="sash_size.3.html"><code>sash_size(3)</code></a> </li>
+      <li> <a href="sash_values.3.html"><code>sash_values(3)</code></a> </li>
+      <li> <a href="sash_values_in_pool.3.html"><code>sash_values_in_pool(3)</code></a> </li>
+      <li> <a href="shash_erase.3.html"><code>shash_erase(3)</code></a> </li>
+      <li> <a href="shash_exists.3.html"><code>shash_exists(3)</code></a> </li>
+      <li> <a href="shash_get.3.html"><code>shash_get(3)</code></a> </li>
+      <li> <a href="shash_get_buckets_allocated.3.html"><code>shash_get_buckets_allocated(3)</code></a> </li>
+      <li> <a href="shash_get_buckets_used.3.html"><code>shash_get_buckets_used(3)</code></a> </li>
+      <li> <a href="shash_get_ptr.3.html"><code>shash_get_ptr(3)</code></a> </li>
+      <li> <a href="shash_insert.3.html"><code>shash_insert(3)</code></a> </li>
+      <li> <a href="shash_keys.3.html"><code>shash_keys(3)</code></a> </li>
+      <li> <a href="shash_keys_in_pool.3.html"><code>shash_keys_in_pool(3)</code></a> </li>
+      <li> <a href="shash_set_buckets_allocated.3.html"><code>shash_set_buckets_allocated(3)</code></a> </li>
+      <li> <a href="shash_size.3.html"><code>shash_size(3)</code></a> </li>
+      <li> <a href="shash_values.3.html"><code>shash_values(3)</code></a> </li>
+      <li> <a href="shash_values_in_pool.3.html"><code>shash_values_in_pool(3)</code></a> </li>
+    </ul>
+
+    <h3>Strings and miscellaneous</h3>
+
+    <ul>
+      <li> <a href="pchomp.3.html"><code>pchomp(3)</code></a> </li>
+      <li> <a href="pchrs.3.html"><code>pchrs(3)</code></a> </li>
+      <li> <a href="pconcat.3.html"><code>pconcat(3)</code></a> </li>
+      <li> <a href="pdtoa.3.html"><code>pdtoa(3)</code></a> </li>
+      <li> <a href="pgetline.3.html"><code>pgetline(3)</code></a> </li>
+      <li> <a href="pgetlinec.3.html"><code>pgetlinec(3)</code></a> </li>
+      <li> <a href="pgetlinex.3.html"><code>pgetlinex(3)</code></a> </li>
+      <li> <a href="pitoa.3.html"><code>pitoa(3)</code></a> </li>
+      <li> <a href="pjoin.3.html"><code>pjoin(3)</code></a> </li>
+      <li> <a href="pmatch.3.html"><code>pmatch(3)</code></a> </li>
+      <li> <a href="pmatchx.3.html"><code>pmatchx(3)</code></a> </li>
+      <li> <a href="pmemdup.3.html"><code>pmemdup(3)</code></a> </li>
+      <li> <a href="psort.3.html"><code>psort(3)</code></a> </li>
+      <li> <a href="psprintf.3.html"><code>psprintf(3)</code></a> </li>
+      <li> <a href="pstrcat.3.html"><code>pstrcat(3)</code></a> </li>
+      <li> <a href="pstrcsplit.3.html"><code>pstrcsplit(3)</code></a> </li>
+      <li> <a href="pstrdup.3.html"><code>pstrdup(3)</code></a> </li>
+      <li> <a href="pstrlwr.3.html"><code>pstrlwr(3)</code></a> </li>
+      <li> <a href="pstrncat.3.html"><code>pstrncat(3)</code></a> </li>
+      <li> <a href="pstrndup.3.html"><code>pstrndup(3)</code></a> </li>
+      <li> <a href="pstrresplit.3.html"><code>pstrresplit(3)</code></a> </li>
+      <li> <a href="pstrs.3.html"><code>pstrs(3)</code></a> </li>
+      <li> <a href="pstrsplit.3.html"><code>pstrsplit(3)</code></a> </li>
+      <li> <a href="pstrupr.3.html"><code>pstrupr(3)</code></a> </li>
+      <li> <a href="psubst.3.html"><code>psubst(3)</code></a> </li>
+      <li> <a href="psubstr.3.html"><code>psubstr(3)</code></a> </li>
+      <li> <a href="psubstx.3.html"><code>psubstx(3)</code></a> </li>
+      <li> <a href="ptrim.3.html"><code>ptrim(3)</code></a> </li>
+      <li> <a href="ptrimback.3.html"><code>ptrimback(3)</code></a> </li>
+      <li> <a href="ptrimfront.3.html"><code>ptrimfront(3)</code></a> </li>
+      <li> <a href="pvdtostr.3.html"><code>pvdtostr(3)</code></a> </li>
+      <li> <a href="pvector.3.html"><code>pvector(3)</code></a> </li>
+      <li> <a href="pvectora.3.html"><code>pvectora(3)</code></a> </li>
+      <li> <a href="pvitostr.3.html"><code>pvitostr(3)</code></a> </li>
+      <li> <a href="pvsprintf.3.html"><code>pvsprintf(3)</code></a> </li>
+      <li> <a href="pvxtostr.3.html"><code>pvxtostr(3)</code></a> </li>
+      <li> <a href="pxtoa.3.html"><code>pxtoa(3)</code></a> </li>
+    </ul>
+
+    <h3>Matrix and vector math</h3>
+
+    <ul>
+      <li> <a href="collision_moving_sphere_and_face.3.html"><code>collision_moving_sphere_and_face(3)</code></a> </li>
+
+      <li> <a href="face_translate_along_normal.3.html"><code>face_translate_along_normal(3)</code></a> </li>
+      <li> <a href="identity_matrix.3.html"><code>identity_matrix(3)</code></a> </li>
+      <li> <a href="make_identity_matrix.3.html"><code>make_identity_matrix(3)</code></a> </li>
+      <li> <a href="make_zero_vec.3.html"><code>make_zero_vec(3)</code></a> </li>
+      <li> <a href="new_identity_matrix.3.html"><code>new_identity_matrix(3)</code></a> </li>
+      <li> <a href="new_matrix.3.html"><code>new_matrix(3)</code></a> </li>
+      <li> <a href="new_subvector.3.html"><code>new_subvector(3)</code></a> </li>
+      <li> <a href="new_vec.3.html"><code>new_vec(3)</code></a> </li>
+
+      <li> <a href="new_zero_vec.3.html"><code>new_zero_vec(3)</code></a> </li>
+      <li> <a href="plane_coefficients.3.html"><code>plane_coefficients(3)</code></a> </li>
+      <li> <a href="plane_translate_along_normal.3.html"><code>plane_translate_along_normal(3)</code></a> </li>
+
+      <li> <a href="point_distance_to_face.3.html"><code>point_distance_to_face(3)</code></a> </li>
+      <li> <a href="point_distance_to_line.3.html"><code>point_distance_to_line(3)</code></a> </li>
+      <li> <a href="point_distance_to_line_segment.3.html"><code>point_distance_to_line_segment(3)</code></a> </li>
+      <li> <a href="point_distance_to_plane.3.html"><code>point_distance_to_plane(3)</code></a> </li>
+      <li> <a href="point_face_angle_sum.3.html"><code>point_face_angle_sum(3)</code></a> </li>
+      <li> <a href="point_is_inside_plane.3.html"><code>point_is_inside_plane(3)</code></a> </li>
+      <li> <a href="point_lies_in_face.3.html"><code>point_lies_in_face(3)</code></a> </li>
+      <li> <a href="vec_angle_between.3.html"><code>vec_angle_between(3)</code></a> </li>
+      <li> <a href="vec_dot_product.3.html"><code>vec_dot_product(3)</code></a> </li>
+      <li> <a href="vec_magnitude2d.3.html"><code>vec_magnitude2d(3)</code></a> </li>
+      <li> <a href="vec_magnitude.3.html"><code>vec_magnitude(3)</code></a> </li>
+      <li> <a href="vec_magnitude_in_direction.3.html"><code>vec_magnitude_in_direction(3)</code></a> </li>
+      <li> <a href="vec_normalize2d.3.html"><code>vec_normalize2d(3)</code></a> </li>
+      <li> <a href="vec_normalize.3.html"><code>vec_normalize(3)</code></a> </li>
+      <li> <a href="zero_vec.3.html"><code>zero_vec(3)</code></a> </li>
+    </ul>
+
+    <hr>
+    <address><a href="mailto:rich@annexia.org">Richard Jones</a></address>
+<!-- Created: Wed May  1 19:36:16 BST 2002 -->
+<!-- hhmts start -->
+Last modified: Fri May  2 19:42:09 BST 2002
+<!-- hhmts end -->
+  </body>
+</html>
diff --git a/doc/make_identity_matrix.3.html b/doc/make_identity_matrix.3.html
new file mode 100644 (file)
index 0000000..7c97df9
--- /dev/null
@@ -0,0 +1,105 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>identity_matrix</title>
+</head>
+<body>
+
+<h1 align=center>identity_matrix</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+<a href="#SEE ALSO">SEE ALSO</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:02 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+identity_matrix, zero_vec, new_identity_matrix, new_zero_vec, make_identity_matrix, make_zero_vec - identity matrix and zero vector</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;matvec.h&gt;
+
+float identity_matrix[16];
+float zero_vec[4];
+float *new_identity_matrix (pool);
+float *new_zero_vec (pool);
+#define make_identity_matrix(m) memcpy (m, identity_matrix, sizeof(float)*16);
+#define make_zero_vec(v) memcpy (v, zero_vec, sizeof (float) * 4);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The <b>identity_matrix</b> variable contains a read-only
+copy of the identity matrix. The <b>zero_vec</b> variable
+contains a read-only copy of the zero vector.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Use <b>new_identity_matrix</b> to allocate a new identity
+matrix variable in <b>pool</b>. Use <b>new_zero_vec</b> to
+similarly allocate a new zero vector.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Use <b>make_identity_matrix</b> to copy the identity matrix
+over an existing matrix <b>m</b>. Use <b>make_zero_vec</b>
+to similarly copy the zero vector over an existing vector
+<b>v</b>.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<a name="SEE ALSO"></a>
+<h2>SEE ALSO</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>new_matrix(3)</b>, <b>new_vec(3)</b>.</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/make_zero_vec.3.html b/doc/make_zero_vec.3.html
new file mode 100644 (file)
index 0000000..61aaead
--- /dev/null
@@ -0,0 +1,105 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>identity_matrix</title>
+</head>
+<body>
+
+<h1 align=center>identity_matrix</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+<a href="#SEE ALSO">SEE ALSO</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:03 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+identity_matrix, zero_vec, new_identity_matrix, new_zero_vec, make_identity_matrix, make_zero_vec - identity matrix and zero vector</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;matvec.h&gt;
+
+float identity_matrix[16];
+float zero_vec[4];
+float *new_identity_matrix (pool);
+float *new_zero_vec (pool);
+#define make_identity_matrix(m) memcpy (m, identity_matrix, sizeof(float)*16);
+#define make_zero_vec(v) memcpy (v, zero_vec, sizeof (float) * 4);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The <b>identity_matrix</b> variable contains a read-only
+copy of the identity matrix. The <b>zero_vec</b> variable
+contains a read-only copy of the zero vector.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Use <b>new_identity_matrix</b> to allocate a new identity
+matrix variable in <b>pool</b>. Use <b>new_zero_vec</b> to
+similarly allocate a new zero vector.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Use <b>make_identity_matrix</b> to copy the identity matrix
+over an existing matrix <b>m</b>. Use <b>make_zero_vec</b>
+to similarly copy the zero vector over an existing vector
+<b>v</b>.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<a name="SEE ALSO"></a>
+<h2>SEE ALSO</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>new_matrix(3)</b>, <b>new_vec(3)</b>.</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/new_hash.3.html b/doc/new_hash.3.html
new file mode 100644 (file)
index 0000000..e3239ea
--- /dev/null
@@ -0,0 +1,90 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>new_hash</title>
+</head>
+<body>
+
+<h1 align=center>new_hash</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:04 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+new_hash, _hash_new - allocate a new hash</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+#define new_hash(pool,key_type,value_type) _hash_new ((pool), sizeof (key_type), sizeof (value_type))
+hash _hash_new (pool, size_t key_size, size_t value_size);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Allocate a new hash in <b>pool</b> mapping <b>key_type</b>
+to <b>value_type</b>. You can map both simple types like
+<b>int</b> and also aggregate types like structures and
+unions. However, beware of aggregate types that might
+contain 'holes' because of alignment -- such types will
+probably not work as you expect, particularly if used as
+keys.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+If you wish to have a hash which maps strings to something,
+then calling <b>new_hash(pool, char *, char *)</b> (for
+example) will not do what you expect. You are better to use
+either a sash (string to string hash) or a shash (string to
+anything hash) instead (see <b>new_sash(3)</b> and
+<b>new_shash(3)</b>).</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/new_identity_matrix.3.html b/doc/new_identity_matrix.3.html
new file mode 100644 (file)
index 0000000..6e20028
--- /dev/null
@@ -0,0 +1,105 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>identity_matrix</title>
+</head>
+<body>
+
+<h1 align=center>identity_matrix</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+<a href="#SEE ALSO">SEE ALSO</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:06 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+identity_matrix, zero_vec, new_identity_matrix, new_zero_vec, make_identity_matrix, make_zero_vec - identity matrix and zero vector</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;matvec.h&gt;
+
+float identity_matrix[16];
+float zero_vec[4];
+float *new_identity_matrix (pool);
+float *new_zero_vec (pool);
+#define make_identity_matrix(m) memcpy (m, identity_matrix, sizeof(float)*16);
+#define make_zero_vec(v) memcpy (v, zero_vec, sizeof (float) * 4);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The <b>identity_matrix</b> variable contains a read-only
+copy of the identity matrix. The <b>zero_vec</b> variable
+contains a read-only copy of the zero vector.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Use <b>new_identity_matrix</b> to allocate a new identity
+matrix variable in <b>pool</b>. Use <b>new_zero_vec</b> to
+similarly allocate a new zero vector.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Use <b>make_identity_matrix</b> to copy the identity matrix
+over an existing matrix <b>m</b>. Use <b>make_zero_vec</b>
+to similarly copy the zero vector over an existing vector
+<b>v</b>.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<a name="SEE ALSO"></a>
+<h2>SEE ALSO</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>new_matrix(3)</b>, <b>new_vec(3)</b>.</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/new_matrix.3.html b/doc/new_matrix.3.html
new file mode 100644 (file)
index 0000000..be87012
--- /dev/null
@@ -0,0 +1,109 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>new_matrix</title>
+</head>
+<body>
+
+<h1 align=center>new_matrix</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+<a href="#SEE ALSO">SEE ALSO</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:07 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+new_matrix, new_vec - allocate a new matrix or vector</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;matvec.h&gt;
+
+#define new_matrix(pool) ((float *) pmalloc ((pool), sizeof (float) * 16))
+#define new_vec(pool) ((float *) pmalloc ((pool), sizeof (float) * 4))
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>new_matrix</b> allocates a new 4x4 matrix of floats in
+<b>pool</b>.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>new_vec</b> allocates a new 4-vector of floats in
+<b>pool</b>.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+You may use these functions to allocate matrices and vectors
+dynamically, or you may allocate them statically. The other
+matrix and vector functions available do not distriguish
+between dynamically and statically allocated
+variables.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Note: All matrices are stored in COLUMN-MAJOR ORDER! This is
+for compatibility with OpenGL, but it is the OPPOSITE of the
+natural C row-major ordering, so beware.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<a name="SEE ALSO"></a>
+<h2>SEE ALSO</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>new_identity_matrix(3)</b>,
+<b>new_zero_vec(3)</b>.</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/new_pool.3.html b/doc/new_pool.3.html
new file mode 100644 (file)
index 0000000..6b1a962
--- /dev/null
@@ -0,0 +1,105 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>new_pool</title>
+</head>
+<body>
+
+<h1 align=center>new_pool</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+<a href="#SEE ALSO">SEE ALSO</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:08 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+new_pool - allocate a new pool</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pool.h&gt;
+
+pool new_pool (void);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Allocate a new pool. Pools must eventually be deleted
+explicitly by calling <b>delete_pool(3)</b>.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Note that <b>new_pool</b> is now deprecated. It is almost
+always better to create a subpool of the global pool,
+ie:</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pool = new_subpool (global_pool);</b></td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+This has the distinct advantage that your new pool will be
+cleaned up properly if the process calls
+<b>exit</b>.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<a name="SEE ALSO"></a>
+<h2>SEE ALSO</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>new_subpool(3)</b>, <b>global_pool(3)</b>,
+<b>delete_pool(3)</b>.</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/new_sash.3.html b/doc/new_sash.3.html
new file mode 100644 (file)
index 0000000..6fdd32e
--- /dev/null
@@ -0,0 +1,81 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>new_sash</title>
+</head>
+<body>
+
+<h1 align=center>new_sash</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:09 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+new_sash - allocate a new sash (string hash)</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+sash new_sash (pool);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Allocate a new sash in <b>pool</b> mapping strings to
+strings.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Use a string hash in preference to a hash of <b>char *</b>
+-&gt; <b>char *</b> which will probably not quite work as
+you expect.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/new_shash.3.html b/doc/new_shash.3.html
new file mode 100644 (file)
index 0000000..c29b092
--- /dev/null
@@ -0,0 +1,81 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>new_shash</title>
+</head>
+<body>
+
+<h1 align=center>new_shash</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:10 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+new_shash - allocate a new shash (string -&gt; something hash)</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+#define new_shash(pool,value_type) _shash_new ((pool), sizeof (value_type))
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Allocate a new shash in <b>pool</b> mapping strings to
+strings.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Use a shash in preference to a hash of <b>char *</b> -&gt;
+something which will probably not quite work as you
+expect.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/new_subpool.3.html b/doc/new_subpool.3.html
new file mode 100644 (file)
index 0000000..ea49c94
--- /dev/null
@@ -0,0 +1,74 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>new_subpool</title>
+</head>
+<body>
+
+<h1 align=center>new_subpool</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:11 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+new_subpool - allocate a subpool of an existing pool</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pool.h&gt;
+
+pool new_subpool (pool);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Allocate a new subpool. The pool may either be deleted
+explicitly, or else is deleted implicitly when the parent
+pool is deleted.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/new_subvector.3.html b/doc/new_subvector.3.html
new file mode 100644 (file)
index 0000000..9f945a2
--- /dev/null
@@ -0,0 +1,85 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>copy_vector</title>
+</head>
+<body>
+
+<h1 align=center>copy_vector</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:12 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+copy_vector, new_subvector - copy a vector</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;vector.h&gt;
+
+vector copy_vector (pool, vector v);
+vector new_subvector (pool, vector v, int i, int j);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Copy a vector <b>v</b> into pool <b>pool</b>. If the vector
+contains pointers, then this function will not copy the
+pointed-to data as well: you will need to copy this yourself
+if appropriate.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>new_subvector</b> creates a copy of part of an existing
+vector. The new vector contains the <b>j-i</b> elements of
+the old vector starting at element number <b>i</b> and
+finishing at element number <b>j-1</b>.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/new_vec.3.html b/doc/new_vec.3.html
new file mode 100644 (file)
index 0000000..6f17d26
--- /dev/null
@@ -0,0 +1,109 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>new_matrix</title>
+</head>
+<body>
+
+<h1 align=center>new_matrix</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+<a href="#SEE ALSO">SEE ALSO</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:13 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+new_matrix, new_vec - allocate a new matrix or vector</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;matvec.h&gt;
+
+#define new_matrix(pool) ((float *) pmalloc ((pool), sizeof (float) * 16))
+#define new_vec(pool) ((float *) pmalloc ((pool), sizeof (float) * 4))
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>new_matrix</b> allocates a new 4x4 matrix of floats in
+<b>pool</b>.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>new_vec</b> allocates a new 4-vector of floats in
+<b>pool</b>.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+You may use these functions to allocate matrices and vectors
+dynamically, or you may allocate them statically. The other
+matrix and vector functions available do not distriguish
+between dynamically and statically allocated
+variables.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Note: All matrices are stored in COLUMN-MAJOR ORDER! This is
+for compatibility with OpenGL, but it is the OPPOSITE of the
+natural C row-major ordering, so beware.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<a name="SEE ALSO"></a>
+<h2>SEE ALSO</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>new_identity_matrix(3)</b>,
+<b>new_zero_vec(3)</b>.</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/new_vector.3.html b/doc/new_vector.3.html
new file mode 100644 (file)
index 0000000..eaf1f48
--- /dev/null
@@ -0,0 +1,76 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>new_vector</title>
+</head>
+<body>
+
+<h1 align=center>new_vector</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:14 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+new_vector, _vector_new - allocate a new vector</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;vector.h&gt;
+
+#define new_vector(pool,type) _vector_new ((pool), sizeof (type))
+vector _vector_new (pool, size_t size);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Allocate a new vector in <b>pool</b> of type <b>type</b>.
+The first form is just a macro which evaluates the size of
+<b>type</b>. The second form creates a vector with elements
+of the given <b>size</b> directly.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/new_zero_vec.3.html b/doc/new_zero_vec.3.html
new file mode 100644 (file)
index 0000000..a9c1912
--- /dev/null
@@ -0,0 +1,105 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>identity_matrix</title>
+</head>
+<body>
+
+<h1 align=center>identity_matrix</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+<a href="#SEE ALSO">SEE ALSO</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:15 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+identity_matrix, zero_vec, new_identity_matrix, new_zero_vec, make_identity_matrix, make_zero_vec - identity matrix and zero vector</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;matvec.h&gt;
+
+float identity_matrix[16];
+float zero_vec[4];
+float *new_identity_matrix (pool);
+float *new_zero_vec (pool);
+#define make_identity_matrix(m) memcpy (m, identity_matrix, sizeof(float)*16);
+#define make_zero_vec(v) memcpy (v, zero_vec, sizeof (float) * 4);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The <b>identity_matrix</b> variable contains a read-only
+copy of the identity matrix. The <b>zero_vec</b> variable
+contains a read-only copy of the zero vector.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Use <b>new_identity_matrix</b> to allocate a new identity
+matrix variable in <b>pool</b>. Use <b>new_zero_vec</b> to
+similarly allocate a new zero vector.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Use <b>make_identity_matrix</b> to copy the identity matrix
+over an existing matrix <b>m</b>. Use <b>make_zero_vec</b>
+to similarly copy the zero vector over an existing vector
+<b>v</b>.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<a name="SEE ALSO"></a>
+<h2>SEE ALSO</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>new_matrix(3)</b>, <b>new_vec(3)</b>.</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/pcalloc.3.html b/doc/pcalloc.3.html
new file mode 100644 (file)
index 0000000..0a8a4c0
--- /dev/null
@@ -0,0 +1,116 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>pmalloc</title>
+</head>
+<body>
+
+<h1 align=center>pmalloc</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#BUGS">BUGS</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:16 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+pmalloc, pcalloc, prealloc - allocate memory in a pool</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pool.h&gt;
+
+void *pmalloc (pool, size_t n);
+void *pcalloc (pool, size_t nmemb, size_t size);
+void *prealloc (pool, void *ptr, size_t n);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Allocate memory in a pool or, if pool is null, on the main
+heap (equivalent to plain <b>malloc</b>). If memory is
+allocated in a real pool, then it is automatically freed
+when the pool is deleted.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Memory returned is word-aligned.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+If a memory allocation fails, the <b>bad_malloc_handler</b>
+function is called (which defaults to just calling
+<b>abort(3)</b>).</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pcalloc</b> is identical to <b>pmalloc</b> but also sets
+the memory to zero before returning it.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>prealloc</b> increases the size of an existing memory
+allocation. <b>prealloc</b> might move the memory in the
+process of reallocating it.</td></table>
+<a name="BUGS"></a>
+<h2>BUGS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>prealloc</b> cannot reduce the size of an existing memory
+allocation.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/pchomp.3.html b/doc/pchomp.3.html
new file mode 100644 (file)
index 0000000..a8ec6e1
--- /dev/null
@@ -0,0 +1,74 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>pchomp</title>
+</head>
+<body>
+
+<h1 align=center>pchomp</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:17 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+pchomp - remove line endings from a string</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pstring.h&gt;
+
+char *pchomp (char *line);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Remove line endings (either CR, CRLF or LF) from the string
+argument. The string is modified in-place and a pointer to
+the string is also returned.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/pchrs.3.html b/doc/pchrs.3.html
new file mode 100644 (file)
index 0000000..782cbe5
--- /dev/null
@@ -0,0 +1,85 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>pchrs</title>
+</head>
+<body>
+
+<h1 align=center>pchrs</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:18 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+pchrs, pstrs - generate a string of n repeated characters or strings</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pstring.h&gt;
+
+char *pchrs (pool, char c, int n);
+char *pstrs (pool, const char *str, int n);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pchrs (pool, 'c', n)</b> is similar to the Perl
+expression <b>'c' x n</b>. It generates a pool-allocated
+string of <b>n</b> copies of character
+<b>'c'</b>.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pstrs (pool, str, n)</b> is similar to the Perl
+expression <b>str x n</b>. It generates a pool-allocated
+string of <b>n</b> copies of the string
+<b>str</b>.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/pconcat.3.html b/doc/pconcat.3.html
new file mode 100644 (file)
index 0000000..c11d119
--- /dev/null
@@ -0,0 +1,88 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>pconcat</title>
+</head>
+<body>
+
+<h1 align=center>pconcat</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:19 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+pconcat, pjoin - concatenate a vector of strings</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pstring.h&gt;
+
+char *pconcat (pool, vector);
+char *pjoin (pool, vector, const char *sep);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pconcat</b> concatenates a vector of strings to form a
+string.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pjoin</b> is similar except that <b>sep</b> is inserted
+between each concatenated string in the output.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pjoin</b> is kind of the opposite of
+<b>pstrsplit(3)</b>.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/pdtoa.3.html b/doc/pdtoa.3.html
new file mode 100644 (file)
index 0000000..8380d84
--- /dev/null
@@ -0,0 +1,84 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>pitoa</title>
+</head>
+<body>
+
+<h1 align=center>pitoa</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:21 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+pitoa, pdtoa, pxtoa - convert number types to strings</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pstring.h&gt;
+
+char *pitoa (pool, int);
+char *pdtoa (pool, double);
+char *pxtoa (pool, unsigned);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+These functions convert a decimal <b>int</b>, <b>double</b>
+or hexadecimal <b>unsigned</b> into a string, which is
+allocated in <b>pool</b>.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pitoa</b> is equivalent to <b>psprintf (pool,
+&quot;%d&quot;, i)</b>, and the other functions have similar
+equivalents.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/pgetline.3.html b/doc/pgetline.3.html
new file mode 100644 (file)
index 0000000..e8d01cd
--- /dev/null
@@ -0,0 +1,171 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>pgetline</title>
+</head>
+<body>
+
+<h1 align=center>pgetline</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+<a href="#SEE ALSO">SEE ALSO</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:22 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+pgetline, pgetlinex, pgetlinec - read a line from a file, optionally removing comments</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pstring.h&gt;
+
+char *pgetline (pool, FILE *fp, char *line);
+char *pgetlinex (pool, FILE *fp, char *line, const char *comment_set, int flags);
+#define pgetlinec(p,fp,line) pgetlinex ((p), (fp), (line),</b> <i>#&quot;,</i><b>0)&quot;
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pgetline</b> reads a single line from a file and returns
+it. It allocates enough space to read lines of arbitrary'
+and '0) are length. Line ending characters (' automatically
+removed from the end of the line.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The <b>pool</b> argument is a pool for allocating the line.
+The <b>fp</b> argument is the C <b>FILE</b> pointer. The
+<b>line</b> argument is a pointer to a string allocated in
+pool which will be reallocated and filled with the contents
+of the line. You may pass <b>line</b> as <b>NULL</b> to get
+a newly allocated buffer.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Use <b>pgetline</b> in one of the following two
+ways:</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>line = pgetline (pool, fp, line);</b></td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+or</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>line = pgetline (pool, fp, NULL);</b></td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pgetlinex</b> is a more advanced function which reads a
+line from a file, optionally removing comments,
+concatenating together lines which have been split with a
+backslash, and ignoring blank lines. <b>pgetlinex</b> (and
+the related macro <b>pgetlinec</b>) are very useful for
+reading lines of input from a configuration
+file.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The <b>pool</b> argument is a pool for allocating the line.
+The <b>fp</b> argument is the C <b>FILE</b> pointer. The
+<b>line</b> argument is a buffer allocated in pool which
+will be reallocated and filled with the result.
+<b>comment_set</b> is the set of possible comment characters
+-- eg. <b>&quot;#!&quot;</b> to allow either <b>#</b> or
+<b>!</b> to be used to introduce comments. <b>flags</b> is
+zero or more of the following flags OR-ed
+together:</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>PGETL_NO_CONCAT</b>: Don't concatenate lines which have
+been split with trailing backslash characters.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>PGETL_INLINE_COMMENTS</b>: Treat everything following a
+comment character as a comment. The default is to only allow
+comments which appear on a line on their own.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pgetlinec</b> is a helper macro which calls
+<b>pgetlinex</b> with <b>comment_set == &quot;#&quot;</b>
+and <b>flags == 0</b>.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<a name="SEE ALSO"></a>
+<h2>SEE ALSO</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pmatch(3)</b>.</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/pgetlinec.3.html b/doc/pgetlinec.3.html
new file mode 100644 (file)
index 0000000..a3557c0
--- /dev/null
@@ -0,0 +1,171 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>pgetline</title>
+</head>
+<body>
+
+<h1 align=center>pgetline</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+<a href="#SEE ALSO">SEE ALSO</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:23 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+pgetline, pgetlinex, pgetlinec - read a line from a file, optionally removing comments</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pstring.h&gt;
+
+char *pgetline (pool, FILE *fp, char *line);
+char *pgetlinex (pool, FILE *fp, char *line, const char *comment_set, int flags);
+#define pgetlinec(p,fp,line) pgetlinex ((p), (fp), (line),</b> <i>#&quot;,</i><b>0)&quot;
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pgetline</b> reads a single line from a file and returns
+it. It allocates enough space to read lines of arbitrary'
+and '0) are length. Line ending characters (' automatically
+removed from the end of the line.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The <b>pool</b> argument is a pool for allocating the line.
+The <b>fp</b> argument is the C <b>FILE</b> pointer. The
+<b>line</b> argument is a pointer to a string allocated in
+pool which will be reallocated and filled with the contents
+of the line. You may pass <b>line</b> as <b>NULL</b> to get
+a newly allocated buffer.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Use <b>pgetline</b> in one of the following two
+ways:</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>line = pgetline (pool, fp, line);</b></td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+or</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>line = pgetline (pool, fp, NULL);</b></td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pgetlinex</b> is a more advanced function which reads a
+line from a file, optionally removing comments,
+concatenating together lines which have been split with a
+backslash, and ignoring blank lines. <b>pgetlinex</b> (and
+the related macro <b>pgetlinec</b>) are very useful for
+reading lines of input from a configuration
+file.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The <b>pool</b> argument is a pool for allocating the line.
+The <b>fp</b> argument is the C <b>FILE</b> pointer. The
+<b>line</b> argument is a buffer allocated in pool which
+will be reallocated and filled with the result.
+<b>comment_set</b> is the set of possible comment characters
+-- eg. <b>&quot;#!&quot;</b> to allow either <b>#</b> or
+<b>!</b> to be used to introduce comments. <b>flags</b> is
+zero or more of the following flags OR-ed
+together:</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>PGETL_NO_CONCAT</b>: Don't concatenate lines which have
+been split with trailing backslash characters.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>PGETL_INLINE_COMMENTS</b>: Treat everything following a
+comment character as a comment. The default is to only allow
+comments which appear on a line on their own.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pgetlinec</b> is a helper macro which calls
+<b>pgetlinex</b> with <b>comment_set == &quot;#&quot;</b>
+and <b>flags == 0</b>.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<a name="SEE ALSO"></a>
+<h2>SEE ALSO</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pmatch(3)</b>.</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/pgetlinex.3.html b/doc/pgetlinex.3.html
new file mode 100644 (file)
index 0000000..10cc5fd
--- /dev/null
@@ -0,0 +1,171 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>pgetline</title>
+</head>
+<body>
+
+<h1 align=center>pgetline</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+<a href="#SEE ALSO">SEE ALSO</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:24 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+pgetline, pgetlinex, pgetlinec - read a line from a file, optionally removing comments</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pstring.h&gt;
+
+char *pgetline (pool, FILE *fp, char *line);
+char *pgetlinex (pool, FILE *fp, char *line, const char *comment_set, int flags);
+#define pgetlinec(p,fp,line) pgetlinex ((p), (fp), (line),</b> <i>#&quot;,</i><b>0)&quot;
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pgetline</b> reads a single line from a file and returns
+it. It allocates enough space to read lines of arbitrary'
+and '0) are length. Line ending characters (' automatically
+removed from the end of the line.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The <b>pool</b> argument is a pool for allocating the line.
+The <b>fp</b> argument is the C <b>FILE</b> pointer. The
+<b>line</b> argument is a pointer to a string allocated in
+pool which will be reallocated and filled with the contents
+of the line. You may pass <b>line</b> as <b>NULL</b> to get
+a newly allocated buffer.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Use <b>pgetline</b> in one of the following two
+ways:</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>line = pgetline (pool, fp, line);</b></td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+or</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>line = pgetline (pool, fp, NULL);</b></td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pgetlinex</b> is a more advanced function which reads a
+line from a file, optionally removing comments,
+concatenating together lines which have been split with a
+backslash, and ignoring blank lines. <b>pgetlinex</b> (and
+the related macro <b>pgetlinec</b>) are very useful for
+reading lines of input from a configuration
+file.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The <b>pool</b> argument is a pool for allocating the line.
+The <b>fp</b> argument is the C <b>FILE</b> pointer. The
+<b>line</b> argument is a buffer allocated in pool which
+will be reallocated and filled with the result.
+<b>comment_set</b> is the set of possible comment characters
+-- eg. <b>&quot;#!&quot;</b> to allow either <b>#</b> or
+<b>!</b> to be used to introduce comments. <b>flags</b> is
+zero or more of the following flags OR-ed
+together:</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>PGETL_NO_CONCAT</b>: Don't concatenate lines which have
+been split with trailing backslash characters.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>PGETL_INLINE_COMMENTS</b>: Treat everything following a
+comment character as a comment. The default is to only allow
+comments which appear on a line on their own.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pgetlinec</b> is a helper macro which calls
+<b>pgetlinex</b> with <b>comment_set == &quot;#&quot;</b>
+and <b>flags == 0</b>.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<a name="SEE ALSO"></a>
+<h2>SEE ALSO</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pmatch(3)</b>.</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/pitoa.3.html b/doc/pitoa.3.html
new file mode 100644 (file)
index 0000000..b403a7c
--- /dev/null
@@ -0,0 +1,84 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>pitoa</title>
+</head>
+<body>
+
+<h1 align=center>pitoa</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:25 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+pitoa, pdtoa, pxtoa - convert number types to strings</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pstring.h&gt;
+
+char *pitoa (pool, int);
+char *pdtoa (pool, double);
+char *pxtoa (pool, unsigned);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+These functions convert a decimal <b>int</b>, <b>double</b>
+or hexadecimal <b>unsigned</b> into a string, which is
+allocated in <b>pool</b>.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pitoa</b> is equivalent to <b>psprintf (pool,
+&quot;%d&quot;, i)</b>, and the other functions have similar
+equivalents.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/pjoin.3.html b/doc/pjoin.3.html
new file mode 100644 (file)
index 0000000..969d1eb
--- /dev/null
@@ -0,0 +1,88 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>pconcat</title>
+</head>
+<body>
+
+<h1 align=center>pconcat</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:26 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+pconcat, pjoin - concatenate a vector of strings</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pstring.h&gt;
+
+char *pconcat (pool, vector);
+char *pjoin (pool, vector, const char *sep);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pconcat</b> concatenates a vector of strings to form a
+string.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pjoin</b> is similar except that <b>sep</b> is inserted
+between each concatenated string in the output.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pjoin</b> is kind of the opposite of
+<b>pstrsplit(3)</b>.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/plane_coefficients.3.html b/doc/plane_coefficients.3.html
new file mode 100644 (file)
index 0000000..0663c20
--- /dev/null
@@ -0,0 +1,114 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>plane_coefficients</title>
+</head>
+<body>
+
+<h1 align=center>plane_coefficients</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:27 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+plane_coefficients - calculate the coefficient form for a plane</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;matvec.h&gt;
+
+void plane_coefficients (const float *p, const float *q, const float *r, float *co);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Given three points, not colinear, which naturally form a
+plane, calculate the 4-vector form for the plane
+coefficients. The three points are passed as <b>p</b>,
+<b>q</b> and <b>r</b>. The coefficients are returned in
+vector <b>co</b>.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The four coefficients returned are respectively <b>a</b>,
+<b>b</b>, <b>c</b> and <b>d</b> in the standard plane
+equation:</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>a x + b y + c z + d = 0</b></td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+(Note that many texts use <b>- d</b>, so be
+warned).</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The normal (perpendicular) vector to the plane may be
+derived immediately: it is just <b>(a, b, c)</b>. Note that
+the normal vector is not normalized!</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Planes are unbounded: they stretch off to infinity in all
+directions. If what you really want are bounded convex
+polygons, then you need to use a c2lib
+&quot;face&quot;.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/plane_translate_along_normal.3.html b/doc/plane_translate_along_normal.3.html
new file mode 100644 (file)
index 0000000..3479b6c
--- /dev/null
@@ -0,0 +1,94 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>plane_translate_along_normal</title>
+</head>
+<body>
+
+<h1 align=center>plane_translate_along_normal</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+<a href="#SEE ALSO">SEE ALSO</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:28 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+plane_translate_along_normal, face_translate_along_normal - translate a plane or face some distance in the direction of the normal</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;matvec.h&gt;
+
+void plane_translate_along_normal (const float *plane, float distance, float *new_plane);
+void face_translate_along_normal (const float *points, int nr_points, const float *plane, float distance, float *new_points, float *new_plane);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Given an existing <b>plane</b> (expressed as plane
+coefficients), produce a new plane <b>new_plane</b> which
+has been translated by <b>distance</b> units along the
+direction of the normal. The new plane is also returned as
+plane coefficients.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>face_translate_along_normal</b> is similar, except that
+it also translates a list of points by the same
+distance.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<a name="SEE ALSO"></a>
+<h2>SEE ALSO</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>plane_coefficients(3)</b>.</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/pmalloc.3.html b/doc/pmalloc.3.html
new file mode 100644 (file)
index 0000000..4ebdd5c
--- /dev/null
@@ -0,0 +1,116 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>pmalloc</title>
+</head>
+<body>
+
+<h1 align=center>pmalloc</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#BUGS">BUGS</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:29 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+pmalloc, pcalloc, prealloc - allocate memory in a pool</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pool.h&gt;
+
+void *pmalloc (pool, size_t n);
+void *pcalloc (pool, size_t nmemb, size_t size);
+void *prealloc (pool, void *ptr, size_t n);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Allocate memory in a pool or, if pool is null, on the main
+heap (equivalent to plain <b>malloc</b>). If memory is
+allocated in a real pool, then it is automatically freed
+when the pool is deleted.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Memory returned is word-aligned.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+If a memory allocation fails, the <b>bad_malloc_handler</b>
+function is called (which defaults to just calling
+<b>abort(3)</b>).</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pcalloc</b> is identical to <b>pmalloc</b> but also sets
+the memory to zero before returning it.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>prealloc</b> increases the size of an existing memory
+allocation. <b>prealloc</b> might move the memory in the
+process of reallocating it.</td></table>
+<a name="BUGS"></a>
+<h2>BUGS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>prealloc</b> cannot reduce the size of an existing memory
+allocation.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/pmatch.3.html b/doc/pmatch.3.html
new file mode 100644 (file)
index 0000000..8ab063d
--- /dev/null
@@ -0,0 +1,109 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>pmatch</title>
+</head>
+<body>
+
+<h1 align=center>pmatch</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:30 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+pmatch, pmatchx - test if a string matches a regular expression</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pstring.h&gt;
+
+#define pmatch(p,str,re) pmatchx ((p), (str), (re), REG_EXTENDED, 0, 0)
+vector pmatchx (pool, const char *str, const char *re, int cflags, int eflags, int flags);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pmatch</b> is used as a quick way to test if a string
+<b>str</b> matches a POSIX regular expression <b>re</b>. The
+function internally caches compiled regular expressions for
+speed. The function returns a <b>vector</b> of <b>char
+*</b>, containing the list of substrings which match. If the
+regular expression does not match, then <b>NULL</b> is
+returned.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pmatchx</b> is the same as <b>pmatch</b> except that it
+allows greater control with flags. <b>cflags</b> and
+<b>eflags</b> are passed directly to <b>regcomp(3)</b> and
+<b>regexec(3)</b> respectively. <b>flags</b> may
+contain:</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>PMATCH_NO_CACHE</b>: Compile the regular expression
+regardless of whether the <b>re</b> is stored in the cache,
+and do not store the compiled regular expression back into
+the cache. This flag is useful to save memory if you know
+that the particular <b>re</b> will only be used very
+infrequently, and hence storing it in the cache would just
+be a waste of space.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Note that the state of <b>cflags</b> is not stored in the
+cache. In rare circumstances this could cause
+problems.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/pmatchx.3.html b/doc/pmatchx.3.html
new file mode 100644 (file)
index 0000000..10c9b3b
--- /dev/null
@@ -0,0 +1,109 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>pmatch</title>
+</head>
+<body>
+
+<h1 align=center>pmatch</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:31 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+pmatch, pmatchx - test if a string matches a regular expression</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pstring.h&gt;
+
+#define pmatch(p,str,re) pmatchx ((p), (str), (re), REG_EXTENDED, 0, 0)
+vector pmatchx (pool, const char *str, const char *re, int cflags, int eflags, int flags);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pmatch</b> is used as a quick way to test if a string
+<b>str</b> matches a POSIX regular expression <b>re</b>. The
+function internally caches compiled regular expressions for
+speed. The function returns a <b>vector</b> of <b>char
+*</b>, containing the list of substrings which match. If the
+regular expression does not match, then <b>NULL</b> is
+returned.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pmatchx</b> is the same as <b>pmatch</b> except that it
+allows greater control with flags. <b>cflags</b> and
+<b>eflags</b> are passed directly to <b>regcomp(3)</b> and
+<b>regexec(3)</b> respectively. <b>flags</b> may
+contain:</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>PMATCH_NO_CACHE</b>: Compile the regular expression
+regardless of whether the <b>re</b> is stored in the cache,
+and do not store the compiled regular expression back into
+the cache. This flag is useful to save memory if you know
+that the particular <b>re</b> will only be used very
+infrequently, and hence storing it in the cache would just
+be a waste of space.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Note that the state of <b>cflags</b> is not stored in the
+cache. In rare circumstances this could cause
+problems.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/pmemdup.3.html b/doc/pmemdup.3.html
new file mode 100644 (file)
index 0000000..83e7076
--- /dev/null
@@ -0,0 +1,90 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>pstrdup</title>
+</head>
+<body>
+
+<h1 align=center>pstrdup</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:32 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+pstrdup, pstrndup, pmemdup - duplicate a string or area of memory</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pstring.h&gt;
+
+char *pstrdup (pool, const char *s);
+char *pstrndup (pool, const char *s, int n);
+void *pmemdup (pool, const void *data, size_t size);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pstrdup</b> duplicates string <b>s</b>, allocating new
+memory for the string in pool <b>pool</b>.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pstrndup</b> duplicates just the first <b>n</b>
+characters of the string.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pmemdup</b> duplicates an arbitrary area of memory of
+size <b>size</b> bytes starting at address
+<b>data</b>.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/point_distance_to_face.3.html b/doc/point_distance_to_face.3.html
new file mode 100644 (file)
index 0000000..fdbf9d2
--- /dev/null
@@ -0,0 +1,152 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>point_distance_to_face</title>
+</head>
+<body>
+
+<h1 align=center>point_distance_to_face</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#RETURNS">RETURNS</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+<a href="#SEE ALSO">SEE ALSO</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:33 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+point_distance_to_face - distance from point to bounded convex polygon (face)</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;matvec.h&gt;
+
+float point_distance_to_face (const float *points, int nr_points, const float *plane, const float *point, int *edge);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Given a point and a bounded convex polygon (a
+&quot;face&quot;), the function
+<b>point_distance_to_face</b> calculates the distance from
+the point to the face. There are two importance cases to
+consider here:</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+(a) The point is directly above or below the face. In other
+words, a line dropped from the point perpendicular to the
+face intersects the face within the boundary of the polygon.
+In this case, the function returns the shortest distance
+from the point to the intersection (and is essentially
+equivalent to <b>point_distance_to_plane</b>).</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+(b) The point is not directly above or below the face. In
+this case the function works out the distance to the nearest
+edge of the face.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The face is specified as a list of points and a plane (ie.
+plane coefficients). If <b>plane</b> is <b>NULL</b>, then
+the function calls <b>plane_coefficients(3)</b> on your
+behalf. If the face is fixed, and you will call this
+function lots of times, then it is a good idea to calculate
+the plane coefficients once only and cache
+them.</td></table>
+<a name="RETURNS"></a>
+<h2>RETURNS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The distance of the point from the face. The distance will
+be positive if the point is above the face (ie. inside the
+plane: see <b>point_distance_to_plane(3)</b>), or negative
+otherwise.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+If <b>edge</b> is not <b>NULL</b>, then it is set to one of
+the following values:</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>*edge == -1</b> if the point is directly above or below
+the face, corresponding to case (a) above.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>*edge == 0 .. nr_points-1</b> if the point is closest to
+that particular edge, corresponding to case (b)
+above.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<a name="SEE ALSO"></a>
+<h2>SEE ALSO</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>point_distance_to_plane(3)</b>,
+<b>plane_coefficients(3)</b>, <b>point_lies_in_face(3)</b>,
+<b>point_distance_to_line(3)</b>.</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/point_distance_to_line.3.html b/doc/point_distance_to_line.3.html
new file mode 100644 (file)
index 0000000..4efceff
--- /dev/null
@@ -0,0 +1,86 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>point_distance_to_line</title>
+</head>
+<body>
+
+<h1 align=center>point_distance_to_line</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+<a href="#SEE ALSO">SEE ALSO</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:35 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+point_distance_to_line - shortest distance from a point to a line</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;matvec.h&gt;
+
+float point_distance_to_line (const float *point, const float *line_point, const float *line_vector);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Given a <b>point</b> and a line, expressed as
+<b>line_point</b> and parallel <b>line_vector</b>, compute
+the shortest distance from the point to the
+line.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<a name="SEE ALSO"></a>
+<h2>SEE ALSO</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>point_distance_to_plane(3)</b>,
+<b>point_distance_to_face(3)</b>,
+<b>point_distance_to_line_segment(3)</b>.</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/point_distance_to_line_segment.3.html b/doc/point_distance_to_line_segment.3.html
new file mode 100644 (file)
index 0000000..8b807de
--- /dev/null
@@ -0,0 +1,84 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>point_distance_to_line_segment</title>
+</head>
+<body>
+
+<h1 align=center>point_distance_to_line_segment</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+<a href="#SEE ALSO">SEE ALSO</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:36 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+point_distance_to_line_segment - shortest distance from a point to a line segment</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;matvec.h&gt;
+
+float point_distance_to_line_segment (const float *point, const float *line_point0, const float *line_point1);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Given a <b>point</b> and a line segment from
+<b>line_point0</b> to <b>line_point1</b>, compute the
+shortest distance from the point to the line
+segment.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<a name="SEE ALSO"></a>
+<h2>SEE ALSO</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>point_distance_to_line(3)</b>.</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/point_distance_to_plane.3.html b/doc/point_distance_to_plane.3.html
new file mode 100644 (file)
index 0000000..5b9bb03
--- /dev/null
@@ -0,0 +1,99 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>point_distance_to_plane</title>
+</head>
+<body>
+
+<h1 align=center>point_distance_to_plane</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+<a href="#SEE ALSO">SEE ALSO</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:37 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+point_distance_to_plane, point_is_inside_plane - distance from point to plane</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;matvec.h&gt;
+
+float point_distance_to_plane (const float *plane, const float *point);
+int point_is_inside_plane (const float *plane, const float *point);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>point_distance_to_plane</b> calculates the (shortest)
+distance from the point <b>point</b> to the plane
+<b>plane</b>. This distance is positive if the point is
+&quot;inside&quot; the plane -- that is, if the normal
+vector drawn from the plane points towards the point. It is
+negative if the point is &quot;outside&quot; the plane. It
+is zero if the point lies on the plane.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>point_is_inside_plane</b> returns true if the point is
+strictly inside the plane, and false if the point lies on
+the plane or is outside. It is much faster to compute this
+than to use <b>point_distance_to_plane</b> and take the sign
+of the result.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<a name="SEE ALSO"></a>
+<h2>SEE ALSO</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>plane_coefficients(3)</b>,
+<b>point_distance_to_face(3)</b>.</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/point_face_angle_sum.3.html b/doc/point_face_angle_sum.3.html
new file mode 100644 (file)
index 0000000..aee5d4e
--- /dev/null
@@ -0,0 +1,103 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>point_lies_in_face</title>
+</head>
+<body>
+
+<h1 align=center>point_lies_in_face</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+<a href="#SEE ALSO">SEE ALSO</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:38 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+point_lies_in_face, point_face_angle_sum - does a point lie on the interior of a bounded convex polygon</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;matvec.h&gt;
+
+int point_lies_in_face (const float *points, int nr_points, const float *point);
+float point_face_angle_sum (const float *points, int nr_points, const float *point);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Take a bounded convex polygon (a &quot;face&quot;) and a
+point. The function <b>point_lies_in_face</b> returns true
+iff the point is both (a) coplanar with the face, and (b)
+lies inside the edges of the face.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+In order to do this, <b>point_lies_in_face</b> calls
+<b>point_face_angle_sum</b> which works out the sum of the
+interior angles. If conditions (a) and (b) are both
+satisfied then the sum of the interior angles will be very
+close to 2.PI.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The face is expressed as a flat list of points
+(3-vectors).</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<a name="SEE ALSO"></a>
+<h2>SEE ALSO</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>plane_coefficients(3)</b>,
+<b>point_distance_to_face(3)</b>.</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/point_is_inside_plane.3.html b/doc/point_is_inside_plane.3.html
new file mode 100644 (file)
index 0000000..3767f12
--- /dev/null
@@ -0,0 +1,99 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>point_distance_to_plane</title>
+</head>
+<body>
+
+<h1 align=center>point_distance_to_plane</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+<a href="#SEE ALSO">SEE ALSO</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:39 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+point_distance_to_plane, point_is_inside_plane - distance from point to plane</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;matvec.h&gt;
+
+float point_distance_to_plane (const float *plane, const float *point);
+int point_is_inside_plane (const float *plane, const float *point);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>point_distance_to_plane</b> calculates the (shortest)
+distance from the point <b>point</b> to the plane
+<b>plane</b>. This distance is positive if the point is
+&quot;inside&quot; the plane -- that is, if the normal
+vector drawn from the plane points towards the point. It is
+negative if the point is &quot;outside&quot; the plane. It
+is zero if the point lies on the plane.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>point_is_inside_plane</b> returns true if the point is
+strictly inside the plane, and false if the point lies on
+the plane or is outside. It is much faster to compute this
+than to use <b>point_distance_to_plane</b> and take the sign
+of the result.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<a name="SEE ALSO"></a>
+<h2>SEE ALSO</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>plane_coefficients(3)</b>,
+<b>point_distance_to_face(3)</b>.</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/point_lies_in_face.3.html b/doc/point_lies_in_face.3.html
new file mode 100644 (file)
index 0000000..43abbd7
--- /dev/null
@@ -0,0 +1,103 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>point_lies_in_face</title>
+</head>
+<body>
+
+<h1 align=center>point_lies_in_face</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+<a href="#SEE ALSO">SEE ALSO</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:40 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+point_lies_in_face, point_face_angle_sum - does a point lie on the interior of a bounded convex polygon</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;matvec.h&gt;
+
+int point_lies_in_face (const float *points, int nr_points, const float *point);
+float point_face_angle_sum (const float *points, int nr_points, const float *point);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Take a bounded convex polygon (a &quot;face&quot;) and a
+point. The function <b>point_lies_in_face</b> returns true
+iff the point is both (a) coplanar with the face, and (b)
+lies inside the edges of the face.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+In order to do this, <b>point_lies_in_face</b> calls
+<b>point_face_angle_sum</b> which works out the sum of the
+interior angles. If conditions (a) and (b) are both
+satisfied then the sum of the interior angles will be very
+close to 2.PI.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The face is expressed as a flat list of points
+(3-vectors).</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<a name="SEE ALSO"></a>
+<h2>SEE ALSO</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>plane_coefficients(3)</b>,
+<b>point_distance_to_face(3)</b>.</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/pool_get_stats.3.html b/doc/pool_get_stats.3.html
new file mode 100644 (file)
index 0000000..10189a9
--- /dev/null
@@ -0,0 +1,98 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>pool_get_stats</title>
+</head>
+<body>
+
+<h1 align=center>pool_get_stats</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:41 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+pool_get_stats - get statistics from the pool</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pool.h&gt;
+
+void pool_get_stats (const pool, struct pool_stats *stats, size_t n);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Return various statistics collected for the pool. This
+function fills in the <b>stats</b> argument which should
+point to a structure of type <b>struct pool_stats</b>.
+<b>n</b> should be set to the size of this
+structure.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>struct pool_stats</b> currently contains the following
+fields:</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>nr_subpools</b>: The number of subpools (including the
+current pool).</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>struct_size</b>: The memory overhead used by the pool
+allocator itself to store structures. This includes
+subpools.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/pool_register_cleanup_fn.3.html b/doc/pool_register_cleanup_fn.3.html
new file mode 100644 (file)
index 0000000..3cdae5e
--- /dev/null
@@ -0,0 +1,75 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>pool_register_cleanup_fn</title>
+</head>
+<body>
+
+<h1 align=center>pool_register_cleanup_fn</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:42 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+pool_register_cleanup_fn - call function when pool is deleted</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pool.h&gt;
+
+void pool_register_cleanup_fn (pool, void (*fn) (void *), void *data);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Register a function to be called when the pool is deleted.
+There is no way to unregister this function. If you wish to
+do that, then you probably want to register it in a
+subpool.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/pool_register_fd.3.html b/doc/pool_register_fd.3.html
new file mode 100644 (file)
index 0000000..af8d946
--- /dev/null
@@ -0,0 +1,75 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>pool_register_fd</title>
+</head>
+<body>
+
+<h1 align=center>pool_register_fd</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:43 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+pool_register_fd - allow pool to own file descriptor</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pool.h&gt;
+
+void pool_register_fd (pool, int fd);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Register a file descriptor to be closed when the pool is
+deleted. There is no way to unregister a file descriptor. If
+you wish to do that, then you probably want to register the
+fd in a subpool.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/pool_register_malloc.3.html b/doc/pool_register_malloc.3.html
new file mode 100644 (file)
index 0000000..9e28696
--- /dev/null
@@ -0,0 +1,74 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>pool_register_malloc</title>
+</head>
+<body>
+
+<h1 align=center>pool_register_malloc</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:44 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+pool_register_malloc - allow pool to own malloc'd memory</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pool.h&gt;
+
+void pool_register_malloc (pool, void *ptr);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Register an anonymous area of malloc-allocated memory which
+will be freed (with <b>free(3)</b>) when the pool is
+deleted.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/pool_set_bad_malloc_handler.3.html b/doc/pool_set_bad_malloc_handler.3.html
new file mode 100644 (file)
index 0000000..49131f9
--- /dev/null
@@ -0,0 +1,74 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>pool_set_bad_malloc_handler</title>
+</head>
+<body>
+
+<h1 align=center>pool_set_bad_malloc_handler</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:45 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+pool_set_bad_malloc_handler - set handler for when malloc fails</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pool.h&gt;
+
+void pool_set_bad_malloc_handler (void (*fn) (void));
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Set the function which is called when an underlying malloc
+or realloc operation fails. The default is that
+<b>abort(3)</b> is called.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/prealloc.3.html b/doc/prealloc.3.html
new file mode 100644 (file)
index 0000000..1c1bc86
--- /dev/null
@@ -0,0 +1,116 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>pmalloc</title>
+</head>
+<body>
+
+<h1 align=center>pmalloc</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#BUGS">BUGS</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:46 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+pmalloc, pcalloc, prealloc - allocate memory in a pool</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pool.h&gt;
+
+void *pmalloc (pool, size_t n);
+void *pcalloc (pool, size_t nmemb, size_t size);
+void *prealloc (pool, void *ptr, size_t n);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Allocate memory in a pool or, if pool is null, on the main
+heap (equivalent to plain <b>malloc</b>). If memory is
+allocated in a real pool, then it is automatically freed
+when the pool is deleted.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Memory returned is word-aligned.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+If a memory allocation fails, the <b>bad_malloc_handler</b>
+function is called (which defaults to just calling
+<b>abort(3)</b>).</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pcalloc</b> is identical to <b>pmalloc</b> but also sets
+the memory to zero before returning it.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>prealloc</b> increases the size of an existing memory
+allocation. <b>prealloc</b> might move the memory in the
+process of reallocating it.</td></table>
+<a name="BUGS"></a>
+<h2>BUGS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>prealloc</b> cannot reduce the size of an existing memory
+allocation.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/psort.3.html b/doc/psort.3.html
new file mode 100644 (file)
index 0000000..d7cce33
--- /dev/null
@@ -0,0 +1,82 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>psort</title>
+</head>
+<body>
+
+<h1 align=center>psort</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:47 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+psort - sort a vector of strings</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pstring.h&gt;
+
+void psort (vector, int (*compare_fn) (const char **, const char **));
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Sort a vector of strings, using <b>compare_fn</b> to compare
+strings. The vector is sorted in-place.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+It is a common mistake to try to use <b>strcmp</b> directly
+as your comparison function. This will not work. See the C
+FAQ, section 12, question 12.2
+(<b>http://www.lysator.liu.se/c/c-faq/c-12.html</b>).</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/psprintf.3.html b/doc/psprintf.3.html
new file mode 100644 (file)
index 0000000..a627176
--- /dev/null
@@ -0,0 +1,82 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>psprintf</title>
+</head>
+<body>
+
+<h1 align=center>psprintf</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:48 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+psprintf, pvsprintf - sprintf which allocates the result in a pool</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pstring.h&gt;
+
+char *psprintf (pool, const char *format, ...) __attribute__ ((format (printf, 2, 3)));
+char *pvsprintf (pool, const char *format, va_list ap);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The <b>psprintf</b> function is equivalent to <b>sprintf</b>
+but it allocates the result string in
+<b>pool</b>.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pvsprintf</b> works similarly to
+<b>vsprintf</b>.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/pstrcat.3.html b/doc/pstrcat.3.html
new file mode 100644 (file)
index 0000000..e59238e
--- /dev/null
@@ -0,0 +1,96 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>pstrcat</title>
+</head>
+<body>
+
+<h1 align=center>pstrcat</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:49 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+pstrcat, pstrncat - extend a string</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pstring.h&gt;
+
+char *pstrcat (pool, char *str, const char *ending);
+char *pstrncat (pool, char *str, const char *ending, size_t n);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>str</b> is a string allocated in <b>pool</b>. Append
+<b>ending</b> to <b>str</b>, reallocating <b>str</b> if
+necessary.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Because <b>str</b> may be reallocated (ie. moved) you must
+invoke this function as follows:</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>str = pstrcat (pool, str, ending);</b></td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pstrncat</b> is similar to <b>pstrcat</b> except that
+only the first <b>n</b> characters of <b>ending</b> are
+appended to <b>str</b>.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/pstrcsplit.3.html b/doc/pstrcsplit.3.html
new file mode 100644 (file)
index 0000000..30538d2
--- /dev/null
@@ -0,0 +1,95 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>pstrsplit</title>
+</head>
+<body>
+
+<h1 align=center>pstrsplit</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:50 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+pstrsplit, pstrcsplit, pstrresplit - split a string on a character, string or regexp.</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pstring.h&gt;
+
+vector pstrsplit (pool, const char *str, const char *sep);
+vector pstrcsplit (pool, const char *str, char c);
+vector pstrresplit (pool, const char *str, const regex_t *re);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+These functions split string <b>str</b> on either a string
+<b>sep</b>, a character <b>c</b> or a regular expression
+<b>re</b>.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The result is a vector of newly created
+substrings.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Perl's <b>split</b> function treats zero-length strings
+differently from other strings -- returning an empty vector
+(rather than returning a vector containing a single
+zero-length string which is what you might expect, and is
+slightly more orthogonal). The author has not decided what
+the correct behaviour should be, so treat this case as
+undefined in the current release.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/pstrdup.3.html b/doc/pstrdup.3.html
new file mode 100644 (file)
index 0000000..9abadeb
--- /dev/null
@@ -0,0 +1,90 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>pstrdup</title>
+</head>
+<body>
+
+<h1 align=center>pstrdup</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:51 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+pstrdup, pstrndup, pmemdup - duplicate a string or area of memory</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pstring.h&gt;
+
+char *pstrdup (pool, const char *s);
+char *pstrndup (pool, const char *s, int n);
+void *pmemdup (pool, const void *data, size_t size);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pstrdup</b> duplicates string <b>s</b>, allocating new
+memory for the string in pool <b>pool</b>.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pstrndup</b> duplicates just the first <b>n</b>
+characters of the string.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pmemdup</b> duplicates an arbitrary area of memory of
+size <b>size</b> bytes starting at address
+<b>data</b>.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/pstrlwr.3.html b/doc/pstrlwr.3.html
new file mode 100644 (file)
index 0000000..95f0831
--- /dev/null
@@ -0,0 +1,75 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>pstrupr</title>
+</head>
+<body>
+
+<h1 align=center>pstrupr</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:52 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+pstrupr, pstrlwr - convert a string to upper- or lowercase</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pstring.h&gt;
+
+char *pstrupr (char *str);
+char *pstrlwr (char *str);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Convert a string, in-place, to upper or lowercase by
+applying <b>toupper</b> or <b>tolower</b> to each character
+in turn.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/pstrncat.3.html b/doc/pstrncat.3.html
new file mode 100644 (file)
index 0000000..9a15169
--- /dev/null
@@ -0,0 +1,96 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>pstrcat</title>
+</head>
+<body>
+
+<h1 align=center>pstrcat</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:53 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+pstrcat, pstrncat - extend a string</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pstring.h&gt;
+
+char *pstrcat (pool, char *str, const char *ending);
+char *pstrncat (pool, char *str, const char *ending, size_t n);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>str</b> is a string allocated in <b>pool</b>. Append
+<b>ending</b> to <b>str</b>, reallocating <b>str</b> if
+necessary.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Because <b>str</b> may be reallocated (ie. moved) you must
+invoke this function as follows:</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>str = pstrcat (pool, str, ending);</b></td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pstrncat</b> is similar to <b>pstrcat</b> except that
+only the first <b>n</b> characters of <b>ending</b> are
+appended to <b>str</b>.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/pstrndup.3.html b/doc/pstrndup.3.html
new file mode 100644 (file)
index 0000000..9d59434
--- /dev/null
@@ -0,0 +1,90 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>pstrdup</title>
+</head>
+<body>
+
+<h1 align=center>pstrdup</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:54 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+pstrdup, pstrndup, pmemdup - duplicate a string or area of memory</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pstring.h&gt;
+
+char *pstrdup (pool, const char *s);
+char *pstrndup (pool, const char *s, int n);
+void *pmemdup (pool, const void *data, size_t size);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pstrdup</b> duplicates string <b>s</b>, allocating new
+memory for the string in pool <b>pool</b>.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pstrndup</b> duplicates just the first <b>n</b>
+characters of the string.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pmemdup</b> duplicates an arbitrary area of memory of
+size <b>size</b> bytes starting at address
+<b>data</b>.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/pstrresplit.3.html b/doc/pstrresplit.3.html
new file mode 100644 (file)
index 0000000..3809815
--- /dev/null
@@ -0,0 +1,95 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>pstrsplit</title>
+</head>
+<body>
+
+<h1 align=center>pstrsplit</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:56 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+pstrsplit, pstrcsplit, pstrresplit - split a string on a character, string or regexp.</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pstring.h&gt;
+
+vector pstrsplit (pool, const char *str, const char *sep);
+vector pstrcsplit (pool, const char *str, char c);
+vector pstrresplit (pool, const char *str, const regex_t *re);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+These functions split string <b>str</b> on either a string
+<b>sep</b>, a character <b>c</b> or a regular expression
+<b>re</b>.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The result is a vector of newly created
+substrings.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Perl's <b>split</b> function treats zero-length strings
+differently from other strings -- returning an empty vector
+(rather than returning a vector containing a single
+zero-length string which is what you might expect, and is
+slightly more orthogonal). The author has not decided what
+the correct behaviour should be, so treat this case as
+undefined in the current release.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/pstrs.3.html b/doc/pstrs.3.html
new file mode 100644 (file)
index 0000000..0c4ac35
--- /dev/null
@@ -0,0 +1,85 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>pchrs</title>
+</head>
+<body>
+
+<h1 align=center>pchrs</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:57:58 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+pchrs, pstrs - generate a string of n repeated characters or strings</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pstring.h&gt;
+
+char *pchrs (pool, char c, int n);
+char *pstrs (pool, const char *str, int n);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pchrs (pool, 'c', n)</b> is similar to the Perl
+expression <b>'c' x n</b>. It generates a pool-allocated
+string of <b>n</b> copies of character
+<b>'c'</b>.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pstrs (pool, str, n)</b> is similar to the Perl
+expression <b>str x n</b>. It generates a pool-allocated
+string of <b>n</b> copies of the string
+<b>str</b>.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/pstrsplit.3.html b/doc/pstrsplit.3.html
new file mode 100644 (file)
index 0000000..2bd717f
--- /dev/null
@@ -0,0 +1,95 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>pstrsplit</title>
+</head>
+<body>
+
+<h1 align=center>pstrsplit</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:02 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+pstrsplit, pstrcsplit, pstrresplit - split a string on a character, string or regexp.</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pstring.h&gt;
+
+vector pstrsplit (pool, const char *str, const char *sep);
+vector pstrcsplit (pool, const char *str, char c);
+vector pstrresplit (pool, const char *str, const regex_t *re);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+These functions split string <b>str</b> on either a string
+<b>sep</b>, a character <b>c</b> or a regular expression
+<b>re</b>.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The result is a vector of newly created
+substrings.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Perl's <b>split</b> function treats zero-length strings
+differently from other strings -- returning an empty vector
+(rather than returning a vector containing a single
+zero-length string which is what you might expect, and is
+slightly more orthogonal). The author has not decided what
+the correct behaviour should be, so treat this case as
+undefined in the current release.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/pstrupr.3.html b/doc/pstrupr.3.html
new file mode 100644 (file)
index 0000000..3721a82
--- /dev/null
@@ -0,0 +1,75 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>pstrupr</title>
+</head>
+<body>
+
+<h1 align=center>pstrupr</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:03 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+pstrupr, pstrlwr - convert a string to upper- or lowercase</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pstring.h&gt;
+
+char *pstrupr (char *str);
+char *pstrlwr (char *str);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Convert a string, in-place, to upper or lowercase by
+applying <b>toupper</b> or <b>tolower</b> to each character
+in turn.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/psubst.3.html b/doc/psubst.3.html
new file mode 100644 (file)
index 0000000..c69d8b4
--- /dev/null
@@ -0,0 +1,117 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>psubst</title>
+</head>
+<body>
+
+<h1 align=center>psubst</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:04 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+psubst, psubstx - substitute string matching regular expression</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pstring.h&gt;
+
+#define psubst(p,str,pat,sub) psubstx ((p), (str), (pat), (sub), REG_EXTENDED, 0, 0)
+const char *psubstx (pool, const char *str, const char *pat, const char *sub, int cflags, int eflags, int flags);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>psubst</b> is used as a quick way to substitute strings
+which match a regular expression with other strings. It is
+the equivalent of the <b>s///</b> operator in Perl. The
+function internally caches compiled regular expressions for
+speed. The function returns a new string which is formed
+from <b>str</b> by substituting string <b>sub</b> for the
+first regular expression which matches
+<b>pat</b>.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>psubstx</b> is the same as <b>psubst</b> except that it
+allows greater control with flags. <b>cflags</b> and
+<b>eflags</b> are passed directly to <b>regcomp(3)</b> and
+<b>regexec(3)</b> respectively. <b>flags</b> may
+contain:</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>PSUBST_GLOBAL</b>: Match and replace every instance of
+<b>pat</b> in the string, not just the first.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>PSUBST_NO_CACHE</b>: Compile the regular expression
+regardless of whether the <b>re</b> is stored in the cache,
+and do not store the compiled regular expression back into
+the cache. This flag is useful to save memory if you know
+that the particular <b>re</b> will only be used very
+infrequently, and hence storing it in the cache would just
+be a waste of space.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Note that the state of <b>cflags</b> is not stored in the
+cache. In rare circumstances this could cause
+problems.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/psubstr.3.html b/doc/psubstr.3.html
new file mode 100644 (file)
index 0000000..87b6940
--- /dev/null
@@ -0,0 +1,75 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>psubstr</title>
+</head>
+<body>
+
+<h1 align=center>psubstr</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:05 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+psubstr - return a substring of a string</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pstring.h&gt;
+
+char *psubstr (pool, const char *str, int offset, int len);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Return the substring starting at <b>offset</b> and of length
+<b>len</b> of <b>str</b>, allocated as a new string. If
+<b>len</b> is negative, everything up to the end of
+<b>str</b> is returned.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/psubstx.3.html b/doc/psubstx.3.html
new file mode 100644 (file)
index 0000000..40cd5ff
--- /dev/null
@@ -0,0 +1,117 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>psubst</title>
+</head>
+<body>
+
+<h1 align=center>psubst</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:06 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+psubst, psubstx - substitute string matching regular expression</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pstring.h&gt;
+
+#define psubst(p,str,pat,sub) psubstx ((p), (str), (pat), (sub), REG_EXTENDED, 0, 0)
+const char *psubstx (pool, const char *str, const char *pat, const char *sub, int cflags, int eflags, int flags);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>psubst</b> is used as a quick way to substitute strings
+which match a regular expression with other strings. It is
+the equivalent of the <b>s///</b> operator in Perl. The
+function internally caches compiled regular expressions for
+speed. The function returns a new string which is formed
+from <b>str</b> by substituting string <b>sub</b> for the
+first regular expression which matches
+<b>pat</b>.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>psubstx</b> is the same as <b>psubst</b> except that it
+allows greater control with flags. <b>cflags</b> and
+<b>eflags</b> are passed directly to <b>regcomp(3)</b> and
+<b>regexec(3)</b> respectively. <b>flags</b> may
+contain:</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>PSUBST_GLOBAL</b>: Match and replace every instance of
+<b>pat</b> in the string, not just the first.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>PSUBST_NO_CACHE</b>: Compile the regular expression
+regardless of whether the <b>re</b> is stored in the cache,
+and do not store the compiled regular expression back into
+the cache. This flag is useful to save memory if you know
+that the particular <b>re</b> will only be used very
+infrequently, and hence storing it in the cache would just
+be a waste of space.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Note that the state of <b>cflags</b> is not stored in the
+cache. In rare circumstances this could cause
+problems.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/ptrim.3.html b/doc/ptrim.3.html
new file mode 100644 (file)
index 0000000..833c0d6
--- /dev/null
@@ -0,0 +1,91 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>ptrim</title>
+</head>
+<body>
+
+<h1 align=center>ptrim</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:07 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+ptrim, ptrimfront, ptrimback - remove whitespace from the ends of a string</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pstring.h&gt;
+
+char *ptrim (char *str);
+char *ptrimfront (char *str);
+char *ptrimback (char *str);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>ptrim</b> modifies a string of text in place, removing
+any whitespace characters from the beginning and end of the
+line.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>ptrimfront</b> is the same as <b>ptrim</b> but only
+removes whitespace from the beginning of a
+string.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>ptrimback</b> is the same as <b>ptrim</b> but only
+removes whitespace from the end of a string.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/ptrimback.3.html b/doc/ptrimback.3.html
new file mode 100644 (file)
index 0000000..875b8c7
--- /dev/null
@@ -0,0 +1,91 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>ptrim</title>
+</head>
+<body>
+
+<h1 align=center>ptrim</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:09 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+ptrim, ptrimfront, ptrimback - remove whitespace from the ends of a string</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pstring.h&gt;
+
+char *ptrim (char *str);
+char *ptrimfront (char *str);
+char *ptrimback (char *str);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>ptrim</b> modifies a string of text in place, removing
+any whitespace characters from the beginning and end of the
+line.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>ptrimfront</b> is the same as <b>ptrim</b> but only
+removes whitespace from the beginning of a
+string.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>ptrimback</b> is the same as <b>ptrim</b> but only
+removes whitespace from the end of a string.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/ptrimfront.3.html b/doc/ptrimfront.3.html
new file mode 100644 (file)
index 0000000..ae21b10
--- /dev/null
@@ -0,0 +1,91 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>ptrim</title>
+</head>
+<body>
+
+<h1 align=center>ptrim</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:10 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+ptrim, ptrimfront, ptrimback - remove whitespace from the ends of a string</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pstring.h&gt;
+
+char *ptrim (char *str);
+char *ptrimfront (char *str);
+char *ptrimback (char *str);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>ptrim</b> modifies a string of text in place, removing
+any whitespace characters from the beginning and end of the
+line.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>ptrimfront</b> is the same as <b>ptrim</b> but only
+removes whitespace from the beginning of a
+string.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>ptrimback</b> is the same as <b>ptrim</b> but only
+removes whitespace from the end of a string.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/pvdtostr.3.html b/doc/pvdtostr.3.html
new file mode 100644 (file)
index 0000000..7dac52d
--- /dev/null
@@ -0,0 +1,100 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>pvitostr</title>
+</head>
+<body>
+
+<h1 align=center>pvitostr</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:11 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+pvitostr, pvdtostr, pvxtostr - convert vectors of numbers to vectors of strings</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pstring.h&gt;
+
+vector pvitostr (pool, vector);
+vector pvdtostr (pool, vector);
+vector pvxtostr (pool, vector);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Promote vector of numbers to vector of strings.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pvitostr</b> expects a vector of <b>int</b>.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pvdtostr</b> expects a vector of
+<b>double</b>.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pvxtostr</b> expects a vector of hexadecimal
+<b>unsigned</b>.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+All functions return a vector of <b>char *</b>.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/pvector.3.html b/doc/pvector.3.html
new file mode 100644 (file)
index 0000000..1a58092
--- /dev/null
@@ -0,0 +1,112 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>pvector</title>
+</head>
+<body>
+
+<h1 align=center>pvector</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+<a href="#SEE ALSO">SEE ALSO</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:12 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+pvector, pvectora - generate a vector from a list or array of strings</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pstring.h&gt;
+
+vector pvector (pool, ...);
+vector pvectora (pool, const char *array[], int n);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pvector</b> takes a NULL-terminated list of strings as
+arguments and returns a vector of strings. <b>pvectora</b>
+takes a pointer to an array of strings and the number of
+strings and returns a vector of strings.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+A typical use of this is to quickly concatenate
+strings:</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>s = pconcat (pool, pvector (pool, s1, s2, s3,
+NULL));</b></td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+which is roughly equivalent to:</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>s = psprintf (pool, &quot;%s%s%s&quot;, s1, s2,
+s3);</b></td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<a name="SEE ALSO"></a>
+<h2>SEE ALSO</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pconcat(3)</b>, <b>psprintf(3)</b>.</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/pvectora.3.html b/doc/pvectora.3.html
new file mode 100644 (file)
index 0000000..8bbf934
--- /dev/null
@@ -0,0 +1,112 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>pvector</title>
+</head>
+<body>
+
+<h1 align=center>pvector</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+<a href="#SEE ALSO">SEE ALSO</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:13 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+pvector, pvectora - generate a vector from a list or array of strings</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pstring.h&gt;
+
+vector pvector (pool, ...);
+vector pvectora (pool, const char *array[], int n);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pvector</b> takes a NULL-terminated list of strings as
+arguments and returns a vector of strings. <b>pvectora</b>
+takes a pointer to an array of strings and the number of
+strings and returns a vector of strings.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+A typical use of this is to quickly concatenate
+strings:</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>s = pconcat (pool, pvector (pool, s1, s2, s3,
+NULL));</b></td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+which is roughly equivalent to:</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>s = psprintf (pool, &quot;%s%s%s&quot;, s1, s2,
+s3);</b></td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<a name="SEE ALSO"></a>
+<h2>SEE ALSO</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pconcat(3)</b>, <b>psprintf(3)</b>.</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/pvitostr.3.html b/doc/pvitostr.3.html
new file mode 100644 (file)
index 0000000..e1ddcd4
--- /dev/null
@@ -0,0 +1,100 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>pvitostr</title>
+</head>
+<body>
+
+<h1 align=center>pvitostr</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:14 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+pvitostr, pvdtostr, pvxtostr - convert vectors of numbers to vectors of strings</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pstring.h&gt;
+
+vector pvitostr (pool, vector);
+vector pvdtostr (pool, vector);
+vector pvxtostr (pool, vector);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Promote vector of numbers to vector of strings.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pvitostr</b> expects a vector of <b>int</b>.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pvdtostr</b> expects a vector of
+<b>double</b>.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pvxtostr</b> expects a vector of hexadecimal
+<b>unsigned</b>.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+All functions return a vector of <b>char *</b>.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/pvsprintf.3.html b/doc/pvsprintf.3.html
new file mode 100644 (file)
index 0000000..4f80550
--- /dev/null
@@ -0,0 +1,82 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>psprintf</title>
+</head>
+<body>
+
+<h1 align=center>psprintf</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:15 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+psprintf, pvsprintf - sprintf which allocates the result in a pool</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pstring.h&gt;
+
+char *psprintf (pool, const char *format, ...) __attribute__ ((format (printf, 2, 3)));
+char *pvsprintf (pool, const char *format, va_list ap);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The <b>psprintf</b> function is equivalent to <b>sprintf</b>
+but it allocates the result string in
+<b>pool</b>.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pvsprintf</b> works similarly to
+<b>vsprintf</b>.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/pvxtostr.3.html b/doc/pvxtostr.3.html
new file mode 100644 (file)
index 0000000..43dc480
--- /dev/null
@@ -0,0 +1,100 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>pvitostr</title>
+</head>
+<body>
+
+<h1 align=center>pvitostr</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:16 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+pvitostr, pvdtostr, pvxtostr - convert vectors of numbers to vectors of strings</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pstring.h&gt;
+
+vector pvitostr (pool, vector);
+vector pvdtostr (pool, vector);
+vector pvxtostr (pool, vector);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Promote vector of numbers to vector of strings.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pvitostr</b> expects a vector of <b>int</b>.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pvdtostr</b> expects a vector of
+<b>double</b>.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pvxtostr</b> expects a vector of hexadecimal
+<b>unsigned</b>.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+All functions return a vector of <b>char *</b>.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/pxtoa.3.html b/doc/pxtoa.3.html
new file mode 100644 (file)
index 0000000..087331e
--- /dev/null
@@ -0,0 +1,84 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>pitoa</title>
+</head>
+<body>
+
+<h1 align=center>pitoa</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:17 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+pitoa, pdtoa, pxtoa - convert number types to strings</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;pstring.h&gt;
+
+char *pitoa (pool, int);
+char *pdtoa (pool, double);
+char *pxtoa (pool, unsigned);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+These functions convert a decimal <b>int</b>, <b>double</b>
+or hexadecimal <b>unsigned</b> into a string, which is
+allocated in <b>pool</b>.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>pitoa</b> is equivalent to <b>psprintf (pool,
+&quot;%d&quot;, i)</b>, and the other functions have similar
+equivalents.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/sash_erase.3.html b/doc/sash_erase.3.html
new file mode 100644 (file)
index 0000000..ac8135e
--- /dev/null
@@ -0,0 +1,73 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>sash_erase</title>
+</head>
+<body>
+
+<h1 align=center>sash_erase</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:18 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+sash_erase - erase a key from a sash</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+int sash_erase (sash, const char *key);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Erase <b>key</b> from the sash. If an element was erased,
+this returns true, else this returns false.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/sash_exists.3.html b/doc/sash_exists.3.html
new file mode 100644 (file)
index 0000000..37f3bde
--- /dev/null
@@ -0,0 +1,85 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>sash_get</title>
+</head>
+<body>
+
+<h1 align=center>sash_get</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:19 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+sash_get, _sash_get, sash_exists - look up in a sash</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+#define sash_get(sash,key,value) _sash_get((sash),(key),&amp;(value))
+int _sash_get (sash, const char *key, const char **ptr);
+#define sash_exists(sash,key) _sash_get ((sash), (key), 0)
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Get the <b>value</b> associated with key <b>key</b> and
+return true. If there is no <b>value</b> associated with
+<b>key</b>, this returns false and <b>value</b> is left
+unchanged.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>sash_exists</b> simply tests whether or not <b>key</b>
+exists in the sash. If so, it returns true, otherwise
+false.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/sash_get.3.html b/doc/sash_get.3.html
new file mode 100644 (file)
index 0000000..cfc2971
--- /dev/null
@@ -0,0 +1,85 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>sash_get</title>
+</head>
+<body>
+
+<h1 align=center>sash_get</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:20 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+sash_get, _sash_get, sash_exists - look up in a sash</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+#define sash_get(sash,key,value) _sash_get((sash),(key),&amp;(value))
+int _sash_get (sash, const char *key, const char **ptr);
+#define sash_exists(sash,key) _sash_get ((sash), (key), 0)
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Get the <b>value</b> associated with key <b>key</b> and
+return true. If there is no <b>value</b> associated with
+<b>key</b>, this returns false and <b>value</b> is left
+unchanged.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>sash_exists</b> simply tests whether or not <b>key</b>
+exists in the sash. If so, it returns true, otherwise
+false.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/sash_get_buckets_allocated.3.html b/doc/sash_get_buckets_allocated.3.html
new file mode 100644 (file)
index 0000000..da6fbec
--- /dev/null
@@ -0,0 +1,76 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>sash_get_buckets_used</title>
+</head>
+<body>
+
+<h1 align=center>sash_get_buckets_used</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:21 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+sash_get_buckets_used, sash_get_buckets_allocated - return the number of buckets in a sash</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+int sash_get_buckets_used (sash);
+int sash_get_buckets_allocated (sash);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Return the number of sash buckets used and allocated. The
+number of buckets allocated is always a power of 2. See also
+<b>sash_set_buckets_allocated</b> to change the number used
+in the sash.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/sash_get_buckets_used.3.html b/doc/sash_get_buckets_used.3.html
new file mode 100644 (file)
index 0000000..2fb774e
--- /dev/null
@@ -0,0 +1,76 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>sash_get_buckets_used</title>
+</head>
+<body>
+
+<h1 align=center>sash_get_buckets_used</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:22 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+sash_get_buckets_used, sash_get_buckets_allocated - return the number of buckets in a sash</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+int sash_get_buckets_used (sash);
+int sash_get_buckets_allocated (sash);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Return the number of sash buckets used and allocated. The
+number of buckets allocated is always a power of 2. See also
+<b>sash_set_buckets_allocated</b> to change the number used
+in the sash.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/sash_insert.3.html b/doc/sash_insert.3.html
new file mode 100644 (file)
index 0000000..b057363
--- /dev/null
@@ -0,0 +1,76 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>sash_insert</title>
+</head>
+<body>
+
+<h1 align=center>sash_insert</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:23 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+sash_insert - insert a (key, value) pair into a sash</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+int sash_insert (sash, const char *key, const char *value);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Insert an element (<b>key</b>, <b>value</b>) into the sash.
+If <b>key</b> already exists in the sash, then the existing
+value is replaced by <b>value</b> and the function returns
+true. If there was no previous <b>key</b> in the sash then
+this function returns false.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/sash_keys.3.html b/doc/sash_keys.3.html
new file mode 100644 (file)
index 0000000..e1861fd
--- /dev/null
@@ -0,0 +1,78 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>sash_keys</title>
+</head>
+<body>
+
+<h1 align=center>sash_keys</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:24 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+sash_keys, sash_keys_in_pool, sash_values, sash_values_in_pool - return a vector of the keys or values in a sash</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+vector sash_keys (sash);
+vector sash_keys_in_pool (sash, pool);
+vector sash_values (sash);
+vector sash_values_in_pool (sash, pool);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Return a vector containing all the keys or values of sash.
+The <b>*_in_pool</b> variants allow you to allocate the
+vector in another pool (the default is to allocate the
+vector in the same pool as the sash).</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/sash_keys_in_pool.3.html b/doc/sash_keys_in_pool.3.html
new file mode 100644 (file)
index 0000000..59228b5
--- /dev/null
@@ -0,0 +1,78 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>sash_keys</title>
+</head>
+<body>
+
+<h1 align=center>sash_keys</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:25 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+sash_keys, sash_keys_in_pool, sash_values, sash_values_in_pool - return a vector of the keys or values in a sash</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+vector sash_keys (sash);
+vector sash_keys_in_pool (sash, pool);
+vector sash_values (sash);
+vector sash_values_in_pool (sash, pool);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Return a vector containing all the keys or values of sash.
+The <b>*_in_pool</b> variants allow you to allocate the
+vector in another pool (the default is to allocate the
+vector in the same pool as the sash).</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/sash_set_buckets_allocated.3.html b/doc/sash_set_buckets_allocated.3.html
new file mode 100644 (file)
index 0000000..b61bfbd
--- /dev/null
@@ -0,0 +1,76 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>sash_set_buckets_allocated</title>
+</head>
+<body>
+
+<h1 align=center>sash_set_buckets_allocated</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:26 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+sash_set_buckets_allocated - set the number of buckets</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+void sash_set_buckets_allocated (sash, int);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Set the number of buckets allocated. You may ONLY do this
+when you have just created the sash and before you have
+inserted any elements. Otherwise the results are undefined
+(and probably bad). The number of buckets MUST be a power of
+2.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/sash_size.3.html b/doc/sash_size.3.html
new file mode 100644 (file)
index 0000000..4075ff9
--- /dev/null
@@ -0,0 +1,73 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>sash_size</title>
+</head>
+<body>
+
+<h1 align=center>sash_size</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:27 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+sash_size - return the number of (key, value) pairs in a sash</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+int sash_size (sash);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Count the number of (key, value) pairs in the
+sash.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/sash_values.3.html b/doc/sash_values.3.html
new file mode 100644 (file)
index 0000000..756b32d
--- /dev/null
@@ -0,0 +1,78 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>sash_keys</title>
+</head>
+<body>
+
+<h1 align=center>sash_keys</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:28 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+sash_keys, sash_keys_in_pool, sash_values, sash_values_in_pool - return a vector of the keys or values in a sash</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+vector sash_keys (sash);
+vector sash_keys_in_pool (sash, pool);
+vector sash_values (sash);
+vector sash_values_in_pool (sash, pool);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Return a vector containing all the keys or values of sash.
+The <b>*_in_pool</b> variants allow you to allocate the
+vector in another pool (the default is to allocate the
+vector in the same pool as the sash).</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/sash_values_in_pool.3.html b/doc/sash_values_in_pool.3.html
new file mode 100644 (file)
index 0000000..2f011d3
--- /dev/null
@@ -0,0 +1,78 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>sash_keys</title>
+</head>
+<body>
+
+<h1 align=center>sash_keys</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:29 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+sash_keys, sash_keys_in_pool, sash_values, sash_values_in_pool - return a vector of the keys or values in a sash</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+vector sash_keys (sash);
+vector sash_keys_in_pool (sash, pool);
+vector sash_values (sash);
+vector sash_values_in_pool (sash, pool);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Return a vector containing all the keys or values of sash.
+The <b>*_in_pool</b> variants allow you to allocate the
+vector in another pool (the default is to allocate the
+vector in the same pool as the sash).</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/shash_erase.3.html b/doc/shash_erase.3.html
new file mode 100644 (file)
index 0000000..126234e
--- /dev/null
@@ -0,0 +1,73 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>shash_erase</title>
+</head>
+<body>
+
+<h1 align=center>shash_erase</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:30 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+shash_erase - erase a key from a shash</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+int shash_erase (shash, const char *key);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Erase <b>key</b> from the shash. If an element was erased,
+this returns true, else this returns false.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/shash_exists.3.html b/doc/shash_exists.3.html
new file mode 100644 (file)
index 0000000..6afab4d
--- /dev/null
@@ -0,0 +1,97 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>shash_get</title>
+</head>
+<body>
+
+<h1 align=center>shash_get</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:32 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+shash_get, _shash_get, shash_get_ptr, _shash_get_ptr, shash_exists - look up in a shash</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+#define shash_get(shash,key,value) _shash_get((shash),(key),&amp;(value))
+int _shash_get (shash, const char *key, void *value);
+#define shash_get_ptr(h,key,ptr) _shash_get_ptr ((h),(key),&amp;(ptr))
+int _shash_get_ptr (shash, const char *key, void **ptr);
+#define shash_exists(shash,key) _shash_get_ptr ((shash), (key), 0)
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Get the <b>value</b> associated with key <b>key</b> and
+return true. If there is no <b>value</b> associated with
+<b>key</b>, this returns false and <b>value</b> is left
+unchanged.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The <b>*_ptr</b> variants return a pointer rather than
+copying out the entire value object. The pointer is
+typically only valid for a short period of time.
+Particularly if you insert or remove elements from the
+shash, this pointer may become invalid.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>shash_exists</b> simply tests whether or not <b>key</b>
+exists in the shash. If so, it returns true, otherwise
+false.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/shash_get.3.html b/doc/shash_get.3.html
new file mode 100644 (file)
index 0000000..09e8da8
--- /dev/null
@@ -0,0 +1,97 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>shash_get</title>
+</head>
+<body>
+
+<h1 align=center>shash_get</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:33 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+shash_get, _shash_get, shash_get_ptr, _shash_get_ptr, shash_exists - look up in a shash</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+#define shash_get(shash,key,value) _shash_get((shash),(key),&amp;(value))
+int _shash_get (shash, const char *key, void *value);
+#define shash_get_ptr(h,key,ptr) _shash_get_ptr ((h),(key),&amp;(ptr))
+int _shash_get_ptr (shash, const char *key, void **ptr);
+#define shash_exists(shash,key) _shash_get_ptr ((shash), (key), 0)
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Get the <b>value</b> associated with key <b>key</b> and
+return true. If there is no <b>value</b> associated with
+<b>key</b>, this returns false and <b>value</b> is left
+unchanged.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The <b>*_ptr</b> variants return a pointer rather than
+copying out the entire value object. The pointer is
+typically only valid for a short period of time.
+Particularly if you insert or remove elements from the
+shash, this pointer may become invalid.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>shash_exists</b> simply tests whether or not <b>key</b>
+exists in the shash. If so, it returns true, otherwise
+false.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/shash_get_buckets_allocated.3.html b/doc/shash_get_buckets_allocated.3.html
new file mode 100644 (file)
index 0000000..3af2c8c
--- /dev/null
@@ -0,0 +1,76 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>shash_get_buckets_used</title>
+</head>
+<body>
+
+<h1 align=center>shash_get_buckets_used</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:34 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+shash_get_buckets_used, shash_get_buckets_allocated - return the number of buckets in a shash</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+int shash_get_buckets_used (shash);
+int shash_get_buckets_allocated (shash);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Return the number of shash buckets used and allocated. The
+number of buckets allocated is always a power of 2. See also
+<b>shash_set_buckets_allocated</b> to change the number used
+in the shash.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/shash_get_buckets_used.3.html b/doc/shash_get_buckets_used.3.html
new file mode 100644 (file)
index 0000000..f550064
--- /dev/null
@@ -0,0 +1,76 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>shash_get_buckets_used</title>
+</head>
+<body>
+
+<h1 align=center>shash_get_buckets_used</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:35 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+shash_get_buckets_used, shash_get_buckets_allocated - return the number of buckets in a shash</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+int shash_get_buckets_used (shash);
+int shash_get_buckets_allocated (shash);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Return the number of shash buckets used and allocated. The
+number of buckets allocated is always a power of 2. See also
+<b>shash_set_buckets_allocated</b> to change the number used
+in the shash.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/shash_get_ptr.3.html b/doc/shash_get_ptr.3.html
new file mode 100644 (file)
index 0000000..dd261d8
--- /dev/null
@@ -0,0 +1,97 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>shash_get</title>
+</head>
+<body>
+
+<h1 align=center>shash_get</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:36 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+shash_get, _shash_get, shash_get_ptr, _shash_get_ptr, shash_exists - look up in a shash</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+#define shash_get(shash,key,value) _shash_get((shash),(key),&amp;(value))
+int _shash_get (shash, const char *key, void *value);
+#define shash_get_ptr(h,key,ptr) _shash_get_ptr ((h),(key),&amp;(ptr))
+int _shash_get_ptr (shash, const char *key, void **ptr);
+#define shash_exists(shash,key) _shash_get_ptr ((shash), (key), 0)
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Get the <b>value</b> associated with key <b>key</b> and
+return true. If there is no <b>value</b> associated with
+<b>key</b>, this returns false and <b>value</b> is left
+unchanged.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The <b>*_ptr</b> variants return a pointer rather than
+copying out the entire value object. The pointer is
+typically only valid for a short period of time.
+Particularly if you insert or remove elements from the
+shash, this pointer may become invalid.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>shash_exists</b> simply tests whether or not <b>key</b>
+exists in the shash. If so, it returns true, otherwise
+false.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/shash_insert.3.html b/doc/shash_insert.3.html
new file mode 100644 (file)
index 0000000..248e2ac
--- /dev/null
@@ -0,0 +1,77 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>shash_insert</title>
+</head>
+<body>
+
+<h1 align=center>shash_insert</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:37 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+shash_insert, _shash_insert - insert a (key, value) pair into a shash</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+#define shash_insert(h,key,value) _shash_insert((h),(key),&amp;(value))
+int _shash_insert (shash, const char *key, const void *value);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Insert an element (<b>key</b>, <b>value</b>) into the shash.
+If <b>key</b> already exists in the shash, then the existing
+value is replaced by <b>value</b> and the function returns
+true. If there was no previous <b>key</b> in the shash then
+this function returns false.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/shash_keys.3.html b/doc/shash_keys.3.html
new file mode 100644 (file)
index 0000000..441836c
--- /dev/null
@@ -0,0 +1,78 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>shash_keys</title>
+</head>
+<body>
+
+<h1 align=center>shash_keys</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:38 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+shash_keys, shash_keys_in_pool, shash_values, shash_values_in_pool - return a vector of the keys or values in a shash</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+vector shash_keys (shash);
+vector shash_keys_in_pool (shash, pool);
+vector shash_values (shash);
+vector shash_values_in_pool (shash, pool);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Return a vector containing all the keys or values of shash.
+The <b>*_in_pool</b> variants allow you to allocate the
+vector in another pool (the default is to allocate the
+vector in the same pool as the shash).</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/shash_keys_in_pool.3.html b/doc/shash_keys_in_pool.3.html
new file mode 100644 (file)
index 0000000..5d58e3d
--- /dev/null
@@ -0,0 +1,78 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>shash_keys</title>
+</head>
+<body>
+
+<h1 align=center>shash_keys</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:39 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+shash_keys, shash_keys_in_pool, shash_values, shash_values_in_pool - return a vector of the keys or values in a shash</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+vector shash_keys (shash);
+vector shash_keys_in_pool (shash, pool);
+vector shash_values (shash);
+vector shash_values_in_pool (shash, pool);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Return a vector containing all the keys or values of shash.
+The <b>*_in_pool</b> variants allow you to allocate the
+vector in another pool (the default is to allocate the
+vector in the same pool as the shash).</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/shash_set_buckets_allocated.3.html b/doc/shash_set_buckets_allocated.3.html
new file mode 100644 (file)
index 0000000..d0626bb
--- /dev/null
@@ -0,0 +1,76 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>shash_set_buckets_allocated</title>
+</head>
+<body>
+
+<h1 align=center>shash_set_buckets_allocated</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:40 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+shash_set_buckets_allocated - set the number of buckets</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+void shash_set_buckets_allocated (shash, int);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Set the number of buckets allocated. You may ONLY do this
+when you have just created the shash and before you have
+inserted any elements. Otherwise the results are undefined
+(and probably bad). The number of buckets MUST be a power of
+2.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/shash_size.3.html b/doc/shash_size.3.html
new file mode 100644 (file)
index 0000000..030b624
--- /dev/null
@@ -0,0 +1,73 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>shash_size</title>
+</head>
+<body>
+
+<h1 align=center>shash_size</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:41 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+shash_size - return the number of (key, value) pairs in a shash</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+int shash_size (shash);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Count the number of (key, value) pairs in the
+shash.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/shash_values.3.html b/doc/shash_values.3.html
new file mode 100644 (file)
index 0000000..8838388
--- /dev/null
@@ -0,0 +1,78 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>shash_keys</title>
+</head>
+<body>
+
+<h1 align=center>shash_keys</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:42 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+shash_keys, shash_keys_in_pool, shash_values, shash_values_in_pool - return a vector of the keys or values in a shash</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+vector shash_keys (shash);
+vector shash_keys_in_pool (shash, pool);
+vector shash_values (shash);
+vector shash_values_in_pool (shash, pool);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Return a vector containing all the keys or values of shash.
+The <b>*_in_pool</b> variants allow you to allocate the
+vector in another pool (the default is to allocate the
+vector in the same pool as the shash).</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/shash_values_in_pool.3.html b/doc/shash_values_in_pool.3.html
new file mode 100644 (file)
index 0000000..8747de2
--- /dev/null
@@ -0,0 +1,78 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>shash_keys</title>
+</head>
+<body>
+
+<h1 align=center>shash_keys</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:43 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+shash_keys, shash_keys_in_pool, shash_values, shash_values_in_pool - return a vector of the keys or values in a shash</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;hash.h&gt;
+
+vector shash_keys (shash);
+vector shash_keys_in_pool (shash, pool);
+vector shash_values (shash);
+vector shash_values_in_pool (shash, pool);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Return a vector containing all the keys or values of shash.
+The <b>*_in_pool</b> variants allow you to allocate the
+vector in another pool (the default is to allocate the
+vector in the same pool as the shash).</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/vec_angle_between.3.html b/doc/vec_angle_between.3.html
new file mode 100644 (file)
index 0000000..32dd6fe
--- /dev/null
@@ -0,0 +1,83 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>vec_angle_between</title>
+</head>
+<body>
+
+<h1 align=center>vec_angle_between</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+<a href="#SEE ALSO">SEE ALSO</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:44 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+vec_angle_between - calculate the angle between two vectors</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;matvec.h&gt;
+
+float vec_angle_between (const float *v1, const float *v2);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+This function returns the angle between two vectors
+<b>v1</b> and <b>v2</b>.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<a name="SEE ALSO"></a>
+<h2>SEE ALSO</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>vec_dot_product(3)</b>,
+<b>vec_magnitude_in_direction(3)</b></td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/vec_dot_product.3.html b/doc/vec_dot_product.3.html
new file mode 100644 (file)
index 0000000..ed8934c
--- /dev/null
@@ -0,0 +1,107 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>vec_dot_product</title>
+</head>
+<body>
+
+<h1 align=center>vec_dot_product</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+<a href="#SEE ALSO">SEE ALSO</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:45 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+vec_dot_product - calculate the dot product of two vectors</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;matvec.h&gt;
+
+float vec_dot_product (const float *v1, const float *v2);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>vec_dot_product</b> calculates the dot product of two
+vectors <b>v1</b> and <b>v2</b> and returns it. The dot
+product is formally defined as:</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>|v1| |v2| cos theta</b></td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+where <b>theta</b> is the angle between the two
+vectors.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+One interesting consequence of this is that if both
+<b>v1</b> and <b>v2</b> are already normalized, then the dot
+product is 1 if the vectors are parallel and running in the
+same direction, and 0 if the vectors are
+perpendicular.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<a name="SEE ALSO"></a>
+<h2>SEE ALSO</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>vec_magnitude_in_direction(3)</b>,
+<b>vec_angle_between(3)</b></td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/vec_magnitude.3.html b/doc/vec_magnitude.3.html
new file mode 100644 (file)
index 0000000..e7b91ab
--- /dev/null
@@ -0,0 +1,85 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>vec_magnitude</title>
+</head>
+<body>
+
+<h1 align=center>vec_magnitude</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+<a href="#SEE ALSO">SEE ALSO</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:46 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+vec_magnitude, vec_magnitude2d - calculate magnitude (length) of a vector</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;matvec.h&gt;
+
+float vec_magnitude (const float *v);
+float vec_magnitude2d (const float *v);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>vec_magnitude</b> calculates the magnitude (length) of a
+3D vector. <b>vec_magnitude2d</b> calculates the magnitude
+of a 2D vector.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<a name="SEE ALSO"></a>
+<h2>SEE ALSO</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>vec_normalize(3)</b>,
+<b>vec_normalize2d(3)</b>.</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/vec_magnitude2d.3.html b/doc/vec_magnitude2d.3.html
new file mode 100644 (file)
index 0000000..e018a80
--- /dev/null
@@ -0,0 +1,85 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>vec_magnitude</title>
+</head>
+<body>
+
+<h1 align=center>vec_magnitude</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+<a href="#SEE ALSO">SEE ALSO</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:47 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+vec_magnitude, vec_magnitude2d - calculate magnitude (length) of a vector</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;matvec.h&gt;
+
+float vec_magnitude (const float *v);
+float vec_magnitude2d (const float *v);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>vec_magnitude</b> calculates the magnitude (length) of a
+3D vector. <b>vec_magnitude2d</b> calculates the magnitude
+of a 2D vector.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<a name="SEE ALSO"></a>
+<h2>SEE ALSO</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>vec_normalize(3)</b>,
+<b>vec_normalize2d(3)</b>.</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/vec_magnitude_in_direction.3.html b/doc/vec_magnitude_in_direction.3.html
new file mode 100644 (file)
index 0000000..64562c9
--- /dev/null
@@ -0,0 +1,88 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>vec_magnitude_in_direction</title>
+</head>
+<body>
+
+<h1 align=center>vec_magnitude_in_direction</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+<a href="#SEE ALSO">SEE ALSO</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:48 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+vec_magnitude_in_direction - calculate relative direction of two vectors</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;matvec.h&gt;
+
+float vec_magnitude_in_direction (const float *v1, const float *v2);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+If <b>v1</b> and <b>v2</b> are parallel and point in the
+same direction, then <b>vec_magnitude_in_direction</b>
+returns +1. If <b>v1</b> and <b>v2</b> are perpendicular,
+this returns 0. If <b>v1</b> and <b>v2</b> are parallel and
+point in opposite directions to each other, this returns -1.
+For other vectors, this function returns the cosine of the
+angle between the vectors.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<a name="SEE ALSO"></a>
+<h2>SEE ALSO</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>vec_dot_product(3)</b>,
+<b>vec_angle_between(3)</b></td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/vec_normalize.3.html b/doc/vec_normalize.3.html
new file mode 100644 (file)
index 0000000..434d866
--- /dev/null
@@ -0,0 +1,98 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>vec_normalize</title>
+</head>
+<body>
+
+<h1 align=center>vec_normalize</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+<a href="#SEE ALSO">SEE ALSO</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:49 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+vec_normalize, vec_normalize2d - normalize a vector</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;matvec.h&gt;
+
+void vec_normalize (const float *v, float *r);
+void vec_normalize2d (const float *v, float *r);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+These two functions normalize respectively a 3D or 2D vector
+<b>v</b>. The original vector <b>v</b> is not touched, and
+the result is placed in vector <b>r</b>.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+To normalize a vector in-place (ie. modifying the original
+vector), do:</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>vec_normalize (v, v);</b></td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<a name="SEE ALSO"></a>
+<h2>SEE ALSO</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>vec_magnitude(3)</b>,
+<b>vec_magnitude2d(3)</b>.</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/vec_normalize2d.3.html b/doc/vec_normalize2d.3.html
new file mode 100644 (file)
index 0000000..6f0d535
--- /dev/null
@@ -0,0 +1,98 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>vec_normalize</title>
+</head>
+<body>
+
+<h1 align=center>vec_normalize</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+<a href="#SEE ALSO">SEE ALSO</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:50 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+vec_normalize, vec_normalize2d - normalize a vector</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;matvec.h&gt;
+
+void vec_normalize (const float *v, float *r);
+void vec_normalize2d (const float *v, float *r);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+These two functions normalize respectively a 3D or 2D vector
+<b>v</b>. The original vector <b>v</b> is not touched, and
+the result is placed in vector <b>r</b>.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+To normalize a vector in-place (ie. modifying the original
+vector), do:</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>vec_normalize (v, v);</b></td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<a name="SEE ALSO"></a>
+<h2>SEE ALSO</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>vec_magnitude(3)</b>,
+<b>vec_magnitude2d(3)</b>.</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/vector_allocated.3.html b/doc/vector_allocated.3.html
new file mode 100644 (file)
index 0000000..12a525b
--- /dev/null
@@ -0,0 +1,77 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>vector_allocated</title>
+</head>
+<body>
+
+<h1 align=center>vector_allocated</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:51 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+vector_allocated - return the space allocated to a vector</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;vector.h&gt;
+
+#define vector_allocated(v) ((v)-&gt;allocated)
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Return the amount of space which has been allocated for
+storing elements of the vector. This is different from the
+number of elements actually stored by the vector (see
+<b>vector_size(3)</b>) and also different from the size of
+each element in bytes (see
+<b>vector_element_size(3)</b>).</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/vector_clear.3.html b/doc/vector_clear.3.html
new file mode 100644 (file)
index 0000000..70f8f60
--- /dev/null
@@ -0,0 +1,97 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>vector_erase</title>
+</head>
+<body>
+
+<h1 align=center>vector_erase</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:52 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+vector_erase, vector_erase_range, vector_clear - erase elements of a vector</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;vector.h&gt;
+
+void vector_erase (vector v, int i);
+void vector_erase_range (vector v, int i, int j);
+void vector_clear (vector v);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>vector_erase</b> removes the element <b>v[i]</b>,
+shuffling the later elements down by one place to fill the
+space.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>vector_erase_range</b> removes a range of elements
+<b>v[i]</b> to <b>v[j-1]</b> (<b>i &lt;= j</b>), shuffling
+later elements down to fill the space.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>vector_clear</b> removes all elements from the vector,
+setting its size to <b>0</b>.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Array indexes are checked.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/vector_compare.3.html b/doc/vector_compare.3.html
new file mode 100644 (file)
index 0000000..4cc298e
--- /dev/null
@@ -0,0 +1,76 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>vector_compare</title>
+</head>
+<body>
+
+<h1 align=center>vector_compare</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:53 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+vector_compare, _vector_compare - compare two vectors</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;vector.h&gt;
+
+#define vector_compare(v1,v2,compare_fn) _vector_compare ((v1), (v2), (int (*)(const void *,const void *)) (compare_fn))
+int _vector_compare (vector, vector, int (*compare_fn) (const void *, const void *));
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Compare two vectors. This returns 0 if the two vectors are
+identical. It returns &gt; 0 if <b>v1</b> &gt; <b>v2</b>.
+This returns &lt; 0 if <b>v1</b> &lt;
+<b>v2</b>.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/vector_element_size.3.html b/doc/vector_element_size.3.html
new file mode 100644 (file)
index 0000000..b147491
--- /dev/null
@@ -0,0 +1,73 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>vector_element_size</title>
+</head>
+<body>
+
+<h1 align=center>vector_element_size</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:54 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+vector_element_size - return the size of each element of a vector</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;vector.h&gt;
+
+#define vector_element_size(v) ((v)-&gt;size)
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Return the size in bytes of each element in
+vector.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/vector_erase.3.html b/doc/vector_erase.3.html
new file mode 100644 (file)
index 0000000..a1c1ce8
--- /dev/null
@@ -0,0 +1,97 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>vector_erase</title>
+</head>
+<body>
+
+<h1 align=center>vector_erase</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:55 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+vector_erase, vector_erase_range, vector_clear - erase elements of a vector</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;vector.h&gt;
+
+void vector_erase (vector v, int i);
+void vector_erase_range (vector v, int i, int j);
+void vector_clear (vector v);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>vector_erase</b> removes the element <b>v[i]</b>,
+shuffling the later elements down by one place to fill the
+space.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>vector_erase_range</b> removes a range of elements
+<b>v[i]</b> to <b>v[j-1]</b> (<b>i &lt;= j</b>), shuffling
+later elements down to fill the space.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>vector_clear</b> removes all elements from the vector,
+setting its size to <b>0</b>.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Array indexes are checked.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/vector_erase_range.3.html b/doc/vector_erase_range.3.html
new file mode 100644 (file)
index 0000000..9bec9fb
--- /dev/null
@@ -0,0 +1,97 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>vector_erase</title>
+</head>
+<body>
+
+<h1 align=center>vector_erase</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:56 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+vector_erase, vector_erase_range, vector_clear - erase elements of a vector</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;vector.h&gt;
+
+void vector_erase (vector v, int i);
+void vector_erase_range (vector v, int i, int j);
+void vector_clear (vector v);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>vector_erase</b> removes the element <b>v[i]</b>,
+shuffling the later elements down by one place to fill the
+space.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>vector_erase_range</b> removes a range of elements
+<b>v[i]</b> to <b>v[j-1]</b> (<b>i &lt;= j</b>), shuffling
+later elements down to fill the space.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>vector_clear</b> removes all elements from the vector,
+setting its size to <b>0</b>.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Array indexes are checked.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/vector_fill.3.html b/doc/vector_fill.3.html
new file mode 100644 (file)
index 0000000..57f7be5
--- /dev/null
@@ -0,0 +1,76 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>vector_fill</title>
+</head>
+<body>
+
+<h1 align=center>vector_fill</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:57 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+vector_fill, _vector_fill - fill a vector with identical elements</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;vector.h&gt;
+
+#define vector_fill(v,obj,n) _vector_fill((v),&amp;(obj),(n))
+void _vector_fill (vector, const void *ptr, int n);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>vector_fill</b> appends <b>n</b> identical copies of
+<b>obj</b> to the vector. It is equivalent to calling
+<b>vector_push_back(3)</b> in a loop <b>n</b>
+times.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/vector_get.3.html b/doc/vector_get.3.html
new file mode 100644 (file)
index 0000000..38d7b29
--- /dev/null
@@ -0,0 +1,106 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>vector_get</title>
+</head>
+<body>
+
+<h1 align=center>vector_get</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:58 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+vector_get, _vector_get, vector_get_ptr, _vector_get_ptr - array-style indexing for vectors</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;vector.h&gt;
+
+#define vector_get(v,i,obj) _vector_get((v),(i),&amp;(obj))
+void _vector_get (vector, int i, void *ptr);
+#define vector_get_ptr(v,i,ptr) (ptr) =((typeof (ptr))_vector_get_ptr((v),(i)))
+const void *_vector_get_ptr (vector, int i);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>vector_get</b> copies the element at index <b>v[i]</b>
+into local variable <b>obj</b>. The vector is
+unaffected.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>_vector_get</b> copies the element into the memory
+pointed to by <b>ptr</b>. If <b>ptr</b> is <b>NULL</b> then
+the effect is simply to check that element <b>v[i]</b>
+exists.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>vector_get_ptr</b> and <b>_vector_get_ptr</b> are used to
+get a pointer to an element in the vector. This pointer
+actually points to the vector's internal data array. It is
+only valid as long as the user does not cause the internal
+data array to be reallocated or moved - typically this can
+happen when the user performs some operation which inserts
+more elements into the array.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Array indexes are checked. An attempt to access an
+out-of-bounds element will result in a call to
+<b>abort(3)</b>.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/vector_get_ptr.3.html b/doc/vector_get_ptr.3.html
new file mode 100644 (file)
index 0000000..4599344
--- /dev/null
@@ -0,0 +1,106 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>vector_get</title>
+</head>
+<body>
+
+<h1 align=center>vector_get</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:58:59 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+vector_get, _vector_get, vector_get_ptr, _vector_get_ptr - array-style indexing for vectors</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;vector.h&gt;
+
+#define vector_get(v,i,obj) _vector_get((v),(i),&amp;(obj))
+void _vector_get (vector, int i, void *ptr);
+#define vector_get_ptr(v,i,ptr) (ptr) =((typeof (ptr))_vector_get_ptr((v),(i)))
+const void *_vector_get_ptr (vector, int i);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>vector_get</b> copies the element at index <b>v[i]</b>
+into local variable <b>obj</b>. The vector is
+unaffected.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>_vector_get</b> copies the element into the memory
+pointed to by <b>ptr</b>. If <b>ptr</b> is <b>NULL</b> then
+the effect is simply to check that element <b>v[i]</b>
+exists.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>vector_get_ptr</b> and <b>_vector_get_ptr</b> are used to
+get a pointer to an element in the vector. This pointer
+actually points to the vector's internal data array. It is
+only valid as long as the user does not cause the internal
+data array to be reallocated or moved - typically this can
+happen when the user performs some operation which inserts
+more elements into the array.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Array indexes are checked. An attempt to access an
+out-of-bounds element will result in a call to
+<b>abort(3)</b>.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/vector_grep.3.html b/doc/vector_grep.3.html
new file mode 100644 (file)
index 0000000..b1300cc
--- /dev/null
@@ -0,0 +1,75 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>vector_grep</title>
+</head>
+<body>
+
+<h1 align=center>vector_grep</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:59:00 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+vector_grep - produce a new vector containing elements of the old vector which match a boolean function</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;vector.h&gt;
+
+vector vector_grep (pool, vector v, int (*match_fn) (const void *));
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+This macro calls <b>match_fn(&amp;t)</b> for each element
+<b>t</b> of vector <b>v</b>. It constructs and returns a new
+vector containing all those elements where the function
+returns true.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/vector_grep_pool.3.html b/doc/vector_grep_pool.3.html
new file mode 100644 (file)
index 0000000..fdf5c10
--- /dev/null
@@ -0,0 +1,75 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>vector_grep_pool</title>
+</head>
+<body>
+
+<h1 align=center>vector_grep_pool</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:59:02 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+vector_grep_pool - produce a new vector containing elements of the old vector which match a boolean function</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;vector.h&gt;
+
+vector vector_grep_pool (pool, vector v, int (*match_fn) (pool, const void *));
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+This macro calls <b>match_fn(pool, &amp;t)</b> for each
+element <b>t</b> of vector <b>v</b>. It constructs and
+returns a new vector containing all those elements where the
+function returns true.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/vector_insert.3.html b/doc/vector_insert.3.html
new file mode 100644 (file)
index 0000000..4351667
--- /dev/null
@@ -0,0 +1,90 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>vector_insert</title>
+</head>
+<body>
+
+<h1 align=center>vector_insert</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:59:03 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+vector_insert, _vector_insert, vector_insert_array - insert elements into a vector</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;vector.h&gt;
+
+#define vector_insert(v,i,obj) _vector_insert((v),(i),&amp;(obj))
+void _vector_insert (vector, int i, const void *ptr);
+void vector_insert_array (vector v, int i, const void *ptr, int n);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>vector_insert</b> inserts a single object <b>obj</b>
+before element <b>i</b>. All other elements are moved up to
+make space.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>vector_insert_array</b> inserts an array of <b>n</b>
+objects starting at address <b>ptr</b> into the vector
+before index <b>i</b>.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Array indexes are checked.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/vector_insert_array.3.html b/doc/vector_insert_array.3.html
new file mode 100644 (file)
index 0000000..e5b2565
--- /dev/null
@@ -0,0 +1,90 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>vector_insert</title>
+</head>
+<body>
+
+<h1 align=center>vector_insert</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:59:04 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+vector_insert, _vector_insert, vector_insert_array - insert elements into a vector</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;vector.h&gt;
+
+#define vector_insert(v,i,obj) _vector_insert((v),(i),&amp;(obj))
+void _vector_insert (vector, int i, const void *ptr);
+void vector_insert_array (vector v, int i, const void *ptr, int n);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>vector_insert</b> inserts a single object <b>obj</b>
+before element <b>i</b>. All other elements are moved up to
+make space.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>vector_insert_array</b> inserts an array of <b>n</b>
+objects starting at address <b>ptr</b> into the vector
+before index <b>i</b>.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Array indexes are checked.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/vector_map.3.html b/doc/vector_map.3.html
new file mode 100644 (file)
index 0000000..6bd53a8
--- /dev/null
@@ -0,0 +1,76 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>vector_map</title>
+</head>
+<body>
+
+<h1 align=center>vector_map</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:59:05 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+vector_map, _vector_map - apply function to each element of a vector</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;vector.h&gt;
+
+#define vector_map(pool,v,map_fn,result_type) _vector_map ((pool), (v), (map_fn), sizeof (result_type))
+vector _vector_map (pool, vector v, void (*map_fn) (const void *, void *), size_t result_size);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Call <b>map_fn(&amp;t, &amp;r)</b> for each element <b>t</b>
+of vector <b>v</b>. The result (<b>r</b>) should have type
+<b>result_type</b> and these are concatenated to form a new
+vector which is returned.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/vector_map_pool.3.html b/doc/vector_map_pool.3.html
new file mode 100644 (file)
index 0000000..e039a83
--- /dev/null
@@ -0,0 +1,76 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>vector_map_pool</title>
+</head>
+<body>
+
+<h1 align=center>vector_map_pool</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:59:06 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+vector_map_pool, _vector_map_pool - apply function to each element of a vector</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;vector.h&gt;
+
+#define vector_map_pool(pool,v,map_fn,result_type) _vector_map_pool ((pool), (v), (map_fn), sizeof (result_type))
+vector _vector_map_pool (pool, vector v, void (*map_fn_pool) (pool, const void *, void *), size_t result_size);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Call <b>map_fn(pool, &amp;t, &amp;r)</b> for each element
+<b>t</b> of vector <b>v</b>. The result (<b>r</b>) should
+have type <b>result_type</b> and these are concatenated to
+form a new vector which is returned.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/vector_pop_back.3.html b/doc/vector_pop_back.3.html
new file mode 100644 (file)
index 0000000..16bb0cd
--- /dev/null
@@ -0,0 +1,118 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>vector_push_back</title>
+</head>
+<body>
+
+<h1 align=center>vector_push_back</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:59:07 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+vector_push_back, _vector_push_back, vector_pop_back, _vector_pop_back, vector_push_front, _vector_push_front, vector_pop_front, _vector_pop_front - push and pop objects into and out of vectors</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;vector.h&gt;
+
+#define vector_push_back(v,obj) _vector_push_back((v),&amp;(obj))
+void _vector_push_back (vector, const void *ptr);
+#define vector_pop_back(v,obj) _vector_pop_back((v),&amp;(obj))
+void _vector_pop_back (vector, void *ptr);
+#define vector_push_front(v,obj) _vector_push_front((v),&amp;(obj))
+void _vector_push_front (vector, const void *ptr);
+#define vector_pop_front(v,obj) _vector_pop_front((v),&amp;(obj))
+void _vector_pop_front (vector, void *ptr);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The <b>*_push_*</b> functions push objects onto
+vectors.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The <b>*_pop_*</b> functions pop objects off vectors into
+local variables.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The <b>*_front</b> functions push and pop objects off the
+front of a vector. This type of operation is not very
+efficient, because it involves moving all other elements of
+the vector up or down by one place.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The <b>*_back</b> functions push and pop elements off the
+end of the vector, which is efficient.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Each function has two forms: a macro version and an
+underlying function.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Array indexes are checked. You cannot pop an empty vector.
+If <b>ptr</b> is <b>NULL</b> then the popped object is
+discarded.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/vector_pop_front.3.html b/doc/vector_pop_front.3.html
new file mode 100644 (file)
index 0000000..288a2f2
--- /dev/null
@@ -0,0 +1,118 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>vector_push_back</title>
+</head>
+<body>
+
+<h1 align=center>vector_push_back</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:59:08 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+vector_push_back, _vector_push_back, vector_pop_back, _vector_pop_back, vector_push_front, _vector_push_front, vector_pop_front, _vector_pop_front - push and pop objects into and out of vectors</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;vector.h&gt;
+
+#define vector_push_back(v,obj) _vector_push_back((v),&amp;(obj))
+void _vector_push_back (vector, const void *ptr);
+#define vector_pop_back(v,obj) _vector_pop_back((v),&amp;(obj))
+void _vector_pop_back (vector, void *ptr);
+#define vector_push_front(v,obj) _vector_push_front((v),&amp;(obj))
+void _vector_push_front (vector, const void *ptr);
+#define vector_pop_front(v,obj) _vector_pop_front((v),&amp;(obj))
+void _vector_pop_front (vector, void *ptr);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The <b>*_push_*</b> functions push objects onto
+vectors.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The <b>*_pop_*</b> functions pop objects off vectors into
+local variables.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The <b>*_front</b> functions push and pop objects off the
+front of a vector. This type of operation is not very
+efficient, because it involves moving all other elements of
+the vector up or down by one place.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The <b>*_back</b> functions push and pop elements off the
+end of the vector, which is efficient.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Each function has two forms: a macro version and an
+underlying function.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Array indexes are checked. You cannot pop an empty vector.
+If <b>ptr</b> is <b>NULL</b> then the popped object is
+discarded.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/vector_push_back.3.html b/doc/vector_push_back.3.html
new file mode 100644 (file)
index 0000000..6cb511f
--- /dev/null
@@ -0,0 +1,118 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>vector_push_back</title>
+</head>
+<body>
+
+<h1 align=center>vector_push_back</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:59:09 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+vector_push_back, _vector_push_back, vector_pop_back, _vector_pop_back, vector_push_front, _vector_push_front, vector_pop_front, _vector_pop_front - push and pop objects into and out of vectors</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;vector.h&gt;
+
+#define vector_push_back(v,obj) _vector_push_back((v),&amp;(obj))
+void _vector_push_back (vector, const void *ptr);
+#define vector_pop_back(v,obj) _vector_pop_back((v),&amp;(obj))
+void _vector_pop_back (vector, void *ptr);
+#define vector_push_front(v,obj) _vector_push_front((v),&amp;(obj))
+void _vector_push_front (vector, const void *ptr);
+#define vector_pop_front(v,obj) _vector_pop_front((v),&amp;(obj))
+void _vector_pop_front (vector, void *ptr);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The <b>*_push_*</b> functions push objects onto
+vectors.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The <b>*_pop_*</b> functions pop objects off vectors into
+local variables.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The <b>*_front</b> functions push and pop objects off the
+front of a vector. This type of operation is not very
+efficient, because it involves moving all other elements of
+the vector up or down by one place.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The <b>*_back</b> functions push and pop elements off the
+end of the vector, which is efficient.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Each function has two forms: a macro version and an
+underlying function.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Array indexes are checked. You cannot pop an empty vector.
+If <b>ptr</b> is <b>NULL</b> then the popped object is
+discarded.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/vector_push_front.3.html b/doc/vector_push_front.3.html
new file mode 100644 (file)
index 0000000..f493bf4
--- /dev/null
@@ -0,0 +1,118 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>vector_push_back</title>
+</head>
+<body>
+
+<h1 align=center>vector_push_back</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:59:10 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+vector_push_back, _vector_push_back, vector_pop_back, _vector_pop_back, vector_push_front, _vector_push_front, vector_pop_front, _vector_pop_front - push and pop objects into and out of vectors</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;vector.h&gt;
+
+#define vector_push_back(v,obj) _vector_push_back((v),&amp;(obj))
+void _vector_push_back (vector, const void *ptr);
+#define vector_pop_back(v,obj) _vector_pop_back((v),&amp;(obj))
+void _vector_pop_back (vector, void *ptr);
+#define vector_push_front(v,obj) _vector_push_front((v),&amp;(obj))
+void _vector_push_front (vector, const void *ptr);
+#define vector_pop_front(v,obj) _vector_pop_front((v),&amp;(obj))
+void _vector_pop_front (vector, void *ptr);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The <b>*_push_*</b> functions push objects onto
+vectors.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The <b>*_pop_*</b> functions pop objects off vectors into
+local variables.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The <b>*_front</b> functions push and pop objects off the
+front of a vector. This type of operation is not very
+efficient, because it involves moving all other elements of
+the vector up or down by one place.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The <b>*_back</b> functions push and pop elements off the
+end of the vector, which is efficient.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Each function has two forms: a macro version and an
+underlying function.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Array indexes are checked. You cannot pop an empty vector.
+If <b>ptr</b> is <b>NULL</b> then the popped object is
+discarded.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/vector_reallocate.3.html b/doc/vector_reallocate.3.html
new file mode 100644 (file)
index 0000000..6443663
--- /dev/null
@@ -0,0 +1,77 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>vector_reallocate</title>
+</head>
+<body>
+
+<h1 align=center>vector_reallocate</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:59:11 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+vector_reallocate - change allocation for a vector</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;vector.h&gt;
+
+void vector_reallocate (vector v, int n);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Increase the amount of space allocated to a vector. See also
+<b>vector_allocated(3)</b>. This function can be used to
+avoid the vector itself making too many calls to the
+underlying <b>prealloc(3)</b>, particularly if you know in
+advance exactly how many elements the vector will
+contain.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/vector_replace.3.html b/doc/vector_replace.3.html
new file mode 100644 (file)
index 0000000..092cb5b
--- /dev/null
@@ -0,0 +1,89 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>vector_replace</title>
+</head>
+<body>
+
+<h1 align=center>vector_replace</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:59:12 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+vector_replace, _vector_replace, vector_replace_array - replace elements of a vector</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;vector.h&gt;
+
+#define vector_replace(v,i,obj) _vector_replace((v),(i),&amp;(obj))
+void _vector_replace (vector, int i, const void *ptr);
+void vector_replace_array (vector v, int i, const void *ptr, int n);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>vector_replace</b> replaces the single element at
+<b>v[i]</b> with object <b>obj</b>.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>vector_replace_array</b> replaces the <b>n</b> elements
+in the vector starting at index <b>i</b> with the <b>n</b>
+elements from the array <b>ptr</b>.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Array indexes are checked.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/vector_replace_array.3.html b/doc/vector_replace_array.3.html
new file mode 100644 (file)
index 0000000..f52126d
--- /dev/null
@@ -0,0 +1,89 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>vector_replace</title>
+</head>
+<body>
+
+<h1 align=center>vector_replace</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:59:13 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+vector_replace, _vector_replace, vector_replace_array - replace elements of a vector</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;vector.h&gt;
+
+#define vector_replace(v,i,obj) _vector_replace((v),(i),&amp;(obj))
+void _vector_replace (vector, int i, const void *ptr);
+void vector_replace_array (vector v, int i, const void *ptr, int n);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>vector_replace</b> replaces the single element at
+<b>v[i]</b> with object <b>obj</b>.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>vector_replace_array</b> replaces the <b>n</b> elements
+in the vector starting at index <b>i</b> with the <b>n</b>
+elements from the array <b>ptr</b>.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Array indexes are checked.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/vector_reverse.3.html b/doc/vector_reverse.3.html
new file mode 100644 (file)
index 0000000..f0b6139
--- /dev/null
@@ -0,0 +1,72 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>vector_reverse</title>
+</head>
+<body>
+
+<h1 align=center>vector_reverse</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:59:15 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+vector_reverse - reverse the elements of a vector in-place</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;vector.h&gt;
+
+void vector_reverse (vector v);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Reverse the elements of a vector in-place.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/vector_size.3.html b/doc/vector_size.3.html
new file mode 100644 (file)
index 0000000..1ede40a
--- /dev/null
@@ -0,0 +1,73 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>vector_size</title>
+</head>
+<body>
+
+<h1 align=center>vector_size</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:59:17 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+vector_size - return the size of a vector</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;vector.h&gt;
+
+#define vector_size(v) ((v)-&gt;used)
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Return the size (ie. number of elements) in the
+vector.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/vector_sort.3.html b/doc/vector_sort.3.html
new file mode 100644 (file)
index 0000000..a58d601
--- /dev/null
@@ -0,0 +1,74 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>vector_sort</title>
+</head>
+<body>
+
+<h1 align=center>vector_sort</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:59:19 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+vector_sort, _vector_sort - sort a vector in-place</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;vector.h&gt;
+
+#define vector_sort(v,compare_fn) _vector_sort ((v), (int (*)(const void *,const void *)) (compare_fn))
+void _vector_sort (vector v, int (*compare_fn) (const void *, const void *));
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Sort a vector in-place, comparing elements using
+<b>compare_fn</b>.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/vector_swap.3.html b/doc/vector_swap.3.html
new file mode 100644 (file)
index 0000000..4544dd0
--- /dev/null
@@ -0,0 +1,73 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>vector_swap</title>
+</head>
+<body>
+
+<h1 align=center>vector_swap</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:59:22 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+vector_swap - swap two elements of a vector</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;vector.h&gt;
+
+void vector_swap (vector v, int i, int j);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Swap elements <b>i</b> and <b>j</b> of vector
+<b>v</b>.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<hr>
+</body>
+</html>
diff --git a/doc/zero_vec.3.html b/doc/zero_vec.3.html
new file mode 100644 (file)
index 0000000..1f8dc0f
--- /dev/null
@@ -0,0 +1,105 @@
+<html>
+<head>
+<meta name="generator" content="groff -Thtml, see www.gnu.org">
+<meta name="Content-Style" content="text/css">
+<title>identity_matrix</title>
+</head>
+<body>
+
+<h1 align=center>identity_matrix</h1>
+<a href="#NAME">NAME</a><br>
+<a href="#SYNOPSIS">SYNOPSIS</a><br>
+<a href="#DESCRIPTION">DESCRIPTION</a><br>
+<a href="#AUTHOR">AUTHOR</a><br>
+<a href="#LICENSE">LICENSE</a><br>
+<a href="#VERSION">VERSION</a><br>
+<a href="#SEE ALSO">SEE ALSO</a><br>
+
+<hr>
+<!-- Creator     : groff version 1.17.2 -->
+<!-- CreationDate: Fri May  3 14:59:23 2002 -->
+<a name="NAME"></a>
+<h2>NAME</h2>
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+identity_matrix, zero_vec, new_identity_matrix, new_zero_vec, make_identity_matrix, make_zero_vec - identity matrix and zero vector</td></table>
+<a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<pre><b>#include &lt;matvec.h&gt;
+
+float identity_matrix[16];
+float zero_vec[4];
+float *new_identity_matrix (pool);
+float *new_zero_vec (pool);
+#define make_identity_matrix(m) memcpy (m, identity_matrix, sizeof(float)*16);
+#define make_zero_vec(v) memcpy (v, zero_vec, sizeof (float) * 4);
+</b></pre></td></table>
+<a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+The <b>identity_matrix</b> variable contains a read-only
+copy of the identity matrix. The <b>zero_vec</b> variable
+contains a read-only copy of the zero vector.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Use <b>new_identity_matrix</b> to allocate a new identity
+matrix variable in <b>pool</b>. Use <b>new_zero_vec</b> to
+similarly allocate a new zero vector.</td></table>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Use <b>make_identity_matrix</b> to copy the identity matrix
+over an existing matrix <b>m</b>. Use <b>make_zero_vec</b>
+to similarly copy the zero vector over an existing vector
+<b>v</b>.</td></table>
+<a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+Richard Jones &lt;rich@annexia.org&gt;</td></table>
+<a name="LICENSE"></a>
+<h2>LICENSE</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+GNU LGPL (see http://www.gnu.org/)</td></table>
+<a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+c2lib-1.2.13</td></table>
+<a name="SEE ALSO"></a>
+<h2>SEE ALSO</h2>
+
+<table width="100%" border=0 rules="none" frame="void"
+       cols="2" cellspacing="0" cellpadding="0">
+<tr valign="top" align="left">
+<td width="10%"></td><td width="90%">
+<b>new_matrix(3)</b>, <b>new_vec(3)</b>.</td></table>
+<hr>
+</body>
+</html>
diff --git a/hash.c b/hash.c
new file mode 100644 (file)
index 0000000..b88c9e8
--- /dev/null
+++ b/hash.c
@@ -0,0 +1,936 @@
+/* A hash class.
+ * By Richard W.M. Jones <rich@annexia.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id: hash.c,v 1.4 2002/11/26 19:47:29 rich Exp $
+ */
+
+#include "config.h"
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include <pstring.h>
+#include <vector.h>
+#include <hash.h>
+
+struct hash
+{
+  pool pool;
+  size_t key_size;
+  size_t value_size;
+  vector buckets;
+};
+
+struct sash
+{
+  pool pool;
+  vector buckets;
+};
+
+struct shash
+{
+  pool pool;
+  size_t value_size;
+  vector buckets;
+};
+
+#define HASH_NR_BUCKETS 32
+
+/* This is the hashing function -- the same one as used by Perl. */
+static inline unsigned
+HASH (const void *key, size_t key_size, int nr_buckets)
+{
+  unsigned h = 0;
+  const char *s = (const char *) key;
+
+  while (key_size--)
+    h = h * 33 + *s++;
+
+  return h & (nr_buckets - 1);
+}
+
+/*----- HASHes -----*/
+
+struct hash_bucket_entry
+{
+  void *key;
+  void *value;
+};
+
+hash
+_hash_new (pool pool, size_t key_size, size_t value_size)
+{
+  hash h;
+  vector null = 0;
+
+  h = pmalloc (pool, sizeof *h);
+  h->pool = pool;
+  h->key_size = key_size;
+  h->value_size = value_size;
+  h->buckets = new_vector (pool, sizeof (vector));
+  vector_fill (h->buckets, null, HASH_NR_BUCKETS);
+
+  return h;
+}
+
+/* NB. This only copies the hash, NOT the structures or whatever
+ * which might be pointed to by keys/values in the hash. Beware.
+ */
+hash
+copy_hash (pool pool, hash h)
+{
+  hash new_h;
+  int b, i;
+
+  new_h = pmalloc (pool, sizeof *new_h);
+  new_h->pool = pool;
+  new_h->key_size = h->key_size;
+  new_h->value_size = h->value_size;
+  new_h->buckets = copy_vector (pool, h->buckets);
+
+  /* Copy the buckets. */
+  for (b = 0; b < vector_size (new_h->buckets); ++b)
+    {
+      vector v;
+
+      vector_get (new_h->buckets, b, v);
+
+      if (v)
+       {
+         v = copy_vector (pool, v);
+         vector_replace (new_h->buckets, b, v);
+
+         /* Copy the keys/values in this vector. */
+         for (i = 0; i < vector_size (v); ++i)
+           {
+             struct hash_bucket_entry entry;
+
+             vector_get (v, i, entry);
+             entry.key = pmemdup (pool, entry.key, h->key_size);
+             entry.value = pmemdup (pool, entry.value, h->value_size);
+             vector_replace (v, i, entry);
+           }
+       }
+    }
+
+  return new_h;
+}
+
+int
+_hash_get (hash h, const void *key, void *value)
+{
+  const void *ptr;
+
+  ptr = _hash_get_ptr (h, key);
+  if (ptr == 0) return 0;
+
+  if (value) memcpy (value, ptr, h->value_size);
+  return 1;
+}
+
+const void *
+_hash_get_ptr (hash h, const void *key)
+{
+  int b, i;
+  vector bucket;
+
+  /* Find the appropriate bucket. */
+  b = HASH (key, h->key_size, vector_size (h->buckets));
+  vector_get (h->buckets, b, bucket);
+
+  if (bucket == 0)
+    return 0;
+
+  /* Search this bucket linearly. */
+  for (i = 0; i < vector_size (bucket); ++i)
+    {
+      struct hash_bucket_entry entry;
+
+      vector_get (bucket, i, entry);
+      if (memcmp (entry.key, key, h->key_size) == 0)
+       return entry.value;
+    }
+
+  return 0;
+}
+
+int
+_hash_insert (hash h, const void *key, const void *value)
+{
+  int b, i;
+  vector bucket;
+  struct hash_bucket_entry entry;
+
+  /* Find the appropriate bucket. */
+  b = HASH (key, h->key_size, vector_size (h->buckets));
+  vector_get (h->buckets, b, bucket);
+
+  /* If there is no bucket there, we have to allocate a fresh vector. */
+  if (bucket == 0)
+    {
+      bucket = new_vector (h->pool, struct hash_bucket_entry);
+      vector_replace (h->buckets, b, bucket);
+    }
+
+  /* Search this bucket linearly. */
+  for (i = 0; i < vector_size (bucket); ++i)
+    {
+      vector_get (bucket, i, entry);
+      if (memcmp (entry.key, key, h->key_size) == 0)
+       {
+         memcpy (entry.value, value, h->value_size);
+         /*entry.value = pmemdup (h->pool, value, h->value_size);*/
+
+         /* Replace this entry. */
+         vector_replace (bucket, i, entry);
+
+         return 1;
+       }
+    }
+
+  /* Append to this bucket. */
+  entry.key = pmemdup (h->pool, key, h->key_size);
+  entry.value = pmemdup (h->pool, value, h->value_size);
+
+  vector_push_back (bucket, entry);
+  return 0;
+}
+
+int
+_hash_erase (hash h, const void *key)
+{
+  int b, i;
+  vector bucket;
+  struct hash_bucket_entry entry;
+
+  /* Find the appropriate bucket. */
+  b = HASH (key, h->key_size, vector_size (h->buckets));
+  vector_get (h->buckets, b, bucket);
+
+  if (bucket == 0) return 0;
+
+  /* Search this bucket linearly. */
+  for (i = 0; i < vector_size (bucket); ++i)
+    {
+      vector_get (bucket, i, entry);
+      if (memcmp (entry.key, key, h->key_size) == 0)
+       {
+         /* Remove this entry. */
+         vector_erase (bucket, i);
+
+         return 1;
+       }
+    }
+
+  return 0;
+}
+
+inline vector
+hash_keys_in_pool (hash h, pool p)
+{
+  int i, j;
+  vector bucket, keys;
+  struct hash_bucket_entry entry;
+
+  keys = _vector_new (p, h->key_size);
+
+  for (i = 0; i < vector_size (h->buckets); ++i)
+    {
+      vector_get (h->buckets, i, bucket);
+
+      if (bucket)
+       for (j = 0; j < vector_size (bucket); ++j)
+         {
+           vector_get (bucket, j, entry);
+           _vector_push_back (keys, entry.key);
+         }
+    }
+
+  return keys;
+}
+
+vector
+hash_keys (hash h)
+{
+  return hash_keys_in_pool (h, h->pool);
+}
+
+inline vector
+hash_values_in_pool (hash h, pool p)
+{
+  int i, j;
+  vector bucket, values;
+  struct hash_bucket_entry entry;
+
+  values = _vector_new (p, h->value_size);
+
+  for (i = 0; i < vector_size (h->buckets); ++i)
+    {
+      vector_get (h->buckets, i, bucket);
+
+      if (bucket)
+       for (j = 0; j < vector_size (bucket); ++j)
+         {
+           vector_get (bucket, j, entry);
+           _vector_push_back (values, entry.value);
+         }
+    }
+
+  return values;
+}
+
+vector
+hash_values (hash h)
+{
+  return hash_values_in_pool (h, h->pool);
+}
+
+int
+hash_size (hash h)
+{
+  vector bucket;
+  int n = 0, i;
+
+  for (i = 0; i < vector_size (h->buckets); ++i)
+    {
+      vector_get (h->buckets, i, bucket);
+      n += bucket ? vector_size (bucket) : 0;
+    }
+
+  return n;
+}
+
+int
+hash_get_buckets_used (hash h)
+{
+  vector bucket;
+  int n = 0, i;
+
+  for (i = 0; i < vector_size (h->buckets); ++i)
+    {
+      vector_get (h->buckets, i, bucket);
+      n += bucket ? 1 : 0;
+    }
+
+  return n;
+}
+
+int
+hash_get_buckets_allocated (hash h)
+{
+  return vector_size (h->buckets);
+}
+
+void
+hash_set_buckets_allocated (hash h, int new_size)
+{
+  vector null = 0;
+
+  /* The user has been warned not to call this after elements have been
+   * inserted into the hash, and to make NEW_SIZE a power of 2.
+   */
+  if (vector_size (h->buckets) > new_size)
+    vector_erase_range (h->buckets, new_size, vector_size (h->buckets));
+  else if (vector_size (h->buckets) < new_size)
+    vector_fill (h->buckets, null, new_size - vector_size (h->buckets));
+}
+
+/*----- SASHes -----*/
+
+struct sash_bucket_entry
+{
+  char *key;
+  char *value;
+  int value_allocated;
+};
+
+sash
+new_sash (pool pool)
+{
+  sash h;
+  vector null = 0;
+
+  h = pmalloc (pool, sizeof *h);
+  h->pool = pool;
+  h->buckets = new_vector (pool, sizeof (vector));
+  vector_fill (h->buckets, null, HASH_NR_BUCKETS);
+
+  return h;
+}
+
+/* NB. Unlike copy_hash, this does copy the strings into the new
+ * pool. So a copy_sash is really a deep copy of the string hash and the
+ * strings.
+ */
+sash
+copy_sash (pool pool, sash h)
+{
+  sash new_h;
+  int b, i;
+
+  new_h = pmalloc (pool, sizeof *new_h);
+  new_h->pool = pool;
+  new_h->buckets = copy_vector (pool, h->buckets);
+
+  /* Copy the buckets. */
+  for (b = 0; b < vector_size (new_h->buckets); ++b)
+    {
+      vector v;
+
+      vector_get (new_h->buckets, b, v);
+
+      if (v)
+       {
+         v = copy_vector (pool, v);
+         vector_replace (new_h->buckets, b, v);
+
+         /* Copy the string keys/values in this vector. */
+         for (i = 0; i < vector_size (v); ++i)
+           {
+             struct sash_bucket_entry entry;
+
+             vector_get (v, i, entry);
+             entry.key = pstrdup (pool, entry.key);
+             entry.value = pstrdup (pool, entry.value);
+             vector_replace (v, i, entry);
+           }
+       }
+    }
+
+  return new_h;
+}
+
+int
+_sash_get (sash h, const char *key, const char **ptr)
+{
+  int b, i;
+  vector bucket;
+
+  /* Find the appropriate bucket. */
+  b = HASH (key, strlen (key), vector_size (h->buckets));
+  vector_get (h->buckets, b, bucket);
+
+  if (bucket == 0)
+    {
+      if (ptr) *ptr = 0;
+      return 0;
+    }
+
+  /* Search this bucket linearly. */
+  for (i = 0; i < vector_size (bucket); ++i)
+    {
+      struct sash_bucket_entry entry;
+
+      vector_get (bucket, i, entry);
+      if (strcmp (entry.key, key) == 0)
+       {
+         if (ptr) *ptr = entry.value;
+         return 1;
+       }
+    }
+
+  if (ptr) *ptr = 0;
+  return 0;
+}
+
+int
+sash_insert (sash h, const char *key, const char *value)
+{
+  int b, i, len = strlen (value);
+  vector bucket;
+  struct sash_bucket_entry entry;
+
+  /* Find the appropriate bucket. */
+  b = HASH (key, strlen (key), vector_size (h->buckets));
+  vector_get (h->buckets, b, bucket);
+
+  /* If there is no bucket there, we have to allocate a fresh vector. */
+  if (bucket == 0)
+    {
+      bucket = new_vector (h->pool, struct sash_bucket_entry);
+      vector_replace (h->buckets, b, bucket);
+    }
+
+  /* Search this bucket linearly. */
+  for (i = 0; i < vector_size (bucket); ++i)
+    {
+      vector_get (bucket, i, entry);
+      if (strcmp (entry.key, key) == 0)
+       {
+         /* To avoid unnecessarily allocating more memory, we try to
+          * be clever here. If the existing allocation is large enough
+          * to store the new string, use it. Otherwise reallocate it
+          * to make it bigger.
+          */
+         if (len < entry.value_allocated)
+           memcpy (entry.value, value, len + 1);
+         else
+           {
+             entry.value = prealloc (h->pool, entry.value, len + 1);
+             memcpy (entry.value, value, len + 1);
+             entry.value_allocated = len + 1;
+           }
+
+         /* Replace this entry. */
+         vector_replace (bucket, i, entry);
+
+         return 1;
+       }
+    }
+
+  /* Append to this bucket. */
+  entry.key = pstrdup (h->pool, key);
+  entry.value = pstrdup (h->pool, value);
+  entry.value_allocated = len + 1;
+
+  vector_push_back (bucket, entry);
+  return 0;
+}
+
+int
+sash_erase (sash h, const char *key)
+{
+  int b, i;
+  vector bucket;
+  struct sash_bucket_entry entry;
+
+  /* Find the appropriate bucket. */
+  b = HASH (key, strlen (key), vector_size (h->buckets));
+  vector_get (h->buckets, b, bucket);
+
+  if (bucket == 0) return 0;
+
+  /* Search this bucket linearly. */
+  for (i = 0; i < vector_size (bucket); ++i)
+    {
+      vector_get (bucket, i, entry);
+      if (strcmp (entry.key, key) == 0)
+       {
+         /* Remove this entry. */
+         vector_erase (bucket, i);
+
+         return 1;
+       }
+    }
+
+  return 0;
+}
+
+inline vector
+sash_keys_in_pool (sash h, pool p)
+{
+  int i, j;
+  vector bucket, keys;
+  struct sash_bucket_entry entry;
+
+  keys = new_vector (p, char *);
+
+  for (i = 0; i < vector_size (h->buckets); ++i)
+    {
+      vector_get (h->buckets, i, bucket);
+
+      if (bucket)
+       for (j = 0; j < vector_size (bucket); ++j)
+         {
+           char *key;
+
+           vector_get (bucket, j, entry);
+           key = pstrdup (p, entry.key);
+           vector_push_back (keys, key);
+         }
+    }
+
+  return keys;
+}
+
+vector
+sash_keys (sash h)
+{
+  return sash_keys_in_pool (h, h->pool);
+}
+
+inline vector
+sash_values_in_pool (sash h, pool p)
+{
+  int i, j;
+  vector bucket, values;
+  struct sash_bucket_entry entry;
+
+  values = new_vector (p, char *);
+
+  for (i = 0; i < vector_size (h->buckets); ++i)
+    {
+      vector_get (h->buckets, i, bucket);
+
+      if (bucket)
+       for (j = 0; j < vector_size (bucket); ++j)
+         {
+           char *value;
+
+           vector_get (bucket, j, entry);
+           value = pstrdup (p, entry.value);
+           vector_push_back (values, value);
+         }
+    }
+
+  return values;
+}
+
+vector
+sash_values (sash h)
+{
+  return sash_values_in_pool (h, h->pool);
+}
+
+int
+sash_size (sash h)
+{
+  vector bucket;
+  int n = 0, i;
+
+  for (i = 0; i < vector_size (h->buckets); ++i)
+    {
+      vector_get (h->buckets, i, bucket);
+      n += bucket ? vector_size (bucket) : 0;
+    }
+
+  return n;
+}
+
+int
+sash_get_buckets_used (sash h)
+{
+  vector bucket;
+  int n = 0, i;
+
+  for (i = 0; i < vector_size (h->buckets); ++i)
+    {
+      vector_get (h->buckets, i, bucket);
+      n += bucket ? 1 : 0;
+    }
+
+  return n;
+}
+
+int
+sash_get_buckets_allocated (sash h)
+{
+  return vector_size (h->buckets);
+}
+
+void
+sash_set_buckets_allocated (sash h, int new_size)
+{
+  vector null = 0;
+
+  /* The user has been warned not to call this after elements have been
+   * inserted into the sash, and to make NEW_SIZE a power of 2.
+   */
+  if (vector_size (h->buckets) > new_size)
+    vector_erase_range (h->buckets, new_size, vector_size (h->buckets));
+  else if (vector_size (h->buckets) < new_size)
+    vector_fill (h->buckets, null, new_size - vector_size (h->buckets));
+}
+
+/*----- SHASHes -----*/
+
+struct shash_bucket_entry
+{
+  char *key;
+  void *value;
+};
+
+shash
+_shash_new (pool pool, size_t value_size)
+{
+  shash h;
+  vector null = 0;
+
+  h = pmalloc (pool, sizeof *h);
+  h->pool = pool;
+  h->value_size = value_size;
+  h->buckets = new_vector (pool, sizeof (vector));
+  vector_fill (h->buckets, null, HASH_NR_BUCKETS);
+
+  return h;
+}
+
+/* NB. Unlike copy_hash, this does copy the strings into the new
+ * pool. So a copy_shash is really a deep copy of the shash and the
+ * strings.
+ */
+shash
+copy_shash (pool pool, shash h)
+{
+  shash new_h;
+  int b, i;
+
+  new_h = pmalloc (pool, sizeof *new_h);
+  new_h->pool = pool;
+  new_h->value_size = h->value_size;
+  new_h->buckets = copy_vector (pool, h->buckets);
+
+  /* Copy the buckets. */
+  for (b = 0; b < vector_size (new_h->buckets); ++b)
+    {
+      vector v;
+
+      vector_get (new_h->buckets, b, v);
+
+      if (v)
+       {
+         v = copy_vector (pool, v);
+         vector_replace (new_h->buckets, b, v);
+
+         /* Copy the string keys in this vector. */
+         for (i = 0; i < vector_size (v); ++i)
+           {
+             struct shash_bucket_entry entry;
+
+             vector_get (v, i, entry);
+             entry.key = pstrdup (pool, entry.key);
+             entry.value = pmemdup (pool, entry.value, h->value_size);
+             vector_replace (v, i, entry);
+           }
+       }
+    }
+
+  return new_h;
+}
+
+int
+_shash_get (shash h, const char *key, void *value)
+{
+  const void *ptr;
+
+  ptr = _shash_get_ptr (h, key);
+  if (ptr == 0) return 0;
+
+  if (value) memcpy (value, ptr, h->value_size);
+  return 1;
+}
+
+const void *
+_shash_get_ptr (shash h, const char *key)
+{
+  int b, i;
+  vector bucket;
+
+  /* Find the appropriate bucket. */
+  b = HASH (key, strlen (key), vector_size (h->buckets));
+  vector_get (h->buckets, b, bucket);
+
+  if (bucket == 0)
+    return 0;
+
+  /* Search this bucket linearly. */
+  for (i = 0; i < vector_size (bucket); ++i)
+    {
+      struct shash_bucket_entry entry;
+
+      vector_get (bucket, i, entry);
+      if (strcmp (entry.key, key) == 0)
+       return entry.value;
+    }
+
+  return 0;
+}
+
+int
+_shash_insert (shash h, const char *key, const void *value)
+{
+  int b, i;
+  vector bucket;
+  struct shash_bucket_entry entry;
+
+  /* Find the appropriate bucket. */
+  b = HASH (key, strlen (key), vector_size (h->buckets));
+  vector_get (h->buckets, b, bucket);
+
+  /* If there is no bucket there, we have to allocate a fresh vector. */
+  if (bucket == 0)
+    {
+      bucket = new_vector (h->pool, struct shash_bucket_entry);
+      vector_replace (h->buckets, b, bucket);
+    }
+
+  /* Search this bucket linearly. */
+  for (i = 0; i < vector_size (bucket); ++i)
+    {
+      vector_get (bucket, i, entry);
+      if (strcmp (entry.key, key) == 0)
+       {
+         memcpy (entry.value, value, h->value_size);
+         /*entry.value = pmemdup (h->pool, value, h->value_size);*/
+
+         /* Replace this entry. */
+         vector_replace (bucket, i, entry);
+
+         return 1;
+       }
+    }
+
+  /* Append to this bucket. */
+  entry.key = pstrdup (h->pool, key);
+  entry.value = pmemdup (h->pool, value, h->value_size);
+
+  vector_push_back (bucket, entry);
+  return 0;
+}
+
+int
+shash_erase (shash h, const char *key)
+{
+  int b, i;
+  vector bucket;
+  struct shash_bucket_entry entry;
+
+  /* Find the appropriate bucket. */
+  b = HASH (key, strlen (key), vector_size (h->buckets));
+  vector_get (h->buckets, b, bucket);
+
+  if (bucket == 0) return 0;
+
+  /* Search this bucket linearly. */
+  for (i = 0; i < vector_size (bucket); ++i)
+    {
+      vector_get (bucket, i, entry);
+      if (strcmp (entry.key, key) == 0)
+       {
+         /* Remove this entry. */
+         vector_erase (bucket, i);
+
+         return 1;
+       }
+    }
+
+  return 0;
+}
+
+inline vector
+shash_keys_in_pool (shash h, pool p)
+{
+  int i, j;
+  vector bucket, keys;
+  struct shash_bucket_entry entry;
+
+  keys = new_vector (p, char *);
+
+  for (i = 0; i < vector_size (h->buckets); ++i)
+    {
+      vector_get (h->buckets, i, bucket);
+
+      if (bucket)
+       for (j = 0; j < vector_size (bucket); ++j)
+         {
+           char *key;
+
+           vector_get (bucket, j, entry);
+           key = pstrdup (p, entry.key);
+           vector_push_back (keys, key);
+         }
+    }
+
+  return keys;
+}
+
+vector
+shash_keys (shash h)
+{
+  return shash_keys_in_pool (h, h->pool);
+}
+
+inline vector
+shash_values_in_pool (shash h, pool p)
+{
+  int i, j;
+  vector bucket, values;
+  struct shash_bucket_entry entry;
+
+  values = _vector_new (p, h->value_size);
+
+  for (i = 0; i < vector_size (h->buckets); ++i)
+    {
+      vector_get (h->buckets, i, bucket);
+
+      if (bucket)
+       for (j = 0; j < vector_size (bucket); ++j)
+         {
+           vector_get (bucket, j, entry);
+           _vector_push_back (values, entry.value);
+         }
+    }
+
+  return values;
+}
+
+vector
+shash_values (shash h)
+{
+  return shash_values_in_pool (h, h->pool);
+}
+
+int
+shash_size (shash h)
+{
+  vector bucket;
+  int n = 0, i;
+
+  for (i = 0; i < vector_size (h->buckets); ++i)
+    {
+      vector_get (h->buckets, i, bucket);
+      n += bucket ? vector_size (bucket) : 0;
+    }
+
+  return n;
+}
+
+int
+shash_get_buckets_used (shash h)
+{
+  vector bucket;
+  int n = 0, i;
+
+  for (i = 0; i < vector_size (h->buckets); ++i)
+    {
+      vector_get (h->buckets, i, bucket);
+      n += bucket ? 1 : 0;
+    }
+
+  return n;
+}
+
+int
+shash_get_buckets_allocated (shash h)
+{
+  return vector_size (h->buckets);
+}
+
+void
+shash_set_buckets_allocated (shash h, int new_size)
+{
+  vector null = 0;
+
+  /* The user has been warned not to call this after elements have been
+   * inserted into the shash, and to make NEW_SIZE a power of 2.
+   */
+  if (vector_size (h->buckets) > new_size)
+    vector_erase_range (h->buckets, new_size, vector_size (h->buckets));
+  else if (vector_size (h->buckets) < new_size)
+    vector_fill (h->buckets, null, new_size - vector_size (h->buckets));
+}
diff --git a/hash.h b/hash.h
new file mode 100644 (file)
index 0000000..161d6c6
--- /dev/null
+++ b/hash.h
@@ -0,0 +1,358 @@
+/* Generalized hash and string hash (sash) classes.
+ * By Richard W.M. Jones <rich@annexia.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id: hash.h,v 1.6 2002/11/26 19:47:30 rich Exp $
+ */
+
+#ifndef HASH_H
+#define HASH_H
+
+#include <vector.h>
+
+/* Note, hash and sash are identical but for the fact that
+ * hash maps fixed sized keys to values (eg. int -> int or
+ * int -> struct) and sash maps nul-terminated ASCII strings
+ * to nul-terminated ASCII strings (ie. string -> string ONLY).
+ * shash maps nul-terminated ASCII strings to anything else.
+ */
+
+struct hash;
+typedef struct hash *hash;
+
+struct sash;
+typedef struct sash *sash;
+
+struct shash;
+typedef struct shash *shash;
+
+/* Function: new_hash - allocate a new hash
+ * Function: _hash_new
+ *
+ * Allocate a new hash in @code{pool} mapping
+ * @code{key_type} to @code{value_type}. You can map both
+ * simple types like @code{int} and also aggregate types
+ * like structures and unions. However, beware of aggregate
+ * types that might contain 'holes' because of alignment --
+ * such types will probably not work as you expect, particularly
+ * if used as keys.
+ *
+ * If you wish to have
+ * a hash which maps strings to something, then calling
+ * @code{new_hash(pool, char *, char *)} (for example) will not do what
+ * you expect. You are better to use either a sash (string to string hash)
+ * or a shash (string to anything hash) instead (see
+ * @ref{new_sash(3)} and @ref{new_shash(3)}).
+ */
+#define new_hash(pool,key_type,value_type) _hash_new ((pool), sizeof (key_type), sizeof (value_type))
+extern hash _hash_new (pool, size_t key_size, size_t value_size);
+
+/* Function: copy_hash - copy a hash
+ *
+ * Copy a hash into a new pool. This function copies the keys
+ * and values, but if keys and values are pointers, then it does
+ * not perform a 'deep' copy.
+ */
+extern hash copy_hash (pool, hash);
+
+/* Function: hash_get - look up in a hash
+ * Function: _hash_get
+ * Function: hash_get_ptr
+ * Function: _hash_get_ptr
+ * Function: hash_exists
+ *
+ * Get the @code{value} associated with key @code{key} and return true.
+ * If there is no @code{value} associated with @code{key}, this returns
+ * false and @code{value} is left unchanged.
+ *
+ * The @code{*_ptr} variants return a pointer rather than copying
+ * out the entire value object. The pointer is typically only
+ * valid for a short period of time. Particularly if you insert
+ * or remove elements from the hash, this pointer may become
+ * invalid.
+ *
+ * @code{hash_exists} simply tests whether or not @code{key} exists
+ * in the hash. If so, it returns true, otherwise false.
+ */
+#define hash_get(h,key,value) _hash_get ((h), &(key), &(value))
+extern int _hash_get (hash, const void *key, void *value);
+#define hash_get_ptr(h,key,ptr) ((ptr) = ((typeof (ptr))_hash_get_ptr ((h), &(key))))
+extern const void *_hash_get_ptr (hash, const void *key);
+#define hash_exists(h,key) (_hash_get_ptr ((h), &(key)) ? 1 : 0)
+
+/* Function: hash_insert - insert a (key, value) pair into a hash
+ * Function: _hash_insert
+ *
+ * Insert an element (@code{key}, @code{value}) into the hash.
+ * If @code{key} already
+ * exists in the hash, then the existing value is replaced by
+ * @code{value}
+ * and the function returns true. If there was no previous @code{key}
+ * in the hash then this function returns false.
+ */
+#define hash_insert(h,key,value) _hash_insert((h),&(key),&(value))
+extern int _hash_insert (hash, const void *key, const void *value);
+
+/* Function: hash_erase - erase a key from a hash
+ * Function: _hash_erase
+ *
+ * Erase @code{key} from the hash. If an element was erased,
+ * this returns true, else this returns false.
+ */
+#define hash_erase(h,key) _hash_erase((h),&(key))
+extern int _hash_erase (hash, const void *key);
+
+/* Function: hash_keys - return a vector of the keys or values in a hash
+ * Function: hash_keys_in_pool
+ * Function: hash_values
+ * Function: hash_values_in_pool
+ * 
+ * Return a vector containing all the keys or values of hash. The
+ * @code{*_in_pool} variants allow you to allocate the vector in
+ * another pool (the default is to allocate the vector in the same
+ * pool as the hash).
+ */
+extern vector hash_keys (hash);
+extern vector hash_keys_in_pool (hash, pool);
+extern vector hash_values (hash);
+extern vector hash_values_in_pool (hash, pool);
+
+/* Function: hash_size - return the number of (key, value) pairs in a hash
+ *
+ * Count the number of (key, value) pairs in the hash.
+ */
+extern int hash_size (hash);
+
+/* Function: hash_get_buckets_used - return the number of buckets in a hash
+ * Function: hash_get_buckets_allocated
+ *
+ * Return the number of hash buckets used and allocated. The number of
+ * buckets allocated is always a power of 2. See also
+ * @ref{hash_set_buckets_allocated} to change the number used
+ * in the hash.
+ */
+extern int hash_get_buckets_used (hash);
+extern int hash_get_buckets_allocated (hash);
+
+/* Function: hash_set_buckets_allocated - set the number of buckets
+ *
+ * Set the number of buckets allocated. You may ONLY do this when you
+ * have just created the hash and before you have inserted any elements.
+ * Otherwise the results are undefined (and probably bad). The number
+ * of buckets MUST be a power of 2.
+ */
+extern void hash_set_buckets_allocated (hash, int);
+
+/* Function: new_sash - allocate a new sash (string hash)
+ *
+ * Allocate a new sash in @code{pool} mapping
+ * strings to strings.
+ *
+ * Use a string hash in preference to a hash of
+ * @code{char *} -> @code{char *} which will probably not
+ * quite work as you expect.
+ */
+extern sash new_sash (pool);
+
+/* Function: copy_sash - copy a sash
+ *
+ * Copy a sash into a new pool. This function copies the keys
+ * and values, but if keys and values are pointers, then it does
+ * not perform a 'deep' copy.
+ */
+extern sash copy_sash (pool, sash);
+
+/* Function: sash_get - look up in a sash
+ * Function: _sash_get
+ * Function: sash_exists
+ *
+ * Get the @code{value} associated with key @code{key} and return true.
+ * If there is no @code{value} associated with @code{key}, this returns
+ * false and @code{value} is left unchanged.
+ *
+ * @code{sash_exists} simply tests whether or not @code{key} exists
+ * in the sash. If so, it returns true, otherwise false.
+ */
+#define sash_get(sash,key,value) _sash_get((sash),(key),&(value))
+extern int _sash_get (sash, const char *key, const char **ptr);
+#define sash_exists(sash,key) _sash_get ((sash), (key), 0)
+
+/* Function: sash_insert - insert a (key, value) pair into a sash
+ *
+ * Insert an element (@code{key}, @code{value}) into the sash.
+ * If @code{key} already
+ * exists in the sash, then the existing value is replaced by
+ * @code{value}
+ * and the function returns true. If there was no previous @code{key}
+ * in the sash then this function returns false.
+ */
+extern int sash_insert (sash, const char *key, const char *value);
+
+/* Function: sash_erase - erase a key from a sash
+ *
+ * Erase @code{key} from the sash. If an element was erased,
+ * this returns true, else this returns false.
+ */
+extern int sash_erase (sash, const char *key);
+
+/* Function: sash_keys - return a vector of the keys or values in a sash
+ * Function: sash_keys_in_pool
+ * Function: sash_values
+ * Function: sash_values_in_pool
+ * 
+ * Return a vector containing all the keys or values of sash. The
+ * @code{*_in_pool} variants allow you to allocate the vector in
+ * another pool (the default is to allocate the vector in the same
+ * pool as the sash).
+ */
+extern vector sash_keys (sash);
+extern vector sash_keys_in_pool (sash, pool);
+extern vector sash_values (sash);
+extern vector sash_values_in_pool (sash, pool);
+
+/* Function: sash_size - return the number of (key, value) pairs in a sash
+ *
+ * Count the number of (key, value) pairs in the sash.
+ */
+extern int sash_size (sash);
+
+/* Function: sash_get_buckets_used - return the number of buckets in a sash
+ * Function: sash_get_buckets_allocated
+ *
+ * Return the number of sash buckets used and allocated. The number of
+ * buckets allocated is always a power of 2. See also
+ * @ref{sash_set_buckets_allocated} to change the number used
+ * in the sash.
+ */
+extern int sash_get_buckets_used (sash);
+extern int sash_get_buckets_allocated (sash);
+
+/* Function: sash_set_buckets_allocated - set the number of buckets
+ *
+ * Set the number of buckets allocated. You may ONLY do this when you
+ * have just created the sash and before you have inserted any elements.
+ * Otherwise the results are undefined (and probably bad). The number
+ * of buckets MUST be a power of 2.
+ */
+extern void sash_set_buckets_allocated (sash, int);
+
+/* Function: new_shash - allocate a new shash (string -> something hash)
+ *
+ * Allocate a new shash in @code{pool} mapping
+ * strings to strings.
+ *
+ * Use a shash in preference to a hash of
+ * @code{char *} -> something which will probably not
+ * quite work as you expect.
+ */
+#define new_shash(pool,value_type) _shash_new ((pool), sizeof (value_type))
+extern shash _shash_new (pool, size_t value_size);
+
+/* Function: copy_shash - copy a shash
+ *
+ * Copy a shash into a new pool. This function copies the keys
+ * and values, but if keys and values are pointers, then it does
+ * not perform a 'deep' copy.
+ */
+extern shash copy_shash (pool, shash);
+
+/* Function: shash_get - look up in a shash
+ * Function: _shash_get
+ * Function: shash_get_ptr
+ * Function: _shash_get_ptr
+ * Function: shash_exists
+ *
+ * Get the @code{value} associated with key @code{key} and return true.
+ * If there is no @code{value} associated with @code{key}, this returns
+ * false and @code{value} is left unchanged.
+ *
+ * The @code{*_ptr} variants return a pointer rather than copying
+ * out the entire value object. The pointer is typically only
+ * valid for a short period of time. Particularly if you insert
+ * or remove elements from the shash, this pointer may become
+ * invalid.
+ *
+ * @code{shash_exists} simply tests whether or not @code{key} exists
+ * in the shash. If so, it returns true, otherwise false.
+ */
+#define shash_get(shash,key,value) _shash_get((shash),(key),&(value))
+extern int _shash_get (shash, const char *key, void *value);
+#define shash_get_ptr(h,key,ptr) ((ptr) = ((typeof (ptr))_shash_get_ptr ((h),(key))))
+extern const void *_shash_get_ptr (shash, const char *key);
+#define shash_exists(shash,key) (_shash_get_ptr ((shash), (key)) ? 1 : 0)
+
+/* Function: shash_insert - insert a (key, value) pair into a shash
+ * Function: _shash_insert
+ *
+ * Insert an element (@code{key}, @code{value}) into the shash.
+ * If @code{key} already
+ * exists in the shash, then the existing value is replaced by
+ * @code{value}
+ * and the function returns true. If there was no previous @code{key}
+ * in the shash then this function returns false.
+ */
+#define shash_insert(h,key,value) _shash_insert((h),(key),&(value))
+extern int _shash_insert (shash, const char *key, const void *value);
+
+/* Function: shash_erase - erase a key from a shash
+ *
+ * Erase @code{key} from the shash. If an element was erased,
+ * this returns true, else this returns false.
+ */
+extern int shash_erase (shash, const char *key);
+
+/* Function: shash_keys - return a vector of the keys or values in a shash
+ * Function: shash_keys_in_pool
+ * Function: shash_values
+ * Function: shash_values_in_pool
+ * 
+ * Return a vector containing all the keys or values of shash. The
+ * @code{*_in_pool} variants allow you to allocate the vector in
+ * another pool (the default is to allocate the vector in the same
+ * pool as the shash).
+ */
+extern vector shash_keys (shash);
+extern vector shash_keys_in_pool (shash, pool);
+extern vector shash_values (shash);
+extern vector shash_values_in_pool (shash, pool);
+
+/* Function: shash_size - return the number of (key, value) pairs in a shash
+ *
+ * Count the number of (key, value) pairs in the shash.
+ */
+extern int shash_size (shash);
+
+/* Function: shash_get_buckets_used - return the number of buckets in a shash
+ * Function: shash_get_buckets_allocated
+ *
+ * Return the number of shash buckets used and allocated. The number of
+ * buckets allocated is always a power of 2. See also
+ * @ref{shash_set_buckets_allocated} to change the number used
+ * in the shash.
+ */
+extern int shash_get_buckets_used (shash);
+extern int shash_get_buckets_allocated (shash);
+
+/* Function: shash_set_buckets_allocated - set the number of buckets
+ *
+ * Set the number of buckets allocated. You may ONLY do this when you
+ * have just created the shash and before you have inserted any elements.
+ * Otherwise the results are undefined (and probably bad). The number
+ * of buckets MUST be a power of 2.
+ */
+extern void shash_set_buckets_allocated (shash, int);
+
+#endif /* HASH_H */
diff --git a/matvec.c b/matvec.c
new file mode 100644 (file)
index 0000000..f8c033e
--- /dev/null
+++ b/matvec.c
@@ -0,0 +1,909 @@
+/* Matrix and vector arithmetic.
+ * By Richard W.M. Jones <rich@annexia.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id: matvec.c,v 1.5 2002/05/04 11:54:23 rich Exp $
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include "matvec.h"
+
+float identity_matrix[16] = {
+  1, 0, 0, 0,
+  0, 1, 0, 0,
+  0, 0, 1, 0,
+  0, 0, 0, 1
+};
+
+float zero_vec[4] = { 0, 0, 0, 1 };
+
+float *
+new_identity_matrix (pool pool)
+{
+  float *m = new_matrix (pool);
+  make_identity_matrix (m);
+  return m;
+}
+
+float *
+new_zero_vec (pool pool)
+{
+  float *v = new_vec (pool);
+  make_zero_vec (v);
+  return v;
+}
+
+/* This code is taken from Mesa 3.0. I have exchanged degrees for radians. */
+void
+make_rotation_matrix (float angle,
+                     float x, float y, float z,
+                     float *m)
+{
+  /* This function contributed by Erich Boleyn (erich@uruk.org) */
+  float mag, s, c;
+  float xx, yy, zz, xy, yz, zx, xs, ys, zs, one_c;
+
+  s = sin(angle);
+  c = cos(angle);
+
+  mag = sqrt ( x*x + y*y + z*z );
+
+  if (mag == 0.0) {
+    /* generate an identity matrix and return */
+    make_identity_matrix (m);
+    return;
+  }
+
+  x /= mag;
+  y /= mag;
+  z /= mag;
+
+#define M(row,col)  m[col*4+row]
+
+  /*
+   *     Arbitrary axis rotation matrix.
+   *
+   *  This is composed of 5 matrices, Rz, Ry, T, Ry', Rz', multiplied
+   *  like so:  Rz * Ry * T * Ry' * Rz'.  T is the final rotation
+   *  (which is about the X-axis), and the two composite transforms
+   *  Ry' * Rz' and Rz * Ry are (respectively) the rotations necessary
+   *  from the arbitrary axis to the X-axis then back.  They are
+   *  all elementary rotations.
+   *
+   *  Rz' is a rotation about the Z-axis, to bring the axis vector
+   *  into the x-z plane.  Then Ry' is applied, rotating about the
+   *  Y-axis to bring the axis vector parallel with the X-axis.  The
+   *  rotation about the X-axis is then performed.  Ry and Rz are
+   *  simply the respective inverse transforms to bring the arbitrary
+   *  axis back to it's original orientation.  The first transforms
+   *  Rz' and Ry' are considered inverses, since the data from the
+   *  arbitrary axis gives you info on how to get to it, not how
+   *  to get away from it, and an inverse must be applied.
+   *
+   *  The basic calculation used is to recognize that the arbitrary
+   *  axis vector (x, y, z), since it is of unit length, actually
+   *  represents the sines and cosines of the angles to rotate the
+   *  X-axis to the same orientation, with theta being the angle about
+   *  Z and phi the angle about Y (in the order described above)
+   *  as follows:
+   *
+   *  cos ( theta ) = x / sqrt ( 1 - z^2 )
+   *  sin ( theta ) = y / sqrt ( 1 - z^2 )
+   *
+   *  cos ( phi ) = sqrt ( 1 - z^2 )
+   *  sin ( phi ) = z
+   *
+   *  Note that cos ( phi ) can further be inserted to the above
+   *  formulas:
+   *
+   *  cos ( theta ) = x / cos ( phi )
+   *  sin ( theta ) = y / sin ( phi )
+   *
+   *  ...etc.  Because of those relations and the standard trigonometric
+   *  relations, it is pssible to reduce the transforms down to what
+   *  is used below.  It may be that any primary axis chosen will give the
+   *  same results (modulo a sign convention) using thie method.
+   *
+   *  Particularly nice is to notice that all divisions that might
+   *  have caused trouble when parallel to certain planes or
+   *  axis go away with care paid to reducing the expressions.
+   *  After checking, it does perform correctly under all cases, since
+   *  in all the cases of division where the denominator would have
+   *  been zero, the numerator would have been zero as well, giving
+   *  the expected result.
+   */
+
+  xx = x * x;
+  yy = y * y;
+  zz = z * z;
+  xy = x * y;
+  yz = y * z;
+  zx = z * x;
+  xs = x * s;
+  ys = y * s;
+  zs = z * s;
+  one_c = 1.0F - c;
+
+  M(0,0) = (one_c * xx) + c;
+  M(0,1) = (one_c * xy) - zs;
+  M(0,2) = (one_c * zx) + ys;
+  M(0,3) = 0.0F;
+
+  M(1,0) = (one_c * xy) + zs;
+  M(1,1) = (one_c * yy) + c;
+  M(1,2) = (one_c * yz) - xs;
+  M(1,3) = 0.0F;
+
+  M(2,0) = (one_c * zx) - ys;
+  M(2,1) = (one_c * yz) + xs;
+  M(2,2) = (one_c * zz) + c;
+  M(2,3) = 0.0F;
+
+  M(3,0) = 0.0F;
+  M(3,1) = 0.0F;
+  M(3,2) = 0.0F;
+  M(3,3) = 1.0F;
+
+#undef M
+}
+
+void
+make_translation_matrix (float x, float y, float z, float *m)
+{
+  make_identity_matrix (m);
+  m[12] = x;
+  m[13] = y;
+  m[14] = z;
+}
+
+void
+make_scaling_matrix (float x, float y, float z, float *m)
+{
+  make_identity_matrix (m);
+  m[0] = x;
+  m[5] = y;
+  m[10] = z;
+}
+
+/* The next two functions are from the matrix FAQ by <hexapod@netcom.com>, see:
+ * http://www.flipcode.com/documents/matrfaq.html
+ */
+
+/* Quickly convert 3 Euler angles to a rotation matrix. */
+void
+matrix_euler_to_rotation (float angle_x, float angle_y, float angle_z,
+                         float *mat)
+{
+  float A       = cos(angle_x);
+  float B       = sin(angle_x);
+  float C       = cos(angle_y);
+  float D       = sin(angle_y);
+  float E       = cos(angle_z);
+  float F       = sin(angle_z);
+
+  float AD      =   A * D;
+  float BD      =   B * D;
+
+  mat[0]  =   C * E;
+  mat[4]  =  -C * F;
+  mat[8]  =  -D;
+  mat[1]  = -BD * E + A * F;
+  mat[5]  =  BD * F + A * E;
+  mat[9]  =  -B * C;
+  mat[2]  =  AD * E + B * F;
+  mat[6]  = -AD * F + B * E;
+  mat[10] =   A * C;
+
+  mat[12]  =  mat[13] = mat[14] = mat[3] = mat[7] = mat[11] = 0;
+  mat[15] =  1;
+}
+
+static inline float
+clamp (float v, float low, float high)
+{
+  /* This is not very efficient ... */
+  v -= low;
+  while (v > high - low) v -= high - low;
+  while (v < 0) v += high - low;
+  v += low;
+  return v;
+}
+
+/* Convert a rotation matrix to 3 Euler angles. */
+void
+matrix_rotation_to_euler (const float *mat,
+                         float *angle_x, float *angle_y, float *angle_z)
+{
+  float C, trx, try;
+
+  *angle_y = -asin( mat[8]);        /* Calculate Y-axis angle */
+  C           =  cos( *angle_y );
+
+  if ( fabs( C ) > 0.005 )             /* Gimball lock? */
+    {
+      trx      =  mat[10] / C;           /* No, so get X-axis angle */
+      try      = -mat[9]  / C;
+
+      *angle_x  = atan2( try, trx );
+
+      trx      =  mat[0] / C;            /* Get Z-axis angle */
+      try      = -mat[4] / C;
+
+      *angle_z  = atan2( try, trx );
+    }
+  else                                 /* Gimball lock has occurred */
+    {
+      trx      = mat[5];                 /* And calculate Z-axis angle */
+      try      = mat[1];
+
+      *angle_z  = atan2( try, trx );
+    }
+
+  /* Clamp all angles to range */
+  *angle_x = clamp (*angle_x, 0, 2 * M_PI);
+  *angle_y = clamp (*angle_y, 0, 2 * M_PI);
+  *angle_z = clamp (*angle_z, 0, 2 * M_PI);
+}
+
+/* This code is taken from Mesa 3.0.
+ */
+void
+matrix_multiply (const float *a, const float *b,
+                float *product)
+{
+   /* This matmul was contributed by Thomas Malik */
+  int i;
+
+#define A(row,col)  a[(col<<2)+row]
+#define B(row,col)  b[(col<<2)+row]
+#define P(row,col)  product[(col<<2)+row]
+
+   /* i-te Zeile */
+   for (i = 0; i < 4; i++) {
+     float ai0=A(i,0),  ai1=A(i,1),  ai2=A(i,2),  ai3=A(i,3);
+     P(i,0) = ai0 * B(0,0) + ai1 * B(1,0) + ai2 * B(2,0) + ai3 * B(3,0);
+     P(i,1) = ai0 * B(0,1) + ai1 * B(1,1) + ai2 * B(2,1) + ai3 * B(3,1);
+     P(i,2) = ai0 * B(0,2) + ai1 * B(1,2) + ai2 * B(2,2) + ai3 * B(3,2);
+     P(i,3) = ai0 * B(0,3) + ai1 * B(1,3) + ai2 * B(2,3) + ai3 * B(3,3);
+   }
+
+#undef A
+#undef B
+#undef P
+}
+
+/* Multiply matrix by vector. */
+void
+matrix_vec_multiply (const float *m, const float *v,
+                    float *result)
+{
+  result[0] = m[0]*v[0] + m[1]*v[1] + m[2]*v[2] + m[3]*v[3];
+  result[1] = m[4]*v[0] + m[5]*v[1] + m[6]*v[2] + m[7]*v[3];
+  result[2] = m[8]*v[0] + m[9]*v[1] + m[10]*v[2] + m[11]*v[3];
+  result[3] = m[12]*v[0] + m[13]*v[1] + m[14]*v[2] + m[15]*v[3];
+}
+
+/* Compute the magnitude of a vector. */
+float
+vec_magnitude (const float *v)
+{
+  return sqrt (v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
+}
+
+/* Compute the magnitude of a 2D vector. */
+float
+vec_magnitude2d (const float *v)
+{
+  return sqrt (v[0]*v[0] + v[1]*v[1]);
+}
+
+/* Normalize a vector. */
+void
+vec_normalize (const float *v, float *r)
+{
+  float w = vec_magnitude (v);
+  r[0] = v[0] / w;
+  r[1] = v[1] / w;
+  r[2] = v[2] / w;
+}
+
+/* Normalize a 2D vector. */
+void
+vec_normalize2d (const float *v, float *r)
+{
+  float w = vec_magnitude2d (v);
+  r[0] = v[0] / w;
+  r[1] = v[1] / w;
+}
+
+void
+vec_unit_normal_to_side (float *side, float *normal)
+{
+  float n[3] = { side[0], side[1], side[2] };
+  vec_normalize (n, normal);
+}
+
+/* Compute the dot product of two vectors. */
+float
+vec_dot_product (const float *v1, const float *v2)
+{
+  return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];
+}
+
+/* Compute the magnitude of vector v1 in direction vector v2.
+ * If v1 == v2, this returns 1. If v1 = -v2, this returns -1.
+ * If v1 is perpendicular to v2 this returns 0.
+ */
+float
+vec_magnitude_in_direction (const float *v1, const float *v2)
+{
+  static float v1n[3], v2n[3];
+
+  /* Normalize both vectors. */
+  vec_normalize (v1, v1n);
+  vec_normalize (v2, v2n);
+
+  /* Return their dot product. */
+  return vec_dot_product (v1n, v2n);
+}
+
+/* Compute angle between two vectors. */
+float
+vec_angle_between (const float *v1, const float *v2)
+{
+  return acos (vec_magnitude_in_direction (v1, v2));
+}
+
+/* Scale a vector. */
+void
+vec_scale (const float *a, float n, float *r)
+{
+  r[0] = a[0] * n;
+  r[1] = a[1] * n;
+  r[2] = a[2] * n;
+}
+
+/* Add two vectors. */
+void
+vec_add (const float *a, const float *b, float *r)
+{
+  r[0] = a[0] + b[0];
+  r[1] = a[1] + b[1];
+  r[2] = a[2] + b[2];
+}
+
+/* Subtract two vectors. */
+void
+vec_subtract (const float *a, const float *b, float *r)
+{
+  r[0] = a[0] - b[0];
+  r[1] = a[1] - b[1];
+  r[2] = a[2] - b[2];
+}
+
+/* Calculate midpoint. */
+void
+point_midpoint (const float *p1, const float *p2, float *mp)
+{
+  mp[0] = (p1[0] + p2[0]) / 2;
+  mp[1] = (p1[1] + p2[1]) / 2;
+  mp[2] = (p1[2] + p2[2]) / 2;
+}
+
+/* Calculate midpoint (in 2D). */
+void
+point_midpoint2d (const float *p1, const float *p2, float *mp)
+{
+  mp[0] = (p1[0] + p2[0]) / 2;
+  mp[1] = (p1[1] + p2[1]) / 2;
+}
+
+/* Distance between two points. */
+float
+point_distance_to_point (const float *p1, const float *p2)
+{
+  float v[3];
+
+  vec_subtract (p1, p2, v);
+  return vec_magnitude (v);
+}
+
+/* Cross product of vectors v and w.
+ * The cross product is a vector:
+ *
+ *   v x w = |v| |w| sin t n^
+ *
+ * where t is the angle between a and
+ * b, and n^ is a normal vector perpendicular
+ * to a and b such that a,b,n^ form a
+ * right-handed set.
+ */
+void
+vec_cross_product (const float *v, const float *w, float *r)
+{
+  r[0] = v[1]*w[2] - v[2]*w[1];
+  r[1] = v[2]*w[0] - v[0]*w[2];
+  r[2] = v[0]*w[1] - v[1]*w[0];
+}
+
+/* Distance between two points. */
+float
+point_distance (const float *p, const float *q)
+{
+  double x = p[0] - q[0];
+  double y = p[1] - q[1];
+  double z = p[2] - q[2];
+  return sqrt (x*x + y*y + z*z);
+}
+
+/* Distance from a point to a plane. */
+float
+point_distance_to_plane (const float *plane, const float *point)
+{
+  float a = plane[0];
+  float b = plane[1];
+  float c = plane[2];
+  float d = plane[3];
+  float x = point[0];
+  float y = point[1];
+  float z = point[2];
+  float t = (a*x + b*y + c*z + d) / - (a*a + b*b + c*c);
+  float t2 = t*t;
+  float dist = sqrt (t2*a*a + t2*b*b + t2*c*c);
+  /* Don't lose the sign of t. */
+  if (t < 0) return dist; else return -dist;
+}
+
+/* Return true if point_distance_to_plane > 0. */
+int
+point_is_inside_plane (const float *plane, const float *point)
+{
+  float a = plane[0];
+  float b = plane[1];
+  float c = plane[2];
+  float d = plane[3];
+  float x = point[0];
+  float y = point[1];
+  float z = point[2];
+  float t = (a*x + b*y + c*z + d) / - (a*a + b*b + c*c);
+
+  return t < 0;
+
+#if 0
+  float t2 = t*t;
+  float dist = sqrt (t2*a*a + t2*b*b + t2*c*c);
+  /* Don't lose the sign of t. */
+  if (t < 0) return dist; else return -dist;
+#endif
+}
+
+/* See: http://www.greuer.de/efaq.html */
+void
+point_footprint_on_line (const float *point,
+                        const float *line_point, const float *line_vector,
+                        float *footprint)
+{
+  float t;
+  float s[3];
+
+  vec_subtract (point, line_point, s);
+  t = vec_dot_product (s, line_vector) /
+      vec_dot_product (line_vector, line_vector);
+
+  vec_scale (line_vector, t, s);
+  vec_add (line_point, s, footprint);
+}
+
+float
+point_distance_to_line (const float *point,
+                       const float *line_point, const float *line_vector)
+{
+#if 0
+  float footprint[3];
+
+  point_footprint_on_line (point, line_point, line_vector, footprint);
+  return point_distance_to_point (point, footprint);
+#else
+  float u[3], p[3], prod[3], dist;
+
+  /* Normalize vector u along the line. */
+  vec_normalize (line_vector, u);
+
+  /* The distance is given by | (p-a) x u | where p is the
+   * point, a is a point on the line and x is the cross product.
+   */
+  vec_subtract (point, line_point, p);
+  vec_cross_product (p, u, prod);
+  dist = vec_magnitude (prod);
+
+  return dist;
+#endif
+}
+
+float
+point_distance_to_line_segment (const float *point,
+                               const float *line_point0,
+                               const float *line_point1)
+{
+  float t;
+  float s[3], v[3];
+
+  vec_subtract (line_point1, line_point0, v);
+  vec_subtract (point, line_point0, s);
+  t = vec_dot_product (s, v) /
+      vec_dot_product (v, v);
+
+  if (t >= 0 && t <= 1)
+    {
+      float footprint[3];
+
+      vec_scale (v, t, s);
+      vec_add (line_point0, s, footprint);
+      return point_distance_to_point (point, footprint);
+    }
+  else if (t < 0)
+    return point_distance_to_point (point, line_point0);
+  /* else t > 1 */
+  return point_distance_to_point (point, line_point1);
+}
+
+int
+point_lies_in_face (const float *points, int nr_points, const float *point)
+{
+  float sum = point_face_angle_sum (points, nr_points, point);
+  return fabs (sum - 2*M_PI) < 1e-5;
+}
+
+/* See: http://astronomy.swin.edu.au/pbourke/geometry/insidepoly/ */
+float
+point_face_angle_sum (const float *points, int nr_points, const float *point)
+{
+  float sum = 0;
+  int i, next;
+
+  for (i = 0, next = 1; i < nr_points; ++i, ++next)
+    {
+      float p1[3], p2[3], m1, m2, costheta;
+
+      if (next == nr_points) next = 0;
+
+      p1[0] = points[i*3] - point[0];
+      p1[1] = points[i*3+1] - point[1];
+      p1[2] = points[i*3+2] - point[2];
+      p2[0] = points[next*3] - point[0];
+      p2[1] = points[next*3+1] - point[1];
+      p2[2] = points[next*3+2] - point[2];
+
+      m1 = vec_magnitude (p1);
+      m2 = vec_magnitude (p2);
+
+      if (m1 * m2 < 1e-5)
+       return 2 * M_PI;
+      else
+       costheta = (p1[0]*p2[0] + p1[1]*p2[1] + p1[2]*p2[2]) / (m1*m2);
+
+      sum += acos (costheta);
+    }
+
+  return sum;
+}
+
+float
+point_distance_to_face (const float *points, int nr_points,
+                       const float *plane, const float *point, int *edge)
+{
+  float my_plane_coeffs[4];
+  float a, b, c, d, tq, q[3], dist;
+  int e, i, next;
+
+  /* Calculate plane coefficients, if necessary. */
+  if (plane == 0)
+    {
+      plane = my_plane_coeffs;
+      plane_coefficients (&points[0], &points[3], &points[6], (float *) plane);
+    }
+
+  a = plane[0];
+  b = plane[1];
+  c = plane[2];
+  d = plane[3];
+
+  /* q is the coordinate of the point of intersection of a
+   * normal line from the point to the plane. It may or may
+   * not be on the bounded face (we'll work that out in the
+   * moment). tq is the parameter of point q.
+   */
+  tq = - (a*point[0] + b*point[1] + c*point[2] + d) / (a*a + b*b + c*c);
+  q[0] = point[0] + tq*a;
+  q[1] = point[1] + tq*b;
+  q[2] = point[2] + tq*c;
+
+  /* Is q on the bounded face? */
+  if (point_lies_in_face (points, nr_points, q))
+    {
+      /* Compute the distance from the point to the plane. */
+      float t2 = tq*tq;
+
+      dist = sqrt (t2*a*a + t2*b*b + t2*c*c);
+
+      if (edge) *edge = -1;
+
+      return tq < 0 ? dist : -dist;
+    }
+
+  /* Find the closest edge. */
+  e = -1;
+  dist = 0;
+
+  for (i = 0, next = 1; i < nr_points; ++i, ++next)
+    {
+      float d;
+
+      if (next == nr_points) next = 0;
+
+      d = point_distance_to_line_segment (point,
+                                         &points[i*3], &points[next*3]);
+
+      if (e == -1 || d < dist)
+       {
+         dist = d;
+         e = i;
+       }
+    }
+
+  if (edge) *edge = e;
+
+  return tq < 0 ? dist : -dist;
+}
+
+/* Compute the four coefficients of a plane which
+ * uniquely specify that plane, given three points
+ * (not colinear) on the plane. Most of the variables
+ * in this function are redundant (optimized out?),
+ * but they get it into the same form as in
+ * Lansdown, p. 178.
+ */
+void
+plane_coefficients (const float *p, const float *q, const float *r,
+                   float *co)
+{
+  float x2 = p[0];
+  float y2 = p[1];
+  float z2 = p[2];
+  float x1 = q[0];
+  float y1 = q[1];
+  float z1 = q[2];
+  float x3 = r[0];
+  float y3 = r[1];
+  float z3 = r[2];
+  float xa = x1 + x2;
+  float xb = x2 + x3;
+  float xc = x3 + x1;
+  float ya = y1 + y2;
+  float yb = y2 + y3;
+  float yc = y3 + y1;
+  float za = z1 + z2;
+  float zb = z2 + z3;
+  float zc = z3 + z1;
+
+  co[0] = (y1-y2) * za + (y2-y3) * zb + (y3-y1) * zc;
+  co[1] = (z1-z2) * xa + (z2-z3) * xb + (z3-z1) * xc;
+  co[2] = (x1-x2) * ya + (x2-x3) * yb + (x3-x1) * yc;
+  co[3] = - (co[0]*x1 + co[1]*y1 + co[2]*z1);
+}
+
+void
+plane_translate_along_normal (const float *plane, float distance,
+                             float *new_plane)
+{
+  float w = vec_magnitude (plane);
+
+  new_plane[0] = plane[0];
+  new_plane[1] = plane[1];
+  new_plane[2] = plane[2];
+  new_plane[3] = plane[3] - w * distance;
+}
+
+void
+face_translate_along_normal (const float *points, int nr_points,
+                            const float *plane, float distance,
+                            float *new_points, float *new_plane)
+{
+  float w = vec_magnitude (plane), nv[3];
+  int i;
+
+  new_plane[0] = plane[0];
+  new_plane[1] = plane[1];
+  new_plane[2] = plane[2];
+  new_plane[3] = plane[3] - w * distance;
+
+  vec_scale (plane, distance / w, nv);
+  for (i = 0; i < nr_points; ++i)
+    {
+      new_points[i*3] = points[i*3] + nv[0];
+      new_points[i*3+1] = points[i*3+1] + nv[1];
+      new_points[i*3+2] = points[i*3+2] + nv[2];
+    }
+}
+
+/* All these quaternion functions are modified from the matrix FAQ again. */
+void
+quaternion_normalize (const float *a, float *r)
+{
+  float w = vec_magnitude (a);
+  r[0] = a[0] / w;
+  r[1] = a[1] / w;
+  r[2] = a[2] / w;
+  r[3] = a[3] / w;
+}
+
+void
+quaternion_conjugate (const float *a, float *r)
+{
+  r[0] = -a[0];
+  r[1] = -a[1];
+  r[2] = -a[2];
+  r[3] = a[3];
+}
+
+float
+quaternion_magnitude (const float *a)
+{
+  return sqrt (a[3]*a[3] + a[0]*a[0] + a[1]*a[1] + a[2]*a[2]);
+}
+
+void
+quaternion_multiply (const float *a, const float *b, float *r)
+{
+  float va[3], vb[3], vc[3];
+
+  r[3] = vec_dot_product (a, b);
+
+  vec_cross_product (a, b, va);
+  vec_scale (a, b[3], vb);
+  vec_scale (b, a[3], vc);
+  vec_add (va, vb, va);
+  vec_add (va, vc, r);
+
+  quaternion_normalize (r, r);
+}
+
+void
+quaternion_to_rotation_matrix (const float *q, float *mat)
+{
+  float X = q[0];
+  float Y = q[1];
+  float Z = q[2];
+  float W = q[3];
+
+  float xx      = X * X;
+  float xy      = X * Y;
+  float xz      = X * Z;
+  float xw      = X * W;
+
+  float yy      = Y * Y;
+  float yz      = Y * Z;
+  float yw      = Y * W;
+
+  float zz      = Z * Z;
+  float zw      = Z * W;
+
+  mat[0]  = 1 - 2 * ( yy + zz );
+  mat[4]  =     2 * ( xy - zw );
+  mat[8]  =     2 * ( xz + yw );
+
+  mat[1]  =     2 * ( xy + zw );
+  mat[5]  = 1 - 2 * ( xx + zz );
+  mat[9]  =     2 * ( yz - xw );
+
+  mat[2]  =     2 * ( xz - yw );
+  mat[6]  =     2 * ( yz + xw );
+  mat[10] = 1 - 2 * ( xx + yy );
+
+  mat[3]  = mat[7] = mat[11] = mat[12] = mat[13] = mat[14] = 0;
+  mat[15] = 1;
+}
+
+void
+make_quaternion_from_axis_angle (const float *axis, float angle,
+                                float *q)
+{
+  double sin_a = sin (angle / 2);
+  double cos_a = cos (angle / 2);
+
+  q[0] = axis[0] * sin_a;
+  q[1] = axis[1] * sin_a;
+  q[2] = axis[2] * sin_a;
+  q[3] = cos_a;
+
+  quaternion_normalize (q, q);
+}
+
+int
+collision_moving_sphere_and_face (const float *p0, const float *p1,
+                                 float radius,
+                                 const float *points, int nr_points,
+                                 const float *plane,
+                                 float *collision_point)
+{
+  float my_plane_coeffs[4], raised_plane[4], t, v[3], quot;
+  float raised_points[3 * nr_points];
+
+  /* Get the plane coefficients. */
+  if (plane == 0)
+    {
+      plane = my_plane_coeffs;
+      plane_coefficients (&points[0], &points[3], &points[6], (float *) plane);
+    }
+
+  /* Raise the plane up by the distance of one radius. Then we can
+   * just test for the intersection of the ray and the face.This is
+   * something of an approximation, but hopefully will give us good
+   * results in practice. If not, then we may need to rework this
+   * code. (XXX)
+   */
+  face_translate_along_normal (points, nr_points, plane, radius,
+                              raised_points, raised_plane);
+
+  /* Get the intersection point of the ray and the plane, as a
+   * parameter, t.
+   */
+  vec_subtract (p1, p0, v);
+  quot = raised_plane[0]*v[0] + raised_plane[1]*v[1] + raised_plane[2]*v[2];
+  if (fabs (quot)
+#if 0
+      < 1e-5
+#else
+      == 0
+#endif
+      )
+    {
+      /* The path of the sphere is nearly parallel to the plane. Don't
+       * count this as a collision at all.
+       */
+      return 0;
+    }
+
+  t = - (raised_plane[0]*p0[0] + raised_plane[1]*p0[1] + raised_plane[2]*p0[2]
+        + raised_plane[3]) / quot;
+  if (t < 0 || t > 1)
+    {
+      /* There is no collision. */
+      return 0;
+    }
+
+  /* Calculate the actual point of collision. NOTE: This is the centre
+   * of the sphere, NOT the point where the sphere and plane touch.
+   */
+  vec_scale (v, t, v);
+  vec_add (p0, v, collision_point);
+
+  /* Is the collision point actually within the bounded convex polygon
+   * which defines the face? If not, then no collision actually
+   * occurred. Note that we have to translate (ie. raise) the points
+   * list too.
+   */
+  return point_lies_in_face (raised_points, nr_points, collision_point);
+}
diff --git a/matvec.h b/matvec.h
new file mode 100644 (file)
index 0000000..240317b
--- /dev/null
+++ b/matvec.h
@@ -0,0 +1,392 @@
+/* Matrix and vector arithmetic.
+ * By Richard W.M. Jones <rich@annexia.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id: matvec.h,v 1.3 2001/11/19 17:10:54 rich Exp $
+ */
+
+#ifndef MATVEC_H
+#define MATVEC_H
+
+#include <pool.h>
+#include <math.h>
+
+/* Notes:
+ *
+ * This library only handles 4x4 matrices and 4-vectors, for
+ * basic 3D graphics use. A matrix is just an array float[16]
+ * and a vector is just an array float[4]. You can either allocate
+ * these in a pool using ``new_matrix'' and ``new_vec'', or
+ * else you can allocate them statically.
+ *
+ * All matrices are stored in COLUMN-MAJOR ORDER! This is for
+ * compatibility with OpenGL, but it is the OPPOSITE of the
+ * normal C row-major ordering, so beware. Matrix elements in
+ * column-major order are as follows:
+ *
+ *   M = | m0  m4  m8  m12 |
+ *       | m1  m5  m9  m13 |
+ *       | m2  m6  m10 m14 |
+ *       | m3  m7  m11 m15 |
+ *
+ * Some of these functions have been inlined. I only inline
+ * functions based on evidence from profiling the code as a
+ * whole or where the function is so simple that the overhead
+ * of calling it is larger than the inlined code. Excessive
+ * inlining can itself cause performance problems, particularly
+ * on modern processors which are very good at making jumps
+ * and function calls.
+ *
+ */
+
+/* Function: new_matrix - allocate a new matrix or vector
+ * Function: new_vec
+ *
+ * @code{new_matrix} allocates a new 4x4 matrix of floats
+ * in @code{pool}.
+ *
+ * @code{new_vec} allocates a new 4-vector of floats in
+ * @code{pool}.
+ *
+ * You may use these functions to allocate matrices and
+ * vectors dynamically, or you may allocate them statically.
+ * The other matrix and vector functions available do not
+ * distriguish between dynamically and statically allocated
+ * variables.
+ *
+ * Note: All matrices are stored in COLUMN-MAJOR ORDER!
+ * This is for compatibility with OpenGL, but it is the
+ * OPPOSITE of the natural C row-major ordering, so beware.
+ *
+ * See also: @ref{new_identity_matrix(3)}, @ref{new_zero_vec(3)}.
+ */
+#define new_matrix(pool) ((float *) pmalloc ((pool), sizeof (float) * 16))
+#define new_vec(pool) ((float *) pmalloc ((pool), sizeof (float) * 4))
+
+/* Variable: identity_matrix - identity matrix and zero vector
+ * Variable: zero_vec
+ * Function: new_identity_matrix
+ * Function: new_zero_vec
+ * Function: make_identity_matrix
+ * Function: make_zero_vec
+ *
+ * The @code{identity_matrix} variable contains a read-only
+ * copy of the identity matrix. The @code{zero_vec} variable
+ * contains a read-only copy of the zero vector.
+ *
+ * Use @code{new_identity_matrix} to allocate a new
+ * identity matrix variable in @code{pool}. Use @code{new_zero_vec}
+ * to similarly allocate a new zero vector.
+ *
+ * Use @code{make_identity_matrix} to copy the identity
+ * matrix over an existing matrix @code{m}. Use @code{make_zero_vec}
+ * to similarly copy the zero vector over an existing vector @code{v}.
+ *
+ * See also: @ref{new_matrix(3)}, @ref{new_vec(3)}.
+ */
+extern float identity_matrix[16];
+extern float zero_vec[4];
+extern float *new_identity_matrix (pool);
+extern float *new_zero_vec (pool);
+#define make_identity_matrix(m) memcpy (m, identity_matrix, sizeof(float)*16);
+#define make_zero_vec(v) memcpy (v, zero_vec, sizeof (float) * 4);
+
+extern void make_rotation_matrix (float angle,
+                                 float x, float y, float z,
+                                 float *m);
+
+extern void make_translation_matrix (float x, float y, float z, float *m);
+
+extern void make_scaling_matrix (float x, float y, float z, float *m);
+
+extern void matrix_euler_to_rotation (float angle_x, float angle_y,
+                                     float angle_z,
+                                     float *mat);
+extern void matrix_rotation_to_euler (const float *mat,
+                                     float *angle_x, float *angle_y,
+                                     float *angle_z);
+
+extern void matrix_multiply (const float *a, const float *b,
+                            float *product);
+
+extern void matrix_vec_multiply (const float *m, const float *v,
+                                float *result);
+
+/* Function: vec_magnitude - calculate magnitude (length) of a vector
+ * Function: vec_magnitude2d
+ *
+ * @code{vec_magnitude} calculates the magnitude (length) of a
+ * 3D vector. @code{vec_magnitude2d} calculates the magnitude
+ * of a 2D vector.
+ *
+ * See also: @ref{vec_normalize(3)}, @ref{vec_normalize2d(3)}.
+ */
+extern float vec_magnitude (const float *v);
+extern float vec_magnitude2d (const float *v);
+
+/* Function: vec_normalize - normalize a vector
+ * Function: vec_normalize2d
+ *
+ * These two functions normalize respectively a 3D or 2D
+ * vector @code{v}. The original vector @code{v} is not touched,
+ * and the result is placed in vector @code{r}.
+ *
+ * To normalize a vector in-place (ie. modifying the original
+ * vector), do:
+ *
+ * @code{vec_normalize (v, v);}
+ *
+ * See also: @ref{vec_magnitude(3)}, @ref{vec_magnitude2d(3)}.
+ */
+extern void vec_normalize (const float *v, float *r);
+extern void vec_normalize2d (const float *v, float *r);
+
+extern void vec_unit_normal_to_side (float *side, float *normal);
+
+/* Function: vec_dot_product - calculate the dot product of two vectors
+ *
+ * @code{vec_dot_product} calculates the dot product of two
+ * vectors @code{v1} and @code{v2} and returns it. The dot
+ * product is formally defined as:
+ *
+ * @code{|v1| |v2| cos theta}
+ *
+ * where @code{theta} is the angle between the two vectors.
+ *
+ * One interesting consequence of this is that if both @code{v1}
+ * and @code{v2} are already normalized, then the dot product
+ * is 1 if the vectors are parallel and running in the same
+ * direction, and 0 if the vectors are
+ * perpendicular.
+ *
+ * See also: @ref{vec_magnitude_in_direction(3)}, @ref{vec_angle_between(3)}
+ */
+extern float vec_dot_product (const float *v1, const float *v2);
+
+/* Function: vec_magnitude_in_direction - calculate relative direction of two vectors
+ *
+ * If @code{v1} and @code{v2} are parallel and point in the
+ * same direction, then @code{vec_magnitude_in_direction} returns +1.
+ * If @code{v1} and @code{v2} are perpendicular, this returns
+ * 0. If @code{v1} and @code{v2} are parallel and point in
+ * opposite directions to each other, this returns -1.
+ * For other vectors, this function returns the cosine of
+ * the angle between the vectors.
+ *
+ * See also: @ref{vec_dot_product(3)}, @ref{vec_angle_between(3)}
+ */
+extern float vec_magnitude_in_direction (const float *v1, const float *v2);
+
+/* Function: vec_angle_between - calculate the angle between two vectors
+ *
+ * This function returns the angle between two vectors
+ * @code{v1} and @code{v2}.
+ *
+ * See also: @ref{vec_dot_product(3)}, @ref{vec_magnitude_in_direction(3)}
+ */
+extern float vec_angle_between (const float *v1, const float *v2);
+
+extern void vec_cross_product (const float *v, const float *w, float *r);
+
+extern void vec_scale (const float *a, float n, float *r);
+extern void vec_add (const float *a, const float *b, float *r);
+extern void vec_subtract (const float *a, const float *b, float *r);
+
+float point_distance_to_point (const float *p1, const float *p2);
+
+extern void point_midpoint (const float *p1, const float *p2, float *mp);
+extern void point_midpoint2d (const float *p1, const float *p2, float *mp);
+extern float point_distance (const float *p, const float *q);
+
+/* Function: point_distance_to_plane - distance from point to plane
+ * Function: point_is_inside_plane
+ *
+ * @code{point_distance_to_plane} calculates the (shortest) distance from
+ * the point @code{point} to the plane @code{plane}. This distance is
+ * positive if the point is "inside" the plane -- that is, if the
+ * normal vector drawn from the plane points towards the point. It
+ * is negative if the point is "outside" the plane. It is zero if the
+ * point lies on the plane.
+ *
+ * @code{point_is_inside_plane} returns true if the point is strictly
+ * inside the plane, and false if the point lies on the plane or is
+ * outside. It is much faster to compute this than to use
+ * @code{point_distance_to_plane} and take the sign of the result.
+ *
+ * See also: @ref{plane_coefficients(3)}, @ref{point_distance_to_face(3)}.
+ */
+extern float point_distance_to_plane (const float *plane, const float *point);
+extern int point_is_inside_plane (const float *plane, const float *point);
+
+extern void point_footprint_on_line (const float *point, const float *line_point, const float *line_vector, float *footprint);
+
+/* Function: point_distance_to_line - shortest distance from a point to a line
+ *
+ * Given a @code{point} and a line, expressed as @code{line_point}
+ * and parallel @code{line_vector}, compute the shortest distance
+ * from the point to the line.
+ *
+ * See also: @ref{point_distance_to_plane(3)}, @ref{point_distance_to_face(3)},
+ * @ref{point_distance_to_line_segment(3)}.
+ */
+extern float point_distance_to_line (const float *point, const float *line_point, const float *line_vector);
+
+/* Function: point_distance_to_line_segment - shortest distance from a point to a line segment
+ *
+ * Given a @code{point} and a line segment from @code{line_point0} to
+ * @code{line_point1}, compute the shortest distance from the
+ * point to the line segment.
+ *
+ * See also: @ref{point_distance_to_line(3)}.
+ */
+extern float point_distance_to_line_segment (const float *point, const float *line_point0, const float *line_point1);
+
+/* Function: point_lies_in_face - does a point lie on the interior of a bounded convex polygon
+ * Function: point_face_angle_sum
+ *
+ * Take a bounded convex polygon (a "face") and a point. The function
+ * @code{point_lies_in_face} returns true iff the point is both
+ * (a) coplanar with the face, and
+ * (b) lies inside the edges of the face.
+ *
+ * In order to do this, @code{point_lies_in_face} calls
+ * @code{point_face_angle_sum} which works out the sum of
+ * the interior angles. If conditions (a) and (b) are both
+ * satisfied then the sum of the interior angles will be
+ * very close to 2.PI.
+ *
+ * The face is expressed as a flat list of points (3-vectors).
+ *
+ * See also: @ref{plane_coefficients(3)}, @ref{point_distance_to_face(3)}.
+ */
+extern int point_lies_in_face (const float *points, int nr_points, const float *point);
+extern float point_face_angle_sum (const float *points, int nr_points, const float *point);
+
+/* Function: point_distance_to_face - distance from point to bounded convex polygon (face)
+ *
+ * Given a point and a bounded convex polygon (a "face"), the
+ * function @code{point_distance_to_face} calculates the distance
+ * from the point to the face. There are two importance cases to
+ * consider here:
+ *
+ * (a) The point is directly above or below the face. In other words,
+ * a line dropped from the point perpendicular to the face intersects
+ * the face within the boundary of the polygon. In this case, the
+ * function returns the shortest distance from the point to the
+ * intersection (and is essentially equivalent to
+ * @code{point_distance_to_plane}).
+ *
+ * (b) The point is not directly above or below the face. In this case
+ * the function works out the distance to the nearest edge of the face.
+ *
+ * The face is specified as a list of points and a plane (ie.
+ * plane coefficients). If @code{plane} is @code{NULL}, then the
+ * function calls @ref{plane_coefficients(3)} on your behalf. If
+ * the face is fixed, and you will call this function lots of
+ * times, then it is a good idea to calculate the plane coefficients
+ * once only and cache them.
+ *
+ * Returns: The distance of the point from the face. The distance
+ * will be positive if the point is above the face (ie. inside
+ * the plane: see @ref{point_distance_to_plane(3)}), or negative
+ * otherwise.
+ *
+ * If @code{edge} is not @code{NULL}, then it is set to one of
+ * the following values:
+ *
+ * @code{*edge == -1} if the point is directly above or below
+ * the face, corresponding to case (a) above.
+ *
+ * @code{*edge == 0 .. nr_points-1} if the point is closest to
+ * that particular edge, corresponding to case (b) above.
+ *
+ * See also: @ref{point_distance_to_plane(3)},
+ * @ref{plane_coefficients(3)}, @ref{point_lies_in_face(3)},
+ * @ref{point_distance_to_line(3)}.
+ */
+extern float point_distance_to_face (const float *points, int nr_points, const float *plane, const float *point, int *edge);
+
+/* Function: plane_coefficients - calculate the coefficient form for a plane
+ *
+ * Given three points, not colinear, which naturally form a plane, calculate
+ * the 4-vector form for the plane coefficients. The three points
+ * are passed as @code{p}, @code{q} and @code{r}. The coefficients
+ * are returned in vector @code{co}.
+ *
+ * The four coefficients returned are respectively @code{a}, @code{b},
+ * @code{c} and @code{d} in the standard plane equation:
+ *
+ * @code{a x + b y + c z + d = 0}
+ *
+ * (Note that many texts use @code{- d}, so be warned).
+ *
+ * The normal (perpendicular) vector to the plane may be derived
+ * immediately: it is just @code{(a, b, c)}. Note that the normal
+ * vector is not normalized!
+ *
+ * Planes are unbounded: they stretch off to infinity in all directions.
+ * If what you really want are bounded convex polygons, then you
+ * need to use a c2lib "face".
+ */
+extern void plane_coefficients (const float *p, const float *q, const float *r, float *co);
+
+/* Function: plane_translate_along_normal - translate a plane or face some distance in the direction of the normal
+ * Function: face_translate_along_normal
+ *
+ * Given an existing @code{plane} (expressed as plane coefficients),
+ * produce a new plane @code{new_plane} which has been translated
+ * by @code{distance} units along the direction of the normal. The
+ * new plane is also returned as plane coefficients.
+ *
+ * @code{face_translate_along_normal} is similar, except that it also
+ * translates a list of points by the same distance.
+ *
+ * See also: @ref{plane_coefficients(3)}.
+ */
+extern void plane_translate_along_normal (const float *plane, float distance, float *new_plane);
+extern void face_translate_along_normal (const float *points, int nr_points, const float *plane, float distance, float *new_points, float *new_plane);
+
+extern void quaternion_normalize (const float *a, float *r);
+extern void quaternion_conjugate (const float *a, float *r);
+extern float quaternion_magnitude (const float *a);
+extern void quaternion_multiply (const float *a, const float *b, float *r);
+extern void quaternion_to_rotation_matrix (const float *q, float *mat);
+extern void make_quaternion_from_axis_angle (const float *axis, float angle,
+                                            float *q);
+
+/* Function: collision_moving_sphere_and_face - detect collision between a moving sphere and a fixed face
+ *
+ * This function detects collisions between a sphere which is moving
+ * at constant speed along a linear path and a fixed bounded
+ * convex polygon ("face").
+ *
+ * The centre of the sphere moves from point @code{p0} to point @code{p1}.
+ * The sphere has radius @code{radius}.
+ *
+ * The face is described by the list of bounding points, and the plane
+ * coefficients of the plane of the face (you may pass @code{plane}
+ * as @code{NULL} in which case the function works out the plane
+ * coefficients for you, although this is generally less efficient).
+ *
+ * Returns: If there was a collision, this function returns true and
+ * sets the collision point in @code{collision_point}. Note that the
+ * collision point is the position of the centre of the sphere at
+ * the point of collision, NOT the place where the sphere touches
+ * the face. If there was no collision, this function returns false.
+ */
+extern int collision_moving_sphere_and_face (const float *p0, const float *p1, float radius, const float *points, int nr_points, const float *plane, float *collision_point);
+
+#endif /* MATVEC_H */
diff --git a/pool.c b/pool.c
new file mode 100644 (file)
index 0000000..2155c62
--- /dev/null
+++ b/pool.c
@@ -0,0 +1,488 @@
+/* An Apache-like pool allocator.
+ * By Richard W.M. Jones <rich@annexia.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id: pool.c,v 1.8 2002/10/13 12:25:42 rich Exp $
+ */
+
+#include "config.h"
+
+#if SIZEOF_VOID_P != SIZEOF_LONG
+#error "This library currently assumes that sizeof (void *) == sizeof (long), which is not the case on your platform. This may cause the library to crash at runtime."
+#endif
+
+/* If set, then calls to pmalloc will initialise the memory to 0xefefef...,
+ * helping to catch uninitialised memory problems. This is very useful for
+ * debugging new code, but should be turned off on production systems.
+ */
+#define DEBUG_UNINITIALISED_MEMORY 1
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#include <pool.h>
+
+struct _pool_allocs
+{
+  struct _pool_allocs *next;
+
+  /* The flags field contains:
+   * bit  31    == if set, this structure shouldn't be freed
+   * bits 30-16 == number of slots in the structure
+   * bits 15- 0 == number of slots used in the structure.
+   */
+  unsigned flags;
+
+#define _PA_NO_FREE(pa) ((pa)->flags & 0x80000000U)
+#define _PA_SLOTS(pa) (((pa)->flags & 0x7fff0000U) >> 16)
+#define _PA_SLOTS_USED(pa) ((pa)->flags & 0xffffU)
+
+  void *slot[0];
+} __attribute__((packed));
+
+struct _pool_cleanup_slot
+{
+  void (*fn) (void *);
+  void *data;
+};
+
+struct _pool_cleanups
+{
+  struct _pool_cleanups *next;
+
+  /* The flags field contains:
+   * bit  31    == if set, this structure shouldn't be freed
+   * bits 30-16 == number of slots in the structure
+   * bits 15- 0 == number of slots used in the structure.
+   */
+  unsigned flags;
+
+#define _PC_NO_FREE(pc) ((pc)->flags & 0x80000000U)
+#define _PC_SLOTS(pc) (((pc)->flags & 0x7fff0000U) >> 16)
+#define _PC_SLOTS_USED(pc) ((pc)->flags & 0xffffU)
+
+  struct _pool_cleanup_slot slot[0];
+} __attribute__((packed));
+
+#define INITIAL_PA_SLOTS 16U
+#define MAX_PA_SLOTS     16384U        /* Must be <= 16384 */
+#define INITIAL_PC_SLOTS 2U
+#define MAX_PC_SLOTS     16384U        /* Must be <= 16384 */
+
+struct pool
+{
+  /* If this is a subpool, then this points to the parent. */
+  struct pool *parent_pool;
+
+  /* When subpools are stored on a list, this is used to link the list. */
+  struct pool *next;
+
+  /* Sub-pools. */
+  struct pool *subpool_list;
+
+  /* Pointer to head block of memory allocations. */
+  struct _pool_allocs *allocs;
+
+  /* Pointer to head block of clean-up functions. */
+  struct _pool_cleanups *cleanups;
+};
+
+#ifndef NO_GLOBAL_POOL
+pool global_pool;
+#endif
+
+static int trace_fd = -1;
+static const char *trace_filename = 0;
+
+static void (*bad_malloc_handler) (void) = abort;
+#ifndef NO_GLOBAL_POOL
+static void alloc_global_pool (void) __attribute__((constructor));
+static void free_global_pool (void) __attribute__((destructor));
+#endif
+static void open_trace_file (void) __attribute__((constructor));
+static void trace (const char *fn, void *caller, struct pool *ptr1, void *ptr2, void *ptr3, int i1);
+
+#define TRACE(ptr1, ptr2, ptr3, i1) do { if (trace_filename) trace (__PRETTY_FUNCTION__, __builtin_return_address (0), (ptr1), (ptr2), (ptr3), (i1)); } while (0)
+
+pool
+new_pool ()
+{
+  /* The amount of space required for pool + allocs + cleanups. */
+  const int size
+    = sizeof (struct pool) +
+    sizeof (struct _pool_allocs) +
+    INITIAL_PA_SLOTS * sizeof (void *) +
+    sizeof (struct _pool_cleanups) +
+    INITIAL_PC_SLOTS * sizeof (struct _pool_cleanup_slot);
+
+  pool p = malloc (size);
+  if (p == 0) bad_malloc_handler ();
+
+  memset (p, 0, size);
+
+  p->allocs = (struct _pool_allocs *) ((void *)p + sizeof (struct pool));
+  p->cleanups = (struct _pool_cleanups *)
+    ((void *)p + sizeof (struct pool) + sizeof (struct _pool_allocs)
+     + INITIAL_PA_SLOTS * sizeof (void *));
+
+  p->allocs->flags = 0x80000000U | INITIAL_PA_SLOTS << 16;
+  p->cleanups->flags = 0x80000000U | INITIAL_PC_SLOTS << 16;
+
+  TRACE (p, 0, 0, 0);
+
+  return p;
+}
+
+pool
+new_subpool (pool parent)
+{
+  pool p = new_pool ();
+  p->parent_pool = parent;
+
+  p->next = parent->subpool_list;
+  parent->subpool_list = p;
+
+  TRACE (p, parent, 0, 0);
+
+  return p;
+}
+
+static inline void
+_do_cleanups (pool p)
+{
+  struct _pool_cleanups *pc, *pc_next;
+  int i;
+
+  for (pc = p->cleanups; pc; pc = pc_next)
+    {
+      pc_next = pc->next;
+
+      for (i = 0; i < _PC_SLOTS_USED (pc); ++i)
+       pc->slot[i].fn (pc->slot[i].data);
+      if (!_PC_NO_FREE (pc))
+       free (pc);
+    }
+}
+
+static inline void
+_do_frees (pool p)
+{
+  struct _pool_allocs *pa, *pa_next;
+  int i;
+
+  for (pa = p->allocs; pa; pa = pa_next)
+    {
+      pa_next = pa->next;
+
+      for (i = 0; i < _PA_SLOTS_USED (pa); ++i)
+       free (pa->slot[i]);
+      if (!_PA_NO_FREE (pa))
+       free (pa);
+    }
+}
+
+void
+delete_pool (pool p)
+{
+  _do_cleanups (p);
+
+  /* Clean up any sub-pools. */
+  while (p->subpool_list) delete_pool (p->subpool_list);
+
+  _do_frees (p);
+
+  /* Do I have a parent? If so, remove myself from my parent's subpool
+   * list.
+   */
+  if (p->parent_pool)
+    {
+      pool parent = p->parent_pool, this, last = 0;
+
+      for (this = parent->subpool_list; this; last = this, this = this->next)
+       {
+         if (this == p)
+           {
+             /* Remove this one. */
+             if (last != 0)
+               last->next = this->next;
+             else
+               parent->subpool_list = this->next;
+
+             goto found_me;
+           }
+       }
+
+      abort ();                        /* Oops - self not found on subpool list. */
+    found_me:;
+    }
+
+  free (p);
+
+  TRACE (p, 0, 0, 0);
+}
+
+void *
+pmalloc (pool p, size_t n)
+{
+  void *ptr;
+
+  ptr = malloc (n);
+  if (ptr == 0) bad_malloc_handler ();
+
+#if DEBUG_UNINITIALISED_MEMORY
+  memset (ptr, 0xef, n);
+#endif
+
+  pool_register_malloc (p, ptr);
+
+  TRACE (p, ptr, 0, n);
+
+  return ptr;
+}
+
+void *
+pcalloc (pool p, size_t nmemb, size_t size)
+{
+  void *ptr = pmalloc (p, nmemb * size);
+  if (ptr) memset (ptr, 0, nmemb * size);
+  return ptr;
+}
+
+void *
+prealloc (pool p, void *ptr, size_t n)
+{
+  struct _pool_allocs *pa;
+  int i;
+  void *new_ptr;
+
+  if (ptr == 0)
+    return pmalloc (p, n);
+
+  new_ptr = realloc (ptr, n);
+  if (new_ptr == 0) bad_malloc_handler ();
+
+  /* XXX This is inefficient. We need to search through the
+   * allocations to find this one and update the pointer.
+   */
+  if (ptr != new_ptr)
+    {
+      for (pa = p->allocs; pa; pa = pa->next)
+       {
+         for (i = 0; i < _PA_SLOTS_USED (pa); ++i)
+           if (pa->slot[i] == ptr)
+             {
+               pa->slot[i] = new_ptr;
+               goto found;
+             }
+       }
+      abort ();
+
+    found:;
+    }
+
+  TRACE (p, ptr, new_ptr, n);
+
+  return new_ptr;
+}
+
+void
+pool_register_cleanup_fn (pool p, void (*fn) (void *), void *data)
+{
+  unsigned nr_slots;
+  struct _pool_cleanups *pc;
+
+  if (_PC_SLOTS_USED (p->cleanups) < _PC_SLOTS (p->cleanups))
+    {
+    again:
+      p->cleanups->slot[_PC_SLOTS_USED(p->cleanups)].fn = fn;
+      p->cleanups->slot[_PC_SLOTS_USED(p->cleanups)].data = data;
+      p->cleanups->flags++;
+      return;
+    }
+
+  /* Allocate a new block of cleanup slots. */
+  nr_slots = _PC_SLOTS (p->cleanups);
+  if (nr_slots < MAX_PC_SLOTS)
+    nr_slots *= 2;
+
+  pc = malloc (sizeof (struct _pool_cleanups) +
+              nr_slots * sizeof (struct _pool_cleanup_slot));
+  if (pc == 0) bad_malloc_handler ();
+  pc->next = p->cleanups;
+  pc->flags = nr_slots << 16;
+  p->cleanups = pc;
+
+  goto again;
+}
+
+void
+pool_register_malloc (pool p, void *ptr)
+{
+  unsigned nr_slots;
+  struct _pool_allocs *pa;
+
+  if (_PA_SLOTS_USED (p->allocs) < _PA_SLOTS (p->allocs))
+    {
+    again:
+      p->allocs->slot[_PA_SLOTS_USED(p->allocs)] = ptr;
+      p->allocs->flags++;
+      return;
+    }
+
+  /* Allocate a new block of slots. */
+  nr_slots = _PA_SLOTS (p->allocs);
+  if (nr_slots < MAX_PA_SLOTS)
+    nr_slots *= 2;
+
+  pa = malloc (sizeof (struct _pool_allocs) + nr_slots * sizeof (void *));
+  if (pa == 0) bad_malloc_handler ();
+  pa->next = p->allocs;
+  pa->flags = nr_slots << 16;
+  p->allocs = pa;
+
+  goto again;
+}
+
+static void
+_pool_close (void *fdv)
+{
+  long fd = (long) fdv;
+  close (fd);
+}
+
+void
+pool_register_fd (pool p, int fd)
+{
+  pool_register_cleanup_fn (p, _pool_close, (void *) (long) fd);
+}
+
+#ifndef NO_GLOBAL_POOL
+static void
+alloc_global_pool ()
+{
+  global_pool = new_pool ();
+}
+
+static void
+free_global_pool ()
+{
+  delete_pool (global_pool);
+}
+#endif /* !NO_GLOBAL_POOL */
+
+void (*
+pool_set_bad_malloc_handler (void (*fn) (void))) (void)
+{
+  void (*old_fn) (void) = bad_malloc_handler;
+  bad_malloc_handler = fn;
+  return old_fn;
+}
+
+static int
+_get_struct_size (const pool p)
+{
+  pool subpool;
+  struct _pool_allocs *pa;
+  struct _pool_cleanups *pc;
+  int size;
+
+  size = sizeof (*p);
+
+  for (pa = p->allocs; pa; pa = pa->next)
+    size += sizeof (struct _pool_allocs)
+            + _PA_SLOTS (pa) * sizeof (void *);
+
+  for (pc = p->cleanups; pc; pc = pc->next)
+    size += sizeof (struct _pool_cleanups)
+            + _PC_SLOTS (pc) * sizeof (struct _pool_cleanup_slot);
+
+  for (subpool = p->subpool_list; subpool; subpool = subpool->next)
+    size += _get_struct_size (subpool);
+
+  return size;
+}
+
+static int
+_get_nr_subpools (const pool p)
+{
+  pool subpool;
+  int count = 1;
+
+  for (subpool = p->subpool_list; subpool; subpool = subpool->next)
+    count += _get_nr_subpools (subpool);
+
+  return count;
+}
+
+void
+pool_get_stats (const pool p, struct pool_stats *stats, size_t n)
+{
+  struct pool_stats s;
+
+  s.nr_subpools = _get_nr_subpools (p);
+  s.struct_size = _get_struct_size (p);
+
+  memcpy (stats, &s, n);
+}
+
+static void
+open_trace_file ()
+{
+  char msg1[] =
+    "\n"
+    "Pool allocator running in trace mode.\n"
+    "Trace is being saved to file ";
+  char msg2[] = "\n\n";
+
+  trace_filename = getenv ("POOL_TRACE");
+
+  if (trace_filename)
+    {
+      trace_fd = open (trace_filename, O_WRONLY|O_CREAT|O_TRUNC, 0644);
+      if (trace_fd == -1)
+       {
+         perror (trace_filename);
+         exit (1);
+       }
+
+      write (2, msg1, sizeof msg1);
+      write (2, trace_filename, strlen (trace_filename));
+      write (2, msg2, sizeof msg2);
+    }
+}
+
+static void
+trace (const char *fn, void *caller, struct pool *ptr1, void *ptr2, void *ptr3, int i1)
+{
+  char buffer[128];
+
+  sprintf (buffer,
+          "%s caller: %p ptr1: %p ptr2: %p ptr3: %p i1: %d\n",
+          fn, caller, ptr1, ptr2, ptr3, i1);
+  write (trace_fd, buffer, strlen (buffer));
+}
diff --git a/pool.h b/pool.h
new file mode 100644 (file)
index 0000000..f8ed4c4
--- /dev/null
+++ b/pool.h
@@ -0,0 +1,158 @@
+/* An Apache-like pool allocator.
+ * By Richard W.M. Jones <rich@annexia.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id: pool.h,v 1.7 2002/06/08 11:50:44 rich Exp $
+ */
+
+#ifndef POOL_H
+#define POOL_H
+
+#include <stdlib.h>
+
+struct pool;
+typedef struct pool *pool;
+
+/* Function: new_pool - allocate a new pool
+ *
+ * Allocate a new pool. Pools must eventually be deleted explicitly
+ * by calling @ref{delete_pool(3)}.
+ *
+ * Note that @code{new_pool} is now deprecated. It is almost always
+ * better to create a subpool of the global pool, ie:
+ *
+ * @code{pool = new_subpool (global_pool);}
+ *
+ * This has the distinct advantage that your new pool will be cleaned
+ * up properly if the process calls @code{exit}.
+ *
+ * See also: @ref{new_subpool(3)}, @ref{global_pool(3)},
+ * @ref{delete_pool(3)}.
+ */
+extern pool new_pool (void);
+
+/* Function: new_subpool - allocate a subpool of an existing pool
+ *
+ * Allocate a new subpool. The pool may either be deleted explicitly, or
+ * else is deleted implicitly when the parent pool is deleted.
+ */
+extern pool new_subpool (pool);
+
+/* Function: delete_pool - delete a pool
+ *
+ * Delete a pool or subpool. This also deletes any subpools that the
+ * pool may own (and recursively subpools of those subpools, etc.)
+ */
+extern void delete_pool (pool);
+
+/* Function: pmalloc - allocate memory in a pool
+ * Function: pcalloc
+ * Function: prealloc
+ *
+ * Allocate memory in a pool or, if pool is null, on the main heap
+ * (equivalent to plain @code{malloc}). If memory is allocated in a real
+ * pool, then it is automatically freed when the pool is deleted.
+ *
+ * Memory returned is word-aligned.
+ *
+ * If a memory allocation fails, the @code{bad_malloc_handler} function is
+ * called (which defaults to just calling @ref{abort(3)}).
+ *
+ * @code{pcalloc} is identical to @code{pmalloc} but also sets the memory
+ * to zero before returning it.
+ *
+ * @code{prealloc} increases the size of an existing memory allocation.
+ * @code{prealloc} might move the memory in the process of reallocating it.
+ *
+ * Bugs: @code{prealloc} cannot reduce the size of an existing memory
+ * allocation.
+ */
+extern void *pmalloc (pool, size_t n);
+extern void *pcalloc (pool, size_t nmemb, size_t size);
+extern void *prealloc (pool, void *ptr, size_t n);
+
+/* Function: pool_register_malloc - allow pool to own malloc'd memory
+ *
+ * Register an anonymous area of malloc-allocated memory which
+ * will be freed (with @ref{free(3)}) when the pool is deleted.
+ */
+extern void pool_register_malloc (pool, void *ptr);
+
+/* Function: pool_register_fd - allow pool to own file descriptor
+ *
+ * Register a file descriptor to be closed when the pool is deleted.
+ * There is no way to unregister a file descriptor. If you wish to
+ * do that, then you probably want to register the fd in a subpool.
+ */
+extern void pool_register_fd (pool, int fd);
+
+/* Function: pool_register_cleanup_fn - call function when pool is deleted
+ *
+ * Register a function to be called when the pool is deleted. There
+ * is no way to unregister this function. If you wish to do that, then
+ * you probably want to register it in a subpool.
+ */
+extern void pool_register_cleanup_fn (pool, void (*fn) (void *), void *data);
+
+/* Function: pool_set_bad_malloc_handler - set handler for when malloc fails
+ *
+ * Set the function which is called when an underlying malloc or realloc
+ * operation fails. The default is that @ref{abort(3)} is called.
+ *
+ * This function returns the previous handler.
+ */
+extern void (*pool_set_bad_malloc_handler (void (*fn) (void))) (void);
+
+struct pool_stats
+{
+  int nr_subpools;
+  int struct_size;
+};
+
+/* Function: pool_get_stats - get statistics from the pool
+ *
+ * Return various statistics collected for the pool. This function
+ * fills in the @code{stats} argument which should point to a
+ * structure of type @code{struct pool_stats}. @code{n} should be
+ * set to the size of this structure.
+ *
+ * @code{struct pool_stats} currently contains the following fields:
+ *
+ * @code{nr_subpools}: The number of subpools (including the current pool).
+ *
+ * @code{struct_size}: The memory overhead used by the pool allocator
+ * itself to store structures. This includes subpools.
+ */
+extern void pool_get_stats (const pool, struct pool_stats *stats, size_t n);
+
+/* Obsolete calls for backwards compatibility. These will be removed soon. */
+#define pool_get_size(p) (-1)
+#define pool_get_areas(p) (-1)
+#define pool_get_allocations(p) (-1)
+#define pool_nr_subpools(p) (-1)
+
+#ifndef NO_GLOBAL_POOL
+/* Variable: global_pool - the global pool for global allocations
+ *
+ * This is the global pool which is allocated before @code{main()} is called
+ * and deleted automatically upon program exit. Items allocated on this
+ * pool cannot be deleted until the program ends, and so it is a good
+ * idea not to allocate short-lived items here.
+ */
+extern pool global_pool;
+#endif /* !NO_GLOBAL_POOL */
+
+#endif /* POOL_H */
diff --git a/pre.c b/pre.c
new file mode 100644 (file)
index 0000000..d616552
--- /dev/null
+++ b/pre.c
@@ -0,0 +1,278 @@
+/* String functions which allocate strings on the pool.
+ * By Richard W.M. Jones <rich@annexia.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id: pre.c,v 1.3 2003/01/22 14:29:37 rich Exp $
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef HAVE_ALLOCA_H
+#include <alloca.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include <pcre.h>
+
+#include <pool.h>
+#include <vector.h>
+#include <pstring.h>
+#include <pre.h>
+
+/* These private functions are used to capture memory allocations made
+ * by the PCRE library.
+ */
+static void *malloc_in_pool (size_t);
+static void do_nothing (void *);
+static pool malloc_pool = 0;
+
+pcre *
+precomp (pool pool, const char *pattern, int options)
+{
+  const char *errptr;
+  int erroffset;
+  pcre *result;
+  void *(*old_malloc)(size_t);
+  void (*old_free) (void *);
+
+  /* Allocations to the pool. */
+  old_malloc = pcre_malloc;
+  old_free = pcre_free;
+  pcre_malloc = malloc_in_pool;
+  malloc_pool = pool;
+  pcre_free = do_nothing;
+
+  /* Compile the pattern. */
+  result = pcre_compile (pattern, options, &errptr, &erroffset, 0);
+  if (result == 0)
+    {
+      fprintf (stderr,
+              "pcre: internal error compiling regular expression:\n"
+              "pcre: %s\n"
+              "pcre: %s\n"
+              "pcre: %s^\n",
+              errptr,
+              pattern,
+              pchrs (pool, ' ', erroffset-1));
+      exit (1);
+    }
+
+  /* Restore memory allocation. */
+  pcre_malloc = old_malloc;
+  pcre_free = old_free;
+
+  return result;
+}
+
+vector
+prematch (pool pool, const char *str, const pcre *pattern, int options)
+{
+  int err, n, i, ovecsize;
+  int *ovector;
+  vector result;
+  void *(*old_malloc)(size_t);
+  void (*old_free) (void *);
+
+  /* Allocations to the pool. */
+  old_malloc = pcre_malloc;
+  old_free = pcre_free;
+  pcre_malloc = malloc_in_pool;
+  malloc_pool = pool;
+  pcre_free = do_nothing;
+
+  /* Get the number of capturing substrings in the pattern (n). */
+  if ((err = pcre_fullinfo (pattern, 0, PCRE_INFO_CAPTURECOUNT, &n)) != 0)
+    abort ();
+
+  /* Allocate a vector large enough to contain the resulting substrings. */
+  ovecsize = (n+1) * 3;
+  ovector = alloca (ovecsize * sizeof (int));
+
+  /* Do the match. n is the number of strings found. */
+  n = pcre_exec (pattern, 0, str, strlen (str), 0, options, ovector, ovecsize);
+
+  /* Restore memory allocation. */
+  pcre_malloc = old_malloc;
+  pcre_free = old_free;
+
+  if (n == PCRE_ERROR_NOMATCH) /* No match, return NULL. */
+    return 0;
+  else if (n <= 0)             /* Some other error. */
+    abort ();
+
+  /* Some matches. Construct the vector. */
+  result = new_vector (pool, char *);
+  for (i = 0; i < n; ++i)
+    {
+      char *s = 0;
+      int start = ovector[i*2];
+      int end = ovector[i*2+1];
+
+      if (start >= 0)
+       s = pstrndup (pool, str + start, end - start);
+      vector_push_back (result, s);
+    }
+
+  return result;
+}
+
+static int do_match_and_sub (pool pool, const char *str, char **newstrp,
+                            const pcre *pattern, const char *sub,
+                            int startoffset, int options, int cc,
+                            int *ovector, int ovecsize, int placeholders);
+
+const char *
+presubst (pool pool, const char *str,
+         const pcre *pattern, const char *sub,
+         int options)
+{
+  char *newstr = pstrdup (pool, "");
+  int cc, err, n, ovecsize;
+  int *ovector;
+  void *(*old_malloc)(size_t);
+  void (*old_free) (void *);
+  int placeholders = (options & PRESUBST_NO_PLACEHOLDERS) ? 0 : 1;
+  int global = (options & PRESUBST_GLOBAL) ? 1 : 0;
+
+  options &= ~(PRESUBST_NO_PLACEHOLDERS | PRESUBST_GLOBAL);
+
+  /* Allocations to the pool. */
+  old_malloc = pcre_malloc;
+  old_free = pcre_free;
+  pcre_malloc = malloc_in_pool;
+  malloc_pool = pool;
+  pcre_free = do_nothing;
+
+  /* Get the number of capturing substrings in the pattern. */
+  if ((err = pcre_fullinfo (pattern, 0, PCRE_INFO_CAPTURECOUNT, &cc)) != 0)
+    abort ();
+
+  /* Allocate a vector large enough to contain the resulting substrings. */
+  ovecsize = (cc+1) * 3;
+  ovector = alloca (ovecsize * sizeof (int));
+
+  /* Find a match and substitute. */
+  n = do_match_and_sub (pool, str, &newstr, pattern, sub, 0, options, cc,
+                       ovector, ovecsize, placeholders);
+
+  if (global)
+    {
+      /* Do the remaining matches. */
+      while (n > 0)
+       {
+         n = do_match_and_sub (pool, str, &newstr, pattern, sub, n,
+                               options, cc,
+                               ovector, ovecsize, placeholders);
+       }
+    }
+  else if (n > 0)
+    {
+      /* Concatenate the remainder of the string. */
+      newstr = pstrcat (pool, newstr, str + n);
+    }
+
+  /* Restore memory allocation. */
+  pcre_malloc = old_malloc;
+  pcre_free = old_free;
+
+  return newstr;
+}
+
+static int
+do_match_and_sub (pool pool, const char *str, char **newstrp,
+                 const pcre *pattern, const char *sub,
+                 int startoffset, int options, int cc,
+                 int *ovector, int ovecsize, int placeholders)
+{
+  int so, eo, err;
+  char *newstr = *newstrp;
+
+  /* Find the next match. */
+  err = pcre_exec (pattern, 0, str, strlen (str), startoffset,
+                  options, ovector, ovecsize);
+  if (err == PCRE_ERROR_NOMATCH) /* No match. */
+    {
+      if (startoffset == 0)
+       /* Special case: we can just return the original string. */
+       *newstrp = (char *) str;
+      else
+       {
+         /* Concatenate the end of the string. */
+         newstr = pstrcat (pool, newstr, str + startoffset);
+         *newstrp = newstr;
+       }
+      return -1;
+    }
+  else if (err != cc+1)                /* Some other error. */
+    abort ();
+
+  /* Get position of the match. */
+  so = ovector[0];
+  eo = ovector[1];
+
+  /* Substitute for the match. */
+  newstr = pstrncat (pool, newstr, str + startoffset, so - startoffset);
+  if (placeholders)
+    {
+      int i;
+
+      /* Substitute $1, $2, ... placeholders with captured substrings. */
+      for (i = 0; i < strlen (sub); ++i)
+       {
+         if (sub[i] == '$' && (sub[i+1] >= '0' && sub[i+1] <= '9'))
+           {
+             int n = sub[i+1] - '0';
+
+             if (n > cc)
+               newstr = pstrncat (pool, newstr, &sub[i], 2);
+             else
+               {
+                 int nso = ovector[n*2];
+                 int neo = ovector[n*2+1];
+
+                 newstr = pstrncat (pool, newstr, str+nso, neo-nso);
+               }
+
+             i++;
+           }
+         else
+           newstr = pstrncat (pool, newstr, &sub[i], 1);
+       }
+    }
+  else
+    newstr = pstrcat (pool, newstr, sub);
+
+  *newstrp = newstr;
+  return eo;
+}
+
+static void *
+malloc_in_pool (size_t n)
+{
+  return pmalloc (malloc_pool, n);
+}
+
+static void
+do_nothing (void *p)
+{
+  /* Yes, really, do nothing. */
+}
diff --git a/pre.h b/pre.h
new file mode 100644 (file)
index 0000000..00f7913
--- /dev/null
+++ b/pre.h
@@ -0,0 +1,87 @@
+/* Regular expression functions which allocate in the pool.
+ * By Richard W.M. Jones <rich@annexia.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id: pre.h,v 1.1 2002/10/05 16:42:04 rich Exp $
+ */
+
+#ifndef PRE_H
+#define PRE_H
+
+#include <pcre.h>
+
+#include <pool.h>
+#include <vector.h>
+
+/* Function: precomp - Compile, match, substitute regular expressions.
+ * Function: prematch
+ * Function: presubst
+ *
+ * These functions are wrappers around the Perl Compatible
+ * Regular Expressions (PCRE) library (see
+ * @code{http://www.pcre.org/}).
+ *
+ * @code{precomp} compiles the regular expression @code{pattern}
+ * returning a pointer to the opaque @code{pcre} structure. The
+ * structure is allocated in @code{pool}. The @code{options} argument
+ * is a list of PCRE options, passed directly to the
+ * @code{pcre_compile} function (see @ref{pcre(3)}). You
+ * should normally set @code{options} to 0.
+ *
+ * @code{prematch} matches the string @code{str} with the
+ * compiled regular expression @code{pattern}.
+ *
+ * If there is no match, this returns @code{NULL}. If the string
+ * matches, then this function returns a @code{vector} of @code{char *},
+ * allocated in @code{pool}.  The first element of this vector is
+ * the portion of the original string which matched the whole
+ * pattern. The second and subsequent elements of this vector are
+ * captured substrings. It is possible in rare circumstances for some
+ * of these captured substrings to be @code{NULL} (see the
+ * @ref{pcre(3)} manual page for an example).
+ *
+ * The @code{options} argument is passed directly to
+ * @code{pcre_exec}. You should normally set @code{options} to 0.
+ *
+ * @code{presubst} substitutes @code{sub} for @code{pattern}
+ * wherever @code{pattern} occurs in @code{str}. It is equivalent
+ * to the @code{str =~ s/pat/sub/} function in Perl.
+ *
+ * Placeholders @code{$1}, @code{$2}, etc. in @code{sub} are
+ * substituted for the matching substrings of @code{pattern}.
+ * Placeholder substitution can be disabled completely by
+ * including the @code{PRESUBST_NO_PLACEHOLDERS} flag in @code{options}.
+ *
+ * If the @code{PRESUBST_GLOBAL} flag is given, then all
+ * matches are substituted. Otherwise only the first match
+ * is substituted.
+ *
+ * The @code{options} argument is passed to @code{pcre_exec}
+ * (after removing the @code{PRESUBST_*} flags).
+ *
+ * The return value from @code{presubst} is the string with
+ * replacements.
+ *
+ * See also: @ref{pcre(3)}.
+ */
+pcre *precomp (pool pool, const char *pattern, int options);
+vector prematch (pool pool, const char *str, const pcre *pattern, int options);
+const char *presubst (pool pool, const char *str, const pcre *pattern, const char *sub, int options);
+
+#define PRESUBST_NO_PLACEHOLDERS 0x10000000
+#define PRESUBST_GLOBAL          0x20000000
+
+#endif /* PRE_H */
diff --git a/pstring.c b/pstring.c
new file mode 100644 (file)
index 0000000..f57f17e
--- /dev/null
+++ b/pstring.c
@@ -0,0 +1,721 @@
+/* String functions which allocate strings on the pool.
+ * By Richard W.M. Jones <rich@annexia.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id: pstring.c,v 1.24 2003/01/22 14:29:37 rich Exp $
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#ifdef HAVE_ALLOCA_H
+#include <alloca.h>
+#endif
+
+#ifdef HAVE_CTYPE_H
+#include <ctype.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include <vector.h>
+#include <hash.h>
+#include <pstring.h>
+
+#define MIN(a,b) ((a)<(b)?(a):(b))
+
+/* Duplicate a string. */
+char *
+pstrdup (pool pool, const char *str)
+{
+  int len = strlen (str);
+  char *ptr = pmalloc (pool, (len+1) * sizeof (char));
+  return memcpy (ptr, str, len+1);
+}
+
+/* Duplicate up to the first N characters of a string. */
+char *
+pstrndup (pool pool, const char *str, int n)
+{
+  int len = MIN (strlen (str), n);
+  char *ptr = pmalloc (pool, (len+1) * sizeof (char));
+  memcpy (ptr, str, len);
+  ptr[len] = '\0';
+  return ptr;
+}
+
+/* Duplicate a fixed-size area of memory. */
+void *
+pmemdup (pool pool, const void *data, size_t size)
+{
+  void *ptr = pmalloc (pool, size);
+  return memcpy (ptr, data, size);
+}
+
+static vector generic_split (pool pool, const char *str, const void *sep, const char *(*find) (const char *str, const void *sep, const char **end_match), int keep);
+
+static const char *
+find_strstr (const char *str, const void *sep, const char **end_match)
+{
+  const char *csep = (const char *) sep;
+  const char *t = strstr (str, csep);
+  if (t) *end_match = t + strlen (csep);
+  return t;
+}
+
+vector
+pstrsplit (pool pool, const char *str, const char *sep)
+{
+  return generic_split (pool, str, sep, find_strstr, 0);
+}
+
+static const char *
+find_strchr (const char *str, const void *sep, const char **end_match)
+{
+  char c = * (const char *) sep;
+  const char *t = strchr (str, c);
+  if (t) *end_match = t+1;
+  return t;
+}
+
+vector
+pstrcsplit (pool pool, const char *str, char c)
+{
+  return generic_split (pool, str, &c, find_strchr, 0);
+}
+
+static const char *
+find_re (const char *str, const void *sep, const char **end_match)
+{
+  const pcre *re = (const pcre *) sep;
+#define ovecsize 3
+  int ovector[ovecsize];
+  int r = pcre_exec (re, 0, str, strlen (str), 0, 0, ovector, ovecsize);
+
+  if (r >= 0)                  /* Successful match. */
+    {
+      int so = ovector[0];
+      int eo = ovector[1];
+
+      if (so == -1) abort ();  /* Bad pattern. */
+      *end_match = str + eo;
+      return str + so;
+    }
+  else if (r == PCRE_ERROR_NOMATCH)
+    return 0;
+  else
+    abort ();                  /* Some other error reported by PCRE. */
+#undef ovecsize
+}
+
+vector
+pstrresplit (pool pool, const char *str, const pcre *re)
+{
+  return generic_split (pool, str, re, find_re, 0);
+}
+
+vector
+pstrsplit2 (pool pool, const char *str, const char *sep)
+{
+  return generic_split (pool, str, sep, find_strstr, 1);
+}
+
+vector
+pstrcsplit2 (pool pool, const char *str, char c)
+{
+  return generic_split (pool, str, &c, find_strchr, 1);
+}
+
+vector
+pstrresplit2 (pool pool, const char *str, const pcre *re)
+{
+  return generic_split (pool, str, re, find_re, 1);
+}
+
+/* Generic split function. */
+static vector
+generic_split (pool pool, const char *str, const void *sep,
+              const char *(*find) (const char *str, const void *sep,
+                                   const char **end_match),
+              int keep)
+{
+  const char *start_match, *end_match;
+  char *s;
+  vector v;
+
+  /* If the string is zero length, always return a zero length vector. */
+  if (strcmp (str, "") == 0) return new_vector (pool, char *);
+
+  /* Find the splitting point. */
+  start_match = find (str, sep, &end_match);
+
+  if (start_match != 0)                /* Successful match. */
+    {
+      s = start_match > str ? pstrndup (pool, str, start_match - str) : 0;
+      v = generic_split (pool, end_match, sep, find, keep);
+      if (keep)                        /* Keep the matching text. */
+       {
+         const char *match;
+
+         match = pstrndup (pool, start_match, end_match - start_match);
+         vector_push_front (v, match);
+       }
+      if (s) vector_push_front (v, s);
+    }
+  else                         /* Not successful match. */
+    {
+      s = pstrdup (pool, str);
+      v = new_vector (pool, char *);
+      vector_push_back (v, s);
+    }
+
+  return v;
+}
+
+/* Concatenate a vector of strings to form a string. */
+char *
+pconcat (pool pool, vector v)
+{
+  int i;
+  char *s = pstrdup (pool, "");
+
+  for (i = 0; i < vector_size (v); ++i)
+    {
+      char *t;
+
+      vector_get (v, i, t);
+      s = pstrcat (pool, s, t);
+    }
+
+  return s;
+}
+
+/* Join a vector of strings, separating each string by the given string. */
+char *
+pjoin (pool pool, vector v, const char *sep)
+{
+  int i;
+  char *s = pstrdup (pool, "");
+
+  for (i = 0; i < vector_size (v); ++i)
+    {
+      char *t;
+
+      vector_get (v, i, t);
+      s = pstrcat (pool, s, t);
+      if (i < vector_size (v) - 1) s = pstrcat (pool, s, sep);
+    }
+
+  return s;
+}
+
+char *
+pchrs (pool pool, char c, int n)
+{
+  char *s = pmalloc (pool, sizeof (char) * (n + 1));
+  int i;
+
+  for (i = 0; i < n; ++i)
+    s[i] = c;
+  s[n] = '\0';
+
+  return s;
+}
+
+char *
+pstrs (pool pool, const char *str, int n)
+{
+  int len = strlen (str);
+  char *s = pmalloc (pool, sizeof (char) * (len * n + 1));
+  int i, j;
+
+  for (i = j = 0; i < n; ++i, j += len)
+    memcpy (&s[j], str, len);
+
+  s[len * n] = '\0';
+
+  return s;
+}
+
+vector
+pvector (pool pool, ...)
+{
+  va_list args;
+  const char *s;
+  vector v = new_vector (pool, const char *);
+
+  va_start (args, pool);
+  while ((s = va_arg (args, const char *)) != 0)
+    vector_push_back (v, s);
+  va_end (args);
+
+  return v;
+}
+
+vector
+pvectora (pool pool, const char *array[], int n)
+{
+  int i;
+  vector v = new_vector (pool, const char *);
+
+  for (i = 0; i < n; ++i)
+    vector_push_back (v, array[i]);
+
+  return v;
+}
+
+/* Sort a vector of strings. */
+void
+psort (vector v, int (*compare_fn) (const char **, const char **))
+{
+  vector_sort (v, (int (*) (const void *, const void *)) compare_fn);
+}
+
+/* Remove line endings (either CR, CRLF or LF) from the string. */
+char *
+pchomp (char *line)
+{
+  int len = strlen (line);
+
+  while (line[len-1] == '\n' || line[len-1] == '\r')
+    line[--len] = '\0';
+
+  return line;
+}
+
+char *
+ptrimfront (char *str)
+{
+  char *p;
+  int len;
+
+  for (p = str; *p && isspace ((int) *p); ++p)
+    ;
+
+  len = strlen (p);
+  memmove (str, p, len + 1);
+
+  return str;
+}
+
+char *
+ptrimback (char *str)
+{
+  int len;
+  char *p;
+
+  len = strlen (str);
+  for (p = str + len - 1; p >= str && isspace ((int) *p); --p)
+    ;
+
+  p[1] = '\0';
+
+  return str;
+}
+
+char *
+ptrim (char *str)
+{
+  ptrimback (str);
+  ptrimfront (str);
+  return str;
+}
+
+/* This is equivalent to sprintf but it allocates the result string in POOL.*/
+char *
+psprintf (pool pool, const char *format, ...)
+{
+  va_list args;
+  char *s;
+
+  va_start (args, format);
+  s = pvsprintf (pool, format, args);
+  va_end (args);
+
+  return s;
+}
+
+/* Similar to vsprintf. */
+char *
+pvsprintf (pool pool, const char *format, va_list args)
+{
+#ifdef HAVE_VASPRINTF
+
+  char *s;
+
+  vasprintf (&s, format, args);
+  if (s == 0) abort ();                /* XXX Should call bad_malloc_handler. */
+
+  /* The pool will clean up the malloc when it goes. */
+  pool_register_malloc (pool, s);
+
+  return s;
+
+#else /* !HAVE_VASPRINTF */
+
+  int r, n = 256;
+  char *s = alloca (n), *t;
+
+  /* Note: according to the manual page, a return value of -1 indicates
+   * that the string was truncated. We have found that this is not
+   * actually true however. In fact, the library seems to return the
+   * number of characters which would have been written into the string
+   * excluding the '\0' (ie. r > n).
+   */
+  r = vsnprintf (s, n, format, args);
+
+  if (r < n)
+    {
+      /* Copy the string into a pool-allocated area of the correct size
+       * and return it.
+       */
+      n = r + 1;
+      t = pmalloc (pool, n);
+      memcpy (t, s, n);
+
+      return t;
+    }
+  else
+    {
+      /* String was truncated. Allocate enough space for the string
+       * in the pool and repeat the vsnprintf into this buffer.
+       */
+      n = r + 1;
+      t = pmalloc (pool, n);
+
+      vsnprintf (t, n, format, args);
+
+      return t;
+    }
+
+#endif /* !HAVE_VASPRINTF */
+}
+
+/* Convert various number types to strings. */
+char *
+pitoa (pool pool, int n)
+{
+  char *s = pmalloc (pool, 16);
+  snprintf (s, 16, "%d", n);
+  return s;
+}
+
+char *
+pdtoa (pool pool, double n)
+{
+  char *s = pmalloc (pool, 16);
+  snprintf (s, 16, "%f", n);
+  return s;
+}
+
+char *
+pxtoa (pool pool, unsigned n)
+{
+  char *s = pmalloc (pool, 16);
+  snprintf (s, 16, "%x", n);
+  return s;
+}
+
+/* Promote vector of numbers to vector of strings. */
+vector
+pvitostr (pool pool, vector v)
+{
+  vector nv = new_vector (pool, char *);
+  int i;
+
+  vector_reallocate (nv, vector_size (v));
+
+  for (i = 0; i < vector_size (v); ++i)
+    {
+      char *s;
+      int j;
+
+      vector_get (v, i, j);
+      s = pitoa (pool, j);
+      vector_push_back (nv, s);
+    }
+
+  return nv;
+}
+
+vector
+pvdtostr (pool pool, vector v)
+{
+  vector nv = new_vector (pool, char *);
+  int i;
+
+  vector_reallocate (nv, vector_size (v));
+
+  for (i = 0; i < vector_size (v); ++i)
+    {
+      char *s;
+      double j;
+
+      vector_get (v, i, j);
+      s = pdtoa (pool, j);
+      vector_push_back (nv, s);
+    }
+
+  return nv;
+}
+
+vector
+pvxtostr (pool pool, vector v)
+{
+  vector nv = new_vector (pool, char *);
+  int i;
+
+  vector_reallocate (nv, vector_size (v));
+
+  for (i = 0; i < vector_size (v); ++i)
+    {
+      char *s;
+      unsigned j;
+
+      vector_get (v, i, j);
+      s = pxtoa (pool, j);
+      vector_push_back (nv, s);
+    }
+
+  return nv;
+}
+
+/* STR is a string allocated in POOL. Append ENDING to STR, reallocating
+ * STR if necessary.
+ */
+char *
+pstrcat (pool pool, char *str, const char *ending)
+{
+  /* There are probably more efficient ways to implement this ... */
+  int slen = strlen (str);
+  int elen = strlen (ending);
+
+  str = prealloc (pool, str, slen + elen + 1);
+  strcat (str, ending);
+  return str;
+}
+
+char *
+pstrncat (pool pool, char *str, const char *ending, size_t n)
+{
+  int slen = strlen (str);
+  int elen = strlen (ending);
+
+  elen = elen > n ? n : elen;
+
+  str = prealloc (pool, str, slen + elen + 1);
+  strncat (str, ending, n);
+  return str;
+}
+
+/* Return the substring starting at OFFSET and of length LEN of STR, allocated
+ * as a new string. If LEN is negative, everything up to the end of STR
+ * is returned.
+ */
+char *
+psubstr (pool pool, const char *str, int offset, int len)
+{
+  char *new_str;
+
+  if (len >= 0)
+    {
+      new_str = pmalloc (pool, len + 1);
+      memcpy (new_str, str + offset, len);
+      new_str[len] = '\0';
+      return new_str;
+    }
+  else
+    {
+      len = strlen (str + offset);
+      new_str = pmalloc (pool, len + 1);
+      memcpy (new_str, str + offset, len);
+      new_str[len] = '\0';
+      return new_str;
+    }
+}
+
+char *
+pstrupr (char *str)
+{
+  char *s = str;
+  while (*s) { *s = toupper (*s); s++; }
+  return str;
+}
+
+char *
+pstrlwr (char *str)
+{
+  char *s = str;
+  while (*s) { *s = tolower (*s); s++; }
+  return str;
+}
+
+/* NB. The following figures were derived by examining a large number
+ * of configuration files in /etc/ on a Red Hat Linux box.
+ */
+#define _PGETL_INITIAL_BUFFER 96
+#define _PGETL_INCR_BUFFER 32
+
+char *
+pgetline (pool pool, FILE *fp, char *line)
+{
+  int allocated = _PGETL_INITIAL_BUFFER;
+  int len = 0;
+  int c;
+
+  /* Reallocate the buffer. */
+  line = prealloc (pool, line, _PGETL_INITIAL_BUFFER);
+
+  /* Read in the line until we reach EOF or a '\n' character. */
+  while ((c = getc (fp)) != EOF && c != '\n')
+    {
+      if (len == allocated)
+       line = prealloc (pool, line, allocated += _PGETL_INCR_BUFFER);
+      line[len++] = c;
+    }
+
+  /* EOF and no content? */
+  if (c == EOF && len == 0)
+    return 0;
+
+  /* Last character is '\r'? Remove it. */
+  if (line[len-1] == '\r')
+    len--;
+
+  /* Append a '\0' character to the buffer. */
+  if (len == allocated)
+    line = prealloc (pool, line, ++allocated);
+  line[len] = '\0';
+
+  return line;
+}
+
+char *
+pgetlinex (pool pool, FILE *fp, char *line, const char *comment_set,
+          int flags)
+{
+  int i, len;
+
+ again:
+  /* Read a single line. */
+  line = pgetline (pool, fp, line);
+  if (line == 0) return 0;
+
+  len = strlen (line);
+
+  /* Concatenate? */
+  if (!(flags & PGETL_NO_CONCAT))
+    {
+    another_concat:
+      if (line[len-1] == '\\')
+       {
+         char *next;
+
+         line[--len] = '\0';   /* Remove backslash char from first line. */
+
+         next = pgetline (pool, fp, 0);
+         if (next)
+           {
+             line = pstrcat (pool, line, next);
+             len = strlen (line);
+             goto another_concat;
+           }
+       }
+    }
+
+  /* Remove comments? */
+  if (!(flags & PGETL_INLINE_COMMENTS))
+    {
+      /* No inline comments. We're searching for whitespace followed
+       * by a comment character. If we find it, remove the line following
+       * the comment character.
+       */
+      for (i = 0; i < len; ++i)
+       if (!isspace ((int) line[i]))
+         {
+           if (strchr (comment_set, line[i]) != 0)
+             {
+               line[i] = '\0';
+               len = i;
+             }
+           break;
+         }
+    }
+  else
+    {
+      /* Inline comments. Search for the first occurance of any
+       * comment character and just remove the rest of the line
+       * from that point.
+       */
+      for (i = 0; i < len; ++i)
+       if (strchr (comment_set, line[i]) != 0)
+         {
+           line[i] = '\0';
+           len = i;
+           break;
+         }
+    }
+
+  /* Trim the line. */
+  ptrim (line);
+
+  /* Ignore blank lines. */
+  if (line[0] == '\0')
+    goto again;
+
+  return line;
+}
+
+vector
+pmap (pool p, const vector v, char *(*map_fn) (pool, const char *))
+{
+  int i;
+  vector nv = new_vector (p, char *);
+
+  for (i = 0; i < vector_size (v); ++i)
+    {
+      const char *s;
+      char *r;
+
+      vector_get (v, i, s);
+      r = map_fn (p, s);
+      vector_push_back (nv, r);
+    }
+
+  return nv;
+}
+
+vector
+pgrep (pool p, const vector v, int (*grep_fn) (pool, const char *))
+{
+  int i;
+  vector nv = new_vector (p, char *);
+
+  for (i = 0; i < vector_size (v); ++i)
+    {
+      const char *s;
+
+      vector_get (v, i, s);
+      if (grep_fn (p, s))
+       vector_push_back (nv, s);
+    }
+
+  return nv;
+}
diff --git a/pstring.h b/pstring.h
new file mode 100644 (file)
index 0000000..ccb280a
--- /dev/null
+++ b/pstring.h
@@ -0,0 +1,337 @@
+/* String functions which allocate strings on the pool.
+ * By Richard W.M. Jones <rich@annexia.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id: pstring.h,v 1.16 2002/12/04 21:03:25 rich Exp $
+ */
+
+#ifndef PSTRING_H
+#define PSTRING_H
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#include <pcre.h>
+
+#include <pool.h>
+#include <vector.h>
+
+/* Function: pstrdup - duplicate a string or area of memory
+ * Function: pstrndup
+ * Function: pmemdup
+ *
+ * @code{pstrdup} duplicates string @code{s}, allocating new memory for the
+ * string in pool @code{pool}.
+ *
+ * @code{pstrndup} duplicates just the first @code{n} characters of the
+ * string.
+ *
+ * @code{pmemdup} duplicates an arbitrary area of memory of size
+ * @code{size} bytes starting at address @code{data}.
+ */
+extern char *pstrdup (pool, const char *s);
+extern char *pstrndup (pool, const char *s, int n);
+extern void *pmemdup (pool, const void *data, size_t size);
+
+/* Function: pstrsplit - split a string on a character, string or regexp.
+ * Function: pstrcsplit
+ * Function: pstrresplit
+ * Function: pstrsplit2
+ * Function: pstrcsplit2
+ * Function: pstrresplit2
+ * 
+ * These functions split string @code{str} on either a string
+ * @code{sep}, a character @code{c} or a regular expression @code{re}.
+ *
+ * The result is a vector of newly created substrings.
+ *
+ * The @code{*2} variants split the string in the same way
+ * on the regular expression, but keeps the matching splitting text as
+ * separate elements in the vector. To illustrate this, imagine that
+ * @code{pstrresplit} and @code{pstrresplit2} are called on the string
+ * "This text is <b>bold</b>" with the regular expression @code{[<>]}.
+ *
+ * @code{pstrresplit} will return a vector containing:
+ *
+ * @code{ ( "This text is ", "b", "bold", "/b" ) }
+ *
+ * whereas @code{pstrcsplit2} will return:
+ *
+ * @code{ ( "This text is ", "<", "b", ">", "bold", "<", "/b", ">" ) }
+ *
+ * Note that the first element of the vector might be splitting
+ * text, or might be ordinary text as in the example above. Also
+ * the elements may not be interleaved like this (think about
+ * what would happen if the original string contained @code{"<b></b>"}).
+ * The only way to decide would be to call @code{prematch} on each element.
+ *
+ * This turns out to be very useful for certain sorts of simple
+ * parsing, or if you need to reconstruct the original string (just
+ * concatenate all of the elements together using @code{pconcat}).
+ *
+ * In common with Perl's @code{split} function, all of these functions
+ * return a zero length vector if @code{str} is the empty string.
+ *
+ * See also: @ref{prematch(3)}, @ref{pconcat(3)}.
+ */
+extern vector pstrsplit (pool, const char *str, const char *sep);
+extern vector pstrcsplit (pool, const char *str, char c);
+extern vector pstrresplit (pool, const char *str, const pcre *re);
+extern vector pstrsplit2 (pool, const char *str, const char *sep);
+extern vector pstrcsplit2 (pool, const char *str, char c);
+extern vector pstrresplit2 (pool, const char *str, const pcre *re);
+
+/* Function: pconcat - concatenate a vector of strings
+ * Function: pjoin
+ *
+ * @code{pconcat} concatenates a vector of strings to form a string.
+ *
+ * @code{pjoin} is similar except that @code{sep} is inserted between
+ * each concatenated string in the output.
+ *
+ * @code{pjoin} is kind of the opposite of @ref{pstrsplit(3)}.
+ */
+extern char *pconcat (pool, vector);
+extern char *pjoin (pool, vector, const char *sep);
+
+/* Function: pchrs - generate a string of n repeated characters or strings
+ * Function: pstrs
+ *
+ * @code{pchrs (pool, 'c', n)} is similar to the Perl expression
+ * @code{'c' x n}. It generates a pool-allocated string of @code{n} copies
+ * of character @code{'c'}.
+ *
+ * @code{pstrs (pool, str, n)} is similar to the Perl expression
+ * @code{str x n}. It generates a pool-allocated string of @code{n} copies
+ * of the string @code{str}.
+ */
+extern char *pchrs (pool, char c, int n);
+extern char *pstrs (pool, const char *str, int n);
+
+/* Function: pvector - generate a vector from a list or array of strings
+ * Function: pvectora
+ *
+ * @code{pvector} takes a NULL-terminated list of strings as arguments
+ * and returns a vector of strings. @code{pvectora} takes a pointer to
+ * an array of strings and the number of strings and returns a vector
+ * of strings.
+ *
+ * A typical use of this is to quickly concatenate strings:
+ *
+ * @code{s = pconcat (pool, pvector (pool, s1, s2, s3, NULL));}
+ *
+ * which is roughly equivalent to:
+ *
+ * @code{s = psprintf (pool, "%s%s%s", s1, s2, s3);}
+ *
+ * See also: @ref{pconcat(3)}, @ref{psprintf(3)}.
+ */
+extern vector pvector (pool, ...);
+extern vector pvectora (pool, const char *array[], int n);
+
+/* Function: psort - sort a vector of strings
+ *
+ * Sort a vector of strings, using @code{compare_fn} to compare
+ * strings. The vector is sorted in-place.
+ *
+ * It is a common mistake to try to use @code{strcmp} directly
+ * as your comparison function. This will not work. See the
+ * C FAQ, section 12, question 12.2
+ * (@code{http://www.lysator.liu.se/c/c-faq/c-12.html}).
+ */
+extern void psort (vector, int (*compare_fn) (const char **, const char **));
+
+/* Function: pchomp - remove line endings from a string
+ *
+ * Remove line endings (either CR, CRLF or LF) from the string argument.
+ * The string is modified in-place and a pointer to the string
+ * is also returned.
+ */
+extern char *pchomp (char *line);
+
+/* Function: ptrim - remove whitespace from the ends of a string
+ * Function: ptrimfront
+ * Function: ptrimback
+ *
+ * @code{ptrim} modifies a string of text in place, removing any
+ * whitespace characters from the beginning and end of the line.
+ *
+ * @code{ptrimfront} is the same as @code{ptrim} but only removes
+ * whitespace from the beginning of a string.
+ *
+ * @code{ptrimback} is the same as @code{ptrim} but only removes
+ * whitespace from the end of a string.
+ */
+extern char *ptrim (char *str);
+extern char *ptrimfront (char *str);
+extern char *ptrimback (char *str);
+
+/* Function: psprintf - sprintf which allocates the result in a pool
+ * Function: pvsprintf
+ *
+ * The @code{psprintf} function is equivalent to @code{sprintf}
+ * but it allocates the result string in @code{pool}.
+ *
+ * @code{pvsprintf} works similarly to @code{vsprintf}.
+ */
+extern char *psprintf (pool, const char *format, ...) __attribute__ ((format (printf, 2, 3)));
+extern char *pvsprintf (pool, const char *format, va_list ap);
+
+/* Function: pitoa - convert number types to strings
+ * Function: pdtoa
+ * Function: pxtoa
+ *
+ * These functions convert a decimal @code{int}, @code{double} or
+ * hexadecimal @code{unsigned} into a string, which is allocated
+ * in @code{pool}.
+ *
+ * @code{pitoa} is equivalent to @code{psprintf (pool, "%d", i)},
+ * and the other functions have similar equivalents.
+ */
+extern char *pitoa (pool, int);
+extern char *pdtoa (pool, double);
+extern char *pxtoa (pool, unsigned);
+
+/* Function: pvitostr - convert vectors of numbers to vectors of strings
+ * Function: pvdtostr
+ * Function: pvxtostr
+ *
+ * Promote vector of numbers to vector of strings.
+ *
+ * @code{pvitostr} expects a vector of @code{int}.
+ *
+ * @code{pvdtostr} expects a vector of @code{double}.
+ *
+ * @code{pvxtostr} expects a vector of hexadecimal @code{unsigned}.
+ *
+ * All functions return a vector of @code{char *}.
+ */
+extern vector pvitostr (pool, vector);
+extern vector pvdtostr (pool, vector);
+extern vector pvxtostr (pool, vector);
+
+/* Function: pstrcat - extend a string
+ * Function: pstrncat
+ *
+ * @code{str} is a string allocated in @code{pool}.
+ * Append @code{ending} to @code{str}, reallocating
+ * @code{str} if necessary.
+ *
+ * Because @code{str} may be reallocated (ie. moved) you
+ * must invoke this function as follows:
+ *
+ * @code{str = pstrcat (pool, str, ending);}
+ *
+ * @code{pstrncat} is similar to @code{pstrcat} except that
+ * only the first @code{n} characters of @code{ending}
+ * are appended to @code{str}.
+ */
+extern char *pstrcat (pool, char *str, const char *ending);
+extern char *pstrncat (pool, char *str, const char *ending, size_t n);
+
+/* Function: psubstr - return a substring of a string
+ *
+ * Return the substring starting at @code{offset} and of length
+ * @code{len} of @code{str}, allocated
+ * as a new string. If @code{len} is negative,
+ * everything up to the end of @code{str}
+ * is returned.
+ */
+extern char *psubstr (pool, const char *str, int offset, int len);
+
+/* Function: pstrupr - convert a string to upper- or lowercase
+ * Function: pstrlwr
+ *
+ * Convert a string, in-place, to upper or lowercase by applying
+ * @code{toupper} or @code{tolower} to each character in turn.
+ */
+extern char *pstrupr (char *str);
+extern char *pstrlwr (char *str);
+
+/* Function: pgetline - read a line from a file, optionally removing comments
+ * Function: pgetlinex
+ * Function: pgetlinec
+ *
+ * @code{pgetline} reads a single line from a file and returns it. It
+ * allocates enough space to read lines of arbitrary length. Line ending
+ * characters ('\r' and '\n') are automatically removed from the end
+ * of the line.
+ *
+ * The @code{pool} argument is a pool for allocating the line. The
+ * @code{fp} argument is the C @code{FILE} pointer. The @code{line}
+ * argument is a pointer to a string allocated in pool which will
+ * be reallocated and filled with the contents of the line. You may
+ * pass @code{line} as @code{NULL} to get a newly allocated buffer.
+ *
+ * Use @code{pgetline} in one of the following two ways:
+ *
+ * @code{line = pgetline (pool, fp, line);}
+ *
+ * or
+ *
+ * @code{line = pgetline (pool, fp, NULL);}
+ *
+ * @code{pgetlinex} is a more advanced function which reads a line
+ * from a file, optionally removing comments, concatenating together
+ * lines which have been split with a backslash, and ignoring blank
+ * lines. @code{pgetlinex} (and the related macro @code{pgetlinec}) are
+ * very useful for reading lines of input from a configuration file.
+ *
+ * The @code{pool} argument is a pool for allocating the line. The
+ * @code{fp} argument is the C @code{FILE} pointer. The @code{line}
+ * argument is a buffer allocated in pool which will be reallocated
+ * and filled with the result. @code{comment_set} is the set of
+ * possible comment characters -- eg. @code{"#!"} to allow either
+ * @code{#} or @code{!} to be used to introduce comments.
+ * @code{flags} is zero or more of the following flags OR-ed
+ * together:
+ *
+ * @code{PGETL_NO_CONCAT}: Don't concatenate lines which have been
+ * split with trailing backslash characters.
+ *
+ * @code{PGETL_INLINE_COMMENTS}: Treat everything following a comment
+ * character as a comment. The default is to only allow comments which
+ * appear on a line on their own.
+ *
+ * @code{pgetlinec} is a helper macro which calls @code{pgetlinex}
+ * with @code{comment_set == "#"} and @code{flags == 0}.
+ */
+extern char *pgetline (pool, FILE *fp, char *line);
+extern char *pgetlinex (pool, FILE *fp, char *line, const char *comment_set, int flags);
+#define pgetlinec(p,fp,line) pgetlinex ((p), (fp), (line), "#", 0)
+
+#define PGETL_NO_CONCAT 1
+#define PGETL_INLINE_COMMENTS 2
+
+/* Function: pmap - map, search vectors of strings
+ * Function: pgrep
+ *
+ * @code{pmap} takes a @code{vector} of strings (@code{char *}) and
+ * transforms it into another @code{vector} of strings by applying
+ * the function @code{char *map_fn (pool, const char *)} to each
+ * string.
+ *
+ * @code{pgrep} applies the function @code{int grep_fn (pool, const char *)}
+ * to each element in a @code{vector} of strings, and returns a
+ * new vector of strings containing only those strings where
+ * @code{grep_fn} returns true.
+ *
+ * See also: @ref{vector_map_pool(3)}, @ref{vector_grep_pool(3)}.
+ */
+vector pmap (pool, const vector v, char *(*map_fn) (pool, const char *));
+vector pgrep (pool, const vector v, int (*grep_fn) (pool, const char *));
+
+#endif /* PSTRING_H */
diff --git a/test_hash.c b/test_hash.c
new file mode 100644 (file)
index 0000000..faebfba
--- /dev/null
@@ -0,0 +1,99 @@
+/* Test the hash class.
+ * By Richard W.M. Jones <rich@annexia.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id: test_hash.c,v 1.1 2001/02/08 12:51:31 rich Exp $
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include <pool.h>
+#include <vector.h>
+#include <pstring.h>
+#include <hash.h>
+
+/* You can't take the address of non-lvalues in C (ie. you can't
+ * evaluate expressions like "&2"). Hence the following constant
+ * definitions are necessary.
+ */
+const int one = 1;
+const int two = 2;
+const int three = 3;
+const int four = 4;
+const int five = 5;
+const int six = 6;
+const int nine = 9;
+const int sixteen = 16;
+const int twentyfour = 24;
+const int twentyfive = 25;
+const int thirtyfive = 35;
+const int thirtysix = 36;
+
+int
+main ()
+{
+  hash h;
+  pool pool = new_pool ();
+  int v;
+  vector keys, values;
+
+  /* Create a int -> int hash. */
+  h = new_hash (pool, int, int);
+
+  /* Insert some new values. */
+  if (hash_insert (h, one, one) != 0) abort ();
+  if (hash_insert (h, two, four) != 0) abort ();
+  if (hash_insert (h, three, nine) != 0) abort ();
+  if (hash_insert (h, four, sixteen) != 0) abort ();
+  if (hash_insert (h, five, twentyfour) != 0) abort (); /* sic */
+  if (hash_insert (h, six, thirtyfive) != 0) abort (); /* sic */
+
+  /* This should replace existing values. */
+  if (hash_insert (h, five, twentyfive) == 0) abort ();
+  if (hash_insert (h, six, thirtysix) == 0) abort ();
+
+  /* Retrieve some values. */
+  if (hash_get (h, one, v) == 0 || v != 1) abort ();
+  if (hash_get (h, six, v) == 0 || v != 36) abort ();
+  if (hash_get (h, two, v) == 0 || v != 4) abort ();
+  if (hash_get (h, five, v) == 0 || v != 25) abort ();
+
+  /* Copy the hash. */
+  h = copy_hash (pool, h);
+
+  /* Erase a key and check that it no longer exists. */
+  if (hash_erase (h, one) == 0) abort ();
+  if (hash_get (h, one, v) != 0) abort ();
+
+  /* Get list of keys and values. */
+  keys = hash_keys (h);
+  values = hash_values (h);
+
+  printf ("keys = [ %s ]\n",
+         pjoin (pool, pvitostr (pool, keys), ", "));
+  printf ("values = [ %s ]\n",
+         pjoin (pool, pvitostr (pool, values), ", "));
+
+  delete_pool (pool);
+  exit (0);
+}
diff --git a/test_matvec.c b/test_matvec.c
new file mode 100644 (file)
index 0000000..be20218
--- /dev/null
@@ -0,0 +1,218 @@
+/* Test matrix, vector arithmetic.
+ * By Richard W.M. Jones <rich@annexia.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id: test_matvec.c,v 1.2 2001/11/19 17:10:55 rich Exp $
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <math.h>
+
+#include "pool.h"
+#include "matvec.h"
+
+static inline int
+is_equal (float a, float b)
+{
+  return fabs (a - b) < 1e-6;
+}
+
+static void
+test_identity_zero ()
+{
+  pool p = new_subpool (global_pool);
+  float *m = new_identity_matrix (p);
+  float *v = new_zero_vec (p);
+
+  assert (m[0] == 1 && m[1] == 0 && m[2] == 0 && m[3] == 0 &&
+         m[4] == 0 && m[5] == 1 && m[6] == 0 && m[7] == 0 &&
+         m[8] == 0 && m[9] == 0 && m[10] == 1 && m[11] == 0 &&
+         m[12] == 0 && m[13] == 0 && m[14] == 0 && m[15] == 1);
+  assert (v[0] == 0 && v[1] == 0 && v[2] == 0 && v[3] == 1);
+
+  delete_pool (p);
+}
+
+static void
+test_mag_norm ()
+{
+  float v[3] = {2, 0, 0}, r[3];
+
+  assert (vec_magnitude (v) == 2);
+  assert (vec_magnitude2d (v) == 2);
+
+  vec_normalize (v, r);
+  assert (r[0] == 1 && r[1] == 0 && r[2] == 0);
+
+  vec_normalize2d (v, r);
+  assert (r[0] == 1 && r[1] == 0);
+}
+
+static void
+test_dot_product ()
+{
+  float v1[3] = { 1, 0, 0 }, v2[3] = { 0, 1, 0 }, v3[3] = { 1, 1, 0 };
+
+  /* Dot product of perpendicular vectors is 0. */
+  assert (vec_dot_product (v1, v2) == 0);
+
+  /* Dot product of identical normal vectors is 1. */
+  assert (vec_dot_product (v1, v1) == 1);
+
+  /* Angle between vectors. */
+  assert (vec_angle_between (v1, v1) == 0);
+  assert (is_equal (vec_angle_between (v1, v2), M_PI/2));
+  assert (is_equal (vec_angle_between (v1, v3), M_PI/4));
+}
+
+static void
+test_point_line ()
+{
+  float p[3], v[3], q[3], d;
+
+  /* Line running along the x axis. */
+  p[0] = 0; p[1] = 0; p[2] = 0; v[0] = 1; v[1] = 0; v[2] = 0;
+
+  q[0] = 0; q[1] = 0; q[2] = 0;
+  assert (point_distance_to_line (q, p, v) == 0);
+
+  q[0] = 1; q[1] = 0; q[2] = 0;
+  assert (point_distance_to_line (q, p, v) == 0);
+
+  q[0] = 0; q[1] = 1; q[2] = 0;
+  assert (point_distance_to_line (q, p, v) == 1);
+
+  q[0] = 0; q[1] = 0; q[2] = 1;
+  assert (point_distance_to_line (q, p, v) == 1);
+
+  q[0] = 2; q[1] = 1; q[2] = 0;
+  assert (point_distance_to_line (q, p, v) == 1);
+
+  /* Line running diagonally x-y. */
+  p[0] = 2; p[1] = 2; p[2] = 0; v[0] = 1; v[1] = 1; v[2] = 0;
+
+  q[0] = 0; q[1] = 0; q[2] = 0;
+  assert (point_distance_to_line (q, p, v) == 0);
+
+  q[0] = 1; q[1] = 0; q[2] = 0;
+  d = point_distance_to_line (q, p, v);
+  assert (is_equal (d * d, 0.5));
+}
+
+static void
+test_point_plane ()
+{
+  float p[3], q[3], r[3], pl[4];
+
+  p[0] = 0; p[1] = 0; p[2] = 0;
+  q[0] = 2; q[1] = 0; q[2] = 0;
+  r[0] = 2; r[1] = 2; r[2] = 0;
+  plane_coefficients (p, q, r, pl);
+
+  assert (pl[3] == 0);
+  vec_normalize (pl, pl);
+  assert (pl[0] == 0 && pl[1] == 0 && pl[2] == -1);
+
+  assert (point_distance_to_plane (pl, p) == 0);
+  assert (point_distance_to_plane (pl, q) == 0);
+  assert (point_distance_to_plane (pl, r) == 0);
+
+  p[0] = 5; p[1] = 5; p[2] = -3;
+  assert (point_distance_to_plane (pl, p) == 3);
+  assert (point_is_inside_plane (pl, p));
+
+  p[0] = 5; p[1] = 5; p[2] = 3;
+  assert (point_distance_to_plane (pl, p) == -3);
+  assert (!point_is_inside_plane (pl, p));
+}
+
+static void
+test_point_in_face ()
+{
+  float points[4][3] = {
+    { 0, 0, 0 },
+    { 1, 1, 0 },
+    { 1, 1, 1 },
+    { 0, 0, 1 }
+  };
+  float p[3];
+
+  p[0] = 0.5; p[1] = 0.5; p[2] = 0.5;
+  assert (point_lies_in_face ((float *) points, 4, p));
+
+  p[0] = 0.01; p[1] = 0.01; p[2] = 0.9;
+  assert (point_lies_in_face ((float *) points, 4, p));
+
+  p[0] = 0; p[1] = 0; p[2] = 0;
+  assert (point_lies_in_face ((float *) points, 4, p));
+
+  p[0] = 1; p[1] = 1; p[2] = 1;
+  assert (point_lies_in_face ((float *) points, 4, p));
+
+  p[0] = 1; p[1] = 0; p[2] = 0;
+  assert (!point_lies_in_face ((float *) points, 4, p));
+
+  p[0] = 1; p[1] = 1; p[2] = -1;
+  assert (!point_lies_in_face ((float *) points, 4, p));
+
+  p[0] = 0.5; p[1] = 0.5; p[2] = 2;
+  assert (!point_lies_in_face ((float *) points, 4, p));
+}
+
+static void
+test_point_to_face ()
+{
+  float points[4][3] = {
+    { 0, 0, 0 },
+    { 1, 0, 0 },
+    { 1, 1, 0 },
+    { 0, 1, 0 }
+  };
+  float p[3];
+  int edge;
+
+  p[0] = 0.5; p[1] = 0.5; p[2] = 0;
+  assert (point_distance_to_face ((float *) points, 4, 0, p, &edge) == 0
+         && edge == -1);
+
+  p[0] = 0.5; p[1] = 0.5; p[2] = 1;
+  assert (point_distance_to_face ((float *) points, 4, 0, p, &edge) == -1
+         && edge == -1);
+
+  p[0] = 0.5; p[1] = 0.5; p[2] = -1;
+  assert (point_distance_to_face ((float *) points, 4, 0, p, &edge) == 1
+         && edge == -1);
+
+  p[0] = -1; p[1] = 0.5; p[2] = 0;
+  assert (point_distance_to_face ((float *) points, 4, 0, p, &edge) == -1
+         && edge == 3);
+}
+
+int
+main ()
+{
+  test_identity_zero ();
+  test_mag_norm ();
+  test_dot_product ();
+  test_point_line ();
+  test_point_plane ();
+  test_point_in_face ();
+  test_point_to_face ();
+
+  exit (0);
+}
diff --git a/test_pool.c b/test_pool.c
new file mode 100644 (file)
index 0000000..1f2e906
--- /dev/null
@@ -0,0 +1,281 @@
+/* Test pools, subpools, memory allocation and so on.
+ * By Richard W.M. Jones <rich@annexia.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id: test_pool.c,v 1.5 2002/12/07 15:18:26 rich Exp $
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <assert.h>
+#include <fcntl.h>
+#include <errno.h>
+
+/* Implement a simple malloc debugger -- which counts allocations and
+ * frees and ensures that all memory allocated by the pool code is
+ * evenually freed.
+ */
+
+static void  trace_init (void);
+static void  trace_finish (void);
+static void *trace_malloc (size_t n, const char *filename, int line);
+static void *trace_realloc (void *p, size_t n, const char *filename, int line);
+static void  trace_free (void *p);
+
+#define malloc(n)    trace_malloc ((n), __FILE__, __LINE__);
+#define realloc(p,n) trace_realloc ((p), (n), __FILE__, __LINE__);
+#define free(p)      trace_free ((p));
+
+#define NO_GLOBAL_POOL 1
+
+#include "pool.h"
+#include "pool.c"
+
+static void test (void);
+
+int
+main ()
+{
+  trace_init ();
+  test ();
+  trace_finish ();
+  exit (0);
+}
+
+/* Perform the tests. */
+static void
+simple_alloc_test ()
+{
+  pool p;
+  int i;
+
+  p = new_pool ();
+
+  for (i = 0; i < 1000; ++i)
+    {
+      pmalloc (p, 1);
+      pmalloc (p, 1);
+      prealloc (p, pmalloc (p, 200), 300);
+      pmalloc (p, 1000);
+      prealloc (p, pmalloc (p, 1000), 1001);
+      prealloc (p, pmalloc (p, 900), 901);
+      pmalloc (p, 1);
+      pmalloc (p, 4);
+      pmalloc (p, 8);
+      pmalloc (p, 1);
+      pmalloc (p, 400);
+    }
+
+  delete_pool (p);
+}
+
+static void
+simple_subpool_test (pool parent, int level)
+{
+  pool p;
+  int i;
+
+  if (level >= 8) return;
+
+  if (parent)
+    {
+      /* The following two statements must remain together. */
+      p = new_subpool (parent);
+      prealloc (p, prealloc (p, pmalloc (p, 16), 100),
+               200);
+      /* End of realloc test. */
+
+      pcalloc (p, 4, 4);
+      prealloc (p, 0, 8);
+      prealloc (p, pmalloc (p, 4), 8);
+      pmalloc (parent, 1);
+      prealloc (parent, pmalloc (parent, 8), 8);
+      prealloc (parent, pmalloc (parent, 8), 16);
+    }
+  else
+    {
+      p = new_pool ();
+      prealloc (p, pmalloc (p, 4), 8);
+      pmalloc (p, 8);
+      pmalloc (p, 1);
+    }
+
+  for (i = 0; i < 3; ++i)
+    {
+      simple_subpool_test (p, level+1);
+      pmalloc (p, 1);
+      if (parent) pmalloc (parent, 1);
+    }
+
+  if (parent == 0 || level == 4)
+    delete_pool (p);
+}
+
+/* This is a regression test: we had reason to believe this didn't work
+ * at one point.
+ */
+static void
+create_delete_test ()
+{
+  pool p;
+
+  p = new_pool ();
+  delete_pool (p);
+}
+
+static int cleanup_called = 0;
+
+static void
+cleanup_fn (void *v)
+{
+  cleanup_called ++;
+}
+
+static void
+cleanup_fn_test ()
+{
+  pool p, sp1, sp2;
+
+  p = new_pool ();
+  pool_register_cleanup_fn (p, cleanup_fn, 0);
+  delete_pool (p);
+  assert (cleanup_called == 1);
+
+  p = new_pool ();
+  sp1 = new_subpool (p);
+  sp2 = new_subpool (p);
+  pool_register_cleanup_fn (p, cleanup_fn, 0);
+  pool_register_cleanup_fn (sp1, cleanup_fn, 0);
+  pool_register_cleanup_fn (sp2, cleanup_fn, 0);
+  delete_pool (sp1);
+  assert (cleanup_called == 2);
+  delete_pool (p);
+  assert (cleanup_called == 4);
+}
+
+static void
+cleanup_fd_test ()
+{
+  int fd;
+  pool p;
+
+  p = new_pool ();
+  fd = open ("/dev/null", O_RDONLY);
+  pool_register_fd (p, fd);
+  delete_pool (p);
+
+  assert (close (fd) == -1 && errno == EBADF);
+}
+
+static void
+cleanup_malloc_test ()
+{
+  void *m;
+  pool p;
+
+  p = new_pool ();
+  m = malloc (10);
+  pool_register_malloc (p, m);
+  delete_pool (p);
+}
+
+static void
+lots_of_pmalloc_test ()
+{
+  pool p;
+  pool *subpools;
+  int i, j, np = 0;
+
+  /* This test kind of simulates what the chat server does, in an
+   * attempt to find the putative memory leak.
+   */
+  p = new_pool ();
+  subpools = pcalloc (p, sizeof (struct pool), 100);
+
+  for (i = 0; i < 10000; ++i)
+    {
+      if (subpools[np] != 0)
+       delete_pool (subpools[np]);
+      subpools[np] = new_subpool (p);
+
+      for (j = 0; j < 100; ++j)
+       {
+         void *ptr = pmalloc (subpools[np], 100);
+         prealloc (subpools[np], ptr, 200);
+       }
+
+      np++;
+      if (np == 100) np = 0;
+    }
+
+  delete_pool (p);
+}
+
+static void
+test ()
+{
+  simple_alloc_test ();
+  simple_subpool_test (0, 0);
+  create_delete_test ();
+  cleanup_fn_test ();
+  cleanup_fd_test ();
+  cleanup_malloc_test ();
+  lots_of_pmalloc_test ();
+}
+
+/* The tracing code. */
+#undef malloc
+#undef realloc
+#undef free
+
+static int nr_allocations = 0;
+
+static void
+trace_init ()
+{
+}
+
+static void
+trace_finish ()
+{
+  if (nr_allocations > 0)
+    {
+      fprintf (stderr, "*** error: %d allocation(s) leaked.\n",
+              nr_allocations);
+      exit (1);
+    }
+}
+
+static void *
+trace_malloc (size_t n, const char *filename, int line)
+{
+  nr_allocations++;
+  return malloc (n);
+}
+
+static void *
+trace_realloc (void *p, size_t n, const char *filename, int line)
+{
+  return realloc (p, n);
+}
+
+static void
+trace_free (void *p)
+{
+  nr_allocations--;
+  free (p);
+}
diff --git a/test_pre.c b/test_pre.c
new file mode 100644 (file)
index 0000000..42bffd0
--- /dev/null
@@ -0,0 +1,152 @@
+/* Test pre library.
+ * By Richard W.M. Jones <rich@annexia.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id: test_pre.c,v 1.1 2002/10/05 16:42:06 rich Exp $
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <pcre.h>
+
+#include "pool.h"
+#include "vector.h"
+#include "pstring.h"
+#include "pre.h"
+
+static int vequals (vector v, int i, const char *str);
+
+int
+main ()
+{
+  pool pool;
+  vector v;
+  pcre *re1, *re2, *re3, *re4, *re5;
+  const char *str;
+
+  pool = new_subpool (global_pool);
+
+  /* Compile some regular expressions. */
+  re1 = precomp (pool, "a*b+", 0);
+  re2 = precomp (pool, "bu(t+)ery", 0);
+  re3 = precomp (pool, "m(a+)rgar(ee+)ne", 0);
+  re4 = precomp (pool, "(a|b)(c|d)+", 0);
+  re5 = precomp (pool, "(a|b)((c|d)+)", 0);
+
+  /* Matching tests. */
+  v = prematch (pool, "", re1, 0);
+  assert (v == 0);
+
+  v = prematch (pool, "a", re1, 0);
+  assert (v == 0);
+
+  v = prematch (pool, "ab", re1, 0);
+  assert (v);
+  assert (vector_size (v) == 1);
+  assert (vequals (v, 0, "ab"));
+
+  v = prematch (pool, "b", re1, 0);
+  assert (v);
+  assert (vector_size (v) == 1);
+  assert (vequals (v, 0, "b"));
+
+  v = prematch (pool, "xxxaaaaaaaaaabby", re1, 0);
+  assert (v);
+  assert (vector_size (v) == 1);
+  assert (vequals (v, 0, "aaaaaaaaaabb"));
+
+  v = prematch (pool, "This is quite buttery.", re2, 0);
+  assert (v);
+  assert (vector_size (v) == 2);
+  assert (vequals (v, 0, "buttery"));
+  assert (vequals (v, 1, "tt"));
+
+  v = prematch (pool, "This is quite buttttttery.", re2, 0);
+  assert (v);
+  assert (vector_size (v) == 2);
+  assert (vequals (v, 0, "buttttttery"));
+  assert (vequals (v, 1, "tttttt"));
+
+  v = prematch (pool, "margarene", re3, 0);
+  assert (v == 0);
+
+  v = prematch (pool, "margareene", re3, 0);
+  assert (v);
+  assert (vector_size (v) == 3);
+  assert (vequals (v, 0, "margareene"));
+  assert (vequals (v, 1, "a"));
+  assert (vequals (v, 2, "ee"));
+
+  v = prematch (pool, "maargareeene", re3, 0);
+  assert (v);
+  assert (vector_size (v) == 3);
+  assert (vequals (v, 0, "maargareeene"));
+  assert (vequals (v, 1, "aa"));
+  assert (vequals (v, 2, "eee"));
+
+  v = prematch (pool, "abcd", re4, 0);
+  assert (v);
+  assert (vector_size (v) == 3);
+  assert (vequals (v, 0, "bcd"));
+  assert (vequals (v, 1, "b"));
+  assert (vequals (v, 2, "d"));
+
+  v = prematch (pool, "abcd", re5, 0);
+  assert (v);
+  assert (vector_size (v) == 4);
+  assert (vequals (v, 0, "bcd"));
+  assert (vequals (v, 1, "b"));
+  assert (vequals (v, 2, "cd"));
+  assert (vequals (v, 3, "d"));
+
+  /* Substitution tests. */
+
+  str = presubst (pool, "xxxxmaargareeeeneyy", re3, "$1$2", 0);
+  assert (strcmp (str, "xxxxaaeeeeyy") == 0);
+
+  str = presubst (pool, "xxxxmaargareeeeneyy", re3, "$2$1", 0);
+  assert (strcmp (str, "xxxxeeeeaayy") == 0);
+
+  str = presubst (pool, "xxxxmaargareeeeneyy xxxxmaargareeeeneyy",
+                 re3, "$2$1", 0);
+  assert (strcmp (str, "xxxxeeeeaayy xxxxmaargareeeeneyy") == 0);
+
+  str = presubst (pool, "abcd", re4, "$2$1", 0);
+  assert (strcmp (str, "adb") == 0);
+
+  /* Check all the presubst flags work correctly. */
+  str = presubst (pool, "xxxxmaargareeeeneyy", re3, "$1$2",
+                 PRESUBST_NO_PLACEHOLDERS);
+  assert (strcmp (str, "xxxx$1$2yy") == 0);
+
+  str = presubst (pool, "This is buttery buttery toast.", re2, "tasty",
+                 PRESUBST_GLOBAL);
+  assert (strcmp (str, "This is tasty tasty toast.") == 0);
+
+  delete_pool (pool);
+  exit (0);
+}
+
+static int
+vequals (vector v, int i, const char *str)
+{
+  const char *s;
+
+  vector_get (v, i, s);
+  return strcmp (s, str) == 0;
+}
diff --git a/test_pstring.c b/test_pstring.c
new file mode 100644 (file)
index 0000000..c02a3ad
--- /dev/null
@@ -0,0 +1,351 @@
+/* Test pstring library.
+ * By Richard W.M. Jones <rich@annexia.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id: test_pstring.c,v 1.11 2003/02/09 16:48:46 rich Exp $
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include <pcre.h>
+
+#include "pstring.h"
+#include "vector.h"
+
+const int i_one = 1, i_two = 2, i_three = 3, i_four = 4,
+  i_15 = 15, i_31 = 31, i_63 = 63, i_127 = 127;
+const double d_one = 1, d_two = 2, d_three = 3, d_four = 4;
+const char *s_one = "one", *s_two = "two", *s_three = "three",
+  *s_four = "four";
+
+const char *stra[] = { "one", "two", "three", "four" };
+
+const char *file1[] = { "line1\r\n",
+                       "line2\r\n",
+                       "line3\r\n", 0};
+const char *file2[] = { "line1\n",
+                       "line2\n",
+                       "line3\n", 0 };
+const char *file3[] = { "line1\n",
+                       "line2\n",
+                       "\n",
+                       "line3\n", 0 };
+const char *file4[] = { "line1\\\n",
+                       "line2\n",
+                       "line3\n", 0 };
+const char *file5[] = { "line1\n",
+                       "# a comment\n",
+                       "line2\n",
+                       "line3\n", 0 };
+const char *res1[] = { "line1", "line2", "line3", 0 };
+const char *res2[] = { "line1line2", "line3", 0 };
+
+static int
+my_strcmp (const char **p1, const char **p2)
+{
+  return strcmp (*p1, *p2);
+}
+
+int
+main ()
+{
+  pool pool;
+  char *s1, *s2;
+  vector v1, v2, v3, v4, v5;
+  pcre *re;
+  int i;
+  FILE *fp;
+  const char **sp;
+  const char *errptr;
+  int erroffset;
+
+  pool = new_pool ();
+
+  /* pstrdup */
+  s1 = pstrdup (pool, "sheep");
+  s2 = pstrdup (pool, s1);
+
+  s1[1] = 'l';
+
+  assert (strcmp (s2, "sheep") == 0);
+
+  /* pstrndup */
+  s1 = pstrndup (pool, "sheep", 3);
+  s2 = pstrndup (pool, "sheep", 6);
+
+  assert (strcmp (s1, "she") == 0);
+  assert (strcmp (s2, "sheep") == 0);
+
+  /* pmemdup */
+  s1 = pmemdup (pool, "waves", 6);
+
+  assert (strcmp (s1, "waves") == 0);
+
+  /* pstrsplit */
+  v1 = pstrsplit (pool, "one", "--");
+  v2 = pstrsplit (pool, "--one--two", "--");
+  v3 = pstrsplit (pool, "one--two--three", "--");
+  v4 = pstrsplit (pool, "one--two--three--four--", "--");
+
+  v5 = new_vector (pool, char *);
+  vector_push_back (v5, s_one);
+  assert (vector_compare (v1, v5, (int (*)(const void *,const void *))my_strcmp) == 0);
+  vector_push_back (v5, s_two);
+  assert (vector_compare (v2, v5, (int (*)(const void *,const void *))my_strcmp) == 0);
+  vector_push_back (v5, s_three);
+  assert (vector_compare (v3, v5, (int (*)(const void *,const void *))my_strcmp) == 0);
+  vector_push_back (v5, s_four);
+  assert (vector_compare (v4, v5, (int (*)(const void *,const void *))my_strcmp) == 0);
+
+  /* pstrcsplit */
+  v1 = pstrcsplit (pool, "one", ',');
+  v2 = pstrcsplit (pool, ",one,two", ',');
+  v3 = pstrcsplit (pool, "one,two,three,", ',');
+  v4 = pstrcsplit (pool, "one,two,three,four", ',');
+
+  v5 = new_vector (pool, char *);
+  vector_push_back (v5, s_one);
+  assert (vector_compare (v1, v5, (int (*)(const void *,const void *))my_strcmp) == 0);
+  vector_push_back (v5, s_two);
+  assert (vector_compare (v2, v5, (int (*)(const void *,const void *))my_strcmp) == 0);
+  vector_push_back (v5, s_three);
+  assert (vector_compare (v3, v5, (int (*)(const void *,const void *))my_strcmp) == 0);
+  vector_push_back (v5, s_four);
+  assert (vector_compare (v4, v5, (int (*)(const void *,const void *))my_strcmp) == 0);
+
+  /* pstrresplit */
+  re = pcre_compile ("[ \t]+", 0, &errptr, &erroffset, 0);
+  assert (re);
+  v1 = pstrresplit (pool, "one", re);
+  v2 = pstrresplit (pool, " one \ttwo", re);
+  v3 = pstrresplit (pool, " one\ttwo\tthree ", re);
+  v4 = pstrresplit (pool, "  one two \t three   four  ", re);
+
+  v5 = new_vector (pool, char *);
+  vector_push_back (v5, s_one);
+  assert (vector_compare (v1, v5, (int (*)(const void *,const void *))my_strcmp) == 0);
+  vector_push_back (v5, s_two);
+  assert (vector_compare (v2, v5, (int (*)(const void *,const void *))my_strcmp) == 0);
+  vector_push_back (v5, s_three);
+  assert (vector_compare (v3, v5, (int (*)(const void *,const void *))my_strcmp) == 0);
+  vector_push_back (v5, s_four);
+  assert (vector_compare (v4, v5, (int (*)(const void *,const void *))my_strcmp) == 0);
+  free (re);
+
+  /* pconcat, pjoin */
+  v1 = new_vector (pool, char *);
+  vector_push_back (v1, s_one);
+  vector_push_back (v1, s_two);
+  vector_push_back (v1, s_three);
+  vector_push_back (v1, s_four);
+  s1 = pconcat (pool, v1);
+  assert (strcmp (s1, "onetwothreefour") == 0);
+  s1 = pjoin (pool, v1, "");
+  assert (strcmp (s1, "onetwothreefour") == 0);
+  s1 = pjoin (pool, v1, ",");
+  assert (strcmp (s1, "one,two,three,four") == 0);
+  s1 = pjoin (pool, v1, ", ");
+  assert (strcmp (s1, "one, two, three, four") == 0);
+
+  /* pstrresplit2 -> pconcat = original string */
+  re = pcre_compile ("[ \t]+", 0, &errptr, &erroffset, 0);
+  s1 = "the quick brown fox";
+  v1 = pstrresplit2 (pool, s1, re);
+  s2 = pconcat (pool, v1);
+  assert (strcmp (s1, s2) == 0);
+
+  s1 = " the   quick \tbrown fox";
+  v1 = pstrresplit2 (pool, s1, re);
+  s2 = pconcat (pool, v1);
+  assert (strcmp (s1, s2) == 0);
+
+  s1 = "the quick brown  \tfox\t";
+  v1 = pstrresplit2 (pool, s1, re);
+  s2 = pconcat (pool, v1);
+  assert (strcmp (s1, s2) == 0);
+
+  s1 = "  \tthe quick brown  \tfox\t";
+  v1 = pstrresplit2 (pool, s1, re);
+  s2 = pconcat (pool, v1);
+  assert (strcmp (s1, s2) == 0);
+  free (re);
+
+  /* psort */
+  v1 = new_vector (pool, char *);
+  vector_push_back (v1, s_one);
+  vector_push_back (v1, s_two);
+  vector_push_back (v1, s_three);
+  vector_push_back (v1, s_four);
+  psort (v1, my_strcmp);
+  s1 = pconcat (pool, v1);
+  assert (strcmp (s1, "fouronethreetwo") == 0);
+
+  /* pchomp */
+  s1 = pstrdup (pool, "sheep");
+  pchomp (s1);
+  assert (strcmp (s1, "sheep") == 0);
+  s1 = pstrdup (pool, "sheep\r");
+  pchomp (s1);
+  assert (strcmp (s1, "sheep") == 0);
+  s1 = pstrdup (pool, "sheep\r\n");
+  pchomp (s1);
+  assert (strcmp (s1, "sheep") == 0);
+  s1 = pstrdup (pool, "sheep\n");
+  pchomp (s1);
+  assert (strcmp (s1, "sheep") == 0);
+
+  /* pchrs, pstrs */
+  s1 = pchrs (pool, 'x', 20);
+  assert (strcmp (s1, "xxxxxxxxxxxxxxxxxxxx") == 0);
+  s1 = pchrs (pool, 'x', 0);
+  assert (strcmp (s1, "") == 0);
+  s1 = pstrs (pool, "x", 20);
+  assert (strcmp (s1, "xxxxxxxxxxxxxxxxxxxx") == 0);
+  s1 = pstrs (pool, "xyz", 10);
+  assert (strcmp (s1, "xyzxyzxyzxyzxyzxyzxyzxyzxyzxyz") == 0);
+  s1 = pstrs (pool, "xyz", 0);
+  assert (strcmp (s1, "") == 0);
+  s1 = pstrs (pool, "", 100);
+  assert (strcmp (s1, "") == 0);
+
+  /* psprintf (also implicitly tests pvsprintf) */
+  s1 = psprintf (pool, "%d %s %s %s %s",
+                4, "one", "two", "three", "four");
+  assert (strcmp (s1, "4 one two three four") == 0);
+  for (i = 250; i < 270; ++i)
+    {
+      s1 = pchrs (pool, 'x', i);
+      s2 = psprintf (pool, "%s", s1);
+      assert (strcmp (s1, s2) == 0);
+    }
+
+  /* pvector, pvectora */
+  s1 = pjoin (pool, pvector (pool, "one", "two", "three", "four", 0), ",");
+  assert (strcmp (s1, "one,two,three,four") == 0);
+  s1 = pjoin (pool, pvectora (pool, stra, 4), ",");
+  assert (strcmp (s1, "one,two,three,four") == 0);
+
+  /* pitoa, pdtoa, pxtoa */
+  assert (strcmp (pitoa (pool, 1), "1") == 0);
+  assert (strcmp (pdtoa (pool, 2.1), "2.100000") == 0);
+  assert (strcmp (pxtoa (pool, 15), "f") == 0);
+
+  /* pvitostr, pvdtostr, pvxtostr */
+  v1 = new_vector (pool, int);
+  vector_push_back (v1, i_one);
+  vector_push_back (v1, i_two);
+  vector_push_back (v1, i_three);
+  vector_push_back (v1, i_four);
+  s1 = pjoin (pool, pvitostr (pool, v1), ",");
+  assert (strcmp (s1, "1,2,3,4") == 0);
+
+  v1 = new_vector (pool, double);
+  vector_push_back (v1, d_one);
+  vector_push_back (v1, d_two);
+  vector_push_back (v1, d_three);
+  vector_push_back (v1, d_four);
+  s1 = pjoin (pool, pvdtostr (pool, v1), ",");
+  assert (strcmp (s1, "1.000000,2.000000,3.000000,4.000000") == 0);
+
+  v1 = new_vector (pool, unsigned);
+  vector_push_back (v1, i_15);
+  vector_push_back (v1, i_31);
+  vector_push_back (v1, i_63);
+  vector_push_back (v1, i_127);
+  s1 = pjoin (pool, pvxtostr (pool, v1), ",");
+  assert (strcmp (s1, "f,1f,3f,7f") == 0);
+
+  /* pstrcat */
+  s1 = pstrdup (pool, "one");
+  s1 = pstrcat (pool, s1, ",two");
+  assert (strcmp (s1, "one,two") == 0);
+
+  /* pstrncat */
+  s1 = pstrdup (pool, "one");
+  s1 = pstrncat (pool, s1, ",two,three", 4);
+  assert (strcmp (s1, "one,two") == 0);
+
+  /* psubstr */
+  s1 = psubstr (pool, "sheep", 1, 2);
+  assert (strcmp (s1, "he") == 0);
+  s1 = psubstr (pool, "sheep", 1, -1);
+  assert (strcmp (s1, "heep") == 0);
+
+  /* pstrupr, pstrlwr */
+  s1 = pstrdup (pool, "sheep");
+  pstrupr (s1);
+  assert (strcmp (s1, "SHEEP") == 0);
+  pstrlwr (s1);
+  assert (strcmp (s1, "sheep") == 0);
+
+  /* pgetline, pgetlinex, pgetlinec */
+#define TEST_PGETL(getfn,input,expect) s1 = pstrdup (pool, ""); fp = tmpfile (); for (sp = input; *sp; ++sp) fputs (*sp, fp); rewind (fp); for (sp = expect; *sp; ++sp) { s1 = getfn (pool, fp, s1); assert (strcmp (s1, *sp) == 0); } assert (getfn (pool, fp, s1) == 0); fclose (fp);
+
+  TEST_PGETL (pgetline, file1, res1);
+  TEST_PGETL (pgetline, file2, res1);
+  TEST_PGETL (pgetlinec, file3, res1);
+  TEST_PGETL (pgetlinec, file4, res2);
+  TEST_PGETL (pgetlinec, file5, res1);
+
+  /* ptrim, ptrimfront, ptrimback */
+  s1 = pstrdup (pool, "          sheep\t\t\t");
+  ptrim (s1);
+  assert (strcmp (s1, "sheep") == 0);
+  s1 = pstrdup (pool, "sheep   ");
+  ptrim (s1);
+  assert (strcmp (s1, "sheep") == 0);
+  s1 = pstrdup (pool, "          sheep");
+  ptrim (s1);
+  assert (strcmp (s1, "sheep") == 0);
+  s1 = pstrdup (pool, "sheep");
+  ptrim (s1);
+  assert (strcmp (s1, "sheep") == 0);
+  s1 = pstrdup (pool, "");
+  ptrim (s1);
+  assert (strcmp (s1, "") == 0);
+
+  s1 = pstrdup (pool, "          sheep");
+  ptrimfront (s1);
+  assert (strcmp (s1, "sheep") == 0);
+  s1 = pstrdup (pool, "sheep  ");
+  ptrimfront (s1);
+  assert (strcmp (s1, "sheep  ") == 0);
+  s1 = pstrdup (pool, "sheep");
+  ptrimfront (s1);
+  assert (strcmp (s1, "sheep") == 0);
+  s1 = pstrdup (pool, "");
+  ptrimfront (s1);
+  assert (strcmp (s1, "") == 0);
+
+  s1 = pstrdup (pool, "          sheep");
+  ptrimback (s1);
+  assert (strcmp (s1, "          sheep") == 0);
+  s1 = pstrdup (pool, "sheep  ");
+  ptrimback (s1);
+  assert (strcmp (s1, "sheep") == 0);
+  s1 = pstrdup (pool, "sheep");
+  ptrimback (s1);
+  assert (strcmp (s1, "sheep") == 0);
+  s1 = pstrdup (pool, "");
+  ptrimback (s1);
+  assert (strcmp (s1, "") == 0);
+
+  delete_pool (pool);
+  exit (0);
+}
diff --git a/test_sash.c b/test_sash.c
new file mode 100644 (file)
index 0000000..4c22db4
--- /dev/null
@@ -0,0 +1,93 @@
+/* Test the sash (string hash) class.
+ * By Richard W.M. Jones <rich@annexia.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id: test_sash.c,v 1.1 2001/02/08 12:51:32 rich Exp $
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include <pool.h>
+#include <vector.h>
+#include <pstring.h>
+#include <hash.h>
+
+int
+main ()
+{
+  sash h;
+  pool pool = new_pool (), pool2;
+  const char *v;
+  vector keys, values;
+
+  /* Create a string -> string hash. */
+  h = new_sash (pool);
+
+  /* Insert some new values. */
+  if (sash_insert (h, "tomato", "red") != 0) abort ();
+  if (sash_insert (h, "orange", "orange") != 0) abort ();
+  if (sash_insert (h, "lemon", "yellow") != 0) abort ();
+  if (sash_insert (h, "lime", "green") != 0) abort ();
+  if (sash_insert (h, "peach", "orange") != 0) abort ();
+  if (sash_insert (h, "apple", "green") != 0) abort ();
+  if (sash_insert (h, "raspberry", "red") != 0) abort ();
+
+  /* This should replace existing values. */
+  if (sash_insert (h, "apple", "red") == 0) abort ();
+  if (sash_insert (h, "peach", "yellow") == 0) abort ();
+
+  /* Retrieve some values. */
+  if (sash_get (h, "apple", v) == 0 || strcmp (v, "red") != 0) abort ();
+  if (sash_get (h, "tomato", v) == 0 || strcmp (v, "red") != 0) abort ();
+  if (sash_get (h, "orange", v) == 0 || strcmp (v, "orange") != 0) abort ();
+
+  /* Copy the sash. */
+  h = copy_sash (pool, h);
+
+  /* Erase a key and check that it no longer exists. */
+  if (sash_erase (h, "apple") == 0) abort ();
+  if (sash_get (h, "apple", v) != 0) abort ();
+
+  /* Get list of keys and values. */
+  keys = sash_keys (h);
+  values = sash_values (h);
+
+  printf ("keys = [ %s ]\n", pjoin (pool, keys, ", "));
+  printf ("values = [ %s ]\n", pjoin (pool, values, ", "));
+
+  /* Copy the sash into another pool, delete the old pool, check all
+   * keys and values have been copied across.
+   */
+  pool2 = new_pool ();
+  h = copy_sash (pool2, h);
+  delete_pool (pool);
+
+  keys = sash_keys (h);
+  values = sash_values (h);
+
+  printf ("keys = [ %s ]\n", pjoin (pool2, keys, ", "));
+  printf ("values = [ %s ]\n", pjoin (pool2, values, ", "));
+
+  delete_pool (pool2);
+  exit (0);
+}
diff --git a/test_shash.c b/test_shash.c
new file mode 100644 (file)
index 0000000..f867a42
--- /dev/null
@@ -0,0 +1,101 @@
+/* Test the shash (string -> something hash) class.
+ * By Richard W.M. Jones <rich@annexia.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id: test_shash.c,v 1.2 2002/08/23 09:44:08 rich Exp $
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include <pool.h>
+#include <vector.h>
+#include <pstring.h>
+#include <hash.h>
+
+const int red = 1, orange = 2, yellow = 3, green = 4;
+
+int
+main ()
+{
+  shash h;
+  pool pool = new_pool (), pool2, tmp;
+  int v;
+  vector keys, values;
+
+  /* Create a string -> string hash. */
+  h = new_shash (pool, int);
+
+  /* Insert some new values. */
+  if (shash_insert (h, "tomato", red) != 0) abort ();
+  if (shash_insert (h, "orange", orange) != 0) abort ();
+  if (shash_insert (h, "lemon", yellow) != 0) abort ();
+  if (shash_insert (h, "lime", green) != 0) abort ();
+  if (shash_insert (h, "peach", orange) != 0) abort ();
+  if (shash_insert (h, "apple", green) != 0) abort ();
+  if (shash_insert (h, "raspberry", red) != 0) abort ();
+
+  /* This should replace existing values. */
+  if (shash_insert (h, "apple", red) == 0) abort ();
+  if (shash_insert (h, "peach", yellow) == 0) abort ();
+
+  /* Retrieve some values. */
+  if (shash_get (h, "apple", v) == 0 || v != red) abort ();
+  if (shash_get (h, "tomato", v) == 0 || v != red) abort ();
+  if (shash_get (h, "orange", v) == 0 || v != orange) abort ();
+
+  /* Copy the shash. */
+  h = copy_shash (pool, h);
+
+  /* Erase a key and check that it no longer exists. */
+  if (shash_erase (h, "apple") == 0) abort ();
+  if (shash_get (h, "apple", v) != 0) abort ();
+
+  /* Get list of keys and values. */
+  keys = shash_keys (h);
+  values = shash_values (h);
+
+  printf ("keys = [ %s ]\n", pjoin (pool, keys, ", "));
+  printf ("values = [ %s ]\n", pjoin (pool, pvitostr (pool, values), ", "));
+
+  /* Regression test: get list of keys into another temporary pool. */
+  tmp = new_pool ();
+  keys = shash_keys_in_pool (h, tmp);
+  printf ("keys = [ %s ]\n", pjoin (pool, keys, ", "));
+  delete_pool (tmp);
+
+  /* Copy the shash into another pool, delete the old pool, check all
+   * keys and values have been copied across.
+   */
+  pool2 = new_pool ();
+  h = copy_shash (pool2, h);
+  delete_pool (pool);
+
+  keys = shash_keys (h);
+  values = shash_values (h);
+
+  printf ("keys = [ %s ]\n", pjoin (pool2, keys, ", "));
+  printf ("values = [ %s ]\n", pjoin (pool2, pvitostr (pool2, values), ", "));
+
+  delete_pool (pool2);
+  exit (0);
+}
diff --git a/test_tree.c b/test_tree.c
new file mode 100644 (file)
index 0000000..200bd54
--- /dev/null
@@ -0,0 +1,148 @@
+/* Test the tree class.
+ * By Richard W.M. Jones <rich@annexia.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id: test_tree.c,v 1.1 2002/09/15 15:08:52 rich Exp $
+ *
+ * XXX This test is incomplete.
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#ifdef HAVE_ASSERT_H
+#include <assert.h>
+#endif
+
+#include "pool.h"
+#include "tree.h"
+
+int
+main ()
+{
+  pool pool1 = new_subpool (global_pool), pool2;
+  tree root, leaf1, leaf2, leaf3, t;
+  const char *root_node = "root node";
+  const char *leaf1_node = "leaf1 node";
+  const char *leaf2_node = "leaf2 node";
+  const char *leaf3_node = "leaf3 node";
+  char *str;
+
+  /* Create a simple node and test node access functions. */
+  root = new_tree (pool1, char *);
+
+  tree_set_data (root, root_node);
+
+  leaf1 = new_tree (pool1, char *);
+  tree_set_data (leaf1, leaf1_node);
+  leaf2 = new_tree (pool1, char *);
+  tree_set_data (leaf2, leaf2_node);
+  leaf3 = new_tree (pool1, char *);
+  tree_set_data (leaf3, leaf3_node);
+  tree_push_back (root, leaf1);
+  tree_push_back (root, leaf2);
+  tree_push_back (root, leaf3);
+
+  assert (tree_size (root) == 3);
+
+  tree_get (root, 0, t);
+  assert (t == leaf1);
+  tree_get (root, 1, t);
+  assert (t == leaf2);
+  tree_get (root, 2, t);
+  assert (t == leaf3);
+
+  tree_pop_front (root, t);
+  assert (t == leaf1);
+  tree_pop_back (root, t);
+  assert (t == leaf3);
+  tree_pop_front (root, t);
+  assert (t == leaf2);
+
+  assert (tree_size (root) == 0);
+
+  tree_insert (root, 0, leaf1);
+  tree_insert (root, 1, leaf2);
+  tree_insert (root, 2, leaf3);
+
+  tree_get (root, 0, t);
+  assert (t == leaf1);
+  tree_get (root, 1, t);
+  assert (t == leaf2);
+  tree_get (root, 2, t);
+  assert (t == leaf3);
+
+  tree_replace (root, 0, leaf3);
+  tree_replace (root, 1, leaf1);
+  tree_replace (root, 2, leaf2);
+
+  tree_get (root, 0, t);
+  assert (t == leaf3);
+  tree_get (root, 1, t);
+  assert (t == leaf1);
+  tree_get (root, 2, t);
+  assert (t == leaf2);
+
+  tree_erase (root, 0);
+  assert (tree_size (root) == 2);
+
+  tree_erase_range (root, 0, 2);
+  assert (tree_size (root) == 0);
+
+  tree_insert (root, 0, leaf1);
+  tree_insert (root, 1, leaf2);
+  tree_insert (root, 2, leaf3);
+
+  tree_clear (root);
+  assert (tree_size (root) == 0);
+
+  tree_get_data (root, str);
+  assert (strcmp (str, root_node) == 0);
+
+  /* Copy the tree into another pool, delete the original. */
+  tree_insert (root, 0, leaf1);
+  tree_insert (root, 1, leaf2);
+  tree_insert (root, 2, leaf3);
+
+  pool2 = new_subpool (global_pool);
+  root = copy_tree (pool2, root);
+  delete_pool (pool1);
+
+  assert (tree_size (root) == 3);
+
+  tree_get_data (root, str);
+  assert (strcmp (str, root_node) == 0);
+
+  tree_get (root, 0, t);
+  tree_get_data (t, str);
+  assert (strcmp (str, leaf1_node) == 0);
+
+  tree_get (root, 1, t);
+  tree_get_data (t, str);
+  assert (strcmp (str, leaf2_node) == 0);
+
+  tree_get (root, 2, t);
+  tree_get_data (t, str);
+  assert (strcmp (str, leaf3_node) == 0);
+
+  exit (0);
+}
diff --git a/test_vector.c b/test_vector.c
new file mode 100644 (file)
index 0000000..28fb569
--- /dev/null
@@ -0,0 +1,78 @@
+/* Test the vector class.
+ * By Richard W.M. Jones <rich@annexia.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id: test_vector.c,v 1.2 2001/02/16 12:55:54 rich Exp $
+ *
+ * XXX This test is very incomplete at present.
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#ifdef HAVE_ASSERT_H
+#include <assert.h>
+#endif
+
+#include <pool.h>
+#include <vector.h>
+#include <pstring.h>
+
+/* These are the numbers we'll be inserting into the array. */
+static int numbers1to9[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+
+static void sqr_ptr (int *a, int *r) { *r = *a * *a; }
+static int gt20_ptr (int *a) { return *a > 20; }
+
+int
+main ()
+{
+  pool pool = new_pool ();
+  vector numbers, squares, squaresgt20;
+
+  /* Create initial vector. */
+  numbers = new_vector (pool, int);
+  vector_insert_array (numbers, 0, numbers1to9, 9);
+  assert (vector_size (numbers) == 9);
+
+  /* Print numbers. */
+  printf ("numbers = [ %s ]\n",
+         pjoin (pool, pvitostr (pool, numbers), ", "));
+
+  /* Square each number. */
+  squares = vector_map (pool, numbers,
+                       (void (*) (const void *, void *)) sqr_ptr,
+                       int);
+  assert (vector_size (squares) == 9);
+  printf ("squares = [ %s ]\n",
+         pjoin (pool, pvitostr (pool, squares), ", "));
+
+  /* Get squares > 20. */
+  squaresgt20 = vector_grep (pool, squares,
+                            (int (*) (const void *)) gt20_ptr);
+  assert (vector_size (squaresgt20) == 5);
+  printf ("squares > 20 = [ %s ]\n",
+         pjoin (pool, pvitostr (pool, squaresgt20), ", "));
+
+  delete_pool (pool);
+  exit (0);
+}
diff --git a/trace/.cvsignore b/trace/.cvsignore
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/trace/curallocs.pl b/trace/curallocs.pl
new file mode 100755 (executable)
index 0000000..30901ae
--- /dev/null
@@ -0,0 +1,187 @@
+#!/usr/bin/perl -w
+
+# Show current allocations from a trace file. If run over a trace file
+# from a program which has exited, this will show memory leaks. If run
+# over a trace file for a program which is currently running, this will
+# show currently allocated space.
+#
+# By Richard W.M. Jones <rich@annexia.org>
+#
+# $Id: curallocs.pl,v 1.1 2001/02/08 12:51:35 rich Exp $
+
+use strict;
+
+my %pools = ();
+
+my $lineno = 0;
+
+while (<>)
+  {
+    $lineno++;
+
+    s/[\n\r]+$//;
+
+    if (/^([a-z_]+)\s+caller:\s+([0-9a-fx]+)\s+ptr1:\s+([0-9a-fx]+|\(nil\))\s+ptr2:\s+([0-9a-fx]+|\(nil\))\s+ptr3:\s+([0-9a-fx]+|\(nil\))\s+i1:\s+([0-9]+)\s*$/)
+      {
+       my $fn = $1;
+       my $caller = $2;
+       my $ptr1 = $3 ne '(nil)' ? $3 : 0;
+       my $ptr2 = $4 ne '(nil)' ? $4 : 0;
+       my $ptr3 = $5 ne '(nil)' ? $4 : 0;
+       my $i1 = $6;
+
+       if ($fn eq "new_pool")
+         {
+           die "new_pool: pool exists, line $lineno"
+             if exists $pools{$ptr1};
+
+           $pools{$ptr1} = {
+                            creator => $caller,
+                            pool => $ptr1,
+                            children => {},
+                            allocations => {}
+                           };
+         }
+       elsif ($fn eq "new_subpool")
+         {
+           die "new_subpool: pool exists, line $lineno"
+             if exists $pools{$ptr1};
+
+           $pools{$ptr1} = {
+                            creator => $caller,
+                            pool => $ptr1,
+                            parent => $ptr2,
+                            children => {},
+                            allocations => {}
+                           };
+           $pools{$ptr2}{children}{$ptr1} = 1;
+         }
+       elsif ($fn eq "delete_pool")
+         {
+           if ($pools{$ptr1}{parent})
+             {
+               delete $pools{$pools{$ptr1}{parent}}{children}{$ptr1};
+             }
+
+           remove_pool_recursively ($ptr1);
+         }
+       elsif ($fn eq "pmalloc")
+         {
+           die "pmalloc: no pool $ptr1, line $lineno"
+             unless exists $pools{$ptr1};
+
+           $pools{$ptr1}{allocations}{$ptr2} = {
+                                                creator => $caller,
+                                                pool => $ptr1,
+                                                address => $ptr2,
+                                                size => $i1
+                                               };
+         }
+       elsif ($fn eq "prealloc")
+         {
+           die "prealloc: no pool $ptr1, line $lineno"
+             unless exists $pools{$ptr1};
+           die "prealloc: allocation already exists, line $lineno"
+             unless exists $pools{$ptr1}{allocations}{$ptr2};
+
+           # Delete the old allocation.
+           delete $pools{$ptr1}{allocations}{$ptr2};
+
+           $pools{$ptr1}{allocations}{$ptr3} = {
+                                                creator => $caller,
+                                                pool => $ptr1,
+                                                address => $ptr3,
+                                                size => $i1
+                                               };
+         }
+       else
+         {
+           die "unknown pool function traced: $fn, line $lineno";
+         }
+      }
+    else
+      {
+       print "$lineno: $_\n";
+       die "cannot parse line";
+      }
+  }
+
+if (keys %pools > 0) {
+  show_pools ();
+} else {
+  print "No pools are currently allocated.\n";
+}
+
+exit 0;
+
+sub remove_pool_recursively
+  {
+    my $pool = shift;
+    local $_;
+
+    die unless exists $pools{$pool};
+
+    # Remove children first.
+    foreach (keys %{$pools{$pool}{children}})
+      {
+       remove_pool_recursively ($_);
+      }
+
+    delete $pools{$pool};
+  }
+
+sub show_pools
+  {
+    local $_;
+
+    foreach (keys %pools)
+      {
+       show_pool ($_);
+      }
+  }
+
+sub show_pool
+  {
+    my $pool = shift;
+    my $indent = shift || 0;
+    local $_;
+
+    my $sp = " " x $indent;
+
+    print $sp, "pool $pool created by $pools{$pool}{creator}:\n";
+    print $sp, "  number of direct allocations: ", 0 + keys %{$pools{$pool}{allocations}}, "\n";
+    print $sp, "  number of children: ", 0 + keys %{$pools{$pool}{children}}, "\n";
+    print $sp, "  allocations:\n";
+
+    show_allocations ($pools{$pool}{allocations}, $indent);
+
+    print $sp, "  children:\n";
+
+    foreach (keys %{$pools{$pool}{children}})
+      {
+       show_pool ($_, $indent + 2);
+      }
+  }
+
+sub show_allocations
+  {
+    my $allocations = shift;
+    my $indent = shift || 0;
+    local $_;
+
+    foreach (keys %$allocations)
+      {
+       show_allocation ($allocations->{$_}, $indent);
+      }
+  }
+
+sub show_allocation
+  {
+    my $allocation = shift;
+    my $indent = shift || 0;
+    local $_;
+
+    my $sp = " " x $indent;
+
+    print $sp, "    allocation $allocation->{address} created by $allocation->{creator} size $allocation->{size}\n";
+  }
diff --git a/tree.c b/tree.c
new file mode 100644 (file)
index 0000000..06d10a8
--- /dev/null
+++ b/tree.c
@@ -0,0 +1,78 @@
+/* A tree class.
+ * - By Richard W.M. Jones <rich@annexia.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id: tree.c,v 1.2 2002/10/08 15:10:28 rich Exp $
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include <pool.h>
+#include <vector.h>
+#include <pstring.h>
+
+#include "tree.h"
+
+tree
+_tree_new (pool pool, size_t size)
+{
+  tree t = (tree) new_vector (pool, tree);
+
+  t = prealloc (pool, t, sizeof (*t) + size);
+  t->size = size;
+
+  return t;
+}
+
+extern tree
+copy_tree (pool pool, tree t)
+{
+  tree nt = _tree_new (pool, t->size);
+  int i;
+
+  /* Copy the node data. */
+  memcpy (nt->data, t->data, t->size);
+
+  /* Copy each subnode, recursively. */
+  for (i = 0; i < tree_size (t); ++i)
+    {
+      tree st, nst;
+
+      tree_get (t, i, st);
+      nst = copy_tree (pool, st);
+      tree_push_back (nt, nst);
+    }
+
+  return nt;
+}
+
+void
+_tree_get_data (tree t, void *ptr)
+{
+  if (ptr) memcpy (ptr, t->data, t->size);
+}
+
+void
+_tree_set_data (tree t, const void *ptr)
+{
+  if (ptr) memcpy (t->data, ptr, t->size);
+}
diff --git a/tree.h b/tree.h
new file mode 100644 (file)
index 0000000..ecb282f
--- /dev/null
+++ b/tree.h
@@ -0,0 +1,188 @@
+/* A tree class.
+ * By Richard W.M. Jones <rich@annexia.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id: tree.h,v 1.1 2002/09/15 15:08:52 rich Exp $
+ */
+
+#ifndef TREE_H
+#define TREE_H
+
+#include <pool.h>
+#include <vector.h>
+
+struct tree
+{
+  struct vector v;             /* Vector of subnodes. */
+  size_t size;                 /* Size of the data. */
+  char data[0];                        /* Opaque data (used by the application). */
+};
+
+typedef struct tree *tree;
+
+/* Function: new_tree - allocate a new tree, node or leaf
+ * Function: _tree_new
+ *
+ * Allocate a new tree / node / leaf.
+ *
+ * A node in the tree is defined as a list of pointers to subnodes
+ * and some data stored in the node itself. Because of the recursive
+ * definition of trees, a tree is just a node, the special 'root'
+ * node. A leaf is just a node which happens to have no subnodes. You
+ * can add subnodes to a leaf later if you want.
+ *
+ * The @code{new_vector} macro is used to allocate a node in the
+ * tree storing data @code{type} in the node. It just evaluates the
+ * size of @code{type} and calls @code{_tree_new} which actually
+ * allocates the node.
+ *
+ * Unless you are very careful with types, you should always make
+ * sure that each node in your tree has the same @code{type}.
+ *
+ * Returns: The tree / node (of type @code{tree}).
+ */
+#define new_tree(pool,type) _tree_new ((pool), sizeof (type))
+extern tree _tree_new (pool, size_t size);
+
+/* Function: tree_get_data - access the data stored in a node
+ * Function: _tree_get_data
+ * Function: tree_set_data
+ * Function: _tree_set_data
+ *
+ * These functions allow you to access the data stored in the node.
+ *
+ * @code{tree_get_data} copies the data out of the node into the
+ * local variable.
+ *
+ * @code{tree_set_data} copies the data from the local variable into
+ * the node.
+ */
+#define tree_get_data(t,obj) _tree_get_data ((t), &(obj))
+extern void _tree_get_data (tree t, void *ptr);
+#define tree_set_data(t,obj) _tree_set_data ((t), &(obj))
+extern void _tree_set_data (tree t, const void *ptr);
+
+/* Function: copy_tree - make a deep copy of a tree
+ *
+ * Make a deep copy of tree @code{t} into pool @code{pool}. This
+ * copies all of the nodes and the data in those nodes recursively
+ * Note however that if the data in a node is a / contains a pointer
+ * then the pointed-to data will not be copied.
+ *
+ * Returns: The copied tree (of type @code{tree}).
+ */
+extern tree copy_tree (pool, tree t);
+
+/* Function: tree_push_back - add or remove subnodes to or from a node
+ * Function: tree_pop_back
+ * Function: tree_push_front
+ * Function: tree_pop_front
+ *
+ * The @code{*_push_*} functions push subnodes into nodes.
+ *
+ * The @code{*_pop_*} functions pop subnodes off nodes into local variables.
+ *
+ * The @code{*_front} functions push and pop subnodes off the front
+ * of a node.
+ *
+ * The @code{*_back} functions push and pop subnodes
+ * off the end of the node.
+ *
+ * Array indexes are checked. You cannot pop a node which has
+ * no subnodes.
+ */
+#define tree_push_back(t,subnode) (vector_push_back ((vector)(t), (subnode)))
+#define tree_pop_back(t,subnode) (vector_pop_back ((vector)(t), (subnode)))
+#define tree_push_front(t,subnode) (vector_push_front ((vector)(t), (subnode)))
+#define tree_pop_front(t,subnode) (vector_pop_front ((vector)(t), (subnode)))
+
+/* Function: tree_get_subnode - get a particular subnode of a node
+ * Function: tree_get
+ *
+ * @code{tree_get_subnode} returns the @code{i}th subnode of a node. The
+ * node is unaffected.
+ *
+ * @code{tree_get} is identical.
+ */
+#define tree_get_subnode(t,i,subnode) tree_get((t), (i), (subnode))
+#define tree_get(t,i,subnode) (vector_get ((vector)(t), (i), (subnode)))
+
+/* Function: tree_insert - insert subnodes into a tree
+ * Function: tree_insert_array
+ *
+ * @code{tree_insert} inserts a single subnode @code{subnode} before subnode
+ * @code{i}. All other subnodes are moved up to make space.
+ *
+ * @code{tree_insert_array} inserts an array of @code{n} subnodes
+ * starting at address @code{ptr} into the node before index
+ * @code{i}.
+ *
+ * Array indexes are checked.
+ */
+#define tree_insert(t,i,subnode) (vector_insert ((vector)(t), (i), (subnode)))
+#define tree_insert_array(t,i,ptr,n) (vector_insert_array ((vector)(t), (i), (ptr), (n)))
+
+/* Function: tree_replace - replace subnodes of a node
+ * Function: tree_replace_array
+ *
+ * @code{tree_replace} replaces the single subnode at
+ * @code{v[i]} with @code{subnode}.
+ *
+ * @code{tree_replace_array} replaces the @code{n} subnodes
+ * in the node starting at index @code{i} with the @code{n}
+ * subnodes from the array @code{ptr}.
+ * 
+ * Array indexes are checked.
+ */
+#define tree_replace(t,i,subnode) (vector_replace ((vector)(t), (i), (subnode)))
+#define tree_replace_array(t,i,ptr,n) (vector_replace_array ((vector)(t), (i), (ptr), (n)))
+
+/* Function: tree_erase - erase subnodes of a node
+ * Function: tree_erase_range
+ * Function: tree_clear
+ *
+ * @code{tree_erase} removes the subnode index @code{i}, shuffling
+ * the later subnodes down by one place to fill the space.
+ *
+ * @code{tree_erase_range} removes a range of subnodes @code{i}
+ * to @code{j-1} (@code{i <= j}), shuffling later subnodes down
+ * to fill the space.
+ *
+ * @code{tree_clear} removes all subnodes from the node, setting
+ * its size to @code{0}, and effectively making the node into a leaf.
+ *
+ * Array indexes are checked.
+ */
+#define tree_erase(t,i) (vector_erase ((vector)(t), (i)))
+#define tree_erase_range(t,i,j) (vector_erase_range ((vector)(t), (i), (j)))
+#define tree_clear(t) (vector_clear ((vector)(t)))
+
+/* Function: tree_size - return the number of subnodes of a node
+ * Function: tree_nr_subnodes
+ *
+ * Return the size (ie. number of subnodes) in the node. The
+ * @code{tree_nr_subnodes} macro is identical.
+ */
+#define tree_size(t) (vector_size ((vector)(t)))
+#define tree_nr_subnodes(t) tree_size(t)
+
+/* Function: tree_swap - swap the order of two subnodes of a node
+ *
+ * Swap subnodes @code{i} and @code{j} of tree @code{t}.
+ */
+#define tree_swap(t,i,j) (vector_swap ((vector)(t), (i), (j)))
+
+#endif /* TREE_H */
diff --git a/vector.c b/vector.c
new file mode 100644 (file)
index 0000000..5f4e43b
--- /dev/null
+++ b/vector.c
@@ -0,0 +1,353 @@
+/* A vector class.
+ * - By Richard W.M. Jones <rich@annexia.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id: vector.c,v 1.4 2002/10/27 16:04:42 rich Exp $
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#ifdef HAVE_ASSERT_H
+#include <assert.h>
+#endif
+
+#include <pstring.h>
+#include <pool.h>
+#include <vector.h>
+
+#define INCREMENT 16
+
+vector
+_vector_new (pool pool, size_t size)
+{
+  vector v = pmalloc (pool, sizeof *v);
+
+  v->pool = pool;
+  v->size = size;
+  v->data = 0;
+  v->used = v->allocated = 0;
+
+  return v;
+}
+
+inline vector
+new_subvector (pool pool, vector v, int i, int j)
+{
+  vector new_v = pmalloc (pool, sizeof *v);
+
+  assert (0 <= i && j <= v->used);
+
+  new_v->pool = pool;
+  new_v->size = v->size;
+
+  if (i < j)
+    {
+      new_v->data = pmemdup (pool, v->data + i * v->size, (j - i) * v->size);
+      new_v->used = new_v->allocated = j - i;
+    }
+  else
+    {
+      new_v->data = 0;
+      new_v->used = new_v->allocated = 0;
+    }
+
+  return new_v;
+}
+
+vector
+copy_vector (pool pool, vector v)
+{
+  return new_subvector (pool, v, 0, v->used);
+}
+
+inline void
+_vector_push_back (vector v, const void *ptr)
+{
+  if (v->used >= v->allocated)
+    {
+      int a = v->allocated + INCREMENT;
+      void *d = prealloc (v->pool, v->data, a * v->size);
+      v->allocated = a;
+      v->data = d;
+    }
+
+  if (ptr) memcpy (v->data + v->used * v->size, ptr, v->size);
+  v->used++;
+}
+
+void
+_vector_pop_back (vector v, void *ptr)
+{
+  assert (v->used > 0);
+  v->used--;
+  if (ptr) memcpy (ptr, v->data + v->used * v->size, v->size);
+}
+
+inline void
+vector_insert_array (vector v, int i, const void *ptr, int n)
+{
+  int j;
+
+  assert (0 <= i && i <= v->used);
+
+  /* Insert n dummy elements at the end of the list. */
+  for (j = 0; j < n; ++j) _vector_push_back (v, 0);
+
+  /* Move the other elements up. */
+  for (j = v->used-1; j > i; --j)
+    memcpy (v->data + j * v->size, v->data + (j-n) * v->size, v->size);
+
+  /* Insert these elements at position i. */
+  if (ptr) memcpy (v->data + i * v->size, ptr, v->size * n);
+}
+
+void
+_vector_insert (vector v, int i, const void *ptr)
+{
+  vector_insert_array (v, i, ptr, 1);
+}
+
+void
+_vector_push_front (vector v, const void *ptr)
+{
+  _vector_insert (v, 0, ptr);
+}
+
+void
+_vector_pop_front (vector v, void *ptr)
+{
+  _vector_get (v, 0, ptr);
+  vector_erase (v, 0);
+}
+
+void
+vector_push_back_vector (vector v, const vector w)
+{
+  int size = v->size;
+
+  assert (size == w->size);
+
+  if (v->used + w->used > v->allocated)
+    {
+      int a = v->used + w->used;
+      void *d = prealloc (v->pool, v->data, a * size);
+      v->allocated = a;
+      v->data = d;
+    }
+
+  memcpy (v->data + v->used * size, w->data, size * w->used);
+  v->used += w->used;
+}
+
+void
+vector_push_front_vector (vector v, const vector w)
+{
+  int size = v->size;
+
+  assert (size == w->size);
+
+  if (v->used + w->used > v->allocated)
+    {
+      int a = v->used + w->used;
+      void *d = prealloc (v->pool, v->data, a * size);
+      v->allocated = a;
+      v->data = d;
+    }
+
+  memmove (v->data + w->used * size, v->data, v->used * size);
+  memcpy (v->data, w->data, size * w->used);
+  v->used += w->used;
+}
+
+void
+_vector_replace (vector v, int i, const void *ptr)
+{
+  assert (0 <= i && i < v->used);
+
+  if (ptr) memcpy (v->data + i * v->size, ptr, v->size);
+}
+
+inline void
+vector_erase_range (vector v, int i, int j)
+{
+  assert (0 <= i && i < v->used && 0 <= j && j <= v->used);
+
+  if (i < j)
+    {
+      int n = j - i, k;
+
+      for (k = i+n; k < v->used; ++k)
+       memcpy (v->data + (k-n) * v->size, v->data + k * v->size, v->size);
+
+      v->used -= n;
+    }
+}
+
+void
+vector_erase (vector v, int i)
+{
+  vector_erase_range (v, i, i+1);
+}
+
+void
+vector_clear (vector v)
+{
+  v->used = 0;
+}
+
+void
+_vector_get (vector v, int i, void *ptr)
+{
+  assert (0 <= i && i < v->used);
+  if (ptr) memcpy (ptr, v->data + i * v->size, v->size);
+}
+
+const void *
+_vector_get_ptr (vector v, int i)
+{
+  assert (0 <= i && i < v->used);
+  return v->data + i * v->size;
+}
+
+void
+_vector_sort (vector v, int (*compare_fn) (const void *, const void *))
+{
+  qsort (v->data, v->used, v->size, compare_fn);
+}
+
+int
+_vector_compare (vector v1, vector v2,
+                int (*compare_fn) (const void *, const void *))
+{
+  int i, r;
+  void *p1, *p2;
+
+  if (vector_size (v1) < vector_size (v2)) return -1;
+  else if (vector_size (v1) > vector_size (v2)) return 1;
+
+  for (i = 0; i < vector_size (v1); ++i)
+    {
+      vector_get_ptr (v1, i, p1);
+      vector_get_ptr (v2, i, p2);
+
+      r = compare_fn (p1, p2);
+
+      if (r != 0) return r;
+    }
+
+  return 0;
+}
+
+void
+_vector_fill (vector v, const void *ptr, int n)
+{
+  while (n--)
+    _vector_push_back (v, ptr);
+}
+
+void
+vector_swap (vector v, int i, int j)
+{
+  void *pi, *pj;
+  char data[v->size];
+
+  if (i == j) return;
+
+  vector_get_ptr (v, i, pi);
+  vector_get_ptr (v, j, pj);
+
+  memcpy (data, pi, v->size);
+  memcpy (pi, pj, v->size);
+  memcpy (pj, data, v->size);
+}
+
+void
+vector_reallocate (vector v, int n)
+{
+  if (n > v->allocated)
+    {
+      void *d = prealloc (v->pool, v->data, n * v->size);
+      v->allocated = n;
+      v->data = d;
+    }
+}
+
+vector
+vector_grep (pool p, vector v, int (*match_fn) (const void *))
+{
+  vector nv = _vector_new (p, v->size);
+  int i;
+
+  for (i = 0; i < v->used; ++i)
+    if (match_fn (v->data + i * v->size))
+      _vector_push_back (nv, v->data + i * v->size);
+
+  return nv;
+}
+
+vector
+vector_grep_pool (pool p, vector v, int (*match_fn) (pool, const void *))
+{
+  vector nv = _vector_new (p, v->size);
+  int i;
+
+  for (i = 0; i < v->used; ++i)
+    if (match_fn (p, v->data + i * v->size))
+      _vector_push_back (nv, v->data + i * v->size);
+
+  return nv;
+}
+
+vector
+_vector_map (pool p, vector v,
+            void (*map_fn) (const void *, void *),
+            size_t result_size)
+{
+  vector nv = _vector_new (p, result_size);
+  int i;
+
+  vector_reallocate (nv, v->used);
+  nv->used = v->used;
+
+  for (i = 0; i < v->used; ++i)
+    map_fn (v->data + i * v->size, nv->data + i * nv->size);
+
+  return nv;
+}
+
+vector
+_vector_map_pool (pool p, vector v,
+                 void (*map_fn) (pool, const void *, void *),
+                 size_t result_size)
+{
+  vector nv = _vector_new (p, result_size);
+  int i;
+
+  vector_reallocate (nv, v->used);
+  nv->used = v->used;
+
+  for (i = 0; i < v->used; ++i)
+    map_fn (p, v->data + i * v->size, nv->data + i * nv->size);
+
+  return nv;
+}
diff --git a/vector.h b/vector.h
new file mode 100644 (file)
index 0000000..aff02cd
--- /dev/null
+++ b/vector.h
@@ -0,0 +1,304 @@
+/* A vector class.
+ * By Richard W.M. Jones <rich@annexia.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id: vector.h,v 1.4 2002/10/27 16:04:42 rich Exp $
+ */
+
+#ifndef VECTOR_H
+#define VECTOR_H
+
+#include <pool.h>
+
+struct vector
+{
+  pool pool;
+  size_t size;
+  void *data;
+  int used, allocated;
+};
+
+typedef struct vector *vector;
+
+/* Function: new_vector - allocate a new vector
+ * Function: _vector_new
+ *
+ * Allocate a new vector in @code{pool} of type @code{type}. The
+ * first form is just a macro which evaluates the size of @code{type}.
+ * The second form creates a vector with elements of the given
+ * @code{size} directly.
+ */
+#define new_vector(pool,type) _vector_new ((pool), sizeof (type))
+extern vector _vector_new (pool, size_t size);
+
+/* Function: copy_vector - copy a vector
+ * Function: new_subvector
+ *
+ * Copy a vector @code{v} into pool @code{pool}. If the vector
+ * contains pointers, then this function will not copy the pointed-to
+ * data as well: you will need to copy this yourself if appropriate.
+ *
+ * @code{new_subvector} creates a copy of part of an existing vector.
+ * The new vector contains the @code{j-i} elements of the old vector
+ * starting at element number @code{i} and finishing at element number
+ * @code{j-1}.
+ */
+extern vector copy_vector (pool, vector v);
+extern vector new_subvector (pool, vector v, int i, int j);
+
+/* Function: vector_push_back - push and pop objects into and out of vectors
+ * Function: _vector_push_back
+ * Function: vector_pop_back
+ * Function: _vector_pop_back
+ * Function: vector_push_front
+ * Function: _vector_push_front
+ * Function: vector_pop_front
+ * Function: _vector_pop_front
+ *
+ * The @code{*_push_*} functions push objects onto vectors.
+ *
+ * The @code{*_pop_*} functions pop objects off vectors into local variables.
+ *
+ * The @code{*_front} functions push and pop objects off the front
+ * of a vector. This type of operation is not very efficient, because
+ * it involves moving all other elements of the vector up or down
+ * by one place.
+ *
+ * The @code{*_back} functions push and pop elements
+ * off the end of the vector, which is efficient.
+ *
+ * Each function has two forms: a macro version and an underlying
+ * function.
+ *
+ * Array indexes are checked. You cannot pop an empty vector. If
+ * @code{ptr} is @code{NULL} then the popped object is discarded.
+ */
+#define vector_push_back(v,obj) _vector_push_back((v),&(obj))
+extern void _vector_push_back (vector, const void *ptr);
+#define vector_pop_back(v,obj) _vector_pop_back((v),&(obj))
+extern void _vector_pop_back (vector, void *ptr);
+#define vector_push_front(v,obj) _vector_push_front((v),&(obj))
+extern void _vector_push_front (vector, const void *ptr);
+#define vector_pop_front(v,obj) _vector_pop_front((v),&(obj))
+extern void _vector_pop_front (vector, void *ptr);
+
+/* Function: vector_push_back_vector - push list of objects on to vector
+ * Function: vector_push_front_vector
+ *
+ * @code{vector_push_back_vector} appends the elements of vector
+ * @code{w} on to the end of vector @code{v}.
+ *
+ * @code{vector_push_front_vector} prepends the elements of vector
+ * @code{w} on to the front of vector @code{v}.
+ *
+ * In both cases, vector @code{w} is left unchanged.
+ *
+ * See also: @ref{vector_push_back(3)}, @ref{vector_push_front(3)}.
+ */
+extern void vector_push_back_vector (vector v, const vector w);
+extern void vector_push_front_vector (vector v, const vector w);
+
+/* Function: vector_get - array-style indexing for vectors
+ * Function: _vector_get
+ * Function: vector_get_ptr
+ * Function: _vector_get_ptr
+ *
+ * @code{vector_get} copies the element at index @code{v[i]} into
+ * local variable @code{obj}. The vector is unaffected.
+ *
+ * @code{_vector_get} copies the element into the memory pointed
+ * to by @code{ptr}. If @code{ptr} is @code{NULL} then the effect
+ * is simply to check that element @code{v[i]} exists.
+ *
+ * @code{vector_get_ptr} and @code{_vector_get_ptr} are used to
+ * get a pointer to an element in the vector. This pointer actually
+ * points to the vector's internal data array. It is only valid
+ * as long as the user does not cause the internal data array to
+ * be reallocated or moved - typically this can happen when the
+ * user performs some operation which inserts more elements into
+ * the array.
+ *
+ * Array indexes are checked. An attempt to access an out-of-bounds
+ * element will result in a call to @ref{abort(3)}.
+ */
+#define vector_get(v,i,obj) _vector_get((v),(i),&(obj))
+extern void _vector_get (vector, int i, void *ptr);
+#define vector_get_ptr(v,i,ptr) (ptr) =((typeof (ptr))_vector_get_ptr((v),(i)))
+extern const void *_vector_get_ptr (vector, int i);
+
+/* Function: vector_insert - insert elements into a vector
+ * Function: _vector_insert
+ * Function: vector_insert_array
+ *
+ * @code{vector_insert} inserts a single object @code{obj} before element
+ * @code{i}. All other elements are moved up to make space.
+ *
+ * @code{vector_insert_array} inserts an array of @code{n} objects
+ * starting at address @code{ptr} into the vector before index
+ * @code{i}.
+ *
+ * Array indexes are checked.
+ */
+#define vector_insert(v,i,obj) _vector_insert((v),(i),&(obj))
+extern void _vector_insert (vector, int i, const void *ptr);
+extern void vector_insert_array (vector v, int i, const void *ptr, int n);
+
+/* Function: vector_replace - replace elements of a vector
+ * Function: _vector_replace
+ * Function: vector_replace_array
+ *
+ * @code{vector_replace} replaces the single element at
+ * @code{v[i]} with object @code{obj}.
+ *
+ * @code{vector_replace_array} replaces the @code{n} elements
+ * in the vector starting at index @code{i} with the @code{n}
+ * elements from the array @code{ptr}.
+ * 
+ * Array indexes are checked.
+ */
+#define vector_replace(v,i,obj) _vector_replace((v),(i),&(obj))
+extern void _vector_replace (vector, int i, const void *ptr);
+extern void vector_replace_array (vector v, int i, const void *ptr, int n);
+
+/* Function: vector_erase - erase elements of a vector
+ * Function: vector_erase_range
+ * Function: vector_clear
+ *
+ * @code{vector_erase} removes the element @code{v[i]}, shuffling
+ * the later elements down by one place to fill the space.
+ *
+ * @code{vector_erase_range} removes a range of elements @code{v[i]}
+ * to @code{v[j-1]} (@code{i <= j}), shuffling later elements down
+ * to fill the space.
+ *
+ * @code{vector_clear} removes all elements from the vector, setting
+ * its size to @code{0}.
+ *
+ * Array indexes are checked.
+ */
+extern void vector_erase (vector v, int i);
+extern void vector_erase_range (vector v, int i, int j);
+extern void vector_clear (vector v);
+
+/* Function: vector_fill - fill a vector with identical elements
+ * Function: _vector_fill
+ *
+ * @code{vector_fill} appends @code{n} identical copies of
+ * @code{obj} to the vector. It is equivalent to calling
+ * @ref{vector_push_back(3)} in a loop @code{n} times.
+ */
+#define vector_fill(v,obj,n) _vector_fill((v),&(obj),(n))
+extern void _vector_fill (vector, const void *ptr, int n);
+
+/* Function: vector_size - return the size of a vector
+ *
+ * Return the size (ie. number of elements) in the vector.
+ */
+#define vector_size(v) ((v)->used)
+
+/* Function: vector_allocated - return the space allocated to a vector
+ *
+ * Return the amount of space which has been allocated for storing
+ * elements of the vector. This is different from the number of
+ * elements actually stored by the vector (see @ref{vector_size(3)})
+ * and also different from the size of each element in bytes
+ * (see @ref{vector_element_size(3)}).
+ */
+#define vector_allocated(v) ((v)->allocated)
+
+/* Function: vector_element_size - return the size of each element of a vector
+ *
+ * Return the size in bytes of each element in vector.
+ */
+#define vector_element_size(v) ((v)->size)
+
+/* Function: vector_reallocate - change allocation for a vector
+ *
+ * Increase the amount of space allocated to a vector. See also
+ * @ref{vector_allocated(3)}. This function can be used to avoid
+ * the vector itself making too many calls to the underlying
+ * @ref{prealloc(3)}, particularly if you know in advance exactly
+ * how many elements the vector will contain.
+ */
+extern void vector_reallocate (vector v, int n);
+
+/* Function: vector_grep - produce a new vector containing elements of the old vector which match a boolean function
+ *
+ * This macro calls @code{match_fn(&t)} for each element @code{t} of
+ * vector @code{v}. It constructs and returns a new vector containing
+ * all those elements where the function returns true.
+ */
+extern vector vector_grep (pool, vector v, int (*match_fn) (const void *));
+
+/* Function: vector_grep_pool - produce a new vector containing elements of the old vector which match a boolean function
+ *
+ * This macro calls @code{match_fn(pool, &t)} for each element @code{t} of
+ * vector @code{v}. It constructs and returns a new vector containing
+ * all those elements where the function returns true.
+ */
+extern vector vector_grep_pool (pool, vector v, int (*match_fn) (pool, const void *));
+
+/* Function: vector_map - apply function to each element of a vector
+ * Function: _vector_map
+ *
+ * Call @code{map_fn(&t, &r)} for each element @code{t} of vector @code{v}.
+ * The result (@code{r}) should have type @code{result_type}
+ * and these are concatenated to form a new vector which is returned.
+ */
+#define vector_map(pool,v,map_fn,result_type) _vector_map ((pool), (v), (map_fn), sizeof (result_type))
+extern vector _vector_map (pool, vector v, void (*map_fn) (const void *, void *), size_t result_size);
+
+/* Function: vector_map_pool - apply function to each element of a vector
+ * Function: _vector_map_pool
+ *
+ * Call @code{map_fn(pool, &t, &r)} for each element @code{t} of vector
+ * @code{v}. The result (@code{r}) should have type @code{result_type}
+ * and these are concatenated to form a new vector which is returned.
+ */
+#define vector_map_pool(pool,v,map_fn,result_type) _vector_map_pool ((pool), (v), (map_fn), sizeof (result_type))
+extern vector _vector_map_pool (pool, vector v, void (*map_fn_pool) (pool, const void *, void *), size_t result_size);
+
+/* Function: vector_sort - sort a vector in-place
+ * Function: _vector_sort
+ *
+ * Sort a vector in-place, comparing elements using @code{compare_fn}.
+ */
+#define vector_sort(v,compare_fn) _vector_sort ((v), (int (*)(const void *,const void *)) (compare_fn))
+extern void _vector_sort (vector v, int (*compare_fn) (const void *, const void *));
+
+/* Function: vector_compare - compare two vectors
+ * Function: _vector_compare
+ *
+ * Compare two vectors. This returns 0 if the two vectors are
+ * identical. It returns > 0 if @code{v1} > @code{v2}. This
+ * returns < 0 if @code{v1} < @code{v2}.
+ */
+#define vector_compare(v1,v2,compare_fn) _vector_compare ((v1), (v2), (int (*)(const void *,const void *)) (compare_fn))
+extern int _vector_compare (vector, vector, int (*compare_fn) (const void *, const void *));
+
+/* Function: vector_reverse - reverse the elements of a vector in-place
+ *
+ * Reverse the elements of a vector in-place.
+ */
+extern void vector_reverse (vector v);
+
+/* Function: vector_swap - swap two elements of a vector
+ *
+ * Swap elements @code{i} and @code{j} of vector @code{v}.
+ */
+extern void vector_swap (vector v, int i, int j);
+
+#endif /* VECTOR_H */