Beispiel #1
0
void
s_check_missing_attribute(OBJECT *object, char *attribute, SYMCHECK *s_current)
{
  char *string;
  int found_first=FALSE;
  int counter=0;
  char *message;

  if (!attribute) {
    return;
  }

  string = o_attrib_search_object_attribs_by_name (object, attribute, counter);
  if (!string)
  {
    message = g_strdup_printf (
      "Missing %s= attribute\n",
      attribute);
    s_current->warning_messages = g_list_append(s_current->warning_messages,
                                                message);
    s_current->warning_count++;
  }

  while (string)
  {

    if (found_first) {
      message = g_strdup_printf (
        "Found multiple %s=%s attributes on one pin\n",
        attribute, string);
      s_current->error_messages = g_list_append(s_current->error_messages,
                                                message);
      s_current->error_count++;
    }
        
    /* this is the first attribute found */
    if (!found_first) {

      message = g_strdup_printf (
        "Found %s=%s attribute\n",
        attribute, string);
      s_current->info_messages = g_list_append(s_current->info_messages,
                                               message);
      found_first=TRUE;
    }

    g_free(string);

    counter++;
    string = o_attrib_search_object_attribs_by_name (object, attribute, counter);
  }

}
Beispiel #2
0
CPINLIST *s_traverse_component(TOPLEVEL * pr_current, OBJECT * component,
			       char *hierarchy_tag)
{
  CPINLIST *cpinlist_head = NULL;
  CPINLIST *cpins = NULL;
  NET *nets_head = NULL;
  NET *nets = NULL;
  GList *iter;

  cpinlist_head = cpins = s_cpinlist_add(NULL);
  cpins->plid = -1;

  for (iter = component->complex->prim_objs;
       iter != NULL;
       iter = g_list_next (iter)) {
    OBJECT *o_current = iter->data;

    /* Ignore objects which aren't net pins */
    if (o_current->type != OBJ_PIN ||
        o_current->pin_type != PIN_TYPE_NET)
      continue;

    /* add cpin node */
    cpins = s_cpinlist_add(cpins);
    cpins->plid = o_current->sid;
    cpins->type = o_current->pin_type;

    cpins->pin_number =
      o_attrib_search_object_attribs_by_name (o_current, "pinnumber", 0);

    cpins->pin_label =
      o_attrib_search_object_attribs_by_name (o_current, "pinlabel", 0);

    /* head nets node */
    /* is this really need */
    nets_head = nets = s_net_add(NULL);
    nets->nid = -1;

    /* This avoids us adding an unnamed net for an unconnected pin */
    if (o_current->conn_list != NULL) {
      s_traverse_net (pr_current, nets, TRUE,
		      o_current, hierarchy_tag, cpins->type);
      s_traverse_clear_all_visited (s_page_objects (pr_current->page_current));
    }

    cpins->nets = nets_head;
    /* s_net_print(nets); */
  }


  return (cpinlist_head);
}
Beispiel #3
0
/*! \brief Find a pin with a particular attribute.
 *  \par Function Description
 *  Search for a pin inside the given complex which has an attribute
 *  matching those passed.
 *
 *  \param [in] object        complex OBJECT whos pins to search.
 *  \param [in] name          the attribute name to search for.
 *  \param [in] wanted_value  the attribute value to search for.
 *  \return The pin OBJECT with the given attribute, NULL otherwise.
 */
OBJECT *o_complex_find_pin_by_attribute (OBJECT *object, char *name, char *wanted_value)
{
  GList *iter;
  OBJECT *o_current;
  char *value;
  int found;

  g_return_val_if_fail (object != NULL, NULL);
  g_return_val_if_fail (object->type == OBJ_COMPLEX ||
                        object->type == OBJ_PLACEHOLDER, NULL);

  for (iter = object->complex->prim_objs; iter != NULL;
       iter = g_list_next (iter)) {
    o_current = iter->data;

    if (o_current->type != OBJ_PIN)
      continue;

    value = o_attrib_search_object_attribs_by_name (o_current, name, 0);
    found = (value != NULL && strcmp (value, wanted_value) == 0);
    g_free (value);

    if (found)
      return o_current;
  }

  return NULL;
}
Beispiel #4
0
/* object being a pin */
char *s_net_return_connected_string(TOPLEVEL * pr_current, OBJECT * object,
				    char *hierarchy_tag)
{
    OBJECT *o_current;
    char *pinnum = NULL;
    char *uref = NULL;
    SCM scm_uref;
    char *temp_uref = NULL;
    char *string;
    char *misc;

    o_current = object;

    pinnum = o_attrib_search_object_attribs_by_name (o_current, "pinnumber", 0);

#if DEBUG
    printf("found pinnum: %s\n", pinnum);
#endif

    scm_uref = g_scm_c_get_uref(pr_current, o_current->parent);

    if (scm_is_string( scm_uref )) {
      temp_uref = scm_to_utf8_string (scm_uref);
    }

    /* apply the hierarchy name to the uref */
    uref = s_hierarchy_create_uref(pr_current, temp_uref, hierarchy_tag);

    if (uref && pinnum) {
	string = g_strdup_printf("%s %s", uref, pinnum);
    } else {
	if (pinnum) {
	    string = g_strdup_printf("POWER %s", pinnum);
	} else {
	    if (hierarchy_tag) {
		misc =
		    s_hierarchy_create_uref(pr_current, "U?",
					    hierarchy_tag);
		string = g_strdup_printf("%s ?", misc);
		g_free(misc);
	    } else {
		string = g_strdup("U? ?");
	    }

	    fprintf(stderr, "Missing Attributes (refdes and pin number)\n");
	}
    }

    g_free(pinnum);

    g_free(uref);

    g_free(temp_uref);

    return (string);
}
Beispiel #5
0
int s_hierarchy_graphical_search (OBJECT* o_current, int count)
{
  char *graphical_attrib;
  graphical_attrib =
    o_attrib_search_object_attribs_by_name (o_current, "graphical", count);

  if (graphical_attrib) {
    g_free (graphical_attrib);
    return TRUE;
  }

  return FALSE;
}
Beispiel #6
0
/*! \todo Finish function documentation!!!
 *  \brief Change slot of selected component
 *  \par Function Description
 *
 */
void o_slot_start (GSCHEM_TOPLEVEL *w_current, OBJECT *object)
{
  char *slot_value;

  /* single object for now */
  if (object->type != OBJ_COMPLEX)
    return;

  slot_value = o_attrib_search_object_attribs_by_name (object, "slot", 0);

  if (slot_value == NULL) {
    /* we didn't find a slot=? attribute, make something up */
    /* for now.. this is an error condition */
    slot_value = g_strdup ("1");
  }

  slot_edit_dialog (w_current, slot_value);
  g_free (slot_value);
}
Beispiel #7
0
/*! \brief Get attribute value(s) from a package with given uref.
 *  \par Function Description
 *  This function returns the values of a specific attribute type
 *  attached to the symbol instances with the given refdes.
 *
 *  Every first attribute value found is added to the return list. A
 *  Scheme false value is added if the instance has no such attribute.
 *
 *  \note The order of the values in the return list is the order of
 *  symbol instances within gnetlist (the first element is the value
 *  associated with the first symbol instance).
 *
 *  \param [in] scm_uref           Package reference.
 *  \param [in] scm_wanted_attrib  Attribute name.
 *  \return A list of attribute values as strings and #f.
 */
SCM g_get_all_package_attributes(SCM scm_uref, SCM scm_wanted_attrib)
{
    SCM ret = SCM_EOL;
    NETLIST *nl_current;
    char *uref;
    char *wanted_attrib;

    SCM_ASSERT(scm_is_string (scm_uref),
	       scm_uref, SCM_ARG1, "gnetlist:get-all-package-attributes");

    SCM_ASSERT(scm_is_string (scm_wanted_attrib),
	       scm_wanted_attrib, SCM_ARG2, "gnetlist:get-all-package-attributes");

    uref          = scm_to_utf8_string (scm_uref);
    wanted_attrib = scm_to_utf8_string (scm_wanted_attrib);

    /* here is where you make it multi page aware */
    nl_current = netlist_head;

    /* search for uref instances and through the entire list */
    while (nl_current != NULL) {

	if (nl_current->component_uref) {
	    if (strcmp(nl_current->component_uref, uref) == 0) {
		char *value =
		    o_attrib_search_object_attribs_by_name (nl_current->object_ptr,
		                                            wanted_attrib, 0);

		ret = scm_cons (value ? scm_from_utf8_string (value) : SCM_BOOL_F, ret);

		g_free (value);
	    }
	}
	nl_current = nl_current->next;
    }

    free (uref);
    free (wanted_attrib);

    return scm_reverse_x (ret, SCM_EOL);
}
Beispiel #8
0
/*! \brief Search for slotdef attribute.
 *  \par Function Description
 *  Search for slotdef attribute.
 *
 *  \param [in] object      The OBJECT list to search.
 *  \param [in] slotnumber  The slot number to search for.
 *  \return Character string with attribute value, NULL otherwise.
 *
 *  \warning
 *  Caller must g_free returned character string.
 */
