---
 libgeda/include/prototype.h |    4 +-
 libgeda/src/g_rc.c          |   75 +++++-------
 libgeda/src/s_basic.c       |  284 ++++++++++++-------------------------------
 3 files changed, 108 insertions(+), 255 deletions(-)

diff --git a/libgeda/include/prototype.h b/libgeda/include/prototype.h
index ee78204..610611a 100644
--- a/libgeda/include/prototype.h
+++ b/libgeda/include/prototype.h
@@ -347,9 +347,7 @@ void string_tolower(char *in, char *out);
 int colornametovalue(char *string);
 char *remove_nl(char *string);
 char *remove_last_nl(char *string);
-char *remove_string(char *string, int start, int end);
-char *insert_string(char *string, int start, char *insert_string);
-char *s_expand_env_variables(char *string);
+gchar *s_expand_env_variables (const gchar *string);
 
 /* s_clib.c */
 void s_clib_free (void);
diff --git a/libgeda/src/g_rc.c b/libgeda/src/g_rc.c
index 6e91098..a0472ab 100644
--- a/libgeda/src/g_rc.c
+++ b/libgeda/src/g_rc.c
@@ -401,7 +401,7 @@ void g_rc_parse(TOPLEVEL *toplevel,
  */
 SCM g_rc_component_library(SCM path, SCM name)
 {
-  char *string;
+  gchar *string;
   char *namestr = NULL;
 
   SCM_ASSERT (scm_is_string (path), path,
@@ -413,9 +413,8 @@ SCM g_rc_component_library(SCM path, SCM name)
     namestr = SCM_STRING_CHARS (name);
   }
   
-  string = g_strdup (SCM_STRING_CHARS (path));
   /* take care of any shell variables */
-  string = s_expand_env_variables(string);
+  string = s_expand_env_variables (SCM_STRING_CHARS (path));
 
   /* invalid path? */
   if (!g_file_test (string, G_FILE_TEST_IS_DIR)) {
@@ -460,40 +459,36 @@ SCM g_rc_component_library(SCM path, SCM name)
 SCM g_rc_component_library_command (SCM listcmd, SCM getcmd, 
                                     SCM name)
 {
-  gchar *namestr = NULL;
-  gchar *lcmdstr = NULL;
-  gchar *gcmdstr = NULL;
   const CLibSource *src;
-  char *tmp_str;
+  gchar *lcmdstr, *gcmdstr;
+  char *tmp_str, *namestr;
 
   SCM_ASSERT (scm_is_string (listcmd), listcmd, SCM_ARG1, 
               "component-library-command");
-  tmp_str = scm_to_locale_string (listcmd);
-  lcmdstr = g_strdup (tmp_str);
-  free (tmp_str); /* this should stay as free (allocated from guile) */
-
   SCM_ASSERT (scm_is_string (getcmd), getcmd, SCM_ARG2, 
               "component-library-command");
-  tmp_str = scm_to_locale_string (getcmd);
-  gcmdstr = g_strdup (tmp_str);
-  free (tmp_str); /* this should stay as free (allocated from guile) */
-
   SCM_ASSERT (scm_is_string (name), name, SCM_ARG3, 
               "component-library-command");
-  tmp_str = scm_to_locale_string (name);
-  namestr = g_strdup (tmp_str);
+
+  /* take care of any shell variables */
+  /*! \bug this may be a security risk! */
+  tmp_str = scm_to_locale_string (listcmd);
+  lcmdstr = s_expand_env_variables (tmp_str);
   free (tmp_str); /* this should stay as free (allocated from guile) */
 
   /* take care of any shell variables */
   /*! \bug this may be a security risk! */
-  lcmdstr = s_expand_env_variables(lcmdstr);
-  gcmdstr = s_expand_env_variables(gcmdstr);
+  tmp_str = scm_to_locale_string (getcmd);
+  gcmdstr = s_expand_env_variables (tmp_str);
+  free (tmp_str); /* this should stay as free (allocated from guile) */
+
+  namestr = scm_to_locale_string (name);
 
   src = s_clib_add_command (lcmdstr, gcmdstr, namestr);
 
+  free (namestr); /* this should stay as free (allocated from guile) */
   g_free (lcmdstr);
   g_free (gcmdstr);
-  g_free (namestr);
 
   if (src != NULL) return SCM_BOOL_T;
 
@@ -541,16 +536,15 @@ SCM g_rc_component_library_funcs (SCM listfunc, SCM 
getfunc, SCM name)
  */
 SCM g_rc_component_library_search(SCM path)
 {
-  char *string;
+  gchar *string;
   GDir *dir;
   const gchar *entry;
   
   SCM_ASSERT (scm_is_string (path), path,
               SCM_ARG1, "component-library-search");
 
-  string = g_strdup (SCM_STRING_CHARS (path));
   /* take care of any shell variables */
-  string = s_expand_env_variables(string);
+  string = s_expand_env_variables (SCM_STRING_CHARS (path));
 
   /* invalid path? */
   if (!g_file_test (string, G_FILE_TEST_IS_DIR)) {
@@ -619,14 +613,13 @@ SCM g_rc_component_library_search(SCM path)
  */
 SCM g_rc_source_library(SCM path)
 {
-  char *string;
+  gchar *string;
   
   SCM_ASSERT (scm_is_string (path), path,
               SCM_ARG1, "source-library");
 
-  string = g_strdup (SCM_STRING_CHARS (path));
   /* take care of any shell variables */
-  string = s_expand_env_variables(string);
+  string = s_expand_env_variables (SCM_STRING_CHARS (path));
   
   /* invalid path? */
   if (!g_file_test (string, G_FILE_TEST_IS_DIR)) {
@@ -670,16 +663,15 @@ SCM g_rc_source_library(SCM path)
  */
 SCM g_rc_source_library_search(SCM path)
 {
-  char *string;
+  gchar *string;
   GDir *dir;
   const gchar *entry;
   
   SCM_ASSERT (scm_is_string (path), path,
               SCM_ARG1, "source-library-search");
 
-  string = g_strdup (SCM_STRING_CHARS (path));
   /* take care of any shell variables */
-  string = s_expand_env_variables(string);
+  string = s_expand_env_variables (SCM_STRING_CHARS (path));
 
   /* invalid path? */
   if (!g_file_test (string, G_FILE_TEST_IS_DIR)) {
@@ -836,14 +828,13 @@ SCM g_rc_untitled_name(SCM name)
  */
 SCM g_rc_font_directory(SCM path)
 {
-  char *string;
+  gchar *string;
 
   SCM_ASSERT (scm_is_string (path), path,
               SCM_ARG1, "font-directory");
 
-  string = g_strdup (SCM_STRING_CHARS (path));
   /* take care of any shell variables */
-  string = s_expand_env_variables(string);
+  string = s_expand_env_variables (SCM_STRING_CHARS (path));
 
   /* invalid path? */
   if (!g_file_test (string, G_FILE_TEST_IS_DIR)) {
@@ -873,14 +864,13 @@ SCM g_rc_font_directory(SCM path)
  */
 SCM g_rc_scheme_directory(SCM path)
 {
-  char *string;
+  gchar *string;
 
   SCM_ASSERT (scm_is_string (path), path,
               SCM_ARG1, "scheme-directory");
 
-  string = g_strdup (SCM_STRING_CHARS (path));
   /* take care of any shell variables */
-  string = s_expand_env_variables(string);
+  string = s_expand_env_variables (SCM_STRING_CHARS (path));
 
   /* invalid path? */
   if (!g_file_test (string, G_FILE_TEST_IS_DIR)) {
@@ -910,14 +900,13 @@ SCM g_rc_scheme_directory(SCM path)
  */
 SCM g_rc_bitmap_directory(SCM path)
 {
-  char *string;
+  gchar *string;
 
   SCM_ASSERT (scm_is_string (path), path,
               SCM_ARG1, "bitmap-directory");
   
-  string = g_strdup (SCM_STRING_CHARS (path));
   /* take care of any shell variables */
-  string = s_expand_env_variables(string);
+  string = s_expand_env_variables (SCM_STRING_CHARS (path));
 
   /* invalid path? */
   if (!g_file_test (string, G_FILE_TEST_IS_DIR)) {
@@ -967,8 +956,6 @@ SCM g_rc_bus_ripper_symname(SCM scmsymname)
  */
 SCM g_rc_postscript_prolog(SCM scmsymname)
 {
-  char *string;
-  
   SCM_ASSERT (scm_is_string (scmsymname), scmsymname,
               SCM_ARG1, "postsript-prolog");
 
@@ -976,11 +963,9 @@ SCM g_rc_postscript_prolog(SCM scmsymname)
     g_free(default_postscript_prolog);
   }
 
-  string = g_strdup (SCM_STRING_CHARS (scmsymname));
   /* take care of any shell variables */
-  string = s_expand_env_variables(string);
-
-  default_postscript_prolog = g_strdup (string);
+  default_postscript_prolog =
+    s_expand_env_variables (SCM_STRING_CHARS (scmsymname));
 
   return SCM_BOOL_T;
 }
@@ -1042,7 +1027,7 @@ SCM g_rc_map_font_character_to_file(SCM scmcharstr, SCM 
scmfilename)
   }
 
   /* take care of expansion of any shell variables in filename */
-  filename = s_expand_env_variables (g_strdup (filename));
+  filename = s_expand_env_variables (filename);
 
   character = g_utf8_get_char_validated (charstr, -1);
   
diff --git a/libgeda/src/s_basic.c b/libgeda/src/s_basic.c
index 3e4fdf7..2eab043 100644
--- a/libgeda/src/s_basic.c
+++ b/libgeda/src/s_basic.c
@@ -680,229 +680,99 @@ void vsnprintf(char *buff, size_t bufsiz, const char 
*fmt, va_list ap)
 }
 #endif
 
-/*! \todo Finish function documentation!!!
- *  \brief
+/*! \brief Expand environment variables in string.
  *  \par Function Description
+ *  This function returns the passed string with environment variables
+ *  expanded.
  *
- */
-/* this function is called by s_expand_env_variables */
-/* changes and returns new string, frees the one that was passed in */
-char *remove_string(char *string, int start, int end) 
-{
-  char *return_string;
-  int i;
-  int len;
-  int j;
-
-  if (!string) {
-    return(NULL);
-  }
-
-  len = strlen(string);
-
-  return_string = (char *) g_malloc(sizeof(char)*(len+1));
-
-  j = 0;
-  for (i = 0 ; i < len; i++) {
-    if (i >= start && i <= end) {
-      /* do nothing */
-      /* removing characters */
-    } else {
-      return_string[j] = string[i];
-      j++;
-    }
-  }
-  return_string[j] = '\0';
-
-  /* free original string */
-  g_free(string);
-
-  return(return_string);
-}
-
-/*! \todo Finish function documentation!!!
- *  \brief
- *  \par Function Description
+ *  The invocations of environment variable MUST be in the form
+ *  '${variable_name}', '$variable_name' is not valid here. Environment
+ *  variable names consists solely of letters, digits and '_'. It is
+ *  possible to escape a '$' character in the string by repeating it
+ *  twice.
+ *
+ *  It outputs error messages to console and leaves the malformed and
+ *  bad variable names in the returned string.
  *
+ *  \param [in] string The string with variables to expand.
+ *  \return A newly-allocated string with variables expanded or NULL
+ *  if input string was NULL.
  */
-/* this function is called by s_expand_env_variables */
-/* changes and returns new string, frees the one that was passed in */
-char *insert_string(char *string, int start, char *insert_string)
+gchar*
+s_expand_env_variables (const gchar *string)
 {
-  char *new_string=NULL;
-  int i;
-  int len;
-  int insert_len;
-  int total_len;
-  int j;
-  int orig_count=0;
-
-  /* this should never happen */
-  if (!insert_string) {
-    return(NULL);      
-  }
+  GString *gstring;
+  gint i;
 
-  /* this should never happen either */
-  if (!string) {
-    return(NULL);      
+  if (string == NULL) {
+    return NULL;
   }
 
-  len = strlen(string);
-  insert_len = strlen(insert_string);
-  total_len = len+insert_len;
-
-  new_string = (char *) g_malloc(sizeof(char)*(total_len+1));
-
+  gstring = g_string_sized_new (strlen (string));
   i = 0;
-  while (i < total_len) {
-    if (i == start) {
-      for (j = 0 ; j < insert_len; j++) {
-        new_string[i+j] = insert_string[j];
-      }
-      i = j+i;
-    } else {
-      new_string[i] = string[orig_count];
-      i++;
-      orig_count++;
+  while (TRUE) {
+    gint start;
+
+    start = i;
+    /* look for end of string or possible variable name start */
+    while (string[i] != '\0' && string[i] != '$') i++;
+    g_string_append_len (gstring, string + start, i - start);
+    if (string[i] == '\0') {
+      /* end of string, return built string */
+      return g_string_free (gstring, FALSE);
     }
-  }
-
-  new_string[i] = '\0';
-
-  /* now free the original string */
-  g_free(string);
-
-  return(new_string);
-}
 
-/*! \todo Finish function documentation!!!
- *  \brief
- *  \par Function Description
- *
- */
-/* this function changes and then returns the string which has the 
- * expanded environment variables, frees passed in string */
-/* Environment variables MUST be in the form ${variable_name} */
-/* $variable_name is not valid here */
-char *s_expand_env_variables(char *string)
-{
-  char wanted_var[80]; /* size is hack */
-  char *return_string=NULL;
-  char *environment_string=NULL;
-  int changed=1;
-  int found_dollar=0;
-  int found_lbrac=0; 
-  int found_rbrac=0;
-  int start_of_variable= -1;
-  int end_of_variable= -1;
-  int count=0;
-  int i,j;
-
-  if (!string) {
-    return(NULL);
-  }
-
-  return_string = string;      
-
-  while(changed) {
-       
-    changed=0;
-    j=0;
-    for (i = 0 ; i < strlen(return_string); i++) {
-
-      switch(return_string[i]) {
-
-        case('$'):
-
-#if DEBUG
-          printf("found a $\n");
-#endif
-          found_dollar=1;      
-          start_of_variable=i;
-          break;
-
-        case('{'):
-          if (found_dollar) {
-            found_lbrac=1;
-            count=1;
+    i++;
+    switch (string[i]) {
+        case ('{'):
+          /* look for the end of the variable name */
+          start = i;
+          while (string[i] != '\0' && string[i] != '}') i++;
+          if (string[i] == '\0') {
+            /* problem: no closing '}' to variable */
+            fprintf (stderr,
+                     "Found malformed environment variable in '%s'\n",
+                     string);
+            g_string_append (gstring, "$");
+            g_string_append_len (gstring, string + start, i - start + 1);
+          } else {
+            gint j;
+
+            /* discard "${" */
+            start = start + 1;
+            /* test characters of variable name */
+            for (j = start;
+                 j < i && (g_ascii_isalnum (string[j]) || string[j] == '_');
+                 j++);
+            if (i != j) {
+              /* illegal character detected in variable name */
+              fprintf (stderr,
+                       "Found bad character [%c] in variable name.\n",
+                       string[j]);
+              g_string_append (gstring, "${");
+              g_string_append_len (gstring, string + start, i - start + 1);
+            } else {
+              /* extract variable name from string and expand it */
+              gchar *variable_name = g_strndup (string + start, i - start);
+              const gchar *env = g_getenv (variable_name);
+              g_free (variable_name);
+              g_string_append (gstring, (env == NULL) ? "" : env);
+            }
+            i++;
           }
           break;
 
-        case('}'):
-          if (found_dollar) {
-            found_rbrac=1;
-            /* ends filling of wanted_var */   
-            found_lbrac=0;
-            end_of_variable=i;
-          }
+        case ('$'):
+          /* an escaped '$' */
+          g_string_append_c (gstring, string[i++]);
           break;
-
-      }
-
-      /* the > 1 bit is so that we don't store the { */
-      if (found_dollar && found_lbrac && (count > 1)) {
-        wanted_var[j] = return_string[i];
-        j++; /* check for size */
-      }
-
-      /* skip over initial { */ 
-      count++;
-
-      if (found_rbrac && !found_lbrac) {
-        wanted_var[j] = '\0';
-#if DEBUG
-        printf("variable wanted: _%s_\n",  wanted_var);
-        printf("Between index: %d and %d\n", 
-               start_of_variable,
-               end_of_variable);
-#endif
-
-               
-        environment_string = getenv(wanted_var);       
-
-#if DEBUG
-        if (environment_string) {
-          printf("%s = _%s_\n", wanted_var, 
-                 environment_string);
-        }
-#endif
-
-        return_string = remove_string(return_string,
-                                      start_of_variable,
-                                      end_of_variable);
-
-#if DEBUG
-        printf("removed string: _%s_\n", return_string);
-#endif
-
-        if (environment_string) {
-          return_string = insert_string(
-                                        return_string,
-                                        start_of_variable,
-                                        environment_string);
-
-        }
-
-#if DEBUG
-        printf("final string: _%s_\n", return_string);
-#endif
-        changed=1;
-
-                               /* end of search */
-        found_dollar=0;
-        found_rbrac=0;
-        count=0;
-        start_of_variable= -1;
-        end_of_variable= -1;
-
-        break;
-      }
+          
+        default:
+          /* an isolated '$', put it in output */
+          g_string_append_c (gstring, '$');
     }
   }
 
-  if (found_dollar) {
-    fprintf(stderr, "Found malformed environment variable (use 
${varname})!\n");
-  }
-
-  return(return_string);
+  /* never reached */
+  return NULL;
 }
-- 
1.5.6




_______________________________________________
geda-dev mailing list
[email protected]
http://www.seul.org/cgi-bin/mailman/listinfo/geda-dev

Reply via email to