From 3ae535eae71380d28ae58e872ccebfdf4fcbfc21 Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 14 Sep 2020 02:32:37 +0300 Subject: [PATCH 01/99] Make get_message_dialog_id static. GitOrigin-RevId: 66761856feedcd56b491f19538b6ef61260ad5e8 --- td/telegram/MessagesManager.cpp | 8 ++++---- td/telegram/MessagesManager.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index ff9a1b94a..2ea2b7317 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -2409,7 +2409,7 @@ class SendMultiMediaActor : public NetActorOnce { is_result_wrong = true; } for (auto &sent_message : sent_messages) { - if (td->messages_manager_->get_message_dialog_id(*sent_message) != dialog_id_) { + if (MessagesManager::get_message_dialog_id(*sent_message) != dialog_id_) { is_result_wrong = true; } } @@ -3079,7 +3079,7 @@ class ForwardMessagesActor : public NetActorOnce { is_result_wrong = true; } for (auto &sent_message : sent_messages) { - if (td->messages_manager_->get_message_dialog_id(*sent_message) != to_dialog_id_) { + if (MessagesManager::get_message_dialog_id(*sent_message) != to_dialog_id_) { is_result_wrong = true; } } @@ -10906,7 +10906,7 @@ MessageId MessagesManager::get_message_id(const tl_object_ptr &message_ptr) const { +DialogId MessagesManager::get_message_dialog_id(const tl_object_ptr &message_ptr) { switch (message_ptr->get_id()) { case telegram_api::messageEmpty::ID: return DialogId(); @@ -10925,7 +10925,7 @@ DialogId MessagesManager::get_message_dialog_id(const tl_object_ptr &message_ptr, - bool is_scheduled) const { + bool is_scheduled) { return {get_message_dialog_id(message_ptr), get_message_id(message_ptr, is_scheduled)}; } diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index dd6401861..b01c4625c 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -196,7 +196,7 @@ class MessagesManager : public Actor { static MessageId get_message_id(const tl_object_ptr &message_ptr, bool is_scheduled); - DialogId get_message_dialog_id(const tl_object_ptr &message_ptr) const; + static DialogId get_message_dialog_id(const tl_object_ptr &message_ptr); tl_object_ptr get_input_peer(DialogId dialog_id, AccessRights access_rights) const; @@ -1638,7 +1638,7 @@ class MessagesManager : public Actor { static constexpr bool DROP_UPDATES = false; - FullMessageId get_full_message_id(const tl_object_ptr &message_ptr, bool is_scheduled) const; + static FullMessageId get_full_message_id(const tl_object_ptr &message_ptr, bool is_scheduled); static int32 get_message_date(const tl_object_ptr &message_ptr); From a74d02f412215d4d8fd31af76e9c01f2fc774a8a Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 14 Sep 2020 03:58:57 +0300 Subject: [PATCH 02/99] Add option for checking IP address in the certificate as host. GitOrigin-RevId: dba5b87a59f3d3d3241051ee0257a5786fdf4fb0 --- tdnet/td/net/SslStream.cpp | 9 +++++---- tdnet/td/net/SslStream.h | 3 ++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/tdnet/td/net/SslStream.cpp b/tdnet/td/net/SslStream.cpp index 64f3af931..00d3cb0a4 100644 --- a/tdnet/td/net/SslStream.cpp +++ b/tdnet/td/net/SslStream.cpp @@ -291,7 +291,7 @@ Result create_ssl_ctx(CSlice cert_file, SslStream::VerifyPeer verify_pee class SslStreamImpl { public: - Status init(CSlice host, CSlice cert_file, SslStream::VerifyPeer verify_peer) { + Status init(CSlice host, CSlice cert_file, SslStream::VerifyPeer verify_peer, bool check_ip_address_as_host) { static bool init_openssl = [] { #if OPENSSL_VERSION_NUMBER >= 0x10100000L return OPENSSL_init_ssl(0, nullptr) != 0; @@ -317,7 +317,7 @@ class SslStreamImpl { #if OPENSSL_VERSION_NUMBER >= 0x10002000L X509_VERIFY_PARAM *param = SSL_get0_param(ssl_handle.get()); X509_VERIFY_PARAM_set_hostflags(param, 0); - if (r_ip_address.is_ok()) { + if (r_ip_address.is_ok() && !check_ip_address_as_host) { LOG(DEBUG) << "Set verification IP address to " << r_ip_address.ok().get_ip_str(); X509_VERIFY_PARAM_set1_ip_asc(param, r_ip_address.ok().get_ip_str().c_str()); } else { @@ -509,9 +509,10 @@ SslStream::SslStream(SslStream &&) = default; SslStream &SslStream::operator=(SslStream &&) = default; SslStream::~SslStream() = default; -Result SslStream::create(CSlice host, CSlice cert_file, VerifyPeer verify_peer) { +Result SslStream::create(CSlice host, CSlice cert_file, VerifyPeer verify_peer, + bool use_ip_address_as_host) { auto impl = make_unique(); - TRY_STATUS(impl->init(host, cert_file, verify_peer)); + TRY_STATUS(impl->init(host, cert_file, verify_peer, use_ip_address_as_host)); return SslStream(std::move(impl)); } SslStream::SslStream(unique_ptr impl) : impl_(std::move(impl)) { diff --git a/tdnet/td/net/SslStream.h b/tdnet/td/net/SslStream.h index d5bb6752c..07b832288 100644 --- a/tdnet/td/net/SslStream.h +++ b/tdnet/td/net/SslStream.h @@ -25,7 +25,8 @@ class SslStream { enum class VerifyPeer { On, Off }; - static Result create(CSlice host, CSlice cert_file = CSlice(), VerifyPeer verify_peer = VerifyPeer::On); + static Result create(CSlice host, CSlice cert_file = CSlice(), VerifyPeer verify_peer = VerifyPeer::On, + bool check_ip_address_as_host = false); ByteFlowInterface &read_byte_flow(); ByteFlowInterface &write_byte_flow(); From e96e8a45f879a503bbaae4409193566d49ff212a Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 14 Sep 2020 12:48:10 +0300 Subject: [PATCH 03/99] Increase message cache time to 30 minutes for bots. GitOrigin-RevId: ef7a6833d62ce356012aba043c526199a200717d --- td/telegram/MessagesManager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 2ea2b7317..28fa32b5d 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -9876,8 +9876,8 @@ void MessagesManager::delete_all_channel_messages_from_user_on_server(ChannelId } int32 MessagesManager::get_unload_dialog_delay() const { - constexpr int32 DIALOG_UNLOAD_DELAY = 60; // seconds - constexpr int32 DIALOG_UNLOAD_BOT_DELAY = 600; // seconds + constexpr int32 DIALOG_UNLOAD_DELAY = 60; // seconds + constexpr int32 DIALOG_UNLOAD_BOT_DELAY = 1800; // seconds return td_->auth_manager_->is_bot() ? DIALOG_UNLOAD_BOT_DELAY : DIALOG_UNLOAD_DELAY; } From 96835d417b1d6eb266209c475037f7d1ff191807 Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 14 Sep 2020 14:22:43 +0300 Subject: [PATCH 04/99] Improve OptionParser error messages. GitOrigin-RevId: 97795e0a64122986e78d01a34205317fc5bef835 --- tdutils/td/utils/OptionParser.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tdutils/td/utils/OptionParser.cpp b/tdutils/td/utils/OptionParser.cpp index f688d3b2b..c431744a7 100644 --- a/tdutils/td/utils/OptionParser.cpp +++ b/tdutils/td/utils/OptionParser.cpp @@ -96,20 +96,20 @@ Result> OptionParser::run(int argc, char *argv[], int expected_no auto it = long_options.find(long_arg.str()); if (it == long_options.end()) { - return Status::Error(PSLICE() << "Option " << long_arg << " was unrecognized"); + return Status::Error(PSLICE() << "Option \"" << long_arg << "\" is unrecognized"); } auto option = it->second; switch (option->type) { case Option::Type::NoArg: if (has_equal) { - return Status::Error(PSLICE() << "Option " << long_arg << " must not have argument"); + return Status::Error(PSLICE() << "Option \"" << long_arg << "\" must not have an argument"); } break; case Option::Type::Arg: if (!has_equal) { if (++arg_pos == argc) { - return Status::Error(PSLICE() << "Option " << long_arg << " must have argument"); + return Status::Error(PSLICE() << "Option \"" << long_arg << "\" requires an argument"); } parameter = Slice(argv[arg_pos], std::strlen(argv[arg_pos])); } @@ -125,7 +125,7 @@ Result> OptionParser::run(int argc, char *argv[], int expected_no for (size_t opt_pos = 1; arg[opt_pos] != '\0'; opt_pos++) { auto it = short_options.find(arg[opt_pos]); if (it == short_options.end()) { - return Status::Error(PSLICE() << "Option " << arg[opt_pos] << " was unrecognized"); + return Status::Error(PSLICE() << "Option \"" << arg[opt_pos] << "\" is unrecognized"); } auto option = it->second; @@ -137,7 +137,7 @@ Result> OptionParser::run(int argc, char *argv[], int expected_no case Option::Type::Arg: if (arg[opt_pos + 1] == '\0') { if (++arg_pos == argc) { - return Status::Error(PSLICE() << "Option " << arg[opt_pos] << " must have argument"); + return Status::Error(PSLICE() << "Option \"" << arg[opt_pos] << "\" requires an argument"); } parameter = Slice(argv[arg_pos], std::strlen(argv[arg_pos])); } else { From b8e0201694d9fe60627bc96c097834b5849bbb82 Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 14 Sep 2020 14:33:42 +0300 Subject: [PATCH 05/99] Align long options in OptionParser usage. GitOrigin-RevId: 496c90e876c02ba923e3d7dac7e04a57b4e9766c --- tdutils/td/utils/OptionParser.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/tdutils/td/utils/OptionParser.cpp b/tdutils/td/utils/OptionParser.cpp index c431744a7..fcaaf224f 100644 --- a/tdutils/td/utils/OptionParser.cpp +++ b/tdutils/td/utils/OptionParser.cpp @@ -177,9 +177,10 @@ StringBuilder &operator<<(StringBuilder &sb, const OptionParser &o) { size_t max_length = 0; for (auto &opt : o.options_) { - bool has_short_key = opt.short_key != '\0'; - bool has_long_key = !opt.long_key.empty(); - size_t length = (has_short_key ? 2 : 0) + (has_long_key ? 2 + opt.long_key.size() + 2 * has_short_key : 0); + size_t length = 2; + if (!opt.long_key.empty()) { + length += 4 + opt.long_key.size(); + } if (opt.type != OptionParser::Option::Type::NoArg) { length += 5; } @@ -195,15 +196,18 @@ StringBuilder &operator<<(StringBuilder &sb, const OptionParser &o) { size_t length = max_length; if (has_short_key) { sb << '-' << opt.short_key; - length -= 2; + } else { + sb << " "; } + length -= 2; if (!opt.long_key.empty()) { if (has_short_key) { sb << ", "; - length -= 2; + } else { + sb << " "; } sb << "--" << opt.long_key; - length -= 2 + opt.long_key.size(); + length -= 4 + opt.long_key.size(); } if (opt.type != OptionParser::Option::Type::NoArg) { sb << ""; From 91942f29d35e2a31df79c88eaa92733438fc6278 Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 14 Sep 2020 14:45:22 +0300 Subject: [PATCH 06/99] Add OptionParser::parse_integer helper function. GitOrigin-RevId: d202848b64c27bb260e189783722508684b633c5 --- tdutils/td/utils/OptionParser.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tdutils/td/utils/OptionParser.h b/tdutils/td/utils/OptionParser.h index 2fbd86698..af611ec3f 100644 --- a/tdutils/td/utils/OptionParser.h +++ b/tdutils/td/utils/OptionParser.h @@ -7,6 +7,7 @@ #pragma once #include "td/utils/common.h" +#include "td/utils/misc.h" #include "td/utils/Slice.h" #include "td/utils/Status.h" #include "td/utils/StringBuilder.h" @@ -30,6 +31,14 @@ class OptionParser { std::function callback); public: + template + static std::function parse_integer(T &value) { + return [&value](Slice value_str) { + TRY_RESULT_ASSIGN(value, to_integer_safe(value_str)); + return Status::OK(); + }; + } + void set_description(string description); void add_checked_option(char short_key, Slice long_key, Slice description, std::function callback); From bc000b5a53d3fc3bb1705680cfe7212464fbe97e Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 14 Sep 2020 14:51:52 +0300 Subject: [PATCH 07/99] Add OptionParser::parse_string helper. GitOrigin-RevId: 506b1d9c1b6cfb6029bb87e32a98f08b0d16b2d4 --- td/telegram/cli.cpp | 4 ++-- tdutils/td/utils/OptionParser.h | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index d9c871ba7..f543eb849 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -4461,8 +4461,8 @@ void main(int argc, char **argv) { [&](Slice parameter) { api_id = to_integer(parameter); }); options.add_option('\0', "api_id", "Set Telegram API ID", [&](Slice parameter) { api_id = to_integer(parameter); }); - options.add_option('\0', "api-hash", "Set Telegram API hash", [&](Slice parameter) { api_hash = parameter.str(); }); - options.add_option('\0', "api_hash", "Set Telegram API hash", [&](Slice parameter) { api_hash = parameter.str(); }); + options.add_option('\0', "api-hash", "Set Telegram API hash", OptionParser::parse_string(api_hash)); + options.add_option('\0', "api_hash", "Set Telegram API hash", OptionParser::parse_string(api_hash)); options.add_check([&] { if (api_id == 0 || api_hash.empty()) { return Status::Error("You must provide valid api-id and api-hash obtained at https://my.telegram.org"); diff --git a/tdutils/td/utils/OptionParser.h b/tdutils/td/utils/OptionParser.h index af611ec3f..d1ba27f3d 100644 --- a/tdutils/td/utils/OptionParser.h +++ b/tdutils/td/utils/OptionParser.h @@ -39,6 +39,12 @@ class OptionParser { }; } + static std::function parse_string(string &value) { + return [&value](Slice value_str) { + value = value_str.str(); + }; + } + void set_description(string description); void add_checked_option(char short_key, Slice long_key, Slice description, std::function callback); From 143a4961b6cd374ddb2c40bf1112b2e1771ae00d Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 14 Sep 2020 15:40:34 +0300 Subject: [PATCH 08/99] Improve inputMessageDocument.disable_content_type_detection field name. GitOrigin-RevId: b2155f743635437e11d4c346bad641427cb737fa --- td/generate/scheme/td_api.tl | 4 ++-- td/generate/scheme/td_api.tlo | Bin 181400 -> 181420 bytes td/telegram/MessageContent.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index c1d8b475e..ee2bd980f 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -1750,8 +1750,8 @@ inputMessageAnimation animation:InputFile thumbnail:inputThumbnail added_sticker //@performer Performer of the audio; 0-64 characters, may be replaced by the server @caption Audio caption; 0-GetOption("message_caption_length_max") characters inputMessageAudio audio:InputFile album_cover_thumbnail:inputThumbnail duration:int32 title:string performer:string caption:formattedText = InputMessageContent; -//@description A document message (general file) @document Document to be sent @thumbnail Document thumbnail, if available @force_file If true, automatic file type detection will be disabled and the document will be always sent as file. Always true for files sent to secret chats @caption Document caption; 0-GetOption("message_caption_length_max") characters -inputMessageDocument document:InputFile thumbnail:inputThumbnail force_file:Bool caption:formattedText = InputMessageContent; +//@description A document message (general file) @document Document to be sent @thumbnail Document thumbnail, if available @disable_content_type_detection If true, automatic file type detection will be disabled and the document will be always sent as file. Always true for files sent to secret chats @caption Document caption; 0-GetOption("message_caption_length_max") characters +inputMessageDocument document:InputFile thumbnail:inputThumbnail disable_content_type_detection:Bool caption:formattedText = InputMessageContent; //@description A photo message @photo Photo to send @thumbnail Photo thumbnail to be sent, this is sent to the other party in secret chats only @added_sticker_file_ids File identifiers of the stickers added to the photo, if applicable @width Photo width @height Photo height @caption Photo caption; 0-GetOption("message_caption_length_max") characters //@ttl Photo TTL (Time To Live), in seconds (0-60). A non-zero TTL can be specified only in private chats diff --git a/td/generate/scheme/td_api.tlo b/td/generate/scheme/td_api.tlo index 8df9db5605880192d8d261d38a0276f9e6a8eb8d..24ef0ef40f2ce7b0ebecde1c7ed4bec1675d1da5 100644 GIT binary patch delta 758 zcmbQy$-SnNdxMV%%f&ZZw>Jlfa7=)(VwT)c2D2tRTvFH^abgA|f+uoH1&J4P+60NW z<;)T!Ud=fjCWO8-7YZP9n;kBNAgS7M*#L>hb9E0A@69zH1aGp;4GD;G2ZCg#FWA5+ zFgfK$3`FF}4Gl13^M@M>P#q$-R3LITw_ccn{Ko(VSLL{3b{0h^ie%;$l$Q9W78fU` zr@G`Pm*%GCl>pU%)ZRQMP1o_T@Ij?#(iHM4-+wxeIkp%-tyvcYT41Y?ir~0#(#< zAL5P48}846C<=H06{&du6_I%e6-g*Hn7rV;!ej>r4v5+%5203^d1wF@ne+%EF#Ulr zBSd6!3{2?F1SXxy8y-Q;y7Ned6XtKG>4q^(+LJRvbRfp2JcfFv=kWrlI}M&9l(SD~ z%wY7NZm^k=XL5ld>*T#pw?p(*Jkx-i$uiy1f=Pe+hl7kNlm9#m0V`+@dA>d5IpYKs zR&eZ04>V$u-_F6qBm)y*+`y!;-P3@{8e;4837kOw3PUCzCS)BFCQJe-0zPI;7ZSlX VOjnq}^a84OV+YW5otaEI+5p!0VetR} delta 693 zcmZ3}$vvZ!dxMV%%l?KX=Qan3a7=)(VwT)c2D2tRTvFH^abgA|f+uoH1&J4P+60NW z<;)T!Ud=fjCWO8-7YZP9n;kBNAgS7M*#L>hb9E0A@69zH1aGp;4GD;G2ZCg#3zRVN zOis9w01-KILj%m%{NaWIRENkd6^NY8trw;s|1m(pRXMJh>vC61L^AUVN=tlGi;EM} zQ(f|tOLJ56N`PuWYHuDB@?n{rxLA7fo1+4g6>h3W`jE-P@6sOLgfnXPJuXq;~q@Wy%eaT8TTPBo_yr~9EhTn2T+j-51=9j51}Fn zr3RB1oL89a;J^V7^@qBy6bH)h}mD3%} zm=w0l@G!|h`5(A|{1^i!8;JhtVE!IMCLc)RfT-6oVG@Aww*&QmNCX=UmYNQ;#+PFAhY- diff --git a/td/telegram/MessageContent.cpp b/td/telegram/MessageContent.cpp index ed3774ede..6f6c025f4 100644 --- a/td/telegram/MessageContent.cpp +++ b/td/telegram/MessageContent.cpp @@ -1859,7 +1859,7 @@ Result get_input_message_content( } case td_api::inputMessageDocument::ID: { auto input_message = static_cast(input_message_content.get()); - auto file_type = input_message->force_file_ ? FileType::DocumentAsFile : FileType::Document; + auto file_type = input_message->disable_content_type_detection_ ? FileType::DocumentAsFile : FileType::Document; r_file_id = td->file_manager_->get_input_file_id(file_type, input_message->document_, dialog_id, false, is_secret, true); input_thumbnail = std::move(input_message->thumbnail_); From 12577df8c567e76c597e28749c742e2b655f5146 Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 14 Sep 2020 15:47:38 +0300 Subject: [PATCH 09/99] Fix CHECK. GitOrigin-RevId: 17c371798e0a67e4af25d0653c7edf604a33ab03 --- td/telegram/MessagesManager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 28fa32b5d..c2444c3ae 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -12195,7 +12195,6 @@ std::pair> MessagesManager::creat } } if (sender_dialog_id.is_valid()) { - CHECK(!sender_user_id.is_valid()); if (dialog_type == DialogType::User || dialog_type == DialogType::SecretChat) { LOG(ERROR) << "Receive " << message_id << " sent by " << sender_dialog_id << " in " << dialog_id; return {DialogId(), nullptr}; @@ -29756,7 +29755,8 @@ MessagesManager::Message *MessagesManager::add_message_to_dialog(Dialog *d, uniq if (!td_->auth_manager_->is_bot() && m->top_reply_message_id.is_valid() && m->top_reply_message_id != message_id) { Message *top_m = get_message(d, m->top_reply_message_id); if (top_m != nullptr && is_active_message_reply_info(dialog_id, top_m->reply_info)) { - top_m->reply_info.add_reply(m->sender_dialog_id.is_valid() ? m->sender_dialog_id : DialogId(m->sender_user_id)); + top_m->reply_info.add_reply(has_message_sender_user_id(dialog_id, m) ? DialogId(m->sender_user_id) + : m->sender_dialog_id); send_update_message_interaction_info(dialog_id, top_m); on_message_changed(d, top_m, true, "update_message_reply_count"); } From 6e08881d819dbe17e18215df4c4cc2a1818c07a3 Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 14 Sep 2020 16:02:37 +0300 Subject: [PATCH 10/99] Fix handling of updateCallSignalingData. GitOrigin-RevId: 81a12c58a8e5d015ebe25de0b8c1fb1e31bd84e7 --- td/telegram/CallManager.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/td/telegram/CallManager.cpp b/td/telegram/CallManager.cpp index 1900b2c01..6bfc4e89c 100644 --- a/td/telegram/CallManager.cpp +++ b/td/telegram/CallManager.cpp @@ -48,6 +48,7 @@ void CallManager::update_call_signaling_data(int64 call_id, string data) { auto info_it = call_info_.find(call_id); if (info_it == call_info_.end() || !info_it->second.call_id.is_valid()) { LOG(INFO) << "Ignore signaling data for " << call_id; + return; } auto actor = get_call_actor(info_it->second.call_id); From 0ad6ff059976708331e4c3656c174fbdc76cdaf6 Mon Sep 17 00:00:00 2001 From: levlam Date: Mon, 14 Sep 2020 17:04:45 +0300 Subject: [PATCH 11/99] Add usage in OptionParser. GitOrigin-RevId: 0a15b69eda345c0fbc503afc26c6787f5fbcaa8e --- tdutils/td/utils/OptionParser.cpp | 9 +++++++++ tdutils/td/utils/OptionParser.h | 3 +++ 2 files changed, 12 insertions(+) diff --git a/tdutils/td/utils/OptionParser.cpp b/tdutils/td/utils/OptionParser.cpp index fcaaf224f..fbbcb8421 100644 --- a/tdutils/td/utils/OptionParser.cpp +++ b/tdutils/td/utils/OptionParser.cpp @@ -7,12 +7,18 @@ #include "td/utils/OptionParser.h" #include "td/utils/logging.h" +#include "td/utils/PathView.h" #include #include namespace td { +void OptionParser::set_usage(Slice executable_name, Slice usage) { + PathView path_view(executable_name); + usage_ = PSTRING() << path_view.file_name() << " " << usage; +} + void OptionParser::set_description(string description) { description_ = std::move(description); } @@ -170,6 +176,9 @@ Result> OptionParser::run(int argc, char *argv[], int expected_no } StringBuilder &operator<<(StringBuilder &sb, const OptionParser &o) { + if (!o.usage_.empty()) { + sb << "Usage: " << o.usage_ << "\n\n"; + } if (!o.description_.empty()) { sb << o.description_ << ". "; } diff --git a/tdutils/td/utils/OptionParser.h b/tdutils/td/utils/OptionParser.h index d1ba27f3d..6ca4cd759 100644 --- a/tdutils/td/utils/OptionParser.h +++ b/tdutils/td/utils/OptionParser.h @@ -45,6 +45,8 @@ class OptionParser { }; } + void set_usage(Slice executable_name, Slice usage); + void set_description(string description); void add_checked_option(char short_key, Slice long_key, Slice description, std::function callback); @@ -69,6 +71,7 @@ class OptionParser { private: vector