1 #include "sdlskk.h"
2 #include "sdlskk_internal.h"
3 #include <string.h>
4 #include <stdio.h>
5 
6 
7 #define BUF_SIZE 1024
parse_skk_jisyo_line(SDLSKK_Map * map,char * line,char users)8 static void parse_skk_jisyo_line( SDLSKK_Map* map, char* line, char users )
9 {
10   int pos;
11   SDLSKK_Char* yomi;
12   SDLSKK_Char* kanji;
13   SDLSKK_StrList* list;
14 
15   if( line[0] == ';' || line[0] == ' ' || line[0] == '\n' || line[0] == '\0' )
16     return;
17 
18   pos = 0;
19   yomi = SDLSKK_cstr_tokenize( line, '/', &pos );
20   SDLSKK_Str_chop( yomi );
21 
22   list = SDLSKK_Map_get( map, yomi );
23   if( list == NULL ){
24     list = SDLSKK_StrList_new();
25     SDLSKK_Map_set( map, yomi, list );
26   }
27 
28   for(;;){
29     kanji = SDLSKK_cstr_tokenize( line, '/', &pos );
30     if( kanji[0]==0 ){
31       free( kanji );
32       return;
33     }
34     if( ! SDLSKK_StrList_find( list, kanji ) ){
35       SDLSKK_StrList_push( list, kanji, users );
36     }
37   }
38 
39 }
40 
SDLSKK_Dict_new(void)41 SDLSKK_Dictionary* SDLSKK_Dict_new( void )
42 {
43   SDLSKK_Dictionary* dict;
44 
45   dict = SDLSKK_malloc( sizeof(SDLSKK_Dictionary) );
46   dict->map = SDLSKK_Map_new( DICT_TABLE_SIZE );
47 
48   return dict;
49 }
50 
SDLSKK_Dict_load(SDLSKK_Dictionary * dict,char * filename,int users)51 int SDLSKK_Dict_load( SDLSKK_Dictionary* dict, char* filename, int users )
52 {
53   FILE* fp;
54   char buf[2048];
55 
56   fp = fopen( filename, "rt" );
57   if( fp==NULL )
58     return 0;
59 
60   while( fgets( buf, sizeof(buf), fp ) != NULL ){
61     parse_skk_jisyo_line( dict->map, buf, users );
62   }
63   fclose( fp );
64   return 1;
65 }
66 
SDLSKK_Dict_delete(SDLSKK_Dictionary * dict)67 void SDLSKK_Dict_delete( SDLSKK_Dictionary* dict )
68 {
69   SDLSKK_Dict_delete_all( dict );
70 }
71 
SDLSKK_Dict_delete_all(SDLSKK_Dictionary * dict)72 void SDLSKK_Dict_delete_all( SDLSKK_Dictionary* dict )
73 {
74   SDLSKK_Map_delete_all( dict->map );
75   free( dict );
76 }
77 
SDLSKK_Dict_get(SDLSKK_Dictionary * dict,SDLSKK_Char * hiragana)78 SDLSKK_DictionaryItem* SDLSKK_Dict_get( SDLSKK_Dictionary* dict,
79 					SDLSKK_Char *hiragana )
80 {
81   SDLSKK_StrList *vals = SDLSKK_Map_get( dict->map, hiragana );
82   SDLSKK_DictionaryItem* item;
83   if( vals == NULL )
84     return NULL;
85 
86   item = SDLSKK_malloc( sizeof(SDLSKK_DictionaryItem) );
87   item->dict = dict;
88   item->hiragana = hiragana;
89   item->kanji = vals;
90   item->cur = item->kanji->begin->next;
91 
92   return item;
93 }
94 
SDLSKK_Dict_add_empty_yomi(SDLSKK_Dictionary * dict,SDLSKK_Char * yomi)95 void SDLSKK_Dict_add_empty_yomi( SDLSKK_Dictionary* dict,
96 				 SDLSKK_Char* yomi )
97 {
98   if( SDLSKK_Map_get( dict->map, yomi ) != NULL )
99     return;
100   SDLSKK_Map_set( dict->map, yomi, SDLSKK_StrList_new() );
101 }
102 
SDLSKK_DictItem_get_current(SDLSKK_DictionaryItem * item)103 SDLSKK_Char* SDLSKK_DictItem_get_current( SDLSKK_DictionaryItem* item )
104 {
105   return item->cur->val;
106 }
107 
SDLSKK_DictItem_next(SDLSKK_DictionaryItem * item)108 void SDLSKK_DictItem_next( SDLSKK_DictionaryItem* item )
109 {
110   if( SDLSKK_DictItem_is_end( item ) )
111     return;
112   item->cur = item->cur->next;
113 }
114 
SDLSKK_DictItem_prev(SDLSKK_DictionaryItem * item)115 void SDLSKK_DictItem_prev( SDLSKK_DictionaryItem* item )
116 {
117   if( SDLSKK_DictItem_is_begin( item ) )
118     return;
119   item->cur = item->cur->prev;
120 }
SDLSKK_DictItem_reset(SDLSKK_DictionaryItem * item)121 void SDLSKK_DictItem_reset( SDLSKK_DictionaryItem* item )
122 {
123   item->cur = item->kanji->begin->next;
124 }
125 
SDLSKK_DictItem_delete(SDLSKK_DictionaryItem * item)126 void SDLSKK_DictItem_delete( SDLSKK_DictionaryItem* item )
127 {
128   free( item );
129 }
130 
SDLSKK_DictItem_is_end(SDLSKK_DictionaryItem * item)131 int SDLSKK_DictItem_is_end( SDLSKK_DictionaryItem* item )
132 {
133   return item->cur->next == item->kanji->end;
134 }
135 
SDLSKK_DictItem_is_begin(SDLSKK_DictionaryItem * item)136 int SDLSKK_DictItem_is_begin( SDLSKK_DictionaryItem* item )
137 {
138   return item->cur->prev == item->kanji->begin;
139 }
140 
SDLSKK_DictItem_commit(SDLSKK_DictionaryItem * item)141 void SDLSKK_DictItem_commit( SDLSKK_DictionaryItem* item )
142 {
143   item->cur->save = 1;
144   item->cur->prev->next = item->cur->next;
145   item->cur->next->prev = item->cur->prev;
146 
147   item->cur->prev = item->kanji->begin;
148   item->cur->next = item->kanji->begin->next;
149   item->kanji->begin->next->prev = item->cur;
150   item->kanji->begin->next = item->cur;
151 }
152 
SDLSKK_DictItem_register_word(SDLSKK_DictionaryItem * item,SDLSKK_Char * new_word)153 void SDLSKK_DictItem_register_word( SDLSKK_DictionaryItem* item,
154 				    SDLSKK_Char* new_word )
155 {
156   SDLSKK_Char* word = SDLSKK_Str_new( new_word );
157 
158   SDLSKK_StrList_shift( item->kanji, word, 1 );
159 }
160 
SDLSKK_DictItem_set_current(SDLSKK_DictionaryItem * item,SDLSKK_Char * word)161 void SDLSKK_DictItem_set_current( SDLSKK_DictionaryItem* item,
162 				  SDLSKK_Char* word )
163 {
164   item->cur = SDLSKK_StrList_find( item->kanji, word );
165 }
166 
SDLSKK_DictItem_get_count(SDLSKK_DictionaryItem * item)167 int SDLSKK_DictItem_get_count( SDLSKK_DictionaryItem* item )
168 {
169   int result;
170   SDLSKK_DictionaryItem tmp_item;
171 
172   tmp_item = *item;
173   for( result=0; !SDLSKK_DictItem_is_begin( &tmp_item ); ++result ){
174     SDLSKK_DictItem_prev( &tmp_item );
175   }
176 
177   return result;
178 }
179 
SDLSKK_Dict_save_user_dict(SDLSKK_Dictionary * dict,char * filename)180 int SDLSKK_Dict_save_user_dict( SDLSKK_Dictionary* dict, char* filename )
181 {
182   FILE* fp;
183   char line[5000];
184   char buf[1000];
185   int i;
186   int save;
187   SDLSKK_HashElement* hash_el;
188   SDLSKK_ListElement* list_el;
189 
190   fp = fopen( filename, "wt" );
191   if( fp == NULL )
192     return 0;
193 
194   for( i = 0; i < dict->map->table_size; ++i ){
195     for( hash_el = dict->map->table[i]; hash_el != NULL;
196 	 hash_el = hash_el->next ){
197       save = 0;
198       SDLSKK_Str_to_cstr( hash_el->key, buf, sizeof(buf) );
199 #ifdef HAVE_SNPRINTF
200       snprintf( line, sizeof(line), "%s /", buf );
201 #else
202       sprintf( line, "%s /", buf );
203 #endif
204       for( list_el = hash_el->vals->begin->next;
205 	   list_el != hash_el->vals->end;
206 	   list_el = list_el->next ){
207 	if( list_el->save ){
208 	  save = 1;
209 	  SDLSKK_Str_to_cstr( list_el->val, buf, sizeof(buf) - 1 );
210 	  if( strlen( line ) + strlen( buf ) + 2 < sizeof(line) ){
211 	    strcat( buf, "/" );
212 	    strcat( line, buf );
213 	  }
214 	}
215       }
216 
217       if( save ){
218 	fputs( line, fp );
219 	fputc( '\n', fp );
220       }
221 
222     }
223   }
224 
225   fclose(fp);
226 
227   return 1;
228 }
229