From d07fdf8b9ece2c4339b325921add50792077bf97 Mon Sep 17 00:00:00 2001 From: Manuel Novoa III Date: Mon, 6 May 2002 07:37:32 +0000 Subject: New locale support (in development). Supports LC_CTYPE, LC_NUMERIC, LC_TIME, LC_MONETARY, and LC_MESSAGES for the SUSv3 items. Also, nl_langinfo() when real locale support is enabled. New implementation of ctype.h. New implementation of wctype.h. New implementation of most of the string functions (smaller). New implementation of the wcs/wmem functions. These are untested, but they're also just preprocessor-modified versions ot the corresponding str/mem functions. Tweaked qsort and new bsearch. Stuff still pending: stdlib.h and wchar.h mb<->wc functions. I actually have working versions of the stdlib ones, but the reentrant versions from wchar.h require some reworking. Basic replacement and translit support for wc->mb conversions. (groundwork laid). Simple-minded collate support such as was provided by the previous locale implementation. (mostly done -- 8-bit codesets only) Shared mmaping of the locale data and strerror message text. --- include/ctype.h | 176 +++++++++++++++++++++++++++++++++-------------------- include/inttypes.h | 4 +- include/langinfo.h | 36 ++++++++--- include/libgen.h | 2 - include/locale.h | 120 ++++++++++++++++++++++++++++++------ include/stdint.h | 12 ++-- include/stdlib.h | 12 ++-- 7 files changed, 251 insertions(+), 111 deletions(-) (limited to 'include') diff --git a/include/ctype.h b/include/ctype.h index a7e397e3d..c39bd3ccd 100644 --- a/include/ctype.h +++ b/include/ctype.h @@ -1,82 +1,126 @@ -/* vi: set sw=4 ts=4: */ -/* - * ctype.h - * Character classification and conversion +/* Copyright (C) 2002 Manuel Novoa III * - * Copyright (C) 2000 by Lineo, inc. - * Copyright (C) 2000,2001 Erik Andersen + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Library General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License - * for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#ifndef __CTYPE_H -#define __CTYPE_H +/* NOTE: It is assumed here and throughout the library that the underlying + * char encoding for the portable C character set is ASCII (host & target). */ + +#ifndef _CTYPE_H +#define _CTYPE_H #include +#include __BEGIN_DECLS +extern int isalnum(int c) __THROW; +extern int isalpha(int c) __THROW; +#ifdef __USE_ISOC99 +extern int isblank(int c) __THROW; +#endif +extern int iscntrl(int c) __THROW; +extern int isdigit(int c) __THROW; +extern int isgraph(int c) __THROW; +extern int islower(int c) __THROW; +extern int isprint(int c) __THROW; +extern int ispunct(int c) __THROW; +extern int isspace(int c) __THROW; +extern int isupper(int c) __THROW; +extern int isxdigit(int c) __THROW; -/* function prototpes */ -extern int isalnum(int c); -extern int isalpha(int c); -extern int isascii(int c); -extern int isblank(int c); -extern int iscntrl(int c); -extern int isdigit(int c); -extern int isgraph(int c); -extern int islower(int c); -extern int isprint(int c); -extern int ispunct(int c); -extern int isspace(int c); -extern int isupper(int c); -extern int isxdigit(int c); -extern int isxlower(int c); -extern int isxupper(int c); -extern int toascii(int c); -extern int tolower(int c); -extern int toupper(int c); - - -/* Locale-compatible macros/inlines have yet to be implemented. */ -#if defined(__USE_CTYPE_MACROS) && !defined __UCLIBC_HAS_LOCALE__ - -/* macro definitions */ -#define isalnum(c) (isalpha(c) || isdigit(c)) -#define isalpha(c) (isupper(c) || islower(c)) -#define isascii(c) (c > 0 && c <= 0x7f) -#define isblank(c) (c == ' ' || c == '\t') -#define iscntrl(c) ((c >= 0) && ((c <= 0x1F) || (c == 0x7f))) -#define isdigit(c) (c >= '0' && c <= '9') -#define isgraph(c) (c != ' ' && isprint(c)) -#define islower(c) (c >= 'a' && c <= 'z') -#define isprint(c) (c >= ' ' && c <= '~') -#define ispunct(c) ((c > ' ' && c <= '~') && !isalnum(c)) -#define isspace(c) (c == ' ' || c == '\f' || c == '\n' || c == '\r' ||\ - c == '\t' || c == '\v') -#define isupper(c) (c >= 'A' && c <= 'Z') -#define isxdigit(c) (isxupper(c) || isxlower(c)) -#define isxlower(c) (isdigit(c) || (c >= 'a' && c <= 'f')) -#define isxupper(c) (isdigit(c) || (c >= 'A' && c <= 'F')) -#define toascii(c) (c & 0x7f) -#define tolower(c) (isupper(c) ? ( c - 'A' + 'a') : (c)) -#define toupper(c) (islower(c) ? (c - 'a' + 'A') : (c)) +extern int tolower(int c) __THROW; +extern int toupper(int c) __THROW; +#if defined __USE_SVID || defined __USE_MISC || defined __USE_XOPEN +extern int isascii(int c) __THROW; +extern int toascii(int c) __THROW; #endif +/* The following are included for compatibility with older versions of + * uClibc; but now they're only visible if MISC funcctionality is requested. + * However, as they are locale-independent, the hidden macro versions are + * always present. */ +#ifdef __USE_MISC +extern int isxlower(int c) __THROW; /* uClibc-specific. */ +extern int isxupper(int c) __THROW; /* uClibc-specific. */ +#endif + +/* Next, some ctype macros which are valid for all supported locales. */ +/* WARNING: isspace and isblank need to be reverified if more 8-bit codesets + * are added!!! But isdigit and isxdigit are always valid. */ + +#define __isspace(c) __C_isspace(c) +#define __isblank(c) __C_isblank(c) + +#define __isdigit(c) __C_isdigit(c) +#define __isxdigit(c) __C_isxdigit(c) + +/* Now some non-ansi/iso c99 macros. */ + +#define __isascii(c) (((unsigned int)(c)) <= 0x7f) +#define __toascii(c) ((c) & 0x7f) + +#define _toupper(c) ((c) | 0x20) +#define _tolower(c) ((c) ^ 0x20) + +/* For compatibility with older versions of uClibc. Are these ever used? */ +#define __isxlower(c) __C_isxlower(c) /* uClibc-specific. */ +#define __isxupper(c) __C_isxupper(c) /* uClibc-specific. */ + +/* Apparently, glibc implements things as macros if __NO_CTYPE isn't defined. + * If we don't have locale support, we'll do the same. Otherwise, we'll + * only use macros for the supported-locale-invariant cases. */ +#ifndef __NO_CTYPE + +#define isdigit(c) __isdigit(c) +#define isxdigit(c) __isxdigit(c) +#define isspace(c) __isspace(c) +#ifdef __USE_ISOC99 +#define isblank(c) __isblank(c) +#endif + +#if defined __USE_SVID || defined __USE_MISC || defined __USE_XOPEN +#define isascii(c) __isascii(c) +#define toascii(c) __toascii(c) +#endif + +#ifdef __USE_MISC +#define isxlower(c) __C_isxlower(c) /* uClibc-specific. */ +#define isxupper(c) __C_isxupper(c) /* uClibc-specific. */ +#endif + +/* TODO - Should test for 8-bit codesets instead, but currently impossible. */ +#ifndef __UCLIBC_HAS_LOCALE__ + +#define isalnum(c) __C_isalnum(c) +#define isalpha(c) __C_isalpha(c) +#define iscntrl(c) __C_iscntrl(c) +#define isgraph(c) __C_isgraph(c) +#define islower(c) __C_islower(c) +#define isprint(c) __C_isprint(c) +#define ispunct(c) __C_ispunct(c) +#define isupper(c) __C_isupper(c) + +#define tolower(c) __C_tolower(c) +#define toupper(c) __C_toupper(c) + +#endif /* __UCLIBC_HAS_LOCALE__ */ + +#endif /* __NO_CTYPE */ + __END_DECLS -#endif /* __CTYPE_H */ +#endif /* _CTYPE_H */ diff --git a/include/inttypes.h b/include/inttypes.h index 6c1553f58..b81e73179 100644 --- a/include/inttypes.h +++ b/include/inttypes.h @@ -27,7 +27,7 @@ /* Get the type definitions. */ #include -#if 0 +#if __UCLIBC_HAS_WCHAR__ /* Get a definition for wchar_t. But we must not define wchar_t itself. */ #ifndef ____gwchar_t_defined # ifdef __cplusplus @@ -311,7 +311,7 @@ extern intmax_t strtoimax (__const char *__restrict __nptr, extern uintmax_t strtoumax (__const char *__restrict __nptr, char ** __restrict __endptr, int __base) __THROW; -#if 0 +#if __UCLIBC_HAS_WCHAR__ /* Like `wcstol' but convert to `intmax_t'. */ extern intmax_t wcstoimax (__const __gwchar_t *__restrict __nptr, __gwchar_t **__restrict __endptr, int __base) diff --git a/include/langinfo.h b/include/langinfo.h index 3d0e7e8f0..109923ff5 100644 --- a/include/langinfo.h +++ b/include/langinfo.h @@ -23,7 +23,7 @@ /* Get the type definition. */ #include -#include /* Define the __LC_* category names. */ +#include /* Define the __LC_* category names. */ __BEGIN_DECLS @@ -32,11 +32,12 @@ __BEGIN_DECLS (LC_*) and an item index within the category. Some code may depend on the item values within a category increasing monotonically with the indices. */ -#define _NL_ITEM(category, index) (((category) << 16) | (index)) +#define _NL_ITEM(category, index) \ + (((category) << __NL_ITEM_CATEGORY_SHIFT) | (index)) /* Extract the category and item index from a constructed `nl_item' value. */ -#define _NL_ITEM_CATEGORY(item) ((int) (item) >> 16) -#define _NL_ITEM_INDEX(item) ((int) (item) & 0xffff) +#define _NL_ITEM_CATEGORY(item) ((int) (item) >> __NL_ITEM_CATEGORY_SHIFT) +#define _NL_ITEM_INDEX(item) ((int) (item) & __NL_ITEM_INDEX_MASK) /* Enumeration of locale items that can be queried with `nl_langinfo'. */ @@ -157,6 +158,7 @@ enum ERA_T_FMT, /* Time in alternate era format. */ #define ERA_T_FMT ERA_T_FMT +#if 0 _NL_TIME_ERA_NUM_ENTRIES, /* Number entries in the era arrays. */ _NL_TIME_ERA_ENTRIES, /* Structure with era entries in usable form.*/ @@ -232,12 +234,14 @@ enum _NL_W_DATE_FMT, _NL_TIME_CODESET, +#endif /* 0 */ _NL_NUM_LC_TIME, /* Number of indices in LC_TIME category. */ /* LC_COLLATE category: text sorting. This information is accessed by the strcoll and strxfrm functions. These `nl_langinfo' names are used only internally. */ +#if 0 _NL_COLLATE_NRULES = _NL_ITEM (__LC_COLLATE, 0), _NL_COLLATE_RULESETS, _NL_COLLATE_TABLEMB, @@ -258,10 +262,12 @@ enum _NL_COLLATE_COLLSEQWC, _NL_COLLATE_CODESET, _NL_NUM_LC_COLLATE, +#endif /* LC_CTYPE category: character classification. This information is accessed by the functions in . These `nl_langinfo' names are used only internally. */ +#if 0 _NL_CTYPE_CLASS = _NL_ITEM (__LC_CTYPE, 0), _NL_CTYPE_TOUPPER, _NL_CTYPE_GAP1, @@ -349,6 +355,11 @@ enum _NL_CTYPE_EXTRA_MAP_13, _NL_CTYPE_EXTRA_MAP_14, _NL_NUM_LC_CTYPE, +#else /* 0 */ + _NL_CTYPE_CODESET_NAME = _NL_ITEM (__LC_CTYPE, 0), + CODESET = _NL_CTYPE_CODESET_NAME, +#define CODESET CODESET +#endif /* 0 */ /* LC_MONETARY category: formatting of monetary quantities. These items each correspond to a member of `struct lconv', @@ -413,8 +424,6 @@ enum #ifdef __USE_GNU # define N_SIGN_POSN __N_SIGN_POSN #endif - _NL_MONETARY_CRNCYSTR, -#define CRNCYSTR _NL_MONETARY_CRNCYSTR __INT_P_CS_PRECEDES, #ifdef __USE_GNU # define INT_P_CS_PRECEDES __INT_P_CS_PRECEDES @@ -439,6 +448,11 @@ enum #ifdef __USE_GNU # define INT_N_SIGN_POSN __INT_N_SIGN_POSN #endif + + _NL_MONETARY_CRNCYSTR, +#define CRNCYSTR _NL_MONETARY_CRNCYSTR + +#if 0 _NL_MONETARY_DUO_INT_CURR_SYMBOL, _NL_MONETARY_DUO_CURRENCY_SYMBOL, _NL_MONETARY_DUO_INT_FRAC_DIGITS, @@ -463,6 +477,7 @@ enum _NL_MONETARY_DECIMAL_POINT_WC, _NL_MONETARY_THOUSANDS_SEP_WC, _NL_MONETARY_CODESET, +#endif /* 0 */ _NL_NUM_LC_MONETARY, /* LC_NUMERIC category: formatting of numbers. @@ -483,15 +498,18 @@ enum #ifdef __USE_GNU # define GROUPING __GROUPING #endif +#if 0 _NL_NUMERIC_DECIMAL_POINT_WC, _NL_NUMERIC_THOUSANDS_SEP_WC, _NL_NUMERIC_CODESET, +#endif _NL_NUM_LC_NUMERIC, __YESEXPR = _NL_ITEM (__LC_MESSAGES, 0), /* Regex matching ``yes'' input. */ #define YESEXPR __YESEXPR __NOEXPR, /* Regex matching ``no'' input. */ #define NOEXPR __NOEXPR +#if 0 __YESSTR, /* Output string for ``yes''. */ #if defined __USE_GNU || (defined __USE_XOPEN && !defined __USE_XOPEN2K) # define YESSTR __YESSTR @@ -501,8 +519,10 @@ enum # define NOSTR __NOSTR #endif _NL_MESSAGES_CODESET, +#endif _NL_NUM_LC_MESSAGES, +#if 0 _NL_PAPER_HEIGHT = _NL_ITEM (__LC_PAPER, 0), _NL_PAPER_WIDTH, _NL_PAPER_CODESET, @@ -560,7 +580,7 @@ enum _NL_IDENTIFICATION_CATEGORY, _NL_IDENTIFICATION_CODESET, _NL_NUM_LC_IDENTIFICATION, - +#endif /* This marks the highest value used. */ _NL_NUM }; @@ -585,7 +605,7 @@ extern char *nl_langinfo (nl_item __item) __THROW; /* Just like nl_langinfo but get the information from the locale object L. */ extern char *__nl_langinfo_l (nl_item __item, __locale_t l); -#endif +#endif /* 0 */ __END_DECLS diff --git a/include/libgen.h b/include/libgen.h index dc3f064d3..b25254357 100644 --- a/include/libgen.h +++ b/include/libgen.h @@ -26,7 +26,6 @@ __BEGIN_DECLS /* Return directory part of PATH or "." if none is available. */ extern char *dirname (char *__path) __THROW; -#if 0 /* Return final component of PATH. This is the weird XPG version of this function. It sometimes will @@ -35,7 +34,6 @@ extern char *dirname (char *__path) __THROW; version available under the real name. */ extern char *__xpg_basename (char *__path) __THROW; #define basename __xpg_basename -#endif __END_DECLS diff --git a/include/locale.h b/include/locale.h index b3736dd11..1101bb15a 100644 --- a/include/locale.h +++ b/include/locale.h @@ -1,30 +1,51 @@ -/* locale.h - * Support international type specific characters. +/* Copyright (C) 1991,92,1995-1999,2000,2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* + * ISO C99 Standard: 7.11 Localization */ -#ifndef _LOCALE_H -#define _LOCALE_H 1 + +#ifndef _LOCALE_H +#define _LOCALE_H 1 #include -__BEGIN_DECLS +#define __need_NULL +#include +#include -#ifndef NULL -#ifdef __cplusplus -#define NULL 0 -#else -#define NULL ((void *) 0) -#endif -#endif +__BEGIN_DECLS /* These are the possibilities for the first argument to setlocale. - The code assumes that LC_ALL is the highest value, and zero the lowest. */ -#define LC_CTYPE 0 -#define LC_NUMERIC 1 -#define LC_TIME 2 -#define LC_COLLATE 3 -#define LC_MONETARY 4 -#define LC_MESSAGES 5 -#define LC_ALL 6 + The code assumes that the lowest LC_* symbol has the value zero. */ +#define LC_CTYPE __LC_CTYPE +#define LC_NUMERIC __LC_NUMERIC +#define LC_TIME __LC_TIME +#define LC_COLLATE __LC_COLLATE +#define LC_MONETARY __LC_MONETARY +#define LC_MESSAGES __LC_MESSAGES +/* #define LC_PAPER __LC_PAPER */ +/* #define LC_NAME __LC_NAME */ +/* #define LC_ADDRESS __LC_ADDRESS */ +/* #define LC_TELEPHONE __LC_TELEPHONE */ +/* #define LC_MEASUREMENT __LC_MEASUREMENT */ +/* #define LC_IDENTIFICATION __LC_IDENTIFICATION */ +#define LC_ALL __LC_ALL /* Structure giving information about numeric and monetary notation. */ @@ -70,6 +91,31 @@ struct lconv 4 The sign string immediately follows the currency_symbol. */ char p_sign_posn; char n_sign_posn; +#ifdef __USE_ISOC99 + /* 1 if int_curr_symbol precedes a positive value, 0 if succeeds. */ + char int_p_cs_precedes; + /* 1 iff a space separates int_curr_symbol from a positive value. */ + char int_p_sep_by_space; + /* 1 if int_curr_symbol precedes a negative value, 0 if succeeds. */ + char int_n_cs_precedes; + /* 1 iff a space separates int_curr_symbol from a negative value. */ + char int_n_sep_by_space; + /* Positive and negative sign positions: + 0 Parentheses surround the quantity and int_curr_symbol. + 1 The sign string precedes the quantity and int_curr_symbol. + 2 The sign string follows the quantity and int_curr_symbol. + 3 The sign string immediately precedes the int_curr_symbol. + 4 The sign string immediately follows the int_curr_symbol. */ + char int_p_sign_posn; + char int_n_sign_posn; +#else + char __int_p_cs_precedes; + char __int_p_sep_by_space; + char __int_n_cs_precedes; + char __int_n_sep_by_space; + char __int_p_sign_posn; + char __int_n_sign_posn; +#endif }; @@ -79,6 +125,40 @@ extern char *setlocale (int __category, __const char *__locale) __THROW; /* Return the numeric/monetary information for the current locale. */ extern struct lconv *localeconv (void) __THROW; +#if 0 +/* #ifdef __USE_GNU */ +/* The concept of one static locale per category is not very well + thought out. Many applications will need to process its data using + information from several different locales. Another application is + the implementation of the internationalization handling in the + upcoming ISO C++ standard library. To support this another set of + the functions using locale data exist which have an additional + argument. + + Attention: all these functions are *not* standardized in any form. + This is a proof-of-concept implementation. */ + +/* Get locale datatype definition. */ +# include + +/* Return a reference to a data structure representing a set of locale + datasets. Unlike for the CATEGORY parameter for `setlocale' the + CATEGORY_MASK parameter here uses a single bit for each category. + I.e., 1 << LC_CTYPE means to load data for this category. If + BASE is non-null the appropriate category information in the BASE + record is replaced. */ +extern __locale_t __newlocale (int __category_mask, __const char *__locale, + __locale_t __base) __THROW; + +/* Return a duplicate of the set of locale in DATASET. All usage + counters are increased if necessary. */ +extern __locale_t __duplocale (__locale_t __dataset) __THROW; + +/* Free the data associated with a locale dataset previously returned + by a call to `setlocale_r'. */ +extern void __freelocale (__locale_t __dataset) __THROW; +#endif + __END_DECLS #endif /* locale.h */ diff --git a/include/stdint.h b/include/stdint.h index cfd11d4f2..ba0a79037 100644 --- a/include/stdint.h +++ b/include/stdint.h @@ -24,11 +24,9 @@ #define _STDINT_H 1 #include -#if 0 -/*#define __need_wchar_t*/ -#include -#endif -/*#include */ +#ifdef __UCLIBC_HAS_WCHAR__ +#include +#endif /* __UCLIBC_HAS_WCHAR__ */ #include /* Exact integral types. */ @@ -280,18 +278,18 @@ typedef unsigned long long int uintmax_t; # define SIZE_MAX (4294967295U) # endif -#if 0 +#ifdef __UCLIBC_HAS_WCHAR__ /* Limits of `wchar_t'. */ # ifndef WCHAR_MIN /* These constants might also be defined in . */ # define WCHAR_MIN __WCHAR_MIN # define WCHAR_MAX __WCHAR_MAX # endif -#endif /* Limits of `wint_t'. */ # define WINT_MIN (0u) # define WINT_MAX (4294967295u) +#endif /* __UCLIBC_HAS_WCHAR__ */ #endif /* C++ && limit macros */ diff --git a/include/stdlib.h b/include/stdlib.h index 302f2819a..1920e418a 100644 --- a/include/stdlib.h +++ b/include/stdlib.h @@ -27,7 +27,7 @@ /* Get size_t, wchar_t and NULL from . */ #define __need_size_t #ifndef __need_malloc_and_calloc -#if 0 +#ifdef __UCLIBC_HAS_WCHAR__ # define __need_wchar_t #endif # define __need_NULL @@ -130,10 +130,10 @@ __extension__ typedef struct #define EXIT_SUCCESS 0 /* Successful exit status. */ -#if 0 +#ifdef __UCLIBC_HAS_WCHAR__ /* Maximum length of a multibyte character in the current locale. */ -#define MB_CUR_MAX (__ctype_get_mb_cur_max ()) -extern size_t __ctype_get_mb_cur_max (void) __THROW; +#define MB_CUR_MAX (_stdlib_mb_cur_max ()) +extern size_t _stdlib_mb_cur_max (void) __THROW; #endif /* Convert a string to a floating-point number. */ @@ -776,7 +776,7 @@ extern int qfcvt_r (long double __value, int __ndigit, # endif /* misc */ #endif /* use MISC || use X/Open Unix */ -#if 0 +#ifdef __UCLIBC_HAS_WCHAR__ /* Return the length of the multibyte character in S, which is no longer than N. */ extern int mblen (__const char *__s, size_t __n) __THROW; @@ -796,7 +796,7 @@ extern size_t mbstowcs (wchar_t *__restrict __pwcs, extern size_t wcstombs (char *__restrict __s, __const wchar_t *__restrict __pwcs, size_t __n) __THROW; -#endif +#endif /* def __UCLIBC_HAS_WCHAR__ */ #ifdef __USE_SVID /* Determine whether the string value of RESPONSE matches the affirmation -- cgit v1.2.3