mirror of
https://github.com/stedolan/jq.git
synced 2024-05-11 05:55:39 +00:00
Add string division by string (split on separator)
This commit is contained in:
@@ -160,6 +160,8 @@ static jv f_divide(jv input, jv a, jv b) {
|
|||||||
jv_free(input);
|
jv_free(input);
|
||||||
if (jv_get_kind(a) == JV_KIND_NUMBER && jv_get_kind(b) == JV_KIND_NUMBER) {
|
if (jv_get_kind(a) == JV_KIND_NUMBER && jv_get_kind(b) == JV_KIND_NUMBER) {
|
||||||
return jv_number(jv_number_value(a) / jv_number_value(b));
|
return jv_number(jv_number_value(a) / jv_number_value(b));
|
||||||
|
} else if (jv_get_kind(a) == JV_KIND_STRING && jv_get_kind(b) == JV_KIND_STRING) {
|
||||||
|
return jv_string_split(a, b);
|
||||||
} else {
|
} else {
|
||||||
return type_error2(a, b, "cannot be divided");
|
return type_error2(a, b, "cannot be divided");
|
||||||
}
|
}
|
||||||
@@ -539,6 +541,7 @@ static const struct cfunction function_list[] = {
|
|||||||
{(cfunction_ptr)f_keys, "keys", 1},
|
{(cfunction_ptr)f_keys, "keys", 1},
|
||||||
{(cfunction_ptr)f_startswith, "startswith", 2},
|
{(cfunction_ptr)f_startswith, "startswith", 2},
|
||||||
{(cfunction_ptr)f_endswith, "endswith", 2},
|
{(cfunction_ptr)f_endswith, "endswith", 2},
|
||||||
|
{(cfunction_ptr)jv_string_split, "split", 2},
|
||||||
{(cfunction_ptr)jv_string_explode, "explode", 1},
|
{(cfunction_ptr)jv_string_explode, "explode", 1},
|
||||||
{(cfunction_ptr)jv_string_implode, "implode", 1},
|
{(cfunction_ptr)jv_string_implode, "implode", 1},
|
||||||
{(cfunction_ptr)jv_setpath, "setpath", 3}, // FIXME typechecking
|
{(cfunction_ptr)jv_setpath, "setpath", 3}, // FIXME typechecking
|
||||||
|
48
jv.c
48
jv.c
@@ -596,6 +596,54 @@ int jv_string_length_codepoints(jv j) {
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef HAVE_MEMMEM
|
||||||
|
static const void *memmem(const void *haystack, size_t haystacklen,
|
||||||
|
const void *needle, size_t needlelen)
|
||||||
|
{
|
||||||
|
const char *h = haystack;
|
||||||
|
const char *n = needle;
|
||||||
|
size_t hi, hi2, ni;
|
||||||
|
|
||||||
|
if (haystacklen < needlelen || haystacklen == 0)
|
||||||
|
return NULL;
|
||||||
|
for (hi = 0; hi < (haystacklen - needlelen + 1); hi++) {
|
||||||
|
for (ni = 0, hi2 = hi; ni < needlelen; ni++, hi2++) {
|
||||||
|
if (h[hi2] != n[ni])
|
||||||
|
goto not_this;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &h[hi];
|
||||||
|
|
||||||
|
not_this:
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_MEMMEM */
|
||||||
|
|
||||||
|
jv jv_string_split(jv j, jv sep) {
|
||||||
|
assert(jv_get_kind(j) == JV_KIND_STRING);
|
||||||
|
assert(jv_get_kind(sep) == JV_KIND_STRING);
|
||||||
|
const char *jstr = jv_string_value(j);
|
||||||
|
const char *sepstr = jv_string_value(sep);
|
||||||
|
const char *p, *s;
|
||||||
|
int jlen = jv_string_length_bytes(jv_copy(j));
|
||||||
|
int seplen = jv_string_length_bytes(jv_copy(sep));
|
||||||
|
jv a = jv_array();
|
||||||
|
|
||||||
|
assert(jv_get_refcnt(a) == 1);
|
||||||
|
|
||||||
|
for (p = jstr; p < jstr + jlen; p = s + seplen) {
|
||||||
|
s = memmem(p, (jstr + jlen) - p, sepstr, seplen);
|
||||||
|
if (s == NULL)
|
||||||
|
s = jstr + jlen;
|
||||||
|
a = jv_array_append(a, jv_string_sized(p, s - p));
|
||||||
|
}
|
||||||
|
jv_free(j);
|
||||||
|
jv_free(sep);
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
jv jv_string_explode(jv j) {
|
jv jv_string_explode(jv j) {
|
||||||
assert(jv_get_kind(j) == JV_KIND_STRING);
|
assert(jv_get_kind(j) == JV_KIND_STRING);
|
||||||
const char* i = jv_string_value(j);
|
const char* i = jv_string_value(j);
|
||||||
|
1
jv.h
1
jv.h
@@ -87,6 +87,7 @@ jv jv_string_fmt(const char*, ...);
|
|||||||
jv jv_string_append_codepoint(jv a, uint32_t c);
|
jv jv_string_append_codepoint(jv a, uint32_t c);
|
||||||
jv jv_string_append_buf(jv a, const char* buf, int len);
|
jv jv_string_append_buf(jv a, const char* buf, int len);
|
||||||
jv jv_string_append_str(jv a, const char* str);
|
jv jv_string_append_str(jv a, const char* str);
|
||||||
|
jv jv_string_split(jv j, jv sep);
|
||||||
jv jv_string_explode(jv j);
|
jv jv_string_explode(jv j);
|
||||||
jv jv_string_implode(jv j);
|
jv jv_string_implode(jv j);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user