mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
*** empty log message ***
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/v1_1r@230 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
a8382af43a
commit
cfe64537f8
5 changed files with 116 additions and 76 deletions
|
@ -1,3 +1,7 @@
|
|||
Thu May 28 18:02:55 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
|
||||
|
||||
* object.c (nil_plus): no more `+' method for nil.
|
||||
|
||||
Wed May 27 17:33:46 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
|
||||
|
||||
* hash.c (hash_fetch): new method.
|
||||
|
|
4
object.c
4
object.c
|
@ -287,6 +287,7 @@ nil_type(obj)
|
|||
return cNilClass;
|
||||
}
|
||||
|
||||
#ifdef NIL_PLUS
|
||||
static VALUE
|
||||
nil_plus(x, y)
|
||||
VALUE x, y;
|
||||
|
@ -306,6 +307,7 @@ nil_plus(x, y)
|
|||
}
|
||||
/* not reached */
|
||||
}
|
||||
#endif
|
||||
|
||||
static VALUE
|
||||
main_to_s(obj)
|
||||
|
@ -996,7 +998,9 @@ Init_Object()
|
|||
rb_define_global_const("NIL", Qnil);
|
||||
|
||||
/* default addition */
|
||||
#ifdef NIL_PLUS
|
||||
rb_define_method(cNilClass, "+", nil_plus, 1);
|
||||
#endif
|
||||
|
||||
rb_define_global_function("initialize", obj_dummy, -1);
|
||||
rb_define_global_function("singleton_method_added", obj_dummy, 1);
|
||||
|
|
96
regex.c
96
regex.c
|
@ -1064,24 +1064,24 @@ re_compile_pattern(pattern, size, bufp)
|
|||
{
|
||||
case '$':
|
||||
{
|
||||
char *p1 = p;
|
||||
p0 = p;
|
||||
/* When testing what follows the $,
|
||||
look past the \-constructs that don't consume anything. */
|
||||
|
||||
while (p1 != pend)
|
||||
while (p0 != pend)
|
||||
{
|
||||
if (*p1 == '\\' && p1 + 1 != pend
|
||||
&& (p1[1] == 'b' || p1[1] == 'B'))
|
||||
p1 += 2;
|
||||
if (*p0 == '\\' && p0 + 1 != pend
|
||||
&& (p0[1] == 'b' || p0[1] == 'B'))
|
||||
p0 += 2;
|
||||
else
|
||||
break;
|
||||
}
|
||||
/* $ means succeed if at end of line, but only in special contexts.
|
||||
If validly in the middle of a pattern, it is a normal character. */
|
||||
|
||||
if (p1 == pend || *p1 == '\n'
|
||||
|| *p1 == ')'
|
||||
|| *p1 == '|')
|
||||
if (p0 == pend || *p0 == '\n'
|
||||
|| *p0 == ')'
|
||||
|| *p0 == '|')
|
||||
{
|
||||
BUFPUSH(endline);
|
||||
break;
|
||||
|
@ -1544,7 +1544,8 @@ re_compile_pattern(pattern, size, bufp)
|
|||
break;
|
||||
|
||||
case ')':
|
||||
if (stackp == stackb) goto unmatched_close;
|
||||
if (stackp == stackb)
|
||||
FREE_AND_RETURN(stackb, "unmatched )");
|
||||
if ((options ^ stackp[-1]) & RE_OPTION_IGNORECASE) {
|
||||
BUFPUSH((options&RE_OPTION_IGNORECASE)?casefold_off:casefold_on);
|
||||
}
|
||||
|
@ -1749,7 +1750,12 @@ re_compile_pattern(pattern, size, bufp)
|
|||
|
||||
GET_BUFFER_SPACE(5);
|
||||
BUFPUSH(set_number_at);
|
||||
STORE_NUMBER_AND_INCR(b, -5);
|
||||
STORE_NUMBER_AND_INCR(b, laststart - b + 11);
|
||||
STORE_NUMBER_AND_INCR(b, lower_bound);
|
||||
|
||||
GET_BUFFER_SPACE(5);
|
||||
BUFPUSH(set_number_at);
|
||||
STORE_NUMBER_AND_INCR(b, -10);
|
||||
STORE_NUMBER_AND_INCR(b, upper_bound - 1);
|
||||
}
|
||||
pending_exact = 0;
|
||||
|
@ -1951,7 +1957,8 @@ re_compile_pattern(pattern, size, bufp)
|
|||
if (fixup_jump)
|
||||
store_jump(fixup_jump, jump, b);
|
||||
|
||||
if (stackp != stackb) goto unmatched_open;
|
||||
if (stackp != stackb)
|
||||
FREE_AND_RETURN(stackb, "unmatched (");
|
||||
|
||||
bufp->used = b - bufp->buffer;
|
||||
bufp->re_nsub = regnum;
|
||||
|
@ -1961,12 +1968,6 @@ re_compile_pattern(pattern, size, bufp)
|
|||
invalid_pattern:
|
||||
FREE_AND_RETURN(stackb, "invalid regular expression");
|
||||
|
||||
unmatched_open:
|
||||
FREE_AND_RETURN(stackb, "unmatched (");
|
||||
|
||||
unmatched_close:
|
||||
FREE_AND_RETURN(stackb, "unmatched )");
|
||||
|
||||
end_of_pattern:
|
||||
FREE_AND_RETURN(stackb, "premature end of regular expression");
|
||||
|
||||
|
@ -2249,6 +2250,7 @@ re_compile_fastmap(bufp)
|
|||
continue;
|
||||
|
||||
case casefold_on:
|
||||
bufp->options |= RE_MAY_IGNORECASE;
|
||||
case casefold_off:
|
||||
options ^= RE_OPTION_IGNORECASE;
|
||||
continue;
|
||||
|
@ -2530,6 +2532,11 @@ re_search(bufp, string, size, startpos, range, regs)
|
|||
}
|
||||
}
|
||||
|
||||
/* Update the fastmap now if not correct already. */
|
||||
if (fastmap && !bufp->fastmap_accurate) {
|
||||
re_compile_fastmap(bufp);
|
||||
}
|
||||
|
||||
if (range > 0
|
||||
&& bufp->must
|
||||
&& !must_instr(bufp->must+1, bufp->must[0],
|
||||
|
@ -2538,11 +2545,6 @@ re_search(bufp, string, size, startpos, range, regs)
|
|||
return -1;
|
||||
}
|
||||
|
||||
/* Update the fastmap now if not correct already. */
|
||||
if (fastmap && !bufp->fastmap_accurate) {
|
||||
re_compile_fastmap(bufp);
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
/* If a fastmap is supplied, skip quickly over characters that
|
||||
|
@ -2660,14 +2662,25 @@ int re_max_failures = 2000;
|
|||
|
||||
/* Structure and accessing macros used in re_match: */
|
||||
|
||||
struct register_info
|
||||
typedef union
|
||||
{
|
||||
unsigned is_active : 1;
|
||||
unsigned matched_something : 1;
|
||||
};
|
||||
unsigned char *word;
|
||||
struct
|
||||
{
|
||||
/* This field is one if this group can match the empty string,
|
||||
zero if not. If not yet determined, `MATCH_NULL_UNSET_VALUE'. */
|
||||
#define MATCH_NULL_UNSET_VALUE 3
|
||||
unsigned match_null_string_p : 2;
|
||||
unsigned is_active : 1;
|
||||
unsigned matched_something : 1;
|
||||
unsigned ever_matched_something : 1;
|
||||
} bits;
|
||||
} register_info_type;
|
||||
|
||||
#define IS_ACTIVE(R) ((R).is_active)
|
||||
#define MATCHED_SOMETHING(R) ((R).matched_something)
|
||||
#define REG_MATCH_NULL_STRING_P(R) ((R).bits.match_null_string_p)
|
||||
#define IS_ACTIVE(R) ((R).bits.is_active)
|
||||
#define MATCHED_SOMETHING(R) ((R).bits.matched_something)
|
||||
#define EVER_MATCHED_SOMETHING(R) ((R).bits.ever_matched_something)
|
||||
|
||||
|
||||
/* Macros used by re_match: */
|
||||
|
@ -2698,7 +2711,7 @@ struct register_info
|
|||
/* Find out how many registers are active or have been matched. \
|
||||
(Aside from register zero, which is only set at the end.) */ \
|
||||
for (last_used_reg = num_regs - 1; last_used_reg > 0; last_used_reg--)\
|
||||
if (regstart[last_used_reg] != (unsigned char *)(-1L)) \
|
||||
if (!REG_UNSET(regstart[last_used_reg])) \
|
||||
break; \
|
||||
\
|
||||
if (stacke - stackp <= NUM_FAILURE_ITEMS) \
|
||||
|
@ -2720,7 +2733,7 @@ struct register_info
|
|||
{ \
|
||||
*stackp++ = regstart[this_reg]; \
|
||||
*stackp++ = regend[this_reg]; \
|
||||
*stackp++ = (unsigned char *)®_info[this_reg]; \
|
||||
*stackp++ = reg_info[this_reg].word; \
|
||||
} \
|
||||
\
|
||||
/* Push how many registers we saved. */ \
|
||||
|
@ -2743,6 +2756,10 @@ struct register_info
|
|||
stackp -= temp; /* Remove the register info. */ \
|
||||
}
|
||||
|
||||
/* Registers are set to a sentinel when they haven't yet matched. */
|
||||
#define REG_UNSET_VALUE ((unsigned char *) -1)
|
||||
#define REG_UNSET(e) ((e) == REG_UNSET_VALUE)
|
||||
|
||||
#define PREFETCH if (d == dend) goto fail
|
||||
|
||||
/* Call this when have matched something; it sets `matched' flags for the
|
||||
|
@ -2867,7 +2884,7 @@ re_match(bufp, string_arg, size, pos, regs)
|
|||
subexpression. These two fields get reset each time through any
|
||||
loop their register is in. */
|
||||
|
||||
struct register_info *reg_info = RE_TALLOC(num_regs, struct register_info);
|
||||
register_info_type *reg_info = RE_TALLOC(num_regs, register_info_type);
|
||||
|
||||
/* The following record the register info as found in the above
|
||||
variables when we find a match better than any we've seen before.
|
||||
|
@ -2896,9 +2913,11 @@ re_match(bufp, string_arg, size, pos, regs)
|
|||
inactive and mark them as not having matched anything or ever
|
||||
failed. */
|
||||
for (mcnt = 0; mcnt < num_regs; mcnt++) {
|
||||
regstart[mcnt] = regend[mcnt] = (unsigned char *) (-1L);
|
||||
IS_ACTIVE(reg_info[mcnt]) = 0;
|
||||
MATCHED_SOMETHING(reg_info[mcnt]) = 0;
|
||||
regstart[mcnt] = regend[mcnt]
|
||||
= best_regstart[mcnt] = best_regend[mcnt] = REG_UNSET_VALUE;
|
||||
reg_info[mcnt].word = 0;
|
||||
IS_ACTIVE (reg_info[mcnt]) = 0;
|
||||
MATCHED_SOMETHING (reg_info[mcnt]) = 0;
|
||||
}
|
||||
|
||||
/* Set up pointers to ends of strings.
|
||||
|
@ -2977,7 +2996,7 @@ re_match(bufp, string_arg, size, pos, regs)
|
|||
regs->end[0] = d - string;
|
||||
for (mcnt = 1; mcnt < num_regs; mcnt++)
|
||||
{
|
||||
if (regend[mcnt] == (unsigned char *)(-1L))
|
||||
if (REG_UNSET(regend[mcnt]))
|
||||
{
|
||||
regs->beg[mcnt] = -1;
|
||||
regs->end[mcnt] = -1;
|
||||
|
@ -3058,8 +3077,11 @@ re_match(bufp, string_arg, size, pos, regs)
|
|||
int regno = *p++; /* Get which register to match against */
|
||||
register unsigned char *d2, *dend2;
|
||||
|
||||
if (IS_ACTIVE(reg_info[regno])) break;
|
||||
|
||||
/* Where in input to try to start matching. */
|
||||
d2 = regstart[regno];
|
||||
if (REG_UNSET(d2)) break;
|
||||
|
||||
/* Where to stop matching; if both the place to start and
|
||||
the place to stop matching are in the same string, then
|
||||
|
@ -3067,6 +3089,7 @@ re_match(bufp, string_arg, size, pos, regs)
|
|||
the end of the first string. */
|
||||
|
||||
dend2 = regend[regno];
|
||||
if (REG_UNSET(dend2)) break;
|
||||
for (;;)
|
||||
{
|
||||
/* At end of register contents => success */
|
||||
|
@ -3380,7 +3403,6 @@ re_match(bufp, string_arg, size, pos, regs)
|
|||
continue;
|
||||
|
||||
case casefold_on:
|
||||
bufp->options |= RE_MAY_IGNORECASE;
|
||||
options |= RE_OPTION_IGNORECASE;
|
||||
continue;
|
||||
|
||||
|
@ -3511,7 +3533,7 @@ re_match(bufp, string_arg, size, pos, regs)
|
|||
/* And restore the rest from the stack. */
|
||||
for ( ; this_reg > 0; this_reg--)
|
||||
{
|
||||
reg_info[this_reg] = *(struct register_info *) *--stackp;
|
||||
reg_info[this_reg].word = *--stackp;
|
||||
regend[this_reg] = *--stackp;
|
||||
regstart[this_reg] = *--stackp;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ freq = {}
|
|||
while gets
|
||||
while sub!(/\w+/, '')
|
||||
word = $&
|
||||
freq[word] +=1
|
||||
freq[word] = freq.fetch(word, 0)+1
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -9,34 +9,59 @@
|
|||
|
||||
require "tkscrollbox"
|
||||
|
||||
list = TkScrollbox.new {
|
||||
relief 'raised'
|
||||
width 20
|
||||
height 20
|
||||
setgrid 'yes'
|
||||
pack
|
||||
}
|
||||
|
||||
# The procedure below is invoked to open a browser on a given file; if the
|
||||
# file is a directory then another instance of this program is invoked; if
|
||||
# the file is a regular file then the Mx editor is invoked to display
|
||||
# the file.
|
||||
|
||||
def browse (dir, file)
|
||||
if dir != "."
|
||||
file="#{dir}/#{file}"
|
||||
if File.directory? file
|
||||
system "browse #{file} &"
|
||||
else
|
||||
if File.file? file
|
||||
if ENV['EDITOR']
|
||||
system format("%s %s&", ENV['EDITOR'], file)
|
||||
else
|
||||
sysmte "xedit #{file}&"
|
||||
end
|
||||
else
|
||||
STDERR.print "\"#{file}\" isn't a directory or regular file"
|
||||
$dirlist = {}
|
||||
|
||||
def browsedir (dir)
|
||||
if $dirlist.key? dir
|
||||
$dirlist[dir]
|
||||
else
|
||||
top = if $dirlist.size > 0 then TkToplevel.new else nil end
|
||||
list = TkScrollbox.new(top) {
|
||||
relief 'raised'
|
||||
width 20
|
||||
height 20
|
||||
setgrid 'yes'
|
||||
pack
|
||||
}
|
||||
list.insert 'end', *`ls #{dir}`.split
|
||||
|
||||
# Set up bindings for the browser.
|
||||
|
||||
list.focus
|
||||
list.bind "Control-q", proc{exit}
|
||||
list.bind "Control-c", proc{exit}
|
||||
list.bind "Control-p", proc{
|
||||
print "selection <", TkSelection.get, ">\n"
|
||||
}
|
||||
|
||||
list.bind "Double-Button-1", proc{
|
||||
for i in TkSelection.get.split
|
||||
print "clicked ", i, "\n"
|
||||
browse dir, i
|
||||
end
|
||||
}
|
||||
$dirlist[dir] = list
|
||||
end
|
||||
end
|
||||
|
||||
def browse (dir, file)
|
||||
file="#{dir}/#{file}"
|
||||
if File.directory? file
|
||||
browsedir(file)
|
||||
else
|
||||
if File.file? file
|
||||
if ENV['EDITOR']
|
||||
system format("%s %s&", ENV['EDITOR'], file)
|
||||
else
|
||||
system "xedit #{file}&"
|
||||
end
|
||||
else
|
||||
STDERR.print "\"#{file}\" isn't a directory or regular file"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -49,21 +74,6 @@ if ARGV.length>0
|
|||
else
|
||||
dir="."
|
||||
end
|
||||
list.insert 'end', *`ls #{dir}`.split
|
||||
|
||||
# Set up bindings for the browser.
|
||||
|
||||
list.focus
|
||||
list.bind "Control-q", proc{exit}
|
||||
list.bind "Control-c", proc{exit}
|
||||
list.bind "Control-p", proc{
|
||||
print "selection <", TkSelection.get, ">\n"
|
||||
}
|
||||
|
||||
list.bind "Double-Button-1", proc{
|
||||
for i in TkSelection.get.split
|
||||
print "clicked ", i, "\n"
|
||||
browse dir, i
|
||||
end
|
||||
}
|
||||
browsedir(dir)
|
||||
Tk.mainloop
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue