program ruby_aw;    // このファイルの最後にドキュメントがあります 

{$AppType Console}

uses
  Messages, // WM_QUIT 
  SysUtils, // ExtractFileName 
  Registry, // TRegistry 
  windows;

// ----

const
  version = 'Ruby Anywhere + Chemeleon Loader. ver.1.08 2002-11-01';
  author_J= 'たけ(tk) ( ggb03124@nifty.ne.jp )';
  author_E= 'kumagai hidetake( ggb03124@nifty.ne.jp )';

// ---- from tkUtils.pas

function GetRegValue( const Root:HKEY;const Key,ID:string ):string;
begin
  Result := '';
  with TRegistry.Create do try
    RootKey := Root;
    if OpenKey( Key , false ) then try
      Result:= ReadString( ID );
    finally CloseKey ; end;
  finally Free ; end;
end;

const RegAppKey:string='Software\Microsoft\Windows\CurrentVersion\App Paths\' ;

function GetAppPath(ExeName: String): String;
 (* レジストリの App Path から ExeName を取得する *)
begin
  // ExeName のファイル名部分だけ取り出す＋拡張子の補正
  ExeName := ExtractFileName( ExeName );
  if ExtractFileExt( ExeName )='' then ExeName := ExeName+'.exe';
  result := GetRegValue( HKEY_LOCAL_MACHINE , RegAppKey+ExeName , '' );
end;

function tkExecSub( const Cmd:string ; Timeout:integer ):boolean;
Var
  SI :TStartupInfo;
  PI :TProcessInformation;
  Msg:string;
  res:word;
begin
  GetStartupInfo(SI);
  If not CreateProcess(
      nil ,         // アプリケーション名／コマンドファイル 
      pChar(Cmd) ,  // コマンドライン 
      nil,          // プロセスのセキュリティ属性 
      nil,          // スレッドのセキュリティ属性 
      False,        // ハンドルを承継するかどうかのフラグ 
      CREATE_DEFAULT_ERROR_MODE,    // 作成モード 
      nil,          // 環境変数ブロックへのポインタ 
      nil,          // カレントディレクトリ名へのポインタ 
      SI,           // StartupInfo へのポインタ 
      PI)           // ProcessInfo へのポインタ 
  Then begin
    res := GetLastError;
    case res of
        2,3:  Msg := 'パスなしエラー';
        8:    Msg := 'メモリ不足';
        else  Msg := '不明なエラー';
    end;
    raise exception.createFmt(
            'tkExec(win32): Error(%d)! %s[%s]' ,
            [ res , Msg , Cmd ] );
    result := false;
    exit;   // error 2:File not Found ,3:Path Not Found 
  end;
  result := true;
end;

function GetEnv( const name:string ):string;
var d:integer;
begin
   SetLength(result,1024*4);
   d:=GetEnvironmentVariable( Pchar(name),PChar(result),length(result));
   SetLength(result,d); // 文字列の長さをセット
end;

function SearchPath_ex( const name:string ):string;
begin
  result := FileSearch( name , GetEnv('Path') );
  if result <> '' then exit;
  result := FileSearch( name , GetEnv('RubyLib') );
end;

// ----

procedure Usage0( alias_name:string);
begin
  if SysLocale.PriLangID = LANG_JAPANESE then begin
    writeLn(alias_name+'： '+version);
    writeLn('          by '+author_J);
    writeLn;
    writeLn('ruby_ap.exe の所在地が見つかりません。');
    writeLn('所在地を登録・更新するには、');
    writeLn('ダウンロードした Apollo のディレクトリにある');
    writeLn('AppPath.exe を実行してください。');
  end else begin
    writeLn(alias_name+'： '+version);
    writeLn('          by '+author_E);
    writeLn;
    writeLn('Cannot find "ruby_ap.exe"');
    writeLn('In order to register the location of "ruby_ap.exe",');
    writeLn('please run AppPath.exe on the directory of latest Apollo.');
  end;
end;

