1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-08 08:58:00 +00:00
putty-source/be_misc.c
Simon Tatham 8d186c3c93 Formatting change to braces around one case of a switch.
Sometimes, within a switch statement, you want to declare local
variables specific to the handler for one particular case. Until now
I've mostly been writing this in the form

    switch (discriminant) {
      case SIMPLE:
        do stuff;
        break;
      case COMPLICATED:
        {
            declare variables;
            do stuff;
        }
        break;
    }

which is ugly because the two pieces of essentially similar code
appear at different indent levels, and also inconvenient because you
have less horizontal space available to write the complicated case
handler in - particuarly undesirable because _complicated_ case
handlers are the ones most likely to need all the space they can get!

After encountering a rather nicer idiom in the LLVM source code, and
after a bit of hackery this morning figuring out how to persuade
Emacs's auto-indent to do what I wanted with it, I've decided to move
to an idiom in which the open brace comes right after the case
statement, and the code within it is indented the same as it would
have been without the brace. Then the whole case handler (including
the break) lives inside those braces, and you get something that looks
more like this:

    switch (discriminant) {
      case SIMPLE:
        do stuff;
        break;
      case COMPLICATED: {
        declare variables;
        do stuff;
        break;
      }
    }

This commit is a big-bang change that reformats all the complicated
case handlers I could find into the new layout. This is particularly
nice in the Pageant main function, in which almost _every_ case
handler had a bundle of variables and was long and complicated. (In
fact that's what motivated me to get round to this.) Some of the
innermost parts of the terminal escape-sequence handling are also
breathing a bit easier now the horizontal pressure on them is
relieved.

(Also, in a few cases, I was able to remove the extra braces
completely, because the only variable local to the case handler was a
loop variable which our new C99 policy allows me to move into the
initialiser clause of its for statement.)

Viewed with whitespace ignored, this is not too disruptive a change.
Downstream patches that conflict with it may need to be reapplied
using --ignore-whitespace or similar.
2020-02-16 11:26:21 +00:00

155 lines
4.7 KiB
C

/*
* be_misc.c: helper functions shared between main network backends.
*/
#include <assert.h>
#include <string.h>
#include "putty.h"
#include "network.h"
void backend_socket_log(Seat *seat, LogContext *logctx,
PlugLogType type, SockAddr *addr, int port,
const char *error_msg, int error_code, Conf *conf,
bool session_started)
{
char addrbuf[256], *msg;
switch (type) {
case PLUGLOG_CONNECT_TRYING:
sk_getaddr(addr, addrbuf, lenof(addrbuf));
if (sk_addr_needs_port(addr)) {
msg = dupprintf("Connecting to %s port %d", addrbuf, port);
} else {
msg = dupprintf("Connecting to %s", addrbuf);
}
break;
case PLUGLOG_CONNECT_FAILED:
sk_getaddr(addr, addrbuf, lenof(addrbuf));
msg = dupprintf("Failed to connect to %s: %s", addrbuf, error_msg);
break;
case PLUGLOG_CONNECT_SUCCESS:
sk_getaddr(addr, addrbuf, lenof(addrbuf));
msg = dupprintf("Connected to %s", addrbuf);
break;
case PLUGLOG_PROXY_MSG: {
/* Proxy-related log messages have their own identifying
* prefix already, put on by our caller. */
int len, log_to_term;
/* Suffix \r\n temporarily, so we can log to the terminal. */
msg = dupprintf("%s\r\n", error_msg);
len = strlen(msg);
assert(len >= 2);
log_to_term = conf_get_int(conf, CONF_proxy_log_to_term);
if (log_to_term == AUTO)
log_to_term = session_started ? FORCE_OFF : FORCE_ON;
if (log_to_term == FORCE_ON)
seat_stderr(seat, msg, len);
msg[len-2] = '\0'; /* remove the \r\n again */
break;
}
default:
msg = NULL; /* shouldn't happen, but placate optimiser */
break;
}
if (msg) {
logevent(logctx, msg);
sfree(msg);
}
}
void psb_init(ProxyStderrBuf *psb)
{
psb->size = 0;
}
void log_proxy_stderr(Plug *plug, ProxyStderrBuf *psb,
const void *vdata, size_t len)
{
const char *data = (const char *)vdata;
/*
* This helper function allows us to collect the data written to a
* local proxy command's standard error in whatever size chunks we
* happen to get from its pipe, and whenever we have a complete
* line, we pass it to plug_log.
*
* (We also do this when the buffer in psb fills up, to avoid just
* allocating more and more memory forever, and also to keep Event
* Log lines reasonably bounded in size.)
*
* Prerequisites: a plug to log to, and a ProxyStderrBuf stored
* somewhere to collect any not-yet-output partial line.
*/
while (len > 0) {
/*
* Copy as much data into psb->buf as will fit.
*/
assert(psb->size < lenof(psb->buf));
size_t to_consume = lenof(psb->buf) - psb->size;
if (to_consume > len)
to_consume = len;
memcpy(psb->buf + psb->size, data, to_consume);
data += to_consume;
len -= to_consume;
psb->size += to_consume;
/*
* Output any full lines in psb->buf.
*/
size_t pos = 0;
while (pos < psb->size) {
char *nlpos = memchr(psb->buf + pos, '\n', psb->size - pos);
if (!nlpos)
break;
/*
* Found a newline in the buffer, so we can output a line.
*/
size_t endpos = nlpos - psb->buf;
while (endpos > pos && (psb->buf[endpos-1] == '\n' ||
psb->buf[endpos-1] == '\r'))
endpos--;
char *msg = dupprintf(
"proxy: %.*s", (int)(endpos - pos), psb->buf + pos);
plug_log(plug, PLUGLOG_PROXY_MSG, NULL, 0, msg, 0);
sfree(msg);
pos = nlpos - psb->buf + 1;
assert(pos <= psb->size);
}
/*
* If the buffer is completely full and we didn't output
* anything, then output the whole thing, flagging it as a
* truncated line.
*/
if (pos == 0 && psb->size == lenof(psb->buf)) {
char *msg = dupprintf(
"proxy (partial line): %.*s", (int)psb->size, psb->buf);
plug_log(plug, PLUGLOG_PROXY_MSG, NULL, 0, msg, 0);
sfree(msg);
pos = psb->size = 0;
}
/*
* Now move any remaining data up to the front of the buffer.
*/
size_t newsize = psb->size - pos;
if (newsize)
memmove(psb->buf, psb->buf + pos, newsize);
psb->size = newsize;
/*
* And loop round again if there's more data to be read from
* our input.
*/
}
}