]> pd.if.org Git - pdclib/commitdiff
* Change the style of inclusion of the internal/ headers. Modern preprocessors
authorOwen Shepherd <owen.shepherd@e43.eu>
Thu, 2 Aug 2012 20:48:01 +0000 (21:48 +0100)
committerOwen Shepherd <owen.shepherd@e43.eu>
Thu, 2 Aug 2012 20:48:01 +0000 (21:48 +0100)
  all detect the header guards and know not to include anyhow. The old style may
  have actually been counterproductive
* Make the built library be standard independent (i.e. the library build is
  independent of _PDCLIB_C_VERSION/__STDC_VERSION__/_PDCLIB_CXX_VERSION
  /__cplusplus.
* <threads.h> from C11. A bit off of the track of C99 support (which is still a
  higher priority goal), but solid implementation of many C99 functions on many
  real platforms will need proper thread support. <stdio.h> support to come.
  This is a stub implementation.
* Move malloc/free/realloc etc to opt/malloc-solar, in preparation for support
  of other memory allocators. On the cards are at least ptmalloc3 (BSD) and
  dlmalloc (public domain) as options.
* New build system (See CoreMakefile.mk). Not ready yet; but its coming. This
  doesn't change the project dependencies - you still only need GNU make.

This is a large bundle of changes - most of them are as a result of implementing
PDClib into my system, so they're mostly "changes I was doing" that have got
wrapped up together. Hopefully, now that things are together, future changesets
should be better factored.

Special thanks go to Martin "Solar" Baute for the work he has put in on this
code over many years.

55 files changed:
CoreMakefile.mk [new file with mode: 0644]
Readme.Legacy.txt [new file with mode: 0644]
Readme.txt
functions/_PDCLIB/assert.c
functions/_PDCLIB/atomax.c
functions/_PDCLIB/digits.c
functions/_PDCLIB/errno.c
functions/_PDCLIB/prepread.c
functions/_PDCLIB/stdarg.c
functions/_PDCLIB/strtox_main.c
functions/stdio/fgets.c
functions/stdio/fwrite.c
functions/stdio/gets.c
functions/string/strdup.c [new file with mode: 0644]
includes/assert.h
includes/ctype.h
includes/errno.h
includes/inttypes.h
includes/iso646.h
includes/limits.h
includes/locale.h
includes/stdarg.h
includes/stdbool.h
includes/stddef.h
includes/stdint.h
includes/stdio.h
includes/stdlib.h
includes/stdnoreturn.h [new file with mode: 0644]
includes/string.h
includes/threads.h [new file with mode: 0644]
includes/time.h [new file with mode: 0644]
internals/_PDCLIB_aux.h
internals/_PDCLIB_glue.h
internals/_PDCLIB_int.h
opt/malloc-solar/calloc.c [new file with mode: 0644]
opt/malloc-solar/free.c [new file with mode: 0644]
opt/malloc-solar/malloc.c [new file with mode: 0644]
opt/malloc-solar/realloc.c [new file with mode: 0644]
opt/nothread/_PDCLIB_threadconfig.h [new file with mode: 0644]
opt/nothread/call_once.c [new file with mode: 0644]
opt/nothread/cnd_init.c [new file with mode: 0644]
opt/nothread/cnd_signal.c [new file with mode: 0644]
opt/nothread/cnd_wait.c [new file with mode: 0644]
opt/nothread/config.mk [new file with mode: 0644]
opt/nothread/mtx_destroy.c [new file with mode: 0644]
opt/nothread/mtx_init.c [new file with mode: 0644]
opt/nothread/mtx_lock.c [new file with mode: 0644]
opt/nothread/mtx_timedlock.c [new file with mode: 0644]
opt/nothread/mtx_trylock.c [new file with mode: 0644]
opt/nothread/mtx_unlock.c [new file with mode: 0644]
opt/nothread/thrd_yield.c [new file with mode: 0644]
opt/nothread/tss_create.c [new file with mode: 0644]
opt/nothread/tss_delete.c [new file with mode: 0644]
opt/nothread/tss_get.c [new file with mode: 0644]
opt/nothread/tss_set.c [new file with mode: 0644]

diff --git a/CoreMakefile.mk b/CoreMakefile.mk
new file mode 100644 (file)
index 0000000..ac7d495
--- /dev/null
@@ -0,0 +1,35 @@
+TARGETS = pdclib\r
+\r
+ifndef PDCLIB_PLATFORM_EXT\r
+endif\r
+\r
+ifndef PDCLIB_MALLOC\r
+    $(error malloc to use unspecified. Set PDCLIB_MALLOC.)\r
+endif\r
+\r
+ifeq ($(PDCLIB_MALLOC),solar)\r
+    pdclib_SOURCEDIRS += opt/malloc-solar\r
+else\r
+ifeq ($(PDCLIB_MALLOC),ptmalloc3)\r
+    pdclib_SOURCEDIRS += opt/ptmalloc3\r
+else\r
+    $(error Bad malloc specified. Supported: solar, ptmalloc3)\r
+endif\r
+endif\r
+\r
+# No: -Wcast-align; spurious for uses of char* to do pointer arithmetic\r
+# No: -Winline; generates spirous errors on -Os builds\r
+WARNINGS := -Wall -Wextra -pedantic -Wno-unused-parameter -Wshadow -Wpointer-arith -Wwrite-strings -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls -Wnested-externs -Wno-long-long -Wuninitialized -Wstrict-prototypes\r
+\r
+pdclib_COMFLAGS += -ffreestanding $(WARNINGS)\r
+pdclib_CFLAGS   += -std=c11\r
+pdclib_SOURCEDIRS      +=      functions/_PDCLIB functions/ctype functions/inttypes  \\r
+                                               functions/locale functions/stdio functions/stdlib         \\r
+                                               functions/string/\r
+pdclib_OUT_TYPE        += archive\r
+pdclib_INCLUDE_DIRS    += $(pdclib_SOURCE_DIR)/includes $(pdclib_SOURCE_DIR)/internals\r
+\r
+ifdef PDCLIB_OPT_NOTHREAD\r
+       pdclib_SOURCEDIRS   += opt/nothread\r
+       pdclib_INCLUDE_DIRS += $(pdclib_SOURCE_DIR)/opt/nothread\r
+endif
\ No newline at end of file
diff --git a/Readme.Legacy.txt b/Readme.Legacy.txt
new file mode 100644 (file)
index 0000000..0628fc6
--- /dev/null
@@ -0,0 +1,217 @@
+$Id$
+
+PDCLib - Public Domain C Library
+================================
+
+License
+-------
+
+Permission is granted to use, modify, and / or redistribute at will.
+
+This includes removing authorship notices, re-use of code parts in
+other software (with or without giving credit), and / or creating a
+commercial product based on it.
+
+This permission is not revocable by the author.
+
+This software is provided as-is. Use it at your own risk. There is
+no warranty whatsoever, neither expressed nor implied, and by using
+this software you accept that the author(s) shall not be held liable
+for any loss of data, loss of service, or other damages, be they
+incidental or consequential. Your only option other than accepting
+this is not to use the software at all.
+
+A case for Public Domain
+------------------------
+
+There was a time when you could just post a piece of code to usenet
+and say, "I give it away for free; perhaps it's useful for you."
+
+Then came the lawyers.
+
+There are building blocks in software engineering that are so basic
+that everyone should have free access to them without having to
+employ a complete legal department for advice. They should be FREE.
+Available for free, free of licensing implications, free of attached
+propaganda, free of everything but their useful self.
+
+Today, even the term "free" has to be defined by several paragraphs
+of legal blah-blah.
+
+Sick and tired of it, the author brought you this piece of software
+under a "license" that should not be neccessary in the first place:
+"Free" should have been enough.
+
+Unfortunately, German law does not even *allow* to declare a work to
+be "in the Public Domain", so the "free for all" license I intended
+had to be made expressively.
+
+What is it
+----------
+
+This is a C Standard Library. Nothing more, nothing less. No POSIX
+or other extensions, just what's defined in ISO/IEC 9899.
+
+(Well, this is what it will be when the 1.0 release comes out. See
+the "Development Status" section to see what's implemented so far.)
+
+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;
+6) platform-specific, optimized "overlay" implementations (optional).
+
+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).
+
+Note that there *might* be some feature to remove this additional
+level of indirection for a production release, to ease the workload
+put on the preprocessor.
+
+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.
+
+Of course, your platform might provide more efficient replacements
+for the generic implementations offered by PDCLib. The math functions
+are an especially "juicy" target for optimization - while PDCLib does
+provide generic implementations for each of them, there are usually
+FPU opcodes that do the same job, only orders of magnitude faster. For
+this, you might want to create an "optimization overlay" for PDCLib.
+
+Optimization Overlay
+--------------------
+
+The basic idea of PDCLib is to provide a generic implementation that
+is useable even on platforms I have never heard of - for example, the
+OS and/or compiler *you* just wrote and now need a C library for. That
+is actually what PDCLib was written for: To provide a C library for
+compiler and OS builders that do not want the usual baggage of POSIX
+and GNU extensions, licensing considerations etc. etc.
+
+Thus, PDCLib provides generic implementations. They do work, and do
+so correctly, but they are not very efficient when compared to hand-
+crafted assembler or compiler build-ins. So I wanted to provide a
+means to modify PDCLib to run more efficiently on a given platform,
+without cluttering the main branch with tons of #ifdef statements and
+"featureset #defines" that grow stale quickly.
+
+The solution is the "optimization overlay". Every function has its
+own implementation file, which makes it possible to replace them
+piecemeal by copying a platform-specific overlay over the main PDCLib
+branch to create a PDCLib adapted / optimized for the platform in
+question. That overlay could be part of the PDCLib source tree (for
+established platforms where maintainers won't bother with PDCLib), or
+part of that platform's source tree (for under-development platforms
+PDCLib maintainers won't bother with).
+
+So, to use PDCLib on your given platform, you unpack PDCLib (as you
+obviously have done already since you are reading this), and copy
+the overlay for your platform over the PDCLib source tree structure.
+
+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           (fixed)
+- #2  stdlib.h - insufficient documentation (fixed)
+- #4  Misspelled name in credits            (fixed)
+- #5  malloc() splits off too-small nodes   (fixed)
+- #6  qsort() stack overflow                (fixed)
+- #7  malloc() bug in list handling         (fixed)
+- #8  strncmp() does not terminate at '\0'  (fixed)
+- #9  stdint.h dysfunctional                (fixed)
+- #10 NULL redefinition warnings            (fixed)
+
+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.
+
+
+A WORD ON THE v0.5 RELEASE
+==========================
+
+The v0.5 release is not well-tested. There are several things in it done
+in a way that I would never label "release quality". Some things are not
+even in the *structure* I would like them to be. An example for this is
+the current handling of errno values: It needlessly introduces dependency
+on PDCLib (because I use non-standard values), and the values are placed
+in the wrong header (_PDCLIB_int.h instead of _PDCLIB_glue.h where they
+would be more appropriate).
+
+But at some point during the development toward the v0.5 release, I found
+that my current PDCLib work schedule simply does not allow me to wait
+until every piece of <stdio.h> is as I would like it to be. It would
+probably take another year or two, and my patience is UP.
+
+I want this released, and I want to think about something else but
+<stdio.h> for some time.
+
+So, expect significant change to how stdio is done in upcoming releases.
+Everything *WILL* be stable by the time v1.0 comes around, but until then
+you will have to accept that I can only deliver "hobby quality" for now.
+
index 0628fc6a7b9ddced0f268356313cea13bed0aab9..77762e5ffedc03ef9a2a2ac8e70d3d3a1941ba4a 100644 (file)
-$Id$
-
-PDCLib - Public Domain C Library
-================================
-
-License
--------
-
-Permission is granted to use, modify, and / or redistribute at will.
-
-This includes removing authorship notices, re-use of code parts in
-other software (with or without giving credit), and / or creating a
-commercial product based on it.
-
-This permission is not revocable by the author.
-
-This software is provided as-is. Use it at your own risk. There is
-no warranty whatsoever, neither expressed nor implied, and by using
-this software you accept that the author(s) shall not be held liable
-for any loss of data, loss of service, or other damages, be they
-incidental or consequential. Your only option other than accepting
-this is not to use the software at all.
-
-A case for Public Domain
-------------------------
-
-There was a time when you could just post a piece of code to usenet
-and say, "I give it away for free; perhaps it's useful for you."
-
-Then came the lawyers.
-
-There are building blocks in software engineering that are so basic
-that everyone should have free access to them without having to
-employ a complete legal department for advice. They should be FREE.
-Available for free, free of licensing implications, free of attached
-propaganda, free of everything but their useful self.
-
-Today, even the term "free" has to be defined by several paragraphs
-of legal blah-blah.
-
-Sick and tired of it, the author brought you this piece of software
-under a "license" that should not be neccessary in the first place:
-"Free" should have been enough.
-
-Unfortunately, German law does not even *allow* to declare a work to
-be "in the Public Domain", so the "free for all" license I intended
-had to be made expressively.
-
-What is it
-----------
-
-This is a C Standard Library. Nothing more, nothing less. No POSIX
-or other extensions, just what's defined in ISO/IEC 9899.
-
-(Well, this is what it will be when the 1.0 release comes out. See
-the "Development Status" section to see what's implemented so far.)
-
-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;
-6) platform-specific, optimized "overlay" implementations (optional).
-
-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).
-
-Note that there *might* be some feature to remove this additional
-level of indirection for a production release, to ease the workload
-put on the preprocessor.
-
-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.
-
-Of course, your platform might provide more efficient replacements
-for the generic implementations offered by PDCLib. The math functions
-are an especially "juicy" target for optimization - while PDCLib does
-provide generic implementations for each of them, there are usually
-FPU opcodes that do the same job, only orders of magnitude faster. For
-this, you might want to create an "optimization overlay" for PDCLib.
-
-Optimization Overlay
---------------------
-
-The basic idea of PDCLib is to provide a generic implementation that
-is useable even on platforms I have never heard of - for example, the
-OS and/or compiler *you* just wrote and now need a C library for. That
-is actually what PDCLib was written for: To provide a C library for
-compiler and OS builders that do not want the usual baggage of POSIX
-and GNU extensions, licensing considerations etc. etc.
-
-Thus, PDCLib provides generic implementations. They do work, and do
-so correctly, but they are not very efficient when compared to hand-
-crafted assembler or compiler build-ins. So I wanted to provide a
-means to modify PDCLib to run more efficiently on a given platform,
-without cluttering the main branch with tons of #ifdef statements and
-"featureset #defines" that grow stale quickly.
-
-The solution is the "optimization overlay". Every function has its
-own implementation file, which makes it possible to replace them
-piecemeal by copying a platform-specific overlay over the main PDCLib
-branch to create a PDCLib adapted / optimized for the platform in
-question. That overlay could be part of the PDCLib source tree (for
-established platforms where maintainers won't bother with PDCLib), or
-part of that platform's source tree (for under-development platforms
-PDCLib maintainers won't bother with).
-
-So, to use PDCLib on your given platform, you unpack PDCLib (as you
-obviously have done already since you are reading this), and copy
-the overlay for your platform over the PDCLib source tree structure.
-
-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           (fixed)
-- #2  stdlib.h - insufficient documentation (fixed)
-- #4  Misspelled name in credits            (fixed)
-- #5  malloc() splits off too-small nodes   (fixed)
-- #6  qsort() stack overflow                (fixed)
-- #7  malloc() bug in list handling         (fixed)
-- #8  strncmp() does not terminate at '\0'  (fixed)
-- #9  stdint.h dysfunctional                (fixed)
-- #10 NULL redefinition warnings            (fixed)
-
-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.
-
-
-A WORD ON THE v0.5 RELEASE
-==========================
-
-The v0.5 release is not well-tested. There are several things in it done
-in a way that I would never label "release quality". Some things are not
-even in the *structure* I would like them to be. An example for this is
-the current handling of errno values: It needlessly introduces dependency
-on PDCLib (because I use non-standard values), and the values are placed
-in the wrong header (_PDCLIB_int.h instead of _PDCLIB_glue.h where they
-would be more appropriate).
-
-But at some point during the development toward the v0.5 release, I found
-that my current PDCLib work schedule simply does not allow me to wait
-until every piece of <stdio.h> is as I would like it to be. It would
-probably take another year or two, and my patience is UP.
-
-I want this released, and I want to think about something else but
-<stdio.h> for some time.
-
-So, expect significant change to how stdio is done in upcoming releases.
-Everything *WILL* be stable by the time v1.0 comes around, but until then
-you will have to accept that I can only deliver "hobby quality" for now.
-
+PDCLib - Public Domain C Library\r
+================================\r
+\r
+License\r
+-------\r
+\r
+Written in 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
+NOTE: Some configuration options may include components under non-public domain\r
+      conditions. In particular, selecting ptmalloc3 as the malloc \r
+      implementation will cause the incorporation of elements under the BSD \r
+      license.\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
+Terms for extensions\r
+--------------------\r
+Extensions are permitted where their inclusion is reasonable, they are widely\r
+used, in  keeping with the spirit of the standard, and do not convey \r
+additional requirements upon the target system, and do not needlessly duplicate\r
+functionality already contained within the standard.\r
+\r
+As an example: strdup is in, because (a) it can be implemented entirely in \r
+terms of existing standard C functions and (b) is very widely used. Something\r
+like open, write or close would not be considered, because it implies POSIXy \r
+assumptions.\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.\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
+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
+- #1  realloc( NULL, size ) fails           (fixed)\r
+- #2  stdlib.h - insufficient documentation (fixed)\r
+- #4  Misspelled name in credits            (fixed)\r
+- #5  malloc() splits off too-small nodes   (fixed)\r
+- #6  qsort() stack overflow                (fixed)\r
+- #7  malloc() bug in list handling         (fixed)\r
+- #8  strncmp() does not terminate at '\0'  (fixed)\r
+- #9  stdint.h dysfunctional                (fixed)\r
+- #10 NULL redefinition warnings            (fixed)\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
+Cleanup portions of <stdio.h>, particularly the backend. _PDCLIB_fillbuffer and\r
+_PDCLIB_flushbuffer in particular do not feel 'well' factored and need to know\r
+too much about FILE's internals. \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
+continues.
\ No newline at end of file
index fbee63404eb97417ea59fcf0cb97cb6b34c04713..8f8791274451ffb28aefab3129ce781e7629bfe3 100644 (file)
 
 #ifndef REGTEST
 
-#ifndef _PDCLIB_AUX_H
-#define _PDCLIB_AUX_H _PDCLIB_AUX_H
 #include <_PDCLIB_aux.h>
-#endif
 
-#if _PDCLIB_C_VERSION == 99
-void _PDCLIB_assert( char const * const message1, char const * const function, char const * const message2 )
+void _PDCLIB_assert99( char const * const message1, char const * const function, char const * const message2 )
 {
     fputs( message1, stderr );
     fputs( function, stderr );
     fputs( message2, stderr );
     abort();
 }
-#else
-void _PDCLIB_assert( char const * const message )
+
+void _PDCLIB_assert89( char const * const message )
 {
     fputs( message, stderr );
     abort();
 }
-#endif
 
 #endif
 
index 9a7021813bf1122f73794a8a36e75cade05850c1..45095e77256767070b35008dcc2119413b161a22 100644 (file)
@@ -6,7 +6,6 @@
    Permission is granted to use, modify, and / or redistribute at will.
 */
 
-#define _PDCLIB_INT_H _PDCLIB_INT_H
 #include <_PDCLIB_int.h>
 #include <string.h>
 #include <ctype.h>
index 940e962bd943f55e2d9469339621af72bbeba0e3..ad41e5d906bdd00a8df28aa3fec1dde30f8a4b0a 100644 (file)
@@ -6,10 +6,7 @@
    Permission is granted to use, modify, and / or redistribute at will.
 */
 
-#ifndef _PDCLIB_INT_H
-#define _PDCLIB_INT_H _PDCLIB_INT_H
 #include <_PDCLIB_int.h>
-#endif
 
 char _PDCLIB_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
 
index 5ae0ca4c2521d25e38e7af144cd20412e8e52af9..7a690800d45f92c6b492448f1b3238d77427c406 100644 (file)
@@ -6,7 +6,6 @@
    Permission is granted to use, modify, and / or redistribute at will.
 */
 
-#define _PDCLIB_INT_H _PDCLIB_INT_H
 #include <_PDCLIB_int.h>
 
 #ifndef REGTEST
index 9111ff49b9eaf0a7309d932acd216aecc2e781a3..d2288c7455d188e552c87c94410d47ca3059dd12 100644 (file)
@@ -8,7 +8,6 @@
 
 #include <stdio.h>
 
-#define _PDCLIB_GLUE_H _PDCLIB_GLUE_H
 #include <_PDCLIB_glue.h>
 
 int _PDCLIB_prepread( struct _PDCLIB_file_t * stream )
index fb3f4d636cd2f8560545d6ca725946638515b5a0..abb1f4c4f7478b8208b6074b1ca856c997ea381a 100644 (file)
@@ -9,6 +9,7 @@
 #include <stdarg.h>
 #include <limits.h>
 #include <float.h>
+#ifdef TEST
 
 #include <_PDCLIB_test.h>
 
@@ -111,3 +112,4 @@ int main( void )
     test( TAG_INTPTR, &x, TAG_LDBLPTR, &d, TAG_FUNCPTR, dummy, TAG_END );
     return TEST_RESULTS;
 }
