terom@17: #ifndef IRC_LINE_H terom@17: #define IRC_LINE_H terom@17: terom@34: /** terom@34: * @file terom@34: * terom@34: * The low-level IRC protocol unit is a line, with prefix, command and arguments terom@34: */ terom@75: #include "irc_proto.h" terom@17: #include "error.h" terom@17: terom@34: /** terom@18: * The maximum length of a line, without terminating CRLF terom@17: */ terom@18: #define IRC_LINE_MAX 510 terom@17: terom@34: /** terom@17: * The maximum number of arguments for a single command terom@17: */ terom@17: #define IRC_ARG_MAX 15 terom@17: terom@34: /** terom@17: * Chars that are invalid inside of tokens terom@17: */ terom@17: #define IRC_TOKEN_INVALID "\r\n\n " terom@17: #define IRC_TOKEN_TRAILING_INVALID "\r\n\n" terom@17: terom@34: /** terom@34: * Low-level IRC protocol unit terom@17: */ terom@17: struct irc_line { terom@75: /** The message source as a nickmask, for those messages that have a valid prefix. May be NULL otherwise */ terom@75: const struct irc_nm *source; terom@17: terom@34: /** The command, either a numeric or a primary command */ terom@17: const char *command; terom@17: terom@34: /** The arguments, with unused ones set to NULL */ terom@17: const char *args[IRC_ARG_MAX]; terom@17: }; terom@17: terom@34: /** terom@17: * Parse an IRC message to fill in an irc_line. This mutates the value of data (to insert NULs between tokens), and terom@17: * stores pointers into this data into the irc_line. terom@34: * terom@75: * If the prefix is a valid nickmask, it will be stored in the given given irc_nm, and irc_line.nm set to this. terom@75: * terom@34: * The irc_line will have the first N args values set to valid values, and all the rest set to NULL. terom@17: */ terom@75: err_t irc_line_parse (struct irc_line *line, struct irc_nm *nm, char *data); terom@17: terom@34: /** terom@17: * Formats an irc_line as a protocol line into the given buffer (which should hold at least IRC_LINE_MAX bytes). terom@34: * terom@34: * The irc_line.args are ignored from the first NULL argument onwards. terom@34: * terom@34: * An error is returned if a token has an invalid value (e.g. a space in the command or an argument other than the last terom@34: * one), or if the resulting line is too long. terom@17: */ terom@17: err_t irc_line_build (const struct irc_line *line, char *buf); terom@17: terom@68: /** terom@68: * Iterate through the arguments in an irc_line terom@68: */ terom@68: #define FOREACH_IRC_LINE_ARGS(line, arg_ptr) \ terom@68: for (size_t _irc_line_arg_idx = 0; _irc_line_arg_idx < IRC_ARG_MAX && (arg_ptr = line->args[_irc_line_arg_idx]); _irc_line_arg_idx++) terom@68: terom@17: #endif /* IRC_LINE_H */