1 | /* -*- c-basic-offset: 2 -*- */ |
2 | /* |
3 | Copyright(C) 2015 Brazil |
4 | |
5 | This library is free software; you can redistribute it and/or |
6 | modify it under the terms of the GNU Lesser General Public |
7 | License version 2.1 as published by the Free Software Foundation. |
8 | |
9 | This library is distributed in the hope that it will be useful, |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | Lesser General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU Lesser General Public |
15 | License along with this library; if not, write to the Free Software |
16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
17 | */ |
18 | |
19 | #include "ts_str.h" |
20 | |
21 | #include <ctype.h> |
22 | #include <string.h> |
23 | |
24 | /*------------------------------------------------------------- |
25 | * Byte. |
26 | */ |
27 | |
28 | grn_ts_bool |
29 | grn_ts_byte_is_decimal(uint8_t byte) |
30 | { |
31 | return (byte >= '0') && (byte <= '9'); |
32 | } |
33 | |
34 | grn_ts_bool |
35 | grn_ts_byte_is_name_char(uint8_t byte) |
36 | { |
37 | /* |
38 | * Note: A table name allows '#', '@' and '-'. |
39 | * http://groonga.org/docs/reference/commands/table_create.html#name |
40 | */ |
41 | if (((byte >= '0') && (byte <= '9')) || ((byte >= 'A') && (byte <= 'Z')) || |
42 | ((byte >= 'a') && (byte <= 'z')) || (byte == '_')) { |
43 | return GRN_TRUE; |
44 | } |
45 | return GRN_FALSE; |
46 | } |
47 | |
48 | /*------------------------------------------------------------- |
49 | * String. |
50 | */ |
51 | |
52 | grn_ts_bool |
53 | grn_ts_str_starts_with(grn_ts_str str, grn_ts_str prefix) |
54 | { |
55 | if (str.size < prefix.size) { |
56 | return GRN_FALSE; |
57 | } |
58 | return !memcmp(str.ptr, prefix.ptr, prefix.size); |
59 | } |
60 | |
61 | grn_ts_str |
62 | grn_ts_str_trim_left(grn_ts_str str) |
63 | { |
64 | size_t i; |
65 | for (i = 0; i < str.size; i++) { |
66 | if (!isspace((uint8_t)str.ptr[i])) { |
67 | break; |
68 | } |
69 | } |
70 | str.ptr += i; |
71 | str.size -= i; |
72 | return str; |
73 | } |
74 | |
75 | grn_ts_str |
76 | grn_ts_str_trim_score_assignment(grn_ts_str str) |
77 | { |
78 | grn_ts_str rest; |
79 | str = grn_ts_str_trim_left(str); |
80 | if (!grn_ts_str_starts_with(str, (grn_ts_str){ "_score" , 6 })) { |
81 | return str; |
82 | } |
83 | rest.ptr = str.ptr + 6; |
84 | rest.size = str.size - 6; |
85 | rest = grn_ts_str_trim_left(rest); |
86 | if (!rest.size || (rest.ptr[0] != '=') || |
87 | ((rest.size >= 2) && (rest.ptr[1] == '='))) { |
88 | return str; |
89 | } |
90 | rest.ptr++; |
91 | rest.size--; |
92 | return grn_ts_str_trim_left(rest); |
93 | } |
94 | |
95 | grn_ts_bool |
96 | grn_ts_str_has_number_prefix(grn_ts_str str) |
97 | { |
98 | if (!str.size) { |
99 | return GRN_FALSE; |
100 | } |
101 | if (grn_ts_byte_is_decimal(str.ptr[0])) { |
102 | return GRN_TRUE; |
103 | } |
104 | if (str.size == 1) { |
105 | return GRN_FALSE; |
106 | } |
107 | switch (str.ptr[0]) { |
108 | case '+': case '-': { |
109 | if (grn_ts_byte_is_decimal(str.ptr[1])) { |
110 | return GRN_TRUE; |
111 | } |
112 | if (str.size == 2) { |
113 | return GRN_FALSE; |
114 | } |
115 | return (str.ptr[1] == '.') && grn_ts_byte_is_decimal(str.ptr[2]); |
116 | } |
117 | case '.': { |
118 | return grn_ts_byte_is_decimal(str.ptr[1]); |
119 | } |
120 | default: { |
121 | return GRN_FALSE; |
122 | } |
123 | } |
124 | } |
125 | |
126 | grn_ts_bool |
127 | grn_ts_str_is_name_prefix(grn_ts_str str) |
128 | { |
129 | size_t i; |
130 | for (i = 0; i < str.size; i++) { |
131 | if (!grn_ts_byte_is_name_char(str.ptr[i])) { |
132 | return GRN_FALSE; |
133 | } |
134 | } |
135 | return GRN_TRUE; |
136 | } |
137 | |
138 | grn_ts_bool |
139 | grn_ts_str_is_name(grn_ts_str str) |
140 | { |
141 | if (!str.size) { |
142 | return GRN_FALSE; |
143 | } |
144 | return grn_ts_str_is_name_prefix(str); |
145 | } |
146 | |
147 | grn_ts_bool |
148 | grn_ts_str_is_true(grn_ts_str str) |
149 | { |
150 | return (str.size == 4) && !memcmp(str.ptr, "true" , 4); |
151 | } |
152 | |
153 | grn_ts_bool |
154 | grn_ts_str_is_false(grn_ts_str str) |
155 | { |
156 | return (str.size == 5) && !memcmp(str.ptr, "false" , 5); |
157 | } |
158 | |
159 | grn_ts_bool |
160 | grn_ts_str_is_bool(grn_ts_str str) |
161 | { |
162 | return grn_ts_str_is_true(str) || grn_ts_str_is_false(str); |
163 | } |
164 | |
165 | grn_ts_bool |
166 | grn_ts_str_is_id_name(grn_ts_str str) |
167 | { |
168 | return (str.size == GRN_COLUMN_NAME_ID_LEN) && |
169 | !memcmp(str.ptr, GRN_COLUMN_NAME_ID, GRN_COLUMN_NAME_ID_LEN); |
170 | } |
171 | |
172 | grn_ts_bool |
173 | grn_ts_str_is_score_name(grn_ts_str str) |
174 | { |
175 | return (str.size == GRN_COLUMN_NAME_SCORE_LEN) && |
176 | !memcmp(str.ptr, GRN_COLUMN_NAME_SCORE, GRN_COLUMN_NAME_SCORE_LEN); |
177 | } |
178 | |
179 | grn_ts_bool |
180 | grn_ts_str_is_key_name(grn_ts_str str) |
181 | { |
182 | return (str.size == GRN_COLUMN_NAME_KEY_LEN) && |
183 | !memcmp(str.ptr, GRN_COLUMN_NAME_KEY, GRN_COLUMN_NAME_KEY_LEN); |
184 | } |
185 | |
186 | grn_ts_bool |
187 | grn_ts_str_is_value_name(grn_ts_str str) |
188 | { |
189 | return (str.size == GRN_COLUMN_NAME_VALUE_LEN) && |
190 | !memcmp(str.ptr, GRN_COLUMN_NAME_VALUE, GRN_COLUMN_NAME_VALUE_LEN); |
191 | } |
192 | |