Differences From Artifact [f1f9b8362f0839ce]:
- File        
src/qbga32.d
- 2011-02-23 12:53:16 - part of checkin [c2b7a98c21] on branch trunk - Initial import (user: kinaba) [annotate]
 
 
To Artifact [bcd83037acfbb1eb]:
- File        
src/qbga32.d
- 2015-04-21 10:46:55 - part of checkin [4e2933c620] on branch trunk - Rebased to the latest verson dmd 2.067. Not yet verified the outcome. (user: kinaba) [annotate]
 
 
                                                                                        >     1  private import core.sys.windows.dll;
                                                                                        >     2  private import win32.windows;
                                                                                        >     3  private import win32.winuser;
    1  private import std.string;                                                             4  private import std.string;
    2  private import std.file;                                                               5  private import std.file;
    3  private import win32.ansi.windows;                                               <
    4  private import util;                                                                   6  private import util;
    5  private import windll;                                                                 7  private import windll;
    6  private import bga_melter;                                                             8  private import bga_melter;
    7  private import qbga_gui;                                                               9  private import qbga_gui;
    8                                                                                        10  
    9  //----------------------------------------------------------------                    11  //----------------------------------------------------------------
   10  // おきまりのDLL初期化ルーチン                                                                    12  // おきまりのDLL初期化ルーチン
   11  //----------------------------------------------------------------                    13  //----------------------------------------------------------------
   12                                                                                        14  
   13  HINSTANCE g_hinst;                                                               |    15  __gshared HINSTANCE g_hinst;
   14                                                                                   <
   15  extern(C)                                                                        <
   16  {                                                                                <
   17          void gc_init();                                                          <
   18          void gc_term();                                                          <
   19          void _minit();                                                           <
   20          void _moduleCtor();                                                      <
   21          void _moduleDtor();                                                      <
   22          void _moduleUnitTests();                                                 <
   23  }                                                                                <
   24                                                                                        16  
   25  extern (Windows)                                                                      17  extern (Windows)
   26  BOOL DllMain( HINSTANCE inst, ULONG reason, void* reserved )                          18  BOOL DllMain( HINSTANCE inst, ULONG reason, void* reserved )
   27  {                                                                                     19  {
   28          switch( reason )                                                              20          switch( reason )
   29          {                                                                             21          {
   30          case DLL_PROCESS_ATTACH:                                                      22          case DLL_PROCESS_ATTACH:
   31                  g_hinst = inst;                                                       23                  g_hinst = inst;
   32                  gc_init();          // GC初期化                                     |    24                  dll_process_attach( inst, true );
   33                  _minit();           // モジュールリスト初期化                               <
   34                  _moduleCtor();      // モジュールコンストラクタ実行                            <
   35                  _moduleUnitTests(); // 単体テスト実行                                   <
   36                  if( g_orig_dll is null )                                              25                  if( g_orig_dll is null )
   37                          return false;                                                 26                          return false;
   38                  break;                                                                27                  break;
   39                                                                                        28  
   40          case DLL_PROCESS_DETACH:                                                      29          case DLL_PROCESS_DETACH:
   41                  _moduleDtor();                                                   |    30                  dll_process_detach( inst, true );
   42                  gc_term();     // GC終了                                           |    31                  break;
                                                                                        >    32  
                                                                                        >    33          case DLL_THREAD_ATTACH:
                                                                                        >    34                  dll_thread_attach( true, true );
                                                                                        >    35                  break;
                                                                                        >    36  
                                                                                        >    37          case DLL_THREAD_DETACH:
                                                                                        >    38                  dll_thread_detach( true, true );
   43                  break;                                                                39                  break;
   44                                                                                        40  
   45          default:                                                                      41          default:
   46          case DLL_THREAD_ATTACH:                                                  <
   47          case DLL_THREAD_DETACH:                                                  <
   48                  break;                                                           <
   49          }                                                                             42          }
   50          return true;                                                                  43          return true;
   51  }                                                                                     44  }
   52                                                                                        45  
   53  //----------------------------------------------------------------                    46  //----------------------------------------------------------------
   54  // API転送処理                                                                            47  // API転送処理
   55  //----------------------------------------------------------------                    48  //----------------------------------------------------------------
   56                                                                                        49  
   57  WinDLL g_orig_dll = null;                                                        |    50  __gshared WinDLL g_orig_dll = null;
   58  UINT   WM_ARCEXTRACT;                                                            |    51  __gshared UINT   WM_ARCEXTRACT;
   59                                                                                        52  
   60  static this()                                                                         53  static this()
   61  {                                                                                     54  {
   62          g_orig_dll = WinDLL.load( "_Bga32.DLL" );                                     55          g_orig_dll = WinDLL.load( "_Bga32.DLL" );
   63          WM_ARCEXTRACT = RegisterWindowMessage("wm_arcextract");                       56          WM_ARCEXTRACT = RegisterWindowMessage("wm_arcextract");
   64  }                                                                                     57  }
   65                                                                                        58  
