---
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