1 /*
2
3 Copyright (c) 2003-2013 uim Project https://github.com/uim/uim
4
5 All rights reserved.
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 1. Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13 2. Redistributions in binary form must reproduce the above copyright
14 notice, this list of conditions and the following disclaimer in the
15 documentation and/or other materials provided with the distribution.
16 3. Neither the name of authors nor the names of its contributors
17 may be used to endorse or promote products derived from this software
18 without specific prior written permission.
19
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
21 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE
24 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 SUCH DAMAGE.
31
32 */
33
34 #include <config.h>
35
36 #include <string.h>
37
38 #include "uim-internal.h"
39 #include "uim-scm.h"
40 #include "uim-scm-abbrev.h"
41
42
43 static uim_bool
string_equalp(uim_lisp x,uim_lisp y)44 string_equalp(uim_lisp x, uim_lisp y)
45 {
46 return (strcmp(uim_scm_refer_c_str(x), uim_scm_refer_c_str(y)) == 0);
47 }
48
49 static uim_lisp
str_seq_equal(uim_lisp seq,uim_lisp rule)50 str_seq_equal(uim_lisp seq, uim_lisp rule)
51 {
52 int sl = uim_scm_length(seq);
53 int rl = uim_scm_length(rule);
54 int i;
55 if (sl != rl) {
56 return uim_scm_f();
57 }
58 for (i = 0; i < sl; i++) {
59 if (!string_equalp(uim_scm_car(seq), uim_scm_car(rule))) {
60 return uim_scm_f();
61 }
62 seq = uim_scm_cdr(seq);
63 rule = uim_scm_cdr(rule);
64 }
65 return uim_scm_t();
66 }
67
68 /*
69 * Partial -> first string of remaining sequence
70 * eg. ("a" "b") ("a" "b" "c") -> "c"
71 * Not partial -> #f
72 *
73 */
74 static uim_lisp
str_seq_partial(uim_lisp seq,uim_lisp rule)75 str_seq_partial(uim_lisp seq, uim_lisp rule)
76 {
77 int sl = uim_scm_length(seq);
78 int rl = uim_scm_length(rule);
79 int i;
80
81 if (sl >= rl) {
82 return uim_scm_f();
83 }
84 /* Obviously. sl < rl */
85 for (i = 0; i < sl; i++) {
86 if (!string_equalp(uim_scm_car(seq), uim_scm_car(rule))) {
87 return uim_scm_f();
88 }
89 seq = uim_scm_cdr(seq);
90 rule = uim_scm_cdr(rule);
91 }
92 if (rule && uim_scm_car(rule)) {
93 return uim_scm_car(rule);
94 }
95 /* never reach here */
96 return uim_scm_f();
97 }
98
99 static uim_lisp
rk_find_seq(uim_lisp seq,uim_lisp rules)100 rk_find_seq(uim_lisp seq, uim_lisp rules)
101 {
102 for (; !uim_scm_nullp(rules); rules = uim_scm_cdr(rules)) {
103 uim_lisp rule = uim_scm_car(rules);
104 uim_lisp key = uim_scm_car(uim_scm_car(rule));
105 if (TRUEP(str_seq_equal(seq, key))) {
106 return rule;
107 }
108 }
109 return uim_scm_f();
110 }
111
112 static uim_lisp
rk_find_partial_seq(uim_lisp seq,uim_lisp rules)113 rk_find_partial_seq(uim_lisp seq, uim_lisp rules)
114 {
115 for (; !uim_scm_nullp(rules); rules = uim_scm_cdr(rules)) {
116 uim_lisp rule = uim_scm_car(rules);
117 uim_lisp key = uim_scm_car(uim_scm_car(rule));
118 if (TRUEP(str_seq_partial(seq, key))) {
119 return rule;
120 }
121 }
122 return uim_scm_f();
123 }
124
125 static uim_lisp
rk_find_partial_seqs(uim_lisp seq,uim_lisp rules)126 rk_find_partial_seqs(uim_lisp seq, uim_lisp rules)
127 {
128 uim_lisp ret = uim_scm_null();
129
130 for (; !uim_scm_nullp(rules); rules = uim_scm_cdr(rules)) {
131 uim_lisp rule = uim_scm_car(rules);
132 uim_lisp key = uim_scm_car(uim_scm_car(rule));
133 if (TRUEP(str_seq_partial(seq, key))) {
134 ret = uim_scm_cons(rule, ret);
135 }
136 }
137 return uim_scm_callf("reverse", "o", ret);
138 }
139
140 /*
141 * returns possible next characters
142 * (rk-lib-expect-seq '("k" "y") ja-rk-rule) -> ("o" "e" "u" "i" "a")
143 */
144 static uim_lisp
rk_expect_seq(uim_lisp seq,uim_lisp rules)145 rk_expect_seq(uim_lisp seq, uim_lisp rules)
146 {
147 uim_lisp cur, res = uim_scm_null();
148 for (cur = rules; !uim_scm_nullp(cur); cur = uim_scm_cdr(cur)) {
149 uim_lisp rule = uim_scm_car(cur);
150 uim_lisp key = CAR(CAR(rule));
151 uim_lisp e = str_seq_partial(seq, key);
152 if (TRUEP(e)) {
153 res = uim_scm_cons(e, res);
154 }
155 }
156 return res; /* don't return uim_scm_f() */
157 }
158
159 /*
160 * returns #t if key is expected
161 * (rk-lib-expect-seq-for-key '("k" "y") ja-rk-rule "o") -> #t
162 * (rk-lib-expect-seq-for-key '("k" "y") ja-rk-rule "y") -> #f
163 */
164 static uim_lisp
rk_expect_key_for_seq(uim_lisp seq,uim_lisp rules,uim_lisp key)165 rk_expect_key_for_seq(uim_lisp seq, uim_lisp rules, uim_lisp key)
166 {
167 uim_lisp cur;
168 for (cur = rules; !uim_scm_nullp(cur); cur = uim_scm_cdr(cur)) {
169 uim_lisp rule = uim_scm_car(cur);
170 uim_lisp seq_in_rule = CAR(CAR(rule));
171 uim_lisp e = str_seq_partial(seq, seq_in_rule);
172 if (TRUEP(e) && string_equalp(e, key)) {
173 return uim_scm_t();
174 }
175 }
176 return uim_scm_f();
177 }
178
179
180 void
uim_init_rk_subrs(void)181 uim_init_rk_subrs(void)
182 {
183 uim_scm_init_proc2("str-seq-equal?", str_seq_equal);
184 uim_scm_init_proc2("str-seq-partial?", str_seq_partial);
185 uim_scm_init_proc2("rk-lib-find-seq", rk_find_seq);
186 uim_scm_init_proc2("rk-lib-find-partial-seq", rk_find_partial_seq);
187 uim_scm_init_proc2("rk-lib-find-partial-seqs", rk_find_partial_seqs);
188 uim_scm_init_proc2("rk-lib-expect-seq", rk_expect_seq);
189 uim_scm_init_proc3("rk-lib-expect-key-for-seq?", rk_expect_key_for_seq);
190 }
191