Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Add pchar.h and main.h
  • Loading branch information
brson committed Feb 22, 2023
commit 4d163f233547ac598ffec99212973742acd429ed
1 change: 1 addition & 0 deletions src/support/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ set(support_SOURCES
file.cpp
istring.cpp
path.cpp
pchar.cpp
safe_integer.cpp
threads.cpp
utilities.cpp
Expand Down
36 changes: 36 additions & 0 deletions src/support/main.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright 2016 WebAssembly Community Group participants
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

//
// Cross-platform definition of main.
//
// Users will write main like:
//
// int BYN_MAIN(int argc, const pchar* argv[]) { ... }
//

#ifndef wasm_support_main_h
#define wasm_support_main_h

#include "support/pchar.h"

#ifdef _WIN32
#define BYN_MAIN wmain
#else
#define BYN_MAIN main
#endif

#endif // wasm_support_main_h
94 changes: 94 additions & 0 deletions src/support/pchar.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* Copyright 2015 WebAssembly Community Group participants
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "pchar.h"

namespace wasm {

#ifdef _WIN32

#include "windows.h"

// The conversion functions here will always succeed, with invalid chars
// converted to replacement chars. If there are bugs here they should manifest
// in file-not-found errors and not something worse.

wasm::pstring string_to_pstring(const std::string& s) {
auto inptr = s.data();
auto inlen = s.size();
auto outlen = MultiByteToWideChar(CP_UTF8, 0, inptr, inlen, NULL, 0);
auto outstr = wasm::pstring(outlen, 0);
auto outptr = outstr.data();
MultiByteToWideChar(CP_UTF8, 0, inptr, inlen, outptr, outlen);
return outstr;
}

std::string pstring_to_string(const wasm::pstring& s) {
auto inptr = s.data();
auto inlen = s.size();
auto outlen = WideCharToMultiByte(CP_UTF8, 0, inptr, inlen, NULL, 0, NULL, NULL);
auto outstr = std::string(outlen, 0);
auto outptr = outstr.data();
WideCharToMultiByte(CP_UTF8, 0, inptr, inlen, outptr, outlen, NULL, NULL);
return outstr;
}

#else

wasm::pstring string_to_pstring(const std::string& s) {
return wasm::pstring(s);
}

std::string pstring_to_string(const wasm::pstring& s) {
return std::string(s);
}

#endif

std::filesystem::path string_to_path(const std::string& s) {
auto pstring = wasm::string_to_pstring(s);
return std::filesystem::path(pstring);
}

fspath::fspath(const std::string& path) {
inner_path = string_to_path(path);
}

fspath::fspath(const char path[]) {
inner_path = string_to_path(std::string(path));
}

fspath::fspath(const wasm::fspath& path) {
inner_path = path.inner_path;
}

fspath::fspath(const std::filesystem::path& path) {
inner_path = path;
}

wasm::fspath fspath::from_pstring(const wasm::pstring& path) {
return fspath(std::filesystem::path(path));
}

wasm::fspath fspath::operator=(const wasm::fspath& path) const {
return wasm::fspath(path);
}

const std::filesystem::path& fspath::stdpath() const {
return inner_path;
}

} // namespace wasm
102 changes: 102 additions & 0 deletions src/support/pchar.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
* Copyright 2015 WebAssembly Community Group participants
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

//
// The platform char / string type.
//
// Used entirely for managing unicode-correct paths on windows.
//

#ifndef wasm_support_pchar_h
#define wasm_support_pchar_h

#include <filesystem>

namespace wasm {

// The platform string type.
//
// basic_string<wchar_t> on Windows, basic_string<char> elsewhere
typedef std::filesystem::path::string_type pstring;
typedef std::filesystem::path::value_type pchar;

// Conversion from string to pstring.
//
// On windows this performs a UTF-8 to UTF-16 conversion, on the assumption that
// the incoming string was previously created through pstring_to_string.
//
// If a non-UTF-8 string is passed as input, then the output will contain
// replacement characters.
//
// On non-windows this just copies the string..
pstring string_to_pstring(const std::string& s);

// Conversion from pstring to string.
//
// On windows this performs a UTF-16 to UTF-8 conversion, on the assumption that
// the pstring was received from the wmain function as UTF-16.
//
// If a non-UTF-16 string is passed as input, then the output will contain
// replacement characters.
//
// On non-windows this just copies the string.
std::string pstring_to_string(const pstring& s);

// A light wrapper around std::filesystem::path
//
// This class only exists to avoid silent errors: the copy constructor performs
// conversion from UTF-8 on windows where the std::filesystem::path constructor
// silently does not.
//
// Using this in APIs instead of std::filesystem::path allows paths to be
// seamlessly and correctly constructed from strings without the possibility of
// silently forgetting a conversion from UTF-8.
//
// The above is true as long as all paths encoded as strings are UTF-8, which is
// true on windows if all CLI arguments are processed through the Options::parse
// method.
class fspath {
public:
fspath(): inner_path() { }
fspath(const std::string& path);
fspath(const char path[]);
fspath(const wasm::fspath& path);

// This exists to satisfy one conversion in read_possible_response_file.
//
// We can't have a constructor from pstring - on windows pstring
// and string are the same type.
//
// We could also make the private constructor from filesystem::path public,
// and the compiler would use it as an implicit conversion from pstring; but
// because filesystem::path also has a lossy conversion from string that
// motivates the existence of this class, we choose to hide that conversion
// and use this explicit static method.
static wasm::fspath from_pstring(const wasm::pstring& path);

wasm::fspath operator=(const wasm::fspath& path) const;

const std::filesystem::path& stdpath() const;

private:
fspath(const std::filesystem::path& path);

std::filesystem::path inner_path;
};

} // namespace wasm

#endif // wasm_support_pchar_h