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
28grn_ts_bool
29grn_ts_byte_is_decimal(uint8_t byte)
30{
31 return (byte >= '0') && (byte <= '9');
32}
33
34grn_ts_bool
35grn_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
52grn_ts_bool
53grn_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
61grn_ts_str
62grn_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
75grn_ts_str
76grn_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
95grn_ts_bool
96grn_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
126grn_ts_bool
127grn_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
138grn_ts_bool
139grn_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
147grn_ts_bool
148grn_ts_str_is_true(grn_ts_str str)
149{
150 return (str.size == 4) && !memcmp(str.ptr, "true", 4);
151}
152
153grn_ts_bool
154grn_ts_str_is_false(grn_ts_str str)
155{
156 return (str.size == 5) && !memcmp(str.ptr, "false", 5);
157}
158
159grn_ts_bool
160grn_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
165grn_ts_bool
166grn_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
172grn_ts_bool
173grn_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
179grn_ts_bool
180grn_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
186grn_ts_bool
187grn_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