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.
 
 
 
 

371 lines
7.3 KiB

  1. /* Copyright (C) 2011-2014 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. #define GPO_STD 0 /* standard */
  30. #define GPO_MRG 0x100 /* merge */
  31. struct GPlot {
  32. short id;
  33. short op;/* options + nb plots */
  34. FILE *p; /* pipe */
  35. char *t; /* title */
  36. char *f; /* file */
  37. char *a; /* command append */
  38. int pid; /* pid */
  39. void *n; /* next */
  40. };
  41. static short GPid=0;
  42. static void *stackGP = VIDE;
  43. /* file manipulations */
  44. static void GPF_init(char *f)
  45. {
  46. int fd;
  47. chdir(".nife");
  48. if ((fd = creat(f,0600)) != -1) {
  49. write(fd,"# Nife auto-generated GNUplot file !\n",37);
  50. close(fd);
  51. }
  52. chdir("..");
  53. }
  54. static void GPF_del(char *f)
  55. {
  56. unlink(f);
  57. }
  58. static void GPF_supL(char * f, int n)
  59. {
  60. void * M;
  61. char *f2;
  62. char l[512];
  63. FILE *fIn, *fOut;
  64. int i=1;
  65. if ((M = malloc(strlen(f)+5)) == NULL) stopErr("GPF_supL","malloc");
  66. f2 = (char*)M;
  67. strcpy(f2,f);
  68. f2 += strlen(f);
  69. strcpy(f2,".wni");
  70. f2 = (char*)M;
  71. if ((fIn = fopen(f, "r")) != NULL) {
  72. if ((fOut = fopen(f2, "w")) != NULL) {
  73. while (fgets(l, sizeof(l), fIn)) {
  74. if (i != n) fputs(l, fOut);
  75. i++;
  76. }
  77. fclose(fOut);
  78. }
  79. fclose(fIn);
  80. rename(f2, f);
  81. }
  82. free(M);
  83. }
  84. /* struct GPlot functions */
  85. static void eraseGP(struct GPlot *F)
  86. {
  87. GPF_del(F->f);
  88. free((void*)F->t);
  89. free((void*)F->f);
  90. if (F->a != NULL) free((void*)F->a);
  91. free((void*)F);
  92. }
  93. static void GP_initial(struct GPlot * N)
  94. {
  95. fprintf(N->p, "set term x11 title \"Nife GPlot %d\" size 400,300\n", N->id);
  96. fprintf(N->p, "unset mouse\n");
  97. }
  98. static void GP_create(short op, char *T, char *F)
  99. {
  100. int pid, p[2];
  101. void * M;
  102. struct GPlot *N;
  103. if ((M = malloc(sizeof(struct GPlot)))==NULL) stopErr("GP_create","malloc");
  104. N = (struct GPlot*)M;
  105. N->id = ++GPid;
  106. N->op = op;
  107. N->t = T;
  108. N->f = F;
  109. N->a = NULL;
  110. N->n = stackGP;
  111. GPF_init(N->f);
  112. /* Old method **********
  113. N->p = popen("gnuplot -p -raise","w");
  114. *********/
  115. if (pipe(p) != 0) stopErr("GP_create","pipe");
  116. N->p = fdopen(p[1], "w"); /* w side */
  117. if ((pid = fork()) == -1) {
  118. fprintf(stderr,"GP_create : error fork !\n");
  119. eraseGP(N);
  120. } else {
  121. if (pid == 0) { /* fils */
  122. dup2(p[0],0);
  123. close(p[0]);
  124. close(p[1]);
  125. _MODIF_inSonProc_(1);
  126. setsid();
  127. execlp("gnuplot", "Nife_gplot", "-p", "-raise", NULL);
  128. perror("gnuplot");
  129. exit(1);
  130. } else {
  131. N->pid = pid;
  132. close(p[0]);
  133. stackGP = M;
  134. GP_initial(N);
  135. }
  136. }
  137. }
  138. static void GP_del(short id)
  139. {
  140. void ** PNext;
  141. struct GPlot * N;
  142. PNext = &stackGP;
  143. while (*PNext != VIDE) {
  144. N = (struct GPlot*) *PNext;
  145. if (N->id == id) {
  146. *PNext = N->n;
  147. /* stop gnuplot */
  148. fprintf(N->p,"exit\n");
  149. fflush(N->p);
  150. kill(N->pid,SIGKILL);
  151. eraseGP(N);
  152. return;
  153. }
  154. PNext = &N->n;
  155. }
  156. messErr(42);
  157. }
  158. void IF_delAllGP(void)
  159. {
  160. struct GPlot * N;
  161. while (stackGP != VIDE) {
  162. N = (struct GPlot*) stackGP;
  163. stackGP = N->n;
  164. /* stop gnuplot */
  165. fprintf(N->p,"exit\n");
  166. fflush(N->p);
  167. kill(N->pid,SIGKILL);
  168. eraseGP(N);
  169. }
  170. GPid=0;
  171. }
  172. static struct GPlot * GP_getPlot(short id)
  173. {
  174. void ** PNext;
  175. struct GPlot * N;
  176. PNext = &stackGP;
  177. while (*PNext != VIDE) {
  178. N = (struct GPlot*) *PNext;
  179. if (N->id == id) {
  180. return N;
  181. }
  182. PNext = &N->n;
  183. }
  184. messErr(42);
  185. return NULL;
  186. }
  187. static void GP_plot(struct GPlot * N)
  188. {
  189. int i;
  190. fprintf(N->p, "set term x11 title \"Nife GPlot %d\"\n", N->id);
  191. fprintf(N->p, "plot ");
  192. for (i=0; i<(N->op&0xFF); i++) {
  193. if (i) fprintf(N->p,", ");
  194. fprintf(N->p,"\"%s\" using 1:%d title \"",N->f, i+2);
  195. if (i) fprintf(N->p,"col %d",i+1);
  196. else fprintf(N->p,"%s",N->t);
  197. fprintf(N->p,"\" with lines ");
  198. if (N->a != NULL) fprintf(N->p,"%s",N->a);
  199. }
  200. fprintf(N->p,"\n");
  201. fflush(N->p);
  202. }
  203. static void GP_updApp(short id, char * a)
  204. {
  205. struct GPlot * N;
  206. if ((N = GP_getPlot(id)) != NULL) {
  207. if (N->a != NULL) free((void*)N->a);
  208. N->a = a;
  209. /* redraw gnuplot */
  210. GP_plot(N);
  211. return;
  212. }
  213. free((void*)a);
  214. }
  215. static void GP_addData(short id)
  216. {
  217. struct GPlot * N;
  218. FILE *fd;
  219. if ((N = GP_getPlot(id)) != NULL) {
  220. /* Add data to file */
  221. fd = fopen(N->f,"a");
  222. IF_inFile_1d(fd, ' ', 0);
  223. fclose(fd);
  224. /* redraw gnuplot */
  225. GP_plot(N);
  226. }
  227. }
  228. static void GP_replData(short id)
  229. {
  230. struct GPlot * N;
  231. FILE *fd;
  232. if ((N = GP_getPlot(id)) != NULL) {
  233. /* delete the second line */
  234. GPF_supL(N->f,2);
  235. /* Add data to file */
  236. fd = fopen(N->f,"a");
  237. IF_inFile_1d(fd, ' ', 0);
  238. fclose(fd);
  239. /* redraw gnuplot */
  240. GP_plot(N);
  241. }
  242. }
  243. void IF_gplot_new(void)
  244. {
  245. char *t, *f;
  246. if (!isNString(2)) {
  247. messErr(6);
  248. return;
  249. }
  250. t = getString();
  251. f = getString();
  252. GP_create(GPO_STD|1,t,f);
  253. }
  254. void IF_gplot_newM(void)
  255. {
  256. char *t, *f;
  257. long n;
  258. if (getParLong(&n)) {
  259. if (!isNString(2)) {
  260. messErr(6);
  261. return;
  262. }
  263. t = getString();
  264. f = getString();
  265. GP_create(GPO_STD|(short)n,t,f);
  266. }
  267. }
  268. void IF_gplot_del(void)
  269. {
  270. long t;
  271. if (getParLong(&t)) {
  272. GP_del((short)t);
  273. }
  274. }
  275. void IF_gplot_clear(void)
  276. {
  277. long t;
  278. struct GPlot * N;
  279. if (getParLong(&t)) {
  280. if ((N = GP_getPlot((short)t)) != NULL) {
  281. GPF_init(N->f);
  282. /* redraw gnuplot */
  283. GP_plot(N);
  284. }
  285. }
  286. }
  287. void IF_gplot_commapp(void)
  288. {
  289. long t;
  290. char *a;
  291. if (getParLong(&t)) {
  292. if (!isNString(1)) {
  293. messErr(6);
  294. return;
  295. }
  296. a = getString();
  297. GP_updApp((short)t,a);
  298. }
  299. }
  300. void IF_gplot_append(void)
  301. {
  302. long t;
  303. if (getParLong(&t)) {
  304. if (!is1Tab()) {
  305. messErr(12);
  306. return;
  307. }
  308. GP_addData((short)t);
  309. }
  310. }
  311. void IF_gplot_replace(void)
  312. {
  313. long t;
  314. if (getParLong(&t)) {
  315. if (!is1Tab()) {
  316. messErr(12);
  317. return;
  318. }
  319. GP_replData((short)t);
  320. }
  321. }
  322. void IF_show_stackGP(void)
  323. {
  324. void * Next;
  325. struct GPlot * N;
  326. if (stackGP != VIDE)
  327. printf(" id |NbP| filename | Title | Options\n");
  328. Next = stackGP;
  329. while (Next != VIDE) {
  330. N = (struct GPlot*) Next;
  331. printf("%5d|%3d|%-12s|%-25s|%s\n",N->id,N->op&0xFF,N->f, N->t, N->a);
  332. Next = N->n;
  333. }
  334. printf("<end of GNUPlot list>\n");
  335. }