File: s_sheet_data.c

package info (click to toggle)
geda-gattrib 20050313-2
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 1,708 kB
  • ctags: 1,532
  • sloc: ansic: 24,372; sh: 3,460; makefile: 140
file content (441 lines) | stat: -rw-r--r-- 15,992 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
/* gEDA - GPL Electronic Design Automation
 * gattrib -- gEDA component and net attribute manipulation using spreadsheet.
 * Copyright (C) 2003 Stuart D. Brorson.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
 */

/*------------------------------------------------------------------
 * This file holds fcns involved in manipulating an entire SHEET_DATA
 * structure.  The SHEET_DATA structure is the intermediate structure
 * between TOPLEVEL (gEDA's native format) and the graphical gtksheet
 * widget (from gtkextra), which is the spreadsheet widget displaying 
 * the attribs.
 *------------------------------------------------------------------*/

#include <config.h>

#include <stdio.h>
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#include <math.h>

/*------------------------------------------------------------------
 * Gattrib specific includes
 *------------------------------------------------------------------*/
#include <libgeda/libgeda.h>       /* geda library fcns  */
#include "../include/struct.h"     /* typdef and struct declarations */
#include "../include/prototype.h"  /* function prototypes */
#include "../include/globals.h"

#ifdef HAVE_LIBDMALLOC
#include <dmalloc.h>
#endif


/*------------------------------------------------------------------
 * This fcn is the sheet_data creator.  It returns a pointer to 
 * an initialized SHEET_DATA struct.
 *------------------------------------------------------------------*/
SHEET_DATA *s_sheet_data_new()
{
  SHEET_DATA *new_sheet;

  new_sheet = (SHEET_DATA *) malloc(sizeof(SHEET_DATA));

  /* We will malloc and fill out the comp table later. */
  new_sheet->component_table = NULL;

  /* We will malloc and fill out the net table later. */
  new_sheet->net_table = NULL;

  /* We will malloc and fill out the pin table later. */
  new_sheet->pin_table = NULL;

  /* Now we create the first cell in each master list. */
  new_sheet->master_comp_list_head = (STRING_LIST *) s_string_list_new();
  new_sheet->master_comp_attrib_list_head = (STRING_LIST *) s_string_list_new();
  new_sheet->comp_count = 0;
  new_sheet->comp_attrib_count = 0;

  new_sheet->master_net_list_head = (STRING_LIST *) s_string_list_new();
  new_sheet->master_net_attrib_list_head = (STRING_LIST *) s_string_list_new();
  new_sheet->net_count = 0;
  new_sheet->net_attrib_count = 0;

  new_sheet->master_pin_list_head = (STRING_LIST *) s_string_list_new();
  new_sheet->master_pin_attrib_list_head = (STRING_LIST *) s_string_list_new();
  new_sheet->pin_count = 0;
  new_sheet->pin_attrib_count = 0;

  new_sheet->CHANGED = FALSE;

  return (new_sheet);

}



/*------------------------------------------------------------------
 * This fcn adds to the master list of components refdeses by running
 * through the components and recording the comp refdeses
 * it discovers. Then it sorts them into alphabetical order.
 * Data struct being searched is: OBJECT->attribs(->next. . .)->object->text->string
 *------------------------------------------------------------------*/
