// utf-8

/*	Copyright  (c)	Günter Woigk   1995-2003
  					mailto:kio@little-bat.de

	This file is free software

 	This program is distributed in the hope that it will be useful,
 	but WITHOUT ANY WARRANTY; without even the implied warranty of
 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  

 	Permission to use, copy, modify, distribute, and sell this software and
 	its documentation for any purpose is hereby granted without fee, provided
 	that the above copyright notice appear in all copies and that both that
 	copyright notice and this permission notice appear in supporting
 	documentation, and that the name of the copyright holder not be used
 	in advertising or publicity pertaining to distribution of the software
 	without specific, written prior permission. The copyright holder makes no
 	representations about the suitability of this software for any purpose.
 	It is provided "as is" without express or implied warranty.

 	THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 	INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 	EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 	CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 	DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 	TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 	PERFORMANCE OF THIS SOFTWARE.

	Quick & dirty string utilities

	this module provides string manipulation for c-type strings.
	results are stored in a small buffer and are overwritten after some
	more calls. they are intended for immediate use, e.g. for printing.
*/


#ifndef _cstrings_h_
#define _cstrings_h_

#include	"kio/kio.h"



inline	bool	_is_uppercase(char c)	{ return uchar(c-'A')<='Z'-'A'; }
inline	char	_to_lower(char c)		{ return uchar(c-'A')<='Z'-'A' ? c|0x20 : c; }
inline	bool	_is_lowercase(char c)	{ return uchar(c-'a')<='z'-'a'; }
inline	char	_to_upper(char c)		{ return uchar(c-'a')<='z'-'a' ? c&~0x20 : c; }
inline	bool	_is_letter(char c)		{ return uchar((c|0x20)-'a')<='z'-'a'; }

inline	bool	_is_bin_digit(char c)  	{ return uchar(c-'0')<='1'-'0'; } // { return (c|1)=='1'; }
inline	bool	_is_oct_digit(char c)  	{ return uchar(c-'0')<='7'-'0'; } // { return (c|7)=='7'; }
inline	bool	_is_dec_digit(char c)  	{ return uchar(c-'0')<='9'-'0'; }
inline	bool	_is_hex_digit(char c) 	{ return uchar(c-'0')<='9'-'0' || uchar((c|0x20)-'a') <= 'f'-'a'; }

inline	bool	_no_bin_digit(char c)  	{ return uchar(c-'0')>'1'-'0'; } // { return (c|1)=='1'; }
inline	bool	_no_oct_digit(char c)  	{ return uchar(c-'0')>'7'-'0'; } // { return (c|7)=='7'; }
inline	bool	_no_dec_digit(char c)  	{ return uchar(c-'0')>'9'-'0'; }
inline	bool	_no_hex_digit(char c) 	{ return uchar(c-'0')>'9'-'0' && uchar((c|0x20)-'a') > 'f'-'a'; }

// char -> digit value: ['0'..'9'] ---> [0..9]; non-digits ---> [10..255]
inline	int		_digit_val(char c)	 	{ return uchar(c-'0'); }
// char -> digit value: ['0'..'9']['A'..'Z']['a'..'z'] ---> [0...35]; non-digits ---> [36..233]
inline	int		_digit_value(char c)	{ return c<='9' ? uchar(c-'0') : int(uchar((c&~0x20)-'A'))+10; }



// ----	enum for ConvertedTo/FromStr() -------------
enum strconvtype
{
	str_noconv,
	str_html,
	str_escaped,
	str_printable		 = str_escaped,
	str_quoted
};


// ----	memory management ----
str 		NewStr		( int n );			// allocate memory with new, OMEM check
str			NewCopy		( cstr );			// allocate memory with new, OMEM check, and copy text


// user methods
inline int	StrLen		( cstr s )					{ return s?strlen(s):0; }		// c-string
inline int	StrLen		( const uchar* s )			{ return s?*s:0; }				// pascal-string

str			QString		( int len );
str			SpaceStr	( int n, char c=' ' );
str			WhiteStr	( cstr, char c=' ' );
str			SubStr		( cstr a, cstr e );

str			DupStr		( cstr );
str 		MulStr 		( cstr, int n );
str 		CatStr 		( cstr, cstr );
str 		CatStr 		( cstr, cstr, cstr, cstr=0, cstr=0, cstr=0 );
str 		MidStr 		( cstr, int a, int n );
str 		MidStr 		( cstr, int a );
str 		LeftStr 	( cstr, int n );
str 		RightStr 	( cstr, int n );

str			HexStr 		( long n, int len );
str			NumStr 		( double );
str			NumStr 		( long n );
inline str	NumStr 		( ulong n )					{ return NumStr((long)n); }
inline str	NumStr 		( int n )					{ return NumStr((long)n); }
inline str	NumStr 		( uint n )					{ return NumStr((long)n); }
str			CharStr		( char c );
#if defined(_MACINTOSH)
inline void	ToUpper		( str s )					{ UpperText(s,StrLen(s)); }
inline void	ToLower		( str s )					{ LowerText(s,StrLen(s)); }
#else
inline void	ToUpper		( str s )					{ if(s) for( ;*s;s++ ) *s = _to_upper(*s); }
inline void	ToLower		( str s )					{ if(s) for( ;*s;s++ ) *s = _to_lower(*s); }
#endif
str			UpperStr	( cstr );
str			LowerStr	( cstr );
str			ReplaceStr	( cstr, char oldchar, char newchar );
bool		SameStr		( cstr, cstr );
str			FindStr		( cstr target, cstr search );
str			RFindStr	( cstr target, cstr search );
OSErr 		ReadStr		( str , short fileID );
OSErr 		WriteStr	( cstr, short fileID );
void		SkipSpace 	( cstr, short& idx );
void		SkipWord	( cstr, short& idx );
str 		NextWord	( cstr, short& idx );
void		FindChar	( cstr, char c, short& idx );
str 		DurationStr	( uint d, cstr format = 0 );
str			ClockStr 	( uint d, cstr format = 0 );
str			VaUsing		( cstr format, va_list arg );
str			Using		( cstr format, ... );
str			SpeakingNumber ( double n );
str			ConvertedTo	( cstr, strconvtype );
str			ConvertedFrom(cstr, strconvtype );
inline str	Escaped		( cstr s )					{ return ConvertedTo(s,str_escaped); }
inline str	Unescaped	( cstr s )					{ return ConvertedFrom(s,str_escaped); }
inline str	Quoted		( cstr s )					{ return ConvertedTo(s,str_quoted); }
inline str	Unquoted	( cstr s )					{ return ConvertedFrom(s,str_quoted); }

char		NextChar	( const char *& p );		// read & skip next char, decode escape seqence
double		StrToDouble	( cptr a, cptr* endptr=NULL );
str			ParseStr	( cptr&  q );
inline str	ParseStr	( void*& q )				{ return ParseStr((cptr&)q); }

inline char	LastChar	( cstr s )					{ return s&&*s ? s[strlen(s)-1] : 0; }

str 		NewReadStr 	( FILE* f );				// read from file up to EOF,0,10,13,10+13,13+10

void		FlushQSPool	( );						// free up memory by purging all current cstrings

#define		CompileDate()		(__DATE__" at "__TIME__)

#endif
