Jack2 1.9.6

jslist.h

00001 /*
00002    Based on gslist.c from glib-1.2.9 (LGPL).
00003 
00004    Adaption to JACK, Copyright (C) 2002 Kai Vehmanen.
00005      - replaced use of gtypes with normal ANSI C types
00006      - glib's memery allocation routines replaced with
00007        malloc/free calls
00008 
00009    This program is free software; you can redistribute it and/or modify
00010    it under the terms of the GNU Lesser General Public License as published by
00011    the Free Software Foundation; either version 2.1 of the License, or
00012    (at your option) any later version.
00013 
00014    This program is distributed in the hope that it will be useful,
00015    but WITHOUT ANY WARRANTY; without even the implied warranty of
00016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017    GNU Lesser General Public License for more details.
00018 
00019    You should have received a copy of the GNU Lesser General Public License
00020    along with this program; if not, write to the Free Software
00021    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00022 
00023    $Id: jslist.h,v 1.2 2005/11/23 11:24:29 letz Exp $
00024 */
00025 
00026 #ifndef __jack_jslist_h__
00027 #define __jack_jslist_h__
00028 
00029 #include <stdlib.h>
00030 
00031 typedef struct _JSList JSList;
00032 
00033 typedef int     (*JCompareFunc) (void*  a,
00034                              void*      b);
00035 struct _JSList
00036 {
00037     void *data;
00038     JSList *next;
00039 };
00040 
00041 static __inline__
00042 JSList*
00043 jack_slist_alloc (void)
00044 {
00045     JSList *new_list;
00046 
00047     new_list = (JSList*)malloc(sizeof(JSList));
00048     new_list->data = NULL;
00049     new_list->next = NULL;
00050 
00051     return new_list;
00052 }
00053 
00054 static __inline__
00055 JSList*
00056 jack_slist_prepend (JSList *list,
00057                     void *data)
00058 {
00059     JSList *new_list;
00060 
00061     new_list = (JSList*)malloc(sizeof(JSList));
00062     new_list->data = data;
00063     new_list->next = list;
00064 
00065     return new_list;
00066 }
00067 
00068 #define jack_slist_next(slist)  ((slist) ? (((JSList *)(slist))->next) : NULL)
00069 static __inline__
00070 JSList*
00071 jack_slist_last (JSList *list)
00072 {
00073     if (list) {
00074         while (list->next)
00075             list = list->next;
00076     }
00077 
00078     return list;
00079 }
00080 
00081 static __inline__
00082 JSList*
00083 jack_slist_remove_link (JSList *list,
00084                         JSList *link)
00085 {
00086     JSList *tmp;
00087     JSList *prev;
00088 
00089     prev = NULL;
00090     tmp = list;
00091 
00092     while (tmp) {
00093         if (tmp == link) {
00094             if (prev)
00095                 prev->next = tmp->next;
00096             if (list == tmp)
00097                 list = list->next;
00098 
00099             tmp->next = NULL;
00100             break;
00101         }
00102 
00103         prev = tmp;
00104         tmp = tmp->next;
00105     }
00106 
00107     return list;
00108 }
00109 
00110 static __inline__
00111 void
00112 jack_slist_free (JSList *list)
00113 {
00114     while (list) {
00115         JSList *next = list->next;
00116         free(list);
00117         list = next;
00118     }
00119 }
00120 
00121 static __inline__
00122 void
00123 jack_slist_free_1 (JSList *list)
00124 {
00125     if (list) {
00126         free(list);
00127     }
00128 }
00129 
00130 static __inline__
00131 JSList*
00132 jack_slist_remove (JSList *list,
00133                    void *data)
00134 {
00135     JSList *tmp;
00136     JSList *prev;
00137 
00138     prev = NULL;
00139     tmp = list;
00140 
00141     while (tmp) {
00142         if (tmp->data == data) {
00143             if (prev)
00144                 prev->next = tmp->next;
00145             if (list == tmp)
00146                 list = list->next;
00147 
00148             tmp->next = NULL;
00149             jack_slist_free (tmp);
00150 
00151             break;
00152         }
00153 
00154         prev = tmp;
00155         tmp = tmp->next;
00156     }
00157 
00158     return list;
00159 }
00160 
00161 static __inline__
00162 unsigned int
00163 jack_slist_length (JSList *list)
00164 {
00165     unsigned int length;
00166 
00167     length = 0;
00168     while (list) {
00169         length++;
00170         list = list->next;
00171     }
00172 
00173     return length;
00174 }
00175 
00176 static __inline__
00177 JSList*
00178 jack_slist_find (JSList *list,
00179                  void *data)
00180 {
00181     while (list) {
00182         if (list->data == data)
00183             break;
00184         list = list->next;
00185     }
00186 
00187     return list;
00188 }
00189 
00190 static __inline__
00191 JSList*
00192 jack_slist_copy (JSList *list)
00193 {
00194     JSList *new_list = NULL;
00195 
00196     if (list) {
00197         JSList *last;
00198 
00199         new_list = jack_slist_alloc ();
00200         new_list->data = list->data;
00201         last = new_list;
00202         list = list->next;
00203         while (list) {
00204             last->next = jack_slist_alloc ();
00205             last = last->next;
00206             last->data = list->data;
00207             list = list->next;
00208         }
00209     }
00210 
00211     return new_list;
00212 }
00213 
00214 static __inline__
00215 JSList*
00216 jack_slist_append (JSList *list,
00217                    void *data)
00218 {
00219     JSList *new_list;
00220     JSList *last;
00221 
00222     new_list = jack_slist_alloc ();
00223     new_list->data = data;
00224 
00225     if (list) {
00226         last = jack_slist_last (list);
00227         last->next = new_list;
00228 
00229         return list;
00230     } else
00231         return new_list;
00232 }
00233 
00234 static __inline__
00235 JSList*
00236 jack_slist_sort_merge (JSList *l1,
00237                        JSList *l2,
00238                        JCompareFunc compare_func)
00239 {
00240     JSList list, *l;
00241 
00242     l = &list;
00243 
00244     while (l1 && l2) {
00245         if (compare_func(l1->data, l2->data) < 0) {
00246             l = l->next = l1;
00247             l1 = l1->next;
00248         } else {
00249             l = l->next = l2;
00250             l2 = l2->next;
00251         }
00252     }
00253     l->next = l1 ? l1 : l2;
00254 
00255     return list.next;
00256 }
00257 
00258 static __inline__
00259 JSList*
00260 jack_slist_sort (JSList *list,
00261                  JCompareFunc compare_func)
00262 {
00263     JSList *l1, *l2;
00264 
00265     if (!list)
00266         return NULL;
00267     if (!list->next)
00268         return list;
00269 
00270     l1 = list;
00271     l2 = list->next;
00272 
00273     while ((l2 = l2->next) != NULL) {
00274         if ((l2 = l2->next) == NULL)
00275             break;
00276         l1 = l1->next;
00277     }
00278     l2 = l1->next;
00279     l1->next = NULL;
00280 
00281     return jack_slist_sort_merge (jack_slist_sort (list, compare_func),
00282                                   jack_slist_sort (l2, compare_func),
00283                                   compare_func);
00284 }
00285 
00286 #endif /* __jack_jslist_h__ */