1*3b35e7eeSXin LI // SPDX-License-Identifier: 0BSD 2*3b35e7eeSXin LI 3e0f0e66dSMartin Matuska /////////////////////////////////////////////////////////////////////////////// 4e0f0e66dSMartin Matuska // 5a8675d92SXin LI /// \file tuklib_mbstr.h 6e0f0e66dSMartin Matuska /// \brief Utility functions for handling multibyte strings 7e0f0e66dSMartin Matuska /// 8e0f0e66dSMartin Matuska /// If not enough multibyte string support is available in the C library, 9e0f0e66dSMartin Matuska /// these functions keep working with the assumption that all strings 10e0f0e66dSMartin Matuska /// are in a single-byte character set without combining characters, e.g. 11e0f0e66dSMartin Matuska /// US-ASCII or ISO-8859-*. 12e0f0e66dSMartin Matuska // 13e0f0e66dSMartin Matuska // Author: Lasse Collin 14e0f0e66dSMartin Matuska // 15e0f0e66dSMartin Matuska /////////////////////////////////////////////////////////////////////////////// 16e0f0e66dSMartin Matuska 17e0f0e66dSMartin Matuska #ifndef TUKLIB_MBSTR_H 18e0f0e66dSMartin Matuska #define TUKLIB_MBSTR_H 19e0f0e66dSMartin Matuska 20e0f0e66dSMartin Matuska #include "tuklib_common.h" 21e0f0e66dSMartin Matuska TUKLIB_DECLS_BEGIN 22e0f0e66dSMartin Matuska 23e0f0e66dSMartin Matuska #define tuklib_mbstr_width TUKLIB_SYMBOL(tuklib_mbstr_width) 24e0f0e66dSMartin Matuska extern size_t tuklib_mbstr_width(const char *str, size_t *bytes); 25e0f0e66dSMartin Matuska ///< 26e0f0e66dSMartin Matuska /// \brief Get the number of columns needed for the multibyte string 27e0f0e66dSMartin Matuska /// 28e0f0e66dSMartin Matuska /// This is somewhat similar to wcswidth() but works on multibyte strings. 29e0f0e66dSMartin Matuska /// 30e0f0e66dSMartin Matuska /// \param str String whose width is to be calculated. If the 31e0f0e66dSMartin Matuska /// current locale uses a multibyte character set 32e0f0e66dSMartin Matuska /// that has shift states, the string must begin 33e0f0e66dSMartin Matuska /// and end in the initial shift state. 34e0f0e66dSMartin Matuska /// \param bytes If this is not NULL, *bytes is set to the 35e0f0e66dSMartin Matuska /// value returned by strlen(str) (even if an 36e0f0e66dSMartin Matuska /// error occurs when calculating the width). 37e0f0e66dSMartin Matuska /// 38e0f0e66dSMartin Matuska /// \return On success, the number of columns needed to display the 39e0f0e66dSMartin Matuska /// string e.g. in a terminal emulator is returned. On error, 40e0f0e66dSMartin Matuska /// (size_t)-1 is returned. Possible errors include invalid, 41e0f0e66dSMartin Matuska /// partial, or non-printable multibyte character in str, or 42e0f0e66dSMartin Matuska /// that str doesn't end in the initial shift state. 43e0f0e66dSMartin Matuska 44e0f0e66dSMartin Matuska #define tuklib_mbstr_fw TUKLIB_SYMBOL(tuklib_mbstr_fw) 45e0f0e66dSMartin Matuska extern int tuklib_mbstr_fw(const char *str, int columns_min); 46e0f0e66dSMartin Matuska ///< 47e0f0e66dSMartin Matuska /// \brief Get the field width for printf() e.g. to align table columns 48e0f0e66dSMartin Matuska /// 49e0f0e66dSMartin Matuska /// Printing simple tables to a terminal can be done using the field field 50e0f0e66dSMartin Matuska /// feature in the printf() format string, but it works only with single-byte 51e0f0e66dSMartin Matuska /// character sets. To do the same with multibyte strings, tuklib_mbstr_fw() 52e0f0e66dSMartin Matuska /// can be used to calculate appropriate field width. 53e0f0e66dSMartin Matuska /// 54e0f0e66dSMartin Matuska /// The behavior of this function is undefined, if 55e0f0e66dSMartin Matuska /// - str is NULL or not terminated with '\0'; 56e0f0e66dSMartin Matuska /// - columns_min <= 0; or 57e0f0e66dSMartin Matuska /// - the calculated field width exceeds INT_MAX. 58e0f0e66dSMartin Matuska /// 59e0f0e66dSMartin Matuska /// \return If tuklib_mbstr_width(str, NULL) fails, -1 is returned. 60e0f0e66dSMartin Matuska /// If str needs more columns than columns_min, zero is returned. 61e0f0e66dSMartin Matuska /// Otherwise a positive integer is returned, which can be 62e0f0e66dSMartin Matuska /// used as the field width, e.g. printf("%*s", fw, str). 63e0f0e66dSMartin Matuska 64e0f0e66dSMartin Matuska TUKLIB_DECLS_END 65e0f0e66dSMartin Matuska #endif 66