diff --git a/ChangeLog b/ChangeLog
index a5e279fd9..6c701aaad 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2008-03-22 Paolo Nenzi
+ * src/frontend/{commands.c, com_gnuplot.c, com_gnuplot.h},
+ * src/frontend/plotting/{gnuplot.c, gnuplot.h,plotit.c}: added
+ initial support for gnuplot plotting of simulation outputs.
+ Gnuplot interface code has been sent by Stefano Pedretti.
+
2008-01-19 Dietmar Warning
* configure.in: w/o optimization better debug
* src/main.c: fix conflict for own shutdown function
diff --git a/src/frontend/Makefile.am b/src/frontend/Makefile.am
index 0a417607d..48261dfd6 100644
--- a/src/frontend/Makefile.am
+++ b/src/frontend/Makefile.am
@@ -31,6 +31,8 @@ libfte_a_SOURCES = \
com_echo.h \
com_ghelp.c \
com_ghelp.h \
+ com_gnuplot.h \
+ com_gnuplot.c \
com_hardcopy.c \
com_hardcopy.h \
com_help.c \
diff --git a/src/frontend/com_gnuplot.c b/src/frontend/com_gnuplot.c
new file mode 100644
index 000000000..392513ae0
--- /dev/null
+++ b/src/frontend/com_gnuplot.c
@@ -0,0 +1,41 @@
+#include
+
+#include
+#include
+#include
+
+#include "plotting/plotit.h"
+
+#include "com_gnuplot.h"
+
+
+/* gnuplot file plotargs */
+void
+com_gnuplot(wordlist *wl)
+{
+ char *fname;
+ bool tempf = FALSE;
+
+ if (wl) {
+ fname = wl->wl_word;
+ wl = wl->wl_next;
+ }
+ if (!wl) {
+ return;
+ }
+ if (cieq(fname, "temp") || cieq(fname, "tmp")) {
+ fname = smktemp("gp"); /* Is this the correct name ? */
+ tempf = TRUE;
+ }
+
+ (void) plotit(wl, fname, "gnuplot");
+
+#if 0
+ /* Leave temp file sitting around so gnuplot can grab it from
+ background. */
+ if (tempf)
+ (void) unlink(fname);
+#endif
+
+ return;
+}
diff --git a/src/frontend/com_gnuplot.h b/src/frontend/com_gnuplot.h
new file mode 100644
index 000000000..255d5717f
--- /dev/null
+++ b/src/frontend/com_gnuplot.h
@@ -0,0 +1,6 @@
+#ifndef _COM_GNUPLOT_H
+#define _COM_GNUPLOT_H
+
+void com_gnuplot(wordlist *wl);
+
+#endif
diff --git a/src/frontend/commands.c b/src/frontend/commands.c
index 5f0f9edd1..94069f20c 100644
--- a/src/frontend/commands.c
+++ b/src/frontend/commands.c
@@ -48,6 +48,7 @@
#include "com_plot.h"
#include "com_setscale.h"
#include "com_xgraph.h"
+#include "com_gnuplot.h"
#include "com_state.h"
#include "com_chdir.h"
#include "com_echo.h"
@@ -149,6 +150,10 @@ struct comm spcp_coms[] = {
{ 1, 041000, 041000, 041000 }, E_DEFHMASK, 1, LOTS,
(void (*)()) NULL,
"file plotargs : Send plot to Xgraph-11." } ,
+ { "gnuplot", com_gnuplot, FALSE, FALSE, TRUE,
+ { 1, 041000, 041000, 041000 }, E_DEFHMASK, 1, LOTS,
+ (void (*)()) NULL,
+ "file plotargs : Send plot to gnuplot." } ,
{ "hardcopy", com_hardcopy, FALSE, FALSE, TRUE,
{ 1, 041000, 041000, 041000 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
@@ -540,6 +545,10 @@ struct comm nutcp_coms[] = {
{ 1, 041000, 041000, 041000 }, E_DEFHMASK, 1, LOTS,
(void (*)()) NULL,
"file plotargs : Send plot to Xgraph-11." } ,
+ { "gnuplot", com_gnuplot, FALSE, FALSE, TRUE,
+ { 1, 041000, 041000, 041000 }, E_DEFHMASK, 1, LOTS,
+ (void (*)()) NULL,
+ "file plotargs : Send plot to gnuplot." } ,
{ "hardcopy", com_hardcopy, FALSE, FALSE, TRUE,
{ 1, 041000, 041000, 041000 }, E_DEFHMASK, 0, LOTS,
(void (*)()) NULL,
diff --git a/src/frontend/plotting/Makefile.am b/src/frontend/plotting/Makefile.am
index ec152081e..90aef1c6a 100644
--- a/src/frontend/plotting/Makefile.am
+++ b/src/frontend/plotting/Makefile.am
@@ -7,6 +7,8 @@ libplotting_a_SOURCES = \
agraf.h \
clip.c \
clip.h \
+ gnuplot.c \
+ gnuplot.h \
graf.c \
graf.h \
graphdb.c \
diff --git a/src/frontend/plotting/gnuplot.c b/src/frontend/plotting/gnuplot.c
new file mode 100644
index 000000000..6a33707ec
--- /dev/null
+++ b/src/frontend/plotting/gnuplot.c
@@ -0,0 +1,203 @@
+/**********
+ * From xgraph.c:
+ * Copyright 1992 Regents of the University of California. All rights reserved.
+ * Author: 1992 David A. Gates, U. C. Berkeley CAD Group
+ *
+ * Author: 2008 Stefano Pedretti
+**********/
+
+/*
+ * gnuplot plots.
+ */
+
+#include "ngspice.h"
+#include "cpdefs.h"
+#include "ftedefs.h"
+#include "dvec.h"
+#include "fteparse.h"
+#include "gnuplot.h"
+
+#include
+
+#define GP_MAXVECTORS 64
+
+void
+ft_gnuplot(double *xlims, double *ylims, char *filename, char *title, char *xlabel, char *ylabel, GRIDTYPE gridtype, PLOTTYPE plottype, struct dvec *vecs)
+{
+
+ FILE *file, *file_data;
+ struct dvec *v, *scale;
+ double xval, yval;
+ int i, numVecs, linewidth;
+ bool xlog, ylog, nogrid, markers;
+ char buf[BSIZE_SP], pointstyle[BSIZE_SP], *text;
+
+ char filename_data[15];
+ sprintf(filename_data, "%s.data", filename);
+
+
+ /* Sanity checking. */
+ for ( v = vecs, numVecs = 0; v; v = v->v_link2 ) {
+ numVecs++;
+ }
+ if (numVecs == 0) {
+ return;
+ } else if (numVecs > GP_MAXVECTORS) {
+ fprintf( cp_err, "Error: too many vectors for gnuplot.\n" );
+ return;
+ }
+ if (!cp_getvar("xbrushwidth", VT_NUM, &linewidth))
+ linewidth = 1;
+ if (linewidth < 1) linewidth = 1;
+
+ if (!cp_getvar("pointstyle", VT_STRING, pointstyle)) {
+ markers = FALSE;
+ } else {
+ if (cieq(pointstyle,"markers")) {
+ markers = TRUE;
+ } else {
+ markers = FALSE;
+ }
+ }
+
+
+ /* Make sure the gridtype is supported. */
+ switch (gridtype) {
+ case GRID_LIN:
+ nogrid = xlog = ylog = FALSE;
+ break;
+ case GRID_XLOG:
+ xlog = TRUE;
+ nogrid = ylog = FALSE;
+ break;
+ case GRID_YLOG:
+ ylog = TRUE;
+ nogrid = xlog = FALSE;
+ break;
+ case GRID_LOGLOG:
+ xlog = ylog = TRUE;
+ nogrid = FALSE;
+ break;
+ case GRID_NONE:
+ nogrid = TRUE;
+ xlog = ylog = FALSE;
+ break;
+ default:
+ fprintf( cp_err, "Error: grid type unsupported by gnuplot.\n" );
+ return;
+ }
+
+ /* Open the output gnuplot file. */
+ if (!(file = fopen(filename, "w"))) {
+ perror(filename);
+ return;
+ }
+
+ /* Set up the file header. */
+ if (title) {
+ text = cp_unquote(title);
+ fprintf( file, "set title \"%s\"\n", text );
+ tfree(text);
+ }
+ if (xlabel) {
+ text = cp_unquote(xlabel);
+ fprintf( file, "set xlabel \"%s\"\n", text );
+ tfree(text);
+ }
+ if (ylabel) {
+ text = cp_unquote(ylabel);
+ fprintf( file, "set ylabel \"%s\"\n", text );
+ tfree(text);
+ }
+ if (nogrid) {
+ fprintf( file, "set grid\n" );
+ }
+ if (xlog) {
+ fprintf( file, "set logscale x\n" );
+ if (xlims) {
+ fprintf( file, "set xrange [% e: % e]\n", log10(xlims[0]),log10(xlims[1]) );
+ }
+ } else {
+ fprintf( file, "unset logscale x \n" );
+ if (xlims) {
+ fprintf( file, "set xrange [% e: % e]\n", xlims[0],xlims[1] );
+ }
+ }
+ if (ylog) {
+ fprintf( file, "set logscale y \n" );
+ if (ylims) {
+ fprintf( file, "set yrange [% e: % e]\n", log10(ylims[0]),log10(ylims[1]) );
+ }
+ } else {
+ fprintf( file, "unset logscale y \n" );
+ if (ylims) {
+ fprintf( file, "set yrange [% e: % e]\n", ylims[0],ylims[1] );
+ }
+ }
+
+ fprintf( file, "#set xtics 1\n" );
+ fprintf( file, "#set x2tics 1\n" );
+ fprintf( file, "#set ytics 1\n" );
+ fprintf( file, "#set y2tics 1\n" );
+
+/* TODO
+ fprintf( file, "LineWidth: %d\n", linewidth );
+ if (plottype == PLOT_COMB) {
+ fprintf( file, "BarGraph: True\n" );
+ fprintf( file, "NoLines: True\n" );
+ } else if (plottype == PLOT_POINT) {
+ if (markers) {
+ fprintf( file, "Markers: True\n" );
+ } else {
+ fprintf( file, "LargePixels: True\n" );
+ }
+ fprintf( file, "NoLines: True\n" );
+ }
+*/
+
+ /* Open the output gnuplot data file. */
+
+ if (!(file_data = fopen(filename_data, "w"))) {
+ perror(filename);
+ return;
+ }
+
+ fprintf( file, "plot ", v->v_name );
+ i = 0;
+
+ /* Write out the data and setup arrays */
+ for ( v = vecs; v; v = v->v_link2 ) {
+ scale = v->v_scale;
+ if (v->v_name) {
+ i= i+2;
+ fprintf( file, "\'%s\' using %d:%d with lines t \"%s\" ,", filename_data , i , i+1 , v->v_name );
+ }
+ }
+ fprintf( file, "\n");
+ fprintf (file, "set terminal postscript eps\nset out %s.eps\nreplot\nset term pop", filename);
+
+ for ( i = 0; i < scale->v_length; i++ ) {
+ for ( v = vecs; v; v = v->v_link2 ) {
+ scale = v->v_scale;
+
+ xval = isreal(scale) ?
+ scale->v_realdata[i] : realpart(&scale->v_compdata[i]);
+
+ yval = isreal(v) ?
+ v->v_realdata[i] : realpart(&v->v_compdata[i]);
+
+ fprintf( file_data, "% e % e ", xval, yval );
+ }
+ fprintf( file_data, "\n");
+ }
+
+
+ (void) fclose( file );
+ (void) fclose( file_data );
+
+ (void) sprintf( buf, "gnuplot %s &", filename );
+ (void) system( buf );
+
+
+ return;
+}
diff --git a/src/frontend/plotting/gnuplot.h b/src/frontend/plotting/gnuplot.h
new file mode 100644
index 000000000..afc84c17c
--- /dev/null
+++ b/src/frontend/plotting/gnuplot.h
@@ -0,0 +1,16 @@
+/*************
+ * Header file for gnuplot.c
+ * 2008 Stefano Pedretti
+ ************/
+
+#ifndef GNUPLOT_H_INCLUDED
+#define GNUPLOT_H_INCLUDED
+
+void ft_gnuplot(double *xlims, double *ylims, char *filename, char *title,
+ char *xlabel, char *ylabel, GRIDTYPE gridtype, PLOTTYPE plottype,
+ struct dvec *vecs);
+
+
+
+
+#endif
diff --git a/src/frontend/plotting/plotit.c b/src/frontend/plotting/plotit.c
index a10445557..8557a009f 100644
--- a/src/frontend/plotting/plotit.c
+++ b/src/frontend/plotting/plotit.c
@@ -14,6 +14,7 @@
#include "plotit.h"
#include "agraf.h"
#include "xgraph.h"
+#include "gnuplot.h"
#include "graf.h"
static wordlist *wl_root;
@@ -960,6 +961,20 @@ plotit(wordlist *wl, char *hcopy, char *devname)
rtn = TRUE;
goto quit;
}
+
+
+ if (devname && eq(devname, "gnuplot")) {
+ /* Interface to XGraph-11 Plot Program */
+ ft_gnuplot(xlims, ylims, hcopy,
+ title ? title : vecs->v_plot->pl_title,
+ xlabel ? xlabel : ft_typabbrev(vecs->v_scale->v_type),
+ ylabel ? ylabel : ft_typabbrev(j),
+ gtype, ptype, vecs);
+ rtn = TRUE;
+ goto quit;
+ }
+
+
for (d = vecs, i = 0; d; d = d->v_link2)
i++;