@@ -136,14 +136,14 @@ find_c::find_c()
136136find_c::~find_c ()
137137{}
138138
139- bool GlobMatch ( const std::filesystem::path& glob, const std::filesystem::path& file )
139+ std::optional<std::string> BuildGlobPattern ( std::filesystem::path const & glob )
140140{
141141 using namespace std ::literals::string_view_literals;
142- auto globStr = glob.generic_u8string ();
142+ auto globStr = glob.u8string ();
143143
144144 // Deal with traditional "everything" wildcards.
145145 if (glob == " *" || glob == " *.*" ) {
146- return true ;
146+ return {} ;
147147 }
148148
149149 fmt::memory_buffer buf;
@@ -179,32 +179,34 @@ bool GlobMatch(const std::filesystem::path& glob, const std::filesystem::path& f
179179 }
180180 }
181181 }
182+ return to_string (buf);
183+ }
182184
185+ bool GlobMatch (std::optional<std::string> const & globPattern, std::filesystem::path const & file)
186+ {
187+ if (!globPattern.has_value ()) {
188+ // Empty pattern is like "*" and "*.*".
189+ return true ;
190+ }
183191 // Assume case-insensitive comparisons are desired.
184192 RE2::Options reOpts;
185193 reOpts.set_case_sensitive (false );
186- RE2 reGlob{to_string (buf ), reOpts};
194+ RE2 reGlob{globPattern. value ( ), reOpts};
187195
188- auto fileStr = file.generic_u8string ();
196+ auto fileStr = file.u8string ();
189197 return RE2::FullMatch (fileStr, reGlob);
190198}
191199
192- bool find_c::FindFirst (const char * fileSpec)
200+ bool find_c::FindFirst (std::filesystem::path const && fileSpec)
193201{
194- #ifdef _WIN32
195- wchar_t * wideSpec = WidenUTF8String (fileSpec);
196- std::filesystem::path p (wideSpec);
197- FreeWideString (wideSpec);
198- #else
199- std::filesystem::path p (fileSpec);
200- #endif
201- glob = p.filename ();
202+ auto parent = fileSpec.parent_path ();
203+ globPattern = BuildGlobPattern (fileSpec.filename ());
202204
203205 std::error_code ec;
204- for (iter = std::filesystem::directory_iterator (p. parent_path () , ec); iter != std::filesystem::directory_iterator{}; ++iter) {
206+ for (iter = std::filesystem::directory_iterator (parent , ec); iter != std::filesystem::directory_iterator{}; ++iter) {
205207 auto candFilename = iter->path ().filename ();
206- if (GlobMatch (glob , candFilename)) {
207- fileName = candFilename. u8string () ;
208+ if (GlobMatch (globPattern , candFilename)) {
209+ fileName = candFilename;
208210 isDirectory = iter->is_directory ();
209211 fileSize = iter->file_size ();
210212 auto mod = iter->last_write_time ();
@@ -223,8 +225,8 @@ bool find_c::FindNext()
223225
224226 for (++iter; iter != std::filesystem::directory_iterator{}; ++iter) {
225227 auto candFilename = iter->path ().filename ();
226- if (GlobMatch (glob , candFilename)) {
227- fileName = candFilename. u8string () ;
228+ if (GlobMatch (globPattern , candFilename)) {
229+ fileName = candFilename;
228230 isDirectory = iter->is_directory ();
229231 fileSize = iter->file_size ();
230232 auto mod = iter->last_write_time ();
@@ -398,26 +400,27 @@ bool sys_main_c::SetWorkDir(std::filesystem::path const& newCwd)
398400 }
399401}
400402
401- void sys_main_c::SpawnProcess (const char * cmdName, const char * argList)
403+ void sys_main_c::SpawnProcess (std::filesystem::path cmdName, const char * argList)
402404{
403405#ifdef _WIN32
404- char cmd[512 ];
405- strcpy (cmd, cmdName);
406- if ( !strchr (cmd, ' .' ) ) {
407- strcat (cmd, " .exe" );
406+ if (!cmdName.has_extension ()) {
407+ cmdName.replace_extension (" .exe" );
408408 }
409- SHELLEXECUTEINFOA sinfo;
410- memset (&sinfo, 0 , sizeof (SHELLEXECUTEINFOA));
411- sinfo.cbSize = sizeof (SHELLEXECUTEINFOA);
409+ auto fileStr = cmdName.wstring ();
410+ auto wideArgs = WidenUTF8String (argList);
411+ SHELLEXECUTEINFOW sinfo;
412+ memset (&sinfo, 0 , sizeof (sinfo));
413+ sinfo.cbSize = sizeof (sinfo);
412414 sinfo.fMask = SEE_MASK_NOCLOSEPROCESS;
413- sinfo.lpFile = cmd ;
414- sinfo.lpParameters = argList ;
415- sinfo.lpVerb = " open" ;
415+ sinfo.lpFile = fileStr. c_str () ;
416+ sinfo.lpParameters = wideArgs ;
417+ sinfo.lpVerb = L " open" ;
416418 sinfo.nShow = SW_SHOWMAXIMIZED;
417- if ( !ShellExecuteExA (&sinfo) ) {
418- sinfo.lpVerb = " runas" ;
419- ShellExecuteExA (&sinfo);
419+ if ( !ShellExecuteExW (&sinfo) ) {
420+ sinfo.lpVerb = L " runas" ;
421+ ShellExecuteExW (&sinfo);
420422 }
423+ FreeWideString (wideArgs);
421424#else
422425#warning LV: Subprocesses not implemented on this OS.
423426 // TODO(LV): Implement subprocesses for other OSes.
0 commit comments