[リストへもどる]
一括表示
タイトル[K2E]マクロ用文字列の予約語展開
記事No3492
投稿日: 2006/01/30(Mon) 20:58
投稿者NakIT
ヘルプのマクロ用文字列記述基準にて述べられている予約語(%CopyStr% や
%MacroStr0% など)の展開に関する問題です。

// 行の2重化
// DblLine.mac
BeginUpdate
SelectLine
InputStr(%SelText%%SelText%)
CursorLeft
CursorUp
EndUpdate

上記のような、以前に掲示板にて提示させていただいた行の二重化マクロを利用
しております。ここで、

|マクロ文字列9は「%MacroStr9%」です。

のような行に対してこのマクロを実行したとき、

|マクロ文字列9は「%MacroStr9%」です。
|マクロ文字列9は「%MacroStr9%」です。

といった結果を期待しますが、実際には、

|マクロ文字列9は「」です。
|マクロ文字列9は「」です。

となります。「」内には共通設定で定義されている %MacroStr9% の内容が入りま
す。この程度ならまだよいのですが、「%SelText%」を含む行に対しては無限ルー
プとなってしまいます。

同様に、コピーバッファの内容に「%CopyStr%」が含まれているとき、マクロで
%CopyStr% を展開すると無限ループとなります。Paste なら期待通りです。

ソースを拝見したところ、KeyMacro.pas の ChangeMacroParamToStr が展開場所
のようです。もしかしたら、最後のほうの
Insert(AnsiUpperCase(InsertStr), s1, index);

Insert(AnsiLowerCase(InsertStr), s1, index);
に変更すれば改善できるのではないかと考えております。Delphi は門外漢であり、
上記はあてずっぽうです。すいません。

ご検討をお願いします。

タイトルRe: [K2E]マクロ用文字列の予約語展開
記事No3493
投稿日: 2006/01/31(Tue) 09:24
投稿者K2
 K2です。

 これは、明確には定義されていない仕様の問題だと思います。

 現在は、予約語展開に関して、再起的に処理を行っています。
だから、たとえば選択文字列の中に%%で囲まれた予約語があれば、
それも変換してしまいます。結果的に無限ループに陥ることも
ありますが、動作上の仕様ですので、使用時に避けて頂く必要が
あります。

 で、これを、先頭文字列から展開していき、変換された文字列
に関しては、2度目の変換はしないように作ることも可能なので
すが、現在までに作成されたマクロで、再起的展開の機能に
依存したものがないとは限りませんので、仕様変更はできません。

 よって、仕様的には放置します。

 ちなみに、

> ソースを拝見したところ、KeyMacro.pas の ChangeMacroParamToStr が展開場所
> のようです。もしかしたら、最後のほうの
> Insert(AnsiUpperCase(InsertStr), s1, index);
> を
> Insert(AnsiLowerCase(InsertStr), s1, index);
> に変更すれば改善できるのではないかと考えております。

ですが、ここは関係ないと思います。s1は、予約語を見つける
ための検索用文字列で、InsertStrを大文字にしてから挿入して
いるのは、「再起的に文字列変換を行う」という仕様にするという
明確な意志の現れと取ることができます。

タイトルRe^2: [K2E]マクロ用文字列の予約語展開
記事No3494
投稿日: 2006/02/01(Wed) 20:43
投稿者NakIT
仕様だったのですか。失礼しました。

そういうことでしたら、互換性確保のためには変えるべきではないですね。また、
循環チェックについても、コストが見合わないのでやるべきではないと思います。


以下は蛇足…というか愚痴です。軽くスルーしてください。


実は、私がこの現象を不具合ではないかと疑ったのは、
(1) 無限ループの危険がある。
(2) マクロ用ファイル名記述基準の予約語は展開されない。
(3) 予約語の扱いが対等でなく、順位がある。

といった現象が見えたからです。(2)(3) は、たとえば以下で確認できます。

MacroStr7=%MacroStr8%
MacroStr8=Foo
MacroStr9=%MacroStr8%

となっているとき、

// マクロ文字列展開のテスト
Paste
InputStr(=)
InputStr(%CopyStr%)

のようなマクロをコピーバッファを変えて実験すると、

コピーバッファが %MacroStr7% なら結果は %MacroStr7%=Foo
コピーバッファが %MacroStr9% なら結果は %MacroStr9%=%MacroStr8%
コピーバッファが %User% なら結果は %User%=%User%

となります。すなわち、CopyStr の中の %MacroStr7% や %MacroStr9%、MacroStr7
の中の %MacroStr8% は展開されますが、MacroStr9 の中の予約語は展開されませ
ん。この順位は、おおむねヘルプのマクロ用文字列記述基準に書かれている順で
す。

展開が 1 回なら、予約語をどのような順で処理しても問題が無く、マクロ用ファ
イル名記述基準の予約語と同等の扱いとなり、無限ループの危険もありません。
これらのことから、Insert された予約語の内容に立ち入らないように
AnsiLowerCase を使うのが K2 さん本来の意図であり、再帰的に処理される
(AnsiUpperCase を使う)のは誤りではないかと勘違いしたのでした。