text: 
  /*
   * Copyright (C) Igor Sysoev
   * Copyright (C) Nginx, Inc.
   */
  
  
  #ifndef _NGX_HTTP_SCRIPT_H_INCLUDED_
  #define _NGX_HTTP_SCRIPT_H_INCLUDED_
  
  
  #include <ngx_config.h>
  #include <ngx_core.h>
  #include <ngx_http.h>
  
  
  typedef struct {
      u_char                     *ip;     //e->ip = rlcf->codes->elts
      /*关于pos && code: 每次调用code,都会将解析到的新的字符串放入pos指向的字符串处，
  	然后将pos向后移动，下次进入的时候，会自动将数据追加到后面的。
  	对于ip也是这个原理，code里面会将e->ip向后移动。移动的大小根据不同的变量类型相关。
  	ip指向一快内存，其内容为变量相关的一个结构体，比如ngx_http_script_copy_capture_code_t，
  	结构体之后，又是下一个ip的地址。比如移动时是这样的 :
  	code = (ngx_http_script_copy_capture_code_t *) e->ip;
      e->ip += sizeof(ngx_http_script_copy_capture_code_t);//移动这么多位移。
  	*/
      u_char                     *pos;//pos之前的数据就是解析成功的，后面的数据将追加到pos后面。
      ngx_http_variable_value_t  *sp;//这里貌似是用sp来保存中间结果，比如保存当前这一步的进度，到下一步好用e->sp--来找到上一步的结果。
  
      ngx_str_t                   buf;//存放结果，也就是buffer，pos指向其中。
      ngx_str_t                   line;//记录请求行URI  e->line = r->uri;
  
      /* the start of the rewritten arguments */
      u_char                     *args;
  
      unsigned                    flushed:1;
      unsigned                    skip:1;
      unsigned                    quote:1;
      unsigned                    is_args:1;
      unsigned                    log:1;
  
      ngx_int_t                   status;
      ngx_http_request_t         *request;//所属的请求
  } ngx_http_script_engine_t;
  
  
  typedef struct {
      ngx_conf_t                 *cf;
      ngx_str_t                  *source;
  
      ngx_array_t               **flushes;
      ngx_array_t               **lengths;
      ngx_array_t               **values;
  
      ngx_uint_t                  variables;
      ngx_uint_t                  ncaptures;
      ngx_uint_t                  captures_mask;
      ngx_uint_t                  size;
  
      void                       *main;
  
      unsigned                    compile_args:1;
      unsigned                    complete_lengths:1;
      unsigned                    complete_values:1;
      unsigned                    zero:1;
      unsigned                    conf_prefix:1;
      unsigned                    root_prefix:1;
  
      unsigned                    dup_capture:1;
      unsigned                    args:1;
  } ngx_http_script_compile_t;
  
  
  typedef struct {
      ngx_str_t                   value;
      ngx_uint_t                 *flushes;
      void                       *lengths;
      void                       *values;
  } ngx_http_complex_value_t;
  
  
  typedef struct {
      ngx_conf_t                 *cf;
      ngx_str_t                  *value;
      ngx_http_complex_value_t   *complex_value;
  
      unsigned                    zero:1;
      unsigned                    conf_prefix:1;
      unsigned                    root_prefix:1;
  } ngx_http_compile_complex_value_t;
  
  
  typedef void (*ngx_http_script_code_pt) (ngx_http_script_engine_t *e);
  typedef size_t (*ngx_http_script_len_code_pt) (ngx_http_script_engine_t *e);
  
  
  typedef struct {
      ngx_http_script_code_pt     code;
      uintptr_t                   len;
  } ngx_http_script_copy_code_t;
  
  
  typedef struct {
      ngx_http_script_code_pt     code;
      uintptr_t                   index;
  } ngx_http_script_var_code_t;
  
  
  typedef struct {
      ngx_http_script_code_pt     code;
      ngx_http_set_variable_pt    handler;
      uintptr_t                   data;
  } ngx_http_script_var_handler_code_t;
  
  
  typedef struct {
      ngx_http_script_code_pt     code;
      uintptr_t                   n;
  } ngx_http_script_copy_capture_code_t;
  
  
  #if (NGX_PCRE)
  
  typedef struct {
      ngx_http_script_code_pt     code;
      ngx_http_regex_t           *regex;
      ngx_array_t                *lengths;
      uintptr_t                   size;
      uintptr_t                   status;
      uintptr_t                   next;
  
      unsigned                    test:1;
      unsigned                    negative_test:1;
      unsigned                    uri:1;
      unsigned                    args:1;
  
      /* add the r->args to the new arguments */
      unsigned                    add_args:1;
  
      unsigned                    redirect:1;
      unsigned                    break_cycle:1;
  
      ngx_str_t                   name;
  } ngx_http_script_regex_code_t;
  
  
  typedef struct {
      ngx_http_script_code_pt     code;
  
      unsigned                    uri:1;
      unsigned                    args:1;
  
      /* add the r->args to the new arguments */
      unsigned                    add_args:1;
  
      unsigned                    redirect:1;
  } ngx_http_script_regex_end_code_t;
  
  #endif
  
  
  typedef struct {
      ngx_http_script_code_pt     code;
      uintptr_t                   conf_prefix;
  } ngx_http_script_full_name_code_t;
  
  
  typedef struct {
      ngx_http_script_code_pt     code;
      uintptr_t                   status;
      ngx_http_complex_value_t    text;
  } ngx_http_script_return_code_t;
  
  
  typedef enum {
      ngx_http_script_file_plain = 0,
      ngx_http_script_file_not_plain,
      ngx_http_script_file_dir,
      ngx_http_script_file_not_dir,
      ngx_http_script_file_exists,
      ngx_http_script_file_not_exists,
      ngx_http_script_file_exec,
      ngx_http_script_file_not_exec
  } ngx_http_script_file_op_e;
  
  
  typedef struct {
      ngx_http_script_code_pt     code;
      uintptr_t                   op;
  } ngx_http_script_file_code_t;
  
  
  typedef struct {
      ngx_http_script_code_pt     code;
      uintptr_t                   next;
      void                      **loc_conf;
  } ngx_http_script_if_code_t;
  
  
  typedef struct {
      ngx_http_script_code_pt     code;
      ngx_array_t                *lengths;
  } ngx_http_script_complex_value_code_t;
  
  
  typedef struct {
      ngx_http_script_code_pt     code;
      uintptr_t                   value;
      uintptr_t                   text_len;
      uintptr_t                   text_data;
  } ngx_http_script_value_code_t;
  
  
  void ngx_http_script_flush_complex_value(ngx_http_request_t *r,
      ngx_http_complex_value_t *val);
  ngx_int_t ngx_http_complex_value(ngx_http_request_t *r,
      ngx_http_complex_value_t *val, ngx_str_t *value);
  ngx_int_t ngx_http_compile_complex_value(ngx_http_compile_complex_value_t *ccv);
  char *ngx_http_set_complex_value_slot(ngx_conf_t *cf, ngx_command_t *cmd,
      void *conf);
  
  
  ngx_int_t ngx_http_test_predicates(ngx_http_request_t *r,
      ngx_array_t *predicates);
  char *ngx_http_set_predicate_slot(ngx_conf_t *cf, ngx_command_t *cmd,
      void *conf);
  
  ngx_uint_t ngx_http_script_variables_count(ngx_str_t *value);
  ngx_int_t ngx_http_script_compile(ngx_http_script_compile_t *sc);
  u_char *ngx_http_script_run(ngx_http_request_t *r, ngx_str_t *value,
      void *code_lengths, size_t reserved, void *code_values);
  void ngx_http_script_flush_no_cacheable_variables(ngx_http_request_t *r,
      ngx_array_t *indices);
  
  void *ngx_http_script_start_code(ngx_pool_t *pool, ngx_array_t **codes,
      size_t size);
  void *ngx_http_script_add_code(ngx_array_t *codes, size_t size, void *code);
  
  size_t ngx_http_script_copy_len_code(ngx_http_script_engine_t *e);
  void ngx_http_script_copy_code(ngx_http_script_engine_t *e);
  size_t ngx_http_script_copy_var_len_code(ngx_http_script_engine_t *e);
  void ngx_http_script_copy_var_code(ngx_http_script_engine_t *e);
  size_t ngx_http_script_copy_capture_len_code(ngx_http_script_engine_t *e);
  void ngx_http_script_copy_capture_code(ngx_http_script_engine_t *e);
  size_t ngx_http_script_mark_args_code(ngx_http_script_engine_t *e);
  void ngx_http_script_start_args_code(ngx_http_script_engine_t *e);
  #if (NGX_PCRE)
  void ngx_http_script_regex_start_code(ngx_http_script_engine_t *e);
  void ngx_http_script_regex_end_code(ngx_http_script_engine_t *e);
  #endif
  void ngx_http_script_return_code(ngx_http_script_engine_t *e);
  void ngx_http_script_break_code(ngx_http_script_engine_t *e);
  void ngx_http_script_if_code(ngx_http_script_engine_t *e);
  void ngx_http_script_equal_code(ngx_http_script_engine_t *e);
  void ngx_http_script_not_equal_code(ngx_http_script_engine_t *e);
  void ngx_http_script_file_code(ngx_http_script_engine_t *e);
  void ngx_http_script_complex_value_code(ngx_http_script_engine_t *e);
  void ngx_http_script_value_code(ngx_http_script_engine_t *e);
  void ngx_http_script_set_var_code(ngx_http_script_engine_t *e);
  void ngx_http_script_var_set_handler_code(ngx_http_script_engine_t *e);
  void ngx_http_script_var_code(ngx_http_script_engine_t *e);
  void ngx_http_script_nop_code(ngx_http_script_engine_t *e);
  
  
  #endif /* _NGX_HTTP_SCRIPT_H_INCLUDED_ */
  