|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376 |
- /* Copyright (C) 2011-2024 Patrick H. E. Foubet - S.E.R.I.A.N.E.
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or any
- later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>
- *******************************************************************/
- /* liste des fonctions liees a gnuplot */
- /* gplot.c */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <signal.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
-
- #include "gplot.h"
- #include "nife.h"
- #include "mth.h"
- #include "stackN.h"
- #include "stackC.h"
- #include "err.h"
- #include "debug.h"
-
- #define GPO_STD 0 /* standard */
- #define GPO_MRG 0x100 /* merge */
-
- struct GPlot {
- short id;
- short op;/* options + nb plots */
- FILE *p; /* pipe */
- char *t; /* title */
- char *f; /* file */
- char *a; /* command append */
- int pid; /* pid */
- void *n; /* next */
- };
-
- static short GPid=0;
-
- static void *stackGP = VIDE;
-
- /* file manipulations */
- static void GPF_init(char *f)
- {
- int fd, r, nc;
- r = chdir(".nife");
- if ((fd = creat(f,0600)) != -1) {
- nc=write(fd,"# Nife auto-generated GNUplot file !\n",37);
- close(fd);
- }
- if (r==0) r=chdir("..");
- }
-
- static void GPF_del(char *f)
- {
- unlink(f);
- }
-
- static void GPF_supL(char * f, int n)
- {
- void * M;
- char *f2;
- char l[512];
- FILE *fIn, *fOut;
- int i=1;
- if ((M = malloc(strlen(f)+5)) == NULL) stopErr("GPF_supL","malloc");
- f2 = (char*)M;
- strcpy(f2,f);
- f2 += strlen(f);
- strcpy(f2,".wni");
- f2 = (char*)M;
- if ((fIn = fopen(f, "r")) != NULL) {
- if ((fOut = fopen(f2, "w")) != NULL) {
- while (fgets(l, sizeof(l), fIn)) {
- if (i != n) fputs(l, fOut);
- i++;
- }
- fclose(fOut);
- }
- fclose(fIn);
- rename(f2, f);
- }
- free(M);
- }
-
- /* struct GPlot functions */
-
- static void eraseGP(struct GPlot *F)
- {
- GPF_del(F->f);
- free((void*)F->t);
- free((void*)F->f);
- if (F->a != NULL) free((void*)F->a);
- free((void*)F);
- }
-
- static void GP_initial(struct GPlot * N)
- {
- fprintf(N->p, "set term x11 title \"Nife GPlot %d\" size 400,300\n", N->id);
- fprintf(N->p, "unset mouse\n");
- }
-
- static void GP_create(short op, char *T, char *F)
- {
- int pid, p[2];
- void * M;
- struct GPlot *N;
- if ((M = malloc(sizeof(struct GPlot)))==NULL) stopErr("GP_create","malloc");
- N = (struct GPlot*)M;
- N->id = ++GPid;
- N->op = op;
- N->t = T;
- N->f = F;
- N->a = NULL;
- N->n = stackGP;
- GPF_init(N->f);
- /* Old method **********
- N->p = popen("gnuplot -p -raise","w");
- *********/
- if (pipe(p) != 0) stopErr("GP_create","pipe");
- N->p = fdopen(p[1], "w"); /* w side */
- if ((pid = fork()) == -1) {
- fprintf(stderr,"GP_create : error fork !\n");
- eraseGP(N);
- } else {
- if (pid == 0) { /* fils */
- dup2(p[0],0);
- close(p[0]);
- close(p[1]);
- _MODIF_inSonProc_(1);
- setsid();
- execlp("gnuplot", "Nife_gplot", "-p", "-raise", NULL);
- perror("gnuplot");
- exit(1);
- } else {
- N->pid = pid;
- close(p[0]);
- stackGP = M;
- GP_initial(N);
- }
- }
- }
-
- static void GP_del(short id)
- {
- void ** PNext;
- struct GPlot * N;
- PNext = &stackGP;
- while (*PNext != VIDE) {
- N = (struct GPlot*) *PNext;
- if (N->id == id) {
- *PNext = N->n;
- /* stop gnuplot */
- fprintf(N->p,"exit\n");
- fflush(N->p);
- kill(N->pid,SIGKILL);
- eraseGP(N);
- return;
- }
- PNext = &N->n;
- }
- messErr(42);
- }
-
- void IF_delAllGP(void)
- {
- struct GPlot * N;
- while (stackGP != VIDE) {
- N = (struct GPlot*) stackGP;
- stackGP = N->n;
- /* stop gnuplot */
- fprintf(N->p,"exit\n");
- fflush(N->p);
- kill(N->pid,SIGKILL);
- eraseGP(N);
- }
- GPid=0;
- }
-
- static struct GPlot * GP_getPlot(short id)
- {
- void ** PNext;
- struct GPlot * N;
- PNext = &stackGP;
- while (*PNext != VIDE) {
- N = (struct GPlot*) *PNext;
- if (N->id == id) {
- return N;
- }
- PNext = &N->n;
- }
- messErr(42);
- return NULL;
- }
-
-
- static void GP_plot(struct GPlot * N)
- {
- int i;
- fprintf(N->p, "set term x11 title \"Nife GPlot %d\"\n", N->id);
- fprintf(N->p, "plot ");
- for (i=0; i<(N->op&0xFF); i++) {
- if (i) fprintf(N->p,", ");
- fprintf(N->p,"\"%s\" using 1:%d title \"",N->f, i+2);
- if (i) fprintf(N->p,"col %d",i+1);
- else fprintf(N->p,"%s",N->t);
- fprintf(N->p,"\" with lines ");
- if (N->a != NULL) fprintf(N->p,"%s",N->a);
- }
- fprintf(N->p,"\n");
- fflush(N->p);
- }
-
- static void GP_updApp(short id, char * a)
- {
- struct GPlot * N;
- if ((N = GP_getPlot(id)) != NULL) {
- if (N->a != NULL) free((void*)N->a);
- N->a = a;
- /* redraw gnuplot */
- GP_plot(N);
- return;
- }
- free((void*)a);
- }
-
- static void GP_addData(short id)
- {
- struct GPlot * N;
- FILE *fd;
- if ((N = GP_getPlot(id)) != NULL) {
- /* Add data to file */
- fd = fopen(N->f,"a");
- IF_inFile_1d(fd, ' ', 0);
- fclose(fd);
- /* redraw gnuplot */
- GP_plot(N);
- }
- }
-
- static void GP_replData(short id)
- {
- struct GPlot * N;
- FILE *fd;
- if ((N = GP_getPlot(id)) != NULL) {
- /* delete the second line */
- GPF_supL(N->f,2);
- /* Add data to file */
- fd = fopen(N->f,"a");
- IF_inFile_1d(fd, ' ', 0);
- fclose(fd);
- /* redraw gnuplot */
- GP_plot(N);
- }
- }
-
- void IF_gplot_new(void)
- {
- char *t, *f;
- if (!isNString(2)) {
- messErr(6);
- return;
- }
- t = getString();
- f = getString();
- GP_create(GPO_STD|1,t,f);
- }
-
- void IF_gplot_newM(void)
- {
- char *t, *f;
- long n;
- if (getParLong(&n)) {
- if (!isNString(2)) {
- messErr(6);
- return;
- }
- t = getString();
- f = getString();
- GP_create(GPO_STD|(short)n,t,f);
- }
- }
-
- void IF_gplot_del(void)
- {
- long t;
- if (getParLong(&t)) {
- GP_del((short)t);
- }
- }
-
- void IF_gplot_clear(void)
- {
- long t;
- struct GPlot * N;
- if (getParLong(&t)) {
- if ((N = GP_getPlot((short)t)) != NULL) {
- GPF_init(N->f);
- /* redraw gnuplot */
- GP_plot(N);
- }
- }
- }
-
- void IF_gplot_commapp(void)
- {
- long t;
- char *a;
- if (getParLong(&t)) {
- if (!isNString(1)) {
- messErr(6);
- return;
- }
- a = getString();
- GP_updApp((short)t,a);
- }
- }
-
- void IF_gplot_append(void)
- {
- long t;
- if (getParLong(&t)) {
- if (!is1Tab()) {
- messErr(12);
- return;
- }
- GP_addData((short)t);
- }
- }
-
- void IF_gplot_replace(void)
- {
- long t;
- if (getParLong(&t)) {
- if (!is1Tab()) {
- messErr(12);
- return;
- }
- GP_replData((short)t);
- }
- }
-
- void IF_show_stackGP(void)
- {
- void * Next;
- struct GPlot * N;
- if (stackGP != VIDE)
- printf(" id |NbP| filename | Title | Options\n");
- Next = stackGP;
- while (Next != VIDE) {
- N = (struct GPlot*) Next;
- printf("%5d|%3d|%-12s|%-25s|%s\n",N->id,N->op&0xFF,N->f, N->t, N->a);
- Next = N->n;
- }
- printf("<end of GNUPlot list>\n");
- }
-
- void IFD_show_stackGP(void)
- {
- _IFD_BEGIN_
- IF_show_stackGP();
- _IFD_END_
- }
-
-
|