チケット #46476

ログデフォルトファイル名に strftime が正しく置換されない

登録: 2023-01-07 14:23 最終更新: 2023-07-30 01:24

報告者:
担当者:
チケットの種類:
状況:
完了
コンポーネント:
マイルストーン:
優先度:
5 - 中
重要度:
5 - 中
解決法:
修正済み
ファイル:
なし
投票
点数: 0
No votes
0.0% (0/0)
0.0% (0/0)

詳細

ログデフォルトファイル名に strftime 文字列で指定した場合、置換は行われるが、地域に合った文字列に置換されない。

teraterm/teraterm/terater.cpp の WinMain() でロケールクリアすれば正しく置換される。(コントロールパネル「言語と地域設定」の設定が使われる)

setlocale(LC_ALL, "");

以下の環境で行っています。(win11 でビルドしているけど vs2022 にあげてないからかも)

実行環境:Windows 11 Home 22H2 22621.963

ビルド環境:Visual Studio 2019 Community/Windows SDK version 10.0.17763.0/cmake version 3.25.0-rc1

チケットの履歴 (13 件中 3 件表示)

2023-01-07 14:23 更新者: tomo3136
  • 新しいチケット "ログデフォルトファイル名に strftime が正しく置換されない" が作成されました
2023-01-07 18:02 更新者: tomo3136
コメント

LANG, LC_ALL, LC_TIME の環境変数を設定してから起動しましたが、いずれもロケールの切り替えは出来ませんでした。

なお、私のところでビルドすると、Teraterm4 で以下が現象を確認できたので、ビルド環境によりロケールが正しく扱われていないようでした。


端末設定のロケールを american の Equivalent Locale Name (en-US)で指定。

  • v4.106(配布バイナリ) ⇒ 問題なし
  • v4.106(tags/teraterm-4_106) をビルド ⇒ ハングアップ。
  • 4-stable/r10452 をビルド ⇒ ハングアップ。

※ビルドした場合でも en-US.utf8 まで指定すればハングアップしないので cランタイムが適切でないのかもしれない。

2023-01-09 23:27 更新者: nmaya
2023-01-18 22:34 更新者: zmatsuo
コメント

Tera Term 4 はプログラム内で

setlocale(LC_ALL, ts.Locale)
とやっているので環境変数の影響は受けないのではないかと思います。

ハングアップするのは腑に落ちないですね。

Tera Term 5 は setlocale()を行っていません。

起動時に setlocale(LC_ALL, "C") と同等な処理が行われるようです。

https://learn.microsoft.com/ja-jp/cpp/c-runtime-library/reference/setlocale-wsetlocale?view=msvc-170

ロケールクリアすれば正しく置換される。

Tera Term 5 の起動最初の方で

setlocale(LC_ALL, "")
を実行しておいた方がよさそうですね。

入れようと思いますが、 特に問題なさそうですか?

2023-06-04 21:32 更新者: zmatsuo
コメント

プログラムの最初に setlocale(LC_ALL, "") を追加しました。r10738です。

LANG, LC_ALL, LC_TIME の環境変数を設定してから起動しましたが、いずれ もロケールの切り替えは出来ませんでした。

setlocale() のドキュメントには環境変数を参照する、とないですね。

コントロールパネル「地域」-「形式」タブにはしたがうようです。

そういう仕様(VS2022のCランタイムの仕様)なのかなと思います。

書式指定 %C などは、今のところ isInvalidStrftimeCharW() で不正と判定、 deleteInvalidStrftimeCharW() で削除されてます。

使用可能な書式指定はVSのバージョンで変化すると思います。 ハードコードじゃない方法でチェックしたいですがどうしたものでしょうか。

2023-06-06 22:41 更新者: zmatsuo
コメント

r10739 で VS2022 で使える "%C" などが使えるよう修正しました。

strftime() は使用できない書式を与えるとパラメータ不正で内部でassert()します。