void s_sheet_data_add_master_comp_list_items(OBJECT *start_obj) {
  char *temp_uref;
  OBJECT *o_current;
  
#ifdef DEBUG
  printf("=========== Just entered  s_sheet_data_add_master_comp_list_items!  ==============\n");
#endif

  if (verbose_mode) {
    printf("- Starting master comp list creation.\n");
  }

  /* -----  Iterate through all objects found on page looking for components  ----- */
  o_current = start_obj;
  while (o_current != NULL) {

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

      /*-----  only process if this is a non-graphical comp with attributes ----*/
      if ( (o_current->type == OBJ_COMPLEX) &&
	    o_current->attribs && 
	    !o_attrib_search_component(o_current, "graphical") ) {    
	
#if DEBUG
	printf("      In s_sheet_data_add_master_comp_list_items; found component on page\n");
	printf(". . . . complex_basename = %s.\n", o_current->complex_basename);
#endif
	verbose_print(" C");
      
	temp_uref = s_attrib_get_refdes(o_current);
	
	/* Now that we have refdes, store refdes and attach attrib list to component */
	if (temp_uref) {
#if DEBUG
	  printf("       In s_sheet_add_master_comp_list, about to add to master list refdes = %s\n", temp_uref);
#endif
	  s_string_list_add_item(sheet_head->master_comp_list_head, &(sheet_head->comp_count), temp_uref);
	  free(temp_uref);
	}
	
      } /*  if (o_current->type == OBJ_COMPLEX . . . . .) */
      
      o_current = o_current->next;  /* iterate to next object on page */
  }  /*  while o_current != NULL */
  
  return;
}


/*------------------------------------------------------------------
 * This fcn adds to the master list of comp attribs by running
 * through each component on the page and recording all attribs 
 * it discovers. Then it sorts them into an order used for the 
 * horiz listing of the attribs on the spreadsheet.
 * Data struct being searched is: sheet_head->component_list_head->attrib->name;
 *------------------------------------------------------------------*/
void s_sheet_data_add_master_comp_attrib_list_items(OBJECT *start_obj) {
  char *attrib_text;
  char *attrib_name;
  OBJECT *o_current;
  ATTRIB *a_current;
  
#ifdef DEBUG
  fflush(stderr);
  fflush(stdout);
  printf("=========== Just entered  s_sheet_data_add_master_comp_attrib_list_items!  ==============\n");
#endif

  if (verbose_mode) {
    printf("- Starting master comp attrib list creation.\n");
  }

  /* -----  Iterate through all objects found on page looking for components (OBJ_COMPLEX) ----- */
  o_current = start_obj;
  while (o_current != NULL) {

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

      /*-----  only process if this is a non-graphical comp with attributes ----*/
      if ( (o_current->type == OBJ_COMPLEX) &&
	    o_current->attribs && 
	    !o_attrib_search_component(o_current, "graphical") ) {    

	
	verbose_print(" C");
	
	/*------ Iterate through all attribs found on component -----*/
	a_current = o_current->attribs; /* This has a side effect.  Why? */
	while (a_current != NULL) {
	  if (a_current->object->type == OBJ_TEXT 
	      && a_current->object->text != NULL) {  /* found an attribute */
	    attrib_text = g_strdup(a_current->object->text->string);
	    attrib_name = u_basic_breakup_string(attrib_text, '=', 0);

	      /* Don't include "refdes" or "slot" because they form the row name */
	    if ( (strcmp(attrib_name, "refdes") != 0) 
		 && (strcmp(attrib_name, "slot") != 0) ) {  
#if DEBUG
	      printf(" . . . from this component, about to add to master comp attrib list attrib = %s\n", attrib_name);
#endif
	      s_string_list_add_item(sheet_head->master_comp_attrib_list_head, 
				     &(sheet_head->comp_attrib_count), attrib_name);
	    }   /* if (strcmp(attrib_name, "refdes") != 0) */ 
	    free(attrib_name);
	    free(attrib_text);
	  }
	  a_current = a_current->next;
	}   /*  while  */
	
      }   /* if (o_current->type == OBJ_COMPLEX) */
      
      o_current = o_current->next;
  }   /* while (o_current != NULL) */
  
  /* -----  Now sort component list into alphabetical order  ----- */
  
  return;
}



/*------------------------------------------------------------------
 * This fcn builds the master list of net names by running
 * through the individual cells and recording the net refdeses
 * it discovers. 
 *------------------------------------------------------------------*/
void s_sheet_data_add_master_net_list_items(OBJECT *start_obj) {
  return;
}


/*------------------------------------------------------------------
 * This fcn builds the master list of net attribs.
 *------------------------------------------------------------------*/
void s_sheet_data_add_master_net_attrib_list_items(OBJECT *start_obj) {
  return;
}


