VS code Arduino 文字化け

最近では、Visual Studio Code に慣れて便利に使っている。

しかし、突然出力コンソールの日本語文字化けが発生。何かと思ったら、Arduinoプラグインがupdateされたみたいだ。

f:id:chiyoh:20201108123223p:plain

これは、導入したときにも発生していてファイルにパッチを充てることで回避したが今回はまた上書きされてしまったみたいだ。

chiyoh.hatenablog.com

"C:\Users\%username%\.vscode\extensions\vsciot-vscode.vscode-arduino-0.3.3\out\src\common\util.js"

Ver. 0.3.4
"C:\Users\%username%\.vscode\extensions\vsciot-vscode.vscode-arduino-0.3.4\out\src\common\util.js"

<span style="color:red"></span>
    return new Promise((resolve, reject) => {
        const stdout = "";
        const stderr = "";
        options.cwd = options.cwd || path.resolve(path.join(__dirname, ".."));
        const child = childProcess.spawn(command, args, options);
        let codepage = "65001";
        if (os.platform() === "win32") {
            try {
                const chcp = childProcess.execSync("chcp.com");
                codepage = chcp.toString().split(":").pop().trim();
            }
            catch (error) {
                outputChannel_1.arduinoChannel.warning(`Defaulting to code page 850 because chcp.com failed.\
                \rEnsure your path includes %SystemRoot%\\system32\r${error.message}`);
                codepage = "850";
            }
        }
        codepage = "65001";  /* 今回はここを追加 */
        if (outputChannel) {
            child.stdout.on("data", (data) => {
                outputChannel.append(decodeData(data, codepage));
            });
            child.stderr.on("data", (data) => {
                outputChannel.append(decodeData(data, codepage));
            });
        }

前回は、よく分かっていなかったがよくよく見ればやっていることは単純。で、悩ましい問題でもあった。
マイクロソフトMS-DOSWindowsは、世界各国で販売をしていてその国毎にカスタマイズをしてきた。これによりその国の時間、通貨、言語に対応しシェアを伸ばしてきたのだが世界的に広まると今度は有名なソフトウェアが海外でも実行され、一応動くがローカライズされた文字が化けて表示できない等の問題を起こした。過去DOS(現在でいうとcmd.exe)では、CHCPというコマンドがある。 S-JISコードが932で、DOS/Vコードが437となっている。つまり、英語モードにして実行するときは、'CHCP 437'と打ち込み日本語に戻すのは'CHCP 932'である。MS-DOSには、US.BAT JP.BATなるバッチコマンドがありそれほど必要な人には必要なコマンドであった。

f:id:chiyoh:20201108131419p:plain

いまでも、CHCP 437と打てば英語モードになる。

f:id:chiyoh:20201108131555p:plain

UNIXの世界でも、同じことが起きていてscriptやbatchが動かないときには、setenv LANG Cや、unsetenv LANGを実行してお節介な日本語処理を無効にしたりしていた。もう世の中21世紀も四半世紀近くになりだいぶUNICODEUTF-8が浸透してきている。今回の文字化けはこれに起因する。

docs.microsoft.com

にあるように、'65001'は、UTF-8である。上のコードの一部は、文字体系をUTF-8に変更するよ。エラーがあったら'850'欧州多言語コードに変更みたいな。我々のwindowsは、chcp.comを実行すると932が返ってくる。

f:id:chiyoh:20201108133247p:plain

つまり、日本語 Shift-JISだ。最近は、UTF-8でプログラムソースを書いていることも多いが、WindwosのすべてがUTF-8ではないためシステムをUTF-8に変更するといままで動作していたアプリケーションが動かなくなってしまうことが予想されるのでシステムの文字体系を変更というのは安易にはできない。UTF-8を使っていて1バイトしか使わない欧米では問題ないが。その他の国でも、システム変数のページコードにしておけば問題ないよね。ということである。しかし、日本はマイクロソフトのOSをけん引してきたことによりつまりOSは、シフトJIS。しかし世の中は、世界標準のUTF-8なのでこの齟齬が発生している。Linux等は、UTF-8で統一されているからこの問題は起きていない?

文字化けは、親切に各開発ツールの出力を多国語対応表示つまり母国語出力するための仕組みであった。基本的に、開発ツールのコマンドは、LANG Cつまりlibcライブラリのコード体系GNUツール関係の出力メッセージを取り込んで判断するscriptがあるので基本英語出力にするのが基本である。

過去の日本語文字化けパッチは、windows環境では、chcpコマンドを実行してdefault言語体系に変更しなさいということころをコメントに変更しているのである。いろんな国でVisual Studio Code が使われているのでこのコードでうまくいっている地域が多いのであろう。かといって、ソースコードSJISで書いていけば問題ないというわけにもいかないのでだれかがPR書くまで毎回パッチを充てるのであった。

今回は、内容が分かったので、再度codepage = "65001";として再定義をすることで1行追加するだけで済むパッチにした。 まあ、'os.platform() === "win32"'を'os.platform() === "hogehoge"'でもいいんだけどね。