From 148b26f687ce85dc01e852a2358b03d493757ada Mon Sep 17 00:00:00 2001 From: Adam Date: Mon, 23 Jun 2014 07:12:41 -0400 Subject: Mostly working language string rewrite with new format strings --- include/anope.h | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++- include/bots.h | 2 ++ include/commands.h | 11 ++++++++- include/config.h | 2 ++ include/event.h | 2 +- include/language.h | 64 ---------------------------------------------------- include/users.h | 13 +++++++---- 7 files changed, 89 insertions(+), 71 deletions(-) (limited to 'include') diff --git a/include/anope.h b/include/anope.h index 845a2b1fb..839d201cf 100644 --- a/include/anope.h +++ b/include/anope.h @@ -631,7 +631,7 @@ class spacesepstream : public sepstream public: /** Initialize with space seperator */ - spacesepstream(const Anope::string &source) : sepstream(source, ' ') { } + spacesepstream(const Anope::string &source, bool allowempty = false) : sepstream(source, ' ', allowempty) { } }; /** This class can be used on its own to represent an exception, or derived to represent a module-specific exception. @@ -775,3 +775,67 @@ template inline T anope_dynamic_static_cast(O ptr) return static_cast(ptr); } #endif + +struct kwarg +{ + Anope::string name, value; + + template + kwarg& operator=(const T& rhs) + { + value = stringify(rhs); + return *this; + } +}; + +inline kwarg operator"" _kw(const char *literal, size_t n) +{ + return kwarg{ literal }; +} + +struct FormatInfo +{ + Anope::string format; + std::vector parameters; + unsigned int pos = 0; + + FormatInfo(const Anope::string &fmt, size_t size) : format(fmt), parameters(size) { } + + template + void Add(T& arg) + { + parameters[pos] = kwarg{ stringify(pos).c_str() } = stringify(arg); + ++pos; + } + + template + void Format(Arg &&arg, Args&&... args) + { + Add(arg); + Format(std::forward(args)...); + } + + void Format() + { + for (kwarg& arg : parameters) + format = format.replace_all_cs("{" + arg.name + "}", arg.value); + } +}; + +template<> +inline void FormatInfo::Add(kwarg &arg) +{ + parameters[pos++] = arg; +} + +namespace Anope +{ + template + inline Anope::string Format(const Anope::string &format, Args&&... args) + { + FormatInfo fi(format, sizeof...(Args)); + fi.Format(std::forward(args)...); + return fi.format; + } +} + diff --git a/include/bots.h b/include/bots.h index 9a2c5d237..ef57d31f3 100644 --- a/include/bots.h +++ b/include/bots.h @@ -124,6 +124,8 @@ class CoreExport BotInfo : public User, public Serializable */ CommandInfo *GetCommand(const Anope::string &cname); + CommandInfo *FindCommand(const Anope::string &service); + /** Find a bot by nick * @param nick The nick * @param nick_only True to only look by nick, and not by UID diff --git a/include/commands.h b/include/commands.h index 359995f8f..6f29aa135 100644 --- a/include/commands.h +++ b/include/commands.h @@ -14,6 +14,7 @@ #include "service.h" #include "anope.h" #include "channels.h" +#include "language.h" struct CommandGroup { @@ -29,6 +30,8 @@ struct CommandInfo /* Service name of the command */ Anope::string name; + /* User visible name */ + Anope::string cname; /* Permission required to execute the command */ Anope::string permission; /* Group this command is in */ @@ -77,7 +80,13 @@ class CoreExport CommandSource ChanServ::AccessGroup AccessFor(ChanServ::Channel *ci); bool IsFounder(ChanServ::Channel *ci); - void Reply(const char *message, ...); + template + void Reply(const char *message, Args&&... args) + { + const char *translated_message = Language::Translate(this->nc, message); + Reply(Anope::Format(translated_message, std::forward(args)...)); + } + void Reply(const Anope::string &message); bool HasCommand(const Anope::string &cmd); diff --git a/include/config.h b/include/config.h index 585c681fb..ccb7bcdf1 100644 --- a/include/config.h +++ b/include/config.h @@ -122,6 +122,8 @@ namespace Configuration std::vector CommandGroups; /* List of modules to autoload */ std::vector ModulesAutoLoad; + /* After how many characters do we wrap lines? */ + unsigned int LineWrap; /* module configuration blocks */ std::map modules; diff --git a/include/event.h b/include/event.h index 83d5a79e1..381db967b 100644 --- a/include/event.h +++ b/include/event.h @@ -123,7 +123,7 @@ class EventHook : public EventHandler } priority; - EventHook(const Anope::string &name, Priority p = Priority::LAST) : handlers(this, name) + EventHook(const Anope::string &name, Priority p = Priority::LAST) : handlers(this, name), priority(p) { handlers.Check(); } diff --git a/include/language.h b/include/language.h index 0aaa5ac9c..3bb732ddf 100644 --- a/include/language.h +++ b/include/language.h @@ -63,67 +63,3 @@ namespace Language } // namespace Language -/* Commonly used language strings */ -#define MORE_INFO _("\002%s%s HELP %s\002 for more information.") -#define BAD_USERHOST_MASK _("Mask must be in the form \037user\037@\037host\037.") -#define BAD_EXPIRY_TIME _("Invalid expiry time.") -#define USERHOST_MASK_TOO_WIDE _("%s coverage is too wide; Please use a more specific mask.") -#define READ_ONLY_MODE _("Services are in read-only mode!") -#define PASSWORD_INCORRECT _("Password incorrect.") -#define ACCESS_DENIED _("Access denied.") -#define MORE_OBSCURE_PASSWORD _("Please try again with a more obscure password. Passwords should be at least\n" \ - "five characters long, should not be something easily guessed\n" \ - "(e.g. your real name or your nick), and cannot contain the space or tab characters.") -#define PASSWORD_TOO_LONG _("Your password is too long. Please try again with a shorter password.") -#define NICK_NOT_REGISTERED _("Your nick isn't registered.") -#define NICK_X_NOT_REGISTERED _("Nick \002%s\002 isn't registered.") -#define NICK_X_NOT_IN_USE _("Nick \002%s\002 isn't currently in use.") -#define NICK_X_NOT_ON_CHAN _("\002%s\002 is not currently on channel %s.") -#define NICK_X_SUSPENDED _("Nick %s is currently suspended.") -#define CHAN_X_SUSPENDED _("Channel %s is currently suspended.") -#define CHAN_X_NOT_REGISTERED _("Channel \002%s\002 isn't registered.") -#define CHAN_X_NOT_IN_USE _("Channel \002%s\002 doesn't exist.") -#define NICK_IDENTIFY_REQUIRED _("Password authentication required for that command.") -#define MAIL_X_INVALID _("\002%s\002 is not a valid e-mail address.") -#define UNKNOWN _("") -#define NO_EXPIRE _("does not expire") -#define LIST_INCORRECT_RANGE _("Incorrect range specified. The correct syntax is \002#\037from\037-\037to\037\002.") -#define NICK_IS_REGISTERED _("This nick is owned by someone else. Please choose another.\n" \ - "(If this is your nick, type \002%s%s IDENTIFY \037password\037\002.)") -#define NICK_IS_SECURE _("This nickname is registered and protected. If it is your\n" \ - "nick, type \002%s%s IDENTIFY \037password\037\002. Otherwise,\n" \ - "please choose a different nick.") -#define FORCENICKCHANGE_NOW _("This nickname has been registered; you may not use it.") -#define NICK_CANNOT_BE_REGISTERED _("Nickname \002%s\002 may not be registered.") -#define NICK_ALREADY_REGISTERED _("Nickname \002%s\002 is already registered!") -#define NICK_SET_DISPLAY_CHANGED _("The new display is now \002%s\002.") -#define NICK_CONFIRM_INVALID _("Invalid passcode has been entered, please check the e-mail again, and retry.") -#define CHAN_NOT_ALLOWED_TO_JOIN _("You are not permitted to be on this channel.") -#define CHAN_X_INVALID _("Channel %s is not a valid channel.") -#define CHAN_REACHED_CHANNEL_LIMIT _("Sorry, you have already reached your limit of \002%d\002 channels.") -#define CHAN_EXCEEDED_CHANNEL_LIMIT _("Sorry, you have already exceeded your limit of \002%d\002 channels.") -#define CHAN_SYMBOL_REQUIRED _("Please use the symbol of \002#\002 when attempting to register.") -#define CHAN_SETTING_CHANGED _("%s for %s set to %s.") -#define CHAN_SETTING_UNSET _("%s for %s unset.") -#define CHAN_ACCESS_LEVEL_RANGE _("Access level must be between %d and %d inclusive.") -#define CHAN_INFO_HEADER _("Information for channel \002%s\002:") -#define CHAN_EXCEPTED _("\002%s\002 matches an except on %s and cannot be banned until the except has been removed.") -#define MEMO_NEW_X_MEMO_ARRIVED _("There is a new memo on channel %s.\n" \ - "Type \002%s%s READ %s %d\002 to read it.") -#define MEMO_NEW_MEMO_ARRIVED _("You have a new memo from %s.\n" \ - "Type \002%s%s READ %d\002 to read it.") -#define MEMO_HAVE_NO_MEMOS _("You have no memos.") -#define MEMO_X_HAS_NO_MEMOS _("%s has no memos.") -#define MEMO_SEND_DISABLED _("Sorry, memo sending is temporarily disabled.") -#define MEMO_HAVE_NO_NEW_MEMOS _("You have no new memos.") -#define MEMO_X_HAS_NO_NEW_MEMOS _("%s has no new memos.") -#define BOT_DOES_NOT_EXIST _("Bot \002%s\002 does not exist.") -#define BOT_NOT_ASSIGNED _("You must assign a bot to the channel before using this command.") -#define BOT_NOT_ON_CHANNEL _("Bot is not on channel \002%s\002.") -#define HOST_SET_ERROR _("A vHost must be in the format of a valid hostname.") -#define HOST_SET_IDENT_ERROR _("A vHost ident must be in the format of a valid ident.") -#define HOST_SET_TOOLONG _("Error! The vHost is too long, please use a hostname shorter than %d characters.") -#define HOST_SET_IDENTTOOLONG _("Error! The vHost ident is too long, please use an ident shorter than %d characters.") -#define HOST_NOT_ASSIGNED _("Please contact an Operator to get a vHost assigned to this nick.") -#define HOST_NO_VIDENT _("Your IRCd does not support vIdent's, if this is incorrect, please report this as a possible bug") - diff --git a/include/users.h b/include/users.h index e89d7c8af..972fa2ac0 100644 --- a/include/users.h +++ b/include/users.h @@ -185,10 +185,15 @@ class CoreExport User : public virtual Base, public Extensible, public CommandRe /** * Send a message (notice or privmsg, depending on settings) to a user * @param source Sender - * @param fmt Format of the Message - * @param ... any number of parameters - */ - void SendMessage(const MessageSource &, const char *fmt, ...); + * @param message Format of the Message + * @param args any number of parameters + */ + template + void SendMessage(const MessageSource &source, const char *message, Args&&... args) + { + const char *translated_message = Language::Translate(this->Account(), message); + SendMessage(source, Anope::Format(translated_message, std::forward(args)...)); + } void SendMessage(const MessageSource &, const Anope::string &msg) override; /** Identify the user to a nick. -- cgit