diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..2c1d6f0 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,24 @@ +cmake_minimum_required(VERSION 3.12...3.27) + +project(gnuplot_i + DESCRIPTION "A gnuplot interface library written in C." + LANGUAGES C +) + +# This project is an OBJECT-library, used by other git submodules and the main project. +add_library(gnuplot_i_ObjLib OBJECT) + +# The list of source files. +target_sources(gnuplot_i_ObjLib + PRIVATE + "gnuplot_i.c" + "gnuplot_i.h" +) + +target_include_directories(gnuplot_i_ObjLib + INTERFACE + "${CMAKE_CURRENT_SOURCE_DIR}" +) + +# Create an ALIAS target. +add_library(gnuplot_i::gnuplot_i ALIAS gnuplot_i_ObjLib) diff --git a/examples/example.c b/examples/example.c index c3db5be..a215c08 100644 --- a/examples/example.c +++ b/examples/example.c @@ -174,7 +174,7 @@ int main(int argc, char *argv[]) { h3 = gnuplot_init(); gnuplot_setstyle(h3, "filledcurves"); printf("window 1: x*sin(x)\n"); - gnuplot_cmd(h1, "set linecolor rgb 'blue'"); // this does not work yet + gnuplot_cmd(h1, "set style line 1 lc rgb 'blue'"); // Still not working, but doesn't print an error anymore. gnuplot_plot_equation(h1, "x*sin(x)", "x*sin(x)"); sleep(SECONDS); printf("window 2: log(x)/x\n"); diff --git a/gnuplot_i.c b/gnuplot_i.c old mode 100755 new mode 100644 index e8ecd0e..ae175c5 --- a/gnuplot_i.c +++ b/gnuplot_i.c @@ -79,7 +79,7 @@ */ /*-------------------------------------------------------------------------*/ -int mkstemp (char *name) { +int mkstemp (char const* name) { srand(time(NULL)); int i; char *start = strstr(name, "XXXXXX"); @@ -125,9 +125,9 @@ int mkstemp (char *name) { */ /*-------------------------------------------------------------------------*/ -char *gnuplot_get_program_path (char *pname) { +char const* gnuplot_get_program_path (char const* pname) { int i, j, lg; - char *path; + char const* path; static char buf[PATH_MAXNAMESZ]; /* Trivial case: try in current working directory */ @@ -297,7 +297,7 @@ void gnuplot_close (gnuplot_ctrl *handle) { */ /*--------------------------------------------------------------------------*/ -void gnuplot_cmd (gnuplot_ctrl *handle, char *cmd, ...) { +void gnuplot_cmd (gnuplot_ctrl *handle, char const* cmd, ...) { va_list ap; char local_cmd[GP_CMD_SIZE]; @@ -310,6 +310,26 @@ void gnuplot_cmd (gnuplot_ctrl *handle, char *cmd, ...) { return; } +void send_plot_cmd(gnuplot_ctrl* handle, char* cmd, char const* name, char const* title) +{ + char const* command = (handle->nplots > 0) ? "replot" : "plot"; + if (title) + sprintf(cmd, "%s \"%s\" title \"%s\" with %s", command, name, title, handle->pstyle); + else + sprintf(cmd, "%s \"%s\" notitle with %s", command, name, handle->pstyle); + gnuplot_cmd(handle, cmd); +} + +void send_splot_cmd(gnuplot_ctrl* handle, char* cmd, char const* name, char const* title) +{ + char const* command = "splot"; + if (title) + sprintf(cmd, "%s \"%s\" title \"%s\" with %s", command, name, title, handle->pstyle); + else + sprintf(cmd, "%s \"%s\" notitle with %s", command, name, handle->pstyle); + gnuplot_cmd(handle, cmd); +} + /*-------------------------------------------------------------------------*/ /** @brief Change the plotting style of a gnuplot session. @@ -330,7 +350,7 @@ void gnuplot_cmd (gnuplot_ctrl *handle, char *cmd, ...) { */ /*--------------------------------------------------------------------------*/ -void gnuplot_setstyle (gnuplot_ctrl *handle, char *plot_style) { +void gnuplot_setstyle (gnuplot_ctrl *handle, char const* plot_style) { if (strcmp(plot_style, "lines") && strcmp(plot_style, "points") && strcmp(plot_style, "linespoints") && @@ -349,6 +369,12 @@ void gnuplot_setstyle (gnuplot_ctrl *handle, char *plot_style) { return; } +void gnuplot_append_style (gnuplot_ctrl *handle, char const* plot_style) { + int len = strlen(handle->pstyle); + strncpy(handle->pstyle + len, plot_style, sizeof(handle->pstyle) - len - 1); + return; +} + /*-------------------------------------------------------------------------*/ /** @brief Change the terminal of a gnuplot session. @@ -371,7 +397,7 @@ void gnuplot_setstyle (gnuplot_ctrl *handle, char *plot_style) { */ /*--------------------------------------------------------------------------*/ -void gnuplot_setterm (gnuplot_ctrl *handle, char *terminal, int width, int height) { +void gnuplot_setterm (gnuplot_ctrl *handle, char const* terminal, int width, int height) { char cmd[GP_CMD_SIZE]; strncpy(handle->term, terminal, 32); @@ -399,7 +425,7 @@ void gnuplot_setterm (gnuplot_ctrl *handle, char *terminal, int width, int heigh */ /*--------------------------------------------------------------------------*/ -void gnuplot_set_axislabel (gnuplot_ctrl *handle, char *axis, char *label) { +void gnuplot_set_axislabel (gnuplot_ctrl *handle, char const* axis, char const* label) { char cmd[GP_CMD_SIZE]; sprintf(cmd, "set %slabel \"%s\"", axis, label); @@ -482,14 +508,13 @@ void gnuplot_i_error (gnuplot_ctrl *handle) { */ /*--------------------------------------------------------------------------*/ -void gnuplot_plot_coordinates (gnuplot_ctrl *handle, double *x, double *y, int n, char *title) { +void gnuplot_plot_coordinates (gnuplot_ctrl *handle, double const* x, double const* y, int n, char const* title) { int tmpfd; char name[NAME_SIZE]; char cmd[GP_CMD_SIZE]; /* Error handling: mandatory arguments, already open session, opening temporary file */ FAIL_IF (x == NULL || (n < 1), "One of the parameters to gnuplot_plot_coordinates() has been misspecified"); - gnuplot_i_error(handle); /* Open temporary file for output */ sprintf(name, GNUPLOT_TEMPFILE, P_tmpdir); @@ -501,14 +526,13 @@ void gnuplot_plot_coordinates (gnuplot_ctrl *handle, double *x, double *y, int n /* Write data to this file */ for (int i = 0; i < n; i++) { - (y == NULL || memcmp(y, y+1, (sizeof(y)-1)*sizeof(y[0])) == 0) ? sprintf(cmd, "%g\n", x[i]) : sprintf(cmd, "%g %g\n", x[i], y[i]); + (y == NULL) ? sprintf(cmd, "%g\n", x[i]) : sprintf(cmd, "%g %g\n", x[i], y[i]); write(tmpfd, cmd, strlen(cmd)); } close(tmpfd); /* Command to be sent to gnuplot */ - sprintf(cmd, "%s \"%s\" title \"%s\" with %s", (handle->nplots > 0) ? "replot" : "plot", name, (title) ? title : "No title" , handle->pstyle); - gnuplot_cmd(handle, cmd); + send_plot_cmd(handle, cmd, name, title); handle->nplots++; } @@ -547,7 +571,7 @@ void gnuplot_plot_coordinates (gnuplot_ctrl *handle, double *x, double *y, int n */ /*--------------------------------------------------------------------------*/ -void gnuplot_splot (gnuplot_ctrl *handle, double *x, double *y, double *z, int n, char *title) { +void gnuplot_splot (gnuplot_ctrl *handle, double const* x, double const* y, double const* z, int n, char const* title) { int tmpfd; char name[NAME_SIZE]; char cmd[GP_CMD_SIZE]; @@ -572,8 +596,7 @@ void gnuplot_splot (gnuplot_ctrl *handle, double *x, double *y, double *z, int n close(tmpfd); /* Command to be sent to gnuplot */ - sprintf(cmd, "splot \"%s\" title \"%s\" with %s", name, (title) ? title : "No title", handle->pstyle); - gnuplot_cmd(handle, cmd); + send_splot_cmd(handle, cmd, name, title); handle->nplots++; } @@ -599,7 +622,7 @@ void gnuplot_splot (gnuplot_ctrl *handle, double *x, double *y, double *z, int n */ /*--------------------------------------------------------------------------*/ -void gnuplot_splot_grid (gnuplot_ctrl *handle, double *points, int rows, int cols, char *title) { +void gnuplot_splot_grid (gnuplot_ctrl *handle, double const* points, int rows, int cols, char const* title) { int tmpfd; char name[NAME_SIZE]; char cmd[GP_CMD_SIZE]; @@ -628,8 +651,7 @@ void gnuplot_splot_grid (gnuplot_ctrl *handle, double *points, int rows, int col close(tmpfd); /* Command to be sent to gnuplot */ - sprintf(cmd, "splot \"%s\" title \"%s\" with %s", name, (title) ? title : "No title", handle->pstyle); - gnuplot_cmd(handle, cmd); + send_splot_cmd(handle, cmd, name, title); handle->nplots++; } @@ -672,7 +694,7 @@ void gnuplot_splot_grid (gnuplot_ctrl *handle, double *points, int rows, int col */ /*--------------------------------------------------------------------------*/ -void gnuplot_contour_plot (gnuplot_ctrl *handle, double *x, double *y, double *z, int nx, int ny, char *title) { +void gnuplot_contour_plot (gnuplot_ctrl *handle, double const* x, double const* y, double const* z, int nx, int ny, char const* title) { int tmpfd; char name[NAME_SIZE]; char cmd[GP_CMD_SIZE]; @@ -707,8 +729,7 @@ void gnuplot_contour_plot (gnuplot_ctrl *handle, double *x, double *y, double *z gnuplot_cmd(handle, "set view 0,0"); /* Command to be sent to gnuplot */ - sprintf(cmd, "splot \"%s\" title \"%s\" with %s", name, (title) ? title : "No title", handle->pstyle); - gnuplot_cmd(handle, cmd); + send_splot_cmd(handle, cmd, name, title); handle->nplots++; } @@ -733,7 +754,7 @@ void gnuplot_contour_plot (gnuplot_ctrl *handle, double *x, double *y, double *z */ /*--------------------------------------------------------------------------*/ -void gnuplot_splot_obj (gnuplot_ctrl *handle, void *obj, void (*getPoint)(void *, gnuplot_point *, int, int), int n, char *title) { +void gnuplot_splot_obj (gnuplot_ctrl *handle, void *obj, void (*getPoint)(void *, gnuplot_point *, int, int), int n, char const* title) { int tmpfd; char name[NAME_SIZE]; char cmd[GP_CMD_SIZE]; @@ -760,8 +781,7 @@ void gnuplot_splot_obj (gnuplot_ctrl *handle, void *obj, void (*getPoint)(void * close(tmpfd); /* Command to be sent to gnuplot */ - sprintf(cmd, "splot \"%s\" title \"%s\" with %s", name, (title) ? title : "No title", handle->pstyle); - gnuplot_cmd(handle, cmd); + send_splot_cmd(handle, cmd, name, title); handle->nplots++; } @@ -813,14 +833,13 @@ void gnuplot_splot_obj (gnuplot_ctrl *handle, void *obj, void (*getPoint)(void * */ /*-------------------------------------------------------------------------*/ -void gnuplot_plot_obj_xy (gnuplot_ctrl *handle, void *obj, void (*getPoint)(void *, gnuplot_point *, int, int), int n, char *title) { +void gnuplot_plot_obj_xy (gnuplot_ctrl *handle, void *obj, void (*getPoint)(void *, gnuplot_point *, int, int), int n, char const* title) { int tmpfd; char name[NAME_SIZE]; char cmd[GP_CMD_SIZE]; /* Error handling: mandatory arguments, already open session, opening temporary file */ FAIL_IF (getPoint == NULL || (n < 1), "One of the parameters to gnuplot_plot_obj_xy() has been misspecified"); - gnuplot_i_error(handle); /* Open temporary file for output */ sprintf(name, GNUPLOT_TEMPFILE, P_tmpdir); @@ -840,8 +859,7 @@ void gnuplot_plot_obj_xy (gnuplot_ctrl *handle, void *obj, void (*getPoint)(void close(tmpfd); /* Command to be sent to gnuplot */ - sprintf(cmd, "%s \"%s\" title \"%s\" with %s", (handle->nplots > 0) ? "replot" : "plot", name, (title) ? title : "No title", handle->pstyle); - gnuplot_cmd(handle, cmd); + send_plot_cmd(handle, cmd, name, title); handle->nplots++; } @@ -866,7 +884,7 @@ void gnuplot_plot_obj_xy (gnuplot_ctrl *handle, void *obj, void (*getPoint)(void */ /*--------------------------------------------------------------------------*/ -void gnuplot_plot_once (char *style, char *label_x, char *label_y, double *x, double *y, int n, char *title) { +void gnuplot_plot_once (char const* style, char const* label_x, char const* label_y, double const* x, double const* y, int n, char const* title) { /* Define handle as local variable to isolate it from other gnuplot sessions */ gnuplot_ctrl *handle; @@ -909,10 +927,14 @@ void gnuplot_plot_once (char *style, char *label_x, char *label_y, double *x, do */ /*--------------------------------------------------------------------------*/ -void gnuplot_plot_equation (gnuplot_ctrl *handle, char *equation, char *title) { +void gnuplot_plot_equation (gnuplot_ctrl *handle, char const* equation, char const* title) { char cmd[GP_CMD_SIZE]; - sprintf(cmd, "%s %s title \"%s\" with %s", (handle->nplots > 0) ? "replot" : "plot", equation, (title) ? title : "No title", handle->pstyle); + char const* command = (handle->nplots > 0) ? "replot" : "plot"; + if (title) + sprintf(cmd, "%s %s title \"%s\" with %s", command, equation, title, handle->pstyle); + else + sprintf(cmd, "%s %s notitle with %s", command, equation, handle->pstyle); gnuplot_cmd(handle, cmd); handle->nplots++; } @@ -944,7 +966,7 @@ void gnuplot_plot_equation (gnuplot_ctrl *handle, char *equation, char *title) { */ /*--------------------------------------------------------------------------*/ -void gnuplot_hardcopy (gnuplot_ctrl *handle, char *filename, char *color) { +void gnuplot_hardcopy (gnuplot_ctrl *handle, char const* filename, char const* color) { if (color == NULL) { gnuplot_cmd(handle, "set terminal postscript"); } else { diff --git a/gnuplot_i.h b/gnuplot_i.h old mode 100755 new mode 100644 index 463e234..2ec1e33 --- a/gnuplot_i.h +++ b/gnuplot_i.h @@ -23,6 +23,10 @@ /** Maximum amount of characters of a temporary file name */ #define GP_TMP_NAME_SIZE 512 +#ifdef __cplusplus +extern "C" { +#endif + /*--------------------------------------------------------------------------- Gnuplot_i types ---------------------------------------------------------------------------*/ @@ -47,7 +51,7 @@ typedef struct _GNUPLOT_CTRL_ { FILE *gnucmd; /*!< Pipe to gnuplot process. */ int nplots; /*!< Number of currently active plots. */ - char pstyle[32]; /*!< Current plotting style. */ + char pstyle[256]; /*!< Current plotting style. */ char term[32]; /*!< Save terminal name, used by `gnuplot_hardcopy()` function. */ char to_delete[GP_MAX_TMP_FILES][GP_TMP_NAME_SIZE]; /*!< Names of temporary files. */ int ntmp; /*!< Number of temporary files in the current session. */ @@ -77,29 +81,34 @@ typedef struct _GNUPLOT_POINT_ { /* Auxiliary functions */ -char *gnuplot_get_program_path (char *pname); +char const* gnuplot_get_program_path (char const* pname); void print_gnuplot_handle (gnuplot_ctrl *handle); /* Gnuplot interface handling functions */ gnuplot_ctrl *gnuplot_init (void); void gnuplot_close (gnuplot_ctrl *handle); -void gnuplot_cmd (gnuplot_ctrl *handle, char *cmd, ...); -void gnuplot_setstyle (gnuplot_ctrl *handle, char *plot_style); -void gnuplot_setterm (gnuplot_ctrl *handle, char *terminal, int width, int height); -void gnuplot_set_axislabel (gnuplot_ctrl *handle, char *axis, char *label); +void gnuplot_cmd (gnuplot_ctrl *handle, char const* cmd, ...); +void gnuplot_setstyle (gnuplot_ctrl *handle, char const* plot_style); +void gnuplot_append_style (gnuplot_ctrl *handle, char const* plot_style); +void gnuplot_setterm (gnuplot_ctrl *handle, char const* terminal, int width, int height); +void gnuplot_set_axislabel (gnuplot_ctrl *handle, char const* axis, char const* label); void gnuplot_resetplot (gnuplot_ctrl *handle); /* Gnuplot interface plotting functions */ -void gnuplot_plot_coordinates (gnuplot_ctrl *handle, double *x, double *y, int n, char *title); -void gnuplot_splot (gnuplot_ctrl *handle, double *x, double *y, double *z, int n, char *title); -void gnuplot_splot_grid (gnuplot_ctrl *handle, double *points, int rows, int cols, char *title); -void gnuplot_contour_plot (gnuplot_ctrl *handle, double *x, double *y, double *z, int nx, int ny, char *title); -void gnuplot_splot_obj (gnuplot_ctrl *handle, void *obj, void (*getPoint)(void *, gnuplot_point *, int, int), int n, char *title); -void gnuplot_plot_obj_xy (gnuplot_ctrl *handle, void *obj, void (*getPoint)(void *, gnuplot_point *, int, int), int n, char *title); -void gnuplot_plot_once (char *style, char *label_x, char *label_y, double *x, double *y, int n, char *title); -void gnuplot_plot_equation (gnuplot_ctrl *handle, char *equation, char *title); -void gnuplot_hardcopy (gnuplot_ctrl *handle, char *filename, char *color); +void gnuplot_plot_coordinates (gnuplot_ctrl *handle, double const* x, double const* y, int n, char const* title); +void gnuplot_splot (gnuplot_ctrl *handle, double const* x, double const* y, double const* z, int n, char const* title); +void gnuplot_splot_grid (gnuplot_ctrl *handle, double const* points, int rows, int cols, char const* title); +void gnuplot_contour_plot (gnuplot_ctrl *handle, double const* x, double const* y, double const* z, int nx, int ny, char const* title); +void gnuplot_splot_obj (gnuplot_ctrl *handle, void *obj, void (*getPoint)(void *, gnuplot_point *, int, int), int n, char const* title); +void gnuplot_plot_obj_xy (gnuplot_ctrl *handle, void *obj, void (*getPoint)(void *, gnuplot_point *, int, int), int n, char const* title); +void gnuplot_plot_once (char const* style, char const* label_x, char const* label_y, double const* x, double const* y, int n, char const* title); +void gnuplot_plot_equation (gnuplot_ctrl *handle, char const* equation, char const* title); +void gnuplot_hardcopy (gnuplot_ctrl *handle, char const* filename, char const* color); + +#ifdef __cplusplus +} +#endif #endif