Move some functions around to improve overall structure
[lttv.git] / lttv / lttv / sync / graph_functions.c
index 9b61e1208c2718092587e83f36e413e0340b816c..6bd28b8091ed26354b1d7a308934543ac0556c3f 100644 (file)
@@ -21,6 +21,9 @@
 #endif
 
 #include <errno.h>
+#include <fcntl.h>
+#include <stdlib.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->matchingModule->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),
+               },
        };
 
-       for (l= 0; l < sizeof(funcTypes) / sizeof(*funcTypes); l++)
+       fprintf(syncState->graphsStream, "\n");
+
+       // Write variables
+       pos1= ftell(syncState->graphsStream);
+       for (i= 0; i < syncState->traceNb; i++)
+       {
+               for (k= 0; k < sizeof(moduleGraphFunctions) /
+                       sizeof(*moduleGraphFunctions); k++)
+               {
+                       GraphVariableFunction** writeVariables= (void*)
+                               moduleGraphFunctions[k] + offsetof(GraphFunctions,
+                                       writeVariables);
+
+                       if (*writeVariables)
+                       {
+                               (*writeVariables)(syncState, i);
+                       }
+               }
+       }
+       fflush(syncState->graphsStream);
+       pos2= ftell(syncState->graphsStream);
+       if (pos1 != pos2)
+       {
+               fprintf(syncState->graphsStream, "\n");
+       }
+
+       // 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++)
                {
                        for (j= i + 1; j < syncState->traceNb; j++)
                        {
-                               long pos1, pos2, trunc;
-                               const GraphFunctions* moduleGraphFunctions[]= {
-                                       &syncState->processingModule->graphFunctions,
-                                       &syncState->matchingModule->graphFunctions,
-                                       &syncState->analysisModule->graphFunctions,
-                               };
+                               long trunc;
 
                                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);
+                                               }
                                        }
                                }
 
@@ -100,13 +242,13 @@ void writeGraphsScript(SyncState* const syncState)
 
                                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)
                                        {
This page took 0.02989 seconds and 4 git commands to generate.