Rewrote o_attrib_get_name_value(): it now has support for UTF-8
attribute strings ; plus it can return only the name or the value or
both name and value.
Finally adapted code wherever it can benefits this new feature.
---
gnetlist/src/vams_misc.c | 4 +-
gschem/src/g_hook.c | 5 +-
gschem/src/o_misc.c | 5 +-
gschem/src/o_slot.c | 7 +---
gschem/src/x_dialog.c | 5 +--
gschem/src/x_multiattrib.c | 22 +++------
libgeda/include/prototype.h | 2 +-
libgeda/src/g_smob.c | 4 +-
libgeda/src/o_attrib.c | 96 ++++++++++++++---------------------------
libgeda/src/o_complex_basic.c | 4 +-
10 files changed, 51 insertions(+), 103 deletions(-)
diff --git a/gnetlist/src/vams_misc.c b/gnetlist/src/vams_misc.c
index 9b0d0ed..fb7094c 100644
--- a/gnetlist/src/vams_misc.c
+++ b/gnetlist/src/vams_misc.c
@@ -45,7 +45,6 @@ vams_get_attribs_list(OBJECT *object, SCM *list, OBJECT
**return_found)
OBJECT *found;
int val;
char* found_name = NULL;
- char* found_value = NULL;
o_current = object;
@@ -55,14 +54,13 @@ vams_get_attribs_list(OBJECT *object, SCM *list, OBJECT
**return_found)
found = a_current->object;
if (found != NULL && found->text && found->text->string) {
val = o_attrib_get_name_value(found->text->string,
- &found_name, &found_value);
+ &found_name, NULL);
if (val) {
*list = scm_cons (scm_makfrom0str (found_name), *list);
}
g_free(found_name);
- g_free(found_value);
#if DEBUG
printf("0 _%s_\n", found->text->string);
printf("1 _%s_\n", found_name);
diff --git a/gschem/src/g_hook.c b/gschem/src/g_hook.c
index 6368fe0..bb5963a 100644
--- a/gschem/src/g_hook.c
+++ b/gschem/src/g_hook.c
@@ -416,7 +416,7 @@ static void custom_world_get_single_object_bounds
GList *a_iter;
int rleft, rright, rbottom, rtop;
char *text_value;
- char *name_ptr, *value_ptr, aux_ptr[2];
+ char *name_ptr, aux_ptr[2];
gboolean include_text;
*left = rleft = toplevel->init_right;
@@ -437,7 +437,7 @@ static void custom_world_get_single_object_bounds
case (OBJ_TEXT):
if (obj_ptr->text && obj_ptr->text->string) {
text_value = obj_ptr->text->string;
- if (o_attrib_get_name_value(text_value, &name_ptr, &value_ptr) &&
+ if (o_attrib_get_name_value(text_value, &name_ptr, NULL) &&
g_list_find_custom(exclude_attrib_list, name_ptr,
(GCompareFunc) &strcmp)) {
include_text = FALSE;
}
@@ -450,7 +450,6 @@ static void custom_world_get_single_object_bounds
&rleft, &rtop, &rright,
&rbottom);
}
g_free(name_ptr);
- g_free(value_ptr);
}
break;
case (OBJ_COMPLEX):
diff --git a/gschem/src/o_misc.c b/gschem/src/o_misc.c
index b548d34..36a8bc0 100644
--- a/gschem/src/o_misc.c
+++ b/gschem/src/o_misc.c
@@ -817,17 +817,16 @@ void o_update_component(GSCHEM_TOPLEVEL *w_current,
OBJECT *o_current)
while (a_iter != NULL) {
a_current = a_iter->data;
OBJECT *o_attrib;
- gchar *name, *value;
+ gchar *name;
char *attrfound;
g_assert (a_current->object->type == OBJ_TEXT);
o_attrib_get_name_value (a_current->object->text->string,
- &name, &value);
+ &name, NULL);
attrfound = o_attrib_search_name_single(o_current, name, NULL);
/* free these now since they are no longer being used */
g_free(name);
- g_free(value);
if (attrfound == NULL) {
/* attribute with same name not found in old component: */
diff --git a/gschem/src/o_slot.c b/gschem/src/o_slot.c
index d8363d7..a47d7c4 100644
--- a/gschem/src/o_slot.c
+++ b/gschem/src/o_slot.c
@@ -113,13 +113,12 @@ void o_slot_end(GSCHEM_TOPLEVEL *w_current, char *string,
int len)
char *slot_value;
char *numslots_value;
OBJECT *slot_text_object;
- char *name = NULL;
char *value = NULL;
int numslots;
int new_slot_number;
int status;
- status = o_attrib_get_name_value(string, &name, &value);
+ status = o_attrib_get_name_value(string, NULL, &value);
if (!status) {
s_log_message(_("Slot attribute malformed\n"));
return;
@@ -142,7 +141,6 @@ void o_slot_end(GSCHEM_TOPLEVEL *w_current, char *string,
int len)
s_log_message(_("numslots attribute missing\n"));
s_log_message(
_("Slotting not allowed for this component\n"));
- g_free(name);
g_free(value);
return;
}
@@ -158,7 +156,6 @@ void o_slot_end(GSCHEM_TOPLEVEL *w_current, char *string,
int len)
if (new_slot_number > numslots || new_slot_number <=0 ) {
s_log_message(_("New slot number out of range\n"));
- g_free(name);
g_free(value);
return;
}
@@ -223,13 +220,11 @@ void o_slot_end(GSCHEM_TOPLEVEL *w_current, char *string,
int len)
o_redraw_single(w_current,object);
toplevel->page_current->CHANGED = 1;
- g_free(name);
g_free(value);
} else {
fprintf(stderr,
_("uggg! you tried to slot edit something that doesn't exist!\n"));
- g_free(name);
g_free(value);
exit(-1);
}
diff --git a/gschem/src/x_dialog.c b/gschem/src/x_dialog.c
index 180fbbf..c25f468 100644
--- a/gschem/src/x_dialog.c
+++ b/gschem/src/x_dialog.c
@@ -4072,10 +4072,9 @@ x_dialog_close_window (GSCHEM_TOPLEVEL *w_current)
int x_dialog_validate_attribute(GtkWindow* parent, char *attribute)
{
GtkWidget* message_box;
- char *name_ptr, *value_ptr;
/* validate the new attribute */
- if (!o_attrib_get_name_value(attribute, &name_ptr, &value_ptr)) {
+ if (!o_attrib_get_name_value(attribute, NULL, NULL)) {
message_box = gtk_message_dialog_new_with_markup (parent,
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
@@ -4087,8 +4086,6 @@ int x_dialog_validate_attribute(GtkWindow* parent, char
*attribute)
gtk_widget_destroy (message_box);
return FALSE;
}
- g_free(name_ptr);
- g_free(value_ptr);
return TRUE;
}
/***************** End of misc helper dialog boxes **************/
diff --git a/gschem/src/x_multiattrib.c b/gschem/src/x_multiattrib.c
index 4aeebe8..679d428 100644
--- a/gschem/src/x_multiattrib.c
+++ b/gschem/src/x_multiattrib.c
@@ -536,19 +536,18 @@ static void
multiattrib_column_set_data_name(GtkTreeViewColumn *tree_column,
gpointer data)
{
OBJECT *o_attrib;
- gchar *name, *value;
+ gchar *name;
gtk_tree_model_get (tree_model, iter,
COLUMN_ATTRIBUTE, &o_attrib,
-1);
g_assert (o_attrib->type == OBJ_TEXT);
- o_attrib_get_name_value (o_attrib->text->string, &name, &value);
+ o_attrib_get_name_value (o_attrib->text->string, &name, NULL);
g_object_set (cell,
"text", name,
NULL);
g_free (name);
- g_free (value);
}
@@ -564,18 +563,17 @@ static void
multiattrib_column_set_data_value(GtkTreeViewColumn *tree_column,
gpointer data)
{
OBJECT *o_attrib;
- gchar *name, *value;
+ gchar *value;
gtk_tree_model_get (tree_model, iter,
COLUMN_ATTRIBUTE, &o_attrib,
-1);
g_assert (o_attrib->type == OBJ_TEXT);
- o_attrib_get_name_value (o_attrib->text->string, &name, &value);
+ o_attrib_get_name_value (o_attrib->text->string, NULL, &value);
g_object_set (cell,
"text", value,
NULL);
- g_free (name);
g_free (value);
}
@@ -690,7 +688,7 @@ static void
multiattrib_callback_edited_name(GtkCellRendererText *cellrendererte
GtkTreeIter iter;
OBJECT *o_attrib;
GSCHEM_TOPLEVEL *w_current;
- gchar *name, *value, *newtext;
+ gchar *value, *newtext;
model = gtk_tree_view_get_model (multiattrib->treeview);
w_current = GSCHEM_DIALOG (multiattrib)->w_current;
@@ -717,11 +715,10 @@ static void
multiattrib_callback_edited_name(GtkCellRendererText *cellrendererte
-1);
g_assert (o_attrib->type == OBJ_TEXT);
- o_attrib_get_name_value (o_attrib->text->string, &name, &value);
+ o_attrib_get_name_value (o_attrib->text->string, NULL, &value);
newtext = g_strdup_printf ("%s=%s", arg2, value);
if (!x_dialog_validate_attribute(GTK_WINDOW(multiattrib), newtext)) {
- g_free (name);
g_free (value);
g_free(newtext);
return;
@@ -732,7 +729,6 @@ static void
multiattrib_callback_edited_name(GtkCellRendererText *cellrendererte
o_text_change (w_current, o_attrib,
newtext, o_attrib->visibility, o_attrib->show_name_value);
- g_free (name);
g_free (value);
g_free (newtext);
@@ -753,7 +749,7 @@ static void
multiattrib_callback_edited_value(GtkCellRendererText *cell_renderer
GtkTreeIter iter;
OBJECT *o_attrib;
GSCHEM_TOPLEVEL *w_current;
- gchar *name, *value, *newtext;
+ gchar *name, *newtext;
model = gtk_tree_view_get_model (multiattrib->treeview);
w_current = GSCHEM_DIALOG (multiattrib)->w_current;
@@ -767,12 +763,11 @@ static void
multiattrib_callback_edited_value(GtkCellRendererText *cell_renderer
-1);
g_assert (o_attrib->type == OBJ_TEXT);
- o_attrib_get_name_value (o_attrib->text->string, &name, &value);
+ o_attrib_get_name_value (o_attrib->text->string, &name, NULL);
newtext = g_strdup_printf ("%s=%s", name, arg2);
if (!x_dialog_validate_attribute(GTK_WINDOW(multiattrib), newtext)) {
g_free (name);
- g_free (value);
g_free(newtext);
return;
}
@@ -785,7 +780,6 @@ static void
multiattrib_callback_edited_value(GtkCellRendererText *cell_renderer
update_row_display (model, &iter);
g_free (name);
- g_free (value);
g_free (newtext);
}
diff --git a/libgeda/include/prototype.h b/libgeda/include/prototype.h
index f1c08d3..82e69d8 100644
--- a/libgeda/include/prototype.h
+++ b/libgeda/include/prototype.h
@@ -106,7 +106,7 @@ void o_attrib_attach(TOPLEVEL *toplevel, OBJECT
*parent_list, OBJECT *text_objec
void o_attrib_free_all(TOPLEVEL *toplevel, GList *list);
void o_attrib_print(GList *attributes);
void o_attrib_remove(GList **list, OBJECT *remove);
-int o_attrib_get_name_value(char *string, char **name, char **value);
+gboolean o_attrib_get_name_value (const gchar *string, gchar **name_ptr, gchar
**value_ptr);
void o_attrib_free_current(TOPLEVEL *toplevel);
void o_attrib_set_string(TOPLEVEL *toplevel, char *string);
void o_attrib_set_color(TOPLEVEL *toplevel, GList *attributes);
diff --git a/libgeda/src/g_smob.c b/libgeda/src/g_smob.c
index ca2527e..fc1b0c9 100644
--- a/libgeda/src/g_smob.c
+++ b/libgeda/src/g_smob.c
@@ -164,7 +164,6 @@ SCM g_set_attrib_value_internal(SCM attrib_smob, SCM
scm_value,
struct st_attrib_smob *attribute;
char *name = NULL;
char *value = NULL;
- char *old_value = NULL;
SCM_ASSERT ( SCM_NIMP(attrib_smob) &&
((long) SCM_CAR(attrib_smob) == attrib_smob_tag),
@@ -182,7 +181,7 @@ SCM g_set_attrib_value_internal(SCM attrib_smob, SCM
scm_value,
attribute->attribute->object->text->string ) {
o_attrib_get_name_value(attribute->attribute->object->text->string,
- &name, &old_value );
+ &name, NULL);
*new_string = g_strconcat (name, "=", value, NULL);
@@ -190,7 +189,6 @@ SCM g_set_attrib_value_internal(SCM attrib_smob, SCM
scm_value,
*o_attrib = attribute->attribute->object;
g_free(name);
- g_free(old_value);
}
return SCM_UNDEFINED;
diff --git a/libgeda/src/o_attrib.c b/libgeda/src/o_attrib.c
index eb29775..962789c 100644
--- a/libgeda/src/o_attrib.c
+++ b/libgeda/src/o_attrib.c
@@ -571,79 +571,52 @@ gchar *o_save_attribs(GList *attribs)
return g_string_free(acc, FALSE);
}
-/*! \brief Get name and value from name=value attribute.
+/*! \brief Get name and value from an attribute 'name=value' string.
* \par Function Description
- * Get name and value from a name=value attribute.
+ * This function parses the character string \a string expected to be
+ * an attribute string of the form 'name=value'.
*
- * \param [in] string String to split into name/value pair.
- * \param [out] name_ptr Name if found in string, NULL otherwise.
- * \param [out] value_ptr Value if found in string, NULL otherwise.
- * \return TRUE if string had equals in it, FALSE otherwise.
+ * It returns TRUE if it has been able to parse the string into the
+ * name and value parts of an attribute. Otherwise it returns FALSE,
+ * in that case \a *name_ptr and \a *value_ptr are unset.
*
- * \note
- * both name and value must be pre allocated
- * And if you get an invalid attribute (improper) with a name and no
- * value, then it is NOT an attribute.
- * Also, there cannot be any spaces beside the equals sign
- * Changed: now it allocates memory for name and value strings.
- * \warning
- * Caller must g_free these strings when not needed.
+ * \a name_ptr and/or \a value_ptr can be NULL.
+ *
+ * \param [in] string String to split into name/value pair.
+ * \param [out] name_ptr The return location for the name, or NULL.
+ * \param [out] value_ptr The return location for the value, or NULL.
+ * \return TRUE on success, FALSE otherwise.
*/
-int o_attrib_get_name_value(char *string, char **name_ptr, char **value_ptr )
+gboolean
+o_attrib_get_name_value (const gchar *string, gchar **name_ptr, gchar
**value_ptr)
{
- char *equal_ptr;
- char **str_array;
+ gchar *ptr, *prev_char, *next_char;
+
+ g_return_val_if_fail (string != NULL, FALSE);
- if (name_ptr == NULL || value_ptr == NULL) {
- return(FALSE);
+ ptr = g_utf8_strchr (string, -1, g_utf8_get_char ("="));
+ if (ptr == NULL) {
+ return FALSE;
}
- *name_ptr = NULL; /* force these values to null */
- *value_ptr = NULL;
-
- if (!string) {
- return(FALSE);
+ prev_char = g_utf8_find_prev_char (string, ptr);
+ next_char = g_utf8_find_next_char (ptr, NULL);
+ if ((prev_char == NULL) ||
+ g_unichar_isspace (g_utf8_get_char (prev_char)) ||
+ ((next_char != NULL) &&
+ g_unichar_isspace (g_utf8_get_char (next_char)))) {
+ return FALSE;
}
- /* make sure there are no spaces in between equals */
- equal_ptr = strchr(string, '=');
- if (equal_ptr == NULL) {
- return(FALSE);
+ if (name_ptr != NULL) {
+ *name_ptr = g_strndup (string, (ptr - string));
}
-
- /*! \todo Technically this isn't a correct if statement. This if will
- * cause an invalid read for strings: =name and value=
- */
- if ( (*(equal_ptr + 1) == ' ') || (*(equal_ptr - 1) == ' ') ) {
- /* sometimes you have text with an ='s in it, it shouldn't be */
- /* treated like an attribute */
-
-#if DEBUG
- s_log_message("Found attrib/text with spaces beside the ='s [%s]\n",
- string);
- s_log_message("You can ignore the above message if the text is not
intended to be an attribute\n");
-#endif
-
- return(FALSE);
+ if (value_ptr != NULL) {
+ *value_ptr = g_strdup (next_char != NULL ? next_char : "");
}
- str_array = g_strsplit (string, "=", 2);
-
- *name_ptr = g_strdup(str_array[0]);
- *value_ptr = g_strdup(str_array[1]);
- g_strfreev(str_array);
-
- if (*value_ptr && (*value_ptr)[0] == '\0') {
- s_log_message(_("Found an improper attribute: _%s_\n"), string);
-#if 0 /* for now leak this memory till this is verified correct everywhere */
- g_free(*name_ptr); *name_ptr = NULL;
- g_free(*value_ptr); *value_ptr = NULL;
-#endif
- return(FALSE);
- } else {
- return(TRUE);
- }
+ return TRUE;
}
/*! \brief Free the currently selected attribute.
@@ -934,7 +907,6 @@ char *o_attrib_search_string_partial(OBJECT *object, char
*search_for,
OBJECT *o_current;
int val;
int internal_counter=0;
- char *found_name = NULL;
char *found_value = NULL;
char *return_string = NULL;
@@ -950,10 +922,9 @@ char *o_attrib_search_string_partial(OBJECT *object, char
*search_for,
internal_counter++;
} else {
val = o_attrib_get_name_value(o_current->text->string,
- &found_name, &found_value);
+ NULL, &found_value);
if (val) {
return_string = g_strdup(found_value);
- g_free(found_name);
g_free(found_value);
return(return_string);
}
@@ -961,7 +932,6 @@ char *o_attrib_search_string_partial(OBJECT *object, char
*search_for,
}
}
- g_free(found_name);
g_free(found_value);
return (NULL);
}
diff --git a/libgeda/src/o_complex_basic.c b/libgeda/src/o_complex_basic.c
index 03cd837..0b8bddb 100644
--- a/libgeda/src/o_complex_basic.c
+++ b/libgeda/src/o_complex_basic.c
@@ -231,7 +231,6 @@ int o_complex_is_eligible_attribute (TOPLEVEL *toplevel,
OBJECT *object,
int promote_invisible)
{
char *name = NULL;
- char *value = NULL;
char *padded_name = NULL;
int promotableAttribute = FALSE;
char *ptr;
@@ -260,7 +259,7 @@ int o_complex_is_eligible_attribute (TOPLEVEL *toplevel,
OBJECT *object,
if (toplevel->always_promote_attributes &&
(strlen(toplevel->always_promote_attributes) != 0))
{
- if (o_attrib_get_name_value(object->text->string, &name, &value))
+ if (o_attrib_get_name_value(object->text->string, &name, NULL))
{
padded_name = g_strdup_printf(" %s ", name);
if (strstr(toplevel->always_promote_attributes, padded_name))
@@ -272,7 +271,6 @@ int o_complex_is_eligible_attribute (TOPLEVEL *toplevel,
OBJECT *object,
g_free(padded_name);
g_free(name);
- g_free(value);
if (promotableAttribute)
return TRUE;
}
--
1.5.6
_______________________________________________
geda-dev mailing list
[email protected]
http://www.seul.org/cgi-bin/mailman/listinfo/geda-dev