Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright  2012 Ran Benita <ran234 (at) gmail.com>
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a
      5  * copy of this software and associated documentation files (the "Software"),
      6  * to deal in the Software without restriction, including without limitation
      7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8  * and/or sell copies of the Software, and to permit persons to whom the
      9  * Software is furnished to do so, subject to the following conditions:
     10  *
     11  * The above copyright notice and this permission notice (including the next
     12  * paragraph) shall be included in all copies or substantial portions of the
     13  * Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     21  * DEALINGS IN THE SOFTWARE.
     22  */
     23 
     24 #ifndef UTILS_H
     25 #define UTILS_H 1
     26 
     27 #include <errno.h>
     28 #include <inttypes.h>
     29 #include <stdbool.h>
     30 #include <stdio.h>
     31 #include <string.h>
     32 #include <strings.h>
     33 
     34 #include "darray.h"
     35 
     36 /*
     37  * We sometimes malloc strings and then expose them as const char*'s. This
     38  * macro is used when we free these strings in order to avoid -Wcast-qual
     39  * errors.
     40  */
     41 #define UNCONSTIFY(const_ptr)  ((void *) (uintptr_t) (const_ptr))
     42 
     43 #define STATIC_ASSERT(expr, message) do { \
     44     switch (0) { case 0: case (expr): ; } \
     45 } while (0)
     46 
     47 static inline bool
     48 streq(const char *s1, const char *s2)
     49 {
     50     return strcmp(s1, s2) == 0;
     51 }
     52 
     53 static inline bool
     54 streq_not_null(const char *s1, const char *s2)
     55 {
     56     if (!s1 || !s2)
     57         return false;
     58     return streq(s1, s2);
     59 }
     60 
     61 static inline bool
     62 istreq(const char *s1, const char *s2)
     63 {
     64     return strcasecmp(s1, s2) == 0;
     65 }
     66 
     67 static inline bool
     68 istreq_prefix(const char *s1, const char *s2)
     69 {
     70     return strncasecmp(s1, s2, strlen(s1)) == 0;
     71 }
     72 
     73 static inline char *
     74 strdup_safe(const char *s)
     75 {
     76     return s ? strdup(s) : NULL;
     77 }
     78 
     79 static inline size_t
     80 strlen_safe(const char *s)
     81 {
     82     return s ? strlen(s) : 0;
     83 }
     84 
     85 static inline bool
     86 isempty(const char *s)
     87 {
     88     return s == NULL || s[0] == '\0';
     89 }
     90 
     91 static inline const char *
     92 strnull(const char *s)
     93 {
     94     return s ? s : "(null)";
     95 }
     96 
     97 static inline const char *
     98 strempty(const char *s)
     99 {
    100     return s ? s : "";
    101 }
    102 
    103 static inline void *
    104 memdup(const void *mem, size_t nmemb, size_t size)
    105 {
    106     void *p = calloc(nmemb, size);
    107     if (p)
    108         memcpy(p, mem, nmemb * size);
    109     return p;
    110 }
    111 
    112 static inline int
    113 min(int misc, int other)
    114 {
    115     return (misc < other) ? misc : other;
    116 }
    117 
    118 static inline int
    119 max(int misc, int other)
    120 {
    121     return (misc > other) ? misc : other;
    122 }
    123 
    124 /* ctype.h is locale-dependent and has other oddities. */
    125 static inline bool
    126 is_space(char ch)
    127 {
    128     return ch == ' ' || (ch >= '\t' && ch <= '\r');
    129 }
    130 
    131 static inline bool
    132 is_alpha(char ch)
    133 {
    134     return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z');
    135 }
    136 
    137 static inline bool
    138 is_digit(char ch)
    139 {
    140     return ch >= '0' && ch <= '9';
    141 }
    142 
    143 static inline bool
    144 is_alnum(char ch)
    145 {
    146     return is_alpha(ch) || is_digit(ch);
    147 }
    148 
    149 static inline bool
    150 is_xdigit(char ch)
    151 {
    152     return
    153         (ch >= '0' && ch <= '9') ||
    154         (ch >= 'a' && ch <= 'f') ||
    155         (ch >= 'A' && ch <= 'F');
    156 }
    157 
    158 static inline bool
    159 is_graph(char ch)
    160 {
    161     /* See table in ascii(7). */
    162     return ch >= '!' && ch <= '~';
    163 }
    164 
    165 /*
    166  * Return the bit position of the most significant bit.
    167  * Note: this is 1-based! It's more useful this way, and returns 0 when
    168  * mask is all 0s.
    169  */
    170 static inline unsigned
    171 msb_pos(uint32_t mask)
    172 {
    173     unsigned pos = 0;
    174     while (mask) {
    175         pos++;
    176         mask >>= 1u;
    177     }
    178     return pos;
    179 }
    180 
    181 bool
    182 map_file(FILE *file, const char **string_out, size_t *size_out);
    183 
    184 void
    185 unmap_file(const char *str, size_t size);
    186 
    187 #define ARRAY_SIZE(arr) ((sizeof(arr) / sizeof(*(arr))))
    188 
    189 #define MIN(a, b) ((a) < (b) ? (a) : (b))
    190 #define MIN3(a, b, c) MIN(MIN((a), (b)), (c))
    191 #define MAX(a, b) ((a) > (b) ? (a) : (b))
    192 #define MAX3(a, b, c) MAX(MAX((a), (b)), (c))
    193 
    194 /* Round up @a so it's divisible by @b. */
    195 #define ROUNDUP(a, b) (((a) + (b) - 1) / (b) * (b))
    196 
    197 #if defined(HAVE_SECURE_GETENV)
    198 # define secure_getenv secure_getenv
    199 #elif defined(HAVE___SECURE_GETENV)
    200 # define secure_getenv __secure_getenv
    201 #else
    202 # define secure_getenv getenv
    203 #endif
    204 
    205 #if defined(HAVE___BUILTIN_EXPECT)
    206 # define likely(x)   __builtin_expect(!!(x), 1)
    207 # define unlikely(x) __builtin_expect(!!(x), 0)
    208 #else
    209 # define likely(x)   (x)
    210 # define unlikely(x) (x)
    211 #endif
    212 
    213 /* Compiler Attributes */
    214 
    215 #if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__CYGWIN__)
    216 # define XKB_EXPORT      __attribute__((visibility("default")))
    217 #elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
    218 # define XKB_EXPORT      __global
    219 #else /* not gcc >= 4 and not Sun Studio >= 8 */
    220 # define XKB_EXPORT
    221 #endif
    222 
    223 #if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 203)
    224 # define ATTR_PRINTF(x,y) __attribute__((__format__(__printf__, x, y)))
    225 #else /* not gcc >= 2.3 */
    226 # define ATTR_PRINTF(x,y)
    227 #endif
    228 
    229 #if (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 205)) \
    230     || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
    231 # define ATTR_NORETURN __attribute__((__noreturn__))
    232 #else
    233 # define ATTR_NORETURN
    234 #endif /* GNUC  */
    235 
    236 #if (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 296)
    237 #define ATTR_MALLOC  __attribute__((__malloc__))
    238 #else
    239 #define ATTR_MALLOC
    240 #endif
    241 
    242 #if defined(__GNUC__) && (__GNUC__ >= 4)
    243 # define ATTR_NULL_SENTINEL __attribute__((__sentinel__))
    244 #else
    245 # define ATTR_NULL_SENTINEL
    246 #endif /* GNUC >= 4 */
    247 
    248 #if (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 295)
    249 #define ATTR_PACKED  __attribute__((__packed__))
    250 #else
    251 #define ATTR_PACKED
    252 #endif
    253 
    254 #endif /* UTILS_H */
    255