[gegl] serialize: add support for resolving relative paths



commit 0748b512f92411f5879f80d53a102997ee8d264c
Author: Øyvind Kolås <pippin gimp org>
Date:   Tue May 2 18:24:01 2017 +0200

    serialize: add support for resolving relative paths

 bin/gegl.c               |    2 +-
 bin/ui.c                 |    4 +++
 gegl/gegl-serialize.c    |   48 +++++++++++++++++++++++++++++++++++++--------
 gegl/gegl-utils.h        |   16 +++++++++-----
 operations/common/gegl.c |    8 ++++++-
 5 files changed, 61 insertions(+), 17 deletions(-)
---
diff --git a/bin/gegl.c b/bin/gegl.c
index e17c083..123819e 100644
--- a/bin/gegl.c
+++ b/bin/gegl.c
@@ -229,7 +229,7 @@ main (gint    argc,
   if (o->rest)
     {
       GError *error = NULL;
-      gegl_create_chain_argv (o->rest, iter, proxy, 0, gegl_node_get_bounding_box (gegl).height, &error);
+      gegl_create_chain_argv (o->rest, iter, proxy, 0, gegl_node_get_bounding_box (gegl).height, path_root, 
&error);
       if (error)
       {
         fprintf (stderr, "Error: %s\n", error->message);
diff --git a/bin/ui.c b/bin/ui.c
index 8cb6278..4522033 100644
--- a/bin/ui.c
+++ b/bin/ui.c
@@ -1396,10 +1396,14 @@ static void load_path (State *o)
   if (o->ops)
   {
     GError *error = NULL;
+
+    char *containing_path = get_path_parent (o->path);
     gegl_create_chain_argv (o->ops,
                     gegl_node_get_producer (o->sink, "input", NULL),
                     o->sink, 0, gegl_node_get_bounding_box (o->sink).height,
+                    containing_path,
                     &error);
+    free (containing_path);
     if (error)
     {
       fprintf (stderr, "Error: %s\n", error->message);
diff --git a/gegl/gegl-serialize.c b/gegl/gegl-serialize.c
index a7fb3ce..e63a888 100644
--- a/gegl/gegl-serialize.c
+++ b/gegl/gegl-serialize.c
@@ -18,6 +18,8 @@
 
 #include "gegl.h"
 #include <string.h>
+#include <limits.h>
+#include <stdlib.h>
 #include <stdio.h>
 #include "property-types/gegl-paramspecs.h"
 
@@ -50,12 +52,13 @@ remove_in_betweens (GeglNode *nop_raw,
 }
 
 void
-gegl_create_chain_argv (char    **ops,
-                        GeglNode *start,
-                        GeglNode *proxy,
-                        double    time,
-                        int       rel_dim,
-                        GError  **error)
+gegl_create_chain_argv (char      **ops,
+                        GeglNode   *start,
+                        GeglNode   *proxy,
+                        double      time,
+                        int         rel_dim,
+                        const char *path_root,
+                        GError    **error)
 {
   GeglNode   *iter[10] = {start, NULL};
   GeglNode   *new = NULL;
@@ -421,6 +424,31 @@ gegl_create_chain_argv (char    **ops,
 
                         gegl_node_set (iter[level], key, format, NULL);
                       }
+                    else if (g_type_is_a (G_PARAM_SPEC_TYPE (pspec),
+                             GEGL_TYPE_PARAM_FILE_PATH))
+                      {
+                        gchar *buf;
+                        if (g_path_is_absolute (value))
+                          {
+                            gegl_node_set (iter[level], key, value, NULL);
+                          }
+                        else
+                          {
+                            gchar *absolute_path;
+                            if (path_root)
+                              buf = g_strdup_printf ("%s/%s", path_root, value);
+                            else
+                              buf = g_strdup_printf ("./%s", value);
+                            absolute_path = realpath (buf, NULL);
+                            g_free (buf);
+                            if (absolute_path)
+                              {
+                                gegl_node_set (iter[level], key, absolute_path, NULL);
+                                free (absolute_path);
+                              }
+                            gegl_node_set (iter[level], key, value, NULL);
+                          }
+                      }
                     else if (g_type_is_a (target_type, G_TYPE_STRING))
                       {
                         gegl_node_set (iter[level], key, value, NULL);
@@ -580,7 +608,8 @@ gegl_create_chain_argv (char    **ops,
 
 void
 gegl_create_chain (const char *str, GeglNode *op_start, GeglNode *op_end,
-                   double time, int rel_dim, GError **error)
+                   double time, int rel_dim, const char *path_root,
+                   GError **error)
 {
   gchar **argv = NULL;
   gint argc = 0;
@@ -588,7 +617,8 @@ gegl_create_chain (const char *str, GeglNode *op_start, GeglNode *op_end,
   g_shell_parse_argv (str, &argc, &argv, NULL);
   if (argv)
     {
-      gegl_create_chain_argv (argv, op_start, op_end, time, rel_dim, error);
+      gegl_create_chain_argv (argv, op_start, op_end, time, rel_dim, path_root,
+                              error);
       g_strfreev (argv);
     }
 }
@@ -910,7 +940,7 @@ gegl_node_new_from_serialized (const gchar *chaindata,
   gegl_node_set (foo, "operation", "gegl:nop", NULL);
 
   gegl_node_link_many (foo, ret, NULL);
-  gegl_create_chain (chaindata, foo, ret, 0, 1024, NULL);
+  gegl_create_chain (chaindata, foo, ret, 0, 1024, path_root, NULL);
 
   return ret;
 }
diff --git a/gegl/gegl-utils.h b/gegl/gegl-utils.h
index 213574d..9848e33 100644
--- a/gegl/gegl-utils.h
+++ b/gegl/gegl-utils.h
@@ -273,16 +273,18 @@ typedef enum GeglSerializeFlag {
  * @op_end: node to get processed data
  * @time: the time to use for interpolatino of keyframed values
  * @rel_dim: relative dimension to scale rel suffixed values by
+ * @path_root: path in filesystem to use as relative root
  * @error: error for signalling parsing errors
  *
  * Create a node chain from argv style list of op data.
  */
-void gegl_create_chain_argv (char    **ops,
-                             GeglNode *op_start,
-                             GeglNode *op_end,
-                             double    time,
-                             int       rel_dim,
-                             GError  **error);
+void gegl_create_chain_argv (char      **ops,
+                             GeglNode   *op_start,
+                             GeglNode   *op_end,
+                             double      time,
+                             int         rel_dim,
+                             const char *path_root,
+                             GError    **error);
 /**
  * gegl_create_chain:
  * @ops: an argv style, NULL terminated array of arguments
@@ -290,6 +292,7 @@ void gegl_create_chain_argv (char    **ops,
  * @op_end: node to get processed data
  * @time: the time to use for interpolatino of keyframed values
  * @rel_dim: relative dimension to scale rel suffixed values by
+ * @path_root: path in filesystem to use as relative root
  * @error: error for signalling parsing errors
  *
  * Create a node chain from an unparsed commandline string.
@@ -299,6 +302,7 @@ void gegl_create_chain (const char *str,
                         GeglNode   *op_end,
                         double      time,
                         int         rel_dim,
+                        const char *path_root,
                         GError    **error);
 
 /**
diff --git a/operations/common/gegl.c b/operations/common/gegl.c
index 707ab37..e0484e0 100644
--- a/operations/common/gegl.c
+++ b/operations/common/gegl.c
@@ -36,6 +36,7 @@ property_string (error, _("Eeeeeek"), "")
 #define GEGL_OP_C_SOURCE gegl.c
 
 #include "gegl-op.h"
+#include <unistd.h>
 
 /* XXX: leaking o->user_data */
 
@@ -53,6 +54,7 @@ attach (GeglOperation *operation)
 }
 
 #include <stdio.h>
+#include <stdlib.h>
 
 static void
 prepare (GeglOperation *operation)
@@ -73,9 +75,13 @@ prepare (GeglOperation *operation)
   output = gegl_node_get_output_proxy (gegl, "output");
 
   gegl_node_link_many (input, output, NULL);
+  {
+     gchar cwd[81920]; // XXX: should do better
+     getcwd (cwd, sizeof(cwd));
   gegl_create_chain (o->string, input, output, 0.0,
-                     gegl_node_get_bounding_box (input).height,
+                     gegl_node_get_bounding_box (input).height, cwd,
                      &error);
+  }
 
   if (error)
   {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]