+#endif
index b19a1e7d15d4f2b3cfba54bc3f07b6bac6353120..1556ec4bab7a9a201740ae91de8ceb20aedb422a 100644 (file)
@@ -6,7 +6,6 @@
    Permission is granted to use, modify, and / or redistribute at will.
 */
 
-#define _PDCLIB_INT_H _PDCLIB_INT_H
 #include <_PDCLIB_int.h>
 #include <ctype.h>
 #include <errno.h>
index 7d5801bb89ea2da4fd9d405135d1873a194b935d..44518a3e0b0f2552a8d5b1a47c81fb7fd3bf37f0 100644 (file)
@@ -10,7 +10,6 @@
 
 #ifndef REGTEST
 
-#define _PDCLIB_GLUE_H _PDCLIB_GLUE_H
 #include <_PDCLIB_glue.h>
 
 char * fgets( char * _PDCLIB_restrict s, int size, struct _PDCLIB_file_t * _PDCLIB_restrict stream )
index 0ea1b02e75fcef534a2ecc132984c2f1ed3a5f7e..89e9c03944f1c86a8cc11d2e0431b845d6e707d4 100644 (file)
@@ -15,6 +15,8 @@
 #include <stdbool.h>
 #include <string.h>
 
+//TODO OS(2012-08-01): Ascertain purpose of lineend & potentially remove
+
 size_t fwrite( const void * _PDCLIB_restrict ptr, size_t size, size_t nmemb, struct _PDCLIB_file_t * _PDCLIB_restrict stream )
 {
     if ( _PDCLIB_prepwrite( stream ) == EOF )
@@ -22,7 +24,7 @@ size_t fwrite( const void * _PDCLIB_restrict ptr, size_t size, size_t nmemb, str
         return 0;
     }
     _PDCLIB_size_t offset = 0;
-    bool lineend = false;
+    //bool lineend = false;
     size_t nmemb_i;
     for ( nmemb_i = 0; nmemb_i < nmemb; ++nmemb_i )
     {
@@ -32,7 +34,7 @@ size_t fwrite( const void * _PDCLIB_restrict ptr, size_t size, size_t nmemb, str
             {
                 /* Remember last newline, in case we have to do a partial line-buffered flush */
                 offset = stream->bufidx;
-                lineend = true;
+                //lineend = true;
             }
             if ( stream->bufidx == stream->bufsize )
             {
@@ -41,7 +43,7 @@ size_t fwrite( const void * _PDCLIB_restrict ptr, size_t size, size_t nmemb, str
                     /* Returning number of objects completely buffered */
                     return nmemb_i;
                 }
-                lineend = false;
+                //lineend = false;
             }
         }
     }
index ac93e972585616a0cb79215b14b005ce383494f9..9bf3a2694916d66a278a2a1e64135f1cd25a2427 100644 (file)
@@ -9,8 +9,6 @@
 #include <stdio.h>
 
 #ifndef REGTEST
-
-#define _PDCLIB_GLUE_H _PDCLIB_GLUE_H
 #include <_PDCLIB_glue.h>
 
 char * gets( char * s )
diff --git a/functions/string/strdup.c b/functions/string/strdup.c
new file mode 100644 (file)
index 0000000..ac2200e
--- /dev/null
@@ -0,0 +1,46 @@
+/* [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
+#include <string.h>\r
+#include <stdlib.h>\r
+\r
+#ifndef REGTEST\r
+\r
+#pragma weak strdup\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));\r
+    TESTCASE(testres2 = strdup(teststr2));\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
index fb6dbf1b1b63a5118cf523c3f2c6567b953b580f..7874167258675dcb713b9e2f69328db9f2e2b4ad 100644 (file)
@@ -6,44 +6,40 @@
    Permission is granted to use, modify, and / or redistribute at will.
 */
 
-#ifndef _PDCLIB_AUX_H
-#define _PDCLIB_AUX_H _PDCLIB_AUX_H
+#ifndef _PDCLIB_ASSERT_H
+#define _PDCLIB_ASSERT_H _PDCLIB_ASSERT_H
 #include <_PDCLIB_aux.h>
-#endif
-
-#ifndef _PDCLIB_CONFIG_H
-#define _PDCLIB_CONFIG_H _PDCLIB_CONFIG_H
 #include <_PDCLIB_config.h>
-#endif
+_PDCLIB_BEGIN_EXTERN_C
 
-#ifndef _PDCLIB_ASSERT_H
-#define _PDCLIB_ASSERT_H _PDCLIB_ASSERT_H
-#if _PDCLIB_C_VERSION == 99
-void _PDCLIB_assert( char const * const, char const * const, char const * const );
-#else
-void _PDCLIB_assert( char const * const );
-#endif
-#endif
+void _PDCLIB_assert99( char const * const, char const * const, char const * const );
+void _PDCLIB_assert89( char const * const );
 
 /* If NDEBUG is set, assert() is a null operation. */
 #undef assert
 
 #ifdef NDEBUG
 #define assert( ignore ) ( (void) 0 )
+#elif _PDCLIB_C_VERSION >= 99
+#define assert(expression) \
+    do { if(!(expression)) \
+        _PDCLIB_assert99("Assertion failed: " #expression \
+                         ", function ", __func__, \
+                         ", file " __FILE__ \
+                         ", line " _PDCLIB_symbol2string( __LINE__ ) \
+                         "." _PDCLIB_endl ); \
+    } while(0)
 #else
-#if _PDCLIB_C_VERSION == 99
-#define assert( expression ) ( ( expression ) ? (void) 0 \
-        : _PDCLIB_assert( "Assertion failed: " #expression \
-                          ", function ", __func__, \
+#define assert(expression) \
+    do { \
+        if(!(expression)) \
+            _PDCLIB_assert89( "Assertion failed: " #expression \
                           ", file " __FILE__ \
                           ", line " _PDCLIB_symbol2string( __LINE__ ) \
-                          "." _PDCLIB_endl ) )
-#else
-#define assert( expression ) ( ( expression ) ? (void) 0 \
-        : _PDCLIB_assert( "Assertion failed: " #expression \
-                          ", file " __FILE__ \
-                          ", line " _PDCLIB_symbol2string( __LINE__ ) \
-                          "." _PDCLIB_endl ) )
+                          "." _PDCLIB_endl ); \
+    } while(0)
 #endif
