2 * util.c - useful functions header
4 * Copyright © 2007 Julien Danjou <julien@danjou.info>
5 * Copyright © 2006 Pierre Habouzit <madcoder@debian.org>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
30 /** \brief replace \c NULL strings with emtpy strings */
31 #define NONULL(x) (x ? x : "")
35 #define MAX(a,b) ((a) < (b) ? (b) : (a))
36 #define MIN(a,b) ((a) < (b) ? (a) : (b))
38 #define ssizeof(foo) (ssize_t)sizeof(foo)
39 #define countof(foo) (ssizeof(foo) / ssizeof(foo[0]))
41 #define p_new(type, count) ((type *)xmalloc(sizeof(type) * (count)))
42 #define p_clear(p, count) ((void)memset((p), 0, sizeof(*(p)) * (count)))
43 #define p_realloc(pp, count) xrealloc((void*)(pp), sizeof(**(pp)) * (count))
44 #define p_dup(p, count) xmemdup((p), sizeof(*(p)) * (count))
48 #define p_delete(mem_pp) \
50 typeof(**(mem_pp)) **__ptr = (mem_pp); \
57 #define p_delete(mem_p) \
59 void *__ptr = (mem_p); \
61 *(void **)__ptr = NULL; \
66 static inline void * __attribute__ ((malloc
)) xmalloc(ssize_t size
)
73 ptr
= calloc(1, size
);
82 xrealloc(void **ptr
, ssize_t newsize
)
88 *ptr
= realloc(*ptr
, newsize
);
94 static inline void *xmemdup(const void *src
, ssize_t size
)
96 return memcpy(xmalloc(size
), src
, size
);
99 /** \brief \c NULL resistant strlen.
101 * Unlinke it's libc sibling, a_strlen returns a ssize_t, and supports its
102 * argument beeing NULL.
104 * \param[in] s the string.
105 * \return the string length (or 0 if \c s is \c NULL).
107 static inline ssize_t
a_strlen(const char *s
)
109 return s
? strlen(s
) : 0;
112 /** \brief \c NULL resistant strnlen.
114 * Unlinke it's GNU libc sibling, a_strnlen returns a ssize_t, and supports
115 * its argument beeing NULL.
117 * The a_strnlen() function returns the number of characters in the string
118 * pointed to by \c s, not including the terminating \c \\0 character, but at
119 * most \c n. In doing this, a_strnlen() looks only at the first \c n
120 * characters at \c s and never beyond \c s+n.
122 * \param[in] s the string.
123 * \param[in] n the maximum length to return.
124 * \return \c a_strlen(s) if less than \c n, else \c n.
126 static inline ssize_t
a_strnlen(const char *s
, ssize_t n
)
130 const char *p
= memchr(s
, '\0', n
);
131 return p
? p
- s
: n
;
136 /** \brief \c NULL resistant strdup.
138 * the a_strdup() function returns a pointer to a new string, which is a
139 * duplicate of \c s. Memory should be freed using p_delete().
141 * \warning when s is \c "", it returns NULL !
143 * \param[in] s the string to duplicate.
144 * \return a pointer to the duplicated string.
146 static inline char *a_strdup(const char *s
)
148 ssize_t len
= a_strlen(s
);
149 return len
? p_dup(s
, len
+ 1) : NULL
;
152 /** \brief \c NULL resistant strcmp.
153 * \param[in] a the first string.
154 * \param[in] b the second string.
155 * \return <tt>strcmp(a, b)</tt>, and treats \c NULL strings like \c ""
158 static inline int a_strcmp(const char *a
, const char *b
)
160 return strcmp(NONULL(a
), NONULL(b
));
163 /** \brief \c NULL resistant strncmp.
164 * \param[in] a the first string.
165 * \param[in] b the second string.
166 * \param[in] n the number of maximum chars to compare.
167 * \return <tt>strncmp(a, b, n)</tt>, and treats \c NULL strings like \c ""
170 static inline int a_strncmp(const char *a
, const char *b
, ssize_t n
)
172 return strncmp(NONULL(a
), NONULL(b
), n
);
175 ssize_t
a_strncpy(char *dst
, ssize_t n
, const char *src
, ssize_t l
) __attribute__((nonnull(1)));
176 ssize_t
a_strcpy(char *dst
, ssize_t n
, const char *src
) __attribute__((nonnull(1)));
178 /** \brief safe strcat.
180 * The a_strcat() function appends the string \c src at the end of the buffer
181 * \c dst if space is available.
183 * \param[in] dst destination buffer.
184 * \param[in] n size of the buffer, Negative sizes are allowed.
185 * \param[in] src the string to append.
186 * \return <tt>a_strlen(dst) + a_strlen(src)</tt>
188 static inline ssize_t
a_strcat(char *dst
, ssize_t n
, const char *src
)
190 ssize_t dlen
= a_strnlen(dst
, n
- 1);
191 return dlen
+ a_strcpy(dst
+ dlen
, n
- dlen
, src
);
194 void die(const char *, ...) __attribute__ ((noreturn
)) __attribute__ ((format(printf
, 1, 2)));
195 void eprint(const char *, ...) __attribute__ ((noreturn
)) __attribute__ ((format(printf
, 1, 2)));
196 Bool
xgettextprop(Display
*, Window
, Atom
, char *, ssize_t
);
197 double compute_new_value_from_arg(const char *, double);
199 UICB_PROTO(uicb_spawn
);