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
This commit is contained in:
axel 2006-02-28 23:17:16 +10:00
parent e8d802c5e1
commit 2401a163fe
46 changed files with 1199 additions and 1015 deletions

View file

@ -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.

View file

@ -38,7 +38,10 @@
#include <time.h>
#include "config.h"
#include "fallback.h"
#include "util.h"
#include "wutil.h"
#include "builtin.h"
#include "function.h"

View file

@ -12,7 +12,10 @@ Functions used for implementing the commandline builtin.
#include <signal.h>
#include "config.h"
#include "fallback.h"
#include "util.h"
#include "wutil.h"
#include "builtin.h"
#include "common.h"

View file

@ -12,7 +12,10 @@ Functions used for implementing the complete builtin.
#include <signal.h>
#include "config.h"
#include "fallback.h"
#include "util.h"
#include "wutil.h"
#include "builtin.h"
#include "common.h"

View file

@ -12,7 +12,10 @@ Functions used for implementing the set builtin.
#include <signal.h>
#include "config.h"
#include "fallback.h"
#include "util.h"
#include "wutil.h"
#include "builtin.h"
#include "env.h"

View file

@ -13,7 +13,10 @@ Functions used for implementing the ulimit builtin.
#include <errno.h>
#include "config.h"
#include "fallback.h"
#include "util.h"
#include "builtin.h"
#include "common.h"
#include "wgetopt.h"

View file

@ -6,6 +6,7 @@ parts of fish.
#include "config.h"
#include <stdlib.h>
#include <termios.h>
#include <wchar.h>
@ -50,7 +51,9 @@ parts of fish.
#include <ncurses/term.h>
#endif
#include "fallback.h"
#include "util.h"
#include "wutil.h"
#include "common.h"
#include "expand.h"

View file

@ -21,7 +21,10 @@
#include <wchar.h>
#include "config.h"
#include "fallback.h"
#include "util.h"
#include "tokenizer.h"
#include "wildcard.h"
#include "proc.h"

3
env.c
View file

@ -33,7 +33,10 @@
#include <errno.h>
#include "fallback.h"
#include "util.h"
#include "wutil.h"
#include "proc.h"
#include "common.h"

View file

@ -1,5 +1,6 @@
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <wchar.h>
@ -26,7 +27,9 @@
#include <signal.h>
#include "fallback.h"
#include "util.h"
#include "common.h"
#include "wutil.h"
#include "env_universal_common.h"

View file

@ -7,6 +7,7 @@
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <wchar.h>
@ -27,7 +28,9 @@
#include <signal.h>
#include <sys/stat.h>
#include "fallback.h"
#include "util.h"
#include "common.h"
#include "wutil.h"
#include "env_universal_common.h"

View file

@ -12,7 +12,10 @@
#include <string.h>
#include "config.h"
#include "fallback.h"
#include "util.h"
#include "wutil.h"
#include "function.h"
#include "proc.h"

3
exec.c
View file

@ -22,7 +22,10 @@
#include <dirent.h>
#include "config.h"
#include "fallback.h"
#include "util.h"
#include "common.h"
#include "wutil.h"
#include "proc.h"

View file

@ -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"

882
fallback.c Normal file
View file

@ -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 <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <wchar.h>
#include <wctype.h>
#include <string.h>
#include <dirent.h>
#include <stdarg.h>
#include <limits.h>
#if HAVE_NCURSES_H
#include <ncurses.h>
#else
#include <curses.h>
#endif
#if HAVE_TERMIO_H
#include <termio.h>
#endif
#if HAVE_TERM_H
#include <term.h>
#elif HAVE_NCURSES_TERM_H
#include <ncurses/term.h>
#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<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;
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

192
fallback.h Normal file
View file

@ -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

View file

@ -35,7 +35,10 @@
#include <signal.h>
#include "fallback.h"
#include "util.h"
#include "wutil.h"
#include "common.h"
#include "complete.h"

View file

@ -4,6 +4,7 @@
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <wchar.h>
@ -26,7 +27,9 @@
#include <locale.h>
#include <dirent.h>
#include "fallback.h"
#include "util.h"
#include "common.h"
#include "proc.h"
#include "reader.h"

View file

@ -41,6 +41,7 @@ time the original barrier request was sent have been received.
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>
@ -61,7 +62,9 @@ time the original barrier request was sent have been received.
#include <locale.h>
#include <signal.h>
#include "fallback.h"
#include "util.h"
#include "common.h"
#include "wutil.h"
#include "env_universal_common.h"

View file

@ -9,8 +9,11 @@
#include <signal.h>
#include "config.h"
#include "wutil.h"
#include "fallback.h"
#include "util.h"
#include "function.h"
#include "proc.h"
#include "parser.h"

View file

