����JFIFXX�����    $.' ",#(7),01444'9=82<.342  2!!22222222222222222222222222222222222222222222222222����"��4�� ���,�PG"Z_�4�˷����kjز�Z�,F+��_z�,�© �����zh6�٨�ic�fu���#ډb���_�N�?��wQ���5-�~�I���8����TK<5o�Iv-�����k�_U_�����~b�M��d����Ӝ�U�Hh��?]��E�w��Q���k�{��_}qFW7HTՑ��Y��F�?_�'ϔ��_�Ջt��=||I ��6�έ"�����D���/[�k�9���Y�8ds|\���Ҿp6�Ҵ���]��.����6�z<�v��@]�i%��$j��~�g��J>��no����pM[me�i$[����s�o�ᘨ�˸ nɜG-�ĨU�ycP�3.DB�li�;��hj���x7Z^�N�h������N3u{�:j�x�힞��#M&��jL P@_���� P��&��o8������9�����@Sz6�t7#O�ߋ �s}Yf�T���lmr����Z)'N��k�۞p����w\�Tȯ?�8`�O��i{wﭹW�[�r�� ��Q4F�׊���3m&L�=��h3����z~��#�\�l :�F,j@�� ʱ�wQT����8�"kJO���6�֚l����}���R�>ډK���]��y����&����p�}b��;N�1�m�r$�|��7�>e�@B�TM*-iH��g�D�)� E�m�|�ؘbҗ�a��Ҿ����t4���o���G��*oCN�rP���Q��@z,|?W[0�����:�n,jWiE��W��$~/�hp\��?��{(�0���+�Y8rΟ�+����>S-S����VN;�}�s?.����� w�9��˟<���Mq4�Wv'��{)0�1mB��V����W[�����8�/<� �%���wT^�5���b��)iM� pg�N�&ݝ��VO~�q���u���9� ����!��J27����$O-���! �:�%H��� ـ����y�ΠM=t{!S�� oK8������t<����è:a������[�����ա�H���~��w��Qz`�po�^ ����Q��n� �,uu�C�$ ^���,������8�#��:�6��e�|~���!�3�3.�\0��q��o�4`.|� ����y�Q�`~;�d�ׯ,��O�Zw�������`73�v�܋�<���Ȏ�� ـ4k��5�K�a�u�=9Yd��$>x�A�&�� j0� ���vF��� Y�|�y��� ~�6�@c��1vOp�Ig����4��l�OD���L����� R���c���j�_�uX6��3?nk��Wy�f;^*B� ��@�~a�`��Eu������+���6�L��.ü>��}y���}_�O�6�͐�:�YrG�X��kG�����l^w���~㒶sy��Iu�!� W ��X��N�7BV��O��!X�2����wvG�R�f�T#�����t�/?���%8�^�W�aT��G�cL�M���I��(J����1~�8�?aT ���]����AS�E��(��*E}� 2��#I/�׍qz��^t�̔���b�Yz4x���t�){ OH��+(E��A&�N�������XT��o��"�XC��'���)}�J�z�p� ��~5�}�^����+�6����w��c��Q�|Lp�d�H��}�(�.|����k��c4^�"�����Z?ȕ ��a<�L�!039C� �Eu�C�F�Ew�ç ;�n?�*o���B�8�bʝ���'#Rqf���M}7����]����s2tcS{�\icTx;�\��7K���P���ʇ Z O-��~��c>"��?�������P��E��O�8��@�8��G��Q�g�a�Վ���󁶠�䧘��_%#r�>�1�z�a��eb��qcPѵ��n���#L��� =��׀t� L�7�`��V���A{�C:�g���e@�w1 Xp3�c3�ġ����p��M"'-�@n4���fG��B3�DJ�8[Jo�ߐ���gK)ƛ��$���� ���8�3�����+���� �����6�ʻ���� ���S�kI�*KZlT _`���?��K����QK�d����B`�s}�>���`��*�>��,*@J�d�oF*����弝��O}�k��s��]��y�ߘ��c1G�V���<=�7��7����6�q�PT��tXԀ�!9*4�4Tހ3XΛex�46���Y��D ����� �BdemDa����\�_l,��G�/���֌7���Y�](�xTt^%�GE�����4�}bT���ڹ�����;Y)���B�Q��u��>J/J �⮶.�XԄ��j�ݳ�+E��d ��r�5�_D�1 ��o�� �B�x�΢�#���<��W�����8���R6�@g�M�.��� dr�D��>(otU��@x=��~v���2� ӣ�d�oBd��3�eO�6�㣷�����ݜ6��6Y��Qz`��S��{���\P�~z m5{J/L��1������<�e�ͅPu�b�]�ϔ���'������f�b� Zpw��c`"��i���BD@:)ִ�:�]��hv�E�w���T�l��P���"Ju�}��وV J��G6��. J/�Qgl߭�e�����@�z�Zev2u�)]կ�����7x���s�M�-<ɯ�c��r�v�����@��$�ޮ}lk���a���'����>x��O\�ZFu>�����ck#��&:��`�$�ai�>2Δ����l���oF[h��lE�ܺ�Πk:)���`�� $[6�����9�����kOw�\|���8}������ބ:��񶐕��I�A1/�=�2[�,�!��.}gN#�u����b��� ~��݊��}34q����d�E��Lc��$��"�[q�U�硬g^��%B �z���r�pJ�ru%v\h1Y�ne`ǥ:g���pQM~�^�Xi� ��`S�:V29.�P���V�?B�k�� AEvw%�_�9C�Q����wKekPؠ�\�;Io d�{ ߞo�c1eP����\� `����E=���@K<�Y���eڼ�J���w����{av�F�'�M�@/J��+9p���|]�����Iw &`��8���&M�hg��[�{��Xj��%��Ӓ�$��(����ʹN���<>�I���RY���K2�NPlL�ɀ)��&e����B+ь����( � �JTx���_?EZ� }@ 6�U���뙢ط�z��dWI�n` D����噥�[��uV��"�G&Ú����2g�}&m��?ċ�"����Om#��������� ��{�ON��"S�X��Ne��ysQ���@Fn��Vg���dX�~nj�]J�<�K]:��FW��b�������62�=��5f����JKw��bf�X�55��~J �%^����:�-�QIE��P��v�nZum� z � ~ə ���� ���ة����;�f��\v���g�8�1��f24;�V���ǔ�)����9���1\��c��v�/'Ƞ�w�������$�4�R-��t���� e�6�/�ġ �̕Ecy�J���u�B���<�W�ַ~�w[B1L۲�-JS΂�{���΃������A��20�c#��@ 0!1@AP"#2Q`$3V�%45a6�FRUq��� ����^7ׅ,$n�������+��F�`��2X'��0vM��p�L=������5��8������u�p~���.�`r�����\���O��,ư�0oS ��_�M�����l���4�kv\JSd���x���SW�<��Ae�IX����������$I���w�:S���y���›R��9�Q[���,�5�;�@]�%���u�@ *ro�lbI �� ��+���%m:�͇ZV�����u�̉����θau<�fc�.����{�4Ա� �Q����*�Sm��8\ujqs]{kN���)qO�y�_*dJ�b�7���yQqI&9�ԌK!�M}�R�;������S�T���1���i[U�ɵz�]��U)V�S6���3$K{�ߊ<�(� E]Զ[ǼENg�����'�\?#)Dkf��J���o��v���'�%ƞ�&K�u�!��b�35LX�Ϸ��63$K�a�;�9>,R��W��3�3� d�JeTYE.Mϧ��-�o�j3+y��y^�c�������VO�9NV\nd�1 ��!͕_)a�v;����թ�M�lWR1��)El��P;��yوÏ�u 3�k�5Pr6<�⒲l�!˞*��u־�n�!�l:����UNW ��%��Chx8vL'��X�@��*��)���̮��ˍ��� ���D-M�+J�U�kvK����+�x8��cY������?�Ԡ��~3mo��|�u@[XeY�C�\Kp�x8�oC�C�&����N�~3-H���� ��MX�s�u<`���~"WL��$8ξ��3���a�)|:@�m�\���^�`�@ҷ)�5p+��6���p�%i)P M���ngc�����#0Aruz���RL+xSS?���ʮ}()#�t��mˇ!��0}}y����<�e� �-ή�Ԩ��X������ MF���ԙ~l L.3���}�V뽺�v�����멬��Nl�)�2����^�Iq��a��M��qG��T�����c3#������3U�Ǎ���}��לS�|qa��ڃ�+���-��2�f����/��bz��ڐ�� �ݼ[2�ç����k�X�2�* �Z�d���J�G����M*9W���s{��w���T��x��y,�in�O�v��]���n����P�$�JB@=4�OTI�n��e�22a\����q�d���%�$��(���:���: /*�K[PR�fr\nڙdN���F�n�$�4�[�� U�zƶ����� �mʋ���,�ao�u 3�z� �x��Kn����\[��VFmbE;�_U��&V�Gg�]L�۪&#n%�$ɯ�dG���D�TI=�%+AB�Ru#��b4�1�»x�cs�YzڙJG��f��Il��d�eF'T� iA��T���uC�$����Y��H?����[!G`}���ͪ� �纤Hv\������j�Ex�K���!���OiƸ�Yj�+u-<���'q����uN�*�r\��+�]���<�wOZ.fp�ێ��,-*)V?j-kÊ#�`�r��dV����(�ݽBk�����G�ƛk�QmUڗe��Z���f}|����8�8��a���i��3'J�����~G_�^���d�8w������ R�`(�~�.��u���l�s+g�bv���W���lGc}��u���afE~1�Ue������Z�0�8�=e�� f@/�jqEKQQ�J��oN��J���W5~M>$6�Lt�;$ʳ{���^��6�{����v6���ķܰg�V�cnn �~z�x�«�,2�u�?cE+Ș�H؎�%�Za�)���X>uW�Tz�Nyo����s���FQƤ��$��*�&�LLXL)�1�" L��eO��ɟ�9=���:t��Z���c��Ž���Y?�ӭV�wv�~,Y��r�ۗ�|�y��GaF�����C�����.�+� ���v1���fήJ�����]�S��T��B��n5sW}y�$��~z�'�c ��8 ��� ,! �p��VN�S��N�N�q��y8z˱�A��4��*��'������2n<�s���^ǧ˭P�Jޮɏ�U�G�L�J�*#��<�V��t7�8����TĜ>��i}K%,���)[��z�21z ?�N�i�n1?T�I�R#��m-�����������������1����lA�`��fT5+��ܐ�c�q՝��ʐ��,���3�f2U�եmab��#ŠdQ�y>\��)�SLY����w#��.���ʑ�f��� ,"+�w�~�N�'�c�O�3F�������N<���)j��&��,-� �љ���֊�_�zS���TǦ����w�>��?�������n��U仆�V���e�����0���$�C�d���rP �m�׈e�Xm�Vu� �L��.�bֹ��� �[Դaզ���*��\y�8�Է:�Ez\�0�Kq�C b��̘��cө���Q��=0Y��s�N��S.���3.���O�o:���#���v7�[#߫ ��5�܎�L���Er4���9n��COWlG�^��0k�%<���ZB���aB_���������'=��{i�v�l�$�uC���mƎҝ{�c㱼�y]���W�i ��ߧc��m�H� m�"�"�����;Y�ߝ�Z�Ǔ�����:S#��|}�y�,/k�Ld� TA�(�AI$+I3��;Y*���Z��}|��ӧO��d�v��..#:n��f>�>���ȶI�TX��� 8��y����"d�R�|�)0���=���n4��6ⲑ�+��r<�O�܂~zh�z����7ܓ�HH�Ga롏���nCo�>������a ���~]���R���̲c?�6(�q�;5%� |�uj�~z8R=X��I�V=�|{v�Gj\gc��q����z�؋%M�ߍ����1y��#��@f^���^�>N�����#x#۹��6�Y~�?�dfPO��{��P�4��V��u1E1J �*|���%���JN��`eWu�zk M6���q t[�� ��g�G���v��WIG��u_ft����5�j�"�Y�:T��ɐ���*�;� e5���4����q$C��2d�}���� _S�L#m�Yp��O�.�C�;��c����Hi#֩%+) �Ӎ��ƲV���SYź��g |���tj��3�8���r|���V��1#;.SQ�A[���S������#���`n�+���$��$I �P\[�@�s��(�ED�z���P��])8�G#��0B��[ى��X�II�q<��9�~[Z멜�Z�⊔IWU&A>�P~�#��dp<�?����7���c��'~���5 ��+$���lx@�M�dm��n<=e�dyX��?{�|Aef ,|n3�<~z�ƃ�uۧ�����P��Y,�ӥQ�*g�#먙R�\���;T��i,��[9Qi歉����c>]9�� ��"�c��P�� �Md?٥��If�ت�u��k��/����F��9�c*9��Ǎ:�ØF���z�n*�@|I�ށ9����N3{'��[�'ͬ�Ҳ4��#}��!�V� Fu��,�,mTIk���v C�7v���B�6k�T9��1�*l� '~��ƞF��lU��'�M ����][ΩũJ_�{�i�I�n��$���L�� j��O�dx�����kza۪��#�E��Cl����x˘�o�����V���ɞ�ljr��)�/,�߬h�L��#��^��L�ф�,íMƁe�̩�NB�L�����iL����q�}��(��q��6IçJ$�W�E$��:������=#����(�K�B����zђ <��K(�N�۫K�w��^O{!����)�H���>x�������lx�?>Պ�+�>�W���,Ly!_�D���Ō�l���Q�!�[ �S����J��1��Ɛ�Y}��b,+�Lo�x�ɓ)����=�y�oh�@�꥟/��I��ѭ=��P�y9��� �ۍYӘ�e+�p�Jnϱ?V\SO%�(�t� ���=?MR�[Ș�����d�/ ��n�l��B�7j� ��!�;ӥ�/�[-���A�>�dN�sLj ��,ɪv��=1c�.SQ�O3�U���ƀ�ܽ�E����������̻��9G�ϷD�7(�}��Ävӌ\�y�_0[w ���<΍>����a_��[0+�L��F.�޺��f�>oN�T����q;���y\��bՃ��y�jH�<|q-eɏ�_?_9+P���Hp$�����[ux�K w�Mw��N�ی'$Y2�=��q���KB��P��~������Yul:�[<����F1�2�O���5=d����]Y�sw:���Ϯ���E��j,_Q��X��z`H1,#II ��d�wr��P˂@�ZJV����y$�\y�{}��^~���[:N����ߌ�U�������O��d�����ؾe��${p>G��3c���Ė�lʌ�� ת��[��`ϱ�-W����dg�I��ig2��� ��}s ��ؤ(%#sS@���~���3�X�nRG�~\jc3�v��ӍL��M[JB�T��s3}��j�Nʖ��W����;7��ç?=X�F=-�=����q�ߚ���#���='�c��7���ڑW�I(O+=:uxq�������������e2�zi+�kuG�R��������0�&e�n���iT^J����~\jy���p'dtG��s����O��3����9* �b#Ɋ�� p������[Bws�T�>d4�ۧs���nv�n���U���_�~,�v����ƜJ1��s�� �QIz��)�(lv8M���U=�;����56��G���s#�K���MP�=��LvyGd��}�VwWBF�'�à �?MH�U�g2�� ����!�p�7Q��j��ڴ����=��j�u��� Jn�A s���uM������e��Ɔ�Ҕ�!)'��8Ϣ�ٔ��ޝ(��Vp���צ֖d=�IC�J�Ǡ{q������kԭ�߸���i��@K����u�|�p=..�*+����x�����z[Aqġ#s2a�Ɗ���RR�)*HRsi�~�a &f��M��P����-K�L@��Z��Xy�'x�{}��Zm+���:�)�) IJ�-i�u���� ���ܒH��'�L(7�y�GӜq���� j��� 6ߌg1�g�o���,kر���tY�?W,���p���e���f�OQS��!K�۟cҒA�|ս�j�>��=⬒��˧L[�� �߿2JaB~R��u�:��Q�] �0H~���]�7��Ƽ�I���(}��cq '�ήET���q�?f�ab���ӥvr� �)o��-Q��_'����ᴎo��K������;��V���o��%���~OK ����*��b�f:���-ťIR��`B�5!RB@���ï�� �u �̯e\�_U�_������� g�ES��3�������QT��a����x����U<~�c?�*�#]�MW,[8O�a�x��]�1bC|踤�P��lw5V%�)�{t�<��d��5���0i�XSU��m:��Z�┵�i�"��1�^B�-��P�hJ��&)O��*�D��c�W��vM��)����}���P��ܗ-q����\mmζZ-l@�}��a��E�6��F�@��&Sg@���ݚ�M����� ȹ 4����#p�\H����dYDo�H���"��\��..R�B�H�z_�/5˘����6��KhJR��P�mƶi�m���3�,#c�co��q�a)*Pt����R�m�k�7x�D�E�\Y�閣_X�<���~�)���c[[�BP����6�Yq���S��0����%_����;��Àv�~�| VS؇ ��'O0��F0��\���U�-�d@�����7�SJ*z��3n��y��P����O���������m�~�P�3|Y��ʉr#�C�<�G~�.,! ���bqx���h~0=��!ǫ�jy����l�O,�[B��~��|9��ٱ����Xly�#�i�B��g%�S��������tˋ���e���ې��\[d�t)��.+u�|1 ������#�~Oj����hS�%��i.�~X���I�H�m��0n���c�1uE�q��cF�RF�o���7� �O�ꮧ� ���ۛ{��ʛi5�rw?׌#Qn�TW��~?y$��m\�\o����%W� ?=>S�N@�� �Ʈ���R����N�)�r"C�:��:����� �����#��qb��Y�. �6[��2K����2u�Ǧ�HYR��Q�MV��� �G�$��Q+.>�����nNH��q�^��� ����q��mM��V��D�+�-�#*�U�̒ ���p욳��u:�������IB���m���PV@O���r[b= �� ��1U�E��_Nm�yKbN�O���U�}�the�`�|6֮P>�\2�P�V���I�D�i�P�O;�9�r�mAHG�W�S]��J*�_�G��+kP�2����Ka�Z���H�'K�x�W�MZ%�O�YD�Rc+o��?�q��Ghm��d�S�oh�\�D�|:W������UA�Qc yT�q������~^�H��/��#p�CZ���T�I�1�ӏT����4��"�ČZ�����}��`w�#�*,ʹ�� ��0�i��課�Om�*�da��^gJ݅{���l�e9uF#T�ֲ��̲�ٞC"�q���ߍ ոޑ�o#�XZTp����@ o�8��(jd��xw�]�,f���`~�|,s��^����f�1���t��|��m�򸄭/ctr��5s��7�9Q�4�H1꠲BB@l9@���C�����+�wp�xu�£Yc�9��?`@#�o�mH�s2��)�=��2�.�l����jg�9$�Y�S�%*L������R�Y������7Z���,*=�䷘$�������arm�o�ϰ���UW.|�r�uf����IGw�t����Zwo��~5 ��YյhO+=8fF�)�W�7�L9lM�̘·Y���֘YLf�큹�pRF���99.A �"wz��=E\Z���'a� 2��Ǚ�#;�'}�G���*��l��^"q��+2FQ� hj��kŦ��${���ޮ-�T�٭cf�|�3#~�RJ����t��$b�(R��(����r���dx� >U b�&9,>���%E\� Ά�e�$��'�q't��*�א���ެ�b��-|d���SB�O�O��$�R+�H�)�܎�K��1m`;�J�2�Y~9��O�g8=vqD`K[�F)k�[���1m޼c��n���]s�k�z$@��)!I �x՝"v��9=�ZA=`Ɠi �:�E��)`7��vI��}d�YI�_ �o�:ob���o ���3Q��&D&�2=�� �Ά��;>�h����y.*ⅥS������Ӭ�+q&����j|UƧ����}���J0��WW< ۋS�)jQR�j���Ư��rN)�Gű�4Ѷ(�S)Ǣ�8��i��W52���No˓� ۍ%�5brOn�L�;�n��\G����=�^U�dI���8$�&���h��'���+�(������cȁ߫k�l��S^���cƗjԌE�ꭔ��gF���Ȓ��@���}O���*;e�v�WV���YJ\�]X'5��ղ�k�F��b 6R�o՜m��i N�i����>J����?��lPm�U��}>_Z&�KK��q�r��I�D�Չ~�q�3fL�:S�e>���E���-G���{L�6p�e,8��������QI��h��a�Xa��U�A'���ʂ���s�+טIjP�-��y�8ۈZ?J$��W�P� ��R�s�]��|�l(�ԓ��sƊi��o(��S0��Y� 8�T97.�����WiL��c�~�dxc�E|�2!�X�K�Ƙਫ਼�$((�6�~|d9u+�qd�^3�89��Y�6L�.I�����?���iI�q���9�)O/뚅����O���X��X�V��ZF[�یgQ�L��K1���RҖr@v�#��X�l��F���Нy�S�8�7�kF!A��sM���^rkp�jP�DyS$N���q��nxҍ!U�f�!eh�i�2�m���`�Y�I�9r�6� �TF���C}/�y�^���Η���5d�'��9A-��J��>{�_l+�`��A���[�'��յ�ϛ#w:݅�%��X�}�&�PSt�Q�"�-��\縵�/����$Ɨh�Xb�*�y��BS����;W�ջ_mc�����vt?2}1�;qS�d�d~u:2k5�2�R�~�z+|HE!)�Ǟl��7`��0�<�,�2*���Hl-��x�^����'_TV�gZA�'j� ^�2Ϊ��N7t�����?w�� �x1��f��Iz�C-Ȗ��K�^q�;���-W�DvT�7��8�Z�������� hK�(P:��Q- �8�n�Z���܃e貾�<�1�YT<�,�����"�6{/ �?�͟��|1�:�#g��W�>$����d��J��d�B��=��jf[��%rE^��il:��B���x���Sּ�1հ��,�=��*�7 fcG��#q� �eh?��2�7�����,�!7x��6�n�LC�4x��},Geǝ�tC.��vS �F�43��zz\��;QYC,6����~;RYS/6���|2���5���v��T��i����������mlv��������&� �nRh^ejR�LG�f���? �ۉҬܦƩ��|��Ȱ����>3����!v��i�ʯ�>�v��オ�X3e���_1z�Kȗ\<������!�8���V��]��?b�k41�Re��T�q��mz��TiOʦ�Z��Xq���L������q"+���2ۨ��8}�&N7XU7Ap�d�X��~�׿��&4e�o�F��� �H����O���č�c�� 懴�6���͉��+)��v;j��ݷ�� �UV�� i��� j���Y9GdÒJ1��詞�����V?h��l����l�cGs�ځ�������y�Ac�����\V3�? �� ܙg�>qH�S,�E�W�[�㺨�uch�⍸�O�}���a��>�q�6�n6����N6�q������N ! 1AQaq�0@����"2BRb�#Pr���3C`��Scst���$4D���%Td�� ?���N����a��3��m���C���w��������xA�m�q�m���m������$����4n淿t'��C"w��zU=D�\R+w�p+Y�T�&�պ@��ƃ��3ޯ?�Aﶂ��aŘ���@-�����Q�=���9D��ռ�ѻ@��M�V��P��܅�G5�f�Y<�u=,EC)�<�Fy'�"�&�չ�X~f��l�KԆV��?�� �W�N����=(� �;���{�r����ٌ�Y���h{�١������jW����P���Tc�����X�K�r��}���w�R��%��?���E��m�� �Y�q|����\lEE4���r���}�lsI�Y������f�$�=�d�yO����p�����yBj8jU�o�/�S��?�U��*������ˍ�0������u�q�m [�?f����a�� )Q�>����6#������� ?����0UQ����,IX���(6ڵ[�DI�MNލ�c&���υ�j\��X�R|,4��� j������T�hA�e��^���d���b<����n�� �즇�=!���3�^�`j�h�ȓr��jẕ�c�,ٞX����-����a�ﶔ���#�$��]w�O��Ӫ�1y%��L�Y<�wg#�ǝ�̗`�x�xa�t�w��»1���o7o5��>�m뭛C���Uƃߜ}�C���y1Xνm�F8�jI���]����H���ۺиE@I�i;r�8ӭ����V�F�Շ| ��&?�3|x�B�MuS�Ge�=Ӕ�#BE5G�����Y!z��_e��q�р/W>|-�Ci߇�t�1ޯќd�R3�u��g�=0 5��[?�#͏��q�cf���H��{ ?u�=?�?ǯ���}Z��z���hmΔ�BFTW�����<�q�(v� ��!��z���iW]*�J�V�z��gX֧A�q�&��/w���u�gYӘa���; �i=����g:��?2�dž6�ى�k�4�>�Pxs����}������G�9��3 ���)gG�R<>r h�$��'nc�h�P��Bj��J�ҧH� -��N1���N��?��~��}-q!=��_2hc�M��l�vY%UE�@|�v����M2�.Y[|y�"Eï��K�ZF,�ɯ?,q�?v�M 80jx�"�;�9vk�����+ ֧�� �ȺU��?�%�vcV��mA�6��Qg^M����A}�3�nl� QRN�l8�kkn�'�����(��M�7m9و�q���%ޟ���*h$Zk"��$�9��: �?U8�Sl��,,|ɒ��xH(ѷ����Gn�/Q�4�P��G�%��Ա8�N��!� �&�7�;���eKM7�4��9R/%����l�c>�x;������>��C�:�����t��h?aKX�bhe�ᜋ^�$�Iհ �hr7%F$�E��Fd���t��5���+�(M6�t����Ü�UU|zW�=a�Ts�Tg������dqP�Q����b'�m���1{|Y����X�N��b �P~��F^F:����k6�"�j!�� �I�r�`��1&�-$�Bevk:y���#yw��I0��x��=D�4��tU���P�ZH��ڠ底taP��6����b>�xa����Q�#� WeF��ŮNj�p�J* mQ�N����*I�-*�ȩ�F�g�3 �5��V�ʊ�ɮ�a��5F���O@{���NX��?����H�]3��1�Ri_u��������ѕ�� ����0��� F��~��:60�p�͈�S��qX#a�5>���`�o&+�<2�D����: �������ڝ�$�nP���*)�N�|y�Ej�F�5ټ�e���ihy�Z �>���k�bH�a�v��h�-#���!�Po=@k̆IEN��@��}Ll?j�O������߭�ʞ���Q|A07x���wt!xf���I2?Z��<ץ�T���cU�j��]��陎Ltl �}5�ϓ��$�,��O�mˊ�;�@O��jE��j(�ا,��LX���LO���Ц�90�O �.����a��nA���7������j4 ��W��_ٓ���zW�jcB������y՗+EM�)d���N�g6�y1_x��p�$Lv:��9�"z��p���ʙ$��^��JԼ*�ϭ����o���=x�Lj�6�J��u82�A�H�3$�ٕ@�=Vv�]�'�qEz�;I˼��)��=��ɯ���x �/�W(V���p�����$ �m�������u�����񶤑Oqˎ�T����r��㠚x�sr�GC��byp�G��1ߠ�w e�8�$⿄����/�M{*}��W�]˷.�CK\�ުx���/$�WPw���r� |i���&�}�{�X� �>��$-��l���?-z���g����lΆ���(F���h�vS*���b���߲ڡn,|)mrH[���a�3�ר�[1��3o_�U�3�TC�$��(�=�)0�kgP���� ��u�^=��4 �WYCҸ:��vQ�ר�X�à��tk�m,�t*��^�,�}D*� �"(�I��9R����>`�`��[~Q]�#af��i6l��8���6�:,s�s�N6�j"�A4���IuQ��6E,�GnH��zS�HO�uk�5$�I�4��ؤ�Q9�@��C����wp�BGv[]�u�Ov���0I4���\��y�����Q�Ѹ��~>Z��8�T��a��q�ޣ;z��a���/��S��I:�ܫ_�|������>=Z����8:�S��U�I�J��"IY���8%b8���H��:�QO�6�;7�I�S��J��ҌAά3��>c���E+&jf$eC+�z�;��V����� �r���ʺ������my�e���aQ�f&��6�ND��.:��NT�vm�<- u���ǝ\MvZY�N�NT��-A�>jr!S��n�O 1�3�Ns�%�3D@���`������ܟ 1�^c<���� �a�ɽ�̲�Xë#�w�|y�cW�=�9I*H8�p�^(4���՗�k��arOcW�tO�\�ƍR��8����'�K���I�Q�����?5�>[�}��yU�ײ -h��=��% q�ThG�2�)���"ו3]�!kB��*p�FDl�A���,�eEi�H�f�Ps�����5�H:�Փ~�H�0Dت�D�I����h�F3�������c��2���E��9�H��5�zԑ�ʚ�i�X�=:m�xg�hd(�v����׊�9iS��O��d@0ڽ���:�p�5�h-��t�&���X�q�ӕ,��ie�|���7A�2���O%P��E��htj��Y1��w�Ѓ!����  ���� ࢽ��My�7�\�a�@�ţ�J �4�Ȼ�F�@o�̒?4�wx��)��]�P��~�����u�����5�����7X ��9��^ܩ�U;Iꭆ 5 �������eK2�7(�{|��Y׎ �V��\"���Z�1� Z�����}��(�Ǝ"�1S���_�vE30>���p;� ΝD��%x�W�?W?v����o�^V�i�d��r[��/&>�~`�9Wh��y�;���R��� ;;ɮT��?����r$�g1�K����A��C��c��K��l:�'��3 c�ﳯ*"t8�~l��)���m��+U,z��`(�>yJ�?����h>��]��v��ЍG*�{`��;y]��I�T� ;c��NU�fo¾h���/$���|NS���1�S�"�H��V���T���4��uhǜ�]�v;���5�͠x��'C\�SBpl���h}�N����� A�Bx���%��ޭ�l��/����T��w�ʽ]D�=����K���ž�r㻠l4�S�O?=�k �M:� ��c�C�a�#ha���)�ѐxc�s���gP�iG��{+���x���Q���I= �� z��ԫ+ �8"�k�ñ�j=|����c ��y��CF��/��*9ж�h{ �?4�o� ��k�m�Q�N�x��;�Y��4膚�a�w?�6�>e]�����Q�r�:����g�,i"�����ԩA�*M�<�G��b�if��l^M��5� �Ҩ�{����6J��ZJ�����P�*�����Y���ݛu�_4�9�I8�7���������,^ToR���m4�H��?�N�S�ѕw��/S��甍�@�9H�S�T��t�ƻ���ʒU��*{Xs�@����f�����֒Li�K{H�w^���������Ϥm�tq���s� ���ք��f:��o~s��g�r��ט� �S�ѱC�e]�x���a��) ���(b-$(�j>�7q�B?ӕ�F��hV25r[7 Y� }L�R��}����*sg+��x�r�2�U=�*'WS��ZDW]�WǞ�<��叓���{�$�9Ou4��y�90-�1�'*D`�c�^o?(�9��u���ݐ��'PI&� f�Jݮ�������:wS����jfP1F:X �H�9dԯ���˝[�_54 �}*;@�ܨ�� ð�yn�T���?�ןd�#���4rG�ͨ��H�1�|-#���Mr�S3��G�3�����)�.᧏3v�z֑��r����$G"�`j �1t��x0<Ɔ�Wh6�y�6��,œ�Ga��gA����y��b��)��h�D��ß�_�m��ü �gG;��e�v��ݝ�nQ� ��C����-�*��o���y�a��M��I�>�<���]obD��"�:���G�A��-\%LT�8���c�)��+y76���o�Q�#*{�(F�⽕�y����=���rW�\p���۩�c���A���^e6��K������ʐ�cVf5$�'->���ՉN"���F�"�UQ@�f��Gb~��#�&�M=��8�ט�JNu9��D��[̤�s�o�~������ G��9T�tW^g5y$b��Y'��س�Ǵ�=��U-2 #�MC�t(�i� �lj�@Q 5�̣i�*�O����s�x�K�f��}\��M{E�V�{�υ��Ƈ�����);�H����I��fe�Lȣr�2��>��W�I�Ȃ6������i��k�� �5�YOxȺ����>��Y�f5'��|��H+��98pj�n�.O�y�������jY��~��i�w'������l�;�s�2��Y��:'lg�ꥴ)o#'Sa�a�K��Z� �m��}�`169�n���"���x��I ��*+� }F<��cГ���F�P�������ֹ*�PqX�x۩��,� ��N�� �4<-����%����:��7����W���u�`����� $�?�I��&����o��o��`v�>��P��"��l���4��5'�Z�gE���8���?��[�X�7(��.Q�-��*���ތL@̲����v��.5���[��=�t\+�CNܛ��,g�SQnH����}*F�G16���&:�t��4ُ"A��̣��$�b �|����#rs��a�����T�� ]�<�j��BS�('$�ɻ� �wP;�/�n��?�ݜ��x�F��yUn�~mL*-�������Xf�wd^�a�}��f�,=t�׵i�.2/wpN�Ep8�OР���•��R�FJ� 55TZ��T �ɭ�<��]��/�0�r�@�f��V��V����Nz�G��^���7hZi����k��3�,kN�e|�vg�1{9]_i��X5y7� 8e]�U����'�-2,���e"����]ot�I��Y_��n�(JҼ��1�O ]bXc���Nu�No��pS���Q_���_�?i�~�x h5d'�(qw52] ��'ޤ�q��o1�R!���`ywy�A4u���h<קy���\[~�4�\ X�Wt/� 6�����n�F�a8��f���z �3$�t(���q��q�x��^�XWeN'p<-v�!�{�(>ӽDP7��ո0�y)�e$ٕv�Ih'Q�EA�m*�H��RI��=:��� ���4牢) �%_iN�ݧ�l]� �Nt���G��H�L��� ɱ�g<���1V�,�J~�ٹ�"K��Q�� 9�HS�9�?@��k����r�;we݁�]I�!{ �@�G�[�"��`���J:�n]�{�cA�E����V��ʆ���#��U9�6����j�#Y�m\��q�e4h�B�7��C�������d<�?J����1g:ٳ���=Y���D�p�ц� ׈ǔ��1�]26؜oS�'��9�V�FVu�P�h�9�xc�oq�X��p�o�5��Ա5$�9W�V(�[Ak�aY錎qf;�'�[�|���b�6�Ck��)��#a#a˙��8���=äh�4��2��C��4tm^ �n'c���]GQ$[Wҿ��i���vN�{Fu ��1�gx��1┷���N�m��{j-,��x�� Ūm�ЧS�[�s���Gna���䑴�� x�p 8<������97�Q���ϴ�v�aϚG��Rt�Һ׈�f^\r��WH�JU�7Z���y)�vg=����n��4�_)y��D'y�6�]�c�5̪�\� �PF�k����&�c;��cq�$~T�7j ���nç]�<�g ":�to�t}�159�<�/�8������m�b�K#g'I'.W�����6��I/��>v��\�MN��g���m�A�yQL�4u�Lj�j9��#44�t��l^�}L����n��R��!��t��±]��r��h6ٍ>�yҏ�N��fU�� ���� Fm@�8}�/u��jb9������he:A�y�ծw��GpΧh�5����l}�3p468��)U��d��c����;Us/�֔�YX�1�O2��uq�s��`hwg�r~�{ R��mhN��؎*q 42�*th��>�#���E����#��Hv�O����q�}�����6�e��\�,Wk�#���X��b>��p}�դ��3���T5��†��6��[��@�P�y*n��|'f�֧>�lư΂�̺����SU�'*�q�p�_S�����M�� '��c�6�����m�� ySʨ;M��r���Ƌ�m�Kxo,���Gm�P��A�G�:��i��w�9�}M(�^�V��$ǒ�ѽ�9���|���� �a����J�SQ�a���r�B;����}���ٻ֢�2�%U���c�#�g���N�a�ݕ�'�v�[�OY'��3L�3�;,p�]@�S��{ls��X�'���c�jw�k'a�.��}�}&�� �dP�*�bK=ɍ!����;3n�gΊU�ߴmt�'*{,=SzfD� A��ko~�G�aoq�_mi}#�m�������P�Xhύ����mxǍ�΂���巿zf��Q���c���|kc�����?���W��Y�$���_Lv����l߶��c���`?����l�j�ݲˏ!V��6����U�Ђ(A���4y)H���p�Z_�x��>���e��R��$�/�`^'3qˏ�-&Q�=?��CFVR �D�fV�9��{�8g�������n�h�(P"��6�[�D���< E�����~0<@�`�G�6����Hг�cc�� �c�K.5��D��d�B���`?�XQ��2��ٿyqo&+�1^� DW�0�ꊩ���G�#��Q�nL3��c���������/��x ��1�1[y�x�პCW��C�c�UĨ80�m�e�4.{�m��u���I=��f�����0QRls9���f���������9���~f�����Ǩ��a�"@�8���ȁ�Q����#c�ic������G��$���G���r/$W�(��W���V�"��m�7�[m�A�m����bo��D� j����۳� l���^�k�h׽����� ��#� iXn�v��eT�k�a�^Y�4�BN��ĕ��0 !01@Q"2AaPq3BR������?���@4�Q�����T3,���㺠�W�[=JK�Ϟ���2�r^7��vc�:�9 �E�ߴ�w�S#d���Ix��u��:��Hp��9E!�� V 2;73|F��9Y���*ʬ�F��D����u&���y؟��^EA��A��(ɩ���^��GV:ݜDy�`��Jr29ܾ�㝉��[���E;Fzx��YG��U�e�Y�C���� ����v-tx����I�sם�Ę�q��Eb�+P\ :>�i�C'�;�����k|z�رn�y]�#ǿb��Q��������w�����(�r|ӹs��[�D��2v-%��@;�8<a���[\o[ϧw��I!��*0�krs)�[�J9^��ʜ��p1)� "��/_>��o��<1����A�E�y^�C��`�x1'ܣn�p��s`l���fQ��):�l����b>�Me�jH^?�kl3(�z:���1ŠK&?Q�~�{�ٺ�h�y���/�[��V�|6��}�KbX����mn[-��7�5q�94�������dm���c^���h� X��5��<�eޘ>G���-�}�دB�ޟ� ��|�rt�M��V+�]�c?�-#ڛ��^ǂ}���Lkr���O��u�>�-D�ry� D?:ޞ�U��ǜ�7�V��?瓮�"�#���r��չģVR;�n���/_� ؉v�ݶe5d�b9��/O��009�G���5n�W����JpA�*�r9�>�1��.[t���s�F���nQ� V 77R�]�ɫ8����_0<՜�IF�u(v��4��F�k�3��E)��N:��yڮe��P�`�1}�$WS��J�SQ�N�j�ٺ��޵�#l���ј(�5=��5�lǏmoW�v-�1����v,W�mn��߀$x�<����v�j(����c]��@#��1������Ǔ���o'��u+����;G�#�޸��v-lη��/(`i⣍Pm^���ԯ̾9Z��F��������n��1��� ��]�[��)�'������:�֪�W��FC����� �B9،!?���]��V��A�Վ�M��b�w��G F>_DȬ0¤�#�QR�[V��kz���m�w�"��9ZG�7'[��=�Q����j8R?�zf�\a�=��O�U����*oB�A�|G���2�54 �p��.w7� �� ��&������ξxGHp� B%��$g�����t�Џ򤵍z���HN�u�Я�-�'4��0��;_��3 !01"@AQa2Pq#3BR������?��ʩca��en��^��8���<�u#��m*08r��y�N"�<�Ѳ0��@\�p��� �����Kv�D��J8�Fҽ� �f�Y��-m�ybX�NP����}�!*8t(�OqѢ��Q�wW�K��ZD��Δ^e��!� ��B�K��p~�����e*l}z#9ң�k���q#�Ft�o��S�R����-�w�!�S���Ӥß|M�l޶V��!eˈ�8Y���c�ЮM2��tk���� ������J�fS����Ö*i/2�����n]�k�\���|4yX�8��U�P.���Ы[���l��@"�t�<������5�lF���vU�����W��W��;�b�cД^6[#7@vU�xgZv��F�6��Q,K�v��� �+Ъ��n��Ǣ��Ft���8��0��c�@�!�Zq s�v�t�;#](B��-�nῃ~���3g������5�J�%���O������n�kB�ĺ�.r��+���#�N$?�q�/�s�6��p��a����a��J/��M�8��6�ܰ"�*������ɗud"\w���aT(����[��F��U՛����RT�b���n�*��6���O��SJ�.�ij<�v�MT��R\c��5l�sZB>F��<7�;EA��{��E���Ö��1U/�#��d1�a�n.1ě����0�ʾR�h��|�R��Ao�3�m3 ��%�� ���28Q� ��y��φ���H�To�7�lW>����#i`�q���c����a��� �m,B�-j����݋�'mR1Ήt�>��V��p���s�0IbI�C.���1R�ea�����]H�6����������4B>��o��](��$B���m�����a�!=��?�B� K�Ǿ+�Ծ"�n���K��*��+��[T#�{E�J�S����Q�����s�5�:�U�\wĐ�f�3����܆&�)����I���Ԇw��E T�lrTf6Q|R�h:��[K�� �z��c֧�G�C��%\��_�a�84��HcO�bi��ؖV��7H �)*ģK~Xhչ0��4?�0��� �E<���}3���#���u�?�� ��|g�S�6ꊤ�|�I#Hڛ� �ա��w�X��9��7���Ŀ%�SL��y6č��|�F�a 8���b��$�sק�h���b9RAu7�˨p�Č�_\*w��묦��F ����4D~�f����|(�"m���NK��i�S�>�$d7SlA��/�²����SL��|6N�}���S�˯���g��]6��; �#�.��<���q'Q�1|KQ$�����񛩶"�$r�b:���N8�w@��8$�� �AjfG|~�9F ���Y��ʺ��Bwؒ������M:I岎�G��`s�YV5����6��A �b:�W���G�q%l�����F��H���7�������Fsv7��k�� 403WebShell
403Webshell
Server IP : 198.54.115.249  /  Your IP : 216.73.216.228
Web Server : LiteSpeed
System : Linux server66.web-hosting.com 4.18.0-553.44.1.lve.el8.x86_64 #1 SMP Thu Mar 13 14:29:12 UTC 2025 x86_64
User : digigcnj ( 11081)
PHP Version : 8.0.30
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /opt/alt/ruby21/lib64/ruby/2.1.0/rdoc/parser/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /opt/alt/ruby21/lib64/ruby/2.1.0/rdoc/parser/c.rb
require 'tsort'

