Guest User

Untitled

a guest
Aug 24th, 2010
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.49 KB | None | 0 0
  1. #ifndef __GENLIST__H
  2. #define __GENLIST__H
  3.  
  4. /** nodo della lista generica
  5.  
  6. Notare che sia la chiave (\b key) che l'informazione (\b payload) sono dei puntatori generici
  7.  
  8. */
  9.  
  10. typedef struct elem {
  11.   /** chiave */
  12.     void *key;
  13.   /** informazione */
  14.     void *payload;
  15.   /** puntatore elemento successivo */
  16.     struct elem *next;
  17. } elem_t;
  18.  
  19.  
  20. /**
  21.    Lista generica
  22.  
  23.    compare -- permette di confrontare due chiavi, ritorna 0 se sono uguali ed un valore diverso da 0 altrimenti
  24.    copyk,copyp -- creano una copia di una chiave o un payload (allocando la memoria necessaria) e ritornano il puntatore alla copia (se tutto e' andato bene) o NULL (se si e' verificato un errore)
  25.  */
  26. typedef struct {
  27.   /** la testa della lista */
  28.     elem_t *head;
  29.   /** la funzione per confrontare due chiavi */
  30.     int (*compare) (void *, void *);
  31.   /** la funzione per copiare una chiave */
  32.     void *(*copyk) (void *);
  33.   /** la funzione per copiare un payload*/
  34.     void *(*copyp) (void *);
  35. } list_t;
  36.  
  37. /** FUNZIONI DA IMPLEMENTARE */
  38.  
  39. /** crea una lista generica
  40.     \param compare funzione usata per confrontare due chiavi
  41.     \param copyk funzione usata per copiare una chiave
  42.     \param copyp funzione usata per copiare un payload
  43.  
  44.     \retval NULL in caso di errori con \c errno impostata opportunamente
  45.     \retval p (p!=NULL) puntatore alla nuova lista
  46. */
  47. list_t *new_List(int (*compare) (void *, void *), void *(*copyk) (void *),
  48.          void *(*copyp) (void *))
  49. {
  50.  
  51.     list_t *t;
  52.     t = (list_t *) malloc(sizeof(list_t));
  53.     if (t == NULL)
  54.     return NULL;
  55.  
  56.     t->head = NULL;
  57.     t->compare = compare;
  58.     t->copyk = copyk;
  59.     t->copyp = copyp;
  60.  
  61.     return t;
  62.  
  63. }
  64.  
  65. /** distrugge una lista deallocando tutta la memoria occupata
  66.     \param pt puntatore al puntatore della lista da distruggere
  67.  
  68.     nota: mette a NULL il puntatore \c *t
  69.  */
  70. void free_List(list_t ** pt)
  71. {
  72.  
  73.     if (pt == NULL || *pt == NULL)
  74.     return;
  75.     elem_t *curr = (*pt)->head;
  76.  
  77.     while (curr != NULL) {
  78.     elem_t *temp = curr;
  79.     free(curr->key);
  80.     free(curr->payload);
  81.     free(temp);
  82.     curr = curr->next;
  83.  
  84.     }
  85.     free(*pt);
  86.     *pt = NULL;
  87.  
  88. }
  89.  
  90. /** cerca l'elemento di chiave (key)
  91.  
  92.     \param t puntatore alla lista
  93.     \param key la chiave
  94.  
  95.  
  96.     \retval NULL se l'elemento non c'e'
  97.     \retval p puntatore all'elemento trovato (puntatore interno alla lista non alloca memoria)
  98.  
  99.  */
  100. elem_t *find_ListElement(list_t * t, void *key)
  101. {
  102.  
  103.     elem_t *current = t->head;
  104.  
  105.     while (current != NULL) {
  106.     if (t->compare(current->key, key) == 0)
  107.         return current;
  108.     current = current->next;
  109.     }
  110.  
  111.     return NULL;
  112.  
  113. }
  114.  
  115. /** inserisce una nuova coppia (key, payload) in testa alla lista,
  116.     sia key che payload devono essere copiate nel nuovo elemento della lista.
  117.     Nella lista \b non sono permesse chiavi replicate
  118.  
  119.     \param t puntatore alla lista
  120.     \param key la chiave
  121.     \param payload l'informazione
  122.  
  123.     \retval -1 se si sono verificati errori (errno settato opportunamente)
  124.     \retval 0 se l'inserimento \`e andato a buon fine
  125.  
  126.  */
  127. int add_ListElement(list_t * t, void *key, void *payload)
  128. {
  129.  
  130.     if (find_ListElement(t, key) != NULL)
  131.     return -1;
  132.  
  133.     elem_t *new_nodo = malloc(sizeof(elem_t));
  134.     if (new_nodo == NULL)
  135.     return -1;
  136.  
  137.     new_nodo->key = t->copyk(key);
  138.     new_nodo->payload = t->copyp(payload);
  139.     new_nodo->next = NULL;
  140.  
  141.     new_nodo->next = t->head;
  142.     t->head = new_nodo;
  143.  
  144.     return 0;
  145.  
  146. }
  147.  
  148. /** elimina l'elemento di chiave (key) deallocando la memoria
  149.  
  150.     \param t puntatore alla lista
  151.     \param key la chiave
  152.  
  153.  
  154.     \retval -1 se si sono verificati errori (errno settato opportunamente)
  155.     \retval 0 se l'esecuzione e' stata corretta
  156.  
  157.  */
  158. int remove_ListElement(list_t * t, void *key)
  159. {
  160.  
  161.     elem_t *key_element_prec;
  162.     elem_t *key_element;
  163.  
  164.     key_element_prec = key_element = t->head;
  165.  
  166. /*primo elemento*/
  167.  
  168.     if (t->compare(t->head->key, key) == 0) {
  169.  
  170.     t->head = t->head->next;
  171.  
  172.     /*dealloco memoria */
  173.     free(key_element->key);
  174.     free(key_element->payload);
  175.     free(key_element);
  176.     key_element = NULL;
  177.  
  178.     return 0;
  179.  
  180.     }
  181.  
  182. /*altri elementi*/
  183.  
  184.     while (key_element != NULL) {
  185.  
  186.     key_element = key_element->next;
  187.  
  188.     if (t->compare(key_element->key, key) == 0) {
  189.         key_element_prec->next = key_element->next;
  190.  
  191.         free(key_element->key);
  192.         free(key_element->payload);
  193.         free(key_element);
  194.         key_element = NULL;
  195.  
  196.         return 0;
  197.     }
  198.  
  199.     key_element_prec = key_element;
  200.  
  201.     }
  202.  
  203.     return -1;
  204.  
  205. }
  206.  
  207. #endif
Advertisement
Add Comment
Please, Sign In to add comment