Extended maintenance of Ruby 1.9.3 ended on February 23, 2015. Read more

In Files

  • tk/tkutil/tkutil.c

Class/Module Index [+]

Quicksearch

TkUtil::CallbackSubst


Public Class Methods

_define_attribute_aliases(p1) click to toggle source
 
               static VALUE
cbsubst_def_attr_aliases(self, tbl)
    VALUE self;
    VALUE tbl;
{
    struct cbsubst_info *inf;

    if (TYPE(tbl) != T_HASH) {
        rb_raise(rb_eArgError, "expected a Hash");
    }

    Data_Get_Struct(rb_const_get(self, ID_SUBST_INFO),
                    struct cbsubst_info, inf);

    rb_hash_foreach(tbl, each_attr_def, self);

    return rb_funcall(inf->aliases, rb_intern("update"), 1, tbl);
}
            
_get_all_subst_keys() click to toggle source
 
               static VALUE
cbsubst_get_all_subst_keys(self)
    VALUE self;
{
    struct cbsubst_info *inf;
    char *buf, *ptr;
    char *keys_buf, *keys_ptr;
    int idx, len;
    volatile VALUE ret;

    Data_Get_Struct(rb_const_get(self, ID_SUBST_INFO),
                    struct cbsubst_info, inf);

    ptr = buf = ALLOC_N(char, inf->full_subst_length + 1);
    keys_ptr = keys_buf = ALLOC_N(char, CBSUBST_TBL_MAX + 1);

    for(idx = 0; idx < CBSUBST_TBL_MAX; idx++) {
      if (inf->ivar[idx] == (ID) 0) continue;

      *(keys_ptr++) = (unsigned char)idx;

      *(ptr++) = '%';

      if (len = inf->keylen[idx]) {
        /* longname */
        strncpy(ptr, inf->key[idx], len);
        ptr += len;
      } else {
        /* single char */
        *(ptr++) = (unsigned char)idx;
      }

      *(ptr++) = ' ';
    }

    *ptr = '\0';
    *keys_ptr = '\0';

    ret = rb_ary_new3(2, rb_str_new2(keys_buf), rb_str_new2(buf));

    xfree(buf);
    xfree(keys_buf);

    return ret;
}
            
_get_extra_args_tbl() click to toggle source
 
               static VALUE
cbsubst_get_extra_args_tbl(self)
    VALUE self;
{
  return rb_ary_new();
}
            
_get_subst_key(p1) click to toggle source
 
               static VALUE
cbsubst_get_subst_key(self, str)
    VALUE self;
    VALUE str;
{
    struct cbsubst_info *inf;
    volatile VALUE list;
    volatile VALUE ret;
    VALUE keyval;
    int i, len, keylen, idx;
    char *buf, *ptr, *key;

    list = rb_funcall(cTclTkLib, ID_split_tklist, 1, str);
    len = RARRAY_LEN(list);

    Data_Get_Struct(rb_const_get(self, ID_SUBST_INFO),
                    struct cbsubst_info, inf);

    ptr = buf = ALLOC_N(char, inf->full_subst_length + len + 1);

    for(i = 0; i < len; i++) {
      keyval = RARRAY_PTR(list)[i];
      key = RSTRING_PTR(keyval);
      if (*key == '%') {
        if (*(key + 2) == '\0') {
          /* single char */
          *(ptr++) = *(key + 1);
        } else {
          /* search longname-key */
          keylen = RSTRING_LEN(keyval) - 1;
          for(idx = 0; idx < CBSUBST_TBL_MAX; idx++) {
            if (inf->keylen[idx] != keylen) continue;
            if ((unsigned char)inf->key[idx][0] != (unsigned char)*(key + 1)) continue;
            if (strncmp(inf->key[idx], key + 1, keylen)) continue;
            break;
          }
          if (idx < CBSUBST_TBL_MAX) {
            *(ptr++) = (unsigned char)idx;
          } else {
            *(ptr++) = ' ';
          }
        }
      } else {
        *(ptr++) = ' ';
      }
    }
    *ptr = '\0';

    ret = rb_str_new2(buf);
    xfree(buf);
    return ret;
}
            
