]> pd.if.org Git - pdclib/commitdiff
* New feature check macro system. See _PDCLIB_aux.h for details
authorOwen Shepherd <owen.shepherd@e43.eu>
Sun, 12 Aug 2012 18:47:31 +0000 (19:47 +0100)
committerOwen Shepherd <owen.shepherd@e43.eu>
Sun, 12 Aug 2012 18:47:31 +0000 (19:47 +0100)
 * remove "#pragma weak" from strdup.c. It's nonportable and shouldn't be
   necessary
 * <string.h> changed to use new feature test system for strdup + strndup
 * add strndup implementation
 * <assert.h> more reliable handling of error messages

 Build system:
 * The CoreMake system is dead. It proved to be unscalable
 * The old Make based system is gone, also
 * We now use a Jam based system (requires the latest FT_Jam). Reasons:
  * Make is hard to scale in a non-recursive manner. The interactions get
    intractably complex
  * The build system depended upon GNU Make. GNU Make's license (the GPLv3) is
    about as diametrically opposed to PDCLib's CC0 as you can get without being
    closed source
  * Jam is actually more portable. In particular, it doesn't require a Unix
    emulation layer (unlike GMake)
  * The Jam system, as is, can be incorporated into the build system of a larger
    project.

Why Jam?
 * GNU make is too low level. It also incorporates too much magic: it can spend
   significant ammounts of time trying to update source files from SCCS and RCS
   files for example (a feature it is doubtful somebody has used in the last
   decade)
 * Systems like CMake are too high level: CMake is very difficult to use in a
   cross compilation environment.
 * Systems like Scons and Waf pose similar issues. Scons is also incredibly
   slow.

13 files changed:
CoreMakefile.mk [deleted file]
Jamfile [new file with mode: 0644]
Jamrules [new file with mode: 0644]
Makefile [deleted file]
functions/string/strdup.c
functions/string/strndup.c [new file with mode: 0644]
includes/assert.h
includes/string.h
internals/_PDCLIB_aux.h
platform/example/Config.jam [new file with mode: 0644]
platform/example/functions/_PDCLIB/_PDCLIB_Exit.c [moved from platform/example/functions/_PDCLIB/_Exit.c with 100% similarity]
platform/posix/Config.jam [new file with mode: 0644]
platform/posix/functions/_PDCLIB/_PDCLIB_Exit.c [moved from platform/posix/functions/_PDCLIB/_Exit.c with 100% similarity]

