/* Generated from "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod" by precompile.pike running Pike v8.0 release 1089
 *
 * Do NOT edit this file.
 */

#undef PRECOMPILE_API_VERSION
#define PRECOMPILE_API_VERSION 6

#undef PRECOMPILE_SUB_PIKEVARS
#define PRECOMPILE_SUB_PIKEVARS 1

#undef PRECOMPILE_DYNAMIC_TYPES
#define PRECOMPILE_DYNAMIC_TYPES 1



#undef cmod___CMOD__
#define cmod___CMOD__ 1
#line 1 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
#line 1 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
#line 1 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
#line 3003 "/Users/hww3/devel/pike/lib/modules/Tools.pmod/Standalone.pmod/precompile.pike"







#line 3010 "/Users/hww3/devel/pike/lib/modules/Tools.pmod/Standalone.pmod/precompile.pike"
#line 1 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
#line 1 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
/* -*- c -*-
|| This file is part of Pike. For copyright information see COPYRIGHT.
|| Pike is distributed under GPL, LGPL and MPL. See the file COPYING
|| for more information.
*/

#include "global.h"
#include "stralloc.h"
#include "pike_macros.h"
#include "interpret.h"
#include "program.h"
#include "program_id.h"
#include "object.h"
#include "operators.h"
#include "module_support.h"
#include "array.h"

#include "config.h"
#include "normalize.h"
#include "split.h"
#include "buffer.h"
#include "uversion.h"
#include "rtl.h"



#ifndef PIKE_UNUSED_ATTRIBUTE
#define PIKE_UNUSED_ATTRIBUTE
#endif
#define CMOD_MAP_PROGRAM_IDS_DEFINED 1
static int ___cmod_map_program_ids(int id) PIKE_UNUSED_ATTRIBUTE;
#ifndef TYPEOF
/* Compat with older Pikes. */
#define TYPEOF(SVAL)	((SVAL).type)
#define SUBTYPEOF(SVAL)	((SVAL).subtype)
#define SET_SVAL_TYPE(SVAL, TYPE)	(TYPEOF(SVAL) = TYPE)
#define SET_SVAL_SUBTYPE(SVAL, TYPE)	(SUBTYPEOF(SVAL) = TYPE)
#define SET_SVAL(SVAL, TYPE, SUBTYPE, FIELD, EXPR) do {	\
    /* Set the type afterwards to avoid a clobbered	\
     * svalue in case EXPR throws. */			\
    (SVAL).u.FIELD = (EXPR);				\
    SET_SVAL_TYPE((SVAL), (TYPE));			\
    SET_SVAL_SUBTYPE((SVAL), (SUBTYPE));		\
  } while(0)
#endif /* !TYPEOF */
#ifndef PIKE_UNUSED
/* Compat with Pike 7.8 and earlier. */
/* NB: Not strictly correct; PIKE_UNUSED was added the
 *     day after set_program_id_to_id(), but good enough.
 */
#ifndef UNUSED
#define UNUSED(X)	X
#endif
#ifndef set_program_id_to_id
/* NB: Recent Pike 7.8 has a #define that conflicts with
 *     the following declaration.
 */
static void set_program_id_to_id(void*UNUSED(id)){}
#endif
#else /* */
PMOD_EXPORT void set_program_id_to_id( int (*to)(int) );
#endif /* !PIKE_UNUSED */


#ifndef DEFAULT_CMOD_STORAGE
#define CMOD_COND_USED
#define DEFAULT_CMOD_STORAGE static
#endif
#ifndef CMOD_COND_USED
# define f_Unicode_split_words_fun_num_used 1
#else
#undef f_Unicode_split_words_fun_num_used
#endif
#ifndef CMOD_COND_USED
# define f_Unicode_normalize_fun_num_used 1
#else
#undef f_Unicode_normalize_fun_num_used
#endif
#ifndef CMOD_COND_USED
# define f_Unicode_is_wordchar_fun_num_used 1
#else
#undef f_Unicode_is_wordchar_fun_num_used
#endif
#ifndef CMOD_COND_USED
# define f_Unicode_is_rtlchar_fun_num_used 1
#else
#undef f_Unicode_is_rtlchar_fun_num_used
#endif
#ifndef CMOD_COND_USED
# define f_Unicode_is_rtlstring_fun_num_used 1
#else
#undef f_Unicode_is_rtlstring_fun_num_used
#endif
#ifndef CMOD_COND_USED
# define f_Unicode_split_words_and_normalize_fun_num_used 1
#else
#undef f_Unicode_split_words_and_normalize_fun_num_used
#endif
/*! @module Unicode
 */