起動時に自動的にログ取得を開始するようになっている状態で、 誤って使用できない書式のファイル名を指定してしまうと 困ったことになるので厳密にチェックしているんだと思います。

_set_invalid_parameter_handler() (Debugビルドなら _CrtSetReportMode()も) を使えばstrftime()内部で止まらず、呼び出し側に戻るようにできそうでした。 とりあえず今のところはリリースで使用する予定のVS2022でうまく動けば良いかなと思い、 パラメータチェックはハードコードで実装しています。

2023-06-06 23:12 更新者: nmaya
コメント

こちらでもテストしてみました。

  • 文字列
    "%a, %A, %b, %B, %c, %p, %r, %x, %X, %Z.log"
    
  • Tera Term 4.106 (リリースバイナリ)
    火, 火曜日, 6, 6月, 20230606 224932, 午後, , 20230606, 224932, 東京 (標準時).log
    
  • trunk r10739 Visual Studio 2019 で手元でコンパイル
    火, 火曜日, 6, 6月, 2023_06_06 23_01_44, 午後, 23_01_44, 2023_06_06, 23_01_44, 東京 (標準時).log
    

書式指定文字

  • MSDN のここ で説明に「ロケール」とある書式
    %a	ロケールでの曜日の省略名
    %A	ロケールでの完全な曜日名
    %b	ロケールでの月の省略名
    %B	ロケールでの月の完全な名前
    %c	ロケールに合った日付と時刻の表記
    %p	ロケールでの 12 時間形式の午前/午後の標識
    %r	ロケールでの 12 時間制時刻
    %x	ロケールの日付表現
    %X	ロケールの時刻表現
    %Z	レジストリ設定に応じて、ロケールのタイム ゾーンの名前またはタイム ゾーンの略称のいずれか。タイム ゾーンが不明の場合は文字なし
    
  • Tera Term のマニュアルにないフォーマットは「%r」のみ。
    %a      曜日の省略形。
    %A      曜日の正式名。
    %b      月の省略形。
    %B      月の正式名。
    %c      ロケールに対応する日付と時刻の表現。
    %p      現在のロケールの午前/午後。
    %x      現在のロケールの日付表現。
    %X      現在のロケールの時刻表現。
    %z, %Z  レジストリの設定に応じて、タイム ゾーンの名前または省略形を指定します。
    	タイム ゾーンが不明な場合は指定しません。
    

書式指定 %C などは、今のところ

isInvalidStrftimeCharW() で不正と判定、

deleteInvalidStrftimeCharW() で削除されてます。

一番最初に「Tera Term 4 は VIsual Studio 2005 を使うのであるから、その範囲内でしかサポートし得ない」がありました。

次に「Visual Studio 2005 のマニュアルを Microsoft がオンライン上から消してしまった」がありました。これが次の項目の確認を困難にしています。

「Visual Studio 2005 のサポートするフォーマットをすべてサポートしていたが、%Cはその中に含まれていなかった」か、「含まれていたがあまり使わなそうだと思ったか、長い文字列に展開されそうで固定長で確保しているバッファがあふれそうな気がすると思ったのでサポート外とした」ような気もします。前者は古い MSDN Library を引っ張り出さないと確認できませんし、後者は私のおぼろげな記憶なのでソースのコメントになかったら確認できません。とにかく現在サポートされているのはドキュメントに書いてあるとおり、これだけということになります。

使用可能な書式指定はVSのバージョンで変化すると思います。

ハードコードじゃない方法でチェックしたいですがどうしたものでしょうか。

「Tera Term 側でサポートする書式を、コンパイラのサポートしている書式に対応して動的に変化させる」をしたら、マニュアルもそうしなければなりません。こういう場合は「コンパイルをサポートする最も低い VS バージョンにあわせる。その場合には新しい VS のみ使える書式は導入できない」でよいと考えます。

