| /* Rely on vasprintf (GNU extension) instead of vsnprintf if |
| possible... */ |
| #ifdef HAVE_VASPRINTF |
| #define _GNU_SOURCE |
| #include <stdio.h> |
| #endif |
| |
| #include <xcb/xcb.h> |
| #include <stdlib.h> |
| #include <stdarg.h> |
| #include "xcb_atom.h" |
| |
| static char *makename(const char *fmt, ...) |
| { |
| char *ret; |
| int n; |
| va_list ap; |
| |
| #ifndef HAVE_VASPRINTF |
| char *np; |
| int size = 64; |
| |
| /* First allocate 'size' bytes, should be enough usually */ |
| if((ret = malloc(size)) == NULL) |
| return NULL; |
| |
| while(1) |
| { |
| va_start(ap, fmt); |
| n = vsnprintf(ret, size, fmt, ap); |
| va_end(ap); |
| |
| if(n < 0) |
| return NULL; |
| |
| if(n < size) |
| return ret; |
| |
| size = n + 1; |
| if((np = realloc(ret, size)) == NULL) |
| { |
| free(ret); |
| return NULL; |
| } |
| |
| ret = np; |
| } |
| #else |
| va_start(ap, fmt); |
| n = vasprintf(&ret, fmt, ap); |
| va_end(ap); |
| |
| if(n < 0) |
| return NULL; |
| |
| return ret; |
| #endif |
| } |
| |
| char *xcb_atom_name_by_screen(const char *base, uint8_t screen) |
| { |
| return makename("%s_S%u", base, screen); |
| } |
| |
| char *xcb_atom_name_by_resource(const char *base, uint32_t resource) |
| { |
| return makename("%s_R%08X", base, resource); |
| } |
| |
| char *xcb_atom_name_unique(const char *base, uint32_t id) |
| { |
| if(base) |
| return makename("%s_U%lu", base, id); |
| else |
| return makename("U%lu", id); |
| } |