gattrib

s_string_list.c

Go to the documentation of this file.
00001 /* gEDA - GPL Electronic Design Automation
00002  * gattrib -- gEDA component and net attribute manipulation using spreadsheet.
00003  * Copyright (C) 2003-2010 Stuart D. Brorson.
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00018  */
00019 
00020 /*------------------------------------------------------------------*/
00036 #include <config.h>
00037 
00038 #include <stdio.h>
00039 #ifdef HAVE_STRING_H
00040 #include <string.h>
00041 #endif
00042 #include <math.h>
00043 
00044 /*------------------------------------------------------------------
00045  * Gattrib specific includes
00046  *------------------------------------------------------------------*/
00047 #include <libgeda/libgeda.h>       /* geda library fcns  */
00048 #include "../include/struct.h"     /* typdef and struct declarations */
00049 #include "../include/prototype.h"  /* function prototypes */
00050 #include "../include/globals.h"
00051 
00052 #ifdef HAVE_LIBDMALLOC
00053 #include <dmalloc.h>
00054 #endif
00055 
00056 
00057 
00058 /*------------------------------------------------------------------*/
00064 STRING_LIST *s_string_list_new() {
00065   STRING_LIST *local_string_list;
00066   
00067   local_string_list = g_malloc(sizeof(STRING_LIST));
00068   local_string_list->data = NULL;
00069   local_string_list->next = NULL;
00070   local_string_list->prev = NULL;
00071   local_string_list->pos = -1;   /* can look for this later . . .  */
00072   
00073   return local_string_list;
00074 }
00075 
00076 
00077 /*------------------------------------------------------------------*/
00085 STRING_LIST *s_string_list_duplicate_string_list(STRING_LIST *old_string_list) {
00086   STRING_LIST *new_string_list;
00087   STRING_LIST *local_string_list;
00088   char *data;
00089   gint count;
00090 
00091   new_string_list = s_string_list_new();
00092 
00093   if (old_string_list->data == NULL) 
00094     /* This is an empty string list */
00095     return new_string_list;
00096 
00097   local_string_list = old_string_list;
00098   while (local_string_list != NULL) {
00099     data = g_strdup(local_string_list->data);
00100     s_string_list_add_item(new_string_list, &count, data);
00101     g_free(data);
00102     local_string_list = local_string_list->next;
00103   }
00104 
00105   return new_string_list;
00106 }
00107 
00108 
00109 /*------------------------------------------------------------------*/
00119 void s_string_list_add_item(STRING_LIST *list, int *count, char *item) {
00120 
00121   gchar *trial_item = NULL;
00122   STRING_LIST *prev;
00123   STRING_LIST *local_list;
00124   
00125   if (list == NULL) {
00126     fprintf(stderr, "In s_string_list_add_item, tried to add to a NULL list.\n");
00127     return;
00128   }
00129 
00130   /* First check to see if list is empty.  Handle insertion of first item 
00131      into empty list separately.  (Is this necessary?) */
00132   if (list->data == NULL) {
00133 #ifdef DEBUG
00134     printf("In s_string_list_add_item, about to place first item in list.\n");
00135 #endif
00136     list->data = (gchar *) g_strdup(item);
00137     list->next = NULL;
00138     list->prev = NULL;  /* this may have already been initialized. . . . */
00139     list->pos = *count; /* This enumerates the pos on the list.  Value is reset later by sorting. */
00140     (*count)++;  /* increment count to 1 */
00141     return;
00142   }
00143 
00144   /* Otherwise, loop through list looking for duplicates */
00145   prev = list;
00146   while (list != NULL) {
00147     trial_item = (gchar *) g_strdup(list->data);        
00148     if (strcmp(trial_item, item) == 0) {
00149       /* Found item already in list.  Just return. */
00150       g_free(trial_item);
00151       return;
00152     }
00153     g_free(trial_item);
00154     prev = list;
00155     list = list->next;
00156   }
00157 
00158   /* If we are here, it's 'cause we didn't find the item pre-existing in the list. */
00159   /* In this case, we insert it. */
00160 
00161   local_list = (STRING_LIST *) g_malloc(sizeof(STRING_LIST));  /* allocate space for this list entry */
00162   local_list->data = (gchar *) g_strdup(item);   /* copy data into list */
00163   local_list->next = NULL;
00164   local_list->prev = prev;  /* point this item to last entry in old list */
00165   prev->next = local_list;  /* make last item in old list point to this one. */
00166   local_list->pos = *count; /* This enumerates the pos on the list.  Value is reset later by sorting. */
00167   (*count)++;  /* increment count */
00168   /*   list = local_list;  */
00169   return;
00170 
00171 }
00172 
00173 
00174 /*------------------------------------------------------------------*/
00182 void s_string_list_delete_item(STRING_LIST **list, int *count, gchar *item) {
00183 
00184   gchar *trial_item = NULL;
00185   STRING_LIST *list_item;
00186   STRING_LIST *next_item = NULL;
00187   STRING_LIST *prev_item = NULL;
00188 
00189   /* First check to see if list is empty.  If empty, spew error and return */
00190   if ( (*list)->data == NULL) {
00191     fprintf(stderr, "In s_string_list_delete_item, tried to remove item from empty list\n");
00192     return;
00193   }
00194 
00195 #ifdef DEBUG
00196     printf("In s_string_list_delete_item, about to delete item %s from list.\n", item);
00197 #endif
00198 
00199   /* Now loop through list looking for item */
00200   list_item = (*list);
00201   while (list_item != NULL) {
00202     trial_item = (gchar *) g_strdup(list_item->data);        
00203 #ifdef DEBUG
00204     printf("In s_string_list_delete_item, matching item against trial item = %s from list.\n", trial_item);
00205 #endif
00206     if (strcmp(trial_item, item) == 0) {
00207       /* found item, now delete it. */
00208 #ifdef DEBUG
00209     printf("In s_string_list_delete_item, found match . . . . . \n");
00210 #endif
00211       prev_item = list_item->prev;
00212       next_item = list_item->next;
00213 
00214       /* Check position in list */
00215       if (next_item == NULL && prev_item == NULL) {
00216     /* pathological case of one item list. */
00217     (*list) = NULL;
00218       } else if (next_item == NULL && prev_item != NULL) {
00219     /* at list's end */
00220     prev_item->next = NULL;
00221       } else if (next_item != NULL && prev_item == NULL) {
00222     /* at list's beginning */
00223     next_item->prev = NULL;
00224     (*list) = next_item;         /* also need to fix pointer to list head */
00225     /*  g_free(list);  */
00226       } else {
00227     /* normal case of element in middle of list */
00228     prev_item->next = next_item;
00229     next_item->prev = prev_item;
00230       }
00231       
00232 #ifdef DEBUG
00233     printf("In s_string_list_delete_item, now free list_item\n");
00234 #endif
00235       g_free(list_item);  /* free current list item */
00236       (*count)--;       /* decrement count */
00237       /* Do we need to re-number the list? */
00238 
00239 #ifdef DEBUG
00240     printf("In s_string_list_delete_item, now free trial_item\n");
00241 #endif
00242       g_free(trial_item); /* free trial item before returning */
00243 #ifdef DEBUG
00244     printf("In s_string_list_delete_item, returning . . . .\n");
00245 #endif
00246       return;
00247     }
00248     g_free(trial_item);
00249     list_item = list_item->next;
00250   }
00251 
00252   /* If we are here, it's 'cause we didn't find the item.
00253    * Spew error and return.
00254    */
00255   fprintf(stderr, "In s_string_list_delete_item, couldn't delete item %s\n", item);
00256   return;
00257 
00258 }
00259 
00260 /*------------------------------------------------------------------*/
00269 int s_string_list_in_list(STRING_LIST *list, char *item) {
00270 
00271   gchar *trial_item = NULL;
00272   
00273   /* First check to see if list is empty.  If empty, return
00274    * 0 automatically.  (I probably don't need to handle this 
00275    * separately.)  */
00276   if (list->data == NULL) {
00277     return 0;
00278   }
00279 
00280   /* Otherwise, loop through list looking for duplicates */
00281   while (list != NULL) {
00282     trial_item = (gchar *) g_strdup(list->data);        
00283     if (strcmp(trial_item, item) == 0) {
00284       /* Found item already in list.  return 1. */
00285       g_free(trial_item);
00286       return 1;
00287     }
00288     g_free(trial_item);
00289     list = list->next;
00290   }
00291 
00292   /* If we are here, it's 'cause we didn't find the item 
00293    * pre-existing in the list.  In this case, return 0 */
00294   return 0;
00295 
00296 }
00297 
00298 
00299 /*------------------------------------------------------------------*/
00309 gint s_string_list_find_in_list(STRING_LIST *list, char *item) {
00310 
00311   gint index = 0;
00312   gchar *trial_item = NULL; 
00313   
00314   /* First check to see if list is empty.  If empty, return -1. */
00315   if (list->data == NULL) {
00316     return -1;
00317   }
00318 
00319   /* Otherwise, loop through list looking for the item */
00320   while (list != NULL) {
00321     trial_item = (gchar *) g_strdup(list->data);        
00322     if (strcmp(trial_item, item) == 0) {
00323       /* Found item in list; return index. */
00324       g_free(trial_item);
00325       return index;
00326     }
00327     g_free(trial_item);
00328     list = list->next;
00329     index++;
00330   }
00331 
00332   /* If we are here, it's 'cause we didn't find the item 
00333    * pre-existing in the list.  In this case, return -1 */
00334   return -1;
00335 
00336 }
00337 
00338 
00339 /*------------------------------------------------------------------*/
00348 gchar *s_string_list_get_data_at_index(STRING_LIST *list, gint index) 
00349 {
00350   gint i;
00351   STRING_LIST *local_item;
00352 
00353   /* First check to see if list is empty.  If empty, return
00354    * NULL automatically.  */
00355   if (list->data == NULL) {
00356     return NULL;
00357   }
00358 
00359   local_item = list;
00360   for (i = 0 ; i < index ; i++) {
00361     if (local_item == NULL) {
00362       return NULL;
00363     } else {
00364       local_item = local_item->next;
00365     }
00366   }
00367   return local_item->data;
00368 }
00369 
00370 
00371 /*------------------------------------------------------------------*/
00381 void s_string_list_sort_master_comp_list() {
00382   int i = 0;
00383   STRING_LIST *local_list, *p;
00384 
00385   /* Here's where we do the sort.  The sort is done using a fcn found on the web. */
00386   local_list = sheet_head->master_comp_list_head;
00387   for (p=local_list; p; p=p->next)
00388     p->pos = 0;
00389   local_list = listsort(local_list, 0, 1);
00390 
00391   /* Do this after sorting is done.  This resets the order of the individual items
00392    * in the list.  */
00393   while (local_list != NULL) {  /* make sure item is not null */
00394     local_list->pos = i;
00395     if (local_list->next != NULL) {  
00396       i++;
00397       local_list = local_list->next;
00398     } else {
00399       break;                    /* leave loop *before* iterating to NULL EOL marker */
00400     }
00401   }
00402 
00403   /* Now go to first item in local list and reassign list head to new first element */
00404   while (local_list->prev != NULL) {
00405     local_list = local_list->prev;
00406   }
00407 
00408   sheet_head->master_comp_list_head = local_list;
00409 
00410   return;
00411 }
00412 
00413 
00414 /* This list overrides the alphanumeric sort.  Attribs not found in
00415    this list are sorted as if they had a value of DEFAULT_ATTRIB_POS
00416    within this list, but alphanumerically relative to each other.  */
00417 static struct {
00418   const char *attrib;
00419   int pos;
00420 } certain_attribs[] = {
00421   {"device", 1},
00422   {"footprint", 2},
00423   {"value", 3},
00424   {"symversion", 200}
00425 };
00426 #define NUM_CERTAINS (sizeof(certain_attribs)/sizeof(certain_attribs[0]))
00427 #define DEFAULT_ATTRIB_POS 100
00428 
00429 /*------------------------------------------------------------------*/
00439 void s_string_list_sort_master_comp_attrib_list() {
00440   int i = 0;
00441   STRING_LIST *local_list, *p;
00442 
00443   /* Here's where we do the sort */
00444   local_list = sheet_head->master_comp_attrib_list_head;
00445 
00446   /*
00447    * Note that this sort is TBD -- it is more than just an alphabetic sort 'cause we want 
00448    * certain attribs to go first. 
00449    */
00450   for (p=local_list; p; p=p->next) {
00451     int i;
00452     p->pos = DEFAULT_ATTRIB_POS;
00453     for (i=0; i<NUM_CERTAINS; i++)
00454       if (p->data != NULL) {
00455         if (strcmp (certain_attribs[i].attrib, p->data) == 0)
00456     {
00457       p->pos = certain_attribs[i].pos;
00458       break;
00459     }
00460       }
00461   }
00462 
00463   local_list = listsort(local_list, 0, 1);
00464   sheet_head->master_comp_attrib_list_head = local_list;
00465 
00466   /* Do this after sorting is done.  This resets the order of the individual items
00467    * in the list.  */
00468   while (local_list != NULL) {
00469     local_list->pos = i;
00470     i++;
00471     local_list = local_list->next;
00472   }
00473 
00474   return;
00475 }
00476 
00477 /*------------------------------------------------------------------*/
00485 void s_string_list_sort_master_net_list() {
00486   int i = 0;
00487   STRING_LIST *local_list;
00488 
00489 
00490   /* Do this after sorting is done.  This resets the order of the individual items
00491    * in the list.  */
00492   local_list = sheet_head->master_net_list_head;
00493   while (local_list != NULL) {
00494     local_list->pos = i;
00495     i++;
00496     local_list = local_list->next;
00497   }
00498 
00499   return;
00500 }
00501 
00502 /*------------------------------------------------------------------*/
00511 /*------------------------------------------------------------------*/
00512 void s_string_list_sort_master_net_attrib_list() {
00513   int i = 0;
00514   STRING_LIST *local_list;
00515 
00516 
00517   /* Do this after sorting is done.  This resets the order of the individual items
00518    * in the list.  */
00519   local_list = sheet_head->master_net_attrib_list_head;
00520   while (local_list != NULL) {
00521     local_list->pos = i;
00522     i++;
00523     local_list = local_list->next;
00524   }
00525 
00526   return;
00527 }
00528 
00529 
00530 /*------------------------------------------------------------------*/
00540 /*------------------------------------------------------------------*/
00541 void s_string_list_sort_master_pin_list() {
00542   int i = 0;
00543   STRING_LIST *local_list, *p;
00544 
00545   /* Here's where we do the sort.  The sort is done using a fcn found on the web. */
00546   local_list = sheet_head->master_pin_list_head;
00547   for (p=local_list; p; p=p->next)
00548     p->pos = 0;
00549   local_list = listsort(local_list, 0, 1);
00550 
00551   /* Do this after sorting is done.  This resets the order of the individual items
00552    * in the list.  */
00553   while (local_list != NULL) {  /* make sure item is not null */
00554     local_list->pos = i;
00555     if (local_list->next != NULL) {  
00556       i++;
00557       local_list = local_list->next;
00558     } else {
00559       break;                    /* leave loop *before* iterating to NULL EOL marker */
00560     }
00561   }
00562 
00563   /* Now go to first item in local list and reassign list head to new first element */
00564   while (local_list->prev != NULL) {
00565     local_list = local_list->prev;
00566   }
00567 
00568   sheet_head->master_pin_list_head = local_list;
00569 
00570   return;
00571 }
00572 
00573 /*------------------------------------------------------------------*/
00583 /*------------------------------------------------------------------*/
00584 void s_string_list_sort_master_pin_attrib_list() {
00585   int i = 0;
00586   STRING_LIST *local_list;
00587 
00588   /* Here's where we do the sort */
00589 
00590   /*
00591    * Note that this sort is TBD -- it is more than just an alphabetic sort 'cause we want 
00592    * certain attribs to go first. 
00593    */
00594   
00595 
00596   /* Do this after sorting is done.  This resets the order of the individual items
00597    * in the list.  */
00598   local_list = sheet_head->master_pin_attrib_list_head;
00599   while (local_list != NULL) {
00600     local_list->pos = i;
00601     i++;
00602     local_list = local_list->next;
00603   }
00604 
00605   return;
00606 }
00607 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines