1 /* gEDA - GPL Electronic Design Automation
2 * gattrib -- gEDA component and net attribute manipulation using spreadsheet.
3 * Copyright (C) 2003 Stuart D. Brorson.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
20 /*------------------------------------------------------------------
21 * This file holds fcns involved in manipulating an entire SHEET_DATA
22 * structure. The SHEET_DATA structure is the intermediate structure
23 * between TOPLEVEL (gEDA's native format) and the graphical gtksheet
24 * widget (from gtkextra), which is the spreadsheet widget displaying
26 *------------------------------------------------------------------*/
36 /*------------------------------------------------------------------
37 * Gattrib specific includes
38 *------------------------------------------------------------------*/
39 #include <libgeda/libgeda.h> /* geda library fcns */
40 #include "../include/struct.h" /* typdef and struct declarations */
41 #include "../include/prototype.h" /* function prototypes */
42 #include "../include/globals.h"
45 /*------------------------------------------------------------------
46 * This fcn is the sheet_data creator. It returns a pointer to
47 * an initialized SHEET_DATA struct.
48 *------------------------------------------------------------------*/
49 SHEET_DATA
*s_sheet_data_new()
51 SHEET_DATA
*new_sheet
;
53 new_sheet
= (SHEET_DATA
*) malloc(sizeof(SHEET_DATA
));
55 /* We will malloc and fill out the comp table later. */
56 new_sheet
->component_table
= NULL
;
58 /* We will malloc and fill out the net table later. */
59 new_sheet
->net_table
= NULL
;
61 /* We will malloc and fill out the pin table later. */
62 new_sheet
->pin_table
= NULL
;
64 /* Now we create the first cell in each master list. */
65 new_sheet
->master_comp_list_head
= (STRING_LIST
*) s_string_list_new();
66 new_sheet
->master_comp_attrib_list_head
= (STRING_LIST
*) s_string_list_new();
67 new_sheet
->comp_count
= 0;
68 new_sheet
->comp_attrib_count
= 0;
70 new_sheet
->master_net_list_head
= (STRING_LIST
*) s_string_list_new();
71 new_sheet
->master_net_attrib_list_head
= (STRING_LIST
*) s_string_list_new();
72 new_sheet
->net_count
= 0;
73 new_sheet
->net_attrib_count
= 0;
75 new_sheet
->master_pin_list_head
= (STRING_LIST
*) s_string_list_new();
76 new_sheet
->master_pin_attrib_list_head
= (STRING_LIST
*) s_string_list_new();
77 new_sheet
->pin_count
= 0;
78 new_sheet
->pin_attrib_count
= 0;
86 /*------------------------------------------------------------------
87 * This fcn adds to the master list of components refdeses by running
88 * through the components and recording the comp refdeses
89 * it discovers. Then it sorts them into alphabetical order.
90 * Data struct being searched is: OBJECT->attribs(->next. . .)->object->text->string
91 *------------------------------------------------------------------*/
92 void s_sheet_data_add_master_comp_list_items(OBJECT
*start_obj
) {
100 printf("=========== Just entered s_sheet_data_add_master_comp_list_items! ==============\n");
104 printf("- Starting master comp list creation.\n");
107 /* ----- Iterate through all objects found on page looking for components ----- */
108 o_current
= start_obj
;
109 while (o_current
!= NULL
) {
112 printf("In s_sheet_data_add_master_comp_list_items, examining o_current->name = %s\n", o_current
->name
);
115 /*----- only process if this is a non-graphical comp with attributes ----*/
116 if ( (o_current
->type
== OBJ_COMPLEX
) &&
117 o_current
->attribs
&&
118 !o_attrib_search_component(o_current
, "graphical") ) {
123 printf(" In s_sheet_data_add_master_comp_list_items; found component on page\n");
124 fprintf(stderr
, ". . . . complex_basename = %s.\n", o_current
->complex_basename
);
128 /*------ Try to get the refdes -----*/
129 temp_uref
= o_attrib_search_name_single(o_current
, "refdes", NULL
);
131 temp_uref
= o_attrib_search_name_single(o_current
, "uref", NULL
); // deprecated
133 printf("WARNING: Found uref=%s, uref= is deprecated, please use refdes=\n", temp_uref
);
134 } else { /* didn't find refdes. Report error to log. */
135 fprintf(stderr
, " In s_sheet_data_add_master_comp_list_items, found non-graphical component with no refdes.\n");
137 fprintf(stderr
, ". . . . complex_basename = %s.\n", o_current
->complex_basename
);
140 } /*--- if(!temp_uref) ---*/
143 /* Now that we have refdes, store refdes and attach attrib list to component */
148 printf(" In s_sheet_add_master_comp_list, about to add to master list refdes = %s\n", temp_uref
);
150 s_string_list_add_item(sheet_head
->master_comp_list_head
, &(sheet_head
->comp_count
), temp_uref
);
154 } /* if (o_current->type == OBJ_COMPLEX . . . . .) */
156 o_current
= o_current
->next
; /* iterate to next object on page */
157 } /* while o_current != NULL */
163 /*------------------------------------------------------------------
164 * This fcn adds to the master list of comp attribs by running
165 * through each component on the page and recording all attribs
166 * it discovers. Then it sorts them into an order used for the
167 * horiz listing of the attribs on the spreadsheet.
168 * Data struct being searched is: sheet_head->component_list_head->attrib->name;
169 *------------------------------------------------------------------*/
170 void s_sheet_data_add_master_comp_attrib_list_items(OBJECT
*start_obj
) {
182 printf("=========== Just entered s_sheet_data_add_master_comp_attrib_list_items! ==============\n");
186 printf("- Starting master comp attrib list creation.\n");
189 /* ----- Iterate through all objects found on page looking for components ----- */
190 o_current
= start_obj
;
191 while (o_current
!= NULL
) {
194 printf("In s_sheet_data_add_master_comp_attrib_list_items, examining o_current->name = %s\n", o_current
->name
);
197 /*----- only process if this is a non-graphical comp with attributes ----*/
198 if ( (o_current
->type
== OBJ_COMPLEX
) &&
199 o_current
->attribs
&&
200 !o_attrib_search_component(o_current
, "graphical") ) {
205 /*------ Iterate through all attribs found on component -----*/
206 a_current
= o_current
->attribs
; /* This has a side effect. Why? */
207 while (a_current
!= NULL
) {
208 if (a_current
->object
->type
== OBJ_TEXT
209 && a_current
->object
->text
!= NULL
) { /* found an attribute */
210 attrib_text
= u_basic_strdup(a_current
->object
->text
->string
);
211 attrib_name
= u_basic_breakup_string(attrib_text
, '=', 0);
212 if (strcmp(attrib_name
, "refdes") != 0) {
213 /* Don't include "refdes" because it is already in other master list */
215 temp_uref
= o_attrib_search_name_single(o_current
, "refdes", NULL
);
218 printf("In s_sheet_data_add_master_comp_attrib_list, examining component refdes = %s\n", temp_uref
);
220 printf(" . . . from this component, about to add to master comp attrib list attrib = %s\n", attrib_name
);
222 s_string_list_add_item(sheet_head
->master_comp_attrib_list_head
,
223 &(sheet_head
->comp_attrib_count
), attrib_name
);
224 } /* if (strcmp(attrib_name, "refdes") != 0) */
228 a_current
= a_current
->next
;
231 } /* if (o_current->type == OBJ_COMPLEX) */
233 o_current
= o_current
->next
;
234 } /* while (o_current != NULL) */
236 /* ----- Now sort component list into alphabetical order ----- */
243 /*------------------------------------------------------------------
244 * This fcn builds the master list of net names by running
245 * through the individual cells and recording the net refdeses
247 *------------------------------------------------------------------*/
248 void s_sheet_data_add_master_net_list_items(OBJECT
*start_obj
) {
253 /*------------------------------------------------------------------
254 * This fcn builds the master list of net attribs.
255 *------------------------------------------------------------------*/
256 void s_sheet_data_add_master_net_attrib_list_items(OBJECT
*start_obj
) {
261 /*------------------------------------------------------------------
262 * This fcn builds the master list of pin names. It writes the
263 * label refdes:pinnumber into the global master pin list.
265 * 1. Loop on o_current looking for OBJ_COMPLEX
266 * 2. When we find a complex, save the refdes.
267 * 3. Dive down to o_lower_current = o_current->complex->prim_objs
268 * 4. Loop on o_lower_current looking for OBJ_PIN
269 * 5. When we find a pin, find the pinnumber by calling
270 * o_attrib_search_name_single(o_lower_current, "pinnumber", NULL)
271 * 6. Create the pin list label as "refdes=XXX", and stick it into
272 * the master pin list.
273 * Since this fcn operates on the global sheet_data->master_pin_list,
274 * it doesn't return a value.
275 *------------------------------------------------------------------*/
276 void s_sheet_data_add_master_pin_list_items(OBJECT
*start_obj
) {
278 char *temp_pinnumber
;
281 OBJECT
*o_lower_current
;
286 printf("=========== Just entered s_sheet_data_add_master_pin_list_items! ==============\n");
290 printf("- Starting master pin list creation.\n");
293 /* ----- Iterate through all objects found on page looking for components ----- */
294 o_current
= start_obj
;
295 while (o_current
!= NULL
) {
298 printf("In s_sheet_data_add_master_pin_list_items, examining o_current->name = %s\n", o_current
->name
);
301 if (o_current
->type
== OBJ_COMPLEX
) {
302 temp_uref
= o_attrib_search_name_single(o_current
, "refdes", NULL
);
303 if (temp_uref
!= NULL
) { /* make sure object complex has a refdes */
305 /* ----- Now iterate through lower level objects looking for pins. ----- */
306 o_lower_current
= o_current
->complex->prim_objs
;
307 while (o_lower_current
!= NULL
) {
309 printf("In s_sheet_data_add_master_pin_list_items, examining object name %s\n", o_lower_current
->name
);
311 if (o_lower_current
->type
== OBJ_PIN
) {
312 temp_pinnumber
= o_attrib_search_name_single(o_lower_current
, "pinnumber", NULL
);
314 if( temp_pinnumber
!= NULL
) {
315 row_label
= u_basic_strdup_multiple(temp_uref
, ":", temp_pinnumber
, NULL
);
317 printf("In s_sheet_data_add_master_pin_list_items, about to add to master pin list row_label = %s\n", row_label
);
319 s_string_list_add_item(sheet_head
->master_pin_list_head
, &(sheet_head
->pin_count
), row_label
);
321 } else { /* didn't find pinnumber. Report error to log. */
322 fprintf(stderr
, "In s_sheet_data_add_master_pin_list_items, found component pin with no pinnumber.\n");
324 fprintf(stderr
, ". . . . refdes = %s.\n", temp_uref
);
327 free(temp_pinnumber
);
330 o_lower_current
= o_lower_current
->next
;
331 } /* while (o_lower_current != NULL) */
333 } else { /* didn't find refdes. Report error to log. */
334 fprintf(stderr
, "In s_sheet_data_add_master_pin_list_items, found non-graphical component with no refdes.\n");
336 fprintf(stderr
, ". . . . complex_basename = %s.\n", o_current
->complex_basename
);
341 } /* if (o_current->type == OBJ_COMPLEX) */
342 o_current
= o_current
->next
;
344 } /* while o_current != NULL */
350 /*------------------------------------------------------------------
351 * This fcn builds the master list of pin attributes. It writes
352 * each attrib name into the master pin attrib list.
354 * 1. Loop on o_current looking for OBJ_COMPLEX
355 * 2. When we find a complex, save the refdes.
356 * 3. Dive down to o_lower_current = o_current->complex->prim_objs
357 * 4. Loop on o_lower_current looking for OBJ_PIN
358 * 5. When we find a pin, get pin_attribs = o_lower_current->attribs
359 * 6. Loop on attribs looking for non-NULL text.
360 * 7. When we find a non-NULL text attrib, extract the attrib name
361 * and stick it in the master pin attrib list.
362 *------------------------------------------------------------------*/
363 void s_sheet_data_add_master_pin_attrib_list_items(OBJECT
*start_obj
) {
368 OBJECT
*o_lower_current
;
374 printf("=========== Just entered s_sheet_data_add_master_pin_attrib_list_items! ==============\n");
378 printf("- Starting master pin attrib list creation.\n");
381 /* ----- Iterate through all objects found on page looking for components ----- */
382 o_current
= start_obj
;
383 while (o_current
!= NULL
) {
386 printf("In s_sheet_data_add_master_pin_attrib_list_items, examining o_current->name = %s\n", o_current
->name
);
389 if (o_current
->type
== OBJ_COMPLEX
) {
390 temp_uref
= o_attrib_search_name_single(o_current
, "refdes", NULL
);
391 if (temp_uref
!= NULL
) { /* make sure object complex has a refdes */
393 /* ----- Now iterate through lower level objects looking for pins. ----- */
394 o_lower_current
= o_current
->complex->prim_objs
;
395 while (o_lower_current
!= NULL
) {
397 printf("In s_sheet_data_add_master_pin_attrib_list_items, examining component refdes = %s\n", temp_uref
);
399 if (o_lower_current
->type
== OBJ_PIN
) {
400 /* ----- Found a pin. Now get attrib head and loop on attribs. ----- */
401 pin_attrib
= o_lower_current
->attribs
;
402 while (pin_attrib
!= NULL
) {
403 if (pin_attrib
->object
->type
== OBJ_TEXT
404 && pin_attrib
->object
->text
!= NULL
) { /* found an attribute */
405 attrib_text
= u_basic_strdup(pin_attrib
->object
->text
->string
);
406 attrib_name
= u_basic_breakup_string(attrib_text
, '=', 0);
407 if (strcmp(attrib_name
, "pinnumber") != 0) {
408 /* Don't include "pinnumber" because it is already in other master list */
411 printf("In s_sheet_data_add_master_pin_attrib_list_items, found pin attrib = %s\n", attrib_name
);
412 printf(". . . . . adding it to master_pin_attrib_list\n");
415 s_string_list_add_item(sheet_head
->master_pin_attrib_list_head
,
416 &(sheet_head
->pin_attrib_count
), attrib_name
);
417 } /* if (strcmp(attrib_name, "pinnumber") != 0) */
421 pin_attrib
= pin_attrib
->next
;
422 } /* while (pin_attrib != NULL) */
424 o_lower_current
= o_lower_current
->next
;
425 } /* while (o_lower_current != NULL) */
428 } /* if (temp_uref != NULL ) */
430 } /* if (o_current->type == OBJ_COMPLEX) */
431 o_current
= o_current
->next
;
433 } /* while (o_current != NULL) */
441 /*------------------------------------------------------------------
442 * This fcn extracts the attribs from the gtksheet
443 * cells, and places them back into SHEET_DATA. This is the
444 * first step in saving out a project. Right now I just invoke
445 * s_table_gtksheet_to_table. Do I need to do anything else here?
446 *------------------------------------------------------------------*/
447 void s_sheet_data_gtksheet_to_sheetdata() {
448 s_table_gtksheet_to_all_tables();
449 /* do I need to do anything else here? */