Added jben.py as a script to install.
[jben2_gui.git] / kpengine / kpengine.c
blob0e0d1fbe72a7fa0cbffa361768fb90142d4c3a78
1 /* Modified by Paul Goins:
2 * This file contains modifications so it will compile without GTK
3 * dependencies and to make it better work with wxKanjipad.
4 */
5 /* KanjiPad - Japanese handwriting recognition front end
6 * Copyright (C) 1997 Owen Taylor
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #include "jstroke.h"
24 #include <ctype.h>
26 #define MAX_STROKES 32
27 #define BUFLEN 1024
28 #ifndef PATH_MAX //FIXME: this is not found if debug mode is used (-pedantic ?)
29 # define PATH_MAX BUFLEN
30 #endif
32 static StrokeDic stroke_dicts[MAX_STROKES];
33 static char *progname;
34 static char *data_dir;
36 void
37 load_database()
39 char buf[PATH_MAX];
40 char fname[PATH_MAX];
41 int at_db;
42 FILE *fd;
43 char *dir=0;
45 if(data_dir)
47 int len = strlen(data_dir)+1;
48 dir = malloc(sizeof(char)*(len));
49 strncpy(dir, data_dir, len);
51 else
53 /* Default to current directory if no data dir is specified. */
54 dir = malloc(sizeof(char)*9);
55 strcpy(dir, "kanjipad");
56 dir[8]=0;
59 for(at_db=0;at_db<MAX_STROKES;++at_db)
60 stroke_dicts[at_db]=0;
62 for(at_db=0;at_db<MAX_STROKES;++at_db)
64 int len = strlen(dir) + 12; /* dir len + ##.unistrok (11 chars)
65 + sep char = dir len + 12 */
66 if(len<1 || len>=PATH_MAX)
68 fprintf(stderr,"Failed to format path\n");
69 if(dir) free(dir);
70 exit(-5);
73 #ifdef __MSWINDOWS__
74 char separator = '\\';
75 #else
76 char separator = '/';
77 #endif
78 sprintf(fname,"%s%c%02d.unistrok",dir,separator,at_db);
80 fd = fopen(fname,"r");
81 if(fd)
83 StrokeDicEntryList **ppnext=&stroke_dicts[at_db];
85 while( fgets(buf,PATH_MAX,fd) )
87 unsigned long unicode_point;
88 char *begin;
89 char *next_pchr;
90 char *pchr = buf;
91 StrokeDicEntryList *plist=0;
93 if( pchr[0]=='#')
94 continue;
96 unicode_point = strtol(pchr,&next_pchr,16);
98 if(pchr==next_pchr)
100 fprintf(stderr,"Failed to parse line:\n\"%s\"\n",pchr);
101 continue;
103 pchr=next_pchr;
105 if(unicode_point<0x3300 ||
106 unicode_point>0x2FA1F)
108 fprintf(stderr,"Unicode out of range for Kanji: 0x%08lX\n"
109 "file \"%s\"\n\"%s\" ",
110 unicode_point,
111 fname,
114 continue;
117 plist = malloc(sizeof(StrokeDicEntryList));
119 if(!plist)
121 mem_err:
122 fprintf(stderr,"out of memory\n");
123 if(dir) free(dir);
124 exit(-1);
127 plist->m_next=0;
128 plist->m_entry.m_character=malloc(20);
129 if(!plist->m_entry.m_character)
130 goto mem_err;
131 //plist->m_entry.m_character[ucs4toutf8(unicode_point,plist->m_entry.m_character)]=0;
132 sprintf(plist->m_entry.m_character,"%lu",unicode_point);
134 //Strokes
135 while(*pchr!='|')
137 if( !*pchr || *pchr=='\n')
139 fail_no_strokes:
140 fprintf(stderr,"Failed to parse line: No Strokes\n\"%s\"\n",buf);
141 free(plist->m_entry.m_character);
142 free(plist);
143 continue;
145 ++pchr;
147 ++pchr;
149 while(*pchr==' '||*pchr=='\t')
150 ++pchr;
151 begin=pchr;
152 while(*pchr && *pchr!='#' && *pchr!='|' && *pchr!='\n')
153 ++pchr;
154 if(pchr==begin)
155 goto fail_no_strokes;
156 plist->m_entry.m_strokes=malloc(pchr-begin+1);
157 if(!plist->m_entry.m_strokes)
158 goto mem_err;
159 strncpy(plist->m_entry.m_strokes,begin,pchr-begin);
160 plist->m_entry.m_strokes[pchr-begin]=0;
162 //Filter
163 plist->m_entry.m_filters=0;
164 while(*pchr!='|')
166 if( !*pchr || *pchr=='\n')
167 break;
168 ++pchr;
170 if(*pchr=='|')
172 ++pchr;
173 //Possible Filter
174 while(*pchr==' '||*pchr=='\t')
175 ++pchr;
176 begin=pchr;
177 while(*pchr && *pchr!='#' && *pchr!='\n')
178 ++pchr;
179 if(pchr!=begin)
181 plist->m_entry.m_filters=malloc(pchr-begin+1);
182 if(!plist->m_entry.m_filters)
183 goto mem_err;
184 strncpy(plist->m_entry.m_filters, begin,pchr-begin);
185 plist->m_entry.m_filters[pchr-begin]=0;
189 //line accepted
190 *ppnext=plist;
191 ppnext=&plist->m_next;
193 fprintf(stderr,"Loaded %s\n",plist->m_entry.m_character);
194 fprintf(stderr,"Strokes:--%s--\n",plist->m_entry.m_strokes);
195 if(plist->m_entry.m_filters)
197 fprintf(stderr,"Filters:--%s--\n",plist->m_entry.m_filters);
198 break;
203 fclose(fd);
207 free(dir);
211 process_strokes (FILE *file)
213 RawStroke strokes[MAX_STROKES];
214 char *buffer = malloc(BUFLEN);
215 int buflen = BUFLEN;
216 int nstrokes = 0;
218 /* Read in strokes from standard in, all points for each stroke
219 * strung together on one line, until we get a blank line
222 while (1)
224 char *p,*q;
225 int len;
227 if (!fgets(buffer, buflen, file))
228 return 0;
230 len=strlen(buffer);
231 while( (buffer[len-1] != '\n') )
233 //fprintf(stderr,"READ PARTIAL (%d so far)\n",buflen-1);
234 //fflush(stderr);
235 if(buflen < 2*len)
237 buflen += BUFLEN;
238 buffer = realloc(buffer, buflen);
240 if (!fgets(buffer+len, buflen-len, file))
241 return 0;
242 len=strlen(buffer);
245 //fprintf(stderr,"parsing %d bytes\n",strlen(buffer));
246 //fflush(stderr);
247 len = 0;
248 p = buffer;
250 while (1) {
251 while (isspace ((unsigned char) *p)) p++;
252 if (*p == 0)
253 break;
254 strokes[nstrokes].m_x[len] = strtol (p, &q, 0);
255 if (p == q)
256 break;
257 p = q;
259 while (isspace ((unsigned char) *p)) p++;
260 if (*p == 0)
261 break;
262 strokes[nstrokes].m_y[len] = strtol (p, &q, 0);
263 if (p == q)
264 break;
265 p = q;
267 len++;
270 if (len == 0)
271 break;
273 strokes[nstrokes].m_len = len;
274 nstrokes++;
275 if (nstrokes == MAX_STROKES)
276 break;
277 //fprintf(stderr,"added strok (%d)\n",nstrokes);
280 if (nstrokes != 0 && nstrokes < MAX_STROKES && stroke_dicts[nstrokes])
282 //fprintf(stderr,"attempting %d stroke lookup\n",nstrokes);
283 int i;
284 ListMem *top_picks;
285 StrokeScorer *scorer = StrokeScorerCreate (stroke_dicts[nstrokes],
286 strokes, nstrokes);
287 if (scorer)
289 StrokeScorerProcess(scorer, -1);
290 top_picks = StrokeScorerTopPicks(scorer);
291 StrokeScorerDestroy(scorer);
293 printf("K");
294 for (i=0;i<(int)top_picks->m_argc;i++)
296 if (i)
297 printf(" ");
298 printf("%s",top_picks->m_argv[i]);
301 free(top_picks);
303 printf("\n");
305 fflush(stdout);
307 else
309 fprintf(stderr,"Invalid number of strokes: %d\n",nstrokes);
311 return 1;
314 void
315 usage ()
317 fprintf(stderr, "Usage: %s [-f/--data-dir DIR]\n", progname);
318 exit (1);
321 int
322 real_main(int argc, char **argv)
324 int i;
325 char *p = progname = argv[0];
326 while (*p)
328 if (*p == '/') progname = p+1;
329 p++;
332 for (i=1; i<argc; i++)
334 if (!strcmp(argv[i], "--data-dir") ||
335 !strcmp(argv[i], "-d"))
337 i++;
338 if (i < argc)
339 data_dir = argv[i];
340 else
341 usage();
343 else
345 usage();
349 load_database();
351 while (process_strokes (stdin))
354 return 0;
357 #ifdef __MSWINDOWS__
358 #include <windows.h>
360 /* To avoid a console window coming up while running our
361 * program, on Win32, we act as a GUI app... a WinMain()
362 * and no main().
364 #ifdef __GNUC__
365 # ifndef _stdcall
366 # define _stdcall __attribute__((stdcall))
367 # endif
368 #endif
370 int _stdcall
371 WinMain (struct HINSTANCE__ *hInstance,
372 struct HINSTANCE__ *hPrevInstance,
373 char *lpszCmdLine,
374 int nCmdShow)
376 return real_main (__argc, __argv);
378 #else
379 int
380 main(int argc, char **argv)
382 return real_main (argc, argv);
384 #endif