aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar David Adam <zanchey@ucc.gu.uwa.edu.au>2016-05-15 22:08:43 +0000
committerGravatar David Adam <zanchey@ucc.gu.uwa.edu.au>2016-05-18 22:39:20 +0000
commit44757c81afc41d71917f71bd644b2f0092bb4053 (patch)
treef993347e134e109f425945cce826cd673e135b25
parentd0aa46158796196b79125573703024ae48c6c0dd (diff)
fallback: remove fwprintf and friends fallbacks
All modern operating systems implement fwprintf, including NetBSD (which introduced them in 2005). Work on #2999.
-rw-r--r--configure.ac2
-rw-r--r--src/fallback.cpp411
-rw-r--r--src/fallback.h32
3 files changed, 1 insertions, 444 deletions
diff --git a/configure.ac b/configure.ac
index 48fdaf35..c1d02404 100644
--- a/configure.ac
+++ b/configure.ac
@@ -310,7 +310,7 @@ AC_STRUCT_DIRENT_D_TYPE
# Check for presense of various functions used by fish
#
-AC_CHECK_FUNCS( wcsdup wcsndup wcslen wcscasecmp wcsncasecmp fwprintf )
+AC_CHECK_FUNCS( wcsdup wcsndup wcslen wcscasecmp wcsncasecmp )
AC_CHECK_FUNCS( futimes wcwidth wcswidth wcstok fputwc fgetwc )
AC_CHECK_FUNCS( wcstol wcslcat wcslcpy lrand48_r killpg )
AC_CHECK_FUNCS( backtrace backtrace_symbols_fd getifaddrs )
diff --git a/src/fallback.cpp b/src/fallback.cpp
index 15c5614f..518e907a 100644
--- a/src/fallback.cpp
+++ b/src/fallback.cpp
@@ -90,417 +90,6 @@ char *tparm_solaris_kludge(char *str, ...) {
#endif
-#ifndef HAVE_FWPRINTF
-#define INTERNAL_FWPRINTF 1
-#endif
-
-#ifdef INTERNAL_FWPRINTF
-
-/// Internal function for the wprintf fallbacks. USed to write the specified number of spaces.
-static void pad(void (*writer)(wchar_t), int count) {
- int i;
- if (count < 0) return;
-
- for (i = 0; i < count; i++) {
- writer(L' ');
- }
-}
-
-/// Generic formatting function. All other string formatting functions are secretly a wrapper around
-/// this function. vgprintf does not implement all the filters supported by printf, only those that
-/// are currently used by fish. vgprintf internally uses snprintf to implement the number outputs,
-/// such as %f and %x.
-///
-/// Currently supported functionality:
-///
-/// - precision specification, both through .* and .N
-/// - Padding through * and N
-/// - Right padding using the - prefix
-/// - long versions of all filters thorugh l and ll prefix
-/// - Character output using %c
-/// - String output through %s
-/// - Floating point number output through %f
-/// - Integer output through %d, %i, %u, %o, %x and %X
-///
-/// For a full description on the usage of *printf, see use 'man 3 printf'.
-static int vgwprintf(void (*writer)(wchar_t), const wchar_t *filter, va_list va) {
- const wchar_t *filter_org = filter;
- int count = 0;
-
- for (; *filter; filter++) {
- if (*filter == L'%') {
- int is_long = 0;
- int width = -1;
- filter++;
- int loop = 1;
- int precision = -1;
- int pad_left = 1;
-
- if (iswdigit(*filter)) {
- width = 0;
- while ((*filter >= L'0') && (*filter <= L'9')) {
- width = 10 * width + (*filter++ - L'0');
- }
- }
-
- while (loop) {
- switch (*filter) {
- case L'l': {
- // Long variable.
- is_long++;
- filter++;
- break;
- }
- case L'*': {
- // Set minimum field width.
- width = va_arg(va, int);
- filter++;
- break;
- }
- case L'-': {
- filter++;
- pad_left = 0;
- break;
- }
- case L'.': {
- // Set precision.
- filter++;
- if (*filter == L'*') {
- precision = va_arg(va, int);
- } else {
- precision = 0;
- while ((*filter >= L'0') && (*filter <= L'9')) {
- precision = 10 * precision + (*filter++ - L'0');
- }
- }
- break;
- }
- default: {
- loop = 0;
- break;
- }
- }
- }
-
- switch (*filter) {
- case L'c': {
- wchar_t c;
-
- if ((width >= 0) && pad_left) {
- pad(writer, width - 1);
- count += maxi(width - 1, 0);
- }
-
- c = is_long ? va_arg(va, wint_t) : btowc(va_arg(va, int));
- if (precision != 0) writer(c);
-
- if ((width >= 0) && !pad_left) {
- pad(writer, width - 1);
- count += maxi(width - 1, 0);
- }
-
- count++;
- break;
- }
- case L's': {
- wchar_t *ss = 0;
- wcstring wide_ss;
- if (is_long) {
- ss = va_arg(va, wchar_t *);
- } else {
- char *ns = va_arg(va, char *);
-
- if (ns) {
- wide_ss = str2wcstring(ns);
- ss = wide_ss.c_str();
- }
- }
-
- if (!ss) {
- return -1;
- }
-
- if ((width >= 0) && pad_left) {
- pad(writer, width - wcslen(ss));
- count += maxi(width - wcslen(ss), 0);
- }
-
- wchar_t *s = ss;
- int precount = count;
-
- while (*s) {
- if ((precision > 0) && (precision <= (count - precount))) break;
- writer(*(s++));
- count++;
- }
-
- if ((width >= 0) && !pad_left) {
- pad(writer, width - wcslen(ss));
- count += maxi(width - wcslen(ss), 0);
- }
-
- break;
- }
- case L'd':
- case L'i':
- case L'o':
- case L'u':
- case L'x':
- case L'X': {
- char str[33];
- char *pos;
- char format[16];
- int len;
-
- format[0] = 0;
- strcat(format, "%");
- if (precision >= 0) strcat(format, ".*");
- switch (is_long) {
- case 2: {
- strcat(format, "ll");
- break;
- }
- case 1: {
- strcat(format, "l");
- break;
- }
- }
-
- len = strlen(format);
- format[len++] = (char)*filter;
- format[len] = 0;
-
- switch (*filter) {
- case L'd':
- case L'i': {
- switch (is_long) {
- case 0: {
- int d = va_arg(va, int);
- if (precision >= 0)
- snprintf(str, 32, format, precision, d);
- else
- snprintf(str, 32, format, d);
-
- break;
- }
- case 1: {
- long d = va_arg(va, long);
- if (precision >= 0)
- snprintf(str, 32, format, precision, d);
- else
- snprintf(str, 32, format, d);
- break;
- }
- case 2: {
- long long d = va_arg(va, long long);
- if (precision >= 0)
- snprintf(str, 32, format, precision, d);
- else
- snprintf(str, 32, format, d);
- break;
- }
- default: {
- debug(0, L"Invalid length modifier in string %ls\n",
- filter_org);
- return -1;
- }
- }
- break;
- }
-
- case L'u':
- case L'o':
- case L'x':
- case L'X': {
- switch (is_long) {
- case 0: {
- unsigned d = va_arg(va, unsigned);
- if (precision >= 0)
- snprintf(str, 32, format, precision, d);
- else
- snprintf(str, 32, format, d);
- break;
- }
- case 1: {
- unsigned long d = va_arg(va, unsigned long);
- if (precision >= 0)
- snprintf(str, 32, format, precision, d);
- else
- snprintf(str, 32, format, d);
- break;
- }
- case 2: {
- unsigned long long d = va_arg(va, unsigned long long);
- if (precision >= 0)
- snprintf(str, 32, format, precision, d);
- else
- snprintf(str, 32, format, d);
- break;
- }
- default: {
- debug(0, L"Invalid length modifier in string %ls\n",
- filter_org);
- return -1;
- }
- }
- break;
- }
- default: {
- debug(0, L"Invalid filter %ls in string %ls\n", *filter, filter_org);
- return -1;
- }
- }
-
- if ((width >= 0) && pad_left) {
- int l = maxi(width - strlen(str), 0);
- pad(writer, l);
- count += l;
- }
-
- pos = str;
-
- while (*pos) {
- writer(*(pos++));
- count++;
- }
-
- if ((width >= 0) && !pad_left) {
- int l = maxi(width - strlen(str), 0);
- pad(writer, l);
- count += l;
- }
-
- break;
- }
-
- case L'f': {
- char str[32];
- char *pos;
- double val = va_arg(va, double);
-
- if (precision >= 0) {
- if (width >= 0) {
- snprintf(str, 32, "%*.*f", width, precision, val);
- } else {
- snprintf(str, 32, "%.*f", precision, val);
- }
- } else {
- if (width >= 0) {
- snprintf(str, 32, "%*f", width, val);
- } else {
- snprintf(str, 32, "%f", val);
- }
- }
-
- pos = str;
-
- while (*pos) {
- writer(*(pos++));
- count++;
- }
-
- break;
- }
-
- case L'n': {
- int *n = va_arg(va, int *);
-
- *n = count;
- break;
- }
- case L'%': {
- writer('%');
- count++;
- break;
- }
- default: {
- debug(0, L"Unknown switch %lc in string %ls\n", *filter, filter_org);
- return -1;
- }
- }
- } else {
- writer(*filter);
- count++;
- }
- }
-
- return count;
-}
-
-/// Holds data for swprintf writer.
-static struct {
- int count;
- int max;
- wchar_t *pos;
-} sw_data;
-
-/// Writers for string output.
-static void sw_writer(wchar_t c) {
- if (sw_data.count < sw_data.max) *(sw_data.pos++) = c;
- sw_data.count++;
-}
-
-int vswprintf(wchar_t *out, size_t n, const wchar_t *filter, va_list va) {
- int written;
-
- sw_data.pos = out;
- sw_data.max = n;
- sw_data.count = 0;
- written = vgwprintf(&sw_writer, filter, va);
- if (written < n) {
- *sw_data.pos = 0;
- } else {
- written = -1;
- }
-
- return written;
-}
-
-int swprintf(wchar_t *out, size_t n, const wchar_t *filter, ...) {
- va_list va;
- int written;
-
- va_start(va, filter);
- written = vswprintf(out, n, filter, va);
- va_end(va);
- return written;
-}
-
-/// Holds auxiliary data for fwprintf and wprintf writer.
-static FILE *fw_data;
-
-static void fw_writer(wchar_t c) { fputwc(c, fw_data); }
-
-/// Writers for file output.
-int vfwprintf(FILE *f, const wchar_t *filter, va_list va) {
- fw_data = f;
- return vgwprintf(&fw_writer, filter, va);
-}
-
-int fwprintf(FILE *f, const wchar_t *filter, ...) {
- va_list va;
- int written;
-
- va_start(va, filter);
- written = vfwprintf(f, filter, va);
- va_end(va);
- return written;
-}
-
-int vwprintf(const wchar_t *filter, va_list va) { return vfwprintf(stdout, filter, va); }
-
-int wprintf(const wchar_t *filter, ...) {
- va_list va;
- int written;
-
- va_start(va, filter);
- written = vwprintf(filter, va);
- va_end(va);
- return written;
-}
-
-#endif
-
#ifndef HAVE_FGETWC
wint_t fgetwc(FILE *stream) {
wchar_t res;
diff --git a/src/fallback.h b/src/fallback.h
index 241edb5a..13caf0b3 100644
--- a/src/fallback.h
+++ b/src/fallback.h
@@ -63,38 +63,6 @@ struct winsize {
char *tparm_solaris_kludge(char *str, ...);
#endif
-#ifndef HAVE_FWPRINTF
-/// Print formated string. Some operating systems (Like NetBSD) do not have wide string formating
-/// functions. Therefore we implement our own. Not at all complete. Supports wide and narrow
-/// characters, strings and decimal numbers, position (%n), field width and precision.
-int fwprintf(FILE *f, const wchar_t *format, ...);
-
-/// Print formated string. Some operating systems (Like NetBSD) do not have wide string formating
-/// functions. Therefore we define our own. Not at all complete. Supports wide and narrow
-/// characters, strings and decimal numbers, position (%n), field width and precision.
-int swprintf(wchar_t *str, size_t l, const wchar_t *format, ...);
-
-/// Print formated string. Some operating systems (Like NetBSD) do not have wide string formating
-/// functions. Therefore we define our own. Not at all complete. Supports wide and narrow
-/// characters, strings and decimal numbers, position (%n), field width and precision.
-int wprintf(const wchar_t *format, ...);
-
-/// Print formated string. Some operating systems (Like NetBSD) do not have wide string formating
-/// functions. Therefore we define our own. Not at all complete. Supports wide and narrow
-/// characters, strings and decimal numbers, position (%n), field width and precision.
-int vwprintf(const wchar_t *filter, va_list va);
-
-/// Print formated string. Some operating systems (Like NetBSD) do not have wide string formating
-/// functions. Therefore we define our own. Not at all complete. Supports wide and narrow
-/// characters, strings and decimal numbers, position (%n), field width and precision.
-int vfwprintf(FILE *f, const wchar_t *filter, va_list va);
-
-/// Print formated string. Some operating systems (Like NetBSD) do not have wide string formating
-/// functions. Therefore we define our own. Not at all complete. Supports wide and narrow
-/// characters, strings and decimal numbers, position (%n), field width and precision.
-int vswprintf(wchar_t *out, size_t n, const wchar_t *filter, va_list va);
-#endif
-
#ifndef HAVE_FGETWC
// Fallback implementation of fgetwc.
wint_t fgetwc(FILE *stream);