static char *s_slot_search_slotdef (OBJECT *object, int slotnumber)
{
  int counter = 0;
  char *slotdef;
  char *search_for;

  search_for = g_strdup_printf ("%d:", slotnumber);

  while (1) {
    slotdef = o_attrib_search_object_attribs_by_name (object, "slotdef",
                                                      counter++);
    if (slotdef == NULL ||
        strncmp (slotdef, search_for, strlen (search_for)) == 0)
      break;

    g_free (slotdef);
  }

  g_free (search_for);
  return slotdef;
}
Beispiel #9
0
void s_check_pintype (const GList *obj_list, SYMCHECK *s_current)
{
  const GList *iter;
  int counter=0;
  char *pintype;
  char *message;
  char *pintypes[] = {"in", "out", "io", "oc", "oe",
		      "pas", "tp", "tri", "clk", "pwr",
		      NULL};
  
  for (iter = obj_list; iter != NULL; iter = g_list_next (iter)) {
    OBJECT *o_current = iter->data;

    if (o_current->type == OBJ_PIN) {

      for (counter = 0;
           (pintype = o_attrib_search_object_attribs_by_name (o_current, "pintype",
                                                              counter)) != NULL;
           counter++) {

        message = g_strdup_printf("Found pintype=%s attribute\n", pintype);
        s_current->info_messages = g_list_append(s_current->info_messages,
	 	    			         message);

	if ( ! s_check_list_has_item(pintypes, pintype)) {
	  message = g_strdup_printf ("Invalid pintype=%s attribute\n", pintype);
	  s_current->error_messages = g_list_append(s_current->error_messages, 
						    message); 
	  s_current->error_count++; 
	}

        g_free(pintype);
      }
    }
  }
}
Beispiel #10
0
/*! \brief check the symversion of a complex object
 *  \par Function Description
 *  This function compares the symversion of a symbol with it's 
 *  earlier saved symversion in a schematic.
 *  Major symversion changes are added to the toplevel object 
 *  (toplevel->major_changed_refdes), minor changes are reported
 *  to the messaging system.
 *  
 *  \param toplevel  The TOPLEVEL object
 *  \param object    The complex OBJECT
 */
void
o_complex_check_symversion(TOPLEVEL* toplevel, OBJECT* object)
{
  char *inside = NULL;
  char *outside = NULL;
  char *refdes = NULL;
  double inside_value = -1.0;
  double outside_value = -1.0;
  char *err_check = NULL;
  int inside_present = FALSE;
  int outside_present = FALSE;
  double inside_major, inside_minor;
  double outside_major, outside_minor;
  
  g_return_if_fail (object != NULL);
  g_return_if_fail ((object->type == OBJ_COMPLEX || 
		     object->type == OBJ_PLACEHOLDER));
  g_return_if_fail (object->complex != NULL);

  /* first look on the inside for the symversion= attribute */
  inside = o_attrib_search_inherited_attribs_by_name (object, "symversion", 0);

  /* now look for the symversion= attached to object */
  outside = o_attrib_search_attached_attribs_by_name (object, "symversion", 0);

  /* get the uref for future use */
  refdes = o_attrib_search_object_attribs_by_name(object, "refdes", 0);
  if (!refdes)
  {
    refdes = g_strdup ("unknown");
  }
  
  if (inside)
  {
    inside_value = strtod(inside, &err_check);
    if (inside_value == 0 && inside == err_check)
    {
      if (inside)
      { 
        s_log_message(_("WARNING: Symbol version parse error on refdes %s:\n"
                        "\tCould not parse symbol file symversion=%s\n"),
                      refdes, inside);
      } else {
        s_log_message(_("WARNING: Symbol version parse error on refdes %s:\n"
                        "\tCould not parse symbol file symversion=\n"),
                      refdes);
      }
      goto done;
    }
    inside_present = TRUE;
  } else {
    inside_present = FALSE;  /* attribute not inside */
  }

  if (outside)
  {
    outside_value = strtod(outside, &err_check);
    if (outside_value == 0 && outside == err_check)
    {
      s_log_message(_("WARNING: Symbol version parse error on refdes %s:\n"
                      "\tCould not parse attached symversion=%s\n"),
                    refdes, outside);
      goto done;
    }
    outside_present = TRUE; 
  } else {
    outside_present = FALSE;  /* attribute not outside */
  }

#if DEBUG
  printf("%s:\n\tinside: %.1f outside: %.1f\n\n", object->name,
         inside_value, outside_value);
#endif
  
  /* symversion= is not present anywhere */
  if (!inside_present && !outside_present)
  {
    /* symbol is legacy and versioned okay */
    goto done;
  }

  /* No symversion inside, but a version is outside, this is a weird case */
  if (!inside_present && outside_present)
  {
    s_log_message(_("WARNING: Symbol version oddity on refdes %s:\n"
                    "\tsymversion=%s attached to instantiated symbol, "
                    "but no symversion= inside symbol file\n"),
                  refdes, outside);
    goto done;
  }

  /* inside & not outside is a valid case, means symbol in library is newer */
  /* also if inside_value is greater than outside_value, then symbol in */
  /* library is newer */
  if ((inside_present && !outside_present) ||
      ((inside_present && outside_present) && (inside_value > outside_value)))
  {
    
    s_log_message(_("WARNING: Symbol version mismatch on refdes %s (%s):\n"
                    "\tSymbol in library is newer than "
                    "instantiated symbol\n"),
                  refdes, object->complex_basename);

    /* break up the version values into major.minor numbers */
    inside_major = floor(inside_value);
    inside_minor = inside_value - inside_major;

    if (outside_present)
    {
      outside_major = floor(outside_value);
      outside_minor = outside_value - outside_major;
    } else {
      /* symversion was not attached to the symbol, set all to zero */
      outside_major = 0.0;
      outside_minor = 0.0;
      outside_value = 0.0;
    }

#if DEBUG
    printf("i: %f %f %f\n", inside_value, inside_major, inside_minor);
    printf("o: %f %f %f\n", outside_value, outside_major, outside_minor);
#endif
    
    if (inside_major > outside_major)
    {
      char* refdes_copy;
      s_log_message(_("\tMAJOR VERSION CHANGE (file %.3f, "
                      "instantiated %.3f, %s)!\n"),
                    inside_value, outside_value, refdes);

      /* add the refdes to the major_changed_refdes GList */
      /* make sure refdes_copy is freed somewhere */
      refdes_copy = g_strconcat (refdes, " (",
                                 object->complex_basename,
                                 ")", NULL);
      toplevel->major_changed_refdes =
        g_list_append(toplevel->major_changed_refdes, refdes_copy);

      /* don't bother checking minor changes if there are major ones*/
      goto done; 
    }

    if (inside_minor > outside_minor)
    {
      s_log_message(_("\tMinor version change (file %.3f, "
                      "instantiated %.3f)\n"),
                    inside_value, outside_value);
    }

    goto done;
  }

  /* outside value is greater than inside value, this is weird case */
  if ((inside_present && outside_present) && (outside_value > inside_value))
  {
    s_log_message(_("WARNING: Symbol version oddity on refdes %s:\n"
                    "\tInstantiated symbol is newer than "
                    "symbol in library\n"),
                  refdes);
    goto done;
  }

  /* if inside_value and outside_value match, then symbol versions are okay */

done:
  g_free(inside);
  g_free(outside);
  g_free(refdes);
}
Beispiel #11
0
void
s_check_pinseq (const GList *obj_list, SYMCHECK *s_current)
{
  char *string;
  int found_first=FALSE;
  int missing_pinseq_attrib_sum=0;
  int multiple_pinseq_attrib_sum=0;
  int counter=0;

  GList *found_numbers = NULL;
  GList *ptr1 = NULL;
  GList *ptr2 = NULL;
  const GList *iter;
  char *number;
  char *message;
  
  for (iter = obj_list; iter != NULL; iter = g_list_next (iter)) {
    OBJECT *o_current = iter->data;
    
    if (o_current->type == OBJ_PIN)
    {
      missing_pinseq_attrib_sum = 0;
      multiple_pinseq_attrib_sum = 0;
      found_first = FALSE;
      counter = 0;
      
      string = o_attrib_search_object_attribs_by_name (o_current, "pinseq",
                                                       counter);
      if (!string)
      {
        message = g_strdup ("Missing pinseq= attribute\n");
        s_current->error_messages = g_list_append(s_current->error_messages,
                                                  message);
        missing_pinseq_attrib_sum++;
        s_current->error_count++;
      }

      while (string)
      {
        
        message = g_strdup_printf ("Found pinseq=%s attribute\n", string); 
        s_current->info_messages = g_list_append(s_current->info_messages,
	 	    			         message);

        number = g_strdup (string);

        if (strcmp(number, "0") == 0) {
          message = g_strdup ("Found pinseq=0 attribute\n");
          s_current->error_messages = g_list_append(s_current->error_messages,
	 	    			            message);
          s_current->error_count++;
        }

        if (found_first) {
          message = g_strdup_printf (
            "Found multiple pinseq=%s attributes on one pin\n",
            string);
          s_current->error_messages = g_list_append(s_current->error_messages,
	 	    			            message);
          multiple_pinseq_attrib_sum++;
          s_current->error_count++;
        }

        g_free(string);
        
        /* this is the first attribute found */
        if (!found_first) {
          found_numbers = g_list_append(found_numbers, number);
          found_first=TRUE;
        } else {
          g_free(number);
        }
        
        counter++;
        string = o_attrib_search_object_attribs_by_name (o_current, "pinseq",
                                                         counter);
      }

      s_current->missing_pinseq_attrib += missing_pinseq_attrib_sum;
      s_current->multiple_pinseq_attrib += multiple_pinseq_attrib_sum;
    }

  }

  ptr1 = found_numbers;
  while (ptr1)
  {
    char *string = (char *) ptr1->data;
    int found = 0;
    
    ptr2 = found_numbers;
    while(ptr2 && string)
    {
      char *current = (char *) ptr2->data;

      if (current && strcmp(string, current) == 0) {
        found++;
      }
      
      ptr2 = g_list_next(ptr2);
    }

    if (found > 1)
    {
      message = g_strdup_printf (
        "Found duplicate pinseq=%s attribute in the symbol\n",
        string);
      s_current->error_messages = g_list_append(s_current->error_messages,
                                                message);
      s_current->error_count++;
      s_current->duplicate_pinseq_attrib++;
    }
    
    ptr1 = g_list_next(ptr1);
  }

  ptr1 = found_numbers;
  while (ptr1)
  {
    g_free(ptr1->data);
    ptr1 = g_list_next(ptr1);
  }
  g_list_free(found_numbers);
  
}
Beispiel #12
0
/*! \brief Get pin attributes
 *
 * This function takes a pointer to the OBJECT pin, and returns a list
 * of attribs found attached to the pin.  The returned list is a
 * STRING_LIST where the ->data holds a name=value string.
 * The algorithm is as follows:
 * -# Form refdes:pinnumber label for this pin.
 * -# Get row number of this refdes:pinnumber
 * -# Create a list of name=value pairs from entries in the pin_table
 *    on this row.
 * -# Return list of name=value pairs found.
 *
 * \param refdes Ref des string
 * \param pin Pin object
 * \returns name=value pair as a STRING_LIST
 */