+
+_PDCLIB_END_EXTERN_C
 #endif
 
index ae951460b042dee3f8f872c2052b7654967f4753..8f979ef7bb15c2112df8ec4114c78b23e6c93d9a 100644 (file)
@@ -8,11 +8,8 @@
 
 #ifndef _PDCLIB_CTYPE_H
 #define _PDCLIB_CTYPE_H _PDCLIB_CTYPE_H
-
-#ifndef _PDCLIB_INT_H
-#define _PDCLIB_INT_H _PDCLIB_INT_H
 #include <_PDCLIB_int.h>
-#endif
+_PDCLIB_BEGIN_EXTERN_C
 
 /* Character classification functions */
 
@@ -95,4 +92,5 @@ int tolower( int c );
 */
 int toupper( int c );
 
+_PDCLIB_END_EXTERN_C
 #endif
index 90c61db1fbf9dfda207aabe1b2129f3d9729faf8..039368c8f53ec2878fbaf0d151fe164e9f7f4af5 100644 (file)
@@ -8,16 +8,14 @@
 
 #ifndef _PDCLIB_ERRNO_H
 #define _PDCLIB_ERRNO_H _PDCLIB_ERRNO_H
-
-#ifndef _PDCLIB_INT_H
-#define _PDCLIB_INT_H _PDCLIB_INT_H
 #include <_PDCLIB_int.h>
-#endif
+_PDCLIB_BEGIN_EXTERN_C
 
 #define errno (*_PDCLIB_errno_func())
 
 #define ERANGE _PDCLIB_ERANGE
 #define EDOM _PDCLIB_EDOM
 
+_PDCLIB_END_EXTERN_C
 #endif
 
index dc9af3540b99894c3bb7acfb5138f31b3a43681b..231dfab9408a87df3286500ff31fcf57ad0807af 100644 (file)
@@ -8,8 +8,8 @@
 
 #ifndef _PDCLIB_INTTYPES_H
 #define _PDCLIB_INTTYPES_H _PDCLIB_INTTYPES_H
-
 #include <stdint.h>
+_PDCLIB_BEGIN_EXTERN_C
 
 typedef struct _PDCLIB_imaxdiv_t imaxdiv_t;
 
