[Groonga-commit] groonga/groonga at e83381d [master] grn_ts: add grn_ts_split_output_columns()

Back to archive index

susumu.yata null+****@clear*****
Wed Sep 16 12:04:25 JST 2015


susumu.yata	2015-09-16 12:04:25 +0900 (Wed, 16 Sep 2015)

  New Revision: e83381d30eee380b91e5ddbbc880baf13c9685d2
  https://github.com/groonga/groonga/commit/e83381d30eee380b91e5ddbbc880baf13c9685d2

  Message:
    grn_ts: add grn_ts_split_output_columns()
    
    GitHub: #402

  Modified files:
    lib/ts.c

  Modified: lib/ts.c (+109 -0)
===================================================================
--- lib/ts.c    2015-09-16 00:29:40 +0900 (4ce5337)
+++ lib/ts.c    2015-09-16 12:04:25 +0900 (0665529)
@@ -5441,6 +5441,115 @@ grn_ts_select_filter(grn_ctx *ctx, grn_obj *table,
   return GRN_SUCCESS;
 }
 
+/*
+ * grn_ts_split_output_columns() splits an --output_columns option string which
+ * is separated by commas.
+ */
+static grn_rc
+grn_ts_split_output_columns(grn_ctx *ctx, grn_ts_str str,
+                            grn_ts_str **out, size_t *n_out) {
+  grn_rc rc = GRN_SUCCESS;
+  grn_ts_str rest = str;
+  grn_ts_buf stack;
+  grn_ts_str *tokens = NULL;
+  size_t n_tokens = 0, max_n_tokens = 0;
+
+  grn_ts_buf_init(ctx, &stack);
+  while (rest.size) {
+    size_t i, token_size, next_offset;
+    char stack_top = '\0';
+    rest = grn_ts_str_trim_left(rest);
+    if (!rest.size) {
+      break;
+    }
+    /* Find the end of the current token. */
+    for (i = 0; i < rest.size; i++) {
+      if (stack.pos) {
+        if (rest.ptr[i] == stack_top) {
+          stack.pos--;
+          stack_top = stack.pos ? ((char *)stack.ptr)[stack.pos - 1] : '\0';
+          continue;
+        }
+        if (stack_top == '"') {
+          /* '\' works as an escape character in a string. */
+          if (rest.ptr[i] == '\\') {
+            /* Skip the next byte if exists. */
+            if (i < (rest.size - 1)) {
+              i++;
+            }
+          }
+          continue;
+        }
+      } else if (rest.ptr[i] == ',') {
+        break;
+      }
+      switch (rest.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;
+    }
+
+    /* Append the current token. */
+    token_size = i;
+    if (token_size) {
+      grn_ts_str new_token = { rest.ptr, token_size };
+      if (n_tokens == max_n_tokens) {
+        size_t new_max_n_tokens = n_tokens ? (n_tokens * 2) : 1;
+        size_t n_bytes = sizeof(grn_ts_str) * new_max_n_tokens;
+        grn_ts_str *new_tokens = (grn_ts_str *)GRN_REALLOC(tokens, n_bytes);
+        if (!new_tokens) {
+          rc = GRN_NO_MEMORY_AVAILABLE;
+          break;
+        }
+        tokens = new_tokens;
+        max_n_tokens = new_max_n_tokens;
+      }
+      tokens[n_tokens++] = new_token;
+    }
+
+    /* Update the rest. */
+    next_offset = token_size;
+    if (token_size != rest.size) {
+      next_offset++;
+    }
+    rest.ptr = (char *)rest.ptr + next_offset;
+    rest.size -= next_offset;
+  }
+
+  grn_ts_buf_fin(ctx, &stack);
+  if (rc == GRN_SUCCESS) {
+    *out = tokens;
+    *n_out = n_tokens;
+  } else if (tokens) {
+    GRN_FREE(tokens);
+  }
+  return rc;
+}
+
 /* grn_ts_select_output_parse() parses an output_columns option. */
 static grn_rc
 grn_ts_select_output_parse(grn_ctx *ctx, grn_obj *table,
-------------- next part --------------
HTML����������������������������...
다운로드 



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