STRING_LIST *s_toplevel_get_pin_attribs_in_sheet(char *refdes, OBJECT *pin)
{
    STRING_LIST *new_attrib_list;
    STRING_LIST *local_attrib_list;
    int i;
    int row = -1;
    int count = 0;
    char *pinnumber;
    char *row_label;
    char *name_value_pair;
    char *new_attrib_value;
    char *new_attrib_name;

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

    /* First find pos of this pin in the master pin list */
    /* first convert refdes, pin to refdes:pinno text string. Then call table_get_index.  */

    pinnumber = o_attrib_search_object_attribs_by_name (pin, "pinnumber", 0);

    if ( (refdes != NULL) && (pinnumber != NULL) ) {
        row_label = g_strconcat(refdes, ":", pinnumber, NULL);
    } else {
        fprintf(stderr,
                "In s_toplevel_get_pin_attribs_in_sheet, either refdes or pinnumber of object missing!\n");
        return NULL;
    }
    row = s_table_get_index(sheet_head->master_pin_list_head, row_label);

    /* Sanity check */
    if (row == -1) {
        /* we didn't find the item in the list */
        fprintf(stderr,
                "In s_toplevel_get_pin_attribs_in_sheet, we didn't find the refdes:pin in the master list!\n");
        return NULL;
    }

    /* Now get all attribs associated with this refdes (in TABLE, indexed
     * by position), and insert them into new_attrib_list.  */
    new_attrib_list = s_string_list_new();  /* init new_attrib_list */

    i = 0;
    local_attrib_list = sheet_head->master_pin_attrib_list_head;
    while (local_attrib_list != NULL) {  /* iterate over all possible attribs */
        new_attrib_name = g_strdup(local_attrib_list->data);  /* take attrib name from column headings */

        if ( ((sheet_head->pin_table)[row][i]).attrib_value ) {
            new_attrib_value = g_strdup( ((sheet_head->pin_table)[row][i]).attrib_value );
            name_value_pair = g_strconcat(new_attrib_name, "=", new_attrib_value, NULL);
            g_free(new_attrib_value);
        } else {
            name_value_pair = g_strconcat(new_attrib_name, "=", NULL);  /* empty attrib */
        }
        s_string_list_add_item(new_attrib_list, &count, name_value_pair);  /* add name=value to new list */
        g_free(new_attrib_name);
        g_free(name_value_pair);

        /* Sanity check */
        if (count != i+1) {
            /* for some reason, we have lost a name_value_pair somewhere . . .  */
            fprintf(stderr,
                    "In s_toplevel_get_pin_attribs_in_sheet, count != i!  Exiting . . . .\n");
            exit(-1);
        }

        /* iterate */
        i++;
        local_attrib_list = local_attrib_list->next;
    } /* while (local_attrib_list != NULL)  */

    return new_attrib_list;
}
Beispiel #13
0
/*! \brief Copy SHEET_DATA content to TOP_LEVEL
 *
 * This function
 * loops through all objects on (PAGE page)->(OBJECT *start_obj).
 * It takes the updated SHEET_DATA->TABLE data and then updates the
 * objects with the new attribs & attrib values.
 * For each component, it updates the attached
 * attrib values using the updated values held in the SHEET_DATA->TABLE
 * structure.  It does so in three steps:
 * -# First find and update component attribs.
 * -# Then find and update net attribs.
 * -# Finally find and update pin attribs.
 * \param toplevel TOPLEVEL structure
 * \param page schematic page to copy
 */
