static void netlist_helper_nl_wire_traverse (Wire *wire, GSList **lst) { GSList *nodes; g_return_if_fail (wire != NULL); g_return_if_fail (IS_WIRE (wire)); if (wire_is_visited (wire)) return; wire_set_visited (wire, TRUE); for (nodes = wire_get_nodes (wire); nodes; nodes = nodes->next) { GSList *pins; Part *part; Node *node = nodes->data; for (pins=node->pins; pins; pins=pins->next) { char *template, *tmp; char **template_split; part = PART (((Pin *)pins->data)->part); tmp = part_get_property (part, "template"); if (!tmp) continue;
static char * part_get_refdes_prefix (ItemData *data) { Part *part; char *refdes; int i, length; g_return_val_if_fail (IS_PART (data), NULL); part = PART (data); refdes = part_get_property (part, "refdes"); if (refdes == NULL) return NULL; // Get the 'prefix' i.e R for resistors. length = strlen (refdes); for (i = 0; i < length; i++) { if (isdigit (refdes[length-i -1])) { refdes[length -i -1] = '\0'; } else break; } return g_strdup (refdes); }
static void edit_properties (SheetItem *object) { GSList *properties; PartItem *item; Part *part; char *internal, *msg; GtkBuilder *gui; GError *error = NULL; GtkGrid *prop_grid; GtkNotebook *notebook; gint response, y = 0; gboolean has_model; gchar *model_name = NULL; g_return_if_fail (object != NULL); g_return_if_fail (IS_PART_ITEM (object)); item = PART_ITEM (object); part = PART (sheet_item_get_data (SHEET_ITEM (item))); internal = part_get_property (part, "internal"); if (internal) { if (g_ascii_strcasecmp (internal, "ground") == 0) { g_free (internal); return; } if (g_ascii_strcasecmp (internal, "point") == 0) { edit_properties_point (item); return; } } g_free (internal); if ((gui = gtk_builder_new ()) == NULL) { oregano_error (_("Could not create part properties dialog.")); return; } else gtk_builder_set_translation_domain (gui, NULL); if (gtk_builder_add_from_file (gui, OREGANO_UIDIR "/part-properties-dialog.ui", &error) <= 0) { msg = error->message; oregano_error_with_title (_("Could not create part properties dialog."), msg); g_error_free (error); return; } prop_dialog = g_new0 (PartPropDialog, 1); prop_dialog->part_item = item; prop_dialog->dialog = GTK_DIALOG (gtk_builder_get_object (gui, "part-properties-dialog")); prop_grid = GTK_GRID (gtk_builder_get_object (gui, "prop_grid")); notebook = GTK_NOTEBOOK (gtk_builder_get_object (gui, "notebook")); g_signal_connect (prop_dialog->dialog, "destroy", G_CALLBACK (prop_dialog_destroy), prop_dialog); prop_dialog->widgets = NULL; has_model = FALSE; for (properties = part_get_properties (part); properties; properties = properties->next) { Property *prop; prop = properties->data; if (prop->name) { GtkWidget *entry; GtkWidget *label; gchar *temp=NULL; if (!g_ascii_strcasecmp (prop->name, "internal")) continue; if (!g_ascii_strcasecmp (prop->name, "model")) { has_model = TRUE; model_name = g_strdup (prop->value); } // Find the Refdes and replace by their real value temp = prop->name; if (!g_ascii_strcasecmp (temp, "Refdes")) temp = _("Designation"); if (!g_ascii_strcasecmp (temp, "Template")) temp = _("Template"); if (!g_ascii_strcasecmp (temp, "Res")) temp = _("Resistor"); if (!g_ascii_strcasecmp (temp, "Cap")) temp = _("Capacitor"); if (!g_ascii_strcasecmp (temp, "Ind")) temp = _("Inductor"); label = gtk_label_new (temp); entry = gtk_entry_new (); gtk_entry_set_text (GTK_ENTRY (entry), prop->value); g_object_set_data (G_OBJECT (entry), "user", g_strdup (prop->name)); gtk_grid_attach (prop_grid, label, 0,y, 1,1); gtk_grid_attach (prop_grid, entry, 1,y, 1,1); y++; gtk_widget_show (label); gtk_widget_show (entry); prop_dialog->widgets = g_list_prepend (prop_dialog->widgets, entry); } } if (!has_model) { gtk_notebook_remove_page (notebook, 1); } else { GtkTextBuffer *txtbuffer; GtkTextView *txtmodel; gchar *filename, *str; GError *read_error = NULL; txtmodel = GTK_TEXT_VIEW (gtk_builder_get_object (gui, "txtmodel")); txtbuffer = gtk_text_buffer_new (NULL); filename = g_strdup_printf ("%s/%s.model", OREGANO_MODELDIR, model_name); if (g_file_get_contents (filename, &str, NULL, &read_error)) { gtk_text_buffer_set_text (txtbuffer, str, -1); g_free (str); } else { gtk_text_buffer_set_text (txtbuffer, read_error->message, -1); g_error_free (read_error); } g_free (filename); g_free (model_name); gtk_text_view_set_buffer (txtmodel, txtbuffer); } gtk_dialog_set_default_response (prop_dialog->dialog, 1); response = gtk_dialog_run (prop_dialog->dialog); prop_dialog_response (GTK_WIDGET (prop_dialog->dialog), response, prop_dialog); g_slist_free_full (properties, g_object_unref); gtk_widget_destroy (GTK_WIDGET (prop_dialog->dialog)); }
char *part_property_expand_macros (Part *part, char *string) { static char mcode[] = {"@?~#&"}; char *value; char *tmp0, *temp, *qn, *q0, *t0; char *cls1, *cls2; GString *out; size_t sln; char *ret; g_return_val_if_fail (part != NULL, NULL); g_return_val_if_fail (IS_PART (part), NULL); g_return_val_if_fail (string != NULL, NULL); cls1 = cls2 = q0 = NULL; // Rules: // @<id> value of <id>. If no value, error // &<id> value of <id> if <id> is defined // ?<id>s...s text between s...s separators if <id> defined // ?<id>s...ss...s text between 1st s...s separators if <id> defined // else 2nd s...s clause // ~<id>s...s text between s...s separators if <id> undefined // ~<id>s...ss...s text between 1st s...s separators if <id> undefined // else 2nd s...s clause // #<id>s...s text between s...s separators if <id> defined, but // delete rest of tempalte if <id> undefined // Separators can be any of (, . ; / |) For an opening-closing pair of // separators the same character ahs to be used. // Examples: R^@refdes %1 %2 @value // V^@refdes %+ %- SIN(@offset @ampl @freq 0 0) // ?DC|DC @DC| tmp0 = temp = g_strdup (string); out = g_string_new (""); for (temp = string; *temp;) { // Look for any of the macro char codes. if (strchr (mcode, *temp)) { qn = get_macro_name (temp + 1, &cls1, &cls2, &sln); if (qn == NULL) return NULL; value = part_get_property (part, qn); if ((*temp == '@' || *temp == '&') && value) { out = g_string_append (out, value); } else if (*temp == '&' && !value) { g_warning ("expand macro error: macro %s undefined", qn); g_free (qn); return NULL; } else if (*temp == '?' || *temp == '~') { if (cls1 == NULL) { g_warning ("error in template: %s", temp); g_free (qn); return NULL; } q0 = (value ? (*temp == '?' ? cls1 : cls2) : (*temp == '?' ? cls2 : cls1)); if (q0) { t0 = part_property_expand_macros (part, q0); if (!t0) { g_warning ("error in template: %s", temp); g_free (qn); } else { out = g_string_append (out, t0); g_free (t0); } } } else if (*temp == '#') { if (value) { t0 = part_property_expand_macros (part, value); if (!t0) { g_warning ("error in template: %s", temp); g_free (qn); } else { out = g_string_append (out, t0); g_free (t0); } } else *(temp + sln) = 0; } temp += 1; temp += sln; if (qn) g_free (qn); if (cls1) g_free (cls1); if (cls2) g_free (cls2); } else { if (*temp == '\\') { temp++; switch (*temp) { case 'n': out = g_string_append_c (out, '\n'); break; case 't': out = g_string_append_c (out, '\t'); break; case 'r': out = g_string_append_c (out, '\r'); break; case 'f': out = g_string_append_c (out, '\f'); } temp++; } else { out = g_string_append_c (out, *temp); temp++; } } } if (tmp0) g_free (tmp0); out = g_string_append_c (out, '\0'); ret = g_strdup (out->str); g_string_free (out, TRUE); return ret; }