diff --git a/ChangeLog b/ChangeLog index badd3481cc..7583c6f75a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +Fri Jan 2 15:30:57 2009 Tanaka Akira + + * ext/socket/mkconstants.rb: make common prefix optional. + Fri Jan 2 14:59:52 2009 Tanaka Akira * ext/socket/mkconstants.rb: use hash for family_to_str to avoid diff --git a/ext/socket/mkconstants.rb b/ext/socket/mkconstants.rb index 0491924a86..574ad25b71 100644 --- a/ext/socket/mkconstants.rb +++ b/ext/socket/mkconstants.rb @@ -73,25 +73,44 @@ def reverse_each_name(pat) } end -def each_names_with_len(pat) +def each_names_with_len(pat, prefix_optional=nil) h = {} DEFS.each {|name, default_value| next if pat !~ name - (h[name.length] ||= []) << name + (h[name.length] ||= []) << [name, name] + } + if prefix_optional + if Regexp === prefix_optional + prefix_pat = prefix_optional + else + prefix_pat = /\A#{Regexp.escape prefix_optional}/ + end + DEFS.each {|const, default_value| + next if pat !~ const + next if prefix_pat !~ const + name = $' + (h[name.length] ||= []) << [name, const] + } + end + hh = {} + h.each {|len, pairs| + pairs.each {|name, const| + raise "name crash: #{name}" if hh[name] + hh[name] = true + } } h.keys.sort.each {|len| yield h[len], len } end -ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_name_to_int(str_var, len_var, retp_var, pat)") +ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_name_to_int(str_var, len_var, retp_var, pat, prefix_optional=nil)") switch (<%=len_var%>) { -% each_names_with_len(pat) {|names, len| +% each_names_with_len(pat, prefix_optional) {|pairs, len| case <%=len%>: -% names.each {|name| -#ifdef <%=name%> -% size = name.bytesize - if (memcmp(<%=str_var%>, <%=c_str name%>, <%=size%>) == 0) { *<%=retp_var%> = <%=name%>; return 0; } +% pairs.each {|name, const| +#ifdef <%=const%> + if (memcmp(<%=str_var%>, <%=c_str name%>, <%=len%>) == 0) { *<%=retp_var%> = <%=const%>; return 0; } #endif % } return -1; @@ -146,49 +165,49 @@ init_constants(VALUE mConst) static int family_to_int(char *str, int len, int *valp) { -<%= gen_name_to_int("str", "len", "valp", /\A[AP]F_/) %> +<%= gen_name_to_int("str", "len", "valp", /\A[AP]F_/, "AF_") %> } static int socktype_to_int(char *str, int len, int *valp) { -<%= gen_name_to_int("str", "len", "valp", /\ASOCK_/) %> +<%= gen_name_to_int("str", "len", "valp", /\ASOCK_/, "SOCK_") %> } static int level_to_int(char *str, int len, int *valp) { -<%= gen_name_to_int("str", "len", "valp", /\A(SOL_SOCKET\z|IPPROTO_)/) %> +<%= gen_name_to_int("str", "len", "valp", /\A(SOL_SOCKET\z|IPPROTO_)/, /\A(SOL_|IPPROTO_)/) %> } static int so_optname_to_int(char *str, int len, int *valp) { -<%= gen_name_to_int("str", "len", "valp", /\ASO_/) %> +<%= gen_name_to_int("str", "len", "valp", /\ASO_/, "SO_") %> } static int ip_optname_to_int(char *str, int len, int *valp) { -<%= gen_name_to_int("str", "len", "valp", /\AIP_/) %> +<%= gen_name_to_int("str", "len", "valp", /\AIP_/, "IP_") %> } static int ipv6_optname_to_int(char *str, int len, int *valp) { -<%= gen_name_to_int("str", "len", "valp", /\AIPV6_/) %> +<%= gen_name_to_int("str", "len", "valp", /\AIPV6_/, "IPV6_") %> } static int tcp_optname_to_int(char *str, int len, int *valp) { -<%= gen_name_to_int("str", "len", "valp", /\ATCP_/) %> +<%= gen_name_to_int("str", "len", "valp", /\ATCP_/, "TCP_") %> } static int udp_optname_to_int(char *str, int len, int *valp) { -<%= gen_name_to_int("str", "len", "valp", /\AUDP_/) %> +<%= gen_name_to_int("str", "len", "valp", /\AUDP_/, "UDP_") %> } static char * diff --git a/test/socket/test_socket.rb b/test/socket/test_socket.rb index 4733d12c2a..c94861b06c 100644 --- a/test/socket/test_socket.rb +++ b/test/socket/test_socket.rb @@ -16,12 +16,19 @@ class TestBasicSocket < Test::Unit::TestCase inet_stream do |s| n = s.getsockopt(Socket::SOL_SOCKET, Socket::SO_TYPE) assert_equal([Socket::SOCK_STREAM].pack("i"), n) + n = s.getsockopt("SOL_SOCKET", "SO_TYPE") assert_equal([Socket::SOCK_STREAM].pack("i"), n) + n = s.getsockopt(:SOL_SOCKET, :SO_TYPE) assert_equal([Socket::SOCK_STREAM].pack("i"), n) + + n = s.getsockopt(:SOCKET, :TYPE) + assert_equal([Socket::SOCK_STREAM].pack("i"), n) + n = s.getsockopt(Socket::SOL_SOCKET, Socket::SO_ERROR) assert_equal([0].pack("i"), n) + val = Object.new class << val; self end.send(:define_method, :to_int) { s.close