From 4c9a6047ef908344caa7aa67df9edefdf0a42d5a Mon Sep 17 00:00:00 2001 From: matz Date: Tue, 21 Jul 1998 09:18:05 +0000 Subject: [PATCH] st.c(rehash) git-svn-id: http://svn.ruby-lang.org/repos/ruby/branches/v1_1r@275 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 4 + lib/tk.rb | 313 ++++++++++++++++++++++++++++++++++++++++++++---- lib/tkcanvas.rb | 4 +- lib/tkfont.rb | 6 + lib/tktext.rb | 10 +- st.c | 15 ++- 6 files changed, 314 insertions(+), 38 deletions(-) diff --git a/ChangeLog b/ChangeLog index b900c524b4..e30ce0c03a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +Tue Jul 21 13:19:30 1998 Yukihiro Matsumoto + + * st.c (rehash): GC during rehash caused SEGV. + Tue Jul 21 01:25:10 1998 Yukihiro Matsumoto * sprintf.c (f_sprintf): integer formatter totally re-written. diff --git a/lib/tk.rb b/lib/tk.rb index dc52675d59..7c04798222 100644 --- a/lib/tk.rb +++ b/lib/tk.rb @@ -25,6 +25,28 @@ def error_at end private :error_at + def _genobj_for_tkwidget(path) + return TkRoot.new if path == '.' + + begin + tk_class = TkCore::INTERP._invoke('winfo', 'class', path) + rescue + return path + end + + ruby_class = TkClassBind::WidgetClassNameTBL[tk_class] + gen_class_name = ruby_class.name + 'GeneratedOnTk' + unless Object.const_defined? gen_class_name + eval "class #{gen_class_name}<#{ruby_class.name} + def initialize(path) + @path=path + Tk_WINDOWS[@path] = self + end + end" + end + eval "#{gen_class_name}.new('#{path}')" + end + def tk_tcl2ruby(val) if val =~ /^rb_out (c\d+)/ return Tk_CMDTBL[$1] @@ -38,7 +60,7 @@ def tk_tcl2ruby(val) when /^-?\d+$/ val.to_i when /^\./ - Tk_WINDOWS[val] + Tk_WINDOWS[val] ? Tk_WINDOWS[val] : _genobj_for_tkwidget(val) when / / val.split.collect{|elt| tk_tcl2ruby(elt) @@ -74,7 +96,33 @@ def tk_split_list(str) list += tk_split_list(str[i+1..-1]) list end - private :tk_tcl2ruby, :tk_split_list + + def tk_split_simplelist(str) + return [] if str == "" + idx = str.index('{') + return str.split unless idx + + list = str[0,idx].split + str = str[idx+1..-1] + i = -1 + brace = 1 + str.each_byte {|c| + i += 1 + brace += 1 if c == ?{ + brace -= 1 if c == ?} + break if brace == 0 + } + if i == 0 + list.push '' + elsif str[0, i] == ' ' + list.push ' ' + else + list.push str[0..i-1] + end + list += tk_split_simplelist(str[i+1..-1]) + list + end + private :tk_tcl2ruby, :tk_split_list, :tk_split_simplelist def hash_kv(keys) conf = [] @@ -425,6 +473,10 @@ def rb_appsend_displayof(interp, win, async, *args) appsend_displayof(interp, win, async, *args) end + def info(*args) + tk_call('info', *args) + end + def mainloop TclTkLib.mainloop end @@ -661,7 +713,7 @@ def id def value begin - INTERP._eval(format('global %s; set %s', @id, @id)) + tk_tcl2ruby(INTERP._eval(format('global %s; set %s', @id, @id))) rescue if INTERP._eval(format('global %s; array exists %s', @id, @id)) != "1" raise @@ -1029,7 +1081,7 @@ def winfo_classname TkWinfo.classname self end def TkWinfo.containing(rootX, rootY) - path = tk_call('winfo', 'class', window.path) + path = tk_call('winfo', 'containing', rootX, rootY) window(path) end def winfo_containing(x, y) @@ -1073,22 +1125,10 @@ def winfo_id end def TkWinfo.interps(window=nil) if window - tk_split_list(tk_call('winfo', '-displayof', window.path, - 'interps')).collect{|ip| - if ip.kind_of? Array - ip.flatten.join(' ') - else - ip - end - } + tk_split_simplelist(tk_call('winfo', '-displayof', window.path, + 'interps')) else - tk_split_list(tk_call('winfo', 'interps')).collect{|ip| - if ip.kind_of? Array - ip.flatten.join(' ') - else - ip - end - } + tk_split_simplelist(tk_call('winfo', 'interps')) end end def winfo_interps @@ -1100,6 +1140,12 @@ def TkWinfo.mapped?(window) def winfo_mapped? TkWinfo.mapped? self end + def TkWinfo.appname(window) + bool(tk_call('winfo', 'name', window.path)) + end + def winfo_appname + TkWinfo.appname self + end def TkWinfo.parent(window) window(tk_call('winfo', 'parent', window.path)) end @@ -1803,16 +1849,51 @@ def self.to_eval end def initialize(parent=nil, screen=nil, classname=nil, keys=nil) - @screen = screen if screen - @classname = classname if classname + if screen.kind_of? Hash + keys = screen.dup + else + @screen = screen + end + @classname = classname + if keys.kind_of? Hash + keys = keys.dup + if keys['classname'] + @classname = keys['classname'] + keys['classname'] = nil + end + if keys['colormap'] + @colormap = keys['colormap'] + keys['colormap'] = nil + end + if keys['container'] + @classname = keys['container'] + keys['classname'] = nil + end + if keys['screen'] + @screen = keys['screen'] + keys['screen'] = nil + end + if keys['use'] + @use = keys['use'] + keys['use'] = nil + end + if keys['visual'] + @screen = keys['visual'] + keys['visual'] = nil + end + end super(parent, keys) end def create_self s = [] - s.push "-screen #@screen" if @screen - s.push "-class #@classname" if @classname - tk_call 'toplevel', path, *s + s.push << "-class" << @classname if @classname + s.push << "-colormap" << @colormap if @colormap + s.push << "-container" << @container if @container + s.push << "-screen" << @screen if @screen + s.push << "-use" << @use if @use + s.push << "-visual" << @visual if @visual + tk_call 'toplevel', @path, *s end def specific_class @@ -1826,8 +1907,37 @@ class TkFrameval}) + else + tk_call 'entryconfigure', index, "-#{key}", val + end + end + end + + def entryconfiginfo(index, key=nil) + if key + conf = tk_split_list(tk_send('entryconfigure',index,"-#{key}")) + conf[0] = conf[0][1..-1] + conf + else + tk_split_list(tk_send('entryconfigure', index)).collect{|conf| + conf[0] = conf[0][1..-1] + conf + } + end + end end class TkMenubuttontype->compare)(x, y) == 0) #define do_hash(key, table) (*(table)->type->hash)((key), (table)->num_bins) +#define do_hash2(key, table, bins) (*(table)->type->hash)((key), bins) st_table* st_init_table_with_size(type, size) @@ -222,29 +223,31 @@ rehash(table) register st_table *table; { register st_table_entry *ptr, *next, **old_bins = table->bins; - int i, old_num_bins = table->num_bins, hash_val; + int i, old_num_bins = table->num_bins, new_num_bins, hash_val; - table->num_bins = 1.79*old_num_bins; + new_num_bins = 1.79*old_num_bins; - if (table->num_bins%2 == 0) { - table->num_bins += 1; + if (new_num_bins%2 == 0) { + new_num_bins += 1; } + table->num_bins = 0; table->num_entries = 0; table->bins = (st_table_entry **) - Calloc((unsigned)table->num_bins, sizeof(st_table_entry*)); + Calloc((unsigned)new_num_bins, sizeof(st_table_entry*)); for(i = 0; i < old_num_bins ; i++) { ptr = old_bins[i]; while (ptr != nil(st_table_entry)) { next = ptr->next; - hash_val = do_hash(ptr->key, table); + hash_val = do_hash2(ptr->key, table, new_num_bins); ptr->next = table->bins[hash_val]; table->bins[hash_val] = ptr; table->num_entries++; ptr = next; } } + table->num_bins = new_num_bins; free((char*)old_bins); }