1 
2 #ifdef HAVE_CONFIG_H
3 #include "config.h"
4 #endif
5 
6 /* Rely on vasprintf (GNU extension) instead of vsnprintf if
7    possible... */
8 #define _GNU_SOURCE
9 #include <stdio.h>
10 
11 #include <xcb/xcb.h>
12 #include <stdlib.h>
13 #include <stdarg.h>
14 #include "xcb_atom.h"
15 
makename(const char * fmt,...)16 static char *makename(const char *fmt, ...)
17 {
18 	char *ret;
19 	int n;
20 	va_list ap;
21 
22 #ifndef HAVE_VASPRINTF
23 	char *np;
24 	int size = 64;
25 
26 	/* First allocate 'size' bytes, should be enough usually */
27 	if((ret = malloc(size)) == NULL)
28 		return NULL;
29 
30 	while(1)
31 	{
32 		va_start(ap, fmt);
33 		n = vsnprintf(ret, size, fmt, ap);
34 		va_end(ap);
35 
36 		if(n < 0)
37 			return NULL;
38 
39 		if(n < size)
40 			return ret;
41 
42 		size = n + 1;
43 		if((np = realloc(ret, size)) == NULL)
44 		{
45 			free(ret);
46 			return NULL;
47 		}
48 
49 		ret = np;
50 	}
51 #else
52 	va_start(ap, fmt);
53 	n = vasprintf(&ret, fmt, ap);
54 	va_end(ap);
55 
56 	if(n < 0)
57 		return NULL;
58 
59 	return ret;
60 #endif
61 }
62 
xcb_atom_name_by_screen(const char * base,uint8_t screen)63 char *xcb_atom_name_by_screen(const char *base, uint8_t screen)
64 {
65 	return makename("%s_S%u", base, screen);
66 }
67 
xcb_atom_name_by_resource(const char * base,uint32_t resource)68 char *xcb_atom_name_by_resource(const char *base, uint32_t resource)
69 {
70 	return makename("%s_R%08X", base, resource);
71 }
72 
xcb_atom_name_unique(const char * base,uint32_t id)73 char *xcb_atom_name_unique(const char *base, uint32_t id)
74 {
75 	if(base)
76 		return makename("%s_U%lu", base, id);
77 	else
78 		return makename("U%lu", id);
79 }
80