]> pd.if.org Git - pdclib/commitdiff
dos2unix
authorMartin Baute <solar@rootdirectory.de>
Sun, 13 Mar 2016 20:31:40 +0000 (21:31 +0100)
committerMartin Baute <solar@rootdirectory.de>
Sun, 13 Mar 2016 20:31:40 +0000 (21:31 +0100)
127 files changed:
COPYING.CC0
Readme.rst
UNICODE DATA LICENSE.txt
functions/_dlmalloc/dlmalloc.c
functions/_dlmalloc/dlmalloc.h
functions/locale/UnicodeData.py
functions/locale/freelocale.c
functions/stdio/_PDCLIB_fillbuffer.c
functions/stdio/_PDCLIB_flushbuffer.c
functions/stdio/_PDCLIB_ftell64.c
functions/stdio/_PDCLIB_fvopen.c
functions/stdio/_PDCLIB_seek.c
functions/stdio/flockfile.c
functions/stdio/ftrylockfile.c
functions/stdio/funlockfile.c
functions/string/strdup.c
functions/string/strndup.c
functions/string/strnlen.c
functions/uchar/c16rtomb.c
functions/uchar/mbrtoc16.c
functions/wchar/mbsinit.c
functions/wchar/wcscat.c
functions/wchar/wcschr.c
functions/wchar/wcscmp.c
functions/wchar/wcscpy.c
functions/wchar/wcscspn.c
functions/wchar/wcslen.c
functions/wchar/wcsncat.c
functions/wchar/wcsncmp.c
functions/wchar/wcsncpy.c
functions/wchar/wcspbrk.c
functions/wchar/wcsrchr.c
functions/wchar/wcsspn.c
functions/wchar/wcsstr.c
functions/wchar/wcstok.c
functions/wchar/wmemchr.c
functions/wchar/wmemcmp.c
functions/wchar/wmemcpy.c
functions/wchar/wmemmove.c
functions/wctype/iswalnum.c
functions/wctype/iswalpha.c
functions/wctype/iswblank.c
functions/wctype/iswcntrl.c
functions/wctype/iswctype.c
functions/wctype/iswdigit.c
functions/wctype/iswgraph.c
functions/wctype/iswlower.c
functions/wctype/iswprint.c
functions/wctype/iswpunct.c
functions/wctype/iswspace.c
functions/wctype/iswupper.c
functions/wctype/iswxdigit.c
functions/wctype/towctrans.c
functions/wctype/towlower.c
functions/wctype/towupper.c
functions/wctype/wctrans.c
functions/wctype/wctype.c
html/style.css
includes/float.h
includes/stdnoreturn.h
internals/_PDCLIB_float.h
internals/_PDCLIB_io.h
man3/abort.3
man3/assert.3
man3/assert.h.3
man3/atexit.3
man3/errno.3
man3/errno.h.3
man3/exit.3
man3/flockfile.3
man3/mbsinit.3
man3/pdclib.3
man3/posix_locale.3
man3/setlocale.3
man3/strdup.3
man3/string.h.3
man3/wchar.h.3
opt/c_locale/README.txt
opt/c_locale/_PDCLIB_clocale.h
opt/c_locale/_PDCLIB_initclocale.c
opt/mincoll/wcscoll.c
opt/mincoll/wcsxfrm.c
opt/nothread/_PDCLIB_threadconfig.h
opt/nothread/call_once.c
opt/nothread/cnd_init.c
opt/nothread/cnd_signal.c
opt/nothread/cnd_wait.c
opt/nothread/mtx_destroy.c
opt/nothread/mtx_init.c
opt/nothread/mtx_lock.c
opt/nothread/mtx_timedlock.c
opt/nothread/mtx_trylock.c
opt/nothread/mtx_unlock.c
opt/nothread/thrd_yield.c
opt/nothread/tss_create.c
opt/nothread/tss_delete.c
opt/nothread/tss_get.c
opt/nothread/tss_set.c
opt/notime/time.c
opt/notime/timespec_get.c
platform/example/Config.jam
platform/example/Jamfile
platform/example/functions/_PDCLIB/_PDCLIB_fileops.c
platform/example/functions/_PDCLIB/_PDCLIB_open.c
platform/example/functions/_PDCLIB/freepages.c
platform/gandr/functions/_PDCLIB/_PDCLIB_freepages.c
platform/posix/Config.jam
platform/win32/Config.jam
platform/win32/Jamfile
platform/win32/crt0.c
platform/win32/functions/_PDCLIB/_PDCLIB_fileops.c
platform/win32/functions/_PDCLIB/_PDCLIB_freepages.c
platform/win32/functions/_PDCLIB/_PDCLIB_runTlsCallbacks.c
platform/win32/functions/_PDCLIB/_PDCLIB_w32errno.c
platform/win32/functions/_PDCLIB/_tls_used.c
platform/win32/functions/threads/call_once.c
platform/win32/functions/threads/mtx_destroy.c
platform/win32/functions/threads/mtx_init.c
platform/win32/functions/threads/mtx_lock.c
platform/win32/functions/threads/mtx_timedlock.c
platform/win32/functions/threads/mtx_trylock.c
platform/win32/functions/threads/mtx_unlock.c
platform/win32/functions/threads/tss_create.c
platform/win32/functions/threads/tss_delete.c
platform/win32/functions/threads/tss_get.c
platform/win32/functions/threads/tss_set.c
platform/win32/internals/_PDCLIB_threadconfig.h

index a4715202b3cbe87ad1a48c76e888631a0d89dec0..1625c1793607996fcfc46420e8aa2f3d2b7efd1e 100644 (file)
-Creative Commons Legal Code\r
-\r
-CC0 1.0 Universal\r
-\r
-    CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE\r
-    LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN\r
-    ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS\r
-    INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES\r
-    REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS\r
-    PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM\r
-    THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED\r
-    HEREUNDER.\r
-\r
-Statement of Purpose\r
-\r
-The laws of most jurisdictions throughout the world automatically confer\r
-exclusive Copyright and Related Rights (defined below) upon the creator\r
-and subsequent owner(s) (each and all, an "owner") of an original work of\r
-authorship and/or a database (each, a "Work").\r
-\r
-Certain owners wish to permanently relinquish those rights to a Work for\r
-the purpose of contributing to a commons of creative, cultural and\r
-scientific works ("Commons") that the public can reliably and without fear\r
-of later claims of infringement build upon, modify, incorporate in other\r
-works, reuse and redistribute as freely as possible in any form whatsoever\r
-and for any purposes, including without limitation commercial purposes.\r
-These owners may contribute to the Commons to promote the ideal of a free\r
-culture and the further production of creative, cultural and scientific\r
-works, or to gain reputation or greater distribution for their Work in\r
-part through the use and efforts of others.\r
-\r
-For these and/or other purposes and motivations, and without any\r
-expectation of additional consideration or compensation, the person\r
-associating CC0 with a Work (the "Affirmer"), to the extent that he or she\r
-is an owner of Copyright and Related Rights in the Work, voluntarily\r
-elects to apply CC0 to the Work and publicly distribute the Work under its\r
-terms, with knowledge of his or her Copyright and Related Rights in the\r
-Work and the meaning and intended legal effect of CC0 on those rights.\r
-\r
-1. Copyright and Related Rights. A Work made available under CC0 may be\r
-protected by copyright and related or neighboring rights ("Copyright and\r
-Related Rights"). Copyright and Related Rights include, but are not\r
-limited to, the following:\r
-\r
-  i. the right to reproduce, adapt, distribute, perform, display,\r
-     communicate, and translate a Work;\r
- ii. moral rights retained by the original author(s) and/or performer(s);\r
-iii. publicity and privacy rights pertaining to a person's image or\r
-     likeness depicted in a Work;\r
- iv. rights protecting against unfair competition in regards to a Work,\r
-     subject to the limitations in paragraph 4(a), below;\r
-  v. rights protecting the extraction, dissemination, use and reuse of data\r
-     in a Work;\r
- vi. database rights (such as those arising under Directive 96/9/EC of the\r
-     European Parliament and of the Council of 11 March 1996 on the legal\r
-     protection of databases, and under any national implementation\r
-     thereof, including any amended or successor version of such\r
-     directive); and\r
-vii. other similar, equivalent or corresponding rights throughout the\r
-     world based on applicable law or treaty, and any national\r
-     implementations thereof.\r
-\r
-2. Waiver. To the greatest extent permitted by, but not in contravention\r
-of, applicable law, Affirmer hereby overtly, fully, permanently,\r
-irrevocably and unconditionally waives, abandons, and surrenders all of\r
-Affirmer's Copyright and Related Rights and associated claims and causes\r
-of action, whether now known or unknown (including existing as well as\r
-future claims and causes of action), in the Work (i) in all territories\r
-worldwide, (ii) for the maximum duration provided by applicable law or\r
-treaty (including future time extensions), (iii) in any current or future\r
-medium and for any number of copies, and (iv) for any purpose whatsoever,\r
-including without limitation commercial, advertising or promotional\r
-purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each\r
-member of the public at large and to the detriment of Affirmer's heirs and\r
-successors, fully intending that such Waiver shall not be subject to\r
-revocation, rescission, cancellation, termination, or any other legal or\r
-equitable action to disrupt the quiet enjoyment of the Work by the public\r
-as contemplated by Affirmer's express Statement of Purpose.\r
-\r
-3. Public License Fallback. Should any part of the Waiver for any reason\r
-be judged legally invalid or ineffective under applicable law, then the\r
-Waiver shall be preserved to the maximum extent permitted taking into\r
-account Affirmer's express Statement of Purpose. In addition, to the\r
-extent the Waiver is so judged Affirmer hereby grants to each affected\r
-person a royalty-free, non transferable, non sublicensable, non exclusive,\r
-irrevocable and unconditional license to exercise Affirmer's Copyright and\r
-Related Rights in the Work (i) in all territories worldwide, (ii) for the\r
-maximum duration provided by applicable law or treaty (including future\r
-time extensions), (iii) in any current or future medium and for any number\r
-of copies, and (iv) for any purpose whatsoever, including without\r
-limitation commercial, advertising or promotional purposes (the\r
-"License"). The License shall be deemed effective as of the date CC0 was\r
-applied by Affirmer to the Work. Should any part of the License for any\r
-reason be judged legally invalid or ineffective under applicable law, such\r
-partial invalidity or ineffectiveness shall not invalidate the remainder\r
-of the License, and in such case Affirmer hereby affirms that he or she\r
-will not (i) exercise any of his or her remaining Copyright and Related\r
-Rights in the Work or (ii) assert any associated claims and causes of\r
-action with respect to the Work, in either case contrary to Affirmer's\r
-express Statement of Purpose.\r
-\r
-4. Limitations and Disclaimers.\r
-\r
- a. No trademark or patent rights held by Affirmer are waived, abandoned,\r
-    surrendered, licensed or otherwise affected by this document.\r
- b. Affirmer offers the Work as-is and makes no representations or\r
-    warranties of any kind concerning the Work, express, implied,\r
-    statutory or otherwise, including without limitation warranties of\r
-    title, merchantability, fitness for a particular purpose, non\r
-    infringement, or the absence of latent or other defects, accuracy, or\r
-    the present or absence of errors, whether or not discoverable, all to\r
-    the greatest extent permissible under applicable law.\r
- c. Affirmer disclaims responsibility for clearing rights of other persons\r
-    that may apply to the Work or any use thereof, including without\r
-    limitation any person's Copyright and Related Rights in the Work.\r
-    Further, Affirmer disclaims responsibility for obtaining any necessary\r
-    consents, permissions or other rights required for any use of the\r
-    Work.\r
- d. Affirmer understands and acknowledges that Creative Commons is not a\r
-    party to this document and has no duty or obligation with respect to\r
+Creative Commons Legal Code
+
+CC0 1.0 Universal
+
+    CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
+    LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
+    ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
+    INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
+    REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
+    PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
+    THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
+    HEREUNDER.
+
+Statement of Purpose
+
+The laws of most jurisdictions throughout the world automatically confer
+exclusive Copyright and Related Rights (defined below) upon the creator
+and subsequent owner(s) (each and all, an "owner") of an original work of
+authorship and/or a database (each, a "Work").
+
+Certain owners wish to permanently relinquish those rights to a Work for
+the purpose of contributing to a commons of creative, cultural and
+scientific works ("Commons") that the public can reliably and without fear
+of later claims of infringement build upon, modify, incorporate in other
+works, reuse and redistribute as freely as possible in any form whatsoever
+and for any purposes, including without limitation commercial purposes.
+These owners may contribute to the Commons to promote the ideal of a free
+culture and the further production of creative, cultural and scientific
+works, or to gain reputation or greater distribution for their Work in
+part through the use and efforts of others.
+
+For these and/or other purposes and motivations, and without any
+expectation of additional consideration or compensation, the person
+associating CC0 with a Work (the "Affirmer"), to the extent that he or she
+is an owner of Copyright and Related Rights in the Work, voluntarily
+elects to apply CC0 to the Work and publicly distribute the Work under its
+terms, with knowledge of his or her Copyright and Related Rights in the
+Work and the meaning and intended legal effect of CC0 on those rights.
+
+1. Copyright and Related Rights. A Work made available under CC0 may be
+protected by copyright and related or neighboring rights ("Copyright and
+Related Rights"). Copyright and Related Rights include, but are not
+limited to, the following:
+
+  i. the right to reproduce, adapt, distribute, perform, display,
+     communicate, and translate a Work;
+ ii. moral rights retained by the original author(s) and/or performer(s);
+iii. publicity and privacy rights pertaining to a person's image or
+     likeness depicted in a Work;
+ iv. rights protecting against unfair competition in regards to a Work,
+     subject to the limitations in paragraph 4(a), below;
+  v. rights protecting the extraction, dissemination, use and reuse of data
+     in a Work;
+ vi. database rights (such as those arising under Directive 96/9/EC of the
+     European Parliament and of the Council of 11 March 1996 on the legal
+     protection of databases, and under any national implementation
+     thereof, including any amended or successor version of such
+     directive); and
+vii. other similar, equivalent or corresponding rights throughout the
+     world based on applicable law or treaty, and any national
+     implementations thereof.
+
+2. Waiver. To the greatest extent permitted by, but not in contravention
+of, applicable law, Affirmer hereby overtly, fully, permanently,
+irrevocably and unconditionally waives, abandons, and surrenders all of
+Affirmer's Copyright and Related Rights and associated claims and causes
+of action, whether now known or unknown (including existing as well as
+future claims and causes of action), in the Work (i) in all territories
+worldwide, (ii) for the maximum duration provided by applicable law or
+treaty (including future time extensions), (iii) in any current or future
+medium and for any number of copies, and (iv) for any purpose whatsoever,
+including without limitation commercial, advertising or promotional
+purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
+member of the public at large and to the detriment of Affirmer's heirs and
+successors, fully intending that such Waiver shall not be subject to
+revocation, rescission, cancellation, termination, or any other legal or
+equitable action to disrupt the quiet enjoyment of the Work by the public
+as contemplated by Affirmer's express Statement of Purpose.
+
+3. Public License Fallback. Should any part of the Waiver for any reason
+be judged legally invalid or ineffective under applicable law, then the
+Waiver shall be preserved to the maximum extent permitted taking into
+account Affirmer's express Statement of Purpose. In addition, to the
+extent the Waiver is so judged Affirmer hereby grants to each affected
+person a royalty-free, non transferable, non sublicensable, non exclusive,
+irrevocable and unconditional license to exercise Affirmer's Copyright and
+Related Rights in the Work (i) in all territories worldwide, (ii) for the
+maximum duration provided by applicable law or treaty (including future
+time extensions), (iii) in any current or future medium and for any number
+of copies, and (iv) for any purpose whatsoever, including without
+limitation commercial, advertising or promotional purposes (the
+"License"). The License shall be deemed effective as of the date CC0 was
+applied by Affirmer to the Work. Should any part of the License for any
+reason be judged legally invalid or ineffective under applicable law, such
+partial invalidity or ineffectiveness shall not invalidate the remainder
+of the License, and in such case Affirmer hereby affirms that he or she
+will not (i) exercise any of his or her remaining Copyright and Related
+Rights in the Work or (ii) assert any associated claims and causes of
+action with respect to the Work, in either case contrary to Affirmer's
+express Statement of Purpose.
+
+4. Limitations and Disclaimers.
+
+ a. No trademark or patent rights held by Affirmer are waived, abandoned,
+    surrendered, licensed or otherwise affected by this document.
+ b. Affirmer offers the Work as-is and makes no representations or
+    warranties of any kind concerning the Work, express, implied,
+    statutory or otherwise, including without limitation warranties of
+    title, merchantability, fitness for a particular purpose, non
+    infringement, or the absence of latent or other defects, accuracy, or
+    the present or absence of errors, whether or not discoverable, all to
+    the greatest extent permissible under applicable law.
+ c. Affirmer disclaims responsibility for clearing rights of other persons
+    that may apply to the Work or any use thereof, including without
+    limitation any person's Copyright and Related Rights in the Work.
+    Further, Affirmer disclaims responsibility for obtaining any necessary
+    consents, permissions or other rights required for any use of the
+    Work.
+ d. Affirmer understands and acknowledges that Creative Commons is not a
+    party to this document and has no duty or obligation with respect to
     this CC0 or use of the Work.
\ No newline at end of file
index fce23ea414e1b76404c6789ffee7b76ce0ffa3c4..f3c27a5ac1ba5240cb1d3dec08f0d69a8f7c6bc3 100644 (file)
-==============================================================\r
-PDCLib - the `Public Domain C Library <http://pdclib.e43.eu>`_\r
-==============================================================\r
-\r
-What is it\r
-==========\r
-\r
-This is a C Standard Library - what's defined in ISO/IEC 9899 "Information \r
-technology â€” Programming languages â€” C" or extensions to the above defined in\r
-ISO/IEC 14882 "Information technology â€” Programming languages â€” C++". A few \r
-extensions may optionally be provided.\r
-\r
-License\r
-=======\r
-\r
-Written in \r
- * 2003-2012 by Martin "Solar" Baute,\r
- * 2012-     by Owen Shepherd\r
-\r
-To the extent possible under law, the author(s) have dedicated all copyright \r
-and related and neighboring rights to this software to the public domain \r
-worldwide. This software is distributed without any warranty.\r
-\r
-You should have received a copy of the CC0 Public Domain Dedication along with \r
-this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.\r
-\r
-Exceptions\r
-----------\r
-\r
-Unicode Character Data\r
-~~~~~~~~~~~~~~~~~~~~~~\r
-PDCLib necessarily includes Unicode character data derived from that provided by\r
-Unicode, Inc in its' implementation of the localization and wide character \r
-support (in particular for use by the ctype.h and wctype.h functions.)\r
-\r
-Unicode, Inc licenses that data under a license agreement which can be found at\r
-<http://www.unicode.org/copyright.html#Exhibit1>, or in the file \r
-UNICODE_DATA_LICENSE.txt. found in the same directory as this file.\r
-\r
-Test Suite\r
-~~~~~~~~~~\r
-Portions of the test suite are under different licenses. Where this is the case, \r
-it is clearly noted in the relevant location.\r
-\r
-The license of this code has no bearing upon the licensing of the built library \r
-(as it does not comprise part of it).\r
-\r
-At the time this was written, this exception only applies to portions of the \r
-printf test suite, which are released under the terms of the 2-clause BSD \r
-license (see testing/printf_testcases.h for full details)\r
-\r
-Terms for extensions\r
-====================\r
-Extensions are permitted only if they pass the following tests:\r
-\r
-Pre-existing wide usage\r
-    On most systems, the system C library must maintain its application binary\r
-    interface for long periods of time (potentially eternity). Existing wide \r
-    usage demonstrates utility\r
-\r
-In keeping with the spirit of the standard\r
-    The extension should respect the design, intentions and conventions of the C\r
-    standard, and feel like a natural extension to the offered capability. \r
-\r
-Not system dependent\r
-    The extension should not add any additional dependencies on the underlying \r
-    system\r
-\r
-Non-duplicative\r
-    Extensions should not duplicate functionality already provided by the \r
-    standard\r
-\r
-Disabled by default\r
-    PDCLib will always default to a "strictly conforming" mode exposing only\r
-    functionality offered by the version of the standard specified by the\r
-    __STDC_VERSION__, __STDC__ or __cplusplus macro; extensions will only be \r
-    exposed when requested.\r
-\r
-Additionally, extra consideration will be given to extensions which are \r
-difficult or impossible to implement without access to internal structures of \r
-the C library.\r
-\r
-Conrete Examples:\r
-\r
-strndup\r
-    **Included.** strndup is easily defined in terms of existing standard \r
-    functions, follows  the standard's naming conventions, is in wide usage, and\r
-    does not duplicate  features already provided.\r
-\r
-posix_memalign\r
-    **Rejected.** Has existing wide usage, is not system dependent (can be \r
-    implemented, albeit inefficiently, on top of malloc), but naming is not \r
-    consistent with the naming used by the standard (posix_ prefix) and \r
-    duplicates functionality provided by the C11 standard\r
-\r
-open, close, read, write, ...\r
-    **Rejected.** Widely used, but duplicates functionality provided by the \r
-    standard (FILE objects set to be unbuffered), and not able to implement full\r
-    semantics (e.g. in relation to POSIX fork and other functionality from the \r
-    same defining standard) in a platform-neutral way\r
-\r
-strl*\r
-    **Rejected.** Used somewhat widely, in keeping with the standard, not system\r
-    dependent, but duplicative of functionality provided by (optional) Annex K \r
-    of the C standard. \r
-\r
-flockfile, funlockfile, getc_unlocked, putc_unlocked, fwrite_unlocked, ...\r
-    **Accepted.** Provide functionality not provided by the standard (and \r
-    useful in light of the C11 addition of threading). Can be trivially \r
-    implemented in terms of the <threads.h> mutex functions and the bodies of \r
-    the existing I/O functions, and impossible to implement externally\r
-\r
-Internals\r
-=========\r
-\r
-As a namespace convention, everything (files, typedefs, functions,\r
-macros) not defined in ISO/IEC 9899 is prefixed with _PDCLIB.\r
-The standard defines any identifiers starting with '_' and a capital\r
-letter as reserved for the implementation, and since the chances of\r
-your compiler using an identifier in the _PDCLIB range are slim,\r
-any strictly conforming application should work with this library.\r
-\r
-PDCLib consists of several parts:\r
-\r
-1) standard headers;\r
-2) implementation files for standard functions;\r
-3) internal header files keeping complex stuff out of the standard\r
-   headers;\r
-4) the central, platform-specific file _PDCLIB_config.h;\r
-5) platform-specific implementation files;\r
-\r
-The standard headers (in ./includes/) only contain what they are\r
-defined to contain. Where additional logic or macro magic is\r
-necessary, that is deferred to the internal files. This has been done\r
-so that the headers are actually educational as to what they provide\r
-(as opposed to how the library does it).\r
-\r
-There is a seperate implementation file (in ./function/{header}/) for\r
-every function defined by the standard, named {function}.c. Not only\r
-does this avoid linking in huge amounts of unused code when you use\r
-but a single function, it also allows the optimization overlay to work\r
-(see below).\r
-\r
-(The directory ./functions/_PDCLIB/ contains internal and helper\r
-functions that are not part of the standard.)\r
-\r
-Then there are internal header files (in ./internal/), which contain\r
-all the "black magic" and "code fu" that was kept out of the standard\r
-headers. You should not have to touch them if you want to adapt PDCLib\r
-to a new platform. Note that, if you *do* have to touch them, I would\r
-consider it a serious design flaw, and would be happy to fix it in the\r
-next PDCLib release. Any adaption work should be covered by the steps\r
-detailed below.\r
-\r
-For adapting PDCLib to a new platform (the trinity of CPU, operating\r
-system, and compiler), make a copy of ./platform/example/ named\r
-./platform/{your_platform}/, and modify the files of your copy to suit\r
-the constraints of your platform. When you are done, copy the contents\r
-of your platform directory over the source directory structure\r
-of PDCLib (or link them into the appropriate places). That should be\r
-all that is actually required to make PDCLib work for your platform.\r
-\r
-Future directions\r
-=================\r
-Obviously, full C89, C99 and C11 conformance; and full support for the \r
-applicable portions of C++98, C++03 and C++11 (the version which acomplishes \r
-this will be christened "1.0").\r
-\r
-Support for "optimization overlays." These would allow efficient \r
-implementations of certain functions on individual platforms, for example \r
-memcpy, strcpy and memset. This requires further work to only compile in one\r
-version of a given function.\r
-\r
-Post 1.0, support for C11 Annexe K "Bounds checking interfaces"\r
-\r
-Development Status\r
-==================\r
-\r
-``v0.1 - 2004-12-12``\r
-    Freestanding-only C99 implementation without any overlay, and missing\r
-    the INTN_C() / UINTN_C() macros. <float.h> still has the enquire.c\r
-    values hardcoded into it; not sure whether to include enquire.c in the\r
-    package, to leave <float.h> to the overlay, or devise some parameterized\r
-    macro magic as for <limits.h> / <stdint.h>. Not thoroughly tested, but\r
-    I had to make the 0.1 release sometime so why not now.\r
-\r
-``v0.2 - 2005-01-12``\r
-    Adds implementations for <string.h> (excluding strerror()), INTN_C() /\r
-    UINTN_C() macros, and some improvements in the internal headers.\r
-    Test drivers still missing, but added warnings about that.\r
-\r
-``v0.3 - 2005-11-21``\r
-    Adds test drivers, fixes some bugs in <string.h>.\r
-\r
-``v0.4 - 2005-02-06``\r
-    Implementations for parts of <stdlib.h>. Still missing are the floating\r
-    point conversions, and the wide-/multibyte-character functions.\r
-\r
-``v0.4.1 - 2006-11-16``\r
-    With v0.5 (<stdio.h>) taking longer than expected, v0.4.1 was set up as\r
-    a backport of bugfixes in the current development code.\r
-\r
-    - #1 realloc( NULL, size ) fails\r
-    - #2 stdlib.h - insufficient documentation\r
-    - #4  Misspelled name in credits\r
-    - #5  malloc() splits off too-small nodes\r
-    - #6  qsort() stack overflow\r
-    - #7  malloc() bug in list handling\r
-    - #8  strncmp() does not terminate at '\0'\r
-    - #9  stdint.h dysfunctional\r
-    - #10 NULL redefinition warnings\r
-\r
-``v0.5 - 2010-12-22``\r
-    Implementations for <inttypes.h>, <errno.h>, most parts of <stdio.h>,\r
-    and strerror() from <string.h>.\r
-    Still no locale / wide-char support. Enabled all GCC compiler warnings I\r
-    could find, and fixed everything that threw a warning. (You see this,\r
-    maintainers of Open Source software? No warnings whatsoever. Stop telling\r
-    me it cannot be done.) Fixed all known bugs in the v0.4 release.\r
-\r
-Near Future\r
-===========\r
-Current development directions are:\r
-\r
-Implement portions of the C11 standard that have a direct impact on the way \r
-that PDCLib itself is built. For example, in order to support multithreading,\r
-PDCLib needs a threading abstraction; therefore, C11's thread library is being\r
-implemented to provide the backing for this (as there is no purpose in \r
-implementing two abstractions)\r
-\r
-Modularize the library somewhat. This can already be seen with components under \r
-"opt/". This structure is preliminary; it will likely change as the process \r
+==============================================================
+PDCLib - the `Public Domain C Library <http://pdclib.e43.eu>`_
+==============================================================
+
+What is it
+==========
+
+This is a C Standard Library - what's defined in ISO/IEC 9899 "Information 
+technology â€” Programming languages â€” C" or extensions to the above defined in
+ISO/IEC 14882 "Information technology â€” Programming languages â€” C++". A few 
+extensions may optionally be provided.
+
+License
+=======
+
+Written in 
+ * 2003-2012 by Martin "Solar" Baute,
+ * 2012-     by Owen Shepherd
+
+To the extent possible under law, the author(s) have dedicated all copyright 
+and related and neighboring rights to this software to the public domain 
+worldwide. This software is distributed without any warranty.
+
+You should have received a copy of the CC0 Public Domain Dedication along with 
+this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
+
+Exceptions
+----------
+
+Unicode Character Data
+~~~~~~~~~~~~~~~~~~~~~~
+PDCLib necessarily includes Unicode character data derived from that provided by
+Unicode, Inc in its' implementation of the localization and wide character 
+support (in particular for use by the ctype.h and wctype.h functions.)
+
+Unicode, Inc licenses that data under a license agreement which can be found at
+<http://www.unicode.org/copyright.html#Exhibit1>, or in the file 
+UNICODE_DATA_LICENSE.txt. found in the same directory as this file.
+
+Test Suite
+~~~~~~~~~~
+Portions of the test suite are under different licenses. Where this is the case, 
+it is clearly noted in the relevant location.
+
+The license of this code has no bearing upon the licensing of the built library 
+(as it does not comprise part of it).
+
+At the time this was written, this exception only applies to portions of the 
+printf test suite, which are released under the terms of the 2-clause BSD 
+license (see testing/printf_testcases.h for full details)
+
+Terms for extensions
+====================
+Extensions are permitted only if they pass the following tests:
+
+Pre-existing wide usage
+    On most systems, the system C library must maintain its application binary
+    interface for long periods of time (potentially eternity). Existing wide 
+    usage demonstrates utility
+
+In keeping with the spirit of the standard
+    The extension should respect the design, intentions and conventions of the C
+    standard, and feel like a natural extension to the offered capability. 
+
+Not system dependent
+    The extension should not add any additional dependencies on the underlying 
+    system
+
+Non-duplicative
+    Extensions should not duplicate functionality already provided by the 
+    standard
+
+Disabled by default
+    PDCLib will always default to a "strictly conforming" mode exposing only
+    functionality offered by the version of the standard specified by the
+    __STDC_VERSION__, __STDC__ or __cplusplus macro; extensions will only be 
+    exposed when requested.
+
+Additionally, extra consideration will be given to extensions which are 
+difficult or impossible to implement without access to internal structures of 
+the C library.
+
+Conrete Examples:
+
+strndup
+    **Included.** strndup is easily defined in terms of existing standard 
+    functions, follows  the standard's naming conventions, is in wide usage, and
+    does not duplicate  features already provided.
+
+posix_memalign
+    **Rejected.** Has existing wide usage, is not system dependent (can be 
+    implemented, albeit inefficiently, on top of malloc), but naming is not 
+    consistent with the naming used by the standard (posix_ prefix) and 
+    duplicates functionality provided by the C11 standard
+
+open, close, read, write, ...
+    **Rejected.** Widely used, but duplicates functionality provided by the 
+    standard (FILE objects set to be unbuffered), and not able to implement full
+    semantics (e.g. in relation to POSIX fork and other functionality from the 
+    same defining standard) in a platform-neutral way
+
+strl*
+    **Rejected.** Used somewhat widely, in keeping with the standard, not system
+    dependent, but duplicative of functionality provided by (optional) Annex K 
+    of the C standard. 
+
+flockfile, funlockfile, getc_unlocked, putc_unlocked, fwrite_unlocked, ...
+    **Accepted.** Provide functionality not provided by the standard (and 
+    useful in light of the C11 addition of threading). Can be trivially 
+    implemented in terms of the <threads.h> mutex functions and the bodies of 
+    the existing I/O functions, and impossible to implement externally
+
+Internals
+=========
+
+As a namespace convention, everything (files, typedefs, functions,
+macros) not defined in ISO/IEC 9899 is prefixed with _PDCLIB.
+The standard defines any identifiers starting with '_' and a capital
+letter as reserved for the implementation, and since the chances of
+your compiler using an identifier in the _PDCLIB range are slim,
+any strictly conforming application should work with this library.
+
+PDCLib consists of several parts:
+
+1) standard headers;
+2) implementation files for standard functions;
+3) internal header files keeping complex stuff out of the standard
+   headers;
+4) the central, platform-specific file _PDCLIB_config.h;
+5) platform-specific implementation files;
+
+The standard headers (in ./includes/) only contain what they are
+defined to contain. Where additional logic or macro magic is
+necessary, that is deferred to the internal files. This has been done
+so that the headers are actually educational as to what they provide
+(as opposed to how the library does it).
+
+There is a seperate implementation file (in ./function/{header}/) for
+every function defined by the standard, named {function}.c. Not only
+does this avoid linking in huge amounts of unused code when you use
+but a single function, it also allows the optimization overlay to work
+(see below).
+
+(The directory ./functions/_PDCLIB/ contains internal and helper
+functions that are not part of the standard.)
+
+Then there are internal header files (in ./internal/), which contain
+all the "black magic" and "code fu" that was kept out of the standard
+headers. You should not have to touch them if you want to adapt PDCLib
+to a new platform. Note that, if you *do* have to touch them, I would
+consider it a serious design flaw, and would be happy to fix it in the
+next PDCLib release. Any adaption work should be covered by the steps
+detailed below.
+
+For adapting PDCLib to a new platform (the trinity of CPU, operating
+system, and compiler), make a copy of ./platform/example/ named
+./platform/{your_platform}/, and modify the files of your copy to suit
+the constraints of your platform. When you are done, copy the contents
+of your platform directory over the source directory structure
+of PDCLib (or link them into the appropriate places). That should be
+all that is actually required to make PDCLib work for your platform.
+
+Future directions
+=================
+Obviously, full C89, C99 and C11 conformance; and full support for the 
+applicable portions of C++98, C++03 and C++11 (the version which acomplishes 
+this will be christened "1.0").
+
+Support for "optimization overlays." These would allow efficient 
+implementations of certain functions on individual platforms, for example 
+memcpy, strcpy and memset. This requires further work to only compile in one
+version of a given function.
+
+Post 1.0, support for C11 Annexe K "Bounds checking interfaces"
+
+Development Status
+==================
+
+``v0.1 - 2004-12-12``
+    Freestanding-only C99 implementation without any overlay, and missing
+    the INTN_C() / UINTN_C() macros. <float.h> still has the enquire.c
+    values hardcoded into it; not sure whether to include enquire.c in the
+    package, to leave <float.h> to the overlay, or devise some parameterized
+    macro magic as for <limits.h> / <stdint.h>. Not thoroughly tested, but
+    I had to make the 0.1 release sometime so why not now.
+
+``v0.2 - 2005-01-12``
+    Adds implementations for <string.h> (excluding strerror()), INTN_C() /
+    UINTN_C() macros, and some improvements in the internal headers.
+    Test drivers still missing, but added warnings about that.
+
+``v0.3 - 2005-11-21``
+    Adds test drivers, fixes some bugs in <string.h>.
+
+``v0.4 - 2005-02-06``
+    Implementations for parts of <stdlib.h>. Still missing are the floating
+    point conversions, and the wide-/multibyte-character functions.
+
+``v0.4.1 - 2006-11-16``
+    With v0.5 (<stdio.h>) taking longer than expected, v0.4.1 was set up as
+    a backport of bugfixes in the current development code.
+
+    - #1 realloc( NULL, size ) fails
+    - #2 stdlib.h - insufficient documentation
+    - #4  Misspelled name in credits
+    - #5  malloc() splits off too-small nodes
+    - #6  qsort() stack overflow
+    - #7  malloc() bug in list handling
+    - #8  strncmp() does not terminate at '\0'
+    - #9  stdint.h dysfunctional
+    - #10 NULL redefinition warnings
+
+``v0.5 - 2010-12-22``
+    Implementations for <inttypes.h>, <errno.h>, most parts of <stdio.h>,
+    and strerror() from <string.h>.
+    Still no locale / wide-char support. Enabled all GCC compiler warnings I
+    could find, and fixed everything that threw a warning. (You see this,
+    maintainers of Open Source software? No warnings whatsoever. Stop telling
+    me it cannot be done.) Fixed all known bugs in the v0.4 release.
+
+Near Future
+===========
+Current development directions are:
+
+Implement portions of the C11 standard that have a direct impact on the way 
+that PDCLib itself is built. For example, in order to support multithreading,
+PDCLib needs a threading abstraction; therefore, C11's thread library is being
+implemented to provide the backing for this (as there is no purpose in 
+implementing two abstractions)
+
+Modularize the library somewhat. This can already be seen with components under 
+"opt/". This structure is preliminary; it will likely change as the process 
 continues.
\ No newline at end of file
index 9f693b6b9b83ea15fd746a45614fd0324c7bb499..c33d814a6295dacd83b2dbdcdea8bb9e05a24178 100644 (file)
@@ -1,46 +1,46 @@
-Unicode Data Files include all data files under the directories\r
-http://www.unicode.org/Public/, http://www.unicode.org/reports/, and\r
-http://www.unicode.org/cldr/data/. Unicode Data Files do not include PDF online\r
-code charts under the directory http://www.unicode.org/Public/. Software\r
-includes any source code published in the Unicode Standard or under the\r
-directories http://www.unicode.org/Public/, http://www.unicode.org/reports/, and\r
-http://www.unicode.org/cldr/data/.\r
-\r
-NOTICE TO USER: Carefully read the following legal agreement. BY DOWNLOADING,\r
-INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S DATA FILES ("DATA FILES"),\r
-AND/OR SOFTWARE ("SOFTWARE"), YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND\r
-BY, ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO\r
-NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWAR.\r
-\r
-COPYRIGHT AND PERMISSION NOTICE\r
-\r
-Copyright Â© 1991-2013 Unicode, Inc. All rights reserved. Distributed under the\r
-Terms of Use in http://www.unicode.org/copyright.html.\r
-\r
-Permission is hereby granted, free of charge, to any person obtaining a copy of\r
-the Unicode data files and any associated documentation (the "Data Files") or\r
-Unicode software and any associated documentation (the "Software") to deal in\r
-the Data Files or Software without restriction, including without limitation the\r
-rights to use, copy, modify, merge, publish, distribute, and/or sell copies of\r
-the Data Files or Software, and to permit persons to whom the Data Files or\r
-Software are furnished to do so, provided that (a) the above copyright notice(s)\r
-and this permission notice appear with all copies of the Data Files or Software,\r
-(b) both the above copyright notice(s) and this permission notice appear in\r
-associated documentation, and (c) there is clear notice in each modified Data\r
-File or in the Software as well as in the documentation associated with the Data\r
-File(s) or Software that the data or software has been modified.\r
-\r
-THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD\r
-PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS\r
-NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL\r
-DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,\r
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING\r
-OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR\r
-SOFTWARE.\r
-\r
-Except as contained in this notice, the name of a copyright holder shall not be\r
-used in advertising or otherwise to promote the sale, use or other dealings in\r
-these Data Files or Software without prior written authorization of the\r
-copyright holder.\r
+Unicode Data Files include all data files under the directories
+http://www.unicode.org/Public/, http://www.unicode.org/reports/, and
+http://www.unicode.org/cldr/data/. Unicode Data Files do not include PDF online
+code charts under the directory http://www.unicode.org/Public/. Software
+includes any source code published in the Unicode Standard or under the
+directories http://www.unicode.org/Public/, http://www.unicode.org/reports/, and
+http://www.unicode.org/cldr/data/.
+
+NOTICE TO USER: Carefully read the following legal agreement. BY DOWNLOADING,
+INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S DATA FILES ("DATA FILES"),
+AND/OR SOFTWARE ("SOFTWARE"), YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND
+BY, ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO
+NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWAR.
+
+COPYRIGHT AND PERMISSION NOTICE
+
+Copyright Â© 1991-2013 Unicode, Inc. All rights reserved. Distributed under the
+Terms of Use in http://www.unicode.org/copyright.html.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+the Unicode data files and any associated documentation (the "Data Files") or
+Unicode software and any associated documentation (the "Software") to deal in
+the Data Files or Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, and/or sell copies of
+the Data Files or Software, and to permit persons to whom the Data Files or
+Software are furnished to do so, provided that (a) the above copyright notice(s)
+and this permission notice appear with all copies of the Data Files or Software,
+(b) both the above copyright notice(s) and this permission notice appear in
+associated documentation, and (c) there is clear notice in each modified Data
+File or in the Software as well as in the documentation associated with the Data
+File(s) or Software that the data or software has been modified.
+
+THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD
+PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS
+NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL
+DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR
+SOFTWARE.
+
+Except as contained in this notice, the name of a copyright holder shall not be
+used in advertising or otherwise to promote the sale, use or other dealings in
+these Data Files or Software without prior written authorization of the
+copyright holder.
index 33e393bbfdd311be1aa2ee4108d354483b77d2b2..4c26642b5b70adf533a2e52ba56706e85a1a7c4d 100644 (file)
-/*\r
-  This is a version (aka dlmalloc) of malloc/free/realloc written by\r
-  Doug Lea and released to the public domain, as explained at\r
-  http://creativecommons.org/publicdomain/zero/1.0/ Send questions,\r
-  comments, complaints, performance data, etc to dl@cs.oswego.edu\r
-\r
-* Version 2.8.5 Sun May 22 10:26:02 2011  Doug Lea  (dl at gee)\r
-\r
-   Note: There may be an updated version of this malloc obtainable at\r
-           ftp://gee.cs.oswego.edu/pub/misc/malloc.c\r
-         Check before installing!\r
-\r
-* Quickstart\r
-\r
-  This library is all in one file to simplify the most common usage:\r
-  ftp it, compile it (-O3), and link it into another program. All of\r
-  the compile-time options default to reasonable values for use on\r
-  most platforms.  You might later want to step through various\r
-  compile-time and dynamic tuning options.\r
-\r
-  For convenience, an include file for code using this malloc is at:\r
-     ftp://gee.cs.oswego.edu/pub/misc/malloc-2.8.5.h\r
-  You don't really need this .h file unless you call functions not\r
-  defined in your system include files.  The .h file contains only the\r
-  excerpts from this file needed for using this malloc on ANSI C/C++\r
-  systems, so long as you haven't changed compile-time options about\r
-  naming and tuning parameters.  If you do, then you can create your\r
-  own malloc.h that does include all settings by cutting at the point\r
-  indicated below. Note that you may already by default be using a C\r
-  library containing a malloc that is based on some version of this\r
-  malloc (for example in linux). You might still want to use the one\r
-  in this file to customize settings or to avoid overheads associated\r
-  with library versions.\r
-\r
-* Vital statistics:\r
-\r
-  Supported pointer/size_t representation:       4 or 8 bytes\r
-       size_t MUST be an unsigned type of the same width as\r
-       pointers. (If you are using an ancient system that declares\r
-       size_t as a signed type, or need it to be a different width\r
-       than pointers, you can use a previous release of this malloc\r
-       (e.g. 2.7.2) supporting these.)\r
-\r
-  Alignment:                                     8 bytes (default)\r
-       This suffices for nearly all current machines and C compilers.\r
-       However, you can define MALLOC_ALIGNMENT to be wider than this\r
-       if necessary (up to 128bytes), at the expense of using more space.\r
-\r
-  Minimum overhead per allocated chunk:   4 or  8 bytes (if 4byte sizes)\r
-                                          8 or 16 bytes (if 8byte sizes)\r
-       Each malloced chunk has a hidden word of overhead holding size\r
-       and status information, and additional cross-check word\r
-       if FOOTERS is defined.\r
-\r
-  Minimum allocated size: 4-byte ptrs:  16 bytes    (including overhead)\r
-                          8-byte ptrs:  32 bytes    (including overhead)\r
-\r
-       Even a request for zero bytes (i.e., malloc(0)) returns a\r
-       pointer to something of the minimum allocatable size.\r
-       The maximum overhead wastage (i.e., number of extra bytes\r
-       allocated than were requested in malloc) is less than or equal\r
-       to the minimum size, except for requests >= mmap_threshold that\r
-       are serviced via mmap(), where the worst case wastage is about\r
-       32 bytes plus the remainder from a system page (the minimal\r
-       mmap unit); typically 4096 or 8192 bytes.\r
-\r
-  Security: static-safe; optionally more or less\r
-       The "security" of malloc refers to the ability of malicious\r
-       code to accentuate the effects of errors (for example, freeing\r
-       space that is not currently malloc'ed or overwriting past the\r
-       ends of chunks) in code that calls malloc.  This malloc\r
-       guarantees not to modify any memory locations below the base of\r
-       heap, i.e., static variables, even in the presence of usage\r
-       errors.  The routines additionally detect most improper frees\r
-       and reallocs.  All this holds as long as the static bookkeeping\r
-       for malloc itself is not corrupted by some other means.  This\r
-       is only one aspect of security -- these checks do not, and\r
-       cannot, detect all possible programming errors.\r
-\r
-       If FOOTERS is defined nonzero, then each allocated chunk\r
-       carries an additional check word to verify that it was malloced\r
-       from its space.  These check words are the same within each\r
-       execution of a program using malloc, but differ across\r
-       executions, so externally crafted fake chunks cannot be\r
-       freed. This improves security by rejecting frees/reallocs that\r
-       could corrupt heap memory, in addition to the checks preventing\r
-       writes to statics that are always on.  This may further improve\r
-       security at the expense of time and space overhead.  (Note that\r
-       FOOTERS may also be worth using with MSPACES.)\r
-\r
-       By default detected errors cause the program to abort (calling\r
-       "abort()"). You can override this to instead proceed past\r
-       errors by defining PROCEED_ON_ERROR.  In this case, a bad free\r
-       has no effect, and a malloc that encounters a bad address\r
-       caused by user overwrites will ignore the bad address by\r
-       dropping pointers and indices to all known memory. This may\r
-       be appropriate for programs that should continue if at all\r
-       possible in the face of programming errors, although they may\r
-       run out of memory because dropped memory is never reclaimed.\r
-\r
-       If you don't like either of these options, you can define\r
-       CORRUPTION_ERROR_ACTION and USAGE_ERROR_ACTION to do anything\r
-       else. And if if you are sure that your program using malloc has\r
-       no errors or vulnerabilities, you can define INSECURE to 1,\r
-       which might (or might not) provide a small performance improvement.\r
-\r
-       It is also possible to limit the maximum total allocatable\r
-       space, using malloc_set_footprint_limit. This is not\r
-       designed as a security feature in itself (calls to set limits\r
-       are not screened or privileged), but may be useful as one\r
-       aspect of a secure implementation.\r
-\r
-  Thread-safety: NOT thread-safe unless USE_LOCKS defined non-zero\r
-       When USE_LOCKS is defined, each public call to malloc, free,\r
-       etc is surrounded with a lock. By default, this uses a plain\r
-       pthread mutex, win32 critical section, or a spin-lock if if\r
-       available for the platform and not disabled by setting\r
-       USE_SPIN_LOCKS=0.  However, if USE_RECURSIVE_LOCKS is defined,\r
-       recursive versions are used instead (which are not required for\r
-       base functionality but may be needed in layered extensions).\r
-       Using a global lock is not especially fast, and can be a major\r
-       bottleneck.  It is designed only to provide minimal protection\r
-       in concurrent environments, and to provide a basis for\r
-       extensions.  If you are using malloc in a concurrent program,\r
-       consider instead using nedmalloc\r
-       (http://www.nedprod.com/programs/portable/nedmalloc/) or\r
-       ptmalloc (See http://www.malloc.de), which are derived from\r
-       versions of this malloc.\r
-\r
-  System requirements: Any combination of MORECORE and/or MMAP/MUNMAP\r
-       This malloc can use unix sbrk or any emulation (invoked using\r
-       the CALL_MORECORE macro) and/or mmap/munmap or any emulation\r
-       (invoked using CALL_MMAP/CALL_MUNMAP) to get and release system\r
-       memory.  On most unix systems, it tends to work best if both\r
-       MORECORE and MMAP are enabled.  On Win32, it uses emulations\r
-       based on VirtualAlloc. It also uses common C library functions\r
-       like memset.\r
-\r
-  Compliance: I believe it is compliant with the Single Unix Specification\r
-       (See http://www.unix.org). Also SVID/XPG, ANSI C, and probably\r
-       others as well.\r
-\r
-* Overview of algorithms\r
-\r
-  This is not the fastest, most space-conserving, most portable, or\r
-  most tunable malloc ever written. However it is among the fastest\r
-  while also being among the most space-conserving, portable and\r
-  tunable.  Consistent balance across these factors results in a good\r
-  general-purpose allocator for malloc-intensive programs.\r
-\r
-  In most ways, this malloc is a best-fit allocator. Generally, it\r
-  chooses the best-fitting existing chunk for a request, with ties\r
-  broken in approximately least-recently-used order. (This strategy\r
-  normally maintains low fragmentation.) However, for requests less\r
-  than 256bytes, it deviates from best-fit when there is not an\r
-  exactly fitting available chunk by preferring to use space adjacent\r
-  to that used for the previous small request, as well as by breaking\r
-  ties in approximately most-recently-used order. (These enhance\r
-  locality of series of small allocations.)  And for very large requests\r
-  (>= 256Kb by default), it relies on system memory mapping\r
-  facilities, if supported.  (This helps avoid carrying around and\r
-  possibly fragmenting memory used only for large chunks.)\r
-\r
-  All operations (except malloc_stats and mallinfo) have execution\r
-  times that are bounded by a constant factor of the number of bits in\r
-  a size_t, not counting any clearing in calloc or copying in realloc,\r
-  or actions surrounding MORECORE and MMAP that have times\r
-  proportional to the number of non-contiguous regions returned by\r
-  system allocation routines, which is often just 1. In real-time\r
-  applications, you can optionally suppress segment traversals using\r
-  NO_SEGMENT_TRAVERSAL, which assures bounded execution even when\r
-  system allocators return non-contiguous spaces, at the typical\r
-  expense of carrying around more memory and increased fragmentation.\r
-\r
-  The implementation is not very modular and seriously overuses\r
-  macros. Perhaps someday all C compilers will do as good a job\r
-  inlining modular code as can now be done by brute-force expansion,\r
-  but now, enough of them seem not to.\r
-\r
-  Some compilers issue a lot of warnings about code that is\r
-  dead/unreachable only on some platforms, and also about intentional\r
-  uses of negation on unsigned types. All known cases of each can be\r
-  ignored.\r
-\r
-  For a longer but out of date high-level description, see\r
-     http://gee.cs.oswego.edu/dl/html/malloc.html\r
-\r
-* MSPACES\r
-  If MSPACES is defined, then in addition to malloc, free, etc.,\r
-  this file also defines mspace_malloc, mspace_free, etc. These\r
-  are versions of malloc routines that take an "mspace" argument\r
-  obtained using create_mspace, to control all internal bookkeeping.\r
-  If ONLY_MSPACES is defined, only these versions are compiled.\r
-  So if you would like to use this allocator for only some allocations,\r
-  and your system malloc for others, you can compile with\r
-  ONLY_MSPACES and then do something like...\r
-    static mspace mymspace = create_mspace(0,0); // for example\r
-    #define mymalloc(bytes)  mspace_malloc(mymspace, bytes)\r
-\r
-  (Note: If you only need one instance of an mspace, you can instead\r
-  use "USE_DL_PREFIX" to relabel the global malloc.)\r
-\r
-  You can similarly create thread-local allocators by storing\r
-  mspaces as thread-locals. For example:\r
-    static __thread mspace tlms = 0;\r
-    void*  tlmalloc(size_t bytes) {\r
-      if (tlms == 0) tlms = create_mspace(0, 0);\r
-      return mspace_malloc(tlms, bytes);\r
-    }\r
-    void  tlfree(void* mem) { mspace_free(tlms, mem); }\r
-\r
-  Unless FOOTERS is defined, each mspace is completely independent.\r
-  You cannot allocate from one and free to another (although\r
-  conformance is only weakly checked, so usage errors are not always\r
-  caught). If FOOTERS is defined, then each chunk carries around a tag\r
-  indicating its originating mspace, and frees are directed to their\r
-  originating spaces. Normally, this requires use of locks.\r
-\r
- -------------------------  Compile-time options ---------------------------\r
-\r
-Be careful in setting #define values for numerical constants of type\r
-size_t. On some systems, literal values are not automatically extended\r
-to size_t precision unless they are explicitly casted. You can also\r
-use the symbolic values MAX_SIZE_T, SIZE_T_ONE, etc below.\r
-\r
-WIN32                    default: defined if _WIN32 defined\r
-  Defining WIN32 sets up defaults for MS environment and compilers.\r
-  Otherwise defaults are for unix. Beware that there seem to be some\r
-  cases where this malloc might not be a pure drop-in replacement for\r
-  Win32 malloc: Random-looking failures from Win32 GDI API's (eg;\r
-  SetDIBits()) may be due to bugs in some video driver implementations\r
-  when pixel buffers are malloc()ed, and the region spans more than\r
-  one VirtualAlloc()ed region. Because dlmalloc uses a small (64Kb)\r
-  default granularity, pixel buffers may straddle virtual allocation\r
-  regions more often than when using the Microsoft allocator.  You can\r
-  avoid this by using VirtualAlloc() and VirtualFree() for all pixel\r
-  buffers rather than using malloc().  If this is not possible,\r
-  recompile this malloc with a larger DEFAULT_GRANULARITY. Note:\r
-  in cases where MSC and gcc (cygwin) are known to differ on WIN32,\r
-  conditions use _MSC_VER to distinguish them.\r
-\r
-DLMALLOC_EXPORT       default: extern\r
-  Defines how public APIs are declared. If you want to export via a\r
-  Windows DLL, you might define this as\r
-    #define DLMALLOC_EXPORT extern  __declspace(dllexport)\r
-  If you want a POSIX ELF shared object, you might use\r
-    #define DLMALLOC_EXPORT extern __attribute__((visibility("default")))\r
-\r
-MALLOC_ALIGNMENT         default: (size_t)8\r
-  Controls the minimum alignment for malloc'ed chunks.  It must be a\r
-  power of two and at least 8, even on machines for which smaller\r
-  alignments would suffice. It may be defined as larger than this\r
-  though. Note however that code and data structures are optimized for\r
-  the case of 8-byte alignment.\r
-\r
-MSPACES                  default: 0 (false)\r
-  If true, compile in support for independent allocation spaces.\r
-  This is only supported if HAVE_MMAP is true.\r
-\r
-ONLY_MSPACES             default: 0 (false)\r
-  If true, only compile in mspace versions, not regular versions.\r
-\r
-USE_LOCKS                default: 0 (false)\r
-  Causes each call to each public routine to be surrounded with\r
-  pthread or WIN32 mutex lock/unlock. (If set true, this can be\r
-  overridden on a per-mspace basis for mspace versions.) If set to a\r
-  non-zero value other than 1, locks are used, but their\r
-  implementation is left out, so lock functions must be supplied manually,\r
-  as described below.\r
-\r
-USE_SPIN_LOCKS           default: 1 iff USE_LOCKS and spin locks available\r
-  If true, uses custom spin locks for locking. This is currently\r
-  supported only gcc >= 4.1, older gccs on x86 platforms, and recent\r
-  MS compilers.  Otherwise, posix locks or win32 critical sections are\r
-  used.\r
-\r
-USE_RECURSIVE_LOCKS      default: not defined\r
-  If defined nonzero, uses recursive (aka reentrant) locks, otherwise\r
-  uses plain mutexes. This is not required for malloc proper, but may\r
-  be needed for layered allocators such as nedmalloc.\r
-\r
-FOOTERS                  default: 0\r
-  If true, provide extra checking and dispatching by placing\r
-  information in the footers of allocated chunks. This adds\r
-  space and time overhead.\r
-\r
-INSECURE                 default: 0\r
-  If true, omit checks for usage errors and heap space overwrites.\r
-\r
-USE_DL_PREFIX            default: NOT defined\r
-  Causes compiler to prefix all public routines with the string 'dl'.\r
-  This can be useful when you only want to use this malloc in one part\r
-  of a program, using your regular system malloc elsewhere.\r
-\r
-MALLOC_INSPECT_ALL       default: NOT defined\r
-  If defined, compiles malloc_inspect_all and mspace_inspect_all, that\r
-  perform traversal of all heap space.  Unless access to these\r
-  functions is otherwise restricted, you probably do not want to\r
-  include them in secure implementations.\r
-\r
-ABORT                    default: defined as abort()\r
-  Defines how to abort on failed checks.  On most systems, a failed\r
-  check cannot die with an "assert" or even print an informative\r
-  message, because the underlying print routines in turn call malloc,\r
-  which will fail again.  Generally, the best policy is to simply call\r
-  abort(). It's not very useful to do more than this because many\r
-  errors due to overwriting will show up as address faults (null, odd\r
-  addresses etc) rather than malloc-triggered checks, so will also\r
-  abort.  Also, most compilers know that abort() does not return, so\r
-  can better optimize code conditionally calling it.\r
-\r
-PROCEED_ON_ERROR           default: defined as 0 (false)\r
-  Controls whether detected bad addresses cause them to bypassed\r
-  rather than aborting. If set, detected bad arguments to free and\r
-  realloc are ignored. And all bookkeeping information is zeroed out\r
-  upon a detected overwrite of freed heap space, thus losing the\r
-  ability to ever return it from malloc again, but enabling the\r
-  application to proceed. If PROCEED_ON_ERROR is defined, the\r
-  static variable malloc_corruption_error_count is compiled in\r
-  and can be examined to see if errors have occurred. This option\r
-  generates slower code than the default abort policy.\r
-\r
-DEBUG                    default: NOT defined\r
-  The DEBUG setting is mainly intended for people trying to modify\r
-  this code or diagnose problems when porting to new platforms.\r
-  However, it may also be able to better isolate user errors than just\r
-  using runtime checks.  The assertions in the check routines spell\r
-  out in more detail the assumptions and invariants underlying the\r
-  algorithms.  The checking is fairly extensive, and will slow down\r
-  execution noticeably. Calling malloc_stats or mallinfo with DEBUG\r
-  set will attempt to check every non-mmapped allocated and free chunk\r
-  in the course of computing the summaries.\r
-\r
-ABORT_ON_ASSERT_FAILURE   default: defined as 1 (true)\r
-  Debugging assertion failures can be nearly impossible if your\r
-  version of the assert macro causes malloc to be called, which will\r
-  lead to a cascade of further failures, blowing the runtime stack.\r
-  ABORT_ON_ASSERT_FAILURE cause assertions failures to call abort(),\r
-  which will usually make debugging easier.\r
-\r
-MALLOC_FAILURE_ACTION     default: sets errno to ENOMEM, or no-op on win32\r
-  The action to take before "return 0" when malloc fails to be able to\r
-  return memory because there is none available.\r
-\r
-HAVE_MORECORE             default: 1 (true) unless win32 or ONLY_MSPACES\r
-  True if this system supports sbrk or an emulation of it.\r
-\r
-MORECORE                  default: sbrk\r
-  The name of the sbrk-style system routine to call to obtain more\r
-  memory.  See below for guidance on writing custom MORECORE\r
-  functions. The type of the argument to sbrk/MORECORE varies across\r
-  systems.  It cannot be size_t, because it supports negative\r
-  arguments, so it is normally the signed type of the same width as\r
-  size_t (sometimes declared as "intptr_t").  It doesn't much matter\r
-  though. Internally, we only call it with arguments less than half\r
-  the max value of a size_t, which should work across all reasonable\r
-  possibilities, although sometimes generating compiler warnings.\r
-\r
-MORECORE_CONTIGUOUS       default: 1 (true) if HAVE_MORECORE\r
-  If true, take advantage of fact that consecutive calls to MORECORE\r
-  with positive arguments always return contiguous increasing\r
-  addresses.  This is true of unix sbrk. It does not hurt too much to\r
-  set it true anyway, since malloc copes with non-contiguities.\r
-  Setting it false when definitely non-contiguous saves time\r
-  and possibly wasted space it would take to discover this though.\r
-\r
-MORECORE_CANNOT_TRIM      default: NOT defined\r
-  True if MORECORE cannot release space back to the system when given\r
-  negative arguments. This is generally necessary only if you are\r
-  using a hand-crafted MORECORE function that cannot handle negative\r
-  arguments.\r
-\r
-NO_SEGMENT_TRAVERSAL       default: 0\r
-  If non-zero, suppresses traversals of memory segments\r
-  returned by either MORECORE or CALL_MMAP. This disables\r
-  merging of segments that are contiguous, and selectively\r
-  releasing them to the OS if unused, but bounds execution times.\r
-\r
-HAVE_MMAP                 default: 1 (true)\r
-  True if this system supports mmap or an emulation of it.  If so, and\r
-  HAVE_MORECORE is not true, MMAP is used for all system\r
-  allocation. If set and HAVE_MORECORE is true as well, MMAP is\r
-  primarily used to directly allocate very large blocks. It is also\r
-  used as a backup strategy in cases where MORECORE fails to provide\r
-  space from system. Note: A single call to MUNMAP is assumed to be\r
-  able to unmap memory that may have be allocated using multiple calls\r
-  to MMAP, so long as they are adjacent.\r
-\r
-HAVE_MREMAP               default: 1 on linux, else 0\r
-  If true realloc() uses mremap() to re-allocate large blocks and\r
-  extend or shrink allocation spaces.\r
-\r
-MMAP_CLEARS               default: 1 except on WINCE.\r
-  True if mmap clears memory so calloc doesn't need to. This is true\r
-  for standard unix mmap using /dev/zero and on WIN32 except for WINCE.\r
-\r
-USE_BUILTIN_FFS            default: 0 (i.e., not used)\r
-  Causes malloc to use the builtin ffs() function to compute indices.\r
-  Some compilers may recognize and intrinsify ffs to be faster than the\r
-  supplied C version. Also, the case of x86 using gcc is special-cased\r
-  to an asm instruction, so is already as fast as it can be, and so\r
-  this setting has no effect. Similarly for Win32 under recent MS compilers.\r
-  (On most x86s, the asm version is only slightly faster than the C version.)\r
-\r
-malloc_getpagesize         default: derive from system includes, or 4096.\r
-  The system page size. To the extent possible, this malloc manages\r
-  memory from the system in page-size units.  This may be (and\r
-  usually is) a function rather than a constant. This is ignored\r
-  if WIN32, where page size is determined using getSystemInfo during\r
-  initialization.\r
-\r
-USE_DEV_RANDOM             default: 0 (i.e., not used)\r
-  Causes malloc to use /dev/random to initialize secure magic seed for\r
-  stamping footers. Otherwise, the current time is used.\r
-\r
-NO_MALLINFO                default: 0\r
-  If defined, don't compile "mallinfo". This can be a simple way\r
-  of dealing with mismatches between system declarations and\r
-  those in this file.\r
-\r
-MALLINFO_FIELD_TYPE        default: size_t\r
-  The type of the fields in the mallinfo struct. This was originally\r
-  defined as "int" in SVID etc, but is more usefully defined as\r
-  size_t. The value is used only if  HAVE_USR_INCLUDE_MALLOC_H is not set\r
-\r
-NO_MALLOC_STATS            default: 0\r
-  If defined, don't compile "malloc_stats". This avoids calls to\r
-  fprintf and bringing in stdio dependencies you might not want.\r
-\r
-REALLOC_ZERO_BYTES_FREES    default: not defined\r
-  This should be set if a call to realloc with zero bytes should\r
-  be the same as a call to free. Some people think it should. Otherwise,\r
-  since this malloc returns a unique pointer for malloc(0), so does\r
-  realloc(p, 0).\r
-\r
-LACKS_UNISTD_H, LACKS_FCNTL_H, LACKS_SYS_PARAM_H, LACKS_SYS_MMAN_H\r
-LACKS_STRINGS_H, LACKS_STRING_H, LACKS_SYS_TYPES_H,  LACKS_ERRNO_H\r
-LACKS_STDLIB_H LACKS_SCHED_H LACKS_TIME_H  default: NOT defined unless on WIN32\r
-  Define these if your system does not have these header files.\r
-  You might need to manually insert some of the declarations they provide.\r
-\r
-DEFAULT_GRANULARITY        default: page size if MORECORE_CONTIGUOUS,\r
-                                system_info.dwAllocationGranularity in WIN32,\r
-                                otherwise 64K.\r
-      Also settable using mallopt(M_GRANULARITY, x)\r
-  The unit for allocating and deallocating memory from the system.  On\r
-  most systems with contiguous MORECORE, there is no reason to\r
-  make this more than a page. However, systems with MMAP tend to\r
-  either require or encourage larger granularities.  You can increase\r
-  this value to prevent system allocation functions to be called so\r
-  often, especially if they are slow.  The value must be at least one\r
-  page and must be a power of two.  Setting to 0 causes initialization\r
-  to either page size or win32 region size.  (Note: In previous\r
-  versions of malloc, the equivalent of this option was called\r
-  "TOP_PAD")\r
-\r
-DEFAULT_TRIM_THRESHOLD    default: 2MB\r
-      Also settable using mallopt(M_TRIM_THRESHOLD, x)\r
-  The maximum amount of unused top-most memory to keep before\r
-  releasing via malloc_trim in free().  Automatic trimming is mainly\r
-  useful in long-lived programs using contiguous MORECORE.  Because\r
-  trimming via sbrk can be slow on some systems, and can sometimes be\r
-  wasteful (in cases where programs immediately afterward allocate\r
-  more large chunks) the value should be high enough so that your\r
-  overall system performance would improve by releasing this much\r
-  memory.  As a rough guide, you might set to a value close to the\r
-  average size of a process (program) running on your system.\r
-  Releasing this much memory would allow such a process to run in\r
-  memory.  Generally, it is worth tuning trim thresholds when a\r
-  program undergoes phases where several large chunks are allocated\r
-  and released in ways that can reuse each other's storage, perhaps\r
-  mixed with phases where there are no such chunks at all. The trim\r
-  value must be greater than page size to have any useful effect.  To\r
-  disable trimming completely, you can set to MAX_SIZE_T. Note that the trick\r
-  some people use of mallocing a huge space and then freeing it at\r
-  program startup, in an attempt to reserve system memory, doesn't\r
-  have the intended effect under automatic trimming, since that memory\r
-  will immediately be returned to the system.\r
-\r
-DEFAULT_MMAP_THRESHOLD       default: 256K\r
-      Also settable using mallopt(M_MMAP_THRESHOLD, x)\r
-  The request size threshold for using MMAP to directly service a\r
-  request. Requests of at least this size that cannot be allocated\r
-  using already-existing space will be serviced via mmap.  (If enough\r
-  normal freed space already exists it is used instead.)  Using mmap\r
-  segregates relatively large chunks of memory so that they can be\r
-  individually obtained and released from the host system. A request\r
-  serviced through mmap is never reused by any other request (at least\r
-  not directly; the system may just so happen to remap successive\r
-  requests to the same locations).  Segregating space in this way has\r
-  the benefits that: Mmapped space can always be individually released\r
-  back to the system, which helps keep the system level memory demands\r
-  of a long-lived program low.  Also, mapped memory doesn't become\r
-  `locked' between other chunks, as can happen with normally allocated\r
-  chunks, which means that even trimming via malloc_trim would not\r
-  release them.  However, it has the disadvantage that the space\r
-  cannot be reclaimed, consolidated, and then used to service later\r
-  requests, as happens with normal chunks.  The advantages of mmap\r
-  nearly always outweigh disadvantages for "large" chunks, but the\r
-  value of "large" may vary across systems.  The default is an\r
-  empirically derived value that works well in most systems. You can\r
-  disable mmap by setting to MAX_SIZE_T.\r
-\r
-MAX_RELEASE_CHECK_RATE   default: 4095 unless not HAVE_MMAP\r
-  The number of consolidated frees between checks to release\r
-  unused segments when freeing. When using non-contiguous segments,\r
-  especially with multiple mspaces, checking only for topmost space\r
-  doesn't always suffice to trigger trimming. To compensate for this,\r
-  free() will, with a period of MAX_RELEASE_CHECK_RATE (or the\r
-  current number of segments, if greater) try to release unused\r
-  segments to the OS when freeing chunks that result in\r
-  consolidation. The best value for this parameter is a compromise\r
-  between slowing down frees with relatively costly checks that\r
-  rarely trigger versus holding on to unused memory. To effectively\r
-  disable, set to MAX_SIZE_T. This may lead to a very slight speed\r
-  improvement at the expense of carrying around more memory.\r
-*/\r
-\r
-#ifndef REGTEST\r
-#include "dlmalloc.h"\r
-\r
-/* Version identifier to allow people to support multiple versions */\r
-#ifndef DLMALLOC_VERSION\r
-#define DLMALLOC_VERSION 20805\r
-#endif /* DLMALLOC_VERSION */\r
-\r
-#ifndef DLMALLOC_EXPORT\r
-#define DLMALLOC_EXPORT extern\r
-#endif\r
-\r
-#ifndef WIN32\r
-#ifdef _WIN32\r
-#define WIN32 1\r
-#endif  /* _WIN32 */\r
-#ifdef _WIN32_WCE\r
-#define LACKS_FCNTL_H\r
-#define WIN32 1\r
-#endif /* _WIN32_WCE */\r
-#endif  /* WIN32 */\r
-#ifdef WIN32\r
-#define WIN32_LEAN_AND_MEAN\r
-#include <windows.h>\r
-#include <tchar.h>\r
-#define HAVE_MMAP 1\r
-#define HAVE_MORECORE 0\r
-#define LACKS_UNISTD_H\r
-#define LACKS_SYS_PARAM_H\r
-#define LACKS_SYS_MMAN_H\r
-#define LACKS_STRING_H\r
-#define LACKS_STRINGS_H\r
-#define LACKS_SYS_TYPES_H\r
-#define LACKS_ERRNO_H\r
-#define LACKS_SCHED_H\r
-#ifndef MALLOC_FAILURE_ACTION\r
-#define MALLOC_FAILURE_ACTION\r
-#endif /* MALLOC_FAILURE_ACTION */\r
-#ifndef MMAP_CLEARS\r
-#ifdef _WIN32_WCE /* WINCE reportedly does not clear */\r
-#define MMAP_CLEARS 0\r
-#else\r
-#define MMAP_CLEARS 1\r
-#endif /* _WIN32_WCE */\r
-#endif /*MMAP_CLEARS */\r
-#endif  /* WIN32 */\r
-\r
-#if defined(DARWIN) || defined(_DARWIN)\r
-/* Mac OSX docs advise not to use sbrk; it seems better to use mmap */\r
-#ifndef HAVE_MORECORE\r
-#define HAVE_MORECORE 0\r
-#define HAVE_MMAP 1\r
-/* OSX allocators provide 16 byte alignment */\r
-#ifndef MALLOC_ALIGNMENT\r
-#define MALLOC_ALIGNMENT ((size_t)16U)\r
-#endif\r
-#endif  /* HAVE_MORECORE */\r
-#endif  /* DARWIN */\r
-\r
-#ifndef LACKS_SYS_TYPES_H\r
-#include <sys/types.h>  /* For size_t */\r
-#endif  /* LACKS_SYS_TYPES_H */\r
-\r
-/* The maximum possible size_t value has all bits set */\r
-#define MAX_SIZE_T           (~(size_t)0)\r
-\r
-#ifndef USE_LOCKS /* ensure true if spin or recursive locks set */\r
-#define USE_LOCKS  ((defined(USE_SPIN_LOCKS) && USE_SPIN_LOCKS != 0) || \\r
-                    (defined(USE_RECURSIVE_LOCKS) && USE_RECURSIVE_LOCKS != 0))\r
-#endif /* USE_LOCKS */\r
-\r
-#if USE_LOCKS /* Spin locks for gcc >= 4.1, older gcc on x86, MSC >= 1310 */\r
-#if ((defined(__GNUC__) &&                                              \\r
-      ((__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) ||      \\r
-       defined(__i386__) || defined(__x86_64__))) ||                    \\r
-     (defined(_MSC_VER) && _MSC_VER>=1310))\r
-#ifndef USE_SPIN_LOCKS\r
-#define USE_SPIN_LOCKS 1\r
-#endif /* USE_SPIN_LOCKS */\r
-#elif USE_SPIN_LOCKS\r
-#error "USE_SPIN_LOCKS defined without implementation"\r
-#endif /* ... locks available... */\r
-#elif !defined(USE_SPIN_LOCKS)\r
-#define USE_SPIN_LOCKS 0\r
-#endif /* USE_LOCKS */\r
-\r
-#ifndef ONLY_MSPACES\r
-#define ONLY_MSPACES 0\r
-#endif  /* ONLY_MSPACES */\r
-#ifndef MSPACES\r
-#if ONLY_MSPACES\r
-#define MSPACES 1\r
-#else   /* ONLY_MSPACES */\r
-#define MSPACES 0\r
-#endif  /* ONLY_MSPACES */\r
-#endif  /* MSPACES */\r
-#ifndef MALLOC_ALIGNMENT\r
-#define MALLOC_ALIGNMENT ((size_t)8U)\r
-#endif  /* MALLOC_ALIGNMENT */\r
-#ifndef FOOTERS\r
-#define FOOTERS 0\r
-#endif  /* FOOTERS */\r
-#ifndef ABORT\r
-#define ABORT  abort()\r
-#endif  /* ABORT */\r
-#ifndef ABORT_ON_ASSERT_FAILURE\r
-#define ABORT_ON_ASSERT_FAILURE 1\r
-#endif  /* ABORT_ON_ASSERT_FAILURE */\r
-#ifndef PROCEED_ON_ERROR\r
-#define PROCEED_ON_ERROR 0\r
-#endif  /* PROCEED_ON_ERROR */\r
-\r
-#ifndef INSECURE\r
-#define INSECURE 0\r
-#endif  /* INSECURE */\r
-#ifndef MALLOC_INSPECT_ALL\r
-#define MALLOC_INSPECT_ALL 0\r
-#endif  /* MALLOC_INSPECT_ALL */\r
-#ifndef HAVE_MMAP\r
-#define HAVE_MMAP 1\r
-#endif  /* HAVE_MMAP */\r
-#ifndef MMAP_CLEARS\r
-#define MMAP_CLEARS 1\r
-#endif  /* MMAP_CLEARS */\r
-#ifndef HAVE_MREMAP\r
-#ifdef linux\r
-#define HAVE_MREMAP 1\r
-#define _GNU_SOURCE /* Turns on mremap() definition */\r
-#else   /* linux */\r
-#define HAVE_MREMAP 0\r
-#endif  /* linux */\r
-#endif  /* HAVE_MREMAP */\r
-#ifndef MALLOC_FAILURE_ACTION\r
-#define MALLOC_FAILURE_ACTION  errno = ENOMEM;\r
-#endif  /* MALLOC_FAILURE_ACTION */\r
-#ifndef HAVE_MORECORE\r
-#if ONLY_MSPACES\r
-#define HAVE_MORECORE 0\r
-#else   /* ONLY_MSPACES */\r
-#define HAVE_MORECORE 1\r
-#endif  /* ONLY_MSPACES */\r
-#endif  /* HAVE_MORECORE */\r
-#if !HAVE_MORECORE\r
-#define MORECORE_CONTIGUOUS 0\r
-#else   /* !HAVE_MORECORE */\r
-#define MORECORE_DEFAULT sbrk\r
-#ifndef MORECORE_CONTIGUOUS\r
-#define MORECORE_CONTIGUOUS 1\r
-#endif  /* MORECORE_CONTIGUOUS */\r
-#endif  /* HAVE_MORECORE */\r
-#ifndef DEFAULT_GRANULARITY\r
-#if (MORECORE_CONTIGUOUS || defined(WIN32))\r
-#define DEFAULT_GRANULARITY (0)  /* 0 means to compute in init_mparams */\r
-#else   /* MORECORE_CONTIGUOUS */\r
-#define DEFAULT_GRANULARITY ((size_t)64U * (size_t)1024U)\r
-#endif  /* MORECORE_CONTIGUOUS */\r
-#endif  /* DEFAULT_GRANULARITY */\r
-#ifndef DEFAULT_TRIM_THRESHOLD\r
-#ifndef MORECORE_CANNOT_TRIM\r
-#define DEFAULT_TRIM_THRESHOLD ((size_t)2U * (size_t)1024U * (size_t)1024U)\r
-#else   /* MORECORE_CANNOT_TRIM */\r
-#define DEFAULT_TRIM_THRESHOLD MAX_SIZE_T\r
-#endif  /* MORECORE_CANNOT_TRIM */\r
-#endif  /* DEFAULT_TRIM_THRESHOLD */\r
-#ifndef DEFAULT_MMAP_THRESHOLD\r
-#if HAVE_MMAP\r
-#define DEFAULT_MMAP_THRESHOLD ((size_t)256U * (size_t)1024U)\r
-#else   /* HAVE_MMAP */\r
-#define DEFAULT_MMAP_THRESHOLD MAX_SIZE_T\r
-#endif  /* HAVE_MMAP */\r
-#endif  /* DEFAULT_MMAP_THRESHOLD */\r
-#ifndef MAX_RELEASE_CHECK_RATE\r
-#if HAVE_MMAP\r
-#define MAX_RELEASE_CHECK_RATE 4095\r
-#else\r
-#define MAX_RELEASE_CHECK_RATE MAX_SIZE_T\r
-#endif /* HAVE_MMAP */\r
-#endif /* MAX_RELEASE_CHECK_RATE */\r
-#ifndef USE_BUILTIN_FFS\r
-#define USE_BUILTIN_FFS 0\r
-#endif  /* USE_BUILTIN_FFS */\r
-#ifndef USE_DEV_RANDOM\r
-#define USE_DEV_RANDOM 0\r
-#endif  /* USE_DEV_RANDOM */\r
-#ifndef NO_MALLINFO\r
-#define NO_MALLINFO 0\r
-#endif  /* NO_MALLINFO */\r
-#ifndef MALLINFO_FIELD_TYPE\r
-#define MALLINFO_FIELD_TYPE size_t\r
-#endif  /* MALLINFO_FIELD_TYPE */\r
-#ifndef NO_MALLOC_STATS\r
-#define NO_MALLOC_STATS 0\r
-#endif  /* NO_MALLOC_STATS */\r
-#ifndef NO_SEGMENT_TRAVERSAL\r
-#define NO_SEGMENT_TRAVERSAL 0\r
-#endif /* NO_SEGMENT_TRAVERSAL */\r
-\r
-/*\r
-  mallopt tuning options.  SVID/XPG defines four standard parameter\r
-  numbers for mallopt, normally defined in malloc.h.  None of these\r
-  are used in this malloc, so setting them has no effect. But this\r
-  malloc does support the following options.\r
-*/\r
-\r
-#define M_TRIM_THRESHOLD     (-1)\r
-#define M_GRANULARITY        (-2)\r
-#define M_MMAP_THRESHOLD     (-3)\r
-\r
-/* ------------------------ Mallinfo declarations ------------------------ */\r
-\r
-#if !NO_MALLINFO\r
-/*\r
-  This version of malloc supports the standard SVID/XPG mallinfo\r
-  routine that returns a struct containing usage properties and\r
-  statistics. It should work on any system that has a\r
-  /usr/include/malloc.h defining struct mallinfo.  The main\r
-  declaration needed is the mallinfo struct that is returned (by-copy)\r
-  by mallinfo().  The malloinfo struct contains a bunch of fields that\r
-  are not even meaningful in this version of malloc.  These fields are\r
-  are instead filled by mallinfo() with other numbers that might be of\r
-  interest.\r
-\r
-  HAVE_USR_INCLUDE_MALLOC_H should be set if you have a\r
-  /usr/include/malloc.h file that includes a declaration of struct\r
-  mallinfo.  If so, it is included; else a compliant version is\r
-  declared below.  These must be precisely the same for mallinfo() to\r
-  work.  The original SVID version of this struct, defined on most\r
-  systems with mallinfo, declares all fields as ints. But some others\r
-  define as unsigned long. If your system defines the fields using a\r
-  type of different width than listed here, you MUST #include your\r
-  system version and #define HAVE_USR_INCLUDE_MALLOC_H.\r
-*/\r
-\r
-/* #define HAVE_USR_INCLUDE_MALLOC_H */\r
-\r
-#ifdef HAVE_USR_INCLUDE_MALLOC_H\r
-#include "/usr/include/malloc.h"\r
-#else /* HAVE_USR_INCLUDE_MALLOC_H */\r
-#ifndef STRUCT_MALLINFO_DECLARED\r
-/* HP-UX (and others?) redefines mallinfo unless _STRUCT_MALLINFO is defined */\r
-#define _STRUCT_MALLINFO\r
-#define STRUCT_MALLINFO_DECLARED 1\r
-struct mallinfo {\r
-  MALLINFO_FIELD_TYPE arena;    /* non-mmapped space allocated from system */\r
-  MALLINFO_FIELD_TYPE ordblks;  /* number of free chunks */\r
-  MALLINFO_FIELD_TYPE smblks;   /* always 0 */\r
-  MALLINFO_FIELD_TYPE hblks;    /* always 0 */\r
-  MALLINFO_FIELD_TYPE hblkhd;   /* space in mmapped regions */\r
-  MALLINFO_FIELD_TYPE usmblks;  /* maximum total allocated space */\r
-  MALLINFO_FIELD_TYPE fsmblks;  /* always 0 */\r
-  MALLINFO_FIELD_TYPE uordblks; /* total allocated space */\r
-  MALLINFO_FIELD_TYPE fordblks; /* total free space */\r
-  MALLINFO_FIELD_TYPE keepcost; /* releasable (via malloc_trim) space */\r
-};\r
-#endif /* STRUCT_MALLINFO_DECLARED */\r
-#endif /* HAVE_USR_INCLUDE_MALLOC_H */\r
-#endif /* NO_MALLINFO */\r
-\r
-/*\r
-  Try to persuade compilers to inline. The most critical functions for\r
-  inlining are defined as macros, so these aren't used for them.\r
-*/\r
-\r
-#ifndef FORCEINLINE\r
-  #if defined(__GNUC__)\r
-#define FORCEINLINE __inline __attribute__ ((always_inline))\r
-  #elif defined(_MSC_VER)\r
-    #define FORCEINLINE __forceinline\r
-  #endif\r
-#endif\r
-#ifndef NOINLINE\r
-  #if defined(__GNUC__)\r
-    #define NOINLINE __attribute__ ((noinline))\r
-  #elif defined(_MSC_VER)\r
-    #define NOINLINE __declspec(noinline)\r
-  #else\r
-    #define NOINLINE\r
-  #endif\r
-#endif\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#ifndef FORCEINLINE\r
- #define FORCEINLINE inline\r
-#endif\r
-#endif /* __cplusplus */\r
-#ifndef FORCEINLINE\r
- #define FORCEINLINE\r
-#endif\r
-\r
-#if !ONLY_MSPACES\r
-\r
-/* ------------------- Declarations of public routines ------------------- */\r
-\r
-#ifndef USE_DL_PREFIX\r
-#define dlcalloc               calloc\r
-#define dlfree                 free\r
-#define dlmalloc               malloc\r
-#define dlmemalign             aligned_alloc\r
-#define dlposix_memalign       posix_memalign\r
-#define dlrealloc              realloc\r
-#define dlrealloc_in_place     realloc_in_place\r
-#define dlvalloc               valloc\r
-#define dlpvalloc              pvalloc\r
-#define dlmallinfo             mallinfo\r
-#define dlmallopt              mallopt\r
-#define dlmalloc_trim          malloc_trim\r
-#define dlmalloc_stats         malloc_stats\r
-#define dlmalloc_usable_size   malloc_usable_size\r
-#define dlmalloc_footprint     malloc_footprint\r
-#define dlmalloc_max_footprint malloc_max_footprint\r
-#define dlmalloc_footprint_limit malloc_footprint_limit\r
-#define dlmalloc_set_footprint_limit malloc_set_footprint_limit\r
-#define dlmalloc_inspect_all   malloc_inspect_all\r
-#define dlindependent_calloc   independent_calloc\r
-#define dlindependent_comalloc independent_comalloc\r
-#define dlbulk_free            bulk_free\r
-#endif /* USE_DL_PREFIX */\r
-\r
-#if 0 // Redeclaration warnings as PDCLib already declares these in <stdio.h>\r
-\r
-/*\r
-  malloc(size_t n)\r
-  Returns a pointer to a newly allocated chunk of at least n bytes, or\r
-  null if no space is available, in which case errno is set to ENOMEM\r
-  on ANSI C systems.\r
-\r
-  If n is zero, malloc returns a minimum-sized chunk. (The minimum\r
-  size is 16 bytes on most 32bit systems, and 32 bytes on 64bit\r
-  systems.)  Note that size_t is an unsigned type, so calls with\r
-  arguments that would be negative if signed are interpreted as\r
-  requests for huge amounts of space, which will often fail. The\r
-  maximum supported value of n differs across systems, but is in all\r
-  cases less than the maximum representable value of a size_t.\r
-*/\r
-DLMALLOC_EXPORT void* dlmalloc(size_t);\r
-\r
-/*\r
-  free(void* p)\r
-  Releases the chunk of memory pointed to by p, that had been previously\r
-  allocated using malloc or a related routine such as realloc.\r
-  It has no effect if p is null. If p was not malloced or already\r
-  freed, free(p) will by default cause the current program to abort.\r
-*/\r
-DLMALLOC_EXPORT void  dlfree(void*);\r
-\r
-/*\r
-  calloc(size_t n_elements, size_t element_size);\r
-  Returns a pointer to n_elements * element_size bytes, with all locations\r
-  set to zero.\r
-*/\r
-DLMALLOC_EXPORT void* dlcalloc(size_t, size_t);\r
-\r
-/*\r
-  realloc(void* p, size_t n)\r
-  Returns a pointer to a chunk of size n that contains the same data\r
-  as does chunk p up to the minimum of (n, p's size) bytes, or null\r
-  if no space is available.\r
-\r
-  The returned pointer may or may not be the same as p. The algorithm\r
-  prefers extending p in most cases when possible, otherwise it\r
-  employs the equivalent of a malloc-copy-free sequence.\r
-\r
-  If p is null, realloc is equivalent to malloc.\r
-\r
-  If space is not available, realloc returns null, errno is set (if on\r
-  ANSI) and p is NOT freed.\r
-\r
-  if n is for fewer bytes than already held by p, the newly unused\r
-  space is lopped off and freed if possible.  realloc with a size\r
-  argument of zero (re)allocates a minimum-sized chunk.\r
-\r
-  The old unix realloc convention of allowing the last-free'd chunk\r
-  to be used as an argument to realloc is not supported.\r
-*/\r
-DLMALLOC_EXPORT void* dlrealloc(void*, size_t);\r
-\r
-#endif\r
-\r
-/*\r
-  realloc_in_place(void* p, size_t n)\r
-  Resizes the space allocated for p to size n, only if this can be\r
-  done without moving p (i.e., only if there is adjacent space\r
-  available if n is greater than p's current allocated size, or n is\r
-  less than or equal to p's size). This may be used instead of plain\r
-  realloc if an alternative allocation strategy is needed upon failure\r
-  to expand space; for example, reallocation of a buffer that must be\r
-  memory-aligned or cleared. You can use realloc_in_place to trigger\r
-  these alternatives only when needed.\r
-\r
-  Returns p if successful; otherwise null.\r
-*/\r
-DLMALLOC_EXPORT void* dlrealloc_in_place(void*, size_t);\r
-\r
-#if 0 // Redeclaration warnings as PDCLib already declares these in <stdio.h>\r
-\r
-/*\r
-  memalign(size_t alignment, size_t n);\r
-  Returns a pointer to a newly allocated chunk of n bytes, aligned\r
-  in accord with the alignment argument.\r
-\r
-  The alignment argument should be a power of two. If the argument is\r
-  not a power of two, the nearest greater power is used.\r
-  8-byte alignment is guaranteed by normal malloc calls, so don't\r
-  bother calling memalign with an argument of 8 or less.\r
-\r
-  Overreliance on memalign is a sure way to fragment space.\r
-*/\r
-DLMALLOC_EXPORT void* dlmemalign(size_t, size_t);\r
-\r
-#endif\r
-\r
-/*\r
-  int posix_memalign(void** pp, size_t alignment, size_t n);\r
-  Allocates a chunk of n bytes, aligned in accord with the alignment\r
-  argument. Differs from memalign only in that it (1) assigns the\r
-  allocated memory to *pp rather than returning it, (2) fails and\r
-  returns EINVAL if the alignment is not a power of two (3) fails and\r
-  returns ENOMEM if memory cannot be allocated.\r
-*/\r
-DLMALLOC_EXPORT int dlposix_memalign(void**, size_t, size_t);\r
-\r
-/*\r
-  valloc(size_t n);\r
-  Equivalent to memalign(pagesize, n), where pagesize is the page\r
-  size of the system. If the pagesize is unknown, 4096 is used.\r
-*/\r
-DLMALLOC_EXPORT void* dlvalloc(size_t);\r
-\r
-/*\r
-  mallopt(int parameter_number, int parameter_value)\r
-  Sets tunable parameters The format is to provide a\r
-  (parameter-number, parameter-value) pair.  mallopt then sets the\r
-  corresponding parameter to the argument value if it can (i.e., so\r
-  long as the value is meaningful), and returns 1 if successful else\r
-  0.  To workaround the fact that mallopt is specified to use int,\r
-  not size_t parameters, the value -1 is specially treated as the\r
-  maximum unsigned size_t value.\r
-\r
-  SVID/XPG/ANSI defines four standard param numbers for mallopt,\r
-  normally defined in malloc.h.  None of these are use in this malloc,\r
-  so setting them has no effect. But this malloc also supports other\r
-  options in mallopt. See below for details.  Briefly, supported\r
-  parameters are as follows (listed defaults are for "typical"\r
-  configurations).\r
-\r
-  Symbol            param #  default    allowed param values\r
-  M_TRIM_THRESHOLD     -1   2*1024*1024   any   (-1 disables)\r
-  M_GRANULARITY        -2     page size   any power of 2 >= page size\r
-  M_MMAP_THRESHOLD     -3      256*1024   any   (or 0 if no MMAP support)\r
-*/\r
-DLMALLOC_EXPORT int dlmallopt(int, int);\r
-\r
-/*\r
-  malloc_footprint();\r
-  Returns the number of bytes obtained from the system.  The total\r
-  number of bytes allocated by malloc, realloc etc., is less than this\r
-  value. Unlike mallinfo, this function returns only a precomputed\r
-  result, so can be called frequently to monitor memory consumption.\r
-  Even if locks are otherwise defined, this function does not use them,\r
-  so results might not be up to date.\r
-*/\r
-DLMALLOC_EXPORT size_t dlmalloc_footprint(void);\r
-\r
-/*\r
-  malloc_max_footprint();\r
-  Returns the maximum number of bytes obtained from the system. This\r
-  value will be greater than current footprint if deallocated space\r
-  has been reclaimed by the system. The peak number of bytes allocated\r
-  by malloc, realloc etc., is less than this value. Unlike mallinfo,\r
-  this function returns only a precomputed result, so can be called\r
-  frequently to monitor memory consumption.  Even if locks are\r
-  otherwise defined, this function does not use them, so results might\r
-  not be up to date.\r
-*/\r
-DLMALLOC_EXPORT size_t dlmalloc_max_footprint(void);\r
-\r
-/*\r
-  malloc_footprint_limit();\r
-  Returns the number of bytes that the heap is allowed to obtain from\r
-  the system, returning the last value returned by\r
-  malloc_set_footprint_limit, or the maximum size_t value if\r
-  never set. The returned value reflects a permission. There is no\r
-  guarantee that this number of bytes can actually be obtained from\r
-  the system.\r
-*/\r
-DLMALLOC_EXPORT size_t dlmalloc_footprint_limit(void);\r
-\r
-/*\r
-  malloc_set_footprint_limit();\r
-  Sets the maximum number of bytes to obtain from the system, causing\r
-  failure returns from malloc and related functions upon attempts to\r
-  exceed this value. The argument value may be subject to page\r
-  rounding to an enforceable limit; this actual value is returned.\r
-  Using an argument of the maximum possible size_t effectively\r
-  disables checks. If the argument is less than or equal to the\r
-  current malloc_footprint, then all future allocations that require\r
-  additional system memory will fail. However, invocation cannot\r
-  retroactively deallocate existing used memory.\r
-*/\r
-DLMALLOC_EXPORT size_t dlmalloc_set_footprint_limit(size_t bytes);\r
-\r
-#if MALLOC_INSPECT_ALL\r
-/*\r
-  malloc_inspect_all(void(*handler)(void *start,\r
-                                    void *end,\r
-                                    size_t used_bytes,\r
-                                    void* callback_arg),\r
-                      void* arg);\r
-  Traverses the heap and calls the given handler for each managed\r
-  region, skipping all bytes that are (or may be) used for bookkeeping\r
-  purposes.  Traversal does not include include chunks that have been\r
-  directly memory mapped. Each reported region begins at the start\r
-  address, and continues up to but not including the end address.  The\r
-  first used_bytes of the region contain allocated data. If\r
-  used_bytes is zero, the region is unallocated. The handler is\r
-  invoked with the given callback argument. If locks are defined, they\r
-  are held during the entire traversal. It is a bad idea to invoke\r
-  other malloc functions from within the handler.\r
-\r
-  For example, to count the number of in-use chunks with size greater\r
-  than 1000, you could write:\r
-  static int count = 0;\r
-  void count_chunks(void* start, void* end, size_t used, void* arg) {\r
-    if (used >= 1000) ++count;\r
-  }\r
-  then:\r
-    malloc_inspect_all(count_chunks, NULL);\r
-\r
-  malloc_inspect_all is compiled only if MALLOC_INSPECT_ALL is defined.\r
-*/\r
-DLMALLOC_EXPORT void dlmalloc_inspect_all(void(*handler)(void*, void *, size_t, void*),\r
-                           void* arg);\r
-\r
-#endif /* MALLOC_INSPECT_ALL */\r
-\r
-#if !NO_MALLINFO\r
-/*\r
-  mallinfo()\r
-  Returns (by copy) a struct containing various summary statistics:\r
-\r
-  arena:     current total non-mmapped bytes allocated from system\r
-  ordblks:   the number of free chunks\r
-  smblks:    always zero.\r
-  hblks:     current number of mmapped regions\r
-  hblkhd:    total bytes held in mmapped regions\r
-  usmblks:   the maximum total allocated space. This will be greater\r
-                than current total if trimming has occurred.\r
-  fsmblks:   always zero\r
-  uordblks:  current total allocated space (normal or mmapped)\r
-  fordblks:  total free space\r
-  keepcost:  the maximum number of bytes that could ideally be released\r
-               back to system via malloc_trim. ("ideally" means that\r
-               it ignores page restrictions etc.)\r
-\r
-  Because these fields are ints, but internal bookkeeping may\r
-  be kept as longs, the reported values may wrap around zero and\r
-  thus be inaccurate.\r
-*/\r
-DLMALLOC_EXPORT struct mallinfo dlmallinfo(void);\r
-#endif /* NO_MALLINFO */\r
-\r
-/*\r
-  independent_calloc(size_t n_elements, size_t element_size, void* chunks[]);\r
-\r
-  independent_calloc is similar to calloc, but instead of returning a\r
-  single cleared space, it returns an array of pointers to n_elements\r
-  independent elements that can hold contents of size elem_size, each\r
-  of which starts out cleared, and can be independently freed,\r
-  realloc'ed etc. The elements are guaranteed to be adjacently\r
-  allocated (this is not guaranteed to occur with multiple callocs or\r
-  mallocs), which may also improve cache locality in some\r
-  applications.\r
-\r
-  The "chunks" argument is optional (i.e., may be null, which is\r
-  probably the most typical usage). If it is null, the returned array\r
-  is itself dynamically allocated and should also be freed when it is\r
-  no longer needed. Otherwise, the chunks array must be of at least\r
-  n_elements in length. It is filled in with the pointers to the\r
-  chunks.\r
-\r
-  In either case, independent_calloc returns this pointer array, or\r
-  null if the allocation failed.  If n_elements is zero and "chunks"\r
-  is null, it returns a chunk representing an array with zero elements\r
-  (which should be freed if not wanted).\r
-\r
-  Each element must be freed when it is no longer needed. This can be\r
-  done all at once using bulk_free.\r
-\r
-  independent_calloc simplifies and speeds up implementations of many\r
-  kinds of pools.  It may also be useful when constructing large data\r
-  structures that initially have a fixed number of fixed-sized nodes,\r
-  but the number is not known at compile time, and some of the nodes\r
-  may later need to be freed. For example:\r
-\r
-  struct Node { int item; struct Node* next; };\r
-\r
-  struct Node* build_list() {\r
-    struct Node** pool;\r
-    int n = read_number_of_nodes_needed();\r
-    if (n <= 0) return 0;\r
-    pool = (struct Node**)(independent_calloc(n, sizeof(struct Node), 0);\r
-    if (pool == 0) die();\r
-    // organize into a linked list...\r
-    struct Node* first = pool[0];\r
-    for (i = 0; i < n-1; ++i)\r
-      pool[i]->next = pool[i+1];\r
-    free(pool);     // Can now free the array (or not, if it is needed later)\r
-    return first;\r
-  }\r
-*/\r
-DLMALLOC_EXPORT void** dlindependent_calloc(size_t, size_t, void**);\r
-\r
-/*\r
-  independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]);\r
-\r
-  independent_comalloc allocates, all at once, a set of n_elements\r
-  chunks with sizes indicated in the "sizes" array.    It returns\r
-  an array of pointers to these elements, each of which can be\r
-  independently freed, realloc'ed etc. The elements are guaranteed to\r
-  be adjacently allocated (this is not guaranteed to occur with\r
-  multiple callocs or mallocs), which may also improve cache locality\r
-  in some applications.\r
-\r
-  The "chunks" argument is optional (i.e., may be null). If it is null\r
-  the returned array is itself dynamically allocated and should also\r
-  be freed when it is no longer needed. Otherwise, the chunks array\r
-  must be of at least n_elements in length. It is filled in with the\r
-  pointers to the chunks.\r
-\r
-  In either case, independent_comalloc returns this pointer array, or\r
-  null if the allocation failed.  If n_elements is zero and chunks is\r
-  null, it returns a chunk representing an array with zero elements\r
-  (which should be freed if not wanted).\r
-\r
-  Each element must be freed when it is no longer needed. This can be\r
-  done all at once using bulk_free.\r
-\r
-  independent_comallac differs from independent_calloc in that each\r
-  element may have a different size, and also that it does not\r
-  automatically clear elements.\r
-\r
-  independent_comalloc can be used to speed up allocation in cases\r
-  where several structs or objects must always be allocated at the\r
-  same time.  For example:\r
-\r
-  struct Head { ... }\r
-  struct Foot { ... }\r
-\r
-  void send_message(char* msg) {\r
-    int msglen = strlen(msg);\r
-    size_t sizes[3] = { sizeof(struct Head), msglen, sizeof(struct Foot) };\r
-    void* chunks[3];\r
-    if (independent_comalloc(3, sizes, chunks) == 0)\r
-      die();\r
-    struct Head* head = (struct Head*)(chunks[0]);\r
-    char*        body = (char*)(chunks[1]);\r
-    struct Foot* foot = (struct Foot*)(chunks[2]);\r
-    // ...\r
-  }\r
-\r
-  In general though, independent_comalloc is worth using only for\r
-  larger values of n_elements. For small values, you probably won't\r
-  detect enough difference from series of malloc calls to bother.\r
-\r
-  Overuse of independent_comalloc can increase overall memory usage,\r
-  since it cannot reuse existing noncontiguous small chunks that\r
-  might be available for some of the elements.\r
-*/\r
-DLMALLOC_EXPORT void** dlindependent_comalloc(size_t, size_t*, void**);\r
-\r
-/*\r
-  bulk_free(void* array[], size_t n_elements)\r
-  Frees and clears (sets to null) each non-null pointer in the given\r
-  array.  This is likely to be faster than freeing them one-by-one.\r
-  If footers are used, pointers that have been allocated in different\r
-  mspaces are not freed or cleared, and the count of all such pointers\r
-  is returned.  For large arrays of pointers with poor locality, it\r
-  may be worthwhile to sort this array before calling bulk_free.\r
-*/\r
-DLMALLOC_EXPORT size_t  dlbulk_free(void**, size_t n_elements);\r
-\r
-/*\r
-  pvalloc(size_t n);\r
-  Equivalent to valloc(minimum-page-that-holds(n)), that is,\r
-  round up n to nearest pagesize.\r
- */\r
-DLMALLOC_EXPORT void*  dlpvalloc(size_t);\r
-\r
-/*\r
-  malloc_trim(size_t pad);\r
-\r
-  If possible, gives memory back to the system (via negative arguments\r
-  to sbrk) if there is unused memory at the `high' end of the malloc\r
-  pool or in unused MMAP segments. You can call this after freeing\r
-  large blocks of memory to potentially reduce the system-level memory\r
-  requirements of a program. However, it cannot guarantee to reduce\r
-  memory. Under some allocation patterns, some large free blocks of\r
-  memory will be locked between two used chunks, so they cannot be\r
-  given back to the system.\r
-\r
-  The `pad' argument to malloc_trim represents the amount of free\r
-  trailing space to leave untrimmed. If this argument is zero, only\r
-  the minimum amount of memory to maintain internal data structures\r
-  will be left. Non-zero arguments can be supplied to maintain enough\r
-  trailing space to service future expected allocations without having\r
-  to re-obtain memory from the system.\r
-\r
-  Malloc_trim returns 1 if it actually released any memory, else 0.\r
-*/\r
-DLMALLOC_EXPORT int  dlmalloc_trim(size_t);\r
-\r
-/*\r
-  malloc_stats();\r
-  Prints on stderr the amount of space obtained from the system (both\r
-  via sbrk and mmap), the maximum amount (which may be more than\r
-  current if malloc_trim and/or munmap got called), and the current\r
-  number of bytes allocated via malloc (or realloc, etc) but not yet\r
-  freed. Note that this is the number of bytes allocated, not the\r
-  number requested. It will be larger than the number requested\r
-  because of alignment and bookkeeping overhead. Because it includes\r
-  alignment wastage as being in use, this figure may be greater than\r
-  zero even when no user-level chunks are allocated.\r
-\r
-  The reported current and maximum system memory can be inaccurate if\r
-  a program makes other calls to system memory allocation functions\r
-  (normally sbrk) outside of malloc.\r
-\r
-  malloc_stats prints only the most commonly interesting statistics.\r
-  More information can be obtained by calling mallinfo.\r
-*/\r
-DLMALLOC_EXPORT void  dlmalloc_stats(void);\r
-\r
-#endif /* ONLY_MSPACES */\r
-\r
-/*\r
-  malloc_usable_size(void* p);\r
-\r
-  Returns the number of bytes you can actually use in\r
-  an allocated chunk, which may be more than you requested (although\r
-  often not) due to alignment and minimum size constraints.\r
-  You can use this many bytes without worrying about\r
-  overwriting other allocated objects. This is not a particularly great\r
-  programming practice. malloc_usable_size can be more useful in\r
-  debugging and assertions, for example:\r
-\r
-  p = malloc(n);\r
-  assert(malloc_usable_size(p) >= 256);\r
-*/\r
-size_t dlmalloc_usable_size(void*);\r
-\r
-#if MSPACES\r
-\r
-/*\r
-  mspace is an opaque type representing an independent\r
-  region of space that supports mspace_malloc, etc.\r
-*/\r
-typedef void* mspace;\r
-\r
-/*\r
-  create_mspace creates and returns a new independent space with the\r
-  given initial capacity, or, if 0, the default granularity size.  It\r
-  returns null if there is no system memory available to create the\r
-  space.  If argument locked is non-zero, the space uses a separate\r
-  lock to control access. The capacity of the space will grow\r
-  dynamically as needed to service mspace_malloc requests.  You can\r
-  control the sizes of incremental increases of this space by\r
-  compiling with a different DEFAULT_GRANULARITY or dynamically\r
-  setting with mallopt(M_GRANULARITY, value).\r
-*/\r
-DLMALLOC_EXPORT mspace create_mspace(size_t capacity, int locked);\r
-\r
-/*\r
-  destroy_mspace destroys the given space, and attempts to return all\r
-  of its memory back to the system, returning the total number of\r
-  bytes freed. After destruction, the results of access to all memory\r
-  used by the space become undefined.\r
-*/\r
-DLMALLOC_EXPORT size_t destroy_mspace(mspace msp);\r
-\r
-/*\r
-  create_mspace_with_base uses the memory supplied as the initial base\r
-  of a new mspace. Part (less than 128*sizeof(size_t) bytes) of this\r
-  space is used for bookkeeping, so the capacity must be at least this\r
-  large. (Otherwise 0 is returned.) When this initial space is\r
-  exhausted, additional memory will be obtained from the system.\r
-  Destroying this space will deallocate all additionally allocated\r
-  space (if possible) but not the initial base.\r
-*/\r
-DLMALLOC_EXPORT mspace create_mspace_with_base(void* base, size_t capacity, int locked);\r
-\r
-/*\r
-  mspace_track_large_chunks controls whether requests for large chunks\r
-  are allocated in their own untracked mmapped regions, separate from\r
-  others in this mspace. By default large chunks are not tracked,\r
-  which reduces fragmentation. However, such chunks are not\r
-  necessarily released to the system upon destroy_mspace.  Enabling\r
-  tracking by setting to true may increase fragmentation, but avoids\r
-  leakage when relying on destroy_mspace to release all memory\r
-  allocated using this space.  The function returns the previous\r
-  setting.\r
-*/\r
-DLMALLOC_EXPORT int mspace_track_large_chunks(mspace msp, int enable);\r
-\r
-\r
-/*\r
-  mspace_malloc behaves as malloc, but operates within\r
-  the given space.\r
-*/\r
-DLMALLOC_EXPORT void* mspace_malloc(mspace msp, size_t bytes);\r
-\r
-/*\r
-  mspace_free behaves as free, but operates within\r
-  the given space.\r
-\r
-  If compiled with FOOTERS==1, mspace_free is not actually needed.\r
-  free may be called instead of mspace_free because freed chunks from\r
-  any space are handled by their originating spaces.\r
-*/\r
-DLMALLOC_EXPORT void mspace_free(mspace msp, void* mem);\r
-\r
-/*\r
-  mspace_realloc behaves as realloc, but operates within\r
-  the given space.\r
-\r
-  If compiled with FOOTERS==1, mspace_realloc is not actually\r
-  needed.  realloc may be called instead of mspace_realloc because\r
-  realloced chunks from any space are handled by their originating\r
-  spaces.\r
-*/\r
-DLMALLOC_EXPORT void* mspace_realloc(mspace msp, void* mem, size_t newsize);\r
-\r
-/*\r
-  mspace_calloc behaves as calloc, but operates within\r
-  the given space.\r
-*/\r
-DLMALLOC_EXPORT void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size);\r
-\r
-/*\r
-  mspace_memalign behaves as memalign, but operates within\r
-  the given space.\r
-*/\r
-DLMALLOC_EXPORT void* mspace_memalign(mspace msp, size_t alignment, size_t bytes);\r
-\r
-/*\r
-  mspace_independent_calloc behaves as independent_calloc, but\r
-  operates within the given space.\r
-*/\r
-DLMALLOC_EXPORT void** mspace_independent_calloc(mspace msp, size_t n_elements,\r
-                                 size_t elem_size, void* chunks[]);\r
-\r
-/*\r
-  mspace_independent_comalloc behaves as independent_comalloc, but\r
-  operates within the given space.\r
-*/\r
-DLMALLOC_EXPORT void** mspace_independent_comalloc(mspace msp, size_t n_elements,\r
-                                   size_t sizes[], void* chunks[]);\r
-\r
-/*\r
-  mspace_footprint() returns the number of bytes obtained from the\r
-  system for this space.\r
-*/\r
-DLMALLOC_EXPORT size_t mspace_footprint(mspace msp);\r
-\r
-/*\r
-  mspace_max_footprint() returns the peak number of bytes obtained from the\r
-  system for this space.\r
-*/\r
-DLMALLOC_EXPORT size_t mspace_max_footprint(mspace msp);\r
-\r
-\r
-#if !NO_MALLINFO\r
-/*\r
-  mspace_mallinfo behaves as mallinfo, but reports properties of\r
-  the given space.\r
-*/\r
-DLMALLOC_EXPORT struct mallinfo mspace_mallinfo(mspace msp);\r
-#endif /* NO_MALLINFO */\r
-\r
-/*\r
-  malloc_usable_size(void* p) behaves the same as malloc_usable_size;\r
-*/\r
-DLMALLOC_EXPORT size_t mspace_usable_size(void* mem);\r
-\r
-/*\r
-  mspace_malloc_stats behaves as malloc_stats, but reports\r
-  properties of the given space.\r
-*/\r
-DLMALLOC_EXPORT void mspace_malloc_stats(mspace msp);\r
-\r
-/*\r
-  mspace_trim behaves as malloc_trim, but\r
-  operates within the given space.\r
-*/\r
-DLMALLOC_EXPORT int mspace_trim(mspace msp, size_t pad);\r
-\r
-/*\r
-  An alias for mallopt.\r
-*/\r
-DLMALLOC_EXPORT int mspace_mallopt(int, int);\r
-\r
-#endif /* MSPACES */\r
-\r
-#ifdef __cplusplus\r
-}  /* end of extern "C" */\r
-#endif /* __cplusplus */\r
-\r
-/*\r
-  ========================================================================\r
-  To make a fully customizable malloc.h header file, cut everything\r
-  above this line, put into file malloc.h, edit to suit, and #include it\r
-  on the next line, as well as in programs that use this malloc.\r
-  ========================================================================\r
-*/\r
-\r
-/* #include "malloc.h" */\r
-\r
-/*------------------------------ internal #includes ---------------------- */\r
-\r
-#ifdef _MSC_VER\r
-#pragma warning( disable : 4146 ) /* no "unsigned" warnings */\r
-#endif /* _MSC_VER */\r
-#if !NO_MALLOC_STATS\r
-#include <stdio.h>       /* for printing in malloc_stats */\r
-#endif /* NO_MALLOC_STATS */\r
-#ifndef LACKS_ERRNO_H\r
-#include <errno.h>       /* for MALLOC_FAILURE_ACTION */\r
-#endif /* LACKS_ERRNO_H */\r
-#ifdef DEBUG\r
-#if ABORT_ON_ASSERT_FAILURE\r
-#undef assert\r
-#define assert(x) if(!(x)) ABORT\r
-#else /* ABORT_ON_ASSERT_FAILURE */\r
-#include <assert.h>\r
-#endif /* ABORT_ON_ASSERT_FAILURE */\r
-#else  /* DEBUG */\r
-#ifndef assert\r
-#define assert(x)\r
-#endif\r
-#define DEBUG 0\r
-#endif /* DEBUG */\r
-#if !defined(WIN32) && !defined(LACKS_TIME_H)\r
-#include <time.h>        /* for magic initialization */\r
-#endif /* WIN32 */\r
-#ifndef LACKS_STDLIB_H\r
-#include <stdlib.h>      /* for abort() */\r
-#endif /* LACKS_STDLIB_H */\r
-#ifndef LACKS_STRING_H\r
-#include <string.h>      /* for memset etc */\r
-#endif  /* LACKS_STRING_H */\r
-#if USE_BUILTIN_FFS\r
-#ifndef LACKS_STRINGS_H\r
-#include <strings.h>     /* for ffs */\r
-#endif /* LACKS_STRINGS_H */\r
-#endif /* USE_BUILTIN_FFS */\r
-#if HAVE_MMAP\r
-#ifndef LACKS_SYS_MMAN_H\r
-/* On some versions of linux, mremap decl in mman.h needs __USE_GNU set */\r
-#if (defined(linux) && !defined(__USE_GNU))\r
-#define __USE_GNU 1\r
-#include <sys/mman.h>    /* for mmap */\r
-#undef __USE_GNU\r
-#else\r
-#include <sys/mman.h>    /* for mmap */\r
-#endif /* linux */\r
-#endif /* LACKS_SYS_MMAN_H */\r
-#ifndef LACKS_FCNTL_H\r
-#include <fcntl.h>\r
-#endif /* LACKS_FCNTL_H */\r
-#endif /* HAVE_MMAP */\r
-#ifndef LACKS_UNISTD_H\r
-#include <unistd.h>     /* for sbrk, sysconf */\r
-#else /* LACKS_UNISTD_H */\r
-#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__)\r
-/*extern void*     sbrk(ptrdiff_t);*/\r
-#endif /* FreeBSD etc */\r
-#endif /* LACKS_UNISTD_H */\r
-\r
-/* Declarations for locking */\r
-#if USE_LOCKS\r
-#ifndef WIN32\r
-#if defined (__SVR4) && defined (__sun)  /* solaris */\r
-#include <thread.h>\r
-#elif !defined(LACKS_SCHED_H)\r
-#include <sched.h>\r
-#endif /* solaris or LACKS_SCHED_H */\r
-#if (defined(USE_RECURSIVE_LOCKS) && USE_RECURSIVE_LOCKS != 0) || !USE_SPIN_LOCKS\r
-/*#include <pthread.h>*/\r
-#endif /* USE_RECURSIVE_LOCKS ... */\r
-#elif defined(_MSC_VER)\r
-#ifndef _M_AMD64\r
-/* These are already defined on AMD64 builds */\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif /* __cplusplus */\r
-LONG __cdecl _InterlockedCompareExchange(LONG volatile *Dest, LONG Exchange, LONG Comp);\r
-LONG __cdecl _InterlockedExchange(LONG volatile *Target, LONG Value);\r
-#ifdef __cplusplus\r
-}\r
-#endif /* __cplusplus */\r
-#endif /* _M_AMD64 */\r
-#pragma intrinsic (_InterlockedCompareExchange)\r
-#pragma intrinsic (_InterlockedExchange)\r
-#define interlockedcompareexchange _InterlockedCompareExchange\r
-#define interlockedexchange _InterlockedExchange\r
-#elif defined(WIN32) && defined(__GNUC__)\r
-#define interlockedcompareexchange(a, b, c) __sync_val_compare_and_swap(a, c, b)\r
-#define interlockedexchange __sync_lock_test_and_set\r
-#endif /* Win32 */\r
-#endif /* USE_LOCKS */\r
-\r
-/* Declarations for bit scanning on win32 */\r
-#if defined(_MSC_VER) && _MSC_VER>=1300\r
-#ifndef BitScanForward /* Try to avoid pulling in WinNT.h */\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif /* __cplusplus */\r
-unsigned char _BitScanForward(unsigned long *index, unsigned long mask);\r
-unsigned char _BitScanReverse(unsigned long *index, unsigned long mask);\r
-#ifdef __cplusplus\r
-}\r
-#endif /* __cplusplus */\r
-\r
-#define BitScanForward _BitScanForward\r
-#define BitScanReverse _BitScanReverse\r
-#pragma intrinsic(_BitScanForward)\r
-#pragma intrinsic(_BitScanReverse)\r
-#endif /* BitScanForward */\r
-#endif /* defined(_MSC_VER) && _MSC_VER>=1300 */\r
-\r
-#ifndef WIN32\r
-#ifndef malloc_getpagesize\r
-#  ifdef _SC_PAGESIZE         /* some SVR4 systems omit an underscore */\r
-#    ifndef _SC_PAGE_SIZE\r
-#      define _SC_PAGE_SIZE _SC_PAGESIZE\r
-#    endif\r
-#  endif\r
-#  ifdef _SC_PAGE_SIZE\r
-#    define malloc_getpagesize sysconf(_SC_PAGE_SIZE)\r
-#  else\r
-#    if defined(BSD) || defined(DGUX) || defined(HAVE_GETPAGESIZE)\r
-       extern size_t getpagesize();\r
-#      define malloc_getpagesize getpagesize()\r
-#    else\r
-#      ifdef WIN32 /* use supplied emulation of getpagesize */\r
-#        define malloc_getpagesize getpagesize()\r
-#      else\r
-#        ifndef LACKS_SYS_PARAM_H\r
-#          include <sys/param.h>\r
-#        endif\r
-#        ifdef EXEC_PAGESIZE\r
-#          define malloc_getpagesize EXEC_PAGESIZE\r
-#        else\r
-#          ifdef NBPG\r
-#            ifndef CLSIZE\r
-#              define malloc_getpagesize NBPG\r
-#            else\r
-#              define malloc_getpagesize (NBPG * CLSIZE)\r
-#            endif\r
-#          else\r
-#            ifdef NBPC\r
-#              define malloc_getpagesize NBPC\r
-#            else\r
-#              ifdef PAGESIZE\r
-#                define malloc_getpagesize PAGESIZE\r
-#              else /* just guess */\r
-#                define malloc_getpagesize ((size_t)4096U)\r
-#              endif\r
-#            endif\r
-#          endif\r
-#        endif\r
-#      endif\r
-#    endif\r
-#  endif\r
-#endif\r
-#endif\r
-\r
-/* ------------------- size_t and alignment properties -------------------- */\r
-\r
-/* The byte and bit size of a size_t */\r
-#define SIZE_T_SIZE         (sizeof(size_t))\r
-#define SIZE_T_BITSIZE      (sizeof(size_t) << 3)\r
-\r
-/* Some constants coerced to size_t */\r
-/* Annoying but necessary to avoid errors on some platforms */\r
-#define SIZE_T_ZERO         ((size_t)0)\r
-#define SIZE_T_ONE          ((size_t)1)\r
-#define SIZE_T_TWO          ((size_t)2)\r
-#define SIZE_T_FOUR         ((size_t)4)\r
-#define TWO_SIZE_T_SIZES    (SIZE_T_SIZE<<1)\r
-#define FOUR_SIZE_T_SIZES   (SIZE_T_SIZE<<2)\r
-#define SIX_SIZE_T_SIZES    (FOUR_SIZE_T_SIZES+TWO_SIZE_T_SIZES)\r
-#define HALF_MAX_SIZE_T     (MAX_SIZE_T / 2U)\r
-\r
-/* The bit mask value corresponding to MALLOC_ALIGNMENT */\r
-#define CHUNK_ALIGN_MASK    (MALLOC_ALIGNMENT - SIZE_T_ONE)\r
-\r
-/* True if address a has acceptable alignment */\r
-#define is_aligned(A)       (((size_t)((A)) & (CHUNK_ALIGN_MASK)) == 0)\r
-\r
-/* the number of bytes to offset an address to align it */\r
-#define align_offset(A)\\r
- ((((size_t)(A) & CHUNK_ALIGN_MASK) == 0)? 0 :\\r
-  ((MALLOC_ALIGNMENT - ((size_t)(A) & CHUNK_ALIGN_MASK)) & CHUNK_ALIGN_MASK))\r
-\r
-/* -------------------------- MMAP preliminaries ------------------------- */\r
-\r
-/*\r
-   If HAVE_MORECORE or HAVE_MMAP are false, we just define calls and\r
-   checks to fail so compiler optimizer can delete code rather than\r
-   using so many "#if"s.\r
-*/\r
-\r
-\r
-/* MORECORE and MMAP must return MFAIL on failure */\r
-#define MFAIL                ((void*)(MAX_SIZE_T))\r
-#define CMFAIL               ((char*)(MFAIL)) /* defined for convenience */\r
-\r
-#if HAVE_MMAP\r
-\r
-#ifdef MMAP_DEFAULT\r
-#elif !defined(WIN32)\r
-#define MUNMAP_DEFAULT(a, s)  munmap((a), (s))\r
-#define MMAP_PROT            (PROT_READ|PROT_WRITE)\r
-#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)\r
-#define MAP_ANONYMOUS        MAP_ANON\r
-#endif /* MAP_ANON */\r
-#ifdef MAP_ANONYMOUS\r
-#define MMAP_FLAGS           (MAP_PRIVATE|MAP_ANONYMOUS)\r
-#define MMAP_DEFAULT(s)       mmap(0, (s), MMAP_PROT, MMAP_FLAGS, -1, 0)\r
-#else /* MAP_ANONYMOUS */\r
-/*\r
-   Nearly all versions of mmap support MAP_ANONYMOUS, so the following\r
-   is unlikely to be needed, but is supplied just in case.\r
-*/\r
-#define MMAP_FLAGS           (MAP_PRIVATE)\r
-#define MMAP_DEFAULT(s) ((dev_zero_fd < 0) ? \\r
-           (dev_zero_fd = open("/dev/zero", O_RDWR), \\r
-            mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0)) : \\r
-            mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0))\r
-#endif /* MAP_ANONYMOUS */\r
-\r
-#define DIRECT_MMAP_DEFAULT(s) MMAP_DEFAULT(s)\r
-\r
-#else /* WIN32 */\r
-\r
-/* Win32 MMAP via VirtualAlloc */\r
-static FORCEINLINE void* win32mmap(size_t size) {\r
-  void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);\r
-  return (ptr != 0)? ptr: MFAIL;\r
-}\r
-\r
-/* For direct MMAP, use MEM_TOP_DOWN to minimize interference */\r
-static FORCEINLINE void* win32direct_mmap(size_t size) {\r
-  void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN,\r
-                           PAGE_READWRITE);\r
-  return (ptr != 0)? ptr: MFAIL;\r
-}\r
-\r
-/* This function supports releasing coalesed segments */\r
-static FORCEINLINE int win32munmap(void* ptr, size_t size) {\r
-  MEMORY_BASIC_INFORMATION minfo;\r
-  char* cptr = (char*)ptr;\r
-  while (size) {\r
-    if (VirtualQuery(cptr, &minfo, sizeof(minfo)) == 0)\r
-      return -1;\r
-    if (minfo.BaseAddress != cptr || minfo.AllocationBase != cptr ||\r
-        minfo.State != MEM_COMMIT || minfo.RegionSize > size)\r
-      return -1;\r
-    if (VirtualFree(cptr, 0, MEM_RELEASE) == 0)\r
-      return -1;\r
-    cptr += minfo.RegionSize;\r
-    size -= minfo.RegionSize;\r
-  }\r
-  return 0;\r
-}\r
-\r
-#define MMAP_DEFAULT(s)             win32mmap(s)\r
-#define MUNMAP_DEFAULT(a, s)        win32munmap((a), (s))\r
-#define DIRECT_MMAP_DEFAULT(s)      win32direct_mmap(s)\r
-#endif /* WIN32 */\r
-#endif /* HAVE_MMAP */\r
-\r
-#if HAVE_MREMAP && !defined(MREMAP_DEFAULT)\r
-#ifndef WIN32\r
-#define MREMAP_DEFAULT(addr, osz, nsz, mv) mremap((addr), (osz), (nsz), (mv))\r
-#endif /* WIN32 */\r
-#endif /* HAVE_MREMAP */\r
-\r
-/**\r
- * Define CALL_MORECORE\r
- */\r
-#if HAVE_MORECORE\r
-    #ifdef MORECORE\r
-        #define CALL_MORECORE(S)    MORECORE(S)\r
-    #else  /* MORECORE */\r
-        #define CALL_MORECORE(S)    MORECORE_DEFAULT(S)\r
-    #endif /* MORECORE */\r
-#else  /* HAVE_MORECORE */\r
-    #define CALL_MORECORE(S)        MFAIL\r
-#endif /* HAVE_MORECORE */\r
-\r
-/**\r
- * Define CALL_MMAP/CALL_MUNMAP/CALL_DIRECT_MMAP\r
- */\r
-#if HAVE_MMAP\r
-    #define USE_MMAP_BIT            (SIZE_T_ONE)\r
-\r
-    #ifdef MMAP\r
-        #define CALL_MMAP(s)        MMAP(s)\r
-    #else /* MMAP */\r
-        #define CALL_MMAP(s)        MMAP_DEFAULT(s)\r
-    #endif /* MMAP */\r
-    #ifdef MUNMAP\r
-        #define CALL_MUNMAP(a, s)   MUNMAP((a), (s))\r
-    #else /* MUNMAP */\r
-        #define CALL_MUNMAP(a, s)   MUNMAP_DEFAULT((a), (s))\r
-    #endif /* MUNMAP */\r
-    #ifdef DIRECT_MMAP\r
-        #define CALL_DIRECT_MMAP(s) DIRECT_MMAP(s)\r
-    #else /* DIRECT_MMAP */\r
-        #define CALL_DIRECT_MMAP(s) DIRECT_MMAP_DEFAULT(s)\r
-    #endif /* DIRECT_MMAP */\r
-#else  /* HAVE_MMAP */\r
-    #define USE_MMAP_BIT            (SIZE_T_ZERO)\r
-\r
-    #define MMAP(s)                 MFAIL\r
-    #define MUNMAP(a, s)            (-1)\r
-    #define DIRECT_MMAP(s)          MFAIL\r
-    #define CALL_DIRECT_MMAP(s)     DIRECT_MMAP(s)\r
-    #define CALL_MMAP(s)            MMAP(s)\r
-    #define CALL_MUNMAP(a, s)       MUNMAP((a), (s))\r
-#endif /* HAVE_MMAP */\r
-\r
-/**\r
- * Define CALL_MREMAP\r
- */\r
-#if HAVE_MMAP && HAVE_MREMAP\r
-    #ifdef MREMAP\r
-        #define CALL_MREMAP(addr, osz, nsz, mv) MREMAP((addr), (osz), (nsz), (mv))\r
-    #else /* MREMAP */\r
-        #define CALL_MREMAP(addr, osz, nsz, mv) MREMAP_DEFAULT((addr), (osz), (nsz), (mv))\r
-    #endif /* MREMAP */\r
-#else  /* HAVE_MMAP && HAVE_MREMAP */\r
-    #define CALL_MREMAP(addr, osz, nsz, mv)     MFAIL\r
-#endif /* HAVE_MMAP && HAVE_MREMAP */\r
-\r
-/* mstate bit set if continguous morecore disabled or failed */\r
-#define USE_NONCONTIGUOUS_BIT (4U)\r
-\r
-/* segment bit set in create_mspace_with_base */\r
-#define EXTERN_BIT            (8U)\r
-\r
-\r
-/* --------------------------- Lock preliminaries ------------------------ */\r
-\r
-/*\r
-  When locks are defined, there is one global lock, plus\r
-  one per-mspace lock.\r
-\r
-  The global lock_ensures that mparams.magic and other unique\r
-  mparams values are initialized only once. It also protects\r
-  sequences of calls to MORECORE.  In many cases sys_alloc requires\r
-  two calls, that should not be interleaved with calls by other\r
-  threads.  This does not protect against direct calls to MORECORE\r
-  by other threads not using this lock, so there is still code to\r
-  cope the best we can on interference.\r
-\r
-  Per-mspace locks surround calls to malloc, free, etc.\r
-  By default, locks are simple non-reentrant mutexes.\r
-\r
-  Because lock-protected regions generally have bounded times, it is\r
-  OK to use the supplied simple spinlocks. Spinlocks are likely to\r
-  improve performance for lightly contended applications, but worsen\r
-  performance under heavy contention.\r
-\r
-  If USE_LOCKS is > 1, the definitions of lock routines here are\r
-  bypassed, in which case you will need to define the type MLOCK_T,\r
-  and at least INITIAL_LOCK, DESTROY_LOCK, ACQUIRE_LOCK, RELEASE_LOCK\r
-  and TRY_LOCK.  You must also declare a\r
-    static MLOCK_T malloc_global_mutex = { initialization values };.\r
-\r
-*/\r
-\r
-#if !USE_LOCKS\r
-#define USE_LOCK_BIT               (0U)\r
-#define INITIAL_LOCK(l)            (0)\r
-#define DESTROY_LOCK(l)            (0)\r
-#define ACQUIRE_MALLOC_GLOBAL_LOCK()\r
-#define RELEASE_MALLOC_GLOBAL_LOCK()\r
-\r
-#else\r
-#if USE_LOCKS > 1\r
-/* -----------------------  User-defined locks ------------------------ */\r
-/* Define your own lock implementation here */\r
-/* #define INITIAL_LOCK(lk)  ... */\r
-/* #define DESTROY_LOCK(lk)  ... */\r
-/* #define ACQUIRE_LOCK(lk)  ... */\r
-/* #define RELEASE_LOCK(lk)  ... */\r
-/* #define TRY_LOCK(lk) ... */\r
-/* static MLOCK_T malloc_global_mutex = ... */\r
-\r
-#elif USE_SPIN_LOCKS\r
-\r
-/* First, define CAS_LOCK and CLEAR_LOCK on ints */\r
-/* Note CAS_LOCK defined to return 0 on success */\r
-\r
-#if defined(__GNUC__)&& (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1))\r
-#define CAS_LOCK(sl)     __sync_lock_test_and_set(sl, 1)\r
-#define CLEAR_LOCK(sl)   __sync_lock_release(sl)\r
-\r
-#elif (defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)))\r
-/* Custom spin locks for older gcc on x86 */\r
-static FORCEINLINE int x86_cas_lock(int *sl) {\r
-  int ret;\r
-  int val = 1;\r
-  int cmp = 0;\r
-  __asm__ __volatile__  ("lock; cmpxchgl %1, %2"\r
-                         : "=a" (ret)\r
-                         : "r" (val), "m" (*(sl)), "0"(cmp)\r
-                         : "memory", "cc");\r
-  return ret;\r
-}\r
-\r
-static FORCEINLINE void x86_clear_lock(int* sl) {\r
-  assert(*sl != 0);\r
-  int prev = 0;\r
-  int ret;\r
-  __asm__ __volatile__ ("lock; xchgl %0, %1"\r
-                        : "=r" (ret)\r
-                        : "m" (*(sl)), "0"(prev)\r
-                        : "memory");\r
-}\r
-\r
-#define CAS_LOCK(sl)     x86_cas_lock(sl)\r
-#define CLEAR_LOCK(sl)   x86_clear_lock(sl)\r
-\r
-#else /* Win32 MSC */\r
-#define CAS_LOCK(sl)     interlockedexchange(sl, 1)\r
-#define CLEAR_LOCK(sl)   interlockedexchange (sl, 0)\r
-\r
-#endif /* ... gcc spins locks ... */\r
-\r
-/* How to yield for a spin lock */\r
-#define SPINS_PER_YIELD       63\r
-#if defined(_MSC_VER)\r
-#define SLEEP_EX_DURATION     50 /* delay for yield/sleep */\r
-#define SPIN_LOCK_YIELD  SleepEx(SLEEP_EX_DURATION, FALSE)\r
-#elif defined (__SVR4) && defined (__sun) /* solaris */\r
-#define SPIN_LOCK_YIELD   thr_yield();\r
-#elif !defined(LACKS_SCHED_H)\r
-#define SPIN_LOCK_YIELD   sched_yield();\r
-#else\r
-#define SPIN_LOCK_YIELD\r
-#endif /* ... yield ... */\r
-\r
-#if !defined(USE_RECURSIVE_LOCKS) || USE_RECURSIVE_LOCKS == 0\r
-/* Plain spin locks use single word (embedded in malloc_states) */\r
-static int spin_acquire_lock(int *sl) {\r
-  int spins = 0;\r
-  while (*(volatile int *)sl != 0 || CAS_LOCK(sl)) {\r
-    if ((++spins & SPINS_PER_YIELD) == 0) {\r
-      SPIN_LOCK_YIELD;\r
-    }\r
-  }\r
-  return 0;\r
-}\r
-\r
-#define MLOCK_T               int\r
-#define TRY_LOCK(sl)          !CAS_LOCK(sl)\r
-#define RELEASE_LOCK(sl)      CLEAR_LOCK(sl)\r
-#define ACQUIRE_LOCK(sl)      (CAS_LOCK(sl)? spin_acquire_lock(sl) : 0)\r
-#define INITIAL_LOCK(sl)      (*sl = 0)\r
-#define DESTROY_LOCK(sl)      (0)\r
-static MLOCK_T malloc_global_mutex = 0;\r
-\r
-#else /* USE_RECURSIVE_LOCKS */\r
-/* types for lock owners */\r
-#ifdef WIN32\r
-#define THREAD_ID_T           DWORD\r
-#define CURRENT_THREAD        GetCurrentThreadId()\r
-#define EQ_OWNER(X,Y)         ((X) == (Y))\r
-#else\r
-/*\r
-  Note: the following assume that pthread_t is a type that can be\r
-  initialized to (casted) zero. If this is not the case, you will need to\r
-  somehow redefine these or not use spin locks.\r
-*/\r
-#define THREAD_ID_T           pthread_t\r
-#define CURRENT_THREAD        pthread_self()\r
-#define EQ_OWNER(X,Y)         pthread_equal(X, Y)\r
-#endif\r
-\r
-struct malloc_recursive_lock {\r
-  int sl;\r
-  unsigned int c;\r
-  THREAD_ID_T threadid;\r
-};\r
-\r
-#define MLOCK_T  struct malloc_recursive_lock\r
-static MLOCK_T malloc_global_mutex = { 0, 0, (THREAD_ID_T)0};\r
-\r
-static FORCEINLINE void recursive_release_lock(MLOCK_T *lk) {\r
-  assert(lk->sl != 0);\r
-  if (--lk->c == 0) {\r
-    CLEAR_LOCK(&lk->sl);\r
-  }\r
-}\r
-\r
-static FORCEINLINE int recursive_acquire_lock(MLOCK_T *lk) {\r
-  THREAD_ID_T mythreadid = CURRENT_THREAD;\r
-  int spins = 0;\r
-  for (;;) {\r
-    if (*((volatile int *)(&lk->sl)) == 0) {\r
-      if (!CAS_LOCK(&lk->sl)) {\r
-        lk->threadid = mythreadid;\r
-        lk->c = 1;\r
-        return 0;\r
-      }\r
-    }\r
-    else if (EQ_OWNER(lk->threadid, mythreadid)) {\r
-      ++lk->c;\r
-      return 0;\r
-    }\r
-    if ((++spins & SPINS_PER_YIELD) == 0) {\r
-      SPIN_LOCK_YIELD;\r
-    }\r
-  }\r
-}\r
-\r
-static FORCEINLINE int recursive_try_lock(MLOCK_T *lk) {\r
-  THREAD_ID_T mythreadid = CURRENT_THREAD;\r
-  if (*((volatile int *)(&lk->sl)) == 0) {\r
-    if (!CAS_LOCK(&lk->sl)) {\r
-      lk->threadid = mythreadid;\r
-      lk->c = 1;\r
-      return 1;\r
-    }\r
-  }\r
-  else if (EQ_OWNER(lk->threadid, mythreadid)) {\r
-    ++lk->c;\r
-    return 1;\r
-  }\r
-  return 0;\r
-}\r
-\r
-#define RELEASE_LOCK(lk)      recursive_release_lock(lk)\r
-#define TRY_LOCK(lk)          recursive_try_lock(lk)\r
-#define ACQUIRE_LOCK(lk)      recursive_acquire_lock(lk)\r
-#define INITIAL_LOCK(lk)      ((lk)->threadid = (THREAD_ID_T)0, (lk)->sl = 0, (lk)->c = 0)\r
-#define DESTROY_LOCK(lk)      (0)\r
-#endif /* USE_RECURSIVE_LOCKS */\r
-\r
-#elif defined(WIN32) /* Win32 critical sections */\r
-#define MLOCK_T               CRITICAL_SECTION\r
-#define ACQUIRE_LOCK(lk)      (EnterCriticalSection(lk), 0)\r
-#define RELEASE_LOCK(lk)      LeaveCriticalSection(lk)\r
-#define TRY_LOCK(lk)          TryEnterCriticalSection(lk)\r
-#define INITIAL_LOCK(lk)      (!InitializeCriticalSectionAndSpinCount((lk), 0x80000000|4000))\r
-#define DESTROY_LOCK(lk)      (DeleteCriticalSection(lk), 0)\r
-#define NEED_GLOBAL_LOCK_INIT\r
-\r
-static MLOCK_T malloc_global_mutex;\r
-static volatile long malloc_global_mutex_status;\r
-\r
-/* Use spin loop to initialize global lock */\r
-static void init_malloc_global_mutex() {\r
-  for (;;) {\r
-    long stat = malloc_global_mutex_status;\r
-    if (stat > 0)\r
-      return;\r
-    /* transition to < 0 while initializing, then to > 0) */\r
-    if (stat == 0 &&\r
-        interlockedcompareexchange(&malloc_global_mutex_status, -1, 0) == 0) {\r
-      InitializeCriticalSection(&malloc_global_mutex);\r
-      interlockedexchange(&malloc_global_mutex_status,1);\r
-      return;\r
-    }\r
-    SleepEx(0, FALSE);\r
-  }\r
-}\r
-\r
-#else /* pthreads-based locks */\r
-#define MLOCK_T               pthread_mutex_t\r
-#define ACQUIRE_LOCK(lk)      pthread_mutex_lock(lk)\r
-#define RELEASE_LOCK(lk)      pthread_mutex_unlock(lk)\r
-#define TRY_LOCK(lk)          (!pthread_mutex_trylock(lk))\r
-#define INITIAL_LOCK(lk)      pthread_init_lock(lk)\r
-#define DESTROY_LOCK(lk)      pthread_mutex_destroy(lk)\r
-\r
-#if defined(USE_RECURSIVE_LOCKS) && USE_RECURSIVE_LOCKS != 0 && defined(linux) && !defined(PTHREAD_MUTEX_RECURSIVE)\r
-/* Cope with old-style linux recursive lock initialization by adding */\r
-/* skipped internal declaration from pthread.h */\r
-extern int pthread_mutexattr_setkind_np __P ((pthread_mutexattr_t *__attr,\r
-                                          int __kind));\r
-#define PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP\r
-#define pthread_mutexattr_settype(x,y) pthread_mutexattr_setkind_np(x,y)\r
-#endif /* USE_RECURSIVE_LOCKS ... */\r
-\r
-static MLOCK_T malloc_global_mutex = PTHREAD_MUTEX_INITIALIZER;\r
-\r
-static int pthread_init_lock (MLOCK_T *lk) {\r
-  pthread_mutexattr_t attr;\r
-  if (pthread_mutexattr_init(&attr)) return 1;\r
-#if defined(USE_RECURSIVE_LOCKS) && USE_RECURSIVE_LOCKS != 0\r
-  if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)) return 1;\r
-#endif\r
-  if (pthread_mutex_init(lk, &attr)) return 1;\r
-  if (pthread_mutexattr_destroy(&attr)) return 1;\r
-  return 0;\r
-}\r
-\r
-#endif /* ... lock types ... */\r
-\r
-/* Common code for all lock types */\r
-#define USE_LOCK_BIT               (2U)\r
-\r
-#ifndef ACQUIRE_MALLOC_GLOBAL_LOCK\r
-#define ACQUIRE_MALLOC_GLOBAL_LOCK()  ACQUIRE_LOCK(&malloc_global_mutex);\r
-#endif\r
-\r
-#ifndef RELEASE_MALLOC_GLOBAL_LOCK\r
-#define RELEASE_MALLOC_GLOBAL_LOCK()  RELEASE_LOCK(&malloc_global_mutex);\r
-#endif\r
-\r
-#endif /* USE_LOCKS */\r
-\r
-/* -----------------------  Chunk representations ------------------------ */\r
-\r
-/*\r
-  (The following includes lightly edited explanations by Colin Plumb.)\r
-\r
-  The malloc_chunk declaration below is misleading (but accurate and\r
-  necessary).  It declares a "view" into memory allowing access to\r
-  necessary fields at known offsets from a given base.\r
-\r
-  Chunks of memory are maintained using a `boundary tag' method as\r
-  originally described by Knuth.  (See the paper by Paul Wilson\r
-  ftp://ftp.cs.utexas.edu/pub/garbage/allocsrv.ps for a survey of such\r
-  techniques.)  Sizes of free chunks are stored both in the front of\r
-  each chunk and at the end.  This makes consolidating fragmented\r
-  chunks into bigger chunks fast.  The head fields also hold bits\r
-  representing whether chunks are free or in use.\r
-\r
-  Here are some pictures to make it clearer.  They are "exploded" to\r
-  show that the state of a chunk can be thought of as extending from\r
-  the high 31 bits of the head field of its header through the\r
-  prev_foot and PINUSE_BIT bit of the following chunk header.\r
-\r
-  A chunk that's in use looks like:\r
-\r
-   chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-           | Size of previous chunk (if P = 0)                             |\r
-           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P|\r
-         | Size of this chunk                                         1| +-+\r
-   mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-         |                                                               |\r
-         +-                                                             -+\r
-         |                                                               |\r
-         +-                                                             -+\r
-         |                                                               :\r
-         +-      size - sizeof(size_t) available payload bytes          -+\r
-         :                                                               |\r
- chunk-> +-                                                             -+\r
-         |                                                               |\r
-         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |1|\r
-       | Size of next chunk (may or may not be in use)               | +-+\r
- mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-\r
-    And if it's free, it looks like this:\r
-\r
-   chunk-> +-                                                             -+\r
-           | User payload (must be in use, or we would have merged!)       |\r
-           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P|\r
-         | Size of this chunk                                         0| +-+\r
-   mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-         | Next pointer                                                  |\r
-         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-         | Prev pointer                                                  |\r
-         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-         |                                                               :\r
-         +-      size - sizeof(struct chunk) unused bytes               -+\r
-         :                                                               |\r
- chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-         | Size of this chunk                                            |\r
-         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |0|\r
-       | Size of next chunk (must be in use, or we would have merged)| +-+\r
- mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-       |                                                               :\r
-       +- User payload                                                -+\r
-       :                                                               |\r
-       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-                                                                     |0|\r
-                                                                     +-+\r
-  Note that since we always merge adjacent free chunks, the chunks\r
-  adjacent to a free chunk must be in use.\r
-\r
-  Given a pointer to a chunk (which can be derived trivially from the\r
-  payload pointer) we can, in O(1) time, find out whether the adjacent\r
-  chunks are free, and if so, unlink them from the lists that they\r
-  are on and merge them with the current chunk.\r
-\r
-  Chunks always begin on even word boundaries, so the mem portion\r
-  (which is returned to the user) is also on an even word boundary, and\r
-  thus at least double-word aligned.\r
-\r
-  The P (PINUSE_BIT) bit, stored in the unused low-order bit of the\r
-  chunk size (which is always a multiple of two words), is an in-use\r
-  bit for the *previous* chunk.  If that bit is *clear*, then the\r
-  word before the current chunk size contains the previous chunk\r
-  size, and can be used to find the front of the previous chunk.\r
-  The very first chunk allocated always has this bit set, preventing\r
-  access to non-existent (or non-owned) memory. If pinuse is set for\r
-  any given chunk, then you CANNOT determine the size of the\r
-  previous chunk, and might even get a memory addressing fault when\r
-  trying to do so.\r
-\r
-  The C (CINUSE_BIT) bit, stored in the unused second-lowest bit of\r
-  the chunk size redundantly records whether the current chunk is\r
-  inuse (unless the chunk is mmapped). This redundancy enables usage\r
-  checks within free and realloc, and reduces indirection when freeing\r
-  and consolidating chunks.\r
-\r
-  Each freshly allocated chunk must have both cinuse and pinuse set.\r
-  That is, each allocated chunk borders either a previously allocated\r
-  and still in-use chunk, or the base of its memory arena. This is\r
-  ensured by making all allocations from the `lowest' part of any\r
-  found chunk.  Further, no free chunk physically borders another one,\r
-  so each free chunk is known to be preceded and followed by either\r
-  inuse chunks or the ends of memory.\r
-\r
-  Note that the `foot' of the current chunk is actually represented\r
-  as the prev_foot of the NEXT chunk. This makes it easier to\r
-  deal with alignments etc but can be very confusing when trying\r
-  to extend or adapt this code.\r
-\r
-  The exceptions to all this are\r
-\r
-     1. The special chunk `top' is the top-most available chunk (i.e.,\r
-        the one bordering the end of available memory). It is treated\r
-        specially.  Top is never included in any bin, is used only if\r
-        no other chunk is available, and is released back to the\r
-        system if it is very large (see M_TRIM_THRESHOLD).  In effect,\r
-        the top chunk is treated as larger (and thus less well\r
-        fitting) than any other available chunk.  The top chunk\r
-        doesn't update its trailing size field since there is no next\r
-        contiguous chunk that would have to index off it. However,\r
-        space is still allocated for it (TOP_FOOT_SIZE) to enable\r
-        separation or merging when space is extended.\r
-\r
-     3. Chunks allocated via mmap, have both cinuse and pinuse bits\r
-        cleared in their head fields.  Because they are allocated\r
-        one-by-one, each must carry its own prev_foot field, which is\r
-        also used to hold the offset this chunk has within its mmapped\r
-        region, which is needed to preserve alignment. Each mmapped\r
-        chunk is trailed by the first two fields of a fake next-chunk\r
-        for sake of usage checks.\r
-\r
-*/\r
-\r
-struct malloc_chunk {\r
-  size_t               prev_foot;  /* Size of previous chunk (if free).  */\r
-  size_t               head;       /* Size and inuse bits. */\r
-  struct malloc_chunk* fd;         /* double links -- used only if free. */\r
-  struct malloc_chunk* bk;\r
-};\r
-\r
-typedef struct malloc_chunk  mchunk;\r
-typedef struct malloc_chunk* mchunkptr;\r
-typedef struct malloc_chunk* sbinptr;  /* The type of bins of chunks */\r
-typedef unsigned int bindex_t;         /* Described below */\r
-typedef unsigned int binmap_t;         /* Described below */\r
-typedef unsigned int flag_t;           /* The type of various bit flag sets */\r
-\r
-/* ------------------- Chunks sizes and alignments ----------------------- */\r
-\r
-#define MCHUNK_SIZE         (sizeof(mchunk))\r
-\r
-#if FOOTERS\r
-#define CHUNK_OVERHEAD      (TWO_SIZE_T_SIZES)\r
-#else /* FOOTERS */\r
-#define CHUNK_OVERHEAD      (SIZE_T_SIZE)\r
-#endif /* FOOTERS */\r
-\r
-/* MMapped chunks need a second word of overhead ... */\r
-#define MMAP_CHUNK_OVERHEAD (TWO_SIZE_T_SIZES)\r
-/* ... and additional padding for fake next-chunk at foot */\r
-#define MMAP_FOOT_PAD       (FOUR_SIZE_T_SIZES)\r
-\r
-/* The smallest size we can malloc is an aligned minimal chunk */\r
-#define MIN_CHUNK_SIZE\\r
-  ((MCHUNK_SIZE + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK)\r
-\r
-/* conversion from malloc headers to user pointers, and back */\r
-#define chunk2mem(p)        ((void*)((char*)(p)       + TWO_SIZE_T_SIZES))\r
-#define mem2chunk(mem)      ((mchunkptr)((char*)(mem) - TWO_SIZE_T_SIZES))\r
-/* chunk associated with aligned address A */\r
-#define align_as_chunk(A)   (mchunkptr)((A) + align_offset(chunk2mem(A)))\r
-\r
-/* Bounds on request (not chunk) sizes. */\r
-#define MAX_REQUEST         ((-MIN_CHUNK_SIZE) << 2)\r
-#define MIN_REQUEST         (MIN_CHUNK_SIZE - CHUNK_OVERHEAD - SIZE_T_ONE)\r
-\r
-/* pad request bytes into a usable size */\r
-#define pad_request(req) \\r
-   (((req) + CHUNK_OVERHEAD + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK)\r
-\r
-/* pad request, checking for minimum (but not maximum) */\r
-#define request2size(req) \\r
-  (((req) < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(req))\r
-\r
-\r
-/* ------------------ Operations on head and foot fields ----------------- */\r
-\r
-/*\r
-  The head field of a chunk is or'ed with PINUSE_BIT when previous\r
-  adjacent chunk in use, and or'ed with CINUSE_BIT if this chunk is in\r
-  use, unless mmapped, in which case both bits are cleared.\r
-\r
-  FLAG4_BIT is not used by this malloc, but might be useful in extensions.\r
-*/\r
-\r
-#define PINUSE_BIT          (SIZE_T_ONE)\r
-#define CINUSE_BIT          (SIZE_T_TWO)\r
-#define FLAG4_BIT           (SIZE_T_FOUR)\r
-#define INUSE_BITS          (PINUSE_BIT|CINUSE_BIT)\r
-#define FLAG_BITS           (PINUSE_BIT|CINUSE_BIT|FLAG4_BIT)\r
-\r
-/* Head value for fenceposts */\r
-#define FENCEPOST_HEAD      (INUSE_BITS|SIZE_T_SIZE)\r
-\r
-/* extraction of fields from head words */\r
-#define cinuse(p)           ((p)->head & CINUSE_BIT)\r
-#define pinuse(p)           ((p)->head & PINUSE_BIT)\r
-#define flag4inuse(p)       ((p)->head & FLAG4_BIT)\r
-#define is_inuse(p)         (((p)->head & INUSE_BITS) != PINUSE_BIT)\r
-#define is_mmapped(p)       (((p)->head & INUSE_BITS) == 0)\r
-\r
-#define chunksize(p)        ((p)->head & ~(FLAG_BITS))\r
-\r
-#define clear_pinuse(p)     ((p)->head &= ~PINUSE_BIT)\r
-#define set_flag4(p)        ((p)->head |= FLAG4_BIT)\r
-#define clear_flag4(p)      ((p)->head &= ~FLAG4_BIT)\r
-\r
-/* Treat space at ptr +/- offset as a chunk */\r
-#define chunk_plus_offset(p, s)  ((mchunkptr)(((char*)(p)) + (s)))\r
-#define chunk_minus_offset(p, s) ((mchunkptr)(((char*)(p)) - (s)))\r
-\r
-/* Ptr to next or previous physical malloc_chunk. */\r
-#define next_chunk(p) ((mchunkptr)( ((char*)(p)) + ((p)->head & ~FLAG_BITS)))\r
-#define prev_chunk(p) ((mchunkptr)( ((char*)(p)) - ((p)->prev_foot) ))\r
-\r
-/* extract next chunk's pinuse bit */\r
-#define next_pinuse(p)  ((next_chunk(p)->head) & PINUSE_BIT)\r
-\r
-/* Get/set size at footer */\r
-#define get_foot(p, s)  (((mchunkptr)((char*)(p) + (s)))->prev_foot)\r
-#define set_foot(p, s)  (((mchunkptr)((char*)(p) + (s)))->prev_foot = (s))\r
-\r
-/* Set size, pinuse bit, and foot */\r
-#define set_size_and_pinuse_of_free_chunk(p, s)\\r
-  ((p)->head = (s|PINUSE_BIT), set_foot(p, s))\r
-\r
-/* Set size, pinuse bit, foot, and clear next pinuse */\r
-#define set_free_with_pinuse(p, s, n)\\r
-  (clear_pinuse(n), set_size_and_pinuse_of_free_chunk(p, s))\r
-\r
-/* Get the internal overhead associated with chunk p */\r
-#define overhead_for(p)\\r
- (is_mmapped(p)? MMAP_CHUNK_OVERHEAD : CHUNK_OVERHEAD)\r
-\r
-/* Return true if malloced space is not necessarily cleared */\r
-#if MMAP_CLEARS\r
-#define calloc_must_clear(p) (!is_mmapped(p))\r
-#else /* MMAP_CLEARS */\r
-#define calloc_must_clear(p) (1)\r
-#endif /* MMAP_CLEARS */\r
-\r
-/* ---------------------- Overlaid data structures ----------------------- */\r
-\r
-/*\r
-  When chunks are not in use, they are treated as nodes of either\r
-  lists or trees.\r
-\r
-  "Small"  chunks are stored in circular doubly-linked lists, and look\r
-  like this:\r
-\r
-    chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-            |             Size of previous chunk                            |\r
-            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-    `head:' |             Size of chunk, in bytes                         |P|\r
-      mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-            |             Forward pointer to next chunk in list             |\r
-            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-            |             Back pointer to previous chunk in list            |\r
-            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-            |             Unused space (may be 0 bytes long)                .\r
-            .                                                               .\r
-            .                                                               |\r
-nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-    `foot:' |             Size of chunk, in bytes                           |\r
-            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-\r
-  Larger chunks are kept in a form of bitwise digital trees (aka\r
-  tries) keyed on chunksizes.  Because malloc_tree_chunks are only for\r
-  free chunks greater than 256 bytes, their size doesn't impose any\r
-  constraints on user chunk sizes.  Each node looks like:\r
-\r
-    chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-            |             Size of previous chunk                            |\r
-            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-    `head:' |             Size of chunk, in bytes                         |P|\r
-      mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-            |             Forward pointer to next chunk of same size        |\r
-            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-            |             Back pointer to previous chunk of same size       |\r
-            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-            |             Pointer to left child (child[0])                  |\r
-            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-            |             Pointer to right child (child[1])                 |\r
-            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-            |             Pointer to parent                                 |\r
-            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-            |             bin index of this chunk                           |\r
-            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-            |             Unused space                                      .\r
-            .                                                               |\r
-nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-    `foot:' |             Size of chunk, in bytes                           |\r
-            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
-\r
-  Each tree holding treenodes is a tree of unique chunk sizes.  Chunks\r
-  of the same size are arranged in a circularly-linked list, with only\r
-  the oldest chunk (the next to be used, in our FIFO ordering)\r
-  actually in the tree.  (Tree members are distinguished by a non-null\r
-  parent pointer.)  If a chunk with the same size an an existing node\r
-  is inserted, it is linked off the existing node using pointers that\r
-  work in the same way as fd/bk pointers of small chunks.\r
-\r
-  Each tree contains a power of 2 sized range of chunk sizes (the\r
-  smallest is 0x100 <= x < 0x180), which is is divided in half at each\r
-  tree level, with the chunks in the smaller half of the range (0x100\r
-  <= x < 0x140 for the top nose) in the left subtree and the larger\r
-  half (0x140 <= x < 0x180) in the right subtree.  This is, of course,\r
-  done by inspecting individual bits.\r
-\r
-  Using these rules, each node's left subtree contains all smaller\r
-  sizes than its right subtree.  However, the node at the root of each\r
-  subtree has no particular ordering relationship to either.  (The\r
-  dividing line between the subtree sizes is based on trie relation.)\r
-  If we remove the last chunk of a given size from the interior of the\r
-  tree, we need to replace it with a leaf node.  The tree ordering\r
-  rules permit a node to be replaced by any leaf below it.\r
-\r
-  The smallest chunk in a tree (a common operation in a best-fit\r
-  allocator) can be found by walking a path to the leftmost leaf in\r
-  the tree.  Unlike a usual binary tree, where we follow left child\r
-  pointers until we reach a null, here we follow the right child\r
-  pointer any time the left one is null, until we reach a leaf with\r
-  both child pointers null. The smallest chunk in the tree will be\r
-  somewhere along that path.\r
-\r
-  The worst case number of steps to add, find, or remove a node is\r
-  bounded by the number of bits differentiating chunks within\r
-  bins. Under current bin calculations, this ranges from 6 up to 21\r
-  (for 32 bit sizes) or up to 53 (for 64 bit sizes). The typical case\r
-  is of course much better.\r
-*/\r
-\r
-struct malloc_tree_chunk {\r
-  /* The first four fields must be compatible with malloc_chunk */\r
-  size_t                    prev_foot;\r
-  size_t                    head;\r
-  struct malloc_tree_chunk* fd;\r
-  struct malloc_tree_chunk* bk;\r
-\r
-  struct malloc_tree_chunk* child[2];\r
-  struct malloc_tree_chunk* parent;\r
-  bindex_t                  index;\r
-};\r
-\r
-typedef struct malloc_tree_chunk  tchunk;\r
-typedef struct malloc_tree_chunk* tchunkptr;\r
-typedef struct malloc_tree_chunk* tbinptr; /* The type of bins of trees */\r
-\r
-/* A little helper macro for trees */\r
-#define leftmost_child(t) ((t)->child[0] != 0? (t)->child[0] : (t)->child[1])\r
-\r
-/* ----------------------------- Segments -------------------------------- */\r
-\r
-/*\r
-  Each malloc space may include non-contiguous segments, held in a\r
-  list headed by an embedded malloc_segment record representing the\r
-  top-most space. Segments also include flags holding properties of\r
-  the space. Large chunks that are directly allocated by mmap are not\r
-  included in this list. They are instead independently created and\r
-  destroyed without otherwise keeping track of them.\r
-\r
-  Segment management mainly comes into play for spaces allocated by\r
-  MMAP.  Any call to MMAP might or might not return memory that is\r
-  adjacent to an existing segment.  MORECORE normally contiguously\r
-  extends the current space, so this space is almost always adjacent,\r
-  which is simpler and faster to deal with. (This is why MORECORE is\r
-  used preferentially to MMAP when both are available -- see\r
-  sys_alloc.)  When allocating using MMAP, we don't use any of the\r
-  hinting mechanisms (inconsistently) supported in various\r
-  implementations of unix mmap, or distinguish reserving from\r
-  committing memory. Instead, we just ask for space, and exploit\r
-  contiguity when we get it.  It is probably possible to do\r
-  better than this on some systems, but no general scheme seems\r
-  to be significantly better.\r
-\r
-  Management entails a simpler variant of the consolidation scheme\r
-  used for chunks to reduce fragmentation -- new adjacent memory is\r
-  normally prepended or appended to an existing segment. However,\r
-  there are limitations compared to chunk consolidation that mostly\r
-  reflect the fact that segment processing is relatively infrequent\r
-  (occurring only when getting memory from system) and that we\r
-  don't expect to have huge numbers of segments:\r
-\r
-  * Segments are not indexed, so traversal requires linear scans.  (It\r
-    would be possible to index these, but is not worth the extra\r
-    overhead and complexity for most programs on most platforms.)\r
-  * New segments are only appended to old ones when holding top-most\r
-    memory; if they cannot be prepended to others, they are held in\r
-    different segments.\r
-\r
-  Except for the top-most segment of an mstate, each segment record\r
-  is kept at the tail of its segment. Segments are added by pushing\r
-  segment records onto the list headed by &mstate.seg for the\r
-  containing mstate.\r
-\r
-  Segment flags control allocation/merge/deallocation policies:\r
-  * If EXTERN_BIT set, then we did not allocate this segment,\r
-    and so should not try to deallocate or merge with others.\r
-    (This currently holds only for the initial segment passed\r
-    into create_mspace_with_base.)\r
-  * If USE_MMAP_BIT set, the segment may be merged with\r
-    other surrounding mmapped segments and trimmed/de-allocated\r
-    using munmap.\r
-  * If neither bit is set, then the segment was obtained using\r
-    MORECORE so can be merged with surrounding MORECORE'd segments\r
-    and deallocated/trimmed using MORECORE with negative arguments.\r
-*/\r
-\r
-struct malloc_segment {\r
-  char*        base;             /* base address */\r
-  size_t       size;             /* allocated size */\r
-  struct malloc_segment* next;   /* ptr to next segment */\r
-  flag_t       sflags;           /* mmap and extern flag */\r
-};\r
-\r
-#define is_mmapped_segment(S)  ((S)->sflags & USE_MMAP_BIT)\r
-#define is_extern_segment(S)   ((S)->sflags & EXTERN_BIT)\r
-\r
-typedef struct malloc_segment  msegment;\r
-typedef struct malloc_segment* msegmentptr;\r
-\r
-/* ---------------------------- malloc_state ----------------------------- */\r
-\r
-/*\r
-   A malloc_state holds all of the bookkeeping for a space.\r
-   The main fields are:\r
-\r
-  Top\r
-    The topmost chunk of the currently active segment. Its size is\r
-    cached in topsize.  The actual size of topmost space is\r
-    topsize+TOP_FOOT_SIZE, which includes space reserved for adding\r
-    fenceposts and segment records if necessary when getting more\r
-    space from the system.  The size at which to autotrim top is\r
-    cached from mparams in trim_check, except that it is disabled if\r
-    an autotrim fails.\r
-\r
-  Designated victim (dv)\r
-    This is the preferred chunk for servicing small requests that\r
-    don't have exact fits.  It is normally the chunk split off most\r
-    recently to service another small request.  Its size is cached in\r
-    dvsize. The link fields of this chunk are not maintained since it\r
-    is not kept in a bin.\r
-\r
-  SmallBins\r
-    An array of bin headers for free chunks.  These bins hold chunks\r
-    with sizes less than MIN_LARGE_SIZE bytes. Each bin contains\r
-    chunks of all the same size, spaced 8 bytes apart.  To simplify\r
-    use in double-linked lists, each bin header acts as a malloc_chunk\r
-    pointing to the real first node, if it exists (else pointing to\r
-    itself).  This avoids special-casing for headers.  But to avoid\r
-    waste, we allocate only the fd/bk pointers of bins, and then use\r
-    repositioning tricks to treat these as the fields of a chunk.\r
-\r
-  TreeBins\r
-    Treebins are pointers to the roots of trees holding a range of\r
-    sizes. There are 2 equally spaced treebins for each power of two\r
-    from TREE_SHIFT to TREE_SHIFT+16. The last bin holds anything\r
-    larger.\r
-\r
-  Bin maps\r
-    There is one bit map for small bins ("smallmap") and one for\r
-    treebins ("treemap).  Each bin sets its bit when non-empty, and\r
-    clears the bit when empty.  Bit operations are then used to avoid\r
-    bin-by-bin searching -- nearly all "search" is done without ever\r
-    looking at bins that won't be selected.  The bit maps\r
-    conservatively use 32 bits per map word, even if on 64bit system.\r
-    For a good description of some of the bit-based techniques used\r
-    here, see Henry S. Warren Jr's book "Hacker's Delight" (and\r
-    supplement at http://hackersdelight.org/). Many of these are\r
-    intended to reduce the branchiness of paths through malloc etc, as\r
-    well as to reduce the number of memory locations read or written.\r
-\r
-  Segments\r
-    A list of segments headed by an embedded malloc_segment record\r
-    representing the initial space.\r
-\r
-  Address check support\r
-    The least_addr field is the least address ever obtained from\r
-    MORECORE or MMAP. Attempted frees and reallocs of any address less\r
-    than this are trapped (unless INSECURE is defined).\r
-\r
-  Magic tag\r
-    A cross-check field that should always hold same value as mparams.magic.\r
-\r
-  Max allowed footprint\r
-    The maximum allowed bytes to allocate from system (zero means no limit)\r
-\r
-  Flags\r
-    Bits recording whether to use MMAP, locks, or contiguous MORECORE\r
-\r
-  Statistics\r
-    Each space keeps track of current and maximum system memory\r
-    obtained via MORECORE or MMAP.\r
-\r
-  Trim support\r
-    Fields holding the amount of unused topmost memory that should trigger\r
-    trimming, and a counter to force periodic scanning to release unused\r
-    non-topmost segments.\r
-\r
-  Locking\r
-    If USE_LOCKS is defined, the "mutex" lock is acquired and released\r
-    around every public call using this mspace.\r
-\r
-  Extension support\r
-    A void* pointer and a size_t field that can be used to help implement\r
-    extensions to this malloc.\r
-*/\r
-\r
-/* Bin types, widths and sizes */\r
-#define NSMALLBINS        (32U)\r
-#define NTREEBINS         (32U)\r
-#define SMALLBIN_SHIFT    (3U)\r
-#define SMALLBIN_WIDTH    (SIZE_T_ONE << SMALLBIN_SHIFT)\r
-#define TREEBIN_SHIFT     (8U)\r
-#define MIN_LARGE_SIZE    (SIZE_T_ONE << TREEBIN_SHIFT)\r
-#define MAX_SMALL_SIZE    (MIN_LARGE_SIZE - SIZE_T_ONE)\r
-#define MAX_SMALL_REQUEST (MAX_SMALL_SIZE - CHUNK_ALIGN_MASK - CHUNK_OVERHEAD)\r
-\r
-struct malloc_state {\r
-  binmap_t   smallmap;\r
-  binmap_t   treemap;\r
-  size_t     dvsize;\r
-  size_t     topsize;\r
-  char*      least_addr;\r
-  mchunkptr  dv;\r
-  mchunkptr  top;\r
-  size_t     trim_check;\r
-  size_t     release_checks;\r
-  size_t     magic;\r
-  mchunkptr  smallbins[(NSMALLBINS+1)*2];\r
-  tbinptr    treebins[NTREEBINS];\r
-  size_t     footprint;\r
-  size_t     max_footprint;\r
-  size_t     footprint_limit; /* zero means no limit */\r
-  flag_t     mflags;\r
-#if USE_LOCKS\r
-  MLOCK_T    mutex;     /* locate lock among fields that rarely change */\r
-#endif /* USE_LOCKS */\r
-  msegment   seg;\r
-  void*      extp;      /* Unused but available for extensions */\r
-  size_t     exts;\r
-};\r
-\r
-typedef struct malloc_state*    mstate;\r
-\r
-/* ------------- Global malloc_state and malloc_params ------------------- */\r
-\r
-/*\r
-  malloc_params holds global properties, including those that can be\r
-  dynamically set using mallopt. There is a single instance, mparams,\r
-  initialized in init_mparams. Note that the non-zeroness of "magic"\r
-  also serves as an initialization flag.\r
-*/\r
-\r
-struct malloc_params {\r
-  size_t magic;\r
-  size_t page_size;\r
-  size_t granularity;\r
-  size_t mmap_threshold;\r
-  size_t trim_threshold;\r
-  flag_t default_mflags;\r
-};\r
-\r
-static struct malloc_params mparams;\r
-\r
-/* Ensure mparams initialized */\r
-#define ensure_initialization() (void)(mparams.magic != 0 || init_mparams())\r
-\r
-#if !ONLY_MSPACES\r
-\r
-/* The global malloc_state used for all non-"mspace" calls */\r
-static struct malloc_state _gm_;\r
-#define gm                 (&_gm_)\r
-#define is_global(M)       ((M) == &_gm_)\r
-\r
-#endif /* !ONLY_MSPACES */\r
-\r
-#define is_initialized(M)  ((M)->top != 0)\r
-\r
-/* -------------------------- system alloc setup ------------------------- */\r
-\r
-/* Operations on mflags */\r
-\r
-#define use_lock(M)           ((M)->mflags &   USE_LOCK_BIT)\r
-#define enable_lock(M)        ((M)->mflags |=  USE_LOCK_BIT)\r
-#if USE_LOCKS\r
-#define disable_lock(M)       ((M)->mflags &= ~USE_LOCK_BIT)\r
-#else\r
-#define disable_lock(M)\r
-#endif\r
-\r
-#define use_mmap(M)           ((M)->mflags &   USE_MMAP_BIT)\r
-#define enable_mmap(M)        ((M)->mflags |=  USE_MMAP_BIT)\r
-#if HAVE_MMAP\r
-#define disable_mmap(M)       ((M)->mflags &= ~USE_MMAP_BIT)\r
-#else\r
-#define disable_mmap(M)\r
-#endif\r
-\r
-#define use_noncontiguous(M)  ((M)->mflags &   USE_NONCONTIGUOUS_BIT)\r
-#define disable_contiguous(M) ((M)->mflags |=  USE_NONCONTIGUOUS_BIT)\r
-\r
-#define set_lock(M,L)\\r
- ((M)->mflags = (L)?\\r
-  ((M)->mflags | USE_LOCK_BIT) :\\r
-  ((M)->mflags & ~USE_LOCK_BIT))\r
-\r
-/* page-align a size */\r
-#define page_align(S)\\r
- (((S) + (mparams.page_size - SIZE_T_ONE)) & ~(mparams.page_size - SIZE_T_ONE))\r
-\r
-/* granularity-align a size */\r
-#define granularity_align(S)\\r
-  (((S) + (mparams.granularity - SIZE_T_ONE))\\r
-   & ~(mparams.granularity - SIZE_T_ONE))\r
-\r
-\r
-/* For mmap, use granularity alignment on windows, else page-align */\r
-#ifdef WIN32\r
-#define mmap_align(S) granularity_align(S)\r
-#else\r
-#define mmap_align(S) page_align(S)\r
-#endif\r
-\r
-/* For sys_alloc, enough padding to ensure can malloc request on success */\r
-#define SYS_ALLOC_PADDING (TOP_FOOT_SIZE + MALLOC_ALIGNMENT)\r
-\r
-#define is_page_aligned(S)\\r
-   (((size_t)(S) & (mparams.page_size - SIZE_T_ONE)) == 0)\r
-#define is_granularity_aligned(S)\\r
-   (((size_t)(S) & (mparams.granularity - SIZE_T_ONE)) == 0)\r
-\r
-/*  True if segment S holds address A */\r
-#define segment_holds(S, A)\\r
-  ((char*)(A) >= S->base && (char*)(A) < S->base + S->size)\r
-\r
-/* Return segment holding given address */\r
-static msegmentptr segment_holding(mstate m, char* addr) {\r
-  msegmentptr sp = &m->seg;\r
-  for (;;) {\r
-    if (addr >= sp->base && addr < sp->base + sp->size)\r
-      return sp;\r
-    if ((sp = sp->next) == 0)\r
-      return 0;\r
-  }\r
-}\r
-\r
-/* Return true if segment contains a segment link */\r
-static int has_segment_link(mstate m, msegmentptr ss) {\r
-  msegmentptr sp = &m->seg;\r
-  for (;;) {\r
-    if ((char*)sp >= ss->base && (char*)sp < ss->base + ss->size)\r
-      return 1;\r
-    if ((sp = sp->next) == 0)\r
-      return 0;\r
-  }\r
-}\r
-\r
-#ifndef MORECORE_CANNOT_TRIM\r
-#define should_trim(M,s)  ((s) > (M)->trim_check)\r
-#else  /* MORECORE_CANNOT_TRIM */\r
-#define should_trim(M,s)  (0)\r
-#endif /* MORECORE_CANNOT_TRIM */\r
-\r
-/*\r
-  TOP_FOOT_SIZE is padding at the end of a segment, including space\r
-  that may be needed to place segment records and fenceposts when new\r
-  noncontiguous segments are added.\r
-*/\r
-#define TOP_FOOT_SIZE\\r
-  (align_offset(chunk2mem(0))+pad_request(sizeof(struct malloc_segment))+MIN_CHUNK_SIZE)\r
-\r
-\r
-/* -------------------------------  Hooks -------------------------------- */\r
-\r
-/*\r
-  PREACTION should be defined to return 0 on success, and nonzero on\r
-  failure. If you are not using locking, you can redefine these to do\r
-  anything you like.\r
-*/\r
-\r
-#if USE_LOCKS\r
-#define PREACTION(M)  ((use_lock(M))? ACQUIRE_LOCK(&(M)->mutex) : 0)\r
-#define POSTACTION(M) { if (use_lock(M)) RELEASE_LOCK(&(M)->mutex); }\r
-#else /* USE_LOCKS */\r
-\r
-#ifndef PREACTION\r
-#define PREACTION(M) (0)\r
-#endif  /* PREACTION */\r
-\r
-#ifndef POSTACTION\r
-#define POSTACTION(M)\r
-#endif  /* POSTACTION */\r
-\r
-#endif /* USE_LOCKS */\r
-\r
-/*\r
-  CORRUPTION_ERROR_ACTION is triggered upon detected bad addresses.\r
-  USAGE_ERROR_ACTION is triggered on detected bad frees and\r
-  reallocs. The argument p is an address that might have triggered the\r
-  fault. It is ignored by the two predefined actions, but might be\r
-  useful in custom actions that try to help diagnose errors.\r
-*/\r
-\r
-#if PROCEED_ON_ERROR\r
-\r
-/* A count of the number of corruption errors causing resets */\r
-int malloc_corruption_error_count;\r
-\r
-/* default corruption action */\r
-static void reset_on_error(mstate m);\r
-\r
-#define CORRUPTION_ERROR_ACTION(m)  reset_on_error(m)\r
-#define USAGE_ERROR_ACTION(m, p)\r
-\r
-#else /* PROCEED_ON_ERROR */\r
-\r
-#ifndef CORRUPTION_ERROR_ACTION\r
-#define CORRUPTION_ERROR_ACTION(m) ABORT\r
-#endif /* CORRUPTION_ERROR_ACTION */\r
-\r
-#ifndef USAGE_ERROR_ACTION\r
-#define USAGE_ERROR_ACTION(m,p) ABORT\r
-#endif /* USAGE_ERROR_ACTION */\r
-\r
-#endif /* PROCEED_ON_ERROR */\r
-\r
-\r
-/* -------------------------- Debugging setup ---------------------------- */\r
-\r
-#if ! DEBUG\r
-\r
-#define check_free_chunk(M,P)\r
-#define check_inuse_chunk(M,P)\r
-#define check_malloced_chunk(M,P,N)\r
-#define check_mmapped_chunk(M,P)\r
-#define check_malloc_state(M)\r
-#define check_top_chunk(M,P)\r
-\r
-#else /* DEBUG */\r
-#define check_free_chunk(M,P)       do_check_free_chunk(M,P)\r
-#define check_inuse_chunk(M,P)      do_check_inuse_chunk(M,P)\r
-#define check_top_chunk(M,P)        do_check_top_chunk(M,P)\r
-#define check_malloced_chunk(M,P,N) do_check_malloced_chunk(M,P,N)\r
-#define check_mmapped_chunk(M,P)    do_check_mmapped_chunk(M,P)\r
-#define check_malloc_state(M)       do_check_malloc_state(M)\r
-\r
-static void   do_check_any_chunk(mstate m, mchunkptr p);\r
-static void   do_check_top_chunk(mstate m, mchunkptr p);\r
-static void   do_check_mmapped_chunk(mstate m, mchunkptr p);\r
-static void   do_check_inuse_chunk(mstate m, mchunkptr p);\r
-static void   do_check_free_chunk(mstate m, mchunkptr p);\r
-static void   do_check_malloced_chunk(mstate m, void* mem, size_t s);\r
-static void   do_check_tree(mstate m, tchunkptr t);\r
-static void   do_check_treebin(mstate m, bindex_t i);\r
-static void   do_check_smallbin(mstate m, bindex_t i);\r
-static void   do_check_malloc_state(mstate m);\r
-static int    bin_find(mstate m, mchunkptr x);\r
-static size_t traverse_and_check(mstate m);\r
-#endif /* DEBUG */\r
-\r
-/* ---------------------------- Indexing Bins ---------------------------- */\r
-\r
-#define is_small(s)         (((s) >> SMALLBIN_SHIFT) < NSMALLBINS)\r
-#define small_index(s)      (bindex_t)((s)  >> SMALLBIN_SHIFT)\r
-#define small_index2size(i) ((i)  << SMALLBIN_SHIFT)\r
-#define MIN_SMALL_INDEX     (small_index(MIN_CHUNK_SIZE))\r
-\r
-/* addressing by index. See above about smallbin repositioning */\r
-#define smallbin_at(M, i)   ((sbinptr)((char*)&((M)->smallbins[(i)<<1])))\r
-#define treebin_at(M,i)     (&((M)->treebins[i]))\r
-\r
-/* assign tree index for size S to variable I. Use x86 asm if possible  */\r
-#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))\r
-#define compute_tree_index(S, I)\\r
-{\\r
-  unsigned int X = S >> TREEBIN_SHIFT;\\r
-  if (X == 0)\\r
-    I = 0;\\r
-  else if (X > 0xFFFF)\\r
-    I = NTREEBINS-1;\\r
-  else {\\r
-    unsigned int K = (unsigned) sizeof(X)*__CHAR_BIT__ - 1 - (unsigned) __builtin_clz(X); \\r
-    I =  (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\\r
-  }\\r
-}\r
-\r
-#elif defined (__INTEL_COMPILER)\r
-#define compute_tree_index(S, I)\\r
-{\\r
-  size_t X = S >> TREEBIN_SHIFT;\\r
-  if (X == 0)\\r
-    I = 0;\\r
-  else if (X > 0xFFFF)\\r
-    I = NTREEBINS-1;\\r
-  else {\\r
-    unsigned int K = _bit_scan_reverse (X); \\r
-    I =  (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\\r
-  }\\r
-}\r
-\r
-#elif defined(_MSC_VER) && _MSC_VER>=1300\r
-#define compute_tree_index(S, I)\\r
-{\\r
-  size_t X = S >> TREEBIN_SHIFT;\\r
-  if (X == 0)\\r
-    I = 0;\\r
-  else if (X > 0xFFFF)\\r
-    I = NTREEBINS-1;\\r
-  else {\\r
-    unsigned int K;\\r
-    _BitScanReverse((DWORD *) &K, (DWORD) X);\\r
-    I =  (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\\r
-  }\\r
-}\r
-\r
-#else /* GNUC */\r
-#define compute_tree_index(S, I)\\r
-{\\r
-  size_t X = S >> TREEBIN_SHIFT;\\r
-  if (X == 0)\\r
-    I = 0;\\r
-  else if (X > 0xFFFF)\\r
-    I = NTREEBINS-1;\\r
-  else {\\r
-    unsigned int Y = (unsigned int)X;\\r
-    unsigned int N = ((Y - 0x100) >> 16) & 8;\\r
-    unsigned int K = (((Y <<= N) - 0x1000) >> 16) & 4;\\r
-    N += K;\\r
-    N += K = (((Y <<= K) - 0x4000) >> 16) & 2;\\r
-    K = 14 - N + ((Y <<= K) >> 15);\\r
-    I = (K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1));\\r
-  }\\r
-}\r
-#endif /* GNUC */\r
-\r
-/* Bit representing maximum resolved size in a treebin at i */\r
-#define bit_for_tree_index(i) \\r
-   (i == NTREEBINS-1)? (SIZE_T_BITSIZE-1) : (((i) >> 1) + TREEBIN_SHIFT - 2)\r
-\r
-/* Shift placing maximum resolved bit in a treebin at i as sign bit */\r
-#define leftshift_for_tree_index(i) \\r
-   ((i == NTREEBINS-1)? 0 : \\r
-    ((SIZE_T_BITSIZE-SIZE_T_ONE) - (((i) >> 1) + TREEBIN_SHIFT - 2)))\r
-\r
-/* The size of the smallest chunk held in bin with index i */\r
-#define minsize_for_tree_index(i) \\r
-   ((SIZE_T_ONE << (((i) >> 1) + TREEBIN_SHIFT)) |  \\r
-   (((size_t)((i) & SIZE_T_ONE)) << (((i) >> 1) + TREEBIN_SHIFT - 1)))\r
-\r
-\r
-/* ------------------------ Operations on bin maps ----------------------- */\r
-\r
-/* bit corresponding to given index */\r
-#define idx2bit(i)              ((binmap_t)(1) << (i))\r
-\r
-/* Mark/Clear bits with given index */\r
-#define mark_smallmap(M,i)      ((M)->smallmap |=  idx2bit(i))\r
-#define clear_smallmap(M,i)     ((M)->smallmap &= ~idx2bit(i))\r
-#define smallmap_is_marked(M,i) ((M)->smallmap &   idx2bit(i))\r
-\r
-#define mark_treemap(M,i)       ((M)->treemap  |=  idx2bit(i))\r
-#define clear_treemap(M,i)      ((M)->treemap  &= ~idx2bit(i))\r
-#define treemap_is_marked(M,i)  ((M)->treemap  &   idx2bit(i))\r
-\r
-/* isolate the least set bit of a bitmap */\r
-#define least_bit(x)         ((x) & -(x))\r
-\r
-/* mask with all bits to left of least bit of x on */\r
-#define left_bits(x)         ((x<<1) | -(x<<1))\r
-\r
-/* mask with all bits to left of or equal to least bit of x on */\r
-#define same_or_left_bits(x) ((x) | -(x))\r
-\r
-/* index corresponding to given bit. Use x86 asm if possible */\r
-\r
-#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))\r
-#define compute_bit2idx(X, I)\\r
-{\\r
-  unsigned int J;\\r
-  J = __builtin_ctz(X); \\r
-  I = (bindex_t)J;\\r
-}\r
-\r
-#elif defined (__INTEL_COMPILER)\r
-#define compute_bit2idx(X, I)\\r
-{\\r
-  unsigned int J;\\r
-  J = _bit_scan_forward (X); \\r
-  I = (bindex_t)J;\\r
-}\r
-\r
-#elif defined(_MSC_VER) && _MSC_VER>=1300\r
-#define compute_bit2idx(X, I)\\r
-{\\r
-  unsigned int J;\\r
-  _BitScanForward((DWORD *) &J, X);\\r
-  I = (bindex_t)J;\\r
-}\r
-\r
-#elif USE_BUILTIN_FFS\r
-#define compute_bit2idx(X, I) I = ffs(X)-1\r
-\r
-#else\r
-#define compute_bit2idx(X, I)\\r
-{\\r
-  unsigned int Y = X - 1;\\r
-  unsigned int K = Y >> (16-4) & 16;\\r
-  unsigned int N = K;        Y >>= K;\\r
-  N += K = Y >> (8-3) &  8;  Y >>= K;\\r
-  N += K = Y >> (4-2) &  4;  Y >>= K;\\r
-  N += K = Y >> (2-1) &  2;  Y >>= K;\\r
-  N += K = Y >> (1-0) &  1;  Y >>= K;\\r
-  I = (bindex_t)(N + Y);\\r
-}\r
-#endif /* GNUC */\r
-\r
-\r
-/* ----------------------- Runtime Check Support ------------------------- */\r
-\r
-/*\r
-  For security, the main invariant is that malloc/free/etc never\r
-  writes to a static address other than malloc_state, unless static\r
-  malloc_state itself has been corrupted, which cannot occur via\r
-  malloc (because of these checks). In essence this means that we\r
-  believe all pointers, sizes, maps etc held in malloc_state, but\r
-  check all of those linked or offsetted from other embedded data\r
-  structures.  These checks are interspersed with main code in a way\r
-  that tends to minimize their run-time cost.\r
-\r
-  When FOOTERS is defined, in addition to range checking, we also\r
-  verify footer fields of inuse chunks, which can be used guarantee\r
-  that the mstate controlling malloc/free is intact.  This is a\r
-  streamlined version of the approach described by William Robertson\r
-  et al in "Run-time Detection of Heap-based Overflows" LISA'03\r
-  http://www.usenix.org/events/lisa03/tech/robertson.html The footer\r
-  of an inuse chunk holds the xor of its mstate and a random seed,\r
-  that is checked upon calls to free() and realloc().  This is\r
-  (probabalistically) unguessable from outside the program, but can be\r
-  computed by any code successfully malloc'ing any chunk, so does not\r
-  itself provide protection against code that has already broken\r
-  security through some other means.  Unlike Robertson et al, we\r
-  always dynamically check addresses of all offset chunks (previous,\r
-  next, etc). This turns out to be cheaper than relying on hashes.\r
-*/\r
-\r
-#if !INSECURE\r
-/* Check if address a is at least as high as any from MORECORE or MMAP */\r
-#define ok_address(M, a) ((char*)(a) >= (M)->least_addr)\r
-/* Check if address of next chunk n is higher than base chunk p */\r
-#define ok_next(p, n)    ((char*)(p) < (char*)(n))\r
-/* Check if p has inuse status */\r
-#define ok_inuse(p)     is_inuse(p)\r
-/* Check if p has its pinuse bit on */\r
-#define ok_pinuse(p)     pinuse(p)\r
-\r
-#else /* !INSECURE */\r
-#define ok_address(M, a) (1)\r
-#define ok_next(b, n)    (1)\r
-#define ok_inuse(p)      (1)\r
-#define ok_pinuse(p)     (1)\r
-#endif /* !INSECURE */\r
-\r
-#if (FOOTERS && !INSECURE)\r
-/* Check if (alleged) mstate m has expected magic field */\r
-#define ok_magic(M)      ((M)->magic == mparams.magic)\r
-#else  /* (FOOTERS && !INSECURE) */\r
-#define ok_magic(M)      (1)\r
-#endif /* (FOOTERS && !INSECURE) */\r
-\r
-/* In gcc, use __builtin_expect to minimize impact of checks */\r
-#if !INSECURE\r
-#if defined(__GNUC__) && __GNUC__ >= 3\r
-#define RTCHECK(e)  __builtin_expect(e, 1)\r
-#else /* GNUC */\r
-#define RTCHECK(e)  (e)\r
-#endif /* GNUC */\r
-#else /* !INSECURE */\r
-#define RTCHECK(e)  (1)\r
-#endif /* !INSECURE */\r
-\r
-/* macros to set up inuse chunks with or without footers */\r
-\r
-#if !FOOTERS\r
-\r
-#define mark_inuse_foot(M,p,s)\r
-\r
-/* Macros for setting head/foot of non-mmapped chunks */\r
-\r
-/* Set cinuse bit and pinuse bit of next chunk */\r
-#define set_inuse(M,p,s)\\r
-  ((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\\r
-  ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT)\r
-\r
-/* Set cinuse and pinuse of this chunk and pinuse of next chunk */\r
-#define set_inuse_and_pinuse(M,p,s)\\r
-  ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\\r
-  ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT)\r
-\r
-/* Set size, cinuse and pinuse bit of this chunk */\r
-#define set_size_and_pinuse_of_inuse_chunk(M, p, s)\\r
-  ((p)->head = (s|PINUSE_BIT|CINUSE_BIT))\r
-\r
-#else /* FOOTERS */\r
-\r
-/* Set foot of inuse chunk to be xor of mstate and seed */\r
-#define mark_inuse_foot(M,p,s)\\r
-  (((mchunkptr)((char*)(p) + (s)))->prev_foot = ((size_t)(M) ^ mparams.magic))\r
-\r
-#define get_mstate_for(p)\\r
-  ((mstate)(((mchunkptr)((char*)(p) +\\r
-    (chunksize(p))))->prev_foot ^ mparams.magic))\r
-\r
-#define set_inuse(M,p,s)\\r
-  ((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\\r
-  (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT), \\r
-  mark_inuse_foot(M,p,s))\r
-\r
-#define set_inuse_and_pinuse(M,p,s)\\r
-  ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\\r
-  (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT),\\r
- mark_inuse_foot(M,p,s))\r
-\r
-#define set_size_and_pinuse_of_inuse_chunk(M, p, s)\\r
-  ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\\r
-  mark_inuse_foot(M, p, s))\r
-\r
-#endif /* !FOOTERS */\r
-\r
-/* ---------------------------- setting mparams -------------------------- */\r
-\r
-/* Initialize mparams */\r
-static int init_mparams(void) {\r
-#ifdef NEED_GLOBAL_LOCK_INIT\r
-    call_once(&malloc_global_mutex_init_once, init_malloc_global_mutex);\r
-#endif\r
-\r
-  ACQUIRE_MALLOC_GLOBAL_LOCK();\r
-  if (mparams.magic == 0) {\r
-    size_t magic;\r
-    size_t psize;\r
-    size_t gsize;\r
-\r
-#ifndef WIN32\r
-    psize = malloc_getpagesize;\r
-    gsize = ((DEFAULT_GRANULARITY != 0)? DEFAULT_GRANULARITY : psize);\r
-#else /* WIN32 */\r
-    {\r
-      SYSTEM_INFO system_info;\r
-      GetSystemInfo(&system_info);\r
-      psize = system_info.dwPageSize;\r
-      gsize = ((DEFAULT_GRANULARITY != 0)?\r
-               DEFAULT_GRANULARITY : system_info.dwAllocationGranularity);\r
-    }\r
-#endif /* WIN32 */\r
-\r
-    /* Sanity-check configuration:\r
-       size_t must be unsigned and as wide as pointer type.\r
-       ints must be at least 4 bytes.\r
-       alignment must be at least 8.\r
-       Alignment, min chunk size, and page size must all be powers of 2.\r
-    */\r
-    if ((sizeof(size_t) != sizeof(char*)) ||\r
-        (MAX_SIZE_T < MIN_CHUNK_SIZE)  ||\r
-        (sizeof(int) < 4)  ||\r
-        (MALLOC_ALIGNMENT < (size_t)8U) ||\r
-        ((MALLOC_ALIGNMENT & (MALLOC_ALIGNMENT-SIZE_T_ONE)) != 0) ||\r
-        ((MCHUNK_SIZE      & (MCHUNK_SIZE-SIZE_T_ONE))      != 0) ||\r
-        ((gsize            & (gsize-SIZE_T_ONE))            != 0) ||\r
-        ((psize            & (psize-SIZE_T_ONE))            != 0))\r
-      ABORT;\r
-\r
-    mparams.granularity = gsize;\r
-    mparams.page_size = psize;\r
-    mparams.mmap_threshold = DEFAULT_MMAP_THRESHOLD;\r
-    mparams.trim_threshold = DEFAULT_TRIM_THRESHOLD;\r
-#if MORECORE_CONTIGUOUS\r
-    mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT;\r
-#else  /* MORECORE_CONTIGUOUS */\r
-    mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT|USE_NONCONTIGUOUS_BIT;\r
-#endif /* MORECORE_CONTIGUOUS */\r
-\r
-#if !ONLY_MSPACES\r
-    /* Set up lock for main malloc area */\r
-    gm->mflags = mparams.default_mflags;\r
-    (void)INITIAL_LOCK(&gm->mutex);\r
-#endif\r
-\r
-    {\r
-#if USE_DEV_RANDOM\r
-      int fd;\r
-      unsigned char buf[sizeof(size_t)];\r
-      /* Try to use /dev/urandom, else fall back on using time */\r
-      if ((fd = open("/dev/urandom", O_RDONLY)) >= 0 &&\r
-          read(fd, buf, sizeof(buf)) == sizeof(buf)) {\r
-        magic = *((size_t *) buf);\r
-        close(fd);\r
-      }\r
-      else\r
-#endif /* USE_DEV_RANDOM */\r
-#ifdef WIN32\r
-        magic = (size_t)(GetTickCount() ^ (size_t)0x55555555U);\r
-#elif defined(LACKS_TIME_H)\r
-      magic = (size_t)&magic ^ (size_t)0x55555555U;\r
-#else\r
-        magic = (size_t)(time(0) ^ (size_t)0x55555555U);\r
-#endif\r
-      magic |= (size_t)8U;    /* ensure nonzero */\r
-      magic &= ~(size_t)7U;   /* improve chances of fault for bad values */\r
-      /* Until memory modes commonly available, use volatile-write */\r
-      (*(volatile size_t *)(&(mparams.magic))) = magic;\r
-    }\r
-  }\r
-\r
-  RELEASE_MALLOC_GLOBAL_LOCK();\r
-  return 1;\r
-}\r
-\r
-/* support for mallopt */\r
-static int change_mparam(int param_number, int value) {\r
-  size_t val;\r
-  ensure_initialization();\r
-  val = (value == -1)? MAX_SIZE_T : (size_t)value;\r
-  switch(param_number) {\r
-  case M_TRIM_THRESHOLD:\r
-    mparams.trim_threshold = val;\r
-    return 1;\r
-  case M_GRANULARITY:\r
-    if (val >= mparams.page_size && ((val & (val-1)) == 0)) {\r
-      mparams.granularity = val;\r
-      return 1;\r
-    }\r
-    else\r
-      return 0;\r
-  case M_MMAP_THRESHOLD:\r
-    mparams.mmap_threshold = val;\r
-    return 1;\r
-  default:\r
-    return 0;\r
-  }\r
-}\r
-\r
-#if DEBUG\r
-/* ------------------------- Debugging Support --------------------------- */\r
-\r
-/* Check properties of any chunk, whether free, inuse, mmapped etc  */\r
-static void do_check_any_chunk(mstate m, mchunkptr p) {\r
-  assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD));\r
-  assert(ok_address(m, p));\r
-}\r
-\r
-/* Check properties of top chunk */\r
-static void do_check_top_chunk(mstate m, mchunkptr p) {\r
-  msegmentptr sp = segment_holding(m, (char*)p);\r
-  size_t  sz = p->head & ~INUSE_BITS; /* third-lowest bit can be set! */\r
-  assert(sp != 0);\r
-  assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD));\r
-  assert(ok_address(m, p));\r
-  assert(sz == m->topsize);\r
-  assert(sz > 0);\r
-  assert(sz == ((sp->base + sp->size) - (char*)p) - TOP_FOOT_SIZE);\r
-  assert(pinuse(p));\r
-  assert(!pinuse(chunk_plus_offset(p, sz)));\r
-}\r
-\r
-/* Check properties of (inuse) mmapped chunks */\r
-static void do_check_mmapped_chunk(mstate m, mchunkptr p) {\r
-  size_t  sz = chunksize(p);\r
-  size_t len = (sz + (p->prev_foot) + MMAP_FOOT_PAD);\r
-  assert(is_mmapped(p));\r
-  assert(use_mmap(m));\r
-  assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD));\r
-  assert(ok_address(m, p));\r
-  assert(!is_small(sz));\r
-  assert((len & (mparams.page_size-SIZE_T_ONE)) == 0);\r
-  assert(chunk_plus_offset(p, sz)->head == FENCEPOST_HEAD);\r
-  assert(chunk_plus_offset(p, sz+SIZE_T_SIZE)->head == 0);\r
-}\r
-\r
-/* Check properties of inuse chunks */\r
-static void do_check_inuse_chunk(mstate m, mchunkptr p) {\r
-  do_check_any_chunk(m, p);\r
-  assert(is_inuse(p));\r
-  assert(next_pinuse(p));\r
-  /* If not pinuse and not mmapped, previous chunk has OK offset */\r
-  assert(is_mmapped(p) || pinuse(p) || next_chunk(prev_chunk(p)) == p);\r
-  if (is_mmapped(p))\r
-    do_check_mmapped_chunk(m, p);\r
-}\r
-\r
-/* Check properties of free chunks */\r
-static void do_check_free_chunk(mstate m, mchunkptr p) {\r
-  size_t sz = chunksize(p);\r
-  mchunkptr next = chunk_plus_offset(p, sz);\r
-  do_check_any_chunk(m, p);\r
-  assert(!is_inuse(p));\r
-  assert(!next_pinuse(p));\r
-  assert (!is_mmapped(p));\r
-  if (p != m->dv && p != m->top) {\r
-    if (sz >= MIN_CHUNK_SIZE) {\r
-      assert((sz & CHUNK_ALIGN_MASK) == 0);\r
-      assert(is_aligned(chunk2mem(p)));\r
-      assert(next->prev_foot == sz);\r
-      assert(pinuse(p));\r
-      assert (next == m->top || is_inuse(next));\r
-      assert(p->fd->bk == p);\r
-      assert(p->bk->fd == p);\r
-    }\r
-    else  /* markers are always of size SIZE_T_SIZE */\r
-      assert(sz == SIZE_T_SIZE);\r
-  }\r
-}\r
-\r
-/* Check properties of malloced chunks at the point they are malloced */\r
-static void do_check_malloced_chunk(mstate m, void* mem, size_t s) {\r
-  if (mem != 0) {\r
-    mchunkptr p = mem2chunk(mem);\r
-    size_t sz = p->head & ~INUSE_BITS;\r
-    do_check_inuse_chunk(m, p);\r
-    assert((sz & CHUNK_ALIGN_MASK) == 0);\r
-    assert(sz >= MIN_CHUNK_SIZE);\r
-    assert(sz >= s);\r
-    /* unless mmapped, size is less than MIN_CHUNK_SIZE more than request */\r
-    assert(is_mmapped(p) || sz < (s + MIN_CHUNK_SIZE));\r
-  }\r
-}\r
-\r
-/* Check a tree and its subtrees.  */\r
-static void do_check_tree(mstate m, tchunkptr t) {\r
-  tchunkptr head = 0;\r
-  tchunkptr u = t;\r
-  bindex_t tindex = t->index;\r
-  size_t tsize = chunksize(t);\r
-  bindex_t idx;\r
-  compute_tree_index(tsize, idx);\r
-  assert(tindex == idx);\r
-  assert(tsize >= MIN_LARGE_SIZE);\r
-  assert(tsize >= minsize_for_tree_index(idx));\r
-  assert((idx == NTREEBINS-1) || (tsize < minsize_for_tree_index((idx+1))));\r
-\r
-  do { /* traverse through chain of same-sized nodes */\r
-    do_check_any_chunk(m, ((mchunkptr)u));\r
-    assert(u->index == tindex);\r
-    assert(chunksize(u) == tsize);\r
-    assert(!is_inuse(u));\r
-    assert(!next_pinuse(u));\r
-    assert(u->fd->bk == u);\r
-    assert(u->bk->fd == u);\r
-    if (u->parent == 0) {\r
-      assert(u->child[0] == 0);\r
-      assert(u->child[1] == 0);\r
-    }\r
-    else {\r
-      assert(head == 0); /* only one node on chain has parent */\r
-      head = u;\r
-      assert(u->parent != u);\r
-      assert (u->parent->child[0] == u ||\r
-              u->parent->child[1] == u ||\r
-              *((tbinptr*)(u->parent)) == u);\r
-      if (u->child[0] != 0) {\r
-        assert(u->child[0]->parent == u);\r
-        assert(u->child[0] != u);\r
-        do_check_tree(m, u->child[0]);\r
-      }\r
-      if (u->child[1] != 0) {\r
-        assert(u->child[1]->parent == u);\r
-        assert(u->child[1] != u);\r
-        do_check_tree(m, u->child[1]);\r
-      }\r
-      if (u->child[0] != 0 && u->child[1] != 0) {\r
-        assert(chunksize(u->child[0]) < chunksize(u->child[1]));\r
-      }\r
-    }\r
-    u = u->fd;\r
-  } while (u != t);\r
-  assert(head != 0);\r
-}\r
-\r
-/*  Check all the chunks in a treebin.  */\r
-static void do_check_treebin(mstate m, bindex_t i) {\r
-  tbinptr* tb = treebin_at(m, i);\r
-  tchunkptr t = *tb;\r
-  int empty = (m->treemap & (1U << i)) == 0;\r
-  if (t == 0)\r
-    assert(empty);\r
-  if (!empty)\r
-    do_check_tree(m, t);\r
-}\r
-\r
-/*  Check all the chunks in a smallbin.  */\r
-static void do_check_smallbin(mstate m, bindex_t i) {\r
-  sbinptr b = smallbin_at(m, i);\r
-  mchunkptr p = b->bk;\r
-  unsigned int empty = (m->smallmap & (1U << i)) == 0;\r
-  if (p == b)\r
-    assert(empty);\r
-  if (!empty) {\r
-    for (; p != b; p = p->bk) {\r
-      size_t size = chunksize(p);\r
-      mchunkptr q;\r
-      /* each chunk claims to be free */\r
-      do_check_free_chunk(m, p);\r
-      /* chunk belongs in bin */\r
-      assert(small_index(size) == i);\r
-      assert(p->bk == b || chunksize(p->bk) == chunksize(p));\r
-      /* chunk is followed by an inuse chunk */\r
-      q = next_chunk(p);\r
-      if (q->head != FENCEPOST_HEAD)\r
-        do_check_inuse_chunk(m, q);\r
-    }\r
-  }\r
-}\r
-\r
-/* Find x in a bin. Used in other check functions. */\r
-static int bin_find(mstate m, mchunkptr x) {\r
-  size_t size = chunksize(x);\r
-  if (is_small(size)) {\r
-    bindex_t sidx = small_index(size);\r
-    sbinptr b = smallbin_at(m, sidx);\r
-    if (smallmap_is_marked(m, sidx)) {\r
-      mchunkptr p = b;\r
-      do {\r
-        if (p == x)\r
-          return 1;\r
-      } while ((p = p->fd) != b);\r
-    }\r
-  }\r
-  else {\r
-    bindex_t tidx;\r
-    compute_tree_index(size, tidx);\r
-    if (treemap_is_marked(m, tidx)) {\r
-      tchunkptr t = *treebin_at(m, tidx);\r
-      size_t sizebits = size << leftshift_for_tree_index(tidx);\r
-      while (t != 0 && chunksize(t) != size) {\r
-        t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1];\r
-        sizebits <<= 1;\r
-      }\r
-      if (t != 0) {\r
-        tchunkptr u = t;\r
-        do {\r
-          if (u == (tchunkptr)x)\r
-            return 1;\r
-        } while ((u = u->fd) != t);\r
-      }\r
-    }\r
-  }\r
-  return 0;\r
-}\r
-\r
-/* Traverse each chunk and check it; return total */\r
-static size_t traverse_and_check(mstate m) {\r
-  size_t sum = 0;\r
-  if (is_initialized(m)) {\r
-    msegmentptr s = &m->seg;\r
-    sum += m->topsize + TOP_FOOT_SIZE;\r
-    while (s != 0) {\r
-      mchunkptr q = align_as_chunk(s->base);\r
-      mchunkptr lastq = 0;\r
-      assert(pinuse(q));\r
-      while (segment_holds(s, q) &&\r
-             q != m->top && q->head != FENCEPOST_HEAD) {\r
-        sum += chunksize(q);\r
-        if (is_inuse(q)) {\r
-          assert(!bin_find(m, q));\r
-          do_check_inuse_chunk(m, q);\r
-        }\r
-        else {\r
-          assert(q == m->dv || bin_find(m, q));\r
-          assert(lastq == 0 || is_inuse(lastq)); /* Not 2 consecutive free */\r
-          do_check_free_chunk(m, q);\r
-        }\r
-        lastq = q;\r
-        q = next_chunk(q);\r
-      }\r
-      s = s->next;\r
-    }\r
-  }\r
-  return sum;\r
-}\r
-\r
-\r
-/* Check all properties of malloc_state. */\r
-static void do_check_malloc_state(mstate m) {\r
-  bindex_t i;\r
-  size_t total;\r
-  /* check bins */\r
-  for (i = 0; i < NSMALLBINS; ++i)\r
-    do_check_smallbin(m, i);\r
-  for (i = 0; i < NTREEBINS; ++i)\r
-    do_check_treebin(m, i);\r
-\r
-  if (m->dvsize != 0) { /* check dv chunk */\r
-    do_check_any_chunk(m, m->dv);\r
-    assert(m->dvsize == chunksize(m->dv));\r
-    assert(m->dvsize >= MIN_CHUNK_SIZE);\r
-    assert(bin_find(m, m->dv) == 0);\r
-  }\r
-\r
-  if (m->top != 0) {   /* check top chunk */\r
-    do_check_top_chunk(m, m->top);\r
-    /*assert(m->topsize == chunksize(m->top)); redundant */\r
-    assert(m->topsize > 0);\r
-    assert(bin_find(m, m->top) == 0);\r
-  }\r
-\r
-  total = traverse_and_check(m);\r
-  assert(total <= m->footprint);\r
-  assert(m->footprint <= m->max_footprint);\r
-}\r
-#endif /* DEBUG */\r
-\r
-/* ----------------------------- statistics ------------------------------ */\r
-\r
-#if !NO_MALLINFO\r
-static struct mallinfo internal_mallinfo(mstate m) {\r
-  struct mallinfo nm = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };\r
-  ensure_initialization();\r
-  if (!PREACTION(m)) {\r
-    check_malloc_state(m);\r
-    if (is_initialized(m)) {\r
-      size_t nfree = SIZE_T_ONE; /* top always free */\r
-      size_t mfree = m->topsize + TOP_FOOT_SIZE;\r
-      size_t sum = mfree;\r
-      msegmentptr s = &m->seg;\r
-      while (s != 0) {\r
-        mchunkptr q = align_as_chunk(s->base);\r
-        while (segment_holds(s, q) &&\r
-               q != m->top && q->head != FENCEPOST_HEAD) {\r
-          size_t sz = chunksize(q);\r
-          sum += sz;\r
-          if (!is_inuse(q)) {\r
-            mfree += sz;\r
-            ++nfree;\r
-          }\r
-          q = next_chunk(q);\r
-        }\r
-        s = s->next;\r
-      }\r
-\r
-      nm.arena    = sum;\r
-      nm.ordblks  = nfree;\r
-      nm.hblkhd   = m->footprint - sum;\r
-      nm.usmblks  = m->max_footprint;\r
-      nm.uordblks = m->footprint - mfree;\r
-      nm.fordblks = mfree;\r
-      nm.keepcost = m->topsize;\r
-    }\r
-\r
-    POSTACTION(m);\r
-  }\r
-  return nm;\r
-}\r
-#endif /* !NO_MALLINFO */\r
-\r
-#if !NO_MALLOC_STATS\r
-static void internal_malloc_stats(mstate m) {\r
-  ensure_initialization();\r
-  if (!PREACTION(m)) {\r
-    size_t maxfp = 0;\r
-    size_t fp = 0;\r
-    size_t used = 0;\r
-    check_malloc_state(m);\r
-    if (is_initialized(m)) {\r
-      msegmentptr s = &m->seg;\r
-      maxfp = m->max_footprint;\r
-      fp = m->footprint;\r
-      used = fp - (m->topsize + TOP_FOOT_SIZE);\r
-\r
-      while (s != 0) {\r
-        mchunkptr q = align_as_chunk(s->base);\r
-        while (segment_holds(s, q) &&\r
-               q != m->top && q->head != FENCEPOST_HEAD) {\r
-          if (!is_inuse(q))\r
-            used -= chunksize(q);\r
-          q = next_chunk(q);\r
-        }\r
-        s = s->next;\r
-      }\r
-    }\r
-    POSTACTION(m); /* drop lock */\r
-    fprintf(stderr, "max system bytes = %10lu\n", (unsigned long)(maxfp));\r
-    fprintf(stderr, "system bytes     = %10lu\n", (unsigned long)(fp));\r
-    fprintf(stderr, "in use bytes     = %10lu\n", (unsigned long)(used));\r
-  }\r
-}\r
-#endif /* NO_MALLOC_STATS */\r
-\r
-/* ----------------------- Operations on smallbins ----------------------- */\r
-\r
-/*\r
-  Various forms of linking and unlinking are defined as macros.  Even\r
-  the ones for trees, which are very long but have very short typical\r
-  paths.  This is ugly but reduces reliance on inlining support of\r
-  compilers.\r
-*/\r
-\r
-/* Link a free chunk into a smallbin  */\r
-#define insert_small_chunk(M, P, S) {\\r
-  bindex_t I  = small_index(S);\\r
-  mchunkptr B = smallbin_at(M, I);\\r
-  mchunkptr F = B;\\r
-  assert(S >= MIN_CHUNK_SIZE);\\r
-  if (!smallmap_is_marked(M, I))\\r
-    mark_smallmap(M, I);\\r
-  else if (RTCHECK(ok_address(M, B->fd)))\\r
-    F = B->fd;\\r
-  else {\\r
-    CORRUPTION_ERROR_ACTION(M);\\r
-  }\\r
-  B->fd = P;\\r
-  F->bk = P;\\r
-  P->fd = F;\\r
-  P->bk = B;\\r
-}\r
-\r
-/* Unlink a chunk from a smallbin  */\r
-#define unlink_small_chunk(M, P, S) {\\r
-  mchunkptr F = P->fd;\\r
-  mchunkptr B = P->bk;\\r
-  bindex_t I = small_index(S);\\r
-  assert(P != B);\\r
-  assert(P != F);\\r
-  assert(chunksize(P) == small_index2size(I));\\r
-  if (RTCHECK(F == smallbin_at(M,I) || (ok_address(M, F) && F->bk == P))) { \\r
-    if (B == F) {\\r
-      clear_smallmap(M, I);\\r
-    }\\r
-    else if (RTCHECK(B == smallbin_at(M,I) ||\\r
-                     (ok_address(M, B) && B->fd == P))) {\\r
-      F->bk = B;\\r
-      B->fd = F;\\r
-    }\\r
-    else {\\r
-      CORRUPTION_ERROR_ACTION(M);\\r
-    }\\r
-  }\\r
-  else {\\r
-    CORRUPTION_ERROR_ACTION(M);\\r
-  }\\r
-}\r
-\r
-/* Unlink the first chunk from a smallbin */\r
-#define unlink_first_small_chunk(M, B, P, I) {\\r
-  mchunkptr F = P->fd;\\r
-  assert(P != B);\\r
-  assert(P != F);\\r
-  assert(chunksize(P) == small_index2size(I));\\r
-  if (B == F) {\\r
-    clear_smallmap(M, I);\\r
-  }\\r
-  else if (RTCHECK(ok_address(M, F) && F->bk == P)) {\\r
-    F->bk = B;\\r
-    B->fd = F;\\r
-  }\\r
-  else {\\r
-    CORRUPTION_ERROR_ACTION(M);\\r
-  }\\r
-}\r
-\r
-/* Replace dv node, binning the old one */\r
-/* Used only when dvsize known to be small */\r
-#define replace_dv(M, P, S) {\\r
-  size_t DVS = M->dvsize;\\r
-  assert(is_small(DVS));\\r
-  if (DVS != 0) {\\r
-    mchunkptr DV = M->dv;\\r
-    insert_small_chunk(M, DV, DVS);\\r
-  }\\r
-  M->dvsize = S;\\r
-  M->dv = P;\\r
-}\r
-\r
-/* ------------------------- Operations on trees ------------------------- */\r
-\r
-/* Insert chunk into tree */\r
-#define insert_large_chunk(M, X, S) {\\r
-  tbinptr* H;\\r
-  bindex_t I;\\r
-  compute_tree_index(S, I);\\r
-  H = treebin_at(M, I);\\r
-  X->index = I;\\r
-  X->child[0] = X->child[1] = 0;\\r
-  if (!treemap_is_marked(M, I)) {\\r
-    mark_treemap(M, I);\\r
-    *H = X;\\r
-    X->parent = (tchunkptr)H;\\r
-    X->fd = X->bk = X;\\r
-  }\\r
-  else {\\r
-    tchunkptr T = *H;\\r
-    size_t K = S << leftshift_for_tree_index(I);\\r
-    for (;;) {\\r
-      if (chunksize(T) != S) {\\r
-        tchunkptr* C = &(T->child[(K >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]);\\r
-        K <<= 1;\\r
-        if (*C != 0)\\r
-          T = *C;\\r
-        else if (RTCHECK(ok_address(M, C))) {\\r
-          *C = X;\\r
-          X->parent = T;\\r
-          X->fd = X->bk = X;\\r
-          break;\\r
-        }\\r
-        else {\\r
-          CORRUPTION_ERROR_ACTION(M);\\r
-          break;\\r
-        }\\r
-      }\\r
-      else {\\r
-        tchunkptr F = T->fd;\\r
-        if (RTCHECK(ok_address(M, T) && ok_address(M, F))) {\\r
-          T->fd = F->bk = X;\\r
-          X->fd = F;\\r
-          X->bk = T;\\r
-          X->parent = 0;\\r
-          break;\\r
-        }\\r
-        else {\\r
-          CORRUPTION_ERROR_ACTION(M);\\r
-          break;\\r
-        }\\r
-      }\\r
-    }\\r
-  }\\r
-}\r
-\r
-/*\r
-  Unlink steps:\r
-\r
-  1. If x is a chained node, unlink it from its same-sized fd/bk links\r
-     and choose its bk node as its replacement.\r
-  2. If x was the last node of its size, but not a leaf node, it must\r
-     be replaced with a leaf node (not merely one with an open left or\r
-     right), to make sure that lefts and rights of descendents\r
-     correspond properly to bit masks.  We use the rightmost descendent\r
-     of x.  We could use any other leaf, but this is easy to locate and\r
-     tends to counteract removal of leftmosts elsewhere, and so keeps\r
-     paths shorter than minimally guaranteed.  This doesn't loop much\r
-     because on average a node in a tree is near the bottom.\r
-  3. If x is the base of a chain (i.e., has parent links) relink\r
-     x's parent and children to x's replacement (or null if none).\r
-*/\r
-\r
-#define unlink_large_chunk(M, X) {\\r
-  tchunkptr XP = X->parent;\\r
-  tchunkptr R;\\r
-  if (X->bk != X) {\\r
-    tchunkptr F = X->fd;\\r
-    R = X->bk;\\r
-    if (RTCHECK(ok_address(M, F) && F->bk == X && R->fd == X)) {\\r
-      F->bk = R;\\r
-      R->fd = F;\\r
-    }\\r
-    else {\\r
-      CORRUPTION_ERROR_ACTION(M);\\r
-    }\\r
-  }\\r
-  else {\\r
-    tchunkptr* RP;\\r
-    if (((R = *(RP = &(X->child[1]))) != 0) ||\\r
-        ((R = *(RP = &(X->child[0]))) != 0)) {\\r
-      tchunkptr* CP;\\r
-      while ((*(CP = &(R->child[1])) != 0) ||\\r
-             (*(CP = &(R->child[0])) != 0)) {\\r
-        R = *(RP = CP);\\r
-      }\\r
-      if (RTCHECK(ok_address(M, RP)))\\r
-        *RP = 0;\\r
-      else {\\r
-        CORRUPTION_ERROR_ACTION(M);\\r
-      }\\r
-    }\\r
-  }\\r
-  if (XP != 0) {\\r
-    tbinptr* H = treebin_at(M, X->index);\\r
-    if (X == *H) {\\r
-      if ((*H = R) == 0) \\r
-        clear_treemap(M, X->index);\\r
-    }\\r
-    else if (RTCHECK(ok_address(M, XP))) {\\r
-      if (XP->child[0] == X) \\r
-        XP->child[0] = R;\\r
-      else \\r
-        XP->child[1] = R;\\r
-    }\\r
-    else\\r
-      CORRUPTION_ERROR_ACTION(M);\\r
-    if (R != 0) {\\r
-      if (RTCHECK(ok_address(M, R))) {\\r
-        tchunkptr C0, C1;\\r
-        R->parent = XP;\\r
-        if ((C0 = X->child[0]) != 0) {\\r
-          if (RTCHECK(ok_address(M, C0))) {\\r
-            R->child[0] = C0;\\r
-            C0->parent = R;\\r
-          }\\r
-          else\\r
-            CORRUPTION_ERROR_ACTION(M);\\r
-        }\\r
-        if ((C1 = X->child[1]) != 0) {\\r
-          if (RTCHECK(ok_address(M, C1))) {\\r
-            R->child[1] = C1;\\r
-            C1->parent = R;\\r
-          }\\r
-          else\\r
-            CORRUPTION_ERROR_ACTION(M);\\r
-        }\\r
-      }\\r
-      else\\r
-        CORRUPTION_ERROR_ACTION(M);\\r
-    }\\r
-  }\\r
-}\r
-\r
-/* Relays to large vs small bin operations */\r
-\r
-#define insert_chunk(M, P, S)\\r
-  if (is_small(S)) insert_small_chunk(M, P, S)\\r
-  else { tchunkptr TP = (tchunkptr)(P); insert_large_chunk(M, TP, S); }\r
-\r
-#define unlink_chunk(M, P, S)\\r
-  if (is_small(S)) unlink_small_chunk(M, P, S)\\r
-  else { tchunkptr TP = (tchunkptr)(P); unlink_large_chunk(M, TP); }\r
-\r
-\r
-/* Relays to internal calls to malloc/free from realloc, memalign etc */\r
-\r
-#if ONLY_MSPACES\r
-#define internal_malloc(m, b) mspace_malloc(m, b)\r
-#define internal_free(m, mem) mspace_free(m,mem);\r
-#else /* ONLY_MSPACES */\r
-#if MSPACES\r
-#define internal_malloc(m, b)\\r
-  ((m == gm)? dlmalloc(b) : mspace_malloc(m, b))\r
-#define internal_free(m, mem)\\r
-   if (m == gm) dlfree(mem); else mspace_free(m,mem);\r
-#else /* MSPACES */\r
-#define internal_malloc(m, b) dlmalloc(b)\r
-#define internal_free(m, mem) dlfree(mem)\r
-#endif /* MSPACES */\r
-#endif /* ONLY_MSPACES */\r
-\r
-/* -----------------------  Direct-mmapping chunks ----------------------- */\r
-\r
-/*\r
-  Directly mmapped chunks are set up with an offset to the start of\r
-  the mmapped region stored in the prev_foot field of the chunk. This\r
-  allows reconstruction of the required argument to MUNMAP when freed,\r
-  and also allows adjustment of the returned chunk to meet alignment\r
-  requirements (especially in memalign).\r
-*/\r
-\r
-/* Malloc using mmap */\r
-static void* mmap_alloc(mstate m, size_t nb) {\r
-  size_t mmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK);\r
-  if (m->footprint_limit != 0) {\r
-    size_t fp = m->footprint + mmsize;\r
-    if (fp <= m->footprint || fp > m->footprint_limit)\r
-      return 0;\r
-  }\r
-  if (mmsize > nb) {     /* Check for wrap around 0 */\r
-    char* mm = (char*)(CALL_DIRECT_MMAP(mmsize));\r
-    if (mm != CMFAIL) {\r
-      size_t offset = align_offset(chunk2mem(mm));\r
-      size_t psize = mmsize - offset - MMAP_FOOT_PAD;\r
-      mchunkptr p = (mchunkptr)(mm + offset);\r
-      p->prev_foot = offset;\r
-      p->head = psize;\r
-      mark_inuse_foot(m, p, psize);\r
-      chunk_plus_offset(p, psize)->head = FENCEPOST_HEAD;\r
-      chunk_plus_offset(p, psize+SIZE_T_SIZE)->head = 0;\r
-\r
-      if (m->least_addr == 0 || mm < m->least_addr)\r
-        m->least_addr = mm;\r
-      if ((m->footprint += mmsize) > m->max_footprint)\r
-        m->max_footprint = m->footprint;\r
-      assert(is_aligned(chunk2mem(p)));\r
-      check_mmapped_chunk(m, p);\r
-      return chunk2mem(p);\r
-    }\r
-  }\r
-  return 0;\r
-}\r
-\r
-/* Realloc using mmap */\r
-static mchunkptr mmap_resize(mstate m, mchunkptr oldp, size_t nb, int flags) {\r
-  size_t oldsize = chunksize(oldp);\r
-  (void) flags;\r
-  if (is_small(nb)) /* Can't shrink mmap regions below small size */\r
-    return 0;\r
-  /* Keep old chunk if big enough but not too big */\r
-  if (oldsize >= nb + SIZE_T_SIZE &&\r
-      (oldsize - nb) <= (mparams.granularity << 1))\r
-    return oldp;\r
-  else {\r
-    size_t offset = oldp->prev_foot;\r
-    size_t oldmmsize = oldsize + offset + MMAP_FOOT_PAD;\r
-    size_t newmmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK);\r
-    char* cp = (char*)CALL_MREMAP((char*)oldp - offset,\r
-                                  oldmmsize, newmmsize, flags);\r
-    if (cp != CMFAIL) {\r
-      mchunkptr newp = (mchunkptr)(cp + offset);\r
-      size_t psize = newmmsize - offset - MMAP_FOOT_PAD;\r
-      newp->head = psize;\r
-      mark_inuse_foot(m, newp, psize);\r
-      chunk_plus_offset(newp, psize)->head = FENCEPOST_HEAD;\r
-      chunk_plus_offset(newp, psize+SIZE_T_SIZE)->head = 0;\r
-\r
-      if (cp < m->least_addr)\r
-        m->least_addr = cp;\r
-      if ((m->footprint += newmmsize - oldmmsize) > m->max_footprint)\r
-        m->max_footprint = m->footprint;\r
-      check_mmapped_chunk(m, newp);\r
-      return newp;\r
-    }\r
-  }\r
-  return 0;\r
-}\r
-\r
-\r
-/* -------------------------- mspace management -------------------------- */\r
-\r
-/* Initialize top chunk and its size */\r
-static void init_top(mstate m, mchunkptr p, size_t psize) {\r
-  /* Ensure alignment */\r
-  size_t offset = align_offset(chunk2mem(p));\r
-  p = (mchunkptr)((char*)p + offset);\r
-  psize -= offset;\r
-\r
-  m->top = p;\r
-  m->topsize = psize;\r
-  p->head = psize | PINUSE_BIT;\r
-  /* set size of fake trailing chunk holding overhead space only once */\r
-  chunk_plus_offset(p, psize)->head = TOP_FOOT_SIZE;\r
-  m->trim_check = mparams.trim_threshold; /* reset on each update */\r
-}\r
-\r
-/* Initialize bins for a new mstate that is otherwise zeroed out */\r
-static void init_bins(mstate m) {\r
-  /* Establish circular links for smallbins */\r
-  bindex_t i;\r
-  for (i = 0; i < NSMALLBINS; ++i) {\r
-    sbinptr bin = smallbin_at(m,i);\r
-    bin->fd = bin->bk = bin;\r
-  }\r
-}\r
-\r
-#if PROCEED_ON_ERROR\r
-\r
-/* default corruption action */\r
-static void reset_on_error(mstate m) {\r
-  int i;\r
-  ++malloc_corruption_error_count;\r
-  /* Reinitialize fields to forget about all memory */\r
-  m->smallmap = m->treemap = 0;\r
-  m->dvsize = m->topsize = 0;\r
-  m->seg.base = 0;\r
-  m->seg.size = 0;\r
-  m->seg.next = 0;\r
-  m->top = m->dv = 0;\r
-  for (i = 0; i < NTREEBINS; ++i)\r
-    *treebin_at(m, i) = 0;\r
-  init_bins(m);\r
-}\r
-#endif /* PROCEED_ON_ERROR */\r
-\r
-/* Allocate chunk and prepend remainder with chunk in successor base. */\r
-static void* prepend_alloc(mstate m, char* newbase, char* oldbase,\r
-                           size_t nb) {\r
-  mchunkptr p = align_as_chunk(newbase);\r
-  mchunkptr oldfirst = align_as_chunk(oldbase);\r
-  size_t psize = (char*)oldfirst - (char*)p;\r
-  mchunkptr q = chunk_plus_offset(p, nb);\r
-  size_t qsize = psize - nb;\r
-  set_size_and_pinuse_of_inuse_chunk(m, p, nb);\r
-\r
-  assert((char*)oldfirst > (char*)q);\r
-  assert(pinuse(oldfirst));\r
-  assert(qsize >= MIN_CHUNK_SIZE);\r
-\r
-  /* consolidate remainder with first chunk of old base */\r
-  if (oldfirst == m->top) {\r
-    size_t tsize = m->topsize += qsize;\r
-    m->top = q;\r
-    q->head = tsize | PINUSE_BIT;\r
-    check_top_chunk(m, q);\r
-  }\r
-  else if (oldfirst == m->dv) {\r
-    size_t dsize = m->dvsize += qsize;\r
-    m->dv = q;\r
-    set_size_and_pinuse_of_free_chunk(q, dsize);\r
-  }\r
-  else {\r
-    if (!is_inuse(oldfirst)) {\r
-      size_t nsize = chunksize(oldfirst);\r
-      unlink_chunk(m, oldfirst, nsize);\r
-      oldfirst = chunk_plus_offset(oldfirst, nsize);\r
-      qsize += nsize;\r
-    }\r
-    set_free_with_pinuse(q, qsize, oldfirst);\r
-    insert_chunk(m, q, qsize);\r
-    check_free_chunk(m, q);\r
-  }\r
-\r
-  check_malloced_chunk(m, chunk2mem(p), nb);\r
-  return chunk2mem(p);\r
-}\r
-\r
-/* Add a segment to hold a new noncontiguous region */\r
-static void add_segment(mstate m, char* tbase, size_t tsize, flag_t mmapped) {\r
-  /* Determine locations and sizes of segment, fenceposts, old top */\r
-  char* old_top = (char*)m->top;\r
-  msegmentptr oldsp = segment_holding(m, old_top);\r
-  char* old_end = oldsp->base + oldsp->size;\r
-  size_t ssize = pad_request(sizeof(struct malloc_segment));\r
-  char* rawsp = old_end - (ssize + FOUR_SIZE_T_SIZES + CHUNK_ALIGN_MASK);\r
-  size_t offset = align_offset(chunk2mem(rawsp));\r
-  char* asp = rawsp + offset;\r
-  char* csp = (asp < (old_top + MIN_CHUNK_SIZE))? old_top : asp;\r
-  mchunkptr sp = (mchunkptr)csp;\r
-  msegmentptr ss = (msegmentptr)(chunk2mem(sp));\r
-  mchunkptr tnext = chunk_plus_offset(sp, ssize);\r
-  mchunkptr p = tnext;\r
-  int nfences = 0;\r
-\r
-  /* reset top to new space */\r
-  init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE);\r
-\r
-  /* Set up segment record */\r
-  assert(is_aligned(ss));\r
-  set_size_and_pinuse_of_inuse_chunk(m, sp, ssize);\r
-  *ss = m->seg; /* Push current record */\r
-  m->seg.base = tbase;\r
-  m->seg.size = tsize;\r
-  m->seg.sflags = mmapped;\r
-  m->seg.next = ss;\r
-\r
-  /* Insert trailing fenceposts */\r
-  for (;;) {\r
-    mchunkptr nextp = chunk_plus_offset(p, SIZE_T_SIZE);\r
-    p->head = FENCEPOST_HEAD;\r
-    ++nfences;\r
-    if ((char*)(&(nextp->head)) < old_end)\r
-      p = nextp;\r
-    else\r
-      break;\r
-  }\r
-  assert(nfences >= 2);\r
-\r
-  /* Insert the rest of old top into a bin as an ordinary free chunk */\r
-  if (csp != old_top) {\r
-    mchunkptr q = (mchunkptr)old_top;\r
-    size_t psize = csp - old_top;\r
-    mchunkptr tn = chunk_plus_offset(q, psize);\r
-    set_free_with_pinuse(q, psize, tn);\r
-    insert_chunk(m, q, psize);\r
-  }\r
-\r
-  check_top_chunk(m, m->top);\r
-}\r
-\r
-/* -------------------------- System allocation -------------------------- */\r
-\r
-/* Get memory from system using MORECORE or MMAP */\r
-static void* sys_alloc(mstate m, size_t nb) {\r
-  char* tbase = CMFAIL;\r
-  size_t tsize = 0;\r
-  flag_t mmap_flag = 0;\r
-  size_t asize; /* allocation size */\r
-\r
-  ensure_initialization();\r
-\r
-  /* Directly map large chunks, but only if already initialized */\r
-  if (use_mmap(m) && nb >= mparams.mmap_threshold && m->topsize != 0) {\r
-    void* mem = mmap_alloc(m, nb);\r
-    if (mem != 0)\r
-      return mem;\r
-  }\r
-\r
-  asize = granularity_align(nb + SYS_ALLOC_PADDING);\r
-  if (asize <= nb)\r
-    return 0; /* wraparound */\r
-  if (m->footprint_limit != 0) {\r
-    size_t fp = m->footprint + asize;\r
-    if (fp <= m->footprint || fp > m->footprint_limit)\r
-      return 0;\r
-  }\r
-\r
-  /*\r
-    Try getting memory in any of three ways (in most-preferred to\r
-    least-preferred order):\r
-    1. A call to MORECORE that can normally contiguously extend memory.\r
-       (disabled if not MORECORE_CONTIGUOUS or not HAVE_MORECORE or\r
-       or main space is mmapped or a previous contiguous call failed)\r
-    2. A call to MMAP new space (disabled if not HAVE_MMAP).\r
-       Note that under the default settings, if MORECORE is unable to\r
-       fulfill a request, and HAVE_MMAP is true, then mmap is\r
-       used as a noncontiguous system allocator. This is a useful backup\r
-       strategy for systems with holes in address spaces -- in this case\r
-       sbrk cannot contiguously expand the heap, but mmap may be able to\r
-       find space.\r
-    3. A call to MORECORE that cannot usually contiguously extend memory.\r
-       (disabled if not HAVE_MORECORE)\r
-\r
-   In all cases, we need to request enough bytes from system to ensure\r
-   we can malloc nb bytes upon success, so pad with enough space for\r
-   top_foot, plus alignment-pad to make sure we don't lose bytes if\r
-   not on boundary, and round this up to a granularity unit.\r
-  */\r
-\r
-  if (MORECORE_CONTIGUOUS && !use_noncontiguous(m)) {\r
-    char* br = CMFAIL;\r
-    msegmentptr ss = (m->top == 0)? 0 : segment_holding(m, (char*)m->top);\r
-    ACQUIRE_MALLOC_GLOBAL_LOCK();\r
-\r
-    if (ss == 0) {  /* First time through or recovery */\r
-      char* base = (char*)CALL_MORECORE(0);\r
-      if (base != CMFAIL) {\r
-        size_t fp;\r
-        /* Adjust to end on a page boundary */\r
-        if (!is_page_aligned(base))\r
-          asize += (page_align((size_t)base) - (size_t)base);\r
-        fp = m->footprint + asize; /* recheck limits */\r
-        if (asize > nb && asize < HALF_MAX_SIZE_T &&\r
-            (m->footprint_limit == 0 ||\r
-             (fp > m->footprint && fp <= m->footprint_limit)) &&\r
-            (br = (char*)(CALL_MORECORE(asize))) == base) {\r
-          tbase = base;\r
-          tsize = asize;\r
-        }\r
-      }\r
-    }\r
-    else {\r
-      /* Subtract out existing available top space from MORECORE request. */\r
-      asize = granularity_align(nb - m->topsize + SYS_ALLOC_PADDING);\r
-      /* Use mem here only if it did continuously extend old space */\r
-      if (asize < HALF_MAX_SIZE_T &&\r
-          (br = (char*)(CALL_MORECORE(asize))) == ss->base+ss->size) {\r
-        tbase = br;\r
-        tsize = asize;\r
-      }\r
-    }\r
-\r
-    if (tbase == CMFAIL) {    /* Cope with partial failure */\r
-      if (br != CMFAIL) {    /* Try to use/extend the space we did get */\r
-        if (asize < HALF_MAX_SIZE_T &&\r
-            asize < nb + SYS_ALLOC_PADDING) {\r
-          size_t esize = granularity_align(nb + SYS_ALLOC_PADDING - asize);\r
-          if (esize < HALF_MAX_SIZE_T) {\r
-            char* end = (char*)CALL_MORECORE(esize);\r
-            if (end != CMFAIL)\r
-              asize += esize;\r
-            else {            /* Can't use; try to release */\r
-              (void) CALL_MORECORE(-asize);\r
-              br = CMFAIL;\r
-            }\r
-          }\r
-        }\r
-      }\r
-      if (br != CMFAIL) {    /* Use the space we did get */\r
-        tbase = br;\r
-        tsize = asize;\r
-      }\r
-      else\r
-        disable_contiguous(m); /* Don't try contiguous path in the future */\r
-    }\r
-\r
-    RELEASE_MALLOC_GLOBAL_LOCK();\r
-  }\r
-\r
-  if (HAVE_MMAP && tbase == CMFAIL) {  /* Try MMAP */\r
-    char* mp = (char*)(CALL_MMAP(asize));\r
-    if (mp != CMFAIL) {\r
-      tbase = mp;\r
-      tsize = asize;\r
-      mmap_flag = USE_MMAP_BIT;\r
-    }\r
-  }\r
-\r
-  if (HAVE_MORECORE && tbase == CMFAIL) { /* Try noncontiguous MORECORE */\r
-    if (asize < HALF_MAX_SIZE_T) {\r
-      char* br = CMFAIL;\r
-      char* end = CMFAIL;\r
-      ACQUIRE_MALLOC_GLOBAL_LOCK();\r
-      br = (char*)(CALL_MORECORE(asize));\r
-      end = (char*)(CALL_MORECORE(0));\r
-      RELEASE_MALLOC_GLOBAL_LOCK();\r
-      if (br != CMFAIL && end != CMFAIL && br < end) {\r
-        size_t ssize = end - br;\r
-        if (ssize > nb + TOP_FOOT_SIZE) {\r
-          tbase = br;\r
-          tsize = ssize;\r
-        }\r
-      }\r
-    }\r
-  }\r
-\r
-  if (tbase != CMFAIL) {\r
-\r
-    if ((m->footprint += tsize) > m->max_footprint)\r
-      m->max_footprint = m->footprint;\r
-\r
-    if (!is_initialized(m)) { /* first-time initialization */\r
-      if (m->least_addr == 0 || tbase < m->least_addr)\r
-        m->least_addr = tbase;\r
-      m->seg.base = tbase;\r
-      m->seg.size = tsize;\r
-      m->seg.sflags = mmap_flag;\r
-      m->magic = mparams.magic;\r
-      m->release_checks = MAX_RELEASE_CHECK_RATE;\r
-      init_bins(m);\r
-#if !ONLY_MSPACES\r
-      if (is_global(m))\r
-        init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE);\r
-      else\r
-#endif\r
-      {\r
-        /* Offset top by embedded malloc_state */\r
-        mchunkptr mn = next_chunk(mem2chunk(m));\r
-        init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) -TOP_FOOT_SIZE);\r
-      }\r
-    }\r
-\r
-    else {\r
-      /* Try to merge with an existing segment */\r
-      msegmentptr sp = &m->seg;\r
-      /* Only consider most recent segment if traversal suppressed */\r
-      while (sp != 0 && tbase != sp->base + sp->size)\r
-        sp = (NO_SEGMENT_TRAVERSAL) ? 0 : sp->next;\r
-      if (sp != 0 &&\r
-          !is_extern_segment(sp) &&\r
-          (sp->sflags & USE_MMAP_BIT) == mmap_flag &&\r
-          segment_holds(sp, m->top)) { /* append */\r
-        sp->size += tsize;\r
-        init_top(m, m->top, m->topsize + tsize);\r
-      }\r
-      else {\r
-        if (tbase < m->least_addr)\r
-          m->least_addr = tbase;\r
-        sp = &m->seg;\r
-        while (sp != 0 && sp->base != tbase + tsize)\r
-          sp = (NO_SEGMENT_TRAVERSAL) ? 0 : sp->next;\r
-        if (sp != 0 &&\r
-            !is_extern_segment(sp) &&\r
-            (sp->sflags & USE_MMAP_BIT) == mmap_flag) {\r
-          char* oldbase = sp->base;\r
-          sp->base = tbase;\r
-          sp->size += tsize;\r
-          return prepend_alloc(m, tbase, oldbase, nb);\r
-        }\r
-        else\r
-          add_segment(m, tbase, tsize, mmap_flag);\r
-      }\r
-    }\r
-\r
-    if (nb < m->topsize) { /* Allocate from new or extended top space */\r
-      size_t rsize = m->topsize -= nb;\r
-      mchunkptr p = m->top;\r
-      mchunkptr r = m->top = chunk_plus_offset(p, nb);\r
-      r->head = rsize | PINUSE_BIT;\r
-      set_size_and_pinuse_of_inuse_chunk(m, p, nb);\r
-      check_top_chunk(m, m->top);\r
-      check_malloced_chunk(m, chunk2mem(p), nb);\r
-      return chunk2mem(p);\r
-    }\r
-  }\r
-\r
-  MALLOC_FAILURE_ACTION;\r
-  return 0;\r
-}\r
-\r
-/* -----------------------  system deallocation -------------------------- */\r
-\r
-/* Unmap and unlink any mmapped segments that don't contain used chunks */\r
-static size_t release_unused_segments(mstate m) {\r
-  size_t released = 0;\r
-  int nsegs = 0;\r
-  msegmentptr pred = &m->seg;\r
-  msegmentptr sp = pred->next;\r
-  while (sp != 0) {\r
-    char* base = sp->base;\r
-    size_t size = sp->size;\r
-    msegmentptr next = sp->next;\r
-    ++nsegs;\r
-    if (is_mmapped_segment(sp) && !is_extern_segment(sp)) {\r
-      mchunkptr p = align_as_chunk(base);\r
-      size_t psize = chunksize(p);\r
-      /* Can unmap if first chunk holds entire segment and not pinned */\r
-      if (!is_inuse(p) && (char*)p + psize >= base + size - TOP_FOOT_SIZE) {\r
-        tchunkptr tp = (tchunkptr)p;\r
-        assert(segment_holds(sp, (char*)sp));\r
-        if (p == m->dv) {\r
-          m->dv = 0;\r
-          m->dvsize = 0;\r
-        }\r
-        else {\r
-          unlink_large_chunk(m, tp);\r
-        }\r
-        if (CALL_MUNMAP(base, size) == 0) {\r
-          released += size;\r
-          m->footprint -= size;\r
-          /* unlink obsoleted record */\r
-          sp = pred;\r
-          sp->next = next;\r
-        }\r
-        else { /* back out if cannot unmap */\r
-          insert_large_chunk(m, tp, psize);\r
-        }\r
-      }\r
-    }\r
-    if (NO_SEGMENT_TRAVERSAL) /* scan only first segment */\r
-      break;\r
-    pred = sp;\r
-    sp = next;\r
-  }\r
-  /* Reset check counter */\r
-  m->release_checks = ((nsegs > MAX_RELEASE_CHECK_RATE)?\r
-                       nsegs : MAX_RELEASE_CHECK_RATE);\r
-  return released;\r
-}\r
-\r
-static int sys_trim(mstate m, size_t pad) {\r
-  size_t released = 0;\r
-  ensure_initialization();\r
-  if (pad < MAX_REQUEST && is_initialized(m)) {\r
-    pad += TOP_FOOT_SIZE; /* ensure enough room for segment overhead */\r
-\r
-    if (m->topsize > pad) {\r
-      /* Shrink top space in granularity-size units, keeping at least one */\r
-      size_t unit = mparams.granularity;\r
-      size_t extra = ((m->topsize - pad + (unit - SIZE_T_ONE)) / unit -\r
-                      SIZE_T_ONE) * unit;\r
-      msegmentptr sp = segment_holding(m, (char*)m->top);\r
-\r
-      if (!is_extern_segment(sp)) {\r
-        if (is_mmapped_segment(sp)) {\r
-          if (HAVE_MMAP &&\r
-              sp->size >= extra &&\r
-              !has_segment_link(m, sp)) { /* can't shrink if pinned */\r
-            size_t newsize = sp->size - extra;\r
-            /* Prefer mremap, fall back to munmap */\r
-            if ((CALL_MREMAP(sp->base, sp->size, newsize, 0) != MFAIL) ||\r
-                (CALL_MUNMAP(sp->base + newsize, extra) == 0)) {\r
-              released = extra;\r
-            }\r
-          }\r
-        }\r
-        else if (HAVE_MORECORE) {\r
-          if (extra >= HALF_MAX_SIZE_T) /* Avoid wrapping negative */\r
-            extra = (HALF_MAX_SIZE_T) + SIZE_T_ONE - unit;\r
-          ACQUIRE_MALLOC_GLOBAL_LOCK();\r
-          {\r
-            /* Make sure end of memory is where we last set it. */\r
-            char* old_br = (char*)(CALL_MORECORE(0));\r
-            if (old_br == sp->base + sp->size) {\r
-              char* rel_br = (char*)(CALL_MORECORE(-extra));\r
-              char* new_br = (char*)(CALL_MORECORE(0));\r
-              if (rel_br != CMFAIL && new_br < old_br)\r
-                released = old_br - new_br;\r
-            }\r
-          }\r
-          RELEASE_MALLOC_GLOBAL_LOCK();\r
-        }\r
-      }\r
-\r
-      if (released != 0) {\r
-        sp->size -= released;\r
-        m->footprint -= released;\r
-        init_top(m, m->top, m->topsize - released);\r
-        check_top_chunk(m, m->top);\r
-      }\r
-    }\r
-\r
-    /* Unmap any unused mmapped segments */\r
-    if (HAVE_MMAP)\r
-      released += release_unused_segments(m);\r
-\r
-    /* On failure, disable autotrim to avoid repeated failed future calls */\r
-    if (released == 0 && m->topsize > m->trim_check)\r
-      m->trim_check = MAX_SIZE_T;\r
-  }\r
-\r
-  return (released != 0)? 1 : 0;\r
-}\r
-\r
-/* Consolidate and bin a chunk. Differs from exported versions\r
-   of free mainly in that the chunk need not be marked as inuse.\r
-*/\r
-static void dispose_chunk(mstate m, mchunkptr p, size_t psize) {\r
-  mchunkptr next = chunk_plus_offset(p, psize);\r
-  if (!pinuse(p)) {\r
-    mchunkptr prev;\r
-    size_t prevsize = p->prev_foot;\r
-    if (is_mmapped(p)) {\r
-      psize += prevsize + MMAP_FOOT_PAD;\r
-      if (CALL_MUNMAP((char*)p - prevsize, psize) == 0)\r
-        m->footprint -= psize;\r
-      return;\r
-    }\r
-    prev = chunk_minus_offset(p, prevsize);\r
-    psize += prevsize;\r
-    p = prev;\r
-    if (RTCHECK(ok_address(m, prev))) { /* consolidate backward */\r
-      if (p != m->dv) {\r
-        unlink_chunk(m, p, prevsize);\r
-      }\r
-      else if ((next->head & INUSE_BITS) == INUSE_BITS) {\r
-        m->dvsize = psize;\r
-        set_free_with_pinuse(p, psize, next);\r
-        return;\r
-      }\r
-    }\r
-    else {\r
-      CORRUPTION_ERROR_ACTION(m);\r
-      return;\r
-    }\r
-  }\r
-  if (RTCHECK(ok_address(m, next))) {\r
-    if (!cinuse(next)) {  /* consolidate forward */\r
-      if (next == m->top) {\r
-        size_t tsize = m->topsize += psize;\r
-        m->top = p;\r
-        p->head = tsize | PINUSE_BIT;\r
-        if (p == m->dv) {\r
-          m->dv = 0;\r
-          m->dvsize = 0;\r
-        }\r
-        return;\r
-      }\r
-      else if (next == m->dv) {\r
-        size_t dsize = m->dvsize += psize;\r
-        m->dv = p;\r
-        set_size_and_pinuse_of_free_chunk(p, dsize);\r
-        return;\r
-      }\r
-      else {\r
-        size_t nsize = chunksize(next);\r
-        psize += nsize;\r
-        unlink_chunk(m, next, nsize);\r
-        set_size_and_pinuse_of_free_chunk(p, psize);\r
-        if (p == m->dv) {\r
-          m->dvsize = psize;\r
-          return;\r
-        }\r
-      }\r
-    }\r
-    else {\r
-      set_free_with_pinuse(p, psize, next);\r
-    }\r
-    insert_chunk(m, p, psize);\r
-  }\r
-  else {\r
-    CORRUPTION_ERROR_ACTION(m);\r
-  }\r
-}\r
-\r
-/* ---------------------------- malloc --------------------------- */\r
-\r
-/* allocate a large request from the best fitting chunk in a treebin */\r
-static void* tmalloc_large(mstate m, size_t nb) {\r
-  tchunkptr v = 0;\r
-  size_t rsize = -nb; /* Unsigned negation */\r
-  tchunkptr t;\r
-  bindex_t idx;\r
-  compute_tree_index(nb, idx);\r
-  if ((t = *treebin_at(m, idx)) != 0) {\r
-    /* Traverse tree for this bin looking for node with size == nb */\r
-    size_t sizebits = nb << leftshift_for_tree_index(idx);\r
-    tchunkptr rst = 0;  /* The deepest untaken right subtree */\r
-    for (;;) {\r
-      tchunkptr rt;\r
-      size_t trem = chunksize(t) - nb;\r
-      if (trem < rsize) {\r
-        v = t;\r
-        if ((rsize = trem) == 0)\r
-          break;\r
-      }\r
-      rt = t->child[1];\r
-      t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1];\r
-      if (rt != 0 && rt != t)\r
-        rst = rt;\r
-      if (t == 0) {\r
-        t = rst; /* set t to least subtree holding sizes > nb */\r
-        break;\r
-      }\r
-      sizebits <<= 1;\r
-    }\r
-  }\r
-  if (t == 0 && v == 0) { /* set t to root of next non-empty treebin */\r
-    binmap_t leftbits = left_bits(idx2bit(idx)) & m->treemap;\r
-    if (leftbits != 0) {\r
-      bindex_t i;\r
-      binmap_t leastbit = least_bit(leftbits);\r
-      compute_bit2idx(leastbit, i);\r
-      t = *treebin_at(m, i);\r
-    }\r
-  }\r
-\r
-  while (t != 0) { /* find smallest of tree or subtree */\r
-    size_t trem = chunksize(t) - nb;\r
-    if (trem < rsize) {\r
-      rsize = trem;\r
-      v = t;\r
-    }\r
-    t = leftmost_child(t);\r
-  }\r
-\r
-  /*  If dv is a better fit, return 0 so malloc will use it */\r
-  if (v != 0 && rsize < (size_t)(m->dvsize - nb)) {\r
-    if (RTCHECK(ok_address(m, v))) { /* split */\r
-      mchunkptr r = chunk_plus_offset(v, nb);\r
-      assert(chunksize(v) == rsize + nb);\r
-      if (RTCHECK(ok_next(v, r))) {\r
-        unlink_large_chunk(m, v);\r
-        if (rsize < MIN_CHUNK_SIZE)\r
-          set_inuse_and_pinuse(m, v, (rsize + nb));\r
-        else {\r
-          set_size_and_pinuse_of_inuse_chunk(m, v, nb);\r
-          set_size_and_pinuse_of_free_chunk(r, rsize);\r
-          insert_chunk(m, r, rsize);\r
-        }\r
-        return chunk2mem(v);\r
-      }\r
-    }\r
-    CORRUPTION_ERROR_ACTION(m);\r
-  }\r
-  return 0;\r
-}\r
-\r
-/* allocate a small request from the best fitting chunk in a treebin */\r
-static void* tmalloc_small(mstate m, size_t nb) {\r
-  tchunkptr t, v;\r
-  size_t rsize;\r
-  bindex_t i;\r
-  binmap_t leastbit = least_bit(m->treemap);\r
-  compute_bit2idx(leastbit, i);\r
-  v = t = *treebin_at(m, i);\r
-  rsize = chunksize(t) - nb;\r
-\r
-  while ((t = leftmost_child(t)) != 0) {\r
-    size_t trem = chunksize(t) - nb;\r
-    if (trem < rsize) {\r
-      rsize = trem;\r
-      v = t;\r
-    }\r
-  }\r
-\r
-  if (RTCHECK(ok_address(m, v))) {\r
-    mchunkptr r = chunk_plus_offset(v, nb);\r
-    assert(chunksize(v) == rsize + nb);\r
-    if (RTCHECK(ok_next(v, r))) {\r
-      unlink_large_chunk(m, v);\r
-      if (rsize < MIN_CHUNK_SIZE)\r
-        set_inuse_and_pinuse(m, v, (rsize + nb));\r
-      else {\r
-        set_size_and_pinuse_of_inuse_chunk(m, v, nb);\r
-        set_size_and_pinuse_of_free_chunk(r, rsize);\r
-        replace_dv(m, r, rsize);\r
-      }\r
-      return chunk2mem(v);\r
-    }\r
-  }\r
-\r
-  CORRUPTION_ERROR_ACTION(m);\r
-  return 0;\r
-}\r
-\r
-#if !ONLY_MSPACES\r
-\r
-void* dlmalloc(size_t bytes) {\r
-  /*\r
-     Basic algorithm:\r
-     If a small request (< 256 bytes minus per-chunk overhead):\r
-       1. If one exists, use a remainderless chunk in associated smallbin.\r
-          (Remainderless means that there are too few excess bytes to\r
-          represent as a chunk.)\r
-       2. If it is big enough, use the dv chunk, which is normally the\r
-          chunk adjacent to the one used for the most recent small request.\r
-       3. If one exists, split the smallest available chunk in a bin,\r
-          saving remainder in dv.\r
-       4. If it is big enough, use the top chunk.\r
-       5. If available, get memory from system and use it\r
-     Otherwise, for a large request:\r
-       1. Find the smallest available binned chunk that fits, and use it\r
-          if it is better fitting than dv chunk, splitting if necessary.\r
-       2. If better fitting than any binned chunk, use the dv chunk.\r
-       3. If it is big enough, use the top chunk.\r
-       4. If request size >= mmap threshold, try to directly mmap this chunk.\r
-       5. If available, get memory from system and use it\r
-\r
-     The ugly goto's here ensure that postaction occurs along all paths.\r
-  */\r
-\r
-#if USE_LOCKS\r
-  ensure_initialization(); /* initialize in sys_alloc if not using locks */\r
-#endif\r
-\r
-  if (!PREACTION(gm)) {\r
-    void* mem;\r
-    size_t nb;\r
-    if (bytes <= MAX_SMALL_REQUEST) {\r
-      bindex_t idx;\r
-      binmap_t smallbits;\r
-      nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes);\r
-      idx = small_index(nb);\r
-      smallbits = gm->smallmap >> idx;\r
-\r
-      if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */\r
-        mchunkptr b, p;\r
-        idx += ~smallbits & 1;       /* Uses next bin if idx empty */\r
-        b = smallbin_at(gm, idx);\r
-        p = b->fd;\r
-        assert(chunksize(p) == small_index2size(idx));\r
-        unlink_first_small_chunk(gm, b, p, idx);\r
-        set_inuse_and_pinuse(gm, p, small_index2size(idx));\r
-        mem = chunk2mem(p);\r
-        check_malloced_chunk(gm, mem, nb);\r
-        goto postaction;\r
-      }\r
-\r
-      else if (nb > gm->dvsize) {\r
-        if (smallbits != 0) { /* Use chunk in next nonempty smallbin */\r
-          mchunkptr b, p, r;\r
-          size_t rsize;\r
-          bindex_t i;\r
-          binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx));\r
-          binmap_t leastbit = least_bit(leftbits);\r
-          compute_bit2idx(leastbit, i);\r
-          b = smallbin_at(gm, i);\r
-          p = b->fd;\r
-          assert(chunksize(p) == small_index2size(i));\r
-          unlink_first_small_chunk(gm, b, p, i);\r
-          rsize = small_index2size(i) - nb;\r
-          /* Fit here cannot be remainderless if 4byte sizes */\r
-          if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE)\r
-            set_inuse_and_pinuse(gm, p, small_index2size(i));\r
-          else {\r
-            set_size_and_pinuse_of_inuse_chunk(gm, p, nb);\r
-            r = chunk_plus_offset(p, nb);\r
-            set_size_and_pinuse_of_free_chunk(r, rsize);\r
-            replace_dv(gm, r, rsize);\r
-          }\r
-          mem = chunk2mem(p);\r
-          check_malloced_chunk(gm, mem, nb);\r
-          goto postaction;\r
-        }\r
-\r
-        else if (gm->treemap != 0 && (mem = tmalloc_small(gm, nb)) != 0) {\r
-          check_malloced_chunk(gm, mem, nb);\r
-          goto postaction;\r
-        }\r
-      }\r
-    }\r
-    else if (bytes >= MAX_REQUEST)\r
-      nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */\r
-    else {\r
-      nb = pad_request(bytes);\r
-      if (gm->treemap != 0 && (mem = tmalloc_large(gm, nb)) != 0) {\r
-        check_malloced_chunk(gm, mem, nb);\r
-        goto postaction;\r
-      }\r
-    }\r
-\r
-    if (nb <= gm->dvsize) {\r
-      size_t rsize = gm->dvsize - nb;\r
-      mchunkptr p = gm->dv;\r
-      if (rsize >= MIN_CHUNK_SIZE) { /* split dv */\r
-        mchunkptr r = gm->dv = chunk_plus_offset(p, nb);\r
-        gm->dvsize = rsize;\r
-        set_size_and_pinuse_of_free_chunk(r, rsize);\r
-        set_size_and_pinuse_of_inuse_chunk(gm, p, nb);\r
-      }\r
-      else { /* exhaust dv */\r
-        size_t dvs = gm->dvsize;\r
-        gm->dvsize = 0;\r
-        gm->dv = 0;\r
-        set_inuse_and_pinuse(gm, p, dvs);\r
-      }\r
-      mem = chunk2mem(p);\r
-      check_malloced_chunk(gm, mem, nb);\r
-      goto postaction;\r
-    }\r
-\r
-    else if (nb < gm->topsize) { /* Split top */\r
-      size_t rsize = gm->topsize -= nb;\r
-      mchunkptr p = gm->top;\r
-      mchunkptr r = gm->top = chunk_plus_offset(p, nb);\r
-      r->head = rsize | PINUSE_BIT;\r
-      set_size_and_pinuse_of_inuse_chunk(gm, p, nb);\r
-      mem = chunk2mem(p);\r
-      check_top_chunk(gm, gm->top);\r
-      check_malloced_chunk(gm, mem, nb);\r
-      goto postaction;\r
-    }\r
-\r
-    mem = sys_alloc(gm, nb);\r
-\r
-  postaction:\r
-    POSTACTION(gm);\r
-    return mem;\r
-  }\r
-\r
-  return 0;\r
-}\r
-\r
-/* ---------------------------- free --------------------------- */\r
-\r
-void dlfree(void* mem) {\r
-  /*\r
-     Consolidate freed chunks with preceeding or succeeding bordering\r
-     free chunks, if they exist, and then place in a bin.  Intermixed\r
-     with special cases for top, dv, mmapped chunks, and usage errors.\r
-  */\r
-\r
-  if (mem != 0) {\r
-    mchunkptr p  = mem2chunk(mem);\r
-#if FOOTERS\r
-    mstate fm = get_mstate_for(p);\r
-    if (!ok_magic(fm)) {\r
-      USAGE_ERROR_ACTION(fm, p);\r
-      return;\r
-    }\r
-#else /* FOOTERS */\r
-#define fm gm\r
-#endif /* FOOTERS */\r
-    if (!PREACTION(fm)) {\r
-      check_inuse_chunk(fm, p);\r
-      if (RTCHECK(ok_address(fm, p) && ok_inuse(p))) {\r
-        size_t psize = chunksize(p);\r
-        mchunkptr next = chunk_plus_offset(p, psize);\r
-        if (!pinuse(p)) {\r
-          size_t prevsize = p->prev_foot;\r
-          if (is_mmapped(p)) {\r
-            psize += prevsize + MMAP_FOOT_PAD;\r
-            if (CALL_MUNMAP((char*)p - prevsize, psize) == 0)\r
-              fm->footprint -= psize;\r
-            goto postaction;\r
-          }\r
-          else {\r
-            mchunkptr prev = chunk_minus_offset(p, prevsize);\r
-            psize += prevsize;\r
-            p = prev;\r
-            if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */\r
-              if (p != fm->dv) {\r
-                unlink_chunk(fm, p, prevsize);\r
-              }\r
-              else if ((next->head & INUSE_BITS) == INUSE_BITS) {\r
-                fm->dvsize = psize;\r
-                set_free_with_pinuse(p, psize, next);\r
-                goto postaction;\r
-              }\r
-            }\r
-            else\r
-              goto erroraction;\r
-          }\r
-        }\r
-\r
-        if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) {\r
-          if (!cinuse(next)) {  /* consolidate forward */\r
-            if (next == fm->top) {\r
-              size_t tsize = fm->topsize += psize;\r
-              fm->top = p;\r
-              p->head = tsize | PINUSE_BIT;\r
-              if (p == fm->dv) {\r
-                fm->dv = 0;\r
-                fm->dvsize = 0;\r
-              }\r
-              if (should_trim(fm, tsize))\r
-                sys_trim(fm, 0);\r
-              goto postaction;\r
-            }\r
-            else if (next == fm->dv) {\r
-              size_t dsize = fm->dvsize += psize;\r
-              fm->dv = p;\r
-              set_size_and_pinuse_of_free_chunk(p, dsize);\r
-              goto postaction;\r
-            }\r
-            else {\r
-              size_t nsize = chunksize(next);\r
-              psize += nsize;\r
-              unlink_chunk(fm, next, nsize);\r
-              set_size_and_pinuse_of_free_chunk(p, psize);\r
-              if (p == fm->dv) {\r
-                fm->dvsize = psize;\r
-                goto postaction;\r
-              }\r
-            }\r
-          }\r
-          else\r
-            set_free_with_pinuse(p, psize, next);\r
-\r
-          if (is_small(psize)) {\r
-            insert_small_chunk(fm, p, psize);\r
-            check_free_chunk(fm, p);\r
-          }\r
-          else {\r
-            tchunkptr tp = (tchunkptr)p;\r
-            insert_large_chunk(fm, tp, psize);\r
-            check_free_chunk(fm, p);\r
-            if (--fm->release_checks == 0)\r
-              release_unused_segments(fm);\r
-          }\r
-          goto postaction;\r
-        }\r
-      }\r
-    erroraction:\r
-      USAGE_ERROR_ACTION(fm, p);\r
-    postaction:\r
-      POSTACTION(fm);\r
-    }\r
-  }\r
-#if !FOOTERS\r
-#undef fm\r
-#endif /* FOOTERS */\r
-}\r
-\r
-void* dlcalloc(size_t n_elements, size_t elem_size) {\r
-  void* mem;\r
-  size_t req = 0;\r
-  if (n_elements != 0) {\r
-    req = n_elements * elem_size;\r
-    if (((n_elements | elem_size) & ~(size_t)0xffff) &&\r
-        (req / n_elements != elem_size))\r
-      req = MAX_SIZE_T; /* force downstream failure on overflow */\r
-  }\r
-  mem = dlmalloc(req);\r
-  if (mem != 0 && calloc_must_clear(mem2chunk(mem)))\r
-    memset(mem, 0, req);\r
-  return mem;\r
-}\r
-\r
-#endif /* !ONLY_MSPACES */\r
-\r
-/* ------------ Internal support for realloc, memalign, etc -------------- */\r
-\r
-/* Try to realloc; only in-place unless can_move true */\r
-static mchunkptr try_realloc_chunk(mstate m, mchunkptr p, size_t nb,\r
-                                   int can_move) {\r
-  mchunkptr newp = 0;\r
-  size_t oldsize = chunksize(p);\r
-  mchunkptr next = chunk_plus_offset(p, oldsize);\r
-  if (RTCHECK(ok_address(m, p) && ok_inuse(p) &&\r
-              ok_next(p, next) && ok_pinuse(next))) {\r
-    if (is_mmapped(p)) {\r
-      newp = mmap_resize(m, p, nb, can_move);\r
-    }\r
-    else if (oldsize >= nb) {             /* already big enough */\r
-      size_t rsize = oldsize - nb;\r
-      if (rsize >= MIN_CHUNK_SIZE) {      /* split off remainder */\r
-        mchunkptr r = chunk_plus_offset(p, nb);\r
-        set_inuse(m, p, nb);\r
-        set_inuse(m, r, rsize);\r
-        dispose_chunk(m, r, rsize);\r
-      }\r
-      newp = p;\r
-    }\r
-    else if (next == m->top) {  /* extend into top */\r
-      if (oldsize + m->topsize > nb) {\r
-        size_t newsize = oldsize + m->topsize;\r
-        size_t newtopsize = newsize - nb;\r
-        mchunkptr newtop = chunk_plus_offset(p, nb);\r
-        set_inuse(m, p, nb);\r
-        newtop->head = newtopsize |PINUSE_BIT;\r
-        m->top = newtop;\r
-        m->topsize = newtopsize;\r
-        newp = p;\r
-      }\r
-    }\r
-    else if (next == m->dv) { /* extend into dv */\r
-      size_t dvs = m->dvsize;\r
-      if (oldsize + dvs >= nb) {\r
-        size_t dsize = oldsize + dvs - nb;\r
-        if (dsize >= MIN_CHUNK_SIZE) {\r
-          mchunkptr r = chunk_plus_offset(p, nb);\r
-          mchunkptr n = chunk_plus_offset(r, dsize);\r
-          set_inuse(m, p, nb);\r
-          set_size_and_pinuse_of_free_chunk(r, dsize);\r
-          clear_pinuse(n);\r
-          m->dvsize = dsize;\r
-          m->dv = r;\r
-        }\r
-        else { /* exhaust dv */\r
-          size_t newsize = oldsize + dvs;\r
-          set_inuse(m, p, newsize);\r
-          m->dvsize = 0;\r
-          m->dv = 0;\r
-        }\r
-        newp = p;\r
-      }\r
-    }\r
-    else if (!cinuse(next)) { /* extend into next free chunk */\r
-      size_t nextsize = chunksize(next);\r
-      if (oldsize + nextsize >= nb) {\r
-        size_t rsize = oldsize + nextsize - nb;\r
-        unlink_chunk(m, next, nextsize);\r
-        if (rsize < MIN_CHUNK_SIZE) {\r
-          size_t newsize = oldsize + nextsize;\r
-          set_inuse(m, p, newsize);\r
-        }\r
-        else {\r
-          mchunkptr r = chunk_plus_offset(p, nb);\r
-          set_inuse(m, p, nb);\r
-          set_inuse(m, r, rsize);\r
-          dispose_chunk(m, r, rsize);\r
-        }\r
-        newp = p;\r
-      }\r
-    }\r
-  }\r
-  else {\r
-    USAGE_ERROR_ACTION(m, oldmem);\r
-  }\r
-  return newp;\r
-}\r
-\r
-static void* internal_memalign(mstate m, size_t alignment, size_t bytes) {\r
-  void* mem = 0;\r
-  if (alignment <  MIN_CHUNK_SIZE) /* must be at least a minimum chunk size */\r
-    alignment = MIN_CHUNK_SIZE;\r
-  if ((alignment & (alignment-SIZE_T_ONE)) != 0) {/* Ensure a power of 2 */\r
-    size_t a = MALLOC_ALIGNMENT << 1;\r
-    while (a < alignment) a <<= 1;\r
-    alignment = a;\r
-  }\r
-  if (bytes >= MAX_REQUEST - alignment) {\r
-    if (m != 0)  { /* Test isn't needed but avoids compiler warning */\r
-      MALLOC_FAILURE_ACTION;\r
-    }\r
-  }\r
-  else {\r
-    size_t nb = request2size(bytes);\r
-    size_t req = nb + alignment + MIN_CHUNK_SIZE - CHUNK_OVERHEAD;\r
-    mem = internal_malloc(m, req);\r
-    if (mem != 0) {\r
-      mchunkptr p = mem2chunk(mem);\r
-      if (PREACTION(m))\r
-        return 0;\r
-      if ((((size_t)(mem)) & (alignment - 1)) != 0) { /* misaligned */\r
-        /*\r
-          Find an aligned spot inside chunk.  Since we need to give\r
-          back leading space in a chunk of at least MIN_CHUNK_SIZE, if\r
-          the first calculation places us at a spot with less than\r
-          MIN_CHUNK_SIZE leader, we can move to the next aligned spot.\r
-          We've allocated enough total room so that this is always\r
-          possible.\r
-        */\r
-        char* br = (char*)mem2chunk((size_t)(((size_t)((char*)mem + alignment -\r
-                                                       SIZE_T_ONE)) &\r
-                                             -alignment));\r
-        char* pos = ((size_t)(br - (char*)(p)) >= MIN_CHUNK_SIZE)?\r
-          br : br+alignment;\r
-        mchunkptr newp = (mchunkptr)pos;\r
-        size_t leadsize = pos - (char*)(p);\r
-        size_t newsize = chunksize(p) - leadsize;\r
-\r
-        if (is_mmapped(p)) { /* For mmapped chunks, just adjust offset */\r
-          newp->prev_foot = p->prev_foot + leadsize;\r
-          newp->head = newsize;\r
-        }\r
-        else { /* Otherwise, give back leader, use the rest */\r
-          set_inuse(m, newp, newsize);\r
-          set_inuse(m, p, leadsize);\r
-          dispose_chunk(m, p, leadsize);\r
-        }\r
-        p = newp;\r
-      }\r
-\r
-      /* Give back spare room at the end */\r
-      if (!is_mmapped(p)) {\r
-        size_t size = chunksize(p);\r
-        if (size > nb + MIN_CHUNK_SIZE) {\r
-          size_t remainder_size = size - nb;\r
-          mchunkptr remainder = chunk_plus_offset(p, nb);\r
-          set_inuse(m, p, nb);\r
-          set_inuse(m, remainder, remainder_size);\r
-          dispose_chunk(m, remainder, remainder_size);\r
-        }\r
-      }\r
-\r
-      mem = chunk2mem(p);\r
-      assert (chunksize(p) >= nb);\r
-      assert(((size_t)mem & (alignment - 1)) == 0);\r
-      check_inuse_chunk(m, p);\r
-      POSTACTION(m);\r
-    }\r
-  }\r
-  return mem;\r
-}\r
-\r
-/*\r
-  Common support for independent_X routines, handling\r
-    all of the combinations that can result.\r
-  The opts arg has:\r
-    bit 0 set if all elements are same size (using sizes[0])\r
-    bit 1 set if elements should be zeroed\r
-*/\r
-static void** ialloc(mstate m,\r
-                     size_t n_elements,\r
-                     size_t* sizes,\r
-                     int opts,\r
-                     void* chunks[]) {\r
-\r
-  size_t    element_size;   /* chunksize of each element, if all same */\r
-  size_t    contents_size;  /* total size of elements */\r
-  size_t    array_size;     /* request size of pointer array */\r
-  void*     mem;            /* malloced aggregate space */\r
-  mchunkptr p;              /* corresponding chunk */\r
-  size_t    remainder_size; /* remaining bytes while splitting */\r
-  void**    marray;         /* either "chunks" or malloced ptr array */\r
-  mchunkptr array_chunk;    /* chunk for malloced ptr array */\r
-  flag_t    was_enabled;    /* to disable mmap */\r
-  size_t    size;\r
-  size_t    i;\r
-\r
-  ensure_initialization();\r
-  /* compute array length, if needed */\r
-  if (chunks != 0) {\r
-    if (n_elements == 0)\r
-      return chunks; /* nothing to do */\r
-    marray = chunks;\r
-    array_size = 0;\r
-  }\r
-  else {\r
-    /* if empty req, must still return chunk representing empty array */\r
-    if (n_elements == 0)\r
-      return (void**)internal_malloc(m, 0);\r
-    marray = 0;\r
-    array_size = request2size(n_elements * (sizeof(void*)));\r
-  }\r
-\r
-  /* compute total element size */\r
-  if (opts & 0x1) { /* all-same-size */\r
-    element_size = request2size(*sizes);\r
-    contents_size = n_elements * element_size;\r
-  }\r
-  else { /* add up all the sizes */\r
-    element_size = 0;\r
-    contents_size = 0;\r
-    for (i = 0; i != n_elements; ++i)\r
-      contents_size += request2size(sizes[i]);\r
-  }\r
-\r
-  size = contents_size + array_size;\r
-\r
-  /*\r
-     Allocate the aggregate chunk.  First disable direct-mmapping so\r
-     malloc won't use it, since we would not be able to later\r
-     free/realloc space internal to a segregated mmap region.\r
-  */\r
-  was_enabled = use_mmap(m);\r
-  disable_mmap(m);\r
-  mem = internal_malloc(m, size - CHUNK_OVERHEAD);\r
-  if (was_enabled)\r
-    enable_mmap(m);\r
-  if (mem == 0)\r
-    return 0;\r
-\r
-  if (PREACTION(m)) return 0;\r
-  p = mem2chunk(mem);\r
-  remainder_size = chunksize(p);\r
-\r
-  assert(!is_mmapped(p));\r
-\r
-  if (opts & 0x2) {       /* optionally clear the elements */\r
-    memset((size_t*)mem, 0, remainder_size - SIZE_T_SIZE - array_size);\r
-  }\r
-\r
-  /* If not provided, allocate the pointer array as final part of chunk */\r
-  if (marray == 0) {\r
-    size_t  array_chunk_size;\r
-    array_chunk = chunk_plus_offset(p, contents_size);\r
-    array_chunk_size = remainder_size - contents_size;\r
-    marray = (void**) (chunk2mem(array_chunk));\r
-    set_size_and_pinuse_of_inuse_chunk(m, array_chunk, array_chunk_size);\r
-    remainder_size = contents_size;\r
-  }\r
-\r
-  /* split out elements */\r
-  for (i = 0; ; ++i) {\r
-    marray[i] = chunk2mem(p);\r
-    if (i != n_elements-1) {\r
-      if (element_size != 0)\r
-        size = element_size;\r
-      else\r
-        size = request2size(sizes[i]);\r
-      remainder_size -= size;\r
-      set_size_and_pinuse_of_inuse_chunk(m, p, size);\r
-      p = chunk_plus_offset(p, size);\r
-    }\r
-    else { /* the final element absorbs any overallocation slop */\r
-      set_size_and_pinuse_of_inuse_chunk(m, p, remainder_size);\r
-      break;\r
-    }\r
-  }\r
-\r
-#if DEBUG\r
-  if (marray != chunks) {\r
-    /* final element must have exactly exhausted chunk */\r
-    if (element_size != 0) {\r
-      assert(remainder_size == element_size);\r
-    }\r
-    else {\r
-      assert(remainder_size == request2size(sizes[i]));\r
-    }\r
-    check_inuse_chunk(m, mem2chunk(marray));\r
-  }\r
-  for (i = 0; i != n_elements; ++i)\r
-    check_inuse_chunk(m, mem2chunk(marray[i]));\r
-\r
-#endif /* DEBUG */\r
-\r
-  POSTACTION(m);\r
-  return marray;\r
-}\r
-\r
-/* Try to free all pointers in the given array.\r
-   Note: this could be made faster, by delaying consolidation,\r
-   at the price of disabling some user integrity checks, We\r
-   still optimize some consolidations by combining adjacent\r
-   chunks before freeing, which will occur often if allocated\r
-   with ialloc or the array is sorted.\r
-*/\r
-static size_t internal_bulk_free(mstate m, void* array[], size_t nelem) {\r
-  size_t unfreed = 0;\r
-  if (!PREACTION(m)) {\r
-    void** a;\r
-    void** fence = &(array[nelem]);\r
-    for (a = array; a != fence; ++a) {\r
-      void* mem = *a;\r
-      if (mem != 0) {\r
-        mchunkptr p = mem2chunk(mem);\r
-        size_t psize = chunksize(p);\r
-#if FOOTERS\r
-        if (get_mstate_for(p) != m) {\r
-          ++unfreed;\r
-          continue;\r
-        }\r
-#endif\r
-        check_inuse_chunk(m, p);\r
-        *a = 0;\r
-        if (RTCHECK(ok_address(m, p) && ok_inuse(p))) {\r
-          void ** b = a + 1; /* try to merge with next chunk */\r
-          mchunkptr next = next_chunk(p);\r
-          if (b != fence && *b == chunk2mem(next)) {\r
-            size_t newsize = chunksize(next) + psize;\r
-            set_inuse(m, p, newsize);\r
-            *b = chunk2mem(p);\r
-          }\r
-          else\r
-            dispose_chunk(m, p, psize);\r
-        }\r
-        else {\r
-          CORRUPTION_ERROR_ACTION(m);\r
-          break;\r
-        }\r
-      }\r
-    }\r
-    if (should_trim(m, m->topsize))\r
-      sys_trim(m, 0);\r
-    POSTACTION(m);\r
-  }\r
-  return unfreed;\r
-}\r
-\r
-/* Traversal */\r
-#if MALLOC_INSPECT_ALL\r
-static void internal_inspect_all(mstate m,\r
-                                 void(*handler)(void *start,\r
-                                                void *end,\r
-                                                size_t used_bytes,\r
-                                                void* callback_arg),\r
-                                 void* arg) {\r
-  if (is_initialized(m)) {\r
-    mchunkptr top = m->top;\r
-    msegmentptr s;\r
-    for (s = &m->seg; s != 0; s = s->next) {\r
-      mchunkptr q = align_as_chunk(s->base);\r
-      while (segment_holds(s, q) && q->head != FENCEPOST_HEAD) {\r
-        mchunkptr next = next_chunk(q);\r
-        size_t sz = chunksize(q);\r
-        size_t used;\r
-        void* start;\r
-        if (is_inuse(q)) {\r
-          used = sz - CHUNK_OVERHEAD; /* must not be mmapped */\r
-          start = chunk2mem(q);\r
-        }\r
-        else {\r
-          used = 0;\r
-          if (is_small(sz)) {     /* offset by possible bookkeeping */\r
-            start = (void*)((char*)q + sizeof(malloc_chunk));\r
-          }\r
-          else {\r
-            start = (void*)((char*)q + sizeof(malloc_tree_chunk));\r
-          }\r
-        }\r
-        if (start < (void*)next)  /* skip if all space is bookkeeping */\r
-          handler(start, next, used, arg);\r
-        if (q == top)\r
-          break;\r
-        q = next;\r
-      }\r
-    }\r
-  }\r
-}\r
-#endif /* MALLOC_INSPECT_ALL */\r
-\r
-/* ------------------ Exported realloc, memalign, etc -------------------- */\r
-\r
-#if !ONLY_MSPACES\r
-\r
-void* dlrealloc(void* oldmem, size_t bytes) {\r
-  void* mem = 0;\r
-  if (oldmem == 0) {\r
-    mem = dlmalloc(bytes);\r
-  }\r
-  else if (bytes >= MAX_REQUEST) {\r
-    MALLOC_FAILURE_ACTION;\r
-  }\r
-#ifdef REALLOC_ZERO_BYTES_FREES\r
-  else if (bytes == 0) {\r
-    dlfree(oldmem);\r
-  }\r
-#endif /* REALLOC_ZERO_BYTES_FREES */\r
-  else {\r
-    size_t nb = request2size(bytes);\r
-    mchunkptr oldp = mem2chunk(oldmem);\r
-#if ! FOOTERS\r
-    mstate m = gm;\r
-#else /* FOOTERS */\r
-    mstate m = get_mstate_for(oldp);\r
-    if (!ok_magic(m)) {\r
-      USAGE_ERROR_ACTION(m, oldmem);\r
-      return 0;\r
-    }\r
-#endif /* FOOTERS */\r
-    if (!PREACTION(m)) {\r
-      mchunkptr newp = try_realloc_chunk(m, oldp, nb, 1);\r
-      POSTACTION(m);\r
-      if (newp != 0) {\r
-        check_inuse_chunk(m, newp);\r
-        mem = chunk2mem(newp);\r
-      }\r
-      else {\r
-        mem = internal_malloc(m, bytes);\r
-        if (mem != 0) {\r
-          size_t oc = chunksize(oldp) - overhead_for(oldp);\r
-          memcpy(mem, oldmem, (oc < bytes)? oc : bytes);\r
-          internal_free(m, oldmem);\r
-        }\r
-      }\r
-    }\r
-  }\r
-  return mem;\r
-}\r
-\r
-void* dlrealloc_in_place(void* oldmem, size_t bytes) {\r
-  void* mem = 0;\r
-  if (oldmem != 0) {\r
-    if (bytes >= MAX_REQUEST) {\r
-      MALLOC_FAILURE_ACTION;\r
-    }\r
-    else {\r
-      size_t nb = request2size(bytes);\r
-      mchunkptr oldp = mem2chunk(oldmem);\r
-#if ! FOOTERS\r
-      mstate m = gm;\r
-#else /* FOOTERS */\r
-      mstate m = get_mstate_for(oldp);\r
-      if (!ok_magic(m)) {\r
-        USAGE_ERROR_ACTION(m, oldmem);\r
-        return 0;\r
-      }\r
-#endif /* FOOTERS */\r
-      if (!PREACTION(m)) {\r
-        mchunkptr newp = try_realloc_chunk(m, oldp, nb, 0);\r
-        POSTACTION(m);\r
-        if (newp == oldp) {\r
-          check_inuse_chunk(m, newp);\r
-          mem = oldmem;\r
-        }\r
-      }\r
-    }\r
-  }\r
-  return mem;\r
-}\r
-\r
-void* dlmemalign(size_t alignment, size_t bytes) {\r
-  if (alignment <= MALLOC_ALIGNMENT) {\r
-    return dlmalloc(bytes);\r
-  }\r
-  return internal_memalign(gm, alignment, bytes);\r
-}\r
-\r
-int dlposix_memalign(void** pp, size_t alignment, size_t bytes) {\r
-  void* mem = 0;\r
-  if (alignment == MALLOC_ALIGNMENT)\r
-    mem = dlmalloc(bytes);\r
-  else {\r
-    size_t d = alignment / sizeof(void*);\r
-    size_t r = alignment % sizeof(void*);\r
-    if (r != 0 || d == 0 || (d & (d-SIZE_T_ONE)) != 0)\r
-      return EINVAL;\r
-    else if (bytes >= MAX_REQUEST - alignment) {\r
-      if (alignment <  MIN_CHUNK_SIZE)\r
-        alignment = MIN_CHUNK_SIZE;\r
-      mem = internal_memalign(gm, alignment, bytes);\r
-    }\r
-  }\r
-  if (mem == 0)\r
-    return ENOMEM;\r
-  else {\r
-    *pp = mem;\r
-    return 0;\r
-  }\r
-}\r
-\r
-void* dlvalloc(size_t bytes) {\r
-  size_t pagesz;\r
-  ensure_initialization();\r
-  pagesz = mparams.page_size;\r
-  return dlmemalign(pagesz, bytes);\r
-}\r
-\r
-void* dlpvalloc(size_t bytes) {\r
-  size_t pagesz;\r
-  ensure_initialization();\r
-  pagesz = mparams.page_size;\r
-  return dlmemalign(pagesz, (bytes + pagesz - SIZE_T_ONE) & ~(pagesz - SIZE_T_ONE));\r
-}\r
-\r
-void** dlindependent_calloc(size_t n_elements, size_t elem_size,\r
-                            void* chunks[]) {\r
-  size_t sz = elem_size; /* serves as 1-element array */\r
-  return ialloc(gm, n_elements, &sz, 3, chunks);\r
-}\r
-\r
-void** dlindependent_comalloc(size_t n_elements, size_t sizes[],\r
-                              void* chunks[]) {\r
-  return ialloc(gm, n_elements, sizes, 0, chunks);\r
-}\r
-\r
-size_t dlbulk_free(void* array[], size_t nelem) {\r
-  return internal_bulk_free(gm, array, nelem);\r
-}\r
-\r
-#if MALLOC_INSPECT_ALL\r
-void dlmalloc_inspect_all(void(*handler)(void *start,\r
-                                         void *end,\r
-                                         size_t used_bytes,\r
-                                         void* callback_arg),\r
-                          void* arg) {\r
-  ensure_initialization();\r
-  if (!PREACTION(gm)) {\r
-    internal_inspect_all(gm, handler, arg);\r
-    POSTACTION(gm);\r
-  }\r
-}\r
-#endif /* MALLOC_INSPECT_ALL */\r
-\r
-int dlmalloc_trim(size_t pad) {\r
-  int result = 0;\r
-  ensure_initialization();\r
-  if (!PREACTION(gm)) {\r
-    result = sys_trim(gm, pad);\r
-    POSTACTION(gm);\r
-  }\r
-  return result;\r
-}\r
-\r
-size_t dlmalloc_footprint(void) {\r
-  return gm->footprint;\r
-}\r
-\r
-size_t dlmalloc_max_footprint(void) {\r
-  return gm->max_footprint;\r
-}\r
-\r
-size_t dlmalloc_footprint_limit(void) {\r
-  size_t maf = gm->footprint_limit;\r
-  return maf == 0 ? MAX_SIZE_T : maf;\r
-}\r
-\r
-size_t dlmalloc_set_footprint_limit(size_t bytes) {\r
-  size_t result;  /* invert sense of 0 */\r
-  if (bytes == 0)\r
-    result = granularity_align(1); /* Use minimal size */\r
-  if (bytes == MAX_SIZE_T)\r
-    result = 0;                    /* disable */\r
-  else\r
-    result = granularity_align(bytes);\r
-  return gm->footprint_limit = result;\r
-}\r
-\r
-#if !NO_MALLINFO\r
-struct mallinfo dlmallinfo(void) {\r
-  return internal_mallinfo(gm);\r
-}\r
-#endif /* NO_MALLINFO */\r
-\r
-#if !NO_MALLOC_STATS\r
-void dlmalloc_stats() {\r
-  internal_malloc_stats(gm);\r
-}\r
-#endif /* NO_MALLOC_STATS */\r
-\r
-int dlmallopt(int param_number, int value) {\r
-  return change_mparam(param_number, value);\r
-}\r
-\r
-size_t dlmalloc_usable_size(void* mem) {\r
-  if (mem != 0) {\r
-    mchunkptr p = mem2chunk(mem);\r
-    if (is_inuse(p))\r
-      return chunksize(p) - overhead_for(p);\r
-  }\r
-  return 0;\r
-}\r
-\r
-#endif /* !ONLY_MSPACES */\r
-\r
-/* ----------------------------- user mspaces ---------------------------- */\r
-\r
-#if MSPACES\r
-\r
-static mstate init_user_mstate(char* tbase, size_t tsize) {\r
-  size_t msize = pad_request(sizeof(struct malloc_state));\r
-  mchunkptr mn;\r
-  mchunkptr msp = align_as_chunk(tbase);\r
-  mstate m = (mstate)(chunk2mem(msp));\r
-  memset(m, 0, msize);\r
-  (void)INITIAL_LOCK(&m->mutex);\r
-  msp->head = (msize|INUSE_BITS);\r
-  m->seg.base = m->least_addr = tbase;\r
-  m->seg.size = m->footprint = m->max_footprint = tsize;\r
-  m->magic = mparams.magic;\r
-  m->release_checks = MAX_RELEASE_CHECK_RATE;\r
-  m->mflags = mparams.default_mflags;\r
-  m->extp = 0;\r
-  m->exts = 0;\r
-  disable_contiguous(m);\r
-  init_bins(m);\r
-  mn = next_chunk(mem2chunk(m));\r
-  init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) - TOP_FOOT_SIZE);\r
-  check_top_chunk(m, m->top);\r
-  return m;\r
-}\r
-\r
-mspace create_mspace(size_t capacity, int locked) {\r
-  mstate m = 0;\r
-  size_t msize;\r
-  ensure_initialization();\r
-  msize = pad_request(sizeof(struct malloc_state));\r
-  if (capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) {\r
-    size_t rs = ((capacity == 0)? mparams.granularity :\r
-                 (capacity + TOP_FOOT_SIZE + msize));\r
-    size_t tsize = granularity_align(rs);\r
-    char* tbase = (char*)(CALL_MMAP(tsize));\r
-    if (tbase != CMFAIL) {\r
-      m = init_user_mstate(tbase, tsize);\r
-      m->seg.sflags = USE_MMAP_BIT;\r
-      set_lock(m, locked);\r
-    }\r
-  }\r
-  return (mspace)m;\r
-}\r
-\r
-mspace create_mspace_with_base(void* base, size_t capacity, int locked) {\r
-  mstate m = 0;\r
-  size_t msize;\r
-  ensure_initialization();\r
-  msize = pad_request(sizeof(struct malloc_state));\r
-  if (capacity > msize + TOP_FOOT_SIZE &&\r
-      capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) {\r
-    m = init_user_mstate((char*)base, capacity);\r
-    m->seg.sflags = EXTERN_BIT;\r
-    set_lock(m, locked);\r
-  }\r
-  return (mspace)m;\r
-}\r
-\r
-int mspace_track_large_chunks(mspace msp, int enable) {\r
-  int ret = 0;\r
-  mstate ms = (mstate)msp;\r
-  if (!PREACTION(ms)) {\r
-    if (!use_mmap(ms))\r
-      ret = 1;\r
-    if (!enable)\r
-      enable_mmap(ms);\r
-    else\r
-      disable_mmap(ms);\r
-    POSTACTION(ms);\r
-  }\r
-  return ret;\r
-}\r
-\r
-size_t destroy_mspace(mspace msp) {\r
-  size_t freed = 0;\r
-  mstate ms = (mstate)msp;\r
-  if (ok_magic(ms)) {\r
-    msegmentptr sp = &ms->seg;\r
-    (void)DESTROY_LOCK(&ms->mutex); /* destroy before unmapped */\r
-    while (sp != 0) {\r
-      char* base = sp->base;\r
-      size_t size = sp->size;\r
-      flag_t flag = sp->sflags;\r
-      sp = sp->next;\r
-      if ((flag & USE_MMAP_BIT) && !(flag & EXTERN_BIT) &&\r
-          CALL_MUNMAP(base, size) == 0)\r
-        freed += size;\r
-    }\r
-  }\r
-  else {\r
-    USAGE_ERROR_ACTION(ms,ms);\r
-  }\r
-  return freed;\r
-}\r
-\r
-/*\r
-  mspace versions of routines are near-clones of the global\r
-  versions. This is not so nice but better than the alternatives.\r
-*/\r
-\r
-void* mspace_malloc(mspace msp, size_t bytes) {\r
-  mstate ms = (mstate)msp;\r
-  if (!ok_magic(ms)) {\r
-    USAGE_ERROR_ACTION(ms,ms);\r
-    return 0;\r
-  }\r
-  if (!PREACTION(ms)) {\r
-    void* mem;\r
-    size_t nb;\r
-    if (bytes <= MAX_SMALL_REQUEST) {\r
-      bindex_t idx;\r
-      binmap_t smallbits;\r
-      nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes);\r
-      idx = small_index(nb);\r
-      smallbits = ms->smallmap >> idx;\r
-\r
-      if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */\r
-        mchunkptr b, p;\r
-        idx += ~smallbits & 1;       /* Uses next bin if idx empty */\r
-        b = smallbin_at(ms, idx);\r
-        p = b->fd;\r
-        assert(chunksize(p) == small_index2size(idx));\r
-        unlink_first_small_chunk(ms, b, p, idx);\r
-        set_inuse_and_pinuse(ms, p, small_index2size(idx));\r
-        mem = chunk2mem(p);\r
-        check_malloced_chunk(ms, mem, nb);\r
-        goto postaction;\r
-      }\r
-\r
-      else if (nb > ms->dvsize) {\r
-        if (smallbits != 0) { /* Use chunk in next nonempty smallbin */\r
-          mchunkptr b, p, r;\r
-          size_t rsize;\r
-          bindex_t i;\r
-          binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx));\r
-          binmap_t leastbit = least_bit(leftbits);\r
-          compute_bit2idx(leastbit, i);\r
-          b = smallbin_at(ms, i);\r
-          p = b->fd;\r
-          assert(chunksize(p) == small_index2size(i));\r
-          unlink_first_small_chunk(ms, b, p, i);\r
-          rsize = small_index2size(i) - nb;\r
-          /* Fit here cannot be remainderless if 4byte sizes */\r
-          if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE)\r
-            set_inuse_and_pinuse(ms, p, small_index2size(i));\r
-          else {\r
-            set_size_and_pinuse_of_inuse_chunk(ms, p, nb);\r
-            r = chunk_plus_offset(p, nb);\r
-            set_size_and_pinuse_of_free_chunk(r, rsize);\r
-            replace_dv(ms, r, rsize);\r
-          }\r
-          mem = chunk2mem(p);\r
-          check_malloced_chunk(ms, mem, nb);\r
-          goto postaction;\r
-        }\r
-\r
-        else if (ms->treemap != 0 && (mem = tmalloc_small(ms, nb)) != 0) {\r
-          check_malloced_chunk(ms, mem, nb);\r
-          goto postaction;\r
-        }\r
-      }\r
-    }\r
-    else if (bytes >= MAX_REQUEST)\r
-      nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */\r
-    else {\r
-      nb = pad_request(bytes);\r
-      if (ms->treemap != 0 && (mem = tmalloc_large(ms, nb)) != 0) {\r
-        check_malloced_chunk(ms, mem, nb);\r
-        goto postaction;\r
-      }\r
-    }\r
-\r
-    if (nb <= ms->dvsize) {\r
-      size_t rsize = ms->dvsize - nb;\r
-      mchunkptr p = ms->dv;\r
-      if (rsize >= MIN_CHUNK_SIZE) { /* split dv */\r
-        mchunkptr r = ms->dv = chunk_plus_offset(p, nb);\r
-        ms->dvsize = rsize;\r
-        set_size_and_pinuse_of_free_chunk(r, rsize);\r
-        set_size_and_pinuse_of_inuse_chunk(ms, p, nb);\r
-      }\r
-      else { /* exhaust dv */\r
-        size_t dvs = ms->dvsize;\r
-        ms->dvsize = 0;\r
-        ms->dv = 0;\r
-        set_inuse_and_pinuse(ms, p, dvs);\r
-      }\r
-      mem = chunk2mem(p);\r
-      check_malloced_chunk(ms, mem, nb);\r
-      goto postaction;\r
-    }\r
-\r
-    else if (nb < ms->topsize) { /* Split top */\r
-      size_t rsize = ms->topsize -= nb;\r
-      mchunkptr p = ms->top;\r
-      mchunkptr r = ms->top = chunk_plus_offset(p, nb);\r
-      r->head = rsize | PINUSE_BIT;\r
-      set_size_and_pinuse_of_inuse_chunk(ms, p, nb);\r
-      mem = chunk2mem(p);\r
-      check_top_chunk(ms, ms->top);\r
-      check_malloced_chunk(ms, mem, nb);\r
-      goto postaction;\r
-    }\r
-\r
-    mem = sys_alloc(ms, nb);\r
-\r
-  postaction:\r
-    POSTACTION(ms);\r
-    return mem;\r
-  }\r
-\r
-  return 0;\r
-}\r
-\r
-void mspace_free(mspace msp, void* mem) {\r
-  if (mem != 0) {\r
-    mchunkptr p  = mem2chunk(mem);\r
-#if FOOTERS\r
-    mstate fm = get_mstate_for(p);\r
-    msp = msp; /* placate people compiling -Wunused */\r
-#else /* FOOTERS */\r
-    mstate fm = (mstate)msp;\r
-#endif /* FOOTERS */\r
-    if (!ok_magic(fm)) {\r
-      USAGE_ERROR_ACTION(fm, p);\r
-      return;\r
-    }\r
-    if (!PREACTION(fm)) {\r
-      check_inuse_chunk(fm, p);\r
-      if (RTCHECK(ok_address(fm, p) && ok_inuse(p))) {\r
-        size_t psize = chunksize(p);\r
-        mchunkptr next = chunk_plus_offset(p, psize);\r
-        if (!pinuse(p)) {\r
-          size_t prevsize = p->prev_foot;\r
-          if (is_mmapped(p)) {\r
-            psize += prevsize + MMAP_FOOT_PAD;\r
-            if (CALL_MUNMAP((char*)p - prevsize, psize) == 0)\r
-              fm->footprint -= psize;\r
-            goto postaction;\r
-          }\r
-          else {\r
-            mchunkptr prev = chunk_minus_offset(p, prevsize);\r
-            psize += prevsize;\r
-            p = prev;\r
-            if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */\r
-              if (p != fm->dv) {\r
-                unlink_chunk(fm, p, prevsize);\r
-              }\r
-              else if ((next->head & INUSE_BITS) == INUSE_BITS) {\r
-                fm->dvsize = psize;\r
-                set_free_with_pinuse(p, psize, next);\r
-                goto postaction;\r
-              }\r
-            }\r
-            else\r
-              goto erroraction;\r
-          }\r
-        }\r
-\r
-        if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) {\r
-          if (!cinuse(next)) {  /* consolidate forward */\r
-            if (next == fm->top) {\r
-              size_t tsize = fm->topsize += psize;\r
-              fm->top = p;\r
-              p->head = tsize | PINUSE_BIT;\r
-              if (p == fm->dv) {\r
-                fm->dv = 0;\r
-                fm->dvsize = 0;\r
-              }\r
-              if (should_trim(fm, tsize))\r
-                sys_trim(fm, 0);\r
-              goto postaction;\r
-            }\r
-            else if (next == fm->dv) {\r
-              size_t dsize = fm->dvsize += psize;\r
-              fm->dv = p;\r
-              set_size_and_pinuse_of_free_chunk(p, dsize);\r
-              goto postaction;\r
-            }\r
-            else {\r
-              size_t nsize = chunksize(next);\r
-              psize += nsize;\r
-              unlink_chunk(fm, next, nsize);\r
-              set_size_and_pinuse_of_free_chunk(p, psize);\r
-              if (p == fm->dv) {\r
-                fm->dvsize = psize;\r
-                goto postaction;\r
-              }\r
-            }\r
-          }\r
-          else\r
-            set_free_with_pinuse(p, psize, next);\r
-\r
-          if (is_small(psize)) {\r
-            insert_small_chunk(fm, p, psize);\r
-            check_free_chunk(fm, p);\r
-          }\r
-          else {\r
-            tchunkptr tp = (tchunkptr)p;\r
-            insert_large_chunk(fm, tp, psize);\r
-            check_free_chunk(fm, p);\r
-            if (--fm->release_checks == 0)\r
-              release_unused_segments(fm);\r
-          }\r
-          goto postaction;\r
-        }\r
-      }\r
-    erroraction:\r
-      USAGE_ERROR_ACTION(fm, p);\r
-    postaction:\r
-      POSTACTION(fm);\r
-    }\r
-  }\r
-}\r
-\r
-void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size) {\r
-  void* mem;\r
-  size_t req = 0;\r
-  mstate ms = (mstate)msp;\r
-  if (!ok_magic(ms)) {\r
-    USAGE_ERROR_ACTION(ms,ms);\r
-    return 0;\r
-  }\r
-  if (n_elements != 0) {\r
-    req = n_elements * elem_size;\r
-    if (((n_elements | elem_size) & ~(size_t)0xffff) &&\r
-        (req / n_elements != elem_size))\r
-      req = MAX_SIZE_T; /* force downstream failure on overflow */\r
-  }\r
-  mem = internal_malloc(ms, req);\r
-  if (mem != 0 && calloc_must_clear(mem2chunk(mem)))\r
-    memset(mem, 0, req);\r
-  return mem;\r
-}\r
-\r
-void* mspace_realloc(mspace msp, void* oldmem, size_t bytes) {\r
-  void* mem = 0;\r
-  if (oldmem == 0) {\r
-    mem = mspace_malloc(msp, bytes);\r
-  }\r
-  else if (bytes >= MAX_REQUEST) {\r
-    MALLOC_FAILURE_ACTION;\r
-  }\r
-#ifdef REALLOC_ZERO_BYTES_FREES\r
-  else if (bytes == 0) {\r
-    mspace_free(msp, oldmem);\r
-  }\r
-#endif /* REALLOC_ZERO_BYTES_FREES */\r
-  else {\r
-    size_t nb = request2size(bytes);\r
-    mchunkptr oldp = mem2chunk(oldmem);\r
-#if ! FOOTERS\r
-    mstate m = (mstate)msp;\r
-#else /* FOOTERS */\r
-    mstate m = get_mstate_for(oldp);\r
-    if (!ok_magic(m)) {\r
-      USAGE_ERROR_ACTION(m, oldmem);\r
-      return 0;\r
-    }\r
-#endif /* FOOTERS */\r
-    if (!PREACTION(m)) {\r
-      mchunkptr newp = try_realloc_chunk(m, oldp, nb, 1);\r
-      POSTACTION(m);\r
-      if (newp != 0) {\r
-        check_inuse_chunk(m, newp);\r
-        mem = chunk2mem(newp);\r
-      }\r
-      else {\r
-        mem = mspace_malloc(m, bytes);\r
-        if (mem != 0) {\r
-          size_t oc = chunksize(oldp) - overhead_for(oldp);\r
-          memcpy(mem, oldmem, (oc < bytes)? oc : bytes);\r
-          mspace_free(m, oldmem);\r
-        }\r
-      }\r
-    }\r
-  }\r
-  return mem;\r
-}\r
-\r
-void* mspace_realloc_in_place(mspace msp, void* oldmem, size_t bytes) {\r
-  void* mem = 0;\r
-  if (oldmem != 0) {\r
-    if (bytes >= MAX_REQUEST) {\r
-      MALLOC_FAILURE_ACTION;\r
-    }\r
-    else {\r
-      size_t nb = request2size(bytes);\r
-      mchunkptr oldp = mem2chunk(oldmem);\r
-#if ! FOOTERS\r
-      mstate m = (mstate)msp;\r
-#else /* FOOTERS */\r
-      mstate m = get_mstate_for(oldp);\r
-      msp = msp; /* placate people compiling -Wunused */\r
-      if (!ok_magic(m)) {\r
-        USAGE_ERROR_ACTION(m, oldmem);\r
-        return 0;\r
-      }\r
-#endif /* FOOTERS */\r
-      if (!PREACTION(m)) {\r
-        mchunkptr newp = try_realloc_chunk(m, oldp, nb, 0);\r
-        POSTACTION(m);\r
-        if (newp == oldp) {\r
-          check_inuse_chunk(m, newp);\r
-          mem = oldmem;\r
-        }\r
-      }\r
-    }\r
-  }\r
-  return mem;\r
-}\r
-\r
-void* mspace_memalign(mspace msp, size_t alignment, size_t bytes) {\r
-  mstate ms = (mstate)msp;\r
-  if (!ok_magic(ms)) {\r
-    USAGE_ERROR_ACTION(ms,ms);\r
-    return 0;\r
-  }\r
-  if (alignment <= MALLOC_ALIGNMENT)\r
-    return mspace_malloc(msp, bytes);\r
-  return internal_memalign(ms, alignment, bytes);\r
-}\r
-\r
-void** mspace_independent_calloc(mspace msp, size_t n_elements,\r
-                                 size_t elem_size, void* chunks[]) {\r
-  size_t sz = elem_size; /* serves as 1-element array */\r
-  mstate ms = (mstate)msp;\r
-  if (!ok_magic(ms)) {\r
-    USAGE_ERROR_ACTION(ms,ms);\r
-    return 0;\r
-  }\r
-  return ialloc(ms, n_elements, &sz, 3, chunks);\r
-}\r
-\r
-void** mspace_independent_comalloc(mspace msp, size_t n_elements,\r
-                                   size_t sizes[], void* chunks[]) {\r
-  mstate ms = (mstate)msp;\r
-  if (!ok_magic(ms)) {\r
-    USAGE_ERROR_ACTION(ms,ms);\r
-    return 0;\r
-  }\r
-  return ialloc(ms, n_elements, sizes, 0, chunks);\r
-}\r
-\r
-size_t mspace_bulk_free(mspace msp, void* array[], size_t nelem) {\r
-  return internal_bulk_free((mstate)msp, array, nelem);\r
-}\r
-\r
-#if MALLOC_INSPECT_ALL\r
-void mspace_inspect_all(mspace msp,\r
-                        void(*handler)(void *start,\r
-                                       void *end,\r
-                                       size_t used_bytes,\r
-                                       void* callback_arg),\r
-                        void* arg) {\r
-  mstate ms = (mstate)msp;\r
-  if (ok_magic(ms)) {\r
-    if (!PREACTION(ms)) {\r
-      internal_inspect_all(ms, handler, arg);\r
-      POSTACTION(ms);\r
-    }\r
-  }\r
-  else {\r
-    USAGE_ERROR_ACTION(ms,ms);\r
-  }\r
-}\r
-#endif /* MALLOC_INSPECT_ALL */\r
-\r
-int mspace_trim(mspace msp, size_t pad) {\r
-  int result = 0;\r
-  mstate ms = (mstate)msp;\r
-  if (ok_magic(ms)) {\r
-    if (!PREACTION(ms)) {\r
-      result = sys_trim(ms, pad);\r
-      POSTACTION(ms);\r
-    }\r
-  }\r
-  else {\r
-    USAGE_ERROR_ACTION(ms,ms);\r
-  }\r
-  return result;\r
-}\r
-\r
-#if !NO_MALLOC_STATS\r
-void mspace_malloc_stats(mspace msp) {\r
-  mstate ms = (mstate)msp;\r
-  if (ok_magic(ms)) {\r
-    internal_malloc_stats(ms);\r
-  }\r
-  else {\r
-    USAGE_ERROR_ACTION(ms,ms);\r
-  }\r
-}\r
-#endif /* NO_MALLOC_STATS */\r
-\r
-size_t mspace_footprint(mspace msp) {\r
-  size_t result = 0;\r
-  mstate ms = (mstate)msp;\r
-  if (ok_magic(ms)) {\r
-    result = ms->footprint;\r
-  }\r
-  else {\r
-    USAGE_ERROR_ACTION(ms,ms);\r
-  }\r
-  return result;\r
-}\r
-\r
-size_t mspace_max_footprint(mspace msp) {\r
-  size_t result = 0;\r
-  mstate ms = (mstate)msp;\r
-  if (ok_magic(ms)) {\r
-    result = ms->max_footprint;\r
-  }\r
-  else {\r
-    USAGE_ERROR_ACTION(ms,ms);\r
-  }\r
-  return result;\r
-}\r
-\r
-size_t mspace_footprint_limit(mspace msp) {\r
-  size_t result = 0;\r
-  mstate ms = (mstate)msp;\r
-  if (ok_magic(ms)) {\r
-    size_t maf = ms->footprint_limit;\r
-    result = (maf == 0) ? MAX_SIZE_T : maf;\r
-  }\r
-  else {\r
-    USAGE_ERROR_ACTION(ms,ms);\r
-  }\r
-  return result;\r
-}\r
-\r
-size_t mspace_set_footprint_limit(mspace msp, size_t bytes) {\r
-  size_t result = 0;\r
-  mstate ms = (mstate)msp;\r
-  if (ok_magic(ms)) {\r
-    if (bytes == 0)\r
-      result = granularity_align(1); /* Use minimal size */\r
-    if (bytes == MAX_SIZE_T)\r
-      result = 0;                    /* disable */\r
-    else\r
-      result = granularity_align(bytes);\r
-    ms->footprint_limit = result;\r
-  }\r
-  else {\r
-    USAGE_ERROR_ACTION(ms,ms);\r
-  }\r
-  return result;\r
-}\r
-\r
-#if !NO_MALLINFO\r
-struct mallinfo mspace_mallinfo(mspace msp) {\r
-  mstate ms = (mstate)msp;\r
-  if (!ok_magic(ms)) {\r
-    USAGE_ERROR_ACTION(ms,ms);\r
-  }\r
-  return internal_mallinfo(ms);\r
-}\r
-#endif /* NO_MALLINFO */\r
-\r
-size_t mspace_usable_size(void* mem) {\r
-  if (mem != 0) {\r
-    mchunkptr p = mem2chunk(mem);\r
-    if (is_inuse(p))\r
-      return chunksize(p) - overhead_for(p);\r
-  }\r
-  return 0;\r
-}\r
-\r
-int mspace_mallopt(int param_number, int value) {\r
-  return change_mparam(param_number, value);\r
-}\r
-\r
-#endif /* MSPACES */\r
-\r
-\r
-/* -------------------- Alternative MORECORE functions ------------------- */\r
-\r
-/*\r
-  Guidelines for creating a custom version of MORECORE:\r
-\r
-  * For best performance, MORECORE should allocate in multiples of pagesize.\r
-  * MORECORE may allocate more memory than requested. (Or even less,\r
-      but this will usually result in a malloc failure.)\r
-  * MORECORE must not allocate memory when given argument zero, but\r
-      instead return one past the end address of memory from previous\r
-      nonzero call.\r
-  * For best performance, consecutive calls to MORECORE with positive\r
-      arguments should return increasing addresses, indicating that\r
-      space has been contiguously extended.\r
-  * Even though consecutive calls to MORECORE need not return contiguous\r
-      addresses, it must be OK for malloc'ed chunks to span multiple\r
-      regions in those cases where they do happen to be contiguous.\r
-  * MORECORE need not handle negative arguments -- it may instead\r
-      just return MFAIL when given negative arguments.\r
-      Negative arguments are always multiples of pagesize. MORECORE\r
-      must not misinterpret negative args as large positive unsigned\r
-      args. You can suppress all such calls from even occurring by defining\r
-      MORECORE_CANNOT_TRIM,\r
-\r
-  As an example alternative MORECORE, here is a custom allocator\r
-  kindly contributed for pre-OSX macOS.  It uses virtually but not\r
-  necessarily physically contiguous non-paged memory (locked in,\r
-  present and won't get swapped out).  You can use it by uncommenting\r
-  this section, adding some #includes, and setting up the appropriate\r
-  defines above:\r
-\r
-      #define MORECORE osMoreCore\r
-\r
-  There is also a shutdown routine that should somehow be called for\r
-  cleanup upon program exit.\r
-\r
-  #define MAX_POOL_ENTRIES 100\r
-  #define MINIMUM_MORECORE_SIZE  (64 * 1024U)\r
-  static int next_os_pool;\r
-  void *our_os_pools[MAX_POOL_ENTRIES];\r
-\r
-  void *osMoreCore(int size)\r
-  {\r
-    void *ptr = 0;\r
-    static void *sbrk_top = 0;\r
-\r
-    if (size > 0)\r
-    {\r
-      if (size < MINIMUM_MORECORE_SIZE)\r
-         size = MINIMUM_MORECORE_SIZE;\r
-      if (CurrentExecutionLevel() == kTaskLevel)\r
-         ptr = PoolAllocateResident(size + RM_PAGE_SIZE, 0);\r
-      if (ptr == 0)\r
-      {\r
-        return (void *) MFAIL;\r
-      }\r
-      // save ptrs so they can be freed during cleanup\r
-      our_os_pools[next_os_pool] = ptr;\r
-      next_os_pool++;\r
-      ptr = (void *) ((((size_t) ptr) + RM_PAGE_MASK) & ~RM_PAGE_MASK);\r
-      sbrk_top = (char *) ptr + size;\r
-      return ptr;\r
-    }\r
-    else if (size < 0)\r
-    {\r
-      // we don't currently support shrink behavior\r
-      return (void *) MFAIL;\r
-    }\r
-    else\r
-    {\r
-      return sbrk_top;\r
-    }\r
-  }\r
-\r
-  // cleanup any allocated memory pools\r
-  // called as last thing before shutting down driver\r
-\r
-  void osCleanupMem(void)\r
-  {\r
-    void **ptr;\r
-\r
-    for (ptr = our_os_pools; ptr < &our_os_pools[MAX_POOL_ENTRIES]; ptr++)\r
-      if (*ptr)\r
-      {\r
-         PoolDeallocate(*ptr);\r
-         *ptr = 0;\r
-      }\r
-  }\r
-\r
-*/\r
-\r
-\r
-/* -----------------------------------------------------------------------\r
-History:\r
-    v2.8.5 Sun May 22 10:26:02 2011  Doug Lea  (dl at gee)\r
-      * Always perform unlink checks unless INSECURE\r
-      * Add posix_memalign.\r
-      * Improve realloc to expand in more cases; expose realloc_in_place.\r
-        Thanks to Peter Buhr for the suggestion.\r
-      * Add footprint_limit, inspect_all, bulk_free. Thanks\r
-        to Barry Hayes and others for the suggestions.\r
-      * Internal refactorings to avoid calls while holding locks\r
-      * Use non-reentrant locks by default. Thanks to Roland McGrath\r
-        for the suggestion.\r
-      * Small fixes to mspace_destroy, reset_on_error.\r
-      * Various configuration extensions/changes. Thanks\r
-         to all who contributed these.\r
-\r
-    V2.8.4a Thu Apr 28 14:39:43 2011 (dl at gee.cs.oswego.edu)\r
-      * Update Creative Commons URL\r
-\r
-    V2.8.4 Wed May 27 09:56:23 2009  Doug Lea  (dl at gee)\r
-      * Use zeros instead of prev foot for is_mmapped\r
-      * Add mspace_track_large_chunks; thanks to Jean Brouwers\r
-      * Fix set_inuse in internal_realloc; thanks to Jean Brouwers\r
-      * Fix insufficient sys_alloc padding when using 16byte alignment\r
-      * Fix bad error check in mspace_footprint\r
-      * Adaptations for ptmalloc; thanks to Wolfram Gloger.\r
-      * Reentrant spin locks; thanks to Earl Chew and others\r
-      * Win32 improvements; thanks to Niall Douglas and Earl Chew\r
-      * Add NO_SEGMENT_TRAVERSAL and MAX_RELEASE_CHECK_RATE options\r
-      * Extension hook in malloc_state\r
-      * Various small adjustments to reduce warnings on some compilers\r
-      * Various configuration extensions/changes for more platforms. Thanks\r
-         to all who contributed these.\r
-\r
-    V2.8.3 Thu Sep 22 11:16:32 2005  Doug Lea  (dl at gee)\r
-      * Add max_footprint functions\r
-      * Ensure all appropriate literals are size_t\r
-      * Fix conditional compilation problem for some #define settings\r
-      * Avoid concatenating segments with the one provided\r
-        in create_mspace_with_base\r
-      * Rename some variables to avoid compiler shadowing warnings\r
-      * Use explicit lock initialization.\r
-      * Better handling of sbrk interference.\r
-      * Simplify and fix segment insertion, trimming and mspace_destroy\r
-      * Reinstate REALLOC_ZERO_BYTES_FREES option from 2.7.x\r
-      * Thanks especially to Dennis Flanagan for help on these.\r
-\r
-    V2.8.2 Sun Jun 12 16:01:10 2005  Doug Lea  (dl at gee)\r
-      * Fix memalign brace error.\r
-\r
-    V2.8.1 Wed Jun  8 16:11:46 2005  Doug Lea  (dl at gee)\r
-      * Fix improper #endif nesting in C++\r
-      * Add explicit casts needed for C++\r
-\r
-    V2.8.0 Mon May 30 14:09:02 2005  Doug Lea  (dl at gee)\r
-      * Use trees for large bins\r
-      * Support mspaces\r
-      * Use segments to unify sbrk-based and mmap-based system allocation,\r
-        removing need for emulation on most platforms without sbrk.\r
-      * Default safety checks\r
-      * Optional footer checks. Thanks to William Robertson for the idea.\r
-      * Internal code refactoring\r
-      * Incorporate suggestions and platform-specific changes.\r
-        Thanks to Dennis Flanagan, Colin Plumb, Niall Douglas,\r
-        Aaron Bachmann,  Emery Berger, and others.\r
-      * Speed up non-fastbin processing enough to remove fastbins.\r
-      * Remove useless cfree() to avoid conflicts with other apps.\r
-      * Remove internal memcpy, memset. Compilers handle builtins better.\r
-      * Remove some options that no one ever used and rename others.\r
-\r
-    V2.7.2 Sat Aug 17 09:07:30 2002  Doug Lea  (dl at gee)\r
-      * Fix malloc_state bitmap array misdeclaration\r
-\r
-    V2.7.1 Thu Jul 25 10:58:03 2002  Doug Lea  (dl at gee)\r
-      * Allow tuning of FIRST_SORTED_BIN_SIZE\r
-      * Use PTR_UINT as type for all ptr->int casts. Thanks to John Belmonte.\r
-      * Better detection and support for non-contiguousness of MORECORE.\r
-        Thanks to Andreas Mueller, Conal Walsh, and Wolfram Gloger\r
-      * Bypass most of malloc if no frees. Thanks To Emery Berger.\r
-      * Fix freeing of old top non-contiguous chunk im sysmalloc.\r
-      * Raised default trim and map thresholds to 256K.\r
-      * Fix mmap-related #defines. Thanks to Lubos Lunak.\r
-      * Fix copy macros; added LACKS_FCNTL_H. Thanks to Neal Walfield.\r
-      * Branch-free bin calculation\r
-      * Default trim and mmap thresholds now 256K.\r
-\r
-    V2.7.0 Sun Mar 11 14:14:06 2001  Doug Lea  (dl at gee)\r
-      * Introduce independent_comalloc and independent_calloc.\r
-        Thanks to Michael Pachos for motivation and help.\r
-      * Make optional .h file available\r
-      * Allow > 2GB requests on 32bit systems.\r
-      * new WIN32 sbrk, mmap, munmap, lock code from <Walter@GeNeSys-e.de>.\r
-        Thanks also to Andreas Mueller <a.mueller at paradatec.de>,\r
-        and Anonymous.\r
-      * Allow override of MALLOC_ALIGNMENT (Thanks to Ruud Waij for\r
-        helping test this.)\r
-      * memalign: check alignment arg\r
-      * realloc: don't try to shift chunks backwards, since this\r
-        leads to  more fragmentation in some programs and doesn't\r
-        seem to help in any others.\r
-      * Collect all cases in malloc requiring system memory into sysmalloc\r
-      * Use mmap as backup to sbrk\r
-      * Place all internal state in malloc_state\r
-      * Introduce fastbins (although similar to 2.5.1)\r
-      * Many minor tunings and cosmetic improvements\r
-      * Introduce USE_PUBLIC_MALLOC_WRAPPERS, USE_MALLOC_LOCK\r
-      * Introduce MALLOC_FAILURE_ACTION, MORECORE_CONTIGUOUS\r
-        Thanks to Tony E. Bennett <tbennett@nvidia.com> and others.\r
-      * Include errno.h to support default failure action.\r
-\r
-    V2.6.6 Sun Dec  5 07:42:19 1999  Doug Lea  (dl at gee)\r
-      * return null for negative arguments\r
-      * Added Several WIN32 cleanups from Martin C. Fong <mcfong at yahoo.com>\r
-         * Add 'LACKS_SYS_PARAM_H' for those systems without 'sys/param.h'\r
-          (e.g. WIN32 platforms)\r
-         * Cleanup header file inclusion for WIN32 platforms\r
-         * Cleanup code to avoid Microsoft Visual C++ compiler complaints\r
-         * Add 'USE_DL_PREFIX' to quickly allow co-existence with existing\r
-           memory allocation routines\r
-         * Set 'malloc_getpagesize' for WIN32 platforms (needs more work)\r
-         * Use 'assert' rather than 'ASSERT' in WIN32 code to conform to\r
-           usage of 'assert' in non-WIN32 code\r
-         * Improve WIN32 'sbrk()' emulation's 'findRegion()' routine to\r
-           avoid infinite loop\r
-      * Always call 'fREe()' rather than 'free()'\r
-\r
-    V2.6.5 Wed Jun 17 15:57:31 1998  Doug Lea  (dl at gee)\r
-      * Fixed ordering problem with boundary-stamping\r
-\r
-    V2.6.3 Sun May 19 08:17:58 1996  Doug Lea  (dl at gee)\r
-      * Added pvalloc, as recommended by H.J. Liu\r
-      * Added 64bit pointer support mainly from Wolfram Gloger\r
-      * Added anonymously donated WIN32 sbrk emulation\r
-      * Malloc, calloc, getpagesize: add optimizations from Raymond Nijssen\r
-      * malloc_extend_top: fix mask error that caused wastage after\r
-        foreign sbrks\r
-      * Add linux mremap support code from HJ Liu\r
-\r
-    V2.6.2 Tue Dec  5 06:52:55 1995  Doug Lea  (dl at gee)\r
-      * Integrated most documentation with the code.\r
-      * Add support for mmap, with help from\r
-        Wolfram Gloger (Gloger@lrz.uni-muenchen.de).\r
-      * Use last_remainder in more cases.\r
-      * Pack bins using idea from  colin@nyx10.cs.du.edu\r
-      * Use ordered bins instead of best-fit threshhold\r
-      * Eliminate block-local decls to simplify tracing and debugging.\r
-      * Support another case of realloc via move into top\r
-      * Fix error occuring when initial sbrk_base not word-aligned.\r
-      * Rely on page size for units instead of SBRK_UNIT to\r
-        avoid surprises about sbrk alignment conventions.\r
-      * Add mallinfo, mallopt. Thanks to Raymond Nijssen\r
-        (raymond@es.ele.tue.nl) for the suggestion.\r
-      * Add `pad' argument to malloc_trim and top_pad mallopt parameter.\r
-      * More precautions for cases where other routines call sbrk,\r
-        courtesy of Wolfram Gloger (Gloger@lrz.uni-muenchen.de).\r
-      * Added macros etc., allowing use in linux libc from\r
-        H.J. Lu (hjl@gnu.ai.mit.edu)\r
-      * Inverted this history list\r
-\r
-    V2.6.1 Sat Dec  2 14:10:57 1995  Doug Lea  (dl at gee)\r
-      * Re-tuned and fixed to behave more nicely with V2.6.0 changes.\r
-      * Removed all preallocation code since under current scheme\r
-        the work required to undo bad preallocations exceeds\r
-        the work saved in good cases for most test programs.\r
-      * No longer use return list or unconsolidated bins since\r
-        no scheme using them consistently outperforms those that don't\r
-        given above changes.\r
-      * Use best fit for very large chunks to prevent some worst-cases.\r
-      * Added some support for debugging\r
-\r
-    V2.6.0 Sat Nov  4 07:05:23 1995  Doug Lea  (dl at gee)\r
-      * Removed footers when chunks are in use. Thanks to\r
-        Paul Wilson (wilson@cs.texas.edu) for the suggestion.\r
-\r
-    V2.5.4 Wed Nov  1 07:54:51 1995  Doug Lea  (dl at gee)\r
-      * Added malloc_trim, with help from Wolfram Gloger\r
-        (wmglo@Dent.MED.Uni-Muenchen.DE).\r
-\r
-    V2.5.3 Tue Apr 26 10:16:01 1994  Doug Lea  (dl at g)\r
-\r
-    V2.5.2 Tue Apr  5 16:20:40 1994  Doug Lea  (dl at g)\r
-      * realloc: try to expand in both directions\r
-      * malloc: swap order of clean-bin strategy;\r
-      * realloc: only conditionally expand backwards\r
-      * Try not to scavenge used bins\r
-      * Use bin counts as a guide to preallocation\r
-      * Occasionally bin return list chunks in first scan\r
-      * Add a few optimizations from colin@nyx10.cs.du.edu\r
-\r
-    V2.5.1 Sat Aug 14 15:40:43 1993  Doug Lea  (dl at g)\r
-      * faster bin computation & slightly different binning\r
-      * merged all consolidations to one part of malloc proper\r
-         (eliminating old malloc_find_space & malloc_clean_bin)\r
-      * Scan 2 returns chunks (not just 1)\r
-      * Propagate failure in realloc if malloc returns 0\r
-      * Add stuff to allow compilation on non-ANSI compilers\r
-          from kpv@research.att.com\r
-\r
-    V2.5 Sat Aug  7 07:41:59 1993  Doug Lea  (dl at g.oswego.edu)\r
-      * removed potential for odd address access in prev_chunk\r
-      * removed dependency on getpagesize.h\r
-      * misc cosmetics and a bit more internal documentation\r
-      * anticosmetics: mangled names in macros to evade debugger strangeness\r
-      * tested on sparc, hp-700, dec-mips, rs6000\r
-          with gcc & native cc (hp, dec only) allowing\r
-          Detlefs & Zorn comparison study (in SIGPLAN Notices.)\r
-\r
-    Trial version Fri Aug 28 13:14:29 1992  Doug Lea  (dl at g.oswego.edu)\r
-      * Based loosely on libg++-1.2X malloc. (It retains some of the overall\r
-         structure of old version,  but most details differ.)\r
-\r
-*/\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-/* TODO: TEST ME */\r
-int main( void )\r
-{\r
-    return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
+/*
+  This is a version (aka dlmalloc) of malloc/free/realloc written by
+  Doug Lea and released to the public domain, as explained at
+  http://creativecommons.org/publicdomain/zero/1.0/ Send questions,
+  comments, complaints, performance data, etc to dl@cs.oswego.edu
+
+* Version 2.8.5 Sun May 22 10:26:02 2011  Doug Lea  (dl at gee)
+
+   Note: There may be an updated version of this malloc obtainable at
+           ftp://gee.cs.oswego.edu/pub/misc/malloc.c
+         Check before installing!
+
+* Quickstart
+
+  This library is all in one file to simplify the most common usage:
+  ftp it, compile it (-O3), and link it into another program. All of
+  the compile-time options default to reasonable values for use on
+  most platforms.  You might later want to step through various
+  compile-time and dynamic tuning options.
+
+  For convenience, an include file for code using this malloc is at:
+     ftp://gee.cs.oswego.edu/pub/misc/malloc-2.8.5.h
+  You don't really need this .h file unless you call functions not
+  defined in your system include files.  The .h file contains only the
+  excerpts from this file needed for using this malloc on ANSI C/C++
+  systems, so long as you haven't changed compile-time options about
+  naming and tuning parameters.  If you do, then you can create your
+  own malloc.h that does include all settings by cutting at the point
+  indicated below. Note that you may already by default be using a C
+  library containing a malloc that is based on some version of this
+  malloc (for example in linux). You might still want to use the one
+  in this file to customize settings or to avoid overheads associated
+  with library versions.
+
+* Vital statistics:
+
+  Supported pointer/size_t representation:       4 or 8 bytes
+       size_t MUST be an unsigned type of the same width as
+       pointers. (If you are using an ancient system that declares
+       size_t as a signed type, or need it to be a different width
+       than pointers, you can use a previous release of this malloc
+       (e.g. 2.7.2) supporting these.)
+
+  Alignment:                                     8 bytes (default)
+       This suffices for nearly all current machines and C compilers.
+       However, you can define MALLOC_ALIGNMENT to be wider than this
+       if necessary (up to 128bytes), at the expense of using more space.
+
+  Minimum overhead per allocated chunk:   4 or  8 bytes (if 4byte sizes)
+                                          8 or 16 bytes (if 8byte sizes)
+       Each malloced chunk has a hidden word of overhead holding size
+       and status information, and additional cross-check word
+       if FOOTERS is defined.
+
+  Minimum allocated size: 4-byte ptrs:  16 bytes    (including overhead)
+                          8-byte ptrs:  32 bytes    (including overhead)
+
+       Even a request for zero bytes (i.e., malloc(0)) returns a
+       pointer to something of the minimum allocatable size.
+       The maximum overhead wastage (i.e., number of extra bytes
+       allocated than were requested in malloc) is less than or equal
+       to the minimum size, except for requests >= mmap_threshold that
+       are serviced via mmap(), where the worst case wastage is about
+       32 bytes plus the remainder from a system page (the minimal
+       mmap unit); typically 4096 or 8192 bytes.
+
+  Security: static-safe; optionally more or less
+       The "security" of malloc refers to the ability of malicious
+       code to accentuate the effects of errors (for example, freeing
+       space that is not currently malloc'ed or overwriting past the
+       ends of chunks) in code that calls malloc.  This malloc
+       guarantees not to modify any memory locations below the base of
+       heap, i.e., static variables, even in the presence of usage
+       errors.  The routines additionally detect most improper frees
+       and reallocs.  All this holds as long as the static bookkeeping
+       for malloc itself is not corrupted by some other means.  This
+       is only one aspect of security -- these checks do not, and
+       cannot, detect all possible programming errors.
+
+       If FOOTERS is defined nonzero, then each allocated chunk
+       carries an additional check word to verify that it was malloced
+       from its space.  These check words are the same within each
+       execution of a program using malloc, but differ across
+       executions, so externally crafted fake chunks cannot be
+       freed. This improves security by rejecting frees/reallocs that
+       could corrupt heap memory, in addition to the checks preventing
+       writes to statics that are always on.  This may further improve
+       security at the expense of time and space overhead.  (Note that
+       FOOTERS may also be worth using with MSPACES.)
+
+       By default detected errors cause the program to abort (calling
+       "abort()"). You can override this to instead proceed past
+       errors by defining PROCEED_ON_ERROR.  In this case, a bad free
+       has no effect, and a malloc that encounters a bad address
+       caused by user overwrites will ignore the bad address by
+       dropping pointers and indices to all known memory. This may
+       be appropriate for programs that should continue if at all
+       possible in the face of programming errors, although they may
+       run out of memory because dropped memory is never reclaimed.
+
+       If you don't like either of these options, you can define
+       CORRUPTION_ERROR_ACTION and USAGE_ERROR_ACTION to do anything
+       else. And if if you are sure that your program using malloc has
+       no errors or vulnerabilities, you can define INSECURE to 1,
+       which might (or might not) provide a small performance improvement.
+
+       It is also possible to limit the maximum total allocatable
+       space, using malloc_set_footprint_limit. This is not
+       designed as a security feature in itself (calls to set limits
+       are not screened or privileged), but may be useful as one
+       aspect of a secure implementation.
+
+  Thread-safety: NOT thread-safe unless USE_LOCKS defined non-zero
+       When USE_LOCKS is defined, each public call to malloc, free,
+       etc is surrounded with a lock. By default, this uses a plain
+       pthread mutex, win32 critical section, or a spin-lock if if
+       available for the platform and not disabled by setting
+       USE_SPIN_LOCKS=0.  However, if USE_RECURSIVE_LOCKS is defined,
+       recursive versions are used instead (which are not required for
+       base functionality but may be needed in layered extensions).
+       Using a global lock is not especially fast, and can be a major
+       bottleneck.  It is designed only to provide minimal protection
+       in concurrent environments, and to provide a basis for
+       extensions.  If you are using malloc in a concurrent program,
+       consider instead using nedmalloc
+       (http://www.nedprod.com/programs/portable/nedmalloc/) or
+       ptmalloc (See http://www.malloc.de), which are derived from
+       versions of this malloc.
+
+  System requirements: Any combination of MORECORE and/or MMAP/MUNMAP
+       This malloc can use unix sbrk or any emulation (invoked using
+       the CALL_MORECORE macro) and/or mmap/munmap or any emulation
+       (invoked using CALL_MMAP/CALL_MUNMAP) to get and release system
+       memory.  On most unix systems, it tends to work best if both
+       MORECORE and MMAP are enabled.  On Win32, it uses emulations
+       based on VirtualAlloc. It also uses common C library functions
+       like memset.
+
+  Compliance: I believe it is compliant with the Single Unix Specification
+       (See http://www.unix.org). Also SVID/XPG, ANSI C, and probably
+       others as well.
+
+* Overview of algorithms
+
+  This is not the fastest, most space-conserving, most portable, or
+  most tunable malloc ever written. However it is among the fastest
+  while also being among the most space-conserving, portable and
+  tunable.  Consistent balance across these factors results in a good
+  general-purpose allocator for malloc-intensive programs.
+
+  In most ways, this malloc is a best-fit allocator. Generally, it
+  chooses the best-fitting existing chunk for a request, with ties
+  broken in approximately least-recently-used order. (This strategy
+  normally maintains low fragmentation.) However, for requests less
+  than 256bytes, it deviates from best-fit when there is not an
+  exactly fitting available chunk by preferring to use space adjacent
+  to that used for the previous small request, as well as by breaking
+  ties in approximately most-recently-used order. (These enhance
+  locality of series of small allocations.)  And for very large requests
+  (>= 256Kb by default), it relies on system memory mapping
+  facilities, if supported.  (This helps avoid carrying around and
+  possibly fragmenting memory used only for large chunks.)
+
+  All operations (except malloc_stats and mallinfo) have execution
+  times that are bounded by a constant factor of the number of bits in
+  a size_t, not counting any clearing in calloc or copying in realloc,
+  or actions surrounding MORECORE and MMAP that have times
+  proportional to the number of non-contiguous regions returned by
+  system allocation routines, which is often just 1. In real-time
+  applications, you can optionally suppress segment traversals using
+  NO_SEGMENT_TRAVERSAL, which assures bounded execution even when
+  system allocators return non-contiguous spaces, at the typical
+  expense of carrying around more memory and increased fragmentation.
+
+  The implementation is not very modular and seriously overuses
+  macros. Perhaps someday all C compilers will do as good a job
+  inlining modular code as can now be done by brute-force expansion,
+  but now, enough of them seem not to.
+
+  Some compilers issue a lot of warnings about code that is
+  dead/unreachable only on some platforms, and also about intentional
+  uses of negation on unsigned types. All known cases of each can be
+  ignored.
+
+  For a longer but out of date high-level description, see
+     http://gee.cs.oswego.edu/dl/html/malloc.html
+
+* MSPACES
+  If MSPACES is defined, then in addition to malloc, free, etc.,
+  this file also defines mspace_malloc, mspace_free, etc. These
+  are versions of malloc routines that take an "mspace" argument
+  obtained using create_mspace, to control all internal bookkeeping.
+  If ONLY_MSPACES is defined, only these versions are compiled.
+  So if you would like to use this allocator for only some allocations,
+  and your system malloc for others, you can compile with
+  ONLY_MSPACES and then do something like...
+    static mspace mymspace = create_mspace(0,0); // for example
+    #define mymalloc(bytes)  mspace_malloc(mymspace, bytes)
+
+  (Note: If you only need one instance of an mspace, you can instead
+  use "USE_DL_PREFIX" to relabel the global malloc.)
+
+  You can similarly create thread-local allocators by storing
+  mspaces as thread-locals. For example:
+    static __thread mspace tlms = 0;
+    void*  tlmalloc(size_t bytes) {
+      if (tlms == 0) tlms = create_mspace(0, 0);
+      return mspace_malloc(tlms, bytes);
+    }
+    void  tlfree(void* mem) { mspace_free(tlms, mem); }
+
+  Unless FOOTERS is defined, each mspace is completely independent.
+  You cannot allocate from one and free to another (although
+  conformance is only weakly checked, so usage errors are not always
+  caught). If FOOTERS is defined, then each chunk carries around a tag
+  indicating its originating mspace, and frees are directed to their
+  originating spaces. Normally, this requires use of locks.
+
+ -------------------------  Compile-time options ---------------------------
+
+Be careful in setting #define values for numerical constants of type
+size_t. On some systems, literal values are not automatically extended
+to size_t precision unless they are explicitly casted. You can also
+use the symbolic values MAX_SIZE_T, SIZE_T_ONE, etc below.
+
+WIN32                    default: defined if _WIN32 defined
+  Defining WIN32 sets up defaults for MS environment and compilers.
+  Otherwise defaults are for unix. Beware that there seem to be some
+  cases where this malloc might not be a pure drop-in replacement for
+  Win32 malloc: Random-looking failures from Win32 GDI API's (eg;
+  SetDIBits()) may be due to bugs in some video driver implementations
+  when pixel buffers are malloc()ed, and the region spans more than
+  one VirtualAlloc()ed region. Because dlmalloc uses a small (64Kb)
+  default granularity, pixel buffers may straddle virtual allocation
+  regions more often than when using the Microsoft allocator.  You can
+  avoid this by using VirtualAlloc() and VirtualFree() for all pixel
+  buffers rather than using malloc().  If this is not possible,
+  recompile this malloc with a larger DEFAULT_GRANULARITY. Note:
+  in cases where MSC and gcc (cygwin) are known to differ on WIN32,
+  conditions use _MSC_VER to distinguish them.
+
+DLMALLOC_EXPORT       default: extern
+  Defines how public APIs are declared. If you want to export via a
+  Windows DLL, you might define this as
+    #define DLMALLOC_EXPORT extern  __declspace(dllexport)
+  If you want a POSIX ELF shared object, you might use
+    #define DLMALLOC_EXPORT extern __attribute__((visibility("default")))
+
+MALLOC_ALIGNMENT         default: (size_t)8
+  Controls the minimum alignment for malloc'ed chunks.  It must be a
+  power of two and at least 8, even on machines for which smaller
+  alignments would suffice. It may be defined as larger than this
+  though. Note however that code and data structures are optimized for
+  the case of 8-byte alignment.
+
+MSPACES                  default: 0 (false)
+  If true, compile in support for independent allocation spaces.
+  This is only supported if HAVE_MMAP is true.
+
+ONLY_MSPACES             default: 0 (false)
+  If true, only compile in mspace versions, not regular versions.
+
+USE_LOCKS                default: 0 (false)
+  Causes each call to each public routine to be surrounded with
+  pthread or WIN32 mutex lock/unlock. (If set true, this can be
+  overridden on a per-mspace basis for mspace versions.) If set to a
+  non-zero value other than 1, locks are used, but their
+  implementation is left out, so lock functions must be supplied manually,
+  as described below.
+
+USE_SPIN_LOCKS           default: 1 iff USE_LOCKS and spin locks available
+  If true, uses custom spin locks for locking. This is currently
+  supported only gcc >= 4.1, older gccs on x86 platforms, and recent
+  MS compilers.  Otherwise, posix locks or win32 critical sections are
+  used.
+
+USE_RECURSIVE_LOCKS      default: not defined
+  If defined nonzero, uses recursive (aka reentrant) locks, otherwise
+  uses plain mutexes. This is not required for malloc proper, but may
+  be needed for layered allocators such as nedmalloc.
+
+FOOTERS                  default: 0
+  If true, provide extra checking and dispatching by placing
+  information in the footers of allocated chunks. This adds
+  space and time overhead.
+
+INSECURE                 default: 0
+  If true, omit checks for usage errors and heap space overwrites.
+
+USE_DL_PREFIX            default: NOT defined
+  Causes compiler to prefix all public routines with the string 'dl'.
+  This can be useful when you only want to use this malloc in one part
+  of a program, using your regular system malloc elsewhere.
+
+MALLOC_INSPECT_ALL       default: NOT defined
+  If defined, compiles malloc_inspect_all and mspace_inspect_all, that
+  perform traversal of all heap space.  Unless access to these
+  functions is otherwise restricted, you probably do not want to
+  include them in secure implementations.
+
+ABORT                    default: defined as abort()
+  Defines how to abort on failed checks.  On most systems, a failed
+  check cannot die with an "assert" or even print an informative
+  message, because the underlying print routines in turn call malloc,
+  which will fail again.  Generally, the best policy is to simply call
+  abort(). It's not very useful to do more than this because many
+  errors due to overwriting will show up as address faults (null, odd
+  addresses etc) rather than malloc-triggered checks, so will also
+  abort.  Also, most compilers know that abort() does not return, so
+  can better optimize code conditionally calling it.
+
+PROCEED_ON_ERROR           default: defined as 0 (false)
+  Controls whether detected bad addresses cause them to bypassed
+  rather than aborting. If set, detected bad arguments to free and
+  realloc are ignored. And all bookkeeping information is zeroed out
+  upon a detected overwrite of freed heap space, thus losing the
+  ability to ever return it from malloc again, but enabling the
+  application to proceed. If PROCEED_ON_ERROR is defined, the
+  static variable malloc_corruption_error_count is compiled in
+  and can be examined to see if errors have occurred. This option
+  generates slower code than the default abort policy.
+
+DEBUG                    default: NOT defined
+  The DEBUG setting is mainly intended for people trying to modify
+  this code or diagnose problems when porting to new platforms.
+  However, it may also be able to better isolate user errors than just
+  using runtime checks.  The assertions in the check routines spell
+  out in more detail the assumptions and invariants underlying the
+  algorithms.  The checking is fairly extensive, and will slow down
+  execution noticeably. Calling malloc_stats or mallinfo with DEBUG
+  set will attempt to check every non-mmapped allocated and free chunk
+  in the course of computing the summaries.
+
+ABORT_ON_ASSERT_FAILURE   default: defined as 1 (true)
+  Debugging assertion failures can be nearly impossible if your
+  version of the assert macro causes malloc to be called, which will
+  lead to a cascade of further failures, blowing the runtime stack.
+  ABORT_ON_ASSERT_FAILURE cause assertions failures to call abort(),
+  which will usually make debugging easier.
+
+MALLOC_FAILURE_ACTION     default: sets errno to ENOMEM, or no-op on win32
+  The action to take before "return 0" when malloc fails to be able to
+  return memory because there is none available.
+
+HAVE_MORECORE             default: 1 (true) unless win32 or ONLY_MSPACES
+  True if this system supports sbrk or an emulation of it.
+
+MORECORE                  default: sbrk
+  The name of the sbrk-style system routine to call to obtain more
+  memory.  See below for guidance on writing custom MORECORE
+  functions. The type of the argument to sbrk/MORECORE varies across
+  systems.  It cannot be size_t, because it supports negative
+  arguments, so it is normally the signed type of the same width as
+  size_t (sometimes declared as "intptr_t").  It doesn't much matter
+  though. Internally, we only call it with arguments less than half
+  the max value of a size_t, which should work across all reasonable
+  possibilities, although sometimes generating compiler warnings.
+
+MORECORE_CONTIGUOUS       default: 1 (true) if HAVE_MORECORE
+  If true, take advantage of fact that consecutive calls to MORECORE
+  with positive arguments always return contiguous increasing
+  addresses.  This is true of unix sbrk. It does not hurt too much to
+  set it true anyway, since malloc copes with non-contiguities.
+  Setting it false when definitely non-contiguous saves time
+  and possibly wasted space it would take to discover this though.
+
+MORECORE_CANNOT_TRIM      default: NOT defined
+  True if MORECORE cannot release space back to the system when given
+  negative arguments. This is generally necessary only if you are
+  using a hand-crafted MORECORE function that cannot handle negative
+  arguments.
+
+NO_SEGMENT_TRAVERSAL       default: 0
+  If non-zero, suppresses traversals of memory segments
+  returned by either MORECORE or CALL_MMAP. This disables
+  merging of segments that are contiguous, and selectively
+  releasing them to the OS if unused, but bounds execution times.
+
+HAVE_MMAP                 default: 1 (true)
+  True if this system supports mmap or an emulation of it.  If so, and
+  HAVE_MORECORE is not true, MMAP is used for all system
+  allocation. If set and HAVE_MORECORE is true as well, MMAP is
+  primarily used to directly allocate very large blocks. It is also
+  used as a backup strategy in cases where MORECORE fails to provide
+  space from system. Note: A single call to MUNMAP is assumed to be
+  able to unmap memory that may have be allocated using multiple calls
+  to MMAP, so long as they are adjacent.
+
+HAVE_MREMAP               default: 1 on linux, else 0
+  If true realloc() uses mremap() to re-allocate large blocks and
+  extend or shrink allocation spaces.
+
+MMAP_CLEARS               default: 1 except on WINCE.
+  True if mmap clears memory so calloc doesn't need to. This is true
+  for standard unix mmap using /dev/zero and on WIN32 except for WINCE.
+
+USE_BUILTIN_FFS            default: 0 (i.e., not used)
+  Causes malloc to use the builtin ffs() function to compute indices.
+  Some compilers may recognize and intrinsify ffs to be faster than the
+  supplied C version. Also, the case of x86 using gcc is special-cased
+  to an asm instruction, so is already as fast as it can be, and so
+  this setting has no effect. Similarly for Win32 under recent MS compilers.
+  (On most x86s, the asm version is only slightly faster than the C version.)
+
+malloc_getpagesize         default: derive from system includes, or 4096.
+  The system page size. To the extent possible, this malloc manages
+  memory from the system in page-size units.  This may be (and
+  usually is) a function rather than a constant. This is ignored
+  if WIN32, where page size is determined using getSystemInfo during
+  initialization.
+
+USE_DEV_RANDOM             default: 0 (i.e., not used)
+  Causes malloc to use /dev/random to initialize secure magic seed for
+  stamping footers. Otherwise, the current time is used.
+
+NO_MALLINFO                default: 0
+  If defined, don't compile "mallinfo". This can be a simple way
+  of dealing with mismatches between system declarations and
+  those in this file.
+
+MALLINFO_FIELD_TYPE        default: size_t
+  The type of the fields in the mallinfo struct. This was originally
+  defined as "int" in SVID etc, but is more usefully defined as
+  size_t. The value is used only if  HAVE_USR_INCLUDE_MALLOC_H is not set
+
+NO_MALLOC_STATS            default: 0
+  If defined, don't compile "malloc_stats". This avoids calls to
+  fprintf and bringing in stdio dependencies you might not want.
+
+REALLOC_ZERO_BYTES_FREES    default: not defined
+  This should be set if a call to realloc with zero bytes should
+  be the same as a call to free. Some people think it should. Otherwise,
+  since this malloc returns a unique pointer for malloc(0), so does
+  realloc(p, 0).
+
+LACKS_UNISTD_H, LACKS_FCNTL_H, LACKS_SYS_PARAM_H, LACKS_SYS_MMAN_H
+LACKS_STRINGS_H, LACKS_STRING_H, LACKS_SYS_TYPES_H,  LACKS_ERRNO_H
+LACKS_STDLIB_H LACKS_SCHED_H LACKS_TIME_H  default: NOT defined unless on WIN32
+  Define these if your system does not have these header files.
+  You might need to manually insert some of the declarations they provide.
+
+DEFAULT_GRANULARITY        default: page size if MORECORE_CONTIGUOUS,
+                                system_info.dwAllocationGranularity in WIN32,
+                                otherwise 64K.
+      Also settable using mallopt(M_GRANULARITY, x)
+  The unit for allocating and deallocating memory from the system.  On
+  most systems with contiguous MORECORE, there is no reason to
+  make this more than a page. However, systems with MMAP tend to
+  either require or encourage larger granularities.  You can increase
+  this value to prevent system allocation functions to be called so
+  often, especially if they are slow.  The value must be at least one
+  page and must be a power of two.  Setting to 0 causes initialization
+  to either page size or win32 region size.  (Note: In previous
+  versions of malloc, the equivalent of this option was called
+  "TOP_PAD")
+
+DEFAULT_TRIM_THRESHOLD    default: 2MB
+      Also settable using mallopt(M_TRIM_THRESHOLD, x)
+  The maximum amount of unused top-most memory to keep before
+  releasing via malloc_trim in free().  Automatic trimming is mainly
+  useful in long-lived programs using contiguous MORECORE.  Because
+  trimming via sbrk can be slow on some systems, and can sometimes be
+  wasteful (in cases where programs immediately afterward allocate
+  more large chunks) the value should be high enough so that your
+  overall system performance would improve by releasing this much
+  memory.  As a rough guide, you might set to a value close to the
+  average size of a process (program) running on your system.
+  Releasing this much memory would allow such a process to run in
+  memory.  Generally, it is worth tuning trim thresholds when a
+  program undergoes phases where several large chunks are allocated
+  and released in ways that can reuse each other's storage, perhaps
+  mixed with phases where there are no such chunks at all. The trim
+  value must be greater than page size to have any useful effect.  To
+  disable trimming completely, you can set to MAX_SIZE_T. Note that the trick
+  some people use of mallocing a huge space and then freeing it at
+  program startup, in an attempt to reserve system memory, doesn't
+  have the intended effect under automatic trimming, since that memory
+  will immediately be returned to the system.
+
+DEFAULT_MMAP_THRESHOLD       default: 256K
+      Also settable using mallopt(M_MMAP_THRESHOLD, x)
+  The request size threshold for using MMAP to directly service a
+  request. Requests of at least this size that cannot be allocated
+  using already-existing space will be serviced via mmap.  (If enough
+  normal freed space already exists it is used instead.)  Using mmap
+  segregates relatively large chunks of memory so that they can be
+  individually obtained and released from the host system. A request
+  serviced through mmap is never reused by any other request (at least
+  not directly; the system may just so happen to remap successive
+  requests to the same locations).  Segregating space in this way has
+  the benefits that: Mmapped space can always be individually released
+  back to the system, which helps keep the system level memory demands
+  of a long-lived program low.  Also, mapped memory doesn't become
+  `locked' between other chunks, as can happen with normally allocated
+  chunks, which means that even trimming via malloc_trim would not
+  release them.  However, it has the disadvantage that the space
+  cannot be reclaimed, consolidated, and then used to service later
+  requests, as happens with normal chunks.  The advantages of mmap
+  nearly always outweigh disadvantages for "large" chunks, but the
+  value of "large" may vary across systems.  The default is an
+  empirically derived value that works well in most systems. You can
+  disable mmap by setting to MAX_SIZE_T.
+
+MAX_RELEASE_CHECK_RATE   default: 4095 unless not HAVE_MMAP
+  The number of consolidated frees between checks to release
+  unused segments when freeing. When using non-contiguous segments,
+  especially with multiple mspaces, checking only for topmost space
+  doesn't always suffice to trigger trimming. To compensate for this,
+  free() will, with a period of MAX_RELEASE_CHECK_RATE (or the
+  current number of segments, if greater) try to release unused
+  segments to the OS when freeing chunks that result in
+  consolidation. The best value for this parameter is a compromise
+  between slowing down frees with relatively costly checks that
+  rarely trigger versus holding on to unused memory. To effectively
+  disable, set to MAX_SIZE_T. This may lead to a very slight speed
+  improvement at the expense of carrying around more memory.
+*/
+
+#ifndef REGTEST
+#include "dlmalloc.h"
+
+/* Version identifier to allow people to support multiple versions */
+#ifndef DLMALLOC_VERSION
+#define DLMALLOC_VERSION 20805
+#endif /* DLMALLOC_VERSION */
+
+#ifndef DLMALLOC_EXPORT
+#define DLMALLOC_EXPORT extern
+#endif
+
+#ifndef WIN32
+#ifdef _WIN32
+#define WIN32 1
+#endif  /* _WIN32 */
+#ifdef _WIN32_WCE
+#define LACKS_FCNTL_H
+#define WIN32 1
+#endif /* _WIN32_WCE */
+#endif  /* WIN32 */
+#ifdef WIN32
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <tchar.h>
+#define HAVE_MMAP 1
+#define HAVE_MORECORE 0
+#define LACKS_UNISTD_H
+#define LACKS_SYS_PARAM_H
+#define LACKS_SYS_MMAN_H
+#define LACKS_STRING_H
+#define LACKS_STRINGS_H
+#define LACKS_SYS_TYPES_H
+#define LACKS_ERRNO_H
+#define LACKS_SCHED_H
+#ifndef MALLOC_FAILURE_ACTION
+#define MALLOC_FAILURE_ACTION
+#endif /* MALLOC_FAILURE_ACTION */
+#ifndef MMAP_CLEARS
+#ifdef _WIN32_WCE /* WINCE reportedly does not clear */
+#define MMAP_CLEARS 0
+#else
+#define MMAP_CLEARS 1
+#endif /* _WIN32_WCE */
+#endif /*MMAP_CLEARS */
+#endif  /* WIN32 */
+
+#if defined(DARWIN) || defined(_DARWIN)
+/* Mac OSX docs advise not to use sbrk; it seems better to use mmap */
+#ifndef HAVE_MORECORE
+#define HAVE_MORECORE 0
+#define HAVE_MMAP 1
+/* OSX allocators provide 16 byte alignment */
+#ifndef MALLOC_ALIGNMENT
+#define MALLOC_ALIGNMENT ((size_t)16U)
+#endif
+#endif  /* HAVE_MORECORE */
+#endif  /* DARWIN */
+
+#ifndef LACKS_SYS_TYPES_H
+#include <sys/types.h>  /* For size_t */
+#endif  /* LACKS_SYS_TYPES_H */
+
+/* The maximum possible size_t value has all bits set */
+#define MAX_SIZE_T           (~(size_t)0)
+
+#ifndef USE_LOCKS /* ensure true if spin or recursive locks set */
+#define USE_LOCKS  ((defined(USE_SPIN_LOCKS) && USE_SPIN_LOCKS != 0) || \
+                    (defined(USE_RECURSIVE_LOCKS) && USE_RECURSIVE_LOCKS != 0))
+#endif /* USE_LOCKS */
+
+#if USE_LOCKS /* Spin locks for gcc >= 4.1, older gcc on x86, MSC >= 1310 */
+#if ((defined(__GNUC__) &&                                              \
+      ((__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) ||      \
+       defined(__i386__) || defined(__x86_64__))) ||                    \
+     (defined(_MSC_VER) && _MSC_VER>=1310))
+#ifndef USE_SPIN_LOCKS
+#define USE_SPIN_LOCKS 1
+#endif /* USE_SPIN_LOCKS */
+#elif USE_SPIN_LOCKS
+#error "USE_SPIN_LOCKS defined without implementation"
+#endif /* ... locks available... */
+#elif !defined(USE_SPIN_LOCKS)
+#define USE_SPIN_LOCKS 0
+#endif /* USE_LOCKS */
+
+#ifndef ONLY_MSPACES
+#define ONLY_MSPACES 0
+#endif  /* ONLY_MSPACES */
+#ifndef MSPACES
+#if ONLY_MSPACES
+#define MSPACES 1
+#else   /* ONLY_MSPACES */
+#define MSPACES 0
+#endif  /* ONLY_MSPACES */
+#endif  /* MSPACES */
+#ifndef MALLOC_ALIGNMENT
+#define MALLOC_ALIGNMENT ((size_t)8U)
+#endif  /* MALLOC_ALIGNMENT */
+#ifndef FOOTERS
+#define FOOTERS 0
+#endif  /* FOOTERS */
+#ifndef ABORT
+#define ABORT  abort()
+#endif  /* ABORT */
+#ifndef ABORT_ON_ASSERT_FAILURE
+#define ABORT_ON_ASSERT_FAILURE 1
+#endif  /* ABORT_ON_ASSERT_FAILURE */
+#ifndef PROCEED_ON_ERROR
+#define PROCEED_ON_ERROR 0
+#endif  /* PROCEED_ON_ERROR */
+
+#ifndef INSECURE
+#define INSECURE 0
+#endif  /* INSECURE */
+#ifndef MALLOC_INSPECT_ALL
+#define MALLOC_INSPECT_ALL 0
+#endif  /* MALLOC_INSPECT_ALL */
+#ifndef HAVE_MMAP
+#define HAVE_MMAP 1
+#endif  /* HAVE_MMAP */
+#ifndef MMAP_CLEARS
+#define MMAP_CLEARS 1
+#endif  /* MMAP_CLEARS */
+#ifndef HAVE_MREMAP
+#ifdef linux
+#define HAVE_MREMAP 1
+#define _GNU_SOURCE /* Turns on mremap() definition */
+#else   /* linux */
+#define HAVE_MREMAP 0
+#endif  /* linux */
+#endif  /* HAVE_MREMAP */
+#ifndef MALLOC_FAILURE_ACTION
+#define MALLOC_FAILURE_ACTION  errno = ENOMEM;
+#endif  /* MALLOC_FAILURE_ACTION */
+#ifndef HAVE_MORECORE
+#if ONLY_MSPACES
+#define HAVE_MORECORE 0
+#else   /* ONLY_MSPACES */
+#define HAVE_MORECORE 1
+#endif  /* ONLY_MSPACES */
+#endif  /* HAVE_MORECORE */
+#if !HAVE_MORECORE
+#define MORECORE_CONTIGUOUS 0
+#else   /* !HAVE_MORECORE */
+#define MORECORE_DEFAULT sbrk
+#ifndef MORECORE_CONTIGUOUS
+#define MORECORE_CONTIGUOUS 1
+#endif  /* MORECORE_CONTIGUOUS */
+#endif  /* HAVE_MORECORE */
+#ifndef DEFAULT_GRANULARITY
+#if (MORECORE_CONTIGUOUS || defined(WIN32))
+#define DEFAULT_GRANULARITY (0)  /* 0 means to compute in init_mparams */
+#else   /* MORECORE_CONTIGUOUS */
+#define DEFAULT_GRANULARITY ((size_t)64U * (size_t)1024U)
+#endif  /* MORECORE_CONTIGUOUS */
+#endif  /* DEFAULT_GRANULARITY */
+#ifndef DEFAULT_TRIM_THRESHOLD
+#ifndef MORECORE_CANNOT_TRIM
+#define DEFAULT_TRIM_THRESHOLD ((size_t)2U * (size_t)1024U * (size_t)1024U)
+#else   /* MORECORE_CANNOT_TRIM */
+#define DEFAULT_TRIM_THRESHOLD MAX_SIZE_T
+#endif  /* MORECORE_CANNOT_TRIM */
+#endif  /* DEFAULT_TRIM_THRESHOLD */
+#ifndef DEFAULT_MMAP_THRESHOLD
+#if HAVE_MMAP
+#define DEFAULT_MMAP_THRESHOLD ((size_t)256U * (size_t)1024U)
+#else   /* HAVE_MMAP */
+#define DEFAULT_MMAP_THRESHOLD MAX_SIZE_T
+#endif  /* HAVE_MMAP */
+#endif  /* DEFAULT_MMAP_THRESHOLD */
+#ifndef MAX_RELEASE_CHECK_RATE
+#if HAVE_MMAP
+#define MAX_RELEASE_CHECK_RATE 4095
+#else
+#define MAX_RELEASE_CHECK_RATE MAX_SIZE_T
+#endif /* HAVE_MMAP */
+#endif /* MAX_RELEASE_CHECK_RATE */
+#ifndef USE_BUILTIN_FFS
+#define USE_BUILTIN_FFS 0
+#endif  /* USE_BUILTIN_FFS */
+#ifndef USE_DEV_RANDOM
+#define USE_DEV_RANDOM 0
+#endif  /* USE_DEV_RANDOM */
+#ifndef NO_MALLINFO
+#define NO_MALLINFO 0
+#endif  /* NO_MALLINFO */
+#ifndef MALLINFO_FIELD_TYPE
+#define MALLINFO_FIELD_TYPE size_t
+#endif  /* MALLINFO_FIELD_TYPE */
+#ifndef NO_MALLOC_STATS
+#define NO_MALLOC_STATS 0
+#endif  /* NO_MALLOC_STATS */
+#ifndef NO_SEGMENT_TRAVERSAL
+#define NO_SEGMENT_TRAVERSAL 0
+#endif /* NO_SEGMENT_TRAVERSAL */
+
+/*
+  mallopt tuning options.  SVID/XPG defines four standard parameter
+  numbers for mallopt, normally defined in malloc.h.  None of these
+  are used in this malloc, so setting them has no effect. But this
+  malloc does support the following options.
+*/
+
+#define M_TRIM_THRESHOLD     (-1)
+#define M_GRANULARITY        (-2)
+#define M_MMAP_THRESHOLD     (-3)
+
+/* ------------------------ Mallinfo declarations ------------------------ */
+
+#if !NO_MALLINFO
+/*
+  This version of malloc supports the standard SVID/XPG mallinfo
+  routine that returns a struct containing usage properties and
+  statistics. It should work on any system that has a
+  /usr/include/malloc.h defining struct mallinfo.  The main
+  declaration needed is the mallinfo struct that is returned (by-copy)
+  by mallinfo().  The malloinfo struct contains a bunch of fields that
+  are not even meaningful in this version of malloc.  These fields are
+  are instead filled by mallinfo() with other numbers that might be of
+  interest.
+
+  HAVE_USR_INCLUDE_MALLOC_H should be set if you have a
+  /usr/include/malloc.h file that includes a declaration of struct
+  mallinfo.  If so, it is included; else a compliant version is
+  declared below.  These must be precisely the same for mallinfo() to
+  work.  The original SVID version of this struct, defined on most
+  systems with mallinfo, declares all fields as ints. But some others
+  define as unsigned long. If your system defines the fields using a
+  type of different width than listed here, you MUST #include your
+  system version and #define HAVE_USR_INCLUDE_MALLOC_H.
+*/
+
+/* #define HAVE_USR_INCLUDE_MALLOC_H */
+
+#ifdef HAVE_USR_INCLUDE_MALLOC_H
+#include "/usr/include/malloc.h"
+#else /* HAVE_USR_INCLUDE_MALLOC_H */
+#ifndef STRUCT_MALLINFO_DECLARED
+/* HP-UX (and others?) redefines mallinfo unless _STRUCT_MALLINFO is defined */
+#define _STRUCT_MALLINFO
+#define STRUCT_MALLINFO_DECLARED 1
+struct mallinfo {
+  MALLINFO_FIELD_TYPE arena;    /* non-mmapped space allocated from system */
+  MALLINFO_FIELD_TYPE ordblks;  /* number of free chunks */
+  MALLINFO_FIELD_TYPE smblks;   /* always 0 */
+  MALLINFO_FIELD_TYPE hblks;    /* always 0 */
+  MALLINFO_FIELD_TYPE hblkhd;   /* space in mmapped regions */
+  MALLINFO_FIELD_TYPE usmblks;  /* maximum total allocated space */
+  MALLINFO_FIELD_TYPE fsmblks;  /* always 0 */
+  MALLINFO_FIELD_TYPE uordblks; /* total allocated space */
+  MALLINFO_FIELD_TYPE fordblks; /* total free space */
+  MALLINFO_FIELD_TYPE keepcost; /* releasable (via malloc_trim) space */
+};
+#endif /* STRUCT_MALLINFO_DECLARED */
+#endif /* HAVE_USR_INCLUDE_MALLOC_H */
+#endif /* NO_MALLINFO */
+
+/*
+  Try to persuade compilers to inline. The most critical functions for
+  inlining are defined as macros, so these aren't used for them.
+*/
+
+#ifndef FORCEINLINE
+  #if defined(__GNUC__)
+#define FORCEINLINE __inline __attribute__ ((always_inline))
+  #elif defined(_MSC_VER)
+    #define FORCEINLINE __forceinline
+  #endif
+#endif
+#ifndef NOINLINE
+  #if defined(__GNUC__)
+    #define NOINLINE __attribute__ ((noinline))
+  #elif defined(_MSC_VER)
+    #define NOINLINE __declspec(noinline)
+  #else
+    #define NOINLINE
+  #endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#ifndef FORCEINLINE
+ #define FORCEINLINE inline
+#endif
+#endif /* __cplusplus */
+#ifndef FORCEINLINE
+ #define FORCEINLINE
+#endif
+
+#if !ONLY_MSPACES
+
+/* ------------------- Declarations of public routines ------------------- */
+
+#ifndef USE_DL_PREFIX
+#define dlcalloc               calloc
+#define dlfree                 free
+#define dlmalloc               malloc
+#define dlmemalign             aligned_alloc
+#define dlposix_memalign       posix_memalign
+#define dlrealloc              realloc
+#define dlrealloc_in_place     realloc_in_place
+#define dlvalloc               valloc
+#define dlpvalloc              pvalloc
+#define dlmallinfo             mallinfo
+#define dlmallopt              mallopt
+#define dlmalloc_trim          malloc_trim
+#define dlmalloc_stats         malloc_stats
+#define dlmalloc_usable_size   malloc_usable_size
+#define dlmalloc_footprint     malloc_footprint
+#define dlmalloc_max_footprint malloc_max_footprint
+#define dlmalloc_footprint_limit malloc_footprint_limit
+#define dlmalloc_set_footprint_limit malloc_set_footprint_limit
+#define dlmalloc_inspect_all   malloc_inspect_all
+#define dlindependent_calloc   independent_calloc
+#define dlindependent_comalloc independent_comalloc
+#define dlbulk_free            bulk_free
+#endif /* USE_DL_PREFIX */
+
+#if 0 // Redeclaration warnings as PDCLib already declares these in <stdio.h>
+
+/*
+  malloc(size_t n)
+  Returns a pointer to a newly allocated chunk of at least n bytes, or
+  null if no space is available, in which case errno is set to ENOMEM
+  on ANSI C systems.
+
+  If n is zero, malloc returns a minimum-sized chunk. (The minimum
+  size is 16 bytes on most 32bit systems, and 32 bytes on 64bit
+  systems.)  Note that size_t is an unsigned type, so calls with
+  arguments that would be negative if signed are interpreted as
+  requests for huge amounts of space, which will often fail. The
+  maximum supported value of n differs across systems, but is in all
+  cases less than the maximum representable value of a size_t.
+*/
+DLMALLOC_EXPORT void* dlmalloc(size_t);
+
+/*
+  free(void* p)
+  Releases the chunk of memory pointed to by p, that had been previously
+  allocated using malloc or a related routine such as realloc.
+  It has no effect if p is null. If p was not malloced or already
+  freed, free(p) will by default cause the current program to abort.
+*/
+DLMALLOC_EXPORT void  dlfree(void*);
+
+/*
+  calloc(size_t n_elements, size_t element_size);
+  Returns a pointer to n_elements * element_size bytes, with all locations
+  set to zero.
+*/
+DLMALLOC_EXPORT void* dlcalloc(size_t, size_t);
+
+/*
+  realloc(void* p, size_t n)
+  Returns a pointer to a chunk of size n that contains the same data
+  as does chunk p up to the minimum of (n, p's size) bytes, or null
+  if no space is available.
+
+  The returned pointer may or may not be the same as p. The algorithm
+  prefers extending p in most cases when possible, otherwise it
+  employs the equivalent of a malloc-copy-free sequence.
+
+  If p is null, realloc is equivalent to malloc.
+
+  If space is not available, realloc returns null, errno is set (if on
+  ANSI) and p is NOT freed.
+
+  if n is for fewer bytes than already held by p, the newly unused
+  space is lopped off and freed if possible.  realloc with a size
+  argument of zero (re)allocates a minimum-sized chunk.
+
+  The old unix realloc convention of allowing the last-free'd chunk
+  to be used as an argument to realloc is not supported.
+*/
+DLMALLOC_EXPORT void* dlrealloc(void*, size_t);
+
+#endif
+
+/*
+  realloc_in_place(void* p, size_t n)
+  Resizes the space allocated for p to size n, only if this can be
+  done without moving p (i.e., only if there is adjacent space
+  available if n is greater than p's current allocated size, or n is
+  less than or equal to p's size). This may be used instead of plain
+  realloc if an alternative allocation strategy is needed upon failure
+  to expand space; for example, reallocation of a buffer that must be
+  memory-aligned or cleared. You can use realloc_in_place to trigger
+  these alternatives only when needed.
+
+  Returns p if successful; otherwise null.
+*/
+DLMALLOC_EXPORT void* dlrealloc_in_place(void*, size_t);
+
+#if 0 // Redeclaration warnings as PDCLib already declares these in <stdio.h>
+
+/*
+  memalign(size_t alignment, size_t n);
+  Returns a pointer to a newly allocated chunk of n bytes, aligned
+  in accord with the alignment argument.
+
+  The alignment argument should be a power of two. If the argument is
+  not a power of two, the nearest greater power is used.
+  8-byte alignment is guaranteed by normal malloc calls, so don't
+  bother calling memalign with an argument of 8 or less.
+
+  Overreliance on memalign is a sure way to fragment space.
+*/
+DLMALLOC_EXPORT void* dlmemalign(size_t, size_t);
+
+#endif
+
+/*
+  int posix_memalign(void** pp, size_t alignment, size_t n);
+  Allocates a chunk of n bytes, aligned in accord with the alignment
+  argument. Differs from memalign only in that it (1) assigns the
+  allocated memory to *pp rather than returning it, (2) fails and
+  returns EINVAL if the alignment is not a power of two (3) fails and
+  returns ENOMEM if memory cannot be allocated.
+*/
+DLMALLOC_EXPORT int dlposix_memalign(void**, size_t, size_t);
+
+/*
+  valloc(size_t n);
+  Equivalent to memalign(pagesize, n), where pagesize is the page
+  size of the system. If the pagesize is unknown, 4096 is used.
+*/
+DLMALLOC_EXPORT void* dlvalloc(size_t);
+
+/*
+  mallopt(int parameter_number, int parameter_value)
+  Sets tunable parameters The format is to provide a
+  (parameter-number, parameter-value) pair.  mallopt then sets the
+  corresponding parameter to the argument value if it can (i.e., so
+  long as the value is meaningful), and returns 1 if successful else
+  0.  To workaround the fact that mallopt is specified to use int,
+  not size_t parameters, the value -1 is specially treated as the
+  maximum unsigned size_t value.
+
+  SVID/XPG/ANSI defines four standard param numbers for mallopt,
+  normally defined in malloc.h.  None of these are use in this malloc,
+  so setting them has no effect. But this malloc also supports other
+  options in mallopt. See below for details.  Briefly, supported
+  parameters are as follows (listed defaults are for "typical"
+  configurations).
+
+  Symbol            param #  default    allowed param values
+  M_TRIM_THRESHOLD     -1   2*1024*1024   any   (-1 disables)
+  M_GRANULARITY        -2     page size   any power of 2 >= page size
+  M_MMAP_THRESHOLD     -3      256*1024   any   (or 0 if no MMAP support)
+*/
+DLMALLOC_EXPORT int dlmallopt(int, int);
+
+/*
+  malloc_footprint();
+  Returns the number of bytes obtained from the system.  The total
+  number of bytes allocated by malloc, realloc etc., is less than this
+  value. Unlike mallinfo, this function returns only a precomputed
+  result, so can be called frequently to monitor memory consumption.
+  Even if locks are otherwise defined, this function does not use them,
+  so results might not be up to date.
+*/
+DLMALLOC_EXPORT size_t dlmalloc_footprint(void);
+
+/*
+  malloc_max_footprint();
+  Returns the maximum number of bytes obtained from the system. This
+  value will be greater than current footprint if deallocated space
+  has been reclaimed by the system. The peak number of bytes allocated
+  by malloc, realloc etc., is less than this value. Unlike mallinfo,
+  this function returns only a precomputed result, so can be called
+  frequently to monitor memory consumption.  Even if locks are
+  otherwise defined, this function does not use them, so results might
+  not be up to date.
+*/
+DLMALLOC_EXPORT size_t dlmalloc_max_footprint(void);
+
+/*
+  malloc_footprint_limit();
+  Returns the number of bytes that the heap is allowed to obtain from
+  the system, returning the last value returned by
+  malloc_set_footprint_limit, or the maximum size_t value if
+  never set. The returned value reflects a permission. There is no
+  guarantee that this number of bytes can actually be obtained from
+  the system.
+*/
+DLMALLOC_EXPORT size_t dlmalloc_footprint_limit(void);
+
+/*
+  malloc_set_footprint_limit();
+  Sets the maximum number of bytes to obtain from the system, causing
+  failure returns from malloc and related functions upon attempts to
+  exceed this value. The argument value may be subject to page
+  rounding to an enforceable limit; this actual value is returned.
+  Using an argument of the maximum possible size_t effectively
+  disables checks. If the argument is less than or equal to the
+  current malloc_footprint, then all future allocations that require
+  additional system memory will fail. However, invocation cannot
+  retroactively deallocate existing used memory.
+*/
+DLMALLOC_EXPORT size_t dlmalloc_set_footprint_limit(size_t bytes);
+
+#if MALLOC_INSPECT_ALL
+/*
+  malloc_inspect_all(void(*handler)(void *start,
+                                    void *end,
+                                    size_t used_bytes,
+                                    void* callback_arg),
+                      void* arg);
+  Traverses the heap and calls the given handler for each managed
+  region, skipping all bytes that are (or may be) used for bookkeeping
+  purposes.  Traversal does not include include chunks that have been
+  directly memory mapped. Each reported region begins at the start
+  address, and continues up to but not including the end address.  The
+  first used_bytes of the region contain allocated data. If
+  used_bytes is zero, the region is unallocated. The handler is
+  invoked with the given callback argument. If locks are defined, they
+  are held during the entire traversal. It is a bad idea to invoke
+  other malloc functions from within the handler.
+
+  For example, to count the number of in-use chunks with size greater
+  than 1000, you could write:
+  static int count = 0;
+  void count_chunks(void* start, void* end, size_t used, void* arg) {
+    if (used >= 1000) ++count;
+  }
+  then:
+    malloc_inspect_all(count_chunks, NULL);
+
+  malloc_inspect_all is compiled only if MALLOC_INSPECT_ALL is defined.
+*/
+DLMALLOC_EXPORT void dlmalloc_inspect_all(void(*handler)(void*, void *, size_t, void*),
+                           void* arg);
+
+#endif /* MALLOC_INSPECT_ALL */
+
+#if !NO_MALLINFO
+/*
+  mallinfo()
+  Returns (by copy) a struct containing various summary statistics:
+
+  arena:     current total non-mmapped bytes allocated from system
+  ordblks:   the number of free chunks
+  smblks:    always zero.
+  hblks:     current number of mmapped regions
+  hblkhd:    total bytes held in mmapped regions
+  usmblks:   the maximum total allocated space. This will be greater
+                than current total if trimming has occurred.
+  fsmblks:   always zero
+  uordblks:  current total allocated space (normal or mmapped)
+  fordblks:  total free space
+  keepcost:  the maximum number of bytes that could ideally be released
+               back to system via malloc_trim. ("ideally" means that
+               it ignores page restrictions etc.)
+
+  Because these fields are ints, but internal bookkeeping may
+  be kept as longs, the reported values may wrap around zero and
+  thus be inaccurate.
+*/
+DLMALLOC_EXPORT struct mallinfo dlmallinfo(void);
+#endif /* NO_MALLINFO */
+
+/*
+  independent_calloc(size_t n_elements, size_t element_size, void* chunks[]);
+
+  independent_calloc is similar to calloc, but instead of returning a
+  single cleared space, it returns an array of pointers to n_elements
+  independent elements that can hold contents of size elem_size, each
+  of which starts out cleared, and can be independently freed,
+  realloc'ed etc. The elements are guaranteed to be adjacently
+  allocated (this is not guaranteed to occur with multiple callocs or
+  mallocs), which may also improve cache locality in some
+  applications.
+
+  The "chunks" argument is optional (i.e., may be null, which is
+  probably the most typical usage). If it is null, the returned array
+  is itself dynamically allocated and should also be freed when it is
+  no longer needed. Otherwise, the chunks array must be of at least
+  n_elements in length. It is filled in with the pointers to the
+  chunks.
+
+  In either case, independent_calloc returns this pointer array, or
+  null if the allocation failed.  If n_elements is zero and "chunks"
+  is null, it returns a chunk representing an array with zero elements
+  (which should be freed if not wanted).
+
+  Each element must be freed when it is no longer needed. This can be
+  done all at once using bulk_free.
+
+  independent_calloc simplifies and speeds up implementations of many
+  kinds of pools.  It may also be useful when constructing large data
+  structures that initially have a fixed number of fixed-sized nodes,
+  but the number is not known at compile time, and some of the nodes
+  may later need to be freed. For example:
+
+  struct Node { int item; struct Node* next; };
+
+  struct Node* build_list() {
+    struct Node** pool;
+    int n = read_number_of_nodes_needed();
+    if (n <= 0) return 0;
+    pool = (struct Node**)(independent_calloc(n, sizeof(struct Node), 0);
+    if (pool == 0) die();
+    // organize into a linked list...
+    struct Node* first = pool[0];
+    for (i = 0; i < n-1; ++i)
+      pool[i]->next = pool[i+1];
+    free(pool);     // Can now free the array (or not, if it is needed later)
+    return first;
+  }
+*/
+DLMALLOC_EXPORT void** dlindependent_calloc(size_t, size_t, void**);
+
+/*
+  independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]);
+
+  independent_comalloc allocates, all at once, a set of n_elements
+  chunks with sizes indicated in the "sizes" array.    It returns
+  an array of pointers to these elements, each of which can be
+  independently freed, realloc'ed etc. The elements are guaranteed to
+  be adjacently allocated (this is not guaranteed to occur with
+  multiple callocs or mallocs), which may also improve cache locality
+  in some applications.
+
+  The "chunks" argument is optional (i.e., may be null). If it is null
+  the returned array is itself dynamically allocated and should also
+  be freed when it is no longer needed. Otherwise, the chunks array
+  must be of at least n_elements in length. It is filled in with the
+  pointers to the chunks.
+
+  In either case, independent_comalloc returns this pointer array, or
+  null if the allocation failed.  If n_elements is zero and chunks is
+  null, it returns a chunk representing an array with zero elements
+  (which should be freed if not wanted).
+
+  Each element must be freed when it is no longer needed. This can be
+  done all at once using bulk_free.
+
+  independent_comallac differs from independent_calloc in that each
+  element may have a different size, and also that it does not
+  automatically clear elements.
+
+  independent_comalloc can be used to speed up allocation in cases
+  where several structs or objects must always be allocated at the
+  same time.  For example:
+
+  struct Head { ... }
+  struct Foot { ... }
+
+  void send_message(char* msg) {
+    int msglen = strlen(msg);
+    size_t sizes[3] = { sizeof(struct Head), msglen, sizeof(struct Foot) };
+    void* chunks[3];
+    if (independent_comalloc(3, sizes, chunks) == 0)
+      die();
+    struct Head* head = (struct Head*)(chunks[0]);
+    char*        body = (char*)(chunks[1]);
+    struct Foot* foot = (struct Foot*)(chunks[2]);
+    // ...
+  }
+
+  In general though, independent_comalloc is worth using only for
+  larger values of n_elements. For small values, you probably won't
+  detect enough difference from series of malloc calls to bother.
+
+  Overuse of independent_comalloc can increase overall memory usage,
+  since it cannot reuse existing noncontiguous small chunks that
+  might be available for some of the elements.
+*/
+DLMALLOC_EXPORT void** dlindependent_comalloc(size_t, size_t*, void**);
+
+/*
+  bulk_free(void* array[], size_t n_elements)
+  Frees and clears (sets to null) each non-null pointer in the given
+  array.  This is likely to be faster than freeing them one-by-one.
+  If footers are used, pointers that have been allocated in different
+  mspaces are not freed or cleared, and the count of all such pointers
+  is returned.  For large arrays of pointers with poor locality, it
+  may be worthwhile to sort this array before calling bulk_free.
+*/
+DLMALLOC_EXPORT size_t  dlbulk_free(void**, size_t n_elements);
+
+/*
+  pvalloc(size_t n);
+  Equivalent to valloc(minimum-page-that-holds(n)), that is,
+  round up n to nearest pagesize.
+ */
+DLMALLOC_EXPORT void*  dlpvalloc(size_t);
+
+/*
+  malloc_trim(size_t pad);
+
+  If possible, gives memory back to the system (via negative arguments
+  to sbrk) if there is unused memory at the `high' end of the malloc
+  pool or in unused MMAP segments. You can call this after freeing
+  large blocks of memory to potentially reduce the system-level memory
+  requirements of a program. However, it cannot guarantee to reduce
+  memory. Under some allocation patterns, some large free blocks of
+  memory will be locked between two used chunks, so they cannot be
+  given back to the system.
+
+  The `pad' argument to malloc_trim represents the amount of free
+  trailing space to leave untrimmed. If this argument is zero, only
+  the minimum amount of memory to maintain internal data structures
+  will be left. Non-zero arguments can be supplied to maintain enough
+  trailing space to service future expected allocations without having
+  to re-obtain memory from the system.
+
+  Malloc_trim returns 1 if it actually released any memory, else 0.
+*/
+DLMALLOC_EXPORT int  dlmalloc_trim(size_t);
+
+/*
+  malloc_stats();
+  Prints on stderr the amount of space obtained from the system (both
+  via sbrk and mmap), the maximum amount (which may be more than
+  current if malloc_trim and/or munmap got called), and the current
+  number of bytes allocated via malloc (or realloc, etc) but not yet
+  freed. Note that this is the number of bytes allocated, not the
+  number requested. It will be larger than the number requested
+  because of alignment and bookkeeping overhead. Because it includes
+  alignment wastage as being in use, this figure may be greater than
+  zero even when no user-level chunks are allocated.
+
+  The reported current and maximum system memory can be inaccurate if
+  a program makes other calls to system memory allocation functions
+  (normally sbrk) outside of malloc.
+
+  malloc_stats prints only the most commonly interesting statistics.
+  More information can be obtained by calling mallinfo.
+*/
+DLMALLOC_EXPORT void  dlmalloc_stats(void);
+
+#endif /* ONLY_MSPACES */
+
+/*
+  malloc_usable_size(void* p);
+
+  Returns the number of bytes you can actually use in
+  an allocated chunk, which may be more than you requested (although
+  often not) due to alignment and minimum size constraints.
+  You can use this many bytes without worrying about
+  overwriting other allocated objects. This is not a particularly great
+  programming practice. malloc_usable_size can be more useful in
+  debugging and assertions, for example:
+
+  p = malloc(n);
+  assert(malloc_usable_size(p) >= 256);
+*/
+size_t dlmalloc_usable_size(void*);
+
+#if MSPACES
+
+/*
+  mspace is an opaque type representing an independent
+  region of space that supports mspace_malloc, etc.
+*/
+typedef void* mspace;
+
+/*
+  create_mspace creates and returns a new independent space with the
+  given initial capacity, or, if 0, the default granularity size.  It
+  returns null if there is no system memory available to create the
+  space.  If argument locked is non-zero, the space uses a separate
+  lock to control access. The capacity of the space will grow
+  dynamically as needed to service mspace_malloc requests.  You can
+  control the sizes of incremental increases of this space by
+  compiling with a different DEFAULT_GRANULARITY or dynamically
+  setting with mallopt(M_GRANULARITY, value).
+*/
+DLMALLOC_EXPORT mspace create_mspace(size_t capacity, int locked);
+
+/*
+  destroy_mspace destroys the given space, and attempts to return all
+  of its memory back to the system, returning the total number of
+  bytes freed. After destruction, the results of access to all memory
+  used by the space become undefined.
+*/
+DLMALLOC_EXPORT size_t destroy_mspace(mspace msp);
+
+/*
+  create_mspace_with_base uses the memory supplied as the initial base
+  of a new mspace. Part (less than 128*sizeof(size_t) bytes) of this
+  space is used for bookkeeping, so the capacity must be at least this
+  large. (Otherwise 0 is returned.) When this initial space is
+  exhausted, additional memory will be obtained from the system.
+  Destroying this space will deallocate all additionally allocated
+  space (if possible) but not the initial base.
+*/
+DLMALLOC_EXPORT mspace create_mspace_with_base(void* base, size_t capacity, int locked);
+
+/*
+  mspace_track_large_chunks controls whether requests for large chunks
+  are allocated in their own untracked mmapped regions, separate from
+  others in this mspace. By default large chunks are not tracked,
+  which reduces fragmentation. However, such chunks are not
+  necessarily released to the system upon destroy_mspace.  Enabling
+  tracking by setting to true may increase fragmentation, but avoids
+  leakage when relying on destroy_mspace to release all memory
+  allocated using this space.  The function returns the previous
+  setting.
+*/
+DLMALLOC_EXPORT int mspace_track_large_chunks(mspace msp, int enable);
+
+
+/*
+  mspace_malloc behaves as malloc, but operates within
+  the given space.
+*/
+DLMALLOC_EXPORT void* mspace_malloc(mspace msp, size_t bytes);
+
+/*
+  mspace_free behaves as free, but operates within
+  the given space.
+
+  If compiled with FOOTERS==1, mspace_free is not actually needed.
+  free may be called instead of mspace_free because freed chunks from
+  any space are handled by their originating spaces.
+*/
+DLMALLOC_EXPORT void mspace_free(mspace msp, void* mem);
+
+/*
+  mspace_realloc behaves as realloc, but operates within
+  the given space.
+
+  If compiled with FOOTERS==1, mspace_realloc is not actually
+  needed.  realloc may be called instead of mspace_realloc because
+  realloced chunks from any space are handled by their originating
+  spaces.
+*/
+DLMALLOC_EXPORT void* mspace_realloc(mspace msp, void* mem, size_t newsize);
+
+/*
+  mspace_calloc behaves as calloc, but operates within
+  the given space.
+*/
+DLMALLOC_EXPORT void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size);
+
+/*
+  mspace_memalign behaves as memalign, but operates within
+  the given space.
+*/
+DLMALLOC_EXPORT void* mspace_memalign(mspace msp, size_t alignment, size_t bytes);
+
+/*
+  mspace_independent_calloc behaves as independent_calloc, but
+  operates within the given space.
+*/
+DLMALLOC_EXPORT void** mspace_independent_calloc(mspace msp, size_t n_elements,
+                                 size_t elem_size, void* chunks[]);
+
+/*
+  mspace_independent_comalloc behaves as independent_comalloc, but
+  operates within the given space.
+*/
+DLMALLOC_EXPORT void** mspace_independent_comalloc(mspace msp, size_t n_elements,
+                                   size_t sizes[], void* chunks[]);
+
+/*
+  mspace_footprint() returns the number of bytes obtained from the
+  system for this space.
+*/
+DLMALLOC_EXPORT size_t mspace_footprint(mspace msp);
+
+/*
+  mspace_max_footprint() returns the peak number of bytes obtained from the
+  system for this space.
+*/
+DLMALLOC_EXPORT size_t mspace_max_footprint(mspace msp);
+
+
+#if !NO_MALLINFO
+/*
+  mspace_mallinfo behaves as mallinfo, but reports properties of
+  the given space.
+*/
+DLMALLOC_EXPORT struct mallinfo mspace_mallinfo(mspace msp);
+#endif /* NO_MALLINFO */
+
+/*
+  malloc_usable_size(void* p) behaves the same as malloc_usable_size;
+*/
+DLMALLOC_EXPORT size_t mspace_usable_size(void* mem);
+
+/*
+  mspace_malloc_stats behaves as malloc_stats, but reports
+  properties of the given space.
+*/
+DLMALLOC_EXPORT void mspace_malloc_stats(mspace msp);
+
+/*
+  mspace_trim behaves as malloc_trim, but
+  operates within the given space.
+*/
+DLMALLOC_EXPORT int mspace_trim(mspace msp, size_t pad);
+
+/*
+  An alias for mallopt.
+*/
+DLMALLOC_EXPORT int mspace_mallopt(int, int);
+
+#endif /* MSPACES */
+
+#ifdef __cplusplus
+}  /* end of extern "C" */
+#endif /* __cplusplus */
+
+/*
+  ========================================================================
+  To make a fully customizable malloc.h header file, cut everything
+  above this line, put into file malloc.h, edit to suit, and #include it
+  on the next line, as well as in programs that use this malloc.
+  ========================================================================
+*/
+
+/* #include "malloc.h" */
+
+/*------------------------------ internal #includes ---------------------- */
+
+#ifdef _MSC_VER
+#pragma warning( disable : 4146 ) /* no "unsigned" warnings */
+#endif /* _MSC_VER */
+#if !NO_MALLOC_STATS
+#include <stdio.h>       /* for printing in malloc_stats */
+#endif /* NO_MALLOC_STATS */
+#ifndef LACKS_ERRNO_H
+#include <errno.h>       /* for MALLOC_FAILURE_ACTION */
+#endif /* LACKS_ERRNO_H */
+#ifdef DEBUG
+#if ABORT_ON_ASSERT_FAILURE
+#undef assert
+#define assert(x) if(!(x)) ABORT
+#else /* ABORT_ON_ASSERT_FAILURE */
+#include <assert.h>
+#endif /* ABORT_ON_ASSERT_FAILURE */
+#else  /* DEBUG */
+#ifndef assert
+#define assert(x)
+#endif
+#define DEBUG 0
+#endif /* DEBUG */
+#if !defined(WIN32) && !defined(LACKS_TIME_H)
+#include <time.h>        /* for magic initialization */
+#endif /* WIN32 */
+#ifndef LACKS_STDLIB_H
+#include <stdlib.h>      /* for abort() */
+#endif /* LACKS_STDLIB_H */
+#ifndef LACKS_STRING_H
+#include <string.h>      /* for memset etc */
+#endif  /* LACKS_STRING_H */
+#if USE_BUILTIN_FFS
+#ifndef LACKS_STRINGS_H
+#include <strings.h>     /* for ffs */
+#endif /* LACKS_STRINGS_H */
+#endif /* USE_BUILTIN_FFS */
+#if HAVE_MMAP
+#ifndef LACKS_SYS_MMAN_H
+/* On some versions of linux, mremap decl in mman.h needs __USE_GNU set */
+#if (defined(linux) && !defined(__USE_GNU))
+#define __USE_GNU 1
+#include <sys/mman.h>    /* for mmap */
+#undef __USE_GNU
+#else
+#include <sys/mman.h>    /* for mmap */
+#endif /* linux */
+#endif /* LACKS_SYS_MMAN_H */
+#ifndef LACKS_FCNTL_H
+#include <fcntl.h>
+#endif /* LACKS_FCNTL_H */
+#endif /* HAVE_MMAP */
+#ifndef LACKS_UNISTD_H
+#include <unistd.h>     /* for sbrk, sysconf */
+#else /* LACKS_UNISTD_H */
+#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__)
+/*extern void*     sbrk(ptrdiff_t);*/
+#endif /* FreeBSD etc */
+#endif /* LACKS_UNISTD_H */
+
+/* Declarations for locking */
+#if USE_LOCKS
+#ifndef WIN32
+#if defined (__SVR4) && defined (__sun)  /* solaris */
+#include <thread.h>
+#elif !defined(LACKS_SCHED_H)
+#include <sched.h>
+#endif /* solaris or LACKS_SCHED_H */
+#if (defined(USE_RECURSIVE_LOCKS) && USE_RECURSIVE_LOCKS != 0) || !USE_SPIN_LOCKS
+/*#include <pthread.h>*/
+#endif /* USE_RECURSIVE_LOCKS ... */
+#elif defined(_MSC_VER)
+#ifndef _M_AMD64
+/* These are already defined on AMD64 builds */
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+LONG __cdecl _InterlockedCompareExchange(LONG volatile *Dest, LONG Exchange, LONG Comp);
+LONG __cdecl _InterlockedExchange(LONG volatile *Target, LONG Value);
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* _M_AMD64 */
+#pragma intrinsic (_InterlockedCompareExchange)
+#pragma intrinsic (_InterlockedExchange)
+#define interlockedcompareexchange _InterlockedCompareExchange
+#define interlockedexchange _InterlockedExchange
+#elif defined(WIN32) && defined(__GNUC__)
+#define interlockedcompareexchange(a, b, c) __sync_val_compare_and_swap(a, c, b)
+#define interlockedexchange __sync_lock_test_and_set
+#endif /* Win32 */
+#endif /* USE_LOCKS */
+
+/* Declarations for bit scanning on win32 */
+#if defined(_MSC_VER) && _MSC_VER>=1300
+#ifndef BitScanForward /* Try to avoid pulling in WinNT.h */
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+unsigned char _BitScanForward(unsigned long *index, unsigned long mask);
+unsigned char _BitScanReverse(unsigned long *index, unsigned long mask);
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#define BitScanForward _BitScanForward
+#define BitScanReverse _BitScanReverse
+#pragma intrinsic(_BitScanForward)
+#pragma intrinsic(_BitScanReverse)
+#endif /* BitScanForward */
+#endif /* defined(_MSC_VER) && _MSC_VER>=1300 */
+
+#ifndef WIN32
+#ifndef malloc_getpagesize
+#  ifdef _SC_PAGESIZE         /* some SVR4 systems omit an underscore */
+#    ifndef _SC_PAGE_SIZE
+#      define _SC_PAGE_SIZE _SC_PAGESIZE
+#    endif
+#  endif
+#  ifdef _SC_PAGE_SIZE
+#    define malloc_getpagesize sysconf(_SC_PAGE_SIZE)
+#  else
+#    if defined(BSD) || defined(DGUX) || defined(HAVE_GETPAGESIZE)
+       extern size_t getpagesize();
+#      define malloc_getpagesize getpagesize()
+#    else
+#      ifdef WIN32 /* use supplied emulation of getpagesize */
+#        define malloc_getpagesize getpagesize()
+#      else
+#        ifndef LACKS_SYS_PARAM_H
+#          include <sys/param.h>
+#        endif
+#        ifdef EXEC_PAGESIZE
+#          define malloc_getpagesize EXEC_PAGESIZE
+#        else
+#          ifdef NBPG
+#            ifndef CLSIZE
+#              define malloc_getpagesize NBPG
+#            else
+#              define malloc_getpagesize (NBPG * CLSIZE)
+#            endif
+#          else
+#            ifdef NBPC
+#              define malloc_getpagesize NBPC
+#            else
+#              ifdef PAGESIZE
+#                define malloc_getpagesize PAGESIZE
+#              else /* just guess */
+#                define malloc_getpagesize ((size_t)4096U)
+#              endif
+#            endif
+#          endif
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+#endif
+
+/* ------------------- size_t and alignment properties -------------------- */
+
+/* The byte and bit size of a size_t */
+#define SIZE_T_SIZE         (sizeof(size_t))
+#define SIZE_T_BITSIZE      (sizeof(size_t) << 3)
+
+/* Some constants coerced to size_t */
+/* Annoying but necessary to avoid errors on some platforms */
+#define SIZE_T_ZERO         ((size_t)0)
+#define SIZE_T_ONE          ((size_t)1)
+#define SIZE_T_TWO          ((size_t)2)
+#define SIZE_T_FOUR         ((size_t)4)
+#define TWO_SIZE_T_SIZES    (SIZE_T_SIZE<<1)
+#define FOUR_SIZE_T_SIZES   (SIZE_T_SIZE<<2)
+#define SIX_SIZE_T_SIZES    (FOUR_SIZE_T_SIZES+TWO_SIZE_T_SIZES)
+#define HALF_MAX_SIZE_T     (MAX_SIZE_T / 2U)
+
+/* The bit mask value corresponding to MALLOC_ALIGNMENT */
+#define CHUNK_ALIGN_MASK    (MALLOC_ALIGNMENT - SIZE_T_ONE)
+
+/* True if address a has acceptable alignment */
+#define is_aligned(A)       (((size_t)((A)) & (CHUNK_ALIGN_MASK)) == 0)
+
+/* the number of bytes to offset an address to align it */
+#define align_offset(A)\
+ ((((size_t)(A) & CHUNK_ALIGN_MASK) == 0)? 0 :\
+  ((MALLOC_ALIGNMENT - ((size_t)(A) & CHUNK_ALIGN_MASK)) & CHUNK_ALIGN_MASK))
+
+/* -------------------------- MMAP preliminaries ------------------------- */
+
+/*
+   If HAVE_MORECORE or HAVE_MMAP are false, we just define calls and
+   checks to fail so compiler optimizer can delete code rather than
+   using so many "#if"s.
+*/
+
+
+/* MORECORE and MMAP must return MFAIL on failure */
+#define MFAIL                ((void*)(MAX_SIZE_T))
+#define CMFAIL               ((char*)(MFAIL)) /* defined for convenience */
+
+#if HAVE_MMAP
+
+#ifdef MMAP_DEFAULT
+#elif !defined(WIN32)
+#define MUNMAP_DEFAULT(a, s)  munmap((a), (s))
+#define MMAP_PROT            (PROT_READ|PROT_WRITE)
+#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
+#define MAP_ANONYMOUS        MAP_ANON
+#endif /* MAP_ANON */
+#ifdef MAP_ANONYMOUS
+#define MMAP_FLAGS           (MAP_PRIVATE|MAP_ANONYMOUS)
+#define MMAP_DEFAULT(s)       mmap(0, (s), MMAP_PROT, MMAP_FLAGS, -1, 0)
+#else /* MAP_ANONYMOUS */
+/*
+   Nearly all versions of mmap support MAP_ANONYMOUS, so the following
+   is unlikely to be needed, but is supplied just in case.
+*/
+#define MMAP_FLAGS           (MAP_PRIVATE)
+#define MMAP_DEFAULT(s) ((dev_zero_fd < 0) ? \
+           (dev_zero_fd = open("/dev/zero", O_RDWR), \
+            mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0)) : \
+            mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0))
+#endif /* MAP_ANONYMOUS */
+
+#define DIRECT_MMAP_DEFAULT(s) MMAP_DEFAULT(s)
+
+#else /* WIN32 */
+
+/* Win32 MMAP via VirtualAlloc */
+static FORCEINLINE void* win32mmap(size_t size) {
+  void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
+  return (ptr != 0)? ptr: MFAIL;
+}
+
+/* For direct MMAP, use MEM_TOP_DOWN to minimize interference */
+static FORCEINLINE void* win32direct_mmap(size_t size) {
+  void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN,
+                           PAGE_READWRITE);
+  return (ptr != 0)? ptr: MFAIL;
+}
+
+/* This function supports releasing coalesed segments */
+static FORCEINLINE int win32munmap(void* ptr, size_t size) {
+  MEMORY_BASIC_INFORMATION minfo;
+  char* cptr = (char*)ptr;
+  while (size) {
+    if (VirtualQuery(cptr, &minfo, sizeof(minfo)) == 0)
+      return -1;
+    if (minfo.BaseAddress != cptr || minfo.AllocationBase != cptr ||
+        minfo.State != MEM_COMMIT || minfo.RegionSize > size)
+      return -1;
+    if (VirtualFree(cptr, 0, MEM_RELEASE) == 0)
+      return -1;
+    cptr += minfo.RegionSize;
+    size -= minfo.RegionSize;
+  }
+  return 0;
+}
+
+#define MMAP_DEFAULT(s)             win32mmap(s)
+#define MUNMAP_DEFAULT(a, s)        win32munmap((a), (s))
+#define DIRECT_MMAP_DEFAULT(s)      win32direct_mmap(s)
+#endif /* WIN32 */
+#endif /* HAVE_MMAP */
+
+#if HAVE_MREMAP && !defined(MREMAP_DEFAULT)
+#ifndef WIN32
+#define MREMAP_DEFAULT(addr, osz, nsz, mv) mremap((addr), (osz), (nsz), (mv))
+#endif /* WIN32 */
+#endif /* HAVE_MREMAP */
+
+/**
+ * Define CALL_MORECORE
+ */
+#if HAVE_MORECORE
+    #ifdef MORECORE
+        #define CALL_MORECORE(S)    MORECORE(S)
+    #else  /* MORECORE */
+        #define CALL_MORECORE(S)    MORECORE_DEFAULT(S)
+    #endif /* MORECORE */
+#else  /* HAVE_MORECORE */
+    #define CALL_MORECORE(S)        MFAIL
+#endif /* HAVE_MORECORE */
+
+/**
+ * Define CALL_MMAP/CALL_MUNMAP/CALL_DIRECT_MMAP
+ */
+#if HAVE_MMAP
+    #define USE_MMAP_BIT            (SIZE_T_ONE)
+
+    #ifdef MMAP
+        #define CALL_MMAP(s)        MMAP(s)
+    #else /* MMAP */
+        #define CALL_MMAP(s)        MMAP_DEFAULT(s)
+    #endif /* MMAP */
+    #ifdef MUNMAP
+        #define CALL_MUNMAP(a, s)   MUNMAP((a), (s))
+    #else /* MUNMAP */
+        #define CALL_MUNMAP(a, s)   MUNMAP_DEFAULT((a), (s))
+    #endif /* MUNMAP */
+    #ifdef DIRECT_MMAP
+        #define CALL_DIRECT_MMAP(s) DIRECT_MMAP(s)
+    #else /* DIRECT_MMAP */
+        #define CALL_DIRECT_MMAP(s) DIRECT_MMAP_DEFAULT(s)
+    #endif /* DIRECT_MMAP */
+#else  /* HAVE_MMAP */
+    #define USE_MMAP_BIT            (SIZE_T_ZERO)
+
+    #define MMAP(s)                 MFAIL
+    #define MUNMAP(a, s)            (-1)
+    #define DIRECT_MMAP(s)          MFAIL
+    #define CALL_DIRECT_MMAP(s)     DIRECT_MMAP(s)
+    #define CALL_MMAP(s)            MMAP(s)
+    #define CALL_MUNMAP(a, s)       MUNMAP((a), (s))
+#endif /* HAVE_MMAP */
+
+/**
+ * Define CALL_MREMAP
+ */
+#if HAVE_MMAP && HAVE_MREMAP
+    #ifdef MREMAP
+        #define CALL_MREMAP(addr, osz, nsz, mv) MREMAP((addr), (osz), (nsz), (mv))
+    #else /* MREMAP */
+        #define CALL_MREMAP(addr, osz, nsz, mv) MREMAP_DEFAULT((addr), (osz), (nsz), (mv))
+    #endif /* MREMAP */
+#else  /* HAVE_MMAP && HAVE_MREMAP */
+    #define CALL_MREMAP(addr, osz, nsz, mv)     MFAIL
+#endif /* HAVE_MMAP && HAVE_MREMAP */
+
+/* mstate bit set if continguous morecore disabled or failed */
+#define USE_NONCONTIGUOUS_BIT (4U)
+
+/* segment bit set in create_mspace_with_base */
+#define EXTERN_BIT            (8U)
+
+
+/* --------------------------- Lock preliminaries ------------------------ */
+
+/*
+  When locks are defined, there is one global lock, plus
+  one per-mspace lock.
+
+  The global lock_ensures that mparams.magic and other unique
+  mparams values are initialized only once. It also protects
+  sequences of calls to MORECORE.  In many cases sys_alloc requires
+  two calls, that should not be interleaved with calls by other
+  threads.  This does not protect against direct calls to MORECORE
+  by other threads not using this lock, so there is still code to
+  cope the best we can on interference.
+
+  Per-mspace locks surround calls to malloc, free, etc.
+  By default, locks are simple non-reentrant mutexes.
+
+  Because lock-protected regions generally have bounded times, it is
+  OK to use the supplied simple spinlocks. Spinlocks are likely to
+  improve performance for lightly contended applications, but worsen
+  performance under heavy contention.
+
+  If USE_LOCKS is > 1, the definitions of lock routines here are
+  bypassed, in which case you will need to define the type MLOCK_T,
+  and at least INITIAL_LOCK, DESTROY_LOCK, ACQUIRE_LOCK, RELEASE_LOCK
+  and TRY_LOCK.  You must also declare a
+    static MLOCK_T malloc_global_mutex = { initialization values };.
+
+*/
+
+#if !USE_LOCKS
+#define USE_LOCK_BIT               (0U)
+#define INITIAL_LOCK(l)            (0)
+#define DESTROY_LOCK(l)            (0)
+#define ACQUIRE_MALLOC_GLOBAL_LOCK()
+#define RELEASE_MALLOC_GLOBAL_LOCK()
+
+#else
+#if USE_LOCKS > 1
+/* -----------------------  User-defined locks ------------------------ */
+/* Define your own lock implementation here */
+/* #define INITIAL_LOCK(lk)  ... */
+/* #define DESTROY_LOCK(lk)  ... */
+/* #define ACQUIRE_LOCK(lk)  ... */
+/* #define RELEASE_LOCK(lk)  ... */
+/* #define TRY_LOCK(lk) ... */
+/* static MLOCK_T malloc_global_mutex = ... */
+
+#elif USE_SPIN_LOCKS
+
+/* First, define CAS_LOCK and CLEAR_LOCK on ints */
+/* Note CAS_LOCK defined to return 0 on success */
+
+#if defined(__GNUC__)&& (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1))
+#define CAS_LOCK(sl)     __sync_lock_test_and_set(sl, 1)
+#define CLEAR_LOCK(sl)   __sync_lock_release(sl)
+
+#elif (defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)))
+/* Custom spin locks for older gcc on x86 */
+static FORCEINLINE int x86_cas_lock(int *sl) {
+  int ret;
+  int val = 1;
+  int cmp = 0;
+  __asm__ __volatile__  ("lock; cmpxchgl %1, %2"
+                         : "=a" (ret)
+                         : "r" (val), "m" (*(sl)), "0"(cmp)
+                         : "memory", "cc");
+  return ret;
+}
+
+static FORCEINLINE void x86_clear_lock(int* sl) {
+  assert(*sl != 0);
+  int prev = 0;
+  int ret;
+  __asm__ __volatile__ ("lock; xchgl %0, %1"
+                        : "=r" (ret)
+                        : "m" (*(sl)), "0"(prev)
+                        : "memory");
+}
+
+#define CAS_LOCK(sl)     x86_cas_lock(sl)
+#define CLEAR_LOCK(sl)   x86_clear_lock(sl)
+
+#else /* Win32 MSC */
+#define CAS_LOCK(sl)     interlockedexchange(sl, 1)
+#define CLEAR_LOCK(sl)   interlockedexchange (sl, 0)
+
+#endif /* ... gcc spins locks ... */
+
+/* How to yield for a spin lock */
+#define SPINS_PER_YIELD       63
+#if defined(_MSC_VER)
+#define SLEEP_EX_DURATION     50 /* delay for yield/sleep */
+#define SPIN_LOCK_YIELD  SleepEx(SLEEP_EX_DURATION, FALSE)
+#elif defined (__SVR4) && defined (__sun) /* solaris */
+#define SPIN_LOCK_YIELD   thr_yield();
+#elif !defined(LACKS_SCHED_H)
+#define SPIN_LOCK_YIELD   sched_yield();
+#else
+#define SPIN_LOCK_YIELD
+#endif /* ... yield ... */
+
+#if !defined(USE_RECURSIVE_LOCKS) || USE_RECURSIVE_LOCKS == 0
+/* Plain spin locks use single word (embedded in malloc_states) */
+static int spin_acquire_lock(int *sl) {
+  int spins = 0;
+  while (*(volatile int *)sl != 0 || CAS_LOCK(sl)) {
+    if ((++spins & SPINS_PER_YIELD) == 0) {
+      SPIN_LOCK_YIELD;
+    }
+  }
+  return 0;
+}
+
+#define MLOCK_T               int
+#define TRY_LOCK(sl)          !CAS_LOCK(sl)
+#define RELEASE_LOCK(sl)      CLEAR_LOCK(sl)
+#define ACQUIRE_LOCK(sl)      (CAS_LOCK(sl)? spin_acquire_lock(sl) : 0)
+#define INITIAL_LOCK(sl)      (*sl = 0)
+#define DESTROY_LOCK(sl)      (0)
+static MLOCK_T malloc_global_mutex = 0;
+
+#else /* USE_RECURSIVE_LOCKS */
+/* types for lock owners */
+#ifdef WIN32
+#define THREAD_ID_T           DWORD
+#define CURRENT_THREAD        GetCurrentThreadId()
+#define EQ_OWNER(X,Y)         ((X) == (Y))
+#else
+/*
+  Note: the following assume that pthread_t is a type that can be
+  initialized to (casted) zero. If this is not the case, you will need to
+  somehow redefine these or not use spin locks.
+*/
+#define THREAD_ID_T           pthread_t
+#define CURRENT_THREAD        pthread_self()
+#define EQ_OWNER(X,Y)         pthread_equal(X, Y)
+#endif
+
+struct malloc_recursive_lock {
+  int sl;
+  unsigned int c;
+  THREAD_ID_T threadid;
+};
+
+#define MLOCK_T  struct malloc_recursive_lock
+static MLOCK_T malloc_global_mutex = { 0, 0, (THREAD_ID_T)0};
+
+static FORCEINLINE void recursive_release_lock(MLOCK_T *lk) {
+  assert(lk->sl != 0);
+  if (--lk->c == 0) {
+    CLEAR_LOCK(&lk->sl);
+  }
+}
+
+static FORCEINLINE int recursive_acquire_lock(MLOCK_T *lk) {
+  THREAD_ID_T mythreadid = CURRENT_THREAD;
+  int spins = 0;
+  for (;;) {
+    if (*((volatile int *)(&lk->sl)) == 0) {
+      if (!CAS_LOCK(&lk->sl)) {
+        lk->threadid = mythreadid;
+        lk->c = 1;
+        return 0;
+      }
+    }
+    else if (EQ_OWNER(lk->threadid, mythreadid)) {
+      ++lk->c;
+      return 0;
+    }
+    if ((++spins & SPINS_PER_YIELD) == 0) {
+      SPIN_LOCK_YIELD;
+    }
+  }
+}
+
+static FORCEINLINE int recursive_try_lock(MLOCK_T *lk) {
+  THREAD_ID_T mythreadid = CURRENT_THREAD;
+  if (*((volatile int *)(&lk->sl)) == 0) {
+    if (!CAS_LOCK(&lk->sl)) {
+      lk->threadid = mythreadid;
+      lk->c = 1;
+      return 1;
+    }
+  }
+  else if (EQ_OWNER(lk->threadid, mythreadid)) {
+    ++lk->c;
+    return 1;
+  }
+  return 0;
+}
+
+#define RELEASE_LOCK(lk)      recursive_release_lock(lk)
+#define TRY_LOCK(lk)          recursive_try_lock(lk)
+#define ACQUIRE_LOCK(lk)      recursive_acquire_lock(lk)
+#define INITIAL_LOCK(lk)      ((lk)->threadid = (THREAD_ID_T)0, (lk)->sl = 0, (lk)->c = 0)
+#define DESTROY_LOCK(lk)      (0)
+#endif /* USE_RECURSIVE_LOCKS */
+
+#elif defined(WIN32) /* Win32 critical sections */
+#define MLOCK_T               CRITICAL_SECTION
+#define ACQUIRE_LOCK(lk)      (EnterCriticalSection(lk), 0)
+#define RELEASE_LOCK(lk)      LeaveCriticalSection(lk)
+#define TRY_LOCK(lk)          TryEnterCriticalSection(lk)
+#define INITIAL_LOCK(lk)      (!InitializeCriticalSectionAndSpinCount((lk), 0x80000000|4000))
+#define DESTROY_LOCK(lk)      (DeleteCriticalSection(lk), 0)
+#define NEED_GLOBAL_LOCK_INIT
+
+static MLOCK_T malloc_global_mutex;
+static volatile long malloc_global_mutex_status;
+
+/* Use spin loop to initialize global lock */
+static void init_malloc_global_mutex() {
+  for (;;) {
+    long stat = malloc_global_mutex_status;
+    if (stat > 0)
+      return;
+    /* transition to < 0 while initializing, then to > 0) */
+    if (stat == 0 &&
+        interlockedcompareexchange(&malloc_global_mutex_status, -1, 0) == 0) {
+      InitializeCriticalSection(&malloc_global_mutex);
+      interlockedexchange(&malloc_global_mutex_status,1);
+      return;
+    }
+    SleepEx(0, FALSE);
+  }
+}
+
+#else /* pthreads-based locks */
+#define MLOCK_T               pthread_mutex_t
+#define ACQUIRE_LOCK(lk)      pthread_mutex_lock(lk)
+#define RELEASE_LOCK(lk)      pthread_mutex_unlock(lk)
+#define TRY_LOCK(lk)          (!pthread_mutex_trylock(lk))
+#define INITIAL_LOCK(lk)      pthread_init_lock(lk)
+#define DESTROY_LOCK(lk)      pthread_mutex_destroy(lk)
+
+#if defined(USE_RECURSIVE_LOCKS) && USE_RECURSIVE_LOCKS != 0 && defined(linux) && !defined(PTHREAD_MUTEX_RECURSIVE)
+/* Cope with old-style linux recursive lock initialization by adding */
+/* skipped internal declaration from pthread.h */
+extern int pthread_mutexattr_setkind_np __P ((pthread_mutexattr_t *__attr,
+                                          int __kind));
+#define PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP
+#define pthread_mutexattr_settype(x,y) pthread_mutexattr_setkind_np(x,y)
+#endif /* USE_RECURSIVE_LOCKS ... */
+
+static MLOCK_T malloc_global_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static int pthread_init_lock (MLOCK_T *lk) {
+  pthread_mutexattr_t attr;
+  if (pthread_mutexattr_init(&attr)) return 1;
+#if defined(USE_RECURSIVE_LOCKS) && USE_RECURSIVE_LOCKS != 0
+  if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)) return 1;
+#endif
+  if (pthread_mutex_init(lk, &attr)) return 1;
+  if (pthread_mutexattr_destroy(&attr)) return 1;
+  return 0;
+}
+
+#endif /* ... lock types ... */
+
+/* Common code for all lock types */
+#define USE_LOCK_BIT               (2U)
+
+#ifndef ACQUIRE_MALLOC_GLOBAL_LOCK
+#define ACQUIRE_MALLOC_GLOBAL_LOCK()  ACQUIRE_LOCK(&malloc_global_mutex);
+#endif
+
+#ifndef RELEASE_MALLOC_GLOBAL_LOCK
+#define RELEASE_MALLOC_GLOBAL_LOCK()  RELEASE_LOCK(&malloc_global_mutex);
+#endif
+
+#endif /* USE_LOCKS */
+
+/* -----------------------  Chunk representations ------------------------ */
+
+/*
+  (The following includes lightly edited explanations by Colin Plumb.)
+
+  The malloc_chunk declaration below is misleading (but accurate and
+  necessary).  It declares a "view" into memory allowing access to
+  necessary fields at known offsets from a given base.
+
+  Chunks of memory are maintained using a `boundary tag' method as
+  originally described by Knuth.  (See the paper by Paul Wilson
+  ftp://ftp.cs.utexas.edu/pub/garbage/allocsrv.ps for a survey of such
+  techniques.)  Sizes of free chunks are stored both in the front of
+  each chunk and at the end.  This makes consolidating fragmented
+  chunks into bigger chunks fast.  The head fields also hold bits
+  representing whether chunks are free or in use.
+
+  Here are some pictures to make it clearer.  They are "exploded" to
+  show that the state of a chunk can be thought of as extending from
+  the high 31 bits of the head field of its header through the
+  prev_foot and PINUSE_BIT bit of the following chunk header.
+
+  A chunk that's in use looks like:
+
+   chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+           | Size of previous chunk (if P = 0)                             |
+           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P|
+         | Size of this chunk                                         1| +-+
+   mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+         |                                                               |
+         +-                                                             -+
+         |                                                               |
+         +-                                                             -+
+         |                                                               :
+         +-      size - sizeof(size_t) available payload bytes          -+
+         :                                                               |
+ chunk-> +-                                                             -+
+         |                                                               |
+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |1|
+       | Size of next chunk (may or may not be in use)               | +-+
+ mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+    And if it's free, it looks like this:
+
+   chunk-> +-                                                             -+
+           | User payload (must be in use, or we would have merged!)       |
+           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P|
+         | Size of this chunk                                         0| +-+
+   mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+         | Next pointer                                                  |
+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+         | Prev pointer                                                  |
+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+         |                                                               :
+         +-      size - sizeof(struct chunk) unused bytes               -+
+         :                                                               |
+ chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+         | Size of this chunk                                            |
+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |0|
+       | Size of next chunk (must be in use, or we would have merged)| +-+
+ mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                                                               :
+       +- User payload                                                -+
+       :                                                               |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+                                                                     |0|
+                                                                     +-+
+  Note that since we always merge adjacent free chunks, the chunks
+  adjacent to a free chunk must be in use.
+
+  Given a pointer to a chunk (which can be derived trivially from the
+  payload pointer) we can, in O(1) time, find out whether the adjacent
+  chunks are free, and if so, unlink them from the lists that they
+  are on and merge them with the current chunk.
+
+  Chunks always begin on even word boundaries, so the mem portion
+  (which is returned to the user) is also on an even word boundary, and
+  thus at least double-word aligned.
+
+  The P (PINUSE_BIT) bit, stored in the unused low-order bit of the
+  chunk size (which is always a multiple of two words), is an in-use
+  bit for the *previous* chunk.  If that bit is *clear*, then the
+  word before the current chunk size contains the previous chunk
+  size, and can be used to find the front of the previous chunk.
+  The very first chunk allocated always has this bit set, preventing
+  access to non-existent (or non-owned) memory. If pinuse is set for
+  any given chunk, then you CANNOT determine the size of the
+  previous chunk, and might even get a memory addressing fault when
+  trying to do so.
+
+  The C (CINUSE_BIT) bit, stored in the unused second-lowest bit of
+  the chunk size redundantly records whether the current chunk is
+  inuse (unless the chunk is mmapped). This redundancy enables usage
+  checks within free and realloc, and reduces indirection when freeing
+  and consolidating chunks.
+
+  Each freshly allocated chunk must have both cinuse and pinuse set.
+  That is, each allocated chunk borders either a previously allocated
+  and still in-use chunk, or the base of its memory arena. This is
+  ensured by making all allocations from the `lowest' part of any
+  found chunk.  Further, no free chunk physically borders another one,
+  so each free chunk is known to be preceded and followed by either
+  inuse chunks or the ends of memory.
+
+  Note that the `foot' of the current chunk is actually represented
+  as the prev_foot of the NEXT chunk. This makes it easier to
+  deal with alignments etc but can be very confusing when trying
+  to extend or adapt this code.
+
+  The exceptions to all this are
+
+     1. The special chunk `top' is the top-most available chunk (i.e.,
+        the one bordering the end of available memory). It is treated
+        specially.  Top is never included in any bin, is used only if
+        no other chunk is available, and is released back to the
+        system if it is very large (see M_TRIM_THRESHOLD).  In effect,
+        the top chunk is treated as larger (and thus less well
+        fitting) than any other available chunk.  The top chunk
+        doesn't update its trailing size field since there is no next
+        contiguous chunk that would have to index off it. However,
+        space is still allocated for it (TOP_FOOT_SIZE) to enable
+        separation or merging when space is extended.
+
+     3. Chunks allocated via mmap, have both cinuse and pinuse bits
+        cleared in their head fields.  Because they are allocated
+        one-by-one, each must carry its own prev_foot field, which is
+        also used to hold the offset this chunk has within its mmapped
+        region, which is needed to preserve alignment. Each mmapped
+        chunk is trailed by the first two fields of a fake next-chunk
+        for sake of usage checks.
+
+*/
+
+struct malloc_chunk {
+  size_t               prev_foot;  /* Size of previous chunk (if free).  */
+  size_t               head;       /* Size and inuse bits. */
+  struct malloc_chunk* fd;         /* double links -- used only if free. */
+  struct malloc_chunk* bk;
+};
+
+typedef struct malloc_chunk  mchunk;
+typedef struct malloc_chunk* mchunkptr;
+typedef struct malloc_chunk* sbinptr;  /* The type of bins of chunks */
+typedef unsigned int bindex_t;         /* Described below */
+typedef unsigned int binmap_t;         /* Described below */
+typedef unsigned int flag_t;           /* The type of various bit flag sets */
+
+/* ------------------- Chunks sizes and alignments ----------------------- */
+
+#define MCHUNK_SIZE         (sizeof(mchunk))
+
+#if FOOTERS
+#define CHUNK_OVERHEAD      (TWO_SIZE_T_SIZES)
+#else /* FOOTERS */
+#define CHUNK_OVERHEAD      (SIZE_T_SIZE)
+#endif /* FOOTERS */
+
+/* MMapped chunks need a second word of overhead ... */
+#define MMAP_CHUNK_OVERHEAD (TWO_SIZE_T_SIZES)
+/* ... and additional padding for fake next-chunk at foot */
+#define MMAP_FOOT_PAD       (FOUR_SIZE_T_SIZES)
+
+/* The smallest size we can malloc is an aligned minimal chunk */
+#define MIN_CHUNK_SIZE\
+  ((MCHUNK_SIZE + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK)
+
+/* conversion from malloc headers to user pointers, and back */
+#define chunk2mem(p)        ((void*)((char*)(p)       + TWO_SIZE_T_SIZES))
+#define mem2chunk(mem)      ((mchunkptr)((char*)(mem) - TWO_SIZE_T_SIZES))
+/* chunk associated with aligned address A */
+#define align_as_chunk(A)   (mchunkptr)((A) + align_offset(chunk2mem(A)))
+
+/* Bounds on request (not chunk) sizes. */
+#define MAX_REQUEST         ((-MIN_CHUNK_SIZE) << 2)
+#define MIN_REQUEST         (MIN_CHUNK_SIZE - CHUNK_OVERHEAD - SIZE_T_ONE)
+
+/* pad request bytes into a usable size */
+#define pad_request(req) \
+   (((req) + CHUNK_OVERHEAD + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK)
+
+/* pad request, checking for minimum (but not maximum) */
+#define request2size(req) \
+  (((req) < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(req))
+
+
+/* ------------------ Operations on head and foot fields ----------------- */
+
+/*
+  The head field of a chunk is or'ed with PINUSE_BIT when previous
+  adjacent chunk in use, and or'ed with CINUSE_BIT if this chunk is in
+  use, unless mmapped, in which case both bits are cleared.
+
+  FLAG4_BIT is not used by this malloc, but might be useful in extensions.
+*/
+
+#define PINUSE_BIT          (SIZE_T_ONE)
+#define CINUSE_BIT          (SIZE_T_TWO)
+#define FLAG4_BIT           (SIZE_T_FOUR)
+#define INUSE_BITS          (PINUSE_BIT|CINUSE_BIT)
+#define FLAG_BITS           (PINUSE_BIT|CINUSE_BIT|FLAG4_BIT)
+
+/* Head value for fenceposts */
+#define FENCEPOST_HEAD      (INUSE_BITS|SIZE_T_SIZE)
+
+/* extraction of fields from head words */
+#define cinuse(p)           ((p)->head & CINUSE_BIT)
+#define pinuse(p)           ((p)->head & PINUSE_BIT)
+#define flag4inuse(p)       ((p)->head & FLAG4_BIT)
+#define is_inuse(p)         (((p)->head & INUSE_BITS) != PINUSE_BIT)
+#define is_mmapped(p)       (((p)->head & INUSE_BITS) == 0)
+
+#define chunksize(p)        ((p)->head & ~(FLAG_BITS))
+
+#define clear_pinuse(p)     ((p)->head &= ~PINUSE_BIT)
+#define set_flag4(p)        ((p)->head |= FLAG4_BIT)
+#define clear_flag4(p)      ((p)->head &= ~FLAG4_BIT)
+
+/* Treat space at ptr +/- offset as a chunk */
+#define chunk_plus_offset(p, s)  ((mchunkptr)(((char*)(p)) + (s)))
+#define chunk_minus_offset(p, s) ((mchunkptr)(((char*)(p)) - (s)))
+
+/* Ptr to next or previous physical malloc_chunk. */
+#define next_chunk(p) ((mchunkptr)( ((char*)(p)) + ((p)->head & ~FLAG_BITS)))
+#define prev_chunk(p) ((mchunkptr)( ((char*)(p)) - ((p)->prev_foot) ))
+
+/* extract next chunk's pinuse bit */
+#define next_pinuse(p)  ((next_chunk(p)->head) & PINUSE_BIT)
+
+/* Get/set size at footer */
+#define get_foot(p, s)  (((mchunkptr)((char*)(p) + (s)))->prev_foot)
+#define set_foot(p, s)  (((mchunkptr)((char*)(p) + (s)))->prev_foot = (s))
+
+/* Set size, pinuse bit, and foot */
+#define set_size_and_pinuse_of_free_chunk(p, s)\
+  ((p)->head = (s|PINUSE_BIT), set_foot(p, s))
+
+/* Set size, pinuse bit, foot, and clear next pinuse */
+#define set_free_with_pinuse(p, s, n)\
+  (clear_pinuse(n), set_size_and_pinuse_of_free_chunk(p, s))
+
+/* Get the internal overhead associated with chunk p */
+#define overhead_for(p)\
+ (is_mmapped(p)? MMAP_CHUNK_OVERHEAD : CHUNK_OVERHEAD)
+
+/* Return true if malloced space is not necessarily cleared */
+#if MMAP_CLEARS
+#define calloc_must_clear(p) (!is_mmapped(p))
+#else /* MMAP_CLEARS */
+#define calloc_must_clear(p) (1)
+#endif /* MMAP_CLEARS */
+
+/* ---------------------- Overlaid data structures ----------------------- */
+
+/*
+  When chunks are not in use, they are treated as nodes of either
+  lists or trees.
+
+  "Small"  chunks are stored in circular doubly-linked lists, and look
+  like this:
+
+    chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+            |             Size of previous chunk                            |
+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    `head:' |             Size of chunk, in bytes                         |P|
+      mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+            |             Forward pointer to next chunk in list             |
+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+            |             Back pointer to previous chunk in list            |
+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+            |             Unused space (may be 0 bytes long)                .
+            .                                                               .
+            .                                                               |
+nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    `foot:' |             Size of chunk, in bytes                           |
+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+  Larger chunks are kept in a form of bitwise digital trees (aka
+  tries) keyed on chunksizes.  Because malloc_tree_chunks are only for
+  free chunks greater than 256 bytes, their size doesn't impose any
+  constraints on user chunk sizes.  Each node looks like:
+
+    chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+            |             Size of previous chunk                            |
+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    `head:' |             Size of chunk, in bytes                         |P|
+      mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+            |             Forward pointer to next chunk of same size        |
+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+            |             Back pointer to previous chunk of same size       |
+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+            |             Pointer to left child (child[0])                  |
+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+            |             Pointer to right child (child[1])                 |
+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+            |             Pointer to parent                                 |
+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+            |             bin index of this chunk                           |
+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+            |             Unused space                                      .
+            .                                                               |
+nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    `foot:' |             Size of chunk, in bytes                           |
+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+  Each tree holding treenodes is a tree of unique chunk sizes.  Chunks
+  of the same size are arranged in a circularly-linked list, with only
+  the oldest chunk (the next to be used, in our FIFO ordering)
+  actually in the tree.  (Tree members are distinguished by a non-null
+  parent pointer.)  If a chunk with the same size an an existing node
+  is inserted, it is linked off the existing node using pointers that
+  work in the same way as fd/bk pointers of small chunks.
+
+  Each tree contains a power of 2 sized range of chunk sizes (the
+  smallest is 0x100 <= x < 0x180), which is is divided in half at each
+  tree level, with the chunks in the smaller half of the range (0x100
+  <= x < 0x140 for the top nose) in the left subtree and the larger
+  half (0x140 <= x < 0x180) in the right subtree.  This is, of course,
+  done by inspecting individual bits.
+
+  Using these rules, each node's left subtree contains all smaller
+  sizes than its right subtree.  However, the node at the root of each
+  subtree has no particular ordering relationship to either.  (The
+  dividing line between the subtree sizes is based on trie relation.)
+  If we remove the last chunk of a given size from the interior of the
+  tree, we need to replace it with a leaf node.  The tree ordering
+  rules permit a node to be replaced by any leaf below it.
+
+  The smallest chunk in a tree (a common operation in a best-fit
+  allocator) can be found by walking a path to the leftmost leaf in
+  the tree.  Unlike a usual binary tree, where we follow left child
+  pointers until we reach a null, here we follow the right child
+  pointer any time the left one is null, until we reach a leaf with
+  both child pointers null. The smallest chunk in the tree will be
+  somewhere along that path.
+
+  The worst case number of steps to add, find, or remove a node is
+  bounded by the number of bits differentiating chunks within
+  bins. Under current bin calculations, this ranges from 6 up to 21
+  (for 32 bit sizes) or up to 53 (for 64 bit sizes). The typical case
+  is of course much better.
+*/
+
+struct malloc_tree_chunk {
+  /* The first four fields must be compatible with malloc_chunk */
+  size_t                    prev_foot;
+  size_t                    head;
+  struct malloc_tree_chunk* fd;
+  struct malloc_tree_chunk* bk;
+
+  struct malloc_tree_chunk* child[2];
+  struct malloc_tree_chunk* parent;
+  bindex_t                  index;
+};
+
+typedef struct malloc_tree_chunk  tchunk;
+typedef struct malloc_tree_chunk* tchunkptr;
+typedef struct malloc_tree_chunk* tbinptr; /* The type of bins of trees */
+
+/* A little helper macro for trees */
+#define leftmost_child(t) ((t)->child[0] != 0? (t)->child[0] : (t)->child[1])
+
+/* ----------------------------- Segments -------------------------------- */
+
+/*
+  Each malloc space may include non-contiguous segments, held in a
+  list headed by an embedded malloc_segment record representing the
+  top-most space. Segments also include flags holding properties of
+  the space. Large chunks that are directly allocated by mmap are not
+  included in this list. They are instead independently created and
+  destroyed without otherwise keeping track of them.
+
+  Segment management mainly comes into play for spaces allocated by
+  MMAP.  Any call to MMAP might or might not return memory that is
+  adjacent to an existing segment.  MORECORE normally contiguously
+  extends the current space, so this space is almost always adjacent,
+  which is simpler and faster to deal with. (This is why MORECORE is
+  used preferentially to MMAP when both are available -- see
+  sys_alloc.)  When allocating using MMAP, we don't use any of the
+  hinting mechanisms (inconsistently) supported in various
+  implementations of unix mmap, or distinguish reserving from
+  committing memory. Instead, we just ask for space, and exploit
+  contiguity when we get it.  It is probably possible to do
+  better than this on some systems, but no general scheme seems
+  to be significantly better.
+
+  Management entails a simpler variant of the consolidation scheme
+  used for chunks to reduce fragmentation -- new adjacent memory is
+  normally prepended or appended to an existing segment. However,
+  there are limitations compared to chunk consolidation that mostly
+  reflect the fact that segment processing is relatively infrequent
+  (occurring only when getting memory from system) and that we
+  don't expect to have huge numbers of segments:
+
+  * Segments are not indexed, so traversal requires linear scans.  (It
+    would be possible to index these, but is not worth the extra
+    overhead and complexity for most programs on most platforms.)
+  * New segments are only appended to old ones when holding top-most
+    memory; if they cannot be prepended to others, they are held in
+    different segments.
+
+  Except for the top-most segment of an mstate, each segment record
+  is kept at the tail of its segment. Segments are added by pushing
+  segment records onto the list headed by &mstate.seg for the
+  containing mstate.
+
+  Segment flags control allocation/merge/deallocation policies:
+  * If EXTERN_BIT set, then we did not allocate this segment,
+    and so should not try to deallocate or merge with others.
+    (This currently holds only for the initial segment passed
+    into create_mspace_with_base.)
+  * If USE_MMAP_BIT set, the segment may be merged with
+    other surrounding mmapped segments and trimmed/de-allocated
+    using munmap.
+  * If neither bit is set, then the segment was obtained using
+    MORECORE so can be merged with surrounding MORECORE'd segments
+    and deallocated/trimmed using MORECORE with negative arguments.
+*/
+
+struct malloc_segment {
+  char*        base;             /* base address */
+  size_t       size;             /* allocated size */
+  struct malloc_segment* next;   /* ptr to next segment */
+  flag_t       sflags;           /* mmap and extern flag */
+};
+
+#define is_mmapped_segment(S)  ((S)->sflags & USE_MMAP_BIT)
+#define is_extern_segment(S)   ((S)->sflags & EXTERN_BIT)
+
+typedef struct malloc_segment  msegment;
+typedef struct malloc_segment* msegmentptr;
+
+/* ---------------------------- malloc_state ----------------------------- */
+
+/*
+   A malloc_state holds all of the bookkeeping for a space.
+   The main fields are:
+
+  Top
+    The topmost chunk of the currently active segment. Its size is
+    cached in topsize.  The actual size of topmost space is
+    topsize+TOP_FOOT_SIZE, which includes space reserved for adding
+    fenceposts and segment records if necessary when getting more
+    space from the system.  The size at which to autotrim top is
+    cached from mparams in trim_check, except that it is disabled if
+    an autotrim fails.
+
+  Designated victim (dv)
+    This is the preferred chunk for servicing small requests that
+    don't have exact fits.  It is normally the chunk split off most
+    recently to service another small request.  Its size is cached in
+    dvsize. The link fields of this chunk are not maintained since it
+    is not kept in a bin.
+
+  SmallBins
+    An array of bin headers for free chunks.  These bins hold chunks
+    with sizes less than MIN_LARGE_SIZE bytes. Each bin contains
+    chunks of all the same size, spaced 8 bytes apart.  To simplify
+    use in double-linked lists, each bin header acts as a malloc_chunk
+    pointing to the real first node, if it exists (else pointing to
+    itself).  This avoids special-casing for headers.  But to avoid
+    waste, we allocate only the fd/bk pointers of bins, and then use
+    repositioning tricks to treat these as the fields of a chunk.
+
+  TreeBins
+    Treebins are pointers to the roots of trees holding a range of
+    sizes. There are 2 equally spaced treebins for each power of two
+    from TREE_SHIFT to TREE_SHIFT+16. The last bin holds anything
+    larger.
+
+  Bin maps
+    There is one bit map for small bins ("smallmap") and one for
+    treebins ("treemap).  Each bin sets its bit when non-empty, and
+    clears the bit when empty.  Bit operations are then used to avoid
+    bin-by-bin searching -- nearly all "search" is done without ever
+    looking at bins that won't be selected.  The bit maps
+    conservatively use 32 bits per map word, even if on 64bit system.
+    For a good description of some of the bit-based techniques used
+    here, see Henry S. Warren Jr's book "Hacker's Delight" (and
+    supplement at http://hackersdelight.org/). Many of these are
+    intended to reduce the branchiness of paths through malloc etc, as
+    well as to reduce the number of memory locations read or written.
+
+  Segments
+    A list of segments headed by an embedded malloc_segment record
+    representing the initial space.
+
+  Address check support
+    The least_addr field is the least address ever obtained from
+    MORECORE or MMAP. Attempted frees and reallocs of any address less
+    than this are trapped (unless INSECURE is defined).
+
+  Magic tag
+    A cross-check field that should always hold same value as mparams.magic.
+
+  Max allowed footprint
+    The maximum allowed bytes to allocate from system (zero means no limit)
+
+  Flags
+    Bits recording whether to use MMAP, locks, or contiguous MORECORE
+
+  Statistics
+    Each space keeps track of current and maximum system memory
+    obtained via MORECORE or MMAP.
+
+  Trim support
+    Fields holding the amount of unused topmost memory that should trigger
+    trimming, and a counter to force periodic scanning to release unused
+    non-topmost segments.
+
+  Locking
+    If USE_LOCKS is defined, the "mutex" lock is acquired and released
+    around every public call using this mspace.
+
+  Extension support
+    A void* pointer and a size_t field that can be used to help implement
+    extensions to this malloc.
+*/
+
+/* Bin types, widths and sizes */
+#define NSMALLBINS        (32U)
+#define NTREEBINS         (32U)
+#define SMALLBIN_SHIFT    (3U)
+#define SMALLBIN_WIDTH    (SIZE_T_ONE << SMALLBIN_SHIFT)
+#define TREEBIN_SHIFT     (8U)
+#define MIN_LARGE_SIZE    (SIZE_T_ONE << TREEBIN_SHIFT)
+#define MAX_SMALL_SIZE    (MIN_LARGE_SIZE - SIZE_T_ONE)
+#define MAX_SMALL_REQUEST (MAX_SMALL_SIZE - CHUNK_ALIGN_MASK - CHUNK_OVERHEAD)
+
+struct malloc_state {
+  binmap_t   smallmap;
+  binmap_t   treemap;
+  size_t     dvsize;
+  size_t     topsize;
+  char*      least_addr;
+  mchunkptr  dv;
+  mchunkptr  top;
+  size_t     trim_check;
+  size_t     release_checks;
+  size_t     magic;
+  mchunkptr  smallbins[(NSMALLBINS+1)*2];
+  tbinptr    treebins[NTREEBINS];
+  size_t     footprint;
+  size_t     max_footprint;
+  size_t     footprint_limit; /* zero means no limit */
+  flag_t     mflags;
+#if USE_LOCKS
+  MLOCK_T    mutex;     /* locate lock among fields that rarely change */
+#endif /* USE_LOCKS */
+  msegment   seg;
+  void*      extp;      /* Unused but available for extensions */
+  size_t     exts;
+};
+
+typedef struct malloc_state*    mstate;
+
+/* ------------- Global malloc_state and malloc_params ------------------- */
+
+/*
+  malloc_params holds global properties, including those that can be
+  dynamically set using mallopt. There is a single instance, mparams,
+  initialized in init_mparams. Note that the non-zeroness of "magic"
+  also serves as an initialization flag.
+*/
+
+struct malloc_params {
+  size_t magic;
+  size_t page_size;
+  size_t granularity;
+  size_t mmap_threshold;
+  size_t trim_threshold;
+  flag_t default_mflags;
+};
+
+static struct malloc_params mparams;
+
+/* Ensure mparams initialized */
+#define ensure_initialization() (void)(mparams.magic != 0 || init_mparams())
+
+#if !ONLY_MSPACES
+
+/* The global malloc_state used for all non-"mspace" calls */
+static struct malloc_state _gm_;
+#define gm                 (&_gm_)
+#define is_global(M)       ((M) == &_gm_)
+
+#endif /* !ONLY_MSPACES */
+
+#define is_initialized(M)  ((M)->top != 0)
+
+/* -------------------------- system alloc setup ------------------------- */
+
+/* Operations on mflags */
+
+#define use_lock(M)           ((M)->mflags &   USE_LOCK_BIT)
+#define enable_lock(M)        ((M)->mflags |=  USE_LOCK_BIT)
+#if USE_LOCKS
+#define disable_lock(M)       ((M)->mflags &= ~USE_LOCK_BIT)
+#else
+#define disable_lock(M)
+#endif
+
+#define use_mmap(M)           ((M)->mflags &   USE_MMAP_BIT)
+#define enable_mmap(M)        ((M)->mflags |=  USE_MMAP_BIT)
+#if HAVE_MMAP
+#define disable_mmap(M)       ((M)->mflags &= ~USE_MMAP_BIT)
+#else
+#define disable_mmap(M)
+#endif
+
+#define use_noncontiguous(M)  ((M)->mflags &   USE_NONCONTIGUOUS_BIT)
+#define disable_contiguous(M) ((M)->mflags |=  USE_NONCONTIGUOUS_BIT)
+
+#define set_lock(M,L)\
+ ((M)->mflags = (L)?\
+  ((M)->mflags | USE_LOCK_BIT) :\
+  ((M)->mflags & ~USE_LOCK_BIT))
+
+/* page-align a size */
+#define page_align(S)\
+ (((S) + (mparams.page_size - SIZE_T_ONE)) & ~(mparams.page_size - SIZE_T_ONE))
+
+/* granularity-align a size */
+#define granularity_align(S)\
+  (((S) + (mparams.granularity - SIZE_T_ONE))\
+   & ~(mparams.granularity - SIZE_T_ONE))
+
+
+/* For mmap, use granularity alignment on windows, else page-align */
+#ifdef WIN32
+#define mmap_align(S) granularity_align(S)
+#else
+#define mmap_align(S) page_align(S)
+#endif
+
+/* For sys_alloc, enough padding to ensure can malloc request on success */
+#define SYS_ALLOC_PADDING (TOP_FOOT_SIZE + MALLOC_ALIGNMENT)
+
+#define is_page_aligned(S)\
+   (((size_t)(S) & (mparams.page_size - SIZE_T_ONE)) == 0)
+#define is_granularity_aligned(S)\
+   (((size_t)(S) & (mparams.granularity - SIZE_T_ONE)) == 0)
+
+/*  True if segment S holds address A */
+#define segment_holds(S, A)\
+  ((char*)(A) >= S->base && (char*)(A) < S->base + S->size)
+
+/* Return segment holding given address */
+static msegmentptr segment_holding(mstate m, char* addr) {
+  msegmentptr sp = &m->seg;
+  for (;;) {
+    if (addr >= sp->base && addr < sp->base + sp->size)
+      return sp;
+    if ((sp = sp->next) == 0)
+      return 0;
+  }
+}
+
+/* Return true if segment contains a segment link */
+static int has_segment_link(mstate m, msegmentptr ss) {
+  msegmentptr sp = &m->seg;
+  for (;;) {
+    if ((char*)sp >= ss->base && (char*)sp < ss->base + ss->size)
+      return 1;
+    if ((sp = sp->next) == 0)
+      return 0;
+  }
+}
+
+#ifndef MORECORE_CANNOT_TRIM
+#define should_trim(M,s)  ((s) > (M)->trim_check)
+#else  /* MORECORE_CANNOT_TRIM */
+#define should_trim(M,s)  (0)
+#endif /* MORECORE_CANNOT_TRIM */
+
+/*
+  TOP_FOOT_SIZE is padding at the end of a segment, including space
+  that may be needed to place segment records and fenceposts when new
+  noncontiguous segments are added.
+*/
+#define TOP_FOOT_SIZE\
+  (align_offset(chunk2mem(0))+pad_request(sizeof(struct malloc_segment))+MIN_CHUNK_SIZE)
+
+
+/* -------------------------------  Hooks -------------------------------- */
+
+/*
+  PREACTION should be defined to return 0 on success, and nonzero on
+  failure. If you are not using locking, you can redefine these to do
+  anything you like.
+*/
+
+#if USE_LOCKS
+#define PREACTION(M)  ((use_lock(M))? ACQUIRE_LOCK(&(M)->mutex) : 0)
+#define POSTACTION(M) { if (use_lock(M)) RELEASE_LOCK(&(M)->mutex); }
+#else /* USE_LOCKS */
+
+#ifndef PREACTION
+#define PREACTION(M) (0)
+#endif  /* PREACTION */
+
+#ifndef POSTACTION
+#define POSTACTION(M)
+#endif  /* POSTACTION */
+
+#endif /* USE_LOCKS */
+
+/*
+  CORRUPTION_ERROR_ACTION is triggered upon detected bad addresses.
+  USAGE_ERROR_ACTION is triggered on detected bad frees and
+  reallocs. The argument p is an address that might have triggered the
+  fault. It is ignored by the two predefined actions, but might be
+  useful in custom actions that try to help diagnose errors.
+*/
+
+#if PROCEED_ON_ERROR
+
+/* A count of the number of corruption errors causing resets */
+int malloc_corruption_error_count;
+
+/* default corruption action */
+static void reset_on_error(mstate m);
+
+#define CORRUPTION_ERROR_ACTION(m)  reset_on_error(m)
+#define USAGE_ERROR_ACTION(m, p)
+
+#else /* PROCEED_ON_ERROR */
+
+#ifndef CORRUPTION_ERROR_ACTION
+#define CORRUPTION_ERROR_ACTION(m) ABORT
+#endif /* CORRUPTION_ERROR_ACTION */
+
+#ifndef USAGE_ERROR_ACTION
+#define USAGE_ERROR_ACTION(m,p) ABORT
+#endif /* USAGE_ERROR_ACTION */
+
+#endif /* PROCEED_ON_ERROR */
+
+
+/* -------------------------- Debugging setup ---------------------------- */
+
+#if ! DEBUG
+
+#define check_free_chunk(M,P)
+#define check_inuse_chunk(M,P)
+#define check_malloced_chunk(M,P,N)
+#define check_mmapped_chunk(M,P)
+#define check_malloc_state(M)
+#define check_top_chunk(M,P)
+
+#else /* DEBUG */
+#define check_free_chunk(M,P)       do_check_free_chunk(M,P)
+#define check_inuse_chunk(M,P)      do_check_inuse_chunk(M,P)
+#define check_top_chunk(M,P)        do_check_top_chunk(M,P)
+#define check_malloced_chunk(M,P,N) do_check_malloced_chunk(M,P,N)
+#define check_mmapped_chunk(M,P)    do_check_mmapped_chunk(M,P)
+#define check_malloc_state(M)       do_check_malloc_state(M)
+
+static void   do_check_any_chunk(mstate m, mchunkptr p);
+static void   do_check_top_chunk(mstate m, mchunkptr p);
+static void   do_check_mmapped_chunk(mstate m, mchunkptr p);
+static void   do_check_inuse_chunk(mstate m, mchunkptr p);
+static void   do_check_free_chunk(mstate m, mchunkptr p);
+static void   do_check_malloced_chunk(mstate m, void* mem, size_t s);
+static void   do_check_tree(mstate m, tchunkptr t);
+static void   do_check_treebin(mstate m, bindex_t i);
+static void   do_check_smallbin(mstate m, bindex_t i);
+static void   do_check_malloc_state(mstate m);
+static int    bin_find(mstate m, mchunkptr x);
+static size_t traverse_and_check(mstate m);
+#endif /* DEBUG */
+
+/* ---------------------------- Indexing Bins ---------------------------- */
+
+#define is_small(s)         (((s) >> SMALLBIN_SHIFT) < NSMALLBINS)
+#define small_index(s)      (bindex_t)((s)  >> SMALLBIN_SHIFT)
+#define small_index2size(i) ((i)  << SMALLBIN_SHIFT)
+#define MIN_SMALL_INDEX     (small_index(MIN_CHUNK_SIZE))
+
+/* addressing by index. See above about smallbin repositioning */
+#define smallbin_at(M, i)   ((sbinptr)((char*)&((M)->smallbins[(i)<<1])))
+#define treebin_at(M,i)     (&((M)->treebins[i]))
+
+/* assign tree index for size S to variable I. Use x86 asm if possible  */
+#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+#define compute_tree_index(S, I)\
+{\
+  unsigned int X = S >> TREEBIN_SHIFT;\
+  if (X == 0)\
+    I = 0;\
+  else if (X > 0xFFFF)\
+    I = NTREEBINS-1;\
+  else {\
+    unsigned int K = (unsigned) sizeof(X)*__CHAR_BIT__ - 1 - (unsigned) __builtin_clz(X); \
+    I =  (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\
+  }\
+}
+
+#elif defined (__INTEL_COMPILER)
+#define compute_tree_index(S, I)\
+{\
+  size_t X = S >> TREEBIN_SHIFT;\
+  if (X == 0)\
+    I = 0;\
+  else if (X > 0xFFFF)\
+    I = NTREEBINS-1;\
+  else {\
+    unsigned int K = _bit_scan_reverse (X); \
+    I =  (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\
+  }\
+}
+
+#elif defined(_MSC_VER) && _MSC_VER>=1300
+#define compute_tree_index(S, I)\
+{\
+  size_t X = S >> TREEBIN_SHIFT;\
+  if (X == 0)\
+    I = 0;\
+  else if (X > 0xFFFF)\
+    I = NTREEBINS-1;\
+  else {\
+    unsigned int K;\
+    _BitScanReverse((DWORD *) &K, (DWORD) X);\
+    I =  (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\
+  }\
+}
+
+#else /* GNUC */
+#define compute_tree_index(S, I)\
+{\
+  size_t X = S >> TREEBIN_SHIFT;\
+  if (X == 0)\
+    I = 0;\
+  else if (X > 0xFFFF)\
+    I = NTREEBINS-1;\
+  else {\
+    unsigned int Y = (unsigned int)X;\
+    unsigned int N = ((Y - 0x100) >> 16) & 8;\
+    unsigned int K = (((Y <<= N) - 0x1000) >> 16) & 4;\
+    N += K;\
+    N += K = (((Y <<= K) - 0x4000) >> 16) & 2;\
+    K = 14 - N + ((Y <<= K) >> 15);\
+    I = (K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1));\
+  }\
+}
+#endif /* GNUC */
+
+/* Bit representing maximum resolved size in a treebin at i */
+#define bit_for_tree_index(i) \
+   (i == NTREEBINS-1)? (SIZE_T_BITSIZE-1) : (((i) >> 1) + TREEBIN_SHIFT - 2)
+
+/* Shift placing maximum resolved bit in a treebin at i as sign bit */
+#define leftshift_for_tree_index(i) \
+   ((i == NTREEBINS-1)? 0 : \
+    ((SIZE_T_BITSIZE-SIZE_T_ONE) - (((i) >> 1) + TREEBIN_SHIFT - 2)))
+
+/* The size of the smallest chunk held in bin with index i */
+#define minsize_for_tree_index(i) \
+   ((SIZE_T_ONE << (((i) >> 1) + TREEBIN_SHIFT)) |  \
+   (((size_t)((i) & SIZE_T_ONE)) << (((i) >> 1) + TREEBIN_SHIFT - 1)))
+
+
+/* ------------------------ Operations on bin maps ----------------------- */
+
+/* bit corresponding to given index */
+#define idx2bit(i)              ((binmap_t)(1) << (i))
+
+/* Mark/Clear bits with given index */
+#define mark_smallmap(M,i)      ((M)->smallmap |=  idx2bit(i))
+#define clear_smallmap(M,i)     ((M)->smallmap &= ~idx2bit(i))
+#define smallmap_is_marked(M,i) ((M)->smallmap &   idx2bit(i))
+
+#define mark_treemap(M,i)       ((M)->treemap  |=  idx2bit(i))
+#define clear_treemap(M,i)      ((M)->treemap  &= ~idx2bit(i))
+#define treemap_is_marked(M,i)  ((M)->treemap  &   idx2bit(i))
+
+/* isolate the least set bit of a bitmap */
+#define least_bit(x)         ((x) & -(x))
+
+/* mask with all bits to left of least bit of x on */
+#define left_bits(x)         ((x<<1) | -(x<<1))
+
+/* mask with all bits to left of or equal to least bit of x on */
+#define same_or_left_bits(x) ((x) | -(x))
+
+/* index corresponding to given bit. Use x86 asm if possible */
+
+#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+#define compute_bit2idx(X, I)\
+{\
+  unsigned int J;\
+  J = __builtin_ctz(X); \
+  I = (bindex_t)J;\
+}
+
+#elif defined (__INTEL_COMPILER)
+#define compute_bit2idx(X, I)\
+{\
+  unsigned int J;\
+  J = _bit_scan_forward (X); \
+  I = (bindex_t)J;\
+}
+
+#elif defined(_MSC_VER) && _MSC_VER>=1300
+#define compute_bit2idx(X, I)\
+{\
+  unsigned int J;\
+  _BitScanForward((DWORD *) &J, X);\
+  I = (bindex_t)J;\
+}
+
+#elif USE_BUILTIN_FFS
+#define compute_bit2idx(X, I) I = ffs(X)-1
+
+#else
+#define compute_bit2idx(X, I)\
+{\
+  unsigned int Y = X - 1;\
+  unsigned int K = Y >> (16-4) & 16;\
+  unsigned int N = K;        Y >>= K;\
+  N += K = Y >> (8-3) &  8;  Y >>= K;\
+  N += K = Y >> (4-2) &  4;  Y >>= K;\
+  N += K = Y >> (2-1) &  2;  Y >>= K;\
+  N += K = Y >> (1-0) &  1;  Y >>= K;\
+  I = (bindex_t)(N + Y);\
+}
+#endif /* GNUC */
+
+
+/* ----------------------- Runtime Check Support ------------------------- */
+
+/*
+  For security, the main invariant is that malloc/free/etc never
+  writes to a static address other than malloc_state, unless static
+  malloc_state itself has been corrupted, which cannot occur via
+  malloc (because of these checks). In essence this means that we
+  believe all pointers, sizes, maps etc held in malloc_state, but
+  check all of those linked or offsetted from other embedded data
+  structures.  These checks are interspersed with main code in a way
+  that tends to minimize their run-time cost.
+
+  When FOOTERS is defined, in addition to range checking, we also
+  verify footer fields of inuse chunks, which can be used guarantee
+  that the mstate controlling malloc/free is intact.  This is a
+  streamlined version of the approach described by William Robertson
+  et al in "Run-time Detection of Heap-based Overflows" LISA'03
+  http://www.usenix.org/events/lisa03/tech/robertson.html The footer
+  of an inuse chunk holds the xor of its mstate and a random seed,
+  that is checked upon calls to free() and realloc().  This is
+  (probabalistically) unguessable from outside the program, but can be
+  computed by any code successfully malloc'ing any chunk, so does not
+  itself provide protection against code that has already broken
+  security through some other means.  Unlike Robertson et al, we
+  always dynamically check addresses of all offset chunks (previous,
+  next, etc). This turns out to be cheaper than relying on hashes.
+*/
+
+#if !INSECURE
+/* Check if address a is at least as high as any from MORECORE or MMAP */
+#define ok_address(M, a) ((char*)(a) >= (M)->least_addr)
+/* Check if address of next chunk n is higher than base chunk p */
+#define ok_next(p, n)    ((char*)(p) < (char*)(n))
+/* Check if p has inuse status */
+#define ok_inuse(p)     is_inuse(p)
+/* Check if p has its pinuse bit on */
+#define ok_pinuse(p)     pinuse(p)
+
+#else /* !INSECURE */
+#define ok_address(M, a) (1)
+#define ok_next(b, n)    (1)
+#define ok_inuse(p)      (1)
+#define ok_pinuse(p)     (1)
+#endif /* !INSECURE */
+
+#if (FOOTERS && !INSECURE)
+/* Check if (alleged) mstate m has expected magic field */
+#define ok_magic(M)      ((M)->magic == mparams.magic)
+#else  /* (FOOTERS && !INSECURE) */
+#define ok_magic(M)      (1)
+#endif /* (FOOTERS && !INSECURE) */
+
+/* In gcc, use __builtin_expect to minimize impact of checks */
+#if !INSECURE
+#if defined(__GNUC__) && __GNUC__ >= 3
+#define RTCHECK(e)  __builtin_expect(e, 1)
+#else /* GNUC */
+#define RTCHECK(e)  (e)
+#endif /* GNUC */
+#else /* !INSECURE */
+#define RTCHECK(e)  (1)
+#endif /* !INSECURE */
+
+/* macros to set up inuse chunks with or without footers */
+
+#if !FOOTERS
+
+#define mark_inuse_foot(M,p,s)
+
+/* Macros for setting head/foot of non-mmapped chunks */
+
+/* Set cinuse bit and pinuse bit of next chunk */
+#define set_inuse(M,p,s)\
+  ((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\
+  ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT)
+
+/* Set cinuse and pinuse of this chunk and pinuse of next chunk */
+#define set_inuse_and_pinuse(M,p,s)\
+  ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\
+  ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT)
+
+/* Set size, cinuse and pinuse bit of this chunk */
+#define set_size_and_pinuse_of_inuse_chunk(M, p, s)\
+  ((p)->head = (s|PINUSE_BIT|CINUSE_BIT))
+
+#else /* FOOTERS */
+
+/* Set foot of inuse chunk to be xor of mstate and seed */
+#define mark_inuse_foot(M,p,s)\
+  (((mchunkptr)((char*)(p) + (s)))->prev_foot = ((size_t)(M) ^ mparams.magic))
+
+#define get_mstate_for(p)\
+  ((mstate)(((mchunkptr)((char*)(p) +\
+    (chunksize(p))))->prev_foot ^ mparams.magic))
+
+#define set_inuse(M,p,s)\
+  ((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\
+  (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT), \
+  mark_inuse_foot(M,p,s))
+
+#define set_inuse_and_pinuse(M,p,s)\
+  ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\
+  (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT),\
+ mark_inuse_foot(M,p,s))
+
+#define set_size_and_pinuse_of_inuse_chunk(M, p, s)\
+  ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\
+  mark_inuse_foot(M, p, s))
+
+#endif /* !FOOTERS */
+
+/* ---------------------------- setting mparams -------------------------- */
+
+/* Initialize mparams */
+static int init_mparams(void) {
+#ifdef NEED_GLOBAL_LOCK_INIT
+    call_once(&malloc_global_mutex_init_once, init_malloc_global_mutex);
+#endif
+
+  ACQUIRE_MALLOC_GLOBAL_LOCK();
+  if (mparams.magic == 0) {
+    size_t magic;
+    size_t psize;
+    size_t gsize;
+
+#ifndef WIN32
+    psize = malloc_getpagesize;
+    gsize = ((DEFAULT_GRANULARITY != 0)? DEFAULT_GRANULARITY : psize);
+#else /* WIN32 */
+    {
+      SYSTEM_INFO system_info;
+      GetSystemInfo(&system_info);
+      psize = system_info.dwPageSize;
+      gsize = ((DEFAULT_GRANULARITY != 0)?
+               DEFAULT_GRANULARITY : system_info.dwAllocationGranularity);
+    }
+#endif /* WIN32 */
+
+    /* Sanity-check configuration:
+       size_t must be unsigned and as wide as pointer type.
+       ints must be at least 4 bytes.
+       alignment must be at least 8.
+       Alignment, min chunk size, and page size must all be powers of 2.
+    */
+    if ((sizeof(size_t) != sizeof(char*)) ||
+        (MAX_SIZE_T < MIN_CHUNK_SIZE)  ||
+        (sizeof(int) < 4)  ||
+        (MALLOC_ALIGNMENT < (size_t)8U) ||
+        ((MALLOC_ALIGNMENT & (MALLOC_ALIGNMENT-SIZE_T_ONE)) != 0) ||
+        ((MCHUNK_SIZE      & (MCHUNK_SIZE-SIZE_T_ONE))      != 0) ||
+        ((gsize            & (gsize-SIZE_T_ONE))            != 0) ||
+        ((psize            & (psize-SIZE_T_ONE))            != 0))
+      ABORT;
+
+    mparams.granularity = gsize;
+    mparams.page_size = psize;
+    mparams.mmap_threshold = DEFAULT_MMAP_THRESHOLD;
+    mparams.trim_threshold = DEFAULT_TRIM_THRESHOLD;
+#if MORECORE_CONTIGUOUS
+    mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT;
+#else  /* MORECORE_CONTIGUOUS */
+    mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT|USE_NONCONTIGUOUS_BIT;
+#endif /* MORECORE_CONTIGUOUS */
+
+#if !ONLY_MSPACES
+    /* Set up lock for main malloc area */
+    gm->mflags = mparams.default_mflags;
+    (void)INITIAL_LOCK(&gm->mutex);
+#endif
+
+    {
+#if USE_DEV_RANDOM
+      int fd;
+      unsigned char buf[sizeof(size_t)];
+      /* Try to use /dev/urandom, else fall back on using time */
+      if ((fd = open("/dev/urandom", O_RDONLY)) >= 0 &&
+          read(fd, buf, sizeof(buf)) == sizeof(buf)) {
+        magic = *((size_t *) buf);
+        close(fd);
+      }
+      else
+#endif /* USE_DEV_RANDOM */
+#ifdef WIN32
+        magic = (size_t)(GetTickCount() ^ (size_t)0x55555555U);
+#elif defined(LACKS_TIME_H)
+      magic = (size_t)&magic ^ (size_t)0x55555555U;
+#else
+        magic = (size_t)(time(0) ^ (size_t)0x55555555U);
+#endif
+      magic |= (size_t)8U;    /* ensure nonzero */
+      magic &= ~(size_t)7U;   /* improve chances of fault for bad values */
+      /* Until memory modes commonly available, use volatile-write */
+      (*(volatile size_t *)(&(mparams.magic))) = magic;
+    }
+  }
+
+  RELEASE_MALLOC_GLOBAL_LOCK();
+  return 1;
+}
+
+/* support for mallopt */
+static int change_mparam(int param_number, int value) {
+  size_t val;
+  ensure_initialization();
+  val = (value == -1)? MAX_SIZE_T : (size_t)value;
+  switch(param_number) {
+  case M_TRIM_THRESHOLD:
+    mparams.trim_threshold = val;
+    return 1;
+  case M_GRANULARITY:
+    if (val >= mparams.page_size && ((val & (val-1)) == 0)) {
+      mparams.granularity = val;
+      return 1;
+    }
+    else
+      return 0;
+  case M_MMAP_THRESHOLD:
+    mparams.mmap_threshold = val;
+    return 1;
+  default:
+    return 0;
+  }
+}
+
+#if DEBUG
+/* ------------------------- Debugging Support --------------------------- */
+
+/* Check properties of any chunk, whether free, inuse, mmapped etc  */
+static void do_check_any_chunk(mstate m, mchunkptr p) {
+  assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD));
+  assert(ok_address(m, p));
+}
+
+/* Check properties of top chunk */
+static void do_check_top_chunk(mstate m, mchunkptr p) {
+  msegmentptr sp = segment_holding(m, (char*)p);
+  size_t  sz = p->head & ~INUSE_BITS; /* third-lowest bit can be set! */
+  assert(sp != 0);
+  assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD));
+  assert(ok_address(m, p));
+  assert(sz == m->topsize);
+  assert(sz > 0);
+  assert(sz == ((sp->base + sp->size) - (char*)p) - TOP_FOOT_SIZE);
+  assert(pinuse(p));
+  assert(!pinuse(chunk_plus_offset(p, sz)));
+}
+
+/* Check properties of (inuse) mmapped chunks */
+static void do_check_mmapped_chunk(mstate m, mchunkptr p) {
+  size_t  sz = chunksize(p);
+  size_t len = (sz + (p->prev_foot) + MMAP_FOOT_PAD);
+  assert(is_mmapped(p));
+  assert(use_mmap(m));
+  assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD));
+  assert(ok_address(m, p));
+  assert(!is_small(sz));
+  assert((len & (mparams.page_size-SIZE_T_ONE)) == 0);
+  assert(chunk_plus_offset(p, sz)->head == FENCEPOST_HEAD);
+  assert(chunk_plus_offset(p, sz+SIZE_T_SIZE)->head == 0);
+}
+
+/* Check properties of inuse chunks */
+static void do_check_inuse_chunk(mstate m, mchunkptr p) {
+  do_check_any_chunk(m, p);
+  assert(is_inuse(p));
+  assert(next_pinuse(p));
+  /* If not pinuse and not mmapped, previous chunk has OK offset */
+  assert(is_mmapped(p) || pinuse(p) || next_chunk(prev_chunk(p)) == p);
+  if (is_mmapped(p))
+    do_check_mmapped_chunk(m, p);
+}
+
+/* Check properties of free chunks */
+static void do_check_free_chunk(mstate m, mchunkptr p) {
+  size_t sz = chunksize(p);
+  mchunkptr next = chunk_plus_offset(p, sz);
+  do_check_any_chunk(m, p);
+  assert(!is_inuse(p));
+  assert(!next_pinuse(p));
+  assert (!is_mmapped(p));
+  if (p != m->dv && p != m->top) {
+    if (sz >= MIN_CHUNK_SIZE) {
+      assert((sz & CHUNK_ALIGN_MASK) == 0);
+      assert(is_aligned(chunk2mem(p)));
+      assert(next->prev_foot == sz);
+      assert(pinuse(p));
+      assert (next == m->top || is_inuse(next));
+      assert(p->fd->bk == p);
+      assert(p->bk->fd == p);
+    }
+    else  /* markers are always of size SIZE_T_SIZE */
+      assert(sz == SIZE_T_SIZE);
+  }
+}
+
+/* Check properties of malloced chunks at the point they are malloced */
+static void do_check_malloced_chunk(mstate m, void* mem, size_t s) {
+  if (mem != 0) {
+    mchunkptr p = mem2chunk(mem);
+    size_t sz = p->head & ~INUSE_BITS;
+    do_check_inuse_chunk(m, p);
+    assert((sz & CHUNK_ALIGN_MASK) == 0);
+    assert(sz >= MIN_CHUNK_SIZE);
+    assert(sz >= s);
+    /* unless mmapped, size is less than MIN_CHUNK_SIZE more than request */
+    assert(is_mmapped(p) || sz < (s + MIN_CHUNK_SIZE));
+  }
+}
+
+/* Check a tree and its subtrees.  */
+static void do_check_tree(mstate m, tchunkptr t) {
+  tchunkptr head = 0;
+  tchunkptr u = t;
+  bindex_t tindex = t->index;
+  size_t tsize = chunksize(t);
+  bindex_t idx;
+  compute_tree_index(tsize, idx);
+  assert(tindex == idx);
+  assert(tsize >= MIN_LARGE_SIZE);
+  assert(tsize >= minsize_for_tree_index(idx));
+  assert((idx == NTREEBINS-1) || (tsize < minsize_for_tree_index((idx+1))));
+
+  do { /* traverse through chain of same-sized nodes */
+    do_check_any_chunk(m, ((mchunkptr)u));
+    assert(u->index == tindex);
+    assert(chunksize(u) == tsize);
+    assert(!is_inuse(u));
+    assert(!next_pinuse(u));
+    assert(u->fd->bk == u);
+    assert(u->bk->fd == u);
+    if (u->parent == 0) {
+      assert(u->child[0] == 0);
+      assert(u->child[1] == 0);
+    }
+    else {
+      assert(head == 0); /* only one node on chain has parent */
+      head = u;
+      assert(u->parent != u);
+      assert (u->parent->child[0] == u ||
+              u->parent->child[1] == u ||
+              *((tbinptr*)(u->parent)) == u);
+      if (u->child[0] != 0) {
+        assert(u->child[0]->parent == u);
+        assert(u->child[0] != u);
+        do_check_tree(m, u->child[0]);
+      }
+      if (u->child[1] != 0) {
+        assert(u->child[1]->parent == u);
+        assert(u->child[1] != u);
+        do_check_tree(m, u->child[1]);
+      }
+      if (u->child[0] != 0 && u->child[1] != 0) {
+        assert(chunksize(u->child[0]) < chunksize(u->child[1]));
+      }
+    }
+    u = u->fd;
+  } while (u != t);
+  assert(head != 0);
+}
+
+/*  Check all the chunks in a treebin.  */
+static void do_check_treebin(mstate m, bindex_t i) {
+  tbinptr* tb = treebin_at(m, i);
+  tchunkptr t = *tb;
+  int empty = (m->treemap & (1U << i)) == 0;
+  if (t == 0)
+    assert(empty);
+  if (!empty)
+    do_check_tree(m, t);
+}
+
+/*  Check all the chunks in a smallbin.  */
+static void do_check_smallbin(mstate m, bindex_t i) {
+  sbinptr b = smallbin_at(m, i);
+  mchunkptr p = b->bk;
+  unsigned int empty = (m->smallmap & (1U << i)) == 0;
+  if (p == b)
+    assert(empty);
+  if (!empty) {
+    for (; p != b; p = p->bk) {
+      size_t size = chunksize(p);
+      mchunkptr q;
+      /* each chunk claims to be free */
+      do_check_free_chunk(m, p);
+      /* chunk belongs in bin */
+      assert(small_index(size) == i);
+      assert(p->bk == b || chunksize(p->bk) == chunksize(p));
+      /* chunk is followed by an inuse chunk */
+      q = next_chunk(p);
+      if (q->head != FENCEPOST_HEAD)
+        do_check_inuse_chunk(m, q);
+    }
+  }
+}
+
+/* Find x in a bin. Used in other check functions. */
+static int bin_find(mstate m, mchunkptr x) {
+  size_t size = chunksize(x);
+  if (is_small(size)) {
+    bindex_t sidx = small_index(size);
+    sbinptr b = smallbin_at(m, sidx);
+    if (smallmap_is_marked(m, sidx)) {
+      mchunkptr p = b;
+      do {
+        if (p == x)
+          return 1;
+      } while ((p = p->fd) != b);
+    }
+  }
+  else {
+    bindex_t tidx;
+    compute_tree_index(size, tidx);
+    if (treemap_is_marked(m, tidx)) {
+      tchunkptr t = *treebin_at(m, tidx);
+      size_t sizebits = size << leftshift_for_tree_index(tidx);
+      while (t != 0 && chunksize(t) != size) {
+        t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1];
+        sizebits <<= 1;
+      }
+      if (t != 0) {
+        tchunkptr u = t;
+        do {
+          if (u == (tchunkptr)x)
+            return 1;
+        } while ((u = u->fd) != t);
+      }
+    }
+  }
+  return 0;
+}
+
+/* Traverse each chunk and check it; return total */
+static size_t traverse_and_check(mstate m) {
+  size_t sum = 0;
+  if (is_initialized(m)) {
+    msegmentptr s = &m->seg;
+    sum += m->topsize + TOP_FOOT_SIZE;
+    while (s != 0) {
+      mchunkptr q = align_as_chunk(s->base);
+      mchunkptr lastq = 0;
+      assert(pinuse(q));
+      while (segment_holds(s, q) &&
+             q != m->top && q->head != FENCEPOST_HEAD) {
+        sum += chunksize(q);
+        if (is_inuse(q)) {
+          assert(!bin_find(m, q));
+          do_check_inuse_chunk(m, q);
+        }
+        else {
+          assert(q == m->dv || bin_find(m, q));
+          assert(lastq == 0 || is_inuse(lastq)); /* Not 2 consecutive free */
+          do_check_free_chunk(m, q);
+        }
+        lastq = q;
+        q = next_chunk(q);
+      }
+      s = s->next;
+    }
+  }
+  return sum;
+}
+
+
+/* Check all properties of malloc_state. */
+static void do_check_malloc_state(mstate m) {
+  bindex_t i;
+  size_t total;
+  /* check bins */
+  for (i = 0; i < NSMALLBINS; ++i)
+    do_check_smallbin(m, i);
+  for (i = 0; i < NTREEBINS; ++i)
+    do_check_treebin(m, i);
+
+  if (m->dvsize != 0) { /* check dv chunk */
+    do_check_any_chunk(m, m->dv);
+    assert(m->dvsize == chunksize(m->dv));
+    assert(m->dvsize >= MIN_CHUNK_SIZE);
+    assert(bin_find(m, m->dv) == 0);
+  }
+
+  if (m->top != 0) {   /* check top chunk */
+    do_check_top_chunk(m, m->top);
+    /*assert(m->topsize == chunksize(m->top)); redundant */
+    assert(m->topsize > 0);
+    assert(bin_find(m, m->top) == 0);
+  }
+
+  total = traverse_and_check(m);
+  assert(total <= m->footprint);
+  assert(m->footprint <= m->max_footprint);
+}
+#endif /* DEBUG */
+
+/* ----------------------------- statistics ------------------------------ */
+
+#if !NO_MALLINFO
+static struct mallinfo internal_mallinfo(mstate m) {
+  struct mallinfo nm = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+  ensure_initialization();
+  if (!PREACTION(m)) {
+    check_malloc_state(m);
+    if (is_initialized(m)) {
+      size_t nfree = SIZE_T_ONE; /* top always free */
+      size_t mfree = m->topsize + TOP_FOOT_SIZE;
+      size_t sum = mfree;
+      msegmentptr s = &m->seg;
+      while (s != 0) {
+        mchunkptr q = align_as_chunk(s->base);
+        while (segment_holds(s, q) &&
+               q != m->top && q->head != FENCEPOST_HEAD) {
+          size_t sz = chunksize(q);
+          sum += sz;
+          if (!is_inuse(q)) {
+            mfree += sz;
+            ++nfree;
+          }
+          q = next_chunk(q);
+        }
+        s = s->next;
+      }
+
+      nm.arena    = sum;
+      nm.ordblks  = nfree;
+      nm.hblkhd   = m->footprint - sum;
+      nm.usmblks  = m->max_footprint;
+      nm.uordblks = m->footprint - mfree;
+      nm.fordblks = mfree;
+      nm.keepcost = m->topsize;
+    }
+
+    POSTACTION(m);
+  }
+  return nm;
+}
+#endif /* !NO_MALLINFO */
+
+#if !NO_MALLOC_STATS
+static void internal_malloc_stats(mstate m) {
+  ensure_initialization();
+  if (!PREACTION(m)) {
+    size_t maxfp = 0;
+    size_t fp = 0;
+    size_t used = 0;
+    check_malloc_state(m);
+    if (is_initialized(m)) {
+      msegmentptr s = &m->seg;
+      maxfp = m->max_footprint;
+      fp = m->footprint;
+      used = fp - (m->topsize + TOP_FOOT_SIZE);
+
+      while (s != 0) {
+        mchunkptr q = align_as_chunk(s->base);
+        while (segment_holds(s, q) &&
+               q != m->top && q->head != FENCEPOST_HEAD) {
+          if (!is_inuse(q))
+            used -= chunksize(q);
+          q = next_chunk(q);
+        }
+        s = s->next;
+      }
+    }
+    POSTACTION(m); /* drop lock */
+    fprintf(stderr, "max system bytes = %10lu\n", (unsigned long)(maxfp));
+    fprintf(stderr, "system bytes     = %10lu\n", (unsigned long)(fp));
+    fprintf(stderr, "in use bytes     = %10lu\n", (unsigned long)(used));
+  }
+}
+#endif /* NO_MALLOC_STATS */
+
+/* ----------------------- Operations on smallbins ----------------------- */
+
+/*
+  Various forms of linking and unlinking are defined as macros.  Even
+  the ones for trees, which are very long but have very short typical
+  paths.  This is ugly but reduces reliance on inlining support of
+  compilers.
+*/
+
+/* Link a free chunk into a smallbin  */
+#define insert_small_chunk(M, P, S) {\
+  bindex_t I  = small_index(S);\
+  mchunkptr B = smallbin_at(M, I);\
+  mchunkptr F = B;\
+  assert(S >= MIN_CHUNK_SIZE);\
+  if (!smallmap_is_marked(M, I))\
+    mark_smallmap(M, I);\
+  else if (RTCHECK(ok_address(M, B->fd)))\
+    F = B->fd;\
+  else {\
+    CORRUPTION_ERROR_ACTION(M);\
+  }\
+  B->fd = P;\
+  F->bk = P;\
+  P->fd = F;\
+  P->bk = B;\
+}
+
+/* Unlink a chunk from a smallbin  */
+#define unlink_small_chunk(M, P, S) {\
+  mchunkptr F = P->fd;\
+  mchunkptr B = P->bk;\
+  bindex_t I = small_index(S);\
+  assert(P != B);\
+  assert(P != F);\
+  assert(chunksize(P) == small_index2size(I));\
+  if (RTCHECK(F == smallbin_at(M,I) || (ok_address(M, F) && F->bk == P))) { \
+    if (B == F) {\
+      clear_smallmap(M, I);\
+    }\
+    else if (RTCHECK(B == smallbin_at(M,I) ||\
+                     (ok_address(M, B) && B->fd == P))) {\
+      F->bk = B;\
+      B->fd = F;\
+    }\
+    else {\
+      CORRUPTION_ERROR_ACTION(M);\
+    }\
+  }\
+  else {\
+    CORRUPTION_ERROR_ACTION(M);\
+  }\
+}
+
+/* Unlink the first chunk from a smallbin */
+#define unlink_first_small_chunk(M, B, P, I) {\
+  mchunkptr F = P->fd;\
+  assert(P != B);\
+  assert(P != F);\
+  assert(chunksize(P) == small_index2size(I));\
+  if (B == F) {\
+    clear_smallmap(M, I);\
+  }\
+  else if (RTCHECK(ok_address(M, F) && F->bk == P)) {\
+    F->bk = B;\
+    B->fd = F;\
+  }\
+  else {\
+    CORRUPTION_ERROR_ACTION(M);\
+  }\
+}
+
+/* Replace dv node, binning the old one */
+/* Used only when dvsize known to be small */
+#define replace_dv(M, P, S) {\
+  size_t DVS = M->dvsize;\
+  assert(is_small(DVS));\
+  if (DVS != 0) {\
+    mchunkptr DV = M->dv;\
+    insert_small_chunk(M, DV, DVS);\
+  }\
+  M->dvsize = S;\
+  M->dv = P;\
+}
+
+/* ------------------------- Operations on trees ------------------------- */
+
+/* Insert chunk into tree */
+#define insert_large_chunk(M, X, S) {\
+  tbinptr* H;\
+  bindex_t I;\
+  compute_tree_index(S, I);\
+  H = treebin_at(M, I);\
+  X->index = I;\
+  X->child[0] = X->child[1] = 0;\
+  if (!treemap_is_marked(M, I)) {\
+    mark_treemap(M, I);\
+    *H = X;\
+    X->parent = (tchunkptr)H;\
+    X->fd = X->bk = X;\
+  }\
+  else {\
+    tchunkptr T = *H;\
+    size_t K = S << leftshift_for_tree_index(I);\
+    for (;;) {\
+      if (chunksize(T) != S) {\
+        tchunkptr* C = &(T->child[(K >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]);\
+        K <<= 1;\
+        if (*C != 0)\
+          T = *C;\
+        else if (RTCHECK(ok_address(M, C))) {\
+          *C = X;\
+          X->parent = T;\
+          X->fd = X->bk = X;\
+          break;\
+        }\
+        else {\
+          CORRUPTION_ERROR_ACTION(M);\
+          break;\
+        }\
+      }\
+      else {\
+        tchunkptr F = T->fd;\
+        if (RTCHECK(ok_address(M, T) && ok_address(M, F))) {\
+          T->fd = F->bk = X;\
+          X->fd = F;\
+          X->bk = T;\
+          X->parent = 0;\
+          break;\
+        }\
+        else {\
+          CORRUPTION_ERROR_ACTION(M);\
+          break;\
+        }\
+      }\
+    }\
+  }\
+}
+
+/*
+  Unlink steps:
+
+  1. If x is a chained node, unlink it from its same-sized fd/bk links
+     and choose its bk node as its replacement.
+  2. If x was the last node of its size, but not a leaf node, it must
+     be replaced with a leaf node (not merely one with an open left or
+     right), to make sure that lefts and rights of descendents
+     correspond properly to bit masks.  We use the rightmost descendent
+     of x.  We could use any other leaf, but this is easy to locate and
+     tends to counteract removal of leftmosts elsewhere, and so keeps
+     paths shorter than minimally guaranteed.  This doesn't loop much
+     because on average a node in a tree is near the bottom.
+  3. If x is the base of a chain (i.e., has parent links) relink
+     x's parent and children to x's replacement (or null if none).
+*/
+
+#define unlink_large_chunk(M, X) {\
+  tchunkptr XP = X->parent;\
+  tchunkptr R;\
+  if (X->bk != X) {\
+    tchunkptr F = X->fd;\
+    R = X->bk;\
+    if (RTCHECK(ok_address(M, F) && F->bk == X && R->fd == X)) {\
+      F->bk = R;\
+      R->fd = F;\
+    }\
+    else {\
+      CORRUPTION_ERROR_ACTION(M);\
+    }\
+  }\
+  else {\
+    tchunkptr* RP;\
+    if (((R = *(RP = &(X->child[1]))) != 0) ||\
+        ((R = *(RP = &(X->child[0]))) != 0)) {\
+      tchunkptr* CP;\
+      while ((*(CP = &(R->child[1])) != 0) ||\
+             (*(CP = &(R->child[0])) != 0)) {\
+        R = *(RP = CP);\
+      }\
+      if (RTCHECK(ok_address(M, RP)))\
+        *RP = 0;\
+      else {\
+        CORRUPTION_ERROR_ACTION(M);\
+      }\
+    }\
+  }\
+  if (XP != 0) {\
+    tbinptr* H = treebin_at(M, X->index);\
+    if (X == *H) {\
+      if ((*H = R) == 0) \
+        clear_treemap(M, X->index);\
+    }\
+    else if (RTCHECK(ok_address(M, XP))) {\
+      if (XP->child[0] == X) \
+        XP->child[0] = R;\
+      else \
+        XP->child[1] = R;\
+    }\
+    else\
+      CORRUPTION_ERROR_ACTION(M);\
+    if (R != 0) {\
+      if (RTCHECK(ok_address(M, R))) {\
+        tchunkptr C0, C1;\
+        R->parent = XP;\
+        if ((C0 = X->child[0]) != 0) {\
+          if (RTCHECK(ok_address(M, C0))) {\
+            R->child[0] = C0;\
+            C0->parent = R;\
+          }\
+          else\
+            CORRUPTION_ERROR_ACTION(M);\
+        }\
+        if ((C1 = X->child[1]) != 0) {\
+          if (RTCHECK(ok_address(M, C1))) {\
+            R->child[1] = C1;\
+            C1->parent = R;\
+          }\
+          else\
+            CORRUPTION_ERROR_ACTION(M);\
+        }\
+      }\
+      else\
+        CORRUPTION_ERROR_ACTION(M);\
+    }\
+  }\
+}
+
+/* Relays to large vs small bin operations */
+
+#define insert_chunk(M, P, S)\
+  if (is_small(S)) insert_small_chunk(M, P, S)\
+  else { tchunkptr TP = (tchunkptr)(P); insert_large_chunk(M, TP, S); }
+
+#define unlink_chunk(M, P, S)\
+  if (is_small(S)) unlink_small_chunk(M, P, S)\
+  else { tchunkptr TP = (tchunkptr)(P); unlink_large_chunk(M, TP); }
+
+
+/* Relays to internal calls to malloc/free from realloc, memalign etc */
+
+#if ONLY_MSPACES
+#define internal_malloc(m, b) mspace_malloc(m, b)
+#define internal_free(m, mem) mspace_free(m,mem);
+#else /* ONLY_MSPACES */
+#if MSPACES
+#define internal_malloc(m, b)\
+  ((m == gm)? dlmalloc(b) : mspace_malloc(m, b))
+#define internal_free(m, mem)\
+   if (m == gm) dlfree(mem); else mspace_free(m,mem);
+#else /* MSPACES */
+#define internal_malloc(m, b) dlmalloc(b)
+#define internal_free(m, mem) dlfree(mem)
+#endif /* MSPACES */
+#endif /* ONLY_MSPACES */
+
+/* -----------------------  Direct-mmapping chunks ----------------------- */
+
+/*
+  Directly mmapped chunks are set up with an offset to the start of
+  the mmapped region stored in the prev_foot field of the chunk. This
+  allows reconstruction of the required argument to MUNMAP when freed,
+  and also allows adjustment of the returned chunk to meet alignment
+  requirements (especially in memalign).
+*/
+
+/* Malloc using mmap */
+static void* mmap_alloc(mstate m, size_t nb) {
+  size_t mmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK);
+  if (m->footprint_limit != 0) {
+    size_t fp = m->footprint + mmsize;
+    if (fp <= m->footprint || fp > m->footprint_limit)
+      return 0;
+  }
+  if (mmsize > nb) {     /* Check for wrap around 0 */
+    char* mm = (char*)(CALL_DIRECT_MMAP(mmsize));
+    if (mm != CMFAIL) {
+      size_t offset = align_offset(chunk2mem(mm));
+      size_t psize = mmsize - offset - MMAP_FOOT_PAD;
+      mchunkptr p = (mchunkptr)(mm + offset);
+      p->prev_foot = offset;
+      p->head = psize;
+      mark_inuse_foot(m, p, psize);
+      chunk_plus_offset(p, psize)->head = FENCEPOST_HEAD;
+      chunk_plus_offset(p, psize+SIZE_T_SIZE)->head = 0;
+
+      if (m->least_addr == 0 || mm < m->least_addr)
+        m->least_addr = mm;
+      if ((m->footprint += mmsize) > m->max_footprint)
+        m->max_footprint = m->footprint;
+      assert(is_aligned(chunk2mem(p)));
+      check_mmapped_chunk(m, p);
+      return chunk2mem(p);
+    }
+  }
+  return 0;
+}
+
+/* Realloc using mmap */
+static mchunkptr mmap_resize(mstate m, mchunkptr oldp, size_t nb, int flags) {
+  size_t oldsize = chunksize(oldp);
+  (void) flags;
+  if (is_small(nb)) /* Can't shrink mmap regions below small size */
+    return 0;
+  /* Keep old chunk if big enough but not too big */
+  if (oldsize >= nb + SIZE_T_SIZE &&
+      (oldsize - nb) <= (mparams.granularity << 1))
+    return oldp;
+  else {
+    size_t offset = oldp->prev_foot;
+    size_t oldmmsize = oldsize + offset + MMAP_FOOT_PAD;
+    size_t newmmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK);
+    char* cp = (char*)CALL_MREMAP((char*)oldp - offset,
+                                  oldmmsize, newmmsize, flags);
+    if (cp != CMFAIL) {
+      mchunkptr newp = (mchunkptr)(cp + offset);
+      size_t psize = newmmsize - offset - MMAP_FOOT_PAD;
+      newp->head = psize;
+      mark_inuse_foot(m, newp, psize);
+      chunk_plus_offset(newp, psize)->head = FENCEPOST_HEAD;
+      chunk_plus_offset(newp, psize+SIZE_T_SIZE)->head = 0;
+
+      if (cp < m->least_addr)
+        m->least_addr = cp;
+      if ((m->footprint += newmmsize - oldmmsize) > m->max_footprint)
+        m->max_footprint = m->footprint;
+      check_mmapped_chunk(m, newp);
+      return newp;
+    }
+  }
+  return 0;
+}
+
+
+/* -------------------------- mspace management -------------------------- */
+
+/* Initialize top chunk and its size */
+static void init_top(mstate m, mchunkptr p, size_t psize) {
+  /* Ensure alignment */
+  size_t offset = align_offset(chunk2mem(p));
+  p = (mchunkptr)((char*)p + offset);
+  psize -= offset;
+
+  m->top = p;
+  m->topsize = psize;
+  p->head = psize | PINUSE_BIT;
+  /* set size of fake trailing chunk holding overhead space only once */
+  chunk_plus_offset(p, psize)->head = TOP_FOOT_SIZE;
+  m->trim_check = mparams.trim_threshold; /* reset on each update */
+}
+
+/* Initialize bins for a new mstate that is otherwise zeroed out */
+static void init_bins(mstate m) {
+  /* Establish circular links for smallbins */
+  bindex_t i;
+  for (i = 0; i < NSMALLBINS; ++i) {
+    sbinptr bin = smallbin_at(m,i);
+    bin->fd = bin->bk = bin;
+  }
+}
+
+#if PROCEED_ON_ERROR
+
+/* default corruption action */
+static void reset_on_error(mstate m) {
+  int i;
+  ++malloc_corruption_error_count;
+  /* Reinitialize fields to forget about all memory */
+  m->smallmap = m->treemap = 0;
+  m->dvsize = m->topsize = 0;
+  m->seg.base = 0;
+  m->seg.size = 0;
+  m->seg.next = 0;
+  m->top = m->dv = 0;
+  for (i = 0; i < NTREEBINS; ++i)
+    *treebin_at(m, i) = 0;
+  init_bins(m);
+}
+#endif /* PROCEED_ON_ERROR */
+
+/* Allocate chunk and prepend remainder with chunk in successor base. */
+static void* prepend_alloc(mstate m, char* newbase, char* oldbase,
+                           size_t nb) {
+  mchunkptr p = align_as_chunk(newbase);
+  mchunkptr oldfirst = align_as_chunk(oldbase);
+  size_t psize = (char*)oldfirst - (char*)p;
+  mchunkptr q = chunk_plus_offset(p, nb);
+  size_t qsize = psize - nb;
+  set_size_and_pinuse_of_inuse_chunk(m, p, nb);
+
+  assert((char*)oldfirst > (char*)q);
+  assert(pinuse(oldfirst));
+  assert(qsize >= MIN_CHUNK_SIZE);
+
+  /* consolidate remainder with first chunk of old base */
+  if (oldfirst == m->top) {
+    size_t tsize = m->topsize += qsize;
+    m->top = q;
+    q->head = tsize | PINUSE_BIT;
+    check_top_chunk(m, q);
+  }
+  else if (oldfirst == m->dv) {
+    size_t dsize = m->dvsize += qsize;
+    m->dv = q;
+    set_size_and_pinuse_of_free_chunk(q, dsize);
+  }
+  else {
+    if (!is_inuse(oldfirst)) {
+      size_t nsize = chunksize(oldfirst);
+      unlink_chunk(m, oldfirst, nsize);
+      oldfirst = chunk_plus_offset(oldfirst, nsize);
+      qsize += nsize;
+    }
+    set_free_with_pinuse(q, qsize, oldfirst);
+    insert_chunk(m, q, qsize);
+    check_free_chunk(m, q);
+  }
+
+  check_malloced_chunk(m, chunk2mem(p), nb);
+  return chunk2mem(p);
+}
+
+/* Add a segment to hold a new noncontiguous region */
+static void add_segment(mstate m, char* tbase, size_t tsize, flag_t mmapped) {
+  /* Determine locations and sizes of segment, fenceposts, old top */
+  char* old_top = (char*)m->top;
+  msegmentptr oldsp = segment_holding(m, old_top);
+  char* old_end = oldsp->base + oldsp->size;
+  size_t ssize = pad_request(sizeof(struct malloc_segment));
+  char* rawsp = old_end - (ssize + FOUR_SIZE_T_SIZES + CHUNK_ALIGN_MASK);
+  size_t offset = align_offset(chunk2mem(rawsp));
+  char* asp = rawsp + offset;
+  char* csp = (asp < (old_top + MIN_CHUNK_SIZE))? old_top : asp;
+  mchunkptr sp = (mchunkptr)csp;
+  msegmentptr ss = (msegmentptr)(chunk2mem(sp));
+  mchunkptr tnext = chunk_plus_offset(sp, ssize);
+  mchunkptr p = tnext;
+  int nfences = 0;
+
+  /* reset top to new space */
+  init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE);
+
+  /* Set up segment record */
+  assert(is_aligned(ss));
+  set_size_and_pinuse_of_inuse_chunk(m, sp, ssize);
+  *ss = m->seg; /* Push current record */
+  m->seg.base = tbase;
+  m->seg.size = tsize;
+  m->seg.sflags = mmapped;
+  m->seg.next = ss;
+
+  /* Insert trailing fenceposts */
+  for (;;) {
+    mchunkptr nextp = chunk_plus_offset(p, SIZE_T_SIZE);
+    p->head = FENCEPOST_HEAD;
+    ++nfences;
+    if ((char*)(&(nextp->head)) < old_end)
+      p = nextp;
+    else
+      break;
+  }
+  assert(nfences >= 2);
+
+  /* Insert the rest of old top into a bin as an ordinary free chunk */
+  if (csp != old_top) {
+    mchunkptr q = (mchunkptr)old_top;
+    size_t psize = csp - old_top;
+    mchunkptr tn = chunk_plus_offset(q, psize);
+    set_free_with_pinuse(q, psize, tn);
+    insert_chunk(m, q, psize);
+  }
+
+  check_top_chunk(m, m->top);
+}
+
+/* -------------------------- System allocation -------------------------- */
+
+/* Get memory from system using MORECORE or MMAP */
+static void* sys_alloc(mstate m, size_t nb) {
+  char* tbase = CMFAIL;
+  size_t tsize = 0;
+  flag_t mmap_flag = 0;
+  size_t asize; /* allocation size */
+
+  ensure_initialization();
+
+  /* Directly map large chunks, but only if already initialized */
+  if (use_mmap(m) && nb >= mparams.mmap_threshold && m->topsize != 0) {
+    void* mem = mmap_alloc(m, nb);
+    if (mem != 0)
+      return mem;
+  }
+
+  asize = granularity_align(nb + SYS_ALLOC_PADDING);
+  if (asize <= nb)
+    return 0; /* wraparound */
+  if (m->footprint_limit != 0) {
+    size_t fp = m->footprint + asize;
+    if (fp <= m->footprint || fp > m->footprint_limit)
+      return 0;
+  }
+
+  /*
+    Try getting memory in any of three ways (in most-preferred to
+    least-preferred order):
+    1. A call to MORECORE that can normally contiguously extend memory.
+       (disabled if not MORECORE_CONTIGUOUS or not HAVE_MORECORE or
+       or main space is mmapped or a previous contiguous call failed)
+    2. A call to MMAP new space (disabled if not HAVE_MMAP).
+       Note that under the default settings, if MORECORE is unable to
+       fulfill a request, and HAVE_MMAP is true, then mmap is
+       used as a noncontiguous system allocator. This is a useful backup
+       strategy for systems with holes in address spaces -- in this case
+       sbrk cannot contiguously expand the heap, but mmap may be able to
+       find space.
+    3. A call to MORECORE that cannot usually contiguously extend memory.
+       (disabled if not HAVE_MORECORE)
+
+   In all cases, we need to request enough bytes from system to ensure
+   we can malloc nb bytes upon success, so pad with enough space for
+   top_foot, plus alignment-pad to make sure we don't lose bytes if
+   not on boundary, and round this up to a granularity unit.
+  */
+
+  if (MORECORE_CONTIGUOUS && !use_noncontiguous(m)) {
+    char* br = CMFAIL;
+    msegmentptr ss = (m->top == 0)? 0 : segment_holding(m, (char*)m->top);
+    ACQUIRE_MALLOC_GLOBAL_LOCK();
+
+    if (ss == 0) {  /* First time through or recovery */
+      char* base = (char*)CALL_MORECORE(0);
+      if (base != CMFAIL) {
+        size_t fp;
+        /* Adjust to end on a page boundary */
+        if (!is_page_aligned(base))
+          asize += (page_align((size_t)base) - (size_t)base);
+        fp = m->footprint + asize; /* recheck limits */
+        if (asize > nb && asize < HALF_MAX_SIZE_T &&
+            (m->footprint_limit == 0 ||
+             (fp > m->footprint && fp <= m->footprint_limit)) &&
+            (br = (char*)(CALL_MORECORE(asize))) == base) {
+          tbase = base;
+          tsize = asize;
+        }
+      }
+    }
+    else {
+      /* Subtract out existing available top space from MORECORE request. */
+      asize = granularity_align(nb - m->topsize + SYS_ALLOC_PADDING);
+      /* Use mem here only if it did continuously extend old space */
+      if (asize < HALF_MAX_SIZE_T &&
+          (br = (char*)(CALL_MORECORE(asize))) == ss->base+ss->size) {
+        tbase = br;
+        tsize = asize;
+      }
+    }
+
+    if (tbase == CMFAIL) {    /* Cope with partial failure */
+      if (br != CMFAIL) {    /* Try to use/extend the space we did get */
+        if (asize < HALF_MAX_SIZE_T &&
+            asize < nb + SYS_ALLOC_PADDING) {
+          size_t esize = granularity_align(nb + SYS_ALLOC_PADDING - asize);
+          if (esize < HALF_MAX_SIZE_T) {
+            char* end = (char*)CALL_MORECORE(esize);
+            if (end != CMFAIL)
+              asize += esize;
+            else {            /* Can't use; try to release */
+              (void) CALL_MORECORE(-asize);
+              br = CMFAIL;
+            }
+          }
+        }
+      }
+      if (br != CMFAIL) {    /* Use the space we did get */
+        tbase = br;
+        tsize = asize;
+      }
+      else
+        disable_contiguous(m); /* Don't try contiguous path in the future */
+    }
+
+    RELEASE_MALLOC_GLOBAL_LOCK();
+  }
+
+  if (HAVE_MMAP && tbase == CMFAIL) {  /* Try MMAP */
+    char* mp = (char*)(CALL_MMAP(asize));
+    if (mp != CMFAIL) {
+      tbase = mp;
+      tsize = asize;
+      mmap_flag = USE_MMAP_BIT;
+    }
+  }
+
+  if (HAVE_MORECORE && tbase == CMFAIL) { /* Try noncontiguous MORECORE */
+    if (asize < HALF_MAX_SIZE_T) {
+      char* br = CMFAIL;
+      char* end = CMFAIL;
+      ACQUIRE_MALLOC_GLOBAL_LOCK();
+      br = (char*)(CALL_MORECORE(asize));
+      end = (char*)(CALL_MORECORE(0));
+      RELEASE_MALLOC_GLOBAL_LOCK();
+      if (br != CMFAIL && end != CMFAIL && br < end) {
+        size_t ssize = end - br;
+        if (ssize > nb + TOP_FOOT_SIZE) {
+          tbase = br;
+          tsize = ssize;
+        }
+      }
+    }
+  }
+
+  if (tbase != CMFAIL) {
+
+    if ((m->footprint += tsize) > m->max_footprint)
+      m->max_footprint = m->footprint;
+
+    if (!is_initialized(m)) { /* first-time initialization */
+      if (m->least_addr == 0 || tbase < m->least_addr)
+        m->least_addr = tbase;
+      m->seg.base = tbase;
+      m->seg.size = tsize;
+      m->seg.sflags = mmap_flag;
+      m->magic = mparams.magic;
+      m->release_checks = MAX_RELEASE_CHECK_RATE;
+      init_bins(m);
+#if !ONLY_MSPACES
+      if (is_global(m))
+        init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE);
+      else
+#endif
+      {
+        /* Offset top by embedded malloc_state */
+        mchunkptr mn = next_chunk(mem2chunk(m));
+        init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) -TOP_FOOT_SIZE);
+      }
+    }
+
+    else {
+      /* Try to merge with an existing segment */
+      msegmentptr sp = &m->seg;
+      /* Only consider most recent segment if traversal suppressed */
+      while (sp != 0 && tbase != sp->base + sp->size)
+        sp = (NO_SEGMENT_TRAVERSAL) ? 0 : sp->next;
+      if (sp != 0 &&
+          !is_extern_segment(sp) &&
+          (sp->sflags & USE_MMAP_BIT) == mmap_flag &&
+          segment_holds(sp, m->top)) { /* append */
+        sp->size += tsize;
+        init_top(m, m->top, m->topsize + tsize);
+      }
+      else {
+        if (tbase < m->least_addr)
+          m->least_addr = tbase;
+        sp = &m->seg;
+        while (sp != 0 && sp->base != tbase + tsize)
+          sp = (NO_SEGMENT_TRAVERSAL) ? 0 : sp->next;
+        if (sp != 0 &&
+            !is_extern_segment(sp) &&
+            (sp->sflags & USE_MMAP_BIT) == mmap_flag) {
+          char* oldbase = sp->base;
+          sp->base = tbase;
+          sp->size += tsize;
+          return prepend_alloc(m, tbase, oldbase, nb);
+        }
+        else
+          add_segment(m, tbase, tsize, mmap_flag);
+      }
+    }
+
+    if (nb < m->topsize) { /* Allocate from new or extended top space */
+      size_t rsize = m->topsize -= nb;
+      mchunkptr p = m->top;
+      mchunkptr r = m->top = chunk_plus_offset(p, nb);
+      r->head = rsize | PINUSE_BIT;
+      set_size_and_pinuse_of_inuse_chunk(m, p, nb);
+      check_top_chunk(m, m->top);
+      check_malloced_chunk(m, chunk2mem(p), nb);
+      return chunk2mem(p);
+    }
+  }
+
+  MALLOC_FAILURE_ACTION;
+  return 0;
+}
+
+/* -----------------------  system deallocation -------------------------- */
+
+/* Unmap and unlink any mmapped segments that don't contain used chunks */
+static size_t release_unused_segments(mstate m) {
+  size_t released = 0;
+  int nsegs = 0;
+  msegmentptr pred = &m->seg;
+  msegmentptr sp = pred->next;
+  while (sp != 0) {
+    char* base = sp->base;
+    size_t size = sp->size;
+    msegmentptr next = sp->next;
+    ++nsegs;
+    if (is_mmapped_segment(sp) && !is_extern_segment(sp)) {
+      mchunkptr p = align_as_chunk(base);
+      size_t psize = chunksize(p);
+      /* Can unmap if first chunk holds entire segment and not pinned */
+      if (!is_inuse(p) && (char*)p + psize >= base + size - TOP_FOOT_SIZE) {
+        tchunkptr tp = (tchunkptr)p;
+        assert(segment_holds(sp, (char*)sp));
+        if (p == m->dv) {
+          m->dv = 0;
+          m->dvsize = 0;
+        }
+        else {
+          unlink_large_chunk(m, tp);
+        }
+        if (CALL_MUNMAP(base, size) == 0) {
+          released += size;
+          m->footprint -= size;
+          /* unlink obsoleted record */
+          sp = pred;
+          sp->next = next;
+        }
+        else { /* back out if cannot unmap */
+          insert_large_chunk(m, tp, psize);
+        }
+      }
+    }
+    if (NO_SEGMENT_TRAVERSAL) /* scan only first segment */
+      break;
+    pred = sp;
+    sp = next;
+  }
+  /* Reset check counter */
+  m->release_checks = ((nsegs > MAX_RELEASE_CHECK_RATE)?
+                       nsegs : MAX_RELEASE_CHECK_RATE);
+  return released;
+}
+
+static int sys_trim(mstate m, size_t pad) {
+  size_t released = 0;
+  ensure_initialization();
+  if (pad < MAX_REQUEST && is_initialized(m)) {
+    pad += TOP_FOOT_SIZE; /* ensure enough room for segment overhead */
+
+    if (m->topsize > pad) {
+      /* Shrink top space in granularity-size units, keeping at least one */
+      size_t unit = mparams.granularity;
+      size_t extra = ((m->topsize - pad + (unit - SIZE_T_ONE)) / unit -
+                      SIZE_T_ONE) * unit;
+      msegmentptr sp = segment_holding(m, (char*)m->top);
+
+      if (!is_extern_segment(sp)) {
+        if (is_mmapped_segment(sp)) {
+          if (HAVE_MMAP &&
+              sp->size >= extra &&
+              !has_segment_link(m, sp)) { /* can't shrink if pinned */
+            size_t newsize = sp->size - extra;
+            /* Prefer mremap, fall back to munmap */
+            if ((CALL_MREMAP(sp->base, sp->size, newsize, 0) != MFAIL) ||
+                (CALL_MUNMAP(sp->base + newsize, extra) == 0)) {
+              released = extra;
+            }
+          }
+        }
+        else if (HAVE_MORECORE) {
+          if (extra >= HALF_MAX_SIZE_T) /* Avoid wrapping negative */
+            extra = (HALF_MAX_SIZE_T) + SIZE_T_ONE - unit;
+          ACQUIRE_MALLOC_GLOBAL_LOCK();
+          {
+            /* Make sure end of memory is where we last set it. */
+            char* old_br = (char*)(CALL_MORECORE(0));
+            if (old_br == sp->base + sp->size) {
+              char* rel_br = (char*)(CALL_MORECORE(-extra));
+              char* new_br = (char*)(CALL_MORECORE(0));
+              if (rel_br != CMFAIL && new_br < old_br)
+                released = old_br - new_br;
+            }
+          }
+          RELEASE_MALLOC_GLOBAL_LOCK();
+        }
+      }
+
+      if (released != 0) {
+        sp->size -= released;
+        m->footprint -= released;
+        init_top(m, m->top, m->topsize - released);
+        check_top_chunk(m, m->top);
+      }
+    }
+
+    /* Unmap any unused mmapped segments */
+    if (HAVE_MMAP)
+      released += release_unused_segments(m);
+
+    /* On failure, disable autotrim to avoid repeated failed future calls */
+    if (released == 0 && m->topsize > m->trim_check)
+      m->trim_check = MAX_SIZE_T;
+  }
+
+  return (released != 0)? 1 : 0;
+}
+
+/* Consolidate and bin a chunk. Differs from exported versions
+   of free mainly in that the chunk need not be marked as inuse.
+*/
+static void dispose_chunk(mstate m, mchunkptr p, size_t psize) {
+  mchunkptr next = chunk_plus_offset(p, psize);
+  if (!pinuse(p)) {
+    mchunkptr prev;
+    size_t prevsize = p->prev_foot;
+    if (is_mmapped(p)) {
+      psize += prevsize + MMAP_FOOT_PAD;
+      if (CALL_MUNMAP((char*)p - prevsize, psize) == 0)
+        m->footprint -= psize;
+      return;
+    }
+    prev = chunk_minus_offset(p, prevsize);
+    psize += prevsize;
+    p = prev;
+    if (RTCHECK(ok_address(m, prev))) { /* consolidate backward */
+      if (p != m->dv) {
+        unlink_chunk(m, p, prevsize);
+      }
+      else if ((next->head & INUSE_BITS) == INUSE_BITS) {
+        m->dvsize = psize;
+        set_free_with_pinuse(p, psize, next);
+        return;
+      }
+    }
+    else {
+      CORRUPTION_ERROR_ACTION(m);
+      return;
+    }
+  }
+  if (RTCHECK(ok_address(m, next))) {
+    if (!cinuse(next)) {  /* consolidate forward */
+      if (next == m->top) {
+        size_t tsize = m->topsize += psize;
+        m->top = p;
+        p->head = tsize | PINUSE_BIT;
+        if (p == m->dv) {
+          m->dv = 0;
+          m->dvsize = 0;
+        }
+        return;
+      }
+      else if (next == m->dv) {
+        size_t dsize = m->dvsize += psize;
+        m->dv = p;
+        set_size_and_pinuse_of_free_chunk(p, dsize);
+        return;
+      }
+      else {
+        size_t nsize = chunksize(next);
+        psize += nsize;
+        unlink_chunk(m, next, nsize);
+        set_size_and_pinuse_of_free_chunk(p, psize);
+        if (p == m->dv) {
+          m->dvsize = psize;
+          return;
+        }
+      }
+    }
+    else {
+      set_free_with_pinuse(p, psize, next);
+    }
+    insert_chunk(m, p, psize);
+  }
+  else {
+    CORRUPTION_ERROR_ACTION(m);
+  }
+}
+
+/* ---------------------------- malloc --------------------------- */
+
+/* allocate a large request from the best fitting chunk in a treebin */
+static void* tmalloc_large(mstate m, size_t nb) {
+  tchunkptr v = 0;
+  size_t rsize = -nb; /* Unsigned negation */
+  tchunkptr t;
+  bindex_t idx;
+  compute_tree_index(nb, idx);
+  if ((t = *treebin_at(m, idx)) != 0) {
+    /* Traverse tree for this bin looking for node with size == nb */
+    size_t sizebits = nb << leftshift_for_tree_index(idx);
+    tchunkptr rst = 0;  /* The deepest untaken right subtree */
+    for (;;) {
+      tchunkptr rt;
+      size_t trem = chunksize(t) - nb;
+      if (trem < rsize) {
+        v = t;
+        if ((rsize = trem) == 0)
+          break;
+      }
+      rt = t->child[1];
+      t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1];
+      if (rt != 0 && rt != t)
+        rst = rt;
+      if (t == 0) {
+        t = rst; /* set t to least subtree holding sizes > nb */
+        break;
+      }
+      sizebits <<= 1;
+    }
+  }
+  if (t == 0 && v == 0) { /* set t to root of next non-empty treebin */
+    binmap_t leftbits = left_bits(idx2bit(idx)) & m->treemap;
+    if (leftbits != 0) {
+      bindex_t i;
+      binmap_t leastbit = least_bit(leftbits);
+      compute_bit2idx(leastbit, i);
+      t = *treebin_at(m, i);
+    }
+  }
+
+  while (t != 0) { /* find smallest of tree or subtree */
+    size_t trem = chunksize(t) - nb;
+    if (trem < rsize) {
+      rsize = trem;
+      v = t;
+    }
+    t = leftmost_child(t);
+  }
+
+  /*  If dv is a better fit, return 0 so malloc will use it */
+  if (v != 0 && rsize < (size_t)(m->dvsize - nb)) {
+    if (RTCHECK(ok_address(m, v))) { /* split */
+      mchunkptr r = chunk_plus_offset(v, nb);
+      assert(chunksize(v) == rsize + nb);
+      if (RTCHECK(ok_next(v, r))) {
+        unlink_large_chunk(m, v);
+        if (rsize < MIN_CHUNK_SIZE)
+          set_inuse_and_pinuse(m, v, (rsize + nb));
+        else {
+          set_size_and_pinuse_of_inuse_chunk(m, v, nb);
+          set_size_and_pinuse_of_free_chunk(r, rsize);
+          insert_chunk(m, r, rsize);
+        }
+        return chunk2mem(v);
+      }
+    }
+    CORRUPTION_ERROR_ACTION(m);
+  }
+  return 0;
+}
+
+/* allocate a small request from the best fitting chunk in a treebin */
+static void* tmalloc_small(mstate m, size_t nb) {
+  tchunkptr t, v;
+  size_t rsize;
+  bindex_t i;
+  binmap_t leastbit = least_bit(m->treemap);
+  compute_bit2idx(leastbit, i);
+  v = t = *treebin_at(m, i);
+  rsize = chunksize(t) - nb;
+
+  while ((t = leftmost_child(t)) != 0) {
+    size_t trem = chunksize(t) - nb;
+    if (trem < rsize) {
+      rsize = trem;
+      v = t;
+    }
+  }
+
+  if (RTCHECK(ok_address(m, v))) {
+    mchunkptr r = chunk_plus_offset(v, nb);
+    assert(chunksize(v) == rsize + nb);
+    if (RTCHECK(ok_next(v, r))) {
+      unlink_large_chunk(m, v);
+      if (rsize < MIN_CHUNK_SIZE)
+        set_inuse_and_pinuse(m, v, (rsize + nb));
+      else {
+        set_size_and_pinuse_of_inuse_chunk(m, v, nb);
+        set_size_and_pinuse_of_free_chunk(r, rsize);
+        replace_dv(m, r, rsize);
+      }
+      return chunk2mem(v);
+    }
+  }
+
+  CORRUPTION_ERROR_ACTION(m);
+  return 0;
+}
+
+#if !ONLY_MSPACES
+
+void* dlmalloc(size_t bytes) {
+  /*
+     Basic algorithm:
+     If a small request (< 256 bytes minus per-chunk overhead):
+       1. If one exists, use a remainderless chunk in associated smallbin.
+          (Remainderless means that there are too few excess bytes to
+          represent as a chunk.)
+       2. If it is big enough, use the dv chunk, which is normally the
+          chunk adjacent to the one used for the most recent small request.
+       3. If one exists, split the smallest available chunk in a bin,
+          saving remainder in dv.
+       4. If it is big enough, use the top chunk.
+       5. If available, get memory from system and use it
+     Otherwise, for a large request:
+       1. Find the smallest available binned chunk that fits, and use it
+          if it is better fitting than dv chunk, splitting if necessary.
+       2. If better fitting than any binned chunk, use the dv chunk.
+       3. If it is big enough, use the top chunk.
+       4. If request size >= mmap threshold, try to directly mmap this chunk.
+       5. If available, get memory from system and use it
+
+     The ugly goto's here ensure that postaction occurs along all paths.
+  */
+
+#if USE_LOCKS
+  ensure_initialization(); /* initialize in sys_alloc if not using locks */
+#endif
+
+  if (!PREACTION(gm)) {
+    void* mem;
+    size_t nb;
+    if (bytes <= MAX_SMALL_REQUEST) {
+      bindex_t idx;
+      binmap_t smallbits;
+      nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes);
+      idx = small_index(nb);
+      smallbits = gm->smallmap >> idx;
+
+      if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */
+        mchunkptr b, p;
+        idx += ~smallbits & 1;       /* Uses next bin if idx empty */
+        b = smallbin_at(gm, idx);
+        p = b->fd;
+        assert(chunksize(p) == small_index2size(idx));
+        unlink_first_small_chunk(gm, b, p, idx);
+        set_inuse_and_pinuse(gm, p, small_index2size(idx));
+        mem = chunk2mem(p);
+        check_malloced_chunk(gm, mem, nb);
+        goto postaction;
+      }
+
+      else if (nb > gm->dvsize) {
+        if (smallbits != 0) { /* Use chunk in next nonempty smallbin */
+          mchunkptr b, p, r;
+          size_t rsize;
+          bindex_t i;
+          binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx));
+          binmap_t leastbit = least_bit(leftbits);
+          compute_bit2idx(leastbit, i);
+          b = smallbin_at(gm, i);
+          p = b->fd;
+          assert(chunksize(p) == small_index2size(i));
+          unlink_first_small_chunk(gm, b, p, i);
+          rsize = small_index2size(i) - nb;
+          /* Fit here cannot be remainderless if 4byte sizes */
+          if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE)
+            set_inuse_and_pinuse(gm, p, small_index2size(i));
+          else {
+            set_size_and_pinuse_of_inuse_chunk(gm, p, nb);
+            r = chunk_plus_offset(p, nb);
+            set_size_and_pinuse_of_free_chunk(r, rsize);
+            replace_dv(gm, r, rsize);
+          }
+          mem = chunk2mem(p);
+          check_malloced_chunk(gm, mem, nb);
+          goto postaction;
+        }
+
+        else if (gm->treemap != 0 && (mem = tmalloc_small(gm, nb)) != 0) {
+          check_malloced_chunk(gm, mem, nb);
+          goto postaction;
+        }
+      }
+    }
+    else if (bytes >= MAX_REQUEST)
+      nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */
+    else {
+      nb = pad_request(bytes);
+      if (gm->treemap != 0 && (mem = tmalloc_large(gm, nb)) != 0) {
+        check_malloced_chunk(gm, mem, nb);
+        goto postaction;
+      }
+    }
+
+    if (nb <= gm->dvsize) {
+      size_t rsize = gm->dvsize - nb;
+      mchunkptr p = gm->dv;
+      if (rsize >= MIN_CHUNK_SIZE) { /* split dv */
+        mchunkptr r = gm->dv = chunk_plus_offset(p, nb);
+        gm->dvsize = rsize;
+        set_size_and_pinuse_of_free_chunk(r, rsize);
+        set_size_and_pinuse_of_inuse_chunk(gm, p, nb);
+      }
+      else { /* exhaust dv */
+        size_t dvs = gm->dvsize;
+        gm->dvsize = 0;
+        gm->dv = 0;
+        set_inuse_and_pinuse(gm, p, dvs);
+      }
+      mem = chunk2mem(p);
+      check_malloced_chunk(gm, mem, nb);
+      goto postaction;
+    }
+
+    else if (nb < gm->topsize) { /* Split top */
+      size_t rsize = gm->topsize -= nb;
+      mchunkptr p = gm->top;
+      mchunkptr r = gm->top = chunk_plus_offset(p, nb);
+      r->head = rsize | PINUSE_BIT;
+      set_size_and_pinuse_of_inuse_chunk(gm, p, nb);
+      mem = chunk2mem(p);
+      check_top_chunk(gm, gm->top);
+      check_malloced_chunk(gm, mem, nb);
+      goto postaction;
+    }
+
+    mem = sys_alloc(gm, nb);
+
+  postaction:
+    POSTACTION(gm);
+    return mem;
+  }
+
+  return 0;
+}
+
+/* ---------------------------- free --------------------------- */
+
+void dlfree(void* mem) {
+  /*
+     Consolidate freed chunks with preceeding or succeeding bordering
+     free chunks, if they exist, and then place in a bin.  Intermixed
+     with special cases for top, dv, mmapped chunks, and usage errors.
+  */
+
+  if (mem != 0) {
+    mchunkptr p  = mem2chunk(mem);
+#if FOOTERS
+    mstate fm = get_mstate_for(p);
+    if (!ok_magic(fm)) {
+      USAGE_ERROR_ACTION(fm, p);
+      return;
+    }
+#else /* FOOTERS */
+#define fm gm
+#endif /* FOOTERS */
+    if (!PREACTION(fm)) {
+      check_inuse_chunk(fm, p);
+      if (RTCHECK(ok_address(fm, p) && ok_inuse(p))) {
+        size_t psize = chunksize(p);
+        mchunkptr next = chunk_plus_offset(p, psize);
+        if (!pinuse(p)) {
+          size_t prevsize = p->prev_foot;
+          if (is_mmapped(p)) {
+            psize += prevsize + MMAP_FOOT_PAD;
+            if (CALL_MUNMAP((char*)p - prevsize, psize) == 0)
+              fm->footprint -= psize;
+            goto postaction;
+          }
+          else {
+            mchunkptr prev = chunk_minus_offset(p, prevsize);
+            psize += prevsize;
+            p = prev;
+            if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */
+              if (p != fm->dv) {
+                unlink_chunk(fm, p, prevsize);
+              }
+              else if ((next->head & INUSE_BITS) == INUSE_BITS) {
+                fm->dvsize = psize;
+                set_free_with_pinuse(p, psize, next);
+                goto postaction;
+              }
+            }
+            else
+              goto erroraction;
+          }
+        }
+
+        if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) {
+          if (!cinuse(next)) {  /* consolidate forward */
+            if (next == fm->top) {
+              size_t tsize = fm->topsize += psize;
+              fm->top = p;
+              p->head = tsize | PINUSE_BIT;
+              if (p == fm->dv) {
+                fm->dv = 0;
+                fm->dvsize = 0;
+              }
+              if (should_trim(fm, tsize))
+                sys_trim(fm, 0);
+              goto postaction;
+            }
+            else if (next == fm->dv) {
+              size_t dsize = fm->dvsize += psize;
+              fm->dv = p;
+              set_size_and_pinuse_of_free_chunk(p, dsize);
+              goto postaction;
+            }
+            else {
+              size_t nsize = chunksize(next);
+              psize += nsize;
+              unlink_chunk(fm, next, nsize);
+              set_size_and_pinuse_of_free_chunk(p, psize);
+              if (p == fm->dv) {
+                fm->dvsize = psize;
+                goto postaction;
+              }
+            }
+          }
+          else
+            set_free_with_pinuse(p, psize, next);
+
+          if (is_small(psize)) {
+            insert_small_chunk(fm, p, psize);
+            check_free_chunk(fm, p);
+          }
+          else {
+            tchunkptr tp = (tchunkptr)p;
+            insert_large_chunk(fm, tp, psize);
+            check_free_chunk(fm, p);
+            if (--fm->release_checks == 0)
+              release_unused_segments(fm);
+          }
+          goto postaction;
+        }
+      }
+    erroraction:
+      USAGE_ERROR_ACTION(fm, p);
+    postaction:
+      POSTACTION(fm);
+    }
+  }
+#if !FOOTERS
+#undef fm
+#endif /* FOOTERS */
+}
+
+void* dlcalloc(size_t n_elements, size_t elem_size) {
+  void* mem;
+  size_t req = 0;
+  if (n_elements != 0) {
+    req = n_elements * elem_size;
+    if (((n_elements | elem_size) & ~(size_t)0xffff) &&
+        (req / n_elements != elem_size))
+      req = MAX_SIZE_T; /* force downstream failure on overflow */
+  }
+  mem = dlmalloc(req);
+  if (mem != 0 && calloc_must_clear(mem2chunk(mem)))
+    memset(mem, 0, req);
+  return mem;
+}
+
+#endif /* !ONLY_MSPACES */
+
+/* ------------ Internal support for realloc, memalign, etc -------------- */
+
+/* Try to realloc; only in-place unless can_move true */
+static mchunkptr try_realloc_chunk(mstate m, mchunkptr p, size_t nb,
+                                   int can_move) {
+  mchunkptr newp = 0;
+  size_t oldsize = chunksize(p);
+  mchunkptr next = chunk_plus_offset(p, oldsize);
+  if (RTCHECK(ok_address(m, p) && ok_inuse(p) &&
+              ok_next(p, next) && ok_pinuse(next))) {
+    if (is_mmapped(p)) {
+      newp = mmap_resize(m, p, nb, can_move);
+    }
+    else if (oldsize >= nb) {             /* already big enough */
+      size_t rsize = oldsize - nb;
+      if (rsize >= MIN_CHUNK_SIZE) {      /* split off remainder */
+        mchunkptr r = chunk_plus_offset(p, nb);
+        set_inuse(m, p, nb);
+        set_inuse(m, r, rsize);
+        dispose_chunk(m, r, rsize);
+      }
+      newp = p;
+    }
+    else if (next == m->top) {  /* extend into top */
+      if (oldsize + m->topsize > nb) {
+        size_t newsize = oldsize + m->topsize;
+        size_t newtopsize = newsize - nb;
+        mchunkptr newtop = chunk_plus_offset(p, nb);
+        set_inuse(m, p, nb);
+        newtop->head = newtopsize |PINUSE_BIT;
+        m->top = newtop;
+        m->topsize = newtopsize;
+        newp = p;
+      }
+    }
+    else if (next == m->dv) { /* extend into dv */
+      size_t dvs = m->dvsize;
+      if (oldsize + dvs >= nb) {
+        size_t dsize = oldsize + dvs - nb;
+        if (dsize >= MIN_CHUNK_SIZE) {
+          mchunkptr r = chunk_plus_offset(p, nb);
+          mchunkptr n = chunk_plus_offset(r, dsize);
+          set_inuse(m, p, nb);
+          set_size_and_pinuse_of_free_chunk(r, dsize);
+          clear_pinuse(n);
+          m->dvsize = dsize;
+          m->dv = r;
+        }
+        else { /* exhaust dv */
+          size_t newsize = oldsize + dvs;
+          set_inuse(m, p, newsize);
+          m->dvsize = 0;
+          m->dv = 0;
+        }
+        newp = p;
+      }
+    }
+    else if (!cinuse(next)) { /* extend into next free chunk */
+      size_t nextsize = chunksize(next);
+      if (oldsize + nextsize >= nb) {
+        size_t rsize = oldsize + nextsize - nb;
+        unlink_chunk(m, next, nextsize);
+        if (rsize < MIN_CHUNK_SIZE) {
+          size_t newsize = oldsize + nextsize;
+          set_inuse(m, p, newsize);
+        }
+        else {
+          mchunkptr r = chunk_plus_offset(p, nb);
+          set_inuse(m, p, nb);
+          set_inuse(m, r, rsize);
+          dispose_chunk(m, r, rsize);
+        }
+        newp = p;
+      }
+    }
+  }
+  else {
+    USAGE_ERROR_ACTION(m, oldmem);
+  }
+  return newp;
+}
+
+static void* internal_memalign(mstate m, size_t alignment, size_t bytes) {
+  void* mem = 0;
+  if (alignment <  MIN_CHUNK_SIZE) /* must be at least a minimum chunk size */
+    alignment = MIN_CHUNK_SIZE;
+  if ((alignment & (alignment-SIZE_T_ONE)) != 0) {/* Ensure a power of 2 */
+    size_t a = MALLOC_ALIGNMENT << 1;
+    while (a < alignment) a <<= 1;
+    alignment = a;
+  }
+  if (bytes >= MAX_REQUEST - alignment) {
+    if (m != 0)  { /* Test isn't needed but avoids compiler warning */
+      MALLOC_FAILURE_ACTION;
+    }
+  }
+  else {
+    size_t nb = request2size(bytes);
+    size_t req = nb + alignment + MIN_CHUNK_SIZE - CHUNK_OVERHEAD;
+    mem = internal_malloc(m, req);
+    if (mem != 0) {
+      mchunkptr p = mem2chunk(mem);
+      if (PREACTION(m))
+        return 0;
+      if ((((size_t)(mem)) & (alignment - 1)) != 0) { /* misaligned */
+        /*
+          Find an aligned spot inside chunk.  Since we need to give
+          back leading space in a chunk of at least MIN_CHUNK_SIZE, if
+          the first calculation places us at a spot with less than
+          MIN_CHUNK_SIZE leader, we can move to the next aligned spot.
+          We've allocated enough total room so that this is always
+          possible.
+        */
+        char* br = (char*)mem2chunk((size_t)(((size_t)((char*)mem + alignment -
+                                                       SIZE_T_ONE)) &
+                                             -alignment));
+        char* pos = ((size_t)(br - (char*)(p)) >= MIN_CHUNK_SIZE)?
+          br : br+alignment;
+        mchunkptr newp = (mchunkptr)pos;
+        size_t leadsize = pos - (char*)(p);
+        size_t newsize = chunksize(p) - leadsize;
+
+        if (is_mmapped(p)) { /* For mmapped chunks, just adjust offset */
+          newp->prev_foot = p->prev_foot + leadsize;
+          newp->head = newsize;
+        }
+        else { /* Otherwise, give back leader, use the rest */
+          set_inuse(m, newp, newsize);
+          set_inuse(m, p, leadsize);
+          dispose_chunk(m, p, leadsize);
+        }
+        p = newp;
+      }
+
+      /* Give back spare room at the end */
+      if (!is_mmapped(p)) {
+        size_t size = chunksize(p);
+        if (size > nb + MIN_CHUNK_SIZE) {
+          size_t remainder_size = size - nb;
+          mchunkptr remainder = chunk_plus_offset(p, nb);
+          set_inuse(m, p, nb);
+          set_inuse(m, remainder, remainder_size);
+          dispose_chunk(m, remainder, remainder_size);
+        }
+      }
+
+      mem = chunk2mem(p);
+      assert (chunksize(p) >= nb);
+      assert(((size_t)mem & (alignment - 1)) == 0);
+      check_inuse_chunk(m, p);
+      POSTACTION(m);
+    }
+  }
+  return mem;
+}
+
+/*
+  Common support for independent_X routines, handling
+    all of the combinations that can result.
+  The opts arg has:
+    bit 0 set if all elements are same size (using sizes[0])
+    bit 1 set if elements should be zeroed
+*/
+static void** ialloc(mstate m,
+                     size_t n_elements,
+                     size_t* sizes,
+                     int opts,
+                     void* chunks[]) {
+
+  size_t    element_size;   /* chunksize of each element, if all same */
+  size_t    contents_size;  /* total size of elements */
+  size_t    array_size;     /* request size of pointer array */
+  void*     mem;            /* malloced aggregate space */
+  mchunkptr p;              /* corresponding chunk */
+  size_t    remainder_size; /* remaining bytes while splitting */
+  void**    marray;         /* either "chunks" or malloced ptr array */
+  mchunkptr array_chunk;    /* chunk for malloced ptr array */
+  flag_t    was_enabled;    /* to disable mmap */
+  size_t    size;
+  size_t    i;
+
+  ensure_initialization();
+  /* compute array length, if needed */
+  if (chunks != 0) {
+    if (n_elements == 0)
+      return chunks; /* nothing to do */
+    marray = chunks;
+    array_size = 0;
+  }
+  else {
+    /* if empty req, must still return chunk representing empty array */
+    if (n_elements == 0)
+      return (void**)internal_malloc(m, 0);
+    marray = 0;
+    array_size = request2size(n_elements * (sizeof(void*)));
+  }
+
+  /* compute total element size */
+  if (opts & 0x1) { /* all-same-size */
+    element_size = request2size(*sizes);
+    contents_size = n_elements * element_size;
+  }
+  else { /* add up all the sizes */
+    element_size = 0;
+    contents_size = 0;
+    for (i = 0; i != n_elements; ++i)
+      contents_size += request2size(sizes[i]);
+  }
+
+  size = contents_size + array_size;
+
+  /*
+     Allocate the aggregate chunk.  First disable direct-mmapping so
+     malloc won't use it, since we would not be able to later
+     free/realloc space internal to a segregated mmap region.
+  */
+  was_enabled = use_mmap(m);
+  disable_mmap(m);
+  mem = internal_malloc(m, size - CHUNK_OVERHEAD);
+  if (was_enabled)
+    enable_mmap(m);
+  if (mem == 0)
+    return 0;
+
+  if (PREACTION(m)) return 0;
+  p = mem2chunk(mem);
+  remainder_size = chunksize(p);
+
+  assert(!is_mmapped(p));
+
+  if (opts & 0x2) {       /* optionally clear the elements */
+    memset((size_t*)mem, 0, remainder_size - SIZE_T_SIZE - array_size);
+  }
+
+  /* If not provided, allocate the pointer array as final part of chunk */
+  if (marray == 0) {
+    size_t  array_chunk_size;
+    array_chunk = chunk_plus_offset(p, contents_size);
+    array_chunk_size = remainder_size - contents_size;
+    marray = (void**) (chunk2mem(array_chunk));
+    set_size_and_pinuse_of_inuse_chunk(m, array_chunk, array_chunk_size);
+    remainder_size = contents_size;
+  }
+
+  /* split out elements */
+  for (i = 0; ; ++i) {
+    marray[i] = chunk2mem(p);
+    if (i != n_elements-1) {
+      if (element_size != 0)
+        size = element_size;
+      else
+        size = request2size(sizes[i]);
+      remainder_size -= size;
+      set_size_and_pinuse_of_inuse_chunk(m, p, size);
+      p = chunk_plus_offset(p, size);
+    }
+    else { /* the final element absorbs any overallocation slop */
+      set_size_and_pinuse_of_inuse_chunk(m, p, remainder_size);
+      break;
+    }
+  }
+
+#if DEBUG
+  if (marray != chunks) {
+    /* final element must have exactly exhausted chunk */
+    if (element_size != 0) {
+      assert(remainder_size == element_size);
+    }
+    else {
+      assert(remainder_size == request2size(sizes[i]));
+    }
+    check_inuse_chunk(m, mem2chunk(marray));
+  }
+  for (i = 0; i != n_elements; ++i)
+    check_inuse_chunk(m, mem2chunk(marray[i]));
+
+#endif /* DEBUG */
+
+  POSTACTION(m);
+  return marray;
+}
+
+/* Try to free all pointers in the given array.
+   Note: this could be made faster, by delaying consolidation,
+   at the price of disabling some user integrity checks, We
+   still optimize some consolidations by combining adjacent
+   chunks before freeing, which will occur often if allocated
+   with ialloc or the array is sorted.
+*/
+static size_t internal_bulk_free(mstate m, void* array[], size_t nelem) {
+  size_t unfreed = 0;
+  if (!PREACTION(m)) {
+    void** a;
+    void** fence = &(array[nelem]);
+    for (a = array; a != fence; ++a) {
+      void* mem = *a;
+      if (mem != 0) {
+        mchunkptr p = mem2chunk(mem);
+        size_t psize = chunksize(p);
+#if FOOTERS
+        if (get_mstate_for(p) != m) {
+          ++unfreed;
+          continue;
+        }
+#endif
+        check_inuse_chunk(m, p);
+        *a = 0;
+        if (RTCHECK(ok_address(m, p) && ok_inuse(p))) {
+          void ** b = a + 1; /* try to merge with next chunk */
+          mchunkptr next = next_chunk(p);
+          if (b != fence && *b == chunk2mem(next)) {
+            size_t newsize = chunksize(next) + psize;
+            set_inuse(m, p, newsize);
+            *b = chunk2mem(p);
+          }
+          else
+            dispose_chunk(m, p, psize);
+        }
+        else {
+          CORRUPTION_ERROR_ACTION(m);
+          break;
+        }
+      }
+    }
+    if (should_trim(m, m->topsize))
+      sys_trim(m, 0);
+    POSTACTION(m);
+  }
+  return unfreed;
+}
+
+/* Traversal */
+#if MALLOC_INSPECT_ALL
+static void internal_inspect_all(mstate m,
+                                 void(*handler)(void *start,
+                                                void *end,
+                                                size_t used_bytes,
+                                                void* callback_arg),
+                                 void* arg) {
+  if (is_initialized(m)) {
+    mchunkptr top = m->top;
+    msegmentptr s;
+    for (s = &m->seg; s != 0; s = s->next) {
+      mchunkptr q = align_as_chunk(s->base);
+      while (segment_holds(s, q) && q->head != FENCEPOST_HEAD) {
+        mchunkptr next = next_chunk(q);
+        size_t sz = chunksize(q);
+        size_t used;
+        void* start;
+        if (is_inuse(q)) {
+          used = sz - CHUNK_OVERHEAD; /* must not be mmapped */
+          start = chunk2mem(q);
+        }
+        else {
+          used = 0;
+          if (is_small(sz)) {     /* offset by possible bookkeeping */
+            start = (void*)((char*)q + sizeof(malloc_chunk));
+          }
+          else {
+            start = (void*)((char*)q + sizeof(malloc_tree_chunk));
+          }
+        }
+        if (start < (void*)next)  /* skip if all space is bookkeeping */
+          handler(start, next, used, arg);
+        if (q == top)
+          break;
+        q = next;
+      }
+    }
+  }
+}
+#endif /* MALLOC_INSPECT_ALL */
+
+/* ------------------ Exported realloc, memalign, etc -------------------- */
+
+#if !ONLY_MSPACES
+
+void* dlrealloc(void* oldmem, size_t bytes) {
+  void* mem = 0;
+  if (oldmem == 0) {
+    mem = dlmalloc(bytes);
+  }
+  else if (bytes >= MAX_REQUEST) {
+    MALLOC_FAILURE_ACTION;
+  }
+#ifdef REALLOC_ZERO_BYTES_FREES
+  else if (bytes == 0) {
+    dlfree(oldmem);
+  }
+#endif /* REALLOC_ZERO_BYTES_FREES */
+  else {
+    size_t nb = request2size(bytes);
+    mchunkptr oldp = mem2chunk(oldmem);
+#if ! FOOTERS
+    mstate m = gm;
+#else /* FOOTERS */
+    mstate m = get_mstate_for(oldp);
+    if (!ok_magic(m)) {
+      USAGE_ERROR_ACTION(m, oldmem);
+      return 0;
+    }
+#endif /* FOOTERS */
+    if (!PREACTION(m)) {
+      mchunkptr newp = try_realloc_chunk(m, oldp, nb, 1);
+      POSTACTION(m);
+      if (newp != 0) {
+        check_inuse_chunk(m, newp);
+        mem = chunk2mem(newp);
+      }
+      else {
+        mem = internal_malloc(m, bytes);
+        if (mem != 0) {
+          size_t oc = chunksize(oldp) - overhead_for(oldp);
+          memcpy(mem, oldmem, (oc < bytes)? oc : bytes);
+          internal_free(m, oldmem);
+        }
+      }
+    }
+  }
+  return mem;
+}
+
+void* dlrealloc_in_place(void* oldmem, size_t bytes) {
+  void* mem = 0;
+  if (oldmem != 0) {
+    if (bytes >= MAX_REQUEST) {
+      MALLOC_FAILURE_ACTION;
+    }
+    else {
+      size_t nb = request2size(bytes);
+      mchunkptr oldp = mem2chunk(oldmem);
+#if ! FOOTERS
+      mstate m = gm;
+#else /* FOOTERS */
+      mstate m = get_mstate_for(oldp);
+      if (!ok_magic(m)) {
+        USAGE_ERROR_ACTION(m, oldmem);
+        return 0;
+      }
+#endif /* FOOTERS */
+      if (!PREACTION(m)) {
+        mchunkptr newp = try_realloc_chunk(m, oldp, nb, 0);
+        POSTACTION(m);
+        if (newp == oldp) {
+          check_inuse_chunk(m, newp);
+          mem = oldmem;
+        }
+      }
+    }
+  }
+  return mem;
+}
+
+void* dlmemalign(size_t alignment, size_t bytes) {
+  if (alignment <= MALLOC_ALIGNMENT) {
+    return dlmalloc(bytes);
+  }
+  return internal_memalign(gm, alignment, bytes);
+}
+
+int dlposix_memalign(void** pp, size_t alignment, size_t bytes) {
+  void* mem = 0;
+  if (alignment == MALLOC_ALIGNMENT)
+    mem = dlmalloc(bytes);
+  else {
+    size_t d = alignment / sizeof(void*);
+    size_t r = alignment % sizeof(void*);
+    if (r != 0 || d == 0 || (d & (d-SIZE_T_ONE)) != 0)
+      return EINVAL;
+    else if (bytes >= MAX_REQUEST - alignment) {
+      if (alignment <  MIN_CHUNK_SIZE)
+        alignment = MIN_CHUNK_SIZE;
+      mem = internal_memalign(gm, alignment, bytes);
+    }
+  }
+  if (mem == 0)
+    return ENOMEM;
+  else {
+    *pp = mem;
+    return 0;
+  }
+}
+
+void* dlvalloc(size_t bytes) {
+  size_t pagesz;
+  ensure_initialization();
+  pagesz = mparams.page_size;
+  return dlmemalign(pagesz, bytes);
+}
+
+void* dlpvalloc(size_t bytes) {
+  size_t pagesz;
+  ensure_initialization();
+  pagesz = mparams.page_size;
+  return dlmemalign(pagesz, (bytes + pagesz - SIZE_T_ONE) & ~(pagesz - SIZE_T_ONE));
+}
+
+void** dlindependent_calloc(size_t n_elements, size_t elem_size,
+                            void* chunks[]) {
+  size_t sz = elem_size; /* serves as 1-element array */
+  return ialloc(gm, n_elements, &sz, 3, chunks);
+}
+
+void** dlindependent_comalloc(size_t n_elements, size_t sizes[],
+                              void* chunks[]) {
+  return ialloc(gm, n_elements, sizes, 0, chunks);
+}
+
+size_t dlbulk_free(void* array[], size_t nelem) {
+  return internal_bulk_free(gm, array, nelem);
+}
+
+#if MALLOC_INSPECT_ALL
+void dlmalloc_inspect_all(void(*handler)(void *start,
+                                         void *end,
+                                         size_t used_bytes,
+                                         void* callback_arg),
+                          void* arg) {
+  ensure_initialization();
+  if (!PREACTION(gm)) {
+    internal_inspect_all(gm, handler, arg);
+    POSTACTION(gm);
+  }
+}
+#endif /* MALLOC_INSPECT_ALL */
+
+int dlmalloc_trim(size_t pad) {
+  int result = 0;
+  ensure_initialization();
+  if (!PREACTION(gm)) {
+    result = sys_trim(gm, pad);
+    POSTACTION(gm);
+  }
+  return result;
+}
+
+size_t dlmalloc_footprint(void) {
+  return gm->footprint;
+}
+
+size_t dlmalloc_max_footprint(void) {
+  return gm->max_footprint;
+}
+
+size_t dlmalloc_footprint_limit(void) {
+  size_t maf = gm->footprint_limit;
+  return maf == 0 ? MAX_SIZE_T : maf;
+}
+
+size_t dlmalloc_set_footprint_limit(size_t bytes) {
+  size_t result;  /* invert sense of 0 */
+  if (bytes == 0)
+    result = granularity_align(1); /* Use minimal size */
+  if (bytes == MAX_SIZE_T)
+    result = 0;                    /* disable */
+  else
+    result = granularity_align(bytes);
+  return gm->footprint_limit = result;
+}
+
+#if !NO_MALLINFO
+struct mallinfo dlmallinfo(void) {
+  return internal_mallinfo(gm);
+}
+#endif /* NO_MALLINFO */
+
+#if !NO_MALLOC_STATS
+void dlmalloc_stats() {
+  internal_malloc_stats(gm);
+}
+#endif /* NO_MALLOC_STATS */
+
+int dlmallopt(int param_number, int value) {
+  return change_mparam(param_number, value);
+}
+
+size_t dlmalloc_usable_size(void* mem) {
+  if (mem != 0) {
+    mchunkptr p = mem2chunk(mem);
+    if (is_inuse(p))
+      return chunksize(p) - overhead_for(p);
+  }
+  return 0;
+}
+
+#endif /* !ONLY_MSPACES */
+
+/* ----------------------------- user mspaces ---------------------------- */
+
+#if MSPACES
+
+static mstate init_user_mstate(char* tbase, size_t tsize) {
+  size_t msize = pad_request(sizeof(struct malloc_state));
+  mchunkptr mn;
+  mchunkptr msp = align_as_chunk(tbase);
+  mstate m = (mstate)(chunk2mem(msp));
+  memset(m, 0, msize);
+  (void)INITIAL_LOCK(&m->mutex);
+  msp->head = (msize|INUSE_BITS);
+  m->seg.base = m->least_addr = tbase;
+  m->seg.size = m->footprint = m->max_footprint = tsize;
+  m->magic = mparams.magic;
+  m->release_checks = MAX_RELEASE_CHECK_RATE;
+  m->mflags = mparams.default_mflags;
+  m->extp = 0;
+  m->exts = 0;
+  disable_contiguous(m);
+  init_bins(m);
+  mn = next_chunk(mem2chunk(m));
+  init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) - TOP_FOOT_SIZE);
+  check_top_chunk(m, m->top);
+  return m;
+}
+
+mspace create_mspace(size_t capacity, int locked) {
+  mstate m = 0;
+  size_t msize;
+  ensure_initialization();
+  msize = pad_request(sizeof(struct malloc_state));
+  if (capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) {
+    size_t rs = ((capacity == 0)? mparams.granularity :
+                 (capacity + TOP_FOOT_SIZE + msize));
+    size_t tsize = granularity_align(rs);
+    char* tbase = (char*)(CALL_MMAP(tsize));
+    if (tbase != CMFAIL) {
+      m = init_user_mstate(tbase, tsize);
+      m->seg.sflags = USE_MMAP_BIT;
+      set_lock(m, locked);
+    }
+  }
+  return (mspace)m;
+}
+
+mspace create_mspace_with_base(void* base, size_t capacity, int locked) {
+  mstate m = 0;
+  size_t msize;
+  ensure_initialization();
+  msize = pad_request(sizeof(struct malloc_state));
+  if (capacity > msize + TOP_FOOT_SIZE &&
+      capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) {
+    m = init_user_mstate((char*)base, capacity);
+    m->seg.sflags = EXTERN_BIT;
+    set_lock(m, locked);
+  }
+  return (mspace)m;
+}
+
+int mspace_track_large_chunks(mspace msp, int enable) {
+  int ret = 0;
+  mstate ms = (mstate)msp;
+  if (!PREACTION(ms)) {
+    if (!use_mmap(ms))
+      ret = 1;
+    if (!enable)
+      enable_mmap(ms);
+    else
+      disable_mmap(ms);
+    POSTACTION(ms);
+  }
+  return ret;
+}
+
+size_t destroy_mspace(mspace msp) {
+  size_t freed = 0;
+  mstate ms = (mstate)msp;
+  if (ok_magic(ms)) {
+    msegmentptr sp = &ms->seg;
+    (void)DESTROY_LOCK(&ms->mutex); /* destroy before unmapped */
+    while (sp != 0) {
+      char* base = sp->base;
+      size_t size = sp->size;
+      flag_t flag = sp->sflags;
+      sp = sp->next;
+      if ((flag & USE_MMAP_BIT) && !(flag & EXTERN_BIT) &&
+          CALL_MUNMAP(base, size) == 0)
+        freed += size;
+    }
+  }
+  else {
+    USAGE_ERROR_ACTION(ms,ms);
+  }
+  return freed;
+}
+
+/*
+  mspace versions of routines are near-clones of the global
+  versions. This is not so nice but better than the alternatives.
+*/
+
+void* mspace_malloc(mspace msp, size_t bytes) {
+  mstate ms = (mstate)msp;
+  if (!ok_magic(ms)) {
+    USAGE_ERROR_ACTION(ms,ms);
+    return 0;
+  }
+  if (!PREACTION(ms)) {
+    void* mem;
+    size_t nb;
+    if (bytes <= MAX_SMALL_REQUEST) {
+      bindex_t idx;
+      binmap_t smallbits;
+      nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes);
+      idx = small_index(nb);
+      smallbits = ms->smallmap >> idx;
+
+      if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */
+        mchunkptr b, p;
+        idx += ~smallbits & 1;       /* Uses next bin if idx empty */
+        b = smallbin_at(ms, idx);
+        p = b->fd;
+        assert(chunksize(p) == small_index2size(idx));
+        unlink_first_small_chunk(ms, b, p, idx);
+        set_inuse_and_pinuse(ms, p, small_index2size(idx));
+        mem = chunk2mem(p);
+        check_malloced_chunk(ms, mem, nb);
+        goto postaction;
+      }
+
+      else if (nb > ms->dvsize) {
+        if (smallbits != 0) { /* Use chunk in next nonempty smallbin */
+          mchunkptr b, p, r;
+          size_t rsize;
+          bindex_t i;
+          binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx));
+          binmap_t leastbit = least_bit(leftbits);
+          compute_bit2idx(leastbit, i);
+          b = smallbin_at(ms, i);
+          p = b->fd;
+          assert(chunksize(p) == small_index2size(i));
+          unlink_first_small_chunk(ms, b, p, i);
+          rsize = small_index2size(i) - nb;
+          /* Fit here cannot be remainderless if 4byte sizes */
+          if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE)
+            set_inuse_and_pinuse(ms, p, small_index2size(i));
+          else {
+            set_size_and_pinuse_of_inuse_chunk(ms, p, nb);
+            r = chunk_plus_offset(p, nb);
+            set_size_and_pinuse_of_free_chunk(r, rsize);
+            replace_dv(ms, r, rsize);
+          }
+          mem = chunk2mem(p);
+          check_malloced_chunk(ms, mem, nb);
+          goto postaction;
+        }
+
+        else if (ms->treemap != 0 && (mem = tmalloc_small(ms, nb)) != 0) {
+          check_malloced_chunk(ms, mem, nb);
+          goto postaction;
+        }
+      }
+    }
+    else if (bytes >= MAX_REQUEST)
+      nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */
+    else {
+      nb = pad_request(bytes);
+      if (ms->treemap != 0 && (mem = tmalloc_large(ms, nb)) != 0) {
+        check_malloced_chunk(ms, mem, nb);
+        goto postaction;
+      }
+    }
+
+    if (nb <= ms->dvsize) {
+      size_t rsize = ms->dvsize - nb;
+      mchunkptr p = ms->dv;
+      if (rsize >= MIN_CHUNK_SIZE) { /* split dv */
+        mchunkptr r = ms->dv = chunk_plus_offset(p, nb);
+        ms->dvsize = rsize;
+        set_size_and_pinuse_of_free_chunk(r, rsize);
+        set_size_and_pinuse_of_inuse_chunk(ms, p, nb);
+      }
+      else { /* exhaust dv */
+        size_t dvs = ms->dvsize;
+        ms->dvsize = 0;
+        ms->dv = 0;
+        set_inuse_and_pinuse(ms, p, dvs);
+      }
+      mem = chunk2mem(p);
+      check_malloced_chunk(ms, mem, nb);
+      goto postaction;
+    }
+
+    else if (nb < ms->topsize) { /* Split top */
+      size_t rsize = ms->topsize -= nb;
+      mchunkptr p = ms->top;
+      mchunkptr r = ms->top = chunk_plus_offset(p, nb);
+      r->head = rsize | PINUSE_BIT;
+      set_size_and_pinuse_of_inuse_chunk(ms, p, nb);
+      mem = chunk2mem(p);
+      check_top_chunk(ms, ms->top);
+      check_malloced_chunk(ms, mem, nb);
+      goto postaction;
+    }
+
+    mem = sys_alloc(ms, nb);
+
+  postaction:
+    POSTACTION(ms);
+    return mem;
+  }
+
+  return 0;
+}
+
+void mspace_free(mspace msp, void* mem) {
+  if (mem != 0) {
+    mchunkptr p  = mem2chunk(mem);
+#if FOOTERS
+    mstate fm = get_mstate_for(p);
+    msp = msp; /* placate people compiling -Wunused */
+#else /* FOOTERS */
+    mstate fm = (mstate)msp;
+#endif /* FOOTERS */
+    if (!ok_magic(fm)) {
+      USAGE_ERROR_ACTION(fm, p);
+      return;
+    }
+    if (!PREACTION(fm)) {
+      check_inuse_chunk(fm, p);
+      if (RTCHECK(ok_address(fm, p) && ok_inuse(p))) {
+        size_t psize = chunksize(p);
+        mchunkptr next = chunk_plus_offset(p, psize);
+        if (!pinuse(p)) {
+          size_t prevsize = p->prev_foot;
+          if (is_mmapped(p)) {
+            psize += prevsize + MMAP_FOOT_PAD;
+            if (CALL_MUNMAP((char*)p - prevsize, psize) == 0)
+              fm->footprint -= psize;
+            goto postaction;
+          }
+          else {
+            mchunkptr prev = chunk_minus_offset(p, prevsize);
+            psize += prevsize;
+            p = prev;
+            if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */
+              if (p != fm->dv) {
+                unlink_chunk(fm, p, prevsize);
+              }
+              else if ((next->head & INUSE_BITS) == INUSE_BITS) {
+                fm->dvsize = psize;
+                set_free_with_pinuse(p, psize, next);
+                goto postaction;
+              }
+            }
+            else
+              goto erroraction;
+          }
+        }
+
+        if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) {
+          if (!cinuse(next)) {  /* consolidate forward */
+            if (next == fm->top) {
+              size_t tsize = fm->topsize += psize;
+              fm->top = p;
+              p->head = tsize | PINUSE_BIT;
+              if (p == fm->dv) {
+                fm->dv = 0;
+                fm->dvsize = 0;
+              }
+              if (should_trim(fm, tsize))
+                sys_trim(fm, 0);
+              goto postaction;
+            }
+            else if (next == fm->dv) {
+              size_t dsize = fm->dvsize += psize;
+              fm->dv = p;
+              set_size_and_pinuse_of_free_chunk(p, dsize);
+              goto postaction;
+            }
+            else {
+              size_t nsize = chunksize(next);
+              psize += nsize;
+              unlink_chunk(fm, next, nsize);
+              set_size_and_pinuse_of_free_chunk(p, psize);
+              if (p == fm->dv) {
+                fm->dvsize = psize;
+                goto postaction;
+              }
+            }
+          }
+          else
+            set_free_with_pinuse(p, psize, next);
+
+          if (is_small(psize)) {
+            insert_small_chunk(fm, p, psize);
+            check_free_chunk(fm, p);
+          }
+          else {
+            tchunkptr tp = (tchunkptr)p;
+            insert_large_chunk(fm, tp, psize);
+            check_free_chunk(fm, p);
+            if (--fm->release_checks == 0)
+              release_unused_segments(fm);
+          }
+          goto postaction;
+        }
+      }
+    erroraction:
+      USAGE_ERROR_ACTION(fm, p);
+    postaction:
+      POSTACTION(fm);
+    }
+  }
+}
+
+void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size) {
+  void* mem;
+  size_t req = 0;
+  mstate ms = (mstate)msp;
+  if (!ok_magic(ms)) {
+    USAGE_ERROR_ACTION(ms,ms);
+    return 0;
+  }
+  if (n_elements != 0) {
+    req = n_elements * elem_size;
+    if (((n_elements | elem_size) & ~(size_t)0xffff) &&
+        (req / n_elements != elem_size))
+      req = MAX_SIZE_T; /* force downstream failure on overflow */
+  }
+  mem = internal_malloc(ms, req);
+  if (mem != 0 && calloc_must_clear(mem2chunk(mem)))
+    memset(mem, 0, req);
+  return mem;
+}
+
+void* mspace_realloc(mspace msp, void* oldmem, size_t bytes) {
+  void* mem = 0;
+  if (oldmem == 0) {
+    mem = mspace_malloc(msp, bytes);
+  }
+  else if (bytes >= MAX_REQUEST) {
+    MALLOC_FAILURE_ACTION;
+  }
+#ifdef REALLOC_ZERO_BYTES_FREES
+  else if (bytes == 0) {
+    mspace_free(msp, oldmem);
+  }
+#endif /* REALLOC_ZERO_BYTES_FREES */
+  else {
+    size_t nb = request2size(bytes);
+    mchunkptr oldp = mem2chunk(oldmem);
+#if ! FOOTERS
+    mstate m = (mstate)msp;
+#else /* FOOTERS */
+    mstate m = get_mstate_for(oldp);
+    if (!ok_magic(m)) {
+      USAGE_ERROR_ACTION(m, oldmem);
+      return 0;
+    }
+#endif /* FOOTERS */
+    if (!PREACTION(m)) {
+      mchunkptr newp = try_realloc_chunk(m, oldp, nb, 1);
+      POSTACTION(m);
+      if (newp != 0) {
+        check_inuse_chunk(m, newp);
+        mem = chunk2mem(newp);
+      }
+      else {
+        mem = mspace_malloc(m, bytes);
+        if (mem != 0) {
+          size_t oc = chunksize(oldp) - overhead_for(oldp);
+          memcpy(mem, oldmem, (oc < bytes)? oc : bytes);
+          mspace_free(m, oldmem);
+        }
+      }
+    }
+  }
+  return mem;
+}
+
+void* mspace_realloc_in_place(mspace msp, void* oldmem, size_t bytes) {
+  void* mem = 0;
+  if (oldmem != 0) {
+    if (bytes >= MAX_REQUEST) {
+      MALLOC_FAILURE_ACTION;
+    }
+    else {
+      size_t nb = request2size(bytes);
+      mchunkptr oldp = mem2chunk(oldmem);
+#if ! FOOTERS
+      mstate m = (mstate)msp;
+#else /* FOOTERS */
+      mstate m = get_mstate_for(oldp);
+      msp = msp; /* placate people compiling -Wunused */
+      if (!ok_magic(m)) {
+        USAGE_ERROR_ACTION(m, oldmem);
+        return 0;
+      }
+#endif /* FOOTERS */
+      if (!PREACTION(m)) {
+        mchunkptr newp = try_realloc_chunk(m, oldp, nb, 0);
+        POSTACTION(m);
+        if (newp == oldp) {
+          check_inuse_chunk(m, newp);
+          mem = oldmem;
+        }
+      }
+    }
+  }
+  return mem;
+}
+
+void* mspace_memalign(mspace msp, size_t alignment, size_t bytes) {
+  mstate ms = (mstate)msp;
+  if (!ok_magic(ms)) {
+    USAGE_ERROR_ACTION(ms,ms);
+    return 0;
+  }
+  if (alignment <= MALLOC_ALIGNMENT)
+    return mspace_malloc(msp, bytes);
+  return internal_memalign(ms, alignment, bytes);
+}
+
+void** mspace_independent_calloc(mspace msp, size_t n_elements,
+                                 size_t elem_size, void* chunks[]) {
+  size_t sz = elem_size; /* serves as 1-element array */
+  mstate ms = (mstate)msp;
+  if (!ok_magic(ms)) {
+    USAGE_ERROR_ACTION(ms,ms);
+    return 0;
+  }
+  return ialloc(ms, n_elements, &sz, 3, chunks);
+}
+
+void** mspace_independent_comalloc(mspace msp, size_t n_elements,
+                                   size_t sizes[], void* chunks[]) {
+  mstate ms = (mstate)msp;
+  if (!ok_magic(ms)) {
+    USAGE_ERROR_ACTION(ms,ms);
+    return 0;
+  }
+  return ialloc(ms, n_elements, sizes, 0, chunks);
+}
+
+size_t mspace_bulk_free(mspace msp, void* array[], size_t nelem) {
+  return internal_bulk_free((mstate)msp, array, nelem);
+}
+
+#if MALLOC_INSPECT_ALL
+void mspace_inspect_all(mspace msp,
+                        void(*handler)(void *start,
+                                       void *end,
+                                       size_t used_bytes,
+                                       void* callback_arg),
+                        void* arg) {
+  mstate ms = (mstate)msp;
+  if (ok_magic(ms)) {
+    if (!PREACTION(ms)) {
+      internal_inspect_all(ms, handler, arg);
+      POSTACTION(ms);
+    }
+  }
+  else {
+    USAGE_ERROR_ACTION(ms,ms);
+  }
+}
+#endif /* MALLOC_INSPECT_ALL */
+
+int mspace_trim(mspace msp, size_t pad) {
+  int result = 0;
+  mstate ms = (mstate)msp;
+  if (ok_magic(ms)) {
+    if (!PREACTION(ms)) {
+      result = sys_trim(ms, pad);
+      POSTACTION(ms);
+    }
+  }
+  else {
+    USAGE_ERROR_ACTION(ms,ms);
+  }
+  return result;
+}
+
+#if !NO_MALLOC_STATS
+void mspace_malloc_stats(mspace msp) {
+  mstate ms = (mstate)msp;
+  if (ok_magic(ms)) {
+    internal_malloc_stats(ms);
+  }
+  else {
+    USAGE_ERROR_ACTION(ms,ms);
+  }
+}
+#endif /* NO_MALLOC_STATS */
+
+size_t mspace_footprint(mspace msp) {
+  size_t result = 0;
+  mstate ms = (mstate)msp;
+  if (ok_magic(ms)) {
+    result = ms->footprint;
+  }
+  else {
+    USAGE_ERROR_ACTION(ms,ms);
+  }
+  return result;
+}
+
+size_t mspace_max_footprint(mspace msp) {
+  size_t result = 0;
+  mstate ms = (mstate)msp;
+  if (ok_magic(ms)) {
+    result = ms->max_footprint;
+  }
+  else {
+    USAGE_ERROR_ACTION(ms,ms);
+  }
+  return result;
+}
+
+size_t mspace_footprint_limit(mspace msp) {
+  size_t result = 0;
+  mstate ms = (mstate)msp;
+  if (ok_magic(ms)) {
+    size_t maf = ms->footprint_limit;
+    result = (maf == 0) ? MAX_SIZE_T : maf;
+  }
+  else {
+    USAGE_ERROR_ACTION(ms,ms);
+  }
+  return result;
+}
+
+size_t mspace_set_footprint_limit(mspace msp, size_t bytes) {
+  size_t result = 0;
+  mstate ms = (mstate)msp;
+  if (ok_magic(ms)) {
+    if (bytes == 0)
+      result = granularity_align(1); /* Use minimal size */
+    if (bytes == MAX_SIZE_T)
+      result = 0;                    /* disable */
+    else
+      result = granularity_align(bytes);
+    ms->footprint_limit = result;
+  }
+  else {
+    USAGE_ERROR_ACTION(ms,ms);
+  }
+  return result;
+}
+
+#if !NO_MALLINFO
+struct mallinfo mspace_mallinfo(mspace msp) {
+  mstate ms = (mstate)msp;
+  if (!ok_magic(ms)) {
+    USAGE_ERROR_ACTION(ms,ms);
+  }
+  return internal_mallinfo(ms);
+}
+#endif /* NO_MALLINFO */
+
+size_t mspace_usable_size(void* mem) {
+  if (mem != 0) {
+    mchunkptr p = mem2chunk(mem);
+    if (is_inuse(p))
+      return chunksize(p) - overhead_for(p);
+  }
+  return 0;
+}
+
+int mspace_mallopt(int param_number, int value) {
+  return change_mparam(param_number, value);
+}
+
+#endif /* MSPACES */
+
+
+/* -------------------- Alternative MORECORE functions ------------------- */
+
+/*
+  Guidelines for creating a custom version of MORECORE:
+
+  * For best performance, MORECORE should allocate in multiples of pagesize.
+  * MORECORE may allocate more memory than requested. (Or even less,
+      but this will usually result in a malloc failure.)
+  * MORECORE must not allocate memory when given argument zero, but
+      instead return one past the end address of memory from previous
+      nonzero call.
+  * For best performance, consecutive calls to MORECORE with positive
+      arguments should return increasing addresses, indicating that
+      space has been contiguously extended.
+  * Even though consecutive calls to MORECORE need not return contiguous
+      addresses, it must be OK for malloc'ed chunks to span multiple
+      regions in those cases where they do happen to be contiguous.
+  * MORECORE need not handle negative arguments -- it may instead
+      just return MFAIL when given negative arguments.
+      Negative arguments are always multiples of pagesize. MORECORE
+      must not misinterpret negative args as large positive unsigned
+      args. You can suppress all such calls from even occurring by defining
+      MORECORE_CANNOT_TRIM,
+
+  As an example alternative MORECORE, here is a custom allocator
+  kindly contributed for pre-OSX macOS.  It uses virtually but not
+  necessarily physically contiguous non-paged memory (locked in,
+  present and won't get swapped out).  You can use it by uncommenting
+  this section, adding some #includes, and setting up the appropriate
+  defines above:
+
+      #define MORECORE osMoreCore
+
+  There is also a shutdown routine that should somehow be called for
+  cleanup upon program exit.
+
+  #define MAX_POOL_ENTRIES 100
+  #define MINIMUM_MORECORE_SIZE  (64 * 1024U)
+  static int next_os_pool;
+  void *our_os_pools[MAX_POOL_ENTRIES];
+
+  void *osMoreCore(int size)
+  {
+    void *ptr = 0;
+    static void *sbrk_top = 0;
+
+    if (size > 0)
+    {
+      if (size < MINIMUM_MORECORE_SIZE)
+         size = MINIMUM_MORECORE_SIZE;
+      if (CurrentExecutionLevel() == kTaskLevel)
+         ptr = PoolAllocateResident(size + RM_PAGE_SIZE, 0);
+      if (ptr == 0)
+      {
+        return (void *) MFAIL;
+      }
+      // save ptrs so they can be freed during cleanup
+      our_os_pools[next_os_pool] = ptr;
+      next_os_pool++;
+      ptr = (void *) ((((size_t) ptr) + RM_PAGE_MASK) & ~RM_PAGE_MASK);
+      sbrk_top = (char *) ptr + size;
+      return ptr;
+    }
+    else if (size < 0)
+    {
+      // we don't currently support shrink behavior
+      return (void *) MFAIL;
+    }
+    else
+    {
+      return sbrk_top;
+    }
+  }
+
+  // cleanup any allocated memory pools
+  // called as last thing before shutting down driver
+
+  void osCleanupMem(void)
+  {
+    void **ptr;
+
+    for (ptr = our_os_pools; ptr < &our_os_pools[MAX_POOL_ENTRIES]; ptr++)
+      if (*ptr)
+      {
+         PoolDeallocate(*ptr);
+         *ptr = 0;
+      }
+  }
+
+*/
+
+
+/* -----------------------------------------------------------------------
+History:
+    v2.8.5 Sun May 22 10:26:02 2011  Doug Lea  (dl at gee)
+      * Always perform unlink checks unless INSECURE
+      * Add posix_memalign.
+      * Improve realloc to expand in more cases; expose realloc_in_place.
+        Thanks to Peter Buhr for the suggestion.
+      * Add footprint_limit, inspect_all, bulk_free. Thanks
+        to Barry Hayes and others for the suggestions.
+      * Internal refactorings to avoid calls while holding locks
+      * Use non-reentrant locks by default. Thanks to Roland McGrath
+        for the suggestion.
+      * Small fixes to mspace_destroy, reset_on_error.
+      * Various configuration extensions/changes. Thanks
+         to all who contributed these.
+
+    V2.8.4a Thu Apr 28 14:39:43 2011 (dl at gee.cs.oswego.edu)
+      * Update Creative Commons URL
+
+    V2.8.4 Wed May 27 09:56:23 2009  Doug Lea  (dl at gee)
+      * Use zeros instead of prev foot for is_mmapped
+      * Add mspace_track_large_chunks; thanks to Jean Brouwers
+      * Fix set_inuse in internal_realloc; thanks to Jean Brouwers
+      * Fix insufficient sys_alloc padding when using 16byte alignment
+      * Fix bad error check in mspace_footprint
+      * Adaptations for ptmalloc; thanks to Wolfram Gloger.
+      * Reentrant spin locks; thanks to Earl Chew and others
+      * Win32 improvements; thanks to Niall Douglas and Earl Chew
+      * Add NO_SEGMENT_TRAVERSAL and MAX_RELEASE_CHECK_RATE options
+      * Extension hook in malloc_state
+      * Various small adjustments to reduce warnings on some compilers
+      * Various configuration extensions/changes for more platforms. Thanks
+         to all who contributed these.
+
+    V2.8.3 Thu Sep 22 11:16:32 2005  Doug Lea  (dl at gee)
+      * Add max_footprint functions
+      * Ensure all appropriate literals are size_t
+      * Fix conditional compilation problem for some #define settings
+      * Avoid concatenating segments with the one provided
+        in create_mspace_with_base
+      * Rename some variables to avoid compiler shadowing warnings
+      * Use explicit lock initialization.
+      * Better handling of sbrk interference.
+      * Simplify and fix segment insertion, trimming and mspace_destroy
+      * Reinstate REALLOC_ZERO_BYTES_FREES option from 2.7.x
+      * Thanks especially to Dennis Flanagan for help on these.
+
+    V2.8.2 Sun Jun 12 16:01:10 2005  Doug Lea  (dl at gee)
+      * Fix memalign brace error.
+
+    V2.8.1 Wed Jun  8 16:11:46 2005  Doug Lea  (dl at gee)
+      * Fix improper #endif nesting in C++
+      * Add explicit casts needed for C++
+
+    V2.8.0 Mon May 30 14:09:02 2005  Doug Lea  (dl at gee)
+      * Use trees for large bins
+      * Support mspaces
+      * Use segments to unify sbrk-based and mmap-based system allocation,
+        removing need for emulation on most platforms without sbrk.
+      * Default safety checks
+      * Optional footer checks. Thanks to William Robertson for the idea.
+      * Internal code refactoring
+      * Incorporate suggestions and platform-specific changes.
+        Thanks to Dennis Flanagan, Colin Plumb, Niall Douglas,
+        Aaron Bachmann,  Emery Berger, and others.
+      * Speed up non-fastbin processing enough to remove fastbins.
+      * Remove useless cfree() to avoid conflicts with other apps.
+      * Remove internal memcpy, memset. Compilers handle builtins better.
+      * Remove some options that no one ever used and rename others.
+
+    V2.7.2 Sat Aug 17 09:07:30 2002  Doug Lea  (dl at gee)
+      * Fix malloc_state bitmap array misdeclaration
+
+    V2.7.1 Thu Jul 25 10:58:03 2002  Doug Lea  (dl at gee)
+      * Allow tuning of FIRST_SORTED_BIN_SIZE
+      * Use PTR_UINT as type for all ptr->int casts. Thanks to John Belmonte.
+      * Better detection and support for non-contiguousness of MORECORE.
+        Thanks to Andreas Mueller, Conal Walsh, and Wolfram Gloger
+      * Bypass most of malloc if no frees. Thanks To Emery Berger.
+      * Fix freeing of old top non-contiguous chunk im sysmalloc.
+      * Raised default trim and map thresholds to 256K.
+      * Fix mmap-related #defines. Thanks to Lubos Lunak.
+      * Fix copy macros; added LACKS_FCNTL_H. Thanks to Neal Walfield.
+      * Branch-free bin calculation
+      * Default trim and mmap thresholds now 256K.
+
+    V2.7.0 Sun Mar 11 14:14:06 2001  Doug Lea  (dl at gee)
+      * Introduce independent_comalloc and independent_calloc.
+        Thanks to Michael Pachos for motivation and help.
+      * Make optional .h file available
+      * Allow > 2GB requests on 32bit systems.
+      * new WIN32 sbrk, mmap, munmap, lock code from <Walter@GeNeSys-e.de>.
+        Thanks also to Andreas Mueller <a.mueller at paradatec.de>,
+        and Anonymous.
+      * Allow override of MALLOC_ALIGNMENT (Thanks to Ruud Waij for
+        helping test this.)
+      * memalign: check alignment arg
+      * realloc: don't try to shift chunks backwards, since this
+        leads to  more fragmentation in some programs and doesn't
+        seem to help in any others.
+      * Collect all cases in malloc requiring system memory into sysmalloc
+      * Use mmap as backup to sbrk
+      * Place all internal state in malloc_state
+      * Introduce fastbins (although similar to 2.5.1)
+      * Many minor tunings and cosmetic improvements
+      * Introduce USE_PUBLIC_MALLOC_WRAPPERS, USE_MALLOC_LOCK
+      * Introduce MALLOC_FAILURE_ACTION, MORECORE_CONTIGUOUS
+        Thanks to Tony E. Bennett <tbennett@nvidia.com> and others.
+      * Include errno.h to support default failure action.
+
+    V2.6.6 Sun Dec  5 07:42:19 1999  Doug Lea  (dl at gee)
+      * return null for negative arguments
+      * Added Several WIN32 cleanups from Martin C. Fong <mcfong at yahoo.com>
+         * Add 'LACKS_SYS_PARAM_H' for those systems without 'sys/param.h'
+          (e.g. WIN32 platforms)
+         * Cleanup header file inclusion for WIN32 platforms
+         * Cleanup code to avoid Microsoft Visual C++ compiler complaints
+         * Add 'USE_DL_PREFIX' to quickly allow co-existence with existing
+           memory allocation routines
+         * Set 'malloc_getpagesize' for WIN32 platforms (needs more work)
+         * Use 'assert' rather than 'ASSERT' in WIN32 code to conform to
+           usage of 'assert' in non-WIN32 code
+         * Improve WIN32 'sbrk()' emulation's 'findRegion()' routine to
+           avoid infinite loop
+      * Always call 'fREe()' rather than 'free()'
+
+    V2.6.5 Wed Jun 17 15:57:31 1998  Doug Lea  (dl at gee)
+      * Fixed ordering problem with boundary-stamping
+
+    V2.6.3 Sun May 19 08:17:58 1996  Doug Lea  (dl at gee)
+      * Added pvalloc, as recommended by H.J. Liu
+      * Added 64bit pointer support mainly from Wolfram Gloger
+      * Added anonymously donated WIN32 sbrk emulation
+      * Malloc, calloc, getpagesize: add optimizations from Raymond Nijssen
+      * malloc_extend_top: fix mask error that caused wastage after
+        foreign sbrks
+      * Add linux mremap support code from HJ Liu
+
+    V2.6.2 Tue Dec  5 06:52:55 1995  Doug Lea  (dl at gee)
+      * Integrated most documentation with the code.
+      * Add support for mmap, with help from
+        Wolfram Gloger (Gloger@lrz.uni-muenchen.de).
+      * Use last_remainder in more cases.
+      * Pack bins using idea from  colin@nyx10.cs.du.edu
+      * Use ordered bins instead of best-fit threshhold
+      * Eliminate block-local decls to simplify tracing and debugging.
+      * Support another case of realloc via move into top
+      * Fix error occuring when initial sbrk_base not word-aligned.
+      * Rely on page size for units instead of SBRK_UNIT to
+        avoid surprises about sbrk alignment conventions.
+      * Add mallinfo, mallopt. Thanks to Raymond Nijssen
+        (raymond@es.ele.tue.nl) for the suggestion.
+      * Add `pad' argument to malloc_trim and top_pad mallopt parameter.
+      * More precautions for cases where other routines call sbrk,
+        courtesy of Wolfram Gloger (Gloger@lrz.uni-muenchen.de).
+      * Added macros etc., allowing use in linux libc from
+        H.J. Lu (hjl@gnu.ai.mit.edu)
+      * Inverted this history list
+
+    V2.6.1 Sat Dec  2 14:10:57 1995  Doug Lea  (dl at gee)
+      * Re-tuned and fixed to behave more nicely with V2.6.0 changes.
+      * Removed all preallocation code since under current scheme
+        the work required to undo bad preallocations exceeds
+        the work saved in good cases for most test programs.
+      * No longer use return list or unconsolidated bins since
+        no scheme using them consistently outperforms those that don't
+        given above changes.
+      * Use best fit for very large chunks to prevent some worst-cases.
+      * Added some support for debugging
+
+    V2.6.0 Sat Nov  4 07:05:23 1995  Doug Lea  (dl at gee)
+      * Removed footers when chunks are in use. Thanks to
+        Paul Wilson (wilson@cs.texas.edu) for the suggestion.
+
+    V2.5.4 Wed Nov  1 07:54:51 1995  Doug Lea  (dl at gee)
+      * Added malloc_trim, with help from Wolfram Gloger
+        (wmglo@Dent.MED.Uni-Muenchen.DE).
+
+    V2.5.3 Tue Apr 26 10:16:01 1994  Doug Lea  (dl at g)
+
+    V2.5.2 Tue Apr  5 16:20:40 1994  Doug Lea  (dl at g)
+      * realloc: try to expand in both directions
+      * malloc: swap order of clean-bin strategy;
+      * realloc: only conditionally expand backwards
+      * Try not to scavenge used bins
+      * Use bin counts as a guide to preallocation
+      * Occasionally bin return list chunks in first scan
+      * Add a few optimizations from colin@nyx10.cs.du.edu
+
+    V2.5.1 Sat Aug 14 15:40:43 1993  Doug Lea  (dl at g)
+      * faster bin computation & slightly different binning
+      * merged all consolidations to one part of malloc proper
+         (eliminating old malloc_find_space & malloc_clean_bin)
+      * Scan 2 returns chunks (not just 1)
+      * Propagate failure in realloc if malloc returns 0
+      * Add stuff to allow compilation on non-ANSI compilers
+          from kpv@research.att.com
+
+    V2.5 Sat Aug  7 07:41:59 1993  Doug Lea  (dl at g.oswego.edu)
+      * removed potential for odd address access in prev_chunk
+      * removed dependency on getpagesize.h
+      * misc cosmetics and a bit more internal documentation
+      * anticosmetics: mangled names in macros to evade debugger strangeness
+      * tested on sparc, hp-700, dec-mips, rs6000
+          with gcc & native cc (hp, dec only) allowing
+          Detlefs & Zorn comparison study (in SIGPLAN Notices.)
+
+    Trial version Fri Aug 28 13:14:29 1992  Doug Lea  (dl at g.oswego.edu)
+      * Based loosely on libg++-1.2X malloc. (It retains some of the overall
+         structure of old version,  but most details differ.)
+
+*/
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+/* TODO: TEST ME */
+int main( void )
+{
+    return TEST_RESULTS;
+}
+
+#endif
index b79a83e24bd1d517b32634dad097490524030ef2..bf53a682144e36f203c5ab86eee417d9813de517 100644 (file)
@@ -1,85 +1,85 @@
-#include "_PDCLIB_aux.h"\r
-#include "_PDCLIB_config.h"\r
-#include "_PDCLIB_glue.h"\r
-#include <threads.h>\r
-\r
-typedef mtx_t MLOCK_T;\r
-#define INITIAL_LOCK(lk) mtx_init(lk, mtx_plain)\r
-#define DESTROY_LOCK(lk) mtx_destroy(lk)\r
-#define ACQUIRE_LOCK(lk) mtx_lock(lk)\r
-#define RELEASE_LOCK(lk) mtx_unlock(lk)\r
-#define TRY_LOCK(lk) mtx_trylock(lk)\r
-#define NEED_GLOBAL_LOCK_INIT\r
-static mtx_t malloc_global_mutex;\r
-static once_flag malloc_global_mutex_init_once;\r
-\r
-static void init_malloc_global_mutex(void)\r
-{\r
-       mtx_init(&malloc_global_mutex, mtx_plain);\r
-}\r
-\r
-static inline void *MMAP( size_t nbytes )\r
-{\r
-    void *p = _PDCLIB_allocpages( nbytes / _PDCLIB_MALLOC_PAGESIZE );\r
-    return p ? p : (void*) (~(size_t)0);\r
-}\r
-\r
-#define MMAP(s) MMAP(s)\r
-#define DIRECT_MMAP(s) MMAP(s)\r
-#define MUNMAP(a, s) ((_PDCLIB_freepages((a), (s)/_PDCLIB_MALLOC_PAGESIZE)), 0)\r
-#define MREMAP(a, osz, nsz, mv) _PDCLIB_reallocpages((a), (osz)/_PDCLIB_MALLOC_PAGESIZE, (nsz)/_PDCLIB_MALLOC_PAGESIZE, (mv))\r
-\r
-#undef WIN32\r
-#undef _WIN32\r
-#define DLMALLOC_EXPORT  _PDCLIB_API\r
-#define MALLOC_ALIGNMENT _PDCLIB_MALLOC_ALIGN\r
-#define MSPACES 0\r
-#define USE_LOCKS 2\r
-#define USE_SPIN_LOCKS 0\r
-#define USE_RECURSIVE_LOCKS 0\r
-#define FOOTERS 0\r
-#undef USE_DL_PREFIX\r
-#define MALLOC_INSPECT_ALL 0\r
-#define ABORT abort()\r
-#define PROCEED_ON_ERROR 0\r
-#define DEBUG 0\r
-#define ABORT_ON_ASSERT_FAILURE 0\r
-#define MALLOC_FAILURE_ACTION errno = ENOMEM\r
-#define HAVE_MORECORE 0\r
-#define MORECORE __unnamed__\r
-#define MORECORE_CONTIGUOUS 0\r
-#define MORECORE_CANNOT_TRIM 0\r
-#define NO_SEGMENT_TRAVERSAL 0\r
-#define HAVE_MMAP 1\r
-#if defined(_PDCLIB_HAVE_REALLOCPAGES)\r
-       #define HAVE_MREMAP 1\r
-#else\r
-       #define HAVE_MREMAP 0\r
-#endif\r
-#if defined(_PDCLIB_ALLOCPAGES_CLEARS)\r
-       #define MMAP_CLEARS 1\r
-#else\r
-       #define MMAP_CLEARS 0\r
-#endif\r
-#define USE_BUILTIN_FFS 0\r
-#define malloc_getpagesize _PDCLIB_MALLOC_PAGESIZE\r
-#define USE_DEV_RANDOM 0\r
-#define NO_MALLINFO 1\r
-#define MALLINFO_FIELD_TYPE size_t\r
-#define NO_MALLOC_STATS 1\r
-#define DEFAULT_GRANULARITY _PDCLIB_MALLOC_GRANULARITY\r
-#define DEFAULT_TRIM_THRESHOLD _PDCLIB_MALLOC_TRIM_THRESHOLD\r
-#define DEFAULT_MMAP_THREHOLD _PDCLIB_MALLOC_MMAP_THRESHOLD\r
-#define MAX_RELEASE_CHECK_RATE _PDCLIB_MALLOC_RELEASE_CHECK_RATE\r
-\r
-/* C standard says this is so */\r
-#define REALLOC_ZERO_BYTES_FREES 1\r
-#define LACKS_UNISTD_H\r
-#define LACKS_FCNTL_H\r
-#define LACKS_SYS_PARAM_H\r
-#define LACKS_SYS_MMAN_H\r
-#define LACKS_STRINGS_H\r
-#define LACKS_SYS_TYPES_H\r
-#define LACKS_SCHED_H\r
-#include <stdlib.h>\r
-#include <errno.h>\r
+#include "_PDCLIB_aux.h"
+#include "_PDCLIB_config.h"
+#include "_PDCLIB_glue.h"
+#include <threads.h>
+
+typedef mtx_t MLOCK_T;
+#define INITIAL_LOCK(lk) mtx_init(lk, mtx_plain)
+#define DESTROY_LOCK(lk) mtx_destroy(lk)
+#define ACQUIRE_LOCK(lk) mtx_lock(lk)
+#define RELEASE_LOCK(lk) mtx_unlock(lk)
+#define TRY_LOCK(lk) mtx_trylock(lk)
+#define NEED_GLOBAL_LOCK_INIT
+static mtx_t malloc_global_mutex;
+static once_flag malloc_global_mutex_init_once;
+
+static void init_malloc_global_mutex(void)
+{
+       mtx_init(&malloc_global_mutex, mtx_plain);
+}
+
+static inline void *MMAP( size_t nbytes )
+{
+    void *p = _PDCLIB_allocpages( nbytes / _PDCLIB_MALLOC_PAGESIZE );
+    return p ? p : (void*) (~(size_t)0);
+}
+
+#define MMAP(s) MMAP(s)
+#define DIRECT_MMAP(s) MMAP(s)
+#define MUNMAP(a, s) ((_PDCLIB_freepages((a), (s)/_PDCLIB_MALLOC_PAGESIZE)), 0)
+#define MREMAP(a, osz, nsz, mv) _PDCLIB_reallocpages((a), (osz)/_PDCLIB_MALLOC_PAGESIZE, (nsz)/_PDCLIB_MALLOC_PAGESIZE, (mv))
+
+#undef WIN32
+#undef _WIN32
+#define DLMALLOC_EXPORT  _PDCLIB_API
+#define MALLOC_ALIGNMENT _PDCLIB_MALLOC_ALIGN
+#define MSPACES 0
+#define USE_LOCKS 2
+#define USE_SPIN_LOCKS 0
+#define USE_RECURSIVE_LOCKS 0
+#define FOOTERS 0
+#undef USE_DL_PREFIX
+#define MALLOC_INSPECT_ALL 0
+#define ABORT abort()
+#define PROCEED_ON_ERROR 0
+#define DEBUG 0
+#define ABORT_ON_ASSERT_FAILURE 0
+#define MALLOC_FAILURE_ACTION errno = ENOMEM
+#define HAVE_MORECORE 0
+#define MORECORE __unnamed__
+#define MORECORE_CONTIGUOUS 0
+#define MORECORE_CANNOT_TRIM 0
+#define NO_SEGMENT_TRAVERSAL 0
+#define HAVE_MMAP 1
+#if defined(_PDCLIB_HAVE_REALLOCPAGES)
+       #define HAVE_MREMAP 1
+#else
+       #define HAVE_MREMAP 0
+#endif
+#if defined(_PDCLIB_ALLOCPAGES_CLEARS)
+       #define MMAP_CLEARS 1
+#else
+       #define MMAP_CLEARS 0
+#endif
+#define USE_BUILTIN_FFS 0
+#define malloc_getpagesize _PDCLIB_MALLOC_PAGESIZE
+#define USE_DEV_RANDOM 0
+#define NO_MALLINFO 1
+#define MALLINFO_FIELD_TYPE size_t
+#define NO_MALLOC_STATS 1
+#define DEFAULT_GRANULARITY _PDCLIB_MALLOC_GRANULARITY
+#define DEFAULT_TRIM_THRESHOLD _PDCLIB_MALLOC_TRIM_THRESHOLD
+#define DEFAULT_MMAP_THREHOLD _PDCLIB_MALLOC_MMAP_THRESHOLD
+#define MAX_RELEASE_CHECK_RATE _PDCLIB_MALLOC_RELEASE_CHECK_RATE
+
+/* C standard says this is so */
+#define REALLOC_ZERO_BYTES_FREES 1
+#define LACKS_UNISTD_H
+#define LACKS_FCNTL_H
+#define LACKS_SYS_PARAM_H
+#define LACKS_SYS_MMAN_H
+#define LACKS_STRINGS_H
+#define LACKS_SYS_TYPES_H
+#define LACKS_SCHED_H
+#include <stdlib.h>
+#include <errno.h>
index bb557872a4ea30e640ee15465519ed0eb7be735a..e0f87e58c159e5b359cc5f33e8e96766138306b8 100644 (file)
-#!/usr/bin/python\r
-# -*- coding: ascii -*-\r
-# Unicode Data Converter\r
-#\r
-# This file is part of the Public Domain C Library (PDCLib).\r
-# Permission is granted to use, modify, and / or redistribute at will.\r
-"""\r
-Converts the character information provdied by Unicode in the UnicodeData.txt\r
-file from the Unicode character database into a table for use by PDCLib.\r
-\r
-Usage: Download the UnicodeData.txt file to the same directory as this script \r
-and then run it. Both Python 2 and 3 are supported.\r
-\r
-Download the data from\r
-    ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt\r
-\r
-We do some simple "run" compression, because characters in the Unicode Data file\r
-tend to come in groups with the same properties.\r
-"""\r
-import os\r
-\r
-# MUST BE KEPT SYNCHRONIZED WITH _PDCLIB_locale.h\r
-BIT_ALPHA =   1\r
-BIT_BLANK =   2\r
-BIT_CNTRL =   4\r
-BIT_GRAPH =   8\r
-BIT_PUNCT =  16\r
-BIT_SPACE =  32\r
-BIT_LOWER =  64\r
-BIT_UPPER = 128\r
-BIT_DIGIT = 256\r
-BIT_XDIGT = 512\r
-\r
-# Category to bitfield mapping\r
-categories = {\r
-    'Lu': BIT_ALPHA | BIT_GRAPH | BIT_UPPER,    # Uppercase\r
-    'Ll': BIT_ALPHA | BIT_GRAPH | BIT_LOWER,    # Lowercase\r
-    'Lt': BIT_ALPHA | BIT_GRAPH | BIT_UPPER,    # Title case. Upper?\r
-    'Lm': BIT_ALPHA | BIT_GRAPH,                # Modifier. Case?\r
-    'Lo': BIT_ALPHA | BIT_GRAPH,                # "Other" letter (e.g. Ideograph)\r
-    'Nd': BIT_DIGIT | BIT_GRAPH,                # Decimal digit\r
-    'Nl': BIT_GRAPH,                            # Letter-like numeric character\r
-    'No': BIT_GRAPH,                            # Other numeric\r
-    'Pc': BIT_PUNCT | BIT_GRAPH,                # Connecting punctuation\r
-    'Pd': BIT_PUNCT | BIT_GRAPH,                # Dash punctuation\r
-    'Ps': BIT_PUNCT | BIT_GRAPH,                # Opening punctuation\r
-    'Pe': BIT_PUNCT | BIT_GRAPH,                # Closing punctuation\r
-    'Pi': BIT_PUNCT | BIT_GRAPH,                # Opening quote\r
-    'Pf': BIT_PUNCT | BIT_GRAPH,                # Closing quote\r
-    'Po': BIT_PUNCT | BIT_GRAPH,                # Other punctuation\r
-    'Sm': BIT_GRAPH,                            # Mathematical symbol\r
-    'Sc': BIT_GRAPH,                            # Currency symbol\r
-    'Sk': BIT_GRAPH,                            # Non-letterlike modifier symbol\r
-    'So': BIT_GRAPH,                            # Other symbol\r
-    'Zs': BIT_SPACE,                            # Non-zero-width space character\r
-    'Zl': BIT_SPACE,                            # Line separator\r
-    'Zp': BIT_SPACE,                            # Paragraph separator\r
-    'Cc': BIT_CNTRL,                            # C0/C1 control codes\r
-}\r
-\r
-# Characters with special properties\r
-special = {\r
-    # Blank characters\r
-    0x0020: BIT_SPACE | BIT_BLANK, # space\r
-    0x0009: BIT_SPACE | BIT_BLANK, # tab\r
-\r
-    # Digits\r
-    0x0030: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH,\r
-    0x0031: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH,\r
-    0x0032: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH,\r
-    0x0033: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH,\r
-    0x0034: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH,\r
-    0x0035: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH,\r
-    0x0036: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH,\r
-    0x0037: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH,\r
-    0x0038: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH,\r
-    0x0039: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH,\r
-\r
-    # A-F (hex uppercase)\r
-    0x0041: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_UPPER,\r
-    0x0042: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_UPPER,\r
-    0x0043: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_UPPER,\r
-    0x0044: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_UPPER,\r
-    0x0045: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_UPPER,\r
-    0x0046: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_UPPER,\r
-\r
-\r
-    # a-f (hex lowercase)\r
-    0x0061: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_LOWER,\r
-    0x0062: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_LOWER,\r
-    0x0063: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_LOWER,\r
-    0x0064: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_LOWER,\r
-    0x0065: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_LOWER,\r
-    0x0066: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_LOWER,\r
-}\r
-\r
-class Group:\r
-    def __init__(self, start, flags, upper_delta, lower_delta):\r
-        self.start = start\r
-        self.flags = flags\r
-        self.upper_delta = upper_delta\r
-        self.lower_delta = lower_delta\r
-        self.chars = []\r
-\r
-    def add_char(self, num, label):\r
-        self.chars.append((num, label))\r
-\r
-    def write_to_file(self, f):\r
-        for char in self.chars:\r
-            f.write("// %x %s\n" % char)\r
-        f.write("    { 0x%X, \t0x%X, \t0x%X, \t%d, \t%d },\n" %\r
-            (self.start, len(self.chars), self.flags, self.lower_delta, self.upper_delta))\r
-\r
-    def next(self):\r
-        return self.start + len(self.chars)\r
-\r
-groups = []\r
-\r
-def add_char(num, upper, lower, bits, label):\r
-    upper_delta = upper - num\r
-    lower_delta = lower - num\r
-\r
-    if len(groups) != 0:\r
-        cur = groups[-1]\r
-        if num == cur.next() and cur.flags == bits and \\r
-                cur.upper_delta == upper_delta and \\r
-                cur.lower_delta == lower_delta:\r
-            cur.add_char(num, label)\r
-            return\r
-\r
-    g = Group(num, bits, upper_delta, lower_delta)\r
-    g.add_char(num, label)\r
-    groups.append(g)\r
-\r
-in_file  = open('UnicodeData.txt', 'r')\r
-out_file = open('_PDCLIB_unicodedata.c', 'w')\r
-try:\r
-    for line in in_file:\r
-        (num_hex, name, category, combining_class, bidi_class, decomposition,\r
-         numeric_type, numeric_digit, numeric_value, mirrored, u1name, iso_com, \r
-         upper_case_hex, lower_case_hex, title_case_hex) = line.split(";")\r
-\r
-        num        = int(num_hex, 16)\r
-        upper_case = int(upper_case_hex, 16) if len(upper_case_hex) else num\r
-        lower_case = int(lower_case_hex, 16) if len(lower_case_hex) else num\r
-        bits = special.get(num, categories.get(category, 0))\r
-\r
-        if upper_case == 0 and lower_case == 0 and bits == 0:\r
-            continue\r
-\r
-        add_char(num, upper_case, lower_case, bits, name)\r
-\r
-    out_file.write("""\r
-/* Unicode Character Information ** AUTOMATICALLY GENERATED FILE **\r
- *\r
- * This file is part of the PDCLib public domain C Library, but is automatically\r
- * generated from the Unicode character data information file found at\r
- *   ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt\r
- * \r
- * As a result, the licensing that applies to that file also applies to this \r
- * file. The licensing which applies to the Unicode character data can be found \r
- * in Exhibit 1 of the Unicode Terms of Use, found at\r
- *   http://www.unicode.org/copyright.html#Exhibit1\r
- */\r
- #ifndef REGTEST\r
- #include <_PDCLIB_locale.h>\r
-\r
-const _PDCLIB_wcinfo_t _PDCLIB_wcinfo[] = {\r
-//   { value, \tlength, \tflags,\tlower,\tupper\t}, // name\r
- """)\r
-    for g in groups:\r
-        g.write_to_file(out_file)\r
-    out_file.write('};\n\n')\r
-    out_file.write("""\r
-const size_t _PDCLIB_wcinfo_size = sizeof(_PDCLIB_wcinfo) / sizeof(_PDCLIB_wcinfo[0]);\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-int main( void )\r
-{\r
-    return TEST_RESULTS;\r
-}\r
-#endif\r
-\r
-""")\r
-except:\r
-    in_file.close()\r
-    out_file.close()\r
-    os.remove('_PDCLIB_unicodedata.c')\r
-    raise\r
-else:\r
-    in_file.close()\r
-    out_file.close()\r
+#!/usr/bin/python
+# -*- coding: ascii -*-
+# Unicode Data Converter
+#
+# This file is part of the Public Domain C Library (PDCLib).
+# Permission is granted to use, modify, and / or redistribute at will.
+"""
+Converts the character information provdied by Unicode in the UnicodeData.txt
+file from the Unicode character database into a table for use by PDCLib.
+
+Usage: Download the UnicodeData.txt file to the same directory as this script 
+and then run it. Both Python 2 and 3 are supported.
+
+Download the data from
+    ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt
+
+We do some simple "run" compression, because characters in the Unicode Data file
+tend to come in groups with the same properties.
+"""
+import os
+
+# MUST BE KEPT SYNCHRONIZED WITH _PDCLIB_locale.h
+BIT_ALPHA =   1
+BIT_BLANK =   2
+BIT_CNTRL =   4
+BIT_GRAPH =   8
+BIT_PUNCT =  16
+BIT_SPACE =  32
+BIT_LOWER =  64
+BIT_UPPER = 128
+BIT_DIGIT = 256
+BIT_XDIGT = 512
+
+# Category to bitfield mapping
+categories = {
+    'Lu': BIT_ALPHA | BIT_GRAPH | BIT_UPPER,    # Uppercase
+    'Ll': BIT_ALPHA | BIT_GRAPH | BIT_LOWER,    # Lowercase
+    'Lt': BIT_ALPHA | BIT_GRAPH | BIT_UPPER,    # Title case. Upper?
+    'Lm': BIT_ALPHA | BIT_GRAPH,                # Modifier. Case?
+    'Lo': BIT_ALPHA | BIT_GRAPH,                # "Other" letter (e.g. Ideograph)
+    'Nd': BIT_DIGIT | BIT_GRAPH,                # Decimal digit
+    'Nl': BIT_GRAPH,                            # Letter-like numeric character
+    'No': BIT_GRAPH,                            # Other numeric
+    'Pc': BIT_PUNCT | BIT_GRAPH,                # Connecting punctuation
+    'Pd': BIT_PUNCT | BIT_GRAPH,                # Dash punctuation
+    'Ps': BIT_PUNCT | BIT_GRAPH,                # Opening punctuation
+    'Pe': BIT_PUNCT | BIT_GRAPH,                # Closing punctuation
+    'Pi': BIT_PUNCT | BIT_GRAPH,                # Opening quote
+    'Pf': BIT_PUNCT | BIT_GRAPH,                # Closing quote
+    'Po': BIT_PUNCT | BIT_GRAPH,                # Other punctuation
+    'Sm': BIT_GRAPH,                            # Mathematical symbol
+    'Sc': BIT_GRAPH,                            # Currency symbol
+    'Sk': BIT_GRAPH,                            # Non-letterlike modifier symbol
+    'So': BIT_GRAPH,                            # Other symbol
+    'Zs': BIT_SPACE,                            # Non-zero-width space character
+    'Zl': BIT_SPACE,                            # Line separator
+    'Zp': BIT_SPACE,                            # Paragraph separator
+    'Cc': BIT_CNTRL,                            # C0/C1 control codes
+}
+
+# Characters with special properties
+special = {
+    # Blank characters
+    0x0020: BIT_SPACE | BIT_BLANK, # space
+    0x0009: BIT_SPACE | BIT_BLANK, # tab
+
+    # Digits
+    0x0030: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH,
+    0x0031: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH,
+    0x0032: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH,
+    0x0033: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH,
+    0x0034: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH,
+    0x0035: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH,
+    0x0036: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH,
+    0x0037: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH,
+    0x0038: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH,
+    0x0039: BIT_XDIGT | BIT_DIGIT | BIT_GRAPH,
+
+    # A-F (hex uppercase)
+    0x0041: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_UPPER,
+    0x0042: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_UPPER,
+    0x0043: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_UPPER,
+    0x0044: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_UPPER,
+    0x0045: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_UPPER,
+    0x0046: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_UPPER,
+
+
+    # a-f (hex lowercase)
+    0x0061: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_LOWER,
+    0x0062: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_LOWER,
+    0x0063: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_LOWER,
+    0x0064: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_LOWER,
+    0x0065: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_LOWER,
+    0x0066: BIT_XDIGT | BIT_ALPHA | BIT_GRAPH | BIT_LOWER,
+}
+
+class Group:
+    def __init__(self, start, flags, upper_delta, lower_delta):
+        self.start = start
+        self.flags = flags
+        self.upper_delta = upper_delta
+        self.lower_delta = lower_delta
+        self.chars = []
+
+    def add_char(self, num, label):
+        self.chars.append((num, label))
+
+    def write_to_file(self, f):
+        for char in self.chars:
+            f.write("// %x %s\n" % char)
+        f.write("    { 0x%X, \t0x%X, \t0x%X, \t%d, \t%d },\n" %
+            (self.start, len(self.chars), self.flags, self.lower_delta, self.upper_delta))
+
+    def next(self):
+        return self.start + len(self.chars)
+
+groups = []
+
+def add_char(num, upper, lower, bits, label):
+    upper_delta = upper - num
+    lower_delta = lower - num
+
+    if len(groups) != 0:
+        cur = groups[-1]
+        if num == cur.next() and cur.flags == bits and \
+                cur.upper_delta == upper_delta and \
+                cur.lower_delta == lower_delta:
+            cur.add_char(num, label)
+            return
+
+    g = Group(num, bits, upper_delta, lower_delta)
+    g.add_char(num, label)
+    groups.append(g)
+
+in_file  = open('UnicodeData.txt', 'r')
+out_file = open('_PDCLIB_unicodedata.c', 'w')
+try:
+    for line in in_file:
+        (num_hex, name, category, combining_class, bidi_class, decomposition,
+         numeric_type, numeric_digit, numeric_value, mirrored, u1name, iso_com, 
+         upper_case_hex, lower_case_hex, title_case_hex) = line.split(";")
+
+        num        = int(num_hex, 16)
+        upper_case = int(upper_case_hex, 16) if len(upper_case_hex) else num
+        lower_case = int(lower_case_hex, 16) if len(lower_case_hex) else num
+        bits = special.get(num, categories.get(category, 0))
+
+        if upper_case == 0 and lower_case == 0 and bits == 0:
+            continue
+
+        add_char(num, upper_case, lower_case, bits, name)
+
+    out_file.write("""
+/* Unicode Character Information ** AUTOMATICALLY GENERATED FILE **
+ *
+ * This file is part of the PDCLib public domain C Library, but is automatically
+ * generated from the Unicode character data information file found at
+ *   ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt
+ * 
+ * As a result, the licensing that applies to that file also applies to this 
+ * file. The licensing which applies to the Unicode character data can be found 
+ * in Exhibit 1 of the Unicode Terms of Use, found at
+ *   http://www.unicode.org/copyright.html#Exhibit1
+ */
+ #ifndef REGTEST
+ #include <_PDCLIB_locale.h>
+
+const _PDCLIB_wcinfo_t _PDCLIB_wcinfo[] = {
+//   { value, \tlength, \tflags,\tlower,\tupper\t}, // name
+ """)
+    for g in groups:
+        g.write_to_file(out_file)
+    out_file.write('};\n\n')
+    out_file.write("""
+const size_t _PDCLIB_wcinfo_size = sizeof(_PDCLIB_wcinfo) / sizeof(_PDCLIB_wcinfo[0]);
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+int main( void )
+{
+    return TEST_RESULTS;
+}
+#endif
+
+""")
+except:
+    in_file.close()
+    out_file.close()
+    os.remove('_PDCLIB_unicodedata.c')
+    raise
+else:
+    in_file.close()
+    out_file.close()
index 7d5073b4ded6fd89e28471dcd0d1634b1864a417..6ab34e9f0bb0ca7f49b026292fab148023bbf5a2 100644 (file)
@@ -1,29 +1,29 @@
-/* freelocale( locale_t )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <locale.h>\r
-#ifndef REGTEST\r
-#include "_PDCLIB_locale.h"\r
-#include <assert.h>\r
-\r
-void freelocale( locale_t newloc )\r
-{\r
-    if( newloc != NULL ) {\r
-        assert( ! "Not implemented" );\r
-    }\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    TESTCASE( NO_TESTDRIVER );\r
-    return TEST_RESULTS;\r
-}\r
-#endif\r
+/* freelocale( locale_t )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <locale.h>
+#ifndef REGTEST
+#include "_PDCLIB_locale.h"
+#include <assert.h>
+
+void freelocale( locale_t newloc )
+{
+    if( newloc != NULL ) {
+        assert( ! "Not implemented" );
+    }
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    TESTCASE( NO_TESTDRIVER );
+    return TEST_RESULTS;
+}
+#endif
index 146edf0716539acc958a7b6a29101a9b2fd4e568..7cfbe9355351eb469f5e06a721493a610607105a 100644 (file)
@@ -1,46 +1,46 @@
-/* _PDCLIB_fillbuffer( FILE * stream )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <stdio.h>\r
-\r
-#ifndef REGTEST\r
-#include "_PDCLIB_glue.h"\r
-#include "_PDCLIB_io.h"\r
-\r
-int _PDCLIB_fillbuffer( FILE * stream )\r
-{\r
-    size_t bytesRead;\r
-    bool ok = stream->ops->read( stream->handle, stream->buffer, stream->bufsize,\r
-                        &bytesRead);\r
-\r
-    if( ok ) {\r
-        if( bytesRead == 0 ) {\r
-            stream->status |= _PDCLIB_EOFFLAG;\r
-            return EOF;\r
-        }\r
-        stream->pos.offset += bytesRead;\r
-        stream->bufend = bytesRead;\r
-        stream->bufidx = 0;\r
-        return 0;\r
-    } else {\r
-        stream->status |= _PDCLIB_ERRORFLAG;\r
-        return EOF;\r
-    }\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    /* Testing covered by ftell.c */\r
-    return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
-\r
+/* _PDCLIB_fillbuffer( FILE * stream )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <stdio.h>
+
+#ifndef REGTEST
+#include "_PDCLIB_glue.h"
+#include "_PDCLIB_io.h"
+
+int _PDCLIB_fillbuffer( FILE * stream )
+{
+    size_t bytesRead;
+    bool ok = stream->ops->read( stream->handle, stream->buffer, stream->bufsize,
+                        &bytesRead);
+
+    if( ok ) {
+        if( bytesRead == 0 ) {
+            stream->status |= _PDCLIB_EOFFLAG;
+            return EOF;
+        }
+        stream->pos.offset += bytesRead;
+        stream->bufend = bytesRead;
+        stream->bufidx = 0;
+        return 0;
+    } else {
+        stream->status |= _PDCLIB_ERRORFLAG;
+        return EOF;
+    }
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    /* Testing covered by ftell.c */
+    return TEST_RESULTS;
+}
+
+#endif
+
index 30f132f0261a82faf8af181cad12136a43478578..e7cf47c3549cad4d09e3687ec448666c0d450623 100644 (file)
-/* _PDCLIB_flushbuffer( struct _PDCLIB_file_t * )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <stdio.h>\r
-#include <string.h>\r
-\r
-#ifndef REGTEST\r
-#include "_PDCLIB_glue.h"\r
-#include "_PDCLIB_io.h"\r
-\r
-\r
-static int flushsubbuffer( FILE * stream, size_t length )\r
-{\r
-    size_t justWrote;\r
-    size_t written = 0;\r
-    int rv = 0;\r
-\r
-#if 0\r
-    // Very useful for debugging buffering issues\r
-    char l = '<', r = '>';\r
-    stream->ops->write( stream->handle, &l,  1, &justWrote );\r
-#endif\r
-\r
-    while( written != length )\r
-    {\r
-        size_t toWrite = length - written;\r
-\r
-        bool res = stream->ops->write( stream->handle, stream->buffer + written,\r
-                              toWrite, &justWrote);\r
-        written += justWrote;\r
-        stream->pos.offset += justWrote;\r
-\r
-        if (!res)\r
-        {\r
-            stream->status |= _PDCLIB_ERRORFLAG;\r
-            rv = EOF;\r
-            break;\r
-        }\r
-    }\r
-\r
-#if 0\r
-    stream->ops->write( stream->handle, &r,  1, &justWrote );\r
-#endif\r
-\r
-    stream->bufidx   -= written;\r
-#ifdef _PDCLIB_NEED_EOL_TRANSLATION\r
-    stream->bufnlexp -= written;\r
-#endif\r
-    memmove( stream->buffer, stream->buffer + written, stream->bufidx );\r
-\r
-    return rv;\r
-}\r
-\r
-int _PDCLIB_flushbuffer( FILE * stream )\r
-{\r
-#ifdef _PDCLIB_NEED_EOL_TRANSLATION\r
-    // if a text stream, and this platform needs EOL translation, well...\r
-    if ( ! ( stream->status & _PDCLIB_FBIN ) )\r
-    {\r
-        // Special case: buffer is full and we start with a \n\r
-        if ( stream->bufnlexp == 0\r
-            && stream->bufidx == stream->bufend\r
-            && stream->buffer[0] == '\n' )\r
-        {\r
-            char cr = '\r';\r
-            size_t written = 0;\r
-            bool res = stream->ops->write( stream->handle, &cr, 1, &written );\r
-\r
-            if (!res) {\r
-                stream->status |= _PDCLIB_ERRORFLAG;\r
-                return EOF;\r
-            }\r
-\r
-        }\r
-\r
-        for ( ; stream->bufnlexp < stream->bufidx; stream->bufnlexp++ )\r
-        {\r
-            if (stream->buffer[stream->bufnlexp] == '\n' ) {\r
-                if ( stream->bufidx == stream->bufend ) {\r
-                    // buffer is full. Need to print out everything up till now\r
-                    if( flushsubbuffer( stream, stream->bufnlexp - 1 ) )\r
-                    {\r
-                        return EOF;\r
-                    }\r
-                }\r
-\r
-                // we have spare space in buffer. Shift everything 1char and\r
-                // insert \r\r
-                memmove( &stream->buffer[stream->bufnlexp + 1],\r
-                         &stream->buffer[stream->bufnlexp],\r
-                         stream->bufidx - stream->bufnlexp );\r
-                stream->buffer[stream->bufnlexp] = '\r';\r
-\r
-                stream->bufnlexp++;\r
-                stream->bufidx++;\r
-            }\r
-        }\r
-    }\r
-#endif\r
-    return flushsubbuffer( stream, stream->bufidx );\r
-}\r
-\r
-#endif\r
-\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    /* Testing covered by ftell.c */\r
-    return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
-\r
+/* _PDCLIB_flushbuffer( struct _PDCLIB_file_t * )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <stdio.h>
+#include <string.h>
+
+#ifndef REGTEST
+#include "_PDCLIB_glue.h"
+#include "_PDCLIB_io.h"
+
+
+static int flushsubbuffer( FILE * stream, size_t length )
+{
+    size_t justWrote;
+    size_t written = 0;
+    int rv = 0;
+
+#if 0
+    // Very useful for debugging buffering issues
+    char l = '<', r = '>';
+    stream->ops->write( stream->handle, &l,  1, &justWrote );
+#endif
+
+    while( written != length )
+    {
+        size_t toWrite = length - written;
+
+        bool res = stream->ops->write( stream->handle, stream->buffer + written,
+                              toWrite, &justWrote);
+        written += justWrote;
+        stream->pos.offset += justWrote;
+
+        if (!res)
+        {
+            stream->status |= _PDCLIB_ERRORFLAG;
+            rv = EOF;
+            break;
+        }
+    }
+
+#if 0
+    stream->ops->write( stream->handle, &r,  1, &justWrote );
+#endif
+
+    stream->bufidx   -= written;
+#ifdef _PDCLIB_NEED_EOL_TRANSLATION
+    stream->bufnlexp -= written;
+#endif
+    memmove( stream->buffer, stream->buffer + written, stream->bufidx );
+
+    return rv;
+}
+
+int _PDCLIB_flushbuffer( FILE * stream )
+{
+#ifdef _PDCLIB_NEED_EOL_TRANSLATION
+    // if a text stream, and this platform needs EOL translation, well...
+    if ( ! ( stream->status & _PDCLIB_FBIN ) )
+    {
+        // Special case: buffer is full and we start with a \n
+        if ( stream->bufnlexp == 0
+            && stream->bufidx == stream->bufend
+            && stream->buffer[0] == '\n' )
+        {
+            char cr = '\r';
+            size_t written = 0;
+            bool res = stream->ops->write( stream->handle, &cr, 1, &written );
+
+            if (!res) {
+                stream->status |= _PDCLIB_ERRORFLAG;
+                return EOF;
+            }
+
+        }
+
+        for ( ; stream->bufnlexp < stream->bufidx; stream->bufnlexp++ )
+        {
+            if (stream->buffer[stream->bufnlexp] == '\n' ) {
+                if ( stream->bufidx == stream->bufend ) {
+                    // buffer is full. Need to print out everything up till now
+                    if( flushsubbuffer( stream, stream->bufnlexp - 1 ) )
+                    {
+                        return EOF;
+                    }
+                }
+
+                // we have spare space in buffer. Shift everything 1char and
+                // insert \r
+                memmove( &stream->buffer[stream->bufnlexp + 1],
+                         &stream->buffer[stream->bufnlexp],
+                         stream->bufidx - stream->bufnlexp );
+                stream->buffer[stream->bufnlexp] = '\r';
+
+                stream->bufnlexp++;
+                stream->bufidx++;
+            }
+        }
+    }
+#endif
+    return flushsubbuffer( stream, stream->bufidx );
+}
+
+#endif
+
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    /* Testing covered by ftell.c */
+    return TEST_RESULTS;
+}
+
+#endif
+
index 77ab8723921e6f9513e7b3bba03bd4f36adb7163..ea93fc69f467a481304181e65f73fb84e430fd9f 100644 (file)
@@ -1,62 +1,62 @@
-/* _PDCLIB_ftell64( FILE * )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <stdio.h>\r
-#include <stdint.h>\r
-#include <limits.h>\r
-\r
-#ifndef REGTEST\r
-#include "_PDCLIB_io.h"\r
-\r
-uint_fast64_t _PDCLIB_ftell64_unlocked( FILE * stream )\r
-{\r
-    /* ftell() must take into account:\r
-       - the actual *physical* offset of the file, i.e. the offset as recognized\r
-         by the operating system (and stored in stream->pos.offset); and\r
-       - any buffers held by PDCLib, which\r
-         - in case of unwritten buffers, count in *addition* to the offset; or\r
-         - in case of unprocessed pre-read buffers, count in *substraction* to\r
-           the offset. (Remember to count ungetidx into this number.)\r
-       Conveniently, the calculation ( ( bufend - bufidx ) + ungetidx ) results\r
-       in just the right number in both cases:\r
-         - in case of unwritten buffers, ( ( 0 - unwritten ) + 0 )\r
-           i.e. unwritten bytes as negative number\r
-         - in case of unprocessed pre-read, ( ( preread - processed ) + unget )\r
-           i.e. unprocessed bytes as positive number.\r
-       That is how the somewhat obscure return-value calculation works.\r
-    */\r
-\r
-    /* ungetc on a stream at offset==0 will cause an overflow to UINT64_MAX.\r
-     * C99/C11 says that the return value of ftell in this case is \r
-     * "indeterminate"\r
-     */\r
-\r
-    return ( stream->pos.offset - ( ( (int)stream->bufend - (int)stream->bufidx ) + (int)stream->ungetidx ) );\r
-}\r
-\r
-uint_fast64_t _PDCLIB_ftell64( FILE * stream )\r
-{\r
-  _PDCLIB_flockfile( stream );\r
-  uint_fast64_t pos = _PDCLIB_ftell64_unlocked( stream );\r
-  _PDCLIB_funlockfile( stream );\r
-  return pos;\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-#include <stdlib.h>\r
-\r
-int main( void )\r
-{\r
-    /* Tested by ftell */\r
-    return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
-\r
+/* _PDCLIB_ftell64( FILE * )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <stdio.h>
+#include <stdint.h>
+#include <limits.h>
+
+#ifndef REGTEST
+#include "_PDCLIB_io.h"
+
+uint_fast64_t _PDCLIB_ftell64_unlocked( FILE * stream )
+{
+    /* ftell() must take into account:
+       - the actual *physical* offset of the file, i.e. the offset as recognized
+         by the operating system (and stored in stream->pos.offset); and
+       - any buffers held by PDCLib, which
+         - in case of unwritten buffers, count in *addition* to the offset; or
+         - in case of unprocessed pre-read buffers, count in *substraction* to
+           the offset. (Remember to count ungetidx into this number.)
+       Conveniently, the calculation ( ( bufend - bufidx ) + ungetidx ) results
+       in just the right number in both cases:
+         - in case of unwritten buffers, ( ( 0 - unwritten ) + 0 )
+           i.e. unwritten bytes as negative number
+         - in case of unprocessed pre-read, ( ( preread - processed ) + unget )
+           i.e. unprocessed bytes as positive number.
+       That is how the somewhat obscure return-value calculation works.
+    */
+
+    /* ungetc on a stream at offset==0 will cause an overflow to UINT64_MAX.
+     * C99/C11 says that the return value of ftell in this case is 
+     * "indeterminate"
+     */
+
+    return ( stream->pos.offset - ( ( (int)stream->bufend - (int)stream->bufidx ) + (int)stream->ungetidx ) );
+}
+
+uint_fast64_t _PDCLIB_ftell64( FILE * stream )
+{
+  _PDCLIB_flockfile( stream );
+  uint_fast64_t pos = _PDCLIB_ftell64_unlocked( stream );
+  _PDCLIB_funlockfile( stream );
+  return pos;
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+#include <stdlib.h>
+
+int main( void )
+{
+    /* Tested by ftell */
+    return TEST_RESULTS;
+}
+
+#endif
+
index 307d0c9cc04a38fb879005ff0f080800128934fd..292ba3922c05f5d1ba5acd511e83942aa353f8a7 100644 (file)
-/* _PDCLIB_fvopen( _PDCLIB_fd_t, _PDCLIB_fileops_t * )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-\r
-#ifndef REGTEST\r
-#include "_PDCLIB_glue.h"\r
-#include "_PDCLIB_io.h"\r
-#include <string.h>\r
-#include <threads.h>\r
-\r
-extern FILE * _PDCLIB_filelist;\r
-\r
-FILE * _PDCLIB_fvopen(\r
-    _PDCLIB_fd_t                                    fd,\r
-    const _PDCLIB_fileops_t    *_PDCLIB_restrict    ops,\r
-    int                                             mode,\r
-    const char                  *_PDCLIB_restrict   filename\r
-)\r
-{\r
-    size_t filename_len;\r
-    FILE * rc;\r
-    if ( mode == NULL )\r
-    {\r
-        /* Mode invalid */\r
-        return NULL;\r
-    }\r
-    /* To reduce the number of malloc calls, all data fields are concatenated:\r
-       * the FILE structure itself,\r
-       * ungetc buffer,\r
-       * filename buffer,\r
-       * data buffer.\r
-       Data buffer comes last because it might change in size ( setvbuf() ).\r
-    */\r
-    filename_len = filename ? strlen( filename ) + 1 : 1;\r
-    if ( ( rc = calloc( 1, sizeof( FILE ) + _PDCLIB_UNGETCBUFSIZE + filename_len + BUFSIZ ) ) == NULL )\r
-    {\r
-        /* no memory */\r
-        return NULL;\r
-    }\r
-\r
-    if(mtx_init(&rc->lock, mtx_recursive) != thrd_success) {\r
-        free(rc);\r
-        return NULL;\r
-    }\r
-\r
-    rc->status = mode;\r
-    rc->ops    = ops;\r
-    rc->handle = fd;\r
-    /* Setting pointers into the memory block allocated above */\r
-    rc->ungetbuf = (unsigned char *)rc + sizeof( FILE );\r
-    rc->filename = (char *)rc->ungetbuf + _PDCLIB_UNGETCBUFSIZE;\r
-    rc->buffer   = rc->filename + filename_len;\r
-    /* Copying filename to FILE structure */\r
-    if(filename) strcpy( rc->filename, filename );\r
-    /* Initializing the rest of the structure */\r
-    rc->bufsize = BUFSIZ;\r
-    rc->bufidx = 0;\r
-#ifdef _PDCLIB_NEED_EOL_TRANSLATION\r
-    rc->bufnlexp = 0;\r
-#endif\r
-    rc->ungetidx = 0;\r
-    /* Setting buffer to _IOLBF because "when opened, a stream is fully\r
-       buffered if and only if it can be determined not to refer to an\r
-       interactive device."\r
-    */\r
-    rc->status |= _IOLBF;\r
-    /* TODO: Setting mbstate */\r
-    /* Adding to list of open files */\r
-    rc->next = _PDCLIB_filelist;\r
-    _PDCLIB_filelist = rc;\r
-    return rc;\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    /* Some of the tests are not executed for regression tests, as the libc on\r
-       my system is at once less forgiving (segfaults on mode NULL) and more\r
-       forgiving (accepts undefined modes).\r
-    */\r
-    FILE * fh;\r
-    remove( testfile );\r
-    TESTCASE_NOREG( fopen( NULL, NULL ) == NULL );\r
-    TESTCASE( fopen( NULL, "w" ) == NULL );\r
-    TESTCASE_NOREG( fopen( "", NULL ) == NULL );\r
-    TESTCASE( fopen( "", "w" ) == NULL );\r
-    TESTCASE( fopen( "foo", "" ) == NULL );\r
-    TESTCASE_NOREG( fopen( testfile, "wq" ) == NULL ); /* Undefined mode */\r
-    TESTCASE_NOREG( fopen( testfile, "wr" ) == NULL ); /* Undefined mode */\r
-    TESTCASE( ( fh = fopen( testfile, "w" ) ) != NULL );\r
-    TESTCASE( fclose( fh ) == 0 );\r
-    TESTCASE( remove( testfile ) == 0 );\r
-    return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
+/* _PDCLIB_fvopen( _PDCLIB_fd_t, _PDCLIB_fileops_t * )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifndef REGTEST
+#include "_PDCLIB_glue.h"
+#include "_PDCLIB_io.h"
+#include <string.h>
+#include <threads.h>
+
+extern FILE * _PDCLIB_filelist;
+
+FILE * _PDCLIB_fvopen(
+    _PDCLIB_fd_t                                    fd,
+    const _PDCLIB_fileops_t    *_PDCLIB_restrict    ops,
+    int                                             mode,
+    const char                  *_PDCLIB_restrict   filename
+)
+{
+    size_t filename_len;
+    FILE * rc;
+    if ( mode == NULL )
+    {
+        /* Mode invalid */
+        return NULL;
+    }
+    /* To reduce the number of malloc calls, all data fields are concatenated:
+       * the FILE structure itself,
+       * ungetc buffer,
+       * filename buffer,
+       * data buffer.
+       Data buffer comes last because it might change in size ( setvbuf() ).
+    */
+    filename_len = filename ? strlen( filename ) + 1 : 1;
+    if ( ( rc = calloc( 1, sizeof( FILE ) + _PDCLIB_UNGETCBUFSIZE + filename_len + BUFSIZ ) ) == NULL )
+    {
+        /* no memory */
+        return NULL;
+    }
+
+    if(mtx_init(&rc->lock, mtx_recursive) != thrd_success) {
+        free(rc);
+        return NULL;
+    }
+
+    rc->status = mode;
+    rc->ops    = ops;
+    rc->handle = fd;
+    /* Setting pointers into the memory block allocated above */
+    rc->ungetbuf = (unsigned char *)rc + sizeof( FILE );
+    rc->filename = (char *)rc->ungetbuf + _PDCLIB_UNGETCBUFSIZE;
+    rc->buffer   = rc->filename + filename_len;
+    /* Copying filename to FILE structure */
+    if(filename) strcpy( rc->filename, filename );
+    /* Initializing the rest of the structure */
+    rc->bufsize = BUFSIZ;
+    rc->bufidx = 0;
+#ifdef _PDCLIB_NEED_EOL_TRANSLATION
+    rc->bufnlexp = 0;
+#endif
+    rc->ungetidx = 0;
+    /* Setting buffer to _IOLBF because "when opened, a stream is fully
+       buffered if and only if it can be determined not to refer to an
+       interactive device."
+    */
+    rc->status |= _IOLBF;
+    /* TODO: Setting mbstate */
+    /* Adding to list of open files */
+    rc->next = _PDCLIB_filelist;
+    _PDCLIB_filelist = rc;
+    return rc;
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    /* Some of the tests are not executed for regression tests, as the libc on
+       my system is at once less forgiving (segfaults on mode NULL) and more
+       forgiving (accepts undefined modes).
+    */
+    FILE * fh;
+    remove( testfile );
+    TESTCASE_NOREG( fopen( NULL, NULL ) == NULL );
+    TESTCASE( fopen( NULL, "w" ) == NULL );
+    TESTCASE_NOREG( fopen( "", NULL ) == NULL );
+    TESTCASE( fopen( "", "w" ) == NULL );
+    TESTCASE( fopen( "foo", "" ) == NULL );
+    TESTCASE_NOREG( fopen( testfile, "wq" ) == NULL ); /* Undefined mode */
+    TESTCASE_NOREG( fopen( testfile, "wr" ) == NULL ); /* Undefined mode */
+    TESTCASE( ( fh = fopen( testfile, "w" ) ) != NULL );
+    TESTCASE( fclose( fh ) == 0 );
+    TESTCASE( remove( testfile ) == 0 );
+    return TEST_RESULTS;
+}
+
+#endif
index f8dac3033704b3de365298ecba9f44904301913d..5d88a15cb9adb28ad083628eb029052a0f87929d 100644 (file)
@@ -1,41 +1,41 @@
-/* int64_t _PDCLIB_seek( FILE *, int64_t, int )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <stdio.h>\r
-#include <stdint.h>\r
-#include <errno.h>\r
-#ifndef REGTEST\r
-#include "_PDCLIB_io.h"\r
-\r
-int_fast64_t _PDCLIB_seek( FILE * stream, \r
-                           int_fast64_t offset, \r
-                           int whence )\r
-{\r
-    int_fast64_t newPos;\r
-    if(!stream->ops->seek(stream->handle, offset, whence, &newPos)) {\r
-        return EOF;\r
-    }\r
-\r
-    stream->ungetidx = 0;\r
-    stream->bufidx = 0;\r
-    stream->bufend = 0;\r
-    stream->pos.offset = newPos;\r
-    return newPos;\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    /* Testing covered by ftell.c */\r
-    return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
-\r
+/* int64_t _PDCLIB_seek( FILE *, int64_t, int )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <stdio.h>
+#include <stdint.h>
+#include <errno.h>
+#ifndef REGTEST
+#include "_PDCLIB_io.h"
+
+int_fast64_t _PDCLIB_seek( FILE * stream, 
+                           int_fast64_t offset, 
+                           int whence )
+{
+    int_fast64_t newPos;
+    if(!stream->ops->seek(stream->handle, offset, whence, &newPos)) {
+        return EOF;
+    }
+
+    stream->ungetidx = 0;
+    stream->bufidx = 0;
+    stream->bufend = 0;
+    stream->pos.offset = newPos;
+    return newPos;
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    /* Testing covered by ftell.c */
+    return TEST_RESULTS;
+}
+
+#endif
+
index c37699b91e2d5dcb516da7a011b09ae238cb8974..559f46abd33d47c94b082d336ba90140a8160af8 100644 (file)
@@ -1,33 +1,33 @@
-/* flockfile(FILE * )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <stdio.h>\r
-#include <stdarg.h>\r
-\r
-#ifndef REGTEST\r
-#include "_PDCLIB_io.h"\r
-#include <threads.h>\r
-#include <stdlib.h>\r
-\r
-void _PDCLIB_flockfile( FILE * file )\r
-{\r
-    if( mtx_lock( &file->lock ) != thrd_success ) {\r
-        abort();\r
-    }\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    // Not tested here - tested by other stdio test drivers\r
-    return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
+/* flockfile(FILE * )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#ifndef REGTEST
+#include "_PDCLIB_io.h"
+#include <threads.h>
+#include <stdlib.h>
+
+void _PDCLIB_flockfile( FILE * file )
+{
+    if( mtx_lock( &file->lock ) != thrd_success ) {
+        abort();
+    }
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    // Not tested here - tested by other stdio test drivers
+    return TEST_RESULTS;
+}
+
+#endif
index f377ec06cbd154f86d4905047f24290a34d996dc..efb67199bee0b7e86c38b365f954a5d48083e551 100644 (file)
@@ -1,40 +1,40 @@
-/* ftrylockfile( FILE * )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <stdio.h>\r
-#include <stdarg.h>\r
-\r
-#ifndef REGTEST\r
-#include "_PDCLIB_io.h"\r
-#include <threads.h>\r
-#include <stdlib.h>\r
-\r
-int _PDCLIB_ftrylockfile( FILE * file )\r
-{\r
-    int res = mtx_trylock( &file->lock );\r
-    switch(res) {\r
-        case thrd_success:\r
-            return 0;\r
-        case thrd_busy:\r
-            return 1;\r
-\r
-        default:\r
-            abort();\r
-    }\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    // Not tested here - tested by other stdio test drivers\r
-    return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
+/* ftrylockfile( FILE * )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#ifndef REGTEST
+#include "_PDCLIB_io.h"
+#include <threads.h>
+#include <stdlib.h>
+
+int _PDCLIB_ftrylockfile( FILE * file )
+{
+    int res = mtx_trylock( &file->lock );
+    switch(res) {
+        case thrd_success:
+            return 0;
+        case thrd_busy:
+            return 1;
+
+        default:
+            abort();
+    }
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    // Not tested here - tested by other stdio test drivers
+    return TEST_RESULTS;
+}
+
+#endif
index 4e9ed045f4c12df547721cd8f138f092888565cc..98a375c971d051273f8cb6ac3a88eb503ca1c105 100644 (file)
@@ -1,38 +1,38 @@
-/* funlockfile( FILE * )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <stdio.h>\r
-#include <stdarg.h>\r
-\r
-#ifndef REGTEST\r
-#include "_PDCLIB_io.h"\r
-#include <threads.h>\r
-#include <stdlib.h>\r
-\r
-void _PDCLIB_funlockfile( FILE * file )\r
-{\r
-    int res = mtx_unlock( &file->lock );\r
-    switch(res) {\r
-        case thrd_success:\r
-            return;\r
-\r
-        default:\r
-            abort();\r
-    }\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    // Not tested here - tested by other stdio test drivers\r
-    return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
+/* funlockfile( FILE * )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#ifndef REGTEST
+#include "_PDCLIB_io.h"
+#include <threads.h>
+#include <stdlib.h>
+
+void _PDCLIB_funlockfile( FILE * file )
+{
+    int res = mtx_unlock( &file->lock );
+    switch(res) {
+        case thrd_success:
+            return;
+
+        default:
+            abort();
+    }
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    // Not tested here - tested by other stdio test drivers
+    return TEST_RESULTS;
+}
+
+#endif
index bbd1e93be1c0485f6b61be1b312f4b09c0540d17..78dd01d4f645f3e49215fdd0b45f4cac794a62d3 100644 (file)
@@ -1,49 +1,49 @@
-/* [XSI] char * strdup( const char * )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#ifdef REGTEST\r
-#define _POSIX_C_SOURCE 200809L\r
-#endif\r
-\r
-#include <string.h>\r
-#include <stdlib.h>\r
-\r
-#ifndef REGTEST\r
-\r
-char *strdup(const char *s)\r
-{\r
-    char* ns = NULL;\r
-    if(s) {\r
-        size_t len = strlen(s) + 1;\r
-        ns = malloc(len);\r
-        if(ns)\r
-            strncpy(ns, s, len);\r
-    }\r
-    return ns;\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    const char *teststr  = "Hello, world";\r
-    const char *teststr2 = "An alternative test string with non-7-bit characters \xFE\x8C\n";\r
-    char *testres, *testres2;\r
-\r
-    TESTCASE((testres  = strdup(teststr)) != NULL);\r
-    TESTCASE((testres2 = strdup(teststr2)) != NULL);\r
-    TESTCASE(strcmp(testres, teststr) == 0);\r
-    TESTCASE(strcmp(testres2, teststr2) == 0);\r
-    free(testres);\r
-    free(testres2);\r
-\r
-    return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
+/* [XSI] char * strdup( const char * )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#ifdef REGTEST
+#define _POSIX_C_SOURCE 200809L
+#endif
+
+#include <string.h>
+#include <stdlib.h>
+
+#ifndef REGTEST
+
+char *strdup(const char *s)
+{
+    char* ns = NULL;
+    if(s) {
+        size_t len = strlen(s) + 1;
+        ns = malloc(len);
+        if(ns)
+            strncpy(ns, s, len);
+    }
+    return ns;
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    const char *teststr  = "Hello, world";
+    const char *teststr2 = "An alternative test string with non-7-bit characters \xFE\x8C\n";
+    char *testres, *testres2;
+
+    TESTCASE((testres  = strdup(teststr)) != NULL);
+    TESTCASE((testres2 = strdup(teststr2)) != NULL);
+    TESTCASE(strcmp(testres, teststr) == 0);
+    TESTCASE(strcmp(testres2, teststr2) == 0);
+    free(testres);
+    free(testres2);
+
+    return TEST_RESULTS;
+}
+
+#endif
index 446fb5d6a6ac87e0fc9aeed516a27ae81931ac3b..b7baca2cc506895abd974618c6b50c0fb4e7087f 100644 (file)
@@ -1,63 +1,63 @@
-/* [XSI] char * strndup( const char *, size_t )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#ifdef REGTEST\r
-#define _POSIX_C_SOURCE 200809L\r
-#endif\r
-\r
-#include <string.h>\r
-#include <stdlib.h>\r
-\r
-#ifndef REGTEST\r
-\r
-char *strndup( const char * s, size_t len )\r
-{\r
-    char* ns = NULL;\r
-    if(s) {\r
-        ns = malloc(len + 1);\r
-        if(ns) {\r
-            ns[len] = 0;\r
-            // strncpy to be pedantic about modification in multithreaded \r
-            // applications\r
-            return strncpy(ns, s, len);\r
-        }\r
-    }\r
-    return ns;\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-#ifndef REGTEST\r
-    /* Missing on Windows. Maybe use conditionals? */\r
-    const char *teststr  = "Hello, world";\r
-    const char *teststr2 = "\xFE\x8C\n";\r
-    char *testres, *testres2;\r
-\r
-    TESTCASE((testres  = strndup(teststr, 5)) != NULL);\r
-    TESTCASE((testres2 = strndup(teststr2, 1)) != NULL);\r
-    TESTCASE(strcmp(testres, teststr) != 0);\r
-    TESTCASE(strncmp(testres, teststr, 5) == 0);\r
-    TESTCASE(strcmp(testres2, teststr2) != 0);\r
-    TESTCASE(strncmp(testres2, teststr2, 1) == 0);\r
-    free(testres);\r
-    free(testres2);\r
-    TESTCASE((testres  = strndup(teststr, 20)) != NULL);\r
-    TESTCASE((testres2 = strndup(teststr2, 5)) != NULL);\r
-    TESTCASE(strcmp(testres, teststr) == 0);\r
-    TESTCASE(strcmp(testres2, teststr2) == 0);\r
-    free(testres);\r
-    free(testres2);\r
-#endif\r
-\r
-    return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
+/* [XSI] char * strndup( const char *, size_t )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#ifdef REGTEST
+#define _POSIX_C_SOURCE 200809L
+#endif
+
+#include <string.h>
+#include <stdlib.h>
+
+#ifndef REGTEST
+
+char *strndup( const char * s, size_t len )
+{
+    char* ns = NULL;
+    if(s) {
+        ns = malloc(len + 1);
+        if(ns) {
+            ns[len] = 0;
+            // strncpy to be pedantic about modification in multithreaded 
+            // applications
+            return strncpy(ns, s, len);
+        }
+    }
+    return ns;
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+#ifndef REGTEST
+    /* Missing on Windows. Maybe use conditionals? */
+    const char *teststr  = "Hello, world";
+    const char *teststr2 = "\xFE\x8C\n";
+    char *testres, *testres2;
+
+    TESTCASE((testres  = strndup(teststr, 5)) != NULL);
+    TESTCASE((testres2 = strndup(teststr2, 1)) != NULL);
+    TESTCASE(strcmp(testres, teststr) != 0);
+    TESTCASE(strncmp(testres, teststr, 5) == 0);
+    TESTCASE(strcmp(testres2, teststr2) != 0);
+    TESTCASE(strncmp(testres2, teststr2, 1) == 0);
+    free(testres);
+    free(testres2);
+    TESTCASE((testres  = strndup(teststr, 20)) != NULL);
+    TESTCASE((testres2 = strndup(teststr2, 5)) != NULL);
+    TESTCASE(strcmp(testres, teststr) == 0);
+    TESTCASE(strcmp(testres2, teststr2) == 0);
+    free(testres);
+    free(testres2);
+#endif
+
+    return TEST_RESULTS;
+}
+
+#endif
index a4b5a9eadf134301a286bf4652b1e1537e5b5164..915fa76c0747cbe030b8c0d58dc275df4fe46a9b 100644 (file)
@@ -1,36 +1,36 @@
-/* strnlen( const char *, size_t len )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <string.h>\r
-#include <stdint.h>\r
-\r
-#ifndef REGTEST\r
-\r
-size_t strnlen( const char * s, size_t maxlen )\r
-{\r
-    for( size_t len = 0; len != maxlen; len++ )\r
-    {\r
-        if(s[len] == '\0')\r
-            return len;\r
-    }\r
-    return maxlen;\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-#ifndef REGTEST\r
-    TESTCASE( strnlen( abcde, 5 ) == 5 );\r
-    TESTCASE( strnlen( abcde, 3 ) == 3 )\r
-    TESTCASE( strnlen( "", SIZE_MAX ) == 0 );\r
-#endif\r
-    return TEST_RESULTS;\r
-}\r
-#endif\r
+/* strnlen( const char *, size_t len )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <string.h>
+#include <stdint.h>
+
+#ifndef REGTEST
+
+size_t strnlen( const char * s, size_t maxlen )
+{
+    for( size_t len = 0; len != maxlen; len++ )
+    {
+        if(s[len] == '\0')
+            return len;
+    }
+    return maxlen;
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+#ifndef REGTEST
+    TESTCASE( strnlen( abcde, 5 ) == 5 );
+    TESTCASE( strnlen( abcde, 3 ) == 3 )
+    TESTCASE( strnlen( "", SIZE_MAX ) == 0 );
+#endif
+    return TEST_RESULTS;
+}
+#endif
index bce172bd00ff070a5095d33747ff273d56b8021b..5070e28f86b5b004a34062a1c7d6300f2834d405 100644 (file)
-/* c16rtomb( char *, char16_t, mbstate_t * )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#ifndef REGTEST\r
-#include <uchar.h>\r
-#include <errno.h>\r
-#include <stdint.h>\r
-#include <assert.h>\r
-#include <stdlib.h>\r
-#include "_PDCLIB_encoding.h"\r
-#include "_PDCLIB_locale.h"\r
-\r
-size_t c16rtomb_l(\r
-    char        *restrict   s, \r
-    char16_t                c16,\r
-    mbstate_t   *restrict   ps,\r
-    locale_t     restrict   l\r
-)\r
-{\r
-    const char16_t *restrict psrc = &c16;\r
-    char buf[s ? 0 : MB_CUR_MAX];\r
-    s =      s ? s : buf;\r
-\r
-    if(!l->_Codec->__c16stombs) {\r
-        // Codec doesn't support direct conversion - translate via UCS-4\r
-        if(ps->_Surrogate == 0) {\r
-            // No pending surrogate\r
-            if((c16 & 0xF800) == 0xD800) {\r
-                // Surrogate range\r
-                if((c16 & 0x0400) == 0) {\r
-                    // 0xD800 -> 0xDBFF leading surrogate\r
-                    ps->_Surrogate = c16;\r
-\r
-                    // Need more data\r
-                    // Return 0 - we haven't output anything yet\r
-\r
-                    /* STD: ISO/IEC 9899:2011 is very implcifit about this being\r
-                     *      the correct return value. N1040, from which the \r
-                     *      function was adopted, is explicit about 0 being a \r
-                     *      valid return.\r
-                     */\r
-                    return (size_t) 0;\r
-                } else {\r
-                    // 0xDC00 -> 0xDFFF trailing surrogate\r
-                    errno = EILSEQ;\r
-                    return (size_t) -1;\r
-                }\r
-            } else {\r
-                // BMP range - UTF16 == UCS-4, pass through to c32rtomb_l\r
-                return c32rtomb_l(s, c16, ps, l);\r
-            }\r
-        } else {\r
-            // We have a stored surrogate\r
-            if((c16 & 0xFC00) == 0xDC00) {\r
-                // Trailing surrogate\r
-                char32_t c32 = (ps->_Surrogate & 0x3FF) << 10 | (c16 & 0x3FF);\r
-                ps->_Surrogate = 0;\r
-                return c32rtomb_l(s, c32, ps, l);\r
-            } else {\r
-                // Not a trailing surrogate - encoding error\r
-                errno = EILSEQ;\r
-                return (size_t) -1;\r
-            }\r
-\r
-        }\r
-    } else {\r
-        // Codec supports direct conversion\r
-        size_t srcsz  = 1;\r
-        size_t dstsz  = MB_CUR_MAX;\r
-        size_t dstrem = dstsz;\r
-\r
-        if(l->_Codec->__c16stombs(&s, &dstrem, &psrc, &srcsz, ps)) {\r
-            // Successful conversion\r
-            return dstsz - dstrem;\r
-        } else {\r
-            errno = EILSEQ;\r
-            return (size_t) -1;\r
-        }\r
-    }\r
-}\r
-\r
-size_t c16rtomb(\r
-    char        *restrict   s, \r
-    char16_t                c16,\r
-    mbstate_t   *restrict   ps\r
-)\r
-{\r
-    return c16rtomb_l(s, c16, ps, _PDCLIB_threadlocale());\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    TESTCASE( NO_TESTDRIVER );\r
-    return TEST_RESULTS;\r
-}\r
-#endif\r
+/* c16rtomb( char *, char16_t, mbstate_t * )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#ifndef REGTEST
+#include <uchar.h>
+#include <errno.h>
+#include <stdint.h>
+#include <assert.h>
+#include <stdlib.h>
+#include "_PDCLIB_encoding.h"
+#include "_PDCLIB_locale.h"
+
+size_t c16rtomb_l(
+    char        *restrict   s, 
+    char16_t                c16,
+    mbstate_t   *restrict   ps,
+    locale_t     restrict   l
+)
+{
+    const char16_t *restrict psrc = &c16;
+    char buf[s ? 0 : MB_CUR_MAX];
+    s =      s ? s : buf;
+
+    if(!l->_Codec->__c16stombs) {
+        // Codec doesn't support direct conversion - translate via UCS-4
+        if(ps->_Surrogate == 0) {
+            // No pending surrogate
+            if((c16 & 0xF800) == 0xD800) {
+                // Surrogate range
+                if((c16 & 0x0400) == 0) {
+                    // 0xD800 -> 0xDBFF leading surrogate
+                    ps->_Surrogate = c16;
+
+                    // Need more data
+                    // Return 0 - we haven't output anything yet
+
+                    /* STD: ISO/IEC 9899:2011 is very implcifit about this being
+                     *      the correct return value. N1040, from which the 
+                     *      function was adopted, is explicit about 0 being a 
+                     *      valid return.
+                     */
+                    return (size_t) 0;
+                } else {
+                    // 0xDC00 -> 0xDFFF trailing surrogate
+                    errno = EILSEQ;
+                    return (size_t) -1;
+                }
+            } else {
+                // BMP range - UTF16 == UCS-4, pass through to c32rtomb_l
+                return c32rtomb_l(s, c16, ps, l);
+            }
+        } else {
+            // We have a stored surrogate
+            if((c16 & 0xFC00) == 0xDC00) {
+                // Trailing surrogate
+                char32_t c32 = (ps->_Surrogate & 0x3FF) << 10 | (c16 & 0x3FF);
+                ps->_Surrogate = 0;
+                return c32rtomb_l(s, c32, ps, l);
+            } else {
+                // Not a trailing surrogate - encoding error
+                errno = EILSEQ;
+                return (size_t) -1;
+            }
+
+        }
+    } else {
+        // Codec supports direct conversion
+        size_t srcsz  = 1;
+        size_t dstsz  = MB_CUR_MAX;
+        size_t dstrem = dstsz;
+
+        if(l->_Codec->__c16stombs(&s, &dstrem, &psrc, &srcsz, ps)) {
+            // Successful conversion
+            return dstsz - dstrem;
+        } else {
+            errno = EILSEQ;
+            return (size_t) -1;
+        }
+    }
+}
+
+size_t c16rtomb(
+    char        *restrict   s, 
+    char16_t                c16,
+    mbstate_t   *restrict   ps
+)
+{
+    return c16rtomb_l(s, c16, ps, _PDCLIB_threadlocale());
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    TESTCASE( NO_TESTDRIVER );
+    return TEST_RESULTS;
+}
+#endif
index 93c35fd287d94ef733aceb7e668d36d26ee41346..c44c165c9f4372cb471cd8eabec8b184444967cf 100644 (file)
@@ -1,95 +1,95 @@
-/* size_t mbrtoc16( char16_t *, const char *, size_t, mbstate_t * )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#ifndef REGTEST\r
-#include <uchar.h>\r
-#include <errno.h>\r
-#include <stdint.h>\r
-#include <assert.h>\r
-#include "_PDCLIB_encoding.h"\r
-#include "_PDCLIB_locale.h"\r
-\r
-size_t mbrtoc16_l(\r
-    char16_t    *restrict   pc16,\r
-    const char  *restrict   s, \r
-    size_t                  n,\r
-    mbstate_t   *restrict   ps,\r
-    locale_t     restrict   l\r
-)\r
-{\r
-    size_t dstlen = 1;\r
-    size_t nr = n;\r
-\r
-    if(!l->_Codec->__mbstoc16s) {\r
-        // No UTF-16 support in codec. Must synthesize on top of UCS-4 support.\r
-\r
-        if(ps->_Surrogate) {\r
-            // If a pending surrogate is stored in the state\r
-            *pc16 = ps->_Surrogate;\r
-            ps->_Surrogate = 0;\r
-            return (size_t) -3;\r
-        }\r
-\r
-        char32_t c32;\r
-        size_t res = mbrtoc32_l(&c32, s, n, ps, l);\r
-        if(res != (size_t) -1) {\r
-            // Conversion was successful. Check for surrogates\r
-            if(c32 <= 0xFFFF) {\r
-                // BMP char\r
-                *pc16 = c32;\r
-            } else {\r
-                // Supplementary char\r
-                *pc16 = 0xD800 | (c32 >> 10);\r
-                ps->_Surrogate = 0xDC00 | (c32 & 0x3FF);\r
-            }\r
-        }\r
-        return res;\r
-    } else if(l->_Codec->__mbstoc16s(&pc16, &dstlen, &s, &nr, ps)) {\r
-        // Successful conversion\r
-        if(dstlen == 0) {\r
-            // A character was output\r
-            if(nr == n) {\r
-                // The output character resulted entirely from stored state\r
-                return (size_t) -3;\r
-            } else if(pc16[-1] == 0) {\r
-                // Was null character\r
-                return 0;\r
-            } else {\r
-                // Count of processed characters\r
-                return n - nr;\r
-            }\r
-        } else {\r
-            assert(nr == 0 && "Must have processed whole input");\r
-            return (size_t) -2;\r
-        }\r
-    } else {\r
-        // Failed conversion\r
-        errno = EILSEQ;\r
-        return (size_t) -1;\r
-    }\r
-}\r
-\r
-size_t mbrtoc16(\r
-    char16_t    *restrict   pc16,\r
-    const char  *restrict   s, \r
-    size_t                  n,\r
-    mbstate_t   *restrict   ps\r
-)\r
-{\r
-    return mbrtoc16_l(pc16, s, n, ps, _PDCLIB_threadlocale());\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    TESTCASE( NO_TESTDRIVER );\r
-    return TEST_RESULTS;\r
-}\r
-#endif\r
+/* size_t mbrtoc16( char16_t *, const char *, size_t, mbstate_t * )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#ifndef REGTEST
+#include <uchar.h>
+#include <errno.h>
+#include <stdint.h>
+#include <assert.h>
+#include "_PDCLIB_encoding.h"
+#include "_PDCLIB_locale.h"
+
+size_t mbrtoc16_l(
+    char16_t    *restrict   pc16,
+    const char  *restrict   s, 
+    size_t                  n,
+    mbstate_t   *restrict   ps,
+    locale_t     restrict   l
+)
+{
+    size_t dstlen = 1;
+    size_t nr = n;
+
+    if(!l->_Codec->__mbstoc16s) {
+        // No UTF-16 support in codec. Must synthesize on top of UCS-4 support.
+
+        if(ps->_Surrogate) {
+            // If a pending surrogate is stored in the state
+            *pc16 = ps->_Surrogate;
+            ps->_Surrogate = 0;
+            return (size_t) -3;
+        }
+
+        char32_t c32;
+        size_t res = mbrtoc32_l(&c32, s, n, ps, l);
+        if(res != (size_t) -1) {
+            // Conversion was successful. Check for surrogates
+            if(c32 <= 0xFFFF) {
+                // BMP char
+                *pc16 = c32;
+            } else {
+                // Supplementary char
+                *pc16 = 0xD800 | (c32 >> 10);
+                ps->_Surrogate = 0xDC00 | (c32 & 0x3FF);
+            }
+        }
+        return res;
+    } else if(l->_Codec->__mbstoc16s(&pc16, &dstlen, &s, &nr, ps)) {
+        // Successful conversion
+        if(dstlen == 0) {
+            // A character was output
+            if(nr == n) {
+                // The output character resulted entirely from stored state
+                return (size_t) -3;
+            } else if(pc16[-1] == 0) {
+                // Was null character
+                return 0;
+            } else {
+                // Count of processed characters
+                return n - nr;
+            }
+        } else {
+            assert(nr == 0 && "Must have processed whole input");
+            return (size_t) -2;
+        }
+    } else {
+        // Failed conversion
+        errno = EILSEQ;
+        return (size_t) -1;
+    }
+}
+
+size_t mbrtoc16(
+    char16_t    *restrict   pc16,
+    const char  *restrict   s, 
+    size_t                  n,
+    mbstate_t   *restrict   ps
+)
+{
+    return mbrtoc16_l(pc16, s, n, ps, _PDCLIB_threadlocale());
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    TESTCASE( NO_TESTDRIVER );
+    return TEST_RESULTS;
+}
+#endif
index f78ae4ce4374132ebc08bb9340dee2e8a7274365..0e6d7d3264ef724894a2cc36723afcada7829e75 100644 (file)
@@ -1,53 +1,53 @@
-/* mbsinit( mbstate_t * ps )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <wchar.h>\r
-#ifndef REGTEST\r
-#include "_PDCLIB_encoding.h"\r
-#include "_PDCLIB_locale.h"\r
-\r
-static int _PDCLIB_mbsinit_l( const mbstate_t *ps, locale_t l )\r
-{\r
-    if( ps ) {\r
-        return ps->_Surrogate == 0\r
-            && ps->_PendState == 0\r
-            && l->_Codec->__mbsinit(ps);\r
-    } else return 1;\r
-}\r
-\r
-int mbsinit( const mbstate_t * ps )\r
-{\r
-    return _PDCLIB_mbsinit_l(ps, _PDCLIB_threadlocale());\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    mbstate_t mbs;\r
-    memset(&mbs, 0, sizeof mbs);\r
-\r
-    TESTCASE(mbsinit(NULL) != 0);\r
-    TESTCASE(mbsinit(&mbs) != 0);\r
-\r
-#ifndef REGTEST\r
-    // Surrogate pending\r
-    mbs._Surrogate = 0xFEED;\r
-    TESTCASE(mbsinit(&mbs) == 0);\r
-\r
-    mbs._Surrogate = 0;\r
-    mbs._PendState = 1;\r
-    TESTCASE(mbsinit(&mbs) == 0);\r
-#endif\r
-    return TEST_RESULTS;\r
-}\r
-#endif\r
-\r
-\r
-\r
+/* mbsinit( mbstate_t * ps )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <wchar.h>
+#ifndef REGTEST
+#include "_PDCLIB_encoding.h"
+#include "_PDCLIB_locale.h"
+
+static int _PDCLIB_mbsinit_l( const mbstate_t *ps, locale_t l )
+{
+    if( ps ) {
+        return ps->_Surrogate == 0
+            && ps->_PendState == 0
+            && l->_Codec->__mbsinit(ps);
+    } else return 1;
+}
+
+int mbsinit( const mbstate_t * ps )
+{
+    return _PDCLIB_mbsinit_l(ps, _PDCLIB_threadlocale());
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    mbstate_t mbs;
+    memset(&mbs, 0, sizeof mbs);
+
+    TESTCASE(mbsinit(NULL) != 0);
+    TESTCASE(mbsinit(&mbs) != 0);
+
+#ifndef REGTEST
+    // Surrogate pending
+    mbs._Surrogate = 0xFEED;
+    TESTCASE(mbsinit(&mbs) == 0);
+
+    mbs._Surrogate = 0;
+    mbs._PendState = 1;
+    TESTCASE(mbsinit(&mbs) == 0);
+#endif
+    return TEST_RESULTS;
+}
+#endif
+
+
+
index 22a04c57935d567773b2ef10de7a79dfdc5c6fd0..c467af0ef04819bc7c556396e449e82f82abe10f 100644 (file)
@@ -1,45 +1,45 @@
-/* wcscat( wchar_t *, const wchar_t * )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <wchar.h>\r
-\r
-#ifndef REGTEST\r
-\r
-wchar_t * wcscat( wchar_t * _PDCLIB_restrict s1, \r
-                  const wchar_t * _PDCLIB_restrict s2 )\r
-{\r
-    wchar_t * rc = s1;\r
-    if ( *s1 )\r
-    {\r
-        while ( *++s1 );\r
-    }\r
-    while ( (*s1++ = *s2++) );\r
-    return rc;\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    wchar_t s[] = L"xx\0xxxxxx";\r
-    TESTCASE( wcscat( s, wabcde ) == s );\r
-    TESTCASE( s[2] == L'a' );\r
-    TESTCASE( s[6] == L'e' );\r
-    TESTCASE( s[7] == L'\0' );\r
-    TESTCASE( s[8] == L'x' );\r
-    s[0] = L'\0';\r
-    TESTCASE( wcscat( s, wabcdx ) == s );\r
-    TESTCASE( s[4] == L'x' );\r
-    TESTCASE( s[5] == L'\0' );\r
-    TESTCASE( wcscat( s, L"\0" ) == s );\r
-    TESTCASE( s[5] == L'\0' );\r
-    TESTCASE( s[6] == L'e' );\r
-    return TEST_RESULTS;\r
-}\r
-#endif\r
+/* wcscat( wchar_t *, const wchar_t * )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <wchar.h>
+
+#ifndef REGTEST
+
+wchar_t * wcscat( wchar_t * _PDCLIB_restrict s1, 
+                  const wchar_t * _PDCLIB_restrict s2 )
+{
+    wchar_t * rc = s1;
+    if ( *s1 )
+    {
+        while ( *++s1 );
+    }
+    while ( (*s1++ = *s2++) );
+    return rc;
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    wchar_t s[] = L"xx\0xxxxxx";
+    TESTCASE( wcscat( s, wabcde ) == s );
+    TESTCASE( s[2] == L'a' );
+    TESTCASE( s[6] == L'e' );
+    TESTCASE( s[7] == L'\0' );
+    TESTCASE( s[8] == L'x' );
+    s[0] = L'\0';
+    TESTCASE( wcscat( s, wabcdx ) == s );
+    TESTCASE( s[4] == L'x' );
+    TESTCASE( s[5] == L'\0' );
+    TESTCASE( wcscat( s, L"\0" ) == s );
+    TESTCASE( s[5] == L'\0' );
+    TESTCASE( s[6] == L'e' );
+    return TEST_RESULTS;
+}
+#endif
index 0dffcaab138f3dfc6616ea69cc8ec8f1e3d6063c..5629aa6fdc1e70fd0df0a4d64ad775f26851ca2d 100644 (file)
@@ -1,32 +1,32 @@
-/* wcschr( const wchar_t *, wchar_t );\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <wchar.h>\r
-#include <stddef.h>\r
-\r
-#ifndef REGTEST\r
-\r
-wchar_t *wcschr(const wchar_t * haystack, wchar_t needle)\r
-{\r
-    while(*haystack) {\r
-        if(*haystack == needle) return (wchar_t*) haystack;\r
-        haystack++;\r
-    }\r
-    return NULL;\r
-}\r
-\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
+/* wcschr( const wchar_t *, wchar_t );
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <wchar.h>
+#include <stddef.h>
+
+#ifndef REGTEST
+
+wchar_t *wcschr(const wchar_t * haystack, wchar_t needle)
+{
+    while(*haystack) {
+        if(*haystack == needle) return (wchar_t*) haystack;
+        haystack++;
+    }
+    return NULL;
+}
+
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    return TEST_RESULTS;
+}
+
+#endif
index 8a3d22782312a77d75bf6312377738c5322bb944..b338b5d30b2ba3fe05b2345c2bde945426055672 100644 (file)
@@ -1,39 +1,39 @@
-/* wcscmp( const wchar_t *, const wchar_t * )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <wchar.h>\r
-\r
-#ifndef REGTEST\r
-\r
-int wcscmp( const wchar_t * s1, const wchar_t * s2 )\r
-{\r
-    while ( ( *s1 ) && ( *s1 == *s2 ) )\r
-    {\r
-        ++s1;\r
-        ++s2;\r
-    }\r
-    return ( *(wchar_t *)s1 - *(wchar_t *)s2 );\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    wchar_t cmpabcde[] = L"abcde";\r
-    wchar_t cmpabcd_[] = L"abcd\xfc";\r
-    wchar_t empty[] = L"";\r
-    TESTCASE( wcscmp( wabcde, cmpabcde ) == 0 );\r
-    TESTCASE( wcscmp( wabcde, wabcdx ) < 0 );\r
-    TESTCASE( wcscmp( wabcdx, wabcde ) > 0 );\r
-    TESTCASE( wcscmp( empty, wabcde ) < 0 );\r
-    TESTCASE( wcscmp( wabcde, empty ) > 0 );\r
-    TESTCASE( wcscmp( wabcde, cmpabcd_ ) < 0 );\r
-    return TEST_RESULTS;\r
-}\r
-#endif\r
+/* wcscmp( const wchar_t *, const wchar_t * )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <wchar.h>
+
+#ifndef REGTEST
+
+int wcscmp( const wchar_t * s1, const wchar_t * s2 )
+{
+    while ( ( *s1 ) && ( *s1 == *s2 ) )
+    {
+        ++s1;
+        ++s2;
+    }
+    return ( *(wchar_t *)s1 - *(wchar_t *)s2 );
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    wchar_t cmpabcde[] = L"abcde";
+    wchar_t cmpabcd_[] = L"abcd\xfc";
+    wchar_t empty[] = L"";
+    TESTCASE( wcscmp( wabcde, cmpabcde ) == 0 );
+    TESTCASE( wcscmp( wabcde, wabcdx ) < 0 );
+    TESTCASE( wcscmp( wabcdx, wabcde ) > 0 );
+    TESTCASE( wcscmp( empty, wabcde ) < 0 );
+    TESTCASE( wcscmp( wabcde, empty ) > 0 );
+    TESTCASE( wcscmp( wabcde, cmpabcd_ ) < 0 );
+    return TEST_RESULTS;
+}
+#endif
index f52041ffbc6f3877fc507b139d6fd0ce27e7828b..62a52663a5f79d2e2183ab6e336ed51db54b9b9f 100644 (file)
@@ -1,33 +1,33 @@
-/* wchar_t * wcscpy( wchar_t *, const wchar_t * );\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <wchar.h>\r
-\r
-#ifndef REGTEST\r
-\r
-wchar_t *wcscpy( wchar_t * _PDCLIB_restrict dest, \r
-                 const wchar_t * _PDCLIB_restrict src)\r
-{\r
-    wchar_t * rv = dest;\r
-    while(*src) {\r
-        *(dest++) = *(src++);\r
-    }\r
-\r
-    return rv;\r
-}\r
-\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
+/* wchar_t * wcscpy( wchar_t *, const wchar_t * );
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <wchar.h>
+
+#ifndef REGTEST
+
+wchar_t *wcscpy( wchar_t * _PDCLIB_restrict dest, 
+                 const wchar_t * _PDCLIB_restrict src)
+{
+    wchar_t * rv = dest;
+    while(*src) {
+        *(dest++) = *(src++);
+    }
+
+    return rv;
+}
+
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    return TEST_RESULTS;
+}
+
+#endif
index 853b06a698f4ef0ae2457fa52543acb276eaed09..248c20072ba5bed9c23426f69debce64212e76fe 100644 (file)
@@ -1,48 +1,48 @@
-/* wcscspn( const wchar_t *, const wchar_t * )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <wchar.h>\r
-\r
-#ifndef REGTEST\r
-\r
-size_t wcscspn( const wchar_t * s1, const wchar_t * s2 )\r
-{\r
-    size_t len = 0;\r
-    const wchar_t * p;\r
-    while ( s1[len] )\r
-    {\r
-        p = s2;\r
-        while ( *p )\r
-        {\r
-            if ( s1[len] == *p++ )\r
-            {\r
-                return len;\r
-            }\r
-        }\r
-        ++len;\r
-    }\r
-    return len;\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    TESTCASE( wcscspn( wabcde, L"x" ) == 5 );\r
-    TESTCASE( wcscspn( wabcde, L"xyz" ) == 5 );\r
-    TESTCASE( wcscspn( wabcde, L"zyx" ) == 5 );\r
-    TESTCASE( wcscspn( wabcdx, L"x" ) == 4 );\r
-    TESTCASE( wcscspn( wabcdx, L"xyz" ) == 4 );\r
-    TESTCASE( wcscspn( wabcdx, L"zyx" ) == 4 );\r
-    TESTCASE( wcscspn( wabcde, L"a" ) == 0 );\r
-    TESTCASE( wcscspn( wabcde, L"abc" ) == 0 );\r
-    TESTCASE( wcscspn( wabcde, L"cba" ) == 0 );\r
-    return TEST_RESULTS;\r
-}\r
-#endif\r
+/* wcscspn( const wchar_t *, const wchar_t * )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <wchar.h>
+
+#ifndef REGTEST
+
+size_t wcscspn( const wchar_t * s1, const wchar_t * s2 )
+{
+    size_t len = 0;
+    const wchar_t * p;
+    while ( s1[len] )
+    {
+        p = s2;
+        while ( *p )
+        {
+            if ( s1[len] == *p++ )
+            {
+                return len;
+            }
+        }
+        ++len;
+    }
+    return len;
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    TESTCASE( wcscspn( wabcde, L"x" ) == 5 );
+    TESTCASE( wcscspn( wabcde, L"xyz" ) == 5 );
+    TESTCASE( wcscspn( wabcde, L"zyx" ) == 5 );
+    TESTCASE( wcscspn( wabcdx, L"x" ) == 4 );
+    TESTCASE( wcscspn( wabcdx, L"xyz" ) == 4 );
+    TESTCASE( wcscspn( wabcdx, L"zyx" ) == 4 );
+    TESTCASE( wcscspn( wabcde, L"a" ) == 0 );
+    TESTCASE( wcscspn( wabcde, L"abc" ) == 0 );
+    TESTCASE( wcscspn( wabcde, L"cba" ) == 0 );
+    return TEST_RESULTS;
+}
+#endif
index 1ae9fe4f9f1adbcedd470a7676be4478d1120a9c..00e3ca55008155e869e3ca9d418f3afede1878a1 100644 (file)
@@ -1,29 +1,29 @@
-/* wcslen( const wchar_t * );\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <wchar.h>\r
-\r
-#ifndef REGTEST\r
-\r
-size_t wcslen( const wchar_t * str )\r
-{\r
-    size_t n = 0;\r
-    while(*(str++)) n++;\r
-    return n;\r
-}\r
-\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
+/* wcslen( const wchar_t * );
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <wchar.h>
+
+#ifndef REGTEST
+
+size_t wcslen( const wchar_t * str )
+{
+    size_t n = 0;
+    while(*(str++)) n++;
+    return n;
+}
+
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    return TEST_RESULTS;
+}
+
+#endif
index b240009612f4ea1dd793bd955476c0aa5460c4aa..633e54df6473e6aeb2adb3709888326b4daf5893 100644 (file)
@@ -1,60 +1,60 @@
-/* wcsncat( wchar_t *, const wchar_t *, size_t )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <wchar.h>\r
-\r
-#ifndef REGTEST\r
-\r
-wchar_t * wcsncat( wchar_t * _PDCLIB_restrict s1, \r
-                   const wchar_t * _PDCLIB_restrict s2, \r
-                   size_t n )\r
-{\r
-    wchar_t * rc = s1;\r
-    while ( *s1 )\r
-    {\r
-        ++s1;\r
-    }\r
-    while ( n && ( *s1++ = *s2++ ) )\r
-    {\r
-        --n;\r
-    }\r
-    if ( n == 0 )\r
-    {\r
-        *s1 = '\0';\r
-    }\r
-    return rc;\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    wchar_t s[] = L"xx\0xxxxxx";\r
-    TESTCASE( wcsncat( s, wabcde, 10 ) == s );\r
-    TESTCASE( s[2] == L'a' );\r
-    TESTCASE( s[6] == L'e' );\r
-    TESTCASE( s[7] == L'\0' );\r
-    TESTCASE( s[8] == L'x' );\r
-    s[0] = L'\0';\r
-    TESTCASE( wcsncat( s, wabcdx, 10 ) == s );\r
-    TESTCASE( s[4] == L'x' );\r
-    TESTCASE( s[5] == L'\0' );\r
-    TESTCASE( wcsncat( s, L"\0", 10 ) == s );\r
-    TESTCASE( s[5] == L'\0' );\r
-    TESTCASE( s[6] == L'e' );\r
-    TESTCASE( wcsncat( s, wabcde, 0 ) == s );\r
-    TESTCASE( s[5] == L'\0' );\r
-    TESTCASE( s[6] == L'e' );\r
-    TESTCASE( wcsncat( s, wabcde, 3 ) == s );\r
-    TESTCASE( s[5] == L'a' );\r
-    TESTCASE( s[7] == L'c' );\r
-    TESTCASE( s[8] == L'\0' );\r
-    return TEST_RESULTS;\r
-}\r
-#endif\r
+/* wcsncat( wchar_t *, const wchar_t *, size_t )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <wchar.h>
+
+#ifndef REGTEST
+
+wchar_t * wcsncat( wchar_t * _PDCLIB_restrict s1, 
+                   const wchar_t * _PDCLIB_restrict s2, 
+                   size_t n )
+{
+    wchar_t * rc = s1;
+    while ( *s1 )
+    {
+        ++s1;
+    }
+    while ( n && ( *s1++ = *s2++ ) )
+    {
+        --n;
+    }
+    if ( n == 0 )
+    {
+        *s1 = '\0';
+    }
+    return rc;
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    wchar_t s[] = L"xx\0xxxxxx";
+    TESTCASE( wcsncat( s, wabcde, 10 ) == s );
+    TESTCASE( s[2] == L'a' );
+    TESTCASE( s[6] == L'e' );
+    TESTCASE( s[7] == L'\0' );
+    TESTCASE( s[8] == L'x' );
+    s[0] = L'\0';
+    TESTCASE( wcsncat( s, wabcdx, 10 ) == s );
+    TESTCASE( s[4] == L'x' );
+    TESTCASE( s[5] == L'\0' );
+    TESTCASE( wcsncat( s, L"\0", 10 ) == s );
+    TESTCASE( s[5] == L'\0' );
+    TESTCASE( s[6] == L'e' );
+    TESTCASE( wcsncat( s, wabcde, 0 ) == s );
+    TESTCASE( s[5] == L'\0' );
+    TESTCASE( s[6] == L'e' );
+    TESTCASE( wcsncat( s, wabcde, 3 ) == s );
+    TESTCASE( s[5] == L'a' );
+    TESTCASE( s[7] == L'c' );
+    TESTCASE( s[8] == L'\0' );
+    return TEST_RESULTS;
+}
+#endif
index 7197c060b75892c849d9c44d411f5ea8560f617c..d857d7c3af3ccc1c704023db8e0c7fbc203838e6 100644 (file)
@@ -1,52 +1,52 @@
-/* wcsncmp( const wchar_t *, const wchar_t *, size_t )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <wchar.h>\r
-\r
-#ifndef REGTEST\r
-\r
-int wcsncmp( const wchar_t * s1, const wchar_t * s2, size_t n )\r
-{\r
-    while ( *s1 && n && ( *s1 == *s2 ) )\r
-    {\r
-        ++s1;\r
-        ++s2;\r
-        --n;\r
-    }\r
-    if ( n == 0 )\r
-    {\r
-        return 0;\r
-    }\r
-    else\r
-    {\r
-        return ( *(wchar_t *)s1 - *(wchar_t *)s2 );\r
-    }\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    wchar_t cmpabcde[] = L"abcde\0f";\r
-    wchar_t cmpabcd_[] = L"abcde\xfc";\r
-    wchar_t empty[] = L"";\r
-    wchar_t x[] = L"x";\r
-    TESTCASE( wcsncmp( wabcde, cmpabcde, 5 ) == 0 );\r
-    TESTCASE( wcsncmp( wabcde, cmpabcde, 10 ) == 0 );\r
-    TESTCASE( wcsncmp( wabcde, wabcdx, 5 ) < 0 );\r
-    TESTCASE( wcsncmp( wabcdx, wabcde, 5 ) > 0 );\r
-    TESTCASE( wcsncmp( empty, wabcde, 5 ) < 0 );\r
-    TESTCASE( wcsncmp( wabcde, empty, 5 ) > 0 );\r
-    TESTCASE( wcsncmp( wabcde, wabcdx, 4 ) == 0 );\r
-    TESTCASE( wcsncmp( wabcde, x, 0 ) == 0 );\r
-    TESTCASE( wcsncmp( wabcde, x, 1 ) < 0 );\r
-    TESTCASE( wcsncmp( wabcde, cmpabcd_, 10 ) < 0 );\r
-    return TEST_RESULTS;\r
-}\r
-#endif\r
+/* wcsncmp( const wchar_t *, const wchar_t *, size_t )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <wchar.h>
+
+#ifndef REGTEST
+
+int wcsncmp( const wchar_t * s1, const wchar_t * s2, size_t n )
+{
+    while ( *s1 && n && ( *s1 == *s2 ) )
+    {
+        ++s1;
+        ++s2;
+        --n;
+    }
+    if ( n == 0 )
+    {
+        return 0;
+    }
+    else
+    {
+        return ( *(wchar_t *)s1 - *(wchar_t *)s2 );
+    }
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    wchar_t cmpabcde[] = L"abcde\0f";
+    wchar_t cmpabcd_[] = L"abcde\xfc";
+    wchar_t empty[] = L"";
+    wchar_t x[] = L"x";
+    TESTCASE( wcsncmp( wabcde, cmpabcde, 5 ) == 0 );
+    TESTCASE( wcsncmp( wabcde, cmpabcde, 10 ) == 0 );
+    TESTCASE( wcsncmp( wabcde, wabcdx, 5 ) < 0 );
+    TESTCASE( wcsncmp( wabcdx, wabcde, 5 ) > 0 );
+    TESTCASE( wcsncmp( empty, wabcde, 5 ) < 0 );
+    TESTCASE( wcsncmp( wabcde, empty, 5 ) > 0 );
+    TESTCASE( wcsncmp( wabcde, wabcdx, 4 ) == 0 );
+    TESTCASE( wcsncmp( wabcde, x, 0 ) == 0 );
+    TESTCASE( wcsncmp( wabcde, x, 1 ) < 0 );
+    TESTCASE( wcsncmp( wabcde, cmpabcd_, 10 ) < 0 );
+    return TEST_RESULTS;
+}
+#endif
index 570946461b1952ba508781f52c820945f6520f34..2734fdd6905202d973a5b4b4fd5b315663407e34 100644 (file)
@@ -1,43 +1,43 @@
-/* wchar_t * wcsncpy( wchar_t *, const wchar_t * , size_t );\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <wchar.h>\r
-\r
-#ifndef REGTEST\r
-\r
-wchar_t *wcsncpy( wchar_t * _PDCLIB_restrict s1, \r
-                  const wchar_t * _PDCLIB_restrict s2,\r
-                  size_t n )\r
-{\r
-    wchar_t * rc = s1;\r
-    while ( ( n > 0 ) && ( *s1++ = *s2++ ) )\r
-    {\r
-        /* Cannot do "n--" in the conditional as size_t is unsigned and we have\r
-           to check it again for >0 in the next loop below, so we must not risk\r
-           underflow.\r
-        */\r
-        --n;\r
-    }\r
-    /* Checking against 1 as we missed the last --n in the loop above. */\r
-    while ( n-- > 1 )\r
-    {\r
-        *s1++ = '\0';\r
-    }\r
-    return rc;\r
-}\r
-\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
+/* wchar_t * wcsncpy( wchar_t *, const wchar_t * , size_t );
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <wchar.h>
+
+#ifndef REGTEST
+
+wchar_t *wcsncpy( wchar_t * _PDCLIB_restrict s1, 
+                  const wchar_t * _PDCLIB_restrict s2,
+                  size_t n )
+{
+    wchar_t * rc = s1;
+    while ( ( n > 0 ) && ( *s1++ = *s2++ ) )
+    {
+        /* Cannot do "n--" in the conditional as size_t is unsigned and we have
+           to check it again for >0 in the next loop below, so we must not risk
+           underflow.
+        */
+        --n;
+    }
+    /* Checking against 1 as we missed the last --n in the loop above. */
+    while ( n-- > 1 )
+    {
+        *s1++ = '\0';
+    }
+    return rc;
+}
+
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    return TEST_RESULTS;
+}
+
+#endif
index c9434f847005749d34d315d44736624d5421c8b0..6503a854299b2384429aaa26f14ccebc708d3067 100644 (file)
@@ -1,47 +1,47 @@
-/* wcspbrk( const wchar_t *, const wchar_t * )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <wchar.h>\r
-\r
-#ifndef REGTEST\r
-\r
-wchar_t * wcspbrk( const wchar_t * s1, const wchar_t * s2 )\r
-{\r
-    const wchar_t * p1 = s1;\r
-    const wchar_t * p2;\r
-    while ( *p1 )\r
-    {\r
-        p2 = s2;\r
-        while ( *p2 )\r
-        {\r
-            if ( *p1 == *p2++ )\r
-            {\r
-                return (wchar_t *) p1;\r
-            }\r
-        }\r
-        ++p1;\r
-    }\r
-    return NULL;\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    TESTCASE( wcspbrk( wabcde, L"x" ) == NULL );\r
-    TESTCASE( wcspbrk( wabcde, L"xyz" ) == NULL );\r
-    TESTCASE( wcspbrk( wabcdx, L"x" ) == &wabcdx[4] );\r
-    TESTCASE( wcspbrk( wabcdx, L"xyz" ) == &wabcdx[4] );\r
-    TESTCASE( wcspbrk( wabcdx, L"zyx" ) == &wabcdx[4] );\r
-    TESTCASE( wcspbrk( wabcde, L"a" ) == &wabcde[0] );\r
-    TESTCASE( wcspbrk( wabcde, L"abc" ) == &wabcde[0] );\r
-    TESTCASE( wcspbrk( wabcde, L"cba" ) == &wabcde[0] );\r
-    return TEST_RESULTS;\r
-}\r
-#endif\r
+/* wcspbrk( const wchar_t *, const wchar_t * )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <wchar.h>
+
+#ifndef REGTEST
+
+wchar_t * wcspbrk( const wchar_t * s1, const wchar_t * s2 )
+{
+    const wchar_t * p1 = s1;
+    const wchar_t * p2;
+    while ( *p1 )
+    {
+        p2 = s2;
+        while ( *p2 )
+        {
+            if ( *p1 == *p2++ )
+            {
+                return (wchar_t *) p1;
+            }
+        }
+        ++p1;
+    }
+    return NULL;
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    TESTCASE( wcspbrk( wabcde, L"x" ) == NULL );
+    TESTCASE( wcspbrk( wabcde, L"xyz" ) == NULL );
+    TESTCASE( wcspbrk( wabcdx, L"x" ) == &wabcdx[4] );
+    TESTCASE( wcspbrk( wabcdx, L"xyz" ) == &wabcdx[4] );
+    TESTCASE( wcspbrk( wabcdx, L"zyx" ) == &wabcdx[4] );
+    TESTCASE( wcspbrk( wabcde, L"a" ) == &wabcde[0] );
+    TESTCASE( wcspbrk( wabcde, L"abc" ) == &wabcde[0] );
+    TESTCASE( wcspbrk( wabcde, L"cba" ) == &wabcde[0] );
+    return TEST_RESULTS;
+}
+#endif
index 76e22a34652b43b5fb1ad3850afe6c376d6529e2..5f2a66daa02d6517e48635fa694809b1c5920b2e 100644 (file)
@@ -1,33 +1,33 @@
-/* wcsrchr( const wchar_t *, wchar_t );\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <wchar.h>\r
-#include <stddef.h>\r
-\r
-#ifndef REGTEST\r
-\r
-wchar_t *wcsrchr(const wchar_t * haystack, wchar_t needle)\r
-{\r
-    wchar_t *found = NULL;\r
-    while(*haystack) {\r
-        if(*haystack == needle) found = (wchar_t*) haystack;\r
-        haystack++;\r
-    }\r
-    return found;\r
-}\r
-\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
+/* wcsrchr( const wchar_t *, wchar_t );
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <wchar.h>
+#include <stddef.h>
+
+#ifndef REGTEST
+
+wchar_t *wcsrchr(const wchar_t * haystack, wchar_t needle)
+{
+    wchar_t *found = NULL;
+    while(*haystack) {
+        if(*haystack == needle) found = (wchar_t*) haystack;
+        haystack++;
+    }
+    return found;
+}
+
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    return TEST_RESULTS;
+}
+
+#endif
index 2f7860f7ccd0696bd63f8df105b5a33b6bf12c11..dbdf522c716ae6b65f48f48b7944b0d64b918e10 100644 (file)
@@ -1,47 +1,47 @@
-/* wcsspn( const wchar_t *, const wchar_t * )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <wchar.h>\r
-\r
-#ifndef REGTEST\r
-\r
-size_t wcsspn( const wchar_t * s1, const wchar_t * s2 )\r
-{\r
-    size_t len = 0;\r
-    const wchar_t * p;\r
-    while ( s1[ len ] )\r
-    {\r
-        p = s2;\r
-        while ( *p )\r
-        {\r
-            if ( s1[len] == *p )\r
-            {\r
-                break;\r
-            }\r
-            ++p;\r
-        }\r
-        if ( ! *p )\r
-        {\r
-            return len;\r
-        }\r
-        ++len;\r
-    }\r
-    return len;\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    TESTCASE( wcsspn( wabcde, L"abc" ) == 3 );\r
-    TESTCASE( wcsspn( wabcde, L"b" ) == 0 );\r
-    TESTCASE( wcsspn( wabcde, wabcde ) == 5 );\r
-    return TEST_RESULTS;\r
-}\r
-#endif\r
+/* wcsspn( const wchar_t *, const wchar_t * )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <wchar.h>
+
+#ifndef REGTEST
+
+size_t wcsspn( const wchar_t * s1, const wchar_t * s2 )
+{
+    size_t len = 0;
+    const wchar_t * p;
+    while ( s1[ len ] )
+    {
+        p = s2;
+        while ( *p )
+        {
+            if ( s1[len] == *p )
+            {
+                break;
+            }
+            ++p;
+        }
+        if ( ! *p )
+        {
+            return len;
+        }
+        ++len;
+    }
+    return len;
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    TESTCASE( wcsspn( wabcde, L"abc" ) == 3 );
+    TESTCASE( wcsspn( wabcde, L"b" ) == 0 );
+    TESTCASE( wcsspn( wabcde, wabcde ) == 5 );
+    return TEST_RESULTS;
+}
+#endif
index 84f7c492b388e3edd1ec4530596901001b5b5c8a..1427a8a573de7690bf7a3bb5e5ea62d358513638 100644 (file)
@@ -1,49 +1,49 @@
-/* wcsstr( const wchar_t *, const wchar_t * )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <wchar.h>\r
-\r
-#ifndef REGTEST\r
-\r
-wchar_t * wcsstr( const wchar_t * s1, const wchar_t * s2 )\r
-{\r
-    const wchar_t * p1 = s1;\r
-    const wchar_t * p2;\r
-    while ( *s1 )\r
-    {\r
-        p2 = s2;\r
-        while ( *p2 && ( *p1 == *p2 ) )\r
-        {\r
-            ++p1;\r
-            ++p2;\r
-        }\r
-        if ( ! *p2 )\r
-        {\r
-            return (wchar_t *) s1;\r
-        }\r
-        ++s1;\r
-        p1 = s1;\r
-    }\r
-    return NULL;\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    wchar_t s[] = L"abcabcabcdabcde";\r
-    TESTCASE( wcsstr( s, L"x" ) == NULL );\r
-    TESTCASE( wcsstr( s, L"xyz" ) == NULL );\r
-    TESTCASE( wcsstr( s, L"a" ) == &s[0] );\r
-    TESTCASE( wcsstr( s, L"abc" ) == &s[0] );\r
-    TESTCASE( wcsstr( s, L"abcd" ) == &s[6] );\r
-    TESTCASE( wcsstr( s, L"abcde" ) == &s[10] );\r
-    return TEST_RESULTS;\r
-}\r
-#endif\r
+/* wcsstr( const wchar_t *, const wchar_t * )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <wchar.h>
+
+#ifndef REGTEST
+
+wchar_t * wcsstr( const wchar_t * s1, const wchar_t * s2 )
+{
+    const wchar_t * p1 = s1;
+    const wchar_t * p2;
+    while ( *s1 )
+    {
+        p2 = s2;
+        while ( *p2 && ( *p1 == *p2 ) )
+        {
+            ++p1;
+            ++p2;
+        }
+        if ( ! *p2 )
+        {
+            return (wchar_t *) s1;
+        }
+        ++s1;
+        p1 = s1;
+    }
+    return NULL;
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    wchar_t s[] = L"abcabcabcdabcde";
+    TESTCASE( wcsstr( s, L"x" ) == NULL );
+    TESTCASE( wcsstr( s, L"xyz" ) == NULL );
+    TESTCASE( wcsstr( s, L"a" ) == &s[0] );
+    TESTCASE( wcsstr( s, L"abc" ) == &s[0] );
+    TESTCASE( wcsstr( s, L"abcd" ) == &s[6] );
+    TESTCASE( wcsstr( s, L"abcde" ) == &s[10] );
+    return TEST_RESULTS;
+}
+#endif
index 13415198d364db0f08f9a0a0b75d3fad91f75219..b8bcf14184a0f7f8c562efa794e406537d125f92 100644 (file)
-/* wcstok( wchar_t *, const wchar_t * )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <wchar.h>\r
-\r
-#ifndef REGTEST\r
-\r
-wchar_t * wcstok( wchar_t * _PDCLIB_restrict s1, \r
-                  const wchar_t * _PDCLIB_restrict s2,\r
-                  wchar_t ** _PDCLIB_restrict ptr )\r
-{\r
-    const wchar_t * p = s2;\r
-\r
-    if ( s1 != NULL )\r
-    {\r
-        /* new string */\r
-        *ptr = s1;\r
-    }\r
-    else\r
-    {\r
-        /* old string continued */\r
-        if ( *ptr == NULL )\r
-        {\r
-            /* No old string, no new string, nothing to do */\r
-            return NULL;\r
-        }\r
-        s1 = *ptr;\r
-    }\r
-\r
-    /* skipping leading s2 characters */\r
-    while ( *p && *s1 )\r
-    {\r
-        if ( *s1 == *p )\r
-        {\r
-            /* found seperator; skip and start over */\r
-            ++s1;\r
-            p = s2;\r
-            continue;\r
-        }\r
-        ++p;\r
-    }\r
-\r
-    if ( ! *s1 )\r
-    {\r
-        /* no more to parse */\r
-        return ( *ptr = NULL );\r
-    }\r
-\r
-    /* skipping non-s2 characters */\r
-    *ptr = s1;\r
-    while ( **ptr )\r
-    {\r
-        p = s2;\r
-        while ( *p )\r
-        {\r
-            if ( **ptr == *p++ )\r
-            {\r
-                /* found seperator; overwrite with '\0', position *ptr, return */\r
-                *(*ptr)++ = L'\0';\r
-                return s1;\r
-            }\r
-        }\r
-        ++(*ptr);\r
-    }\r
-\r
-    /* parsed to end of string */\r
-    *ptr = NULL;\r
-    return s1;\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    // MinGW at least has a very nonconforming (different signature!) variety\r
-    // of wcstok\r
-#ifndef REGTEST\r
-    wchar_t s[] = L"_a_bc__d_";\r
-    wchar_t* state  = NULL;\r
-    wchar_t* tokres;\r
-\r
-    TESTCASE( ( tokres = wcstok( s, L"_", &state ) ) == &s[1] );\r
-    TESTCASE( s[1] == L'a' );\r
-    TESTCASE( s[2] == L'\0' );\r
-    TESTCASE( ( tokres = wcstok( NULL, L"_", &state ) ) == &s[3] );\r
-    TESTCASE( s[3] == L'b' );\r
-    TESTCASE( s[4] == L'c' );\r
-    TESTCASE( s[5] == L'\0' );\r
-    TESTCASE( ( tokres = wcstok( NULL, L"_", &state ) ) == &s[7] );\r
-    TESTCASE( s[6] == L'_' );\r
-    TESTCASE( s[7] == L'd' );\r
-    TESTCASE( s[8] == L'\0' );\r
-    TESTCASE( ( tokres = wcstok( NULL, L"_", &state ) ) == NULL );\r
-    wcscpy( s, L"ab_cd" );\r
-    TESTCASE( ( tokres = wcstok( s, L"_", &state ) ) == &s[0] );\r
-    TESTCASE( s[0] == L'a' );\r
-    TESTCASE( s[1] == L'b' );\r
-    TESTCASE( s[2] == L'\0' );\r
-    TESTCASE( ( tokres = wcstok( NULL, L"_", &state ) ) == &s[3] );\r
-    TESTCASE( s[3] == L'c' );\r
-    TESTCASE( s[4] == L'd' );\r
-    TESTCASE( s[5] == L'\0' );\r
-    TESTCASE( ( tokres = wcstok( NULL, L"_", &state ) ) == NULL );\r
-#endif\r
-    return TEST_RESULTS;\r
-}\r
-#endif\r
+/* wcstok( wchar_t *, const wchar_t * )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <wchar.h>
+
+#ifndef REGTEST
+
+wchar_t * wcstok( wchar_t * _PDCLIB_restrict s1, 
+                  const wchar_t * _PDCLIB_restrict s2,
+                  wchar_t ** _PDCLIB_restrict ptr )
+{
+    const wchar_t * p = s2;
+
+    if ( s1 != NULL )
+    {
+        /* new string */
+        *ptr = s1;
+    }
+    else
+    {
+        /* old string continued */
+        if ( *ptr == NULL )
+        {
+            /* No old string, no new string, nothing to do */
+            return NULL;
+        }
+        s1 = *ptr;
+    }
+
+    /* skipping leading s2 characters */
+    while ( *p && *s1 )
+    {
+        if ( *s1 == *p )
+        {
+            /* found seperator; skip and start over */
+            ++s1;
+            p = s2;
+            continue;
+        }
+        ++p;
+    }
+
+    if ( ! *s1 )
+    {
+        /* no more to parse */
+        return ( *ptr = NULL );
+    }
+
+    /* skipping non-s2 characters */
+    *ptr = s1;
+    while ( **ptr )
+    {
+        p = s2;
+        while ( *p )
+        {
+            if ( **ptr == *p++ )
+            {
+                /* found seperator; overwrite with '\0', position *ptr, return */
+                *(*ptr)++ = L'\0';
+                return s1;
+            }
+        }
+        ++(*ptr);
+    }
+
+    /* parsed to end of string */
+    *ptr = NULL;
+    return s1;
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    // MinGW at least has a very nonconforming (different signature!) variety
+    // of wcstok
+#ifndef REGTEST
+    wchar_t s[] = L"_a_bc__d_";
+    wchar_t* state  = NULL;
+    wchar_t* tokres;
+
+    TESTCASE( ( tokres = wcstok( s, L"_", &state ) ) == &s[1] );
+    TESTCASE( s[1] == L'a' );
+    TESTCASE( s[2] == L'\0' );
+    TESTCASE( ( tokres = wcstok( NULL, L"_", &state ) ) == &s[3] );
+    TESTCASE( s[3] == L'b' );
+    TESTCASE( s[4] == L'c' );
+    TESTCASE( s[5] == L'\0' );
+    TESTCASE( ( tokres = wcstok( NULL, L"_", &state ) ) == &s[7] );
+    TESTCASE( s[6] == L'_' );
+    TESTCASE( s[7] == L'd' );
+    TESTCASE( s[8] == L'\0' );
+    TESTCASE( ( tokres = wcstok( NULL, L"_", &state ) ) == NULL );
+    wcscpy( s, L"ab_cd" );
+    TESTCASE( ( tokres = wcstok( s, L"_", &state ) ) == &s[0] );
+    TESTCASE( s[0] == L'a' );
+    TESTCASE( s[1] == L'b' );
+    TESTCASE( s[2] == L'\0' );
+    TESTCASE( ( tokres = wcstok( NULL, L"_", &state ) ) == &s[3] );
+    TESTCASE( s[3] == L'c' );
+    TESTCASE( s[4] == L'd' );
+    TESTCASE( s[5] == L'\0' );
+    TESTCASE( ( tokres = wcstok( NULL, L"_", &state ) ) == NULL );
+#endif
+    return TEST_RESULTS;
+}
+#endif
index e05b68e183ff3ab38c9a2dd8b321e26bbae7236d..75b010d4c2db28365ee6448ec400539eaea50670 100644 (file)
@@ -1,39 +1,39 @@
-/* wmemchr( const void *, int, size_t )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <wchar.h>\r
-\r
-#ifndef REGTEST\r
-\r
-wchar_t * wmemchr( const wchar_t * p, wchar_t c, size_t n )\r
-{\r
-    while ( n-- )\r
-    {\r
-        if ( *p == c )\r
-        {\r
-            return (wchar_t*) p;\r
-        }\r
-        ++p;\r
-    }\r
-    return NULL;\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    TESTCASE( wmemchr( wabcde, L'c', 5 ) == &wabcde[2] );\r
-    TESTCASE( wmemchr( wabcde, L'a', 1 ) == &wabcde[0] );\r
-    TESTCASE( wmemchr( wabcde, L'a', 0 ) == NULL );\r
-    TESTCASE( wmemchr( wabcde, L'\0', 5 ) == NULL );\r
-    TESTCASE( wmemchr( wabcde, L'\0', 6 ) == &wabcde[5] );\r
-    return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
+/* wmemchr( const void *, int, size_t )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <wchar.h>
+
+#ifndef REGTEST
+
+wchar_t * wmemchr( const wchar_t * p, wchar_t c, size_t n )
+{
+    while ( n-- )
+    {
+        if ( *p == c )
+        {
+            return (wchar_t*) p;
+        }
+        ++p;
+    }
+    return NULL;
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    TESTCASE( wmemchr( wabcde, L'c', 5 ) == &wabcde[2] );
+    TESTCASE( wmemchr( wabcde, L'a', 1 ) == &wabcde[0] );
+    TESTCASE( wmemchr( wabcde, L'a', 0 ) == NULL );
+    TESTCASE( wmemchr( wabcde, L'\0', 5 ) == NULL );
+    TESTCASE( wmemchr( wabcde, L'\0', 6 ) == &wabcde[5] );
+    return TEST_RESULTS;
+}
+
+#endif
index 15401166120d6242708aefedaf3a8ccb23f5849e..de5d49afd2ee533114b18dfa5713becd57e779a5 100644 (file)
@@ -1,39 +1,39 @@
-/* wmemcmp( const wchar_t *, const wchar_t *, size_t )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <wchar.h>\r
-\r
-#ifndef REGTEST\r
-\r
-int wmemcmp( const wchar_t * p1, const wchar_t * p2, size_t n )\r
-{\r
-    while ( n-- )\r
-    {\r
-        if ( *p1 != *p2 )\r
-        {\r
-            return *p1 - *p2;\r
-        }\r
-        ++p1;\r
-        ++p2;\r
-    }\r
-    return 0;\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    wchar_t const xxxxx[] = L"xxxxx";\r
-    TESTCASE( wmemcmp( wabcde, wabcdx, 5 ) < 0 );\r
-    TESTCASE( wmemcmp( wabcde, wabcdx, 4 ) == 0 );\r
-    TESTCASE( wmemcmp( wabcde, xxxxx,  0 ) == 0 );\r
-    TESTCASE( wmemcmp( xxxxx,  wabcde, 1 ) > 0 );\r
-    return 0;\r
-}\r
-#endif\r
+/* wmemcmp( const wchar_t *, const wchar_t *, size_t )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <wchar.h>
+
+#ifndef REGTEST
+
+int wmemcmp( const wchar_t * p1, const wchar_t * p2, size_t n )
+{
+    while ( n-- )
+    {
+        if ( *p1 != *p2 )
+        {
+            return *p1 - *p2;
+        }
+        ++p1;
+        ++p2;
+    }
+    return 0;
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    wchar_t const xxxxx[] = L"xxxxx";
+    TESTCASE( wmemcmp( wabcde, wabcdx, 5 ) < 0 );
+    TESTCASE( wmemcmp( wabcde, wabcdx, 4 ) == 0 );
+    TESTCASE( wmemcmp( wabcde, xxxxx,  0 ) == 0 );
+    TESTCASE( wmemcmp( xxxxx,  wabcde, 1 ) > 0 );
+    return 0;
+}
+#endif
index b0b9c200d4667daa827934c63cb390453284c443..2f3bdac3355a3ab5e7a199c017f350bac2d5b524 100644 (file)
@@ -1,39 +1,39 @@
-/* wmemcpy( wchar_t *, const wchar_t *, size_t )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <wchar.h>\r
-\r
-#ifndef REGTEST\r
-\r
-wchar_t * wmemcpy( wchar_t * _PDCLIB_restrict dest, \r
-                   const wchar_t * _PDCLIB_restrict src, \r
-                   size_t n )\r
-{\r
-    wchar_t* rv = dest;\r
-    while ( n-- )\r
-    {\r
-        *dest++ = *src++;\r
-    }\r
-    return rv;\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    wchar_t s[] = L"xxxxxxxxxxx";\r
-    TESTCASE( wmemcpy( s, wabcde, 6 ) == s );\r
-    TESTCASE( s[4] == L'e' );\r
-    TESTCASE( s[5] == L'\0' );\r
-    TESTCASE( wmemcpy( s + 5, wabcde, 5 ) == s + 5 );\r
-    TESTCASE( s[9] == L'e' );\r
-    TESTCASE( s[10] == L'x' );\r
-    return TEST_RESULTS;\r
-}\r
-#endif\r
+/* wmemcpy( wchar_t *, const wchar_t *, size_t )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <wchar.h>
+
+#ifndef REGTEST
+
+wchar_t * wmemcpy( wchar_t * _PDCLIB_restrict dest, 
+                   const wchar_t * _PDCLIB_restrict src, 
+                   size_t n )
+{
+    wchar_t* rv = dest;
+    while ( n-- )
+    {
+        *dest++ = *src++;
+    }
+    return rv;
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    wchar_t s[] = L"xxxxxxxxxxx";
+    TESTCASE( wmemcpy( s, wabcde, 6 ) == s );
+    TESTCASE( s[4] == L'e' );
+    TESTCASE( s[5] == L'\0' );
+    TESTCASE( wmemcpy( s + 5, wabcde, 5 ) == s + 5 );
+    TESTCASE( s[9] == L'e' );
+    TESTCASE( s[10] == L'x' );
+    return TEST_RESULTS;
+}
+#endif
index fe6a53eb4d3f3c083dd3bfdd4e5404c1e5d6e720..a5288f40cbf1fcde21db9b3f67db74762a11c88d 100644 (file)
@@ -1,49 +1,49 @@
-/* wmemmove( wchar_t *, const wchar_t *, size_t )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <wchar.h>\r
-\r
-#ifndef REGTEST\r
-\r
-wchar_t * wmemmove( wchar_t * dest, const wchar_t * src, size_t n )\r
-{\r
-    wchar_t* rv = dest;\r
-    if ( dest <= src )\r
-    {\r
-        while ( n-- )\r
-        {\r
-            *dest++ = *src++;\r
-        }\r
-    }\r
-    else\r
-    {\r
-        src += n;\r
-        dest += n;\r
-        while ( n-- )\r
-        {\r
-            *--dest = *--src;\r
-        }\r
-    }\r
-    return rv;\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    wchar_t s[] = L"xxxxabcde";\r
-    TESTCASE( wmemmove( s, s + 4, 5 ) == s );\r
-    TESTCASE( s[0] == L'a' );\r
-    TESTCASE( s[4] == L'e' );\r
-    TESTCASE( s[5] == L'b' );\r
-    TESTCASE( wmemmove( s + 4, s, 5 ) == s + 4 );\r
-    TESTCASE( s[4] == L'a' );\r
-    return TEST_RESULTS;\r
-}\r
-#endif\r
+/* wmemmove( wchar_t *, const wchar_t *, size_t )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <wchar.h>
+
+#ifndef REGTEST
+
+wchar_t * wmemmove( wchar_t * dest, const wchar_t * src, size_t n )
+{
+    wchar_t* rv = dest;
+    if ( dest <= src )
+    {
+        while ( n-- )
+        {
+            *dest++ = *src++;
+        }
+    }
+    else
+    {
+        src += n;
+        dest += n;
+        while ( n-- )
+        {
+            *--dest = *--src;
+        }
+    }
+    return rv;
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    wchar_t s[] = L"xxxxabcde";
+    TESTCASE( wmemmove( s, s + 4, 5 ) == s );
+    TESTCASE( s[0] == L'a' );
+    TESTCASE( s[4] == L'e' );
+    TESTCASE( s[5] == L'b' );
+    TESTCASE( wmemmove( s + 4, s, 5 ) == s + 4 );
+    TESTCASE( s[4] == L'a' );
+    return TEST_RESULTS;
+}
+#endif
index 5f12a800353a664b2401d5684186eb2b2454453e..df5dbb2ae985161515365cf391494ec0012a7244 100644 (file)
@@ -1,30 +1,30 @@
-/* iswalnum( wint_t )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <wctype.h>\r
-#ifndef REGTEST\r
-#include "_PDCLIB_locale.h"\r
-\r
-int iswalnum( wint_t wc )\r
-{\r
-    return iswctype( wc, _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_DIGIT );\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    TESTCASE(iswalnum(L'a'));\r
-    TESTCASE(iswalnum(L'z'));\r
-    TESTCASE(iswalnum(L'E'));\r
-    TESTCASE(iswalnum(L'3'));\r
-    TESTCASE(!iswalnum(L';'));\r
-    return TEST_RESULTS;\r
-}\r
-#endif\r
+/* iswalnum( wint_t )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <wctype.h>
+#ifndef REGTEST
+#include "_PDCLIB_locale.h"
+
+int iswalnum( wint_t wc )
+{
+    return iswctype( wc, _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_DIGIT );
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    TESTCASE(iswalnum(L'a'));
+    TESTCASE(iswalnum(L'z'));
+    TESTCASE(iswalnum(L'E'));
+    TESTCASE(iswalnum(L'3'));
+    TESTCASE(!iswalnum(L';'));
+    return TEST_RESULTS;
+}
+#endif
index 5c173788a6740934bd0ea9c605ae376bbdd5da9d..9cf5cfaa0646f7538a90b8b58e8d7a5f7ef5ba6a 100644 (file)
@@ -1,30 +1,30 @@
-/* iswalpha( wint_t )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <wctype.h>\r
-#ifndef REGTEST\r
-#include "_PDCLIB_locale.h"\r
-\r
-int iswalpha( wint_t wc )\r
-{\r
-    return iswctype( wc, _PDCLIB_CTYPE_ALPHA );\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    TESTCASE(iswalpha(L'a'));\r
-    TESTCASE(iswalpha(L'z'));\r
-    TESTCASE(iswalpha(L'E'));\r
-    TESTCASE(!iswalpha(L'3'));\r
-    TESTCASE(!iswalpha(L';'));\r
-    return TEST_RESULTS;\r
-}\r
-#endif\r
+/* iswalpha( wint_t )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <wctype.h>
+#ifndef REGTEST
+#include "_PDCLIB_locale.h"
+
+int iswalpha( wint_t wc )
+{
+    return iswctype( wc, _PDCLIB_CTYPE_ALPHA );
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    TESTCASE(iswalpha(L'a'));
+    TESTCASE(iswalpha(L'z'));
+    TESTCASE(iswalpha(L'E'));
+    TESTCASE(!iswalpha(L'3'));
+    TESTCASE(!iswalpha(L';'));
+    return TEST_RESULTS;
+}
+#endif
index 082370046bfff22ccef4134bb1a4adf0be3cd472..a73b9f63ce177ac1e229eabd395d0e203e4d1586 100644 (file)
@@ -1,29 +1,29 @@
-/* iswblank( wint_t )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <wctype.h>\r
-#ifndef REGTEST\r
-#include "_PDCLIB_locale.h"\r
-\r
-int iswblank( wint_t wc )\r
-{\r
-    return iswctype( wc, _PDCLIB_CTYPE_BLANK );\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    TESTCASE(iswblank(L' '));\r
-    TESTCASE(iswblank(L'\t'));\r
-    TESTCASE(!iswblank(L'\n'));\r
-    TESTCASE(!iswblank(L'a'));\r
-    return TEST_RESULTS;\r
-}\r
-#endif\r
+/* iswblank( wint_t )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <wctype.h>
+#ifndef REGTEST
+#include "_PDCLIB_locale.h"
+
+int iswblank( wint_t wc )
+{
+    return iswctype( wc, _PDCLIB_CTYPE_BLANK );
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    TESTCASE(iswblank(L' '));
+    TESTCASE(iswblank(L'\t'));
+    TESTCASE(!iswblank(L'\n'));
+    TESTCASE(!iswblank(L'a'));
+    return TEST_RESULTS;
+}
+#endif
index e3cd1cd9e3755edccbe4c7c46bef98062635e510..1c81c54437006264cd76114e791f235e28ab576d 100644 (file)
@@ -1,30 +1,30 @@
-/* iswcntrl( wint_t )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <wctype.h>\r
-#ifndef REGTEST\r
-#include "_PDCLIB_locale.h"\r
-\r
-int iswcntrl( wint_t wc )\r
-{\r
-    return iswctype( wc, _PDCLIB_CTYPE_CNTRL );\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    TESTCASE(iswcntrl(L'\0'));\r
-    TESTCASE(iswcntrl(L'\n'));\r
-    TESTCASE(iswcntrl(L'\v'));\r
-    TESTCASE(!iswcntrl(L'\t'));\r
-    TESTCASE(!iswcntrl(L'a'));\r
-    return TEST_RESULTS;\r
-}\r
-#endif\r
+/* iswcntrl( wint_t )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <wctype.h>
+#ifndef REGTEST
+#include "_PDCLIB_locale.h"
+
+int iswcntrl( wint_t wc )
+{
+    return iswctype( wc, _PDCLIB_CTYPE_CNTRL );
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    TESTCASE(iswcntrl(L'\0'));
+    TESTCASE(iswcntrl(L'\n'));
+    TESTCASE(iswcntrl(L'\v'));
+    TESTCASE(!iswcntrl(L'\t'));
+    TESTCASE(!iswcntrl(L'a'));
+    return TEST_RESULTS;
+}
+#endif
index ab626ea8757971015247cf5d75aeda6c35e662af..cac41150acc033fbd1a1dec956b9236636f79cfc 100644 (file)
-/* iswctype( wint_t, wctype_t )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <wctype.h>\r
-#ifndef REGTEST\r
-#include "_PDCLIB_locale.h"\r
-\r
-int _PDCLIB_iswctype_l( wint_t wc, wctype_t desc, locale_t l )\r
-{\r
-    wc = _PDCLIB_unpackwint( wc );\r
-\r
-    _PDCLIB_wcinfo_t *info = _PDCLIB_wcgetinfo( l, wc );\r
-\r
-    if(!info) return 0;\r
-\r
-    return info->flags & desc;\r
-}\r
-\r
-int iswctype( wint_t wc, wctype_t desc )\r
-{\r
-    return _PDCLIB_iswctype_l( wc, desc, _PDCLIB_threadlocale() );\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    TESTCASE( iswctype(L'a', wctype("alpha")));\r
-    TESTCASE( iswctype(L'z', wctype("alpha")));\r
-    TESTCASE( iswctype(L'E', wctype("alpha")));\r
-    TESTCASE(!iswctype(L'3', wctype("alpha")));\r
-    TESTCASE(!iswctype(L';', wctype("alpha")));\r
-\r
-    TESTCASE( iswctype(L'a', wctype("alnum")));\r
-    TESTCASE( iswctype(L'3', wctype("alnum")));\r
-    TESTCASE(!iswctype(L';', wctype("alnum")));\r
-\r
-    TESTCASE( iswctype(L' ',  wctype("blank")));\r
-    TESTCASE( iswctype(L'\t', wctype("blank")));\r
-    TESTCASE(!iswctype(L'\n', wctype("blank")));\r
-    TESTCASE(!iswctype(L';',  wctype("blank")));\r
-\r
-    TESTCASE( iswctype(L'\0', wctype("cntrl")));\r
-    TESTCASE( iswctype(L'\n', wctype("cntrl")));\r
-    TESTCASE( iswctype(L'\v', wctype("cntrl")));\r
-    TESTCASE(!iswctype(L'\t', wctype("cntrl")));\r
-    TESTCASE(!iswctype(L'a',  wctype("cntrl")));\r
-\r
-    TESTCASE( iswctype(L'0',  wctype("digit")));\r
-    TESTCASE( iswctype(L'1',  wctype("digit")));\r
-    TESTCASE( iswctype(L'2',  wctype("digit")));\r
-    TESTCASE( iswctype(L'3',  wctype("digit")));\r
-    TESTCASE( iswctype(L'4',  wctype("digit")));\r
-    TESTCASE( iswctype(L'5',  wctype("digit")));\r
-    TESTCASE( iswctype(L'6',  wctype("digit")));\r
-    TESTCASE( iswctype(L'7',  wctype("digit")));\r
-    TESTCASE( iswctype(L'8',  wctype("digit")));\r
-    TESTCASE( iswctype(L'9',  wctype("digit")));\r
-    TESTCASE(!iswctype(L'X',  wctype("digit")));\r
-    TESTCASE(!iswctype(L'?',  wctype("digit")));\r
-\r
-    TESTCASE( iswctype(L'a',  wctype("graph")));\r
-    TESTCASE( iswctype(L'z',  wctype("graph")));\r
-    TESTCASE( iswctype(L'E',  wctype("graph")));\r
-    TESTCASE( iswctype(L'E',  wctype("graph")));\r
-    TESTCASE(!iswctype(L' ',  wctype("graph")));\r
-    TESTCASE(!iswctype(L'\t', wctype("graph")));\r
-    TESTCASE(!iswctype(L'\n', wctype("graph")));\r
-\r
-    TESTCASE( iswctype(L'a',  wctype("lower")));\r
-    TESTCASE( iswctype(L'e',  wctype("lower")));\r
-    TESTCASE( iswctype(L'z',  wctype("lower")));\r
-    TESTCASE(!iswctype(L'A',  wctype("lower")));\r
-    TESTCASE(!iswctype(L'E',  wctype("lower")));\r
-    TESTCASE(!iswctype(L'Z',  wctype("lower")));\r
-\r
-    TESTCASE(!iswctype(L'a',  wctype("upper")));\r
-    TESTCASE(!iswctype(L'e',  wctype("upper")));\r
-    TESTCASE(!iswctype(L'z',  wctype("upper")));\r
-    TESTCASE( iswctype(L'A',  wctype("upper")));\r
-    TESTCASE( iswctype(L'E',  wctype("upper")));\r
-    TESTCASE( iswctype(L'Z',  wctype("upper")));\r
-\r
-    TESTCASE( iswctype(L'Z',  wctype("print")));\r
-    TESTCASE( iswctype(L'a',  wctype("print")));\r
-    TESTCASE( iswctype(L';',  wctype("print")));\r
-    TESTCASE( iswctype(L'\t', wctype("print")));\r
-    TESTCASE(!iswctype(L'\0', wctype("print")));\r
-\r
-    TESTCASE( iswctype(L';',  wctype("punct")));\r
-    TESTCASE( iswctype(L'.',  wctype("punct")));\r
-    TESTCASE( iswctype(L'?',  wctype("punct")));\r
-    TESTCASE(!iswctype(L' ',  wctype("punct")));\r
-    TESTCASE(!iswctype(L'Z',  wctype("punct")));\r
-\r
-    TESTCASE( iswctype(L' ',  wctype("space")));\r
-    TESTCASE( iswctype(L'\t', wctype("space")));\r
-\r
-    TESTCASE( iswctype(L'0',  wctype("xdigit")));\r
-    TESTCASE( iswctype(L'1',  wctype("xdigit")));\r
-    TESTCASE( iswctype(L'2',  wctype("xdigit")));\r
-    TESTCASE( iswctype(L'3',  wctype("xdigit")));\r
-    TESTCASE( iswctype(L'4',  wctype("xdigit")));\r
-    TESTCASE( iswctype(L'5',  wctype("xdigit")));\r
-    TESTCASE( iswctype(L'6',  wctype("xdigit")));\r
-    TESTCASE( iswctype(L'7',  wctype("xdigit")));\r
-    TESTCASE( iswctype(L'8',  wctype("xdigit")));\r
-    TESTCASE( iswctype(L'9',  wctype("xdigit")));\r
-    TESTCASE( iswctype(L'a',  wctype("xdigit")));\r
-    TESTCASE( iswctype(L'b',  wctype("xdigit")));\r
-    TESTCASE( iswctype(L'c',  wctype("xdigit")));\r
-    TESTCASE( iswctype(L'd',  wctype("xdigit")));\r
-    TESTCASE( iswctype(L'e',  wctype("xdigit")));\r
-    TESTCASE( iswctype(L'f',  wctype("xdigit")));\r
-    TESTCASE( iswctype(L'A',  wctype("xdigit")));\r
-    TESTCASE( iswctype(L'B',  wctype("xdigit")));\r
-    TESTCASE( iswctype(L'C',  wctype("xdigit")));\r
-    TESTCASE( iswctype(L'D',  wctype("xdigit")));\r
-    TESTCASE( iswctype(L'E',  wctype("xdigit")));\r
-    TESTCASE( iswctype(L'F',  wctype("xdigit")));\r
-    TESTCASE(!iswctype(L'g',  wctype("xdigit")));\r
-    TESTCASE(!iswctype(L'G',  wctype("xdigit")));\r
-    TESTCASE(!iswctype(L'x',  wctype("xdigit")));\r
-    TESTCASE(!iswctype(L'X',  wctype("xdigit")));\r
-    TESTCASE(!iswctype(L' ',  wctype("xdigit")));\r
-\r
-    return TEST_RESULTS;\r
-}\r
-#endif\r
+/* iswctype( wint_t, wctype_t )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <wctype.h>
+#ifndef REGTEST
+#include "_PDCLIB_locale.h"
+
+int _PDCLIB_iswctype_l( wint_t wc, wctype_t desc, locale_t l )
+{
+    wc = _PDCLIB_unpackwint( wc );
+
+    _PDCLIB_wcinfo_t *info = _PDCLIB_wcgetinfo( l, wc );
+
+    if(!info) return 0;
+
+    return info->flags & desc;
+}
+
+int iswctype( wint_t wc, wctype_t desc )
+{
+    return _PDCLIB_iswctype_l( wc, desc, _PDCLIB_threadlocale() );
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    TESTCASE( iswctype(L'a', wctype("alpha")));
+    TESTCASE( iswctype(L'z', wctype("alpha")));
+    TESTCASE( iswctype(L'E', wctype("alpha")));
+    TESTCASE(!iswctype(L'3', wctype("alpha")));
+    TESTCASE(!iswctype(L';', wctype("alpha")));
+
+    TESTCASE( iswctype(L'a', wctype("alnum")));
+    TESTCASE( iswctype(L'3', wctype("alnum")));
+    TESTCASE(!iswctype(L';', wctype("alnum")));
+
+    TESTCASE( iswctype(L' ',  wctype("blank")));
+    TESTCASE( iswctype(L'\t', wctype("blank")));
+    TESTCASE(!iswctype(L'\n', wctype("blank")));
+    TESTCASE(!iswctype(L';',  wctype("blank")));
+
+    TESTCASE( iswctype(L'\0', wctype("cntrl")));
+    TESTCASE( iswctype(L'\n', wctype("cntrl")));
+    TESTCASE( iswctype(L'\v', wctype("cntrl")));
+    TESTCASE(!iswctype(L'\t', wctype("cntrl")));
+    TESTCASE(!iswctype(L'a',  wctype("cntrl")));
+
+    TESTCASE( iswctype(L'0',  wctype("digit")));
+    TESTCASE( iswctype(L'1',  wctype("digit")));
+    TESTCASE( iswctype(L'2',  wctype("digit")));
+    TESTCASE( iswctype(L'3',  wctype("digit")));
+    TESTCASE( iswctype(L'4',  wctype("digit")));
+    TESTCASE( iswctype(L'5',  wctype("digit")));
+    TESTCASE( iswctype(L'6',  wctype("digit")));
+    TESTCASE( iswctype(L'7',  wctype("digit")));
+    TESTCASE( iswctype(L'8',  wctype("digit")));
+    TESTCASE( iswctype(L'9',  wctype("digit")));
+    TESTCASE(!iswctype(L'X',  wctype("digit")));
+    TESTCASE(!iswctype(L'?',  wctype("digit")));
+
+    TESTCASE( iswctype(L'a',  wctype("graph")));
+    TESTCASE( iswctype(L'z',  wctype("graph")));
+    TESTCASE( iswctype(L'E',  wctype("graph")));
+    TESTCASE( iswctype(L'E',  wctype("graph")));
+    TESTCASE(!iswctype(L' ',  wctype("graph")));
+    TESTCASE(!iswctype(L'\t', wctype("graph")));
+    TESTCASE(!iswctype(L'\n', wctype("graph")));
+
+    TESTCASE( iswctype(L'a',  wctype("lower")));
+    TESTCASE( iswctype(L'e',  wctype("lower")));
+    TESTCASE( iswctype(L'z',  wctype("lower")));
+    TESTCASE(!iswctype(L'A',  wctype("lower")));
+    TESTCASE(!iswctype(L'E',  wctype("lower")));
+    TESTCASE(!iswctype(L'Z',  wctype("lower")));
+
+    TESTCASE(!iswctype(L'a',  wctype("upper")));
+    TESTCASE(!iswctype(L'e',  wctype("upper")));
+    TESTCASE(!iswctype(L'z',  wctype("upper")));
+    TESTCASE( iswctype(L'A',  wctype("upper")));
+    TESTCASE( iswctype(L'E',  wctype("upper")));
+    TESTCASE( iswctype(L'Z',  wctype("upper")));
+
+    TESTCASE( iswctype(L'Z',  wctype("print")));
+    TESTCASE( iswctype(L'a',  wctype("print")));
+    TESTCASE( iswctype(L';',  wctype("print")));
+    TESTCASE( iswctype(L'\t', wctype("print")));
+    TESTCASE(!iswctype(L'\0', wctype("print")));
+
+    TESTCASE( iswctype(L';',  wctype("punct")));
+    TESTCASE( iswctype(L'.',  wctype("punct")));
+    TESTCASE( iswctype(L'?',  wctype("punct")));
+    TESTCASE(!iswctype(L' ',  wctype("punct")));
+    TESTCASE(!iswctype(L'Z',  wctype("punct")));
+
+    TESTCASE( iswctype(L' ',  wctype("space")));
+    TESTCASE( iswctype(L'\t', wctype("space")));
+
+    TESTCASE( iswctype(L'0',  wctype("xdigit")));
+    TESTCASE( iswctype(L'1',  wctype("xdigit")));
+    TESTCASE( iswctype(L'2',  wctype("xdigit")));
+    TESTCASE( iswctype(L'3',  wctype("xdigit")));
+    TESTCASE( iswctype(L'4',  wctype("xdigit")));
+    TESTCASE( iswctype(L'5',  wctype("xdigit")));
+    TESTCASE( iswctype(L'6',  wctype("xdigit")));
+    TESTCASE( iswctype(L'7',  wctype("xdigit")));
+    TESTCASE( iswctype(L'8',  wctype("xdigit")));
+    TESTCASE( iswctype(L'9',  wctype("xdigit")));
+    TESTCASE( iswctype(L'a',  wctype("xdigit")));
+    TESTCASE( iswctype(L'b',  wctype("xdigit")));
+    TESTCASE( iswctype(L'c',  wctype("xdigit")));
+    TESTCASE( iswctype(L'd',  wctype("xdigit")));
+    TESTCASE( iswctype(L'e',  wctype("xdigit")));
+    TESTCASE( iswctype(L'f',  wctype("xdigit")));
+    TESTCASE( iswctype(L'A',  wctype("xdigit")));
+    TESTCASE( iswctype(L'B',  wctype("xdigit")));
+    TESTCASE( iswctype(L'C',  wctype("xdigit")));
+    TESTCASE( iswctype(L'D',  wctype("xdigit")));
+    TESTCASE( iswctype(L'E',  wctype("xdigit")));
+    TESTCASE( iswctype(L'F',  wctype("xdigit")));
+    TESTCASE(!iswctype(L'g',  wctype("xdigit")));
+    TESTCASE(!iswctype(L'G',  wctype("xdigit")));
+    TESTCASE(!iswctype(L'x',  wctype("xdigit")));
+    TESTCASE(!iswctype(L'X',  wctype("xdigit")));
+    TESTCASE(!iswctype(L' ',  wctype("xdigit")));
+
+    return TEST_RESULTS;
+}
+#endif
index 127fe59b0bc7470bb9777e688d629ca225697466..31300cc2140d224453f069e9e0c32421b63701df 100644 (file)
@@ -1,52 +1,52 @@
-/* iswdigit( wint_t )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <wctype.h>\r
-#ifndef REGTEST\r
-#include "_PDCLIB_locale.h"\r
-\r
-int iswdigit( wint_t wc )\r
-{\r
-    return iswctype( wc, _PDCLIB_CTYPE_DIGIT );\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    TESTCASE(iswdigit(L'0'));\r
-    TESTCASE(iswdigit(L'1'));\r
-    TESTCASE(iswdigit(L'2'));\r
-    TESTCASE(iswdigit(L'3'));\r
-    TESTCASE(iswdigit(L'4'));\r
-    TESTCASE(iswdigit(L'5'));\r
-    TESTCASE(iswdigit(L'6'));\r
-    TESTCASE(iswdigit(L'7'));\r
-    TESTCASE(iswdigit(L'8'));\r
-    TESTCASE(iswdigit(L'9'));\r
-    TESTCASE(!iswdigit(L'a'));\r
-    TESTCASE(!iswdigit(L'b'));\r
-    TESTCASE(!iswdigit(L'c'));\r
-    TESTCASE(!iswdigit(L'd'));\r
-    TESTCASE(!iswdigit(L'e'));\r
-    TESTCASE(!iswdigit(L'f'));\r
-    TESTCASE(!iswdigit(L'A'));\r
-    TESTCASE(!iswdigit(L'B'));\r
-    TESTCASE(!iswdigit(L'C'));\r
-    TESTCASE(!iswdigit(L'D'));\r
-    TESTCASE(!iswdigit(L'E'));\r
-    TESTCASE(!iswdigit(L'F'));\r
-    TESTCASE(!iswdigit(L'g'));\r
-    TESTCASE(!iswdigit(L'G'));\r
-    TESTCASE(!iswdigit(L'x'));\r
-    TESTCASE(!iswdigit(L'X'));\r
-    TESTCASE(!iswdigit(L' '));\r
-    return TEST_RESULTS;\r
-}\r
-#endif\r
+/* iswdigit( wint_t )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <wctype.h>
+#ifndef REGTEST
+#include "_PDCLIB_locale.h"
+
+int iswdigit( wint_t wc )
+{
+    return iswctype( wc, _PDCLIB_CTYPE_DIGIT );
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    TESTCASE(iswdigit(L'0'));
+    TESTCASE(iswdigit(L'1'));
+    TESTCASE(iswdigit(L'2'));
+    TESTCASE(iswdigit(L'3'));
+    TESTCASE(iswdigit(L'4'));
+    TESTCASE(iswdigit(L'5'));
+    TESTCASE(iswdigit(L'6'));
+    TESTCASE(iswdigit(L'7'));
+    TESTCASE(iswdigit(L'8'));
+    TESTCASE(iswdigit(L'9'));
+    TESTCASE(!iswdigit(L'a'));
+    TESTCASE(!iswdigit(L'b'));
+    TESTCASE(!iswdigit(L'c'));
+    TESTCASE(!iswdigit(L'd'));
+    TESTCASE(!iswdigit(L'e'));
+    TESTCASE(!iswdigit(L'f'));
+    TESTCASE(!iswdigit(L'A'));
+    TESTCASE(!iswdigit(L'B'));
+    TESTCASE(!iswdigit(L'C'));
+    TESTCASE(!iswdigit(L'D'));
+    TESTCASE(!iswdigit(L'E'));
+    TESTCASE(!iswdigit(L'F'));
+    TESTCASE(!iswdigit(L'g'));
+    TESTCASE(!iswdigit(L'G'));
+    TESTCASE(!iswdigit(L'x'));
+    TESTCASE(!iswdigit(L'X'));
+    TESTCASE(!iswdigit(L' '));
+    return TEST_RESULTS;
+}
+#endif
index 8da4de642bc3f60eb727c4229ac41cd76a28bf1e..954844a2a58bf0ce1830808c1ee76fd062fd9a0e 100644 (file)
@@ -1,31 +1,31 @@
-/* iswgraph( wint_t )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <wctype.h>\r
-#ifndef REGTEST\r
-#include "_PDCLIB_locale.h"\r
-\r
-int iswgraph( wint_t wc )\r
-{\r
-    return iswctype( wc, _PDCLIB_CTYPE_GRAPH );\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    TESTCASE(iswgraph(L'a'));\r
-    TESTCASE(iswgraph(L'z'));\r
-    TESTCASE(iswgraph(L'E'));\r
-    TESTCASE(!iswgraph(L' '));\r
-    TESTCASE(!iswgraph(L'\t'));\r
-    TESTCASE(!iswgraph(L'\n'));\r
-    return TEST_RESULTS;\r
-}\r
-#endif\r
+/* iswgraph( wint_t )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <wctype.h>
+#ifndef REGTEST
+#include "_PDCLIB_locale.h"
+
+int iswgraph( wint_t wc )
+{
+    return iswctype( wc, _PDCLIB_CTYPE_GRAPH );
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    TESTCASE(iswgraph(L'a'));
+    TESTCASE(iswgraph(L'z'));
+    TESTCASE(iswgraph(L'E'));
+    TESTCASE(!iswgraph(L' '));
+    TESTCASE(!iswgraph(L'\t'));
+    TESTCASE(!iswgraph(L'\n'));
+    return TEST_RESULTS;
+}
+#endif
index 7639d4d704cfadf6f9b3c96c130754bb72ba7fd4..628ae64010cdc8d24f848382a495f3ceac66537d 100644 (file)
@@ -1,31 +1,31 @@
-/* iswalnum( wint_t )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <wctype.h>\r
-#ifndef REGTEST\r
-#include "_PDCLIB_locale.h"\r
-\r
-int iswlower( wint_t wc )\r
-{\r
-    return iswctype( wc, _PDCLIB_CTYPE_LOWER );\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    TESTCASE(iswlower(L'a'));\r
-    TESTCASE(iswlower(L'e'));\r
-    TESTCASE(iswlower(L'z'));\r
-    TESTCASE(!iswlower(L'A'));\r
-    TESTCASE(!iswlower(L'E'));\r
-    TESTCASE(!iswlower(L'Z'));\r
-    return TEST_RESULTS;\r
-}\r
-#endif\r
+/* iswalnum( wint_t )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <wctype.h>
+#ifndef REGTEST
+#include "_PDCLIB_locale.h"
+
+int iswlower( wint_t wc )
+{
+    return iswctype( wc, _PDCLIB_CTYPE_LOWER );
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    TESTCASE(iswlower(L'a'));
+    TESTCASE(iswlower(L'e'));
+    TESTCASE(iswlower(L'z'));
+    TESTCASE(!iswlower(L'A'));
+    TESTCASE(!iswlower(L'E'));
+    TESTCASE(!iswlower(L'Z'));
+    return TEST_RESULTS;
+}
+#endif
index 52d43988889ca954921dbca1e68b11ba76652838..395eb635af360863ce172fdab8538d895c20176c 100644 (file)
@@ -1,26 +1,26 @@
-/* iswprint( wint_t )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <wctype.h>\r
-#ifndef REGTEST\r
-#include "_PDCLIB_locale.h"\r
-\r
-int iswprint( wint_t wc )\r
-{\r
-    return iswctype( wc, _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_SPACE );\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-\r
-    return TEST_RESULTS;\r
-}\r
-#endif\r
+/* iswprint( wint_t )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <wctype.h>
+#ifndef REGTEST
+#include "_PDCLIB_locale.h"
+
+int iswprint( wint_t wc )
+{
+    return iswctype( wc, _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_SPACE );
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+
+    return TEST_RESULTS;
+}
+#endif
index b3fe83b8ed10c4556b7a6aa3c994fcbed6678e4e..c59672c44bcd984fdd75d8df10285ce70e7b0519 100644 (file)
@@ -1,31 +1,31 @@
-/* iswpunct( wint_t )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <wctype.h>\r
-#ifndef REGTEST\r
-#include "_PDCLIB_locale.h"\r
-\r
-int iswpunct( wint_t wc )\r
-{\r
-    return iswctype( wc, _PDCLIB_CTYPE_PUNCT );\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    TESTCASE(iswpunct(L';'));\r
-    TESTCASE(iswpunct(L'?'));\r
-    TESTCASE(iswpunct(L'.'));\r
-    TESTCASE(!iswpunct(L' '));\r
-    TESTCASE(!iswpunct(L'Z'));\r
-\r
-    return TEST_RESULTS;\r
-}\r
-#endif\r
+/* iswpunct( wint_t )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <wctype.h>
+#ifndef REGTEST
+#include "_PDCLIB_locale.h"
+
+int iswpunct( wint_t wc )
+{
+    return iswctype( wc, _PDCLIB_CTYPE_PUNCT );
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    TESTCASE(iswpunct(L';'));
+    TESTCASE(iswpunct(L'?'));
+    TESTCASE(iswpunct(L'.'));
+    TESTCASE(!iswpunct(L' '));
+    TESTCASE(!iswpunct(L'Z'));
+
+    return TEST_RESULTS;
+}
+#endif
index 85e30f3e43388aa6bfdd8a09cd80d1b41b04f9da..501a30139f82d14e738f029b36b3b32e0ad64bb7 100644 (file)
@@ -1,28 +1,28 @@
-/* iswspace( wint_t )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <wctype.h>\r
-#ifndef REGTEST\r
-#include "_PDCLIB_locale.h"\r
-\r
-int iswspace( wint_t wc )\r
-{\r
-    return iswctype( wc,  _PDCLIB_CTYPE_SPACE );\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    TESTCASE(iswspace(L' '));\r
-    TESTCASE(iswspace(L'\t'));\r
-    TESTCASE(!iswspace(L'a'));\r
-    return TEST_RESULTS;\r
-}\r
-#endif\r
+/* iswspace( wint_t )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <wctype.h>
+#ifndef REGTEST
+#include "_PDCLIB_locale.h"
+
+int iswspace( wint_t wc )
+{
+    return iswctype( wc,  _PDCLIB_CTYPE_SPACE );
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    TESTCASE(iswspace(L' '));
+    TESTCASE(iswspace(L'\t'));
+    TESTCASE(!iswspace(L'a'));
+    return TEST_RESULTS;
+}
+#endif
index eed40c7d3f1d58697801767ef652d184a1df02b8..4806a281b55b9039907fa8e1adbdd84442a545ca 100644 (file)
@@ -1,31 +1,31 @@
-/* iswupper( wint_t )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <wctype.h>\r
-#ifndef REGTEST\r
-#include "_PDCLIB_locale.h"\r
-\r
-int iswupper( wint_t wc )\r
-{\r
-    return iswctype( wc, _PDCLIB_CTYPE_UPPER );\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    TESTCASE(!iswupper(L'a'));\r
-    TESTCASE(!iswupper(L'e'));\r
-    TESTCASE(!iswupper(L'z'));\r
-    TESTCASE(iswupper(L'A'));\r
-    TESTCASE(iswupper(L'E'));\r
-    TESTCASE(iswupper(L'Z'));\r
-    return TEST_RESULTS;\r
-}\r
-#endif\r
+/* iswupper( wint_t )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <wctype.h>
+#ifndef REGTEST
+#include "_PDCLIB_locale.h"
+
+int iswupper( wint_t wc )
+{
+    return iswctype( wc, _PDCLIB_CTYPE_UPPER );
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    TESTCASE(!iswupper(L'a'));
+    TESTCASE(!iswupper(L'e'));
+    TESTCASE(!iswupper(L'z'));
+    TESTCASE(iswupper(L'A'));
+    TESTCASE(iswupper(L'E'));
+    TESTCASE(iswupper(L'Z'));
+    return TEST_RESULTS;
+}
+#endif
index b73440e277bb9761f51138fb39e5b9a597b13c74..3f51ae81bfcce73fcc315ea50d2075e326064f89 100644 (file)
@@ -1,52 +1,52 @@
-/* iswxdigit( wint_t )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <wctype.h>\r
-#ifndef REGTEST\r
-#include "_PDCLIB_locale.h"\r
-\r
-int iswxdigit( wint_t wc )\r
-{\r
-    return iswctype( wc, _PDCLIB_CTYPE_XDIGT );\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    TESTCASE(iswxdigit(L'0'));\r
-    TESTCASE(iswxdigit(L'1'));\r
-    TESTCASE(iswxdigit(L'2'));\r
-    TESTCASE(iswxdigit(L'3'));\r
-    TESTCASE(iswxdigit(L'4'));\r
-    TESTCASE(iswxdigit(L'5'));\r
-    TESTCASE(iswxdigit(L'6'));\r
-    TESTCASE(iswxdigit(L'7'));\r
-    TESTCASE(iswxdigit(L'8'));\r
-    TESTCASE(iswxdigit(L'9'));\r
-    TESTCASE(iswxdigit(L'a'));\r
-    TESTCASE(iswxdigit(L'b'));\r
-    TESTCASE(iswxdigit(L'c'));\r
-    TESTCASE(iswxdigit(L'd'));\r
-    TESTCASE(iswxdigit(L'e'));\r
-    TESTCASE(iswxdigit(L'f'));\r
-    TESTCASE(iswxdigit(L'A'));\r
-    TESTCASE(iswxdigit(L'B'));\r
-    TESTCASE(iswxdigit(L'C'));\r
-    TESTCASE(iswxdigit(L'D'));\r
-    TESTCASE(iswxdigit(L'E'));\r
-    TESTCASE(iswxdigit(L'F'));\r
-    TESTCASE(!iswxdigit(L'g'));\r
-    TESTCASE(!iswxdigit(L'G'));\r
-    TESTCASE(!iswxdigit(L'x'));\r
-    TESTCASE(!iswxdigit(L'X'));\r
-    TESTCASE(!iswxdigit(L' '));\r
-    return TEST_RESULTS;\r
-}\r
-#endif\r
+/* iswxdigit( wint_t )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <wctype.h>
+#ifndef REGTEST
+#include "_PDCLIB_locale.h"
+
+int iswxdigit( wint_t wc )
+{
+    return iswctype( wc, _PDCLIB_CTYPE_XDIGT );
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    TESTCASE(iswxdigit(L'0'));
+    TESTCASE(iswxdigit(L'1'));
+    TESTCASE(iswxdigit(L'2'));
+    TESTCASE(iswxdigit(L'3'));
+    TESTCASE(iswxdigit(L'4'));
+    TESTCASE(iswxdigit(L'5'));
+    TESTCASE(iswxdigit(L'6'));
+    TESTCASE(iswxdigit(L'7'));
+    TESTCASE(iswxdigit(L'8'));
+    TESTCASE(iswxdigit(L'9'));
+    TESTCASE(iswxdigit(L'a'));
+    TESTCASE(iswxdigit(L'b'));
+    TESTCASE(iswxdigit(L'c'));
+    TESTCASE(iswxdigit(L'd'));
+    TESTCASE(iswxdigit(L'e'));
+    TESTCASE(iswxdigit(L'f'));
+    TESTCASE(iswxdigit(L'A'));
+    TESTCASE(iswxdigit(L'B'));
+    TESTCASE(iswxdigit(L'C'));
+    TESTCASE(iswxdigit(L'D'));
+    TESTCASE(iswxdigit(L'E'));
+    TESTCASE(iswxdigit(L'F'));
+    TESTCASE(!iswxdigit(L'g'));
+    TESTCASE(!iswxdigit(L'G'));
+    TESTCASE(!iswxdigit(L'x'));
+    TESTCASE(!iswxdigit(L'X'));
+    TESTCASE(!iswxdigit(L' '));
+    return TEST_RESULTS;
+}
+#endif
index 5c1c0a2f460293c26880423bbfac229beed13e2c..1ecb2ff2b7c2d8f410d2dae86e356477ca9384ec 100644 (file)
@@ -1,42 +1,42 @@
-/* towctrans( wint_t, wctrans_t )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <wctype.h>\r
-#ifndef REGTEST\r
-#include <string.h>\r
-#include "_PDCLIB_locale.h"\r
-\r
-wint_t _PDCLIB_towctrans_l( wint_t wc, wctrans_t trans, locale_t l )\r
-{\r
-    switch( trans ) {\r
-        case 0:                         return wc;\r
-        case _PDCLIB_WCTRANS_TOLOWER:   return _PDCLIB_towlower_l( wc, l );\r
-        case _PDCLIB_WCTRANS_TOUPPER:   return _PDCLIB_towupper_l( wc, l );\r
-        default: abort();\r
-    }\r
-}\r
-\r
-wint_t towctrans( wint_t wc, wctrans_t trans )\r
-{\r
-    return _PDCLIB_towctrans_l( wc, trans, _PDCLIB_threadlocale() );\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    TESTCASE(towctrans(L'a', wctrans("toupper")) == L'A');\r
-    TESTCASE(towctrans(L'B', wctrans("toupper")) == L'B');\r
-    TESTCASE(towctrans(L'a', wctrans("tolower")) == L'a');\r
-    TESTCASE(towctrans(L'B', wctrans("tolower")) == L'b');\r
-    TESTCASE(towctrans(L'B', wctrans("invalid")) == L'B');\r
-    TESTCASE(towctrans(L'B', 0)                  == L'B');\r
-    return TEST_RESULTS;\r
-}\r
-#endif\r
+/* towctrans( wint_t, wctrans_t )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <wctype.h>
+#ifndef REGTEST
+#include <string.h>
+#include "_PDCLIB_locale.h"
+
+wint_t _PDCLIB_towctrans_l( wint_t wc, wctrans_t trans, locale_t l )
+{
+    switch( trans ) {
+        case 0:                         return wc;
+        case _PDCLIB_WCTRANS_TOLOWER:   return _PDCLIB_towlower_l( wc, l );
+        case _PDCLIB_WCTRANS_TOUPPER:   return _PDCLIB_towupper_l( wc, l );
+        default: abort();
+    }
+}
+
+wint_t towctrans( wint_t wc, wctrans_t trans )
+{
+    return _PDCLIB_towctrans_l( wc, trans, _PDCLIB_threadlocale() );
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    TESTCASE(towctrans(L'a', wctrans("toupper")) == L'A');
+    TESTCASE(towctrans(L'B', wctrans("toupper")) == L'B');
+    TESTCASE(towctrans(L'a', wctrans("tolower")) == L'a');
+    TESTCASE(towctrans(L'B', wctrans("tolower")) == L'b');
+    TESTCASE(towctrans(L'B', wctrans("invalid")) == L'B');
+    TESTCASE(towctrans(L'B', 0)                  == L'B');
+    return TEST_RESULTS;
+}
+#endif
index 666bf6b53e4e69bb0835cb6f26ca2249e1d24e50..b81e7579cada4b747f44b1cb902cbc34b54ba959 100644 (file)
@@ -1,41 +1,41 @@
-/* towlower( wint_t )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <wctype.h>\r
-#ifndef REGTEST\r
-#include "_PDCLIB_locale.h"\r
-\r
-wint_t _PDCLIB_towlower_l( wint_t wc, locale_t l )\r
-{\r
-    wint_t uwc = _PDCLIB_unpackwint( wc );\r
-    _PDCLIB_wcinfo_t *info = _PDCLIB_wcgetinfo( l, uwc );\r
-    if( info ) \r
-    {\r
-        uwc += info->lower_delta;\r
-    }\r
-    return uwc;\r
-}\r
-\r
-wint_t towlower( wint_t wc )\r
-{\r
-    return _PDCLIB_towlower_l( wc, _PDCLIB_threadlocale() );\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    TESTCASE(towlower(0) == 0);\r
-    TESTCASE(towlower(L'a') == L'a');\r
-    TESTCASE(towlower(L'B') == L'b');\r
-    TESTCASE(towlower(L'0') == L'0');\r
-\r
-    return TEST_RESULTS;\r
-}\r
-#endif\r
+/* towlower( wint_t )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <wctype.h>
+#ifndef REGTEST
+#include "_PDCLIB_locale.h"
+
+wint_t _PDCLIB_towlower_l( wint_t wc, locale_t l )
+{
+    wint_t uwc = _PDCLIB_unpackwint( wc );
+    _PDCLIB_wcinfo_t *info = _PDCLIB_wcgetinfo( l, uwc );
+    if( info ) 
+    {
+        uwc += info->lower_delta;
+    }
+    return uwc;
+}
+
+wint_t towlower( wint_t wc )
+{
+    return _PDCLIB_towlower_l( wc, _PDCLIB_threadlocale() );
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    TESTCASE(towlower(0) == 0);
+    TESTCASE(towlower(L'a') == L'a');
+    TESTCASE(towlower(L'B') == L'b');
+    TESTCASE(towlower(L'0') == L'0');
+
+    return TEST_RESULTS;
+}
+#endif
index e04ebc0f996e79fa9a10b5aa76cdfd49a76cae76..368ca2cdb526e32bc3b9c6d4e9f27e6fe296eb76 100644 (file)
@@ -1,41 +1,41 @@
-/* towupper( wint_t )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <wctype.h>\r
-#ifndef REGTEST\r
-#include "_PDCLIB_locale.h"\r
-\r
-wint_t _PDCLIB_towupper_l( wint_t wc, locale_t l )\r
-{\r
-    wint_t uwc = _PDCLIB_unpackwint( wc );\r
-    _PDCLIB_wcinfo_t *info = _PDCLIB_wcgetinfo( l, uwc );\r
-    if( info ) \r
-    {\r
-        uwc += info->upper_delta;\r
-    }\r
-    return uwc;\r
-}\r
-\r
-wint_t towupper( wint_t wc )\r
-{\r
-    return _PDCLIB_towupper_l( wc, _PDCLIB_threadlocale() );\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    TESTCASE(towupper(0) == 0);\r
-    TESTCASE(towupper(L'a') == L'A');\r
-    TESTCASE(towupper(L'B') == L'B');\r
-    TESTCASE(towupper(L'0') == L'0');\r
-\r
-    return TEST_RESULTS;\r
-}\r
-#endif\r
+/* towupper( wint_t )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <wctype.h>
+#ifndef REGTEST
+#include "_PDCLIB_locale.h"
+
+wint_t _PDCLIB_towupper_l( wint_t wc, locale_t l )
+{
+    wint_t uwc = _PDCLIB_unpackwint( wc );
+    _PDCLIB_wcinfo_t *info = _PDCLIB_wcgetinfo( l, uwc );
+    if( info ) 
+    {
+        uwc += info->upper_delta;
+    }
+    return uwc;
+}
+
+wint_t towupper( wint_t wc )
+{
+    return _PDCLIB_towupper_l( wc, _PDCLIB_threadlocale() );
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    TESTCASE(towupper(0) == 0);
+    TESTCASE(towupper(L'a') == L'A');
+    TESTCASE(towupper(L'B') == L'B');
+    TESTCASE(towupper(L'0') == L'0');
+
+    return TEST_RESULTS;
+}
+#endif
index efc18bfad95591aec928794c5ef71f0f56e8c3d7..c15bde085c7009b007beb616f8bfba1e0dd1533d 100644 (file)
@@ -1,38 +1,38 @@
-/* wctrans( const char * )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <wctype.h>\r
-#ifndef REGTEST\r
-#include <string.h>\r
-#include "_PDCLIB_locale.h"\r
-\r
-wctrans_t wctrans( const char * property )\r
-{\r
-    if(!property) {\r
-        return 0;\r
-    } else if(strcmp(property, "tolower") == 0) {\r
-        return _PDCLIB_WCTRANS_TOLOWER;\r
-    } else if(strcmp(property, "toupper") == 0) {\r
-        return _PDCLIB_WCTRANS_TOUPPER;\r
-    } else {\r
-        return 0;\r
-    }\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    TESTCASE(wctrans("") == 0);\r
-    TESTCASE(wctrans("invalid") == 0);\r
-    TESTCASE(wctrans("toupper") != 0);\r
-    TESTCASE(wctrans("tolower") != 0);\r
-    return TEST_RESULTS;\r
-}\r
-#endif\r
+/* wctrans( const char * )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <wctype.h>
+#ifndef REGTEST
+#include <string.h>
+#include "_PDCLIB_locale.h"
+
+wctrans_t wctrans( const char * property )
+{
+    if(!property) {
+        return 0;
+    } else if(strcmp(property, "tolower") == 0) {
+        return _PDCLIB_WCTRANS_TOLOWER;
+    } else if(strcmp(property, "toupper") == 0) {
+        return _PDCLIB_WCTRANS_TOUPPER;
+    } else {
+        return 0;
+    }
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    TESTCASE(wctrans("") == 0);
+    TESTCASE(wctrans("invalid") == 0);
+    TESTCASE(wctrans("toupper") != 0);
+    TESTCASE(wctrans("tolower") != 0);
+    return TEST_RESULTS;
+}
+#endif
index c07fc0f2682b200b3ba512c7dbdca7992f8a2ff8..3e8aa1f1234849af217fa4c8dc75a374a1f3ee18 100644 (file)
-/* wctype( const char * )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <wctype.h>\r
-#ifndef REGTEST\r
-#include <string.h>\r
-#include "_PDCLIB_locale.h"\r
-\r
-wctype_t wctype( const char * property )\r
-{\r
-    if(property) switch(property[0])\r
-    {\r
-        case 'a':\r
-            if(strcmp(property, "alpha") == 0) {\r
-                return _PDCLIB_CTYPE_ALPHA;\r
-            } else if(strcmp(property, "alnum") == 0) {\r
-                return _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_DIGIT;\r
-            } else return 0;\r
-\r
-        case 'b':\r
-            if(strcmp(property, "blank") == 0) {\r
-                return _PDCLIB_CTYPE_BLANK;\r
-            } else return 0;\r
-\r
-        case 'c':\r
-            if(strcmp(property, "cntrl") == 0) {\r
-                return _PDCLIB_CTYPE_CNTRL;\r
-            } else return 0;\r
-\r
-        case 'd':\r
-            if(strcmp(property, "digit") == 0) {\r
-                return _PDCLIB_CTYPE_DIGIT;\r
-            } else return 0;\r
-\r
-        case 'g':\r
-            if(strcmp(property, "graph") == 0) {\r
-                return _PDCLIB_CTYPE_GRAPH;\r
-            } else return 0;\r
-\r
-        case 'l':\r
-            if(strcmp(property, "lower") == 0) {\r
-                return _PDCLIB_CTYPE_LOWER;\r
-            } else return 0;\r
-\r
-        case 'p':\r
-            if(strcmp(property, "print") == 0) {\r
-                return _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_SPACE;\r
-            } else if(strcmp(property, "punct") == 0) {\r
-                return _PDCLIB_CTYPE_PUNCT;\r
-            } else return 0;\r
-\r
-        case 's':\r
-            if(strcmp(property, "space") == 0) {\r
-                return _PDCLIB_CTYPE_SPACE;\r
-            } else return 0;\r
-\r
-        case 'u':\r
-            if(strcmp(property, "upper") == 0) {\r
-                return _PDCLIB_CTYPE_UPPER;\r
-            } else return 0;\r
-\r
-        case 'x':\r
-            if(strcmp(property, "xdigit") == 0) {\r
-                return _PDCLIB_CTYPE_XDIGT;\r
-            } else return 0;\r
-    }\r
-    return 0;\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    TESTCASE(wctype("")   == 0);\r
-    TESTCASE_NOREG(wctype(NULL) == 0); // mingw libc crashes on this\r
-\r
-    TESTCASE(wctype("alpha")  != 0);\r
-    TESTCASE(wctype("alnum")  != 0);\r
-    TESTCASE(wctype("blank")  != 0);\r
-    TESTCASE(wctype("cntrl")  != 0);\r
-    TESTCASE(wctype("digit")  != 0);\r
-    TESTCASE(wctype("graph")  != 0);\r
-    TESTCASE(wctype("lower")  != 0);\r
-    TESTCASE(wctype("print")  != 0);\r
-    TESTCASE(wctype("punct")  != 0);\r
-    TESTCASE(wctype("space")  != 0);\r
-    TESTCASE(wctype("upper")  != 0);\r
-    TESTCASE(wctype("xdigit") != 0);\r
-\r
-    TESTCASE_NOREG(wctype("alpha")  == _PDCLIB_CTYPE_ALPHA);\r
-    TESTCASE_NOREG(wctype("alnum")  == (_PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_DIGIT));\r
-    TESTCASE_NOREG(wctype("blank")  == _PDCLIB_CTYPE_BLANK);\r
-    TESTCASE_NOREG(wctype("cntrl")  == _PDCLIB_CTYPE_CNTRL);\r
-    TESTCASE_NOREG(wctype("digit")  == _PDCLIB_CTYPE_DIGIT);\r
-    TESTCASE_NOREG(wctype("graph")  == _PDCLIB_CTYPE_GRAPH);\r
-    TESTCASE_NOREG(wctype("lower")  == _PDCLIB_CTYPE_LOWER);\r
-    TESTCASE_NOREG(wctype("print")  == (_PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_SPACE));\r
-    TESTCASE_NOREG(wctype("punct")  == _PDCLIB_CTYPE_PUNCT);\r
-    TESTCASE_NOREG(wctype("space")  == _PDCLIB_CTYPE_SPACE);\r
-    TESTCASE_NOREG(wctype("upper")  == _PDCLIB_CTYPE_UPPER);\r
-    TESTCASE_NOREG(wctype("xdigit") == _PDCLIB_CTYPE_XDIGT);\r
-    return TEST_RESULTS;\r
-}\r
-#endif\r
+/* wctype( const char * )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <wctype.h>
+#ifndef REGTEST
+#include <string.h>
+#include "_PDCLIB_locale.h"
+
+wctype_t wctype( const char * property )
+{
+    if(property) switch(property[0])
+    {
+        case 'a':
+            if(strcmp(property, "alpha") == 0) {
+                return _PDCLIB_CTYPE_ALPHA;
+            } else if(strcmp(property, "alnum") == 0) {
+                return _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_DIGIT;
+            } else return 0;
+
+        case 'b':
+            if(strcmp(property, "blank") == 0) {
+                return _PDCLIB_CTYPE_BLANK;
+            } else return 0;
+
+        case 'c':
+            if(strcmp(property, "cntrl") == 0) {
+                return _PDCLIB_CTYPE_CNTRL;
+            } else return 0;
+
+        case 'd':
+            if(strcmp(property, "digit") == 0) {
+                return _PDCLIB_CTYPE_DIGIT;
+            } else return 0;
+
+        case 'g':
+            if(strcmp(property, "graph") == 0) {
+                return _PDCLIB_CTYPE_GRAPH;
+            } else return 0;
+
+        case 'l':
+            if(strcmp(property, "lower") == 0) {
+                return _PDCLIB_CTYPE_LOWER;
+            } else return 0;
+
+        case 'p':
+            if(strcmp(property, "print") == 0) {
+                return _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_SPACE;
+            } else if(strcmp(property, "punct") == 0) {
+                return _PDCLIB_CTYPE_PUNCT;
+            } else return 0;
+
+        case 's':
+            if(strcmp(property, "space") == 0) {
+                return _PDCLIB_CTYPE_SPACE;
+            } else return 0;
+
+        case 'u':
+            if(strcmp(property, "upper") == 0) {
+                return _PDCLIB_CTYPE_UPPER;
+            } else return 0;
+
+        case 'x':
+            if(strcmp(property, "xdigit") == 0) {
+                return _PDCLIB_CTYPE_XDIGT;
+            } else return 0;
+    }
+    return 0;
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    TESTCASE(wctype("")   == 0);
+    TESTCASE_NOREG(wctype(NULL) == 0); // mingw libc crashes on this
+
+    TESTCASE(wctype("alpha")  != 0);
+    TESTCASE(wctype("alnum")  != 0);
+    TESTCASE(wctype("blank")  != 0);
+    TESTCASE(wctype("cntrl")  != 0);
+    TESTCASE(wctype("digit")  != 0);
+    TESTCASE(wctype("graph")  != 0);
+    TESTCASE(wctype("lower")  != 0);
+    TESTCASE(wctype("print")  != 0);
+    TESTCASE(wctype("punct")  != 0);
+    TESTCASE(wctype("space")  != 0);
+    TESTCASE(wctype("upper")  != 0);
+    TESTCASE(wctype("xdigit") != 0);
+
+    TESTCASE_NOREG(wctype("alpha")  == _PDCLIB_CTYPE_ALPHA);
+    TESTCASE_NOREG(wctype("alnum")  == (_PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_DIGIT));
+    TESTCASE_NOREG(wctype("blank")  == _PDCLIB_CTYPE_BLANK);
+    TESTCASE_NOREG(wctype("cntrl")  == _PDCLIB_CTYPE_CNTRL);
+    TESTCASE_NOREG(wctype("digit")  == _PDCLIB_CTYPE_DIGIT);
+    TESTCASE_NOREG(wctype("graph")  == _PDCLIB_CTYPE_GRAPH);
+    TESTCASE_NOREG(wctype("lower")  == _PDCLIB_CTYPE_LOWER);
+    TESTCASE_NOREG(wctype("print")  == (_PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_SPACE));
+    TESTCASE_NOREG(wctype("punct")  == _PDCLIB_CTYPE_PUNCT);
+    TESTCASE_NOREG(wctype("space")  == _PDCLIB_CTYPE_SPACE);
+    TESTCASE_NOREG(wctype("upper")  == _PDCLIB_CTYPE_UPPER);
+    TESTCASE_NOREG(wctype("xdigit") == _PDCLIB_CTYPE_XDIGT);
+    return TEST_RESULTS;
+}
+#endif
index 20d7d731937a09941d73f4ee52dfe018e8725f76..d349538c4943fd4987852a9322ce479ed9c51309 100644 (file)
-/*\r
- * This is an example style-sheet provided for mandoc(1) and the -Thtml\r
- * or -Txhtml output mode.\r
- *\r
- * It mimics the appearance of the traditional cvsweb output.\r
- *\r
- * See mdoc(7) and man(7) for macro explanations.\r
- */\r
-\r
-/* modified for pdclib: no max width; our wrapper handles that */;\r
-\r
-html        { margin-left: 1em; }\r
-body        { font-size: smaller; font-family: Helvetica,Arial,sans-serif; }\r
-h1      { margin-bottom: 1ex; font-size: 110%; margin-left: -4ex; } /* Section header (Sh, SH). */\r
-h2      { margin-bottom: 1ex; font-size: 105%; margin-left: -2ex; } /* Sub-section header (Ss, SS). */\r
-table       { width: 100%; margin-top: 0ex; margin-bottom: 0ex; } /* All tables. */\r
-td      { vertical-align: top; } /* All table cells. */\r
-p       { } /* Paragraph: Pp, Lp. */\r
-blockquote  { margin-left: 5ex; margin-top: 0ex; margin-bottom: 0ex; } /* D1. */\r
-div.section { margin-bottom: 2ex; margin-left: 5ex; } /* Sections (Sh, SH). */\r
-div.subsection  { } /* Sub-sections (Ss, SS). */\r
-table.synopsis  { } /* SYNOPSIS section table. */\r
-\r
-/* Preamble structure. */\r
-\r
-table.foot  { font-size: smaller; margin-top: 1em; border-top: 1px dotted #dddddd; } /* Document footer. */\r
-td.foot-date    { width: 50%; } /* Document footer: date. */\r
-td.foot-os  { width: 50%; text-align: right; } /* Document footer: OS/source. */\r
-table.head  { font-size: smaller; margin-bottom: 1em; border-bottom: 1px dotted #dddddd; } /* Document header. */\r
-td.head-ltitle  { width: 10%; } /* Document header: left-title. */\r
-td.head-vol { width: 80%; text-align: center; } /* Document header: volume. */\r
-td.head-rtitle  { width: 10%; text-align: right; } /* Document header: right-title. */\r
-\r
-/* General font modes. */\r
-\r
-i       { } /* Italic: BI, IB, I, (implicit). */\r
-.emph       { font-style: italic; font-weight: normal; } /* Emphasis: Em, Bl -emphasis. */\r
-b       { } /* Bold: SB, BI, IB, BR, RB, B, (implicit). */\r
-.symb       { font-style: normal; font-weight: bold; } /* Symbolic: Sy, Ms, Bf -symbolic. */\r
-small       { } /* Small: SB, SM. */\r
-.lit        { font-style: normal; font-weight: normal; font-family: monospace; } /* Literal: Dl, Li, Ql, Bf -literal, Bl -literal, Bl -unfilled. */\r
-\r
-/* Block modes. */\r
-\r
-.display    { } /* Top of all Bd, D1, Dl. */\r
-.list       { } /* Top of all Bl. */\r
-\r
-/* Context-specific modes. */\r
-\r
-i.addr      { font-weight: normal; } /* Address (Ad). */\r
-i.arg       { font-weight: normal; } /* Command argument (Ar). */\r
-span.author { } /* Author name (An). */\r
-b.cmd       { font-style: normal; } /* Command (Cm). */ \r
-b.config    { font-style: normal; } /* Config statement (Cd). */\r
-span.define { } /* Defines (Dv). */\r
-span.desc   { } /* Nd.  After em-dash. */\r
-b.diag      { font-style: normal; } /* Diagnostic (Bl -diag). */\r
-span.env    { } /* Environment variables (Ev). */\r
-span.errno  { } /* Error string (Er). */\r
-i.farg      { font-weight: normal; } /* Function argument (Fa, Fn). */\r
-i.file      { font-weight: normal; } /* File (Pa). */\r
-b.flag      { font-style: normal; } /* Flag (Fl, Cm). */\r
-b.fname     { font-style: normal; } /* Function name (Fa, Fn, Rv). */\r
-i.ftype     { font-weight: normal; } /* Function types (Ft, Fn). */\r
-b.includes  { font-style: normal; } /* Header includes (In). */\r
-span.lib    { } /* Library (Lb). */\r
-i.link-sec  { font-weight: normal; } /* Section links (Sx). */\r
-b.macro     { font-style: normal; } /* Macro-ish thing (Fd). */\r
-b.name      { font-style: normal; } /* Name of utility (Nm). */\r
-span.opt    { } /* Options (Op, Oo/Oc). */\r
-span.ref    { } /* Citations (Rs). */\r
-span.ref-auth   { } /* Reference author (%A). */\r
-i.ref-book  { font-weight: normal; } /* Reference book (%B). */\r
-span.ref-city   { } /* Reference city (%C). */\r
-span.ref-date   { } /* Reference date (%D). */\r
-i.ref-issue { font-weight: normal; } /* Reference issuer/publisher (%I). */\r
-i.ref-jrnl  { font-weight: normal; } /* Reference journal (%J). */\r
-span.ref-num    { } /* Reference number (%N). */\r
-span.ref-opt    { } /* Reference optionals (%O). */\r
-span.ref-page   { } /* Reference page (%P). */\r
-span.ref-corp   { } /* Reference corporate/foreign author (%Q). */\r
-span.ref-rep    { } /* Reference report (%R). */\r
-span.ref-title  { text-decoration: underline; } /* Reference title (%T). */\r
-span.ref-vol    { } /* Reference volume (%V). */\r
-span.type   { font-style: italic; font-weight: normal; } /* Variable types (Vt). */\r
-span.unix   { } /* Unices (Ux, Ox, Nx, Fx, Bx, Bsx, Dx). */\r
-b.utility   { font-style: normal; } /* Name of utility (Ex). */\r
-b.var       { font-style: normal; } /* Variables (Rv). */\r
-\r
-a.link-ext  { } /* Off-site link (Lk). */\r
-a.link-includes { } /* Include-file link (In). */\r
-a.link-mail { } /* Mailto links (Mt). */\r
-a.link-man  { } /* Manual links (Xr). */\r
-a.link-ref  { } /* Reference section links (%Q). */\r
-a.link-sec  { } /* Section links (Sx). */\r
-\r
-/* Formatting for lists.  See mdoc(7). */\r
-\r
-dl.list-diag    { }\r
-dt.list-diag    { }\r
-dd.list-diag    { }\r
-\r
-dl.list-hang    { }\r
-dt.list-hang    { }\r
-dd.list-hang    { }\r
-\r
-dl.list-inset   { }\r
-dt.list-inset   { }\r
-dd.list-inset   { }\r
-\r
-dl.list-ohang   { }\r
-dt.list-ohang   { }\r
-dd.list-ohang   { margin-left: 0ex; }\r
-\r
-dl.list-tag { }\r
-dt.list-tag { }\r
-dd.list-tag { }\r
-\r
-table.list-col  { }\r
-tr.list-col { }\r
-td.list-col { }\r
-\r
-ul.list-bul { list-style-type: disc; padding-left: 1em; }\r
-li.list-bul { }\r
-\r
-ul.list-dash    { list-style-type: none; padding-left: 0em; }\r
-li.list-dash:before { content: "\2014  "; }\r
-\r
-ul.list-hyph    { list-style-type: none; padding-left: 0em; }\r
-li.list-hyph:before { content: "\2013  "; }\r
-\r
-ul.list-item    { list-style-type: none; padding-left: 0em; }\r
-li.list-item    { }\r
-\r
-ol.list-enum    { padding-left: 2em; }\r
-li.list-enum    { }\r
-\r
-/* Equation modes.  See eqn(7). */\r
-\r
-span.eqn    { }\r
-\r
-/* Table modes.  See tbl(7). */\r
-\r
+/*
+ * This is an example style-sheet provided for mandoc(1) and the -Thtml
+ * or -Txhtml output mode.
+ *
+ * It mimics the appearance of the traditional cvsweb output.
+ *
+ * See mdoc(7) and man(7) for macro explanations.
+ */
+
+/* modified for pdclib: no max width; our wrapper handles that */;
+
+html        { margin-left: 1em; }
+body        { font-size: smaller; font-family: Helvetica,Arial,sans-serif; }
+h1      { margin-bottom: 1ex; font-size: 110%; margin-left: -4ex; } /* Section header (Sh, SH). */
+h2      { margin-bottom: 1ex; font-size: 105%; margin-left: -2ex; } /* Sub-section header (Ss, SS). */
+table       { width: 100%; margin-top: 0ex; margin-bottom: 0ex; } /* All tables. */
+td      { vertical-align: top; } /* All table cells. */
+p       { } /* Paragraph: Pp, Lp. */
+blockquote  { margin-left: 5ex; margin-top: 0ex; margin-bottom: 0ex; } /* D1. */
+div.section { margin-bottom: 2ex; margin-left: 5ex; } /* Sections (Sh, SH). */
+div.subsection  { } /* Sub-sections (Ss, SS). */
+table.synopsis  { } /* SYNOPSIS section table. */
+
+/* Preamble structure. */
+
+table.foot  { font-size: smaller; margin-top: 1em; border-top: 1px dotted #dddddd; } /* Document footer. */
+td.foot-date    { width: 50%; } /* Document footer: date. */
+td.foot-os  { width: 50%; text-align: right; } /* Document footer: OS/source. */
+table.head  { font-size: smaller; margin-bottom: 1em; border-bottom: 1px dotted #dddddd; } /* Document header. */
+td.head-ltitle  { width: 10%; } /* Document header: left-title. */
+td.head-vol { width: 80%; text-align: center; } /* Document header: volume. */
+td.head-rtitle  { width: 10%; text-align: right; } /* Document header: right-title. */
+
+/* General font modes. */
+
+i       { } /* Italic: BI, IB, I, (implicit). */
+.emph       { font-style: italic; font-weight: normal; } /* Emphasis: Em, Bl -emphasis. */
+b       { } /* Bold: SB, BI, IB, BR, RB, B, (implicit). */
+.symb       { font-style: normal; font-weight: bold; } /* Symbolic: Sy, Ms, Bf -symbolic. */
+small       { } /* Small: SB, SM. */
+.lit        { font-style: normal; font-weight: normal; font-family: monospace; } /* Literal: Dl, Li, Ql, Bf -literal, Bl -literal, Bl -unfilled. */
+
+/* Block modes. */
+
+.display    { } /* Top of all Bd, D1, Dl. */
+.list       { } /* Top of all Bl. */
+
+/* Context-specific modes. */
+
+i.addr      { font-weight: normal; } /* Address (Ad). */
+i.arg       { font-weight: normal; } /* Command argument (Ar). */
+span.author { } /* Author name (An). */
+b.cmd       { font-style: normal; } /* Command (Cm). */ 
+b.config    { font-style: normal; } /* Config statement (Cd). */
+span.define { } /* Defines (Dv). */
+span.desc   { } /* Nd.  After em-dash. */
+b.diag      { font-style: normal; } /* Diagnostic (Bl -diag). */
+span.env    { } /* Environment variables (Ev). */
+span.errno  { } /* Error string (Er). */
+i.farg      { font-weight: normal; } /* Function argument (Fa, Fn). */
+i.file      { font-weight: normal; } /* File (Pa). */
+b.flag      { font-style: normal; } /* Flag (Fl, Cm). */
+b.fname     { font-style: normal; } /* Function name (Fa, Fn, Rv). */
+i.ftype     { font-weight: normal; } /* Function types (Ft, Fn). */
+b.includes  { font-style: normal; } /* Header includes (In). */
+span.lib    { } /* Library (Lb). */
+i.link-sec  { font-weight: normal; } /* Section links (Sx). */
+b.macro     { font-style: normal; } /* Macro-ish thing (Fd). */
+b.name      { font-style: normal; } /* Name of utility (Nm). */
+span.opt    { } /* Options (Op, Oo/Oc). */
+span.ref    { } /* Citations (Rs). */
+span.ref-auth   { } /* Reference author (%A). */
+i.ref-book  { font-weight: normal; } /* Reference book (%B). */
+span.ref-city   { } /* Reference city (%C). */
+span.ref-date   { } /* Reference date (%D). */
+i.ref-issue { font-weight: normal; } /* Reference issuer/publisher (%I). */
+i.ref-jrnl  { font-weight: normal; } /* Reference journal (%J). */
+span.ref-num    { } /* Reference number (%N). */
+span.ref-opt    { } /* Reference optionals (%O). */
+span.ref-page   { } /* Reference page (%P). */
+span.ref-corp   { } /* Reference corporate/foreign author (%Q). */
+span.ref-rep    { } /* Reference report (%R). */
+span.ref-title  { text-decoration: underline; } /* Reference title (%T). */
+span.ref-vol    { } /* Reference volume (%V). */
+span.type   { font-style: italic; font-weight: normal; } /* Variable types (Vt). */
+span.unix   { } /* Unices (Ux, Ox, Nx, Fx, Bx, Bsx, Dx). */
+b.utility   { font-style: normal; } /* Name of utility (Ex). */
+b.var       { font-style: normal; } /* Variables (Rv). */
+
+a.link-ext  { } /* Off-site link (Lk). */
+a.link-includes { } /* Include-file link (In). */
+a.link-mail { } /* Mailto links (Mt). */
+a.link-man  { } /* Manual links (Xr). */
+a.link-ref  { } /* Reference section links (%Q). */
+a.link-sec  { } /* Section links (Sx). */
+
+/* Formatting for lists.  See mdoc(7). */
+
+dl.list-diag    { }
+dt.list-diag    { }
+dd.list-diag    { }
+
+dl.list-hang    { }
+dt.list-hang    { }
+dd.list-hang    { }
+
+dl.list-inset   { }
+dt.list-inset   { }
+dd.list-inset   { }
+
+dl.list-ohang   { }
+dt.list-ohang   { }
+dd.list-ohang   { margin-left: 0ex; }
+
+dl.list-tag { }
+dt.list-tag { }
+dd.list-tag { }
+
+table.list-col  { }
+tr.list-col { }
+td.list-col { }
+
+ul.list-bul { list-style-type: disc; padding-left: 1em; }
+li.list-bul { }
+
+ul.list-dash    { list-style-type: none; padding-left: 0em; }
+li.list-dash:before { content: "\2014  "; }
+
+ul.list-hyph    { list-style-type: none; padding-left: 0em; }
+li.list-hyph:before { content: "\2013  "; }
+
+ul.list-item    { list-style-type: none; padding-left: 0em; }
+li.list-item    { }
+
+ol.list-enum    { padding-left: 2em; }
+li.list-enum    { }
+
+/* Equation modes.  See eqn(7). */
+
+span.eqn    { }
+
+/* Table modes.  See tbl(7). */
+
 table.tbl   { }
\ No newline at end of file
index 59dbf547a9bdce9aa0aeea38430e096ae4afa08b..1d6f89dc3b2c0b50bcfab4682429191067381840 100644 (file)
-/* Characteristics of floating types <float.h>\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#ifndef _PDCLIB_FLOAT_H\r
-#define _PDCLIB_FLOAT_H _PDCLIB_FLOAT_H\r
-#include "_PDCLIB_float.h"\r
-\r
-#define FLT_ROUNDS      _PDCLIB_FLT_ROUNDS\r
-#define FLT_EVAL_METHOD _PDCLIB_FLT_EVAL_METHOD\r
-#define DECIMAL_DIG     _PDCLIB_DECIMAL_DIG\r
-\r
-/* Radix of exponent representation */\r
-#define FLT_RADIX       _PDCLIB_FLT_RADIX\r
-\r
-/* Number of base-FLT_RADIX digits in the significand of a float */\r
-#define FLT_MANT_DIG    _PDCLIB_FLT_MANT_DIG\r
-\r
-/* Number of decimal digits of precision in a float */\r
-#define FLT_DIG         _PDCLIB_FLT_DIG\r
-\r
-/* Difference between 1.0 and the minimum float greater than 1.0 */\r
-#define FLT_EPSILON     _PDCLIB_FLT_EPSILON\r
-\r
-/* Minimum int x such that FLT_RADIX**(x-1) is a normalised float */\r
-#define FLT_MIN_EXP     _PDCLIB_FLT_MIN_EXP\r
-\r
-/* Minimum normalised float */\r
-#define FLT_MIN         _PDCLIB_FLT_MIN\r
-\r
-/* Minimum int x such that 10**x is a normalised float */\r
-#define FLT_MIN_10_EXP  _PDCLIB_FLT_MIN_10_EXP\r
-\r
-/* Maximum int x such that FLT_RADIX**(x-1) is a representable float */\r
-#define FLT_MAX_EXP     _PDCLIB_FLT_MAX_EXP\r
-\r
-/* Maximum float */\r
-#define FLT_MAX         _PDCLIB_FLT_MAX\r
-\r
-/* Maximum int x such that 10**x is a representable float */\r
-#define FLT_MAX_10_EXP  _PDCLIB_FLT_MAX_10_EXP\r
-\r
-\r
-/* Number of base-FLT_RADIX digits in the significand of a double */\r
-#define DBL_MANT_DIG    _PDCLIB_DBL_MANT_DIG\r
-\r
-/* Number of decimal digits of precision in a double */\r
-#define DBL_DIG         _PDCLIB_DBL_DIG\r
-\r
-/* Difference between 1.0 and the minimum double greater than 1.0 */\r
-#define DBL_EPSILON     _PDCLIB_DBL_EPSILON\r
-\r
-/* Minimum int x such that FLT_RADIX**(x-1) is a normalised double */\r
-#define DBL_MIN_EXP     _PDCLIB_DBL_MIN_EXP\r
-\r
-/* Minimum normalised double */\r
-#define DBL_MIN         _PDCLIB_DBL_MIN\r
-\r
-/* Minimum int x such that 10**x is a normalised double */\r
-#define DBL_MIN_10_EXP  _PDCLIB_DBL_MIN_10_EXP\r
-\r
-/* Maximum int x such that FLT_RADIX**(x-1) is a representable double */\r
-#define DBL_MAX_EXP     _PDCLIB_DBL_MAX_EXP\r
-\r
-/* Maximum double */\r
-#define DBL_MAX         _PDCLIB_DBL_MAX\r
-\r
-/* Maximum int x such that 10**x is a representable double */\r
-#define DBL_MAX_10_EXP  _PDCLIB_DBL_MAX_10_EXP\r
-\r
-\r
-/* Number of base-FLT_RADIX digits in the significand of a long double */\r
-#define LDBL_MANT_DIG   _PDCLIB_LDBL_MANT_DIG\r
-\r
-/* Number of decimal digits of precision in a long double */\r
-#define LDBL_DIG        _PDCLIB_LDBL_DIG\r
-\r
-/* Difference between 1.0 and the minimum long double greater than 1.0 */\r
-#define LDBL_EPSILON    _PDCLIB_LDBL_EPSILON\r
-\r
-/* Minimum int x such that FLT_RADIX**(x-1) is a normalised long double */\r
-#define LDBL_MIN_EXP    _PDCLIB_LDBL_MIN_EXP\r
-\r
-/* Minimum normalised long double */\r
-#define LDBL_MIN        _PDCLIB_LDBL_MIN\r
-\r
-/* Minimum int x such that 10**x is a normalised long double */\r
-#define LDBL_MIN_10_EXP _PDCLIB_LDBL_MIN_10_EXP\r
-\r
-/* Maximum int x such that FLT_RADIX**(x-1) is a representable long double */\r
-#define LDBL_MAX_EXP    _PDCLIB_LDBL_MAX_EXP\r
-\r
-/* Maximum long double */\r
-#define LDBL_MAX        _PDCLIB_LDBL_MAX\r
-\r
-/* Maximum int x such that 10**x is a representable long double */\r
-#define LDBL_MAX_10_EXP _PDCLIB_LDBL_MAX_10_EXP\r
-\r
-#endif\r
+/* Characteristics of floating types <float.h>
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#ifndef _PDCLIB_FLOAT_H
+#define _PDCLIB_FLOAT_H _PDCLIB_FLOAT_H
+#include "_PDCLIB_float.h"
+
+#define FLT_ROUNDS      _PDCLIB_FLT_ROUNDS
+#define FLT_EVAL_METHOD _PDCLIB_FLT_EVAL_METHOD
+#define DECIMAL_DIG     _PDCLIB_DECIMAL_DIG
+
+/* Radix of exponent representation */
+#define FLT_RADIX       _PDCLIB_FLT_RADIX
+
+/* Number of base-FLT_RADIX digits in the significand of a float */
+#define FLT_MANT_DIG    _PDCLIB_FLT_MANT_DIG
+
+/* Number of decimal digits of precision in a float */
+#define FLT_DIG         _PDCLIB_FLT_DIG
+
+/* Difference between 1.0 and the minimum float greater than 1.0 */
+#define FLT_EPSILON     _PDCLIB_FLT_EPSILON
+
+/* Minimum int x such that FLT_RADIX**(x-1) is a normalised float */
+#define FLT_MIN_EXP     _PDCLIB_FLT_MIN_EXP
+
+/* Minimum normalised float */
+#define FLT_MIN         _PDCLIB_FLT_MIN
+
+/* Minimum int x such that 10**x is a normalised float */
+#define FLT_MIN_10_EXP  _PDCLIB_FLT_MIN_10_EXP
+
+/* Maximum int x such that FLT_RADIX**(x-1) is a representable float */
+#define FLT_MAX_EXP     _PDCLIB_FLT_MAX_EXP
+
+/* Maximum float */
+#define FLT_MAX         _PDCLIB_FLT_MAX
+
+/* Maximum int x such that 10**x is a representable float */
+#define FLT_MAX_10_EXP  _PDCLIB_FLT_MAX_10_EXP
+
+
+/* Number of base-FLT_RADIX digits in the significand of a double */
+#define DBL_MANT_DIG    _PDCLIB_DBL_MANT_DIG
+
+/* Number of decimal digits of precision in a double */
+#define DBL_DIG         _PDCLIB_DBL_DIG
+
+/* Difference between 1.0 and the minimum double greater than 1.0 */
+#define DBL_EPSILON     _PDCLIB_DBL_EPSILON
+
+/* Minimum int x such that FLT_RADIX**(x-1) is a normalised double */
+#define DBL_MIN_EXP     _PDCLIB_DBL_MIN_EXP
+
+/* Minimum normalised double */
+#define DBL_MIN         _PDCLIB_DBL_MIN
+
+/* Minimum int x such that 10**x is a normalised double */
+#define DBL_MIN_10_EXP  _PDCLIB_DBL_MIN_10_EXP
+
+/* Maximum int x such that FLT_RADIX**(x-1) is a representable double */
+#define DBL_MAX_EXP     _PDCLIB_DBL_MAX_EXP
+
+/* Maximum double */
+#define DBL_MAX         _PDCLIB_DBL_MAX
+
+/* Maximum int x such that 10**x is a representable double */
+#define DBL_MAX_10_EXP  _PDCLIB_DBL_MAX_10_EXP
+
+
+/* Number of base-FLT_RADIX digits in the significand of a long double */
+#define LDBL_MANT_DIG   _PDCLIB_LDBL_MANT_DIG
+
+/* Number of decimal digits of precision in a long double */
+#define LDBL_DIG        _PDCLIB_LDBL_DIG
+
+/* Difference between 1.0 and the minimum long double greater than 1.0 */
+#define LDBL_EPSILON    _PDCLIB_LDBL_EPSILON
+
+/* Minimum int x such that FLT_RADIX**(x-1) is a normalised long double */
+#define LDBL_MIN_EXP    _PDCLIB_LDBL_MIN_EXP
+
+/* Minimum normalised long double */
+#define LDBL_MIN        _PDCLIB_LDBL_MIN
+
+/* Minimum int x such that 10**x is a normalised long double */
+#define LDBL_MIN_10_EXP _PDCLIB_LDBL_MIN_10_EXP
+
+/* Maximum int x such that FLT_RADIX**(x-1) is a representable long double */
+#define LDBL_MAX_EXP    _PDCLIB_LDBL_MAX_EXP
+
+/* Maximum long double */
+#define LDBL_MAX        _PDCLIB_LDBL_MAX
+
+/* Maximum int x such that 10**x is a representable long double */
+#define LDBL_MAX_10_EXP _PDCLIB_LDBL_MAX_10_EXP
+
+#endif
index c425308cefb67319d05572a345c3866391122b51..8c1814328fc9b6c7a281004b7b9b28f0572f2095 100644 (file)
@@ -1,12 +1,12 @@
-/* _Noreturn <stdnoreturn.h>\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#ifndef _PDCLIB_STDNORETURN_H\r
-#define _PDCLIB_STDNORETURN_H _PDCLIB_STDNORETURN_H\r
-\r
-#define noreturn _Noreturn\r
-\r
-#endif\r
+/* _Noreturn <stdnoreturn.h>
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#ifndef _PDCLIB_STDNORETURN_H
+#define _PDCLIB_STDNORETURN_H _PDCLIB_STDNORETURN_H
+
+#define noreturn _Noreturn
+
+#endif
index b2944e7cb3d868677d574406a00725b475b69d52..87a98bf0b3f7038c36294cec9334cebdbb1780f0 100644 (file)
@@ -1,93 +1,93 @@
-/* PDCLib internal floating point logic <_PDCLIB_float.h>\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#ifndef __PDCLIB_PDCLIB_FLOAT_H\r
-#define __PDCLIB_PDCLIB_FLOAT_H __PDCLIB_PDCLIB_FLOAT_H\r
-\r
-/* IEEE 754 single precision */\r
-#define _PDCLIB_FP_SINGLE_MIN 1.17549435082228750797e-38\r
-#define _PDCLIB_FP_SINGLE_EPSILON 1.19209289550781250000e-7\r
-#define _PDCLIB_FP_SINGLE_HAS_DENORM 1\r
-#define _PDCLIB_FP_SINGLE_MIN_EXP -125\r
-#define _PDCLIB_FP_SINGLE_MANT_DIG 24\r
-#define _PDCLIB_FP_SINGLE_RADIX 2\r
-#define _PDCLIB_FP_SINGLE_HAS_QUIET_NAN 1\r
-#define _PDCLIB_FP_SINGLE_MAX_10_EXP 38\r
-#define _PDCLIB_FP_SINGLE_HAS_INFINITY 1\r
-#define _PDCLIB_FP_SINGLE_DIG 6\r
-#define _PDCLIB_FP_SINGLE_MAX_EXP 128\r
-#define _PDCLIB_FP_SINGLE_DENORM_MIN 1.40129846432481707092e-45\r
-#define _PDCLIB_FP_SINGLE_MAX 3.40282346638528859812e+38\r
-#define _PDCLIB_FP_SINGLE_MIN_10_EXP -37\r
-\r
-/* IEEE 754 double precision */\r
-#define _PDCLIB_FP_DOUBLE_MIN_EXP -1021\r
-#define _PDCLIB_FP_DOUBLE_DENORM_MIN 4.94065645841246544177e-324\r
-#define _PDCLIB_FP_DOUBLE_MIN_10_EXP -307\r
-#define _PDCLIB_FP_DOUBLE_DIG 15\r
-#define _PDCLIB_FP_DOUBLE_MAX 1.79769313486231570815e+308\r
-#define _PDCLIB_FP_DOUBLE_HAS_INFINITY 1\r
-#define _PDCLIB_FP_DOUBLE_MAX_EXP 1024\r
-#define _PDCLIB_FP_DOUBLE_MIN 2.22507385850720138309e-308\r
-#define _PDCLIB_FP_DOUBLE_HAS_DENORM 1\r
-#define _PDCLIB_FP_DOUBLE_HAS_QUIET_NAN 1\r
-#define _PDCLIB_FP_DOUBLE_MANT_DIG 53\r
-#define _PDCLIB_FP_DOUBLE_EPSILON 2.22044604925031308085e-16\r
-#define _PDCLIB_FP_DOUBLE_MAX_10_EXP 308\r
-\r
-/* IEEE 754 80-bit extended precision */\r
-#define _PDCLIB_FP_EXTENDED_MAX 1.18973149535723176502e+4932\r
-#define _PDCLIB_FP_EXTENDED_MAX_EXP 16384\r
-#define _PDCLIB_FP_EXTENDED_HAS_INFINITY 1\r
-#define _PDCLIB_FP_EXTENDED_MIN 3.36210314311209350626e-4932\r
-#define _PDCLIB_FP_EXTENDED_HAS_QUIET_NAN 1\r
-#define _PDCLIB_FP_EXTENDED_HAS_DENORM 1\r
-#define _PDCLIB_FP_EXTENDED_EPSILON 1.08420217248550443401e-19\r
-#define _PDCLIB_FP_EXTENDED_MANT_DIG 64\r
-#define _PDCLIB_FP_EXTENDED_MIN_EXP (-16381)\r
-#define _PDCLIB_FP_EXTENDED_MAX_10_EXP 4932\r
-#define _PDCLIB_FP_EXTENDED_DENORM_MIN 3.64519953188247460253e-4951\r
-#define _PDCLIB_FP_EXTENDED_MIN_10_EXP (-4931)\r
-#define _PDCLIB_FP_EXTENDED_DIG 18\r
-\r
-/* TODO: IEEE754 quadruple precision (_PDCLIB_FP_QUADRUPLE_*) and\r
-         "double-double" math\r
- */\r
-\r
-#define _PDCLIB_FLT_RADIX       _PDCLIB_concat( _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_FLOAT_TYPE, _RADIX ), f )\r
-#define _PDCLIB_FLT_MANT_DIG    _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_FLOAT_TYPE, _MANT_DIG )\r
-#define _PDCLIB_FLT_DIG         _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_FLOAT_TYPE, _DIG )\r
-#define _PDCLIB_FLT_EPSILON     _PDCLIB_concat( _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_FLOAT_TYPE, _EPSILON ), f )\r
-#define _PDCLIB_FLT_MIN_EXP     _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_FLOAT_TYPE, _MIN_EXP )\r
-#define _PDCLIB_FLT_MIN         _PDCLIB_concat( _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_FLOAT_TYPE, _MIN ), f )\r
-#define _PDCLIB_FLT_MIN_10_EXP  _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_FLOAT_TYPE, _MIN_10_EXP )\r
-#define _PDCLIB_FLT_MAX_EXP     _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_FLOAT_TYPE, _MAX_EXP )\r
-#define _PDCLIB_FLT_MAX         _PDCLIB_concat( _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_FLOAT_TYPE, _MAX ), f )\r
-#define _PDCLIB_FLT_MAX_10_EXP  _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_FLOAT_TYPE, _MAX_10_EXP )\r
-\r
-#define _PDCLIB_DBL_RADIX       _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_DOUBLE_TYPE, _RADIX )\r
-#define _PDCLIB_DBL_MANT_DIG    _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_DOUBLE_TYPE, _MANT_DIG )\r
-#define _PDCLIB_DBL_DIG         _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_DOUBLE_TYPE, _DIG )\r
-#define _PDCLIB_DBL_EPSILON     _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_DOUBLE_TYPE, _EPSILON )\r
-#define _PDCLIB_DBL_MIN_EXP     _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_DOUBLE_TYPE, _MIN_EXP )\r
-#define _PDCLIB_DBL_MIN         _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_DOUBLE_TYPE, _MIN )\r
-#define _PDCLIB_DBL_MIN_10_EXP  _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_DOUBLE_TYPE, _MIN_10_EXP )\r
-#define _PDCLIB_DBL_MAX_EXP     _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_DOUBLE_TYPE, _MAX_EXP )\r
-#define _PDCLIB_DBL_MAX         _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_DOUBLE_TYPE, _MAX )\r
-#define _PDCLIB_DBL_MAX_10_EXP  _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_DOUBLE_TYPE, _MAX_10_EXP )\r
-\r
-#define _PDCLIB_LDBL_RADIX       _PDCLIB_concat( _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_LDOUBLE_TYPE, _RADIX ), l )\r
-#define _PDCLIB_LDBL_MANT_DIG    _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_LDOUBLE_TYPE, _MANT_DIG )\r
-#define _PDCLIB_LDBL_DIG         _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_LDOUBLE_TYPE, _DIG )\r
-#define _PDCLIB_LDBL_EPSILON     _PDCLIB_concat( _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_LDOUBLE_TYPE, _EPSILON ), l )\r
-#define _PDCLIB_LDBL_MIN_EXP     _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_LDOUBLE_TYPE, _MIN_EXP )\r
-#define _PDCLIB_LDBL_MIN         _PDCLIB_concat( _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_LDOUBLE_TYPE, _MIN ), l )\r
-#define _PDCLIB_LDBL_MIN_10_EXP  _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_LDOUBLE_TYPE, _MIN_10_EXP )\r
-#define _PDCLIB_LDBL_MAX_EXP     _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_LDOUBLE_TYPE, _MAX_EXP )\r
-#define _PDCLIB_LDBL_MAX         _PDCLIB_concat( _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_LDOUBLE_TYPE, _MAX ), l )\r
-#define _PDCLIB_LDBL_MAX_10_EXP  _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_LDOUBLE_TYPE, _MAX_10_EXP )\r
-\r
-#endif\r
+/* PDCLib internal floating point logic <_PDCLIB_float.h>
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#ifndef __PDCLIB_PDCLIB_FLOAT_H
+#define __PDCLIB_PDCLIB_FLOAT_H __PDCLIB_PDCLIB_FLOAT_H
+
+/* IEEE 754 single precision */
+#define _PDCLIB_FP_SINGLE_MIN 1.17549435082228750797e-38
+#define _PDCLIB_FP_SINGLE_EPSILON 1.19209289550781250000e-7
+#define _PDCLIB_FP_SINGLE_HAS_DENORM 1
+#define _PDCLIB_FP_SINGLE_MIN_EXP -125
+#define _PDCLIB_FP_SINGLE_MANT_DIG 24
+#define _PDCLIB_FP_SINGLE_RADIX 2
+#define _PDCLIB_FP_SINGLE_HAS_QUIET_NAN 1
+#define _PDCLIB_FP_SINGLE_MAX_10_EXP 38
+#define _PDCLIB_FP_SINGLE_HAS_INFINITY 1
+#define _PDCLIB_FP_SINGLE_DIG 6
+#define _PDCLIB_FP_SINGLE_MAX_EXP 128
+#define _PDCLIB_FP_SINGLE_DENORM_MIN 1.40129846432481707092e-45
+#define _PDCLIB_FP_SINGLE_MAX 3.40282346638528859812e+38
+#define _PDCLIB_FP_SINGLE_MIN_10_EXP -37
+
+/* IEEE 754 double precision */
+#define _PDCLIB_FP_DOUBLE_MIN_EXP -1021
+#define _PDCLIB_FP_DOUBLE_DENORM_MIN 4.94065645841246544177e-324
+#define _PDCLIB_FP_DOUBLE_MIN_10_EXP -307
+#define _PDCLIB_FP_DOUBLE_DIG 15
+#define _PDCLIB_FP_DOUBLE_MAX 1.79769313486231570815e+308
+#define _PDCLIB_FP_DOUBLE_HAS_INFINITY 1
+#define _PDCLIB_FP_DOUBLE_MAX_EXP 1024
+#define _PDCLIB_FP_DOUBLE_MIN 2.22507385850720138309e-308
+#define _PDCLIB_FP_DOUBLE_HAS_DENORM 1
+#define _PDCLIB_FP_DOUBLE_HAS_QUIET_NAN 1
+#define _PDCLIB_FP_DOUBLE_MANT_DIG 53
+#define _PDCLIB_FP_DOUBLE_EPSILON 2.22044604925031308085e-16
+#define _PDCLIB_FP_DOUBLE_MAX_10_EXP 308
+
+/* IEEE 754 80-bit extended precision */
+#define _PDCLIB_FP_EXTENDED_MAX 1.18973149535723176502e+4932
+#define _PDCLIB_FP_EXTENDED_MAX_EXP 16384
+#define _PDCLIB_FP_EXTENDED_HAS_INFINITY 1
+#define _PDCLIB_FP_EXTENDED_MIN 3.36210314311209350626e-4932
+#define _PDCLIB_FP_EXTENDED_HAS_QUIET_NAN 1
+#define _PDCLIB_FP_EXTENDED_HAS_DENORM 1
+#define _PDCLIB_FP_EXTENDED_EPSILON 1.08420217248550443401e-19
+#define _PDCLIB_FP_EXTENDED_MANT_DIG 64
+#define _PDCLIB_FP_EXTENDED_MIN_EXP (-16381)
+#define _PDCLIB_FP_EXTENDED_MAX_10_EXP 4932
+#define _PDCLIB_FP_EXTENDED_DENORM_MIN 3.64519953188247460253e-4951
+#define _PDCLIB_FP_EXTENDED_MIN_10_EXP (-4931)
+#define _PDCLIB_FP_EXTENDED_DIG 18
+
+/* TODO: IEEE754 quadruple precision (_PDCLIB_FP_QUADRUPLE_*) and
+         "double-double" math
+ */
+
+#define _PDCLIB_FLT_RADIX       _PDCLIB_concat( _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_FLOAT_TYPE, _RADIX ), f )
+#define _PDCLIB_FLT_MANT_DIG    _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_FLOAT_TYPE, _MANT_DIG )
+#define _PDCLIB_FLT_DIG         _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_FLOAT_TYPE, _DIG )
+#define _PDCLIB_FLT_EPSILON     _PDCLIB_concat( _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_FLOAT_TYPE, _EPSILON ), f )
+#define _PDCLIB_FLT_MIN_EXP     _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_FLOAT_TYPE, _MIN_EXP )
+#define _PDCLIB_FLT_MIN         _PDCLIB_concat( _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_FLOAT_TYPE, _MIN ), f )
+#define _PDCLIB_FLT_MIN_10_EXP  _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_FLOAT_TYPE, _MIN_10_EXP )
+#define _PDCLIB_FLT_MAX_EXP     _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_FLOAT_TYPE, _MAX_EXP )
+#define _PDCLIB_FLT_MAX         _PDCLIB_concat( _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_FLOAT_TYPE, _MAX ), f )
+#define _PDCLIB_FLT_MAX_10_EXP  _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_FLOAT_TYPE, _MAX_10_EXP )
+
+#define _PDCLIB_DBL_RADIX       _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_DOUBLE_TYPE, _RADIX )
+#define _PDCLIB_DBL_MANT_DIG    _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_DOUBLE_TYPE, _MANT_DIG )
+#define _PDCLIB_DBL_DIG         _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_DOUBLE_TYPE, _DIG )
+#define _PDCLIB_DBL_EPSILON     _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_DOUBLE_TYPE, _EPSILON )
+#define _PDCLIB_DBL_MIN_EXP     _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_DOUBLE_TYPE, _MIN_EXP )
+#define _PDCLIB_DBL_MIN         _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_DOUBLE_TYPE, _MIN )
+#define _PDCLIB_DBL_MIN_10_EXP  _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_DOUBLE_TYPE, _MIN_10_EXP )
+#define _PDCLIB_DBL_MAX_EXP     _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_DOUBLE_TYPE, _MAX_EXP )
+#define _PDCLIB_DBL_MAX         _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_DOUBLE_TYPE, _MAX )
+#define _PDCLIB_DBL_MAX_10_EXP  _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_DOUBLE_TYPE, _MAX_10_EXP )
+
+#define _PDCLIB_LDBL_RADIX       _PDCLIB_concat( _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_LDOUBLE_TYPE, _RADIX ), l )
+#define _PDCLIB_LDBL_MANT_DIG    _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_LDOUBLE_TYPE, _MANT_DIG )
+#define _PDCLIB_LDBL_DIG         _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_LDOUBLE_TYPE, _DIG )
+#define _PDCLIB_LDBL_EPSILON     _PDCLIB_concat( _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_LDOUBLE_TYPE, _EPSILON ), l )
+#define _PDCLIB_LDBL_MIN_EXP     _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_LDOUBLE_TYPE, _MIN_EXP )
+#define _PDCLIB_LDBL_MIN         _PDCLIB_concat( _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_LDOUBLE_TYPE, _MIN ), l )
+#define _PDCLIB_LDBL_MIN_10_EXP  _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_LDOUBLE_TYPE, _MIN_10_EXP )
+#define _PDCLIB_LDBL_MAX_EXP     _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_LDOUBLE_TYPE, _MAX_EXP )
+#define _PDCLIB_LDBL_MAX         _PDCLIB_concat( _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_LDOUBLE_TYPE, _MAX ), l )
+#define _PDCLIB_LDBL_MAX_10_EXP  _PDCLIB_concat3( _PDCLIB_FP_, _PDCLIB_LDOUBLE_TYPE, _MAX_10_EXP )
+
+#endif
index 27c33e7dd7a50d360ee58710bacfee8213ed524d..11f351f7977484c1b276fa06a59a79342c670901 100644 (file)
-/* PDCLib I/O support <_PDCLIB_io.h>\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#ifndef __PDCLIB_IO_H\r
-#define __PDCLIB_IO_H __PDCLIB_IO_H\r
-\r
-#include "_PDCLIB_int.h"\r
-#include "_PDCLIB_threadconfig.h"\r
-\r
-/* Flags for representing mode (see fopen()). Note these must fit the same\r
-   status field as the _IO?BF flags in <stdio.h> and the internal flags below.\r
-*/\r
-#define _PDCLIB_FREAD     8u\r
-#define _PDCLIB_FWRITE   16u\r
-#define _PDCLIB_FAPPEND  32u\r
-#define _PDCLIB_FRW      64u\r
-#define _PDCLIB_FBIN    128u\r
-\r
-/* Internal flags, made to fit the same status field as the flags above. */\r
-/* -------------------------------------------------------------------------- */\r
-/* free() the buffer memory on closing (false for user-supplied buffer) */\r
-#define _PDCLIB_FREEBUFFER   512u\r
-/* stream has encountered error / EOF */\r
-#define _PDCLIB_ERRORFLAG   1024u\r
-#define _PDCLIB_EOFFLAG     2048u\r
-/* stream is wide-oriented */\r
-#define _PDCLIB_WIDESTREAM  4096u\r
-/* stream is byte-oriented */\r
-#define _PDCLIB_BYTESTREAM  8192u\r
-/* file associated with stream should be remove()d on closing (tmpfile()) */\r
-#define _PDCLIB_DELONCLOSE 16384u\r
-/* stream handle should not be free()d on close (stdin, stdout, stderr) */\r
-#define _PDCLIB_STATIC     32768u\r
-\r
-union _PDCLIB_fd\r
-{\r
-#if defined(_PDCLIB_OSFD_T)\r
-    _PDCLIB_OSFD_T      osfd;\r
-#endif\r
-    void *              pointer;\r
-    _PDCLIB_uintptr_t   uval;\r
-    _PDCLIB_intptr_t    sval;\r
-};\r
-\r
-/******************************************************************************/\r
-/* Internal functions                                                         */\r
-/******************************************************************************/\r
-\r
-/* The worker for all printf() type of functions. The pointer spec should point\r
-   to the introducing '%' of a conversion specifier. The status structure is to\r
-   be that of the current printf() function, of which the members n, s, stream\r
-   and arg will be preserved; i will be updated; and all others will be trashed\r
-   by the function.\r
-   Returns the number of characters parsed as a conversion specifier (0 if none\r
-   parsed); returns -1 if the underlying I/O callback returns failure.\r
-*/\r
-int _PDCLIB_print( const char * spec, struct _PDCLIB_status_t * status );\r
-\r
-/* The worker for all scanf() type of functions. The pointer spec should point\r
-   to the introducing '%' of a conversion specifier. The status structure is to\r
-   be that of the current scanf() function, of which the member stream will be\r
-   preserved; n, i, and s will be updated; and all others will be trashed by\r
-   the function.\r
-   Returns a pointer to the first character not parsed as conversion specifier,\r
-   or NULL in case of error.\r
-   FIXME: Should distinguish between matching and input error\r
-*/\r
-const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status );\r
-\r
-/* Parsing any fopen() style filemode string into a number of flags. */\r
-unsigned int _PDCLIB_filemode( const char * mode );\r
-\r
-/* Sanity checking and preparing of read buffer, should be called first thing\r
-   by any stdio read-data function.\r
-   Returns 0 on success, EOF on error.\r
-   On error, EOF / error flags and errno are set appropriately.\r
-*/\r
-int _PDCLIB_prepread( _PDCLIB_file_t * stream );\r
-\r
-/* Sanity checking, should be called first thing by any stdio write-data\r
-   function.\r
-   Returns 0 on success, EOF on error.\r
-   On error, error flags and errno are set appropriately.\r
-*/\r
-int _PDCLIB_prepwrite( _PDCLIB_file_t * stream );\r
-\r
-/* Closing all streams on program exit */\r
-void _PDCLIB_closeall( void );\r
-\r
-/* Writes a stream's buffer.\r
-   Returns 0 on success, EOF on write error.\r
-   Sets stream error flags and errno appropriately on error.\r
-*/\r
-int _PDCLIB_flushbuffer( _PDCLIB_file_t * stream );\r
-\r
-/* Fills a stream's buffer.\r
-   Returns 0 on success, EOF on read error / EOF.\r
-   Sets stream EOF / error flags and errno appropriately on error.\r
-*/\r
-int _PDCLIB_fillbuffer( _PDCLIB_file_t * stream );\r
-\r
-/* Repositions within a file. Returns new offset on success,\r
-   -1 / errno on error.\r
-*/\r
-_PDCLIB_int_fast64_t _PDCLIB_seek( _PDCLIB_file_t * stream,\r
-                                  _PDCLIB_int_fast64_t offset, int whence );\r
-\r
-/* File backend I/O operations\r
- *\r
- * PDCLib will call through to these methods as needed to implement the stdio\r
- * functions.\r
- */\r
-struct _PDCLIB_fileops\r
-{\r
-    /*! Read length bytes from the file into buf; returning the number of bytes\r
-     *  actually read in *numBytesRead.\r
-     *\r
-     *  Returns true if bytes were read successfully; on end of file, returns\r
-     *  true with *numBytesRead == 0.\r
-     *\r
-     *  On error, returns false and sets errno appropriately. *numBytesRead is\r
-     *  ignored in this situation.\r
-     */\r
-    _PDCLIB_bool (*read)( _PDCLIB_fd_t self,\r
-                          void * buf,\r
-                          _PDCLIB_size_t length,\r
-                          _PDCLIB_size_t * numBytesRead );\r
-\r
-    /*! Write length bytes to the file from buf; returning the number of bytes\r
-     *  actually written in *numBytesWritten\r
-     *\r
-     *  Returns true if bytes were written successfully. On error, returns false\r
-     *  and setss errno appropriately (as with read, *numBytesWritten is\r
-     *  ignored)\r
-     */\r
-    _PDCLIB_bool (*write)( _PDCLIB_fd_t self, const void * buf,\r
-                   _PDCLIB_size_t length, _PDCLIB_size_t * numBytesWritten );\r
-\r
-    /* Seek to the file offset specified by offset, from location whence, which\r
-     * may be one of the standard constants SEEK_SET/SEEK_CUR/SEEK_END\r
-     */\r
-    _PDCLIB_bool (*seek)( _PDCLIB_fd_t self, _PDCLIB_int_fast64_t offset,\r
-                          int whence, _PDCLIB_int_fast64_t *newPos );\r
-\r
-    void (*close)( _PDCLIB_fd_t self );\r
-\r
-    /*! Behaves as read does, except for wide characters. Both length and\r
-     *  *numCharsRead represent counts of characters, not bytes.\r
-     *\r
-     *  This function is optional; if missing, PDCLib will buffer the character\r
-     *  data as bytes and perform translation directly into the user's buffers.\r
-     *  It is useful if your backend can directly take wide characters (for\r
-     *  example, the Windows console)\r
-     */\r
-    _PDCLIB_bool (*wread)( _PDCLIB_fd_t self, _PDCLIB_wchar_t * buf,\r
-                     _PDCLIB_size_t length, _PDCLIB_size_t * numCharsRead );\r
-\r
-    /* Behaves as write does, except for wide characters. As with wread, both\r
-     * length and *numCharsWritten are character counts.\r
-     *\r
-     * This function is also optional; if missing, PDCLib will buffer the\r
-     * character data as bytes and do translation directly from the user's\r
-     * buffers. You only need to implement this if your backend can directly\r
-     * take wide characters (for example, the Windows console)\r
-     */\r
-    _PDCLIB_bool (*wwrite)( _PDCLIB_fd_t self, const _PDCLIB_wchar_t * buf,\r
-                     _PDCLIB_size_t length, _PDCLIB_size_t * numCharsWritten );\r
-};\r
-\r
-/* struct _PDCLIB_file structure */\r
-struct _PDCLIB_file\r
-{\r
-    const _PDCLIB_fileops_t * ops;\r
-    _PDCLIB_fd_t              handle;   /* OS file handle */\r
-    _PDCLIB_MTX_T             lock;     /* file lock */\r
-    char *                    buffer;   /* Pointer to buffer memory */\r
-    _PDCLIB_size_t            bufsize;  /* Size of buffer */\r
-    _PDCLIB_size_t            bufidx;   /* Index of current position in buffer */\r
-    _PDCLIB_size_t            bufend;   /* Index of last pre-read character in buffer */\r
-#ifdef _PDCLIB_NEED_EOL_TRANSLATION\r
-    _PDCLIB_size_t            bufnlexp; /* Current position of buffer newline expansion */\r
-#endif\r
-    _PDCLIB_size_t            ungetidx; /* Number of ungetc()'ed characters */\r
-    unsigned char *           ungetbuf; /* ungetc() buffer */\r
-    unsigned int              status;   /* Status flags; see above */\r
-    /* multibyte parsing status to be added later */\r
-    _PDCLIB_fpos_t            pos;      /* Offset and multibyte parsing state */\r
-    char *                    filename; /* Name the current stream has been opened with */\r
-    _PDCLIB_file_t *          next;     /* Pointer to next struct (internal) */\r
-};\r
-\r
-static inline _PDCLIB_size_t _PDCLIB_getchars( char * out, _PDCLIB_size_t n,\r
-                                               int stopchar,\r
-                                               _PDCLIB_file_t * stream )\r
-{\r
-    _PDCLIB_size_t i = 0;\r
-    int c;\r
-    while ( stream->ungetidx > 0 && i != n )\r
-    {\r
-        c = (unsigned char)\r
-                ( out[ i++ ] = stream->ungetbuf[ --(stream->ungetidx) ] );\r
-        if( c == stopchar )\r
-            return i;\r
-    }\r
-\r
-    while ( i != n )\r
-    {\r
-        while ( stream->bufidx != stream->bufend && i != n)\r
-        {\r
-            c = (unsigned char) stream->buffer[ stream->bufidx++ ];\r
-#ifdef _PDCLIB_NEED_EOL_TRANSLATION\r
-            if ( !( stream->status & _PDCLIB_FBIN ) && c == '\r' )\r
-            {\r
-                if ( stream->bufidx == stream->bufend )\r
-                    break;\r
-\r
-                if ( stream->buffer[ stream->bufidx ] == '\n' )\r
-                {\r
-                    c = '\n';\r
-                    stream->bufidx++;\r
-                }\r
-            }\r
-#endif\r
-            out[ i++ ] = c;\r
-\r
-            if( c == stopchar )\r
-                return i;\r
-        }\r
-\r
-        if ( i != n )\r
-        {\r
-            if( _PDCLIB_fillbuffer( stream ) == -1 )\r
-            {\r
-                break;\r
-            }\r
-        }\r
-    }\r
-\r
-#ifdef _PDCLIB_NEED_EOL_TRANSLATION\r
-    if ( i != n && stream->bufidx != stream->bufend )\r
-    {\r
-        // we must have EOF'd immediately after a \r\r
-        out[ i++ ] = stream->buffer[ stream->bufidx++ ];\r
-    }\r
-#endif\r
-\r
-    return i;\r
-}\r
-\r
-/* Unlocked functions - internal names\r
- *\r
- * We can't use the functions using their "normal" names internally because that\r
- * would cause namespace leakage. Therefore, we use them by prefixed internal\r
- * names\r
- */\r
-void _PDCLIB_flockfile(struct _PDCLIB_file *file) _PDCLIB_nothrow;\r
-int _PDCLIB_ftrylockfile(struct _PDCLIB_file *file) _PDCLIB_nothrow;\r
-void _PDCLIB_funlockfile(struct _PDCLIB_file *file) _PDCLIB_nothrow;\r
-\r
-int _PDCLIB_getc_unlocked(struct _PDCLIB_file *stream) _PDCLIB_nothrow;\r
-int _PDCLIB_getchar_unlocked(void) _PDCLIB_nothrow;\r
-int _PDCLIB_putc_unlocked(int c, struct _PDCLIB_file *stream) _PDCLIB_nothrow;\r
-int _PDCLIB_putchar_unlocked(int c) _PDCLIB_nothrow;\r
-void _PDCLIB_clearerr_unlocked(struct _PDCLIB_file *stream) _PDCLIB_nothrow;\r
-int _PDCLIB_feof_unlocked(struct _PDCLIB_file *stream) _PDCLIB_nothrow;\r
-int _PDCLIB_ferror_unlocked(struct _PDCLIB_file *stream) _PDCLIB_nothrow;\r
-int _PDCLIB_fflush_unlocked(struct _PDCLIB_file *stream) _PDCLIB_nothrow;\r
-int _PDCLIB_fgetc_unlocked(struct _PDCLIB_file *stream) _PDCLIB_nothrow;\r
-int _PDCLIB_fputc_unlocked(int c, struct _PDCLIB_file *stream) _PDCLIB_nothrow;\r
-_PDCLIB_size_t _PDCLIB_fread_unlocked(void *ptr, _PDCLIB_size_t size, _PDCLIB_size_t n, struct _PDCLIB_file *stream) _PDCLIB_nothrow;\r
-_PDCLIB_size_t _PDCLIB_fwrite_unlocked(const void *ptr, _PDCLIB_size_t size, _PDCLIB_size_t n, struct _PDCLIB_file *stream) _PDCLIB_nothrow;\r
-char *_PDCLIB_fgets_unlocked(char *s, int n, struct _PDCLIB_file *stream) _PDCLIB_nothrow;\r
-int _PDCLIB_fputs_unlocked(const char *s, struct _PDCLIB_file *stream) _PDCLIB_nothrow;\r
-int _PDCLIB_fgetpos_unlocked( struct _PDCLIB_file * _PDCLIB_restrict stream, _PDCLIB_fpos_t * _PDCLIB_restrict pos ) _PDCLIB_nothrow;\r
-int _PDCLIB_fsetpos_unlocked( struct _PDCLIB_file * stream, const _PDCLIB_fpos_t * pos ) _PDCLIB_nothrow;\r
-long int _PDCLIB_ftell_unlocked( struct _PDCLIB_file * stream ) _PDCLIB_nothrow;\r
-int _PDCLIB_fseek_unlocked( struct _PDCLIB_file * stream, long int offset, int whence ) _PDCLIB_nothrow;\r
-void _PDCLIB_rewind_unlocked( struct _PDCLIB_file * stream ) _PDCLIB_nothrow;\r
-\r
-int _PDCLIB_puts_unlocked( const char * s ) _PDCLIB_nothrow;\r
-int _PDCLIB_ungetc_unlocked( int c, struct _PDCLIB_file * stream ) _PDCLIB_nothrow;\r
-\r
-\r
-int _PDCLIB_printf_unlocked( const char * _PDCLIB_restrict format, ... ) _PDCLIB_nothrow;\r
-int _PDCLIB_vprintf_unlocked( const char * _PDCLIB_restrict format, _PDCLIB_va_list arg ) _PDCLIB_nothrow;\r
-int _PDCLIB_fprintf_unlocked( struct _PDCLIB_file * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, ... ) _PDCLIB_nothrow;\r
-int _PDCLIB_vfprintf_unlocked( struct _PDCLIB_file * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, _PDCLIB_va_list arg ) _PDCLIB_nothrow;\r
-int _PDCLIB_scanf_unlocked( const char * _PDCLIB_restrict format, ... ) _PDCLIB_nothrow;\r
-int _PDCLIB_vscanf_unlocked( const char * _PDCLIB_restrict format, _PDCLIB_va_list arg ) _PDCLIB_nothrow;\r
-int _PDCLIB_fscanf_unlocked( struct _PDCLIB_file * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, ... ) _PDCLIB_nothrow;\r
-int _PDCLIB_vfscanf_unlocked( struct _PDCLIB_file * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, _PDCLIB_va_list arg ) _PDCLIB_nothrow;\r
-\r
-#endif\r
+/* PDCLib I/O support <_PDCLIB_io.h>
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#ifndef __PDCLIB_IO_H
+#define __PDCLIB_IO_H __PDCLIB_IO_H
+
+#include "_PDCLIB_int.h"
+#include "_PDCLIB_threadconfig.h"
+
+/* Flags for representing mode (see fopen()). Note these must fit the same
+   status field as the _IO?BF flags in <stdio.h> and the internal flags below.
+*/
+#define _PDCLIB_FREAD     8u
+#define _PDCLIB_FWRITE   16u
+#define _PDCLIB_FAPPEND  32u
+#define _PDCLIB_FRW      64u
+#define _PDCLIB_FBIN    128u
+
+/* Internal flags, made to fit the same status field as the flags above. */
+/* -------------------------------------------------------------------------- */
+/* free() the buffer memory on closing (false for user-supplied buffer) */
+#define _PDCLIB_FREEBUFFER   512u
+/* stream has encountered error / EOF */
+#define _PDCLIB_ERRORFLAG   1024u
+#define _PDCLIB_EOFFLAG     2048u
+/* stream is wide-oriented */
+#define _PDCLIB_WIDESTREAM  4096u
+/* stream is byte-oriented */
+#define _PDCLIB_BYTESTREAM  8192u
+/* file associated with stream should be remove()d on closing (tmpfile()) */
+#define _PDCLIB_DELONCLOSE 16384u
+/* stream handle should not be free()d on close (stdin, stdout, stderr) */
+#define _PDCLIB_STATIC     32768u
+
+union _PDCLIB_fd
+{
+#if defined(_PDCLIB_OSFD_T)
+    _PDCLIB_OSFD_T      osfd;
+#endif
+    void *              pointer;
+    _PDCLIB_uintptr_t   uval;
+    _PDCLIB_intptr_t    sval;
+};
+
+/******************************************************************************/
+/* Internal functions                                                         */
+/******************************************************************************/
+
+/* The worker for all printf() type of functions. The pointer spec should point
+   to the introducing '%' of a conversion specifier. The status structure is to
+   be that of the current printf() function, of which the members n, s, stream
+   and arg will be preserved; i will be updated; and all others will be trashed
+   by the function.
+   Returns the number of characters parsed as a conversion specifier (0 if none
+   parsed); returns -1 if the underlying I/O callback returns failure.
+*/
+int _PDCLIB_print( const char * spec, struct _PDCLIB_status_t * status );
+
+/* The worker for all scanf() type of functions. The pointer spec should point
+   to the introducing '%' of a conversion specifier. The status structure is to
+   be that of the current scanf() function, of which the member stream will be
+   preserved; n, i, and s will be updated; and all others will be trashed by
+   the function.
+   Returns a pointer to the first character not parsed as conversion specifier,
+   or NULL in case of error.
+   FIXME: Should distinguish between matching and input error
+*/
+const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status );
+
+/* Parsing any fopen() style filemode string into a number of flags. */
+unsigned int _PDCLIB_filemode( const char * mode );
+
+/* Sanity checking and preparing of read buffer, should be called first thing
+   by any stdio read-data function.
+   Returns 0 on success, EOF on error.
+   On error, EOF / error flags and errno are set appropriately.
+*/
+int _PDCLIB_prepread( _PDCLIB_file_t * stream );
+
+/* Sanity checking, should be called first thing by any stdio write-data
+   function.
+   Returns 0 on success, EOF on error.
+   On error, error flags and errno are set appropriately.
+*/
+int _PDCLIB_prepwrite( _PDCLIB_file_t * stream );
+
+/* Closing all streams on program exit */
+void _PDCLIB_closeall( void );
+
+/* Writes a stream's buffer.
+   Returns 0 on success, EOF on write error.
+   Sets stream error flags and errno appropriately on error.
+*/
+int _PDCLIB_flushbuffer( _PDCLIB_file_t * stream );
+
+/* Fills a stream's buffer.
+   Returns 0 on success, EOF on read error / EOF.
+   Sets stream EOF / error flags and errno appropriately on error.
+*/
+int _PDCLIB_fillbuffer( _PDCLIB_file_t * stream );
+
+/* Repositions within a file. Returns new offset on success,
+   -1 / errno on error.
+*/
+_PDCLIB_int_fast64_t _PDCLIB_seek( _PDCLIB_file_t * stream,
+                                  _PDCLIB_int_fast64_t offset, int whence );
+
+/* File backend I/O operations
+ *
+ * PDCLib will call through to these methods as needed to implement the stdio
+ * functions.
+ */
+struct _PDCLIB_fileops
+{
+    /*! Read length bytes from the file into buf; returning the number of bytes
+     *  actually read in *numBytesRead.
+     *
+     *  Returns true if bytes were read successfully; on end of file, returns
+     *  true with *numBytesRead == 0.
+     *
+     *  On error, returns false and sets errno appropriately. *numBytesRead is
+     *  ignored in this situation.
+     */
+    _PDCLIB_bool (*read)( _PDCLIB_fd_t self,
+                          void * buf,
+                          _PDCLIB_size_t length,
+                          _PDCLIB_size_t * numBytesRead );
+
+    /*! Write length bytes to the file from buf; returning the number of bytes
+     *  actually written in *numBytesWritten
+     *
+     *  Returns true if bytes were written successfully. On error, returns false
+     *  and setss errno appropriately (as with read, *numBytesWritten is
+     *  ignored)
+     */
+    _PDCLIB_bool (*write)( _PDCLIB_fd_t self, const void * buf,
+                   _PDCLIB_size_t length, _PDCLIB_size_t * numBytesWritten );
+
+    /* Seek to the file offset specified by offset, from location whence, which
+     * may be one of the standard constants SEEK_SET/SEEK_CUR/SEEK_END
+     */
+    _PDCLIB_bool (*seek)( _PDCLIB_fd_t self, _PDCLIB_int_fast64_t offset,
+                          int whence, _PDCLIB_int_fast64_t *newPos );
+
+    void (*close)( _PDCLIB_fd_t self );
+
+    /*! Behaves as read does, except for wide characters. Both length and
+     *  *numCharsRead represent counts of characters, not bytes.
+     *
+     *  This function is optional; if missing, PDCLib will buffer the character
+     *  data as bytes and perform translation directly into the user's buffers.
+     *  It is useful if your backend can directly take wide characters (for
+     *  example, the Windows console)
+     */
+    _PDCLIB_bool (*wread)( _PDCLIB_fd_t self, _PDCLIB_wchar_t * buf,
+                     _PDCLIB_size_t length, _PDCLIB_size_t * numCharsRead );
+
+    /* Behaves as write does, except for wide characters. As with wread, both
+     * length and *numCharsWritten are character counts.
+     *
+     * This function is also optional; if missing, PDCLib will buffer the
+     * character data as bytes and do translation directly from the user's
+     * buffers. You only need to implement this if your backend can directly
+     * take wide characters (for example, the Windows console)
+     */
+    _PDCLIB_bool (*wwrite)( _PDCLIB_fd_t self, const _PDCLIB_wchar_t * buf,
+                     _PDCLIB_size_t length, _PDCLIB_size_t * numCharsWritten );
+};
+
+/* struct _PDCLIB_file structure */
+struct _PDCLIB_file
+{
+    const _PDCLIB_fileops_t * ops;
+    _PDCLIB_fd_t              handle;   /* OS file handle */
+    _PDCLIB_MTX_T             lock;     /* file lock */
+    char *                    buffer;   /* Pointer to buffer memory */
+    _PDCLIB_size_t            bufsize;  /* Size of buffer */
+    _PDCLIB_size_t            bufidx;   /* Index of current position in buffer */
+    _PDCLIB_size_t            bufend;   /* Index of last pre-read character in buffer */
+#ifdef _PDCLIB_NEED_EOL_TRANSLATION
+    _PDCLIB_size_t            bufnlexp; /* Current position of buffer newline expansion */
+#endif
+    _PDCLIB_size_t            ungetidx; /* Number of ungetc()'ed characters */
+    unsigned char *           ungetbuf; /* ungetc() buffer */
+    unsigned int              status;   /* Status flags; see above */
+    /* multibyte parsing status to be added later */
+    _PDCLIB_fpos_t            pos;      /* Offset and multibyte parsing state */
+    char *                    filename; /* Name the current stream has been opened with */
+    _PDCLIB_file_t *          next;     /* Pointer to next struct (internal) */
+};
+
+static inline _PDCLIB_size_t _PDCLIB_getchars( char * out, _PDCLIB_size_t n,
+                                               int stopchar,
+                                               _PDCLIB_file_t * stream )
+{
+    _PDCLIB_size_t i = 0;
+    int c;
+    while ( stream->ungetidx > 0 && i != n )
+    {
+        c = (unsigned char)
+                ( out[ i++ ] = stream->ungetbuf[ --(stream->ungetidx) ] );
+        if( c == stopchar )
+            return i;
+    }
+
+    while ( i != n )
+    {
+        while ( stream->bufidx != stream->bufend && i != n)
+        {
+            c = (unsigned char) stream->buffer[ stream->bufidx++ ];
+#ifdef _PDCLIB_NEED_EOL_TRANSLATION
+            if ( !( stream->status & _PDCLIB_FBIN ) && c == '\r' )
+            {
+                if ( stream->bufidx == stream->bufend )
+                    break;
+
+                if ( stream->buffer[ stream->bufidx ] == '\n' )
+                {
+                    c = '\n';
+                    stream->bufidx++;
+                }
+            }
+#endif
+            out[ i++ ] = c;
+
+            if( c == stopchar )
+                return i;
+        }
+
+        if ( i != n )
+        {
+            if( _PDCLIB_fillbuffer( stream ) == -1 )
+            {
+                break;
+            }
+        }
+    }
+
+#ifdef _PDCLIB_NEED_EOL_TRANSLATION
+    if ( i != n && stream->bufidx != stream->bufend )
+    {
+        // we must have EOF'd immediately after a \r
+        out[ i++ ] = stream->buffer[ stream->bufidx++ ];
+    }
+#endif
+
+    return i;
+}
+
+/* Unlocked functions - internal names
+ *
+ * We can't use the functions using their "normal" names internally because that
+ * would cause namespace leakage. Therefore, we use them by prefixed internal
+ * names
+ */
+void _PDCLIB_flockfile(struct _PDCLIB_file *file) _PDCLIB_nothrow;
+int _PDCLIB_ftrylockfile(struct _PDCLIB_file *file) _PDCLIB_nothrow;
+void _PDCLIB_funlockfile(struct _PDCLIB_file *file) _PDCLIB_nothrow;
+
+int _PDCLIB_getc_unlocked(struct _PDCLIB_file *stream) _PDCLIB_nothrow;
+int _PDCLIB_getchar_unlocked(void) _PDCLIB_nothrow;
+int _PDCLIB_putc_unlocked(int c, struct _PDCLIB_file *stream) _PDCLIB_nothrow;
+int _PDCLIB_putchar_unlocked(int c) _PDCLIB_nothrow;
+void _PDCLIB_clearerr_unlocked(struct _PDCLIB_file *stream) _PDCLIB_nothrow;
+int _PDCLIB_feof_unlocked(struct _PDCLIB_file *stream) _PDCLIB_nothrow;
+int _PDCLIB_ferror_unlocked(struct _PDCLIB_file *stream) _PDCLIB_nothrow;
+int _PDCLIB_fflush_unlocked(struct _PDCLIB_file *stream) _PDCLIB_nothrow;
+int _PDCLIB_fgetc_unlocked(struct _PDCLIB_file *stream) _PDCLIB_nothrow;
+int _PDCLIB_fputc_unlocked(int c, struct _PDCLIB_file *stream) _PDCLIB_nothrow;
+_PDCLIB_size_t _PDCLIB_fread_unlocked(void *ptr, _PDCLIB_size_t size, _PDCLIB_size_t n, struct _PDCLIB_file *stream) _PDCLIB_nothrow;
+_PDCLIB_size_t _PDCLIB_fwrite_unlocked(const void *ptr, _PDCLIB_size_t size, _PDCLIB_size_t n, struct _PDCLIB_file *stream) _PDCLIB_nothrow;
+char *_PDCLIB_fgets_unlocked(char *s, int n, struct _PDCLIB_file *stream) _PDCLIB_nothrow;
+int _PDCLIB_fputs_unlocked(const char *s, struct _PDCLIB_file *stream) _PDCLIB_nothrow;
+int _PDCLIB_fgetpos_unlocked( struct _PDCLIB_file * _PDCLIB_restrict stream, _PDCLIB_fpos_t * _PDCLIB_restrict pos ) _PDCLIB_nothrow;
+int _PDCLIB_fsetpos_unlocked( struct _PDCLIB_file * stream, const _PDCLIB_fpos_t * pos ) _PDCLIB_nothrow;
+long int _PDCLIB_ftell_unlocked( struct _PDCLIB_file * stream ) _PDCLIB_nothrow;
+int _PDCLIB_fseek_unlocked( struct _PDCLIB_file * stream, long int offset, int whence ) _PDCLIB_nothrow;
+void _PDCLIB_rewind_unlocked( struct _PDCLIB_file * stream ) _PDCLIB_nothrow;
+
+int _PDCLIB_puts_unlocked( const char * s ) _PDCLIB_nothrow;
+int _PDCLIB_ungetc_unlocked( int c, struct _PDCLIB_file * stream ) _PDCLIB_nothrow;
+
+
+int _PDCLIB_printf_unlocked( const char * _PDCLIB_restrict format, ... ) _PDCLIB_nothrow;
+int _PDCLIB_vprintf_unlocked( const char * _PDCLIB_restrict format, _PDCLIB_va_list arg ) _PDCLIB_nothrow;
+int _PDCLIB_fprintf_unlocked( struct _PDCLIB_file * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, ... ) _PDCLIB_nothrow;
+int _PDCLIB_vfprintf_unlocked( struct _PDCLIB_file * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, _PDCLIB_va_list arg ) _PDCLIB_nothrow;
+int _PDCLIB_scanf_unlocked( const char * _PDCLIB_restrict format, ... ) _PDCLIB_nothrow;
+int _PDCLIB_vscanf_unlocked( const char * _PDCLIB_restrict format, _PDCLIB_va_list arg ) _PDCLIB_nothrow;
+int _PDCLIB_fscanf_unlocked( struct _PDCLIB_file * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, ... ) _PDCLIB_nothrow;
+int _PDCLIB_vfscanf_unlocked( struct _PDCLIB_file * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format, _PDCLIB_va_list arg ) _PDCLIB_nothrow;
+
+#endif
index 8fcdc2181253530af21a163a1b428c34bcde7b0d..502318bffb894f46de3fd17105481eeaf15d2478 100644 (file)
@@ -1,52 +1,52 @@
-.\" This file is part of the Public Domain C Library (PDCLib).\r
-.\" Permission is granted to use, modify, and / or redistribute at will.\r
-.\"\r
-.Dd\r
-.Dt abort 3\r
-.Os\r
-.\"\r
-.Sh NAME\r
-.Nm abort\r
-.Nd abnormal process termination\r
-.\"\r
-.Sh SYNOPSIS\r
-.In stdlib.h\r
-.Fn "noreturn void abort" "void"\r
-.\"\r
-.Sh DESCRIPTION\r
-.Fn abort\r
-causes abnormal process termination to occur.\r
-.\"\r
-.Pp\r
-First,\r
-.Dv SIGABRT\r
-will be raised, as if by\r
-.Fn raise SIGABRT .\r
-If the signal is not being caught, or the handler which catches the signal \r
-returns, \r
-.Fn abort\r
-will then proceed to cause the process to terminate with a failure exit status.\r
-It is implementation defined whether any open\r
-.Vt FILE\r
-streams are flushed before the process exits.\r
-.\"\r
-.Sh IMPLEMENTATION NOTES\r
-PDCLib implements termination (in the case that the \r
-.Dv SIGABRT\r
-handler returns) by calling\r
-.Fn _Exit EXIT_FAILURE .\r
-Therefore, stream flushing rules for\r
-.Nm\r
-follow those defined for\r
-.Fn _Exit .\r
-.\"\r
-.Sh SEE ALSO\r
-.Xr exit 3\r
-.Xr quick_exit 3\r
-.Xr _Exit 3\r
-.Xr raise 3\r
-.\"\r
-.Sh STANDARDS\r
-.Fn abort\r
-is first defined in\r
+.\" This file is part of the Public Domain C Library (PDCLib).
+.\" Permission is granted to use, modify, and / or redistribute at will.
+.\"
+.Dd
+.Dt abort 3
+.Os
+.\"
+.Sh NAME
+.Nm abort
+.Nd abnormal process termination
+.\"
+.Sh SYNOPSIS
+.In stdlib.h
+.Fn "noreturn void abort" "void"
+.\"
+.Sh DESCRIPTION
+.Fn abort
+causes abnormal process termination to occur.
+.\"
+.Pp
+First,
+.Dv SIGABRT
+will be raised, as if by
+.Fn raise SIGABRT .
+If the signal is not being caught, or the handler which catches the signal 
+returns, 
+.Fn abort
+will then proceed to cause the process to terminate with a failure exit status.
+It is implementation defined whether any open
+.Vt FILE
+streams are flushed before the process exits.
+.\"
+.Sh IMPLEMENTATION NOTES
+PDCLib implements termination (in the case that the 
+.Dv SIGABRT
+handler returns) by calling
+.Fn _Exit EXIT_FAILURE .
+Therefore, stream flushing rules for
+.Nm
+follow those defined for
+.Fn _Exit .
+.\"
+.Sh SEE ALSO
+.Xr exit 3
+.Xr quick_exit 3
+.Xr _Exit 3
+.Xr raise 3
+.\"
+.Sh STANDARDS
+.Fn abort
+is first defined in
 .St -isoC-90 .
\ No newline at end of file
index 09f9307b554e1e3783607b08a8eda8d269f1c062..937a68b77b870ca78aa1a869b2df9a4e1e8cf88b 100644 (file)
@@ -1,43 +1,43 @@
-.\" This file is part of the Public Domain C Library (PDCLib).\r
-.\" Permission is granted to use, modify, and / or redistribute at will.\r
-.\"\r
-.Dd\r
-.Dt assert 3\r
-.Os\r
-.\"\r
-.Sh NAME\r
-.Nm assert\r
-.Nd validate assertion\r
-.\"\r
-.Sh SYNOPSIS\r
-.In assert.h\r
-.Fn "void assert" "<scalar expression>"\r
-.\"\r
-.Sh DESCRIPTION\r
-If\r
-.Dv NDEBUG\r
-was defined when\r
-.In assert.h\r
-was last included, the macro\r
-.Nm\r
-results in no code being generated. Otherwise, if the expression evaluates to \r
-false, an error message is printed to \r
-.Va stderr\r
-and execution is terminated by invoking\r
-.Fn abort .\r
-.Sh IMPLEMENTATION NOTES\r
-The enclosing function of the call to\r
-.Nm\r
-will only be printed in the error message when compiling for C99, or a later\r
-revision of the C standard. \r
-.\"\r
-.Sh SEE ALSO\r
-.Xr _Exit 3\r
-.Xr quick_exit 3\r
-.Xr exit 3\r
-.Xr abort 3\r
-.\"\r
-.Sh STANDARDS\r
-Conforming to\r
-.St -isoC-90 ,\r
+.\" This file is part of the Public Domain C Library (PDCLib).
+.\" Permission is granted to use, modify, and / or redistribute at will.
+.\"
+.Dd
+.Dt assert 3
+.Os
+.\"
+.Sh NAME
+.Nm assert
+.Nd validate assertion
+.\"
+.Sh SYNOPSIS
+.In assert.h
+.Fn "void assert" "<scalar expression>"
+.\"
+.Sh DESCRIPTION
+If
+.Dv NDEBUG
+was defined when
+.In assert.h
+was last included, the macro
+.Nm
+results in no code being generated. Otherwise, if the expression evaluates to 
+false, an error message is printed to 
+.Va stderr
+and execution is terminated by invoking
+.Fn abort .
+.Sh IMPLEMENTATION NOTES
+The enclosing function of the call to
+.Nm
+will only be printed in the error message when compiling for C99, or a later
+revision of the C standard. 
+.\"
+.Sh SEE ALSO
+.Xr _Exit 3
+.Xr quick_exit 3
+.Xr exit 3
+.Xr abort 3
+.\"
+.Sh STANDARDS
+Conforming to
+.St -isoC-90 ,
 .St -isoC-99 .
\ No newline at end of file
index 1a532fa71fdc5d1bf2c91cc623565d322db4e419..58f1923e0875f5d5ac2bb4557da69444082ba861 100644 (file)
@@ -1,39 +1,39 @@
-.\" This file is part of the Public Domain C Library (PDCLib).\r
-.\" Permission is granted to use, modify, and / or redistribute at will.\r
-.\"\r
-.Dd\r
-.Dt ASSERT.H 3\r
-.Os\r
-.\"\r
-.Sh NAME\r
-.Nm assert.h\r
-.Nd verify program assertion\r
-.\"\r
-.Sh SYNOPSIS\r
-.In assert.h\r
-.\"\r
-.Sh DESCRIPTION\r
-The header\r
-.In assert.h\r
-shall define one macro:\r
-.Dv assert(<scalar expression>) .\r
-.Pp\r
-If\r
-.Dv NDEBUG\r
-was undefined at the most recent inclusion of this header, then it shall be\r
-defined as a macro which will evaluate the scalar expression and, if it is\r
-false, abort the program with a descriptive error message as defined in\r
-.Xr assert 3 .\r
-.\"\r
-.Pp\r
-If\r
-.Dv NDEBUG\r
-was defined at the most recent inclusion of this header, then it shall be\r
-defined as a macro which evaluates as a void expression and\r
-.Sy does not\r
-evaluate its parameter.\r
-.\"\r
-.Sh STANDARDS\r
-Conforming to\r
-.St -isoC-90 ,\r
+.\" This file is part of the Public Domain C Library (PDCLib).
+.\" Permission is granted to use, modify, and / or redistribute at will.
+.\"
+.Dd
+.Dt ASSERT.H 3
+.Os
+.\"
+.Sh NAME
+.Nm assert.h
+.Nd verify program assertion
+.\"
+.Sh SYNOPSIS
+.In assert.h
+.\"
+.Sh DESCRIPTION
+The header
+.In assert.h
+shall define one macro:
+.Dv assert(<scalar expression>) .
+.Pp
+If
+.Dv NDEBUG
+was undefined at the most recent inclusion of this header, then it shall be
+defined as a macro which will evaluate the scalar expression and, if it is
+false, abort the program with a descriptive error message as defined in
+.Xr assert 3 .
+.\"
+.Pp
+If
+.Dv NDEBUG
+was defined at the most recent inclusion of this header, then it shall be
+defined as a macro which evaluates as a void expression and
+.Sy does not
+evaluate its parameter.
+.\"
+.Sh STANDARDS
+Conforming to
+.St -isoC-90 ,
 .St -isoC-99 .
\ No newline at end of file
index 09fe18dfa1f7b7407869cc553639e79334f48023..7d1ea31ffe90a741024b9ee4f0584063a4aeaf1b 100644 (file)
-.\" This file is part of the Public Domain C Library (PDCLib).\r
-.\" Permission is granted to use, modify, and / or redistribute at will.\r
-.\"\r
-.Dd\r
-.Dt atexit 3\r
-.Os\r
-.\"\r
-.Sh NAME\r
-.Nm atexit\r
-.Nd registration of functions to be invoked before process termination\r
-.\"\r
-.Sh SYNOPSIS\r
-.In stdlib.h\r
-.Fn "int atexit" "void (*handler)(void)"\r
-.Fn "int at_quick_exit" "void (*handler)(void)" \r
-(C11, C++11)\r
-.\"\r
-.Sh DESCRIPTION\r
-These functions register a function to be called when the corresponding process\r
-exit function is invoked. For\r
-.Fn atexit \r
-the function will be invoked when the process is terminated by calling\r
-.Fn exit ;\r
-for\r
-.Fn at_quick_exit\r
-the function will be invoked when the process is terminated by calling\r
-.Fn quick_exit .\r
-.\"\r
-.Pp\r
-These functions are used in order to permit a program to perform actions before\r
-a process is terminated; for example, releasing an interprocess semaphore. \r
-Special care should be taken when writing \r
-.Fn at_quick_exit\r
-handlers; the purpose of \r
-.Fn quick_exit\r
-is to support the abandonning of a process when normal process termination might\r
-not be possible; at_quick_exit handlers should therefore be used sparingly and\r
-only when their use is essential.\r
-.\"\r
-.Pp\r
-The standard guarantees that \r
-.Fn atexit\r
-and\r
-.Fn at_quick_exit\r
-may each be called at least 32 times successfully.\r
-.\"\r
-.Pp\r
-.Fn atexit \r
-and\r
-.Fn at_quick_exit\r
-handlers are called in reverse order of the order they were registered in. For\r
-precise details of their ordering, see\r
-.Xr exit 3 .\r
-.\"\r
-.Pp\r
-The result of exiting from a handler registered with\r
-.Fn atexit\r
-or\r
-.Fn at_quick_exit\r
-by use of \r
-.Fn longjmp\r
-is undefined. If any function or destructor invoked by\r
-.Fn exit\r
-or\r
-.Fn quick_exit\r
-should throw, \r
-.Fn std::terminate\r
-is invoked.\r
-.\"\r
-.Pp\r
-Undefined behaviour results if an \r
-.Fn atexit\r
-or\r
-.Fn at_quick_exit\r
-handler calls\r
-.Fn exit\r
-or\r
-.Fn quick_exit . \r
-.\"\r
-.Sh RETURN VALUES\r
-Returns 0 to indicate success; nonzero returns indicate failure.\r
-.\"\r
-.Sh ERRORS\r
-No errors are defined\r
-.\"\r
-.Sh SEE ALSO\r
-.Xr abort 3\r
-.Xr exit 3\r
-.Xr quick_exit 3\r
-.Xr _Exit 3\r
-.\"\r
-.Sh STANDARDS\r
-.Fn atexit\r
-is first defined in\r
-.St -isoC-90 ;\r
-.Fn at_quick_exit\r
-was introduced in\r
-.St -isoC-2011 \r
-and\r
+.\" This file is part of the Public Domain C Library (PDCLib).
+.\" Permission is granted to use, modify, and / or redistribute at will.
+.\"
+.Dd
+.Dt atexit 3
+.Os
+.\"
+.Sh NAME
+.Nm atexit
+.Nd registration of functions to be invoked before process termination
+.\"
+.Sh SYNOPSIS
+.In stdlib.h
+.Fn "int atexit" "void (*handler)(void)"
+.Fn "int at_quick_exit" "void (*handler)(void)" 
+(C11, C++11)
+.\"
+.Sh DESCRIPTION
+These functions register a function to be called when the corresponding process
+exit function is invoked. For
+.Fn atexit 
+the function will be invoked when the process is terminated by calling
+.Fn exit ;
+for
+.Fn at_quick_exit
+the function will be invoked when the process is terminated by calling
+.Fn quick_exit .
+.\"
+.Pp
+These functions are used in order to permit a program to perform actions before
+a process is terminated; for example, releasing an interprocess semaphore. 
+Special care should be taken when writing 
+.Fn at_quick_exit
+handlers; the purpose of 
+.Fn quick_exit
+is to support the abandonning of a process when normal process termination might
+not be possible; at_quick_exit handlers should therefore be used sparingly and
+only when their use is essential.
+.\"
+.Pp
+The standard guarantees that 
+.Fn atexit
+and
+.Fn at_quick_exit
+may each be called at least 32 times successfully.
+.\"
+.Pp
+.Fn atexit 
+and
+.Fn at_quick_exit
+handlers are called in reverse order of the order they were registered in. For
+precise details of their ordering, see
+.Xr exit 3 .
+.\"
+.Pp
+The result of exiting from a handler registered with
+.Fn atexit
+or
+.Fn at_quick_exit
+by use of 
+.Fn longjmp
+is undefined. If any function or destructor invoked by
+.Fn exit
+or
+.Fn quick_exit
+should throw, 
+.Fn std::terminate
+is invoked.
+.\"
+.Pp
+Undefined behaviour results if an 
+.Fn atexit
+or
+.Fn at_quick_exit
+handler calls
+.Fn exit
+or
+.Fn quick_exit . 
+.\"
+.Sh RETURN VALUES
+Returns 0 to indicate success; nonzero returns indicate failure.
+.\"
+.Sh ERRORS
+No errors are defined
+.\"
+.Sh SEE ALSO
+.Xr abort 3
+.Xr exit 3
+.Xr quick_exit 3
+.Xr _Exit 3
+.\"
+.Sh STANDARDS
+.Fn atexit
+is first defined in
+.St -isoC-90 ;
+.Fn at_quick_exit
+was introduced in
+.St -isoC-2011 
+and
 ISO/IEC 14882:2011 "C++ 2011" .
\ No newline at end of file
index 80cb02d1be11d14bd79094b108590560630a6227..5beb46487d66cdd335a141e504f0f46d0acd7a38 100644 (file)
@@ -1,66 +1,66 @@
-.\" This file is part of the Public Domain C Library (PDCLib).\r
-.\" Permission is granted to use, modify, and / or redistribute at will.\r
-.\"\r
-.Dd\r
-.Dt ERRNO 3\r
-.Os\r
-.\"\r
-.Sh NAME\r
-.Nm errno\r
-.Nd library error result\r
-.\"\r
-.Sh SYNOPSIS\r
-.In errno.h\r
-.Pp\r
-.Sy #define errno <object of thread local storage duration>\r
-.\"\r
-.Sh DESCRIPTION\r
-The header\r
-.In errno.h\r
-defines the name\r
-.Va errno\r
-to refer to an object of thread local storage duration. It is undefined whether\r
-or not \r
-.Va errno\r
-refers to a preprocessor symbol or not.\r
-.\"\r
-.Pp\r
-At program startup, the runtime shall initialize\r
-.Va errno\r
-to contain the value zero (the initial value in other threads is undefined). It \r
-is guaranteed that no function provided by the C standard library shall set the \r
-value of \r
-.Va errno\r
-to zero; therefore, for functions which do not have a unique return value for\r
-indicating error, it is possible to determine whether an error occured by \r
-setting\r
-.Va errno\r
-to zero before the call, then after the call seeing if an error value has been\r
-stored into \r
-.Va errno.\r
-.Pp\r
-.Bf Sy\r
-Note that it is valid for any function which is not described as explicitly \r
-setting \r
-.Va errno \r
-to set it to a non-zero value. Checking for a non-zero value is only valid with\r
-functions which are defined to modify \r
-.Va errno .\r
-.Ef\r
-.\"\r
-.Pp\r
-In some historical versions of the POSIX standard, the prescribed method of \r
-using errno was to define\r
-.Va extern int errno .\r
-This is no longer supported by the POSIX or C standards, and will not work on \r
-the majority of implementations, including this one.\r
-.\"\r
-.Sh SEE ALSO\r
-.Xr errno.h 3\r
-.Xr abort 3\r
-.Xr assert 3\r
-\"\r
-.Sh STANDARDS\r
-Conforming to\r
-.St -isoC-90 ,\r
+.\" This file is part of the Public Domain C Library (PDCLib).
+.\" Permission is granted to use, modify, and / or redistribute at will.
+.\"
+.Dd
+.Dt ERRNO 3
+.Os
+.\"
+.Sh NAME
+.Nm errno
+.Nd library error result
+.\"
+.Sh SYNOPSIS
+.In errno.h
+.Pp
+.Sy #define errno <object of thread local storage duration>
+.\"
+.Sh DESCRIPTION
+The header
+.In errno.h
+defines the name
+.Va errno
+to refer to an object of thread local storage duration. It is undefined whether
+or not 
+.Va errno
+refers to a preprocessor symbol or not.
+.\"
+.Pp
+At program startup, the runtime shall initialize
+.Va errno
+to contain the value zero (the initial value in other threads is undefined). It 
+is guaranteed that no function provided by the C standard library shall set the 
+value of 
+.Va errno
+to zero; therefore, for functions which do not have a unique return value for
+indicating error, it is possible to determine whether an error occured by 
+setting
+.Va errno
+to zero before the call, then after the call seeing if an error value has been
+stored into 
+.Va errno.
+.Pp
+.Bf Sy
+Note that it is valid for any function which is not described as explicitly 
+setting 
+.Va errno 
+to set it to a non-zero value. Checking for a non-zero value is only valid with
+functions which are defined to modify 
+.Va errno .
+.Ef
+.\"
+.Pp
+In some historical versions of the POSIX standard, the prescribed method of 
+using errno was to define
+.Va extern int errno .
+This is no longer supported by the POSIX or C standards, and will not work on 
+the majority of implementations, including this one.
+.\"
+.Sh SEE ALSO
+.Xr errno.h 3
+.Xr abort 3
+.Xr assert 3
+\"
+.Sh STANDARDS
+Conforming to
+.St -isoC-90 ,
 .St -isoC-99 .
\ No newline at end of file
index a754d804870ddd0119172a280487678b7aba2dde..b9bd12af917e3b087a89ddeee9503e7ffabb9a97 100644 (file)
-.\" This file is part of the Public Domain C Library (PDCLib).\r
-.\" Permission is granted to use, modify, and / or redistribute at will.\r
-.\"\r
-.Dd\r
-.Dt ERRNO.H 3\r
-.Os\r
-.\"\r
-.Sh NAME\r
-.Nm errno.h\r
-.Nd error results\r
-.\"\r
-.Sh SYNOPSIS\r
-.In errno.h\r
-.\"\r
-.Sh DESCRIPTION\r
-The header defines the value\r
-.Dv errno\r
-to be an lvalue of thread-local storage duration.\r
-.\"\r
-.Pp\r
-From the ISO C standard, the following error code constants are defined:\r
-.Bl -tag -compact\r
-.It ERANGE\r
-indicating a value is out of range\r
-.It EDOM\r
-indicating that a value is outside the domain of the current function\r
-.It EILSEQ\r
-indicating an invalid character sequence\r
-.El\r
-.\"\r
-.Pp\r
-From the ISO C++ 2011 standard, the following error code constants are defined:\r
-.Bl -tag -compact\r
-.It E2BIG\r
-.It ECONNRESET\r
-.It EISCONN\r
-.It ENOENT\r
-.It ENOTRECOVERABLE\r
-.It EROFS\r
-.It EACCES\r
-.It EDEADLK\r
-.It EISDIR\r
-.It ENOEXEC\r
-.It ENOTSOCK\r
-.It ESPIPE\r
-.It EADDRINUSE\r
-.It EDESTADDRREQ\r
-.It ELOOP\r
-.It ENOLCK\r
-.It ENOTSUP\r
-.It ESRCH\r
-.It EADDRNOTAVAIL\r
-.It EMFILE\r
-.It ENOLINK\r
-.It ENOTTY\r
-.It ETIME\r
-.It EAFNOSUPPORT\r
-.It EEXIST\r
-.It EMLINK\r
-.It ENOMEM\r
-.It ENXIO\r
-.It ETIMEDOUT\r
-.It EAGAIN\r
-.It EFAULT\r
-.It EMSGSIZE\r
-.It ENOMSG\r
-.It EOPNOTSUPP\r
-.It ETXTBSY\r
-.It EALREADY\r
-.It EFBIG\r
-.It ENAMETOOLONG\r
-.It ENOPROTOOPT\r
-.It EOVERFLOW\r
-.It EWOULDBLOCK\r
-(which may have the same value as \r
-.Ev EAGAIN )\r
-.It EBADF\r
-.It EHOSTUNREACH\r
-.It ENETDOWN\r
-.It ENOSPC\r
-.It EOWNERDEAD\r
-.It EXDEV\r
-.It EBADMSG\r
-.It EIDRM\r
-.It ENETRESET\r
-.It ENOSR\r
-.It EPERM\r
-.It EBUSY\r
-.It ENETUNREACH\r
-.It ENOSTR\r
-.It EPIPE\r
-.It ECANCELED\r
-.It EINPROGRESS\r
-.It ENFILE\r
-.It ENOSYS\r
-.It EPROTO\r
-.It ECHILD\r
-.It EINTR\r
-.It ENOBUFS\r
-.It ENOTCONN\r
-.It EPROTONOSUPPORT\r
-.It ECONNABORTED\r
-.It EINVAL\r
-.It ENODATA\r
-.It ENOTDIR\r
-.It EPROTOTYPE\r
-.El\r
-.Sh SEE ALSO\r
-.Xr errno 3\r
-.Sh STANDARDS\r
-Conforming to\r
-.St -isoC-90 ,\r
-.St -isoC-99 , \r
+.\" This file is part of the Public Domain C Library (PDCLib).
+.\" Permission is granted to use, modify, and / or redistribute at will.
+.\"
+.Dd
+.Dt ERRNO.H 3
+.Os
+.\"
+.Sh NAME
+.Nm errno.h
+.Nd error results
+.\"
+.Sh SYNOPSIS
+.In errno.h
+.\"
+.Sh DESCRIPTION
+The header defines the value
+.Dv errno
+to be an lvalue of thread-local storage duration.
+.\"
+.Pp
+From the ISO C standard, the following error code constants are defined:
+.Bl -tag -compact
+.It ERANGE
+indicating a value is out of range
+.It EDOM
+indicating that a value is outside the domain of the current function
+.It EILSEQ
+indicating an invalid character sequence
+.El
+.\"
+.Pp
+From the ISO C++ 2011 standard, the following error code constants are defined:
+.Bl -tag -compact
+.It E2BIG
+.It ECONNRESET
+.It EISCONN
+.It ENOENT
+.It ENOTRECOVERABLE
+.It EROFS
+.It EACCES
+.It EDEADLK
+.It EISDIR
+.It ENOEXEC
+.It ENOTSOCK
+.It ESPIPE
+.It EADDRINUSE
+.It EDESTADDRREQ
+.It ELOOP
+.It ENOLCK
+.It ENOTSUP
+.It ESRCH
+.It EADDRNOTAVAIL
+.It EMFILE
+.It ENOLINK
+.It ENOTTY
+.It ETIME
+.It EAFNOSUPPORT
+.It EEXIST
+.It EMLINK
+.It ENOMEM
+.It ENXIO
+.It ETIMEDOUT
+.It EAGAIN
+.It EFAULT
+.It EMSGSIZE
+.It ENOMSG
+.It EOPNOTSUPP
+.It ETXTBSY
+.It EALREADY
+.It EFBIG
+.It ENAMETOOLONG
+.It ENOPROTOOPT
+.It EOVERFLOW
+.It EWOULDBLOCK
+(which may have the same value as 
+.Ev EAGAIN )
+.It EBADF
+.It EHOSTUNREACH
+.It ENETDOWN
+.It ENOSPC
+.It EOWNERDEAD
+.It EXDEV
+.It EBADMSG
+.It EIDRM
+.It ENETRESET
+.It ENOSR
+.It EPERM
+.It EBUSY
+.It ENETUNREACH
+.It ENOSTR
+.It EPIPE
+.It ECANCELED
+.It EINPROGRESS
+.It ENFILE
+.It ENOSYS
+.It EPROTO
+.It ECHILD
+.It EINTR
+.It ENOBUFS
+.It ENOTCONN
+.It EPROTONOSUPPORT
+.It ECONNABORTED
+.It EINVAL
+.It ENODATA
+.It ENOTDIR
+.It EPROTOTYPE
+.El
+.Sh SEE ALSO
+.Xr errno 3
+.Sh STANDARDS
+Conforming to
+.St -isoC-90 ,
+.St -isoC-99 , 
 ISO/IEC 14882:2011 "ISO C++ 11"
\ No newline at end of file
index 4d9860ee7abf5c3c04b139cc1c67fe8f2e0a9350..18f53e827ef91b0850a153ee9705466f447aec21 100644 (file)
-.\" This file is part of the Public Domain C Library (PDCLib).\r
-.\" Permission is granted to use, modify, and / or redistribute at will.\r
-.\"\r
-.Dd\r
-.Dt exit 3\r
-.Os\r
-.\"\r
-.Sh NAME\r
-.Nm exit\r
-.Nd terminates the process\r
-.\"\r
-.Sh SYNOPSIS\r
-.In stdlib.h\r
-.Fn "noreturn void exit" "int status"\r
-.Fn "noreturn void quick_exit" "int status"\r
-.Fn "noreturn void _Exit" "int exitcode"\r
-.\"\r
-.Sh DESCRIPTION\r
-Calling any of these three functions terminates the current process, returning \r
-the exit code passed as a parameter. The interpretation of the exit code is \r
-undefined, except that 0 or\r
-.Dv EXIT_SUCCESS\r
-shall indicate successful completion and\r
-.Dv EXIT_FAILURE\r
-shall indicate a non-successful completion.\r
-.\"\r
-.Pp\r
-.Fn exit\r
-first destroys all objects with C++ thread local storage duration (the C \r
-standard leaves whether or not thread local objects are destroyed or not \r
-undefined). Next, the destructors of all C++ objects of static storage duration \r
-are invoked along with all functions passed to\r
-.Fn atexit \r
-in reverse order of registration (the time of registration for C++ objects of \r
-static storage duration is taken to be the time at which the constructor \r
-completes). It then flushes all open\r
-.Vt FILE\r
-streams with unwritten data and closes them. Finally, files created by\r
-.Fn tmpfile\r
-are removed, before handing control back to the host environment. Note in \r
-particular that functions registered with\r
-.Fn at_quick_exit\r
-are\r
-.Sy not\r
-called.\r
-.\"\r
-.Pp\r
-.Fn quick_exit\r
-invokes any functions registered with\r
-.Fn at_quick_exit\r
-in reverse order of registration, then returns control to the host \r
-environment by calling\r
-.Fn _Exit .\r
-No signal handlers are called, nor are any functions registered with\r
-.Fn atexit .\r
-.\"\r
-.Pp\r
-.Fn _Exit\r
-returns control to the controlling environment without invoking any functions\r
-registered by\r
-.Fn atexit ,\r
-.Fn at_quick_exit ,\r
-any signal handlers, or the destructors of any thread local objects or C++ \r
-objects of static storage duration. Whether or not any open \r
-.Vt FILE\r
-streams with unwritten data are flushed or not is undefined.\r
-.\"\r
-.Pp\r
-The result of aborting a call to \r
-.Fn exit\r
-or\r
-.Fn quick_exit\r
-by use of \r
-.Fn longjmp\r
-is undefined. If any function or destructor invoked by\r
-.Fn exit\r
-or\r
-.Fn quick_exit\r
-should throw, \r
-.Fn std::terminate\r
-is invoked.\r
-.\"\r
-.Pp\r
-Undefined behaviour results if, while a call to\r
-.Fn exit\r
-or\r
-.Fn quick_exit\r
-is in progress, a call to \r
-.Fn exit\r
-or\r
-.Fn quick_exit\r
-is made. \r
-.\"\r
-.Sh IMPLEMENTATION NOTES\r
-PDCLib implements the process of flushing streams in\r
-.Fn _Exit ,\r
-and therefore\r
-.Fn exit\r
-calls it after all\r
-.Fn atexit\r
-handlers have been invoked.\r
-.\"\r
-.Sh SEE ALSO\r
-.Xr abort 3\r
-.Xr atexit 3\r
-.Xr at_quick_exit 3\r
-.\"\r
-.Sh STANDARDS\r
-.Fn exit\r
-is first defined in\r
-.St -isoC-90 ;\r
-.Fn _Exit\r
-was introduced in\r
-.St -isoC-99 .\r
-.Fn quick_exit\r
-was introduced in\r
-.St -isoC-11 \r
-and\r
+.\" This file is part of the Public Domain C Library (PDCLib).
+.\" Permission is granted to use, modify, and / or redistribute at will.
+.\"
+.Dd
+.Dt exit 3
+.Os
+.\"
+.Sh NAME
+.Nm exit
+.Nd terminates the process
+.\"
+.Sh SYNOPSIS
+.In stdlib.h
+.Fn "noreturn void exit" "int status"
+.Fn "noreturn void quick_exit" "int status"
+.Fn "noreturn void _Exit" "int exitcode"
+.\"
+.Sh DESCRIPTION
+Calling any of these three functions terminates the current process, returning 
+the exit code passed as a parameter. The interpretation of the exit code is 
+undefined, except that 0 or
+.Dv EXIT_SUCCESS
+shall indicate successful completion and
+.Dv EXIT_FAILURE
+shall indicate a non-successful completion.
+.\"
+.Pp
+.Fn exit
+first destroys all objects with C++ thread local storage duration (the C 
+standard leaves whether or not thread local objects are destroyed or not 
+undefined). Next, the destructors of all C++ objects of static storage duration 
+are invoked along with all functions passed to
+.Fn atexit 
+in reverse order of registration (the time of registration for C++ objects of 
+static storage duration is taken to be the time at which the constructor 
+completes). It then flushes all open
+.Vt FILE
+streams with unwritten data and closes them. Finally, files created by
+.Fn tmpfile
+are removed, before handing control back to the host environment. Note in 
+particular that functions registered with
+.Fn at_quick_exit
+are
+.Sy not
+called.
+.\"
+.Pp
+.Fn quick_exit
+invokes any functions registered with
+.Fn at_quick_exit
+in reverse order of registration, then returns control to the host 
+environment by calling
+.Fn _Exit .
+No signal handlers are called, nor are any functions registered with
+.Fn atexit .
+.\"
+.Pp
+.Fn _Exit
+returns control to the controlling environment without invoking any functions
+registered by
+.Fn atexit ,
+.Fn at_quick_exit ,
+any signal handlers, or the destructors of any thread local objects or C++ 
+objects of static storage duration. Whether or not any open 
+.Vt FILE
+streams with unwritten data are flushed or not is undefined.
+.\"
+.Pp
+The result of aborting a call to 
+.Fn exit
+or
+.Fn quick_exit
+by use of 
+.Fn longjmp
+is undefined. If any function or destructor invoked by
+.Fn exit
+or
+.Fn quick_exit
+should throw, 
+.Fn std::terminate
+is invoked.
+.\"
+.Pp
+Undefined behaviour results if, while a call to
+.Fn exit
+or
+.Fn quick_exit
+is in progress, a call to 
+.Fn exit
+or
+.Fn quick_exit
+is made. 
+.\"
+.Sh IMPLEMENTATION NOTES
+PDCLib implements the process of flushing streams in
+.Fn _Exit ,
+and therefore
+.Fn exit
+calls it after all
+.Fn atexit
+handlers have been invoked.
+.\"
+.Sh SEE ALSO
+.Xr abort 3
+.Xr atexit 3
+.Xr at_quick_exit 3
+.\"
+.Sh STANDARDS
+.Fn exit
+is first defined in
+.St -isoC-90 ;
+.Fn _Exit
+was introduced in
+.St -isoC-99 .
+.Fn quick_exit
+was introduced in
+.St -isoC-11 
+and
 ISO/IEC 14882:2011 "C++ 2011" .
\ No newline at end of file
index 8473fa9cf0e392228672f08e390f5135bbf13f36..bfc9adcf4b9e5c54dc7cd94c531d4b43d04ec9b2 100644 (file)
@@ -1,56 +1,56 @@
-.\" This file is part of the Public Domain C Library (PDCLib).\r
-.\" Permission is granted to use, modify, and / or redistribute at will.\r
-.\"\r
-.Dd\r
-.Dt flockfile 3\r
-.Os\r
-.\"\r
-.Sh NAME\r
-.Nm flockfile, ftrylockfile, funlockfile\r
-.Nd stdio file locking\r
-.\"\r
-.Sh SYNOPSIS\r
-.Sy #define _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600 || _SVID_SOURCE || _BSD_SOURCE\r
-.\"\r
-.In stdio.h\r
-.Fn "void flockfile" "FILE *file"\r
-.Fn "int ftrylockfile" "FILE *file"\r
-.Fn "void funlockfile" "FILE *file"\r
-.\"\r
-.Sh DESCRIPTION\r
-.Fn flockfile\r
-locks the passed FILE stream for access by the calling thread, potentially \r
-blocking. \r
-.Fn ftrylockfile\r
-attempts to lock the file for the calling thread, but will return failure if\r
-another thread has already locked the file.\r
-.Fn funlockfile\r
-releases the lock on the stream, allowing another thread in the process to \r
-access it.\r
-.\"\r
-.Pp\r
-The same stream may be locked multiple times by the calling thread; the number \r
-of calls to \r
-.Fn flockfile \r
-and \r
-.Fn ftrylockfile\r
-on a file must be equal to the number of calls to\r
-.Fn funlockfile .\r
-.\"\r
-.Pp\r
-No other thread may do I/O through the locked file while it is locked.\r
-.\"\r
-.Sh IMPLEMENTATION NOTES\r
-PDCLib implements the file locking on top of the Mutex primitives added by C11\r
-.\"\r
-.Sh SEE ALSO\r
-.Xr fopen 3\r
-.Xr fclose 3\r
-.Xr unlocked_stdio 3\r
-.Xr mtx_t 3\r
-.\"\r
-.Sh STANDARDS\r
-The locked I/O routines were initially introduced in \r
-.St -svid4 ,\r
-and incorporated into POSIX in \r
+.\" This file is part of the Public Domain C Library (PDCLib).
+.\" Permission is granted to use, modify, and / or redistribute at will.
+.\"
+.Dd
+.Dt flockfile 3
+.Os
+.\"
+.Sh NAME
+.Nm flockfile, ftrylockfile, funlockfile
+.Nd stdio file locking
+.\"
+.Sh SYNOPSIS
+.Sy #define _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600 || _SVID_SOURCE || _BSD_SOURCE
+.\"
+.In stdio.h
+.Fn "void flockfile" "FILE *file"
+.Fn "int ftrylockfile" "FILE *file"
+.Fn "void funlockfile" "FILE *file"
+.\"
+.Sh DESCRIPTION
+.Fn flockfile
+locks the passed FILE stream for access by the calling thread, potentially 
+blocking. 
+.Fn ftrylockfile
+attempts to lock the file for the calling thread, but will return failure if
+another thread has already locked the file.
+.Fn funlockfile
+releases the lock on the stream, allowing another thread in the process to 
+access it.
+.\"
+.Pp
+The same stream may be locked multiple times by the calling thread; the number 
+of calls to 
+.Fn flockfile 
+and 
+.Fn ftrylockfile
+on a file must be equal to the number of calls to
+.Fn funlockfile .
+.\"
+.Pp
+No other thread may do I/O through the locked file while it is locked.
+.\"
+.Sh IMPLEMENTATION NOTES
+PDCLib implements the file locking on top of the Mutex primitives added by C11
+.\"
+.Sh SEE ALSO
+.Xr fopen 3
+.Xr fclose 3
+.Xr unlocked_stdio 3
+.Xr mtx_t 3
+.\"
+.Sh STANDARDS
+The locked I/O routines were initially introduced in 
+.St -svid4 ,
+and incorporated into POSIX in 
 .St -p1003.1-2001 .
\ No newline at end of file
index 7e84ae11a68fed1f6cb8992d1c4685db093fa6a8..8c8e5443fd7c1827a699ab2b741d6c645c7a6dd9 100644 (file)
@@ -1,58 +1,58 @@
-.\" This file is part of the Public Domain C Library (PDCLib).\r
-.\" Permission is granted to use, modify, and / or redistribute at will.\r
-.\"\r
-.Dd\r
-.Dt MBSINIT 3\r
-.Os\r
-.\"\r
-.Sh NAME\r
-.Nm mbsinit\r
-.Nd determines multibyte conversion state\r
-.\"\r
-.Sh SYNOPSIS\r
-.In wchar.h\r
-.Fn "int mbsinit" "const mbstate_t *ps"\r
-.In xlocale.h\r
-.Fn "int mbsinit_l" "const mbstate_t *ps" "locale_t loc"\r
-.\"\r
-.Sh DESCRIPTION\r
-.Fn mbsinit \r
-and\r
-.Fn mbsinit_l \r
-shall return a nonzero value if the multibyte converison state pointed to by\r
-.Va ps\r
-corresponds to an initial conversion state. The interpretation of \r
-.Va *ps\r
-is locale dependent; the only guarantee is that an\r
-.Vt mbstate_t\r
-object initialized to zero shall correspond to an initial conversion state. If\r
-.Va ps\r
-is\r
-.Dv NULL ,\r
-then a nonzero value shall be returned.\r
-.\"\r
-.Pp\r
-The locale used for \r
-.Fn mbsinit\r
-shall be the currently active locale; either the current thread locale as set by\r
-.Xr uselocale 3\r
-if one has been specified, or otherwise the global locale controlled by\r
-.Xr setlocale 3 .\r
-The locale used by \r
-.Fn mbsinit_l\r
-is that specified by\r
-.Va loc .\r
-.\"\r
-.Sh SEE ALSO\r
-.Xr mbrtowc 3\r
-.Xr wcrtomb 3\r
-.Xr setlocale 3\r
-.Xr uselocale 3\r
-.\"\r
-.Sh STANDARDS\r
-.Fn mbsinit\r
-is first defined in\r
-.St -isoC-amd1 ;\r
-.Fn mbsinit_l\r
-is a nonstandard extension originating in Darwin. See\r
+.\" This file is part of the Public Domain C Library (PDCLib).
+.\" Permission is granted to use, modify, and / or redistribute at will.
+.\"
+.Dd
+.Dt MBSINIT 3
+.Os
+.\"
+.Sh NAME
+.Nm mbsinit
+.Nd determines multibyte conversion state
+.\"
+.Sh SYNOPSIS
+.In wchar.h
+.Fn "int mbsinit" "const mbstate_t *ps"
+.In xlocale.h
+.Fn "int mbsinit_l" "const mbstate_t *ps" "locale_t loc"
+.\"
+.Sh DESCRIPTION
+.Fn mbsinit 
+and
+.Fn mbsinit_l 
+shall return a nonzero value if the multibyte converison state pointed to by
+.Va ps
+corresponds to an initial conversion state. The interpretation of 
+.Va *ps
+is locale dependent; the only guarantee is that an
+.Vt mbstate_t
+object initialized to zero shall correspond to an initial conversion state. If
+.Va ps
+is
+.Dv NULL ,
+then a nonzero value shall be returned.
+.\"
+.Pp
+The locale used for 
+.Fn mbsinit
+shall be the currently active locale; either the current thread locale as set by
+.Xr uselocale 3
+if one has been specified, or otherwise the global locale controlled by
+.Xr setlocale 3 .
+The locale used by 
+.Fn mbsinit_l
+is that specified by
+.Va loc .
+.\"
+.Sh SEE ALSO
+.Xr mbrtowc 3
+.Xr wcrtomb 3
+.Xr setlocale 3
+.Xr uselocale 3
+.\"
+.Sh STANDARDS
+.Fn mbsinit
+is first defined in
+.St -isoC-amd1 ;
+.Fn mbsinit_l
+is a nonstandard extension originating in Darwin. See
 .Xr xlocale.h 3
\ No newline at end of file
index 8773c2684af678ef65308036144d2d13d0536e8f..dd8e8c12e77282eeb7d0f3270fc4bd57d217c091 100644 (file)
@@ -1,96 +1,96 @@
-.\" This file is part of the Public Domain C Library (PDCLib).\r
-.\" Permission is granted to use, modify, and / or redistribute at will.\r
-.\"\r
-.Dd\r
-.Dt PDCLIB 3\r
-.Os\r
-.\"\r
-.Sh NAME\r
-.Nm PDCLib\r
-.Nd Public domain, portable C library\r
-.\"\r
-.Sh LIBRARY\r
-.Lb pdclib\r
-.Sh SYNOPSIS\r
-.In assert.h\r
-.In ctype.h\r
-.In errno.h\r
-.In inttypes.h\r
-.In iso646.h\r
-.In limits.h\r
-.In locale.h\r
-.In signal.h\r
-.In stdarg.h\r
-.In stdbool.h\r
-.In stddef.h\r
-.In stdint.h\r
-.In stdio.h\r
-.In stdlib.h\r
-.In stdnoreturn.h\r
-.In string.h\r
-.In threads.h\r
-.In time.h\r
-.In wchar.h\r
-.\"\r
-.Sh DESCRIPTION\r
-The\r
-.Nm\r
-library is a portable, public domain C library. It aims at full conformance with\r
-ISO C89, C95, C99 and C11 when used in combination with a conformant compiler. \r
-In addition, it aims at conformance with the portion of ISO C++97 and C++2011 \r
-which is derived from said standards.\r
-.Pp\r
-.Nm\r
-aims for strict conformance with the selected C/C++ standard. Therefore, unlike\r
-most C libraries, it does not by default expose any extensions. Some extensions\r
-(from POSIX or the Single Unix Specification) can be selected by defining the \r
-appropriate feature selection macro, such as \r
-.Dv _POSIX_C_SOURCE\r
-or\r
-.Dv _XOPEN_SOURCE\r
-to the appropriate value. For example, in the following definition:\r
-.Bd -offset indent\r
-.Sy #define _XOPEN_SOURCE || _POSIX_C_SOURCE >= 200809L\r
-.br\r
-.Sy #include\r
-.In string.h\r
-.br\r
-.Fn "char * strdup" "const char *"\r
-.Ed\r
-.\"\r
-it is documented that defining either \r
-.Dv _XOPEN_SOURCE\r
-or\r
-.Dv _POSIX_C_SOURCE\r
-to have a value greater than\r
-.Li 200809L\r
-before the first inclusion of\r
-.In string.h\r
-will expose a definition of the function\r
-.Fn strdup\r
-.\"\r
-.Sh SEE ALSO\r
-.Xr cc 1 ,\r
-.Xr c++ 7\r
-.Sh STANDARDS\r
-When compiled with a C compiler, conformant with \r
-.St -isoC-90 ,\r
-.St -isoC-amd1 ,\r
-.St -isoC-tcor1 ,\r
-.St -isoC-tcor2 ,\r
-.St -isoC-99 or\r
-.St -isoC-2011\r
-as dependent upon the version of C the compiler declares conformance with.\r
-.Pp\r
-When compiled with a C++ compiler, conformant with ISO/IEC 14882:1997 or ISO/IEC\r
-14882:2011 "The C++ Programming Language" as dependent upon the version of C++\r
-the compiler declares conformance with.\r
-.Sh AUTHORS\r
-The\r
-.Nm\r
-library is maintained by by\r
-.An Owen Shepherd ,\r
-.Mt pdclib@owenshepherd.net .\r
-Based upon work by\r
-.An Martin "Solar" Baute ,\r
+.\" This file is part of the Public Domain C Library (PDCLib).
+.\" Permission is granted to use, modify, and / or redistribute at will.
+.\"
+.Dd
+.Dt PDCLIB 3
+.Os
+.\"
+.Sh NAME
+.Nm PDCLib
+.Nd Public domain, portable C library
+.\"
+.Sh LIBRARY
+.Lb pdclib
+.Sh SYNOPSIS
+.In assert.h
+.In ctype.h
+.In errno.h
+.In inttypes.h
+.In iso646.h
+.In limits.h
+.In locale.h
+.In signal.h
+.In stdarg.h
+.In stdbool.h
+.In stddef.h
+.In stdint.h
+.In stdio.h
+.In stdlib.h
+.In stdnoreturn.h
+.In string.h
+.In threads.h
+.In time.h
+.In wchar.h
+.\"
+.Sh DESCRIPTION
+The
+.Nm
+library is a portable, public domain C library. It aims at full conformance with
+ISO C89, C95, C99 and C11 when used in combination with a conformant compiler. 
+In addition, it aims at conformance with the portion of ISO C++97 and C++2011 
+which is derived from said standards.
+.Pp
+.Nm
+aims for strict conformance with the selected C/C++ standard. Therefore, unlike
+most C libraries, it does not by default expose any extensions. Some extensions
+(from POSIX or the Single Unix Specification) can be selected by defining the 
+appropriate feature selection macro, such as 
+.Dv _POSIX_C_SOURCE
+or
+.Dv _XOPEN_SOURCE
+to the appropriate value. For example, in the following definition:
+.Bd -offset indent
+.Sy #define _XOPEN_SOURCE || _POSIX_C_SOURCE >= 200809L
+.br
+.Sy #include
+.In string.h
+.br
+.Fn "char * strdup" "const char *"
+.Ed
+.\"
+it is documented that defining either 
+.Dv _XOPEN_SOURCE
+or
+.Dv _POSIX_C_SOURCE
+to have a value greater than
+.Li 200809L
+before the first inclusion of
+.In string.h
+will expose a definition of the function
+.Fn strdup
+.\"
+.Sh SEE ALSO
+.Xr cc 1 ,
+.Xr c++ 7
+.Sh STANDARDS
+When compiled with a C compiler, conformant with 
+.St -isoC-90 ,
+.St -isoC-amd1 ,
+.St -isoC-tcor1 ,
+.St -isoC-tcor2 ,
+.St -isoC-99 or
+.St -isoC-2011
+as dependent upon the version of C the compiler declares conformance with.
+.Pp
+When compiled with a C++ compiler, conformant with ISO/IEC 14882:1997 or ISO/IEC
+14882:2011 "The C++ Programming Language" as dependent upon the version of C++
+the compiler declares conformance with.
+.Sh AUTHORS
+The
+.Nm
+library is maintained by by
+.An Owen Shepherd ,
+.Mt pdclib@owenshepherd.net .
+Based upon work by
+.An Martin "Solar" Baute ,
 .Mt solar@rootdirectory.de .
\ No newline at end of file
index 78e77e64f0cdf072745980093460c37e0faa7db8..a474e2f747a3af3183eb9c16d647ebf7cb1bb6e9 100644 (file)
-.\" This file is part of the Public Domain C Library (PDCLib).\r
-.\" Permission is granted to use, modify, and / or redistribute at will.\r
-.\"\r
-.Dd\r
-.Dt posix_locale 3\r
-.Os\r
-.\"\r
-.Sh NAME\r
-.Nm posix_locale\r
-.Nd POSIX extended locale functions\r
-.\"\r
-.Sh SYNOPSIS\r
-.Sy #define _POSIX_C_SOURCE >= 200112L\r
-.In locale.h\r
-.Vt typedef <anonymous> locale_t;\r
-.br\r
-#define \r
-.Va LC_GLOBAL_LOCALE\r
-<constant of type locale_t>;\r
-.Fn "locale_t uselocale" "locale_t newlocale"\r
-.Fn "locale_t duplocale" "locale_t loc"\r
-.Fn "locale_t newlocale" "int category_mask" "const char *locale" "locale_t base"\r
-.Fn "void freelocale" "locale_t loc"\r
-.\"\r
-.Sh DESCRIPTION\r
-The ISO C standard defines the\r
-.Xr setlocale 3\r
-function, which can be used for modifying the application global locale. In \r
-multithreaded programs, it can sometimes be useful to allow a thread to, either\r
-temporarily or permanently, assume a different locale from the rest of the \r
-application. POSIX defines extended locale functions which permit this.\r
-.\"\r
-.Pp\r
-The function\r
-.Fn uselocale\r
-is used to change the locale of the current thread. If \r
-.Fa newlocale\r
-is the symbolic constant\r
-.Dv LC_GLOBAL_LOCALE ,\r
-then the thread locale will be set to the application global locale. If\r
-.Fa newlocale\r
-is\r
-.Dv NULL ,\r
-then the locale will not be changed. Otherwise, \r
-.Fa newlocale\r
-should be a value returned from either of the\r
-.Fn newlocale\r
-or\r
-.Fn duplocale\r
-functions. The return value will be the previous thread locale; or \r
-.Dv LC_GLOBAL_LOCALE\r
-if the thread has no current locale.\r
-.Pp\r
-.\"\r
-The function\r
-.Fn duplocale\r
-is used to make an exact copy of an existing locale. The passed locale object \r
-must have been returned from a call to either\r
-.Fn duplocale\r
-or\r
-.Fn newlocale .\r
-.Pp\r
-.\"\r
-The function\r
-.Fn newlocale\r
-is used to modify an existing locale or create a new locale. The returned locale\r
-will have the properties defined by\r
-.Fa category_mask\r
-set to the values from\r
-.Fa locale\r
-as per \r
-.Xr setlocale 3 ,\r
-with the remainder being taken from either\r
-.Fa base\r
-(which must be a locale object previously returned by\r
-.Fn duplocale\r
-or\r
-.Fn newlocale )\r
-if it is specified, or otherwise from the "C" locale.\r
-.Pp\r
-It is undefined if \r
-.Fn newlocale\r
-modifies\r
-.Fa base\r
-or frees it and creates a new locale.\r
-.Pp\r
-.\"\r
-The \r
-.Fn freelocale\r
-function is used to free a locale previously created via\r
-.Fn duplocale\r
-or\r
-.Fn newlocale .\r
-.\"\r
-.\"\r
-.Sh ERRORS\r
-For uselocale,\r
-.Er EINVAL\r
-may be returned if\r
-.Fa locale\r
-is not a valid locale.\r
-.Pp\r
-.\"\r
-For \r
-.Fn duplocale ,\r
-.Bl -tag -width 8\r
-.It Er EINVAL\r
-may be returned if\r
-.Fa locale\r
-is not a valid locale\r
-.It Er ENOMEM\r
-shall be returned if the system had insufficient memory to satisfy the request.\r
-.El\r
-.Pp\r
-.\"\r
-For \r
-.Fn newlocale ,\r
-.Bl -tag -width 8\r
-.It Er EINVAL\r
-shall be returned if \r
-.Fa category_mask\r
-contains a bit which does not correspond to a valid category, and may be \r
-returned if\r
-.Fa locale\r
-is not a valid locale object.\r
-.It Er ENOMEM\r
-shall be returned if the system did not have enough memory to allocate a new \r
-locale object or read the locale data\r
-.It Er ENOENT\r
-shall be returned if the locale specified does not contain data for all the \r
-specified categories\r
-.El\r
-.Pp\r
-.\"\r
-.Fn freelocale\r
-has no errors\r
-.\"\r
-.Sh IMPLEMENTATION NOTES\r
-None\r
-.\"\r
-.Sh SEE ALSO\r
-.Xr lconv 3\r
-.Xr setlocale 3\r
-.\"\r
-.Sh STANDARDS\r
-Conforming to\r
+.\" This file is part of the Public Domain C Library (PDCLib).
+.\" Permission is granted to use, modify, and / or redistribute at will.
+.\"
+.Dd
+.Dt posix_locale 3
+.Os
+.\"
+.Sh NAME
+.Nm posix_locale
+.Nd POSIX extended locale functions
+.\"
+.Sh SYNOPSIS
+.Sy #define _POSIX_C_SOURCE >= 200112L
+.In locale.h
+.Vt typedef <anonymous> locale_t;
+.br
+#define 
+.Va LC_GLOBAL_LOCALE
+<constant of type locale_t>;
+.Fn "locale_t uselocale" "locale_t newlocale"
+.Fn "locale_t duplocale" "locale_t loc"
+.Fn "locale_t newlocale" "int category_mask" "const char *locale" "locale_t base"
+.Fn "void freelocale" "locale_t loc"
+.\"
+.Sh DESCRIPTION
+The ISO C standard defines the
+.Xr setlocale 3
+function, which can be used for modifying the application global locale. In 
+multithreaded programs, it can sometimes be useful to allow a thread to, either
+temporarily or permanently, assume a different locale from the rest of the 
+application. POSIX defines extended locale functions which permit this.
+.\"
+.Pp
+The function
+.Fn uselocale
+is used to change the locale of the current thread. If 
+.Fa newlocale
+is the symbolic constant
+.Dv LC_GLOBAL_LOCALE ,
+then the thread locale will be set to the application global locale. If
+.Fa newlocale
+is
+.Dv NULL ,
+then the locale will not be changed. Otherwise, 
+.Fa newlocale
+should be a value returned from either of the
+.Fn newlocale
+or
+.Fn duplocale
+functions. The return value will be the previous thread locale; or 
+.Dv LC_GLOBAL_LOCALE
+if the thread has no current locale.
+.Pp
+.\"
+The function
+.Fn duplocale
+is used to make an exact copy of an existing locale. The passed locale object 
+must have been returned from a call to either
+.Fn duplocale
+or
+.Fn newlocale .
+.Pp
+.\"
+The function
+.Fn newlocale
+is used to modify an existing locale or create a new locale. The returned locale
+will have the properties defined by
+.Fa category_mask
+set to the values from
+.Fa locale
+as per 
+.Xr setlocale 3 ,
+with the remainder being taken from either
+.Fa base
+(which must be a locale object previously returned by
+.Fn duplocale
+or
+.Fn newlocale )
+if it is specified, or otherwise from the "C" locale.
+.Pp
+It is undefined if 
+.Fn newlocale
+modifies
+.Fa base
+or frees it and creates a new locale.
+.Pp
+.\"
+The 
+.Fn freelocale
+function is used to free a locale previously created via
+.Fn duplocale
+or
+.Fn newlocale .
+.\"
+.\"
+.Sh ERRORS
+For uselocale,
+.Er EINVAL
+may be returned if
+.Fa locale
+is not a valid locale.
+.Pp
+.\"
+For 
+.Fn duplocale ,
+.Bl -tag -width 8
+.It Er EINVAL
+may be returned if
+.Fa locale
+is not a valid locale
+.It Er ENOMEM
+shall be returned if the system had insufficient memory to satisfy the request.
+.El
+.Pp
+.\"
+For 
+.Fn newlocale ,
+.Bl -tag -width 8
+.It Er EINVAL
+shall be returned if 
+.Fa category_mask
+contains a bit which does not correspond to a valid category, and may be 
+returned if
+.Fa locale
+is not a valid locale object.
+.It Er ENOMEM
+shall be returned if the system did not have enough memory to allocate a new 
+locale object or read the locale data
+.It Er ENOENT
+shall be returned if the locale specified does not contain data for all the 
+specified categories
+.El
+.Pp
+.\"
+.Fn freelocale
+has no errors
+.\"
+.Sh IMPLEMENTATION NOTES
+None
+.\"
+.Sh SEE ALSO
+.Xr lconv 3
+.Xr setlocale 3
+.\"
+.Sh STANDARDS
+Conforming to
 .St -p1003.1-2008 .
\ No newline at end of file
index 42eb915b2a9703091828d4ac106abd93e8d5972c..44225a6152f23dd0dee7244fe2aa26f8362f3f59 100644 (file)
@@ -1,83 +1,83 @@
-.\" This file is part of the Public Domain C Library (PDCLib).\r
-.\" Permission is granted to use, modify, and / or redistribute at will.\r
-.\"\r
-.Dd\r
-.Dt setlocale 3\r
-.Os\r
-.\"\r
-.Sh NAME\r
-.Nm setlocale\r
-.Nd Set the application global locale\r
-.\"\r
-.Sh SYNOPSIS\r
-.In locale.h\r
-.Fn "char *setlocale" "int category" "const char * locale"\r
-.\"\r
-.Sh DESCRIPTION\r
-The ISO C standards define an application global locale, which all \r
-locale-dependent functions implicitly use.\r
-.Fn setlocale\r
-may be used to change this locale.\r
-.Pp\r
-The locale is defined to be comprised of several categories; the category \r
-parameter specifies which category of the global locale to change, and takes one\r
-of the following values:\r
-.Bl -tag\r
-.It Dv LC_ALL\r
-Modifies all categories\r
-.It Dv LC_COLLATE\r
-Changes the string collation order; affects \r
-.Fn strcoll\r
-and\r
-.Fn strxfrm .\r
-.It Dv LC_CTYPE\r
-Affects the behaviour of the character handling functions defined in\r
-.In ctype.h ,\r
-excluding \r
-.Fn isdigit\r
-and\r
-.Fn isxdigit .\r
-.It Dv LC_MONETARY\r
-Controls the currency-related information returned by\r
-.Fn localeconv .\r
-.It Dv LC_NUMERIC\r
-Controls the decimal point character used by the number formatting functions,\r
-plus the nonmonetary information returned by \r
-.Fn localeconv .\r
-.It Dv LC_TIME\r
-Controls the formatting used by the\r
-.Fn strftime\r
-and\r
-.Fn wcsftime\r
-functions.\r
-.El\r
-.Pp\r
-.St -p1003.1-2008\r
-defines the\r
-.Fn uselocale\r
-function which controls the locale of the present thread. If the thread locale\r
-has been modified using the \r
-.Fn uselocale\r
-function, and has not been reset to the global locale by invoking\r
-.Fn uselocale\r
-with\r
-.Dv LC_GLOBAL_LOCALE\r
-as its parameter, then the\r
-.Fn setlocale\r
-function will not affect the result of functions invoked on the current thread.\r
-.\"\r
-.Sh IMPLEMENTATION NOTES\r
-None\r
-.\"\r
-.Sh SEE ALSO\r
-.Xr lconv 3\r
-.Xr uselocale 3\r
-.Xr duplocale 3\r
-.Xr freelocale 3\r
-.\"\r
-.Sh STANDARDS\r
-Conforming to\r
-.St -isoC-amd1 ,\r
-.St -isoC-99 ,\r
-.St -isoC-2011 ,\r
+.\" This file is part of the Public Domain C Library (PDCLib).
+.\" Permission is granted to use, modify, and / or redistribute at will.
+.\"
+.Dd
+.Dt setlocale 3
+.Os
+.\"
+.Sh NAME
+.Nm setlocale
+.Nd Set the application global locale
+.\"
+.Sh SYNOPSIS
+.In locale.h
+.Fn "char *setlocale" "int category" "const char * locale"
+.\"
+.Sh DESCRIPTION
+The ISO C standards define an application global locale, which all 
+locale-dependent functions implicitly use.
+.Fn setlocale
+may be used to change this locale.
+.Pp
+The locale is defined to be comprised of several categories; the category 
+parameter specifies which category of the global locale to change, and takes one
+of the following values:
+.Bl -tag
+.It Dv LC_ALL
+Modifies all categories
+.It Dv LC_COLLATE
+Changes the string collation order; affects 
+.Fn strcoll
+and
+.Fn strxfrm .
+.It Dv LC_CTYPE
+Affects the behaviour of the character handling functions defined in
+.In ctype.h ,
+excluding 
+.Fn isdigit
+and
+.Fn isxdigit .
+.It Dv LC_MONETARY
+Controls the currency-related information returned by
+.Fn localeconv .
+.It Dv LC_NUMERIC
+Controls the decimal point character used by the number formatting functions,
+plus the nonmonetary information returned by 
+.Fn localeconv .
+.It Dv LC_TIME
+Controls the formatting used by the
+.Fn strftime
+and
+.Fn wcsftime
+functions.
+.El
+.Pp
+.St -p1003.1-2008
+defines the
+.Fn uselocale
+function which controls the locale of the present thread. If the thread locale
+has been modified using the 
+.Fn uselocale
+function, and has not been reset to the global locale by invoking
+.Fn uselocale
+with
+.Dv LC_GLOBAL_LOCALE
+as its parameter, then the
+.Fn setlocale
+function will not affect the result of functions invoked on the current thread.
+.\"
+.Sh IMPLEMENTATION NOTES
+None
+.\"
+.Sh SEE ALSO
+.Xr lconv 3
+.Xr uselocale 3
+.Xr duplocale 3
+.Xr freelocale 3
+.\"
+.Sh STANDARDS
+Conforming to
+.St -isoC-amd1 ,
+.St -isoC-99 ,
+.St -isoC-2011 ,
 .St -p1003.1-2008 .
\ No newline at end of file
index 28036115251d13c7a1c65d912fa84bac0107da61..61acee56bcea79d3ec19286d9c68b06ef07110dd 100644 (file)
@@ -1,59 +1,59 @@
-.\" This file is part of the Public Domain C Library (PDCLib).\r
-.\" Permission is granted to use, modify, and / or redistribute at will.\r
-.\"\r
-.Dd\r
-.Dt strdup 3\r
-.Os\r
-.\"\r
-.Sh NAME\r
-.Nm strdup\r
-.Nd string duplication\r
-.\"\r
-.Sh SYNOPSIS\r
-.Sy #define _XOPEN_SOURCE || _POSIX_C_SOURCE >= 200809L\r
-.In string.h\r
-.Fn "char *strdup" "const char *str"\r
-.Pp\r
-.Sy #define _POSIX_C_SOURCE >= 200809L\r
-.In string.h\r
-.Fn "char *strndup" "const char *str" "size_t len"\r
-.\"\r
-.Sh DESCRIPTION\r
-.Fn strdup\r
-allocates a new buffer of sufficient size as to be able to hold the entirety of\r
-.Va str ,\r
-including the terminating character, and copies the contents of\r
-.Va str\r
-into it.\r
-.\"\r
-.Pp\r
-.Fn strndup\r
-allocates a buffer large enough to contain\r
-.Va len\r
-characters, plus a trailing null character, or sufficient to contain the \r
-entirety of\r
-.Va str\r
-including the trailing null character, whichever is smaller. The first \r
-.Va len\r
-characters of \r
-.Va str\r
-are then copied into it, and a null character appended.\r
-.\"\r
-.Pp\r
-The buffers returned by these functions must be released by a call to\r
-.Fn free .\r
-.\"\r
-.Sh SEE ALSO\r
-.Xr free 3\r
-.Xr malloc 3\r
-.Xr strcpy 3\r
-.Xr strncpy 3\r
-.\"\r
-.Sh STANDARDS\r
-.Fn strdup\r
-first specified in \r
-.St -xpg3 .\r
-Moved into POSIX, and\r
-.Fn strndup\r
-added, with\r
+.\" This file is part of the Public Domain C Library (PDCLib).
+.\" Permission is granted to use, modify, and / or redistribute at will.
+.\"
+.Dd
+.Dt strdup 3
+.Os
+.\"
+.Sh NAME
+.Nm strdup
+.Nd string duplication
+.\"
+.Sh SYNOPSIS
+.Sy #define _XOPEN_SOURCE || _POSIX_C_SOURCE >= 200809L
+.In string.h
+.Fn "char *strdup" "const char *str"
+.Pp
+.Sy #define _POSIX_C_SOURCE >= 200809L
+.In string.h
+.Fn "char *strndup" "const char *str" "size_t len"
+.\"
+.Sh DESCRIPTION
+.Fn strdup
+allocates a new buffer of sufficient size as to be able to hold the entirety of
+.Va str ,
+including the terminating character, and copies the contents of
+.Va str
+into it.
+.\"
+.Pp
+.Fn strndup
+allocates a buffer large enough to contain
+.Va len
+characters, plus a trailing null character, or sufficient to contain the 
+entirety of
+.Va str
+including the trailing null character, whichever is smaller. The first 
+.Va len
+characters of 
+.Va str
+are then copied into it, and a null character appended.
+.\"
+.Pp
+The buffers returned by these functions must be released by a call to
+.Fn free .
+.\"
+.Sh SEE ALSO
+.Xr free 3
+.Xr malloc 3
+.Xr strcpy 3
+.Xr strncpy 3
+.\"
+.Sh STANDARDS
+.Fn strdup
+first specified in 
+.St -xpg3 .
+Moved into POSIX, and
+.Fn strndup
+added, with
 .St -p1003.1-2008 .
\ No newline at end of file
index eb786ce2096bef86df4124f75a2a5fb7c20dc2e0..49d323221839c6ab3e6b597544b3e6e04d2e94e2 100644 (file)
-.\" This file is part of the Public Domain C Library (PDCLib).\r
-.\" Permission is granted to use" "modify" "and / or redistribute at will.\r
-.\"\r
-.Dd\r
-.Dt STRING.H 3\r
-.Os\r
-.\"\r
-.Sh NAME\r
-.Nm string.h\r
-.Nd byte string manipulation\r
-.\"\r
-.Sh SYNOPSIS\r
-.In string.h\r
-.\"\r
-.Sh DESCRIPTION\r
-The\r
-.In string.h\r
-header provides byte string manipulation operations.\r
-.\"\r
-.Pp\r
-The type\r
-.Vt size_t ,\r
-and the preprocessor constant\r
-.Dv NULL\r
-shall be defined.\r
-.\"\r
-.Pp\r
-The following shall be defined as functions:\r
-.br\r
-.Fn "void *memcpy" "void *restrict dest" "const void *restrict src" "size_t byteCount" \r
-.br\r
-.Fn "void *memmove" "void *dest" "void *src" "size_t byteCount"\r
-.br\r
-.Fn "char *strcpy" "char *restrict dest" "const char *restrict src"\r
-.br\r
-.Fn "char *strncpy" "char *restrict dest" "const char *src" "size_t byteCount"\r
-.br\r
-.Fn "char *strcat" "char *restrict s1" "const char *restrict s2"\r
-.br\r
-.Fn "char *strncat" "char *restrict s1" "const char *restrict s2" "size_t n"\r
-.br\r
-.Fn "int memcmp" "const void *s1" "const void *s2" "size_t n"\r
-.br\r
-.Fn "int strcmp" "const char *s1" "const char *s2"\r
-.br\r
-.Fn "int strcoll" "const char *s1" "const char *s2"\r
-.br\r
-.Fn "int strncmp" "const char *s1" "const char *s2" "size_t n"\r
-.br\r
-.Fn "size_t strxfrm" "char *restrict s1" "const char *restrict s2" "size_t n"\r
-.br\r
-.Fn "void *memchr" "const void *s" "int c" "size_t n"\r
-.br\r
-.Fn "char *strchr" "const char *s" "int c"\r
-.br\r
-.Fn "size_t strcspn" "const char *s1" "const char *s2"\r
-.br\r
-.Fn "char *strpbrk" "const char *s1" "const char *s2"\r
-.br\r
-.Fn "char *strrchr" "const char *s" "int c"\r
-.br\r
-.Fn "size_t strspn" "const char *s1" "const char *s2"\r
-.br\r
-.Fn "char *strstr" "const char *s1" "const char *s2"\r
-.br\r
-.Fn "char *strtok" "char *restrict s1" "const char *restrict s2"\r
-.br\r
-.Fn "void *memset" "void *s" "int c" "size_t n"\r
-.br\r
-.Fn "char *strerror" "int errnum"\r
-.br\r
-.Fn "size_t strlen" "const char *s"\r
-.\"\r
-.Pp\r
-.Sy #define _XOPEN_SOURCE || _POSIX_C_SOURCE >= 200809L\r
-.br\r
-.Fn "char *strdup" "const char*src"\r
-.\"\r
-.Pp\r
-.Sy #define _POSIX_C_SOURCE >= 200809L\r
-.br\r
-.Fn "char *strndup" "const char*src" "size_t n"\r
-.\"\r
-.Sh SEE ALSO\r
-.Xr wchar.h 3\r
-.Xr stdlib.h 3\r
-.Xr memcpy 3\r
-.Xr memmove 3\r
-.Xr strcpy 3\r
-.Xr strncpy 3\r
-.Xr strcat 3\r
-.Xr strncat 3\r
-.Xr memcmp 3\r
-.Xr strcmp 3\r
-.Xr strcoll 3\r
-.Xr strncmp 3\r
-.Xr strxfrm 3\r
-.Xr memchr 3\r
-.Xr strchr 3\r
-.Xr strcspn 3\r
-.Xr strpbrk 3\r
-.Xr strrchr 3\r
-.Xr strspn 3\r
-.Xr strstr 3\r
-.Xr strtok 3\r
-.Xr memset 3\r
-.Xr strerror 3\r
-.Xr strlen 3\r
-.Xr strdup 3\r
-.Xr strndup 3\r
-.Sh STANDARDS\r
-Conforming to\r
-.St -isoC-90 ,\r
+.\" This file is part of the Public Domain C Library (PDCLib).
+.\" Permission is granted to use" "modify" "and / or redistribute at will.
+.\"
+.Dd
+.Dt STRING.H 3
+.Os
+.\"
+.Sh NAME
+.Nm string.h
+.Nd byte string manipulation
+.\"
+.Sh SYNOPSIS
+.In string.h
+.\"
+.Sh DESCRIPTION
+The
+.In string.h
+header provides byte string manipulation operations.
+.\"
+.Pp
+The type
+.Vt size_t ,
+and the preprocessor constant
+.Dv NULL
+shall be defined.
+.\"
+.Pp
+The following shall be defined as functions:
+.br
+.Fn "void *memcpy" "void *restrict dest" "const void *restrict src" "size_t byteCount" 
+.br
+.Fn "void *memmove" "void *dest" "void *src" "size_t byteCount"
+.br
+.Fn "char *strcpy" "char *restrict dest" "const char *restrict src"
+.br
+.Fn "char *strncpy" "char *restrict dest" "const char *src" "size_t byteCount"
+.br
+.Fn "char *strcat" "char *restrict s1" "const char *restrict s2"
+.br
+.Fn "char *strncat" "char *restrict s1" "const char *restrict s2" "size_t n"
+.br
+.Fn "int memcmp" "const void *s1" "const void *s2" "size_t n"
+.br
+.Fn "int strcmp" "const char *s1" "const char *s2"
+.br
+.Fn "int strcoll" "const char *s1" "const char *s2"
+.br
+.Fn "int strncmp" "const char *s1" "const char *s2" "size_t n"
+.br
+.Fn "size_t strxfrm" "char *restrict s1" "const char *restrict s2" "size_t n"
+.br
+.Fn "void *memchr" "const void *s" "int c" "size_t n"
+.br
+.Fn "char *strchr" "const char *s" "int c"
+.br
+.Fn "size_t strcspn" "const char *s1" "const char *s2"
+.br
+.Fn "char *strpbrk" "const char *s1" "const char *s2"
+.br
+.Fn "char *strrchr" "const char *s" "int c"
+.br
+.Fn "size_t strspn" "const char *s1" "const char *s2"
+.br
+.Fn "char *strstr" "const char *s1" "const char *s2"
+.br
+.Fn "char *strtok" "char *restrict s1" "const char *restrict s2"
+.br
+.Fn "void *memset" "void *s" "int c" "size_t n"
+.br
+.Fn "char *strerror" "int errnum"
+.br
+.Fn "size_t strlen" "const char *s"
+.\"
+.Pp
+.Sy #define _XOPEN_SOURCE || _POSIX_C_SOURCE >= 200809L
+.br
+.Fn "char *strdup" "const char*src"
+.\"
+.Pp
+.Sy #define _POSIX_C_SOURCE >= 200809L
+.br
+.Fn "char *strndup" "const char*src" "size_t n"
+.\"
+.Sh SEE ALSO
+.Xr wchar.h 3
+.Xr stdlib.h 3
+.Xr memcpy 3
+.Xr memmove 3
+.Xr strcpy 3
+.Xr strncpy 3
+.Xr strcat 3
+.Xr strncat 3
+.Xr memcmp 3
+.Xr strcmp 3
+.Xr strcoll 3
+.Xr strncmp 3
+.Xr strxfrm 3
+.Xr memchr 3
+.Xr strchr 3
+.Xr strcspn 3
+.Xr strpbrk 3
+.Xr strrchr 3
+.Xr strspn 3
+.Xr strstr 3
+.Xr strtok 3
+.Xr memset 3
+.Xr strerror 3
+.Xr strlen 3
+.Xr strdup 3
+.Xr strndup 3
+.Sh STANDARDS
+Conforming to
+.St -isoC-90 ,
 .St -isoC-99 .
\ No newline at end of file
index 73f2d78e6e7d89f120fbd85de0409c877ca8c872..de7e1b9e553013b22d5e2880d930e14b0409fc7a 100644 (file)
-.\" This file is part of the Public Domain C Library " "PDCLib).\r
-.\" Permission is granted to use" "modify" "and / or redistribute at will.\r
-.\"\r
-.Dd\r
-.Dt WCHAR.H 3\r
-.Os\r
-.\"\r
-.Sh NAME\r
-.Nm wchar.h\r
-.Nd wide character & wide character string manipulation\r
-.\"\r
-.Sh SYNOPSIS\r
-.In wchar.h\r
-.\"\r
-.Sh DESCRIPTION\r
-The\r
-.In wchar.h\r
-header provides functions for manipulating wide character strings" "for\r
-converting between wide characters and multibyte character sets" "for \r
-manipulating wide character strings" "and for wide character oriented input and \r
-output.\r
-.\"\r
-.Ss Types & Definitions\r
-The type\r
-.Vt size_t\r
-and macro\r
-.Dv NULL\r
-shall be defined as in\r
-.In stddef.h .\r
-.Pp\r
-The type\r
-.Vt wchar_t\r
-shall be defined as an integral type capable of representing any wide character\r
-in the implementation defined encoding. The type\r
-.Vt wint_t\r
-shall be defined as an integral type capable of representing any wide character\r
-in the implementation defined encoding" "plus the distinct value given by\r
-.Dv WEOF ,\r
-which evaluates to a constant expression of type\r
-.Vt wint_t\r
-which does not correspond to any character in the implementation defined \r
-character set. The macros \r
-.Dv WCHAR_MIN\r
-and\r
-.Dv WCHAR_MAX\r
-shall be defined as in\r
-.In stdint.h .\r
-.Pp\r
-The type\r
-.Vt mbstate_t\r
-shall be a complete non-array object type used for the storage of the state of\r
-a multibyte to wide character conversion.\r
-.Pp\r
-The type\r
-.Vt struct tm\r
-shall be defined as an incomplete type" "a full definition of wich can be found \r
-in\r
-.In time.h .\r
-.\"\r
-.Ss Wide Character String Handling Functions\r
-.Fn "wchar_t *wcscpy" "wchar_t *restrict s1" "const wchar_t *restrict s2"\r
-.br\r
-.Fn "wchar_t *wcsncpy" "wchar_t *restrict s1" "const wchar_t *restrict s2" "size_t n"\r
-.br\r
-.Fn "wchar_t *wmemcpy" "wchar_t *restrict s1" "const wchar_t *restrict s2" "size_t n"\r
-.br\r
-.Fn "wchar_t *wmemmove" "wchar_t *s1" "const wchar_t *s2" "size_t n"\r
-.br\r
-.Fn "wchar_t *wcscat" "wchar_t *restrict s1" "const wchar_t *restrict s2"\r
-.br\r
-.Fn "wchar_t *wcsncat" "wchar_t *restrict s1" "const wchar_t *restrict s2" "size_t n"\r
-.br\r
-.Fn "int wcscmp" "const wchar_t *s1" "const wchar_t *s2"\r
-.br\r
-.Fn "int wcscoll" "const wchar_t *s1" "const wchar_t *s2"\r
-.br\r
-.Fn "int wcsncmp" "const wchar_t *s1" "const wchar_t *s2" "size_t n"\r
-.br\r
-.Fn "size_t wcsxfrm" "wchar_t *restrict s1" "const wchar_t *restrict s2" "size_t n"\r
-.br\r
-.Fn "int wmemcmp" "const wchar_t *s1" "const wchar_t *s2" "size_t n"\r
-.br\r
-.Fn "wchar_t *wcschr" "const wchar_t *s" "wchar_t c"\r
-.br\r
-.Fn "size_t wcscspn" "const wchar_t *s1" "const wchar_t *s2"\r
-.br\r
-.Fn "wchar_t *wcspbrk" "const wchar_t *s1" "const wchar_t *s2"\r
-.br\r
-.Fn "wchar_t *wcsrchr" "const wchar_t *s" "wchar_t c"\r
-.br\r
-.Fn "size_t wcsspn" "const wchar_t *s1" "const wchar_t *s2"\r
-.br\r
-.Fn "wchar_t *wcsstr" "const wchar_t *s1" "const wchar_t *s2"\r
-.br\r
-.Fn "wchar_t *wcstok" "wchar_t *restrict s1" "const wchar_t *restrict s2" "wchar_t **restrict ptr"\r
-.br\r
-.Fn "wchar_t *wmemchr" "const wchar_t *s" "wchar_t c" "size_t n" \r
-.br\r
-.Fn "size_t wcslen" "const wchar_t *s"\r
-.br\r
-.Fn "wchar_t *wmemset" "wchar_t *s" "wchar_t c" "size_t n"\r
-.\"\r
-.Ss Wide Character String Formatting\r
-.Fn "int swprintf" "wchar_t *restrict s" "size_t n" "const wchar_t *restrict format" "..."\r
-.br\r
-.Fn "int swscanf" "const wchar_t *restrict s" "const wchar_t *restrict format" "..."\r
-.br\r
-.Fn "int vswprintf" "wchar_t *restrict s" "size_t n" "const wchar_t *restrict format" "va_list arg"\r
-.br\r
-.Fn "int vswscanf" "const wchar_t *restrict s" "const wchar_t *restrict format" "va_list arg"\r
-.br\r
-.Fn "size_t wcsftime" "wchar_t *restrict s" "size_t maxsize" "const wchar_t *restrict format" "const struct tm *restrict timeptr"\r
-.\"\r
-.Ss Wide Character Input and Output\r
-.Fn "int fwprintf" "FILE *restrict stream" "const wchar_t *restrict format" "..."\r
-.br\r
-.Fn "int fwscanf" "FILE *restrict stream" "const wchar_t *restrict format" "..."\r
-.br\r
-.Fn "int vfwprintf" "FILE *restrict stream" "const wchar_t *restrict format" "va_list arg"\r
-.br\r
-.Fn "int vfwscanf" "FILE *restrict stream" "const wchar_t *restrict format" "va_list arg"\r
-.br\r
-.Fn "int vwprintf" "const wchar_t *restrict format" "va_list arg"\r
-.br\r
-.Fn "int vwscanf" "const wchar_t *restrict format" "va_list arg"\r
-.br\r
-.Fn "int wprintf" "const wchar_t *restrict format" "..."\r
-.br\r
-.Fn "int wscanf" "const wchar_t *restrict format" "..."\r
-.br\r
-.Fn "wint_t fgetwc" "FILE *stream"\r
-.br\r
-.Fn "wchar_t *fgetws" "wchar_t *restrict s" "int n" "FILE *restrict stream"\r
-.br\r
-.Fn "wint_t fputwc" "wchar_t c" "FILE *stream"\r
-.br\r
-.Fn "int fputws" "const wchar_t *restrict s" "FILE *restrict stream"\r
-.br\r
-.Fn "int fwide" "FILE *stream" "int mode"\r
-.br\r
-.Fn "wint_t getwc" "FILE *stream"\r
-.br\r
-.Fn "wint_t getwchar" "void"\r
-.br\r
-.Fn "wint_t putwc" "wchar_t c" "FILE *stream"\r
-.br\r
-.Fn "wint_t putwchar" "wchar_t c"\r
-.br\r
-.Fn "wint_t ungetwc" "wint_t c" "FILE *stream"\r
-.\"\r
-.Ss Wide Character String Parsing\r
-.Fn "double wcstod" "const wchar_t *restrict nptr" "wchar_t **restrict endptr"\r
-.br\r
-.Fn "float wcstof" "const wchar_t *restrict nptr" "wchar_t **restrict endptr"\r
-.br\r
-.Fn "long double wcstold" "const wchar_t *restrict nptr" "wchar_t **restrict endptr"\r
-.br\r
-.Fn "long int wcstol" "const wchar_t *restrict nptr" "wchar_t **restrict endptr" "int base"\r
-.br\r
-.Fn "long long int wcstoll" "const wchar_t *restrict nptr" "wchar_t **restrict endptr" "int base"\r
-.br\r
-.Fn "unsigned long int wcstoul" "const wchar_t *restrict nptr" "wchar_t **restrict endptr" "int base"\r
-.br\r
-.Fn "unsigned long long int wcstoull" "const wchar_t *restrict nptr" "wchar_t **restrict endptr" "int base"\r
-.\"\r
-.Ss Character Set Conversion\r
-.Fn "wint_t btowc" "int c"\r
-.br\r
-.Fn "int wctob" "wint_t c"\r
-.br\r
-.Fn "int mbsinit" "const mbstate_t *ps"\r
-.br\r
-.Fn "size_t mbrlen" "const char *restrict s" "size_t n" "mbstate_t *restrict ps"\r
-.br\r
-.Fn "size_t mbrtowc" "wchar_t *restrict pwc" "const char *restrict s" "size_t n" "mbstate_t *restrict ps"\r
-.br\r
-.Fn "size_t wcrtomb" "char *restrict s" "wchar_t wc" "mbstate_t *restrict ps"\r
-.br\r
-.Fn "size_t mbsrtowcs" "wchar_t *restrict dst" "const char **restrict src" "size_t len" "mbstate_t *restrict ps"\r
-.br\r
-.Fn "size_t wcsrtombs" "char *restrict dst" "const wchar_t **restrict src" "size_t len" "mbstate_t *restrict ps"\r
-.\"\r
-.Sh SEE ALSO\r
-.Xr string.h 3\r
-.Xr uchar.h 3\r
-.Xr wcscpy 3\r
-.Xr wcsncpy 3\r
-.Xr wmemcpy 3\r
-.Xr wmemmove 3\r
-.Xr wcscat 3\r
-.Xr wcsncat 3\r
-.Xr wcscmp 3\r
-.Xr wcscoll 3\r
-.Xr wcsncmp 3\r
-.Xr wcsxfrm 3\r
-.Xr wmemcmp 3\r
-.Xr wcschr 3\r
-.Xr wcscspn 3\r
-.Xr wcspbrk 3\r
-.Xr wcsrchr 3\r
-.Xr wcsspn 3\r
-.Xr wcsstr 3\r
-.Xr wcstok 3\r
-.Xr wmemchr 3\r
-.Xr wcslen 3\r
-.Xr wmemset 3\r
-.\"\r
-.Xr swprintf 3\r
-.Xr swscanf 3\r
-.Xr vswprintf 3\r
-.Xr vswscanf 3\r
-.Xr wcsftime 3\r
-.\"\r
-.Xr fwprintf 3\r
-.Xr fwscanf 3\r
-.Xr vfwprintf 3\r
-.Xr vfwscanf 3\r
-.Xr vwprintf 3\r
-.Xr vwscanf 3\r
-.Xr wprintf 3\r
-.Xr wscanf 3\r
-.Xr fgetwc 3\r
-.Xr fgetws 3\r
-.Xr fputwc 3\r
-.Xr fputws 3\r
-.Xr fwide 3\r
-.Xr getwc 3\r
-.Xr getwchar 3\r
-.Xr putwc 3\r
-.Xr putwchar 3\r
-.Xr ungetwc 3\r
-.\"\r
-.Xr wcstod 3\r
-.Xr wcstof 3\r
-.Xr wcstold 3\r
-.Xr wcstol 3\r
-.Xr wcstoll 3\r
-.Xr wcstoul 3\r
-.Xr wcstoull 3\r
-.\"\r
-.Xr btowc 3\r
-.Xr wctomb 3\r
-.Xr mbsinit 3\r
-.Xr mbrlen 3\r
-.Xr mbrtowc 3\r
-.Xr wcrtomb 3\r
-.Xr mbsrtowcs 3\r
-.Xr wcsrtombs 3\r
-.\"\r
-.Sh STANDARDS\r
-Conforming to\r
-.St -isoC-amd1 ,\r
-.St -isoC-99 and\r
+.\" This file is part of the Public Domain C Library " "PDCLib).
+.\" Permission is granted to use" "modify" "and / or redistribute at will.
+.\"
+.Dd
+.Dt WCHAR.H 3
+.Os
+.\"
+.Sh NAME
+.Nm wchar.h
+.Nd wide character & wide character string manipulation
+.\"
+.Sh SYNOPSIS
+.In wchar.h
+.\"
+.Sh DESCRIPTION
+The
+.In wchar.h
+header provides functions for manipulating wide character strings" "for
+converting between wide characters and multibyte character sets" "for 
+manipulating wide character strings" "and for wide character oriented input and 
+output.
+.\"
+.Ss Types & Definitions
+The type
+.Vt size_t
+and macro
+.Dv NULL
+shall be defined as in
+.In stddef.h .
+.Pp
+The type
+.Vt wchar_t
+shall be defined as an integral type capable of representing any wide character
+in the implementation defined encoding. The type
+.Vt wint_t
+shall be defined as an integral type capable of representing any wide character
+in the implementation defined encoding" "plus the distinct value given by
+.Dv WEOF ,
+which evaluates to a constant expression of type
+.Vt wint_t
+which does not correspond to any character in the implementation defined 
+character set. The macros 
+.Dv WCHAR_MIN
+and
+.Dv WCHAR_MAX
+shall be defined as in
+.In stdint.h .
+.Pp
+The type
+.Vt mbstate_t
+shall be a complete non-array object type used for the storage of the state of
+a multibyte to wide character conversion.
+.Pp
+The type
+.Vt struct tm
+shall be defined as an incomplete type" "a full definition of wich can be found 
+in
+.In time.h .
+.\"
+.Ss Wide Character String Handling Functions
+.Fn "wchar_t *wcscpy" "wchar_t *restrict s1" "const wchar_t *restrict s2"
+.br
+.Fn "wchar_t *wcsncpy" "wchar_t *restrict s1" "const wchar_t *restrict s2" "size_t n"
+.br
+.Fn "wchar_t *wmemcpy" "wchar_t *restrict s1" "const wchar_t *restrict s2" "size_t n"
+.br
+.Fn "wchar_t *wmemmove" "wchar_t *s1" "const wchar_t *s2" "size_t n"
+.br
+.Fn "wchar_t *wcscat" "wchar_t *restrict s1" "const wchar_t *restrict s2"
+.br
+.Fn "wchar_t *wcsncat" "wchar_t *restrict s1" "const wchar_t *restrict s2" "size_t n"
+.br
+.Fn "int wcscmp" "const wchar_t *s1" "const wchar_t *s2"
+.br
+.Fn "int wcscoll" "const wchar_t *s1" "const wchar_t *s2"
+.br
+.Fn "int wcsncmp" "const wchar_t *s1" "const wchar_t *s2" "size_t n"
+.br
+.Fn "size_t wcsxfrm" "wchar_t *restrict s1" "const wchar_t *restrict s2" "size_t n"
+.br
+.Fn "int wmemcmp" "const wchar_t *s1" "const wchar_t *s2" "size_t n"
+.br
+.Fn "wchar_t *wcschr" "const wchar_t *s" "wchar_t c"
+.br
+.Fn "size_t wcscspn" "const wchar_t *s1" "const wchar_t *s2"
+.br
+.Fn "wchar_t *wcspbrk" "const wchar_t *s1" "const wchar_t *s2"
+.br
+.Fn "wchar_t *wcsrchr" "const wchar_t *s" "wchar_t c"
+.br
+.Fn "size_t wcsspn" "const wchar_t *s1" "const wchar_t *s2"
+.br
+.Fn "wchar_t *wcsstr" "const wchar_t *s1" "const wchar_t *s2"
+.br
+.Fn "wchar_t *wcstok" "wchar_t *restrict s1" "const wchar_t *restrict s2" "wchar_t **restrict ptr"
+.br
+.Fn "wchar_t *wmemchr" "const wchar_t *s" "wchar_t c" "size_t n" 
+.br
+.Fn "size_t wcslen" "const wchar_t *s"
+.br
+.Fn "wchar_t *wmemset" "wchar_t *s" "wchar_t c" "size_t n"
+.\"
+.Ss Wide Character String Formatting
+.Fn "int swprintf" "wchar_t *restrict s" "size_t n" "const wchar_t *restrict format" "..."
+.br
+.Fn "int swscanf" "const wchar_t *restrict s" "const wchar_t *restrict format" "..."
+.br
+.Fn "int vswprintf" "wchar_t *restrict s" "size_t n" "const wchar_t *restrict format" "va_list arg"
+.br
+.Fn "int vswscanf" "const wchar_t *restrict s" "const wchar_t *restrict format" "va_list arg"
+.br
+.Fn "size_t wcsftime" "wchar_t *restrict s" "size_t maxsize" "const wchar_t *restrict format" "const struct tm *restrict timeptr"
+.\"
+.Ss Wide Character Input and Output
+.Fn "int fwprintf" "FILE *restrict stream" "const wchar_t *restrict format" "..."
+.br
+.Fn "int fwscanf" "FILE *restrict stream" "const wchar_t *restrict format" "..."
+.br
+.Fn "int vfwprintf" "FILE *restrict stream" "const wchar_t *restrict format" "va_list arg"
+.br
+.Fn "int vfwscanf" "FILE *restrict stream" "const wchar_t *restrict format" "va_list arg"
+.br
+.Fn "int vwprintf" "const wchar_t *restrict format" "va_list arg"
+.br
+.Fn "int vwscanf" "const wchar_t *restrict format" "va_list arg"
+.br
+.Fn "int wprintf" "const wchar_t *restrict format" "..."
+.br
+.Fn "int wscanf" "const wchar_t *restrict format" "..."
+.br
+.Fn "wint_t fgetwc" "FILE *stream"
+.br
+.Fn "wchar_t *fgetws" "wchar_t *restrict s" "int n" "FILE *restrict stream"
+.br
+.Fn "wint_t fputwc" "wchar_t c" "FILE *stream"
+.br
+.Fn "int fputws" "const wchar_t *restrict s" "FILE *restrict stream"
+.br
+.Fn "int fwide" "FILE *stream" "int mode"
+.br
+.Fn "wint_t getwc" "FILE *stream"
+.br
+.Fn "wint_t getwchar" "void"
+.br
+.Fn "wint_t putwc" "wchar_t c" "FILE *stream"
+.br
+.Fn "wint_t putwchar" "wchar_t c"
+.br
+.Fn "wint_t ungetwc" "wint_t c" "FILE *stream"
+.\"
+.Ss Wide Character String Parsing
+.Fn "double wcstod" "const wchar_t *restrict nptr" "wchar_t **restrict endptr"
+.br
+.Fn "float wcstof" "const wchar_t *restrict nptr" "wchar_t **restrict endptr"
+.br
+.Fn "long double wcstold" "const wchar_t *restrict nptr" "wchar_t **restrict endptr"
+.br
+.Fn "long int wcstol" "const wchar_t *restrict nptr" "wchar_t **restrict endptr" "int base"
+.br
+.Fn "long long int wcstoll" "const wchar_t *restrict nptr" "wchar_t **restrict endptr" "int base"
+.br
+.Fn "unsigned long int wcstoul" "const wchar_t *restrict nptr" "wchar_t **restrict endptr" "int base"
+.br
+.Fn "unsigned long long int wcstoull" "const wchar_t *restrict nptr" "wchar_t **restrict endptr" "int base"
+.\"
+.Ss Character Set Conversion
+.Fn "wint_t btowc" "int c"
+.br
+.Fn "int wctob" "wint_t c"
+.br
+.Fn "int mbsinit" "const mbstate_t *ps"
+.br
+.Fn "size_t mbrlen" "const char *restrict s" "size_t n" "mbstate_t *restrict ps"
+.br
+.Fn "size_t mbrtowc" "wchar_t *restrict pwc" "const char *restrict s" "size_t n" "mbstate_t *restrict ps"
+.br
+.Fn "size_t wcrtomb" "char *restrict s" "wchar_t wc" "mbstate_t *restrict ps"
+.br
+.Fn "size_t mbsrtowcs" "wchar_t *restrict dst" "const char **restrict src" "size_t len" "mbstate_t *restrict ps"
+.br
+.Fn "size_t wcsrtombs" "char *restrict dst" "const wchar_t **restrict src" "size_t len" "mbstate_t *restrict ps"
+.\"
+.Sh SEE ALSO
+.Xr string.h 3
+.Xr uchar.h 3
+.Xr wcscpy 3
+.Xr wcsncpy 3
+.Xr wmemcpy 3
+.Xr wmemmove 3
+.Xr wcscat 3
+.Xr wcsncat 3
+.Xr wcscmp 3
+.Xr wcscoll 3
+.Xr wcsncmp 3
+.Xr wcsxfrm 3
+.Xr wmemcmp 3
+.Xr wcschr 3
+.Xr wcscspn 3
+.Xr wcspbrk 3
+.Xr wcsrchr 3
+.Xr wcsspn 3
+.Xr wcsstr 3
+.Xr wcstok 3
+.Xr wmemchr 3
+.Xr wcslen 3
+.Xr wmemset 3
+.\"
+.Xr swprintf 3
+.Xr swscanf 3
+.Xr vswprintf 3
+.Xr vswscanf 3
+.Xr wcsftime 3
+.\"
+.Xr fwprintf 3
+.Xr fwscanf 3
+.Xr vfwprintf 3
+.Xr vfwscanf 3
+.Xr vwprintf 3
+.Xr vwscanf 3
+.Xr wprintf 3
+.Xr wscanf 3
+.Xr fgetwc 3
+.Xr fgetws 3
+.Xr fputwc 3
+.Xr fputws 3
+.Xr fwide 3
+.Xr getwc 3
+.Xr getwchar 3
+.Xr putwc 3
+.Xr putwchar 3
+.Xr ungetwc 3
+.\"
+.Xr wcstod 3
+.Xr wcstof 3
+.Xr wcstold 3
+.Xr wcstol 3
+.Xr wcstoll 3
+.Xr wcstoul 3
+.Xr wcstoull 3
+.\"
+.Xr btowc 3
+.Xr wctomb 3
+.Xr mbsinit 3
+.Xr mbrlen 3
+.Xr mbrtowc 3
+.Xr wcrtomb 3
+.Xr mbsrtowcs 3
+.Xr wcsrtombs 3
+.\"
+.Sh STANDARDS
+Conforming to
+.St -isoC-amd1 ,
+.St -isoC-99 and
 .St -isoC-2011 .
\ No newline at end of file
index 1fced177d707a2d6d609d54f3dc6c445c75ada67..d9b5dbfd9decd4d16320f041a12666dba0586a49 100644 (file)
@@ -1,2 +1,2 @@
-Basic C Locale Support\r
+Basic C Locale Support
     - i.e. support for the basic (PDCLib-packaged) C locale only
\ No newline at end of file
index 4d13ee5244721daeb21fff7622232887f9bef22b..09ccc4d2d172869dc62a438a7ed8552c5145c408 100644 (file)
@@ -1,19 +1,19 @@
-/* "C" Locale Support\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#ifndef _PDCLIB_CLOCALE_H\r
-#define _PDCLIB_CLOCALE_H _PDCLIB_CLOCALE_H\r
-#include <locale.h>\r
+/* "C" Locale Support
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#ifndef _PDCLIB_CLOCALE_H
+#define _PDCLIB_CLOCALE_H _PDCLIB_CLOCALE_H
+#include <locale.h>
 #ifdef __cplusplus
 extern "C" {
-#endif\r
-\r
-void _PDCLIB_initclocale( locale_t l );\r
-\r
+#endif
+
+void _PDCLIB_initclocale( locale_t l );
+
 #ifdef __cplusplus
 }
-#endif\r
-#endif // _PDCLIB_CLOCALE_H\r
+#endif
+#endif // _PDCLIB_CLOCALE_H
index 4b214e46690d234d996a9317af1498a0a6c317ef..d7cf35063fffa040671787ffc00655a4cac72b63 100644 (file)
@@ -1,29 +1,29 @@
-/* _PDCLIB_initclocale( locale_t )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#ifndef REGTEST\r
-#include "_PDCLIB_clocale.h"\r
-#include "_PDCLIB_locale.h"\r
-\r
-void _PDCLIB_initclocale( locale_t l )\r
-{\r
-    // TODO: There will be more added here...\r
-\r
-    l->_WCType     = _PDCLIB_wcinfo;\r
-    l->_WCTypeSize = _PDCLIB_wcinfo_size;\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main()\r
-{\r
-    return TEST_RESULTS;\r
-}\r
-\r
+/* _PDCLIB_initclocale( locale_t )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#ifndef REGTEST
+#include "_PDCLIB_clocale.h"
+#include "_PDCLIB_locale.h"
+
+void _PDCLIB_initclocale( locale_t l )
+{
+    // TODO: There will be more added here...
+
+    l->_WCType     = _PDCLIB_wcinfo;
+    l->_WCTypeSize = _PDCLIB_wcinfo_size;
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main()
+{
+    return TEST_RESULTS;
+}
+
 #endif
\ No newline at end of file
index 2e79081df14cc7cb6db52cdf464672c4067e5880..9c7c2a60352cfa971dbf8e6b4b324efae805a173 100644 (file)
@@ -1,36 +1,36 @@
-/* wcscoll( const wchar_t *, const wchar_t * )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <wchar.h>\r
-\r
-#ifndef REGTEST\r
-\r
-/* I did much searching as to how various people implement this.\r
- *\r
- * OpenBSD, NetBSD and Musl libc for Linux implement this as a call to wcscmp\r
- * and have various "todo" notices on this function, and on the other hand\r
- * glibc implements it as a 500 line function. FreeBSD has an implementation \r
- * which kind of uses their single byte character strcoll data for the first\r
- * 256 characters, but looks incredibly fragile and likely to break.\r
- *\r
- * TL;DR: Nobody uses this, and this will probably work perfectly fine for you.\r
- */\r
-\r
-int wcscoll( const wchar_t * s1, const wchar_t * s2 )\r
-{\r
-    return wcscmp(s1, s2);\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    return TEST_RESULTS;\r
-}\r
-#endif\r
+/* wcscoll( const wchar_t *, const wchar_t * )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <wchar.h>
+
+#ifndef REGTEST
+
+/* I did much searching as to how various people implement this.
+ *
+ * OpenBSD, NetBSD and Musl libc for Linux implement this as a call to wcscmp
+ * and have various "todo" notices on this function, and on the other hand
+ * glibc implements it as a 500 line function. FreeBSD has an implementation 
+ * which kind of uses their single byte character strcoll data for the first
+ * 256 characters, but looks incredibly fragile and likely to break.
+ *
+ * TL;DR: Nobody uses this, and this will probably work perfectly fine for you.
+ */
+
+int wcscoll( const wchar_t * s1, const wchar_t * s2 )
+{
+    return wcscmp(s1, s2);
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    return TEST_RESULTS;
+}
+#endif
index 4bb6adc0088e0d69bdf44966da27fa4a62d39a56..6d1bd37d76cadcf44bfb0a9f62f085b70c8a7ee0 100644 (file)
@@ -1,28 +1,28 @@
-/* wcsxfrm( char *, const char *, size_t )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#include <wchar.h>\r
-\r
-#ifndef REGTEST\r
-\r
-/* See notes on wcscoll. */\r
-size_t wcsxfrm( wchar_t * _PDCLIB_restrict s1, const wchar_t * _PDCLIB_restrict s2, size_t n )\r
-{\r
-    wcsncpy(s1, s2, n);\r
-    return wcslen(s2);\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    return TEST_RESULTS;\r
-}\r
-#endif\r
-\r
+/* wcsxfrm( char *, const char *, size_t )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <wchar.h>
+
+#ifndef REGTEST
+
+/* See notes on wcscoll. */
+size_t wcsxfrm( wchar_t * _PDCLIB_restrict s1, const wchar_t * _PDCLIB_restrict s2, size_t n )
+{
+    wcsncpy(s1, s2, n);
+    return wcslen(s2);
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    return TEST_RESULTS;
+}
+#endif
+
index cf0a625e0bfd18eb24ff0231186729d1588dc60e..fcc3d399077efd01eb510b02684dff43e36614fa 100644 (file)
@@ -1,28 +1,28 @@
-#ifndef _PDCLIB_THREADCONFIG_H\r
-#define _PDCLIB_THREADCONFIG_H\r
-#include "_PDCLIB_aux.h"\r
-#include "_PDCLIB_config.h"\r
-\r
+#ifndef _PDCLIB_THREADCONFIG_H
+#define _PDCLIB_THREADCONFIG_H
+#include "_PDCLIB_aux.h"
+#include "_PDCLIB_config.h"
+
 #ifdef __cplusplus
 extern "C" {
-#endif\r
-#define _PDCLIB_ONCE_FLAG_INIT 0\r
-#define _PDCLIB_ONCE_FLAG_IS_DONE(_f) (*(_f) == 1)\r
-typedef char _PDCLIB_once_flag;\r
-\r
-void _PDCLIB_call_once(_PDCLIB_once_flag *flag, void (*func)(void));\r
-\r
-#define _PDCLIB_THRD_HAVE_MISC\r
-#define _PDCLIB_CND_T char\r
-#define _PDCLIB_MTX_T char\r
-#define _PDCLIB_TSS_T struct _PDCLIB_tss\r
-\r
-struct _PDCLIB_tss {\r
-       struct _PDCLIB_tss *self;\r
-       void *value;\r
-};\r
-\r
+#endif
+#define _PDCLIB_ONCE_FLAG_INIT 0
+#define _PDCLIB_ONCE_FLAG_IS_DONE(_f) (*(_f) == 1)
+typedef char _PDCLIB_once_flag;
+
+void _PDCLIB_call_once(_PDCLIB_once_flag *flag, void (*func)(void));
+
+#define _PDCLIB_THRD_HAVE_MISC
+#define _PDCLIB_CND_T char
+#define _PDCLIB_MTX_T char
+#define _PDCLIB_TSS_T struct _PDCLIB_tss
+
+struct _PDCLIB_tss {
+       struct _PDCLIB_tss *self;
+       void *value;
+};
+
 #ifdef __cplusplus
 }
-#endif\r
-#endif\r
+#endif
+#endif
index 3bdca049a2f6d3e1dd2734a458d89946a3338299..6673d611a177a3981b2df6e46d5bcb816e4e5d8d 100644 (file)
@@ -1,40 +1,40 @@
-#ifndef REGTEST\r
-#include <threads.h>\r
-\r
-void _PDCLIB_call_once(_PDCLIB_once_flag *flag, void (*func)(void))\r
-{\r
-       if(!_PDCLIB_ONCE_FLAG_IS_DONE(flag)) {\r
-               func();\r
-               *flag = 1;\r
-       }\r
-}\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-#ifndef REGTEST\r
-static int count = 0;\r
-static once_flag once = ONCE_FLAG_INIT;\r
-\r
-static void do_once(void)\r
-{\r
-    count++;\r
-}\r
-#endif\r
-\r
-int main( void )\r
-{\r
-#ifndef REGTEST\r
-    TESTCASE(count == 0);\r
-    call_once(&once, do_once);\r
-    TESTCASE(count == 1);\r
-    call_once(&once, do_once);\r
-    TESTCASE(count == 1);\r
-    do_once();\r
-    TESTCASE(count == 2);\r
-#endif\r
-    return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
+#ifndef REGTEST
+#include <threads.h>
+
+void _PDCLIB_call_once(_PDCLIB_once_flag *flag, void (*func)(void))
+{
+       if(!_PDCLIB_ONCE_FLAG_IS_DONE(flag)) {
+               func();
+               *flag = 1;
+       }
+}
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+#ifndef REGTEST
+static int count = 0;
+static once_flag once = ONCE_FLAG_INIT;
+
+static void do_once(void)
+{
+    count++;
+}
+#endif
+
+int main( void )
+{
+#ifndef REGTEST
+    TESTCASE(count == 0);
+    call_once(&once, do_once);
+    TESTCASE(count == 1);
+    call_once(&once, do_once);
+    TESTCASE(count == 1);
+    do_once();
+    TESTCASE(count == 2);
+#endif
+    return TEST_RESULTS;
+}
+
+#endif
index 13f1732e4971877e713f9b9e55c234371ce0aa5e..4e05427bd54389d71058c4fe7b3ee3982f3aa3b9 100644 (file)
@@ -1,19 +1,19 @@
-#ifndef REGTEST\r
-#include <threads.h>\r
-\r
-int cnd_init(cnd_t *cond)\r
-{\r
-       /* does nothing */\r
-       return thrd_success;\r
-}\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
+#ifndef REGTEST
+#include <threads.h>
+
+int cnd_init(cnd_t *cond)
+{
+       /* does nothing */
+       return thrd_success;
+}
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    return TEST_RESULTS;
+}
+
+#endif
index 2492d82a9dbc505aad1d681094c488f7595bfa35..275ba16ff8d41734d10122fca74216b5b88da064 100644 (file)
@@ -1,18 +1,18 @@
-#ifndef REGTEST\r
-#include <threads.h>\r
-\r
-int cnd_signal(cnd_t *cond)\r
-{\r
-       return thrd_success;\r
-}\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
+#ifndef REGTEST
+#include <threads.h>
+
+int cnd_signal(cnd_t *cond)
+{
+       return thrd_success;
+}
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    return TEST_RESULTS;
+}
+
+#endif
index 86b70ab663c08f23116686556162086152ce91eb..444e1d477c4e62868edfdb41894c8bfa2613f3b5 100644 (file)
@@ -1,18 +1,18 @@
-#ifndef REGTEST\r
-#include <threads.h>\r
-\r
-int cnd_wait(cnd_t *cond, mtx_t *mtx)\r
-{\r
-       return thrd_error;\r
-}\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
+#ifndef REGTEST
+#include <threads.h>
+
+int cnd_wait(cnd_t *cond, mtx_t *mtx)
+{
+       return thrd_error;
+}
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    return TEST_RESULTS;
+}
+
+#endif
index 344e0ee82bf7433a236dd39ff9d2d80b41588bd1..587b525cd880c57a368272d29dcdb8461e63db61 100644 (file)
@@ -1,16 +1,16 @@
-#ifndef REGTEST\r
-#include <threads.h>\r
-\r
-void mtx_destroy(mtx_t *mtx)\r
-{}\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
+#ifndef REGTEST
+#include <threads.h>
+
+void mtx_destroy(mtx_t *mtx)
+{}
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    return TEST_RESULTS;
+}
+
+#endif
index 6d48970a75e1c0fe8db3db36caeacf1a0ecd8b80..e1bf08e93ba51583f99f6e06fcf8b38131a38ff8 100644 (file)
@@ -1,19 +1,19 @@
-#ifndef REGTEST\r
-#include <threads.h>\r
-\r
-int mtx_init(mtx_t *mtx, int type)\r
-{\r
-       *mtx = 0;\r
-       return thrd_success;\r
-}\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
+#ifndef REGTEST
+#include <threads.h>
+
+int mtx_init(mtx_t *mtx, int type)
+{
+       *mtx = 0;
+       return thrd_success;
+}
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    return TEST_RESULTS;
+}
+
+#endif
index cebc07d506551e6b80ae4192d4e5276c6e6d6b2e..2c5a26df3bde69ac94390d356cfbfb94c98946c8 100644 (file)
@@ -1,19 +1,19 @@
-#ifndef REGTEST\r
-#include <threads.h>\r
-\r
-int mtx_lock(mtx_t *mtx)\r
-{\r
-       (*mtx)++;\r
-       return thrd_success;\r
-}\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
+#ifndef REGTEST
+#include <threads.h>
+
+int mtx_lock(mtx_t *mtx)
+{
+       (*mtx)++;
+       return thrd_success;
+}
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    return TEST_RESULTS;
+}
+
+#endif
index 047dce63beb5368baa485199f57b9af3da75a1e5..c9d8f205a523c52fb0384baab1bb8f96aa06b252 100644 (file)
@@ -1,18 +1,18 @@
-#ifndef REGTEST\r
-#include <threads.h>\r
-\r
-int mtx_timedlock(mtx_t *restrict mtx, const struct timespec *restrict ts)\r
-{\r
-       return mtx_lock(mtx);\r
-}\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
+#ifndef REGTEST
+#include <threads.h>
+
+int mtx_timedlock(mtx_t *restrict mtx, const struct timespec *restrict ts)
+{
+       return mtx_lock(mtx);
+}
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    return TEST_RESULTS;
+}
+
+#endif
index 3224e4732654c598b0fefda211fe3da2e18a8c1e..cd0c701c6fed179ff7b10443a13e2a42fafb20b5 100644 (file)
@@ -1,19 +1,19 @@
-#ifndef REGTEST\r
-#include <threads.h>\r
-\r
-int mtx_trylock(mtx_t *mtx)\r
-{\r
-       (*mtx)++;\r
-       return thrd_success;\r
-}\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
+#ifndef REGTEST
+#include <threads.h>
+
+int mtx_trylock(mtx_t *mtx)
+{
+       (*mtx)++;
+       return thrd_success;
+}
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    return TEST_RESULTS;
+}
+
+#endif
index a12c0a061123b40e2c5b3fe597cadb6336769b38..42f696aa27e613d00c2d0a9ac6d248df2a107a54 100644 (file)
@@ -1,20 +1,20 @@
-#ifndef REGTEST\r
-#include <threads.h>\r
-\r
-int mtx_unlock(mtx_t *mtx)\r
-{\r
-       if(--(*mtx) >= 0)\r
-        return thrd_success;\r
-    return thrd_error;\r
-}\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
+#ifndef REGTEST
+#include <threads.h>
+
+int mtx_unlock(mtx_t *mtx)
+{
+       if(--(*mtx) >= 0)
+        return thrd_success;
+    return thrd_error;
+}
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    return TEST_RESULTS;
+}
+
+#endif
index 0cb99acee7e374d2466f9955a794501095512fb3..55ce0a2a4d3ef6f050fe380fd838731b92452f6b 100644 (file)
@@ -1,18 +1,18 @@
-#ifndef REGTEST\r
-#include <threads.h>\r
-\r
-void thrd_yield(void)\r
-{\r
-       /* does nothing */\r
-}\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
+#ifndef REGTEST
+#include <threads.h>
+
+void thrd_yield(void)
+{
+       /* does nothing */
+}
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    return TEST_RESULTS;
+}
+
+#endif
index 640ab3000f349256e3cdd223ba6e74b383de30db..a778c7b438211240e00441ba0ea23437fbeba3f7 100644 (file)
@@ -1,21 +1,21 @@
-#ifndef REGTEST\r
-#include <threads.h>\r
-\r
-int tss_create(tss_t *key, tss_dtor_t dtor)\r
-{\r
-       key->self  = key;\r
-       key->value = NULL;\r
-       return thrd_success;\r
-}\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-/* Tested in tss_get.c */\r
-int main( void )\r
-{\r
-    return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
+#ifndef REGTEST
+#include <threads.h>
+
+int tss_create(tss_t *key, tss_dtor_t dtor)
+{
+       key->self  = key;
+       key->value = NULL;
+       return thrd_success;
+}
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+/* Tested in tss_get.c */
+int main( void )
+{
+    return TEST_RESULTS;
+}
+
+#endif
index 53c6e16d899dba5f365da003bf5e8aa56679cf51..bad8d0bf3d97a3f7052f2cbac89628f4de6c0eff 100644 (file)
@@ -1,19 +1,19 @@
-#ifndef REGTEST\r
-#include <threads.h>\r
-\r
-void tss_delete(tss_t key)\r
-{\r
-       key.self->self = NULL;\r
-}\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-/* Tested in tss_get.c */\r
-int main( void )\r
-{\r
-    return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
+#ifndef REGTEST
+#include <threads.h>
+
+void tss_delete(tss_t key)
+{
+       key.self->self = NULL;
+}
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+/* Tested in tss_get.c */
+int main( void )
+{
+    return TEST_RESULTS;
+}
+
+#endif
index 531368f937d3d7f4e18e0cc8f2c5ce861d843701..483088a252afd0c5ce9b4f2bb4292647272f2f24 100644 (file)
@@ -1,30 +1,30 @@
-#ifndef REGTEST\r
-#include <threads.h>\r
-\r
-void *tss_get(tss_t key)\r
-{\r
-       return key.value;\r
-}\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-#ifndef REGTEST\r
-static tss_t key;\r
-static char v;\r
-#endif\r
-\r
-int main( void )\r
-{\r
-#ifndef REGTEST\r
-    TESTCASE(tss_create(&key, NULL) == thrd_success);\r
-    TESTCASE(tss_get(key) == NULL);\r
-    TESTCASE(tss_set(key, &v) == thrd_success);\r
-    TESTCASE(tss_get(key) == &v);\r
-    tss_delete(key);\r
-#endif\r
-    return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
+#ifndef REGTEST
+#include <threads.h>
+
+void *tss_get(tss_t key)
+{
+       return key.value;
+}
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+#ifndef REGTEST
+static tss_t key;
+static char v;
+#endif
+
+int main( void )
+{
+#ifndef REGTEST
+    TESTCASE(tss_create(&key, NULL) == thrd_success);
+    TESTCASE(tss_get(key) == NULL);
+    TESTCASE(tss_set(key, &v) == thrd_success);
+    TESTCASE(tss_get(key) == &v);
+    tss_delete(key);
+#endif
+    return TEST_RESULTS;
+}
+
+#endif
index 1e8a5eb0ae3ff18115fdc44ba3b1c121e6021ec2..e66ea33894b32613a7f042378a0368da0c92b70a 100644 (file)
@@ -1,20 +1,20 @@
-#ifndef REGTEST\r
-#include <threads.h>\r
-\r
-int tss_set(tss_t key, void *val)\r
-{\r
-       key.self->value = val;\r
-       return thrd_success;\r
-}\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-/* Tested in tss_get.c */\r
-int main( void )\r
-{\r
-    return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
+#ifndef REGTEST
+#include <threads.h>
+
+int tss_set(tss_t key, void *val)
+{
+       key.self->value = val;
+       return thrd_success;
+}
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+/* Tested in tss_get.c */
+int main( void )
+{
+    return TEST_RESULTS;
+}
+
+#endif
index 32058fe99fe997c77a127ca4a770eef2854c8026..6bbf4c76c66ed10c365979541b7e467a14099533 100644 (file)
@@ -1,19 +1,19 @@
-#include <time.h>\r
-\r
-#ifndef REGTEST\r
-time_t time(time_t* t)\r
-{\r
-       if(t) *t = -1;\r
-       return -1;\r
-}\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
+#include <time.h>
+
+#ifndef REGTEST
+time_t time(time_t* t)
+{
+       if(t) *t = -1;
+       return -1;
+}
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    return TEST_RESULTS;
+}
+
+#endif
index 3f844f18f823dca99045ca93aa5b65c0827028ef..04acf61ac947a7212a6f6d91187e4dd8f25fb4ee 100644 (file)
@@ -1,18 +1,18 @@
-#include <time.h>\r
-#ifndef REGTEST\r
-\r
-int timespec_get( struct timespec *ts, int base )\r
-{\r
-    return 0;\r
-}\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
+#include <time.h>
+#ifndef REGTEST
+
+int timespec_get( struct timespec *ts, int base )
+{
+    return 0;
+}
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    return TEST_RESULTS;
+}
+
+#endif
index f17c12f83e46ed470a965447c742f5237127bb54..9b4d07226430df5d7e12812acd38234648448a42 100644 (file)
@@ -1,18 +1,18 @@
-rule PDCLibTargetConfig { }\r
-rule PDCLibTargetHeaders {\r
-    SubDirHdrs $(PDCLIB_TOP) platform example includes ;\r
-    SubDirHdrs $(PDCLIB_TOP) platform example internals ;\r
-}\r
-\r
-if $(PDCLIB_TOOLCHAIN) = "gcc" {\r
-    PDCLIB_TEST_LINKFLAGS += -nostdlib ;\r
-    PDCLIB_TEST_LINKLIBS += -lgcc ;\r
-}\r
-\r
-PDCLIB_OPTIONS = \r
-       nothread \r
-       notime \r
-       tss_errno \r
-       basecodecs \r
-    c_locale \r
-    ;\r
+rule PDCLibTargetConfig { }
+rule PDCLibTargetHeaders {
+    SubDirHdrs $(PDCLIB_TOP) platform example includes ;
+    SubDirHdrs $(PDCLIB_TOP) platform example internals ;
+}
+
+if $(PDCLIB_TOOLCHAIN) = "gcc" {
+    PDCLIB_TEST_LINKFLAGS += -nostdlib ;
+    PDCLIB_TEST_LINKLIBS += -lgcc ;
+}
+
+PDCLIB_OPTIONS = 
+       nothread 
+       notime 
+       tss_errno 
+       basecodecs 
+    c_locale 
+    ;
index 444f44aca5615ac207fa37d76f3ac93c799b966d..cbbdb382f7159adcf28963d077d96138287d7c3a 100644 (file)
@@ -1,2 +1,2 @@
-SubDir PDCLIB_TOP platform example ;\r
+SubDir PDCLIB_TOP platform example ;
 PDCLibConfig ;
\ No newline at end of file
index 1316cd6d691f85eec167c1910247993275484a93..bfe3d85b63196e148c62bc311c287f0f148c5983 100644 (file)
@@ -1,56 +1,56 @@
-/* _PDCLIB_fileops\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#ifndef REGTEST\r
-#include <stdio.h>\r
-#include <stdint.h>\r
-#include "_PDCLIB_glue.h"\r
-#include <errno.h>\r
-\r
-static bool readf( _PDCLIB_fd_t self, void * buf, size_t length, \r
-                   size_t * numBytesRead )\r
-{\r
-    errno = ENOTSUP;\r
-    return false;\r
-}\r
-\r
-static bool writef( _PDCLIB_fd_t self, const void * buf, size_t length, \r
-                   size_t * numBytesWritten )\r
-{\r
-    errno = ENOTSUP;\r
-    return false;\r
-}\r
-static bool seekf( _PDCLIB_fd_t self, int_fast64_t offset, int whence,\r
-    int_fast64_t* newPos )\r
-{\r
-    errno = ENOTSUP;\r
-    return false;\r
-}\r
-\r
-static void closef( _PDCLIB_fd_t self )\r
-{\r
-    errno = ENOTSUP;\r
-}\r
-\r
-const _PDCLIB_fileops_t _PDCLIB_fileops = {\r
-    .read  = readf,\r
-    .write = writef,\r
-    .seek  = seekf,\r
-    .close = closef,\r
-};\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    // Tested by stdio test cases\r
-    return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
+/* _PDCLIB_fileops
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#ifndef REGTEST
+#include <stdio.h>
+#include <stdint.h>
+#include "_PDCLIB_glue.h"
+#include <errno.h>
+
+static bool readf( _PDCLIB_fd_t self, void * buf, size_t length, 
+                   size_t * numBytesRead )
+{
+    errno = ENOTSUP;
+    return false;
+}
+
+static bool writef( _PDCLIB_fd_t self, const void * buf, size_t length, 
+                   size_t * numBytesWritten )
+{
+    errno = ENOTSUP;
+    return false;
+}
+static bool seekf( _PDCLIB_fd_t self, int_fast64_t offset, int whence,
+    int_fast64_t* newPos )
+{
+    errno = ENOTSUP;
+    return false;
+}
+
+static void closef( _PDCLIB_fd_t self )
+{
+    errno = ENOTSUP;
+}
+
+const _PDCLIB_fileops_t _PDCLIB_fileops = {
+    .read  = readf,
+    .write = writef,
+    .seek  = seekf,
+    .close = closef,
+};
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    // Tested by stdio test cases
+    return TEST_RESULTS;
+}
+
+#endif
index 686ea4ba3d9f2a7102b7c8f585d4ed7ec7db2593..117d149c767468db8a8103c55f55e9cbb23d649a 100644 (file)
@@ -1,37 +1,37 @@
-/* _PDCLIB_open( char const * const, int )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-/* This is a stub implementation of open.\r
-*/\r
-\r
-#include <stdio.h>\r
-#include <errno.h>\r
-\r
-#ifndef REGTEST\r
-#include "_PDCLIB_glue.h"\r
-\r
-bool _PDCLIB_open( _PDCLIB_fd_t * pFd, const _PDCLIB_fileops_t ** pOps,\r
-                   char const * const filename, unsigned int mode )\r
-{\r
-    errno = ENOTSUP;\r
-    return false;\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-#include <stdlib.h>\r
-#include <string.h>\r
-\r
-int main( void )\r
-{\r
-    return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
-\r
+/* _PDCLIB_open( char const * const, int )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+/* This is a stub implementation of open.
+*/
+
+#include <stdio.h>
+#include <errno.h>
+
+#ifndef REGTEST
+#include "_PDCLIB_glue.h"
+
+bool _PDCLIB_open( _PDCLIB_fd_t * pFd, const _PDCLIB_fileops_t ** pOps,
+                   char const * const filename, unsigned int mode )
+{
+    errno = ENOTSUP;
+    return false;
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+int main( void )
+{
+    return TEST_RESULTS;
+}
+
+#endif
+
index ef1893e0ef177e1adb98efdfa22d27f967ecb54f..62549762e50d2b4f4b026707155a2e383ec716af 100644 (file)
@@ -1,28 +1,28 @@
-/* _PDCLIB_allocpages( int const )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-/* This is a stub implementation of _PDCLIB_allocpages\r
-*/\r
-\r
-#include <stdint.h>\r
-#include <stddef.h>\r
-#include "_PDCLIB_glue.h"\r
-#include <errno.h>\r
-\r
-void _PDCLIB_freepages( void * p, size_t n )\r
-{\r
-    return;\r
-}\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
+/* _PDCLIB_allocpages( int const )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+/* This is a stub implementation of _PDCLIB_allocpages
+*/
+
+#include <stdint.h>
+#include <stddef.h>
+#include "_PDCLIB_glue.h"
+#include <errno.h>
+
+void _PDCLIB_freepages( void * p, size_t n )
+{
+    return;
+}
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    return TEST_RESULTS;
+}
+
+#endif
index d33f486555967783c06f9010cd172c6bdeeddc36..82eb816f0702421800242c42882c5500fb04ab58 100644 (file)
@@ -1,33 +1,33 @@
-/* _PDCLIB_allocpages( int const )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-/* This is a stub implementation of _PDCLIB_allocpages\r
-*/\r
-\r
-#include <stdint.h>\r
-#include <stddef.h>\r
-#include "_PDCLIB_glue.h"\r
-#include <errno.h>\r
-#include <gd_bal.h>\r
-\r
-void _PDCLIB_freepages( void * p, size_t n )\r
-{\r
-    int rv = 0;\r
-    if((rv = gd_free_pages( p, n ))) {\r
-        perror("_PDCLIB_freepages");\r
-        abort();\r
-    }\r
-}\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
+/* _PDCLIB_allocpages( int const )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+/* This is a stub implementation of _PDCLIB_allocpages
+*/
+
+#include <stdint.h>
+#include <stddef.h>
+#include "_PDCLIB_glue.h"
+#include <errno.h>
+#include <gd_bal.h>
+
+void _PDCLIB_freepages( void * p, size_t n )
+{
+    int rv = 0;
+    if((rv = gd_free_pages( p, n ))) {
+        perror("_PDCLIB_freepages");
+        abort();
+    }
+}
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    return TEST_RESULTS;
+}
+
+#endif
index 449a66be8874f016d423b597beae26c95bac3838..db43ae37b0296565f54007a2327bb9fc6116279c 100644 (file)
@@ -1,18 +1,18 @@
-rule PDCLibTargetConfig { }\r
-rule PDCLibTargetHeaders {\r
-    SubDirHdrs $(PDCLIB_TOP) platform posix includes ;\r
-    SubDirHdrs $(PDCLIB_TOP) platform posix internals ;\r
-}\r
-\r
-if $(OS) = "MACOSX" {\r
-    # Need to link libSystem\r
-} else {\r
-    #PDCLIB_TEST_LINKFLAGS += -nostdlib ;\r
-    PDCLIB_TEST_LINKLIBS += -lgcc -lpthread ;\r
-}\r
-\r
-PDCLIB_OPTIONS =\r
-    pthreads\r
-    notime\r
-    basecodecs\r
-    c_locale ;\r
+rule PDCLibTargetConfig { }
+rule PDCLibTargetHeaders {
+    SubDirHdrs $(PDCLIB_TOP) platform posix includes ;
+    SubDirHdrs $(PDCLIB_TOP) platform posix internals ;
+}
+
+if $(OS) = "MACOSX" {
+    # Need to link libSystem
+} else {
+    #PDCLIB_TEST_LINKFLAGS += -nostdlib ;
+    PDCLIB_TEST_LINKLIBS += -lgcc -lpthread ;
+}
+
+PDCLIB_OPTIONS =
+    pthreads
+    notime
+    basecodecs
+    c_locale ;
index 1c59de6d25a7009e20b49607fb66aaa4d23af61c..ac45789712afd956dbe697fcb79907dab4b39101 100644 (file)
@@ -1,34 +1,34 @@
-rule PDCLibTargetConfig { }\r
-rule PDCLibTargetHeaders {\r
-    SubDirHdrs $(PDCLIB_TOP) platform win32 includes ;\r
-    SubDirHdrs $(PDCLIB_TOP) platform win32 internals ;\r
-\r
-    if $(PDCLIB_TOOLCHAIN) = "WATCOM" {\r
-        SubDirHdrs $(WATCOM) h ;\r
-    }\r
-}\r
-\r
-if $(PDCLIB_TOOLCHAIN) = "gcc" {\r
-    PDCLIB_TEST_LINKFLAGS += -nostdlib ;\r
-    PDCLIB_TEST_LINKLIBS += -lgcc -lkernel32 -lshell32 ;\r
-} else if $(PDCLIB_TOOLCHAIN) = "WATCOM" {\r
-    PDCLIB_TEST_LINKFLAGS = "-\"option start=_mainCRTStartup\"" ;\r
-    PDCLIB_TEST_LINKLIBS = \r
-        $(WATCOM)\\lib386\\nt\\kernel32.lib \r
-        $(WATCOM)\\lib386\\nt\\shell32.lib\r
-        $(WATCOM)\\lib386\\nt\\clib3r.lib ;\r
-    PDCLIB_REGTEST_CCHDRS = [ FIncludes $(WATCOM)\\h ] ;\r
-} else {\r
-    ECHO Win32 doesn't support toolchain $(PDCLIB_TOOLCHAIN) ;\r
-    EXIT ;\r
-}\r
-\r
-PDCLIB_OPTIONS = \r
-    notime \r
-    mincoll \r
-    tss_errno \r
-    basecodecs \r
-    c_locale \r
-    ;\r
-\r
-CRT0 = [ FDirName platform win32 crt0$(SUFOBJ) ] ;\r
+rule PDCLibTargetConfig { }
+rule PDCLibTargetHeaders {
+    SubDirHdrs $(PDCLIB_TOP) platform win32 includes ;
+    SubDirHdrs $(PDCLIB_TOP) platform win32 internals ;
+
+    if $(PDCLIB_TOOLCHAIN) = "WATCOM" {
+        SubDirHdrs $(WATCOM) h ;
+    }
+}
+
+if $(PDCLIB_TOOLCHAIN) = "gcc" {
+    PDCLIB_TEST_LINKFLAGS += -nostdlib ;
+    PDCLIB_TEST_LINKLIBS += -lgcc -lkernel32 -lshell32 ;
+} else if $(PDCLIB_TOOLCHAIN) = "WATCOM" {
+    PDCLIB_TEST_LINKFLAGS = "-\"option start=_mainCRTStartup\"" ;
+    PDCLIB_TEST_LINKLIBS = 
+        $(WATCOM)\\lib386\\nt\\kernel32.lib 
+        $(WATCOM)\\lib386\\nt\\shell32.lib
+        $(WATCOM)\\lib386\\nt\\clib3r.lib ;
+    PDCLIB_REGTEST_CCHDRS = [ FIncludes $(WATCOM)\\h ] ;
+} else {
+    ECHO Win32 doesn't support toolchain $(PDCLIB_TOOLCHAIN) ;
+    EXIT ;
+}
+
+PDCLIB_OPTIONS = 
+    notime 
+    mincoll 
+    tss_errno 
+    basecodecs 
+    c_locale 
+    ;
+
+CRT0 = [ FDirName platform win32 crt0$(SUFOBJ) ] ;
index 35b8deab7eb7b8f62a14b53fe8127627d358b7c3..62f3bb51a3c8dbe0816c0fde37e6cdccf02f37a6 100644 (file)
@@ -1,6 +1,6 @@
-SubDir PDCLIB_TOP platform win32 ;\r
-PDCLibConfig ;\r
-\r
-Object $(CRT0) : $(CRT0:S=.c) ;\r
-\r
+SubDir PDCLIB_TOP platform win32 ;
+PDCLibConfig ;
+
+Object $(CRT0) : $(CRT0:S=.c) ;
+
 DEPENDS all : $(CRT0) ;
\ No newline at end of file
index 471e42c094fb199b39549dcc3911e4e649537e17..8cbb2c549360a199ae6f48760824834b149392f9 100644 (file)
-#include <string.h>\r
-#include <stdlib.h>\r
-#include <stdio.h>\r
-#include <signal.h>\r
-#include <threads.h>\r
-#include <wchar.h> // Watcom bug: winnt.h assumes string.h defines wchar_t\r
-#include <windows.h>\r
-#include "_PDCLIB_io.h"\r
-#include "_PDCLIB_locale.h"\r
-#include "_PDCLIB_clocale.h"\r
-\r
-static char ** argvToAnsi( wchar_t ** wargv, int argc )\r
-{\r
-    char ** argv = malloc( sizeof( *argv ) * argc );\r
-    for ( int i = 0; i != argc; ++i ) {\r
-        int sz = WideCharToMultiByte( CP_ACP, WC_COMPOSITECHECK | WC_SEPCHARS,\r
-                                      wargv[i], -1, NULL, 0, NULL, NULL );\r
-        if(!(argv[i] = malloc(sz))) {\r
-            fputs("Error in C runtime initialization: "\r
-                  "unable to allocate buffer for argument", stderr);\r
-            abort();\r
-        }\r
-\r
-        int rv = WideCharToMultiByte( CP_ACP, WC_COMPOSITECHECK | WC_SEPCHARS,\r
-                                      wargv[i], -1, argv[i], sz, NULL, NULL );\r
-\r
-        if(rv != sz) {\r
-            fputs("Error in C runtime initialization: "\r
-                  "size mismatch during character set conversion", stderr);\r
-            abort();\r
-        }\r
-    }\r
-    return argv;\r
-}\r
-\r
-static int        argc;\r
-static wchar_t *  cl;\r
-static wchar_t ** wargv;\r
-static char    ** argv;\r
-\r
-static void freeArgs( void )\r
-{\r
-    for(int i = 0; i != argc; i++) {\r
-        free( argv[i] );\r
-    }\r
-    free( argv );\r
-    LocalFree( wargv );\r
-}\r
-\r
-extern void (*_PDCLIB_sigfpe)( int );\r
-extern void (*_PDCLIB_sigill)( int );\r
-extern void (*_PDCLIB_sigsegv)( int );\r
-\r
-static LPTOP_LEVEL_EXCEPTION_FILTER oldFilter;\r
-static LONG CALLBACK sehExceptionFilter( EXCEPTION_POINTERS * exInfo )\r
-{\r
-    int sig;\r
-    void (*handler)( int );\r
-\r
-    switch( exInfo->ExceptionRecord->ExceptionCode ) {\r
-        case EXCEPTION_ACCESS_VIOLATION:\r
-        case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:\r
-        case EXCEPTION_DATATYPE_MISALIGNMENT:\r
-        case EXCEPTION_GUARD_PAGE:\r
-        case EXCEPTION_IN_PAGE_ERROR:\r
-        case EXCEPTION_STACK_OVERFLOW:\r
-            sig = SIGSEGV;\r
-            handler = _PDCLIB_sigsegv;\r
-            break;\r
-\r
-        case EXCEPTION_ILLEGAL_INSTRUCTION:\r
-        case EXCEPTION_PRIV_INSTRUCTION:\r
-            sig = SIGILL;\r
-            handler = _PDCLIB_sigill;\r
-            break;\r
-\r
-        case EXCEPTION_INT_DIVIDE_BY_ZERO:\r
-        case EXCEPTION_INT_OVERFLOW:\r
-        case EXCEPTION_FLT_DENORMAL_OPERAND:\r
-        case EXCEPTION_FLT_DIVIDE_BY_ZERO:\r
-        case EXCEPTION_FLT_INEXACT_RESULT:\r
-        case EXCEPTION_FLT_INVALID_OPERATION:\r
-        case EXCEPTION_FLT_OVERFLOW:\r
-        case EXCEPTION_FLT_STACK_CHECK:\r
-        case EXCEPTION_FLT_UNDERFLOW:\r
-            sig = SIGFPE;\r
-            handler = _PDCLIB_sigfpe;\r
-            break;\r
-\r
-        default:\r
-            return oldFilter ? oldFilter( exInfo ) : EXCEPTION_EXECUTE_HANDLER;\r
-    }\r
-\r
-    if(handler == SIG_DFL) {\r
-        return EXCEPTION_EXECUTE_HANDLER;\r
-    } else if(handler == SIG_IGN) {\r
-        return EXCEPTION_CONTINUE_EXECUTION;\r
-    } else {\r
-        handler( sig );\r
-        return EXCEPTION_CONTINUE_EXECUTION;\r
-    }\r
-}\r
-\r
-extern int main( int argc, char ** argv, char ** envp );\r
-\r
-void __cdecl mainCRTStartup( void );\r
-\r
-void __cdecl mainCRTStartup( void ) \r
-{\r
-    stdin->handle.pointer  = GetStdHandle(STD_INPUT_HANDLE);\r
-    stdout->handle.pointer = GetStdHandle(STD_OUTPUT_HANDLE);\r
-    stderr->handle.pointer = GetStdHandle(STD_ERROR_HANDLE);\r
-\r
-    oldFilter = SetUnhandledExceptionFilter( sehExceptionFilter );\r
-\r
-    cl    = GetCommandLineW();\r
-    wargv = CommandLineToArgvW(cl, &argc);\r
-    argv  = argvToAnsi(wargv, argc);\r
-\r
-    _PDCLIB_initclocale( &_PDCLIB_global_locale );\r
-\r
-    if(tss_create(&_PDCLIB_locale_tss, (tss_dtor_t) freelocale) \r
-            != thrd_success) {\r
-        fputs( "Error during C runtime initialization: "\r
-               "Unable to allocate locale TLS", stderr );\r
-        exit( EXIT_FAILURE );\r
-    }\r
-\r
-    if(        mtx_init(&stdin->lock, mtx_recursive) != thrd_success \r
-            || mtx_init(&stdout->lock, mtx_recursive) != thrd_success\r
-            || mtx_init(&stderr->lock, mtx_recursive) != thrd_success ) {\r
-        fputs( "Error during C runtime initialization: "\r
-            "Unable to allocate stdio mutex", stderr );\r
-        exit( EXIT_FAILURE );\r
-    }\r
-\r
-    atexit(freeArgs);\r
-\r
-    int exitStatus = main(argc, argv, NULL);\r
-\r
-    exit(exitStatus);\r
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <signal.h>
+#include <threads.h>
+#include <wchar.h> // Watcom bug: winnt.h assumes string.h defines wchar_t
+#include <windows.h>
+#include "_PDCLIB_io.h"
+#include "_PDCLIB_locale.h"
+#include "_PDCLIB_clocale.h"
+
+static char ** argvToAnsi( wchar_t ** wargv, int argc )
+{
+    char ** argv = malloc( sizeof( *argv ) * argc );
+    for ( int i = 0; i != argc; ++i ) {
+        int sz = WideCharToMultiByte( CP_ACP, WC_COMPOSITECHECK | WC_SEPCHARS,
+                                      wargv[i], -1, NULL, 0, NULL, NULL );
+        if(!(argv[i] = malloc(sz))) {
+            fputs("Error in C runtime initialization: "
+                  "unable to allocate buffer for argument", stderr);
+            abort();
+        }
+
+        int rv = WideCharToMultiByte( CP_ACP, WC_COMPOSITECHECK | WC_SEPCHARS,
+                                      wargv[i], -1, argv[i], sz, NULL, NULL );
+
+        if(rv != sz) {
+            fputs("Error in C runtime initialization: "
+                  "size mismatch during character set conversion", stderr);
+            abort();
+        }
+    }
+    return argv;
+}
+
+static int        argc;
+static wchar_t *  cl;
+static wchar_t ** wargv;
+static char    ** argv;
+
+static void freeArgs( void )
+{
+    for(int i = 0; i != argc; i++) {
+        free( argv[i] );
+    }
+    free( argv );
+    LocalFree( wargv );
+}
+
+extern void (*_PDCLIB_sigfpe)( int );
+extern void (*_PDCLIB_sigill)( int );
+extern void (*_PDCLIB_sigsegv)( int );
+
+static LPTOP_LEVEL_EXCEPTION_FILTER oldFilter;
+static LONG CALLBACK sehExceptionFilter( EXCEPTION_POINTERS * exInfo )
+{
+    int sig;
+    void (*handler)( int );
+
+    switch( exInfo->ExceptionRecord->ExceptionCode ) {
+        case EXCEPTION_ACCESS_VIOLATION:
+        case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
+        case EXCEPTION_DATATYPE_MISALIGNMENT:
+        case EXCEPTION_GUARD_PAGE:
+        case EXCEPTION_IN_PAGE_ERROR:
+        case EXCEPTION_STACK_OVERFLOW:
+            sig = SIGSEGV;
+            handler = _PDCLIB_sigsegv;
+            break;
+
+        case EXCEPTION_ILLEGAL_INSTRUCTION:
+        case EXCEPTION_PRIV_INSTRUCTION:
+            sig = SIGILL;
+            handler = _PDCLIB_sigill;
+            break;
+
+        case EXCEPTION_INT_DIVIDE_BY_ZERO:
+        case EXCEPTION_INT_OVERFLOW:
+        case EXCEPTION_FLT_DENORMAL_OPERAND:
+        case EXCEPTION_FLT_DIVIDE_BY_ZERO:
+        case EXCEPTION_FLT_INEXACT_RESULT:
+        case EXCEPTION_FLT_INVALID_OPERATION:
+        case EXCEPTION_FLT_OVERFLOW:
+        case EXCEPTION_FLT_STACK_CHECK:
+        case EXCEPTION_FLT_UNDERFLOW:
+            sig = SIGFPE;
+            handler = _PDCLIB_sigfpe;
+            break;
+
+        default:
+            return oldFilter ? oldFilter( exInfo ) : EXCEPTION_EXECUTE_HANDLER;
+    }
+
+    if(handler == SIG_DFL) {
+        return EXCEPTION_EXECUTE_HANDLER;
+    } else if(handler == SIG_IGN) {
+        return EXCEPTION_CONTINUE_EXECUTION;
+    } else {
+        handler( sig );
+        return EXCEPTION_CONTINUE_EXECUTION;
+    }
+}
+
+extern int main( int argc, char ** argv, char ** envp );
+
+void __cdecl mainCRTStartup( void );
+
+void __cdecl mainCRTStartup( void ) 
+{
+    stdin->handle.pointer  = GetStdHandle(STD_INPUT_HANDLE);
+    stdout->handle.pointer = GetStdHandle(STD_OUTPUT_HANDLE);
+    stderr->handle.pointer = GetStdHandle(STD_ERROR_HANDLE);
+
+    oldFilter = SetUnhandledExceptionFilter( sehExceptionFilter );
+
+    cl    = GetCommandLineW();
+    wargv = CommandLineToArgvW(cl, &argc);
+    argv  = argvToAnsi(wargv, argc);
+
+    _PDCLIB_initclocale( &_PDCLIB_global_locale );
+
+    if(tss_create(&_PDCLIB_locale_tss, (tss_dtor_t) freelocale) 
+            != thrd_success) {
+        fputs( "Error during C runtime initialization: "
+               "Unable to allocate locale TLS", stderr );
+        exit( EXIT_FAILURE );
+    }
+
+    if(        mtx_init(&stdin->lock, mtx_recursive) != thrd_success 
+            || mtx_init(&stdout->lock, mtx_recursive) != thrd_success
+            || mtx_init(&stderr->lock, mtx_recursive) != thrd_success ) {
+        fputs( "Error during C runtime initialization: "
+            "Unable to allocate stdio mutex", stderr );
+        exit( EXIT_FAILURE );
+    }
+
+    atexit(freeArgs);
+
+    int exitStatus = main(argc, argv, NULL);
+
+    exit(exitStatus);
 }
\ No newline at end of file
index 2bd511389c4c583cee3e60bd89d313a26a16cc4f..f9b695b393495f2225749cbc746c1593cfdc322f 100644 (file)
@@ -1,87 +1,87 @@
-/* _PDCLIB_fileops\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-#ifndef REGTEST\r
-#include <stdio.h>\r
-#include <stdint.h>\r
-#include "_PDCLIB_glue.h"\r
-#include <errno.h>\r
-#include <windows.h>\r
-\r
-#if _PDCLIB_C_MIN(2011)\r
-_Static_assert(SEEK_SET == FILE_BEGIN, "SEEK_SET is incorrect");\r
-_Static_assert(SEEK_CUR == FILE_CURRENT, "SEEK_CUR is incorrect");\r
-_Static_assert(SEEK_END == FILE_END, "SEEK_END is incorrect");\r
-#endif\r
-\r
-void _PDCLIB_w32errno(void);\r
-\r
-static bool readf( _PDCLIB_fd_t self, void * buf, size_t length, \r
-                   size_t * numBytesRead )\r
-{\r
-    DWORD dwLen = length > INT32_MAX ? INT32_MAX : length;\r
-    DWORD dwBytesRead;\r
-    if(ReadFile(self.pointer, buf, dwLen, &dwBytesRead, NULL)) {\r
-        *numBytesRead = dwBytesRead;\r
-        return true;\r
-    } else {\r
-        _PDCLIB_w32errno();\r
-        return false;\r
-    }\r
-}\r
-\r
-static bool writef( _PDCLIB_fd_t self, const void * buf, size_t length, \r
-                   size_t * numBytesWritten )\r
-{\r
-    DWORD dwLen = length > INT32_MAX ? INT32_MAX : length;\r
-    DWORD dwBytesWritten;\r
-\r
-    if(WriteFile(self.pointer, buf, dwLen, &dwBytesWritten, NULL)) {\r
-        *numBytesWritten = dwBytesWritten;\r
-        return true;\r
-    } else {\r
-        _PDCLIB_w32errno();\r
-        return false;\r
-    }\r
-}\r
-static bool seekf( _PDCLIB_fd_t self, int_fast64_t offset, int whence,\r
-    int_fast64_t* newPos )\r
-{\r
-    LARGE_INTEGER liOffset;\r
-    liOffset.QuadPart = offset;\r
-    if(!SetFilePointerEx( self.pointer, liOffset, &liOffset, whence )) {\r
-        _PDCLIB_w32errno();\r
-        return false;\r
-    }\r
-\r
-    *newPos = liOffset.QuadPart;\r
-    return true;\r
-}\r
-\r
-static void closef( _PDCLIB_fd_t self )\r
-{\r
-    CloseHandle( self.pointer );\r
-}\r
-\r
-const _PDCLIB_fileops_t _PDCLIB_fileops = {\r
-    .read  = readf,\r
-    .write = writef,\r
-    .seek  = seekf,\r
-    .close = closef,\r
-};\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    // Tested by stdio test cases\r
-    return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
+/* _PDCLIB_fileops
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#ifndef REGTEST
+#include <stdio.h>
+#include <stdint.h>
+#include "_PDCLIB_glue.h"
+#include <errno.h>
+#include <windows.h>
+
+#if _PDCLIB_C_MIN(2011)
+_Static_assert(SEEK_SET == FILE_BEGIN, "SEEK_SET is incorrect");
+_Static_assert(SEEK_CUR == FILE_CURRENT, "SEEK_CUR is incorrect");
+_Static_assert(SEEK_END == FILE_END, "SEEK_END is incorrect");
+#endif
+
+void _PDCLIB_w32errno(void);
+
+static bool readf( _PDCLIB_fd_t self, void * buf, size_t length, 
+                   size_t * numBytesRead )
+{
+    DWORD dwLen = length > INT32_MAX ? INT32_MAX : length;
+    DWORD dwBytesRead;
+    if(ReadFile(self.pointer, buf, dwLen, &dwBytesRead, NULL)) {
+        *numBytesRead = dwBytesRead;
+        return true;
+    } else {
+        _PDCLIB_w32errno();
+        return false;
+    }
+}
+
+static bool writef( _PDCLIB_fd_t self, const void * buf, size_t length, 
+                   size_t * numBytesWritten )
+{
+    DWORD dwLen = length > INT32_MAX ? INT32_MAX : length;
+    DWORD dwBytesWritten;
+
+    if(WriteFile(self.pointer, buf, dwLen, &dwBytesWritten, NULL)) {
+        *numBytesWritten = dwBytesWritten;
+        return true;
+    } else {
+        _PDCLIB_w32errno();
+        return false;
+    }
+}
+static bool seekf( _PDCLIB_fd_t self, int_fast64_t offset, int whence,
+    int_fast64_t* newPos )
+{
+    LARGE_INTEGER liOffset;
+    liOffset.QuadPart = offset;
+    if(!SetFilePointerEx( self.pointer, liOffset, &liOffset, whence )) {
+        _PDCLIB_w32errno();
+        return false;
+    }
+
+    *newPos = liOffset.QuadPart;
+    return true;
+}
+
+static void closef( _PDCLIB_fd_t self )
+{
+    CloseHandle( self.pointer );
+}
+
+const _PDCLIB_fileops_t _PDCLIB_fileops = {
+    .read  = readf,
+    .write = writef,
+    .seek  = seekf,
+    .close = closef,
+};
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    // Tested by stdio test cases
+    return TEST_RESULTS;
+}
+
+#endif
index 6779b50f70724d586d119a669f70d3d28c718d79..4a0404afc472e9ae16404e4a5030e74ec245ddec 100644 (file)
@@ -1,30 +1,30 @@
-/* _PDCLIB_allocpages( int const )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-/* This is a stub implementation of _PDCLIB_allocpages\r
-*/\r
-\r
-#include <stdint.h>\r
-#include <stddef.h>\r
-#include <errno.h>\r
-#ifndef REGTEST\r
-#include "_PDCLIB_glue.h"\r
-\r
-void _PDCLIB_freepages( void * p, size_t n )\r
-{\r
-    return;\r
-}\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
+/* _PDCLIB_allocpages( int const )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+/* This is a stub implementation of _PDCLIB_allocpages
+*/
+
+#include <stdint.h>
+#include <stddef.h>
+#include <errno.h>
+#ifndef REGTEST
+#include "_PDCLIB_glue.h"
+
+void _PDCLIB_freepages( void * p, size_t n )
+{
+    return;
+}
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    return TEST_RESULTS;
+}
+
+#endif
index 2a656a43db03695ecf9533423de0375074aef208..064fd40957dfc76b714e0b70786890d650740a3f 100644 (file)
@@ -1,34 +1,34 @@
-#include <stddef.h>\r
-#include <windows.h>\r
-\r
-#ifndef REGTEST\r
-extern PIMAGE_TLS_CALLBACK __crt_xl_start__;\r
-#ifdef __GNUC__\r
-__attribute__((section(".CRT$XLZZZ")))\r
-#else\r
-__declspec(allocate(".CRT$XLZZZ")) \r
-#endif\r
-PIMAGE_TLS_CALLBACK __crt_xl_end__ = NULL;\r
-\r
-/* Runs all TLS callbacks registered in the executable\r
- */\r
-\r
-void NTAPI _PDCLIB_runTlsCallbacks(void * image, DWORD reason, PVOID pv);\r
-void NTAPI _PDCLIB_runTlsCallbacks(void * image, DWORD reason, PVOID pv)\r
-{\r
-    PIMAGE_TLS_CALLBACK * pcb = &__crt_xl_start__;\r
-\r
-    while(*pcb) (*(pcb++))(image, reason, pv);\r
-}\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-/* Tested in tss_get.c */\r
-int main( void )\r
-{\r
-    return TEST_RESULTS;\r
-}\r
-\r
+#include <stddef.h>
+#include <windows.h>
+
+#ifndef REGTEST
+extern PIMAGE_TLS_CALLBACK __crt_xl_start__;
+#ifdef __GNUC__
+__attribute__((section(".CRT$XLZZZ")))
+#else
+__declspec(allocate(".CRT$XLZZZ")) 
+#endif
+PIMAGE_TLS_CALLBACK __crt_xl_end__ = NULL;
+
+/* Runs all TLS callbacks registered in the executable
+ */
+
+void NTAPI _PDCLIB_runTlsCallbacks(void * image, DWORD reason, PVOID pv);
+void NTAPI _PDCLIB_runTlsCallbacks(void * image, DWORD reason, PVOID pv)
+{
+    PIMAGE_TLS_CALLBACK * pcb = &__crt_xl_start__;
+
+    while(*pcb) (*(pcb++))(image, reason, pv);
+}
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+/* Tested in tss_get.c */
+int main( void )
+{
+    return TEST_RESULTS;
+}
+
 #endif
\ No newline at end of file
index 6a7bc019cfb5980d40139bccce5ae79003d996b9..8f2c8020c8edae0e902ec7973b56d6606c0e12e9 100644 (file)
@@ -1,57 +1,57 @@
-/* _PDCLIB_allocpages( int const )\r
-\r
-   This file is part of the Public Domain C Library (PDCLib).\r
-   Permission is granted to use, modify, and / or redistribute at will.\r
-*/\r
-\r
-/* This is a stub implementation of _PDCLIB_allocpages\r
-*/\r
-\r
-#ifndef REGTEST\r
-#include <errno.h>\r
-#include <wchar.h> // Watcom bug: winnt.h assumes string.h defines wchar_t\r
-#include <windows.h>\r
-\r
-void _PDCLIB_w32errno(void);\r
-\r
-void _PDCLIB_w32errno(void)\r
-{\r
-    // Not exhaustive\r
-    switch(GetLastError()) {\r
-        case ERROR_SUCCESS:\r
-            return;\r
-        case ERROR_FILE_NOT_FOUND:\r
-        case ERROR_PATH_NOT_FOUND:\r
-        case ERROR_INVALID_DRIVE:\r
-            errno = ENOENT; break;\r
-        case ERROR_TOO_MANY_OPEN_FILES:\r
-            errno = EMFILE; break;\r
-        case ERROR_ACCESS_DENIED:\r
-        case ERROR_WRITE_PROTECT:\r
-            errno = EPERM; break;\r
-        case ERROR_INVALID_HANDLE:\r
-            errno = EBADF; break;\r
-        case ERROR_NOT_ENOUGH_MEMORY:\r
-        case ERROR_OUTOFMEMORY:\r
-            errno = ENOMEM; break;\r
-        case ERROR_NOT_READY:\r
-            errno = EAGAIN; break;\r
-        case ERROR_BAD_LENGTH:\r
-            errno = EINVAL; break;\r
-        default:\r
-            // TODO: reconsider what to use here?\r
-            errno = ENOSYS; break;\r
-    }\r
-}\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
+/* _PDCLIB_allocpages( int const )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+/* This is a stub implementation of _PDCLIB_allocpages
+*/
+
+#ifndef REGTEST
+#include <errno.h>
+#include <wchar.h> // Watcom bug: winnt.h assumes string.h defines wchar_t
+#include <windows.h>
+
+void _PDCLIB_w32errno(void);
+
+void _PDCLIB_w32errno(void)
+{
+    // Not exhaustive
+    switch(GetLastError()) {
+        case ERROR_SUCCESS:
+            return;
+        case ERROR_FILE_NOT_FOUND:
+        case ERROR_PATH_NOT_FOUND:
+        case ERROR_INVALID_DRIVE:
+            errno = ENOENT; break;
+        case ERROR_TOO_MANY_OPEN_FILES:
+            errno = EMFILE; break;
+        case ERROR_ACCESS_DENIED:
+        case ERROR_WRITE_PROTECT:
+            errno = EPERM; break;
+        case ERROR_INVALID_HANDLE:
+            errno = EBADF; break;
+        case ERROR_NOT_ENOUGH_MEMORY:
+        case ERROR_OUTOFMEMORY:
+            errno = ENOMEM; break;
+        case ERROR_NOT_READY:
+            errno = EAGAIN; break;
+        case ERROR_BAD_LENGTH:
+            errno = EINVAL; break;
+        default:
+            // TODO: reconsider what to use here?
+            errno = ENOSYS; break;
+    }
+}
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    return TEST_RESULTS;
+}
+
+#endif
index 328d77e643d9e717299531eb2bee7bee4ad4161d..e13168ba29fb3fd7f7573338ad17026349afd4b4 100644 (file)
@@ -1,55 +1,55 @@
-#ifndef REGTEST\r
-#include <stddef.h>\r
-#include <stdint.h>\r
-#include <windows.h>\r
-\r
-/* Win32 TLS support\r
- *\r
- * Components which depend upon TLS must express a dependency on the symbol \r
- * _tls_used. This will cause said symbol to be emitted.\r
- *\r
- * The linker (in the case of both Microsoft's linker and Binutils, at least)\r
- * will point the TLS directory entry in the PE header to _tls_used.\r
- *\r
- * NOTE: On Windows versions < NT 6.0, the TLS support _only_ works for \r
- *       the main executable and any DLLs loaded as dependencies of it\r
- */\r
-\r
-extern char __tls_start__[], __tls_end__[];\r
-ULONG _tls_index = TLS_OUT_OF_INDEXES;\r
-\r
-extern void NTAPI _PDCLIB_runTlsCallbacks(void * image, DWORD reason, PVOID pv);\r
-static PIMAGE_TLS_CALLBACK tlsCallbacks[] = {\r
-    &_PDCLIB_runTlsCallbacks,\r
-    NULL,\r
-};\r
-\r
-#ifdef __GNUC__\r
-__attribute__((__section__(".rdata$T")))\r
-#else\r
-__declspec(allocate(".rdata$T"))\r
-#endif\r
-#ifdef _WIN64\r
-const IMAGE_TLS_DIRECTORY64 _tls_used = {\r
-#else\r
-const IMAGE_TLS_DIRECTORY _tls_used = {\r
-#endif\r
-        (uintptr_t) &__tls_start__,\r
-        (uintptr_t) &__tls_end__,\r
-        (uintptr_t) &_tls_index,        // TLS index\r
-        (uintptr_t) &tlsCallbacks[0],   // TLS callback array\r
-        (ULONG) 0,                      // Size of zero fill\r
-        (ULONG) 0                       // Characteristics\r
-};\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-/* Tested in tss_get.c */\r
-int main( void )\r
-{\r
-    return TEST_RESULTS;\r
-}\r
-\r
+#ifndef REGTEST
+#include <stddef.h>
+#include <stdint.h>
+#include <windows.h>
+
+/* Win32 TLS support
+ *
+ * Components which depend upon TLS must express a dependency on the symbol 
+ * _tls_used. This will cause said symbol to be emitted.
+ *
+ * The linker (in the case of both Microsoft's linker and Binutils, at least)
+ * will point the TLS directory entry in the PE header to _tls_used.
+ *
+ * NOTE: On Windows versions < NT 6.0, the TLS support _only_ works for 
+ *       the main executable and any DLLs loaded as dependencies of it
+ */
+
+extern char __tls_start__[], __tls_end__[];
+ULONG _tls_index = TLS_OUT_OF_INDEXES;
+
+extern void NTAPI _PDCLIB_runTlsCallbacks(void * image, DWORD reason, PVOID pv);
+static PIMAGE_TLS_CALLBACK tlsCallbacks[] = {
+    &_PDCLIB_runTlsCallbacks,
+    NULL,
+};
+
+#ifdef __GNUC__
+__attribute__((__section__(".rdata$T")))
+#else
+__declspec(allocate(".rdata$T"))
+#endif
+#ifdef _WIN64
+const IMAGE_TLS_DIRECTORY64 _tls_used = {
+#else
+const IMAGE_TLS_DIRECTORY _tls_used = {
+#endif
+        (uintptr_t) &__tls_start__,
+        (uintptr_t) &__tls_end__,
+        (uintptr_t) &_tls_index,        // TLS index
+        (uintptr_t) &tlsCallbacks[0],   // TLS callback array
+        (ULONG) 0,                      // Size of zero fill
+        (ULONG) 0                       // Characteristics
+};
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+/* Tested in tss_get.c */
+int main( void )
+{
+    return TEST_RESULTS;
+}
+
 #endif
\ No newline at end of file
index 211b21984be665be994d6ab42eb01df0a162661f..6996b3e5622e044a204c0f19454210e0b5fe6836 100644 (file)
@@ -1,79 +1,79 @@
-#ifndef REGTEST\r
-#include <threads.h>\r
-#include <windows.h>\r
-\r
-static volatile HANDLE onceHandle = NULL;\r
-\r
-static void initOnceHandle( _PDCLIB_once_flag *flag )\r
-{\r
-    HANDLE tOnceHandle = CreateEvent(NULL, TRUE, TRUE, NULL);\r
-    HANDLE oldVal \r
-        = InterlockedCompareExchangePointer(&flag->_Handle, tOnceHandle, NULL);\r
-    if(oldVal != NULL)\r
-        CloseHandle(tOnceHandle);\r
-}\r
-\r
-void _PDCLIB_call_once(_PDCLIB_once_flag *flag, void (*func)(void))\r
-{\r
-   if(!flag->_Handle) initOnceHandle(flag);\r
-\r
-   long oldVal = InterlockedCompareExchange(&flag->_State, 1, -1);\r
-   for(;;) {\r
-        if(oldVal == 0) {\r
-            // Initialized\r
-            return;\r
-        } else if(oldVal == -1) {\r
-            // We are doing the initialization\r
-            func();\r
-            if(InterlockedDecrement(&flag->_State) == 0)\r
-                CloseHandle(flag->_Handle);\r
-            SetEvent(flag->_Handle);\r
-            return;\r
-        } else {\r
-            // Somebody else is initializing - we are waiting\r
-            long newOldVal = InterlockedCompareExchange(&flag->_State, oldVal, \r
-                                                        oldVal+1);\r
-            if(newOldVal == oldVal) {\r
-                // We incremented the "waiters" counter\r
-                if(WaitForSingleObject(flag->_Handle, INFINITE) != WAIT_OBJECT_0)\r
-                    abort();\r
-                if(InterlockedDecrement(&flag->_State) == 0)\r
-                    CloseHandle(flag->_Handle);\r
-                return;\r
-            } else {\r
-                oldVal = newOldVal;\r
-                continue;\r
-            }\r
-        }\r
-    }\r
-}\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-#ifndef REGTEST\r
-static int count = 0;\r
-static once_flag once = ONCE_FLAG_INIT;\r
-\r
-static void do_once(void)\r
-{\r
-    count++;\r
-}\r
-#endif\r
-\r
-int main( void )\r
-{\r
-#ifndef REGTEST\r
-    TESTCASE(count == 0);\r
-    call_once(&once, do_once);\r
-    TESTCASE(count == 1);\r
-    call_once(&once, do_once);\r
-    TESTCASE(count == 1);\r
-    do_once();\r
-    TESTCASE(count == 2);\r
-#endif\r
-    return TEST_RESULTS;\r
-}\r
-\r
-#endif\r
+#ifndef REGTEST
+#include <threads.h>
+#include <windows.h>
+
+static volatile HANDLE onceHandle = NULL;
+
+static void initOnceHandle( _PDCLIB_once_flag *flag )
+{
+    HANDLE tOnceHandle = CreateEvent(NULL, TRUE, TRUE, NULL);
+    HANDLE oldVal 
+        = InterlockedCompareExchangePointer(&flag->_Handle, tOnceHandle, NULL);
+    if(oldVal != NULL)
+        CloseHandle(tOnceHandle);
+}
+
+void _PDCLIB_call_once(_PDCLIB_once_flag *flag, void (*func)(void))
+{
+   if(!flag->_Handle) initOnceHandle(flag);
+
+   long oldVal = InterlockedCompareExchange(&flag->_State, 1, -1);
+   for(;;) {
+        if(oldVal == 0) {
+            // Initialized
+            return;
+        } else if(oldVal == -1) {
+            // We are doing the initialization
+            func();
+            if(InterlockedDecrement(&flag->_State) == 0)
+                CloseHandle(flag->_Handle);
+            SetEvent(flag->_Handle);
+            return;
+        } else {
+            // Somebody else is initializing - we are waiting
+            long newOldVal = InterlockedCompareExchange(&flag->_State, oldVal, 
+                                                        oldVal+1);
+            if(newOldVal == oldVal) {
+                // We incremented the "waiters" counter
+                if(WaitForSingleObject(flag->_Handle, INFINITE) != WAIT_OBJECT_0)
+                    abort();
+                if(InterlockedDecrement(&flag->_State) == 0)
+                    CloseHandle(flag->_Handle);
+                return;
+            } else {
+                oldVal = newOldVal;
+                continue;
+            }
+        }
+    }
+}
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+#ifndef REGTEST
+static int count = 0;
+static once_flag once = ONCE_FLAG_INIT;
+
+static void do_once(void)
+{
+    count++;
+}
+#endif
+
+int main( void )
+{
+#ifndef REGTEST
+    TESTCASE(count == 0);
+    call_once(&once, do_once);
+    TESTCASE(count == 1);
+    call_once(&once, do_once);
+    TESTCASE(count == 1);
+    do_once();
+    TESTCASE(count == 2);
+#endif
+    return TEST_RESULTS;
+}
+
+#endif
index ac89e11f957aca12069d79bf7473a828c04ade80..2f8a6c308a8be05f4aec0174ddb1f16edda5259f 100644 (file)
@@ -1,19 +1,19 @@
-#ifndef REGTEST\r
-#include <threads.h>\r
-#include <windows.h>\r
-\r
-void mtx_destroy(mtx_t *mtx)\r
-{\r
-    CloseHandle(mtx->_WaitEvHandle);\r
-}\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    return TEST_RESULTS;\r
-}\r
-\r
+#ifndef REGTEST
+#include <threads.h>
+#include <windows.h>
+
+void mtx_destroy(mtx_t *mtx)
+{
+    CloseHandle(mtx->_WaitEvHandle);
+}
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    return TEST_RESULTS;
+}
+
 #endif
\ No newline at end of file
index 72055519128933d52d93dcbfb3e3feb94d9bca02..b97b366c2a9c2430975ea497cf31fe64c0ddc89b 100644 (file)
@@ -1,29 +1,29 @@
-#ifndef REGTEST\r
-#include <threads.h>\r
-#include <windows.h>\r
-\r
-int mtx_init(mtx_t *mtx, int type)\r
-{\r
-    mtx->_WaitEvHandle = CreateEvent(NULL, \r
-        /* bManualReset*/   FALSE, \r
-        /* bInitialState*/  FALSE, \r
-        /* name*/           NULL);\r
-    if(mtx->_WaitEvHandle == NULL)\r
-        return thrd_error;\r
-    \r
-    mtx->_ThreadId     = 0;\r
-    mtx->_NestCount    = 0;;\r
-\r
-    return thrd_success;\r
-}\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    return TEST_RESULTS;\r
-}\r
-\r
+#ifndef REGTEST
+#include <threads.h>
+#include <windows.h>
+
+int mtx_init(mtx_t *mtx, int type)
+{
+    mtx->_WaitEvHandle = CreateEvent(NULL, 
+        /* bManualReset*/   FALSE, 
+        /* bInitialState*/  FALSE, 
+        /* name*/           NULL);
+    if(mtx->_WaitEvHandle == NULL)
+        return thrd_error;
+    
+    mtx->_ThreadId     = 0;
+    mtx->_NestCount    = 0;;
+
+    return thrd_success;
+}
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    return TEST_RESULTS;
+}
+
 #endif
\ No newline at end of file
index b76c8ec5ad66d7c0efa4c3208f5894b7f918a754..f2a17419b4b982498388bfc3be2f3f1303d43a22 100644 (file)
@@ -1,34 +1,34 @@
-#ifndef REGTEST\r
-#include <threads.h>\r
-#include <windows.h>\r
-\r
-int mtx_lock(mtx_t *mtx)\r
-{\r
-    DWORD myId = GetCurrentThreadId();\r
-\r
-    if(mtx->_ThreadId == (long) myId) {\r
-        mtx->_NestCount++;\r
-        return thrd_success;\r
-    }\r
-\r
-    for(;;) {\r
-        LONG prev = InterlockedCompareExchange(&mtx->_ThreadId, myId, 0);\r
-        if(prev == 0)\r
-            return thrd_success;\r
-\r
-        DWORD rv = WaitForSingleObject(mtx->_WaitEvHandle, INFINITE);\r
-        if(rv != WAIT_OBJECT_0)\r
-            return thrd_error;\r
-    }\r
-}\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    return TEST_RESULTS;\r
-}\r
-\r
+#ifndef REGTEST
+#include <threads.h>
+#include <windows.h>
+
+int mtx_lock(mtx_t *mtx)
+{
+    DWORD myId = GetCurrentThreadId();
+
+    if(mtx->_ThreadId == (long) myId) {
+        mtx->_NestCount++;
+        return thrd_success;
+    }
+
+    for(;;) {
+        LONG prev = InterlockedCompareExchange(&mtx->_ThreadId, myId, 0);
+        if(prev == 0)
+            return thrd_success;
+
+        DWORD rv = WaitForSingleObject(mtx->_WaitEvHandle, INFINITE);
+        if(rv != WAIT_OBJECT_0)
+            return thrd_error;
+    }
+}
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    return TEST_RESULTS;
+}
+
 #endif
\ No newline at end of file
index 79c96e9f07c3dbdc621156d87953ce93c54eee3c..a0ddb2b1ae8d9898f8aecbae85d5cf7af3c6ce37 100644 (file)
@@ -1,58 +1,58 @@
-#ifndef REGTEST\r
-#include <threads.h>\r
-#include <windows.h>\r
-#include <stdint.h>\r
-\r
-int mtx_timedlock(mtx_t *_PDCLIB_restrict mtx, \r
-                  const struct timespec *_PDCLIB_restrict until)\r
-{\r
-    DWORD myId = GetCurrentThreadId();\r
-\r
-    if(mtx->_ThreadId == (long) myId) {\r
-        mtx->_NestCount++;\r
-        return thrd_success;\r
-    }\r
-\r
-\r
-    for(;;) {\r
-        LONG prev = InterlockedCompareExchange(&mtx->_ThreadId, myId, 0);\r
-        if(prev == 0)\r
-            return thrd_success;\r
-\r
-        struct timespec now;\r
-        int32_t msToWait = 0;\r
-        if(timespec_get(&now, TIME_UTC) != TIME_UTC) {\r
-            // timespec_get must work!\r
-            return thrd_error;\r
-        } else {\r
-            int64_t deltaSec  = (int64_t)until->tv_sec  - now.tv_sec;\r
-            long    deltaNsec = (long)until->tv_nsec - now.tv_nsec;\r
-\r
-            if(INT32_MAX / 2000U < deltaSec) {\r
-                // Risk of overflow - do a shorter timeout on this iteration\r
-                msToWait = INT32_MAX / 2;\r
-            } else {\r
-                msToWait = deltaSec * 1000 + deltaNsec / 1000;\r
-            }\r
-        }\r
-\r
-        if(msToWait < 0) {\r
-            return thrd_timeout;\r
-        }\r
-\r
-        DWORD rv = WaitForSingleObject(mtx->_WaitEvHandle, msToWait);\r
-        if(rv != WAIT_OBJECT_0 && rv != WAIT_TIMEOUT)\r
-            return thrd_error;\r
-    }\r
-}\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    return TEST_RESULTS;\r
-}\r
-\r
+#ifndef REGTEST
+#include <threads.h>
+#include <windows.h>
+#include <stdint.h>
+
+int mtx_timedlock(mtx_t *_PDCLIB_restrict mtx, 
+                  const struct timespec *_PDCLIB_restrict until)
+{
+    DWORD myId = GetCurrentThreadId();
+
+    if(mtx->_ThreadId == (long) myId) {
+        mtx->_NestCount++;
+        return thrd_success;
+    }
+
+
+    for(;;) {
+        LONG prev = InterlockedCompareExchange(&mtx->_ThreadId, myId, 0);
+        if(prev == 0)
+            return thrd_success;
+
+        struct timespec now;
+        int32_t msToWait = 0;
+        if(timespec_get(&now, TIME_UTC) != TIME_UTC) {
+            // timespec_get must work!
+            return thrd_error;
+        } else {
+            int64_t deltaSec  = (int64_t)until->tv_sec  - now.tv_sec;
+            long    deltaNsec = (long)until->tv_nsec - now.tv_nsec;
+
+            if(INT32_MAX / 2000U < deltaSec) {
+                // Risk of overflow - do a shorter timeout on this iteration
+                msToWait = INT32_MAX / 2;
+            } else {
+                msToWait = deltaSec * 1000 + deltaNsec / 1000;
+            }
+        }
+
+        if(msToWait < 0) {
+            return thrd_timeout;
+        }
+
+        DWORD rv = WaitForSingleObject(mtx->_WaitEvHandle, msToWait);
+        if(rv != WAIT_OBJECT_0 && rv != WAIT_TIMEOUT)
+            return thrd_error;
+    }
+}
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    return TEST_RESULTS;
+}
+
 #endif
\ No newline at end of file
index 753dd6e12a4671564d242086e738b8448d57d62f..4308fb16d9197ce0c37fbc17c93eadba8e1a5e29 100644 (file)
@@ -1,33 +1,33 @@
-#ifndef REGTEST\r
-#include <threads.h>\r
-#include <windows.h>\r
-\r
-int mtx_trylock(mtx_t *mtx)\r
-{\r
-    DWORD myId = GetCurrentThreadId();\r
-\r
-    if(mtx->_ThreadId == (long) myId) {\r
-        mtx->_NestCount++;\r
-        return thrd_success;\r
-    }\r
-\r
-    if(mtx->_ThreadId != 0)\r
-        return thrd_busy;\r
-\r
-    LONG prev = InterlockedCompareExchange(&mtx->_ThreadId, myId, 0);\r
-    if(prev == 0)\r
-        return thrd_success;\r
-    else\r
-        return thrd_busy;\r
-}\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    return TEST_RESULTS;\r
-}\r
-\r
+#ifndef REGTEST
+#include <threads.h>
+#include <windows.h>
+
+int mtx_trylock(mtx_t *mtx)
+{
+    DWORD myId = GetCurrentThreadId();
+
+    if(mtx->_ThreadId == (long) myId) {
+        mtx->_NestCount++;
+        return thrd_success;
+    }
+
+    if(mtx->_ThreadId != 0)
+        return thrd_busy;
+
+    LONG prev = InterlockedCompareExchange(&mtx->_ThreadId, myId, 0);
+    if(prev == 0)
+        return thrd_success;
+    else
+        return thrd_busy;
+}
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    return TEST_RESULTS;
+}
+
 #endif
\ No newline at end of file
index bd1e6038d3ad27c4a969468236ea7c2ecf40bbca..dcbdc78a2a7c00dc9494887476fc0858cedc3a53 100644 (file)
@@ -1,31 +1,31 @@
-#ifndef REGTEST\r
-#include <threads.h>\r
-#include <windows.h>\r
-\r
-extern void _PDCLIB_w32errno( void );\r
-int mtx_unlock(mtx_t *mtx)\r
-{\r
-    if(mtx->_NestCount) {\r
-        mtx->_NestCount--;\r
-        return thrd_success;\r
-    }\r
-\r
-    mtx->_ThreadId = 0;\r
-    DWORD rv = SetEvent(mtx->_WaitEvHandle);\r
-    if(rv == 0) {\r
-        _PDCLIB_w32errno();\r
-        return thrd_error;\r
-    }\r
-    return thrd_success;\r
-}\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-int main( void )\r
-{\r
-    return TEST_RESULTS;\r
-}\r
-\r
+#ifndef REGTEST
+#include <threads.h>
+#include <windows.h>
+
+extern void _PDCLIB_w32errno( void );
+int mtx_unlock(mtx_t *mtx)
+{
+    if(mtx->_NestCount) {
+        mtx->_NestCount--;
+        return thrd_success;
+    }
+
+    mtx->_ThreadId = 0;
+    DWORD rv = SetEvent(mtx->_WaitEvHandle);
+    if(rv == 0) {
+        _PDCLIB_w32errno();
+        return thrd_error;
+    }
+    return thrd_success;
+}
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+    return TEST_RESULTS;
+}
+
 #endif
\ No newline at end of file
index a9394aff4c7c2d95a4e7b379dd7e140c6678ac44..4d41e0309e96d3314347db0a16695dc2a1a783dc 100644 (file)
@@ -1,73 +1,73 @@
-#ifndef REGTEST\r
-#include <threads.h>\r
-#include <stdbool.h>\r
-#include <windows.h>\r
-\r
-/* Pull in TLS support */\r
-extern char _tls_used[];\r
-\r
-struct _PDCLIB_tss * _PDCLIB_tss_first = NULL;\r
-\r
-int tss_create( tss_t *key, tss_dtor_t dtor )\r
-{\r
-    *key = malloc( sizeof *key );\r
-    if( !*key ) {\r
-        return thrd_nomem;\r
-    }\r
-\r
-    (*key)->_Key = TlsAlloc();\r
-    if((*key)->_Key == TLS_OUT_OF_INDEXES) {\r
-        return thrd_error;\r
-    }\r
-    (*key)->_Destructor = dtor;\r
-    (*key)->_Next = _PDCLIB_tss_first;\r
-\r
-    // TODO: make this atomic (& validate no other TLS blocks have been \r
-    // simultaneously allocated)\r
-    _PDCLIB_tss_first = *key;\r
-\r
-    return thrd_success;\r
-}\r
-\r
-static void NTAPI runTlsDestructors( void * image, DWORD reason, PVOID pv )\r
-{\r
-    if( reason == DLL_THREAD_DETACH ) {\r
-        for(unsigned i = 0; i < TSS_DTOR_ITERATIONS; i++) {\r
-            struct _PDCLIB_tss * tss = _PDCLIB_tss_first;\r
-            bool destructorsRan = false;\r
-            while( tss ) {\r
-                void * val = TlsGetValue( tss->_Key );\r
-                if( val ) {\r
-                    TlsSetValue( tss->_Key, NULL );\r
-                    if( tss->_Destructor ) {\r
-                        tss->_Destructor( val );\r
-                        destructorsRan = true;\r
-                    }\r
-                }\r
-\r
-                tss = tss->_Next;\r
-            }\r
-            if(!destructorsRan) break;\r
-        }\r
-    }\r
-}\r
-\r
-#ifdef __GNUC__\r
-__attribute__((__section__(".CRT$XLC")))\r
-#else\r
-__declspec(allocate(".CRT$XLC")) \r
-#endif\r
-PIMAGE_TLS_CALLBACK _PDCLIB_runTlsDestructors = runTlsDestructors;\r
-\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-/* Tested in tss_get.c */\r
-int main( void )\r
-{\r
-    return TEST_RESULTS;\r
-}\r
-\r
+#ifndef REGTEST
+#include <threads.h>
+#include <stdbool.h>
+#include <windows.h>
+
+/* Pull in TLS support */
+extern char _tls_used[];
+
+struct _PDCLIB_tss * _PDCLIB_tss_first = NULL;
+
+int tss_create( tss_t *key, tss_dtor_t dtor )
+{
+    *key = malloc( sizeof *key );
+    if( !*key ) {
+        return thrd_nomem;
+    }
+
+    (*key)->_Key = TlsAlloc();
+    if((*key)->_Key == TLS_OUT_OF_INDEXES) {
+        return thrd_error;
+    }
+    (*key)->_Destructor = dtor;
+    (*key)->_Next = _PDCLIB_tss_first;
+
+    // TODO: make this atomic (& validate no other TLS blocks have been 
+    // simultaneously allocated)
+    _PDCLIB_tss_first = *key;
+
+    return thrd_success;
+}
+
+static void NTAPI runTlsDestructors( void * image, DWORD reason, PVOID pv )
+{
+    if( reason == DLL_THREAD_DETACH ) {
+        for(unsigned i = 0; i < TSS_DTOR_ITERATIONS; i++) {
+            struct _PDCLIB_tss * tss = _PDCLIB_tss_first;
+            bool destructorsRan = false;
+            while( tss ) {
+                void * val = TlsGetValue( tss->_Key );
+                if( val ) {
+                    TlsSetValue( tss->_Key, NULL );
+                    if( tss->_Destructor ) {
+                        tss->_Destructor( val );
+                        destructorsRan = true;
+                    }
+                }
+
+                tss = tss->_Next;
+            }
+            if(!destructorsRan) break;
+        }
+    }
+}
+
+#ifdef __GNUC__
+__attribute__((__section__(".CRT$XLC")))
+#else
+__declspec(allocate(".CRT$XLC")) 
+#endif
+PIMAGE_TLS_CALLBACK _PDCLIB_runTlsDestructors = runTlsDestructors;
+
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+/* Tested in tss_get.c */
+int main( void )
+{
+    return TEST_RESULTS;
+}
+
 #endif
\ No newline at end of file
index 90be920898f6c7593c0f7b15c54cdf11f13fce31..ce841d588022d59e3e8df99d43ef5d966e3d6325 100644 (file)
@@ -1,39 +1,39 @@
-#ifndef REGTEST\r
-#include <windows.h>\r
-#include <threads.h>\r
-#include <stdlib.h>\r
-\r
-extern struct _PDCLIB_tss * _PDCLIB_tss_first;\r
-void tss_delete( tss_t key )\r
-{\r
-    struct _PDCLIB_tss * prev = NULL;\r
-    struct _PDCLIB_tss * cur  = _PDCLIB_tss_first;\r
-    while(cur) {\r
-        if(cur == key) {\r
-            if(prev) {\r
-                prev->_Next = key->_Next;\r
-            } else {\r
-                _PDCLIB_tss_first = key->_Next;\r
-            }\r
-\r
-            TlsFree(key->_Key);\r
-            free(key);\r
-            return;\r
-        }\r
-    }\r
-\r
-    // Not actually a TSS key\r
-    abort();\r
-}\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-/* Tested in tss_get.c */\r
-int main( void )\r
-{\r
-    return TEST_RESULTS;\r
-}\r
-\r
+#ifndef REGTEST
+#include <windows.h>
+#include <threads.h>
+#include <stdlib.h>
+
+extern struct _PDCLIB_tss * _PDCLIB_tss_first;
+void tss_delete( tss_t key )
+{
+    struct _PDCLIB_tss * prev = NULL;
+    struct _PDCLIB_tss * cur  = _PDCLIB_tss_first;
+    while(cur) {
+        if(cur == key) {
+            if(prev) {
+                prev->_Next = key->_Next;
+            } else {
+                _PDCLIB_tss_first = key->_Next;
+            }
+
+            TlsFree(key->_Key);
+            free(key);
+            return;
+        }
+    }
+
+    // Not actually a TSS key
+    abort();
+}
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+/* Tested in tss_get.c */
+int main( void )
+{
+    return TEST_RESULTS;
+}
+
 #endif
\ No newline at end of file
index acb7c62e68b74becf0a925648fda881caa14d0ca..a5e5efbd4bf81817033a6a3b327925beeadae5b3 100644 (file)
@@ -1,33 +1,33 @@
-#ifndef REGTEST\r
-#include <threads.h>\r
-#include <windows.h>\r
-\r
-void *tss_get(tss_t key)\r
-{\r
-    return TlsGetValue(key->_Key);\r
-}\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-#ifndef REGTEST\r
-static tss_t key;\r
-static char v;\r
-#endif\r
-\r
-// Todo: make a thread and test destruction!\r
-\r
-int main( void )\r
-{\r
-#ifndef REGTEST\r
-    TESTCASE(tss_create(&key, NULL) == thrd_success);\r
-    TESTCASE(tss_get(key) == NULL);\r
-    TESTCASE(tss_set(key, &v) == thrd_success);\r
-    TESTCASE(tss_get(key) == &v);\r
-    tss_delete(key);\r
-#endif\r
-    return TEST_RESULTS;\r
-}\r
-\r
+#ifndef REGTEST
+#include <threads.h>
+#include <windows.h>
+
+void *tss_get(tss_t key)
+{
+    return TlsGetValue(key->_Key);
+}
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+#ifndef REGTEST
+static tss_t key;
+static char v;
+#endif
+
+// Todo: make a thread and test destruction!
+
+int main( void )
+{
+#ifndef REGTEST
+    TESTCASE(tss_create(&key, NULL) == thrd_success);
+    TESTCASE(tss_get(key) == NULL);
+    TESTCASE(tss_set(key, &v) == thrd_success);
+    TESTCASE(tss_get(key) == &v);
+    tss_delete(key);
+#endif
+    return TEST_RESULTS;
+}
+
 #endif
\ No newline at end of file
index 5ed15cea51ef6add8c9e78905f3a904fd198616d..f81d274ef00b62939de68ddc76815e9f534dda52 100644 (file)
@@ -1,22 +1,22 @@
-#ifndef REGTEST\r
-#include <threads.h>\r
-#include <windows.h>\r
-\r
-int tss_set(tss_t key, void *val)\r
-{\r
-    if(TlsSetValue(key->_Key, val))\r
-        return thrd_success;\r
-    return thrd_error;\r
-}\r
-#endif\r
-\r
-#ifdef TEST\r
-#include "_PDCLIB_test.h"\r
-\r
-/* Tested in tss_get.c */\r
-int main( void )\r
-{\r
-    return TEST_RESULTS;\r
-}\r
-\r
+#ifndef REGTEST
+#include <threads.h>
+#include <windows.h>
+
+int tss_set(tss_t key, void *val)
+{
+    if(TlsSetValue(key->_Key, val))
+        return thrd_success;
+    return thrd_error;
+}
+#endif
+
+#ifdef TEST
+#include "_PDCLIB_test.h"
+
+/* Tested in tss_get.c */
+int main( void )
+{
+    return TEST_RESULTS;
+}
+
 #endif
\ No newline at end of file
index 5969a7b6c9bd69d4908e2a785ae4ca8967ecd4ac..097942de45589f2c1234a4d026ef851f42fe3e39 100644 (file)
@@ -1,40 +1,40 @@
-#ifndef _PDCLIB_THREADCONFIG_H\r
-#define _PDCLIB_THREADCONFIG_H\r
-#include "_PDCLIB_aux.h"\r
-#include "_PDCLIB_int.h"\r
-\r
+#ifndef _PDCLIB_THREADCONFIG_H
+#define _PDCLIB_THREADCONFIG_H
+#include "_PDCLIB_aux.h"
+#include "_PDCLIB_int.h"
+
 #ifdef __cplusplus
 extern "C" {
-#endif\r
-#define _PDCLIB_TSS_DTOR_ITERATIONS 3\r
-#define _PDCLIB_ONCE_FLAG_INIT { -1, 0 }\r
-#define _PDCLIB_ONCE_FLAG_IS_DONE( _f ) ((_f)->_State == 0)\r
-typedef struct {\r
-    long  _State;\r
-    void *_Handle;\r
-} _PDCLIB_once_flag;\r
-\r
-void _PDCLIB_call_once(_PDCLIB_once_flag *flag, void (*func)(void));\r
-\r
-//#define _PDCLIB_THRD_HAVE_MISC\r
-//#define _PDCLIB_CND_T char\r
-#define _PDCLIB_MTX_T struct _PDCLIB_mtx \r
-\r
-struct _PDCLIB_mtx {\r
-    void                   * _WaitEvHandle;\r
-    volatile          long   _ThreadId; \r
-    volatile unsigned  int   _NestCount;\r
-};\r
-\r
-#define _PDCLIB_TSS_T struct _PDCLIB_tss *\r
-\r
-struct _PDCLIB_tss {\r
-    void    (*_Destructor)(void*);\r
-    struct _PDCLIB_tss * _Next;\r
-    unsigned int _Key;\r
-};\r
-\r
+#endif
+#define _PDCLIB_TSS_DTOR_ITERATIONS 3
+#define _PDCLIB_ONCE_FLAG_INIT { -1, 0 }
+#define _PDCLIB_ONCE_FLAG_IS_DONE( _f ) ((_f)->_State == 0)
+typedef struct {
+    long  _State;
+    void *_Handle;
+} _PDCLIB_once_flag;
+
+void _PDCLIB_call_once(_PDCLIB_once_flag *flag, void (*func)(void));
+
+//#define _PDCLIB_THRD_HAVE_MISC
+//#define _PDCLIB_CND_T char
+#define _PDCLIB_MTX_T struct _PDCLIB_mtx 
+
+struct _PDCLIB_mtx {
+    void                   * _WaitEvHandle;
+    volatile          long   _ThreadId; 
+    volatile unsigned  int   _NestCount;
+};
+
+#define _PDCLIB_TSS_T struct _PDCLIB_tss *
+
+struct _PDCLIB_tss {
+    void    (*_Destructor)(void*);
+    struct _PDCLIB_tss * _Next;
+    unsigned int _Key;
+};
+
 #ifdef __cplusplus
 }
-#endif\r
-#endif\r
+#endif
+#endif