xref: /dflybsd-src/contrib/cvs-1.12/lib/mbchar.h (revision 86d7f5d305c6adaa56ff4582ece9859d73106103)
186d7f5d3SJohn Marino /* Multibyte character data type.
286d7f5d3SJohn Marino    Copyright (C) 2001, 2005 Free Software Foundation, Inc.
386d7f5d3SJohn Marino 
486d7f5d3SJohn Marino    This program is free software; you can redistribute it and/or modify
586d7f5d3SJohn Marino    it under the terms of the GNU General Public License as published by
686d7f5d3SJohn Marino    the Free Software Foundation; either version 2, or (at your option)
786d7f5d3SJohn Marino    any later version.
886d7f5d3SJohn Marino 
986d7f5d3SJohn Marino    This program is distributed in the hope that it will be useful,
1086d7f5d3SJohn Marino    but WITHOUT ANY WARRANTY; without even the implied warranty of
1186d7f5d3SJohn Marino    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1286d7f5d3SJohn Marino    GNU General Public License for more details.
1386d7f5d3SJohn Marino 
1486d7f5d3SJohn Marino    You should have received a copy of the GNU General Public License
1586d7f5d3SJohn Marino    along with this program; if not, write to the Free Software Foundation,
1686d7f5d3SJohn Marino    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
1786d7f5d3SJohn Marino 
1886d7f5d3SJohn Marino /* Written by Bruno Haible <bruno@clisp.org>.  */
1986d7f5d3SJohn Marino 
2086d7f5d3SJohn Marino /* A multibyte character is a short subsequence of a char* string,
2186d7f5d3SJohn Marino    representing a single wide character.
2286d7f5d3SJohn Marino 
2386d7f5d3SJohn Marino    We use multibyte characters instead of wide characters because of
2486d7f5d3SJohn Marino    the following goals:
2586d7f5d3SJohn Marino    1) correct multibyte handling, i.e. operate according to the LC_CTYPE
2686d7f5d3SJohn Marino       locale,
2786d7f5d3SJohn Marino    2) ease of maintenance, i.e. the maintainer needs not know all details
2886d7f5d3SJohn Marino       of the ISO C 99 standard,
2986d7f5d3SJohn Marino    3) don't fail grossly if the input is not in the encoding set by the
3086d7f5d3SJohn Marino       locale, because often different encodings are in use in the same
3186d7f5d3SJohn Marino       countries (ISO-8859-1/UTF-8, EUC-JP/Shift_JIS, ...),
3286d7f5d3SJohn Marino    4) fast in the case of ASCII characters,
3386d7f5d3SJohn Marino    5) portability, i.e. don't make unportable assumptions about wchar_t.
3486d7f5d3SJohn Marino 
3586d7f5d3SJohn Marino    Multibyte characters are only accessed through the mb* macros.
3686d7f5d3SJohn Marino 
3786d7f5d3SJohn Marino    mb_ptr (mbc)
3886d7f5d3SJohn Marino      return a pointer to the beginning of the multibyte sequence.
3986d7f5d3SJohn Marino 
4086d7f5d3SJohn Marino    mb_len (mbc)
4186d7f5d3SJohn Marino      returns the number of bytes occupied by the multibyte sequence.
4286d7f5d3SJohn Marino      Always > 0.
4386d7f5d3SJohn Marino 
4486d7f5d3SJohn Marino    mb_iseq (mbc, sc)
4586d7f5d3SJohn Marino      returns true if mbc is the standard ASCII character sc.
4686d7f5d3SJohn Marino 
4786d7f5d3SJohn Marino    mb_isnul (mbc)
4886d7f5d3SJohn Marino      returns true if mbc is the nul character.
4986d7f5d3SJohn Marino 
5086d7f5d3SJohn Marino    mb_cmp (mbc1, mbc2)
5186d7f5d3SJohn Marino      returns a positive, zero, or negative value depending on whether mbc1
5286d7f5d3SJohn Marino      sorts after, same or before mbc2.
5386d7f5d3SJohn Marino 
5486d7f5d3SJohn Marino    mb_casecmp (mbc1, mbc2)
5586d7f5d3SJohn Marino      returns a positive, zero, or negative value depending on whether mbc1
5686d7f5d3SJohn Marino      sorts after, same or before mbc2, modulo upper/lowercase conversion.
5786d7f5d3SJohn Marino 
5886d7f5d3SJohn Marino    mb_equal (mbc1, mbc2)
5986d7f5d3SJohn Marino      returns true if mbc1 and mbc2 are equal.
6086d7f5d3SJohn Marino 
6186d7f5d3SJohn Marino    mb_caseequal (mbc1, mbc2)
6286d7f5d3SJohn Marino      returns true if mbc1 and mbc2 are equal modulo upper/lowercase conversion.
6386d7f5d3SJohn Marino 
6486d7f5d3SJohn Marino    mb_isalnum (mbc)
6586d7f5d3SJohn Marino      returns true if mbc is alphanumeric.
6686d7f5d3SJohn Marino 
6786d7f5d3SJohn Marino    mb_isalpha (mbc)
6886d7f5d3SJohn Marino      returns true if mbc is alphabetic.
6986d7f5d3SJohn Marino 
7086d7f5d3SJohn Marino    mb_isascii(mbc)
7186d7f5d3SJohn Marino      returns true if mbc is plain ASCII.
7286d7f5d3SJohn Marino 
7386d7f5d3SJohn Marino    mb_isblank (mbc)
7486d7f5d3SJohn Marino      returns true if mbc is a blank.
7586d7f5d3SJohn Marino 
7686d7f5d3SJohn Marino    mb_iscntrl (mbc)
7786d7f5d3SJohn Marino      returns true if mbc is a control character.
7886d7f5d3SJohn Marino 
7986d7f5d3SJohn Marino    mb_isdigit (mbc)
8086d7f5d3SJohn Marino      returns true if mbc is a decimal digit.
8186d7f5d3SJohn Marino 
8286d7f5d3SJohn Marino    mb_isgraph (mbc)
8386d7f5d3SJohn Marino      returns true if mbc is a graphic character.
8486d7f5d3SJohn Marino 
8586d7f5d3SJohn Marino    mb_islower (mbc)
8686d7f5d3SJohn Marino      returns true if mbc is lowercase.
8786d7f5d3SJohn Marino 
8886d7f5d3SJohn Marino    mb_isprint (mbc)
8986d7f5d3SJohn Marino      returns true if mbc is a printable character.
9086d7f5d3SJohn Marino 
9186d7f5d3SJohn Marino    mb_ispunct (mbc)
9286d7f5d3SJohn Marino      returns true if mbc is a punctuation character.
9386d7f5d3SJohn Marino 
9486d7f5d3SJohn Marino    mb_isspace (mbc)
9586d7f5d3SJohn Marino      returns true if mbc is a space character.
9686d7f5d3SJohn Marino 
9786d7f5d3SJohn Marino    mb_isupper (mbc)
9886d7f5d3SJohn Marino      returns true if mbc is uppercase.
9986d7f5d3SJohn Marino 
10086d7f5d3SJohn Marino    mb_isxdigit (mbc)
10186d7f5d3SJohn Marino      returns true if mbc is a hexadecimal digit.
10286d7f5d3SJohn Marino 
10386d7f5d3SJohn Marino    mb_width (mbc)
10486d7f5d3SJohn Marino      returns the number of columns on the output device occupied by mbc.
10586d7f5d3SJohn Marino      Always >= 0.
10686d7f5d3SJohn Marino 
10786d7f5d3SJohn Marino    mb_putc (mbc, stream)
10886d7f5d3SJohn Marino      outputs mbc on stream, a byte oriented FILE stream opened for output.
10986d7f5d3SJohn Marino 
11086d7f5d3SJohn Marino    mb_setascii (&mbc, sc)
11186d7f5d3SJohn Marino      assigns the standard ASCII character sc to mbc.
11286d7f5d3SJohn Marino 
11386d7f5d3SJohn Marino    mb_copy (&destmbc, &srcmbc)
11486d7f5d3SJohn Marino      copies srcmbc to destmbc.
11586d7f5d3SJohn Marino 
11686d7f5d3SJohn Marino    Here are the function prototypes of the macros.
11786d7f5d3SJohn Marino 
11886d7f5d3SJohn Marino    extern const char *	mb_ptr (const mbchar_t mbc);
11986d7f5d3SJohn Marino    extern size_t	mb_len (const mbchar_t mbc);
12086d7f5d3SJohn Marino    extern bool		mb_iseq (const mbchar_t mbc, char sc);
12186d7f5d3SJohn Marino    extern bool		mb_isnul (const mbchar_t mbc);
12286d7f5d3SJohn Marino    extern int		mb_cmp (const mbchar_t mbc1, const mbchar_t mbc2);
12386d7f5d3SJohn Marino    extern int		mb_casecmp (const mbchar_t mbc1, const mbchar_t mbc2);
12486d7f5d3SJohn Marino    extern bool		mb_equal (const mbchar_t mbc1, const mbchar_t mbc2);
12586d7f5d3SJohn Marino    extern bool		mb_caseequal (const mbchar_t mbc1, const mbchar_t mbc2);
12686d7f5d3SJohn Marino    extern bool		mb_isalnum (const mbchar_t mbc);
12786d7f5d3SJohn Marino    extern bool		mb_isalpha (const mbchar_t mbc);
12886d7f5d3SJohn Marino    extern bool		mb_isascii (const mbchar_t mbc);
12986d7f5d3SJohn Marino    extern bool		mb_isblank (const mbchar_t mbc);
13086d7f5d3SJohn Marino    extern bool		mb_iscntrl (const mbchar_t mbc);
13186d7f5d3SJohn Marino    extern bool		mb_isdigit (const mbchar_t mbc);
13286d7f5d3SJohn Marino    extern bool		mb_isgraph (const mbchar_t mbc);
13386d7f5d3SJohn Marino    extern bool		mb_islower (const mbchar_t mbc);
13486d7f5d3SJohn Marino    extern bool		mb_isprint (const mbchar_t mbc);
13586d7f5d3SJohn Marino    extern bool		mb_ispunct (const mbchar_t mbc);
13686d7f5d3SJohn Marino    extern bool		mb_isspace (const mbchar_t mbc);
13786d7f5d3SJohn Marino    extern bool		mb_isupper (const mbchar_t mbc);
13886d7f5d3SJohn Marino    extern bool		mb_isxdigit (const mbchar_t mbc);
13986d7f5d3SJohn Marino    extern int		mb_width (const mbchar_t mbc);
14086d7f5d3SJohn Marino    extern void		mb_putc (const mbchar_t mbc, FILE *stream);
14186d7f5d3SJohn Marino    extern void          mb_setascii (mbchar_t *new, char sc);
14286d7f5d3SJohn Marino    extern void		mb_copy (mbchar_t *new, const mbchar_t *old);
14386d7f5d3SJohn Marino  */
14486d7f5d3SJohn Marino 
14586d7f5d3SJohn Marino #ifndef _MBCHAR_H
14686d7f5d3SJohn Marino #define _MBCHAR_H 1
14786d7f5d3SJohn Marino 
14886d7f5d3SJohn Marino #include <stdbool.h>
14986d7f5d3SJohn Marino #include <string.h>
15086d7f5d3SJohn Marino 
15186d7f5d3SJohn Marino /* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
15286d7f5d3SJohn Marino    <wchar.h>.
15386d7f5d3SJohn Marino    BSD/OS 4.1 has a bug: <stdio.h> and <time.h> must be included before
15486d7f5d3SJohn Marino    <wchar.h>.  */
15586d7f5d3SJohn Marino #include <stdio.h>
15686d7f5d3SJohn Marino #include <time.h>
15786d7f5d3SJohn Marino #include <wchar.h>
15886d7f5d3SJohn Marino 
15986d7f5d3SJohn Marino #include <wctype.h>
16086d7f5d3SJohn Marino 
16186d7f5d3SJohn Marino #define MBCHAR_BUF_SIZE 24
16286d7f5d3SJohn Marino 
16386d7f5d3SJohn Marino struct mbchar
16486d7f5d3SJohn Marino {
16586d7f5d3SJohn Marino   const char *ptr;	/* pointer to current character */
16686d7f5d3SJohn Marino   size_t bytes;		/* number of bytes of current character, > 0 */
16786d7f5d3SJohn Marino   bool wc_valid;	/* true if wc is a valid wide character */
16886d7f5d3SJohn Marino   wchar_t wc;		/* if wc_valid: the current character */
16986d7f5d3SJohn Marino   char buf[MBCHAR_BUF_SIZE]; /* room for the bytes, used for file input only */
17086d7f5d3SJohn Marino };
17186d7f5d3SJohn Marino 
17286d7f5d3SJohn Marino /* EOF (not a real character) is represented with bytes = 0 and
17386d7f5d3SJohn Marino    wc_valid = false.  */
17486d7f5d3SJohn Marino 
17586d7f5d3SJohn Marino typedef struct mbchar mbchar_t;
17686d7f5d3SJohn Marino 
17786d7f5d3SJohn Marino /* Access the current character.  */
17886d7f5d3SJohn Marino #define mb_ptr(mbc) ((mbc).ptr)
17986d7f5d3SJohn Marino #define mb_len(mbc) ((mbc).bytes)
18086d7f5d3SJohn Marino 
18186d7f5d3SJohn Marino /* Comparison of characters.  */
18286d7f5d3SJohn Marino #define mb_iseq(mbc, sc) ((mbc).wc_valid && (mbc).wc == (sc))
18386d7f5d3SJohn Marino #define mb_isnul(mbc) ((mbc).wc_valid && (mbc).wc == 0)
18486d7f5d3SJohn Marino #define mb_cmp(mbc1, mbc2) \
18586d7f5d3SJohn Marino   ((mbc1).wc_valid							\
18686d7f5d3SJohn Marino    ? ((mbc2).wc_valid							\
18786d7f5d3SJohn Marino       ? (int) (mbc1).wc - (int) (mbc2).wc				\
18886d7f5d3SJohn Marino       : -1)								\
18986d7f5d3SJohn Marino    : ((mbc2).wc_valid							\
19086d7f5d3SJohn Marino       ? 1								\
19186d7f5d3SJohn Marino       : (mbc1).bytes == (mbc2).bytes					\
19286d7f5d3SJohn Marino         ? memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes)			\
19386d7f5d3SJohn Marino         : (mbc1).bytes < (mbc2).bytes					\
19486d7f5d3SJohn Marino           ? (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) > 0 ? 1 : -1) \
19586d7f5d3SJohn Marino           : (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc2).bytes) >= 0 ? 1 : -1)))
19686d7f5d3SJohn Marino #define mb_casecmp(mbc1, mbc2) \
19786d7f5d3SJohn Marino   ((mbc1).wc_valid							\
19886d7f5d3SJohn Marino    ? ((mbc2).wc_valid							\
19986d7f5d3SJohn Marino       ? (int) towlower ((mbc1).wc) - (int) towlower ((mbc2).wc)		\
20086d7f5d3SJohn Marino       : -1)								\
20186d7f5d3SJohn Marino    : ((mbc2).wc_valid							\
20286d7f5d3SJohn Marino       ? 1								\
20386d7f5d3SJohn Marino       : (mbc1).bytes == (mbc2).bytes					\
20486d7f5d3SJohn Marino         ? memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes)			\
20586d7f5d3SJohn Marino         : (mbc1).bytes < (mbc2).bytes					\
20686d7f5d3SJohn Marino           ? (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) > 0 ? 1 : -1) \
20786d7f5d3SJohn Marino           : (memcmp ((mbc1).ptr, (mbc2).ptr, (mbc2).bytes) >= 0 ? 1 : -1)))
20886d7f5d3SJohn Marino #define mb_equal(mbc1, mbc2) \
20986d7f5d3SJohn Marino   ((mbc1).wc_valid && (mbc2).wc_valid					\
21086d7f5d3SJohn Marino    ? (mbc1).wc == (mbc2).wc						\
21186d7f5d3SJohn Marino    : (mbc1).bytes == (mbc2).bytes					\
21286d7f5d3SJohn Marino      && memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) == 0)
21386d7f5d3SJohn Marino #define mb_caseequal(mbc1, mbc2) \
21486d7f5d3SJohn Marino   ((mbc1).wc_valid && (mbc2).wc_valid					\
21586d7f5d3SJohn Marino    ? towlower ((mbc1).wc) == towlower ((mbc2).wc)			\
21686d7f5d3SJohn Marino    : (mbc1).bytes == (mbc2).bytes					\
21786d7f5d3SJohn Marino      && memcmp ((mbc1).ptr, (mbc2).ptr, (mbc1).bytes) == 0)
21886d7f5d3SJohn Marino 
21986d7f5d3SJohn Marino /* <ctype.h>, <wctype.h> classification.  */
22086d7f5d3SJohn Marino #define mb_isascii(mbc) \
22186d7f5d3SJohn Marino   ((mbc).wc_valid && (mbc).wc >= 0 && (mbc).wc <= 127)
22286d7f5d3SJohn Marino #define mb_isalnum(mbc) ((mbc).wc_valid && iswalnum ((mbc).wc))
22386d7f5d3SJohn Marino #define mb_isalpha(mbc) ((mbc).wc_valid && iswalpha ((mbc).wc))
22486d7f5d3SJohn Marino #define mb_isblank(mbc) ((mbc).wc_valid && iswblank ((mbc).wc))
22586d7f5d3SJohn Marino #define mb_iscntrl(mbc) ((mbc).wc_valid && iswcntrl ((mbc).wc))
22686d7f5d3SJohn Marino #define mb_isdigit(mbc) ((mbc).wc_valid && iswdigit ((mbc).wc))
22786d7f5d3SJohn Marino #define mb_isgraph(mbc) ((mbc).wc_valid && iswgraph ((mbc).wc))
22886d7f5d3SJohn Marino #define mb_islower(mbc) ((mbc).wc_valid && iswlower ((mbc).wc))
22986d7f5d3SJohn Marino #define mb_isprint(mbc) ((mbc).wc_valid && iswprint ((mbc).wc))
23086d7f5d3SJohn Marino #define mb_ispunct(mbc) ((mbc).wc_valid && iswpunct ((mbc).wc))
23186d7f5d3SJohn Marino #define mb_isspace(mbc) ((mbc).wc_valid && iswspace ((mbc).wc))
23286d7f5d3SJohn Marino #define mb_isupper(mbc) ((mbc).wc_valid && iswupper ((mbc).wc))
23386d7f5d3SJohn Marino #define mb_isxdigit(mbc) ((mbc).wc_valid && iswxdigit ((mbc).wc))
23486d7f5d3SJohn Marino 
23586d7f5d3SJohn Marino /* Extra <wchar.h> function.  */
23686d7f5d3SJohn Marino 
23786d7f5d3SJohn Marino /* Unprintable characters appear as a small box of width 1.  */
23886d7f5d3SJohn Marino #define MB_UNPRINTABLE_WIDTH 1
23986d7f5d3SJohn Marino 
24086d7f5d3SJohn Marino static inline int
mb_width_aux(wint_t wc)24186d7f5d3SJohn Marino mb_width_aux (wint_t wc)
24286d7f5d3SJohn Marino {
24386d7f5d3SJohn Marino   int w = wcwidth (wc);
24486d7f5d3SJohn Marino   /* For unprintable characters, arbitrarily return 0 for control characters
24586d7f5d3SJohn Marino      and MB_UNPRINTABLE_WIDTH otherwise.  */
24686d7f5d3SJohn Marino   return (w >= 0 ? w : iswcntrl (wc) ? 0 : MB_UNPRINTABLE_WIDTH);
24786d7f5d3SJohn Marino }
24886d7f5d3SJohn Marino 
24986d7f5d3SJohn Marino #define mb_width(mbc) \
25086d7f5d3SJohn Marino   ((mbc).wc_valid ? mb_width_aux ((mbc).wc) : MB_UNPRINTABLE_WIDTH)
25186d7f5d3SJohn Marino 
25286d7f5d3SJohn Marino /* Output.  */
25386d7f5d3SJohn Marino #define mb_putc(mbc, stream)  fwrite ((mbc).ptr, 1, (mbc).bytes, (stream))
25486d7f5d3SJohn Marino 
25586d7f5d3SJohn Marino /* Assignment.  */
25686d7f5d3SJohn Marino #define mb_setascii(mbc, sc) \
25786d7f5d3SJohn Marino   ((mbc)->ptr = (mbc)->buf, (mbc)->bytes = 1, (mbc)->wc_valid = 1, \
25886d7f5d3SJohn Marino    (mbc)->wc = (mbc)->buf[0] = (sc))
25986d7f5d3SJohn Marino 
26086d7f5d3SJohn Marino /* Copying a character.  */
26186d7f5d3SJohn Marino static inline void
mb_copy(mbchar_t * new,const mbchar_t * old)26286d7f5d3SJohn Marino mb_copy (mbchar_t *new, const mbchar_t *old)
26386d7f5d3SJohn Marino {
26486d7f5d3SJohn Marino   if (old->ptr == &old->buf[0])
26586d7f5d3SJohn Marino     {
26686d7f5d3SJohn Marino       memcpy (&new->buf[0], &old->buf[0], old->bytes);
26786d7f5d3SJohn Marino       new->ptr = &new->buf[0];
26886d7f5d3SJohn Marino     }
26986d7f5d3SJohn Marino   else
27086d7f5d3SJohn Marino     new->ptr = old->ptr;
27186d7f5d3SJohn Marino   new->bytes = old->bytes;
27286d7f5d3SJohn Marino   if ((new->wc_valid = old->wc_valid))
27386d7f5d3SJohn Marino     new->wc = old->wc;
27486d7f5d3SJohn Marino }
27586d7f5d3SJohn Marino 
27686d7f5d3SJohn Marino 
27786d7f5d3SJohn Marino /* is_basic(c) tests whether the single-byte character c is in the
27886d7f5d3SJohn Marino    ISO C "basic character set".
27986d7f5d3SJohn Marino    This is a convenience function, and is in this file only to share code
28086d7f5d3SJohn Marino    between mbiter_multi.h and mbfile_multi.h.  */
28186d7f5d3SJohn Marino #if (' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
28286d7f5d3SJohn Marino     && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
28386d7f5d3SJohn Marino     && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
28486d7f5d3SJohn Marino     && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
28586d7f5d3SJohn Marino     && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
28686d7f5d3SJohn Marino     && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
28786d7f5d3SJohn Marino     && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
28886d7f5d3SJohn Marino     && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
28986d7f5d3SJohn Marino     && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
29086d7f5d3SJohn Marino     && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
29186d7f5d3SJohn Marino     && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
29286d7f5d3SJohn Marino     && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
29386d7f5d3SJohn Marino     && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
29486d7f5d3SJohn Marino     && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
29586d7f5d3SJohn Marino     && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
29686d7f5d3SJohn Marino     && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
29786d7f5d3SJohn Marino     && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
29886d7f5d3SJohn Marino     && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
29986d7f5d3SJohn Marino     && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
30086d7f5d3SJohn Marino     && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
30186d7f5d3SJohn Marino     && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
30286d7f5d3SJohn Marino     && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
30386d7f5d3SJohn Marino     && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)
30486d7f5d3SJohn Marino /* The character set is ISO-646, not EBCDIC. */
30586d7f5d3SJohn Marino # define IS_BASIC_ASCII 1
30686d7f5d3SJohn Marino 
30786d7f5d3SJohn Marino extern unsigned int is_basic_table[];
30886d7f5d3SJohn Marino 
30986d7f5d3SJohn Marino static inline bool
is_basic(char c)31086d7f5d3SJohn Marino is_basic (char c)
31186d7f5d3SJohn Marino {
31286d7f5d3SJohn Marino   return (is_basic_table [(unsigned char) c >> 5] >> ((unsigned char) c & 31))
31386d7f5d3SJohn Marino 	 & 1;
31486d7f5d3SJohn Marino }
31586d7f5d3SJohn Marino 
31686d7f5d3SJohn Marino #else
31786d7f5d3SJohn Marino 
31886d7f5d3SJohn Marino static inline bool
is_basic(char c)31986d7f5d3SJohn Marino is_basic (char c)
32086d7f5d3SJohn Marino {
32186d7f5d3SJohn Marino   switch (c)
32286d7f5d3SJohn Marino     {
32386d7f5d3SJohn Marino     case '\t': case '\v': case '\f':
32486d7f5d3SJohn Marino     case ' ': case '!': case '"': case '#': case '%':
32586d7f5d3SJohn Marino     case '&': case '\'': case '(': case ')': case '*':
32686d7f5d3SJohn Marino     case '+': case ',': case '-': case '.': case '/':
32786d7f5d3SJohn Marino     case '0': case '1': case '2': case '3': case '4':
32886d7f5d3SJohn Marino     case '5': case '6': case '7': case '8': case '9':
32986d7f5d3SJohn Marino     case ':': case ';': case '<': case '=': case '>':
33086d7f5d3SJohn Marino     case '?':
33186d7f5d3SJohn Marino     case 'A': case 'B': case 'C': case 'D': case 'E':
33286d7f5d3SJohn Marino     case 'F': case 'G': case 'H': case 'I': case 'J':
33386d7f5d3SJohn Marino     case 'K': case 'L': case 'M': case 'N': case 'O':
33486d7f5d3SJohn Marino     case 'P': case 'Q': case 'R': case 'S': case 'T':
33586d7f5d3SJohn Marino     case 'U': case 'V': case 'W': case 'X': case 'Y':
33686d7f5d3SJohn Marino     case 'Z':
33786d7f5d3SJohn Marino     case '[': case '\\': case ']': case '^': case '_':
33886d7f5d3SJohn Marino     case 'a': case 'b': case 'c': case 'd': case 'e':
33986d7f5d3SJohn Marino     case 'f': case 'g': case 'h': case 'i': case 'j':
34086d7f5d3SJohn Marino     case 'k': case 'l': case 'm': case 'n': case 'o':
34186d7f5d3SJohn Marino     case 'p': case 'q': case 'r': case 's': case 't':
34286d7f5d3SJohn Marino     case 'u': case 'v': case 'w': case 'x': case 'y':
34386d7f5d3SJohn Marino     case 'z': case '{': case '|': case '}': case '~':
34486d7f5d3SJohn Marino       return 1;
34586d7f5d3SJohn Marino     default:
34686d7f5d3SJohn Marino       return 0;
34786d7f5d3SJohn Marino     }
34886d7f5d3SJohn Marino }
34986d7f5d3SJohn Marino 
35086d7f5d3SJohn Marino #endif
35186d7f5d3SJohn Marino 
35286d7f5d3SJohn Marino #endif /* _MBCHAR_H */
353