示例#1
0
/*! \brief Find an attribute in a list.
 *  \par Function Description
 *  Search for attribute by name.
 *
 *  Counter is the n'th occurance of the attribute, and starts searching
 *  from zero.  Zero is the first occurance of an attribute.
 *
 *  \param [in] list     GList of attributes to search.
 *  \param [in] name     Character string with attribute name to search for.
 *  \param [in] count    Which occurance to return.
 *  \return The n'th attribute object in the given list with the given name.
 */
OBJECT *o_attrib_find_attrib_by_name (const GList *list, char *name, int count)
{
  OBJECT *a_current;
  const GList *iter;
  char *found_name;
  int internal_counter = 0;

  for (iter = list; iter != NULL; iter = g_list_next (iter)) {
    a_current = iter->data;

    g_return_val_if_fail (a_current->type == OBJ_TEXT, NULL);

    if (!o_attrib_get_name_value (a_current, &found_name, NULL))
      continue;

    if (strcmp (name, found_name) == 0) {
      if (internal_counter == count) {
        g_free (found_name);
        return a_current;
      }
      internal_counter++;
    }

    g_free (found_name);
  }

  return NULL;
}
示例#2
0
/*! \brief check whether an object is a attributes
 *  \par Function Description
 *  This function checks if an object should be promoted.
 *  An attribute object is promotable if it's promoted by default, or the user
 *  has configered it to promote an attribute.
 *
 *  \param [in] toplevel  The TOPLEVEL object
 *  \param [in] object    The attribute object to check
 *  \return TRUE if the object is a eligible attribute, FALSE otherwise
 */
static int o_complex_is_eligible_attribute (TOPLEVEL *toplevel, OBJECT *object)
{
  char *name = NULL;
  int promotableAttribute = FALSE;

  /* always promote symversion= attribute, even if it is invisible */
  if (strncmp(object->text->string, "symversion=", 11) == 0)
    return TRUE;
  
  /* check list against attributes which can be promoted */
  if (toplevel->always_promote_attributes != NULL) {
    if (o_attrib_get_name_value (object, &name, NULL)) {
      if (g_list_find_custom(toplevel->always_promote_attributes,
			     name, (GCompareFunc) strcmp) != NULL) {
        /* Name of the attribute was in the always promote attributes list */
        promotableAttribute = TRUE;
      }

      g_free(name);
      if (promotableAttribute)
        return TRUE;
    }
  }

  /* object is invisible and we do not want to promote invisible text */
  if ((!o_is_visible (toplevel, object)) &&
      (toplevel->promote_invisible == FALSE))
    return FALSE; /* attribute not eligible for promotion */

  /* yup, attribute can be promoted */
  return TRUE;
}
示例#3
0
/*! \brief Search list for partial string match.
 *  \par Function Description
 *  Search list for partial string match.
 *
 *  Counter is the n'th occurance of the attribute, and starts searching
 *  from zero.  Zero is the first occurance of an attribute.
 *
 *  \param [in] object      The OBJECT list to search.
 *  \param [in] search_for  Partial character string to search for.
 *  \param [in] counter     Which occurance to return.
 *  \return Matching object value if found, NULL otherwise.
 *
 *  \warning
 *  Caller must g_free returned character string.
 */
char *o_attrib_search_string_partial(OBJECT *object, char *search_for,
				     int counter) 
{
  OBJECT *o_current;
  int val;
  int internal_counter=0;
  char *found_value = NULL;
  char *return_string = NULL;

  o_current = object;

  if (o_current == NULL) {
    return(NULL);
  }

  if (o_current->type == OBJ_TEXT) {
    if (strstr(o_current->text->string, search_for)) {
      if (counter != internal_counter) {
        internal_counter++;	
      } else {
        val = o_attrib_get_name_value(o_current->text->string, 
                                      NULL, &found_value);
        if (val) {
          return_string = g_strdup(found_value);
	  g_free(found_value);
	  return(return_string);
        }
      }
    }
  }	
	
  g_free(found_value);
  return (NULL);
} 
示例#4
0
/*! \brief Search attribute list by name.
 *  \par Function Description
 *  Search for attribute by name.
 *
 *  Counter is the n'th occurance of the attribute, and starts searching
 *  from zero.  Zero is the first occurance of an attribute.
 *
 *  \param [in] list     GList of attributes to search.
 *  \param [in] name     Character string with attribute name to search for.
 *  \param [in] counter  Which occurance to return.
 *  \return Character string with attribute value, NULL otherwise.
 */
static char *o_attrib_search_attrib_list_by_name (const GList *list, char *name, int counter)
{
  OBJECT *attrib;
  char *value = NULL;

  attrib = o_attrib_find_attrib_by_name (list, name, counter);

  if (attrib != NULL)
    o_attrib_get_name_value (attrib, NULL, &value);

  return value;
}
示例#5
0
/*! \brief Search for attribute by value and name.
 *  \par Function Description
 *  Search for attribute by value and name.
 *  
 *  Counter is the n'th occurance of the attribute, and starts searching
 *  from zero.  Zero is the first occurance of an attribute.
 *
 *  The value is the primary search key, but name is checked before
 *  an OBJECT is returned to ensure the correct OBJECT has been found.
 *
 *  \param [in] list     The attribute OBJECT list to search.
 *  \param [in] value    Character string with value to search for.
 *  \param [in] name     Character string with name to compare.
 *  \param [in] counter  Which occurance to return.
 *  \return The attribute OBJECT if found, NULL otherwise.
 *
 */