diff --git a/CoreMakefile.mk b/CoreMakefile.mk
deleted file mode 100644 (file)
index 39c96be..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-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),dlmalloc)\r
-    pdclib_SOURCEDIRS += opt/dlmalloc\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
-# No: -Wredundant-decls; redefinition of functions is legal and sometimes required\r
-#         (especially applicable to PDCLib sources)\r
-# -Wno-unused-parameter; unused parameters are common in some interfaces\r
-WARNINGS := -Wall -Wextra -pedantic -Wshadow -Wpointer-arith -Wwrite-strings -Wmissing-prototypes -Wmissing-declarations -Wnested-externs -Wno-long-long -Wuninitialized -Wstrict-prototypes -Wno-unused-parameter\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\r
-\r
-ifdef PDCLIB_OPT_NOTIME\r
-       pdclib_SOURCEDIRS += opt/notime\r
-endif
\ No newline at end of file
diff --git a/Jamfile b/Jamfile
new file mode 100644 (file)
index 0000000..971e21d
--- /dev/null
+++ b/Jamfile
@@ -0,0 +1,43 @@
+SubDir PDCLIB_TOP ;\r
+PDCLibConfig ;\r
+\r
+PDCLIB_SOURCES = [ RecursiveGlob $(PDCLIB_TOP) : [ FDirName functions ] : *.c ] ;\r
+\r
+if $(PDCLIB_PLATFORM) {\r
+    PDCLIB_PLATFORM_SOURCE_DIR = \r
+        [ FDirName platform $(PDCLIB_PLATFORM) functions ] ;\r
+    PDCLIB_SOURCES += [ RecursiveGlob $(PDCLIB_TOP) : $(PDCLIB_PLATFORM_SOURCE_DIR) : *.c ] ;\r
+}\r
+\r
+for opt in $(PDCLIB_OPTIONS) {\r
+    optdir = [ FDirName opt $(opt) ] ;\r
+    PDCLIB_SOURCES += [ RecursiveGlob $(PDCLIB_TOP) : $(optdir) : *.c ] ;   \r
+}\r
+\r
+Library $(PDCLIB) : $(PDCLIB_SOURCES) ;\r
+\r
+if ! $(PDCLIB_NO_TEST) {\r
+    for file in $(PDCLIB_SOURCES) {\r
+        testfile    = $(file:S=_t) ;\r
+        regtestfile = $(file:S=_r) ;\r
+        test        = $(file:S=-test) ;\r
+        regtest     = $(file:S=-regtest) ;\r
+\r
+        Object $(testfile).o    : $(file) ;\r
+        Object $(regtestfile).o : $(file) ;\r
+        MainFromObjects $(testfile)    : $(testfile).o ;\r
+        MainFromObjects $(regtestfile) : $(regtestfile).o ;\r
+        CCFLAGS on $(testfile).o += -DTEST $(PDCLIB_TEST_CCFLAGS) ;\r
+        CCFLAGS on $(regtestfile).o += -DTEST -DREGTEST \r
+                                       $(PDCLIB_REGTEST_CCFLAGS) ;\r
+\r
+        LINKFLAGS on $(testfile)$(SUFEXE) += $(PDCLIB_TEST_LINKFLAGS) ;\r
+        LINKFLAGS on $(regtestfile)$(SUFEXE) += $(PDCLIB_REGTEST_LINKFLAGS) ;\r
+        LINKLIBS on $(testfile)$(SUFEXE) += $(PDCLIB_TEST_LINKLIBS) ;\r
+        LINKLIBS on $(regtestfile)$(SUFEXE) += $(PDCLIB_REGTEST_LINKLIBS) ;\r
+        LinkLibraries $(testfile) : $(PDCLIB) ;\r
+\r
+        Test    $(test)    : $(testfile) ;\r
+        RegTest $(regtest) : $(regtestfile) ;\r
+    }\r
+}
\ No newline at end of file
diff --git a/Jamrules b/Jamrules
new file mode 100644 (file)
index 0000000..8657cc9
--- /dev/null
+++ b/Jamrules
@@ -0,0 +1,168 @@
+PDCLIB ?= pdclib ;\r
+\r
+ECHO "PDCLIB_TOP: " $(PDCLIB_TOP) ;\r
+\r
+if ! $(PDCLIB_HAVE_PLATFORM) && ! $(PDCLIB_PLATFORM) {\r
+    if $(NT) {\r
+        PDCLIB_PLATFORM = "win32" ;\r
+    } else if $(UNIX) {\r
+        PDCLIB_PLATFORM = "posix" ;\r
+    } else {\r
+        ECHO "PDCLIB_PLATFORM not set and platform not automatically detected" ;\r
+        ECHO "Set PDCLIB_PLATFORM to the platform to be built for" ;\r
+        EXIT ;\r
+    }\r
+    PDCLIB_HAVE_PLATFORM = 1 ;\r
+}\r
+\r
+#if $(CC) = "gcc" {\r
+# TODO: Better toolchain handling\r
+\r
+    # No -Wcast-align      : spurious warnings when using char* to do pointer \r
+    #                        arithmetic\r
+    # No -Winline          : when compiling with e.g. -Os causes spurious \r
+    #                        warnings that call is unlikely/code size would grow\r
+    # No -Wredundant-decls : some functions must be multiply defined\r
+    PDCLIB_WARNINGS ?= \r
+      -Wall -Wextra -pedantic -Wno-unused-parameter -Wshadow \r
+      -Wpointer-arith -Wwrite-strings -Wmissing-declarations -Wno-long-long \r
+      -Wuninitialized \r
+      ;\r
+    PDCLIB_CCWARNINGS ?= \r
+      -Wnested-externs -Wstrict-prototypes -Wmissing-prototypes ;\r
+    PDCLIB_CCFLAGS  = \r
+      -ffreestanding \r
+      -nostdinc \r
+      -std=c11 \r
+      -g \r
+      -D_PDCLIB_BUILD\r
+      $(PDCLIB_WARNINGS) ;\r
+    PDCLIB_C++FLAGS =\r
+      -ffreestanding\r
+      -nostdinc\r
+      -std=c++11\r
+      -g\r
+      -D_PDCLIB_BUILD\r
+      $(PDCLIB_WARNINGS) ;\r
+\r
+    actions Link bind NEEDLIBS\r
+    {\r
+        $(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) -Wl,--start-group $(NEEDLIBS) $(LINKLIBS) -Wl,--end-group\r
+    }\r
+#}\r
+\r
+if $(PDCLIB_PLATFORM) {\r
+    include [ FDirName $(PDCLIB_TOP) platform $(PDCLIB_PLATFORM) Config.jam ] ;\r
+}\r
+\r
+rule PDCLibHeaders {\r
+    SubDirHdrs $(PDCLIB_TOP) includes ;\r
+    SubDirHdrs $(PDCLIB_TOP) internals ;\r
+    SubDirHdrs $(PDCLIB_TOP) testing ;\r
+    for opt in $(PDCLIB_OPTIONS) {\r
+        SubDirHdrs $(PDCLIB_TOP) opt $(opt) ;\r
+    }\r
+    PDCLibTargetHeaders ;\r
+}\r
+\r
+rule PDCLibConfig {\r
+    SubDirCcFlags $(PDCLIB_CCFLAGS) ;\r
+    SubDirC++Flags $(PDCLIB_C++FLAGS) ;\r
+    PDCLibHeaders ;\r
+    PDCLibTargetConfig ;\r
+}\r
+\r
+# MinGW needs appropriate prodding to cretae executables\r
+if $(TOOLSET) = MINGW {\r
+    PDCLIB_TEST_LINKFLAGS    += -mconsole ;\r
+    PDCLIB_REGTEST_LINKFLAGS += -mconsole ;\r
+}\r
+\r
+# Tests\r
+ALWAYS regtest test ;\r
+\r
+rule Test {\r
+    DEPENDS $(<) : $(>) ;\r
+    ALWAYS $(<) ;\r
+    DEPENDS test : $(<) ;\r
+}\r
+\r
+rule RegTest {\r
+    DEPENDS $(<) : $(>) ;\r
+    ALWAYS $(<) ;\r
+    DEPENDS regtest : $(<) ;\r
+}\r
+\r
+actions Test {\r
+    $(>)\r
+}\r
+\r
+actions RegTest {\r
+    $(>)\r
+}\r
+\r
+# list all files in a directory, except ., ..\r
+# [ ListDir base : dirname ]\r
+rule ListDir {\r
+  # start with empty list\r
+  local _result =  ;\r
+\r
+  # for each file in the directory\r
+  local _dirlist = [ GLOB [ FDirName $(1) $(2) ] : * ] ;\r
+  for _subdir in $(_dirlist) {\r
+\r
+    # if it is not . or ..\r
+    switch $(_subdir) {\r
+    case *\\. :  _dummy = "" ; # is there some no-op statement?\r
+    case *\\.. : _dummy = "" ; # is there some no-op statement?\r
+    case * :\r
+      # add it to the list\r
+      _result += $(_subdir:D=$(2)) ;\r
+    }\r
+  }\r
+\r
+  # return resulting list\r
+  return $(_result) ;\r
+}\r
+\r
+# same as glob, but recurses into subdirs\r
+rule RecursiveGlob {\r
+  # initially use the files in the current directory\r
+  local _dir  = $(2) ;\r
+  local _path = [ FDirName $(1) $(2) ] ;\r
+  local _result = [ GLOB $(_path) : $(3) ] ;\r
+  _result = $(_result:D=$(_dir)) ;\r
+\r
+  # list all subdirectories (and files, but it doesn't hurt)\r
+  local _subdirlist = [ ListDir $(1) : $(2) ] ;\r
+\r
+  # for each subdir/file\r
+  for _subdir in $(_subdirlist) {\r
+    # recurse into it\r
+    _result += [ RecursiveGlob $(1) : $(_subdir) : $(3) ] ;\r
+  }\r
+\r
+  # return the resulting list\r
+  return $(_result) ;\r
+}\r
+\r
+# Fix to work on targets in subdirs\r
+rule MakeLocate\r
+{\r
+    # Note we grist the directory name with 'dir',\r
+    # so that directory path components and other\r
+    # targets don't conflict.\r
+\r
+    if $(>)\r
+    {\r
+        local _rev = [ FReverse $(>) ] ;\r
+        if $(_rev[1]) = "." {\r
+          _rev = $(_rev[2-]) ;\r
+        } \r
+        local _dir = [ FDirName [ FReverse $(_rev) ] $(<[0]:D) ] ;\r
+\r
+        LOCATE on $(<) = [ FDirName $(>) ] ;\r
+        Depends $(<) : $(_dir:G=dir) ;\r
+        MkDir $(_dir:G=dir) ;\r
+    }\r
+}
\ No newline at end of file
diff --git a/Makefile b/Makefile
deleted file mode 100644 (file)
index fa2976a..0000000
--- a/Makefile
+++ /dev/null
@@ -1,131 +0,0 @@
-# $Id$
-
-# This is where you chose which platform to compile for (see 'make links' / './platform')
-PLATFORM := example
-
-# This is a list of all non-source files that are part of the distribution.
-AUXFILES := Makefile Readme.txt
-
-# Directories belonging to the project
-PROJDIRS := functions includes internals
-# All source files of the project
-SRCFILES := $(shell find -L $(PROJDIRS) -type f -name "*.c")
-# All header files of the project
-HDRFILES := $(shell find -L $(PROJDIRS) -type f -name "*.h")
-# All .c files in functions/_PDCLIB that do not have a regression test driver
-INTFILES := _Exit atomax digits open print scan remove rename seed stdinit strtox_main strtox_prelim filemode eol errno seek prepread prepwrite allocpages tmpfilename closeall
-# All object files in the library
-OBJFILES := $(patsubst %.c,%.o,$(SRCFILES))
-# All test drivers (.t)
-TSTFILES := $(patsubst %.c,%_t,$(SRCFILES))
-# All regression test drivers (.r)
-REGFILES := $(filter-out $(patsubst %,functions/_PDCLIB/%_r,$(INTFILES)),$(patsubst %.c,%_r,$(SRCFILES)))
-# All library dependency files (.d)
-DEPFILES := $(patsubst %.c,%.d,$(SRCFILES))
-# All test driver dependency files (_t.d)
-TSTDEPFILES := $(patsubst %,%.d,$(TSTFILES))
-# All regression test driver dependency files (_r.d)
-REGDEPFILES := $(patsubst %,%.d,$(REGFILES))
-# All files belonging to the source distribution
-ALLFILES := $(SRCFILES) $(HDRFILES) $(AUXFILES)
-
-WARNINGS := -Wall -Wextra -pedantic -Wno-unused-parameter -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls -Wnested-externs -Winline -Wno-long-long -Wuninitialized -Wstrict-prototypes 
-CFLAGS := -fno-builtin -g -std=c99 -I./internals -I./testing $(WARNINGS) $(USERFLAGS)
-
-.PHONY: all clean srcdist bindist test tests testdrivers regtests regtestdrivers todos fixmes find links unlink help
-
-all: pdclib.a testdrivers regtestdrivers
-       @echo
-       @echo "========================"
-       @echo "Executing library tests:"
-       @echo "========================"
-       @echo
-       @$(MAKE) tests | grep -v "^ TST" | grep -v "^Failed"
-       @echo
-       @echo "==========================="
-       @echo "Executing regression tests:"
-       @echo "==========================="
-       @echo
-       @$(MAKE) regtests | grep -v "^ RTST" | grep -v "^Failed"
-
-pdclib.a: $(OBJFILES)
-       @echo " AR      $@"
-       @ar rc pdclib.a $?
-       @echo
-
-test: functions/$(FILE)
-       functions/$(FILE)
-
-tests: testdrivers
-       -@rc=0; count=0; failed=""; for file in $(TSTFILES); do echo " TST      $$file"; ./$$file; test=$$?; if [ $$test != 0 ]; then rc=`expr $$rc + $$test`; failed="$$failed $$file"; fi; count=`expr $$count + 1`; done; echo; echo "Tests executed (linking PDCLib): $$count  Tests failed: $$rc"; echo; for file in $$failed; do echo "Failed: $$file"; done; echo
-
-testdrivers: $(TSTFILES)
-       @echo
-
-regtests: regtestdrivers
-       -@rc=0; count=0; failed=""; for file in $(REGFILES); do echo " RTST     $$file"; ./$$file; test=$$?; if [ $$test != 0 ]; then rc=`expr $$rc + $$test`; failed="$$failed $$file"; fi; count=`expr $$count + 1`; done; echo; echo "Tests executed (linking system libc): $$count  Tests failed: $$rc"; echo; for file in $$failed; do echo "Failed: $$file"; done; echo
-
-regtestdrivers: $(REGFILES)
-       @echo
-
--include $(DEPFILES) $(TSTDEPFILES) $(REGDEPFILES)
-
-clean:
-       -@$(RM) $(wildcard $(OBJFILES) $(DEPFILES) $(TSTFILES) $(TSTDEPFILES) $(REGFILES) $(REGDEPFILES) pdclib.a pdclib.tgz scanf_testdata_*)
-
-srcdist:
-       @tar czf pdclib.tgz $(ALLFILES)
-
-todos:
-       -@for file in $(ALLFILES:Makefile=); do grep -H TODO $$file; done; true
-
-fixmes:
-       -@for file in $(ALLFILES:Makefile=); do grep -H FIXME $$file; done; true
-
-find:
-       @find functions/ includes/ internals/ platform/ -name "*\.[ch]" -type f | xargs grep $$FIND
-
-links:
-       @echo "Linking platform/$(PLATFORM)..."
-       @for file in $$(find platform/$(PLATFORM) -mindepth 2 -type f ! -path *.svn* -printf "%P\n"); do ln -s $$(dirname $$file | sed "s@[^/]*@..@g")/platform/$(PLATFORM)/$$file $$file; done
-
-unlink:
-       @echo "Unlinking platform files..."
-       @for dir in $(PROJDIRS); do find $$dir -type l -exec rm {} +; done
-
-help:
-       @echo "Available make targets:"
-       @echo
-       @echo "all              - build pdclib.a"
-       @echo "clean            - remove all object files, dependency files and test drivers"
-       @echo "srcdist          - build pdclib.tgz (source tarball)"
-       @echo "test             - test a single testdriver (Usage: FILE=\"test.[rt]\" make test)"
-       @echo "tests            - build and run test drivers (link pdclib.a)"
-       @echo "  testdrivers    - build but do not run test drivers"
-       @echo "regtests         - build and run regression test drivers (link system clib)"
-       @echo "  regtestdrivers - build but do not run regression test drivers"
-       @echo "todos            - list all TODO comments in the sources"
-       @echo "fixmes           - list all FIXME comments in the sources"
-       @echo "find             - find a phrase in the sources (Usage: FIND=\"phrase\" make find)"
-       @echo "links            - link platform files (development only)"
-       @echo "unlink           - remove links to platform files (development only)"
-       @echo "%.o              - build an individual object file"
-       @echo "%.t              - build an individual test driver"
-       @echo "%.r              - build an individual regression test driver"
-       @echo "help             - print this list"
-       @echo
-       @echo "Any additional compiler flags you want to use can be passed as USERFLAGS"
-       @echo "(Usage: USERFLAGS=\"flags\" make [...])."
-
-%.o: %.c Makefile
-       @echo " CC      $(patsubst functions/%,%,$@)"
-       @$(CC) $(CFLAGS) -MMD -MP -I./includes -c $< -o $@
-
-%_t: %.c Makefile pdclib.a
-       @echo " CC      $(patsubst functions/%,%,$@)"
-       @$(CC) $(CFLAGS) -MMD -MP -DTEST -I./includes $< pdclib.a -o $@
-
-%_r: %.c Makefile
-       @echo " CC      $(patsubst functions/%,%,$@)"
-       @$(CC) $(CFLAGS) -MMD -MP -DTEST -DREGTEST $< -o $@
-
index ac2200e599080243ef9e33d51bb8328e274999d1..6ed0f832feef21b29ec9871c622c6661c75a7b4b 100644 (file)
@@ -9,7 +9,6 @@
 \r
 #ifndef REGTEST\r
 \r