#line 30 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
static void push_words( struct buffer *data, struct words *w )
{
const p_wchar2 *d = data->data;
struct array *r = allocate_array( w->size );
unsigned int i;
for( i=0; i<w->size; i++ )
{
SET_SVAL(r->item[i], PIKE_T_STRING, 0, string,
make_shared_binary_string2( d+w->words[i].start,
w->words[i].size ));
}
r->type_field = BIT_STRING;
push_array( r );
uc_buffer_free( data );
uc_words_free( w );
}

/*! @decl array(string) split_words(string input)
 *! Splits the input string into an array of words, on the boundaries between
 *! the different kinds of word characters as defined by @[is_wordchar]. The
 *! result is an array of words, with the non-word characters between them
 *! thrown away.
 */
#define f_Unicode_split_words_defined

#ifdef f_Unicode_split_words_fun_num_used
DEFAULT_CMOD_STORAGE ptrdiff_t f_Unicode_split_words_fun_num = 0;

#endif /* f_Unicode_split_words_fun_num_used */
DEFAULT_CMOD_STORAGE void f_Unicode_split_words(INT32 args) {
#line 53 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
struct pike_string * input;
#line 53 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
if(args != 1) wrong_number_of_args_error("split_words",args,1);
#line 53 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
if(TYPEOF(Pike_sp[0-1]) != PIKE_T_STRING) SIMPLE_ARG_TYPE_ERROR("split_words",1,"string");
#line 53 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
debug_malloc_pass(input=Pike_sp[0-1].u.string);
#line 55 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
{
struct words *res;
struct buffer * data;
data = uc_buffer_from_pikestring( input );
res = unicode_split_words_buffer( data );
pop_n_elems( args );
push_words( data, res );
}

}
/*! @decl array(string) split_words_and_normalize(string input)
 *!
 *! A less wasteful equivalent of
 *! @expr{@[split_words](@[normalize](@[input], "NFKD"))@}.
 */
#define f_Unicode_split_words_and_normalize_defined

#ifdef f_Unicode_split_words_and_normalize_fun_num_used
DEFAULT_CMOD_STORAGE ptrdiff_t f_Unicode_split_words_and_normalize_fun_num = 0;