/*------------------------------------------------------------------
 * This fcn builds the master list of pin names.  It writes the
 * label refdes:pinnumber into the global master pin list.
 * Algorithm:
 * 1.  Loop on o_current looking for OBJ_COMPLEX
 * 2.  When we find a complex, save the refdes.
 * 3.  Dive down to o_lower_current = o_current->complex->prim_objs
 * 4.  Loop on o_lower_current looking for OBJ_PIN
 * 5.  When we find a pin, find the pinnumber by calling
 *     o_attrib_search_name_single(o_lower_current, "pinnumber", NULL)
 * 6.  Create the pin list label as "refdes=XXX", and stick it into
 *     the master pin list.
 * Since this fcn operates on the global sheet_data->master_pin_list, 
 * it doesn't return a value.
 *------------------------------------------------------------------*/
void s_sheet_data_add_master_pin_list_items(OBJECT *start_obj) {
  char *temp_uref;
  char *temp_pinnumber;
  char *row_label;
  OBJECT *o_current;
  OBJECT *o_lower_current;
  
#ifdef DEBUG
  fflush(stderr);
  fflush(stdout);
  printf("=========== Just entered  s_sheet_data_add_master_pin_list_items!  ==============\n");
#endif

  if (verbose_mode) {
    printf("- Starting master pin list creation.\n");
  }

  /* -----  Iterate through all objects found on page looking for components  ----- */
  o_current = start_obj;
  while (o_current != NULL) {

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

      if (o_current->type == OBJ_COMPLEX) {
	temp_uref = s_attrib_get_refdes(o_current);
	if (temp_uref != NULL) {      /* make sure object complex has a refdes  */
	  
	  /* -----  Now iterate through lower level objects looking for pins.  ----- */
	  o_lower_current = o_current->complex->prim_objs;
	  while (o_lower_current != NULL) {
#if DEBUG
	    printf("In s_sheet_data_add_master_pin_list_items, examining object name %s\n", o_lower_current->name);
#endif
	    if (o_lower_current->type == OBJ_PIN) {
	      temp_pinnumber = o_attrib_search_name_single(o_lower_current, "pinnumber", NULL);
	      
	      if( temp_pinnumber != NULL) {
		row_label = g_strconcat(temp_uref, ":", temp_pinnumber, NULL);
#if DEBUG
		printf("In s_sheet_data_add_master_pin_list_items, about to add to master pin list row_label = %s\n", row_label);
#endif
		s_string_list_add_item(sheet_head->master_pin_list_head, &(sheet_head->pin_count), row_label);
		
	      } else {      /* didn't find pinnumber.  Report error to log. */
		fprintf(stderr, "In s_sheet_data_add_master_pin_list_items, found component pin with no pinnumber.\n");
#ifdef DEBUG
		fprintf(stderr, ". . . . refdes = %s.\n", temp_uref);
#endif
	      }
	      free(temp_pinnumber);
	      
	    }
	    o_lower_current = o_lower_current->next;
	  }   /*   while (o_lower_current != NULL)   */
	  
	} else {          /* didn't find refdes.  Report error to log. */
#ifdef DEBUG
	  fprintf(stderr, "In s_sheet_data_add_master_pin_list_items, found non-graphical component with no refdes.\n");
	  fprintf(stderr, ". . . . complex_basename = %s.\n", o_current->complex_basename);
#endif
	}
	free(temp_uref);

      }  /*  if (o_current->type == OBJ_COMPLEX)  */
      o_current = o_current->next;  
	
  }   /*  while o_current != NULL */
      
  return;
}


/*------------------------------------------------------------------
 * This fcn builds the master list of pin attributes.  It writes 
 * each attrib name into the master pin attrib list.
 * Algorithm:
 * 1.  Loop on o_current looking for OBJ_COMPLEX
 * 2.  When we find a complex, save the refdes.
 * 3.  Dive down to o_lower_current = o_current->complex->prim_objs
 * 4.  Loop on o_lower_current looking for OBJ_PIN
 * 5.  When we find a pin, get pin_attribs = o_lower_current->attribs
 * 6.  Loop on attribs looking for non-NULL text.
 * 7.  When we find a non-NULL text attrib, extract the attrib name
 *     and stick it in the master pin attrib list.
 *------------------------------------------------------------------*/
