From 077f5299c77890c55e7ac28553166d16d4a35bd8 Mon Sep 17 00:00:00 2001 From: "Steffen (Daode) Nurpmeso" Date: Thu, 29 Jun 2017 16:33:12 +0200 Subject: [PATCH] Add n_locale_init(), track $LC_{ALL,CTYPE} and $LANG (for *ttycharset*) --- accmacvar.c | 7 +++++++ auxlily.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++ main.c | 35 +-------------------------------- nail.1 | 64 ++++++++++++++++++++++++++++++++++++++++--------------------- nail.h | 3 +++ nailfuns.h | 3 +++ 6 files changed, 106 insertions(+), 56 deletions(-) diff --git a/accmacvar.c b/accmacvar.c index f104c50f..fac13e77 100644 --- a/accmacvar.c +++ b/accmacvar.c @@ -910,6 +910,13 @@ a_amv_var_check_vips(enum a_amv_var_vip_mode avvm, enum okeys okey, *x = '\0'; n_PS_ROOT_BLOCK(ok_vset(ifs_ws, x_b)); } break; +#ifdef HAVE_SETLOCALE + case ok_v_LANG: + case ok_v_LC_ALL: + case ok_v_LC_CTYPE: + n_locale_init(); + break; +#endif case ok_b_memdebug: n_poption |= n_PO_MEMDEBUG; break; diff --git a/auxlily.c b/auxlily.c index 1e0f6b90..13a9948a 100644 --- a/auxlily.c +++ b/auxlily.c @@ -53,6 +53,13 @@ # include #endif +#ifdef HAVE_NL_LANGINFO +# include +#endif +#ifdef HAVE_SETLOCALE +# include +#endif + #ifndef HAVE_POSIX_RANDOM union rand_state{ struct rand_arc4{ @@ -298,6 +305,49 @@ a_aux_err_map_from_no(si32_t eno){ return aemp; } +FL void +n_locale_init(void){ + NYD2_ENTER; + + n_psonce &= ~(n_PSO_UNICODE | n_PSO_ENC_MBSTATE); + +#ifndef HAVE_SETLOCALE + n_mb_cur_max = 1; +#else + setlocale(LC_ALL, n_empty); + n_mb_cur_max = MB_CUR_MAX; +# ifdef HAVE_NL_LANGINFO + /* C99 */{ + char const *cp; + + /* TODO *ttycharset* may be set several times during startup unless + * TODO we gain a mechanism that -S fixates a setting during startup, + * TODO effectively turning later adjustments (during startup) in noop */ + if((cp = nl_langinfo(CODESET)) != NULL) + ok_vset(ttycharset, cp); + } +# endif + +# ifdef HAVE_C90AMEND1 + if(n_mb_cur_max > 1){ +# ifdef HAVE_ALWAYS_UNICODE_LOCALE + n_psonce |= n_PSO_UNICODE; +# else + wchar_t wc; + if(mbtowc(&wc, "\303\266", 2) == 2 && wc == 0xF6 && + mbtowc(&wc, "\342\202\254", 3) == 3 && wc == 0x20AC) + n_psonce |= n_PSO_UNICODE; + /* Reset possibly messed up state; luckily this also gives us an + * indication whether the encoding has locking shift state sequences */ + if(mbtowc(&wc, NULL, n_mb_cur_max)) + n_psonce |= n_PSO_ENC_MBSTATE; +# endif + } +# endif +#endif + NYD2_LEAVE; +} + FL size_t n_screensize(void){ char const *cp; diff --git a/main.c b/main.c index c1c56b9d..3141e081 100644 --- a/main.c +++ b/main.c @@ -43,13 +43,6 @@ #include -#ifdef HAVE_NL_LANGINFO -# include -#endif -#ifdef HAVE_SETLOCALE -# include -#endif - struct a_arg{ struct a_arg *aa_next; char const *aa_file; @@ -351,33 +344,7 @@ a_main_startup(void){ n_psonce |= n_PSO_BIG_ENDIAN; } -#ifndef HAVE_SETLOCALE - n_mb_cur_max = 1; -#else - setlocale(LC_ALL, n_empty); - n_mb_cur_max = MB_CUR_MAX; -# ifdef HAVE_NL_LANGINFO - if((cp = nl_langinfo(CODESET)) != NULL) - ok_vset(ttycharset, cp); -# endif - -# ifdef HAVE_C90AMEND1 - if(n_mb_cur_max > 1){ -# ifdef HAVE_ALWAYS_UNICODE_LOCALE - n_psonce |= n_PSO_UNICODE; -# else - wchar_t wc; - if(mbtowc(&wc, "\303\266", 2) == 2 && wc == 0xF6 && - mbtowc(&wc, "\342\202\254", 3) == 3 && wc == 0x20AC) - n_psonce |= n_PSO_UNICODE; - /* Reset possibly messed up state; luckily this also gives us an - * indication whether the encoding has locking shift state sequences */ - if(mbtowc(&wc, NULL, n_mb_cur_max)) - n_psonce |= n_PSO_ENC_MBSTATE; -# endif - } -# endif -#endif + n_locale_init(); #ifdef HAVE_ICONV iconvd = (iconv_t)-1; diff --git a/nail.1 b/nail.1 index 8febf43d..a38143a2 100644 --- a/nail.1 +++ b/nail.1 @@ -544,6 +544,7 @@ via may be overwritten from within resource files, the command line setting will be reestablished after all resource files have been loaded in the order they have been given on the command line. +(\*(ID In the future such a setting may be in frozen state during startup.) . .Mx .It Fl s Ar subject @@ -1590,21 +1591,18 @@ mechanisms that are controlled by the .Ev LC_ALL , or .Ev LANG , -in that order) locale setting -.Pf ( Xr setlocale 3 -should give an overview): the \*(UA internal variable +in that order; see there) environment variable, the internal variable .Va ttycharset will be set to the detected terminal character set accordingly, -and will thus show up in the output of the commands +and will thus show up in the output of commands like, e.g., .Ic set and .Ic varshow . . .Pp -However, a user supplied +However, the user may give a value for .Va ttycharset -value is not overwritten by this detection mechanism. -I.e., it is actually possible to send mail in a completely +during startup, so that it is possible to send mail in a completely .Dq faked locale environment, an option which can be used to generate and send, e.g., 8-bit UTF-8 input data in a pure 7-bit US-ASCII @@ -1617,8 +1615,7 @@ of the system, which stays unaffected by .Va ttycharset . . .Pp -If no character set conversion capabilities have been compiled into -\*(UA +If the \*(OPal character set conversion capabilities are not available .Pf ( Va features does not include the term .Ql +iconv ) , @@ -1636,7 +1633,7 @@ detection fails, since in that case it defaults to LATIN1 a.k.a. ISO-8859-1. . .Pp -When reading messages, their text is converted into +\*(OP When reading messages, their text is converted into .Va ttycharset as necessary in order to display them on the users terminal. Unprintable characters and invalid byte sequences are detected @@ -5699,14 +5696,25 @@ Takes a message list and marks all messages as having been read. .Mx .Mx .It Ic set , unset -(se, \*(NQ uns) The latter commands will delete all given variables, +(se, \*(NQ uns) The latter command will delete all given variables, the former, when used without arguments, will show all variables which -are currently known to \*(UA; a more verbose listing will be produced if +are currently known to \*(UA; this will not automatically link-in +.Sx ENVIRONMENT +variables which are known to \*(UA even if they exist in the program +environment: only explicit addressing of variables, e.g., via +.Ic varshow , +using a variable in a +.Ic if +condition or a string passed to +.Ic echo , +or via program-internal use cases will perform this task. +A more verbose listing will be produced if either of .Va debug or .Va verbose are set. +. .Pp Otherwise the given variables (and arguments) are set or adjusted. Arguments are of the form @@ -5716,10 +5724,17 @@ Arguments are of the form or plain .Ql name if there is no value, i.e., a boolean variable. -Quotation marks may be placed around any part of the assignment -statement to quote blanks or tabs, e.g., +\*(ID In conjunction with the +.Cm wysh +command prefix +.Sx "Shell-style argument quoting" +can be used to quote arguments as necessary. +\*(ID Otherwise quotation marks may be placed around any part of the +assignment statement to quote blanks or tabs. +. .Pp -.Dl set indentprefix='->' +.Dl wysh set indentprefix=' -> ' +. .Pp If an argument begins with .Ql no , @@ -5729,6 +5744,7 @@ the effect is the same as invoking the .Ic unset command with the remaining part of the variable .Pf ( Ql unset save ) . +. .Pp Any .Ql name @@ -10897,9 +10913,9 @@ The character set of the terminal \*(UA operates on, and the one and only supported character set that \*(UA can use if no character set conversion capabilities have been compiled into it, in which case it defaults to ISO-8859-1 unless it can deduce a value -from the +from the locale specified in the .Ev LC_CTYPE -locale environment. +environment variable (if supported, see there for more). It defaults to UTF-8 if conversion is available. Refer to the section .Sx "Character sets" @@ -11072,13 +11088,17 @@ This variable is only used when it resides in the process environment. .Mx .Mx .Mx -.Mx -.Mx -.It Ev LANG , LC_ALL , LC_COLLATE , LC_CTYPE , LC_MESSAGES -See +.It Ev LC_ALL , LC_CTYPE , LANG +\*(OP The (names in lookup order of the) .Xr locale 7 -and +(and / or see +.Xr setlocale 3 ) +which indicates the used .Sx "Character sets" . +Runtime changes trigger automatic updates of the entire locale system, +updating and overwriting also a +.Va ttycharset +set by the user. . .Mx .It Ev LINES diff --git a/nail.h b/nail.h index fb0d3601..65ae5250 100644 --- a/nail.h +++ b/nail.h @@ -1588,6 +1588,9 @@ ok_v_fwdheading, ok_b_keep_content_length, ok_b_keepsave, + ok_v_LANG, /* {vip=1,env=1,notempty=1} */ + ok_v_LC_ALL, /* {name=LC_ALL,vip=1,env=1,notempty=1} */ + ok_v_LC_CTYPE, /* {name=LC_CTYPE,vip=1,env=1,notempty=1} */ ok_v_LINES, /* {notempty=1,posnum=1,env=1} */ ok_v_LISTER, /* {env=1,notempty=1,defval=VAL_LISTER} */ ok_v_LOGNAME, /* {rdonly=1,import=1} */ diff --git a/nailfuns.h b/nailfuns.h index f735cf6d..5ced1e7d 100644 --- a/nailfuns.h +++ b/nailfuns.h @@ -279,6 +279,9 @@ FL ssize_t n_attachment_list_print(struct attachment const *aplist, FILE *fp); * auxlily.c */ +/* setlocale(3), *ttycharset* etc. */ +FL void n_locale_init(void); + /* Compute screen size */ FL size_t n_screensize(void); -- 2.11.4.GIT