#endif
#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "graph_functions.h"
+/*
+ * Create the directory used to hold graphs and the header of the gnuplot
+ * script.
+ *
+ * Args:
+ * graphsDir: name of directory
+ *
+ * Returns:
+ * The current working directory before the execution of the function. The
+ * string must be free'd by the caller.
+ */
+FILE* createGraphsDir(const char* const graphsDir)
+{
+ char* cwd;
+ int graphsFp;
+ FILE* result;
+ int retval;
+
+ cwd= changeToGraphsDir(graphsDir);
+
+ if ((graphsFp= open("graphs.gnu", O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR |
+ S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH
+ | S_IWOTH | S_IXOTH)) == -1)
+ {
+ g_error(strerror(errno));
+ }
+ if ((result= fdopen(graphsFp, "w")) == NULL)
+ {
+ g_error(strerror(errno));
+ }
+
+ fprintf(result,
+ "#!/usr/bin/gnuplot\n\n"
+ "set terminal postscript eps color size 8in,6in\n");
+
+ retval= chdir(cwd);
+ if (retval == -1)
+ {
+ g_error(strerror(errno));
+ }
+ free(cwd);
+
+ return result;
+}
+
+
+/*
+ * Change to the directory used to hold graphs. Create it if necessary.
+ *
+ * Args:
+ * graphsDir: name of directory
+ *
+ * Returns:
+ * The current working directory before the execution of the function. The
+ * string must be free'd by the caller.
+ */
+char* changeToGraphsDir(const char* const graphsDir)
+{
+ int retval;
+ char* cwd;
+
+ cwd= getcwd(NULL, 0);
+ if (cwd == NULL)
+ {
+ g_error(strerror(errno));
+ }
+ while ((retval= chdir(graphsDir)) != 0)
+ {
+ if (errno == ENOENT)
+ {
+ retval= mkdir(graphsDir, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP |
+ S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH);
+ if (retval != 0)
+ {
+ g_error(strerror(errno));
+ }
+ }
+ else
+ {
+ g_error(strerror(errno));
+ }
+ }
+
+ return cwd;
+}
+
+
+/*
+ * Call each graph variable, option and plot line function of each module to
+ * produce a gnuplot script.
+ *
+ * Args:
+ * syncState: container for synchronization data
+ */
void writeGraphsScript(SyncState* const syncState)
{
- unsigned int i, j, k, l;
+ unsigned int i, j, k, l, m;
long pos1, pos2;
const GraphFunctions* moduleGraphFunctions[]= {
&syncState->processingModule->graphFunctions,
&syncState->analysisModule->graphFunctions,
};
const struct {
- size_t plotsOffset,
- optionsOffset;
char* name;
- } funcTypes[]= {
- {offsetof(GraphFunctions, writeTraceTracePlots),
- offsetof(GraphFunctions, writeTraceTraceOptions), "TraceTrace"},
- {offsetof(GraphFunctions, writeTraceTimePlots),
- offsetof(GraphFunctions, writeTraceTimeOptions), "TraceTime"},
+ size_t plotsOffsets[2];
+ size_t optionsOffset;
+ } graphTypes[]= {
+ {
+ "TraceTrace",
+ {
+ offsetof(GraphFunctions, writeTraceTraceBackPlots),
+ offsetof(GraphFunctions, writeTraceTraceForePlots),
+ },
+ offsetof(GraphFunctions, writeTraceTraceOptions),
+ },
+ {
+ "TraceTime",
+ {
+ offsetof(GraphFunctions, writeTraceTimeBackPlots),
+ offsetof(GraphFunctions, writeTraceTimeForePlots),
+ },
+ offsetof(GraphFunctions, writeTraceTimeOptions),
+ },
};
fprintf(syncState->graphsStream, "\n");
+
+ // Write variables
pos1= ftell(syncState->graphsStream);
for (i= 0; i < syncState->traceNb; i++)
{
fprintf(syncState->graphsStream, "\n");
}
- for (l= 0; l < sizeof(funcTypes) / sizeof(*funcTypes); l++)
+ // Write plots and options
+ for (l= 0; l < sizeof(graphTypes) / sizeof(*graphTypes); l++)
{
// Cover the upper triangular matrix, i is the reference node.
for (i= 0; i < syncState->traceNb; i++)
fprintf(syncState->graphsStream,
"reset\n"
"set output \"%03d-%03d-%s.eps\"\n"
- "plot \\\n", i, j, funcTypes[l].name);
+ "plot \\\n", i, j, graphTypes[l].name);
pos1= ftell(syncState->graphsStream);
- for (k= 0; k < sizeof(moduleGraphFunctions) /
- sizeof(*moduleGraphFunctions); k++)
+ for (m= 0; m < sizeof(graphTypes[l].plotsOffsets) /
+ sizeof(*graphTypes[l].plotsOffsets); m++)
{
- GraphFunction** writePlots= (void*)
- moduleGraphFunctions[k] + funcTypes[l].plotsOffset;
-
- if (*writePlots)
+ for (k= 0; k < sizeof(moduleGraphFunctions) /
+ sizeof(*moduleGraphFunctions); k++)
{
- (*writePlots)(syncState, i, j);
+ GraphFunction** writePlots= (void*)
+ moduleGraphFunctions[k] +
+ graphTypes[l].plotsOffsets[m];
+
+ if (*writePlots)
+ {
+ (*writePlots)(syncState, i, j);
+ }
}
}
fprintf(syncState->graphsStream,
"\nset output \"%03d-%03d-%s.eps\"\n"
- "set title \"\"\n", i, j, funcTypes[l].name);
+ "set title \"\"\n", i, j, graphTypes[l].name);
for (k= 0; k < sizeof(moduleGraphFunctions) /
sizeof(*moduleGraphFunctions); k++)
{
GraphFunction** writeOptions= (void*)
- moduleGraphFunctions[k] + funcTypes[l].optionsOffset;
+ moduleGraphFunctions[k] + graphTypes[l].optionsOffset;
if (*writeOptions)
{