#endif /* f_Unicode_split_words_and_normalize_fun_num_used */
DEFAULT_CMOD_STORAGE void f_Unicode_split_words_and_normalize(INT32 args) {
#line 69 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
struct pike_string * input;
#line 69 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
if(args != 1) wrong_number_of_args_error("split_words_and_normalize",args,1);
#line 69 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
if(TYPEOF(Pike_sp[0-1]) != PIKE_T_STRING) SIMPLE_ARG_TYPE_ERROR("split_words_and_normalize",1,"string");
#line 69 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
debug_malloc_pass(input=Pike_sp[0-1].u.string);
#line 71 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
{
struct words *res;
{
struct buffer *data;
data = uc_buffer_from_pikestring(input);
pop_n_elems( args );
data = unicode_decompose_buffer( data, COMPAT_BIT );
res = unicode_split_words_buffer( data );
push_words( data, res );
}
}

}
/*! @decl string normalize( string data, string method );
 *!
 *! Normalize the given unicode string according to the specified method.
 *! 
 *! The methods are:
 *!
 *!  NFC, NFD, NFKC and NFKD.
 *!  
 *! The methods are described in detail in the UAX #15 document, which
 *! can currently be found at
 *! http://www.unicode.org/unicode/reports/tr15/tr15-21.html
 *!
 *! A short description:
 *! 
 *! C and D specifies whether to decompose (D) complex characters to
 *! their parts, or compose (C) single characters to complex ones.
 *!
 *! K specifies whether or not do a canonical or compatibility
 *! conversion. When K is present, compatibility transformations are
 *! performed as well as the canonical transformations.
 *!
 *! @i{In the following text, 'X' denotes the single character 'X', even
 *!  if there is more than one character inside the quotation marks. 
 *!  The reson is that it's somewhat hard to describe unicode in
 *!  iso-8859-1.@}
 *!
 *! The Unicode Standard defines two equivalences between characters:
 *! canonical equivalence and compatibility equivalence. Canonical
 *! equivalence is a basic equivalency between characters or
 *! sequences of characters. 
 *!
 *! 'Å'  and  'A' '° (combining ring above)' are canonically equivalent.
 *!
 *! For round-trip compatibility with existing standards, Unicode has
 *! encoded many entities that are really variants of existing nominal
 *! characters. The visual representations of these character are
 *! typically a subset of the possible visual representations of the
 *! nominal character. These are given compatibility decompositions in
 *! the standard. Because the characters are visually distinguished,
 *! replacing a character by a compatibility equivalent may lose
 *! formatting information unless supplemented by markup or styling.
 *!
 *! Examples of compatibility equivalences:
 *! @ul
 *!   @item
 *!     Font variants (thin, italic, extra wide characters etc)
 *!   @item
 *!     Circled and squared characters
 *!   @item
 *!     super/subscript ('²' -> '2')
 *!   @item
 *!     Fractions       ('½' -> '1/2')
 *!   @item
 *!     Other composed characters ('fi' -> 'f' 'i',  'kg' -> 'k' 'g')
 *! @endul
 *!
 */
#define f_Unicode_normalize_defined

#ifdef f_Unicode_normalize_fun_num_used
DEFAULT_CMOD_STORAGE ptrdiff_t f_Unicode_normalize_fun_num = 0;

#endif /* f_Unicode_normalize_fun_num_used */
DEFAULT_CMOD_STORAGE void f_Unicode_normalize(INT32 args) {
#line 140 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
struct pike_string * s;
#line 140 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
struct pike_string * flags;
#line 140 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
if(args != 2) wrong_number_of_args_error("normalize",args,2);
#line 140 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
if(TYPEOF(Pike_sp[0-2]) != PIKE_T_STRING) SIMPLE_ARG_TYPE_ERROR("normalize",1,"string");
#line 140 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
debug_malloc_pass(s=Pike_sp[0-2].u.string);
#line 140 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
if(TYPEOF(Pike_sp[1-2]) != PIKE_T_STRING) SIMPLE_ARG_TYPE_ERROR("normalize",2,"string");
#line 140 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
debug_malloc_pass(flags=Pike_sp[1-2].u.string);
#line 142 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
{
int _flags=0, i;

for( i = 0; i<flags->len; i++ )
switch( flags->str[ i ] )
{
case 'K': _flags |= COMPAT_BIT; break;
case 'C': _flags |= COMPOSE_BIT; break;
}

do { struct pike_string * ret_=(unicode_normalize( s, _flags )); pop_n_elems(2); push_string(ret_); return; }while(0);
#line 153 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
}

}
/*! @decl int is_wordchar(int c)
 *! Returns whether a unicode character @[c] is a word, part of a word or not.
 *! @returns
 *!   @int
 *!     @value 2
 *!       The character is an ideograph (a CJK single-word character)
 *!     @value 1
 *!       The character is a letter, number or non-spacing mark, as defined by
 *!       its unicode (general category) specification
 *!     @value 0
 *!       Any other character (such as symbols, punctuation and separators)
 *!   @endint
 */
#define f_Unicode_is_wordchar_defined

#ifdef f_Unicode_is_wordchar_fun_num_used
DEFAULT_CMOD_STORAGE ptrdiff_t f_Unicode_is_wordchar_fun_num = 0;