-#pragma weak strdup\r
 char *strdup(const char *s)\r
 {\r
     char* ns = NULL;\r
diff --git a/functions/string/strndup.c b/functions/string/strndup.c
new file mode 100644 (file)
index 0000000..e25c7ed
--- /dev/null
@@ -0,0 +1,56 @@
+/* [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
+#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
+    const char *teststr  = "Hello, world";\r
+    const char *teststr2 = "\xFE\x8C\n";\r
+    char *testres, *testres2;\r
+\r
+    TESTCASE(testres  = strndup(teststr, 5));\r
+    TESTCASE(testres2 = strndup(teststr2, 1));\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));\r
+    TESTCASE(testres2 = strndup(teststr2, 5));\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 7874167258675dcb713b9e2f69328db9f2e2b4ad..ca0022d9d03401e489f480c96c6d887e158c6d81 100644 (file)
@@ -12,6 +12,7 @@
 #include <_PDCLIB_config.h>
 _PDCLIB_BEGIN_EXTERN_C
 
+/* Functions _NOT_ tagged noreturn as this hampers debugging */
 void _PDCLIB_assert99( char const * const, char const * const, char const * const );
 void _PDCLIB_assert89( char const * const );
 
@@ -20,23 +21,24 @@ void _PDCLIB_assert89( char const * const );
 
 #ifdef NDEBUG
 #define assert( ignore ) ( (void) 0 )
-#elif _PDCLIB_C_VERSION >= 99
+#elif _PDCLIB_C_MIN(99)
 #define assert(expression) \
-    do { if(!(expression)) \
-        _PDCLIB_assert99("Assertion failed: " #expression \
+    do { if(!(expression)) \
+        _PDCLIB_assert99("Assertion failed: " _PDCLIB_symbol2string(expression)\
                          ", function ", __func__, \
                          ", file " __FILE__ \
                          ", line " _PDCLIB_symbol2string( __LINE__ ) \
                          "." _PDCLIB_endl ); \
+      } \
     } while(0)
 #else
 #define assert(expression) \
-    do { \
-        if(!(expression)) \
-            _PDCLIB_assert89( "Assertion failed: " #expression \
-                          ", file " __FILE__ \
-                          ", line " _PDCLIB_symbol2string( __LINE__ ) \
-                          "." _PDCLIB_endl ); \
+    do { if(!(expression)) { \
+        _PDCLIB_assert89("Assertion failed: " _PDCLIB_symbol2string(expression)\
+                         ", file " __FILE__ \
+                         ", line " _PDCLIB_symbol2string( __LINE__ ) \
+                         "." _PDCLIB_endl ); \
+      } \
     } while(0)
 #endif
 
index d2b22e198c60e9dc9043aad3c0b04dd42573327f..00309f520910d0a0601fe79181d109164d1eae3f 100644 (file)
@@ -184,8 +184,9 @@ char * strerror( int errnum );
 */
 size_t strlen( const char * s );
 
-#ifdef _PDCLIB_POSIX_EX
+#if _PDCLIB_POSIX_MIN(2008098L) || _PDCLIB_XOPEN_MIN(0)
 char * strdup( const char* src );
+char * strndup( const char* src, size_t n );
 #endif
 
 _PDCLIB_END_EXTERN_C
index 8ea40f4254ced580769d959e866a307b1f0c8dab..8990ed8da1faa443c1e9a7b10821db1fdc52724b 100644 (file)
 #endif
 
 #if !defined(__cplusplus) || defined(_PDCLIB_CXX_VERSION)
-       /* Pass - conditional simplification case */
+   #define _PDCLIB_CXX_VERSION 0
 #elif __cplusplus == 201103L
        #define _PDCLIB_CXX_VERSION 2011
+    /* TODO: Do we want this? */
        #if _PDCLIB_C_VERSION < 2011
                #undef _PDCLIB_C_VERSION
                #define _PDCLIB_C_VERSION 2011
@@ -58,7 +59,8 @@
 #endif
 
 #if _PDCLIB_CXX_VERSION >= 2011
-       #define _PDCLIB_noreturn [[noreturn]]
+  // Hold off on C++ attribute syntax for now
+  // #define _PDCLIB_noreturn [[noreturn]]
 #elif _PDCLIB_C_VERSION >= 2011
        #define _PDCLIB_noreturn _Noreturn
 #endif
@@ -90,7 +92,8 @@
        #endif
 
        #ifndef _PDCLIB_noreturn
-               #define _PDCLIB_noreturn __attribute__((noreturn))
+    /* If you don't use __noreturn__, then stdnoreturn.h will break things! */
+               #define _PDCLIB_noreturn __attribute__((__noreturn__))
        #endif
 #endif
 
                #define _PDCLIB_API _PDCLIB_IMPORT
        #endif
 #else
-       #define _PDCLIB_API _PDCLIB_HIDDEN
+       #define _PDCLIB_API
 #endif
 
 #ifndef _PDCLIB_restrict
 #define _PDCLIB_symbol2value( x ) #x
 #define _PDCLIB_symbol2string( x ) _PDCLIB_symbol2value( x )
 
-#ifndef __PDCLIB_PURE
-    #define __PDCLIB_PURE 0
+/* Feature test macros
+ *
+ * All of the feature test macros come in the following forms
+ *   _PDCLIB_*_MIN(min):            Available in versions > min
+ *   _PDCLIB_*_MINMAX(min, max):    Available in versions > min < max
+ *   _PDCLIB_*_MAX(max):            Availabel in versions < max
+ *
+ * The defined tests are:
+ *   C:     C standard versions 
+ *              1990, 1995, 1999, 2011
+ *   CXX:   C++ standard versions 
+ *              1997, 2011
+ *   POSIX: POSIX extension versions.
+ *              1 (POSIX.2), 2 (POSIX.2), 199309L (POSIX.1b), 
+ *              199506L (POSIX.1c), 200112L (2001), 200809L (2008)
+ *   XOPEN: X/Open System Interface (XSI)/Single Unix Specification
+ *              0 (XPG4), 500 (SUSv2/UNIX98), 600 (SUSv3/UNIX03), 700 (SUSv4)
+ *
+ * PDCLib does not attempt or claim POSIX comformance, but makes available these
+ * extensions as
+ *   (a) useful, and
+ *   (b) 
+ */
+#define _PDCLIB_C_MIN(min)         _PDCLIB_C_MINMAX(min, 3000)
+#define _PDCLIB_CXX_MIN(min)     _PDCLIB_CXX_MINMAX(min, 3000)
+#define _PDCLIB_XOPEN_MIN(min) _PDCLIB_XOPEN_MINMAX(min, 30000000)
+#define _PDCLIB_POSIX_MIN(min) _PDCLIB_POSIX_MINMAX(min, 30000000)
+#define _PDCLIB_C_MAX(max)         _PDCLIB_C_MINMAX(0, max)
+#define _PDCLIB_CXX_MAX(max)     _PDCLIB_CXX_MINMAX(0, max)
+#define _PDCLIB_XOPEN_MAX(max) _PDCLIB_XOPEN_MINMAX(0, max)
+#define _PDCLIB_POSIX_MAX(max) _PDCLIB_POSIX_MINMAX(0, max)
+#if defined(_PDCLIB_ALL) || defined(_PDCLIB_BUILD)
+    #define _PDCLIB_C_MINMAX(min, max) 1
+    #define _PDCLIB_CXX_MINMAX(min, max) 1
+    #define _PDCLIB_POSIX_MINMAX(min, max) 1
+    #define _PDCLIB_XOPEN_MINMAX(min, max) 1
+#else
+    #define _PDCLIB_C_MINMAX(min, max) \
+        (_PDCLIB_C_VERSION >= (min) && _PDCLIB_C_VERSION <= (max))
+    #define _PDCLIB_CXX_MINMAX(min, max) \
+        (_PDCLIB_CXX_VERSION >= (min) && _PDCLIB_CXX_VERSION <= (max))
+    #define _PDCLIB_XOPEN_MINMAX(min, max) \
+        (defined(_XOPEN_SOURCE) \
+            && _XOPEN_SOURCE >= (min) && _XOPEN_SOURCE <= (max))
+    #define _PDCLIB_POSIX_MINMAX(min, max) \
+        (defined(_POSIX_C_SOURCE) \
+            && _POSIX_C_SOURCE >= (min) && _POSIX_C_SOURCE <= (max))
+
+    #if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE-1 == -1)
+        /* If _XOPEN_SOURCE is defined as empty, redefine here as zero */
+        #undef _XOPEN_SOURCE
+        #define _XOPEN_SOURCE 0
+    #endif
+
+    #if _PDCLIB_XOPEN_MIN(700) && !_PDCLIB_POSIX_MIN(200809L)
+        #undef _POSIX_C_SOURCE
+        #define _POSIX_C_SOURCE 2008098L    
+    #elif _PDCLIB_XOPEN_MIN(600) && !_PDCLIB_POSIX_MIN(200112L)
+        #undef _POSIX_C_SOURCE
+        #define _POSIX_C_SOURCE 200112L
+    #elif _PDCLIB_XOPEN_MIN(0) && !_PDCLIB_POSIX_MIN(2)
+        #undef _POSIX_C_SOURCE
+        #define _POSIX_C_SOURCE 2
+    #endif
+
+    #if defined(_POSIX_SOURCE) && !defined(_POSIX_C_SOURCE)
+        #define _POSIX_C_SOURCE 1
+    #endif
 #endif
 
-#ifndef _PDCLIB_POSIX_EX
-    #define _PDCLIB_POSIX_EX (!__PDCLIB_PURE)
-#endif
 #endif
\ No newline at end of file
diff --git a/platform/example/Config.jam b/platform/example/Config.jam
new file mode 100644 (file)
index 0000000..7871eb8
--- /dev/null
@@ -0,0 +1,10 @@
+rule PDCLibTargetConfig { }\r
+rule PDCLibTargetHeaders {\r
+    SubDirHdrs $(PDCLIB_TOP) platform example includes ;\r
+    SubDirHdrs $(PDCLIB_TOP) platform example internals ;\r
+}\r
+\r
+PDCLIB_TEST_LINKFLAGS += -nostdlib ;\r
+PDCLIB_TEST_LINKLIBS += -lgcc ;\r
+\r
+PDCLIB_OPTIONS = nothread notime dlmalloc ;
\ No newline at end of file
diff --git a/platform/posix/Config.jam b/platform/posix/Config.jam
new file mode 100644 (file)
index 0000000..92728f9
--- /dev/null
@@ -0,0 +1,10 @@
+rule PDCLibTargetConfig { }\r
+rule PDCLibTargetHeaders {\r
+    SubDirHdrs $(PDCLIB_TOP) platform posix includes ;\r
+    SubDirHdrs $(PDCLIB_TOP) platform posix internals ;\r
+}\r
+\r
+PDCLIB_TEST_LINKFLAGS += -nostdlib ;\r
+PDCLIB_TEST_LINKLIBS += -lgcc ;\r
+\r
+PDCLIB_OPTIONS = nothread notime dlmalloc ;
\ No newline at end of file