void s_sheet_data_add_master_pin_attrib_list_items(OBJECT *start_obj) {
  char *temp_uref;
  char *attrib_text;
  char *attrib_name;
  char *attrib_value;
  OBJECT *o_current;
  OBJECT *o_lower_current;
  ATTRIB *pin_attrib;
  
#ifdef DEBUG
  fflush(stderr);
  fflush(stdout);
  printf("=========== Just entered  s_sheet_data_add_master_pin_attrib_list_items!  ==============\n");
#endif

  if (verbose_mode) {
    printf("- Starting master pin attrib list creation.\n");
  }

  /* -----  Iterate through all objects found on page looking for components  ----- */
  o_current = start_obj;
  while (o_current != NULL) {

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

      if (o_current->type == OBJ_COMPLEX) {
	temp_uref = s_attrib_get_refdes(o_current);
	if (temp_uref != NULL) {      /* make sure object complex has a refdes  */
	  
	  /* -----  Now iterate through lower level objects looking for pins.  ----- */
	  o_lower_current = o_current->complex->prim_objs;
	  while (o_lower_current != NULL) {
#if DEBUG
	    printf("In s_sheet_data_add_master_pin_attrib_list_items, examining component refdes =  %s\n", temp_uref);
#endif
	    if (o_lower_current->type == OBJ_PIN) {
	      /* -----  Found a pin.  Now get attrib head and loop on attribs.  ----- */
	      pin_attrib = o_lower_current->attribs;
	      while (pin_attrib != NULL) {
		if (pin_attrib->object->type == OBJ_TEXT 
		    && pin_attrib->object->text != NULL) {  /* found an attribute */
		  attrib_text = g_strdup(pin_attrib->object->text->string);
		  attrib_name = u_basic_breakup_string(attrib_text, '=', 0);
		  attrib_value = u_basic_breakup_string(attrib_text, '=', 1);
		  if ( (strcmp(attrib_name, "pinnumber") != 0) 
		       && (attrib_value != NULL) ) {  
		    /* Don't include "pinnumber" because it is already in other master list.
		     * Also guard against pathalogical symbols which have non-attrib text inside pins. */

#if DEBUG
	    printf("In s_sheet_data_add_master_pin_attrib_list_items, found pin attrib =  %s\n", attrib_name);
	    printf(". . . . . adding it to master_pin_attrib_list\n");
#endif

		    s_string_list_add_item(sheet_head->master_pin_attrib_list_head, 
					   &(sheet_head->pin_attrib_count), attrib_name);
		  }   /* if (strcmp(attrib_name, "pinnumber") != 0) */ 
		  if (attrib_value != NULL) free(attrib_value);
		  free(attrib_name);
		  free(attrib_text);
		}
		pin_attrib = pin_attrib->next;
	      }   /*   while (pin_attrib != NULL)  */
	    }
	    o_lower_current = o_lower_current->next;
	  }   /*  while (o_lower_current != NULL)   */

	  free(temp_uref);
	}  /*  if (temp_uref != NULL )  */
	
      }  /* if (o_current->type == OBJ_COMPLEX)  */
      o_current = o_current->next;

  }  /*  while (o_current != NULL)  */
  return;

}




/*------------------------------------------------------------------
 * This fcn extracts the attribs from the gtksheet
 * cells, and places them back into SHEET_DATA.  This is the
 * first step in saving out a project.  Right now I just invoke
 * s_table_gtksheet_to_table.  Do I need to do anything else here?
 *------------------------------------------------------------------*/
void s_sheet_data_gtksheet_to_sheetdata() {
  s_table_gtksheet_to_all_tables();
  /* do I need to do anything else here? */

  return;
}