diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 1998-07-21 09:18:05 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 1998-07-21 09:18:05 +0000 |
commit | 334b2c9f855ca8e4a36d34c6e600f5203ec017a5 (patch) | |
tree | 81a3e8889b938217aa68284686b38313241c3f9e | |
parent | 043ec1f18d6e99b73eec029142185019f383f478 (diff) |
st.c(rehash)
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/v1_1r@275 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | lib/tk.rb | 313 | ||||
-rw-r--r-- | lib/tkcanvas.rb | 4 | ||||
-rw-r--r-- | lib/tkfont.rb | 6 | ||||
-rw-r--r-- | lib/tktext.rb | 10 | ||||
-rw-r--r-- | st.c | 15 |
6 files changed, 314 insertions, 38 deletions
@@ -1,3 +1,7 @@ +Tue Jul 21 13:19:30 1998 Yukihiro Matsumoto <matz@netlab.co.jp> + + * st.c (rehash): GC during rehash caused SEGV. + Tue Jul 21 01:25:10 1998 Yukihiro Matsumoto <matz@netlab.co.jp> * sprintf.c (f_sprintf): integer formatter totally re-written. @@ -25,6 +25,28 @@ module TkComm 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 @@ module TkComm 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 @@ module TkComm 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 @@ module TkCore appsend_displayof(interp, win, async, *args) end + def info(*args) + tk_call('info', *args) + end + def mainloop TclTkLib.mainloop end @@ -661,7 +713,7 @@ class TkVariable 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 @@ module TkWinfo 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 @@ module TkWinfo 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 @@ module TkWinfo 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 @@ class TkToplevel<TkWindow 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 TkFrame<TkWindow def self.to_eval WidgetClassName end + + def initialize(parent=nil, keys=nil) + 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['visual'] + @screen = keys['visual'] + keys['visual'] = nil + end + end + super(parent, keys) + end + def create_self - tk_call 'frame', @path + s = [] + s.push << "-class" << @classname if @classname + s.push << "-colormap" << @colormap if @colormap + s.push << "-container" << @container if @container + s.push << "-visual" << @visual if @visual + tk_call 'frame', @path, *s end end @@ -2045,7 +2155,120 @@ class TkListbox<TkTextWin end end +module TkTreatMenuEntryFont + def tagfont_configinfo(index) + pathname = self.path + ';' + index + ret = TkFont.used_on(pathname) + if ret == nil + ret = TkFont.init_widget_font(pathname, + self.path, 'entryconfigure', index) + end + ret + end + alias tagfontobj tagfont_configinfo + + def tagfont_configure(index, slot) + pathname = self.path + ';' + index + if (fnt = slot['font']) + slot['font'] = nil + if fnt.kind_of? TkFont + return fnt.call_font_configure(pathname, + self.path,'entryconfigure',index,slot) + else + latintagfont_configure(index, fnt) if fnt + end + end + if (ltn = slot['latinfont']) + slot['latinfont'] = nil + latintagfont_configure(index, ltn) if ltn + end + if (ltn = slot['asciifont']) + slot['asciifont'] = nil + latintagfont_configure(index, ltn) if ltn + end + if (knj = slot['kanjifont']) + slot['kanjifont'] = nil + kanjitagfont_configure(index, knj) if knj + end + + tk_call(self.path, 'entryconfigure', index, *hash_kv(slot)) if slot != {} + self + end + + def latintagfont_configure(index, ltn, keys=nil) + fobj = tagfontobj(index) + if ltn.kind_of? TkFont + conf = {} + ltn.latin_configinfo.each{|key,val| conf[key] = val if val != []} + if conf == {} + fobj.latin_replace(ltn) + fobj.latin_configure(keys) if keys + elsif keys + fobj.latin_configure(conf.update(keys)) + else + fobj.latin_configure(conf) + end + else + fobj.latin_replace(ltn) + end + end + alias asciitagfont_configure latintagfont_configure + + def kanjitagfont_configure(index, knj, keys=nil) + fobj = tagfontobj(index) + if knj.kind_of? TkFont + conf = {} + knj.kanji_configinfo.each{|key,val| conf[key] = val if val != []} + if conf == {} + fobj.kanji_replace(knj) + fobj.kanji_configure(keys) if keys + elsif keys + fobj.kanji_configure(conf.update(keys)) + else + fobj.kanji_configure(conf) + end + else + fobj.kanji_replace(knj) + end + end + + def tagfont_copy(index, window, wintag=nil) + if wintag + window.tagfontobj(wintag).configinfo.each{|key,value| + tagfontobj(index).configure(key,value) + } + tagfontobj(index).replace(window.tagfontobj(wintag).latin_font, + window.tagfontobj(wintag).kanji_font) + else + window.tagfont(wintag).configinfo.each{|key,value| + tagfontobj(index).configure(key,value) + } + tagfontobj(index).replace(window.fontobj.latin_font, + window.fontobj.kanji_font) + end + end + + def latintagfont_copy(index, window, wintag=nil) + if wintag + tagfontobj(index).latin_replace(window.tagfontobj(wintag).latin_font) + else + tagfontobj(index).latin_replace(window.fontobj.latin_font) + end + end + alias asciitagfont_copy latintagfont_copy + + def kanjitagfont_copy(index, window, wintag=nil) + if wintag + tagfontobj(index).kanji_replace(window.tagfontobj(wintag).kanji_font) + else + tagfontobj(index).kanji_replace(window.fontobj.kanji_font) + end + end +end + class TkMenu<TkWindow + include TkTreatMenuEntryFont + WidgetClassName = 'Menu'.freeze TkClassBind::WidgetClassNameTBL[WidgetClassName] = self def self.to_eval @@ -2069,6 +2292,9 @@ class TkMenu<TkWindow def insert(index, type, keys=nil) tk_send 'add', index, type, *hash_kv(keys) end + def delete(index, last=None) + tk_send 'delete', index, last + end def post(x, y) tk_send 'post', x, y end @@ -2090,6 +2316,43 @@ class TkMenu<TkWindow def entryconfigure(index, keys=nil) tk_send 'entryconfigure', index, *hash_kv(keys) end +# def entryconfigure(index, keys=nil) +# tk_send 'entryconfigure', index, *hash_kv(keys) +# end + def entrycget(index, key) + tk_tcl2ruby tk_send 'entrycget', index, "-#{key}" + end + def entryconfigure(index, key, val=None) + if key.kind_of? Hash + if ( key['font'] || key['kanjifont'] \ + || key['latinfont'] || key['asciifont'] ) + tagfont_configure(index, key.dup) + else + tk_send 'entryconfigure', index, *hash_kv(key) + end + + else + if ( key == 'font' || key == 'kanjifont' \ + || key == 'latinfont' || key == 'asciifont' ) + tagfont_configure({key=>val}) + 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 TkMenubutton<TkLabel diff --git a/lib/tkcanvas.rb b/lib/tkcanvas.rb index 3beb2ff1dc..d5ddafd851 100644 --- a/lib/tkcanvas.rb +++ b/lib/tkcanvas.rb @@ -293,7 +293,7 @@ class TkCanvas<TkWindow end def itemcget(tagOrId, option) - tk_send 'itemcget', tagid(tagOrId), "-#{option}" + tk_tcl2ruby tk_send 'itemcget', tagid(tagOrId), "-#{option}" end def itemconfigure(tagOrId, key, value=None) @@ -772,7 +772,7 @@ class TkPhotoImage<TkImage end def cget(option) - tk_send 'cget', option + tk_tcl2ruby tk_send 'cget', option end def copy(source, *opts) diff --git a/lib/tkfont.rb b/lib/tkfont.rb index 86114c6b62..9c2f4c1b66 100644 --- a/lib/tkfont.rb +++ b/lib/tkfont.rb @@ -493,6 +493,8 @@ class TkFont tk_call(win, 'tag', 'configure', tag, '-font', @latinfont) elsif winobj.kind_of? TkCanvas tk_call(win, 'itemconfigure', tag, '-font', @latinfont) + elsif winobj.kind_of? TkMenu + tk_call(win, 'entryconfigure', tag, '-font', @latinfont) else raise RuntimeError, "unknown widget type" end @@ -525,6 +527,8 @@ class TkFont tk_call(win, 'tag', 'configure', tag, '-kanjifont', @kanjifont) elsif winobj.kind_of? TkCanvas tk_call(win, 'itemconfigure', tag, '-kanjifont', @kanjifont) + elsif winobj.kind_of? TkMenu + tk_call(win, 'entryconfigure', tag, '-kanjifont', @latinfont) else raise RuntimeError, "unknown widget type" end @@ -692,6 +696,8 @@ class TkFont else ret.push([winobj, tag]) end + elsif winobj.kind_of? TkMenu + ret.push([winobj, tag]) else ret.push([win, tag]) end diff --git a/lib/tktext.rb b/lib/tktext.rb index e0b4f9641e..02d5a7f3e0 100644 --- a/lib/tktext.rb +++ b/lib/tktext.rb @@ -99,7 +99,7 @@ module TkTreatTextTagFont tagfontobj(tag).replace(window.tagfontobj(wintag).latin_font, window.tagfontobj(wintag).kanji_font) else - window.tagfont(tag).configinfo.each{|key,value| + window.tagfont(wintag).configinfo.each{|key,value| tagfontobj(tag).configure(key,value) } tagfontobj(tag).replace(window.fontobj.latin_font, @@ -272,7 +272,7 @@ class TkText<TkTextWin end def tag_cget(tag, key) - tk_call @t.path, 'tag', 'cget', tag, "-#{key}" + tk_tcl2ruby tk_call @t.path, 'tag', 'cget', tag, "-#{key}" end def tag_configure(tag, key, val=None) @@ -486,7 +486,7 @@ class TkTextTag<TkObject end def cget(key) - tk_call @t.path, 'tag', 'cget', @id, "-#{key}" + tk_tcl2ruby tk_call @t.path, 'tag', 'cget', @id, "-#{key}" end def configure(key, val=None) @@ -668,7 +668,7 @@ class TkTextWindow<TkObject end def cget(slot) - tk_call @t.path, 'window', 'cget', @index, "-#{slot}" + tk_tcl2ruby tk_call @t.path, 'window', 'cget', @index, "-#{slot}" end def configure(slot, value=None) @@ -758,7 +758,7 @@ class TkTextImage<TkObject end def cget(slot) - tk_call @t.path, 'image', 'cget', @index, "-#{slot}" + tk_tcl2ruby tk_call @t.path, 'image', 'cget', @index, "-#{slot}" end def configure(slot, value=None) @@ -49,6 +49,7 @@ static void rehash(); #define EQUAL(table, x, y) ((*table->type->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); } |