glib-mini.c revision 1d1a2af599bfd91357cbc44b3cf20b1ab104f4ab
124018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne// Copyright 2014 The Android Open Source Project 224018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne// 324018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne// This software is licensed under the terms of the GNU General Public 424018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne// License version 2, as published by the Free Software Foundation, and 524018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne// may be copied, distributed, and modified under those terms. 624018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne// 724018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne// This program is distributed in the hope that it will be useful, 824018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne// but WITHOUT ANY WARRANTY; without even the implied warranty of 924018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1024018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne// GNU General Public License for more details. 1124018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne 1224018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne#include <glib.h> 1324018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne 1424018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne#include <limits.h> 1524018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne#include <stdarg.h> 1624018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne#include <stdio.h> 1724018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne#include <stdlib.h> 1824018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne#include <string.h> 1924018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne 2024018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne// Print a panic message then exit the program immediately. 2124018467ddb13857b764182f7753764d2f32f87dPeter Collingbournestatic __attribute__((noreturn)) void g_panic(const char* fmt, ...){ 22651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines va_list args; 2324018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne fprintf(stderr, "MiniGLib:PANIC: "); 24651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines va_start(args, fmt); 2524018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne vfprintf(stderr, fmt, args); 2624018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne va_end(args); 2724018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne exit(1); 2824018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne} 2924018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne 301ec5750908039701b206fc32dd2b95c45cd5cce8James Dennett 3124018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne// Heap allocation. 3224018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne 3324018467ddb13857b764182f7753764d2f32f87dPeter Collingbournevoid* g_malloc(size_t size) { 3424018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne if (size == 0) 3524018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne return NULL; 3624018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne 3724018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne void* ptr = malloc(size); 3824018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne if (ptr == NULL) 39ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie g_panic("Can't allocate %zu bytes!\n", size); 401ec5750908039701b206fc32dd2b95c45cd5cce8James Dennett 4124018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne return ptr; 42ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie} 431ec5750908039701b206fc32dd2b95c45cd5cce8James Dennett 4424018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne 45ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikievoid* g_malloc0(size_t size) { 461ec5750908039701b206fc32dd2b95c45cd5cce8James Dennett void* ptr = g_malloc(size); 471ec5750908039701b206fc32dd2b95c45cd5cce8James Dennett if (ptr == NULL) 481ec5750908039701b206fc32dd2b95c45cd5cce8James Dennett return NULL; 491ec5750908039701b206fc32dd2b95c45cd5cce8James Dennett 501ec5750908039701b206fc32dd2b95c45cd5cce8James Dennett memset(ptr, 0, size); 5124018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne return ptr; 5224018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne} 5324018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne 5424018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne 5524018467ddb13857b764182f7753764d2f32f87dPeter Collingbournevoid* g_realloc(void* ptr, size_t size) { 5624018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne if (size == 0) { 5724018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne g_free(ptr); 5824018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne return NULL; 5924018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne } 6024018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne void* new_ptr = realloc(ptr, size); 6124018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne if (new_ptr == NULL) 6224018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne g_panic("Can't reallocate pointer %p to %zu bytes!\n", ptr, size); 6324018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne 6424018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne return new_ptr; 6524018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne} 6624018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne 67ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 6824018467ddb13857b764182f7753764d2f32f87dPeter Collingbournevoid g_free(void* ptr) { 6924018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne if (ptr) 7024018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne free(ptr); 7124018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne} 7224018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne 73ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie// Strings. 7424018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne 7524018467ddb13857b764182f7753764d2f32f87dPeter Collingbournechar* g_strdup(const char* str) { 76ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie if (str == NULL) 7724018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne return NULL; 7824018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne 79ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie size_t len = strlen(str); 8024018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne char* copy = g_malloc(len + 1); 8124018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne memcpy(copy, str, len + 1); 8224018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne return copy; 8324018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne} 8424018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne 8524018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne 86ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikiechar* g_strndup(const char* str, size_t size) { 8724018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne const char *end = memchr(str, 0, size); 8824018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne char *copy; 8924018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne 9024018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne if (end) 91ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie size = end - str; 9224018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne 9324018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne copy = g_malloc(size + 1); 94ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie memcpy(copy, str, size); 9524018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne copy[size] = 0; 9624018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne return copy; 9724018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne} 9824018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne 9924018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne 10024018467ddb13857b764182f7753764d2f32f87dPeter Collingbournechar* g_strdup_printf(const char* fmt, ...) { 1011ec5750908039701b206fc32dd2b95c45cd5cce8James Dennett char* result; 10224018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne va_list args; 10324018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne va_start(args, fmt); 10424018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne g_vasprintf(&result, fmt, args); 10524018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne va_end(args); 10624018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne return result; 10724018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne} 108ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 10924018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne 11024018467ddb13857b764182f7753764d2f32f87dPeter Collingbournechar* g_strdup_vprintf(const char* fmt, va_list args) { 11124018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne char* result; 11224018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne g_vasprintf(&result, fmt, args); 11324018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne return result; 114ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie} 11524018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne 11624018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne 11724018467ddb13857b764182f7753764d2f32f87dPeter Collingbourneint g_vasprintf(char** str, const char* fmt, va_list args) { 11824018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne#ifdef _WIN32 11924018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne // On Win32, vsnprintf() is broken and always returns -1 in case of truncation, 120ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie // so make an educated guess, and try again if that fails with a larger pool. 12124018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne size_t capacity = 128; 12224018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne char* buffer = g_malloc(capacity); 123ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie for (;;) { 12424018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne va_list args2; 12524018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne va_copy(args2, args); 126ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie int len = vsnprintf(buffer, capacity, fmt, args2); 12724018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne if (len >= 0) { 12824018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne *str = buffer; 129ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie return len; 13024018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne } 13124018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne va_end(args2); 132ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 13324018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne capacity *= 2; 13424018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne if (capacity > INT_MAX) 13524018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne g_panic("Formatted string is too long!\n"); 13624018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne 13724018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne buffer = g_realloc(buffer, capacity); 13824018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne } 139ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie#else 14024018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne // On other systems, vsnprintf() works properly and returns the size of the 14124018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne // formatted string without truncation. 14224018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne va_list args2; 14324018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne va_copy(args2, args); 14424018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne int len = vsnprintf(NULL, 0, fmt, args2); 145ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie va_end(args2); 14624018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne if (len < 0) 14724018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne g_panic("Can't format string!\n"); 148ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 14924018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne char* result = g_malloc(len + 1); 15024018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne va_copy(args2, args); 151ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie vsnprintf(result, (size_t)len, fmt, args2); 15224018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne va_end(args2); 15324018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne 154c831d8b977a09bf2907d03128b48b5c914a2fafdRichard Smith *str = result; 155c831d8b977a09bf2907d03128b48b5c914a2fafdRichard Smith return len; 156ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie#endif 157c831d8b977a09bf2907d03128b48b5c914a2fafdRichard Smith} 15824018467ddb13857b764182f7753764d2f32f87dPeter Collingbourne