OBJECT *o_attrib_search_attrib_value(GList *list, char *value, char *name,
				     int counter) 
{
  OBJECT *a_current;
  GList *a_iter;
  int val;
  int internal_counter=0;
  char *found_name = NULL;
  char *found_value = NULL;

  a_iter = list;
	
  if (!value) 
  return(NULL);

  if (!name) 
  return(NULL);

  while(a_iter != NULL) {
    a_current = a_iter->data;
    if (a_current->type == OBJ_TEXT) {
      val = o_attrib_get_name_value(a_current->text->string,
                                    &found_name, &found_value);

      if (val) {
#if DEBUG
        printf("found value: %s\n", found_value);
        printf("looking for: %s\n", value);
#endif
        if (strcmp(value, found_value) == 0) {
          if (counter != internal_counter) {
            internal_counter++;
          } else {
            if (strstr(found_name, name)) {
              g_free(found_name);
              g_free(found_value);
              return a_current;
            }
          }
        }
        if (found_name) { g_free(found_name); found_name = NULL; }
        if (found_value) { g_free(found_value); found_value = NULL; }
      }

    }
    a_iter = g_list_next (a_iter);
  }

  g_free(found_name);
  g_free(found_value);
  return (NULL);
} 
示例#6
0
/*! \todo Finish function documentation!!!
 *  \brief
 *  \par Function Description
 *
 */
void o_edit(GSCHEM_TOPLEVEL *w_current, GList *list)
{
  OBJECT *o_current;
  const gchar *str = NULL;

  if (list == NULL) {
    w_current->inside_action = 0;
    i_set_state(w_current, SELECT);
    return;
  }

  o_current = (OBJECT *) list->data;
  if (o_current == NULL) {
    fprintf(stderr, _("Got an unexpected NULL in o_edit\n"));
    exit(-1);
  }

  /* for now deal with only the first item */
  switch(o_current->type) {

    /* also add the ability to multi attrib edit: nets, busses, pins */
    case(OBJ_COMPLEX):
    case(OBJ_PLACEHOLDER):
    case(OBJ_NET):
    case(OBJ_PIN):
    case(OBJ_BUS):
    x_multiattrib_open (w_current);
    break;

    case(OBJ_PICTURE):
    picture_change_filename_dialog(w_current);
    break;
    case(OBJ_ARC):
    arc_angle_dialog(w_current, o_current);
    break;
    case(OBJ_TEXT):
      str = o_text_get_string (w_current->toplevel, o_current);
      if (o_attrib_get_name_value (o_current, NULL, NULL) &&
        /* attribute editor only accept 1-line values for attribute */
        o_text_num_lines (str) == 1) {
        attrib_edit_dialog(w_current,o_current, FROM_MENU);
    } else {
      o_text_edit(w_current, o_current);
    }
    break;
  }

  /* has to be more extensive in the future */
  /* some sort of redrawing? */
}
示例#7
0
/*! \brief update the visible part of a string
 *  \par Function Description
 *  If a string is an attribute, then it is possible to hide
 *  the name or the value part of the attribute string.
 *  This functions updates the text->disp_string according
 *  to the object->show_name_value settings
 *
 *  \param [in] object  The OBJECT to update
 */
static void
update_disp_string (OBJECT *object)
{
  char *name = NULL;
  char *value = NULL;
  TEXT *text = object->text;

  g_free (text->disp_string);

  if (o_attrib_get_name_value (object, &name, &value)) {
    switch (object->show_name_value) {
      case (SHOW_NAME_VALUE):
        text->disp_string = g_strdup (text->string);
        break;

      case (SHOW_NAME):
        if (name[0] != '\0') {
          text->disp_string = g_strdup (name);
        } else {
          g_critical ("Got an improper attribute: %1$s\n",
                      text->string);
          text->disp_string = g_strdup ("invalid");
        }
        break;

      case (SHOW_VALUE):
        if (value[0] != '\0') {
          text->disp_string = g_strdup(value);
        } else {
          g_critical ("Got an improper attribute: %1$s\n",
                      text->string);
          text->disp_string = g_strdup ("invalid");
        }
        break;
    }

    text->name = g_intern_string (name);

    /* free the strings allocated by o_attrib_get_name_value */
    g_free(name);
    g_free(value);
  } else {
    text->disp_string = g_strdup (text->string);
    text->name = NULL;
  }
}
示例#8
0
文件: s_slot.c 项目: SayCV/geda-gaf
/*! \brief Search for slot attribute.
 *  \par Function Description
 *  Search for slot attribute.
 *
 *  The returned value will only come from an attached attribute.
 *
 *  \param [in] object        OBJECT list to search.
 *  \param [in] return_found  attached slot attribute if found, NULL otherwise.
 *  \return Character string with attribute value, NULL otherwise.
 *
 *  \warning
 *  Caller must g_free returned character string
 */
char *s_slot_search_slot (OBJECT *object, OBJECT **return_found)
{
  GList *attributes;
  OBJECT *attrib;
  char *value = NULL;

  attributes = o_attrib_return_attribs (object);
  attrib = o_attrib_find_attrib_by_name (attributes, "slot", 0);
  g_list_free (attributes);

  if (attrib != NULL)
    o_attrib_get_name_value (attrib, NULL, &value);

  if (return_found)
    *return_found = attrib;

  return value;
}
示例#9
0
/*! \brief Search TOPLEVEL attributes.
 *  \par Function Description
 *  This function should only be used to search for TOPLEVEL attributes.
 *  \warning
 *  The list is the top level list. Do not pass it an object_list list
 *  unless you know what you are doing.
 *  
 *  Counter is the n'th occurance of the attribute, and starts searching
 *  from zero.  Zero is the first occurance of an attribute.
 * 
 *  \param [in] list     The GList to search (TOPLEVEL only).
 *  \param [in] name     Character string of attribute name to search for.
 *  \param [in] counter  Which occurance to return.
 *  \return Character string with attribute value, NULL otherwise.
 *
 *  \warning
 *  Caller must g_free returned character string.
 */
