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