##
# RDoc::Parser::C attempts to parse C extension files.  It looks for
# the standard patterns that you find in extensions: <tt>rb_define_class,
# rb_define_method</tt> and so on.  It tries to find the corresponding
# C source for the methods and extract comments, but if we fail
# we don't worry too much.
#
# The comments associated with a Ruby method are extracted from the C
# comment block associated with the routine that _implements_ that
# method, that is to say the method whose name is given in the
# <tt>rb_define_method</tt> call. For example, you might write:
#
#   /*
#    * Returns a new array that is a one-dimensional flattening of this
#    * array (recursively). That is, for every element that is an array,
#    * extract its elements into the new array.
#    *
#    *    s = [ 1, 2, 3 ]           #=> [1, 2, 3]
#    *    t = [ 4, 5, 6, [7, 8] ]   #=> [4, 5, 6, [7, 8]]
#    *    a = [ s, t, 9, 10 ]       #=> [[1, 2, 3], [4, 5, 6, [7, 8]], 9, 10]
#    *    a.flatten                 #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
#    */
#    static VALUE
#    rb_ary_flatten(ary)
#        VALUE ary;
#    {
#        ary = rb_obj_dup(ary);
#        rb_ary_flatten_bang(ary);
#        return ary;
#    }
#
#    ...
#
#    void
#    Init_Array()
#    {
#      ...
#      rb_define_method(rb_cArray, "flatten", rb_ary_flatten, 0);
#
# Here RDoc will determine from the rb_define_method line that there's a
# method called "flatten" in class Array, and will look for the implementation
# in the method rb_ary_flatten. It will then use the comment from that
# method in the HTML output. This method must be in the same source file
# as the rb_define_method.
#
# The comment blocks may include special directives:
#
# [Document-class: +name+]
#   Documentation for the named class.
#
# [Document-module: +name+]
#   Documentation for the named module.
#
# [Document-const: +name+]
#   Documentation for the named +rb_define_const+.
#
#   Constant values can be supplied on the first line of the comment like so:
#
#     /* 300: The highest possible score in bowling */
#     rb_define_const(cFoo, "PERFECT", INT2FIX(300));
#
#   The value can contain internal colons so long as they are escaped with a \
#
# [Document-global: +name+]
#   Documentation for the named +rb_define_global_const+
#
# [Document-variable: +name+]
#   Documentation for the named +rb_define_variable+
#
# [Document-method: +method_name+]
#   Documentation for the named method.  Use this when the method name is
#   unambiguous.
#
# [Document-method: <tt>ClassName::method_name<tt>]
#   Documentation for a singleton method in the given class.  Use this when
#   the method name alone is ambiguous.
#
# [Document-method: <tt>ClassName#method_name<tt>]
#   Documentation for a instance method in the given class.  Use this when the
#   method name alone is ambiguous.
#
# [Document-attr: +name+]
#   Documentation for the named attribute.
#
# [call-seq:  <i>text up to an empty line</i>]
#   Because C source doesn't give descriptive names to Ruby-level parameters,
#   you need to document the calling sequence explicitly
#
# In addition, RDoc assumes by default that the C method implementing a
# Ruby function is in the same source file as the rb_define_method call.
# If this isn't the case, add the comment:
#
#   rb_define_method(....);  // in filename
#
# As an example, we might have an extension that defines multiple classes
# in its Init_xxx method. We could document them using
#
#   /*
#    * Document-class:  MyClass
#    *
#    * Encapsulate the writing and reading of the configuration
#    * file. ...
#    */
#
#   /*
#    * Document-method: read_value
#    *
#    * call-seq:
#    *   cfg.read_value(key)            -> value
#    *   cfg.read_value(key} { |key| }  -> value
#    *
#    * Return the value corresponding to +key+ from the configuration.
#    * In the second form, if the key isn't found, invoke the
#    * block and return its value.
#    */

