#ifndef ULIB_STRING_CHAR_H_
#define ULIB_STRING_CHAR_H_

#define string_chr_islower(c) ((c) >= 'a' && (c) <= 'z')
#define string_chr_isupper(c) ((c) >= 'A' && (c) <= 'Z')
#define string_chr_isalpha(c) (string_chr_islower((c)) || string_chr_isupper((c)))
#define string_chr_isctl(c) (((c) >= 0 && (c) <= 0x1f) || (c) == 0x7f)
#define string_chr_isdigit(c) ((c) >= '0' && (c) <= '9')
#define string_chr_isalnum(c) (string_chr_isalpha((c)) || string_chr_isdigit((c)))
#define string_chr_isprint(c) ((c) > 0x1f && (c) < 0x7f)
#define string_chr_isspace(c) ((c) == ' ' || (c) == '\f' || (c) == '\t' || (c) == '\n' || (c) == '\r' || (c) == '\v')
#define string_chr_tolower(c) (string_chr_isupper((c)) ? ((c) - 'A' + 'a') : (c))
#define string_chr_toupper(c) (string_chr_islower((c)) ? ((c) - 'a' + 'A') : (c))
#define string_chr_isascii(c) (!((c) < 0 || (c) > 0x7f))
#define string_chr_isxdigit(c) (((c) >= '0' && (c) <= '9') || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F'))

#define STRING_CHECK_ALL(str, macro, okp) \
  do { \
    (okp) = true; \
    char *__p = (str); \
    while (*__p) { \
      if (!macro(*__p)) { \
        (okp) = false; \
        break; \
      } \
      __p++; \
    } \
  } while(0)

#endif // ULIB_STRING_CHAR_H_