void
s_toplevel_sheetdata_to_toplevel (TOPLEVEL *toplevel, PAGE *page)
{
    GList *copy_list;
    GList *o_iter, *prim_iter;
    char *temp_uref;
    STRING_LIST *new_comp_attrib_pair_list;
    STRING_LIST *new_pin_attrib_list;

    /* -----  First deal with all components on the page.  ----- */
#ifdef DEBUG
    printf("-----  In s_toplevel_sheetdata_to_toplevel, handling components\n");
#endif

    /* Work from a copy list, as objects can be deleted
     * from the list during iteration over the list.
     */
    /* NB: g_list_copy doesn't declare its input const, so we cast */
    copy_list = g_list_copy ((GList *)s_page_objects (page));

    /* Iterate backwards since attributes are attached after their
     * parent objects in the list. Attributes can get deleted during
     * the iteration.
     */
    for (o_iter = g_list_last (copy_list);
            o_iter != NULL;
            o_iter = g_list_previous (o_iter)) {
        OBJECT *o_current = o_iter->data;

        /* ------- Object is a component.  Handle component attributes. ------- */
        if (o_current->type == OBJ_COMPLEX) {    /* Note that OBJ_COMPLEX = component + attribs */

#if 0
            if (o_attrib_search_object_attribs_by_name (o_current, "graphical", 0)) {
                break;  /* Ignore graphical components */
            }
#endif

            temp_uref = s_attrib_get_refdes(o_current);
            if (temp_uref != NULL) {
                /* Must create a name=value pair list for each particular component
                 * which we can pass to function updating o_current.  This function
                     * places all attribs
                 * found in the row into new_comp_attrib_pair_list.  */
                new_comp_attrib_pair_list = s_table_create_attrib_pair(temp_uref,
                                            sheet_head->component_table,
                                            sheet_head->master_comp_list_head,
                                            sheet_head->comp_attrib_count);


                /* Now update attribs in toplevel using this list.  */
                s_toplevel_update_component_attribs_in_toplevel(toplevel,
                        o_current,
                        new_comp_attrib_pair_list);

                g_free(temp_uref);
            } else {
#ifdef DEBUG
                printf("In s_toplevel_sheetdata_to_toplevel, found complex with no refdes. name = %s\n",
                       o_current->name);
#endif
            }
        }  /* if (o_current->type == OBJ_COMPLEX) */

    }

    g_list_free (copy_list);

#if 0
    /* -----  Next deal with all nets on the page.  ----- */
    /* This is TBD */

#endif


    /* -----  Finally deal with all pins on the page.  ----- */
    /* -----  Next deal with all nets on the page.  ----- */
#ifdef DEBUG
    printf("-----  In s_toplevel_sheetdata_to_toplevel, handling pins\n");
#endif

    /* Work from a copy list in case objects are
     * deleted from the list during its iteration.
     */
    /* NB: g_list_copy doesn't declare its input const, so we cast */
    copy_list = g_list_copy ((GList *)s_page_objects (page));

    for (o_iter = g_list_last (copy_list);
            o_iter != NULL;
            o_iter = g_list_previous (o_iter)) {
        OBJECT *o_current = o_iter->data;

        /* ------- Object is a complex.  Handle pins by looking ------ */
        /* ------- for all pins attached to a component.        ------ */
        if (o_current->type == OBJ_COMPLEX) {
            /*  Upon finding a component, here's what to do:
             *  0.  Get refdes of component.
             *  1.  Loop over prim_objects, looking for pins.
             *  2.  When a pin is found, create refdes:pinnumber pair
             *      used in searching TABLE.
             *  3.  Search TABLE using refdes:pinnumber as key, and get list of
             *      attribs corresponding to this refdes:pinnumber
             *  4.  Stick the attribs into the TOPLEVEL data structure.
             */
            temp_uref =  s_attrib_get_refdes(o_current);
            if ( (temp_uref != NULL) && (o_current->complex->prim_objs) ) {    /* make sure object complex has a refdes  */

                for (prim_iter = o_current->complex->prim_objs;
                        prim_iter != NULL;
                        prim_iter = g_list_next (prim_iter)) {
                    OBJECT *comp_prim_obj = prim_iter->data;

                    if (comp_prim_obj->type == OBJ_PIN) {
                        new_pin_attrib_list =
                            s_toplevel_get_pin_attribs_in_sheet (temp_uref, comp_prim_obj);
                        s_toplevel_update_pin_attribs_in_toplevel (toplevel,
                                temp_uref,
                                comp_prim_obj,
                                new_pin_attrib_list);
                    }
                }
            }     /* if(temp_uref  */

            g_free(temp_uref);
        }
    }

    g_list_free (copy_list);

    return;
}
Beispiel #14
0
/*! \brief Gets or generates free numbers for the autonumbering process.
 *  \par Function Description
 *  This function gets or generates new numbers for the <B>OBJECT o_current</B>. 
 *  It uses the element numbers <B>used_numbers</B> and the list of the free slots
 *  <B>free_slots</B> of the <B>AUTONUMBER_TEXT</B> struct.
 *  \return 
 *  The new number is returned into the <B>number</B> parameter.
 *  <B>slot</B> is set if autoslotting is active, else it is set to zero.
 */
void autonumber_get_new_numbers(AUTONUMBER_TEXT *autotext, OBJECT *o_current, 
				gint *number, gint *slot)
{
  GList *item;
  gint new_number, numslots, i;
  AUTONUMBER_SLOT *freeslot;
  OBJECT *o_parent = NULL;
  GList *freeslot_item;
  gchar *numslot_str;

  new_number = autotext->startnum;
  
  /* Check for slots first */
  /* 1. are there any unused slots in the database? */
  o_parent = o_current->attached_to;
  if (autotext->slotting && o_parent != NULL) {
    freeslot = g_new(AUTONUMBER_SLOT,1);
    freeslot->symbolname = o_parent->complex_basename;
    freeslot->number = 0;
    freeslot->slotnr = 0;
    freeslot_item = g_list_find_custom(autotext->free_slots,
				       freeslot,
				       (GCompareFunc) freeslot_compare);
    g_free(freeslot);
    /* Yes! -> remove from database, apply it */
    if (freeslot_item != NULL) {
      freeslot = freeslot_item->data;
      *number = freeslot->number;
      *slot = freeslot->slotnr;
      g_free(freeslot);
      autotext->free_slots = g_list_delete_link(autotext->free_slots, freeslot_item);
      
      return;
    }
  }

  /* get a new number */
  item = autotext->used_numbers; 
  while (1) {
    while (item != NULL && GPOINTER_TO_INT(item->data) < new_number)
      item = g_list_next(item);

    if (item == NULL || GPOINTER_TO_INT(item->data) > new_number)
      break;
    else  /* new_number == item->data */
      new_number++;
  }
  *number = new_number;
  *slot = 0;
  
  /* insert the new number to the used list */
  autotext->used_numbers = g_list_insert_sorted(autotext->used_numbers,
						GINT_TO_POINTER(new_number),
						(GCompareFunc) autonumber_sort_numbers);

  /* 3. is o_current a slotted object ? */
  if ((autotext->slotting) && o_parent != NULL) {
    numslot_str =
      o_attrib_search_object_attribs_by_name (o_parent, "numslots", 0);
    if (numslot_str != NULL) {
      sscanf(numslot_str," %d",&numslots);
      g_free(numslot_str);
      if (numslots > 0) { 
	/* Yes! -> new number and slot=1; add the other slots to the database */
	*slot = 1;
	for (i=2; i <=numslots; i++) {
	  freeslot = g_new(AUTONUMBER_SLOT,1);
	  freeslot->symbolname = o_parent->complex_basename;
	  freeslot->number = new_number;
	  freeslot->slotnr = i;
	  autotext->free_slots = g_list_insert_sorted(autotext->free_slots,
						      freeslot,
						      (GCompareFunc) freeslot_compare);
	}
      }
    }
  }
}
Beispiel #15
0
/*! \brief Refresh & cache number of connected entities.
 *
 *  \par Function Description
 *  Traverse all network segments reachable from this net and count
 *  total number of unique entities connected to all net segments.
 *
 *  For the purpose of this function, an entity is:
 *    - pin
 *    - bus
 *    - attached netname attribute
 *
 *  Computed number of entities is afterwards stored in all traversed
 *  net segments.
 *
 *  The algorithm does not handle corner cases, ie two bus segments
 *  belonging to the same bus will be counted twice.
 *
 *  \param [in] toplevel    The TOPLEVEL object
 *  \param [in] o_current   The NET OBJECT to check connectivity of
 */
