/* # skkinput (Simple Kana-Kanji Input) * skkconfig.c --- Read dot.skkinput. * This file is part of skkinput. * Copyright (C) 1997 * Takashi SAKAMOTO (sakamoto@yajima.kuis.kyoto-u.ac.jp) * * 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, 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 skkinput; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "commondef.h" #include "buffers.h" #include "SeparateWin.h" #include "config.h" #include "skkkey.h" /* * 定数定義、構造体の宣言…。 */ enum { PARAM_BOOLEAN, PARAM_INTEGER, PARAM_STRING, PARAM_PATH, PARAM_INPUT_VECTOR, PARAM_ROM_KANA_RULE_LIST, #ifdef THIS_IS_NECESSARY PARAM_DEFINE_KEY_SKKMAP, #endif PARAM_DEFINE_KEY_SKKJMAP, PARAM_DEFINE_KEY_ABBREVMAP, PARAM_SKKINPUTLISP, #ifdef THIS_IS_NECESSARY PARAM_UNDEFINE_KEY_SKKMAP, #endif PARAM_UNDEFINE_KEY_SKKJMAP, PARAM_UNDEFINE_KEY_ABBREVMAP, PARAM_END, } ; typedef struct { char *string ; int action ; void *argument ; } SkkInpDef ; struct skk_rom_kana_rule_list { struct skk_rom_kana_rule element ; struct skk_rom_kana_rule_list *next ; } ; /* * プロトタイプ宣言。 */ /* skkldic.c */ extern int check_skkinput_jisyo_code( char *path ) ; /* parseStr.c */ struct myChar *skip_empty_symbols( struct myChar *ptr ) ; struct myChar *parseString ( struct myChar *string, struct myChar **dest, int *result ) ; unsigned char *expand_file_name( unsigned char *path ) ; int parseKeyString ( struct myChar *string, struct myChar *buffer, int bufsize ) ; /* lispeval.c */ extern int skkinputlisp_weak_eval ( struct myChar *commandstring ) ; /* keymap.c */ extern int skkinput_CompileDefaultKeyBind( void ) ; extern int skkinput_DefineKey ( struct myChar *string, int length, int func_no, int map ) ; extern int skkinput_UndefineKey ( struct myChar *string, int length, int map ) ; /* * skkinput の動作を決定する変数群。 */ static int skkserv_portnum ; /* obsoleted, use skkserv_service */ extern char *skkserv_host ; extern char *skkserv_service; extern int skkserv_pf; static char *skkserv_protocol_family ; extern char *skkinput_local_jisyo_name ; extern char *skkinput_backup_jisyo_name ; extern char *skk_local_jisyo_name ; extern char *skkinput_record_name ; extern int skk_egg_like_newline ; extern int skkinput_dabbrev_like_completion ; extern int skkinput_chatadaptermode ; extern int skkinput_search_skk_jisyo ; extern int skkinput_keep_record ; extern int skkinput_date_ad ; extern int skkinput_number_style ; extern int skkinput_delete_implies_kakutei ; extern int skkinput_use_numeric_conversion ; extern int skkinput_tab_width ; extern int skkinput_rjj_like_input ; extern Boolean skkinput_jisyo_dirty ; extern unsigned long skkinput_autosave_interval ; /* * 初期入力ベクトル。 */ static unsigned char *skkinput_default_input_vector[ 128 ] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "!", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "、", "ー", "。", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ":", ";", NULL, NULL, NULL, "?", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "「", NULL, "」", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, } ; /* * 実際に変換に使われる入力ベクトル。 */ struct myChar *skkinput_input_vector[ 128 ] ; /* * 初期全角入力ベクトル。 */ static unsigned char *skkinput_default_zenkaku_vector[ 128 ] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, " ", "!", "”", "#", "$", "%", "&", "’", "(", ")", "*", "+", ",", "−", ".", "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";", "<", "=", ">", "?", "@", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[", "\", "]", "^", "_", "‘", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "{", "|", "}", "〜", NULL, } ; /* * 実際に変換に使われる全角ベクトル。 */ struct myChar *skkinput_zenkaku_vector[ 128 ] ; /* * 初期ローマ字仮名変換ルールリスト。 */ static struct skk_rom_kana_rule skkinput_default_rom_kana_rule_list[] = { { NULL, NULL, NULL, NULL }, { NULL, NULL, NULL, NULL }, { NULL, NULL, NULL, NULL }, } ; static struct skk_rom_kana_rule_list *skkinput_rom_kana_rule_list_top ; extern struct skk_rom_kana_rule *skkinput_rom_kana_rule_list ; /* * .skkinput に記述できる操作の一覧。 */ SkkInpDef skkinput_initdef[] = { { "skk-port-num:", PARAM_INTEGER, &skkserv_portnum }, { "skk-service:", PARAM_STRING, &skkserv_service }, { "skk-server-protocol-family:", PARAM_STRING, &skkserv_protocol_family }, { "skk-server-host:", PARAM_STRING, &skkserv_host }, { "skkinput-jisyo:", PARAM_PATH, &skkinput_local_jisyo_name }, { "skkinput-backup-jisyo:", PARAM_PATH, &skkinput_backup_jisyo_name }, { "skk-jisyo:", PARAM_PATH, &skk_local_jisyo_name }, { "skkinput-record:", PARAM_PATH, &skkinput_record_name }, { "skkinput-egg-like-newline:", PARAM_BOOLEAN, &skk_egg_like_newline }, { "skkinput-dabbrev-like-completion:", PARAM_BOOLEAN, &skkinput_dabbrev_like_completion }, { "skkinput-chat-adapter-mode:", PARAM_BOOLEAN, &skkinput_chatadaptermode }, { "skkinput-keep-record:", PARAM_BOOLEAN, &skkinput_keep_record }, { "skkinput-search-skk-jisyo:", PARAM_BOOLEAN, &skkinput_search_skk_jisyo }, { "skkinput-date-ad:", PARAM_BOOLEAN, &skkinput_date_ad }, { "skkinput-number-style:", PARAM_INTEGER, &skkinput_number_style }, { "skkinput-delete-implies-kakutei:", PARAM_BOOLEAN, &skkinput_delete_implies_kakutei }, { "skkinput-use-numeric-conversion:", PARAM_BOOLEAN, &skkinput_use_numeric_conversion }, { "skkinput-zenkaku-vector:", PARAM_INPUT_VECTOR, skkinput_zenkaku_vector }, { "skkinput-input-vector:", PARAM_INPUT_VECTOR, skkinput_input_vector }, { "skkinput-rom-kana-rule-list:", PARAM_ROM_KANA_RULE_LIST, &skkinput_rom_kana_rule_list_top }, #ifdef THIS_IS_NECESSARY { "define-key-skkmap:", PARAM_DEFINE_KEY_SKKMAP, NULL }, { "define-key-skkjmap:", PARAM_DEFINE_KEY_SKKJMAP, NULL }, #else { "define-key-skkmap:", PARAM_DEFINE_KEY_SKKJMAP, NULL }, #endif { "define-key-abbrevmap:", PARAM_DEFINE_KEY_ABBREVMAP, NULL }, #ifdef THIS_IS_NECESSARY { "undefine-key-skkmap:", PARAM_UNDEFINE_KEY_SKKMAP, NULL }, { "undefine-key-skkjmap:", PARAM_UNDEFINE_KEY_SKKJMAP, NULL }, #else { "undefine-key-skkmap:", PARAM_UNDEFINE_KEY_SKKJMAP, NULL }, #endif { "undefine-key-abbrevmap:", PARAM_UNDEFINE_KEY_ABBREVMAP,NULL }, { "tab-width:", PARAM_INTEGER, &skkinput_tab_width }, { "skkinput-lisp:", PARAM_SKKINPUTLISP, NULL }, { "skkinput-rjj-like-input:", PARAM_BOOLEAN, &skkinput_rjj_like_input }, { "skkinput-autosave-interval:", PARAM_INTEGER, &skkinput_autosave_interval }, { NULL, PARAM_END, NULL }, } ; /* * 指定された文字列が空白文字だけからなるのかどうかを返す関数。 *---- * コメント以下は空白文字であるとして扱う。 */ static int is_empty_line( struct myChar *ptr ) { while( !IS_END_OF_STRING( *ptr ) && !IS_ASCII_EQUAL( *ptr, ';' ) ){ if( !IS_ASCII_EQUAL( *ptr, 0x20 ) && !IS_ASCII_EQUAL( *ptr, '\t' ) && !IS_ASCII_EQUAL( *ptr, '\n' ) && !IS_ASCII_EQUAL( *ptr, '\r' ) ) return False ; ptr ++ ; } return True ; } /* * Boolean つまり "t" か "nil" のどちらが設定されているか見る関数。 */ static int skkinput_analyze_boolean ( struct myChar *oneline, void *argument ) { oneline = skip_empty_symbols( oneline ) ; /* 真とすべく設定されているかどうかを判断する。*/ if( IS_ASCII_EQUAL( *oneline, 't' ) && is_empty_line( oneline + 1 ) ){ *( int *)argument = True ; return True ; } /* 偽とすべく設定されているかどうかを判断する。*/ if( !myCharCharStrncmp( oneline, "nil", 3 ) ){ if( is_empty_line( oneline + 3 ) ){ *( int *)argument = False ; return True ; } } return False ; } static struct myChar *skip_number_digit( struct myChar *ptr ) { /* 数字が続く限りスキップする。*/ while( !IS_END_OF_STRING( *ptr ) ){ if( !IS_ASCII_CHARA( *ptr ) || ptr->chara < '0' || ptr->chara > '9' ) break ; ptr ++ ; } return ptr ; } static struct myChar *analyze_integer_sub ( struct myChar *ptr, int *result, int *value ) { struct myChar *start ; struct myChar ch ; /* まず空の文字をスキップして、と。*/ start = skip_empty_symbols( ptr ) ; /* それから、文字列と覚しき場所を抜き出します。*/ ptr = skip_number_digit( start ) ; /* 文字がなかったら、と。*/ if( start == ptr ){ *result = False ; return ptr ; } /* 数字がきちんと入っていたら、と。*/ ch = *ptr ; MYCHAR_SET_END_OF_STRING( *ptr ) ; *value = myCharAtoi( start ) ; *ptr = ch ; *result = True ; return ptr ; } /* * なんて整数が設定されているか見る関数。 */ static int skkinput_analyze_integer ( struct myChar *oneline, void *argument ) { int result, value ; oneline = analyze_integer_sub( oneline, &result, &value ) ; if( !result ) return False ; /* 数値の次が空白ではない場合にはエラー。*/ if( !is_empty_line( oneline ) ){ /* 値の設定はしない。*/ return False ; } *( int *)argument = value ; return True ; } /* * なんて文字列が設定されているか見る関数。 */ static int skkinput_analyze_string ( struct myChar *oneline, void *argument, int expandFilenameFlag, int convertBackslash ) { struct myChar *result ; unsigned char *asciiString ; int ret ; oneline = parseString( oneline, &result, &ret ) ; /* エラーの判定。*/ if( ret < 0 ) return False ; if( !is_empty_line( oneline ) ){ /* 後ろにゴミが付いているぜ、それじゃ駄目だぜ、ベイビー〜! */ free( result ) ; return False ; } /* 文字列をコピーだぜ! */ asciiString = myCharStringToAsciiString( result ) ; free( result ) ; if( expandFilenameFlag ){ *( unsigned char **)argument = expand_file_name( asciiString ) ; free( asciiString ) ; } else { *( unsigned char **)argument = asciiString ; } return True ; } /* * 与えられた一行は入力ベクトルの設定であるから、それを解釈して、 * skkinput_input_vector や skkinput_zenkaku_vector に代入しようと努力 * する関数。 */ static int skkinput_analyze_input_vector ( struct myChar *oneline, void *argument ) { struct myChar *ptr ; struct myChar *istring ; int result, value, ret ; istring = NULL ; /* 最初の空白文字をスキップします。*/ oneline = skip_empty_symbols( oneline ) ; /* ( 123 "" ) */ if( !IS_ASCII_EQUAL( *oneline, '(' ) ) goto err_ret ; oneline ++ ; /* 数値を抜き出します。*/ ptr = analyze_integer_sub( oneline, &result, &value ) ; /* 結果が返ってこなかったら、駄目でしょ。*/ if( !result ) goto err_ret ; /* input vector に相応しくない値だったら、捨てましょう。*/ if( value > 128 || value < 0 ) goto err_ret ; /* そのまま最後まで行ってしまったら、駄目でしょう。*/ ptr = skip_empty_symbols( ptr ) ; if( !IS_ASCII_EQUAL( *ptr, '.' ) ) goto err_ret ; /* 次に文字列を解析します。*/ ptr = parseString( ptr + 1, &istring, &ret ) ; if( ret < 0 ) goto err_ret ; /* 次に続く空白文字列を飛ばします。*/ ptr = skip_empty_symbols( ptr ) ; /* 最後に ")" で閉じられていなければ、駄目です。*/ if( !IS_ASCII_EQUAL( *ptr, ')' ) ) goto err_ret ; ptr ++ ; /* その後にゴミがあってはいけません。*/ if( !is_empty_line( ptr ) ) goto err_ret ; /* input vector を更新します。*/ if( ( ( struct myChar ** )argument )[ value ] != NULL ){ free( ( ( struct myChar ** )argument )[ value ] ) ; } ( ( struct myChar ** )argument )[ value ] = istring ; return True ; err_ret: if( istring != NULL ) free( istring ) ; return False ; } static void add_skkinput_rule_list ( struct skk_rom_kana_rule_list **top, struct skk_rom_kana_rule element ) { struct skk_rom_kana_rule_list *node ; if( *top == NULL ){ *top = node = malloc( sizeof( struct skk_rom_kana_rule_list ) ) ; } else { node = *top ; while( node->next != NULL ) node = node->next ; node->next = malloc( sizeof( struct skk_rom_kana_rule_list ) ) ; node = node->next ; } if( node == NULL ){ fprintf( stderr, "Fatal: Memory Exhausted.\n" ) ; exit( 1 ) ; } node->next = NULL ; /* 構造体をコピーする。*/ node->element = element ; return ; } static int skkinput_analyze_rule_list ( struct myChar *oneline, void *argument ) { struct myChar *ptr, *rstr[ 4 ] ; struct skk_rom_kana_rule node ; int i, ret ; /* 最初の空白文字をスキップします。*/ oneline = skip_empty_symbols( oneline ) ; /* ( "nn" "" "ん" "ン" ) */ if( !IS_ASCII_EQUAL( *oneline, '(' ) ) return False ; oneline ++ ; ptr = oneline ; for( i = 0 ; i < 4 ; i ++ ){ /* 次に文字列を解析します。*/ ptr = parseString( ptr, rstr + i, &ret ) ; if( ret < 0 ){ while( i < 4 ) rstr[ i ++ ] = NULL ; goto err_analyze ; } } /* 文字列が終わったら、")" で閉じている筈。*/ ptr = skip_empty_symbols( ptr ) ; if( !IS_ASCII_EQUAL( *ptr, ')' ) ) goto err_analyze ; /* で、")" の続きは空白文字だけの筈(もしくはコメントだけどね) */ ptr ++ ; if( !is_empty_line( ptr ) ) goto err_analyze ; /* で、抜き出しまして、と。*/ node.state = rstr[ 0 ] ; node.next = rstr[ 1 ] ; node.houtput = rstr[ 2 ] ; node.koutput = rstr[ 3 ] ; /* 現在の状態が無かったら、そりゃエラーっす。出力の方もチェックします。*/ if( node.state == NULL ) goto err_analyze ; add_skkinput_rule_list( argument, node ) ; return True ; err_analyze: for( i = 0 ; i < 4 ; i ++ ){ if( rstr[ i ] != NULL ) free( rstr[ i ] ) ; } return False ; } /* ( "@" . "j-self-insert" ) */ static int skkinput_analyze_define_key ( struct myChar *oneline, struct myChar **rkeystring, struct myChar **rkeyfunction, int *rlength ) { struct myChar *keyfunction, *ptr, *keystring ; int result ; keystring = keyfunction = NULL ; /* 最初の空白文字をスキップします。*/ oneline = skip_empty_symbols( oneline ) ; /* ( "nn" "" "ん" "ン" ) */ if( !IS_ASCII_EQUAL( *oneline, '(' ) ) goto err_ret ; oneline ++ ; /* 次に文字列を解析します。*/ ptr = parseString( oneline, &keystring, &result ) ; /* 失敗した場合…。*/ if( keystring == NULL || result < 0 ) goto err_ret ; *rlength = result ; /* そのまま最後まで行ってしまったら、駄目でしょう。*/ ptr = skip_empty_symbols( ptr ) ; if( !IS_ASCII_EQUAL( *ptr, '.' ) ) goto err_ret ; /* 次に文字列を解析します。*/ ptr = parseString( ptr + 1, &keyfunction, &result ) ; /* 失敗した場合…。*/ if( keyfunction == NULL || result < 0 ) goto err_ret ; /* 次に続く空白文字列を飛ばします。*/ ptr = skip_empty_symbols( ptr ) ; /* 最後に ")" で閉じられていなければ、駄目です。*/ if( !IS_ASCII_EQUAL( *ptr, ')' ) ) goto err_ret ; ptr ++ ; /* その後にゴミがあってはいけません。*/ if( !is_empty_line( ptr ) ) goto err_ret ; /* 結果を代入します。*/ *rkeystring = keystring ; *rkeyfunction = keyfunction ; return True ; err_ret: if( keystring != NULL ) free( keystring ) ; if( keyfunction != NULL ) free( keyfunction ) ; return False ; } /* * 関数名を関数番号に変換する処理を行う関数。 */ static int skkinput_string2function_number ( struct myChar *keyfunction ) { int func_no ; static unsigned char *function_string_table[] = { "self-insert-command", "j-self-insert", "j-self-zenkaku-insert", "j-display-code-for-char-at-point", "j-set-henkan-point", "j-set-henkan-point-subr", "j-insert-a", "j-insert-e", "j-insert-i", "j-insert-o", "j-insert-u", "j-kana-input", "j-start-henkan", "j-insert-comma", "j-insert-period", "j-purge-from-jisyo", "j-input-by-code-or-menu", "j-mode-off", "j-toggle-kana", "j-previous-candidate", "j-kakutei", "j-abbrev-input", "j-abbrev-period", "j-abbrev-comma", "j-zenkaku-eiji", "j-zenkaku-henkan", "j-today", "save-skkinput-local-jisyo", "vc-toggle-overthespot-like-input", "j-mode-off-and-self-insert", "j-kanainput-mode-on", "newline", "set-mark-command", "forward-char", "backward-char", "delete-char", "delete-backward-char", "j-try-comletion", "end-of-line", "beginning-of-line", "kill-line", "yank", "kill-region", "kill-ring-save", "exchange-point-and-mark", "previous-line", "next-line", "transpose-chars", "redraw", "prefix-char", "sendback-next-key", "sendback-key", "keyboard-quit", "close-skkinput", "vc-toggle-chatmode", "not-modified", "forward-word", "backward-word", "upcase-word", "downcase-word", "capitalize-word", "vc-toggle-eggnl", NULL, } ; /* どの文字列に一致するのかを調べる。*/ func_no = 0 ; while( function_string_table[ func_no ] != NULL ){ if( !myCharCharStrcmp ( keyfunction, function_string_table[ func_no ] ) ) return func_no ; func_no ++ ; } return ERR ; } /* * define-key-skkmap を解釈する関数。 */ static int skkinput_analyze_define_key_skkmap ( struct myChar *oneline, int map ) { struct myChar *keyfunction ; struct myChar *keystring ; int func_no, ret = False, uselen ; /* まず、文字列のペアを解釈する。*/ if( !skkinput_analyze_define_key ( oneline, &keystring, &keyfunction, &uselen ) ) return False ; /* どの関数なのかを番号を見て調べる。*/ if( ( func_no = skkinput_string2function_number( keyfunction ) ) < 0 ) goto err_ret ; ret = skkinput_DefineKey( keystring, uselen, func_no, map ) ; err_ret: free( keystring ) ; free( keyfunction ) ; return ret ; } /* * undefine-key-skkmap を解釈する関数。 */ static int skkinput_analyze_undefine_key_skkmap ( struct myChar *oneline, int map ) { struct myChar *keystring, *keybuf ; int ret = False, uselen ; keystring = keybuf = NULL ; /* まず文字列をを解釈する。*/ if( !skkinput_analyze_string( oneline, &keystring, False, False ) ) goto err_ret ; /* この状態で keystring には、もとのままの文字列がコピーされてい * る。これを解釈しなければならない。*/ uselen = parseKeyString( keystring, NULL, 0 ) ; /* 解釈に失敗した場合には捨てる。*/ if( uselen <= 0 ) goto err_ret ; if( ( keybuf = malloc( sizeof( struct myChar ) * uselen ) ) == NULL ) goto err_ret ; ( void )parseKeyString( keystring, keybuf, uselen ) ; ret = skkinput_UndefineKey( keybuf, uselen, map ) ; free( keybuf ) ; err_ret: if( keystring != NULL ) free( keystring ) ; return ret ; } /* * lisp で書かれた行を解釈する関数。 */ static int skkinput_analyze_skkinputlisp ( struct myChar *oneline ) { if( !skkinputlisp_weak_eval( oneline ) ) return False ; return True ; } /* * 一行を解釈実行する関数。 */ static int skkinput_analyze_line( struct myChar *oneline ) { int i, length ; struct myChar *wptr ; for( i = 0 ; skkinput_initdef[ i ].string != NULL ; i ++ ){ /* 文字列が一致するかどうかを判断する。*/ length = strlen( skkinput_initdef[ i ].string ) ; if( myCharCharStrncmp ( oneline, skkinput_initdef[ i ].string, length ) ) continue ; wptr = oneline + length ; /* 一致した文字列に対応するアクションを実行する。*/ switch( skkinput_initdef[ i ].action ){ case PARAM_BOOLEAN : return skkinput_analyze_boolean ( wptr, skkinput_initdef[ i ].argument ) ; case PARAM_INTEGER : return skkinput_analyze_integer ( wptr, skkinput_initdef[ i ].argument ) ; case PARAM_STRING : return skkinput_analyze_string ( wptr, skkinput_initdef[ i ].argument, False, True ) ; case PARAM_PATH : return skkinput_analyze_string ( wptr, skkinput_initdef[ i ].argument, True, True ) ; case PARAM_INPUT_VECTOR : return skkinput_analyze_input_vector ( wptr, skkinput_initdef[ i ].argument ) ; case PARAM_ROM_KANA_RULE_LIST : return skkinput_analyze_rule_list ( wptr, skkinput_initdef[ i ].argument ) ; #ifdef THIS_IS_NECESSARY case PARAM_DEFINE_KEY_SKKMAP : return skkinput_analyze_define_key_skkmap( wptr, 0 ) ; #endif case PARAM_DEFINE_KEY_SKKJMAP : return skkinput_analyze_define_key_skkmap( wptr, 1 ) ; case PARAM_DEFINE_KEY_ABBREVMAP : return skkinput_analyze_define_key_skkmap( wptr, 2 ) ; #ifdef THIS_IS_NECESSARY case PARAM_UNDEFINE_KEY_SKKMAP : return skkinput_analyze_undefine_key_skkmap( wptr, 0 ) ; #endif case PARAM_UNDEFINE_KEY_SKKJMAP : return skkinput_analyze_undefine_key_skkmap( wptr, 1 ) ; case PARAM_UNDEFINE_KEY_ABBREVMAP : return skkinput_analyze_undefine_key_skkmap( wptr, 2 ) ; case PARAM_SKKINPUTLISP : return skkinput_analyze_skkinputlisp( wptr ) ; default : return False ; } } return False ; } /* * skk-rom-kana-rule-list に相当する skkinput-rom-kana-rule-list を * skkinput が解釈出来るように変換する関数。 *--- */ static struct skk_rom_kana_rule *makeSkkRomKanaRuleList ( struct skk_rom_kana_rule_list *top ) { int i ; struct skk_rom_kana_rule_list *node = top, *nNode ; struct skk_rom_kana_rule *rule_list = NULL ; if( node == NULL ){ return skkinput_default_rom_kana_rule_list ; } else { for( i = 0 ; node != NULL ; i ++ ) node = node->next ; /* 3 つはデフォルトでも持っているので +3 */ rule_list = malloc( sizeof( struct skk_rom_kana_rule ) * ( i + 3 ) ) ; if( rule_list == NULL ){ return NULL ; } node = top ; for( i = 0 ; node != NULL ; i ++ ){ rule_list[ i ] = node->element ; #ifdef DEBUG if( rule_list[ i ].state == NULL ){ fprintf( stderr, "( \"(null)\", " ) ; } else { fprintf( stderr, "( \"" ) ; myCharFputstring( stderr, rule_list[ i ].state ) ; fprintf( stderr, "\", " ) ; fflush( stderr ) ; } if( rule_list[ i ].next == NULL ){ fprintf( stderr, "\"(null)\", " ) ; } else { fprintf( stderr, "\"" ) ; myCharFputstring( stderr, rule_list[ i ].next ) ; fprintf( stderr, "\", " ) ; fflush( stderr ) ; } if( rule_list[ i ].houtput == NULL ){ fprintf( stderr, "\"(null)\", " ) ; } else { fprintf( stderr, "\"" ) ; myCharFputstring( stderr, rule_list[ i ].houtput ) ; fprintf( stderr, "\", " ) ; fflush( stderr ) ; } if( rule_list[ i ].koutput == NULL ){ fprintf( stderr, "\"(null)\" )\n" ) ; } else { fprintf( stderr, "\"" ) ; myCharFputstring( stderr, rule_list[ i ].koutput ) ; fprintf( stderr, "\" )\n" ) ; fflush( stderr ) ; } #endif nNode = node->next ; free( node ) ; node = nNode ; } rule_list[ i++ ] = skkinput_default_rom_kana_rule_list[ 0 ] ; rule_list[ i++ ] = skkinput_default_rom_kana_rule_list[ 1 ] ; rule_list[ i++ ] = skkinput_default_rom_kana_rule_list[ 2 ] ; } return rule_list ; } /* * 設定ファイルを読み込む関数。 *------ * 一番強力なのは、-option での設定だと思う。だから、まず DEFAULT の設 * 定、次にこの設定ファイル読み、最後に option で決定したい…けど…。 * すると? 設定ファイルが何処にあるのかを option で指定できなくならな * いか? それは本意じゃないし…。 */ int skkinput_readConfigFile( char *config_file ) { int chck = False, coding_system ; unsigned char *config_path ; /* 後藤慎也氏の patch …「行番号が一つ小さい」というのに対する patch。*/ unsigned long line = 1 ; FILE *fp ; struct myChar *oneline ; skkinput_rom_kana_rule_list_top = NULL ; /* デフォルトのものを使用するよう指示された場合の処理。*/ config_path = expand_file_name( config_file ) ; chck = True ; coding_system = check_skkinput_jisyo_code( config_path ) ; /* ファイルを開いてみる。*/ if( ( fp = fopen( config_path, "rb" ) ) == NULL ){ if( chck ) free( config_path ) ; return False ; } /* ファイルが続く限り読み出す。*/ while( !feof( fp ) ){ /* 一行読み出す。*/ if( ( oneline = mychar_readOneLine( fp, coding_system ) ) != NULL ){ /* コメント行だった場合には無視する。*/ if( !is_empty_line( oneline ) ){ if( !skkinput_analyze_line( oneline ) ){ fprintf( stderr, "Warning: I ignore line %ld.\n", line ) ; } } free( oneline ) ; oneline = NULL ; } line ++ ; } fclose( fp ) ; /* メモリを解放して終了する。*/ if( chck ) free( config_path ) ; /* rom-kana rule list を設定する。*/ skkinput_rom_kana_rule_list = makeSkkRomKanaRuleList( skkinput_rom_kana_rule_list_top ) ; /* * if skkserv_portnum is defined use skkserv_portnum for * backward compatibility. */ if (skkserv_portnum != 0) { if (skkserv_service) free(skkserv_service); skkserv_service = malloc(8); /* 8 digit is enough */ sprintf(skkserv_service, "%u", skkserv_portnum); } if (skkserv_protocol_family != NULL) { if (strcasecmp(skkserv_protocol_family, "inet4") == 0 || strcasecmp(skkserv_protocol_family, "ipv4") == 0) { skkserv_pf = PF_INET; } else if (strcasecmp(skkserv_protocol_family, "inet6") == 0 || strcasecmp(skkserv_protocol_family, "ipv6") == 0) { #if defined(USE_INET6) skkserv_pf = PF_INET6; #else fprintf( stderr, "Warning: IPv6 not supported.\n" ) ; #endif } } return True ; } static void initialize_skkinputDefaultVectorSub ( struct myChar *myCharVector[], unsigned char *charVector[] ) { unsigned char **cptr = charVector ; struct myChar **wptr = myCharVector ; int i ; for( i = 0 ; i < 128 ; i ++, cptr ++ , wptr ++ ){ if( *cptr != NULL ){ *wptr = malloc( sizeof( struct myChar ) * 2 ) ; ( *wptr )->charset = CHARSET_JISX0208_1983 ; ( *wptr )->chara = ( ( ( ( *cptr )[ 0 ] ) << 8 ) | ( ( *cptr )[ 1 ] ) ) & 0x7F7F ; MYCHAR_SET_END_OF_STRING( ( ( *wptr )[ 1 ] ) ) ; } else { *wptr = NULL ; } } return ; } static void initialize_skkinputDefaultVectors( void ) { initialize_skkinputDefaultVectorSub ( skkinput_input_vector, skkinput_default_input_vector ) ; initialize_skkinputDefaultVectorSub ( skkinput_zenkaku_vector, skkinput_default_zenkaku_vector ) ; return ; } /* * 初期のローマ字仮名変換ルールを設定する関数。 *--- * 以前は char の string で指定していたので、変数宣言の場所で設定でき * たけど、今回から charset を変更してしまったので、それができなくなっ * てしまったがためにこうなりました。 */ static void initialize_skkinputDefaultRomKanaRuleList( void ) { struct myChar *ptr ; ptr = malloc( sizeof( struct myChar ) * 3 ) ; myCharCharStrcpy( ptr, "nn" ) ; skkinput_default_rom_kana_rule_list[ 0 ].state = ptr ; ptr = malloc( sizeof( struct myChar ) * 2 ) ; ptr->charset = CHARSET_JISX0208_1983 ; ptr->chara = 0x2473 ; MYCHAR_SET_END_OF_STRING( *( ptr + 1 ) ) ; skkinput_default_rom_kana_rule_list[ 0 ].houtput = ptr ; ptr = malloc( sizeof( struct myChar ) * 2 ) ; ptr->charset = CHARSET_JISX0208_1983 ; ptr->chara = 0x2573 ; MYCHAR_SET_END_OF_STRING( *( ptr + 1 ) ) ; skkinput_default_rom_kana_rule_list[ 0 ].koutput = ptr ; ptr = malloc( sizeof( struct myChar ) * 3 ) ; myCharCharStrcpy( ptr, "n'" ) ; skkinput_default_rom_kana_rule_list[ 1 ].state = ptr ; ptr = malloc( sizeof( struct myChar ) * 2 ) ; ptr->charset = CHARSET_JISX0208_1983 ; ptr->chara = 0x2473 ; MYCHAR_SET_END_OF_STRING( *( ptr + 1 ) ) ; skkinput_default_rom_kana_rule_list[ 1 ].houtput = ptr ; ptr = malloc( sizeof( struct myChar ) * 2 ) ; ptr->charset = CHARSET_JISX0208_1983 ; ptr->chara = 0x2573 ; MYCHAR_SET_END_OF_STRING( *( ptr + 1 ) ) ; skkinput_default_rom_kana_rule_list[ 1 ].koutput = ptr ; return ; } /* * skkinput の動作記述をする変数を初期化する関数。 *------ * デフォルトの値を入れてしまう関数でもある。 */ void initSkkinputDousaketteiVariables( void ) { struct servent *servent ; /* 局所辞書の所在を知らないとしておく。*/ skkinput_local_jisyo_name = DEFAULT_SKKLJISYO ; skkinput_backup_jisyo_name = DEFAULT_SKKBJISYO ; skkinput_record_name = DEFAULT_SKKRECORD ; skk_local_jisyo_name = DEFAULT_SKKLOCALJISYO ; /* "/etc/services" からポート番号を得ておく。*/ servent = getservbyname( SKKSERV_SERVICE_NAME, SKKSERV_SERVICE_PROTO ) ; if( servent == NULL ){ /* /etc/services に設定はなかったので、config.h の中のを使う。*/ skkserv_service = strdup(DEFAULT_SKKPORT); } else { /* /etc/services に設定があった…。*/ skkserv_service = strdup( servent->s_name ) ; #if defined(DEBUG) fprintf ( stderr, "getservbyname: \"%s\", %d\n", servent->s_name, skkserv_portnum ) ; #endif } /* 環境変数 SKKSERV が設定されていれば、それを DEFAULT の skkserv * * host とする。*/ if( ( skkserv_host = getenv( "SKKSERVER" ) ) == NULL ) skkserv_host = DEFAULT_SKKSERVER ; /* デフォルトのキーマップを作成する。*/ skkinput_CompileDefaultKeyBind() ; /* 入力ベクトルの初期化を行う。*/ initialize_skkinputDefaultVectors() ; /* egg 互換の newline をサポートするか否か。*/ skk_egg_like_newline = False ; /* dabbrev like の completion を行うかどうか。*/ skkinput_dabbrev_like_completion= False ; /* chat-adapter-mode つまり newline を行頭だけでなく入れるか。*/ skkinput_chatadaptermode = False ; /* skk-local-jisyo を検索するかどうか。*/ skkinput_search_skk_jisyo = True ; /* skkinput-record を作成するかどうか。*/ skkinput_keep_record = True ; /* 日付の表示形式。*/ skkinput_date_ad = False ; skkinput_number_style = False ; /* 削除キーは確定の機能を含んでいるのか否か。*/ skkinput_delete_implies_kakutei = True ; /* 数字変換機能を利用する。*/ skkinput_use_numeric_conversion = True ; skkinput_rom_kana_rule_list_top = NULL ; initialize_skkinputDefaultRomKanaRuleList() ; skkinput_rom_kana_rule_list = skkinput_default_rom_kana_rule_list ; /* タブ幅。*/ skkinput_tab_width = 8 ; skkinput_rjj_like_input = False ; /* オートセーブの期間を設定する。デフォルトは 10 秒である。*/ skkinput_autosave_interval = 10 * 1000 ; return ; } /* * 変換プロトコルなんかに関係なく SkkInputWidget を起こすにあたって必 * 要な設定をする関数。 */ int skkinput_setSkkInputValues( Widget gw ) { Arg arg[ 5 ] ; Cardinal i ; i = 0 ; /* 辞書の状態(Modified かどうか)。*/ XtSetArg( arg[ i ], XtNjisyoDirty, skkinput_jisyo_dirty ) ; i ++ ; /* egg-like-newline かどうか。*/ XtSetArg( arg[ i ], XtNeggLikeNewline, skk_egg_like_newline ) ; i ++ ; /* chat adapter モードかどうか。*/ XtSetArg( arg[ i ], XtNchatAdapter, skkinput_chatadaptermode ) ; i ++ ; XtSetValues( gw, arg, i ) ; return 0 ; }