Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 14863] ファイルの概要

このコミットは、Go言語のテストスイート内の2つのファイル、test/safe/nousesafe.gotest/safe/usesafe.go における変更です。これらのファイルは、Goコンパイラのフラグ解析の挙動変更に対応するために修正されました。具体的には、コンパイラオプション -I. の解釈が変更され、-I . のようにスペースを挟む形式が必要になったことに対する適応です。

コミット

commit ab1385ec95fe5eec367b8c40196a8962c1ca8ee5
Author: Rémy Oudompheng <oudomphe@phare.normalesup.org>
Date:   Fri Jan 11 22:05:46 2013 +0100

    test: adapt old-style tests to new flag parsing.
    
    The -I. syntax now needs a space to be recognized in the
    compiler.
    
    R=golang-dev, bradfitz
    CC=golang-dev
    https://golang.org/cl/7098046

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/ab1385ec95fe5eec367b8c40196a8962c1ca8ee5

元コミット内容

このコミットの目的は、「古いスタイルのテストを新しいフラグ解析に適応させる」ことです。具体的には、「-I. という構文が、コンパイラで認識されるためにスペースを必要とするようになった」ため、それに対応する修正が行われました。

変更の背景

Goコンパイラのコマンドライン引数解析の内部的な挙動に変更があったことが背景にあります。以前は -I. のようにオプションと値が連結された形式でも正しく解釈されていた -I フラグが、この変更により -I . のようにオプションと値の間にスペースが必要となりました。

このような変更は、コンパイラのパーサーの堅牢性向上、あるいはより一般的なコマンドライン引数解析の慣習(例えばPOSIX/GNUスタイルの引数解析)に合わせるためのものと考えられます。特に、-I のようなオプションは、通常、インクルードパスを示すディレクトリ名を引数として取ります。. はカレントディレクトリを意味するため、-I. はカレントディレクトリをインクルードパスに追加するという意味になります。この変更により、コンパイラは -I をオプションとして、そして . をそのオプションの引数として明確に区別するようになりました。

このコミットは、Goのテストスイートがこの新しい解析ルールに準拠するように更新するものであり、コンパイラの変更自体は別のコミットで行われたものと推測されます。

前提知識の解説

コマンドライン引数とフラグ

コマンドライン引数とは、プログラムを実行する際に、そのプログラムに渡される追加情報のことです。これらは通常、プログラムの動作を制御するために使用されます。 「フラグ」または「オプション」は、特定の機能の有効化/無効化や、値の設定を行うための引数の一種です。これらは通常、ハイフン (-) やダブルハイフン (--) で始まります。

-I フラグ

多くのコンパイラ(C/C++の gccclang など)において、-I フラグは「インクルードパス」を指定するために使用されます。インクルードパスとは、コンパイラがヘッダーファイルやモジュールなどを検索するディレクトリのリストのことです。例えば、gcc -I/usr/local/include main.c は、/usr/local/include ディレクトリをヘッダーファイルの検索パスに追加することを意味します。

Go言語のコンパイラ go tool compile (または古い $G) においても、-I フラグは同様にインポートパス(パッケージの検索パス)を指定するために使用されます。このコミットで言及されている -I. は、カレントディレクトリ (.) をインポートパスに追加するという意味になります。

フラグ解析 (Flag Parsing)

プログラムがコマンドライン引数をどのように解釈するかを「フラグ解析」と呼びます。これには、オプション名の識別、オプションに続く値の抽出、そしてそれらの値の型変換などが含まれます。フラグ解析のルールは、プログラムや使用されるライブラリによって異なりますが、一般的には以下のようなパターンがあります。

  • ショートオプション: -o value または -ovalue (例: -I .-I.)
  • ロングオプション: --option value または --option=value
  • ブールフラグ: -v (詳細モードを有効にするなど)

このコミットの変更は、ショートオプションの「値の連結」に関する解析ルールが変更されたことを示しています。

技術的詳細

この変更の核心は、Goコンパイラのコマンドライン引数パーサーが、-I フラグの引数を解釈する方法を変更した点にあります。

以前のパーサーは、-I. のようにオプション名と引数(この場合は .)が直接連結されている形式を許容し、これを -I オプションに . という引数が与えられたものとして正しく解釈していました。

しかし、新しいパーサーでは、オプションと引数の間にスペースを挟むことが必須となりました。つまり、-I . の形式でなければ、I をオプションとして認識し、その後の . をその引数として関連付けることができなくなったのです。

