/** @file * IPRT - Simple character type classiciation and conversion. */ /* * Copyright (C) 2006-2024 Oracle and/or its affiliates. * * This file is part of VirtualBox base platform packages, as * available from https://www.virtualbox.org. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation, in version 3 of the * License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * * The contents of this file may alternatively be used under the terms * of the Common Development and Distribution License Version 1.0 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included * in the VirtualBox distribution, in which case the provisions of the * CDDL are applicable instead of those of the GPL. * * You may elect to license modified versions of this file under the * terms and conditions of either the GPL or the CDDL or both. * * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 */ #ifndef IPRT_INCLUDED_ctype_h #define IPRT_INCLUDED_ctype_h #ifndef RT_WITHOUT_PRAGMA_ONCE # pragma once #endif #include /** @name C locale predicates and conversions. * * For most practical purposes, this can safely be used when parsing UTF-8 * strings. Just keep in mind that we only deal with the first 127 chars and * that full correctness is only archived using the non-existing RTLocIs* API. * * @remarks Use the marcros, not the inlined functions. * * @remarks ASSUMES the source code includes the basic ASCII chars. This is a * general IPRT assumption. * @{ */ #define RT_C_IS_BLANK(ch) RTLocCIsBlank((ch)) #define RT_C_IS_ALNUM(ch) RTLocCIsAlNum((ch)) #define RT_C_IS_ALPHA(ch) RTLocCIsAlpha((ch)) #define RT_C_IS_CNTRL(ch) RTLocCIsCntrl((ch)) #define RT_C_IS_DIGIT(ch) RTLocCIsDigit((ch)) #define RT_C_IS_LOWER(ch) RTLocCIsLower((ch)) #define RT_C_IS_GRAPH(ch) RTLocCIsGraph((ch)) #define RT_C_IS_ODIGIT(ch) RTLocCIsODigit((ch)) #define RT_C_IS_PRINT(ch) RTLocCIsPrint((ch)) #define RT_C_IS_PUNCT(ch) RTLocCIsPunct((ch)) #define RT_C_IS_SPACE(ch) RTLocCIsSpace((ch)) #define RT_C_IS_UPPER(ch) RTLocCIsUpper((ch)) #define RT_C_IS_XDIGIT(ch) RTLocCIsXDigit((ch)) #define RT_C_TO_LOWER(ch) RTLocCToLower((ch)) #define RT_C_TO_UPPER(ch) RTLocCToUpper((ch)) /** * Checks for a blank character. * * @returns true / false. * @param ch The character to test. */ DECL_FORCE_INLINE(bool) RTLocCIsBlank(int ch) { return ch == 0x20 /* space */ || ch == 0x09; /* horizontal tab */ } /** * Checks for a control character. * * @returns true / false. * @param ch The character to test. * * @note Will return true of ch is '\0'! */ DECL_FORCE_INLINE(bool) RTLocCIsCntrl(int ch) { return (unsigned)ch < 32U /* 0..2f */ || ch == 0x7f; } /** * Checks for a decimal digit. * * @returns true / false. * @param ch The character to test. */ DECL_FORCE_INLINE(bool) RTLocCIsDigit(int ch) { return (unsigned)ch - 0x30 < 10U; /* 30..39 */ } /** * Checks for a lower case character. * * @returns true / false. * @param ch The character to test. */ DECL_FORCE_INLINE(bool) RTLocCIsLower(int ch) { return (unsigned)ch - 0x61U < 26U; /* 61..7a */ } /** * Checks for an octal digit. * * @returns true / false. * @param ch The character to test. */ DECL_FORCE_INLINE(bool) RTLocCIsODigit(int ch) { return (unsigned)ch - 0x30 < 8U; /* 30..37 */ } /** * Checks for a printable character (whitespace included). * * @returns true / false. * @param ch The character to test. */ DECL_FORCE_INLINE(bool) RTLocCIsPrint(int ch) { return (unsigned)ch - 0x20U < 95U; /* 20..7e */ } /** * Checks for punctuation (?). * * @returns true / false. * @param ch The character to test. */ DECL_FORCE_INLINE(bool) RTLocCIsPunct(int ch) { return (unsigned)ch - 0x21U < 15U /* 21..2f */ || (unsigned)ch - 0x3aU < 7U /* 3a..40 */ || (unsigned)ch - 0x5bU < 6U /* 5a..60 */ || (unsigned)ch - 0x7bU < 4U /* 7b..7e */; } /** * Checks for a white-space character. * * @returns true / false. * @param ch The character to test. */ DECL_FORCE_INLINE(bool) RTLocCIsSpace(int ch) { return ch == 0x20 /* 20 (space) */ || (unsigned)ch - 0x09U < 5U; /* 09..0d */ } /** * Checks for an upper case character. * * @returns true / false. * @param ch The character to test. */ DECL_FORCE_INLINE(bool) RTLocCIsUpper(int ch) { return (unsigned)ch - 0x41 < 26U; /* 41..5a */ } /** * Checks for a hexadecimal digit. * * @returns true / false. * @param ch The character to test. */ DECL_FORCE_INLINE(bool) RTLocCIsXDigit(int ch) { return (unsigned)ch - 0x30 < 10U /* 30..39 (0-9) */ || (unsigned)ch - 0x41 < 6 /* 41..46 (A-F) */ || (unsigned)ch - 0x61 < 6; /* 61..66 (a-f) */ } /** * Checks for an alphabetic character. * * @returns true / false. * @param ch The character to test. */ DECL_FORCE_INLINE(bool) RTLocCIsAlpha(int ch) { return RTLocCIsLower(ch) || RTLocCIsUpper(ch); } /** * Checks for an alphanumerical character. * * @returns true / false. * @param ch The character to test. */ DECL_FORCE_INLINE(bool) RTLocCIsAlNum(int ch) { return RTLocCIsDigit(ch) || RTLocCIsAlpha(ch); } /** * Checks for a printable character whitespace excluded. * * @returns true / false. * @param ch The character to test. */ DECL_FORCE_INLINE(bool) RTLocCIsGraph(int ch) { return RTLocCIsPrint(ch) && !RTLocCIsBlank(ch); } /** * Converts the character to lower case if applicable. * * @returns lower cased character or ch. * @param ch The character to test. */ DECL_FORCE_INLINE(int) RTLocCToLower(int ch) { return RTLocCIsUpper(ch) ? (ch) + 0x20 : (ch); } /** * Converts the character to upper case if applicable. * * @returns upper cased character or ch. * @param ch The character to test. */ DECL_FORCE_INLINE(int) RTLocCToUpper(int ch) { return RTLocCIsLower(ch) ? (ch) - 0x20 : (ch); } /** @} */ #endif /* !IPRT_INCLUDED_ctype_h */