Ejemplo n.º 1
0
int xfclose(XFILE *fp)
{     ENV *env = get_env_ptr();
      int ret;
      switch (fp->type)
      {  case FH_FILE:
            ret = c_fclose(fp->fh);
            break;
         case FH_ZLIB:
            ret = z_fclose(fp->fh);
            break;
         default:
            xassert(fp != fp);
      }
      fp->type = 0xF00BAD;
      if (fp->prev == NULL)
         env->file_ptr = fp->next;
      else
         fp->prev->next = fp->next;
      if (fp->next == NULL)
         ;
      else
         fp->next->prev = fp->prev;
      xfree(fp);
      return ret;
}
Ejemplo n.º 2
0
void    set_env_value(const char *key, const char *value, t_shell *shell)
{
  int   size;
  t_env *cur;
  char  *var;

  size = my_strlen(key) + my_strlen(value) + 2;
  cur = get_env_ptr(key, shell->env);
  if (cur == NULL)
  {
    var = xmalloc(size);
    concat_env_var(var, key, value);
    shell->env = add_env_var(var, shell->env);
  }
  else
  {
    if (size > my_strlen(cur->var))
    {
      var = xmalloc(size);
      concat_env_var(var, key, value);
      if (cur->var != NULL)
        free(cur->var);
      cur->var = var;
    }
    else
      concat_env_var(cur->var, key, value);
  }
}
Ejemplo n.º 3
0
XFILE *xfopen(const char *fname, const char *mode)
{     ENV *env = get_env_ptr();
      XFILE *fp;
      int type;
      void *fh;
      if (!is_gz_file(fname))
      {  type = FH_FILE;
         fh = c_fopen(fname, mode);
      }
      else
      {  type = FH_ZLIB;
         fh = z_fopen(fname, mode);
      }
      if (fh == NULL)
      {  fp = NULL;
         goto done;
      }
      fp = xmalloc(sizeof(XFILE));
      fp->type = type;
      fp->fh = fh;
      fp->prev = NULL;
      fp->next = env->file_ptr;
      if (fp->next != NULL) fp->next->prev = fp;
      env->file_ptr = fp;
done: return fp;
}
Ejemplo n.º 4
0
void glp_puts(const char *s)
{
#ifdef HAVE_ENV
      ENV *env = get_env_ptr();
      /* if terminal output is disabled, do nothing */
      if (!env->term_out)
         goto skip;
      /* pass the string to the hook routine, if defined */
      if (env->term_hook != NULL)
      {  if (env->term_hook(env->term_info, s) != 0)
            goto skip;
      }
      /* write the string on the terminal */
      fputs(s, stdout);
      fflush(stdout);
      /* write the string on the tee file, if required */
      if (env->tee_file != NULL)
      {  fputs(s, env->tee_file);
         fflush(env->tee_file);
      }
skip: return;
#else
    /* write the string on the terminal */
    if (_term_hook_)
        _term_hook_(s);
#endif
}
Ejemplo n.º 5
0
void glp_printf(const char *fmt, ...)
{
#ifdef HAVE_ENV
      ENV *env = get_env_ptr();
      va_list arg;
      /* if terminal output is disabled, do nothing */
      if (!env->term_out)
         goto skip;
      /* format the output */
      va_start(arg, fmt);
      vsprintf(env->term_buf, fmt, arg);
      /* (do not use xassert) */
      assert(strlen(env->term_buf) < TBUF_SIZE);
      va_end(arg);
      /* write the formatted output on the terminal */
      glp_puts(env->term_buf);
skip: return;
#else
    char term_buf[TBUF_SIZE];
    va_list arg;
    // if terminal output is disabled, do nothing
    if (!_term_hook_) return;
    // format the output
    va_start(arg, fmt);
    vsprintf(term_buf, fmt, arg);
    // (do not use xassert)
    assert(strlen(term_buf) < TBUF_SIZE);
    va_end(arg);
    // write the formatted output on the terminal
    glp_puts(term_buf);
#endif
}
Ejemplo n.º 6
0
void *glp_malloc(int size)
{     ENV *env = get_env_ptr();
      MEM *desc;
      int size_of_desc = align_datasize(sizeof(MEM));
      if (size < 1 || size > INT_MAX - size_of_desc)
         xerror("glp_malloc: size = %d; invalid parameter\n", size);
      size += size_of_desc;
      if (xlcmp(xlset(size),
          xlsub(env->mem_limit, env->mem_total)) > 0)
         xerror("glp_malloc: memory limit exceeded\n");
      if (env->mem_count == INT_MAX)
         xerror("glp_malloc: too many memory blocks allocated\n");
      desc = malloc(size);
      if (desc == NULL)
         xerror("glp_malloc: no memory available\n");
      memset(desc, '?', size);
      desc->flag = MEM_MAGIC;
      desc->size = size;
      desc->prev = NULL;
      desc->next = env->mem_ptr;
      if (desc->next != NULL) desc->next->prev = desc;
      env->mem_ptr = desc;
      env->mem_count++;
      if (env->mem_cpeak < env->mem_count)
         env->mem_cpeak = env->mem_count;
      env->mem_total = xladd(env->mem_total, xlset(size));
      if (xlcmp(env->mem_tpeak, env->mem_total) < 0)
         env->mem_tpeak = env->mem_total;
      return (void *)((char *)desc + size_of_desc);
}
Ejemplo n.º 7
0
void glp_free(void *ptr)
{     ENV *env = get_env_ptr();
      MEM *desc;
      int size_of_desc = align_datasize(sizeof(MEM));
      if (ptr == NULL)
         xerror("glp_free: ptr = %p; null pointer\n", ptr);
      desc = (void *)((char *)ptr - size_of_desc);
      if (desc->flag != MEM_MAGIC)
         xerror("glp_free: ptr = %p; invalid pointer\n", ptr);
      if (env->mem_count == 0 ||
          xlcmp(env->mem_total, xlset(desc->size)) < 0)
         xerror("glp_free: memory allocation error\n");
      if (desc->prev == NULL)
         env->mem_ptr = desc->next;
      else
         desc->prev->next = desc->next;
      if (desc->next == NULL)
         ;
      else
         desc->next->prev = desc->prev;
      env->mem_count--;
      env->mem_total = xlsub(env->mem_total, xlset(desc->size));
      memset(desc, '?', size_of_desc);
      free(desc);
      return;
}
Ejemplo n.º 8
0
void ufree(void *ptr)
{     ENV *env = get_env_ptr();
      MEM *desc;
      int size_of_desc = align_datasize(sizeof(MEM));
      if (ptr == NULL)
         fault("ufree: null pointer");
      desc = (void *)((char *)ptr - size_of_desc);
      if (desc->flag != MEM_FLAG)
         fault("ufree: invalid pointer");
      if (env->mem_total < desc->size || env->mem_count == 0)
         fault("ufree: memory allocation error");
      if (desc->prev == NULL)
         env->mem_ptr = desc->next;
      else
         desc->prev->next = desc->next;
      if (desc->next == NULL)
         ;
      else
         desc->next->prev = desc->prev;
      env->mem_total -= desc->size;
      env->mem_count--;
      memset(desc, '?', size_of_desc);
      free(desc);
      return;
}
Ejemplo n.º 9
0
void *umalloc(int size)
{     ENV *env = get_env_ptr();
      MEM *desc;
      int size_of_desc = align_datasize(sizeof(MEM));
      if (size < 1)
         fault("umalloc: invalid size");
      if (size > INT_MAX - size_of_desc)
         fault("umalloc: size too big");
      size += size_of_desc;
      if (size > env->mem_limit - env->mem_total)
         fault("umalloc: no memory available");
      desc = malloc(size);
      if (desc == NULL)
         fault("umalloc: malloc failed");
#if 1
      memset(desc, '?', size);
#endif
      desc->size = size;
      desc->flag = MEM_FLAG;
      desc->prev = NULL;
      desc->next = env->mem_ptr;
      if (desc->next != NULL) desc->next->prev = desc;
      env->mem_ptr = desc;
      env->mem_total += size;
      if (env->mem_tpeak < env->mem_total)
         env->mem_tpeak = env->mem_total;
      env->mem_count++;
      if (env->mem_cpeak < env->mem_count)
         env->mem_cpeak = env->mem_count;
      return (void *)((char *)desc + size_of_desc);
}
Ejemplo n.º 10
0
int glp_term_out(int flag)
{     ENV *env = get_env_ptr();
      int old = env->term_out;
      if (!(flag == GLP_ON || flag == GLP_OFF))
         xerror("glp_term_out: flag = %d; invalid value\n", flag);
      env->term_out = flag;
      return old;
}
Ejemplo n.º 11
0
void glp_mem_limit(int limit)
{     ENV *env = get_env_ptr();
      if (limit < 0)
         xerror("glp_mem_limit: limit = %d; invalid parameter\n",
            limit);
      env->mem_limit = xlmul(xlset(limit), xlset(1 << 20));
      return;
}
Ejemplo n.º 12
0
void glp_mem_usage(int *count, int *cpeak, glp_long *total,
      glp_long *tpeak)
{     ENV *env = get_env_ptr();
      if (count != NULL) *count = env->mem_count;
      if (cpeak != NULL) *cpeak = env->mem_cpeak;
      if (total != NULL) *total = env->mem_total;
      if (tpeak != NULL) *tpeak = env->mem_tpeak;
      return;
}
Ejemplo n.º 13
0
void lib_err_msg(const char *msg)
{     ENV *env = get_env_ptr();
      int len = strlen(msg);
      if (len >= IOERR_MSG_SIZE)
         len = IOERR_MSG_SIZE - 1;
      memcpy(env->ioerr_msg, msg, len);
      if (len > 0 && env->ioerr_msg[len-1] == '\n') len--;
      env->ioerr_msg[len] = '\0';
      return;
}
Ejemplo n.º 14
0
int glp_close_tee(void)
{     ENV *env = get_env_ptr();
      if (env->tee_file == NULL)
      {  /* copying terminal output was not started */
         return 1;
      }
      fclose(env->tee_file);
      env->tee_file = NULL;
      return 0;
}
Ejemplo n.º 15
0
void glp_error_hook(void (*func)(void *info), void *info)
{     ENV *env = get_env_ptr();
      if (func == NULL)
      {  env->err_hook = NULL;
         env->err_info = NULL;
      }
      else
      {  env->err_hook = func;
         env->err_info = info;
      }
      return;
}
Ejemplo n.º 16
0
void put_err_msg(const char *msg)
{     ENV *env = get_env_ptr();
      int len;
      len = strlen(msg);
      if (len >= EBUF_SIZE)
         len = EBUF_SIZE - 1;
      memcpy(env->err_buf, msg, len);
      if (len > 0 && env->err_buf[len-1] == '\n')
         len--;
      env->err_buf[len] = '\0';
      return;
}
Ejemplo n.º 17
0
void glp_term_hook(int (*func)(void *info, const char *s), void *info)
{     ENV *env = get_env_ptr();
      if (func == NULL)
      {  env->term_hook = NULL;
         env->term_info = NULL;
      }
      else
      {  env->term_hook = func;
         env->term_info = info;
      }
      return;
}
Ejemplo n.º 18
0
int glp_open_tee(const char *fname)
{     ENV *env = get_env_ptr();
      if (env->tee_file != NULL)
      {  /* copying terminal output is already active */
         return 1;
      }
      env->tee_file = fopen(fname, "w");
      if (env->tee_file == NULL)
      {  /* unable to create output file */
         return 2;
      }
      return 0;
}
Ejemplo n.º 19
0
int glp_term_out(int flag)
{
#ifdef HAVE_ENV
      ENV *env = get_env_ptr();
      int old = env->term_out;
      if (!(flag == GLP_ON || flag == GLP_OFF))
         xerror("glp_term_out: flag = %d; invalid parameter\n", flag);
      env->term_out = flag;
      return old;
#else
    return GLP_OFF;
#endif
}
Ejemplo n.º 20
0
void glp_vprintf(const char *fmt, va_list arg)
{     ENV *env = get_env_ptr();
      /* if terminal output is disabled, do nothing */
      if (!env->term_out)
         goto skip;
      /* format the output */
      vsprintf(env->term_buf, fmt, arg);
      /* (do not use xassert) */
      assert(strlen(env->term_buf) < TBUF_SIZE);
      /* write the formatted output on the terminal */
      glp_puts(env->term_buf);
skip: return;
}
Ejemplo n.º 21
0
static void error(const char *fmt, ...)
{     ENV *env = get_env_ptr();
      va_list arg;
      env->term_out = GLP_ON;
      va_start(arg, fmt);
      xvprintf(fmt, arg);
      va_end(arg);
      xprintf("Error detected in file %s at line %d\n", env->err_file,
         env->err_line);
      if (env->err_hook != NULL)
         env->err_hook(env->err_info);
      abort();
      exit(EXIT_FAILURE);
      /* no return */
}
Ejemplo n.º 22
0
int xfprintf(XFILE *file, const char *fmt, ...)
{     ENV *env = get_env_ptr();
      int cnt, j;
      va_list arg;
      va_start(arg, fmt);
      cnt = vsprintf(env->term_buf, fmt, arg);
      va_end(arg);
      for (j = 0; j < cnt; j++)
      {  if (xfputc(env->term_buf[j], file) < 0)
         {  cnt = -1;
            break;
         }
      }
      return cnt;
}
Ejemplo n.º 23
0
void glp_vprintf(const char *fmt, va_list arg)
{     ENV *env = get_env_ptr();
      /* if terminal output is disabled, do nothing */
      /* if (!env->term_out) goto skip; */
      /* /\* format the output *\/ */
      /* vsprintf(env->term_buf, fmt, arg); */
      /* /\* pass the output to the user-defined routine *\/ */
      /* if (env->term_hook != NULL) */
      /* {  if (env->term_hook(env->term_info, env->term_buf) != 0) */
      /*       goto skip; */
      /* } */
      /* /\* send the output to the terminal *\/ */
      /* fputs(env->term_buf, stdout); */
      /* fflush(stdout); */
      /* /\* copy the output to the text file *\/ */
      /* if (env->tee_file != NULL) */
      /* {  fputs(env->term_buf, env->tee_file); */
      /*    fflush(env->tee_file); */
      /* } */
skip: return;
}
Ejemplo n.º 24
0
static int preprocess_and_solve_mip(glp_prob *P, const glp_iocp *parm)
{     /* solve MIP using the preprocessor */
      ENV *env = get_env_ptr();
      int term_out = env->term_out;
      NPP *npp;
      glp_prob *mip = NULL;
      glp_bfcp bfcp;
      glp_smcp smcp;
      int ret;
      if (parm->msg_lev >= GLP_MSG_ALL)
         xprintf("Preprocessing...\n");
      /* create preprocessor workspace */
      npp = npp_create_wksp();
      /* load original problem into the preprocessor workspace */
      npp_load_prob(npp, P, GLP_OFF, GLP_MIP, GLP_OFF);
      /* process MIP prior to applying the branch-and-bound method */
      if (!term_out || parm->msg_lev < GLP_MSG_ALL)
         env->term_out = GLP_OFF;
      else
         env->term_out = GLP_ON;
      ret = npp_integer(npp, parm);
      env->term_out = term_out;
      if (ret == 0)
         ;
      else if (ret == GLP_ENOPFS)
      {  if (parm->msg_lev >= GLP_MSG_ALL)
            xprintf("PROBLEM HAS NO PRIMAL FEASIBLE SOLUTION\n");
      }
      else if (ret == GLP_ENODFS)
      {  if (parm->msg_lev >= GLP_MSG_ALL)
            xprintf("LP RELAXATION HAS NO DUAL FEASIBLE SOLUTION\n");
      }
      else
         xassert(ret != ret);
      if (ret != 0) goto done;
      /* build transformed MIP */
      mip = glp_create_prob();
      npp_build_prob(npp, mip);
      /* if the transformed MIP is empty, it has empty solution, which
         is optimal */
      if (mip->m == 0 && mip->n == 0)
      {  mip->mip_stat = GLP_OPT;
         mip->mip_obj = mip->c0;
         if (parm->msg_lev >= GLP_MSG_ALL)
         {  xprintf("Objective value = %17.9e\n", mip->mip_obj);
            xprintf("INTEGER OPTIMAL SOLUTION FOUND BY MIP PREPROCESSOR"
               "\n");
         }
         goto post;
      }
      /* display some statistics */
      if (parm->msg_lev >= GLP_MSG_ALL)
      {  int ni = glp_get_num_int(mip);
         int nb = glp_get_num_bin(mip);
         char s[50];
         xprintf("%d row%s, %d column%s, %d non-zero%s\n",
            mip->m, mip->m == 1 ? "" : "s", mip->n, mip->n == 1 ? "" :
            "s", mip->nnz, mip->nnz == 1 ? "" : "s");
         if (nb == 0)
            strcpy(s, "none of");
         else if (ni == 1 && nb == 1)
            strcpy(s, "");
         else if (nb == 1)
            strcpy(s, "one of");
         else if (nb == ni)
            strcpy(s, "all of");
         else
            sprintf(s, "%d of", nb);
         xprintf("%d integer variable%s, %s which %s binary\n",
            ni, ni == 1 ? "" : "s", s, nb == 1 ? "is" : "are");
      }
      /* inherit basis factorization control parameters */
      glp_get_bfcp(P, &bfcp);
      glp_set_bfcp(mip, &bfcp);
      /* scale the transformed problem */
      if (!term_out || parm->msg_lev < GLP_MSG_ALL)
         env->term_out = GLP_OFF;
      else
         env->term_out = GLP_ON;
      glp_scale_prob(mip,
         GLP_SF_GM | GLP_SF_EQ | GLP_SF_2N | GLP_SF_SKIP);
      env->term_out = term_out;
      /* build advanced initial basis */
      if (!term_out || parm->msg_lev < GLP_MSG_ALL)
         env->term_out = GLP_OFF;
      else
         env->term_out = GLP_ON;
      glp_adv_basis(mip, 0);
      env->term_out = term_out;
      /* solve initial LP relaxation */
      if (parm->msg_lev >= GLP_MSG_ALL)
         xprintf("Solving LP relaxation...\n");
      glp_init_smcp(&smcp);
      smcp.msg_lev = parm->msg_lev;
      mip->it_cnt = P->it_cnt;
      ret = glp_simplex(mip, &smcp);
      P->it_cnt = mip->it_cnt;
      if (ret != 0)
      {  if (parm->msg_lev >= GLP_MSG_ERR)
            xprintf("glp_intopt: cannot solve LP relaxation\n");
         ret = GLP_EFAIL;
         goto done;
      }
      /* check status of the basic solution */
      ret = glp_get_status(mip);
      if (ret == GLP_OPT)
         ret = 0;
      else if (ret == GLP_NOFEAS)
         ret = GLP_ENOPFS;
      else if (ret == GLP_UNBND)
         ret = GLP_ENODFS;
      else
         xassert(ret != ret);
      if (ret != 0) goto done;
      /* solve the transformed MIP */
      mip->it_cnt = P->it_cnt;
#if 0 /* 11/VII-2013 */
      ret = solve_mip(mip, parm);
#else
      if (parm->use_sol)
      {  mip->mip_stat = P->mip_stat;
         mip->mip_obj = P->mip_obj;
      }
      ret = solve_mip(mip, parm, P, npp);
#endif
      P->it_cnt = mip->it_cnt;
      /* only integer feasible solution can be postprocessed */
      if (!(mip->mip_stat == GLP_OPT || mip->mip_stat == GLP_FEAS))
      {  P->mip_stat = mip->mip_stat;
         goto done;
      }
      /* postprocess solution from the transformed MIP */
post: npp_postprocess(npp, mip);
      /* the transformed MIP is no longer needed */
      glp_delete_prob(mip), mip = NULL;
      /* store solution to the original problem */
      npp_unload_sol(npp, P);
done: /* delete the transformed MIP, if it exists */
      if (mip != NULL) glp_delete_prob(mip);
      /* delete preprocessor workspace */
      npp_delete_wksp(npp);
      return ret;
}
Ejemplo n.º 25
0
_glp_error glp_error_(const char *file, int line)
{     ENV *env = get_env_ptr();
      env->err_file = file;
      env->err_line = line;
      return error;
}
Ejemplo n.º 26
0
const char *get_err_msg(void)
{     ENV *env = get_env_ptr();
      return env->err_buf;
}
Ejemplo n.º 27
0
static int preprocess_and_solve_lp(glp_prob *P, const glp_smcp *parm)
{     /* solve LP using the preprocessor */
      NPP *npp;
      glp_prob *lp = NULL;
      glp_bfcp bfcp;
      int ret;
      if (parm->msg_lev >= GLP_MSG_ALL)
         xprintf("Preprocessing...\n");
      /* create preprocessor workspace */
      npp = npp_create_wksp();
      /* load original problem into the preprocessor workspace */
      npp_load_prob(npp, P, GLP_OFF, GLP_SOL, GLP_OFF);
      /* process LP prior to applying primal/dual simplex method */
      ret = npp_simplex(npp, parm);
      if (ret == 0)
         ;
      else if (ret == GLP_ENOPFS)
      {  if (parm->msg_lev >= GLP_MSG_ALL)
            xprintf("PROBLEM HAS NO PRIMAL FEASIBLE SOLUTION\n");
      }
      else if (ret == GLP_ENODFS)
      {  if (parm->msg_lev >= GLP_MSG_ALL)
            xprintf("PROBLEM HAS NO DUAL FEASIBLE SOLUTION\n");
      }
      else
         xassert(ret != ret);
      if (ret != 0) goto done;
      /* build transformed LP */
      lp = glp_create_prob();
      npp_build_prob(npp, lp);
      /* if the transformed LP is empty, it has empty solution, which
         is optimal */
      if (lp->m == 0 && lp->n == 0)
      {  lp->pbs_stat = lp->dbs_stat = GLP_FEAS;
         lp->obj_val = lp->c0;
         if (parm->msg_lev >= GLP_MSG_ON && parm->out_dly == 0)
         {  xprintf("~%6d: obj = %17.9e  infeas = %10.3e\n", P->it_cnt,
               lp->obj_val, 0.0);
         }
         if (parm->msg_lev >= GLP_MSG_ALL)
            xprintf("OPTIMAL SOLUTION FOUND BY LP PREPROCESSOR\n");
         goto post;
      }
      if (parm->msg_lev >= GLP_MSG_ALL)
      {  xprintf("%d row%s, %d column%s, %d non-zero%s\n",
            lp->m, lp->m == 1 ? "" : "s", lp->n, lp->n == 1 ? "" : "s",
            lp->nnz, lp->nnz == 1 ? "" : "s");
      }
      /* inherit basis factorization control parameters */
      glp_get_bfcp(P, &bfcp);
      glp_set_bfcp(lp, &bfcp);
      /* scale the transformed problem */
      {  ENV *env = get_env_ptr();
         int term_out = env->term_out;
         if (!term_out || parm->msg_lev < GLP_MSG_ALL)
            env->term_out = GLP_OFF;
         else
            env->term_out = GLP_ON;
         glp_scale_prob(lp, GLP_SF_AUTO);
         env->term_out = term_out;
      }
      /* build advanced initial basis */
      {  ENV *env = get_env_ptr();
         int term_out = env->term_out;
         if (!term_out || parm->msg_lev < GLP_MSG_ALL)
            env->term_out = GLP_OFF;
         else
            env->term_out = GLP_ON;
         glp_adv_basis(lp, 0);
         env->term_out = term_out;
      }
      /* solve the transformed LP */
      lp->it_cnt = P->it_cnt;
      ret = solve_lp(lp, parm);
      P->it_cnt = lp->it_cnt;
      /* only optimal solution can be postprocessed */
      if (!(ret == 0 && lp->pbs_stat == GLP_FEAS && lp->dbs_stat ==
            GLP_FEAS))
      {  if (parm->msg_lev >= GLP_MSG_ERR)
            xprintf("glp_simplex: unable to recover undefined or non-op"
               "timal solution\n");
         if (ret == 0)
         {  if (lp->pbs_stat == GLP_NOFEAS)
               ret = GLP_ENOPFS;
            else if (lp->dbs_stat == GLP_NOFEAS)
               ret = GLP_ENODFS;
            else
               xassert(lp != lp);
         }
         goto done;
      }
post: /* postprocess solution from the transformed LP */
      npp_postprocess(npp, lp);
      /* the transformed LP is no longer needed */
      glp_delete_prob(lp), lp = NULL;
      /* store solution to the original problem */
      npp_unload_sol(npp, P);
      /* the original LP has been successfully solved */
      ret = 0;
done: /* delete the transformed LP, if it exists */
      if (lp != NULL) glp_delete_prob(lp);
      /* delete preprocessor workspace */
      npp_delete_wksp(npp);
      return ret;
}
Ejemplo n.º 28
0
const char *xerrmsg(void)
{     ENV *env = get_env_ptr();
      return env->ioerr_msg;
}
Ejemplo n.º 29
0
const char *glp_version(void)
{     ENV *env = get_env_ptr();
      return env->version;
}