Allow commands to take multiline input
parent
7ea1a416a1
commit
3cb7cc97f6
86
command.c
86
command.c
|
@ -64,14 +64,14 @@ static void splitMessage(char *cmd, uint id, char *params) {
|
||||||
);
|
);
|
||||||
assert(overhead > 0 && overhead < 512);
|
assert(overhead > 0 && overhead < 512);
|
||||||
int chunk = 512 - overhead;
|
int chunk = 512 - overhead;
|
||||||
if (strlen(params) <= (size_t)chunk) {
|
if (strlen(params) <= (size_t)chunk && !strchr(params, '\n')) {
|
||||||
echoMessage(cmd, id, params);
|
echoMessage(cmd, id, params);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (*params) {
|
while (*params) {
|
||||||
int len = 0;
|
int len = 0;
|
||||||
for (int n = 0; len + n <= chunk; len += n) {
|
for (int n = 0; params[len] != '\n' && len + n <= chunk; len += n) {
|
||||||
n = mblen(¶ms[len], 1 + strlen(¶ms[len]));
|
n = mblen(¶ms[len], 1 + strlen(¶ms[len]));
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
n = 1;
|
n = 1;
|
||||||
|
@ -84,6 +84,7 @@ static void splitMessage(char *cmd, uint id, char *params) {
|
||||||
echoMessage(cmd, id, params);
|
echoMessage(cmd, id, params);
|
||||||
params[len] = ch;
|
params[len] = ch;
|
||||||
params += len;
|
params += len;
|
||||||
|
if (ch == '\n') params++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,45 +361,50 @@ static void commandHelp(uint id, char *params) {
|
||||||
_exit(EX_UNAVAILABLE);
|
_exit(EX_UNAVAILABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum Flag {
|
||||||
|
BIT(Multiline),
|
||||||
|
BIT(Restricted),
|
||||||
|
};
|
||||||
|
|
||||||
static const struct Handler {
|
static const struct Handler {
|
||||||
const char *cmd;
|
const char *cmd;
|
||||||
Command *fn;
|
Command *fn;
|
||||||
bool restricted;
|
enum Flag flags;
|
||||||
} Commands[] = {
|
} Commands[] = {
|
||||||
{ "/away", .fn = commandAway },
|
{ "/away", commandAway, 0 },
|
||||||
{ "/ban", .fn = commandBan },
|
{ "/ban", commandBan, 0 },
|
||||||
{ "/close", .fn = commandClose },
|
{ "/close", commandClose, 0 },
|
||||||
{ "/copy", .fn = commandCopy, .restricted = true },
|
{ "/copy", commandCopy, Restricted },
|
||||||
{ "/cs", .fn = commandCS },
|
{ "/cs", commandCS, 0 },
|
||||||
{ "/debug", .fn = commandDebug, .restricted = true },
|
{ "/debug", commandDebug, Restricted },
|
||||||
{ "/except", .fn = commandExcept },
|
{ "/except", commandExcept, 0 },
|
||||||
{ "/exec", .fn = commandExec, .restricted = true },
|
{ "/exec", commandExec, Multiline | Restricted },
|
||||||
{ "/help", .fn = commandHelp },
|
{ "/help", commandHelp, 0 },
|
||||||
{ "/invex", .fn = commandInvex },
|
{ "/invex", commandInvex, 0 },
|
||||||
{ "/invite", .fn = commandInvite },
|
{ "/invite", commandInvite, 0 },
|
||||||
{ "/join", .fn = commandJoin, .restricted = true },
|
{ "/join", commandJoin, Restricted },
|
||||||
{ "/kick", .fn = commandKick },
|
{ "/kick", commandKick, 0 },
|
||||||
{ "/list", .fn = commandList },
|
{ "/list", commandList, 0 },
|
||||||
{ "/me", .fn = commandMe },
|
{ "/me", commandMe, 0 },
|
||||||
{ "/mode", .fn = commandMode },
|
{ "/mode", commandMode, 0 },
|
||||||
{ "/move", .fn = commandMove },
|
{ "/move", commandMove, 0 },
|
||||||
{ "/msg", .fn = commandMsg, .restricted = true },
|
{ "/msg", commandMsg, Multiline | Restricted },
|
||||||
{ "/names", .fn = commandNames },
|
{ "/names", commandNames, 0 },
|
||||||
{ "/nick", .fn = commandNick },
|
{ "/nick", commandNick, 0 },
|
||||||
{ "/notice", .fn = commandNotice },
|
{ "/notice", commandNotice, Multiline },
|
||||||
{ "/ns", .fn = commandNS },
|
{ "/ns", commandNS, 0 },
|
||||||
{ "/open", .fn = commandOpen, .restricted = true },
|
{ "/open", commandOpen, Restricted },
|
||||||
{ "/part", .fn = commandPart },
|
{ "/part", commandPart, 0 },
|
||||||
{ "/query", .fn = commandQuery, .restricted = true },
|
{ "/query", commandQuery, Restricted },
|
||||||
{ "/quit", .fn = commandQuit },
|
{ "/quit", commandQuit, 0 },
|
||||||
{ "/quote", .fn = commandQuote, .restricted = true },
|
{ "/quote", commandQuote, Multiline | Restricted },
|
||||||
{ "/say", .fn = commandPrivmsg },
|
{ "/say", commandPrivmsg, Multiline },
|
||||||
{ "/topic", .fn = commandTopic },
|
{ "/topic", commandTopic, 0 },
|
||||||
{ "/unban", .fn = commandUnban },
|
{ "/unban", commandUnban, 0 },
|
||||||
{ "/unexcept", .fn = commandUnexcept },
|
{ "/unexcept", commandUnexcept, 0 },
|
||||||
{ "/uninvex", .fn = commandUninvex },
|
{ "/uninvex", commandUninvex, 0 },
|
||||||
{ "/whois", .fn = commandWhois },
|
{ "/whois", commandWhois, 0 },
|
||||||
{ "/window", .fn = commandWindow },
|
{ "/window", commandWindow, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static int compar(const void *cmd, const void *_handler) {
|
static int compar(const void *cmd, const void *_handler) {
|
||||||
|
@ -455,10 +461,14 @@ void command(uint id, char *input) {
|
||||||
uiFormat(id, Warm, NULL, "No such command %s", cmd);
|
uiFormat(id, Warm, NULL, "No such command %s", cmd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (self.restricted && handler->restricted) {
|
if (self.restricted && handler->flags & Restricted) {
|
||||||
uiFormat(id, Warm, NULL, "Command %s is restricted", cmd);
|
uiFormat(id, Warm, NULL, "Command %s is restricted", cmd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!(handler->flags & Multiline)) {
|
||||||
|
char *nl = strchr(input, '\n');
|
||||||
|
if (nl) *nl = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
if (input) {
|
if (input) {
|
||||||
input += strspn(input, " ");
|
input += strspn(input, " ");
|
||||||
|
|
Loading…
Reference in New Issue