From 2401a163fe418310a1ed015b0d4fc8402740ff79 Mon Sep 17 00:00:00 2001 From: axel Date: Tue, 28 Feb 2006 23:17:16 +1000 Subject: [PATCH] Move all fallbacks for standard and not-so-standard unix functions to fallback.c, in order to have a one-stop place to look for such functions darcs-hash:20060228131716-ac50b-0832193dbcaf7191dcb24456dc40f2e861a1382e.gz --- Makefile.in | 2 +- builtin.c | 3 + builtin_commandline.c | 3 + builtin_complete.c | 3 + builtin_set.c | 3 + builtin_ulimit.c | 3 + common.c | 3 + complete.c | 3 + env.c | 3 + env_universal.c | 3 + env_universal_common.c | 3 + event.c | 3 + exec.c | 3 + expand.c | 3 + fallback.c | 882 +++++++++++++++++++++++++++++++++++++++++ fallback.h | 192 +++++++++ fish_pager.c | 3 + fish_tests.c | 3 + fishd.c | 3 + function.c | 3 + halloc.c | 3 + halloc_util.c | 3 + highlight.c | 3 + history.c | 3 + input.c | 3 + input_common.c | 3 + intern.c | 3 + io.c | 3 + kill.c | 3 + main.c | 3 + mimedb.c | 3 + output.c | 13 +- parse_util.c | 3 + parser.c | 3 + proc.c | 3 + reader.c | 3 + sanity.c | 3 + set_color.c | 1 + signal.c | 3 + tokenizer.c | 3 + translate.c | 3 + util.c | 3 + wgetopt.c | 1 + wildcard.c | 3 + wutil.c | 831 +------------------------------------- wutil.h | 178 +-------- 46 files changed, 1199 insertions(+), 1015 deletions(-) create mode 100644 fallback.c create mode 100644 fallback.h diff --git a/Makefile.in b/Makefile.in index 7c0888e3c..5a9061370 100644 --- a/Makefile.in +++ b/Makefile.in @@ -57,7 +57,7 @@ ETC_DIR_INSTALL = etc/fish_interactive.fish # Set to 1 if we have gettext HAVE_GETTEXT=@HAVE_GETTEXT@ -CORE_OBJS := util.o common.o halloc.o halloc_util.o +CORE_OBJS := util.o common.o halloc.o halloc_util.o fallback.o # All objects used by fish, that are compiled from an ordinary .c file # using an ordinary .h file. diff --git a/builtin.c b/builtin.c index dee20bff6..62f7911f6 100644 --- a/builtin.c +++ b/builtin.c @@ -38,7 +38,10 @@ #include #include "config.h" + +#include "fallback.h" #include "util.h" + #include "wutil.h" #include "builtin.h" #include "function.h" diff --git a/builtin_commandline.c b/builtin_commandline.c index 224b7e7db..500a27dec 100644 --- a/builtin_commandline.c +++ b/builtin_commandline.c @@ -12,7 +12,10 @@ Functions used for implementing the commandline builtin. #include #include "config.h" + +#include "fallback.h" #include "util.h" + #include "wutil.h" #include "builtin.h" #include "common.h" diff --git a/builtin_complete.c b/builtin_complete.c index e9f315aa7..13877c924 100644 --- a/builtin_complete.c +++ b/builtin_complete.c @@ -12,7 +12,10 @@ Functions used for implementing the complete builtin. #include #include "config.h" + +#include "fallback.h" #include "util.h" + #include "wutil.h" #include "builtin.h" #include "common.h" diff --git a/builtin_set.c b/builtin_set.c index 3a2f75454..5383456e1 100644 --- a/builtin_set.c +++ b/builtin_set.c @@ -12,7 +12,10 @@ Functions used for implementing the set builtin. #include #include "config.h" + +#include "fallback.h" #include "util.h" + #include "wutil.h" #include "builtin.h" #include "env.h" diff --git a/builtin_ulimit.c b/builtin_ulimit.c index f20e7ec88..13af9cd5a 100644 --- a/builtin_ulimit.c +++ b/builtin_ulimit.c @@ -13,7 +13,10 @@ Functions used for implementing the ulimit builtin. #include #include "config.h" + +#include "fallback.h" #include "util.h" + #include "builtin.h" #include "common.h" #include "wgetopt.h" diff --git a/common.c b/common.c index 76da6eba8..fa9ad60f0 100644 --- a/common.c +++ b/common.c @@ -6,6 +6,7 @@ parts of fish. #include "config.h" + #include #include #include @@ -50,7 +51,9 @@ parts of fish. #include #endif +#include "fallback.h" #include "util.h" + #include "wutil.h" #include "common.h" #include "expand.h" diff --git a/complete.c b/complete.c index cc7fa2ca2..c79195679 100644 --- a/complete.c +++ b/complete.c @@ -21,7 +21,10 @@ #include #include "config.h" + +#include "fallback.h" #include "util.h" + #include "tokenizer.h" #include "wildcard.h" #include "proc.h" diff --git a/env.c b/env.c index 54c53de47..45075e0f2 100644 --- a/env.c +++ b/env.c @@ -33,7 +33,10 @@ #include + +#include "fallback.h" #include "util.h" + #include "wutil.h" #include "proc.h" #include "common.h" diff --git a/env_universal.c b/env_universal.c index ab817e4d2..48e0697dc 100644 --- a/env_universal.c +++ b/env_universal.c @@ -1,5 +1,6 @@ #include "config.h" + #include #include #include @@ -26,7 +27,9 @@ #include +#include "fallback.h" #include "util.h" + #include "common.h" #include "wutil.h" #include "env_universal_common.h" diff --git a/env_universal_common.c b/env_universal_common.c index 07123e0ca..2d39fc51e 100644 --- a/env_universal_common.c +++ b/env_universal_common.c @@ -7,6 +7,7 @@ */ #include "config.h" + #include #include #include @@ -27,7 +28,9 @@ #include #include +#include "fallback.h" #include "util.h" + #include "common.h" #include "wutil.h" #include "env_universal_common.h" diff --git a/event.c b/event.c index d7004ba2f..f45c95f4b 100644 --- a/event.c +++ b/event.c @@ -12,7 +12,10 @@ #include #include "config.h" + +#include "fallback.h" #include "util.h" + #include "wutil.h" #include "function.h" #include "proc.h" diff --git a/exec.c b/exec.c index 627fec476..9dff5985a 100644 --- a/exec.c +++ b/exec.c @@ -22,7 +22,10 @@ #include #include "config.h" + +#include "fallback.h" #include "util.h" + #include "common.h" #include "wutil.h" #include "proc.h" diff --git a/expand.c b/expand.c index 4664a8b4c..764cd72af 100644 --- a/expand.c +++ b/expand.c @@ -27,7 +27,10 @@ parameter expansion. #endif #include "config.h" + +#include "fallback.h" #include "util.h" + #include "common.h" #include "wutil.h" #include "env.h" diff --git a/fallback.c b/fallback.c new file mode 100644 index 000000000..de9fe23a4 --- /dev/null +++ b/fallback.c @@ -0,0 +1,882 @@ +/** + This file only contains fallback implementations of functions which + have been found to be missing or broken by the configuration + scripts. +*/ + +#include "config.h" + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if HAVE_NCURSES_H +#include +#else +#include +#endif + +#if HAVE_TERMIO_H +#include +#endif + +#if HAVE_TERM_H +#include +#elif HAVE_NCURSES_TERM_H +#include +#endif + +#ifdef TPUTS_KLUDGE + +int tputs(const char *str, int affcnt, int (*putc)(tputs_arg_t)) +{ + while( *str ) + { + putc( *str++ ); + } +} + +#endif + + + +#if !HAVE_FWPRINTF + +void pad( void (*writer)(wchar_t), int count) +{ + + int i; + if( count < 0 ) + return; + + for( i=0; i= 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; + if( is_long ) + { + ss = va_arg(va, wchar_t *); + } + else + { + char *ns = va_arg(va, char*); + + if( ns ) + { + ss = str2wcs( ns ); + } + } + + 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 ); + } + + if( !is_long ) + free( ss ); + + 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 ) +{ + putwc( 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=0; + mbstate_t state; + memset (&state, '\0', sizeof (state)); + + while(1) + { + int b = fgetc( stream ); + char bb; + + int sz; + + if( b == EOF ) + return WEOF; + + bb=b; + + sz = mbrtowc( &res, &bb, 1, &state ); + + switch( sz ) + { + case -1: + memset (&state, '\0', sizeof (state)); + return WEOF; + + case -2: + break; + case 0: + return 0; + default: + return res; + } + } + +} + + +wint_t getwc(FILE *stream) +{ + return fgetwc( stream ); +} + + +#endif + +#ifndef HAVE_FPUTWC + +wint_t fputwc(wchar_t wc, FILE *stream) +{ + int res; + char s[MB_CUR_MAX+1]; + memset( s, 0, MB_CUR_MAX+1 ); + wctomb( s, wc ); + res = fputs( s, stream ); + return res==EOF?WEOF:wc; +} + +wint_t putwc(wchar_t wc, FILE *stream) +{ + return fputwc( wc, stream ); +} + +#endif + +#ifndef HAVE_WCSTOK + +/* + Used by fallback wcstok. Borrowed from glibc +*/ +static size_t fish_wcsspn (const wchar_t *wcs, + const wchar_t *accept ) +{ + register const wchar_t *p; + register const wchar_t *a; + register size_t count = 0; + + for (p = wcs; *p != L'\0'; ++p) + { + for (a = accept; *a != L'\0'; ++a) + if (*p == *a) + break; + + if (*a == L'\0') + return count; + else + ++count; + } + return count; +} + +/* + Used by fallback wcstok. Borrowed from glibc +*/ +static wchar_t *fish_wcspbrk (const wchar_t *wcs, const wchar_t *accept) +{ + while (*wcs != L'\0') + if (wcschr (accept, *wcs) == NULL) + ++wcs; + else + return (wchar_t *) wcs; + return NULL; +} + +/* + Fallback wcstok implementation. Borrowed from glibc. +*/ +wchar_t *wcstok(wchar_t *wcs, const wchar_t *delim, wchar_t **save_ptr) +{ + wchar_t *result; + + if (wcs == NULL) + { + if (*save_ptr == NULL) + { + errno = EINVAL; + return NULL; + } + else + wcs = *save_ptr; + } + + /* Scan leading delimiters. */ + wcs += fish_wcsspn (wcs, delim); + + if (*wcs == L'\0') + { + *save_ptr = NULL; + return NULL; + } + + /* Find the end of the token. */ + result = wcs; + + wcs = fish_wcspbrk (result, delim); + + if (wcs == NULL) + { + /* This token finishes the string. */ + *save_ptr = NULL; + } + else + { + /* Terminate the token and make *SAVE_PTR point past it. */ + *wcs = L'\0'; + *save_ptr = wcs + 1; + } + return result; +} + +#endif + +#ifndef HAVE_WCSDUP +wchar_t *wcsdup( const wchar_t *in ) +{ + size_t len=wcslen(in); + wchar_t *out = malloc( sizeof( wchar_t)*(len+1)); + if( out == 0 ) + { + return 0; + } + + memcpy( out, in, sizeof( wchar_t)*(len+1)); + return out; + +} +#endif + +#ifndef HAVE_WCSLEN +size_t wcslen(const wchar_t *in) +{ + const wchar_t *end=in; + while( *end ) + end++; + return end-in; +} +#endif + + +#ifndef HAVE_WCSCASECMP +int wcscasecmp( const wchar_t *a, const wchar_t *b ) +{ + if( *a == 0 ) + { + return (*b==0)?0:-1; + } + else if( *b == 0 ) + { + return 1; + } + int diff = towlower(*a)-towlower(*b); + if( diff != 0 ) + return diff; + else + return wcscasecmp( a+1,b+1); +} +#endif + + +#ifndef HAVE_WCSNCASECMP +int wcsncasecmp( const wchar_t *a, const wchar_t *b, int count ) +{ + if( count == 0 ) + return 0; + + if( *a == 0 ) + { + return (*b==0)?0:-1; + } + else if( *b == 0 ) + { + return 1; + } + int diff = towlower(*a)-towlower(*b); + if( diff != 0 ) + return diff; + else + return wcsncasecmp( a+1,b+1, count-1); +} +#endif + +#ifndef HAVE_WCWIDTH +int wcwidth( wchar_t c ) +{ + if( c < 32 ) + return 0; + if ( c == 127 ) + return 0; + return 1; +} +#endif + +#ifndef HAVE_WCSNDUP +wchar_t *wcsndup( const wchar_t *in, int c ) +{ + wchar_t *res = malloc( sizeof(wchar_t)*(c+1) ); + if( res == 0 ) + { + return 0; + } + wcsncpy( res, in, c+1 ); + res[c] = L'\0'; + return res; +} +#endif + +long convert_digit( wchar_t d, int base ) +{ + long res=-1; + if( (d <= L'9') && (d >= L'0') ) + { + res = d - L'0'; + } + else if( (d <= L'z') && (d >= L'a') ) + { + res = d + 10 - L'a'; + } + else if( (d <= L'Z') && (d >= L'A') ) + { + res = d + 10 - L'A'; + } + if( res >= base ) + { + res = -1; + } + + return res; +} + +#ifndef HAVE_WCSTOL +long wcstol(const wchar_t *nptr, + wchar_t **endptr, + int base) +{ + long long res=0; + int is_set=0; + if( base > 36 ) + { + errno = EINVAL; + return 0; + } + + while( 1 ) + { + long nxt = convert_digit( *nptr, base ); + if( endptr != 0 ) + *endptr = (wchar_t *)nptr; + if( nxt < 0 ) + { + if( !is_set ) + { + errno = EINVAL; + } + return res; + } + res = (res*base)+nxt; + is_set = 1; + if( res > LONG_MAX ) + { + errno = ERANGE; + return LONG_MAX; + } + if( res < LONG_MIN ) + { + errno = ERANGE; + return LONG_MIN; + } + nptr++; + } +} +#endif + + diff --git a/fallback.h b/fallback.h new file mode 100644 index 000000000..c4e1312a1 --- /dev/null +++ b/fallback.h @@ -0,0 +1,192 @@ + +#ifndef FISH_FALLBACK_H +#define FISH_FALLBACK_H + +#ifdef TPUTS_KLUDGE + +/** + Linux on PPC seems to have a tputs implementation that sometimes + behaves strangely. This fallback seems to fix things. +*/ +int tputs(const char *str, int affcnt, int (*putc)(tputs_arg_t)); + +#endif + +/* + Here follows the prototypes for fallback implementations of various + standarcs libc functions relating to wide character support. Some of + these prototypes are always defined, since some libc versions + include the code, but you have to use special magical #defines for + the prototype to appear. +*/ + +#if !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); + +/** + Fallback implementation of getwc +*/ +wint_t getwc(FILE *stream); + +#endif + +#ifndef HAVE_FPUTWC + +/** + Fallback implementation of fputwc +*/ +wint_t fputwc(wchar_t wc, FILE *stream); +/** + Fallback implementation of putwc +*/ +wint_t putwc(wchar_t wc, FILE *stream); + +#endif + +#ifndef HAVE_WCSTOK +/** + Fallback implementation of wcstok. Uses code borrowed from glibc. +*/ +wchar_t *wcstok(wchar_t *wcs, const wchar_t *delim, wchar_t **ptr); + +#endif + +/** + Return the number of columns used by a character. This is a libc + function, but the prototype for this function is missing in some libc + implementations. + + Fish has a fallback implementation in case the implementation is + missing altogether. In locales without a native wcwidth, Unicode + is probably so broken that it isn't worth trying to implement a + real wcwidth. Therefore, the fallback wcwidth assumes any printing + character takes up one column and anything else uses 0 columns. +*/ +int wcwidth( wchar_t c ); + +/** + Create a duplicate string. Wide string version of strdup. Will + automatically exit if out of memory. +*/ +wchar_t *wcsdup(const wchar_t *in); + +size_t wcslen(const wchar_t *in); + +/** + Case insensitive string compare function. Wide string version of + strcasecmp. + + This implementation of wcscasecmp does not take into account + esoteric locales where uppercase and lowercase do not cleanly + transform between each other. Hopefully this should be fine since + fish only uses this function with one of the strings supplied by + fish and guaranteed to be a sane, english word. Using wcscasecmp on + a user-supplied string should be considered a bug. +*/ +int wcscasecmp( const wchar_t *a, const wchar_t *b ); + +/** + Case insensitive string compare function. Wide string version of + strncasecmp. + + This implementation of wcsncasecmp does not take into account + esoteric locales where uppercase and lowercase do not cleanly + transform between each other. Hopefully this should be fine since + fish only uses this function with one of the strings supplied by + fish and guaranteed to be a sane, english word. Using wcsncasecmp on + a user-supplied string should be considered a bug. +*/ +int wcsncasecmp( const wchar_t *a, const wchar_t *b, int count ); + +/** + Returns a newly allocated wide character string wich is a copy of + the string in, but of length c or shorter. The returned string is + always null terminated, and the null is not included in the string + length. +*/ +wchar_t *wcsndup( const wchar_t *in, int c ); + +/** + Converts from wide char to digit in the specified base. If d is not + a valid digit in the specified base, return -1. +*/ +long convert_digit( wchar_t d, int base ); + +/** + Fallback implementation. Convert a wide character string to a + number in the specified base. This functions is the wide character + string equivalent of strtol. For bases of 10 or lower, 0..9 are + used to represent numbers. For bases below 36, a-z and A-Z are used + to represent numbers higher than 9. Higher bases than 36 are not + supported. +*/ +long wcstol(const wchar_t *nptr, + wchar_t **endptr, + int base); + + + +#endif diff --git a/fish_pager.c b/fish_pager.c index 5d9ef1ec0..9fbf17fad 100644 --- a/fish_pager.c +++ b/fish_pager.c @@ -35,7 +35,10 @@ #include + +#include "fallback.h" #include "util.h" + #include "wutil.h" #include "common.h" #include "complete.h" diff --git a/fish_tests.c b/fish_tests.c index 2275eccda..7328d2c9c 100644 --- a/fish_tests.c +++ b/fish_tests.c @@ -4,6 +4,7 @@ #include "config.h" + #include #include #include @@ -26,7 +27,9 @@ #include #include +#include "fallback.h" #include "util.h" + #include "common.h" #include "proc.h" #include "reader.h" diff --git a/fishd.c b/fishd.c index 7afc11874..c78a0fcf3 100644 --- a/fishd.c +++ b/fishd.c @@ -41,6 +41,7 @@ time the original barrier request was sent have been received. #include "config.h" + #include #include #include @@ -61,7 +62,9 @@ time the original barrier request was sent have been received. #include #include +#include "fallback.h" #include "util.h" + #include "common.h" #include "wutil.h" #include "env_universal_common.h" diff --git a/function.c b/function.c index 8e77de3a3..4cac79f08 100644 --- a/function.c +++ b/function.c @@ -9,8 +9,11 @@ #include #include "config.h" + #include "wutil.h" +#include "fallback.h" #include "util.h" + #include "function.h" #include "proc.h" #include "parser.h" diff --git a/halloc.c b/halloc.c index 996a4cb56..dbfbf8ebf 100644 --- a/halloc.c +++ b/halloc.c @@ -8,10 +8,13 @@ #include "config.h" + #include #include +#include "fallback.h" #include "util.h" + #include "common.h" #include "halloc.h" diff --git a/halloc_util.c b/halloc_util.c index 3213fd70a..a5d8ae81f 100644 --- a/halloc_util.c +++ b/halloc_util.c @@ -8,11 +8,14 @@ #include "config.h" + #include #include #include +#include "fallback.h" #include "util.h" + #include "common.h" #include "halloc.h" diff --git a/highlight.c b/highlight.c index 51f336654..6ebcb00fc 100644 --- a/highlight.c +++ b/highlight.c @@ -12,7 +12,10 @@ #include #include "config.h" + +#include "fallback.h" #include "util.h" + #include "wutil.h" #include "highlight.h" #include "tokenizer.h" diff --git a/history.c b/history.c index ae1da8787..112e7cfe3 100644 --- a/history.c +++ b/history.c @@ -12,7 +12,10 @@ #include "config.h" + +#include "fallback.h" #include "util.h" + #include "wutil.h" #include "history.h" #include "common.h" diff --git a/input.c b/input.c index 0352766a9..9c81fb803 100644 --- a/input.c +++ b/input.c @@ -43,7 +43,10 @@ implementation in fish is as of yet incomplete. #include + +#include "fallback.h" #include "util.h" + #include "wutil.h" #include "reader.h" #include "proc.h" diff --git a/input_common.c b/input_common.c index 2f034e95c..a7abc8009 100644 --- a/input_common.c +++ b/input_common.c @@ -5,6 +5,7 @@ Implementation file for the low level input library */ #include "config.h" + #include #include #include @@ -15,7 +16,9 @@ Implementation file for the low level input library #include +#include "fallback.h" #include "util.h" + #include "common.h" #include "wutil.h" #include "input_common.h" diff --git a/intern.c b/intern.c index c52027f78..d54c69f9e 100644 --- a/intern.c +++ b/intern.c @@ -5,12 +5,15 @@ */ #include "config.h" + #include #include #include #include +#include "fallback.h" #include "util.h" + #include "wutil.h" #include "common.h" #include "intern.h" diff --git a/io.c b/io.c index de36e56e2..7d515b2ed 100644 --- a/io.c +++ b/io.c @@ -5,6 +5,7 @@ Utilities for io redirection. */ #include "config.h" + #include #include #include @@ -31,7 +32,9 @@ Utilities for io redirection. #include #endif +#include "fallback.h" #include "util.h" + #include "wutil.h" #include "exec.h" #include "common.h" diff --git a/kill.c b/kill.c index b4a2a7d75..32ed1dcf7 100644 --- a/kill.c +++ b/kill.c @@ -18,7 +18,10 @@ #include "config.h" + +#include "fallback.h" #include "util.h" + #include "wutil.h" #include "kill.h" #include "proc.h" diff --git a/main.c b/main.c index d65fc9ed7..8e9dac8e9 100644 --- a/main.c +++ b/main.c @@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "config.h" + #include #include #include @@ -40,7 +41,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #include +#include "fallback.h" #include "util.h" + #include "common.h" #include "reader.h" #include "builtin.h" diff --git a/mimedb.c b/mimedb.c index c33ef0595..19173c59f 100644 --- a/mimedb.c +++ b/mimedb.c @@ -21,6 +21,7 @@ license. Read the source code of the library for more information. #include "config.h" + #include #include #include @@ -43,8 +44,10 @@ license. Read the source code of the library for more information. #endif #include "xdgmime.h" +#include "fallback.h" #include "util.h" + /** Location of the applications .desktop file, relative to a base mime directory */ diff --git a/output.c b/output.c index 9c9c87131..dda4aa2ee 100644 --- a/output.c +++ b/output.c @@ -38,7 +38,10 @@ #include #include + +#include "fallback.h" #include "util.h" + #include "wutil.h" #include "expand.h" #include "common.h" @@ -292,15 +295,7 @@ int writeb( tputs_arg_t b ) int writembs( char *str ) { -#ifdef TPUTS_KLUDGE - while( *str ) - { - out( *str ); - } -#else - tputs(str,1,writeb); -#endif - return 0; + return tputs(str,1,&writeb)==ERR?1:0; } int writech( wint_t ch ) diff --git a/parse_util.c b/parse_util.c index 18ffad8a2..a326b6465 100644 --- a/parse_util.c +++ b/parse_util.c @@ -6,6 +6,7 @@ #include "config.h" + #include #include #include @@ -17,7 +18,9 @@ #include #include +#include "fallback.h" #include "util.h" + #include "wutil.h" #include "common.h" #include "tokenizer.h" diff --git a/parser.c b/parser.c index a5e613551..9ab8b5ca1 100644 --- a/parser.c +++ b/parser.c @@ -18,7 +18,10 @@ The fish parser. Contains functions for parsing code. #include #include "config.h" + +#include "fallback.h" #include "util.h" + #include "common.h" #include "wutil.h" #include "proc.h" diff --git a/proc.c b/proc.c index 6fe85395a..5ea4f7e33 100644 --- a/proc.c +++ b/proc.c @@ -42,7 +42,10 @@ Some of the code in this file is based on code from the Glibc manual. #include #endif + +#include "fallback.h" #include "util.h" + #include "wutil.h" #include "proc.h" #include "common.h" diff --git a/reader.c b/reader.c index 8e87b5d61..d654b9f70 100644 --- a/reader.c +++ b/reader.c @@ -59,7 +59,10 @@ commence. #include + +#include "fallback.h" #include "util.h" + #include "wutil.h" #include "highlight.h" #include "reader.h" diff --git a/sanity.c b/sanity.c index 1a3423276..a20d1f509 100644 --- a/sanity.c +++ b/sanity.c @@ -14,7 +14,10 @@ #include "config.h" + +#include "fallback.h" #include "util.h" + #include "common.h" #include "sanity.h" #include "proc.h" diff --git a/set_color.c b/set_color.c index 5ac2d5643..5228987e2 100644 --- a/set_color.c +++ b/set_color.c @@ -1,5 +1,6 @@ #include "config.h" + #include #include #include diff --git a/signal.c b/signal.c index 108af53e0..71ba0360a 100644 --- a/signal.c +++ b/signal.c @@ -6,6 +6,7 @@ The library for various signal related issues #include "config.h" + #include #include #include @@ -15,7 +16,9 @@ The library for various signal related issues #include #include "common.h" +#include "fallback.h" #include "util.h" + #include "wutil.h" #include "signal.h" #include "event.h" diff --git a/tokenizer.c b/tokenizer.c index ee9f7eb22..8548852bd 100644 --- a/tokenizer.c +++ b/tokenizer.c @@ -15,7 +15,10 @@ #include #include + +#include "fallback.h" #include "util.h" + #include "wutil.h" #include "tokenizer.h" #include "common.h" diff --git a/translate.c b/translate.c index 4a109ecdd..23de015a0 100644 --- a/translate.c +++ b/translate.c @@ -6,6 +6,7 @@ Translation library, internally uses catgets #include "config.h" + #include #include #include @@ -16,7 +17,9 @@ Translation library, internally uses catgets #endif #include "common.h" +#include "fallback.h" #include "util.h" + #include "halloc_util.h" #if HAVE_GETTEXT diff --git a/util.c b/util.c index bf875370a..608b9a3f1 100644 --- a/util.c +++ b/util.c @@ -6,6 +6,7 @@ #include "config.h" + #include #include #include @@ -22,7 +23,9 @@ #include +#include "fallback.h" #include "util.h" + #include "common.h" #include "wutil.h" diff --git a/wgetopt.c b/wgetopt.c index c6bf2a6f0..d63fc7593 100644 --- a/wgetopt.c +++ b/wgetopt.c @@ -94,6 +94,7 @@ #include "wutil.h" + /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. diff --git a/wildcard.c b/wildcard.c index 7c31f6a1f..0c0243d61 100644 --- a/wildcard.c +++ b/wildcard.c @@ -18,7 +18,10 @@ wildcards using **. #include #include + +#include "fallback.h" #include "util.h" + #include "wutil.h" #include "complete.h" #include "common.h" diff --git a/wutil.c b/wutil.c index 42be86718..8cd1c316e 100644 --- a/wutil.c +++ b/wutil.c @@ -20,7 +20,10 @@ #include #include + +#include "fallback.h" #include "util.h" + #include "common.h" #include "wutil.h" @@ -329,831 +332,3 @@ wchar_t *wrealpath(const wchar_t *pathname, wchar_t *resolved_path) } #endif - -#if !HAVE_FWPRINTF - -void pad( void (*writer)(wchar_t), int count) -{ - - int i; - if( count < 0 ) - return; - - for( i=0; i= 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; - if( is_long ) - { - ss = va_arg(va, wchar_t *); - } - else - { - char *ns = va_arg(va, char*); - - if( ns ) - { - ss = str2wcs( ns ); - } - } - - 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 ); - } - - if( !is_long ) - free( ss ); - - 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 ) -{ - putwc( 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=0; - mbstate_t state; - memset (&state, '\0', sizeof (state)); - - while(1) - { - int b = fgetc( stream ); - char bb; - - int sz; - - if( b == EOF ) - return WEOF; - - bb=b; - - sz = mbrtowc( &res, &bb, 1, &state ); - - switch( sz ) - { - case -1: - memset (&state, '\0', sizeof (state)); - return WEOF; - - case -2: - break; - case 0: - return 0; - default: - return res; - } - } - -} - - -wint_t getwc(FILE *stream) -{ - return fgetwc( stream ); -} - - -#endif - -#ifndef HAVE_FPUTWC - -wint_t fputwc(wchar_t wc, FILE *stream) -{ - int res; - char s[MB_CUR_MAX+1]; - memset( s, 0, MB_CUR_MAX+1 ); - wctomb( s, wc ); - res = fputs( s, stream ); - return res==EOF?WEOF:wc; -} - -wint_t putwc(wchar_t wc, FILE *stream) -{ - return fputwc( wc, stream ); -} - -#endif - -#ifndef HAVE_WCSTOK - -/* - Used by fallback wcstok. Borrowed from glibc -*/ -static size_t fish_wcsspn (const wchar_t *wcs, - const wchar_t *accept ) -{ - register const wchar_t *p; - register const wchar_t *a; - register size_t count = 0; - - for (p = wcs; *p != L'\0'; ++p) - { - for (a = accept; *a != L'\0'; ++a) - if (*p == *a) - break; - - if (*a == L'\0') - return count; - else - ++count; - } - return count; -} - -/* - Used by fallback wcstok. Borrowed from glibc -*/ -static wchar_t *fish_wcspbrk (const wchar_t *wcs, const wchar_t *accept) -{ - while (*wcs != L'\0') - if (wcschr (accept, *wcs) == NULL) - ++wcs; - else - return (wchar_t *) wcs; - return NULL; -} - -/* - Fallback wcstok implementation. Borrowed from glibc. -*/ -wchar_t *wcstok(wchar_t *wcs, const wchar_t *delim, wchar_t **save_ptr) -{ - wchar_t *result; - - if (wcs == NULL) - { - if (*save_ptr == NULL) - { - errno = EINVAL; - return NULL; - } - else - wcs = *save_ptr; - } - - /* Scan leading delimiters. */ - wcs += fish_wcsspn (wcs, delim); - - if (*wcs == L'\0') - { - *save_ptr = NULL; - return NULL; - } - - /* Find the end of the token. */ - result = wcs; - - wcs = fish_wcspbrk (result, delim); - - if (wcs == NULL) - { - /* This token finishes the string. */ - *save_ptr = NULL; - } - else - { - /* Terminate the token and make *SAVE_PTR point past it. */ - *wcs = L'\0'; - *save_ptr = wcs + 1; - } - return result; -} - -#endif - -#ifndef HAVE_WCSDUP -wchar_t *wcsdup( const wchar_t *in ) -{ - size_t len=wcslen(in); - wchar_t *out = malloc( sizeof( wchar_t)*(len+1)); - if( out == 0 ) - { - die_mem(); - } - - memcpy( out, in, sizeof( wchar_t)*(len+1)); - return out; - -} -#endif - -#ifndef HAVE_WCSLEN -size_t wcslen(const wchar_t *in) -{ - const wchar_t *end=in; - while( *end ) - end++; - return end-in; -} -#endif - - -#ifndef HAVE_WCSCASECMP -int wcscasecmp( const wchar_t *a, const wchar_t *b ) -{ - if( *a == 0 ) - { - return (*b==0)?0:-1; - } - else if( *b == 0 ) - { - return 1; - } - int diff = towlower(*a)-towlower(*b); - if( diff != 0 ) - return diff; - else - return wcscasecmp( a+1,b+1); -} -#endif - - -#ifndef HAVE_WCSNCASECMP -int wcsncasecmp( const wchar_t *a, const wchar_t *b, int count ) -{ - if( count == 0 ) - return 0; - - if( *a == 0 ) - { - return (*b==0)?0:-1; - } - else if( *b == 0 ) - { - return 1; - } - int diff = towlower(*a)-towlower(*b); - if( diff != 0 ) - return diff; - else - return wcsncasecmp( a+1,b+1, count-1); -} -#endif - -#ifndef HAVE_WCWIDTH -int wcwidth( wchar_t c ) -{ - if( c < 32 ) - return 0; - if ( c == 127 ) - return 0; - return 1; -} -#endif - -#ifndef HAVE_WCSNDUP -wchar_t *wcsndup( const wchar_t *in, int c ) -{ - wchar_t *res = malloc( sizeof(wchar_t)*(c+1) ); - if( res == 0 ) - { - die_mem(); - } - wcsncpy( res, in, c+1 ); - res[c] = L'\0'; - return res; -} -#endif - -long convert_digit( wchar_t d, int base ) -{ - long res=-1; - if( (d <= L'9') && (d >= L'0') ) - { - res = d - L'0'; - } - else if( (d <= L'z') && (d >= L'a') ) - { - res = d + 10 - L'a'; - } - else if( (d <= L'Z') && (d >= L'A') ) - { - res = d + 10 - L'A'; - } - if( res >= base ) - { - res = -1; - } - - return res; -} - -#ifndef HAVE_WCSTOL -long wcstol(const wchar_t *nptr, - wchar_t **endptr, - int base) -{ - long long res=0; - int is_set=0; - if( base > 36 ) - { - errno = EINVAL; - return 0; - } - - while( 1 ) - { - long nxt = convert_digit( *nptr, base ); - if( endptr != 0 ) - *endptr = (wchar_t *)nptr; - if( nxt < 0 ) - { - if( !is_set ) - { - errno = EINVAL; - } - return res; - } - res = (res*base)+nxt; - is_set = 1; - if( res > LONG_MAX ) - { - errno = ERANGE; - return LONG_MAX; - } - if( res < LONG_MIN ) - { - errno = ERANGE; - return LONG_MIN; - } - nptr++; - } -} -#endif - diff --git a/wutil.h b/wutil.h index b88c7822d..6009af653 100644 --- a/wutil.h +++ b/wutil.h @@ -1,8 +1,7 @@ /** \file wutil.h Prototypes for wide character equivalents of various standard unix - functions. Also contains fallback implementations of a large number - of wide character unix functions. + functions. */ #ifndef FISH_WUTIL_H #define FISH_WUTIL_H @@ -100,179 +99,4 @@ wchar_t *wrealpath(const wchar_t *pathname, wchar_t *resolved_path); struct wdirent *wreaddir(DIR *dir ); -/* - Here follows the prototypes for fallback implementations of various - standarcs libc functions relating to wide character support. Some of - these prototypes are always defined, since some libc versions - include the code, but you have to use special magical #defines for - the prototype to appear. -*/ - -#if !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); - -/** - Fallback implementation of getwc -*/ -wint_t getwc(FILE *stream); - -#endif - -#ifndef HAVE_FPUTWC - -/** - Fallback implementation of fputwc -*/ -wint_t fputwc(wchar_t wc, FILE *stream); -/** - Fallback implementation of putwc -*/ -wint_t putwc(wchar_t wc, FILE *stream); - -#endif - -#ifndef HAVE_WCSTOK -/** - Fallback implementation of wcstok. Uses code borrowed from glibc. -*/ -wchar_t *wcstok(wchar_t *wcs, const wchar_t *delim, wchar_t **ptr); - -#endif - -/** - Return the number of columns used by a character. This is a libc - function, but the prototype for this function is missing in some libc - implementations. - - Fish has a fallback implementation in case the implementation is - missing altogether. In locales without a native wcwidth, Unicode - is probably so broken that it isn't worth trying to implement a - real wcwidth. Therefore, the fallback wcwidth assumes any printing - character takes up one column and anything else uses 0 columns. -*/ -int wcwidth( wchar_t c ); - -/** - Create a duplicate string. Wide string version of strdup. Will - automatically exit if out of memory. -*/ -wchar_t *wcsdup(const wchar_t *in); - -size_t wcslen(const wchar_t *in); - -/** - Case insensitive string compare function. Wide string version of - strcasecmp. - - This implementation of wcscasecmp does not take into account - esoteric locales where uppercase and lowercase do not cleanly - transform between each other. Hopefully this should be fine since - fish only uses this function with one of the strings supplied by - fish and guaranteed to be a sane, english word. Using wcscasecmp on - a user-supplied string should be considered a bug. -*/ -int wcscasecmp( const wchar_t *a, const wchar_t *b ); - -/** - Case insensitive string compare function. Wide string version of - strncasecmp. - - This implementation of wcsncasecmp does not take into account - esoteric locales where uppercase and lowercase do not cleanly - transform between each other. Hopefully this should be fine since - fish only uses this function with one of the strings supplied by - fish and guaranteed to be a sane, english word. Using wcsncasecmp on - a user-supplied string should be considered a bug. -*/ -int wcsncasecmp( const wchar_t *a, const wchar_t *b, int count ); - -/** - Returns a newly allocated wide character string wich is a copy of - the string in, but of length c or shorter. The returned string is - always null terminated, and the null is not included in the string - length. -*/ -wchar_t *wcsndup( const wchar_t *in, int c ); - -/** - Converts from wide char to digit in the specified base. If d is not - a valid digit in the specified base, return -1. -*/ -long convert_digit( wchar_t d, int base ); - -/** - Fallback implementation. Convert a wide character string to a - number in the specified base. This functions is the wide character - string equivalent of strtol. For bases of 10 or lower, 0..9 are - used to represent numbers. For bases below 36, a-z and A-Z are used - to represent numbers higher than 9. Higher bases than 36 are not - supported. -*/ -long wcstol(const wchar_t *nptr, - wchar_t **endptr, - int base); - #endif