class RDoc::Parser::C < RDoc::Parser

  parse_files_matching(/\.(?:([CcHh])\1?|c([+xp])\2|y)\z/)

  include RDoc::Text

  ##
  # Maps C variable names to names of Ruby classes or modules

  attr_reader :classes

  ##
  # C file the parser is parsing

  attr_accessor :content

  ##
  # Dependencies from a missing enclosing class to the classes in
  # missing_dependencies that depend upon it.

  attr_reader :enclosure_dependencies

  ##
  # Maps C variable names to names of Ruby classes (and singleton classes)

  attr_reader :known_classes

  ##
  # Classes found while parsing the C file that were not yet registered due to
  # a missing enclosing class.  These are processed by do_missing

  attr_reader :missing_dependencies

  ##
  # Maps C variable names to names of Ruby singleton classes

  attr_reader :singleton_classes

  ##
  # The TopLevel items in the parsed file belong to

  attr_reader :top_level

  ##
  # Prepares for parsing a C file.  See RDoc::Parser#initialize for details on
  # the arguments.

  def initialize top_level, file_name, content, options, stats
    super

    @known_classes = RDoc::KNOWN_CLASSES.dup
    @content = handle_tab_width handle_ifdefs_in @content
    @file_dir = File.dirname @file_name

    @classes           = load_variable_map :c_class_variables
    @singleton_classes = load_variable_map :c_singleton_class_variables

    # class_variable => { function => [method, ...] }
    @methods = Hash.new { |h, f| h[f] = Hash.new { |i, m| i[m] = [] } }

    # missing variable => [handle_class_module arguments]
    @missing_dependencies = {}

    # missing enclosure variable => [dependent handle_class_module arguments]
    @enclosure_dependencies = Hash.new { |h, k| h[k] = [] }
    @enclosure_dependencies.instance_variable_set :@missing_dependencies,
                                                  @missing_dependencies

    @enclosure_dependencies.extend TSort

    def @enclosure_dependencies.tsort_each_node &block
      each_key(&block)
    rescue TSort::Cyclic => e
      cycle_vars = e.message.scan(/"(.*?)"/).flatten

      cycle = cycle_vars.sort.map do |var_name|
        delete var_name

        var_name, type, mod_name, = @missing_dependencies[var_name]

        "#{type} #{mod_name} (#{var_name})"
      end.join ', '

      warn "Unable to create #{cycle} due to a cyclic class or module creation"

      retry
    end

    def @enclosure_dependencies.tsort_each_child node, &block
      fetch(node, []).each(&block)
    end
  end

  ##
  # Removes duplicate call-seq entries for methods using the same
  # implementation.

  def deduplicate_call_seq
    @methods.each do |var_name, functions|
      class_name = @known_classes[var_name]
      class_obj  = find_class var_name, class_name

      functions.each_value do |method_names|
        next if method_names.length == 1

        method_names.each do |method_name|
          deduplicate_method_name class_obj, method_name
        end
      end
    end
  end

  ##
  # If two ruby methods share a C implementation (and comment) this
  # deduplicates the examples in the call_seq for the method to reduce
  # confusion in the output.

  def deduplicate_method_name class_obj, method_name # :nodoc:
    return unless
      method = class_obj.method_list.find { |m| m.name == method_name }
    return unless call_seq = method.call_seq

    method_name = method_name[0, 1] if method_name =~ /\A\[/

    entries = call_seq.split "\n"

    matching = entries.select do |entry|
      entry =~ /^\w*\.?#{Regexp.escape method_name}/ or
        entry =~ /\s#{Regexp.escape method_name}\s/
    end

    method.call_seq = matching.join "\n"
  end

  ##
  # Scans #content for rb_define_alias

  def do_aliases
    @content.scan(/rb_define_alias\s*\(
                   \s*(\w+),
                   \s*"(.+?)",
                   \s*"(.+?)"
                   \s*\)/xm) do |var_name, new_name, old_name|
      class_name = @known_classes[var_name]

      unless class_name then
        @options.warn "Enclosing class or module %p for alias %s %s is not known" % [
          var_name, new_name, old_name]
        next
      end

      class_obj = find_class var_name, class_name

      al = RDoc::Alias.new '', old_name, new_name, ''
      al.singleton = @singleton_classes.key? var_name

      comment = find_alias_comment var_name, new_name, old_name

      comment.normalize

      al.comment = comment

      al.record_location @top_level

      class_obj.add_alias al
      @stats.add_alias al
    end
  end

  ##
  # Scans #content for rb_attr and rb_define_attr

  def do_attrs
    @content.scan(/rb_attr\s*\(
                   \s*(\w+),
                   \s*([\w"()]+),
                   \s*([01]),
                   \s*([01]),
                   \s*\w+\);/xm) do |var_name, attr_name, read, write|
      handle_attr var_name, attr_name, read, write
    end

    @content.scan(%r%rb_define_attr\(
                             \s*([\w\.]+),
                             \s*"([^"]+)",
                             \s*(\d+),
                             \s*(\d+)\s*\);
                %xm) do |var_name, attr_name, read, write|
      handle_attr var_name, attr_name, read, write
    end
  end

  ##
  # Scans #content for boot_defclass

  def do_boot_defclass
    @content.scan(/(\w+)\s*=\s*boot_defclass\s*\(\s*"(\w+?)",\s*(\w+?)\s*\)/) do
      |var_name, class_name, parent|
      parent = nil if parent == "0"
      handle_class_module(var_name, :class, class_name, parent, nil)
    end
  end

  ##
  # Scans #content for rb_define_class, boot_defclass, rb_define_class_under
  # and rb_singleton_class

  def do_classes
    do_boot_defclass
    do_define_class
    do_define_class_under
    do_singleton_class
    do_struct_define_without_accessor
  end

  ##
  # Scans #content for rb_define_variable, rb_define_readonly_variable,
  # rb_define_const and rb_define_global_const

  def do_constants
    @content.scan(%r%\Wrb_define_
                   ( variable          |
                     readonly_variable |
                     const             |
                     global_const        )
               \s*\(
                 (?:\s*(\w+),)?
                 \s*"(\w+)",
                 \s*(.*?)\s*\)\s*;
                 %xm) do |type, var_name, const_name, definition|
      var_name = "rb_cObject" if !var_name or var_name == "rb_mKernel"
      handle_constants type, var_name, const_name, definition
    end

    @content.scan(%r%
                  \Wrb_curses_define_const
                  \s*\(
                    \s*
                    (\w+)
                    \s*
                  \)
                  \s*;%xm) do |consts|
      const = consts.first

      handle_constants 'const', 'mCurses', const, "UINT2NUM(#{const})"
    end

    @content.scan(%r%
                  \Wrb_file_const
                  \s*\(
                    \s*
                    "([^"]+)",
                    \s*
                    (.*?)
                    \s*
                  \)
                  \s*;%xm) do |name, value|
      handle_constants 'const', 'rb_mFConst', name, value
    end
  end

  ##
  # Scans #content for rb_define_class

  def do_define_class
    # The '.' lets us handle SWIG-generated files
    @content.scan(/([\w\.]+)\s* = \s*rb_define_class\s*
              \(
                 \s*"(\w+)",
                 \s*(\w+)\s*
              \)/mx) do |var_name, class_name, parent|
      handle_class_module(var_name, :class, class_name, parent, nil)
    end
  end

  ##
  # Scans #content for rb_define_class_under

  def do_define_class_under
    @content.scan(/([\w\.]+)\s* =                  # var_name
                   \s*rb_define_class_under\s*
                   \(
                     \s* (\w+),                    # under
                     \s* "(\w+)",                  # class_name
                     \s*
                     (?:
                       ([\w\*\s\(\)\.\->]+) |      # parent_name
                       rb_path2class\("([\w:]+)"\) # path
                     )
                     \s*
                   \)
                  /mx) do |var_name, under, class_name, parent_name, path|
      parent = path || parent_name

      handle_class_module var_name, :class, class_name, parent, under
    end
  end

  ##
  # Scans #content for rb_define_module

  def do_define_module
    @content.scan(/(\w+)\s* = \s*rb_define_module\s*\(\s*"(\w+)"\s*\)/mx) do
      |var_name, class_name|
      handle_class_module(var_name, :module, class_name, nil, nil)
    end
  end

  ##
  # Scans #content for rb_define_module_under

  def do_define_module_under
    @content.scan(/(\w+)\s* = \s*rb_define_module_under\s*
              \(
                 \s*(\w+),
                 \s*"(\w+)"
              \s*\)/mx) do |var_name, in_module, class_name|
      handle_class_module(var_name, :module, class_name, nil, in_module)
    end
  end

  ##
  # Scans #content for rb_include_module

  def do_includes
    @content.scan(/rb_include_module\s*\(\s*(\w+?),\s*(\w+?)\s*\)/) do |c,m|
      next unless cls = @classes[c]
      m = @known_classes[m] || m

      comment = RDoc::Comment.new '', @top_level
      incl = cls.add_include RDoc::Include.new(m, comment)
      incl.record_location @top_level
    end
  end

  ##
  # Scans #content for rb_define_method, rb_define_singleton_method,
  # rb_define_module_function, rb_define_private_method,
  # rb_define_global_function and define_filetest_function

  def do_methods
    @content.scan(%r%rb_define_
                   (
                      singleton_method |
                      method           |
                      module_function  |
                      private_method
                   )
                   \s*\(\s*([\w\.]+),
                     \s*"([^"]+)",
                     \s*(?:RUBY_METHOD_FUNC\(|VALUEFUNC\(|\(METHOD\))?(\w+)\)?,
                     \s*(-?\w+)\s*\)
                   (?:;\s*/[*/]\s+in\s+(\w+?\.(?:cpp|c|y)))?
                 %xm) do |type, var_name, meth_name, function, param_count, source_file|

      # Ignore top-object and weird struct.c dynamic stuff
      next if var_name == "ruby_top_self"
      next if var_name == "nstr"

      var_name = "rb_cObject" if var_name == "rb_mKernel"
      handle_method(type, var_name, meth_name, function, param_count,
                    source_file)
    end

    @content.scan(%r%rb_define_global_function\s*\(
                             \s*"([^"]+)",
                             \s*(?:RUBY_METHOD_FUNC\(|VALUEFUNC\()?(\w+)\)?,
                             \s*(-?\w+)\s*\)
                (?:;\s*/[*/]\s+in\s+(\w+?\.[cy]))?
                %xm) do |meth_name, function, param_count, source_file|
      handle_method("method", "rb_mKernel", meth_name, function, param_count,
                    source_file)
    end

    @content.scan(/define_filetest_function\s*\(
                     \s*"([^"]+)",
                     \s*(?:RUBY_METHOD_FUNC\(|VALUEFUNC\()?(\w+)\)?,
                     \s*(-?\w+)\s*\)/xm) do |meth_name, function, param_count|

      handle_method("method", "rb_mFileTest", meth_name, function, param_count)
      handle_method("singleton_method", "rb_cFile", meth_name, function,
                    param_count)
    end
  end

  ##
  # Creates classes and module that were missing were defined due to the file
  # order being different than the declaration order.

  def do_missing
    return if @missing_dependencies.empty?

    @enclosure_dependencies.tsort.each do |in_module|
      arguments = @missing_dependencies.delete in_module

      next unless arguments # dependency on existing class

      handle_class_module(*arguments)
    end
  end

  ##
  # Scans #content for rb_define_module and rb_define_module_under

  def do_modules
    do_define_module
    do_define_module_under
  end

  ##
  # Scans #content for rb_singleton_class

  def do_singleton_class
    @content.scan(/([\w\.]+)\s* = \s*rb_singleton_class\s*
                  \(
                    \s*(\w+)
                  \s*\)/mx) do |sclass_var, class_var|
      handle_singleton sclass_var, class_var
    end
  end

  ##
  # Scans #content for struct_define_without_accessor

  def do_struct_define_without_accessor
    @content.scan(/([\w\.]+)\s* = \s*rb_struct_define_without_accessor\s*
              \(
                 \s*"(\w+)",  # Class name
                 \s*(\w+),    # Parent class
                 \s*\w+,      # Allocation function
                 (\s*"\w+",)* # Attributes
                 \s*NULL
              \)/mx) do |var_name, class_name, parent|
      handle_class_module(var_name, :class, class_name, parent, nil)
    end
  end

  ##
  # Finds the comment for an alias on +class_name+ from +new_name+ to
  # +old_name+

  def find_alias_comment class_name, new_name, old_name
    content =~ %r%((?>/\*.*?\*/\s+))
                  rb_define_alias\(\s*#{Regexp.escape class_name}\s*,
                                   \s*"#{Regexp.escape new_name}"\s*,
                                   \s*"#{Regexp.escape old_name}"\s*\);%xm

    RDoc::Comment.new($1 || '', @top_level)
  end

  ##
  # Finds a comment for rb_define_attr, rb_attr or Document-attr.
  #
  # +var_name+ is the C class variable the attribute is defined on.
  # +attr_name+ is the attribute's name.
  #
  # +read+ and +write+ are the read/write flags ('1' or '0').  Either both or
  # neither must be provided.

  def find_attr_comment var_name, attr_name, read = nil, write = nil
    attr_name = Regexp.escape attr_name

    rw = if read and write then
           /\s*#{read}\s*,\s*#{write}\s*/xm
         else
           /.*?/m
         end

    comment = if @content =~ %r%((?>/\*.*?\*/\s+))
                                rb_define_attr\((?:\s*#{var_name},)?\s*
                                                "#{attr_name}"\s*,
                                                #{rw}\)\s*;%xm then
                $1
              elsif @content =~ %r%((?>/\*.*?\*/\s+))
                                   rb_attr\(\s*#{var_name}\s*,
                                            \s*#{attr_name}\s*,
                                            #{rw},.*?\)\s*;%xm then
                $1
              elsif @content =~ %r%Document-attr:\s#{attr_name}\s*?\n
                                   ((?>.*?\*/))%xm then
                $1
              else
                ''
              end

    RDoc::Comment.new comment, @top_level
  end

  ##
  # Find the C code corresponding to a Ruby method

  def find_body class_name, meth_name, meth_obj, file_content, quiet = false
    case file_content
    when %r%((?>/\*.*?\*/\s*)?)
            ((?:(?:static|SWIGINTERN)\s+)?
             (?:intern\s+)?VALUE\s+#{meth_name}
             \s*(\([^)]*\))([^;]|$))%xm then
      comment = RDoc::Comment.new $1, @top_level
      body = $2
      offset, = $~.offset(2)

      comment.remove_private if comment

      # try to find the whole body
      body = $& if /#{Regexp.escape body}[^(]*?\{.*?^\}/m =~ file_content

      # The comment block may have been overridden with a 'Document-method'
      # block. This happens in the interpreter when multiple methods are
      # vectored through to the same C method but those methods are logically
      # distinct (for example Kernel.hash and Kernel.object_id share the same
      # implementation

      override_comment = find_override_comment class_name, meth_obj
      comment = override_comment if override_comment

      comment.normalize
      find_modifiers comment, meth_obj if comment

      #meth_obj.params = params
      meth_obj.start_collecting_tokens
      tk = RDoc::RubyToken::Token.new nil, 1, 1
      tk.set_text body
      meth_obj.add_token tk
      meth_obj.comment = comment
      meth_obj.offset  = offset
      meth_obj.line    = file_content[0, offset].count("\n") + 1

      body
    when %r%((?>/\*.*?\*/\s*))^\s*(\#\s*define\s+#{meth_name}\s+(\w+))%m then
      comment = RDoc::Comment.new $1, @top_level
      body = $2
      offset = $~.offset(2).first

      find_body class_name, $3, meth_obj, file_content, true

      comment.normalize
      find_modifiers comment, meth_obj

      meth_obj.start_collecting_tokens
      tk = RDoc::RubyToken::Token.new nil, 1, 1
      tk.set_text body
      meth_obj.add_token tk
      meth_obj.comment = comment
      meth_obj.offset  = offset
      meth_obj.line    = file_content[0, offset].count("\n") + 1

      body
    when %r%^\s*\#\s*define\s+#{meth_name}\s+(\w+)%m then
      # with no comment we hope the aliased definition has it and use it's
      # definition

      body = find_body(class_name, $1, meth_obj, file_content, true)

      return body if body

      @options.warn "No definition for #{meth_name}"
      false
    else # No body, but might still have an override comment
      comment = find_override_comment class_name, meth_obj

      if comment then
        comment.normalize
        find_modifiers comment, meth_obj
        meth_obj.comment = comment

        ''
      else
        @options.warn "No definition for #{meth_name}"
        false
      end
    end
  end

  ##
  # Finds a RDoc::NormalClass or RDoc::NormalModule for +raw_name+

  def find_class(raw_name, name)
    unless @classes[raw_name]
      if raw_name =~ /^rb_m/
        container = @top_level.add_module RDoc::NormalModule, name
      else
        container = @top_level.add_class RDoc::NormalClass, name
      end

      container.record_location @top_level
      @classes[raw_name] = container
    end
    @classes[raw_name]
  end

  ##
  # Look for class or module documentation above Init_+class_name+(void),
  # in a Document-class +class_name+ (or module) comment or above an
  # rb_define_class (or module).  If a comment is supplied above a matching
  # Init_ and a rb_define_class the Init_ comment is used.
  #
  #   /*
  #    * This is a comment for Foo
  #    */
  #   Init_Foo(void) {
  #       VALUE cFoo = rb_define_class("Foo", rb_cObject);
  #   }
  #
  #   /*
  #    * Document-class: Foo
  #    * This is a comment for Foo
  #    */
  #   Init_foo(void) {
  #       VALUE cFoo = rb_define_class("Foo", rb_cObject);
  #   }
  #
  #   /*
  #    * This is a comment for Foo
  #    */
  #   VALUE cFoo = rb_define_class("Foo", rb_cObject);

  def find_class_comment class_name, class_mod
    comment = nil

    if @content =~ %r%
        ((?>/\*.*?\*/\s+))
        (static\s+)?
        void\s+
        Init_#{class_name}\s*(?:_\(\s*)?\(\s*(?:void\s*)?\)%xmi then
      comment = $1.sub(%r%Document-(?:class|module):\s+#{class_name}%, '')
    elsif @content =~ %r%Document-(?:class|module):\s+#{class_name}\s*?
                         (?:<\s+[:,\w]+)?\n((?>.*?\*/))%xm then
      comment = "/*\n#{$1}"
    elsif @content =~ %r%.*((?>/\*.*?\*/\s+))
                         ([\w\.\s]+\s* = \s+)?rb_define_(class|module).*?"(#{class_name})"%xm then
      comment = $1
    elsif @content =~ %r%.*((?>/\*.*?\*/\s+))
                         ([\w\.\s]+\s* = \s+)?rb_define_(class|module)_under.*?"(#{class_name.split('::').last})"%xm then
      comment = $1
    else
      comment = ''
    end

    comment = RDoc::Comment.new comment, @top_level
    comment.normalize

    look_for_directives_in class_mod, comment

    class_mod.add_comment comment, @top_level
  end

  ##
  # Finds a comment matching +type+ and +const_name+ either above the
  # comment or in the matching Document- section.

  def find_const_comment(type, const_name, class_name = nil)
    comment = if @content =~ %r%((?>^\s*/\*.*?\*/\s+))
                             rb_define_#{type}\((?:\s*(\w+),)?\s*
                                                "#{const_name}"\s*,
                                                .*?\)\s*;%xmi then
                $1
              elsif class_name and
                    @content =~ %r%Document-(?:const|global|variable):\s
                                   #{class_name}::#{const_name}
                                   \s*?\n((?>.*?\*/))%xm then
                "/*\n#{$1}"
              elsif @content =~ %r%Document-(?:const|global|variable):
                                   \s#{const_name}
                                   \s*?\n((?>.*?\*/))%xm then
                "/*\n#{$1}"
              else
                ''
              end

    RDoc::Comment.new comment, @top_level
  end

  ##
  # Handles modifiers in +comment+ and updates +meth_obj+ as appropriate.

  def find_modifiers comment, meth_obj
    comment.normalize
    comment.extract_call_seq meth_obj

    look_for_directives_in meth_obj, comment
  end

  ##
  # Finds a <tt>Document-method</tt> override for +meth_obj+ on +class_name+

  def find_override_comment class_name, meth_obj
    name = Regexp.escape meth_obj.name
    prefix = Regexp.escape meth_obj.name_prefix

    comment = if @content =~ %r%Document-method:
                                \s+#{class_name}#{prefix}#{name}
                                \s*?\n((?>.*?\*/))%xm then
                "/*#{$1}"
              elsif @content =~ %r%Document-method:
                                   \s#{name}\s*?\n((?>.*?\*/))%xm then
                "/*#{$1}"
              end

    return unless comment

    RDoc::Comment.new comment, @top_level
  end

  ##
  # Creates a new RDoc::Attr +attr_name+ on class +var_name+ that is either
  # +read+, +write+ or both

  def handle_attr(var_name, attr_name, read, write)
    rw = ''
    rw << 'R' if '1' == read
    rw << 'W' if '1' == write

    class_name = @known_classes[var_name]

    return unless class_name

    class_obj = find_class var_name, class_name

    return unless class_obj

    comment = find_attr_comment var_name, attr_name
    comment.normalize

    name = attr_name.gsub(/rb_intern\("([^"]+)"\)/, '\1')

    attr = RDoc::Attr.new '', name, rw, comment

    attr.record_location @top_level
    class_obj.add_attribute attr
    @stats.add_attribute attr
  end

  ##
  # Creates a new RDoc::NormalClass or RDoc::NormalModule based on +type+
  # named +class_name+ in +parent+ which was assigned to the C +var_name+.

  def handle_class_module(var_name, type, class_name, parent, in_module)
    parent_name = @known_classes[parent] || parent

    if in_module then
      enclosure = @classes[in_module] || @store.find_c_enclosure(in_module)

      if enclosure.nil? and enclosure = @known_classes[in_module] then
        enc_type = /^rb_m/ =~ in_module ? :module : :class
        handle_class_module in_module, enc_type, enclosure, nil, nil
        enclosure = @classes[in_module]
      end

      unless enclosure then
        @enclosure_dependencies[in_module] << var_name
        @missing_dependencies[var_name] =
          [var_name, type, class_name, parent, in_module]

        return
      end
    else
      enclosure = @top_level
    end

    if type == :class then
      full_name = if RDoc::ClassModule === enclosure then
                    enclosure.full_name + "::#{class_name}"
                  else
                    class_name
                  end

      if @content =~ %r%Document-class:\s+#{full_name}\s*<\s+([:,\w]+)% then
        parent_name = $1
      end

      cm = enclosure.add_class RDoc::NormalClass, class_name, parent_name
    else
      cm = enclosure.add_module RDoc::NormalModule, class_name
    end

    cm.record_location enclosure.top_level

    find_class_comment cm.full_name, cm

    case cm
    when RDoc::NormalClass
      @stats.add_class cm
    when RDoc::NormalModule
      @stats.add_module cm
    end

    @classes[var_name] = cm
    @known_classes[var_name] = cm.full_name
    @store.add_c_enclosure var_name, cm
  end

  ##
  # Adds constants.  By providing some_value: at the start of the comment you
  # can override the C value of the comment to give a friendly definition.
  #
  #   /* 300: The perfect score in bowling */
  #   rb_define_const(cFoo, "PERFECT", INT2FIX(300);
  #
  # Will override <tt>INT2FIX(300)</tt> with the value +300+ in the output
  # RDoc.  Values may include quotes and escaped colons (\:).

  def handle_constants(type, var_name, const_name, definition)
    class_name = @known_classes[var_name]

    return unless class_name

    class_obj = find_class var_name, class_name

    unless class_obj then
      @options.warn 'Enclosing class or module %p is not known' % [const_name]
      return
    end

    comment = find_const_comment type, const_name, class_name
    comment.normalize

    # In the case of rb_define_const, the definition and comment are in
    # "/* definition: comment */" form.  The literal ':' and '\' characters
    # can be escaped with a backslash.
    if type.downcase == 'const' then
      no_match, new_definition, new_comment = comment.text.split(/(\A.*):/)

      if no_match and no_match.empty? then
        if new_definition.empty? then # Default to literal C definition
          new_definition = definition
        else
          new_definition.gsub!("\:", ":")
          new_definition.gsub!("\\", '\\')
        end

        new_definition.sub!(/\A(\s+)/, '')

        new_comment = "#{$1}#{new_comment.lstrip}"

        new_comment = RDoc::Comment.new new_comment, @top_level

        con = RDoc::Constant.new const_name, new_definition, new_comment
      else
        con = RDoc::Constant.new const_name, definition, comment
      end
    else
      con = RDoc::Constant.new const_name, definition, comment
    end

    con.record_location @top_level
    @stats.add_constant con
    class_obj.add_constant con
  end

  ##
  # Removes #ifdefs that would otherwise confuse us

  def handle_ifdefs_in(body)
    body.gsub(/^#ifdef HAVE_PROTOTYPES.*?#else.*?\n(.*?)#endif.*?\n/m, '\1')
  end

  ##
  # Adds an RDoc::AnyMethod +meth_name+ defined on a class or module assigned
  # to +var_name+.  +type+ is the type of method definition function used.
  # +singleton_method+ and +module_function+ create a singleton method.

  def handle_method(type, var_name, meth_name, function, param_count,
                    source_file = nil)
    class_name = @known_classes[var_name]
    singleton  = @singleton_classes.key? var_name

    @methods[var_name][function] << meth_name

    return unless class_name

    class_obj = find_class var_name, class_name

    if class_obj then
      if meth_name == 'initialize' then
        meth_name = 'new'
        singleton = true
        type = 'method' # force public
      end

      meth_obj = RDoc::AnyMethod.new '', meth_name
      meth_obj.c_function = function
      meth_obj.singleton =
        singleton || %w[singleton_method module_function].include?(type)

      p_count = Integer(param_count) rescue -1

      if source_file then
        file_name = File.join @file_dir, source_file

        if File.exist? file_name then
          file_content = File.read file_name
        else
          @options.warn "unknown source #{source_file} for #{meth_name} in #{@file_name}"
        end
      else
        file_content = @content
      end

      body = find_body class_name, function, meth_obj, file_content

      if body and meth_obj.document_self then
        meth_obj.params = if p_count < -1 then # -2 is Array
                            '(*args)'
                          elsif p_count == -1 then # argc, argv
                            rb_scan_args body
                          else
                            "(#{(1..p_count).map { |i| "p#{i}" }.join ', '})"
                          end


        meth_obj.record_location @top_level
        class_obj.add_method meth_obj
        @stats.add_method meth_obj
        meth_obj.visibility = :private if 'private_method' == type
      end
    end
  end

  ##
  # Registers a singleton class +sclass_var+ as a singleton of +class_var+

  def handle_singleton sclass_var, class_var
    class_name = @known_classes[class_var]

    @known_classes[sclass_var]     = class_name
    @singleton_classes[sclass_var] = class_name
  end

  ##
  # Normalizes tabs in +body+

  def handle_tab_width(body)
    if /\t/ =~ body
      tab_width = @options.tab_width
      body.split(/\n/).map do |line|
        1 while line.gsub!(/\t+/) do
          ' ' * (tab_width * $&.length - $`.length % tab_width)
        end && $~
        line
      end.join "\n"
    else
      body
    end
  end

  ##
  # Loads the variable map with the given +name+ from the RDoc::Store, if
  # present.

  def load_variable_map map_name
    return {} unless files = @store.cache[map_name]
    return {} unless name_map = files[@file_name]

    class_map = {}

    name_map.each do |variable, name|
      next unless mod = @store.find_class_or_module(name)

      class_map[variable] = if map_name == :c_class_variables then
                              mod
                            else
                              name
                            end
      @known_classes[variable] = name
    end

    class_map
  end

  ##
  # Look for directives in a normal comment block:
  #
  #   /*
  #    * :title: My Awesome Project
  #    */
  #
  # This method modifies the +comment+

  def look_for_directives_in context, comment
    @preprocess.handle comment, context do |directive, param|
      case directive
      when 'main' then
        @options.main_page = param
        ''
      when 'title' then
        @options.default_title = param if @options.respond_to? :default_title=
        ''
      end
    end

    comment
  end

  ##
  # Extracts parameters from the +method_body+ and returns a method
  # parameter string.  Follows 1.9.3dev's scan-arg-spec, see README.EXT

  def rb_scan_args method_body
    method_body =~ /rb_scan_args\((.*?)\)/m
    return '(*args)' unless $1

    $1.split(/,/)[2] =~ /"(.*?)"/ # format argument
    format = $1.split(//)

    lead = opt = trail = 0

    if format.first =~ /\d/ then
      lead = $&.to_i
      format.shift
      if format.first =~ /\d/ then
        opt = $&.to_i
        format.shift
        if format.first =~ /\d/ then
          trail = $&.to_i
          format.shift
          block_arg = true
        end
      end
    end

    if format.first == '*' and not block_arg then
      var = true
      format.shift
      if format.first =~ /\d/ then
        trail = $&.to_i
        format.shift
      end
    end

    if format.first == ':' then
      hash = true
      format.shift
    end

    if format.first == '&' then
      block = true
      format.shift
    end

    # if the format string is not empty there's a bug in the C code, ignore it

    args = []
    position = 1

    (1...(position + lead)).each do |index|
      args << "p#{index}"
    end

    position += lead

    (position...(position + opt)).each do |index|
      args << "p#{index} = v#{index}"
    end

    position += opt

    if var then
      args << '*args'
      position += 1
    end

    (position...(position + trail)).each do |index|
      args << "p#{index}"
    end

    position += trail

    if hash then
      args << "p#{position} = {}"
      position += 1
    end

    args << '&block' if block

    "(#{args.join ', '})"
  end

  ##
  # Removes lines that are commented out that might otherwise get picked up
  # when scanning for classes and methods

  def remove_commented_out_lines
    @content.gsub!(%r%//.*rb_define_%, '//')
  end

  ##
  # Extracts the classes, modules, methods, attributes, constants and aliases
  # from a C file and returns an RDoc::TopLevel for this file

  def scan
    remove_commented_out_lines

    do_modules
    do_classes
    do_missing

    do_constants
    do_methods
    do_includes
    do_aliases
    do_attrs

    deduplicate_call_seq

    @store.add_c_variables self

    @top_level
  end

end


Youez - 2016 - github.com/yon3zu
LinuXploit