#include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include #define MAX_ERRSTR_LEN 1000 typedef struct { AspellCanHaveError *ret; AspellSpeller *speller; AspellConfig *config; char lastError[MAX_ERRSTR_LEN+1]; int errnum; /* Deprecated - only returns 0/1 */ } Aspell_object; static int _create_speller(Aspell_object *self) { AspellCanHaveError *ret; ret = new_aspell_speller(self->config); if ( (self->errnum = aspell_error_number(ret) ) ) { strncpy(self->lastError, aspell_error_message(ret), MAX_ERRSTR_LEN); return 0; } /* The config is no longer needed (check for errors here?) */ delete_aspell_config(self->config); self->config = NULL; self->speller = to_aspell_speller(ret); self->config = aspell_speller_config(self->speller); return 1; } MODULE = Text::Aspell PACKAGE = Text::Aspell # Make sure that we have at least xsubpp version 1.922. REQUIRE: 1.922 Aspell_object * new(CLASS) char *CLASS CODE: RETVAL = (Aspell_object*)safemalloc( sizeof( Aspell_object ) ); if( RETVAL == NULL ){ warn("unable to malloc Aspell_object"); XSRETURN_UNDEF; } memset( RETVAL, 0, sizeof( Aspell_object ) ); /* create the configuration */ RETVAL->config = new_aspell_config(); /* Set initial default */ /* * aspell_config_replace(RETVAL->config, "language-tag", "en"); * default language is 'EN' */ OUTPUT: RETVAL void DESTROY(self) Aspell_object *self CODE: if ( self->speller ) delete_aspell_speller(self->speller); safefree( (char*)self ); int create_speller(self) Aspell_object *self CODE: if ( !_create_speller(self) ) XSRETURN_UNDEF; RETVAL = 1; OUTPUT: RETVAL int print_config(self) Aspell_object *self PREINIT: AspellKeyInfoEnumeration * key_list; const AspellKeyInfo * entry; CODE: key_list = aspell_config_possible_elements( self->config, 0 ); while ( (entry = aspell_key_info_enumeration_next(key_list) ) ) PerlIO_printf(PerlIO_stdout(),"%20s: %s\n", entry->name, aspell_config_retrieve(self->config, entry->name) ); delete_aspell_key_info_enumeration(key_list); RETVAL = 1; OUTPUT: RETVAL int set_option(self, tag, val ) Aspell_object *self char *tag char *val CODE: self->lastError[0] = '\0'; aspell_config_replace(self->config, tag, val ); if ( (self->errnum = aspell_config_error_number( self->config) ) ) { strcpy(self->lastError, aspell_config_error_message( self->config ) ); XSRETURN_UNDEF; } RETVAL = 1; OUTPUT: RETVAL int remove_option(self, tag ) Aspell_object *self char *tag CODE: self->lastError[0] = '\0'; aspell_config_remove(self->config, tag ); if ( (self->errnum = aspell_config_error_number( self->config) ) ) { strcpy(self->lastError, aspell_config_error_message( self->config ) ); XSRETURN_UNDEF; } RETVAL = 1; OUTPUT: RETVAL char * get_option(self, val) Aspell_object *self char *val CODE: self->lastError[0] = '\0'; RETVAL = (char *)aspell_config_retrieve(self->config, val); if ( (self->errnum = aspell_config_error_number( self->config) ) ) { strcpy(self->lastError, aspell_config_error_message( self->config ) ); XSRETURN_UNDEF; } OUTPUT: RETVAL void get_option_as_list(self, val) Aspell_object *self char * val PREINIT: AspellStringList * lst = new_aspell_string_list(); AspellMutableContainer * lst0 = aspell_string_list_to_mutable_container(lst); AspellStringEnumeration * els; const char *option_value; PPCODE: if (!self->config ) XSRETURN_UNDEF; aspell_config_retrieve_list(self->config, val, lst0); if ( (self->errnum = aspell_config_error_number( self->config) ) ) { strncpy(self->lastError, aspell_config_error_message( self->config ), MAX_ERRSTR_LEN); delete_aspell_string_list(lst); XSRETURN_UNDEF; } els = aspell_string_list_elements(lst); while ( (option_value = aspell_string_enumeration_next(els)) != 0) XPUSHs(sv_2mortal(newSVpv( option_value ,0 ))); delete_aspell_string_enumeration(els); delete_aspell_string_list(lst); char * errstr(self) Aspell_object *self CODE: RETVAL = (char*) self->lastError; OUTPUT: RETVAL int errnum(self) Aspell_object *self CODE: RETVAL = self->errnum; OUTPUT: RETVAL int check(self,word) Aspell_object *self char * word CODE: self->lastError[0] = '\0'; self->errnum = 0; if (!self->speller && !_create_speller(self) ) XSRETURN_UNDEF; RETVAL = aspell_speller_check(self->speller, word, -1); if ( aspell_speller_error( self->speller ) ) { self->errnum = aspell_speller_error_number( self->speller ); strncpy(self->lastError, aspell_speller_error_message( self->speller ), MAX_ERRSTR_LEN); XSRETURN_UNDEF; } OUTPUT: RETVAL void suggest(self, word) Aspell_object *self char * word PREINIT: const AspellWordList *wl; AspellStringEnumeration *els; const char *suggestion; PPCODE: self->lastError[0] = '\0'; self->errnum = 0; if (!self->speller && !_create_speller(self) ) XSRETURN_UNDEF; wl = aspell_speller_suggest(self->speller, word, -1); if (!wl) { self->errnum = aspell_speller_error_number( self->speller ); strncpy(self->lastError, aspell_speller_error_message(self->speller), MAX_ERRSTR_LEN); XSRETURN_UNDEF; } els = aspell_word_list_elements(wl); while ( (suggestion = aspell_string_enumeration_next(els)) ) XPUSHs(sv_2mortal(newSVpv( suggestion ,0 ))); delete_aspell_string_enumeration(els); int add_to_personal(self,word) Aspell_object *self char * word CODE: self->lastError[0] = '\0'; self->errnum = 0; if (!self->speller && !_create_speller(self) ) XSRETURN_UNDEF; RETVAL = aspell_speller_add_to_personal(self->speller, word, -1); if ( aspell_speller_error( self->speller ) ) { self->errnum = aspell_speller_error_number( self->speller ); strncpy(self->lastError, aspell_speller_error_message(self->speller), MAX_ERRSTR_LEN); XSRETURN_UNDEF; } OUTPUT: RETVAL int add_to_session(self,word) Aspell_object *self char * word CODE: self->lastError[0] = '\0'; self->errnum = 0; if (!self->speller && !_create_speller(self) ) XSRETURN_UNDEF; RETVAL = aspell_speller_add_to_session(self->speller, word, -1); if ( aspell_speller_error( self->speller ) ) { self->errnum = aspell_speller_error_number( self->speller ); strncpy(self->lastError, aspell_speller_error_message(self->speller), MAX_ERRSTR_LEN); XSRETURN_UNDEF; } OUTPUT: RETVAL int store_replacement(self,word,replacement) Aspell_object *self char * word char * replacement CODE: self->lastError[0] = '\0'; self->errnum = 0; if (!self->speller && !_create_speller(self) ) XSRETURN_UNDEF; RETVAL = aspell_speller_store_replacement(self->speller, word, -1, replacement, -1); if ( aspell_speller_error( self->speller ) ) { self->errnum = aspell_speller_error_number( self->speller ); strncpy(self->lastError, aspell_speller_error_message(self->speller), MAX_ERRSTR_LEN); XSRETURN_UNDEF; } OUTPUT: RETVAL int save_all_word_lists(self) Aspell_object *self CODE: self->lastError[0] = '\0'; self->errnum = 0; if (!self->speller && !_create_speller(self) ) XSRETURN_UNDEF; RETVAL = aspell_speller_save_all_word_lists(self->speller); if ( aspell_speller_error( self->speller ) ) { self->errnum = aspell_speller_error_number( self->speller ); strncpy(self->lastError, aspell_speller_error_message(self->speller), MAX_ERRSTR_LEN); XSRETURN_UNDEF; } OUTPUT: RETVAL int clear_session(self) Aspell_object *self CODE: self->lastError[0] = '\0'; self->errnum = 0; if (!self->speller && !_create_speller(self) ) XSRETURN_UNDEF; RETVAL = aspell_speller_clear_session(self->speller); if ( aspell_speller_error( self->speller ) ) { self->errnum = aspell_speller_error_number( self->speller ); strncpy(self->lastError, aspell_speller_error_message(self->speller), MAX_ERRSTR_LEN); XSRETURN_UNDEF; } OUTPUT: RETVAL void list_dictionaries(self) Aspell_object *self PREINIT: AspellDictInfoList * dlist; AspellDictInfoEnumeration * dels; const AspellDictInfo * entry; PPCODE: if (!self->config ) XSRETURN_UNDEF; dlist = get_aspell_dict_info_list(self->config); dels = aspell_dict_info_list_elements(dlist); while ( (entry = aspell_dict_info_enumeration_next(dels)) != 0) { int len; char *dictname; len = strlen( entry->name ) + strlen( entry->jargon ) + strlen( entry->code ) + strlen( entry->size_str ) + strlen( entry->module->name ) + 4; dictname = (char *)safemalloc( len + 1 ); sprintf( dictname, "%s:%s:%s:%s:%s", entry->name, entry->code, entry->jargon, entry->size_str, entry->module->name ); PUSHs(sv_2mortal(newSVpv( dictname ,0 ))); safefree( dictname ); } delete_aspell_dict_info_enumeration(dels); void dictionary_info(self) Aspell_object *self; PREINIT: AspellDictInfoList *dlist; AspellDictInfoEnumeration *dels; const AspellDictInfo *entry; PPCODE: if (!self->config ) /* type map should catch this error, I'd think */ XSRETURN_UNDEF; dlist = get_aspell_dict_info_list(self->config); dels = aspell_dict_info_list_elements(dlist); while ( (entry = aspell_dict_info_enumeration_next(dels)) != 0) { HV * dict_entry = newHV(); if ( entry->name[0] ) hv_store(dict_entry, "name", 4, newSVpv(entry->name,0),0); if ( entry->jargon[0] ) hv_store(dict_entry, "jargon",6, newSVpv(entry->jargon,0),0); if ( entry->code[0] ) hv_store(dict_entry, "code", 4, newSVpv(entry->code,0),0); if ( entry->code ) hv_store(dict_entry, "size", 4, newSViv(entry->size),0); if ( entry->module->name[0] ) hv_store(dict_entry, "module",6, newSVpv(entry->module->name,0),0); XPUSHs(sv_2mortal(newRV_noinc((SV*)dict_entry))); } delete_aspell_dict_info_enumeration(dels); SV * fetch_option_keys(self) Aspell_object *self; PREINIT: AspellKeyInfoEnumeration * key_list; const AspellKeyInfo * entry; HV * option_hash; CODE: key_list = aspell_config_possible_elements( self->config, 0 ); option_hash = newHV(); while ( (entry = aspell_key_info_enumeration_next(key_list) ) ) { HV * KeyInfo = newHV(); hv_store(KeyInfo, "type", 4, newSViv((int)entry->type),0); if ( entry->def && entry->def[0] ) hv_store(KeyInfo, "default", 7, newSVpv(entry->def,0),0); if ( entry->desc && entry->desc[0] ) hv_store(KeyInfo, "desc",4, newSVpv(entry->desc,0),0); hv_store(option_hash, entry->name, strlen(entry->name), newRV_noinc((SV *)KeyInfo),0); } delete_aspell_key_info_enumeration(key_list); RETVAL = newRV_noinc((SV *)option_hash); OUTPUT: RETVAL