librb: linebuf: reduce the number of "put" implementations from 4 to 1

This commit is contained in:
Simon Arlott 2017-07-30 13:47:27 +01:00
parent a7fed8715b
commit 7a06833fb4
No known key found for this signature in database
GPG key ID: C8975F2043CA5D24
6 changed files with 193 additions and 286 deletions

View file

@ -209,36 +209,36 @@ send_queued_write(rb_fde_t *F, void *data)
} }
/* /*
* linebuf_put_msgvbuf * linebuf_put_tags_prefix
* *
* inputs - msgbuf header, linebuf object, capability mask, pattern, arguments * inputs - msgbuf header, linebuf object, capability mask, pattern, arguments
* outputs - none * outputs - none
* side effects - the linebuf object is cleared, then populated using rb_linebuf_putmsg(). * side effects - the linebuf object is cleared, then populated using rb_linebuf_putprefix().
*/ */
static void static void
linebuf_put_msgvbuf(struct MsgBuf *msgbuf, buf_head_t *linebuf, unsigned int capmask, const char *pattern, va_list *va) linebuf_put_tags_vprefix(struct MsgBuf *msgbuf, buf_head_t *linebuf, unsigned int capmask, const char *pattern, va_list *va)
{ {
static char buf[EXT_BUFSIZE]; static char buf[EXT_BUFSIZE];
size_t buflen = sizeof(buf); size_t buflen = sizeof(buf);
rb_linebuf_newbuf(linebuf); rb_linebuf_newbuf(linebuf);
msgbuf_unparse_prefix(buf, &buflen, msgbuf, capmask); msgbuf_unparse_prefix(buf, &buflen, msgbuf, capmask);
rb_linebuf_putprefix(linebuf, pattern, va, buf, buflen); rb_linebuf_put_vtags_prefix(linebuf, pattern, va, buflen, buf);
} }
/* linebuf_put_msgbuf /* linebuf_put_tags_prefixf
* *
* inputs - msgbuf header, linebuf object, capability mask, pattern, arguments * inputs - msgbuf header, linebuf object, capability mask, pattern, arguments
* outputs - none * outputs - none
* side effects - the linebuf object is cleared, then populated using rb_linebuf_putmsg(). * side effects - the linebuf object is cleared, then populated using rb_linebuf_putprefix().
*/ */
static void static void
linebuf_put_msgbuf(struct MsgBuf *msgbuf, buf_head_t *linebuf, unsigned int capmask, const char *pattern, ...) linebuf_put_tags_prefixf(struct MsgBuf *msgbuf, buf_head_t *linebuf, unsigned int capmask, const char *pattern, ...)
{ {
va_list va; va_list va;
va_start(va, pattern); va_start(va, pattern);
linebuf_put_msgvbuf(msgbuf, linebuf, capmask, pattern, &va); linebuf_put_tags_vprefix(msgbuf, linebuf, capmask, pattern, &va);
va_end(va); va_end(va);
} }
@ -295,7 +295,7 @@ sendto_one(struct Client *target_p, const char *pattern, ...)
rb_linebuf_newbuf(&linebuf); rb_linebuf_newbuf(&linebuf);
va_start(args, pattern); va_start(args, pattern);
rb_linebuf_putmsg(&linebuf, pattern, &args, NULL); rb_linebuf_put_vmsg(&linebuf, pattern, &args);
va_end(args); va_end(args);
_send_linebuf(target_p, &linebuf); _send_linebuf(target_p, &linebuf);
@ -328,7 +328,7 @@ sendto_one_prefix(struct Client *target_p, struct Client *source_p,
rb_linebuf_newbuf(&linebuf); rb_linebuf_newbuf(&linebuf);
va_start(args, pattern); va_start(args, pattern);
rb_linebuf_putmsg(&linebuf, pattern, &args, rb_linebuf_put_vmsg_prefixf(&linebuf, pattern, &args,
":%s %s %s ", ":%s %s %s ",
get_id(source_p, target_p), get_id(source_p, target_p),
command, get_id(target_p, target_p)); command, get_id(target_p, target_p));
@ -363,7 +363,7 @@ sendto_one_notice(struct Client *target_p, const char *pattern, ...)
rb_linebuf_newbuf(&linebuf); rb_linebuf_newbuf(&linebuf);
va_start(args, pattern); va_start(args, pattern);
rb_linebuf_putmsg(&linebuf, pattern, &args, rb_linebuf_put_vmsg_prefixf(&linebuf, pattern, &args,
":%s NOTICE %s ", ":%s NOTICE %s ",
get_id(&me, target_p), *(to = get_id(target_p, target_p)) != '\0' ? to : "*"); get_id(&me, target_p), *(to = get_id(target_p, target_p)) != '\0' ? to : "*");
va_end(args); va_end(args);
@ -398,7 +398,7 @@ sendto_one_numeric(struct Client *target_p, int numeric, const char *pattern, ..
rb_linebuf_newbuf(&linebuf); rb_linebuf_newbuf(&linebuf);
va_start(args, pattern); va_start(args, pattern);
rb_linebuf_putmsg(&linebuf, pattern, &args, rb_linebuf_put_vmsg_prefixf(&linebuf, pattern, &args,
":%s %03d %s ", ":%s %03d %s ",
get_id(&me, target_p), get_id(&me, target_p),
numeric, *(to = get_id(target_p, target_p)) != '\0' ? to : "*"); numeric, *(to = get_id(target_p, target_p)) != '\0' ? to : "*");
@ -444,7 +444,7 @@ sendto_server(struct Client *one, struct Channel *chptr, unsigned long caps,
rb_linebuf_newbuf(&linebuf); rb_linebuf_newbuf(&linebuf);
va_start(args, format); va_start(args, format);
rb_linebuf_putmsg(&linebuf, format, &args, NULL); rb_linebuf_put_vmsg(&linebuf, format, &args);
va_end(args); va_end(args);
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, serv_list.head) RB_DLINK_FOREACH_SAFE(ptr, next_ptr, serv_list.head)
@ -482,16 +482,16 @@ sendto_channel_flags(struct Client *one, int type, struct Client *source_p,
static char buf[BUFSIZE]; static char buf[BUFSIZE];
va_list args; va_list args;
buf_head_t rb_linebuf_local; buf_head_t rb_linebuf_local;
buf_head_t rb_linebuf_id; buf_head_t rb_linebuf_remote;
struct Client *target_p; struct Client *target_p;
struct membership *msptr; struct membership *msptr;
rb_dlink_node *ptr; rb_dlink_node *ptr;
rb_dlink_node *next_ptr; rb_dlink_node *next_ptr;
int current_capmask = 0; int current_capmask = NOCAPS;
struct MsgBuf msgbuf; struct MsgBuf msgbuf;
rb_linebuf_newbuf(&rb_linebuf_local); rb_linebuf_newbuf(&rb_linebuf_local);
rb_linebuf_newbuf(&rb_linebuf_id); rb_linebuf_newbuf(&rb_linebuf_remote);
current_serial++; current_serial++;
@ -501,8 +501,8 @@ sendto_channel_flags(struct Client *one, int type, struct Client *source_p,
vsnprintf(buf, sizeof buf, pattern, args); vsnprintf(buf, sizeof buf, pattern, args);
va_end(args); va_end(args);
linebuf_put_msgbuf(&msgbuf, &rb_linebuf_local, NOCAPS, "%s", buf); linebuf_put_tags_prefixf(&msgbuf, &rb_linebuf_local, current_capmask, "%s", buf);
rb_linebuf_putmsg(&rb_linebuf_id, NULL, NULL, ":%s %s", use_id(source_p), buf); rb_linebuf_put_msgf(&rb_linebuf_remote, ":%s %s", use_id(source_p), buf);
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->members.head) RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->members.head)
{ {
@ -531,7 +531,7 @@ sendto_channel_flags(struct Client *one, int type, struct Client *source_p,
if(target_p->from->serial != current_serial) if(target_p->from->serial != current_serial)
{ {
send_linebuf_remote(target_p, source_p, &rb_linebuf_id); send_linebuf_remote(target_p, source_p, &rb_linebuf_remote);
target_p->from->serial = current_serial; target_p->from->serial = current_serial;
} }
} }
@ -545,7 +545,7 @@ sendto_channel_flags(struct Client *one, int type, struct Client *source_p,
/* render the new linebuf and attach it */ /* render the new linebuf and attach it */
current_capmask = target_p->localClient->caps; current_capmask = target_p->localClient->caps;
linebuf_put_msgbuf(&msgbuf, &rb_linebuf_local, current_capmask, "%s", buf); linebuf_put_tags_prefixf(&msgbuf, &rb_linebuf_local, current_capmask, "%s", buf);
} }
_send_linebuf(target_p, &rb_linebuf_local); _send_linebuf(target_p, &rb_linebuf_local);
@ -565,14 +565,14 @@ sendto_channel_flags(struct Client *one, int type, struct Client *source_p,
/* render the new linebuf and attach it */ /* render the new linebuf and attach it */
current_capmask = target_p->localClient->caps; current_capmask = target_p->localClient->caps;
linebuf_put_msgbuf(&msgbuf, &rb_linebuf_local, current_capmask, "%s", buf); linebuf_put_tags_prefixf(&msgbuf, &rb_linebuf_local, current_capmask, "%s", buf);
} }
_send_linebuf(target_p, &rb_linebuf_local); _send_linebuf(target_p, &rb_linebuf_local);
} }
rb_linebuf_donebuf(&rb_linebuf_local); rb_linebuf_donebuf(&rb_linebuf_local);
rb_linebuf_donebuf(&rb_linebuf_id); rb_linebuf_donebuf(&rb_linebuf_remote);
} }
/* sendto_channel_flags() /* sendto_channel_flags()
@ -601,25 +601,25 @@ sendto_channel_opmod(struct Client *one, struct Client *source_p,
current_serial++; current_serial++;
if(IsServer(source_p)) if(IsServer(source_p))
rb_linebuf_putmsg(&rb_linebuf_local, NULL, NULL, rb_linebuf_put_msgf(&rb_linebuf_local,
":%s %s %s :%s", ":%s %s %s :%s",
source_p->name, command, chptr->chname, text); source_p->name, command, chptr->chname, text);
else else
rb_linebuf_putmsg(&rb_linebuf_local, NULL, NULL, rb_linebuf_put_msgf(&rb_linebuf_local,
":%s!%s@%s %s %s :%s", ":%s!%s@%s %s %s :%s",
source_p->name, source_p->username, source_p->name, source_p->username,
source_p->host, command, chptr->chname, text); source_p->host, command, chptr->chname, text);
if (chptr->mode.mode & MODE_MODERATED) if (chptr->mode.mode & MODE_MODERATED)
rb_linebuf_putmsg(&rb_linebuf_old, NULL, NULL, rb_linebuf_put_msgf(&rb_linebuf_old,
":%s %s %s :%s", ":%s %s %s :%s",
use_id(source_p), command, chptr->chname, text); use_id(source_p), command, chptr->chname, text);
else else
rb_linebuf_putmsg(&rb_linebuf_old, NULL, NULL, rb_linebuf_put_msgf(&rb_linebuf_old,
":%s NOTICE @%s :<%s:%s> %s", ":%s NOTICE @%s :<%s:%s> %s",
use_id(source_p->servptr), chptr->chname, use_id(source_p->servptr), chptr->chname,
source_p->name, chptr->chname, text); source_p->name, chptr->chname, text);
rb_linebuf_putmsg(&rb_linebuf_new, NULL, NULL, rb_linebuf_put_msgf(&rb_linebuf_new,
":%s %s =%s :%s", ":%s %s =%s :%s",
use_id(source_p), command, chptr->chname, text); use_id(source_p), command, chptr->chname, text);
@ -693,7 +693,7 @@ sendto_channel_local(int type, struct Channel *chptr, const char *pattern, ...)
rb_linebuf_newbuf(&linebuf); rb_linebuf_newbuf(&linebuf);
va_start(args, pattern); va_start(args, pattern);
rb_linebuf_putmsg(&linebuf, pattern, &args, NULL); rb_linebuf_put_vmsg(&linebuf, pattern, &args);
va_end(args); va_end(args);
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head) RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head)
@ -734,7 +734,7 @@ _sendto_channel_local_with_capability_butone(struct Client *one, int type, int c
rb_dlink_node *next_ptr; rb_dlink_node *next_ptr;
rb_linebuf_newbuf(&linebuf); rb_linebuf_newbuf(&linebuf);
rb_linebuf_putmsg(&linebuf, pattern, args, NULL); rb_linebuf_put_vmsg(&linebuf, pattern, args);
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head) RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head)
{ {
@ -816,7 +816,7 @@ sendto_channel_local_butone(struct Client *one, int type, struct Channel *chptr,
build_msgbuf_from(&msgbuf, one, NULL); build_msgbuf_from(&msgbuf, one, NULL);
va_start(args, pattern); va_start(args, pattern);
rb_linebuf_putmsg(&linebuf, pattern, &args, NULL); rb_linebuf_put_vmsg(&linebuf, pattern, &args);
va_end(args); va_end(args);
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head) RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head)
@ -868,7 +868,7 @@ sendto_common_channels_local(struct Client *user, int cap, int negcap, const cha
rb_linebuf_newbuf(&linebuf); rb_linebuf_newbuf(&linebuf);
va_start(args, pattern); va_start(args, pattern);
rb_linebuf_putmsg(&linebuf, pattern, &args, NULL); rb_linebuf_put_vmsg(&linebuf, pattern, &args);
va_end(args); va_end(args);
++current_serial; ++current_serial;
@ -931,7 +931,7 @@ sendto_common_channels_local_butone(struct Client *user, int cap, int negcap, co
rb_linebuf_newbuf(&linebuf); rb_linebuf_newbuf(&linebuf);
va_start(args, pattern); va_start(args, pattern);
rb_linebuf_putmsg(&linebuf, pattern, &args, NULL); rb_linebuf_put_vmsg(&linebuf, pattern, &args);
va_end(args); va_end(args);
++current_serial; ++current_serial;
@ -978,25 +978,25 @@ sendto_match_butone(struct Client *one, struct Client *source_p,
rb_dlink_node *ptr; rb_dlink_node *ptr;
rb_dlink_node *next_ptr; rb_dlink_node *next_ptr;
buf_head_t rb_linebuf_local; buf_head_t rb_linebuf_local;
buf_head_t rb_linebuf_id; buf_head_t rb_linebuf_remote;
rb_linebuf_newbuf(&rb_linebuf_local); rb_linebuf_newbuf(&rb_linebuf_local);
rb_linebuf_newbuf(&rb_linebuf_id); rb_linebuf_newbuf(&rb_linebuf_remote);
va_start(args, pattern); va_start(args, pattern);
vsnprintf(buf, sizeof(buf), pattern, args); vsnprintf(buf, sizeof(buf), pattern, args);
va_end(args); va_end(args);
if(IsServer(source_p)) if(IsServer(source_p))
rb_linebuf_putmsg(&rb_linebuf_local, NULL, NULL, rb_linebuf_put_msgf(&rb_linebuf_local,
":%s %s", source_p->name, buf); ":%s %s", source_p->name, buf);
else else
rb_linebuf_putmsg(&rb_linebuf_local, NULL, NULL, rb_linebuf_put_msgf(&rb_linebuf_local,
":%s!%s@%s %s", ":%s!%s@%s %s",
source_p->name, source_p->username, source_p->name, source_p->username,
source_p->host, buf); source_p->host, buf);
rb_linebuf_putmsg(&rb_linebuf_id, NULL, NULL, ":%s %s", use_id(source_p), buf); rb_linebuf_put_msgf(&rb_linebuf_remote, ":%s %s", use_id(source_p), buf);
if(what == MATCH_HOST) if(what == MATCH_HOST)
{ {
@ -1025,11 +1025,11 @@ sendto_match_butone(struct Client *one, struct Client *source_p,
if(target_p == one) if(target_p == one)
continue; continue;
send_linebuf_remote(target_p, source_p, &rb_linebuf_id); send_linebuf_remote(target_p, source_p, &rb_linebuf_remote);
} }
rb_linebuf_donebuf(&rb_linebuf_local); rb_linebuf_donebuf(&rb_linebuf_local);
rb_linebuf_donebuf(&rb_linebuf_id); rb_linebuf_donebuf(&rb_linebuf_remote);
} }
/* sendto_match_servs() /* sendto_match_servs()
@ -1057,8 +1057,7 @@ sendto_match_servs(struct Client *source_p, const char *mask, int cap,
vsnprintf(buf, sizeof(buf), pattern, args); vsnprintf(buf, sizeof(buf), pattern, args);
va_end(args); va_end(args);
rb_linebuf_putmsg(&rb_linebuf_id, NULL, NULL, rb_linebuf_put_msgf(&rb_linebuf_id, ":%s %s", use_id(source_p), buf);
":%s %s", use_id(source_p), buf);
current_serial++; current_serial++;
@ -1110,7 +1109,7 @@ sendto_local_clients_with_capability(int cap, const char *pattern, ...)
rb_linebuf_newbuf(&linebuf); rb_linebuf_newbuf(&linebuf);
va_start(args, pattern); va_start(args, pattern);
rb_linebuf_putmsg(&linebuf, pattern, &args, NULL); rb_linebuf_put_vmsg(&linebuf, pattern, &args);
va_end(args); va_end(args);
RB_DLINK_FOREACH(ptr, lclient_list.head) RB_DLINK_FOREACH(ptr, lclient_list.head)
@ -1144,7 +1143,7 @@ sendto_monitor(struct monitor *monptr, const char *pattern, ...)
rb_linebuf_newbuf(&linebuf); rb_linebuf_newbuf(&linebuf);
va_start(args, pattern); va_start(args, pattern);
rb_linebuf_putmsg(&linebuf, pattern, &args, NULL); rb_linebuf_put_vmsg(&linebuf, pattern, &args);
va_end(args); va_end(args);
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, monptr->users.head) RB_DLINK_FOREACH_SAFE(ptr, next_ptr, monptr->users.head)
@ -1178,7 +1177,7 @@ _sendto_anywhere(struct Client *dest_p, struct Client *target_p,
if(MyClient(dest_p)) if(MyClient(dest_p))
{ {
if(IsServer(source_p)) if(IsServer(source_p))
rb_linebuf_putmsg(&linebuf, pattern, args, ":%s %s %s ", rb_linebuf_put_vmsg_prefixf(&linebuf, pattern, args, ":%s %s %s ",
source_p->name, command, source_p->name, command,
target_p->name); target_p->name);
else else
@ -1188,11 +1187,11 @@ _sendto_anywhere(struct Client *dest_p, struct Client *target_p,
build_msgbuf_from(&msgbuf, source_p, command); build_msgbuf_from(&msgbuf, source_p, command);
msgbuf.target = target_p->name; msgbuf.target = target_p->name;
linebuf_put_msgvbuf(&msgbuf, &linebuf, dest_p->localClient->caps, pattern, args); linebuf_put_tags_vprefix(&msgbuf, &linebuf, dest_p->localClient->caps, pattern, args);
} }
} }
else else
rb_linebuf_putmsg(&linebuf, pattern, args, ":%s %s %s ", rb_linebuf_put_vmsg_prefixf(&linebuf, pattern, args, ":%s %s %s ",
get_id(source_p, target_p), command, get_id(source_p, target_p), command,
get_id(target_p, target_p)); get_id(target_p, target_p));
@ -1268,7 +1267,8 @@ sendto_realops_snomask(int flags, int level, const char *pattern, ...)
va_start(args, pattern); va_start(args, pattern);
vsnprintf(buf, sizeof(buf), pattern, args); vsnprintf(buf, sizeof(buf), pattern, args);
va_end(args); va_end(args);
rb_linebuf_putmsg(&linebuf, pattern, NULL,
rb_linebuf_put_msgf(&linebuf,
":%s NOTICE * :*** Notice -- %s", me.name, buf); ":%s NOTICE * :*** Notice -- %s", me.name, buf);
snobuf = construct_snobuf(flags); snobuf = construct_snobuf(flags);
if (snobuf[1] != '\0') if (snobuf[1] != '\0')
@ -1282,14 +1282,15 @@ sendto_realops_snomask(int flags, int level, const char *pattern, ...)
va_start(args, pattern); va_start(args, pattern);
vsnprintf(buf, sizeof(buf), pattern, args); vsnprintf(buf, sizeof(buf), pattern, args);
va_end(args); va_end(args);
rb_linebuf_putmsg(&linebuf, pattern, NULL,
rb_linebuf_put_msgf(&linebuf,
":%s NOTICE * :*** Notice -- %s", me.name, buf); ":%s NOTICE * :*** Notice -- %s", me.name, buf);
sendto_one_notice(remote_rehash_oper_p, ":*** Notice -- %s", buf); sendto_one_notice(remote_rehash_oper_p, ":*** Notice -- %s", buf);
} }
else else
{ {
va_start(args, pattern); va_start(args, pattern);
rb_linebuf_putmsg(&linebuf, pattern, &args, rb_linebuf_put_vmsg_prefixf(&linebuf, pattern, &args,
":%s NOTICE * :*** Notice -- ", me.name); ":%s NOTICE * :*** Notice -- ", me.name);
va_end(args); va_end(args);
} }
@ -1331,7 +1332,7 @@ sendto_realops_snomask_from(int flags, int level, struct Client *source_p,
rb_linebuf_newbuf(&linebuf); rb_linebuf_newbuf(&linebuf);
va_start(args, pattern); va_start(args, pattern);
rb_linebuf_putmsg(&linebuf, pattern, &args, rb_linebuf_put_vmsg_prefixf(&linebuf, pattern, &args,
":%s NOTICE * :*** Notice -- ", source_p->name); ":%s NOTICE * :*** Notice -- ", source_p->name);
va_end(args); va_end(args);
@ -1376,11 +1377,11 @@ sendto_wallops_flags(int flags, struct Client *source_p, const char *pattern, ..
va_start(args, pattern); va_start(args, pattern);
if(IsPerson(source_p)) if(IsPerson(source_p))
rb_linebuf_putmsg(&linebuf, pattern, &args, rb_linebuf_put_vmsg_prefixf(&linebuf, pattern, &args,
":%s!%s@%s WALLOPS :", source_p->name, ":%s!%s@%s WALLOPS :", source_p->name,
source_p->username, source_p->host); source_p->username, source_p->host);
else else
rb_linebuf_putmsg(&linebuf, pattern, &args, ":%s WALLOPS :", source_p->name); rb_linebuf_put_vmsg_prefixf(&linebuf, pattern, &args, ":%s WALLOPS :", source_p->name);
va_end(args); va_end(args);
@ -1410,7 +1411,7 @@ kill_client(struct Client *target_p, struct Client *diedie, const char *pattern,
rb_linebuf_newbuf(&linebuf); rb_linebuf_newbuf(&linebuf);
va_start(args, pattern); va_start(args, pattern);
rb_linebuf_putmsg(&linebuf, pattern, &args, ":%s KILL %s :", rb_linebuf_put_vmsg_prefixf(&linebuf, pattern, &args, ":%s KILL %s :",
get_id(&me, target_p), get_id(diedie, target_p)); get_id(&me, target_p), get_id(diedie, target_p));
va_end(args); va_end(args);
@ -1446,7 +1447,7 @@ kill_client_serv_butone(struct Client *one, struct Client *target_p, const char
vsnprintf(buf, sizeof(buf), pattern, args); vsnprintf(buf, sizeof(buf), pattern, args);
va_end(args); va_end(args);
rb_linebuf_putmsg(&rb_linebuf_id, NULL, NULL, ":%s KILL %s :%s", rb_linebuf_put_msgf(&rb_linebuf_id, ":%s KILL %s :%s",
use_id(&me), use_id(target_p), buf); use_id(&me), use_id(target_p), buf);
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, serv_list.head) RB_DLINK_FOREACH_SAFE(ptr, next_ptr, serv_list.head)

View file

@ -127,6 +127,17 @@ char *rb_strerror(int error);
#define HOSTIPLEN 53 #define HOSTIPLEN 53
#endif #endif
/* For those unfamiliar with GNU format attributes, a is the 1 based
* argument number of the format string, and b is the 1 based argument
* number of the variadic ... */
#ifdef __GNUC__
#define AFP(a,b) __attribute__((format (printf, a, b)))
#else
#define AFP(a,b)
#endif
#ifdef __GNUC__ #ifdef __GNUC__
#define slrb_assert(expr) ( \ #define slrb_assert(expr) ( \
rb_likely((expr)) || ( \ rb_likely((expr)) || ( \

View file

@ -39,12 +39,14 @@ struct _buf_line;
struct _buf_head; struct _buf_head;
/* IRCv3 tags (512 bytes) + RFC1459 message (510 bytes) */ /* IRCv3 tags (512 bytes) + RFC1459 message (510 bytes) */
#define LINEBUF_DATA_SIZE (512 + 510) #define LINEBUF_TAGSLEN 512 /* IRCv3 message tags */
#define LINEBUF_DATALEN 510 /* RFC1459 message data */
#define LINEBUF_SIZE (512 + 510)
#define CRLF_LEN 2 #define CRLF_LEN 2
typedef struct _buf_line typedef struct _buf_line
{ {
char buf[LINEBUF_DATA_SIZE + CRLF_LEN + 1]; char buf[LINEBUF_SIZE + CRLF_LEN + 1];
uint8_t terminated; /* Whether we've terminated the buffer */ uint8_t terminated; /* Whether we've terminated the buffer */
uint8_t raw; /* Whether this linebuf may hold 8-bit data */ uint8_t raw; /* Whether this linebuf may hold 8-bit data */
int len; /* How much data we've got */ int len; /* How much data we've got */
@ -72,10 +74,15 @@ void rb_linebuf_newbuf(buf_head_t *);
void rb_linebuf_donebuf(buf_head_t *); void rb_linebuf_donebuf(buf_head_t *);
int rb_linebuf_parse(buf_head_t *, char *, int, int); int rb_linebuf_parse(buf_head_t *, char *, int, int);
int rb_linebuf_get(buf_head_t *, char *, int, int, int); int rb_linebuf_get(buf_head_t *, char *, int, int, int);
void rb_linebuf_putmsg(buf_head_t *, const char *, va_list *, const char *, ...); /* "msg" is limited to RFC1459 message size */
void rb_linebuf_putprefix(buf_head_t *, const char *, va_list *, const char *, size_t); void rb_linebuf_put_msgf(buf_head_t *, const char *, ...) AFP(2,3);
void rb_linebuf_put(buf_head_t *, const char *, ...); void rb_linebuf_put_vmsg(buf_head_t *, const char *, va_list *);
void rb_linebuf_putbuf(buf_head_t * bufhead, const char *buffer); void rb_linebuf_put_vmsg_prefixf(buf_head_t *, const char *, va_list *, const char *, ...) AFP(4,5);
/* "tags" has a prefix that contains tags AND messages, it must
* specify the correct total buffer length to enforce the limit
* of the RFC1459 message size */
void rb_linebuf_put_vtags_prefix(buf_head_t *, const char *, va_list *, size_t, const char *);
void rb_linebuf_put_vtags_prefixf(buf_head_t *, const char *, va_list *, size_t, const char *, ...) AFP(5,6);
void rb_linebuf_attach(buf_head_t *, buf_head_t *); void rb_linebuf_attach(buf_head_t *, buf_head_t *);
void rb_count_rb_linebuf_memory(size_t *, size_t *); void rb_count_rb_linebuf_memory(size_t *, size_t *);
int rb_linebuf_flush(rb_fde_t *F, buf_head_t *); int rb_linebuf_flush(rb_fde_t *F, buf_head_t *);

View file

@ -100,10 +100,11 @@ rb_linebuf_get
rb_linebuf_init rb_linebuf_init
rb_linebuf_newbuf rb_linebuf_newbuf
rb_linebuf_parse rb_linebuf_parse
rb_linebuf_put rb_linebuf_put_msgf
rb_linebuf_putbuf rb_linebuf_put_vmsg
rb_linebuf_putmsg rb_linebuf_put_vmsg_prefixf
rb_linebuf_putprefix rb_linebuf_put_vtags_prefix
rb_linebuf_put_vtags_prefixf
rb_listen rb_listen
rb_make_rb_dlink_node rb_make_rb_dlink_node
rb_match_exact_string rb_match_exact_string

View file

@ -215,7 +215,7 @@ rb_helper_write_queue(rb_helper *helper, const char *format, ...)
{ {
va_list ap; va_list ap;
va_start(ap, format); va_start(ap, format);
rb_linebuf_putmsg(&helper->sendq, format, &ap, NULL); rb_linebuf_put_vmsg(&helper->sendq, format, &ap);
va_end(ap); va_end(ap);
} }
@ -231,7 +231,7 @@ rb_helper_write(rb_helper *helper, const char *format, ...)
{ {
va_list ap; va_list ap;
va_start(ap, format); va_start(ap, format);
rb_linebuf_putmsg(&helper->sendq, format, &ap, NULL); rb_linebuf_put_vmsg(&helper->sendq, format, &ap);
va_end(ap); va_end(ap);
rb_helper_write_flush(helper); rb_helper_write_flush(helper);
} }

View file

@ -204,7 +204,7 @@ rb_linebuf_copy_line(buf_head_t * bufhead, buf_line_t * bufline, char *data, int
/* If its full or terminated, ignore it */ /* If its full or terminated, ignore it */
bufline->raw = 0; bufline->raw = 0;
lrb_assert(bufline->len <= LINEBUF_DATA_SIZE); lrb_assert(bufline->len <= LINEBUF_SIZE);
if(bufline->terminated == 1) if(bufline->terminated == 1)
return 0; return 0;
@ -213,12 +213,12 @@ rb_linebuf_copy_line(buf_head_t * bufhead, buf_line_t * bufline, char *data, int
return -1; return -1;
/* This is the ~overflow case..This doesn't happen often.. */ /* This is the ~overflow case..This doesn't happen often.. */
if(cpylen > (LINEBUF_DATA_SIZE - bufline->len)) if(cpylen > (LINEBUF_SIZE - bufline->len))
{ {
cpylen = LINEBUF_DATA_SIZE - bufline->len; cpylen = LINEBUF_SIZE - bufline->len;
memcpy(bufch, ch, cpylen); memcpy(bufch, ch, cpylen);
bufline->buf[LINEBUF_DATA_SIZE] = '\0'; bufline->buf[LINEBUF_SIZE] = '\0';
bufch = bufline->buf + LINEBUF_DATA_SIZE - 1; bufch = bufline->buf + LINEBUF_SIZE - 1;
while(cpylen && (*bufch == '\r' || *bufch == '\n')) while(cpylen && (*bufch == '\r' || *bufch == '\n'))
{ {
*bufch = '\0'; *bufch = '\0';
@ -226,8 +226,8 @@ rb_linebuf_copy_line(buf_head_t * bufhead, buf_line_t * bufline, char *data, int
bufch--; bufch--;
} }
bufline->terminated = 1; bufline->terminated = 1;
bufline->len = LINEBUF_DATA_SIZE; bufline->len = LINEBUF_SIZE;
bufhead->len += LINEBUF_DATA_SIZE; bufhead->len += LINEBUF_SIZE;
return clen; return clen;
} }
@ -278,7 +278,7 @@ rb_linebuf_copy_raw(buf_head_t * bufhead, buf_line_t * bufline, char *data, int
/* If its full or terminated, ignore it */ /* If its full or terminated, ignore it */
bufline->raw = 1; bufline->raw = 1;
lrb_assert(bufline->len <= LINEBUF_DATA_SIZE); lrb_assert(bufline->len <= LINEBUF_SIZE);
if(bufline->terminated == 1) if(bufline->terminated == 1)
return 0; return 0;
@ -287,14 +287,14 @@ rb_linebuf_copy_raw(buf_head_t * bufhead, buf_line_t * bufline, char *data, int
return -1; return -1;
/* This is the overflow case..This doesn't happen often.. */ /* This is the overflow case..This doesn't happen often.. */
if(cpylen > (LINEBUF_DATA_SIZE - bufline->len)) if(cpylen > (LINEBUF_SIZE - bufline->len))
{ {
clen = LINEBUF_DATA_SIZE - bufline->len; clen = LINEBUF_SIZE - bufline->len;
memcpy(bufch, ch, clen); memcpy(bufch, ch, clen);
bufline->buf[LINEBUF_DATA_SIZE] = '\0'; bufline->buf[LINEBUF_SIZE] = '\0';
bufline->terminated = 1; bufline->terminated = 1;
bufline->len = LINEBUF_DATA_SIZE; bufline->len = LINEBUF_SIZE;
bufhead->len += LINEBUF_DATA_SIZE; bufhead->len += LINEBUF_SIZE;
return clen; return clen;
} }
@ -485,253 +485,140 @@ rb_linebuf_attach(buf_head_t * bufhead, buf_head_t * new)
} }
/* /*
* rb_linebuf_putmsg * rb_linebuf_put_vstr_vprefix
* *
* Similar to rb_linebuf_put, but designed for use by send.c. * prefix (with/without prefix_args) is inserted first, then format/va_args is
* appended to the buffer.
* *
* prefixfmt is used as a format for the varargs, and is inserted first. * max_buflen is the maximum size of the buffer that can be used
* Then format/va_args is appended to the buffer. * (including the NULL terminator) so that the RFC1459 message is not too long
*/ */
void static void
rb_linebuf_putmsg(buf_head_t * bufhead, const char *format, va_list * va_args, rb_linebuf_put_vstr_vprefix(buf_head_t *bufhead, const char *format, va_list *format_args,
const char *prefixfmt, ...) size_t max_buflen, const char *prefix, va_list *prefix_args)
{ {
buf_line_t *bufline; buf_line_t *bufline;
int len = 0; ssize_t len = 0;
va_list prefix_args;
/* make sure the previous line is terminated */ /* make sure the previous line is terminated */
if(bufhead->list.tail) if (bufhead->list.tail) {
{
bufline = bufhead->list.tail->data; bufline = bufhead->list.tail->data;
lrb_assert(bufline->terminated); lrb_assert(bufline->terminated);
} }
/* Create a new line */ /* create a new line */
bufline = rb_linebuf_new_line(bufhead); bufline = rb_linebuf_new_line(bufhead);
if(prefixfmt != NULL) if (max_buflen > LINEBUF_SIZE + 1)
{ max_buflen = LINEBUF_SIZE + 1;
va_start(prefix_args, prefixfmt);
len = vsnprintf(bufline->buf, LINEBUF_DATA_SIZE + 1, prefixfmt, prefix_args); if (prefix != NULL) {
va_end(prefix_args); if (prefix_args != NULL) {
len = vsnprintf(bufline->buf, max_buflen, prefix, *prefix_args);
} else {
len = rb_strlcpy(bufline->buf, prefix, max_buflen);
} }
if(va_args != NULL) if (len > max_buflen - 1)
{ len = max_buflen - 1;
len += vsnprintf((bufline->buf + len), (LINEBUF_DATA_SIZE - len) + 1, format, *va_args);
} }
bufline->terminated = 1; if (format != NULL) {
len += vsnprintf(bufline->buf + len, max_buflen - len, format, *format_args);
/* Truncate the data if required */ if (len > max_buflen - 1)
if(len > LINEBUF_DATA_SIZE) len = max_buflen - 1;
{
len = LINEBUF_DATA_SIZE;
bufline->buf[len++] = '\r';
bufline->buf[len++] = '\n';
} }
else if(len == 0)
{ /* add trailing CRLF */
bufline->buf[len++] = '\r'; bufline->buf[len++] = '\r';
bufline->buf[len++] = '\n'; bufline->buf[len++] = '\n';
bufline->buf[len] = '\0'; bufline->buf[len] = '\0';
}
else
{
/* Chop trailing CRLF's .. */
while((bufline->buf[len] == '\r') || (bufline->buf[len] == '\n')
|| (bufline->buf[len] == '\0'))
{
len--;
}
bufline->buf[++len] = '\r'; bufline->terminated = 1;
bufline->buf[++len] = '\n';
bufline->buf[++len] = '\0';
}
bufline->len = len; bufline->len = len;
bufhead->len += len; bufhead->len += len;
} }
/* /*
* rb_linebuf_putprefix * rb_linebuf_put_vtags_prefix
* *
* Similar to rb_linebuf_put, but designed for use by send.c. * prefix is inserted first, then format/va_args is
* appended to the buffer.
* *
* prefix is inserted first, then format/va_args is appended to the buffer. * prefix_buflen is the maximum size of the buffer that can be used
* prefix_buflen is the maximum size of the buffer that can be used so that the RFC1459 message is not too long * (including the NULL terminator) so that the RFC1459 message is not too long
*/ */
void void
rb_linebuf_putprefix(buf_head_t * bufhead, const char *format, va_list * va_args, rb_linebuf_put_vtags_prefix(buf_head_t *bufhead, const char *format, va_list *va_args,
const char *prefix, size_t prefix_buflen) size_t prefix_buflen, const char *prefix)
{ {
buf_line_t *bufline; rb_linebuf_put_vstr_vprefix(bufhead, format, va_args, prefix_buflen, prefix, NULL);
int len = 0;
/* make sure the previous line is terminated */
if(bufhead->list.tail)
{
bufline = bufhead->list.tail->data;
lrb_assert(bufline->terminated);
}
/* Create a new line */
bufline = rb_linebuf_new_line(bufhead);
if(prefix != NULL)
len = rb_strlcpy(bufline->buf, prefix, LINEBUF_DATA_SIZE + 1);
if(va_args != NULL)
{
if (prefix_buflen > LINEBUF_DATA_SIZE + 1)
prefix_buflen = LINEBUF_DATA_SIZE + 1;
len += vsnprintf((bufline->buf + len), prefix_buflen - len, format, *va_args);
}
bufline->terminated = 1;
/* Truncate the data if required */
if(len > LINEBUF_DATA_SIZE)
{
len = LINEBUF_DATA_SIZE;
bufline->buf[len++] = '\r';
bufline->buf[len++] = '\n';
}
else if(len == 0)
{
bufline->buf[len++] = '\r';
bufline->buf[len++] = '\n';
bufline->buf[len] = '\0';
}
else
{
/* Chop trailing CRLF's .. */
while((bufline->buf[len] == '\r') || (bufline->buf[len] == '\n')
|| (bufline->buf[len] == '\0'))
{
len--;
}
bufline->buf[++len] = '\r';
bufline->buf[++len] = '\n';
bufline->buf[++len] = '\0';
}
bufline->len = len;
bufhead->len += len;
} }
/*
* rb_linebuf_put_vtags_prefixf
*
* prefixfmt is inserted first, then format/va_args is
* appended to the buffer.
*
* prefix_buflen is the maximum size of the buffer that can be used
* (including the NULL terminator) so that the RFC1459 message is not too long
*/
void void
rb_linebuf_putbuf(buf_head_t * bufhead, const char *buffer) rb_linebuf_put_vtags_prefixf(buf_head_t *bufhead, const char *format, va_list *va_args,
size_t prefix_buflen, const char *prefixfmt, ...)
{ {
buf_line_t *bufline; va_list prefix_args;
int len = 0;
/* make sure the previous line is terminated */
if(bufhead->list.tail)
{
bufline = bufhead->list.tail->data;
lrb_assert(bufline->terminated);
}
/* Create a new line */
bufline = rb_linebuf_new_line(bufhead);
if(buffer != NULL)
len = rb_strlcpy(bufline->buf, buffer, LINEBUF_DATA_SIZE + 1);
bufline->terminated = 1;
/* Truncate the data if required */
if(len > LINEBUF_DATA_SIZE)
{
len = LINEBUF_DATA_SIZE;
bufline->buf[len++] = '\r';
bufline->buf[len++] = '\n';
}
else if(len == 0)
{
bufline->buf[len++] = '\r';
bufline->buf[len++] = '\n';
bufline->buf[len] = '\0';
}
else
{
/* Chop trailing CRLF's .. */
while((bufline->buf[len] == '\r') || (bufline->buf[len] == '\n')
|| (bufline->buf[len] == '\0'))
{
len--;
}
bufline->buf[++len] = '\r';
bufline->buf[++len] = '\n';
bufline->buf[++len] = '\0';
}
bufline->len = len;
bufhead->len += len;
va_start(prefix_args, prefixfmt);
rb_linebuf_put_vstr_vprefix(bufhead, format, va_args, prefix_buflen, prefixfmt, &prefix_args);
va_end(prefix_args);
} }
/*
* rb_linebuf_put_msgf
*
* format (with args) is appended to the buffer.
* Messages will be limited to the RFC1459 data length
*/
void void
rb_linebuf_put(buf_head_t * bufhead, const char *format, ...) rb_linebuf_put_msgf(buf_head_t *bufhead, const char *format, ...)
{ {
buf_line_t *bufline; va_list va_args;
int len = 0;
va_list args;
/* make sure the previous line is terminated */ va_start(va_args, format);
if(bufhead->list.tail) rb_linebuf_put_vstr_vprefix(bufhead, format, &va_args, LINEBUF_DATALEN + 1, NULL, NULL);
{ va_end(va_args);
bufline = bufhead->list.tail->data; }
lrb_assert(bufline->terminated);
}
/* Create a new line */ /*
bufline = rb_linebuf_new_line(bufhead); * rb_linebuf_put_vmsg
*
* format/va_args is appended to the buffer.
* Messages will be limited to the RFC1459 data length
*/
void
rb_linebuf_put_vmsg(buf_head_t *bufhead, const char *format, va_list *va_args)
{
rb_linebuf_put_vstr_vprefix(bufhead, format, va_args, LINEBUF_DATALEN + 1, NULL, NULL);
}
if(format != NULL) /*
{ * rb_linebuf_put_vmsg_prefixf
va_start(args, format); *
len = vsnprintf(bufline->buf, LINEBUF_DATA_SIZE + 1, format, args); * prefix is inserted first, then format/va_args is appended to the buffer.
va_end(args); * Messages will be limited to the RFC1459 data length
} */
void
rb_linebuf_put_vmsg_prefixf(buf_head_t *bufhead, const char *format, va_list *va_args,
const char *prefixfmt, ...)
{
va_list prefix_args;
bufline->terminated = 1; va_start(prefix_args, prefixfmt);
rb_linebuf_put_vstr_vprefix(bufhead, format, va_args, LINEBUF_DATALEN + 1, prefixfmt, &prefix_args);
/* Truncate the data if required */ va_end(prefix_args);
if(len > LINEBUF_DATA_SIZE)
{
len = LINEBUF_DATA_SIZE;
bufline->buf[len++] = '\r';
bufline->buf[len++] = '\n';
}
else if(len == 0)
{
bufline->buf[len++] = '\r';
bufline->buf[len++] = '\n';
bufline->buf[len] = '\0';
}
else
{
/* Chop trailing CRLF's .. */
while((bufline->buf[len] == '\r') || (bufline->buf[len] == '\n')
|| (bufline->buf[len] == '\0'))
{
len--;
}
bufline->buf[++len] = '\r';
bufline->buf[++len] = '\n';
bufline->buf[++len] = '\0';
}
bufline->len = len;
bufhead->len += len;
} }