]>
git.saurik.com Git - bison.git/blob - lib/mbswidth.c
   1 /* Determine the number of screen columns needed for a string. 
   2    Copyright (C) 2000-2001 Free Software Foundation, Inc. 
   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) 
   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. 
  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.  */ 
  18 /* Written by Bruno Haible <haible@clisp.cons.org>.  */ 
  35 /* Get mbstate_t, mbrtowc(), mbsinit(), wcwidth().  */ 
  40 /* Get iswprint(), iswcntrl().  */ 
  44 #if !defined iswprint && !HAVE_ISWPRINT 
  45 # define iswprint(wc) 1 
  47 #if !defined iswcntrl && !HAVE_ISWCNTRL 
  48 # define iswcntrl(wc) 0 
  53 #  define mbsinit(ps) 1 
  57 #ifndef HAVE_DECL_WCWIDTH 
  58 "this configure-time declaration test was not run" 
  60 #if !HAVE_DECL_WCWIDTH 
  66 /* wcwidth doesn't exist, so assume all printable characters have 
  68 #  define wcwidth(wc) ((wc) == 0 ? 0 : iswprint (wc) ? 1 : -1) 
  73 #if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII)) 
  74 # define IN_CTYPE_DOMAIN(c) 1 
  76 # define IN_CTYPE_DOMAIN(c) isascii(c) 
  78 /* Undefine to protect against the definition in wctype.h of solaris2.6.   */ 
  80 #define ISPRINT(c) (IN_CTYPE_DOMAIN (c) && isprint (c)) 
  82 #define ISCNTRL(c) (IN_CTYPE_DOMAIN (c) && iscntrl (c)) 
  84 /* Returns the number of columns needed to represent the multibyte 
  85    character string pointed to by STRING.  If a non-printable character 
  86    occurs, and MBSW_REJECT_UNPRINTABLE is specified, -1 is returned. 
  87    With flags = MBSW_REJECT_INVALID | MBSW_REJECT_UNPRINTABLE, this is 
  88    the multibyte analogon of the wcswidth function.  */ 
  90 mbswidth (string
, flags
) 
  94   return mbsnwidth (string
, strlen (string
), flags
); 
  97 /* Returns the number of columns needed to represent the multibyte 
  98    character string pointed to by STRING of length NBYTES.  If a 
  99    non-printable character occurs, and MBSW_REJECT_UNPRINTABLE is 
 100    specified, -1 is returned.  */ 
 102 mbsnwidth (string
, nbytes
, flags
) 
 107   const char *p 
= string
; 
 108   const char *plimit 
= p 
+ nbytes
; 
 118             case ' ': case '!': case '"': case '#': case '%': 
 119             case '&': case '\'': case '(': case ')': case '*': 
 120             case '+': case ',': case '-': case '.': case '/': 
 121             case '0': case '1': case '2': case '3': case '4': 
 122             case '5': case '6': case '7': case '8': case '9': 
 123             case ':': case ';': case '<': case '=': case '>': 
 125             case 'A': case 'B': case 'C': case 'D': case 'E': 
 126             case 'F': case 'G': case 'H': case 'I': case 'J': 
 127             case 'K': case 'L': case 'M': case 'N': case 'O': 
 128             case 'P': case 'Q': case 'R': case 'S': case 'T': 
 129             case 'U': case 'V': case 'W': case 'X': case 'Y': 
 131             case '[': case '\\': case ']': case '^': case '_': 
 132             case 'a': case 'b': case 'c': case 'd': case 'e': 
 133             case 'f': case 'g': case 'h': case 'i': case 'j': 
 134             case 'k': case 'l': case 'm': case 'n': case 'o': 
 135             case 'p': case 'q': case 'r': case 's': case 't': 
 136             case 'u': case 'v': case 'w': case 'x': case 'y': 
 137             case 'z': case '{': case '|': case '}': case '~': 
 138               /* These characters are printable ASCII characters.  */ 
 143               /* If we have a multibyte sequence, scan it up to its end.  */ 
 146                 memset (&mbstate
, 0, sizeof mbstate
); 
 153                     bytes 
= mbrtowc (&wc
, p
, plimit 
- p
, &mbstate
); 
 155                     if (bytes 
== (size_t) -1) 
 156                       /* An invalid multibyte sequence was encountered.  */ 
 158                         if (!(flags 
& MBSW_REJECT_INVALID
)) 
 168                     if (bytes 
== (size_t) -2) 
 169                       /* An incomplete multibyte character at the end.  */ 
 171                         if (!(flags 
& MBSW_REJECT_INVALID
)) 
 182                       /* A null wide character was encountered.  */ 
 187                       /* A printable multibyte character.  */ 
 190                       /* An unprintable multibyte character.  */ 
 191                       if (!(flags 
& MBSW_REJECT_UNPRINTABLE
)) 
 192                         width 
+= (iswcntrl (wc
) ? 0 : 1); 
 198                 while (! mbsinit (&mbstate
)); 
 208       unsigned char c 
= (unsigned char) *p
++; 
 212       else if (!(flags 
& MBSW_REJECT_UNPRINTABLE
)) 
 213         width 
+= (ISCNTRL (c
) ? 0 : 1);