2005-09-20 21:26:39 +08:00
/** \file common.h
Prototypes for various functions , mostly string utilities , that are used by most parts of fish .
*/
2005-10-04 23:11:39 +08:00
# ifndef FISH_COMMON_H
2005-10-24 23:26:25 +08:00
/**
Header guard
*/
2005-10-04 23:11:39 +08:00
# define FISH_COMMON_H
2006-02-06 21:45:32 +08:00
# include <stdlib.h>
# include <stdio.h>
2005-10-04 23:11:39 +08:00
# include <wchar.h>
# include <termios.h>
2011-12-27 11:18:46 +08:00
# include <string>
# include <sstream>
# include <vector>
2012-01-06 05:58:48 +08:00
# include <pthread.h>
# include <string.h>
2005-10-04 23:11:39 +08:00
2011-12-27 11:18:46 +08:00
# include <errno.h>
2012-01-29 06:56:13 +08:00
# include <assert.h>
2005-10-04 23:11:39 +08:00
# include "util.h"
2005-09-20 21:26:39 +08:00
2013-01-01 01:27:27 +08:00
/**
Avoid writing the type name twice in a common " static_cast-initialization " .
Caveat : This doesn ' t work with type names containing commas !
*/
# define CAST_INIT(type, dst, src) type dst = static_cast<type >(src)
2012-02-02 08:27:14 +08:00
class completion_t ;
2012-01-17 00:56:47 +08:00
2011-12-27 11:18:46 +08:00
/* Common string type */
typedef std : : wstring wcstring ;
2011-12-27 16:06:07 +08:00
typedef std : : vector < wcstring > wcstring_list_t ;
2011-12-27 11:18:46 +08:00
2005-09-20 21:26:39 +08:00
/**
2005-11-03 00:49:13 +08:00
Maximum number of bytes used by a single utf - 8 character
2005-09-20 21:26:39 +08:00
*/
# define MAX_UTF8_BYTES 6
2006-01-28 10:03:29 +08:00
/**
This is in the unicode private use area .
*/
2006-02-14 19:35:14 +08:00
# define ENCODE_DIRECT_BASE 0xf100
2006-01-28 10:03:29 +08:00
2006-05-27 00:46:38 +08:00
/**
Highest legal ascii value
*/
# define ASCII_MAX 127u
/**
Highest legal 16 - bit unicode value
*/
# define UCS2_MAX 0xffffu
/**
Highest legal byte value
*/
# define BYTE_MAX 0xffu
2013-11-25 14:57:49 +08:00
/* Flags for unescape_string functions */
enum
{
/* Default behavior */
UNESCAPE_DEFAULT = 0 ,
2008-01-14 00:47:47 +08:00
2013-11-25 14:57:49 +08:00
/* Escape special fish syntax characters like the semicolon */
UNESCAPE_SPECIAL = 1 < < 0 ,
/* Allow incomplete escape sequences */
UNESCAPE_INCOMPLETE = 1 < < 1
} ;
typedef unsigned int unescape_flags_t ;
2007-01-19 00:02:46 +08:00
2012-07-07 05:34:53 +08:00
/* Flags for the escape() and escape_string() functions */
2012-11-19 08:30:30 +08:00
enum
{
2012-07-07 05:34:53 +08:00
/** Escape all characters, including magic characters like the semicolon */
2012-11-19 08:30:30 +08:00
ESCAPE_ALL = 1 < < 0 ,
2012-07-07 05:34:53 +08:00
/** Do not try to use 'simplified' quoted escapes, and do not use empty quotes as the empty string */
ESCAPE_NO_QUOTED = 1 < < 1 ,
2012-11-19 08:30:30 +08:00
2012-07-07 05:34:53 +08:00
/** Do not escape tildes */
ESCAPE_NO_TILDE = 1 < < 2
} ;
typedef unsigned int escape_flags_t ;
2007-10-06 18:51:31 +08:00
2014-01-18 04:04:03 +08:00
/* Directions */
2014-01-19 04:42:53 +08:00
enum selection_direction_t
2014-01-18 04:04:03 +08:00
{
2014-01-19 04:42:53 +08:00
/* visual directions */
2014-01-18 04:04:03 +08:00
direction_north ,
direction_east ,
direction_south ,
2014-01-19 04:42:53 +08:00
direction_west ,
2014-04-01 01:01:39 +08:00
2014-01-19 04:42:53 +08:00
/* logical directions */
direction_next ,
2014-01-25 07:59:18 +08:00
direction_prev ,
2014-04-01 01:01:39 +08:00
2014-01-25 07:59:18 +08:00
/* special value that means deselect */
direction_deselect
2014-01-18 04:04:03 +08:00
} ;
2014-01-19 04:42:53 +08:00
inline bool selection_direction_is_cardinal ( selection_direction_t dir )
{
switch ( dir )
{
case direction_north :
case direction_east :
case direction_south :
case direction_west :
return true ;
default :
return false ;
}
}
2010-09-18 09:51:16 +08:00
/**
2011-12-27 11:18:46 +08:00
Helper macro for errors
*/
2014-08-24 15:59:03 +08:00
# define VOMIT_ON_FAILURE(a) do { if (0 != (a)) { VOMIT_ABORT(errno, #a); } } while (0)
# define VOMIT_ON_FAILURE_NO_ERRNO(a) do { int err = (a); if (0 != err) { VOMIT_ABORT(err, #a); } } while (0)
# define VOMIT_ABORT(err, str) do { int code = (err); fprintf(stderr, "%s failed on line %d in file %s: %d (%s)\n", str, __LINE__, __FILE__, code, strerror(code)); abort(); } while(0)
2011-12-27 11:18:46 +08:00
2012-03-26 16:21:10 +08:00
/** Exits without invoking destructors (via _exit), useful for code after fork. */
2012-11-19 08:30:30 +08:00
void exit_without_destructors ( int code ) __attribute__ ( ( noreturn ) ) ;
2012-01-06 05:58:48 +08:00
2012-11-19 08:30:30 +08:00
/**
2005-11-03 00:49:13 +08:00
Save the shell mode on startup so we can restore them on exit
*/
2012-11-19 08:30:30 +08:00
extern struct termios shell_modes ;
2005-09-20 21:26:39 +08:00
2012-11-05 16:05:42 +08:00
/**
The character to use where the text has been truncated . Is an
ellipsis on unicode system and a $ on other systems .
*/
extern wchar_t ellipsis_char ;
2012-12-02 07:44:09 +08:00
/* Character representing an omitted newline at the end of text */
extern wchar_t omitted_newline_char ;
2005-09-25 03:31:17 +08:00
/**
2006-10-26 18:22:53 +08:00
The verbosity level of fish . If a call to debug has a severity
level higher than \ c debug_level , it will not be printed .
2005-09-25 03:31:17 +08:00
*/
extern int debug_level ;
2005-09-20 21:26:39 +08:00
/**
Profiling flag . True if commands should be profiled .
*/
2014-02-10 06:04:43 +08:00
extern bool g_profiling_active ;
2005-09-20 21:26:39 +08:00
/**
Name of the current program . Should be set at startup . Used by the
debug function .
*/
2011-12-27 11:18:46 +08:00
extern const wchar_t * program_name ;
2005-10-25 17:39:45 +08:00
2014-04-28 09:27:34 +08:00
/* Variants of read() and write() that ignores return values, defeating a warning */
void read_ignore ( int fd , void * buff , size_t count ) ;
void write_ignore ( int fd , const void * buff , size_t count ) ;
2006-06-21 08:48:36 +08:00
/**
This macro is used to check that an input argument is not null . It
is a bit lika a non - fatal form of assert . Instead of exit - ing on
2013-02-18 14:03:00 +08:00
failure , the current function is ended at once . The second
parameter is the return value of the current function on failure .
2006-06-21 08:48:36 +08:00
*/
2006-10-30 05:09:11 +08:00
# define CHECK( arg, retval ) \
2012-11-19 08:30:30 +08:00
if ( ! ( arg ) ) \
2006-06-21 08:48:36 +08:00
{ \
2006-11-17 22:58:25 +08:00
debug ( 0 , \
2012-07-18 03:47:01 +08:00
" function %s called with null value for argument %s. " , \
2006-06-21 08:48:36 +08:00
__func__ , \
2006-11-17 22:58:25 +08:00
# arg ); \
bugreport ( ) ; \
2007-01-20 10:36:49 +08:00
show_stackframe ( ) ; \
2006-06-21 08:48:36 +08:00
return retval ; \
2006-10-30 05:09:11 +08:00
}
2006-06-21 08:48:36 +08:00
2007-01-20 10:36:49 +08:00
/**
2007-01-21 23:03:41 +08:00
Pause for input , then exit the program . If supported , print a backtrace first .
2007-01-20 10:36:49 +08:00
*/
2009-02-05 06:43:10 +08:00
# define FATAL_EXIT() \
{ \
2014-04-28 09:27:34 +08:00
char exit_read_buff ; \
show_stackframe ( ) ; \
read_ignore ( 0 , & exit_read_buff , 1 ) ; \
exit_without_destructors ( 1 ) ; \
2009-02-05 06:43:10 +08:00
} \
2013-02-01 07:57:08 +08:00
2007-01-20 10:36:49 +08:00
2006-07-03 18:39:57 +08:00
/**
2006-11-11 18:54:52 +08:00
Exit program at once , leaving an error message about running out of memory .
2006-07-03 18:39:57 +08:00
*/
2006-10-30 05:09:11 +08:00
# define DIE_MEM() \
2006-07-03 18:39:57 +08:00
{ \
2006-10-30 05:09:11 +08:00
fwprintf ( stderr , \
2012-07-29 08:49:46 +08:00
L " fish: Out of memory on line %ld of file %s, shutting down fish \n " , \
( long ) __LINE__ , \
2006-10-30 05:09:11 +08:00
__FILE__ ) ; \
2007-01-21 23:03:41 +08:00
FATAL_EXIT ( ) ; \
2006-10-30 05:09:11 +08:00
}
/**
2006-11-11 18:54:52 +08:00
Check if signals are blocked . If so , print an error message and
return from the function performing this check .
2006-10-30 05:09:11 +08:00
*/
2012-11-19 08:30:30 +08:00
# define CHECK_BLOCK(retval) \
if ( signal_is_blocked ( ) ) \
2006-10-30 05:09:11 +08:00
{ \
debug ( 0 , \
2012-07-18 03:47:01 +08:00
" function %s called while blocking signals. " , \
2006-11-17 22:58:25 +08:00
__func__ ) ; \
bugreport ( ) ; \
2007-01-20 10:36:49 +08:00
show_stackframe ( ) ; \
2006-11-17 22:58:25 +08:00
return retval ; \
2006-10-30 05:09:11 +08:00
}
2012-11-19 08:30:30 +08:00
2006-07-20 06:55:49 +08:00
/**
Shorthand for wgettext call
*/
2013-03-25 06:33:45 +08:00
# define _(wstr) wgettext(wstr)
2006-07-20 06:55:49 +08:00
/**
2006-11-11 18:54:52 +08:00
Noop , used to tell xgettext that a string should be translated ,
2012-11-19 08:30:30 +08:00
even though it is not directly sent to wgettext .
2006-07-20 06:55:49 +08:00
*/
# define N_(wstr) wstr
2008-01-14 00:47:47 +08:00
/**
2012-10-16 09:16:47 +08:00
Check if the specified string element is a part of the specified string list
2008-01-14 00:47:47 +08:00
*/
2014-03-10 09:43:40 +08:00
# define contains( str, ... ) contains_internal( str, 0, __VA_ARGS__, NULL )
2007-04-17 05:40:41 +08:00
2008-01-14 00:47:47 +08:00
/**
2007-01-21 23:01:14 +08:00
Print a stack trace to stderr
*/
2007-01-20 10:36:49 +08:00
void show_stackframe ( ) ;
2005-09-20 21:26:39 +08:00
/**
2012-11-19 08:30:30 +08:00
Read a line from the stream f into the string . Returns
2013-02-18 14:03:00 +08:00
the number of bytes read or - 1 on failure .
2005-09-20 21:26:39 +08:00
If the carriage return character is encountered , it is
ignored . fgetws ( ) considers the line to end if reading the file
results in either a newline ( L ' \n ' ) character , the null ( L ' \ \ 0 ' )
character or the end of file ( WEOF ) character .
*/
2012-07-17 03:05:36 +08:00
int fgetws2 ( wcstring * s , FILE * f ) ;
2006-06-17 21:07:08 +08:00
2011-12-27 11:18:46 +08:00
/**
2012-12-20 05:31:06 +08:00
Returns a wide character string equivalent of the
2011-12-27 11:18:46 +08:00
specified multibyte character string
2012-11-19 08:30:30 +08:00
2011-12-27 11:18:46 +08:00
This function encodes illegal character sequences in a reversible
way using the private use area .
*/
2012-11-19 08:30:30 +08:00
wcstring str2wcstring ( const char * in ) ;
2012-12-20 05:31:06 +08:00
wcstring str2wcstring ( const char * in , size_t len ) ;
2012-11-19 08:30:30 +08:00
wcstring str2wcstring ( const std : : string & in ) ;
2011-12-27 11:18:46 +08:00
2005-09-20 21:26:39 +08:00
/**
2005-11-03 00:49:13 +08:00
Returns a newly allocated multibyte character string equivalent of
the specified wide character string
2006-06-17 21:07:08 +08:00
This function decodes illegal character sequences in a reversible
way using the private use area .
2005-09-20 21:26:39 +08:00
*/
2012-11-19 08:30:30 +08:00
char * wcs2str ( const wchar_t * in ) ;
2013-01-13 06:18:34 +08:00
char * wcs2str ( const wcstring & in ) ;
2011-12-27 11:18:46 +08:00
std : : string wcs2string ( const wcstring & input ) ;
2012-02-01 08:50:03 +08:00
/** Test if a string prefixes another. Returns true if a is a prefix of b */
bool string_prefixes_string ( const wcstring & proposed_prefix , const wcstring & value ) ;
2012-05-09 17:33:42 +08:00
bool string_prefixes_string ( const wchar_t * proposed_prefix , const wcstring & value ) ;
2012-02-01 08:50:03 +08:00
2012-05-14 11:49:14 +08:00
/** Test if a string is a suffix of another */
bool string_suffixes_string ( const wcstring & proposed_suffix , const wcstring & value ) ;
bool string_suffixes_string ( const wchar_t * proposed_suffix , const wcstring & value ) ;
2012-03-02 09:31:45 +08:00
/** Test if a string prefixes another without regard to case. Returns true if a is a prefix of b */
bool string_prefixes_string_case_insensitive ( const wcstring & proposed_prefix , const wcstring & value ) ;
2013-05-26 06:41:18 +08:00
enum fuzzy_match_type_t
{
/* We match the string exactly: FOOBAR matches FOOBAR */
fuzzy_match_exact = 0 ,
2013-06-02 16:14:26 +08:00
2013-05-26 06:41:18 +08:00
/* We match a prefix of the string: FO matches FOOBAR */
fuzzy_match_prefix ,
2013-06-02 16:14:26 +08:00
2013-05-26 06:41:18 +08:00
/* We match the string exactly, but in a case insensitive way: foobar matches FOOBAR */
fuzzy_match_case_insensitive ,
2013-06-02 16:14:26 +08:00
2013-05-26 06:41:18 +08:00
/* We match a prefix of the string, in a case insensitive way: foo matches FOOBAR */
fuzzy_match_prefix_case_insensitive ,
2013-06-02 16:14:26 +08:00
2013-05-26 06:41:18 +08:00
/* We match a substring of the string: OOBA matches FOOBAR */
fuzzy_match_substring ,
2013-06-02 16:14:26 +08:00
2013-05-26 06:41:18 +08:00
/* A subsequence match with insertions only: FBR matches FOOBAR */
fuzzy_match_subsequence_insertions_only ,
2013-06-02 16:14:26 +08:00
2013-05-26 06:41:18 +08:00
/* We don't match the string */
fuzzy_match_none
} ;
/* Indicates where a match type requires replacing the entire token */
static inline bool match_type_requires_full_replacement ( fuzzy_match_type_t t )
{
switch ( t )
{
case fuzzy_match_exact :
case fuzzy_match_prefix :
return false ;
default :
return true ;
}
}
/* Indicates where a match shares a prefix with the string it matches */
static inline bool match_type_shares_prefix ( fuzzy_match_type_t t )
{
switch ( t )
{
case fuzzy_match_exact :
case fuzzy_match_prefix :
case fuzzy_match_case_insensitive :
case fuzzy_match_prefix_case_insensitive :
return true ;
default :
return false ;
}
}
/** Test if string is a fuzzy match to another */
struct string_fuzzy_match_t
{
enum fuzzy_match_type_t type ;
2013-06-02 16:14:26 +08:00
2013-05-26 06:41:18 +08:00
/* Strength of the match. The value depends on the type. Lower is stronger. */
size_t match_distance_first ;
size_t match_distance_second ;
2013-06-02 16:14:26 +08:00
2013-05-26 06:41:18 +08:00
/* Constructor */
string_fuzzy_match_t ( enum fuzzy_match_type_t t , size_t distance_first = 0 , size_t distance_second = 0 ) ;
2013-06-02 16:14:26 +08:00
2013-05-26 06:41:18 +08:00
/* Return -1, 0, 1 if this match is (respectively) better than, equal to, or worse than rhs */
int compare ( const string_fuzzy_match_t & rhs ) const ;
} ;
/* Compute a fuzzy match for a string. If maximum_match is not fuzzy_match_none, limit the type to matches at or below that type. */
string_fuzzy_match_t string_fuzzy_match_string ( const wcstring & string , const wcstring & match_against , fuzzy_match_type_t limit_type = fuzzy_match_none ) ;
2012-02-27 12:11:34 +08:00
/** Test if a list contains a string using a linear search. */
bool list_contains_string ( const wcstring_list_t & list , const wcstring & str ) ;
2011-12-27 11:18:46 +08:00
void assert_is_main_thread ( const char * who ) ;
# define ASSERT_IS_MAIN_THREAD_TRAMPOLINE(x) assert_is_main_thread(x)
# define ASSERT_IS_MAIN_THREAD() ASSERT_IS_MAIN_THREAD_TRAMPOLINE(__FUNCTION__)
void assert_is_background_thread ( const char * who ) ;
# define ASSERT_IS_BACKGROUND_THREAD_TRAMPOLINE(x) assert_is_background_thread(x)
# define ASSERT_IS_BACKGROUND_THREAD() ASSERT_IS_BACKGROUND_THREAD_TRAMPOLINE(__FUNCTION__)
2012-02-25 04:13:35 +08:00
/* Useful macro for asserting that a lock is locked. This doesn't check whether this thread locked it, which it would be nice if it did, but here it is anyways. */
2012-04-22 11:08:08 +08:00
void assert_is_locked ( void * mutex , const char * who , const char * caller ) ;
# define ASSERT_IS_LOCKED(x) assert_is_locked((void *)(&x), #x, __FUNCTION__)
2005-09-20 21:26:39 +08:00
2012-03-06 02:18:42 +08:00
/** Format the specified size (in bytes, kilobytes, etc.) into the specified stringbuffer. */
wcstring format_size ( long long sz ) ;
/** Version of format_size that does not allocate memory. */
void format_size_safe ( char buff [ 128 ] , unsigned long long sz ) ;
/** Our crappier versions of debug which is guaranteed to not allocate any memory, or do anything other than call write(). This is useful after a call to fork() with threads. */
2012-03-09 15:21:07 +08:00
void debug_safe ( int level , const char * msg , const char * param1 = NULL , const char * param2 = NULL , const char * param3 = NULL , const char * param4 = NULL , const char * param5 = NULL , const char * param6 = NULL , const char * param7 = NULL , const char * param8 = NULL , const char * param9 = NULL , const char * param10 = NULL , const char * param11 = NULL , const char * param12 = NULL ) ;
2012-03-06 02:18:42 +08:00
/** Writes out a long safely */
2014-01-13 05:53:59 +08:00
void format_long_safe ( char buff [ 64 ] , long val ) ;
void format_long_safe ( wchar_t buff [ 64 ] , long val ) ;
2012-03-06 02:18:42 +08:00
2011-12-27 11:18:46 +08:00
template < typename T >
2012-11-19 08:30:30 +08:00
T from_string ( const wcstring & x )
{
2011-12-27 11:18:46 +08:00
T result ;
std : : wstringstream stream ( x ) ;
stream > > result ;
return result ;
}
2012-03-06 02:44:08 +08:00
template < typename T >
2012-11-19 08:30:30 +08:00
T from_string ( const std : : string & x )
{
2012-03-06 02:44:08 +08:00
T result = T ( ) ;
std : : stringstream stream ( x ) ;
stream > > result ;
return result ;
}
2012-02-02 08:27:14 +08:00
template < typename T >
2012-11-19 08:30:30 +08:00
wcstring to_string ( const T & x )
{
2012-02-02 08:27:14 +08:00
std : : wstringstream stream ;
stream < < x ;
return stream . str ( ) ;
}
2012-03-06 02:18:42 +08:00
/* wstringstream is a huge memory pig. Let's provide some specializations where we can. */
template < >
2012-11-19 08:30:30 +08:00
inline wcstring to_string ( const long & x )
{
2012-03-06 02:18:42 +08:00
wchar_t buff [ 128 ] ;
format_long_safe ( buff , x ) ;
return wcstring ( buff ) ;
}
2012-03-06 02:44:08 +08:00
template < >
2012-11-19 08:30:30 +08:00
inline bool from_string ( const std : : string & x )
{
2012-03-06 05:39:01 +08:00
return ! x . empty ( ) & & strchr ( " YTyt1 " , x . at ( 0 ) ) ;
2012-03-06 02:44:08 +08:00
}
template < >
2012-11-19 08:30:30 +08:00
inline bool from_string ( const wcstring & x )
{
2012-03-06 05:39:01 +08:00
return ! x . empty ( ) & & wcschr ( L " YTyt1 " , x . at ( 0 ) ) ;
2012-03-06 02:44:08 +08:00
}
2012-03-06 02:18:42 +08:00
template < >
2012-11-19 08:30:30 +08:00
inline wcstring to_string ( const int & x )
{
2012-03-06 02:18:42 +08:00
return to_string ( static_cast < long > ( x ) ) ;
}
2013-02-23 08:22:56 +08:00
wchar_t * * make_null_terminated_array ( const wcstring_list_t & lst ) ;
char * * make_null_terminated_array ( const std : : vector < std : : string > & lst ) ;
2012-03-06 02:18:42 +08:00
2012-02-29 07:11:46 +08:00
/* Helper class for managing a null-terminated array of null-terminated strings (of some char type) */
template < typename CharType_t >
2012-11-19 08:30:30 +08:00
class null_terminated_array_t
{
2012-02-29 07:11:46 +08:00
CharType_t * * array ;
2013-02-28 04:03:30 +08:00
2013-02-23 08:22:56 +08:00
/* No assignment or copying */
void operator = ( null_terminated_array_t rhs ) ;
null_terminated_array_t ( const null_terminated_array_t & ) ;
2012-11-19 08:30:30 +08:00
2013-02-23 08:22:56 +08:00
typedef std : : vector < std : : basic_string < CharType_t > > string_list_t ;
2012-02-29 07:11:46 +08:00
2012-11-19 08:30:30 +08:00
size_t size ( ) const
{
2013-02-23 08:22:56 +08:00
size_t len = 0 ;
2012-11-19 08:30:30 +08:00
if ( array ! = NULL )
{
2013-02-23 08:22:56 +08:00
while ( array [ len ] ! = NULL )
2012-11-19 08:30:30 +08:00
{
2013-02-23 08:22:56 +08:00
len + + ;
2012-02-29 07:11:46 +08:00
}
}
2013-02-23 08:22:56 +08:00
return len ;
}
void free ( void )
{
: : free ( ( void * ) array ) ;
array = NULL ;
2012-02-29 07:11:46 +08:00
}
2012-11-19 08:30:30 +08:00
public :
2012-02-29 07:11:46 +08:00
null_terminated_array_t ( ) : array ( NULL ) { }
2013-02-23 08:22:56 +08:00
null_terminated_array_t ( const string_list_t & argv ) : array ( make_null_terminated_array ( argv ) )
2012-11-19 08:30:30 +08:00
{
}
2013-02-28 04:03:30 +08:00
2012-11-19 08:30:30 +08:00
~ null_terminated_array_t ( )
{
this - > free ( ) ;
}
void set ( const string_list_t & argv )
{
2012-02-29 07:11:46 +08:00
this - > free ( ) ;
2013-02-23 08:22:56 +08:00
this - > array = make_null_terminated_array ( argv ) ;
2012-02-29 07:11:46 +08:00
}
2012-11-19 08:30:30 +08:00
const CharType_t * const * get ( ) const
{
return array ;
}
2013-02-28 04:03:30 +08:00
2013-02-23 08:22:56 +08:00
void clear ( )
2012-11-19 08:30:30 +08:00
{
2013-02-23 08:22:56 +08:00
this - > free ( ) ;
2012-02-29 07:11:46 +08:00
}
} ;
2012-03-01 03:27:14 +08:00
/* Helper function to convert from a null_terminated_array_t<wchar_t> to a null_terminated_array_t<char_t> */
2013-02-23 08:22:56 +08:00
void convert_wide_array_to_narrow ( const null_terminated_array_t < wchar_t > & arr , null_terminated_array_t < char > * output ) ;
2012-03-01 03:27:14 +08:00
2012-03-09 15:21:07 +08:00
/* Helper class to cache a narrow version of a wcstring in a malloc'd buffer, so that we can read it after fork() */
2012-11-19 08:30:30 +08:00
class narrow_string_rep_t
{
private :
2012-03-09 15:21:07 +08:00
const char * str ;
2012-11-19 08:30:30 +08:00
2012-08-06 04:24:33 +08:00
/* No copying */
narrow_string_rep_t & operator = ( const narrow_string_rep_t & ) ;
narrow_string_rep_t ( const narrow_string_rep_t & x ) ;
2012-11-19 08:30:30 +08:00
public :
~ narrow_string_rep_t ( )
{
2012-03-09 15:21:07 +08:00
free ( ( void * ) str ) ;
}
2012-11-19 08:30:30 +08:00
2012-03-09 15:21:07 +08:00
narrow_string_rep_t ( ) : str ( NULL ) { }
2012-11-19 08:30:30 +08:00
void set ( const wcstring & s )
{
2012-03-09 15:21:07 +08:00
free ( ( void * ) str ) ;
str = wcs2str ( s . c_str ( ) ) ;
}
2012-11-19 08:30:30 +08:00
const char * get ( ) const
{
2012-03-09 15:21:07 +08:00
return str ;
}
} ;
2012-02-28 10:43:24 +08:00
bool is_forked_child ( ) ;
2014-05-05 06:06:40 +08:00
2014-07-07 15:38:37 +08:00
class mutex_lock_t
2014-05-05 06:06:40 +08:00
{
public :
pthread_mutex_t mutex ;
2014-07-07 15:38:37 +08:00
mutex_lock_t ( )
2014-05-05 06:06:40 +08:00
{
2014-08-24 15:59:03 +08:00
VOMIT_ON_FAILURE_NO_ERRNO ( pthread_mutex_init ( & mutex , NULL ) ) ;
2014-05-05 06:06:40 +08:00
}
2014-07-07 15:38:37 +08:00
~ mutex_lock_t ( )
2014-05-05 06:06:40 +08:00
{
2014-08-24 15:59:03 +08:00
VOMIT_ON_FAILURE_NO_ERRNO ( pthread_mutex_destroy ( & mutex ) ) ;
2014-05-05 06:06:40 +08:00
}
} ;
2012-02-29 07:11:46 +08:00
/* Basic scoped lock class */
2012-11-19 08:30:30 +08:00
class scoped_lock
{
2012-01-29 06:56:13 +08:00
pthread_mutex_t * lock_obj ;
bool locked ;
2012-11-19 08:30:30 +08:00
2012-08-06 04:24:33 +08:00
/* No copying */
scoped_lock & operator = ( const scoped_lock & ) ;
scoped_lock ( const scoped_lock & ) ;
2011-12-27 11:18:46 +08:00
public :
2012-02-28 10:43:24 +08:00
void lock ( void ) ;
void unlock ( void ) ;
scoped_lock ( pthread_mutex_t & mutex ) ;
2014-07-07 15:38:37 +08:00
scoped_lock ( mutex_lock_t & lock ) ;
2012-02-28 10:43:24 +08:00
~ scoped_lock ( ) ;
2011-12-27 11:18:46 +08:00
} ;
2014-08-24 15:59:03 +08:00
class rwlock_t
{
public :
pthread_rwlock_t rwlock ;
rwlock_t ( )
{
VOMIT_ON_FAILURE_NO_ERRNO ( pthread_rwlock_init ( & rwlock , NULL ) ) ;
}
~ rwlock_t ( )
{
VOMIT_ON_FAILURE_NO_ERRNO ( pthread_rwlock_destroy ( & rwlock ) ) ;
}
} ;
/*
Scoped lock class for rwlocks
*/
class scoped_rwlock
{
pthread_rwlock_t * rwlock_obj ;
bool locked ;
bool locked_shared ;
/* No copying */
scoped_rwlock & operator = ( const scoped_lock & ) ;
scoped_rwlock ( const scoped_lock & ) ;
public :
void lock ( void ) ;
void unlock ( void ) ;
void lock_shared ( void ) ;
void unlock_shared ( void ) ;
/*
upgrade shared lock to exclusive .
equivalent to ` lock . unlock_shared ( ) ; lock . lock ( ) ; `
*/
void upgrade ( void ) ;
scoped_rwlock ( pthread_rwlock_t & rwlock , bool shared = false ) ;
scoped_rwlock ( rwlock_t & rwlock , bool shared = false ) ;
~ scoped_rwlock ( ) ;
} ;
2013-02-22 22:34:30 +08:00
/**
A scoped manager to save the current value of some variable , and optionally
set it to a new value . On destruction it restores the variable to its old
value .
This can be handy when there are multiple code paths to exit a block .
*/
template < typename T >
class scoped_push
{
2013-02-28 04:03:30 +08:00
T * const ref ;
2013-02-22 22:34:30 +08:00
T saved_value ;
bool restored ;
public :
2013-02-28 04:03:30 +08:00
scoped_push ( T * r ) : ref ( r ) , saved_value ( * r ) , restored ( false )
2013-02-22 22:34:30 +08:00
{
}
2013-02-28 04:03:30 +08:00
scoped_push ( T * r , const T & new_value ) : ref ( r ) , saved_value ( * r ) , restored ( false )
2013-02-22 22:34:30 +08:00
{
2013-02-28 04:03:30 +08:00
* r = new_value ;
2013-02-22 22:34:30 +08:00
}
~ scoped_push ( )
{
2013-02-28 04:03:30 +08:00
restore ( ) ;
2013-02-22 22:34:30 +08:00
}
void restore ( )
{
2013-02-28 04:03:30 +08:00
if ( ! restored )
{
std : : swap ( * ref , saved_value ) ;
restored = true ;
}
2013-02-22 22:34:30 +08:00
}
} ;
2012-07-21 05:33:08 +08:00
/* Wrapper around wcstok */
2012-11-19 08:30:30 +08:00
class wcstokenizer
{
2011-12-27 11:18:46 +08:00
wchar_t * buffer , * str , * state ;
const wcstring sep ;
2012-11-19 08:30:30 +08:00
2012-08-06 04:24:33 +08:00
/* No copying */
wcstokenizer & operator = ( const wcstokenizer & ) ;
wcstokenizer ( const wcstokenizer & ) ;
2012-11-19 08:30:30 +08:00
2011-12-27 11:18:46 +08:00
public :
2012-07-21 05:33:08 +08:00
wcstokenizer ( const wcstring & s , const wcstring & separator ) ;
bool next ( wcstring & result ) ;
~ wcstokenizer ( ) ;
2011-12-27 11:18:46 +08:00
} ;
2012-11-19 08:30:30 +08:00
/**
2011-12-27 11:18:46 +08:00
Appends a path component , with a / if necessary
*/
void append_path_component ( wcstring & path , const wcstring & component ) ;
wcstring format_string ( const wchar_t * format , . . . ) ;
2012-02-10 10:43:36 +08:00
wcstring vformat_string ( const wchar_t * format , va_list va_orig ) ;
2012-02-23 02:51:06 +08:00
void append_format ( wcstring & str , const wchar_t * format , . . . ) ;
2013-03-25 06:24:29 +08:00
void append_formatv ( wcstring & str , const wchar_t * format , va_list ap ) ;
2011-12-27 11:18:46 +08:00
2006-04-21 22:29:39 +08:00
/**
2012-11-19 08:30:30 +08:00
Test if the given string is a valid variable name .
2006-04-21 22:29:39 +08:00
\ return null if this is a valid name , and a pointer to the first invalid character otherwise
*/
2014-06-10 03:57:44 +08:00
const wchar_t * wcsvarname ( const wchar_t * str ) ;
2006-10-19 23:39:50 +08:00
2005-09-20 21:26:39 +08:00
2006-10-19 23:47:47 +08:00
/**
2012-11-19 08:30:30 +08:00
Test if the given string is a valid function name .
2006-10-19 23:47:47 +08:00
\ return null if this is a valid name , and a pointer to the first invalid character otherwise
*/
2012-11-19 08:30:30 +08:00
const wchar_t * wcsfuncname ( const wchar_t * str ) ;
2006-10-19 23:47:47 +08:00
2006-06-02 07:04:38 +08:00
/**
2012-11-19 08:30:30 +08:00
Test if the given string is valid in a variable name
2006-06-02 07:04:38 +08:00
2013-08-09 06:06:46 +08:00
\ return true if this is a valid name , false otherwise
2006-06-02 07:04:38 +08:00
*/
2013-08-09 06:06:46 +08:00
bool wcsvarchr ( wchar_t chr ) ;
2006-06-02 07:04:38 +08:00
2005-09-20 21:26:39 +08:00
/**
2014-09-26 09:04:11 +08:00
Convenience variants on fish_wcwswidth ( ) .
See fallback . h for the normal definitions .
2005-09-20 21:26:39 +08:00
*/
2014-09-26 09:04:11 +08:00
int fish_wcswidth ( const wchar_t * str ) ;
int fish_wcswidth ( const wcstring & str ) ;
2005-09-20 21:26:39 +08:00
/**
2005-11-03 00:49:13 +08:00
This functions returns the end of the quoted substring beginning at
2006-02-01 20:27:15 +08:00
\ c in . The type of quoting character is detemrined by examining \ c
in . Returns 0 on error .
2005-11-03 00:49:13 +08:00
\ param in the position of the opening quote
2005-09-20 21:26:39 +08:00
*/
2012-11-19 08:30:30 +08:00
wchar_t * quote_end ( const wchar_t * in ) ;
2005-09-20 21:26:39 +08:00
/**
A call to this function will reset the error counter . Some
functions print out non - critical error messages . These should check
the error_count before , and skip printing the message if
MAX_ERROR_COUNT messages have been printed . The error_reset ( )
should be called after each interactive command executes , to allow
new messages to be printed .
*/
void error_reset ( ) ;
/**
2006-01-09 07:00:49 +08:00
This function behaves exactly like a wide character equivalent of
2012-11-05 16:05:42 +08:00
the C function setlocale , except that it will also try to detect if
the user is using a Unicode character set , and if so , use the
2012-11-19 08:30:30 +08:00
unicode ellipsis character as ellipsis , instead of ' $ ' .
2005-09-20 21:26:39 +08:00
*/
2012-11-19 08:30:30 +08:00
wcstring wsetlocale ( int category , const wchar_t * locale ) ;
2005-09-20 21:26:39 +08:00
/**
2006-05-03 00:28:30 +08:00
Checks if \ c needle is included in the list of strings specified . A warning is printed if needle is zero .
2005-09-20 21:26:39 +08:00
2012-11-19 08:30:30 +08:00
\ param needle the string to search for in the list
2006-05-03 00:28:30 +08:00
2007-09-24 16:18:23 +08:00
\ return zero if needle is not found , of if needle is null , non - zero otherwise
2005-09-20 21:26:39 +08:00
*/
2014-03-10 09:43:40 +08:00
__sentinel bool contains_internal ( const wchar_t * needle , int vararg_handle , . . . ) ;
__sentinel bool contains_internal ( const wcstring & needle , int vararg_handle , . . . ) ;
2005-09-20 21:26:39 +08:00
/**
Call read while blocking the SIGCHLD signal . Should only be called
2007-09-24 16:18:23 +08:00
if you _know_ there is data available for reading , or the program
will hang until there is data .
2005-09-20 21:26:39 +08:00
*/
2012-08-05 06:11:43 +08:00
long read_blocked ( int fd , void * buf , size_t count ) ;
2005-09-20 21:26:39 +08:00
2009-02-23 04:28:52 +08:00
/**
2013-02-18 14:03:00 +08:00
Loop a write request while failure is non - critical . Return - 1 and set errno
2009-02-23 04:28:52 +08:00
in case of critical error .
*/
2012-01-14 19:41:50 +08:00
ssize_t write_loop ( int fd , const char * buff , size_t count ) ;
2009-02-23 04:28:52 +08:00
2012-03-01 09:55:50 +08:00
/**
2013-02-18 14:03:00 +08:00
Loop a read request while failure is non - critical . Return - 1 and set errno
2012-03-01 09:55:50 +08:00
in case of critical error .
*/
ssize_t read_loop ( int fd , void * buff , size_t count ) ;
2005-09-20 21:26:39 +08:00
/**
2005-10-14 19:40:33 +08:00
Issue a debug message with printf - style string formating and
automatic line breaking . The string will begin with the string \ c
program_name , followed by a colon and a whitespace .
2006-12-14 18:01:31 +08:00
Because debug is often called to tell the user about an error ,
before using wperror to give a specific error message , debug will
never ever modify the value of errno .
2012-11-19 08:30:30 +08:00
2005-10-14 19:40:33 +08:00
\ param level the priority of the message . Lower number means higher priority . Messages with a priority_number higher than \ c debug_level will be ignored . .
2012-11-19 08:30:30 +08:00
\ param msg the message format string .
2005-10-14 19:40:33 +08:00
Example :
< code > debug ( 1 , L " Pi = %.3f " , M_PI ) ; < / code >
will print the string ' fish : Pi = 3.141 ' , given that debug_level is 1 or higher , and that program_name is ' fish ' .
2005-09-20 21:26:39 +08:00
*/
2012-11-19 08:30:30 +08:00
void debug ( int level , const char * msg , . . . ) ;
void debug ( int level , const wchar_t * msg , . . . ) ;
2005-09-20 21:26:39 +08:00
2014-03-17 07:45:00 +08:00
/** Writes a string to stderr, followed by a newline */
void print_stderr ( const wcstring & str ) ;
2005-09-20 21:26:39 +08:00
/**
2005-10-14 19:40:33 +08:00
Replace special characters with backslash escape sequences . Newline is
2012-11-19 08:30:30 +08:00
replaced with \ n , etc .
2005-09-20 21:26:39 +08:00
\ param in The string to be escaped
2014-09-23 03:37:11 +08:00
\ param flags Flags to control the escaping
2014-09-26 09:20:03 +08:00
\ return The escaped string
2005-09-20 21:26:39 +08:00
*/
2014-09-26 09:20:03 +08:00
wcstring escape ( const wchar_t * in , escape_flags_t flags ) ;
2012-11-19 08:30:30 +08:00
wcstring escape_string ( const wcstring & in , escape_flags_t flags ) ;
2005-09-20 21:26:39 +08:00
2005-10-24 23:26:25 +08:00
/**
Expand backslashed escapes and substitute them with their unescaped
counterparts . Also optionally change the wildcards , the tilde
character and a few more into constants which are defined in a
private use area of Unicode . This assumes wchar_t is a unicode
2005-10-25 19:03:52 +08:00
character set .
2005-10-24 23:26:25 +08:00
*/
2005-09-20 21:26:39 +08:00
2013-11-25 14:57:49 +08:00
/** Unescapes a string in-place. A true result indicates the string was unescaped, a false result indicates the string was unmodified. */
bool unescape_string_in_place ( wcstring * str , unescape_flags_t escape_special ) ;
/** Unescapes a string, returning the unescaped value by reference. On failure, the output is set to an empty string. */
bool unescape_string ( const wchar_t * input , wcstring * output , unescape_flags_t escape_special ) ;
bool unescape_string ( const wcstring & input , wcstring * output , unescape_flags_t escape_special ) ;
2011-12-27 11:18:46 +08:00
2005-10-14 19:40:33 +08:00
2012-11-19 08:30:30 +08:00
/**
2007-09-24 16:18:23 +08:00
Returns the width of the terminal window , so that not all
functions that use these values continually have to keep track of
it separately .
2005-10-14 19:40:33 +08:00
2007-09-24 16:18:23 +08:00
Only works if common_handle_winch is registered to handle winch signals .
2005-10-14 19:40:33 +08:00
*/
int common_get_width ( ) ;
/**
Returns the height of the terminal window , so that not all
functions that use these values continually have to keep track of
2007-09-24 16:18:23 +08:00
it separatly .
2005-10-14 19:40:33 +08:00
Only works if common_handle_winch is registered to handle winch signals .
*/
int common_get_height ( ) ;
2005-10-24 23:26:25 +08:00
/**
2005-10-14 19:40:33 +08:00
Handle a window change event by looking up the new window size and
saving it in an internal variable used by common_get_wisth and
common_get_height ( ) .
*/
2012-11-19 08:30:30 +08:00
void common_handle_winch ( int signal ) ;
2005-10-14 19:40:33 +08:00
2006-01-15 19:58:05 +08:00
/**
2006-05-14 17:47:21 +08:00
Write paragraph of output to the specified stringbuffer , and redo
the linebreaks to fit the current screen .
2006-01-15 19:58:05 +08:00
*/
2012-11-19 08:30:30 +08:00
void write_screen ( const wcstring & msg , wcstring & buff ) ;
2006-01-15 19:58:05 +08:00
2006-05-29 19:13:42 +08:00
/**
2012-11-19 08:30:30 +08:00
Tokenize the specified string into the specified wcstring_list_t .
2006-05-29 19:13:42 +08:00
\ param val the input string . The contents of this string is not changed .
2012-11-19 08:30:30 +08:00
\ param out the list in which to place the elements .
2006-05-29 19:13:42 +08:00
*/
2012-11-19 08:30:30 +08:00
void tokenize_variable_array ( const wcstring & val , wcstring_list_t & out ) ;
2006-05-29 19:13:42 +08:00
2006-10-19 19:50:23 +08:00
/**
2007-09-24 16:18:23 +08:00
Make sure the specified direcotry exists . If needed , try to create
it and any currently not existing parent directories . .
2006-10-19 19:50:23 +08:00
2007-09-24 16:18:23 +08:00
\ return 0 if , at the time of function return the directory exists , - 1 otherwise .
2006-10-19 19:50:23 +08:00
*/
2012-11-19 08:30:30 +08:00
int create_directory ( const wcstring & d ) ;
2006-10-19 19:50:23 +08:00
2006-11-17 22:58:25 +08:00
/**
Print a short message about how to file a bug report to stderr
*/
void bugreport ( ) ;
2009-02-03 06:46:45 +08:00
/**
Return the number of seconds from the UNIX epoch , with subsecond
precision . This function uses the gettimeofday function , and will
have the same precision as that function .
If an error occurs , NAN is returned .
*/
double timef ( ) ;
2012-01-06 05:58:48 +08:00
/**
Call the following function early in main to set the main thread .
This is our replacement for pthread_main_np ( ) .
*/
void set_main_thread ( ) ;
2012-03-20 02:52:18 +08:00
bool is_main_thread ( ) ;
2012-01-06 05:58:48 +08:00
2012-05-14 11:19:02 +08:00
/** Configures thread assertions for testing */
void configure_thread_assertions_for_testing ( ) ;
2012-02-28 10:43:24 +08:00
/** Set up a guard to complain if we try to do certain things (like take a lock) after calling fork */
void setup_fork_guards ( void ) ;
2012-01-06 05:58:48 +08:00
2012-11-18 18:16:14 +08:00
/** Save the value of tcgetpgrp so we can restore it on exit */
void save_term_foreground_process_group ( void ) ;
void restore_term_foreground_process_group ( void ) ;
2012-02-28 10:43:24 +08:00
/** Return whether we are the child of a fork */
bool is_forked_child ( void ) ;
void assert_is_not_forked_child ( const char * who ) ;
# define ASSERT_IS_NOT_FORKED_CHILD_TRAMPOLINE(x) assert_is_not_forked_child(x)
# define ASSERT_IS_NOT_FORKED_CHILD() ASSERT_IS_NOT_FORKED_CHILD_TRAMPOLINE(__FUNCTION__)
2009-02-03 06:46:45 +08:00
2014-05-02 07:44:37 +08:00
/** Macro to help suppress potentially unused variable warnings */
# define USE(var) (void)(var)
2012-03-01 09:55:50 +08:00
extern " C " {
2012-11-19 08:30:30 +08:00
__attribute__ ( ( noinline ) ) void debug_thread_error ( void ) ;
2012-03-01 09:55:50 +08:00
}
2005-10-04 23:11:39 +08:00
# endif