PageRenderTime 44ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/ext/socket/mkconstants.rb

http://github.com/MacRuby/MacRuby
Ruby | 562 lines | 498 code | 50 blank | 14 comment | 17 complexity | 53459b954c9afc237bc5dd877f18e192 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, LGPL-2.1
  1. require 'optparse'
  2. require 'erb'
  3. opt = OptionParser.new
  4. opt.def_option('-h', 'help') {
  5. puts opt
  6. exit 0
  7. }
  8. opt_o = nil
  9. opt.def_option('-o FILE', 'specify output file') {|filename|
  10. opt_o = filename
  11. }
  12. C_ESC = {
  13. "\\" => "\\\\",
  14. '"' => '\"',
  15. "\n" => '\n',
  16. }
  17. 0x00.upto(0x1f) {|ch| C_ESC[[ch].pack("C")] ||= "\\%03o" % ch }
  18. 0x7f.upto(0xff) {|ch| C_ESC[[ch].pack("C")] = "\\%03o" % ch }
  19. C_ESC_PAT = Regexp.union(*C_ESC.keys)
  20. def c_str(str)
  21. '"' + str.gsub(C_ESC_PAT) {|s| C_ESC[s]} + '"'
  22. end
  23. opt.parse!
  24. result = ''
  25. # workaround for NetBSD, OpenBSD and etc.
  26. result << "#define pseudo_AF_FTIP pseudo_AF_RTIP\n"
  27. h = {}
  28. DATA.each_line {|s|
  29. name, default_value = s.scan(/\S+/)
  30. next unless name && name[0] != ?#
  31. raise "duplicate name: #{name}" if h.has_key? name
  32. h[name] = default_value
  33. }
  34. DEFS = h.to_a
  35. def each_const
  36. DEFS.each {|name, default_value|
  37. if name =~ /\AINADDR_/
  38. define = "sock_define_uconst"
  39. else
  40. define = "sock_define_const"
  41. end
  42. guard = nil
  43. if /\A(AF_INET6|PF_INET6)\z/ =~ name
  44. # IPv6 is not supported although AF_INET6 is defined on bcc32/mingw
  45. guard = "defined(INET6)"
  46. end
  47. yield guard, define, name, default_value
  48. }
  49. end
  50. def each_name(pat)
  51. DEFS.each {|name, default_value|
  52. next if pat !~ name
  53. yield name
  54. }
  55. end
  56. ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_const_defs_in_guard(define, name, default_value)")
  57. % if default_value
  58. #ifndef <%=name%>
  59. #define <%=name%> <%=default_value%>
  60. #endif
  61. <%=define%>(<%=c_str name%>, <%=name%>);
  62. % else
  63. #if defined(<%=name%>)
  64. <%=define%>(<%=c_str name%>, <%=name%>);
  65. #endif
  66. % end
  67. EOS
  68. ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_const_defs")
  69. % each_const {|guard, define, name, default_value|
  70. % if guard
  71. #if <%=guard%>
  72. <%= gen_const_defs_in_guard(define, name, default_value).chomp %>
  73. #endif
  74. % else
  75. <%= gen_const_defs_in_guard(define, name, default_value).chomp %>
  76. % end
  77. % }
  78. EOS
  79. def reverse_each_name(pat)
  80. DEFS.reverse_each {|name, default_value|
  81. next if pat !~ name
  82. yield name
  83. }
  84. end
  85. def each_names_with_len(pat, prefix_optional=nil)
  86. h = {}
  87. DEFS.each {|name, default_value|
  88. next if pat !~ name
  89. (h[name.length] ||= []) << [name, name]
  90. }
  91. if prefix_optional
  92. if Regexp === prefix_optional
  93. prefix_pat = prefix_optional
  94. else
  95. prefix_pat = /\A#{Regexp.escape prefix_optional}/
  96. end
  97. DEFS.each {|const, default_value|
  98. next if pat !~ const
  99. next if prefix_pat !~ const
  100. name = $'
  101. (h[name.length] ||= []) << [name, const]
  102. }
  103. end
  104. hh = {}
  105. h.each {|len, pairs|
  106. pairs.each {|name, const|
  107. raise "name crash: #{name}" if hh[name]
  108. hh[name] = true
  109. }
  110. }
  111. h.keys.sort.each {|len|
  112. yield h[len], len
  113. }
  114. end
  115. ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_name_to_int_func_in_guard(funcname, pat, prefix_optional, guard=nil)")
  116. static int
  117. <%=funcname%>(char *str, int len, int *valp)
  118. {
  119. switch (len) {
  120. % each_names_with_len(pat, prefix_optional) {|pairs, len|
  121. case <%=len%>:
  122. % pairs.each {|name, const|
  123. #ifdef <%=const%>
  124. if (memcmp(str, <%=c_str name%>, <%=len%>) == 0) { *valp = <%=const%>; return 0; }
  125. #endif
  126. % }
  127. return -1;
  128. % }
  129. default:
  130. return -1;
  131. }
  132. }
  133. EOS
  134. ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_name_to_int_func(funcname, pat, prefix_optional, guard=nil)")
  135. %if guard
  136. #ifdef <%=guard%>
  137. <%=gen_name_to_int_func_in_guard(funcname, pat, prefix_optional, guard)%>
  138. #endif
  139. %else
  140. <%=gen_name_to_int_func_in_guard(funcname, pat, prefix_optional, guard)%>
  141. %end
  142. EOS
  143. def reverse_each_name_with_prefix_optional(pat, prefix_pat)
  144. reverse_each_name(pat) {|n|
  145. yield n, n
  146. }
  147. if prefix_pat
  148. reverse_each_name(pat) {|n|
  149. next if prefix_pat !~ n
  150. yield n, $'
  151. }
  152. end
  153. end
  154. ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_int_to_name_hash(hash_var, pat, prefix_pat)")
  155. <%=hash_var%> = st_init_numtable();
  156. GC_RETAIN(<%=hash_var%>);
  157. % reverse_each_name_with_prefix_optional(pat, prefix_pat) {|n,s|
  158. #ifdef <%=n%>
  159. st_insert(<%=hash_var%>, (st_data_t)<%=n%>, (st_data_t)rb_intern2(<%=c_str s%>, <%=s.length%>));
  160. #endif
  161. % }
  162. EOS
  163. ERB.new(<<'EOS', nil, '%').def_method(Object, "gen_int_to_name_func(func_name, hash_var)")
  164. static ID
  165. <%=func_name%>(int val)
  166. {
  167. st_data_t name;
  168. if (st_lookup(<%=hash_var%>, (st_data_t)val, &name))
  169. return (ID)name;
  170. return 0;
  171. }
  172. EOS
  173. INTERN_DEFS = []
  174. def def_intern(func_name, pat, prefix_optional=nil)
  175. prefix_pat = nil
  176. if prefix_optional
  177. if Regexp === prefix_optional
  178. prefix_pat = prefix_optional
  179. else
  180. prefix_pat = /\A#{Regexp.escape prefix_optional}/
  181. end
  182. end
  183. hash_var = "#{func_name}_hash"
  184. decl = "static st_table *#{hash_var};"
  185. gen_hash = gen_int_to_name_hash(hash_var, pat, prefix_pat)
  186. func = gen_int_to_name_func(func_name, hash_var)
  187. INTERN_DEFS << [decl, gen_hash, func]
  188. end
  189. def_intern('intern_family', /\AAF_/)
  190. def_intern('intern_protocol_family', /\APF_/)
  191. def_intern('intern_socktype', /\ASOCK_/)
  192. def_intern('intern_ipproto', /\AIPPROTO_/)
  193. result << ERB.new(<<'EOS', nil, '%').result(binding)
  194. <%= INTERN_DEFS.map {|decl, gen_hash, func| decl }.join("\n") %>
  195. static void
  196. init_constants(VALUE mConst)
  197. {
  198. <%= gen_const_defs %>
  199. <%= INTERN_DEFS.map {|decl, gen_hash, func| gen_hash }.join("\n") %>
  200. }
  201. <%= gen_name_to_int_func("family_to_int", /\A(AF_|PF_)/, "AF_") %>
  202. <%= gen_name_to_int_func("socktype_to_int", /\ASOCK_/, "SOCK_") %>
  203. <%= gen_name_to_int_func("level_to_int", /\A(SOL_SOCKET\z|IPPROTO_)/, /\A(SOL_|IPPROTO_)/) %>
  204. <%= gen_name_to_int_func("so_optname_to_int", /\ASO_/, "SO_") %>
  205. <%= gen_name_to_int_func("ip_optname_to_int", /\AIP_/, "IP_") %>
  206. <%= gen_name_to_int_func("ipv6_optname_to_int", /\AIPV6_/, "IPV6_", "IPPROTO_IPV6") %>
  207. <%= gen_name_to_int_func("tcp_optname_to_int", /\ATCP_/, "TCP_") %>
  208. <%= gen_name_to_int_func("udp_optname_to_int", /\AUDP_/, "UDP_") %>
  209. <%= gen_name_to_int_func("shutdown_how_to_int", /\ASHUT_/, "SHUT_") %>
  210. <%= INTERN_DEFS.map {|decl, gen_hash, func| func }.join("\n") %>
  211. EOS
  212. if opt_o
  213. File.open(opt_o, 'w') {|f|
  214. f << result
  215. }
  216. else
  217. $stdout << result
  218. end
  219. __END__
  220. SOCK_STREAM
  221. SOCK_DGRAM
  222. SOCK_RAW
  223. SOCK_RDM
  224. SOCK_SEQPACKET
  225. SOCK_PACKET
  226. AF_UNSPEC
  227. PF_UNSPEC
  228. AF_INET
  229. PF_INET
  230. AF_INET6
  231. PF_INET6
  232. AF_UNIX
  233. PF_UNIX
  234. AF_AX25
  235. PF_AX25
  236. AF_IPX
  237. PF_IPX
  238. AF_APPLETALK
  239. PF_APPLETALK
  240. AF_LOCAL
  241. PF_LOCAL
  242. AF_IMPLINK
  243. PF_IMPLINK
  244. AF_PUP
  245. PF_PUP
  246. AF_CHAOS
  247. PF_CHAOS
  248. AF_NS
  249. PF_NS
  250. AF_ISO
  251. PF_ISO
  252. AF_OSI
  253. PF_OSI
  254. AF_ECMA
  255. PF_ECMA
  256. AF_DATAKIT
  257. PF_DATAKIT
  258. AF_CCITT
  259. PF_CCITT
  260. AF_SNA
  261. PF_SNA
  262. AF_DEC
  263. PF_DEC
  264. AF_DLI
  265. PF_DLI
  266. AF_LAT
  267. PF_LAT
  268. AF_HYLINK
  269. PF_HYLINK
  270. AF_ROUTE
  271. PF_ROUTE
  272. AF_LINK
  273. PF_LINK
  274. AF_COIP
  275. PF_COIP
  276. AF_CNT
  277. PF_CNT
  278. AF_SIP
  279. PF_SIP
  280. AF_NDRV
  281. PF_NDRV
  282. AF_ISDN
  283. PF_ISDN
  284. AF_NATM
  285. PF_NATM
  286. AF_SYSTEM
  287. PF_SYSTEM
  288. AF_NETBIOS
  289. PF_NETBIOS
  290. AF_PPP
  291. PF_PPP
  292. AF_ATM
  293. PF_ATM
  294. AF_NETGRAPH
  295. PF_NETGRAPH
  296. AF_MAX
  297. PF_MAX
  298. AF_PACKET
  299. PF_PACKET
  300. AF_E164
  301. PF_XTP
  302. PF_RTIP
  303. PF_PIP
  304. PF_KEY
  305. MSG_OOB
  306. MSG_PEEK
  307. MSG_DONTROUTE
  308. MSG_EOR
  309. MSG_TRUNC
  310. MSG_CTRUNC
  311. MSG_WAITALL
  312. MSG_DONTWAIT
  313. MSG_EOF
  314. MSG_FLUSH
  315. MSG_HOLD
  316. MSG_SEND
  317. MSG_HAVEMORE
  318. MSG_RCVMORE
  319. MSG_COMPAT
  320. SOL_SOCKET
  321. SOL_IP
  322. SOL_IPX
  323. SOL_AX25
  324. SOL_ATALK
  325. SOL_TCP
  326. SOL_UDP
  327. IPPROTO_IP 0
  328. IPPROTO_ICMP 1
  329. IPPROTO_IGMP
  330. IPPROTO_GGP
  331. IPPROTO_TCP 6
  332. IPPROTO_EGP
  333. IPPROTO_PUP
  334. IPPROTO_UDP 17
  335. IPPROTO_IDP
  336. IPPROTO_HELLO
  337. IPPROTO_ND
  338. IPPROTO_TP
  339. IPPROTO_XTP
  340. IPPROTO_EON
  341. IPPROTO_BIP
  342. IPPROTO_AH
  343. IPPROTO_DSTOPTS
  344. IPPROTO_ESP
  345. IPPROTO_FRAGMENT
  346. IPPROTO_HOPOPTS
  347. IPPROTO_ICMPV6
  348. IPPROTO_IPV6
  349. IPPROTO_NONE
  350. IPPROTO_ROUTING
  351. IPPROTO_RAW 255
  352. IPPROTO_MAX
  353. # Some port configuration
  354. IPPORT_RESERVED 1024
  355. IPPORT_USERRESERVED 5000
  356. # Some reserved IP v.4 addresses
  357. INADDR_ANY 0x00000000
  358. INADDR_BROADCAST 0xffffffff
  359. INADDR_LOOPBACK 0x7F000001
  360. INADDR_UNSPEC_GROUP 0xe0000000
  361. INADDR_ALLHOSTS_GROUP 0xe0000001
  362. INADDR_MAX_LOCAL_GROUP 0xe00000ff
  363. INADDR_NONE 0xffffffff
  364. # IP [gs]etsockopt options
  365. IP_OPTIONS
  366. IP_HDRINCL
  367. IP_TOS
  368. IP_TTL
  369. IP_RECVOPTS
  370. IP_RECVRETOPTS
  371. IP_RECVDSTADDR
  372. IP_RETOPTS
  373. IP_MINTTL
  374. IP_DONTFRAG
  375. IP_SENDSRCADDR
  376. IP_ONESBCAST
  377. IP_RECVTTL
  378. IP_RECVIF
  379. IP_PORTRANGE
  380. IP_MULTICAST_IF
  381. IP_MULTICAST_TTL
  382. IP_MULTICAST_LOOP
  383. IP_ADD_MEMBERSHIP
  384. IP_DROP_MEMBERSHIP
  385. IP_DEFAULT_MULTICAST_TTL
  386. IP_DEFAULT_MULTICAST_LOOP
  387. IP_MAX_MEMBERSHIPS
  388. SO_DEBUG
  389. SO_REUSEADDR
  390. SO_REUSEPORT
  391. SO_TYPE
  392. SO_ERROR
  393. SO_DONTROUTE
  394. SO_BROADCAST
  395. SO_SNDBUF
  396. SO_RCVBUF
  397. SO_KEEPALIVE
  398. SO_OOBINLINE
  399. SO_NO_CHECK
  400. SO_PRIORITY
  401. SO_LINGER
  402. SO_PASSCRED
  403. SO_PEERCRED
  404. SO_RCVLOWAT
  405. SO_SNDLOWAT
  406. SO_RCVTIMEO
  407. SO_SNDTIMEO
  408. SO_ACCEPTCONN
  409. SO_USELOOPBACK
  410. SO_ACCEPTFILTER
  411. SO_DONTTRUNC
  412. SO_WANTMORE
  413. SO_WANTOOBFLAG
  414. SO_NREAD
  415. SO_NKE
  416. SO_NOSIGPIPE
  417. SO_SECURITY_AUTHENTICATION
  418. SO_SECURITY_ENCRYPTION_TRANSPORT
  419. SO_SECURITY_ENCRYPTION_NETWORK
  420. SO_BINDTODEVICE
  421. SO_ATTACH_FILTER
  422. SO_DETACH_FILTER
  423. SO_PEERNAME
  424. SO_TIMESTAMP
  425. SOPRI_INTERACTIVE
  426. SOPRI_NORMAL
  427. SOPRI_BACKGROUND
  428. IPX_TYPE
  429. TCP_NODELAY
  430. TCP_MAXSEG
  431. TCP_CORK
  432. TCP_DEFER_ACCEPT
  433. TCP_INFO
  434. TCP_KEEPCNT
  435. TCP_KEEPIDLE
  436. TCP_KEEPINTVL
  437. TCP_LINGER2
  438. TCP_MD5SIG
  439. TCP_NOOPT
  440. TCP_NOPUSH
  441. TCP_QUICKACK
  442. TCP_SYNCNT
  443. TCP_WINDOW_CLAMP
  444. UDP_CORK
  445. EAI_ADDRFAMILY
  446. EAI_AGAIN
  447. EAI_BADFLAGS
  448. EAI_FAIL
  449. EAI_FAMILY
  450. EAI_MEMORY
  451. EAI_NODATA
  452. EAI_NONAME
  453. EAI_OVERFLOW
  454. EAI_SERVICE
  455. EAI_SOCKTYPE
  456. EAI_SYSTEM
  457. EAI_BADHINTS
  458. EAI_PROTOCOL
  459. EAI_MAX
  460. AI_PASSIVE
  461. AI_CANONNAME
  462. AI_NUMERICHOST
  463. AI_NUMERICSERV
  464. AI_MASK
  465. AI_ALL
  466. AI_V4MAPPED_CFG
  467. AI_ADDRCONFIG
  468. AI_V4MAPPED
  469. AI_DEFAULT
  470. NI_MAXHOST
  471. NI_MAXSERV
  472. NI_NOFQDN
  473. NI_NUMERICHOST
  474. NI_NAMEREQD
  475. NI_NUMERICSERV
  476. NI_DGRAM
  477. SHUT_RD 0
  478. SHUT_WR 1
  479. SHUT_RDWR 2
  480. IPV6_JOIN_GROUP
  481. IPV6_LEAVE_GROUP
  482. IPV6_MULTICAST_HOPS
  483. IPV6_MULTICAST_IF
  484. IPV6_MULTICAST_LOOP
  485. IPV6_UNICAST_HOPS
  486. IPV6_V6ONLY
  487. IPV6_CHECKSUM
  488. IPV6_DONTFRAG
  489. IPV6_DSTOPTS
  490. IPV6_HOPLIMIT
  491. IPV6_HOPOPTS
  492. IPV6_NEXTHOP
  493. IPV6_PATHMTU
  494. IPV6_PKTINFO
  495. IPV6_RECVDSTOPTS
  496. IPV6_RECVHOPLIMIT
  497. IPV6_RECVHOPOPTS
  498. IPV6_RECVPKTINFO
  499. IPV6_RECVRTHDR
  500. IPV6_RECVTCLASS
  501. IPV6_RTHDR
  502. IPV6_RTHDRDSTOPTS
  503. IPV6_RTHDR_TYPE_0
  504. IPV6_RECVPATHMTU
  505. IPV6_TCLASS
  506. IPV6_USE_MIN_MTU
  507. INET_ADDRSTRLEN
  508. INET6_ADDRSTRLEN