@@ -248,5 +248,6 @@ uintmax_t strtoumax( const char * _PDCLIB_restrict nptr, char * * _PDCLIB_restri
 
 /* TODO: wcstoimax(), wcstoumax() */
 
+_PDCLIB_END_EXTERN_C
 #endif
 
index a97817ec3f92a0b1ab5f42febe0105625deb5f40..80159fcb8a8e009bccab68508b59cd34b7442095 100644 (file)
@@ -9,6 +9,7 @@
 #ifndef _PDCLIB_ISO646_H
 #define _PDCLIB_ISO646_H _PDCLIB_ISO646_H
 
+#ifndef __cplusplus
 #define and &&
 #define and_eq &=
 #define bitand &
@@ -20,6 +21,7 @@
 #define or_eq |=
 #define xor ^
 #define xor_eq ^=
+#endif
 
 #endif
 
index 5eeaf1017a8ca878565eac1a1f7cb1becb75180d..998aa390306262337005afd40bd78adbe91282e4 100644 (file)
@@ -8,11 +8,7 @@
 
 #ifndef _PDCLIB_LIMITS_H
 #define _PDCLIB_LIMITS_H _PDCLIB_LIMITS_H
-
-#ifndef _PDCLIB_INT_H
-#define _PDCLIB_INT_H _PDCLIB_INT_H
 #include <_PDCLIB_int.h>
-#endif
 
 /* TODO: Defined to 1 as multibyte characters are not supported yet. */
 #define MB_LEN_MAX 1
index 82fc21ba44da0c7438fa6ed653f4ff5ff1298f13..6d9d4829dd88cad2c61d463e7aec3dcc9e565057 100644 (file)
@@ -8,11 +8,8 @@
 
 #ifndef _PDCLIB_LOCALE_H
 #define _PDCLIB_LOCALE_H _PDCLIB_LOCALE_H
-
-#ifndef _PDCLIB_INT_H
-#define _PDCLIB_INT_H _PDCLIB_INT_H
 #include <_PDCLIB_int.h>
-#endif
+_PDCLIB_BEGIN_EXTERN_C
 
 #ifndef _PDCLIB_NULL_DEFINED
 #define _PDCLIB_NULL_DEFINED _PDCLIB_NULL_DEFINED
@@ -100,5 +97,6 @@ char * setlocale( int category, const char * locale );
 */
 struct lconv * localeconv( void );
 
+_PDCLIB_END_EXTERN_C
 #endif
 
index e75cd55c68b8a61cd4e730ed3a317747c83a58ac..202d37274a5070521b41fa153b9222e3d4b20d1a 100644 (file)
@@ -8,11 +8,9 @@
 
 #ifndef _PDCLIB_STDARG_H
 #define _PDCLIB_STDARG_H _PDCLIB_STDARG_H
-
-#ifndef _PDCLIB_CONFIG_H
-#define _PDCLIB_CONFIG_H _PDCLIB_CONFIG_H
+#include <_PDCLIB_aux.h>
 #include <_PDCLIB_config.h>
-#endif
+_PDCLIB_BEGIN_EXTERN_C
 
 typedef _PDCLIB_va_list va_list;
 
@@ -21,5 +19,6 @@ typedef _PDCLIB_va_list va_list;
 #define va_end( ap )          _PDCLIB_va_end( ap )
 #define va_start( ap, parmN ) _PDCLIB_va_start( ap, parmN )
 
+_PDCLIB_END_EXTERN_C
 #endif
 
index 66166e16deea21a6e783fe77e2615f3fe31a7612..a01cc2f600cc93345629c56db7d755134c818ad2 100644 (file)
@@ -9,9 +9,12 @@
 #ifndef _PDCLIB_STDBOOL_H
 #define _PDCLIB_STDBOOL_H _PDCLIB_STDBOOL_H
 
+#ifndef __cplusplus
 #define bool                          _Bool
 #define true                          1
 #define false                         0
+#endif
+
 #define __bool_true_false_are_defined 1
 
 #endif
index 8968577e73f7f7853f13294e86202df5b8afc575..6d8c03a9e466e846cfc4df6e665d177f8a73432f 100644 (file)
@@ -8,16 +8,9 @@
 
 #ifndef _PDCLIB_STDDEF_H
 #define _PDCLIB_STDDEF_H _PDCLIB_STDDEF_H
-
-#ifndef _PDCLIB_CONFIG_H
-#define _PDCLIB_CONFIG_H _PDCLIB_CONFIG_H
 #include <_PDCLIB_config.h>
-#endif
-
-#ifndef _PDCLIB_INT_H
-#define _PDCLIB_INT_H _PDCLIB_INT_H
 #include <_PDCLIB_int.h>
-#endif
+_PDCLIB_BEGIN_EXTERN_C
 
 typedef _PDCLIB_ptrdiff_t ptrdiff_t;
 
@@ -26,7 +19,9 @@ typedef _PDCLIB_ptrdiff_t ptrdiff_t;
 typedef _PDCLIB_size_t size_t;
 #endif
 
+#ifndef __cplusplus
 typedef _PDCLIB_wchar_t   wchar_t;
+#endif
 
 #ifndef _PDCLIB_NULL_DEFINED
 #define _PDCLIB_NULL_DEFINED _PDCLIB_NULL_DEFINED
@@ -35,5 +30,6 @@ typedef _PDCLIB_wchar_t   wchar_t;
 
 #define offsetof( type, member ) _PDCLIB_offsetof( type, member )
 
+_PDCLIB_END_EXTERN_C
 #endif
 
index a5dfc5cdc17672999e683058720010cb1e2db687..2a7683672cd5ffe3627dd9a9fef163c6f50bcdf0 100644 (file)
@@ -8,11 +8,7 @@
 
 #ifndef _PDCLIB_STDINT_H
 #define _PDCLIB_STDINT_H _PDCLIB_STDINT_H
-
-#ifndef _PDCLIB_INT_H
-#define _PDCLIB_INT_H _PDCLIB_INT_H
 #include <_PDCLIB_int.h>
-#endif
 
 /* 7.18.1.1 Exact-width integer types. */
 
index a2428a50faab6847a2085e6e7ee0417177e5332b..1d7c0bf23ecddf47979700d7dbd660005e53301e 100644 (file)
@@ -8,11 +8,8 @@
 
 #ifndef _PDCLIB_STDIO_H
 #define _PDCLIB_STDIO_H _PDCLIB_STDIO_H
-
-#ifndef _PDCLIB_INT_H
-#define _PDCLIB_INT_H _PDCLIB_INT_H
 #include <_PDCLIB_int.h>
-#endif
+_PDCLIB_BEGIN_EXTERN_C
 
 #ifndef _PDCLIB_SIZE_T_DEFINED
 #define _PDCLIB_SIZE_T_DEFINED _PDCLIB_SIZE_T_DEFINED
@@ -65,7 +62,7 @@ int remove( const char * filename );
    If there already is a file with the new filename, behaviour is defined by
    the glue code (see functions/_PDCLIB/rename.c).
 */
-int rename( const char * old, const char * new );
+int rename( const char * old, const char * newn );
 
 /* Open a temporary file with mode "wb+", i.e. binary-update. Remove the file
    automatically if it is closed or the program exits normally (by returning
@@ -796,4 +793,5 @@ int ferror( FILE * stream );
 */
 void perror( const char * s );
 
+_PDCLIB_END_EXTERN_C
 #endif
index b035c9cfbbacdc0b692eb533fd7cdbc7e7cd844e..15f07b026c2d4da7a723249f22803135e2a2f234 100644 (file)
@@ -8,11 +8,8 @@
 
 #ifndef _PDCLIB_STDLIB_H
 #define _PDCLIB_STDLIB_H _PDCLIB_STDLIB_H
-
-#ifndef _PDCLIB_INT_H
-#define _PDCLIB_INT_H _PDCLIB_INT_H
 #include <_PDCLIB_int.h>
-#endif
+_PDCLIB_BEGIN_EXTERN_C
 
 #ifndef _PDCLIB_SIZE_T_DEFINED
 #define _PDCLIB_SIZE_T_DEFINED _PDCLIB_SIZE_T_DEFINED
@@ -141,7 +138,7 @@ void * realloc( void * ptr, size_t size );
    temporary files before exiting with EXIT_FAILURE.
    abort() does not return.
 */
-void abort( void );
+_PDCLIB_noreturn void abort( void );
 
 /* Register a function that will be called on exit(), or when main() returns.
    At least 32 functions can be registered this way, and will be called in
@@ -156,7 +153,7 @@ int atexit( void (*func)( void ) );
    and EXIT_FAILURE above.)
    exit() does not return.
 */
-void exit( int status );
+_PDCLIB_noreturn void exit( int status );
 
 /* Normal process termination. Functions registered by atexit() (see above) are
    NOT CALLED. This implementation DOES flush streams, close files and removes
@@ -164,7 +161,7 @@ void exit( int status );
    comment for EXIT_SUCCESS and EXIT_FAILURE above.)
    _Exit() does not return.
 */
-void _Exit( int status );
+_PDCLIB_noreturn void _Exit( int status );
 
 /* Search an environment-provided key-value map for the given key name, and
    return a pointer to the associated value string (or NULL if key name cannot
@@ -244,4 +241,5 @@ size_t mbstowcs( wchar_t * _PDCLIB_restrict pwcs, const char * _PDCLIB_restrict
 size_t wcstombs( char * _PDCLIB_restrict s, const wchar_t * _PDCLIB_restrict pwcs, size_t n );
 */
 
+_PDCLIB_END_EXTERN_C
 #endif
diff --git a/includes/stdnoreturn.h b/includes/stdnoreturn.h
new file mode 100644 (file)
index 0000000..5997ff6
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef _PDCLIB_STDNORETURN_H\r
+#define _PDCLIB_STDNORETURN_H\r
+#include <_PDCLIB_aux.h>\r
+\r
+#ifndef __cplusplus\r
+/* This is problematic - if we don't define it, then C code can't be compiled\r
+ * on a C++ compiler. If we do define it, then we break all instances of C++\r
+ * [[noreturn]]\r
+ *\r
+ * This does not appear well thought out...\r
+ */\r
+#define noreturn _PDCLIB_noreturn\r
+#endif\r
+\r
+\r
+#endif\r
index c5f74b5e50729bf3f97bedf149ca460fcba74285..d2b22e198c60e9dc9043aad3c0b04dd42573327f 100644 (file)
@@ -8,11 +8,8 @@
 
 #ifndef _PDCLIB_STRING_H
 #define _PDCLIB_STRING_H _PDCLIB_STRING_H
-
-#ifndef _PDCLIB_INT_H
-#define _PDCLIB_INT_H _PDCLIB_INT_H
 #include <_PDCLIB_int.h>
-#endif
+_PDCLIB_BEGIN_EXTERN_C
 
 #ifndef _PDCLIB_SIZE_T_DEFINED
 #define _PDCLIB_SIZE_T_DEFINED _PDCLIB_SIZE_T_DEFINED
@@ -187,4 +184,9 @@ char * strerror( int errnum );
 */
 size_t strlen( const char * s );
 
+#ifdef _PDCLIB_POSIX_EX
+char * strdup( const char* src );
+#endif
+
+_PDCLIB_END_EXTERN_C
 #endif
diff --git a/includes/threads.h b/includes/threads.h
new file mode 100644 (file)
index 0000000..5de3d38
--- /dev/null
@@ -0,0 +1,98 @@
+#ifndef _PDCLIB_THREADS_H\r
+#define _PDCLIB_THREADS_H\r
+#include <_PDCLIB_threadconfig.h>\r
+#include <time.h>\r
+_PDCLIB_BEGIN_EXTERN_C\r
+\r
+#define thread_local _Thread_local\r
+\r
+typedef _PDCLIB_once_flag once_flag;\r
+\r
+enum {\r
+       mtx_plain               = 0,\r
+       mtx_recursive   = (1 << 0),\r
+       mtx_timed               = (1 << 1),\r
+\r
+       _PDCLIB_mtx_valid_mask = mtx_recursive | mtx_timed\r
+};\r
+\r
+enum {\r
+       thrd_success    = 0,\r
+       thrd_timeout    = 1,\r
+       thrd_busy               = 2,\r
+       thrd_error              = 3,\r
+       thrd_nomem              = 4,\r
+};\r
+\r
+#define ONCE_FLAG_INIT _PDCLIB_ONCE_FLAG_INIT\r
+#if defined(_PDCLIB_ONCE_FLAG_DONE)\r
+static inline void call_once(once_flag *flag, void (*func)(void))\r
+{\r
+       if(*flag != _PDCLIB_ONCE_FLAG_DONE) {\r
+               _PDCLIB_call_once(flag, func);\r
+       }\r
+}\r
+#else\r
+void call_once(once_flag *flag, void (*func)(void))\r
+#endif\r
+\r
+#if defined(_PDCLIB_MTX_T)\r
+typedef _PDCLIB_MTX_T          mtx_t;\r
+void mtx_destroy(mtx_t *mtx);\r
+int mtx_init(mtx_t *mtx, int type);\r
+int mtx_lock(mtx_t *mtx);\r
+int mtx_timedlock(mtx_t *_PDCLIB_restrict mtx, const struct timespec *_PDCLIB_restrict ts);\r
+int mtx_trylock(mtx_t *mtx);\r
+int mtx_unlock(mtx_t *mtx);\r
+#endif\r
+\r
+#if defined(_PDCLIB_CND_T)\r
+typedef _PDCLIB_CND_T          cnd_t;\r
+int cnd_broadcast(cnd_t *cond);\r
+void cnd_destroy(cnd_t *cond);\r
+int cnd_init(cnd_t *cond);\r
+int cnd_signal(cnd_t *cond);\r
+int cnd_timedwait(cnd_t *_PDCLIB_restrict cond,\r
+       mtx_t *_PDCLIB_restrict mtx,\r
+       const struct timespec *_PDCLIB_restrict ts);\r
+int cnd_wait(cnd_t *cond, mtx_t *mtx);\r
+#endif\r
+\r
+#if defined(_PDCLIB_THRD_T)\r
+#define _PDCLIB_THRD_HAVE_MISC\r
+typedef _PDCLIB_THRD_T         thrd_t;\r
+typedef int (*)(void*)  thrd_start_t;\r
+\r
+int thrd_create(thrd_t *thr, thrd_start_t func, void *arg);\r
+thrd_t thrd_current(void);\r
+int thrd_detach(thrd_t thr);\r
+int thrd_equal(thrd_t thr0, thrd_t thr1);\r
+_PDCLIB_noreturn void thrd_exit(int res);\r
+int thrd_join(thrd_t thr, int *res);\r
+#endif\r
+\r
+#if defined(_PDCLIB_THRD_HAVE_MISC)\r
+int thrd_sleep(const struct timespec *duration, struct timespec *remaining);\r
+void thrd_yield(void);\r
+#endif\r
+\r
+/* The behaviour of tss_t is woefully underspecified in the C11 standard. In \r
+ * particular, it never specifies where/when/<b>if</b> destructors are called.\r
+ *\r
+ * In lieu of any clarification, we assume the behaviour of POSIX pthread_key_t\r
+ */\r
+\r
+#if defined(_PDCLIB_TSS_T)\r
+#define TSS_DTOR_ITERATIONS _PDCLIB_TSS_DTOR_ITERATIONS\r
+\r
+typedef _PDCLIB_TSS_T          tss_t;\r
+typedef void (*tss_dtor_t)(void*);\r
+\r
+int tss_create(tss_t *key, tss_dtor_t dtor);\r
+void tss_delete(tss_t key);\r
+void *tss_get(tss_t key);\r
+int tss_set(tss_t key, void *val);\r
+#endif\r
+\r
+_PDCLIB_END_EXTERN_C\r
+#endif\r
diff --git a/includes/time.h b/includes/time.h
new file mode 100644 (file)
index 0000000..3fc090e
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef _PDCLIB_TIME_H\r
+#define _PDCLIB_TIME_H\r
+#include <_PDCLIB_aux.h>\r
+#include <_PDCLIB_int.h>\r
+\r
+_PDCLIB_BEGIN_EXTERN_C\r
+#ifndef _PDCLIB_SIZE_T_DEFINED\r
+#define _PDCLIB_SIZE_T_DEFINED _PDCLIB_SIZE_T_DEFINED\r
+typedef _PDCLIB_size_t size_t;\r
+#endif\r
+\r
+#ifndef _PDCLIB_NULL_DEFINED\r
+#define _PDCLIB_NULL_DEFINED _PDCLIB_NULL_DEFINED\r
+#define NULL _PDCLIB_NULL\r
+#endif\r
+\r
+typedef _PDCLIB_time_t  time_t;\r
+typedef _PDCLIB_clock_t clock_t;\r
+\r
+#ifndef _PDCLIB_STRUCT_TIMESPEC_DEFINED\r
+#define _PDCLIB_STRUCT_TIMESPEC_DEFINED\r
+_PDCLIB_DEFINE_STRUCT_TIMESPEC()\r
+#endif\r
+\r
+#ifndef _PDCLIB_STRUCT_TM_DEFINED\r
+#define _PDCLIB_STRUCT_TM_DEFINED\r
+_PDCLIB_DEFINE_STRUCT_TM()\r
+#endif\r
+\r
+_PDCLIB_END_EXTERN_C\r
+#endif\r
index 15c5db6f168febfe4ce1745e8919d0d5d604eded..d34dfb57e28aee30eb7755c9c0e97ba7d66b33ca 100644 (file)
@@ -1,4 +1,5 @@
-/* $Id$ */
+#ifndef _PDCLIB_AUX_H
+#define _PDCLIB_AUX_H
 
 /* Auxiliary PDCLib code <_PDCLIB_aux.h>
 
 #error Compiler does not define _ _STDC_ _ to 1 (not standard-compliant)!
 #endif
 
-#ifndef __STDC_VERSION__
-#define _PDCLIB_C_VERSION 90
-#define _PDCLIB_restrict
-#define _PDCLIB_inline
+#if defined(_PDCLIB_C_VERSION)
+       /* Pass - conditional simplification case */
+#elif !defined(__STDC_VERSION__)
+       #define _PDCLIB_C_VERSION 1990
 #elif __STDC_VERSION__ == 199409L
-#define _PDCLIB_C_VERSION 95
-#define _PDCLIB_restrict
-#define _PDCLIB_inline
+       #define _PDCLIB_C_VERSION 1995
 #elif __STDC_VERSION__ == 199901L
-#define _PDCLIB_C_VERSION 99
-#define _PDCLIB_restrict restrict
-#define _PDCLIB_inline inline
+       #define _PDCLIB_C_VERSION 1999
+#elif __STDC_VERSION__ == 201112L
+       #define _PDCLIB_C_VERSION 2011
 #else
-#error Unsupported _ _STDC_VERSION_ _ (__STDC_VERSION__) (supported: ISO/IEC 9899:1990, 9899/AMD1:1995, and 9899:1999).
+       #error Unsupported _ _STDC_VERSION_ _ (__STDC_VERSION__) (supported: ISO/IEC 9899:1990, 9899/AMD1:1995, 9899:1999, 9899:2011).
+#endif
+
+#if !defined(__cplusplus) || defined(_PDCLIB_CXX_VERSION)
+       /* Pass - conditional simplification case */
+#elif __cplusplus == 201103L
+       #define _PDCLIB_CXX_VERSION 2011
+       #if _PDCLIB_C_VERSION < 2011
+               #undef _PDCLIB_C_VERSION
+               #define _PDCLIB_C_VERSION 2011
+       #endif
+#elif __cplusplus == 199711L
+   #define _PDCLIB_CXX_VERSION 1997
+#else
+   #error Unsupported _ _cplusplus (__cplusplus) (supported: ISO/IEC 14882:1997, ISO/IEC 14882:2011).
+#endif
+
+#if _PDCLIB_C_VERSION >= 1999 || defined(__cplusplus)
+       #ifndef __cplusplus
+               #define _PDCLIB_restrict restrict
+       #endif
+       #define _PDCLIB_inline   inline
+#endif
+
+#if _PDCLIB_CXX_VERSION >= 2011
+       #define _PDCLIB_noreturn [[noreturn]]
+#elif _PDCLIB_C_VERSION >= 2011
+       #define _PDCLIB_noreturn _Noreturn
+#endif
+
+#ifdef __GNUC__
+       #ifndef _PDCLIB_restrict
+               #define _PDCLIB_restrict __restrict
+       #endif
+
+       #ifndef _PDCLIB_inline
+               #define _PDCLIB_inline __inline
+       #endif
+
+       #ifndef _PDCLIB_noreturn
+               #define _PDCLIB_noreturn __attribute__((noreturn))
+       #endif
+#endif
+
+#ifndef _PDCLIB_restrict
+       #define _PDCLIB_restrict
+#endif
+
+#ifndef _PDCLIB_inline
+       #define _PDCLIB_inline
+#endif
+
+#ifndef _PDCLIB_noreturn
+       #define _PDCLIB_noreturn
 #endif
 
 #ifndef __STDC_HOSTED__
 #error Compiler does not define _ _STDC_HOSTED_ _ to 0 or 1 (not standard-compliant)!
 #endif
 
-#if _PDCLIB_C_VERSION != 99
-#error PDCLib might not be fully conforming to either C89 or C95 prior to v2.x.
+#ifdef __cplusplus
+       #define _PDCLIB_BEGIN_EXTERN_C extern "C" {
+       #define _PDCLIB_END_EXTERN_C }
+#else
+   #define _PDCLIB_BEGIN_EXTERN_C
+   #define _PDCLIB_END_EXTERN_C
 #endif
 
+/*#if _PDCLIB_C_VERSION != 1999
+#error PDCLib might not be fully conforming to either C89 or C95 prior to v2.x.
+#endif*/
+
 /* -------------------------------------------------------------------------- */
 /* Helper macros:                                                             */
 /* _PDCLIB_cc( x, y ) concatenates two preprocessor tokens without extending  */
 #define _PDCLIB_symbol2value( x ) #x
 #define _PDCLIB_symbol2string( x ) _PDCLIB_symbol2value( x )
 
+#ifndef __PDCLIB_PURE
+    #define __PDCLIB_PURE 0
+#endif
+
+#ifndef _PDCLIB_POSIX_EX
+    #define _PDCLIB_POSIX_EX (!__PDCLIB_PURE)
+#endif
+#endif
\ No newline at end of file
index 3c5872bcbeab7744d215b9b765d78e9cc72ab684..f946cf5effe5c6099b5849dc63baf2228aca51aa 100644 (file)
@@ -1,3 +1,5 @@
+#ifndef _PDCLIB_GLUE_H
+#define _PDCLIB_GLUE_H
 /* $Id$ */
 
 /* OS glue functions declaration <_PDCLIB_glue.h>
@@ -6,10 +8,8 @@
    Permission is granted to use, modify, and / or redistribute at will.
 */
 
-#ifndef _PDCLIB_INT_H
-#define _PDCLIB_INT_H _PDCLIB_INT_H
 #include <_PDCLIB_int.h>
-#endif
+_PDCLIB_BEGIN_EXTERN_C
 
 /* -------------------------------------------------------------------------- */
 /* OS "glue", part 2                                                          */
@@ -73,5 +73,7 @@ int _PDCLIB_remove( const char * filename );
    must still be accessible by old name. Any handling of open files etc. is
    done by standard rename() already.
 */
-int _PDCLIB_rename( const char * old, const char * new );
+int _PDCLIB_rename( const char * old, const char * newn);
 
+_PDCLIB_END_EXTERN_C
+#endif
index a46c2dc6c7f93014a58cb85a3949e976891ce821..4477fc1ddb479333fc693001b3ae3a85937b3b26 100644 (file)
@@ -1,4 +1,5 @@
-/* $Id$ */
+#ifndef _PDCLIB_INT_H
+#define _PDCLIB_INT_H
 
 /* PDCLib internal integer logic <_PDCLIB_int.h>
 
 /* would be considered a bug / missing feature: notify the author(s).         */
 /* -------------------------------------------------------------------------- */
 
-#ifndef _PDCLIB_CONFIG_H
-#define _PDCLIB_CONFIG_H _PDCLIB_CONFIG_H
 #include <_PDCLIB_config.h>
-#endif
-
-#ifndef _PDCLIB_AUX_H
-#define _PDCLIB_AUX_H _PDCLIB_AUX_H
 #include <_PDCLIB_aux.h>
-#endif
 
 /* null pointer constant */
 #define _PDCLIB_NULL 0
@@ -254,6 +248,36 @@ typedef unsigned _PDCLIB_intmax _PDCLIB_uintmax_t;
 #define _PDCLIB_INTMAX_C( value )  _PDCLIB_concat( value, _PDCLIB_INTMAX_LITERAL )
 #define _PDCLIB_UINTMAX_C( value ) _PDCLIB_concat( value, _PDCLIB_concat( u, _PDCLIB_INTMAX_LITERAL ) )
 
+/* -------------------------------------------------------------------------- */
+/* Various <time.h> internals                                                 */
+/* -------------------------------------------------------------------------- */
+
+typedef _PDCLIB_time            _PDCLIB_time_t;
+typedef _PDCLIB_clock           _PDCLIB_clock_t;
+
+#if !defined(_PDCLIB_DEFINE_STRUCT_TIMESPEC)
+#define _PDCLIB_DEFINE_STRUCT_TIMESPEC()    \
+    struct timespec {                       \
+        time_t tv_sec;                      \
+        long tv_nsec;                       \
+    };
+#endif
+
+#if !defined(_PDCLIB_DEFINE_STRUCT_TM)
+#define _PDCLIB_DEFINE_STRUCT_TM()          \
+    struct tm {                             \
+        int tm_sec;                         \
+        int tm_min;                         \
+        int tm_hour;                        \
+        int tm_mday;                        \
+        int tm_mon;                         \
+        int tm_year;                        \
+        int tm_wday;                        \
+        int tm_yday;                        \
+        int tm_isdst;                       \
+    };
+#endif
+    
 /* -------------------------------------------------------------------------- */
 /* Various <stdio.h> internals                                                */
 /* -------------------------------------------------------------------------- */
@@ -442,3 +466,4 @@ struct _PDCLIB_ctype_t
     unsigned char collation;
 };
 