char *o_attrib_search_toplevel (const GList *list, char *name, int counter)
{
  OBJECT *o_current;
  int val;
  int internal_counter=0;
  char *found_name = NULL;
  char *found_value = NULL;
  char *return_string = NULL;
  const GList *iter;

  iter = list;

  while (iter != NULL) {
    o_current = (OBJECT *)iter->data;

    /* search for attributes outside */

    if (o_current->type == OBJ_TEXT) {
      val = o_attrib_get_name_value(o_current->text->string, 
                                    &found_name, &found_value);
      if (val) {
        if (strcmp(name, found_name) == 0) {
          if (counter != internal_counter) {
            internal_counter++;	
          } else {
            return_string = g_strdup (found_value);
	    g_free(found_name);
	    g_free(found_value);
            return(return_string);
          }
        }
	if (found_name) { g_free(found_name); found_name = NULL; }
	if (found_value) { g_free(found_value); found_value = NULL; }
      }	
    }

    iter = g_list_next (iter);
  }
	
  g_free(found_name);
  g_free(found_value);
  return (NULL);
} 
示例#10
0
/*! \brief Find all floating attributes in the given object list.
 *  \par Function Description
 *  Find all floating attributes in the given object list.
 *
 *  \param [in] list  GList of OBJECTs to search for floating attributes.
 *  \return GList of floating attributes from the input list
 *
 *  \warning
 *  Caller must g_list_free returned list.
 */
GList *o_attrib_find_floating_attribs (const GList *list)
{
  GList *floating_attributes = NULL;
  const GList *iter;
  OBJECT *o_current;

  for (iter = list; iter != NULL; iter = g_list_next (iter)) {
    o_current = iter->data;

    /* Skip non text objects, attached attributes and text which doesn't
     * constitute a valid attributes (e.g. general text placed on the page)
     */
    if (o_current->type == OBJ_TEXT &&
        o_current->attached_to == NULL &&
        o_attrib_get_name_value (o_current, NULL, NULL)) {

      floating_attributes = g_list_prepend (floating_attributes, o_current);
    }
  }

  return g_list_reverse (floating_attributes);
}
示例#11
0
/*! \brief Get all attached attributes of the specified OBJECT.
 *  \par Function Description
 *  This function returns all attributes of the specified object.
 *
 *  The returned GList should be freed using the #g_list_free().
 *
 *  This function aggregates the attached and inherited attributes
 *  belonging to a given OBJECT. (inherited attributes are those
 *  which live as toplevel un-attached attributes inside in a
 *  complex OBJECT's prim_objs).
 *
 *  \param [in] object       OBJECT whos attributes to return.
 *  \return A GList of attributes belinging to the passed object.
 */
GList * o_attrib_return_attribs (OBJECT *object)
{
  GList *attribs = NULL;
  GList *inherited_attribs;
  OBJECT *a_current;
  GList *a_iter;

  g_return_val_if_fail (object != NULL, NULL);

  /* Directly attached attributes */
  for (a_iter = object->attribs; a_iter != NULL;
       a_iter = g_list_next (a_iter)) {
    a_current = a_iter->data;

    if (a_current->type != OBJ_TEXT)
      continue;

    /* Don't add invalid attributes to the list */
    if (!o_attrib_get_name_value (a_current, NULL, NULL))
      continue;

    attribs = g_list_prepend (attribs, a_current);
  }

  attribs = g_list_reverse (attribs);

  /* Inherited attributes (inside complex objects) */
  if (object->type == OBJ_COMPLEX ||
      object->type == OBJ_PLACEHOLDER) {

    inherited_attribs =
      o_attrib_find_floating_attribs (object->complex->prim_objs);

    attribs = g_list_concat (attribs, inherited_attribs);
  }

  return attribs;
}
示例#12
0
/*! \brief Update component attributes in TOP_LEVEL
 *
 * For each attrib string attached to the component, update it using the value
 * held in new_comp_attrib_list.  Algorithm:
 * -# Form list of all component attribs held on both the component
 *    (o_current), as well as in the attrib list (SHEET_DATA).
 * -# Loop over name=value pairs held in complete_comp_attrib_list.
 * -# For each name=value pair, look for corresponding attrib on o_current.
 * -# For each name=value pair, look for the corresponding attrib in
 *    new_comp_attrib_list.
 * -# If the attrib exists on o_current and in new_comp_attrib_list, write the
 *    new value (from new_comp_attrib_list) into o_current.
 * -# If the attrib exists on o_current, but is null in name=value pair,
 *    delete the attrib from o_current.
 * -# If the attribs doesn't exist on o_current, but is non-null in
 *    the name=value pair, create an attrib object and add it to the part
 *    on o_current.
 * \param toplevel TOPLEVEL structure
 * \param o_current Component (complex) to be updated.
 * \param new_comp_attrib_list list of name=value attribute pairs
 *                             from SHEET_DATA.
 */
