/* GNU moe - My Own Editor
   Copyright (C) 2005-2025 Antonio Diaz Diaz.

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 2 of the License, or
   (at your option) any later version.

   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.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

namespace ISO_8859 {

/* 'seq[i]' begins a escape sequence (the characters following a '\').
   Return the corresponding code and, in *lenp, the number of bytes read.
   Return -1 if unknown escape sequence, -2 if syntax error.
*/
int escape( const std::string & seq, const unsigned long i,
            int * const lenp = 0, const bool allow_u = false );

// Replace special characters with escape sequences; '\n' --> "\n"
//
void escapize( const unsigned char ch, std::string & out );

bool islower( const unsigned char ch );
bool isupper( const unsigned char ch );
inline bool isalpha( const unsigned char ch )
  { return islower( ch ) || isupper( ch ); }
inline bool isalpha_( const unsigned char ch )
  { return ch == '_' || isalpha( ch ); }
inline bool isalnum_( const unsigned char ch )
  { return ( ch < 128 && std::isdigit( ch ) ) || isalpha_( ch ); }
inline bool isblank( const unsigned char ch )
  { return ch == ' ' || ch == '\t'; }
inline bool isspace( const unsigned char ch )	// is 'ch' whitespace?
  { return std::isspace( ch ) || ch == 0xA0; }

/* Don't consider characters in control block C1 (0x80-0x9F) as control chars
   so that UTF-8 file names can be copied from the buffer to the file prompt
   and typed in the buffer and in the file prompt. */
inline bool iscntrl( const unsigned char ch )
  { return ch < 32 || ch == 0x7F; }		// 0x80-0x9F appear in UTF-8
inline bool isgraph( const unsigned char ch )
  { return !iscntrl( ch ) && ch != ' ' && ch != 0xA0; }
inline bool isprint( const unsigned char ch )
  { return !iscntrl( ch ); }

inline bool isodigit( const unsigned char ch )	// is 'ch' an octal digit?
  { return ch <= '7' && ch >= '0'; }

inline bool isuchar( const int c ) { return c >= 0 && c <= 255; }

unsigned char base_char( const unsigned char ch );	// of equivalence class

const char * control_name( const unsigned char ch );	// '^A' --> "^A"
int controlize( int code );		// converts 'A' or 'a' into '^A'
int decontrolize( int code );		// converts '^A' or 'a' into 'A'
unsigned char tolower( const unsigned char ch );
unsigned char toupper( const unsigned char ch );
void map_to_ascii( const unsigned char ch, std::string & out );
int xvalue( const unsigned char ch );	// value of hex digit 'ch' or -1

// Do ch1 and ch2 belong to the same equivalence class?
inline bool equivalent( const unsigned char ch1, const unsigned char ch2,
                        const bool icase = false )
  {
  if( !icase || !isalpha( ch1 ) || !isalpha( ch2 ) )
    return base_char( ch1 ) == base_char( ch2 );
  return tolower( base_char( ch1 ) ) == tolower( base_char( ch2 ) );
  }

} // end namespace ISO_8859

const char * format_hex4( unsigned long long num );
