Fish-shell: Lokal UTF-8 tidak berfungsi di DragonFly BSD, FreeBSD 11, 12

Dibuat pada 21 Mei 2016  ·  60Komentar  ·  Sumber: fish-shell/fish-shell

ketika menempatkan garis seperti:
set LANG zh_CN.UTF-8
ke .config / fish / config.fish
maka tidak dapat menghapus karakter apa pun jika perintah salah.

sebagai contoh:

kate

Saya ingin menghapus 'e' untuk perintah 'cat'
tetapi tidak dapat menghapus karakter apa pun
di bawah 2.2.0 baik-baik saja.


Versi ikan: ikan, versi 2.3.0

Sistem operasi: DragonFly testdf.com 4.4-RELEASE DragonFly v4.4.1.18.gc5db8-RELEASE # 0: Kam 28 Jan 15:02:10 CST 2016 [email protected] : / usr / obj / usr / src / sys / lhmwzy x86_64

Terminal atau emulator terminal: xterm

bug

Komentar yang paling membantu

Saya telah membuka bug FreeBSD ini. Kami masih harus menyelesaikan implementasi yang rusak ini.

Semua 60 komentar

Tombol mana yang Anda tekan? Menghapus?

Jika itu benar, jalankan bind -k backspace untuk mengetahui apa yang telah diatur, lalu jalankan mis script (atau bash dan tekan ctrl + v) dan tekan tombol untuk mencari tahu urutan mana itu mengirimkan. (Script akan secara default meletakkan seluruh output dari sesi itu ke dalam file bernama "skrip tipe" di direktori saat ini). Xterm harus mengirim "\ cH", ikan mana yang harus (melalui terminfo, yang _membutuhkan_ $ TERM untuk disetel dengan benar) diambil sebagai backspace.

Versi ikan yang akan datang akan membuatnya lebih mudah dengan program pembantu kecil yang disebut "fish_key_reader".

Setel $ TERM Anda ke apa? "xterm"?

kuncinya adalah Backspace.
tolong kirimkan saya maill, dan saya akan memberikan akses kepada Anda kotak saya, biarkan Anda mencari tahu alasannya.

kuncinya adalah Backspace.

Label pada kunci tidak memberi tahu kita urutan karakter apa yang dikirimkannya. Dapatkah Anda menginstal ikan dari sumber yang ditarik dari repositori git? Jika Anda kemudian dapat make fish_key_reader diikuti oleh ./fish_key_reader lalu tekan tombol backspace Anda. Jika Anda tidak dapat menjalankan xxd atau od -tx1z lalu tekan tombol spasi mundur diikuti oleh [ctrl-D]. Jalankan juga bind -k backspace dan tunjukkan output tersebut. Jalankan juga echo $TERM .

Kami lebih memilih untuk tidak masuk ke sistem Anda karena alasan kewajiban dan karena kami tidak membaca bahasa Mandarin sehingga set LANG zh_CN.UTF-8 akan sulit bagi kami untuk bekerja dengannya.

./fish_key_reader
999999 usec dec: 8 hex: 8 char: \ b (alias \ cH)
FYI: Melihat urutan untuk nama kunci bind "backspace"

bind -k backspace
mengikat: Tidak ada pengikatan yang ditemukan untuk kunci 'backspace'

echo $ TERM
xterm

mengikat: Tidak ada pengikatan yang ditemukan untuk kunci 'backspace'

Oke, itu masalahmu. Ini harus mengatakan sesuatu seperti

bind -k backspace backward-delete-char

Saya tidak melihat bagaimana ini bisa ada hubungannya dengan pengaturan variabel LANG. Anda entah bagaimana telah menimpa key binding default. Saya akan mencari file _ ~ / .config / fish / _ ** Anda untuk menyebutkan kata "bind". Selain itu, apakah Anda menggunakan pengelola plugin (mis., Nelayan atau oh-my-fish) atau apakah Anda telah menginstal skrip pihak ketiga lainnya yang mungkin relevan dengan masalah ini?

BAIK.
~ / .config / fish / hanya memiliki 3 file: config.fish fish_history fishd.lhmtestdf.com