void
s_toplevel_update_component_attribs_in_toplevel (
    TOPLEVEL *toplevel,
    OBJECT *o_current,
    STRING_LIST *new_comp_attrib_list)
{
    STRING_LIST *local_list;
    STRING_LIST *complete_comp_attrib_list;
    char *old_name_value_pair;
    char *new_attrib_name;
    char *new_attrib_value;
    char *old_attrib_name;
    char *old_attrib_value;
    gchar *refdes;
    GList *a_iter;
    OBJECT *a_current;
    int count = 0;  /* This is to fake out a function called later */
    gint row, col;
    gint visibility = 0;
    gint show_name_value = 0;

#if DEBUG
    printf("-----  Entering s_toplevel_update_component_attribs_in_toplevel.\n");
#endif

    /*
     * To remove dead attribs from o_current, we need to form a complete list of unique
     * attribs by taking the union of the new attribs from the SHEET_DATA, and
     * the old attribs living on o_current.  That's what we're doing here.
     * Later, we can delete those attribs in o_current which don't apear in
     * new_comp_attrib_list.
     */
    /* First duplicate new_comp_attrib_list */
    complete_comp_attrib_list = s_string_list_duplicate_string_list(new_comp_attrib_list);

    /* Now create a complete list of unique attribute names.  This will be used in
    *  the loop below when updating attributes.  */
    a_iter = o_current->attribs;
    while (a_iter != NULL) {
        a_current = a_iter->data;
        if (a_current->type == OBJ_TEXT
                && a_current->text != NULL) {  /* found a name=value attribute pair. */
            /* may need to check more thoroughly here. . . . */
            old_name_value_pair = g_strdup(a_current->text->string);

            /* Else clause is suggestion from Ales */
#if 1
            old_attrib_name = u_basic_breakup_string(old_name_value_pair, '=', 0);
            if ( (strcmp(old_attrib_name, "refdes") != 0) &&
                    (strcmp(old_attrib_name, "net") != 0) &&
                    (strcmp(old_attrib_name, "slot") != 0) &&
                    (s_attrib_name_in_list(new_comp_attrib_list, old_attrib_name) == FALSE) ) {
                s_string_list_add_item(complete_comp_attrib_list, &count, old_name_value_pair);
            }
#else
            /* might now compile now, but this #if'd out branch isn't being built */
            gint status;
            status = o_attrib_get_name_value (a_current, &old_attrib_name, &old_attrib_value);
            if (status == 0) {
                /* Don't put "refdes" or "slot" into list.  Don't put old name=value pair into list if a new
                 * one is already in there. */
                if ( (strcmp(old_attrib_name, "refdes") != 0) &&
                        (strcmp(old_attrib_name, "net") != 0) &&
                        (strcmp(old_attrib_name, "slot") != 0) &&
                        (s_attrib_name_in_list(new_comp_attrib_list, old_attrib_name) == FALSE) ) {
                    s_string_list_add_item(complete_comp_attrib_list, &count, old_name_value_pair);
                }
                g_free (old_attrib_name);
                g_free (old_attrib_value);
            }
#endif
            g_free(old_name_value_pair);
            g_free(old_attrib_name);
        }
        a_iter = g_list_next (a_iter);
    }  /* while (a_current != NULL) */


    /*
     *Now the main business of this function:  updating the attribs attached to this o_current.
     * Loop on name=value pairs held in complete_comp_attrib_list , and then use this to get the
     * name=value pairs out of new_comp_attrib_list and from o_current.
     */

    /* First handle a special case: the component has no attribs (beside refdes). */
    if (complete_comp_attrib_list->data == NULL)
        return;

    /* Now the normal case. . . . */
    local_list = complete_comp_attrib_list;
    while (local_list != NULL) {

#if DEBUG
        printf("\n\n");
        printf("        In s_toplevel_update_component_attribs_in_toplevel, handling entry in complete list %s .\n",
               local_list->data);
#endif

        /*  Now get the old attrib name & value from complete_comp_attrib_list
         *  and value from o_current  */
        old_attrib_name = u_basic_breakup_string(local_list->data, '=', 0);
        old_attrib_value = o_attrib_search_attached_attribs_by_name (o_current, old_attrib_name, 0);

#if DEBUG
        printf("        In s_toplevel_update_component_attribs_in_toplevel, old name = \"%s\" .\n",
               old_attrib_name);
        printf("        In s_toplevel_update_component_attribs_in_toplevel, old value = \"%s\" .\n",
               old_attrib_value);
#endif

        /*  Next try to get this attrib from new_comp_attrib_list  */
        new_attrib_name = u_basic_breakup_string(local_list->data, '=', 0);
        if (s_string_list_in_list(new_comp_attrib_list, local_list->data)) {
            new_attrib_value = s_misc_remaining_string(local_list->data, '=', 1);
        } else {
            new_attrib_value = NULL;
        }
#if DEBUG
        printf("        In s_toplevel_update_component_attribs_in_toplevel, new name = \"%s\" .\n",
               new_attrib_name);
        printf("        In s_toplevel_update_component_attribs_in_toplevel, new value = \"%s\" .\n",
               new_attrib_value);
#endif

        /* Now get row and col where this new attrib lives.  Then get
         * visibility of the new attrib stored in the component table */
        /* We'll need this later */
        refdes = g_strdup(s_attrib_get_refdes(o_current));
        row = s_table_get_index(sheet_head->master_comp_list_head, refdes);
        col = s_table_get_index(sheet_head->master_comp_attrib_list_head, new_attrib_name);
        /* if attribute has been deleted from the sheet, here is where we detect that */
        if ( (row == -1) || (col == -1) ) {
            new_attrib_value = NULL;  /* attrib will be deleted below */
        } else { /* we need a better place to get this info since the TABLE can be out of date */
            visibility = sheet_head->component_table[row][col].visibility;
            show_name_value = sheet_head->component_table[row][col].show_name_value;
        }
        g_free(refdes);


        /* -------  Four cases to consider: Case 1 ----- */
        if ( (old_attrib_value != NULL) && (new_attrib_value != NULL) && (strlen(new_attrib_value) != 0) ) {
            /* simply write new attrib into place of old one. */
#if DEBUG
            printf("     -- In s_toplevel_update_component_attribs_in_toplevel,\n");
            printf("               about to replace old attrib with name= %s, value= %s\n",
                   new_attrib_name, new_attrib_value);
            printf("               visibility = %d, show_name_value = %d.\n",
                   visibility, show_name_value);
#endif
            s_object_replace_attrib_in_object(toplevel,
                                              o_current,
                                              new_attrib_name,
                                              new_attrib_value,
                                              visibility,
                                              show_name_value);
        }

        /* -------  Four cases to consider: Case 2 ----- */
        else if ( (old_attrib_value != NULL) && (new_attrib_value == NULL) ) {
            /* remove attrib from component*/
#if DEBUG
            printf("     -- In s_toplevel_update_component_attribs_in_toplevel, about to remove old attrib with name= %s, value= %s\n",
                   old_attrib_name, old_attrib_value);
#endif
            s_object_remove_attrib_in_object (toplevel, o_current, old_attrib_name);
        }

        /* -------  Four cases to consider: Case 3 ----- */
        else if ( (old_attrib_value == NULL) && (new_attrib_value != NULL) ) {
            /* add new attrib to component. */

#if DEBUG
            printf("     -- In s_toplevel_update_component_attribs_in_toplevel, about to add new attrib with name= %s, value= %s\n",
                   new_attrib_name, new_attrib_value);
#endif

            s_object_add_comp_attrib_to_object (toplevel,
                                                o_current,
                                                new_attrib_name,
                                                new_attrib_value,
                                                visibility,
                                                show_name_value);

            /* -------  Four cases to consider: Case 4 ----- */
        } else {
            /* Do nothing. */
#if DEBUG
            printf("     -- In s_toplevel_update_component_attribs_in_toplevel, nothing needs to be done.\n");
#endif
        }

        /* Toggle attribute visibility and name/value setting */


        /* free everything and iterate */
        g_free(new_attrib_name);
        g_free(new_attrib_value);
        g_free(old_attrib_name);
        g_free(old_attrib_value);
        local_list = local_list->next;
    }   /*   while (local_list != NULL)  */
    return;
}
示例#13
0
/*! \brief Search for attibute by name.
 *  \par Function Description
 *  Search for attribute by name.
 *
 *  \warning
 *  The list is the top level list. Do not pass it an object_list list
 *  unless you know what you are doing.
 *  
 *  Counter is the n'th occurance of the attribute, and starts searching
 *  from zero.  Zero is the first occurance of an attribute.
 *
 *  \param [in] list     GList to search.
 *  \param [in] name     Character string with attribute name to search for.
 *  \param [in] counter  Which occurance to return.
 *  \return Character string with attribute value, NULL otherwise.
 *
 *  \warning
 *  Caller must g_free returned character string.
 */