_setup_subst_table(p1, p2, p3 = v3) click to toggle source
 
               static VALUE
cbsubst_table_setup(argc, argv, self)
     int   argc;
     VALUE *argv;
     VALUE self;
{
  volatile VALUE cbsubst_obj;
  volatile VALUE key_inf;
  volatile VALUE longkey_inf;
  volatile VALUE proc_inf;
  VALUE inf;
  ID id;
  struct cbsubst_info *subst_inf;
  int idx, len;
  unsigned char chr;

  /* accept (key_inf, proc_inf) or (key_inf, longkey_inf, procinf) */
  if (rb_scan_args(argc, argv, "21", &key_inf, &longkey_inf, &proc_inf) == 2) {
    proc_inf = longkey_inf;
    longkey_inf = rb_ary_new();
  }

  /* check the number of longkeys */
  if (RARRAY_LEN(longkey_inf) > 125 /* from 0x80 to 0xFD */) {
    rb_raise(rb_eArgError, "too many longname-key definitions");
  }

  /* init */
  cbsubst_obj = allocate_cbsubst_info(&subst_inf);

  /*
   * keys : array of [subst, type, ivar]
   *         subst ==> char code or string
   *         type  ==> char code or string
   *         ivar  ==> symbol
   */
  len = RARRAY_LEN(key_inf);
  for(idx = 0; idx < len; idx++) {
    inf = RARRAY_PTR(key_inf)[idx];
    if (TYPE(inf) != T_ARRAY) continue;

    if (TYPE(RARRAY_PTR(inf)[0]) == T_STRING) {
      chr = *(RSTRING_PTR(RARRAY_PTR(inf)[0]));
    } else {
      chr = NUM2CHR(RARRAY_PTR(inf)[0]);
    }
    if (TYPE(RARRAY_PTR(inf)[1]) == T_STRING) {
      subst_inf->type[chr] = *(RSTRING_PTR(RARRAY_PTR(inf)[1]));
    } else {
      subst_inf->type[chr] = NUM2CHR(RARRAY_PTR(inf)[1]);
    }

    subst_inf->full_subst_length += 3;

    id = SYM2ID(RARRAY_PTR(inf)[2]);
    subst_inf->ivar[chr] = rb_intern(RSTRING_PTR(rb_str_cat2(rb_str_new2("@"), rb_id2name(id))));

    rb_attr(self, id, 1, 0, Qtrue);
  }


  /*
   * longkeys : array of [name, type, ivar]
   *         name ==> longname key string
   *         type ==> char code or string
   *         ivar ==> symbol
   */
  len = RARRAY_LEN(longkey_inf);
  for(idx = 0; idx < len; idx++) {
    inf = RARRAY_PTR(longkey_inf)[idx];
    if (TYPE(inf) != T_ARRAY) continue;

    chr = (unsigned char)(0x80 + idx);
    subst_inf->keylen[chr] = RSTRING_LEN(RARRAY_PTR(inf)[0]);
#if HAVE_STRNDUP
    subst_inf->key[chr] = strndup(RSTRING_PTR(RARRAY_PTR(inf)[0]),
                                  RSTRING_LEN(RARRAY_PTR(inf)[0]));
#else
    subst_inf->key[chr] = malloc(RSTRING_LEN(RARRAY_PTR(inf)[0]) + 1);
    if (subst_inf->key[chr]) {
      strncpy(subst_inf->key[chr], RSTRING_PTR(RARRAY_PTR(inf)[0]),
              RSTRING_LEN(RARRAY_PTR(inf)[0]) + 1);
      subst_inf->key[chr][RSTRING_LEN(RARRAY_PTR(inf)[0])] = '\0';
    }
#endif
    if (TYPE(RARRAY_PTR(inf)[1]) == T_STRING) {
      subst_inf->type[chr] = *(RSTRING_PTR(RARRAY_PTR(inf)[1]));
    } else {
      subst_inf->type[chr] = NUM2CHR(RARRAY_PTR(inf)[1]);
    }

    subst_inf->full_subst_length += (subst_inf->keylen[chr] + 2);

    id = SYM2ID(RARRAY_PTR(inf)[2]);
    subst_inf->ivar[chr] = rb_intern(RSTRING_PTR(rb_str_cat2(rb_str_new2("@"), rb_id2name(id))));

    rb_attr(self, id, 1, 0, Qtrue);
  }

  /*
   * procs : array of [type, proc]
   *         type  ==> char code or string
   *         proc  ==> proc/method/obj (must respond to 'call')
   */
  len = RARRAY_LEN(proc_inf);
  for(idx = 0; idx < len; idx++) {
    inf = RARRAY_PTR(proc_inf)[idx];
    if (TYPE(inf) != T_ARRAY) continue;
    rb_hash_aset(subst_inf->proc,
                 ((TYPE(RARRAY_PTR(inf)[0]) == T_STRING)?
                  INT2FIX(*(RSTRING_PTR(RARRAY_PTR(inf)[0]))) :
                  RARRAY_PTR(inf)[0]),
                 RARRAY_PTR(inf)[1]);
  }

  rb_const_set(self, ID_SUBST_INFO, cbsubst_obj);

  return self;
}
            