procedure Usage1( alias_name,ruby_exe:string);
begin
  if SysLocale.PriLangID = LANG_JAPANESE then begin
    writeLn(alias_name+'： '+version);
    writeLn('          by '+author_J);
    writeLn;
    writeLn('ruby_ap.exe の最新の所在地は');
    writeLn('  [',ruby_exe,']です。');
    writeLn;
    writeLn('Ruby_aw に引数を付けて実行すれば、最新の ruby_ap.exe が起動します｡');
    writeLn;
    writeLn('所在地を登録・更新するには、');
    writeLn('ダウンロードした Apollo のディレクトリにある');
    writeLn('AppPath.exe を実行してください。');
    writeLn;
    writeLn('【カメレオン機能】');
    writeLn('このコマンドをスクリプトと同じ名前にすると、');
    writeLn('同名のスクリプトを ruby_aw.exe で実行します。');
    writeLn;
    writeLn('copy Ruby_aw.exe hoge.exe');
    writeLn('hoge');
    writeLn('  == Ruby_aw hoge.rb');
  end else begin
    writeLn(alias_name+'： '+version);
    writeLn('          by '+author_E);
    writeLn;
    writeLn('The location of recognized "ruby_ap.exe" is');
    writeLn('  [',ruby_exe,'].');
    writeLn;
    writeLn('Please run "Ruby_aw.exe" with scrpit_file_name or Ruby_options,');
    writeLn('and it runs the latest "ruby_ap.exe".');
    writeLn;
    writeLn('In order to register the location of "ruby_ap.exe",');
    writeLn('please run AppPath.exe on the directory of latest Apollo.');
    writeLn;
    writeLn('Ruby_aw as CHAMELEON:');
    writeLn('If you rename this command to the same name of script FOO.rb,');
    writeLn('FOO.exe runs "Ruby_aw FOO.rb" in the same directory.');
    writeLn;
    writeLn('copy Ruby_aw.exe FOO.exe');
    writeLn('FOO');
    writeLn('  == Ruby_aw FOO.rb');
  end;
end;

var
  alias_name,alias_path,script,ruby_exe,options:string;
begin
  script := '';
  alias_name := 'ruby_aw';      //  for msg
  alias_path := ParamStr(0);    //  for run
  options := copy( CmdLine,length(ParamStr(0))+1,256 );

  if Pos( 'RUBY_AW.EXE', UpperCase(alias_path) ) <> 0 then begin
    alias_path := '';
    script := ParamStr(1);
    if ( ParamCount = 0 ) or ( script[1] = '-' ) then begin
      script := '';
    end else begin
      options := copy( trim(options) , length(ParamStr(1))+1,255);
      if ExtractFileExt( script ) = '' then script := script + '.rb';
      if not FileExists(script) then script := SearchPath_ex( script );
    end;
  end else begin
    script := ChangeFileExt(ExpandFileName(alias_path),'.rb');
    if not FileExists(script)
      then script := SearchPath_ex( ExtractFileName(script) );
    alias_name := 'ruby_aw(=>'+ExtractFileName(alias_path)+')';
  end;

  ruby_exe := GetAppPath( 'ruby_ap.exe' );
  if ruby_exe = '' then begin
    Usage0( alias_name );
    exit;
  end;

  if (script = '' ) and ( ParamCount = 0) then begin
    Usage1( alias_name,ruby_exe);
    exit;
  end;

  TkExecSub(ruby_exe  +' '+ script +' '+ options,0);