これは、パーサーが引数をトークン化する際のロジックがより厳密になったことを示唆しています。例えば、以前は -I に続く文字が数字やピリオドなどの特定の文字であれば、それをオプションの引数の一部として貪欲に解釈していた可能性があります。しかし、変更後は、オプションの終わりを明確に区切るためにスペースを要求するようになったと考えられます。これは、曖昧さを減らし、より予測可能な解析挙動を実現するためによく行われる変更です。

この変更は、Goコンパイラ自体のコードベースで行われたものであり、このコミットは、そのコンパイラの変更によって影響を受ける既存のテストスクリプトを修正するものです。

コアとなるコードの変更箇所

変更は、test/safe/nousesafe.gotest/safe/usesafe.go の2つのファイルで行われています。それぞれのファイルの最初の行にあるコメント行が修正されています。

test/safe/nousesafe.go の変更

--- a/test/safe/nousesafe.go
+++ b/test/safe/nousesafe.go
@@ -1,4 +1,4 @@
-// $G $D/pkg.go && pack grc pkg.a pkg.$A 2> /dev/null && rm pkg.$A && errchk $G -I. -u $D/main.go
+// $G $D/pkg.go && pack grc pkg.a pkg.$A 2> /dev/null && rm pkg.$A && errchk $G -I . -u $D/main.go
 // rm -f pkg.a
 
 // Copyright 2012 The Go Authors. All rights reserved.

test/safe/usesafe.go の変更

--- a/test/safe/usesafe.go
+++ b/test/safe/usesafe.go
@@ -1,4 +1,4 @@
-// $G $D/pkg.go && pack grcS pkg.a pkg.$A 2> /dev/null && rm pkg.$A && $G -I. -u $D/main.go
+// $G $D/pkg.go && pack grcS pkg.a pkg.$A 2> /dev/null && rm pkg.$A && $G -I . -u $D/main.go
 // rm -f pkg.a
 
 // Copyright 2012 The Go Authors. All rights reserved.

両ファイルともに、コメント行内の $G -I.$G -I . に変更されています。

コアとなるコードの解説

これらのファイルは、Go言語のテストスイートの一部であり、特に test/safe ディレクトリは、Goコンパイラの「セーフモード」または特定のコンパイルオプションの挙動をテストするために使用されると考えられます。

コメント行は、テストを実行するためのシェルコマンドを示しています。

  • $G: Goコンパイラへのパス(またはコンパイラを実行するコマンド)を指す変数です。
  • $D/pkg.go: テスト対象のGoソースファイルです。
  • pack grc pkg.a pkg.$A: パッケージをアーカイブするコマンドです。
  • 2> /dev/null: 標準エラー出力を破棄します。
  • rm pkg.$A: 生成されたパッケージファイルを削除します。
  • errchk: エラーチェックを行うためのユーティリティコマンドです。
  • -u: 未使用のインポートや変数に関する警告を有効にするフラグと考えられます。
  • $D/main.go: テスト対象のメインGoソースファイルです。

変更された部分 $G -I. は、Goコンパイラを呼び出す際に、カレントディレクトリ (.) をインポートパスとして追加するオプションを指定していました。このコミットにより、このオプションの記述が -I . となり、コンパイラが正しくインポートパスを認識できるように修正されました。

これらのテストファイルは、コンパイラの特定の挙動(この場合はインポートパスの解決)が期待通りに行われることを検証するためのものです。コンパイラのフラグ解析の変更により、テストが失敗するようになったため、テストスクリプト自体を新しいコンパイラの挙動に合わせて更新する必要が生じました。

関連リンク

  • Go Gerrit Change-ID: https://golang.org/cl/7098046

参考にした情報源リンク

  • GitHubコミットページ: https://github.com/golang/go/commit/ab1385ec95fe5eec367b8c40196a8962c1ca8ee5
  • Go言語の flag パッケージに関する一般的な情報 (Web検索結果より):
    • https://pkg.go.dev/flag
    • https://stackoverflow.com/questions/17147862/how-does-go-flag-package-handle-arguments-after-a-non-flag-argument
  • Goコンパイラの -I フラグに関する一般的な情報 (Goのドキュメントや関連する議論から推測)
  • 一般的なコンパイラのコマンドライン引数に関する知識