Added to the repository
Showing
4 changed files
with
364 additions
and
0 deletions
lib/mbswidth.c
0 → 100644
1 | /* Determine the number of screen columns needed for a string. | ||
2 | Copyright (C) 2000-2004 Free Software Foundation, Inc. | ||
3 | |||
4 | This program is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation; either version 2, or (at your option) | ||
7 | any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program; if not, write to the Free Software Foundation, | ||
16 | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | ||
17 | |||
18 | /* Written by Bruno Haible <haible@clisp.cons.org>. */ | ||
19 | |||
20 | #ifdef HAVE_CONFIG_H | ||
21 | # include <config.h> | ||
22 | #endif | ||
23 | |||
24 | /* Specification. */ | ||
25 | #include "mbswidth.h" | ||
26 | |||
27 | /* Get MB_CUR_MAX. */ | ||
28 | #include <stdlib.h> | ||
29 | |||
30 | #include <string.h> | ||
31 | |||
32 | /* Get isprint(). */ | ||
33 | #include <ctype.h> | ||
34 | |||
35 | /* Get mbstate_t, mbrtowc(), mbsinit(), wcwidth(). */ | ||
36 | #if HAVE_WCHAR_H | ||
37 | /* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before | ||
38 | <wchar.h>. | ||
39 | BSD/OS 4.1 has a bug: <stdio.h> and <time.h> must be included before | ||
40 | <wchar.h>. */ | ||
41 | # include <stdio.h> | ||
42 | # include <time.h> | ||
43 | # include <wchar.h> | ||
44 | #endif | ||
45 | |||
46 | /* Get iswprint(), iswcntrl(). */ | ||
47 | #if HAVE_WCTYPE_H | ||
48 | # include <wctype.h> | ||
49 | #endif | ||
50 | #if !defined iswprint && !HAVE_ISWPRINT | ||
51 | # define iswprint(wc) 1 | ||
52 | #endif | ||
53 | #if !defined iswcntrl && !HAVE_ISWCNTRL | ||
54 | # define iswcntrl(wc) 0 | ||
55 | #endif | ||
56 | |||
57 | #ifndef mbsinit | ||
58 | # if !HAVE_MBSINIT | ||
59 | # define mbsinit(ps) 1 | ||
60 | # endif | ||
61 | #endif | ||
62 | |||
63 | #ifndef HAVE_DECL_WCWIDTH | ||
64 | "this configure-time declaration test was not run" | ||
65 | #endif | ||
66 | #if !HAVE_DECL_WCWIDTH | ||
67 | int wcwidth (); | ||
68 | #endif | ||
69 | |||
70 | #ifndef wcwidth | ||
71 | # if !HAVE_WCWIDTH | ||
72 | /* wcwidth doesn't exist, so assume all printable characters have | ||
73 | width 1. */ | ||
74 | # define wcwidth(wc) ((wc) == 0 ? 0 : iswprint (wc) ? 1 : -1) | ||
75 | # endif | ||
76 | #endif | ||
77 | |||
78 | /* Get ISPRINT. */ | ||
79 | #if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII)) | ||
80 | # define IN_CTYPE_DOMAIN(c) 1 | ||
81 | #else | ||
82 | # define IN_CTYPE_DOMAIN(c) isascii(c) | ||
83 | #endif | ||
84 | /* Undefine to protect against the definition in wctype.h of Solaris 2.6. */ | ||
85 | #undef ISPRINT | ||
86 | #define ISPRINT(c) (IN_CTYPE_DOMAIN (c) && isprint (c)) | ||
87 | #undef ISCNTRL | ||
88 | #define ISCNTRL(c) (IN_CTYPE_DOMAIN (c) && iscntrl (c)) | ||
89 | |||
90 | /* Returns the number of columns needed to represent the multibyte | ||
91 | character string pointed to by STRING. If a non-printable character | ||
92 | occurs, and MBSW_REJECT_UNPRINTABLE is specified, -1 is returned. | ||
93 | With flags = MBSW_REJECT_INVALID | MBSW_REJECT_UNPRINTABLE, this is | ||
94 | the multibyte analogue of the wcswidth function. */ | ||
95 | int | ||
96 | mbswidth (const char *string, int flags) | ||
97 | { | ||
98 | return mbsnwidth (string, strlen (string), flags); | ||
99 | } | ||
100 | |||
101 | /* Returns the number of columns needed to represent the multibyte | ||
102 | character string pointed to by STRING of length NBYTES. If a | ||
103 | non-printable character occurs, and MBSW_REJECT_UNPRINTABLE is | ||
104 | specified, -1 is returned. */ | ||
105 | int | ||
106 | mbsnwidth (const char *string, size_t nbytes, int flags) | ||
107 | { | ||
108 | const char *p = string; | ||
109 | const char *plimit = p + nbytes; | ||
110 | int width; | ||
111 | |||
112 | width = 0; | ||
113 | #if HAVE_MBRTOWC | ||
114 | if (MB_CUR_MAX > 1) | ||
115 | { | ||
116 | while (p < plimit) | ||
117 | switch (*p) | ||
118 | { | ||
119 | case ' ': case '!': case '"': case '#': case '%': | ||
120 | case '&': case '\'': case '(': case ')': case '*': | ||
121 | case '+': case ',': case '-': case '.': case '/': | ||
122 | case '0': case '1': case '2': case '3': case '4': | ||
123 | case '5': case '6': case '7': case '8': case '9': | ||
124 | case ':': case ';': case '<': case '=': case '>': | ||
125 | case '?': | ||
126 | case 'A': case 'B': case 'C': case 'D': case 'E': | ||
127 | case 'F': case 'G': case 'H': case 'I': case 'J': | ||
128 | case 'K': case 'L': case 'M': case 'N': case 'O': | ||
129 | case 'P': case 'Q': case 'R': case 'S': case 'T': | ||
130 | case 'U': case 'V': case 'W': case 'X': case 'Y': | ||
131 | case 'Z': | ||
132 | case '[': case '\\': case ']': case '^': case '_': | ||
133 | case 'a': case 'b': case 'c': case 'd': case 'e': | ||
134 | case 'f': case 'g': case 'h': case 'i': case 'j': | ||
135 | case 'k': case 'l': case 'm': case 'n': case 'o': | ||
136 | case 'p': case 'q': case 'r': case 's': case 't': | ||
137 | case 'u': case 'v': case 'w': case 'x': case 'y': | ||
138 | case 'z': case '{': case '|': case '}': case '~': | ||
139 | /* These characters are printable ASCII characters. */ | ||
140 | p++; | ||
141 | width++; | ||
142 | break; | ||
143 | default: | ||
144 | /* If we have a multibyte sequence, scan it up to its end. */ | ||
145 | { | ||
146 | mbstate_t mbstate; | ||
147 | memset (&mbstate, 0, sizeof mbstate); | ||
148 | do | ||
149 | { | ||
150 | wchar_t wc; | ||
151 | size_t bytes; | ||
152 | int w; | ||
153 | |||
154 | bytes = mbrtowc (&wc, p, plimit - p, &mbstate); | ||
155 | |||
156 | if (bytes == (size_t) -1) | ||
157 | /* An invalid multibyte sequence was encountered. */ | ||
158 | { | ||
159 | if (!(flags & MBSW_REJECT_INVALID)) | ||
160 | { | ||
161 | p++; | ||
162 | width++; | ||
163 | break; | ||
164 | } | ||
165 | else | ||
166 | return -1; | ||
167 | } | ||
168 | |||
169 | if (bytes == (size_t) -2) | ||
170 | /* An incomplete multibyte character at the end. */ | ||
171 | { | ||
172 | if (!(flags & MBSW_REJECT_INVALID)) | ||
173 | { | ||
174 | p = plimit; | ||
175 | width++; | ||
176 | break; | ||
177 | } | ||
178 | else | ||
179 | return -1; | ||
180 | } | ||
181 | |||
182 | if (bytes == 0) | ||
183 | /* A null wide character was encountered. */ | ||
184 | bytes = 1; | ||
185 | |||
186 | w = wcwidth (wc); | ||
187 | if (w >= 0) | ||
188 | /* A printable multibyte character. */ | ||
189 | width += w; | ||
190 | else | ||
191 | /* An unprintable multibyte character. */ | ||
192 | if (!(flags & MBSW_REJECT_UNPRINTABLE)) | ||
193 | width += (iswcntrl (wc) ? 0 : 1); | ||
194 | else | ||
195 | return -1; | ||
196 | |||
197 | p += bytes; | ||
198 | } | ||
199 | while (! mbsinit (&mbstate)); | ||
200 | } | ||
201 | break; | ||
202 | } | ||
203 | return width; | ||
204 | } | ||
205 | #endif | ||
206 | |||
207 | while (p < plimit) | ||
208 | { | ||
209 | unsigned char c = (unsigned char) *p++; | ||
210 | |||
211 | if (ISPRINT (c)) | ||
212 | width++; | ||
213 | else if (!(flags & MBSW_REJECT_UNPRINTABLE)) | ||
214 | width += (ISCNTRL (c) ? 0 : 1); | ||
215 | else | ||
216 | return -1; | ||
217 | } | ||
218 | return width; | ||
219 | } |
lib/mbswidth.h
0 → 100644
1 | /* Determine the number of screen columns needed for a string. | ||
2 | Copyright (C) 2000-2004 Free Software Foundation, Inc. | ||
3 | |||
4 | This program is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation; either version 2, or (at your option) | ||
7 | any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program; if not, write to the Free Software Foundation, | ||
16 | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | ||
17 | |||
18 | #include <stddef.h> | ||
19 | |||
20 | /* Avoid a clash of our mbswidth() with a function of the same name defined | ||
21 | in UnixWare 7.1.1 <wchar.h>. We need this #include before the #define | ||
22 | below. | ||
23 | However, we don't want to #include <wchar.h> on all platforms because | ||
24 | - Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before | ||
25 | <wchar.h>. | ||
26 | - BSD/OS 4.1 has a bug: <stdio.h> and <time.h> must be included before | ||
27 | <wchar.h>. */ | ||
28 | #if HAVE_DECL_MBSWIDTH_IN_WCHAR_H | ||
29 | # include <wchar.h> | ||
30 | #endif | ||
31 | |||
32 | |||
33 | #ifdef __cplusplus | ||
34 | extern "C" { | ||
35 | #endif | ||
36 | |||
37 | |||
38 | /* Optional flags to influence mbswidth/mbsnwidth behavior. */ | ||
39 | |||
40 | /* If this bit is set, return -1 upon finding an invalid or incomplete | ||
41 | character. Otherwise, assume invalid characters have width 1. */ | ||
42 | #define MBSW_REJECT_INVALID 1 | ||
43 | |||
44 | /* If this bit is set, return -1 upon finding a non-printable character. | ||
45 | Otherwise, assume unprintable characters have width 0 if they are | ||
46 | control characters and 1 otherwise. */ | ||
47 | #define MBSW_REJECT_UNPRINTABLE 2 | ||
48 | |||
49 | |||
50 | /* Returns the number of screen columns needed for STRING. */ | ||
51 | #define mbswidth gnu_mbswidth /* avoid clash with UnixWare 7.1.1 function */ | ||
52 | extern int mbswidth (const char *string, int flags); | ||
53 | |||
54 | /* Returns the number of screen columns needed for the NBYTES bytes | ||
55 | starting at BUF. */ | ||
56 | extern int mbsnwidth (const char *buf, size_t nbytes, int flags); | ||
57 | |||
58 | |||
59 | #ifdef __cplusplus | ||
60 | } | ||
61 | #endif |
m4/mbrtowc.m4
0 → 100644
1 | # mbrtowc.m4 serial 7 | ||
2 | dnl Copyright (C) 2001-2002, 2004 Free Software Foundation, Inc. | ||
3 | dnl This file is free software; the Free Software Foundation | ||
4 | dnl gives unlimited permission to copy and/or distribute it, | ||
5 | dnl with or without modifications, as long as this notice is preserved. | ||
6 | |||
7 | dnl From Paul Eggert | ||
8 | |||
9 | dnl This file can be removed, and gl_FUNC_MBRTOWC replaced with | ||
10 | dnl AC_FUNC_MBRTOWC, when autoconf 2.57 can be assumed everywhere. | ||
11 | |||
12 | AC_DEFUN([gl_FUNC_MBRTOWC], | ||
13 | [ | ||
14 | AC_CACHE_CHECK([whether mbrtowc and mbstate_t are properly declared], | ||
15 | gl_cv_func_mbrtowc, | ||
16 | [AC_TRY_LINK( | ||
17 | [#include <wchar.h>], | ||
18 | [mbstate_t state; return ! (sizeof state && mbrtowc);], | ||
19 | gl_cv_func_mbrtowc=yes, | ||
20 | gl_cv_func_mbrtowc=no)]) | ||
21 | if test $gl_cv_func_mbrtowc = yes; then | ||
22 | AC_DEFINE(HAVE_MBRTOWC, 1, | ||
23 | [Define to 1 if mbrtowc and mbstate_t are properly declared.]) | ||
24 | fi | ||
25 | ]) |
m4/mbswidth.m4
0 → 100644
1 | # mbswidth.m4 serial 11 | ||
2 | dnl Copyright (C) 2000-2002, 2004 Free Software Foundation, Inc. | ||
3 | dnl This file is free software; the Free Software Foundation | ||
4 | dnl gives unlimited permission to copy and/or distribute it, | ||
5 | dnl with or without modifications, as long as this notice is preserved. | ||
6 | |||
7 | dnl autoconf tests required for use of mbswidth.c | ||
8 | dnl From Bruno Haible. | ||
9 | |||
10 | AC_DEFUN([gl_MBSWIDTH], | ||
11 | [ | ||
12 | AC_CHECK_HEADERS_ONCE(wchar.h wctype.h) | ||
13 | AC_CHECK_FUNCS_ONCE(isascii iswprint mbsinit) | ||
14 | AC_CHECK_FUNCS(iswcntrl wcwidth) | ||
15 | gl_FUNC_MBRTOWC | ||
16 | |||
17 | AC_CACHE_CHECK([whether wcwidth is declared], ac_cv_have_decl_wcwidth, | ||
18 | [AC_TRY_COMPILE([ | ||
19 | /* AIX 3.2.5 declares wcwidth in <string.h>. */ | ||
20 | #if HAVE_STRING_H | ||
21 | # include <string.h> | ||
22 | #endif | ||
23 | #if HAVE_WCHAR_H | ||
24 | # include <wchar.h> | ||
25 | #endif | ||
26 | ], [ | ||
27 | #ifndef wcwidth | ||
28 | char *p = (char *) wcwidth; | ||
29 | #endif | ||
30 | ], ac_cv_have_decl_wcwidth=yes, ac_cv_have_decl_wcwidth=no)]) | ||
31 | if test $ac_cv_have_decl_wcwidth = yes; then | ||
32 | ac_val=1 | ||
33 | else | ||
34 | ac_val=0 | ||
35 | fi | ||
36 | AC_DEFINE_UNQUOTED(HAVE_DECL_WCWIDTH, $ac_val, | ||
37 | [Define to 1 if you have the declaration of wcwidth(), and to 0 otherwise.]) | ||
38 | |||
39 | dnl UnixWare 7.1.1 <wchar.h> has a declaration of a function mbswidth() | ||
40 | dnl that clashes with ours. | ||
41 | AC_CACHE_CHECK([whether mbswidth is declared in <wchar.h>], | ||
42 | ac_cv_have_decl_mbswidth, | ||
43 | [AC_TRY_COMPILE([ | ||
44 | #if HAVE_WCHAR_H | ||
45 | # include <wchar.h> | ||
46 | #endif | ||
47 | ], [ | ||
48 | char *p = (char *) mbswidth; | ||
49 | ], ac_cv_have_decl_mbswidth=yes, ac_cv_have_decl_mbswidth=no)]) | ||
50 | if test $ac_cv_have_decl_mbswidth = yes; then | ||
51 | ac_val=1 | ||
52 | else | ||
53 | ac_val=0 | ||
54 | fi | ||
55 | AC_DEFINE_UNQUOTED(HAVE_DECL_MBSWIDTH_IN_WCHAR_H, $ac_val, | ||
56 | [Define to 1 if you have a declaration of mbswidth() in <wchar.h>, and to 0 otherwise.]) | ||
57 | |||
58 | AC_TYPE_MBSTATE_T | ||
59 | ]) |
-
Please register or sign in to post a comment