void o_net_refresh_conn_cache(TOPLEVEL *toplevel, OBJECT *o_current)
{
  gint            num_conns = 0;
  GHashTable     *visited;
  GHashTableIter  iter;
  GList          *stack = NULL;
  OBJECT         *obj;
  gpointer       key;

  g_return_if_fail (toplevel);
  g_return_if_fail (o_current);
  g_return_if_fail (o_current->type == OBJ_NET);

  /* Keep track of visited nets, pins and buses in the hash table.
   * This way we short-circuit the search and avoid loops.
   */
  visited = g_hash_table_new (NULL, NULL);

  /*
   * Add the starting net to the hash so:
   *   1. it is not traversed twice
   *   2. it is updated at the end if no connections are found
   */
  g_hash_table_insert (visited, o_current, o_current);

  /* Check if a netname= is attached to the starting net segment */
  if (NULL != o_attrib_search_object_attribs_by_name (o_current,
                                                      "netname",
                                                      0)) {
    num_conns += 1;
  }

  /* Keep track of connections to search at each net segment in a stack.
   * Each stack entry points to an entry in obj->conn_list.
   * Pop the stack when we have no more connections to check.
   * Push next entry on the stack if we encounter a net segment.
   */

  /* Initialise the stack for the starting net segment. */
  stack = g_list_prepend (stack, o_current->conn_list);

  while (stack != NULL) {
    /* At start of the loop, take a new connection from the stack. */
    GList *conn_list = (GList*) stack->data;
    CONN *conn;

    if (conn_list == NULL) {
      /* No more connections to check at this level. Pop the stack. */
      stack = g_list_delete_link (stack, stack);
      continue;
    }

    /* Extract the next connected object and advance the connection list. */
    conn = (CONN*) conn_list->data;
    stack->data = (gpointer) g_list_next (conn_list);

    if (conn == NULL)
        /* should not happen */
        continue;
    obj = conn->other_object;
    if (obj == NULL)
        /* should not happen */
        continue;

    /* Act upon the object that is connected to the segment. */
    switch (obj->type) {
      case OBJ_PIN:
      case OBJ_BUS:
        if (NULL == g_hash_table_lookup (visited, obj)) {
          g_hash_table_insert (visited, obj, obj);
          num_conns += 1;
        }
        break;
      case OBJ_NET:
        if (NULL == g_hash_table_lookup (visited, obj)) {
          g_hash_table_insert (visited, obj, obj);
          /* Check if a netname= is attached to this net segment */
          if (NULL != o_attrib_search_object_attribs_by_name (obj,
                                                              "netname",
                                                              0)) {
            num_conns += 1;
          }
          /* Push new list of connections to check onto the stack */
          stack = g_list_prepend (stack, obj->conn_list);
        }
        break;
      default:
        break;
    }
  }

  /* Cache value of num_conns in all visited objects */
  g_hash_table_iter_init (&iter, visited);

  while (g_hash_table_iter_next (&iter, &key, NULL)) {
    obj = (OBJECT*) key;
    if (obj->type == OBJ_NET) {
      obj->net_num_connected = num_conns;
      obj->valid_num_connected = TRUE;
    }
  }

  g_hash_table_destroy (visited);
  g_list_free (stack);
}
Beispiel #16
0
void
s_check_pinnumber (const GList *obj_list, SYMCHECK *s_current)
{
  char *string;
  int missing_pinnumber_attrib_sum=0;
  int multiple_pinnumber_attrib_sum=0;
  int counter=0;
  int i;

  gchar **net_tokens;
  gchar **pin_tokens;
  GList *net_numbers = NULL;
  GList *pin_numbers = NULL;
  GList *cur = NULL;
  GList *cur2 = NULL;
  const GList *iter;
  char *message;
  char *net = NULL;
    
  /* collect all net pins */
  for (counter = 0;
       (net = o_attrib_search_floating_attribs_by_name (obj_list, "net", counter)) != NULL;
       counter++) {
    message = g_strdup_printf ("Found net=%s attribute\n", net);
    s_current->info_messages = g_list_append(s_current->info_messages,
					     message);

    net_tokens = g_strsplit(net,":", -1);
    /* length of net tokens have to be 2 */
    if (net_tokens[1] == NULL) {
      message = g_strdup_printf ("Bad net= attribute [net=%s]\n", net);
      s_current->error_messages = g_list_append(s_current->error_messages,
						message);
      s_current->error_count++;
      g_strfreev(net_tokens);
      continue;
    } else if (net_tokens[2] != NULL) { /* more than 2 tokens */
      message = g_strdup_printf ("Bad net= attribute [net=%s]\n", net);
      s_current->error_messages = g_list_append(s_current->error_messages,
						message);
      s_current->error_count++;
      g_strfreev(net_tokens);
      continue;
    }

    pin_tokens = g_strsplit(net_tokens[1],",",-1);
    
    for (i = 0; pin_tokens[i] != NULL; i++) {
      net_numbers = g_list_append(net_numbers, g_strdup(pin_tokens[i]));
      message = g_strdup_printf ("Found pin number %s in net attribute\n",
                                 pin_tokens[i]);
      s_current->info_messages = g_list_append(s_current->info_messages,
					       message);
      s_current->numnetpins++;
    }
    g_free(net);
    g_strfreev(net_tokens);
    g_strfreev(pin_tokens);
  }
  
  /* check for duplicate net pin numbers */
  net_numbers = g_list_sort(net_numbers, (GCompareFunc)strcmp);

  for (cur = net_numbers;
       cur != NULL && g_list_next(cur) != NULL;
       cur = g_list_next(cur)) {
    if (strcmp((gchar*)cur->data, (gchar*) cur->next->data) == 0) {
      message = g_strdup_printf ("Found duplicate pin in net= "
				 "attributes [%s]\n", (gchar*) cur->data);
      s_current->error_messages = g_list_append(s_current->error_messages,
						message);
      s_current->error_count++;
    }
    if (strcmp((gchar*) cur->data, "0") == 0) {
      message = g_strdup ("Found pinnumber 0 in net= attribute\n");
      s_current->error_messages = g_list_append(s_current->error_messages,
                                                message);
      s_current->error_count++;
    }
  }

  /* collect all pin numbers */
  for (iter = obj_list; iter != NULL; iter = g_list_next (iter)) {
    OBJECT *o_current = iter->data;
    
    if (o_current->type == OBJ_PIN) {
      s_current->numpins++;
      
      missing_pinnumber_attrib_sum = 0;
      multiple_pinnumber_attrib_sum = 0;
      
      for (counter = 0; 
	   (string = o_attrib_search_object_attribs_by_name (o_current, "pinnumber",
	                                                     counter)) != NULL;
	   counter++) {
	
        message = g_strdup_printf ("Found pinnumber=%s attribute\n", string);
        s_current->info_messages = g_list_append(s_current->info_messages,
	 	    			         message);

	if (counter == 0) { /* collect the first appearance */
	  pin_numbers = g_list_append(pin_numbers, string);
	}
        if (counter >= 1) {
          message = g_strdup_printf ("Found multiple pinnumber=%s attributes"
				     " on one pin\n", string);
          s_current->error_messages = g_list_append(s_current->error_messages,
	 	    			            message);
          multiple_pinnumber_attrib_sum++;
          s_current->error_count++;
	  g_free(string); 
        }
      }
	   
      if (counter == 0) {
        message = g_strdup ("Missing pinnumber= attribute\n");
        s_current->error_messages = g_list_append(s_current->error_messages,
                                                  message);
        missing_pinnumber_attrib_sum++;
        s_current->error_count++;
      }

      s_current->missing_pinnumber_attrib += missing_pinnumber_attrib_sum;
      s_current->multiple_pinnumber_attrib += multiple_pinnumber_attrib_sum;
    }
  }

  /* check for duplicate pinlabel numbers */
  pin_numbers = g_list_sort(pin_numbers, (GCompareFunc)strcmp);
  for (cur = pin_numbers;
       cur != NULL && g_list_next(cur) != NULL;
       cur = g_list_next(cur)) { 
    if (strcmp((gchar*)cur->data, (gchar*) cur->next->data) == 0) {
      message = g_strdup_printf ("Found duplicate pinnumber=%s attribute "
				 "in the symbol\n", (gchar*) cur->data);
      s_current->error_messages = g_list_append(s_current->error_messages,
						message);
      s_current->error_count++;
      s_current->duplicate_pinnumber_attrib++;
    }
    if (strcmp((gchar*) cur->data, "0") == 0) {
      message = g_strdup ("Found pinnumber=0 attribute\n");
      s_current->error_messages = g_list_append(s_current->error_messages,
						message);
      s_current->error_count++;
    }
  }

  /* Check for all pins that are in both lists and print a warning.
     Sometimes this is useful and sometimes it's an error. */

  cur = net_numbers;
  cur2 = pin_numbers;

  while (cur != NULL && cur2 != NULL) {
    
    i = strcmp((gchar*)cur->data, (gchar*)cur2->data);

    if (i == 0) {
      message = g_strdup_printf ("Found the same number in a pinnumber "
				 "attribute and in a net attribute [%s]\n",
				 (gchar*) cur->data);
      s_current->warning_messages = g_list_append(s_current->warning_messages,
						  message);
      s_current->warning_count++;
      cur = g_list_next(cur);

    } else if ( i > 0 ) {
      cur2 = g_list_next(cur2);

    } else { /* i < 0 */
      cur = g_list_next(cur);
    }
  }

  /* FIXME: this is not correct if a pinnumber is defined as pinnumber and
     inside a net. We have to calculate the union set */
  message = g_strdup_printf ("Found %d pins inside symbol\n", 
			     s_current->numpins + s_current->numnetpins);
  s_current->info_messages = g_list_append(s_current->info_messages,
                                           message);

  g_list_foreach(pin_numbers, (GFunc) g_free, NULL);
  g_list_free(pin_numbers);
  g_list_foreach(net_numbers, (GFunc) g_free, NULL);
  g_list_free(net_numbers);
}
Beispiel #17
0
/*! \todo Finish function documentation!!!
 *  \brief
 *  \par Function Description
 *
 */
