From e08039a2bd0352b219c733140365ec0c8ef9cca6 Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Wed, 27 Apr 2016 16:10:14 -0700 Subject: [PATCH] restyle common module to match project style Reduces lint errors from 194 to 142 (-27%). Line count from 3352 to 2645 (-21%). Another step in resolving issue #2902. --- src/common.cpp | 1972 ++++++++++++++++++------------------------------ src/common.h | 877 +++++++++------------ 2 files changed, 1072 insertions(+), 1777 deletions(-) diff --git a/src/common.cpp b/src/common.cpp index 75f3c945a..eedcd1c99 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -1,46 +1,43 @@ -/** \file common.c - -Various functions, mostly string utilities, that are used by most -parts of fish. -*/ +// Various functions, mostly string utilities, that are used by most parts of fish. #include "config.h" -#include -#ifdef HAVE_SIGINFO_H -#include -#endif -#include -#include -#include -#include -#include -#include #include -#include -#include -#ifdef HAVE_SYS_IOCTL_H -#include -#endif -#include -#include #include #include -#include -#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -#include +#include +#include +#include +#include +#include #ifdef HAVE_EXECINFO_H #include #endif -#include -#include +#ifdef HAVE_SIGINFO_H +#include +#endif +#ifdef HAVE_SYS_IOCTL_H +#include +#endif +#include +#include // IWYU pragma: keep -#include "fallback.h" // IWYU pragma: keep -#include "wutil.h" // IWYU pragma: keep #include "common.h" #include "expand.h" +#include "fallback.h" // IWYU pragma: keep #include "wildcard.h" +#include "wutil.h" // IWYU pragma: keep #define NOT_A_WCHAR (static_cast(WEOF)) @@ -57,25 +54,22 @@ bool g_profiling_active = false; const wchar_t *program_name; -int debug_level=1; +int debug_level = 1; -/** - This struct maintains the current state of the terminal size. It is updated on demand after receiving a SIGWINCH. - Do not touch this struct directly, it's managed with a rwlock. Use common_get_width()/common_get_height(). -*/ +/// This struct maintains the current state of the terminal size. It is updated on demand after +/// receiving a SIGWINCH. Do not touch this struct directly, it's managed with a rwlock. Use +/// common_get_width()/common_get_height(). static struct winsize termsize; static volatile bool termsize_valid; static rwlock_t termsize_rwlock; static char *wcs2str_internal(const wchar_t *in, char *out); -void show_stackframe() -{ +void show_stackframe() { ASSERT_IS_NOT_FORKED_CHILD(); - /* Hack to avoid showing backtraces in the tester */ - if (program_name && ! wcscmp(program_name, L"(ignore)")) - return; + // Hack to avoid showing backtraces in the tester. + if (program_name && !wcscmp(program_name, L"(ignore)")) return; void *trace[32]; int trace_size = 0; @@ -85,65 +79,55 @@ void show_stackframe() backtrace_symbols_fd(trace, trace_size, STDERR_FILENO); } -int fgetws2(wcstring *s, FILE *f) -{ - int i=0; +int fgetws2(wcstring *s, FILE *f) { + int i = 0; wint_t c; - while (1) - { - errno=0; + while (1) { + errno = 0; c = fgetwc(f); - if (errno == EILSEQ || errno == EINTR) - { + if (errno == EILSEQ || errno == EINTR) { continue; } - switch (c) - { - /* End of line */ + switch (c) { + // End of line. case WEOF: case L'\n': - case L'\0': + case L'\0': { return i; - /* Ignore carriage returns */ - case L'\r': + } + // Ignore carriage returns. + case L'\r': { break; - - default: + } + default: { i++; s->push_back((wchar_t)c); break; + } } } } -/** - Converts the narrow character string \c in into its wide - equivalent, and return it - - The string may contain embedded nulls. - - This function encodes illegal character sequences in a reversible - way using the private use area. -*/ - -static wcstring str2wcs_internal(const char *in, const size_t in_len) -{ - if (in_len == 0) - return wcstring(); - +/// Converts the narrow character string \c in into its wide equivalent, and return it. +/// +/// The string may contain embedded nulls. +/// +/// This function encodes illegal character sequences in a reversible way using the private use +/// area. +static wcstring str2wcs_internal(const char *in, const size_t in_len) { + if (in_len == 0) return wcstring(); assert(in != NULL); wcstring result; result.reserve(in_len); size_t in_pos = 0; - if (MB_CUR_MAX == 1) // single-byte locale, all values are legal + if (MB_CUR_MAX == 1) // single-byte locale, all values are legal { - while (in_pos < in_len) - { + while (in_pos < in_len) { result.push_back((unsigned char)in[in_pos]); in_pos++; } @@ -151,54 +135,39 @@ static wcstring str2wcs_internal(const char *in, const size_t in_len) } mbstate_t state = {}; - while (in_pos < in_len) - { + while (in_pos < in_len) { wchar_t wc = 0; - size_t ret = mbrtowc(&wc, &in[in_pos], in_len-in_pos, &state); + size_t ret = mbrtowc(&wc, &in[in_pos], in_len - in_pos, &state); - /* Determine whether to encode this characters with our crazy scheme */ + // Determine whether to encode this characters with our crazy scheme. bool use_encode_direct = false; - if (wc >= ENCODE_DIRECT_BASE && wc < ENCODE_DIRECT_BASE+256) - { + if (wc >= ENCODE_DIRECT_BASE && wc < ENCODE_DIRECT_BASE + 256) { use_encode_direct = true; - } - else if (wc == INTERNAL_SEPARATOR) - { + } else if (wc == INTERNAL_SEPARATOR) { use_encode_direct = true; - } - else if (ret == (size_t)-2) - { - /* Incomplete sequence */ + } else if (ret == (size_t)-2) { + // Incomplete sequence. use_encode_direct = true; - } - else if (ret == (size_t)-1) - { - /* Invalid data */ + } else if (ret == (size_t)-1) { + // Invalid data. use_encode_direct = true; - } - else if (ret > in_len - in_pos) - { - /* Other error codes? Terrifying, should never happen */ + } else if (ret > in_len - in_pos) { + // Other error codes? Terrifying, should never happen. use_encode_direct = true; } - if (use_encode_direct) - { + if (use_encode_direct) { wc = ENCODE_DIRECT_BASE + (unsigned char)in[in_pos]; result.push_back(wc); in_pos++; memset(&state, 0, sizeof state); - } - else if (ret == 0) - { - /* Embedded null byte! */ + } else if (ret == 0) { + // Embedded null byte! result.push_back(L'\0'); in_pos++; memset(&state, 0, sizeof state); - } - else - { - /* Normal case */ + } else { + // Normal case. result.push_back(wc); in_pos += ret; } @@ -206,102 +175,72 @@ static wcstring str2wcs_internal(const char *in, const size_t in_len) return result; } -wcstring str2wcstring(const char *in, size_t len) -{ - return str2wcs_internal(in, len); -} +wcstring str2wcstring(const char *in, size_t len) { return str2wcs_internal(in, len); } -wcstring str2wcstring(const char *in) -{ - return str2wcs_internal(in, strlen(in)); -} +wcstring str2wcstring(const char *in) { return str2wcs_internal(in, strlen(in)); } -wcstring str2wcstring(const std::string &in) -{ +wcstring str2wcstring(const std::string &in) { /* Handles embedded nulls! */ return str2wcs_internal(in.data(), in.size()); } -char *wcs2str(const wchar_t *in) -{ - if (! in) - return NULL; - size_t desired_size = MAX_UTF8_BYTES*wcslen(in)+1; +char *wcs2str(const wchar_t *in) { + if (!in) return NULL; + size_t desired_size = MAX_UTF8_BYTES * wcslen(in) + 1; char local_buff[512]; - if (desired_size <= sizeof local_buff / sizeof *local_buff) - { - // convert into local buff, then use strdup() so we don't waste malloc'd space + if (desired_size <= sizeof local_buff / sizeof *local_buff) { + // Convert into local buff, then use strdup() so we don't waste malloc'd space. char *result = wcs2str_internal(in, local_buff); - if (result) - { - // It converted into the local buffer, so copy it + if (result) { + // It converted into the local buffer, so copy it. result = strdup(result); - if (! result) - { + if (!result) { DIE_MEM(); } } return result; - } - else - { - // here we fall into the bad case of allocating a buffer probably much larger than necessary - char *out = (char *)malloc(MAX_UTF8_BYTES*wcslen(in)+1); - if (!out) - { + } else { + // Here we probably allocate a buffer probably much larger than necessary. + char *out = (char *)malloc(MAX_UTF8_BYTES * wcslen(in) + 1); + if (!out) { DIE_MEM(); } return wcs2str_internal(in, out); } } -char *wcs2str(const wcstring &in) -{ - return wcs2str(in.c_str()); -} +char *wcs2str(const wcstring &in) { return wcs2str(in.c_str()); } -/* This function is distinguished from wcs2str_internal in that it allows embedded null bytes */ -std::string wcs2string(const wcstring &input) -{ +/// This function is distinguished from wcs2str_internal in that it allows embedded null bytes. +std::string wcs2string(const wcstring &input) { std::string result; result.reserve(input.size()); mbstate_t state = {}; char converted[MB_LEN_MAX + 1]; - for (size_t i=0; i < input.size(); i++) - { + for (size_t i = 0; i < input.size(); i++) { wchar_t wc = input[i]; - if (wc == INTERNAL_SEPARATOR) - { + if (wc == INTERNAL_SEPARATOR) { // Do nothing. - } - else if (wc >= ENCODE_DIRECT_BASE && wc < ENCODE_DIRECT_BASE + 256) - { + } else if (wc >= ENCODE_DIRECT_BASE && wc < ENCODE_DIRECT_BASE + 256) { result.push_back(wc - ENCODE_DIRECT_BASE); - } - else if (MB_CUR_MAX == 1) // single-byte locale (C/POSIX/ISO-8859) + } else if (MB_CUR_MAX == 1) // single-byte locale (C/POSIX/ISO-8859) { // If `wc` contains a wide character we emit a question-mark. - if (wc & ~0xFF) - { + if (wc & ~0xFF) { wc = '?'; } converted[0] = wc; result.append(converted, 1); - } - else - { + } else { memset(converted, 0, sizeof converted); size_t len = wcrtomb(converted, wc, &state); - if (len == (size_t)(-1)) - { + if (len == (size_t)(-1)) { debug(1, L"Wide character %d has no narrow representation", wc); memset(&state, 0, sizeof(state)); - } - else - { + } else { result.append(converted, len); } } @@ -310,16 +249,12 @@ std::string wcs2string(const wcstring &input) return result; } -/** - Converts the wide character string \c in into it's narrow - equivalent, stored in \c out. \c out must have enough space to fit - the entire string. - - This function decodes illegal character sequences in a reversible - way using the private use area. -*/ -static char *wcs2str_internal(const wchar_t *in, char *out) -{ +/// Converts the wide character string \c in into it's narrow equivalent, stored in \c out. \c out +/// must have enough space to fit the entire string. +/// +/// This function decodes illegal character sequences in a reversible way using the private use +/// area. +static char *wcs2str_internal(const wchar_t *in, char *out) { CHECK(in, 0); CHECK(out, 0); @@ -327,39 +262,25 @@ static char *wcs2str_internal(const wchar_t *in, char *out) size_t out_pos = 0; mbstate_t state = {}; - while (in[in_pos]) - { - if (in[in_pos] == INTERNAL_SEPARATOR) - { + while (in[in_pos]) { + if (in[in_pos] == INTERNAL_SEPARATOR) { // Do nothing. - } - else if (in[in_pos] >= ENCODE_DIRECT_BASE && - in[in_pos] < ENCODE_DIRECT_BASE + 256) - { - out[out_pos++] = in[in_pos]- ENCODE_DIRECT_BASE; - } - else if (MB_CUR_MAX == 1) // single-byte locale (C/POSIX/ISO-8859) + } else if (in[in_pos] >= ENCODE_DIRECT_BASE && in[in_pos] < ENCODE_DIRECT_BASE + 256) { + out[out_pos++] = in[in_pos] - ENCODE_DIRECT_BASE; + } else if (MB_CUR_MAX == 1) // single-byte locale (C/POSIX/ISO-8859) { // If `wc` contains a wide character we emit a question-mark. - if (in[in_pos] & ~0xFF) - { + if (in[in_pos] & ~0xFF) { out[out_pos++] = '?'; - } - else - { + } else { out[out_pos++] = (unsigned char)in[in_pos]; } - } - else - { + } else { size_t len = wcrtomb(&out[out_pos], in[in_pos], &state); - if (len == (size_t)-1) - { + if (len == (size_t)-1) { debug(1, L"Wide character %d has no narrow representation", in[in_pos]); memset(&state, 0, sizeof(state)); - } - else - { + } else { out_pos += len; } } @@ -370,8 +291,7 @@ static char *wcs2str_internal(const wchar_t *in, char *out) return out; } -wcstring format_string(const wchar_t *format, ...) -{ +wcstring format_string(const wchar_t *format, ...) { va_list va; va_start(va, format); wcstring result = vformat_string(format, va); @@ -379,51 +299,39 @@ wcstring format_string(const wchar_t *format, ...) return result; } -void append_formatv(wcstring &target, const wchar_t *format, va_list va_orig) -{ +void append_formatv(wcstring &target, const wchar_t *format, va_list va_orig) { const int saved_err = errno; - /* - As far as I know, there is no way to check if a - vswprintf-call failed because of a badly formated string - option or because the supplied destination string was to - small. In GLIBC, errno seems to be set to EINVAL either way. - - Because of this, on failiure we try to - increase the buffer size until the free space is - larger than max_size, at which point it will - conclude that the error was probably due to a badly - formated string option, and return an error. Make - sure to null terminate string before that, though. - */ - const size_t max_size = (128*1024*1024); + // As far as I know, there is no way to check if a vswprintf-call failed because of a badly + // formated string option or because the supplied destination string was to small. In GLIBC, + // errno seems to be set to EINVAL either way. + // + // Because of this, on failiure we try to increase the buffer size until the free space is + // larger than max_size, at which point it will conclude that the error was probably due to a + // badly formated string option, and return an error. Make sure to null terminate string before + // that, though. + const size_t max_size = (128 * 1024 * 1024); wchar_t static_buff[256]; size_t size = 0; wchar_t *buff = NULL; int status = -1; - while (status < 0) - { - /* Reallocate if necessary */ - if (size == 0) - { + while (status < 0) { + // Reallocate if necessary. + if (size == 0) { buff = static_buff; size = sizeof static_buff; - } - else - { + } else { size *= 2; - if (size >= max_size) - { + if (size >= max_size) { buff[0] = '\0'; break; } buff = (wchar_t *)realloc((buff == static_buff ? NULL : buff), size); - if (buff == NULL) - { + if (buff == NULL) { DIE_MEM(); } } - /* Try printing */ + // Try printing. va_list va; va_copy(va, va_orig); status = vswprintf(buff, size / sizeof(wchar_t), format, va); @@ -432,35 +340,29 @@ void append_formatv(wcstring &target, const wchar_t *format, va_list va_orig) target.append(buff); - if (buff != static_buff) - { + if (buff != static_buff) { free(buff); } errno = saved_err; } -wcstring vformat_string(const wchar_t *format, va_list va_orig) -{ +wcstring vformat_string(const wchar_t *format, va_list va_orig) { wcstring result; append_formatv(result, format, va_orig); return result; } -void append_format(wcstring &str, const wchar_t *format, ...) -{ +void append_format(wcstring &str, const wchar_t *format, ...) { va_list va; va_start(va, format); append_formatv(str, format, va); va_end(va); } -const wchar_t *wcsvarname(const wchar_t *str) -{ - while (*str) - { - if ((!iswalnum(*str)) && (*str != L'_')) - { +const wchar_t *wcsvarname(const wchar_t *str) { + while (*str) { + if ((!iswalnum(*str)) && (*str != L'_')) { return str; } str++; @@ -468,72 +370,42 @@ const wchar_t *wcsvarname(const wchar_t *str) return NULL; } -const wchar_t *wcsvarname(const wcstring &str) -{ - return wcsvarname(str.c_str()); -} +const wchar_t *wcsvarname(const wcstring &str) { return wcsvarname(str.c_str()); } -const wchar_t *wcsfuncname(const wcstring &str) -{ - return wcschr(str.c_str(), L'/'); -} +const wchar_t *wcsfuncname(const wcstring &str) { return wcschr(str.c_str(), L'/'); } +bool wcsvarchr(wchar_t chr) { return iswalnum(chr) || chr == L'_'; } -bool wcsvarchr(wchar_t chr) -{ - return iswalnum(chr) || chr == L'_'; -} +int fish_wcswidth(const wchar_t *str) { return fish_wcswidth(str, wcslen(str)); } -int fish_wcswidth(const wchar_t *str) -{ - return fish_wcswidth(str, wcslen(str)); -} +int fish_wcswidth(const wcstring &str) { return fish_wcswidth(str.c_str(), str.size()); } -int fish_wcswidth(const wcstring& str) -{ - return fish_wcswidth(str.c_str(), str.size()); -} - -wchar_t *quote_end(const wchar_t *pos) -{ +wchar_t *quote_end(const wchar_t *pos) { wchar_t c = *pos; - while (1) - { + while (1) { pos++; - if (!*pos) - return 0; + if (!*pos) return 0; - if (*pos == L'\\') - { + if (*pos == L'\\') { pos++; - if (!*pos) - return 0; - } - else - { - if (*pos == c) - { + if (!*pos) return 0; + } else { + if (*pos == c) { return (wchar_t *)pos; } } } return 0; - } - -wcstring wsetlocale(int category, const wchar_t *locale) -{ - +wcstring wsetlocale(int category, const wchar_t *locale) { char *lang = locale ? wcs2str(locale) : NULL; char *res = setlocale(category, lang); free(lang); - /* - Use ellipsis if on known unicode system, otherwise use $ - */ + // Use ellipsis if on known unicode system, otherwise use $. ellipsis_char = (wcwidth(L'\x2026') > 0) ? L'\x2026' : L'$'; // U+23CE is the "return" character @@ -545,8 +417,7 @@ wcstring wsetlocale(int category, const wchar_t *locale) return format_string(L"%s", res); } -bool contains_internal(const wchar_t *a, int vararg_handle, ...) -{ +bool contains_internal(const wchar_t *a, int vararg_handle, ...) { const wchar_t *arg; va_list va; bool res = false; @@ -554,44 +425,38 @@ bool contains_internal(const wchar_t *a, int vararg_handle, ...) CHECK(a, 0); va_start(va, vararg_handle); - while ((arg=va_arg(va, const wchar_t *))!= 0) - { - if (wcscmp(a,arg) == 0) - { + while ((arg = va_arg(va, const wchar_t *)) != 0) { + if (wcscmp(a, arg) == 0) { res = true; break; } - } va_end(va); return res; } -/* wcstring variant of contains_internal. The first parameter is a wcstring, the rest are const wchar_t *. vararg_handle exists only to give us a POD-value to pass to va_start */ -__sentinel bool contains_internal(const wcstring &needle, int vararg_handle, ...) -{ +/// wcstring variant of contains_internal. The first parameter is a wcstring, the rest are const +/// wchar_t *. vararg_handle exists only to give us a POD-value to pass to va_start. +__sentinel bool contains_internal(const wcstring &needle, int vararg_handle, ...) { const wchar_t *arg; va_list va; int res = 0; const wchar_t *needle_cstr = needle.c_str(); va_start(va, vararg_handle); - while ((arg=va_arg(va, const wchar_t *))!= 0) - { - /* libc++ has an unfortunate implementation of operator== that unconditonally wcslen's the wchar_t* parameter, so prefer wcscmp directly */ - if (! wcscmp(needle_cstr, arg)) - { - res=1; + while ((arg = va_arg(va, const wchar_t *)) != 0) { + // libc++ has an unfortunate implementation of operator== that unconditonally wcslen's the + // wchar_t* parameter, so prefer wcscmp directly. + if (!wcscmp(needle_cstr, arg)) { + res = 1; break; } - } va_end(va); return res; } -long read_blocked(int fd, void *buf, size_t count) -{ +long read_blocked(int fd, void *buf, size_t count) { ssize_t res; sigset_t chldset, oldset; @@ -603,60 +468,45 @@ long read_blocked(int fd, void *buf, size_t count) return res; } -ssize_t write_loop(int fd, const char *buff, size_t count) -{ - size_t out_cum=0; - while (out_cum < count) - { +ssize_t write_loop(int fd, const char *buff, size_t count) { + size_t out_cum = 0; + while (out_cum < count) { ssize_t out = write(fd, &buff[out_cum], count - out_cum); - if (out < 0) - { - if (errno != EAGAIN && errno != EINTR) - { + if (out < 0) { + if (errno != EAGAIN && errno != EINTR) { return -1; } - } - else - { + } else { out_cum += (size_t)out; } } return (ssize_t)out_cum; } -ssize_t read_loop(int fd, void *buff, size_t count) -{ +ssize_t read_loop(int fd, void *buff, size_t count) { ssize_t result; - do - { + do { result = read(fd, buff, count); - } - while (result < 0 && (errno == EAGAIN || errno == EINTR)); + } while (result < 0 && (errno == EAGAIN || errno == EINTR)); return result; } -static bool should_debug(int level) -{ - if (level > debug_level) - return false; +static bool should_debug(int level) { + if (level > debug_level) return false; - /* Hack to not print error messages in the tests */ - if (program_name && ! wcscmp(program_name, L"(ignore)")) - return false; + // Hack to not print error messages in the tests. + if (program_name && !wcscmp(program_name, L"(ignore)")) return false; return true; } -static void debug_shared(const wcstring &msg) -{ +static void debug_shared(const wcstring &msg) { const wcstring sb = wcstring(program_name) + L": " + msg; fwprintf(stderr, L"%ls", reformat_for_screen(sb).c_str()); } -void debug(int level, const wchar_t *msg, ...) -{ - if (! should_debug(level)) - return; +void debug(int level, const wchar_t *msg, ...) { + if (!should_debug(level)) return; int errno_old = errno; va_list va; va_start(va, msg); @@ -666,10 +516,8 @@ void debug(int level, const wchar_t *msg, ...) errno = errno_old; } -void debug(int level, const char *msg, ...) -{ - if (! should_debug(level)) - return; +void debug(int level, const char *msg, ...) { + if (!should_debug(level)) return; int errno_old = errno; char local_msg[512]; va_list va; @@ -680,95 +528,78 @@ void debug(int level, const char *msg, ...) errno = errno_old; } -void read_ignore(int fd, void *buff, size_t count) -{ +void read_ignore(int fd, void *buff, size_t count) { size_t ignore __attribute__((unused)); ignore = read(fd, buff, count); } -void write_ignore(int fd, const void *buff, size_t count) -{ +void write_ignore(int fd, const void *buff, size_t count) { size_t ignore __attribute__((unused)); ignore = write(fd, buff, count); } +void debug_safe(int level, const char *msg, const char *param1, const char *param2, + const char *param3, const char *param4, const char *param5, const char *param6, + const char *param7, const char *param8, const char *param9, const char *param10, + const char *param11, const char *param12) { + const char *const params[] = {param1, param2, param3, param4, param5, param6, + param7, param8, param9, param10, param11, param12}; + if (!msg) return; -void debug_safe(int level, const char *msg, const char *param1, const char *param2, const char *param3, const char *param4, const char *param5, const char *param6, const char *param7, const char *param8, const char *param9, const char *param10, const char *param11, const char *param12) -{ - const char * const params[] = {param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12}; - if (! msg) - return; - - /* Can't call printf, that may allocate memory Just call write() over and over. */ - if (level > debug_level) - return; + // Can't call printf, that may allocate memory Just call write() over and over. + if (level > debug_level) return; int errno_old = errno; size_t param_idx = 0; const char *cursor = msg; - while (*cursor != '\0') - { + while (*cursor != '\0') { const char *end = strchr(cursor, '%'); - if (end == NULL) - end = cursor + strlen(cursor); + if (end == NULL) end = cursor + strlen(cursor); write_ignore(STDERR_FILENO, cursor, end - cursor); - if (end[0] == '%' && end[1] == 's') - { - /* Handle a format string */ + if (end[0] == '%' && end[1] == 's') { + // Handle a format string. assert(param_idx < sizeof params / sizeof *params); const char *format = params[param_idx++]; - if (! format) - format = "(null)"; + if (!format) format = "(null)"; write_ignore(STDERR_FILENO, format, strlen(format)); cursor = end + 2; - } - else if (end[0] == '\0') - { - /* Must be at the end of the string */ + } else if (end[0] == '\0') { + // Must be at the end of the string. cursor = end; - } - else - { - /* Some other format specifier, just skip it */ + } else { + // Some other format specifier, just skip it. cursor = end + 1; } } - // We always append a newline + // We always append a newline. write_ignore(STDERR_FILENO, "\n", 1); errno = errno_old; } -void format_long_safe(char buff[64], long val) -{ - if (val == 0) - { +void format_long_safe(char buff[64], long val) { + if (val == 0) { strcpy(buff, "0"); - } - else - { - /* Generate the string in reverse */ + } else { + // Generate the string in reverse. size_t idx = 0; bool negative = (val < 0); - /* Note that we can't just negate val if it's negative, because it may be the most negative value. We do rely on round-towards-zero division though. */ - - while (val != 0) - { + // Note that we can't just negate val if it's negative, because it may be the most negative + // value. We do rely on round-towards-zero division though. + while (val != 0) { long rem = val % 10; buff[idx++] = '0' + (rem < 0 ? -rem : rem); val /= 10; } - if (negative) - buff[idx++] = '-'; + if (negative) buff[idx++] = '-'; buff[idx] = 0; size_t left = 0, right = idx - 1; - while (left < right) - { + while (left < right) { char tmp = buff[left]; buff[left++] = buff[right]; buff[right--] = tmp; @@ -776,31 +607,24 @@ void format_long_safe(char buff[64], long val) } } -void format_long_safe(wchar_t buff[64], long val) -{ - if (val == 0) - { +void format_long_safe(wchar_t buff[64], long val) { + if (val == 0) { wcscpy(buff, L"0"); - } - else - { - /* Generate the string in reverse */ + } else { + // Generate the string in reverse. size_t idx = 0; bool negative = (val < 0); - while (val != 0) - { + while (val != 0) { long rem = val % 10; buff[idx++] = L'0' + (wchar_t)(rem < 0 ? -rem : rem); val /= 10; } - if (negative) - buff[idx++] = L'-'; + if (negative) buff[idx++] = L'-'; buff[idx] = 0; size_t left = 0, right = idx - 1; - while (left < right) - { + while (left < right) { wchar_t tmp = buff[left]; buff[left++] = buff[right]; buff[right--] = tmp; @@ -808,17 +632,13 @@ void format_long_safe(wchar_t buff[64], long val) } } -void narrow_string_safe(char buff[64], const wchar_t *s) -{ +void narrow_string_safe(char buff[64], const wchar_t *s) { size_t idx = 0; - for (size_t widx = 0; s[widx] != L'\0'; widx++) - { + for (size_t widx = 0; s[widx] != L'\0'; widx++) { wchar_t c = s[widx]; - if (c <= 127) - { + if (c <= 127) { buff[idx++] = char(c); - if (idx + 1 == 64) - { + if (idx + 1 == 64) { break; } } @@ -826,34 +646,24 @@ void narrow_string_safe(char buff[64], const wchar_t *s) buff[idx] = '\0'; } -wcstring reformat_for_screen(const wcstring &msg) -{ +wcstring reformat_for_screen(const wcstring &msg) { wcstring buff; int line_width = 0; int screen_width = common_get_width(); - if (screen_width) - { + if (screen_width) { const wchar_t *start = msg.c_str(); const wchar_t *pos = start; - while (1) - { + while (1) { int overflow = 0; - int tok_width=0; + int tok_width = 0; - /* - Tokenize on whitespace, and also calculate the width of the token - */ - while (*pos && (!wcschr(L" \n\r\t", *pos))) - { - - /* - Check is token is wider than one line. - If so we mark it as an overflow and break the token. - */ - if ((tok_width + fish_wcwidth(*pos)) > (screen_width-1)) - { + // Tokenize on whitespace, and also calculate the width of the token. + while (*pos && (!wcschr(L" \n\r\t", *pos))) { + // Check is token is wider than one line. If so we mark it as an overflow and break + // the token. + if ((tok_width + fish_wcwidth(*pos)) > (screen_width - 1)) { overflow = 1; break; } @@ -862,163 +672,132 @@ wcstring reformat_for_screen(const wcstring &msg) pos++; } - /* - If token is zero character long, we don't do anything - */ - if (pos == start) - { - start = pos = pos+1; - } - else if (overflow) - { - /* - In case of overflow, we print a newline, except if we already are at position 0 - */ - wchar_t *token = wcsndup(start, pos-start); - if (line_width != 0) - buff.push_back(L'\n'); + // If token is zero character long, we don't do anything. + if (pos == start) { + start = pos = pos + 1; + } else if (overflow) { + // In case of overflow, we print a newline, except if we already are at position 0. + wchar_t *token = wcsndup(start, pos - start); + if (line_width != 0) buff.push_back(L'\n'); buff.append(format_string(L"%ls-\n", token)); free(token); - line_width=0; - } - else - { - /* - Print the token - */ - wchar_t *token = wcsndup(start, pos-start); - if ((line_width + (line_width!=0?1:0) + tok_width) > screen_width) - { + line_width = 0; + } else { + // Print the token. + wchar_t *token = wcsndup(start, pos - start); + if ((line_width + (line_width != 0 ? 1 : 0) + tok_width) > screen_width) { buff.push_back(L'\n'); - line_width=0; + line_width = 0; } - buff.append(format_string(L"%ls%ls", line_width?L" ":L"", token)); + buff.append(format_string(L"%ls%ls", line_width ? L" " : L"", token)); free(token); - line_width += (line_width!=0?1:0) + tok_width; + line_width += (line_width != 0 ? 1 : 0) + tok_width; } - /* - Break on end of string - */ - if (!*pos) - { + // Break on end of string. + if (!*pos) { break; } - start=pos; + start = pos; } - } - else - { + } else { buff.append(msg); } buff.push_back(L'\n'); return buff; } -/* Escape a string, storing the result in out_str */ -static void escape_string_internal(const wchar_t *orig_in, size_t in_len, wcstring *out_str, escape_flags_t flags) -{ +/// Escape a string, storing the result in out_str. +static void escape_string_internal(const wchar_t *orig_in, size_t in_len, wcstring *out_str, + escape_flags_t flags) { assert(orig_in != NULL); const wchar_t *in = orig_in; bool escape_all = !!(flags & ESCAPE_ALL); - bool no_quoted = !!(flags & ESCAPE_NO_QUOTED); + bool no_quoted = !!(flags & ESCAPE_NO_QUOTED); bool no_tilde = !!(flags & ESCAPE_NO_TILDE); - int need_escape=0; - int need_complex_escape=0; + int need_escape = 0; + int need_complex_escape = 0; - /* Avoid dereferencing all over the place */ + // Avoid dereferencing all over the place. wcstring &out = *out_str; - if (!no_quoted && in_len == 0) - { + if (!no_quoted && in_len == 0) { out.assign(L"''"); return; } - while (*in != 0) - { - - if ((*in >= ENCODE_DIRECT_BASE) && - (*in < ENCODE_DIRECT_BASE+256)) - { + while (*in != 0) { + if ((*in >= ENCODE_DIRECT_BASE) && (*in < ENCODE_DIRECT_BASE + 256)) { int val = *in - ENCODE_DIRECT_BASE; int tmp; out += L'\\'; out += L'X'; - tmp = val/16; - out += tmp > 9? L'a'+(tmp-10):L'0'+tmp; + tmp = val / 16; + out += tmp > 9 ? L'a' + (tmp - 10) : L'0' + tmp; - tmp = val%16; - out += tmp > 9? L'a'+(tmp-10):L'0'+tmp; - need_escape=need_complex_escape=1; + tmp = val % 16; + out += tmp > 9 ? L'a' + (tmp - 10) : L'0' + tmp; + need_escape = need_complex_escape = 1; - } - else - { + } else { wchar_t c = *in; - switch (c) - { - case L'\t': + switch (c) { + case L'\t': { out += L'\\'; out += L't'; - need_escape=need_complex_escape=1; + need_escape = need_complex_escape = 1; break; - - case L'\n': + } + case L'\n': { out += L'\\'; out += L'n'; - need_escape=need_complex_escape=1; + need_escape = need_complex_escape = 1; break; - - case L'\b': + } + case L'\b': { out += L'\\'; out += L'b'; - need_escape=need_complex_escape=1; + need_escape = need_complex_escape = 1; break; - - case L'\r': + } + case L'\r': { out += L'\\'; out += L'r'; - need_escape=need_complex_escape=1; + need_escape = need_complex_escape = 1; break; - - case L'\x1b': + } + case L'\x1b': { out += L'\\'; out += L'e'; - need_escape=need_complex_escape=1; + need_escape = need_complex_escape = 1; break; - - + } case L'\\': - case L'\'': - { - need_escape=need_complex_escape=1; - if (escape_all) - out += L'\\'; + case L'\'': { + need_escape = need_complex_escape = 1; + if (escape_all) out += L'\\'; out += *in; break; } - - - // Experimental fix for #1614 - // The hope is that any time these appear in a string, they came from wildcard expansion - case ANY_CHAR: + case ANY_CHAR: { + // Experimental fix for #1614. The hope is that any time these appear in a + // string, they came from wildcard expansion. out += L'?'; break; - - case ANY_STRING: + } + case ANY_STRING: { out += L'*'; break; - - case ANY_STRING_RECURSIVE: + } + case ANY_STRING_RECURSIVE: { out += L"**"; break; - + } case L'&': case L'$': case L' ': @@ -1038,43 +817,33 @@ static void escape_string_internal(const wchar_t *orig_in, size_t in_len, wcstri case L';': case L'"': case L'%': - case L'~': - { - if (! no_tilde || c != L'~') - { - need_escape=1; - if (escape_all) - out += L'\\'; + case L'~': { + if (!no_tilde || c != L'~') { + need_escape = 1; + if (escape_all) out += L'\\'; } out += *in; break; } - default: - { - if (*in < 32) - { - if (*in <27 && *in > 0) - { + default: { + if (*in < 32) { + if (*in < 27 && *in > 0) { out += L'\\'; out += L'c'; - out += L'a' + *in -1; + out += L'a' + *in - 1; - need_escape=need_complex_escape=1; + need_escape = need_complex_escape = 1; break; - } - - int tmp = (*in)%16; + int tmp = (*in) % 16; out += L'\\'; out += L'x'; - out += ((*in>15)? L'1' : L'0'); - out += tmp > 9? L'a'+(tmp-10):L'0'+tmp; - need_escape=need_complex_escape=1; - } - else - { + out += ((*in > 15) ? L'1' : L'0'); + out += tmp > 9 ? L'a' + (tmp - 10) : L'0' + tmp; + need_escape = need_complex_escape = 1; + } else { out += *in; } break; @@ -1085,12 +854,8 @@ static void escape_string_internal(const wchar_t *orig_in, size_t in_len, wcstri in++; } - /* - Use quoted escaping if possible, since most people find it - easier to read. - */ - if (!no_quoted && need_escape && !need_complex_escape && escape_all) - { + // Use quoted escaping if possible, since most people find it easier to read. + if (!no_quoted && need_escape && !need_complex_escape && escape_all) { wchar_t single_quote = L'\''; out.clear(); out.reserve(2 + in_len); @@ -1100,59 +865,52 @@ static void escape_string_internal(const wchar_t *orig_in, size_t in_len, wcstri } } -wcstring escape(const wchar_t *in, escape_flags_t flags) -{ +wcstring escape(const wchar_t *in, escape_flags_t flags) { wcstring result; escape_string_internal(in, wcslen(in), &result, flags); return result; } -wcstring escape_string(const wcstring &in, escape_flags_t flags) -{ +wcstring escape_string(const wcstring &in, escape_flags_t flags) { wcstring result; escape_string_internal(in.c_str(), in.size(), &result, flags); return result; } -/* Helper to return the last character in a string, or NOT_A_WCHAR */ -static wint_t string_last_char(const wcstring &str) -{ +/// Helper to return the last character in a string, or NOT_A_WCHAR. +static wint_t string_last_char(const wcstring &str) { size_t len = str.size(); return len == 0 ? NOT_A_WCHAR : str.at(len - 1); } -/* Given a null terminated string starting with a backslash, read the escape as if it is unquoted, appending to result. Return the number of characters consumed, or 0 on error */ -size_t read_unquoted_escape(const wchar_t *input, wcstring *result, bool allow_incomplete, bool unescape_special) -{ - if (input[0] != L'\\') - { - // not an escape - return 0; +/// Given a null terminated string starting with a backslash, read the escape as if it is unquoted, +/// appending to result. Return the number of characters consumed, or 0 on error. +size_t read_unquoted_escape(const wchar_t *input, wcstring *result, bool allow_incomplete, + bool unescape_special) { + if (input[0] != L'\\') { + return 0; // not an escape } - /* Here's the character we'll ultimately append, or NOT_A_WCHAR for none. Note that L'\0' is a valid thing to append. */ + // Here's the character we'll ultimately append, or NOT_A_WCHAR for none. Note that L'\0' is a + // valid thing to append. wint_t result_char_or_none = NOT_A_WCHAR; bool errored = false; - size_t in_pos = 1; //in_pos always tracks the next character to read (and therefore the number of characters read so far) + size_t in_pos = 1; // in_pos always tracks the next character to read (and therefore the number + // of characters read so far) const wchar_t c = input[in_pos++]; - switch (c) - { - - /* A null character after a backslash is an error */ - case L'\0': - { - /* Adjust in_pos to only include the backslash */ + switch (c) { + // A null character after a backslash is an error. + case L'\0': { + // Adjust in_pos to only include the backslash. assert(in_pos > 0); in_pos--; - /* It's an error, unless we're allowing incomplete escapes */ - if (! allow_incomplete) - errored = true; + // It's an error, unless we're allowing incomplete escapes. + if (!allow_incomplete) errored = true; break; } - - /* Numeric escape sequences. No prefix means octal escape, otherwise hexadecimal. */ + // Numeric escape sequences. No prefix means octal escape, otherwise hexadecimal. case L'0': case L'1': case L'2': @@ -1164,200 +922,144 @@ size_t read_unquoted_escape(const wchar_t *input, wcstring *result, bool allow_i case L'u': case L'U': case L'x': - case L'X': - { - long long res=0; - size_t chars=2; - int base=16; - + case L'X': { + long long res = 0; + size_t chars = 2; + int base = 16; bool byte_literal = false; wchar_t max_val = ASCII_MAX; - switch (c) - { - case L'u': - { - chars=4; + switch (c) { + case L'u': { + chars = 4; max_val = UCS2_MAX; break; } - - case L'U': - { - chars=8; + case L'U': { + chars = 8; max_val = WCHAR_MAX; - // Don't exceed the largest Unicode code point - see #1107 - if (0x10FFFF < max_val) - max_val = (wchar_t)0x10FFFF; - + // Don't exceed the largest Unicode code point - see #1107. + if (0x10FFFF < max_val) max_val = (wchar_t)0x10FFFF; break; } - - case L'x': - { + case L'x': { chars = 2; max_val = ASCII_MAX; break; } - - case L'X': - { + case L'X': { byte_literal = true; max_val = BYTE_MAX; break; } - - default: - { - base=8; - chars=3; - // note that in_pos currently is just after the first post-backslash character; we want to start our escape from there + default: { + base = 8; + chars = 3; + // Note that in_pos currently is just after the first post-backslash character; + // we want to start our escape from there. assert(in_pos > 0); in_pos--; break; } } - for (size_t i=0; i= L'a' && sequence_char <= (L'a'+32)) - { - result_char_or_none = sequence_char-L'a'+1; - } - else if (sequence_char >= L'A' && sequence_char <= (L'A'+32)) - { - result_char_or_none = sequence_char-L'A'+1; - } - else - { + if (sequence_char >= L'a' && sequence_char <= (L'a' + 32)) { + result_char_or_none = sequence_char - L'a' + 1; + } else if (sequence_char >= L'A' && sequence_char <= (L'A' + 32)) { + result_char_or_none = sequence_char - L'A' + 1; + } else { errored = true; } break; } - - /* \x1b means escape */ - case L'e': - { + // \x1b means escape. + case L'e': { result_char_or_none = L'\x1b'; break; } - - /* - \f means form feed - */ - case L'f': - { + // \f means form feed. + case L'f': { result_char_or_none = L'\f'; break; } - - /* - \n means newline - */ - case L'n': - { + // \n means newline. + case L'n': { result_char_or_none = L'\n'; break; } - - /* - \r means carriage return - */ - case L'r': - { + // \r means carriage return. + case L'r': { result_char_or_none = L'\r'; break; } - - /* - \t means tab - */ - case L't': - { + // \t means tab. + case L't': { result_char_or_none = L'\t'; break; } - - /* - \v means vertical tab - */ - case L'v': - { + // \v means vertical tab. + case L'v': { result_char_or_none = L'\v'; break; } - - /* If a backslash is followed by an actual newline, swallow them both */ - case L'\n': - { + // If a backslash is followed by an actual newline, swallow them both. + case L'\n': { result_char_or_none = NOT_A_WCHAR; break; } - - default: - { - if (unescape_special) - result->push_back(INTERNAL_SEPARATOR); + default: { + if (unescape_special) result->push_back(INTERNAL_SEPARATOR); result_char_or_none = c; break; } } - if (! errored && result_char_or_none != NOT_A_WCHAR) - { + if (!errored && result_char_or_none != NOT_A_WCHAR) { wchar_t result_char = static_cast(result_char_or_none); - // if result_char is not NOT_A_WCHAR, it must be a valid wchar + // If result_char is not NOT_A_WCHAR, it must be a valid wchar. assert((wint_t)result_char == result_char_or_none); result->push_back(result_char); } return errored ? 0 : in_pos; } -/* Returns the unescaped version of input_str into output_str (by reference). Returns true if successful. If false, the contents of output_str are undefined (!) */ -static bool unescape_string_internal(const wchar_t * const input, const size_t input_len, wcstring *output_str, unescape_flags_t flags) -{ - /* Set up result string, which we'll swap with the output on success */ +/// Returns the unescaped version of input_str into output_str (by reference). Returns true if +/// successful. If false, the contents of output_str are undefined (!). +static bool unescape_string_internal(const wchar_t *const input, const size_t input_len, + wcstring *output_str, unescape_flags_t flags) { + // Set up result string, which we'll swap with the output on success. wcstring result; result.reserve(input_len); @@ -1367,310 +1069,228 @@ static bool unescape_string_internal(const wchar_t * const input, const size_t i int bracket_count = 0; bool errored = false; - enum - { - mode_unquoted, - mode_single_quotes, - mode_double_quotes - } mode = mode_unquoted; + enum { mode_unquoted, mode_single_quotes, mode_double_quotes } mode = mode_unquoted; - for (size_t input_position = 0; input_position < input_len && ! errored; input_position++) - { + for (size_t input_position = 0; input_position < input_len && !errored; input_position++) { const wchar_t c = input[input_position]; - /* Here's the character we'll append to result, or NOT_A_WCHAR to suppress it */ + // Here's the character we'll append to result, or NOT_A_WCHAR to suppress it. wint_t to_append_or_none = c; - if (mode == mode_unquoted) - { - - switch (c) - { - case L'\\': - { - /* Backslashes (escapes) are complicated and may result in errors, or appending INTERNAL_SEPARATORs, so we have to handle them specially */ - size_t escape_chars = read_unquoted_escape(input + input_position, &result, allow_incomplete, unescape_special); - if (escape_chars == 0) - { - /* A 0 return indicates an error */ + if (mode == mode_unquoted) { + switch (c) { + case L'\\': { + // Backslashes (escapes) are complicated and may result in errors, or appending + // INTERNAL_SEPARATORs, so we have to handle them specially. + size_t escape_chars = read_unquoted_escape(input + input_position, &result, + allow_incomplete, unescape_special); + if (escape_chars == 0) { + // A 0 return indicates an error. errored = true; - } - else - { - /* Skip over the characters we read, minus one because the outer loop will increment it */ + } else { + // Skip over the characters we read, minus one because the outer loop will + // increment it. assert(escape_chars > 0); input_position += escape_chars - 1; } - /* We've already appended, don't append anything else */ + // We've already appended, don't append anything else. to_append_or_none = NOT_A_WCHAR; break; } - - case L'~': - { - if (unescape_special && (input_position == 0)) - { + case L'~': { + if (unescape_special && (input_position == 0)) { to_append_or_none = HOME_DIRECTORY; } break; } - - case L'%': - { - if (unescape_special && (input_position == 0)) - { + case L'%': { + if (unescape_special && (input_position == 0)) { to_append_or_none = PROCESS_EXPAND; } break; } - - case L'*': - { - if (unescape_special) - { - /* In general, this is ANY_STRING. But as a hack, if the last appended char is ANY_STRING, delete the last char and store ANY_STRING_RECURSIVE to reflect the fact that ** is the recursive wildcard. */ - if (string_last_char(result) == ANY_STRING) - { + case L'*': { + if (unescape_special) { + // In general, this is ANY_STRING. But as a hack, if the last appended char + // is ANY_STRING, delete the last char and store ANY_STRING_RECURSIVE to + // reflect the fact that ** is the recursive wildcard. + if (string_last_char(result) == ANY_STRING) { assert(result.size() > 0); result.resize(result.size() - 1); to_append_or_none = ANY_STRING_RECURSIVE; - } - else - { + } else { to_append_or_none = ANY_STRING; } } break; } - - case L'?': - { - if (unescape_special) - { + case L'?': { + if (unescape_special) { to_append_or_none = ANY_CHAR; } break; } - - case L'$': - { - if (unescape_special) - { + case L'$': { + if (unescape_special) { to_append_or_none = VARIABLE_EXPAND; } break; } - - case L'{': - { - if (unescape_special) - { + case L'{': { + if (unescape_special) { bracket_count++; to_append_or_none = BRACKET_BEGIN; } break; } - - case L'}': - { - if (unescape_special) - { + case L'}': { + if (unescape_special) { bracket_count--; to_append_or_none = BRACKET_END; } break; } - - case L',': - { - /* If the last character was a separator, then treat this as a literal comma */ - if (unescape_special && bracket_count > 0 && string_last_char(result) != BRACKET_SEP) - { + case L',': { + // If the last character was a separator, then treat this as a literal comma. + if (unescape_special && bracket_count > 0 && + string_last_char(result) != BRACKET_SEP) { to_append_or_none = BRACKET_SEP; } break; } - - case L'\'': - { + case L'\'': { mode = mode_single_quotes; to_append_or_none = unescape_special ? INTERNAL_SEPARATOR : NOT_A_WCHAR; break; } - - case L'\"': - { + case L'\"': { mode = mode_double_quotes; to_append_or_none = unescape_special ? INTERNAL_SEPARATOR : NOT_A_WCHAR; break; } } - } - else if (mode == mode_single_quotes) - { - if (c == L'\\') - { - /* A backslash may or may not escape something in single quotes */ - switch (input[input_position + 1]) - { + } else if (mode == mode_single_quotes) { + if (c == L'\\') { + // A backslash may or may not escape something in single quotes. + switch (input[input_position + 1]) { case '\\': - case L'\'': - { + case L'\'': { to_append_or_none = input[input_position + 1]; - input_position += 1; /* Skip over the backslash */ + input_position += 1; // skip over the backslash break; } - - case L'\0': - { - if (!allow_incomplete) - { + case L'\0': { + if (!allow_incomplete) { errored = true; - } - else - { - // PCA this line had the following cryptic comment: - // 'We may ever escape a NULL character, but still appending a \ in case I am wrong.' - // Not sure what it means or the importance of this + } else { + // PCA this line had the following cryptic comment: 'We may ever escape + // a NULL character, but still appending a \ in case I am wrong.' Not + // sure what it means or the importance of this. input_position += 1; /* Skip over the backslash */ to_append_or_none = L'\\'; } + break; } - break; - - default: - { - /* Literal backslash that doesn't escape anything! Leave things alone; we'll append the backslash itself */ + default: { + // Literal backslash that doesn't escape anything! Leave things alone; we'll + // append the backslash itself. break; } } - } - else if (c == L'\'') - { + } else if (c == L'\'') { to_append_or_none = unescape_special ? INTERNAL_SEPARATOR : NOT_A_WCHAR; mode = mode_unquoted; } - } - else if (mode == mode_double_quotes) - { - switch (c) - { - case L'"': - { + } else if (mode == mode_double_quotes) { + switch (c) { + case L'"': { mode = mode_unquoted; to_append_or_none = unescape_special ? INTERNAL_SEPARATOR : NOT_A_WCHAR; break; } - - case '\\': - { - switch (input[input_position + 1]) - { - case L'\0': - { - if (!allow_incomplete) - { + case '\\': { + switch (input[input_position + 1]) { + case L'\0': { + if (!allow_incomplete) { errored = true; - } - else - { + } else { to_append_or_none = L'\0'; } + break; } - break; - case '\\': case L'$': - case '"': - { + case '"': { to_append_or_none = input[input_position + 1]; input_position += 1; /* Skip over the backslash */ break; } - - case '\n': - { + case '\n': { /* Swallow newline */ to_append_or_none = NOT_A_WCHAR; input_position += 1; /* Skip over the backslash */ break; } - - default: - { - /* Literal backslash that doesn't escape anything! Leave things alone; we'll append the backslash itself */ + default: { + /* Literal backslash that doesn't escape anything! Leave things alone; + * we'll append the backslash itself */ break; } } break; } - - case '$': - { - if (unescape_special) - { + case '$': { + if (unescape_special) { to_append_or_none = VARIABLE_EXPAND_SINGLE; } break; } - } } - /* Now maybe append the char */ - if (to_append_or_none != NOT_A_WCHAR) - { + // Now maybe append the char. + if (to_append_or_none != NOT_A_WCHAR) { wchar_t to_append_char = static_cast(to_append_or_none); - // if result_char is not NOT_A_WCHAR, it must be a valid wchar + // If result_char is not NOT_A_WCHAR, it must be a valid wchar. assert((wint_t)to_append_char == to_append_or_none); result.push_back(to_append_char); } } - /* Return the string by reference, and then success */ - if (! errored) - { + // Return the string by reference, and then success. + if (!errored) { output_str->swap(result); } - return ! errored; + return !errored; } -bool unescape_string_in_place(wcstring *str, unescape_flags_t escape_special) -{ +bool unescape_string_in_place(wcstring *str, unescape_flags_t escape_special) { assert(str != NULL); wcstring output; bool success = unescape_string_internal(str->c_str(), str->size(), &output, escape_special); - if (success) - { + if (success) { str->swap(output); } return success; } -bool unescape_string(const wchar_t *input, wcstring *output, unescape_flags_t escape_special) -{ +bool unescape_string(const wchar_t *input, wcstring *output, unescape_flags_t escape_special) { bool success = unescape_string_internal(input, wcslen(input), output, escape_special); - if (! success) - output->clear(); + if (!success) output->clear(); return success; } -bool unescape_string(const wcstring &input, wcstring *output, unescape_flags_t escape_special) -{ +bool unescape_string(const wcstring &input, wcstring *output, unescape_flags_t escape_special) { bool success = unescape_string_internal(input.c_str(), input.size(), output, escape_special); - if (! success) - output->clear(); + if (!success) output->clear(); return success; } - -void common_handle_winch(int signal) -{ - /* don't run ioctl() here, it's not safe to use in signals */ +void common_handle_winch(int signal) { + // Don't run ioctl() here, it's not safe to use in signals. termsize_valid = false; } -/* updates termsize as needed, and returns a copy of the winsize. */ -static struct winsize get_current_winsize() -{ +/// Updates termsize as needed, and returns a copy of the winsize. +static struct winsize get_current_winsize() { #ifndef HAVE_WINSIZE struct winsize retval = {0}; retval.ws_col = 80; @@ -1679,11 +1299,9 @@ static struct winsize get_current_winsize() #endif scoped_rwlock guard(termsize_rwlock, true); struct winsize retval = termsize; - if (!termsize_valid) - { + if (!termsize_valid) { struct winsize size; - if (ioctl(1,TIOCGWINSZ,&size) == 0) - { + if (ioctl(1, TIOCGWINSZ, &size) == 0) { retval = size; guard.upgrade(); termsize = retval; @@ -1693,277 +1311,210 @@ static struct winsize get_current_winsize() return retval; } -int common_get_width() -{ - return get_current_winsize().ws_col; -} +int common_get_width() { return get_current_winsize().ws_col; } +int common_get_height() { return get_current_winsize().ws_row; } -int common_get_height() -{ - return get_current_winsize().ws_row; -} - -void tokenize_variable_array(const wcstring &val, std::vector &out) -{ +void tokenize_variable_array(const wcstring &val, std::vector &out) { size_t pos = 0, end = val.size(); - while (pos <= end) - { + while (pos <= end) { size_t next_pos = val.find(ARRAY_SEP, pos); - if (next_pos == wcstring::npos) - { + if (next_pos == wcstring::npos) { next_pos = end; } out.resize(out.size() + 1); out.back().assign(val, pos, next_pos - pos); - pos = next_pos + 1; //skip the separator, or skip past the end + pos = next_pos + 1; // skip the separator, or skip past the end } } -bool string_prefixes_string(const wchar_t *proposed_prefix, const wcstring &value) -{ +bool string_prefixes_string(const wchar_t *proposed_prefix, const wcstring &value) { size_t prefix_size = wcslen(proposed_prefix); return prefix_size <= value.size() && value.compare(0, prefix_size, proposed_prefix) == 0; } -bool string_prefixes_string(const wcstring &proposed_prefix, const wcstring &value) -{ +bool string_prefixes_string(const wcstring &proposed_prefix, const wcstring &value) { size_t prefix_size = proposed_prefix.size(); return prefix_size <= value.size() && value.compare(0, prefix_size, proposed_prefix) == 0; } -bool string_prefixes_string_case_insensitive(const wcstring &proposed_prefix, const wcstring &value) -{ +bool string_prefixes_string_case_insensitive(const wcstring &proposed_prefix, + const wcstring &value) { size_t prefix_size = proposed_prefix.size(); - return prefix_size <= value.size() && wcsncasecmp(proposed_prefix.c_str(), value.c_str(), prefix_size) == 0; + return prefix_size <= value.size() && + wcsncasecmp(proposed_prefix.c_str(), value.c_str(), prefix_size) == 0; } -bool string_suffixes_string(const wcstring &proposed_suffix, const wcstring &value) -{ +bool string_suffixes_string(const wcstring &proposed_suffix, const wcstring &value) { size_t suffix_size = proposed_suffix.size(); - return suffix_size <= value.size() && value.compare(value.size() - suffix_size, suffix_size, proposed_suffix) == 0; + return suffix_size <= value.size() && + value.compare(value.size() - suffix_size, suffix_size, proposed_suffix) == 0; } -bool string_suffixes_string(const wchar_t *proposed_suffix, const wcstring &value) -{ +bool string_suffixes_string(const wchar_t *proposed_suffix, const wcstring &value) { size_t suffix_size = wcslen(proposed_suffix); - return suffix_size <= value.size() && value.compare(value.size() - suffix_size, suffix_size, proposed_suffix) == 0; + return suffix_size <= value.size() && + value.compare(value.size() - suffix_size, suffix_size, proposed_suffix) == 0; } -// Returns true if seq, represented as a subsequence, is contained within string -static bool subsequence_in_string(const wcstring &seq, const wcstring &str) -{ - /* Impossible if seq is larger than string */ - if (seq.size() > str.size()) - { +/// Returns true if seq, represented as a subsequence, is contained within string. +static bool subsequence_in_string(const wcstring &seq, const wcstring &str) { + // Impossible if seq is larger than string. + if (seq.size() > str.size()) { return false; } - /* Empty strings are considered to be subsequences of everything */ - if (seq.empty()) - { + // Empty strings are considered to be subsequences of everything. + if (seq.empty()) { return true; } size_t str_idx, seq_idx; - for (seq_idx = str_idx = 0; seq_idx < seq.size() && str_idx < str.size(); seq_idx++) - { + for (seq_idx = str_idx = 0; seq_idx < seq.size() && str_idx < str.size(); seq_idx++) { wchar_t c = seq.at(seq_idx); size_t char_loc = str.find(c, str_idx); - if (char_loc == wcstring::npos) - { - /* Didn't find this character */ - break; - } - else - { - /* We found it. Continue the search just after it. */ - str_idx = char_loc + 1; + if (char_loc == wcstring::npos) { + break; // didn't find this character + } else { + str_idx = char_loc + 1; // we found it, continue the search just after it } } - /* We succeeded if we exhausted our sequence */ + // We succeeded if we exhausted our sequence. assert(seq_idx <= seq.size()); return seq_idx == seq.size(); } -string_fuzzy_match_t::string_fuzzy_match_t(enum fuzzy_match_type_t t, size_t distance_first, size_t distance_second) : - type(t), - match_distance_first(distance_first), - match_distance_second(distance_second) -{ -} +string_fuzzy_match_t::string_fuzzy_match_t(enum fuzzy_match_type_t t, size_t distance_first, + size_t distance_second) + : type(t), match_distance_first(distance_first), match_distance_second(distance_second) {} - -string_fuzzy_match_t string_fuzzy_match_string(const wcstring &string, const wcstring &match_against, fuzzy_match_type_t limit_type) -{ - // Distances are generally the amount of text not matched +string_fuzzy_match_t string_fuzzy_match_string(const wcstring &string, + const wcstring &match_against, + fuzzy_match_type_t limit_type) { + // Distances are generally the amount of text not matched. string_fuzzy_match_t result(fuzzy_match_none, 0, 0); size_t location; - if (limit_type >= fuzzy_match_exact && string == match_against) - { + if (limit_type >= fuzzy_match_exact && string == match_against) { result.type = fuzzy_match_exact; - } - else if (limit_type >= fuzzy_match_prefix && string_prefixes_string(string, match_against)) - { + } else if (limit_type >= fuzzy_match_prefix && string_prefixes_string(string, match_against)) { result.type = fuzzy_match_prefix; assert(match_against.size() >= string.size()); result.match_distance_first = match_against.size() - string.size(); - } - else if (limit_type >= fuzzy_match_case_insensitive && wcscasecmp(string.c_str(), match_against.c_str()) == 0) - { + } else if (limit_type >= fuzzy_match_case_insensitive && + wcscasecmp(string.c_str(), match_against.c_str()) == 0) { result.type = fuzzy_match_case_insensitive; - } - else if (limit_type >= fuzzy_match_prefix_case_insensitive && string_prefixes_string_case_insensitive(string, match_against)) - { + } else if (limit_type >= fuzzy_match_prefix_case_insensitive && + string_prefixes_string_case_insensitive(string, match_against)) { result.type = fuzzy_match_prefix_case_insensitive; assert(match_against.size() >= string.size()); result.match_distance_first = match_against.size() - string.size(); - } - else if (limit_type >= fuzzy_match_substring && (location = match_against.find(string)) != wcstring::npos) - { - // string is contained within match against + } else if (limit_type >= fuzzy_match_substring && + (location = match_against.find(string)) != wcstring::npos) { + // String is contained within match against. result.type = fuzzy_match_substring; assert(match_against.size() >= string.size()); result.match_distance_first = match_against.size() - string.size(); - result.match_distance_second = location; //prefer earlier matches - } - else if (limit_type >= fuzzy_match_subsequence_insertions_only && subsequence_in_string(string, match_against)) - { + result.match_distance_second = location; // prefer earlier matches + } else if (limit_type >= fuzzy_match_subsequence_insertions_only && + subsequence_in_string(string, match_against)) { result.type = fuzzy_match_subsequence_insertions_only; assert(match_against.size() >= string.size()); result.match_distance_first = match_against.size() - string.size(); - // it would be nice to prefer matches with greater matching runs here + // It would be nice to prefer matches with greater matching runs here. } return result; } -template -static inline int compare_ints(T a, T b) -{ +template +static inline int compare_ints(T a, T b) { if (a < b) return -1; if (a == b) return 0; return 1; } -// Compare types; if the types match, compare distances -int string_fuzzy_match_t::compare(const string_fuzzy_match_t &rhs) const -{ - if (this->type != rhs.type) - { +/// Compare types; if the types match, compare distances. +int string_fuzzy_match_t::compare(const string_fuzzy_match_t &rhs) const { + if (this->type != rhs.type) { return compare_ints(this->type, rhs.type); - } - else if (this->match_distance_first != rhs.match_distance_first) - { + } else if (this->match_distance_first != rhs.match_distance_first) { return compare_ints(this->match_distance_first, rhs.match_distance_first); - } - else if (this->match_distance_second != rhs.match_distance_second) - { + } else if (this->match_distance_second != rhs.match_distance_second) { return compare_ints(this->match_distance_second, rhs.match_distance_second); } - return 0; //equal + return 0; // equal } -bool list_contains_string(const wcstring_list_t &list, const wcstring &str) -{ +bool list_contains_string(const wcstring_list_t &list, const wcstring &str) { return std::find(list.begin(), list.end(), str) != list.end(); } -int create_directory(const wcstring &d) -{ +int create_directory(const wcstring &d) { int ok = 0; struct stat buf; int stat_res = 0; - while ((stat_res = wstat(d, &buf)) != 0) - { - if (errno != EAGAIN) - break; + while ((stat_res = wstat(d, &buf)) != 0) { + if (errno != EAGAIN) break; } - if (stat_res == 0) - { - if (S_ISDIR(buf.st_mode)) - { + if (stat_res == 0) { + if (S_ISDIR(buf.st_mode)) { ok = 1; } - } - else - { - if (errno == ENOENT) - { + } else { + if (errno == ENOENT) { wcstring dir = wdirname(d); - if (!create_directory(dir)) - { - if (!wmkdir(d, 0700)) - { + if (!create_directory(dir)) { + if (!wmkdir(d, 0700)) { ok = 1; } } } } - return ok?0:-1; + return ok ? 0 : -1; } -__attribute__((noinline)) -void bugreport() -{ - debug(1, - _(L"This is a bug. Break on bugreport to debug." - L"If you can reproduce it, please send a bug report to %s."), +__attribute__((noinline)) void bugreport() { + debug(1, _(L"This is a bug. Break on bugreport to debug." + L"If you can reproduce it, please send a bug report to %s."), PACKAGE_BUGREPORT); } -wcstring format_size(long long sz) -{ +wcstring format_size(long long sz) { wcstring result; - const wchar_t *sz_name[]= - { - L"kB", L"MB", L"GB", L"TB", L"PB", L"EB", L"ZB", L"YB", 0 - }; + const wchar_t *sz_name[] = {L"kB", L"MB", L"GB", L"TB", L"PB", L"EB", L"ZB", L"YB", 0}; - if (sz < 0) - { + if (sz < 0) { result.append(L"unknown"); - } - else if (sz < 1) - { + } else if (sz < 1) { result.append(_(L"empty")); - } - else if (sz < 1024) - { + } else if (sz < 1024) { result.append(format_string(L"%lldB", sz)); - } - else - { + } else { int i; - for (i=0; sz_name[i]; i++) - { - if (sz < (1024*1024) || !sz_name[i+1]) - { - long isz = ((long)sz)/1024; + for (i = 0; sz_name[i]; i++) { + if (sz < (1024 * 1024) || !sz_name[i + 1]) { + long isz = ((long)sz) / 1024; if (isz > 9) result.append(format_string(L"%d%ls", isz, sz_name[i])); else - result.append(format_string(L"%.1f%ls", (double)sz/1024, sz_name[i])); + result.append(format_string(L"%.1f%ls", (double)sz / 1024, sz_name[i])); break; } sz /= 1024; - } } return result; } -/* Crappy function to extract the most significant digit of an unsigned long long value */ -static char extract_most_significant_digit(unsigned long long *xp) -{ +/// Crappy function to extract the most significant digit of an unsigned long long value. +static char extract_most_significant_digit(unsigned long long *xp) { unsigned long long place_value = 1; unsigned long long x = *xp; - while (x >= 10) - { + while (x >= 10) { x /= 10; place_value *= 10; } @@ -1971,67 +1522,45 @@ static char extract_most_significant_digit(unsigned long long *xp) return x + '0'; } -void append_ull(char *buff, unsigned long long val, size_t *inout_idx, size_t max_len) -{ +void append_ull(char *buff, unsigned long long val, size_t *inout_idx, size_t max_len) { size_t idx = *inout_idx; - while (val > 0 && idx < max_len) - buff[idx++] = extract_most_significant_digit(&val); + while (val > 0 && idx < max_len) buff[idx++] = extract_most_significant_digit(&val); *inout_idx = idx; } -void append_str(char *buff, const char *str, size_t *inout_idx, size_t max_len) -{ +void append_str(char *buff, const char *str, size_t *inout_idx, size_t max_len) { size_t idx = *inout_idx; - while (*str && idx < max_len) - buff[idx++] = *str++; + while (*str && idx < max_len) buff[idx++] = *str++; *inout_idx = idx; } -void format_size_safe(char buff[128], unsigned long long sz) -{ +void format_size_safe(char buff[128], unsigned long long sz) { const size_t buff_size = 128; - const size_t max_len = buff_size - 1; //need to leave room for a null terminator + const size_t max_len = buff_size - 1; // need to leave room for a null terminator memset(buff, 0, buff_size); size_t idx = 0; - const char * const sz_name[]= - { - "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB", NULL - }; - if (sz < 1) - { + const char *const sz_name[] = {"kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB", NULL}; + if (sz < 1) { strncpy(buff, "empty", buff_size); - } - else if (sz < 1024) - { + } else if (sz < 1024) { append_ull(buff, sz, &idx, max_len); append_str(buff, "B", &idx, max_len); - } - else - { - for (size_t i=0; sz_name[i]; i++) - { - if (sz < (1024*1024) || !sz_name[i+1]) - { - unsigned long long isz = sz/1024; - if (isz > 9) - { + } else { + for (size_t i = 0; sz_name[i]; i++) { + if (sz < (1024 * 1024) || !sz_name[i + 1]) { + unsigned long long isz = sz / 1024; + if (isz > 9) { append_ull(buff, isz, &idx, max_len); - } - else - { - if (isz == 0) - { + } else { + if (isz == 0) { append_str(buff, "0", &idx, max_len); - } - else - { + } else { append_ull(buff, isz, &idx, max_len); } - // Maybe append a single fraction digit + // Maybe append a single fraction digit. unsigned long long remainder = sz % 1024; - if (remainder > 0) - { + if (remainder > 0) { char tmp[3] = {'.', extract_most_significant_digit(&remainder), 0}; append_str(buff, tmp, &idx, max_len); } @@ -2044,70 +1573,52 @@ void format_size_safe(char buff[128], unsigned long long sz) } } -double timef() -{ - int time_res; +double timef() { struct timeval tv; + int time_res = gettimeofday(&tv, 0); - time_res = gettimeofday(&tv, 0); - - if (time_res) - { - /* - Fixme: What on earth is the correct parameter value for NaN? - The man pages and the standard helpfully state that this - parameter is implementation defined. Gcc gives a warning if - a null pointer is used. But not even all mighty Google gives - a hint to what value should actually be returned. - */ + if (time_res) { + // Fixme: What on earth is the correct parameter value for NaN? The man pages and the + // standard helpfully state that this parameter is implementation defined. Gcc gives a + // warning if a null pointer is used. But not even all mighty Google gives a hint to what + // value should actually be returned. return nan(""); } - return (double)tv.tv_sec + 0.000001*tv.tv_usec; + return (double)tv.tv_sec + 0.000001 * tv.tv_usec; } -void exit_without_destructors(int code) -{ - _exit(code); -} +void exit_without_destructors(int code) { _exit(code); } -/* Helper function to convert from a null_terminated_array_t to a null_terminated_array_t */ -void convert_wide_array_to_narrow(const null_terminated_array_t &wide_arr, null_terminated_array_t *output) -{ +/// Helper function to convert from a null_terminated_array_t to a +/// null_terminated_array_t. +void convert_wide_array_to_narrow(const null_terminated_array_t &wide_arr, + null_terminated_array_t *output) { const wchar_t *const *arr = wide_arr.get(); - if (! arr) - { + if (!arr) { output->clear(); return; } std::vector list; - for (size_t i=0; arr[i]; i++) - { + for (size_t i = 0; arr[i]; i++) { list.push_back(wcs2string(arr[i])); } output->set(list); } -void append_path_component(wcstring &path, const wcstring &component) -{ - if (path.empty() || component.empty()) - { +void append_path_component(wcstring &path, const wcstring &component) { + if (path.empty() || component.empty()) { path.append(component); - } - else - { + } else { size_t path_len = path.size(); - bool path_slash = path.at(path_len-1) == L'/'; + bool path_slash = path.at(path_len - 1) == L'/'; bool comp_slash = component.at(0) == L'/'; - if (! path_slash && ! comp_slash) - { + if (!path_slash && !comp_slash) { // Need a slash path.push_back(L'/'); - } - else if (path_slash && comp_slash) - { - // Too many slashes + } else if (path_slash && comp_slash) { + // Too many slashes. path.erase(path_len - 1, 1); } path.append(component); @@ -2115,304 +1626,253 @@ void append_path_component(wcstring &path, const wcstring &component) } extern "C" { - __attribute__((noinline)) void debug_thread_error(void) - { - while (1) sleep(9999999); - } +__attribute__((noinline)) void debug_thread_error(void) { + while (1) sleep(9999999); +} } +void set_main_thread() { main_thread_id = pthread_self(); } -void set_main_thread() -{ - main_thread_id = pthread_self(); -} - -void configure_thread_assertions_for_testing(void) -{ +void configure_thread_assertions_for_testing(void) { thread_assertions_configured_for_testing = true; } -/* Notice when we've forked */ +/// Notice when we've forked. static pid_t initial_pid = 0; -/* Be able to restore the term's foreground process group */ +/// Be able to restore the term's foreground process group. static pid_t initial_foreground_process_group = -1; -bool is_forked_child(void) -{ - /* Just bail if nobody's called setup_fork_guards, e.g. some of our tools */ - if (! initial_pid) return false; +bool is_forked_child(void) { + // Just bail if nobody's called setup_fork_guards, e.g. some of our tools. + if (!initial_pid) return false; bool is_child_of_fork = (getpid() != initial_pid); - if (is_child_of_fork) - { + if (is_child_of_fork) { printf("Uh-oh: %d\n", getpid()); while (1) sleep(10000); } return is_child_of_fork; } -void setup_fork_guards(void) -{ - /* Notice when we fork by stashing our pid. This seems simpler than pthread_atfork(). */ +void setup_fork_guards(void) { + // Notice when we fork by stashing our pid. This seems simpler than pthread_atfork(). initial_pid = getpid(); } -void save_term_foreground_process_group(void) -{ +void save_term_foreground_process_group(void) { initial_foreground_process_group = tcgetpgrp(STDIN_FILENO); } -void restore_term_foreground_process_group(void) -{ - if (initial_foreground_process_group != -1) - { - /* This is called during shutdown and from a signal handler. We don't bother to complain on failure. */ - if (0 > tcsetpgrp(STDIN_FILENO, initial_foreground_process_group)) - { - /* Ignore failure */ - } +void restore_term_foreground_process_group(void) { + if (initial_foreground_process_group != -1) { + // This is called during shutdown and from a signal handler. We don't bother to complain on + // failure. + tcsetpgrp(STDIN_FILENO, initial_foreground_process_group); } } -bool is_main_thread() -{ +bool is_main_thread() { assert(main_thread_id != 0); return main_thread_id == pthread_self(); } -void assert_is_main_thread(const char *who) -{ - if (! is_main_thread() && ! thread_assertions_configured_for_testing) - { - fprintf(stderr, "Warning: %s called off of main thread. Break on debug_thread_error to debug.\n", who); +void assert_is_main_thread(const char *who) { + if (!is_main_thread() && !thread_assertions_configured_for_testing) { + fprintf(stderr, + "Warning: %s called off of main thread. Break on debug_thread_error to debug.\n", + who); debug_thread_error(); } } -void assert_is_not_forked_child(const char *who) -{ - if (is_forked_child()) - { - fprintf(stderr, "Warning: %s called in a forked child. Break on debug_thread_error to debug.\n", who); +void assert_is_not_forked_child(const char *who) { + if (is_forked_child()) { + fprintf(stderr, + "Warning: %s called in a forked child. Break on debug_thread_error to debug.\n", + who); debug_thread_error(); } } -void assert_is_background_thread(const char *who) -{ - if (is_main_thread() && ! thread_assertions_configured_for_testing) - { - fprintf(stderr, "Warning: %s called on the main thread (may block!). Break on debug_thread_error to debug.\n", who); +void assert_is_background_thread(const char *who) { + if (is_main_thread() && !thread_assertions_configured_for_testing) { + fprintf(stderr, + "Warning: %s called on the main thread (may block!). Break on debug_thread_error " + "to debug.\n", + who); debug_thread_error(); } } -void assert_is_locked(void *vmutex, const char *who, const char *caller) -{ - pthread_mutex_t *mutex = static_cast(vmutex); - if (0 == pthread_mutex_trylock(mutex)) - { - fprintf(stderr, "Warning: %s is not locked when it should be in '%s'. Break on debug_thread_error to debug.\n", who, caller); +void assert_is_locked(void *vmutex, const char *who, const char *caller) { + pthread_mutex_t *mutex = static_cast(vmutex); + if (0 == pthread_mutex_trylock(mutex)) { + fprintf(stderr, + "Warning: %s is not locked when it should be in '%s'. Break on debug_thread_error " + "to debug.\n", + who, caller); debug_thread_error(); pthread_mutex_unlock(mutex); } } -void scoped_lock::lock(void) -{ - assert(! locked); - assert(! is_forked_child()); +void scoped_lock::lock(void) { + assert(!locked); + assert(!is_forked_child()); VOMIT_ON_FAILURE_NO_ERRNO(pthread_mutex_lock(lock_obj)); locked = true; } -void scoped_lock::unlock(void) -{ +void scoped_lock::unlock(void) { assert(locked); - assert(! is_forked_child()); + assert(!is_forked_child()); VOMIT_ON_FAILURE_NO_ERRNO(pthread_mutex_unlock(lock_obj)); locked = false; } -scoped_lock::scoped_lock(pthread_mutex_t &mutex) : lock_obj(&mutex), locked(false) -{ +scoped_lock::scoped_lock(pthread_mutex_t &mutex) : lock_obj(&mutex), locked(false) { this->lock(); } + +scoped_lock::scoped_lock(mutex_lock_t &lock) : lock_obj(&lock.mutex), locked(false) { this->lock(); } -scoped_lock::scoped_lock(mutex_lock_t &lock) : lock_obj(&lock.mutex), locked(false) -{ - this->lock(); -} - -scoped_lock::~scoped_lock() -{ +scoped_lock::~scoped_lock() { if (locked) this->unlock(); } -void scoped_rwlock::lock(void) -{ - assert(! (locked || locked_shared)); - assert(! is_forked_child()); +void scoped_rwlock::lock(void) { + assert(!(locked || locked_shared)); + assert(!is_forked_child()); VOMIT_ON_FAILURE_NO_ERRNO(pthread_rwlock_rdlock(rwlock_obj)); locked = true; } -void scoped_rwlock::unlock(void) -{ +void scoped_rwlock::unlock(void) { assert(locked); - assert(! is_forked_child()); + assert(!is_forked_child()); VOMIT_ON_FAILURE_NO_ERRNO(pthread_rwlock_unlock(rwlock_obj)); locked = false; } -void scoped_rwlock::lock_shared(void) -{ - assert(! (locked || locked_shared)); - assert(! is_forked_child()); +void scoped_rwlock::lock_shared(void) { + assert(!(locked || locked_shared)); + assert(!is_forked_child()); VOMIT_ON_FAILURE_NO_ERRNO(pthread_rwlock_wrlock(rwlock_obj)); locked_shared = true; } -void scoped_rwlock::unlock_shared(void) -{ +void scoped_rwlock::unlock_shared(void) { assert(locked_shared); - assert(! is_forked_child()); + assert(!is_forked_child()); VOMIT_ON_FAILURE_NO_ERRNO(pthread_rwlock_unlock(rwlock_obj)); locked_shared = false; } -void scoped_rwlock::upgrade(void) -{ +void scoped_rwlock::upgrade(void) { assert(locked_shared); - assert(! is_forked_child()); + assert(!is_forked_child()); VOMIT_ON_FAILURE_NO_ERRNO(pthread_rwlock_unlock(rwlock_obj)); locked = false; VOMIT_ON_FAILURE_NO_ERRNO(pthread_rwlock_wrlock(rwlock_obj)); locked_shared = true; } -scoped_rwlock::scoped_rwlock(pthread_rwlock_t &rwlock, bool shared) : rwlock_obj(&rwlock), locked(false), locked_shared(false) -{ - if (shared) - { +scoped_rwlock::scoped_rwlock(pthread_rwlock_t &rwlock, bool shared) + : rwlock_obj(&rwlock), locked(false), locked_shared(false) { + if (shared) { this->lock_shared(); - } - else - { + } else { this->lock(); } } -scoped_rwlock::scoped_rwlock(rwlock_t &rwlock, bool shared) : rwlock_obj(&rwlock.rwlock), locked(false), locked_shared(false) -{ - if (shared) - { +scoped_rwlock::scoped_rwlock(rwlock_t &rwlock, bool shared) + : rwlock_obj(&rwlock.rwlock), locked(false), locked_shared(false) { + if (shared) { this->lock_shared(); - } - else - { + } else { this->lock(); } } -scoped_rwlock::~scoped_rwlock() -{ - if (locked) - { +scoped_rwlock::~scoped_rwlock() { + if (locked) { this->unlock(); - } - else if (locked_shared) - { + } else if (locked_shared) { this->unlock_shared(); } } -wcstokenizer::wcstokenizer(const wcstring &s, const wcstring &separator) : - buffer(), - str(), - state(), - sep(separator) -{ +wcstokenizer::wcstokenizer(const wcstring &s, const wcstring &separator) + : buffer(), str(), state(), sep(separator) { buffer = wcsdup(s.c_str()); str = buffer; state = NULL; } -bool wcstokenizer::next(wcstring &result) -{ +bool wcstokenizer::next(wcstring &result) { wchar_t *tmp = wcstok(str, sep.c_str(), &state); str = NULL; if (tmp) result = tmp; return tmp != NULL; } -wcstokenizer::~wcstokenizer() -{ - free(buffer); -} - +wcstokenizer::~wcstokenizer() { free(buffer); } template -static CharType_t **make_null_terminated_array_helper(const std::vector > &argv) -{ +static CharType_t **make_null_terminated_array_helper( + const std::vector > &argv) { size_t count = argv.size(); - /* We allocate everything in one giant block. First compute how much space we need. */ - - /* N + 1 pointers */ + // We allocate everything in one giant block. First compute how much space we need. + // N + 1 pointers. size_t pointers_allocation_len = (count + 1) * sizeof(CharType_t *); - /* In the very unlikely event that CharType_t has stricter alignment requirements than does a pointer, round us up to the size of a CharType_t */ + // In the very unlikely event that CharType_t has stricter alignment requirements than does a + // pointer, round us up to the size of a CharType_t. pointers_allocation_len += sizeof(CharType_t) - 1; pointers_allocation_len -= pointers_allocation_len % sizeof(CharType_t); - /* N null terminated strings */ + // N null terminated strings. size_t strings_allocation_len = 0; - for (size_t i=0; i < count; i++) - { - /* The size of the string, plus a null terminator */ + for (size_t i = 0; i < count; i++) { + // The size of the string, plus a null terminator. strings_allocation_len += (argv.at(i).size() + 1) * sizeof(CharType_t); } - /* Now allocate their sum */ - unsigned char *base = static_cast(malloc(pointers_allocation_len + strings_allocation_len)); - if (! base) return NULL; + // Now allocate their sum. + unsigned char *base = + static_cast(malloc(pointers_allocation_len + strings_allocation_len)); + if (!base) return NULL; - /* Divvy it up into the pointers and strings */ + // Divvy it up into the pointers and strings. CharType_t **pointers = reinterpret_cast(base); CharType_t *strings = reinterpret_cast(base + pointers_allocation_len); - /* Start copying */ - for (size_t i=0; i < count; i++) - { + // Start copying. + for (size_t i = 0; i < count; i++) { const std::basic_string &str = argv.at(i); - // store the current string pointer into self - *pointers++ = strings; - - // copy the string into strings - strings = std::copy(str.begin(), str.end(), strings); - // each string needs a null terminator - *strings++ = (CharType_t)(0); + *pointers++ = strings; // store the current string pointer into self + strings = std::copy(str.begin(), str.end(), strings); // copy the string into strings + *strings++ = (CharType_t)(0); // each string needs a null terminator } - // array of pointers needs a null terminator - *pointers++ = NULL; + *pointers++ = NULL; // array of pointers needs a null terminator - // Make sure we know what we're doing + // Make sure we know what we're doing. assert((unsigned char *)pointers - base == (std::ptrdiff_t)pointers_allocation_len); - assert((unsigned char *)strings - (unsigned char *)pointers == (std::ptrdiff_t)strings_allocation_len); - assert((unsigned char *)strings - base == (std::ptrdiff_t)(pointers_allocation_len + strings_allocation_len)); + assert((unsigned char *)strings - (unsigned char *)pointers == + (std::ptrdiff_t)strings_allocation_len); + assert((unsigned char *)strings - base == + (std::ptrdiff_t)(pointers_allocation_len + strings_allocation_len)); - // Return what we did - return reinterpret_cast(base); + return reinterpret_cast(base); } -wchar_t **make_null_terminated_array(const wcstring_list_t &lst) -{ +wchar_t **make_null_terminated_array(const wcstring_list_t &lst) { return make_null_terminated_array_helper(lst); } -char **make_null_terminated_array(const std::vector &lst) -{ +char **make_null_terminated_array(const std::vector &lst) { return make_null_terminated_array_helper(lst); } diff --git a/src/common.h b/src/common.h index dc6e02366..3d1a771f5 100644 --- a/src/common.h +++ b/src/common.h @@ -1,34 +1,31 @@ -/** \file common.h - Prototypes for various functions, mostly string utilities, that are used by most parts of fish. -*/ +// Prototypes for various functions, mostly string utilities, that are used by most parts of fish. #ifndef FISH_COMMON_H #define FISH_COMMON_H #include "config.h" -#include -#include -#include -#include -#include -#include +#include #include +#include // IWYU pragma: keep +#include +#include +#include #include #include -#include #include -#include -#include +#include +#include // IWYU pragma: keep +#include +#include +#include #include "fallback.h" // IWYU pragma: keep -#include "signal.h" // IWYU pragma: keep +#include "signal.h" // IWYU pragma: keep -/** - Avoid writing the type name twice in a common "static_cast-initialization". - Caveat: This doesn't work with type names containing commas! -*/ -#define CAST_INIT(type, dst, src) type dst = static_cast(src) +/// Avoid writing the type name twice in a common "static_cast-initialization". Caveat: This doesn't +/// work with type names containing commas! +#define CAST_INIT(type, dst, src) type dst = static_cast(src) -/* Common string type */ +// Common string type. typedef std::wstring wcstring; typedef std::vector wcstring_list_t; @@ -54,13 +51,13 @@ typedef std::vector wcstring_list_t; // gives us 32 "characters" for internal use that we can guarantee should not // appear in our input stream. See http://www.unicode.org/faq/private_use.html. #define RESERVED_CHAR_BASE 0xFDD0u -#define RESERVED_CHAR_END 0xFDF0u +#define RESERVED_CHAR_END 0xFDF0u // Split the available noncharacter values into two ranges to ensure there are // no conflicts among the places we use these special characters. #define EXPAND_RESERVED_BASE RESERVED_CHAR_BASE -#define EXPAND_RESERVED_END (EXPAND_RESERVED_BASE + 16) +#define EXPAND_RESERVED_END (EXPAND_RESERVED_BASE + 16) #define WILDCARD_RESERVED_BASE EXPAND_RESERVED_END -#define WILDCARD_RESERVED_END (WILDCARD_RESERVED_BASE + 16) +#define WILDCARD_RESERVED_END (WILDCARD_RESERVED_BASE + 16) // Make sure the ranges defined above don't exceed the range for noncharacters. // This is to make sure we didn't do something stupid in subdividing the // Unicode range for our needs. @@ -81,42 +78,35 @@ typedef std::vector wcstring_list_t; // of at least one use of a codepoint in that range: the Apple symbol (0xF8FF) // on Mac OS X. See http://www.unicode.org/faq/private_use.html. #define ENCODE_DIRECT_BASE 0xF600u -#define ENCODE_DIRECT_END (ENCODE_DIRECT_BASE + 256) -#define INPUT_COMMON_BASE 0xF700u -#define INPUT_COMMON_END (INPUT_COMMON_BASE + 64) +#define ENCODE_DIRECT_END (ENCODE_DIRECT_BASE + 256) +#define INPUT_COMMON_BASE 0xF700u +#define INPUT_COMMON_END (INPUT_COMMON_BASE + 64) -/* Flags for unescape_string functions */ -enum -{ - /* Default behavior */ - UNESCAPE_DEFAULT = 0, - - /* Escape special fish syntax characters like the semicolon */ - UNESCAPE_SPECIAL = 1 << 0, - - /* Allow incomplete escape sequences */ - UNESCAPE_INCOMPLETE = 1 << 1 +// Flags for unescape_string functions. +enum { + UNESCAPE_DEFAULT = 0, // default behavior + UNESCAPE_SPECIAL = 1 << 0, // escape special fish syntax characters like the semicolon + UNESCAPE_INCOMPLETE = 1 << 1 // allow incomplete escape sequences }; typedef unsigned int unescape_flags_t; -/* Flags for the escape() and escape_string() functions */ -enum -{ - /** Escape all characters, including magic characters like the semicolon */ +// Flags for the escape() and escape_string() functions. +enum { + /// Escape all characters, including magic characters like the semicolon. ESCAPE_ALL = 1 << 0, - /** Do not try to use 'simplified' quoted escapes, and do not use empty quotes as the empty string */ + /// Do not try to use 'simplified' quoted escapes, and do not use empty quotes as the empty + /// string. ESCAPE_NO_QUOTED = 1 << 1, - /** Do not escape tildes */ + /// Do not escape tildes. ESCAPE_NO_TILDE = 1 << 2 }; typedef unsigned int escape_flags_t; -/* Directions */ -enum selection_direction_t -{ - /* visual directions */ +// Directions. +enum selection_direction_t { + // Visual directions. direction_north, direction_east, direction_south, @@ -124,275 +114,237 @@ enum selection_direction_t direction_page_north, direction_page_south, - /* logical directions */ + // Logical directions. direction_next, direction_prev, - /* special value that means deselect */ + // Special value that means deselect. direction_deselect }; -inline bool selection_direction_is_cardinal(selection_direction_t dir) -{ - switch (dir) - { +inline bool selection_direction_is_cardinal(selection_direction_t dir) { + switch (dir) { case direction_north: case direction_page_north: case direction_east: case direction_page_south: case direction_south: - case direction_west: + case direction_west: { return true; - default: - return false; + } + default: { return false; } } } -/** - Helper macro for errors - */ -#define VOMIT_ON_FAILURE(a) do { if (0 != (a)) { VOMIT_ABORT(errno, #a); } } while (0) -#define VOMIT_ON_FAILURE_NO_ERRNO(a) do { int err = (a); if (0 != err) { VOMIT_ABORT(err, #a); } } while (0) -#define VOMIT_ABORT(err, str) do { int code = (err); fprintf(stderr, "%s failed on line %d in file %s: %d (%s)\n", str, __LINE__, __FILE__, code, strerror(code)); abort(); } while(0) +/// Helper macro for errors. +#define VOMIT_ON_FAILURE(a) \ + do { \ + if (0 != (a)) { \ + VOMIT_ABORT(errno, #a); \ + } \ + } while (0) +#define VOMIT_ON_FAILURE_NO_ERRNO(a) \ + do { \ + int err = (a); \ + if (0 != err) { \ + VOMIT_ABORT(err, #a); \ + } \ + } while (0) +#define VOMIT_ABORT(err, str) \ + do { \ + int code = (err); \ + fprintf(stderr, "%s failed on line %d in file %s: %d (%s)\n", str, __LINE__, __FILE__, \ + code, strerror(code)); \ + abort(); \ + } while (0) -/** Exits without invoking destructors (via _exit), useful for code after fork. */ +/// Exits without invoking destructors (via _exit), useful for code after fork. void exit_without_destructors(int code) __attribute__((noreturn)); -/** - Save the shell mode on startup so we can restore them on exit -*/ +/// Save the shell mode on startup so we can restore them on exit. extern struct termios shell_modes; -/** - The character to use where the text has been truncated. Is an - ellipsis on unicode system and a $ on other systems. -*/ +/// The character to use where the text has been truncated. Is an ellipsis on unicode system and a $ +/// on other systems. extern wchar_t ellipsis_char; -/* Character representing an omitted newline at the end of text */ +/// Character representing an omitted newline at the end of text. extern wchar_t omitted_newline_char; -/** - The verbosity level of fish. If a call to debug has a severity - level higher than \c debug_level, it will not be printed. -*/ +/// The verbosity level of fish. If a call to debug has a severity level higher than \c debug_level, +/// it will not be printed. extern int debug_level; -/** - Profiling flag. True if commands should be profiled. -*/ +/// Profiling flag. True if commands should be profiled. extern bool g_profiling_active; -/** - Name of the current program. Should be set at startup. Used by the - debug function. -*/ +/// Name of the current program. Should be set at startup. Used by the debug function. extern const wchar_t *program_name; -/* Variants of read() and write() that ignores return values, defeating a warning */ +// Variants of read() and write() that ignores return values, defeating a warning. void read_ignore(int fd, void *buff, size_t count); void write_ignore(int fd, const void *buff, size_t count); -/** - This macro is used to check that an input argument is not null. It - is a bit lika a non-fatal form of assert. Instead of exit-ing on - failure, the current function is ended at once. The second - parameter is the return value of the current function on failure. -*/ -#define CHECK( arg, retval ) \ - if (!(arg)) \ - { \ - debug( 0, \ - "function %s called with null value for argument %s. ", \ - __func__, \ - #arg ); \ - bugreport(); \ - show_stackframe(); \ - return retval; \ - } +/// This macro is used to check that an input argument is not null. It is a bit lika a non-fatal +/// form of assert. Instead of exit-ing on failure, the current function is ended at once. The +/// second parameter is the return value of the current function on failure. +#define CHECK(arg, retval) \ + if (!(arg)) { \ + debug(0, "function %s called with null value for argument %s. ", __func__, #arg); \ + bugreport(); \ + show_stackframe(); \ + return retval; \ + } -/** - Pause for input, then exit the program. If supported, print a backtrace first. -*/ -#define FATAL_EXIT() \ - { \ - char exit_read_buff; \ - show_stackframe(); \ - read_ignore( 0, &exit_read_buff, 1 ); \ - exit_without_destructors( 1 ); \ - } \ - +/// Pause for input, then exit the program. If supported, print a backtrace first. +#define FATAL_EXIT() \ + { \ + char exit_read_buff; \ + show_stackframe(); \ + read_ignore(0, &exit_read_buff, 1); \ + exit_without_destructors(1); \ + } -/** - Exit program at once, leaving an error message about running out of memory. -*/ -#define DIE_MEM() \ - { \ - fwprintf( stderr, \ - L"fish: Out of memory on line %ld of file %s, shutting down fish\n", \ - (long)__LINE__, \ - __FILE__ ); \ - FATAL_EXIT(); \ - } +/// Exit program at once, leaving an error message about running out of memory. +#define DIE_MEM() \ + { \ + fwprintf(stderr, L"fish: Out of memory on line %ld of file %s, shutting down fish\n", \ + (long)__LINE__, __FILE__); \ + FATAL_EXIT(); \ + } -/** - Check if signals are blocked. If so, print an error message and - return from the function performing this check. -*/ -#define CHECK_BLOCK(retval) \ - if (signal_is_blocked()) \ - { \ - debug( 0, \ - "function %s called while blocking signals. ", \ - __func__); \ - bugreport(); \ - show_stackframe(); \ - return retval; \ - } +/// Check if signals are blocked. If so, print an error message and return from the function +/// performing this check. +#define CHECK_BLOCK(retval) \ + if (signal_is_blocked()) { \ + debug(0, "function %s called while blocking signals. ", __func__); \ + bugreport(); \ + show_stackframe(); \ + return retval; \ + } -/** - Shorthand for wgettext call -*/ +/// Shorthand for wgettext call. #define _(wstr) wgettext(wstr) -/** - Noop, used to tell xgettext that a string should be translated, - even though it is not directly sent to wgettext. -*/ +/// Noop, used to tell xgettext that a string should be translated, even though it is not directly +/// sent to wgettext. #define N_(wstr) wstr -/** - Check if the specified string element is a part of the specified string list - */ -#define contains( str, ... ) contains_internal( str, 0, __VA_ARGS__, NULL ) +/// Check if the specified string element is a part of the specified string list. +#define contains(str, ...) contains_internal(str, 0, __VA_ARGS__, NULL) -/** - Print a stack trace to stderr -*/ +/// Print a stack trace to stderr. void show_stackframe(); - -/** - Read a line from the stream f into the string. Returns - the number of bytes read or -1 on failure. - - If the carriage return character is encountered, it is - ignored. fgetws() considers the line to end if reading the file - results in either a newline (L'\n') character, the null (L'\\0') - character or the end of file (WEOF) character. -*/ +/// Read a line from the stream f into the string. Returns the number of bytes read or -1 on +/// failure. +/// +/// If the carriage return character is encountered, it is ignored. fgetws() considers the line to +/// end if reading the file results in either a newline (L'\n') character, the null (L'\\0') +/// character or the end of file (WEOF) character. int fgetws2(wcstring *s, FILE *f); - -/** - Returns a wide character string equivalent of the - specified multibyte character string - - This function encodes illegal character sequences in a reversible - way using the private use area. - */ +/// Returns a wide character string equivalent of the specified multibyte character string. +/// +/// This function encodes illegal character sequences in a reversible way using the private use +/// area. wcstring str2wcstring(const char *in); wcstring str2wcstring(const char *in, size_t len); wcstring str2wcstring(const std::string &in); -/** - Returns a newly allocated multibyte character string equivalent of - the specified wide character string - - This function decodes illegal character sequences in a reversible - way using the private use area. -*/ +/// Returns a newly allocated multibyte character string equivalent of the specified wide character +/// string. +/// +/// This function decodes illegal character sequences in a reversible way using the private use +/// area. char *wcs2str(const wchar_t *in); char *wcs2str(const wcstring &in); std::string wcs2string(const wcstring &input); -/** Test if a string prefixes another. Returns true if a is a prefix of b */ +/// Test if a string prefixes another. Returns true if a is a prefix of b. bool string_prefixes_string(const wcstring &proposed_prefix, const wcstring &value); bool string_prefixes_string(const wchar_t *proposed_prefix, const wcstring &value); -/** Test if a string is a suffix of another */ +/// Test if a string is a suffix of another. bool string_suffixes_string(const wcstring &proposed_suffix, const wcstring &value); bool string_suffixes_string(const wchar_t *proposed_suffix, const wcstring &value); -/** Test if a string prefixes another without regard to case. Returns true if a is a prefix of b */ -bool string_prefixes_string_case_insensitive(const wcstring &proposed_prefix, const wcstring &value); +/// Test if a string prefixes another without regard to case. Returns true if a is a prefix of b. +bool string_prefixes_string_case_insensitive(const wcstring &proposed_prefix, + const wcstring &value); -enum fuzzy_match_type_t -{ - /* We match the string exactly: FOOBAR matches FOOBAR */ +enum fuzzy_match_type_t { + // We match the string exactly: FOOBAR matches FOOBAR. fuzzy_match_exact = 0, - /* We match a prefix of the string: FO matches FOOBAR */ + // We match a prefix of the string: FO matches FOOBAR. fuzzy_match_prefix, - /* We match the string exactly, but in a case insensitive way: foobar matches FOOBAR */ + // We match the string exactly, but in a case insensitive way: foobar matches FOOBAR. fuzzy_match_case_insensitive, - /* We match a prefix of the string, in a case insensitive way: foo matches FOOBAR */ + // We match a prefix of the string, in a case insensitive way: foo matches FOOBAR. fuzzy_match_prefix_case_insensitive, - /* We match a substring of the string: OOBA matches FOOBAR */ + // We match a substring of the string: OOBA matches FOOBAR. fuzzy_match_substring, - /* A subsequence match with insertions only: FBR matches FOOBAR */ + // A subsequence match with insertions only: FBR matches FOOBAR. fuzzy_match_subsequence_insertions_only, - /* We don't match the string */ + // We don't match the string. fuzzy_match_none }; -/* Indicates where a match type requires replacing the entire token */ -static inline bool match_type_requires_full_replacement(fuzzy_match_type_t t) -{ - switch (t) - { +/// Indicates where a match type requires replacing the entire token. +static inline bool match_type_requires_full_replacement(fuzzy_match_type_t t) { + switch (t) { case fuzzy_match_exact: - case fuzzy_match_prefix: + case fuzzy_match_prefix: { return false; - default: - return true; + } + default: { return true; } } } -/* Indicates where a match shares a prefix with the string it matches */ -static inline bool match_type_shares_prefix(fuzzy_match_type_t t) -{ - switch (t) - { +/// Indicates where a match shares a prefix with the string it matches. +static inline bool match_type_shares_prefix(fuzzy_match_type_t t) { + switch (t) { case fuzzy_match_exact: case fuzzy_match_prefix: case fuzzy_match_case_insensitive: - case fuzzy_match_prefix_case_insensitive: + case fuzzy_match_prefix_case_insensitive: { return true; - default: - return false; + } + default: { return false; } } } -/** Test if string is a fuzzy match to another */ -struct string_fuzzy_match_t -{ +/// Test if string is a fuzzy match to another. +struct string_fuzzy_match_t { enum fuzzy_match_type_t type; - /* Strength of the match. The value depends on the type. Lower is stronger. */ + // Strength of the match. The value depends on the type. Lower is stronger. size_t match_distance_first; size_t match_distance_second; - /* Constructor */ - explicit string_fuzzy_match_t(enum fuzzy_match_type_t t, size_t distance_first = 0, size_t distance_second = 0); + // Constructor. + explicit string_fuzzy_match_t(enum fuzzy_match_type_t t, size_t distance_first = 0, + size_t distance_second = 0); - /* Return -1, 0, 1 if this match is (respectively) better than, equal to, or worse than rhs */ + // Return -1, 0, 1 if this match is (respectively) better than, equal to, or worse than rhs. int compare(const string_fuzzy_match_t &rhs) const; }; -/* Compute a fuzzy match for a string. If maximum_match is not fuzzy_match_none, limit the type to matches at or below that type. */ -string_fuzzy_match_t string_fuzzy_match_string(const wcstring &string, const wcstring &match_against, fuzzy_match_type_t limit_type = fuzzy_match_none); +/// Compute a fuzzy match for a string. If maximum_match is not fuzzy_match_none, limit the type to +/// matches at or below that type. +string_fuzzy_match_t string_fuzzy_match_string(const wcstring &string, + const wcstring &match_against, + fuzzy_match_type_t limit_type = fuzzy_match_none); - -/** Test if a list contains a string using a linear search. */ +/// Test if a list contains a string using a linear search. bool list_contains_string(const wcstring_list_t &list, const wcstring &str); - void assert_is_main_thread(const char *who); #define ASSERT_IS_MAIN_THREAD_TRAMPOLINE(x) assert_is_main_thread(x) #define ASSERT_IS_MAIN_THREAD() ASSERT_IS_MAIN_THREAD_TRAMPOLINE(__FUNCTION__) @@ -401,185 +353,158 @@ void assert_is_background_thread(const char *who); #define ASSERT_IS_BACKGROUND_THREAD_TRAMPOLINE(x) assert_is_background_thread(x) #define ASSERT_IS_BACKGROUND_THREAD() ASSERT_IS_BACKGROUND_THREAD_TRAMPOLINE(__FUNCTION__) -/* Useful macro for asserting that a lock is locked. This doesn't check whether this thread locked it, which it would be nice if it did, but here it is anyways. */ +/// Useful macro for asserting that a lock is locked. This doesn't check whether this thread locked +/// it, which it would be nice if it did, but here it is anyways. void assert_is_locked(void *mutex, const char *who, const char *caller); #define ASSERT_IS_LOCKED(x) assert_is_locked((void *)(&x), #x, __FUNCTION__) -/** Format the specified size (in bytes, kilobytes, etc.) into the specified stringbuffer. */ +/// Format the specified size (in bytes, kilobytes, etc.) into the specified stringbuffer. wcstring format_size(long long sz); -/** Version of format_size that does not allocate memory. */ +/// Version of format_size that does not allocate memory. void format_size_safe(char buff[128], unsigned long long sz); -/** Our crappier versions of debug which is guaranteed to not allocate any memory, or do anything other than call write(). This is useful after a call to fork() with threads. */ -void debug_safe(int level, const char *msg, const char *param1 = NULL, const char *param2 = NULL, const char *param3 = NULL, const char *param4 = NULL, const char *param5 = NULL, const char *param6 = NULL, const char *param7 = NULL, const char *param8 = NULL, const char *param9 = NULL, const char *param10 = NULL, const char *param11 = NULL, const char *param12 = NULL); +/// Our crappier versions of debug which is guaranteed to not allocate any memory, or do anything +/// other than call write(). This is useful after a call to fork() with threads. +void debug_safe(int level, const char *msg, const char *param1 = NULL, const char *param2 = NULL, + const char *param3 = NULL, const char *param4 = NULL, const char *param5 = NULL, + const char *param6 = NULL, const char *param7 = NULL, const char *param8 = NULL, + const char *param9 = NULL, const char *param10 = NULL, const char *param11 = NULL, + const char *param12 = NULL); -/** Writes out a long safely */ +/// Writes out a long safely. void format_long_safe(char buff[64], long val); void format_long_safe(wchar_t buff[64], long val); -/** "Narrows" a wide character string. This just grabs any ASCII characters and trunactes. */ +/// "Narrows" a wide character string. This just grabs any ASCII characters and trunactes. void narrow_string_safe(char buff[64], const wchar_t *s); - -template -T from_string(const wcstring &x) -{ +template +T from_string(const wcstring &x) { T result; std::wstringstream stream(x); stream >> result; return result; } -template -T from_string(const std::string &x) -{ +template +T from_string(const std::string &x) { T result = T(); std::stringstream stream(x); stream >> result; return result; } -template -wcstring to_string(const T &x) -{ +template +wcstring to_string(const T &x) { std::wstringstream stream; stream << x; return stream.str(); } -/* wstringstream is a huge memory pig. Let's provide some specializations where we can. */ -template<> -inline wcstring to_string(const long &x) -{ +// wstringstream is a huge memory pig. Let's provide some specializations where we can. +template <> +inline wcstring to_string(const long &x) { wchar_t buff[128]; format_long_safe(buff, x); return wcstring(buff); } -template<> -inline bool from_string(const std::string &x) -{ - return ! x.empty() && strchr("YTyt1", x.at(0)); +template <> +inline bool from_string(const std::string &x) { + return !x.empty() && strchr("YTyt1", x.at(0)); } -template<> -inline bool from_string(const wcstring &x) -{ - return ! x.empty() && wcschr(L"YTyt1", x.at(0)); +template <> +inline bool from_string(const wcstring &x) { + return !x.empty() && wcschr(L"YTyt1", x.at(0)); } -template<> -inline wcstring to_string(const int &x) -{ +template <> +inline wcstring to_string(const int &x) { return to_string(static_cast(x)); } -/* A hackish thing to simulate rvalue references in C++98. - The idea is that you can define a constructor to take a moved_ref and then swap() out of it. - */ -template -struct moved_ref -{ +// A hackish thing to simulate rvalue references in C++98. The idea is that you can define a +// constructor to take a moved_ref and then swap() out of it. +template +struct moved_ref { T &val; - - explicit moved_ref(T &v) : val(v) { } + + explicit moved_ref(T &v) : val(v) {} }; wchar_t **make_null_terminated_array(const wcstring_list_t &lst); char **make_null_terminated_array(const std::vector &lst); -/* Helper class for managing a null-terminated array of null-terminated strings (of some char type) */ +// Helper class for managing a null-terminated array of null-terminated strings (of some char type). template -class null_terminated_array_t -{ +class null_terminated_array_t { CharType_t **array; - /* No assignment or copying */ + // No assignment or copying. void operator=(null_terminated_array_t rhs); null_terminated_array_t(const null_terminated_array_t &); typedef std::vector > string_list_t; - size_t size() const - { + size_t size() const { size_t len = 0; - if (array != NULL) - { - while (array[len] != NULL) - { + if (array != NULL) { + while (array[len] != NULL) { len++; } } return len; } - void free(void) - { + void free(void) { ::free((void *)array); array = NULL; } -public: - null_terminated_array_t() : array(NULL) { } - explicit null_terminated_array_t(const string_list_t &argv) : array(make_null_terminated_array(argv)) - { - } + public: + null_terminated_array_t() : array(NULL) {} + explicit null_terminated_array_t(const string_list_t &argv) + : array(make_null_terminated_array(argv)) {} - ~null_terminated_array_t() - { - this->free(); - } + ~null_terminated_array_t() { this->free(); } - void set(const string_list_t &argv) - { + void set(const string_list_t &argv) { this->free(); this->array = make_null_terminated_array(argv); } - const CharType_t * const *get() const - { - return array; - } + const CharType_t *const *get() const { return array; } - void clear() - { - this->free(); - } + void clear() { this->free(); } }; -/* Helper function to convert from a null_terminated_array_t to a null_terminated_array_t */ -void convert_wide_array_to_narrow(const null_terminated_array_t &arr, null_terminated_array_t *output); +// Helper function to convert from a null_terminated_array_t to a +// null_terminated_array_t. +void convert_wide_array_to_narrow(const null_terminated_array_t &arr, + null_terminated_array_t *output); bool is_forked_child(); - -class mutex_lock_t -{ - public: +class mutex_lock_t { + public: pthread_mutex_t mutex; - mutex_lock_t() - { - VOMIT_ON_FAILURE_NO_ERRNO(pthread_mutex_init(&mutex, NULL)); - } - - ~mutex_lock_t() - { - VOMIT_ON_FAILURE_NO_ERRNO(pthread_mutex_destroy(&mutex)); - } + mutex_lock_t() { VOMIT_ON_FAILURE_NO_ERRNO(pthread_mutex_init(&mutex, NULL)); } + + ~mutex_lock_t() { VOMIT_ON_FAILURE_NO_ERRNO(pthread_mutex_destroy(&mutex)); } }; -/* Basic scoped lock class */ -class scoped_lock -{ +// Basic scoped lock class. +class scoped_lock { pthread_mutex_t *lock_obj; bool locked; - /* No copying */ + // No copying. scoped_lock &operator=(const scoped_lock &); scoped_lock(const scoped_lock &); -public: + public: void lock(void); void unlock(void); explicit scoped_lock(pthread_mutex_t &mutex); @@ -587,108 +512,79 @@ public: ~scoped_lock(); }; -class rwlock_t -{ -public: +class rwlock_t { + public: pthread_rwlock_t rwlock; - rwlock_t() - { - VOMIT_ON_FAILURE_NO_ERRNO(pthread_rwlock_init(&rwlock, NULL)); - } + rwlock_t() { VOMIT_ON_FAILURE_NO_ERRNO(pthread_rwlock_init(&rwlock, NULL)); } - ~rwlock_t() - { - VOMIT_ON_FAILURE_NO_ERRNO(pthread_rwlock_destroy(&rwlock)); - } + ~rwlock_t() { VOMIT_ON_FAILURE_NO_ERRNO(pthread_rwlock_destroy(&rwlock)); } }; -/* - Scoped lock class for rwlocks - */ -class scoped_rwlock -{ +// Scoped lock class for rwlocks. +class scoped_rwlock { pthread_rwlock_t *rwlock_obj; bool locked; bool locked_shared; - /* No copying */ + // No copying. scoped_rwlock &operator=(const scoped_lock &); explicit scoped_rwlock(const scoped_lock &); -public: + public: void lock(void); void unlock(void); void lock_shared(void); void unlock_shared(void); - /* - upgrade shared lock to exclusive. - equivalent to `lock.unlock_shared(); lock.lock();` - */ + // Upgrade shared lock to exclusive. Equivalent to `lock.unlock_shared(); lock.lock();`. void upgrade(void); explicit scoped_rwlock(pthread_rwlock_t &rwlock, bool shared = false); explicit scoped_rwlock(rwlock_t &rwlock, bool shared = false); ~scoped_rwlock(); }; -/** - A scoped manager to save the current value of some variable, and optionally - set it to a new value. On destruction it restores the variable to its old - value. - - This can be handy when there are multiple code paths to exit a block. -*/ +/// A scoped manager to save the current value of some variable, and optionally set it to a new +/// value. On destruction it restores the variable to its old value. +/// +/// This can be handy when there are multiple code paths to exit a block. template -class scoped_push -{ - T * const ref; +class scoped_push { + T *const ref; T saved_value; bool restored; -public: - explicit scoped_push(T *r): ref(r), saved_value(*r), restored(false) - { - } + public: + explicit scoped_push(T *r) : ref(r), saved_value(*r), restored(false) {} - scoped_push(T *r, const T &new_value) : ref(r), saved_value(*r), restored(false) - { + scoped_push(T *r, const T &new_value) : ref(r), saved_value(*r), restored(false) { *r = new_value; } - ~scoped_push() - { - restore(); - } + ~scoped_push() { restore(); } - void restore() - { - if (!restored) - { + void restore() { + if (!restored) { std::swap(*ref, saved_value); restored = true; } } }; - -/* Wrapper around wcstok */ -class wcstokenizer -{ +/// Wrapper around wcstok. +class wcstokenizer { wchar_t *buffer, *str, *state; const wcstring sep; - /* No copying */ + // No copying. wcstokenizer &operator=(const wcstokenizer &); wcstokenizer(const wcstokenizer &); -public: + public: wcstokenizer(const wcstring &s, const wcstring &separator); bool next(wcstring &result); ~wcstokenizer(); }; -/** - Appends a path component, with a / if necessary - */ +/// Appends a path component, with a / if necessary. void append_path_component(wcstring &path, const wcstring &component); wcstring format_string(const wchar_t *format, ...); @@ -696,237 +592,176 @@ wcstring vformat_string(const wchar_t *format, va_list va_orig); void append_format(wcstring &str, const wchar_t *format, ...); void append_formatv(wcstring &str, const wchar_t *format, va_list ap); -/** - Test if the given string is a valid variable name. - - \return null if this is a valid name, and a pointer to the first invalid character otherwise -*/ - +/// Test if the given string is a valid variable name. +/// +/// \return null if this is a valid name, and a pointer to the first invalid character otherwise. const wchar_t *wcsvarname(const wchar_t *str); const wchar_t *wcsvarname(const wcstring &str); - -/** - Test if the given string is a valid function name. - - \return null if this is a valid name, and a pointer to the first invalid character otherwise -*/ - +/// Test if the given string is a valid function name. +/// +/// \return null if this is a valid name, and a pointer to the first invalid character otherwise. const wchar_t *wcsfuncname(const wcstring &str); -/** - Test if the given string is valid in a variable name - - \return true if this is a valid name, false otherwise -*/ - +/// Test if the given string is valid in a variable name. +/// +/// \return true if this is a valid name, false otherwise. bool wcsvarchr(wchar_t chr); -/** - Convenience variants on fish_wcwswidth(). - - See fallback.h for the normal definitions. -*/ +/// Convenience variants on fish_wcwswidth(). +/// +/// See fallback.h for the normal definitions. int fish_wcswidth(const wchar_t *str); -int fish_wcswidth(const wcstring& str); +int fish_wcswidth(const wcstring &str); -/** - This functions returns the end of the quoted substring beginning at - \c in. The type of quoting character is detemrined by examining \c - in. Returns 0 on error. - - \param in the position of the opening quote -*/ +/// This functions returns the end of the quoted substring beginning at \c in. The type of quoting +/// character is detemrined by examining \c in. Returns 0 on error. +/// +/// \param in the position of the opening quote. wchar_t *quote_end(const wchar_t *in); -/** - A call to this function will reset the error counter. Some - functions print out non-critical error messages. These should check - the error_count before, and skip printing the message if - MAX_ERROR_COUNT messages have been printed. The error_reset() - should be called after each interactive command executes, to allow - new messages to be printed. -*/ +/// A call to this function will reset the error counter. Some functions print out non-critical +/// error messages. These should check the error_count before, and skip printing the message if +/// MAX_ERROR_COUNT messages have been printed. The error_reset() should be called after each +/// interactive command executes, to allow new messages to be printed. void error_reset(); -/** - This function behaves exactly like a wide character equivalent of - the C function setlocale, except that it will also try to detect if - the user is using a Unicode character set, and if so, use the - unicode ellipsis character as ellipsis, instead of '$'. -*/ +/// This function behaves exactly like a wide character equivalent of the C function setlocale, +/// except that it will also try to detect if the user is using a Unicode character set, and if so, +/// use the unicode ellipsis character as ellipsis, instead of '$'. wcstring wsetlocale(int category, const wchar_t *locale); -/** - Checks if \c needle is included in the list of strings specified. A warning is printed if needle is zero. - - \param needle the string to search for in the list - - \return zero if needle is not found, of if needle is null, non-zero otherwise -*/ +/// Checks if \c needle is included in the list of strings specified. A warning is printed if needle +/// is zero. +/// +/// \param needle the string to search for in the list. +/// +/// \return zero if needle is not found, of if needle is null, non-zero otherwise. __sentinel bool contains_internal(const wchar_t *needle, int vararg_handle, ...); __sentinel bool contains_internal(const wcstring &needle, int vararg_handle, ...); -/** - Call read while blocking the SIGCHLD signal. Should only be called - if you _know_ there is data available for reading, or the program - will hang until there is data. -*/ +/// Call read while blocking the SIGCHLD signal. Should only be called if you _know_ there is data +/// available for reading, or the program will hang until there is data. long read_blocked(int fd, void *buf, size_t count); -/** - Loop a write request while failure is non-critical. Return -1 and set errno - in case of critical error. - */ +/// Loop a write request while failure is non-critical. Return -1 and set errno in case of critical +/// error. ssize_t write_loop(int fd, const char *buff, size_t count); -/** - Loop a read request while failure is non-critical. Return -1 and set errno - in case of critical error. - */ +/// Loop a read request while failure is non-critical. Return -1 and set errno in case of critical +/// error. ssize_t read_loop(int fd, void *buff, size_t count); - -/** - Issue a debug message with printf-style string formating and - automatic line breaking. The string will begin with the string \c - program_name, followed by a colon and a whitespace. - - Because debug is often called to tell the user about an error, - before using wperror to give a specific error message, debug will - never ever modify the value of errno. - - \param level the priority of the message. Lower number means higher priority. Messages with a priority_number higher than \c debug_level will be ignored.. - \param msg the message format string. - - Example: - - debug( 1, L"Pi = %.3f", M_PI ); - - will print the string 'fish: Pi = 3.141', given that debug_level is 1 or higher, and that program_name is 'fish'. -*/ +/// Issue a debug message with printf-style string formating and automatic line breaking. The string +/// will begin with the string \c program_name, followed by a colon and a whitespace. +/// +/// Because debug is often called to tell the user about an error, before using wperror to give a +/// specific error message, debug will never ever modify the value of errno. +/// +/// \param level the priority of the message. Lower number means higher priority. Messages with a +/// priority_number higher than \c debug_level will be ignored.. +/// \param msg the message format string. +/// +/// Example: +/// +/// debug( 1, L"Pi = %.3f", M_PI ); +/// +/// will print the string 'fish: Pi = 3.141', given that debug_level is 1 or higher, and that +/// program_name is 'fish'. void debug(int level, const char *msg, ...); void debug(int level, const wchar_t *msg, ...); -/** - Replace special characters with backslash escape sequences. Newline is - replaced with \n, etc. - - \param in The string to be escaped - \param flags Flags to control the escaping - \return The escaped string -*/ - +/// Replace special characters with backslash escape sequences. Newline is replaced with \n, etc. +/// +/// \param in The string to be escaped +/// \param flags Flags to control the escaping +/// \return The escaped string wcstring escape(const wchar_t *in, escape_flags_t flags); wcstring escape_string(const wcstring &in, escape_flags_t flags); -/** - Expand backslashed escapes and substitute them with their unescaped - counterparts. Also optionally change the wildcards, the tilde - character and a few more into constants which are defined in a - private use area of Unicode. This assumes wchar_t is a unicode - character set. -*/ +/// Expand backslashed escapes and substitute them with their unescaped counterparts. Also +/// optionally change the wildcards, the tilde character and a few more into constants which are +/// defined in a private use area of Unicode. This assumes wchar_t is a unicode character set. -/** Given a null terminated string starting with a backslash, read the escape as if it is unquoted, appending to result. Return the number of characters consumed, or 0 on error */ -size_t read_unquoted_escape(const wchar_t *input, wcstring *result, bool allow_incomplete, bool unescape_special); +/// Given a null terminated string starting with a backslash, read the escape as if it is unquoted, +/// appending to result. Return the number of characters consumed, or 0 on error. +size_t read_unquoted_escape(const wchar_t *input, wcstring *result, bool allow_incomplete, + bool unescape_special); -/** Unescapes a string in-place. A true result indicates the string was unescaped, a false result indicates the string was unmodified. */ +/// Unescapes a string in-place. A true result indicates the string was unescaped, a false result +/// indicates the string was unmodified. bool unescape_string_in_place(wcstring *str, unescape_flags_t escape_special); -/** Unescapes a string, returning the unescaped value by reference. On failure, the output is set to an empty string. */ +/// Unescapes a string, returning the unescaped value by reference. On failure, the output is set to +/// an empty string. bool unescape_string(const wchar_t *input, wcstring *output, unescape_flags_t escape_special); bool unescape_string(const wcstring &input, wcstring *output, unescape_flags_t escape_special); - -/** - Returns the width of the terminal window, so that not all - functions that use these values continually have to keep track of - it separately. - - Only works if common_handle_winch is registered to handle winch signals. -*/ +/// Returns the width of the terminal window, so that not all functions that use these values +/// continually have to keep track of it separately. +/// +/// Only works if common_handle_winch is registered to handle winch signals. int common_get_width(); -/** - Returns the height of the terminal window, so that not all - functions that use these values continually have to keep track of - it separatly. - Only works if common_handle_winch is registered to handle winch signals. -*/ +/// Returns the height of the terminal window, so that not all functions that use these values +/// continually have to keep track of it separatly. +/// +/// Only works if common_handle_winch is registered to handle winch signals. int common_get_height(); -/** - Handle a window change event by looking up the new window size and - saving it in an internal variable used by common_get_wisth and - common_get_height(). -*/ +/// Handle a window change event by looking up the new window size and saving it in an internal +/// variable used by common_get_wisth and common_get_height(). void common_handle_winch(int signal); -/** - Write the given paragraph of output, redoing linebreaks to fit - the current screen. -*/ +/// Write the given paragraph of output, redoing linebreaks to fit the current screen. wcstring reformat_for_screen(const wcstring &msg); -/** - Tokenize the specified string into the specified wcstring_list_t. - \param val the input string. The contents of this string is not changed. - \param out the list in which to place the elements. -*/ +/// Tokenize the specified string into the specified wcstring_list_t. +/// +/// \param val the input string. The contents of this string is not changed. +/// \param out the list in which to place the elements. void tokenize_variable_array(const wcstring &val, wcstring_list_t &out); -/** - Make sure the specified direcotry exists. If needed, try to create - it and any currently not existing parent directories.. - - \return 0 if, at the time of function return the directory exists, -1 otherwise. -*/ +/// Make sure the specified direcotry exists. If needed, try to create it and any currently not +/// existing parent directories. +/// +/// \return 0 if, at the time of function return the directory exists, -1 otherwise. int create_directory(const wcstring &d); -/** - Print a short message about how to file a bug report to stderr -*/ +/// Print a short message about how to file a bug report to stderr. void bugreport(); -/** - Return the number of seconds from the UNIX epoch, with subsecond - precision. This function uses the gettimeofday function, and will - have the same precision as that function. - - If an error occurs, NAN is returned. - */ +/// Return the number of seconds from the UNIX epoch, with subsecond precision. This function uses +/// the gettimeofday function, and will have the same precision as that function. If an error +/// occurs, NAN is returned. double timef(); -/** - Call the following function early in main to set the main thread. - This is our replacement for pthread_main_np(). - */ +/// Call the following function early in main to set the main thread. This is our replacement for +/// pthread_main_np(). void set_main_thread(); bool is_main_thread(); -/** Configures thread assertions for testing */ +/// Configures thread assertions for testing. void configure_thread_assertions_for_testing(); -/** Set up a guard to complain if we try to do certain things (like take a lock) after calling fork */ +/// Set up a guard to complain if we try to do certain things (like take a lock) after calling fork. void setup_fork_guards(void); -/** Save the value of tcgetpgrp so we can restore it on exit */ +/// Save the value of tcgetpgrp so we can restore it on exit. void save_term_foreground_process_group(void); void restore_term_foreground_process_group(void); -/** Return whether we are the child of a fork */ +/// Return whether we are the child of a fork. bool is_forked_child(void); void assert_is_not_forked_child(const char *who); #define ASSERT_IS_NOT_FORKED_CHILD_TRAMPOLINE(x) assert_is_not_forked_child(x) #define ASSERT_IS_NOT_FORKED_CHILD() ASSERT_IS_NOT_FORKED_CHILD_TRAMPOLINE(__FUNCTION__) -/** Macro to help suppress potentially unused variable warnings */ +/// Macro to help suppress potentially unused variable warnings. #define USE(var) (void)(var) extern "C" { - __attribute__((noinline)) void debug_thread_error(void); +__attribute__((noinline)) void debug_thread_error(void); } - #endif