cat config.fish
set LANG zh_CN.UTF-8
cat fishd.lhmtestdf.com 
# This file is automatically generated by the fish.
# Do NOT edit it directly, your changes will be overwritten.
SET __fish_init_1_50_0:\x1d
SET __fish_init_2_3_0:\x1d
SET fish_color_autosuggestion:555\x1eyellow
SET fish_color_command:005fd7\x1epurple
SET fish_color_comment:red
SET fish_color_cwd:green
SET fish_color_cwd_root:red
SET fish_color_end:green
SET fish_color_error:red\x1e\x2d\x2dbold
SET fish_color_escape:cyan
SET fish_color_history_current:cyan
SET fish_color_host:normal
SET fish_color_match:cyan
SET fish_color_normal:normal
SET fish_color_operator:cyan
SET fish_color_param:00afff\x1ecyan
SET fish_color_quote:brown
SET fish_color_redirection:normal
SET fish_color_search_match:\x2d\x2dbackground\x3dpurple
SET fish_color_selection:\x2d\x2dbackground\x3dpurple
SET fish_color_user:green
SET fish_color_valid_path:\x2d\x2dunderline
SET fish_greeting:Welcome\x20to\x20fish\x2c\x20the\x20friendly\x20interactive\x20shell\x0aType\x20\x1b\x5b32mhelp\x1b\x5b30m\x1b\x28B\x1b\x5bm\x20for\x20instructions\x20on\x20how\x20to\x20use\x20fish
SET fish_key_bindings:fish_default_key_bindings
SET fish_pager_color_completion:normal
SET fish_pager_color_description:555\x1eyellow
SET fish_pager_color_prefix:cyan
SET fish_pager_color_progress:cyan

di bawah ikan-2.2.0
perintah mengikat ouput:

bind
bind '' self-insert
bind \n execute
bind \ck kill-line
bind \cy yank
bind \t complete
bind \e\n commandline\ -i\ \\n
bind \e\[A up-or-search
bind \e\[B down-or-search
bind -k down down-or-search
bind -k up up-or-search
bind \e\[C forward-char
bind \e\[D backward-char
bind -k right forward-char
bind -k left backward-char
bind -k dc delete-char
bind -k backspace backward-delete-char
bind backward-delete-char
bind \e\[H beginning-of-line
bind \e\[F end-of-line
bind \e\[1\~ beginning-of-line
bind \e\[4\~ end-of-line
bind -k home beginning-of-line
bind -k end end-of-line
bind -k sdc backward-delete-char
bind \e\eOC nextd-or-forward-word
bind \e\eOD prevd-or-backward-word
bind \e\e\[C nextd-or-forward-word
bind \e\e\[D prevd-or-backward-word
bind \eO3C nextd-or-forward-word
bind \eO3D prevd-or-backward-word
bind \e\[3C nextd-or-forward-word
bind \e\[3D prevd-or-backward-word
bind \e\[1\;3C nextd-or-forward-word
bind \e\[1\;3D prevd-or-backward-word
bind \e\eOA history-token-search-backward
bind \e\eOB history-token-search-forward
bind \e\e\[A history-token-search-backward
bind \e\e\[B history-token-search-forward
bind \eO3A history-token-search-backward
bind \eO3B history-token-search-forward
bind \e\[3A history-token-search-backward
bind \e\[3B history-token-search-forward
bind \e\[1\;3A history-token-search-backward
bind \e\[1\;3B history-token-search-forward
bind \ca beginning-of-line
bind \ce end-of-line
bind \ey yank-pop
bind \cw backward-kill-path-component
bind \cp history-search-backward
bind \cn history-search-forward
bind \cf forward-char
bind \cb backward-char
bind \ct transpose-chars
bind \et transpose-words
bind \eu upcase-word
bind \ec capitalize-word
bind \ backward-kill-word
bind \eb backward-word
bind \ef forward-word
bind \e\[1\;5C forward-word
bind \e\[1\;5D backward-word
bind \e\[1\;9A history-token-search-backward
bind \e\[1\;9B history-token-search-forward
bind \e\[1\;9C forward-word
bind \e\[1\;9D backward-word
bind \e. history-token-search-backward
bind -k ppage beginning-of-history
bind -k npage end-of-history
bind \e\< beginning-of-buffer
bind \e\> end-of-buffer
bind \el __fish_list_current_token
bind \ew 'set tok (commandline -pt); if test $tok[1]; echo; whatis $tok[1]; commandline -f repaint; end'
bind \cl 'clear; commandline -f repaint'
bind \cc 'commandline ""'
bind \cu backward-kill-line
bind \ed kill-word
bind \cd delete-or-exit
bind -k f1 __fish_man_page
bind \eh __fish_man_page
bind \ep __fish_paginate
bind -k btab complete-and-search
bind \e cancel
bind \e\[I 'begin;end'
bind \e\[O 'begin;end'

tetapi di bawah fish-2.3.0, perintah bind output:

bind
bind '' self-insert
bind \n execute
bind \r execute
bind \t complete
bind \cc 'commandline ""'
bind \cd exit
bind \ce bind

Bagaimana Anda menginstal fish 2.3.0? Sepertinya Anda menjalankan biner ikan yang tidak dapat menemukan skrip ruang penggunanya.

dari sumber

git clone
autoconf
configure
gmake
gmake install

Oke, itu terlihat masuk akal. Apa output perintah berikut ini:

echo $__fish_active_key_bindings
echo $fish_function_path

Apakah ada _fish_default_key_bindings.fish_ di salah satu direktori jalur fungsi (biasanya yang terakhir terdaftar)? Saya ingin tahu apa functions fish_default_key_bindings output. Jangan salin-tempel keluaran itu tetapi harus cocok dengan apa yang ada di file _fish_default_key_bindings.fish_. Juga, pengikatan kunci biasanya diatur oleh skrip ___ fish_config_interactive.fish_ yang seharusnya ada di salah satu direktori yang terdaftar oleh jalur fungsi var.

ketika saya menghapus .config / fish / config.fish, semuanya berjalan dengan baik.
tetapi ketika saya meletakkan string set LANG zh_CN.UTF-8 ke .config / fish / config.fish atau /usr/local/etc/fish/config.fish, masalahnya muncul.

echo $__fish_active_key_bindings tidak menghasilkan apa-apa.

echo $fish_function_path keluaran:
/home/lhm/.config/fish/functions /usr/local/etc/fish/functions /usr/local/share/fish/vendor_functions.d /usr/local/share/fish/functions

ketika saya menghapus .config / fish / config.fish atau mengomentari semua baris di /usr/local/etc/fish/config.fish, hasilnya adalah:

echo $__fish_active_key_bindings keluaran:
fish_default_key_bindings

echo $fish_function_path keluaran:
/home/lhm/.config/fish/functions /usr/local/etc/fish/functions /usr/local/share/fish/vendor_functions.d /usr/local/share/fish/functions

file fish_default_key_bindings.fish ada di /usr/local/share/fish/functions/fish_default_key_bindings.fish

Sepertinya ikan tidak pernah menyetel keybindings.

Ini bisa terjadi karena __fish_config_interactive (yang mencakup setup binding) tidak pernah dijalankan (yang seharusnya tepat sebelum prompt pertama Anda) atau karena $ fish_key_bindings Anda kosong (kita mungkin harus kembali ke binding default jika nilainya adalah tidak valid).

Karena tampaknya dipicu dengan menyetel $ LANG, ini menunjuk ke masalah encoding.

Semua file konfigurasi dan file fishd Anda mungkin bagus dalam bentuk asli karena saya tidak yakin apakah github mencoba memperbaiki pengkodean dengan membantu. Juga, apa nilai $ LANG Anda jika Anda tidak menyetelnya di config.fish? (Seharusnya kompatibel dengan ASCII, karena jika tidak, saya rasa kita bahkan tidak dapat membaca file kita sendiri, tetapi Anda tidak pernah tahu)

Saya menambahkan set LANG zh_CN.UTF-8 ke _config.fish_ saya dan tidak mengalami masalah. Seperti yang dikatakan @faho , ini sepertinya masalah pengkodean karakter. Secara khusus, file ikan Anda tidak dienkode sebagai UTF-8. Apa yang dilaporkan file /usr/local/share/fish/functions/__fish_config_interactive.fish ? Jika tertulis "teks ASCII", tambahkan baris LANG Anda kemudian mulai shell baru seperti ini untuk mengumpulkan keluaran debugging:

script
fish -d5
exit
exit

Kemudian lampirkan file _typescript_ ke masalah ini.

file /usr/local/share/fish/functions/__fish_config_interactive.fish
/usr/local/share/fish/functions/__fish_config_interactive.fish: ASCII text

cat typescript output:
Script started on Mon May 23 07:34:02 2016
@ ~/home/lhm> /usr/local/bin/fish -d5
@ ~/home/lhm> exit

@ ~/home/lhm> exit

Apa apaan? Anda mengatakan bahwa fish -d5 tidak menghasilkan keluaran selain prompt shell? Anda seharusnya mendapatkan banyak sekali keluaran yang terlihat seperti berikut:

fish: Continue job 1, gid 0 (fish_title), COMPLETED, NON-INTERACTIVE
fish: proc::read_try('fish_title')
fish: io_buffer_t::read: blocking read on fd 3

Apakah DragonFly merupakan referensi ke https://www.dragonflybsd.org/? Saya ingin tahu apakah teks di halaman web itu, "sistem lokal baru", relevan. Apakah Anda membangun ikan dari git head di sistem itu? Jika tidak, dari mana asal biner ikan? Apa yang terjadi jika Anda malah set LANG C atau set LANG en_US.UTF-8 .

ya, https://www.dragonflybsd.org/ adalah halaman beranda proyek.
Saya membangun dari sumber git seperti:

git clone
autoconf
configure
gmake
gmake install

hanya mengatur LANG C yang dapat menghasilkan fish -d5 bekerja. output seperti:

<2> fish: sourcing /usr/local/share/fish/config.fish
<4> fish: Exec job 'builtin source /usr/local/share/fish/config.fish' with id 1
<4> fish: Exec job 'set -g IFS \n\ \t' with id 2
<3> fish: Skipping fork: no output for internal builtin 'set'
<3> fish: Set status of set -g IFS \n\ \t to 0 using short circuit
<3> fish: Job is constructed
<4> fish: Continue job 2, gid 0 (set -g IFS \n\ \t), COMPLETED, NON-INTERACTIVE
<4> fish: Exec job 'status --is-interactive' with id 2
<3> fish: Skipping fork: no output for internal builtin 'status'
<3> fish: Set status of status --is-interactive to 0 using short circuit
<3> fish: Job is constructed
<4> fish: Continue job 2, gid 0 (status --is-interactive), COMPLETED, NON-INTERACTIVE
<4> fish: Exec job 'not set -q NVIM_LISTEN_ADDRESS' with id 2
<3> fish: Skipping fork: no output for internal builtin 'set'
<3> fish: Set status of not set -q NVIM_LISTEN_ADDRESS to 1 using short circuit
<3> fish: Job is constructed
<4> fish: Continue job 2, gid 0 (not set -q NVIM_LISTEN_ADDRESS), COMPLETED, NON-INTERACTIV

set LANG en_US.UTF-8 adalah hasil yang sama dengan set LANG zh_CN.UTF-8 , tidak menghasilkan keluaran selain prompt shell.

pada kotak DF 4.4 lainnya

/usr/local/bin/fish -d5
There is no fish_key_bindings function called: 'fish_default_key_bindings'
Reverting to default bindings
There is no fish_key_bindings function called: 'fish_default_key_bindings'
Reverting to default bindings
There is no fish_key_bindings function called: 'fish_default_key_bindings'
Reverting to default bindings
There is no fish_key_bindings function called: 'fish_default_key_bindings'
Reverting to default bindings
There is no fish_key_bindings function called: 'fish_default_key_bindings'
Reverting to default bindings
There is no fish_key_bindings function called: 'fish_default_key_bindings'
Reverting to default bindings
There is no fish_key_bindings function called: 'fish_default_key_bindings'
Reverting to default bindings

fish-2.2.0 berjalan OK.

Oke, jelas ada ketidakcocokan antara fish dan fungsi karakter lebar DragonFly atau bug di yang terakhir. Apakah Anda memiliki akses ke sistem DragonFly 4.3 yang dapat Anda buat dan uji coba ikan? Akan lebih baik jika kita dapat memulai dengan mengonfirmasi bahwa perubahan yang diperkenalkan pada dukungan lokal DragonFly 4.4 itulah perubahan utamanya.

Saya menguji ikan terbaru pada kotak DragonFly 4.2-RELEASE, semuanya berjalan dengan baik.

cat .config/fish/config.fish 
set -gx LANG zh_CN.UTF-8

locale
LANG="zh_CN.UTF-8"
LC_CTYPE="zh_CN.UTF-8"
LC_COLLATE="zh_CN.UTF-8"
LC_TIME="zh_CN.UTF-8"
LC_NUMERIC="zh_CN.UTF-8"
LC_MONETARY="zh_CN.UTF-8"
LC_MESSAGES="zh_CN.UTF-8"
LC_ALL=""


/usr/local/bin/fish -v
fish, version 2.3.0-162-g85e701f

uname -a
DragonFly . 4.2-RELEASE DragonFly v4.2.4-RELEASE #6: Sun Aug  9 13:25:14 EDT 2015     [email protected]:/usr/obj/home/justin/release/4_2/sys/X86_64_GENERIC  x86_64

Oke, silakan bicara dengan pengelola DragonFly. Saya tidak mengatakan bahwa kesalahan terletak pada kode mereka. Tetapi mereka lebih cenderung memiliki penjelasan mengapa fungsi seperti mbrtowc() dan wcrtomb() tidak memberikan hasil yang diharapkan ketika ikan memanggilnya. Sangat tidak mungkin perilaku ini hanya memengaruhi ikan.

Saya juga dapat mereproduksi ini di DragonFly BSD 4.5-DEVELOPMENT, dengan semua lokal UTF-8 (misalnya en_AU.UTF-8 ).

@krisnadi
jadi, bisakah Anda memberi saya kasus uji untuk menguji fungsi mbrtowc () dan wcrtomb ()?

Oke, silakan bicara dengan pengelola DragonFly. Saya tidak mengatakan bahwa kesalahan terletak pada kode mereka. Tetapi mereka lebih cenderung memiliki penjelasan mengapa fungsi seperti mbrtowc () dan wcrtomb () tidak memberikan hasil yang diharapkan saat ikan memanggilnya. Sangat tidak mungkin perilaku ini hanya memengaruhi ikan.

jadi, bisakah Anda memberi saya kasus uji untuk menguji fungsi mbrtowc () dan wcrtomb ()?

Saya akan menyarankan

$ gmake fish_tests
$ ./fish_tests convert

Tapi itu tidak gagal. Menjalankan semua tes melalui ./fish_tests gagal dalam beberapa tes tetapi tidak ada yang bisa menjelaskan masalah ini.

Saya menginstal DragonFly 4.4.3 dan membangun serta menginstal ikan dari git head. Memulai ikan dengan set -x LANG en_US.UTF-8 di _config.fish_ saya menghasilkan banyak kesalahan tak terduga seperti

alias: Name cannot be empty
There is no fish_key_bindings function called: 'fish_default_key_bindings'
Reverting to default bindings

Tidak mengherankan bind menunjukkan sangat sedikit pengikatan kunci karena pengikatan default minimal. Perintah locale melaporkan C sampai saya secara eksplisit mengaturnya ke en_US.UTF-8 . Yang pertama bekerja sedangkan yang terakhir tidak. Fakta bahwa lokal default sistem adalah "C" daripada "en_US.UTF-8" cukup mengejutkan. Apakah itu menunjukkan bahwa pengembang DragonFly mengenali bahwa dukungan UTF-8 mereka bermasalah?

Saya mungkin atau mungkin tidak menghabiskan lebih banyak waktu untuk debugging ini. Saya mendorong Anda untuk berbicara dengan pengelola DragonFly karena mereka mungkin dapat memberikan wawasan tentang masalah ini.

Saya memiliki testcase yang sangat minim dengan fwprintf , jadi saya akan menanyakan tipe DragonFly BSD.

Saya akan dengan senang hati menguji tambalan apa pun.

Di milis DragonFly BSD, Romick mengatakan :

Saya melihat pengurai di cangkang ikan, Anda menggunakan karakter khusus langsung di aliran masukan untuk menandai hal-hal yang berbeda, seperti BRACKET_BEGIN, BRACKET_END, BRACKET_SEP, INTERNAL_SEPARATOR, dan sebagainya.

Ini baik-baik saja sampai Anda menemukan lokal di mana karakter adalah anggota lengkap alfabet.
Soalnya, rentang Unicode adalah 0x0 hingga 0x10FFFF, dan karakter INTERNAL_SEPARATOR memiliki kode 0xFDD7.

Dalam fungsi DragonFly BSD iswalnum () memeriksa semua lokal secara bersamaan, jadi
bahwa Anda memiliki tiga pilihan:
1) gunakan iswalnum Anda sendiri ():

diff --git a/src/common.h b/src/common.h
index e59dfc0..e8c01c3 100644
--- a/src/common.h
+++ b/src/common.h
@@ -769,4 +769,8 @@ __attribute__((noinline)) void debug_thread_error(void);
 /// specified base, return -1.
 long convert_digit(wchar_t d, int base);

+inline int iswalnum(wchar_t chr) {
+ return((chr >= L'a' && chr <= L'z') || (chr >= L'A' && chr <= L'Z') || iswdigit(chr));
+}
+
 #endif

2) gunakan nilai yang lebih besar untuk karakter khusus Anda (saya belum menguji ini).

3) sesuatu yang lain :)

Saya ingin tahu apakah orang itu tahu sesuatu tentang Unicode. "Karakter khusus" tersebut adalah karakter area penggunaan pribadi yang didefinisikan sebagai bukan alfanum: https://en.wikipedia.org/wiki/Unicode_character_property#General_Category. Saya menguji ini di OS X, Linux, dan DragonFly. Dan, tentu saja, ketiganya mengembalikan false sebesar iswalnum(INTERNAL_SEPARATOR) . Juga, kami tidak pernah meneruskan karakter khusus itu ke fungsi seperti fwprintf () jadi saya tidak mengerti mengapa ini bahkan relevan.

Kasus uji yang dikurangi sangat bagus @zanchey!

Bagaimana Anda menginstal DragonflyBSD? Saya mencoba dengan ISO setiap malam dan juga ISO rilis 4.4.3 (menggunakan Virtualbox) dan tidak dapat mereproduksi masalah dengan kasus uji yang dikurangi fwprintf.

edit: Saya juga bisa membangun dan menginstal fish di 4.4.3, dan tes juga lulus, kecuali untuk tes pemberi tahu.

Kasus uji hanya gagal melalui SSH - ini berfungsi di konsol sistem di VirtualBox.

Oh wow. Apakah Anda menggunakan Vagrant?

Tidak, cukup VirtualBox 5.0.20.

Saya akan mengambil kepemilikan ini setelah menutup # 3406 sebagai duplikat. Saya akan mencoba mencari waktu untuk menginstal FreeBSD dan mereproduksi masalah dan jika berhasil melakukan debug lebih lanjut.

@ lhmwzy ini mungkin masalah yang sama dengan # 3406. FYI, saya membagi dua masalah yang terakhir itu dan melacaknya untuk melakukan f2246dfb343bea19beb176fb2cc534f85513b2eb.

Dari pembaruan saya ke masalah # 3406 (perhatikan bahwa saya sekarang bekerja dengan FreeBSD 12 daripada DragonFly BSD):

FYI, saya menginstal FreeBSD 12 dan dapat mereproduksi masalah ini. Alasan tidak ada kunci yang berfungsi adalah karena binding kunci default tidak disiapkan di lokal UTF-8:

Reverting to default bindings
The function call stack limit has been exceeded. Do you have an accidental infinite loop?
fish: __fish_reload_key_bindings VARIABLE SET fish_key_bindings
      ^
in event handler: handler for variable 'fish_key_bindings'

Ada juga kesalahan lain seperti alias: Name cannot be empty . Saya juga memastikan bahwa bangunan dari git checkout f2246df~ tidak menunjukkan masalah. Yang sangat mengejutkan saya sebagai penulis perubahan itu.

Kerja bagus menemukan komit di mana perilaku menyimpang. Tidak jelas bagi saya apa yang salah dengan itu.

Ada juga kesalahan lain seperti alias: Nama tidak boleh kosong

@ krader1961 : Ini tampaknya masalah yang sama @floam saw: kutipan dengan hanya variabel di dalamnya menyelesaikan argumen kosong - kesalahan itu muncul ketika alias gagal test -z "$name" .

@faho , Ya, saya baru saja

Juga, saya menambahkan pernyataan debug dan semua fungsi isw...() kami gunakan (mis., iswalnum() ) mengembalikan hasil yang benar untuk token internal tersebut di FreeBSD 12. Jadi saran yang diberikan kepada @zanchey oleh seseorang di milis BSD untuk mendefinisikan iswalnum kita sendiri tidak berguna.

Nyatanya, Anda dapat mereproduksi ekspansi var di dalam masalah string kutip ganda dengan cukup mudah dengan lokal UTF-8 di BSD:

$ set wtf b
$ echo a "$wtf" c
a  c
$ echo "a $wtf c"
a b c
$ echo "a $wtf"
a
$ echo "$wtf c"
b c

Layak untuk menggali lebih dalam apa yang terjadi saat mengakhiri referensi var dengan kutipan ganda. Semua contoh di atas berfungsi dengan baik dengan LC_ALL = C.

Saya salah ketika mengatakan beberapa jam yang lalu bahwa iswalnum() mengembalikan jawaban yang benar di FreeBSD. Saya salah memanggil fungsi itu dalam keluaran debugging saya sebelum setlocale("") dipanggil. Memindahkan cetakan debug tersebut menunjukkan bahwa 32 blok titik kode yang dimulai dari 0xFDD0 menyebabkan iswalnum() dan iswgraph() mengembalikan satu daripada nilai yang benar, nol, pada FreeBSD tetapi bukan GNU. Di sisi lain GNU salah mengembalikan satu untuk iswgraph() untuk karakter penggunaan pribadi mulai dari 0xF600 yang kita gunakan sementara FreeBSD mengembalikan nol dengan benar.

Jadi sepertinya kita harus menerapkan pembungkus kita sendiri di sekitar fungsi tersebut untuk mendapatkan perilaku yang benar terlepas dari platformnya. Saya perlu berpikir sedikit tentang bagaimana melakukannya dengan jumlah minimum kode tambahan dan lapisan abstraksi yang membingungkan.

Saya telah membuka bug FreeBSD ini. Kami masih harus menyelesaikan implementasi yang rusak ini.

Kami telah menetapkan pola yang harus dipanggil oleh kode ikan fish_wcswidth() daripada wcswidth() . Kami telah menetapkannya sebagai aturan cppcheck (lihat _.cppcheck.rule_). Kita bisa melakukan hal yang sama untuk fungsi keluarga isw...() . Tapi apakah itu solusi terbaik? Ini tentu yang paling mudah untuk diterapkan. Apakah ada yang punya solusi yang lebih baik?

NB, saya cenderung mengklasifikasikan masalah ini sebagai "peningkatan" daripada "bug" karena kita berbicara tentang meningkatkan ikan untuk mengatasi bug di salah satu platform yang kami dukung. Iya? Tidak? Siapa peduli? :tersenyum:

PPS, saya telah memverifikasi bahwa mengesampingkan platform menyediakan iswalnum() memperbaiki masalah ini di FreeBSD 12.

Cara yang saya sukai untuk menangani ini adalah dengan memeriksa perilaku pada waktu konfigurasi, dan menimpa fungsi jika dan hanya jika tidak kompatibel dalam hal ini.

Saya tidak akan mendasarkan mengganti fungsi platform pada tes autoconf. Pertama, kami telah melihat contoh distro yang memiliki perilaku yang benar (atau salah) dalam satu rilis dan kemudian membalik perilaku tersebut dalam rilis berikutnya. Biner yang dibangun untuk FreeBSD 10, misalnya, seharusnya masih berfungsi dengan benar di FreeBSD 12. Mendasarkan perilaku kita pada uji autoconf tidak menanganinya. Kedua, pengujian yang dipermasalahkan sangat murah meskipun kami menggabungkannya untuk memastikan perilaku yang benar dan panggilan ke fungsi yang terpengaruh tidak berada dalam loop performa kritis. Ketiga, kita memerlukan salah satu fungsi pembantu yang akan diperkenalkan oleh perubahan ini untuk memastikan kita tidak mengizinkan pengguna untuk memasukkan titik kode penggunaan internal sihir kita saja (yang ada di daftar TODO saya) ke dalam status internal kita.

Juga, sebagai catatan ketika saya menulis pernyataan berikut di komentar sebelumnya saya memiliki dua distro yang dibalik:

Di sisi lain GNU salah mengembalikan satu untuk iswgraph () untuk karakter penggunaan pribadi mulai dari 0xF600 yang kita gunakan sementara FreeBSD mengembalikan nol dengan benar.

Menurut poin kode FAQ Unicode di area penggunaan pribadi dimaksudkan untuk diklasifikasikan sebagai memiliki mesin terbang terkait (yaitu, iswgraph() harus mengembalikan satu) tetapi bukan alfanumerik (yaitu, iswalnum() harus dikembalikan nol).

Bagi saya tes autoconf yang memeriksa hasil iswalnum () pada salah satu nilai ini akan berfungsi.

Paket biner FreeBSD dari port tidak akan dibuat pada libc yang berbeda dari target - ini menjadi dasar untuk cara kerja semua pengujian waktu konfigurasi kami.

Seperti yang dilakukan, ini akan menimpa fungsi yang disediakan sistem secara tidak perlu di Linux dan OS X juga, @ krader1961.

Fish dibuat dan ditautkan secara dinamis ke libc bersama di FreeBSD:

$ ldd fish
fish:
        libncurses.so.8 => /lib/libncurses.so.8 (0x800948000)
        libthr.so.3 => /lib/libthr.so.3 (0x800b9c000)
        libc++.so.1 => /usr/lib/libc++.so.1 (0x800dc3000)
        libcxxrt.so.1 => /lib/libcxxrt.so.1 (0x801082000)
        libm.so.5 => /lib/libm.so.5 (0x8012a0000)
        libc.so.7 => /lib/libc.so.7 (0x8014cb000)
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x801885000)

Apakah Anda mengatakan dengan kepastian 100% bahwa jika perilaku subsistem lokal berubah, nomor versi libc.so akan berubah? Saya tidak punya waktu atau kecenderungan untuk mengeksplorasi pertanyaan itu. Saya lebih suka konservatif mengingat perbaikan saya tidak akan terlalu memengaruhi perilaku atau kinerja ikan.

Apakah Anda mengatakan dengan kepastian 100% bahwa jika perilaku subsistem lokal berubah, nomor versi libc.so akan berubah?

"bukan masalah kita".

"bukan masalah kita"

Tentu saja itu masalah kita. Itulah alasan kami memiliki fish_wcswidth() dan solusi serupa untuk implementasi yang rusak.

Bug ada di alat localedef yang menghasilkan file ctype, dan itu berasal dari Illumos. Memperbaiki DF di sini:

https://github.com/DragonFlyBSD/DragonFlyBSD/commit/07ed7d329a83714ec268e2f3ce026bba5a1ac5c2

@jrmarino : Terima kasih atas infonya! Apakah Anda tahu kapan ini akan masuk ke berbagai OS? Apakah perubahan DF sudah sampai ke pengguna?

Terima kasih banyak baptisan! Saya baru saja memutakhirkan ke FreeBSD 11.0-RELEASE-p1 dan ini benar-benar mengganggu. Tahukah Anda jika atau kapan tambalan akan diintegrasikan ke FreeBSD 11.0-RELEASE?

Perhatikan bahwa kami mengatasi bug ini pada ikan yang terbuat dari git head. Jika Anda masih mengalami masalah dengan ikan dari git head di BSD, beri tahu kami. Solusinya tidak pada ikan 2.3.1 atau rilis sebelumnya, tetapi akan ada di rilis 2.4.0 mendatang.

Perubahan ini cukup mandiri - harus mudah untuk di-backport oleh pengelola di luar sana.

Sudah dalam peninjauan kode.
https://reviews.freebsd.org/D8148

Bagus.

@shanavar Saya akan menggabungkan setelah 1 bulan karena perubahannya agak mengganggu dan saya ingin memastikan tidak ada efek samping, setelah ini divalidasi saya akan meminta errata untuk 11.0-RELEASE, artinya Anda dapat mengharapkannya sekitar satu bulan +

Mengompilasi Ikan dari git berfungsi untuk saya di FreeBSD 11.0-RELEASE-p1:

sudo pkg remove fish
sudo pkg install autoconf  gmake
git clone [email protected]:fish-shell/fish-shell.git
cd fish-shell
autoconf
./configure
gmake
sudo gmake install

Kemudian tambahkan /usr/local/bin/fish ke /etc/shells dan jalankan chsh -s fish untuk mengubah shell Anda ke Fish.

Jadi saya bukan satu-satunya dengan masalah ini. Terima kasih semua untuk mengoreksinya, ini membuatku gila.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat