大規模なアプリ (XE3 で正常に動作) を XE4 でコンパイルした後に実行したときにのみ表示される動作をデバッグしようとしています。この問題により、Web.HTTPProd で TPageProducer によって「引用符が解除」された後でも、一部の引用符付き文字列 ("MyString" など) の引用符が保持されるようです。たとえば、この Delphi ソース ユニット Web.HTTPApp から抜粋した以下のコードを考えてみましょう。
procedure ExtractHeaderFields(Separators, _WhiteSpace: TSysCharSet; Content: PChar;
Strings: TStrings; Decode: Boolean; StripQuotes: Boolean = False);
{$ENDIF NEXTGEN}
var
Head, Tail: PChar;
EOS, InQuote, LeadQuote: Boolean;
QuoteChar: Char;
ExtractedField: string;
{$IFNDEF NEXTGEN}
WhiteSpaceWithCRLF: TSysCharSet;
SeparatorsWithCRLF: TSysCharSet;
{$ENDIF !NEXTGEN}
function DoStripQuotes(const S: string): string;
var
I: Integer;
InStripQuote: Boolean;
StripQuoteChar: Char;
begin
Result := S;
InStripQuote := False;
StripQuoteChar := #0;
if StripQuotes then
begin
for I := Result.Length - 1 downto 0 do
if Result.Chars[I].IsInArray(['''', '"']) then
if InStripQuote and (StripQuoteChar = Result.Chars[I]) then
begin
Result.Remove(I, 1);
InStripQuote := False;
end
else if not InStripQuote then
begin
StripQuoteChar := Result.Chars[I];
InStripQuote := True;
Result.Remove(I, 1);
end
end;
end;
TPageProducer を使用するときにこれが呼び出されるのを確認し、適切なソース文字列が上記の ExtractHeaderFields ルーチンに入り、次に「DoStripQuotes」関数に入ることがわかります。DoStripQuotes にステップインして 'Result' を見ると、Result.Remove が呼び出されても (引用符を削除するために) 変更されないことがわかります。この「DoStripQuotes」ルーチンを単純なテスト アプリに使用すると、コンパイルされず、「Result.anything」が許可されていないことがわかります。「文字列」として定義されていますが、結果はWeb.HTTPProdのコンテキストでは別のタイプの文字列でなければならないと思います。
それで、これは私が聞いた「不変の文字列」と関係があるのではないかと考え始めました。私はそれについてこのSOの質問を読みました。要点はわかりましたが、より実用的なアドバイスを行うことができました。
具体的には、次の質問に対する回答を希望します。
- 表記法 Result.Length が許可されている場合、「結果」はどのタイプの「文字列」ですか?
- ユニットに「XE3」互換性を使用するようにコンパイラに指示する方法はありますか? (これにより、問題の発生場所を確認できる場合があります)。{$ZEROBASEDSTRINGS ON} / OFF を試してみましたが、これはさらに混乱を引き起こしているようで、何をしているのかわかりません!
助けてくれてありがとう。
LATER EDIT:以下の受け入れられた回答に記載されているように、これは VCL ユニット Web.HTTPApp.pas のバグであり、「Result := Result.Remove(I,1)」を 2645 行付近の 2 か所で読み、「Result.削除(I,1)"