2023-06-07 00:01 更新者: zmatsuo
コメント

こちらでもテストしてみました。

ありがとうございます。

「Tera Term 側でサポートする書式を、コンパイラのサポートしている書式 に対応して動的に変化させる」をしたら、マニュアルもそうしなければなり ません。

「strftime の書式が使用できます」とマニュアルにあると「"%C"が使えない?」 と思ってしまいますね(思ってしまいました)。内部の実装はstrftimeですが、 マニュアルではstrftimeを削除して「次の書式が使用できます」としたほうが よいかも、とおもいました。

でもstrftime()を知っている人なら、strftime とあるほうがわかりやすいですね。 「strftimeと同様の次の書式が使用できます」のほうがよさそうでしょうか?

ついさっきVS2022で使える書式を使えるようにした修正を入れましたが、 従来と同等に戻そうと思います。

それとマニュアルの"%a"などの説明に「現在のロケールの」を追加したほうがよさそうですね。

2023-06-07 00:10 更新者: zmatsuo
コメント

環境変数で動作(フォーマット)を変更する件ですが、Visual Studio 2022で作っ たプログラムはできないように思います。

また手もと(r10739相当+VS2022)で LANG=en-US としてハングアップすることなく起動し ています。気になります。

環境変数で変更できなくても、日本語環境以外のときに"%B"なら"%#m月"とするなどで表現可能ものもあります。 以前よりは制限が減ったのではないかと思います。

でも"%A" ("日曜日"など)は日本語環境以外では再現できないですね。

2023-06-07 00:51 更新者: zmatsuo
コメント

環境変数 TZ は参照されるようです。

https://learn.microsoft.com/ja-jp/cpp/c-runtime-library/reference/tzset?view=msvc-170

ttermpro.exe では _tzset() はコールしていないのですがうまく設定されているようです。

setlocale() でセットされているのかもしれません。

2023-06-07 01:40 更新者: nmaya
コメント

「strftime の書式が使用できます」とマニュアルにあると

直下に書式を列挙しているのでそこを見るだろうと思っていました。strftime の書式を暗記していて覚えている書式をそのまま書くと、Tera Term に限らず、VS バージョンによって/もしかしたらプラットフォームによってもサポート状況が違う、という罠があるわけですね。

「strftimeと同様の次の書式が使用できます」

こう書くと、よりわかりやすくなると思います。

マニュアルの"%a"などの説明に「現在のロケールの」を追加したほうがよさそうですね。

今列挙している書式は、Visual Studio 2005 のときの MSDN の説明のコピペです。現在の MSDN では変わっているんですね。

(編集済, 2023-06-07 01:59 更新者: nmaya)
2023-06-08 00:49 更新者: zmatsuo
コメント

つかえる書式チェックを従来と同等に戻して、マニュアルを修正しました。r10744です。

直下に書式を列挙しているのでそこを見るだろうと思っていました。

確かにそうですよね。

そちらよりダイアログの「標準ログファイル名(strftimeフォーマット可) (&F)」 に引っ張られたのかなと思います。

思い切って省略して「標準ログファイル名(&F)」でもよいかなと思いますが いかがでしょうか?

(ちょっと省略しすぎかな・・strfime以外の書式もありますし・・悩ましい)

ドロップダウンで書式指定の例を見ることができるので、 調べたくなったユーザーはヘルプ参照、となるのかなと思います。

2023-07-30 01:24 更新者: zmatsuo
  • 状況オープン から 完了 に更新されました
  • 担当者(未割り当て) から zmatsuo に更新されました
  • 解決法なし から 修正済み に更新されました
コメント

思い切って省略して「標準ログファイル名(&F)」でもよいかなと思いますが いかがでしょうか?

変更せずに現在のままにしましょう。

クローズします。

添付ファイルリスト

添付ファイルはありません

編集

ログインしていません。ログインしていない状態では、コメントに記載者の記録が残りません。 » ログインする