xref: /freebsd/contrib/xz/src/common/tuklib_mbstr.h (revision 3b35e7ee8de9b0260149a2b77e87a2b9c7a36244)
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