mirror of
https://github.com/qpdf/qpdf.git
synced 2024-12-22 02:49:00 +00:00
Pull wmain -> main code from qpdf.cc into QUtil.cc
This commit is contained in:
parent
ab4061f1ee
commit
a44b5a34a0
@ -1,3 +1,9 @@
|
||||
2020-01-14 Jay Berkenbilt <ejb@ql.org>
|
||||
|
||||
* Add QUtil::call_main_from_wmain, a helper function that can be
|
||||
called in the body of wmain to convert UTF-16 arguments to UTF-8
|
||||
arguments and then call another main function.
|
||||
|
||||
2020-01-13 Jay Berkenbilt <ejb@ql.org>
|
||||
|
||||
* QUtil::read_lines_from_file: add new versions that use FILE*,
|
||||
|
@ -362,6 +362,13 @@ namespace QUtil
|
||||
// command-line tool. May throw std::runtime_error.
|
||||
QPDF_DLL
|
||||
std::vector<int> parse_numrange(char const* range, int max);
|
||||
|
||||
// Take an argv array consisting of wchar_t, as when wmain is
|
||||
// invoked, convert all UTF-16 encoded strings to UTF-8, and call
|
||||
// another main.
|
||||
QPDF_DLL
|
||||
int call_main_from_wmain(int argc, wchar_t* argv[],
|
||||
std::function<int(int, char*[])> realmain);
|
||||
};
|
||||
|
||||
#endif // QUTIL_HH
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <memory>
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <direct.h>
|
||||
@ -2361,3 +2362,38 @@ QUtil::possible_repaired_encodings(std::string supplied)
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
int
|
||||
QUtil::call_main_from_wmain(int argc, wchar_t* argv[], std::function<int(int, char*[])> realmain)
|
||||
{
|
||||
// argv contains UTF-16-encoded strings with a 16-bit wchar_t.
|
||||
// Convert this to UTF-8-encoded strings for compatibility with
|
||||
// other systems. That way the rest of qpdf.cc can just act like
|
||||
// arguments are UTF-8.
|
||||
|
||||
std::vector<std::shared_ptr<char>> utf8_argv;
|
||||
for (int i = 0; i < argc; ++i)
|
||||
{
|
||||
std::string utf16;
|
||||
for (size_t j = 0; j < wcslen(argv[i]); ++j)
|
||||
{
|
||||
unsigned short codepoint = static_cast<unsigned short>(argv[i][j]);
|
||||
utf16.append(1, static_cast<char>(
|
||||
QIntC::to_uchar(codepoint >> 8)));
|
||||
utf16.append(1, static_cast<char>(
|
||||
QIntC::to_uchar(codepoint & 0xff)));
|
||||
}
|
||||
std::string utf8 = QUtil::utf16_to_utf8(utf16);
|
||||
utf8_argv.push_back(std::shared_ptr<char>(QUtil::copy_string(utf8.c_str()), std::default_delete<char[]>()));
|
||||
}
|
||||
auto utf8_argv_sp =
|
||||
std::shared_ptr<char*>(new char*[1+utf8_argv.size()], std::default_delete<char*[]>());
|
||||
char** new_argv = utf8_argv_sp.get();
|
||||
for (size_t i = 0; i < utf8_argv.size(); ++i)
|
||||
{
|
||||
new_argv[i] = utf8_argv.at(i).get();
|
||||
}
|
||||
argc = QIntC::to_int(utf8_argv.size());
|
||||
new_argv[argc] = 0;
|
||||
return realmain(argc, new_argv);
|
||||
}
|
||||
|
@ -105,3 +105,7 @@ rename file
|
||||
create file
|
||||
rename over existing
|
||||
delete file
|
||||
---- wmain
|
||||
ascii
|
||||
10 ÷ 2 = 5
|
||||
qwww÷π
|
||||
|
@ -543,6 +543,17 @@ void rename_delete_test()
|
||||
assert_no_file("old\xcf\x80.~tmp");
|
||||
}
|
||||
|
||||
void wmain_test()
|
||||
{
|
||||
auto realmain = [](int argc, char* argv[]) {
|
||||
for (int i = 0; i < argc; ++i) { std::cout << argv[i] << std::endl; } return 0; };
|
||||
wchar_t* argv[3];
|
||||
argv[0] = const_cast<wchar_t*>(L"ascii");
|
||||
argv[1] = const_cast<wchar_t*>(L"10 \xf7 2 = 5");
|
||||
argv[2] = const_cast<wchar_t*>(L"qwww\xf7\x03c0");
|
||||
QUtil::call_main_from_wmain(3, argv, realmain);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
try
|
||||
@ -573,6 +584,8 @@ int main(int argc, char* argv[])
|
||||
hex_encode_decode_test();
|
||||
std::cout << "---- rename/delete" << std::endl;
|
||||
rename_delete_test();
|
||||
std::cout << "---- wmain" << std::endl;
|
||||
wmain_test();
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
|
31
qpdf/qpdf.cc
31
qpdf/qpdf.cc
@ -5304,36 +5304,7 @@ int realmain(int argc, char* argv[])
|
||||
extern "C"
|
||||
int wmain(int argc, wchar_t* argv[])
|
||||
{
|
||||
// If wmain is supported, argv contains UTF-16-encoded strings
|
||||
// with a 16-bit wchar_t. Convert this to UTF-8-encoded strings
|
||||
// for compatibility with other systems. That way the rest of
|
||||
// qpdf.cc can just act like arguments are UTF-8.
|
||||
std::vector<PointerHolder<char> > utf8_argv;
|
||||
for (int i = 0; i < argc; ++i)
|
||||
{
|
||||
std::string utf16;
|
||||
for (size_t j = 0; j < wcslen(argv[i]); ++j)
|
||||
{
|
||||
unsigned short codepoint = static_cast<unsigned short>(argv[i][j]);
|
||||
utf16.append(1, static_cast<char>(
|
||||
QIntC::to_uchar(codepoint >> 8)));
|
||||
utf16.append(1, static_cast<char>(
|
||||
QIntC::to_uchar(codepoint & 0xff)));
|
||||
}
|
||||
std::string utf8 = QUtil::utf16_to_utf8(utf16);
|
||||
utf8_argv.push_back(
|
||||
PointerHolder<char>(true, QUtil::copy_string(utf8.c_str())));
|
||||
}
|
||||
PointerHolder<char*> utf8_argv_ph =
|
||||
PointerHolder<char*>(true, new char*[1+utf8_argv.size()]);
|
||||
char** new_argv = utf8_argv_ph.getPointer();
|
||||
for (size_t i = 0; i < utf8_argv.size(); ++i)
|
||||
{
|
||||
new_argv[i] = utf8_argv.at(i).getPointer();
|
||||
}
|
||||
argc = QIntC::to_int(utf8_argv.size());
|
||||
new_argv[argc] = 0;
|
||||
return realmain(argc, new_argv);
|
||||
return QUtil::call_main_from_wmain(argc, argv, realmain);
|
||||
}
|
||||
|
||||
#else
|
||||
|
Loading…
Reference in New Issue
Block a user