char *o_attrib_search_name (const GList *list, char *name, int counter)
{
  OBJECT *o_current;
  OBJECT *a_current;
  GList *a_iter;
  int val;
  int internal_counter=0;
  char *found_name = NULL;
  char *found_value = NULL;
  char *return_string = NULL;
  const GList *iter;

  iter = list;

  while (iter != NULL) {
    o_current = (OBJECT *)iter->data;
    if (o_current->attribs != NULL) {
      a_iter = o_current->attribs;
      while(a_iter != NULL) {
        a_current = a_iter->data;
        if (a_current->type == OBJ_TEXT) {
          val = o_attrib_get_name_value(a_current->text->string,
                                        &found_name, &found_value);

          if (val) {
            if (strcmp(name, found_name) == 0) {
              if (counter != internal_counter) {
                internal_counter++;
              } else {
                return_string = g_strdup (found_value);
                g_free(found_name);
                g_free(found_value);
                return(return_string);
              }
            }
            if (found_name) { g_free(found_name); found_name = NULL; }
            if (found_value) { g_free(found_value); found_value = NULL; }
          }

#if DEBUG
          printf("0 _%s_\n", a_current->text->string);
          printf("1 _%s_\n", found_name);
          printf("2 _%s_\n", found_value);
#endif
        }
        a_iter = g_list_next (a_iter);
      }
    }

    /* search for attributes outside */

    if (o_current->type == OBJ_TEXT) {
      g_free(found_name);
      g_free(found_value);
      val = o_attrib_get_name_value(o_current->text->string, 
                                    &found_name, &found_value);
      if (val) {
        if (strcmp(name, found_name) == 0) {
          if (counter != internal_counter) {
            internal_counter++;	
          } else {
            return_string = g_strdup (found_value);
	    g_free(found_name);
	    g_free(found_value);
            return(return_string);
          }
        }
	if (found_name) { g_free(found_name); found_name = NULL; }
	if (found_value) { g_free(found_value); found_value = NULL; }
      }	
    }

    iter = g_list_next (iter);
  }
	
  g_free(found_name);
  g_free(found_value);
  return (NULL);
} 
示例#14
0
/*! \todo Finish function documentation!!!
 *  \brief
 *  \par Function Description
 *
 */