_sym2subst(p1) click to toggle source
 
               static VALUE
cbsubst_sym_to_subst(self, sym)
    VALUE self;
    VALUE sym;
{
    struct cbsubst_info *inf;
    const char *str;
    char *buf, *ptr;
    int idx, len;
    ID id;
    volatile VALUE ret;

    if (TYPE(sym) != T_SYMBOL) return sym;

    Data_Get_Struct(rb_const_get(self, ID_SUBST_INFO),
                    struct cbsubst_info, inf);

    if (!NIL_P(ret = rb_hash_aref(inf->aliases, sym))) {
      str = rb_id2name(SYM2ID(ret));
    } else {
      str = rb_id2name(SYM2ID(sym));
    }

    id = rb_intern(RSTRING_PTR(rb_str_cat2(rb_str_new2("@"), str)));

    for(idx = 0; idx < CBSUBST_TBL_MAX; idx++) {
      if (inf->ivar[idx] == id) break;
    }
    if (idx >= CBSUBST_TBL_MAX)  return sym;

    ptr = buf = ALLOC_N(char, inf->full_subst_length + 1);

    *(ptr++) = '%';

    if (len = inf->keylen[idx]) {
      /* longname */
      strncpy(ptr, inf->key[idx], len);
      ptr += len;
    } else {
      /* single char */
      *(ptr++) = (unsigned char)idx;
    }

    *(ptr++) = ' ';
    *(ptr++) = '\0';

    ret = rb_str_new2(buf);

    xfree(buf);

    return ret;
}
            
inspect() click to toggle source
 
               static VALUE
cbsubst_inspect(self)
    VALUE self;
{
    return rb_str_new2("CallbackSubst");
}
            
new(*args) click to toggle source
 
               static VALUE
cbsubst_initialize(argc, argv, self)
    int   argc;
    VALUE *argv;
    VALUE self;
{
    struct cbsubst_info *inf;
    int idx, iv_idx;

    Data_Get_Struct(rb_const_get(rb_obj_class(self), ID_SUBST_INFO),
                    struct cbsubst_info, inf);

   idx = 0;
    for(iv_idx = 0; iv_idx < CBSUBST_TBL_MAX; iv_idx++) {
      if ( inf->ivar[iv_idx] == (ID) 0 ) continue;
      rb_ivar_set(self, inf->ivar[iv_idx], argv[idx++]);
      if (idx >= argc) break;
    }

    return self;
}
            
ret_val(p1) click to toggle source
 
               static VALUE
cbsubst_ret_val(self, val)
    VALUE self;
    VALUE val;
{
    /* This method may be overwritten on some sub-classes.                  */
    /* This method is used for converting from ruby's callback-return-value */
    /* to tcl's value (e.g. validation procedure of entry widget).          */
    return val;
}
            
scan_args(p1, p2) click to toggle source
 
               static VALUE
