text: #ifndef DDEBUG
  #define DDEBUG 0
  #endif
  #include "ddebug.h"
  
  #include "ngx_http_echo_foreach.h"
  #include "ngx_http_echo_util.h"
  
  #include <nginx.h>
  
  
  ngx_int_t
  ngx_http_echo_it_variable(ngx_http_request_t *r,
      ngx_http_variable_value_t *v, uintptr_t data)
  {
      ngx_http_echo_ctx_t         *ctx;
      ngx_uint_t                  i;
      ngx_array_t                 *choices;
      ngx_str_t                   *choice_elts, *choice;
  
      ctx = ngx_http_get_module_ctx(r, ngx_http_echo_module);
  
      if (ctx && ctx->foreach != NULL) {
  
          choices = ctx->foreach->choices;
          i = ctx->foreach->next_choice;
  
          if (i < choices->nelts) {
              choice_elts = choices->elts;
              choice = &choice_elts[i];
  
              v->len = choice->len;
              v->data = choice->data;
              v->valid = 1;
              v->no_cacheable = 1;
              v->not_found = 0;
  
              return NGX_OK;
          }
      }
  
      v->not_found = 1;
  
      return NGX_OK;
  }
  
  
  ngx_int_t
  ngx_http_echo_exec_echo_foreach_split(ngx_http_request_t *r,
      ngx_http_echo_ctx_t *ctx, ngx_array_t *computed_args)
  {
      ngx_http_echo_loc_conf_t    *elcf;
      ngx_str_t                   *delimiter, *compound;
      u_char                      *pos, *last, *end;
      ngx_str_t                   *choice;
      ngx_str_t                   *computed_arg_elts;
      ngx_array_t                 *cmds;
      ngx_http_echo_cmd_t         *cmd;
      ngx_http_echo_cmd_t         *cmd_elts;
  
      if (ctx->foreach != NULL) {
          ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                        "Nested echo_foreach not supported yet.");
          return NGX_HTTP_INTERNAL_SERVER_ERROR;
      }
  
      if (computed_args->nelts < 2) {
          ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                        "echo_foreach should take at least two arguments. "
                        "(if your delimiter starts with \"-\", preceding it "
                        "with a \"--\".)");
  
          return NGX_HTTP_INTERNAL_SERVER_ERROR;
      }
  
      computed_arg_elts = computed_args->elts;
  
      compound  = &computed_arg_elts[1];
  
      dd("HEY coumpound len: %u", (int) compound->len);
  
      ctx->foreach = ngx_palloc(r->pool, sizeof(ngx_http_echo_foreach_ctx_t));
  
      if (ctx->foreach == NULL) {
          return NGX_ERROR;
      }
  
      ctx->foreach->cmd_index = ctx->next_handler_cmd;
  
      ctx->foreach->next_choice = 0;
  
      ctx->foreach->choices = ngx_array_create(r->pool, 10, sizeof(ngx_str_t));
      if (ctx->foreach->choices == NULL) {
          return NGX_ERROR;
      }
  
      delimiter = &computed_arg_elts[0];
  
      pos = compound->data;
      end = compound->data + compound->len;
  
      while ((last = ngx_http_echo_strlstrn(pos, end, delimiter->data,
                                            delimiter->len - 1)) != NULL)
      {
          dd("entered the loop");
  
          if (last == pos) {
              dd("!!! len == 0");
              pos = last + delimiter->len;
              continue;
          }
  
          choice = ngx_array_push(ctx->foreach->choices);
          if (choice == NULL) {
              return NGX_ERROR;
          }
  
          choice->data = pos;
          choice->len  = last - pos;
          pos = last + delimiter->len;
      }
  
      if (pos < end) {
          choice = ngx_array_push(ctx->foreach->choices);
          if (choice == NULL) {
              return NGX_ERROR;
          }
  
          choice->data = pos;
          choice->len  = end - pos;
      }
  
      if (ctx->foreach->choices->nelts == 0) {
          /* skip the foreach body entirely */
          elcf = ngx_http_get_module_loc_conf(r, ngx_http_echo_module);
          cmds = elcf->handler_cmds;
          cmd_elts = cmds->elts;
          for (/* void */; ctx->next_handler_cmd < cmds->nelts;
               ctx->next_handler_cmd++)
          {
              cmd = &cmd_elts[ctx->next_handler_cmd + 1];
              if (cmd->opcode == echo_opcode_echo_end) {
                  return NGX_OK;
              }
          }
  
      }
  
      return NGX_OK;
  }
  
  
  ngx_int_t
  ngx_http_echo_exec_echo_end(ngx_http_request_t *r,
      ngx_http_echo_ctx_t *ctx)
  {
      if (ctx->foreach == NULL) {
          ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                       "Found a echo_end that has no corresponding echo_foreach "
                       "before it.");
          return NGX_ERROR;
      }
  
      ctx->foreach->next_choice++;
  
      if (ctx->foreach->next_choice >= ctx->foreach->choices->nelts) {
          /* TODO We need to explicitly free the foreach ctx from
           * the pool */
          ctx->foreach = NULL;
  
          return NGX_OK;
      }
  
      dd("echo_end: ++ next_choice (total: %u): %u",
         (unsigned) ctx->foreach->choices->nelts,
         (unsigned) ctx->foreach->next_choice);
  
      /* the main handler dispatcher loop will increment
       *   ctx->next_handler_cmd for us anyway. */
      ctx->next_handler_cmd = ctx->foreach->cmd_index;
  
      return NGX_OK;
  }
  