DelFusa Blog 総本山

プログラミングの話題とかです。

NEW | PAGE-SELECT | NEXT

≫ EDIT

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

| スポンサー広告 | --:-- | comments(-) | trackbacks(-) | TOP↑

≫ EDIT

思い通りにはいかない


   _____________
 /
 | 世の中自分の思い通りに
 | ならないことだらけなんだよ...
 \_ ____________
    |/
   ∧,,∧ フー
  ミ,,  ミy━~~
  .(o   ミ
  ミ @ ミ
   ∪''∪ 


さて、ヒアドキュメント拡張(?)の仕様書です。


◇ビルド前処理

  ソースを読み込む
  ソースのバックアップをとる
  _here_doc_backup\Unit1.pas

  行の中の『(*<<<』を求める。
  それ以降の文字列を求めて 「Label」とする。

  行の中の「Lable」+『*)』を見つける。
  みつからなければエラーなので変換しない。

  みつかれば、
  「(*<<  行頭にクウォート
  行末にクウォート+#13#10+
  をつけて、変換

◇ビルド後処理

  _here_doc_backup\Unit1.pas
  が存在すれば、移動して元に戻す

っとっとっと。
つまり、pasに対してビルド前に変換かけているんですよ…

そこはかとなく、泥臭くて、使えないニホヒ・・・

ということで、ソースです。

コマンドラインプログラムで、同一フォルダにあるpasを書き換えるという荒技というか
我ながら、ちょっと痛々しい感じの構文拡張というか、なんというか、、、

このプログラムを、ソースと同一フォルダに配置して
プロジェクトオプションで、MSBuildのビルド前オプションとビルド後オプションを設定してください。

program DelphiHereDoc;

uses
 SysUtils,
 Windows,
 Classes,

 SystemUnit,
 StringListObjectUnit,
 FileList,
 ShellFileCtrl,
 StringUnit,
 ConstUnit,
 StringListUnit,
 FileNameUnit,

 MECSUtils,

uses_end;

function GetHereDocBackupFilePath(FilePath: string): String;
begin
 Result := ExtractFilePath(FilePath)+'_here_doc_backup\'+
      ExtractFileName(FilePath)
end;

var
 FileList: TFileList;
 I, J: Integer;
 TargetFilePath: String;
 HereDocStartIndex, HereDocEndIndex: Integer;
 HereDocLable: String;
 StartHereDocTag, EndHereDocTag: String;
 EndHereDocIndent: Integer;
 BackupFilePath: String;
label LoopEnd1;
begin
 try
  //バックアップファイルがあるのならリストアして終了
  FileList := TFileList.Create(nil); try
  FileList.Directory := IncludeLastPathDelim(GetCurrentDir)+'_here_doc_backup';

  FileList.FileListType := flNormal;
  FileList.DestStrings := StrList('FileList');
  FileList.List;
  finally FileList.Free; end;

  if 1 <= StrList('FileList').Count then
  begin
   for I := 0 to StrList('FileList').Count - 1 do
   begin
    TargetFilePath := StrList('FileList')[I];

    //リストア
    ShellMoveFile(0, TargetFilePath,
     GetUpFolderPath(TargetFilePath));
   end;
   Exit;
  end;

  FileList := TFileList.Create(nil); try
  FileList.Directory := GetCurrentDir;

  FileList.FileListType := flNormal;
  FileList.DestStrings := StrList('FileList');
  FileList.List;

  finally FileList.Free; end;

  for I := 0 to StrList('FileList').Count - 1 do
  begin
   TargetFilePath := StrList('FileList')[I];
   if not SameText( ExtractFileExt(TargetFilePath) , '.pas') then
    Continue;

   //ファイル読込
   StrList('FileText').LoadFromFile(TargetFilePath);
   StrList('OriginalFileText').Text := StrList('FileText').Text;

   while True do
   begin
    StartHereDocTag := '(*<<<';
    HereDocStartIndex :=
     Strings_IndexOfSubStr(StrList('FileText'), StartHereDocTag);
    if HereDocStartIndex = -1 then
    begin
     //ヒアドキュメントがないので終了
     Break;
    end;
    HereDocLable :=
     DelimiterRightLong(StartHereDocTag, StrList('FileText')[HereDocStartIndex]);
    if HereDocLable = EmptyStr then
    begin
     //ラベルがないのでエラー
     goto LoopEnd1;
    end;

    EndHereDocTag := HereDocLable+'*)';

    HereDocEndIndex :=
     Strings_IndexOfSubStr(StrList('FileText'), EndHereDocTag);
    if HereDocEndIndex = -1 then
    begin
     //ヒアドキュメント終了マークがないのでエラー
     goto LoopEnd1;
    end;

    StrList('FileText')[HereDocStartIndex] :=
     DelimiterLeft(StartHereDocTag, StrList('FileText')[HereDocStartIndex]);
    for J := HereDocStartIndex+1 to HereDocEndIndex - 1 do
    begin
     StrList('FileText')[J] := IncludeBothEndsStr(StrList('FileText')[J], SingleQuote) + '+ #13#10 +';
    end;
    StrList('FileText')[HereDocEndIndex] :=
     IncludeBothEndsStr(
      DelimiterLeft(EndHereDocTag, StrList('FileText')[HereDocEndIndex]), SingleQuote)
     + DelimiterRightLong(EndHereDocTag, StrList('FileText')[HereDocEndIndex]);
   end;

   while True do
   begin
    StartHereDocTag := '(*<<-';
    HereDocStartIndex :=
     Strings_IndexOfSubStr(StrList('FileText'), StartHereDocTag);
    if HereDocStartIndex = -1 then
    begin
     Break;
    end;
    HereDocLable :=
     DelimiterRightLong(StartHereDocTag, StrList('FileText')[HereDocStartIndex]);
    if HereDocLable = EmptyStr then
    begin
     goto LoopEnd1;
    end;

    EndHereDocTag := HereDocLable+'*)';

    HereDocEndIndex :=
     Strings_IndexOfSubStr(StrList('FileText'), EndHereDocTag);
    if HereDocEndIndex = -1 then
    begin
     goto LoopEnd1;
    end;
    EndHereDocIndent := MecsLength(
     DelimiterLeft(EndHereDocTag, StrList('FileText')[HereDocEndIndex]) );

    StrList('FileText')[HereDocStartIndex] :=
     DelimiterLeft(StartHereDocTag, StrList('FileText')[HereDocStartIndex]);
    for J := HereDocStartIndex+1 to HereDocEndIndex - 1 do
    begin
     StrList('FileText')[J] := IncludeBothEndsStr(
      MecsCopy(StrList('FileText')[J], EndHereDocIndent + 1, MaxInt), SingleQuote) + '+ #13#10 +';
    end;
    StrList('FileText')[HereDocEndIndex] :=
     SingleQuote + SingleQuote +
     DelimiterRightLong(EndHereDocTag, StrList('FileText')[HereDocEndIndex]);
   end;

   BackupFilePath := GetHereDocBackupFilePath(TargetFilePath);
   ShellCopyFile(0, TargetFilePath, BackupFilePath);
   StrList('FileText').SaveToFile(TargetFilePath);

   LoopEnd1:
  end;

 except
  on E: Exception do
   Writeln(E.ClassName, ': ', E.Message);
 end;
end.
---------------------------------
program DelphiHereDocEnd;

uses
 SysUtils,
 Windows,
 Classes,

 SystemUnit,
 StringListObjectUnit,
 FileList,
 ShellFileCtrl,
 StringUnit,
 ConstUnit,
 FileNameUnit,

uses_end;

function GetHereDocBackupFilePath(FilePath: string): String;
begin
 Result := ExtractFilePath(FilePath)+'_here_doc_backup\'+
      ExtractFileName(FilePath)
end;

var
 FileList: TFileList;
 I, J: Integer;
 TargetFilePath: String;
 RestoreFlag: Boolean;
 HereDocStartIndex, HereDocEndIndex: Integer;
 HereDocLable: String;

begin
 try

  FileList := TFileList.Create(nil); try
  FileList.Directory := IncludeLastPathDelim(GetCurrentDir)+'_here_doc_backup';

  FileList.FileListType := flNormal;
  FileList.DestStrings := StrList('FileList');
  FileList.List;

  finally FileList.Free; end;

  for I := 0 to StrList('FileList').Count - 1 do
  begin
   TargetFilePath := StrList('FileList')[I];

   ShellMoveFile(0, TargetFilePath,
    GetUpFolderPath(TargetFilePath));
  end;

 except
  on E: Exception do
   Writeln(E.ClassName, ': ', E.Message);
 end;
end.

---------

まあ、こんなことするより。

DLangExtensions 入れときなさい。って話ですよ。
http://andy.jgknet.de/dlang/
スポンサーサイト

| 未分類 | 02:56 | comments:1 | trackbacks(-) | TOP↑

COMMENT

DLangExtensions
http://andy.jgknet.de/dlang/

DelphiXEでは使えないのかな・・・
なんかうごかねーぜ

| ミ・д・彡 | 2011/07/24 02:33 | URL | ≫ EDIT















非公開コメント

PREV | PAGE-SELECT | NEXT

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。