cbsubst_scan_args(self, arg_key, val_ary)
    VALUE self;
    VALUE arg_key;
    VALUE val_ary;
{
    struct cbsubst_info *inf;
    int idx;
    unsigned char *keyptr = (unsigned char*)RSTRING_PTR(arg_key);
    int keylen = RSTRING_LEN(arg_key);
    int vallen = RARRAY_LEN(val_ary);
    unsigned char type_chr;
    volatile VALUE dst = rb_ary_new2(vallen);
    volatile VALUE proc;
    int thr_crit_bup;
    VALUE old_gc;

    thr_crit_bup = rb_thread_critical;
    rb_thread_critical = Qtrue;

    old_gc = rb_gc_disable();

    Data_Get_Struct(rb_const_get(self, ID_SUBST_INFO),
                    struct cbsubst_info, inf);

    for(idx = 0; idx < vallen; idx++) {
      if (idx >= keylen) {
        proc = Qnil;
      } else if (*(keyptr + idx) == ' ') {
        proc = Qnil;
      } else {
        if (type_chr = inf->type[*(keyptr + idx)]) {
          proc = rb_hash_aref(inf->proc, INT2FIX((int)type_chr));
        } else {
          proc = Qnil;
        }
      }

      if (NIL_P(proc)) {
        rb_ary_push(dst, RARRAY_PTR(val_ary)[idx]);
      } else {
        rb_ary_push(dst, rb_funcall(proc, ID_call, 1,
                                    RARRAY_PTR(val_ary)[idx]));
      }
    }

    if (old_gc == Qfalse) rb_gc_enable();
    rb_thread_critical = thr_crit_bup;

    return dst;
}
            
subst_arg(*args) click to toggle source
 
               static VALUE
cbsubst_get_subst_arg(argc, argv, self)
    int   argc;
    VALUE *argv;
    VALUE self;
{
    struct cbsubst_info *inf;
    const char *str;
    char *buf, *ptr;
    int i, idx, len;
    ID id;
    volatile VALUE arg_sym, ret;

    Data_Get_Struct(rb_const_get(self, ID_SUBST_INFO),
                    struct cbsubst_info, inf);

    ptr = buf = ALLOC_N(char, inf->full_subst_length + 1);

    for(i = 0; i < argc; i++) {
        switch(TYPE(argv[i])) {
        case T_STRING:
            str = RSTRING_PTR(argv[i]);
            arg_sym = ID2SYM(rb_intern(str));
            break;
        case T_SYMBOL:
            arg_sym = argv[i];
            str = rb_id2name(SYM2ID(arg_sym));
            break;
        default:
            rb_raise(rb_eArgError, "arg #%d is not a String or a Symbol", i);
        }

        if (!NIL_P(ret = rb_hash_aref(inf->aliases, arg_sym))) {
            str = rb_id2name(SYM2ID(ret));
        }

        id = rb_intern(RSTRING_PTR(rb_str_cat2(rb_str_new2("@"), str)));

        for(idx = 0; idx < CBSUBST_TBL_MAX; idx++) {
          if (inf->ivar[idx] == id) break;
        }
        if (idx >= CBSUBST_TBL_MAX) {
            rb_raise(rb_eArgError, "cannot find attribute :%s", str);
        }

        *(ptr++) = '%';

        if (len = inf->keylen[idx]) {
          /* longname */
          strncpy(ptr, inf->key[idx], len);
          ptr += len;
        } else {
          /* single char */
          *(ptr++) = (unsigned char)idx;
        }

        *(ptr++) = ' ';
    }

    *ptr = '\0';

    ret = rb_str_new2(buf);

    xfree(buf);

    return ret;
}
            

Commenting is here to help enhance the documentation. For example, code samples, or clarification of the documentation.

If you have questions about Ruby or the documentation, please post to one of the Ruby mailing lists. You will get better, faster, help that way.

If you wish to post a correction of the docs, please do so, but also file bug report so that it can be corrected for the next release. Thank you.

If you want to help improve the Ruby documentation, please visit Documenting-ruby.org.