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