void o_slot_end(GSCHEM_TOPLEVEL *w_current, OBJECT *object, const char *string)
{
  TOPLEVEL *toplevel = w_current->toplevel;
  OBJECT *new_obj;
  char *slot_value;
  char *numslots_value;
  OBJECT *o_slot;
  char *value = NULL;
  int numslots;
  int new_slot_number;
  int status;

  g_return_if_fail (object != NULL);

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

  numslots_value =
    o_attrib_search_object_attribs_by_name (object, "numslots", 0);

  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 = s_slot_search_slot (object, &o_slot);
  g_free (slot_value);

  if (o_slot != NULL && !o_attrib_is_inherited (o_slot)) {
    o_text_set_string (toplevel, o_slot, string);
  } 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, toplevel->page_current, new_obj);

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

  s_slot_update_object (toplevel, object);

  toplevel->page_current->CHANGED = 1;
  g_free (value);
}
Beispiel #18
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:graphical-objs-in-net-with-attrib-get-attrib");

    SCM_ASSERT(scm_is_string (scm_wanted_attribute),
	       scm_wanted_attribute, SCM_ARG3, 
	       "gnetlist:graphical-objs-in-net-with-attrib-get-attrib");

    SCM_ASSERT(scm_is_string (scm_has_attribute),
	       scm_has_attribute, SCM_ARG2, 
	       "gnetlist:graphical-objs-in-net-with-attrib-get-attrib");

    scm_dynwind_begin (0);

    wanted_net_name = scm_to_utf8_string (scm_netname);
    if (wanted_net_name == NULL) {
	return list;
    }

    scm_dynwind_free (wanted_net_name);

    wanted_attrib = scm_to_utf8_string (scm_wanted_attribute);
    scm_dynwind_free (wanted_attrib);

    has_attrib = scm_to_utf8_string (scm_has_attribute);
    scm_dynwind_free (has_attrib);

    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_string_get_name_value (has_attrib, &has_attrib_name,
					       &has_attrib_value) != 0) {
		    attrib_value = 
		      o_attrib_search_object_attribs_by_name (nl_current->object_ptr,
		                                              has_attrib_name, 0);
		    
		    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_object_attribs_by_name (nl_current->object_ptr,
		                                                wanted_attrib, 0);
		      if (attrib_value) {
			list = scm_cons (scm_from_utf8_string (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;
    }

    scm_dynwind_end ();
    return list;
}
Beispiel #19
0
/* scm_pin is the value associated with the pinnumber= attribute and uref */
SCM g_get_attribute_by_pinnumber(SCM scm_uref, SCM scm_pin, SCM
                               scm_wanted_attrib)
{
    SCM scm_return_value;
    NETLIST *nl_current;
    OBJECT *pin_object;
    char *uref;
    char *pin;
    char *wanted_attrib;
    char *return_value = NULL;
    int done = FALSE;

    SCM_ASSERT(scm_is_string (scm_uref),
	       scm_uref, SCM_ARG1, "gnetlist:get-attribute-by-pinnumber");

    SCM_ASSERT(scm_is_string (scm_pin),
	       scm_pin, SCM_ARG2, "gnetlist:get-attribute-by-pinnumber");

    SCM_ASSERT(scm_is_string (scm_wanted_attrib),
	       scm_wanted_attrib, SCM_ARG3, "gnetlist:get-attribute-by-pinnumber");

    scm_dynwind_begin (0);

    uref = scm_to_utf8_string (scm_uref);
    scm_dynwind_free (uref);

    pin = scm_to_utf8_string (scm_pin);
    scm_dynwind_free (pin);

    wanted_attrib = scm_to_utf8_string (scm_wanted_attrib);
    scm_dynwind_free (wanted_attrib);

    /* here is where you make it multi page aware */
    nl_current = netlist_head;

    /* search for the first instance */
    /* through the entire list */
    while (nl_current != NULL && !done) {
	if (nl_current->component_uref) {
	    if (strcmp(nl_current->component_uref, uref) == 0) {

		pin_object =
		    o_complex_find_pin_by_attribute (nl_current->object_ptr,
		                                     "pinnumber", pin);

		if (pin_object) {

		    /* only look for the first occurance of wanted_attrib */
		    return_value =
		      o_attrib_search_object_attribs_by_name (pin_object,
		                                              wanted_attrib, 0);
#if DEBUG
		    if (return_value) {
			printf("GOT IT: %s\n", return_value);
		    }
#endif
		} else if (strcmp("pintype",
				  wanted_attrib) == 0) {
		  if (nl_current->cpins) {
		    CPINLIST *pinobject =
		      s_cpinlist_search_pin(nl_current->cpins, pin);
		    if (pinobject) {
		      return_value="pwr";
#if DEBUG
		      
		      printf("Supplied pintype 'pwr' for artificial pin '%s' of '%s'\n",
			     pin, uref);
#endif
		    }
		  }		
		}
	    }
	}
	nl_current = nl_current->next;
    }

    scm_dynwind_end ();

    if (return_value) {
      scm_return_value = scm_from_utf8_string (return_value);
    } else {
      scm_return_value = scm_from_utf8_string ("unknown");
    }

    return (scm_return_value);
}
Beispiel #20
0
/* with that pinseq pin and component */
SCM g_get_attribute_by_pinseq(SCM scm_uref, SCM scm_pinseq,
                              SCM scm_wanted_attrib)
{
  SCM scm_return_value;
  NETLIST *nl_current;
  char *uref;
  char *pinseq;
  char *wanted_attrib;
  char *return_value = NULL;
  OBJECT *o_pin_object;

  SCM_ASSERT(scm_is_string (scm_uref),
	     scm_uref, SCM_ARG1, "gnetlist:get-attribute-by-pinseq");

  SCM_ASSERT(scm_is_string (scm_pinseq),
             scm_pinseq, SCM_ARG2, "gnetlist:get-attribute-by-pinseq");


  SCM_ASSERT(scm_is_string (scm_wanted_attrib),
             scm_wanted_attrib, SCM_ARG3, "gnetlist:get-attribute-by-pinseq");

  scm_dynwind_begin (0);

  uref = scm_to_utf8_string (scm_uref);
  scm_dynwind_free (uref);

  pinseq = scm_to_utf8_string (scm_pinseq);
  scm_dynwind_free (pinseq);

  wanted_attrib = scm_to_utf8_string (scm_wanted_attrib);
  scm_dynwind_free (wanted_attrib);

#if DEBUG
  printf("gnetlist:g_netlist.c:g_get_attribute_by_pinseq -- \n");
  printf("  wanted uref = %s\n", uref);
  printf("  wanted_pin_seq = %s\n", pinseq);
  printf("  wanted_attrib = %s\n", wanted_attrib);
#endif

  /* here is where you make it multi page aware */
  nl_current = netlist_head;

  /* search for the first instance */
  /* through the entire list */
  while (nl_current != NULL) {

    if (nl_current->component_uref) {
      if (strcmp(nl_current->component_uref, uref) == 0) {

        o_pin_object = o_complex_find_pin_by_attribute (nl_current->object_ptr,
                                                        "pinseq", pinseq);

        if (o_pin_object) {
          return_value =
            o_attrib_search_object_attribs_by_name (o_pin_object,
                                                    wanted_attrib, 0);
          if (return_value) {
            break;
          }
        }

        /* Don't break until we search the whole netlist to handle slotted */
        /* parts.   4.28.2007 -- SDB. */
      }
    }
    nl_current = nl_current->next;
  }

  scm_dynwind_end ();

  if (return_value) {
    scm_return_value = scm_from_utf8_string (return_value);
  } else {
    scm_return_value = scm_from_utf8_string ("unknown");
  }

#if DEBUG
  printf("gnetlist:g_netlist.c:g_get_attribute_by_pinseq -- ");
  printf("return_value: %s\n", return_value);
#endif

  return (scm_return_value);
}
Beispiel #21
0
/*! \brief Add pins to pin table.
 *
 * This function iterates over adds all items found on this page
 * looking for pins.  WHen it finds a pin, it gathers all
 * pin attribs and sticks them into the pin table. 
 * \param obj_list List of objects on page
 */
void s_table_add_toplevel_pin_items_to_pin_table (const GList *obj_list) {
  gchar *temp_uref;
  gchar *pinnumber;
  gchar *row_label;
  int row, col;
  gchar *attrib_text;
  gchar *attrib_name;
  gchar *attrib_value;
  const GList *o_iter;
  GList *a_iter;
  GList *o_lower_iter;
  OBJECT *pin_attrib;

  if (verbose_mode) {
    printf("- Starting internal pin TABLE creation\n");
  }

#ifdef DEBUG
  printf("=========== Just entered  s_table_add_toplevel_pin_items_to_pin_table!  ==============\n");
#endif

  /* -----  Iterate through all objects found on page  ----- */
  for (o_iter = obj_list; o_iter != NULL; o_iter = g_list_next (o_iter)) {
    OBJECT *o_current = o_iter->data;

#ifdef DEBUG
      printf("   ---> In s_table_add_toplevel_pin_items_to_pin_table, examining o_current->name = %s\n", o_current->name);
#endif

    /* -----  Now process objects found on page  ----- */
    if (o_current->type == OBJ_COMPLEX &&
        o_current->attribs != NULL) {

      /* ---- Don't process part if it lacks a refdes ----- */
      temp_uref = s_attrib_get_refdes(o_current);
      if (temp_uref) {

	/* -----  Now iterate through lower level objects looking for pins.  ----- */
        for (o_lower_iter = o_current->complex->prim_objs;
             o_lower_iter != NULL;
             o_lower_iter = g_list_next (o_lower_iter)) {
          OBJECT *o_lower_current = o_lower_iter->data;

	  if (o_lower_current->type == OBJ_PIN) {
	    /* -----  Found a pin.  First get its pinnumber.  then get attrib head and loop on attribs.  ----- */
	    pinnumber = o_attrib_search_object_attribs_by_name (o_lower_current, "pinnumber", 0);
	    row_label = g_strconcat(temp_uref, ":", pinnumber, NULL);

#if DEBUG
        printf("      In s_table_add_toplevel_pin_items_to_pin_table, examining pin %s\n", row_label);
#endif

	    a_iter = o_lower_current->attribs;
	    while (a_iter != NULL) {
	      pin_attrib = a_iter->data;
	      if (pin_attrib->type == OBJ_TEXT
		  && pin_attrib->text != NULL) {  /* found an attribute */
		attrib_text = g_strdup(pin_attrib->text->string);
		attrib_name = u_basic_breakup_string(attrib_text, '=', 0);
		attrib_value = s_misc_remaining_string(attrib_text, '=', 1);
 
		if ( (strcmp(attrib_name, "pinnumber") != 0) 
		     && (attrib_value != 0) ) {
		  /* Don't include "pinnumber" because it is already in other master list.
		   * Also must ensure that value is non-null; certain symbols are not well formed.
		   */

		  /* Get row and col where to put this attrib */
		  row = s_table_get_index(sheet_head->master_pin_list_head, row_label);
		  col = s_table_get_index(sheet_head->master_pin_attrib_list_head, attrib_name);
                  /* Sanity check */
                  if (row == -1 || col == -1) {
                    /* we didn't find the item in the table */
                    fprintf (stderr,
                             "In s_table_add_toplevel_pin_items_to_pin_table, we didn't find either row or col in the lists!\n");
                  } else {

#if DEBUG
                    printf("       In s_table_add_toplevel_pin_items_to_pin_table, about to add row %d, col %d, attrib_value = %s\n",
                           row, col, attrib_value);
                    printf(" . . . current address of attrib_value cell is [%p]\n", &((sheet_head->component_table)[row][col]).attrib_value);
#endif
                    /* Is there a compelling reason for me to put this into a separate fcn? */
                    ((sheet_head->pin_table)[row][col]).row = row;
                    ((sheet_head->pin_table)[row][col]).col = col;
                    ((sheet_head->pin_table)[row][col]).row_name = g_strdup(row_label);
                    ((sheet_head->pin_table)[row][col]).col_name = g_strdup(attrib_name);
                    ((sheet_head->pin_table)[row][col]).attrib_value = g_strdup(attrib_value);
                  }
                }
		g_free(attrib_name);
		g_free(attrib_text);
		g_free(attrib_value);
	      }
	      a_iter = g_list_next (a_iter);
           
	    }  /* while (pin_attrib != NULL) */
	    g_free(pinnumber);
	    g_free(row_label);
	  }

        }
      }

      g_free(temp_uref);
    }

  }
 
  verbose_done();
}
Beispiel #22
0
NET *s_traverse_net (TOPLEVEL *pr_current, NET *nets, int starting,
                     OBJECT *object, char *hierarchy_tag, int type)
{
  NET *new_net;
  CONN *c_current;
  GList *cl_current;
  char *temp = NULL;
  const gchar *netattrib_pinnum = NULL;

  visit (object);

  if (connection_type (object) != type)
    return nets;

  new_net = nets = s_net_add(nets);
  new_net->nid = object->sid;

  /* pins are not allowed to have the netname attribute attached to them */
  if (object->type != OBJ_PIN) {
    /* Ignore netname attributes on buses */
    if (object->type == OBJ_NET)
      temp = o_attrib_search_object_attribs_by_name (object, "netname", 0);

    if (temp) {
      new_net->net_name =
        s_hierarchy_create_netname(pr_current, temp,
                                   hierarchy_tag);
      g_free(temp);
    } else if (object->type == OBJ_NET) {
      /* search for the old label= attribute on nets */
      temp = o_attrib_search_object_attribs_by_name (object, "label", 0);
      if (temp) {
        printf(_("WARNING: Found label=%s. label= is deprecated, please use netname=\n"), temp);
        new_net->net_name =
          s_hierarchy_create_netname(pr_current, temp,
                                     hierarchy_tag);
        g_free(temp);
      }
    }
  }
#if DEBUG
  printf("inside traverse: %s\n", object->name);
#endif

  if (object->type == OBJ_PIN) {

    verbose_print (starting ? "p" : "P");

    new_net->connected_to =
      s_net_return_connected_string (pr_current, object, hierarchy_tag);

    temp = o_attrib_search_object_attribs_by_name (object, "pinlabel", 0);

    if (temp) {
      new_net->pin_label = temp;
    }

    /* net= new */
    netattrib_pinnum = s_netattrib_connected_string_get_pinnum (nets->connected_to);
    if (netattrib_pinnum != NULL && type == PIN_TYPE_NET) {

#if DEBUG
      printf("going to find netname %s \n", nets->connected_to);
#endif
      nets->net_name =
        s_netattrib_return_netname (pr_current, object,
                                    nets->connected_to,
                                    hierarchy_tag);
      nets->net_name_has_priority = TRUE;
      g_free(nets->connected_to);
      nets->connected_to = NULL;
    }
#if DEBUG
    printf("traverse connected_to: %s\n", new_net->connected_to);
#endif

    /* Terminate if we hit a pin which isn't the one we started with */
    if (!starting)
      return nets;
  }

  /*printf("Found net %s\n", object->name); */
  verbose_print("n");

  /* this is not perfect yet and won't detect a loop... */
  if (is_visited(object) > 100) {
    fprintf(stderr, _("Found a possible net/pin infinite connection\n"));
    exit(-1);
  }

  cl_current = object->conn_list;
  while (cl_current != NULL) {

    c_current = (CONN *) cl_current->data;

    if (c_current->other_object != NULL) {

      if (!is_visited(c_current->other_object) &&
          c_current->other_object != object) {
        nets = s_traverse_net (pr_current, nets, FALSE,
                               c_current->other_object, hierarchy_tag, type);
      }

    }
    cl_current = g_list_next(cl_current);
  }

  return (nets);
}
Beispiel #23
0
/*! \brief Update all slot attributes in an object.
 *  \par Function Description
 *  Update pinnumber attributes in a graphic object.
 *  The interesting case is where the object is an
 *  instantiation of a slotted part.  This means that
 *  s_slot_update_object iterates through all pins
 *  found on object and sets the pinnumber= attrib
 *  on each.  This doesn't matter for non-slotted
 *  parts, but on slotted parts, this is what sets the
 *  pinnumber= attribute on slots 2, 3, 4....
 *
 *  \param [in]     toplevel  The TOPLEVEL object.
 *  \param [in,out] object     The OBJECT to update.
 */
void s_slot_update_object (TOPLEVEL *toplevel, OBJECT *object)
{
  OBJECT *o_pin_object;
  OBJECT *o_pinnum_attrib;
  GList *attributes;
  char *string;
  char *slotdef;
  char *pinseq;
  int slot;
  int slot_string;
  int pin_counter;    /* Internal pin counter private to this fcn. */
  char* current_pin;  /* text from slotdef= to be made into pinnumber= */
  char* cptr;         /* char pointer pointing to pinnumbers in slotdef=#:#,#,# string */

  /* For this particular graphic object (component instantiation) */
  /* get the slot number as a string */
  string = o_attrib_search_object_attribs_by_name (object, "slot", 0);

  if (string == NULL) {
    /* Did not find slot= attribute.
     * This happens if there is no attached slot attribute, and
     * there is no default slot= attribute inside the symbol.
     * Assume slot=1.
     */
    slot = 1;
    slot_string = 0;
  } else {
    slot_string = 1;
    slot = atoi (string);
    g_free (string);
  }

  /* OK, now that we have the slot number, use it to get the */
  /* corresponding slotdef=#:#,#,# string.  */
  slotdef = s_slot_search_slotdef (object, slot);

  if (slotdef == NULL) {
    if (slot_string) /* only an error if there's a slot string */
      s_log_message (_("Did not find slotdef=#:#,#,#... attribute\n"));
    return;
  }

  if (!strstr (slotdef, ":")) {
    /* Didn't find proper slotdef=#:... put warning into log */
    s_log_message (_("Improper slotdef syntax: missing \":\".\n"));
    g_free (slotdef);
    return;
  }

  /* skip over slotdef number */
  /* slotdef is in the form #:#,#,# */
  /* this code skips first #: */
  cptr = slotdef;
  while (*cptr != '\0' && *cptr != ':') {
    cptr++;
  }
  cptr++; /* skip colon */

  if (*cptr == '\0') {
    s_log_message (_("Did not find proper slotdef=#:#,#,#... attribute\n"));
    g_free (slotdef);
    return;
  }

  /* loop on all pins found in slotdef= attribute */
  pin_counter = 1;  /* internal pin_counter */
  /* get current pinnumber= from slotdef= attrib */
  current_pin = strtok (cptr, DELIMITERS);
  while (current_pin != NULL) {
    /* get pin on this component with pinseq == pin_counter */
    pinseq = g_strdup_printf ("%d", pin_counter);
    o_pin_object = o_complex_find_pin_by_attribute (object, "pinseq", pinseq);
    g_free (pinseq);

    if (o_pin_object != NULL) {
      /* Now rename pinnumber= attrib on this part with value found */
      /* in slotdef attribute  */
      attributes = o_attrib_return_attribs (o_pin_object);
      o_pinnum_attrib = o_attrib_find_attrib_by_name (attributes, "pinnumber", 0);
      g_list_free (attributes);

      if (o_pinnum_attrib != NULL) {
        o_text_set_string (toplevel,
                           o_pinnum_attrib,
                           g_strdup_printf ("pinnumber=%s", current_pin));
      }

      pin_counter++;
    } else {
      s_log_message (_("component missing pinseq= attribute\n"));
    }

    current_pin = strtok (NULL, DELIMITERS);
  }

  g_free (slotdef);
}
Beispiel #24
0
void
s_traverse_sheet (TOPLEVEL * pr_current, const GList *obj_list, char *hierarchy_tag)
{
  NETLIST *netlist;
  char *temp;
  SCM scm_uref;
  char *temp_uref;
  gboolean is_hierarchy = TRUE;
  const GList *iter;
  GError *err = NULL;
  EdaConfig *cfg;

  cfg = eda_config_get_context_for_file (NULL);
  is_hierarchy = eda_config_get_boolean (cfg, "gnetlist", "traverse-hierarchy", &err);
  if (err != NULL) {
    is_hierarchy = TRUE;
    g_clear_error (&err);
  }

  if (verbose_mode) {
    printf("- Starting internal netlist creation\n");
  }

  for (iter = obj_list; iter != NULL; iter = g_list_next (iter)) {
    OBJECT *o_current = iter->data;

    netlist = s_netlist_return_tail(netlist_head);

    if (o_current->type == OBJ_PLACEHOLDER) {
      printf(_("WARNING: Found a placeholder/missing component, are you missing a symbol file? [%s]\n"), o_current->complex_basename);
    }

    if (o_current->type == OBJ_COMPLEX) {
      gboolean is_graphical = FALSE;

#if DEBUG
      printf("starting NEW component\n\n");
#endif

      verbose_print(" C");

      /* look for special tag */
      temp = o_attrib_search_object_attribs_by_name (o_current, "graphical", 0);
      if (g_strcmp0 (temp, "1") == 0) {
        /* traverse graphical elements, but adding them to the
	   graphical netlist */
	
	netlist = s_netlist_return_tail(graphical_netlist_head);
	is_graphical = TRUE;
	
    
      }
      g_free (temp);
      netlist = s_netlist_add(netlist);
      netlist->nlid = o_current->sid;

      scm_uref = g_scm_c_get_uref(pr_current, o_current);

      if (scm_is_string( scm_uref )) {
        temp_uref = scm_to_utf8_string (scm_uref);
        netlist->component_uref =
          s_hierarchy_create_uref(pr_current, temp_uref, hierarchy_tag);
        g_free(temp_uref);
      } else {
        if (hierarchy_tag) {
          netlist->component_uref = g_strdup (hierarchy_tag);
        } else {
          netlist->component_uref = NULL;
        }
      }
      
      if (hierarchy_tag) {
	netlist->hierarchy_tag = g_strdup (hierarchy_tag);
      }

      netlist->object_ptr = o_current;
      
      if (!netlist->component_uref) {
	
	/* search of net attribute */
	/* maybe symbol is not a component */
	/* but a power / gnd symbol */
	temp = o_attrib_search_object_attribs_by_name (o_current, "net", 0);
	
	/* nope net attribute not found */
	if ( (!temp) && (!is_graphical) ) {
	  
	  fprintf(stderr,
		  _("Could not find refdes on component and could not find any special attributes!\n"));
	  
	  netlist->component_uref = g_strdup("U?");
	} else {
	  
#if DEBUG
	  printf("yeah... found a power symbol\n");
#endif
	  /* it's a power or some other special symbol */
	  netlist->component_uref = NULL;
	  g_free(temp);
	}
	
      }

      netlist->cpins =
	s_traverse_component(pr_current, o_current,
			     hierarchy_tag);
      
      /* here is where you deal with the */
      /* net attribute */
      s_netattrib_handle(pr_current, o_current, netlist,
			 hierarchy_tag);
      
      /* now you need to traverse any underlying schematics */
      if (is_hierarchy) {
	s_hierarchy_traverse(pr_current, o_current, netlist);
      }
    }
  }

  verbose_done();
}
Beispiel #25
0
/*! \brief Creates a list of already numbered objects and slots
 *  \par Function Description
 *  This function collects the used numbers of a single schematic page.
 *  The used element numbers are stored in a GList container
 *  inside the <B>AUTONUMBER_TEXT</B> struct.
 *  The slotting container is a little bit different. It stores free slots of
 *  multislotted symbols, that were used only partially.
 *  The criterias are derivated from the autonumber dialog entries.
 */
void autonumber_get_used(GschemToplevel *w_current, AUTONUMBER_TEXT *autotext)
{
  gint number, numslots, slotnr, i;
  OBJECT *o_current, *o_parent;
  AUTONUMBER_SLOT *slot;
  GList *slot_item;
  char *numslot_str, *slot_str;
  const GList *iter;
  
  for (iter = s_page_objects (w_current->toplevel->page_current);
       iter != NULL;
       iter = g_list_next (iter)) {
    o_current = iter->data;
    if (autonumber_match(autotext, o_current, &number) == AUTONUMBER_RESPECT) {
      /* check slot and maybe add it to the lists */
      o_parent = o_current->attached_to;
      if (autotext->slotting && o_parent != NULL) {
	/* check for slotted symbol */
	numslot_str =
	  o_attrib_search_object_attribs_by_name (o_parent, "numslots", 0);
	if (numslot_str != NULL) {
	  sscanf(numslot_str," %d",&numslots);
	  g_free(numslot_str);

	  if (numslots > 0) { 
	    slot_str = o_attrib_search_object_attribs_by_name (o_parent, "slot", 0);
	    if (slot_str == NULL) {
	      s_log_message(_("slotted object without slot attribute may cause "
			      "problems when autonumbering slots\n"));
	    }
	    else {
	      sscanf(slot_str, " %d", &slotnr);
	      slot = g_new(AUTONUMBER_SLOT,1);
	      slot->number = number;
	      slot->slotnr = slotnr;
	      slot->symbolname = o_parent->complex_basename;
	

	      slot_item = g_list_find_custom(autotext->used_slots,
						 slot,
						 (GCompareFunc) freeslot_compare);
	      if (slot_item != NULL) { /* duplicate slot in used_slots */
		s_log_message(_("duplicate slot may cause problems: "
				"[symbolname=%s, number=%d, slot=%d]\n"),
				slot->symbolname, slot->number, slot->slotnr);
		g_free(slot);
	      }
	      else {
		autotext->used_slots = g_list_insert_sorted(autotext->used_slots,
							    slot,
							    (GCompareFunc) freeslot_compare);
		
		slot_item = g_list_find_custom(autotext->free_slots,
						   slot,
						   (GCompareFunc) freeslot_compare);
		if (slot_item == NULL) {
		  /* insert all slots to the list, except of the current one */
		  for (i=1; i <= numslots; i++) {
		    if (i != slotnr) {
		      slot = g_memdup(slot, sizeof(AUTONUMBER_SLOT));
		      slot->slotnr = i;
		      autotext->free_slots = g_list_insert_sorted(autotext->free_slots,
								  slot,
								  (GCompareFunc) freeslot_compare);
		    }
		  }
		}
		else {
		  g_free(slot_item->data);
		  autotext->free_slots = g_list_delete_link(autotext->free_slots, slot_item);
		}
	      }
	    }
	  }
	}
      }
      /* put number into the used list */
      autotext->used_numbers = g_list_insert_sorted(autotext->used_numbers,
						    GINT_TO_POINTER(number),
						    (GCompareFunc) autonumber_sort_numbers);
    }
  }
}