]> granicus.if.org Git - jq/commitdiff
Add index strings by string; return string indexes
authorNicolas Williams <nico@cryptonector.com>
Mon, 2 Dec 2013 18:16:38 +0000 (12:16 -0600)
committerNicolas Williams <nico@cryptonector.com>
Thu, 5 Dec 2013 00:21:42 +0000 (18:21 -0600)
    % jq '.[","]'
    "a,bc,def,ghij,klmno"
    [1,4,8,13]
    %

jv.c
jv.h
jv_aux.c

diff --git a/jv.c b/jv.c
index b66b073820c781f9f9bbb1c56d1838ef0b264df1..0c0bbb76bce29196a8c9503425c6fd20cdd767f2 100644 (file)
--- a/jv.c
+++ b/jv.c
@@ -621,6 +621,26 @@ not_this:
 }
 #endif /* HAVE_MEMMEM */
 
+jv jv_string_indexes(jv j, jv k) {
+  assert(jv_get_kind(j) == JV_KIND_STRING);
+  assert(jv_get_kind(k) == JV_KIND_STRING);
+  const char *jstr = jv_string_value(j);
+  const char *idxstr = jv_string_value(k);
+  const char *p;
+  int jlen = jv_string_length_bytes(jv_copy(j));
+  int idxlen = jv_string_length_bytes(jv_copy(k));
+  jv a = jv_array();
+
+  p = jstr;
+  while ((p = memmem(p, (jstr + jlen) - p, idxstr, idxlen)) != NULL) {
+    a = jv_array_append(a, jv_number(p - jstr));
+    p += idxlen;
+  }
+  jv_free(j);
+  jv_free(k);
+  return a;
+}
+
 jv jv_string_split(jv j, jv sep) {
   assert(jv_get_kind(j) == JV_KIND_STRING);
   assert(jv_get_kind(sep) == JV_KIND_STRING);
diff --git a/jv.h b/jv.h
index 6b06eea32a1390766a8face4e8df6524002e7b5f..efc6fecbe8aff852b412bd4f9b0c0b5e9c69805e 100644 (file)
--- a/jv.h
+++ b/jv.h
@@ -83,6 +83,7 @@ int jv_string_length_bytes(jv);
 int jv_string_length_codepoints(jv);
 unsigned long jv_string_hash(jv);
 const char* jv_string_value(jv);
+jv jv_string_indexes(jv j, jv k);
 jv jv_string_slice(jv j, int start, int end);
 jv jv_string_concat(jv, jv);
 jv jv_string_vfmt(const char*, va_list);
index f3260c9dcf5be694dd3580b73ce7ad0188acb56b..76712aee130e1c73cc1bdbc91e24185bde7d30d1 100644 (file)
--- a/jv_aux.c
+++ b/jv_aux.c
@@ -73,6 +73,8 @@ jv jv_get(jv t, jv k) {
       v = jv_invalid_with_msg(jv_string_fmt("Start and end indices of an string slice must be numbers"));
       jv_free(t);
     }
+  } else if (jv_get_kind(t) == JV_KIND_STRING && jv_get_kind(k) == JV_KIND_STRING) {
+    v = jv_string_indexes(t, k);
   } else if (jv_get_kind(t) == JV_KIND_NULL && 
              (jv_get_kind(k) == JV_KIND_STRING || 
               jv_get_kind(k) == JV_KIND_NUMBER ||