-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgnuplot.c
101 lines (80 loc) · 2.64 KB
/
gnuplot.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include <plotpg.h>
/*
* The gnuplot() function provides a direct way to generate plots with gnuplot
* commands. This is primarily provided for flexibility for gnuplot power
* users.
*
* A user could, for example, build their own data set with a COPY command, and
* subsequently provide a gnuplot script which leverages the data set.
*
* Another use case could be a user that wishes to plot analytic functions.
*
*/
PG_FUNCTION_INFO_V1(gnuplot);
Datum gnuplot(PG_FUNCTION_ARGS) {
FILE *f;
StringInfoData gnuplot_script_filename;
StringInfoData gnuplot_script_buf;
StringInfoData result_set_line;
StringInfoData output_filename;
StringInfoData gnuplot_command;
StringInfoData resultbuf;
int i, ret;
char pid_str[40];
char line[80];
char *gnuplot_cmds = text_to_cstring(PG_GETARG_TEXT_PP(0));
/*
* Prep variables for temporary files
*/
sprintf(pid_str, "%ld", (long) getpid());
initStringInfo(&output_filename);
appendStringInfo(&output_filename, "/tmp/plotpg_%s.output", pid_str);
initStringInfo(&gnuplot_script_filename);
appendStringInfo(&gnuplot_script_filename, "/tmp/plotpg_%s.script", pid_str);
initStringInfo(&gnuplot_command);
appendStringInfo(&gnuplot_command, "gnuplot %s", gnuplot_script_filename.data);
initStringInfo(&result_set_line);
initStringInfo(&resultbuf);
initStringInfo(&gnuplot_script_buf);
/*
*
* Write Gnuplot script
*
* TODO consider adding the application of GUCs to the script in a
* shared function also used by plot().
*/
f = fopen(gnuplot_script_filename.data, "w");
if (f == NULL) {
ereport(ERROR,
(errcode(58030), //ioerror
errmsg("Unable to write temporary gnuplot script file in /tmp")));
PG_RETURN_TEXT_P(cstring_to_text(""));
}
if (strcmp(gnuplot_terminal, "") != 0)
appendStringInfo(&gnuplot_script_buf, "set terminal %s;", gnuplot_terminal);
appendStringInfo(&gnuplot_script_buf, "set output '%s';", output_filename.data);
appendStringInfoString(&gnuplot_script_buf, gnuplot_cmds);
fprintf(f, "%s", gnuplot_script_buf.data);
fclose(f);
/* Execute Gnuplot script */
ret = system(gnuplot_command.data);
if (ret < 0) {
PG_RETURN_TEXT_P(cstring_to_text("There was an error running the gnuplot command"));
}
/* Read and return output */
f = fopen(output_filename.data, "rb");
i = 0;
while(fgets(line, 80, f) != NULL) {
if ((strstr(gnuplot_terminal, "dumb") != gnuplot_terminal) || i > 0) {
appendStringInfoString(&resultbuf, line);
}
i++;
}
fclose(f);
/* Cleanup */
if (plotpg_persist < 1) {
remove(gnuplot_script_filename.data);
remove(output_filename.data);
}
PG_RETURN_TEXT_P(cstring_to_text(resultbuf.data));
}