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