glib-mini.c revision aadb3b585bfe9f7ddd00d8c4276db4828665a81e
124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Copyright 2014 The Android Open Source Project 224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This software is licensed under the terms of the GNU General Public 424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// License version 2, as published by the Free Software Foundation, and 524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// may be copied, distributed, and modified under those terms. 624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This program is distributed in the hope that it will be useful, 824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// but WITHOUT ANY WARRANTY; without even the implied warranty of 924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10d891f9b872103235cfd2ed452c6f14a4394d9b3aDaniel Malea// GNU General Public License for more details. 11d891f9b872103235cfd2ed452c6f14a4394d9b3aDaniel Malea 1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <glib.h> 1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 1424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <limits.h> 1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <stdarg.h> 1624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <stdio.h> 17b1888f24fa181489840b9acf193e224d125d0776Greg Clayton#include <stdlib.h> 1824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <string.h> 1949ce8969d3154e1560106cfe530444c09410f217Greg Clayton 2036b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton// Print a panic message then exit the program immediately. 2124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid g_panic(const char* fmt, ...){ 2224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner va_list args; 2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner fprintf(stderr, "MiniGLib:PANIC: "); 24b1db658333cdebca31a128be95e926d80c3c7796Greg Clayton va_start(args, fmt); 253e8c25f62f92145b6fb699b379cbfe72b1245d4aGreg Clayton vfprintf(stderr, fmt, args); 2636b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton va_end(args); 27e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton exit(1); 2824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 2924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 3024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 3124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Heap allocation. 3224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 3324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid* g_malloc(size_t size) { 345a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham if (size == 0) 355a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham return NULL; 365a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham 375a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham void* ptr = malloc(size); 385a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham if (ptr == NULL) 395a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham g_panic("Can't allocate %zu bytes!\n", size); 4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return ptr; 4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 4324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 445a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham 4594a5d0de4433dce556db59758f3d6124eb0e1a2aJim Inghamvoid* g_malloc0(size_t size) { 4624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner void* ptr = g_malloc(size); 4724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (ptr == NULL) 48c833295baeec641086f536e78050388af36784f8Jim Ingham return NULL; 4924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 505a15e6927b5b3234fb3e688717297ba6b5dd6ad7Jim Ingham memset(ptr, 0, size); 5124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return ptr; 5224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 5324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 5424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 5524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid* g_realloc(void* ptr, size_t size) { 5624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (size == 0) { 5724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner g_free(ptr); 5824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return NULL; 5924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 6024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner void* new_ptr = realloc(ptr, size); 6124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (new_ptr == NULL) 6224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner g_panic("Can't reallocate pointer %p to %zu bytes!\n", ptr, size); 633e8c25f62f92145b6fb699b379cbfe72b1245d4aGreg Clayton 64ed0a0fbd021e44727469d6fa20cc337c58bd04c3Greg Clayton return new_ptr; 653e8c25f62f92145b6fb699b379cbfe72b1245d4aGreg Clayton} 663e8c25f62f92145b6fb699b379cbfe72b1245d4aGreg Clayton 673e8c25f62f92145b6fb699b379cbfe72b1245d4aGreg Clayton 683e8c25f62f92145b6fb699b379cbfe72b1245d4aGreg Claytonvoid g_free(void* ptr) { 693e8c25f62f92145b6fb699b379cbfe72b1245d4aGreg Clayton if (ptr) 703e8c25f62f92145b6fb699b379cbfe72b1245d4aGreg Clayton free(ptr); 713e8c25f62f92145b6fb699b379cbfe72b1245d4aGreg Clayton} 72b1db658333cdebca31a128be95e926d80c3c7796Greg Clayton 73b1db658333cdebca31a128be95e926d80c3c7796Greg Clayton// Strings. 74b1db658333cdebca31a128be95e926d80c3c7796Greg Clayton 75b1db658333cdebca31a128be95e926d80c3c7796Greg Claytonchar* g_strdup(const char* str) { 76b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton if (str == NULL) 77b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton return NULL; 78b1db658333cdebca31a128be95e926d80c3c7796Greg Clayton 79b1db658333cdebca31a128be95e926d80c3c7796Greg Clayton size_t len = strlen(str); 80b1db658333cdebca31a128be95e926d80c3c7796Greg Clayton char* copy = g_malloc(len + 1); 81b1db658333cdebca31a128be95e926d80c3c7796Greg Clayton memcpy(copy, str, len + 1); 82b1db658333cdebca31a128be95e926d80c3c7796Greg Clayton return copy; 83b1db658333cdebca31a128be95e926d80c3c7796Greg Clayton} 84b1db658333cdebca31a128be95e926d80c3c7796Greg Clayton 8536b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton 86b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Claytonchar* g_strndup(const char* str, size_t size) { 8736b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton const char *end = memchr(str, 0, size); 8836b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton char *copy; 8936b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton 9036b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton if (end) 9136b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton size = end - str; 9236b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton 9336b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton copy = g_malloc(size + 1); 9436b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton memcpy(copy, str, size); 957980d35608225dc71b3dd946d4c3aea85bc24e85Greg Clayton copy[size] = 0; 967980d35608225dc71b3dd946d4c3aea85bc24e85Greg Clayton return copy; 9736b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton} 9836b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton 9936b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton 10036b877d2d27f7d1890f2d13807a3addb216648e2Greg Claytonchar* g_strdup_printf(const char* fmt, ...) { 10136b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton char* result; 10236b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton va_list args; 10336b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton va_start(args, fmt); 10436b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton g_vasprintf(&result, fmt, args); 10536b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton va_end(args); 10636b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton return result; 10736b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton} 10836b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton 10997a19b21dacd9063bb5475812df7781777262198Greg Clayton 11036b877d2d27f7d1890f2d13807a3addb216648e2Greg Claytonchar* g_strdup_vprintf(const char* fmt, va_list args) { 11136b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton char* result; 11297a19b21dacd9063bb5475812df7781777262198Greg Clayton g_vasprintf(&result, fmt, args); 11336b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton return result; 11436b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton} 11536b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton 11636b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton 11736b877d2d27f7d1890f2d13807a3addb216648e2Greg Claytonint g_vasprintf(char** str, const char* fmt, va_list args) { 11836b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton#ifdef _WIN32 11936b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton // On Win32, vsnprintf() is broken and always returns -1 in case of truncation, 12036b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton // so make an educated guess, and try again if that fails with a larger pool. 12136b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton size_t capacity = 128; 12236b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton char* buffer = g_malloc(capacity); 12336b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton for (;;) { 12436b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton va_list args2; 12536b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton va_copy(args2, args); 12636b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton int len = vsnprintf(buffer, capacity, fmt, args2); 12736b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton if (len >= 0) { 12836b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton *str = buffer; 12936b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton return len; 13036b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton } 13136b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton va_end(args2); 13236b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton 133ee72ab615fc4f27591cc70756d0fea7a811d95a6Greg Clayton capacity *= 2; 134ee72ab615fc4f27591cc70756d0fea7a811d95a6Greg Clayton if (capacity > INT_MAX) 135ee72ab615fc4f27591cc70756d0fea7a811d95a6Greg Clayton g_panic("Formatted string is too long!\n"); 136ee72ab615fc4f27591cc70756d0fea7a811d95a6Greg Clayton 137ee72ab615fc4f27591cc70756d0fea7a811d95a6Greg Clayton buffer = g_realloc(buffer, capacity); 138ee72ab615fc4f27591cc70756d0fea7a811d95a6Greg Clayton } 139ee72ab615fc4f27591cc70756d0fea7a811d95a6Greg Clayton#else 140ee72ab615fc4f27591cc70756d0fea7a811d95a6Greg Clayton // On other systems, vsnprintf() works properly and returns the size of the 141ee72ab615fc4f27591cc70756d0fea7a811d95a6Greg Clayton // formatted string without truncation. 142ee72ab615fc4f27591cc70756d0fea7a811d95a6Greg Clayton va_list args2; 14336b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton va_copy(args2, args); 14436b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton int len = vsnprintf(NULL, 0, fmt, args2); 14536b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton va_end(args2); 14636b877d2d27f7d1890f2d13807a3addb216648e2Greg Clayton if (len < 0) 147b1db658333cdebca31a128be95e926d80c3c7796Greg Clayton g_panic("Can't format string!\n"); 1483e8c25f62f92145b6fb699b379cbfe72b1245d4aGreg Clayton 1493e8c25f62f92145b6fb699b379cbfe72b1245d4aGreg Clayton char* result = g_malloc(len + 1); 1503e8c25f62f92145b6fb699b379cbfe72b1245d4aGreg Clayton va_copy(args2, args); 1513e8c25f62f92145b6fb699b379cbfe72b1245d4aGreg Clayton vsnprintf(result, (size_t)len, fmt, args2); 1523e8c25f62f92145b6fb699b379cbfe72b1245d4aGreg Clayton va_end(args2); 153b1db658333cdebca31a128be95e926d80c3c7796Greg Clayton 154b1db658333cdebca31a128be95e926d80c3c7796Greg Clayton *str = result; 1553e8c25f62f92145b6fb699b379cbfe72b1245d4aGreg Clayton return len; 156b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton#endif 157b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton} 1583e8c25f62f92145b6fb699b379cbfe72b1245d4aGreg Clayton 1593e8c25f62f92145b6fb699b379cbfe72b1245d4aGreg Clayton 1603e8c25f62f92145b6fb699b379cbfe72b1245d4aGreg Clayton// Single-linked list 1613e8c25f62f92145b6fb699b379cbfe72b1245d4aGreg Clayton 1623e8c25f62f92145b6fb699b379cbfe72b1245d4aGreg Claytonstatic GSList* _g_slist_alloc(void) { 1633e8c25f62f92145b6fb699b379cbfe72b1245d4aGreg Clayton return (GSList*) g_malloc(sizeof(GSList)); 1643e8c25f62f92145b6fb699b379cbfe72b1245d4aGreg Clayton} 165b1db658333cdebca31a128be95e926d80c3c7796Greg Clayton 166b1db658333cdebca31a128be95e926d80c3c7796Greg Claytonvoid g_slist_free(GSList* list) { 167b1db658333cdebca31a128be95e926d80c3c7796Greg Clayton while (list) { 168b1db658333cdebca31a128be95e926d80c3c7796Greg Clayton GSList* next = list->next; 169aad2b0f2e5da0ecbf22ab7fead4c06671f64c6c5Greg Clayton g_free(list); 1703e8c25f62f92145b6fb699b379cbfe72b1245d4aGreg Clayton list = next; 171b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton } 1723e8c25f62f92145b6fb699b379cbfe72b1245d4aGreg Clayton} 1733e8c25f62f92145b6fb699b379cbfe72b1245d4aGreg Clayton 174b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg ClaytonGSList* g_slist_last(GSList* list) { 175b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton while (list && list->next) 176b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton list = list->next; 177b1db658333cdebca31a128be95e926d80c3c7796Greg Clayton return list; 1783e8c25f62f92145b6fb699b379cbfe72b1245d4aGreg Clayton} 179ed0a0fbd021e44727469d6fa20cc337c58bd04c3Greg Clayton 180b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg ClaytonGSList* g_slist_find(GSList* list, const void* data) { 1813e8c25f62f92145b6fb699b379cbfe72b1245d4aGreg Clayton while (list) { 1823e8c25f62f92145b6fb699b379cbfe72b1245d4aGreg Clayton if (list->data == data) 1833e8c25f62f92145b6fb699b379cbfe72b1245d4aGreg Clayton break; 1843e8c25f62f92145b6fb699b379cbfe72b1245d4aGreg Clayton list = list->next; 1853e8c25f62f92145b6fb699b379cbfe72b1245d4aGreg Clayton } 1863e8c25f62f92145b6fb699b379cbfe72b1245d4aGreg Clayton return list; 1873e8c25f62f92145b6fb699b379cbfe72b1245d4aGreg Clayton} 188ed0a0fbd021e44727469d6fa20cc337c58bd04c3Greg Clayton 189ed0a0fbd021e44727469d6fa20cc337c58bd04c3Greg ClaytonGSList* g_slist_append(GSList* list, void* data) { 190ed0a0fbd021e44727469d6fa20cc337c58bd04c3Greg Clayton GSList* new_list = _g_slist_alloc(); 191ed0a0fbd021e44727469d6fa20cc337c58bd04c3Greg Clayton new_list->data = data; 192ed0a0fbd021e44727469d6fa20cc337c58bd04c3Greg Clayton new_list->next = NULL; 193ed0a0fbd021e44727469d6fa20cc337c58bd04c3Greg Clayton 19424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (!list) 19524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return new_list; 196ed0a0fbd021e44727469d6fa20cc337c58bd04c3Greg Clayton 197ed0a0fbd021e44727469d6fa20cc337c58bd04c3Greg Clayton GSList* last = g_slist_last(list); 198b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton last->next = new_list; 1997508e732818c32e1cfeaaf7d1d507fe3834ce9d2Jim Ingham return list; 200b1888f24fa181489840b9acf193e224d125d0776Greg Clayton} 201b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton 202b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg ClaytonGSList* g_slist_prepend(GSList* list, void* data) { 203b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton GSList* new_list = _g_slist_alloc(); 204b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton new_list->data = data; 205b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton new_list->next = list; 206b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton return new_list; 207aad2b0f2e5da0ecbf22ab7fead4c06671f64c6c5Greg Clayton} 208b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton 209b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg ClaytonGSList* g_slist_remove(GSList* list, const void* data) { 210b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton GSList** pnode = &list; 211b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton for (;;) { 212b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton GSList* node = *pnode; 213b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton if (!node) 214b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton break; 2157508e732818c32e1cfeaaf7d1d507fe3834ce9d2Jim Ingham if (node->data == data) { 216b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton *pnode = node->next; 217b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton g_slist_free(node); 218b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton break; 2197f206ba4fb363f9ed3fc641d24a3e0477c6bdf36Greg Clayton } 2207f206ba4fb363f9ed3fc641d24a3e0477c6bdf36Greg Clayton pnode = &node->next; 2217f206ba4fb363f9ed3fc641d24a3e0477c6bdf36Greg Clayton } 2226f8d385ccfa5951709cd7efb28b20a255008ad3dJason Molenda return list; 2236f8d385ccfa5951709cd7efb28b20a255008ad3dJason Molenda} 2246f8d385ccfa5951709cd7efb28b20a255008ad3dJason Molenda 2254349bcb8ec51f3fd447b511b2ce8292a92d3c771Michael Sartainvoid g_slist_foreach(GSList* list, GFunc func, void* user_data) { 2264349bcb8ec51f3fd447b511b2ce8292a92d3c771Michael Sartain while (list) { 2274349bcb8ec51f3fd447b511b2ce8292a92d3c771Michael Sartain GSList* next = list->next; 2284349bcb8ec51f3fd447b511b2ce8292a92d3c771Michael Sartain (*func)(list->data, user_data); 2294349bcb8ec51f3fd447b511b2ce8292a92d3c771Michael Sartain list = next; 2304349bcb8ec51f3fd447b511b2ce8292a92d3c771Michael Sartain } 2314349bcb8ec51f3fd447b511b2ce8292a92d3c771Michael Sartain} 2324349bcb8ec51f3fd447b511b2ce8292a92d3c771Michael Sartain 2334349bcb8ec51f3fd447b511b2ce8292a92d3c771Michael Sartain// 2344349bcb8ec51f3fd447b511b2ce8292a92d3c771Michael Sartainstatic GSList* g_slist_sort_merge(GSList* l1, 2354349bcb8ec51f3fd447b511b2ce8292a92d3c771Michael Sartain GSList* l2, 2366f8d385ccfa5951709cd7efb28b20a255008ad3dJason Molenda GFunc compare_func, 2374349bcb8ec51f3fd447b511b2ce8292a92d3c771Michael Sartain void* user_data) { 238fb4677272d725374b7ff8f20e97f67ee98fca3ffGreg Clayton GSList* list = NULL; 239fb4677272d725374b7ff8f20e97f67ee98fca3ffGreg Clayton GSList** tail = &list; 240fb4677272d725374b7ff8f20e97f67ee98fca3ffGreg Clayton 241e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton while (l1 && l2) { 2427508e732818c32e1cfeaaf7d1d507fe3834ce9d2Jim Ingham int cmp = ((GCompareDataFunc) compare_func)(l1->data, l2->data, user_data); 243fb4677272d725374b7ff8f20e97f67ee98fca3ffGreg Clayton if (cmp <= 0) { 244fb4677272d725374b7ff8f20e97f67ee98fca3ffGreg Clayton *tail = l1; 245fb4677272d725374b7ff8f20e97f67ee98fca3ffGreg Clayton tail = &l1->next; 246ed0a0fbd021e44727469d6fa20cc337c58bd04c3Greg Clayton l1 = l1->next; 247ed0a0fbd021e44727469d6fa20cc337c58bd04c3Greg Clayton } else { 248ed0a0fbd021e44727469d6fa20cc337c58bd04c3Greg Clayton *tail = l2; 249ed0a0fbd021e44727469d6fa20cc337c58bd04c3Greg Clayton tail = &l2->next; 250ed0a0fbd021e44727469d6fa20cc337c58bd04c3Greg Clayton l2 = l2->next; 251ed0a0fbd021e44727469d6fa20cc337c58bd04c3Greg Clayton } 252ed0a0fbd021e44727469d6fa20cc337c58bd04c3Greg Clayton } 253ed0a0fbd021e44727469d6fa20cc337c58bd04c3Greg Clayton *tail = l1 ? l1 : l2; 254ed0a0fbd021e44727469d6fa20cc337c58bd04c3Greg Clayton 255ed0a0fbd021e44727469d6fa20cc337c58bd04c3Greg Clayton return list; 256ed0a0fbd021e44727469d6fa20cc337c58bd04c3Greg Clayton} 257ed0a0fbd021e44727469d6fa20cc337c58bd04c3Greg Clayton 258edd6ade11daf4995c5dac468ed6ae6f55dfaac87Greg Claytonstatic GSList* g_slist_sort_real(GSList* list, 259edd6ade11daf4995c5dac468ed6ae6f55dfaac87Greg Clayton GFunc compare_func, 260edd6ade11daf4995c5dac468ed6ae6f55dfaac87Greg Clayton void* user_data) { 261ed0a0fbd021e44727469d6fa20cc337c58bd04c3Greg Clayton 262ed0a0fbd021e44727469d6fa20cc337c58bd04c3Greg Clayton if (!list) 263ed0a0fbd021e44727469d6fa20cc337c58bd04c3Greg Clayton return NULL; 264ed0a0fbd021e44727469d6fa20cc337c58bd04c3Greg Clayton if (!list->next) 2657508e732818c32e1cfeaaf7d1d507fe3834ce9d2Jim Ingham return list; 266e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton 2679ce953807eb814a93b449dc243de4f7bf32c3115Greg Clayton // Split list into two halves. 2689ce953807eb814a93b449dc243de4f7bf32c3115Greg Clayton GSList* l1 = list; 269b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton GSList* l2 = list->next; 270b170aee2daacc83e3d71c3e3acc9d56c89893a7bGreg Clayton 2719ce953807eb814a93b449dc243de4f7bf32c3115Greg Clayton while (l2->next && l2->next->next) { 2729ce953807eb814a93b449dc243de4f7bf32c3115Greg Clayton l2 = l2->next->next; 2739ce953807eb814a93b449dc243de4f7bf32c3115Greg Clayton l1 = l1->next; 27424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 275e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton l2 = l1->next; 27624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner l1->next = NULL; 2777508e732818c32e1cfeaaf7d1d507fe3834ce9d2Jim Ingham 2787508e732818c32e1cfeaaf7d1d507fe3834ce9d2Jim Ingham return g_slist_sort_merge( 279fa2f48b09bfe19cc42309744a30c90d0d03a79c7Greg Clayton g_slist_sort_real(list, compare_func, user_data), 280fa2f48b09bfe19cc42309744a30c90d0d03a79c7Greg Clayton g_slist_sort_real(l2, compare_func, user_data), 28197a19b21dacd9063bb5475812df7781777262198Greg Clayton compare_func, 28297a19b21dacd9063bb5475812df7781777262198Greg Clayton user_data); 283940b103224f3062578c7a7e6e76d8bf4a7956f2aGreg Clayton} 284fa2f48b09bfe19cc42309744a30c90d0d03a79c7Greg Clayton 285fa2f48b09bfe19cc42309744a30c90d0d03a79c7Greg ClaytonGSList* g_slist_sort(GSList* list, GCompareFunc compare_func) { 286fa2f48b09bfe19cc42309744a30c90d0d03a79c7Greg Clayton return g_slist_sort_real(list, (GFunc) compare_func, NULL); 28797a19b21dacd9063bb5475812df7781777262198Greg Clayton} 28897a19b21dacd9063bb5475812df7781777262198Greg Clayton