1 /*
   2  * This file and its contents are supplied under the terms of the
   3  * Common Development and Distribution License ("CDDL"), version 1.0.
   4  * You may only use this file in accordance with the terms of version
   5  * 1.0 of the CDDL.
   6  *
   7  * A full copy of the text of the CDDL should have accompanied this
   8  * source.  A copy of the CDDL is also available via the Internet at
   9  * http://www.illumos.org/license/CDDL.
  10  */
  11 
  12 /*
  13  * Copyright 2013 Garrett D'Amore <garrett@damore.org>
  14  * Copyright 2010 Nexenta Systems, Inc.  All rights reserved.
  15  */
  16 
  17 /*
  18  * This file contains the implementation of various functional forms
  19  * of the ctype tests, specifically the required by ISO C.  These are defined
  20  * in the "C" (POSIX) locale.
  21  */
  22 
  23 #include "lint.h"
  24 #include <ctype.h>
  25 #include <locale.h>
  26 #include "localeimpl.h"
  27 #include "_ctype.h"
  28 #include "lctype.h"
  29 
  30 /*
  31  * We are supplying functional forms, so make sure to suppress any macros
  32  * we might have imported.
  33  */
  34 
  35 /*
  36  * Performance note: ASCII test is *much* faster, as we can avoid expensive
  37  * function call overhead.  This is the hot case, so we try to do that
  38  * whenever possible.  As far as we know, *every* encoding we support
  39  * is a strict superset of ASCII.  So we can make things faster by trying
  40  * ASCII first, and only then falling to locale specific checks.
  41  */
  42 
  43 static int
  44 isctype_l(int c, int mask, locale_t loc)
  45 {
  46         return ((unsigned)c > 255 ? 0 : (loc->ctype->lc_ctype_mask[c] & mask));
  47 }
  48 
  49 #define ISTYPE_L(c, mask, loc)  \
  50         (isascii(c) ? (__ctype_mask[c] & (mask)) : isctype_l(c, mask, loc))
  51 
  52 #define ISTYPE(c, mask) ISTYPE_L(c, mask, uselocale(NULL))
  53 
  54 #define DEFN_ISTYPE(type, mask)         \
  55 int                                     \
  56 is##type##_l(int c, locale_t l) \
  57 {                                       \
  58         return (ISTYPE_L(c, mask, l));  \
  59 }                                       \
  60                                         \
  61 int                                     \
  62 is##type(int c)                         \
  63 {                                       \
  64         return (ISTYPE(c, mask));       \
  65 }
  66 
  67 #undef  isblank
  68 #undef  isupper
  69 #undef  islower
  70 #undef  isdigit
  71 #undef  isxdigit
  72 #undef  isalpha
  73 #undef  isalnum
  74 #undef  isspace
  75 #undef  iscntrl
  76 #undef  isgraph
  77 #undef  ispunct
  78 #undef  isprint
  79 
  80 DEFN_ISTYPE(blank, _ISBLANK)
  81 DEFN_ISTYPE(upper, _ISUPPER)
  82 DEFN_ISTYPE(lower, _ISLOWER)
  83 DEFN_ISTYPE(digit, _ISDIGIT)
  84 DEFN_ISTYPE(xdigit, _ISXDIGIT)
  85 DEFN_ISTYPE(alpha, _ISALPHA)
  86 DEFN_ISTYPE(alnum, _ISALNUM)
  87 DEFN_ISTYPE(space, _ISSPACE)
  88 DEFN_ISTYPE(cntrl, _ISCNTRL)
  89 DEFN_ISTYPE(graph, _ISGRAPH)
  90 DEFN_ISTYPE(punct, _ISPUNCT)
  91 DEFN_ISTYPE(print, _ISPRINT)