[Groonga-commit] groonga/groonga at 5dc7e04 [master] grn_ts: add grn_ts_parser_split()

Back to archive index

susumu.yata null+****@clear*****
Wed Nov 25 14:24:17 JST 2015


susumu.yata	2015-11-25 14:24:17 +0900 (Wed, 25 Nov 2015)

  New Revision: 5dc7e044ab81bc86b1ecc34af47c2f032b44ec1b
  https://github.com/groonga/groonga/commit/5dc7e044ab81bc86b1ecc34af47c2f032b44ec1b

  Message:
    grn_ts: add grn_ts_parser_split()

  Modified files:
    lib/ts/ts_expr_parser.c
    lib/ts/ts_expr_parser.h

  Modified: lib/ts/ts_expr_parser.c (+85 -0)
===================================================================
--- lib/ts/ts_expr_parser.c    2015-11-25 13:54:03 +0900 (ef52b93)
+++ lib/ts/ts_expr_parser.c    2015-11-25 14:24:17 +0900 (14c3ef2)
@@ -1228,3 +1228,88 @@ grn_ts_expr_parser_parse(grn_ctx *ctx, grn_ts_expr_parser *parser,
   }
   return grn_ts_expr_builder_complete(ctx, parser->builder, expr);
 }
+
+grn_rc
+grn_ts_expr_parser_split(grn_ctx *ctx, grn_ts_expr_parser *parser,
+                         grn_ts_str str, grn_ts_str *first, grn_ts_str *rest)
+{
+  size_t i;
+  char stack_top;
+  grn_rc rc = GRN_SUCCESS;
+  grn_ts_buf stack;
+
+  // FIXME: `stack` should be a member of `parser`.
+  grn_ts_buf_init(ctx, &stack);
+  for ( ; ; ) {
+    str = grn_ts_str_trim_left(str);
+    if (!str.size) {
+      rc = GRN_END_OF_DATA;
+      break;
+    }
+    for (i = 0; i < str.size; i++) {
+      if (stack.pos) {
+        if (str.ptr[i] == stack_top) {
+          if (--stack.pos) {
+            stack_top = ((char *)stack.ptr)[stack.pos - 1];
+          }
+          continue;
+        }
+        if (stack_top == '"') {
+          /* Skip the next byte of an escape character. */
+          if ((str.ptr[i] == '\\') && (i < (str.size - 1))) {
+            i++;
+          }
+          continue;
+        }
+      } else if (str.ptr[i] == ',') {
+        /* An expression delimiter. */
+        break;
+      }
+      switch (str.ptr[i]) {
+        case '(': {
+          stack_top = ')';
+          rc = grn_ts_buf_write(ctx, &stack, &stack_top, 1);
+          break;
+        }
+        case '[': {
+          stack_top = ']';
+          rc = grn_ts_buf_write(ctx, &stack, &stack_top, 1);
+          break;
+        }
+        case '{': {
+          stack_top = '}';
+          rc = grn_ts_buf_write(ctx, &stack, &stack_top, 1);
+          break;
+        }
+        case '"': {
+          stack_top = '"';
+          rc = grn_ts_buf_write(ctx, &stack, &stack_top, 1);
+          break;
+        }
+      }
+      if (rc != GRN_SUCCESS) {
+        break;
+      }
+    }
+    if (rc != GRN_SUCCESS) {
+      break;
+    }
+    if (i) {
+      /* Set the result. */
+      first->ptr = str.ptr;
+      first->size = i;
+      if (first->size == str.size) {
+        rest->ptr = str.ptr + str.size;
+        rest->size = 0;
+      } else {
+        rest->ptr = str.ptr + first->size + 1;
+        rest->size = str.size - first->size - 1;
+      }
+      break;
+    }
+    str.ptr++;
+    str.size--;
+  }
+  grn_ts_buf_fin(ctx, &stack);
+  return rc;
+}

  Modified: lib/ts/ts_expr_parser.h (+9 -0)
===================================================================
--- lib/ts/ts_expr_parser.h    2015-11-25 13:54:03 +0900 (43caec1)
+++ lib/ts/ts_expr_parser.h    2015-11-25 14:24:17 +0900 (9c9122e)
@@ -93,6 +93,15 @@ grn_rc grn_ts_expr_parser_close(grn_ctx *ctx, grn_ts_expr_parser *parser);
 grn_rc grn_ts_expr_parser_parse(grn_ctx *ctx, grn_ts_expr_parser *parser,
                                 grn_ts_str str, grn_ts_expr **expr);
 
+/*
+ * grn_ts_expr_parser_split() splits comma-separated strings into the first
+ * expression and the rest.
+ * Note that if `str` is empty, this function returns GRN_END_OF_DATA.
+ */
+grn_rc grn_ts_expr_parser_split(grn_ctx *ctx, grn_ts_expr_parser *parser,
+                                grn_ts_str str, grn_ts_str *first,
+                                grn_ts_str *rest);
+
 #ifdef __cplusplus
 }
 #endif
-------------- next part --------------
HTML����������������������������...
Download 



More information about the Groonga-commit mailing list
Back to archive index