0

Googleのre2正規表現ライブラリをラップするRubyC ++拡張機能を作成しましたが、ライブラリの最近の更新により、関数のインターフェイスが次のように変更されました。Match()

bool Match(const StringPiece& text,
           int startpos,
           Anchor anchor,
           StringPiece *match,
           int nmatch) const;

に:

bool Match(const StringPiece& text,
           int startpos,
           int endpos,
           Anchor anchor,
           StringPiece *match,
           int nmatch) const;

(新しいint endpos引数に注意してください。)

VERSION私の質問は、re2がイントロスペクトできる定数を指定していないように見えるにもかかわらず、このライブラリの両方のバージョンを1つの拡張機能でサポートすることは可能ですか?

理想的には、新しいバージョン(6つの引数を使用)を試して、失敗した場合は、古いバージョンにフォールバックできるようにしたいです(endpos引数を簡単に埋め戻すことができるため)。

現時点では、私のコードは次のようになっています。

matched = p->pattern->Match(text_as_string_piece, 0, (int)RSTRING_LEN(text), RE2::UNANCHORED, 0, 0);

ただし、古いバージョンのre2を使用している場合は、次のようにする必要があります。

matched = p->pattern->Match(text_as_string_piece, 0, RE2::UNANCHORED, 0, 0);
4

2 に答える 2

0

伝統的な答えはconfig.h、インストール時に何かを生成することです。

つまり、インストール時に のどのバージョンがインストールされているかを検出し、これに応じてre2シンボルを定義します。config.h

// config.h
#ifndef CONFIG_H_INCLUDED
#define CONFIG_H_INCLUDED

#define RE2_MATCH_6_ARGS 1

#endif // CONFIG_H_INCLUDED

そして、これを使用できます:

#if defined(RE2_MATCH_6_ARGS) && RE2_MATCH_6_ARGS == 1
  matched = p->pattern->Match(text_as_string_piece, 0, (int)RSTRING_LEN(text), RE2::UNANCHORED, 0, 0);
#else
  matched = p->pattern->Match(text_as_string_piece, 0, RE2::UNANCHORED, 0, 0);
#endif

これは安定したソリューションであり、うまく機能するはずです。


別の可能性は、システムをハッキングすることです...

Matchラッパー ライブラリで両方の関数の定義を提供します。

  • Match5エラーをスローします (re2 にリンクしてください)
  • Match6に転送しMatch5ます。

問題は (Unix の世界では...)、シンボルが既に読み込まれている場合、新しい定義によって上書きされることはありません。が最初に読み込まれる限り、re2次の 2 つのシナリオのいずれかになります。

  • old re2 : (ラッパー) ライブラリは、提供された の定義にMatch6転送する のre2定義を提供しますMatch5
  • new : 呼び出しは、提供さre2れたの定義に直接移動しますMatch6re2

はるかに脆い。の周りにラッパー ライブラリが必要re2です。静的リンクで動作する可能性は低いです (ただし試したことはありません...)。./configureしかし、ステップは必要ありません。

于 2012-02-27T13:03:32.440 に答える
0

私が知っていることから、あなたはできません。これには、RE2 の古いバージョンと新しいバージョンの両方にリンクする必要があり、名前空間が衝突します。

古いバージョンに似たこのメソッドのバージョンが存在しない限り、新しいバージョンで立ち往生しています。

拡張機能を両方のバージョンでコンパイルできるようにする場合は、コンパイル手順を変更して、制御するフラグを定義する必要があります

#ifdef RE2_ODLFORMAT
matched = p->pattern->Match(text_as_string_piece, 0, RE2::UNANCHORED, 0, 0);
#else
matched = p->pattern->Match(text_as_string_piece, 0, (int)RSTRING_LEN(text), RE2::UNANCHORED, 0, 0);
#endif

次に、コードをコンパイルするには、これらの行に沿って何かを行います。

make RE2_OLDFORMAT=1 all # compile for old version
make all # default target is for new version
于 2012-02-27T12:48:11.910 に答える