@ -8,10 +8,13 @@
#include "config.h"
#include <stdlib.h>
#include <unistd.h>
#include "fallback.h"
#include "util.h"
#include "common.h"
#include "halloc.h"

View file

@ -8,11 +8,14 @@
#include "config.h"
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "fallback.h"
#include "util.h"
#include "common.h"
#include "halloc.h"

View file

@ -12,7 +12,10 @@
#include <signal.h>
#include "config.h"
#include "fallback.h"
#include "util.h"
#include "wutil.h"
#include "highlight.h"
#include "tokenizer.h"

View file

@ -12,7 +12,10 @@
#include "config.h"
#include "fallback.h"
#include "util.h"
#include "wutil.h"
#include "history.h"
#include "common.h"

View file

@ -43,7 +43,10 @@ implementation in fish is as of yet incomplete.
#include <wctype.h>
#include "fallback.h"
#include "util.h"
#include "wutil.h"
#include "reader.h"
#include "proc.h"

View file

@ -5,6 +5,7 @@ Implementation file for the low level input library
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@ -15,7 +16,9 @@ Implementation file for the low level input library
#include <wchar.h>
#include "fallback.h"
#include "util.h"
#include "common.h"
#include "wutil.h"
#include "input_common.h"

View file

@ -5,12 +5,15 @@
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <wchar.h>
#include <unistd.h>
#include "fallback.h"
#include "util.h"
#include "wutil.h"
#include "common.h"
#include "intern.h"

3
io.c
View file

@ -5,6 +5,7 @@ Utilities for io redirection.
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <wchar.h>
@ -31,7 +32,9 @@ Utilities for io redirection.
#include <ncurses/term.h>
#endif
#include "fallback.h"
#include "util.h"
#include "wutil.h"
#include "exec.h"
#include "common.h"

3
kill.c
View file

@ -18,7 +18,10 @@
#include "config.h"
#include "fallback.h"
#include "util.h"
#include "wutil.h"
#include "kill.h"
#include "proc.h"

3
main.c
View file

@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <wchar.h>
@ -40,7 +41,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <locale.h>
#include <signal.h>
#include "fallback.h"
#include "util.h"
#include "common.h"
#include "reader.h"
#include "builtin.h"

View file

@ -21,6 +21,7 @@ license. Read the source code of the library for more information.
#include "config.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
@ -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
*/

View file

@ -38,7 +38,10 @@
#include <time.h>
#include <wchar.h>
#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 )

View file

@ -6,6 +6,7 @@
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
@ -17,7 +18,9 @@
#include <time.h>
#include <assert.h>
#include "fallback.h"
#include "util.h"
#include "wutil.h"
#include "common.h"
#include "tokenizer.h"

View file

@ -18,7 +18,10 @@ The fish parser. Contains functions for parsing code.
#include <signal.h>
#include "config.h"
#include "fallback.h"
#include "util.h"
#include "common.h"
#include "wutil.h"
#include "proc.h"

3
proc.c
View file

@ -42,7 +42,10 @@ Some of the code in this file is based on code from the Glibc manual.
#include <ncurses/term.h>
#endif
#include "fallback.h"
#include "util.h"
#include "wutil.h"
#include "proc.h"
#include "common.h"

View file

@ -59,7 +59,10 @@ commence.
#include <assert.h>
#include "fallback.h"
#include "util.h"
#include "wutil.h"
#include "highlight.h"
#include "reader.h"

View file

@ -14,7 +14,10 @@
#include "config.h"
#include "fallback.h"
#include "util.h"
#include "common.h"
#include "sanity.h"
#include "proc.h"

View file

@ -1,5 +1,6 @@
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

View file

@ -6,6 +6,7 @@ The library for various signal related issues
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
@ -15,7 +16,9 @@ The library for various signal related issues
#include <errno.h>
#include "common.h"
#include "fallback.h"
#include "util.h"
#include "wutil.h"
#include "signal.h"
#include "event.h"

View file

@ -15,7 +15,10 @@
#include <string.h>
#include <unistd.h>
#include "fallback.h"
#include "util.h"
#include "wutil.h"
#include "tokenizer.h"
#include "common.h"

View file

@ -6,6 +6,7 @@ Translation library, internally uses catgets
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@ -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

3
util.c
View file

@ -6,6 +6,7 @@
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>
@ -22,7 +23,9 @@
#include <errno.h>
#include "fallback.h"
#include "util.h"
#include "common.h"
#include "wutil.h"

View file

@ -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.

View file

@ -18,7 +18,10 @@ wildcards using **.
#include <dirent.h>
#include <errno.h>
#include "fallback.h"
#include "util.h"
#include "wutil.h"
#include "complete.h"
#include "common.h"

831
wutil.c
View file

@ -20,7 +20,10 @@
#include <stdarg.h>
#include <limits.h>
#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<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;
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

178
wutil.h
View file

@ -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