#endif /* f_Unicode_is_wordchar_fun_num_used */
DEFAULT_CMOD_STORAGE void f_Unicode_is_wordchar(INT32 args) {
#line 168 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
INT_TYPE c;
#line 168 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
if(args != 1) wrong_number_of_args_error("is_wordchar",args,1);
#line 168 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
if(TYPEOF(Pike_sp[0-1]) != PIKE_T_INT) SIMPLE_ARG_TYPE_ERROR("is_wordchar",1,"int");
#line 168 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
c=Pike_sp[0-1].u.integer;
#line 170 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
{
do { INT_TYPE ret_=(unicode_is_wordchar( c )); pop_stack(); push_int(ret_); return; }while(0);
#line 172 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
}

}
#line 174 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
static int is_rtl_char( int c )
{
unsigned int rtl=0, i;
for(i=0; i<NELEM(_rtl); i++)
{
if(c<_rtl[i]) return rtl;
rtl ^= 1;
}
return 0;
}

/*! @decl int is_rtlchar( int c )
 *! Returns @expr{1@} if the character is a RTL character or
 *! indicator, otherwise @expr{0@}.
 */
#define f_Unicode_is_rtlchar_defined

#ifdef f_Unicode_is_rtlchar_fun_num_used
DEFAULT_CMOD_STORAGE ptrdiff_t f_Unicode_is_rtlchar_fun_num = 0;

#endif /* f_Unicode_is_rtlchar_fun_num_used */
DEFAULT_CMOD_STORAGE void f_Unicode_is_rtlchar(INT32 args) {
#line 189 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
INT_TYPE c;
#line 189 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
if(args != 1) wrong_number_of_args_error("is_rtlchar",args,1);
#line 189 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
if(TYPEOF(Pike_sp[0-1]) != PIKE_T_INT) SIMPLE_ARG_TYPE_ERROR("is_rtlchar",1,"int");
#line 189 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
c=Pike_sp[0-1].u.integer;
#line 191 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
{
do { INT_TYPE ret_=(is_rtl_char(c)); pop_stack(); push_int(ret_); return; }while(0);
#line 193 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
}

}
/*! @decl int is_rtlstring( string s )
 *! Returns @expr{1@} if the string contains RTL characters or
 *! RTL indicators, otherwise @expr{0@}.
 */
#define f_Unicode_is_rtlstring_defined

#ifdef f_Unicode_is_rtlstring_fun_num_used
DEFAULT_CMOD_STORAGE ptrdiff_t f_Unicode_is_rtlstring_fun_num = 0;

#endif /* f_Unicode_is_rtlstring_fun_num_used */
DEFAULT_CMOD_STORAGE void f_Unicode_is_rtlstring(INT32 args) {
#line 199 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
struct pike_string * s;
#line 199 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
if(args != 1) wrong_number_of_args_error("is_rtlstring",args,1);
#line 199 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
if(TYPEOF(Pike_sp[0-1]) != PIKE_T_STRING) SIMPLE_ARG_TYPE_ERROR("is_rtlstring",1,"string");
#line 199 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
debug_malloc_pass(s=Pike_sp[0-1].u.string);
#line 201 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
{
int shift, len;
char *str;
shift = s->size_shift;
if( shift==0 ) do { INT_TYPE ret_=(0); pop_stack(); push_int(ret_); return; }while(0);
#line 206 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
len = s->len;
str = s->str;
while( --len )
if( is_rtl_char(INDEX_CHARP(str,len,shift)) ) do { INT_TYPE ret_=(1); pop_stack(); push_int(ret_); return; }while(0);do { INT_TYPE ret_=(
#line 210 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
0); pop_stack(); push_int(ret_); return; }while(0);
#line 211 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
}

}
/*! @decl constant version
 *! Contains the version of the current Unicode database as a string,
 *! e.g. @expr{"5.0.0"@}.
 */

/*! @endmodule
 */

