Nife version Beta
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

377 lines
7.5 KiB

  1. /* Copyright (C) 2011-2022 Patrick H. E. Foubet - S.E.R.I.A.N.E.
  2. This program is free software: you can redistribute it and/or modify
  3. it under the terms of the GNU General Public License as published by
  4. the Free Software Foundation, either version 3 of the License, or any
  5. later version.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. GNU General Public License for more details.
  10. You should have received a copy of the GNU General Public License
  11. along with this program. If not, see <http://www.gnu.org/licenses/>
  12. *******************************************************************/
  13. /* liste des fonctions liees a gnuplot */
  14. /* gplot.c */
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include <signal.h>
  19. #include <unistd.h>
  20. #include <sys/types.h>
  21. #include <sys/stat.h>
  22. #include <fcntl.h>
  23. #include "gplot.h"
  24. #include "nife.h"
  25. #include "mth.h"
  26. #include "stackN.h"
  27. #include "stackC.h"
  28. #include "err.h"
  29. #include "debug.h"
  30. #define GPO_STD 0 /* standard */
  31. #define GPO_MRG 0x100 /* merge */
  32. struct GPlot {
  33. short id;
  34. short op;/* options + nb plots */
  35. FILE *p; /* pipe */
  36. char *t; /* title */
  37. char *f; /* file */
  38. char *a; /* command append */
  39. int pid; /* pid */
  40. void *n; /* next */
  41. };
  42. static short GPid=0;
  43. static void *stackGP = VIDE;
  44. /* file manipulations */
  45. static void GPF_init(char *f)
  46. {
  47. int fd, r, nc;
  48. r = chdir(".nife");
  49. if ((fd = creat(f,0600)) != -1) {
  50. nc=write(fd,"# Nife auto-generated GNUplot file !\n",37);
  51. close(fd);
  52. }
  53. if (r==0) r=chdir("..");
  54. }
  55. static void GPF_del(char *f)
  56. {
  57. unlink(f);
  58. }
  59. static void GPF_supL(char * f, int n)
  60. {
  61. void * M;
  62. char *f2;
  63. char l[512];
  64. FILE *fIn, *fOut;
  65. int i=1;
  66. if ((M = malloc(strlen(f)+5)) == NULL) stopErr("GPF_supL","malloc");
  67. f2 = (char*)M;
  68. strcpy(f2,f);
  69. f2 += strlen(f);
  70. strcpy(f2,".wni");
  71. f2 = (char*)M;
  72. if ((fIn = fopen(f, "r")) != NULL) {
  73. if ((fOut = fopen(f2, "w")) != NULL) {
  74. while (fgets(l, sizeof(l), fIn)) {
  75. if (i != n) fputs(l, fOut);
  76. i++;
  77. }
  78. fclose(fOut);
  79. }
  80. fclose(fIn);
  81. rename(f2, f);
  82. }
  83. free(M);
  84. }
  85. /* struct GPlot functions */
  86. static void eraseGP(struct GPlot *F)
  87. {
  88. GPF_del(F->f);
  89. free((void*)F->t);
  90. free((void*)F->f);
  91. if (F->a != NULL) free((void*)F->a);
  92. free((void*)F);
  93. }
  94. static void GP_initial(struct GPlot * N)
  95. {
  96. fprintf(N->p, "set term x11 title \"Nife GPlot %d\" size 400,300\n", N->id);
  97. fprintf(N->p, "unset mouse\n");
  98. }
  99. static void GP_create(short op, char *T, char *F)
  100. {
  101. int pid, p[2];
  102. void * M;
  103. struct GPlot *N;
  104. if ((M = malloc(sizeof(struct GPlot)))==NULL) stopErr("GP_create","malloc");
  105. N = (struct GPlot*)M;
  106. N->id = ++GPid;
  107. N->op = op;
  108. N->t = T;
  109. N->f = F;
  110. N->a = NULL;
  111. N->n = stackGP;
  112. GPF_init(N->f);
  113. /* Old method **********
  114. N->p = popen("gnuplot -p -raise","w");
  115. *********/
  116. if (pipe(p) != 0) stopErr("GP_create","pipe");
  117. N->p = fdopen(p[1], "w"); /* w side */
  118. if ((pid = fork()) == -1) {
  119. fprintf(stderr,"GP_create : error fork !\n");
  120. eraseGP(N);
  121. } else {
  122. if (pid == 0) { /* fils */
  123. dup2(p[0],0);
  124. close(p[0]);
  125. close(p[1]);
  126. _MODIF_inSonProc_(1);
  127. setsid();
  128. execlp("gnuplot", "Nife_gplot", "-p", "-raise", NULL);
  129. perror("gnuplot");
  130. exit(1);
  131. } else {
  132. N->pid = pid;
  133. close(p[0]);
  134. stackGP = M;
  135. GP_initial(N);
  136. }
  137. }
  138. }
  139. static void GP_del(short id)
  140. {
  141. void ** PNext;
  142. struct GPlot * N;
  143. PNext = &stackGP;
  144. while (*PNext != VIDE) {
  145. N = (struct GPlot*) *PNext;
  146. if (N->id == id) {
  147. *PNext = N->n;
  148. /* stop gnuplot */
  149. fprintf(N->p,"exit\n");
  150. fflush(N->p);
  151. kill(N->pid,SIGKILL);
  152. eraseGP(N);
  153. return;
  154. }
  155. PNext = &N->n;
  156. }
  157. messErr(42);
  158. }
  159. void IF_delAllGP(void)
  160. {
  161. struct GPlot * N;
  162. while (stackGP != VIDE) {
  163. N = (struct GPlot*) stackGP;
  164. stackGP = N->n;
  165. /* stop gnuplot */
  166. fprintf(N->p,"exit\n");
  167. fflush(N->p);
  168. kill(N->pid,SIGKILL);
  169. eraseGP(N);
  170. }
  171. GPid=0;
  172. }
  173. static struct GPlot * GP_getPlot(short id)
  174. {
  175. void ** PNext;
  176. struct GPlot * N;
  177. PNext = &stackGP;
  178. while (*PNext != VIDE) {
  179. N = (struct GPlot*) *PNext;
  180. if (N->id == id) {
  181. return N;
  182. }
  183. PNext = &N->n;
  184. }
  185. messErr(42);
  186. return NULL;
  187. }
  188. static void GP_plot(struct GPlot * N)
  189. {
  190. int i;
  191. fprintf(N->p, "set term x11 title \"Nife GPlot %d\"\n", N->id);
  192. fprintf(N->p, "plot ");
  193. for (i=0; i<(N->op&0xFF); i++) {
  194. if (i) fprintf(N->p,", ");
  195. fprintf(N->p,"\"%s\" using 1:%d title \"",N->f, i+2);
  196. if (i) fprintf(N->p,"col %d",i+1);
  197. else fprintf(N->p,"%s",N->t);
  198. fprintf(N->p,"\" with lines ");
  199. if (N->a != NULL) fprintf(N->p,"%s",N->a);
  200. }
  201. fprintf(N->p,"\n");
  202. fflush(N->p);
  203. }
  204. static void GP_updApp(short id, char * a)
  205. {
  206. struct GPlot * N;
  207. if ((N = GP_getPlot(id)) != NULL) {
  208. if (N->a != NULL) free((void*)N->a);
  209. N->a = a;
  210. /* redraw gnuplot */
  211. GP_plot(N);
  212. return;
  213. }
  214. free((void*)a);
  215. }
  216. static void GP_addData(short id)
  217. {
  218. struct GPlot * N;
  219. FILE *fd;
  220. if ((N = GP_getPlot(id)) != NULL) {
  221. /* Add data to file */
  222. fd = fopen(N->f,"a");
  223. IF_inFile_1d(fd, ' ', 0);
  224. fclose(fd);
  225. /* redraw gnuplot */
  226. GP_plot(N);
  227. }
  228. }
  229. static void GP_replData(short id)
  230. {
  231. struct GPlot * N;
  232. FILE *fd;
  233. if ((N = GP_getPlot(id)) != NULL) {
  234. /* delete the second line */
  235. GPF_supL(N->f,2);
  236. /* Add data to file */
  237. fd = fopen(N->f,"a");
  238. IF_inFile_1d(fd, ' ', 0);
  239. fclose(fd);
  240. /* redraw gnuplot */
  241. GP_plot(N);
  242. }
  243. }
  244. void IF_gplot_new(void)
  245. {
  246. char *t, *f;
  247. if (!isNString(2)) {
  248. messErr(6);
  249. return;
  250. }
  251. t = getString();
  252. f = getString();
  253. GP_create(GPO_STD|1,t,f);
  254. }
  255. void IF_gplot_newM(void)
  256. {
  257. char *t, *f;
  258. long n;
  259. if (getParLong(&n)) {
  260. if (!isNString(2)) {
  261. messErr(6);
  262. return;
  263. }
  264. t = getString();
  265. f = getString();
  266. GP_create(GPO_STD|(short)n,t,f);
  267. }
  268. }
  269. void IF_gplot_del(void)
  270. {
  271. long t;
  272. if (getParLong(&t)) {
  273. GP_del((short)t);
  274. }
  275. }
  276. void IF_gplot_clear(void)
  277. {
  278. long t;
  279. struct GPlot * N;
  280. if (getParLong(&t)) {
  281. if ((N = GP_getPlot((short)t)) != NULL) {
  282. GPF_init(N->f);
  283. /* redraw gnuplot */
  284. GP_plot(N);
  285. }
  286. }
  287. }
  288. void IF_gplot_commapp(void)
  289. {
  290. long t;
  291. char *a;
  292. if (getParLong(&t)) {
  293. if (!isNString(1)) {
  294. messErr(6);
  295. return;
  296. }
  297. a = getString();
  298. GP_updApp((short)t,a);
  299. }
  300. }
  301. void IF_gplot_append(void)
  302. {
  303. long t;
  304. if (getParLong(&t)) {
  305. if (!is1Tab()) {
  306. messErr(12);
  307. return;
  308. }
  309. GP_addData((short)t);
  310. }
  311. }
  312. void IF_gplot_replace(void)
  313. {
  314. long t;
  315. if (getParLong(&t)) {
  316. if (!is1Tab()) {
  317. messErr(12);
  318. return;
  319. }
  320. GP_replData((short)t);
  321. }
  322. }
  323. void IF_show_stackGP(void)
  324. {
  325. void * Next;
  326. struct GPlot * N;
  327. if (stackGP != VIDE)
  328. printf(" id |NbP| filename | Title | Options\n");
  329. Next = stackGP;
  330. while (Next != VIDE) {
  331. N = (struct GPlot*) Next;
  332. printf("%5d|%3d|%-12s|%-25s|%s\n",N->id,N->op&0xFF,N->f, N->t, N->a);
  333. Next = N->n;
  334. }
  335. printf("<end of GNUPlot list>\n");
  336. }
  337. void IFD_show_stackGP(void)
  338. {
  339. _IFD_BEGIN_
  340. IF_show_stackGP();
  341. _IFD_END_
  342. }