1 /*
2  * engdic.c
3  *
4  * English dictionary for korean
5  *
6  * Author: Oh Junseon <hollywar@mail.holywar.net>
7  * Date  : $Date: 1999/09/06 02:48:50 $
8  *
9  * $Revision: 1.6 $
10  *
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public
14  * License as published by the Free Software Foundation
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20 */
21 
22 
23 /* SCSS/RCS Id */
24 #ifdef LINT
25 static char rcsid[]="@(#)$Id: engdic.c,v 1.6 1999/09/06 02:48:50 hollywar Exp $";
26 #endif /* lint */
27 
28 #if TERMIO
29 #include <termio.h>
30 #endif
31 
32 #include <ctype.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <unistd.h>
37 #include <sys/types.h>
38 #include <sys/stat.h> // for get file size //
39 
40 #include <zlib.h>  // gzip library //
41 
42 #include "engdic.h"
43 
44 
45 void error_exit(char *message) ;
46 int show_result(char *tk , char *tk2) ;
47 char *lower_string (char *data) ;
48 int han_check (char *data) ;
49 void search_hangul (char *key_word) ;
50 char get_command(void) ;
51 struct size_buf get_term(void);
52 
53 void clear_eol(void) ;
54 void deinit(void) ;
55 void flush(void) ;
56 char getchr(void) ;
57 void init(void) ;
58 void lower_left(void) ;
59 int putchr(int) ;
60 char putstr (char *s) ;
61 void raw_mode(int on) ;
62 void so_enter(void) ;
63 void so_exit(void) ;
64 char sep[] = ":" ;
65 static int line = 0 ;
66 
67 struct size_buf sz ;
68 
main(int argc,char * argv[])69 int main (int argc , char *argv[])
70 {
71     char buf[COLS_MAX] ;
72     char command[MAX_LENGTH]  ;
73     register char *key_word ;
74     register char *small_key_word ;
75     register char *tk  , *small_tk;
76     char first_char ;
77     register int file_size=0 , my_value = 0 , sv=1 , check = 0;
78 
79     struct stat sb ;
80 
81     // type of gzip file //
82     register gzFile gzfp ;
83 
84 
85     if (argc > 1) {
86 	key_word = argv[1] ;
87     }
88 
89     sz = get_term();
90     init() ;
91 
92     // start loop //
93     while(1) {
94 	if (argc <= 1) {
95 	    // get search query //
96 	    strcpy(command,"");
97 	    printf("%s",SEARCH_WORD) ;
98 	    fgets(command,MAX_LENGTH,stdin) ;
99 
100 	    // remove enter value //
101 	    command[strlen(command)-1] = '\0' ;
102 	    key_word = command ;
103 	}
104 	// check null line or CTRL + D for terminate program //
105 	if (!strcmp(key_word,"") || key_word[0] == 4) {
106 	    printf("%s\r\n",END_WORD) ;
107 	    break ;
108 	}
109         small_key_word = lower_string(key_word) ;
110 
111 	if (han_check(key_word)) {
112 	    search_hangul(key_word) ;
113 	    if (argc > 1) break ; else continue ;
114 	}
115 
116         // get first keyword character for reading file //
117         first_char = tolower(key_word[0]) ;
118         sprintf(buf,"%s/%c.dic.gz",INSTALL_DIC_DATA_DIR,first_char) ;
119 
120 	// open gzip file //
121         // if ( !(gzfp = gzopen(buf,"rb"))) error_exit("File open failed") ;
122         if ( !(gzfp = gzopen(buf,"rb"))) continue ;
123 	if (stat(buf,&sb)==-1) error_exit("File open failed") ;
124 
125  	file_size = (int) sb.st_size ;
126 	my_value = file_size / 2  ;
127 
128 
129 	// Binary search algorism //
130 	if (strlen(key_word) > 1 && key_word[1] > (int)'c')
131 	while(1) {
132 	    gzseek(gzfp,my_value,SEEK_CUR) ;
133 	    gzgets(gzfp,buf,COLS_MAX) ;
134 	    gzgets(gzfp,buf,COLS_MAX) ;
135 	    if (tolower(buf[sv]) > small_key_word[sv] -1) my_value = 0 - abs((my_value/2)) ;
136             else if (tolower(buf[sv]) < small_key_word[sv] -1) my_value = abs((my_value/2)) ;
137 	    else break ;
138 
139 
140 	    if (my_value == 0) break ;
141 	}
142 	if (strlen(key_word) > 1 && key_word[1] > (int)'c' && tolower(buf[sv]) > small_key_word[sv]-1)
143 	while(1) {
144 	    gzseek(gzfp,-2000,SEEK_CUR) ;
145 	    gzgets(gzfp,buf,COLS_MAX) ;
146 	    gzgets(gzfp,buf,COLS_MAX) ;
147 	    if (tolower(buf[sv]) > small_key_word[sv] -1) continue ;
148 	    else break ;
149 	}
150 
151 
152 	// Matching keyword //
153 	check=0 ;
154         while( (gzgets(gzfp,buf,COLS_MAX))) {
155 	    tk = strtok(buf,sep) ;
156 	    small_tk = lower_string(tk) ;
157 
158 	    // Data have one space (remove one space) //
159 	    small_tk[strlen(small_tk)-1] = '\0' ;
160 
161 	    if (!strcmp(small_tk,small_key_word)) {
162 		check=1;
163 		show_result(tk,strtok(NULL,"\0")) ;
164 	    }
165 	    if (check && small_tk[2] > small_key_word[2]) {
166 	        free(small_tk) ;
167 	        break ;
168 	    }
169 	    free(small_tk) ;
170         }
171 
172 	free(small_key_word) ;
173 
174 	// close gzip file //
175         gzclose(gzfp) ;
176 
177 	putstr("\r\n");
178 	flush() ;
179 	line=0 ;
180 
181 	if (argc > 1) break ;
182     }
183 
184     deinit();
185 
186     return 0 ;
187 }
188 
189 
show_result(char * tk,char * tk2)190 int show_result(char *tk , char *tk2)
191 {
192     register char *i, *j ;
193     register int check_cols_count = 0 ;
194     char ch ;
195 
196     if (tk == NULL || tk2 == NULL) return 0 ;
197 
198     putstr(WORD_COLOR) ; putstr("[ ") ; putstr(tk); putchr(']') ;
199     putstr(NO_COLOR) ; putstr("\r\n") ;
200     flush() ;
201     line++ ;
202     if (line >= sz.height-1) ch = get_command() ;
203 
204     for (i=++tk2 ; *i != '\0' ; i++ ) {
205 	if (!check_cols_count) putchr(' ') ;
206 	check_cols_count ++ ;
207 	if ( (check_cols_count > sz.width-15 && *i == ' ') || (check_cols_count > sz.width-2) ) {
208 	    putstr("\r\n");
209 	    flush() ;
210 	    line++ ;
211 	    if (line >= sz.height-1) ch = get_command() ;
212 	    check_cols_count=0 ;
213 	    continue ;
214 	}
215 	putchr(*i) ;
216     }
217     if (check_cols_count != 0) {
218 	line++ ;
219 	flush() ;
220 	if (line >= sz.height-1) ch = get_command() ;
221     }
222 
223     if (ch == tolower('q')) return 1 ;
224 
225     return 0 ;
226 
227 }
228 
lower_string(char * data)229 char *lower_string (char *data)
230 {
231    register char *i, *j ;
232    register char *code ;
233 
234    code = (char *)malloc ((strlen(data)+1) * sizeof (char) );
235 
236    for (j=code, i=data; *i!='\0'; i++, j++) {
237       if (*i != ' ')
238          *j = tolower(*i);
239       else *j = ' ' ;
240    }
241    *j = '\0';
242 
243    return code ;
244 }
245 
han_check(char * data)246 int han_check (char *data)
247 {
248     int i=0 ;
249 
250     for (i=0 ; data[i] != '\0' ; i++) {
251         if (data[i] & 0x80) return 1 ;
252     }
253     return 0 ;
254 }
255 
search_hangul(char * key_word)256 void search_hangul (char *key_word)
257 {
258     char buf[COLS_MAX] ;
259     register char *tk ;
260     int pid_num=0 ;
261 
262     register FILE *fp ;
263 
264     pid_num = getpid() ;
265 
266     sprintf(buf,"zgrep -hw %s %s/*.dic.gz > /tmp/edic.%d",key_word,INSTALL_DIC_DATA_DIR,pid_num);
267     system(buf) ;
268 
269     sprintf(buf,"/tmp/edic.%d",pid_num) ;
270 
271     if ( !(fp = fopen(buf,"rt"))) error_exit("tmp file does not exits");
272 
273     while (fgets(buf,COLS_MAX,fp)) {
274 	tk = strtok(buf,sep) ;
275 	if (show_result(tk,strtok(NULL,sep))) break ;
276     }
277 
278     fclose(fp) ;
279     sprintf(buf,"rm -f /tmp/edic.%d",pid_num) ;
280     system(buf) ;
281 
282     putstr("\r\n");
283     flush() ;
284     line = 0 ;
285 
286     return ;
287 
288 }
289 
290 
error_exit(char * message)291 void error_exit (char *message)
292 {
293     printf("%s\r\n",message) ;
294     exit(1) ;
295 }
296 
get_command(void)297 char get_command(void)
298 {
299     char ch ;
300 
301     raw_mode(1) ;
302     lower_left() ;
303     so_enter();
304     putstr(GET_COMMAND) ;
305     flush() ;
306     so_exit();
307     ch = getchr();
308     lower_left() ;
309     clear_eol();
310     flush();
311     raw_mode(0) ;
312 
313     if (ch == '\n') line -- ; else line=0 ;
314 
315     return ch ;
316 }
317 
318 
319 
320 /*
321  | $Id: engdic.c,v 1.6 1999/09/06 02:48:50 hollywar Exp $
322  |
323  | Local Variables:
324  | mode: c
325  | mode: font-lock
326  | version-control: t
327  | delete-old-versions: t
328  | End:
329  |
330  | -*- End-Of-File -*-
331  */
332