1.9.2 readline can't handle cursorkeys, mbcs chars etc (msvcrt)

artonです。

ちょっと迷いがあるので、gdgdな長文ですみません。
現象)
ruby-1.9.2-p0のext/readline と GNU readline 4.3-2 (win32) で、カーソルキー
や、Homeキー、Endキーなどが処理されません。また、IMEを有効にした漢字入力
が行えません(MSBがオフのバイトのみが処理される)。
これは、MSWin32だけではなくMingwでも同様のはずです。
åŽŸå› ï¼‰
特殊キーが処理できない問題と、漢字入力ができない問題はそれぞれ異なる原å›
です。
特殊キーが処理できないのは、win32.cがコンソール読み込みに利用している
ReadFile Win32APIがカーソルキーなどの特殊キーを無視することと(Windowsで
はこれらのキーに文字列(エスケープシーケンス)が割り当てられていないため、
そもそも処理できない)です。
漢字入力ができないのは、ext/readlineが読み込みに利用しているIO.getbyteが
charを返すためlibreadlineが期待しているintにするときに符号拡張されて2バ
イトコードを構成する文字コードと判断されないためです。
対応案)
後者については、汎用性があるので0xffでマスクする修正で良いのですが、それ
では前者が救われません。人によるとは思いますが、カーソルキーやHomeキーな
どを利用したいユーザも存在するので、できれば前者も救いたいと思います。
それで、キー入力の有無を判定して無ければスレッド切り替え器を呼び出し、有
ればlibreadlineのキー入力処理を呼び出す添付のパッチを作ったのですが、GNU
readline 4.3.2のWin32ポーティング版に依存した修正なのが気に食わない点で
す。
別案)
というわけで、win32.cの中でコンソール入力時にはReadFile APIではなく
ReadConsoleInput APIのようにキーコードを取れるAPIを利用して、その結果を
ANSIのコードに変換し(たとえば↑ならCSI (ESC [)A)、libreadlineについて
は現在のwin32ポーティング版とは別に(利用したい人が)用意する、というの
が良いのではないかと思います。
結論)
とりあえず、現在のMSWIN32でのext/readlineはカーソルキーなどのハンドリン
グができず、漢字入力にバグがあります。添付のパッチで修正できます
(test/readline/test_readline* が通るのは確認しています)。なので、当てて
いただけると短期的には嬉しいです。
が、可能なら汎用的に外部ライブラリとインターフェイスできるように、特殊キー
をANSIコードに変換すると良いなぁと考えます。

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

e$B$9$_$^$;$s!#%H%7$N$;$$$+D9J8FI2rG=NO$,Mn$A$F$$$k$N$G!“3NG’$Ge(B
e$B$9$,!”:#2s$N%a!<%k$NK<A$Oe(B

In message “Re: [ruby-dev:42232] 1.9.2 readline can’t handle cursorkeys,
mbcs chars etc (msvcrt)”
on Sat, 11 Sep 2010 00:55:20 +0900, arton [email protected]
writes:

|e$B$H$j$"$($:!"8=:_$Ne(BMSWIN32e$B$G$Ne(Bext/readlinee$B$O%+!<%=%k%-!<$J$I$N%O%s%I%j%se(B
|e$B%0$,$G$-$:!“4A;zF~NO$K%P%0$,$”$j$^$9!#E:IU$N%Q%C%A$G=$@5$G$-$^$9e(B
|(test/readline/test_readline* e$B$,DL$k$N$O3NG’$7$F$$$^$9e(B)e$B!#$J$N$G!"Ev$F$Fe(B
|e$B$$$?$@$1$k$HC;4|E*$K$O4r$7$$$G$9!#e(B

e$B$H$$$&$3$H$G$9$M!#$3$l$rEv$F$k$V$s$K$O9=$$$^$;$s!#e(Bartone$B$5$s$,e(B
e$B$4<+J,$GEv$F$F$/$@$5$k$H$h$$$H;W$$$^$9$,!“%3%%C%H8"$O$*;}$Ae(B
e$B$G$J$+$C$?$s$G$7$?$C$1!#%3%
%C%?!<$K$J$k$N$,LLE]$J$I$NM}M3$,e(B
e$B$”$l$P!"Be9T$7$F$b9=$$$^$;$s$,!"e(BWindows e$B$N$3$H$,J,$+$k?M$NJ}e(B
e$B$,NI$$$+$J!#e(BUsae$B$5$s$H$+!#e(B

|e$B$,!"2DG=$J$iHFMQE*$K30It%i%$%V%i%j$H%$%s%?!<%U%'%$%9$G$-$k$h$&$K!"FC<l%-!<e(B
|e$B$re(BANSIe$B%3!<%I$KJQ49$9$k$HNI$$$J$!$H9M$($^$9!#e(B

e$B$3$l$OGyA3$H$7$?I=8=$G$9$,!"$3$l$N0UL#$9$k$H$3$m$Oe(B

  • artone$B$5$s$,$d$k!#e(B(e$BK;$7$$$N$G!)e(B)e$B4|8B$OL$Dje(B
  • e$B$d$i$J$$$+$b!#C/$+$d$C$F$/$l$J$$$@$m$&$+e(B
  • e$B$=$N$[$+e(B

e$B$N$$$:$l$J$s$G$9$+$M!#e(B

artone$B$G$9!#e(B

e$B$H$$$&$3$H$G$9$M!#$3$l$rEv$F$k$V$s$K$O9=$$$^$;$s!#e(B
e$B$"$j$,$H$&$4$6$$$^$9!#e(B

artone$B$5$s$,e(B
e$B$4<+J,$GEv$F$F$/$@$5$k$H$h$$$H;W$$$^$9$,!“%3%%C%H8"$O$*;}$Ae(B
e$B$G$J$+$C$?$s$G$7$?$C$1!#%3%
%C%?!<$K$J$k$N$,LLE]$J$I$NM}M3$,e(B
e$B$”$l$P!"Be9T$7$F$b9=$$$^$;$s$,!"e(BWindows e$B$N$3$H$,J,$+$k?M$NJ}e(B
e$B$,NI$$$+$J!#e(BUsae$B$5$s$H$+!#e(B
e$B$$$d!“LLE]$H$$$&$3$H$O$”$j$^$;$s!#$h$m$7$1$l$P%3%_%C%?!<$K$7$F$$$?$@$1$le(B
e$B$P4r$7$$$G$9!#e(B

  • artone$B$5$s$,$d$k!#e(B(e$BK;$7$$$N$G!)e(B)e$B4|8B$OL$Dje(B
  • e$B$d$i$J$$$+$b!#C/$+$d$C$F$/$l$J$$$@$m$&$+e(B
  • e$B$=$N$[$+e(B

e$B$N$$$:$l$J$s$G$9$+$M!#e(B
1e$B$GLdBj$J$$$N$G$9$,!"$3$N=$@5$r9T$&$He(Brubye$B$NF0:n$,%(%s%I%f!<%6$N%l%Y%k$Ge(B
e$BJQ$o$C$F$7$^$$$^$9!#e(B
e$B$?$H$($P!“8=:L50z?t$G5/F0$7$FI8=`F~NO$+$iFI$^$;$k$H!“%+!<%=%k%-!<$Oe(B
Windowse$B$N%R%9%H%j!<5!G=$,F/$-$^$9$,!”$3$l$,e(BANSIe$B%3!<%I$K$J$k$N$OLdBj!#e(B
e$B$7$?$,$C$F!“C1$KF~$l$k$@$1$G$O$J$/!”%3%s%=!<%kFI$
<h$j$Ne(BCooke$B%b!<%I$He(BRaw
e$B%b!<%I$N@Z$jBX$(e(BAPIe$B$,I,MW$G$O$J$$$+!”$H$+!"e(Blibreadlinee$B$N%?!<%2%C%H<BAue(B
e$B!JGyA3$He(Blibedite$B$r9M$($F$$$^$9$,!“e(BMBCSe$BHsBP1~$J$ILdBj$b$”$j!K$rA[Dj$7$J$$e(B
e$B$H0UL#$,$J$$$H$+!“O@E@$,$$$/$D$+$”$j$^$9!#e(B
e$B$*$=$i$/%Y%9%H$J$N$O<!$N0BDjHD%j%j!<%9;~$K!"e(Bwin32e$BHGe(Brubye$B$,AH$9g$o$;$r?de(B
e$B>)$9$k%i%$%V%i%j$H$7$Fe(Blibedite$B$Ne(Bwin32e$B%]!<%H!JFC<l%-!<$Oe(BANSIe$B%3!<%I$GAw$i$le(B
e$B$F$/$k$3$H$rA[Dj!K$rMQ0U$7$?$&$($G!">e5-$N=$@5$rF~$l$k!J4{DjF0:n$O8=:
$He(B
e$BF1$8$G$=$l$re(BRawe$B%b!<%I$H$7!"e(BCooke$B%b!<%I$OFC<l%-!<$Ne(BANSIe$B%3!<%IJQ49$He(BMBCSe$B$Ne(B
UTF-8e$BJQ49$H$7!“e(Bext/readlinee$B$,e(BCooke$B%b!<%I$X@Z$jBX$($k!K$3$H$G$9!J>/$J$/$He(B
e$B$b;d$K$H$C$F$O!K!#e(B
e$B$,!”$3$l$Oe(BWin32e$B$@$1$G$O$J$/e(BWin64e$B$K$b4X78$7$F$/$k$N$G!"e(BUsae$B$5$s$d@.@%$5$se(B
e$B$N0U8+$b$*J9$-$7$?$$$H$3$m$G$9!#e(B


arton [email protected]

(2010/09/11 11:45), arton wrote:

e$B$$$d!“LLE]$H$$$&$3$H$O$”$j$^$;$s!#$h$m$7$1$l$P%3%_%C%?!<$K$7$F$$$?$@$1$le(B
e$B$P4r$7$$$G$9!#e(B

e$B$H$j$“$($:e(B arton
e$B$5$s$O%3%_%C%?!=$K$J$C$FD:$1$k$H$$$m$$$m$H$”$j$,$?$$$G$9!#e(B

e$B%b!<%I$N@Z$jBX$(e(BAPIe$B$,I,MW$G$O$J$$$+!"$H$+!"e(Blibreadlinee$B$N%?!<%2%C%H<BAue(B
e$B!JGyA3$He(Blibedite$B$r9M$($F$$$^$9$,!“e(BMBCSe$BHsBP1~$J$ILdBj$b$”$j!K$rA[Dj$7$J$$e(B
e$B$H0UL#$,$J$$$H$+!“O@E@$,$$$/$D$+$”$j$^$9!#e(B
e$B$*$=$i$/%Y%9%H$J$N$O<!$N0BDjHD%j%j!<%9;~$K!"e(Bwin32e$BHGe(Brubye$B$,AH$9g$o$;$r?de(B
e$B>)$9$k%i%$%V%i%j$H$7$Fe(Blibedite$B$Ne(Bwin32e$B%]!<%H!JFC<l%-!<$Oe(BANSIe$B%3!<%I$GAw$i$le(B
e$B$F$/$k$3$H$rA[Dj!K$rMQ0U$7$?$&$($G!">e5-$N=$@5$rF~$l$k!J4{DjF0:n$O8=:
$He(B
e$BF1$8$G$=$l$re(BRawe$B%b!<%I$H$7!"e(BCooke$B%b!<%I$OFC<l%-!<$Ne(BANSIe$B%3!<%IJQ49$He(BMBCSe$B$Ne(B
UTF-8e$BJQ49$H$7!“e(Bext/readlinee$B$,e(BCooke$B%b!<%I$X@Z$jBX$($k!K$3$H$G$9!J>/$J$/$He(B
e$B$b;d$K$H$C$F$O!K!#e(B
e$B$,!”$3$l$Oe(BWin32e$B$@$1$G$O$J$/e(BWin64e$B$K$b4X78$7$F$/$k$N$G!"e(BUsae$B$5$s$d@.@%$5$se(B
e$B$N0U8+$b$*J9$-$7$?$$$H$3$m$G$9!#e(B

e$B$$$6$C$Q$JM}2r!u[#Kf$J5-21$J$N$G%"%l$J$s$G$9$,!"e(B
e$B$^$:!"e(B1.9 e$B$Oe(B Windows e$B$G$Oe(B W e$B7O$Ne(B API
e$B$rMQ$$$k$h$&$K$7$F$$$/J}?K$G!"e(B
e$B$=$l$rDL>o$O8_49@-$N$?$a$Ke(B CP932
e$B$KJQ49$7$FEO$9$h$&$K$7$F$$$^$9!#e(B

e$B$G!"%3%s%=!<%k$K$D$$$F$b$=$&$$$&M=Dj$@$C$?$h$&$J5$$,$9$k$N$G!"e(B
ReadConsoleInputW e$B$r;H$&$N$G$O$J$$$+$H;W$$$^$9!#e(B

e$B$J$!"e(Blibedit e$B$O:G6a<B83E$Ke(B UTF-8
e$B%5%]!<%H$,F~$C$F$$$^$9!#e(B

artone$B$G$9!#e(B

e$B$$$6$C$Q$JM}2r!u[#Kf$J5-21$J$N$G%"%l$J$s$G$9$,!"e(B
e$B$^$:!"e(B1.9 e$B$Oe(B Windows e$B$G$Oe(B W e$B7O$Ne(B API e$B$rMQ$$$k$h$&$K$7$F$$$/J}?K$G!“e(B
e$B$=$l$rDL>o$O8_49@-$N$?$a$Ke(B CP932 e$B$KJQ49$7$FEO$9$h$&$K$7$F$$$^$9!#e(B
e$B$G!”%3%s%=!<%k$K$D$$$F$b$=$&$$$&M=Dj$@$C$?$h$&$J5$$,$9$k$N$G!“e(B
ReadConsoleInputW e$B$r;H$&$N$G$O$J$$$+$H;W$$$^$9!#e(B
e$B$J$k$[$I!#$=$l$,NI$$$G$9$M!#e(BCP932 e$B”>e(B
Unicodee$B$J$N$G!J87L)$K$o$+$C$F=q$$$Fe(B
e$B$$$k$N$G$O$J$$$G$9$,!K!#e(B

e$B$J$!"e(Blibedit e$B$O:G6a<B83E$Ke(B UTF-8 e$B%5%]!<%H$,F~$C$F$$$^$9!#e(B
e$B<B$O$3$l$r8+$?$N$G!“e(BUTF-8e$B$KJQ49$9$k$N$,NI$$$+$J!”$H;W$C$?$N$G$7$?!#e(B


arton [email protected]

e$B$3$s$K$A$O!"$J$+$`$ie(B(e$B$&e(B)e$B$G$9!#e(B

In message “[ruby-dev:42233] Re: 1.9.2 readline can’t handle cursorkeys,
mbcs chars etc (msvcrt)”
on Sep.11,2010 04:08:25, [email protected] wrote:

e$B$H$$$&$3$H$G$9$M!#$3$l$rEv$F$k$V$s$K$O9=$$$^$;$s!#e(Bartone$B$5$s$,e(B
e$B$4<+J,$GEv$F$F$/$@$5$k$H$h$$$H;W$$$^$9$,!“%3%%C%H8"$O$*;}$Ae(B
e$B$G$J$+$C$?$s$G$7$?$C$1!#%3%
%C%?!<$K$J$k$N$,LLE]$J$I$NM}M3$,e(B
e$B$”$l$P!"Be9T$7$F$b9=$$$^$;$s$,!"e(BWindows e$B$N$3$H$,J,$+$k?M$NJ}e(B
e$B$,NI$$$+$J!#e(BUsae$B$5$s$H$+!#e(B

e$B$=$Ne(B1e$B!#e(B
e$B:#2s$NOC$N@'Hs$OJL$H$7$F!"e(Bartone$B$5$s$K%3%_%C%?$K$J$C$F$b$i$&$Ne(B
e$B$O$h$$$3$H$J$N$G$O$J$$$+$H;W$$$^$9!#<g$K;d$NET9gE*$K!#e(B

e$B$=$Ne(B2e$B!#e(B
readlinee$B$N%Q%C%A$Oe(Breadlinee$B$N%a%s%F%J$,H=CG$9$Y$-$@$H;W$$$^$9!#e(B
e$B$A$c$s$HB8:_$9$k$s$@$+$i$d$C$F$b$i$$$^$7$g$&!#e(B
e$B9bHx$5$s8+$F$^$9$+!<e(B?

e$B$=$Ne(B3e$B!#e(B
e$B$G!“C/$,=&$&$K$7$F$b!”%A%1%C%H$H$7$FEPO?$9$Y$-$8$c$J$$$G$9$+e(B
e$B$M!#e(B
ruby
1.9e$B$Ne(Bbuge$B%A%1%C%H$H$7$F%a%s%F%J$K%"%5%$%s$7$?>uBV$G%A%1%Ce(B
e$B%H$rEPO?$9$k$3$H$r?d>)$7$^$9!#e(B

|e$B$,!"2DG=$J$iHFMQE*$K30It%i%$%V%i%j$H%$%s%?!<%U%'%$%9$G$-$k$h$&$K!"FC<l%-!<e(B
|e$B$re(BANSIe$B%3!<%I$KJQ49$9$k$HNI$$$J$!$H9M$($^$9!#e(B

e$B4{$K@.@%$5$s$,JV;v$7$F$^$9$1$I!"e(BANSIe$B%3!<%I$KJQ49$9$k$h$&$J%3e(B
e$B!<%I$r:#$+$i?75,$K:n$C$FF~$l$k$N$O$A$g$C$H$J$$$G$7$g$&$M!#e(B

e$B$=$l$G$O!#e(B

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:42243] Re: 1.9.2 readline can’t handle
cursorkeys, mbcs chars etc (msvcrt)”
on Mon, 13 Sep 2010 12:39:53 +0900, “U.Nakamura”
[email protected] writes:

|e$B$=$Ne(B2e$B!#e(B
|readlinee$B$N%Q%C%A$Oe(Breadlinee$B$N%a%s%F%J$,H=CG$9$Y$-$@$H;W$$$^$9!#e(B
|e$B$A$c$s$HB8:_$9$k$s$@$+$i$d$C$F$b$i$$$^$7$g$&!#e(B
|e$B9bHx$5$s8+$F$^$9$+!<e(B?

e$B8+$F$k$+$J$"!#$A$g$C$HK;$7$=$&$G$9!#D9$$$3$H4i8+$F$J$$$J!<!#e(B

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:42234] Re: 1.9.2 readline can’t handle
cursorkeys, mbcs chars etc (msvcrt)”
on Sat, 11 Sep 2010 11:45:29 +0900, arton [email protected]
writes:

|e$B$$$d!“LLE]$H$$$&$3$H$O$”$j$^$;$s!#$h$m$7$1$l$P%3%_%C%?!<$K$7$F$$$?$@$1$le(B
|e$B$P4r$7$$$G$9!#e(B

[email protected]$B$Ke(Bpgpe$B$G%5%$%s$7$?e(Bssh2e$B8x3+80$H4uK>$9$ke(B
e$B%"%+%&%s%HL>e(B(arton?)e$B$rAw$C$F2<$5$$!#e(B

artone$B$G$9!#e(B

e$B$=$Ne(B2e$B!#e(B
readlinee$B$N%Q%C%A$Oe(Breadlinee$B$N%a%s%F%J$,H=CG$9$Y$-$@$H;W$$$^$9!#e(B
e$B$A$c$s$HB8:_$9$k$s$@$+$i$d$C$F$b$i$$$^$7$g$&!#e(B
e$B9bHx$5$s8+$F$^$9$+!<e(B?
e$B$3$l$O;?@.$G$9$,!"e(B

e$B$=$Ne(B3e$B!#e(B
e$B$G!“C/$,=&$&$K$7$F$b!”%A%1%C%H$H$7$FEPO?$9$Y$-$8$c$J$$$G$9$+e(B
e$B$M!#e(B
ruby 1.9e$B$Ne(Bbuge$B%A%1%C%H$H$7$F%a%s%F%J$K%"%5%$%s$7$?>uBV$G%A%1%Ce(B
e$B%H$rEPO?$9$k$3$H$r?d>)$7$^$9!#e(B
e$B%P%0$J$s$G$9$+$M!)e(B e$B$^$?%P%0$H$7$F!"2?$N%P%0$G$7$g$&$+!)e(B
e$B$=$3$,85!9LB$C$Fe(B
e$B%A%1%C%H$r@Z$i$J$+$C$?M}M3$G$9!#!Je(BWin32e$B$G;H$&$N$,%P%0$H$$$&$N$OL5$7$H$7e(B
e$B$F!Ke(B

  1. Win32e$BHG$N%P%0e(B e$B!D!De(B
    e$B%+!<%=%k%-!<$J$I$rFI$_9~$s$G$$$J$$$N$,%P%0e(B
  2. ext/readlinee$B$N%P%0e(B e$B!D!De(B
    Win32e$B$Ne(BSTDIN.getbytee$B$OFC<l%-!<$rL5;k$9$k!J;Ee(B
    e$BMM!)!K$N$@$+$i!"e(Blibreadlinee$B$Ne(Bgetce$B$r8F$S=P$9$h$&$K$9$k!J;d$N%Q%C%A$O$3$Ne(B
    e$B9M$(!Ke(B
  3. 2e$B$Ge(BFAe$B$@$H$7$F$b!"e(BGNU readline
    e$B$Ne(BWin32e$B%5%]!<%H$O=N;$7$F$7$^$C$?$N$G!“e(B
    e$BBeBX%i%$%V%i%j$NMxMQ$J$I$r9M$($?$$$H$3$me(B(e$B”(e(B)e$B!#$=$N4QE@$+$i$O!“e(B1e$B$H$$$&$3e(B
    e$B$H$K$7$?$$$J$!!#$=$N>l9g!“J8;z%3!<%I$H$7$F$OFI$a$J$$FC<l%-!<$r$I$&=hM}$9e(B
    e$B$k$N$,NI$$!)e(B
    e$B”(!K$H$$$&$+!“FC<l%-!<$re(Breadlinee$BFbIt$GJ#?tJ8;z$K3d$jEv$F$k$?$a!”$=$NH=CGe(B
    e$B$re(Bext/readlinee$B$,$7$J$1$l$P$J$i$J$$;~E@$G!”:$$C$?46$,I:$C$F$$$^$9!#$
    $=$ie(B
    e$B$/CY$$%^%7%s$@$H%-!<O"B3F~NO;~$K!“e(Blibreadlinee$B$Ne(Bgetce$B$r8F$VJ}K!$@$He(B
    libreadlinee$B$,F~NO$r%Z%s%G%#%s%0$7$F$$$k$3$H$,30It$+$i$OH=CG$G$-$J$$$N$G!“e(B
    e$B8eB3$NJ8;z$rFI$a$J$/$J$k$O$:$G$9!#$=$l$r2sHr$9$k$K$O!”%9%l%C%I@Z$jBX$(4oe(B
    e$B$X@)8f$r0$9$3$H<+BN$,$^$:$$$H$$$&$3$H$K$J$C$F!”$=$l$O$b$N$9$4$/7y!#e(B

e$B$H$$$&46$8$G$9!#e(B


arton [email protected]

artone$B$G$9!#e(B

e$B$=$NCf$N$I$l$rA*$s$G$be(B Ruby e$B$rD>$5$J$$$H$$$1$J$$$N$G$9$+$i!“e(B
Ruby e$B$N%P%0e(B (e$B$^$?$Oe(B Feature Request) e$B$G$”$k$3$H$OL@$i$+$G$7$g$&!#e(B
e$B$J$k$[$I!#$=$l$O$=$&$G$9$M!#e(B
e$B%A%1%C%H$r@Z$C$F$*$-$^$9!#e(B


arton [email protected]

(2010/09/13 23:44), arton wrote:

  1. 2e$B$Ge(BFAe$B$@$H$7$F$b!"e(BGNU readline e$B$Ne(BWin32e$B%5%]!<%H$O=N;$7$F$7$^$C$?$N$G!"e(B
    e$B$H$$$&46$8$G$9!#e(B
    e$B$=$NCf$N$I$l$rA
    $s$G$be(B Ruby e$B$rD>$5$J$$$H$$$1$J$$$N$G$9$+$i!“e(B
    Ruby e$B$N%P%0e(B (e$B$^$?$Oe(B Feature Request)
    e$B$G$”$k$3$H$OL@$i$+$G$7$g$&!#e(B

e$B$J$*!"e(BSTDIN.getbyte
e$B$GFC<l%-!<$r9MN8$9$k$N$OL5$$$+$J$H$$$&5$$,$7$^$9!#e(B
win32.c e$B$+!"e(Bext/readline e$B$+!"e(Bext/io/console
e$B$N$I$3$+$O$H$b$+$/!#e(B