| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 02f0225 commit 30e021b
20 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,3 +1,21 @@ | |||
| 1 | + 2014-02-27 Ethan A Merritt <merritt@u.washington.edu> | ||
| 2 | + | ||
| 3 | + * src/command.c src/command.h src/eval.c src/eval.h src/external.c | ||
| 4 | + src/external.h src/gp_types.h src/Makefile.am src/show.c src/tables.c: | ||
| 5 | + New command `import func(x) from "sharedobject"` extends gnuplot | ||
| 6 | + expresssion evaluation to allow calling functions exported by an | ||
| 7 | + external shared object (a.k.a. plugins). | ||
| 8 | + - original patch 2002 Stephan Boettcher <boettcher@physik.uni-kiel.de> | ||
| 9 | + - updated for 4.7 2014 Alexander Täschner <taschna@users.sf.net> | ||
| 10 | + - revised syntax and error handling 2014 Ethan A Merritt | ||
| 11 | + | ||
| 12 | + * config/config.nt configure.in demo/Makefile.am.in: | ||
| 13 | + ./configure --disable-plugins [enabled by default] | ||
| 14 | + | ||
| 15 | + * demo/plugin/demo_plugin.c demo/plugin/gnuplot_plugin.h | ||
| 16 | + demo/plugin/Makefile demo/plugin/plugin.dem docs/gnuplot.doc: | ||
| 17 | + Template files demonstrating the creation of custom plugin libraries. | ||
| 18 | + | ||
| 1 | 19 | 2014-02-27 Bastian Maerkisch <bmaerkisch@web.de> | |
| 2 | 20 | ||
| 3 | 21 | src/fit.c demo/fit.dem docs/gnuplot.doc: New syntax to specify errors. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,6 +1,7 @@ | |||
| 1 | 1 | New features, changes and fixes since gnuplot version 4.6 | |
| 2 | 2 | ========================================================= | |
| 3 | 3 | ||
| 4 | + * NEW function plugins, e.g. 'import f(x) from "plugins.so"' | ||
| 4 | 5 | * NEW option to tabulate all input columns "set table; plot ... with table" | |
| 5 | 6 | * NEW smoothing option "mcsplines" for piecewise monotonic cubic splines | |
| 6 | 7 | * NEW 'history !N' reexecutes the command at history entry N. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -94,6 +94,9 @@ | |||
| 94 | 94 | /* Define to 1 if you have the <errno.h> header file. */ | |
| 95 | 95 | #define HAVE_ERRNO_H 1 | |
| 96 | 96 | ||
| 97 | + /* Define if external function plugins are to be supported. */ | ||
| 98 | + #define HAVE_EXTERNAL_FUNCTIONS 1 | ||
| 99 | + | ||
| 97 | 100 | /* Define to 1 if you have the <float.h> header file. */ | |
| 98 | 101 | #define HAVE_FLOAT_H 1 | |
| 99 | 102 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,7 +1,7 @@ | |||
| 1 | 1 | dnl Process this file with autoconf to produce a configure script. | |
| 2 | 2 | dnl configure.in for gnuplot on Unix. | |
| 3 | 3 | dnl | |
| 4 | - dnl $Id: configure.in,v 1.350 2014/02/19 01:14:38 sfeam Exp $ | ||
| 4 | + dnl $Id: configure.in,v 1.351 2014/02/24 22:12:38 sfeam Exp $ | ||
| 5 | 5 | dnl | |
| 6 | 6 | dnl this is actually major.minor ... | |
| 7 | 7 | dnl note that for a non-beta release, we need to disable DEVELOPMENT_RELEASE | |
@@ -198,7 +198,8 @@ AC_CHECK_HEADERS(dirent.h errno.h float.h langinfo.h limits.h locale.h math.h \ | |||
| 198 | 198 | stdlib.h string.h time.h sys/time.h sys/types.h \ | |
| 199 | 199 | sys/bsdtypes.h sys/ioctl.h sys/param.h sys/select.h sys/socket.h \ | |
| 200 | 200 | sys/stat.h sys/systeminfo.h sys/timeb.h sys/utsname.h \ | |
| 201 | - libc.h malloc.h poll.h sgtty.h termios.h values.h dirent.h | ||
| 201 | + libc.h malloc.h poll.h sgtty.h termios.h values.h dirent.h \ | ||
| 202 | + dlfcn.h dl.h | ||
| 202 | 203 | ) | |
| 203 | 204 | ||
| 204 | 205 | AC_HEADER_STDBOOL | |
@@ -217,6 +218,26 @@ if test "$ac_cv_header_sys_stat_h" = yes; then | |||
| 217 | 218 | AC_HEADER_STAT | |
| 218 | 219 | fi | |
| 219 | 220 | ||
| 221 | + dnl Check for external functions plugin infrastructure | ||
| 222 | + AC_ARG_ENABLE(plugins,dnl | ||
| 223 | + [ --disable-plugins disable support for importing external functions],,) | ||
| 224 | + | ||
| 225 | + if test "$enable_plugins" != no; then | ||
| 226 | + if test "$ac_cv_header_dl_h" = yes; then | ||
| 227 | + AC_SEARCH_LIBS(shl_load, dld, | ||
| 228 | + [AC_DEFINE(HAVE_EXTERNAL_FUNCTIONS,1,[ Define if external function plugins are to be supported. ]) | ||
| 229 | + have_external_functions=yes | ||
| 230 | + ]) | ||
| 231 | + fi | ||
| 232 | + if test "$ac_cv_header_dlfcn_h" = yes; then | ||
| 233 | + AC_SEARCH_LIBS(dlopen, dl, | ||
| 234 | + [AC_DEFINE(HAVE_EXTERNAL_FUNCTIONS,1,[ Define if external function plugins are to be supported. ]) | ||
| 235 | + have_external_functions=yes | ||
| 236 | + ]) | ||
| 237 | + fi | ||
| 238 | + fi | ||
| 239 | + AM_CONDITIONAL(BUILD_PLUGIN, test "$have_external_functions" = yes) | ||
| 240 | + | ||
| 220 | 241 | dnl check if unistd actually declares anything. On NeXT 3.2 unistd is | |
| 221 | 242 | dnl conditionalized for _POSIX_SOURCE | |
| 222 | 243 | AC_MSG_CHECKING(for unistd.h) | |
@@ -1568,6 +1589,12 @@ else | |||
| 1568 | 1589 | AC_MSG_RESULT([ cerf() and other special functions: no (libcerf not found)]) | |
| 1569 | 1590 | fi | |
| 1570 | 1591 | ||
| 1592 | + if test "$have_external_functions" = yes; then | ||
| 1593 | + AC_MSG_RESULT([ plugin support for loading external functions: yes (EXPERIMENTAL)]) | ||
| 1594 | + else | ||
| 1595 | + AC_MSG_RESULT([ plugin support for loading external functions: no (EXPERIMENTAL)]) | ||
| 1596 | + fi | ||
| 1597 | + | ||
| 1571 | 1598 | if test "$with_kpsexpand" = yes; then | |
| 1572 | 1599 | AC_MSG_RESULT([ Use TeX kpsexpand to search for fonts: yes]) | |
| 1573 | 1600 | else | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -74,9 +74,14 @@ Makefile.am: Makefile.am.in | |||
| 74 | 74 | sed -n '1,/^##m4-files-begin/p' Makefile.am.in > $@t | |
| 75 | 75 | echo EXTRA_DIST = Makefile.am.in *.bin *.cfg *.cor *.dat *.dem *.edf \ | |
| 76 | 76 | *.fnc *.inc *.pdb *.png *.r3d *.rgb sound.par sound2.par \ | |
| 77 | - start.par *.rot gnu-valley random-points gpdemos.tcl html | fmt | \ | ||
| 77 | + start.par *.rot gnu-valley random-points gpdemos.tcl html plugin | fmt | \ | ||
| 78 | 78 | (tr '\012' @; echo) | sed 's/@$$/%/;s/@/ \\@/g' | tr @% '\012 ' \ | |
| 79 | 79 | >> $@t | |
| 80 | + echo if BUILD_PLUGIN >> $@t | ||
| 81 | + echo SUBDIRS = plugin >> $@t | ||
| 82 | + echo else >> $@t | ||
| 83 | + echo SUBDIRS = >> $@t | ||
| 84 | + echo endif >> $@t | ||
| 80 | 85 | sed -n '/^##m4-files-end/,$$p' $< >> $@t | |
| 81 | 86 | chmod og-w $@t | |
| 82 | 87 | mv $@t $@ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,13 @@ | |||
| 1 | + PLUGIN=demo_plugin | ||
| 2 | + | ||
| 3 | + all: $(PLUGIN).so | ||
| 4 | + | ||
| 5 | + GNUPLOTSRC = ../.. | ||
| 6 | + | ||
| 7 | + CFLAGS = -DHAVE_CONFIG_H -I$(GNUPLOTSRC) -I$(GNUPLOTSRC)/src -rdynamic -fPIC | ||
| 8 | + | ||
| 9 | + %.so: %.o | ||
| 10 | + $(CC) -shared $^ -o $@ | ||
| 11 | + | ||
| 12 | + clean: | ||
| 13 | + rm -f *.o *.so | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,92 @@ | |||
| 1 | + /* | ||
| 2 | + The files demo_plugin.c and gnuplot_plugin.h serve as templates | ||
| 3 | + showing how to create an external shared object containing functions | ||
| 4 | + that can be accessed from inside a gnuplot session using the import | ||
| 5 | + command. For example, after compiling this file into a shared | ||
| 6 | + object (gnuplot_plugin.so or gnuplot_plugin.dll) the functions it | ||
| 7 | + contains can be imported as shown: | ||
| 8 | + | ||
| 9 | + gnuplot> import divisors(x) from "demo_plugin" | ||
| 10 | + gnuplot> import mysinc(x) from "demo_plugin:sinc" | ||
| 11 | + gnuplot> import nsinc(N,x) from "demo_plugin" | ||
| 12 | + */ | ||
| 13 | + | ||
| 14 | + #include "gnuplot_plugin.h" | ||
| 15 | + #include "math.h" | ||
| 16 | + | ||
| 17 | + /* This funcstion returns the number of divisors of the first argument */ | ||
| 18 | + | ||
| 19 | + DLLEXPORT struct value divisors(int nargs, struct value *arg, void *p) | ||
| 20 | + { | ||
| 21 | + int a = IVAL(arg[0]); | ||
| 22 | + int i = 1; | ||
| 23 | + int j = a; | ||
| 24 | + struct value r; | ||
| 25 | + r.type = INTGR; | ||
| 26 | + r.v.int_val = 0; | ||
| 27 | + | ||
| 28 | + /* Enforce a match between the number of parameters declared | ||
| 29 | + * by the gnuplot import command and the number implemented here. | ||
| 30 | + */ | ||
| 31 | + RETURN_ERROR_IF_WRONG_NARGS(r, nargs, 1); | ||
| 32 | + | ||
| 33 | + /* Sanity check on argument type */ | ||
| 34 | + RETURN_ERROR_IF_NONNUMERIC(r, arg[0]); | ||
| 35 | + | ||
| 36 | + while (i <= j) | ||
| 37 | + { | ||
| 38 | + if (a == i*j) | ||
| 39 | + { | ||
| 40 | + r.v.int_val += 1 + (i!=j); | ||
| 41 | + } | ||
| 42 | + i++; | ||
| 43 | + j=a/i; | ||
| 44 | + } | ||
| 45 | + | ||
| 46 | + return r; | ||
| 47 | + } | ||
| 48 | + | ||
| 49 | + DLLEXPORT struct value sinc(int nargs, struct value *arg, void *p) | ||
| 50 | + { | ||
| 51 | + double x = RVAL(arg[0]); | ||
| 52 | + struct value r; | ||
| 53 | + r.type = CMPLX; | ||
| 54 | + | ||
| 55 | + /* Enforce a match between the number of parameters declared | ||
| 56 | + * by the gnuplot import command and the number implemented here. | ||
| 57 | + */ | ||
| 58 | + RETURN_ERROR_IF_WRONG_NARGS(r, nargs, 1); | ||
| 59 | + | ||
| 60 | + /* Sanity check on argument type */ | ||
| 61 | + RETURN_ERROR_IF_NONNUMERIC(r, arg[0]); | ||
| 62 | + | ||
| 63 | + r.v.cmplx_val.real = sin(x)/x; | ||
| 64 | + r.v.cmplx_val.imag = 0.0; | ||
| 65 | + | ||
| 66 | + return r; | ||
| 67 | + } | ||
| 68 | + | ||
| 69 | + DLLEXPORT struct value nsinc(int nargs, struct value *arg, void *p) | ||
| 70 | + { | ||
| 71 | + struct value r; | ||
| 72 | + int n; /* 1st parameter */ | ||
| 73 | + double x; /* 2nd parameter */ | ||
| 74 | + | ||
| 75 | + /* Enforce a match between the number of parameters declared | ||
| 76 | + * by the gnuplot import command and the number implemented here. | ||
| 77 | + */ | ||
| 78 | + RETURN_ERROR_IF_WRONG_NARGS(r, nargs, 2); | ||
| 79 | + | ||
| 80 | + /* Sanity check on argument type */ | ||
| 81 | + RETURN_ERROR_IF_NONNUMERIC(r, arg[0]); | ||
| 82 | + RETURN_ERROR_IF_NONNUMERIC(r, arg[1]); | ||
| 83 | + | ||
| 84 | + n = IVAL(arg[0]); | ||
| 85 | + x = RVAL(arg[1]); | ||
| 86 | + | ||
| 87 | + r.type = CMPLX; | ||
| 88 | + r.v.cmplx_val.real = n * sin(x)/x; | ||
| 89 | + r.v.cmplx_val.imag = 0.0; | ||
| 90 | + | ||
| 91 | + return r; | ||
| 92 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,51 @@ | |||
| 1 | + | ||
| 2 | + #include <gp_types.h> | ||
| 3 | + | ||
| 4 | + #ifdef WIN32 | ||
| 5 | + # define DLLEXPORT __declspec(dllexport) | ||
| 6 | + # define __inline__ __inline | ||
| 7 | + #else | ||
| 8 | + # define DLLEXPORT | ||
| 9 | + #endif | ||
| 10 | + | ||
| 11 | + /* prototype for a plugin function */ | ||
| 12 | + DLLEXPORT void *gnuplot_init(struct value(*)(int, struct value *, void *)); | ||
| 13 | + DLLEXPORT void gnuplot_fini(void *); | ||
| 14 | + | ||
| 15 | + /* Check that the number of parameters declared in the gnuplot import | ||
| 16 | + * statement matches the actual number of parameters in the exported | ||
| 17 | + * function | ||
| 18 | + */ | ||
| 19 | + #define RETURN_ERROR_IF_WRONG_NARGS(r, nargs, ACTUAL_NARGS) \ | ||
| 20 | + if (nargs != ACTUAL_NARGS) { \ | ||
| 21 | + r.type = INVALID_VALUE; \ | ||
| 22 | + return r; \ | ||
| 23 | + } | ||
| 24 | + | ||
| 25 | + #define RETURN_ERROR_IF_NONNUMERIC(r, arg) \ | ||
| 26 | + if (arg.type != CMPLX && arg.type != INTGR) { \ | ||
| 27 | + r.type = INVALID_VALUE; \ | ||
| 28 | + return r; \ | ||
| 29 | + } | ||
| 30 | + | ||
| 31 | + __inline__ static double RVAL(struct value v) | ||
| 32 | + { | ||
| 33 | + if (v.type == CMPLX) | ||
| 34 | + return v.v.cmplx_val.real; | ||
| 35 | + else if (v.type == INTGR) | ||
| 36 | + return (double) v.v.int_val; | ||
| 37 | + else | ||
| 38 | + return 0; /* precluded by sanity check above */ | ||
| 39 | + } | ||
| 40 | + | ||
| 41 | + __inline__ static int IVAL(struct value v) | ||
| 42 | + { | ||
| 43 | + if (v.type == CMPLX) | ||
| 44 | + return (int)v.v.cmplx_val.real; | ||
| 45 | + else if (v.type == INTGR) | ||
| 46 | + return v.v.int_val; | ||
| 47 | + else | ||
| 48 | + return 0; /* precluded by sanity check above */ | ||
| 49 | + } | ||
| 50 | + | ||
| 51 | + #undef NaN | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,43 @@ | |||
| 1 | + # | ||
| 2 | + # demo for the use of external functions | ||
| 3 | + # | ||
| 4 | + if (!strstrt(GPVAL_COMPILE_OPTIONS,"+EXTERNAL_FUNCTIONS")) { | ||
| 5 | + print ">>> Skipping demo <<<\n" ; | ||
| 6 | + print "This copy of gnuplot does not support import of external functions" | ||
| 7 | + exit | ||
| 8 | + } | ||
| 9 | + | ||
| 10 | + # This will look for an exported routined named divisors | ||
| 11 | + # in shared object example.so | ||
| 12 | + set title "import divisors from 'sharedobject'" | ||
| 13 | + import divisors(x) from "demo_plugin" | ||
| 14 | + set samples 10001, 10001 | ||
| 15 | + plot [0:10000] divisors(x) w his | ||
| 16 | + | ||
| 17 | + pause -1 "<cr> to continue" | ||
| 18 | + | ||
| 19 | + # This will cause future invocations of g(x) to call the | ||
| 20 | + # routine sinc(x) contained in shared object example.so | ||
| 21 | + # I.e. g(x) is an alias for an external function sinc(x) | ||
| 22 | + set title "import g(x) from 'sharedobject:sinc'" | ||
| 23 | + import g(x) from "demo_plugin:sinc" | ||
| 24 | + plot [-20:20] g(x) | ||
| 25 | + | ||
| 26 | + pause -1 "<cr> to continue" | ||
| 27 | + | ||
| 28 | + # compare internal and external implementations of sinc(x) | ||
| 29 | + set title "Compare internal and external implementations of sinc" | ||
| 30 | + set samples 250 | ||
| 31 | + sinc(x) = sin(x) / x | ||
| 32 | + plot sinc(x) - g(x) | ||
| 33 | + | ||
| 34 | + pause -1 "<cr> to continue" | ||
| 35 | + | ||
| 36 | + # Similar to above but using a 2-parameter function | ||
| 37 | + set title "Import a 2-parameter function" | ||
| 38 | + import nsinc(N,x) from "demo_plugin:nsinc" | ||
| 39 | + plot for [N=1:5] nsinc(N,x) lw 2 title sprintf("nsinc(%d,x)",N) | ||
| 40 | + | ||
| 41 | + pause -1 "<cr> to continue" | ||
| 42 | + | ||
| 43 | + reset | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,4 +1,4 @@ | |||
| 1 | - C RCS $Id: gnuplot.doc,v 1.853 2014/02/25 06:04:36 sfeam Exp $ | ||
| 1 | + C RCS $Id: gnuplot.doc,v 1.854 2014/02/27 07:57:50 markisch Exp $ | ||
| 2 | 2 | C | |
| 3 | 3 | C Copyright (C) 1986 - 1993, 1998, 1999, 2000, 2001, 2004 Thomas Williams, Colin Kelley et al. | |
| 4 | 4 | C | |
@@ -260,6 +260,11 @@ C | |||
| 260 | 260 | math routines cerf, cdawson, erfi, faddeeva, and the Voigt profile | |
| 261 | 261 | VP(x,sigma,gamma). | |
| 262 | 262 | ||
| 263 | + * The `import` command attaches a user-defined function name to a function | ||
| 264 | + exported by an external shared object (support is operating-system dependent). | ||
| 265 | + A template header and example source and make files for creating a suitable | ||
| 266 | + external shared object are provided in the demo collection. | ||
| 267 | + | ||
| 263 | 268 | 2 Deprecated syntax | |
| 264 | 269 | ?deprecated syntax | |
| 265 | 270 | ?backwards compatibility | |
@@ -4866,6 +4871,32 @@ Ffigure_mapcontours | |||
| 4866 | 4871 | set for [i=1:9] for [j=1:9] label i*10+j sprintf("%d",i*10+j) at i,j | |
| 4867 | 4872 | ||
| 4868 | 4873 | See additional documentation for `iteration`, `do`. | |
| 4874 | + 2 import | ||
| 4875 | + ?commands import | ||
| 4876 | + ?import | ||
| 4877 | + The `import` command associates a user-defined function name with a function | ||
| 4878 | + exported by an external shared object. This constitutes a plugin mechanism | ||
| 4879 | + that extends the set of functions available in gnuplot. | ||
| 4880 | + | ||
| 4881 | + Syntax: | ||
| 4882 | + import func(x[,y,z,...]) from "sharedobj[:symbol]" | ||
| 4883 | + | ||
| 4884 | + Examples: | ||
| 4885 | + # make the function myfun, exported by "mylib.so" or "mylib.dll" | ||
| 4886 | + # available for plotting or numerical calculation in gnuplot | ||
| 4887 | + import myfun(x) from "mylib" | ||
| 4888 | + import myfun(x) from "mylib:myfun" # same as above | ||
| 4889 | + | ||
| 4890 | + # make the function theirfun, defined in "theirlib.so" or "theirlib.dll" | ||
| 4891 | + # available under a different name | ||
| 4892 | + import myfun(x,y,z) from "theirlib:theirfun" | ||
| 4893 | + | ||
| 4894 | + The program extends the name given for the shared object by either ".so" or | ||
| 4895 | + ".dll" depending on the operating system, and searches for it first as a full | ||
| 4896 | + path name and then as a path relative to the current directory. The operating | ||
| 4897 | + system itself may also search any directories in LD_LIBRARY_PATH or | ||
| 4898 | + DYLD_LIBRARY_PATH. | ||
| 4899 | + | ||
| 4869 | 4900 | 2 load | |
| 4870 | 4901 | ?commands load | |
| 4871 | 4902 | ?load | |
| Back | FazBrowse Home | New Git URL |
0 commit comments