summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>1998-07-21 09:18:05 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>1998-07-21 09:18:05 +0000
commit334b2c9f855ca8e4a36d34c6e600f5203ec017a5 (patch)
tree81a3e8889b938217aa68284686b38313241c3f9e
parent043ec1f18d6e99b73eec029142185019f383f478 (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--ChangeLog4
-rw-r--r--lib/tk.rb313
-rw-r--r--lib/tkcanvas.rb4
-rw-r--r--lib/tkfont.rb6
-rw-r--r--lib/tktext.rb10
-rw-r--r--st.c15
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 <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.
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 @@ 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)
diff --git a/st.c b/st.c
index 27ccf3eb8a..eefa8497d9 100644
--- a/st.c
+++ b/st.c
@@ -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);
}