void o_slot_end(GSCHEM_TOPLEVEL *w_current, const char *string, int len)
{
  TOPLEVEL *toplevel = w_current->toplevel;
  OBJECT *new_obj;
  OBJECT *object;
  OBJECT *temp;
  char *slot_value;
  char *numslots_value;
  OBJECT *slot_text_object;
  char *value = NULL;
  int numslots;
  int new_slot_number;
  int status;

  status = o_attrib_get_name_value(string, NULL, &value);
  if (!status) {
    s_log_message(_("Slot attribute malformed\n"));
    return;
  }

  object = o_select_return_first_object(w_current);

  /* get the parent object if the selection is only a text object */
  if (object != NULL && object->type == OBJ_TEXT) {
    if (object->attached_to != NULL) {
      object = object->attached_to;
    }
  }

  /* now find the slot attribute on the outside first */
  if (object != NULL) {
    numslots_value = o_attrib_search_numslots(object, NULL);

    if (!numslots_value) {
      s_log_message(_("numslots attribute missing\n"));
      s_log_message(
                    _("Slotting not allowed for this component\n"));
      g_free(value);
      return;
    }

    numslots = atoi(numslots_value);
    g_free(numslots_value);

    new_slot_number = atoi(value);

#if DEBUG
    printf("numslots = %d\n", numslots);
#endif

    if (new_slot_number > numslots || new_slot_number <=0 ) {
      s_log_message(_("New slot number out of range\n"));
      g_free(value);
      return;
    }

    /* first see if slot attribute already exists outside
     * complex */
    slot_value = o_attrib_search_slot(object, &slot_text_object);

    if (slot_value) {
      o_text_set_string (toplevel, slot_text_object, string);

      temp = slot_text_object;

      if (temp->visibility == VISIBLE ||
          (temp->visibility == INVISIBLE && toplevel->show_hidden_text)) {
        o_invalidate (w_current,temp);
      }

      o_text_recreate(toplevel, temp);

      /* this doesn't deal with the selection list
       * item */
      if (temp->visibility == VISIBLE ||
          (temp->visibility == INVISIBLE && toplevel->show_hidden_text)) {
        o_invalidate (w_current,temp);
      }

      g_free(slot_value);

    } else {
      /* here you need to do the add the slot
         attribute since it doesn't exist */
      new_obj = o_text_new (toplevel, OBJ_TEXT, ATTRIBUTE_COLOR,
                            object->complex->x, object->complex->y,
                            LOWER_LEFT, 0, /* zero is angle */
                            string, 10, INVISIBLE, SHOW_NAME_VALUE);
      s_page_append (toplevel->page_current, new_obj);

      /* manually attach attribute */
      o_attrib_attach (toplevel, new_obj, object, FALSE);

      slot_text_object = new_obj;
    }

    o_invalidate (w_current, object);
    o_attrib_slot_update(toplevel, object);

    o_invalidate (w_current,object);

    toplevel->page_current->CHANGED = 1;
    g_free(value);

  } else {
    fprintf(stderr,
            _("uggg! you tried to slot edit something that doesn't exist!\n"));
    g_free(value);
    exit(-1);
  }
}
示例#15
0
/* given a net name, an attribute, and a wanted attribute, return all 
   the given attribute of all the graphical objects connected to that 
   net name */
SCM g_graphical_objs_in_net_with_attrib_get_attrib (SCM scm_netname, SCM scm_has_attribute, SCM scm_wanted_attribute)
{

    SCM list = SCM_EOL;
    NETLIST *nl_current;
    CPINLIST *pl_current;
    char *wanted_net_name;
    char *wanted_attrib;
    char *has_attrib;
    char *net_name;
    char *attrib_value=NULL;
    char *has_attrib_value = NULL;
    char *has_attrib_name = NULL;

    SCM_ASSERT(scm_is_string (scm_netname), scm_netname, SCM_ARG1, 
	       "gnetlist:get-attr-of-conn-graph-objs-with-attr");

    SCM_ASSERT(scm_is_string (scm_wanted_attribute),
	       scm_wanted_attribute, SCM_ARG2, 
	       "gnetlist:get-attr-of-conn-graph-objs-with-attr");

    SCM_ASSERT(scm_is_string (scm_has_attribute),
	       scm_has_attribute, SCM_ARG3, 
	       "gnetlist:get-attr-of-conn-graph-objs-with-attr");

    wanted_net_name = SCM_STRING_CHARS (scm_netname);
    wanted_attrib = SCM_STRING_CHARS (scm_wanted_attribute);
    has_attrib = SCM_STRING_CHARS (scm_has_attribute);
    
    if (wanted_net_name == NULL) {
	return list;
    }


    nl_current = graphical_netlist_head;
    
    /* walk through the list of components, and through the list
     * of individual pins on each, adding net names to the list
     * being careful to ignore duplicates, and unconnected pins 
     */
    while (nl_current != NULL) {
	pl_current = nl_current->cpins;
	while (pl_current != NULL) {
	    if (pl_current->net_name) {
		net_name = pl_current->net_name;
		if (strcmp(net_name, wanted_net_name) == 0) {

		  if (o_attrib_get_name_value (has_attrib, &has_attrib_name,
					       &has_attrib_value) != 0) {
		    attrib_value = 
		      o_attrib_search_name_single(nl_current->object_ptr,
						  has_attrib_name, NULL);
		    
		    if ( ((has_attrib_value == NULL) && (attrib_value == NULL)) ||
			 ((has_attrib_value != NULL) && (attrib_value != NULL) &&
			  (strcmp(attrib_value, has_attrib_value) == 0)) ) {
		      g_free (attrib_value);
		      attrib_value = o_attrib_search_name_single(nl_current->object_ptr,
								 wanted_attrib, NULL);
		      if (attrib_value) {
			list = scm_cons (scm_makfrom0str (attrib_value), list);
		      }
		      g_free (attrib_value);
		    }
		    g_free (has_attrib_name);
		    g_free (has_attrib_value);
		  }
		}
	    }
	    pl_current = pl_current->next;
	}
	nl_current = nl_current->next;
    }

    return list;
}
示例#16
0
/*! \brief Search for first occurance of a named attribute.
 *  \par Function Description
 *  Search for first occurance of a named attribute.
 *
 *  \param [in]  object        The OBJECT list to search.
 *  \param [in]  name          Character string of attribute name to search for.
 *  \param [out] return_found  Contains attribute OBJECT if found, NULL otherwise.
 *  \return Character string with attribute value, NULL otherwise.
 *
 *  \warning
 *  Caller must g_free returned character string.
 */