................................................................................................................................................................................
   66  static ~this()                                                                        59  static ~this()
   67  {                                                                                     60  {
   68          g_orig_dll.close();                                                           61          g_orig_dll.close();
   69  }                                                                                     62  }
   70                                                                                        63  
   71  template api(FnT)                                                                     64  template api(FnT)
   72  {                                                                                     65  {
   73          FnT api( char[] name )                                                   |    66          FnT api( string name )
   74          {                                                                             67          {
   75                  return g_orig_dll.get_api!(FnT)( name );                              68                  return g_orig_dll.get_api!(FnT)( name );
   76          }                                                                             69          }
   77  }                                                                                     70  }
   78                                                                                        71  
   79  //----------------------------------------------------------------                    72  //----------------------------------------------------------------
   80  // 統合アーカイバAPI:転送                                                                      73  // 統合アーカイバAPI:転送
   81  //----------------------------------------------------------------                    74  //----------------------------------------------------------------
   82                                                                                        75  
   83  extern(Windows)                                                                       76  extern(Windows)
   84  {                                                                                     77  {
   85          int Bga( HWND a, char* b, char* c, DWORD d )                             |    78          int Bga( HWND a, immutable char* b, char* c, DWORD d )
   86          {                                                                             79          {
   87                  int r = Bga_impl( a, toString(b) );                              |    80                  int r = Bga_impl( a, b.fromStringz() );
   88                  if( r < 0 ) // このダミーDLLでは処理できないコマンドだった時                               81                  if( r < 0 ) // このダミーDLLでは処理できないコマンドだった時
   89                          return api!(typeof(&Bga))("Bga")(a,b,c,d);                    82                          return api!(typeof(&Bga))("Bga")(a,b,c,d);
   90                  return r;                                                             83                  return r;
   91          }                                                                             84          }
   92                                                                                        85  
   93          WORD QBgaGetVersion()                                                         86          WORD QBgaGetVersion()
   94          {                                                                             87          {
................................................................................................................................................................................
  203          }                                                                            196          }
  204  }                                                                                    197  }
  205                                                                                       198  
  206  //----------------------------------------------------------------                   199  //----------------------------------------------------------------
  207  // 統合アーカイバAPI:実装( Bga )                                                              200  // 統合アーカイバAPI:実装( Bga )
  208  //----------------------------------------------------------------                   201  //----------------------------------------------------------------
  209                                                                                       202  
  210  int Bga_impl( HWND wnd, char[] cmd_str )                                         |   203  int Bga_impl( HWND wnd, string cmd_str )
  211  {                                                                                    204  {
  212          enum { UNSUPPORTED = -1 }                                                    205          enum { UNSUPPORTED = -1 }
  213                                                                                       206  
  214          //                                                                           207          //
  215          // コマンドライン解析                                                                 208          // コマンドライン解析
  216          //                                                                           209          //
  217          char[][] cmd = cmd_parse(cmd_str);                                       |   210          string[] cmd = cmd_parse(cmd_str);
  218                                                                                       211  
  219          // x以外のコマンドは扱わないで本物DLLに回します。注意点として:                                          212          // x以外のコマンドは扱わないで本物DLLに回します。注意点として:
  220          //  > command はコマンドラインの最初の引数としてください。なお、command を省略                           213          //  > command はコマンドラインの最初の引数としてください。なお、command を省略
  221          //  > した場合は 'x' command が指定されたものとみなします。                                      214          //  > した場合は 'x' command が指定されたものとみなします。
  222          if( cmd.length == 0 )                                                        215          if( cmd.length == 0 )
  223                  return UNSUPPORTED;                                                  216                  return UNSUPPORTED;
  224          if( cmd[0].length == 1 )                                                     217          if( cmd[0].length == 1 )
  225          {                                                                            218          {
  226                  if( 0 <= find("adjlmnstvADJLMNSTV", cmd[0][0]) )                 |   219                  if( 0 <= "adjlmnstvADJLMNSTV".indexOf(cmd[0][0]) )
  227                          return UNSUPPORTED;                                          220                          return UNSUPPORTED;
  228                  if( cmd[0][0]=='x' || cmd[0][0]=='X' )                               221                  if( cmd[0][0]=='x' || cmd[0][0]=='X' )
  229                          cmd = cmd[1 .. length];                                  |   222                          cmd = cmd[1 .. $];
  230          }                                                                            223          }
  231                                                                                       224  
  232                  // ※ この時点で、cmdにはcommandを除いた残りの引数が入っているはず                         |   225          // ※ この時点で、cmdにはcommandを除いた残りの引数が入っているはず
  233                                                                                       226  
  234          //                                                                           227          //
  235          // スイッチ解析、引数解析                                                               228          // スイッチ解析、引数解析
  236          //                                                                           229          //
  237          bool all_attrs       = false; // -a                                          230          bool all_attrs       = false; // -a
  238          bool silent          = false; // -i                                          231          bool silent          = false; // -i
  239          bool ignore_dir      = false; // -j                                          232          bool ignore_dir      = false; // -j
  240          bool newfile_only    = false; // -n                                          233          bool newfile_only    = false; // -n
  241          bool force_overwrite = false; // -o                                          234          bool force_overwrite = false; // -o
  242          bool recursive       = false; // -r                                          235          bool recursive       = false; // -r
  243          bool sanitize_path   = true;                                                 236          bool sanitize_path   = true;
  244                                                                                       237  
  245          char[] arc_name = null;                                                  |   238          string arc_name = null;
  246          char[] base_dir = null;                                                  |   239          string base_dir = null;
  247          char[][] paths;                                                          |   240          string[] paths;
  248                                                                                       241  
  249          foreach( char[] param ; cmd )                                            |   242          foreach( string param ; cmd )
  250                  if( param[0] == '-' )                                                243                  if( param[0] == '-' )
  251                          switch( param[1] )                                           244                          switch( param[1] )
  252                          {                                                            245                          {
  253                          case 'a','A': all_attrs       = true; break;                 246                          case 'a','A': all_attrs       = true; break;
  254                          case 'i','I': silent          = true; break;                 247                          case 'i','I': silent          = true; break;
  255                          case 'j','J': ignore_dir      = true; break;                 248                          case 'j','J': ignore_dir      = true; break;
  256                          case 'n','N': newfile_only    = true; break;                 249                          case 'n','N': newfile_only    = true; break;
................................................................................................................................................................................
  263                          arc_name = param;                                            256                          arc_name = param;
  264                  }                                                                    257                  }
  265                  else if( base_dir is null )                                          258                  else if( base_dir is null )
  266                  {                                                                    259                  {
  267                          if( lastChar(param) == '\\' )                                260                          if( lastChar(param) == '\\' )
  268                                  base_dir = param;                                    261                                  base_dir = param;
  269                          else {                                                       262                          else {
                                                                                        >   263                                  char[] buf;
  270                                  base_dir.length = GetCurrentDirectory(0,null)+1; |   264                                  buf.length = GetCurrentDirectoryA(0,null)+1;
  271                                  GetCurrentDirectory(base_dir.length, base_dir);  |   265                                  GetCurrentDirectoryA(buf.length, buf.ptr);
  272                                  base_dir.length = strlen(base_dir);              <
                                                                                        >   266                                  base_dir = buf.ptr.fromStringz().idup;
  273                                  if( lastChar(base_dir) != '\\' )                     267                                  if( lastChar(base_dir) != '\\' )
  274                                          base_dir ~= '\\';                            268                                          base_dir ~= '\\';
  275                          }                                                            269                          }
  276                  }                                                                    270                  }
  277                  else                                                                 271                  else
  278                          paths ~= param;                                              272                          paths ~= param;
  279                                                                                       273  
................................................................................................................................................................................
  289                  if( !silent && g_handler is null ) // -i / OwnerWndProc              283                  if( !silent && g_handler is null ) // -i / OwnerWndProc
  290                  {                                                                    284                  {
  291                          dlg = new ProgressDlg(                                       285                          dlg = new ProgressDlg(
  292                                  cast(DLGTEMPLATE*) g_orig_dll.load_dialog("#2025     286                                  cast(DLGTEMPLATE*) g_orig_dll.load_dialog("#2025
  293                          dlg.set_arcname(arc_name);                                   287                          dlg.set_arcname(arc_name);
  294                  }                                                                    288                  }
  295                                                                                       289  
  296                  char[]    src_fname; // OwnerWndProc関係                           |   290                  string    src_fname; // OwnerWndProc関係
  297                  BgaHeader cur_hdr;   // OwnerWndProc関係                               291                  BgaHeader cur_hdr;   // OwnerWndProc関係
  298                                                                                       292  
  299                  BgaAnswer handler( inout BgaHeader hdr )                         |   293                  BgaAnswer handler( ref BgaHeader hdr )
  300                  {                                                                    294                  {
  301                          src_fname = hdr.fname;                                       295                          src_fname = hdr.fname;
  302                          process_messages();                                          296                          process_messages();
  303                                                                                       297  
  304                          // paths                                                     298                          // paths
  305                          if( paths.length > 0 )                                       299                          if( paths.length > 0 )
  306                          {                                                            300                          {
  307                                  char[] fname = // -r                             |   301                                  string fname = // -r
  308                                          (recursive ? hdr.fname[hdr.dir_name_len. |   302                                          (recursive ? hdr.fname[hdr.dir_name_len.
  309                                                     : hdr.fname);                 <
  310                                  foreach( char[] w ; paths )                      |   303                                  foreach( string w ; paths )
  311                                          if( wild_match( w, fname ) )                 304                                          if( wild_match( w, fname ) )
  312                                                  goto ok;                             305                                                  goto ok;
  313                                  return BgaAnswer.SkipIt;                             306                                  return BgaAnswer.SkipIt;
  314                          ok:;                                                         307                          ok:;
  315                          }                                                            308                          }
  316                          // -a                                                        309                          // -a
  317                          if( !all_attrs && (hdr.attrib&6) )                           310                          if( !all_attrs && (hdr.attrib&6) )
  318                                  return BgaAnswer.SkipIt;                             311                                  return BgaAnswer.SkipIt;
  319                          // dialog                                                    312                          // dialog
  320                          if( dlg )                                                    313                          if( dlg )
  321                                  if( dlg.closed )                                     314                                  if( dlg.closed )
  322                                          return BgaAnswer.Abort;                      315                                          return BgaAnswer.Abort;
  323                                  else                                                 316                                  else
  324                                          dlg.set_filename( hdr.fname[hdr.dir_name |   317                                          dlg.set_filename( hdr.fname[hdr.dir_name
  325                          // -j                                                        318                          // -j
  326                          if( ignore_dir )                                             319                          if( ignore_dir )
  327                                  hdr.fname = hdr.fname[hdr.dir_name_len .. length |   320                                  hdr.fname = hdr.fname[hdr.dir_name_len .. $];
  328                          // sanitize                                                  321                          // sanitize
  329                          if( sanitize_path )                                          322                          if( sanitize_path )
  330                                  hdr.fname = check_path(hdr.fname);                   323                                  hdr.fname = check_path(hdr.fname);
  331                          // base_dir                                                  324                          // base_dir
  332                          hdr.fname = base_dir ~ hdr.fname;                        |   325                          hdr.fname = (base_dir ~ hdr.fname).dup;
  333                          // -o                                                        326                          // -o
  334                          if( !force_overwrite )                                       327                          if( !force_overwrite )
  335                                  try {                                                328                                  try {
  336                                  if( std.file.exists(hdr.fname) && std.file.isfil |   329                                  if( std.file.exists(hdr.fname) && std.file.isFil
  337                                          // -n                                        330                                          // -n
  338                                          if( newfile_only )                           331                                          if( newfile_only )
  339                                          {                                            332                                          {
  340                                                  if( newer_than(hdr.date,hdr.time     333                                                  if( newer_than(hdr.date,hdr.time
  341                                                          return BgaAnswer.SkipIt;     334                                                          return BgaAnswer.SkipIt;
  342                                          }                                            335                                          }
  343                                          else                                         336                                          else
  344                                          {                                            337                                          {
  345                                                  int r = MessageBox( dlg?dlg.hwnd |   338                                                  int r = MessageBoxA( dlg?dlg.hwn
  346                                                          toStringz("Overwrite "~h     339                                                          toStringz("Overwrite "~h
  347                                                          "QBga32.dll", MB_YESNOCA     340                                                          "QBga32.dll", MB_YESNOCA
  348                                                  if( r == IDNO )     return BgaAn     341                                                  if( r == IDNO )     return BgaAn
  349                                                  if( r == IDCANCEL ) return BgaAn     342                                                  if( r == IDCANCEL ) return BgaAn
  350                                          }                                            343                                          }
  351                                  } catch {}                                           344                                  } catch {}
  352                                                                                       345  
................................................................................................................................................................................
  410          char  szMode[8];                                                             403          char  szMode[8];
  411  }                                                                                    404  }
  412                                                                                       405  
  413  HWND g_owner_window;                                                                 406  HWND g_owner_window;
  414  extern(Windows) BOOL function(HWND,UINT,UINT,EXTRACTINGINFOEX*) g_handler;           407  extern(Windows) BOOL function(HWND,UINT,UINT,EXTRACTINGINFOEX*) g_handler;
  415  extern(Windows) BOOL noex_handler( HWND w,UINT m,UINT s, EXTRACTINGINFOEX* e )       408  extern(Windows) BOOL noex_handler( HWND w,UINT m,UINT s, EXTRACTINGINFOEX* e )
  416  {                                                                                    409  {
  417          return !SendMessage( w, m, s, cast(LPARAM) &e.exinfo );                  |   410          return !SendMessageA( w, m, s, cast(LPARAM) &e.exinfo );
  418  }                                                                                    411  }
  419                                                                                       412  
  420  void BgaSetOwnerWindow_impl( HWND wnd )                                              413  void BgaSetOwnerWindow_impl( HWND wnd )
  421  {                                                                                    414  {
  422          g_owner_window = wnd;                                                        415          g_owner_window = wnd;
  423          g_handler      = &noex_handler;                                              416          g_handler      = &noex_handler;
  424  }                                                                                    417  }
................................................................................................................................................................................
  432  void BgaSetOwnerWindowEx_impl( HWND wnd, ARCHIVERPROC* proc )                        425  void BgaSetOwnerWindowEx_impl( HWND wnd, ARCHIVERPROC* proc )
  433  {                                                                                    426  {
  434          g_owner_window = wnd;                                                        427          g_owner_window = wnd;
  435          g_handler      = *proc;                                                      428          g_handler      = *proc;
  436  }                                                                                    429  }
  437                                                                                       430  
  438  enum { OP_FILE_BEGIN, OP_FILE_MIDDLE, OP_ARC_END, OP_ARC_BEGIN }                     431  enum { OP_FILE_BEGIN, OP_FILE_MIDDLE, OP_ARC_END, OP_ARC_BEGIN }
  439  bool do_ownerwnd_proc( UINT uState, BgaHeader* hdr, int cur, char[] src_fname )  |   432  bool do_ownerwnd_proc( UINT uState, BgaHeader* hdr, int cur, string src_fname )
  440  {                                                                                    433  {
  441          if( g_handler is null )                                                      434          if( g_handler is null )
  442                  return true;                                                         435                  return true;
  443          EXTRACTINGINFOEX ex;                                                         436          EXTRACTINGINFOEX ex;
  444          if( uState == OP_ARC_BEGIN || uState == OP_ARC_END )                         437          if( uState == OP_ARC_BEGIN || uState == OP_ARC_END )
  445          {                                                                            438          {
  446                  lstrcpyn( ex.exinfo.szSourceFileName, toStringz(src_fname), 512  |   439                  lstrcpynA( ex.exinfo.szSourceFileName.ptr, toStringz(src_fname),
  447          }                                                                            440          }
  448          else                                                                         441          else
  449          {                                                                            442          {
  450                  ex.exinfo.dwFileSize  = hdr.original_size;                           443                  ex.exinfo.dwFileSize  = hdr.original_size;
  451                  ex.exinfo.dwWriteSize = cur;                                         444                  ex.exinfo.dwWriteSize = cur;
  452                  lstrcpyn( ex.exinfo.szSourceFileName, toStringz(src_fname), 512  |   445                  lstrcpynA( ex.exinfo.szSourceFileName.ptr, toStringz(src_fname),
  453                  lstrcpyn( ex.exinfo.szDestFileName, toStringz(hdr.fname), 512 ); |   446                  lstrcpynA( ex.exinfo.szDestFileName.ptr, toStringz(hdr.fname), 5
  454                  ex.dwCompressedSize = hdr.compressed_size;                           447                  ex.dwCompressedSize = hdr.compressed_size;
  455                  ex.wRatio = cast(int)( (cast(real)hdr.compressed_size)/hdr.origi |   448                  ex.wRatio = cast(ushort)( (cast(real)hdr.compressed_size)/hdr.or
  456                  ex.wDate  = hdr.date;                                                449                  ex.wDate  = hdr.date;
  457                  ex.wTime  = hdr.time;                                                450                  ex.wTime  = hdr.time;
  458                  ex.szAttribute[0] = (hdr.attrib&32 ? 'A': '-');                      451                  ex.szAttribute[0] = (hdr.attrib&32 ? 'A': '-');
  459                  ex.szAttribute[1] = (hdr.attrib&1  ? 'R': '-');                      452                  ex.szAttribute[1] = (hdr.attrib&1  ? 'R': '-');
  460                  ex.szAttribute[2] = (hdr.attrib&2  ? 'H': '-');                      453                  ex.szAttribute[2] = (hdr.attrib&2  ? 'H': '-');
  461                  ex.szAttribute[3] = (hdr.attrib&4  ? 'S': '-');                      454                  ex.szAttribute[3] = (hdr.attrib&4  ? 'S': '-');
  462                  ex.szAttribute[4] = (hdr.attrib&16 ? 'D': '-');                      455                  ex.szAttribute[4] = (hdr.attrib&16 ? 'D': '-');
  463                  ex.szAttribute[5] = '\0';                                            456                  ex.szAttribute[5] = '\0';
  464                  if( hdr.method[0]=='G' )                                             457                  if( hdr.method[0]=='G' )
  465                          lstrcpy(ex.szMode,"-gzip-");                             |   458                          lstrcpyA(ex.szMode.ptr,"-gzip-");
  466                  else                                                                 459                  else
  467                          lstrcpy(ex.szMode,"-bzip2-");                            |   460                          lstrcpyA(ex.szMode.ptr,"-bzip2-");
  468          }                                                                            461          }
  469                                                                                       462  
  470          return false != g_handler( g_owner_window, WM_ARCEXTRACT, uState, &ex );     463          return false != g_handler( g_owner_window, WM_ARCEXTRACT, uState, &ex );
  471  }                                                                                    464  }
  472                                                                                       465  
  473  //----------------------------------------------------------------                   466  //----------------------------------------------------------------
  474  // パス検査系                                                                             467  // パス検査系
  475  //----------------------------------------------------------------                   468  //----------------------------------------------------------------
  476                                                                                       469  
  477  alias std.c.windows.windows.IsDBCSLeadByte isDL;                                 |   470  alias core.sys.windows.windows.IsDBCSLeadByte isDL;
  478  char[] replace_yen( char[] s )                                                   |   471  string replace_yen( string s )
  479  {                                                                                    472  {
  480          char[] ans;                                                              |   473          string ans;
  481          int j=0;                                                                     474          int j=0;
  482          for(int i=0; i!=s.length; i=i+(isDL(s[i])?2:1))                              475          for(int i=0; i!=s.length; i=i+(isDL(s[i])?2:1))
  483                  if( s[i] == '\\' )                                                   476                  if( s[i] == '\\' )
  484                          ans~=s[j .. i], ans~='/', j=i+1;                             477                          ans~=s[j .. i], ans~='/', j=i+1;
  485          ans ~= s[j .. length];                                                   |   478          ans ~= s[j .. $];
  486          return ans;                                                                  479          return ans;
  487  }                                                                                    480  }
  488                                                                                       481  
  489  bool wild_match( char[] wild, char[] name )                                      |   482  bool wild_match( string wild, string name )
  490  {                                                                                    483  {
  491          bool wild_match_nopath( char[] w, char[] s )                             |   484          bool wild_match_nopath( string w, string s )
  492          {                                                                            485          {
  493                  char[] advance( char[] s )                                       |   486                  string advance( string s )
  494                  {                                                                    487                  {
  495                          return s[(IsDBCSLeadByte(s[0])?2:1) .. length];          |   488                          return s[(IsDBCSLeadByte(s[0])?2:1) .. $];
  496                  }                                                                    489                  }
  497                                                                                       490  
  498                  while( w.length>0 )                                                  491                  while( w.length>0 )
  499                          switch( w[0] )                                               492                          switch( w[0] )
  500                          {                                                            493                          {
  501                          case '?':                                                    494                          case '?':
  502                                  if( s.length==0 )                                    495                                  if( s.length==0 )
................................................................................................................................................................................
  527                          }                                                            520                          }
  528                  return s.length==0;                                                  521                  return s.length==0;
  529          }                                                                            522          }
  530                                                                                       523  
  531          if( wild=="" || wild=="*.*" || wild=="*" || wild=="**" )                     524          if( wild=="" || wild=="*.*" || wild=="*" || wild=="**" )
  532                  return true;                                                         525                  return true;
  533                                                                                       526  
  534          char[][] wilds = split( replace_yen( tolower(wild) ), "/" );             |   527          string[] wilds = split( replace_yen( toLower(wild) ), "/" );
  535          char[][] names = split( replace_yen( tolower(name) ), "/" );             |   528          string[] names = split( replace_yen( toLower(name) ), "/" );
  536                                                                                       529  
  537          if( wilds.length != names.length )                                           530          if( wilds.length != names.length )
  538                  return false;                                                        531                  return false;
  539          for(int i=0; i!=wilds.length; ++i)                                           532          for(int i=0; i!=wilds.length; ++i)
  540                  if( wilds[i]!="*.*" && wilds[i]!="*" && wilds[i]!="**" )             533                  if( wilds[i]!="*.*" && wilds[i]!="*" && wilds[i]!="**" )
  541                          if( !wild_match_nopath( wilds[i], names[i] ) )               534                          if( !wild_match_nopath( wilds[i], names[i] ) )
  542                                  return false;                                        535                                  return false;
  543          return true;                                                                 536          return true;
  544  }                                                                                    537  }
  545                                                                                       538  
  546  char[] check_path( char[] path )                                                 |   539  string check_path( string in_path )
  547  {                                                                                    540  {
                                                                                        >   541          char[] path = in_path.dup;
                                                                                        >   542  
  548          // C:\ ==> C_\                                                               543          // C:\ ==> C_\
  549          if( path.length>=2 && path[1]==':' )                                         544          if( path.length>=2 && path[1]==':' )
  550                  path = path.dup, path[1] = '_';                                  |   545                  path[1] = '_';
  551                                                                                       546  
  552          // \\hoge ==> hoge                                                           547          // \\hoge ==> hoge
  553          // /hoge  ==> hoge                                                           548          // /hoge  ==> hoge
  554          while( path.length>0 && (path[0]=='\\'||path[0]=='/') )                      549          while( path.length>0 && (path[0]=='\\'||path[0]=='/') )
  555                  path = path[1..length];                                          |   550                  path = path[1..$];
  556                                                                                       551  
  557          // .. ==> __                                                                 552          // .. ==> __
  558          char[][] paths = split( replace_yen(path), "/" );                        |   553          string[] paths = split( replace_yen(path.idup), "/" );
  559          L1:                                                                          554          L1:
  560          foreach( inout char[] pc ; paths )                                       |   555          foreach( ref string pc ; paths )
  561                  if( pc.length >= 2 )                                                 556                  if( pc.length >= 2 )
  562                  {                                                                    557                  {
  563                          foreach( char c ; pc )                                       558                          foreach( char c ; pc )
  564                                  if( c != '.' )                                       559                                  if( c != '.' )
  565                                          continue L1;                                 560                                          continue L1;
  566                          pc = replace( pc, ".", "_" );                                561                          pc = replace( pc, ".", "_" );
  567                  }                                                                    562                  }