+#endif
diff --git a/opt/malloc-solar/calloc.c b/opt/malloc-solar/calloc.c
new file mode 100644 (file)
index 0000000..a2dc21f
--- /dev/null
@@ -0,0 +1,49 @@
+/* $Id$ */
+
+/* void * calloc( size_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 <stdlib.h>
+#include <string.h>
+
+#ifndef REGTEST
+
+void * calloc( size_t nmemb, size_t size )
+{
+    /* assign memory for nmemb elements of given size */
+    void * rc = malloc( nmemb * size );
+    if ( rc != NULL )
+    {
+        /* zero-initialize the memory */
+        memset( rc, 0, nmemb * size );
+    }
+    return rc;
+}
+
+#endif
+
+#ifdef TEST
+#include <_PDCLIB_test.h>
+
+int main( void )
+{
+    char * s;
+    TESTCASE( ( s = calloc( 3, 2 ) ) != NULL );
+    TESTCASE( s[0] == '\0' );
+    TESTCASE( s[5] == '\0' );
+    free( s );
+    TESTCASE( ( s = calloc( 6, 1 ) ) != NULL );
+    TESTCASE( s[0] == '\0' );
+    TESTCASE( s[5] == '\0' );
+    free( s );
+    TESTCASE( ( s = calloc( 1, 6 ) ) != NULL );
+    TESTCASE( s[0] == '\0' );
+    TESTCASE( s[5] == '\0' );
+    free( s );
+    return TEST_RESULTS;
+}
+
+#endif
diff --git a/opt/malloc-solar/free.c b/opt/malloc-solar/free.c
new file mode 100644 (file)
index 0000000..4370487
--- /dev/null
@@ -0,0 +1,55 @@
+/* $Id$ */
+
+/* void free( void * )
+
+   This file is part of the Public Domain C Library (PDCLib).
+   Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <stdlib.h>
+
+#ifndef REGTEST
+
+#ifndef _PDCLIB_INT_H
+#define _PDCLIB_INT_H _PDCLIB_INT_H
+#include <_PDCLIB_int.h>
+#endif
+
+/* TODO: Primitive placeholder. Much room for improvement. */
+
+/* structure holding first and last element of free node list */
+extern struct _PDCLIB_headnode_t _PDCLIB_memlist;
+
+void free( void * ptr )
+{
+    if ( ptr == NULL )
+    {
+        return;
+    }
+    ptr = (void *)( (char *)ptr - sizeof( struct _PDCLIB_memnode_t ) );
+    ( (struct _PDCLIB_memnode_t *)ptr )->next = NULL;
+    if ( _PDCLIB_memlist.last != NULL )
+    {
+        _PDCLIB_memlist.last->next = ptr;
+    }
+    else
+    {
+        _PDCLIB_memlist.first = ptr;
+    }
+    _PDCLIB_memlist.last = ptr;
+}
+
+#endif
+
+#ifdef TEST
+#include <_PDCLIB_test.h>
+#include <stdbool.h>
+
+int main( void )
+{
+    free( NULL );
+    TESTCASE( true );
+    return TEST_RESULTS;
+}
+
+#endif
diff --git a/opt/malloc-solar/malloc.c b/opt/malloc-solar/malloc.c
new file mode 100644 (file)
index 0000000..991bdd5
--- /dev/null
@@ -0,0 +1,425 @@
+/* $Id$ */
+
+/* void * malloc( 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 <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifndef REGTEST
+#include <_PDCLIB_glue.h>
+
+/* TODO: Primitive placeholder. Much room for improvement. */
+
+/* Keeping pointers to the first and the last element of the free list. */
+struct _PDCLIB_headnode_t _PDCLIB_memlist = { NULL, NULL };
+
+void * malloc( size_t size )
+{
+    if ( size == 0 )
+    {
+        return NULL;
+    }
+    if ( size < _PDCLIB_MINALLOC )
+    {
+        size = _PDCLIB_MINALLOC;
+    }
+    {
+    struct _PDCLIB_memnode_t * current = _PDCLIB_memlist.first;
+    struct _PDCLIB_memnode_t * previous = NULL;
+    struct _PDCLIB_memnode_t * firstfit = NULL;
+    struct _PDCLIB_memnode_t * firstfit_previous = NULL;
+    /* Trying exact fit */
+    while ( current != NULL )
+    {
+        if ( current->size == size )
+        {
+            /* Found exact fit, allocate node */
+            if ( previous != NULL )
+            {
+                /* Node in the middle of the list */
+                previous->next = current->next;
+            }
+            else
+            {
+                /* Node is first in list */
+                _PDCLIB_memlist.first = current->next;
+            }
+            if ( _PDCLIB_memlist.last == current )
+            {
+                /* Node is last in list */
+                _PDCLIB_memlist.last = previous;
+            }
+            return (char *)current + sizeof( struct _PDCLIB_memnode_t );
+        }
+        else if ( current->size > size && ( firstfit == NULL || current->size < firstfit->size ) )
+        {
+            /* Remember previous node in case we do not get an exact fit.
+               Note that this is the node *pointing to* the first fit,
+               as we need that for allocating (i.e., changing next pointer).
+            */
+            firstfit_previous = previous;
+            firstfit = current;
+        }
+        /* Skip to next node */
+        previous = current;
+        current = current->next;
+    }
+    /* No exact fit; go for first fit */
+    if ( firstfit != NULL )
+    {
+        bool node_split = false;
+        if ( ( firstfit->size - size ) > ( _PDCLIB_MINALLOC + sizeof( struct _PDCLIB_memnode_t ) ) )
+        {
+            /* Oversized - split into two nodes */
+            struct _PDCLIB_memnode_t * newnode = (struct _PDCLIB_memnode_t *)( (char *)firstfit + sizeof( struct _PDCLIB_memnode_t ) + size );
+            newnode->size = firstfit->size - size - sizeof( struct _PDCLIB_memnode_t );
+            newnode->next = firstfit->next;
+            firstfit->next = newnode;
+            firstfit->size = firstfit->size - newnode->size - sizeof( struct _PDCLIB_memnode_t );
+            node_split = true;
+        }
+        if ( firstfit_previous != NULL )
+        {
+            /* Node in the middle of the list */
+            firstfit_previous->next = firstfit->next;
+        }
+        else
+        {
+            /* Node is first in list */
+            _PDCLIB_memlist.first = firstfit->next;
+        }
+        if ( _PDCLIB_memlist.last == firstfit )
+        {
+            /* Node is last in list */
+            if ( node_split )
+            {
+                _PDCLIB_memlist.last = firstfit->next;
+            }
+            else
+            {
+                _PDCLIB_memlist.last = firstfit_previous;
+            }
+        }
+        return (char *)firstfit + sizeof( struct _PDCLIB_memnode_t );
+    }
+    }
+    {
+    /* No fit possible; how many additional pages do we need? */
+    size_t pages = ( ( size + sizeof( struct _PDCLIB_memnode_t ) - 1 ) / _PDCLIB_PAGESIZE ) + 1;
+    /* Allocate more pages */
+    struct _PDCLIB_memnode_t * newnode = (struct _PDCLIB_memnode_t *)_PDCLIB_allocpages( (int)pages );
+    if ( newnode != NULL )
+    {
+        newnode->next = NULL;
+        newnode->size = pages * _PDCLIB_PAGESIZE - sizeof( struct _PDCLIB_memnode_t );
+        if ( ( newnode->size - size ) > ( _PDCLIB_MINALLOC + sizeof( struct _PDCLIB_memnode_t ) ) )
+        {
+            /* Oversized - split into two nodes */
+            struct _PDCLIB_memnode_t * splitnode = (struct _PDCLIB_memnode_t *)( (char *)newnode + sizeof( struct _PDCLIB_memnode_t ) + size );
+            splitnode->size = newnode->size - size - sizeof( struct _PDCLIB_memnode_t );
+            newnode->size = size;
+            /* Add splitted node as last element to free node list */
+            if ( _PDCLIB_memlist.last == NULL )
+            {
+                _PDCLIB_memlist.first = splitnode;
+            }
+            else
+            {
+                _PDCLIB_memlist.last->next = splitnode;
+            }
+            splitnode->next = NULL; /* TODO: This is bug #7, uncovered by testdriver yet. */
+            _PDCLIB_memlist.last = splitnode;
+        }
+        return (char *)newnode + sizeof( struct _PDCLIB_memnode_t );
+    }
+    }
+    /* No fit, heap extension not possible - out of memory */
+    return NULL;
+}
+
+#endif
+
+
+#ifdef TEST
+#include <_PDCLIB_test.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+
+#ifndef REGTEST
+
+/* Effective page size, i.e. how many bytes can be allocated and still be on
+   one page of memory.
+*/
+#define EFFECTIVE _PDCLIB_PAGESIZE - sizeof( struct _PDCLIB_memnode_t )
+#define MEMTEST( ptr, size ) ( ( ptr = malloc( size ) ) != NULL ) && ( memset( ptr, 0, size ) == ptr )
+
+char * pages_start = 0;
+int test_nodes( char const * const, int, ... );
+void PRINT( char const * const, ... );
+
+/* This can be enabled to give a dump of node information */
+#if 0
+void PRINT( char const * const format, ... )
+{
+    va_list( ap );
+    va_start( ap, format );
+    vprintf( format, ap );
+}
+#else
+void PRINT( char const * const format, ... )
+{
+    /* EMPTY */
+}
+#endif
+
+/* Helper function checking number of allocated memory pages and the nodes
+   in the free memory list against expectations.
+*/
+int test_nodes( char const * const action, int expected_pages, ... )
+{
+    static int count = 1;
+    int result = 1;
+    PRINT( action );
+    /* Determining the amount of allocated pages */
+    int allocated_pages = ( (intptr_t)_PDCLIB_allocpages( 0 ) - (intptr_t)pages_start ) / _PDCLIB_PAGESIZE;
+    PRINT( "Test #%2d, %d allocated pages", count++, allocated_pages );
+    if ( allocated_pages != expected_pages )
+    {
+        PRINT( " - MISMATCH, expected\n          %d pages\n", expected_pages );
+        result = 0;
+    }
+    else
+    {
+        PRINT( "\n" );
+    }
+    /* Now moving through the free nodes list */
+    va_list( ap );
+    va_start( ap, expected_pages );
+    struct _PDCLIB_memnode_t * tracer = _PDCLIB_memlist.first;
+    int firstnode = 0;
+    int lastnode = 0;
+    while ( tracer != NULL )
+    {
+        /* Data from node */
+        size_t node_location = (char *)tracer - (char *)pages_start;
+        PRINT( "   - node %.4p, size %#.4x", node_location, tracer->size );
+        /* Expected data */
+        size_t expected_location = va_arg( ap, size_t );
+        if ( expected_location == 0 )
+        {
+            PRINT( " - UNEXPECTED NODE\n" );
+            result = 0;
+            continue;
+        }
+        /* Memorizing first and last expected node for later comparison. */
+        if ( firstnode == 0 )
+        {
+            firstnode = expected_location;
+        }
+        lastnode = expected_location;
+        /* Comparing expected node against current node */
+        size_t expected_size = va_arg( ap, size_t );
+        if ( ( node_location != expected_location ) || ( tracer->size != expected_size ) )
+        {
+            PRINT( " - MISMATCH, expected values\n          %.4p       %#.4p\n", expected_location, expected_size );
+            result = 0;
+        }
+        else
+        {
+            PRINT( "\n" );
+        }
+        tracer = tracer->next;
+    }
+    /* Comparing first and last node in memlist against expectations. */
+    PRINT( "   - memlist first: %#.4x - last: %#.4x",
+            ( _PDCLIB_memlist.first == NULL ) ? NULL : (char *)_PDCLIB_memlist.first - (char *)pages_start,
+            ( _PDCLIB_memlist.last == NULL ) ? NULL : (char *)_PDCLIB_memlist.last - (char *)pages_start );
+    if ( ( firstnode != 0 ) && 
+         ( ( ( (char *)_PDCLIB_memlist.first - (char *)pages_start ) != firstnode )
+         || ( ( (char *)_PDCLIB_memlist.last  - (char *)pages_start ) != lastnode ) ) )
+    {
+        PRINT( " - MISMATCH, expected values\n                    %#.4x - last: %#.4x\n", firstnode, lastnode );
+        result = 0;
+    }
+    else
+    {
+        PRINT( "\n" );
+    }
+    PRINT( "\n" );
+    return result;
+}
+
+#endif 
+
+/* Note that this test driver heavily tests *internals* of the implementation
+   above (and of free() and realloc(), too). That means that changes in the
+   implementation must be accompanied with appropriate changes of the test
+   driver. It does *not* make a good regression tester for the implementation,
+   I am afraid, and thus there is no REGTEST equivalent.
+*/
+
+int main( void )
+{
+#ifndef REGTEST
+    void * ptr1, * ptr2, * ptr3, * ptr4, * ptr5, * ptr6, * ptr7, * ptr8, * ptr9, * ptrA, * ptrB, * ptrC;
+
+    pages_start = _PDCLIB_allocpages( 0 );
+    PRINT( "\nEffective is: %#.4x\nsizeof( memnode ) is: %#.2x\n\n", EFFECTIVE, sizeof( struct _PDCLIB_memnode_t ) ); 
+
+    /* Allocating 10 bytes; expecting one page allocation and a node split */
+    TESTCASE( MEMTEST( ptr1, 10 ) );
+    TESTCASE( test_nodes( "Allocating 10 bytes.", 1,
+               sizeof( struct _PDCLIB_memnode_t ) + 10, EFFECTIVE - sizeof( struct _PDCLIB_memnode_t ) - 10,
+               0 ) );
+
+    /* Allocating the rest of the page; expecting no page allocation and assignment of the remaining node */
+    TESTCASE( MEMTEST( ptr2, EFFECTIVE - 10 - sizeof( struct _PDCLIB_memnode_t ) ) );
+    TESTCASE( test_nodes( "Allocating the rest of the page.", 1,
+               0 ) );
+
+    /* Allocating a full page; expecting one page allocation, no node split */
+    TESTCASE( MEMTEST( ptr3, EFFECTIVE ) );
+    TESTCASE( test_nodes( "Allocating a full page.", 2,
+               0 ) );
+
+    /* Allocating *almost* a full page; expecting one page allocation, no node split */
+    TESTCASE( MEMTEST( ptr4, EFFECTIVE - 4 ) );
+    TESTCASE( test_nodes( "Allocating *almost* a full page.", 3,
+               0 ) );
+
+    /* Freeing and re-allocating the "almost" full page; expecting no page allocation, no node split */
+    free( ptr4 );
+    TESTCASE( MEMTEST( ptr5, EFFECTIVE - 4 ) );
+    TESTCASE( ptr4 == ptr5 );
+    TESTCASE( test_nodes( "Freeing and re-allocating the \"almost\" full page.", 3 ) );
+
+    /* Freeing the full page from test #3; expecting a full-sized free node. */
+    free( ptr3 );
+    TESTCASE( test_nodes( "Freeing the full page from test #3.", 3,
+               _PDCLIB_PAGESIZE * 1, EFFECTIVE,
+               0 ) );
+
+    /* Allocating two full pages; expecting two page allocations, no node split */
+    TESTCASE( MEMTEST( ptr3, EFFECTIVE + _PDCLIB_PAGESIZE ) );
+    TESTCASE( test_nodes( "Allocating two full pages.", 5,
+               _PDCLIB_PAGESIZE * 1, EFFECTIVE,
+               0 ) );
+
+    /* Re-allocating to size of 10 bytes; expecting no page allocation, no node split */
+    /* TODO: Shouldn't realloc() split the now much-too-large node? */
+    TESTCASE( realloc( ptr3, 10 ) == ptr3 );
+    TESTCASE( test_nodes( "Re-allocating to size of 10 bytes.", 5,
+               _PDCLIB_PAGESIZE * 1, EFFECTIVE,
+               0 ) );
+
+    /* Re-allocating to size of two full pages; expecting no page allocation, no node split */
+    TESTCASE( realloc( ptr3, EFFECTIVE + _PDCLIB_PAGESIZE ) == ptr3 );
+    TESTCASE( test_nodes( "Re-allocating to size of two full pages.", 5,
+               _PDCLIB_PAGESIZE * 1, EFFECTIVE,
+               0 ) );
+
+    /* Re-allocating to size of three full pages; expecting three page allocation, freeing of two-page node */
+    TESTCASE( realloc( ptr3, EFFECTIVE + _PDCLIB_PAGESIZE * 2 ) != ptr3 );
+    TESTCASE( test_nodes( "Re-allocating to size of three full pages.", 8,
+               _PDCLIB_PAGESIZE * 1, EFFECTIVE,
+               _PDCLIB_PAGESIZE * 3, EFFECTIVE + _PDCLIB_PAGESIZE,
+               0 ) );
+
+    /* Allocating two full pages; expecting allocation of the available two-page node */
+    TESTCASE( MEMTEST( ptr4, EFFECTIVE + _PDCLIB_PAGESIZE ) );
+    TESTCASE( test_nodes( "Allocating two full pages.", 8,
+               _PDCLIB_PAGESIZE * 1, EFFECTIVE,
+               0 ) );
+
+    /* Allocating zero bytes; expecting no change */
+    TESTCASE( ! MEMTEST( ptr6, 0 ) );
+    TESTCASE( test_nodes( "Allocating zero bytes.", 8,
+               _PDCLIB_PAGESIZE * 1, EFFECTIVE,
+               0 ) );
+
+    /* Allocating 4 bytes; expecting upsizing of requestupsizing of size, node split */
+    TESTCASE( MEMTEST( ptr7, 4 ) );
+    TESTCASE( test_nodes( "Allocating 4 bytes.", 8,
+               _PDCLIB_PAGESIZE * 1 + _PDCLIB_MINALLOC + sizeof( struct _PDCLIB_memnode_t ),
+               EFFECTIVE - _PDCLIB_MINALLOC - sizeof( struct _PDCLIB_memnode_t ),
+               0 ) );
+
+    /* Allocating the rest of the page; expecting no page allocation and assignment of the remaining node */
+    TESTCASE( MEMTEST( ptr8, EFFECTIVE - _PDCLIB_MINALLOC - sizeof( struct _PDCLIB_memnode_t ) ) );
+    TESTCASE( test_nodes( "Allocating the rest of the page.", 8, 0 ) );
+
+    /* Freeing the node from the previous test; expecting node to re-appear in free list */
+    free( ptr8 );
+    TESTCASE( test_nodes( "Freeing the node from the previous test.", 8,
+               _PDCLIB_PAGESIZE * 1 + _PDCLIB_MINALLOC + sizeof( struct _PDCLIB_memnode_t ),
+               EFFECTIVE - _PDCLIB_MINALLOC - sizeof( struct _PDCLIB_memnode_t ),
+               0 ) );
+
+    /* Allocating one byte more than available in free node; expecting page allocation */
+    TESTCASE( MEMTEST( ptr8, EFFECTIVE + 1 - _PDCLIB_MINALLOC - sizeof( struct _PDCLIB_memnode_t ) ) );
+    TESTCASE( test_nodes( "Allocating one byte more than available in free node.", 9,
+               _PDCLIB_PAGESIZE * 1 + _PDCLIB_MINALLOC + sizeof( struct _PDCLIB_memnode_t ),
+               EFFECTIVE - _PDCLIB_MINALLOC - sizeof( struct _PDCLIB_memnode_t ),
+               0 ) );
+
+    /* Re-allocating with NULL pointer; expecting no page allocation, no node split */
+    ptr9 = realloc( NULL, EFFECTIVE - _PDCLIB_MINALLOC - sizeof( struct _PDCLIB_memnode_t ) );
+    TESTCASE( ptr9 != NULL );
+    TESTCASE( memset( ptr9, 0, EFFECTIVE - _PDCLIB_MINALLOC - sizeof( struct _PDCLIB_memnode_t ) ) == ptr9 );
+    TESTCASE( test_nodes( "Re-allocating with NULL pointer.", 9, 0 ) );
+
+    /* Allocating a bit more than half a page; expecting page allocation, node split */
+#define TESTSIZE 3000
+    TESTCASE( MEMTEST( ptrA, TESTSIZE ) );
+    TESTCASE( test_nodes( "Allocating a bit more than half a page.", 10,
+               _PDCLIB_PAGESIZE * 9 + sizeof( struct _PDCLIB_memnode_t ) + TESTSIZE,
+               EFFECTIVE - sizeof( struct _PDCLIB_memnode_t ) - TESTSIZE,
+               0 ) );
+
+    /* Allocating a bit more than half a page; expecting page allocation, node split */
+    TESTCASE( MEMTEST( ptrB, TESTSIZE ) );
+    TESTCASE( test_nodes( "Allocating a bit more than half a page.", 11,
+               _PDCLIB_PAGESIZE * 9 + sizeof( struct _PDCLIB_memnode_t ) + TESTSIZE,
+               EFFECTIVE - sizeof( struct _PDCLIB_memnode_t ) - TESTSIZE,
+               _PDCLIB_PAGESIZE * 10 + sizeof( struct _PDCLIB_memnode_t ) + TESTSIZE,
+               EFFECTIVE - sizeof( struct _PDCLIB_memnode_t ) - TESTSIZE,
+               0 ) );
+
+    /* Allocating a bit more than half a page; expecting page allocation, node split */
+    TESTCASE( MEMTEST( ptrC, TESTSIZE ) );
+    TESTCASE( test_nodes( "Allocating a bit more than half a page.", 12,
+               _PDCLIB_PAGESIZE * 9 + sizeof( struct _PDCLIB_memnode_t ) + TESTSIZE,
+               EFFECTIVE - sizeof( struct _PDCLIB_memnode_t ) - TESTSIZE,
+               _PDCLIB_PAGESIZE * 10 + sizeof( struct _PDCLIB_memnode_t ) + TESTSIZE,
+               EFFECTIVE - sizeof( struct _PDCLIB_memnode_t ) - TESTSIZE,
+               _PDCLIB_PAGESIZE * 11 + sizeof( struct _PDCLIB_memnode_t ) + TESTSIZE,
+               EFFECTIVE - sizeof( struct _PDCLIB_memnode_t ) - TESTSIZE,
+               0 ) );
+
+    /* Freeing the middle node */
+    free( ptrB );
+    TESTCASE( test_nodes( "Freeing the middle node.", 12,
+               _PDCLIB_PAGESIZE * 9 + sizeof( struct _PDCLIB_memnode_t ) + TESTSIZE,
+               EFFECTIVE - sizeof( struct _PDCLIB_memnode_t ) - TESTSIZE,
+               _PDCLIB_PAGESIZE * 10 + sizeof( struct _PDCLIB_memnode_t ) + TESTSIZE,
+               EFFECTIVE - sizeof( struct _PDCLIB_memnode_t ) - TESTSIZE,
+               _PDCLIB_PAGESIZE * 11 + sizeof( struct _PDCLIB_memnode_t ) + TESTSIZE,
+               EFFECTIVE - sizeof( struct _PDCLIB_memnode_t ) - TESTSIZE,
+               _PDCLIB_PAGESIZE * 10,
+               TESTSIZE,
+               0 ) );
+
+#else
+    puts( " NOTEST malloc() test driver is PDCLib-specific." );
+#endif
+    return TEST_RESULTS;
+}
+
+#endif
diff --git a/opt/malloc-solar/realloc.c b/opt/malloc-solar/realloc.c
new file mode 100644 (file)
index 0000000..099ad5d
--- /dev/null
@@ -0,0 +1,58 @@
+/* $Id$ */
+
+/* void * realloc( void *, 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 <stdlib.h>
+#include <string.h>
+#include <stddef.h>
+
+#ifndef REGTEST
+
+/* TODO: Primitive placeholder. Improve. */
+
+void * realloc( void * ptr, size_t size )
+{
+    void * newptr = NULL;
+    if ( ptr == NULL )
+    {
+        return malloc( size );
+    }
+    if ( size > 0 )
+    {
+        struct _PDCLIB_memnode_t * baseptr = (struct _PDCLIB_memnode_t *)( (char *)ptr - sizeof( struct _PDCLIB_memnode_t ) );
+        if ( baseptr->size >= size )
+        {
+            /* Current memnode is large enough; nothing to do. */
+            return ptr;
+        }
+        else
+        {
+            /* Get larger memnode and copy over contents. */
+            if ( ( newptr = malloc( size ) ) == NULL )
+            {
+                return NULL;
+            }
+            memcpy( newptr, ptr, baseptr->size );
+        }
+    }
+    free( ptr );
+    return newptr;
+}
+
+#endif
+
+#ifdef TEST
+#include <_PDCLIB_test.h>
+
+int main( void )
+{
+    /* tests covered in malloc test driver */
+    return TEST_RESULTS;
+}
+
+#endif
+
diff --git a/opt/nothread/_PDCLIB_threadconfig.h b/opt/nothread/_PDCLIB_threadconfig.h
new file mode 100644 (file)
index 0000000..39478e9
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef _PDCLIB_THREADCONFIG_H\r
+#define _PDCLIB_THREADCONFIG_H\r
+#include <_PDCLIB_aux.h>\r
+#include <_PDCLIB_config.h>\r
+\r
+_PDCLIB_BEGIN_EXTERN_C\r
+#define _PDCLIB_ONCE_FLAG_INIT 0\r
+#define _PDCLIB_ONCE_FLAG_DONE 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
+_PDCLIB_END_EXTERN_C\r
+#endif\r
diff --git a/opt/nothread/call_once.c b/opt/nothread/call_once.c
new file mode 100644 (file)
index 0000000..06de779
--- /dev/null
@@ -0,0 +1,9 @@
+#include <threads.h>\r
+\r
+void _PDCLIB_call_once(_PDCLIB_once_flag *flag, void (*func)(void))\r
+{\r
+       if(*flag != _PDCLIB_ONCE_FLAG_DONE) {\r
+               func();\r
+               *flag = _PDCLIB_ONCE_FLAG_DONE;\r
+       }\r
+}
\ No newline at end of file
diff --git a/opt/nothread/cnd_init.c b/opt/nothread/cnd_init.c
new file mode 100644 (file)
index 0000000..1683691
--- /dev/null
@@ -0,0 +1,7 @@
+#include <threads.h>\r
+\r
+int cnd_init(cnd_t *cond)\r
+{\r
+       /* does nothing */\r
+       return thrd_success;\r
+}\r
diff --git a/opt/nothread/cnd_signal.c b/opt/nothread/cnd_signal.c
new file mode 100644 (file)
index 0000000..ca6a789
--- /dev/null
@@ -0,0 +1,6 @@
+#include <threads.h>\r
+\r
+int cnd_signal(cnd_t *cond)\r
+{\r
+       return thrd_success;\r
+}
\ No newline at end of file
diff --git a/opt/nothread/cnd_wait.c b/opt/nothread/cnd_wait.c
new file mode 100644 (file)
index 0000000..2948d4f
--- /dev/null
@@ -0,0 +1,6 @@
+#include <threads.h>\r
+\r
+int cnd_wait(cnd_t *cond, mtx_t *mtx)\r
+{\r
+       return thrd_error;\r
+}
\ No newline at end of file
diff --git a/opt/nothread/config.mk b/opt/nothread/config.mk
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/opt/nothread/mtx_destroy.c b/opt/nothread/mtx_destroy.c
new file mode 100644 (file)
index 0000000..d9aa748
--- /dev/null
@@ -0,0 +1,4 @@
+#include <threads.h>\r
+\r
+void mtx_destroy(mtx_t *mtx)\r
+{}\r
diff --git a/opt/nothread/mtx_init.c b/opt/nothread/mtx_init.c
new file mode 100644 (file)
index 0000000..ff506e9
--- /dev/null
@@ -0,0 +1,7 @@
+#include <threads.h>\r
+\r
+int mtx_init(mtx_t *mtx, int type)\r
+{\r
+       *mtx = 0;\r
+       return thrd_success;\r
+}\r
diff --git a/opt/nothread/mtx_lock.c b/opt/nothread/mtx_lock.c
new file mode 100644 (file)
index 0000000..0a1afbd
--- /dev/null
@@ -0,0 +1,10 @@
+#include <threads.h>\r
+#include <assert.h>\r
+\r
+int mtx_lock(mtx_t *mtx)\r
+{\r
+       if(*mtx == 0) {\r
+               *mtx = 1;\r
+               return thrd_success;\r
+       } else return thrd_error;\r
+}
\ No newline at end of file
diff --git a/opt/nothread/mtx_timedlock.c b/opt/nothread/mtx_timedlock.c
new file mode 100644 (file)
index 0000000..b8166b5
--- /dev/null
@@ -0,0 +1,6 @@
+#include <threads.h>\r
+\r
+int mtx_timedlock(mtx_t *restrict mtx, const struct timespec *restrict ts)\r
+{\r
+       return mtx_lock(mtx);\r
+}
\ No newline at end of file
diff --git a/opt/nothread/mtx_trylock.c b/opt/nothread/mtx_trylock.c
new file mode 100644 (file)
index 0000000..ae32757
--- /dev/null
@@ -0,0 +1,11 @@
+#include <threads.h>\r
+\r
+int mtx_trylock(mtx_t *mtx)\r
+{\r
+       if(*mtx) {\r
+               return thrd_error;\r
+       } else {\r
+               *mtx = 1;\r
+               return thrd_success;\r
+       }\r
+}\r
diff --git a/opt/nothread/mtx_unlock.c b/opt/nothread/mtx_unlock.c
new file mode 100644 (file)
index 0000000..02244bb
--- /dev/null
@@ -0,0 +1,9 @@
+#include <threads.h>\r
+\r
+int mtx_unlock(mtx_t *mtx)\r
+{\r
+       if(*mtx) {\r
+               *mtx = 0;\r
+               return thrd_success;\r
+       } else return thrd_error;\r
+}
\ No newline at end of file
diff --git a/opt/nothread/thrd_yield.c b/opt/nothread/thrd_yield.c
new file mode 100644 (file)
index 0000000..8c7863f
--- /dev/null
@@ -0,0 +1,6 @@
+#include <threads.h>\r
+\r
+void thrd_yield(void)\r
+{\r
+       /* does nothing */\r
+}
\ No newline at end of file
diff --git a/opt/nothread/tss_create.c b/opt/nothread/tss_create.c
new file mode 100644 (file)
index 0000000..4b8ce16
--- /dev/null
@@ -0,0 +1,8 @@
+#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
+}
\ No newline at end of file
diff --git a/opt/nothread/tss_delete.c b/opt/nothread/tss_delete.c
new file mode 100644 (file)
index 0000000..fbaae7e
--- /dev/null
@@ -0,0 +1,6 @@
+#include <threads.h>\r
+\r
+void tss_delete(tss_t key)\r
+{\r
+       key.self->self = NULL;\r
+}\r
diff --git a/opt/nothread/tss_get.c b/opt/nothread/tss_get.c
new file mode 100644 (file)
index 0000000..7077ac6
--- /dev/null
@@ -0,0 +1,6 @@
+#include <threads.h>\r
+\r
+void *tss_get(tss_t key)\r
+{\r
+       return key.value;\r
+}
\ No newline at end of file
diff --git a/opt/nothread/tss_set.c b/opt/nothread/tss_set.c
new file mode 100644 (file)
index 0000000..feea85d
--- /dev/null
@@ -0,0 +1,7 @@
+#include <threads.h>\r
+\r
+int tss_set(tss_t key, void *val)\r
+{\r
+       key.self->value = val;\r
+       return thrd_success;\r
+}
\ No newline at end of file