char *o_attrib_search_name_single(OBJECT *object, char *name,
				  OBJECT **return_found) 
{
  OBJECT *o_current;
  OBJECT *a_current;
  GList *a_iter;
  int val;
  char *found_name = NULL;
  char *found_value = NULL;
  char *return_string = NULL;

  o_current = object;

  if (o_current == NULL) {
    return(NULL);
  }

  if (o_current->attribs != NULL) {
    a_iter = o_current->attribs;

    while(a_iter != NULL) {
      a_current = a_iter->data;
      if (a_current->type == OBJ_TEXT) {
        val = o_attrib_get_name_value(a_current->text->string,
                                      &found_name, &found_value);

        if (val) {
          if (strcmp(name, found_name) == 0) {
            return_string = g_strdup (found_value);
            if (return_found) {
              *return_found = a_current;
            }
            g_free(found_name);
            g_free(found_value);
            return(return_string);
          }
          if (found_name) { g_free(found_name); found_name = NULL; }
          if (found_value) { g_free(found_value); found_value = NULL; }
        }

#if DEBUG
        printf("0 _%s_\n", found->text->string);
        printf("1 _%s_\n", found_name);
        printf("2 _%s_\n", found_value);
#endif
      }
      a_iter = g_list_next (a_iter);
    }
  }
  /* search for attributes outside */

  if (o_current->type == OBJ_TEXT) {
    g_free(found_name);
    g_free(found_value);
    val = o_attrib_get_name_value(o_current->text->string, 
                                  &found_name, &found_value);

    if (val) {
      if (strcmp(name, found_name) == 0) {
        return_string = g_strdup (found_value);
        if (return_found) {
          *return_found = o_current;
        }
	g_free(found_name);
	g_free(found_value);
        return(return_string);
      }
      if (found_name) { g_free(found_name); found_name = NULL; }
      if (found_value) { g_free(found_value); found_value = NULL; }
    }
  }

  if (return_found) {
    *return_found = NULL;
  }
  
  g_free(found_name);
  g_free(found_value);
  return (NULL);
}
示例#17
0
/*! \brief Update a component.
 *
 * \par Function Description
 * Updates \a o_current to the latest version of the symbol available
 * in the symbol library, while preserving any attributes set in the
 * current schematic. On success, returns the new OBJECT which
 * replaces \a o_current on the page; \a o_current is deleted. On
 * failure, returns NULL, and \a o_current is left unchanged.
 *
 * \param [in]     w_current The GSCHEM_TOPLEVEL object.
 * \param [in,out] o_current The OBJECT to be updated.
 *
 * \return the new OBJECT that replaces \a o_current.
 */
