From 8aa07234afff05f5491cd00ce239cea2349f9b9c Mon Sep 17 00:00:00 2001 From: GuBerAtHome Date: Mon, 30 Dec 2024 21:06:13 +0100 Subject: [PATCH 01/17] bugfix: removed warnings in WriteCellBigEndian() for 32bit builds --- csrc/pf_save.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/csrc/pf_save.c b/csrc/pf_save.c index 73c44e6..baa539d 100644 --- a/csrc/pf_save.c +++ b/csrc/pf_save.c @@ -218,13 +218,12 @@ void WriteCellBigEndian( uint8_t *addr, ucell_t data ) { /* Write should be in order of increasing address * to optimize for burst writes to DRAM. */ - if( sizeof(ucell_t) == 8 ) - { + #if (LONG_MAX > 2147483647) /* LONG_MAX from limits.h: values > 2^31-1 indicates 64bit ints */ *addr++ = (uint8_t) (data>>56); *addr++ = (uint8_t) (data>>48); *addr++ = (uint8_t) (data>>40); *addr++ = (uint8_t) (data>>32); - } + #endif *addr++ = (uint8_t) (data>>24); *addr++ = (uint8_t) (data>>16); *addr++ = (uint8_t) (data>>8); From 3efb3b370d0c95a97bec018213df21c2e388baed Mon Sep 17 00:00:00 2001 From: GuBerAtHome Date: Tue, 31 Dec 2024 09:27:09 +0100 Subject: [PATCH 02/17] feature: custom demo cf_demo1 --- custom/01-be-gone/cf_demo1.c | 99 ++++++++++++++++++++++++++++++++++ custom/01-be-gone/cf_helpers.h | 42 +++++++++++++++ custom/01-be-gone/go.sh | 53 ++++++++++++++++++ 3 files changed, 194 insertions(+) create mode 100644 custom/01-be-gone/cf_demo1.c create mode 100644 custom/01-be-gone/cf_helpers.h create mode 100644 custom/01-be-gone/go.sh diff --git a/custom/01-be-gone/cf_demo1.c b/custom/01-be-gone/cf_demo1.c new file mode 100644 index 0000000..e4691ec --- /dev/null +++ b/custom/01-be-gone/cf_demo1.c @@ -0,0 +1,99 @@ +#include "pf_all.h" /* lots of stuff */ +#include "cf_helpers.h" /* panic, safeAlloc, to_C_string, {fprintf, stderr, ...} */ +#include /* errno */ + +/* + * put forward declarations here if necessary +*/ + + +/**************************************************************** +** Step 1: Put your own special glue routines here +** or link them in from another file or library. +****************************************************************/ + +/* exported functions */ + +static cell_t f4711( cell_t Val ) +{/* a quick way to check that custom worlds are available + */ + return 11 + 47*Val; +} + +static cell_t be_gone( cell_t fileName, cell_t fnLen ) +{/* Demonstrates passing strings from PForth to C. + Interprets the passed strings as file name and tries to delete the file. + Returns 0 or errno + */ + int res; + char* buf = to_C_string( fileName, fnLen ); + res = remove(buf); /* delete file in file system */ + if( res!=0 ) + res = errno; + free(buf); + return res; +} + + +/**************************************************************** +** Step 2: Create CustomFunctionTable. +** Do not change the name of CustomFunctionTable! +** It is used by the pForth kernel. +****************************************************************/ + +#ifdef PF_NO_GLOBAL_INIT +/****************** +** If your loader does not support global initialization, then you +** must define PF_NO_GLOBAL_INIT and provide a function to fill +** the table. Some embedded system loaders require this! +** Do not change the name of LoadCustomFunctionTable()! +** It is called by the pForth kernel. +*/ +#define NUM_CUSTOM_FUNCTIONS (2) +CFunc0 CustomFunctionTable[NUM_CUSTOM_FUNCTIONS]; + +Err LoadCustomFunctionTable( void ) +{ + CustomFunctionTable[0] = f4711; + CustomFunctionTable[1] = be_gone; + return 0; +} + +#else +/****************** +** If your loader supports global initialization (most do.) then just +** create the table like this. +*/ +CFunc0 CustomFunctionTable[] = +{ + (CFunc0) f4711, + (CFunc0) be_gone +}; +#endif + + +/**************************************************************** +** Step 3: Add custom functions to the dictionary. +** Do not change the name of CompileCustomFunctions! +** It is called by the pForth kernel. +****************************************************************/ + +#if (!defined(PF_NO_INIT)) && (!defined(PF_NO_SHELL)) +Err CompileCustomFunctions( void ) +{ + Err err; + int i = 0; +/* Compile Forth words that call your custom functions. +** Make sure order of functions matches that in LoadCustomFunctionTable(). +** Parameters are: Name in UPPER CASE, Function, Index, Mode, NumParams +*/ + err = CreateGlueToC( "F4711" , i++, C_RETURNS_VALUE, 1 ); + if( err < 0 ) return err; + err = CreateGlueToC( "BE-GONE", i++, C_RETURNS_VALUE, 2 ); + if( err < 0 ) return err; + + return 0; +} +#else +Err CompileCustomFunctions( void ) { return 0; } +#endif diff --git a/custom/01-be-gone/cf_helpers.h b/custom/01-be-gone/cf_helpers.h new file mode 100644 index 0000000..6de3dff --- /dev/null +++ b/custom/01-be-gone/cf_helpers.h @@ -0,0 +1,42 @@ +/* custom code for pforth (hence Custom Forth = cf) + This is a hack and for demonstration purposes only. + It simplifies a few things (like patching of Makefile) + but violates rules for production C code (e.g placing definitions in header files and terminating at the 1st sign of trouble). + Defines helper functions for several examples. +*/ + +#ifndef CF_HELPERS_H +#define CF_HELPERS_H + +#include /* fprintf() */ +#include /* exit() */ + +static void panic( const char* exitMsg ) +{/* Terminates program with panic message on stderr + Beware: might mess up the terminal sometimes :-/ (restarting pforth works fine though) + */ + fprintf(stderr, "\n====> panic! about to exit: %s\n", exitMsg); + exit(1); +} + +static void* safeAlloc( size_t bytes ) +{/* allocate memory and panic if that did not succees + */ + void* result = malloc(bytes); /* TODO: replace by calloc() ?! */ + if(result==NULL) + panic("can not allocate memory!"); + return result; +} + +static char* to_C_string( cell_t strData, cell_t iStrLen ) +{/* copy PForth string to C-string (zero terminated) + Don't forget to free() the result! + TODO: check if there is already defined a similar function in pforth + */ + char* buf = safeAlloc(iStrLen+1); + memcpy( buf, (void*)strData, iStrLen ); + buf[iStrLen] = 0; + return buf; +} + +#endif diff --git a/custom/01-be-gone/go.sh b/custom/01-be-gone/go.sh new file mode 100644 index 0000000..9f591b7 --- /dev/null +++ b/custom/01-be-gone/go.sh @@ -0,0 +1,53 @@ +#!/bin/sh + +MAKE_CMD="make" # on Linux, MSYS2-Cygwin +#MAKE_CMD="gmake" # on FreeBSD?, NetBSD + + +# Compile pForth with custom code and show that this works. +# We assume a posix shell and system (but adaption should be easy to others). +# This patches the existing source tree and might create confusion when not used on separate Git branch in case an error occurs. + +# save original C sources and copy demo sources. Thus we do not need to change the make file. +mv ../../csrc/pfcustom.c ../../csrc/pfcustom_c.original +cp cf_helpers.h ../../csrc/ +cp cf_demo1.c ../../csrc/pfcustom.c # + +# make pforth (skip standalone executable) +# We would not even need to define DPF_USER_CUSTOM since it is only used in the original pfcustom.c we overwrote. +cd ../../platforms/unix/ +DPF_USER_CUSTOM="1" $MAKE_CMD clean pforth.dic + +# create a nuisance to delete +mv ../../csrc/cf_helpers.h ./terrible_nuisance.asm + +echo +echo "---------------------------" +echo "show that custom code works" +echo "---------------------------" +cat >demo1.fth << EOF +." f4711( 0, 100 ) = " +0 f4711 . +100 f4711 . +CR + +." be-gone: " +s" terrible_nuisance.asm" be-gone 0= dup +if + ." works." + drop +else + ." returns error=" . +then CR +EOF +./pforth -q demo1.fth + +# restore original source tree +rm demo1.fth +mv ../../csrc/pfcustom_c.original ../../csrc/pfcustom.c +$MAKE_CMD clean + +echo +echo "-----------------" +echo "That's all folks!" +echo "-----------------" From 70e74ae003ae5445b9b7a4216b56d272c65ce098 Mon Sep 17 00:00:00 2001 From: GuBerAtHome Date: Tue, 31 Dec 2024 17:38:04 +0100 Subject: [PATCH 03/17] tested and fixed cf_demo1 on MSYS2, Linux, FreeBSD, NetBSD --- custom/01-be-gone/cf_demo1.c | 2 +- custom/01-be-gone/demo.fth | 18 +++++++++ custom/01-be-gone/go.sh | 56 +++++++++++++++------------- custom/{01-be-gone => }/cf_helpers.h | 0 4 files changed, 49 insertions(+), 27 deletions(-) create mode 100644 custom/01-be-gone/demo.fth rename custom/{01-be-gone => }/cf_helpers.h (100%) diff --git a/custom/01-be-gone/cf_demo1.c b/custom/01-be-gone/cf_demo1.c index e4691ec..c6c8c55 100644 --- a/custom/01-be-gone/cf_demo1.c +++ b/custom/01-be-gone/cf_demo1.c @@ -28,7 +28,7 @@ static cell_t be_gone( cell_t fileName, cell_t fnLen ) int res; char* buf = to_C_string( fileName, fnLen ); res = remove(buf); /* delete file in file system */ - if( res!=0 ) + if( res!=0 && errno!=0 ) res = errno; free(buf); return res; diff --git a/custom/01-be-gone/demo.fth b/custom/01-be-gone/demo.fth new file mode 100644 index 0000000..1b6a99e --- /dev/null +++ b/custom/01-be-gone/demo.fth @@ -0,0 +1,18 @@ +\ f4711 is a clear indicator that compilation of custom functions was successful +." f4711( 0, 1, 10, 100, 1000 ) = ( " + 0 f4711 . ." , " + 1 f4711 . ." , " + 10 f4711 . ." , " + 100 f4711 . ." , " +1000 f4711 . ." )" +CR + +\ example of passing passing strings from PForth to custom C code +." be-gone: " +s" terrible_nuisance.asm" be-gone dup 0= +if + ." works." + drop +else + ." returns error=" . +then CR diff --git a/custom/01-be-gone/go.sh b/custom/01-be-gone/go.sh index 9f591b7..65a66f1 100644 --- a/custom/01-be-gone/go.sh +++ b/custom/01-be-gone/go.sh @@ -1,16 +1,33 @@ #!/bin/sh -MAKE_CMD="make" # on Linux, MSYS2-Cygwin -#MAKE_CMD="gmake" # on FreeBSD?, NetBSD - - -# Compile pForth with custom code and show that this works. +# Compile pForth with custom code and show that this works. # We assume a posix shell and system (but adaption should be easy to others). -# This patches the existing source tree and might create confusion when not used on separate Git branch in case an error occurs. +# Note: This is the easiest solution but ignores PForths best practices set up in pfcustom.c +# Warning: This patches the existing source tree and might create confusion when not used on separate Git branch in case an error occurs. +# Tested on MSYS2-Cygwin, Linux, FreeBSD (X86_64 architecture each), NetBSD (i386 architecture) + +os=`uname -o 2>/dev/null` +if test -z "$os" ; then + # NetBSD-uname does not implement '-o' option + os=`uname -s` +fi +case "$os" in + "FreeBSD") + CC="clang" + export CC + MAKE_CMD="gmake" + ;; + "NetBSD") + MAKE_CMD="gmake" + ;; + *) # e.g. "Msys" | "GNU/Linux" + MAKE_CMD="make" + ;; +esac # save original C sources and copy demo sources. Thus we do not need to change the make file. mv ../../csrc/pfcustom.c ../../csrc/pfcustom_c.original -cp cf_helpers.h ../../csrc/ +cp ../cf_helpers.h ../../csrc/ cp cf_demo1.c ../../csrc/pfcustom.c # # make pforth (skip standalone executable) @@ -25,25 +42,12 @@ echo echo "---------------------------" echo "show that custom code works" echo "---------------------------" -cat >demo1.fth << EOF -." f4711( 0, 100 ) = " -0 f4711 . -100 f4711 . -CR - -." be-gone: " -s" terrible_nuisance.asm" be-gone 0= dup -if - ." works." - drop -else - ." returns error=" . -then CR -EOF -./pforth -q demo1.fth - -# restore original source tree -rm demo1.fth +./pforth -q ../../custom/01-be-gone/demo.fth + +echo +echo "----------------------------" +echo "restore original source tree" +echo "----------------------------" mv ../../csrc/pfcustom_c.original ../../csrc/pfcustom.c $MAKE_CMD clean diff --git a/custom/01-be-gone/cf_helpers.h b/custom/cf_helpers.h similarity index 100% rename from custom/01-be-gone/cf_helpers.h rename to custom/cf_helpers.h From 1bd41cfce35f5409fd394ddf66563d177e41cf83 Mon Sep 17 00:00:00 2001 From: GuBerAtHome Date: Tue, 31 Dec 2024 22:22:41 +0100 Subject: [PATCH 04/17] feature: new custom code handling for unix build --- custom/01-be-gone/{go.sh => go-v0.sh} | 7 ++-- custom/01-be-gone/go-v1.sh | 56 +++++++++++++++++++++++++++ platforms/unix/Makefile | 9 ++++- 3 files changed, 68 insertions(+), 4 deletions(-) rename custom/01-be-gone/{go.sh => go-v0.sh} (88%) create mode 100644 custom/01-be-gone/go-v1.sh diff --git a/custom/01-be-gone/go.sh b/custom/01-be-gone/go-v0.sh similarity index 88% rename from custom/01-be-gone/go.sh rename to custom/01-be-gone/go-v0.sh index 65a66f1..867da58 100644 --- a/custom/01-be-gone/go.sh +++ b/custom/01-be-gone/go-v0.sh @@ -13,6 +13,7 @@ if test -z "$os" ; then fi case "$os" in "FreeBSD") + # TODO: remove next line once Makefile has been updated accordingly (pull request pending) CC="clang" export CC MAKE_CMD="gmake" @@ -27,13 +28,13 @@ esac # save original C sources and copy demo sources. Thus we do not need to change the make file. mv ../../csrc/pfcustom.c ../../csrc/pfcustom_c.original -cp ../cf_helpers.h ../../csrc/ -cp cf_demo1.c ../../csrc/pfcustom.c # +cp ../cf_helpers.h ../../csrc/ +cp cf_demo1.c ../../csrc/pfcustom.c # make pforth (skip standalone executable) # We would not even need to define DPF_USER_CUSTOM since it is only used in the original pfcustom.c we overwrote. cd ../../platforms/unix/ -DPF_USER_CUSTOM="1" $MAKE_CMD clean pforth.dic +PF_USER_CUSTOM="1" $MAKE_CMD clean pforth.dic # create a nuisance to delete mv ../../csrc/cf_helpers.h ./terrible_nuisance.asm diff --git a/custom/01-be-gone/go-v1.sh b/custom/01-be-gone/go-v1.sh new file mode 100644 index 0000000..85c7aa7 --- /dev/null +++ b/custom/01-be-gone/go-v1.sh @@ -0,0 +1,56 @@ +#!/bin/sh + +# Compile pForth with custom code and show that this works. +# We assume a posix shell and system (but adaption should be easy to others). +# This improved version only compiles the custom code defined in CF_SOURCES. +# Warning: This patches the existing source tree and might create confusion when not used on separate Git branch in case an error occurs. +# Tested on MSYS2-Cygwin, Linux, FreeBSD (X86_64 architecture each), NetBSD (i386 architecture) + +os=`uname -o 2>/dev/null` +if test -z "$os" ; then + # NetBSD-uname does not implement '-o' option + os=`uname -s` +fi +case "$os" in + "FreeBSD") + # TODO: remove next line once Makefile has been updated accordingly (pull request pending) + CC="clang" + export CC + MAKE_CMD="gmake" + ;; + "NetBSD") + MAKE_CMD="gmake" + ;; + *) # e.g. "Msys" | "GNU/Linux" + MAKE_CMD="make" + ;; +esac + +# copy demo sources. Thus we do not need to change the make file. +cp ../cf_helpers.h ../../csrc/ +cp cf_demo1.c ../../csrc/ + +# make pforth (skip standalone executable) +cd ../../platforms/unix/ +CF_SOURCES="cf_demo1.c" $MAKE_CMD clean pforth.dic + +# create a nuisance to delete +mv ../../csrc/cf_helpers.h ./terrible_nuisance.asm + +echo +echo "---------------------------" +echo "show that custom code works" +echo "---------------------------" +./pforth -q ../../custom/01-be-gone/demo.fth + +echo +echo "----------------------------" +echo "restore original source tree" +echo "----------------------------" +rm ../../csrc/cf_demo1.c +CF_SOURCES="cf_demo1.c" $MAKE_CMD clean + +echo +echo "-----------------" +echo "That's all folks!" +echo "-----------------" diff --git a/platforms/unix/Makefile b/platforms/unix/Makefile index 5bcc164..2eb9e1c 100644 --- a/platforms/unix/Makefile +++ b/platforms/unix/Makefile @@ -39,6 +39,13 @@ FULL_WARNINGS = \ -Wmissing-prototypes \ -Wmissing-declarations +# custom code options +ifndef CF_SOURCES + # note: setting CF_PARAM does not help: It only deactivates all definitions in pfcustom.c, which we only include when no custom code is compiled! + # We do not remove CF_PARAM from code and documentation until we can verify that Makefiles continue to work. + CF_SOURCES=pfcustom.c +endif + DEBUGOPTS = -g CCOPTS = $(WIDTHOPT) -x c -O2 $(FULL_WARNINGS) $(EXTRA_CCOPTS) $(DEBUGOPTS) @@ -70,7 +77,7 @@ PFINCLUDES = pf_all.h pf_cglue.h pf_clib.h pf_core.h pf_float.h \ pfcompil.h pfinnrfp.h pforth.h PFBASESOURCE = pf_cglue.c pf_clib.c pf_core.c pf_inner.c \ pf_io.c pf_io_none.c pf_main.c pf_mem.c pf_save.c \ - pf_text.c pf_words.c pfcompil.c pfcustom.c + pf_text.c pf_words.c pfcompil.c $(CF_SOURCES) PFSOURCE = $(PFBASESOURCE) $(IO_SOURCE) VPATH = .:$(CSRCDIR):$(CSRCDIR)/posix:$(CSRCDIR)/stdio:$(CSRCDIR)/win32_console:$(CSRCDIR)/win32 From 6889a15445216f4f1714e10c418276378f21d428 Mon Sep 17 00:00:00 2001 From: GuBerAtHome Date: Tue, 31 Dec 2024 23:25:14 +0100 Subject: [PATCH 05/17] bugfix: latest merge from upstream simplifies FreeBSD handling --- custom/01-be-gone/go-v0.sh | 10 ++-------- custom/01-be-gone/go-v1.sh | 10 ++-------- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/custom/01-be-gone/go-v0.sh b/custom/01-be-gone/go-v0.sh index 867da58..c27410c 100644 --- a/custom/01-be-gone/go-v0.sh +++ b/custom/01-be-gone/go-v0.sh @@ -12,18 +12,12 @@ if test -z "$os" ; then os=`uname -s` fi case "$os" in - "FreeBSD") - # TODO: remove next line once Makefile has been updated accordingly (pull request pending) - CC="clang" - export CC + "FreeBSD" | "NetBSD") MAKE_CMD="gmake" ;; - "NetBSD") - MAKE_CMD="gmake" - ;; *) # e.g. "Msys" | "GNU/Linux" MAKE_CMD="make" - ;; + ;; esac # save original C sources and copy demo sources. Thus we do not need to change the make file. diff --git a/custom/01-be-gone/go-v1.sh b/custom/01-be-gone/go-v1.sh index 85c7aa7..52bf5d6 100644 --- a/custom/01-be-gone/go-v1.sh +++ b/custom/01-be-gone/go-v1.sh @@ -12,18 +12,12 @@ if test -z "$os" ; then os=`uname -s` fi case "$os" in - "FreeBSD") - # TODO: remove next line once Makefile has been updated accordingly (pull request pending) - CC="clang" - export CC + "FreeBSD" | "NetBSD") MAKE_CMD="gmake" ;; - "NetBSD") - MAKE_CMD="gmake" - ;; *) # e.g. "Msys" | "GNU/Linux" MAKE_CMD="make" - ;; + ;; esac # copy demo sources. Thus we do not need to change the make file. From aeff369c9cccb3952b105a68e4de0dd079d532de Mon Sep 17 00:00:00 2001 From: GuBerAtHome Date: Tue, 31 Dec 2024 23:48:10 +0100 Subject: [PATCH 06/17] refactored get-make-cmd to separate shell script --- custom/01-be-gone/get-make-cmd.sh | 16 ++++++++++++++++ custom/01-be-gone/go-v0.sh | 22 ++++++---------------- custom/01-be-gone/go-v1.sh | 22 +++++++--------------- 3 files changed, 29 insertions(+), 31 deletions(-) create mode 100644 custom/01-be-gone/get-make-cmd.sh diff --git a/custom/01-be-gone/get-make-cmd.sh b/custom/01-be-gone/get-make-cmd.sh new file mode 100644 index 0000000..135f9f4 --- /dev/null +++ b/custom/01-be-gone/get-make-cmd.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +os=`uname -o 2>/dev/null` +if test -z "$os" ; then + # NetBSD-uname does not implement '-o' option + os=`uname -s` +fi + +case "$os" in + "FreeBSD" | "NetBSD") + echo "gmake" + ;; + *) # e.g. "Msys" | "GNU/Linux" + echo "make" + ;; +esac diff --git a/custom/01-be-gone/go-v0.sh b/custom/01-be-gone/go-v0.sh index c27410c..736283c 100644 --- a/custom/01-be-gone/go-v0.sh +++ b/custom/01-be-gone/go-v0.sh @@ -6,28 +6,18 @@ # Warning: This patches the existing source tree and might create confusion when not used on separate Git branch in case an error occurs. # Tested on MSYS2-Cygwin, Linux, FreeBSD (X86_64 architecture each), NetBSD (i386 architecture) -os=`uname -o 2>/dev/null` -if test -z "$os" ; then - # NetBSD-uname does not implement '-o' option - os=`uname -s` -fi -case "$os" in - "FreeBSD" | "NetBSD") - MAKE_CMD="gmake" - ;; - *) # e.g. "Msys" | "GNU/Linux" - MAKE_CMD="make" - ;; -esac - # save original C sources and copy demo sources. Thus we do not need to change the make file. mv ../../csrc/pfcustom.c ../../csrc/pfcustom_c.original cp ../cf_helpers.h ../../csrc/ cp cf_demo1.c ../../csrc/pfcustom.c -# make pforth (skip standalone executable) -# We would not even need to define DPF_USER_CUSTOM since it is only used in the original pfcustom.c we overwrote. +echo +echo "----------------------------------------" +echo "make pforth (skip standalone executable)" +echo "----------------------------------------" +MAKE_CMD=`./get-make-cmd.sh` cd ../../platforms/unix/ +# We would not even need to define DPF_USER_CUSTOM since it is only used in the original pfcustom.c we overwrote. PF_USER_CUSTOM="1" $MAKE_CMD clean pforth.dic # create a nuisance to delete diff --git a/custom/01-be-gone/go-v1.sh b/custom/01-be-gone/go-v1.sh index 52bf5d6..8ec6ab1 100644 --- a/custom/01-be-gone/go-v1.sh +++ b/custom/01-be-gone/go-v1.sh @@ -6,26 +6,18 @@ # Warning: This patches the existing source tree and might create confusion when not used on separate Git branch in case an error occurs. # Tested on MSYS2-Cygwin, Linux, FreeBSD (X86_64 architecture each), NetBSD (i386 architecture) -os=`uname -o 2>/dev/null` -if test -z "$os" ; then - # NetBSD-uname does not implement '-o' option - os=`uname -s` -fi -case "$os" in - "FreeBSD" | "NetBSD") - MAKE_CMD="gmake" - ;; - *) # e.g. "Msys" | "GNU/Linux" - MAKE_CMD="make" - ;; -esac - # copy demo sources. Thus we do not need to change the make file. + cp ../cf_helpers.h ../../csrc/ cp cf_demo1.c ../../csrc/ -# make pforth (skip standalone executable) +echo +echo "----------------------------------------" +echo "make pforth (skip standalone executable)" +echo "----------------------------------------" +MAKE_CMD=`./get-make-cmd.sh` cd ../../platforms/unix/ + CF_SOURCES="cf_demo1.c" $MAKE_CMD clean pforth.dic # create a nuisance to delete From 866422ed83e9dc261eac59a43c06d3df55b63e96 Mon Sep 17 00:00:00 2001 From: GuBerAtHome Date: Thu, 2 Jan 2025 09:32:18 +0100 Subject: [PATCH 07/17] from-codereview: moved to examples/custom/ folder --- .../custom/01-parameter-passing}/cf_demo1.c | 0 .../01-be-gone => examples/custom/01-parameter-passing}/demo.fth | 0 .../01-be-gone => examples/custom/01-parameter-passing}/go-v0.sh | 0 .../01-be-gone => examples/custom/01-parameter-passing}/go-v1.sh | 0 {custom => examples/custom}/cf_helpers.h | 0 {custom/01-be-gone => examples/custom}/get-make-cmd.sh | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename {custom/01-be-gone => examples/custom/01-parameter-passing}/cf_demo1.c (100%) rename {custom/01-be-gone => examples/custom/01-parameter-passing}/demo.fth (100%) rename {custom/01-be-gone => examples/custom/01-parameter-passing}/go-v0.sh (100%) rename {custom/01-be-gone => examples/custom/01-parameter-passing}/go-v1.sh (100%) rename {custom => examples/custom}/cf_helpers.h (100%) rename {custom/01-be-gone => examples/custom}/get-make-cmd.sh (100%) diff --git a/custom/01-be-gone/cf_demo1.c b/examples/custom/01-parameter-passing/cf_demo1.c similarity index 100% rename from custom/01-be-gone/cf_demo1.c rename to examples/custom/01-parameter-passing/cf_demo1.c diff --git a/custom/01-be-gone/demo.fth b/examples/custom/01-parameter-passing/demo.fth similarity index 100% rename from custom/01-be-gone/demo.fth rename to examples/custom/01-parameter-passing/demo.fth diff --git a/custom/01-be-gone/go-v0.sh b/examples/custom/01-parameter-passing/go-v0.sh similarity index 100% rename from custom/01-be-gone/go-v0.sh rename to examples/custom/01-parameter-passing/go-v0.sh diff --git a/custom/01-be-gone/go-v1.sh b/examples/custom/01-parameter-passing/go-v1.sh similarity index 100% rename from custom/01-be-gone/go-v1.sh rename to examples/custom/01-parameter-passing/go-v1.sh diff --git a/custom/cf_helpers.h b/examples/custom/cf_helpers.h similarity index 100% rename from custom/cf_helpers.h rename to examples/custom/cf_helpers.h diff --git a/custom/01-be-gone/get-make-cmd.sh b/examples/custom/get-make-cmd.sh similarity index 100% rename from custom/01-be-gone/get-make-cmd.sh rename to examples/custom/get-make-cmd.sh From 03a4d0a5a836a288999657bc944aad9d82d6cd66 Mon Sep 17 00:00:00 2001 From: GuBerAtHome Date: Thu, 2 Jan 2025 10:03:38 +0100 Subject: [PATCH 08/17] from-codereview: replaced BE-GONE by FILE-INFO, fixed go-v1.sh --- .../custom/01-parameter-passing/cf_demo1.c | 56 +++++++++++++------ examples/custom/01-parameter-passing/demo.fth | 15 +++-- examples/custom/01-parameter-passing/go-v1.sh | 14 ++--- 3 files changed, 52 insertions(+), 33 deletions(-) diff --git a/examples/custom/01-parameter-passing/cf_demo1.c b/examples/custom/01-parameter-passing/cf_demo1.c index c6c8c55..123048a 100644 --- a/examples/custom/01-parameter-passing/cf_demo1.c +++ b/examples/custom/01-parameter-passing/cf_demo1.c @@ -1,6 +1,10 @@ #include "pf_all.h" /* lots of stuff */ #include "cf_helpers.h" /* panic, safeAlloc, to_C_string, {fprintf, stderr, ...} */ -#include /* errno */ +#include /* errno */ +#include /* PATH_MAX */ +#include /* malloc */ +#include /* strerror */ +#include /* struct stat, stat */ /* * put forward declarations here if necessary @@ -20,18 +24,36 @@ static cell_t f4711( cell_t Val ) return 11 + 47*Val; } -static cell_t be_gone( cell_t fileName, cell_t fnLen ) -{/* Demonstrates passing strings from PForth to C. - Interprets the passed strings as file name and tries to delete the file. - Returns 0 or errno - */ - int res; - char* buf = to_C_string( fileName, fnLen ); - res = remove(buf); /* delete file in file system */ - if( res!=0 && errno!=0 ) - res = errno; - free(buf); - return res; +static cell_t FileInfo( cell_t path_caddr, cell_t path_len ) { + char* path = to_C_string( path_caddr, path_len ); + struct stat info; + const char* fmtErr = "error{ id=%i, desc='%s', path='%s' }"; + const char* fmtDir = "directory{ path='%s' }"; + const char* fmtFile = "file{ size=%i, path='%s' }"; + char* result; +#if defined(__MSYS__) || defined(__CYGWIN__) + /* work around the sad fact that MSYS/Cygwin do not provide asprintf() */ + result = malloc(PATH_MAX+128); /* let's be save */ + if( stat(path, &info) == -1 ) + sprintf( result, fmtErr, errno, strerror(errno), path ); + else { + if( S_ISDIR(info.st_mode) ) + sprintf( result, fmtDir, path ); + else + sprintf( result, fmtFile, info.st_size, path ); + } +#else /* __MSYS__ */ + if( stat(path, &info) == -1 ) + asprintf( &result, fmtErr, errno, strerror(errno), path ); + else { + if( S_ISDIR(info.st_mode) ) + asprintf( &result, fmtDir, path ); + else + asprintf( &result, fmtFile, info.st_size, path ); + } +#endif /* __MSYS__ */ + PUSH_DATA_STACK( (cell_t) result ); + return (cell_t)strlen(result); } @@ -55,7 +77,7 @@ CFunc0 CustomFunctionTable[NUM_CUSTOM_FUNCTIONS]; Err LoadCustomFunctionTable( void ) { CustomFunctionTable[0] = f4711; - CustomFunctionTable[1] = be_gone; + CustomFunctionTable[1] = FileInfo; return 0; } @@ -67,7 +89,7 @@ Err LoadCustomFunctionTable( void ) CFunc0 CustomFunctionTable[] = { (CFunc0) f4711, - (CFunc0) be_gone + (CFunc0) FileInfo }; #endif @@ -87,9 +109,9 @@ Err CompileCustomFunctions( void ) ** Make sure order of functions matches that in LoadCustomFunctionTable(). ** Parameters are: Name in UPPER CASE, Function, Index, Mode, NumParams */ - err = CreateGlueToC( "F4711" , i++, C_RETURNS_VALUE, 1 ); + err = CreateGlueToC( "F4711" , i++, C_RETURNS_VALUE, 1 ); if( err < 0 ) return err; - err = CreateGlueToC( "BE-GONE", i++, C_RETURNS_VALUE, 2 ); + err = CreateGlueToC( "FILE-INFO", i++, C_RETURNS_VALUE, 2 ); if( err < 0 ) return err; return 0; diff --git a/examples/custom/01-parameter-passing/demo.fth b/examples/custom/01-parameter-passing/demo.fth index 1b6a99e..b4c1c55 100644 --- a/examples/custom/01-parameter-passing/demo.fth +++ b/examples/custom/01-parameter-passing/demo.fth @@ -8,11 +8,10 @@ CR \ example of passing passing strings from PForth to custom C code -." be-gone: " -s" terrible_nuisance.asm" be-gone dup 0= -if - ." works." - drop -else - ." returns error=" . -then CR +: SHOW-FILE-INFO + FILE-INFO type cr + ; +." FILE-INFO: " cr +s" Makefile" SHOW-FILE-INFO +s" ../../examples" SHOW-FILE-INFO +s" fileNotHere" SHOW-FILE-INFO diff --git a/examples/custom/01-parameter-passing/go-v1.sh b/examples/custom/01-parameter-passing/go-v1.sh index 8ec6ab1..9133390 100644 --- a/examples/custom/01-parameter-passing/go-v1.sh +++ b/examples/custom/01-parameter-passing/go-v1.sh @@ -8,31 +8,29 @@ # copy demo sources. Thus we do not need to change the make file. -cp ../cf_helpers.h ../../csrc/ -cp cf_demo1.c ../../csrc/ +cp ../cf_helpers.h ../../../csrc/ +cp cf_demo1.c ../../../csrc/ echo echo "----------------------------------------" echo "make pforth (skip standalone executable)" echo "----------------------------------------" -MAKE_CMD=`./get-make-cmd.sh` -cd ../../platforms/unix/ +MAKE_CMD=`../get-make-cmd.sh` +cd ../../../platforms/unix/ CF_SOURCES="cf_demo1.c" $MAKE_CMD clean pforth.dic -# create a nuisance to delete -mv ../../csrc/cf_helpers.h ./terrible_nuisance.asm - echo echo "---------------------------" echo "show that custom code works" echo "---------------------------" -./pforth -q ../../custom/01-be-gone/demo.fth +./pforth -q ../../examples/custom/01-parameter-passing/demo.fth echo echo "----------------------------" echo "restore original source tree" echo "----------------------------" +rm ../../csrc/cf_helpers.h rm ../../csrc/cf_demo1.c CF_SOURCES="cf_demo1.c" $MAKE_CMD clean From 122ab9b24587efda10e71617dccd619c73cf99d9 Mon Sep 17 00:00:00 2001 From: GuBerAtHome Date: Thu, 2 Jan 2025 10:15:56 +0100 Subject: [PATCH 09/17] from-codereview: removed panic() and safeAlloc() --- .../custom/01-parameter-passing/cf_demo1.c | 3 +- examples/custom/01-parameter-passing/demo.fth | 2 +- examples/custom/cf_helpers.h | 32 +++++-------------- 3 files changed, 11 insertions(+), 26 deletions(-) diff --git a/examples/custom/01-parameter-passing/cf_demo1.c b/examples/custom/01-parameter-passing/cf_demo1.c index 123048a..02a017d 100644 --- a/examples/custom/01-parameter-passing/cf_demo1.c +++ b/examples/custom/01-parameter-passing/cf_demo1.c @@ -1,8 +1,9 @@ #include "pf_all.h" /* lots of stuff */ -#include "cf_helpers.h" /* panic, safeAlloc, to_C_string, {fprintf, stderr, ...} */ +#include "cf_helpers.h" /* to_C_string */ #include /* errno */ #include /* PATH_MAX */ #include /* malloc */ +#include /* asprintf, sprintf */ #include /* strerror */ #include /* struct stat, stat */ diff --git a/examples/custom/01-parameter-passing/demo.fth b/examples/custom/01-parameter-passing/demo.fth index b4c1c55..2ff043f 100644 --- a/examples/custom/01-parameter-passing/demo.fth +++ b/examples/custom/01-parameter-passing/demo.fth @@ -9,7 +9,7 @@ CR \ example of passing passing strings from PForth to custom C code : SHOW-FILE-INFO - FILE-INFO type cr + ." " FILE-INFO type cr ; ." FILE-INFO: " cr s" Makefile" SHOW-FILE-INFO diff --git a/examples/custom/cf_helpers.h b/examples/custom/cf_helpers.h index 6de3dff..0be275a 100644 --- a/examples/custom/cf_helpers.h +++ b/examples/custom/cf_helpers.h @@ -8,35 +8,19 @@ #ifndef CF_HELPERS_H #define CF_HELPERS_H -#include /* fprintf() */ -#include /* exit() */ - -static void panic( const char* exitMsg ) -{/* Terminates program with panic message on stderr - Beware: might mess up the terminal sometimes :-/ (restarting pforth works fine though) - */ - fprintf(stderr, "\n====> panic! about to exit: %s\n", exitMsg); - exit(1); -} - -static void* safeAlloc( size_t bytes ) -{/* allocate memory and panic if that did not succees - */ - void* result = malloc(bytes); /* TODO: replace by calloc() ?! */ - if(result==NULL) - panic("can not allocate memory!"); - return result; -} +#include /* malloc */ +#include /* memcpy */ static char* to_C_string( cell_t strData, cell_t iStrLen ) {/* copy PForth string to C-string (zero terminated) Don't forget to free() the result! - TODO: check if there is already defined a similar function in pforth */ - char* buf = safeAlloc(iStrLen+1); - memcpy( buf, (void*)strData, iStrLen ); - buf[iStrLen] = 0; + char* buf = malloc(iStrLen+1); + if( buf != NULL ) { + memcpy( buf, (void*)strData, iStrLen ); + buf[iStrLen] = 0; + } return buf; } -#endif +#endif /* CF_HELPERS_H */ \ No newline at end of file From 409cee388be3e237de0372faef48d8193a46c088 Mon Sep 17 00:00:00 2001 From: GuBerAtHome Date: Thu, 2 Jan 2025 10:30:10 +0100 Subject: [PATCH 10/17] from-codereview: renamed Makefile variable to CUSTOM_SOURCES --- examples/custom/01-parameter-passing/go-v1.sh | 10 ++++++---- platforms/unix/Makefile | 6 +++--- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/examples/custom/01-parameter-passing/go-v1.sh b/examples/custom/01-parameter-passing/go-v1.sh index 9133390..805f37b 100644 --- a/examples/custom/01-parameter-passing/go-v1.sh +++ b/examples/custom/01-parameter-passing/go-v1.sh @@ -8,8 +8,10 @@ # copy demo sources. Thus we do not need to change the make file. -cp ../cf_helpers.h ../../../csrc/ -cp cf_demo1.c ../../../csrc/ +cp ../cf_helpers.h ../../../csrc/ +cp cf_demo1.c ../../../csrc/ +CUSTOM_SOURCES="cf_demo1.c" +export CUSTOM_SOURCES echo echo "----------------------------------------" @@ -18,7 +20,7 @@ echo "----------------------------------------" MAKE_CMD=`../get-make-cmd.sh` cd ../../../platforms/unix/ -CF_SOURCES="cf_demo1.c" $MAKE_CMD clean pforth.dic +$MAKE_CMD clean pforth.dic echo echo "---------------------------" @@ -32,7 +34,7 @@ echo "restore original source tree" echo "----------------------------" rm ../../csrc/cf_helpers.h rm ../../csrc/cf_demo1.c -CF_SOURCES="cf_demo1.c" $MAKE_CMD clean +$MAKE_CMD clean echo echo "-----------------" diff --git a/platforms/unix/Makefile b/platforms/unix/Makefile index 2bae58c..5d6932f 100644 --- a/platforms/unix/Makefile +++ b/platforms/unix/Makefile @@ -40,10 +40,10 @@ FULL_WARNINGS = \ -Wmissing-declarations # custom code options -ifndef CF_SOURCES +ifndef CUSTOM_SOURCES # note: setting CF_PARAM does not help: It only deactivates all definitions in pfcustom.c, which we only include when no custom code is compiled! # We do not remove CF_PARAM from code and documentation until we can verify that Makefiles continue to work. - CF_SOURCES=pfcustom.c + CUSTOM_SOURCES=pfcustom.c endif DEBUGOPTS = -g @@ -81,7 +81,7 @@ PFINCLUDES = pf_all.h pf_cglue.h pf_clib.h pf_core.h pf_float.h \ pfcompil.h pfinnrfp.h pforth.h PFBASESOURCE = pf_cglue.c pf_clib.c pf_core.c pf_inner.c \ pf_io.c pf_io_none.c pf_main.c pf_mem.c pf_save.c \ - pf_text.c pf_words.c pfcompil.c $(CF_SOURCES) + pf_text.c pf_words.c pfcompil.c $(CUSTOM_SOURCES) PFSOURCE = $(PFBASESOURCE) $(IO_SOURCE) VPATH = .:$(CSRCDIR):$(CSRCDIR)/posix:$(CSRCDIR)/stdio:$(CSRCDIR)/win32_console:$(CSRCDIR)/win32 From 6daae7973ea3bb12748422696af7400f138e21cd Mon Sep 17 00:00:00 2001 From: GuBerAtHome Date: Thu, 2 Jan 2025 10:33:57 +0100 Subject: [PATCH 11/17] from-codereview: removed go-v0.sh --- examples/custom/01-parameter-passing/go-v0.sh | 42 ------------------- .../01-parameter-passing/{go-v1.sh => go.sh} | 2 +- 2 files changed, 1 insertion(+), 43 deletions(-) delete mode 100644 examples/custom/01-parameter-passing/go-v0.sh rename examples/custom/01-parameter-passing/{go-v1.sh => go.sh} (95%) diff --git a/examples/custom/01-parameter-passing/go-v0.sh b/examples/custom/01-parameter-passing/go-v0.sh deleted file mode 100644 index 736283c..0000000 --- a/examples/custom/01-parameter-passing/go-v0.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/sh - -# Compile pForth with custom code and show that this works. -# We assume a posix shell and system (but adaption should be easy to others). -# Note: This is the easiest solution but ignores PForths best practices set up in pfcustom.c -# Warning: This patches the existing source tree and might create confusion when not used on separate Git branch in case an error occurs. -# Tested on MSYS2-Cygwin, Linux, FreeBSD (X86_64 architecture each), NetBSD (i386 architecture) - -# save original C sources and copy demo sources. Thus we do not need to change the make file. -mv ../../csrc/pfcustom.c ../../csrc/pfcustom_c.original -cp ../cf_helpers.h ../../csrc/ -cp cf_demo1.c ../../csrc/pfcustom.c - -echo -echo "----------------------------------------" -echo "make pforth (skip standalone executable)" -echo "----------------------------------------" -MAKE_CMD=`./get-make-cmd.sh` -cd ../../platforms/unix/ -# We would not even need to define DPF_USER_CUSTOM since it is only used in the original pfcustom.c we overwrote. -PF_USER_CUSTOM="1" $MAKE_CMD clean pforth.dic - -# create a nuisance to delete -mv ../../csrc/cf_helpers.h ./terrible_nuisance.asm - -echo -echo "---------------------------" -echo "show that custom code works" -echo "---------------------------" -./pforth -q ../../custom/01-be-gone/demo.fth - -echo -echo "----------------------------" -echo "restore original source tree" -echo "----------------------------" -mv ../../csrc/pfcustom_c.original ../../csrc/pfcustom.c -$MAKE_CMD clean - -echo -echo "-----------------" -echo "That's all folks!" -echo "-----------------" diff --git a/examples/custom/01-parameter-passing/go-v1.sh b/examples/custom/01-parameter-passing/go.sh similarity index 95% rename from examples/custom/01-parameter-passing/go-v1.sh rename to examples/custom/01-parameter-passing/go.sh index 805f37b..df4a4a7 100644 --- a/examples/custom/01-parameter-passing/go-v1.sh +++ b/examples/custom/01-parameter-passing/go.sh @@ -20,7 +20,7 @@ echo "----------------------------------------" MAKE_CMD=`../get-make-cmd.sh` cd ../../../platforms/unix/ -$MAKE_CMD clean pforth.dic +$MAKE_CMD pforth.dic # we just need a PForth executable+dictionary echo echo "---------------------------" From ea826e996061cddc54187dec990626293f754e33 Mon Sep 17 00:00:00 2001 From: GuBerAtHome Date: Thu, 2 Jan 2025 11:08:18 +0100 Subject: [PATCH 12/17] fixed typo --- examples/custom/01-parameter-passing/cf_demo1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/custom/01-parameter-passing/cf_demo1.c b/examples/custom/01-parameter-passing/cf_demo1.c index 02a017d..4017cef 100644 --- a/examples/custom/01-parameter-passing/cf_demo1.c +++ b/examples/custom/01-parameter-passing/cf_demo1.c @@ -20,7 +20,7 @@ /* exported functions */ static cell_t f4711( cell_t Val ) -{/* a quick way to check that custom worlds are available +{/* a quick way to check that custom words are available */ return 11 + 47*Val; } From e0dd86fc147310bcdecd108ddd96492fa795eb58 Mon Sep 17 00:00:00 2001 From: GuBerAtHome Date: Thu, 2 Jan 2025 12:31:44 +0100 Subject: [PATCH 13/17] bugfix: removed superfluos code for MSYS --- examples/custom/01-parameter-passing/cf_demo1.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/examples/custom/01-parameter-passing/cf_demo1.c b/examples/custom/01-parameter-passing/cf_demo1.c index 4017cef..6648f18 100644 --- a/examples/custom/01-parameter-passing/cf_demo1.c +++ b/examples/custom/01-parameter-passing/cf_demo1.c @@ -32,18 +32,7 @@ static cell_t FileInfo( cell_t path_caddr, cell_t path_len ) { const char* fmtDir = "directory{ path='%s' }"; const char* fmtFile = "file{ size=%i, path='%s' }"; char* result; -#if defined(__MSYS__) || defined(__CYGWIN__) - /* work around the sad fact that MSYS/Cygwin do not provide asprintf() */ - result = malloc(PATH_MAX+128); /* let's be save */ - if( stat(path, &info) == -1 ) - sprintf( result, fmtErr, errno, strerror(errno), path ); - else { - if( S_ISDIR(info.st_mode) ) - sprintf( result, fmtDir, path ); - else - sprintf( result, fmtFile, info.st_size, path ); - } -#else /* __MSYS__ */ + /* MSYS/Cygwin may warn than asprintf() is not defined but compile and run just fine :-/ */ if( stat(path, &info) == -1 ) asprintf( &result, fmtErr, errno, strerror(errno), path ); else { @@ -52,7 +41,6 @@ static cell_t FileInfo( cell_t path_caddr, cell_t path_len ) { else asprintf( &result, fmtFile, info.st_size, path ); } -#endif /* __MSYS__ */ PUSH_DATA_STACK( (cell_t) result ); return (cell_t)strlen(result); } From 82b212bfca3957ad6cd47bd7ba607130e8c60fac Mon Sep 17 00:00:00 2001 From: GuBerAtHome Date: Tue, 7 Jan 2025 17:17:28 +0100 Subject: [PATCH 14/17] changes from review --- .../custom/01-parameter-passing/cf_demo1.c | 32 +++++++++---------- examples/custom/01-parameter-passing/demo.fth | 2 +- examples/custom/cf_helpers.h | 2 +- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/examples/custom/01-parameter-passing/cf_demo1.c b/examples/custom/01-parameter-passing/cf_demo1.c index 6648f18..69f9130 100644 --- a/examples/custom/01-parameter-passing/cf_demo1.c +++ b/examples/custom/01-parameter-passing/cf_demo1.c @@ -26,23 +26,23 @@ static cell_t f4711( cell_t Val ) } static cell_t FileInfo( cell_t path_caddr, cell_t path_len ) { - char* path = to_C_string( path_caddr, path_len ); - struct stat info; - const char* fmtErr = "error{ id=%i, desc='%s', path='%s' }"; - const char* fmtDir = "directory{ path='%s' }"; - const char* fmtFile = "file{ size=%i, path='%s' }"; - char* result; - /* MSYS/Cygwin may warn than asprintf() is not defined but compile and run just fine :-/ */ - if( stat(path, &info) == -1 ) - asprintf( &result, fmtErr, errno, strerror(errno), path ); - else { - if( S_ISDIR(info.st_mode) ) - asprintf( &result, fmtDir, path ); - else - asprintf( &result, fmtFile, info.st_size, path ); - } + char* path = to_C_string( path_caddr, path_len ); + struct stat info; + const char* fmtErr = "error{ id=%i, desc='%s', path='%s' }"; + const char* fmtDir = "directory{ path='%s' }"; + const char* fmtFile = "file{ size=%i, path='%s' }"; + char* result; + /* MSYS/Cygwin may warn than asprintf() is not defined but compile and run just fine :-/ */ + if( stat(path, &info) == -1 ) + asprintf( &result, fmtErr, errno, strerror(errno), path ); + else { + if( S_ISDIR(info.st_mode) ) + asprintf( &result, fmtDir, path ); + else + asprintf( &result, fmtFile, info.st_size, path ); + } PUSH_DATA_STACK( (cell_t) result ); - return (cell_t)strlen(result); + return (cell_t)strlen(result); } diff --git a/examples/custom/01-parameter-passing/demo.fth b/examples/custom/01-parameter-passing/demo.fth index 2ff043f..6895c19 100644 --- a/examples/custom/01-parameter-passing/demo.fth +++ b/examples/custom/01-parameter-passing/demo.fth @@ -7,7 +7,7 @@ 1000 f4711 . ." )" CR -\ example of passing passing strings from PForth to custom C code +\ example of passing strings from PForth to custom C code : SHOW-FILE-INFO ." " FILE-INFO type cr ; diff --git a/examples/custom/cf_helpers.h b/examples/custom/cf_helpers.h index 0be275a..f0c224d 100644 --- a/examples/custom/cf_helpers.h +++ b/examples/custom/cf_helpers.h @@ -23,4 +23,4 @@ static char* to_C_string( cell_t strData, cell_t iStrLen ) return buf; } -#endif /* CF_HELPERS_H */ \ No newline at end of file +#endif /* CF_HELPERS_H */ From 5cb19e1739a858a0d905d15a18e194a21cdb5133 Mon Sep 17 00:00:00 2001 From: GuBerAtHome Date: Tue, 7 Jan 2025 18:27:36 +0100 Subject: [PATCH 15/17] free C buffer --- examples/custom/01-parameter-passing/cf_demo1.c | 17 +++++++++++++++-- examples/custom/01-parameter-passing/demo.fth | 4 +++- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/examples/custom/01-parameter-passing/cf_demo1.c b/examples/custom/01-parameter-passing/cf_demo1.c index 69f9130..13319e9 100644 --- a/examples/custom/01-parameter-passing/cf_demo1.c +++ b/examples/custom/01-parameter-passing/cf_demo1.c @@ -45,6 +45,15 @@ static cell_t FileInfo( cell_t path_caddr, cell_t path_len ) { return (cell_t)strlen(result); } +static void free_c( cell_t c_allocate_buffer ) +{ + /* Using FREE on a c_allocate_buffer is not possible (due to extra information stored), + using pfAllocMem() / pfFreeMem() does not help either. + So we need a separate word to free C-allocated buffers. + */ + free( (void*) c_allocate_buffer ); +} + /**************************************************************** ** Step 2: Create CustomFunctionTable. @@ -60,13 +69,14 @@ static cell_t FileInfo( cell_t path_caddr, cell_t path_len ) { ** Do not change the name of LoadCustomFunctionTable()! ** It is called by the pForth kernel. */ -#define NUM_CUSTOM_FUNCTIONS (2) +#define NUM_CUSTOM_FUNCTIONS (3) CFunc0 CustomFunctionTable[NUM_CUSTOM_FUNCTIONS]; Err LoadCustomFunctionTable( void ) { CustomFunctionTable[0] = f4711; CustomFunctionTable[1] = FileInfo; + CustomFunctionTable[1] = free_c; return 0; } @@ -78,7 +88,8 @@ Err LoadCustomFunctionTable( void ) CFunc0 CustomFunctionTable[] = { (CFunc0) f4711, - (CFunc0) FileInfo + (CFunc0) FileInfo, + (CFunc0) free_c }; #endif @@ -102,6 +113,8 @@ Err CompileCustomFunctions( void ) if( err < 0 ) return err; err = CreateGlueToC( "FILE-INFO", i++, C_RETURNS_VALUE, 2 ); if( err < 0 ) return err; + err = CreateGlueToC( "FREE-C" , i++, C_RETURNS_VOID , 1 ); + if( err < 0 ) return err; return 0; } diff --git a/examples/custom/01-parameter-passing/demo.fth b/examples/custom/01-parameter-passing/demo.fth index 6895c19..c618244 100644 --- a/examples/custom/01-parameter-passing/demo.fth +++ b/examples/custom/01-parameter-passing/demo.fth @@ -9,7 +9,9 @@ CR \ example of passing strings from PForth to custom C code : SHOW-FILE-INFO - ." " FILE-INFO type cr + FILE-INFO over -rot + ." " type cr + free-c ; ." FILE-INFO: " cr s" Makefile" SHOW-FILE-INFO From b9e523555c0c8017fe38a9905b24d0bbed3abbb7 Mon Sep 17 00:00:00 2001 From: GuBerAtHome Date: Tue, 7 Jan 2025 18:38:58 +0100 Subject: [PATCH 16/17] added description for FileInfo() --- examples/custom/01-parameter-passing/cf_demo1.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/examples/custom/01-parameter-passing/cf_demo1.c b/examples/custom/01-parameter-passing/cf_demo1.c index 13319e9..c1fba70 100644 --- a/examples/custom/01-parameter-passing/cf_demo1.c +++ b/examples/custom/01-parameter-passing/cf_demo1.c @@ -25,7 +25,11 @@ static cell_t f4711( cell_t Val ) return 11 + 47*Val; } -static cell_t FileInfo( cell_t path_caddr, cell_t path_len ) { +static cell_t file_info( cell_t path_caddr, cell_t path_len ) +{ + /* takes one filePath (string) as argument and returns some info on it (as a new string) + Note that you need to use FREE-C on the result buffer (FREE does not work). + */ char* path = to_C_string( path_caddr, path_len ); struct stat info; const char* fmtErr = "error{ id=%i, desc='%s', path='%s' }"; @@ -75,7 +79,7 @@ CFunc0 CustomFunctionTable[NUM_CUSTOM_FUNCTIONS]; Err LoadCustomFunctionTable( void ) { CustomFunctionTable[0] = f4711; - CustomFunctionTable[1] = FileInfo; + CustomFunctionTable[1] = file_info; CustomFunctionTable[1] = free_c; return 0; } @@ -88,7 +92,7 @@ Err LoadCustomFunctionTable( void ) CFunc0 CustomFunctionTable[] = { (CFunc0) f4711, - (CFunc0) FileInfo, + (CFunc0) file_info, (CFunc0) free_c }; #endif From 912172e2b85fd0cec08ee08e1c42c8a66567c95c Mon Sep 17 00:00:00 2001 From: GuBerAtHome Date: Tue, 7 Jan 2025 18:53:42 +0100 Subject: [PATCH 17/17] use result of asprintf instead of calling strlen --- examples/custom/01-parameter-passing/cf_demo1.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/examples/custom/01-parameter-passing/cf_demo1.c b/examples/custom/01-parameter-passing/cf_demo1.c index c1fba70..74708cc 100644 --- a/examples/custom/01-parameter-passing/cf_demo1.c +++ b/examples/custom/01-parameter-passing/cf_demo1.c @@ -36,17 +36,18 @@ static cell_t file_info( cell_t path_caddr, cell_t path_len ) const char* fmtDir = "directory{ path='%s' }"; const char* fmtFile = "file{ size=%i, path='%s' }"; char* result; + cell_t res_len = -1; /* MSYS/Cygwin may warn than asprintf() is not defined but compile and run just fine :-/ */ if( stat(path, &info) == -1 ) - asprintf( &result, fmtErr, errno, strerror(errno), path ); + res_len = asprintf( &result, fmtErr, errno, strerror(errno), path ); else { if( S_ISDIR(info.st_mode) ) - asprintf( &result, fmtDir, path ); + res_len = asprintf( &result, fmtDir, path ); else - asprintf( &result, fmtFile, info.st_size, path ); + res_len = asprintf( &result, fmtFile, info.st_size, path ); } PUSH_DATA_STACK( (cell_t) result ); - return (cell_t)strlen(result); + return res_len; } static void free_c( cell_t c_allocate_buffer )