Skip to content
Alex Iadicicco edited this page Feb 3, 2014 · 6 revisions

The snf() and vsnf() functions are replacements for snprintf() and vsnprintf() with some IRC-specific formatting additions.

The prototype for vsnf() is as follows:

extern int vsnf(int type, char *buf, uint size, const char *fmt, va_list va);

snf() is similar, with ... instead of va_list. The interpretation of the arguments is nearly identical to their equivalents in vsnprintf(). The most notable difference is the addition of a type argument, which affects the interpretation of certain format parameters.

type should have one of the following values:

  • FMT_USER
  • FMT_SERVER
  • FMT_LOG
  • FMT_DEBUG

Most uses will only require FMT_USER or FMT_SERVER. Many format parameters only check "if FMT_SERVER ... else ...", and treat all other format types as FMT_USER.

Uses

The most notable use of this command is u_conn_vf, on which all other output functions (u_user_num, u_sendto, etc.) are built, at one time or another. This function picks FMT_USER or FMT_SERVER depending on the context of the connection. This way format strings can be written in a connection context independent manner.

Another use is formatting channel ban setter strings. When a ban is applied, the setter string is formatted by the following line of code:

snf(FMT_USER, ban->setter, 256, "%I", si);

where si is the u_sourceinfo* of the user or server issuing the command that caused the particular ban to be applied.

Format Strings

vsnf() format strings are similar in syntax to those of the standard C printf-family functions. An example use of vsnf() format string for a JOIN message is as follows:

u_sendto_chan(c, NULL, ST_USERS, ":%H JOIN %C", si->u, c);

(u_sendto_chan uses u_sendto which uses u_conn_vf which, as mentioned above, uses vsnf()).

Format specifiers

IRC-specific additions

  • %U user: Expects a pointer to u_user. For FMT_SERVER, uses the user's UID. For FMT_USER, uses their nickname.

  • %H hostmask: Expects a pointer to u_user. For FMT_SERVER, uses the user's UID. For all other formats, uses the full nick!user@host of the user.

  • %C channel: Expects a pointer to u_chan. For all formats, prints the channel name.

  • %S server: Expects a pointer to u_server. For FMT_SERVER, uses the server's SID. For all other formats, uses the server's name.

  • %G connection: Expects a pointer to u_conn. Determines the context of the connection argument and behaves as %U or %S appropriately.

  • %I sourceinfo: Expects a pointer to u_sourceinfo. On as surface level, determines the type of the source and behaves as %H or %S appropriately. On a more detailed level, uses si->id if using FMT_SERVER, %H if si->u is set, and %S if si->s is set. (It is a bug for both si->u and si->s to be NULL, and vsnf() will use "?" in that case).

Cloned from vsnprintf()

The %%, %s, %d, %u, %o, %x, %p, and %c format specifiers behave similarly to their vsnprintf() equivalents.

Parameters

This is where vsnf() deviates from vsnprintf() the most. Only a small subset of the vsnprintf() parameters have been cloned, as of writing.

Essentially, every digit between the "%" and the specifier letter is grabbed and parsed as follows: If it starts with "0", the user wishes to left-pad the output with zeros. Otherwise, left-pad with spaces. Parse the string to an integer, and left-pad the output to this width.

NOTE: the parameter is ignored for some formats! In fact, most of the IRC-specific additions will ignore it!

Clone this wiki locally