OBJECT *
o_update_component (GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
{
  TOPLEVEL *toplevel = w_current->toplevel;
  OBJECT *o_new;
  PAGE *page;
  GList *new_attribs;
  GList *old_attribs;
  GList *iter;
  const CLibSymbol *clib;

  g_return_val_if_fail (o_current != NULL, NULL);
  g_return_val_if_fail (o_current->type == OBJ_COMPLEX, NULL);
  g_return_val_if_fail (o_current->complex_basename != NULL, NULL);

  page = o_get_page (toplevel, o_current);

  /* This should be replaced with API to invalidate only the specific
   * symbol name we want to update */
  s_clib_flush_symbol_cache ();
  clib = s_clib_get_symbol_by_name (o_current->complex_basename);

  if (clib == NULL) {
    s_log_message (_("Could not find symbol [%s] in library. Update failed.\n"),
                   o_current->complex_basename);
    return NULL;
  }

  /* Unselect the old object. */
  o_selection_remove (toplevel, page->selection_list, o_current);

  /* Create new object and set embedded */
  o_new = o_complex_new (toplevel, OBJ_COMPLEX, DEFAULT_COLOR,
                         o_current->complex->x,
                         o_current->complex->y,
                         o_current->complex->angle,
                         o_current->complex->mirror,
                         clib, o_current->complex_basename,
                         1);
  if (o_complex_is_embedded (o_current)) {
    o_embed (toplevel, o_new);
  }

  new_attribs = o_complex_promote_attribs (toplevel, o_new);

  /* Cull any attributes from new COMPLEX that are already attached to
   * old COMPLEX. Note that the new_attribs list is kept consistent by
   * setting GList data pointers to NULL if their OBJECTs are
   * culled. At the end, the new_attribs list is updated by removing
   * all list items with NULL data. This is slightly magic, but
   * works. */
  for (iter = new_attribs; iter != NULL; iter = g_list_next (iter)) {
    OBJECT *attr_new = iter->data;
    gchar *name;
    gchar *value;

    g_assert (attr_new->type == OBJ_TEXT);

    o_attrib_get_name_value (attr_new, &name, NULL);

    value = o_attrib_search_attached_attribs_by_name (o_current, name, 0);
    if (value != NULL) {
      o_attrib_remove (toplevel, &o_new->attribs, attr_new);
      s_delete_object (toplevel, attr_new);
      iter->data = NULL;
    }

    g_free (name);
    g_free (value);
  }
  new_attribs = g_list_remove_all (new_attribs, NULL);

  /* Detach attributes from old OBJECT and attach to new OBJECT */
  old_attribs = g_list_copy (o_current->attribs);
  o_attrib_detach_all (toplevel, o_current);
  o_attrib_attach_list (toplevel, old_attribs, o_new, 1);
  g_list_free (old_attribs);

  /* Add new attributes to page */
  s_page_append_list (toplevel, page, new_attribs);

  /* Update pinnumbers for current slot */
  s_slot_update_object (toplevel, o_new);

  /* Replace old OBJECT with new OBJECT */
  s_page_replace (toplevel, page, o_current, o_new);
  s_delete_object (toplevel, o_current);

  /* Select new OBJECT */
  o_selection_add (toplevel, page->selection_list, o_new);

  /* mark the page as modified */
  toplevel->page_current->CHANGED = 1;
  o_undo_savestate (w_current, UNDO_ALL);

  return o_new;
}
示例#18
0
/*! \brief Get the object bounds of the given object, excluding the object
 *  types given as parameters.
 *  \par Function Description
 *  Get the object bounds without considering the attributes in
 *  exclude_attrib_list, neither the object types included in
 *  exclude_obj_type_list
 *  \param [in] toplevel TOPLEVEL structure.
 *  \param [in] o_current The object we want to know the bounds of.
 *  \param [in] exclude_attrib_list A list with the attribute names we don't
 *  want to include when calculing the bounds.
 *  \param [in] exclude_obj_type_list A list with the object types we don't
 *  want to include when calculing the bounds.
 *  The object types are those used in (OBJECT *)->type converted into strings.
 *  \param [out] left Left bound of the object.
 *  \param [out] top  Top bound of the object.
 *  \param [out] right Right bound of the object.
 *  \param [out] bottom  Bottom bound of the object.
 *
 */
static void custom_world_get_single_object_bounds
(TOPLEVEL *toplevel, OBJECT *o_current,
 int *left, int *top,
 int *right, int *bottom,
 GList *exclude_attrib_list,
 GList *exclude_obj_type_list) {
    OBJECT *obj_ptr = NULL;
    OBJECT *a_current;
    GList *a_iter;
    int rleft, rright, rbottom, rtop;
    const gchar *text_value;
    char *name_ptr, aux_ptr[2];
    gboolean include_text;

    *left = rleft = toplevel->init_right;
    *top = rtop = toplevel->init_bottom;;
    *right = *bottom = rright = rbottom = 0;

    obj_ptr = o_current;
    sprintf(aux_ptr, "%c", obj_ptr->type);
    include_text = TRUE;
    if (!g_list_find_custom(exclude_obj_type_list, aux_ptr,
                            (GCompareFunc) &strcmp)) {

        switch(obj_ptr->type) {
        case (OBJ_PIN):
            world_get_single_object_bounds (toplevel, obj_ptr,
                                            &rleft, &rtop, &rright, &rbottom);
            break;
        case (OBJ_TEXT):
            text_value = o_text_get_string (toplevel, obj_ptr);
            if (text_value) {
                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;
                }
                if (g_list_find_custom(exclude_attrib_list, "all",
                                       (GCompareFunc) &strcmp)) {
                    include_text = FALSE;
                }
                if (include_text) {
                    world_get_single_object_bounds (toplevel, obj_ptr,
                                                    &rleft, &rtop, &rright, &rbottom);
                }
                g_free(name_ptr);
            }
            break;
        case (OBJ_COMPLEX):
        case (OBJ_PLACEHOLDER):
            custom_world_get_object_glist_bounds (toplevel,
                                                  o_current->complex->prim_objs,
                                                  left, top, right, bottom,
                                                  exclude_attrib_list,
                                                  exclude_obj_type_list);
            break;

        default:
            world_get_single_object_bounds (toplevel, obj_ptr,
                                            &rleft, &rtop, &rright, &rbottom);
            break;
        }

        if (rleft < *left) *left = rleft;
        if (rtop < *top) *top = rtop;
        if (rright > *right) *right = rright;
        if (rbottom > *bottom) *bottom = rbottom;

        /* If it's a pin object, check the pin attributes */
        if (obj_ptr->type == OBJ_PIN) {
            a_iter = obj_ptr->attribs;
            while (a_iter != NULL) {
                a_current = a_iter->data;

                if (a_current->type == OBJ_TEXT) {
                    custom_world_get_single_object_bounds(toplevel,
                                                          a_current,
                                                          &rleft, &rtop,
                                                          &rright, &rbottom,
                                                          exclude_attrib_list,
                                                          exclude_obj_type_list);
                    if (rleft < *left) *left = rleft;
                    if (rtop < *top) *top = rtop;
                    if (rright > *right) *right = rright;
                    if (rbottom > *bottom) *bottom = rbottom;
                }

                a_iter = g_list_next (a_iter);
            }
        }
    }
}