#line 221 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
PIKE_MODULE_INIT
{

#ifdef CMOD_MAP_PROGRAM_IDS_DEFINED
set_program_id_to_id( ___cmod_map_program_ids );

#endif /* CMOD_MAP_PROGRAM_IDS_DEFINED */

#ifdef f_Unicode_split_words_defined

#ifdef f_Unicode_split_words_fun_num_used
  f_Unicode_split_words_fun_num =
#endif /* f_Unicode_split_words_fun_num_used */
#line 53 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
    ADD_FUNCTION2("split_words", f_Unicode_split_words, tFunc(tStr,tArr(tStr)), 0, OPT_TRY_OPTIMIZE);

#endif /* f_Unicode_split_words_defined */

#ifdef f_Unicode_split_words_and_normalize_defined

#ifdef f_Unicode_split_words_and_normalize_fun_num_used
  f_Unicode_split_words_and_normalize_fun_num =
#endif /* f_Unicode_split_words_and_normalize_fun_num_used */
#line 69 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
    ADD_FUNCTION2("split_words_and_normalize", f_Unicode_split_words_and_normalize, tFunc(tStr,tArr(tStr)), 0, OPT_TRY_OPTIMIZE);

#endif /* f_Unicode_split_words_and_normalize_defined */

#ifdef f_Unicode_normalize_defined

#ifdef f_Unicode_normalize_fun_num_used
  f_Unicode_normalize_fun_num =
#endif /* f_Unicode_normalize_fun_num_used */
#line 140 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
    ADD_FUNCTION2("normalize", f_Unicode_normalize, tFunc(tStr tStr,tStr), 0, OPT_TRY_OPTIMIZE);

#endif /* f_Unicode_normalize_defined */

#ifdef f_Unicode_is_wordchar_defined

#ifdef f_Unicode_is_wordchar_fun_num_used
  f_Unicode_is_wordchar_fun_num =
#endif /* f_Unicode_is_wordchar_fun_num_used */
#line 168 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
    ADD_FUNCTION2("is_wordchar", f_Unicode_is_wordchar, tFunc("\10\200\0\0\0\177\377\377\377","\10\200\0\0\0\177\377\377\377"), 0, OPT_TRY_OPTIMIZE);

#endif /* f_Unicode_is_wordchar_defined */

#ifdef f_Unicode_is_rtlchar_defined

#ifdef f_Unicode_is_rtlchar_fun_num_used
  f_Unicode_is_rtlchar_fun_num =
#endif /* f_Unicode_is_rtlchar_fun_num_used */
#line 189 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
    ADD_FUNCTION2("is_rtlchar", f_Unicode_is_rtlchar, tFunc("\10\200\0\0\0\177\377\377\377","\10\200\0\0\0\177\377\377\377"), 0, OPT_TRY_OPTIMIZE);

#endif /* f_Unicode_is_rtlchar_defined */

#ifdef f_Unicode_is_rtlstring_defined

#ifdef f_Unicode_is_rtlstring_fun_num_used
  f_Unicode_is_rtlstring_fun_num =
#endif /* f_Unicode_is_rtlstring_fun_num_used */
#line 199 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
    ADD_FUNCTION2("is_rtlstring", f_Unicode_is_rtlstring, tFunc(tStr,"\10\200\0\0\0\177\377\377\377"), 0, OPT_TRY_OPTIMIZE);

#endif /* f_Unicode_is_rtlstring_defined */

#ifdef CMOD_MAP_PROGRAM_IDS_DEFINED
set_program_id_to_id( 0 );
#endif /* CMOD_MAP_PROGRAM_IDS_DEFINED */
#line 224 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
unicode_normalize_init();
add_string_constant("version", UVERSION, 0);
}

PIKE_MODULE_EXIT
{
#line 231 "/Users/hww3/devel/pike/src/post_modules/Unicode/unicode_module.cmod"
}


#ifdef CMOD_MAP_PROGRAM_IDS_DEFINED
static int ___cmod_map_program_ids(int id)
{
  int i = 0;
  if( (id&0x7f000000) != 0x7f000000 ) return id;
  id = id&0x00ffffff;
  return 0;
}
#endif /* CMOD_MAP_PROGRAM_IDS_DEFINED */