(****

  ruby_aw : Ruby AnyWhere

  【基本機能】

  アポロのコンソールバージョン ruby_ap.exe をどこからでも起動できるように
します。

  ruby_ap.exe は AppPath.exe で指定した場所にあるものとします。

  ruby_aw.exe は「パスが通ったディレクトリ」（c:\windows\command\ な
どそこに置いたコマンドであればコンソールから実行可能なディレクトリ）
にコピーしておいてください。

  使い方：

  使い方１：    RUBY_AW.EXE RUBYOPTIONS

  A:\>ruby_aw.exe -v
  ruby 1.6.3 (2001-03-19) [i586-mswin32]

  A:\>ruby_aw.exe -e "p $:"
  ["g:/apollo/tkutils", "G:/RUBY/TKUTILS",
  "C:/APOLLO/lib/ruby/ site_ruby/1.6/i586-mswin32",
  "C:/APOLLO/lib/ ruby/site_ruby/1.6", "C:/APOLLO/lib/ruby/site_ruby",
  "C:/APOLLO/lib/ ruby/1.6/i586-mswin32", "C:/APOLLO/lib/ruby/1.6",
  "C:/APOLLO/bin", "."]

  ＊  RUBY_OPTIONS の後にスクリプトを指定することもできるが、 その場
    合にはスクリプトの拡張子の補充・検索を行いません。スクリプトはフ
    ルパスで指定する必要があります。

  使い方２：    RUBY_AW.EXE SOME_SCRIPT SCRIPT_OPTIONS

  A:\>ruby_aw.exe doc2txt.rb Sample.doc
  Sample.docをSample.txtに変換しました。

  第一引数がスクリプトファイルである場合には拡張子がなければ 「.rb」
を補充し、次の順番でスクリプトファイルを捜して実行します。

    （１）カレントディレクトリ、
    （２）環境変数「Path」のディレクトリ、
    （３）環境変数「RubyLib」のディレクトリ。

  【カメレオン機能】

  Ruby_aw.exe を実行したいスクリプトと同じ名前にしておくと、そのスク
リプトをコマンドとして実行できるようになります。

  A:\>copy ruby_aw.exe doc2txt.exe
  A:\>doc2txt.exe Sample.doc
  Sample.docをSample.txtに変換しました。

  実行されるスクリプトは次の順番で捜します。

    （１）実行ファイルが存在するディレクトリ
    （２）カレントディレクトリ、
    （３）環境変数「Path」のディレクトリ、
    （４）環境変数「RubyLib」のディレクトリ。

  【説明】

  何をするものかは Ruby_aw.exe を引数なしで実行すれば分かるでしょう。
作成した理由は次のとおりです。

  アポロの最新版を展開したディレクトリにある AppPath.exe  を一回実行
すると、「スタート」→「ファイル名で実行」で「Apollo」と入力すれば最
新のアポロを起動するようになります。また、コマンドラインから実行する
には「Start」をつけて、

  Start Apollo
  Start Apollo -q Script.rb     ##  即時実行モード

の様に起動すれば、Apollo がカレントディレクトリになくても （またパス
が通っていなくても）Apollo.exe を起動できるようになります。

  もちろん ruby_ap.exe も

  Start ruby_ap Script.rb

で実行はできることはできるのですが、本来の目的であるコンソールや標準
入力・標準出力を活用することができなくなります。（Start はコンソール
アプリ用にはできていないようです）。

  そこで、Start と同様に「App Paths」レジストリを参照し、かつ、 コン
ソール、標準入出力も利用できるようにしたのが、この ruby_aw.exe です。

  【ログ】

 2002-11-01(金):var.1.08    日本語のコメント問題に対処。win_execに変更。
 2001-05-06(日):var.1.07    ruby.exe -> ruby_ap.exe
 2001-03-27(火):var.1.06    スクリプトの拡張子を補充＋Pathで捜す。
                            ただし、オプションが先行しない場合だけ有効。
 2000-12-14(木):ver.1.05    chameleon 機能を追加。
 2000-11-27(月):ver.1.04    ruby_aw -e "p 1" のバグ取り。
 2000-09-18(月):ver.1.03    パッケージ（Ruby_aw.lzh）にした。
 2000-07-21(金):Ruby_aw
 2000-07-16(日):ver.1.02    tk
 2000-07-14(金):ver.1.01    kimura@guc.co.jp
 2000-07-14(金):ver.1.00    take_tk GGB03124@nifty.ne.jp
 2000-07-14(金):ap_aw

  【パッケージ】

lha a ruby_aw.lzh ruby_aw.dpr ruby_aw.exe
lha a ruby_aw.lzh ruby_aw.dpr ruby_aw.exe hoge.exe hoge.rb

****)

end.
