-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathskkdic-sort.c
191 lines (163 loc) · 4.53 KB
/
skkdic-sort.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
/* SKK JISYO TOOLS (SKK dictionary handling tools)
Copyright (C) 1994, 1996, 1999, 2000
Hironobu Takahashi, Masahiko Sato, Kiyotaka Sakai
Author: Hironobu Takahashi, Masahiko Sato, Kiyotaka Sakai, Kenji Yabuuchi
Maintainer: Mikio Nakajima <[email protected]>
Keywords: japanese
This file is part of Daredevil SKK.
SKK JISYO TOOLS are free software; you can redistribute them and/or modify
them 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.
SKK JISYO TOOLS are distributed in the hope that they 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 SKK; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */
/* skkdic-sort.c
このプログラムは SKK の辞書の整列を行います
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_MALLOC_H
#include <malloc.h>
#endif
/* このプログラムでは辞書をすべてメモリの中に読み込みます。
次の値はあらかじめ用意するメモリと、不足した場合に追加す
るメモリの量を規定します。あまり小さいと頻繁に realloc()
が発生します。*/
#define STEP (256*1024)
/* 辞書は次のポインタによって差されたメモリに書き込まれます */
static unsigned char *dict;
static unsigned int dictsize;
/* 辞書のインデクスリストです */
static unsigned int *index;
/* ソートで使用するポインタです */
static unsigned int *list;
static unsigned int n_line;
/* 辞書の読み込みプログラム */
static void
readdict()
{
unsigned int bufsize, incsize;
dictsize = 0;
/* 辞書用のメモリとして STEP バイトを用意します */
dict = malloc(STEP);
bufsize = STEP;
incsize = fread(dict+dictsize, 1, bufsize-dictsize, stdin);
dictsize += incsize;
/* もしも一杯ならば STEP バイトずつ増やして読み込みを繰り返します */
while (dictsize == bufsize) {
bufsize += STEP;
dict = realloc(dict, bufsize);
incsize = fread(dict+dictsize, 1, bufsize-dictsize, stdin);
dictsize += incsize;
}
}
/* インデクスを作成 */
static void
make_index()
{
int i, n;
n = 0;
for (i = 0; i < dictsize; ++ i)
if (dict[i] == '\n')
++ n;
n_line = n;
index = malloc((sizeof *index)*(n_line+1));
n = 0;
index[0] = 0;
for (i = 0; i < dictsize; ++ i)
if (dict[i] == '\n')
index[++n] = i+1;
list = malloc((sizeof *list)*n_line);
for(i = 0; i < n_line; ++ i)
list[i] = i;
}
/* ソートための文字列比較ルーチン
送りなしのエントリで引数 a が先にくるべき時は -1 を返し、
それ以外の時は 1 を返す */
static int
hexcomp(a, b)
unsigned char *a;
unsigned char *b;
{
while(*a == *b) {
++a; ++ b;
}
if (*a > *b) return 1;
return -1;
}
/* 送りがながあるかどうか判断する 0-なし 1-あり */
static int okuriari(p)
unsigned char *p;
{
if (((p[0] & 0x80) == 0) &&
((p[0] != '>' && p[0] != '#') || (p[1] & 0x80) == 0)) return 0;
while(*p != ' ')
if (*p == '\0') return 0; /* 空白がない行は本当は異常として扱うべき */
else ++ p;
if (('a' <= p[-1]) && (p[-1] <= 'z')) return 1;
return 0;
}
/* ソートための比較ルーチン
引数 a が先にくるべき時は -1 を返し、それ以外の時は 1 を返す */
int skkcompar(a, b)
int *a;
int *b;
{
unsigned char *ptra, *ptrb;
ptra = dict+index[*a];
ptrb = dict+index[*b];
if (okuriari(ptra)) {
if (okuriari(ptrb))
/* いずれも送り仮名があるので、a b を交換して比較する */
return hexcomp(ptrb, ptra);
else
return -1; /* a が先 */
} else {
if (okuriari(ptrb))
return 1; /* a が後 */
else
/* いずれも送り仮名がないので、a b をそのまま比較した結果を返す */
return hexcomp(ptra, ptrb);
}
}
/* 結果を出力 */
static void printout()
{
int i;
unsigned char *ptr, *line;
int okuriflag;
puts(";; okuri-ari entries.");
okuriflag = 1;
for(i = 0; i < n_line; ++ i) {
line = dict+index[list[i]];
if (line[0] == ';') continue; /* コメント行は出力しない */
if (okuriflag) {
if (!okuriari(line)) {
puts(";; okuri-nasi entries.");
okuriflag = 0;
}
}
for (ptr = line; *ptr != '\n'; ++ ptr)
putchar(*ptr);
putchar('\n');
}
}
/* メインプログラム 引数は使用しません */
int main(argc, argv)
int argc;
char **argv;
{
readdict();
make_index();
qsort((char *)list, n_line, sizeof *list, skkcompar);
printout();
return 0;
}
/* end of skkdic-sort.c */