Kenji Okimoto
null+****@clear*****
Wed Feb 15 13:19:47 JST 2017
Kenji Okimoto 2017-02-15 13:19:47 +0900 (Wed, 15 Feb 2017) New Revision: ab48f6efe21419a95032d2196d5fa5219294d86f https://github.com/milter-manager/milter-manager/commit/ab48f6efe21419a95032d2196d5fa5219294d86f Merged ccec3ae: Merge pull request #116 from milter-manager/import-ruby-glib2-3.1.1 Message: binding ruby: Import ruby-glib2 3.1.1 Download ruby-gnome2-all-3.1.1.tar.gz and copy glib2 directory from this archive. Added files: binding/ruby/glib-3.1.1/COPYING.LIB binding/ruby/glib-3.1.1/Makefile.lib binding/ruby/glib-3.1.1/README.md binding/ruby/glib-3.1.1/Rakefile binding/ruby/glib-3.1.1/TODO binding/ruby/glib-3.1.1/ext/glib2/depend binding/ruby/glib-3.1.1/ext/glib2/extconf.rb binding/ruby/glib-3.1.1/ext/glib2/glib2.def binding/ruby/glib-3.1.1/ext/glib2/rbgcompat.h binding/ruby/glib-3.1.1/ext/glib2/rbglib-variant-type.c binding/ruby/glib-3.1.1/ext/glib2/rbglib-variant.c binding/ruby/glib-3.1.1/ext/glib2/rbglib.c binding/ruby/glib-3.1.1/ext/glib2/rbglib.h binding/ruby/glib-3.1.1/ext/glib2/rbglib2conversions.h binding/ruby/glib-3.1.1/ext/glib2/rbglib_bookmarkfile.c binding/ruby/glib-3.1.1/ext/glib2/rbglib_convert.c binding/ruby/glib-3.1.1/ext/glib2/rbglib_datetime.c binding/ruby/glib-3.1.1/ext/glib2/rbglib_error.c binding/ruby/glib-3.1.1/ext/glib2/rbglib_fileutils.c binding/ruby/glib-3.1.1/ext/glib2/rbglib_gettext.c binding/ruby/glib-3.1.1/ext/glib2/rbglib_i18n.c binding/ruby/glib-3.1.1/ext/glib2/rbglib_int64.c binding/ruby/glib-3.1.1/ext/glib2/rbglib_io_constants.c binding/ruby/glib-3.1.1/ext/glib2/rbglib_iochannel.c binding/ruby/glib-3.1.1/ext/glib2/rbglib_iochannel_win32_socket.c binding/ruby/glib-3.1.1/ext/glib2/rbglib_iochannelerror.c binding/ruby/glib-3.1.1/ext/glib2/rbglib_keyfile.c binding/ruby/glib-3.1.1/ext/glib2/rbglib_maincontext.c binding/ruby/glib-3.1.1/ext/glib2/rbglib_mainloop.c binding/ruby/glib-3.1.1/ext/glib2/rbglib_matchinfo.c binding/ruby/glib-3.1.1/ext/glib2/rbglib_messages.c binding/ruby/glib-3.1.1/ext/glib2/rbglib_pollfd.c binding/ruby/glib-3.1.1/ext/glib2/rbglib_regex.c binding/ruby/glib-3.1.1/ext/glib2/rbglib_shell.c binding/ruby/glib-3.1.1/ext/glib2/rbglib_shellerror.c binding/ruby/glib-3.1.1/ext/glib2/rbglib_source.c binding/ruby/glib-3.1.1/ext/glib2/rbglib_spawn.c binding/ruby/glib-3.1.1/ext/glib2/rbglib_spawnerror.c binding/ruby/glib-3.1.1/ext/glib2/rbglib_threads.c binding/ruby/glib-3.1.1/ext/glib2/rbglib_timer.c binding/ruby/glib-3.1.1/ext/glib2/rbglib_timezone.c binding/ruby/glib-3.1.1/ext/glib2/rbglib_ucs4.c binding/ruby/glib-3.1.1/ext/glib2/rbglib_unichar.c binding/ruby/glib-3.1.1/ext/glib2/rbglib_unicode.c binding/ruby/glib-3.1.1/ext/glib2/rbglib_utf16.c binding/ruby/glib-3.1.1/ext/glib2/rbglib_utf8.c binding/ruby/glib-3.1.1/ext/glib2/rbglib_utils.c binding/ruby/glib-3.1.1/ext/glib2/rbglib_win32.c binding/ruby/glib-3.1.1/ext/glib2/rbglibdeprecated.c binding/ruby/glib-3.1.1/ext/glib2/rbglibdeprecated.h binding/ruby/glib-3.1.1/ext/glib2/rbgobj_binding.c binding/ruby/glib-3.1.1/ext/glib2/rbgobj_boxed.c binding/ruby/glib-3.1.1/ext/glib2/rbgobj_closure.c binding/ruby/glib-3.1.1/ext/glib2/rbgobj_convert.c binding/ruby/glib-3.1.1/ext/glib2/rbgobj_enumflags.c binding/ruby/glib-3.1.1/ext/glib2/rbgobj_enums.c binding/ruby/glib-3.1.1/ext/glib2/rbgobj_flags.c binding/ruby/glib-3.1.1/ext/glib2/rbgobj_object.c binding/ruby/glib-3.1.1/ext/glib2/rbgobj_param.c binding/ruby/glib-3.1.1/ext/glib2/rbgobj_paramspecs.c binding/ruby/glib-3.1.1/ext/glib2/rbgobj_signal.c binding/ruby/glib-3.1.1/ext/glib2/rbgobj_strv.c binding/ruby/glib-3.1.1/ext/glib2/rbgobj_type.c binding/ruby/glib-3.1.1/ext/glib2/rbgobj_typeinstance.c binding/ruby/glib-3.1.1/ext/glib2/rbgobj_typeinterface.c binding/ruby/glib-3.1.1/ext/glib2/rbgobj_typemodule.c binding/ruby/glib-3.1.1/ext/glib2/rbgobj_typeplugin.c binding/ruby/glib-3.1.1/ext/glib2/rbgobj_value.c binding/ruby/glib-3.1.1/ext/glib2/rbgobj_valuearray.c binding/ruby/glib-3.1.1/ext/glib2/rbgobj_valuetypes.c binding/ruby/glib-3.1.1/ext/glib2/rbgobject.c binding/ruby/glib-3.1.1/ext/glib2/rbgobject.h binding/ruby/glib-3.1.1/ext/glib2/rbgprivate.h binding/ruby/glib-3.1.1/ext/glib2/rbgutil.c binding/ruby/glib-3.1.1/ext/glib2/rbgutil.h binding/ruby/glib-3.1.1/ext/glib2/rbgutil_callback.c binding/ruby/glib-3.1.1/ext/glib2/rbgutil_list.c binding/ruby/glib-3.1.1/ext/glib2/rbgutil_list.h binding/ruby/glib-3.1.1/ext/glib2/rbgutildeprecated.c binding/ruby/glib-3.1.1/ext/glib2/rbgutildeprecated.h binding/ruby/glib-3.1.1/ext/glib2/ruby-glib2.pc binding/ruby/glib-3.1.1/extconf.rb binding/ruby/glib-3.1.1/lib/glib-mkenums.rb binding/ruby/glib-3.1.1/lib/glib2.rb binding/ruby/glib-3.1.1/lib/glib2/deprecatable.rb binding/ruby/glib-3.1.1/lib/glib2/regex.rb binding/ruby/glib-3.1.1/lib/glib2/version.rb binding/ruby/glib-3.1.1/lib/gnome2-raketask.rb binding/ruby/glib-3.1.1/lib/gnome2/rake/external-package.rb binding/ruby/glib-3.1.1/lib/gnome2/rake/native-binary-build-task.rb binding/ruby/glib-3.1.1/lib/gnome2/rake/package-task.rb binding/ruby/glib-3.1.1/lib/gnome2/rake/package.rb binding/ruby/glib-3.1.1/lib/gnome2/rake/source-download-task.rb binding/ruby/glib-3.1.1/lib/gnome2/rake/windows-binary-build-task.rb binding/ruby/glib-3.1.1/lib/gnome2/rake/windows-binary-download-task.rb binding/ruby/glib-3.1.1/lib/mkmf-gnome2.rb binding/ruby/glib-3.1.1/patches/glib-2.48.0-add-missing-exeext.diff binding/ruby/glib-3.1.1/patches/guile-2.0.11-remove-needless-mkstemp-check.diff binding/ruby/glib-3.1.1/sample/bookmarkfile.rb binding/ruby/glib-3.1.1/sample/idle.rb binding/ruby/glib-3.1.1/sample/iochannel.rb binding/ruby/glib-3.1.1/sample/keyfile.rb binding/ruby/glib-3.1.1/sample/shell.rb binding/ruby/glib-3.1.1/sample/spawn.rb binding/ruby/glib-3.1.1/sample/timeout.rb binding/ruby/glib-3.1.1/sample/timeout2.rb binding/ruby/glib-3.1.1/sample/timer.rb binding/ruby/glib-3.1.1/sample/type-register.rb binding/ruby/glib-3.1.1/sample/type-register2.rb binding/ruby/glib-3.1.1/sample/utils.rb binding/ruby/glib-3.1.1/test/glib-test-init.rb binding/ruby/glib-3.1.1/test/glib-test-utils.rb binding/ruby/glib-3.1.1/test/run-test.rb binding/ruby/glib-3.1.1/test/test-binding.rb binding/ruby/glib-3.1.1/test/test-date-time.rb binding/ruby/glib-3.1.1/test/test-match-info.rb binding/ruby/glib-3.1.1/test/test-regex.rb binding/ruby/glib-3.1.1/test/test-time-zone.rb binding/ruby/glib-3.1.1/test/test-variant-type.rb binding/ruby/glib-3.1.1/test/test-version.rb binding/ruby/glib-3.1.1/test/test_enum.rb binding/ruby/glib-3.1.1/test/test_file_utils.rb binding/ruby/glib-3.1.1/test/test_flags.rb binding/ruby/glib-3.1.1/test/test_glib2.rb binding/ruby/glib-3.1.1/test/test_iochannel.rb binding/ruby/glib-3.1.1/test/test_key_file.rb binding/ruby/glib-3.1.1/test/test_mkenums.rb binding/ruby/glib-3.1.1/test/test_poll_fd.rb binding/ruby/glib-3.1.1/test/test_signal.rb binding/ruby/glib-3.1.1/test/test_source.rb binding/ruby/glib-3.1.1/test/test_spawn.rb binding/ruby/glib-3.1.1/test/test_timeout.rb binding/ruby/glib-3.1.1/test/test_unicode.rb binding/ruby/glib-3.1.1/test/test_utils.rb binding/ruby/glib-3.1.1/test/test_value.rb binding/ruby/glib-3.1.1/test/test_win32.rb Added: binding/ruby/glib-3.1.1/COPYING.LIB (+502 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/COPYING.LIB 2017-02-15 13:19:47 +0900 (4362b49) @@ -0,0 +1,502 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! Added: binding/ruby/glib-3.1.1/Makefile.lib (+242 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/Makefile.lib 2017-02-15 13:19:47 +0900 (ebd1391) @@ -0,0 +1,242 @@ + +SHELL = /bin/sh + +# V=0 quiet, V=1 verbose. other values don't work. +V = 0 +Q1 = $(V:1=) +Q = $(Q1:0=@) +ECHO1 = $(V:1=@:) +ECHO = $(ECHO1:0=@echo) + +#### Start of system configuration section. #### + +srcdir = /home/kou/work/ruby/ruby-gnome2.clean/glib2 +topdir = /usr/include/ruby-2.1.0 +hdrdir = $(topdir) +arch_hdrdir = /usr/include/x86_64-linux-gnu/ruby-2.1.0 +PATH_SEPARATOR = : +VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby +prefix = $(DESTDIR)/usr +rubysitearchprefix = $(sitearchlibdir)/$(RUBY_BASE_NAME) +rubyarchprefix = $(archlibdir)/$(RUBY_BASE_NAME) +rubylibprefix = $(libdir)/$(RUBY_BASE_NAME) +exec_prefix = $(prefix) +vendorarchhdrdir = $(sitearchincludedir)/$(RUBY_VERSION_NAME)/vendor_ruby +sitearchhdrdir = $(sitearchincludedir)/$(RUBY_VERSION_NAME)/site_ruby +rubyarchhdrdir = $(archincludedir)/$(RUBY_VERSION_NAME) +vendorhdrdir = $(rubyhdrdir)/vendor_ruby +sitehdrdir = $(rubyhdrdir)/site_ruby +rubyhdrdir = $(includedir)/$(RUBY_VERSION_NAME) +vendorarchdir = $(rubysitearchprefix)/vendor_ruby/$(ruby_version) +vendorlibdir = $(vendordir)/$(ruby_version) +vendordir = $(rubylibprefix)/vendor_ruby +sitearchdir = $(DESTDIR)/usr/local/lib/x86_64-linux-gnu/site_ruby +sitelibdir = $(sitedir)/$(ruby_version) +sitedir = $(DESTDIR)/usr/local/lib/site_ruby +rubyarchdir = $(rubyarchprefix)/$(ruby_version) +rubylibdir = $(rubylibprefix)/$(ruby_version) +sitearchincludedir = $(includedir)/$(sitearch) +archincludedir = $(includedir)/$(arch) +sitearchlibdir = $(libdir)/$(sitearch) +archlibdir = $(libdir)/$(arch) +ridir = $(datarootdir)/$(RI_BASE_NAME) +mandir = $(prefix)/share/man +localedir = $(datarootdir)/locale +libdir = $(exec_prefix)/lib +psdir = $(docdir) +pdfdir = $(docdir) +dvidir = $(docdir) +htmldir = $(docdir) +infodir = $(prefix)/share/info +docdir = $(datarootdir)/doc/$(PACKAGE) +oldincludedir = $(DESTDIR)/usr/include +includedir = $(prefix)/include +localstatedir = $(DESTDIR)/var +sharedstatedir = $(prefix)/com +sysconfdir = $(DESTDIR)/etc +datadir = $(datarootdir) +datarootdir = $(prefix)/share +libexecdir = $(prefix)/lib/ruby2.1 +sbindir = $(exec_prefix)/sbin +bindir = $(exec_prefix)/bin +archdir = $(rubyarchdir) + + +CC = gcc +CXX = g++ +LIBRUBY = $(LIBRUBY_SO) +LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a +LIBRUBYARG_SHARED = -l$(RUBY_SO_NAME) +LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)-static +empty = +OUTFLAG = -o $(empty) +COUTFLAG = -o $(empty) + +RUBY_EXTCONF_H = +cflags = $(optflags) $(debugflags) $(warnflags) +optflags = -O3 -fno-fast-math +debugflags = -ggdb3 +warnflags = -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wunused-variable -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wimplicit-function-declaration +CCDLFLAGS = -fPIC +CFLAGS = $(CCDLFLAGS) -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -fPIC $(ARCH_FLAG) +INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir) +DEFS = +CPPFLAGS = -D_FORTIFY_SOURCE=2 $(DEFS) $(cppflags) +CXXFLAGS = $(CCDLFLAGS) -g -O2 -fstack-protector-strong -Wformat -Werror=format-security $(ARCH_FLAG) +ldflags = -L. -Wl,-z,relro -L/build/ruby2.1-64qTCU/ruby2.1-2.1.5/debian/lib -fstack-protector -rdynamic -Wl,-export-dynamic +dldflags = +ARCH_FLAG = +DLDFLAGS = $(ldflags) $(dldflags) $(ARCH_FLAG) +LDSHARED = $(CC) -shared +LDSHAREDXX = $(CXX) -shared +AR = ar +EXEEXT = + +RUBY_INSTALL_NAME = ruby2.1 +RUBY_SO_NAME = ruby-2.1 +RUBYW_INSTALL_NAME = +RUBY_VERSION_NAME = $(RUBY_BASE_NAME)-$(ruby_version) +RUBYW_BASE_NAME = rubyw +RUBY_BASE_NAME = ruby + +arch = x86_64-linux-gnu +sitearch = $(arch) +ruby_version = 2.1.0 +ruby = $(bindir)/ruby2.1 +RUBY = $(ruby) +ruby_headers = $(hdrdir)/ruby.h $(hdrdir)/ruby/ruby.h $(hdrdir)/ruby/defines.h $(hdrdir)/ruby/missing.h $(hdrdir)/ruby/intern.h $(hdrdir)/ruby/st.h $(hdrdir)/ruby/subst.h $(arch_hdrdir)/ruby/config.h + +RM = rm -f +RM_RF = $(RUBY) -run -e rm -- -rf +RMDIRS = rmdir --ignore-fail-on-non-empty -p +MAKEDIRS = /bin/mkdir -p +INSTALL = /usr/bin/install -c +INSTALL_PROG = $(INSTALL) -m 0755 +INSTALL_DATA = $(INSTALL) -m 644 +COPY = cp +TOUCH = exit > + +#### End of system configuration section. #### + +preload = + +libpath = . $(archlibdir) +LIBPATH = -L. -L$(archlibdir) +DEFFILE = + +CLEANFILES = mkmf.log +DISTCLEANFILES = +DISTCLEANDIRS = + +extout = +extout_prefix = +target_prefix = +LOCAL_LIBS = +LIBS = $(LIBRUBYARG_SHARED) -lpthread -lgmp -ldl -lcrypt -lm -lc +ORIG_SRCS = +SRCS = $(ORIG_SRCS) +OBJS = +HDRS = +TARGET = +TARGET_NAME = +TARGET_ENTRY = Init_$(TARGET_NAME) +DLLIB = +EXTSTATIC = +STATIC_LIB = + +TIMESTAMP_DIR = . +BINDIR = $(bindir) +RUBYCOMMONDIR = $(sitedir)$(target_prefix) +RUBYLIBDIR = $(sitelibdir)$(target_prefix) +RUBYARCHDIR = $(sitearchdir)$(target_prefix) +HDRDIR = $(rubyhdrdir)/ruby$(target_prefix) +ARCHHDRDIR = $(rubyhdrdir)/$(arch)/ruby$(target_prefix) + +TARGET_SO = $(DLLIB) +CLEANLIBS = $(TARGET).so +CLEANOBJS = *.o *.bak + +all: Makefile +static: $(STATIC_LIB) +.PHONY: all install static install-so install-rb +.PHONY: clean clean-so clean-static clean-rb + +clean-static:: +clean-rb-default:: +clean-rb:: +clean-so:: +clean: clean-so clean-static clean-rb-default clean-rb + -$(Q)$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES) .*.time + +distclean-rb-default:: +distclean-rb:: +distclean-so:: +distclean-static:: +distclean: clean distclean-so distclean-static distclean-rb-default distclean-rb + -$(Q)$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log + -$(Q)$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES) + -$(Q)$(RMDIRS) $(DISTCLEANDIRS) 2> /dev/null || true + +realclean: distclean +install: install-so install-rb + +install-so: Makefile +install-rb: pre-install-rb install-rb-default +install-rb-default: pre-install-rb-default +pre-install-rb: Makefile +pre-install-rb-default: Makefile +pre-install-rb-default: $(TIMESTAMP_DIR)/.RUBYLIBDIR.time +install-rb-default: $(RUBYLIBDIR)/gnome2-raketask.rb +$(RUBYLIBDIR)/gnome2-raketask.rb: $(srcdir)/lib/gnome2-raketask.rb $(TIMESTAMP_DIR)/.RUBYLIBDIR.time + $(Q) $(INSTALL_DATA) $(srcdir)/lib/gnome2-raketask.rb $(@D) +install-rb-default: $(RUBYLIBDIR)/mkmf-gnome2.rb +$(RUBYLIBDIR)/mkmf-gnome2.rb: $(srcdir)/lib/mkmf-gnome2.rb $(TIMESTAMP_DIR)/.RUBYLIBDIR.time + $(Q) $(INSTALL_DATA) $(srcdir)/lib/mkmf-gnome2.rb $(@D) +install-rb-default: $(RUBYLIBDIR)/glib-mkenums.rb +$(RUBYLIBDIR)/glib-mkenums.rb: $(srcdir)/lib/glib-mkenums.rb $(TIMESTAMP_DIR)/.RUBYLIBDIR.time + $(Q) $(INSTALL_DATA) $(srcdir)/lib/glib-mkenums.rb $(@D) +install-rb-default: $(RUBYLIBDIR)/glib2.rb +$(RUBYLIBDIR)/glib2.rb: $(srcdir)/lib/glib2.rb $(TIMESTAMP_DIR)/.RUBYLIBDIR.time + $(Q) $(INSTALL_DATA) $(srcdir)/lib/glib2.rb $(@D) +pre-install-rb-default: $(TIMESTAMP_DIR)/.RUBYLIBDIR.-.gnome2.-.rake.time +install-rb-default: $(RUBYLIBDIR)/gnome2/rake/native-binary-build-task.rb +$(RUBYLIBDIR)/gnome2/rake/native-binary-build-task.rb: $(srcdir)/lib/gnome2/rake/native-binary-build-task.rb $(TIMESTAMP_DIR)/.RUBYLIBDIR.-.gnome2.-.rake.time + $(Q) $(INSTALL_DATA) $(srcdir)/lib/gnome2/rake/native-binary-build-task.rb $(@D) +install-rb-default: $(RUBYLIBDIR)/gnome2/rake/windows-binary-download-task.rb +$(RUBYLIBDIR)/gnome2/rake/windows-binary-download-task.rb: $(srcdir)/lib/gnome2/rake/windows-binary-download-task.rb $(TIMESTAMP_DIR)/.RUBYLIBDIR.-.gnome2.-.rake.time + $(Q) $(INSTALL_DATA) $(srcdir)/lib/gnome2/rake/windows-binary-download-task.rb $(@D) +install-rb-default: $(RUBYLIBDIR)/gnome2/rake/windows-binary-build-task.rb +$(RUBYLIBDIR)/gnome2/rake/windows-binary-build-task.rb: $(srcdir)/lib/gnome2/rake/windows-binary-build-task.rb $(TIMESTAMP_DIR)/.RUBYLIBDIR.-.gnome2.-.rake.time + $(Q) $(INSTALL_DATA) $(srcdir)/lib/gnome2/rake/windows-binary-build-task.rb $(@D) +install-rb-default: $(RUBYLIBDIR)/gnome2/rake/package-task.rb +$(RUBYLIBDIR)/gnome2/rake/package-task.rb: $(srcdir)/lib/gnome2/rake/package-task.rb $(TIMESTAMP_DIR)/.RUBYLIBDIR.-.gnome2.-.rake.time + $(Q) $(INSTALL_DATA) $(srcdir)/lib/gnome2/rake/package-task.rb $(@D) +install-rb-default: $(RUBYLIBDIR)/gnome2/rake/external-package.rb +$(RUBYLIBDIR)/gnome2/rake/external-package.rb: $(srcdir)/lib/gnome2/rake/external-package.rb $(TIMESTAMP_DIR)/.RUBYLIBDIR.-.gnome2.-.rake.time + $(Q) $(INSTALL_DATA) $(srcdir)/lib/gnome2/rake/external-package.rb $(@D) +install-rb-default: $(RUBYLIBDIR)/gnome2/rake/source-download-task.rb +$(RUBYLIBDIR)/gnome2/rake/source-download-task.rb: $(srcdir)/lib/gnome2/rake/source-download-task.rb $(TIMESTAMP_DIR)/.RUBYLIBDIR.-.gnome2.-.rake.time + $(Q) $(INSTALL_DATA) $(srcdir)/lib/gnome2/rake/source-download-task.rb $(@D) +install-rb-default: $(RUBYLIBDIR)/gnome2/rake/package.rb +$(RUBYLIBDIR)/gnome2/rake/package.rb: $(srcdir)/lib/gnome2/rake/package.rb $(TIMESTAMP_DIR)/.RUBYLIBDIR.-.gnome2.-.rake.time + $(Q) $(INSTALL_DATA) $(srcdir)/lib/gnome2/rake/package.rb $(@D) +pre-install-rb-default: $(TIMESTAMP_DIR)/.RUBYLIBDIR.-.glib2.time +install-rb-default: $(RUBYLIBDIR)/glib2/deprecatable.rb +$(RUBYLIBDIR)/glib2/deprecatable.rb: $(srcdir)/lib/glib2/deprecatable.rb $(TIMESTAMP_DIR)/.RUBYLIBDIR.-.glib2.time + $(Q) $(INSTALL_DATA) $(srcdir)/lib/glib2/deprecatable.rb $(@D) +pre-install-rb-default: + $(ECHO) installing default libraries +$(TIMESTAMP_DIR)/.RUBYLIBDIR.time: + $(Q) $(MAKEDIRS) $(@D) $(RUBYLIBDIR) + $(Q) $(TOUCH) $@ +$(TIMESTAMP_DIR)/.RUBYLIBDIR.-.gnome2.-.rake.time: + $(Q) $(MAKEDIRS) $(@D) $(RUBYLIBDIR)/gnome2/rake + $(Q) $(TOUCH) $@ +$(TIMESTAMP_DIR)/.RUBYLIBDIR.-.glib2.time: + $(Q) $(MAKEDIRS) $(@D) $(RUBYLIBDIR)/glib2 + $(Q) $(TOUCH) $@ + +site-install: site-install-so site-install-rb +site-install-so: install-so +site-install-rb: install-rb + Added: binding/ruby/glib-3.1.1/README.md (+42 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/README.md 2017-02-15 13:19:47 +0900 (0cd5a2c) @@ -0,0 +1,42 @@ +# Ruby/GLib2 + +Ruby/GLib2 is a Ruby binding of GLib-2.12.x. + +## Requirements + + Ruby >= 1.9.x: http://www.ruby-lang.org/ + pkg-config.rb: http://github.com/rcairo/pkg-config + GLib >= 2.12.x: http://www.gtk.org/ + +## Install (RubyGems) + +``` + % sudo gem install glib2 +``` +Windows: + +``` + > gem install glib2 --platform x86-mingw32 +``` + +## Install (traditional) + +Install ruby-1.9.x or later, pkg-config.rb and GLib-2.12.x. + +``` + % ruby extconf.rb + % make + % sudo make install +``` + +## Copying + + Copyright (c) 2002-2010 Ruby-GNOME2 Project Team + + This program is free software. + You can distribute/modify this program under the terms of + the GNU LESSER GENERAL PUBLIC LICENSE Version 2.1. + +## Project Website + + http://ruby-gnome2.sourceforge.jp/ Added: binding/ruby/glib-3.1.1/Rakefile (+214 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/Rakefile 2017-02-15 13:19:47 +0900 (4db37ad) @@ -0,0 +1,214 @@ +# -*- ruby -*- +# +# Copyright (C) 2011-2017 Ruby-GNOME2 Project Team +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +$LOAD_PATH.unshift("./lib") +require 'gnome2/rake/package-task' + +bin_dir = nil +include_dir = nil +glib2_include_dir = nil +libffi_lib_dir = nil + +build_host = nil + +package_task = GNOME2::Rake::PackageTask.new do |package| + bin_dir = (package.windows.absolute_binary_dir + "bin").to_s + include_dir = (package.windows.absolute_binary_dir + "include").to_s + glib2_include_dir = File.join(include_dir, "glib-2.0") + libffi_lib_dir = (package.windows.absolute_binary_dir + "lib").to_s + + build_host = package.windows.build_host + + package.summary = "Ruby/GLib2 is a Ruby binding of GLib-2.x." + package.description = "Ruby/GLib2 is a Ruby binding of GLib-2.x." + package.dependency.gem.runtime = [["pkg-config", ">= 0"]] + package.dependency.gem.development = [["test-unit", ">= 2"]] + package.windows.packages = [] + package.windows.dependencies = [] + package.external_packages = [ + { + :name => "libiconv", + :download_site => :gnu, + :label => "libiconv", + :version => "1.14", + :windows => { + :built_file => "bin/libiconv-2.dll", + }, + }, + { + :name => "gettext", + :download_site => :gnu, + :label => "gettext-runtime", + :version => "0.19.7", + :base_dir_in_package => "gettext-runtime", + :windows => { + :built_file => "bin/libintl-8.dll", + }, + }, + { + :name => "libffi", + :download_base_url => "ftp://sourceware.org/pub/libffi", + :label => "libffi", + :version => "3.2.1", + :windows => { + :built_file => "bin/libffi-6.dll", + }, + }, + { + :name => "pcre", + :download_base_url => "ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre", + :label => "PCRE", + :version => "8.40", + :windows => { + :configure_args => [ + "--enable-unicode-properties", + ], + :built_file => "bin/libpcre-1.dll", + }, + }, + { + :name => "glib", + :download_site => :gnome, + :label => "GLib", + :version => "2.50.2", + :compression_method => "xz", + :windows => { + :need_autoreconf => true, + :patches => [ + "glib-2.48.0-add-missing-exeext.diff", + ], + :built_file => "bin/libglib-2.0-0.dll", + }, + }, + { + :name => "gmp", + :download_base_url => "ftp://ftp.gmplib.org/pub/gmp-6.1.0", + :label => "GNU MP", + :version => "6.1.0", + :compression_method => "xz", + :windows => { + :configure_args => [ + "--disable-static", + "--enable-shared", + ], + :built_file => "bin/libgmp-10.dll", + }, + }, + { + :name => "nettle", + :download_base_url => "http://www.lysator.liu.se/~nisse/archive", + :label => "Nettle", + :version => "3.2", + :windows => { + :configure_args => [], + :built_file => "bin/libnettle-6-2.dll", + }, + }, + { + :name => "libtasn1", + :download_site => :gnu, + :label => "Libtasn1", + :version => "4.7", + :windows => { + :built_file => "bin/libtasn1-6.dll", + }, + }, + { + :name => "libidn", + :download_site => :gnu, + :label => "Libidn", + :version => "1.32", + :windows => { + :built_file => "bin/libidn-11.dll", + }, + }, + { + :name => "p11-kit", + :download_base_url => "https://p11-glue.freedesktop.org/releases", + :label => "p11-kit", + :version => "0.23.2", + :windows => { + :built_file => "bin/libp11-kit-0.dll", + }, + }, + { + :name => "gnutls", + :download_base_url => "ftp://ftp.gnutls.org/gcrypt/gnutls/v3.4", + :label => "GnuTLS", + :version => "3.4.10", + :compression_method => "xz", + :windows => { + :configure_args => [ + "--disable-cxx", + "--disable-tools", + "--disable-doc", + ], + :use_cc_environment_variable => false, + :patches => [ + ], + :built_file => "bin/libgnutls-30.dll", + }, + }, + { + :name => "glib-networking", + :download_site => :gnome, + :label => "glib-networking", + :version => "2.50.0", + :compression_method => "xz", + :windows => { + :configure_args => [ + "--without-libproxy", + "--without-gnome-proxy", + "--without-ca-certificates", + ], + :built_file => "lib/gio/modules/libgiognutls.dll", + }, + }, + ] + package.cross_compiling do |spec| + if /mingw|mswin/ =~ spec.platform.to_s + spec.add_runtime_dependency("cairo", ">= 1.12.8") + end + end +end +package_task.define + +namespace :windows do + namespace :glib do + pkg_config_dir = package_task.windows.absolute_binary_dir + "lib/pkgconfig" + pc_path = pkg_config_dir + "glib-2.0.pc" + patched_path = pkg_config_dir + "patched" + file patched_path.to_s do + original_pc = pc_path.read + new_pc = original_pc.gsub(/^Cflags:/) do |matched| + "#{matched} -I${includedir}" + end + pc_path.open("w") do |pc_file| + pc_file.write(new_pc) + end + touch(patched_path) + end + + desc "Add include path for libintl.h" + task :cross => patched_path.to_s + end + + namespace :builder do + task :after => "windows:glib:cross" + end +end Added: binding/ruby/glib-3.1.1/TODO (+3 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/TODO 2017-02-15 13:19:47 +0900 (0e2f714) @@ -0,0 +1,3 @@ +* GIO support +* inspect include readable properties. +* make log message handler set by Ruby/GLib removable. Added: binding/ruby/glib-3.1.1/ext/glib2/depend (+18 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/depend 2017-02-15 13:19:47 +0900 (7d2e1c6) @@ -0,0 +1,18 @@ +install-so: install-headers +install-headers: + $(INSTALL_DATA) $(srcdir)/rbglib.h $(RUBYARCHDIR) + $(INSTALL_DATA) $(srcdir)/rbglibdeprecated.h $(RUBYARCHDIR) + $(INSTALL_DATA) $(srcdir)/rbglib2conversions.h $(RUBYARCHDIR) + $(INSTALL_DATA) $(srcdir)/rbgutil.h $(RUBYARCHDIR) + $(INSTALL_DATA) $(srcdir)/rbgutil_list.h $(RUBYARCHDIR) + $(INSTALL_DATA) $(srcdir)/rbgutildeprecated.h $(RUBYARCHDIR) + $(INSTALL_DATA) $(srcdir)/rbgobject.h $(RUBYARCHDIR) + $(INSTALL_DATA) $(srcdir)/rbgcompat.h $(RUBYARCHDIR) + $(INSTALL_DATA) glib-enum-types.h $(RUBYARCHDIR) + +install: install-pc +install-pc: + if test -n "$(pkgconfigdir)"; then \ + $(MAKEDIRS) $(pkgconfigdir); \ + $(INSTALL_DATA) ruby-glib2.pc $(pkgconfigdir); \ + fi Added: binding/ruby/glib-3.1.1/ext/glib2/extconf.rb (+86 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/extconf.rb 2017-02-15 13:19:47 +0900 (63fbab0) @@ -0,0 +1,86 @@ +=begin +extconf.rb for Ruby/GLib extention library +=end + +require 'pathname' + +base_dir = Pathname(__FILE__).dirname.parent.parent.expand_path +mkmf_gnome2_dir = base_dir + 'lib' + +$LOAD_PATH.unshift(mkmf_gnome2_dir.to_s) + +module_name = "glib2" +package_id = "gobject-2.0" + +require 'mkmf-gnome2' + +setup_windows(module_name, base_dir) + +unless required_pkg_config_package([package_id, 2, 12, 0], + :altlinux => "glib2-devel", + :debian => "libglib2.0-dev", + :redhat => "glib2-devel", + :arch => "glib2", + :homebrew => "glib", + :macports => "glib2") + exit(false) +end +PKGConfig.have_package('gthread-2.0') + +have_header("unistd.h") +have_header("io.h") + +glib_header = "glib.h" +have_func("g_spawn_close_pid", glib_header) +have_func("g_thread_init", glib_header) +have_func("g_main_depth", glib_header) +have_func("g_listenv", glib_header) + +ruby_header = "ruby.h" +have_func("rb_check_array_type", ruby_header) +have_func("rb_check_hash_type", ruby_header) +have_func("rb_exec_recursive", ruby_header) +have_func("rb_errinfo", ruby_header) +have_func("rb_thread_call_without_gvl", ruby_header) +have_func("ruby_native_thread_p", ruby_header) +have_func("rb_thread_call_with_gvl", ruby_header) +have_func("rb_gc_register_mark_object", ruby_header) +have_func("rb_exc_new_str", ruby_header) + +have_var("curr_thread", [ruby_header, "node.h"]) +have_var("rb_curr_thread", [ruby_header, "node.h"]) + +create_pkg_config_file("Ruby/GLib2", package_id) + +enum_types_prefix = "glib-enum-types" +include_paths = PKGConfig.cflags_only_I("glib-2.0") +ignore_headers = [ + "giochannel.h", + "gmain.h", + "gscanner.h", +] +unless windows_platform? + ignore_headers << "gwin32.h" +end +headers = include_paths.split.inject([]) do |result, path| + result + Dir.glob(File.join(path.sub(/^-I/, ""), "glib", "*.h")) +end.reject do |file| + ignore_headers.include?(File.basename(file)) +end +include_paths = PKGConfig.cflags_only_I("gobject-2.0") +headers = include_paths.split.inject(headers) do |result, path| + result + Dir.glob(File.join(path.sub(/^-I/, ""), "gobject", "gsignal.h")) +end +glib_mkenums(enum_types_prefix, headers, "G_TYPE_", ["glib-object.h"]) + +$defs << "-DRUBY_GLIB2_COMPILATION" + +create_makefile(module_name) + +pkg_config_dir = with_config("pkg-config-dir") +if pkg_config_dir.is_a?(String) + File.open("Makefile", "ab") do |makefile| + makefile.puts + makefile.puts("pkgconfigdir=#{pkg_config_dir}") + end +end Added: binding/ruby/glib-3.1.1/ext/glib2/glib2.def (+162 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/glib2.def 2017-02-15 13:19:47 +0900 (99afdaa) @@ -0,0 +1,162 @@ +EXPORTS + Init_glib2 + mGLib DATA + rbgobj_cType DATA + rbgobj_id_children DATA + rbgobj_add_relative + rbgobj_invalidate_relatives + rbgobj_add_relative_removable + rbgobj_get_relative_removable + rbgobj_remove_relative + rbgobj_remove_relative_all + rbgobj_define_class + rbgobj_define_class_dynamic + rbgobj_register_mark_func + rbgobj_register_free_func + rbgobj_instance_from_ruby_object + rbgobj_ruby_object_from_instance + rbgobj_ruby_object_from_instance2 + rbgobj_ruby_object_from_instance_with_unref + rbgobj_instance_unref + rbgobj_get_ruby_object_from_gobject + rbgobj_create_object + rbgobj_gobject_new + rbgobj_gobject_initialize + rbgobj_boxed_create + rbgobj_boxed_get + rbgobj_boxed_get_default + rbgobj_boxed_not_copy_obj + rbgobj_boxed_unown + rbgobj_make_boxed + rbgobj_make_boxed_raw + rbgobj_make_boxed_default + rbgobj_add_abstract_but_create_instance_class + rbgobj_gtype_get + rbgobj_gtype_new + rbgobj_gvalue_to_rvalue + rbgobj_gvalue_to_rvalue_unset + rbgobj_rvalue_to_gvalue + rbgobj_initialize_gvalue + rbgobj_initialize_object + rbgobj_lookup_class + rbgobj_lookup_class_by_gtype + rbgobj_gtype_to_ruby_class + rbgobj_ptr2cptr + rbgobj_ptr_new + rbgobj_make_enum + rbgobj_get_enum + rbgobj_make_flags + rbgobj_get_flags + rbgobj_register_g2r_func + rbgobj_register_r2g_func + rbgobj_register_class + rbgobj_register_property_getter + rbgobj_register_property_setter + rbgobj_class_init_func + rbgobj_register_type + rbgobj_set_signal_func + rbgobj_get_signal_func + rbgobj_set_signal_call_func + rbgobj_get_signal_call_func + rbgobj_add_constants + rbgobj_constant_remap + rbgobj_signal_wrap + g_rclosure_new + g_rclosure_new_call + g_rclosure_attach + g_rclosure_set_tag + rbgobj_ruby_value_get_type + g_value_get_ruby_value + g_value_set_ruby_value + g_key_file_get_type + rbg_rval_inspect + rbg_string_value_ptr + rbg_rval2cstr + rbg_rval2cstr_raw + rbg_rval2cstr_ptr + rbg_rval2cstr_accept_nil + rbg_rval2cstr_raw_accept_nil + rbg_rval2cstr_ptr_accept_nil + rbg_rval2cstr_accept_symbol + rbg_rval2cstr_accept_symbol_accept_nil + rbg_rval2glibid + rbg_cstr2rval + rbg_cstr2rval_len + rbg_cstr2rval_len_free + rbg_cstr2rval_with_encoding + rbg_cstr2rval_len_with_encoding + rbg_cstr2rval_free + rbg_cstr2rval_with_free + rbg_filename_to_ruby + rbg_filename_to_ruby_free + rbg_filename_from_ruby + rbg_filename_gslist_to_array_free + rbg_rval2strv + rbg_rval2strv_accept_nil + rbg_rval2strv_dup + rbg_rval2strv_dup_accept_nil + rbg_strv2rval + rbg_strv2rval_free + rbg_rval2gbooleans + rbg_rval2gints + rbg_rval2gint8s + rbg_rval2guint8s + rbg_rval2guint16s + rbg_rval2guint32s + rbg_rval2gdoubles + rbg_gints2rval + rbg_gints2rval_free + rbg_glist2rval + rbg_gslist2rval + rbg_glist2rval_with_type + rbg_gslist2rval_with_type + rbg_rval2glist + rbg_rval2gslist + rbg_define_method + rbg_define_singleton_method + rbg_to_array + rbg_to_hash + rbg_check_array_type + rbg_check_hash_type + rbg_scan_options + rbg_inspect + rbg_interrupt_source_new + rbg_name_to_nick + rbg_memzero + rbgutil_id_module_eval DATA + rbgutil_def_setters + rbgutil_glist2ary + rbgutil_glist2ary_boxed + rbgutil_glist2ary_string + rbgutil_glist2ary_and_free + rbgutil_glist2ary_boxed_and_free + rbgutil_glist2ary_string_and_free + rbgutil_gslist2ary + rbgutil_gslist2ary_boxed + rbgutil_gslist2ary_and_free + rbgutil_gslist2ary_boxed_and_free + rbgutil_set_properties + rbgutil_glibid_r2g_func + rbgutil_sym_g2r_func + rbgutil_protect + rbgutil_invoke_callback + rbgutil_start_callback_dispatch_thread + rbgutil_stop_callback_dispatch_thread + rbgutil_string_set_utf8_encoding + rbgutil_key_equal + rbgerr_define_gerror + rbgerr_gerror2exception + rbgobj_convert_define + rbgobj_gc_mark_gvalue + rbgobj_gc_mark_instance + rbglib_num_to_uint64 + rbglib_uint64_to_num + rbglib_num_to_int64 + rbglib_int64_to_num + rbg_variant_to_ruby + rbg_variant_from_ruby + + g_source_get_type + g_connect_flags_get_type + g_poll_fd_get_type + g_signal_flags_get_type Added: binding/ruby/glib-3.1.1/ext/glib2/rbgcompat.h (+29 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbgcompat.h 2017-02-15 13:19:47 +0900 (03de03c) @@ -0,0 +1,29 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2007 Ruby-GNOME2 Project Team + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef __RBGCOMPAT_H__ +#define __RBGCOMPAT_H__ + +G_BEGIN_DECLS + +G_END_DECLS + +#endif Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib-variant-type.c (+300 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbglib-variant-type.c 2017-02-15 13:19:47 +0900 (4173f7b) @@ -0,0 +1,300 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2015-2016 Ruby-GNOME2 Project Team + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" + +#define RG_TARGET_NAMESPACE cVariantType + +#define _SELF(s) (RVAL2GVARIANTTYPE(s)) + +static VALUE RG_TARGET_NAMESPACE; + +static VALUE +rg_s_valid_p(G_GNUC_UNUSED VALUE klass, VALUE rb_string) +{ + gboolean is_valid; + + is_valid = g_variant_type_string_is_valid(StringValueCStr(rb_string)); + + return CBOOL2RVAL(is_valid); +} + +static VALUE +rg_s_scan(G_GNUC_UNUSED VALUE klass, VALUE rb_string) +{ + gboolean found; + const gchar *string; + const gchar *end; + + string = StringValueCStr(rb_string); + found = g_variant_type_string_scan(string, NULL, &end); + + if (!found) { + return Qnil; + } + + return CSTR2RVAL(end); +} + +static VALUE +rg_initialize(VALUE self, VALUE rb_string) +{ + GVariantType *variant_type; + const gchar *string; + + string = StringValueCStr(rb_string); + if (!g_variant_type_string_is_valid(string)) { + rb_raise(rb_eArgError, + "invalid type string: %s", rbg_inspect(rb_string)); + } + + variant_type = g_variant_type_new(string); + G_INITIALIZE(self, variant_type); + + return Qnil; +} + +static VALUE +rg_to_s(VALUE self) +{ + GVariantType *variant_type; + const gchar *string; + gsize string_length; + + variant_type = _SELF(self); + string = g_variant_type_peek_string(variant_type); + string_length = g_variant_type_get_string_length(variant_type); + + return CSTR2RVAL_LEN(string, string_length); +} + +static VALUE +rg_definite_p(VALUE self) +{ + GVariantType *variant_type; + + variant_type = _SELF(self); + return CBOOL2RVAL(g_variant_type_is_definite(variant_type)); +} + +static VALUE +rg_container_p(VALUE self) +{ + GVariantType *variant_type; + + variant_type = _SELF(self); + return CBOOL2RVAL(g_variant_type_is_container(variant_type)); +} + +static VALUE +rg_basic_p(VALUE self) +{ + GVariantType *variant_type; + + variant_type = _SELF(self); + return CBOOL2RVAL(g_variant_type_is_basic(variant_type)); +} + +static VALUE +rg_maybe_p(VALUE self) +{ + GVariantType *variant_type; + + variant_type = _SELF(self); + return CBOOL2RVAL(g_variant_type_is_maybe(variant_type)); +} + +static VALUE +rg_array_p(VALUE self) +{ + GVariantType *variant_type; + + variant_type = _SELF(self); + return CBOOL2RVAL(g_variant_type_is_array(variant_type)); +} + +static VALUE +rg_tuple_p(VALUE self) +{ + GVariantType *variant_type; + + variant_type = _SELF(self); + return CBOOL2RVAL(g_variant_type_is_tuple(variant_type)); +} + +static VALUE +rg_dict_entry_p(VALUE self) +{ + GVariantType *variant_type; + + variant_type = _SELF(self); + return CBOOL2RVAL(g_variant_type_is_dict_entry(variant_type)); +} + +static VALUE +rg_variant_p(VALUE self) +{ + GVariantType *variant_type; + + variant_type = _SELF(self); + return CBOOL2RVAL(g_variant_type_is_variant(variant_type)); +} + +static VALUE +rg_operator_eq(VALUE self, VALUE other) +{ + GVariantType *variant_type1; + GVariantType *variant_type2; + + if (!RVAL2CBOOL(rb_obj_is_kind_of(other, RG_TARGET_NAMESPACE))) + return Qfalse; + + variant_type1 = _SELF(self); + variant_type2 = _SELF(other); + return CBOOL2RVAL(g_variant_type_equal(variant_type1, variant_type2)); +} + +static VALUE +rg_hash(VALUE self) +{ + GVariantType *variant_type; + + variant_type = _SELF(self); + return UINT2NUM(g_variant_type_hash(variant_type)); +} + +static VALUE +rg_is_subtype_of_p(VALUE self, VALUE rb_subtype) +{ + GVariantType *variant_type; + GVariantType *sub_variant_type; + + if (!RVAL2CBOOL(rb_obj_is_kind_of(rb_subtype, RG_TARGET_NAMESPACE))) + return Qfalse; + + variant_type = _SELF(self); + sub_variant_type = _SELF(rb_subtype); + return CBOOL2RVAL(g_variant_type_is_subtype_of(variant_type, + sub_variant_type)); +} + +static VALUE +rg_element(VALUE self) +{ + GVariantType *variant_type; + const GVariantType *element; + + variant_type = _SELF(self); + if (!(g_variant_type_is_array(variant_type) || + g_variant_type_is_maybe(variant_type))) { + rb_raise(rb_eArgError, + "must be array or maybe type: <%.*s>", + (int)g_variant_type_get_string_length(variant_type), + g_variant_type_peek_string(variant_type)); + } + + element = g_variant_type_element(variant_type); + return GVARIANTTYPE2RVAL((GVariantType *)element); +} + +void +Init_glib_variant_type(void) +{ + RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_VARIANT_TYPE, "VariantType", mGLib); + + RG_DEF_SMETHOD_P(valid, 1); + RG_DEF_SMETHOD(scan, 1); + + RG_DEF_METHOD(initialize, 1); + RG_DEF_METHOD(to_s, 0); + + RG_DEF_METHOD_P(definite, 0); + RG_DEF_METHOD_P(container, 0); + RG_DEF_METHOD_P(basic, 0); + RG_DEF_METHOD_P(maybe, 0); + RG_DEF_METHOD_P(array, 0); + RG_DEF_METHOD_P(tuple, 0); + RG_DEF_METHOD_P(dict_entry, 0); + RG_DEF_METHOD_P(variant, 0); + + RG_DEF_METHOD_OPERATOR("==", eq, 1); + + RG_DEF_METHOD(hash, 0); + RG_DEF_ALIAS("eql?", "=="); + + RG_DEF_METHOD_P(is_subtype_of, 1); + + RG_DEF_METHOD(element, 0); + + { + ID id_new; + + CONST_ID(id_new, "new"); + +#define DEF_TYPE(name) do { \ + const GVariantType *type = G_VARIANT_TYPE_ ## name; \ + const gchar *type_string; \ + gsize type_string_length; \ + VALUE rb_type_string; \ + \ + type_string = g_variant_type_peek_string(type); \ + type_string_length = g_variant_type_get_string_length(type); \ + rb_type_string = rb_str_new(type_string, \ + type_string_length); \ + rb_define_const(RG_TARGET_NAMESPACE, G_STRINGIFY(name), \ + rb_funcall(RG_TARGET_NAMESPACE, id_new, 1, \ + rb_type_string)); \ + } while (0) + + DEF_TYPE(BOOLEAN); + DEF_TYPE(BYTE); + DEF_TYPE(INT16); + DEF_TYPE(UINT16); + DEF_TYPE(INT32); + DEF_TYPE(UINT32); + DEF_TYPE(INT64); + DEF_TYPE(UINT64); + DEF_TYPE(HANDLE); + DEF_TYPE(DOUBLE); + DEF_TYPE(STRING); + DEF_TYPE(OBJECT_PATH); + DEF_TYPE(SIGNATURE); + DEF_TYPE(VARIANT); + DEF_TYPE(ANY); + DEF_TYPE(BASIC); + DEF_TYPE(MAYBE); + DEF_TYPE(ARRAY); + DEF_TYPE(TUPLE); + DEF_TYPE(UNIT); + DEF_TYPE(DICT_ENTRY); + DEF_TYPE(DICTIONARY); + DEF_TYPE(STRING_ARRAY); +# if GLIB_CHECK_VERSION(2, 30, 0) + DEF_TYPE(OBJECT_PATH_ARRAY); +# endif + DEF_TYPE(BYTESTRING); + DEF_TYPE(BYTESTRING_ARRAY); +# if GLIB_CHECK_VERSION(2, 30, 0) + DEF_TYPE(VARDICT); +# endif + +#undef DEF_TYPE + } +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib-variant.c (+297 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbglib-variant.c 2017-02-15 13:19:47 +0900 (80081ba) @@ -0,0 +1,297 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2015-2016 Ruby-GNOME2 Project Team + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" + +#define RG_TARGET_NAMESPACE cVariant + +#define _SELF(s) (DATA_PTR(s)) + +static VALUE RG_TARGET_NAMESPACE; + +VALUE +rbg_variant_to_ruby(GVariant *variant) +{ + const GVariantType *type; + + if (!variant) { + return Qnil; + } + + type = g_variant_get_type(variant); + + if (g_variant_type_equal(type, G_VARIANT_TYPE_BOOLEAN)) { + return CBOOL2RVAL(g_variant_get_boolean(variant)); + } else if (g_variant_type_equal(type, G_VARIANT_TYPE_BYTE)) { + return UINT2NUM(g_variant_get_byte(variant)); + } else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT16)) { + return INT2NUM(g_variant_get_int16(variant)); + } else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT16)) { + return UINT2NUM(g_variant_get_uint16(variant)); + } else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT32)) { + return INT2NUM(g_variant_get_int32(variant)); + } else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT32)) { + return UINT2NUM(g_variant_get_uint32(variant)); + } else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT64)) { + return rbglib_int64_to_num(g_variant_get_int64(variant)); + } else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT64)) { + return rbglib_uint64_to_num(g_variant_get_uint64(variant)); + } else if (g_variant_type_equal(type, G_VARIANT_TYPE_DOUBLE)) { + return rb_float_new(g_variant_get_double(variant)); + } else if (g_variant_type_equal(type, G_VARIANT_TYPE_STRING) || + g_variant_type_equal(type, G_VARIANT_TYPE_OBJECT_PATH) || + g_variant_type_equal(type, G_VARIANT_TYPE_SIGNATURE)) { + const gchar *string; + gsize string_length; + string = g_variant_get_string(variant, &string_length); + return CSTR2RVAL_LEN(string, string_length); + } else if (g_variant_type_equal(type, G_VARIANT_TYPE_HANDLE)) { + return INT2NUM(g_variant_get_handle(variant)); + } else if (g_variant_type_equal(type, G_VARIANT_TYPE_VARIANT)) { + GVariant *val = g_variant_get_variant(variant); + VALUE value = rbg_variant_to_ruby(val); + g_variant_unref(val); + return value; + } else if (g_variant_type_is_array(type)) { + gsize i, len = g_variant_n_children(variant); + VALUE ary = rb_ary_new2(len); + for (i = 0; i < len; i++) { + GVariant *val = g_variant_get_child_value(variant, i); + rb_ary_store(ary, i, rbg_variant_to_ruby(val)); + g_variant_unref(val); + } + return ary; + } else { + rb_raise(rb_eNotImpError, + "TODO: GVariant(%.*s) -> Ruby", + (int)g_variant_type_get_string_length(type), + g_variant_type_peek_string(type)); + } + + return Qnil; +} + +GVariant * +rbg_variant_from_ruby(VALUE rb_variant) +{ + if (NIL_P(rb_variant)) { + return NULL; + } else { + return _SELF(rb_variant); + } +} + +static void +rg_variant_free(gpointer object) +{ + GVariant *variant = object; + + g_variant_unref(variant); +} + +static VALUE +rg_variant_allocate(VALUE klass) +{ + return Data_Wrap_Struct(klass, NULL, rg_variant_free, NULL); +} + +static GVariant * +rg_ruby_to_variant(VALUE rb_value, VALUE rb_variant_type) +{ + const GVariantType *variant_type; + + if (NIL_P(rb_variant_type)) { + switch (rb_type(rb_value)) { + case RUBY_T_TRUE: + case RUBY_T_FALSE: + variant_type = G_VARIANT_TYPE_BOOLEAN; + break; + case RUBY_T_FIXNUM: + variant_type = G_VARIANT_TYPE_INT64; + break; + case RUBY_T_FLOAT: + variant_type = G_VARIANT_TYPE_DOUBLE; + break; + case RUBY_T_STRING: + variant_type = G_VARIANT_TYPE_STRING; + break; + case RUBY_T_ARRAY: + variant_type = G_VARIANT_TYPE_ARRAY; + break; + default: + rb_raise(rb_eNotImpError, + "TODO: Ruby -> GVariantType: %s", + RBG_INSPECT(rb_value)); + break; + } + } else { + variant_type = RVAL2GVARIANTTYPE(rb_variant_type); + } + + if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_BOOLEAN)) { + return g_variant_new_boolean(RVAL2CBOOL(rb_value)); + } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_BYTE)) { + return g_variant_new_byte(NUM2UINT(rb_value)); + } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_INT16)) { + return g_variant_new_int16(NUM2INT(rb_value)); + } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_UINT16)) { + return g_variant_new_uint16(NUM2UINT(rb_value)); + } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_INT32)) { + return g_variant_new_int32(NUM2INT(rb_value)); + } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_UINT32)) { + return g_variant_new_uint32(NUM2UINT(rb_value)); + } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_INT64)) { + return g_variant_new_int64(NUM2LONG(rb_value)); + } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_UINT64)) { + return g_variant_new_uint64(NUM2ULONG(rb_value)); + } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_HANDLE)) { + return g_variant_new_handle(NUM2INT(rb_value)); + } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_DOUBLE)) { + return g_variant_new_double(NUM2DBL(rb_value)); + } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_STRING)) { + return g_variant_new_string(RVAL2CSTR_ACCEPT_NIL(rb_value)); + } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_OBJECT_PATH)) { + return g_variant_new_object_path(RVAL2CSTR_ACCEPT_NIL(rb_value)); + } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_SIGNATURE)) { + return g_variant_new_signature(RVAL2CSTR_ACCEPT_NIL(rb_value)); + } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_VARIANT)) { + return g_variant_new_variant(rbg_variant_from_ruby(rb_value)); + } else if (g_variant_type_equal(variant_type, + G_VARIANT_TYPE_STRING_ARRAY)) { + const gchar **strings; + gssize length; + if (NIL_P(rb_value)) { + strings = NULL; + length = 0; + } else { + gssize i; + + length = RARRAY_LEN(rb_value); + strings = ALLOCA_N(const gchar *, length); + for (i = 0; i < length; i++) { + VALUE rb_string = RARRAY_PTR(rb_value)[i]; + strings[i] = RVAL2CSTR_ACCEPT_NIL(rb_string); + } + } + return g_variant_new_strv(strings, length); +#if GLIB_CHECK_VERSION(2, 30, 0) + } else if (g_variant_type_equal(variant_type, + G_VARIANT_TYPE_OBJECT_PATH_ARRAY)) { + const gchar **paths; + gssize length; + if (NIL_P(rb_value)) { + paths = NULL; + length = 0; + } else { + gssize i; + + length = RARRAY_LEN(rb_value); + paths = ALLOCA_N(const gchar *, length); + for (i = 0; i < length; i++) { + VALUE rb_path = RARRAY_PTR(rb_value)[i]; + paths[i] = RVAL2CSTR_ACCEPT_NIL(rb_path); + } + } + return g_variant_new_objv(paths, length); +#endif + } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_ARRAY)) { + int i; + GVariantBuilder builder; + g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY); + for (i = 0; i < RARRAY_LEN(rb_value); i++) { + GVariant *val = rg_ruby_to_variant(rb_ary_entry(rb_value, i), Qnil); + g_variant_builder_add_value(&builder, val); + } + return g_variant_builder_end(&builder); + } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_BYTESTRING)) { + return g_variant_new_bytestring(RVAL2CSTR_RAW_ACCEPT_NIL(rb_value)); + } else if (g_variant_type_equal(variant_type, + G_VARIANT_TYPE_BYTESTRING_ARRAY)) { + const gchar **strings; + gssize length; + if (NIL_P(rb_value)) { + strings = NULL; + length = 0; + } else { + gssize i; + + length = RARRAY_LEN(rb_value); + strings = ALLOCA_N(const gchar *, length); + for (i = 0; i < length; i++) { + VALUE rb_string = RARRAY_PTR(rb_value)[i]; + strings[i] = RVAL2CSTR_RAW_ACCEPT_NIL(rb_string); + } + } + return g_variant_new_bytestring_array(strings, length); + } else { + rb_raise(rb_eNotImpError, + "TODO: Ruby -> GVariant(%.*s): %s", + (int)g_variant_type_get_string_length(variant_type), + g_variant_type_peek_string(variant_type), + RBG_INSPECT(rb_value)); + } +} + +static VALUE +rg_initialize(int argc, VALUE *argv, VALUE self) +{ + GVariant *variant; + VALUE rb_value; + VALUE rb_variant_type; + + rb_scan_args(argc, argv, "11", &rb_value, &rb_variant_type); + variant = rg_ruby_to_variant(rb_value, rb_variant_type); + g_variant_ref_sink(variant); + DATA_PTR(self) = variant; + + return Qnil; +} + +static VALUE +rg_value(VALUE self) +{ + GVariant *variant; + + variant = _SELF(self); + + return rbg_variant_to_ruby(variant); +} + +static VALUE +rg_type(VALUE self) +{ + GVariant *variant; + + variant = _SELF(self); + + return GVARIANTTYPE2RVAL((GVariantType *)g_variant_get_type(variant)); +} + +void +Init_glib_variant(void) +{ + RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_VARIANT, "Variant", mGLib); + + rb_define_alloc_func(RG_TARGET_NAMESPACE, rg_variant_allocate); + + RG_DEF_METHOD(initialize, -1); + RG_DEF_METHOD(value, 0); + RG_DEF_METHOD(type, 0); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib.c (+1192 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbglib.c 2017-02-15 13:19:47 +0900 (16ae862) @@ -0,0 +1,1192 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011-2015 Ruby-GNOME2 Project Team + * Copyright (C) 2002,2003 Masahiro Sakai + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include <locale.h> +#include "rbgprivate.h" +#include "rbglib.h" + +#define RG_TARGET_NAMESPACE mGLib + +static ID id_inspect; + +VALUE RG_TARGET_NAMESPACE; + +const gchar * +rbg_rval2cstr(VALUE *str) +{ + StringValue(*str); + + if (rb_enc_get(*str) != rb_utf8_encoding()) + *str = rb_str_export_to_enc(*str, rb_utf8_encoding()); + + return StringValueCStr(*str); +} + +const gchar * +rbg_rval2cstr_raw(VALUE *str) +{ + StringValue(*str); + + return StringValueCStr(*str); +} + +const gchar * +rbg_rval2cstr_ptr(VALUE *str) +{ + StringValue(*str); + + return RSTRING_PTR(*str); +} + +const gchar * +rbg_rval_inspect(VALUE object) +{ + VALUE inspected = rb_funcall(object, id_inspect, 0); + + return RVAL2CSTR(inspected); +} + +char * +rbg_string_value_ptr(volatile VALUE *ptr) +{ + return rb_string_value_ptr(ptr); +} + +const gchar * +rbg_rval2cstr_accept_nil(VALUE *str) +{ + return NIL_P(*str) ? NULL : RVAL2CSTR(*str); +} + +const gchar * +rbg_rval2cstr_raw_accept_nil(VALUE *str) +{ + return NIL_P(*str) ? NULL : RVAL2CSTR_RAW(*str); +} + +const gchar * +rbg_rval2cstr_ptr_accept_nil(VALUE *str) +{ + return NIL_P(*str) ? NULL : RVAL2CSTR_PTR(*str); +} + +/* TODO: How do we deal with encodings? */ +const gchar * +rbg_rval2cstr_accept_symbol(volatile VALUE *value) +{ + if (!SYMBOL_P(*value)) + return rbg_rval2cstr((VALUE *)value); + + return rb_id2name(SYM2ID(*value)); +} + +const gchar * +rbg_rval2cstr_accept_symbol_accept_nil(volatile VALUE *value) +{ + return NIL_P(*value) ? NULL : rbg_rval2cstr_accept_symbol(value); +} + +const gchar * +rbg_rval2glibid(volatile VALUE *value, volatile VALUE *buf, gboolean accept_nil) +{ + gchar *id, *p; + + if (accept_nil && NIL_P(*value)) + return NULL; + + if (SYMBOL_P(*value)) { + *buf = rb_String(*value); + } else { + StringValue(*value); + *buf = rb_str_dup(*value); + } + RB_GC_GUARD(*buf); + + id = RSTRING_PTR(*buf); + for (p = id; *p; p++) + if (*p == '_') + *p = '-'; + + return id; +} + +VALUE +rbg_cstr2rval(const gchar *str) +{ + return str != NULL ? CSTR2RVAL_LEN(str, strlen(str)) : Qnil; +} + +VALUE +rbg_cstr2rval_len(const gchar *str, gsize len) +{ + if (str == NULL) + return Qnil; + + return rb_external_str_new_with_enc(str, len, rb_utf8_encoding()); +} + +struct rbg_cstr2rval_len_free_args { + gchar *str; + gsize len; +}; + +static VALUE +rbg_cstr2rval_len_free_body(VALUE value) +{ + struct rbg_cstr2rval_len_free_args *args = (struct rbg_cstr2rval_len_free_args *)value; + + return CSTR2RVAL_LEN(args->str, args->len); +} + +static VALUE +rbg_cstr2rval_len_free_ensure(VALUE str) +{ + g_free((gchar *)str); + + return Qnil; +} + +VALUE +rbg_cstr2rval_len_free(gchar *str, gsize len) +{ + struct rbg_cstr2rval_len_free_args args = { str, len }; + + return str != NULL ? rb_ensure(rbg_cstr2rval_len_free_body, (VALUE)&args, + rbg_cstr2rval_len_free_ensure, (VALUE)str) : Qnil; +} + +VALUE +rbg_cstr2rval_with_encoding(const gchar *str, const gchar *encoding) +{ + return str != NULL ? CSTR2RVAL_LEN_ENC(str, strlen(str), encoding) : Qnil; +} + +VALUE +rbg_cstr2rval_len_with_encoding(const gchar *str, gsize len, + const gchar *encoding) +{ + if (str == NULL) + return Qnil; + + return rb_external_str_new_with_enc(str, len, + encoding != NULL ? + rb_enc_find(encoding) : + rb_utf8_encoding()); +} + +static VALUE +rbg_cstr2rval_free_body(VALUE str) +{ + return CSTR2RVAL((const gchar *)str); +} + +static VALUE +rbg_cstr2rval_free_ensure(VALUE str) +{ + g_free((gchar *)str); + + return Qnil; +} + +VALUE +rbg_cstr2rval_free(gchar *str) +{ + return str != NULL? rb_ensure(rbg_cstr2rval_free_body, (VALUE)str, + rbg_cstr2rval_free_ensure, (VALUE)str) : Qnil; +} + +/* just for backward compatibility. */ +VALUE +rbg_cstr2rval_with_free(gchar *str) +{ + return rbg_cstr2rval_free(str); +} + +static rb_encoding *filename_encoding_if_not_utf8; + +static VALUE +rbg_filename_to_ruby_body(VALUE filename) +{ + const gchar *filename_utf8 = (const gchar *)filename; + VALUE rb_filename; + + rb_filename = rb_external_str_new_with_enc(filename_utf8, + strlen(filename_utf8), + rb_utf8_encoding()); + + /* if needed, change encoding of Ruby String to filename encoding, so that + upcoming File operations will work properly */ + return filename_encoding_if_not_utf8 != NULL ? + rb_str_export_to_enc(rb_filename, filename_encoding_if_not_utf8) : + rb_filename; +} + +static VALUE +rbg_filename_to_ruby_ensure(VALUE filename) +{ + g_free((gchar *)filename); + + return Qnil; +} + +VALUE +rbg_filename_to_ruby(const gchar *filename) +{ + gchar *filename_utf8; + gsize written; + GError *error = NULL; + + if (filename == NULL) + return Qnil; + + if (filename_encoding_if_not_utf8 == NULL) + return CSTR2RVAL(filename); + + filename_utf8 = g_filename_to_utf8(filename, -1, NULL, &written, &error); + if (error != NULL) + RAISE_GERROR(error); + + return rb_ensure(rbg_filename_to_ruby_body, (VALUE)filename_utf8, + rbg_filename_to_ruby_ensure, (VALUE)filename_utf8); +} + +VALUE +rbg_filename_to_ruby_free(gchar *filename) +{ + gchar *filename_utf8; + gsize written; + + if (filename == NULL) + return Qnil; + + /* convert filename to UTF-8 if needed */ + if (filename_encoding_if_not_utf8 != NULL) { + GError *error = NULL; + + filename_utf8 = g_filename_to_utf8(filename, -1, NULL, &written, &error); + g_free(filename); + if (error != NULL) + RAISE_GERROR(error); + } else { + filename_utf8 = filename; + } + + return rb_ensure(rbg_filename_to_ruby_body, (VALUE)filename_utf8, + rbg_filename_to_ruby_ensure, (VALUE)filename_utf8); +} + +gchar * +rbg_filename_from_ruby(VALUE filename) +{ + gchar *retval; + gsize written; + GError *error = NULL; + + /* if needed, change encoding of Ruby String to UTF-8 */ + StringValue(filename); + if (rb_enc_get(filename) != rb_utf8_encoding()) + filename = rb_str_export_to_enc(filename, rb_utf8_encoding()); + + /* convert it to filename encoding if needed */ + if (filename_encoding_if_not_utf8 == NULL) + return g_strdup(RSTRING_PTR(filename)); + + retval = g_filename_from_utf8(RSTRING_PTR(filename), -1, NULL, &written, &error); + if (error != NULL) + RAISE_GERROR(error); + + return retval; +} + +struct rval2strv_args { + VALUE ary; + long n; + const gchar **result; +}; + +static VALUE +rbg_rval2strv_body(VALUE value) +{ + long i; + struct rval2strv_args *args = (struct rval2strv_args *)value; + + for (i = 0; i < args->n; i++) + args->result[i] = RVAL2CSTR(RARRAY_PTR(args->ary)[i]); + args->result[args->n] = NULL; + + return Qnil; +} + +static G_GNUC_NORETURN VALUE +rbg_rval2strv_rescue(VALUE value) +{ + g_free(((struct rval2strv_args *)value)->result); + + rb_exc_raise(rb_errinfo()); +} + +const gchar ** +rbg_rval2strv(volatile VALUE *value, long *n) +{ + struct rval2strv_args args; + + args.ary = *value = rb_ary_dup(rb_ary_to_ary(*value)); + args.n = RARRAY_LEN(args.ary); + args.result = g_new(const gchar *, args.n + 1); + + rb_rescue(rbg_rval2strv_body, (VALUE)&args, + rbg_rval2strv_rescue, (VALUE)&args); + + if (n != NULL) + *n = args.n; + + return args.result; +} + +const gchar ** +rbg_rval2strv_accept_nil(volatile VALUE *value, long *n) +{ + if (!NIL_P(*value)) + return rbg_rval2strv(value, n); + + if (n != NULL) + *n = 0; + + return NULL; +} + +struct rval2strv_dup_args { + VALUE ary; + long n; + gchar **result; +}; + +static VALUE +rbg_rval2strv_dup_body(VALUE value) +{ + long i; + struct rval2strv_dup_args *args = (struct rval2strv_dup_args *)value; + + for (i = 0; i < args->n; i++) + args->result[i] = g_strdup(RVAL2CSTR(RARRAY_PTR(args->ary)[i])); + args->result[args->n] = NULL; + + return Qnil; +} + +static G_GNUC_NORETURN VALUE +rbg_rval2strv_dup_rescue(VALUE value) +{ + g_free(((struct rval2strv_dup_args *)value)->result); + + rb_exc_raise(rb_errinfo()); +} + +gchar ** +rbg_rval2strv_dup(volatile VALUE *value, long *n) +{ + struct rval2strv_dup_args args; + + args.ary = *value = rb_ary_dup(rb_ary_to_ary(*value)); + args.n = RARRAY_LEN(args.ary); + args.result = g_new(gchar *, args.n + 1); + + rb_rescue(rbg_rval2strv_dup_body, (VALUE)&args, + rbg_rval2strv_dup_rescue, (VALUE)&args); + + if (n != NULL) + *n = args.n; + + return args.result; +} + +gchar ** +rbg_rval2strv_dup_accept_nil(volatile VALUE *value, long *n) +{ + if (!NIL_P(*value)) + rbg_rval2strv_dup(value, n); + + if (n != NULL) + *n = 0; + + return NULL; +} + +VALUE +rbg_strv2rval(const gchar **strings) +{ + VALUE ary; + const gchar **p; + + if (strings == NULL) + return Qnil; + + ary = rb_ary_new(); + for (p = strings; *p != NULL; p++) + rb_ary_push(ary, CSTR2RVAL(*p)); + + return ary; +} + +static VALUE +rbg_strv2rval_free_body(VALUE strings) +{ + return STRV2RVAL((const gchar **)strings); +} + +static VALUE +rbg_strv2rval_free_ensure(VALUE strings) +{ + g_strfreev((gchar **)strings); + + return Qnil; +} + +VALUE +rbg_strv2rval_free(gchar **strings) +{ + return rb_ensure(rbg_strv2rval_free_body, (VALUE)strings, + rbg_strv2rval_free_ensure, (VALUE)strings); +} + +struct rbg_rval2gbooleans_args { + VALUE ary; + long n; + gboolean *result; +}; + +static VALUE +rbg_rval2gbooleans_body(VALUE value) +{ + long i; + struct rbg_rval2gbooleans_args *args = (struct rbg_rval2gbooleans_args *)value; + + for (i = 0; i < args->n; i++) + args->result[i] = RVAL2CBOOL(RARRAY_PTR(args->ary)[i]); + + return Qnil; +} + +static G_GNUC_NORETURN VALUE +rbg_rval2gbooleans_rescue(VALUE value) +{ + g_free(((struct rbg_rval2gbooleans_args *)value)->result); + + rb_exc_raise(rb_errinfo()); +} + +gboolean * +rbg_rval2gbooleans(volatile VALUE *value, long *n) +{ + struct rbg_rval2gbooleans_args args; + + args.ary = *value = rb_ary_dup(rb_ary_to_ary(*value)); + args.n = RARRAY_LEN(args.ary); + args.result = g_new(gboolean, args.n + 1); + + rb_rescue(rbg_rval2gbooleans_body, (VALUE)&args, + rbg_rval2gbooleans_rescue, (VALUE)&args); + + *n = args.n; + + return args.result; +} + +struct rbg_rval2gints_args { + VALUE ary; + long n; + gint *result; +}; + +static VALUE +rbg_rval2gints_body(VALUE value) +{ + long i; + struct rbg_rval2gints_args *args = (struct rbg_rval2gints_args *)value; + + for (i = 0; i < args->n; i++) + args->result[i] = NUM2INT(RARRAY_PTR(args->ary)[i]); + + return Qnil; +} + +static G_GNUC_NORETURN VALUE +rbg_rval2gints_rescue(VALUE value) +{ + g_free(((struct rbg_rval2gints_args *)value)->result); + + rb_exc_raise(rb_errinfo()); +} + +gint * +rbg_rval2gints(volatile VALUE *value, long *n) +{ + struct rbg_rval2gints_args args; + + args.ary = *value = rb_ary_dup(rb_ary_to_ary(*value)); + args.n = RARRAY_LEN(args.ary); + args.result = g_new(gint, args.n + 1); + + rb_rescue(rbg_rval2gints_body, (VALUE)&args, + rbg_rval2gints_rescue, (VALUE)&args); + + *n = args.n; + + return args.result; +} + +struct rbg_rval2gint8s_args { + VALUE ary; + long n; + gint8 *result; +}; + +static VALUE +rbg_rval2gint8s_body(VALUE value) +{ + long i; + struct rbg_rval2gint8s_args *args = (struct rbg_rval2gint8s_args *)value; + + for (i = 0; i < args->n; i++) + args->result[i] = NUM2CHR(RARRAY_PTR(args->ary)[i]); + + return Qnil; +} + +static G_GNUC_NORETURN VALUE +rbg_rval2gint8s_rescue(VALUE value) +{ + g_free(((struct rbg_rval2gint8s_args *)value)->result); + + rb_exc_raise(rb_errinfo()); +} + +gint8 * +rbg_rval2gint8s(volatile VALUE *value, long *n) +{ + struct rbg_rval2gint8s_args args; + + args.ary = *value = rb_ary_dup(rb_ary_to_ary(*value)); + args.n = RARRAY_LEN(args.ary); + args.result = g_new(gint8, args.n + 1); + + rb_rescue(rbg_rval2gint8s_body, (VALUE)&args, + rbg_rval2gint8s_rescue, (VALUE)&args); + + *n = args.n; + + return args.result; +} + +struct rbg_rval2guint8s_args { + VALUE ary; + long n; + guint8 *result; +}; + +static VALUE +rbg_rval2guint8s_body(VALUE value) +{ + long i; + struct rbg_rval2guint8s_args *args = (struct rbg_rval2guint8s_args *)value; + + for (i = 0; i < args->n; i++) + args->result[i] = NUM2UINT(RARRAY_PTR(args->ary)[i]); + + return Qnil; +} + +static G_GNUC_NORETURN VALUE +rbg_rval2guint8s_rescue(VALUE value) +{ + g_free(((struct rbg_rval2guint8s_args *)value)->result); + + rb_exc_raise(rb_errinfo()); +} + +guint8 * +rbg_rval2guint8s(volatile VALUE *value, long *n) +{ + struct rbg_rval2guint8s_args args; + + args.ary = *value = rb_ary_dup(rb_ary_to_ary(*value)); + args.n = RARRAY_LEN(args.ary); + args.result = g_new(guint8, args.n + 1); + + rb_rescue(rbg_rval2guint8s_body, (VALUE)&args, + rbg_rval2guint8s_rescue, (VALUE)&args); + + *n = args.n; + + return args.result; +} + +struct rbg_rval2guint16s_args { + VALUE ary; + long n; + guint16 *result; +}; + +static VALUE +rbg_rval2guint16s_body(VALUE value) +{ + long i; + struct rbg_rval2guint16s_args *args = (struct rbg_rval2guint16s_args *)value; + + for (i = 0; i < args->n; i++) + args->result[i] = NUM2UINT(RARRAY_PTR(args->ary)[i]); + + return Qnil; +} + +static G_GNUC_NORETURN VALUE +rbg_rval2guint16s_rescue(VALUE value) +{ + g_free(((struct rbg_rval2guint16s_args *)value)->result); + + rb_exc_raise(rb_errinfo()); +} + +guint16 * +rbg_rval2guint16s(volatile VALUE *value, long *n) +{ + struct rbg_rval2guint16s_args args; + + args.ary = *value = rb_ary_dup(rb_ary_to_ary(*value)); + args.n = RARRAY_LEN(args.ary); + args.result = g_new(guint16, args.n + 1); + + rb_rescue(rbg_rval2guint16s_body, (VALUE)&args, + rbg_rval2guint16s_rescue, (VALUE)&args); + + *n = args.n; + + return args.result; +} + +struct rbg_rval2guint32s_args { + VALUE ary; + long n; + guint32 *result; +}; + +static VALUE +rbg_rval2guint32s_body(VALUE value) +{ + long i; + struct rbg_rval2guint32s_args *args = (struct rbg_rval2guint32s_args *)value; + + for (i = 0; i < args->n; i++) + args->result[i] = NUM2UINT(RARRAY_PTR(args->ary)[i]); + + return Qnil; +} + +static G_GNUC_NORETURN VALUE +rbg_rval2guint32s_rescue(VALUE value) +{ + g_free(((struct rbg_rval2guint32s_args *)value)->result); + + rb_exc_raise(rb_errinfo()); +} + +guint32 * +rbg_rval2guint32s(volatile VALUE *value, long *n) +{ + struct rbg_rval2guint32s_args args; + + args.ary = *value = rb_ary_dup(rb_ary_to_ary(*value)); + args.n = RARRAY_LEN(args.ary); + args.result = g_new(guint32, args.n + 1); + + rb_rescue(rbg_rval2guint32s_body, (VALUE)&args, + rbg_rval2guint32s_rescue, (VALUE)&args); + + *n = args.n; + + return args.result; +} + +struct rbg_rval2gdoubles_args { + VALUE ary; + long n; + gdouble *result; +}; + +static VALUE +rbg_rval2gdoubles_body(VALUE value) +{ + long i; + struct rbg_rval2gdoubles_args *args = (struct rbg_rval2gdoubles_args *)value; + + for (i = 0; i < args->n; i++) + args->result[i] = NUM2DBL(RARRAY_PTR(args->ary)[i]); + + return Qnil; +} + +static G_GNUC_NORETURN VALUE +rbg_rval2gdoubles_rescue(VALUE value) +{ + g_free(((struct rbg_rval2gdoubles_args *)value)->result); + + rb_exc_raise(rb_errinfo()); +} + +gdouble * +rbg_rval2gdoubles(volatile VALUE *value, long *n) +{ + struct rbg_rval2gdoubles_args args; + + args.ary = *value = rb_ary_dup(rb_ary_to_ary(*value)); + args.n = RARRAY_LEN(args.ary); + args.result = g_new(gdouble, args.n + 1); + + rb_rescue(rbg_rval2gdoubles_body, (VALUE)&args, + rbg_rval2gdoubles_rescue, (VALUE)&args); + + *n = args.n; + + return args.result; +} + +VALUE +rbg_gints2rval(const gint *gints, long n) +{ + long i; + VALUE ary = rb_ary_new(); + + for (i = 0; i < n; i++) + rb_ary_push(ary, INT2NUM(gints[i])); + + return ary; +} + +struct rbg_gints2rval_free_args { + gint *gints; + long n; +}; + +static VALUE +rbg_gints2rval_free_body(VALUE value) +{ + struct rbg_gints2rval_free_args *args = (struct rbg_gints2rval_free_args *)value; + + return rbg_gints2rval(args->gints, args->n); +} + +static VALUE +rbg_gints2rval_free_ensure(VALUE value) +{ + g_free(((struct rbg_gints2rval_free_args *)value)->gints); + + return Qnil; +} + +VALUE +rbg_gints2rval_free(gint *gints, long n) +{ + struct rbg_gints2rval_free_args args = { gints, n }; + + return rb_ensure(rbg_gints2rval_free_body, (VALUE)&args, + rbg_gints2rval_free_ensure, (VALUE)&args); +} + +const gchar * +rbg_inspect (VALUE object) +{ + VALUE inspected; + + inspected = rb_funcall(object, rb_intern("inspect"), 0); + return StringValueCStr(inspected); +} + +VALUE +rbg_to_array (VALUE object) +{ + return rb_convert_type(object, RUBY_T_ARRAY, "Array", "to_ary"); +} + +VALUE +rbg_to_hash (VALUE object) +{ + return rb_convert_type(object, RUBY_T_HASH, "Hash", "to_hash"); +} + +VALUE +rbg_check_array_type (VALUE object) +{ +#ifdef HAVE_RB_CHECK_ARRAY_TYPE + return rb_check_array_type(object); +#else + return rb_check_convert_type(object, RUBY_T_ARRAY, "Array", "to_ary"); +#endif +} + +VALUE +rbg_check_hash_type (VALUE object) +{ +#ifdef HAVE_RB_CHECK_HASH_TYPE + return rb_check_hash_type(object); +#else + return rb_check_convert_type(object, RUBY_T_HASH, "Hash", "to_hash"); +#endif +} + +void +rbg_scan_options (VALUE options, ...) +{ + const char *key; + gsize n_keys = 0; + gsize n_found_keys = 0; + va_list args; + va_list args_copy; + + if (!NIL_P(options)) { + VALUE original_options = options; + options = rbg_check_hash_type(options); + if (NIL_P(options)) { + rb_raise(rb_eArgError, + "options must be Hash or nil: %+" PRIsVALUE, + original_options); + } + } + + va_start(args, options); + va_copy(args_copy, args); + key = va_arg(args, const char *); + n_keys = 0; + n_found_keys = 0; + while (key) { + VALUE *value; + + value = va_arg(args, VALUE *); + if (NIL_P(options)) { + *value = Qnil; + } else { + VALUE rb_key; + rb_key = ID2SYM(rb_intern(key)); + if (RTEST(rb_funcall(options, rb_intern("key?"), 1, rb_key))) { + n_found_keys++; + } + *value = rb_hash_aref(options, rb_key); + } + n_keys++; + + key = va_arg(args, const char *); + } + va_end(args); + + if (NIL_P(options)) { + return; + } + + if (n_found_keys == RHASH_SIZE(options)) { + return; + } + + { + VALUE rb_available_keys; + + rb_available_keys = rb_ary_new(); + key = va_arg(args_copy, const char *); + while (key) { + VALUE rb_key; + + va_arg(args_copy, VALUE *); + rb_key = ID2SYM(rb_intern(key)); + rb_ary_push(rb_available_keys, rb_key); + key = va_arg(args_copy, const char *); + } + va_end(args_copy); + + rb_raise(rb_eArgError, + "unexpected key(s) exist: %+" PRIsVALUE + ": available keys: %+" PRIsVALUE, + rb_funcall(rb_funcall(options, rb_intern("keys"), 0), + rb_intern("-"), + 1, + rb_available_keys), + rb_available_keys); + } +} + +#if 0 +/* +2004-04-15 Commented out by Masao. + +These functions replace g_malloc/g_realloc/g_free of GLib. +When g_malloc is called and the memory area can not reserved, +rb_gc() will be called. It makes Ruby-GNOME2 uses memory efficiently. + +But rb_gc() does not work under multithread. +So they occur "cross-thread violation". +*/ + +static gpointer +my_malloc(gsize n_bytes) +{ + /* Should we rescue NoMemoryError? */ + return ruby_xmalloc(n_bytes); +} + +static gpointer +my_realloc(gpointer mem, gsize n_bytes) +{ + /* Should we rescue NoMemoryError? */ + return ruby_xrealloc(mem, n_bytes); +} + +static void +my_free(gpointer mem) +{ + return ruby_xfree(mem); +} + +static void +Init_mem() +{ + GMemVTable mem_table = { + my_malloc, + my_realloc, + my_free, + NULL, + NULL, + NULL, + }; + g_mem_set_vtable(&mem_table); +} +#endif + +static VALUE +rg_s_os_win32_p(G_GNUC_UNUSED VALUE self) +{ +#ifdef G_OS_WIN32 + return Qtrue; +#else + return Qfalse; +#endif +} + +static VALUE +rg_s_os_beos_p(G_GNUC_UNUSED VALUE self) +{ +#ifdef G_OS_BEOS + return Qtrue; +#else + return Qfalse; +#endif +} + +static VALUE +rg_s_os_unix_p(G_GNUC_UNUSED VALUE self) +{ +#ifdef G_OS_UNIX + return Qtrue; +#else + return Qfalse; +#endif +} + +extern void Init_glib2(void); + +void +Init_glib2(void) +{ + const gchar **filename_charsets; + + id_inspect = rb_intern("inspect"); + + RG_TARGET_NAMESPACE = rb_define_module("GLib"); + + setlocale (LC_CTYPE, ""); +#ifdef LC_MESSAGES + setlocale (LC_MESSAGES, ""); +#endif + + /* Version Information */ + rb_define_const(RG_TARGET_NAMESPACE, "VERSION", + rb_ary_new3(3, + INT2FIX(glib_major_version), + INT2FIX(glib_minor_version), + INT2FIX(glib_micro_version))); + rb_define_const(RG_TARGET_NAMESPACE, "MAJOR_VERSION", INT2FIX(glib_major_version)); + rb_define_const(RG_TARGET_NAMESPACE, "MINOR_VERSION", INT2FIX(glib_minor_version)); + rb_define_const(RG_TARGET_NAMESPACE, "MICRO_VERSION", INT2FIX(glib_micro_version)); + rb_define_const(RG_TARGET_NAMESPACE, "INTERFACE_AGE", INT2FIX(glib_interface_age)); + rb_define_const(RG_TARGET_NAMESPACE, "BINARY_AGE", INT2FIX(glib_binary_age)); + + rb_define_const(RG_TARGET_NAMESPACE, "BINDING_VERSION", + rb_ary_new3(3, + INT2FIX(RBGLIB_MAJOR_VERSION), + INT2FIX(RBGLIB_MINOR_VERSION), + INT2FIX(RBGLIB_MICRO_VERSION))); + + rb_define_const(RG_TARGET_NAMESPACE, "BUILD_VERSION", + rb_ary_new3(3, + INT2FIX(GLIB_MAJOR_VERSION), + INT2FIX(GLIB_MINOR_VERSION), + INT2FIX(GLIB_MICRO_VERSION))); + + /* Limits of Basic Types */ + rb_define_const(RG_TARGET_NAMESPACE, "MININT", INT2FIX(G_MININT)); + rb_define_const(RG_TARGET_NAMESPACE, "MAXINT", INT2NUM(G_MAXINT)); + rb_define_const(RG_TARGET_NAMESPACE, "MAXUINT", UINT2NUM(G_MAXUINT)); + + rb_define_const(RG_TARGET_NAMESPACE, "MINSHORT", INT2FIX(G_MINSHORT)); + rb_define_const(RG_TARGET_NAMESPACE, "MAXSHORT", INT2FIX(G_MAXSHORT)); + rb_define_const(RG_TARGET_NAMESPACE, "MAXUSHORT", UINT2NUM(G_MAXUSHORT)); + + rb_define_const(RG_TARGET_NAMESPACE, "MINLONG", INT2FIX(G_MINLONG)); + rb_define_const(RG_TARGET_NAMESPACE, "MAXLONG", INT2NUM(G_MAXLONG)); + rb_define_const(RG_TARGET_NAMESPACE, "MAXULONG", UINT2NUM(G_MAXULONG)); + + rb_define_const(RG_TARGET_NAMESPACE, "MININT8", INT2FIX(G_MININT8)); + rb_define_const(RG_TARGET_NAMESPACE, "MAXINT8", INT2FIX(G_MAXINT8)); + rb_define_const(RG_TARGET_NAMESPACE, "MAXUINT8", UINT2NUM(G_MAXUINT8)); + + rb_define_const(RG_TARGET_NAMESPACE, "MININT16", INT2FIX(G_MININT16)); + rb_define_const(RG_TARGET_NAMESPACE, "MAXINT16", INT2FIX(G_MAXINT16)); + rb_define_const(RG_TARGET_NAMESPACE, "MAXUINT16", UINT2NUM(G_MAXUINT16)); + + rb_define_const(RG_TARGET_NAMESPACE, "MININT32", INT2FIX(G_MININT32)); + rb_define_const(RG_TARGET_NAMESPACE, "MAXINT32", INT2NUM(G_MAXINT32)); + rb_define_const(RG_TARGET_NAMESPACE, "MAXUINT32", UINT2NUM(G_MAXUINT32)); + + rb_define_const(RG_TARGET_NAMESPACE, "MININT64", INT2FIX(G_MININT64)); + rb_define_const(RG_TARGET_NAMESPACE, "MAXINT64", LL2NUM(G_MAXINT64)); + rb_define_const(RG_TARGET_NAMESPACE, "MAXUINT64", ULL2NUM(G_MAXUINT64)); + + rb_define_const(RG_TARGET_NAMESPACE, "MAXSIZE", UINT2NUM(G_MAXSIZE)); + + rb_define_const(RG_TARGET_NAMESPACE, "MINFLOAT", INT2FIX(G_MINFLOAT)); + rb_define_const(RG_TARGET_NAMESPACE, "MAXFLOAT", DBL2NUM(G_MAXFLOAT)); + + rb_define_const(RG_TARGET_NAMESPACE, "MINDOUBLE", INT2FIX(G_MINDOUBLE)); + rb_define_const(RG_TARGET_NAMESPACE, "MAXDOUBLE", DBL2NUM(G_MAXDOUBLE)); + + /* Standard Macros */ + RG_DEF_SMETHOD_P(os_win32, 0); + RG_DEF_SMETHOD_P(os_beos, 0); + RG_DEF_SMETHOD_P(os_unix, 0); + + rb_define_const(RG_TARGET_NAMESPACE, "DIR_SEPARATOR", CSTR2RVAL(G_DIR_SEPARATOR_S)); + rb_define_const(RG_TARGET_NAMESPACE, "SEARCHPATH_SEPARATOR", CSTR2RVAL(G_SEARCHPATH_SEPARATOR_S)); + + /* discover and store glib filename encoding */ + if (g_get_filename_charsets(&filename_charsets) + || filename_charsets == NULL + || filename_charsets[0] == NULL + || !strcmp(filename_charsets[0], "UTF-8") + || rb_enc_find(filename_charsets[0]) == rb_enc_find("ASCII-8BIT")) { + /* set to NULL, mean do not perform transcoding, either filename + encoding is unknown, UTF-8, or unsupported */ + filename_encoding_if_not_utf8 = NULL; + } else { + filename_encoding_if_not_utf8 = rb_enc_find(filename_charsets[0]); + } + +/* Don't implement them. +#define G_DIR_SEPARATOR_S +#define G_IS_DIR_SEPARATOR (c) +#define G_SEARCHPATH_SEPARATOR +#define TRUE +#define FALSE +#define NULL +#define MIN (a, b) +#define MAX (a, b) +#define ABS (a) +#define CLAMP (x, low, high) +#define G_STRUCT_MEMBER (member_type, struct_p, struct_offset) +#define G_STRUCT_MEMBER_P (struct_p, struct_offset) +#define G_STRUCT_OFFSET (struct_type, member) +#define G_MEM_ALIGN +#define G_CONST_RETURN +*/ + + /* Numerical Definitions */ +/* Don't implement them. +#define G_IEEE754_FLOAT_BIAS +#define G_IEEE754_DOUBLE_BIAS +union GFloatIEEE754; +union GDoubleIEEE754; +*/ + rb_define_const(RG_TARGET_NAMESPACE, "E", CSTR2RVAL(G_STRINGIFY(G_E))); + rb_define_const(RG_TARGET_NAMESPACE, "LN2", CSTR2RVAL(G_STRINGIFY(G_LN2))); + rb_define_const(RG_TARGET_NAMESPACE, "LN10", CSTR2RVAL(G_STRINGIFY(G_LN10))); + rb_define_const(RG_TARGET_NAMESPACE, "PI", CSTR2RVAL(G_STRINGIFY(G_PI))); + rb_define_const(RG_TARGET_NAMESPACE, "PI_2", CSTR2RVAL(G_STRINGIFY(G_PI_2))); + rb_define_const(RG_TARGET_NAMESPACE, "PI_4", CSTR2RVAL(G_STRINGIFY(G_PI_4))); + rb_define_const(RG_TARGET_NAMESPACE, "SQRT2", CSTR2RVAL(G_STRINGIFY(G_SQRT2))); + rb_define_const(RG_TARGET_NAMESPACE, "LOG_2_BASE_10", CSTR2RVAL(G_STRINGIFY(G_LOG_2_BASE_10))); + + /* From "The Main Event Loop" */ + rb_define_const(RG_TARGET_NAMESPACE, "PRIORITY_HIGH", INT2FIX(G_PRIORITY_HIGH)); + rb_define_const(RG_TARGET_NAMESPACE, "PRIORITY_DEFAULT", INT2FIX(G_PRIORITY_DEFAULT)); + rb_define_const(RG_TARGET_NAMESPACE, "PRIORITY_HIGH_IDLE", INT2FIX(G_PRIORITY_HIGH_IDLE)); + rb_define_const(RG_TARGET_NAMESPACE, "PRIORITY_DEFAULT_IDLE", INT2FIX(G_PRIORITY_DEFAULT_IDLE)); + rb_define_const(RG_TARGET_NAMESPACE, "PRIORITY_LOW", INT2FIX(G_PRIORITY_LOW)); + +/* Init_mem(); */ + Init_gutil(); + Init_gutil_callback(); + + Init_glib_gettext(); + Init_glib_int64(); + Init_glib_error(); + Init_glib_threads(); + Init_glib_convert(); + Init_glib_messages(); + Init_glib_fileutils(); + Init_glib_i18n(); + Init_glib_win32(); + + Init_gobject(); + + /* Require GBoxed/GObject */ + Init_glib_utils(); + Init_glib_spawn(); + Init_glib_spawnerror(); + Init_glib_main_loop(); + Init_glib_source(); + Init_glib_main_context(); + Init_glib_poll_fd(); + Init_glib_io_constants(); + Init_glib_io_channel(); + Init_glib_io_channelerror(); + Init_glib_io_channel_win32_socket(); + Init_glib_shell(); + Init_glib_shellerror(); + Init_glib_timer(); + Init_glib_unicode(); + Init_glib_utf8(); + Init_glib_utf16(); + Init_glib_ucs4(); + Init_glib_unichar(); + Init_glib_keyfile(); + Init_glib_bookmark_file(); + Init_glib_variant_type(); + Init_glib_variant(); + Init_glib_regex(); + Init_glib_matchinfo(); + Init_glib_date_time(); + Init_glib_time_zone(); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib.h (+227 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbglib.h 2017-02-15 13:19:47 +0900 (c039630) @@ -0,0 +1,227 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2002-2016 Ruby-GNOME2 Project Team + * Copyright (C) 2002,2003 Masahiro Sakai + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include <glib-object.h> +#include "glib-enum-types.h" + +#include "ruby.h" + +#include "rbglibdeprecated.h" +#include "rbglib2conversions.h" + +#ifndef __RBGLIB_H__ +#define __RBGLIB_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define RBGLIB_MAJOR_VERSION 3 +#define RBGLIB_MINOR_VERSION 1 +#define RBGLIB_MICRO_VERSION 1 + +#ifndef RB_ZALLOC +# ifdef ZALLOC +# define RB_ZALLOC(type) ZALLOC(type) +# else +# define RB_ZALLOC(type) rbg_memzero(ALLOC(type), sizeof(type)) +# endif +#endif + +#ifndef RSTRING_PTR +# define RSTRING_PTR(s) (RSTRING(s)->ptr) +# define RSTRING_LEN(s) (RSTRING(s)->len) +#endif + +#ifndef RARRAY_PTR +# define RARRAY_PTR(a) (RARRAY(a)->ptr) +# define RARRAY_LEN(a) (RARRAY(a)->len) +#endif + +#ifndef RARRAY_CONST_PTR +# define RARRAY_CONST_PTR(a) RARRAY_PTR(a) +#endif + +#ifndef DBL2NUM +# define DBL2NUM(v) (rb_float_new(v)) +#endif + +#ifndef RBASIC_CLASS +# define RBASIC_CLASS(obj) (RBASIC(obj)->klass) +#endif + +#ifndef G_SOURCE_REMOVE +# define G_SOURCE_REMOVE FALSE +#endif + +#ifndef G_SOURCE_CONTINUE +# define G_SOURCE_CONTINUE TRUE +#endif + +#define RBG_INSPECT(object) (rbg_rval_inspect(object)) + +#define RVAL2CSTR(v) (rbg_rval2cstr(&(v))) +#define RVAL2CSTR_RAW(v) (rbg_rval2cstr_raw(&(v))) +#define RVAL2CSTR_PTR(v) (rbg_rval2cstr_ptr(&(v))) +#define RVAL2CSTR_ACCEPT_NIL(v) (rbg_rval2cstr_accept_nil(&(v))) +#define RVAL2CSTR_RAW_ACCEPT_NIL(v) (rbg_rval2cstr_raw_accept_nil(&(v))) +#define RVAL2CSTR_PTR_ACCEPT_NIL(v) (rbg_rval2cstr_ptr_accept_nil(&(v))) +#define RVAL2CSTR2(v) (RVAL2CSTR_ACCEPT_NIL(v)) +#define RVAL2CSTR_ACCEPT_SYMBOL(v) (rbg_rval2cstr_accept_symbol(&(v))) +#define RVAL2CSTR_ACCEPT_SYMBOL_ACCEPT_NIL(v) (rbg_rval2cstr_accept_symbol_accept_nil(&(v))) +#define RVAL2GLIBID(v, buf) (rbg_rval2glibid(&(v), &(buf), FALSE)) +#define RVAL2GLIBID_ACCEPT_NIL(v, buf) (rbg_rval2glibid(&(v), &(buf), TRUE)) +#define CSTR2RVAL(s) (rbg_cstr2rval(s)) +#define CSTR2RVAL_LEN(s, l) (rbg_cstr2rval_len(s, l)) +#define CSTR2RVAL_LEN_FREE(s, l) (rbg_cstr2rval_len_free(s, l)) +#define CSTR2RVAL_ENC(s, e) (rbg_cstr2rval_with_encoding(s, e)) +#define CSTR2RVAL_LEN_ENC(s, l, e) (rbg_cstr2rval_len_with_encoding(s, l, e)) +#define CSTR2RVAL_FREE(s) (rbg_cstr2rval_free(s)) +#define CSTR2RVAL2(s) (CSTR2RVAL_FREE(s)) + +#if G_BYTE_ORDER == G_LITTLE_ENDIAN +# define CSTR2RVAL_LEN_UCS4(s, l) (CSTR2RVAL_LEN_ENC(s, l, "UTF-32LE")) +# define CSTR2RVAL_LEN_UTF16(s, l) (CSTR2RVAL_LEN_ENC(s, l, "UTF-16LE")) +#else +# define CSTR2RVAL_LEN_UCS4(s, l) (CSTR2RVAL_LEN_ENC(s, l, "UTF-32BE")) +# define CSTR2RVAL_LEN_UTF16(s, l) (CSTR2RVAL_LEN_ENC(s, l, "UTF-16BE")) +#endif + +#define RVAL2CSTRFILENAME(v) (rbg_filename_from_ruby(v)) +#define CSTRFILENAME2RVAL(s) (rbg_filename_to_ruby(s)) +#define CSTRFILENAME2RVAL_FREE(s) (rbg_filename_to_ruby_free(s)) + +#define RVAL2STRS(ary, n) rbg_rval2strv(&(ary), &(n)) +#define RVAL2STRS_ACCEPT_NIL(ary, n) rbg_rval2strv_accept_nil(&(ary), &(n)) +#define RVAL2STRV(ary) rbg_rval2strv(&(ary), NULL) +#define RVAL2STRV_ACCEPT_NIL(ary) rbg_rval2strv_accept_nil(&(ary), NULL) +#define RVAL2STRS_DUP(ary, n) rbg_rval2strv_dup(&(ary), &(n)) +#define RVAL2STRS_DUP_ACCEPT_NIL(ary, n) rbg_rval2strv_dup_accept_nil(&(ary), &(n)) +#define RVAL2STRV_DUP(ary) rbg_rval2strv_dup(&(ary), NULL) +#define RVAL2STRV_DUP_ACCEPT_NIL(ary) rbg_rval2strv_dup_accept_nil(&(ary), NULL) + +#define STRV2RVAL(strings) rbg_strv2rval(strings) +#define STRV2RVAL_FREE(strings) rbg_strv2rval_free(strings) + +#define RVAL2GBOOLEANS(ary, n) rbg_rval2gbooleans(&(ary), &(n)) +#define RVAL2GINTS(ary, n) rbg_rval2gints(&(ary), &(n)) +#define RVAL2GINT8S(ary, n) rbg_rval2gint8s(&(ary), &(n)) +#define RVAL2GUINT8S(ary, n) rbg_rval2guint8s(&(ary), &(n)) +#define RVAL2GUINT16S(ary, n) rbg_rval2guint16s(&(ary), &(n)) +#define RVAL2GUINT32S(ary, n) rbg_rval2guint32s(&(ary), &(n)) +#define RVAL2GDOUBLES(ary, n) rbg_rval2gdoubles(&(ary), &(n)) + +#define GINTS2RVAL(ary, n) rbg_gints2rval(ary, n) +#define GINTS2RVAL_FREE(ary, n) rbg_gints2rval(ary, n) + +#define CBOOL2RVAL(b) ((b) ? Qtrue : Qfalse) +#define RVAL2CBOOL(b) (RTEST(b)) +#define GERROR2RVAL(error) (rbgerr_gerror2exception(error)) +#define RG_RAISE_ERROR(error) rb_exc_raise(GERROR2RVAL(error)) +#define RAISE_GERROR(error) RG_RAISE_ERROR(error) /* deprecated */ +#define G_DEF_ERROR(domain, name, module, parent, gtype) \ + rbgerr_define_gerror(domain, name, module, parent, gtype) +#define G_DEF_ERROR2(domain, name, module, parent) \ + rbgerr_define_gerror(domain, name, module, parent, G_TYPE_INVALID) + +#if defined(G_PLATFORM_WIN32) && !defined(RUBY_GLIB2_STATIC_COMPILATION) +# ifdef RUBY_GLIB2_COMPILATION +# define RUBY_GLIB2_VAR __declspec(dllexport) +# else +# define RUBY_GLIB2_VAR extern __declspec(dllimport) +# endif +#else +# define RUBY_GLIB2_VAR extern +#endif + +RUBY_GLIB2_VAR VALUE mGLib; + +extern const gchar *rbg_rval_inspect(VALUE object); + +extern gchar* rbg_string_value_ptr(volatile VALUE* ptr); /* no longer used */ +extern const gchar *rbg_rval2cstr(VALUE *str); +extern const gchar *rbg_rval2cstr_raw(VALUE *str); +extern const gchar *rbg_rval2cstr_ptr(VALUE *str); +extern const gchar *rbg_rval2cstr_accept_nil(VALUE *str); +extern const gchar *rbg_rval2cstr_raw_accept_nil(VALUE *str); +extern const gchar *rbg_rval2cstr_ptr_accept_nil(VALUE *str); +extern const gchar *rbg_rval2cstr_accept_symbol(volatile VALUE *value); +extern const gchar *rbg_rval2cstr_accept_symbol_accept_nil(volatile VALUE *value); +extern const gchar *rbg_rval2glibid(volatile VALUE *value, volatile VALUE *buf, gboolean accept_nil); + +extern VALUE rbg_cstr2rval(const gchar* str); +extern VALUE rbg_cstr2rval_len(const gchar* str, gsize len); +extern VALUE rbg_cstr2rval_len_free(gchar *str, gsize len); +extern VALUE rbg_cstr2rval_with_encoding(const gchar* str, + const gchar *encoding); +extern VALUE rbg_cstr2rval_len_with_encoding(const gchar* str, gsize len, + const gchar *encoding); +extern VALUE rbg_cstr2rval_free(gchar *str); +/* just for backward compatibility. */ +extern VALUE rbg_cstr2rval_with_free(gchar *str); + +VALUE rbg_filename_to_ruby(const gchar *filename); +extern VALUE rbg_filename_to_ruby_free(gchar *filename); +extern gchar *rbg_filename_from_ruby(VALUE filename); + +const gchar **rbg_rval2strv(volatile VALUE *value, long *n); +const gchar **rbg_rval2strv_accept_nil(volatile VALUE *value, long *n); +gchar **rbg_rval2strv_dup(volatile VALUE *value, long *n); +gchar **rbg_rval2strv_dup_accept_nil(volatile VALUE *value, long *n); +VALUE rbg_strv2rval(const gchar **strings); +VALUE rbg_strv2rval_free(gchar **strings); + +gboolean *rbg_rval2gbooleans(volatile VALUE *value, long *n); +gint *rbg_rval2gints(volatile VALUE *value, long *n); +gint8 *rbg_rval2gint8s(volatile VALUE *value, long *n); +guint8 *rbg_rval2guint8s(volatile VALUE *value, long *n); +guint16 *rbg_rval2guint16s(volatile VALUE *value, long *n); +guint32 *rbg_rval2guint32s(volatile VALUE *value, long *n); +gdouble *rbg_rval2gdoubles(volatile VALUE *value, long *n); + +VALUE rbg_gints2rval(const gint *gints, long n); +VALUE rbg_gints2rval_free(gint *gints, long n); + +extern VALUE rbg_to_array(VALUE object); +extern VALUE rbg_to_hash(VALUE object); +extern VALUE rbg_check_array_type(VALUE object); +extern VALUE rbg_check_hash_type(VALUE object); +extern void rbg_scan_options(VALUE options, ...); + +/* rbgerror.h */ +extern VALUE rbgerr_gerror2exception(GError *error); +extern VALUE rbgerr_define_gerror(GQuark domain, const gchar* name, VALUE module, VALUE parent, GType gtype); + +extern VALUE rbglib_int64_to_num(guint64 val); +extern VALUE rbglib_uint64_to_num(guint64 val); +extern gint64 rbglib_num_to_int64(VALUE val); +extern guint64 rbglib_num_to_uint64(VALUE val); + + +extern VALUE rbg_variant_to_ruby(GVariant *variant); +extern GVariant *rbg_variant_from_ruby(VALUE rb_variant); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __RBGLIB_H__ */ Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib2conversions.h (+68 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbglib2conversions.h 2017-02-15 13:19:47 +0900 (32ee7c9) @@ -0,0 +1,68 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011-2015 Ruby-GNOME2 Project Team + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef __GLIB2CONVERSIONS_H__ +#define __GLIB2CONVERSIONS_H__ + +#define RVAL2GPARAMSPEC(o) (G_PARAM_SPEC(RVAL2GOBJ(o))) + +#define RVAL2GCLOSURE(o) ((GClosure*)RVAL2BOXED(o, G_TYPE_CLOSURE)) +#define GCLOSURE2RVAL(o) (BOXED2RVAL(o, G_TYPE_CLOSURE)) +#define RVAL2GIOCHANNEL(o) ((GIOChannel*)RVAL2BOXED(o, G_TYPE_IO_CHANNEL)) +#define GIOCHANNEL2RVAL(o) (BOXED2RVAL(o, G_TYPE_IO_CHANNEL)) +#define RVAL2GKEYFILE(o) ((GKeyFile*)RVAL2BOXED(o, G_TYPE_KEY_FILE)) +#define GKEYFILE2RVAL(o) (BOXED2RVAL(o, G_TYPE_KEY_FILE)) +#define RVAL2GMAINCONTEXT(o) ((GMainContext*)RVAL2BOXED(o, G_TYPE_MAIN_CONTEXT)) +#define GMAINCONTEXT2RVAL(o) (BOXED2RVAL(o, G_TYPE_MAIN_CONTEXT)) +#define RVAL2GMAINLOOP(o) ((GMainLoop*)RVAL2BOXED(o, G_TYPE_MAIN_LOOP)) +#define GMAINLOOP2RVAL(o) (BOXED2RVAL(o, G_TYPE_MAIN_LOOP)) +#define RVAL2GPOLLFD(o) ((GPollFD*)RVAL2BOXED(o, G_TYPE_POLL_FD)) +#define GPOLLFD2RVAL(o) (BOXED2RVAL(o, G_TYPE_POLL_FD)) +#define RVAL2GSOURCE(o) ((GSource*)RVAL2BOXED(o, G_TYPE_SOURCE)) +#define GSOURCE2RVAL(o) (BOXED2RVAL(o, G_TYPE_SOURCE)) +#define RVAL2GTIMER(o) ((GTimer*)RVAL2BOXED(o, G_TYPE_TIMER)) +#define GTIMER2RVAL(o) (BOXED2RVAL(o, G_TYPE_TIMER)) +#define RVAL2GVALUE(o) ((GValue*)RVAL2BOXED(o, G_TYPE_VALUE)) +#define GVALUE2RVAL(o) (BOXED2RVAL(o, G_TYPE_VALUE)) +#define RVAL2GVARIANTTYPE(o) ((GVariantType *)RVAL2BOXED(o, G_TYPE_VARIANT_TYPE)) +#define GVARIANTTYPE2RVAL(o) (BOXED2RVAL(o, G_TYPE_VARIANT_TYPE)) + +#define RVAL2GIOCONDITION(o) (RVAL2GFLAGS(o, G_TYPE_IO_CONDITION)) +#define GIOCONDITION2RVAL(o) (GFLAGS2RVAL(o, G_TYPE_IO_CONDITION)) +#define RVAL2GNORMALIZEMODE(o) (RVAL2GENUM(o, G_TYPE_NORMALIZE_MODE)) +#define GNORMALIZEMODE2RVAL(o) (GENUM2RVAL(o, G_TYPE_NORMALIZE_MODE)) + +#define RVAL2GCONNECTFLAGS(o) (RVAL2GFLAGS(o, G_TYPE_CONNECT_FLAGS)) +#define GCONNECTFLAGS2RVAL(o) (GFLAGS2RVAL(o, G_TYPE_CONNECT_FLAGS)) +#define RVAL2GKEYFILEFLAGS(o) (RVAL2GFLAGS(o, G_TYPE_KEY_FILE_FLAGS)) +#define GKEYFILEFLAGS2RVAL(o) (GFLAGS2RVAL(o, G_TYPE_KEY_FILE_FLAGS)) + +#define RVAL2GFORMATSIZEFLAGS(o) (RVAL2GFLAGS(o, G_TYPE_FORMAT_SIZE_FLAGS)) +#define GFORMATSIZEFLAGS2RVAL(o) (GFLAGS2RVAL(o, G_TYPE_FORMAT_SIZE_FLAGS)) + +#define RVAL2GBINDINGFLAGS(o) (RVAL2GFLAGS(o, G_TYPE_BINDING_FLAGS)) +#define GBINDINGFLAGS2RVAL(o) (GFLAGS2RVAL(o, G_TYPE_BINDING_FLAGS)) +#define RVAL2GREGEXMATCHOPTIONSFLAGS(o) (RVAL2GFLAGS(o, G_TYPE_REGEX_MATCH_FLAGS)) +#define RVAL2GREGEXCOMPILEOPTIONSFLAGS(o) (RVAL2GFLAGS(o, G_TYPE_REGEX_COMPILE_FLAGS)) +#define GMATCHINFO2RVAL(o) (BOXED2RVAL(o, G_TYPE_MATCH_INFO)) +#define GDATETIME2RVAL(o) (BOXED2RVAL(o, G_TYPE_DATE_TIME)) +#define GTIMEZONE2RVAL(o) (BOXED2RVAL(o, G_TYPE_TIME_ZONE)) +#define RVAL2GTIMEZONE(o) ((GTimeZone*)RVAL2BOXED(o, G_TYPE_TIME_ZONE)) +#endif /* __GLIB2CONVERSIONS_H__ */ Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_bookmarkfile.c (+546 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_bookmarkfile.c 2017-02-15 13:19:47 +0900 (1b3ef57) @@ -0,0 +1,546 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2006 Masao Mutoh + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" + +/************************************************/ +static GBookmarkFile* +bookmarkfile_copy(const GBookmarkFile* file) +{ +/* + GBookmarkFile* new_file; + g_return_val_if_fail (file != NULL, NULL); + new_file = g_key_file_new(); + *new_file = (GBookmarkFile*)*file; + return new_file; +*/ + return (GBookmarkFile*)file; +} + +static GType +g_bookmark_file_get_type(void) +{ + static GType our_type = 0; + if (our_type == 0) + our_type = g_boxed_type_register_static("GBookmarkFile", + (GBoxedCopyFunc)bookmarkfile_copy, + (GBoxedFreeFunc)g_bookmark_file_free); + return our_type; +} +/************************************************/ + +#define G_TYPE_BOOKMARK_FILE (g_bookmark_file_get_type()) + +#define RG_TARGET_NAMESPACE cBookmarkFile +#define _SELF(self) ((GBookmarkFile*)(RVAL2BOXED(self, G_TYPE_BOOKMARK_FILE))) + +static VALUE +rg_initialize(VALUE self) +{ + G_INITIALIZE(self, g_bookmark_file_new()); + return Qnil; +} + +static VALUE +rg_load_from_file(VALUE self, VALUE rbfilename) +{ + gchar *filename = RVAL2CSTRFILENAME(rbfilename); + GError* error = NULL; + gboolean ret = g_bookmark_file_load_from_file(_SELF(self), filename, &error); + g_free(filename); + if (!ret) + RAISE_GERROR(error); + + return self; +} + +static VALUE +rg_load_from_data(VALUE self, VALUE data) +{ + GError *error = NULL; + + StringValue(data); + if (!g_bookmark_file_load_from_data(_SELF(self), + RSTRING_PTR(data), + RSTRING_LEN(data), + &error)) + RAISE_GERROR(error); + + return Qnil; +} + +static VALUE +rg_load_from_data_dirs(VALUE self, VALUE file) +{ + GError* error = NULL; + gboolean ret; + gchar* full_path; + + ret = g_bookmark_file_load_from_data_dirs(_SELF(self), + RVAL2CSTR(file), + &full_path, &error); + + if (! ret) RAISE_GERROR(error); + + return full_path ? CSTR2RVAL(full_path) : Qnil; +} + +static VALUE +rg_to_data(VALUE self) +{ + GError* error = NULL; + gchar* data = g_bookmark_file_to_data(_SELF(self), NULL, &error); + + if (error) RAISE_GERROR(error); + + return CSTR2RVAL_FREE(data); +} + +static VALUE +rg_to_file(VALUE self, VALUE rbfilename) +{ + gchar *filename = RVAL2CSTRFILENAME(rbfilename); + GError* error = NULL; + gboolean ret = g_bookmark_file_to_file(_SELF(self), filename, &error); + g_free(filename); + if (!ret) + RAISE_GERROR(error); + + return self; +} + +static VALUE +rg_has_item_p(VALUE self, VALUE uri) +{ + return CBOOL2RVAL(g_bookmark_file_has_item(_SELF(self), + RVAL2CSTR(uri))); +} + +static VALUE +rg_has_group_p(VALUE self, VALUE uri, VALUE group) +{ + GError* error = NULL; + return CBOOL2RVAL(g_bookmark_file_has_group(_SELF(self), + RVAL2CSTR(uri), + RVAL2CSTR(group), + &error)); +} + +static VALUE +rg_has_application_p(VALUE self, VALUE uri, VALUE name) +{ + GError* error = NULL; + return CBOOL2RVAL(g_bookmark_file_has_application(_SELF(self), + RVAL2CSTR(uri), + RVAL2CSTR(name), + &error)); +} + +static VALUE +rg_size(VALUE self) +{ + return INT2NUM(g_bookmark_file_get_size(_SELF(self))); +} + +static VALUE +rg_uris(VALUE self) +{ + return STRV2RVAL_FREE(g_bookmark_file_get_uris(_SELF(self), NULL)); +} + +static VALUE +rg_get_title(VALUE self, VALUE uri) +{ + GError *error = NULL; + gchar* ret = g_bookmark_file_get_title(_SELF(self), + RVAL2CSTR(uri), + &error); + if (error) RAISE_GERROR(error); + return CSTR2RVAL_FREE(ret); +} + +static VALUE +rg_get_description(VALUE self, VALUE uri) +{ + GError *error = NULL; + gchar* ret = g_bookmark_file_get_description(_SELF(self), + RVAL2CSTR(uri), + &error); + if (error) RAISE_GERROR(error); + return CSTR2RVAL_FREE(ret); +} + +static VALUE +rg_get_mime_type(VALUE self, VALUE uri) +{ + GError *error = NULL; + gchar* ret = g_bookmark_file_get_mime_type(_SELF(self), + RVAL2CSTR(uri), + &error); + if (error) RAISE_GERROR(error); + return CSTR2RVAL_FREE(ret); +} + +static VALUE +rg_private_p(VALUE self, VALUE uri) +{ + GError *error = NULL; + gboolean ret = g_bookmark_file_get_is_private(_SELF(self), + RVAL2CSTR(uri), + &error); + if (error) RAISE_GERROR(error); + return CBOOL2RVAL(ret); +} + +static VALUE +rg_get_icon(VALUE self, VALUE uri) +{ + gchar* href; + gchar* mime_type; + GError *error = NULL; + gboolean ret = g_bookmark_file_get_icon(_SELF(self), + RVAL2CSTR(uri), + &href, &mime_type, + &error); + if (!ret){ + if (error) RAISE_GERROR(error); + return Qnil; + } + return rb_assoc_new(CSTR2RVAL_FREE(href), CSTR2RVAL_FREE(mime_type)); +} + +static VALUE +rg_get_added(VALUE self, VALUE uri) +{ + GError *error = NULL; + time_t ret = g_bookmark_file_get_added(_SELF(self), + RVAL2CSTR(uri), + &error); + if (!ret) RAISE_GERROR(error); + + return rb_time_new(ret, 0); +} + +static VALUE +rg_get_modified(VALUE self, VALUE uri) +{ + GError *error = NULL; + time_t ret = g_bookmark_file_get_modified(_SELF(self), + RVAL2CSTR(uri), + &error); + if (!ret) RAISE_GERROR(error); + + return rb_time_new(ret, 0); +} + +static VALUE +rg_get_visited(VALUE self, VALUE uri) +{ + GError *error = NULL; + time_t ret = g_bookmark_file_get_visited(_SELF(self), + RVAL2CSTR(uri), + &error); + if (!ret) RAISE_GERROR(error); + + return rb_time_new(ret, 0); +} + +static VALUE +rg_get_groups(VALUE self, VALUE uri) +{ + gsize length; + VALUE ary; + gsize i; + GError* error = NULL; + gchar** ret = g_bookmark_file_get_groups(_SELF(self), + RVAL2CSTR(uri), + &length, &error); + if (error) RAISE_GERROR(error); + + ary = rb_ary_new(); + for(i = 0; i < length; i++){ + rb_ary_push(ary, CSTR2RVAL(ret[i])); + } + + g_strfreev(ret); + return ary; +} + +static VALUE +rg_get_applications(VALUE self, VALUE uri) +{ + gsize length; + VALUE ary; + gsize i; + GError* error = NULL; + gchar** ret = g_bookmark_file_get_applications(_SELF(self), + RVAL2CSTR(uri), + &length, &error); + if (error) RAISE_GERROR(error); + + ary = rb_ary_new(); + for(i = 0; i < length; i++){ + rb_ary_push(ary, CSTR2RVAL(ret[i])); + } + + g_strfreev(ret); + return ary; +} + +static VALUE +rg_get_app_info(VALUE self, VALUE uri, VALUE name) +{ + gchar* exec; + guint count; + time_t stamp; + GError* error = NULL; + + gboolean ret = g_bookmark_file_get_app_info(_SELF(self), + RVAL2CSTR(uri), + RVAL2CSTR(name), + &exec, &count, &stamp, &error); + if (!ret) RAISE_GERROR(error); + + return rb_ary_new3(3, CSTR2RVAL(exec), UINT2NUM(count), rb_time_new(stamp, 0)); +} + +static VALUE +rg_set_title(VALUE self, VALUE uri, VALUE title) +{ + g_bookmark_file_set_title(_SELF(self), + RVAL2CSTR(uri), + RVAL2CSTR(title)); + return self; +} + +static VALUE +rg_set_description(VALUE self, VALUE uri, VALUE description) +{ + g_bookmark_file_set_description(_SELF(self), + RVAL2CSTR(uri), + RVAL2CSTR(description)); + return self; +} + +static VALUE +rg_set_mime_type(VALUE self, VALUE uri, VALUE mime_type) +{ + g_bookmark_file_set_mime_type(_SELF(self), + RVAL2CSTR(uri), + RVAL2CSTR(mime_type)); + return self; +} + +static VALUE +rg_set_private(VALUE self, VALUE uri, VALUE is_private) +{ + g_bookmark_file_set_is_private(_SELF(self), + RVAL2CSTR(uri), + RVAL2CBOOL(is_private)); + return self; +} + +static VALUE +rg_set_icon(VALUE self, VALUE uri, VALUE href, VALUE mime_type) +{ + g_bookmark_file_set_icon(_SELF(self), + RVAL2CSTR(uri), + RVAL2CSTR(href), + RVAL2CSTR(mime_type)); + return self; +} + +static VALUE +rg_set_added(VALUE self, VALUE uri, VALUE time) +{ + g_bookmark_file_set_added(_SELF(self), + RVAL2CSTR(uri), + (time_t)NUM2LONG(rb_Integer(time))); + return self; +} + +static VALUE +rg_set_groups(VALUE self, VALUE rburi, VALUE rbgroups) +{ + GBookmarkFile *bookmark = _SELF(self); + const gchar *uri = RVAL2CSTR(rburi); + long n; + const gchar **groups = RVAL2STRS(rbgroups, n); + + g_bookmark_file_set_groups(bookmark, uri, groups, n); + + g_free(groups); + + return self; +} + +static VALUE +rg_set_modified(VALUE self, VALUE uri, VALUE time) +{ + g_bookmark_file_set_modified(_SELF(self), + RVAL2CSTR(uri), + (time_t)NUM2LONG(rb_Integer(time))); + return self; +} + +static VALUE +rg_set_visited(VALUE self, VALUE uri, VALUE time) +{ + g_bookmark_file_set_visited(_SELF(self), + RVAL2CSTR(uri), + (time_t)NUM2LONG(rb_Integer(time))); + return self; +} + +static VALUE +rg_set_app_info(VALUE self, VALUE uri, VALUE name, VALUE exec, VALUE count, VALUE stamp) +{ + GError* error = NULL; + gboolean ret = g_bookmark_file_set_app_info(_SELF(self), + RVAL2CSTR(uri), + RVAL2CSTR(name), + RVAL2CSTR(exec), + NUM2INT(count), + (time_t)NUM2LONG(rb_Integer(stamp)), + &error); + + if (! ret) RAISE_GERROR(error); + + return self; +} + +static VALUE +rg_add_group(VALUE self, VALUE uri, VALUE group) +{ + g_bookmark_file_add_group(_SELF(self), + RVAL2CSTR(uri), + RVAL2CSTR(group)); + return self; +} + +static VALUE +rg_add_application(VALUE self, VALUE uri, VALUE name, VALUE exec) +{ + g_bookmark_file_add_application(_SELF(self), + RVAL2CSTR(uri), + RVAL2CSTR(name), + RVAL2CSTR(exec)); + return self; +} + +static VALUE +rg_remove_group(VALUE self, VALUE uri, VALUE group) +{ + GError* error = NULL; + gboolean ret = g_bookmark_file_remove_group(_SELF(self), + RVAL2CSTR(uri), + RVAL2CSTR(group), + &error); + if (! ret) RAISE_GERROR(error); + + return self; +} + +static VALUE +rg_remove_application(VALUE self, VALUE uri, VALUE name) +{ + GError *error = NULL; + gboolean ret = g_bookmark_file_remove_application(_SELF(self), + RVAL2CSTR(uri), + RVAL2CSTR(name), + &error); + if (! ret) RAISE_GERROR(error); + + return self; +} + +static VALUE +rg_remove_item(VALUE self, VALUE uri) +{ + GError *error = NULL; + gboolean ret = g_bookmark_file_remove_item(_SELF(self), + RVAL2CSTR(uri), + &error); + if (! ret) RAISE_GERROR(error); + + return self; +} + +static VALUE +rg_move_item(VALUE self, VALUE old_uri, VALUE new_uri) +{ + GError *error = NULL; + gboolean ret = g_bookmark_file_move_item(_SELF(self), + RVAL2CSTR(old_uri), + RVAL2CSTR(new_uri), + &error); + if (! ret) RAISE_GERROR(error); + + return self; +} + +void +Init_glib_bookmark_file(void) +{ + VALUE RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_BOOKMARK_FILE, "BookmarkFile", mGLib); + + G_DEF_ERROR(G_BOOKMARK_FILE_ERROR, "BookmarkFileError", mGLib, + rb_eRuntimeError, G_TYPE_BOOKMARK_FILE_ERROR); + + RG_DEF_METHOD(initialize, 0); + RG_DEF_METHOD(load_from_file, 1); + RG_DEF_METHOD(load_from_data, 1); + RG_DEF_METHOD(load_from_data_dirs, 1); + RG_DEF_METHOD(to_data, 0); + RG_DEF_METHOD(to_file, 1); + RG_DEF_METHOD_P(has_item, 1); + RG_DEF_METHOD_P(has_group, 2); + RG_DEF_METHOD_P(has_application, 2); + RG_DEF_METHOD(size, 0); + RG_DEF_METHOD(uris, 0); + RG_DEF_METHOD(get_title, 1); + RG_DEF_METHOD(get_description, 1); + RG_DEF_METHOD(get_mime_type, 1); + RG_DEF_METHOD_P(private, 1); + RG_DEF_METHOD(get_icon, 1); + RG_DEF_METHOD(get_added, 1); + RG_DEF_METHOD(get_modified, 1); + RG_DEF_METHOD(get_visited, 1); + RG_DEF_METHOD(get_groups, 1); + RG_DEF_METHOD(get_applications, 1); + RG_DEF_METHOD(get_app_info, 2); + RG_DEF_METHOD(set_title, 2); + RG_DEF_METHOD(set_description, 2); + RG_DEF_METHOD(set_mime_type, 2); + RG_DEF_METHOD(set_private, 2); + RG_DEF_METHOD(set_icon, 3); + RG_DEF_METHOD(set_added, 2); + RG_DEF_METHOD(set_groups, 2); + RG_DEF_METHOD(set_modified, 2); + RG_DEF_METHOD(set_visited, 2); + RG_DEF_METHOD(set_app_info, 5); + RG_DEF_METHOD(add_group, 2); + RG_DEF_METHOD(add_application, 3); + RG_DEF_METHOD(remove_group, 2); + RG_DEF_METHOD(remove_application, 2); + RG_DEF_METHOD(remove_item, 1); + RG_DEF_METHOD(move_item, 2); +} \ No newline at end of file Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_convert.c (+191 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_convert.c 2017-02-15 13:19:47 +0900 (cb99e48) @@ -0,0 +1,191 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011-2016 Ruby-GNOME2 Project Team + * Copyright (C) 2009 Ruby-GNOME2 Project Team + * Copyright (C) 2002,2003 KUBO Takehiro + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" +#include "rbglib.h" + +#define RG_TARGET_NAMESPACE mGLib + +static VALUE +rg_s_convert(G_GNUC_UNUSED VALUE self, VALUE str, VALUE to, VALUE from) +{ + GError *err = NULL; + gchar* ret; + gsize written; + VALUE s = Qnil; + + StringValue(str); + ret = g_convert(RSTRING_PTR(str), RSTRING_LEN(str), + StringValuePtr(to), StringValuePtr(from), + NULL, &written, &err); + + if (err != NULL) + RAISE_GERROR(err); + s = rb_str_new(ret, written); + g_free(ret); + return s; +} + +static VALUE +rg_s_locale_to_utf8(G_GNUC_UNUSED VALUE self, VALUE str) +{ + GError *err = NULL; + gchar* ret; + gsize written; + + StringValue(str); + ret = g_locale_to_utf8(RSTRING_PTR(str), RSTRING_LEN(str), + NULL, &written, &err); + + if (err != NULL) + RAISE_GERROR(err); + return CSTR2RVAL_LEN_FREE(ret, written); +} + +static VALUE +rg_s_locale_from_utf8(G_GNUC_UNUSED VALUE self, VALUE str) +{ + GError *err = NULL; + VALUE s = Qnil; + gchar* ret; + gsize written; + + StringValue(str); + ret = g_locale_from_utf8(RSTRING_PTR(str), RSTRING_LEN(str), + NULL, &written, &err); + + if (err != NULL) + RAISE_GERROR(err); + s = rb_str_new(ret, written); + g_free(ret); + return s; +} + +static VALUE +rg_s_filename_to_utf8(G_GNUC_UNUSED VALUE self, VALUE str) +{ + GError *err = NULL; + gchar* ret; + gsize written; + + StringValue(str); + ret = g_filename_to_utf8(RSTRING_PTR(str), RSTRING_LEN(str), + NULL, &written, &err); + + if (err != NULL) + RAISE_GERROR(err); + return CSTR2RVAL_LEN_FREE(ret, written); +} + +static VALUE +rg_s_filename_from_utf8(G_GNUC_UNUSED VALUE self, VALUE str) +{ + GError *err = NULL; + VALUE s = Qnil; + gchar* ret; + gsize written; + + StringValue(str); + ret = g_filename_from_utf8(RSTRING_PTR(str), RSTRING_LEN(str), + NULL, &written, &err); + + if (err != NULL) + RAISE_GERROR(err); + s = rb_str_new(ret, written); + g_free(ret); + return s; +} + +static VALUE +rg_s_filename_to_uri(int argc, VALUE *argv, G_GNUC_UNUSED VALUE self) +{ + VALUE filename, hostname, s; + GError *err = NULL; + gchar* ret; + + rb_scan_args(argc, argv, "11", &filename, &hostname); + + ret = g_filename_to_uri(StringValuePtr(filename), + NIL_P(hostname) ? NULL : StringValuePtr(hostname), + &err); + + if (err) + RAISE_GERROR(err); + s = rb_str_new2(ret); + g_free(ret); + return s; +} + +static VALUE +rg_s_filename_from_uri(G_GNUC_UNUSED VALUE self, VALUE str) +{ + GError *err = NULL; + VALUE s; + gchar* filename; + char* hostname; + + filename = g_filename_from_uri(StringValuePtr(str), &hostname, &err); + + if (err) + RAISE_GERROR(err); + s = rb_ary_new3(2, rb_str_new2(filename), + hostname ? rb_str_new2(hostname) : Qnil); + g_free(filename); + g_free(hostname); + return s; +} + +static VALUE +rg_s_utf8_validate(G_GNUC_UNUSED VALUE self, VALUE str) +{ + rb_warning("GLib.utf8_validate is deprecated. Use GLib::UTF8.validate instead."); + StringValue(str); + return CBOOL2RVAL(g_utf8_validate(RSTRING_PTR(str), RSTRING_LEN(str), NULL)); +} + +void +Init_glib_convert(void) +{ + VALUE cCharError = G_DEF_ERROR2(G_CONVERT_ERROR, "ConvertError", RG_TARGET_NAMESPACE, rb_eIOError); + + rb_define_const(cCharError, "NO_CONVERSION", INT2NUM(G_CONVERT_ERROR_NO_CONVERSION)); + rb_define_const(cCharError, "ILLEGAL_SEQUENCE", INT2NUM(G_CONVERT_ERROR_ILLEGAL_SEQUENCE)); + rb_define_const(cCharError, "FAILED", INT2NUM(G_CONVERT_ERROR_FAILED)); + rb_define_const(cCharError, "PARTIAL_INPUT", INT2NUM(G_CONVERT_ERROR_PARTIAL_INPUT)); + rb_define_const(cCharError, "BAD_URI", INT2NUM(G_CONVERT_ERROR_BAD_URI)); + rb_define_const(cCharError, "NOT_ABSOLUTE_PATH", INT2NUM(G_CONVERT_ERROR_NOT_ABSOLUTE_PATH)); + + /* glib/gunicode.h */ + /* just for backward compatibility. + Use GLib::UTF8.validate instead. */ + RG_DEF_SMETHOD(utf8_validate, 1); + + /* glib/gconvert.h */ + RG_DEF_SMETHOD(convert, 3); + RG_DEF_SMETHOD(locale_to_utf8, 1); + RG_DEF_SMETHOD(locale_from_utf8, 1); + RG_DEF_SMETHOD(filename_to_utf8, 1); + RG_DEF_SMETHOD(filename_from_utf8, 1); + + RG_DEF_SMETHOD(filename_to_uri, -1); + RG_DEF_SMETHOD(filename_from_uri, 1); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_datetime.c (+250 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_datetime.c 2017-02-15 13:19:47 +0900 (2553498) @@ -0,0 +1,250 @@ +/* + * Copyright (C) 2016 Ruby-GNOME2 Project Team + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" + +#define RG_TARGET_NAMESPACE cDateTime +#define _SELF(s) ((GDateTime*)RVAL2BOXED(s, G_TYPE_DATE_TIME)) + +static gboolean +is_local_timezone(VALUE rb_timezone) +{ + ID id_equal; + ID id_local; + + if (NIL_P(rb_timezone)) { + return TRUE; + } + + CONST_ID(id_equal, "=="); + CONST_ID(id_local, "local"); + return RVAL2CBOOL(rb_funcall(rb_timezone, id_equal, 1, ID2SYM(id_local))); +} + +static gboolean +is_utc_timezone(VALUE rb_timezone) +{ + ID id_equal; + ID id_utc; + + CONST_ID(id_equal, "=="); + CONST_ID(id_utc, "utc"); + return RVAL2CBOOL(rb_funcall(rb_timezone, id_equal, 1, ID2SYM(id_utc))); +} + +static gboolean +is_timezone(VALUE rb_timezone) +{ + VALUE rb_cTimeZone; + + rb_cTimeZone = rb_const_get(mGLib, rb_intern("TimeZone")); + return RVAL2CBOOL(rb_obj_is_kind_of(rb_timezone, rb_cTimeZone)); +} + +static VALUE +rg_s_now(int argc, VALUE *argv, G_GNUC_UNUSED VALUE self) +{ + GDateTime *date = NULL; + VALUE rb_timezone; + + rb_scan_args(argc, argv, "01", &rb_timezone); + + if (is_local_timezone(rb_timezone)) { + date = g_date_time_new_now_local(); + } else if (is_utc_timezone(rb_timezone)) { + date = g_date_time_new_now_utc(); + } else if (is_timezone(rb_timezone)) { + date = g_date_time_new_now(RVAL2GTIMEZONE(rb_timezone)); + } else { + rb_raise(rb_eArgError, + "timezone must be nil, :local, :utc or GLib::TimeZone: " + "%+" PRIsVALUE, + rb_timezone); + } + + return GDATETIME2RVAL(date); +} + +static VALUE +rg_initialize(int argc, VALUE *argv, VALUE self) +{ + /* + * Not implemented: + * GDateTime * g_date_time_new_from_timeval_local () + * GDateTime * g_date_time_new_from_timeval_utc () + * https://developer.gnome.org/glib/stable/glib-Date-and-Time-Functions.html#GTimeVal + * */ + VALUE rb_options; + VALUE rb_unix; + VALUE rb_timezone; + VALUE rb_year; + VALUE rb_month; + VALUE rb_day; + VALUE rb_hour; + VALUE rb_minute; + VALUE rb_second; + GDateTime *datetime = NULL; + + rb_scan_args(argc, argv, "1", &rb_options); + rbg_scan_options(rb_options, + "unix", &rb_unix, + "timezone", &rb_timezone, + "year", &rb_year, + "month", &rb_month, + "day", &rb_day, + "hour", &rb_hour, + "minute", &rb_minute, + "second", &rb_second, + NULL); + + if (!NIL_P(rb_unix)) { + gint64 unix_time; + + unix_time = rbglib_num_to_int64(rb_unix); + if (is_local_timezone(rb_timezone)) { + datetime = g_date_time_new_from_unix_local(unix_time); + } else if (is_utc_timezone(rb_timezone)) { + datetime = g_date_time_new_from_unix_utc(unix_time); + } else { + rb_raise(rb_eArgError, + ":timezone must be nil, :local or :utc: %+" PRIsVALUE, + rb_timezone); + } + } else if (!NIL_P(rb_year) && + !NIL_P(rb_month) && + !NIL_P(rb_hour) && + !NIL_P(rb_minute) && + !NIL_P(rb_second)) { + gint year = 0; + gint month = 0; + gint day = 0; + gint hour = 0; + gint minute = 0; + gdouble second = 0.0; + + year = NUM2INT(rb_year); + month = NUM2INT(rb_month); + day = NUM2INT(rb_day); + hour = NUM2INT(rb_hour); + minute = NUM2INT(rb_minute); + second = NUM2DBL(rb_second); + if (is_local_timezone(rb_timezone)) { + datetime = g_date_time_new_local(year, + month, + day, + hour, + minute, + second); + } else if (is_utc_timezone(rb_timezone)) { + datetime = g_date_time_new_utc(year, + month, + day, + hour, + minute, + second); + } else if (is_timezone(rb_timezone)) { + GTimeZone *timezone = NULL; + + timezone = RVAL2GTIMEZONE(rb_timezone); + datetime = g_date_time_new(timezone, + year, + month, + day, + hour, + minute, + second); + } else { + rb_raise(rb_eArgError, + ":timezone must be nil, :local, :utc or GLib::TimeZone: " + "%+" PRIsVALUE, + rb_timezone); + } + } else { + rb_raise(rb_eArgError, + ":unix or (:year, :month, :day, :hour, :minute and :second) " + "must be specified: %+" PRIsVALUE, + rb_options); + } + + G_INITIALIZE(self, datetime); + + return Qnil; +} + +static VALUE +rg_year(VALUE self) +{ + return INT2NUM(g_date_time_get_year(_SELF(self))); +} + +static VALUE +rg_month(VALUE self) +{ + return INT2NUM(g_date_time_get_month(_SELF(self))); +} + +static VALUE +rg_day_of_month(VALUE self) +{ + return INT2NUM(g_date_time_get_day_of_month(_SELF(self))); +} + +static VALUE +rg_hour(VALUE self) +{ + return INT2NUM(g_date_time_get_hour(_SELF(self))); +} + +static VALUE +rg_minute(VALUE self) +{ + return INT2NUM(g_date_time_get_minute(_SELF(self))); +} + +static VALUE +rg_second(VALUE self) +{ + return DBL2NUM(g_date_time_get_second(_SELF(self))); +} + +static VALUE +rg_format(VALUE self, VALUE rb_format) +{ + const gchar *format = RVAL2CSTR(rb_format); + return CSTR2RVAL(g_date_time_format(_SELF(self), format)); +} + +void +Init_glib_date_time(void) +{ + VALUE RG_TARGET_NAMESPACE; + + RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_DATE_TIME, "DateTime", mGLib); + + RG_DEF_SMETHOD(now, -1); + + RG_DEF_METHOD(initialize, -1); + RG_DEF_METHOD(year, 0); + RG_DEF_METHOD(month, 0); + RG_DEF_METHOD(day_of_month, 0); + RG_DEF_METHOD(hour, 0); + RG_DEF_METHOD(minute, 0); + RG_DEF_METHOD(second, 0); + RG_DEF_METHOD(format, 1); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_error.c (+164 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_error.c 2017-02-15 13:19:47 +0900 (930be3c) @@ -0,0 +1,164 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2004 Masao Mutoh + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" +#include <ctype.h> + +static ID id_code; +static ID id_domain; +static ID id_code_classes; +static VALUE gerror_table; +static VALUE generic_error; +static VALUE error_info; + +VALUE +rbgerr_gerror2exception(GError *error) +{ + VALUE exc = Qnil; + VALUE exception_klass = Qnil; + + if (!error) { + return rb_exc_new2(rb_eRuntimeError, "GError parameter doesn't have a value."); + } + + exception_klass = rb_hash_aref(gerror_table, UINT2NUM(error->domain)); + if (NIL_P(exception_klass)) { + exception_klass = generic_error; + } else { + VALUE code_class = Qnil; + VALUE code_classes; + code_classes = rb_ivar_get(exception_klass, id_code_classes); + if (!NIL_P(code_classes)) { + code_class = rb_hash_aref(code_classes, INT2NUM(error->code)); + } + if (!NIL_P(code_class)) { + exception_klass = code_class; + } + } + exc = rb_exc_new_str(exception_klass, CSTR2RVAL(error->message)); + rb_ivar_set(exc, id_domain, CSTR2RVAL(g_quark_to_string(error->domain))); + rb_ivar_set(exc, id_code, INT2NUM(error->code)); + g_error_free(error); + return exc; +} + +static gchar * +nick_to_constant_name(const gchar *nick) +{ + GString *constant_name; + const gchar *current; + + constant_name = g_string_new(NULL); + + for (current = nick; *current; current++) { + if (*current == '-') { + g_string_append_c(constant_name, '_'); + } else { + g_string_append_c(constant_name, g_ascii_toupper(*current)); + } + } + + return g_string_free(constant_name, FALSE); +} + +static gchar * +nick_to_class_name(const gchar *nick) +{ + GString *class_name; + const gchar *current; + gboolean to_upper = TRUE; + + class_name = g_string_new(NULL); + + for (current = nick; *current; current++) { + if (to_upper) { + g_string_append_c(class_name, g_ascii_toupper(*current)); + to_upper = FALSE; + } else if (*current == '-') { + to_upper = TRUE; + } else { + g_string_append_c(class_name, *current); + } + } + + return g_string_free(class_name, FALSE); +} + +VALUE +rbgerr_define_gerror(GQuark domain, const gchar *name, VALUE module, VALUE parent, GType gtype) +{ + VALUE error_class; + VALUE code_classes; + + error_class = rb_define_class_under(module, name, parent); + rb_include_module(error_class, error_info); + + rb_hash_aset(gerror_table, UINT2NUM(domain), error_class); + + code_classes = rb_hash_new(); + rb_ivar_set(error_class, id_code_classes, code_classes); + + if (gtype != G_TYPE_INVALID) { + GEnumClass* gclass = g_type_class_ref(gtype); + guint i; + + for (i = 0; i < gclass->n_values; i++) { + VALUE code_class; + GEnumValue* entry = &(gclass->values[i]); + gchar *code_constant_name; + gchar *code_class_name; + + code_constant_name = nick_to_constant_name(entry->value_nick); + rbgobj_define_const(error_class, + code_constant_name, + INT2NUM(entry->value)); + g_free(code_constant_name); + + code_class_name = nick_to_class_name(entry->value_nick); + code_class = rb_define_class_under(error_class, + code_class_name, + error_class); + g_free(code_class_name); + rb_hash_aset(code_classes, INT2NUM(entry->value), code_class); + } + + g_type_class_unref(gclass); + } + + return error_class; +} + +void +Init_glib_error(void) +{ + id_code = rb_intern("@code"); + id_domain = rb_intern("@domain"); + id_code_classes = rb_intern("@code_classes"); + gerror_table = rb_hash_new(); + rb_global_variable(&gerror_table); + + error_info = rb_define_module_under(mGLib, "ErrorInfo"); + rb_define_attr(error_info, "code", TRUE, FALSE); + rb_define_attr(error_info, "domain", TRUE, FALSE); + + generic_error = rb_define_class_under(mGLib, "Error", rb_eRuntimeError); + rb_include_module(generic_error, error_info); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_fileutils.c (+119 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_fileutils.c 2017-02-15 13:19:47 +0900 (41e1a81) @@ -0,0 +1,119 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2004 Masao Mutoh + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" +#include "rbglib.h" + +#define RG_TARGET_NAMESPACE cFileError + +/* Use Ruby standard libraries. +enum GFileTest; +GFileError g_file_error_from_errno (gint err_no); +gboolean g_file_get_contents (const gchar *filename, + gchar **contents, + gsize *length, + GError **error); +gboolean g_file_test (const gchar *filename, + GFileTest test); +gint g_mkstemp (gchar *tmpl); +gint g_file_open_tmp (const gchar *tmpl, + gchar **name_used, + GError **error); +gchar* g_file_read_link (const gchar *filename, + GError **error); + +struct GDir; +GDir* g_dir_open (const gchar *path, + guint flags, + GError **error); +G_CONST_RETURN gchar* g_dir_read_name (GDir *dir); +void g_dir_rewind (GDir *dir); +void g_dir_close (GDir *dir); +*/ + +#if GLIB_CHECK_VERSION(2, 16, 0) +static VALUE +rbglib_m_format_size_for_display(G_GNUC_UNUSED VALUE self, VALUE size) +{ + return CSTR2RVAL_FREE(g_format_size_for_display(NUM2OFFT(size))); +} +#endif + +#if GLIB_CHECK_VERSION(2, 30, 0) +static VALUE +rbglib_m_format_size(int argc, VALUE *argv, G_GNUC_UNUSED VALUE self) +{ + VALUE rb_size, rb_options; + + rb_scan_args(argc, argv, "11", &rb_size, &rb_options); + if (NIL_P(rb_options)) { + return CSTR2RVAL_FREE(g_format_size(NUM2ULL(rb_size))); + } else { + VALUE rb_flags; + rbg_scan_options(rb_options, + "flags", &rb_flags, + NULL); + + return CSTR2RVAL_FREE(g_format_size_full(NUM2ULL(rb_size), + RVAL2GFORMATSIZEFLAGS(rb_flags))); + } +} +#endif + +void +Init_glib_fileutils(void) +{ + VALUE RG_TARGET_NAMESPACE = G_DEF_ERROR2(G_FILE_ERROR, "FileError", mGLib, rb_eIOError); + + rb_define_const(RG_TARGET_NAMESPACE, "EXIST", INT2NUM(G_FILE_ERROR_EXIST)); + rb_define_const(RG_TARGET_NAMESPACE, "ISDIR", INT2NUM(G_FILE_ERROR_ISDIR)); + rb_define_const(RG_TARGET_NAMESPACE, "ACCES", INT2NUM(G_FILE_ERROR_ACCES)); + rb_define_const(RG_TARGET_NAMESPACE, "NAMETOOLONG", INT2NUM(G_FILE_ERROR_NAMETOOLONG)); + rb_define_const(RG_TARGET_NAMESPACE, "NOENT", INT2NUM(G_FILE_ERROR_NOENT)); + rb_define_const(RG_TARGET_NAMESPACE, "NOTDIR", INT2NUM(G_FILE_ERROR_NOTDIR)); + rb_define_const(RG_TARGET_NAMESPACE, "NXIO", INT2NUM(G_FILE_ERROR_NXIO)); + rb_define_const(RG_TARGET_NAMESPACE, "NODEV", INT2NUM(G_FILE_ERROR_NODEV)); + rb_define_const(RG_TARGET_NAMESPACE, "ROFS", INT2NUM(G_FILE_ERROR_ROFS)); + rb_define_const(RG_TARGET_NAMESPACE, "TXTBSY", INT2NUM(G_FILE_ERROR_TXTBSY)); + rb_define_const(RG_TARGET_NAMESPACE, "FAULT", INT2NUM(G_FILE_ERROR_FAULT)); + rb_define_const(RG_TARGET_NAMESPACE, "LOOP", INT2NUM(G_FILE_ERROR_LOOP)); + rb_define_const(RG_TARGET_NAMESPACE, "NOSPC", INT2NUM(G_FILE_ERROR_NOSPC)); + rb_define_const(RG_TARGET_NAMESPACE, "NOMEM", INT2NUM(G_FILE_ERROR_NOMEM)); + rb_define_const(RG_TARGET_NAMESPACE, "MFILE", INT2NUM(G_FILE_ERROR_MFILE)); + rb_define_const(RG_TARGET_NAMESPACE, "NFILE", INT2NUM(G_FILE_ERROR_NFILE)); + rb_define_const(RG_TARGET_NAMESPACE, "BADF", INT2NUM(G_FILE_ERROR_BADF)); + rb_define_const(RG_TARGET_NAMESPACE, "INVAL", INT2NUM(G_FILE_ERROR_INVAL)); + rb_define_const(RG_TARGET_NAMESPACE, "PIPE", INT2NUM(G_FILE_ERROR_PIPE)); + rb_define_const(RG_TARGET_NAMESPACE, "AGAIN", INT2NUM(G_FILE_ERROR_AGAIN)); + rb_define_const(RG_TARGET_NAMESPACE, "INTR", INT2NUM(G_FILE_ERROR_INTR)); + rb_define_const(RG_TARGET_NAMESPACE, "IO", INT2NUM(G_FILE_ERROR_IO)); + rb_define_const(RG_TARGET_NAMESPACE, "PERM", INT2NUM(G_FILE_ERROR_PERM)); + rb_define_const(RG_TARGET_NAMESPACE, "FAILED", INT2NUM(G_FILE_ERROR_FAILED)); + +#if GLIB_CHECK_VERSION(2, 16, 0) + rbg_define_singleton_method(mGLib, "format_size_for_display", + rbglib_m_format_size_for_display, 1); +#endif +#if GLIB_CHECK_VERSION(2, 30, 0) + rbg_define_singleton_method(mGLib, "format_size", + rbglib_m_format_size, -1); +#endif +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_gettext.c (+48 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_gettext.c 2017-02-15 13:19:47 +0900 (a18ba6d) @@ -0,0 +1,48 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2013 Ruby-GNOME2 Project Team + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" +#include "rbglib.h" + +#include <libintl.h> + +#define RG_TARGET_NAMESPACE mGetText + +static VALUE +rg_s_bindtextdomain(int argc, VALUE *argv, G_GNUC_UNUSED VALUE self) +{ + VALUE domain_name; + VALUE directory; + const char *current_directory = NULL; + + rb_scan_args(argc, argv, "11", &domain_name, &directory); + current_directory = bindtextdomain(RVAL2CSTR(domain_name), + RVAL2CSTR_ACCEPT_NIL(directory)); + return CSTR2RVAL(current_directory); +} + +void +Init_glib_gettext(void) +{ + VALUE RG_TARGET_NAMESPACE; + + RG_TARGET_NAMESPACE = rb_define_module_under(mGLib, "GetText"); + RG_DEF_SMETHOD(bindtextdomain, -1); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_i18n.c (+40 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_i18n.c 2017-02-15 13:19:47 +0900 (7e2e99f) @@ -0,0 +1,40 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2006 Kouhei Sutou + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" +#include "rbglib.h" +#undef _ +#include <glib/gi18n.h> + +#define RG_TARGET_NAMESPACE mGLib + +static VALUE +rg_s_language_names(G_GNUC_UNUSED VALUE self) +{ + return STRV2RVAL((const gchar **)g_get_language_names()); +} + +void +Init_glib_i18n(void) +{ + /* glib/gi18n.h */ + RG_DEF_SMETHOD(language_names, 0); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_int64.c (+165 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_int64.c 2017-02-15 13:19:47 +0900 (820313c) @@ -0,0 +1,165 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2003 Masahiro Sakai + * Copyright (C) 2002 Masahiro Sakai + * Kenichi Komiya + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" + +static ID id_and; +static ID id_rshift; +static ID id_lshift; +static ID id_lt; +static ID id_plus; +static ID id_uminus; +static ID id_abs; +static VALUE max_PRUint32; + +typedef guint64 PRUint64; +typedef gint64 PRInt64; + +#define LL_ZERO G_GINT64_CONSTANT(0) +#define LL_UI2L(lhs,rhs) ((lhs)=(rhs)) +#define LL_L2UI(lhs,rhs) ((lhs)=(guint32)(rhs)) +#define LL_SHL(lhs,v1,v2) ((lhs)=(v1)<<(v2)) +#define LL_SHR(lhs,v1,v2) ((lhs)=(v1)>>(v2)) +#define LL_ADD(lhs,v1,v2) ((lhs)=(v1)+(v2)) +#define LL_NEG(lhs,rhs) ((lhs)=-(rhs)) +#define LL_CMP(v1,op,v2) ((v1) op (v2)) + +/**********************************************************************/ +/* + following is ripped from rbXPCOM-0.0.3 + http://www.ruby-lang.org/en/raa-list.rhtml?name=rbXPCOM + Copyright (C) 2001 Kenichi Komiya <kom****@mail1*****> +*/ + +static PRUint64 +RubyTo64BitInt(VALUE aRuby) +{ + VALUE bitMask = max_PRUint32; + VALUE lo = rb_funcall(aRuby, id_and, 1, bitMask); + VALUE hi = rb_funcall(aRuby, id_rshift, 1, INT2FIX(32)); + PRUint64 result, hi64, lo64; + LL_UI2L(hi64, NUM2UINT(hi)); + LL_UI2L(lo64, NUM2UINT(lo)); + LL_SHL(result, hi64, 32); + LL_ADD(result, result, lo64); + return result; +} + + +static inline PRUint64 +RubyToPRUint64(VALUE aRuby) +{ + return RubyTo64BitInt(aRuby); +} + + +static PRInt64 +RubyToPRInt64(VALUE aRuby) +{ + if(RVAL2CBOOL(rb_funcall(aRuby, id_lt, 1, INT2FIX(0)))) + { + VALUE absRuby = rb_funcall(aRuby, id_abs, 0); + PRInt64 result; + LL_NEG(result, RubyTo64BitInt(absRuby)); + return result; + } else + return (PRInt64)RubyTo64BitInt(aRuby); + +} + +static VALUE +RubyFrom64BitInt(PRUint64 aNative) +{ + PRUint64 lo64, hi64; + LL_L2UI(lo64, aNative); + LL_SHR(hi64, aNative, 32); + { + VALUE lo = UINT2NUM(lo64); + VALUE hi = UINT2NUM(hi64); + VALUE hiRuby = rb_funcall(hi, id_lshift, 1, INT2FIX(32)); + return rb_funcall(hiRuby, id_plus, 1, lo); + } +} + +static inline VALUE +PRUint64ToRuby(PRUint64 aNative) +{ + return RubyFrom64BitInt(aNative); +} + +static VALUE +PRInt64ToRuby(PRInt64 aNative) +{ + if(LL_CMP(aNative, <, LL_ZERO)) + { + PRUint64 abs64; + LL_NEG(abs64, aNative); + return rb_funcall(RubyFrom64BitInt(abs64), id_uminus, 0); + } + else + return RubyFrom64BitInt((PRUint64)aNative); +} + +/* end of ripping */ +/**********************************************************************/ + +VALUE +rbglib_int64_to_num(guint64 val) +{ + return PRInt64ToRuby(val); +} + +VALUE +rbglib_uint64_to_num(guint64 val) +{ + return PRUint64ToRuby(val); +} + +gint64 +rbglib_num_to_int64(VALUE val) +{ + return RubyToPRInt64(val); +} + +guint64 +rbglib_num_to_uint64(VALUE val) +{ + return RubyToPRUint64(val); +} + +/**********************************************************************/ + +void +Init_glib_int64(void) +{ + id_and = rb_intern("&"); + id_rshift = rb_intern(">>"); + id_lshift = rb_intern("<<"); + id_lt = rb_intern("<"); + id_plus = rb_intern("+"); + id_uminus = rb_intern("-@"); + id_abs = rb_intern("abs"); + + rb_global_variable(&max_PRUint32); + max_PRUint32 = UINT2NUM(0xffffffffL); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_io_constants.c (+30 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_io_constants.c 2017-02-15 13:19:47 +0900 (88e6fb4) @@ -0,0 +1,30 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011-2012 Ruby-GNOME2 Project Team + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" + +void +Init_glib_io_constants(void) +{ + VALUE RG_TARGET_NAMESPACE = mGLib; + + /* GIOCondition */ + G_DEF_CLASS(G_TYPE_IO_CONDITION, "IOCondition", RG_TARGET_NAMESPACE); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_iochannel.c (+821 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_iochannel.c 2017-02-15 13:19:47 +0900 (bf2dbd5) @@ -0,0 +1,821 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2005 Masao Mutoh + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" + +static ID id_call; +static ID id_puts; +static ID id_unpack; + +static VALUE default_rs; + +#define RG_TARGET_NAMESPACE cIOChannel +#define _SELF(s) ((GIOChannel*)RVAL2BOXED(s, G_TYPE_IO_CHANNEL)) + +static void +ioc_error(GIOStatus status, GError *err) +{ + if (err != NULL) RAISE_GERROR(err); + + if (status == G_IO_STATUS_EOF){ + rb_raise(rb_eEOFError, "End of file reached"); + } else if (status == G_IO_STATUS_AGAIN){ + rb_raise(rb_eRuntimeError, "G_IO_STATUS_AGAIN"); + } else if (status == G_IO_STATUS_NORMAL){ + /* Do nothing */ + } else { + rb_raise(rb_eRuntimeError, "An error occurred. status = %d\n", status); + } +} + +static VALUE +rg_initialize(gint argc, VALUE *argv, VALUE self) +{ + VALUE arg1, arg2; + + GIOChannel* io = NULL; + rb_scan_args(argc, argv, "11", &arg1, &arg2); + + if (TYPE(arg1) != T_STRING){ + gint fd; + if (TYPE(arg1) == T_FIXNUM){ + fd = NUM2INT(arg1); + } else { + fd = NUM2INT(rb_funcall(arg1, rb_intern("to_i"), 0)); + } +#ifdef G_OS_UNIX + io = g_io_channel_unix_new(fd); +#elif defined(G_OS_WIN32) + io = g_io_channel_win32_new_fd(fd); +#else + rb_raise(rb_eRuntimeError, "GLib::IOChannel.new(fd) is supported on UNIX environment only"); +#endif + } else { + GError* err = NULL; + io = g_io_channel_new_file(RVAL2CSTR(arg1), + NIL_P(arg2) ? "r" : RVAL2CSTR(arg2), &err); + + if (err != NULL) RAISE_GERROR(err); + } + + G_INITIALIZE(self, io); + + return Qnil; +} + +static VALUE +ioc_close(VALUE self) +{ + GError* err = NULL; + GIOStatus status = g_io_channel_shutdown(_SELF(self), TRUE, &err); + + ioc_error(status, err); + return self; +} + +static VALUE +rg_s_open(gint argc, VALUE *argv, G_GNUC_UNUSED VALUE self) +{ + VALUE arg1, arg2; + VALUE rio; + GIOChannel* io = NULL; + + rb_scan_args(argc, argv, "11", &arg1, &arg2); + + if (TYPE(arg1) == T_FIXNUM){ +#ifdef G_OS_UNIX + io = g_io_channel_unix_new(NUM2INT(arg1)); +#elif defined(G_OS_WIN32) + io = g_io_channel_win32_new_fd(NUM2INT(arg1)); +#else + rb_raise(rb_eRuntimeError, + "GLib::IOChannel.new(fd) is supported on " + "UNIX and Windows environment only"); +#endif + } else { + GError* err = NULL; + io = g_io_channel_new_file(RVAL2CSTR(arg1), + NIL_P(arg2) ? "r" : RVAL2CSTR(arg2), &err); + + if (err != NULL) RAISE_GERROR(err); + } + + rio = BOXED2RVAL(io, G_TYPE_IO_CHANNEL); + + if (rb_block_given_p()) { + return rb_ensure(rb_yield, rio, ioc_close, rio); + } + return rio; +} + +static VALUE +rg_fileno(VALUE self) +{ +#ifdef G_OS_UNIX + return INT2NUM(g_io_channel_unix_get_fd(_SELF(self))); +#elif defined(G_OS_WIN32) + return INT2NUM(g_io_channel_win32_get_fd(_SELF(self))); +#else + rb_warn("GLib::IOChannel#fd is supported on " + "UNIX and Windows environment only."); + return Qnil; +#endif +} + +/* Don't need this +void g_io_channel_init (GIOChannel *channel); +*/ + +static VALUE +rg_read(gint argc, VALUE *argv, VALUE self) +{ + VALUE rbcount; + gsize count; + gchar *buffer; + gsize bytes_read; + GIOChannel *channel = _SELF(self); + GError *error = NULL; + GIOStatus status; + + rb_scan_args(argc, argv, "01", &rbcount); + + if (NIL_P(rbcount)) { + status = g_io_channel_read_to_end(channel, &buffer, &bytes_read, &error); + ioc_error(status, error); + + return buffer != NULL ? CSTR2RVAL_LEN_FREE(buffer, bytes_read) : CSTR2RVAL(""); + } + + count = NUM2UINT(rbcount); + + buffer = g_new(gchar, count); + memset(buffer, '\0', count); + + status = g_io_channel_read_chars(channel, buffer, count, &bytes_read, &error); + if (status == G_IO_STATUS_NORMAL) + return CSTR2RVAL_LEN_FREE(buffer, bytes_read); + else if (status == G_IO_STATUS_EOF) + return CSTR2RVAL(""); + + ioc_error(status, error); + + /* Not reached. */ + return Qnil; +} + +static VALUE +rg_readchar(VALUE self) +{ + gunichar thechar; + GError* err = NULL; + GIOStatus status = g_io_channel_read_unichar(_SELF(self), &thechar, &err); + + ioc_error(status, err); + + return UINT2NUM(thechar); +} + +static VALUE +rg_getc(VALUE self) +{ + gunichar thechar; + GError* err = NULL; + VALUE ret; + GIOStatus status = g_io_channel_read_unichar(_SELF(self), &thechar, &err); + + if (status == G_IO_STATUS_EOF){ + ret = Qnil; + } else { + ioc_error(status, err); + ret = UINT2NUM(thechar); + } + + return ret; +} + +static VALUE +rg_each_char(VALUE self) +{ + if (!rb_block_given_p()) { + rb_raise(rb_eArgError, "called without a block"); + } + + while (TRUE){ + gunichar thechar; + GError* err = NULL; + GIOStatus status = g_io_channel_read_unichar(_SELF(self), &thechar, &err); + if (status == G_IO_STATUS_EOF){ + break; + } else { + ioc_error(status, err); + rb_yield(UINT2NUM(thechar)); + } + } + return self; +} + +static VALUE +rg_readline(gint argc, VALUE *argv, VALUE self) +{ + gchar* str; + VALUE line_term, ret; + GIOStatus status; + GError* err = NULL; + + const gchar* old_line_term = NULL; + gint old_line_term_len; + + rb_scan_args(argc, argv, "01", &line_term); + + if (! NIL_P(line_term)){ + StringValue(line_term); + old_line_term = g_io_channel_get_line_term(_SELF(self), &old_line_term_len); + + g_io_channel_set_line_term(_SELF(self), RVAL2CSTR(line_term), + RSTRING_LEN(line_term)); + } + + status = g_io_channel_read_line(_SELF(self), &str, NULL, NULL, &err); + + if (! NIL_P(line_term)){ + g_io_channel_set_line_term(_SELF(self), old_line_term, old_line_term_len); + } + + ioc_error(status, err); + + ret = str ? CSTR2RVAL(str) : CSTR2RVAL(""); + g_free(str); + + return ret; +} + +static VALUE +rg_gets(gint argc, VALUE *argv, VALUE self) +{ + gchar* str; + VALUE line_term, ret; + GIOStatus status; + GError* err = NULL; + + const gchar* old_line_term = NULL; + gint old_line_term_len; + + rb_scan_args(argc, argv, "01", &line_term); + + if (! NIL_P(line_term)){ + StringValue(line_term); + + old_line_term = g_io_channel_get_line_term(_SELF(self), &old_line_term_len); + g_io_channel_set_line_term(_SELF(self), RVAL2CSTR(line_term), + RSTRING_LEN(line_term)); + } + + status = g_io_channel_read_line(_SELF(self), &str, NULL, NULL, &err); + + if (! NIL_P(line_term)){ + g_io_channel_set_line_term(_SELF(self), old_line_term, old_line_term_len); + } + + if (status == G_IO_STATUS_EOF){ + ret = Qnil; + } else { + ioc_error(status, err); + ret = str ? CSTR2RVAL(str) : CSTR2RVAL(""); + } + g_free(str); + + return ret; +} + +/* Internal use only */ +static VALUE +ioc_set_line_term(VALUE args) +{ + VALUE self = RARRAY_PTR(args)[0]; + VALUE doit = RARRAY_PTR(args)[1]; + VALUE line_term = RARRAY_PTR(args)[2]; + + if (doit == Qtrue){ + StringValue(line_term); + g_io_channel_set_line_term(_SELF(self), RVAL2CSTR(line_term), + RSTRING_LEN(line_term)); + } + return self; +} + +static VALUE +rg_each(gint argc, VALUE *argv, VALUE self) +{ + gchar* str; + VALUE line_term; + GIOStatus status; + GError* err = NULL; + GIOChannel *channel; + const gchar* old_line_term = NULL; + gint old_line_term_len; + + if (!rb_block_given_p()) { + rb_raise(rb_eArgError, "called without a block"); + } + + rb_scan_args(argc, argv, "01", &line_term); + + channel = _SELF(self); + if (!NIL_P(line_term)) { + StringValue(line_term); + + old_line_term = g_io_channel_get_line_term(channel, &old_line_term_len); + g_io_channel_set_line_term(channel, RVAL2CSTR(line_term), + RSTRING_LEN(line_term)); + } + + while (TRUE) { + status = g_io_channel_read_line(channel, &str, NULL, NULL, &err); + if (status == G_IO_STATUS_EOF) { + break; + } else { + VALUE rstr; + ioc_error(status, err); + if (str) { + rstr = CSTR2RVAL(str); + } else { + rstr = CSTR2RVAL(""); + } + g_free(str); + rb_ensure(rb_yield, rstr, ioc_set_line_term, + rb_ary_new3(3, self, + NIL_P(line_term) ? Qfalse : Qtrue, + CSTR2RVAL(old_line_term))); + } + } + return self; +} + +/* Don't need this. +GIOStatus g_io_channel_read_line_string (GIOChannel *channel, + GString *buffer, + gsize *terminator_pos, + GError **error); +*/ + +/* Use GLib::IOChannel#read instead. +static VALUE +ioc_read_to_end(VALUE self) +{ + gchar* str; + gsize length; + VALUE ret; + GError* err = NULL; + + GIOStatus status = g_io_channel_read_to_end(_SELF(self), &str, + &length, &err); + + ioc_error(status, err); + + ret = str ? rb_str_new(str, length) : CSTR2RVAL(""); + g_free(str); + + return ret; +} +*/ + +static VALUE +rg_write(VALUE self, VALUE buf) +{ + gssize count; + gsize bytes_written; + GIOStatus status; + GError* err = NULL; + + buf = rb_obj_as_string(buf); + + StringValue(buf); + + count = RSTRING_LEN(buf); + + status = g_io_channel_write_chars(_SELF(self), RVAL2CSTR(buf), count, &bytes_written, &err); + + ioc_error(status, err); + return UINT2NUM(bytes_written); +} + +static VALUE +rg_putc(VALUE self, VALUE thechar) +{ + GError* err = NULL; + GIOStatus status; + gunichar unichar; + + if (TYPE(thechar) == T_FIXNUM) { + unichar = NUM2UINT(thechar); + } else { + VALUE ary = rb_funcall(thechar, id_unpack, 1, CSTR2RVAL("U")); + unichar = NUM2UINT(RARRAY_PTR(ary)[0]); + } + + status = g_io_channel_write_unichar(_SELF(self), unichar, &err); + + ioc_error(status, err); + + return self; +} + +static VALUE +rg_flush(VALUE self) +{ + GError* err = NULL; + GIOStatus status = g_io_channel_flush(_SELF(self), &err); + ioc_error(status, err); + return self; +} + +static VALUE +rg_seek(gint argc, VALUE *argv, VALUE self) +{ + VALUE ofs, type; + GIOStatus status; + GError* err = NULL; + GSeekType gtype = G_SEEK_SET; + + rb_scan_args(argc, argv, "11", &ofs, &type); + + if (!NIL_P(type)) + gtype = NUM2INT(type); + + status = g_io_channel_seek_position(_SELF(self), NUM2INT(ofs), + gtype, &err); + ioc_error(status, err); + return self; +} + +static VALUE +rg_set_pos(VALUE self, VALUE pos) +{ + GError* err = NULL; + GIOStatus status = g_io_channel_seek_position(_SELF(self), NUM2INT(pos), + G_SEEK_SET, &err); + ioc_error(status, err); + return self; +} + +static VALUE +rg_close(gint argc, VALUE *argv, VALUE self) +{ + VALUE flush; + GError* err = NULL; + gboolean gflush = TRUE; + GIOStatus status; + + rb_scan_args(argc, argv, "01", &flush); + + if (!NIL_P(flush)){ + gflush = RVAL2CBOOL(flush); + } + + status = g_io_channel_shutdown(_SELF(self), gflush, &err); + ioc_error(status, err); + + return self; +} + +static VALUE +rg_create_watch(VALUE self, VALUE condition) +{ + return BOXED2RVAL(g_io_create_watch(_SELF(self), NUM2INT(condition)), + G_TYPE_SOURCE); +} + +static gboolean +io_func(GIOChannel *source, GIOCondition condition, gpointer func) +{ + return RVAL2CBOOL(rb_funcall((VALUE)func, id_call, 2, + BOXED2RVAL(source, G_TYPE_IO_CHANNEL), + INT2NUM(condition))); +} + +static VALUE +rg_add_watch(VALUE self, VALUE condition) +{ + VALUE func = rb_block_proc(); + G_RELATIVE(self, func); + return UINT2NUM(g_io_add_watch(_SELF(self), NUM2INT(condition), + (GIOFunc)io_func, (gpointer)func)); +} + +/* Don't need this +guint g_io_add_watch_full (GIOChannel *channel, + gint priority, + GIOCondition condition, + GIOFunc func, + gpointer user_data, + GDestroyNotify notify); +*/ + +static VALUE +rg_buffer_size(VALUE self) +{ + return UINT2NUM(g_io_channel_get_buffer_size(_SELF(self))); +} + +static VALUE +rg_set_buffer_size(VALUE self, VALUE buffer_size) +{ + g_io_channel_set_buffer_size(_SELF(self), NUM2UINT(buffer_size)); + return self; +} + +static VALUE +rg_buffer_condition(VALUE self) +{ + return INT2NUM(g_io_channel_get_buffer_condition(_SELF(self))); +} + +static VALUE +rg_flags(VALUE self) +{ + return INT2NUM(g_io_channel_get_flags(_SELF(self))); +} + +static VALUE +rg_set_flags(VALUE self, VALUE flags) +{ + GError* err = NULL; + GIOStatus status = g_io_channel_set_flags(_SELF(self), + NUM2INT(flags), &err); + ioc_error(status, err); + return self; +} + +/* Use them with GLib::IOChannel#gets, #readline, #readlines +static VALUE +ioc_get_line_term(VALUE self) +{ + gint length; + const gchar* ret = g_io_channel_get_line_term(_SELF(self), &length); + if (ret) { + if (length < 0) { + return CSTR2RVAL(ret); + } else { + return rb_str_new(ret, length); + } + } + return Qnil; +} + +static VALUE +ioc_set_line_term(VALUE self, VALUE line_term) +{ + StringValue(line_term); + g_io_channel_set_line_term(_SELF(self), RVAL2CSTR(line_term), + RSTRING_LEN(line_term)); + return self; +} +*/ + +static VALUE +rg_buffered(VALUE self) +{ + return CBOOL2RVAL(g_io_channel_get_buffered(_SELF(self))); +} + +static VALUE +rg_set_buffered(VALUE self, VALUE buffered) +{ + g_io_channel_set_buffered(_SELF(self), RVAL2CBOOL(buffered)); + return self; +} + +static VALUE +rg_encoding(VALUE self) +{ + return CSTR2RVAL(g_io_channel_get_encoding(_SELF(self))); +} + +static VALUE +rg_set_encoding(VALUE self, VALUE encoding) +{ + GError* err = NULL; + GIOStatus status; + + status = g_io_channel_set_encoding(_SELF(self), + RVAL2CSTR_ACCEPT_NIL(encoding), + &err); + ioc_error(status, err); + return self; +} + +/* Don't we need them ? +gboolean g_io_channel_get_close_on_unref (GIOChannel *channel); +void g_io_channel_set_close_on_unref (GIOChannel *channel, + gboolean do_close); +*/ + +/* Deprecated +GIOError g_io_channel_read (GIOChannel *channel, + gchar *buf, + gsize count, + gsize *bytes_read); +enum GIOError; +GIOError g_io_channel_write (GIOChannel *channel, + const gchar *buf, + gsize count, + gsize *bytes_written); +GIOError g_io_channel_seek (GIOChannel *channel, + gint64 offset, + GSeekType type); +void g_io_channel_close (GIOChannel *channel); +*/ + +/* + * Stolen some convenient methods from io.c + */ +static VALUE +rg_printf(int argc, VALUE *argv, VALUE self) +{ + rg_write(self, rb_f_sprintf(argc, argv)); + return Qnil; +} + +static VALUE +ioc_puts_ary(VALUE ary, VALUE out, int recur) +{ + VALUE tmp; + long i; + + for (i=0; i<RARRAY_LEN(ary); i++) { + tmp = RARRAY_PTR(ary)[i]; + if (recur) { + tmp = rb_str_new2("[...]"); + } + rb_funcall(out, id_puts, 1, tmp); + } + return Qnil; +} + +static VALUE +rg_puts(int argc, VALUE *argv, VALUE self) +{ + int i; + VALUE line; + + /* if no argument given, print newline. */ + if (argc == 0) { + rg_write(self, default_rs); + return Qnil; + } + for (i=0; i<argc; i++) { + if (NIL_P(argv[i])) { + line = rb_str_new2("nil"); + } + else { + line = rbg_check_array_type(argv[i]); + if (!NIL_P(line)) { +#ifdef HAVE_RB_EXEC_RECURSIVE + rb_exec_recursive(ioc_puts_ary, line, self); +#else + rb_protect_inspect(ioc_puts_ary, line, self); +#endif + continue; + } + line = rb_obj_as_string(argv[i]); + } + rg_write(self, line); + if (RSTRING_LEN(line) == 0 || + RSTRING_PTR(line)[RSTRING_LEN(line)-1] != '\n') { + rg_write(self, default_rs); + } + } + + return Qnil; +} + +static VALUE +rg_print(int argc, VALUE *argv, VALUE out) +{ + int i; + VALUE line; + VALUE output_field_separator; + + /* if no argument given, print `$_' */ + if (argc == 0) { + argc = 1; + line = rb_lastline_get(); + argv = &line; + } + + output_field_separator = rb_gv_get("$,"); + for (i=0; i<argc; i++) { + if (!NIL_P(output_field_separator) && i>0) { + rg_write(out, output_field_separator); + } + switch (TYPE(argv[i])) { + case T_NIL: + rg_write(out, rb_str_new2("nil")); + break; + default: + rg_write(out, argv[i]); + break; + } + } + if (!NIL_P(output_field_separator)) { + rg_write(out, output_field_separator); + } + + return Qnil; +} + +void +Init_glib_io_channel(void) +{ + VALUE RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_IO_CHANNEL, "IOChannel", mGLib); + + rb_include_module(RG_TARGET_NAMESPACE, rb_mEnumerable); + + id_call = rb_intern("call"); + id_puts = rb_intern("puts"); + id_unpack = rb_intern("unpack"); + + default_rs = rb_str_new_cstr("\n"); +#ifdef HAVE_RB_GC_REGISTER_MARK_OBJECT + rb_gc_register_mark_object(default_rs); +#else + rb_global_variable(&default_rs); +#endif + + RG_DEF_METHOD(initialize, -1); + RG_DEF_SMETHOD(open, -1); + RG_DEF_METHOD(fileno, 0); + RG_DEF_ALIAS("to_i", "fileno"); + RG_DEF_METHOD(read, -1); + RG_DEF_METHOD(readchar, 0); + RG_DEF_METHOD(getc, 0); + RG_DEF_METHOD(readline, -1); + RG_DEF_METHOD(gets, -1); + RG_DEF_METHOD(each, -1); + RG_DEF_ALIAS("each_line", "each"); + RG_DEF_METHOD(each_char, 0); + RG_DEF_METHOD(write, 1); + RG_DEF_METHOD(printf, -1); + RG_DEF_METHOD(print, -1); + RG_DEF_METHOD(puts, -1); + RG_DEF_METHOD(putc, 1); + RG_DEF_METHOD(flush, 0); + RG_DEF_METHOD(seek, -1); + RG_DEF_METHOD(set_pos, 1); + RG_DEF_METHOD(close, -1); + RG_DEF_METHOD(create_watch, 1); + RG_DEF_METHOD(add_watch, 1); + RG_DEF_METHOD(buffer_size, 0); + RG_DEF_METHOD(set_buffer_size, 1); + RG_DEF_METHOD(buffer_condition, 0); + RG_DEF_METHOD(flags, 0); + RG_DEF_METHOD(set_flags, 1); + RG_DEF_METHOD(buffered, 0); + RG_DEF_METHOD(set_buffered, 1); + RG_DEF_METHOD(encoding, 0); + RG_DEF_METHOD(set_encoding, 1); + + /* GSeekType */ + rb_define_const(RG_TARGET_NAMESPACE, "SEEK_CUR", INT2NUM(G_SEEK_CUR)); + rb_define_const(RG_TARGET_NAMESPACE, "SEEK_SET", INT2NUM(G_SEEK_SET)); + rb_define_const(RG_TARGET_NAMESPACE, "SEEK_END", INT2NUM(G_SEEK_END)); + + /* GIOStatus */ + rb_define_const(RG_TARGET_NAMESPACE, "STATUS_ERROR", INT2NUM(G_IO_STATUS_ERROR)); + rb_define_const(RG_TARGET_NAMESPACE, "STATUS_NORMAL", INT2NUM(G_IO_STATUS_NORMAL)); + rb_define_const(RG_TARGET_NAMESPACE, "STATUS_EOF", INT2NUM(G_IO_STATUS_EOF)); + rb_define_const(RG_TARGET_NAMESPACE, "STATUS_AGAIN", INT2NUM(G_IO_STATUS_AGAIN)); + + /* GIOCondition */ + /* Deprecated. Just for bacakward compatibility. Use + * GLib::IOCondition::* instead. */ + G_DEF_CONSTANTS(RG_TARGET_NAMESPACE, G_TYPE_IO_CONDITION, "G_IO_"); + + /* GIOFlags */ + rb_define_const(RG_TARGET_NAMESPACE, "FLAG_APPEND", INT2NUM(G_IO_FLAG_APPEND)); + rb_define_const(RG_TARGET_NAMESPACE, "FLAG_NONBLOCK", INT2NUM(G_IO_FLAG_NONBLOCK)); + rb_define_const(RG_TARGET_NAMESPACE, "FLAG_READABLE", INT2NUM(G_IO_FLAG_IS_READABLE)); + rb_define_const(RG_TARGET_NAMESPACE, "FLAG_WRITEABLE", INT2NUM(G_IO_FLAG_IS_WRITEABLE)); + rb_define_const(RG_TARGET_NAMESPACE, "FLAG_IS_SEEKABLE", INT2NUM(G_IO_FLAG_IS_SEEKABLE)); + rb_define_const(RG_TARGET_NAMESPACE, "FLAG_MASK", INT2NUM(G_IO_FLAG_MASK)); + rb_define_const(RG_TARGET_NAMESPACE, "FLAG_GET_MASK", INT2NUM(G_IO_FLAG_GET_MASK)); + rb_define_const(RG_TARGET_NAMESPACE, "FLAG_SET_MASK", INT2NUM(G_IO_FLAG_SET_MASK)); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_iochannel_win32_socket.c (+55 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_iochannel_win32_socket.c 2017-02-15 13:19:47 +0900 (5eaa8f2) @@ -0,0 +1,55 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2005 Masao Mutoh + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" + +#ifdef G_OS_WIN32 + +#define RG_TARGET_NAMESPACE cIOChannelWin32Socket + +static VALUE +rg_initialize(VALUE self, VALUE socket) +{ + GIOChannel *io = NULL; + int fd; + + /* TODO: support IO object */ + fd = NUM2INT(socket); + io = g_io_channel_win32_new_socket(rb_w32_get_osfhandle(fd)); + G_INITIALIZE(self, io); + + return Qnil; +} +#endif + +void +Init_glib_io_channel_win32_socket(void) +{ +#ifdef G_OS_WIN32 + /* GIOWin32Channel */ + VALUE RG_TARGET_NAMESPACE; + RG_TARGET_NAMESPACE = + rb_define_class_under(mGLib, + "IOChannelWin32Socket", + rb_const_get(mGLib, rb_intern("IOChannel"))); + RG_DEF_METHOD(initialize, 1); +#endif +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_iochannelerror.c (+49 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_iochannelerror.c 2017-02-15 13:19:47 +0900 (82fbedf) @@ -0,0 +1,49 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2005 Masao Mutoh + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" + +#define RG_TARGET_NAMESPACE cIOChannelError + +static VALUE +rg_s_from_errno(G_GNUC_UNUSED VALUE self, VALUE errno_) +{ + return INT2NUM(g_io_channel_error_from_errno(NUM2INT(errno_))); +} + +void +Init_glib_io_channelerror(void) +{ + VALUE RG_TARGET_NAMESPACE = G_DEF_ERROR2(G_IO_CHANNEL_ERROR, "IOChannelError", mGLib, rb_eIOError); + + /* GIOChannelError */ + RG_DEF_SMETHOD(from_errno, 1); + + rb_define_const(RG_TARGET_NAMESPACE, "FBIG", INT2NUM(G_IO_CHANNEL_ERROR_FBIG)); + rb_define_const(RG_TARGET_NAMESPACE, "INVAL", INT2NUM(G_IO_CHANNEL_ERROR_INVAL)); + rb_define_const(RG_TARGET_NAMESPACE, "IO", INT2NUM(G_IO_CHANNEL_ERROR_IO)); + rb_define_const(RG_TARGET_NAMESPACE, "ISDIR", INT2NUM(G_IO_CHANNEL_ERROR_ISDIR)); + rb_define_const(RG_TARGET_NAMESPACE, "NOSPC", INT2NUM(G_IO_CHANNEL_ERROR_NOSPC)); + rb_define_const(RG_TARGET_NAMESPACE, "NXIO", INT2NUM(G_IO_CHANNEL_ERROR_NXIO)); + rb_define_const(RG_TARGET_NAMESPACE, "OVERFLOW", INT2NUM(G_IO_CHANNEL_ERROR_OVERFLOW)); + rb_define_const(RG_TARGET_NAMESPACE, "PIPE", INT2NUM(G_IO_CHANNEL_ERROR_PIPE)); + rb_define_const(RG_TARGET_NAMESPACE, "FAILED", INT2NUM(G_IO_CHANNEL_ERROR_FAILED)); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_keyfile.c (+755 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_keyfile.c 2017-02-15 13:19:47 +0900 (af6b1fd) @@ -0,0 +1,755 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2006 Masao Mutoh + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" + +#if !GLIB_CHECK_VERSION(2,31,2) +/************************************************/ +static GKeyFile* +keyfile_copy(const GKeyFile* keyfile) +{ +// GKeyFile* new_keyfile; + g_return_val_if_fail (keyfile != NULL, NULL); +/* + new_keyfile = g_key_file_new(); + *new_keyfile = (GKeyFile*)*keyfile; + return new_keyfile; +*/ + return (GKeyFile*)keyfile; +} + +GType +g_key_file_get_type(void) +{ + static GType our_type = 0; + if (our_type == 0) + our_type = g_boxed_type_register_static("GKeyFile", + (GBoxedCopyFunc)keyfile_copy, + (GBoxedFreeFunc)g_key_file_free); + return our_type; +} +/************************************************/ +#endif + +#define RG_TARGET_NAMESPACE cKeyFile +#define _SELF(self) ((GKeyFile*)(RVAL2BOXED(self, G_TYPE_KEY_FILE))) + +static VALUE +rg_initialize(VALUE self) +{ + G_INITIALIZE(self, g_key_file_new()); + return Qnil; +} + +static VALUE +rg_set_list_separator(VALUE self, VALUE sep) +{ + g_key_file_set_list_separator(_SELF(self), NUM2INT(sep)); + return self; +} + +static VALUE +rg_load_from_file(int argc, VALUE *argv, VALUE self) +{ + VALUE file, flags; + GError* error = NULL; + gboolean ret; + GKeyFileFlags gflags = G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS; + + rb_scan_args(argc, argv, "11", &file, &flags); + + if (!NIL_P(flags)){ + gflags = RVAL2GFLAGS(flags, G_TYPE_KEY_FILE_FLAGS); + } + + ret = g_key_file_load_from_file(_SELF(self), + RVAL2CSTR(file), + gflags, &error); + + if (! ret) RAISE_GERROR(error); + + return self; +} + +static VALUE +rg_load_from_data(int argc, VALUE *argv, VALUE self) +{ + VALUE data, flags; + GError* error = NULL; + gboolean ret; + GKeyFileFlags gflags = G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS; + + rb_scan_args(argc, argv, "11", &data, &flags); + + if (!NIL_P(flags)){ + gflags = RVAL2GFLAGS(flags, G_TYPE_KEY_FILE_FLAGS); + } + StringValue(data); + + ret = g_key_file_load_from_data(_SELF(self), + (const gchar*)RVAL2CSTR(data), + (gsize)RSTRING_LEN(data), + gflags, &error); + + if (! ret) RAISE_GERROR(error); + + return self; +} + +static VALUE +rg_load_from_data_dirs(int argc, VALUE *argv, VALUE self) +{ + VALUE file, flags; + GError* error = NULL; + gboolean ret; + gchar* full_path; + GKeyFileFlags gflags = G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS; + + rb_scan_args(argc, argv, "11", &file, &flags); + + if (!NIL_P(flags)){ + gflags = RVAL2GFLAGS(flags, G_TYPE_KEY_FILE_FLAGS); + } + StringValue(file); + + ret = g_key_file_load_from_data_dirs(_SELF(self), + (const gchar*)RVAL2CSTR(file), + &full_path, + gflags, &error); + + if (! ret) RAISE_GERROR(error); + + return full_path ? CSTR2RVAL(full_path) : Qnil; +} + +#if GLIB_CHECK_VERSION(2, 14, 0) +static VALUE +rg_load_from_dirs(int argc, VALUE *argv, VALUE self) +{ + VALUE rb_file, rb_search_dirs, rb_flags; + GError* error = NULL; + gboolean success; + const gchar *file; + const gchar **search_dirs; + gchar* full_path; + GKeyFileFlags flags; + + rb_scan_args(argc, argv, "12", &rb_file, &rb_search_dirs, &rb_flags); + + file = RVAL2CSTR(rb_file); + search_dirs = RVAL2STRV_ACCEPT_NIL(rb_search_dirs); + flags = G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS; + if (!NIL_P(rb_flags)) + flags = RVAL2GFLAGS(rb_flags, G_TYPE_KEY_FILE_FLAGS); + + if (search_dirs != NULL) + success = g_key_file_load_from_dirs(_SELF(self), file, + search_dirs, + &full_path, flags, &error); + else + success = g_key_file_load_from_data_dirs(_SELF(self), file, + &full_path, flags, &error); + + g_free(search_dirs); + + if (!success) + RAISE_GERROR(error); + + return CSTR2RVAL(full_path); +} +#endif + +static VALUE +rg_to_data(VALUE self) +{ + GError* error = NULL; + gchar* data = g_key_file_to_data(_SELF(self), NULL, &error); + + if (error) RAISE_GERROR(error); + + return CSTR2RVAL_FREE(data); +} + +static VALUE +rg_start_group(VALUE self) +{ + return CSTR2RVAL(g_key_file_get_start_group(_SELF(self))); +} + +static VALUE +rg_groups(VALUE self) +{ + return STRV2RVAL_FREE(g_key_file_get_groups(_SELF(self), NULL)); +} + +static VALUE +rg_get_keys(VALUE self, VALUE group_name) +{ + GError *error = NULL; + gchar **keys = g_key_file_get_keys(_SELF(self), + RVAL2CSTR(group_name), + NULL, + &error); + if (error != NULL) + RAISE_GERROR(error); + + return STRV2RVAL_FREE(keys); +} + +static VALUE +rg_has_group_p(VALUE self, VALUE group_name) +{ + return CBOOL2RVAL(g_key_file_has_group(_SELF(self), + (const gchar*)RVAL2CSTR(group_name))); +} + +static VALUE +rg_has_key_p(VALUE self, VALUE group_name, VALUE key) +{ + GError* error = NULL; + gboolean ret = g_key_file_has_key(_SELF(self), + (const gchar*)RVAL2CSTR(group_name), + (const gchar*)RVAL2CSTR(key), + &error); + + if (error) RAISE_GERROR(error); + + return CBOOL2RVAL(ret); +} + +static VALUE +rg_get_value(VALUE self, VALUE group_name, VALUE key) +{ + GError* error = NULL; + gchar* ret = g_key_file_get_value(_SELF(self), + (const gchar*)RVAL2CSTR(group_name), + (const gchar*)RVAL2CSTR(key), + &error); + + if (error) RAISE_GERROR(error); + + return CSTR2RVAL_FREE(ret); +} + +static VALUE +rg_get_string(VALUE self, VALUE group_name, VALUE key) +{ + GError* error = NULL; + gchar* ret = g_key_file_get_string(_SELF(self), + (const gchar*)RVAL2CSTR(group_name), + (const gchar*)RVAL2CSTR(key), + &error); + + if (error) RAISE_GERROR(error); + + return CSTR2RVAL_FREE(ret); +} + +static VALUE +rg_get_locale_string(int argc, VALUE *argv, VALUE self) +{ + VALUE group_name, key, locale; + GError* error = NULL; + gchar* ret; + + rb_scan_args(argc, argv, "21", &group_name, &key, &locale); + + ret = g_key_file_get_locale_string(_SELF(self), + (const gchar*)RVAL2CSTR(group_name), + (const gchar*)RVAL2CSTR(key), + (const gchar*)RVAL2CSTR_ACCEPT_NIL(locale), + &error); + + if (error) RAISE_GERROR(error); + + return CSTR2RVAL_FREE(ret); +} + +static VALUE +rg_get_boolean(VALUE self, VALUE group_name, VALUE key) +{ + GError* error = NULL; + gboolean ret = g_key_file_get_boolean(_SELF(self), + (const gchar*)RVAL2CSTR(group_name), + (const gchar*)RVAL2CSTR(key), + &error); + + if (error) RAISE_GERROR(error); + + return CBOOL2RVAL(ret); +} + +static VALUE +rg_get_integer(VALUE self, VALUE group_name, VALUE key) +{ + GError* error = NULL; + gint ret = g_key_file_get_integer(_SELF(self), + (const gchar*)RVAL2CSTR(group_name), + (const gchar*)RVAL2CSTR(key), + &error); + + if (error) RAISE_GERROR(error); + + return INT2NUM(ret); +} + +static VALUE +rg_get_double(VALUE self, VALUE group_name, VALUE key) +{ + GError* error = NULL; + gdouble ret = g_key_file_get_double(_SELF(self), + (const gchar*)RVAL2CSTR(group_name), + (const gchar*)RVAL2CSTR(key), + &error); + + if (error) RAISE_GERROR(error); + + return rb_float_new(ret); +} + +static VALUE +rg_get_string_list(VALUE self, VALUE group_name, VALUE key) +{ + VALUE ary; + gsize i; + gsize length; + GError* error = NULL; + gchar** ret = g_key_file_get_string_list(_SELF(self), + (const gchar*)RVAL2CSTR(group_name), + (const gchar*)RVAL2CSTR(key), + &length, &error); + + if (error) RAISE_GERROR(error); + + ary = rb_ary_new(); + for(i = 0; i < length; i++){ + rb_ary_push(ary, CSTR2RVAL(ret[i])); + } + + g_strfreev(ret); + return ary; +} + +static VALUE +rg_get_locale_string_list(int argc, VALUE *argv, VALUE self) +{ + VALUE group_name, key, locale; + GError* error = NULL; + VALUE ary; + gsize i; + gsize length; + gchar** ret; + + rb_scan_args(argc, argv, "21", &group_name, &key, &locale); + + ret = g_key_file_get_locale_string_list(_SELF(self), + (const gchar*)RVAL2CSTR(group_name), + (const gchar*)RVAL2CSTR(key), + (const gchar*)RVAL2CSTR_ACCEPT_NIL(locale), + &length, &error); + + if (error) RAISE_GERROR(error); + + ary = rb_ary_new(); + for(i = 0; i < length; i++){ + rb_ary_push(ary, CSTR2RVAL(ret[i])); + } + + g_strfreev(ret); + return ary; +} + +static VALUE +rg_get_boolean_list(VALUE self, VALUE group_name, VALUE key) +{ + VALUE ary; + gsize i; + gsize length; + GError* error = NULL; + gboolean* ret = g_key_file_get_boolean_list(_SELF(self), + (const gchar*)RVAL2CSTR(group_name), + (const gchar*)RVAL2CSTR(key), + &length, &error); + + if (error) RAISE_GERROR(error); + + ary = rb_ary_new(); + for(i = 0; i < length; i++){ + rb_ary_push(ary, CBOOL2RVAL(ret[i])); + } + return ary; +} + +static VALUE +rg_get_integer_list(VALUE self, VALUE group_name, VALUE key) +{ + VALUE ary; + gsize i; + gsize length; + GError* error = NULL; + gint* ret = g_key_file_get_integer_list(_SELF(self), + (const gchar*)RVAL2CSTR(group_name), + (const gchar*)RVAL2CSTR(key), + &length, &error); + + if (error) RAISE_GERROR(error); + + ary = rb_ary_new(); + for(i = 0; i < length; i++){ + rb_ary_push(ary, INT2NUM(ret[i])); + } + return ary; +} + +static VALUE +rg_get_double_list(VALUE self, VALUE group_name, VALUE key) +{ + VALUE ary; + gsize i; + gsize length; + GError* error = NULL; + gdouble* ret = g_key_file_get_double_list(_SELF(self), + (const gchar*)RVAL2CSTR(group_name), + (const gchar*)RVAL2CSTR(key), + &length, &error); + + if (error) RAISE_GERROR(error); + + ary = rb_ary_new(); + for(i = 0; i < length; i++){ + rb_ary_push(ary, rb_float_new(ret[i])); + } + return ary; +} + +static VALUE +rg_get_comment(VALUE self, VALUE group_name, VALUE key) +{ + GError* error = NULL; + gchar* ret = g_key_file_get_comment(_SELF(self), + (const gchar*)RVAL2CSTR(group_name), + (const gchar*)RVAL2CSTR(key), + &error); + + if (error) RAISE_GERROR(error); + + return CSTR2RVAL_FREE(ret); +} + +static VALUE +rg_set_value(VALUE self, VALUE group_name, VALUE key, VALUE value) +{ + g_key_file_set_value(_SELF(self), (const gchar*)RVAL2CSTR(group_name), + (const gchar*)RVAL2CSTR(key), + (const gchar*)RVAL2CSTR(value)); + return self; +} + +static VALUE +rg_set_string(VALUE self, VALUE group_name, VALUE key, VALUE string) +{ + g_key_file_set_string(_SELF(self), (const gchar*)RVAL2CSTR(group_name), + (const gchar*)RVAL2CSTR(key), + (const gchar*)RVAL2CSTR(string)); + return self; +} + +static VALUE +rg_set_locale_string(VALUE self, VALUE group_name, VALUE key, VALUE locale, VALUE locale_string) +{ + g_key_file_set_locale_string(_SELF(self), (const gchar*)RVAL2CSTR(group_name), + (const gchar*)RVAL2CSTR(key), + (const gchar*)RVAL2CSTR(locale), + (const gchar*)RVAL2CSTR(locale_string)); + return self; +} + +static VALUE +rg_set_boolean(VALUE self, VALUE group_name, VALUE key, VALUE value) +{ + g_key_file_set_boolean(_SELF(self), (const gchar*)RVAL2CSTR(group_name), + (const gchar*)RVAL2CSTR(key), + RVAL2CBOOL(value)); + return self; +} + +static VALUE +rg_set_integer(VALUE self, VALUE group_name, VALUE key, VALUE value) +{ + g_key_file_set_integer(_SELF(self), (const gchar*)RVAL2CSTR(group_name), + (const gchar*)RVAL2CSTR(key), + NUM2INT(value)); + return self; +} + +static VALUE +rg_set_double(VALUE self, VALUE group_name, VALUE key, VALUE value) +{ + g_key_file_set_double(_SELF(self), (const gchar*)RVAL2CSTR(group_name), + (const gchar*)RVAL2CSTR(key), + NUM2DBL(value)); + return self; +} + +static VALUE +rg_set_string_list(VALUE self, VALUE rbgroup_name, VALUE rbkey, VALUE rblist) +{ + GKeyFile *key_file = _SELF(self); + const gchar *group_name = RVAL2CSTR(rbgroup_name); + const gchar *key = RVAL2CSTR(rbkey); + long n; + const gchar **list = RVAL2STRS(rblist, n); + + g_key_file_set_string_list(key_file, group_name, key, list, n); + + g_free(list); + + return self; +} + +static VALUE +rg_set_locale_string_list(VALUE self, VALUE rbgroup_name, VALUE rbkey, VALUE rblocale, VALUE rblist) +{ + GKeyFile *key_file = _SELF(self); + const gchar *group_name = RVAL2CSTR(rbgroup_name); + const gchar *key = RVAL2CSTR(rbkey); + const gchar *locale = RVAL2CSTR(rblocale); + long n; + const gchar **list = RVAL2STRS(rblist, n); + + g_key_file_set_locale_string_list(key_file, group_name, key, locale, list, n); + + g_free(list); + + return self; +} + +static VALUE +rg_set_boolean_list(VALUE self, VALUE rbgroup_name, VALUE rbkey, VALUE rblist) +{ + GKeyFile *key_file = _SELF(self); + const gchar *group_name = RVAL2CSTR(rbgroup_name); + const gchar *key = RVAL2CSTR(rbkey); + long n; + gboolean *list = RVAL2GBOOLEANS(rblist, n); + + g_key_file_set_boolean_list(key_file, group_name, key, list, n); + + g_free(list); + + return self; +} + +static VALUE +rg_set_integer_list(VALUE self, VALUE rbgroup_name, VALUE rbkey, VALUE rblist) +{ + GKeyFile *key_file = _SELF(self); + const gchar *group_name = RVAL2CSTR(rbgroup_name); + const gchar *key = RVAL2CSTR(rbkey); + long n; + gint *list = RVAL2GINTS(rblist, n); + + g_key_file_set_integer_list(key_file, group_name, key, list, n); + + g_free(list); + + return self; +} + +static VALUE +rg_set_double_list(VALUE self, VALUE rbgroup_name, VALUE rbkey, VALUE rblist) +{ + GKeyFile *key_file = _SELF(self); + const gchar *group_name = RVAL2CSTR(rbgroup_name); + const gchar *key = RVAL2CSTR(rbkey); + long n; + gdouble *list = RVAL2GDOUBLES(rblist, n); + + g_key_file_set_double_list(key_file, group_name, key, list, n); + + return self; +} + +static VALUE +rg_set_comment(VALUE self, VALUE group_name, VALUE key, VALUE comment) +{ + GError* error = NULL; + + g_key_file_set_comment(_SELF(self), + RVAL2CSTR(group_name), + RVAL2CSTR_ACCEPT_NIL(key), + RVAL2CSTR(comment), + &error); + if (error != NULL) + RAISE_GERROR(error); + + return self; +} + +static VALUE +rg_remove_group(VALUE self, VALUE group_name) +{ + GError* error = NULL; + + g_key_file_remove_group(_SELF(self), RVAL2CSTR(group_name), &error); + + if (error != NULL) + RAISE_GERROR(error); + + return self; +} + +static VALUE +rg_remove_key(VALUE self, VALUE group_name, VALUE key) +{ + GError* error = NULL; + + g_key_file_remove_key(_SELF(self), + RVAL2CSTR(group_name), + RVAL2CSTR(key), + &error); + + if (error != NULL) + RAISE_GERROR(error); + + return self; +} + +static VALUE +rg_remove_comment(VALUE self, VALUE group_name, VALUE key) +{ + GError* error = NULL; + + g_key_file_remove_comment(_SELF(self), + RVAL2CSTR(group_name), + RVAL2CSTR(key), + &error); + + if (error != NULL) + RAISE_GERROR(error); + + return self; +} + +void +Init_glib_keyfile(void) +{ + VALUE RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_KEY_FILE, "KeyFile", mGLib); + G_DEF_ERROR(G_KEY_FILE_ERROR, "KeyFileError", mGLib, + rb_eRuntimeError, G_TYPE_KEY_FILE_ERROR); + + RG_DEF_METHOD(initialize, 0); + RG_DEF_METHOD(set_list_separator, 1); + RG_DEF_METHOD(load_from_file, -1); + RG_DEF_METHOD(load_from_data, -1); + RG_DEF_METHOD(load_from_data_dirs, -1); +#if GLIB_CHECK_VERSION(2, 14, 0) + RG_DEF_METHOD(load_from_dirs, -1); +#endif + RG_DEF_METHOD(to_data, 0); + RG_DEF_METHOD(start_group, 0); + RG_DEF_METHOD(groups, 0); + RG_DEF_METHOD(get_keys, 1); + RG_DEF_METHOD_P(has_group, 1); + RG_DEF_METHOD_P(has_key, 2); + RG_DEF_METHOD(get_value, 2); + RG_DEF_METHOD(get_string, 2); + RG_DEF_METHOD(get_locale_string, -1); + RG_DEF_METHOD(get_boolean, 2); + RG_DEF_METHOD(get_integer, 2); + RG_DEF_METHOD(get_double, 2); + RG_DEF_METHOD(get_string_list, 2); + RG_DEF_METHOD(get_locale_string_list, -1); + RG_DEF_METHOD(get_boolean_list, 2); + RG_DEF_METHOD(get_integer_list, 2); + RG_DEF_METHOD(get_double_list, 2); + RG_DEF_METHOD(get_comment, 2); + RG_DEF_METHOD(set_value, 3); + RG_DEF_METHOD(set_string, 3); + RG_DEF_METHOD(set_locale_string, 4); + RG_DEF_METHOD(set_boolean, 3); + RG_DEF_METHOD(set_integer, 3); + RG_DEF_METHOD(set_double, 3); + RG_DEF_METHOD(set_string_list, 3); + RG_DEF_METHOD(set_locale_string_list, 4); + RG_DEF_METHOD(set_boolean_list, 3); + RG_DEF_METHOD(set_integer_list, 3); + RG_DEF_METHOD(set_double_list, 3); + RG_DEF_METHOD(set_comment, 3); + RG_DEF_METHOD(remove_group, 1); + RG_DEF_METHOD(remove_key, 2); + RG_DEF_METHOD(remove_comment, 2); + + /* GKeyFileFlags */ + G_DEF_CLASS(G_TYPE_KEY_FILE_FLAGS, "Flags", RG_TARGET_NAMESPACE); + G_DEF_CONSTANTS(RG_TARGET_NAMESPACE, G_TYPE_KEY_FILE_FLAGS, "G_KEY_FILE_"); + +#if GLIB_CHECK_VERSION(2, 14, 0) + /* Defines for handling freedesktop.org Desktop files */ + rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_GROUP", CSTR2RVAL(G_KEY_FILE_DESKTOP_GROUP)); + + rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_KEY_TYPE", + CSTR2RVAL(G_KEY_FILE_DESKTOP_KEY_TYPE)); + rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_KEY_VERSION", + CSTR2RVAL(G_KEY_FILE_DESKTOP_KEY_VERSION)); + rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_KEY_NAME", + CSTR2RVAL(G_KEY_FILE_DESKTOP_KEY_NAME)); + rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_KEY_GENERIC_NAME", + CSTR2RVAL(G_KEY_FILE_DESKTOP_KEY_GENERIC_NAME)); + rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_KEY_NO_DISPLAY", + CSTR2RVAL(G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY)); + rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_KEY_COMMENT", + CSTR2RVAL(G_KEY_FILE_DESKTOP_KEY_COMMENT)); + rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_KEY_ICON", + CSTR2RVAL(G_KEY_FILE_DESKTOP_KEY_ICON)); + rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_KEY_HIDDEN", + CSTR2RVAL(G_KEY_FILE_DESKTOP_KEY_HIDDEN)); + rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_KEY_ONLY_SHOW_IN", + CSTR2RVAL(G_KEY_FILE_DESKTOP_KEY_ONLY_SHOW_IN)); + rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_KEY_NOT_SHOW_IN", + CSTR2RVAL(G_KEY_FILE_DESKTOP_KEY_NOT_SHOW_IN)); + rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_KEY_TRY_EXEC", + CSTR2RVAL(G_KEY_FILE_DESKTOP_KEY_TRY_EXEC)); + rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_KEY_EXEC", + CSTR2RVAL(G_KEY_FILE_DESKTOP_KEY_EXEC)); + rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_KEY_PATH", + CSTR2RVAL(G_KEY_FILE_DESKTOP_KEY_PATH)); + rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_KEY_TERMINAL", + CSTR2RVAL(G_KEY_FILE_DESKTOP_KEY_TERMINAL)); + rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_KEY_MIME_TYPE", + CSTR2RVAL(G_KEY_FILE_DESKTOP_KEY_MIME_TYPE)); + rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_KEY_CATEGORIES", + CSTR2RVAL(G_KEY_FILE_DESKTOP_KEY_CATEGORIES)); + rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_KEY_STARTUP_NOTIFY", + CSTR2RVAL(G_KEY_FILE_DESKTOP_KEY_STARTUP_NOTIFY)); + rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_KEY_STARTUP_WM_CLASS", + CSTR2RVAL(G_KEY_FILE_DESKTOP_KEY_STARTUP_WM_CLASS)); + rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_KEY_URL", + CSTR2RVAL(G_KEY_FILE_DESKTOP_KEY_URL)); + + rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_TYPE_APPLICATION", + CSTR2RVAL(G_KEY_FILE_DESKTOP_TYPE_APPLICATION)); + rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_TYPE_LINK", + CSTR2RVAL(G_KEY_FILE_DESKTOP_TYPE_LINK)); + rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_TYPE_DIRECTORY", + CSTR2RVAL(G_KEY_FILE_DESKTOP_TYPE_DIRECTORY)); +#endif +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_maincontext.c (+595 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_maincontext.c 2017-02-15 13:19:47 +0900 (814563d) @@ -0,0 +1,595 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011-2014 Ruby-GNOME2 Project Team + * Copyright (C) 2005 Masao Mutoh + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" + +#ifdef HAVE_RUBY_THREAD_H +# include <ruby/thread.h> +#endif + +GStaticPrivate rg_polling_key = G_STATIC_PRIVATE_INIT; + +/* +static ID id_poll_func; +*/ +static ID id_call; + +static VALUE mGLibSource; +static ID id__callbacks__; +static GHashTable *callbacks_table; + +static GThread *main_thread; + +typedef struct _callback_info_t +{ + VALUE callback; + guint id; +} callback_info_t; + +/*****************************************/ +static GPollFunc default_poll_func; + +typedef struct _PollInfo +{ + GPollFD *ufds; + guint nfsd; + gint timeout; + gint result; +} PollInfo; + +static void +rg_poll_in_blocking_raw(PollInfo *info) +{ + info->result = default_poll_func(info->ufds, info->nfsd, info->timeout); +} + +#ifdef HAVE_RB_THREAD_CALL_WITHOUT_GVL +static void * +rg_poll_in_blocking(void *data) +{ + PollInfo *info = data; + rg_poll_in_blocking_raw(info); + return NULL; +} +#else +static VALUE +rg_poll_in_blocking(void *data) +{ + PollInfo *info = data; + rg_poll_in_blocking_raw(info); + return Qnil; +} +#endif + +static gint +rg_poll(GPollFD *ufds, guint nfsd, gint timeout) +{ + PollInfo info; + + info.ufds = ufds; + info.nfsd = nfsd; + info.timeout = timeout; + info.result = 0; + + g_static_private_set(&rg_polling_key, GINT_TO_POINTER(TRUE), NULL); + if (g_thread_self() == main_thread) { +#ifdef HAVE_RB_THREAD_CALL_WITHOUT_GVL + rb_thread_call_without_gvl(rg_poll_in_blocking, &info, + RUBY_UBF_IO, NULL); +#else + rb_thread_blocking_region(rg_poll_in_blocking, &info, + RUBY_UBF_IO, NULL); +#endif + } else { + rg_poll_in_blocking_raw(&info); + } + g_static_private_set(&rg_polling_key, GINT_TO_POINTER(FALSE), NULL); + + return info.result; +} + +static VALUE +ruby_source_set_priority (G_GNUC_UNUSED VALUE self, G_GNUC_UNUSED VALUE priority) +{ + return Qnil; +} + +static void +restore_poll_func(G_GNUC_UNUSED VALUE data) +{ + if (g_main_context_get_poll_func(NULL) == (GPollFunc)rg_poll) { + g_main_context_set_poll_func(NULL, default_poll_func); + } +} + +static VALUE +source_remove(G_GNUC_UNUSED VALUE self, VALUE tag) +{ + VALUE callback; + callback = G_GET_RELATIVE(mGLibSource, id__callbacks__, tag); + G_REMOVE_RELATIVE(mGLibSource, id__callbacks__, tag); + g_hash_table_remove(callbacks_table, (gpointer)callback); + return CBOOL2RVAL(g_source_remove(NUM2UINT(tag))); +} + +static VALUE +source_current_source(G_GNUC_UNUSED VALUE self) +{ + return BOXED2RVAL(g_main_current_source, G_TYPE_SOURCE); +} + +static gboolean +invoke_source_func(gpointer data) +{ + callback_info_t *info = (callback_info_t *)data; + gboolean ret; + + ret = RVAL2CBOOL(rb_funcall(info->callback, id_call, 0)); + if (!ret) + G_REMOVE_RELATIVE(mGLibSource, id__callbacks__, UINT2NUM(info->id)); + return ret; +} + +/*****************************************/ +#if !GLIB_CHECK_VERSION(2,30,0) +GType +g_main_context_get_type(void) +{ + static GType our_type = 0; + if (our_type == 0) + our_type = g_boxed_type_register_static ("GMainContext", + (GBoxedCopyFunc)g_main_context_ref, + (GBoxedFreeFunc)g_main_context_unref); + return our_type; +} +#endif +/*****************************************/ + +#define RG_TARGET_NAMESPACE cMainContext +#define _SELF(s) ((GMainContext*)RVAL2BOXED(s, G_TYPE_MAIN_CONTEXT)) + +static VALUE +rg_initialize(VALUE self) +{ + GMainContext *context; + + context = g_main_context_new(); + + g_main_context_set_poll_func(context, rg_poll); + + G_INITIALIZE(self, context); + return Qnil; +} + +static VALUE +rg_s_default(G_GNUC_UNUSED VALUE self) +{ + return BOXED2RVAL(g_main_context_default(), G_TYPE_MAIN_CONTEXT); +} + +static VALUE +rg_iteration(VALUE self, VALUE may_block) +{ + return CBOOL2RVAL(g_main_context_iteration(_SELF(self), RVAL2CBOOL(may_block))); +} + +static VALUE +rg_pending_p(VALUE self) +{ + return CBOOL2RVAL(g_main_context_pending(_SELF(self))); +} + +static VALUE +rg_find_source(VALUE self, VALUE source_id) +{ + GSource* src = g_main_context_find_source_by_id(_SELF(self), NUM2UINT(source_id)); + return BOXED2RVAL(src, G_TYPE_SOURCE); +} + +/* +GSource* g_main_context_find_source_by_user_data + (GMainContext *context, + gpointer user_data); +GSource* g_main_context_find_source_by_funcs_user_data + (GMainContext *context, + GSourceFuncs *funcs, + gpointer user_data); +*/ + +static VALUE +rg_wakeup(VALUE self) +{ + g_main_context_wakeup(_SELF(self)); + return self; +} + +static VALUE +rg_acquire(VALUE self) +{ + return CBOOL2RVAL(g_main_context_acquire(_SELF(self))); +} + +static VALUE +rg_release(VALUE self) +{ + g_main_context_release(_SELF(self)); + return self; +} + +static VALUE +rg_owner_p(VALUE self) +{ + return CBOOL2RVAL(g_main_context_is_owner(_SELF(self))); +} + +/* +gboolean g_main_context_wait (GMainContext *context, + GCond *cond, + GMutex *mutex); +*/ + +static VALUE +rg_prepare(VALUE self) +{ + gint priority; + gboolean ret = g_main_context_prepare(_SELF(self), &priority); + + return rb_assoc_new(CBOOL2RVAL(ret), INT2NUM(priority)); +} + +struct mc_query_body_args { + gint timeout_; + GPollFD *fds; + gint n_fds; +}; + +static VALUE +mc_query_body(VALUE value) +{ + struct mc_query_body_args *args = (struct mc_query_body_args *)value; + gint i; + VALUE ary = rb_ary_new(); + + for (i = 0; i < args->n_fds; i++) + rb_ary_push(ary, BOXED2RVAL(&args->fds[i], G_TYPE_POLL_FD)); + + return rb_assoc_new(INT2NUM(args->timeout_), ary); +} + +static VALUE +mc_query_ensure(VALUE value) +{ + g_free((GPollFD *)value); + + return Qnil; +} + +#define QUERY_DEFAULT_FDS 100 + +static VALUE +rg_query(VALUE self, VALUE rbmax_priority) +{ + GMainContext *context = _SELF(self); + gint max_priority = NUM2INT(rbmax_priority); + gint timeout_; + GPollFD *fds; + gint n_fds; + struct mc_query_body_args args; + + fds = g_new(GPollFD, QUERY_DEFAULT_FDS); + n_fds = g_main_context_query(context, max_priority, &timeout_, fds, QUERY_DEFAULT_FDS); + if (n_fds > QUERY_DEFAULT_FDS) { + g_free(fds); + fds = g_new(GPollFD, n_fds); + g_main_context_query(context, max_priority, &timeout_, fds, n_fds); + } + + args.timeout_ = timeout_; + args.fds = fds; + args.n_fds = n_fds; + return rb_ensure(mc_query_body, (VALUE)&args, + mc_query_ensure, (VALUE)fds); +} + +/* How can I implement this? +static VALUE +rg_check(VALUE self, VALUE max_priority) +{ + gint i, timeout_; + VALUE ary; + + GPollFD* fds; + gint ret, n_fds; + + fds = g_new (GPollFD, 10); + n_fds = g_main_context_query(_SELF(self), NUM2INT(max_priority), + &timeout_, fds, 10); + printf("n_fds = %d\n", n_fds); + + g_free(fds); + fds = g_new (GPollFD, n_fds); + + ret = g_main_context_check(_SELF(self), NUM2INT(max_priority), + fds, n_fds); + printf("ret = %d\n", ret); + ary = rb_ary_new(); + for (i = 0; i < ret; i++) + rb_ary_push(ary, BOXED2RVAL(&fds[i], G_TYPE_POLL_FD)); + + g_free(fds); + return ary; +} +*/ + +static VALUE +rg_dispatch(VALUE self) +{ + g_main_context_dispatch(_SELF(self)); + return self; +} + +/* How can I get "self" or something like it as key .... +static gint +poll_func(GPollFD *ufds, guint nfsd, gint timeout_) +{ + VALUE func = rb_ivar_get(self, id_poll_func); + if (NIL_P(func)) return -1; + + return INT2NUM(rb_funcall(func, 3, BOXED2RVAL(ufds, G_TYPE_POLL_FD), + UINT2NUM(nfsd), INT2NUM(timeout_))); +} + +static VALUE +rg_set_poll_func(VALUE self) +{ + rb_ivar_set(self, id_poll_func, rb_block_proc()); + g_main_context_set_poll_func(_SELF(self), (GPollFunc)poll_func); + + return self; +} +*/ + +/* +GPollFunc g_main_context_get_poll_func (GMainContext *context); +*/ + +static VALUE +rg_add_poll(VALUE self, VALUE fd, VALUE priority) +{ + g_main_context_add_poll(_SELF(self), RVAL2BOXED(fd, G_TYPE_POLL_FD), + NUM2INT(priority)); + return self; +} + +static VALUE +rg_remove_poll(VALUE self, VALUE fd) +{ + g_main_context_remove_poll(_SELF(self), RVAL2BOXED(fd, G_TYPE_POLL_FD)); + return self; +} + +#ifdef HAVE_G_MAIN_DEPTH +static VALUE +rg_s_depth(G_GNUC_UNUSED VALUE self) +{ + return INT2NUM(g_main_depth()); +} +#endif + +static VALUE +timeout_source_new(G_GNUC_UNUSED VALUE self, VALUE interval) +{ + return BOXED2RVAL(g_timeout_source_new(NUM2UINT(interval)), G_TYPE_SOURCE); +} +#if GLIB_CHECK_VERSION(2,14,0) +static VALUE +timeout_source_new_seconds(G_GNUC_UNUSED VALUE self, VALUE interval) +{ + return BOXED2RVAL(g_timeout_source_new_seconds(NUM2UINT(interval)), G_TYPE_SOURCE); +} +#endif + +static VALUE +timeout_add(int argc, VALUE *argv, G_GNUC_UNUSED VALUE self) +{ + VALUE interval, rb_priority, func, rb_id; + gint priority; + callback_info_t *info; + guint id; + + rb_scan_args(argc, argv, "11&", &interval, &rb_priority, &func); + + priority = NIL_P(rb_priority) ? G_PRIORITY_DEFAULT : NUM2INT(rb_priority); + info = ALLOC(callback_info_t); + info->callback = func; + id = g_timeout_add_full(priority, NUM2UINT(interval), + (GSourceFunc)invoke_source_func, + (gpointer)info, g_free); + info->id = id; + rb_id = UINT2NUM(id); + G_RELATIVE2(mGLibSource, func, id__callbacks__, rb_id); + g_hash_table_insert(callbacks_table, (gpointer)func, info); + return rb_id; +} + +#if GLIB_CHECK_VERSION(2,14,0) +static VALUE +timeout_add_seconds(int argc, VALUE *argv, G_GNUC_UNUSED VALUE self) +{ + VALUE interval, rb_priority, func, rb_id; + gint priority; + callback_info_t *info; + guint id; + + rb_scan_args(argc, argv, "11&", &interval, &rb_priority, &func); + + priority = NIL_P(rb_priority) ? G_PRIORITY_DEFAULT : NUM2INT(rb_priority); + info = ALLOC(callback_info_t); + info->callback = func; + id = g_timeout_add_seconds_full(priority, + NUM2UINT(interval), + (GSourceFunc)invoke_source_func, + (gpointer)info, + g_free); + info->id = id; + rb_id = UINT2NUM(id); + G_RELATIVE2(mGLibSource, func, id__callbacks__, rb_id); + g_hash_table_insert(callbacks_table, (gpointer)func, info); + return rb_id; +} +#endif + +static VALUE +idle_source_new(G_GNUC_UNUSED VALUE self) +{ + return BOXED2RVAL(g_idle_source_new(), G_TYPE_SOURCE); +} + +static VALUE +idle_add(gint argc, VALUE *argv, G_GNUC_UNUSED VALUE self) +{ + VALUE arg1, arg2, func, rb_id; + callback_info_t *info; + guint id; + gint priority = G_PRIORITY_DEFAULT_IDLE; + + rb_scan_args(argc, argv, "02", &arg1, &arg2); + + if (RVAL2CBOOL(rb_obj_is_kind_of(arg1, rb_cProc))) { + func = arg1; + } else if (RVAL2CBOOL(rb_obj_is_kind_of(arg1, rb_cInteger))) { + priority = NUM2INT(arg1); + func = rb_block_proc(); + } else { + func = rb_block_proc(); + } + + info = ALLOC(callback_info_t); + info->callback = func; + id = g_idle_add_full(priority, (GSourceFunc)invoke_source_func, + (gpointer)info, g_free); + info->id = id; + rb_id = UINT2NUM(id); + G_RELATIVE2(mGLibSource, func, id__callbacks__, rb_id); + g_hash_table_insert(callbacks_table, (gpointer)func, info); + return rb_id; +} + +static VALUE +idle_remove(G_GNUC_UNUSED VALUE self, VALUE func) +{ + callback_info_t *info; + + info = g_hash_table_lookup(callbacks_table, (gpointer)func); + G_REMOVE_RELATIVE(mGLibSource, id__callbacks__, UINT2NUM(info->id)); + g_hash_table_remove(callbacks_table, (gpointer)func); + return CBOOL2RVAL(g_idle_remove_by_data((gpointer)info)); +} + +static VALUE +child_watch_source_new(G_GNUC_UNUSED VALUE self, VALUE pid) +{ + return BOXED2RVAL(g_child_watch_source_new((GPid)NUM2INT(pid)), G_TYPE_SOURCE); +} + +static void +child_watch_func(GPid pid, gint status, gpointer func) +{ + rb_funcall((VALUE)func, id_call, 2, INT2NUM((long)pid), INT2NUM(status)); +} + +static VALUE +child_watch_add(VALUE self, VALUE pid) +{ + VALUE func = rb_block_proc(); + G_RELATIVE(self, func); + return UINT2NUM(g_child_watch_add((GPid)NUM2INT(pid), + (GChildWatchFunc)child_watch_func, (gpointer)func)); +} + +void +Init_glib_main_context(void) +{ + VALUE RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_MAIN_CONTEXT, "MainContext", mGLib); + + VALUE timeout = rb_define_module_under(mGLib, "Timeout"); + VALUE idle = rb_define_module_under(mGLib, "Idle"); + VALUE child_watch = rb_define_module_under(mGLib, "ChildWatch"); + + id_call = rb_intern("call"); + id__callbacks__ = rb_intern("__callbacks__"); + callbacks_table = g_hash_table_new(NULL, NULL); + + g_static_private_set(&rg_polling_key, GINT_TO_POINTER(FALSE), NULL); + + main_thread = g_thread_self(); + + rbg_define_singleton_method(mGLib, "set_ruby_thread_priority", + ruby_source_set_priority, 1); + + mGLibSource = rb_const_get(mGLib, rb_intern("Source")); + rbg_define_singleton_method(mGLibSource, "remove", source_remove, 1); + rbg_define_singleton_method(mGLibSource, "current", source_current_source, 0); +/* + id_poll_func = rb_intern("__poll_func__"); +*/ + RG_DEF_METHOD(initialize, 0); + RG_DEF_SMETHOD(default, 0); + RG_DEF_METHOD(iteration, 1); + RG_DEF_METHOD_P(pending, 0); + RG_DEF_METHOD(find_source, 1); + RG_DEF_METHOD(wakeup, 0); + RG_DEF_METHOD(acquire, 0); + RG_DEF_METHOD(release, 0); + RG_DEF_METHOD_P(owner, 0); + RG_DEF_METHOD(prepare, 0); + RG_DEF_METHOD(query, 1); +/* + RG_DEF_METHOD(check, 1); +*/ + RG_DEF_METHOD(dispatch, 0); +/* + RG_DEF_METHOD(set_poll_func, 0); +*/ + RG_DEF_METHOD(add_poll, 2); + RG_DEF_METHOD(remove_poll, 1); +#ifdef HAVE_G_MAIN_DEPTH + RG_DEF_SMETHOD(depth, 0); +#endif + rbg_define_singleton_method(timeout, "source_new", timeout_source_new, 1); +#if GLIB_CHECK_VERSION(2,14,0) + rbg_define_singleton_method(timeout, "source_new_seconds", timeout_source_new_seconds, 1); +#endif + rbg_define_singleton_method(timeout, "add", timeout_add, -1); +#if GLIB_CHECK_VERSION(2,14,0) + rbg_define_singleton_method(timeout, "add_seconds", timeout_add_seconds, -1); +#endif + rbg_define_singleton_method(idle, "source_new", idle_source_new, 0); + rbg_define_singleton_method(idle, "add", idle_add, -1); + rbg_define_singleton_method(idle, "remove", idle_remove, 1); + + rbg_define_singleton_method(child_watch, "source_new", child_watch_source_new, 1); + rbg_define_singleton_method(child_watch, "add", child_watch_add, 1); + + default_poll_func = g_main_context_get_poll_func(NULL); + g_main_context_set_poll_func(NULL, rg_poll); + rb_set_end_proc(restore_poll_func, Qnil); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_mainloop.c (+144 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_mainloop.c 2017-02-15 13:19:47 +0900 (74e3963) @@ -0,0 +1,144 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011-2014 Ruby-GNOME2 Project Team + * Copyright (C) 2005,2006 Masao Mutoh + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" + +/*****************************************/ +#if !GLIB_CHECK_VERSION(2,30,0) +GType +g_main_loop_get_type(void) +{ + static GType our_type = 0; + if (our_type == 0) + our_type = g_boxed_type_register_static ("GMainLoop", + (GBoxedCopyFunc)g_main_loop_ref, + (GBoxedFreeFunc)g_main_loop_unref); + return our_type; +} +#endif +/*****************************************/ + +#define RG_TARGET_NAMESPACE cMainLoop +#define _SELF(s) ((GMainLoop*)RVAL2BOXED(s, G_TYPE_MAIN_LOOP)) + +/*****************************************/ + +static VALUE +rg_initialize(int argc, VALUE *argv, VALUE self) +{ + VALUE context, is_running; + GMainLoop *loop; + GMainContext *main_context = NULL; + + rb_scan_args(argc, argv, "02", &context, &is_running); + + if (!NIL_P(context)) + main_context = RVAL2BOXED(context, G_TYPE_MAIN_CONTEXT); + loop = g_main_loop_new(main_context, RVAL2CBOOL(is_running)); + G_INITIALIZE(self, loop); + return Qnil; +} + +typedef struct { + GMainLoop *loop; + int state; +} CheckInterruptData; + +static VALUE +check_interrupt_raw(G_GNUC_UNUSED VALUE user_data) +{ + rb_thread_check_ints(); + return Qnil; +} + +static gboolean +check_interrupt(gpointer user_data) +{ + CheckInterruptData *data = user_data; + + rb_protect(check_interrupt_raw, Qnil, &(data->state)); + if (data->state == 0) { + return G_SOURCE_CONTINUE; + } else { + g_main_loop_quit(data->loop); + return G_SOURCE_REMOVE; + } +} + +static VALUE +rg_run(VALUE self) +{ + CheckInterruptData data; + GSource *interrupt_source; + + data.loop = _SELF(self); + data.state = 0; + + interrupt_source = rbg_interrupt_source_new(); + g_source_set_callback(interrupt_source, + check_interrupt, + &data, + NULL); + g_source_attach(interrupt_source, + g_main_loop_get_context(data.loop)); + g_main_loop_run(data.loop); + g_source_destroy(interrupt_source); + g_source_unref(interrupt_source); + + if (data.state == 0) { + rb_thread_check_ints(); + } else { + rb_jump_tag(data.state); + } + + return self; +} + +static VALUE +rg_quit(VALUE self) +{ + g_main_loop_quit(_SELF(self)); + return Qnil; +} + +static VALUE +rg_running_p(VALUE self) +{ + return CBOOL2RVAL(g_main_loop_is_running(_SELF(self))); +} + +static VALUE +rg_context(VALUE self) +{ + return BOXED2RVAL(g_main_loop_get_context(_SELF(self)), G_TYPE_MAIN_CONTEXT); +} + +void +Init_glib_main_loop(void) +{ + VALUE RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_MAIN_LOOP, "MainLoop", mGLib); + + RG_DEF_METHOD(initialize, -1); + RG_DEF_METHOD(run, 0); + RG_DEF_METHOD(quit, 0); + RG_DEF_METHOD_P(running, 0); + RG_DEF_METHOD(context, 0); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_matchinfo.c (+183 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_matchinfo.c 2017-02-15 13:19:47 +0900 (7b6e698) @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2015-2016 Ruby-GNOME2 Project Team + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" + +#define RG_TARGET_NAMESPACE cMatchInfo +#define _SELF(s) ((GMatchInfo*)RVAL2BOXED(s, G_TYPE_MATCH_INFO)) + +#if GLIB_CHECK_VERSION(2, 30, 0) +static VALUE +rg_regex(VALUE self) +{ + GRegex *regex; + regex = g_match_info_get_regex(_SELF(self)); + return BOXED2RVAL(regex, G_TYPE_REGEX); +} + +static VALUE +rg_string(VALUE self) +{ + return rb_iv_get(self, "@string"); +} + +static VALUE +rg_matches_p(VALUE self) +{ + return CBOOL2RVAL(g_match_info_matches(_SELF(self))); +} + +static VALUE +rg_match_count(VALUE self) +{ + return INT2NUM(g_match_info_get_match_count(_SELF(self))); +} + +static VALUE +rg_partial_match_p(VALUE self) +{ + return CBOOL2RVAL(g_match_info_is_partial_match(_SELF(self))); +} + +static VALUE +rg_fetch(VALUE self, VALUE rb_match_reference) +{ + gchar *match; + + switch (TYPE(rb_match_reference)) { + case RUBY_T_FIXNUM: + { + gint match_num; + match_num = NUM2INT(rb_match_reference); + match = g_match_info_fetch(_SELF(self), match_num); + } + break; + case RUBY_T_STRING: + case RUBY_T_SYMBOL: + { + const gchar *match_name; + match_name = RVAL2CSTR_ACCEPT_SYMBOL(rb_match_reference); + match = g_match_info_fetch_named(_SELF(self), match_name); + } + break; + default: + rb_raise(rb_eArgError, "Expected a String, a Symbol or an Integer"); + break; + } + + return CSTR2RVAL_FREE(match); +} + +static VALUE +rg_fetch_pos(VALUE self, VALUE rb_match_reference) +{ + gint start_pos = 0; + gint end_pos = 0; + gboolean fetched = FALSE; + + switch (TYPE(rb_match_reference)) { + case RUBY_T_FIXNUM: + { + gint match_num; + match_num = NUM2INT(rb_match_reference); + fetched = g_match_info_fetch_pos(_SELF(self), match_num, + &start_pos, &end_pos); + } + break; + case RUBY_T_STRING: + case RUBY_T_SYMBOL: + { + const gchar *match_name; + match_name = RVAL2CSTR_ACCEPT_SYMBOL(rb_match_reference); + fetched = g_match_info_fetch_named_pos(_SELF(self), match_name, + &start_pos, &end_pos); + } + break; + default: + rb_raise(rb_eArgError, "Expected a String, a Symbol or an Integer"); + break; + } + + if (!fetched) { + return Qnil; + } + + return rb_ary_new_from_args(2, INT2NUM(start_pos), INT2NUM(end_pos)); +} + +static VALUE +rg_fetch_all(VALUE self) +{ + gchar **strings; + strings = g_match_info_fetch_all(_SELF(self)); + return STRV2RVAL_FREE(strings); +} + +static VALUE +rg_next(VALUE self) +{ + gboolean matched; + GError *error = NULL; + + matched = g_match_info_next(_SELF(self), &error); + + if (error) + RAISE_GERROR(error); + + return CBOOL2RVAL(matched); +} + +static VALUE +rg_expand_references(VALUE self, VALUE rb_string) +{ + const gchar *string = RVAL2CSTR(rb_string); + gchar *expanded_string = NULL; + GError *error = NULL; + + expanded_string = g_match_info_expand_references(_SELF(self), + string, + &error); + if (error) + RAISE_GERROR(error); + + return CSTR2RVAL_FREE(expanded_string); +} +#endif + +void +Init_glib_matchinfo(void) +{ +#if GLIB_CHECK_VERSION(2, 30, 0) + VALUE RG_TARGET_NAMESPACE; + + RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_MATCH_INFO, "MatchInfo", mGLib); + RG_DEF_METHOD(regex, 0); + RG_DEF_METHOD(string, 0); + RG_DEF_METHOD_P(matches, 0); + RG_DEF_METHOD(match_count, 0); + RG_DEF_METHOD_P(partial_match, 0); + RG_DEF_METHOD(fetch, 1); + RG_DEF_ALIAS("[]", "fetch"); + RG_DEF_METHOD(fetch_pos, 1); + RG_DEF_ALIAS("fetch_position", "fetch_pos"); + RG_DEF_METHOD(fetch_all, 0); + RG_DEF_METHOD(next, 0); + RG_DEF_METHOD(expand_references, 1); +#endif +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_messages.c (+155 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_messages.c 2017-02-15 13:19:47 +0900 (8446c80) @@ -0,0 +1,155 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2002-2005 Masao Mutoh + * Copyright (C) 1998-2000 Yukihiro Matsumoto, + * Daisuke Kanda, + * Hiroshi Igarashi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" + +#define RG_TARGET_NAMESPACE mLog + +static VALUE rbglib_log_handler_procs; +static gboolean log_canceled; + +static const gchar * +logmessage(GLogLevelFlags level) +{ + if (level & G_LOG_LEVEL_ERROR){ + return "ERROR"; + } else if (level & G_LOG_LEVEL_CRITICAL){ + return "CRITICAL"; + } else if (level & G_LOG_LEVEL_WARNING){ + return "WARNING"; + } else if (level & G_LOG_LEVEL_MESSAGE){ + return "MESSAGE"; + } else if (level & G_LOG_LEVEL_INFO){ + return "INFO"; + } else if (level & G_LOG_LEVEL_DEBUG){ + return "DEBUG"; + } + return "UNKNOWN"; +} + +static VALUE +rbg_printerr(VALUE message, G_GNUC_UNUSED VALUE user_data) +{ + g_printerr("\tfrom %.*s\n", + (int)RSTRING_LEN(message), + RSTRING_PTR(message)); + return Qnil; +} + +static void +rbglib_log_handler(const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data) +{ + if (!log_canceled) { + g_printerr("%s-%s **: %s\n", + log_domain, logmessage(log_level), message); + if (rb_during_gc()) { + g_printerr("\tfrom %s:%d\n", rb_sourcefile(), rb_sourceline()); + } else { + VALUE backtrace; + + backtrace = rb_funcall(rb_mKernel, rb_intern("caller"), 0); + rb_iterate(rb_each, backtrace, + rbg_printerr, Qnil); + } + } else { + g_log_default_handler(log_domain, log_level, message, user_data); + } +} + +/* Use Internal only */ +static VALUE +rg_s_cancel_handler(G_GNUC_UNUSED VALUE self) +{ + log_canceled = TRUE; + return Qnil; +} + +static VALUE +rg_s_set_handler(VALUE self, VALUE domain, VALUE levels) +{ + guint handler_id = g_log_set_handler(RVAL2CSTR_ACCEPT_NIL(domain), + NUM2INT(levels), + (GLogFunc)rbglib_log_handler, (gpointer)self); + return UINT2NUM(handler_id); +} + +static VALUE +rg_s_remove_handler(VALUE self, VALUE domain, VALUE handler_id) +{ + g_log_remove_handler(RVAL2CSTR_ACCEPT_NIL(domain), + NUM2UINT(handler_id)); + G_REMOVE_RELATIVE(self, handler_id, rbglib_log_handler_procs); + return Qnil; +} + +static VALUE +rg_s_set_always_fatal(G_GNUC_UNUSED VALUE self, VALUE fatal_mask) +{ + return INT2NUM(g_log_set_always_fatal(NUM2INT(fatal_mask))); +} + +static VALUE +rg_s_set_fatal_mask(G_GNUC_UNUSED VALUE self, VALUE domain, VALUE fatal_mask) +{ + return INT2NUM(g_log_set_fatal_mask(RVAL2CSTR_ACCEPT_NIL(domain), + NUM2INT(fatal_mask))); +} + +static VALUE +rg_s_log(G_GNUC_UNUSED VALUE self, VALUE domain, VALUE level, VALUE str) +{ + g_log(RVAL2CSTR_ACCEPT_NIL(domain), NUM2INT(level), "%s", RVAL2CSTR(str)); + return Qnil; +} + +void +Init_glib_messages(void) +{ + VALUE RG_TARGET_NAMESPACE = rb_define_module_under(mGLib, "Log"); + + log_canceled = FALSE; + + rb_global_variable(&rbglib_log_handler_procs); + rbglib_log_handler_procs = rb_hash_new(); + RG_DEF_SMETHOD(set_handler, 2); + RG_DEF_SMETHOD(remove_handler, 2); + RG_DEF_SMETHOD(cancel_handler, 0); + RG_DEF_SMETHOD(set_always_fatal, 1); + RG_DEF_SMETHOD(set_fatal_mask, 2); + RG_DEF_SMETHOD(log, 3); + + rb_define_const(RG_TARGET_NAMESPACE, "FATAL_MASK", INT2NUM(G_LOG_FATAL_MASK)); + rb_define_const(RG_TARGET_NAMESPACE, "LEVEL_USER_SHIFT", INT2NUM(G_LOG_LEVEL_USER_SHIFT)); + + /* GLogLevelFlags */ + rb_define_const(RG_TARGET_NAMESPACE, "FLAG_RECURSION", INT2NUM(G_LOG_FLAG_RECURSION)); + rb_define_const(RG_TARGET_NAMESPACE, "FLAG_FATAL", INT2NUM(G_LOG_FLAG_FATAL)); + rb_define_const(RG_TARGET_NAMESPACE, "LEVEL_ERROR", INT2NUM(G_LOG_LEVEL_ERROR)); + rb_define_const(RG_TARGET_NAMESPACE, "LEVEL_CRITICAL", INT2NUM(G_LOG_LEVEL_CRITICAL)); + rb_define_const(RG_TARGET_NAMESPACE, "LEVEL_WARNING", INT2NUM(G_LOG_LEVEL_WARNING)); + rb_define_const(RG_TARGET_NAMESPACE, "LEVEL_MESSAGE", INT2NUM(G_LOG_LEVEL_MESSAGE)); + rb_define_const(RG_TARGET_NAMESPACE, "LEVEL_INFO", INT2NUM(G_LOG_LEVEL_INFO)); + rb_define_const(RG_TARGET_NAMESPACE, "LEVEL_DEBUG", INT2NUM(G_LOG_LEVEL_DEBUG)); + rb_define_const(RG_TARGET_NAMESPACE, "LEVEL_MASK", INT2NUM(G_LOG_LEVEL_MASK)); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_pollfd.c (+112 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_pollfd.c 2017-02-15 13:19:47 +0900 (7ca1c71) @@ -0,0 +1,112 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2005 Masao Mutoh + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" + +/*****************************************/ +static GPollFD* +pollfd_copy(const GPollFD* pollfd) +{ + GPollFD* new_pollfd; + g_return_val_if_fail (pollfd != NULL, NULL); + + new_pollfd = g_new(GPollFD, 1); + *new_pollfd = *pollfd; + return new_pollfd; +} + +GType +g_poll_fd_get_type(void) +{ + static GType our_type = 0; + if (our_type == 0) + our_type = g_boxed_type_register_static ("GPollFD", + (GBoxedCopyFunc)pollfd_copy, + (GBoxedFreeFunc)g_free); + return our_type; +} +/*****************************************/ + +#define RG_TARGET_NAMESPACE cPollFD +#define _SELF(s) ((GPollFD*)RVAL2BOXED(s, G_TYPE_POLL_FD)) + +static VALUE +rg_initialize(VALUE self, VALUE fd, VALUE events, VALUE revents) +{ + GPollFD gfd; + gfd.fd = NUM2INT(fd); + gfd.events = NUM2INT(events); + gfd.revents = NUM2INT(revents); + + G_INITIALIZE(self, g_boxed_copy(G_TYPE_POLL_FD, &gfd)); + return Qnil; +} + +static VALUE +rg_set_fd(VALUE self, VALUE fd) +{ + _SELF(self)->fd = fd; + return self; +} +static VALUE +rg_fd(VALUE self) +{ + return INT2NUM(_SELF(self)->fd); +} + +static VALUE +rg_set_events(VALUE self, VALUE events) +{ + _SELF(self)->events = events; + return self; +} +static VALUE +rg_events(VALUE self) +{ + return INT2NUM(_SELF(self)->events); +} + +static VALUE +rg_set_revents(VALUE self, VALUE revents) +{ + _SELF(self)->revents = revents; + return self; +} +static VALUE +rg_revents(VALUE self) +{ + return INT2NUM(_SELF(self)->revents); +} + +void +Init_glib_poll_fd(void) +{ + VALUE RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_POLL_FD, "PollFD", mGLib); + + RG_DEF_METHOD(initialize, 3); + + RG_DEF_METHOD(set_fd, 1); + RG_DEF_METHOD(fd, 0); + RG_DEF_METHOD(set_events, 1); + RG_DEF_METHOD(events, 0); + RG_DEF_METHOD(set_revents, 1); + RG_DEF_METHOD(revents, 0); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_regex.c (+495 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_regex.c 2017-02-15 13:19:47 +0900 (05ceec3) @@ -0,0 +1,495 @@ +/* + * Copyright (C) 2015-2016 Ruby-GNOME2 Project Team + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" + +/* They MRI are internal definitions. Using them reduces + * maintainability. We should reconsider about using them when they + * are changed in MRI. */ +/* from vm_core.h */ +#define RUBY_TAG_BREAK 0x2 + +/* from internal.h */ +struct vm_throw_data { + VALUE flags; + VALUE reserved; + const VALUE throw_obj; + /* const struct rb_control_frame_struct *catch_frame; */ + /* VALUE throw_state; */ +}; +/* from vm_insnhelper.h */ +#define THROW_DATA_VAL(obj) (((struct vm_throw_data *)(obj))->throw_obj) + + +#define RG_TARGET_NAMESPACE cRegex +#define _SELF(s) ((GRegex*)RVAL2BOXED(s, G_TYPE_REGEX)) + +static VALUE +rg_initialize(gint argc, VALUE *argv, VALUE self) +{ + GError *error = NULL; + GRegex *regex = NULL; + + VALUE rb_pattern, rb_compile_options, rb_match_options; + VALUE rb_options; + const char *pattern; + GRegexCompileFlags compile_options = 0; + GRegexMatchFlags match_options = 0; + + rb_scan_args(argc, argv, "11", &rb_pattern, &rb_options); + rbg_scan_options(rb_options, + "compile_options", &rb_compile_options, + "match_options", &rb_match_options, + NULL); + + pattern = RVAL2CSTR(rb_pattern); + if (!NIL_P(rb_compile_options)) + compile_options = RVAL2GREGEXCOMPILEOPTIONSFLAGS(rb_compile_options); + if (!NIL_P(rb_match_options)) + match_options = RVAL2GREGEXMATCHOPTIONSFLAGS(rb_match_options); + + regex = g_regex_new(pattern, + compile_options, + match_options, + &error); + if (error) + RAISE_GERROR(error); + + G_INITIALIZE(self, regex); + return Qnil; +} + +static VALUE +rg_pattern(VALUE self) +{ + return CSTR2RVAL(g_regex_get_pattern(_SELF(self))); +} + +static VALUE +rg_compile_flags(VALUE self) +{ + return UINT2NUM(g_regex_get_compile_flags(_SELF(self))); +} + +static VALUE +rg_match_flags(VALUE self) +{ + return UINT2NUM(g_regex_get_match_flags(_SELF(self))); +} + +static VALUE +rg_split(gint argc, VALUE *argv, VALUE self) +{ + VALUE rb_string, rb_start_position, rb_match_options, rb_max_tokens, rb_options; + GError *error = NULL; + gchar **strings; + const gchar *string; + gssize string_len = -1; + gint start_position = 0; + GRegexMatchFlags match_options = 0; + gint max_tokens = 0; + + rb_scan_args(argc, argv, "11", &rb_string, &rb_options); + + rbg_scan_options(rb_options, + "start_position", &rb_start_position, + "match_options", &rb_match_options, + "max_tokens", &rb_max_tokens, + NULL); + string = RVAL2CSTR(rb_string); + string_len = RSTRING_LEN(rb_string); + + if (!NIL_P(rb_start_position)) + start_position = NUM2INT(rb_start_position); + if (!NIL_P(rb_match_options)) + match_options = RVAL2GREGEXMATCHOPTIONSFLAGS(rb_match_options); + if (!NIL_P(rb_max_tokens)) + max_tokens = NUM2INT(rb_max_tokens); + + strings = g_regex_split_full(_SELF(self), + string, + string_len, + start_position, + match_options, + max_tokens, + &error); + + if (error) + RAISE_GERROR(error); + + return STRV2RVAL_FREE(strings); +} + +#if GLIB_CHECK_VERSION(2, 30, 0) +static VALUE +rg_match(gint argc, VALUE *argv, VALUE self) +{ + VALUE rb_string, rb_start_position, rb_match_options, rb_options; + VALUE rb_frozen_string, rb_match_info; + GMatchInfo *match_info = NULL; + GError *error = NULL; + const gchar *string; + gssize string_len = -1; + gint start_position = 0; + GRegexMatchFlags match_options = 0; + + rb_scan_args(argc, argv, "11", &rb_string, &rb_options); + + rbg_scan_options(rb_options, + "start_position", &rb_start_position, + "match_options", &rb_match_options, + NULL); + + if (OBJ_FROZEN(rb_string)) { + rb_frozen_string = rb_string; + } else { + rb_frozen_string = rb_str_dup(rb_string); + rb_str_freeze(rb_frozen_string); + } + + string = RVAL2CSTR(rb_frozen_string); + string_len = RSTRING_LEN(rb_frozen_string); + + + if (!NIL_P(rb_start_position)) + start_position = NUM2INT(rb_start_position); + if (!NIL_P(rb_match_options)) + match_options = RVAL2GREGEXMATCHOPTIONSFLAGS(rb_match_options); + + g_regex_match_full(_SELF(self), + string, + string_len, + start_position, + match_options, + &match_info, + &error); + + if (error) + RAISE_GERROR(error); + + if (!match_info) + return Qnil; + + rb_match_info = GMATCHINFO2RVAL(match_info); + g_match_info_unref(match_info); + rb_iv_set(rb_match_info, "@string", rb_frozen_string); + return rb_match_info; +} +#endif + +static VALUE +rg_max_backref(VALUE self) +{ + return INT2NUM(g_regex_get_max_backref(_SELF(self))); +} + +static VALUE +rg_capture_count(VALUE self) +{ + return INT2NUM(g_regex_get_capture_count(_SELF(self))); +} + +#if GLIB_CHECK_VERSION(2, 34, 0) +static VALUE +rg_has_cr_or_lf_p(VALUE self) +{ + return CBOOL2RVAL(g_regex_get_has_cr_or_lf(_SELF(self))); +} + +static VALUE +rg_max_lookbehind(VALUE self) +{ + return INT2NUM(g_regex_get_max_lookbehind(_SELF(self))); +} +#endif + +static VALUE +rg_string_number(VALUE self, VALUE string) +{ + return INT2NUM(g_regex_get_string_number(_SELF(self), RVAL2CSTR(string))); +} + +#if GLIB_CHECK_VERSION(2, 30, 0) +static VALUE +rg_match_all(gint argc, VALUE *argv, VALUE self) +{ + VALUE rb_string, rb_start_position, rb_match_options, rb_options; + VALUE rb_frozen_string, rb_match_info; + GMatchInfo *match_info = NULL; + GError *error = NULL; + const gchar *string; + gssize string_len = -1; + gint start_position = 0; + GRegexMatchFlags match_options = 0; + + rb_scan_args(argc, argv, "11", &rb_string, &rb_options); + + rbg_scan_options(rb_options, + "start_position", &rb_start_position, + "match_options", &rb_match_options, + NULL); + + if (OBJ_FROZEN(rb_string)) { + rb_frozen_string = rb_string; + } else { + rb_frozen_string = rb_str_dup(rb_string); + rb_str_freeze(rb_frozen_string); + } + + string = RVAL2CSTR(rb_frozen_string); + string_len = RSTRING_LEN(rb_frozen_string); + + + if (!NIL_P(rb_start_position)) + start_position = NUM2INT(rb_start_position); + if (!NIL_P(rb_match_options)) + match_options = RVAL2GREGEXMATCHOPTIONSFLAGS(rb_match_options); + + g_regex_match_all_full(_SELF(self), + string, + string_len, + start_position, + match_options, + &match_info, + &error); + + if (error) + RAISE_GERROR(error); + + if (!match_info) + return Qnil; + + rb_match_info = GMATCHINFO2RVAL(match_info); + g_match_info_unref(match_info); + rb_iv_set(rb_match_info, "@string", rb_frozen_string); + return rb_match_info; +} + +typedef struct { + VALUE callback; + const GMatchInfo *match_info; + int status; +} RGRegexEvalCallbackData; + +static VALUE +rg_regex_eval_callback_body(VALUE user_data) +{ + RGRegexEvalCallbackData *data = (RGRegexEvalCallbackData *)user_data; + VALUE rb_match_info; + + rb_match_info = BOXED2RVAL((GMatchInfo *)(data->match_info), + G_TYPE_MATCH_INFO); + + return rb_funcall(data->callback, rb_intern("call"), 1, rb_match_info); +} + +static gboolean +rg_regex_eval_callback(const GMatchInfo *match_info, + GString *result, + gpointer user_data) +{ + VALUE returned_data; + RGRegexEvalCallbackData *data = user_data; + + data->match_info = match_info; + returned_data = rb_protect(rg_regex_eval_callback_body, + (VALUE)data, + &(data->status)); + + if (data->status == RUBY_TAG_BREAK) { + returned_data = THROW_DATA_VAL(rb_errinfo()); + } + + if (NIL_P(returned_data)) { + gchar *matched; + matched = g_match_info_fetch(match_info, 0); + g_string_append(result, matched); + g_free(matched); + } else { + g_string_append(result, RVAL2CSTR(returned_data)); + } + + return data->status != 0; +} + +static VALUE +rg_replace(gint argc, VALUE *argv, VALUE self) +{ + VALUE rb_string; + VALUE rb_replacement; + VALUE rb_options; + VALUE rb_start_position; + VALUE rb_match_options; + VALUE rb_literal; + GError *error = NULL; + gchar *modified_string; + const gchar *string; + const gchar *replacement; + gssize string_len = -1; + gint start_position = 0; + GRegexMatchFlags match_options = 0; + + + if (rb_block_given_p()) { + RGRegexEvalCallbackData data; + + rb_scan_args(argc, argv, "11", &rb_string, &rb_options); + rbg_scan_options(rb_options, + "start_position", &rb_start_position, + "match_options", &rb_match_options, + NULL); + + string = RVAL2CSTR(rb_string); + string_len = RSTRING_LEN(rb_string); + + if (!NIL_P(rb_start_position)) + start_position = NUM2INT(rb_start_position); + if (!NIL_P(rb_match_options)) + match_options = RVAL2GREGEXMATCHOPTIONSFLAGS(rb_match_options); + + data.callback = rb_block_proc(); + data.status = 0; + + modified_string = g_regex_replace_eval(_SELF(self), + string, + string_len, + start_position, + match_options, + rg_regex_eval_callback, + &data, + &error); + if (!(data.status == 0 || data.status == RUBY_TAG_BREAK)) { + if (error) + g_error_free(error); + g_free(modified_string); + rb_jump_tag(data.status); + } + } else { + rb_scan_args(argc, argv, "21", &rb_string, &rb_replacement, &rb_options); + + rbg_scan_options(rb_options, + "start_position", &rb_start_position, + "match_options", &rb_match_options, + "literal", &rb_literal, + NULL); + + string = RVAL2CSTR(rb_string); + string_len = RSTRING_LEN(rb_string); + replacement = RVAL2CSTR(rb_replacement); + + if (!NIL_P(rb_start_position)) + start_position = NUM2INT(rb_start_position); + if (!NIL_P(rb_match_options)) + match_options = RVAL2GREGEXMATCHOPTIONSFLAGS(rb_match_options); + + if (RVAL2CBOOL(rb_literal)) { + modified_string = g_regex_replace_literal(_SELF(self), + string, + string_len, + start_position, + replacement, + match_options, + &error); + + } else { + modified_string = g_regex_replace(_SELF(self), + string, + string_len, + start_position, + replacement, + match_options, + &error); + } + } + + if (error) + RAISE_GERROR(error); + + return CSTR2RVAL_FREE(modified_string); +} +#endif + +static VALUE +rg_s_escape_string(G_GNUC_UNUSED VALUE self, VALUE string) +{ + return CSTR2RVAL(g_regex_escape_string(RVAL2CSTR(string), RSTRING_LEN(string))); +} + +static VALUE +rg_s_check_replacement(G_GNUC_UNUSED VALUE self, VALUE rb_replacement) +{ + const gchar *replacement; + GError *error = NULL; + + replacement = RVAL2CSTR(rb_replacement); + g_regex_check_replacement(replacement, NULL, &error); + if (error) + RAISE_GERROR(error); + + return Qtrue; +} + +static VALUE +rg_s_have_reference_p(G_GNUC_UNUSED VALUE self, VALUE rb_replacement) +{ + const gchar *replacement; + gboolean has_references; + GError *error = NULL; + + replacement = RVAL2CSTR(rb_replacement); + g_regex_check_replacement(replacement, &has_references, &error); + + if (error) + RAISE_GERROR(error); + + return CBOOL2RVAL(has_references); +} + +void +Init_glib_regex(void) +{ + VALUE RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_REGEX, "Regex", mGLib); + + RG_DEF_METHOD(initialize, -1); + RG_DEF_METHOD(pattern, 0); + RG_DEF_METHOD(compile_flags, 0); + RG_DEF_METHOD(match_flags, 0); + RG_DEF_METHOD(split, -1); +#if GLIB_CHECK_VERSION(2, 30, 0) + RG_DEF_METHOD(match, -1); +#endif + RG_DEF_METHOD(max_backref, 0); + RG_DEF_METHOD(capture_count, 0); +#if GLIB_CHECK_VERSION(2, 34, 0) + RG_DEF_METHOD_P(has_cr_or_lf, 0); + RG_DEF_METHOD(max_lookbehind, 0); +#endif + RG_DEF_METHOD(string_number, 1); +#if GLIB_CHECK_VERSION(2, 30, 0) + RG_DEF_METHOD(match_all, -1); + RG_DEF_METHOD(replace, -1); +#endif + + RG_DEF_SMETHOD(escape_string, 1); + RG_DEF_SMETHOD(check_replacement, 1); + RG_DEF_SMETHOD_P(have_reference, 1); + + G_DEF_CLASS(G_TYPE_REGEX_MATCH_FLAGS, "RegexMatchFlags", mGLib); + G_DEF_CLASS(G_TYPE_REGEX_COMPILE_FLAGS, "RegexCompileFlags", mGLib); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_shell.c (+64 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_shell.c 2017-02-15 13:19:47 +0900 (7a38a55) @@ -0,0 +1,64 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2005 Masao Mutoh + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" + +#define RG_TARGET_NAMESPACE mShell + +static VALUE +rg_s_parse(G_GNUC_UNUSED VALUE self, VALUE command_line) +{ + gint argc; + gchar **argv; + GError *error = NULL; + + if (!g_shell_parse_argv(RVAL2CSTR(command_line), &argc, &argv, &error)) + RAISE_GERROR(error); + + return STRV2RVAL_FREE(argv); +} + +static VALUE +rg_s_quote(G_GNUC_UNUSED VALUE self, VALUE unquoted_string) +{ + return CSTR2RVAL_FREE(g_shell_quote(RVAL2CSTR(unquoted_string))); +} + +static VALUE +rg_s_unquote(G_GNUC_UNUSED VALUE self, VALUE quoted_string) +{ + GError *error = NULL; + gchar *str = g_shell_unquote(RVAL2CSTR(quoted_string), &error); + if (str == NULL) + RAISE_GERROR(error); + + return CSTR2RVAL_FREE(str); +} + +void +Init_glib_shell(void) +{ + VALUE RG_TARGET_NAMESPACE = rb_define_module_under(mGLib, "Shell"); + + RG_DEF_SMETHOD(parse, 1); + RG_DEF_SMETHOD(quote, 1); + RG_DEF_SMETHOD(unquote, 1); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_shellerror.c (+34 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_shellerror.c 2017-02-15 13:19:47 +0900 (e22a413) @@ -0,0 +1,34 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2005 Masao Mutoh + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" + +#define RG_TARGET_NAMESPACE cShellError + +void +Init_glib_shellerror(void) +{ + VALUE RG_TARGET_NAMESPACE = G_DEF_ERROR2(G_SHELL_ERROR, "ShellError", mGLib, rb_eRuntimeError); + + rb_define_const(RG_TARGET_NAMESPACE, "BAD_QUOTING", INT2FIX(G_SHELL_ERROR_BAD_QUOTING)); + rb_define_const(RG_TARGET_NAMESPACE, "EMPTY_STRING", INT2FIX(G_SHELL_ERROR_EMPTY_STRING)); + rb_define_const(RG_TARGET_NAMESPACE, "FAILED", INT2FIX(G_SHELL_ERROR_FAILED)); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_source.c (+242 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_source.c 2017-02-15 13:19:47 +0900 (c42a5d5) @@ -0,0 +1,242 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011-2013 Ruby-GNOME2 Project Team + * Copyright (C) 2005 Masao Mutoh + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" + +static ID id_call; + +/*****************************************/ +#if !GLIB_CHECK_VERSION(2,30,0) +static void +source_free(GSource *source) +{ + g_source_unref(source); + g_source_destroy(source); +} + +GType +g_source_get_type(void) +{ + static GType our_type = 0; + if (our_type == 0) + our_type = g_boxed_type_register_static ("GSource", + (GBoxedCopyFunc)g_source_ref, + (GBoxedFreeFunc)source_free); + return our_type; +} +#endif +/*****************************************/ + +#define RG_TARGET_NAMESPACE cSource +#define _SELF(s) ((GSource*)RVAL2BOXED(s, G_TYPE_SOURCE)) + +/* +GSource* g_source_new (GSourceFuncs *source_funcs, + guint struct_size); +*/ + +static VALUE +rg_attach(int argc, VALUE *argv, VALUE self) +{ + VALUE context; + + rb_scan_args(argc, argv, "01", &context); + return UINT2NUM(g_source_attach(_SELF(self), + RVAL2BOXED(context, G_TYPE_MAIN_CONTEXT))); +} + +static VALUE +rg_destroy(VALUE self) +{ + g_source_destroy(_SELF(self)); + return self; +} + +static VALUE +rg_destroyed_p(VALUE self) +{ + return CBOOL2RVAL(g_source_is_destroyed(_SELF(self))); +} + +static VALUE +rg_set_priority(VALUE self, VALUE priority) +{ + g_source_set_priority(_SELF(self), NUM2INT(priority)); + return self; +} + +static VALUE +rg_priority(VALUE self) +{ + return INT2NUM(g_source_get_priority(_SELF(self))); +} + +static VALUE +rg_set_can_recurse(VALUE self, VALUE can_recurse) +{ + g_source_set_can_recurse(_SELF(self), RVAL2CBOOL(can_recurse)); + return self; +} + +static VALUE +rg_can_recurse_p(VALUE self) +{ + return CBOOL2RVAL(g_source_get_can_recurse(_SELF(self))); +} + +static VALUE +rg_id(VALUE self) +{ + return UINT2NUM(g_source_get_id(_SELF(self))); +} + +#if GLIB_CHECK_VERSION(2, 26, 0) +static VALUE +rg_name(VALUE self) +{ + return CSTR2RVAL(g_source_get_name(_SELF(self))); +} + +static VALUE +rg_set_name(VALUE self, VALUE name) +{ + g_source_set_name(_SELF(self), RVAL2CSTR(name)); + return self; +} +#endif + +static VALUE +rg_context(VALUE self) +{ + GMainContext* context = g_source_get_context(_SELF(self)); + return BOXED2RVAL(context, G_TYPE_MAIN_CONTEXT); +} + +static gboolean +source_func(gpointer func) +{ + return RVAL2CBOOL(rb_funcall((VALUE)func, id_call, 0)); +} + +static VALUE +rg_set_callback(VALUE self) +{ + VALUE func = rb_block_proc(); + G_RELATIVE(self, func); + g_source_set_callback(_SELF(self), + (GSourceFunc)source_func, + (gpointer)func, + (GDestroyNotify)NULL); + return self; +} + +/* +void g_source_set_callback_indirect (GSource *source, + gpointer callback_data, + GSourceCallbackFuncs *callback_funcs); +*/ + +#if GLIB_CHECK_VERSION(2, 36, 0) +static VALUE +rg_ready_time(VALUE self) +{ + gint64 ready_time; + ready_time = g_source_get_ready_time(_SELF(self)); + return LL2NUM(ready_time); +} + +static VALUE +rg_set_ready_time(VALUE self, VALUE ready_time) +{ + g_source_set_ready_time(_SELF(self), NUM2LL(ready_time)); + return self; +} +#endif + +static VALUE +rg_add_poll(VALUE self, VALUE fd) +{ + g_source_add_poll(_SELF(self), RVAL2BOXED(fd, G_TYPE_POLL_FD)); + return self; +} + +static VALUE +rg_remove_poll(VALUE self, VALUE fd) +{ + g_source_remove_poll(_SELF(self), RVAL2BOXED(fd, G_TYPE_POLL_FD)); + return self; +} + +#if GLIB_CHECK_VERSION(2, 28, 0) +static VALUE +rg_time(VALUE self) +{ + gint64 time; + time = g_source_get_time(_SELF(self)); + return LL2NUM(time); +} +#endif + +/* How can I implement them ? +gboolean g_source_remove_by_funcs_user_data + (GSourceFuncs *funcs, + gpointer user_data); +gboolean g_source_remove_by_user_data (gpointer user_data); +*/ + +void +Init_glib_source(void) +{ + VALUE RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_SOURCE, "Source", mGLib); + + id_call = rb_intern("call"); + + rb_define_const(RG_TARGET_NAMESPACE, + "REMOVE", CBOOL2RVAL(G_SOURCE_REMOVE)); + rb_define_const(RG_TARGET_NAMESPACE, + "CONTINUE", CBOOL2RVAL(G_SOURCE_CONTINUE)); + + RG_DEF_METHOD(attach, -1); + RG_DEF_METHOD(destroy, 0); + RG_DEF_METHOD_P(destroyed, 0); + RG_DEF_METHOD(set_priority, 1); + RG_DEF_METHOD(priority, 0); + RG_DEF_METHOD(set_can_recurse, 1); + RG_DEF_METHOD_P(can_recurse, 0); + RG_DEF_METHOD(id, 0); +#if GLIB_CHECK_VERSION(2, 26, 0) + RG_DEF_METHOD(name, 0); + RG_REPLACE_SET_PROPERTY(name, 1); +#endif + RG_DEF_METHOD(context, 0); + RG_DEF_METHOD(set_callback, 0); +#if GLIB_CHECK_VERSION(2, 36, 0) + RG_DEF_METHOD(ready_time, 0); + RG_REPLACE_SET_PROPERTY(ready_time, 1); +#endif + RG_DEF_METHOD(add_poll, 1); + RG_DEF_METHOD(remove_poll, 1); +#if GLIB_CHECK_VERSION(2, 28, 0) + RG_DEF_METHOD(time, 0); +#endif + + /* GLib::Source.remove is moved to rbglib_maincontext.c */ +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_spawn.c (+245 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_spawn.c 2017-02-15 13:19:47 +0900 (1911780) @@ -0,0 +1,245 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2004 Masao Mutoh + * Copyright (C) 2004 Kazuhiro NISHIYAMA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" +#include "rbglib.h" + +#define RG_TARGET_NAMESPACE mSpawn + +static ID id_call; +static ID id_new; + +static void +child_setup(gpointer func) +{ + if (! NIL_P(func)){ + rb_funcall((VALUE)func, id_call, 0); + } +} + +static VALUE +rg_s_async_with_pipes(VALUE self, VALUE working_directory, VALUE argv, VALUE envp, VALUE flags) +{ + GError *err = NULL; + gboolean ret; + GPid child_pid; + VALUE func = Qnil; + gchar **gargv; + gchar **genvp; + gint standard_input, standard_output, standard_error; + + if (rb_block_given_p()) { + func = rb_block_proc(); + G_RELATIVE(self, func); + } + + gargv = (gchar **)RVAL2STRV(argv); + genvp = (gchar **)RVAL2STRV_ACCEPT_NIL(envp); + ret = g_spawn_async_with_pipes(RVAL2CSTR_ACCEPT_NIL(working_directory), + gargv, genvp, NUM2INT(flags), + (GSpawnChildSetupFunc)child_setup, + (gpointer)func, + &child_pid, + &standard_input, &standard_output, + &standard_error, &err); + g_free(gargv); + g_free(genvp); + if (!ret) + RAISE_GERROR(err); + + return rb_ary_new3(4, INT2NUM((gint)child_pid), + rb_funcall(rb_cIO, id_new, 1, INT2NUM(standard_input)), + rb_funcall(rb_cIO, id_new, 1, INT2NUM(standard_output)), + rb_funcall(rb_cIO, id_new, 1, INT2NUM(standard_error))); +} + +static VALUE +rg_s_async(VALUE self, VALUE working_directory, VALUE argv, VALUE envp, VALUE flags) +{ + GError *err = NULL; + gboolean ret; + GPid child_pid; + VALUE func = Qnil; + gchar **gargv; + gchar **genvp; + + if (rb_block_given_p()) { + func = rb_block_proc(); + G_RELATIVE(self, func); + } + + gargv = (gchar **)RVAL2STRV(argv); + genvp = (gchar **)RVAL2STRV_ACCEPT_NIL(envp); + ret = g_spawn_async(RVAL2CSTR_ACCEPT_NIL(working_directory), + gargv, genvp, NUM2INT(flags), + (GSpawnChildSetupFunc)child_setup, (gpointer)func, + &child_pid, &err); + g_free(gargv); + g_free(genvp); + if (!ret) + RAISE_GERROR(err); + + return INT2NUM((int)child_pid); +} + +static VALUE +rg_s_sync(VALUE self, VALUE working_directory, VALUE argv, VALUE envp, VALUE flags) +{ + GError *err = NULL; + gboolean ret; + VALUE func = Qnil; + gchar** gargv; + gchar** genvp; + gchar *standard_output = NULL, *standard_error = NULL; + gint exit_status; + VALUE std_out, std_err; + + if (rb_block_given_p()) { + func = rb_block_proc(); + G_RELATIVE(self, func); + } + + gargv = (gchar **)RVAL2STRV(argv); + genvp = (gchar **)RVAL2STRV_ACCEPT_NIL(envp); + ret = g_spawn_sync(RVAL2CSTR_ACCEPT_NIL(working_directory), + gargv, genvp, NUM2INT(flags), + (GSpawnChildSetupFunc)child_setup, (gpointer)func, + &standard_output, &standard_error, + &exit_status, &err); + g_free(gargv); + g_free(genvp); + if (!ret) + RAISE_GERROR(err); + + if (standard_output) { + std_out = CSTR2RVAL(standard_output); + g_free(standard_output); + } else { + std_out = Qnil; + standard_output = NULL; + } + if (standard_error) { + std_err = CSTR2RVAL(standard_error); + g_free(standard_error); + standard_error = NULL; + } else { + std_err = Qnil; + } + + if (! ret) + RAISE_GERROR(err); + + return rb_ary_new3(3, std_out, std_err, INT2FIX(exit_status)); + +} + +static VALUE +rg_s_command_line_sync(G_GNUC_UNUSED VALUE self, VALUE str) +{ + GError *err = NULL; + const gchar *command_line; + gchar *standard_output = NULL, *standard_error = NULL; + gint exit_status; + VALUE std_out, std_err; + gboolean ret; + + command_line = RVAL2CSTR(str); + ret = g_spawn_command_line_sync(command_line, + &standard_output, + &standard_error, + &exit_status, + &err); + if (standard_output) { + std_out = CSTR2RVAL(standard_output); + g_free(standard_output); + } else { + std_out = Qnil; + standard_output = NULL; + } + if (standard_error) { + std_err = CSTR2RVAL(standard_error); + g_free(standard_error); + standard_error = NULL; + } else { + std_err = Qnil; + } + + if (! ret) + RAISE_GERROR(err); + + return rb_ary_new3(3, std_out, std_err, INT2FIX(exit_status)); +} + +static VALUE +rg_s_command_line_async(G_GNUC_UNUSED VALUE self, VALUE str) +{ + GError *err = NULL; + const gchar *command_line; + VALUE ret; + + command_line = StringValuePtr(str); + ret = CBOOL2RVAL(g_spawn_command_line_async(command_line, &err)); + if (err != NULL) + RAISE_GERROR(err); + + return ret; +} + +#ifdef HAVE_G_SPAWN_CLOSE_PID + +#define RVAL2GPID(value) ((GPid)NUM2INT(pid)) + +static VALUE +rg_s_close_pid(G_GNUC_UNUSED VALUE self, VALUE pid) +{ + g_spawn_close_pid(RVAL2GPID(pid)); + return Qnil; +} + +#endif + +void +Init_glib_spawn(void) +{ + VALUE RG_TARGET_NAMESPACE = rb_define_module_under(mGLib, "Spawn"); + + id_call = rb_intern("call"); + id_new = rb_intern("new"); + + /* glib/gspawn.h */ + RG_DEF_SMETHOD(async_with_pipes, 4); + RG_DEF_SMETHOD(async, 4); + RG_DEF_SMETHOD(sync, 4); + RG_DEF_SMETHOD(command_line_sync, 1); + RG_DEF_SMETHOD(command_line_async, 1); +#ifdef HAVE_G_SPAWN_CLOSE_PID + RG_DEF_SMETHOD(close_pid, 1); +#endif + + rb_define_const(RG_TARGET_NAMESPACE, "LEAVE_DESCRIPTORS_OPEN", INT2NUM(G_SPAWN_LEAVE_DESCRIPTORS_OPEN)); + rb_define_const(RG_TARGET_NAMESPACE, "DO_NOT_REAP_CHILD", INT2NUM(G_SPAWN_DO_NOT_REAP_CHILD)); + rb_define_const(RG_TARGET_NAMESPACE, "SEARCH_PATH", INT2NUM(G_SPAWN_SEARCH_PATH)); + rb_define_const(RG_TARGET_NAMESPACE, "STDOUT_TO_DEV_NULL", INT2NUM(G_SPAWN_STDOUT_TO_DEV_NULL)); + rb_define_const(RG_TARGET_NAMESPACE, "STDERR_TO_DEV_NULL", INT2NUM(G_SPAWN_STDERR_TO_DEV_NULL)); + rb_define_const(RG_TARGET_NAMESPACE, "CHILD_INHERITS_STDIN", INT2NUM(G_SPAWN_CHILD_INHERITS_STDIN)); + rb_define_const(RG_TARGET_NAMESPACE, "FILE_AND_ARGV_ZERO", INT2NUM(G_SPAWN_FILE_AND_ARGV_ZERO)); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_spawnerror.c (+53 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_spawnerror.c 2017-02-15 13:19:47 +0900 (7eb31b5) @@ -0,0 +1,53 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2004 Masao Mutoh + * Copyright (C) 2004 Kazuhiro NISHIYAMA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" +#include "rbglib.h" + +#define RG_TARGET_NAMESPACE cSpawnError + +void +Init_glib_spawnerror(void) +{ + VALUE RG_TARGET_NAMESPACE = G_DEF_ERROR2(G_SPAWN_ERROR, "SpawnError", mGLib, rb_eIOError); + + rb_define_const(RG_TARGET_NAMESPACE, "FORK", INT2NUM(G_SPAWN_ERROR_FORK)); + rb_define_const(RG_TARGET_NAMESPACE, "READ", INT2NUM(G_SPAWN_ERROR_READ)); + rb_define_const(RG_TARGET_NAMESPACE, "CHDIR", INT2NUM(G_SPAWN_ERROR_CHDIR)); + rb_define_const(RG_TARGET_NAMESPACE, "EACCES", INT2NUM(G_SPAWN_ERROR_ACCES)); + rb_define_const(RG_TARGET_NAMESPACE, "EPERM", INT2NUM(G_SPAWN_ERROR_PERM)); + rb_define_const(RG_TARGET_NAMESPACE, "E2BIG", INT2NUM(G_SPAWN_ERROR_2BIG)); + rb_define_const(RG_TARGET_NAMESPACE, "ENOEXEC", INT2NUM(G_SPAWN_ERROR_NOEXEC)); + rb_define_const(RG_TARGET_NAMESPACE, "ENAMETOOLONG", INT2NUM(G_SPAWN_ERROR_NAMETOOLONG)); + rb_define_const(RG_TARGET_NAMESPACE, "ENOENT", INT2NUM(G_SPAWN_ERROR_NOENT)); + rb_define_const(RG_TARGET_NAMESPACE, "ENOMEM", INT2NUM(G_SPAWN_ERROR_NOMEM)); + rb_define_const(RG_TARGET_NAMESPACE, "ENOTDIR", INT2NUM(G_SPAWN_ERROR_NOTDIR)); + rb_define_const(RG_TARGET_NAMESPACE, "ELOOP", INT2NUM(G_SPAWN_ERROR_LOOP)); + rb_define_const(RG_TARGET_NAMESPACE, "ETXTBUSY", INT2NUM(G_SPAWN_ERROR_TXTBUSY)); + rb_define_const(RG_TARGET_NAMESPACE, "EIO", INT2NUM(G_SPAWN_ERROR_IO)); + rb_define_const(RG_TARGET_NAMESPACE, "ENFILE", INT2NUM(G_SPAWN_ERROR_NFILE)); + rb_define_const(RG_TARGET_NAMESPACE, "EMFILE", INT2NUM(G_SPAWN_ERROR_MFILE)); + rb_define_const(RG_TARGET_NAMESPACE, "EINVAL", INT2NUM(G_SPAWN_ERROR_INVAL)); + rb_define_const(RG_TARGET_NAMESPACE, "EISDIR", INT2NUM(G_SPAWN_ERROR_ISDIR)); + rb_define_const(RG_TARGET_NAMESPACE, "ELIBBAD", INT2NUM(G_SPAWN_ERROR_LIBBAD)); + rb_define_const(RG_TARGET_NAMESPACE, "FAILED", INT2NUM(G_SPAWN_ERROR_FAILED)); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_threads.c (+61 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_threads.c 2017-02-15 13:19:47 +0900 (504fce5) @@ -0,0 +1,61 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2005 Masao Mutoh + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" + +#define RG_TARGET_NAMESPACE cThread + +static VALUE RG_TARGET_NAMESPACE; + +static VALUE +rg_s_init(VALUE self) +{ +#ifdef HAVE_G_THREAD_INIT +#if defined(G_THREADS_ENABLED) && !GLIB_CHECK_VERSION(2, 32, 0) + g_thread_init(NULL); +#endif +#endif + return self; +} + +static VALUE +rg_s_supported_p(G_GNUC_UNUSED VALUE self) +{ +#ifdef HAVE_G_THREAD_INIT +#ifdef G_THREADS_ENABLED + return CBOOL2RVAL(g_thread_supported()); +#else + return Qfalse; +#endif +#else + return Qfalse; +#endif + +} + +void +Init_glib_threads(void) +{ + RG_TARGET_NAMESPACE = rb_define_class_under(mGLib, "Thread", rb_cObject); + + RG_DEF_SMETHOD(init, 0); + RG_DEF_SMETHOD_P(supported, 0); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_timer.c (+127 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_timer.c 2017-02-15 13:19:47 +0900 (f7af229) @@ -0,0 +1,127 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2005 Masao Mutoh + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" + +#ifdef G_OS_WIN32 +#include <windows.h> +#endif + +/*****************************************/ + +/* This is stolen from gtimer.c of glib-2.6.2. */ +struct _GTimer +{ +#ifdef G_OS_WIN32 + DWORD start; + DWORD end; +#else /* !G_OS_WIN32 */ + struct timeval start; + struct timeval end; +#endif /* !G_OS_WIN32 */ + + guint active : 1; +}; + +static GTimer* +timer_copy(GTimer *timer) +{ + GTimer* new_timer; + g_return_val_if_fail (timer != NULL, NULL); + + new_timer = g_new(struct _GTimer, 1); + *new_timer = *timer; + return new_timer; +} + +static GType +g_timer_get_type(void) +{ + static GType our_type = 0; + if (our_type == 0) + our_type = g_boxed_type_register_static ("GTimer", + (GBoxedCopyFunc)timer_copy, + (GBoxedFreeFunc)g_timer_destroy); + return our_type; +} +/*****************************************/ + +#define G_TYPE_TIMER (g_timer_get_type()) + +#define RG_TARGET_NAMESPACE cTimer +#define _SELF(s) ((GTimer*)RVAL2BOXED(s, G_TYPE_TIMER)) + +static VALUE +rg_initialize(VALUE self) +{ + G_INITIALIZE(self, g_timer_new()); + return Qnil; +} + +static VALUE +rg_start(VALUE self) +{ + g_timer_start(_SELF(self)); + return self; +} + +static VALUE +rg_stop(VALUE self) +{ + g_timer_stop(_SELF(self)); + return self; +} + +static VALUE +rg_continue(VALUE self) +{ + g_timer_continue(_SELF(self)); + return self; +} + +static VALUE +rg_elapsed(VALUE self) +{ + gulong microseconds; + gdouble ret = g_timer_elapsed(_SELF(self), µseconds); + + return rb_assoc_new(rb_float_new(ret), ULONG2NUM(microseconds)); +} + +static VALUE +rg_reset(VALUE self) +{ + g_timer_reset(_SELF(self)); + return self; +} + +void +Init_glib_timer(void) +{ + VALUE RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_TIMER, "Timer", mGLib); + + RG_DEF_METHOD(initialize, 0); + RG_DEF_METHOD(start, 0); + RG_DEF_METHOD(stop, 0); + RG_DEF_METHOD(continue, 0); + RG_DEF_METHOD(elapsed, 0); + RG_DEF_METHOD(reset, 0); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_timezone.c (+82 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_timezone.c 2017-02-15 13:19:47 +0900 (7411597) @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2016 Ruby-GNOME2 Project Team + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" + +#define RG_TARGET_NAMESPACE cTimeZone +#define _SELF(s) ((GTimeZone*)RVAL2BOXED(s, G_TYPE_TIME_ZONE)) + +static VALUE +rg_initialize(gint argc, VALUE *argv, VALUE self) +{ + VALUE rb_identifier = Qnil; + const gchar *identifier = NULL; + GTimeZone *time_zone = NULL; + + rb_scan_args(argc, argv, "01", &rb_identifier); + + if (!NIL_P(rb_identifier)) + identifier = RVAL2CSTR(rb_identifier); + + time_zone = g_time_zone_new(identifier); + G_INITIALIZE(self, time_zone); + return Qnil; +} + +static VALUE +rg_s_local(G_GNUC_UNUSED VALUE self) +{ + GTimeZone *time_zone = NULL; + time_zone = g_time_zone_new_local(); + return GTIMEZONE2RVAL(time_zone); +} + +static VALUE +rg_s_utc(G_GNUC_UNUSED VALUE self) +{ + GTimeZone *time_zone = NULL; + time_zone = g_time_zone_new_utc(); + return GTIMEZONE2RVAL(time_zone); +} + +static VALUE +rg_abbreviation(VALUE self, VALUE rb_interval) +{ + gint interval = NUM2INT(rb_interval); + return CSTR2RVAL(g_time_zone_get_abbreviation(_SELF(self), interval)); +} + +static VALUE +rg_offset(VALUE self, VALUE rb_interval) +{ + gint interval = NUM2INT(rb_interval); + return INT2NUM(g_time_zone_get_offset(_SELF(self), interval)); +} + +void +Init_glib_time_zone(void) +{ + VALUE RG_TARGET_NAMESPACE; + RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_TIME_ZONE, "TimeZone", mGLib); + RG_DEF_METHOD(initialize, -1); + RG_DEF_SMETHOD(local, 0); + RG_DEF_SMETHOD(utc, 0); + RG_DEF_METHOD(abbreviation, 1); + RG_DEF_METHOD(offset, 1); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_ucs4.c (+79 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_ucs4.c 2017-02-15 13:19:47 +0900 (2f599d8) @@ -0,0 +1,79 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2006 Kouhei Sutou + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" +#include "rbglib.h" + +#define RG_TARGET_NAMESPACE mUCS4 + +static VALUE +rg_s_to_utf16(G_GNUC_UNUSED VALUE self, VALUE rb_ucs4) +{ + VALUE result; + gunichar *ucs4; + gunichar2 *utf16; + glong len, items_written; + GError *error = NULL; + + ucs4 = (gunichar *)StringValuePtr(rb_ucs4); + len = RSTRING_LEN(rb_ucs4) / sizeof(*ucs4); + + utf16 = g_ucs4_to_utf16(ucs4, len, NULL, &items_written, &error); + + if (error) + RAISE_GERROR(error); + + result = CSTR2RVAL_LEN_UTF16((char *)utf16, + items_written * sizeof(*utf16)); + g_free(utf16); + return result; +} + +static VALUE +rg_s_to_utf8(G_GNUC_UNUSED VALUE self, VALUE rb_ucs4) +{ + VALUE result; + gunichar *ucs4; + gchar *utf8; + glong len, items_written; + GError *error = NULL; + + ucs4 = (gunichar *)StringValuePtr(rb_ucs4); + len = RSTRING_LEN(rb_ucs4) / sizeof(*ucs4); + + utf8 = g_ucs4_to_utf8(ucs4, len, NULL, &items_written, &error); + + if (error) + RAISE_GERROR(error); + + result = CSTR2RVAL_LEN(utf8, items_written); + g_free(utf8); + return result; +} + +void +Init_glib_ucs4(void) +{ + VALUE RG_TARGET_NAMESPACE = rb_define_module_under(mGLib, "UCS4"); + + RG_DEF_SMETHOD(to_utf16, 1); + RG_DEF_SMETHOD(to_utf8, 1); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_unichar.c (+201 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_unichar.c 2017-02-15 13:19:47 +0900 (92f54c3) @@ -0,0 +1,201 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2006 Kouhei Sutou + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" +#include "rbglib.h" + +#define RG_TARGET_NAMESPACE mUniChar + +#define DEF_IS_UNICHAR(name) \ +static VALUE \ +rbglib_m_unichar_is ## name(G_GNUC_UNUSED VALUE self, VALUE unichar) \ +{ \ + return CBOOL2RVAL(g_unichar_is ## name(NUM2UINT(unichar))); \ +} + +DEF_IS_UNICHAR(alnum) +DEF_IS_UNICHAR(alpha) +DEF_IS_UNICHAR(cntrl) +DEF_IS_UNICHAR(digit) +DEF_IS_UNICHAR(graph) +DEF_IS_UNICHAR(lower) +DEF_IS_UNICHAR(print) +DEF_IS_UNICHAR(punct) +DEF_IS_UNICHAR(space) +DEF_IS_UNICHAR(upper) +DEF_IS_UNICHAR(xdigit) +DEF_IS_UNICHAR(title) +DEF_IS_UNICHAR(defined) +DEF_IS_UNICHAR(wide) +DEF_IS_UNICHAR(wide_cjk) + +#undef DEF_IS_UNICHAR + +static VALUE +rg_s_to_upper(G_GNUC_UNUSED VALUE self, VALUE unichar) +{ + return UINT2NUM(g_unichar_toupper(NUM2UINT(unichar))); +} + +static VALUE +rg_s_to_lower(G_GNUC_UNUSED VALUE self, VALUE unichar) +{ + return UINT2NUM(g_unichar_tolower(NUM2UINT(unichar))); +} + +static VALUE +rg_s_to_title(G_GNUC_UNUSED VALUE self, VALUE unichar) +{ + return UINT2NUM(g_unichar_totitle(NUM2UINT(unichar))); +} + +static VALUE +rg_s_digit_value(G_GNUC_UNUSED VALUE self, VALUE unichar) +{ + return INT2NUM(g_unichar_digit_value(NUM2UINT(unichar))); +} + +static VALUE +rg_s_xdigit_value(G_GNUC_UNUSED VALUE self, VALUE unichar) +{ + return INT2NUM(g_unichar_xdigit_value(NUM2UINT(unichar))); +} + +static VALUE +rg_s_type(G_GNUC_UNUSED VALUE self, VALUE unichar) +{ + return GENUM2RVAL(g_unichar_type(NUM2UINT(unichar)), + G_TYPE_UNICODE_TYPE); +} + +static VALUE +rg_s_break_type(G_GNUC_UNUSED VALUE self, VALUE unichar) +{ + return GENUM2RVAL(g_unichar_break_type(NUM2UINT(unichar)), + G_TYPE_UNICODE_BREAK_TYPE); +} + +static VALUE +rg_s_get_mirror_char(G_GNUC_UNUSED VALUE self, VALUE unichar) +{ + gunichar mirrored_char; + + if (g_unichar_get_mirror_char(NUM2UINT(unichar), &mirrored_char)) { + return UINT2NUM(mirrored_char); + } else { + return unichar; + } +} + +#if GLIB_CHECK_VERSION(2,14,0) +static VALUE +rg_s_combining_class(G_GNUC_UNUSED VALUE self, VALUE unichar) +{ + return INT2NUM(g_unichar_combining_class(NUM2UINT(unichar))); +} + +static VALUE +rg_s_get_script(G_GNUC_UNUSED VALUE self, VALUE unichar) +{ + return GENUM2RVAL(g_unichar_get_script(NUM2UINT(unichar)), + G_TYPE_UNICODE_SCRIPT); +} + +static VALUE +rg_s_mark_p(G_GNUC_UNUSED VALUE self, VALUE unichar) +{ + return CBOOL2RVAL(g_unichar_ismark(NUM2UINT(unichar))); +} + +static VALUE +rg_s_zero_width_p(G_GNUC_UNUSED VALUE self, VALUE unichar) +{ + return CBOOL2RVAL(g_unichar_iszerowidth(NUM2UINT(unichar))); +} +#endif + +static VALUE +rg_s_to_utf8(G_GNUC_UNUSED VALUE self, VALUE unichar) +{ + gchar utf8[6]; + gint len; + + len = g_unichar_to_utf8(NUM2UINT(unichar), utf8); + return CSTR2RVAL_LEN(utf8, len); +} + +void +Init_glib_unichar(void) +{ + VALUE RG_TARGET_NAMESPACE = rb_define_module_under(mGLib, "UniChar"); + + rbg_define_singleton_method(RG_TARGET_NAMESPACE, "alnum?", + rbglib_m_unichar_isalnum, 1); + rbg_define_singleton_method(RG_TARGET_NAMESPACE, "alpha?", + rbglib_m_unichar_isalpha, 1); + rbg_define_singleton_method(RG_TARGET_NAMESPACE, "cntrl?", + rbglib_m_unichar_iscntrl, 1); + rbg_define_singleton_method(RG_TARGET_NAMESPACE, "digit?", + rbglib_m_unichar_isdigit, 1); + rbg_define_singleton_method(RG_TARGET_NAMESPACE, "graph?", + rbglib_m_unichar_isgraph, 1); + rbg_define_singleton_method(RG_TARGET_NAMESPACE, "lower?", + rbglib_m_unichar_islower, 1); + rbg_define_singleton_method(RG_TARGET_NAMESPACE, "print?", + rbglib_m_unichar_isprint, 1); + rbg_define_singleton_method(RG_TARGET_NAMESPACE, "punct?", + rbglib_m_unichar_ispunct, 1); + rbg_define_singleton_method(RG_TARGET_NAMESPACE, "space?", + rbglib_m_unichar_isspace, 1); + rbg_define_singleton_method(RG_TARGET_NAMESPACE, "upper?", + rbglib_m_unichar_isupper, 1); + rbg_define_singleton_method(RG_TARGET_NAMESPACE, "xdigit?", + rbglib_m_unichar_isxdigit, 1); + rbg_define_singleton_method(RG_TARGET_NAMESPACE, "title?", + rbglib_m_unichar_istitle, 1); + rbg_define_singleton_method(RG_TARGET_NAMESPACE, "defined?", + rbglib_m_unichar_isdefined, 1); + rbg_define_singleton_method(RG_TARGET_NAMESPACE, "wide?", + rbglib_m_unichar_iswide, 1); + rbg_define_singleton_method(RG_TARGET_NAMESPACE, "wide_cjk?", + rbglib_m_unichar_iswide_cjk, 1); + + RG_DEF_SMETHOD(to_upper, 1); + RG_DEF_SMETHOD(to_lower, 1); + RG_DEF_SMETHOD(to_title, 1); + + RG_DEF_SMETHOD(digit_value, 1); + RG_DEF_SMETHOD(xdigit_value, 1); + + RG_DEF_SMETHOD(type, 1); + RG_DEF_SMETHOD(break_type, 1); + + RG_DEF_SMETHOD(get_mirror_char, 1); + +#if GLIB_CHECK_VERSION(2,14,0) + RG_DEF_SMETHOD(combining_class, 1); + RG_DEF_SMETHOD(get_script, 1); + RG_DEF_SMETHOD_P(mark, 1); + RG_DEF_SMETHOD_P(zero_width, 1); +#endif + + RG_DEF_SMETHOD(to_utf8, 1); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_unicode.c (+90 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_unicode.c 2017-02-15 13:19:47 +0900 (826403c) @@ -0,0 +1,90 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2006 Kouhei Sutou + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" +#include "rbglib.h" + +#define RG_TARGET_NAMESPACE mUnicode + +static VALUE +rbglib_m_charset(G_GNUC_UNUSED VALUE self) +{ + const char *charset; + g_get_charset(&charset); + return CSTR2RVAL(charset); +} + +static VALUE +rg_s_canonical_ordering(G_GNUC_UNUSED VALUE self, VALUE rb_ucs4) +{ + VALUE normalized_ucs4; + gchar *original_str; + gunichar *ucs4; + gint len; + + original_str = StringValuePtr(rb_ucs4); + len = RSTRING_LEN(rb_ucs4); + ucs4 = g_memdup(original_str, len); + g_unicode_canonical_ordering(ucs4, len); + normalized_ucs4 = CSTR2RVAL_LEN_UCS4((const char *)ucs4, len); + g_free(ucs4); + return normalized_ucs4; +} + +static VALUE +rg_s_canonical_decomposition(G_GNUC_UNUSED VALUE self, VALUE unichar) +{ + VALUE normalized_ucs4; + gunichar *ucs4; + gsize len; + + ucs4 = g_unicode_canonical_decomposition(NUM2UINT(unichar), &len); + normalized_ucs4 = CSTR2RVAL_LEN_UCS4((const char *)ucs4, + len * sizeof(gunichar)); + g_free(ucs4); + return normalized_ucs4; +} + +void +Init_glib_unicode(void) +{ + VALUE RG_TARGET_NAMESPACE = rb_define_module_under(mGLib, "Unicode"); + + /* GUnicodeType */ + G_DEF_CLASS(G_TYPE_UNICODE_TYPE, "Type", RG_TARGET_NAMESPACE); + G_DEF_CONSTANTS(RG_TARGET_NAMESPACE, G_TYPE_UNICODE_TYPE, "G_UNICODE_"); + /* GUnicodeBreakType */ + G_DEF_CLASS(G_TYPE_UNICODE_BREAK_TYPE, "BreakType", RG_TARGET_NAMESPACE); + G_DEF_CONSTANTS(RG_TARGET_NAMESPACE, G_TYPE_UNICODE_BREAK_TYPE, "G_UNICODE_"); + +#if GLIB_CHECK_VERSION(2,14,0) + /* GUnicodeScript */ + G_DEF_CLASS(G_TYPE_UNICODE_SCRIPT, "Script", RG_TARGET_NAMESPACE); + G_DEF_CONSTANTS(RG_TARGET_NAMESPACE, G_TYPE_UNICODE_SCRIPT, "G_UNICODE_"); +#endif + + G_DEF_CLASS(G_TYPE_NORMALIZE_MODE, "NormalizeMode", mGLib); + + rbg_define_singleton_method(mGLib, "charset", rbglib_m_charset, 0); + + RG_DEF_SMETHOD(canonical_ordering, 1); + RG_DEF_SMETHOD(canonical_decomposition, 1); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_utf16.c (+78 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_utf16.c 2017-02-15 13:19:47 +0900 (b36a89b) @@ -0,0 +1,78 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2006 Kouhei Sutou + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" +#include "rbglib.h" + +#define RG_TARGET_NAMESPACE mUTF16 + +static VALUE +rg_s_to_ucs4(G_GNUC_UNUSED VALUE self, VALUE rb_utf16) +{ + VALUE result; + gunichar *ucs4; + gunichar2 *utf16; + glong len, items_written; + GError *error = NULL; + + utf16 = (gunichar2 *)StringValueCStr(rb_utf16); + len = RSTRING_LEN(rb_utf16) / sizeof(*utf16); + + ucs4 = g_utf16_to_ucs4(utf16, len, NULL, &items_written, &error); + + if (error) + RAISE_GERROR(error); + + result = CSTR2RVAL_LEN_UCS4((char *)ucs4, items_written * sizeof(*ucs4)); + g_free(ucs4); + return result; +} + +static VALUE +rg_s_to_utf8(G_GNUC_UNUSED VALUE self, VALUE rb_utf16) +{ + VALUE result; + gchar *utf8; + gunichar2 *utf16; + glong len, items_written; + GError *error = NULL; + + utf16 = (gunichar2 *)StringValueCStr(rb_utf16); + len = RSTRING_LEN(rb_utf16) / sizeof(*utf16); + + utf8 = g_utf16_to_utf8(utf16, len, NULL, &items_written, &error); + + if (error) + RAISE_GERROR(error); + + result = CSTR2RVAL_LEN(utf8, items_written * sizeof(*utf8)); + g_free(utf8); + return result; +} + +void +Init_glib_utf16(void) +{ + VALUE RG_TARGET_NAMESPACE = rb_define_module_under(mGLib, "UTF16"); + + RG_DEF_SMETHOD(to_ucs4, 1); + RG_DEF_SMETHOD(to_utf8, 1); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_utf8.c (+257 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_utf8.c 2017-02-15 13:19:47 +0900 (5a6ff25) @@ -0,0 +1,257 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2006 Kouhei Sutou + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" +#include "rbglib.h" + +#define RG_TARGET_NAMESPACE mUTF8 + +static VALUE +rg_s_get_char(int argc, VALUE *argv, G_GNUC_UNUSED VALUE self) +{ + VALUE utf8, validate; + gunichar result; + + rb_scan_args(argc, argv, "11", &utf8, &validate); + + if (RVAL2CBOOL(validate)) { + StringValue(utf8); + result = g_utf8_get_char_validated(RSTRING_PTR(utf8), + RSTRING_LEN(utf8)); + if (result == (gunichar)-1) { + return INT2NUM(-1); + } else if (result == (gunichar)-2) { + return INT2NUM(-2); + } + } else { + result = g_utf8_get_char(StringValueCStr(utf8)); + } + + return UINT2NUM(result); +} + +static VALUE +rg_s_size(G_GNUC_UNUSED VALUE self, VALUE rb_utf8) +{ + gchar *utf8; + + utf8 = StringValueCStr(rb_utf8); + return INT2NUM(g_utf8_strlen(utf8, RSTRING_LEN(rb_utf8))); +} + +static VALUE +rg_s_reverse(G_GNUC_UNUSED VALUE self, VALUE rb_utf8) +{ + VALUE result; + gchar *utf8, *reversed_utf8; + + utf8 = StringValueCStr(rb_utf8); + reversed_utf8 = g_utf8_strreverse(utf8, RSTRING_LEN(rb_utf8)); + result = CSTR2RVAL(reversed_utf8); + g_free(reversed_utf8); + return result; +} + +static VALUE +rg_s_validate(G_GNUC_UNUSED VALUE self, VALUE str) +{ + StringValue(str); + return CBOOL2RVAL(g_utf8_validate(RSTRING_PTR(str), RSTRING_LEN(str), + NULL)); +} + +static VALUE +rg_s_upcase(G_GNUC_UNUSED VALUE self, VALUE rb_utf8) +{ + VALUE result; + gchar *utf8, *upcased_utf8; + + utf8 = StringValueCStr(rb_utf8); + upcased_utf8 = g_utf8_strup(utf8, RSTRING_LEN(rb_utf8)); + result = CSTR2RVAL(upcased_utf8); + g_free(upcased_utf8); + return result; +} + +static VALUE +rg_s_downcase(G_GNUC_UNUSED VALUE self, VALUE rb_utf8) +{ + VALUE result; + gchar *utf8, *downcased_utf8; + + utf8 = StringValueCStr(rb_utf8); + downcased_utf8 = g_utf8_strdown(utf8, RSTRING_LEN(rb_utf8)); + result = CSTR2RVAL(downcased_utf8); + g_free(downcased_utf8); + return result; +} + +static VALUE +rg_s_casefold(G_GNUC_UNUSED VALUE self, VALUE rb_utf8) +{ + VALUE result; + gchar *utf8, *casefolded_utf8; + + utf8 = StringValueCStr(rb_utf8); + casefolded_utf8 = g_utf8_casefold(utf8, RSTRING_LEN(rb_utf8)); + result = CSTR2RVAL(casefolded_utf8); + g_free(casefolded_utf8); + return result; +} + +static VALUE +rg_s_normalize(int argc, VALUE *argv, G_GNUC_UNUSED VALUE self) +{ + VALUE rb_utf8, rb_mode, result; + gchar *utf8, *normalized_utf8; + GNormalizeMode mode = G_NORMALIZE_DEFAULT; + + rb_scan_args(argc, argv, "11", &rb_utf8, &rb_mode); + + if (!NIL_P(rb_mode)) + mode = RVAL2GENUM(rb_mode, G_TYPE_NORMALIZE_MODE); + + utf8 = StringValueCStr(rb_utf8); + normalized_utf8 = g_utf8_normalize(utf8, RSTRING_LEN(rb_utf8), mode); + result = CSTR2RVAL(normalized_utf8); + g_free(normalized_utf8); + return result; +} + +static VALUE +rg_s_collate(G_GNUC_UNUSED VALUE self, VALUE utf8a, VALUE utf8b) +{ + return INT2NUM(g_utf8_collate(StringValueCStr(utf8a), + StringValueCStr(utf8b))); +} + +static VALUE +rg_s_collate_key(int argc, VALUE *argv, G_GNUC_UNUSED VALUE self) +{ + VALUE result, rb_utf8, for_filename; + gchar *key, *utf8; + gssize len; + + rb_scan_args(argc, argv, "11", &rb_utf8, &for_filename); + + utf8 = StringValueCStr(rb_utf8); + len = RSTRING_LEN(rb_utf8); + if (RVAL2CBOOL(for_filename)) + key = g_utf8_collate_key_for_filename(utf8, len); + else + key = g_utf8_collate_key(utf8, len); + + result = CSTR2RVAL(key); + g_free(key); + return result; +} + +static VALUE +rg_s_to_utf16(G_GNUC_UNUSED VALUE self, VALUE rb_utf8) +{ + VALUE result; + gchar *utf8; + gunichar2 *utf16; + glong len, items_written; + GError *error = NULL; + + utf8 = StringValueCStr(rb_utf8); + len = RSTRING_LEN(rb_utf8); + + utf16 = g_utf8_to_utf16(utf8, len, NULL, &items_written, &error); + + if (error) + RAISE_GERROR(error); + + result = CSTR2RVAL_LEN_UTF16((char *)utf16, + items_written * sizeof(*utf16)); + g_free(utf16); + return result; +} + +static VALUE +rg_s_to_ucs4(int argc, VALUE *argv, G_GNUC_UNUSED VALUE self) +{ + VALUE result, rb_utf8, is_fast; + gchar *utf8; + gunichar *ucs4; + glong len, items_written; + + rb_scan_args(argc, argv, "11", &rb_utf8, &is_fast); + + utf8 = StringValueCStr(rb_utf8); + len = RSTRING_LEN(rb_utf8); + + if (RVAL2CBOOL(is_fast)) { + ucs4 = g_utf8_to_ucs4_fast(utf8, len, &items_written); + } else { + GError *error = NULL; + ucs4 = g_utf8_to_ucs4(utf8, len, NULL, &items_written, &error); + + if (error) + RAISE_GERROR(error); + } + + result = CSTR2RVAL_LEN_UCS4((char *)ucs4, items_written * sizeof(*ucs4)); + g_free(ucs4); + return result; +} + +void +Init_glib_utf8(void) +{ + VALUE RG_TARGET_NAMESPACE = rb_define_module_under(mGLib, "UTF8"); + + /* + Not implemented. + g_utf8_next_char + */ + RG_DEF_SMETHOD(get_char, -1); + /* + Not implemented. + g_utf8_offset_to_pointer + g_utf8_pointer_to_offset + g_utf8_prev_char + g_utf8_find_next_char + g_utf8_find_prev_char + g_utf8_prev_char + */ + RG_DEF_SMETHOD(size, 1); + /* + Not implemented. + g_utf8_strncpy + g_utf8_strrchr + */ + RG_DEF_SMETHOD(reverse, 1); + RG_DEF_SMETHOD(validate, 1); + + RG_DEF_SMETHOD(upcase, 1); + RG_DEF_SMETHOD(downcase, 1); + RG_DEF_SMETHOD(casefold, 1); + + RG_DEF_SMETHOD(normalize, -1); + + RG_DEF_SMETHOD(collate, 2); + RG_DEF_SMETHOD(collate_key, -1); + + RG_DEF_SMETHOD(to_utf16, 1); + RG_DEF_SMETHOD(to_ucs4, -1); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_utils.c (+339 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_utils.c 2017-02-15 13:19:47 +0900 (176f4ce) @@ -0,0 +1,339 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2004 Ruby-GNOME2 Project Team + * Copyright (C) 2004 Pascal Terjan + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" + +#define RG_TARGET_NAMESPACE mGLib + +static VALUE +rg_s_application_name(G_GNUC_UNUSED VALUE self) +{ + return CSTR2RVAL(g_get_application_name()); +} + +static VALUE +rg_s_set_application_name(VALUE self, VALUE application_name) +{ + g_set_prgname(RVAL2CSTR_ACCEPT_NIL(application_name)); + return self; +} + +static VALUE +rg_s_prgname(G_GNUC_UNUSED VALUE self) +{ + return CSTR2RVAL(g_get_prgname()); +} + +static VALUE +rg_s_set_prgname(VALUE self, VALUE prgname) +{ + g_set_prgname(RVAL2CSTR_ACCEPT_NIL(prgname)); + return self; +} + +static VALUE +rg_s_getenv(G_GNUC_UNUSED VALUE self, VALUE variable) +{ + return CSTR2RVAL(g_getenv(RVAL2CSTR(variable))); +} + +static VALUE +rg_s_setenv(G_GNUC_UNUSED VALUE self, VALUE variable, VALUE value, VALUE overwrite) +{ + return CBOOL2RVAL(g_setenv(RVAL2CSTR(variable), + RVAL2CSTR_ACCEPT_NIL(value), + RVAL2CBOOL(overwrite))); +} + +static VALUE +rg_s_unsetenv(VALUE self, VALUE variable) +{ + g_unsetenv(RVAL2CSTR(variable)); + return self; +} + +#ifdef HAVE_G_LISTENV +static VALUE +rg_s_listenv(G_GNUC_UNUSED VALUE self) +{ + gchar** c_list; + gchar** c_var; + VALUE r_list = rb_ary_new(); + c_list = g_listenv(); + c_var = c_list; + while(*c_var) { + rb_ary_push(r_list, CSTR2RVAL(*(c_var++))); + } + g_strfreev(c_list); + return r_list; +} +#endif + +static VALUE +rg_s_host_name(G_GNUC_UNUSED VALUE self) +{ + return CSTR2RVAL(g_get_host_name()); +} + +static VALUE +rg_s_user_name(G_GNUC_UNUSED VALUE self) +{ + return CSTR2RVAL(g_get_user_name()); +} + +static VALUE +rg_s_real_name(G_GNUC_UNUSED VALUE self) +{ + return CSTR2RVAL(g_get_real_name()); +} + +static VALUE +rg_s_user_cache_dir(G_GNUC_UNUSED VALUE self) +{ + return CSTR2RVAL(g_get_user_cache_dir()); +} + +static VALUE +rg_s_user_data_dir(G_GNUC_UNUSED VALUE self) +{ + return CSTR2RVAL(g_get_user_data_dir()); +} + +static VALUE +rg_s_user_config_dir(G_GNUC_UNUSED VALUE self) +{ + return CSTR2RVAL(g_get_user_config_dir()); +} + +static VALUE +rg_s_system_data_dirs(G_GNUC_UNUSED VALUE self) +{ + return STRV2RVAL((const gchar **)g_get_system_data_dirs()); +} + +static VALUE +rg_s_system_config_dirs(G_GNUC_UNUSED VALUE self) +{ + return STRV2RVAL((const gchar **)g_get_system_config_dirs()); +} + +#if GLIB_CHECK_VERSION(2, 14, 0) +static VALUE +rg_s_get_user_special_dir(G_GNUC_UNUSED VALUE self, VALUE directory) +{ + return CSTR2RVAL(g_get_user_special_dir(RVAL2GENUM(directory, + G_TYPE_USER_DIRECTORY))); +} +#endif + +static VALUE +rg_s_home_dir(G_GNUC_UNUSED VALUE self) +{ + return CSTR2RVAL(g_get_home_dir()); +} + +static VALUE +rg_s_tmp_dir(G_GNUC_UNUSED VALUE self) +{ + return CSTR2RVAL(g_get_tmp_dir()); +} + +static VALUE +rg_s_current_dir(G_GNUC_UNUSED VALUE self) +{ + gchar* dir = g_get_current_dir(); + VALUE ret = CSTR2RVAL(dir); + g_free(dir); + return ret; +} + +static VALUE +rg_s_path_is_absolute_p(G_GNUC_UNUSED VALUE self, VALUE fname) +{ + return CBOOL2RVAL(g_path_is_absolute(RVAL2CSTR(fname))); +} + +static VALUE +rg_s_path_skip_root(G_GNUC_UNUSED VALUE self, VALUE fname) +{ + return CSTR2RVAL(g_path_skip_root(RVAL2CSTR(fname))); +} + +static VALUE +rg_s_path_get_basename(G_GNUC_UNUSED VALUE self, VALUE fname) +{ + return CSTR2RVAL(g_path_get_basename(RVAL2CSTR(fname))); +} + +static VALUE +rg_s_path_get_dirname(G_GNUC_UNUSED VALUE self, VALUE fname) +{ + return CSTR2RVAL(g_path_get_dirname(RVAL2CSTR(fname))); +} + +/* +Use File.join() +gchar* g_build_filename (const gchar *first_element, + ...); +gchar* g_build_filenamev (gchar **args); +gchar* g_build_path (const gchar *separator, + const gchar *first_element, + ...); +gchar* g_build_pathv (const gchar *separator, + gchar **args); +*/ + +static VALUE +rg_s_find_program_in_path(G_GNUC_UNUSED VALUE self, VALUE program) +{ + gchar* path = g_find_program_in_path(RVAL2CSTR(program)); + VALUE ret = CSTR2RVAL(path); + g_free(path); + return ret; +} + +static VALUE +rg_s_bit_nth_lsf(G_GNUC_UNUSED VALUE self, VALUE mask, VALUE nth_bit) +{ + return INT2NUM(g_bit_nth_lsf(NUM2ULONG(mask), NUM2INT(nth_bit))); +} + +static VALUE +rg_s_bit_nth_msf(G_GNUC_UNUSED VALUE self, VALUE mask, VALUE nth_bit) +{ + return INT2NUM(g_bit_nth_msf(NUM2ULONG(mask), NUM2INT(nth_bit))); +} + +static VALUE +rg_s_bit_storage(G_GNUC_UNUSED VALUE self, VALUE number) +{ + return UINT2NUM(g_bit_storage(NUM2ULONG(number))); +} + +static VALUE +rg_s_spaced_primes_closest(G_GNUC_UNUSED VALUE self, VALUE num) +{ + return UINT2NUM(g_spaced_primes_closest(NUM2UINT(num))); +} + +/* +Use at_exit of ruby instead. +void g_atexit (GVoidFunc func); +*/ + +static VALUE +rg_s_parse_debug_string(G_GNUC_UNUSED VALUE self, VALUE string, VALUE keys) +{ + gint i, nkeys; + VALUE ary; + GDebugKey* gkeys; + + Check_Type(keys, RUBY_T_HASH); + ary = rb_funcall(keys, rb_intern("to_a"), 0); + nkeys = RARRAY_LEN(ary); + gkeys = ALLOCA_N(GDebugKey, nkeys); + for (i = 0; i < nkeys; i++) { + gkeys[i].key = RVAL2CSTR(RARRAY_PTR(RARRAY_PTR(ary)[i])[0]); + gkeys[i].value = NUM2UINT(RARRAY_PTR(RARRAY_PTR(ary)[i])[1]); + } + + return UINT2NUM(g_parse_debug_string(RVAL2CSTR(string), gkeys, nkeys)); +} + +/* +void (*GVoidFunc) (void); +void (*GFreeFunc) (gpointer data); + +Don't need them. +void g_qsort_with_data (gconstpointer pbase, + gint total_elems, + gsize size, + GCompareDataFunc compare_func, + gpointer user_data); + +void g_nullify_pointer (gpointer *nullify_location); +*/ + +static VALUE +rg_s_check_version_p(G_GNUC_UNUSED VALUE self, VALUE major, VALUE minor, VALUE micro) +{ + return CBOOL2RVAL(glib_major_version > NUM2UINT(major) || + (glib_major_version == NUM2UINT(major) && + glib_minor_version > NUM2UINT(minor)) || + (glib_major_version == NUM2UINT(major) && + glib_minor_version == NUM2UINT(minor) && + glib_micro_version >= NUM2UINT(micro))); +} + +void +Init_glib_utils(void) +{ + /* glib/gutils.h */ +#if GLIB_CHECK_VERSION(2, 14, 0) + G_DEF_CLASS(G_TYPE_USER_DIRECTORY, "UserDirectory", RG_TARGET_NAMESPACE); + G_DEF_CONSTANTS(RG_TARGET_NAMESPACE, G_TYPE_USER_DIRECTORY, "G_"); +#endif + +#if GLIB_CHECK_VERSION(2, 30, 0) + G_DEF_CLASS(G_TYPE_FORMAT_SIZE_FLAGS, + "FormatSizeFlags", RG_TARGET_NAMESPACE); +#endif + + RG_DEF_SMETHOD(application_name, 0); + RG_DEF_SMETHOD(set_application_name, 1); + RG_DEF_SMETHOD(prgname, 0); + RG_DEF_SMETHOD(set_prgname, 1); + RG_DEF_SMETHOD(getenv, 1); + RG_DEF_SMETHOD(setenv, 2); + RG_DEF_SMETHOD(unsetenv, 1); +#ifdef HAVE_G_LISTENV + RG_DEF_SMETHOD(listenv, 0); +#endif + RG_DEF_SMETHOD(host_name, 0); + RG_DEF_SMETHOD(user_name, 0); + RG_DEF_SMETHOD(real_name, 0); + + RG_DEF_SMETHOD(user_cache_dir, 0); + RG_DEF_SMETHOD(user_data_dir, 0); + RG_DEF_SMETHOD(user_config_dir, 0); + RG_DEF_SMETHOD(system_data_dirs, 0); + RG_DEF_SMETHOD(system_config_dirs, 0); +#if GLIB_CHECK_VERSION(2, 14, 0) + RG_DEF_SMETHOD(get_user_special_dir, 1); +#endif + RG_DEF_SMETHOD(home_dir, 0); + RG_DEF_SMETHOD(tmp_dir, 0); + RG_DEF_SMETHOD(current_dir, 0); + + RG_DEF_SMETHOD_P(path_is_absolute, 1); + RG_DEF_SMETHOD(path_skip_root, 1); + RG_DEF_SMETHOD(path_get_basename, 1); + RG_DEF_SMETHOD(path_get_dirname, 1); + RG_DEF_SMETHOD(find_program_in_path, 1); + RG_DEF_SMETHOD(bit_nth_lsf, 2); + RG_DEF_SMETHOD(bit_nth_msf, 2); + RG_DEF_SMETHOD(bit_storage, 1); + RG_DEF_SMETHOD(spaced_primes_closest, 1); + RG_DEF_SMETHOD(parse_debug_string, 2); + RG_DEF_SMETHOD_P(check_version, 3); + +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_win32.c (+112 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_win32.c 2017-02-15 13:19:47 +0900 (6e7f1ce) @@ -0,0 +1,112 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2006 Kouhei Sutou + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" +#include "rbglib.h" + +#ifdef G_OS_WIN32 + +#define RG_TARGET_NAMESPACE mWin32 + +static VALUE +rg_s_error_message(VALUE self, VALUE error) +{ + return CSTR2RVAL_FREE(g_win32_error_message(NUM2INT(error))); +} + +static VALUE +rg_s_locale(VALUE self) +{ + return CSTR2RVAL_FREE(g_win32_getlocale()); +} + +static VALUE +rbglib_m_win32_locale_deprecated(VALUE self) +{ + rb_warn("GLib.win32_locale() is deprecated. Use GLib::Win32.locale instead"); + return rg_s_locale(self); +} + +static VALUE +rg_s_version(VALUE self) +{ + return UINT2NUM(g_win32_get_windows_version()); +} + +static VALUE +rg_s_locale_filename_from_utf8(VALUE self, VALUE utf8_filename) +{ + return CSTR2RVAL_FREE(g_win32_locale_filename_from_utf8(RVAL2CSTR(utf8_filename))); +} + +static VALUE +rbglib_m_win32_locale_filename_from_utf8_deprecated(VALUE self, + VALUE utf8_filename) +{ + rb_warn("GLib.win32_locale_filename_from_utf8() is deprecated. Use GLib::Win32.locale_filename_from_utf8 instead"); + return rg_s_locale_filename_from_utf8(self, utf8_filename); +} + +# if GLIB_CHECK_VERSION(2, 16, 0) +static VALUE +rg_s_get_package_installation_directory_of_module(int argc, + VALUE *argv, + VALUE self) +{ + VALUE rb_module; + gchar *directory; + gpointer hmodule; + + rb_scan_args(argc, argv, "01", &rb_module); + if (NIL_P(rb_module)) + hmodule = NULL; + else + hmodule = GINT_TO_POINTER(NUM2INT(rb_module)); + + directory = g_win32_get_package_installation_directory_of_module(hmodule); + return CSTR2RVAL_FREE(directory); +} +# endif +#endif + +void +Init_glib_win32(void) +{ +#ifdef G_OS_WIN32 + /* glib/gwin32.h */ + VALUE RG_TARGET_NAMESPACE = rb_define_module_under(mGLib, "Win32"); + + RG_DEF_SMETHOD(error_message, 1); + RG_DEF_SMETHOD(locale, 0); + RG_DEF_SMETHOD(version, 0); + /* Deprecated */ + rbg_define_singleton_method(mGLib, "win32_locale", rbglib_m_win32_locale_deprecated, 0); + + RG_DEF_SMETHOD(locale_filename_from_utf8, 1); + /* Deprecated */ + rbg_define_singleton_method(mGLib, "win32_locale_filename_from_utf8", + rbglib_m_win32_locale_filename_from_utf8_deprecated, 1); + +# if GLIB_CHECK_VERSION(2, 16, 0) + RG_DEF_SMETHOD(get_package_installation_directory_of_module, -1); +# endif +#endif +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbglibdeprecated.c (+56 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbglibdeprecated.c 2017-02-15 13:19:47 +0900 (8b2e198) @@ -0,0 +1,56 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2002,2003 Masahiro Sakai + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" + +static VALUE +rbg_filename_gslist_to_array_free_body(VALUE list) +{ + VALUE ary = rb_ary_new(); + GSList *p; + + for (p = (GSList *)list; p != NULL; p = g_slist_next(p)) + rb_ary_push(ary, CSTRFILENAME2RVAL(p->data)); + + return ary; +} + +static VALUE +rbg_filename_gslist_to_array_free_ensure(VALUE val) +{ + GSList *list = (GSList *)val; + GSList *p; + + for (p = list; p != NULL; p = g_slist_next(p)) + g_free((gchar *)p->data); + + g_slist_free(list); + + return Qnil; +} + +VALUE +rbg_filename_gslist_to_array_free(GSList *list) +{ + return rb_ensure(rbg_filename_gslist_to_array_free_body, (VALUE)list, + rbg_filename_gslist_to_array_free_ensure, (VALUE)list); +} + Added: binding/ruby/glib-3.1.1/ext/glib2/rbglibdeprecated.h (+34 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbglibdeprecated.h 2017-02-15 13:19:47 +0900 (2315002) @@ -0,0 +1,34 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2002-2005 Ruby-GNOME2 Project + * Copyright (C) 2002,2003 Masahiro Sakai + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef __RBGLIBDEPRECATED_H__ +#define __RBGLIBDEPRECATED_H__ + +G_BEGIN_DECLS + +#define CSTRFILENAMEARRAY2RVAL_FREE(s) (rbg_filename_gslist_to_array_free(s)) + +extern VALUE rbg_filename_gslist_to_array_free(GSList *list); + +G_END_DECLS + +#endif /* __RBGLIBDEPRECATED_H__ */ Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobj_binding.c (+48 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbgobj_binding.c 2017-02-15 13:19:47 +0900 (2ef82bc) @@ -0,0 +1,48 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2015 Ruby-GNOME2 Project Team + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" + +#define RG_TARGET_NAMESPACE cBinding + +#define _SELF(object) G_BINDING(RVAL2GOBJ(self)) + +#if GLIB_CHECK_VERSION(2, 38, 0) +static VALUE +rg_unbind(VALUE self) +{ + g_binding_unbind(_SELF(self)); + return self; +} +#endif + +void +Init_gobject_gbinding(void) +{ +#if GLIB_CHECK_VERSION(2, 26, 0) + VALUE RG_TARGET_NAMESPACE; + + RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_BINDING, "Binding", mGLib); +#endif + +#if GLIB_CHECK_VERSION(2, 38, 0) + RG_DEF_METHOD(unbind, 0); +#endif +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobj_boxed.c (+299 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbgobj_boxed.c 2017-02-15 13:19:47 +0900 (643081c) @@ -0,0 +1,299 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011-2013 Ruby-GNOME2 Project Team + * Copyright (C) 2002,2003 Masahiro Sakai + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" + +#define RG_TARGET_NAMESPACE rbgobj_cBoxed + +VALUE RG_TARGET_NAMESPACE; + +static void +boxed_mark(boxed_holder *holder) +{ + const RGObjClassInfo *cinfo; + + cinfo = GTYPE2CINFO_NO_CREATE(holder->type); + if (cinfo && cinfo->mark) + cinfo->mark(holder->boxed); +} + +static void +boxed_free(boxed_holder *holder) +{ + const RGObjClassInfo *cinfo; + + cinfo = GTYPE2CINFO_NO_CREATE(holder->type); + if (cinfo && cinfo->free) + cinfo->free(holder->boxed); + + if (holder->own && holder->boxed) + g_boxed_free(holder->type, holder->boxed); + + xfree(holder); +} + +/**********************************************************************/ + +static VALUE +rbgobj_boxed_s_allocate(VALUE klass) +{ + const RGObjClassInfo *cinfo = rbgobj_lookup_class(klass); + boxed_holder *holder; + VALUE result; + + if (cinfo->gtype == G_TYPE_BOXED) + rb_raise(rb_eTypeError, "abstract class"); + + result = Data_Make_Struct(klass, boxed_holder, + boxed_mark, boxed_free, holder); + holder->type = cinfo->gtype; + holder->boxed = NULL; + holder->own = FALSE; + + return result; +} + +static VALUE +rg_initialize(VALUE self) +{ + VALUE rb_class; + gsize instance_size = 0; + + rb_class = CLASS_OF(self); + if (RVAL2CBOOL(rb_ivar_defined(rb_class, rb_intern("@size")))) { + instance_size = NUM2UINT(rb_iv_get(rb_class, "@size")); + } + + if (instance_size > 0) { + const RGObjClassInfo *cinfo; + gpointer instance; + + cinfo = rbgobj_lookup_class(rb_class); + instance = alloca(instance_size); + memset(instance, 0, instance_size); + G_INITIALIZE(self, g_boxed_copy(cinfo->gtype, instance)); + } else { + rb_raise(rb_eTypeError, "can't initialize %s", + rb_class2name(rb_class)); + } + + return Qnil; +} + +static VALUE +rg_inspect(VALUE self) +{ + boxed_holder *holder; + gchar *s; + VALUE result; + + Data_Get_Struct(self, boxed_holder, holder); + + s = g_strdup_printf("#<%s:%p ptr=%p own=%s>", + rb_class2name(CLASS_OF(self)), + (void *)self, + holder->boxed, + holder->own ? "true" : "false"); + + result = rb_str_new2(s); + g_free(s); + + return result; +} + +static VALUE +rg_initialize_copy(VALUE self, VALUE orig) +{ + boxed_holder *holder1; + boxed_holder *holder2; + + if (self == orig) return self; + + if (!rb_obj_is_instance_of(orig, rb_obj_class(self))) { + rb_raise(rb_eTypeError, "wrong argument class"); + } + + Data_Get_Struct(self, boxed_holder, holder1); + Data_Get_Struct(orig, boxed_holder, holder2); + + holder1->boxed = g_boxed_copy(holder2->type, holder2->boxed); + holder1->own = TRUE; + + if (!holder1->boxed) + rb_raise(rb_eRuntimeError, "g_boxed_copy() failed"); + + return self; +} + +/* deprecated */ +VALUE +rbgobj_boxed_create(VALUE klass) +{ + return rbgobj_boxed_s_allocate(klass); +} + +/**********************************************************************/ + +void +rbgobj_boxed_initialize(VALUE obj, gpointer boxed) +{ + boxed_holder *holder; + Data_Get_Struct(obj, boxed_holder, holder); + holder->boxed = boxed; + holder->own = TRUE; +} + +gpointer +rbgobj_boxed_get_default(VALUE obj, GType gtype) +{ + boxed_holder *holder; + + if (!RVAL2CBOOL(rb_obj_is_kind_of(obj, GTYPE2CLASS(gtype)))) + rb_raise(rb_eArgError, "invalid argument %s (expect %s)", + rb_class2name(CLASS_OF(obj)), + rb_class2name(GTYPE2CLASS(gtype))); + + Data_Get_Struct(obj, boxed_holder, holder); + if (!holder->boxed) + rb_raise(rb_eArgError, "uninitialize %s", rb_class2name(CLASS_OF(obj))); + + return holder->boxed; +} + +gpointer +rbgobj_boxed_get(VALUE obj, GType gtype) +{ + gpointer boxed = NULL; + + if (NIL_P(obj)) + return NULL; + + if (rbgobj_convert_robj2instance(gtype, obj, &boxed)) { + return boxed; + } + + return rbgobj_boxed_get_default(obj, gtype); +} + +VALUE +rbgobj_make_boxed_raw(gpointer p, GType gtype, VALUE klass, gint flags) +{ + VALUE result; + boxed_holder *holder; + + result = rbgobj_boxed_s_allocate(klass); + + Data_Get_Struct(result, boxed_holder, holder); + + if (flags & RBGOBJ_BOXED_NOT_COPY) { + holder->boxed = p; + holder->own = FALSE; + } else { + holder->boxed = g_boxed_copy(gtype, p); + holder->own = TRUE; + } + + return result; +} + +VALUE +rbgobj_make_boxed_default(gpointer p, GType gtype) +{ + const RGObjClassInfo *cinfo; + + cinfo = GTYPE2CINFO(gtype); + return rbgobj_make_boxed_raw(p, gtype, cinfo->klass, cinfo->flags); +} + +VALUE +rbgobj_make_boxed(gpointer p, GType gtype) +{ + VALUE result; + + if (!p) + return Qnil; + + if (rbgobj_convert_instance2robj(gtype, p, &result)) { + return result; + } + + return rbgobj_make_boxed_default(p, gtype); +} + +void +rbgobj_boxed_not_copy_obj(GType gtype) +{ + RGObjClassInfo *cinfo = (RGObjClassInfo *)GTYPE2CINFO(gtype); + cinfo->flags |= RBGOBJ_BOXED_NOT_COPY; +} + +void +rbgobj_boxed_unown(VALUE boxed) +{ + boxed_holder *holder; + + Data_Get_Struct(boxed, boxed_holder, holder); + + if (!holder->own) { + rb_raise(rb_eArgError, + "The boxed is already unowned: %p", + boxed); + } + + holder->own = FALSE; +} + +/**********************************************************************/ + +static VALUE +boxed_to_ruby(const GValue *from) +{ + gpointer boxed; + boxed = g_value_get_boxed(from); + return rbgobj_make_boxed(boxed, G_VALUE_TYPE(from)); +} + +static void +boxed_from_ruby(VALUE from, GValue *to) +{ + gpointer boxed; + boxed = rbgobj_boxed_get(from, G_VALUE_TYPE(to)); + g_value_set_boxed(to, boxed); +} + +/**********************************************************************/ + +void +Init_gobject_gboxed(void) +{ + RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_BOXED, "Boxed", mGLib); + + rbgobj_register_g2r_func(G_TYPE_BOXED, boxed_to_ruby); + rbgobj_register_r2g_func(G_TYPE_BOXED, boxed_from_ruby); + + rb_define_alloc_func(RG_TARGET_NAMESPACE, (VALUE(*)_((VALUE)))rbgobj_boxed_s_allocate); + rbg_define_singleton_method(RG_TARGET_NAMESPACE, "gtype", generic_s_gtype, 0); + rbg_define_method(RG_TARGET_NAMESPACE, "gtype", generic_gtype, 0); + RG_DEF_METHOD(initialize, 0); + RG_DEF_METHOD(inspect, 0); + RG_DEF_METHOD(initialize_copy, 1); + RG_DEF_ALIAS("copy", "dup"); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobj_closure.c (+382 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbgobj_closure.c 2017-02-15 13:19:47 +0900 (bbf3b28) @@ -0,0 +1,382 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011-2016 Ruby-GNOME2 Project Team + * Copyright (C) 2002-2006 Ruby-GNOME2 Project + * Copyright (C) 2002,2003 Masahiro Sakai + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" + +#define RG_TARGET_NAMESPACE cClosure + +static ID id_call, id_closures; +static gboolean rclosure_initialized = FALSE; + +#define TAG_SIZE 64 +typedef struct _GRClosure GRClosure; +struct _GRClosure +{ + GClosure closure; + VALUE callback; + VALUE extra_args; + VALUE rb_holder; + gint count; + GList *objects; + GValToRValSignalFunc g2r_func; + RGClosureCallFunc call_func; + gchar tag[TAG_SIZE]; +}; + +static VALUE +rclosure_default_g2r_func(guint num, const GValue *values) +{ + guint i; + VALUE args = rb_ary_new2(num); + for (i = 0; i < num; i++) + rb_ary_store(args, i, GVAL2RVAL(&values[i])); + return args; +} + +struct marshal_arg +{ + GClosure* closure; + GValue* return_value; + guint n_param_values; + const GValue* param_values; + gpointer invocation_hint; + gpointer marshal_data; +}; + +static int +rclosure_alive_p(GRClosure *rclosure) +{ + return (rclosure->count > 0 && !NIL_P(rclosure->rb_holder)); +} + +static VALUE +rclosure_marshal_do(VALUE arg_) +{ + VALUE ret = Qnil; + struct marshal_arg *arg; + GRClosure *rclosure; + GValue *return_value; + + arg = (struct marshal_arg *)arg_; + rclosure = (GRClosure *)(arg->closure); + return_value = arg->return_value; + + if (rclosure_alive_p(rclosure)) { + guint n_param_values; + const GValue *param_values; + /* gpointer invocation_hint;*/ + /* gpointer marshal_data; */ + GValToRValSignalFunc g2r_func; + VALUE callback; + VALUE extra_args; + VALUE args; + + n_param_values = arg->n_param_values; + param_values = arg->param_values; + /* invocation_hint = arg->invocation_hint; */ + /* marshal_data = arg->marshal_data; */ + + callback = rclosure->callback; + extra_args = rclosure->extra_args; + + if (rclosure->call_func) { + RGClosureCallData data; + data.return_value = return_value; + data.n_param_values = n_param_values; + data.param_values = param_values; + data.callback = callback; + data.extra_args = extra_args; + rclosure->call_func(&data); + return Qnil; + } + + if (rclosure->g2r_func) { + g2r_func = (GValToRValSignalFunc)rclosure->g2r_func; + } else { + g2r_func = (GValToRValSignalFunc)rclosure_default_g2r_func; + } + args = (*g2r_func)(n_param_values, param_values); + + if (!NIL_P(extra_args)) { + args = rb_ary_concat(args, extra_args); + } + + ret = rb_apply(callback, id_call, args); + } else { + rb_warn("GRClosure invoking callback: already destroyed: %s", + rclosure->tag[0] ? rclosure->tag : "(anonymous)"); + } + + if (return_value && G_VALUE_TYPE(return_value)) + rbgobj_rvalue_to_gvalue(ret, return_value); + + return Qnil; +} + +static void +rclosure_marshal(GClosure* closure, + GValue* return_value, + guint n_param_values, + const GValue* param_values, + gpointer invocation_hint, + gpointer marshal_data) +{ + struct marshal_arg arg; + + if (!rclosure_initialized) { + g_closure_invalidate(closure); + return; + } + + arg.closure = closure; + arg.return_value = return_value; + arg.n_param_values = n_param_values; + arg.param_values = param_values; + arg.invocation_hint = invocation_hint; + arg.marshal_data = marshal_data; + + G_PROTECT_CALLBACK(rclosure_marshal_do, &arg); +} + +static void rclosure_weak_notify(gpointer data, GObject* where_the_object_was); + +static void +rclosure_unref(GRClosure *rclosure) +{ + rclosure->count--; + + if (!rclosure_alive_p(rclosure)) { + GList *next; + for (next = rclosure->objects; next; next = next->next) { + GObject *object = G_OBJECT(next->data); + g_object_weak_unref(object, rclosure_weak_notify, rclosure); + } + g_list_free(rclosure->objects); + rclosure->objects = NULL; + if (!NIL_P(rclosure->rb_holder)) { + DATA_PTR(rclosure->rb_holder) = NULL; + rclosure->rb_holder = Qnil; + } + } +} + +static void +rclosure_invalidate(G_GNUC_UNUSED gpointer data, GClosure *closure) +{ + GRClosure *rclosure = (GRClosure*)closure; + + if (rclosure->count > 0) { + GList *next; + + rclosure->count = 1; + for (next = rclosure->objects; next; next = next->next) { + GObject *object = G_OBJECT(next->data); + VALUE obj = rbgobj_ruby_object_from_instance2(object, FALSE); + if (!NIL_P(rclosure->rb_holder) && !NIL_P(obj)) + G_REMOVE_RELATIVE(obj, id_closures, rclosure->rb_holder); + } + + rclosure_unref(rclosure); + } +} + +static void +gr_closure_holder_mark(GRClosure *rclosure) +{ + if (!rclosure) + return; + + rb_gc_mark(rclosure->callback); + rb_gc_mark(rclosure->extra_args); +} + +static void +gr_closure_holder_free(GRClosure *rclosure) +{ + if (!rclosure) + return; + + if (rclosure->count > 0) { + rclosure->count = 1; + + /* No need to remove us from the relatives hash of our objects, as + * those aren't alive anymore anyway */ + rclosure_unref(rclosure); + } +} + +static GClosure * +g_rclosure_new_raw(VALUE callback_proc, + VALUE extra_args, + GValToRValSignalFunc g2r_func, + RGClosureCallFunc call_func) +{ + GRClosure* closure; + + closure = (GRClosure*)g_closure_new_simple(sizeof(GRClosure), NULL); + + closure->count = 1; + closure->g2r_func = g2r_func; + closure->call_func = call_func; + closure->objects = NULL; + closure->callback = callback_proc; + closure->extra_args = extra_args; + closure->rb_holder = Data_Wrap_Struct(rb_cData, + gr_closure_holder_mark, + gr_closure_holder_free, + closure); + closure->tag[0] = '\0'; + + g_closure_set_marshal((GClosure*)closure, &rclosure_marshal); + g_closure_add_invalidate_notifier((GClosure*)closure, NULL, + &rclosure_invalidate); + + return (GClosure*)closure; +} + +GClosure * +g_rclosure_new(VALUE callback_proc, + VALUE extra_args, + GValToRValSignalFunc g2r_func) +{ + return g_rclosure_new_raw(callback_proc, extra_args, g2r_func, NULL); +} + +GClosure * +g_rclosure_new_call(VALUE callback_proc, + VALUE extra_args, + RGClosureCallFunc call_func) +{ + return g_rclosure_new_raw(callback_proc, + extra_args, + NULL, + call_func); +} + +static void +rclosure_weak_notify(gpointer data, GObject* where_the_object_was) +{ + GRClosure *rclosure = data; + if (rclosure_alive_p(rclosure)) { + rclosure->objects = + g_list_remove(rclosure->objects, where_the_object_was); + rclosure_unref(rclosure); + } +} + +void +g_rclosure_attach(GClosure *closure, VALUE object) +{ + static VALUE mGLibObject = (VALUE)NULL; + GRClosure *rclosure = (GRClosure *)closure; + + G_RELATIVE2(object, Qnil, id_closures, rclosure->rb_holder); + + if (!mGLibObject) { + mGLibObject = rb_const_get(mGLib, rb_intern("Object")); + } + if (rb_obj_is_kind_of(object, mGLibObject)) { + GObject *gobject; + gobject = RVAL2GOBJ(object); + rclosure->count++; + g_object_weak_ref(gobject, rclosure_weak_notify, rclosure); + rclosure->objects = g_list_prepend(rclosure->objects, gobject); + } +} + +void +g_rclosure_set_tag(GClosure *closure, const gchar *tag) +{ + GRClosure *rclosure = (GRClosure *)closure; + + if (tag) { + strncpy(rclosure->tag, tag, TAG_SIZE); + rclosure->tag[TAG_SIZE - 1] = '\0'; + } else { + rclosure->tag[0] = '\0'; + } +} + +static void +rclosure_end_proc(G_GNUC_UNUSED VALUE _) +{ + rclosure_initialized = FALSE; +} + +static void +init_rclosure(void) +{ + id_call = rb_intern("call"); + id_closures = rb_intern("closures"); + rclosure_initialized = TRUE; + rb_set_end_proc(rclosure_end_proc, Qnil); +} + +/**********************************************************************/ + +static VALUE +rg_initialize(VALUE self) +{ + GClosure* closure = g_rclosure_new(rb_block_proc(), Qnil, NULL); + G_INITIALIZE(self, closure); + g_closure_sink(closure); + return self; +} + +static VALUE +rg_in_marshal_p(VALUE self) +{ + GClosure* closure = RVAL2BOXED(self, G_TYPE_CLOSURE); + return CBOOL2RVAL(closure->in_marshal); +} + +static VALUE +rg_invalid_p(VALUE self) +{ + GClosure* closure = RVAL2BOXED(self, G_TYPE_CLOSURE); + return CBOOL2RVAL(closure->is_invalid); +} + +static VALUE +rg_invalidate(VALUE self) +{ + GClosure* closure = RVAL2BOXED(self, G_TYPE_CLOSURE); + g_closure_invalidate(closure); + return self; +} + +/**********************************************************************/ + +void +Init_gobject_gclosure(void) +{ + VALUE RG_TARGET_NAMESPACE; + + init_rclosure(); + + RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_CLOSURE, "Closure", mGLib); + + RG_DEF_METHOD(initialize, 0); + RG_DEF_METHOD_P(in_marshal, 0); + RG_DEF_METHOD_P(invalid, 0); + RG_DEF_METHOD(invalidate, 0); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobj_convert.c (+195 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbgobj_convert.c 2017-02-15 13:19:47 +0900 (fcde0e8) @@ -0,0 +1,195 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011-2014 Ruby-GNOME2 Project Team + * Copyright (C) 2006 Sjoerd Simons, Masao Mutoh + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgobject.h" +#include "rbgprivate.h" + +static GHashTable *tables, *class_to_g_type_map; + +static void +rg_convert_table_free(gpointer data) +{ + RGConvertTable *table = data; + + if (table->notify) { + table->notify(table->user_data); + } + g_free(table); +} + +void +Init_gobject_convert(void) +{ + /* TODO: unref the below tables on exit. */ + tables = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, + rg_convert_table_free); + class_to_g_type_map = g_hash_table_new(g_direct_hash, g_direct_equal); +} + +void +rbgobj_convert_define(const RGConvertTable *table) +{ + RGConvertTable *copied_table; + copied_table = g_memdup(table, sizeof(RGConvertTable)); + g_hash_table_insert(tables, + GUINT_TO_POINTER(copied_table->type), + copied_table); + if (copied_table->klass != Qfalse && !NIL_P(copied_table->klass)) { + g_hash_table_insert(class_to_g_type_map, + GUINT_TO_POINTER(copied_table->klass), + GUINT_TO_POINTER(copied_table->type)); + } +} + +RGConvertTable * +rbgobj_convert_lookup(GType type) +{ + return g_hash_table_lookup(tables, GUINT_TO_POINTER(type)); +} + +gboolean +rbgobj_convert_has_type(GType type) +{ + return rbgobj_convert_lookup(type) != NULL; +} + +gboolean +rbgobj_convert_get_superclass(GType type, VALUE *result) +{ + RGConvertTable *table; + + table = rbgobj_convert_lookup(type); + if (table && table->get_superclass) { + *result = table->get_superclass(table->user_data); + return TRUE; + } + + return FALSE; +} + +gboolean +rbgobj_convert_type_init_hook(GType type, VALUE klass) +{ + RGConvertTable *table; + + table = rbgobj_convert_lookup(type); + if (table && table->type_init_hook) { + table->type_init_hook(klass, table->user_data); + return TRUE; + } + + return FALSE; +} + +gboolean +rbgobj_convert_rvalue2gvalue(GType type, VALUE value, GValue *result) +{ + RGConvertTable *table; + + table = rbgobj_convert_lookup(type); + if (table && table->rvalue2gvalue) { + table->rvalue2gvalue(value, result, table->user_data); + return TRUE; + } + + return FALSE; +} + +gboolean +rbgobj_convert_gvalue2rvalue(GType type, const GValue *value, VALUE *result) +{ + RGConvertTable *table; + + table = rbgobj_convert_lookup(type); + if (table && table->gvalue2rvalue) { + *result = table->gvalue2rvalue(value, table->user_data); + return TRUE; + } + + return FALSE; +} + +GType +rbgobj_convert_rvalue2gtype(VALUE value) +{ + VALUE klass; + gpointer result; + + klass = rb_class_of(value); + result = g_hash_table_lookup(class_to_g_type_map, GUINT_TO_POINTER(klass)); + return GPOINTER_TO_UINT(result); +} + +gboolean +rbgobj_convert_initialize(GType type, VALUE obj, gpointer cobj) +{ + RGConvertTable *table; + + table = rbgobj_convert_lookup(type); + if (table && table->initialize) { + table->initialize(obj, cobj, table->user_data); + return TRUE; + } + + return FALSE; +} + +gboolean +rbgobj_convert_robj2instance(GType type, VALUE obj, gpointer *result) +{ + RGConvertTable *table; + + table = rbgobj_convert_lookup(type); + if (table && table->robj2instance) { + *result = table->robj2instance(obj, table->user_data); + return TRUE; + } + + return FALSE; +} + +gboolean +rbgobj_convert_instance2robj(GType type, gpointer instance, VALUE *result) +{ + RGConvertTable *table; + + table = rbgobj_convert_lookup(type); + if (table && table->instance2robj) { + *result = table->instance2robj(instance, table->user_data); + return TRUE; + } + + return FALSE; +} + +gboolean +rbgobj_convert_unref(GType type, gpointer instance) +{ + RGConvertTable *table; + + table = rbgobj_convert_lookup(type); + if (table && table->unref) { + table->unref(instance, table->user_data); + return TRUE; + } + + return FALSE; +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobj_enumflags.c (+109 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbgobj_enumflags.c 2017-02-15 13:19:47 +0900 (3dd40ad) @@ -0,0 +1,109 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2004-2006 Ruby-GNOME2 Project Team + * Copyright (C) 2002,2003 Masahiro Sakai + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" +#include <ctype.h> + +typedef struct { + char *original; + char *replacement; +} constant_map; + +static GSList *rbgobj_cmap = NULL; + +static gint +rbgobj_constant_find(constant_map *a, char *name) +{ + return strcmp(a->original, name); +} + +void +rbgobj_constant_remap(const char *original, const char *replacement) +{ + constant_map *map = g_new(constant_map,1); + + map->original = g_strdup(original); + map->replacement = g_strdup(replacement); + + rbgobj_cmap = g_slist_append(rbgobj_cmap, map); +} + +char * +rg_obj_constant_lookup(const char *name) +{ + GSList *p = rbgobj_cmap; + + p = g_slist_find_custom(rbgobj_cmap, name, + (GCompareFunc)rbgobj_constant_find); + if (p) { + char *replacement; + constant_map *map; + + map = (constant_map *)p->data; + rbgobj_cmap = g_slist_delete_link(rbgobj_cmap, p); + replacement = map->replacement; + + g_free(map->original); + g_free(map); + + return replacement; + } + + return NULL; +} + +void +rbgobj_define_const(VALUE mod, const char *name, + VALUE value) +{ + if (name[0] >= 'A' && name[0] <= 'Z') { + rb_define_const(mod, name, value); + } else { + char *new_name = rg_obj_constant_lookup(name); + + if (new_name) { + rb_define_const(mod, new_name, value); + g_free(new_name); + } else { + rb_warn("Invalid constant name '%s' - skipped", name); + } + } +} + +void +rbgobj_add_constants(VALUE mod, GType type, const gchar *strip_prefix) +{ + if (G_TYPE_IS_ENUM(type)) { + rg_enum_add_constants(mod, type, strip_prefix); + } else if (G_TYPE_IS_FLAGS(type)) { + rg_flags_add_constants(mod, type, strip_prefix); + } else { + g_warning("`%s' is not an enum/flags type", g_type_name(type)); + } +} + +void +Init_gobject_genumflags(void) +{ + Init_gobject_genums(); + Init_gobject_gflags(); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobj_enums.c (+444 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbgobj_enums.c 2017-02-15 13:19:47 +0900 (d5378d9) @@ -0,0 +1,444 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2004-2006 Ruby-GNOME2 Project Team + * Copyright (C) 2002,2003 Masahiro Sakai + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" +#include <ctype.h> + +#define RG_TARGET_NAMESPACE rbgobj_cEnum + +VALUE RG_TARGET_NAMESPACE; + +static ID id_new; +static ID id_to_s; +static ID id_to_i; + +/**********************************************************************/ + +static gchar * +nick_to_const_name(const gchar *nick) +{ + gchar *const_name; + gchar *p; + + if (!nick) + return NULL; + + const_name = g_strdup(nick); + for (p = const_name; *p; p++) { + if (*p == '-' || *p == ' ') + *p = '_'; + else + *p = g_ascii_toupper(*p); + } + return const_name; +} + +VALUE +rg_enum_resolve_value(VALUE klass, VALUE nick) +{ + VALUE value = Qnil; + gchar *const_nick; + ID const_nick_id; + + if (RVAL2CBOOL(rb_obj_is_kind_of(nick, klass))) + return nick; + + nick = rb_funcall(nick, id_to_s, 0); + const_nick = nick_to_const_name(RVAL2CSTR(nick)); + const_nick_id = rb_intern(const_nick); + if (rb_const_defined(klass, const_nick_id)) { + value = rb_const_get(klass, const_nick_id); + } + g_free(const_nick); + + return value; +} + +void +rg_enum_add_constants(VALUE mod, GType enum_type, const gchar *strip_prefix) +{ + GEnumClass *gclass; + guint i; + int prefix_len = strlen(strip_prefix); + + gclass = G_ENUM_CLASS(g_type_class_ref(enum_type)); + + for (i = 0; i < gclass->n_values; i++) { + const GEnumValue* value = &gclass->values[i]; + + if (strncmp(value->value_name, strip_prefix, prefix_len)) { + g_warning("\"%s\" doesn't have prefix \"%s\"", + value->value_name, strip_prefix); + } else { + const char* name = value->value_name + prefix_len; + rbgobj_define_const(mod, name, + rbgobj_make_enum(value->value, enum_type)); + } + } + + g_type_class_unref(gclass); +} + +/**********************************************************************/ + +typedef struct { + GEnumClass* gclass; + gint value; + GEnumValue* info; +} enum_holder; + +static void +enum_free(enum_holder* p) +{ + g_type_class_unref(p->gclass); + free(p); +} + +static enum_holder* +enum_get_holder(VALUE obj) +{ + enum_holder* p; + Data_Get_Struct(obj, enum_holder, p); + return p; +} + +static VALUE +make_enum(gint n, VALUE klass) +{ + return rb_funcall(klass, id_new, 1, INT2NUM(n)); +} + +VALUE +rbgobj_make_enum(gint n, GType gtype) +{ + return make_enum(n, GTYPE2CLASS(gtype)); +} + +gint +rbgobj_get_enum(VALUE obj, GType gtype) +{ + VALUE klass; + + if (!g_type_is_a(gtype, G_TYPE_ENUM)) + rb_raise(rb_eTypeError, "%s is not a %s: %s", + g_type_name(gtype), g_type_name(G_TYPE_ENUM), + RBG_INSPECT(obj)); + + /* for compatibility */ + if (rb_obj_is_kind_of(obj, rb_cInteger)) + obj = rbgobj_make_enum(NUM2INT(obj), gtype); + + klass = GTYPE2CLASS(gtype); + + if (!rb_obj_is_kind_of(obj, klass)) { + VALUE enum_value; + + enum_value = rg_enum_resolve_value(klass, obj); + if (!NIL_P(enum_value)) + obj = enum_value; + } + + if (rb_obj_is_kind_of(obj, klass)) + return enum_get_holder(obj)->value; + else + rb_raise(rb_eTypeError, "not a %s: %s", + rb_class2name(klass), RBG_INSPECT(obj)); +} + +/**********************************************************************/ + +void +rbgobj_init_enum_class(VALUE klass) +{ + GEnumClass* gclass = g_type_class_ref(CLASS2GTYPE(klass)); + guint i; + + for (i = 0; i < gclass->n_values; i++) { + GEnumValue* entry = &(gclass->values[i]); + gchar *const_nick_name; + + const_nick_name = nick_to_const_name(entry->value_nick); + +#if 0 + { + ID id = rb_intern(const_nick_name); + if (rb_is_const_id(id)) { + VALUE value; + + value = make_enum(entry->value, klass); + rb_define_const(klass, const_nick_name, value); + } + } +#else + { + if (const_nick_name) { + VALUE value; + + value = make_enum(entry->value, klass); + rbgobj_define_const(klass, const_nick_name, value); + } + } +#endif + + g_free(const_nick_name); + } + + g_type_class_unref(gclass); +} + +static VALUE +rg_s_range(VALUE self) +{ + GEnumClass* gclass = g_type_class_ref(CLASS2GTYPE(self)); + VALUE result = rb_range_new(INT2NUM(gclass->minimum), + INT2NUM(gclass->maximum), + FALSE); + g_type_class_unref(gclass); + return result; +} + +struct enum_s_values_body_args { + GEnumClass *gclass; + VALUE self; +}; + +static VALUE +enum_s_values_body(VALUE value) +{ + struct enum_s_values_body_args *args = (struct enum_s_values_body_args *)value; + VALUE result = rb_ary_new(); + guint i; + + for (i = 0; i < args->gclass->n_values; i++) + rb_ary_push(result, make_enum(args->gclass->values[i].value, args->self)); + + return result; +} + +static VALUE +enum_s_values_ensure(VALUE gclass) +{ + g_type_class_unref((GEnumClass *)gclass); + + return Qnil; +} + +static VALUE +rg_s_values(VALUE self) +{ + struct enum_s_values_body_args args = { + g_type_class_ref(CLASS2GTYPE(self)), + self + }; + + return rb_ensure(enum_s_values_body, (VALUE)&args, + enum_s_values_ensure, (VALUE)args.gclass); +} + +static VALUE +enum_s_allocate(VALUE self) +{ + GType gtype = CLASS2GTYPE(self); + + if (G_TYPE_IS_ABSTRACT(gtype)) { + rb_raise(rb_eTypeError, "abstract class"); + } else { + enum_holder* p; + VALUE result = Data_Make_Struct(self, enum_holder, NULL, enum_free, p); + p->gclass = g_type_class_ref(gtype); + p->info = NULL; + return result; + } +} + +static VALUE +rg_initialize(int argc, VALUE *argv, VALUE self) +{ + enum_holder* p = enum_get_holder(self); + VALUE rb_value; + VALUE klass; + + rb_scan_args(argc, argv, "01", &rb_value); + + klass = CLASS_OF(self); + + switch (TYPE(rb_value)) { + case RUBY_T_NIL: + p->value = 0; + break; + case RUBY_T_FIXNUM: + p->value = NUM2UINT(rb_value); + break; + case RUBY_T_STRING: + case RUBY_T_SYMBOL: + { + const gchar *name; + + name = RVAL2CSTR_ACCEPT_SYMBOL(rb_value); + p->info = g_enum_get_value_by_name(p->gclass, name); + if (!p->info) { + gchar *nick; + nick = rbg_name_to_nick(name); + p->info = g_enum_get_value_by_nick(p->gclass, nick); + g_free(nick); + } + if (!p->info) { + rb_raise(rb_eArgError, "unknown enum name: <%s>(%s)", + name, + g_type_name(G_TYPE_FROM_CLASS(p->gclass))); + } + p->value = p->info->value; + break; + } + default: + if (RVAL2CBOOL(rb_obj_is_kind_of(rb_value, klass))) { + p->value = NUM2INT(rb_funcall(rb_value, id_to_i, 0)); + } else { + rb_raise(rb_eArgError, + "enum value must be one of " + "nil, Fixnum, String, Symbol o %s: " + "<%s>(%s)", + RBG_INSPECT(klass), + RBG_INSPECT(rb_value), + g_type_name(G_TYPE_FROM_CLASS(p->gclass))); + } + break; + } + + if (!p->info) { + p->info = g_enum_get_value(p->gclass, p->value); + } + + return Qnil; +} + +static VALUE +rg_to_i(VALUE self) +{ + enum_holder* p = enum_get_holder(self); + return INT2NUM(p->value); +} + +static VALUE +rg_name(VALUE self) +{ + enum_holder* p = enum_get_holder(self); + return p->info ? rb_str_new2(p->info->value_name) : Qnil; +} + +static VALUE +rg_nick(VALUE self) +{ + enum_holder* p = enum_get_holder(self); + return p->info ? rb_str_new2(p->info->value_nick) : Qnil; +} + +static VALUE +rg_inspect(VALUE self) +{ + const char* cname = rb_class2name(CLASS_OF(self)); + enum_holder* p = enum_get_holder(self); + gchar* str; + VALUE result; + + if (p->info) + str = g_strdup_printf("#<%s %s>", + cname, p->info->value_nick); + else + str = g_strdup_printf("#<%s %d>", + cname, p->value); + result = rb_str_new2(str); + g_free(str); + + return result; +} + +static VALUE +rg_operator_enum_eqv(VALUE self, VALUE rhs) +{ + enum_holder* p = enum_get_holder(self); + GType gtype = G_TYPE_FROM_CLASS(p->gclass); + VALUE klass = GTYPE2CLASS(gtype); + + if (!rb_obj_is_kind_of(rhs, rb_cInteger)) { + rhs = rg_enum_resolve_value(klass, rhs); + if (CLASS_OF(rhs) != CLASS_OF(self)) + return Qnil; + } + return CBOOL2RVAL(rbgobj_get_enum(self, gtype) == rbgobj_get_enum(rhs, gtype)); +} + +static VALUE +rg_hash(VALUE self) +{ + enum_holder* p = enum_get_holder(self); + return UINT2NUM(p->value ^ G_TYPE_FROM_CLASS(p->gclass)); +} + +static VALUE +rg_coerce(VALUE self, VALUE other) +{ + enum_holder *holder; + GType gtype; + + if (!rb_obj_is_kind_of(other, rb_cInteger)) + rb_raise(rb_eTypeError, "can't coerce"); + + holder = enum_get_holder(self); + gtype = G_TYPE_FROM_CLASS(holder->gclass); + other = rbgobj_make_enum(NUM2INT(other), gtype); + return rb_ary_new3(2, other, self); +} + +/**********************************************************************/ + +void +Init_gobject_genums(void) +{ + id_new = rb_intern("new"); + id_to_s = rb_intern("to_s"); + id_to_i = rb_intern("to_i"); + + RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_ENUM, "Enum", mGLib); + + rbg_define_singleton_method(RG_TARGET_NAMESPACE, "gtype", generic_s_gtype, 0); + rbg_define_method(RG_TARGET_NAMESPACE, "gtype", generic_gtype, 0); + + RG_DEF_SMETHOD(range, 0); + RG_DEF_SMETHOD(values, 0); + + rb_define_alloc_func(RG_TARGET_NAMESPACE, enum_s_allocate); + + RG_DEF_METHOD(initialize, -1); + RG_DEF_METHOD(to_i, 0); + RG_DEF_METHOD(name, 0); + RG_DEF_METHOD(nick, 0); + + RG_DEF_METHOD(inspect, 0); + RG_DEF_METHOD_OPERATOR("==", enum_eqv, 1); + RG_DEF_METHOD(hash, 0); + RG_DEF_ALIAS("eql?", "=="); + + /* for compatibility */ + RG_DEF_METHOD(coerce, 1); + RG_DEF_ALIAS("to_int", "to_i"); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobj_flags.c (+570 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbgobj_flags.c 2017-02-15 13:19:47 +0900 (557f1b6) @@ -0,0 +1,570 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2004-2015 Ruby-GNOME2 Project Team + * Copyright (C) 2002,2003 Masahiro Sakai + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" +#include <ctype.h> + +#define RG_TARGET_NAMESPACE rbgobj_cFlags + +VALUE RG_TARGET_NAMESPACE; + +static ID id_new; +static ID id_module_eval; +static ID id_or; +static ID id_to_i; + +/**********************************************************************/ + +void +rg_flags_add_constants(VALUE mod, GType flags_type, const gchar *strip_prefix) +{ + GFlagsClass *gclass; + guint i; + int prefix_len = strlen(strip_prefix); + + gclass = G_FLAGS_CLASS(g_type_class_ref(flags_type)); + + for (i = 0; i < gclass->n_values; i++) { + const GFlagsValue* value = &gclass->values[i]; + + if (strncmp(value->value_name, strip_prefix, prefix_len)) { + g_warning("\"%s\" doesn't have prefix \"%s\"", + value->value_name, strip_prefix); + } else { + const char* name = value->value_name + prefix_len; + rbgobj_define_const(mod, name, + rbgobj_make_flags(value->value, flags_type)); + + } + } + + g_type_class_unref(gclass); +} + +/**********************************************************************/ + +typedef struct { + GFlagsClass* gclass; + guint value; + GFlagsValue* info; +} flags_holder; + +static void +flags_free(flags_holder* p) +{ + g_type_class_unref(p->gclass); + free(p); +} + +static flags_holder* +flags_get_holder(VALUE obj) +{ + flags_holder* p; + Data_Get_Struct(obj, flags_holder, p); + return p; +} + +static VALUE +make_flags(guint n, VALUE klass) +{ + return rb_funcall(klass, id_new, 1, UINT2NUM(n)); +} + +VALUE +rbgobj_make_flags(guint n, GType gtype) +{ + return make_flags(n, GTYPE2CLASS(gtype)); +} + +guint +rbgobj_get_flags(VALUE obj, GType gtype) +{ + VALUE klass; + + if (!g_type_is_a(gtype, G_TYPE_FLAGS)) + rb_raise(rb_eTypeError, "%s is not a %s", + g_type_name(gtype), g_type_name(G_TYPE_FLAGS)); + + klass = GTYPE2CLASS(gtype); + + if (!RVAL2CBOOL(rb_obj_is_kind_of(obj, klass))) { + obj = rb_funcall(klass, id_new, 1, obj); + } + + return flags_get_holder(obj)->value; +} + +/**********************************************************************/ + +void +rbgobj_init_flags_class(VALUE klass) +{ + GFlagsClass* gclass = g_type_class_ref(CLASS2GTYPE(klass)); + GString* source = g_string_new(NULL); + guint i; + + for (i = 0; i < gclass->n_values; i++) { + GFlagsValue* entry = &(gclass->values[i]); + gchar* nick; + gchar* p; + gchar* replace_nick; + + replace_nick = rg_obj_constant_lookup(entry->value_nick); + if (replace_nick){ + nick = g_strdup(replace_nick); + } else { + nick = g_strdup(entry->value_nick); + } + + for (p = nick; *p; p++) + if (*p == '-' || *p == ' ') + *p = '_'; + else + *p = tolower(*p); + + g_string_append_printf( + source, + "def %s%s?; self >= self.class.new(%d); end\n", + g_ascii_isdigit(nick[0]) ? "_" : "", + nick, entry->value); + + for (p = nick; *p; p++) + *p = g_ascii_toupper(*p); + +#if 0 + { + ID id = rb_intern(nick); + if (rb_is_const_id(id)) { + rb_define_const(klass, nick, make_flags(entry->value, klass)); + } + } +#else + { + rbgobj_define_const(klass, nick, make_flags(entry->value, klass)); + } +#endif + + g_free(nick); + } + + rb_funcall(klass, id_module_eval, 3, + rb_str_new2(source->str), + rb_str_new2(__FILE__), + INT2NUM(__LINE__)); + g_string_free(source, TRUE); + + g_type_class_unref(gclass); +} + +static VALUE +rg_s_mask(VALUE klass) +{ + GFlagsClass* gclass = g_type_class_ref(CLASS2GTYPE(klass)); + VALUE result = UINT2NUM(gclass->mask); + g_type_class_unref(gclass); + return result; +} + +static VALUE +rg_s_values(VALUE klass) +{ + GFlagsClass *gclass; + VALUE result; + guint i; + + gclass = g_type_class_ref(CLASS2GTYPE(klass)); + result = rb_ary_new(); + for (i = 0; i < gclass->n_values; i++) { + GFlagsValue *p = &(gclass->values[i]); + rb_ary_push(result, make_flags(p->value, klass)); + } + g_type_class_unref(gclass); + + return result; +} + +static VALUE +flags_s_allocate(VALUE self) +{ + GType gtype = CLASS2GTYPE(self); + + if (G_TYPE_IS_ABSTRACT(gtype)) { + rb_raise(rb_eTypeError, "abstract class"); + } else { + flags_holder* p; + VALUE result = Data_Make_Struct(self, flags_holder, NULL, flags_free, p); + p->gclass = g_type_class_ref(gtype); + p->value = 0; + p->info = NULL; + return result; + } +} + +static guint +resolve_flags_value(VALUE klass, GFlagsClass *gclass, VALUE flag_or_flags) +{ + guint value = 0; + + switch (TYPE(flag_or_flags)) { + case RUBY_T_NIL: + value = 0; + break; + case RUBY_T_FIXNUM: + case RUBY_T_BIGNUM: + value = NUM2UINT(flag_or_flags); + break; + case RUBY_T_STRING: + case RUBY_T_SYMBOL: + { + const gchar *name; + GFlagsValue *info; + + name = RVAL2CSTR_ACCEPT_SYMBOL(flag_or_flags); + info = g_flags_get_value_by_name(gclass, name); + if (!info) { + gchar *nick; + nick = rbg_name_to_nick(name); + info = g_flags_get_value_by_nick(gclass, nick); + g_free(nick); + } + if (!info) { + rb_raise(rb_eArgError, + "unknown flag name: <%s>(%s)", + name, + g_type_name(G_TYPE_FROM_CLASS(gclass))); + } + value = info->value; + break; + } + case RUBY_T_ARRAY: + { + int i, n; + n = RARRAY_LEN(flag_or_flags); + for (i = 0; i < n; i++) { + value |= resolve_flags_value(klass, + gclass, + RARRAY_PTR(flag_or_flags)[i]); + } + break; + } + default: + if (RVAL2CBOOL(rb_obj_is_kind_of(flag_or_flags, klass))) { + value = NUM2UINT(rb_funcall(flag_or_flags, id_to_i, 0)); + } else { + rb_raise(rb_eArgError, + "flag value must be one of " + "nil, Fixnum, String, Symbol, %s or Array of them: " + "<%s>(%s)", + RBG_INSPECT(klass), + RBG_INSPECT(flag_or_flags), + g_type_name(G_TYPE_FROM_CLASS(gclass))); + } + break; + } + + return value; +} + +static VALUE +rg_initialize(int argc, VALUE* argv, VALUE self) +{ + flags_holder* p = flags_get_holder(self); + VALUE flag_or_flags; + + rb_scan_args(argc, argv, "01", &flag_or_flags); + + p->value = resolve_flags_value(CLASS_OF(self), p->gclass, flag_or_flags); + + if (!p->info) { + guint i; + for (i = 0; i < p->gclass->n_values; i++){ + GFlagsValue* val = &(p->gclass->values[i]); + if (val->value == p->value){ + p->info = val; + break; + } + } + } + + return Qnil; +} + +static VALUE +rg_to_i(VALUE self) +{ + flags_holder* p = flags_get_holder(self); + return UINT2NUM(p->value); +} + +static VALUE +rg_name(VALUE self) +{ + flags_holder* p = flags_get_holder(self); + return p->info ? rb_str_new2(p->info->value_name) : Qnil; +} + +static VALUE +rg_nick(VALUE self) +{ + flags_holder* p = flags_get_holder(self); + return p->info ? rb_str_new2(p->info->value_nick) : Qnil; +} + +#define FLAGS_COMP_EQUAL 0 +#define FLAGS_COMP_GREATER 1 +#define FLAGS_COMP_LESS -1 +#define FLAGS_COMP_ELSE -2 +#define FLAGS_COMP_INCOMPARABLE -3 + +typedef struct { + GType gtype; + VALUE rb_value; + guint value; + gboolean compatible; +} compare_data; + +static VALUE +flags_compare_get_flags_body(VALUE user_data) +{ + compare_data *data = (compare_data *)user_data; + + data->value = rbgobj_get_flags(data->rb_value, data->gtype); + data->compatible = TRUE; + + return Qnil; +} + +static VALUE +flags_compare_get_flags_rescue(VALUE user_data) +{ + compare_data *data = (compare_data *)user_data; + + data->compatible = FALSE; + + return Qnil; +} + +static gint +flags_compare(VALUE self, VALUE rhs) +{ + flags_holder* p = flags_get_holder(self); + compare_data data; + + data.gtype = G_TYPE_FROM_CLASS(p->gclass); + data.rb_value = rhs; + data.value = 0; + data.compatible = TRUE; + + rb_rescue(flags_compare_get_flags_body, (VALUE)&data, + flags_compare_get_flags_rescue, (VALUE)&data); + if (!data.compatible) { + return FLAGS_COMP_INCOMPARABLE; + } + + if (p->value == data.value) + return FLAGS_COMP_EQUAL; + else if ((p->value & data.value) == data.value) + return FLAGS_COMP_GREATER; + else if ((p->value & data.value) == p->value) + return FLAGS_COMP_LESS; + else + return FLAGS_COMP_ELSE; +} + +static VALUE +rg_operator_flags_compare(VALUE self, VALUE rhs) +{ + gint ret = flags_compare(self, rhs); + switch (ret) { + case FLAGS_COMP_EQUAL: + case FLAGS_COMP_GREATER: + case FLAGS_COMP_LESS: + return INT2FIX(ret); + default: + return Qnil; + } +} + +static VALUE +rg_operator_flags_eqv(VALUE self, VALUE rhs) +{ + gint ret = flags_compare(self, rhs); + if (ret == FLAGS_COMP_INCOMPARABLE) + return Qnil; + return CBOOL2RVAL(ret == FLAGS_COMP_EQUAL); +} + +static VALUE +rg_operator_flags_gt_eq(VALUE self, VALUE rhs) +{ + gint ret = flags_compare(self, rhs); + if (ret == FLAGS_COMP_INCOMPARABLE) + return Qnil; + return CBOOL2RVAL(ret == FLAGS_COMP_GREATER || ret == FLAGS_COMP_EQUAL); +} + +static VALUE +rg_operator_flags_lt_eq(VALUE self, VALUE rhs) +{ + gint ret = flags_compare(self, rhs); + if (ret == FLAGS_COMP_INCOMPARABLE) + return Qnil; + return CBOOL2RVAL(ret == FLAGS_COMP_LESS || ret == FLAGS_COMP_EQUAL); +} + +static VALUE +rg_operator_flags_gt(VALUE self, VALUE rhs) +{ + gint ret = flags_compare(self, rhs); + if (ret == FLAGS_COMP_INCOMPARABLE) + return Qnil; + return CBOOL2RVAL(ret == FLAGS_COMP_GREATER); +} + +static VALUE +rg_operator_flags_lt(VALUE self, VALUE rhs) +{ + gint ret = flags_compare(self, rhs); + if (ret == FLAGS_COMP_INCOMPARABLE) + return Qnil; + return CBOOL2RVAL(ret == FLAGS_COMP_LESS); +} + +static VALUE +rg_operator_flags_not(VALUE self, G_GNUC_UNUSED VALUE rhs) +{ + flags_holder* p = flags_get_holder(self); + return rbgobj_make_flags((~ p->value) & p->gclass->mask, + G_TYPE_FROM_CLASS(p->gclass)); +} + +#define LIFT_BINARY_OP(funcname, op) \ + static VALUE \ + funcname(VALUE self, VALUE rhs) \ + { \ + flags_holder* p = flags_get_holder(self); \ + GType gtype = G_TYPE_FROM_CLASS(p->gclass); \ + return rbgobj_make_flags(p->value op rbgobj_get_flags(rhs, gtype), \ + gtype); \ + } + +LIFT_BINARY_OP(flags_and, &) +LIFT_BINARY_OP(flags_or, |) +LIFT_BINARY_OP(flags_xor, ^) + +static VALUE +rg_operator_flags_minus(VALUE self, VALUE rhs) +{ + flags_holder* p = flags_get_holder(self); + GType gtype = G_TYPE_FROM_CLASS(p->gclass); + return rbgobj_make_flags(p->value & ~rbgobj_get_flags(rhs, gtype), + gtype); +} + +static VALUE +rg_empty_p(VALUE self) +{ + flags_holder* p = flags_get_holder(self); + return CBOOL2RVAL(p->value == 0); +} + +static VALUE +rg_hash(VALUE self) +{ + flags_holder* p = flags_get_holder(self); + return UINT2NUM(p->value ^ G_TYPE_FROM_CLASS(p->gclass)); +} + +static VALUE +rg_coerce(VALUE self, VALUE other) +{ + flags_holder *holder; + GType gtype; + + if (rb_obj_is_kind_of(other, rb_cInteger)) + rb_raise(rb_eTypeError, "can't coerce"); + + holder = flags_get_holder(self); + gtype = G_TYPE_FROM_CLASS(holder->gclass); + other = rbgobj_make_flags(NUM2UINT(other), gtype); + return rb_ary_new3(2, other, self); +} + +static VALUE +rg_nonzero_p(VALUE self) +{ + flags_holder* p = flags_get_holder(self); + return CBOOL2RVAL(p->value != 0); +} + +/**********************************************************************/ + +void +Init_gobject_gflags(void) +{ + id_module_eval = rb_intern("module_eval"); + id_new = rb_intern("new"); + id_or = rb_intern("|"); + id_to_i = rb_intern("to_i"); + + RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_FLAGS, "Flags", mGLib); + + rbg_define_singleton_method(RG_TARGET_NAMESPACE, "gtype", generic_s_gtype, 0); + rbg_define_method(RG_TARGET_NAMESPACE, "gtype", generic_gtype, 0); + + RG_DEF_SMETHOD(mask, 0); + RG_DEF_SMETHOD(values, 0); + + rb_define_alloc_func(RG_TARGET_NAMESPACE, flags_s_allocate); + + RG_DEF_METHOD(initialize, -1); + + RG_DEF_METHOD(to_i, 0); + RG_DEF_ALIAS("to_int", "to_i"); + RG_DEF_METHOD(name, 0); + RG_DEF_METHOD(nick, 0); + + /* + rbg_define_method(RG_TARGET_NAMESPACE, "inspect", flags_inspect, 0); + */ + + RG_DEF_METHOD_OPERATOR("<=>", flags_compare, 1); + RG_DEF_METHOD_OPERATOR("==", flags_eqv, 1); + RG_DEF_METHOD_OPERATOR(">=", flags_gt_eq, 1); + RG_DEF_METHOD_OPERATOR("<=", flags_lt_eq, 1); + RG_DEF_METHOD_OPERATOR(">", flags_gt, 1); + RG_DEF_METHOD_OPERATOR("<", flags_lt, 1); + RG_DEF_METHOD_OPERATOR("~", flags_not, 0); + rbg_define_method(RG_TARGET_NAMESPACE, "&", flags_and, 1); + rbg_define_method(RG_TARGET_NAMESPACE, "|", flags_or, 1); + rbg_define_method(RG_TARGET_NAMESPACE, "^", flags_xor, 1); + RG_DEF_METHOD_OPERATOR("-", flags_minus, 1); + + RG_DEF_METHOD_P(empty, 0); + + RG_DEF_METHOD(hash, 0); + RG_DEF_ALIAS("eql?", "=="); + + /* for compatibility */ + RG_DEF_METHOD(coerce, 1); + RG_DEF_ALIAS("zero?", "empty?"); + RG_DEF_METHOD_P(nonzero, 0); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobj_object.c (+1001 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbgobj_object.c 2017-02-15 13:19:47 +0900 (c51bad7) @@ -0,0 +1,1001 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011-2015 Ruby-GNOME2 Project Team + * Copyright (C) 2002-2004 Ruby-GNOME2 Project Team + * Copyright (C) 2002-2003 Masahiro Sakai + * Copyright (C) 1998-2000 Yukihiro Matsumoto, + * Daisuke Kanda, + * Hiroshi Igarashi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" + +#define RG_TARGET_NAMESPACE rbgobj_cObject + +VALUE RG_TARGET_NAMESPACE; +static VALUE eNoPropertyError; +static GQuark RUBY_GOBJECT_OBJ_KEY; + +/* deperecated */ +void +rbgobj_add_abstract_but_create_instance_class(G_GNUC_UNUSED GType gtype) +{ +} + +static void +weak_notify(gpointer data, G_GNUC_UNUSED GObject *where_the_object_was) +{ + gobj_holder *holder = data; + + rbgobj_instance_call_cinfo_free(holder->gobj); + rbgobj_invalidate_relatives(holder->self); + holder->destroyed = TRUE; + + g_object_unref(holder->gobj); + holder->gobj = NULL; +} + +static void +holder_mark(gobj_holder *holder) +{ + if (holder->gobj && !holder->destroyed) + rbgobj_instance_call_cinfo_mark(holder->gobj); +} + +static void +holder_unref(gobj_holder *holder) +{ + if (holder->gobj) { + if (!holder->destroyed) { + g_object_set_qdata(holder->gobj, RUBY_GOBJECT_OBJ_KEY, NULL); + g_object_weak_unref(holder->gobj, (GWeakNotify)weak_notify, holder); + weak_notify(holder, holder->gobj); + } + holder->gobj = NULL; + } +} + +static void +holder_free(gobj_holder *holder) +{ + holder_unref(holder); + xfree(holder); +} + +static VALUE +gobj_s_allocate(VALUE klass) +{ + gobj_holder* holder; + VALUE result; + + result = Data_Make_Struct(klass, gobj_holder, holder_mark, holder_free, holder); + holder->self = result; + holder->gobj = NULL; + holder->cinfo = NULL; + holder->destroyed = FALSE; + + return result; +} + +/* deprecated */ +VALUE +rbgobj_create_object(VALUE klass) +{ + return gobj_s_allocate(klass); +} + +void +rbgobj_gobject_initialize(VALUE obj, gpointer cobj) +{ + gobj_holder* holder = g_object_get_qdata((GObject*)cobj, RUBY_GOBJECT_OBJ_KEY); + if (holder) + rb_raise(rb_eRuntimeError, "ruby wrapper for this GObject* already exists."); + Data_Get_Struct(obj, gobj_holder, holder); + holder->cinfo = RVAL2CINFO(obj); + holder->gobj = (GObject*)cobj; + holder->destroyed = FALSE; + + g_object_set_qdata((GObject*)cobj, RUBY_GOBJECT_OBJ_KEY, (gpointer)holder); + g_object_weak_ref((GObject*)cobj, (GWeakNotify)weak_notify, holder); + { + GType t1 = G_TYPE_FROM_INSTANCE(cobj); + GType t2 = CLASS2GTYPE(CLASS_OF(obj)); + + if (t1 != t2) { + if (!g_type_is_a(t1, t2)) + rb_raise(rb_eTypeError, "%s is not subtype of %s", + g_type_name(t1), g_type_name(t2)); + } + } +} + +VALUE +rbgobj_get_ruby_object_from_gobject(GObject* gobj, gboolean alloc) +{ + gobj_holder *holder; + + holder = g_object_get_qdata(gobj, RUBY_GOBJECT_OBJ_KEY); + if (holder) { + return holder->self; + } else if (alloc) { + VALUE obj; + + obj = gobj_s_allocate(GTYPE2CLASS(G_OBJECT_TYPE(gobj))); + gobj = g_object_ref(gobj); + rbgobj_gobject_initialize(obj, (gpointer)gobj); + return obj; + } else { + return Qnil; + } +} + +GObject* +rbgobj_get_gobject(VALUE obj) +{ + gobj_holder* holder; + + if (!RVAL2CBOOL(rb_obj_is_kind_of(obj, GTYPE2CLASS(G_TYPE_OBJECT)))) + rb_raise(rb_eTypeError, "not a GLib::Object"); + + Data_Get_Struct(obj, gobj_holder, holder); + + if (holder->destroyed) + rb_raise(rb_eTypeError, "destroyed GLib::Object"); + if (!holder->gobj) + rb_raise(rb_eTypeError, "uninitialize GLib::Object"); + + return holder->gobj; +} + +void +rbgobj_init_object_class(VALUE klass) +{ + rbgobj_define_property_accessors(klass); +} + +/**********************************************************************/ + +static void +gobj_mark(gpointer ptr) +{ + GObject* gobj = ptr; + guint n_properties; + GParamSpec** properties; + guint i; + + properties = g_object_class_list_properties(G_OBJECT_GET_CLASS(gobj), &n_properties); + + for (i = 0; i < n_properties; i++) { + GParamSpec* pspec = properties[i]; + GType value_type = G_PARAM_SPEC_VALUE_TYPE(pspec); + if (G_TYPE_FUNDAMENTAL(value_type) != G_TYPE_OBJECT) continue; + if (!(pspec->flags & G_PARAM_READABLE)) continue; + /* FIXME: exclude types that doesn't have identity. */ + + { + GValue gval = G_VALUE_INIT; + g_value_init(&gval, value_type); + g_object_get_property(gobj, pspec->name, &gval); + rbgobj_gc_mark_gvalue(&gval); + g_value_unset(&gval); + } + } + + g_free(properties); +} + +static VALUE +rg_s_new_bang(int argc, VALUE *argv, VALUE self) +{ + const RGObjClassInfo* cinfo = rbgobj_lookup_class(self); + VALUE params_hash; + GObject* gobj; + VALUE result; + + rb_scan_args(argc, argv, "01", ¶ms_hash); + + if (!NIL_P(params_hash)) + Check_Type(params_hash, RUBY_T_HASH); + + if (cinfo->klass != self) + rb_raise(rb_eTypeError, "%s isn't registered class", + rb_class2name(self)); + + gobj = rbgobj_gobject_new(cinfo->gtype, params_hash); + result = GOBJ2RVAL(gobj); + g_object_unref(gobj); + + return result; +} + +struct param_setup_arg { + GObjectClass* gclass; + GParameter* params; + guint param_size; + VALUE params_hash; + guint index; +}; + +static VALUE +_params_setup(VALUE arg, struct param_setup_arg *param_setup_arg) +{ + guint index; + VALUE name, val; + GParamSpec* pspec; + + index = param_setup_arg->index; + if (index >= param_setup_arg->param_size) + rb_raise(rb_eArgError, "too many parameters"); + + name = rb_ary_entry(arg, 0); + val = rb_ary_entry(arg, 1); + + if (SYMBOL_P(name)) + param_setup_arg->params[index].name = rb_id2name(SYM2ID(name)); + else + param_setup_arg->params[index].name = StringValuePtr(name); + + pspec = g_object_class_find_property( + param_setup_arg->gclass, + param_setup_arg->params[index].name); + if (!pspec) + rb_raise(rb_eArgError, "No such property: %s", + param_setup_arg->params[index].name); + + g_value_init(&(param_setup_arg->params[index].value), + G_PARAM_SPEC_VALUE_TYPE(pspec)); + rbgobj_rvalue_to_gvalue(val, &(param_setup_arg->params[index].value)); + + param_setup_arg->index++; + + return Qnil; +} + +static VALUE +gobj_new_body(struct param_setup_arg* arg) +{ + rb_iterate(rb_each, (VALUE)arg->params_hash, _params_setup, (VALUE)arg); + return (VALUE)g_object_newv(G_TYPE_FROM_CLASS(arg->gclass), + arg->param_size, arg->params); +} + +static VALUE +gobj_new_ensure(struct param_setup_arg* arg) +{ + guint i; + g_type_class_unref(arg->gclass); + for (i = 0; i < arg->param_size; i++) { + if (G_IS_VALUE(&arg->params[i].value)) + g_value_unset(&arg->params[i].value); + } + return Qnil; +} + +GObject* +rbgobj_gobject_new(GType gtype, VALUE params_hash) +{ + GObject* result; + + if (!g_type_is_a(gtype, G_TYPE_OBJECT)) + rb_raise(rb_eArgError, + "type \"%s\" is not descendant of GObject", + g_type_name(gtype)); + + if (NIL_P(params_hash)) { + result = g_object_newv(gtype, 0, NULL); + } else { + size_t param_size; + struct param_setup_arg arg; + + param_size = NUM2INT(rb_funcall(params_hash, rb_intern("length"), 0)); + + arg.param_size = param_size; + arg.gclass = G_OBJECT_CLASS(g_type_class_ref(gtype)); + arg.params = ALLOCA_N(GParameter, param_size); + memset(arg.params, 0, sizeof(GParameter) * param_size); + arg.params_hash = params_hash; + arg.index = 0; + + result = (GObject*)rb_ensure(&gobj_new_body, (VALUE)&arg, + &gobj_new_ensure, (VALUE)&arg); + } + + if (!result) + rb_raise(rb_eRuntimeError, "g_object_newv failed"); + + return result; +} + +static VALUE +rg_s_install_property(int argc, VALUE* argv, VALUE self) +{ + const RGObjClassInfo* cinfo = rbgobj_lookup_class(self); + gpointer gclass; + GParamSpec* pspec; + VALUE pspec_obj, prop_id; + + if (cinfo->klass != self) + rb_raise(rb_eTypeError, "%s isn't registered class", + rb_class2name(self)); + + rb_scan_args(argc, argv, "11", &pspec_obj, &prop_id); + pspec = G_PARAM_SPEC(RVAL2GOBJ(pspec_obj)); + + gclass = g_type_class_ref(cinfo->gtype); + g_object_class_install_property(gclass, + NIL_P(prop_id) ? 1 : NUM2UINT(prop_id), + pspec); + g_type_class_unref(gclass); + + /* FIXME: define accessor methods */ + + return Qnil; +} + +static VALUE +gobj_s_property(VALUE self, VALUE property_name) +{ + GObjectClass* oclass; + const char* name; + GParamSpec* prop; + VALUE result; + + if (SYMBOL_P(property_name)) + name = rb_id2name(SYM2ID(property_name)); + else + name = StringValuePtr(property_name); + + oclass = g_type_class_ref(CLASS2GTYPE(self)); + + prop = g_object_class_find_property(oclass, name); + if (!prop){ + g_type_class_unref(oclass); + rb_raise(eNoPropertyError, "No such property: %s", name); + } + + result = GOBJ2RVAL(prop); + g_type_class_unref(oclass); + return result; +} + +static VALUE +gobj_s_properties(int argc, VALUE* argv, VALUE self) +{ + GObjectClass* oclass = g_type_class_ref(CLASS2GTYPE(self)); + guint n_properties; + GParamSpec** props; + VALUE inherited_too; + VALUE ary; + guint i; + + if (rb_scan_args(argc, argv, "01", &inherited_too) == 0) + inherited_too = Qtrue; + + props = g_object_class_list_properties(oclass, &n_properties); + + ary = rb_ary_new(); + for (i = 0; i < n_properties; i++){ + if (RVAL2CBOOL(inherited_too) + || GTYPE2CLASS(props[i]->owner_type) == self) + rb_ary_push(ary, rb_str_new2(props[i]->name)); + } + g_free(props); + g_type_class_unref(oclass); + return ary; +} + +static VALUE type_to_prop_setter_table; +static VALUE type_to_prop_getter_table; + +void +rbgobj_register_property_setter(GType gtype, const char *name, RValueToGValueFunc func) +{ + GObjectClass* oclass; + GParamSpec* pspec; + + VALUE table = rb_hash_aref(type_to_prop_setter_table, INT2FIX(gtype)); + if (NIL_P(table)){ + table = rb_hash_new(); + rb_hash_aset(type_to_prop_setter_table, INT2FIX(gtype), table); + } + + oclass = g_type_class_ref(gtype); + pspec = g_object_class_find_property(oclass, name); + + rb_hash_aset(table, CSTR2RVAL(g_param_spec_get_name(pspec)), + Data_Wrap_Struct(rb_cData, NULL, NULL, func)); + + g_type_class_unref(oclass); +} + +void +rbgobj_register_property_getter(GType gtype, const char *name, GValueToRValueFunc func) +{ + GObjectClass* oclass; + GParamSpec* pspec; + + VALUE table = rb_hash_aref(type_to_prop_getter_table, INT2FIX(gtype)); + if (NIL_P(table)){ + table = rb_hash_new(); + rb_hash_aset(type_to_prop_getter_table, INT2FIX(gtype), table); + } + + oclass = g_type_class_ref(gtype); + pspec = g_object_class_find_property(oclass, name); + + rb_hash_aset(table, CSTR2RVAL(g_param_spec_get_name(pspec)), + Data_Wrap_Struct(rb_cData, NULL, NULL, func)); + + g_type_class_unref(oclass); +} + +static VALUE +rg_set_property(VALUE self, VALUE prop_name, VALUE val) +{ + GParamSpec* pspec; + const char* name; + + if (SYMBOL_P(prop_name)) + name = rb_id2name(SYM2ID(prop_name)); + else + name = StringValuePtr(prop_name); + + pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(RVAL2GOBJ(self)), + name); + + if (!pspec) + rb_raise(eNoPropertyError, "No such property: %s", name); + else { + // FIXME: use rb_ensure to call g_value_unset() + RValueToGValueFunc setter = NULL; + GValue gval = G_VALUE_INIT; + + g_value_init(&gval, G_PARAM_SPEC_VALUE_TYPE(pspec)); + + { + VALUE table = rb_hash_aref(type_to_prop_setter_table, + INT2FIX(pspec->owner_type)); + if (!NIL_P(table)){ + VALUE obj = rb_hash_aref(table, CSTR2RVAL(g_param_spec_get_name(pspec))); + if (!NIL_P(obj)) + Data_Get_Struct(obj, void, setter); + } + } + if (setter) { + setter(val, &gval); + } else { + rbgobj_rvalue_to_gvalue(val, &gval); + } + + g_object_set_property(RVAL2GOBJ(self), name, &gval); + g_value_unset(&gval); + + G_CHILD_SET(self, rb_intern(name), val); + + return self; + } +} + +static VALUE +rg_get_property(VALUE self, VALUE prop_name) +{ + GParamSpec* pspec; + const char* name; + + if (SYMBOL_P(prop_name)) + name = rb_id2name(SYM2ID(prop_name)); + else + name = StringValuePtr(prop_name); + + pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(RVAL2GOBJ(self)), + name); + + if (!pspec) + rb_raise(eNoPropertyError, "No such property: %s", name); + else { + // FIXME: use rb_ensure to call g_value_unset() + GValueToRValueFunc getter = NULL; + GValue gval = G_VALUE_INIT; + VALUE ret; + + { + VALUE table = rb_hash_aref(type_to_prop_getter_table, + INT2FIX(pspec->owner_type)); + if (!NIL_P(table)){ + VALUE obj = rb_hash_aref(table, CSTR2RVAL(g_param_spec_get_name(pspec))); + if (!NIL_P(obj)) + Data_Get_Struct(obj, void, getter); + } + } + + g_value_init(&gval, G_PARAM_SPEC_VALUE_TYPE(pspec)); + g_object_get_property(RVAL2GOBJ(self), name, &gval); + + ret = getter ? getter(&gval) : GVAL2RVAL(&gval); + g_value_unset(&gval); + + G_CHILD_SET(self, rb_intern(name), ret); + + return ret; + } +} + +static VALUE rg_thaw_notify(VALUE self); + +static VALUE +rg_freeze_notify(VALUE self) +{ + g_object_freeze_notify(RVAL2GOBJ(self)); + if (rb_block_given_p()) { + return rb_ensure(rb_yield, self, rg_thaw_notify, self); + } + return self; +} + +static VALUE +rg_notify(VALUE self, VALUE property_name) +{ + g_object_notify(RVAL2GOBJ(self), StringValuePtr(property_name)); + return self; +} + +static VALUE +rg_thaw_notify(VALUE self) +{ + g_object_thaw_notify(RVAL2GOBJ(self)); + return self; +} + +static VALUE +rg_destroyed_p(VALUE self) +{ + gobj_holder* holder; + + if (!RVAL2CBOOL(rb_obj_is_kind_of(self, GTYPE2CLASS(G_TYPE_OBJECT)))) + rb_raise(rb_eTypeError, "not a GLib::Object"); + + Data_Get_Struct(self, gobj_holder, holder); + + return CBOOL2RVAL(holder->destroyed); +} + +static VALUE +rg_inspect(VALUE self) +{ + gobj_holder* holder; + const char *class_name; + char *s; + VALUE result; + + Data_Get_Struct(self, gobj_holder, holder); + + class_name = rb_class2name(CLASS_OF(self)); + if (!holder->destroyed) + s = g_strdup_printf("#<%s:%p ptr=%p>", class_name, (void *)self, + holder->gobj); + else + s = g_strdup_printf("#<%s:%p destroyed>", class_name, (void *)self); + + result = rb_str_new2(s); + g_free(s); + + return result; +} + +static VALUE +rg_unref(VALUE self) +{ + gobj_holder* holder; + + Data_Get_Struct(self, gobj_holder, holder); + + if (holder->destroyed) + rb_raise(rb_eTypeError, "destroyed GLib::Object"); + if (!holder->gobj) + rb_raise(rb_eTypeError, "uninitialize GLib::Object"); + + holder_unref(holder); + + return self; +} + +static VALUE +rg_type_name(VALUE self) +{ + return CSTR2RVAL(G_OBJECT_TYPE_NAME(RVAL2GOBJ(self))); +} + +#if GLIB_CHECK_VERSION(2, 26, 0) +typedef struct { + VALUE transform_from_callback; + VALUE transform_to_callback; + VALUE self; +} RGBindPropertyCallbackData; + +static gboolean +rg_bind_property_transform_to_callback(G_GNUC_UNUSED GBinding *binding, + const GValue *from_value, + GValue *to_value, + gpointer user_data) +{ + RGBindPropertyCallbackData *data = (RGBindPropertyCallbackData *)user_data; + VALUE proc; + VALUE rb_from_value; + VALUE rb_to_value; + + proc = data->transform_to_callback; + if (NIL_P(proc)) + return FALSE; + + rb_from_value = rbgobj_gvalue_to_rvalue(from_value); + rb_to_value = rbgobj_gvalue_to_rvalue(to_value); + rb_to_value = rb_funcall(proc, rb_intern("call"), 1, rb_from_value); + rbgobj_rvalue_to_gvalue(rb_to_value, to_value); + return TRUE; +} + +static gboolean +rg_bind_property_transform_from_callback(G_GNUC_UNUSED GBinding *binding, + const GValue *from_value, + GValue *to_value, + gpointer user_data) +{ + RGBindPropertyCallbackData *data = (RGBindPropertyCallbackData *)user_data; + VALUE proc; + VALUE rb_from_value; + VALUE rb_to_value; + + proc = data->transform_from_callback; + if (NIL_P(proc)) + return FALSE; + + rb_from_value = rbgobj_gvalue_to_rvalue(from_value); + rb_to_value = rbgobj_gvalue_to_rvalue(to_value); + rb_to_value = rb_funcall(proc, rb_intern("call"), 1, rb_from_value); + rbgobj_rvalue_to_gvalue(rb_to_value, to_value); + return TRUE; +} + +static void +rg_destroy_bind_property_full_data(gpointer user_data) +{ + RGBindPropertyCallbackData *data = (RGBindPropertyCallbackData *)user_data; + + if (!NIL_P(data->transform_to_callback)) + G_CHILD_REMOVE(data->self, data->transform_to_callback); + + if (!NIL_P(data->transform_from_callback)) + G_CHILD_REMOVE(data->self, data->transform_from_callback); + + xfree(data); +} + +static VALUE +rg_bind_property(gint argc, VALUE *argv, VALUE self) +{ + VALUE rb_source_property; + VALUE rb_target; + VALUE rb_target_property; + VALUE rb_flags; + VALUE rb_options; + VALUE rb_transform_to; + VALUE rb_transform_from; + + gpointer source; + const gchar *source_property; + gpointer target; + const gchar *target_property; + GBindingFlags flags; + GBinding *binding; + GBindingTransformFunc transform_to = NULL; + GBindingTransformFunc transform_from = NULL; + + rb_scan_args(argc, argv, "41", &rb_source_property, &rb_target, + &rb_target_property, &rb_flags, &rb_options); + + rbg_scan_options(rb_options, + "transform_to", &rb_transform_to, + "transform_from", &rb_transform_from, + NULL); + + source = RVAL2GOBJ(self); + source_property = RVAL2CSTR(rb_source_property); + target = RVAL2GOBJ(rb_target); + target_property = RVAL2CSTR(rb_target_property); + flags = RVAL2GBINDINGFLAGS(rb_flags); + + if (!NIL_P(rb_transform_to)) { + G_CHILD_ADD(self, rb_transform_to); + transform_to = rg_bind_property_transform_to_callback; + } + + if (!NIL_P(rb_transform_from)) { + G_CHILD_ADD(self, rb_transform_from); + transform_from = rg_bind_property_transform_from_callback; + } + + if (transform_to || transform_from) { + RGBindPropertyCallbackData *data; + data = (RGBindPropertyCallbackData *)xmalloc(sizeof(RGBindPropertyCallbackData)); + data->self = self; + data->transform_to_callback = rb_transform_to; + data->transform_from_callback = rb_transform_from; + binding = g_object_bind_property_full(source, source_property, + target, target_property, + flags, transform_to, + transform_from, + (gpointer)data, + rg_destroy_bind_property_full_data); + } else { + binding = g_object_bind_property(source, source_property, + target, target_property, + flags); + } + + return GOBJ2RVAL(binding); +} +#endif + +static VALUE +rg_initialize(int argc, VALUE *argv, VALUE self) +{ + GType gtype; + VALUE params_hash; + GObject* gobj; + + gtype = CLASS2GTYPE(CLASS_OF(self)); + if (G_TYPE_IS_ABSTRACT(gtype)) { + rb_raise(rb_eTypeError, + "initializing abstract class: %s", + RBG_INSPECT(CLASS_OF(self))); + } + + rb_scan_args(argc, argv, "01", ¶ms_hash); + + if (!NIL_P(params_hash)) + Check_Type(params_hash, RUBY_T_HASH); + + gobj = rbgobj_gobject_new(RVAL2GTYPE(self), params_hash); + + G_INITIALIZE(self, gobj); + return Qnil; +} + +static VALUE +gobj_ref_count(VALUE self) +{ + gobj_holder* holder; + Data_Get_Struct(self, gobj_holder, holder); + return INT2NUM(holder->gobj ? holder->gobj->ref_count : 0); +} + +/**********************************************************************/ + +static GQuark q_ruby_setter; +static GQuark q_ruby_getter; + +// FIXME: use rb_protect +static void +get_prop_func(GObject* object, + G_GNUC_UNUSED guint property_id, + GValue* value, + GParamSpec* pspec) +{ + ID ruby_getter = (ID)g_param_spec_get_qdata(pspec, q_ruby_getter); + if (!ruby_getter) { + gchar* name = g_strdup(g_param_spec_get_name(pspec)); + gchar* p; + for (p = name; *p; p++) { + if (*p == '-') + *p = '_'; + } + ruby_getter = rb_intern(name); + g_param_spec_set_qdata(pspec, q_ruby_getter, (gpointer)ruby_getter); + g_free(name); + } + + { + VALUE ret = rb_funcall(GOBJ2RVAL(object), ruby_getter, 0); + rbgobj_rvalue_to_gvalue(ret, value); + } +} + +// FIXME: use rb_protect +static void +set_prop_func(GObject* object, + G_GNUC_UNUSED guint property_id, + const GValue* value, + GParamSpec* pspec) +{ + ID ruby_setter = (ID)g_param_spec_get_qdata(pspec, q_ruby_setter); + if (!ruby_setter) { + gchar* name = g_strconcat(g_param_spec_get_name(pspec), "=", NULL); + gchar* p; + for (p = name; *p; p++) { + if (*p == '-') + *p = '_'; + } + ruby_setter = rb_intern(name); + g_param_spec_set_qdata(pspec, q_ruby_setter, (gpointer)ruby_setter); + g_free(name); + } + + rb_funcall(GOBJ2RVAL(object), ruby_setter, 1, GVAL2RVAL(value)); +} + +void +rbgobj_class_init_func(gpointer g_class, G_GNUC_UNUSED gpointer class_data) +{ + GObjectClass* g_object_class = G_OBJECT_CLASS(g_class); + + g_object_class->set_property = set_prop_func; + g_object_class->get_property = get_prop_func; +} + +void +rbgobj_register_type(VALUE klass, VALUE type_name, GClassInitFunc class_init) +{ + GType parent_type; + GTypeInfo *info; + + { + const RGObjClassInfo *cinfo = rbgobj_lookup_class(klass); + if (cinfo->klass == klass) + rb_raise(rb_eTypeError, + "already registered class: <%s>", + RBG_INSPECT(klass)); + } + + { + VALUE superclass = rb_funcall(klass, rb_intern("superclass"), 0); + const RGObjClassInfo *cinfo = rbgobj_lookup_class(superclass); + if (cinfo->klass != superclass) + rb_raise(rb_eTypeError, + "super class must be registered to GLib: <%s>", + RBG_INSPECT(superclass)); + parent_type = cinfo->gtype; + } + + if (NIL_P(type_name)) { + VALUE klass_name = rb_funcall(klass, rb_intern("name"), 0); + + if (strlen(StringValueCStr(klass_name)) == 0) + rb_raise(rb_eTypeError, + "can't determine type name: <%s>", + RBG_INSPECT(klass)); + + type_name = rb_funcall(klass_name, rb_intern("gsub"), + 2, + rb_str_new_cstr("::"), + rb_str_new_cstr("")); + } + + { + GTypeQuery query; + g_type_query(parent_type, &query); + + /* TODO: Why new? g_type_register_static() doesn’t retain a copy, so + * this should be allocated on the stack. */ + info = g_new0(GTypeInfo, 1); + info->class_size = query.class_size; + info->base_init = NULL; + info->base_finalize = NULL; + info->class_init = class_init; + info->class_finalize = NULL; + info->class_data = NULL; + info->instance_size = query.instance_size; + info->n_preallocs = 0; + info->instance_init = NULL; + info->value_table = NULL; + } + + { + GType type = g_type_register_static(parent_type, + StringValueCStr(type_name), + info, + 0); + + rbgobj_register_class(klass, type, TRUE, TRUE); + + { + RGObjClassInfo *cinfo = (RGObjClassInfo *)rbgobj_lookup_class(klass); + cinfo->flags |= RBGOBJ_DEFINED_BY_RUBY; + } + + { + GType parent = g_type_parent(type); + const RGObjClassInfo *cinfo = GTYPE2CINFO(parent); + VALUE initialize_module; + + initialize_module = rb_define_module_under(klass, + RubyGObjectHookModule); + if (!(cinfo->flags & RBGOBJ_DEFINED_BY_RUBY)) { + rbg_define_method(initialize_module, + "initialize", rg_initialize, -1); + } + + rb_include_module(klass, initialize_module); + } + } +} + +static VALUE +rg_s_type_register(int argc, VALUE *argv, VALUE self) +{ + VALUE type_name; + + rb_scan_args(argc, argv, "01", &type_name); + + rbgobj_register_type(self, type_name, rbgobj_class_init_func); + + return Qnil; +} + +/**********************************************************************/ + +void +Init_gobject_gobject(void) +{ + RG_TARGET_NAMESPACE = G_DEF_CLASS_WITH_GC_FUNC(G_TYPE_OBJECT, "Object", mGLib, + gobj_mark, NULL); + +#ifdef G_TYPE_INITIALLY_UNOWNED + G_DEF_CLASS(G_TYPE_INITIALLY_UNOWNED, "InitiallyUnowned", mGLib); +#endif + + RUBY_GOBJECT_OBJ_KEY = g_quark_from_static_string("__ruby_gobject_object__"); + + rb_define_alloc_func(RG_TARGET_NAMESPACE, (VALUE(*)_((VALUE)))gobj_s_allocate); + RG_DEF_SMETHOD_BANG(new, -1); + + rbg_define_singleton_method(RG_TARGET_NAMESPACE, "property", &gobj_s_property, 1); + rbg_define_singleton_method(RG_TARGET_NAMESPACE, "properties", &gobj_s_properties, -1); + RG_DEF_SMETHOD(install_property, -1); + q_ruby_getter = g_quark_from_static_string("__ruby_getter"); + q_ruby_setter = g_quark_from_static_string("__ruby_setter"); + + RG_DEF_METHOD(set_property, 2); + RG_DEF_METHOD(get_property, 1); + RG_DEF_METHOD(freeze_notify, 0); + rb_undef_method(RG_TARGET_NAMESPACE, "notify"); + RG_DEF_METHOD(notify, 1); + RG_DEF_METHOD(thaw_notify, 0); + RG_DEF_METHOD_P(destroyed, 0); + + RG_DEF_METHOD(initialize, -1); + rbg_define_method(RG_TARGET_NAMESPACE, "ref_count", gobj_ref_count, 0); /* for debugging */ + RG_DEF_METHOD(unref, 0); + RG_DEF_METHOD(inspect, 0); + RG_DEF_METHOD(type_name, 0); + +#if GLIB_CHECK_VERSION(2, 26, 0) + RG_DEF_METHOD(bind_property, -1); + G_DEF_CLASS(G_TYPE_BINDING_FLAGS, "BindingFlags", mGLib); +#endif + + eNoPropertyError = rb_define_class_under(mGLib, "NoPropertyError", + rb_eNameError); + + rb_global_variable(&type_to_prop_setter_table); + rb_global_variable(&type_to_prop_getter_table); + type_to_prop_setter_table = rb_hash_new(); + type_to_prop_getter_table = rb_hash_new(); + + /* subclass */ + RG_DEF_SMETHOD(type_register, -1); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobj_param.c (+378 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbgobj_param.c 2017-02-15 13:19:47 +0900 (c54d7c8) @@ -0,0 +1,378 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2002,2003 Masahiro Sakai + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" + +#define RG_TARGET_NAMESPACE rbgobj_cParam + +VALUE RG_TARGET_NAMESPACE; +static GQuark qparamspec; + +static VALUE pspec_s_allocate(VALUE klass); + +typedef struct { + GParamSpec* instance; + const RGObjClassInfo* cinfo; +} pspec_holder; + +static void +pspec_mark(pspec_holder *holder) +{ + if (holder->instance) + rbgobj_instance_call_cinfo_mark(holder->instance); +} + +static void +pspec_free(pspec_holder *holder) +{ + if (holder->instance){ + rbgobj_instance_call_cinfo_free(holder->instance); + g_param_spec_set_qdata(holder->instance, qparamspec, NULL); + g_param_spec_unref(holder->instance); + } + free(holder); +} + +GParamSpec* +rbgobj_get_param_spec(VALUE obj) +{ + pspec_holder* holder; + Data_Get_Struct(obj, pspec_holder, holder); + return G_PARAM_SPEC(holder->instance); +} + +void +rbgobj_param_spec_initialize(VALUE self, GParamSpec *pspec) +{ + pspec_holder* holder; + Data_Get_Struct(self, pspec_holder, holder); + + pspec = g_param_spec_ref(pspec); + g_param_spec_sink(pspec); + + holder->instance = pspec; + holder->cinfo = GTYPE2CINFO(G_PARAM_SPEC_TYPE(pspec)); + g_param_spec_set_qdata(pspec, qparamspec, (gpointer)self); +} + +VALUE +rbgobj_get_ruby_object_from_param_spec(GParamSpec* pspec, gboolean alloc) +{ + gpointer data = g_param_spec_get_qdata(pspec, qparamspec); + if (data) + return (VALUE)data; + else if (alloc) { + VALUE result = pspec_s_allocate(GTYPE2CLASS(G_PARAM_SPEC_TYPE(pspec))); + rbgobj_param_spec_initialize(result, pspec); + return result; + } else + return Qnil; +} + +/**********************************************************************/ + +static VALUE +pspec_s_allocate(VALUE klass) +{ + const RGObjClassInfo* cinfo = rbgobj_lookup_class(klass); + if (G_TYPE_IS_ABSTRACT(cinfo->gtype)) + rb_raise(rb_eTypeError, "abstract class"); + + { + pspec_holder* holder; + VALUE result; + + result = Data_Make_Struct(klass, pspec_holder, pspec_mark, pspec_free, + holder); + holder->instance = NULL; + holder->cinfo = NULL; + + return result; + } +} + +static VALUE +rg_inspect(VALUE self) +{ + GParamSpec* pspec = rbgobj_get_param_spec(self); + VALUE v = rb_inspect(GTYPE2CLASS(pspec->owner_type)); + gchar* str = g_strdup_printf("#<%s: %s#%s>", + rb_class2name(CLASS_OF(self)), + StringValuePtr(v), + g_param_spec_get_name(pspec)); + VALUE result = rb_str_new2(str); + g_free(str); + return result; +} + +static VALUE +rg_name(VALUE self) +{ + return rb_str_new2(g_param_spec_get_name(rbgobj_get_param_spec(self))); +} + +static VALUE +rg_nick(VALUE self) +{ + const gchar* str = g_param_spec_get_nick(rbgobj_get_param_spec(self)); + return str ? rb_str_new2(str) : Qnil; +} + +static VALUE +rg_blurb(VALUE self) +{ + const gchar* str = g_param_spec_get_blurb(rbgobj_get_param_spec(self)); + return str ? rb_str_new2(str) : Qnil; +} + +static VALUE +rg_flags(VALUE self) +{ + return INT2NUM(rbgobj_get_param_spec(self)->flags); +} + +static VALUE +rg_value_type(VALUE self) +{ + return rbgobj_gtype_new(G_PARAM_SPEC_VALUE_TYPE(rbgobj_get_param_spec(self))); +} + +static VALUE +rg_owner_type(VALUE self) +{ + return rbgobj_gtype_new(rbgobj_get_param_spec(self)->owner_type); +} + +static VALUE +rg_owner(VALUE self) +{ + return GTYPE2CLASS(rbgobj_get_param_spec(self)->owner_type); +} + +static VALUE +rg_value_default(VALUE self) +{ + GValue tmp = G_VALUE_INIT; + VALUE result; + + g_value_init(&tmp, + G_PARAM_SPEC_VALUE_TYPE(rbgobj_get_param_spec(self))); + g_param_value_set_default(rbgobj_get_param_spec(self), &tmp); + result = rbgobj_gvalue_to_rvalue(&tmp); + g_value_unset(&tmp); + + return result; +} + +#if 0 +static VALUE +rg_value_defaults_p(VALUE self, VALUE val) +{ + GValue tmp = {0,}; + gboolean result; + + /* FIXME: use rb_ensure to ensure following g_value_unset() call*/ + g_value_init(&tmp, + G_PARAM_SPEC_VALUE_TYPE(rbgobj_get_param_spec(self))); + rbgobj_rvalue_to_gvalue(val, &tmp); + result = g_param_value_defaults(rbgobj_get_param_spec(self), &tmp); + g_value_unset(&tmp); + + return CBOOL2RVAL(result); +} +#endif + +struct validate_arg{ + GParamSpec* pspec; + GValue* value; + VALUE obj; +}; + +static VALUE +value_validate_body(struct validate_arg* arg) +{ + VALUE ret; + gboolean b; + + rbgobj_rvalue_to_gvalue(arg->obj, arg->value); + b = g_param_value_validate(arg->pspec, arg->value); + ret = rbgobj_gvalue_to_rvalue(arg->value); + return rb_ary_new3(2, CBOOL2RVAL(b), ret); +} + +static VALUE +value_validate_ensure(struct validate_arg* arg) +{ + g_value_unset(arg->value); + return Qnil; +} + +static VALUE +rg_value_validate(VALUE self, VALUE obj) +{ + struct validate_arg arg; + GValue value = G_VALUE_INIT; + + arg.pspec = rbgobj_get_param_spec(self); + arg.value = &value; + arg.obj = obj; + + g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(arg.pspec)); + + return rb_ensure(value_validate_body, (VALUE)&arg, + value_validate_ensure, (VALUE)&arg); +} + +static VALUE +rg_value_convert(int argc, VALUE* argv, VALUE self) +{ + GParamSpec* pspec = rbgobj_get_param_spec(self); + VALUE src, strict_validation; + VALUE src_type; + VALUE result = Qnil; + GValue src_value = G_VALUE_INIT; + GValue dest_value = G_VALUE_INIT; + gboolean b; + + rb_scan_args(argc, argv, "21", &src, &src_type, &strict_validation); + + /* FIXME: use rb_ensure to ensure following g_value_unset() call*/ + g_value_init(&src_value, rbgobj_gtype_get(src_type)); + g_value_init(&dest_value, G_PARAM_SPEC_VALUE_TYPE(pspec)); + + rbgobj_rvalue_to_gvalue(src, &src_value); + + b = g_param_value_convert(rbgobj_get_param_spec(self), + &src_value, &dest_value, + RVAL2CBOOL(strict_validation)); + + if (b) + result = rbgobj_gvalue_to_rvalue(&dest_value); + + g_value_unset(&src_value); + g_value_unset(&dest_value); + + if (b) + return result; + else + rb_raise(rb_eTypeError, "can't convert"); +} + +static VALUE +rg_value_compare(VALUE self, VALUE a, VALUE b) +{ + GParamSpec* pspec = rbgobj_get_param_spec(self); + GType type = G_PARAM_SPEC_VALUE_TYPE(pspec); + GValue v1 = G_VALUE_INIT; + GValue v2 = G_VALUE_INIT; + gint result; + + g_value_init(&v1, type); + g_value_init(&v2, type); + + /* FIXME: use rb_ensure to ensure following g_value_unset() call*/ + rbgobj_rvalue_to_gvalue(a, &v1); + rbgobj_rvalue_to_gvalue(b, &v2); + + result = g_param_values_cmp(pspec, &v1, &v2); + + g_value_unset(&v1); + g_value_unset(&v2); + + return INT2NUM(result); +} + +static VALUE +rg_ref_count(VALUE self) +{ + return INT2NUM(G_PARAM_SPEC(rbgobj_get_param_spec(self))->ref_count); +} + +#define param_is_flag(flag) \ + static VALUE \ + param_is_##flag(VALUE self) \ + { \ + GParamSpec* pspec = G_PARAM_SPEC(rbgobj_get_param_spec(self)); \ + return CBOOL2RVAL(pspec->flags & flag); \ + } + +param_is_flag(G_PARAM_READABLE) +param_is_flag(G_PARAM_WRITABLE) +param_is_flag(G_PARAM_CONSTRUCT) +param_is_flag(G_PARAM_CONSTRUCT_ONLY) +param_is_flag(G_PARAM_LAX_VALIDATION) +param_is_flag(G_PARAM_PRIVATE) +param_is_flag(G_PARAM_READWRITE) + +/**********************************************************************/ + +void +Init_gobject_gparam(void) +{ + qparamspec = g_quark_from_static_string("__ruby_gobject_param_spec__"); + RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_PARAM, "Param", mGLib); + + /* GParamFlags */ + rb_define_const(RG_TARGET_NAMESPACE, "READABLE", INT2FIX(G_PARAM_READABLE)); + rb_define_const(RG_TARGET_NAMESPACE, "WRITABLE", INT2FIX(G_PARAM_WRITABLE)); + rb_define_const(RG_TARGET_NAMESPACE, "CONSTRUCT", INT2FIX(G_PARAM_CONSTRUCT)); + rb_define_const(RG_TARGET_NAMESPACE, "CONSTRUCT_ONLY", INT2FIX(G_PARAM_CONSTRUCT_ONLY)); + rb_define_const(RG_TARGET_NAMESPACE, "LAX_VALIDATION", INT2FIX(G_PARAM_LAX_VALIDATION)); + rb_define_const(RG_TARGET_NAMESPACE, "PRIVATE", INT2FIX(G_PARAM_PRIVATE)); + rb_define_const(RG_TARGET_NAMESPACE, "READWRITE", INT2FIX(G_PARAM_READWRITE)); + rb_define_const(RG_TARGET_NAMESPACE, "MASK", INT2FIX(G_PARAM_MASK)); + rb_define_const(RG_TARGET_NAMESPACE, "USER_SHIFT", INT2FIX(G_PARAM_USER_SHIFT)); + + rb_define_alloc_func(RG_TARGET_NAMESPACE, pspec_s_allocate); + + RG_DEF_METHOD(inspect, 0); + + RG_DEF_METHOD(name, 0); + RG_DEF_METHOD(nick, 0); + RG_DEF_METHOD(blurb, 0); + + RG_DEF_METHOD(flags, 0); + RG_DEF_METHOD(value_type, 0); + RG_DEF_METHOD(owner_type, 0); + RG_DEF_METHOD(owner, 0); + + RG_DEF_METHOD(value_default, 0); + RG_DEF_ALIAS("default", "value_default"); + + // FIXME: better name +#if 0 + RG_DEF_METHOD_P(value_defaults, 1); +#endif + RG_DEF_METHOD(value_validate, 1); + RG_DEF_METHOD(value_convert, -1); + RG_DEF_METHOD(value_compare, 2); + + /* for debugging */ + RG_DEF_METHOD(ref_count, 0); + + rbg_define_method(RG_TARGET_NAMESPACE, "readable?", param_is_G_PARAM_READABLE, 0); + rbg_define_method(RG_TARGET_NAMESPACE, "writable?", param_is_G_PARAM_WRITABLE, 0); + rbg_define_method(RG_TARGET_NAMESPACE, "construct?", param_is_G_PARAM_CONSTRUCT, 0); + rbg_define_method(RG_TARGET_NAMESPACE, "construct_only?", param_is_G_PARAM_CONSTRUCT_ONLY, 0); + rbg_define_method(RG_TARGET_NAMESPACE, "lax_validation?", param_is_G_PARAM_LAX_VALIDATION, 0); + rbg_define_method(RG_TARGET_NAMESPACE, "private?", param_is_G_PARAM_PRIVATE, 0); + rbg_define_method(RG_TARGET_NAMESPACE, "readwrite?", param_is_G_PARAM_READWRITE, 0); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobj_paramspecs.c (+311 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbgobj_paramspecs.c 2017-02-15 13:19:47 +0900 (140b585) @@ -0,0 +1,311 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2004 Ruby-GNOME2 Project Team + * Copyright (C) 2002,2003 Masahiro Sakai + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" + +#define DEF_NUMERIC_PSPEC_METHODS_FUNC(pspec_type, typename, from_ruby, to_ruby, pspec_cast) \ +static VALUE \ +typename##_initialize(VALUE self, VALUE name, VALUE nick, VALUE blurb, \ + VALUE minimum, VALUE maximum, VALUE default_value, \ + VALUE flags) \ +{ \ + GParamSpec* pspec; \ + pspec = g_param_spec_##typename(StringValuePtr(name), \ + StringValuePtr(nick), \ + StringValuePtr(blurb), \ + from_ruby(minimum), \ + from_ruby(maximum), \ + from_ruby(default_value), \ + NUM2UINT(flags)); \ + rbgobj_param_spec_initialize(self, pspec); \ + return Qnil; \ +} \ + \ +static VALUE \ +typename##_minimum(VALUE self) \ +{ \ + return to_ruby(pspec_cast(RVAL2GOBJ(self))->minimum); \ +} \ + \ +static VALUE \ +typename##_maximum(VALUE self) \ +{ \ + return to_ruby(pspec_cast(RVAL2GOBJ(self))->maximum); \ +} \ + \ +static VALUE \ +typename##_range(VALUE self) \ +{ \ + pspec_type* pspec = pspec_cast(RVAL2GOBJ(self)); \ + return rb_range_new(pspec->minimum, pspec->maximum, 0); \ +} + +DEF_NUMERIC_PSPEC_METHODS_FUNC(GParamSpecChar, char, NUM2INT, INT2FIX, G_PARAM_SPEC_CHAR) +DEF_NUMERIC_PSPEC_METHODS_FUNC(GParamSpecUChar, uchar, NUM2UINT, INT2FIX, G_PARAM_SPEC_UCHAR) +DEF_NUMERIC_PSPEC_METHODS_FUNC(GParamSpecInt, int, NUM2INT, INT2NUM, G_PARAM_SPEC_INT) +DEF_NUMERIC_PSPEC_METHODS_FUNC(GParamSpecUInt, uint, NUM2UINT, UINT2NUM, G_PARAM_SPEC_UINT) +DEF_NUMERIC_PSPEC_METHODS_FUNC(GParamSpecLong, long, NUM2LONG, INT2NUM, G_PARAM_SPEC_LONG) +DEF_NUMERIC_PSPEC_METHODS_FUNC(GParamSpecULong, ulong, NUM2ULONG, UINT2NUM, G_PARAM_SPEC_ULONG) +DEF_NUMERIC_PSPEC_METHODS_FUNC(GParamSpecInt64, int64, rbglib_num_to_int64, rbglib_int64_to_num, G_PARAM_SPEC_INT64) +DEF_NUMERIC_PSPEC_METHODS_FUNC(GParamSpecUInt64, uint64, rbglib_num_to_uint64, rbglib_uint64_to_num, G_PARAM_SPEC_UINT64) +DEF_NUMERIC_PSPEC_METHODS_FUNC(GParamSpecFloat, float, NUM2DBL, rb_float_new, G_PARAM_SPEC_FLOAT) +DEF_NUMERIC_PSPEC_METHODS_FUNC(GParamSpecDouble, double, NUM2DBL, rb_float_new, G_PARAM_SPEC_DOUBLE) + +static VALUE +float_epsilon(VALUE self) +{ + return rb_float_new(G_PARAM_SPEC_FLOAT(RVAL2GOBJ(self))->epsilon); +} + +static VALUE +double_epsilon(VALUE self) +{ + return rb_float_new(G_PARAM_SPEC_DOUBLE(RVAL2GOBJ(self))->epsilon); +} + + +static VALUE +boolean_initialize(VALUE self, VALUE name, VALUE nick, VALUE blurb, + VALUE default_value, VALUE flags) +{ + GParamSpec* pspec; + pspec = g_param_spec_boolean(StringValuePtr(name), + StringValuePtr(nick), + StringValuePtr(blurb), + RVAL2CBOOL(default_value), + NUM2UINT(flags)); + rbgobj_param_spec_initialize(self, pspec); + return Qnil; +} + +static VALUE +unichar_initialize(VALUE self, VALUE name, VALUE nick, VALUE blurb, + VALUE default_value, VALUE flags) +{ + GParamSpec* pspec; + pspec = g_param_spec_unichar(StringValuePtr(name), + StringValuePtr(nick), + StringValuePtr(blurb), + NUM2UINT(default_value), + NUM2UINT(flags)); + rbgobj_param_spec_initialize(self, pspec); + return Qnil; +} + +static VALUE +enum_initialize(VALUE self, VALUE name, VALUE nick, VALUE blurb, + VALUE enum_type, VALUE default_value, VALUE flags) +{ + GParamSpec* pspec; + GType gtype = rbgobj_gtype_get(enum_type); + + pspec = g_param_spec_enum(StringValuePtr(name), + StringValuePtr(nick), + StringValuePtr(blurb), + gtype, + RVAL2GENUM(default_value, gtype), + NUM2UINT(flags)); + rbgobj_param_spec_initialize(self, pspec); + return Qnil; +} + +static VALUE +flags_initialize(VALUE self, VALUE name, VALUE nick, VALUE blurb, + VALUE flags_type, VALUE default_value, VALUE flags) +{ + GParamSpec* pspec; + GType gtype = rbgobj_gtype_get(flags_type); + + pspec = g_param_spec_flags(StringValuePtr(name), + StringValuePtr(nick), + StringValuePtr(blurb), + gtype, + RVAL2GFLAGS(default_value, gtype), + NUM2UINT(flags)); + rbgobj_param_spec_initialize(self, pspec); + return Qnil; +} + +static VALUE +string_initialize(VALUE self, VALUE name, VALUE nick, VALUE blurb, + VALUE default_value, VALUE flags) +{ + GParamSpec* pspec; + pspec = g_param_spec_string(StringValuePtr(name), + StringValuePtr(nick), + StringValuePtr(blurb), + NIL_P(default_value) ? NULL : StringValuePtr(default_value), + NUM2UINT(flags)); + rbgobj_param_spec_initialize(self, pspec); + return Qnil; +} + +static VALUE +param_initialize(VALUE self, VALUE name, VALUE nick, VALUE blurb, + VALUE param_type, VALUE flags) +{ + GParamSpec* pspec; + pspec = g_param_spec_param(StringValuePtr(name), + StringValuePtr(nick), + StringValuePtr(blurb), + rbgobj_gtype_get(param_type), + NUM2UINT(flags)); + rbgobj_param_spec_initialize(self, pspec); + return Qnil; +} + +static VALUE +boxed_initialize(VALUE self, VALUE name, VALUE nick, VALUE blurb, + VALUE boxed_type, VALUE flags) +{ + GParamSpec* pspec; + pspec = g_param_spec_boxed(StringValuePtr(name), + StringValuePtr(nick), + StringValuePtr(blurb), + rbgobj_gtype_get(boxed_type), + NUM2UINT(flags)); + rbgobj_param_spec_initialize(self, pspec); + return Qnil; +} + +static VALUE +pointer_initialize(VALUE self, VALUE name, VALUE nick, VALUE blurb, VALUE flags) +{ + GParamSpec* pspec; + pspec = g_param_spec_pointer(StringValuePtr(name), + StringValuePtr(nick), + StringValuePtr(blurb), + NUM2UINT(flags)); + rbgobj_param_spec_initialize(self, pspec); + return Qnil; +} + +static VALUE +value_array_initialize(VALUE self, VALUE name, VALUE nick, VALUE blurb, + VALUE element_spec, VALUE flags) +{ + GParamSpec* pspec; + pspec = g_param_spec_value_array(StringValuePtr(name), + StringValuePtr(nick), + StringValuePtr(blurb), + RVAL2GOBJ(element_spec), + NUM2UINT(flags)); + rbgobj_param_spec_initialize(self, pspec); + return Qnil; +} + +static VALUE +object_initialize(VALUE self, VALUE name, VALUE nick, VALUE blurb, + VALUE object_type, VALUE flags) +{ + GParamSpec* pspec; + pspec = g_param_spec_object(StringValuePtr(name), + StringValuePtr(nick), + StringValuePtr(blurb), + rbgobj_gtype_get(object_type), + NUM2UINT(flags)); + rbgobj_param_spec_initialize(self, pspec); + return Qnil; +} + +void +Init_gobject_gparamspecs(void) +{ + VALUE cParamSpec = GTYPE2CLASS(G_TYPE_PARAM); + VALUE c; + +#define DEF_NUMERIC_PSPEC_METHODS(c, typename) \ + G_STMT_START {\ + rbg_define_method(c, "initialize", typename##_initialize, 7); \ + rbg_define_method(c, "minimum", typename##_minimum, 0); \ + rbg_define_method(c, "maximum", typename##_maximum, 0); \ + rbg_define_method(c, "range", typename##_range, 0); \ + } G_STMT_END + +#if 0 + rbg_define_method(c, "default_value", typename##_default_value, 0); \ + rb_define_alias(c, "default", "default_value"); \ + +#endif + + c = G_DEF_CLASS(G_TYPE_PARAM_CHAR, "Char", cParamSpec); + DEF_NUMERIC_PSPEC_METHODS(c, char); + + c = G_DEF_CLASS(G_TYPE_PARAM_UCHAR, "UChar", cParamSpec); + DEF_NUMERIC_PSPEC_METHODS(c, uchar); + + c = G_DEF_CLASS(G_TYPE_PARAM_INT, "Int", cParamSpec); + DEF_NUMERIC_PSPEC_METHODS(c, int); + + c = G_DEF_CLASS(G_TYPE_PARAM_UINT, "UInt", cParamSpec); + DEF_NUMERIC_PSPEC_METHODS(c, uint); + + c = G_DEF_CLASS(G_TYPE_PARAM_LONG, "Long", cParamSpec); + DEF_NUMERIC_PSPEC_METHODS(c, long); + + c = G_DEF_CLASS(G_TYPE_PARAM_ULONG, "ULong", cParamSpec); + DEF_NUMERIC_PSPEC_METHODS(c, ulong); + + c = G_DEF_CLASS(G_TYPE_PARAM_INT64, "Int64", cParamSpec); + DEF_NUMERIC_PSPEC_METHODS(c, int64); + + c = G_DEF_CLASS(G_TYPE_PARAM_UINT64, "UInt64", cParamSpec); + DEF_NUMERIC_PSPEC_METHODS(c, uint64); + + c = G_DEF_CLASS(G_TYPE_PARAM_FLOAT, "Float", cParamSpec); + DEF_NUMERIC_PSPEC_METHODS(c, float); + rbg_define_method(c, "epsilon", float_epsilon, 0); + + c = G_DEF_CLASS(G_TYPE_PARAM_DOUBLE, "Double", cParamSpec); + DEF_NUMERIC_PSPEC_METHODS(c, double); + rbg_define_method(c, "epsilon", double_epsilon, 0); + + c = G_DEF_CLASS(G_TYPE_PARAM_BOOLEAN, "Boolean", cParamSpec); + rbg_define_method(c, "initialize", boolean_initialize, 5); + + c = G_DEF_CLASS(G_TYPE_PARAM_UNICHAR, "UniChar", cParamSpec); + rbg_define_method(c, "initialize", unichar_initialize, 5); + + c = G_DEF_CLASS(G_TYPE_PARAM_ENUM, "Enum", cParamSpec); + rbg_define_method(c, "initialize", enum_initialize, 6); + + c = G_DEF_CLASS(G_TYPE_PARAM_FLAGS, "Flags", cParamSpec); + rbg_define_method(c, "initialize", flags_initialize, 6); + + c = G_DEF_CLASS(G_TYPE_PARAM_STRING, "String", cParamSpec); + rbg_define_method(c, "initialize", string_initialize, 5); + + c = G_DEF_CLASS(G_TYPE_PARAM_PARAM, "Param", cParamSpec); + rbg_define_method(c, "initialize", param_initialize, 5); + + c = G_DEF_CLASS(G_TYPE_PARAM_BOXED, "Boxed", cParamSpec); + rbg_define_method(c, "initialize", boxed_initialize, 5); + + c = G_DEF_CLASS(G_TYPE_PARAM_POINTER, "Pointer", cParamSpec); + rbg_define_method(c, "initialize", pointer_initialize, 4); + + c = G_DEF_CLASS(G_TYPE_PARAM_VALUE_ARRAY, "ValueArray", cParamSpec); + rbg_define_method(c, "initialize", value_array_initialize, 5); + + c = G_DEF_CLASS(G_TYPE_PARAM_OBJECT, "Object", cParamSpec); + rbg_define_method(c, "initialize", object_initialize, 5); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobj_signal.c (+1017 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbgobj_signal.c 2017-02-15 13:19:47 +0900 (cd59da2) @@ -0,0 +1,1017 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2002-2004 Ruby-GNOME2 Project Team + * Copyright (C) 2002,2003 Masahiro Sakai + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" + +#define RG_TARGET_NAMESPACE cSignal + +static VALUE RG_TARGET_NAMESPACE; +VALUE rbgobj_signal_wrap(guint sig_id); + +#define default_handler_method_prefix "signal_do_" + +/**********************************************************************/ + +static VALUE signal_func_table; + +void +rbgobj_set_signal_func(VALUE klass, const gchar *sig_name, GValToRValSignalFunc func) +{ + VALUE obj = Data_Wrap_Struct(rb_cData, NULL, NULL, func); + guint signal_id = g_signal_lookup(sig_name, CLASS2GTYPE(klass)); + rb_hash_aset(signal_func_table, UINT2NUM(signal_id), obj); +} + +GValToRValSignalFunc +rbgobj_get_signal_func(guint signal_id) +{ + GValToRValSignalFunc func = NULL; + VALUE func_obj = rb_hash_aref(signal_func_table, UINT2NUM(signal_id)); + if (!NIL_P(func_obj)) + Data_Get_Struct(func_obj, void, func); + return func; +} + +static VALUE signal_call_func_table; + +void +rbgobj_set_signal_call_func(VALUE klass, + const gchar *signal_name, + RGClosureCallFunc func) +{ + VALUE obj = Data_Wrap_Struct(rb_cData, NULL, NULL, func); + guint signal_id = g_signal_lookup(signal_name, CLASS2GTYPE(klass)); + rb_hash_aset(signal_call_func_table, UINT2NUM(signal_id), obj); +} + +RGClosureCallFunc +rbgobj_get_signal_call_func(guint signal_id) +{ + RGClosureCallFunc func = NULL; + VALUE func_obj = rb_hash_aref(signal_call_func_table, UINT2NUM(signal_id)); + if (!NIL_P(func_obj)) + Data_Get_Struct(func_obj, void, func); + return func; +} + +/**********************************************************************/ + +static VALUE eNoSignalError; + +// FIXME: use rb_protect +static gboolean +accumulator_func(G_GNUC_UNUSED GSignalInvocationHint *ihint, + GValue *return_accu, + const GValue *handler_return, + gpointer data) +{ + VALUE proc = (VALUE)data; + VALUE val = GVAL2RVAL(return_accu); + VALUE new = GVAL2RVAL(handler_return); + VALUE hint = Qnil; // FIXME + VALUE tmp; + gboolean continue_emission = TRUE; + + tmp = rb_funcall(proc, rb_intern("call"), 3, hint, val, new); + /* FIXME */ + if (TYPE(tmp) == T_ARRAY) { + continue_emission = RVAL2CBOOL(rb_ary_entry(tmp, 0)); + val = rb_ary_entry(tmp, 1); + } else { + val = tmp; + } + rbgobj_rvalue_to_gvalue(val, return_accu); + + return continue_emission; +} + +struct rval2gtypes_args { + VALUE ary; + long n; + GType *result; +}; + +static VALUE +rbg_rval2gtypes_body(VALUE value) +{ + long i; + struct rval2gtypes_args *args = (struct rval2gtypes_args *)value; + + for (i = 0; i < args->n; i++) + args->result[i] = rbgobj_gtype_get(RARRAY_PTR(args->ary)[i]); + + return Qnil; +} + +static G_GNUC_NORETURN VALUE +rbg_rval2gtypes_rescue(VALUE value) +{ + g_free(((struct rval2gtypes_args *)value)->result); + + rb_exc_raise(rb_errinfo()); +} + +static GType * +rbg_rval2gtypes(volatile VALUE *value, long *n) +{ + struct rval2gtypes_args args; + + args.ary = *value = rb_ary_dup(rb_ary_to_ary(*value)); + args.n = RARRAY_LEN(args.ary); + args.result = g_new(GType, args.n + 1); + + rb_rescue(rbg_rval2gtypes_body, (VALUE)&args, + rbg_rval2gtypes_rescue, (VALUE)&args); + + if (n != NULL) + *n = args.n; + + return args.result; +} + +static GType * +rbg_rval2gtypes_accept_nil(volatile VALUE *value, long *n) +{ + if (!NIL_P(*value)) + return rbg_rval2gtypes(value, n); + + if (n != NULL) + *n = 0; + + return NULL; +} + +#define RVAL2GTYPES(value, n) rbg_rval2gtypes(&(value), &(n)) +#define RVAL2GTYPES_ACCEPT_NIL(value, n) rbg_rval2gtypes_accept_nil(&(value), &(n)) + +static VALUE +gobj_s_signal_new(int argc, VALUE* argv, VALUE self) +{ + const RGObjClassInfo *cinfo = rbgobj_lookup_class(self); + VALUE rbsignal_name, rbsignal_flags, accumulator, rbreturn_type, params; + const gchar *signal_name; + GSignalFlags signal_flags; + GClosure *class_closure; + GType return_type; + GType *param_types; + long n_params; + guint signal; + + rb_scan_args(argc, argv, "4*", + &rbsignal_name, &rbsignal_flags, &accumulator, &rbreturn_type, ¶ms); + + if (cinfo->klass != self) + rb_raise(rb_eTypeError, "not a registered class: %s", + rb_class2name(self)); + + if (SYMBOL_P(rbsignal_name)) + rbsignal_name = rb_str_new2(rb_id2name(SYM2ID(rbsignal_name))); + signal_name = RVAL2CSTR(rbsignal_name); + + signal_flags = NUM2INT(rbsignal_flags); + + { + VALUE proc; + ID method_id; + + method_id = rb_to_id(rb_str_concat(rb_str_new2(default_handler_method_prefix), rbsignal_name)); + + proc = rb_funcall(mMetaInterface, rb_intern("signal_callback"), 2, + self, ID2SYM(method_id)); + + class_closure = g_rclosure_new(proc, Qnil, NULL); + /* TODO: Should this be done even if something below it fails? */ + g_rclosure_attach(class_closure, self); + } + + return_type = rbgobj_gtype_get(rbreturn_type); + param_types = RVAL2GTYPES_ACCEPT_NIL(params, n_params); + + signal = g_signal_newv(signal_name, + cinfo->gtype, + signal_flags, + class_closure, + NIL_P(accumulator) ? NULL : accumulator_func, + NIL_P(accumulator) ? NULL : (gpointer)accumulator, + NULL, /* c_marshaller */ + return_type, + n_params, + param_types); + + g_free(param_types); + + if (!signal) + rb_raise(rb_eRuntimeError, "g_signal_newv failed"); + + if (!NIL_P(accumulator)) + G_RELATIVE(self, accumulator); /* FIXME */ + + return rbgobj_signal_wrap(signal); +} + +static void +_signal_list(VALUE result, GType gtype) +{ + guint n_ids, i; + guint* ids = g_signal_list_ids(gtype, &n_ids); + for (i = 0; i < n_ids; i++) + rb_ary_push(result, rb_str_new2(g_signal_name(ids[i]))); + g_free(ids); +} + +static VALUE +gobj_s_signals(int argc, VALUE* argv, VALUE self) +{ + GType gtype; + VALUE inherited_too, result; + + if (rb_scan_args(argc, argv, "01", &inherited_too) == 0) + inherited_too = Qtrue; + gtype = CLASS2GTYPE(self); + result = rb_ary_new(); + + if (RVAL2CBOOL(inherited_too)){ + guint n_interfaces, i; + GType* interfaces = g_type_interfaces(gtype, &n_interfaces); + for (i = 0; i < n_interfaces; i++) + _signal_list(result, interfaces[i]); + g_free(interfaces); + + for (; gtype; gtype = g_type_parent(gtype)) + _signal_list(result, gtype); + } else if (GTYPE2CLASS(gtype) == self) { + _signal_list(result, gtype); + } + + return result; +} + +static VALUE +gobj_s_signal(VALUE self, VALUE name) +{ + const char* sig_name; + guint sig_id; + + if (SYMBOL_P(name)) + sig_name = rb_id2name(SYM2ID(name)); + else + sig_name = StringValuePtr(name); + + sig_id = g_signal_lookup(sig_name, CLASS2GTYPE(self)); + if (!sig_id) + rb_raise(eNoSignalError, "no such signal: %s", sig_name); + + return rbgobj_signal_wrap(sig_id); +} + +static VALUE +gobj_sig_has_handler_pending(int argc, VALUE *argv, VALUE self) +{ + VALUE sig, may_be_blocked; + const char* sig_name; + guint signal_id; + GQuark detail; + + rb_scan_args(argc, argv, "11", &sig, &may_be_blocked); + + if (SYMBOL_P(sig)) + sig_name = rb_id2name(SYM2ID(sig)); + else + sig_name = StringValuePtr(sig); + + if (!g_signal_parse_name(sig_name, CLASS2GTYPE(CLASS_OF(self)), &signal_id, &detail, TRUE)) + rb_raise(eNoSignalError, "no such signal: %s", sig_name); + + return CBOOL2RVAL(g_signal_has_handler_pending(RVAL2GOBJ(self), + signal_id, detail, + RVAL2CBOOL(may_be_blocked))); +} + +static VALUE +gobj_sig_connect_impl(gboolean after, int argc, VALUE *argv, VALUE self) +{ + VALUE sig, rest; + gulong handler_id; + GClosure* rclosure; + const char* sig_name; + guint signal_id; + GQuark detail; + VALUE func; + GObject *g_object; + gchar *tag; + + rb_scan_args(argc, argv, "1*", &sig, &rest); + + if (NIL_P(rest)) rest = rb_ary_new(); + + if (SYMBOL_P(sig)) + sig_name = rb_id2name(SYM2ID(sig)); + else + sig_name = StringValuePtr(sig); + + if (!g_signal_parse_name(sig_name, CLASS2GTYPE(CLASS_OF(self)), &signal_id, &detail, TRUE)) + rb_raise(eNoSignalError, "no such signal: %s", sig_name); + + { + ID id_create_signal_handler; + const char *normalized_signal_name; + + CONST_ID(id_create_signal_handler, "create_signal_handler"); + normalized_signal_name = g_signal_name(signal_id); + func = rb_funcall(self, + rb_intern("create_signal_handler"), + 2, + rb_str_new_cstr(normalized_signal_name), + rb_block_proc()); + } + { + RGClosureCallFunc call_func; + call_func = rbgobj_get_signal_call_func(signal_id); + if (call_func) { + rclosure = g_rclosure_new_call(func, + rest, + call_func); + } else { + rclosure = g_rclosure_new(func, + rest, + rbgobj_get_signal_func(signal_id)); + } + } + g_rclosure_attach((GClosure *)rclosure, self); + g_object = RVAL2GOBJ(self); + tag = g_strdup_printf("%s::%s", + G_OBJECT_CLASS_NAME(G_OBJECT_GET_CLASS(g_object)), + sig_name); + g_rclosure_set_tag((GClosure *)rclosure, tag); + g_free(tag); + handler_id = g_signal_connect_closure_by_id(g_object, signal_id, detail, + rclosure, after); + + return ULONG2NUM(handler_id); +} + +static VALUE +gobj_sig_connect(int argc, VALUE *argv, VALUE self) +{ + return gobj_sig_connect_impl(FALSE, argc, argv, self); +} + +static VALUE +gobj_sig_connect_after(int argc, VALUE *argv, VALUE self) +{ + return gobj_sig_connect_impl(TRUE, argc, argv, self); +} + +#if 0 +static VALUE +gobj_sig_get_invocation_hint(VALUE self) +{ + GSignalInvocationHint* hint; + hint = g_signal_get_invocation_hint(RVAL2GOBJ(self)); + return rb_ary_new3(3, + rbgobj_signal_wrap(hint->signal_id), + hint->detail ? rb_str_new2(g_quark_to_string(hint->detail)) : Qnil, + INT2NUM(hint->run_type)); +} +#endif + +struct emit_arg { + VALUE self; + VALUE args; + + GSignalQuery query; + GQuark detail; + GValueArray* instance_and_params; +}; + +static VALUE +emit_body(struct emit_arg* arg) +{ + GValue param = G_VALUE_INIT; + + g_value_init(¶m, G_TYPE_FROM_INSTANCE(RVAL2GOBJ(arg->self))); + rbgobj_rvalue_to_gvalue(arg->self, ¶m); + g_value_array_append(arg->instance_and_params, ¶m); + g_value_unset(¶m); + + { + guint i; + for (i = 0; i < arg->query.n_params; i++){ + GType gtype = arg->query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE; + + g_value_init(¶m, gtype); + + rbgobj_rvalue_to_gvalue(rb_ary_entry(arg->args, i), ¶m); + g_value_array_append(arg->instance_and_params, ¶m); + g_value_unset(¶m); + } + } + + { + gboolean use_ret = (arg->query.return_type != G_TYPE_NONE); + GValue return_value = G_VALUE_INIT; + + if (use_ret) + g_value_init(&return_value, + arg->query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE); + + g_signal_emitv(arg->instance_and_params->values, + arg->query.signal_id, arg->detail, + (use_ret) ? &return_value : NULL); + + if (use_ret) { + VALUE ret = GVAL2RVAL(&return_value); + g_value_unset(&return_value); + return ret; + } else { + return Qnil; + } + } +} + +static VALUE +emit_ensure(struct emit_arg* arg) +{ + g_value_array_free(arg->instance_and_params); + return Qnil; +} + +static VALUE +gobj_sig_emit(int argc, VALUE *argv, VALUE self) +{ + VALUE sig; + const char* sig_name; + guint signal_id; + struct emit_arg arg; + + rb_scan_args(argc, argv, "1*", &sig, &arg.args); + + if (SYMBOL_P(sig)) + sig_name = rb_id2name(SYM2ID(sig)); + else + sig_name = StringValuePtr(sig); + + if (!g_signal_parse_name(sig_name, + CLASS2GTYPE(CLASS_OF(self)), + &signal_id, &arg.detail, FALSE)) + rb_raise(eNoSignalError, "invalid signal \"%s\"", sig_name); + + g_signal_query(signal_id, &arg.query); + + if (arg.query.n_params != (guint)RARRAY_LEN(arg.args)) + rb_raise(rb_eArgError, "wrong number of arguments(%ld for %d)", + RARRAY_LEN(arg.args) + 1, + arg.query.n_params + 1); + + arg.self = self; + arg.instance_and_params = g_value_array_new(1 + arg.query.n_params); + + return rb_ensure(emit_body, (VALUE)&arg, emit_ensure, (VALUE)&arg); +} + +static VALUE +gobj_sig_emit_stop(VALUE self, VALUE sig) +{ + gpointer instance = RVAL2GOBJ(self); + const char* sig_name; + guint signal_id; + GQuark detail; + + if (SYMBOL_P(sig)) + sig_name = rb_id2name(SYM2ID(sig)); + else + sig_name = StringValuePtr(sig); + + if (!g_signal_parse_name(sig_name, + CLASS2GTYPE(CLASS_OF(self)), + &signal_id, &detail, FALSE)) + rb_raise(eNoSignalError, "invalid signal \"%s\"", sig_name); + + g_signal_stop_emission(instance, signal_id, detail); + return self; +} + +static VALUE gobj_sig_handler_unblock(VALUE self, VALUE id); + +static VALUE +_sig_handler_block_ensure(VALUE arg) +{ + VALUE self = RARRAY_PTR(arg)[0]; + VALUE id = RARRAY_PTR(arg)[1]; + gobj_sig_handler_unblock(self, id); + return Qnil; +} + +static VALUE +gobj_sig_handler_block(VALUE self, VALUE id) +{ + g_signal_handler_block(RVAL2GOBJ(self), NUM2ULONG(id)); + if (rb_block_given_p()) + rb_ensure(rb_yield, self, _sig_handler_block_ensure, + rb_ary_new3(2, self, id)); + return self; +} + +static VALUE +gobj_sig_handler_unblock(VALUE self, VALUE id) +{ + g_signal_handler_unblock(RVAL2GOBJ(self), NUM2ULONG(id)); + return self; +} + +static VALUE +gobj_sig_handler_disconnect(VALUE self, VALUE id) +{ + g_signal_handler_disconnect(RVAL2GOBJ(self), NUM2ULONG(id)); + return self; +} + +static VALUE +gobj_sig_handler_is_connected(VALUE self, VALUE id) +{ + return CBOOL2RVAL(g_signal_handler_is_connected(RVAL2GOBJ(self), NUM2ULONG(id))); +} + +#if 0 +gulong g_signal_handler_find (gpointer instance, + GSignalMatchType mask, + guint signal_id, + GQuark detail, + GClosure *closure, + gpointer func, + gpointer data); +guint g_signal_handlers_block_matched (gpointer instance, + GSignalMatchType mask, + guint signal_id, + GQuark detail, + GClosure *closure, + gpointer func, + gpointer data); +guint g_signal_handlers_unblock_matched (gpointer instance, + GSignalMatchType mask, + guint signal_id, + GQuark detail, + GClosure *closure, + gpointer func, + gpointer data); +guint g_signal_handlers_disconnect_matched (gpointer instance, + GSignalMatchType mask, + guint signal_id, + GQuark detail, + GClosure *closure, + gpointer func, + gpointer data); +#endif + +static VALUE +chain_from_overridden_body(struct emit_arg* arg) +{ + g_value_init(arg->instance_and_params->values, + G_TYPE_FROM_INSTANCE(RVAL2GOBJ(arg->self))); + rbgobj_rvalue_to_gvalue(arg->self, arg->instance_and_params->values); + + { + GValue* params = arg->instance_and_params->values + 1; + guint i; + for (i = 0; i < arg->query.n_params; i++) { + GType gtype = arg->query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE; + g_value_init(params + i, gtype); + rbgobj_rvalue_to_gvalue(rb_ary_entry(arg->args, i), params + i); + } + } + + { + gboolean use_ret = (arg->query.return_type != G_TYPE_NONE); + GValue return_value = G_VALUE_INIT; + + if (use_ret) + g_value_init(&return_value, + arg->query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE); + + g_signal_chain_from_overridden(arg->instance_and_params->values, + (use_ret) ? &return_value : NULL); + + if (use_ret) { + VALUE ret = GVAL2RVAL(&return_value); + g_value_unset(&return_value); + return ret; + } else { + return Qnil; + } + } +} + +static VALUE +gobj_sig_chain_from_overridden(int argc, VALUE *argv, VALUE self) +{ + struct emit_arg arg; + + { + GSignalInvocationHint* hint; + hint = g_signal_get_invocation_hint(RVAL2GOBJ(self)); + if (!hint) + rb_raise(rb_eRuntimeError, "can't get signal invocation hint"); + g_signal_query(hint->signal_id, &arg.query); + } + + if (arg.query.n_params != (guint)argc) + rb_raise(rb_eArgError, "wrong number of arguments(%d for %d)", + argc, arg.query.n_params); + + arg.self = self; + arg.args = rb_ary_new4(argc, argv); + arg.instance_and_params = g_value_array_new(1 + argc); + + return rb_ensure(chain_from_overridden_body, (VALUE)&arg, + emit_ensure, (VALUE)&arg); +} + +static VALUE +gobj_s_method_added(VALUE klass, VALUE id) +{ + const RGObjClassInfo* cinfo = rbgobj_lookup_class(klass); + const char* name = rb_id2name(SYM2ID(id)); + const int prefix_len = strlen(default_handler_method_prefix); + guint signal_id; + + if (cinfo->klass != klass) return Qnil; + if (strncmp(default_handler_method_prefix, name, prefix_len)) return Qnil; + + signal_id = g_signal_lookup(name + prefix_len, cinfo->gtype); + if (!signal_id) return Qnil; + + { + GSignalQuery query; + g_signal_query(signal_id, &query); + if (query.itype == cinfo->gtype) + return Qnil; + } + + { + VALUE proc = rb_funcall(mMetaInterface, rb_intern("signal_callback"), 2, + klass, id); + GClosure* rclosure = g_rclosure_new(proc, Qnil, + rbgobj_get_signal_func(signal_id)); + g_rclosure_attach((GClosure *)rclosure, klass); + g_signal_override_class_closure(signal_id, cinfo->gtype, rclosure); + } + + { + VALUE mod = rb_define_module_under(klass, RubyGObjectHookModule); + rb_include_module(klass, mod); + rbg_define_method(mod, name, gobj_sig_chain_from_overridden, -1); + } + + return Qnil; +} + +/**********************************************************************/ + +VALUE +rbgobj_signal_wrap(guint sig_id) +{ + VALUE result; + GSignalQuery* query; + + result = Data_Make_Struct(RG_TARGET_NAMESPACE, GSignalQuery, NULL, free, query); + g_signal_query(sig_id, query); + return result; +} + +static VALUE +rg_id(VALUE self) +{ + GSignalQuery* query; + Data_Get_Struct(self, GSignalQuery, query); + return UINT2NUM(query->signal_id); +} + +static VALUE +rg_name(VALUE self) +{ + GSignalQuery* query; + Data_Get_Struct(self, GSignalQuery, query); + return rb_str_new2(query->signal_name); +} + +static VALUE +rg_itype(VALUE self) +{ + GSignalQuery* query; + Data_Get_Struct(self, GSignalQuery, query); + return rbgobj_gtype_new(query->itype); +} + +static VALUE +rg_owner(VALUE self) +{ + GSignalQuery* query; + Data_Get_Struct(self, GSignalQuery, query); + return GTYPE2CLASS(query->itype); +} + +static VALUE +rg_return_type(VALUE self) +{ + GSignalQuery* query; + Data_Get_Struct(self, GSignalQuery, query); + return rbgobj_gtype_new(query->return_type); +} + +static VALUE +rg_flags(VALUE self) +{ + GSignalQuery* query; + Data_Get_Struct(self, GSignalQuery, query); + return UINT2NUM(query->signal_flags); +} + +static VALUE +rg_param_types(VALUE self) +{ + GSignalQuery* query; + VALUE result; + guint i; + Data_Get_Struct(self, GSignalQuery, query); + + result = rb_ary_new2(query->n_params); + for (i = 0; i < query->n_params; i++) + rb_ary_store(result, i, rbgobj_gtype_new(query->param_types[i])); + + return result; +} + +static VALUE +rg_inspect(VALUE self) +{ + GSignalQuery* query; + gchar* s; + VALUE result, v; + + Data_Get_Struct(self, GSignalQuery, query); + + v = rb_inspect(GTYPE2CLASS(query->itype)); + + s = g_strdup_printf("#<%s: %s#%s>", + rb_class2name(CLASS_OF(self)), + StringValuePtr(v), + query->signal_name); + result = rb_str_new2(s); + g_free(s); + + return result; +} + +#define query_is_flag(flag) \ + static VALUE \ + query_is_##flag(VALUE self) \ + { \ + GSignalQuery* query; \ + Data_Get_Struct(self, GSignalQuery, query); \ + return CBOOL2RVAL(query->signal_flags & flag); \ + } + +query_is_flag(G_SIGNAL_RUN_FIRST) +query_is_flag(G_SIGNAL_RUN_LAST) +query_is_flag(G_SIGNAL_RUN_CLEANUP) +query_is_flag(G_SIGNAL_NO_RECURSE) +query_is_flag(G_SIGNAL_DETAILED) +query_is_flag(G_SIGNAL_ACTION) +query_is_flag(G_SIGNAL_NO_HOOKS) + +static gboolean +hook_func(GSignalInvocationHint* ihint, + guint n_param_values, + const GValue* param_values, + gpointer data) +{ + GClosure* closure = data; + GValue ret_val =G_VALUE_INIT; + gboolean ret; + + g_value_init(&ret_val, G_TYPE_BOOLEAN); + g_closure_invoke(closure, &ret_val, n_param_values, param_values, ihint); + ret = g_value_get_boolean(&ret_val); + g_value_unset(&ret_val); + + return ret; +} + +static gulong +g_signal_add_emission_hook_closure (guint signal_id, + GQuark detail, + GClosure* closure) +{ + guint hook_id; + g_closure_ref(closure); + g_closure_sink(closure); + hook_id = g_signal_add_emission_hook(signal_id, detail, + &hook_func, closure, + (GDestroyNotify)&g_closure_unref); + return hook_id; +} + +static VALUE +rg_add_emission_hook(int argc, VALUE* argv, VALUE self) +{ + GSignalQuery* query; + VALUE proc; + guint hook_id; + GQuark detail = 0; + GClosure* closure; + + Data_Get_Struct(self, GSignalQuery, query); + + if (query->signal_flags & G_SIGNAL_DETAILED) { + VALUE detail_obj; + if (rb_scan_args(argc, argv, "01&", &detail_obj, &proc) == 1) { + if (SYMBOL_P(detail_obj)) + detail = g_quark_from_string(rb_id2name(SYM2ID(detail_obj))); + else + detail = g_quark_from_string(StringValuePtr(detail_obj)); + } + } else { + rb_scan_args(argc, argv, "00&", &proc); + } + + closure = g_rclosure_new(proc, Qnil, + rbgobj_get_signal_func(query->signal_id)); + g_rclosure_attach(closure, self); + hook_id = g_signal_add_emission_hook_closure(query->signal_id, detail, closure); + return ULONG2NUM(hook_id); +} + +static VALUE +rg_remove_emission_hook(VALUE self, VALUE hook_id) +{ + GSignalQuery* query; + Data_Get_Struct(self, GSignalQuery, query); + g_signal_remove_emission_hook(query->signal_id, NUM2ULONG(hook_id)); + return Qnil; +} + +/**********************************************************************/ + +void +rbgobj_define_action_methods(VALUE klass) +{ + GType gtype = CLASS2GTYPE(klass); + GString* source; + guint n_ids; + guint* ids; + guint i; + + if (gtype == G_TYPE_INTERFACE) + return; + + ids = g_signal_list_ids(gtype, &n_ids); + if (n_ids == 0) + return; + + source = g_string_new(NULL); + for (i = 0; i < n_ids; i++){ + GSignalQuery query; + g_signal_query(ids[i], &query); + + if (query.signal_flags & G_SIGNAL_ACTION) { + gchar* method_name = g_strdup(query.signal_name); + gchar* p; + GString* args; + guint j; + + for (p = method_name; *p; p++) + if (*p == '-') + *p = '_'; + + args = g_string_new(NULL); + for (j = 0; j < query.n_params; j++) + g_string_append_printf(args, ",x%d", j); + + g_string_append_printf( + source, + "def %s(%s)\n signal_emit('%s'%s)\nend\n", + method_name, + (query.n_params > 0) ? args->str + 1 : "", // Skip initial ',' + query.signal_name, + args->str); + + g_free(method_name); + g_string_free(args, TRUE); + } + } + + if (source->len > 0) + rb_funcall(klass, rb_intern("module_eval"), 3, + rb_str_new2(source->str), + rb_str_new2(__FILE__), + INT2NUM(__LINE__)); + g_string_free(source, TRUE); +} + +/**********************************************************************/ + +void +Init_gobject_gsignal(void) +{ + VALUE cSignalFlags, cSignalMatchType; + + RG_TARGET_NAMESPACE = rb_define_class_under(mGLib, "Signal", rb_cData); + + RG_DEF_METHOD(id, 0); + RG_DEF_METHOD(name, 0); + RG_DEF_METHOD(flags, 0); + RG_DEF_METHOD(itype, 0); + RG_DEF_METHOD(owner, 0); + RG_DEF_METHOD(return_type, 0); + RG_DEF_METHOD(param_types, 0); + RG_DEF_METHOD(inspect, 0); + + RG_DEF_METHOD(add_emission_hook, -1); + RG_DEF_METHOD(remove_emission_hook, 1); + + /* GSignalFlags */ + cSignalFlags = G_DEF_CLASS(G_TYPE_SIGNAL_FLAGS, "SignalFlags", mGLib); + G_DEF_CONSTANTS(RG_TARGET_NAMESPACE, G_TYPE_SIGNAL_FLAGS, "G_SIGNAL_"); + rb_define_const(cSignalFlags, "MASK", INT2NUM(G_SIGNAL_FLAGS_MASK)); + rb_define_const(RG_TARGET_NAMESPACE, "FLAGS_MASK", INT2NUM(G_SIGNAL_FLAGS_MASK)); + + rbg_define_method(RG_TARGET_NAMESPACE, "run_first?", query_is_G_SIGNAL_RUN_FIRST, 0); + rbg_define_method(RG_TARGET_NAMESPACE, "run_last?", query_is_G_SIGNAL_RUN_LAST, 0); + rbg_define_method(RG_TARGET_NAMESPACE, "run_cleanup?", query_is_G_SIGNAL_RUN_CLEANUP, 0); + rbg_define_method(RG_TARGET_NAMESPACE, "no_recurse?", query_is_G_SIGNAL_NO_RECURSE, 0); + rbg_define_method(RG_TARGET_NAMESPACE, "detailed?", query_is_G_SIGNAL_DETAILED, 0); + rbg_define_method(RG_TARGET_NAMESPACE, "action?", query_is_G_SIGNAL_ACTION, 0); + rbg_define_method(RG_TARGET_NAMESPACE, "no_hooks?", query_is_G_SIGNAL_NO_HOOKS, 0); + + /* GConnectFlags */ + G_DEF_CLASS(G_TYPE_CONNECT_FLAGS, "ConnectFlags", mGLib); + G_DEF_CONSTANTS(RG_TARGET_NAMESPACE, G_TYPE_CONNECT_FLAGS, "G_"); + + /* GSignalMatchType */ + cSignalMatchType = G_DEF_CLASS(G_TYPE_SIGNAL_MATCH_TYPE, + "SignalMatchType", mGLib); + G_DEF_CONSTANTS(RG_TARGET_NAMESPACE, G_TYPE_SIGNAL_MATCH_TYPE, "G_SIGNAL_"); + rb_define_const(cSignalMatchType, "MASK", INT2NUM(G_SIGNAL_MATCH_MASK)); + rb_define_const(RG_TARGET_NAMESPACE, "MATCH_MASK", INT2NUM(G_SIGNAL_MATCH_MASK)); + + rb_define_const(RG_TARGET_NAMESPACE, "TYPE_STATIC_SCOPE", INT2FIX(G_SIGNAL_TYPE_STATIC_SCOPE)); + + eNoSignalError = rb_define_class_under(mGLib, "NoSignalError", rb_eNameError); + + signal_func_table = rb_hash_new(); + rb_global_variable(&signal_func_table); + + signal_call_func_table = rb_hash_new(); + rb_global_variable(&signal_call_func_table); + + rbg_define_method(mMetaInterface, "signal_new", gobj_s_signal_new, -1); + rbg_define_method(mMetaInterface, "signals", gobj_s_signals, -1); + rbg_define_method(mMetaInterface, "signal", gobj_s_signal, 1); + + rbg_define_method(cInstantiatable, "signal_has_handler_pending?", + gobj_sig_has_handler_pending, -1); + rbg_define_method(cInstantiatable, "signal_connect", gobj_sig_connect, -1); + rbg_define_method(cInstantiatable, "signal_connect_after", + gobj_sig_connect_after, -1); + +#if 0 + rbg_define_method(cInstantiatable, "signal_invocation_hint", + gobj_sig_get_invocation_hint, 0); +#endif + + rbg_define_method(cInstantiatable, "signal_emit", + gobj_sig_emit, -1); + rbg_define_method(cInstantiatable, "signal_emit_stop", + gobj_sig_emit_stop, 1); + rbg_define_method(cInstantiatable, "signal_handler_block", + gobj_sig_handler_block, 1); + rbg_define_method(cInstantiatable, "signal_handler_unblock", + gobj_sig_handler_unblock, 1); + rbg_define_method(cInstantiatable, "signal_handler_disconnect", + gobj_sig_handler_disconnect, 1); + + rbg_define_method(cInstantiatable, "signal_handler_is_connected?", + gobj_sig_handler_is_connected, 1); + + rbg_define_singleton_method(cInstantiatable, "method_added", + gobj_s_method_added, 1); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobj_strv.c (+44 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbgobj_strv.c 2017-02-15 13:19:47 +0900 (44a78a1) @@ -0,0 +1,44 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2005 Masao Mutoh + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" + +static VALUE +strv_to_ruby(const GValue *from) +{ + return STRV2RVAL((const gchar **)g_value_get_boxed(from)); +} + +static void +strv_from_ruby(VALUE from, GValue *to) +{ + const gchar **strings = RVAL2STRV(from); + g_value_set_boxed(to, strings); + g_free(strings); +} + +void +Init_gobject_gstrv(void) +{ + /* GStrv is treated as Array */ + rbgobj_register_g2r_func(G_TYPE_STRV, strv_to_ruby); + rbgobj_register_r2g_func(G_TYPE_STRV, strv_from_ruby); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobj_type.c (+852 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbgobj_type.c 2017-02-15 13:19:47 +0900 (a8a8009) @@ -0,0 +1,852 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2002-2013 Ruby-GNOME2 Project Team + * Copyright (C) 2002,2003 Masahiro Sakai + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" + +#define RG_TARGET_NAMESPACE rbgobj_cType + +/**********************************************************************/ +/* Type Mapping */ + +#ifndef rb_cMutex +static VALUE rb_cMutex; +#endif +static VALUE lookup_class_mutex; + +static ID id_new; +static ID id_superclass; +static ID id_lock; +static ID id_unlock; +static GHashTable *gtype_to_cinfo; +static VALUE klass_to_cinfo; + +static GHashTable* dynamic_gtype_list; +typedef struct { + const gchar* name; + VALUE module; + RGMarkFunc mark; + RGFreeFunc free; + int flags; /* RGObjClassFlag */ +} RGObjClassInfoDynamic; + +typedef struct { + VALUE parent; + GType gtype; + gboolean create_class; +} RGObjClassByGtypeData; + +static void +cinfo_mark(RGObjClassInfo* cinfo) +{ + rb_gc_mark(cinfo->klass); +} + +const RGObjClassInfo * +rbgobj_lookup_class(VALUE klass) +{ + VALUE data = rb_hash_aref(klass_to_cinfo, klass); + if (!NIL_P(data)){ + RGObjClassInfo* cinfo; + Data_Get_Struct(data, RGObjClassInfo, cinfo); + return cinfo; + } + + if (TYPE(klass) == T_CLASS) { + VALUE super; + super = rb_funcall(klass, id_superclass, 0); + return rbgobj_lookup_class(super); + } + + rb_raise(rb_eRuntimeError, "can't get gobject class information"); +} + +static const RGObjClassInfo *rbgobj_lookup_class_by_gtype_without_lock(GType gtype, + VALUE parent, + gboolean create_class); + +static VALUE +get_superclass(GType gtype) +{ + VALUE super_class; + + if (rbgobj_convert_get_superclass(gtype, &super_class)) + return super_class; + + switch (gtype) { + case G_TYPE_PARAM: + case G_TYPE_OBJECT: + return cInstantiatable; + case G_TYPE_BOXED: + return rb_cObject; + case G_TYPE_POINTER: + return rb_cData; + case G_TYPE_ENUM: + case G_TYPE_FLAGS: + return rb_cObject; + default: + { + GType parent_type; + + parent_type = g_type_parent(gtype); + if (parent_type == G_TYPE_INVALID) { + return cInstantiatable; + } else { + const RGObjClassInfo *cinfo_super; + cinfo_super = + rbgobj_lookup_class_by_gtype_without_lock(parent_type, + Qnil, + TRUE); + return cinfo_super->klass; + } + } + } +} + +static const RGObjClassInfo * +rbgobj_lookup_class_by_gtype_without_lock(GType gtype, VALUE parent, + gboolean create_class) +{ + GType fundamental_type; + RGObjClassInfo* cinfo; + RGObjClassInfoDynamic* cinfod; + void* gclass = NULL; + VALUE c; + + if (gtype == G_TYPE_INVALID) + return NULL; + + cinfo = g_hash_table_lookup(gtype_to_cinfo, GUINT_TO_POINTER(gtype)); + if (cinfo) + return cinfo; + + if (!create_class) + return NULL; + + c = Data_Make_Struct(rb_cData, RGObjClassInfo, cinfo_mark, NULL, cinfo); + cinfo->gtype = gtype; + cinfo->mark = NULL; + cinfo->free = NULL; + cinfo->flags = 0; + + fundamental_type = G_TYPE_FUNDAMENTAL(gtype); + switch (fundamental_type){ + case G_TYPE_POINTER: + case G_TYPE_BOXED: + case G_TYPE_PARAM: + case G_TYPE_OBJECT: + case G_TYPE_ENUM: + case G_TYPE_FLAGS: + if (NIL_P(parent)) parent = get_superclass(gtype); + cinfo->klass = rb_funcall(rb_cClass, id_new, 1, parent); + break; + + case G_TYPE_INTERFACE: + cinfo->klass = rb_module_new(); + break; + + default: + if (NIL_P(parent)) parent = get_superclass(gtype); + if (NIL_P(parent)) { + fprintf(stderr, + "%s: %s's fundamental type %s isn't supported\n", + "rbgobj_lookup_class_by_gtype", + g_type_name(gtype), + g_type_name(fundamental_type)); + return NULL; + } + cinfo->klass = rb_funcall(rb_cClass, id_new, 1, parent); + } + + cinfod = (RGObjClassInfoDynamic *)g_hash_table_lookup(dynamic_gtype_list, + g_type_name(gtype)); + if (cinfod){ + cinfo->mark = cinfod->mark; + cinfo->free = cinfod->free; + rb_define_const(cinfod->module, cinfod->name, cinfo->klass); + } + + rb_hash_aset(klass_to_cinfo, cinfo->klass, c); + g_hash_table_insert(gtype_to_cinfo, GUINT_TO_POINTER(gtype), cinfo); + + if (G_TYPE_IS_CLASSED(gtype)) + gclass = g_type_class_ref(gtype); + + if (G_TYPE_IS_INSTANTIATABLE(gtype) || G_TYPE_IS_INTERFACE(gtype)) + rbgobj_define_action_methods(cinfo->klass); + + if (G_TYPE_IS_INSTANTIATABLE(gtype)){ + GType* interfaces = NULL; + guint n_interfaces = 0; + guint i; + + interfaces = g_type_interfaces(gtype, &n_interfaces); + for (i = 0; i < n_interfaces; i++){ + const RGObjClassInfo *iface_cinfo; + iface_cinfo = + rbgobj_lookup_class_by_gtype_without_lock(interfaces[i], + Qnil, + TRUE); + rb_include_module(cinfo->klass, iface_cinfo->klass); + } + g_free(interfaces); + } + + if (!rbgobj_convert_type_init_hook(gtype, cinfo->klass)) { + switch (fundamental_type) { + case G_TYPE_OBJECT: + rbgobj_init_object_class(cinfo->klass); + break; + case G_TYPE_ENUM: + rbgobj_init_enum_class(cinfo->klass); + break; + case G_TYPE_FLAGS: + rbgobj_init_flags_class(cinfo->klass); + break; + case G_TYPE_INTERFACE: + rbgobj_init_interface(cinfo->klass); + break; + default: + rbgobj_convert_type_init_hook(fundamental_type, cinfo->klass); + break; + } + } + + if (gclass) + g_type_class_unref(gclass); + + return cinfo; +} + +static VALUE +rbgobj_lookup_class_by_gtype_body(VALUE data) +{ + RGObjClassByGtypeData *cdata = (RGObjClassByGtypeData *)data; + const RGObjClassInfo *cinfo; + + cinfo = rbgobj_lookup_class_by_gtype_without_lock(cdata->gtype, + cdata->parent, + cdata->create_class); + return (VALUE)cinfo; +} + +static VALUE +rbgobj_lookup_class_by_gtype_ensure(G_GNUC_UNUSED VALUE data) +{ + rb_funcall(lookup_class_mutex, id_unlock, 0); + return Qundef; +} + +const RGObjClassInfo * +rbgobj_lookup_class_by_gtype(GType gtype, VALUE parent) +{ + return rbgobj_lookup_class_by_gtype_full(gtype, parent, TRUE); +} + +const RGObjClassInfo * +rbgobj_lookup_class_by_gtype_full(GType gtype, VALUE parent, + gboolean create_class) +{ + const RGObjClassInfo *info; + RGObjClassByGtypeData data; + + info = rbgobj_lookup_class_by_gtype_without_lock(gtype, parent, FALSE); + if (info) { + return info; + } + + if (!create_class) { + return NULL; + } + + data.gtype = gtype; + data.parent = parent; + data.create_class = create_class; + + rb_funcall(lookup_class_mutex, id_lock, 0); + return (RGObjClassInfo *)rb_ensure(rbgobj_lookup_class_by_gtype_body, + (VALUE)&data, + rbgobj_lookup_class_by_gtype_ensure, + (VALUE)&data); +} + +VALUE +rbgobj_gtype_to_ruby_class(GType gtype) +{ + const RGObjClassInfo *cinfo; + + cinfo = GTYPE2CINFO(gtype); + return cinfo ? cinfo->klass : Qnil; +} + +VALUE +rbgobj_define_class(GType gtype, const gchar *name, VALUE module, + RGMarkFunc mark, RGFreeFunc free, VALUE parent) +{ + RGObjClassInfo* cinfo; + if (gtype == 0) + rb_bug("rbgobj_define_class: Invalid gtype [%s]\n", name); + + cinfo = (RGObjClassInfo*)rbgobj_lookup_class_by_gtype(gtype, parent); + cinfo->mark = mark; + cinfo->free = free; + rb_define_const(module, name, cinfo->klass); + return cinfo->klass; +} + +void +rbgobj_register_mark_func(GType gtype, RGMarkFunc mark) +{ + RGObjClassInfo *cinfo; + + cinfo = + (RGObjClassInfo *)rbgobj_lookup_class_by_gtype_full(gtype, Qnil, FALSE); + if (!cinfo) { + rb_raise(rb_eArgError, + "rbgobj_register_free_func(): no class is defined: <%s>", + g_type_name(gtype)); + } + cinfo->mark = mark; +} + +void +rbgobj_register_free_func(GType gtype, RGFreeFunc free) +{ + RGObjClassInfo *cinfo; + + cinfo = + (RGObjClassInfo *)rbgobj_lookup_class_by_gtype_full(gtype, Qnil, FALSE); + if (!cinfo) { + rb_raise(rb_eArgError, + "rbgobj_register_free_func(): no class is defined: <%s>", + g_type_name(gtype)); + } + cinfo->free = free; +} + +VALUE +rbgobj_define_class_dynamic(const gchar *gtype_name, const gchar *name, + VALUE module, RGMarkFunc mark, RGFreeFunc free) +{ + RGObjClassInfoDynamic* cinfo; + cinfo = (RGObjClassInfoDynamic*)g_new(RGObjClassInfoDynamic, 1); + cinfo->name = name; + cinfo->module = module; + cinfo->mark = mark; + cinfo->free = free; + g_hash_table_insert(dynamic_gtype_list, (void*)gtype_name, (void*)cinfo); + return Qnil; +} + +void +rbgobj_register_class(VALUE klass, + GType gtype, + gboolean klass2gtype, + gboolean gtype2klass) +{ + RGObjClassInfo* cinfo = NULL; + VALUE c = Qnil; + + if (klass2gtype) + c = Data_Make_Struct(rb_cData, RGObjClassInfo, cinfo_mark, NULL, cinfo); + if (gtype2klass && !cinfo) + cinfo = g_new(RGObjClassInfo, 1); + + if (cinfo) { + cinfo->klass = klass; + cinfo->gtype = gtype; + cinfo->mark = NULL; + cinfo->free = NULL; + cinfo->flags = 0; + } + + if (klass2gtype) + rb_hash_aset(klass_to_cinfo, cinfo->klass, c); + + if (gtype2klass) + g_hash_table_insert(gtype_to_cinfo, GUINT_TO_POINTER(gtype), cinfo); +} + +#define _register_fundamental_klass_to_gtype(klass, gtype) \ + rbgobj_register_class(klass, gtype, TRUE, FALSE) + +#define _register_fundamental_gtype_to_klass(gtype,klass) \ + rbgobj_register_class(klass, gtype, FALSE, TRUE) + +static void +init_typemap(void) +{ + id_new = rb_intern("new"); + id_superclass = rb_intern("superclass"); + + gtype_to_cinfo = g_hash_table_new(g_direct_hash, g_direct_equal); + rb_global_variable(&klass_to_cinfo); + klass_to_cinfo = rb_hash_new(); +#ifndef RUBY_INTEGER_UNIFICATION + _register_fundamental_klass_to_gtype(rb_cFixnum, G_TYPE_LONG); +#endif + _register_fundamental_klass_to_gtype(rb_cFloat, G_TYPE_DOUBLE); + _register_fundamental_klass_to_gtype(rb_cInteger, G_TYPE_LONG); + _register_fundamental_klass_to_gtype(rb_cString, G_TYPE_STRING); + _register_fundamental_klass_to_gtype(rb_cSymbol, G_TYPE_STRING); + _register_fundamental_klass_to_gtype(Qnil, G_TYPE_NONE); + _register_fundamental_klass_to_gtype(rb_cNilClass, G_TYPE_NONE); + _register_fundamental_klass_to_gtype(rb_cTrueClass, G_TYPE_BOOLEAN); + _register_fundamental_klass_to_gtype(rb_cFalseClass, G_TYPE_BOOLEAN); + _register_fundamental_klass_to_gtype(Qtrue, G_TYPE_BOOLEAN); + _register_fundamental_klass_to_gtype(Qfalse, G_TYPE_BOOLEAN); + _register_fundamental_klass_to_gtype(rb_cObject, RBGOBJ_TYPE_RUBY_VALUE); + + _register_fundamental_gtype_to_klass(G_TYPE_UINT, rb_cInteger); + _register_fundamental_gtype_to_klass(G_TYPE_FLOAT, rb_cFloat); + _register_fundamental_gtype_to_klass(G_TYPE_DOUBLE, rb_cFloat); + _register_fundamental_gtype_to_klass(G_TYPE_INT64, rb_cInteger); + _register_fundamental_gtype_to_klass(G_TYPE_UINT64, rb_cInteger); + _register_fundamental_gtype_to_klass(G_TYPE_INT, rb_cInteger); + _register_fundamental_gtype_to_klass(G_TYPE_LONG, rb_cInteger); +#ifdef RUBY_INTEGER_UNIFICATION + _register_fundamental_gtype_to_klass(G_TYPE_CHAR, rb_cInteger); + _register_fundamental_gtype_to_klass(G_TYPE_UCHAR, rb_cInteger); +#else + _register_fundamental_gtype_to_klass(G_TYPE_CHAR, rb_cFixnum); + _register_fundamental_gtype_to_klass(G_TYPE_UCHAR, rb_cFixnum); +#endif + _register_fundamental_gtype_to_klass(G_TYPE_STRING, rb_cString); + _register_fundamental_gtype_to_klass(G_TYPE_ULONG, rb_cInteger); + _register_fundamental_gtype_to_klass(G_TYPE_NONE, rb_cNilClass); + _register_fundamental_gtype_to_klass(G_TYPE_BOOLEAN, rb_cTrueClass); +} + +/**********************************************************************/ +/* GLib::Type */ + +VALUE RG_TARGET_NAMESPACE; +static ID id_gtype; + +VALUE +rbgobj_gtype_new(GType gtype) +{ + VALUE result = rb_obj_alloc(RG_TARGET_NAMESPACE); + VALUE arg = ULONG2NUM(gtype); + rb_obj_call_init(result, 1, &arg); + return result; +} + +GType +rbgobj_gtype_get(VALUE self) +{ + if (RVAL2CBOOL(rb_obj_is_kind_of(self, RG_TARGET_NAMESPACE))) { + return NUM2ULONG(rb_ivar_get(self, id_gtype)); + } else { + return CLASS2GTYPE(self); + } + rb_raise(rb_eTypeError, "Not a GLib::Type"); +} + +static VALUE +rg_initialize(VALUE self, VALUE type) +{ + GType gtype; + + if (RVAL2CBOOL(rb_obj_is_kind_of(type, rb_cInteger))) { + gtype = NUM2ULONG(type); + if (!g_type_name(gtype)) + gtype = G_TYPE_INVALID; + } else { + gtype = g_type_from_name(StringValuePtr(type)); + } + + if (G_TYPE_INVALID == gtype) + rb_raise(rb_eArgError, "invalid GType"); + + rb_ivar_set(self, id_gtype, ULONG2NUM(gtype)); + + return Qnil; +} + +static VALUE +rg_inspect(VALUE self) +{ + GType gtype = rbgobj_gtype_get(self); + gchar* str; + VALUE result; + + str = g_strdup_printf("GLib::Type[\"%s\"]", g_type_name(gtype)); + result = rb_str_new2(str); + g_free(str); + + return result; +} + +static VALUE +rg_operator_type_compare(VALUE self, VALUE other) +{ + if (!RVAL2CBOOL(rb_obj_is_kind_of(other, RG_TARGET_NAMESPACE))) + return Qnil; + else { + GType a = rbgobj_gtype_get(self); + GType b = rbgobj_gtype_get(other); + + if (a==b) + return INT2FIX(0); + else if (g_type_is_a(a,b)) + return INT2FIX(-1); + else if (g_type_is_a(b,a)) + return INT2FIX(1); + else + return Qnil; + } +} + +static VALUE +rg_operator_type_eq(VALUE self, VALUE other) +{ + if (!RVAL2CBOOL(rb_obj_is_kind_of(other, RG_TARGET_NAMESPACE))) + return Qnil; + else { + GType a = rbgobj_gtype_get(self); + GType b = rbgobj_gtype_get(other); + return CBOOL2RVAL(a == b); + } +} + +static VALUE +rg_operator_type_lt_eq(VALUE self, VALUE other) +{ + if (!RVAL2CBOOL(rb_obj_is_kind_of(other, RG_TARGET_NAMESPACE))) + return Qnil; + else { + GType a = rbgobj_gtype_get(self); + GType b = rbgobj_gtype_get(other); + return CBOOL2RVAL(g_type_is_a(a, b)); + } +} + +static VALUE +rg_operator_type_gt_eq(VALUE self, VALUE other) +{ + if (!RVAL2CBOOL(rb_obj_is_kind_of(other, RG_TARGET_NAMESPACE))) + return Qnil; + else { + GType a = rbgobj_gtype_get(self); + GType b = rbgobj_gtype_get(other); + return CBOOL2RVAL(g_type_is_a(b, a)); + } +} + +static VALUE +rg_operator_type_lt(VALUE self, VALUE other) +{ + if (!RVAL2CBOOL(rb_obj_is_kind_of(other, RG_TARGET_NAMESPACE))) + return Qnil; + else { + GType a = rbgobj_gtype_get(self); + GType b = rbgobj_gtype_get(other); + return CBOOL2RVAL(g_type_is_a(a, b) && a != b); + } +} + +static VALUE +rg_operator_type_gt(VALUE self, VALUE other) +{ + if (!RVAL2CBOOL(rb_obj_is_kind_of(other, RG_TARGET_NAMESPACE))) + return Qnil; + else { + GType a = rbgobj_gtype_get(self); + GType b = rbgobj_gtype_get(other); + return CBOOL2RVAL(g_type_is_a(b, a) && a != b); + } +} + +static VALUE +rg_hash(VALUE self) +{ + return rb_ivar_get(self, id_gtype); +} + +static VALUE +rg_to_class(VALUE self) +{ + return GTYPE2CLASS(rbgobj_gtype_get(self)); +} + +static VALUE +rg_fundamental(VALUE self) +{ + return rbgobj_gtype_new(G_TYPE_FUNDAMENTAL(rbgobj_gtype_get(self))); +} + +static VALUE +rg_fundamental_p(VALUE self) +{ + return CBOOL2RVAL(G_TYPE_IS_FUNDAMENTAL(rbgobj_gtype_get(self))); +} + +static VALUE +rg_derived_p(VALUE self) +{ + return CBOOL2RVAL(G_TYPE_IS_DERIVED(rbgobj_gtype_get(self))); +} + +static VALUE +rg_interface_p(VALUE self) +{ + return CBOOL2RVAL(G_TYPE_IS_INTERFACE(rbgobj_gtype_get(self))); +} + +static VALUE +rg_classed_p(VALUE self) +{ + return CBOOL2RVAL(G_TYPE_IS_CLASSED(rbgobj_gtype_get(self))); +} + +static VALUE +rg_instantiatable_p(VALUE self) +{ + return CBOOL2RVAL(G_TYPE_IS_INSTANTIATABLE(rbgobj_gtype_get(self))); +} + +static VALUE +rg_derivable_p(VALUE self) +{ + return CBOOL2RVAL(G_TYPE_IS_DERIVABLE(rbgobj_gtype_get(self))); +} + +static VALUE +rg_deep_derivable_p(VALUE self) +{ + return CBOOL2RVAL(G_TYPE_IS_DEEP_DERIVABLE(rbgobj_gtype_get(self))); +} + +static VALUE +rg_abstract_p(VALUE self) +{ + return CBOOL2RVAL(G_TYPE_IS_ABSTRACT(rbgobj_gtype_get(self))); +} + +static VALUE +rg_value_abstract_p(VALUE self) +{ + return CBOOL2RVAL(G_TYPE_IS_VALUE_ABSTRACT(rbgobj_gtype_get(self))); +} + +static VALUE +rg_value_type_p(VALUE self) +{ + return CBOOL2RVAL(G_TYPE_IS_VALUE_TYPE(rbgobj_gtype_get(self))); +} + +static VALUE +rg_has_value_table(VALUE self) +{ + return CBOOL2RVAL(G_TYPE_HAS_VALUE_TABLE(rbgobj_gtype_get(self))); +} + +static VALUE +rg_name(VALUE self) +{ + return rb_str_new2(g_type_name(rbgobj_gtype_get(self))); +} + +static VALUE +rg_parent(VALUE self) +{ + GType parent = g_type_parent(rbgobj_gtype_get(self)); + return parent ? rbgobj_gtype_new(parent) : Qnil; +} + +static VALUE +rg_depth(VALUE self) +{ + return UINT2NUM(g_type_depth(rbgobj_gtype_get(self))); +} + +static VALUE +rg_next_base(VALUE leaf_type, VALUE root_type) +{ + GType ret = g_type_next_base(rbgobj_gtype_get(leaf_type), + rbgobj_gtype_get(root_type)); + return ret ? rbgobj_gtype_new(ret) : Qnil; +} + +static VALUE +rg_type_is_a_p(VALUE self, VALUE is_a_type) +{ + return CBOOL2RVAL(g_type_is_a(rbgobj_gtype_get(self), rbgobj_gtype_get(is_a_type))); +} + +#if 0 +gpointer g_type_class_ref (GType type); +gpointer g_type_class_peek (GType type); +void g_type_class_unref (gpointer g_class); +gpointer g_type_class_peek_parent (gpointer g_class); +gpointer g_type_interface_peek (gpointer instance_class, + GType iface_type); +gpointer g_type_interface_peek_parent (gpointer g_iface); +#endif + +static VALUE +rg_children(VALUE self) +{ + guint n_children; + GType* types; + VALUE result; + guint i; + + types = g_type_children(rbgobj_gtype_get(self), &n_children); + result = rb_ary_new2(n_children); + for (i = 0; i < n_children; i++) + rb_ary_store(result, i, rbgobj_gtype_new(types[i])); + g_free(types); + + return result; +} + +static VALUE +rg_interfaces(VALUE self) +{ + guint n_interfaces; + GType* types; + VALUE result; + guint i; + + types = g_type_interfaces(rbgobj_gtype_get(self), &n_interfaces); + result = rb_ary_new2(n_interfaces); + for (i = 0; i < n_interfaces; i++) + rb_ary_store(result, i, rbgobj_gtype_new(types[i])); + g_free(types); + + return result; +} + +static VALUE +rg_class_size(VALUE self) +{ + GTypeQuery query; + g_type_query(rbgobj_gtype_get(self), &query); + return UINT2NUM(query.class_size); +} + +static VALUE +rg_instance_size(VALUE self) +{ + GTypeQuery query; + g_type_query(rbgobj_gtype_get(self), &query); + return UINT2NUM(query.instance_size); +} + +static inline void +_def_fundamental_type(VALUE ary, GType gtype, const char* name) +{ + VALUE c = rbgobj_gtype_new(gtype); + rb_define_const(RG_TARGET_NAMESPACE, name, c); + rb_ary_push(ary, c); +} + +/**********************************************************************/ + +void +Init_gobject_gtype(void) +{ +#if !GLIB_CHECK_VERSION(2, 35, 1) + g_type_init(); +#endif + + init_typemap(); + + /* type */ +#ifndef rb_cMutex + rb_cMutex = rb_const_get(rb_cObject, rb_intern("Mutex")); +#endif + id_lock = rb_intern("lock"); + id_unlock = rb_intern("unlock"); + lookup_class_mutex = rb_funcall(rb_cMutex, id_new, 0); + rb_iv_set(mGLib, "lookup_class_mutex", lookup_class_mutex); + + dynamic_gtype_list = g_hash_table_new(g_str_hash, g_str_equal); + id_gtype = rb_intern("__gobject_gtype__"); + + RG_TARGET_NAMESPACE = rb_define_class_under(mGLib, "Type", rb_cObject); + + rb_define_alias(CLASS_OF(RG_TARGET_NAMESPACE), "[]", "new"); + RG_DEF_METHOD(initialize, 1); + RG_DEF_METHOD(inspect, 0); + RG_DEF_METHOD_OPERATOR("<=>", type_compare, 1); + RG_DEF_METHOD_OPERATOR("==", type_eq, 1); + RG_DEF_METHOD_OPERATOR("<=", type_lt_eq, 1); + RG_DEF_METHOD_OPERATOR(">=", type_gt_eq, 1); + RG_DEF_METHOD_OPERATOR("<", type_lt, 1); + RG_DEF_METHOD_OPERATOR(">", type_gt, 1); + RG_DEF_ALIAS("eql?", "=="); + RG_DEF_METHOD(hash, 0); + RG_DEF_ALIAS("to_i", "hash"); + RG_DEF_ALIAS("to_int", "hash"); + RG_DEF_METHOD(to_class, 0); + + RG_DEF_METHOD(fundamental, 0); + RG_DEF_METHOD_P(fundamental, 0); + RG_DEF_METHOD_P(derived, 0); + RG_DEF_METHOD_P(interface, 0); + RG_DEF_METHOD_P(classed, 0); + RG_DEF_METHOD_P(instantiatable, 0); + RG_DEF_METHOD_P(derivable, 0); + RG_DEF_METHOD_P(deep_derivable, 0); + RG_DEF_METHOD_P(abstract, 0); + RG_DEF_METHOD_P(value_abstract, 0); + RG_DEF_METHOD_P(value_type, 0); + RG_DEF_METHOD(has_value_table, 0); + + RG_DEF_METHOD(name, 0); + RG_DEF_ALIAS("to_s", "name"); + RG_DEF_METHOD(parent, 0); + RG_DEF_METHOD(depth, 0); + RG_DEF_METHOD(next_base, 1); + RG_DEF_METHOD_P(type_is_a, 1); + RG_DEF_METHOD(children, 0); + RG_DEF_METHOD(interfaces, 0); + RG_DEF_METHOD(class_size, 0); + RG_DEF_METHOD(instance_size, 0); + + { + VALUE ary = rb_ary_new(); + rb_define_const(RG_TARGET_NAMESPACE, "FUNDAMENTAL_MAX", INT2FIX(G_TYPE_FUNDAMENTAL_MAX)); + _def_fundamental_type(ary, G_TYPE_NONE, "NONE"); + _def_fundamental_type(ary, G_TYPE_INTERFACE, "INTERFACE"); + _def_fundamental_type(ary, G_TYPE_CHAR, "CHAR"); + _def_fundamental_type(ary, G_TYPE_UCHAR, "UCHAR"); + _def_fundamental_type(ary, G_TYPE_BOOLEAN, "BOOLEAN"); + _def_fundamental_type(ary, G_TYPE_INT, "INT"); + _def_fundamental_type(ary, G_TYPE_UINT, "UINT"); + _def_fundamental_type(ary, G_TYPE_LONG, "LONG"); + _def_fundamental_type(ary, G_TYPE_ULONG, "ULONG"); + _def_fundamental_type(ary, G_TYPE_INT64, "INT64"); + _def_fundamental_type(ary, G_TYPE_UINT64, "UINT64"); + _def_fundamental_type(ary, G_TYPE_ENUM, "ENUM"); + _def_fundamental_type(ary, G_TYPE_FLAGS, "FLAGS"); + _def_fundamental_type(ary, G_TYPE_FLOAT, "FLOAT"); + _def_fundamental_type(ary, G_TYPE_DOUBLE, "DOUBLE"); + _def_fundamental_type(ary, G_TYPE_STRING, "STRING"); + _def_fundamental_type(ary, G_TYPE_POINTER, "POINTER"); + _def_fundamental_type(ary, G_TYPE_BOXED, "BOXED"); + _def_fundamental_type(ary, G_TYPE_PARAM, "PARAM"); + _def_fundamental_type(ary, G_TYPE_OBJECT, "OBJECT"); + rb_define_const(RG_TARGET_NAMESPACE, "FUNDAMENTAL_TYPES", ary); /* FIXME: better name */ + } +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobj_typeinstance.c (+134 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbgobj_typeinstance.c 2017-02-15 13:19:47 +0900 (2ac0795) @@ -0,0 +1,134 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2002-2006 Ruby-GNOME2 Project Team + * Copyright (C) 2002,2003 Masahiro Sakai + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" + +#define RG_TARGET_NAMESPACE cInstantiatable + +VALUE RG_TARGET_NAMESPACE; + +typedef void (*ClassInfoCallbackFunc) (gpointer instance, + const RGObjClassInfo *class_info, + gpointer user_data); + +static G_GNUC_NORETURN VALUE +instantiatable_s_allocate(G_GNUC_UNUSED VALUE klass) +{ + rb_raise(rb_eTypeError, "abstract class"); +} + +static VALUE +rg_gtype(VALUE self) +{ + return rbgobj_gtype_new(G_TYPE_FROM_INSTANCE(rbgobj_instance_from_ruby_object(self))); +} + +static G_GNUC_NORETURN VALUE +rg_clone(VALUE self) +{ + rb_raise(rb_eTypeError, "can't clone %s", rb_class2name(CLASS_OF(self))); +} + +/**********************************************************************/ + +static void +each_cinfo(gpointer instance, ClassInfoCallbackFunc func, gpointer user_data) +{ + const GType gtype = G_TYPE_FROM_INSTANCE(instance); + GType* interfaces; + guint n_interfaces = 0; + + interfaces = g_type_interfaces(gtype, &n_interfaces); + { + guint i; + for (i = 0; i < n_interfaces; i++) { + const RGObjClassInfo *info; + + info = GTYPE2CINFO_NO_CREATE(interfaces[i]); + if (info) + func(instance, info, user_data); + } + } + g_free(interfaces); + + { + GType type; + for (type = gtype; type != G_TYPE_INVALID; type = g_type_parent(type)) { + const RGObjClassInfo *info; + + info = GTYPE2CINFO_NO_CREATE(type); + if (info) + func(instance, info, user_data); + } + } +} + +static void +call_cinfo_free(gpointer instance, const RGObjClassInfo *cinfo, G_GNUC_UNUSED gpointer user_data) +{ + if (cinfo->free) cinfo->free(instance); +} + +static void +call_cinfo_mark(gpointer instance, const RGObjClassInfo *cinfo, G_GNUC_UNUSED gpointer user_data) +{ + if (cinfo->mark) cinfo->mark(instance); +} + +void +rbgobj_instance_call_cinfo_mark(gpointer instance) +{ + each_cinfo(instance, call_cinfo_mark, NULL); +} + +void +rbgobj_instance_call_cinfo_free(gpointer instance) +{ + each_cinfo(instance, call_cinfo_free, NULL); +} + +gboolean +rbgobj_gc_mark_instance(gpointer instance) +{ + VALUE obj = rbgobj_ruby_object_from_instance2(instance, FALSE); + + if (NIL_P(obj)) { + return FALSE; + } + + rb_gc_mark(obj); + return TRUE; +} + +/**********************************************************************/ + +void +Init_gobject_typeinstance(void) +{ + /* should be renamed to GLib::Instance? */ + RG_TARGET_NAMESPACE = rb_define_class_under(mGLib, "Instantiatable", rb_cObject); + rb_extend_object(RG_TARGET_NAMESPACE, mMetaInterface); + + rb_define_alloc_func(RG_TARGET_NAMESPACE, (VALUE(*)_((VALUE)))instantiatable_s_allocate); + RG_DEF_METHOD(gtype, 0); + RG_DEF_METHOD(clone, 0); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobj_typeinterface.c (+149 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbgobj_typeinterface.c 2017-02-15 13:19:47 +0900 (9033e34) @@ -0,0 +1,149 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2002-2006 Ruby-GNOME2 Project Team + * Copyright (C) 2002,2003 Masahiro Sakai + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" + +#define RG_TARGET_NAMESPACE mMetaInterface + +VALUE rbgobj_mInterface; +VALUE RG_TARGET_NAMESPACE; + +static VALUE +rg_append_features(G_GNUC_UNUSED VALUE self, VALUE klass) +{ + if (!rb_obj_is_kind_of(klass, cInstantiatable)) + rb_raise(rb_eTypeError, "Not a subclass of GLib::Instantiatable"); + return rb_call_super(1, &klass); +} + +static VALUE +rg_install_property(VALUE self, VALUE pspec_obj) +{ + const RGObjClassInfo* cinfo = rbgobj_lookup_class(self); + gpointer ginterface; + GParamSpec* pspec; + + if (cinfo->klass != self) + rb_raise(rb_eTypeError, "%s isn't registered class", rb_class2name(self)); + + pspec = G_PARAM_SPEC(RVAL2GOBJ(pspec_obj)); + ginterface = g_type_default_interface_ref(cinfo->gtype); + g_object_interface_install_property(ginterface, pspec); + g_type_default_interface_unref(ginterface); + + /* FIXME: define accessor methods */ + return Qnil; +} + +static VALUE +rg_property(VALUE self, VALUE property_name) +{ + gpointer ginterface; + const char* name; + GParamSpec* prop; + VALUE result; + GType gtype = CLASS2GTYPE(self); + + if (SYMBOL_P(property_name)) + name = rb_id2name(SYM2ID(property_name)); + else + name = StringValuePtr(property_name); + + if (!G_TYPE_IS_INTERFACE(gtype)) + rb_raise(rb_eTypeError, "%s isn't interface module", rb_class2name(self)); + /* XXX: g_type_default_interface_ref(G_TYPE_INTERFACE) causes SEGV. */ + if (gtype == G_TYPE_INTERFACE) { + rb_raise(rb_const_get(mGLib, rb_intern("NoPropertyError")), + "No such property: %s", name); + } + + ginterface = g_type_default_interface_ref(gtype); + prop = g_object_interface_find_property(ginterface, name); + if (!prop){ + g_type_default_interface_unref(ginterface); + rb_raise(rb_const_get(mGLib, rb_intern("NoPropertyError")), + "No such property: %s", name); + } + result = GOBJ2RVAL(prop); + g_type_default_interface_unref(ginterface); + + return result; +} + +static VALUE +rg_properties(int argc, VALUE* argv, VALUE self) +{ + guint n_properties; + GParamSpec** props; + VALUE inherited_too; + VALUE ary = rb_ary_new(); + guint i; + gpointer ginterface; + GType gtype = CLASS2GTYPE(self); + + if (rb_scan_args(argc, argv, "01", &inherited_too) == 0) + inherited_too = Qtrue; + + if (!G_TYPE_IS_INTERFACE(gtype)) + rb_raise(rb_eTypeError, "%s isn't interface module", rb_class2name(self)); + /* XXX: g_type_default_interface_ref(G_TYPE_INTERFACE) causes SEGV. */ + if (gtype == G_TYPE_INTERFACE) return ary; + + ginterface = g_type_default_interface_ref(gtype); + props = g_object_interface_list_properties(ginterface, &n_properties); + for (i = 0; i < n_properties; i++){ + if (RVAL2CBOOL(inherited_too) || GTYPE2CLASS(props[i]->owner_type) == self) + rb_ary_push(ary, rb_str_new2(props[i]->name)); + } + g_free(props); + g_type_default_interface_unref(ginterface); + + return ary; +} + +void +rbgobj_init_interface(VALUE interf) +{ + static VALUE rb_mGLibInterface = Qnil; + + rb_extend_object(interf, RG_TARGET_NAMESPACE); + if (CLASS2GTYPE(interf) == G_TYPE_INTERFACE) { + rb_mGLibInterface = interf; + } else { + rb_extend_object(interf, rb_mGLibInterface); + rb_include_module(interf, rb_mGLibInterface); + rbgobj_define_property_accessors(interf); + } +} + +void +Init_gobject_typeinterface(void) +{ + RG_TARGET_NAMESPACE = rb_define_module_under(mGLib, "MetaInterface"); + rbg_define_method(RG_TARGET_NAMESPACE, "gtype", generic_s_gtype, 0); + RG_DEF_METHOD(append_features, 1); + RG_DEF_METHOD(install_property, 1); + RG_DEF_METHOD(property, 1); + RG_DEF_METHOD(properties, -1); + + rbgobj_mInterface = G_DEF_INTERFACE(G_TYPE_INTERFACE, "Interface", mGLib); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobj_typemodule.c (+72 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbgobj_typemodule.c 2017-02-15 13:19:47 +0900 (b7a2be9) @@ -0,0 +1,72 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2002,2003 Masahiro Sakai + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" + +#define RG_TARGET_NAMESPACE cTypeModule + +static VALUE +rg_use(VALUE self) +{ + return CBOOL2RVAL(g_type_module_use(G_TYPE_MODULE(RVAL2GOBJ(self)))); +} + +static VALUE +rg_unuse(VALUE self) +{ + g_type_module_unuse(G_TYPE_MODULE(RVAL2GOBJ(self))); + return self; +} + +static VALUE +rg_name(VALUE self) +{ + return rb_str_new2(G_TYPE_MODULE(RVAL2GOBJ(self))->name); +} + +static VALUE +rg_operator_set_name(VALUE self, VALUE name) +{ + g_type_module_set_name(G_TYPE_MODULE(RVAL2GOBJ(self)), StringValuePtr(name)); + return name; +} + +#if 0 +GType g_type_module_register_type (GTypeModule *module, + GType parent_type, + const gchar *type_name, + const GTypeInfo *type_info, + GTypeFlags flags); +void g_type_module_add_interface (GTypeModule *module, + GType instance_type, + GType interface_type, + const GInterfaceInfo *interface_info); +#endif + +void +Init_gobject_gtypemodule(void) +{ + VALUE RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_TYPE_MODULE, "TypeModule", mGLib); + RG_DEF_METHOD(use, 0); + RG_DEF_METHOD(unuse, 0); + RG_DEF_METHOD(name, 0); + RG_DEF_METHOD_OPERATOR("name=", set_name, 1); +} \ No newline at end of file Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobj_typeplugin.c (+57 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbgobj_typeplugin.c 2017-02-15 13:19:47 +0900 (6291bc1) @@ -0,0 +1,57 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2002,2003 Masahiro Sakai + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" + +#define RG_TARGET_NAMESPACE mTypePlugin + +static VALUE +rg_use(VALUE self) +{ + g_type_plugin_use(G_TYPE_PLUGIN(RVAL2GOBJ(self))); + return self; +} + +static VALUE +rg_unuse(VALUE self) +{ + g_type_plugin_unuse(G_TYPE_PLUGIN(RVAL2GOBJ(self))); + return self; +} + +#if 0 +void g_type_plugin_complete_type_info (GTypePlugin *plugin, + GType g_type, + GTypeInfo *info, + GTypeValueTable *value_table); +void g_type_plugin_complete_interface_info (GTypePlugin *plugin, + GType interface_type, + GType instance_type, + GInterfaceInfo *info); +#endif + +void +Init_gobject_gtypeplugin(void) +{ + VALUE RG_TARGET_NAMESPACE = G_DEF_INTERFACE(G_TYPE_TYPE_PLUGIN, "TypePlugin", mGLib); + RG_DEF_METHOD(use, 0); + RG_DEF_METHOD(unuse, 0); +} \ No newline at end of file Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobj_value.c (+409 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbgobj_value.c 2017-02-15 13:19:47 +0900 (8169874) @@ -0,0 +1,409 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2002,2003 Masahiro Sakai + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" + +/**********************************************************************/ +#define RG_TARGET_NAMESPACE rbgobj_cValue +#define _SELF(self) RVAL2GVALUE(self) + +static ID id_to_s; +static GQuark qRValueToGValueFunc; +static GQuark qGValueToRValueFunc; + +void +rbgobj_register_r2g_func(GType gtype, RValueToGValueFunc func) +{ + g_type_set_qdata(gtype, qRValueToGValueFunc, func); +} + +void +rbgobj_register_g2r_func(GType gtype, GValueToRValueFunc func) +{ + g_type_set_qdata(gtype, qGValueToRValueFunc, func); +} + +/**********************************************************************/ + +VALUE +rbgobj_gvalue_to_rvalue(const GValue* value) +{ + GType type, fundamental_type; + VALUE rvalue; + + if (!value) + return Qnil; + + type = G_VALUE_TYPE(value); + if (rbgobj_convert_gvalue2rvalue(type, value, &rvalue)) + return rvalue; + + fundamental_type = G_TYPE_FUNDAMENTAL(type); + switch (fundamental_type) { + case G_TYPE_NONE: + return Qnil; + case G_TYPE_CHAR: + return CHR2FIX(g_value_get_char(value)); + case G_TYPE_UCHAR: + return INT2FIX(g_value_get_uchar(value)); + case G_TYPE_BOOLEAN: + return CBOOL2RVAL(g_value_get_boolean(value)); + case G_TYPE_INT: + return INT2NUM(g_value_get_int(value)); + case G_TYPE_UINT: + return UINT2NUM(g_value_get_uint(value)); + case G_TYPE_LONG: + return LONG2NUM(g_value_get_long(value)); + case G_TYPE_ULONG: + return ULONG2NUM(g_value_get_ulong(value)); + case G_TYPE_INT64: + return rbglib_int64_to_num(g_value_get_int64(value)); + case G_TYPE_UINT64: + return rbglib_uint64_to_num(g_value_get_uint64(value)); + case G_TYPE_FLOAT: + return rb_float_new(g_value_get_float(value)); + case G_TYPE_DOUBLE: + return rb_float_new(g_value_get_double(value)); + case G_TYPE_STRING: + return CSTR2RVAL(g_value_get_string(value)); + case G_TYPE_ENUM: + return rbgobj_make_enum(g_value_get_enum(value), type); + case G_TYPE_FLAGS: + return rbgobj_make_flags(g_value_get_flags(value), type); + case G_TYPE_OBJECT: + case G_TYPE_INTERFACE: + { + GObject* gobj = g_value_get_object(value); + return gobj ? GOBJ2RVAL(gobj) : Qnil; + } + case G_TYPE_PARAM: + { + GParamSpec* pspec = g_value_get_param(value); + return pspec ? rbgobj_ruby_object_from_instance(pspec) : Qnil; + } + case G_TYPE_POINTER: + { + gpointer ptr = g_value_get_pointer(value); + if (!ptr) + return Qnil; + else + return rbgobj_ptr_new(type, ptr); + } + + case G_TYPE_BOXED: + { + GType gtype; + for (gtype = type; + gtype != G_TYPE_INVALID; + gtype = g_type_parent(gtype)) + { + GValueToRValueFunc func = + g_type_get_qdata(gtype, qGValueToRValueFunc); + if (!func) + continue; + return func(value); + } + } +#if GLIB_CHECK_VERSION(2, 26, 0) + case G_TYPE_VARIANT: + { + GVariant *variant = g_value_peek_pointer(value); + rvalue = rbg_variant_to_ruby(variant); + return rvalue; + } +#endif + default: + if (!rbgobj_convert_gvalue2rvalue(fundamental_type, value, &rvalue)) { + GValueToRValueFunc func; + func = g_type_get_qdata(type, qGValueToRValueFunc); + if (!func) { + g_warning("rbgobj_gvalue_to_rvalue: unsupported type: %s\n", + g_type_name(type)); + } else { + rvalue = func(value); + } + } + return rvalue; + } +} + +static VALUE +rbgobj_gvalue_to_rvalue_unset_body(VALUE value) +{ + return GVAL2RVAL((GValue *)value); +} + +static VALUE +rbgobj_gvalue_to_rvalue_unset_ensure(VALUE value) +{ + g_value_unset((GValue *)value); + + return Qnil; +} + +VALUE +rbgobj_gvalue_to_rvalue_unset(GValue *value) +{ + return rb_ensure(rbgobj_gvalue_to_rvalue_unset_body, (VALUE)value, + rbgobj_gvalue_to_rvalue_unset_ensure, (VALUE)value); +} + +void +rbgobj_initialize_gvalue(GValue *result, VALUE value) +{ + GType type; + + type = rbgobj_convert_rvalue2gtype(value); + if (type == 0) { + switch (TYPE(value)) { + case T_NONE: + case T_NIL: + type = G_TYPE_NONE; + break; + case T_FLOAT: + type = G_TYPE_DOUBLE; + break; + case T_STRING: + case T_SYMBOL: + type = G_TYPE_STRING; + break; + case T_FIXNUM: + type = G_TYPE_INT; + break; + case T_BIGNUM: + type = G_TYPE_INT64; + break; + case T_TRUE: + case T_FALSE: + type = G_TYPE_BOOLEAN; + break; + default: + if (RVAL2CBOOL(rb_obj_is_kind_of(value, rbgobj_cEnum))) { + type = G_TYPE_ENUM; + } + else if (RVAL2CBOOL(rb_obj_is_kind_of(value, rbgobj_cFlags)) || + RVAL2CBOOL(rb_obj_is_kind_of(value, rbgobj_cBoxed)) || + RVAL2CBOOL(rb_obj_is_kind_of(value, rbgobj_cObject))) { + type = RVAL2GTYPE(value); + } + else if (RVAL2CBOOL(rb_obj_is_kind_of(value, rbgobj_cParam))) { + type = G_TYPE_PARAM; + } + else if (RVAL2CBOOL(rb_obj_is_kind_of(value, rbgobj_mInterface))) { + /* should use rbgobj_mMetaInterface? */ + type = G_TYPE_INTERFACE; + } + else { + VALUE inspected_value; + inspected_value = rb_funcall(value, rb_intern("inspect"), 0); + rb_raise(rb_eArgError, + "unsupported value type: %s", + RSTRING_PTR(inspected_value)); + } + break; + } + } + + g_value_init(result, type); + rbgobj_rvalue_to_gvalue(value, result); +} + +void +rbgobj_rvalue_to_gvalue(VALUE val, GValue* result) +{ + GType type, fundamental_type; + + type = G_VALUE_TYPE(result); + if (rbgobj_convert_rvalue2gvalue(type, val, result)) + return; + + fundamental_type = G_TYPE_FUNDAMENTAL(type); + switch (fundamental_type) { + case G_TYPE_NONE: + return; + case G_TYPE_CHAR: + g_value_set_char(result, NUM2INT(val)); + return; + case G_TYPE_UCHAR: + g_value_set_uchar(result, NUM2UINT(val)); + return; + case G_TYPE_BOOLEAN: + g_value_set_boolean(result, RVAL2CBOOL(val)); + return; + case G_TYPE_INT: + g_value_set_int(result, NUM2INT(val)); + return; + case G_TYPE_UINT: + g_value_set_uint(result, NUM2UINT(val)); + return; + case G_TYPE_LONG: + g_value_set_long(result, NUM2LONG(val)); + return; + case G_TYPE_ULONG: + g_value_set_ulong(result, NUM2ULONG(val)); + return; + case G_TYPE_INT64: + g_value_set_int64(result, rbglib_num_to_int64(val)); + return; + case G_TYPE_UINT64: + g_value_set_uint64(result, rbglib_num_to_uint64(val)); + return; + case G_TYPE_ENUM: + g_value_set_enum(result, rbgobj_get_enum(val, G_VALUE_TYPE(result))); + return; + case G_TYPE_FLAGS: + g_value_set_flags(result, rbgobj_get_flags(val, G_VALUE_TYPE(result))); + return; + case G_TYPE_FLOAT: + g_value_set_float(result, NUM2DBL(val)); + return; + case G_TYPE_DOUBLE: + g_value_set_double(result, NUM2DBL(val)); + return; + case G_TYPE_STRING: + { + if (SYMBOL_P(val)) + val = rb_funcall(val, id_to_s, 0); + g_value_set_string(result, RVAL2CSTR_ACCEPT_NIL(val)); + return; + } + case G_TYPE_OBJECT: + case G_TYPE_INTERFACE: + g_value_set_object(result, NIL_P(val) ? NULL : RVAL2GOBJ(val)); + return; + case G_TYPE_PARAM: + g_value_set_param(result, NIL_P(val) ? NULL : RVAL2GOBJ(val)); + return; + case G_TYPE_POINTER: + g_value_set_pointer(result, NIL_P(val) ? NULL : rbgobj_ptr2cptr(val)); + return; + case G_TYPE_BOXED: + { + GType gtype; + for (gtype = type; + gtype != G_TYPE_INVALID; + gtype = g_type_parent(gtype)) + { + RValueToGValueFunc func = + g_type_get_qdata(gtype, qRValueToGValueFunc); + if (!func) + continue; + func(val, result); + return; + } + } +#if GLIB_CHECK_VERSION(2, 26, 0) + case G_TYPE_VARIANT: + g_value_set_variant(result, rbg_variant_from_ruby(val)); + break; +#endif + default: + if (!rbgobj_convert_rvalue2gvalue(fundamental_type, val, result)) { + RValueToGValueFunc func = + g_type_get_qdata(type, qRValueToGValueFunc); + if (!func){ + g_warning("rbgobj_rvalue_to_gvalue: unsupported type: %s\n", + g_type_name(type)); + } else { + func(val, result); + } + } + } +} + +/**********************************************************************/ + +void +rbgobj_gc_mark_gvalue(GValue* value) +{ + GType gtype = G_VALUE_TYPE(value); + /* FIXME */ + if (G_TYPE_FUNDAMENTAL(gtype) == G_TYPE_OBJECT) + rbgobj_gc_mark_instance(g_value_get_object(value)); +} + +/**********************************************************************/ + +static VALUE +rg_initialize(int argc, VALUE *argv, VALUE self) +{ + GValue value = G_VALUE_INIT; + VALUE rb_gtype; + VALUE rb_value; + + rb_scan_args(argc, argv, "11", &rb_gtype, &rb_value); + + g_value_init(&value, NUM2ULONG(rb_to_int(rb_gtype))); + if (argc == 2) { + rbgobj_rvalue_to_gvalue(rb_value, &value); + } + G_INITIALIZE(self, g_boxed_copy(G_TYPE_VALUE, &value)); + g_value_unset(&value); + + return Qnil; +} + +static VALUE +rg_type(VALUE self) +{ + GValue *value; + + value = _SELF(self); + + return rbgobj_gtype_new(value->g_type); +} + +static VALUE +rg_value(VALUE self) +{ + GValue *value; + + value = _SELF(self); + + return GVAL2RVAL(value); +} + +static VALUE +rg_to_s(VALUE self) +{ + GValue *value; + gchar *string_value; + + value = _SELF(self); + string_value = g_strdup_value_contents(value); + return CSTR2RVAL_FREE(string_value); +} + +void +Init_gobject_gvalue(void) +{ + VALUE RG_TARGET_NAMESPACE; + + id_to_s = rb_intern("to_s"); + qRValueToGValueFunc = g_quark_from_static_string("__ruby_r2g_func__"); + qGValueToRValueFunc = g_quark_from_static_string("__ruby_g2r_func__"); + + RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_VALUE, "Value", mGLib); + RG_DEF_METHOD(initialize, -1); + RG_DEF_METHOD(type, 0); + RG_DEF_METHOD(value, 0); + RG_DEF_METHOD(to_s, 0); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobj_valuearray.c (+100 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbgobj_valuearray.c 2017-02-15 13:19:47 +0900 (a6cfabc) @@ -0,0 +1,100 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2006 Sjoerd Simons + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" + +static VALUE +value_array_to_ruby(const GValue *from) +{ + VALUE ary; + guint i; + + GValueArray *array = (GValueArray *)g_value_get_boxed(from); + if (array == NULL) + return Qnil; + + ary = rb_ary_new(); + for (i = 0; i < array->n_values; i++) + rb_ary_push(ary, GVAL2RVAL(g_value_array_get_nth(array, i))); + + return ary; +} + +struct value_array_from_ruby_args { + VALUE ary; + long n; + GValueArray *result; +}; + +static VALUE +value_array_from_ruby_body(VALUE value) +{ + long i; + struct value_array_from_ruby_args *args = (struct value_array_from_ruby_args *)value; + + for (i = 0; i < args->n; i++) { + GValue v = G_VALUE_INIT; + + g_value_init(&v, RVAL2GTYPE(RARRAY_PTR(args->ary)[i])); + rbgobj_rvalue_to_gvalue(RARRAY_PTR(args->ary)[i], &v); + + g_value_array_append(args->result, &v); + } + + return Qnil; +} + +static G_GNUC_NORETURN VALUE +value_array_from_ruby_rescue(VALUE value) +{ + g_value_array_free(((struct value_array_from_ruby_args *)value)->result); + + rb_exc_raise(rb_errinfo()); +} + +static void +value_array_from_ruby(const VALUE from, GValue *to) +{ + struct value_array_from_ruby_args args; + + if (NIL_P(from)) { + g_value_set_boxed(to, NULL); + + return; + } + + args.ary = rb_ary_to_ary(from); + args.n = RARRAY_LEN(args.ary); + args.result = g_value_array_new(args.n); + + rb_rescue(value_array_from_ruby_body, (VALUE)&args, + value_array_from_ruby_rescue, (VALUE)&args); + + g_value_set_boxed(to, args.result); +} + +void +Init_gobject_value_array(void) +{ + /* ValueArray is treated as Array */ + rbgobj_register_g2r_func(G_TYPE_VALUE_ARRAY, value_array_to_ruby); + rbgobj_register_r2g_func(G_TYPE_VALUE_ARRAY, value_array_from_ruby); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobj_valuetypes.c (+243 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbgobj_valuetypes.c 2017-02-15 13:19:47 +0900 (92db741) @@ -0,0 +1,243 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2002,2003 Masahiro Sakai + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" +#include "rbgobject.h" + + +VALUE +rbgobj_ptr_new(GType type, gpointer ptr) +{ + return Data_Wrap_Struct(GTYPE2CLASS(type), NULL, NULL, ptr); +} + +gpointer +rbgobj_ptr2cptr(VALUE ptr) +{ + gpointer dest; + if (rb_obj_is_kind_of(ptr, GTYPE2CLASS(G_TYPE_POINTER))){ + Data_Get_Struct(ptr, void, dest); + } else if (rb_obj_is_kind_of(ptr, rb_cObject)){ + dest = (gpointer)ptr; + } else{ + rb_raise(rb_eTypeError, "not a pointer object"); + } + return dest; +} + +static VALUE +ptr_s_gtype(VALUE klass) +{ + return rbgobj_gtype_new(rbgobj_lookup_class(klass)->gtype); +} + +static VALUE +ptr_gtype(VALUE self) +{ + return ptr_s_gtype(CLASS_OF(self)); +} + +static void +Init_gtype_pointer(void) +{ + VALUE cPtr = G_DEF_CLASS(G_TYPE_POINTER, "Pointer", mGLib); + rbg_define_singleton_method(cPtr, "gtype", ptr_s_gtype, 1); + rbg_define_method(cPtr, "gtype", ptr_gtype, 1); +} + +/**********************************************************************/ + +static GHashTable* boxed_ruby_value_table; +static VALUE boxed_ruby_value_table_wrapper; + +typedef struct { + VALUE obj; + guint ref_count; +} boxed_ruby_value_counter; + +static void +boxed_ruby_value_counter_mark(G_GNUC_UNUSED gpointer key, + gpointer value, + G_GNUC_UNUSED gpointer user_data) +{ + boxed_ruby_value_counter* counter = value; + if (counter->ref_count) + rb_gc_mark(counter->obj); +} + +static void +boxed_ruby_value_table_mark(GHashTable* table) +{ + g_hash_table_foreach(table, boxed_ruby_value_counter_mark, NULL); +} + +static VALUE +boxed_ruby_value_ref(VALUE val) +{ + if (!SPECIAL_CONST_P(val)){ + boxed_ruby_value_counter* counter; + + counter = g_hash_table_lookup(boxed_ruby_value_table, (gpointer)val); + + if (!counter){ + counter = g_new(boxed_ruby_value_counter, 1); + counter->obj = val; + counter->ref_count = 1; + g_hash_table_insert(boxed_ruby_value_table, (gpointer)val, + counter); + } else { + counter->ref_count += 1; + } + } + return val; +} + +static void +boxed_ruby_value_unref(VALUE val) +{ + if (!SPECIAL_CONST_P(val)){ + boxed_ruby_value_counter* counter; + + counter = g_hash_table_lookup(boxed_ruby_value_table, (gpointer)val); + counter->ref_count -= 1; + + if (!counter->ref_count) + g_hash_table_remove(boxed_ruby_value_table, (gpointer)val); + } +} + +struct transform_arg { + const GValue *src_value; + GValue *dest_value; +}; + +static VALUE +value_transform_ruby_any_impl(VALUE arg_) +{ + struct transform_arg* arg = (struct transform_arg*)arg_; + rbgobj_rvalue_to_gvalue(g_value_get_ruby_value(arg->src_value), + arg->dest_value); + return Qnil; +} + +static void +value_transform_ruby_any(const GValue *src_value, + GValue *dest_value) +{ + int state; + struct transform_arg arg; + arg.src_value = src_value; + arg.dest_value = dest_value; + rb_protect(&value_transform_ruby_any_impl, (VALUE)&arg, &state); +} + +static void +value_transform_any_ruby(const GValue *src_value, + GValue *dest_value) +{ + g_value_set_ruby_value(dest_value, GVAL2RVAL(src_value)); +} + +GType +rbgobj_ruby_value_get_type(void) +{ + static GType our_type = 0; + + if (!our_type){ + const GType table[] = { + G_TYPE_CHAR, + G_TYPE_UCHAR, + G_TYPE_BOOLEAN, + G_TYPE_INT, + G_TYPE_UINT, + G_TYPE_LONG, + G_TYPE_ULONG, + G_TYPE_INT64, + G_TYPE_UINT64, + G_TYPE_ENUM, + G_TYPE_FLAGS, + G_TYPE_FLOAT, + G_TYPE_DOUBLE, + G_TYPE_STRING, + G_TYPE_POINTER, + //G_TYPE_BOXED, + G_TYPE_PARAM, + G_TYPE_OBJECT, + }; + size_t i; + + our_type = g_boxed_type_register_static( + "VALUE", + (GBoxedCopyFunc)boxed_ruby_value_ref, + (GBoxedFreeFunc)boxed_ruby_value_unref); + + for (i = 0; i < sizeof(table)/sizeof(table[0]); i++){ + g_value_register_transform_func(table[i], our_type, + value_transform_any_ruby); + } + + g_value_register_transform_func(our_type, G_TYPE_BOOLEAN, + value_transform_ruby_any); + } + return our_type; +} + +VALUE +g_value_get_ruby_value(const GValue* value) +{ + return (VALUE)g_value_get_boxed(value); +} + +void +g_value_set_ruby_value(GValue* value, VALUE ruby) +{ + g_value_set_boxed(value, (gconstpointer)ruby); +} + +static void +ruby_value_r2g(VALUE from, GValue* to) +{ + g_value_set_ruby_value(to, from); +} + +static void +Init_boxed_ruby_value(void) +{ + boxed_ruby_value_table = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free); + + boxed_ruby_value_table_wrapper = + Data_Wrap_Struct(rb_cData, + boxed_ruby_value_table_mark, NULL, + boxed_ruby_value_table); + rb_global_variable(&boxed_ruby_value_table_wrapper); + + rbgobj_register_g2r_func(RBGOBJ_TYPE_RUBY_VALUE, g_value_get_ruby_value); + rbgobj_register_r2g_func(RBGOBJ_TYPE_RUBY_VALUE, ruby_value_r2g); +} + +/**********************************************************************/ + +void +Init_gobject_gvaluetypes(void) +{ + Init_gtype_pointer(); + Init_boxed_ruby_value(); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobject.c (+386 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbgobject.c 2017-02-15 13:19:47 +0900 (c20bd37) @@ -0,0 +1,386 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2003-2006 Ruby-GNOME2 Project Team + * Copyright (C) 2002,2003 Masahiro Sakai + * Copyright (C) 1998-2000 Yukihiro Matsumoto, + * Daisuke Kanda, + * Hiroshi Igarashi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "ruby.h" +#include "rbgprivate.h" +#include <ctype.h> + +#include "rbgprivate.h" + +static ID id_relatives; +static ID id_delete; +static ID id_module_eval; + +ID rbgobj_id_children; + +/**********************************************************************/ + +void +rbgobj_initialize_object(VALUE obj, gpointer cobj) +{ + GType type; + GType parent_type; + + if (!cobj) + rb_raise(rb_eRuntimeError, "failed to initialize"); + + type = RVAL2GTYPE(obj); + + for (parent_type = type; + parent_type != G_TYPE_INVALID; + parent_type = g_type_parent(parent_type)) { + + if (rbgobj_convert_initialize(parent_type, obj, cobj)) + return; + } + + type = G_TYPE_FUNDAMENTAL(type); + switch (type){ + case G_TYPE_OBJECT: + rbgobj_gobject_initialize(obj, cobj); + break; + case G_TYPE_PARAM: + rbgobj_param_spec_initialize(obj, cobj); + break; + case G_TYPE_BOXED: + rbgobj_boxed_initialize(obj, cobj); + break; + default: + rbgobj_convert_initialize(type, obj, cobj); + break; + } +} + +gpointer +rbgobj_instance_from_ruby_object(VALUE obj) +{ + GType type; + GType fundamental_type; + + if (NIL_P(obj)) + return NULL; + + type = RVAL2GTYPE(obj); + if (rbgobj_convert_has_type(type)) { + gpointer instance; + if (rbgobj_convert_robj2instance(type, obj, &instance)) + return instance; + } + + fundamental_type = G_TYPE_FUNDAMENTAL(type); + switch (fundamental_type) { + case G_TYPE_OBJECT: + return rbgobj_get_gobject(obj); + case G_TYPE_BOXED: + return rbgobj_boxed_get(obj, type); + case G_TYPE_PARAM: + return rbgobj_get_param_spec(obj); + default: + { + gpointer instance; + if (!rbgobj_convert_robj2instance(fundamental_type, obj, &instance)) { + rb_raise(rb_eTypeError, "%s isn't supported", + rb_class2name(CLASS_OF(obj))); + } + return instance; + } + } +} + +VALUE +rbgobj_ruby_object_from_instance(gpointer instance) +{ + return rbgobj_ruby_object_from_instance2(instance, TRUE); +} + +VALUE +rbgobj_ruby_object_from_instance2(gpointer instance, gboolean alloc) +{ + VALUE object; + GType type; + + if (!instance) + return Qnil; + + type = G_TYPE_FROM_INSTANCE(instance); + if (alloc) { + GType parent_type; + for (parent_type = type; + parent_type != G_TYPE_INVALID; + parent_type = g_type_parent(parent_type)) { + if (rbgobj_convert_instance2robj(parent_type, instance, &object)) + return object; + } + } + + switch (G_TYPE_FUNDAMENTAL(type)) { + case G_TYPE_OBJECT: + return rbgobj_get_ruby_object_from_gobject(instance, alloc); + case G_TYPE_PARAM: + return rbgobj_get_ruby_object_from_param_spec(instance, alloc); + default: + if (alloc) { + rb_raise(rb_eTypeError, "%s isn't supported", g_type_name(type)); + } else { + return Qnil; + } + } +} + +void +rbgobj_instance_unref(gpointer instance) +{ + GType type; + + type = G_TYPE_FROM_INSTANCE(instance); + if (!rbgobj_convert_unref(type, instance)) { + type = G_TYPE_FUNDAMENTAL(type); + switch (type) { + case G_TYPE_OBJECT: + g_object_unref(instance); + break; + default: + rbgobj_convert_unref(type, instance); + break; + } + } +} + +VALUE +rbgobj_ruby_object_from_instance_with_unref(gpointer instance) +{ + VALUE result = rbgobj_ruby_object_from_instance(instance); + if (!NIL_P(result)) { + rbgobj_instance_unref(instance); + } + return result; +} + +/**********************************************************************/ + +void +rbgobj_add_relative(VALUE obj, VALUE relative) +{ + VALUE hash = Qnil; + + if (RVAL2CBOOL(rb_ivar_defined(obj, id_relatives))) + hash = rb_ivar_get(obj, id_relatives); + + if (NIL_P(hash) || TYPE(hash) != RUBY_T_HASH) { + hash = rb_hash_new(); + rb_ivar_set(obj, id_relatives, hash); + } + rb_hash_aset(hash, relative, Qnil); +} + +void +rbgobj_invalidate_relatives(VALUE obj) +{ + if (RVAL2CBOOL(rb_ivar_defined(obj, id_relatives))) + rb_ivar_set(obj, id_relatives, Qnil); + if (RVAL2CBOOL(rb_ivar_defined(obj, rbgobj_id_children))) + rb_ivar_set(obj, rbgobj_id_children, Qnil); +} + +void +rbgobj_add_relative_removable(VALUE obj, VALUE relative, ID obj_ivar_id, VALUE hash_key) +{ + VALUE hash = Qnil; + + if (RVAL2CBOOL(rb_ivar_defined(obj, obj_ivar_id))) + hash = rb_ivar_get(obj, obj_ivar_id); + + if (NIL_P(hash) || TYPE(hash) != RUBY_T_HASH) { + hash = rb_hash_new(); + rb_ivar_set(obj, obj_ivar_id, hash); + } + rb_hash_aset(hash, hash_key, relative); +} + +VALUE +rbgobj_get_relative_removable(VALUE obj, ID obj_ivar_id, VALUE hash_key) +{ + VALUE hash = Qnil; + + if (RVAL2CBOOL(rb_ivar_defined(obj, obj_ivar_id))) + hash = rb_ivar_get(obj, obj_ivar_id); + + if (NIL_P(hash) || TYPE(hash) != RUBY_T_HASH) { + return Qnil; + } + return rb_hash_aref(hash, hash_key); +} + +void +rbgobj_remove_relative(VALUE obj, ID obj_ivar_id, VALUE hash_key) +{ + VALUE hash = Qnil; + + if (RVAL2CBOOL(rb_ivar_defined(obj, obj_ivar_id))) + hash = rb_ivar_get(obj, obj_ivar_id); + + if (NIL_P(hash) || TYPE(hash) != RUBY_T_HASH) { + /* should not happen. */ + } else { + rb_funcall(hash, id_delete, 1, hash_key); + } +} + +void +rbgobj_remove_relative_all(VALUE obj, ID obj_ivar_id) +{ + rb_ivar_set(obj, obj_ivar_id, Qnil); +} + +/**********************************************************************/ + +static GHashTable* prop_exclude_list; + +#define IS_FLAG(bitmask, flag) (((bitmask) & (flag)) == (flag)) + +void +rbgobj_define_property_accessors(VALUE klass) +{ + GType gtype; + GParamSpec** pspecs = NULL; + guint i; + GString* source; + guint n_properties = 0; + gtype = CLASS2GTYPE(klass); + + if (G_TYPE_IS_INTERFACE(gtype)){ + gpointer iface = g_type_default_interface_ref(gtype); + pspecs = g_object_interface_list_properties(iface, &n_properties); + g_type_default_interface_unref(iface); + } else { + GObjectClass* oclass = G_OBJECT_CLASS(g_type_class_ref(gtype)); + pspecs = g_object_class_list_properties(oclass, &n_properties); + g_type_class_unref(oclass); + } + + if (n_properties == 0) + return; + + source = g_string_new(NULL); + for (i = 0; i < n_properties; i++){ + GParamSpec* pspec = pspecs[i]; + char* buf; + char* prop_name; + char* p; + + if (pspec->owner_type != gtype) + continue; + + buf = g_strdup(pspec->name); + for (p = buf; *p; p++) + if (*p == '-') + *p = '_'; + + if (!strncmp(buf, "is_", 3)) + prop_name = buf + 3; + else + prop_name = buf; + + if (g_hash_table_lookup(prop_exclude_list, prop_name)){ + g_free(buf); + continue; + } + + if (pspec->flags & G_PARAM_READABLE){ + g_string_append_printf( + source, + "def %s%s; get_property('%s'); end\n", + prop_name, + (G_PARAM_SPEC_VALUE_TYPE(pspec) == G_TYPE_BOOLEAN) ? "?" : "", + pspec->name); + } + + if (IS_FLAG(pspec->flags, G_PARAM_WRITABLE) && !IS_FLAG(pspec->flags, G_PARAM_CONSTRUCT_ONLY)){ + g_string_append_printf(source, + "def set_%s(val); set_property('%s', val); end\n", + prop_name, pspec->name); + g_string_append_printf(source, "alias %s= set_%s\n", + prop_name, prop_name); + } + + g_free(buf); + } + + if (source->len > 0) + rb_funcall(klass, id_module_eval, 3, + rb_str_new2(source->str), + rb_str_new2(__FILE__), + INT2NUM(__LINE__)); + g_string_free(source, TRUE); +} + +/**********************************************************************/ + +void +Init_gobject(void) +{ + /* Not defined properties. They are already used as methods of Object */ + prop_exclude_list = g_hash_table_new(g_str_hash, g_str_equal); + g_hash_table_insert(prop_exclude_list, (gpointer)"class", (gpointer)"class"); + g_hash_table_insert(prop_exclude_list, (gpointer)"clone", (gpointer)"clone"); + g_hash_table_insert(prop_exclude_list, (gpointer)"dup", (gpointer)"dup"); + g_hash_table_insert(prop_exclude_list, (gpointer)"extend", (gpointer)"extend"); + g_hash_table_insert(prop_exclude_list, (gpointer)"freeze", (gpointer)"freeze"); + g_hash_table_insert(prop_exclude_list, (gpointer)"hash", (gpointer)"hash"); + g_hash_table_insert(prop_exclude_list, (gpointer)"method", (gpointer)"method"); + g_hash_table_insert(prop_exclude_list, (gpointer)"methods", (gpointer)"methods"); + g_hash_table_insert(prop_exclude_list, (gpointer)"object_id", (gpointer)"object_id"); + g_hash_table_insert(prop_exclude_list, (gpointer)"taint", (gpointer)"taint"); + g_hash_table_insert(prop_exclude_list, (gpointer)"untaint", (gpointer)"untaint"); + + /* IDs */ + id_relatives = rb_intern("__relatives__"); + id_delete = rb_intern("delete"); + id_module_eval = rb_intern("module_eval"); + + rbgobj_id_children = rb_intern("__stored_children__"); + + Init_gobject_convert(); + + Init_gobject_gtype(); + Init_gobject_typeinterface(); + Init_gobject_typeinstance(); + Init_gobject_gvalue(); + Init_gobject_gvaluetypes(); + Init_gobject_gboxed(); + Init_gobject_gstrv(); + Init_gobject_value_array(); + Init_gobject_genumflags(); + Init_gobject_gparam(); + Init_gobject_gparamspecs(); + Init_gobject_gclosure(); + Init_gobject_gobject(); + Init_gobject_gsignal(); + + Init_gobject_gtypeplugin(); + Init_gobject_gtypemodule(); + + Init_gobject_gbinding(); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobject.h (+319 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbgobject.h 2017-02-15 13:19:47 +0900 (430b566) @@ -0,0 +1,319 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2003,2006 Ruby-GNOME2 Project Team + * Copyright (C) 2002,2003 Masahiro Sakai + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef __RBGOBJECT_H__ +#define __RBGOBJECT_H__ + +#include <glib-object.h> +#include "ruby.h" +#include "rbglib.h" +#include "rbgutil.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* macros */ + +#define G_INITIALIZE(obj, cobj)\ + (rbgobj_initialize_object(obj, (gpointer)cobj)) + +#define G_DEF_CLASS(gtype, name, module)\ + (rbgobj_define_class(gtype, name, module, 0, 0, Qnil)) +#define G_DEF_CLASS_WITH_GC_FUNC(gtype, name, module, mark, free) \ + (rbgobj_define_class(gtype, name, module, mark, free, Qnil)) +#define G_DEF_CLASS2(gtype, name, module, mark, free) \ + G_DEF_CLASS_WITH_GC_FUNC(gtype, name, module, mark, free) +#define G_DEF_CLASS3(gtype_name, name, module)\ + (rbgobj_define_class_dynamic(gtype_name, name, module, 0, 0)) +#define G_DEF_CLASS_WITH_PARENT(gtype, name, module, parent) \ + (rbgobj_define_class(gtype, name, module, 0, 0, parent)) +#define G_DEF_CLASS4(gtype, name, module, parent) \ + G_DEF_CLASS_WITH_PARENT(gtype, name, module, parent) + +#define G_DEF_INTERFACE(gtype, name, module)\ + (rbgobj_define_class(gtype, name, module, 0, 0, Qnil)) +#define G_DEF_INTERFACE2(gtype, name, module, mark, free)\ + (rbgobj_define_class(gtype, name, module, mark, free, Qnil)) + +#define RG_DEF_CONVERSION(table) (rbgobj_convert_define(table)) + +#define G_RELATIVE(obj, rel) (rbgobj_add_relative(obj, rel)) + +/* G_RELATIVE2 is useless now. Try G_CHILD_ADD/REMOVE first. */ +#define G_RELATIVE2(obj, rel, id, hash_key)\ + (rbgobj_add_relative_removable(obj, rel, id, hash_key)) +#define G_GET_RELATIVE(obj, id, hash_key)\ + (rbgobj_get_relative_removable(obj, id, hash_key)) +#define G_REMOVE_RELATIVE(obj, id, hash_key)\ + (rbgobj_remove_relative(obj, id, hash_key)) + +RUBY_GLIB2_VAR ID rbgobj_id_children; +#define G_CHILD_SET(self, id, child) (rb_ivar_set(self, id, child)) +#define G_CHILD_UNSET(self, id) (rb_ivar_set(self, id, Qnil)) + +/* G_CHILD_ADD is same as G_RELATIVE, but the macro name is more obviously + to use than G_RELATIVE, and also support "remove" operation with the key + which is the object itself. +*/ +#define G_CHILD_ADD(self, child) \ + (rbgobj_add_relative_removable(self, Qnil, rbgobj_id_children, child)) +#define G_CHILD_REMOVE(self, child) \ + (rbgobj_remove_relative(self, rbgobj_id_children, child)) +#define G_CHILD_REMOVE_ALL(self) \ + (rbgobj_remove_relative_all(self, rbgobj_id_children)) + +#define G_DEF_SIGNAL_FUNC(klass, sig_name, func)\ + (rbgobj_set_signal_func(klass, sig_name, func)) + +#define CLASS2CINFO(klass) (rbgobj_lookup_class(klass)) +#define GTYPE2CINFO(gtype) (rbgobj_lookup_class_by_gtype(gtype, Qnil)) +#define GTYPE2CINFO_NO_CREATE(gtype) (rbgobj_lookup_class_by_gtype_full(gtype, Qnil, FALSE)) +#define RVAL2CINFO(obj) (rbgobj_lookup_class(CLASS_OF(obj))) +#define GTYPE2CLASS(gtype) (rbgobj_gtype_to_ruby_class(gtype)) +#define CLASS2GTYPE(klass) (rbgobj_lookup_class(klass)->gtype) +#define RVAL2GTYPE(obj) (CLASS2GTYPE(CLASS_OF(obj))) + +#define RVAL2GOBJ(obj) (rbgobj_instance_from_ruby_object(obj)) +#define GOBJ2RVAL(gobj) (rbgobj_ruby_object_from_instance(gobj)) +#define GOBJ2RVAL_UNREF(gobj) (rbgobj_ruby_object_from_instance_with_unref(gobj)) +#define GOBJ2RVALU(gobj) GOBJ2RVAL_UNREF(gobj) +#define GVAL2RVAL(v) (rbgobj_gvalue_to_rvalue(v)) +#define GVAL2RVAL_UNSET(v) (rbgobj_gvalue_to_rvalue(v)) + +#define RVAL2BOXED(obj, gtype) (rbgobj_boxed_get(obj, gtype)) +#define BOXED2RVAL(cobj, gtype) (rbgobj_make_boxed(cobj, gtype)) + +#define RVAL2GENUM(obj, gtype) (rbgobj_get_enum(obj, gtype)) +#define RVAL2GFLAGS(obj, gtype) (rbgobj_get_flags(obj, gtype)) +#define GENUM2RVAL(n, gtype) (rbgobj_make_enum(n, gtype)) +#define GFLAGS2RVAL(n, gtype) (rbgobj_make_flags(n, gtype)) + +#define RVAL2GPTR(object) (rbgobj_ptr2cptr(object)) +#define GPTR2RVAL(ptr, gtype) (rbgobj_ptr_new(gtype, ptr)) + +#define G_DEF_CONSTANTS(mod, type, strip_prefix) \ + rbgobj_add_constants(mod, type, strip_prefix) +#define G_RENAME_CONSTANT(orig, alt) \ + rbgobj_constant_remap(orig, alt) +#define G_RENAME_NICK(orig, alt) \ + rbgobj_constant_remap(orig, alt) + +typedef enum +{ + RBGOBJ_ABSTRACT_BUT_CREATABLE = 1 << 0, /* deprecated */ + RBGOBJ_BOXED_NOT_COPY = 1 << 1, + RBGOBJ_DEFINED_BY_RUBY = 1 << 2, +} RGObjClassFlag; + +typedef void (*RGMarkFunc)(gpointer object); +typedef void (*RGFreeFunc)(gpointer object); + +typedef struct { + VALUE klass; + GType gtype; + RGMarkFunc mark; + RGFreeFunc free; + int flags; /* RGObjClassFlag */ +} RGObjClassInfo; + +/* rbgobject.c */ + +extern void rbgobj_initialize_object(VALUE obj, gpointer cobj); +extern gpointer rbgobj_instance_from_ruby_object(VALUE obj); +extern VALUE rbgobj_ruby_object_from_instance(gpointer instance); +extern VALUE rbgobj_ruby_object_from_instance2(gpointer instance, gboolean alloc); +extern VALUE rbgobj_ruby_object_from_instance_with_unref(gpointer instance); +extern void rbgobj_instance_unref(gpointer instance); + +extern void rbgobj_add_relative(VALUE obj, VALUE relative); +extern void rbgobj_invalidate_relatives(VALUE obj); +extern void rbgobj_add_relative_removable(VALUE obj, VALUE relative, + ID obj_ivar_id, VALUE hash_key); +extern VALUE rbgobj_get_relative_removable(VALUE obj, ID obj_ivar_id, + VALUE hash_key); +extern void rbgobj_remove_relative(VALUE obj, ID obj_ivar_id, VALUE hash_key); +extern void rbgobj_remove_relative_all(VALUE obj, ID obj_ivar_id); + +extern GObject* rbgobj_gobject_new(GType type, VALUE params_hash); +extern VALUE rbgobj_create_object(VALUE klass); /* deprecated */ + +extern VALUE rbgobj_get_ruby_object_from_gobject(GObject* gobj, gboolean alloc); + +/* For Ruby/Gstreamer */ +extern void rbgobj_gobject_initialize(VALUE obj, gpointer cobj); + +/* deprecated */ +extern void rbgobj_add_abstract_but_create_instance_class(GType gtype); + +/* rbgobj_typeinstance.c */ +extern gboolean rbgobj_gc_mark_instance(gpointer instance); + + +/* rbgobj_type.c */ +extern const RGObjClassInfo *rbgobj_lookup_class(VALUE klass); +extern const RGObjClassInfo *rbgobj_lookup_class_by_gtype(GType gtype, VALUE parent); +extern const RGObjClassInfo *rbgobj_lookup_class_by_gtype_full(GType gtype, + VALUE parent, + gboolean create_object); +extern VALUE rbgobj_gtype_to_ruby_class(GType gtype); +extern VALUE rbgobj_define_class(GType gtype, const gchar* name, VALUE module, + RGMarkFunc mark, RGFreeFunc free, VALUE parent); +extern VALUE rbgobj_define_class_dynamic(const gchar* gtype_name, + const gchar* name, VALUE module, + RGMarkFunc mark, RGFreeFunc free); +extern void rbgobj_register_class(VALUE klass, + GType gtype, + gboolean klass2gtype, + gboolean gtype2klass); +extern void rbgobj_register_mark_func(GType gtype, RGMarkFunc mark); +extern void rbgobj_register_free_func(GType gtype, RGFreeFunc free); +extern VALUE rbgobj_cType; +extern VALUE rbgobj_gtype_new(GType gtype); +extern GType rbgobj_gtype_get(VALUE obj); + +/* rbgobj_signal.c */ +typedef VALUE (*GValToRValSignalFunc)(guint num,const GValue* values); +extern void rbgobj_set_signal_func(VALUE klass, const gchar *sig_name, GValToRValSignalFunc func); +extern GValToRValSignalFunc rbgobj_get_signal_func(guint signal_id); +extern VALUE rbgobj_signal_wrap(guint sig_id); + +typedef struct { + GValue *return_value; + guint n_param_values; + const GValue *param_values; + VALUE callback; + VALUE extra_args; +} RGClosureCallData; +typedef void (*RGClosureCallFunc)(RGClosureCallData *data); + +extern void rbgobj_set_signal_call_func(VALUE klass, + const gchar *signal_name, + RGClosureCallFunc func); +extern RGClosureCallFunc rbgobj_get_signal_call_func(guint signal_id); + +/* rbgobj_closure.c */ +extern GClosure* g_rclosure_new(VALUE callback_proc, VALUE extra_args, + GValToRValSignalFunc func); +extern GClosure* g_rclosure_new_call(VALUE callback_proc, + VALUE extra_args, + RGClosureCallFunc func); +extern void g_rclosure_attach(GClosure *closure, VALUE object); +extern void g_rclosure_set_tag(GClosure *closure, const gchar *tag); + +/* rbgobj_value.c */ +extern VALUE rbgobj_gvalue_to_rvalue(const GValue* value); +extern VALUE rbgobj_gvalue_to_rvalue_unset(GValue *value); +extern void rbgobj_rvalue_to_gvalue(VALUE val, GValue* result); +extern void rbgobj_initialize_gvalue(GValue *result, VALUE value); + +typedef void (*RValueToGValueFunc)(VALUE from, GValue* to); +typedef VALUE (*GValueToRValueFunc)(const GValue* from); +extern void rbgobj_register_r2g_func(GType gtype, RValueToGValueFunc func); +extern void rbgobj_register_g2r_func(GType gtype, GValueToRValueFunc func); + +extern void rbgobj_gc_mark_gvalue(GValue* value); + +/* rbgobj_valuetypes.c */ +extern VALUE rbgobj_ptr_new(GType type, gpointer ptr); +extern gpointer rbgobj_ptr2cptr(VALUE ptr); + +#define RBGOBJ_TYPE_RUBY_VALUE (rbgobj_ruby_value_get_type()) +extern GType rbgobj_ruby_value_get_type(void); +extern VALUE g_value_get_ruby_value(const GValue* value); +extern void g_value_set_ruby_value(GValue* value, VALUE ruby); + +/* rbgobj_object.c */ +extern void rbgobj_register_property_setter(GType gtype, const char* prop_name, RValueToGValueFunc func); +extern void rbgobj_register_property_getter(GType gtype, const char* prop_name, GValueToRValueFunc func); +extern void rbgobj_class_init_func(gpointer g_class, gpointer class_data); +extern void rbgobj_register_type(VALUE klass, VALUE type_name, GClassInitFunc class_init); + +/* rbgobj_boxed.c */ +extern VALUE rbgobj_boxed_create(VALUE klass); /* deprecated */ +extern gpointer rbgobj_boxed_get(VALUE obj, GType gtype); +extern gpointer rbgobj_boxed_get_default(VALUE obj, GType gtype); +extern VALUE rbgobj_make_boxed(gpointer data, GType gtype); +extern VALUE rbgobj_make_boxed_raw(gpointer p, GType gtype, + VALUE klass, gint flags); +extern VALUE rbgobj_make_boxed_default(gpointer data, GType gtype); +extern void rbgobj_boxed_not_copy_obj(GType gtype); +extern void rbgobj_boxed_unown(VALUE boxed); + +/* rbgobj_enums.c */ +extern void rbgobj_constant_remap(const char *original, const char *replacement); +extern void rbgobj_add_constants(VALUE mod, GType type, const gchar *strip_prefix); +extern VALUE rbgobj_make_enum(gint n, GType gtype); +extern gint rbgobj_get_enum(VALUE obj, GType gtype); +extern VALUE rbgobj_make_flags(guint n, GType gtype); +extern guint rbgobj_get_flags(VALUE obj, GType gtype); +extern void rbgobj_define_const(VALUE mod, const char *name, VALUE value); + + +/* rbglib_mainloop.c */ +#if !GLIB_CHECK_VERSION(2,30,0) + #define G_TYPE_MAIN_LOOP (g_main_loop_get_type()) + extern GType g_main_loop_get_type(void); +#endif + +/* rbglib_maincontext.c */ +#if !GLIB_CHECK_VERSION(2,30,0) + #define G_TYPE_MAIN_CONTEXT (g_main_context_get_type()) + #define G_TYPE_SOURCE (g_source_get_type()) + extern GType g_main_context_get_type(void); + extern GType g_source_get_type(void); +#endif + +#define G_TYPE_POLL_FD (g_poll_fd_get_type()) +extern GType g_poll_fd_get_type(void); + +/* rbglib_keyfile.c */ +#if !GLIB_CHECK_VERSION(2,31,2) + #define G_TYPE_KEY_FILE (g_key_file_get_type()) + extern GType g_key_file_get_type(void); +#endif + +/* rbgobj_convert.c */ +typedef struct { + GType type; + VALUE klass; + gpointer user_data; + GDestroyNotify notify; + VALUE (*get_superclass)(gpointer user_data); + void (*type_init_hook)(VALUE klass, gpointer user_data); + void (*rvalue2gvalue)(VALUE value, GValue *result, gpointer user_data); + VALUE (*gvalue2rvalue)(const GValue *value, gpointer user_data); + void (*initialize)(VALUE rb_instance, gpointer instance, gpointer user_data); + gpointer (*robj2instance)(VALUE rb_instance, gpointer user_data); + VALUE (*instance2robj)(gpointer instance, gpointer user_data); + void (*unref)(gpointer instance, gpointer user_data); +} RGConvertTable; + +extern void rbgobj_convert_define(const RGConvertTable *table); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __RBGOBJECT_H__ */ + +#include "rbgcompat.h" Added: binding/ruby/glib-3.1.1/ext/glib2/rbgprivate.h (+179 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbgprivate.h 2017-02-15 13:19:47 +0900 (69b4729) @@ -0,0 +1,179 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2007-2015 Ruby-GNOME2 Project Team + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef __RBGPRIVATE_H__ +#define __RBGPRIVATE_H__ + +#include "rbgobject.h" + +#ifndef HAVE_RB_ERRINFO +# define rb_errinfo() (ruby_errinfo) +#endif + +#ifndef HAVE_RB_EXC_NEW_STR +# define rb_exc_new_str(klass, message) rb_exc_new3(klass, message) +#endif + +#ifndef G_VALUE_INIT +# define G_VALUE_INIT { 0, { { 0 } } } +#endif + +G_BEGIN_DECLS + +typedef struct { + VALUE self; + GObject* gobj; + const RGObjClassInfo* cinfo; + gboolean destroyed; +} gobj_holder; + +typedef struct { + gpointer boxed; + gboolean own; + GType type; +} boxed_holder; + +G_GNUC_INTERNAL extern GStaticPrivate rg_polling_key; + +extern VALUE rbgobj_cEnum; +extern VALUE rbgobj_cFlags; +extern VALUE rbgobj_cBoxed; +extern VALUE rbgobj_cParam; +extern VALUE rbgobj_mInterface; +extern VALUE rbgobj_cObject; + +extern VALUE rbgobj_cInstantiatable; +extern VALUE rbgobj_mMetaInterface; +#define cInstantiatable rbgobj_cInstantiatable +#define mMetaInterface rbgobj_mMetaInterface + +extern void rbgobj_define_property_accessors(VALUE klass); +extern void rbgobj_define_action_methods(VALUE klass); + +extern void rbgobj_param_spec_initialize(VALUE self, GParamSpec* pspec); +extern void rbgobj_boxed_initialize(VALUE obj, gpointer boxed); + +extern GParamSpec* rbgobj_get_param_spec(VALUE obj); +extern GObject* rbgobj_get_gobject(VALUE obj); + +extern VALUE rbgobj_get_ruby_object_from_param_spec(GParamSpec* pspec, gboolean alloc); + +extern void rbgobj_init_object_class(VALUE klass); +extern void rbgobj_init_flags_class(VALUE klass); +extern void rbgobj_init_enum_class(VALUE klass); +extern void rbgobj_init_interface(VALUE interf); + +/* FIXME: should have better name */ +extern void rbgobj_instance_call_cinfo_mark(gpointer instance); +extern void rbgobj_instance_call_cinfo_free(gpointer instance); + +VALUE rbgutil_generic_s_gtype(VALUE klass); +VALUE rbgutil_generic_gtype(VALUE self); +#define generic_s_gtype rbgutil_generic_s_gtype +#define generic_gtype rbgutil_generic_gtype + +extern gboolean rbgobj_convert_has_type(GType type); +extern RGConvertTable *rbgobj_convert_lookup(GType type); + +extern gboolean rbgobj_convert_get_superclass(GType type, VALUE *result); +extern gboolean rbgobj_convert_type_init_hook(GType type, VALUE klass); +extern gboolean rbgobj_convert_gvalue2rvalue(GType type, const GValue *value, + VALUE *result); +extern gboolean rbgobj_convert_rvalue2gvalue(GType type, VALUE val, + GValue *result); +extern GType rbgobj_convert_rvalue2gtype(VALUE val); +extern gboolean rbgobj_convert_initialize(GType type, VALUE obj, gpointer cobj); +extern gboolean rbgobj_convert_robj2instance(GType type, VALUE obj, + gpointer *result); +extern gboolean rbgobj_convert_instance2robj(GType type, gpointer instance, + VALUE *result); +extern gboolean rbgobj_convert_unref(GType type, gpointer instance); + +#define RubyGObjectHookModule "RubyGObjectHook__" + +G_GNUC_INTERNAL VALUE rg_enum_resolve_value(VALUE klass, VALUE nick); +G_GNUC_INTERNAL void rg_enum_add_constants(VALUE mod, GType enum_type, const gchar *strip_prefix); +G_GNUC_INTERNAL void rg_flags_add_constants(VALUE mod, GType flags_type, const gchar *strip_prefix); +G_GNUC_INTERNAL char *rg_obj_constant_lookup(const char *name); + +G_GNUC_INTERNAL void Init_gutil(void); +G_GNUC_INTERNAL void Init_gutil_callback(void); +G_GNUC_INTERNAL void Init_glib_gettext(void); +G_GNUC_INTERNAL void Init_glib_int64(void); +G_GNUC_INTERNAL void Init_glib_error(void); +G_GNUC_INTERNAL void Init_glib_threads(void); +G_GNUC_INTERNAL void Init_glib_convert(void); +G_GNUC_INTERNAL void Init_glib_messages(void); +G_GNUC_INTERNAL void Init_glib_spawn(void); +G_GNUC_INTERNAL void Init_glib_spawnerror(void); +G_GNUC_INTERNAL void Init_glib_fileutils(void); +G_GNUC_INTERNAL void Init_glib_utils(void); +G_GNUC_INTERNAL void Init_glib_i18n(void); +G_GNUC_INTERNAL void Init_glib_win32(void); +G_GNUC_INTERNAL void Init_gobject(void); +G_GNUC_INTERNAL void Init_glib_main_loop(void); +G_GNUC_INTERNAL void Init_glib_main_context(void); +G_GNUC_INTERNAL void Init_glib_source(void); +G_GNUC_INTERNAL void Init_glib_poll_fd(void); +G_GNUC_INTERNAL void Init_glib_io_constants(void); +G_GNUC_INTERNAL void Init_glib_io_channel(void); +G_GNUC_INTERNAL void Init_glib_io_channelerror(void); +G_GNUC_INTERNAL void Init_glib_io_channel_win32_socket(void); +G_GNUC_INTERNAL void Init_glib_shell(void); +G_GNUC_INTERNAL void Init_glib_shellerror(void); +G_GNUC_INTERNAL void Init_glib_timer(void); +G_GNUC_INTERNAL void Init_glib_unicode(void); +G_GNUC_INTERNAL void Init_glib_utf8(void); +G_GNUC_INTERNAL void Init_glib_utf16(void); +G_GNUC_INTERNAL void Init_glib_ucs4(void); +G_GNUC_INTERNAL void Init_glib_unichar(void); +G_GNUC_INTERNAL void Init_glib_keyfile(void); +G_GNUC_INTERNAL void Init_glib_bookmark_file(void); +G_GNUC_INTERNAL void Init_glib_variant_type(void); +G_GNUC_INTERNAL void Init_glib_variant(void); +G_GNUC_INTERNAL void Init_glib_regex(void); +G_GNUC_INTERNAL void Init_glib_matchinfo(void); +G_GNUC_INTERNAL void Init_glib_date_time(void); +G_GNUC_INTERNAL void Init_glib_time_zone(void); + +G_GNUC_INTERNAL void Init_gobject_convert(void); +G_GNUC_INTERNAL void Init_gobject_gtype(void); +G_GNUC_INTERNAL void Init_gobject_typeinterface(void); +G_GNUC_INTERNAL void Init_gobject_typeinstance(void); +G_GNUC_INTERNAL void Init_gobject_gvalue(void); +G_GNUC_INTERNAL void Init_gobject_gvaluetypes(void); +G_GNUC_INTERNAL void Init_gobject_gboxed(void); +G_GNUC_INTERNAL void Init_gobject_gstrv(void); +G_GNUC_INTERNAL void Init_gobject_value_array(void); +G_GNUC_INTERNAL void Init_gobject_genumflags(void); +G_GNUC_INTERNAL void Init_gobject_genums(void); +G_GNUC_INTERNAL void Init_gobject_gflags(void); +G_GNUC_INTERNAL void Init_gobject_gparam(void); +G_GNUC_INTERNAL void Init_gobject_gparamspecs(void); +G_GNUC_INTERNAL void Init_gobject_gclosure(void); +G_GNUC_INTERNAL void Init_gobject_gobject(void); +G_GNUC_INTERNAL void Init_gobject_gsignal(void); +G_GNUC_INTERNAL void Init_gobject_gtypeplugin(void); +G_GNUC_INTERNAL void Init_gobject_gtypemodule(void); +G_GNUC_INTERNAL void Init_gobject_gbinding(void); + +G_END_DECLS + +#endif Added: binding/ruby/glib-3.1.1/ext/glib2/rbgutil.c (+220 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbgutil.c 2017-02-15 13:19:47 +0900 (20111e3) @@ -0,0 +1,220 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011-2015 Ruby-GNOME2 Project Team + * Copyright (C) 2002-2004 Masao Mutoh + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" + +#include <string.h> + +ID rbgutil_id_module_eval; + +static ID id_add_one_arg_setter; +static ID id_set_property; +static ID id_to_a; +static ID id_allocate; +static ID id_equal; + +void +rbg_define_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc) +{ + rb_define_method(klass, name, func, argc); + if ((argc != 1) || strncmp(name, "set_", 4)) + return; + + name += 4; + rb_funcall(klass, rbgutil_id_module_eval, 3, + CSTR2RVAL_FREE(g_strdup_printf("def %s=(val); set_%s(val); val; end\n", + name, name)), + rb_str_new2(__FILE__), + INT2NUM(__LINE__)); +} + +void +rbg_define_singleton_method(VALUE obj, const char *name, VALUE (*func)(ANYARGS), int argc) +{ + rb_define_singleton_method(obj, name, func, argc); + if ((argc != 1) || strncmp(name, "set_", 4)) + return; + + name += 4; + rb_funcall(obj, rbgutil_id_module_eval, 3, + CSTR2RVAL_FREE(g_strdup_printf("def self.%s=(val); set_%s(val); val; end\n", + name, name)), + rb_str_new2(__FILE__), + INT2NUM(__LINE__)); +} + +void +rbgutil_set_properties(VALUE self, VALUE hash) +{ + int i; + VALUE ary; + GObject* obj; + + Check_Type(hash, RUBY_T_HASH); + ary = rb_funcall(hash, id_to_a, 0); + obj = RVAL2GOBJ(self); + + g_object_freeze_notify(obj); + for (i = 0; i < RARRAY_LEN(ary); i++) { + rb_funcall(self, id_set_property, 2, + RARRAY_PTR(RARRAY_PTR(ary)[i])[0], + RARRAY_PTR(RARRAY_PTR(ary)[i])[1]); + } + g_object_thaw_notify(obj); +} + +VALUE +rbgutil_def_setters(VALUE klass) +{ + return rb_funcall(mGLib, id_add_one_arg_setter, 1, klass); +} + +void +rbgutil_glibid_r2g_func(VALUE from, GValue* to) +{ + VALUE buffer; + g_value_set_string(to, RVAL2GLIBID(from, buffer)); +} + +VALUE +rbgutil_sym_g2r_func(const GValue *from) +{ + const gchar *str = g_value_get_string(from); + return str ? ID2SYM(rb_intern(str)) : Qnil; +} + +VALUE +rbgutil_generic_s_gtype(VALUE klass) +{ + return rbgobj_gtype_new(CLASS2GTYPE(klass)); +} + +VALUE +rbgutil_generic_gtype(VALUE self) +{ + return generic_s_gtype(CLASS_OF(self)); +} + +VALUE +rbgutil_string_set_utf8_encoding(VALUE string) +{ + if (!NIL_P(string)) + rb_enc_associate(string, rb_utf8_encoding()); + return string; +} + +gboolean +rbgutil_key_equal(VALUE rb_key, const char *key) +{ + switch (TYPE(rb_key)) { + case RUBY_T_STRING: + return RVAL2CBOOL(rb_funcall(rb_key, id_equal, 1, rb_str_new_cstr(key))); + break; + case RUBY_T_SYMBOL: + return SYM2ID(rb_key) == rb_intern(key); + break; + default: + return FALSE; + break; + } +} + +static gboolean +rbg_interrupt_prepare (G_GNUC_UNUSED GSource *source, + G_GNUC_UNUSED gint *timeout) +{ + return rb_thread_interrupted(rb_thread_current()); +} + +static gboolean +rbg_interrupt_check (G_GNUC_UNUSED GSource *source) +{ + return rb_thread_interrupted(rb_thread_current()); +} + +static gboolean +rbg_interrupt_dispatch (G_GNUC_UNUSED GSource *source, + GSourceFunc callback, + gpointer user_data) +{ + if (callback) { + return callback(user_data); + } else { + return G_SOURCE_REMOVE; + } +} + +static GSourceFuncs rbg_interrupt_funcs; +static void +rbg_interrupt_funcs_init(void) +{ + memset(&rbg_interrupt_funcs, 0, sizeof(GSourceFuncs)); + rbg_interrupt_funcs.prepare = rbg_interrupt_prepare; + rbg_interrupt_funcs.check = rbg_interrupt_check; + rbg_interrupt_funcs.dispatch = rbg_interrupt_dispatch; +} + +GSource * +rbg_interrupt_source_new(void) +{ + return g_source_new(&rbg_interrupt_funcs, sizeof(GSource)); +} + +gchar * +rbg_name_to_nick(const gchar *name) +{ + gchar *nick, *current; + + nick = g_strdup(name); + for (current = nick; *current; current++) { + switch (*current) { + case '_': + case ' ': + *current = '-'; + break; + default: + *current = g_ascii_tolower(*current); + break; + } + } + + return nick; +} + +void * +rbg_memzero(void *pointer, size_t size) +{ + memset(pointer, 0, size); + return pointer; +} + +void +Init_gutil(void) +{ + rbgutil_id_module_eval = rb_intern("module_eval"); + id_set_property = rb_intern("set_property"); + id_to_a = rb_intern("to_a"); + id_add_one_arg_setter = rb_intern("__add_one_arg_setter"); + id_allocate = rb_intern("allocate"); + id_equal = rb_intern("=="); + + rbg_interrupt_funcs_init(); +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbgutil.h (+121 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbgutil.h 2017-02-15 13:19:47 +0900 (d00c04f) @@ -0,0 +1,121 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011-2015 Ruby-GNOME2 Project Team + * Copyright (C) 2002,2003 Masao Mutoh + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef __RBGUTIL_H__ +#define __RBGUTIL_H__ + +#include <glib-object.h> +#include "ruby.h" +#include <ruby/encoding.h> +#include "rbglib.h" +#include "rbgutil_list.h" +#include "rbgutildeprecated.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define RG_DEF_MODFUNC(method, argc) \ + rb_define_module_function(RG_TARGET_NAMESPACE, #method, rg_m_ ## method, argc) +#define RG_DEF_MODFUNC_P(method, argc) \ + rb_define_module_function(RG_TARGET_NAMESPACE, #method"?", rg_m_ ## method ## _p, argc) +#define RG_DEF_MODFUNC_OPERATOR(ope, func, argc) \ + rb_define_module_function(RG_TARGET_NAMESPACE, ope, rg_m_operator_ ## func, argc) +#define RG_DEF_SMETHOD(method, argc) \ + rbg_define_singleton_method(RG_TARGET_NAMESPACE, #method, rg_s_ ## method, argc) +#define RG_DEF_SMETHOD_P(method, argc) \ + rb_define_singleton_method(RG_TARGET_NAMESPACE, #method"?", rg_s_ ## method ## _p, argc) +#define RG_DEF_SMETHOD_BANG(method, argc) \ + rb_define_singleton_method(RG_TARGET_NAMESPACE, #method"!", rg_s_ ## method ## _bang, argc) +#define RG_DEF_SMETHOD_OPERATOR(ope, func, argc) \ + rb_define_singleton_method(RG_TARGET_NAMESPACE, ope, rg_s_operator_ ## func, argc) +#define RG_DEF_METHOD(method, argc) \ + rbg_define_method(RG_TARGET_NAMESPACE, #method, rg_ ## method, argc) +#define RG_DEF_METHOD_P(method, argc) \ + rb_define_method(RG_TARGET_NAMESPACE, #method"?", rg_ ## method ## _p, argc) +#define RG_DEF_METHOD_BANG(method, argc) \ + rb_define_method(RG_TARGET_NAMESPACE, #method"!", rg_ ## method ## _bang, argc) +#define RG_DEF_METHOD_OPERATOR(ope, func, argc) \ + rb_define_method(RG_TARGET_NAMESPACE, ope, rg_operator_ ## func, argc) +#define RG_DEF_ATTR(attr, read, write, ex) \ + rb_attr(RG_TARGET_NAMESPACE, rb_intern(attr), read, write, ex) +#define RG_DEF_ALIAS(new, old) rb_define_alias(RG_TARGET_NAMESPACE, new, old) + +#define RG_REG_GLIBID_SETTER(name) \ + rbgobj_register_property_setter(CLASS2GTYPE(RG_TARGET_NAMESPACE), name, rbgutil_glibid_r2g_func) +#define RG_REG_SYMBOL_GETTER(name) \ + rbgobj_register_property_getter(CLASS2GTYPE(RG_TARGET_NAMESPACE), name, rbgutil_sym_g2r_func) + +#define RG_REPLACE_SET_PROPERTY(name, args) \ + G_REPLACE_SET_PROPERTY(RG_TARGET_NAMESPACE, #name, rg_set_ ## name, args) +#define RG_REPLACE_GET_PROPERTY(name, args) \ + G_REPLACE_GET_PROPERTY(RG_TARGET_NAMESPACE, #name, rg_get_ ## name, args) +#define RG_REPLACE_ACTION(name, args) \ + G_REPLACE_ACTION(RG_TARGET_NAMESPACE, #name, rg_ ## name, args) + +#define G_REPLACE_SET_PROPERTY(klass, name, function, args) \ + rb_undef_method(klass, "set_" name); \ + rb_undef_method(klass, name "="); \ + rbg_define_method(klass, "set_" name, function, args) + +#define G_REPLACE_GET_PROPERTY(klass, name, function, args) \ + rb_undef_method(klass, name); \ + rb_define_method(klass, name, function, args) + +#define G_REPLACE_ACTION(klass, name, function, args) \ + rb_undef_method(klass, name); \ + rb_define_method(klass, name, function, args) + +#define G_SET_PROPERTIES(self, hash) (rbgutil_set_properties(self, hash)) +#define G_PROTECT_CALLBACK(func, data) (rbgutil_invoke_callback((VALUE(*)(VALUE))func, (VALUE)data)) + +#define RBG_STRING_SET_UTF8_ENCODING(string) \ + (rbgutil_string_set_utf8_encoding(string)) + +extern void rbg_define_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc); +extern void rbg_define_singleton_method(VALUE obj, const char *name, VALUE (*func)(ANYARGS), int argc); +extern VALUE rbgutil_def_setters(VALUE klass); +extern void rbgutil_set_properties(VALUE self, VALUE hash); +extern VALUE rbgutil_protect(VALUE (*proc) (VALUE), VALUE data); +extern VALUE rbgutil_invoke_callback(VALUE (*func)(VALUE), VALUE arg); +extern void rbgutil_start_callback_dispatch_thread(void); +extern void rbgutil_stop_callback_dispatch_thread(void); + +extern VALUE rbgutil_string_set_utf8_encoding(VALUE string); +extern gboolean rbgutil_key_equal(VALUE rb_string, const char *key); + +extern const gchar *rbg_inspect(VALUE object); +extern GSource *rbg_interrupt_source_new(void); + +extern gchar *rbg_name_to_nick(const gchar *name); + +extern void *rbg_memzero(void *poitner, size_t size); + +/*< protected >*/ +RUBY_GLIB2_VAR ID rbgutil_id_module_eval; +extern void rbgutil_glibid_r2g_func(VALUE from, GValue* to); +extern VALUE rbgutil_sym_g2r_func(const GValue *from); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __RBGUTIL_H__ */ Added: binding/ruby/glib-3.1.1/ext/glib2/rbgutil_callback.c (+272 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbgutil_callback.c 2017-02-15 13:19:47 +0900 (faafd0f) @@ -0,0 +1,272 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2007 Ruby-GNOME2 Project + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" + +#ifdef G_OS_WIN32 +# ifdef HAVE_IO_H +# include <io.h> +# define pipe(phandles) _pipe(phandles, 128, _O_BINARY) +# endif +#else +# ifdef HAVE_UNISTD_H +# include <unistd.h> +# endif +#endif +#include <fcntl.h> +#include <errno.h> + +#ifndef HAVE_RUBY_NATIVE_THREAD_P +# define ruby_native_thread_p() is_ruby_native_thread() +#endif + +static VALUE rbgutil_eGLibCallbackNotInitializedError; +static ID id_exit_application; + +/**********************************************************************/ + +VALUE +rbgutil_protect(VALUE (*func) (VALUE), VALUE data) +{ + int state = 0; + VALUE ret = rb_protect(func, data, &state); + VALUE e = rb_errinfo(); + if (state && !NIL_P(e)) + rb_funcall(mGLib, id_exit_application, 2, e, INT2NUM(EXIT_FAILURE)); + return ret; +} + +/**********************************************************************/ + +#ifdef HAVE_NATIVETHREAD + +typedef struct _CallbackRequest { + VALUE (*function)(VALUE); + VALUE argument; + VALUE result; + GMutex *done_mutex; + GCond *done_cond; +} CallbackRequest; + +static GMutex *callback_dispatch_thread_mutex = NULL; +static GAsyncQueue *callback_request_queue = NULL; +static ID id_callback_dispatch_thread; +static gint callback_pipe_fds[2] = {-1, -1}; + +#define CALLBACK_PIPE_READY_MESSAGE "R" +#define CALLBACK_PIPE_READY_MESSAGE_SIZE 1 + +static VALUE +exec_callback(VALUE data) +{ + CallbackRequest *request = (CallbackRequest *)data; + return request->function(request->argument); +} + +static VALUE +process_request(CallbackRequest *request) +{ + g_mutex_lock(request->done_mutex); + request->result = rbgutil_protect(exec_callback, (VALUE)request); + g_cond_signal(request->done_cond); + g_mutex_unlock(request->done_mutex); + + return Qnil; +} + +static VALUE +mainloop(void) +{ + for (;;) { + CallbackRequest *request; + gchar ready_message_buffer[CALLBACK_PIPE_READY_MESSAGE_SIZE]; + + rb_thread_wait_fd(callback_pipe_fds[0]); + if (read(callback_pipe_fds[0], ready_message_buffer, + CALLBACK_PIPE_READY_MESSAGE_SIZE + ) != CALLBACK_PIPE_READY_MESSAGE_SIZE || + strncmp(ready_message_buffer, + CALLBACK_PIPE_READY_MESSAGE, + CALLBACK_PIPE_READY_MESSAGE_SIZE) != 0) { + g_error("failed to read valid callback dispatcher message"); + continue; + } + request = g_async_queue_pop(callback_request_queue); + if (!request) + break; + + rb_thread_create(process_request, request); + } + + close(callback_pipe_fds[0]); + callback_pipe_fds[0] = -1; + close(callback_pipe_fds[1]); + callback_pipe_fds[1] = -1; + + return Qnil; +} + +static void +queue_callback_request(CallbackRequest *request) +{ + ssize_t written; + + g_async_queue_push(callback_request_queue, request); + written = write(callback_pipe_fds[1], + CALLBACK_PIPE_READY_MESSAGE, + CALLBACK_PIPE_READY_MESSAGE_SIZE); + if (written != CALLBACK_PIPE_READY_MESSAGE_SIZE) { + rb_warn("couldn't write all callback pipe ready message: " + "message-size: %d, written: %" G_GSSIZE_FORMAT, + CALLBACK_PIPE_READY_MESSAGE_SIZE, + written); + } +} + +static VALUE +invoke_callback_in_ruby_thread(VALUE (*func)(VALUE), VALUE arg) +{ + CallbackRequest request; + + g_mutex_lock(callback_dispatch_thread_mutex); + if (callback_pipe_fds[0] == -1) { + g_error("Please call rbgutil_start_callback_dispatch_thread() " + "to dispatch a callback from non-ruby thread before " + "callbacks are requested from non-ruby thread."); + g_mutex_unlock(callback_dispatch_thread_mutex); + return Qnil; + } + + request.function = func; + request.argument = arg; + request.result = Qnil; + request.done_mutex = g_mutex_new(); + request.done_cond = g_cond_new(); + + g_mutex_lock(request.done_mutex); + queue_callback_request(&request); + g_mutex_unlock(callback_dispatch_thread_mutex); + + g_cond_wait(request.done_cond, request.done_mutex); + g_mutex_unlock(request.done_mutex); + + g_cond_free(request.done_cond); + g_mutex_free(request.done_mutex); + + + return request.result; +} + +#ifdef HAVE_RB_THREAD_CALL_WITH_GVL +extern void *rb_thread_call_with_gvl(void *(*func)(void *), void *data1); + +static void * +invoke_callback_with_gvl(void *arg) +{ + CallbackRequest *req = (CallbackRequest*)arg; + return (void *)rbgutil_protect(req->function, req->argument); +} +#endif + +#endif + +/**********************************************************************/ + +VALUE +rbgutil_invoke_callback(VALUE (*func)(VALUE), VALUE arg) +{ +#ifdef HAVE_NATIVETHREAD + if (ruby_native_thread_p()) { + if (!GPOINTER_TO_INT(g_static_private_get(&rg_polling_key))) { + return rbgutil_protect(func, arg); + } +# ifdef HAVE_RB_THREAD_CALL_WITH_GVL + { + CallbackRequest req; + req.function = func; + req.argument = arg; + return (VALUE)rb_thread_call_with_gvl(invoke_callback_with_gvl, &req); + } +# endif + } else { + return invoke_callback_in_ruby_thread(func, arg); + } +#endif + return rbgutil_protect(func, arg); +} + +/**********************************************************************/ + +void +rbgutil_start_callback_dispatch_thread(void) +{ +#ifdef HAVE_NATIVETHREAD + VALUE callback_dispatch_thread; + + g_mutex_lock(callback_dispatch_thread_mutex); + callback_dispatch_thread = rb_ivar_get(mGLib, id_callback_dispatch_thread); + if (NIL_P(callback_dispatch_thread)) { + if (pipe(callback_pipe_fds) == -1) + rb_sys_fail("pipe()"); + + callback_dispatch_thread = rb_thread_create(mainloop, NULL); + rb_ivar_set(mGLib, id_callback_dispatch_thread, + callback_dispatch_thread); + } + g_mutex_unlock(callback_dispatch_thread_mutex); +#endif +} + +void +rbgutil_stop_callback_dispatch_thread(void) +{ +#ifdef HAVE_NATIVETHREAD + VALUE callback_dispatch_thread; + + g_mutex_lock(callback_dispatch_thread_mutex); + callback_dispatch_thread = rb_ivar_get(mGLib, id_callback_dispatch_thread); + if (!NIL_P(callback_dispatch_thread)) { + queue_callback_request(NULL); + rb_ivar_set(mGLib, id_callback_dispatch_thread, Qnil); + } + g_mutex_unlock(callback_dispatch_thread_mutex); +#endif +} + +void +Init_gutil_callback(void) +{ + id_exit_application = rb_intern("exit_application"); + rbgutil_eGLibCallbackNotInitializedError = + rb_define_class_under(mGLib, "CallbackNotInitializedError", + rb_eRuntimeError); + +#ifdef HAVE_NATIVETHREAD + if (!g_thread_supported()) + g_thread_init(NULL); + + id_callback_dispatch_thread = rb_intern("callback_dispatch_thread"); + rb_ivar_set(mGLib, id_callback_dispatch_thread, Qnil); + + callback_request_queue = g_async_queue_new(); + callback_dispatch_thread_mutex = g_mutex_new(); +#endif +} Added: binding/ruby/glib-3.1.1/ext/glib2/rbgutil_list.c (+269 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbgutil_list.c 2017-02-15 13:19:47 +0900 (f3dc34a) @@ -0,0 +1,269 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011-2015 Ruby-GNOME2 Project Team + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" + +struct list2rval_args { + gpointer list; + RBGRValueFunc conv; + GFreeFunc free_list; + GFreeFunc free_elem; +}; + +struct list2rval_with_type_args { + struct list2rval_args args; + RBGRValueFuncWithType conv_with_type; + GType gtype; +}; + +static VALUE +glist2rval_body(VALUE data) +{ + struct list2rval_args *args = (struct list2rval_args *)data; + RBGRValueFunc conv = args->conv; + GList *node; + VALUE ary; + + ary = rb_ary_new(); + if (conv) + for (node = args->list; node; node = g_list_next(node)) + rb_ary_push(ary, conv(node->data)); + + return ary; +} + +static VALUE +gslist2rval_body(VALUE data) +{ + struct list2rval_args *args = (struct list2rval_args *)data; + RBGRValueFunc conv = args->conv; + GSList *node; + VALUE ary; + + ary = rb_ary_new(); + if (conv) + for (node = args->list; node; node = g_slist_next(node)) + rb_ary_push(ary, conv(node->data)); + + return ary; +} + +static VALUE +glist2rval_with_type_body(VALUE data) +{ + struct list2rval_with_type_args *args_with_type = (struct list2rval_with_type_args *)data; + struct list2rval_args *args = (struct list2rval_args *)data; + RBGRValueFuncWithType conv = args_with_type->conv_with_type; + GType gtype = args_with_type->gtype; + GList *node; + VALUE ary; + + ary = rb_ary_new(); + if (conv) + for (node = args->list; node; node = g_list_next(node)) + rb_ary_push(ary, conv(node->data, gtype)); + + return ary; +} + +static VALUE +gslist2rval_with_type_body(VALUE data) +{ + struct list2rval_with_type_args *args_with_type = (struct list2rval_with_type_args *)data; + struct list2rval_args *args = (struct list2rval_args *)data; + RBGRValueFuncWithType conv = args_with_type->conv_with_type; + GType gtype = args_with_type->gtype; + GSList *node; + VALUE ary; + + ary = rb_ary_new(); + if (conv) + for (node = args->list; node; node = g_slist_next(node)) + rb_ary_push(ary, conv(node->data, gtype)); + + return ary; +} + +static VALUE +glist2rval_ensure(VALUE data) +{ + struct list2rval_args *args = (struct list2rval_args *)data; + GList *node; + + if (args->free_elem) + for (node = args->list; node; node = g_list_next(node)) + args->free_elem(node->data); + if (args->free_list) + args->free_list(args->list); + + return Qnil; +} + +static VALUE +gslist2rval_ensure(VALUE data) +{ + struct list2rval_args *args = (struct list2rval_args *)data; + GSList *node; + + if (args->free_elem) + for (node = args->list; node; node = g_slist_next(node)) + args->free_elem(node->data); + if (args->free_list) + args->free_list(args->list); + + return Qnil; +} + +VALUE +rbg_glist2rval(GList *const list, RBGRValueFunc conv, + GFreeFunc free_list, GFreeFunc free_elem) +{ + struct list2rval_args args = {list, conv, free_list, free_elem}; + + return rb_ensure(glist2rval_body, (VALUE)&args, + glist2rval_ensure, (VALUE)&args); +} + +VALUE +rbg_gslist2rval(GSList *const list, RBGRValueFunc conv, + GFreeFunc free_list, GFreeFunc free_elem) +{ + struct list2rval_args args = {list, conv, free_list, free_elem}; + + return rb_ensure(gslist2rval_body, (VALUE)&args, + gslist2rval_ensure, (VALUE)&args); +} + +VALUE +rbg_glist2rval_with_type(GList *const list, RBGRValueFuncWithType conv, GType gtype, + GFreeFunc free_list, GFreeFunc free_elem) +{ + struct list2rval_with_type_args args = {{list, NULL, free_list, free_elem}, conv, gtype}; + + return rb_ensure(glist2rval_with_type_body, (VALUE)&args, + glist2rval_ensure, (VALUE)&args); +} + +VALUE +rbg_gslist2rval_with_type(GSList *const list, RBGRValueFuncWithType conv, GType gtype, + GFreeFunc free_list, GFreeFunc free_elem) +{ + struct list2rval_with_type_args args = {{list, NULL, free_list, free_elem}, conv, gtype}; + + return rb_ensure(gslist2rval_with_type_body, (VALUE)&args, + gslist2rval_ensure, (VALUE)&args); +} + +struct rval2glist_args { + GList *list; + VALUE rb_array; +}; + +static VALUE +rval2glist_body(VALUE data) +{ + struct rval2glist_args *args = (struct rval2glist_args *)data; + VALUE rb_array; + int i, n; + + rb_array = rbg_to_array(args->rb_array); + n = RARRAY_LEN(rb_array); + for (i = 0; i < n; i++) { + VALUE rb_element = RARRAY_CONST_PTR(rb_array)[i]; + args->list = g_list_append(args->list, RVAL2GOBJ(rb_element)); + } + + return Qnil; +} + +static VALUE +rval2glist_rescue(VALUE data, VALUE e) +{ + struct rval2glist_args *args = (struct rval2glist_args *)data; + + g_list_free(args->list); + args->list = NULL; + + rb_exc_raise(e); + + return Qnil; +} + +GList * +rbg_rval2glist(VALUE rb_array) +{ + struct rval2glist_args args; + args.list = NULL; + args.rb_array = rb_array; + + rb_rescue(rval2glist_body, (VALUE)&args, + rval2glist_rescue, (VALUE)&args); + + return args.list; +} + +struct rval2gslist_args { + GSList *list; + VALUE rb_array; +}; + +static VALUE +rval2gslist_body(VALUE data) +{ + struct rval2gslist_args *args = (struct rval2gslist_args *)data; + VALUE rb_array; + int i, n; + + rb_array = rbg_to_array(args->rb_array); + n = RARRAY_LEN(rb_array); + for (i = 0; i < n; i++) { + VALUE rb_element = RARRAY_CONST_PTR(rb_array)[i]; + args->list = g_slist_append(args->list, RVAL2GOBJ(rb_element)); + } + + return Qnil; +} + +static VALUE +rval2gslist_rescue(VALUE data, VALUE e) +{ + struct rval2gslist_args *args = (struct rval2gslist_args *)data; + + g_slist_free(args->list); + args->list = NULL; + + rb_exc_raise(e); + + return Qnil; +} + +GSList * +rbg_rval2gslist(VALUE rb_array) +{ + struct rval2gslist_args args; + args.list = NULL; + args.rb_array = rb_array; + + rb_rescue(rval2gslist_body, (VALUE)&args, + rval2gslist_rescue, (VALUE)&args); + + return args.list; +} + Added: binding/ruby/glib-3.1.1/ext/glib2/rbgutil_list.h (+94 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbgutil_list.h 2017-02-15 13:19:47 +0900 (21aa083) @@ -0,0 +1,94 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011-2015 Ruby-GNOME2 Project Team + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef __RBGUTIL_LIST_H__ +#define __RBGUTIL_LIST_H__ + +G_BEGIN_DECLS + +#define CSTRGLIST2RVAL(list) \ + CSTRGLIST2RVAL_FREE(list, NULL, NULL) +#define CSTRGLIST2RVAL_FREE(list, free_list, free_elem) \ + rbg_glist2rval(list, (RBGRValueFunc)rbg_cstr2rval, \ + (GFreeFunc)free_list, (GFreeFunc)free_elem) +#define CSTRGSLIST2RVAL(list) \ + CSTRGSLIST2RVAL_FREE(list, NULL, NULL) +#define CSTRGSLIST2RVAL_FREE(list, free_list, free_elem) \ + rbg_gslist2rval(list, (RBGRValueFunc)rbg_cstr2rval, \ + (GFreeFunc)free_list, (GFreeFunc)free_elem) + +#define FILENAMEGLIST2RVAL(list) \ + FILENAMEGLIST2RVAL_FREE(list, NULL, NULL) +#define FILENAMEGLIST2RVAL_FREE(list, free_list, free_elem) \ + rbg_glist2rval(list, (RBGRValueFunc)rbg_filename_to_ruby, \ + (GFreeFunc)free_list, (GFreeFunc)free_elem) +#define FILENAMEGSLIST2RVAL(list) \ + FILENAMEGSLIST2RVAL_FREE(list, NULL, NULL) +#define FILENAMEGSLIST2RVAL_FREE(list, free_list, free_elem) \ + rbg_gslist2rval(list, (RBGRValueFunc)rbg_filename_to_ruby, \ + (GFreeFunc)free_list, (GFreeFunc)free_elem) + +#define GOBJGLIST2RVAL(list) \ + GOBJGLIST2RVAL_FREE(list, NULL, NULL) +#define GOBJGLIST2RVAL_FREE(list, free_list, free_elem) \ + rbg_glist2rval(list, (RBGRValueFunc)rbgobj_ruby_object_from_instance, \ + (GFreeFunc)free_list, (GFreeFunc)free_elem) +#define GOBJGSLIST2RVAL(list) \ + GOBJGSLIST2RVAL_FREE(list, NULL, NULL) +#define GOBJGSLIST2RVAL_FREE(list, free_list, free_elem) \ + rbg_gslist2rval(list, (RBGRValueFunc)rbgobj_ruby_object_from_instance, \ + (GFreeFunc)free_list, (GFreeFunc)free_elem) + +#define BOXEDGLIST2RVAL(list, gtype) \ + BOXEDGLIST2RVAL_FREE(list, gtype, NULL, NULL) +#define BOXEDGLIST2RVAL_FREE(list, gtype, free_list, free_elem) \ + rbg_glist2rval_with_type(list, (RBGRValueFuncWithType)rbgobj_make_boxed, gtype, \ + (GFreeFunc)free_list, (GFreeFunc)free_elem) +#define BOXEDGSLIST2RVAL(list, gtype) \ + BOXEDGSLIST2RVAL_FREE(list, gtype, NULL, NULL) +#define BOXEDGSLIST2RVAL_FREE(list, gtype, free_list, free_elem) \ + rbg_gslist2rval_with_type(list, (RBGRValueFuncWithType)rbgobj_make_boxed, gtype, \ + (GFreeFunc)free_list, (GFreeFunc)free_elem) + +#define RVAL2GOBJGLIST(rb_array) \ + rbg_rval2glist(rb_array) +#define RVAL2GOBJGSLIST(rb_array) \ + rbg_rval2gslist(rb_array) + + +typedef VALUE (*RBGRValueFunc)(gpointer obj); +typedef VALUE (*RBGRValueFuncWithType)(gpointer obj, GType gtype); + +extern VALUE rbg_glist2rval(GList *const list, RBGRValueFunc conv, + GFreeFunc free_list, GFreeFunc free_elem); +extern VALUE rbg_gslist2rval(GSList *const list, RBGRValueFunc conv, + GFreeFunc free_list, GFreeFunc free_elem); +extern VALUE rbg_glist2rval_with_type(GList *const list, RBGRValueFuncWithType conv, GType gtype, + GFreeFunc free_list, GFreeFunc free_elem); +extern VALUE rbg_gslist2rval_with_type(GSList *const list, RBGRValueFuncWithType conv, GType gtype, + GFreeFunc free_list, GFreeFunc free_elem); + +extern GList *rbg_rval2glist(VALUE rb_array); +extern GSList *rbg_rval2gslist(VALUE rb_array); + +G_END_DECLS + +#endif /* __RBGUTIL_LIST_H__ */ + Added: binding/ruby/glib-3.1.1/ext/glib2/rbgutildeprecated.c (+252 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbgutildeprecated.c 2017-02-15 13:19:47 +0900 (b5d2f65) @@ -0,0 +1,252 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2002-2004 Masao Mutoh + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include "rbgprivate.h" + +VALUE +rbgutil_glist2ary(const GList *const list) +{ + VALUE ary; + const GList *i; + + ary = rb_ary_new(); + for (i = list; i != NULL; i = i->next) + rb_ary_push(ary, GOBJ2RVAL(i->data)); + + return ary; +} + +static VALUE +rbgutil_glist2ary_and_free_body(VALUE data) +{ + VALUE ary; + GList *i; + + ary = rb_ary_new(); + for (i = (GList *)data; i != NULL; i = i->next) + rb_ary_push(ary, GOBJ2RVAL(i->data)); + + return ary; +} + +static VALUE +rbgutil_glist2ary_and_free_ensure(VALUE data) +{ + g_list_free((GList *)data); + + return Qnil; +} + +VALUE +rbgutil_glist2ary_and_free(GList *const list) +{ + return rb_ensure(rbgutil_glist2ary_and_free_body, (VALUE)list, + rbgutil_glist2ary_and_free_ensure, (VALUE)list); +} + +VALUE +rbgutil_glist2ary_boxed(const GList *const list, GType gtype) +{ + VALUE ary; + const GList *i; + + ary = rb_ary_new(); + for (i = list; i != NULL; i = i->next) + rb_ary_push(ary, BOXED2RVAL(i->data, gtype)); + + return ary; +} + +struct rbgutil_glist2ary_boxed_and_free_data +{ + GList *const list; + GType gtype; +}; + +static VALUE +rbgutil_glist2ary_boxed_and_free_body(VALUE data) +{ + struct rbgutil_glist2ary_boxed_and_free_data *real; + VALUE ary; + GList *i; + + real = (struct rbgutil_glist2ary_boxed_and_free_data *)data; + ary = rb_ary_new(); + for (i = real->list; i != NULL; i = i->next) + rb_ary_push(ary, BOXED2RVAL(i->data, real->gtype)); + + return ary; +} + +static VALUE +rbgutil_glist2ary_boxed_and_free_ensure(VALUE data) +{ + g_list_free(((struct rbgutil_glist2ary_boxed_and_free_data *)data)->list); + + return Qnil; +} + +VALUE +rbgutil_glist2ary_boxed_and_free(GList *const list, GType gtype) +{ + struct rbgutil_glist2ary_boxed_and_free_data data = { list, gtype }; + + return rb_ensure(rbgutil_glist2ary_boxed_and_free_body, (VALUE)&data, + rbgutil_glist2ary_boxed_and_free_ensure, (VALUE)&data); +} + +VALUE +rbgutil_glist2ary_string(const GList *const list) +{ + VALUE ary; + const GList *i; + + ary = rb_ary_new(); + for (i = list; i != NULL; i = i->next) + rb_ary_push(ary, CSTR2RVAL(i->data)); + + return ary; +} + +static VALUE +rbgutil_glist2ary_string_and_free_body(VALUE data) +{ + VALUE ary; + GList *i; + + ary = rb_ary_new(); + for (i = (GList *)data; i != NULL; i = i->next) + rb_ary_push(ary, CSTR2RVAL(i->data)); + + return ary; +} + +static VALUE +rbgutil_glist2ary_string_and_free_ensure(VALUE data) +{ + GList *i; + + for (i = (GList *)data; i != NULL; i = i->next) + g_free(i->data); + g_list_free((GList *)data); + + return Qnil; +} + +VALUE +rbgutil_glist2ary_string_and_free(GList *const list) +{ + return rb_ensure(rbgutil_glist2ary_string_and_free_body, (VALUE)list, + rbgutil_glist2ary_string_and_free_ensure, (VALUE)list); +} + +VALUE +rbgutil_gslist2ary(const GSList *const list) +{ + VALUE ary; + const GSList *i; + + ary = rb_ary_new(); + for (i = list; i != NULL; i = i->next) + rb_ary_push(ary, GOBJ2RVAL(i->data)); + + return ary; +} + +static VALUE +rbgutil_gslist2ary_and_free_body(VALUE data) +{ + VALUE ary; + GSList *i; + + ary = rb_ary_new(); + for (i = (GSList *)data; i != NULL; i = i->next) + rb_ary_push(ary, GOBJ2RVAL(i->data)); + + return ary; +} + +static VALUE +rbgutil_gslist2ary_and_free_ensure(VALUE data) +{ + g_slist_free((GSList *)data); + + return Qnil; +} + +VALUE +rbgutil_gslist2ary_and_free(GSList *const list) +{ + return rb_ensure(rbgutil_gslist2ary_and_free_body, (VALUE)list, + rbgutil_gslist2ary_and_free_ensure, (VALUE)list); +} + +VALUE +rbgutil_gslist2ary_boxed(const GSList *const list, GType gtype) +{ + VALUE ary; + const GSList *i; + + ary = rb_ary_new(); + for (i = list; i != NULL; i = i->next) + rb_ary_push(ary, BOXED2RVAL(i->data, gtype)); + + return ary; +} + +struct rbgutil_gslist2ary_boxed_and_free_data +{ + GSList *const list; + GType gtype; +}; + +static VALUE +rbgutil_gslist2ary_boxed_and_free_body(VALUE data) +{ + struct rbgutil_gslist2ary_boxed_and_free_data *real; + VALUE ary; + GSList *i; + + real = (struct rbgutil_gslist2ary_boxed_and_free_data *)data; + ary = rb_ary_new(); + for (i = real->list; i != NULL; i = i->next) + rb_ary_push(ary, BOXED2RVAL(i->data, real->gtype)); + + return ary; +} + +static VALUE +rbgutil_gslist2ary_boxed_and_free_ensure(VALUE data) +{ + g_slist_free(((struct rbgutil_gslist2ary_boxed_and_free_data *)data)->list); + + return Qnil; +} + +VALUE +rbgutil_gslist2ary_boxed_and_free(GSList *const list, GType gtype) +{ + struct rbgutil_gslist2ary_boxed_and_free_data data = { list, gtype }; + + return rb_ensure(rbgutil_gslist2ary_boxed_and_free_body, (VALUE)&data, + rbgutil_gslist2ary_boxed_and_free_ensure, (VALUE)&data); +} + Added: binding/ruby/glib-3.1.1/ext/glib2/rbgutildeprecated.h (+63 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/rbgutildeprecated.h 2017-02-15 13:19:47 +0900 (10abfb0) @@ -0,0 +1,63 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/* + * Copyright (C) 2011 Ruby-GNOME2 Project Team + * Copyright (C) 2002,2003 Masao Mutoh + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#ifndef __RBGUTILDEPRECATED_H__ +#define __RBGUTILDEPRECATED_H__ + +G_BEGIN_DECLS + +#define G_DEF_SETTER(klass, name) \ + rb_funcall(klass, rbgutil_id_module_eval, 1, rb_str_new2( \ + "def " name "=(val); set_" name "(val); val; end\n")) +#define G_DEF_SETTERS(klass) rbgutil_def_setters(klass) + +#define GLIST2ARY(list) (rbgutil_glist2ary(list)) +#define GLIST2ARY_FREE(list) (rbgutil_glist2ary_and_free(list)) +#define GLIST2ARYF(list) (GLIST2ARY_FREE(list)) +#define GLIST2ARY2(list, gtype) (rbgutil_glist2ary_boxed(list, gtype)) +#define GLIST2ARY2F(list, gtype) (rbgutil_glist2ary_boxed_and_free(list, gtype)) +#define GLIST2ARY_STR(list) (rbgutil_glist2ary_string(list)) +#define GLIST2ARY_STR_FREE(list) (rbgutil_glist2ary_string_and_free(list)) +#define GSLIST2ARY(list) (rbgutil_gslist2ary(list)) +#define GSLIST2ARY_FREE(list) (rbgutil_gslist2ary_and_free(list)) +#define GSLIST2ARYF(list) (GSLIST2ARY_FREE(list)) +#define GSLIST2ARY2(list, gtype) (rbgutil_gslist2ary_boxed(list, gtype)) +#define GSLIST2ARY2F(list, gtype) (rbgutil_gslist2ary_boxed_and_free(list, gtype)) + +#define G_SET_SYMBOL_PROPERTY(gtype, name) \ + rbgobj_register_property_getter(gtype, name, rbgutil_sym_g2r_func) + +#define G_BLOCK_PROC rb_block_proc + +extern VALUE rbgutil_glist2ary(const GList *list); +extern VALUE rbgutil_glist2ary_and_free(GList* list); +extern VALUE rbgutil_glist2ary_boxed(const GList *list, GType gtype); +extern VALUE rbgutil_glist2ary_boxed_and_free(GList *list, GType gtype); +extern VALUE rbgutil_glist2ary_string(const GList *list); +extern VALUE rbgutil_glist2ary_string_and_free(GList *list); +extern VALUE rbgutil_gslist2ary(const GSList *list); +extern VALUE rbgutil_gslist2ary_and_free(GSList *list); +extern VALUE rbgutil_gslist2ary_boxed(const GSList *list, GType gtype); +extern VALUE rbgutil_gslist2ary_boxed_and_free(GSList *list, GType gtype); + +G_END_DECLS + +#endif /* __RBGUTILDEPRECATED_H__ */ Added: binding/ruby/glib-3.1.1/ext/glib2/ruby-glib2.pc (+3 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/ext/glib2/ruby-glib2.pc 2017-02-15 13:19:47 +0900 (b5804ee) @@ -0,0 +1,3 @@ +Name: Ruby/GLib2 +Description: Ruby bindings for GLib Type, Object, Parameter and Signal Library +Version: 2.2.4 \ No newline at end of file Added: binding/ruby/glib-3.1.1/extconf.rb (+49 -0) 100755 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/extconf.rb 2017-02-15 13:19:47 +0900 (d0361bd) @@ -0,0 +1,49 @@ +#!/usr/bin/env ruby + +require 'pathname' +require 'mkmf' +require 'rbconfig' +require 'fileutils' + +package = "glib2" + +base_dir = Pathname(__FILE__).dirname.expand_path +ext_dir = base_dir + "ext" + package +mkmf_gnome2_dir = base_dir + 'lib' + +ruby = File.join(RbConfig::CONFIG['bindir'], + RbConfig::CONFIG['ruby_install_name'] + + RbConfig::CONFIG["EXEEXT"]) + +build_dir = Pathname("ext") + package +FileUtils.mkdir_p(build_dir.to_s) unless build_dir.exist? +extconf_rb_path = ext_dir + "extconf.rb" +system(ruby, "-C", build_dir.to_s, extconf_rb_path.to_s, *ARGV) || exit(false) + +create_makefile(package) +FileUtils.mv("Makefile", "Makefile.lib") + +File.open("Makefile", "w") do |makefile| + makefile.puts(<<-EOM) +all: + (cd ext/#{package} && $(MAKE)) + $(MAKE) -f Makefile.lib + +install: + (cd ext/#{package} && $(MAKE) install) + $(MAKE) -f Makefile.lib install + +site-install: + (cd ext/#{package} && $(MAKE) site-install) + $(MAKE) -f Makefile.lib site-install + +clean: + (cd ext/#{package} && $(MAKE) clean) + $(MAKE) -f Makefile.lib clean + +distclean: + (cd ext/#{package} && $(MAKE) distclean) + $(MAKE) -f Makefile.lib distclean + @rm -f Makefile.lib +EOM +end Added: binding/ruby/glib-3.1.1/lib/glib-mkenums.rb (+214 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/lib/glib-mkenums.rb 2017-02-15 13:19:47 +0900 (d1345e0) @@ -0,0 +1,214 @@ +# +# glib-mkenums.rb +# +# C language enum description generation library like as glib-mkenums tool. +# +# Copyright(C) 2006-2015 Ruby-GNOME2 Project. +# +# This program is licenced under the same license of Ruby-GNOME2. +# + +module GLib + class EnumDefinition + attr_accessor :EnumName, :enum_name, :ENUM_NAME, :ENUM_SHORT + attr_accessor :type, :Type + attr_accessor :g_type_prefix, :prefix + + attr_reader :constants + + def initialize(name, const_lines, g_type_prefix, options={}) + @options = options || {} + @EnumName = name + @g_type_prefix = g_type_prefix + @constants = [] + @enum_name = to_snail_case(@EnumName) + @ENUM_NAME = @enum_name.upcase + @ENUM_SHORT = @ENUM_NAME.sub(/^#{@g_type_prefix.sub(/_TYPE.*$/, "")}/, "").sub(/^_/, "") + + parse_const_lines(const_lines) + end + + def parse_const_lines(const_lines) + if @options[:force_flags] or /<</ =~ const_lines + @type = "flags" + @Type = "Flags" + else + @type = "enum" + @Type = "Enum" + end + constants = [] + const_lines.scan(/^\s*([^\s,]*).*\n/) do |name| + constants << name[0] unless name[0] =~ /(^[\/\*]|^#|^$)/ + end + @prefix = extract_prefix(constants) + constants.each do |name| + @constants << [name, name.sub(/#{@prefix}/, "").gsub(/_/, "-").downcase] + end + end + + def extract_prefix(ary) + return [] if ary == nil + a = ary[0].split(//) + if ary.size == 1 + @ENUM_NAME + "_" + else + ary[1..-1].each do |b| + b = b.split(//) + l = [a.length, b.length].min + a = a[0, (0...l).find{|i| a[i] != b[i] } || l] + end + a.join('') + end + end + + def create_c + constants = "\n" +****@const*****{|name, nick| + %Q[ { #{name}, "#{name}", "#{nick}" },\n] + }.join + + %Q[ { 0, NULL, NULL }] + + ret = <<-CREATE_C + +GType +#{@enum_name}_get_type (void) +{ + static GType etype = 0; + if (etype == 0) { + static const G#{@Type}Value values[] = {#{constants} + }; + etype = g_#{@type}_register_static ("#{@EnumName}", values); + } + return etype; +} + CREATE_C + ret + end + + def create_h + %Q[ +GType #{@enum_name}_get_type (void); +#define #{@g_type_prefix}#{@ENUM_SHORT} (#{@enum_name}_get_type())] + end + + private + def to_snail_case(name) + prefix_processed_name = name.sub(/^[A-Z]/) do |prefix| + prefix.downcase + end + snail_cased_name = prefix_processed_name.gsub(/[A-Z]+/) do |upper_case| + down_case = upper_case.downcase + if down_case.size == 1 + "_#{down_case}" + else + "_#{down_case[0..-2]}_#{down_case[-1..-1]}" + end + end + snail_cased_name.sub(/(^_|_$)/, "") + end + + def self.parse(data, g_type_prefix, options={}) + options ||= {} + enums = [] + data.force_encoding("utf-8") if data.respond_to?(:force_encoding) + data.scan(/^\s*typedef\s+enum\s*(\/\*<\s*flags\s*>\*\/)?\s* + \{?\s*(.*?) + \}\s*(\w+);/mx) do |force_flags, constants, name| + enum_options = {} + enum_options[:force_flags] = !force_flags.nil? + force_flags_patterns = [(options[:force_flags] || [])].flatten + if force_flags_patterns.any? {|pattern| pattern === name} + enum_options[:force_flags] = true + end + enum = new(name, constants, g_type_prefix, enum_options) + enums << enum + end + enums + end + end + + class MkEnums + # Create target_filename.c and target_filename.h from files + # with g_type_prefix and include_files. + # * target_filename: the target file name. This creates #{target_filename.c} and #{target_filename.h}. + # * files: header files to parse + # * g_type_prefix: the gtype prefix such as GTK_TYPE_ + # * include_files: define #include <file> lines into target_filename.c + def self.create(target_filename, files, g_type_prefix, include_files, + options) + puts "creating #{target_filename}.c" + mkenums = MkEnums.new(target_filename, files, g_type_prefix, include_files, + options) + + open("#{target_filename}.c", "w") do |out| + out.write(mkenums.create_c) + end + puts "creating #{target_filename}.h" + open("#{target_filename}.h", "w") do |out| + out.write(mkenums.create_h) + end + end + + # Initialize GLib::MkEnums + # + # * target_filename: the target file name. This creates #{target_filename.c} and #{target_filename.h}. + # * files: header files to parse + # * g_type_prefix: the gtype prefix such as GTK_TYPE_ + # * include_files: define #include <file> lines into target_filename.c + def initialize(target_filename, files, g_type_prefix, include_files, options) + @target_filename = target_filename + @include_files = include_files + @targets = [] + files.each do |path| + data = "" + File.open(path) do |i| + data = i.read + end + @targets << [path, EnumDefinition.parse(data, g_type_prefix, options)] + end + end + + def create_enums(meth) # :nodoc: + ret = "" + @targets.each do |target| + if target[1].size > 0 + ret << %Q[\n\n/* enumerations from "#{target[0]}" */] + target[1].each{|enum| + ret << enum.__send__(meth) + } + end + end + ret + end + + # Create a C source as a String. + def create_c + ret = "\n/* Generated by glib-mkenums.rb ($Id$) */ \n\n" + ret << %Q[#include "#{@target_filename}.h"\n] + @include_files.each do |file| + ret << "#include <#{file}>\n" + end + ret << "\n" + ret << create_enums(:create_c) + ret << "\n\n/* Generated data ends here */\n\n" + ret + end + + # Create a C header as a String. + def create_h + header = "#{@target_filename}.h" + const = "__#{File.basename(header).upcase.gsub(/-|\./, '_')}__" + + ret = "\n/* Generated by glib-mkenums.rb ($Id$) */ \n\n" + ret << "#ifndef #{const}\n" + ret << "#define #{const}\n\n" + ret << "#include <glib-object.h>\n\n" + ret << "G_BEGIN_DECLS" + ret << create_enums(:create_h) + ret << "\n\nG_END_DECLS\n\n" + ret << "#endif /* #{const} */\n" + ret << "\n/* Generated data ends here */\n\n" + ret + end + end +end + Added: binding/ruby/glib-3.1.1/lib/glib2.rb (+272 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/lib/glib2.rb 2017-02-15 13:19:47 +0900 (c53a2eb) @@ -0,0 +1,272 @@ +# Copyright (C) 2005-2016 Ruby-GNOME2 Project Team +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +require 'pathname' +require 'English' +require 'thread' +require 'glib2/deprecatable' + +module GLib + module_function + def check_binding_version?(major, minor, micro) + BINDING_VERSION[0] > major || + (BINDING_VERSION[0] == major && + BINDING_VERSION[1] > minor) || + (BINDING_VERSION[0] == major && + BINDING_VERSION[1] == minor && + BINDING_VERSION[2] >= micro) + end + + def exit_application(exception, status) + msg = exception.message || exception.to_s + msg = exception.class.to_s if msg == "" + backtrace = exception.backtrace || [] + first_line = backtrace.shift + if first_line + $stderr.puts("#{first_line}: #{msg}") + else + $stderr.puts(msg) + end + backtrace.each do |v| + $stderr.puts("\t from #{v}") + end + exit(status) + end + + def __add_one_arg_setter(klass) + # for Instance methods. + method_names = klass.instance_methods(false) + method_names.each do |method_name| + next if /\Aset_/ !~ method_name + property_name = $POSTMATCH + next if klass.method_defined?("#{property_name}=") + next if klass.instance_method(method_name).arity != 1 + begin + klass.module_eval("def #{property_name}=(val); set_#{property_name}(val); val; end\n") + rescue SyntaxError + if $DEBUG + $stderr.puts "Couldn't create #{klass}\##{property_name}=(v)." + end + end + end + + # for Class methods/Module functions. + if klass.method(:methods).arity == -1 + method_names = klass.methods(false) + else + method_names = klass.methods + end + singleton_klass = (class << klass; self; end) + method_names.each do |method_name| + next if /\Aset_/ !~ method_name + property_name = $POSTMATCH + next if singleton_klass.method_defined?("#{property_name}=") + next if klass.method(method_name).arity != 1 + begin + klass.module_eval("def self.#{property_name}=(val); set_#{property_name}(val); val; end\n") + rescue SyntaxError + if $DEBUG + $stderr.puts "Couldn't create #{klass}.#{property_name}=(v)." + end + end + end + end + + def prepend_path_to_environment_variable(path, environment_name) + path = Pathname(path) unless path.is_a?(Pathname) + if path.exist? + separator = ::File::PATH_SEPARATOR + + paths = (ENV[environment_name] || '').split(/#{Regexp.escape(separator)}/) + dir = path.to_s + dir = dir.gsub(/\//, ::File::ALT_SEPARATOR) if ::File::ALT_SEPARATOR + unless paths.include?(dir) + paths = [dir] + paths + ENV[environment_name] = paths.join(separator) + end + end + end + + def prepend_dll_path(path) + prepend_path_to_environment_variable(path, "PATH") + end +end + + +base_dir = Pathname.new(__FILE__).dirname.dirname.expand_path +vendor_dir = base_dir + "vendor" + "local" +if vendor_dir.exist? + require "cairo" +end + +GLib.prepend_dll_path(vendor_dir + "bin") +begin + major, minor, _ = RUBY_VERSION.split(/\./) + require "#{major}.#{minor}/glib2.so" +rescue LoadError + require 'glib2.so' +end + +module GLib + module MetaInterface + class << self + def signal_callback(klass, id) + lambda do |instance, *args| + klass.instance_method(id).bind(instance).call(*args) + end + end + end + end + + class Instantiatable + private + def create_signal_handler(signal_name, callback) + callback + end + end + + class Type + + def decendants + [self] + children.map{|t| t.decendants }.flatten + end + + def ancestors + # ([self] + interfaces + (parent ? parent.ancestors : [])).reverse.uniq.reverse + [self] + (parent ? parent.ancestors : []) + end + end + + + class Enum + def _dump(limit) + Marshal.dump(to_i, limit) + end + + def self._load(obj) + new(Marshal.load(obj)) + end + end + + + class Flags + def _dump(limit) + Marshal.dump(to_i, limit) + end + + def self._load(obj) + new(Marshal.load(obj)) + end + + # FIXME + def inspect + values = self.class.values + if values.find{|x| x == self } + body = nick + else + a = values.select{|x| self >= x } + a = a.reject{|x| a.find{|y| y > x } } + body = a.empty? ? '{}' : a.map{|x| x.nick }.join('|') + end + format('#<%s %s>', self.class.inspect, body) + end + end + + module Log + DOMAIN = "Ruby/GLib" + LEVELS = { + LEVEL_ERROR => "ERROR", + LEVEL_CRITICAL => "CRITICAL", + LEVEL_WARNING => "WARNING", + LEVEL_MESSAGE => "MESSAGE", + LEVEL_INFO => "INFO", + LEVEL_DEBUG => "DEBUG" + } + + module_function + def error(str) + log(DOMAIN, LEVEL_ERROR, caller(1)[0] << ": " << str) + end + def message(str) + log(DOMAIN, LEVEL_MESSAGE, caller(1)[0] << ": " << str) + end + def critical(str) + log(DOMAIN, LEVEL_CRITICAL, caller(1)[0] << ": " << str) + end + def warning(str) + log(DOMAIN, LEVEL_WARNING, caller(1)[0] << ": " << str) + end + + def set_log_domain(domain) + level = + FLAG_RECURSION | + FLAG_FATAL | + LEVEL_ERROR | + LEVEL_CRITICAL | + LEVEL_WARNING + if $VERBOSE or $DEBUG + level |= + LEVEL_MESSAGE | + LEVEL_INFO + end + if $DEBUG + level |= LEVEL_DEBUG + end + GLib::Log.set_handler(domain, level) + end + end + + if const_defined?(:UserDirectory) + class UserDirectory + constants.each do |name| + if /\ADIRECTORY_/ =~ name + const_set($POSTMATCH, const_get(name)) + end + end + end + end + + LOG_DOMAIN = "GLib" + + class Object + LOG_DOMAIN = "GLib-GObject" + end + + class Thread + LOG_DOMAIN = "GThread" + end + + module Module + LOG_DOMAIN = "GModule" + end +end + +GLib::Log.set_log_domain(nil) +GLib::Log.set_log_domain(GLib::LOG_DOMAIN) +GLib::Log.set_log_domain(GLib::Object::LOG_DOMAIN) +GLib::Log.set_log_domain(GLib::Thread::LOG_DOMAIN) +GLib::Log.set_log_domain(GLib::Module::LOG_DOMAIN) + +require 'glib2/version' +require "glib2/regex" +=begin +Don't we need this? +ObjectSpace.define_finalizer(GLib) { + GLib::Log.cancel_handler + puts "GLib::Log.cancel_handler was called." if $DEBUG +} +=end + Added: binding/ruby/glib-3.1.1/lib/glib2/deprecatable.rb (+184 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/lib/glib2/deprecatable.rb 2017-02-15 13:19:47 +0900 (adf7eae) @@ -0,0 +1,184 @@ +# Copyright (C) 2015 Ruby-GNOME2 Project Team +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +module GLib + module Deprecatable + unless respond_to?(:define_singleton_method) + def define_singleton_method(name, &block) + singleton_class = class << self; self; end + singleton_class.__send__(:define_method, name, &block) + end + end + + @@deprecated_const = {} + def define_deprecated_const(deprecated_const, new_const = {}) + @@deprecated_const[self] ||= {} + @@deprecated_const[self][deprecated_const.to_sym] = new_const + end + + def define_deprecated_enums(enums, prefix = nil) + enums = resolve_constant_name(enums.to_s) + enums.constants.each do |const| + deprecated_const = prefix ? "#{prefix}_#{const}" : const + new_const = [enums, const].join('::') + define_deprecated_const(deprecated_const, new_const) + end + end + alias :define_deprecated_flags :define_deprecated_enums + + def define_deprecated_singleton_method(deprecated_method, new_method = {}, &block) + __define_deprecated_method__(:singleton, deprecated_method, new_method, &block) + end + + def define_deprecated_method(deprecated_method, new_method = {}, &block) + __define_deprecated_method__(:instance, deprecated_method, new_method, &block) + end + + def define_deprecated_method_by_hash_args(deprecated_method, old_args, new_args, req_argc = 0, &block) + klass = self + alias_name = "__deprecatable_#{object_id}_#{deprecated_method}__" + alias_method alias_name, deprecated_method + private alias_name + + define_method(deprecated_method) do |*margs, &mblock| + if (margs.size == req_argc) || (margs.size == (req_argc + 1) && margs.last.is_a?(Hash)) + else + margs = block.call(self, *margs, &mblock) + msg = "#{caller[0]}: '#{klass}##{deprecated_method}(#{old_args})' style has been deprecated." + warn "#{msg} Use '#{klass}##{deprecated_method}(#{new_args})' style." + end + __send__(alias_name, *margs, &mblock) + end + end + + @@deprecated_signal = {} + def define_deprecated_signal(deprecated_signal, new_signal = {}) + @@deprecated_signal[self] ||= {} + @@deprecated_signal[self][deprecated_signal.to_s.gsub('_', '-').to_sym] = new_signal + end + + def self.extended(class_or_module) + GLib::Instantiatable.class_eval do + %w(signal_connect signal_connect_after).each do |connect_method| + alias_name = "__deprecatable_#{connect_method}__" + next if private_method_defined?(alias_name) + alias_method alias_name, connect_method + private alias_name + + define_method(connect_method) do |signal, *margs, &mblock| + signal = signal.to_s.gsub('_', '-').to_sym + signals = @@deprecated_signal[self] + if new_signal = (signals || {})[signal] + msg = "#{caller[0]}: '#{signal}' signal has been deprecated." + case new_signal + when String, Symbol + warn "#{msg} Use '#{new_signal}' signal." + signal = new_signal + when Hash + if new_signal[:raise] + raise DeprecatedError.new("#{msg} #{new_signal[:raise]}") + elsif new_signal[:warn] + warn "#{msg} #{new_signal[:warn]}" + else + warn "#{msg} Don't use this signal anymore." + end + return + end + end + __send__(alias_name, signal, *margs, &mblock) + end + end + end + end + + private + + def const_missing(deprecated_const) + new_const = (@@deprecated_const[self] || {})[deprecated_const.to_sym] + if new_const.nil? + return super + end + + msg = "#{caller[0]}: '#{[name, deprecated_const].join('::')}' has been deprecated." + case new_const + when String, Symbol + new_const_val = resolve_constant_name(new_const) + case new_const_val + when GLib::Enum, GLib::Flags + alt = " or ':#{new_const_val.nick.gsub('-', '_')}'" + end + warn "#{msg} Use '#{new_const}'#{alt}." + return const_set(deprecated_const, new_const_val) + when Hash + if new_const[:raise] + raise DeprecatedError.new("#{msg} #{new_const[:raise]}") + elsif new_const[:warn] + warn "#{msg} #{new_const[:warn]}" + else + warn "#{msg} Don't use this constant anymore." + end + return + else + super + end + end + + def resolve_constant_name(name) + name.to_s.split("::").inject(nil) do |context, local_name| + if context.nil? + candidates = [] + candidate_context = ::Object + self.to_s.split("::").each do |candidate_name| + candidate = candidate_context.const_get(candidate_name) + candidates.unshift(candidate) + candidate_context = candidate + end + context = candidates.find do |candidate| + candidate.const_defined?(local_name) + end + context ||= ::Object + end + context.const_get(local_name) + end + end + + def __define_deprecated_method__(type, deprecated_method, new_method = {}, &block) + def_method = type == :singleton ? :define_singleton_method : :define_method + sep = type == :singleton ? '.' : '#' + klass = self + + __send__(def_method, deprecated_method) do |*margs, &mblock| + msg = "#{caller[0]}: '#{klass}#{sep}#{deprecated_method}' has been deprecated." + case new_method + when String, Symbol + warn "#{msg} Use '#{klass}#{sep}#{new_method}'." + __send__(new_method, *margs, &mblock) + when Hash + if new_method[:raise] + raise DeprecatedError.new("#{msg} #{new_method[:raise]}") + elsif new_method[:warn] + warn "#{msg} #{new_method[:warn]}" + block.call(self, *margs, &mblock) if block + end + end + end + end + end + + class DeprecatedError < RuntimeError + end +end + Added: binding/ruby/glib-3.1.1/lib/glib2/regex.rb (+29 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/lib/glib2/regex.rb 2017-02-15 13:19:47 +0900 (9879c3f) @@ -0,0 +1,29 @@ +# Copyright (C) 2016 Ruby-GNOME2 Project Team +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +module GLib + class Regex + class << self + def match?(pattern, string, options={}) + new(pattern, options).match(string, options).matches? + end + + def split(pattern, string, options={}) + new(pattern, options).split(string, options) + end + end + end +end Added: binding/ruby/glib-3.1.1/lib/glib2/version.rb (+37 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/lib/glib2/version.rb 2017-02-15 13:19:47 +0900 (6e03773) @@ -0,0 +1,37 @@ +# Copyright (C) 2015 Ruby-GNOME2 Project Team +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +module GLib + module Version + MAJOR = GLib::MAJOR_VERSION + MINOR = GLib::MINOR_VERSION + MICRO = GLib::MICRO_VERSION + STRING = "#{MAJOR}.#{MINOR}.#{MICRO}" + + class << self + def or_later?(major, minor, micro=nil) + micro ||= 0 + version = [ + MAJOR, + MINOR, + MICRO, + ] + (version <=> [major, minor, micro]) >= 0 + end + end + + end +end Added: binding/ruby/glib-3.1.1/lib/gnome2-raketask.rb (+8 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/lib/gnome2-raketask.rb 2017-02-15 13:19:47 +0900 (37cca50) @@ -0,0 +1,8 @@ +# Copyright(C) 2013-2015 Ruby-GNOME2 Project. +# +# This program is licenced under the same license of Ruby-GNOME2. + +# Just for backward compatibility. +require "gnome2/rake/package-task" + +GNOME2Package = GNOME2::Rake::PackageTask Added: binding/ruby/glib-3.1.1/lib/gnome2/rake/external-package.rb (+402 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/lib/gnome2/rake/external-package.rb 2017-02-15 13:19:47 +0900 (4a74ac0) @@ -0,0 +1,402 @@ +# -*- ruby -*- +# +# Copyright (C) 2013-2015 Ruby-GNOME2 Project Team +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +require "open-uri" + +module GNOME2 + module Rake + class ExternalPackage < Struct.new(:name, + :base_name, + :archive_base_name, + :label, + :version, + :download_site, + :download_base_url, + :compression_method, + :base_dir_in_package, + :windows, + :native, + :patches, + :need_autogen, + :need_autoreconf, + :build_concurrently, + :bundled_packages) + def initialize(properties) + super() + properties.each do |key, value| + send("#{key}=", value) + end + end + + def compression_method + resolve_value(super) || "gz" + end + + def base_name + resolve_value(super) || "#{name}-#{version}" + end + + def archive_base_name + resolve_value(super) || "#{base_name}.tar.#{compression_method}" + end + + def archive_url + "#{download_base_url}/#{archive_base_name}" + end + + def download_base_url + resolve_value(super) || download_site_base_url + end + + def patches + super || [] + end + + def need_autogen? + need_autogen + end + + def need_autoreconf? + need_autoreconf + end + + def base_dir_in_package + resolve_value(super) || "." + end + + def windows + super || WindowsConfiguration.new({}) + end + + def windows=(properties) + super(WindowsConfiguration.new(properties)) + end + + def native + super || NativeConfiguration.new({}) + end + + def native=(properties) + super(NativeConfiguration.new(properties)) + end + + def bundled_packages + super || [] + end + + def latest_version + case download_site + when :gnome + latest_version_gnome + when :freedesktop + latest_version_freedesktop + when :freedesktop_gstreamer + latest_version_freedesktop_gstreamer + when :webkitgtk + latest_version_webkitgtk + when :icu + latest_version_icu + else + nil + end + end + + private + def resolve_value(value) + if value.respond_to?(:call) + value.call(self) + else + value + end + end + + def download_site_base_url + case download_site + when :gnome + base_url = gnome_base_url + release_series = version.gsub(/\A(\d+\.\d+)(?:[^\d].*)?\z/, '\1') + base_url << "/#{name}/#{release_series}" + when :freedesktop + base_url = freedesktop_base_url + base_url << "/#{name}/release" + when :freedesktop_gstreamer + base_url = freedesktop_gstreamer_base_url + base_url << "/#{name}" + when :gnu + base_url = "http://ftp.gnu.org/pub/gnu/#{name}" + when :webkitgtk + base_url = webkitgtk_base_url + when :icu + base_url = "#{icu_base_url}/#{version}" + else + base_url = nil + end + base_url + end + + def gnome_base_url + "http://ftp.gnome.org/pub/gnome/sources" + end + + def freedesktop_base_url + "https://www.freedesktop.org/software" + end + + def freedesktop_gstreamer_base_url + "https://gstreamer.freedesktop.org/src" + end + + def webkitgtk_base_url + "https://webkitgtk.org/releases" + end + + def icu_base_url + "http://download.icu-project.org/files/icu4c" + end + + def sort_versions(versions) + versions.sort_by do |version| + version.split(".").collect(&:to_i) + end + end + + def latest_version_gnome + base_url = "#{gnome_base_url}/#{name}" + minor_versions = [] + open(base_url) do |index| + index.read.scan(/<a (.+?)>/) do |content,| + case content + when /href="(\d+(?:\.\d+)*)\/?"/ + minor_version = $1 + next if development_minor_version_gnome?(minor_version) + minor_versions << minor_version + end + end + end + return nil if minor_versions.empty? + + latest_minor_version = sort_versions(minor_versions).last + versions = [] + open("#{base_url}/#{latest_minor_version}") do |index| + index.read.scan(/<a (.+?)>/) do |content,| + case content + when /href="#{Regexp.escape(name)}- + (\d+(?:\.\d+)*) + \.tar\.#{Regexp.escape(compression_method)}"/x + versions << $1 + end + end + end + sort_versions(versions).last + end + + def development_minor_version_gnome?(minor_version) + minor_version.split(".").last.to_i.odd? + end + + def latest_version_freedesktop + base_url = "#{freedesktop_base_url}/#{name}/release" + versions = [] + open(base_url) do |index| + index.read.scan(/<a (.+?)>/) do |content,| + case content + when /href="#{Regexp.escape(name)}- + (\d+(?:\.\d+)*) + \.tar\.#{Regexp.escape(compression_method)}"/x + versions << $1 + end + end + end + sort_versions(versions).last + end + + def latest_version_freedesktop_gstreamer + base_url = "#{freedesktop_gstreamer_base_url}/#{name}" + versions = [] + open(base_url) do |index| + index.read.scan(/<a (.+?)>/) do |content,| + case content + when /href="#{Regexp.escape(name)}- + (\d+(?:\.\d+)*) + \.tar\.#{Regexp.escape(compression_method)}"/x + version = $1 + next if development_version_freedesktop_gstreamer?(version) + versions << version + end + end + end + sort_versions(versions).last + end + + def development_version_freedesktop_gstreamer?(version) + version.split(".")[1].to_i.odd? + end + + def latest_version_webkitgtk + base_url = webkitgtk_base_url + versions = [] + open(base_url) do |index| + index.read.scan(/<a (.+?)>/) do |content,| + case content + when /href="#{Regexp.escape(name)}- + (\d+(?:\.\d+)*) + \.tar\.#{Regexp.escape(compression_method)}"/x + versions << $1 + end + end + end + sort_versions(versions).last + end + + def latest_version_icu + base_url = icu_base_url + versions = [] + open(base_url) do |index| + index.read.scan(/<a (.+?)>/) do |content,| + case content + when /href="(\d+(?:\.\d+)+)\/"/x + versions << $1 + end + end + end + sort_versions(versions).last + end + + class WindowsConfiguration < Struct.new(:build, + :include_paths, + :library_paths, + :configure_args, + :cmake_args, + :cc_args, + :patches, + :built_file, + :need_autogen, + :need_autoreconf, + :build_concurrently, + :use_cc_environment_variable, + :gobject_introspection_compiler_split_args, + :use_gobject_introspection) + def initialize(properties) + super() + properties.each do |key, value| + send("#{key}=", value) + end + end + + def build? + build.nil? ? true : build + end + + def include_paths + super || [] + end + + def library_paths + super || [] + end + + def configure_args + super || [] + end + + def cmake_args + super || [] + end + + def cc_args + super || [] + end + + def patches + super || [] + end + + def built_file + super || nil + end + + def need_autogen? + need_autogen.nil? ? false : need_autogen + end + + def need_autoreconf? + need_autoreconf.nil? ? false : need_autoreconf + end + + def build_concurrently? + build_concurrently.nil? ? true : build_concurrently + end + + def use_cc_environment_variable? + use_cc_environment_variable.nil? ? true : use_cc_environment_variable + end + + def gobject_introspection_compiler_split_args? + gobject_introspection_compiler_split_args + end + + def use_gobject_introspection? + use_gobject_introspection.nil? ? true : use_gobject_introspection + end + end + + class NativeConfiguration < Struct.new(:build, + :configure_args, + :patches, + :built_file, + :need_autogen, + :need_autoreconf, + :build_concurrently) + def initialize(properties) + super() + properties.each do |key, value| + send("#{key}=", value) + end + end + + def build? + build.nil? ? false : build + end + + def configure_args + super || [] + end + + def patches + super || [] + end + + def built_file + super || nil + end + + def need_autogen? + need_autogen.nil? ? false : need_autogen + end + + def need_autoreconf? + need_autoreconf.nil? ? false : need_autoreconf + end + + def build_concurrently? + build_concurrently.nil? ? true : build_concurrently + end + end + end + end +end Added: binding/ruby/glib-3.1.1/lib/gnome2/rake/native-binary-build-task.rb (+129 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/lib/gnome2/rake/native-binary-build-task.rb 2017-02-15 13:19:47 +0900 (bcd11a0) @@ -0,0 +1,129 @@ +# -*- ruby -*- +# +# Copyright (C) 2013-2015 Ruby-GNOME2 Project Team +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +require "rake" + +module GNOME2 + module Rake + class NativeBinaryBuildTask + include ::Rake::DSL + + def initialize(package) + @package = package + end + + def define + namespace :native do + namespace :builder do + task :before + define_build_tasks + build_tasks = build_packages.collect do |package| + "native:builder:build:#{package.name}" + end + task :build => build_tasks + task :after + end + + desc "Build binaries for build environment" + task :build => [ + "native:builder:before", + "native:builder:build", + "native:builder:after", + ] + end + end + + private + def define_build_tasks + namespace :build do + build_packages.each do |package| + namespace package.name do + download_task = "source:downloader:download:#{package.name}" + built_file = package.native.built_file + if built_file + built_file = dist_dir + built_file + file built_file.to_s do + ::Rake::Task[download_task].invoke + build_package_task_body(package) + end + task :build => built_file.to_s + else + task :build => [download_task] do + build_package_task_body(package) + end + end + end + desc "Build #{package.label} and install it into #{dist_dir}." + task package.name => "native:builder:build:#{package.name}:build" + end + end + end + + def build_package_task_body(package) + package_tmp_dir =****@packa*****_dir + "native" + package.name + rm_rf(package_tmp_dir) + mkdir_p(package_tmp_dir) + + tar_full_path =****@packa*****_dir + package.archive_base_name + Dir.chdir(package_tmp_dir.to_s) do + sh("tar", "xf", tar_full_path.to_s) or exit(false) + end + + package_dir_path = + package_tmp_dir + package.base_name + package.base_dir_in_package + Dir.chdir(package_dir_path.to_s) do + package.native.patches.each do |patch| + sh("patch -p1 < #{@package.patches_dir}/#{patch}") + end + sh("./autogen.sh") if package.native.need_autogen? + sh("autoreconf --install") if package.native.need_autoreconf? + sh("./configure", + "PKG_CONFIG_PATH=#{pkg_config_path}", + "--prefix=#{dist_dir}", + *package.native.configure_args) or exit(false) + env = [] + env << "PKG_CONFIG_PATH=#{pkg_config_path}" + common_make_args = [] + common_make_args << "GLIB_COMPILE_SCHEMAS=glib-compile-schemas" + build_make_args = common_make_args.dup + install_make_args = common_make_args.dup + if package.native.build_concurrently? + make_n_jobs = ENV["MAKE_N_JOBS"] + build_make_args << "-j#{make_n_jobs}" if make_n_jobs + end + sh("env", *env, "nice", "make", *build_make_args) or exit(false) + sh("env", *env, "make", "install", *install_make_args) or exit(false) + end + end + + def build_packages + @package.external_packages.select do |package| + package.native.build? + end + end + + def dist_dir + @package.native.absolute_binary_dir + end + + def pkg_config_path + dist_dir + "lib/pkgconfig" + end + end + end +end Added: binding/ruby/glib-3.1.1/lib/gnome2/rake/package-task.rb (+333 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/lib/gnome2/rake/package-task.rb 2017-02-15 13:19:47 +0900 (e4d0e5e) @@ -0,0 +1,333 @@ +# coding: utf-8 + +# Copyright(C) 2011-2015 Ruby-GNOME2 Project. +# +# This program is licenced under the same license of Ruby-GNOME2. + +require "find" +require "pathname" + +require "rubygems" +require "rubygems/package_task" +require "rake/extensiontask" +require "gnome2/rake/package" +require "gnome2/rake/external-package" +require "gnome2/rake/source-download-task" +require "gnome2/rake/native-binary-build-task" +require "gnome2/rake/windows-binary-download-task" +require "gnome2/rake/windows-binary-build-task" + +module GNOME2 + module Rake + class PackageTask + include ::Rake::DSL + + attr_accessor :name, :summary, :description, :author, :email, :homepage, :required_ruby_version, :post_install_message + attr_reader :root_dir + def initialize + initialize_variables + initialize_configurations + file, line, method = caller[1].scan(/^(.*):(\d+)(?::.*`(.*)')?\Z/).first + @package = Package.new(File.dirname(file)) + @packages = FileList["#{@package.root_dir.parent}/*"].map{|f| File.directory?(f) ? File.basename(f) : nil}.compact + @name =****@packa***** + @cross_compiling_hooks = [] + yield(self) if block_given? + end + + def cross_compiling(&block) + @cross_compiling_hooks << block + end + + def define + task :default => :build + define_spec + define_source_tasks + define_native_tasks + define_windows_tasks + define_package_tasks + end + + # Deprecated. Use #define instead. + def define_tasks + define + end + + def ruby_gnome2_package?(name) + @packages.include?(name) + end + + def dependency + @dependency_configuration + end + + def package + @package + end + + def windows + @package.windows + end + + def native + @package.native + end + + def version + ENV["VERSION"] || guess_version + end + + def guess_version + versions = {} + File.open("#{@package.glib2_root_dir}/ext/glib2/rbglib.h") do |rbglib_h| + rbglib_h.each_line do |line| + if /#define\s+RBGLIB_([A-Z]+)_VERSION\s+(\d+)/ =~ line + versions[$1.downcase] = $2.to_i + end + end + end + ["major", "minor", "micro"].collect {|type| versions[type]}.compact.join(".") + end + + def external_packages=(packages) + @package.external_packages = packages + end + + def windows_binary_build_task + @windows_binary_build_task ||= WindowsBinaryBuildTask.new(@package) + end + + private + def initialize_variables + @summary = "" + @description = "" + @author = "The Ruby-GNOME2 Project Team" + @email = "ruby-****@lists*****" + @homepage = "http://ruby-gnome2.sourceforge.jp/" + @external_packages = [] + end + + def initialize_configurations + @dependency_configuration = DependencyConfiguration.new(self) + end + + def cross_platform + "#{windows.build_architecture}-mingw32" + end + + def define_spec + @spec = Gem::Specification.new do |s| + s.name = @name + s.summary = @summary + s.description = @description + s.author = @author + s.email = @email + s.homepage = @homepage + s.licenses = ["LGPLv2.1+"] + s.version = version + extensions = FileList["ext/#{@name}/extconf.rb"] + extensions.existing! + s.extensions = extensions + s.require_paths = ["lib"] + files = FileList["ChangeLog", "README", + "Rakefile", "extconf.rb", + "lib/**/*.rb", + "ext/**/depend", + "ext/**/*.{c,h,def,rb}", + "{sample,test}/**/*"] + files.existing! + s.files = files + s.required_ruby_version = @required_ruby_version || ">= 2.1.0" + s.post_install_message = @post_install_message + @dependency_configuration.apply(s) + end + end + + def define_source_tasks + define_source_download_tasks + end + + def define_source_download_tasks + task = SourceDownloadTask.new(@package) + task.define + end + + def define_native_tasks + define_native_build_tasks + end + + def define_native_build_tasks + task = NativeBinaryBuildTask.new(@package) + task.define + end + + def define_windows_tasks + define_windows_extension_task + define_windows_download_task + define_windows_build_task + define_windows_version_update_task + end + + def so_base_name + @name.gsub(/-/, "_") + end + + def define_windows_extension_task + ::Rake::ExtensionTask.new(so_base_name, @spec) do |ext| + ext.cross_platform = cross_platform + ext.ext_dir = "ext/#{@name}" + ext.cross_compile = true + ext.cross_compiling do |spec| + if /mingw|mswin/ =~ spec.platform.to_s + windows_binary_dir =****@packa*****_binary_dir + windows_files = [] + if windows_binary_dir.exist? + Find.find(windows_binary_dir.to_s) do |path| + next unless File.file?(path) + next if /\.zip\z/ =~ path + windows_files << path + end + end + spec.files += windows_files + stage_path = "#{ext.tmp_dir}/#{ext.cross_platform}/stage" + windows_files.each do |windows_file| + stage_windows_file = "#{stage_path}/#{windows_file}" + stage_windows_binary_dir = File.dirname(stage_windows_file) + directory stage_windows_binary_dir + stage_windows_file_dependencies = [ + stage_windows_binary_dir, + windows_file, + ] + file stage_windows_file => stage_windows_file_dependencies do + cp windows_file, stage_windows_file + end + end + end + @cross_compiling_hooks.each do |hook| + hook.call(spec) + end + end + end + + extconf_rb = "ext/#{@name}/extconf.rb" + unless File.exist?(extconf_rb) + native_task_name = "native:#{@name}:#{cross_platform}" + if ::Rake::Task.task_defined?(native_task_name) + ::Rake::Task[native_task_name].prerequisites.clear + end + end + end + + def define_windows_download_task + task = WindowsBinaryDownloadTask.new(@package) + task.define + end + + def define_windows_build_task + windows_binary_build_task.define + end + + def define_windows_version_update_task + namespace :windows do + namespace :version do + task_names = [] + namespace :update do + @package.external_packages.each do |package| + task_names << package.name + task package.name do + latest_version = package.latest_version || package.version + if package.version != latest_version + update_package_version(package, latest_version) + end + end + end + end + + full_task_names = task_names.collect do |name| + "windows:version:update:#{name}" + end + desc "Update Windows package versions" + task :update => full_task_names + end + end + end + + def update_package_version(package, latest_version) + rakefile_path = ::Rake.application.rakefile + rakefile_content = File.read(rakefile_path) + updated_rakefile_content = "" + in_package = false + escaped_name = Regexp.escape(package.name) + escaped_version = Regexp.escape(package.version) + rakefile_content.each_line do |line| + case line + when /:name => "#{escaped_name}",/ + in_package = true + updated_rakefile_content << line + when /:version => "#{escaped_version}",/ + if in_package + updated_rakefile_content << line.gsub(/#{escaped_version}/, + latest_version) + in_package = false + else + updated_rakefile_content << line + end + else + updated_rakefile_content << line + end + end + File.open(rakefile_path, "w") do |rakefile| + rakefile.write(updated_rakefile_content) + end + end + + def define_package_tasks + Gem::PackageTask.new(@spec) do |pkg| + end + end + + class DependencyConfiguration + attr_accessor :platform, :ruby + def initialize(package) + @package = package + @platform = Gem::Platform::RUBY + @gem_configuration = GemConfiguration.new(@package) + end + + def gem + @gem_configuration + end + + def apply(spec) + spec.platform = @platform + @gem_configuration.apply(spec) + end + + class GemConfiguration + attr_accessor :runtime, :development + def initialize(package) + @package = package + @runtime = [] + @development = [] + end + + def apply(spec) + @runtime.each do |dependency| + spec.add_runtime_dependency(*append_version(dependency)) + end + + @development.each do |dependency| + spec.add_development_dependency(*append_version(dependency)) + end + end + + def append_version(dependency) + name, *ver = dependency.is_a?(Array) ? dependency : [dependency] + ver << "= #{@package.version}" if****@packa*****_gnome2_package?(name) + [name, *ver] + end + end + end + end + end +end Added: binding/ruby/glib-3.1.1/lib/gnome2/rake/package.rb (+161 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/lib/gnome2/rake/package.rb 2017-02-15 13:19:47 +0900 (f969c59) @@ -0,0 +1,161 @@ +# -*- ruby -*- +# +# Copyright (C) 2013-2015 Ruby-GNOME2 Project Team +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +require "pathname" + +module GNOME2 + module Rake + class Package + attr_reader :name + attr_reader :root_dir + attr_reader :windows + attr_reader :native + attr_writer :external_packages + def initialize(root_dir) + @root_dir = Pathname.new(root_dir).expand_path + @name = @root_dir.basename.to_s + @windows = WindowsConfiguration.new + @native = NativeConfiguration.new + @external_packages = [] + end + + def project_root_dir + @root_dir.parent + end + + def glib2_root_dir + project_root_dir + "glib2" + end + + def tmp_dir + @root_dir + "tmp" + end + + def download_dir + tmp_dir + "download" + end + + def patches_dir + @root_dir + "patches" + end + + def external_packages + @external_packages.collect do |package| + ExternalPackage.new(package) + end + end + + class WindowsConfiguration < Struct.new(:packages, + :dependencies, + :build_dependencies, + :gobject_introspection_dependencies, + :build_packages, + :build_host) + + attr_reader :relative_binary_dir, :absolute_binary_dir + def initialize + super + @relative_binary_dir = Pathname.new("vendor/local") + @absolute_binary_dir = @relative_binary_dir.expand_path + end + + def packages + super || [] + end + + def dependencies + super || [] + end + + def build_dependencies + super || [] + end + + def gobject_introspection_dependencies + super || [] + end + + def build_packages + (super || []).collect do |package| + package = package.dup + package[:windows] = { + :include_paths => package.delete(:include_paths), + :library_paths => package.delete(:library_paths), + :configure_args => package.delete(:configure_args), + :patches => package.delete(:patches), + :need_autogen => package.delete(:need_autogen), + :need_autoreconf => package.delete(:need_autoreconf), + } + ExternalPackage.new(package) + end + end + + def build_host + super || guess_build_host + end + + def guess_build_host + ENV["RUBY_GNOME2_BUILD_HOST"] || + guess_build_host_from_architecture || + "i686-w64-mingw32" + end + + def guess_build_host_from_architecture + case build_architecture + when "x86" + "i686-w64-mingw32" + when "x64" + "x86_64-w64-mingw32" + else + nil + end + end + + def build_arch + case build_architecture + when "x86" + "i686" + when "x64" + "x86_64" + end + end + + def build_architecture + ENV["RUBY_GNOME2_BUILD_ARCHITECTURE"] || "x86" + end + + def build_architecture_suffix + case build_architecture + when "x86" + "win32" + when "x64" + "win64" + end + end + end + + class NativeConfiguration + attr_reader :relative_binary_dir, :absolute_binary_dir + def initialize + @relative_binary_dir = Pathname.new("tmp/native/local") + @absolute_binary_dir = @relative_binary_dir.expand_path + end + end + end + end +end Added: binding/ruby/glib-3.1.1/lib/gnome2/rake/source-download-task.rb (+102 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/lib/gnome2/rake/source-download-task.rb 2017-02-15 13:19:47 +0900 (0cf4c12) @@ -0,0 +1,102 @@ +# -*- ruby -*- +# +# Copyright (C) 2013-2015 Ruby-GNOME2 Project Team +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +require "open-uri" +require "pathname" + +require "rake" + +module GNOME2 + module Rake + class SourceDownloadTask + include ::Rake::DSL + + def initialize(package) + @package = package + end + + def define + namespace :source do + namespace :downloader do + task :before + define_download_tasks + download_tasks =****@packa*****_packages.collect do |package| + "source:downloader:download:#{package.name}" + end + task :download => download_tasks + task :after + end + + desc "Dowanload sources" + task :download => [ + "source:downloader:before", + "source:downloader:download", + "source:downloader:after", + ] + end + end + + private + def define_download_tasks + namespace :download do + @package.external_packages.each do |package| + download_dir =****@packa*****_dir + tar_full_path = download_dir + package.archive_base_name + + task :before + task :after + desc "Download #{package.label} into #{download_dir}." + # task package[:name] => [:before, tar_full_path.to_s, :after] + task package[:name] => tar_full_path.to_s + + directory_path = tar_full_path.dirname + directory directory_path.to_s + file tar_full_path.to_s => directory_path.to_s do + archive_url = package.archive_url + rake_output_message "Downloading... #{archive_url}" + download(archive_url, tar_full_path) + end + end + end + end + + def download(url, output_path) + OpenURI.singleton_class.class_eval do + alias_method :redirectable_original?, :redirectable? + def redirectable?(uri1, uri2) + redirectable_original?(uri1, uri2) or + (uri1.scheme.downcase == "http" and + uri2.scheme.downcase == "https") + end + end + begin + open(url) do |input| + output_path.open("wb") do |output_file| + output_file.print(input.read) + end + end + ensure + OpenURI.singleton_class.class_eval do + alias_method :redirectable?, :redirectable_original? + remove_method :redirectable_original? + end + end + end + end + end +end Added: binding/ruby/glib-3.1.1/lib/gnome2/rake/windows-binary-build-task.rb (+351 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/lib/gnome2/rake/windows-binary-build-task.rb 2017-02-15 13:19:47 +0900 (17dd700) @@ -0,0 +1,351 @@ +# Copyright(C) 2012-2015 Ruby-GNOME2 Project. +# +# This program is licenced under the same license of Ruby-GNOME2. + +require "open-uri" +require "pathname" + +module GNOME2 + module Rake + class WindowsBinaryBuildTask + include ::Rake::DSL + + def initialize(package) + @package = package + end + + def define + namespace :windows do + namespace :builder do + task :before + define_build_tasks + build_tasks = build_packages.collect do |package| + "windows:builder:build:#{package.name}" + end + task :build => build_tasks + task :after + end + desc "Build Windows binaries" + task :build => ["windows:builder:before", + "windows:builder:build", + "windows:builder:after"] + end + end + + def rcairo_binary_base_dir + rcairo_dir + "vendor" + "local" + end + + def glib2_binary_base_dir + @package.glib2_root_dir + "vendor" + "local" + end + + def binary_base_dir(package) + @package.project_root_dir + package + "vendor" + "local" + end + + private + def define_build_tasks + namespace :build do + prepare_task_names = [] + namespace :prepare do + prepare_task_names << "pkg_config" + task :pkg_config do + depended_packages =****@packa*****_dependencies + use_packages = [@package.name] + depended_packages + pkg_config_path = use_packages.collect do |package| + "../#{package}/#{@package.windows.relative_binary_dir}/lib/pkgconfig" + end + ENV["PKG_CONFIG_PATH"] = pkg_config_path.collect do |path| + File.expand_path(path) + end.join(":") + ENV["PKG_CONFIG_LIBDIR"] = rcairo_pkgconfig_path + end + + prepare_task_names << "pkg_config_for_build" + task :pkg_config_for_build do + # XXX: Is it needless? + # ENV["PKG_CONFIG_FOR_BUILD"] = "env - pkg-config" + end + end + + full_prepare_task_names = prepare_task_names.collect do |name| + "windows:builder:build:prepare:#{name}" + end + task :prepare => full_prepare_task_names + + build_packages.each do |package| + namespace package.name do + task :before + download_task = "source:downloader:download:#{package.name}" + built_file = package.windows.built_file + if built_file + built_file = dist_dir + built_file + file built_file.to_s do + ::Rake::Task["windows:builder:build:prepare"].invoke + ::Rake::Task[download_task].invoke + build_package_task_body(package) + end + task :build => built_file.to_s + else + task :build => [:prepare, download_task] do + build_package_task_body(package) + end + end + task :after + end + + prefix = "windows:builder:build:#{package.name}" + desc "Build #{package.label} and install it into #{dist_dir}." + task package.name => [ + "#{prefix}:before", + "#{prefix}:build", + "#{prefix}:after", + ] + end + end + end + + def build_package_task_body(package) + package_tmp_dir =****@packa*****_dir + "windows" + package.name + rm_rf(package_tmp_dir) + mkdir_p(package_tmp_dir) + + tar_full_path =****@packa*****_dir + package.archive_base_name + Dir.chdir(package_tmp_dir.to_s) do + sh("tar", "xf", tar_full_path.to_s) + end + + package_dir_path = + package_tmp_dir + package.base_name + package.base_dir_in_package + Dir.chdir(package_dir_path.to_s) do + package.windows.patches.each do |patch| + sh("patch -p1 < #{@package.patches_dir}/#{patch}") + end + if File.exist?("configure") + configure(package) + else + cmake(package) + end + common_make_args = [] + common_make_args << "MAKE=make" + common_make_args << "GLIB_COMPILE_SCHEMAS=glib-compile-schemas" + if package.windows.use_cc_environment_variable? + common_make_args << cc_env(package) + end + add_gobject_introspection_make_args(package, common_make_args) + build_make_args = common_make_args.dup + install_make_args = common_make_args.dup + if package.windows.build_concurrently? + make_n_jobs = ENV["MAKE_N_JOBS"] + build_make_args << "-j#{make_n_jobs}" if make_n_jobs + end + ENV["GREP_OPTIONS"] = "--text" + # ENV["GI_SCANNER_DEBUG"] = "save-temps" + # build_make_args << "--debug" + # build_make_args << "V=1" + # build_make_args << "VERBOSE=1" + sh("nice", "make", *build_make_args) or exit(false) + sh("make", "install", *install_make_args) or exit(false) + + package_license_dir = license_dir + package.name + mkdir_p(package_license_dir) + package_license_files = ["AUTHORS", "COPYING", "COPYING.LIB"] + package_license_files = package_license_files.reject do |file| + not File.exist?(file) + end + cp(package_license_files, package_license_dir) + bundled_packages = package.bundled_packages + bundled_packages.each do |bundled_package| + bundled_package_license_dir = license_dir + bundled_package[:name] + mkdir_p(bundled_package_license_dir) + license_files = bundled_package[:license_files].collect do |file| + File.join(bundled_package[:path], file) + end + cp(license_files, bundled_package_license_dir) + end + end + end + + def configure(package) + sh("./autogen.sh") if package.windows.need_autogen? + sh("autoreconf", "--install", "--force") if package.windows.need_autoreconf? + sh("./configure", + cc_env(package), + dlltool_env, + "CPPFLAGS=#{cppflags(package)}", + "LDFLAGS=#{ldflags(package)}", + "--prefix=#{dist_dir}", + "--host=#{@package.windows.build_host}", + *package.windows.configure_args) or exit(false) + end + + def cmake(package) + sh("cmake", + ".", + "-DCMAKE_INSTALL_PREFIX=#{dist_dir}", + "-DCMAKE_SYSTEM_NAME=Windows", + "-DCMAKE_SYSTEM_PROCESSOR=#{@package.windows.build_architecture}", + "-DCMAKE_C_COMPILER=#{cc(package)}", + "-DCMAKE_CXX_COMPILER=#{cxx(package)}", + *package.windows.cmake_args) or exit(false) + end + + def cc_env(package) + "CC=#{cc(package)}" + end + + def dlltool_env + "DLLTOOL=#{dlltool}" + end + + def build_packages + packages =****@packa*****_packages.select do |package| + package.windows.build? + end + # For backward compatibility + packages +****@packa*****_packages + end + + def dist_dir + @package.windows.absolute_binary_dir + end + + def license_dir + dist_dir + "share" + "license" + end + + def glib2_include_path + "#{glib2_binary_base_dir}/include" + end + + def glib2_lib_path + "#{glib2_binary_base_dir}/lib" + end + + def rcairo_dir + suffix =****@packa*****_architecture_suffix + @package.project_root_dir.parent + "rcairo.#{suffix}" + end + + def rcairo_pkgconfig_path + "#{rcairo_binary_base_dir}/lib/pkgconfig" + end + + def rcairo_include_path + "#{rcairo_binary_base_dir}/include" + end + + def rcairo_lib_path + "#{rcairo_binary_base_dir}/lib" + end + + def cc(package) + cc_command_line = [ + "#{@package.windows.build_host}-gcc", + *package.windows.cc_args, + ] + cc_command_line.compact.join(" ") + end + + def cxx(package) + cxx_command_line = [ + "#{@package.windows.build_host}-g++", + ] + cxx_command_line.compact.join(" ") + end + + def dlltool + "#{@package.windows.build_host}-dlltool" + end + + def cppflags(package) + include_paths = package.windows.include_paths + if****@packa*****_dependencies.include?("glib2") + include_paths += [glib2_include_path] + end + include_paths += [ + rcairo_include_path, + dist_dir + 'include', + ] + cppflags = include_paths.collect do |path| + "-I#{path}" + end + cppflags.join(" ") + end + + def ldflags(package) + library_paths = package.windows.library_paths + if****@packa*****_dependencies.include?("glib2") + library_paths += [glib2_lib_path] + end + library_paths += [ + rcairo_lib_path, + dist_dir + 'lib', + ] + ldflags = library_paths.collect do |path| + "-L#{path}" + end + ldflags.join(" ") + end + + def cmake_root_paths + paths = [ + "/usr/#{@package.windows.build_host}", + rcairo_binary_base_dir.to_path, + ] + @package.windows.build_dependencies.each do |package| + paths << binary_base_dir(package).to_path + end + paths + end + + def add_gobject_introspection_make_args(package, common_make_args) + return unless use_gobject_introspection?(package) + + g_ir_scanner = "#{@package.project_root_dir}/gobject-introspection/" + g_ir_scanner << "#{@package.native.relative_binary_dir}/bin/g-ir-scanner" + introspection_scanner = "INTROSPECTION_SCANNER=#{g_ir_scanner}" + common_make_args << introspection_scanner + + + dependencies = [ + "gobject-introspection", + @package.name, + ] + dependencies +=****@packa*****_introspection_dependencies + + gi_base_dir = binary_base_dir("gobject-introspection") + introspection_compiler = "INTROSPECTION_COMPILER=" + introspection_compiler << "#{gi_base_dir}/bin/g-ir-compiler.exe" + introspection_compiler_args = "" + dependencies.each do |dependent_package| + gir_dir = "#{binary_base_dir(dependent_package)}/share/gir-1.0" + introspection_compiler_args << " --includedir=#{gir_dir}" + end + if package.windows.gobject_introspection_compiler_split_args? + common_make_args << introspection_compiler + common_make_args << + "INTROSPECTION_COMPILER_ARGS=#{introspection_compiler_args}" + common_make_args << + "INTROSPECTION_COMPILER_OPTS=#{introspection_compiler_args}" + else + introspection_compiler << " #{introspection_compiler_args}" + common_make_args << introspection_compiler + end + + common_make_args << dlltool_env + + data_dirs = dependencies.collect do |dependent_package| + "#{binary_base_dir(dependent_package)}/share" + end + common_make_args << "XDG_DATA_DIRS=#{data_dirs.join(File::PATH_SEPARATOR)}" + end + + def use_gobject_introspection?(package) + return false unless package.windows.use_gobject_introspection? + @package.windows.build_dependencies.include?("gobject-introspection") + end + end + end +end Added: binding/ruby/glib-3.1.1/lib/gnome2/rake/windows-binary-download-task.rb (+184 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/lib/gnome2/rake/windows-binary-download-task.rb 2017-02-15 13:19:47 +0900 (418bb5f) @@ -0,0 +1,184 @@ +# Copyright(C) 2010-2015 Ruby-GNOME2 Project. +# +# This program is licenced under the same license of Ruby-GNOME2. + +require 'open-uri' +require 'rubygems' +require 'mechanize' + +module GNOME2 + module Rake + class WindowsBinaryDownloadTask + include ::Rake::DSL + + URL_BASE = "http://ftp.gnome.org/pub/gnome/binaries" + def initialize(package) + @package = package + end + + def define + namespace :windows do + namespace :downloader do + task :before + + download_tasks = [] + namespace :download do + directory dist_dir.to_s + task :prepare => [dist_dir.to_s] + + packages.each do |package| + desc "download #{package}" + task package => [:prepare] do + download_package(package) + end + download_tasks << package + end + + dependencies.each do |dependency| + name, version = dependency + desc "download #{name}" + task name => [:prepare] do + download_dependency(dependency) + end + download_tasks << name + end + end + + download_tasks = download_tasks.collect do |task| + "windows:downloader:download:#{task}" + end + desc "download Windows binaries into #{dist_dir}" + task :download => download_tasks + + task :after + end + desc "download Windows binaries" + task :download => ["windows:downloader:before", + "windows:downloader:download", + "windows:downloader:after"] + end + end + + private + def dist_dir + @package.windows.absolute_binary_dir + end + + def packages + @package.windows.packages + end + + def dependencies + @package.windows.dependencies + end + + def build_architecture_suffix + @package.windows.build_architecture_suffix + end + + def download_package(package) + suffix = build_architecture_suffix + version_page_url = "#{URL_BASE}/#{suffix}/#{package}" + version_page = agent.get(version_page_url) + latest_version_link = version_page.links.sort_by do |link| + if /\A(\d+\.\d+)\/\z/ =~ link.href + $1.split(/\./).collect {|component| component.to_i} + else + [-1] + end + end.last + + escaped_package = Regexp.escape(package) + latest_version_page = latest_version_link.click + latest_version = latest_version_page.links.collect do |link| + case link.href + when /#{escaped_package}_([\d\.\-]+)_#{suffix}\.zip\z/, + /#{escaped_package}-([\d\.\-]+)-#{suffix}\.zip\z/, # old + /#{escaped_package}-([\d\.\-]+)\.zip\z/ # old + version = $1 + normalized_version = version.split(/[\.\-]/).collect do |component| + component.to_i + end + [normalized_version, version] + else + [[-1], nil] + end + end.sort_by do |normalized_version, version| + normalized_version + end.last[1] + + if latest_version.nil? + raise "can't find package: <#{package}>:<#{version_page_url}>" + end + escaped_latest_version = Regexp.escape(latest_version) + latest_version_page.links.each do |link| + case link.href + when /#{escaped_package}(?:-dev)?_#{escaped_latest_version}_#{suffix}\.zip\z/, + /#{escaped_package}(?:-dev)?-#{escaped_latest_version}-#{suffix}\.zip\z/, # old + /#{escaped_package}(?:-dev)?-#{escaped_latest_version}\.zip\z/ # old + click_zip_link(link) + end + end + end + + def download_dependency(dependency) + suffix = build_architecture_suffix + dependency_version = "any" + dependency_version_re = /[\d\.\-]+/ + if dependency.is_a?(Array) + dependency, dependency_version = dependency + dependency_version_re = /#{Regexp.escape(dependency_version)}/ + end + escaped_dependency = Regexp.escape(dependency) + dependencies_url = "#{URL_BASE}/dependencies" + dependencies_page = agent.get(dependencies_url) + latest_version = dependencies_page.links.collect do |link| + case link.href + when /\A#{escaped_dependency}_(#{dependency_version_re})_#{suffix}\.zip\z/ + version = $1 + [version.split(/[\.\-]/).collect {|component| component.to_i}, version] + else + [[-1], nil] + end + end.sort_by do |normalized_version, version| + normalized_version + end.last[1] + + if latest_version.nil? + message = "can't find dependency package: " + + "<#{dependency}>(#{dependency_version}):<#{dependencies_url}>" + raise message + end + escaped_latest_version = Regexp.escape(latest_version) + dependencies_page.links.each do |link| + case link.href + when /\A#{escaped_dependency}(?:-dev)?_#{escaped_latest_version}_#{suffix}\.zip\z/ + click_zip_link(link) + end + end + end + + private + def agent + @agent ||= Mechanize.new + end + + def click_zip_link(link) + zip = link.click + Dir.chdir(dist_dir) do + open(zip.filename, "wb") do |file| + file.print(zip.body) + end + system("unzip", "-o", zip.filename) + Dir.glob("lib/pkgconfig/*.pc") do |pc_path| + pc = File.read(pc_path) + pc = pc.gsub(/\Aprefix=.+$/) {"prefix=#{dist_dir}"} + File.open(pc_path, "w") do |pc_file| + pc_file.print(pc) + end + end + end + end + end + end +end Added: binding/ruby/glib-3.1.1/lib/mkmf-gnome2.rb (+618 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/lib/mkmf-gnome2.rb 2017-02-15 13:19:47 +0900 (d74b1ea) @@ -0,0 +1,618 @@ +# +# mkmf-gnome2.rb +# +# Extended mkmf for Ruby-GNOME2 and Ruby/GLib based libraries. +# +# Copyright(C) 2003-2015 Ruby-GNOME2 Project. +# +# This program is licenced under the same +# license of Ruby-GNOME2. +# + +require 'English' +require 'mkmf' +require 'pkg-config' +require 'glib-mkenums' + +$CFLAGS += " #{ENV['CFLAGS']}" if ENV['CFLAGS'] + +def gcc? + CONFIG["GCC"] == "yes" +end + +def disable_optimization_build_flag(flags) + if gcc? + flags.gsub(/(^|\s)?-O\d(\s|$)?/, '\\1-O0\\2') + else + flags + end +end + +def enable_debug_build_flag(flags) + if gcc? + debug_option_pattern = /(^|\s)-g\d?(\s|$)/ + if debug_option_pattern =~ flags + flags.gsub(debug_option_pattern, '\\1-g3\\2') + else + flags + " -g3" + end + else + flags + end +end + +checking_for(checking_message("--enable-debug-build option")) do + enable_debug_build = enable_config("debug-build", false) + if enable_debug_build + $CFLAGS = disable_optimization_build_flag($CFLAGS) + $CFLAGS = enable_debug_build_flag($CFLAGS) + + CONFIG["CXXFLAGS"] = disable_optimization_build_flag(CONFIG["CXXFLAGS"]) + CONFIG["CXXFLAGS"] = enable_debug_build_flag(CONFIG["CXXFLAGS"]) + end + enable_debug_build +end + +def try_compiler_option(opt, &block) + checking_for "#{opt} option to compiler" do + if try_compile '', opt + " -Werror", &block + $CFLAGS += " #{opt}" + true + else + false + end + end +end + +try_compiler_option '-Wall' +try_compiler_option '-Waggregate-return' +try_compiler_option '-Wcast-align' +# NOTE: Generates way too many false positives. +# try_compiler_option '-Wconversion' +try_compiler_option '-Wextra' +try_compiler_option '-Wformat=2' +try_compiler_option '-Winit-self' +# NOTE: This generates warnings for functions defined in ruby.h. +# try_compiler_option '-Winline' +try_compiler_option '-Wlarger-than-65500' +try_compiler_option '-Wmissing-declarations' +try_compiler_option '-Wmissing-format-attribute' +try_compiler_option '-Wmissing-include-dirs' +try_compiler_option '-Wmissing-noreturn' +try_compiler_option '-Wmissing-prototypes' +try_compiler_option '-Wnested-externs' +try_compiler_option '-Wold-style-definition' +try_compiler_option '-Wpacked' +try_compiler_option '-Wp,-D_FORTIFY_SOURCE=2' +try_compiler_option '-Wpointer-arith' +# NOTE: ruby.h and intern.h have too many of these. +# try_compiler_option '-Wredundant-decls' +# NOTE: Complains about index, for example. +# try_compiler_option '-Wshadow' +try_compiler_option '-Wswitch-default' +try_compiler_option '-Wswitch-enum' +try_compiler_option '-Wundef' +# NOTE: Incredible amounts of false positives. +#try_compiler_option '-Wunreachable-code' +try_compiler_option '-Wout-of-line-declaration' +try_compiler_option '-Wunsafe-loop-optimizations' +try_compiler_option '-Wwrite-strings' + +if /-Wl,--no-undefined/ =~ $LDFLAGS.to_s + $LDFLAGS.gsub!(/-Wl,--no-undefined/, '') +end + +include_path = nil +if ENV['GTK_BASEPATH'] and /cygwin/ !~ RUBY_PLATFORM + include_path = (ENV['GTK_BASEPATH'] + "\\INCLUDE").gsub("\\", "/") +# $hdrdir += " -I#{include_path} " + $CFLAGS += " -I#{include_path} " +end + +def windows_platform? + /cygwin|mingw|mswin/ === RUBY_PLATFORM +end + +def setup_windows(target_name, base_dir=nil) + checking_for(checking_message("Windows")) do + if windows_platform? + import_library_name = "libruby-#{target_name}.a" + $DLDFLAGS << " -Wl,--out-implib=#{import_library_name}" + $cleanfiles << import_library_name + base_dir ||= Pathname($0).dirname.parent.parent.expand_path + base_dir = Pathname(base_dir) if base_dir.is_a?(String) + binary_base_dir = base_dir + "vendor" + "local" + if binary_base_dir.exist? + $CFLAGS += " -I#{binary_base_dir}/include" + pkg_config_dir = binary_base_dir + "lib" + "pkgconfig" + PKGConfig.add_path(pkg_config_dir.to_s) + end + true + else + false + end + end +end +# For backward compatibility +def setup_win32(*args, &block) + setup_windows(*args, &block) +end + +def find_gem_spec(package) + begin + Gem::Specification.find_by_name(package) + rescue LoadError + nil + end +end + +def setup_homebrew_libffi + return unless package_platform == :homebrew + + PKGConfig.add_path("/usr/local/opt/libffi/lib/pkgconfig") +end + +#add_depend_package("glib2", "ext/glib2", "/...../ruby-gnome2") +def add_depend_package(target_name, target_srcdir, top_srcdir, options={}) + setup_homebrew_libffi if target_name == "gobject-introspection" + + gem_spec = find_gem_spec(target_name) + if gem_spec + target_source_dir = File.join(gem_spec.full_gem_path, "ext/#{target_name}") + target_build_dir = target_source_dir + add_depend_package_path(target_name, + target_source_dir, + target_build_dir) + end + + [top_srcdir, + File.join(top_srcdir, target_name), + $configure_args['--topdir'], + File.join($configure_args['--topdir'], target_name)].each do |topdir| + topdir = File.expand_path(topdir) + target_source_dir_full_path = File.join(topdir, target_srcdir) + + top_build_dir = options[:top_build_dir] || topdir + target_build_dir = options[:target_build_dir] || target_srcdir + target_build_dir_full_path = File.join(top_build_dir, target_build_dir) + unless File.exist?(target_build_dir_full_path) + target_build_dir_full_path = File.join(top_build_dir, target_srcdir) + end + unless File.exist?(target_build_dir_full_path) + target_build_dir_full_path = File.join(topdir, target_build_dir) + end + unless File.exist?(target_build_dir_full_path) + target_build_dir_full_path = File.join(topdir, target_srcdir) + end + add_depend_package_path(target_name, + target_source_dir_full_path, + target_build_dir_full_path) + end +end + +def add_depend_package_path(target_name, target_source_dir, target_build_dir) + if File.exist?(target_source_dir) + $INCFLAGS = "-I#{target_source_dir} #{$INCFLAGS}" + end + + if windows_platform? + target_base_dir = Pathname.new(target_source_dir).parent.parent + target_binary_base_dir = target_base_dir + "vendor" + "local" + if target_binary_base_dir.exist? + $INCFLAGS = "-I#{target_binary_base_dir}/include #{$INCFLAGS}" + target_pkg_config_dir = target_binary_base_dir + "lib" + "pkgconfig" + PKGConfig.add_path(target_pkg_config_dir.to_s) + end + end + + return unless File.exist?(target_build_dir) + if target_source_dir != target_build_dir + $INCFLAGS = "-I#{target_build_dir} #{$INCFLAGS}" + end + + if windows_platform? + library_base_name = "ruby-#{target_name.gsub(/-/, '_')}" + case RUBY_PLATFORM + when /cygwin|mingw/ + $LDFLAGS << " -L#{target_build_dir}" + $libs << " -l#{library_base_name}" + when /mswin/ + $DLDFLAGS << " /libpath:#{target_build_dir}" + $libs << " lib#{library_base_name}.lib" + end + end +end + +def add_distcleanfile(file) + $distcleanfiles ||= [] + $distcleanfiles << file +end + +def create_pkg_config_file(package_name, c_package, + version=nil, pc_file_name=nil) + pc_file_name ||= "#{package_name.downcase.sub(/\//, '-')}.pc" + version ||= ruby_gnome2_version || PKGConfig.modversion(c_package) + + puts "creating #{pc_file_name}" + + File.open(pc_file_name, 'w') do |pc_file| + if package_name.nil? + c_module_name = PKGConfig.name(c_package) + package_name = "Ruby/#{c_module_name}" if c_module_name + end + pc_file.puts("Name: #{package_name}") if package_name + + description = PKGConfig.description(c_package) + pc_file.puts("Description: Ruby bindings for #{description}") if description + pc_file.printf("Version: #{version}") + end + + add_distcleanfile(pc_file_name) +end + +def ruby_gnome2_version(glib_source_directory=nil) + glib_source_directory ||= File.join(File.dirname(__FILE__), "..", + "ext", "glib2") + rbglib_h = File.join(glib_source_directory, "rbglib.h") + return nil unless File.exist?(rbglib_h) + + version = nil + File.open(rbglib_h) do |h_file| + version_info = {} + h_file.each_line do |line| + case line + when /\A#define RBGLIB_(MAJOR|MINOR|MICRO)_VERSION\s+(\d+)/ + version_info[$1] = $2 + end + end + version_info = [version_info["MAJOR"], + version_info["MINOR"], + version_info["MICRO"]].compact + version = version_info.join(".") if version_info.size == 3 + end + + version +end + +def ensure_objs + return unless $objs.nil? + + source_dir = '$(srcdir)' + RbConfig.expand(source_dir) + + pattern = "*.{#{SRC_EXT.join(',')}}" + srcs = Dir[File.join(source_dir, pattern)] + srcs |= Dir[File.join(".", pattern)] + $objs = srcs.collect do |f| + File.basename(f, ".*") + ".o" + end.uniq +end + +def create_makefile_at_srcdir(pkg_name, srcdir, defs = nil) + base_dir = File.basename(Dir.pwd) + last_common_index = srcdir.rindex(base_dir) + if last_common_index + builddir = srcdir[(last_common_index + base_dir.size + 1)..-1] + end + builddir ||= "." + FileUtils.mkdir_p(builddir) + + Dir.chdir(builddir) do + yield if block_given? + + $defs << defs if defs + ensure_objs + create_makefile(pkg_name, srcdir) + end +end + +def run_make_in_sub_dirs_command(command, sub_dirs) + if /mswin/ =~ RUBY_PLATFORM + sub_dirs.collect do |dir| + <<-EOM.chmop + @cd #{dir} + @nmake -nologo DESTDIR=$(DESTDIR) #{command} + @cd .. + EOM + end.join("\n") + else + sub_dirs.collect do |dir| + "\t at cd #{dir}; $(MAKE) #{command}" + end.join("\n") + end +end + +def create_top_makefile(sub_dirs=["src"]) + File.open("Makefile", "w") do |makefile| + makefile.print(<<-EOM) +all: +#{run_make_in_sub_dirs_command("all", sub_dirs)} + +install: +#{run_make_in_sub_dirs_command("install", sub_dirs)} + +site-install: +#{run_make_in_sub_dirs_command("site-install", sub_dirs)} + +clean: +#{run_make_in_sub_dirs_command("clean", sub_dirs)} + EOM + + if /mswin/ =~ RUBY_PLATFORM + makefile.print(<<-EOM) + @if exist extconf.h del extconf.h + @if exist conftest.* del conftest.* + @if exist *.lib del *.lib + @if exist *~ del *~ + @if exist mkmf.log del mkmf.log + EOM + else + makefile.print(<<-EOM) + +distclean: clean +#{run_make_in_sub_dirs_command("distclean", sub_dirs)} + @rm -f Makefile extconf.h conftest.* + @rm -f core *~ mkmf.log + EOM + end + end +end + +# This is used for the library which doesn't support version info. +def make_version_header(app_name, pkgname, dir = "src") + version = PKGConfig.modversion(pkgname).split(/\./) + (0..2).each do |v| + version[v] = "0" unless version[v] + if /\A(\d+)/ =~ version[v] + number = $1 + tag = $POSTMATCH + unless tag.empty? + version[v] = number + version[3] = tag + end + end + end + filename = "rb#{app_name.downcase}version.h" + + puts "creating #{filename}" + + add_distcleanfile(filename) + + FileUtils.mkdir_p(dir) + out = File.open(File.join(dir, filename), "w") + + version_definitions = [] + ["MAJOR", "MINOR", "MICRO", "TAG"].each_with_index do |type, i| + _version = version[i] + next if _version.nil? + version_definitions << "#define #{app_name}_#{type}_VERSION (#{_version})" + end + out.print %Q[/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ +/************************************************ + + #{filename} - + + This file was generated by mkmf-gnome2.rb. + +************************************************/ + +#ifndef __RB#{app_name}_VERSION_H__ +#define __RB#{app_name}_VERSION_H__ + +#{version_definitions.join("\n")} + +#define #{app_name}_CHECK_VERSION(major,minor,micro) \\ + (#{app_name}_MAJOR_VERSION > (major) || \\ + (#{app_name}_MAJOR_VERSION == (major) && #{app_name}_MINOR_VERSION > (minor)) || \\ + (#{app_name}_MAJOR_VERSION == (major) && #{app_name}_MINOR_VERSION == (minor) && \\ + #{app_name}_MICRO_VERSION >= (micro))) + + +#endif /* __RB#{app_name}_VERSION_H__ */ +] + out.close +end + +def add_obj(name) + ensure_objs + $objs << name unless $objs.index(name) +end + +def glib_mkenums(prefix, files, g_type_prefix, include_files, options={}) + add_distcleanfile(prefix + ".h") + add_distcleanfile(prefix + ".c") + GLib::MkEnums.create(prefix, files, g_type_prefix, include_files, options) + add_obj("#{prefix}.o") +end + +def check_cairo(options={}) + rcairo_source_dir = options[:rcairo_source_dir] + if rcairo_source_dir.nil? + suffix = nil + if windows_platform? + case RUBY_PLATFORM + when /\Ax86-mingw/ + suffix = "win32" + when /\Ax64-mingw/ + suffix = "win64" + end + end + rcairo_source_base_dir = "rcairo" + rcairo_source_base_dir << ".#{suffix}" if suffix + top_dir = options[:top_dir] + if top_dir + rcairo_source_dir = File.join(top_dir, "..", rcairo_source_base_dir) + end + end + + if rcairo_source_dir and !File.exist?(rcairo_source_dir) + rcairo_source_dir = nil + end + if rcairo_source_dir.nil? + cairo_gem_spec = find_gem_spec("cairo") + rcairo_source_dir = cairo_gem_spec.full_gem_path if cairo_gem_spec + end + + unless rcairo_source_dir.nil? + if windows_platform? + options = {} + build_dir = "tmp/#{RUBY_PLATFORM}/cairo/#{RUBY_VERSION}" + if File.exist?(File.join(rcairo_source_dir, build_dir)) + options[:target_build_dir] = build_dir + end + add_depend_package("cairo", "ext/cairo", rcairo_source_dir, options) + $defs << "-DRUBY_CAIRO_PLATFORM_WIN32" + end + $CFLAGS += " -I#{rcairo_source_dir}/ext/cairo" + end + + PKGConfig.have_package('cairo') and have_header('rb_cairo.h') +end + +def package_platform + if File.exist?("/etc/debian_version") + :debian + elsif File.exist?("/etc/fedora-release") + :fedora + elsif File.exist?("/etc/redhat-release") + :redhat + elsif File.exist?("/etc/SuSE-release") + :suse + elsif File.exist?("/etc/altlinux-release") + :altlinux + elsif find_executable("pacman") + :arch + elsif find_executable("brew") + :homebrew + elsif find_executable("port") + :macports + else + :unknown + end +end + +def super_user? + Process.uid.zero? +end + +def normalize_native_package_info(native_package_info) + native_package_info ||= {} + native_package_info = native_package_info.dup + native_package_info[:fedora] ||= native_package_info[:redhat] + native_package_info[:suse] ||= native_package_info[:fedora] + native_package_info +end + +def install_missing_native_package(native_package_info) + platform = package_platform + native_package_info = normalize_native_package_info(native_package_info) + package = native_package_info[platform] + return false if package.nil? + + package_name, *options = package + package_command_line = [package_name, *options].join(" ") + need_super_user_priviledge = true + case platform + when :debian, :altlinux + install_command = "apt-get install -V -y #{package_command_line}" + when :fedora, :redhat + install_command = "yum install -y #{package_command_line}" + when :suse + install_command = "zypper --non-interactive install #{package_command_line}" + when :arch + install_command = "pacman -S --noconfirm #{package_command_line}" + when :homebrew + need_super_user_priviledge = false + install_command = "brew install #{package_command_line}" + when :macports + install_command = "port install -y #{package_command_line}" + else + return false + end + + have_priviledge = (not need_super_user_priviledge or super_user?) + unless have_priviledge + sudo = find_executable("sudo") + end + + installing_message = "installing '#{package_name}' native package... " + message("%s", installing_message) + failed_to_get_super_user_priviledge = false + if have_priviledge + succeeded = xsystem(install_command) + else + if sudo + prompt = "[sudo] password for %u to install <#{package_name}>: " + sudo_options = "-p #{Shellwords.escape(prompt)}" + install_command = "#{sudo} #{sudo_options} #{install_command}" + succeeded = xsystem(install_command) + else + succeeded = false + failed_to_get_super_user_priviledge = true + end + end + + if failed_to_get_super_user_priviledge + result_message = "require super user privilege" + else + result_message = succeeded ? "succeeded" : "failed" + end + Logging.postpone do + "#{installing_message}#{result_message}\n" + end + message("#{result_message}\n") + + error_message = nil + unless succeeded + if failed_to_get_super_user_priviledge + error_message = <<-EOM +'#{package_name}' native package is required. +run the following command as super user to install required native package: + \# #{install_command} +EOM + else + error_message = <<-EOM +failed to run '#{install_command}'. +EOM + end + end + if error_message + message("%s", error_message) + Logging.message("%s", error_message) + end + + Logging.message("--------------------\n\n") + + succeeded +end + +def required_pkg_config_package(package_info, native_package_info=nil) + if package_info.is_a?(Array) + required_package_info = package_info + else + required_package_info = [package_info] + end + if required_package_info.include?("gobject-introspection-1.0") + setup_homebrew_libffi + end + return true if PKGConfig.have_package(*required_package_info) + + native_package_info ||= {} + return false unless install_missing_native_package(native_package_info) + + PKGConfig.have_package(*required_package_info) +end + +add_include_path = Proc.new do |dir_variable| + value = RbConfig::CONFIG[dir_variable] + if value and File.exist?(value) + $INCFLAGS << " -I$(#{dir_variable}) " + end +end + +add_include_path.call("sitearchdir") +add_include_path.call("vendorarchdir") + +if /mingw/ =~ RUBY_PLATFORM + $ruby.gsub!('\\', '/') +end Added: binding/ruby/glib-3.1.1/patches/glib-2.48.0-add-missing-exeext.diff (+36 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/patches/glib-2.48.0-add-missing-exeext.diff 2017-02-15 13:19:47 +0900 (cf0cc44) @@ -0,0 +1,36 @@ +diff -ru glib-2.48.0.orig/gio/tests/Makefile.am glib-2.48.0/gio/tests/Makefile.am +--- glib-2.48.0.orig/gio/tests/Makefile.am 2016-03-23 00:15:18.000000000 +0900 ++++ glib-2.48.0/gio/tests/Makefile.am 2016-04-01 23:57:17.701727371 +0900 +@@ -532,7 +532,7 @@ + libresourceplugin_la_LDFLAGS += -rpath / + endif + +-glib_compile_resources=$(top_builddir)/gio/glib-compile-resources ++glib_compile_resources=$(top_builddir)/gio/glib-compile-resources$(EXEEXT) + + resources.o: test_resources2.h + test_resources.c: test2.gresource.xml Makefile $(shell $(glib_compile_resources) --sourcedir=$(srcdir) --generate-dependencies $(srcdir)/test2.gresource.xml) +diff -ru glib-2.48.0.orig/gobject/tests/Makefile.am glib-2.48.0/gobject/tests/Makefile.am +--- glib-2.48.0.orig/gobject/tests/Makefile.am 2016-02-29 23:32:08.000000000 +0900 ++++ glib-2.48.0/gobject/tests/Makefile.am 2016-04-02 00:03:17.344944211 +0900 +@@ -36,7 +36,7 @@ + # cross-compiling + + if !CROSS_COMPILING +-glib_genmarshal=$(top_builddir)/gobject/glib-genmarshal ++glib_genmarshal=$(top_builddir)/gobject/glib-genmarshal$(EXEEXT) + + test_programs += signals + signals_SOURCES = signals.c +diff -ru glib-2.48.0.orig/tests/gobject/Makefile.am glib-2.48.0/tests/gobject/Makefile.am +--- glib-2.48.0.orig/tests/gobject/Makefile.am 2016-02-24 07:25:37.000000000 +0900 ++++ glib-2.48.0/tests/gobject/Makefile.am 2016-04-02 00:00:07.259367148 +0900 +@@ -51,7 +51,7 @@ + # The marshal test requires running a binary, which means we cannot + # build it when cross-compiling + if !CROSS_COMPILING +-glib_genmarshal=$(top_builddir)/gobject/glib-genmarshal ++glib_genmarshal=$(top_builddir)/gobject/glib-genmarshal$(EXEEXT) + + testmarshal.h: stamp-testmarshal.h + @true Added: binding/ruby/glib-3.1.1/patches/guile-2.0.11-remove-needless-mkstemp-check.diff (+12 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/patches/guile-2.0.11-remove-needless-mkstemp-check.diff 2017-02-15 13:19:47 +0900 (1225b0a) @@ -0,0 +1,12 @@ +diff -ru guile-2.0.11.orig/configure.ac guile-2.0.11/configure.ac +--- guile-2.0.11.orig/configure.ac 2014-03-12 22:36:02.000000000 +0900 ++++ guile-2.0.11/configure.ac 2015-09-06 15:42:11.103807090 +0900 +@@ -1129,7 +1129,7 @@ + AC_DEFINE([ENABLE_REGEX], 1, [Define when regex support is enabled.]) + fi + +-AC_REPLACE_FUNCS([strerror memmove mkstemp]) ++AC_REPLACE_FUNCS([strerror memmove]) + + # Reasons for testing: + # asinh, acosh, atanh, trunc - C99 standard, generally not available on Added: binding/ruby/glib-3.1.1/sample/bookmarkfile.rb (+66 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/sample/bookmarkfile.rb 2017-02-15 13:19:47 +0900 (ebbaab3) @@ -0,0 +1,66 @@ +=begin + bookmarkfile.rb - Sample for GLib::BookmarkFile + + Copyright (C) 2006 Ruby-GNOME2 Project Team + This program is licenced under the same licence as Ruby-GNOME2. + + $Id: bookmarkfile.rb,v 1.1 2006/12/26 09:59:51 mutoh Exp $ +=end + +require 'glib2' + +$KCODE = "U" + +# +# Create bookmarkfile data. +# +URI = "http://ruby-gnome2.sourceforge.jp/" +bf = GLib::BookmarkFile.new +bf.set_title(URI, "Ruby-GNOME2 sample") +bf.set_description(URI, "Ruby-GNOME2 Sampe for GLib::BookmarkFile") +bf.set_mime_type(URI, "text/html") +bf.set_private(URI, false) +bf.set_icon(URI, "http://ruby-gnome2.sourceforge.jp/logo-gy.png", "image/png") +bf.set_added(URI, Time.now) +bf.set_modified(URI, Time.now) +bf.set_visited(URI, Time.now) +bf.set_groups(URI, ["Ruby", "GTK+"]) +bf.set_app_info(URI, "WWW Browser", "firefox %u", 1, Time.now) +bf.add_group(URI, "GNOME") +bf.add_application(URI, "Ruby VM", "ruby %u") + +#bf.remove_group(URI, "GTK+") +#bf.remove_application(URI, "Ruby VM") +#bf.remove_item(URI) +#bf.move_item(URI, "http://gtk.org/") + +# Save as "bookmarkfile.xml" +bf.to_file("bookmarkfile.xml") + +# +# Load from "bookmarkfile.xml" +# +bf2 = GLib::BookmarkFile.new +bf2.load_from_file("bookmarkfile.xml") + +puts "size = #{bf2.size}" +puts "uris = #{bf2.uris.inspect}" +bf2.uris.each do |uri| + puts "uri: [#{uri}]" + puts " * title: [#{bf2.get_title(uri)}]" + puts " * description: [#{bf2.get_description(uri)}]" + puts " * mime_type: [#{bf2.get_mime_type(uri)}]" + puts " * private?: [#{bf2.private?(uri)}]" + puts " * icon: [#{bf2.get_icon(uri).inspect}]" + puts " * added: [#{bf2.get_added(uri)}]" + puts " * modified: [#{bf2.get_modified(uri)}]" + puts " * visited: [#{bf2.get_visited(uri)}]" + puts " * groups: #{bf2.get_groups(uri).inspect}" + puts " * applications: #{bf2.get_applications(uri).inspect}" + begin + puts " * app_info: #{bf2.get_app_info(uri, "WWW Browser").inspect}" + rescue + puts $! + end + puts +end Added: binding/ruby/glib-3.1.1/sample/idle.rb (+41 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/sample/idle.rb 2017-02-15 13:19:47 +0900 (81794e2) @@ -0,0 +1,41 @@ +=begin + idle.rb - Sample for GLib::Idle, GLib::MainLoop. + + Copyright (C) 2005 Ruby-GNOME2 Project Team + This program is licenced under the same licence as Ruby-GNOME2. + + $Date: 2005/03/13 14:39:58 $ + $Id: idle.rb,v 1.1 2005/03/13 14:39:58 mutoh Exp $ +=end + +require 'glib2' + +mainloop = GLib::MainLoop.new(nil, true) + +i = 0 +GLib::Idle.add { + i += 1 + p "timeout1-#{i}" + if i > 9 + mainloop.quit + false # the source is removed. + else + true # continue ... + end +} + +j = 0 +GLib::Idle.add { + j += 1 + p "timeout2-#{i}" + if j > 9 + mainloop.quit + false # the source is removed. + else + true # continue ... + end +} + +mainloop.run + +p "quit..." Added: binding/ruby/glib-3.1.1/sample/iochannel.rb (+44 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/sample/iochannel.rb 2017-02-15 13:19:47 +0900 (3a793b3) @@ -0,0 +1,44 @@ +=begin + iochannel.rb - Sample for GLib::IOChannel. + + Copyright (C) 2005 Ruby-GNOME2 Project Team + This program is licenced under the same licence as Ruby-GNOME2. + + $Id: iochannel.rb,v 1.3 2006/12/20 18:08:20 mutoh Exp $ +=end + +require 'glib2' + +path = ARGV[0] || __FILE__ + +GLib::IOChannel.open(path) {|io| + puts io.read +} + +stdout = GLib::IOChannel.new(path, "r") +stdout.add_watch(GLib::IOChannel::IN + ) {|io, condition| + puts "condition = #{condition}" + false +} + +context = GLib::MainContext.default +mainloop = GLib::MainLoop.new(context, true) + + +Thread.new{ + num = 0 + loop { + num += 1 + str = stdout.gets + puts "line #{num}: #{str}" + unless str + mainloop.quit + break + end + } +} + +mainloop.run + +stdout.close Added: binding/ruby/glib-3.1.1/sample/keyfile.rb (+62 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/sample/keyfile.rb 2017-02-15 13:19:47 +0900 (d87badf) @@ -0,0 +1,62 @@ +=begin + keyfile.rb - Sample for GLib::KeyFile + + Copyright (C) 2006 Ruby-GNOME2 Project Team + This program is licenced under the same licence as Ruby-GNOME2. + + $Id: keyfile.rb,v 1.2 2006/12/23 17:43:03 mutoh Exp $ +=end + +require 'glib2' + +$KCODE = "U" + +# +# Create a GLib::KeyFile +# +kf = GLib::KeyFile.new +kf.set_value("Group 1", "value", "Hello World") +kf.set_comment("Group 1", nil, "This file is generated by keyfile.rb") +kf.set_string("Group 1", "string", "Hello World\nRuby-GNOME2") +kf.set_locale_string("Group 1", "locale_string", "ja", "こんにちわ世界") +kf.set_locale_string("Group 1", "locale_string", "en", "Hello World") +kf.set_boolean("Group 1", "boolean", true) +kf.set_integer("Group 1", "integer", 1) +kf.set_double("Group 1", "double", 1.0) +kf.set_string_list("Group 2", "string_list", ["foo", "bar"]) +kf.set_locale_string_list("Group 2", "locale_string_list", "ja", ["こんにちわ", "世界"]) +kf.set_locale_string_list("Group 2", "locale_string_list", "en", ["Hellow", "World"]) +kf.set_boolean_list("Group 2", "boolean_list", [true, false]) +kf.set_integer_list("Group 2", "integer_list", [1, 2, 3]) +kf.set_double_list("Group 2", "double_list", [1.2, 1.3, 1.45]) +kf.set_comment("Group 2", "string_list", "comment of string_list") + +# Save as "keyfile.ini" +File.open("keyfile.ini", "w") do |out| + out.write kf.to_data +end + +#kf.remove_comment("Group 2", "string_list") +#kf.remove_key("Group 2", "string_list") +#kf.remove_group("Group 2") + +# +# Load from "keyfile.ini" +# +kf2 = GLib::KeyFile.new +kf2.load_from_file("keyfile.ini") + +puts "Group 1: value = #{kf2.get_value("Group 1", "value")}" +puts "Group 1: string = #{kf2.get_string("Group 1", "string")}" +puts "Group 1: locale_string[ja] = #{kf2.get_locale_string("Group 1", "locale_string", "ja")}" +puts "Group 1: locale_string[en] = #{kf2.get_locale_string("Group 1", "locale_string", "en")}" +puts "Group 1: boolean = #{kf2.get_boolean("Group 1", "boolean")}" +puts "Group 1: integer = #{kf2.get_integer("Group 1", "integer")}" +puts "Group 1: double = #{kf2.get_double("Group 1", "double")}" +puts "Group 2: string_list = #{kf2.get_string_list("Group 2", "string_list").inspect}" +puts "Group 2: locale_string_list[ja] = #{kf2.get_locale_string_list("Group 2", "locale_string_list", "ja").inspect}" +puts "Group 2: locale_string_list[en] = #{kf2.get_locale_string_list("Group 2", "locale_string_list", "en").inspect}" +puts "Group 2: boolean_list = #{kf2.get_boolean_list("Group 2", "boolean_list").inspect}" +puts "Group 2: integer_list = #{kf2.get_integer_list("Group 2", "integer_list").inspect}" +puts "Group 2: double_list = #{kf2.get_double_list("Group 2", "double_list").inspect}" +puts "Group 2: comment = #{kf2.get_comment("Group 2", "string_list")}" Added: binding/ruby/glib-3.1.1/sample/shell.rb (+36 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/sample/shell.rb 2017-02-15 13:19:47 +0900 (9ec9b1b) @@ -0,0 +1,36 @@ +=begin + shell.rb - Sample for GLib::Shell + + Copyright (C) 2005 Ruby-GNOME2 Project Team + This program is licenced under the same licence as Ruby-GNOME2. + + $Id: shell.rb,v 1.1 2005/10/14 19:10:07 mutoh Exp $ +=end + +require 'glib2' + +cmd = "ls *.c *.o" + +p GLib::Shell.parse(cmd) + +puts quote = GLib::Shell.quote(cmd) +puts GLib::Shell.unquote(quote) + +puts "----" + +#Samples to catch an Exception +begin + GLib::Shell.parse('foooo "bar') +rescue GLib::ShellError => e + puts "domain = #{e.domain}" + puts "code = #{e.code}" + puts "message = #{e.message}" +end + +begin + GLib::Shell.unquote('foooo "bar') +rescue GLib::ShellError => e + puts "domain = #{e.domain}" + puts "code = #{e.code}" + puts "message = #{e.message}" +end Added: binding/ruby/glib-3.1.1/sample/spawn.rb (+25 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/sample/spawn.rb 2017-02-15 13:19:47 +0900 (bec35f2) @@ -0,0 +1,25 @@ +=begin + spawn.rb - Sample for GLib::Spawn + + Copyright (C) 2005 Ruby-GNOME2 Project Team + This program is licenced under the same licence as Ruby-GNOME2. + + $Date: 2005/10/14 19:10:07 $ + $Id: spawn.rb,v 1.3 2005/10/14 19:10:07 mutoh Exp $ +=end + +require 'glib2' + +p GLib::Spawn.command_line_sync("ls") + +puts "---" + +#Here is an example to catch GLib::SpawnError. +begin +p GLib::Spawn.command_line_sync("nonexist_app") +rescue => e + puts "class = #{e.class}" + puts "domain = #{e.domain}" + puts "code = #{e.code}" + puts "message = #{e.message}" +end Added: binding/ruby/glib-3.1.1/sample/timeout.rb (+28 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/sample/timeout.rb 2017-02-15 13:19:47 +0900 (10abc43) @@ -0,0 +1,28 @@ +=begin + timeout.rb - Sample for GLib::Timeout, GLib::MainLoop. + + Copyright (C) 2005 Ruby-GNOME2 Project Team + This program is licenced under the same licence as Ruby-GNOME2. + + $Id: timeout.rb,v 1.2 2005/07/14 17:05:22 mutoh Exp $ +=end + +require 'glib2' + +mainloop = GLib::MainLoop.new(nil, true) + +i = 0 +GLib::Timeout.add(1000) { + i += 1 + p "timeout-#{i}" + if i > 9 + mainloop.quit + false # the source is removed. + else + true # continue ... + end +} + +mainloop.run + +p "quit..." Added: binding/ruby/glib-3.1.1/sample/timeout2.rb (+35 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/sample/timeout2.rb 2017-02-15 13:19:47 +0900 (85ec098) @@ -0,0 +1,35 @@ +=begin + timeout2.rb - Sample for GLib::Timeout, GLib::MainLoop. + + Copyright (C) 2005 Ruby-GNOME2 Project Team + This program is licenced under the same licence as Ruby-GNOME2. + + $Date: 2005/03/13 15:43:32 $ + $Id: timeout2.rb,v 1.2 2005/03/13 15:43:32 mutoh Exp $ +=end + +require 'glib2' + +context = GLib::MainContext.new + +mainloop = GLib::MainLoop.new(context, true) + +source = GLib::Timeout.source_new(1000) + +i = 0 +source.set_callback { + i += 1 + p "timeout2-#{i}" + if i > 9 + mainloop.quit + false # the source is removed. + else + true # continue ... + end + +} +source.attach(context) + +mainloop.run + +p "quit..." Added: binding/ruby/glib-3.1.1/sample/timer.rb (+40 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/sample/timer.rb 2017-02-15 13:19:47 +0900 (b811690) @@ -0,0 +1,40 @@ +=begin + timer.rb - Sample for GLib::Timer + + Copyright (C) 2005 Ruby-GNOME2 Project Team + This program is licenced under the same licence as Ruby-GNOME2. + + $Id: timer.rb,v 1.1 2005/10/14 19:48:41 mutoh Exp $ +=end + +require 'glib2' + +timer = GLib::Timer.new + +timer.start +puts "start (status = running) : #{timer.elapsed}" + +sleep(3) + +puts "after 3 sec (status = running) : #{timer.elapsed}" + +sleep(3) + +puts "after 3 sec (status = running) : #{timer.elapsed}" +timer.stop +puts "stop (status = stoped) : #{timer.elapsed}" + +sleep(3) +puts "after 3 sec (status = stoped) : #{timer.elapsed}" + +timer.continue +puts "continue (status = running) : #{timer.elapsed}" +sleep(3) +puts "after 3 sec (status = running) : #{timer.elapsed}" + +timer.reset +puts "reset (status = running) : #{timer.elapsed}" +sleep(3) +puts "after 3 sec (status = running) : #{timer.elapsed}" + + Added: binding/ruby/glib-3.1.1/sample/type-register.rb (+103 -0) 100755 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/sample/type-register.rb 2017-02-15 13:19:47 +0900 (1896eb5) @@ -0,0 +1,103 @@ +=begin + type-register.rb - Sample for GLib::Object + + You also need Ruby/GTK. + + Copyright (C) 2004-2006 Ruby-GNOME2 Project Team + This program is licenced under the same licence as Ruby-GNOME2. + + $Date: 2006/06/17 14:31:22 $ + $Id: type-register.rb,v 1.9 2006/06/17 14:31:22 mutoh Exp $ +=end + +require 'gtk2' + +class MyButton < Gtk::Button + type_register + + def initialize(label = nil) + # XXX: + # When type_register() is used. + # super is equivalent to GLib::Object#initialize. + super("label" => label) + @fuga = 0 + end + + # override existing default handler of "clicked" signal. + def signal_do_clicked(*args) + puts "MyButton#signal_do_clicked enter" + #p caller + super + puts "MyButton#signal_do_clicked leave" + end + + # define new signal "hoge" + signal_new("hoge", # name + GLib::Signal::RUN_FIRST, # flags + nil, # accumulator (XXX: not supported yet) + nil, # return type (void == nil) + Integer, Integer # parameter types + ) + # define default handler of "hoge" signal + def signal_do_hoge(a, b) + puts "MyButton#signal_do_hoge enter" + #p caller + puts "MyButton#signal_do_hoge leave" + end + + # define new property "fuga" + install_property(GLib::Param::Int.new("fuga", # name + "Fuga", # nick + "fuga hoge", # blurb + 0, # min + 10000, # max + 0, # default + GLib::Param::READABLE | + GLib::Param::WRITABLE)) + # implementation of the property "fuga" + def fuga + puts "MyButton#fuga is called" + @fuga + end + def fuga=(arg) + puts "MyButton#fuga= is called" + @fuga = arg + notify("fuga") + end +end + +class MyButton2 < MyButton + type_register("MyButton2") + + # override default handler of "clicked" signal + def signal_do_clicked(*args) + puts "MyButton2#signal_do_clicked enter" + super(*args) + puts "MyButton2#signal_do_clicked leave" + end + + # override default handler of "hoge" signal + def signal_do_hoge(a, b) + puts "MyButton2#signal_do_hoge enter" + puts "a, b = #{a}, #{b}" + super + puts "MyButton2#signal_do_hoge leave" + end +end + +b = MyButton2.new("Hello") +p b +p b.label +p b.gtype +b.clicked +b.signal_emit("hoge", 1, 2) + +b.signal_connect("notify"){|obj, pspec| + puts "#{b} notify #{pspec}" +} + +p b.get_property("fuga") +b.set_property("fuga", 1) +p b.get_property("fuga") + +p MyButton2.ancestors Added: binding/ruby/glib-3.1.1/sample/type-register2.rb (+104 -0) 100755 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/sample/type-register2.rb 2017-02-15 13:19:47 +0900 (02c5a7b) @@ -0,0 +1,104 @@ +=begin + type-register2.rb - Sample for GLib::Object + + You also need Ruby/GTK. + + Copyright (C) 2004-2006 Ruby-GNOME2 Project Team + This program is licenced under the same licence as Ruby-GNOME2. + + $Date: 2006/06/17 14:31:22 $ + $Id: type-register2.rb,v 1.3 2006/06/17 14:31:22 mutoh Exp $ +=end + +require 'gtk2' + +class MyButton < Gtk::Button + type_register + + def initialize(label = nil) + # XXX: + # When type_register() is used. + # super is equivalent to GLib::Object#initialize. + super("label" => label) + @fuga = 0 + end + + # override existing default handler of "clicked" signal. + def signal_do_clicked(*args) + puts "MyButton#signal_do_clicked enter" + #p caller + super + puts "MyButton#signal_do_clicked leave" + end + + # define new signal "hoge" + signal_new("hoge", # name + GLib::Signal::RUN_FIRST, # flags + nil, # accumulator (XXX: not supported yet) + GLib::Type["void"], # return type + GLib::Type["gint"], GLib::Type["gint"] # parameter types + ) + # define default handler of "hoge" signal + def signal_do_hoge(a, b) + puts "MyButton#signal_do_hoge enter" + #p caller + puts "MyButton#signal_do_hoge leave" + end + + # define new property "fuga" + install_property(GLib::Param::Int.new("fuga", # name + "Fuga", # nick + "fuga hoge", # blurb + 0, # min + 10000, # max + 0, # default + GLib::Param::READABLE | + GLib::Param::WRITABLE)) + # implementation of the property "fuga" + def fuga + puts "MyButton#fuga is called" + @fuga + end + def fuga=(arg) + puts "MyButton#fuga= is called" + @fuga = arg + notify("fuga") + end +end + +class MyButton2 < MyButton + type_register("MyButton2") + + # override default handler of "clicked" signal + def signal_do_clicked(*args) + puts "MyButton2#signal_do_clicked enter" + super(*args) + puts "MyButton2#signal_do_clicked leave" + end + + # override default handler of "hoge" signal + def signal_do_hoge(a, b) + puts "MyButton2#signal_do_hoge enter" + puts "a, b = #{a}, #{b}" + #p caller + super + puts "MyButton2#signal_do_hoge leave" + end +end + +b = MyButton2.new("Hello") +p b +p b.label +p b.gtype +b.clicked +b.signal_emit("hoge", 1, 2) + +b.signal_connect("notify"){|obj, pspec| + puts "#{b} notify #{pspec}" +} + +p b.get_property("fuga") +b.set_property("fuga", 1) +p b.get_property("fuga") + +p MyButton2.ancestors Added: binding/ruby/glib-3.1.1/sample/utils.rb (+54 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/sample/utils.rb 2017-02-15 13:19:47 +0900 (c9ad4ca) @@ -0,0 +1,54 @@ +=begin + utils.rb - Sample for GLib module function produced by rbglib_utils.c + + Copyright (C) 2004 Masao Mutoh + This program is licenced under the same licence as Ruby-GNOME2. + + $Date: 2004/10/21 15:50:21 $ + $Id: utils.rb,v 1.2 2004/10/21 15:50:21 mutoh Exp $ +=end + +require 'glib2' + +if GLib.check_version?(2, 2, 0) + GLib.application_name = "application name" + puts "GLib.application_name = #{GLib.application_name}" +end + +GLib.prgname = "program name" +puts "GLib.prgname = #{GLib.prgname}" + +puts "GLib.getenv('HOME') = #{GLib.getenv('HOME')}" +if GLib.check_version?(2, 4, 0) + GLib.setenv("FOO", "foo") + puts "GLib.getenv('FOO') = #{GLib.getenv('FOO')}" + GLib.unsetenv("FOO") + puts "GLib.getenv('FOO') = #{GLib.getenv('FOO')}" +end + +puts "GLib.user_name = #{GLib.user_name}" +puts "GLib.real_name = #{GLib.real_name}" +puts "GLib.home_dir = #{GLib.home_dir}" +puts "GLib.tmp_dir = #{GLib.tmp_dir}" +puts "GLib.current_dir = #{GLib.current_dir}" +puts "GLib.path_is_absolute?('./') = #{GLib.path_is_absolute?("./")}" +puts "GLib.path_skip_root('/usr/local/bin/ruby') = #{GLib.path_skip_root('/usr/local/bin/ruby')}" +puts "GLib.path_get_basename(GLib.home_dir) = #{GLib.path_get_basename(GLib.home_dir)}" +puts "GLib.path_get_dirname(GLib.home_dir) = #{GLib.path_get_dirname(GLib.home_dir)}" +puts "GLib.find_program_in_path(GLib.prgname) = #{GLib.find_program_in_path(GLib.prgname)}" +puts "GLib.bit_nth_lsf(3, 1) = #{GLib.bit_nth_lsf(3, 1)}" +puts "GLib.bit_nth_msf(3, 1) = #{GLib.bit_nth_msf(3, 1)}" +puts "GLib.bit_storage(3) = #{GLib.bit_storage(3)}" +puts "GLib.spaced_primes_closest(10) = #{GLib.spaced_primes_closest(10)}" + +keys = { + "foo" => 1 << 0, + "bar" => 1 << 1, + "hoge" => 1 << 2, + "fuga" => 1 << 3 +} + +puts GLib.parse_debug_string("foo", keys) +puts GLib.parse_debug_string("bar", keys) +puts GLib.parse_debug_string("foo:bar:hoge", keys) +puts GLib.parse_debug_string("foo:bar:hoge:fuga", keys) Added: binding/ruby/glib-3.1.1/test/glib-test-init.rb (+21 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/test/glib-test-init.rb 2017-02-15 13:19:47 +0900 (fd09786) @@ -0,0 +1,21 @@ +# Copyright (C) 2015 Ruby-GNOME2 Project Team +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +$VERBOSE = true + +require "rubygems" +gem 'test-unit' +require 'test/unit' Added: binding/ruby/glib-3.1.1/test/glib-test-utils.rb (+28 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/test/glib-test-utils.rb 2017-02-15 13:19:47 +0900 (c24d265) @@ -0,0 +1,28 @@ +# Copyright (C) 2015 Ruby-GNOME2 Project Team +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +module GLibTestUtils + private + def only_glib_version(major, minor, micro) + unless GLib.check_version?(major, minor, micro) + omit("Require GLib >= #{major}.#{minor}.#{micro}") + end + end + + def only_win32 + omit("Only for Win32 platform") unless GLib.os_win32? + end +end Added: binding/ruby/glib-3.1.1/test/run-test.rb (+37 -0) 100755 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/test/run-test.rb 2017-02-15 13:19:47 +0900 (08216db) @@ -0,0 +1,37 @@ +#!/usr/bin/env ruby +# Copyright (C) 2015 Ruby-GNOME2 Project Team +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + +base = File.expand_path(File.join(File.dirname(__FILE__))) +top = File.expand_path(File.join(base, "..")) + +$LOAD_PATH.unshift(top) +require 'test/glib-test-init' + +if system("which make > /dev/null") + system("cd #{top.dump} && make > /dev/null") or exit(1) +end + +$LOAD_PATH.unshift(File.join(top, "ext", "glib2")) +$LOAD_PATH.unshift(File.join(top, "lib")) + +$LOAD_PATH.unshift(base) +require 'glib-test-utils' + +require 'glib2' + +exit Test::Unit::AutoRunner.run(true, base) Added: binding/ruby/glib-3.1.1/test/test-binding.rb (+188 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/test/test-binding.rb 2017-02-15 13:19:47 +0900 (6cbc93f) @@ -0,0 +1,188 @@ +# Copyright (C) 2015 Ruby-GNOME2 Project Team +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +class TestGLibBinding < Test::Unit::TestCase + include GLibTestUtils + sub_test_case "bind_property" do + class DataObjectDefault < GLib::Object + type_register + + install_property(GLib::Param::Int.new("source", # name + "Source", # nick + "The source data", # blurb + 0, # min + 100, # max + 0, # default + GLib::Param::READABLE | + GLib::Param::WRITABLE)) + install_property(GLib::Param::Int.new("target", # name + "Target", # nick + "The target data", # blurb + 0, # min + 100, # max + 0, # default + GLib::Param::READABLE | + GLib::Param::WRITABLE)) + + attr_reader :source, :target + def initialize + @source = 0 + @target = 0 + super + end + + def source=(value) + @source = value + notify("source") + end + + def target=(value) + @target = value + notify("target") + end + end + + setup do + only_glib_version(2, 26, 0) + end + + setup do + @source = DataObjectDefault.new + @target = DataObjectDefault.new + @binding =****@sourc*****_property("source", @target, "target", :default) + end + + test "#source" do + assert_equal(@source, @binding.source) + end + + test "#source_property" do + assert_equal("source", @binding.source_property) + end + + test "#target" do + assert_equal(@target, @binding.target) + end + + test "#target_property" do + assert_equal("target", @binding.target_property) + end + + test "#flags" do + assert_equal(GLib::BindingFlags::DEFAULT, @binding.flags) + end + + test "#unbind" do + only_glib_version(2, 38, 0) + assert_equal(0, @target.target) + @source.source = 10 + assert_equal(10, @target.target) + @binding.unbind + @source.source = 20 + assert_equal(10, @target.target) + end + end + sub_test_case "bind_property_full" do + class DataObjectBidir < GLib::Object + type_register + + install_property(GLib::Param::Int.new("source", # name + "Source", # nick + "The source data", # blurb + 0, # min + 100, # max + 0, # default + GLib::Param::READABLE | + GLib::Param::WRITABLE)) + install_property(GLib::Param::String.new("target", # name + "Target", # nick + "The target data", # blurb + "", # default + GLib::Param::READABLE | + GLib::Param::WRITABLE)) + + attr_reader :source, :target + def initialize + @source = 0 + @target = "nan" + super + end + + def source=(value) + @source = value + notify("source") + end + + def target=(value) + @target = value + notify("target") + end + end + + setup do + only_glib_version(2, 26, 0) + end + + setup do + @source = DataObjectBidir.new + @target = DataObjectBidir.new + transform_to_callback = proc do |source_value| + source_value.to_s + end + + transform_from_callback = proc do |target_value| + target_value.to_i + end + + @binding =****@sourc*****_property("source", @target, "target", + :bidirectional, + :transform_to => transform_to_callback, + :transform_from => transform_from_callback) + end + + test "#source" do + assert_equal(@source, @binding.source) + end + + test "#source_property" do + assert_equal("source", @binding.source_property) + end + + test "#target" do + assert_equal(@target, @binding.target) + end + + test "#target_property" do + assert_equal("target", @binding.target_property) + end + + test "#flags" do + assert_equal(GLib::BindingFlags::BIDIRECTIONAL, @binding.flags) + end + + test "#unbind" do + only_glib_version(2, 38, 0) + assert_equal("nan", @target.target) + @source.source = 10 + assert_equal("10", @target.target) + @target.target = "30" + assert_equal(30, @source.source) + @binding.unbind + @source.source = 20 + assert_equal("30", @target.target) + end + end +end Added: binding/ruby/glib-3.1.1/test/test-date-time.rb (+112 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/test/test-date-time.rb 2017-02-15 13:19:47 +0900 (e5f1738) @@ -0,0 +1,112 @@ +# Copyright (C) 2016 Ruby-GNOME2 Project Team +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +class TestDateTime < Test::Unit::TestCase + def test_now_local + now = GLib::DateTime.now(:local) + format = "%Y-%m-%d-%H-%M" + assert_equal(Time.now.strftime(format), now.format(format)) + end + + sub_test_case "new" do + + test "unix: :local" do + time = Time.now + format = "%Y-%m-%d-%H-%M" + datetime = GLib::DateTime.new(:unix => time.to_i, + :timezone => :local) + assert_equal(time.strftime(format), datetime.format(format)) + end + + test "unix: :utc" do + time = Time.now.utc + format = "%Y-%m-%d-%H-%M" + datetime = GLib::DateTime.new(:unix => time.to_i, + :timezone => :utc) + assert_equal(time.strftime(format), datetime.format(format)) + end + + test "timezone: :local" do + time = Time.now + datetime = GLib::DateTime.new(:timezone => :local, + :year => time.year, + :month => time.month, + :day => time.day, + :hour => time.hour, + :minute => time.min, + :second => time.sec) + assert_equal(time.year, datetime.year) + assert_equal(time.month, datetime.month) + assert_equal(time.day, datetime.day_of_month) + assert_equal(time.hour, datetime.hour) + assert_equal(time.min, datetime.minute) + assert_equal(time.sec, datetime.second) + end + + test "timezone: :utc" do + time = Time.now.utc + datetime = GLib::DateTime.new(:timezone => :utc, + :year => time.year, + :month => time.month, + :day => time.day, + :hour => time.hour, + :minute => time.min, + :second => time.sec) + assert_equal(time.year, datetime.year) + assert_equal(time.month, datetime.month) + assert_equal(time.day, datetime.day_of_month) + assert_equal(time.hour, datetime.hour) + assert_equal(time.min, datetime.minute) + assert_equal(time.sec, datetime.second) + end + + test "timezone: local time zone" do + time = Time.now + tz = GLib::TimeZone.local + datetime = GLib::DateTime.new(:timezone => tz, + :year => time.year, + :month => time.month, + :day => time.day, + :hour => time.hour, + :minute => time.min, + :second => time.sec) + assert_equal(time.year, datetime.year) + assert_equal(time.month, datetime.month) + assert_equal(time.day, datetime.day_of_month) + assert_equal(time.hour, datetime.hour) + assert_equal(time.min, datetime.minute) + assert_equal(time.sec, datetime.second) + end + + test "timezone: UTC time zone" do + time = Time.now.utc + tz = GLib::TimeZone.utc + datetime = GLib::DateTime.new(:timezone => tz, + :year => time.year, + :month => time.month, + :day => time.day, + :hour => time.hour, + :minute => time.min, + :second => time.sec) + assert_equal(time.year, datetime.year) + assert_equal(time.month, datetime.month) + assert_equal(time.day, datetime.day_of_month) + assert_equal(time.hour, datetime.hour) + assert_equal(time.min, datetime.minute) + assert_equal(time.sec, datetime.second) + end + end +end Added: binding/ruby/glib-3.1.1/test/test-match-info.rb (+113 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/test/test-match-info.rb 2017-02-15 13:19:47 +0900 (9046f69) @@ -0,0 +1,113 @@ +# Copyright (C) 2015-2016 Ruby-GNOME2 Project Team +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +class TestMatchInfo < Test::Unit::TestCase + def test_string + regex = GLib::Regex.new("[A-Z]+") + match_info = regex.match("abc def") + assert_equal("abc def", match_info.string) + end + + def test_regex + regex = GLib::Regex.new("[A-Z]+") + match_info = regex.match("abc def") + assert_equal("[A-Z]+", match_info.regex.pattern) + end + + def test_partial_match + flags = GLib::RegexMatchFlags::PARTIAL_SOFT + regex = GLib::Regex.new("jan") + match_info = regex.match_all("ja", :match_options => flags) + assert do + !match_info.matches? + end + assert do + match_info.partial_match? + end + end + + sub_test_case "fetch" do + test "Integer" do + regex = GLib::Regex.new("[A-Z]+") + match_info = regex.match_all("abc DEF ghi JKL mnop") + assert_equal("DEF", match_info.fetch(0)) + assert_equal("DE", match_info.fetch(1)) + end + + test "String" do + regex = GLib::Regex.new("(?<a_name>fo+)") + match_info = regex.match("tatafoo") + assert_equal("foo", match_info.fetch("a_name")) + end + + test "Symbol" do + regex = GLib::Regex.new("(?<a_name>fo+)") + match_info = regex.match("tatafoo") + assert_equal("foo", match_info.fetch(:a_name)) + end + + test "[]" do + regex = GLib::Regex.new("(?<a_name>fo+)") + match_info = regex.match("tatafoo") + assert_equal("foo", match_info[:a_name]) + end + end + + sub_test_case "fetch_pos" do + test "Integer" do + regex = GLib::Regex.new("[A-Z]+") + match_info = regex.match_all("abc DEF ghi JKL mnop") + assert_equal([4, 7], match_info.fetch_pos(0)) + assert_equal([4, 6], match_info.fetch_pos(1)) + end + + test "String" do + regex = GLib::Regex.new("(?<a_name>fo+)") + match_info = regex.match("tatafoo") + assert_equal([4, 7], match_info.fetch_pos("a_name")) + end + + test "Symbol" do + regex = GLib::Regex.new("(?<a_name>fo+)") + match_info = regex.match("tatafoo") + assert_equal([4, 7], match_info.fetch_pos(:a_name)) + end + end + + def test_fetch_all + regex = GLib::Regex.new("[A-Z]+") + str = "abc DEF ghi JKL mnop" + match_info = regex.match_all(str) + assert_equal(["DEF", "DE", "D"], match_info.fetch_all) + end + + def test_next + regex = GLib::Regex.new("[A-Z]+") + str = "abc DEF ghi JKL mnop" + match_info = regex.match(str) + assert_equal("DEF", match_info[0]) + assert {match_info.next} + assert_equal("JKL", match_info[0]) + assert {!match_info.next} + end + + def test_expand_references + regex = GLib::Regex.new("a(?P<G>.)c") + match_info = regex.match("xabcy") + expanded_string = match_info.expand_references("X\\g<G>X") + assert_equal("XbX", expanded_string) + end +end Added: binding/ruby/glib-3.1.1/test/test-regex.rb (+320 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/test/test-regex.rb 2017-02-15 13:19:47 +0900 (61a96ff) @@ -0,0 +1,320 @@ +# Copyright (C) 2015-2016 Ruby-GNOME2 Project Team +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +class TestRegex < Test::Unit::TestCase + def test_enum_match_flags + assert_const_defined(GLib, :RegexMatchFlags) + assert_kind_of(GLib::RegexMatchFlags, GLib::RegexMatchFlags::PARTIAL_HARD) + end + + def test_enum_compile_flags + assert_const_defined(GLib, :RegexCompileFlags) + assert_kind_of(GLib::RegexCompileFlags, GLib::RegexCompileFlags::CASELESS) + end + + def test_pattern + regex = GLib::Regex.new("to??") + assert_equal("to??", regex.pattern) + end + + def test_compile_flags + flags = GLib::RegexCompileFlags::CASELESS + regex = GLib::Regex.new("to??", :compile_options => flags) + assert_equal(flags, regex.compile_flags) + end + + def test_match_flags + flags = GLib::RegexMatchFlags::PARTIAL_HARD + regex = GLib::Regex.new("to??", :match_options => flags) + assert_equal(flags, regex.match_flags) + end + + sub_test_case "split" do + test "no options" do + regex = GLib::Regex.new("\s") + string_to_split = "a bc" + splited_strings = regex.split(string_to_split) + assert_equal(["a", "bc"], splited_strings) + end + + test "start_position" do + regex = GLib::Regex.new("\s") + string_to_split = "a bc" + splited_strings = regex.split(string_to_split, :start_position => 2) + assert_equal(["bc"], splited_strings) + end + + test "max_tokens" do + regex = GLib::Regex.new("\s") + string_to_split = "a bc de fg" + splited_strings = regex.split(string_to_split, :max_tokens => 2) + assert_equal(["a", "bc de fg"], splited_strings) + end + + test "match_options" do + regex = GLib::Regex.new("a?b?") + string_to_split = "toto ab" + splited_strings = regex.split(string_to_split) + assert_equal(["t", "o", "t", "o", " "], + splited_strings) + splited_strings = regex.split(string_to_split, + :match_options => :notempty) + assert_equal(["toto ", ""], splited_strings) + end + end + + sub_test_case "match" do + setup do + @regex = GLib::Regex.new("[A-Z]+") + end + + test "no match no options" do + match_info =****@regex*****("abc def") + assert do + not match_info.matches? + end + end + + test "matched no options" do + match_info =****@regex*****("abc DEF") + assert do + match_info.matches? + end + end + + test "no match and start position option" do + match_info =****@regex*****("abc def", :start_position => 4) + assert do + not match_info.matches? + end + end + + test "matched and start position option" do + match_info =****@regex*****("abc DEF", :start_position => 4) + assert do + match_info.matches? + end + end + end + + sub_test_case "max_backref" do + test "none" do + regex = GLib::Regex.new("to?o") + assert_equal(0, regex.max_backref) + end + + test "one" do + regex = GLib::Regex.new("(to(?)o)\\g1") + assert_equal(1, regex.max_backref) + end + end + + sub_test_case "capture_count" do + test "none" do + regex = GLib::Regex.new("to?o") + assert_equal(0, regex.capture_count) + end + + test "one" do + regex = GLib::Regex.new("(to(\?)o)") + assert_equal(1, regex.capture_count) + end + + test "three" do + regex = GLib::Regex.new("((red|white) (king|queen))") + assert_equal(3, regex.capture_count) + end + end + + sub_test_case "has_cr_or_lf" do + test "none" do + regex = GLib::Regex.new("to?o") + assert do + not regex.has_cr_or_lf? + end + end + + test "both" do + regex = GLib::Regex.new("to\no") + assert do + regex.has_cr_or_lf? + end + end + + test "cr" do + regex = GLib::Regex.new("to\rtiti") + assert do + regex.has_cr_or_lf? + end + end + end + + sub_test_case "max_lookbehind" do + test "none" do + regex = GLib::Regex.new("to?o") + assert_equal(0, regex.max_lookbehind) + end + + test "three" do + regex = GLib::Regex.new("(?<!foo)bar") + assert_equal(3, regex.max_lookbehind) + end + end + + sub_test_case "string_number" do + test "none" do + regex = GLib::Regex.new("too") + assert_equal(-1, regex.string_number("a_name")) + end + + test "one" do + regex = GLib::Regex.new("(?<a_name>foo)bar") + assert_equal(1, regex.string_number("a_name")) + end + + test "two" do + regex = GLib::Regex.new("(?<another_name>foo)(?<a_name>bar)") + assert_equal(2, regex.string_number("a_name")) + end + end + + def test_regex_escape_string + assert_equal("a\\.b\\*c", GLib::Regex.escape_string("a.b*c")) + end + + sub_test_case "match?" do + test "true" do + assert do + GLib::Regex.match?("to", "tatota") + end + end + + test "false" do + assert do + not GLib::Regex.match?("ti", "tatota") + end + end + end + + sub_test_case "match_all" do + test "no match" do + regex = GLib::Regex.new("[A-Z]+") + assert do + not regex.match_all("abc def").matches? + end + end + + test ":start_position" do + regex = GLib::Regex.new("[A-Z]") + assert do + regex.match_all("a B c", :start_position => 2).matches? + end + assert do + not regex.match_all("a B c", :start_position => 3).matches? + end + end + + test "match all" do + regex = GLib::Regex.new("<.*>") + assert_equal(3, regex.match_all("<a> <b> <c>").match_count) + end + end + + sub_test_case "split simple" do + test "no options" do + splited_strings = GLib::Regex.split("\s", "a bc") + assert_equal(["a", "bc"], splited_strings) + end + + test "match_options" do + splited_strings = GLib::Regex.split("a?b?", "toto ab") + assert_equal(["t", "o", "t", "o", " "], splited_strings) + + splited_strings = GLib::Regex.split("a?b?", + "toto ab", + :match_options => :notempty) + assert_equal(["toto ", ""], splited_strings) + end + end + + sub_test_case "replace" do + test "simple" do + regex = GLib::Regex.new("\\s") + assert_equal("a_bc", regex.replace("a bc", "_")) + end + + test "back reference" do + regex = GLib::Regex.new("\\s") + assert_equal("a_ _bc", regex.replace("a bc", "_\\0_")) + end + + test "literal" do + regex = GLib::Regex.new("\\s") + assert_equal("a_\\0_bc", + regex.replace("a bc", + "_\\0_", + :literal => true)) + end + + sub_test_case "eval" do + test "all" do + regex = GLib::Regex.new("1|2|3|4") + modified_string = regex.replace(" 4 3 2 1") do |match_info| + "to" + end + assert_equal(" to to to to", modified_string) + end + + test "break" do + regex = GLib::Regex.new("1|2|3|4") + modified_string = regex.replace(" 4 3 2 1") do |match_info| + break "to" + end + assert_equal(" to 3 2 1", modified_string) + end + end + end + + sub_test_case "check_replacement" do + test "no references" do + assert_true(GLib::Regex.check_replacement("foo\\n")) + end + + test "with references" do + assert_true(GLib::Regex.check_replacement("\\0\\1")) + end + + test "invalid" do + assert_raise(GLib::Error) do + GLib::Regex.check_replacement("\\") + end + end + end + + sub_test_case "have_reference?" do + test "no references" do + assert do + not GLib::Regex.have_reference?("foo\\n") + end + end + + test "with references" do + assert do + GLib::Regex.have_reference?("\\0\\1") + end + end + end +end Added: binding/ruby/glib-3.1.1/test/test-time-zone.rb (+31 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/test/test-time-zone.rb 2017-02-15 13:19:47 +0900 (9b86451) @@ -0,0 +1,31 @@ +# Copyright (C) 2016 Ruby-GNOME2 Project Team +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +class TestTimeZone < Test::Unit::TestCase + sub_test_case "new" do + test "local" do + local_1 = GLib::TimeZone.local + local_2 = GLib::TimeZone.new + assert_equal(local_1.abbreviation(0), local_2.abbreviation(0)) + end + + test "UTC" do + utc_1 = GLib::TimeZone.utc + utc_2 = GLib::TimeZone.new("UTC") + assert_equal(utc_1.offset(0), utc_2.offset(0)) + end + end +end Added: binding/ruby/glib-3.1.1/test/test-variant-type.rb (+357 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/test/test-variant-type.rb 2017-02-15 13:19:47 +0900 (bd4d9eb) @@ -0,0 +1,357 @@ +# Copyright (C) 2015 Ruby-GNOME2 Project Team +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +class TestGLibVariantType < Test::Unit::TestCase + include GLibTestUtils + + sub_test_case "constants" do + test "BOOLEAN" do + assert_equal("b", GLib::VariantType::BOOLEAN.to_s) + end + + test "BYTE" do + assert_equal("y", GLib::VariantType::BYTE.to_s) + end + + test "INT16" do + assert_equal("n", GLib::VariantType::INT16.to_s) + end + + test "UINT16" do + assert_equal("q", GLib::VariantType::UINT16.to_s) + end + + test "INT32" do + assert_equal("i", GLib::VariantType::INT32.to_s) + end + + test "UINT32" do + assert_equal("u", GLib::VariantType::UINT32.to_s) + end + + test "INT64" do + assert_equal("x", GLib::VariantType::INT64.to_s) + end + + test "UINT64" do + assert_equal("t", GLib::VariantType::UINT64.to_s) + end + + test "HANDLE" do + assert_equal("h", GLib::VariantType::HANDLE.to_s) + end + + test "DOUBLE" do + assert_equal("d", GLib::VariantType::DOUBLE.to_s) + end + + test "STRING" do + assert_equal("s", GLib::VariantType::STRING.to_s) + end + + test "OBJECT_PATH" do + assert_equal("o", GLib::VariantType::OBJECT_PATH.to_s) + end + + test "SIGNATURE" do + assert_equal("g", GLib::VariantType::SIGNATURE.to_s) + end + + test "VARIANT" do + assert_equal("v", GLib::VariantType::VARIANT.to_s) + end + + test "ANY" do + assert_equal("*", GLib::VariantType::ANY.to_s) + end + + test "BASIC" do + assert_equal("?", GLib::VariantType::BASIC.to_s) + end + + test "MAYBE" do + assert_equal("m*", GLib::VariantType::MAYBE.to_s) + end + + test "ARRAY" do + assert_equal("a*", GLib::VariantType::ARRAY.to_s) + end + + test "TUPLE" do + assert_equal("r", GLib::VariantType::TUPLE.to_s) + end + + test "UNIT" do + assert_equal("()", GLib::VariantType::UNIT.to_s) + end + + test "DICT_ENTRY" do + assert_equal("{?*}", GLib::VariantType::DICT_ENTRY.to_s) + end + + test "DICTIONARY" do + assert_equal("a{?*}", GLib::VariantType::DICTIONARY.to_s) + end + + test "STRING_ARRAY" do + assert_equal("as", GLib::VariantType::STRING_ARRAY.to_s) + end + + test "OBJECT_PATH_ARRAY" do + assert_equal("ao", GLib::VariantType::OBJECT_PATH_ARRAY.to_s) + end + + test "BYTESTRING" do + assert_equal("ay", GLib::VariantType::BYTESTRING.to_s) + end + + test "BYTESTRING_ARRAY" do + assert_equal("aay", GLib::VariantType::BYTESTRING_ARRAY.to_s) + end + + test "VARDICT" do + assert_equal("a{sv}", GLib::VariantType::VARDICT.to_s) + end + end + + sub_test_case ".valid?" do + test "valid" do + assert do + GLib::VariantType.valid?("s") + end + end + + test "invalid" do + assert do + !GLib::VariantType.valid?("X") + end + end + end + + sub_test_case ".scan" do + test "found" do + assert_equal("X", GLib::VariantType.scan("sX")) + end + + test "not found" do + assert_nil(GLib::VariantType.scan("X")) + end + end + + sub_test_case "#initialize" do + test "invalid" do + assert_raise(ArgumentError.new("invalid type string: \"X\"")) do + GLib::VariantType.new("X") + end + end + end + + test "#to_s" do + variant_type = GLib::VariantType.new("s") + assert_equal("s", variant_type.to_s) + end + + sub_test_case "#definite?" do + test "definite" do + variant_type = GLib::VariantType.new("s") + assert do + variant_type.definite? + end + end + + test "not definite" do + variant_type = GLib::VariantType.new("?") + assert do + !variant_type.definite? + end + end + end + + sub_test_case "#container?" do + test "container" do + variant_type = GLib::VariantType.new("a*") + assert do + variant_type.container? + end + end + + test "not container" do + variant_type = GLib::VariantType.new("s") + assert do + !variant_type.container? + end + end + end + + sub_test_case "#basic?" do + test "basic" do + variant_type = GLib::VariantType.new("s") + assert do + variant_type.basic? + end + end + + test "not basic" do + variant_type = GLib::VariantType.new("as") + assert do + !variant_type.basic? + end + end + end + + sub_test_case "#maybe?" do + test "maybe" do + variant_type = GLib::VariantType.new("ms") + assert do + variant_type.maybe? + end + end + + test "not maybe" do + variant_type = GLib::VariantType.new("s") + assert do + !variant_type.maybe? + end + end + end + + sub_test_case "#array?" do + test "array" do + variant_type = GLib::VariantType.new("as") + assert do + variant_type.array? + end + end + + test "not array" do + variant_type = GLib::VariantType.new("s") + assert do + !variant_type.array? + end + end + end + + sub_test_case "#tuple?" do + test "tuple" do + variant_type = GLib::VariantType.new("(s)") + assert do + variant_type.tuple? + end + end + + test "not tuple" do + variant_type = GLib::VariantType.new("s") + assert do + !variant_type.tuple? + end + end + end + + sub_test_case "#dict_entry?" do + test "dictionary entry" do + variant_type = GLib::VariantType.new("{ss}") + assert do + variant_type.dict_entry? + end + end + + test "not dictionary entry" do + variant_type = GLib::VariantType.new("s") + assert do + !variant_type.dict_entry? + end + end + end + + sub_test_case "#variant?" do + test "variant" do + variant_type = GLib::VariantType.new("v") + assert do + variant_type.variant? + end + end + + test "not variant" do + variant_type = GLib::VariantType.new("s") + assert do + !variant_type.variant? + end + end + end + + sub_test_case "#==" do + test "same" do + variant_type = GLib::VariantType.new("s") + assert_equal(variant_type, + variant_type) + end + + test "equivalence" do + assert_equal(GLib::VariantType.new("s"), + GLib::VariantType.new("s")) + end + + test "not VariantType" do + assert_not_equal(GLib::VariantType.new("s"), + "s") + end + end + + sub_test_case "#hash and #eql?" do + test "Hash key" do + hash = { + GLib::VariantType.new("s") => :s, + } + assert_equal(:s, hash[GLib::VariantType.new("s")]) + end + end + + sub_test_case "#is_subtype_of?" do + test "subtype" do + string = GLib::VariantType.new("s") + basic = GLib::VariantType.new("?") + assert do + string.is_subtype_of?(basic) + end + end + + test "not subtype" do + string = GLib::VariantType.new("s") + int32 = GLib::VariantType.new("i") + assert do + !string.is_subtype_of?(int32) + end + end + end + + sub_test_case "#element" do + test "array" do + assert_equal(GLib::VariantType.new("s"), + GLib::VariantType.new("as").element) + end + + test "maybe" do + assert_equal(GLib::VariantType.new("s"), + GLib::VariantType.new("ms").element) + end + + test "unexpected" do + assert_raise(ArgumentError.new("must be array or maybe type: <s>")) do + GLib::VariantType.new("s").element + end + end + end +end Added: binding/ruby/glib-3.1.1/test/test-version.rb (+47 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/test/test-version.rb 2017-02-15 13:19:47 +0900 (13b8e13) @@ -0,0 +1,47 @@ +# Copyright (C) 2015 Ruby-GNOME2 Project Team +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +class TestGLibVersion < Test::Unit::TestCase + include GLibTestUtils + + test "STRING" do + major = GLib::Version::MAJOR + minor = GLib::Version::MINOR + micro = GLib::Version::MICRO + assert_equal([major, minor, micro].join("."), + GLib::Version::STRING) + end + + sub_test_case("#or_later?") do + test "same" do + assert_true(GLib::Version.or_later?(GLib::Version::MAJOR, + GLib::Version::MINOR, + GLib::Version::MICRO)) + end + + test "later" do + assert_true(GLib::Version.or_later?(GLib::Version::MAJOR, + GLib::Version::MINOR - 1, + GLib::Version::MICRO)) + end + + test "earlier" do + assert_false(GLib::Version.or_later?(GLib::Version::MAJOR, + GLib::Version::MINOR + 1, + GLib::Version::MICRO)) + end + end +end Added: binding/ruby/glib-3.1.1/test/test_enum.rb (+111 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/test/test_enum.rb 2017-02-15 13:19:47 +0900 (1659066) @@ -0,0 +1,111 @@ +# Copyright (C) 2015 Ruby-GNOME2 Project Team +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +require 'test/unit' +require 'glib2' + +class TestEnum < Test::Unit::TestCase + def test_enum_by_symbol + original = [0x00c1].pack("U*") # A with acute + + assert_equal(GLib::UTF8.normalize(original, GLib::NormalizeMode::NFD), + GLib::UTF8.normalize(original, :nfd)) + assert_equal(GLib::UTF8.normalize(original, GLib::NormalizeMode::NFD), + GLib::UTF8.normalize(original, :NFD)) + + assert_raise(TypeError) do + GLib::UTF8.normalize(original, :unknown) + end + end + + def test_enum_by_string + original = [0x00c1].pack("U*") # A with acute + + assert_equal(GLib::UTF8.normalize(original, GLib::NormalizeMode::NFD), + GLib::UTF8.normalize(original, "nfd")) + assert_equal(GLib::UTF8.normalize(original, GLib::NormalizeMode::NFD), + GLib::UTF8.normalize(original, "NFD")) + + assert_raise(TypeError) do + GLib::UTF8.normalize(original, "unknown") + end + end + + def test_flags_simple + assert_key_file_load(GLib::KeyFile::KEEP_COMMENTS, :keep_comments) + assert_key_file_load(GLib::KeyFile::KEEP_COMMENTS, :KEEP_COMMENTS) + assert_key_file_load(GLib::KeyFile::KEEP_COMMENTS, "keep_comments") + assert_key_file_load(GLib::KeyFile::KEEP_COMMENTS, "KEEP_COMMENTS") + assert_key_file_load(GLib::KeyFile::KEEP_COMMENTS, "keep COMMENTS") + + assert_raise(ArgumentError) do + assert_key_file_load(GLib::KeyFile::KEEP_COMMENTS, :unknown) + end + + assert_raise(ArgumentError) do + assert_key_file_load(GLib::KeyFile::KEEP_COMMENTS, "UNKNOWN") + end + end + + def test_flags_by_array + assert_key_file_load(GLib::KeyFile::KEEP_COMMENTS | + GLib::KeyFile::KEEP_TRANSLATIONS, + [:keep_comments, :keep_translations]) + assert_key_file_load(GLib::KeyFile::KEEP_COMMENTS | + GLib::KeyFile::KEEP_TRANSLATIONS, + [:keep_COMMENTS, "KEEP_TRANSLATIONS"]) + assert_key_file_load(GLib::KeyFile::KEEP_COMMENTS | + GLib::KeyFile::KEEP_TRANSLATIONS, + ["keep_comments", "KEEP_translations"]) + assert_key_file_load(GLib::KeyFile::KEEP_COMMENTS | + GLib::KeyFile::KEEP_TRANSLATIONS, + [:keep_comments, GLib::KeyFile::KEEP_TRANSLATIONS]) + assert_key_file_load(GLib::KeyFile::KEEP_COMMENTS | + GLib::KeyFile::KEEP_TRANSLATIONS, + [:keep_comments, nil, :keep_translations]) + end + + def test_flags_or + assert_equal(GLib::KeyFile::KEEP_COMMENTS, + GLib::KeyFile::KEEP_COMMENTS | []) + assert_equal(GLib::KeyFile::KEEP_COMMENTS | + GLib::KeyFile::KEEP_TRANSLATIONS , + GLib::KeyFile::KEEP_COMMENTS | [:keep_translations]) + end + + private + def assert_key_file_load(flags, convenience_flags) + data = <<-EOD +[SECTION] +KEY=VALUE +# comment + +KEY[ja]=値 +EOD + + expected_key_file = GLib::KeyFile.new + expected_key_file.load_from_data(data, flags) + + actual_key_file = GLib::KeyFile.new + actual_key_file.load_from_data(data, convenience_flags) + + assert_equal(expected_key_file.get_value("SECTION", "KEY"), + actual_key_file.get_value("SECTION", "KEY")) + + assert_equal(expected_key_file.to_data, + actual_key_file.to_data) + end +end Added: binding/ruby/glib-3.1.1/test/test_file_utils.rb (+89 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/test/test_file_utils.rb 2017-02-15 13:19:47 +0900 (69c63eb) @@ -0,0 +1,89 @@ +# Copyright (C) 2015 Ruby-GNOME2 Project Team +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +class TestGLibFileUtils < Test::Unit::TestCase + include GLibTestUtils + + sub_test_case "#format_size_for_display" do + def setup + only_glib_version(2, 16, 0) + end + + def test_kb + assert_equal("1.0 KB", GLib.format_size_for_display(1024)) + end + + def test_10kb + assert_equal("10.0 KB", GLib.format_size_for_display(1024 * 10)) + end + + def test_mb + assert_equal("1.0 MB", GLib.format_size_for_display(1024 * 1024)) + end + + def test_gb + assert_equal("1.0 GB", GLib.format_size_for_display(1024 * 1024 * 1024)) + end + + def test_over_guint32_value + guint32_max = 2 ** 32 - 1 + assert_equal("4.0 GB", GLib.format_size_for_display(guint32_max + 1)) + end + end + + sub_test_case "#format_size" do + def setup + only_glib_version(2, 30, 0) + end + + def test_kb + assert_equal("1.0 kB", GLib.format_size(1000)) + end + + def test_mb + assert_equal("1.0 MB", GLib.format_size(1000 * 1000)) + end + + def test_gb + assert_equal("1.0 GB", GLib.format_size(1000 * 1000 * 1000)) + end + + def test_over_guint32_value + guint32_max = 2 ** 32 - 1 + assert_equal("4.3 GB", GLib.format_size(guint32_max + 1)) + end + + sub_test_case "flags" do + sub_test_case ":iec_units" do + def format_size(size) + GLib.format_size(size, :flags => :iec_units) + end + + def test_kib + assert_equal("1.0 KiB", format_size(1024)) + end + + def test_mib + assert_equal("1.0 MiB", format_size(1024 * 1024)) + end + + def test_gib + assert_equal("1.0 GiB", format_size(1024 * 1024 * 1024)) + end + end + end + end +end Added: binding/ruby/glib-3.1.1/test/test_flags.rb (+143 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/test/test_flags.rb 2017-02-15 13:19:47 +0900 (b47aef1) @@ -0,0 +1,143 @@ +# Copyright (C) 2015 Ruby-GNOME2 Project Team +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +require 'test/unit' +require 'glib2' + +class TestFlags < Test::Unit::TestCase + { + '<=>' => [ + [0b0000, 0.0, nil], + [0b0000, 0b0000, 0], + [0b0000, 0b0110, -1], + [0b0000, 0b1111, -1], + [0b0110, 0b0000, 1], + [0b0110, 0b0011, nil], + [0b0110, 0b0110, 0], + [0b0110, 0b0111, -1], + [0b0110, 0b1001, nil], + [0b0110, 0b1100, nil], + [0b0110, 0b1110, -1], + [0b0110, 0b1111, -1], + [0b1111, 0b0000, 1], + [0b1111, 0b0110, 1], + [0b1111, 0b1111, 0], + ], + '==' => [ + [0b0000, 0.0, nil], + [0b0000, 0b0000, true], + [0b0000, 0b0110, false], + [0b0000, 0b1111, false], + [0b0110, 0b0000, false], + [0b0110, 0b0011, false], + [0b0110, 0b0110, true], + [0b0110, 0b0111, false], + [0b0110, 0b1001, false], + [0b0110, 0b1100, false], + [0b0110, 0b1110, false], + [0b0110, 0b1111, false], + [0b1111, 0b0000, false], + [0b1111, 0b0110, false], + [0b1111, 0b1111, true], + ], + '>=' => [ + [0b0000, 0.0, nil], + [0b0000, 0b0000, true], + [0b0000, 0b0110, false], + [0b0000, 0b1111, false], + [0b0110, 0b0000, true], + [0b0110, 0b0011, false], + [0b0110, 0b0110, true], + [0b0110, 0b0111, false], + [0b0110, 0b1001, false], + [0b0110, 0b1100, false], + [0b0110, 0b1110, false], + [0b0110, 0b1111, false], + [0b1111, 0b0000, true], + [0b1111, 0b0110, true], + [0b1111, 0b1111, true], + ], + '<=' => [ + [0b0000, 0.0, nil], + [0b0000, 0b0000, true], + [0b0000, 0b0110, true], + [0b0000, 0b1111, true], + [0b0110, 0b0000, false], + [0b0110, 0b0011, false], + [0b0110, 0b0110, true], + [0b0110, 0b0111, true], + [0b0110, 0b1001, false], + [0b0110, 0b1100, false], + [0b0110, 0b1110, true], + [0b0110, 0b1111, true], + [0b1111, 0b0000, false], + [0b1111, 0b0110, false], + [0b1111, 0b1111, true], + ], + '>' => [ + [0b0000, 0.0, nil], + [0b0000, 0b0000, false], + [0b0000, 0b0110, false], + [0b0000, 0b1111, false], + [0b0110, 0b0000, true], + [0b0110, 0b0011, false], + [0b0110, 0b0110, false], + [0b0110, 0b0111, false], + [0b0110, 0b1001, false], + [0b0110, 0b1100, false], + [0b0110, 0b1110, false], + [0b0110, 0b1111, false], + [0b1111, 0b0000, true], + [0b1111, 0b0110, true], + [0b1111, 0b1111, false], + ], + '<' => [ + [0b0000, 0.0, nil], + [0b0000, 0b0000, false], + [0b0000, 0b0110, true], + [0b0000, 0b1111, true], + [0b0110, 0b0000, false], + [0b0110, 0b0011, false], + [0b0110, 0b0110, false], + [0b0110, 0b0111, true], + [0b0110, 0b1001, false], + [0b0110, 0b1100, false], + [0b0110, 0b1110, true], + [0b0110, 0b1111, true], + [0b1111, 0b0000, false], + [0b1111, 0b0110, false], + [0b1111, 0b1111, false], + ], + }.each do |operator, values| + values.each do |a, b, expected| + a_format = a.is_a?(Float) ? "%f" : "0b%04b" + b_format = b.is_a?(Float) ? "%f" : "0b%04b" + label_format = "#{a_format} %s #{b_format} == %s" + data((label_format % [a, operator, b, expected.inspect]), + { + :a => a, + :operator => operator, + :b => b, + :expected => expected, + }) + end + end + def test_flags_compare(data) + flags = GLib::KeyFile::Flags.new(data[:a]) + assert_equal(data[:expected], + flags.send(data[:operator], data[:b])) + end +end Added: binding/ruby/glib-3.1.1/test/test_glib2.rb (+153 -0) 100755 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/test/test_glib2.rb 2017-02-15 13:19:47 +0900 (a092e11) @@ -0,0 +1,153 @@ +# encoding: ascii-8bit +# +# Copyright (C) 2015 Ruby-GNOME2 Project Team +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +require 'test/unit' +require 'glib2' + +class TestGLib < Test::Unit::TestCase + + def test_version + assert_kind_of(Array, GLib::VERSION) + assert_equal(GLib::VERSION.length, 3) + assert(GLib::VERSION.all?{|i| i.is_a? Integer }) + + assert_kind_of(Integer, GLib::MAJOR_VERSION) + assert_kind_of(Integer, GLib::MINOR_VERSION) + assert_kind_of(Integer, GLib::MICRO_VERSION) + + assert_kind_of(Array, GLib::BINDING_VERSION) + assert_equal(GLib::BINDING_VERSION.length, 3) + assert(GLib::BINDING_VERSION.all?{|i| i.is_a? Integer }) + end + + def test_priority + assert_kind_of(Integer, GLib::PRIORITY_HIGH) + assert_kind_of(Integer, GLib::PRIORITY_DEFAULT) + assert_kind_of(Integer, GLib::PRIORITY_HIGH_IDLE) + assert_kind_of(Integer, GLib::PRIORITY_DEFAULT_IDLE) + assert_kind_of(Integer, GLib::PRIORITY_LOW) + end + + def test_int64 + end + + def test_convert + assert_kind_of(String, GLib.charset) + + sjis = "\202\261\202\361\202\311\202\277\202\315\220\242\212E" + euc = "\244\263\244\363\244\313\244\301\244\317\300\244\263\246" + utf8 = "\343\201\223\343\202\223\343\201\253\343\201\241\343\201\257\344\270\226\347\225\214" + assert_equal(GLib.convert(sjis, "UTF-8", "SHIFT_JIS"), utf8) + assert_equal(GLib.convert(sjis, "EUC-JP", "SHIFT_JIS"), euc) + assert_equal(GLib.convert(sjis, "SHIFT_JIS", "SHIFT_JIS"), sjis) + assert_equal(GLib.convert(euc, "UTF-8", "EUC-JP"), utf8) + assert_equal(GLib.convert(euc, "EUC-JP", "EUC-JP"), euc) + assert_equal(GLib.convert(euc, "SHIFT_JIS", "EUC-JP"), sjis) + assert_equal(GLib.convert(utf8, "UTF-8", "UTF-8"), utf8) + assert_equal(GLib.convert(utf8, "EUC-JP", "UTF-8"), euc) + assert_equal(GLib.convert(utf8, "SHIFT_JIS", "UTF-8"), sjis) + end + + def tet_locale_to_utf8 + assert_equal(Encoding::UTF8, + GLib.locale_to_utf8("ascii").encoding) + end + + def tet_locale_from_utf8 + assert_equal(Encoding::ASCII_8BIT, + GLib.locale_from_utf8("ascii").encoding) + end + + def tet_filename_to_utf8 + assert_equal(Encoding::UTF8, + GLib.filename_to_utf8("ascii.txt").encoding) + end + + def tet_filename_from_utf8 + assert_equal(Encoding::ASCII_8BIT, + GLib.filename_from_utf8("ascii.txt").encoding) + end + + # rb_define_module_function(mGLib, "filename_to_uri", rbglib_m_filename_to_uri, -1); + # rb_define_module_function(mGLib, "filename_from_uri", rbglib_m_filename_from_uri, 1); + + + def test_messages + #rb_define_module_function(mGLog, "set_handler", rbglib_m_log_set_handler, 2); + #rb_define_module_function(mGLog, "remove_handler", rbglib_m_log_remove_handler, 2); + end + + def test_object + assert_raises(GLib::NoPropertyError) { + GLib::Object.property("foo") + } + + assert_raises(GLib::NoSignalError) { + GLib::Object.signal("foo") + } + end + + def test_interface_extend + assert_raises(TypeError){ + Object.__send__(:include, GLib::TypePlugin) + } + end + + def test_signal_has_handler_pending + obj = GLib::Object.new + signal_name = "notify" + + assert(!obj.signal_has_handler_pending?(signal_name)) + + h = obj.signal_connect(signal_name){} + assert(obj.signal_has_handler_pending?(signal_name)) + + obj.signal_handler_block(h) { + assert(obj.signal_has_handler_pending?(signal_name, true)) + assert(!obj.signal_has_handler_pending?(signal_name, false)) + } + assert(obj.signal_has_handler_pending?(signal_name, false)) + + obj.signal_handler_disconnect(h) + assert(!obj.signal_has_handler_pending?(signal_name)) + + obj = nil + end + + def test_signal_handler_disconnect_and_gc + obj = GLib::Object.new + klass = Class.new + 1000.times { + a = klass.new + id = obj.signal_connect("notify") { p a } + obj.signal_handler_disconnect(id) + } + GC.start + ary = [] + ObjectSpace.each_object(klass) { |a| ary.push(a) } + assert_operator(ary.size, :<, 1000) + end + + def test_gtype + assert_equal(GLib::Object.gtype, GLib::Type["GObject"]) + assert_equal(GLib::Interface.gtype, GLib::Type["GInterface"]) + + obj = GLib::Object.new + assert_equal(obj.gtype, GLib::Object.gtype) + end +end Added: binding/ruby/glib-3.1.1/test/test_iochannel.rb (+289 -0) 100755 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/test/test_iochannel.rb 2017-02-15 13:19:47 +0900 (d823d03) @@ -0,0 +1,289 @@ +# Copyright (C) 2015 Ruby-GNOME2 Project Team +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +require 'test/unit' +require 'glib2' + +require 'tempfile' +require 'nkf' + +$KCODE = "U" unless defined?(:Encoding) + +class TestGIOChannel < Test::Unit::TestCase + def setup + @content = "aaa\nbbb\nccc\nあああ\n" + @sjis_content = NKF.nkf("-sW", @content) + + @file = Tempfile.new("glib2-content") + @file.open + @file.print(@content) + @file.close + + @sjis_file = Tempfile.new("glib2-sjis-content") + @sjis_file.open + @sjis_file.print(@sjis_content) + @sjis_file.close + end + + def test_open + write_test_file = Tempfile.new("glib2-write-test") + + io = GLib::IOChannel.open(@file.path) + io.close + + io = GLib::IOChannel.open(@file.path, "r") + assert_equal(@content, io.read) + io.close + + io = GLib::IOChannel.open(write_test_file.path, "w") + assert_raises(RuntimeError){ + assert_equal(@content, io.read) + } + io.close + + GLib::IOChannel.open(@file.path) do |_io| + assert_equal(@content, _io.read) + end + + GLib::IOChannel.open(@file.path, "r") do |_io| + assert_equal(@content, _io.read) + end + + GLib::IOChannel.open(write_test_file.path, "w") do |_io| + io = _io + assert_raises(RuntimeError) do + assert_equal(@content, io.read) + end + end + + assert_raises(GLib::IOChannelError) do + io.close + end + + assert_raises(GLib::FileError) do + GLib::IOChannel.new("foo") + end + end + + def test_getc + io = GLib::IOChannel.new(@file.path) + ["a", "b", "c", "あ"].each do |v| + 3.times do + assert_equal(v.unpack("U")[0], io.getc) + end + assert_equal("\n".unpack("U")[0], io.getc) + end + assert_equal(nil, io.getc) + io.close + end + + def test_each_char + text =****@conte*****(//u) + io = GLib::IOChannel.new(@file.path) + i = 0 + io.each_char {|ch| + assert_equal(text[i].unpack("U")[0], ch) + i += 1 + } + io.close + end + + def test_readchar + io = GLib::IOChannel.new(@file.path) + text =****@conte*****(//u) + text.each do |v| + assert_equal(v.unpack("U")[0], io.readchar) + end + assert_raises(EOFError) { + io.readchar + } + io.close + end + + def test_gets + io = GLib::IOChannel.new(@file.path) + assert_equal("aaa\n", io.gets) + assert_equal("bbb\n", io.gets) + assert_equal("ccc\n", io.gets) + assert_equal("あああ\n", io.gets) + assert_equal(nil, io.gets) + io.close + + io = GLib::IOChannel.new(@file.path) + assert_equal("aaa\nbbb\n", io.gets("bbb\n")) + assert_equal("ccc\nあああ\n", io.gets("bbb\n")) + assert_equal(nil, io.gets("bbb\n")) + io.close + end + + def test_readline + io = GLib::IOChannel.new(@file.path) + assert_equal("aaa\n", io.readline) + assert_equal("bbb\n", io.readline) + assert_equal("ccc\n", io.readline) + assert_equal("あああ\n", io.readline) + assert_raises(EOFError) { + io.readline + } + io.close + + io = GLib::IOChannel.new(@file.path) + assert_equal("aaa\nbbb\n", io.readline("bbb\n")) + assert_equal("ccc\nあああ\n", io.readline("bbb\n")) + assert_raises(EOFError) { + io.readline("bbb\n") + } + io.close + end + + def test_each_line + lines = ["aaa\n", "bbb\n", "ccc\n", "あああ\n"] + io = GLib::IOChannel.new(@file.path) + i = 0 + io.each {|line| + assert_equal(lines[i], line) + i += 1 + } + io.close + + io = GLib::IOChannel.new(@file.path) + assert_raises(RuntimeError) { + io.each {|line| + raise "test" + } + } + io.close + + io = GLib::IOChannel.new(@file.path) + i = 0 + io.each_line {|line| + assert_equal(lines[i], line) + i += 1 + } + io.close + + #Test for Enumerable + GLib::IOChannel.open(@file.path) do |_io| + io = _io + io.each_with_index do |line, _i| + assert_equal(lines[_i], line) + end + end + + assert_raises(ArgumentError) do + io.each + end + end + + def test_read + io = GLib::IOChannel.new(@file.path) + assert_equal(@content, io.read) + io.close + + io = GLib::IOChannel.new(@file.path) + assert_equal(@content, io.read(100)) + io.close + + io = GLib::IOChannel.new(@file.path) + assert_equal("aaa\nbbb\n", io.read(8)) + assert_equal("ccc\n", io.read(4)) + assert_equal("あああ\n", io.read(10)) + assert_equal("", io.read(10)) + assert_equal("", io.read(10)) + io.close + end + + def test_seek + text = @content + io = GLib::IOChannel.new(@file.path) + io.seek(5) + assert_equal(text.unpack("U*")[5], io.getc) + io.seek(6, GLib::IOChannel::SEEK_SET) + assert_equal(text.unpack("U*")[6], io.getc) + + io.seek(1, GLib::IOChannel::SEEK_CUR) + assert_equal(text.unpack("U*")[8], io.getc) + + io.pos = 0 + assert_equal(text.unpack("U*")[0], io.getc) + + io.set_pos(2) + assert_equal(text.unpack("U*")[2], io.getc) + + io.close + end + + def test_write + write_test_file = Tempfile.new("glib2-write-test") + + io = GLib::IOChannel.new(write_test_file.path, "w") + io.write("a\n") + io.write("あいう\n") + io.printf("a%sa\n", "a") + io.print("a", 100, "a\n") + io.puts("b", 200, "b") + io.putc("c") + io.putc("c".unpack("U")[0]) + io.putc("cc".unpack("U")[0]) + io.putc("あ".unpack("U")[0]) + io.putc("あ") + io.putc("あい") #Ignore 2nd char + io.putc("aあ") #Ignore 2nd char + io.close + + # check them + io = GLib::IOChannel.new(write_test_file.path, "r") + assert_equal("a\n", io.gets) + assert_equal("あいう\n", io.gets) + assert_equal("aaa\n", io.gets) + assert_equal("a100a\n", io.gets) + assert_equal("b\n", io.gets) + assert_equal("200\n", io.gets) + assert_equal("b\n", io.gets) + assert_equal("c".unpack("U")[0], io.getc) + assert_equal("c".unpack("U")[0], io.getc) + assert_equal("c".unpack("U")[0], io.getc) + assert_equal("あ".unpack("U")[0], io.getc) + assert_equal("あ".unpack("U")[0], io.getc) + assert_equal("あ".unpack("U")[0], io.getc) + assert_equal("a".unpack("U")[0], io.getc) + io.close + end + + def test_encoding + io = GLib::IOChannel.new(@file.path) + assert_equal("UTF-8", io.encoding) + io.encoding = "Shift_JIS" + assert_equal("Shift_JIS", io.encoding) + assert_raises(GLib::ConvertError) { + io.read + } + io.close + + io = GLib::IOChannel.new(@sjis_file.path) + io.encoding = "Shift_JIS" + assert_equal("Shift_JIS", io.encoding) + assert_equal(@content, io.read) + io.close + end + + def test_error + assert_raises(GLib::FileError) { + # No such file or directory + GLib::IOChannel.new("foo") + } + end +end Added: binding/ruby/glib-3.1.1/test/test_key_file.rb (+56 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/test/test_key_file.rb 2017-02-15 13:19:47 +0900 (9e4dbb6) @@ -0,0 +1,56 @@ +# Copyright (C) 2015 Ruby-GNOME2 Project Team +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +require 'tempfile' + +class TestGLibKeyFile < Test::Unit::TestCase + include GLibTestUtils + + def test_load_from_dirs + only_glib_version(2, 14, 0) + + key_file = GLib::KeyFile.new + assert_raise(GLib::KeyFileError::NotFound) do + key_file.load_from_dirs("non-existent") + end + + temp = Tempfile.new("key-file") + base_name = File.basename(temp.path) + search_dirs = [File.dirname(temp.path)] + assert_raise(GLib::KeyFileError::NotFound) do + key_file.load_from_dirs("non-existent", search_dirs) + end + if GLib.check_version?(2, 31, 2) + assert_equal(temp.path, key_file.load_from_dirs(base_name, search_dirs)) + else + assert_raise(GLib::KeyFileError::NotFound) do + key_file.load_from_dirs(base_name, search_dirs) + end + end + temp.puts(<<-EOK) +[General] +key = value +EOK + temp.close + assert_equal(temp.path, key_file.load_from_dirs(base_name, search_dirs)) + end + + def test_desktop_constants + only_glib_version(2, 14, 0) + assert_equal("Desktop Entry", GLib::KeyFile::DESKTOP_GROUP) + assert_equal("URL", GLib::KeyFile::DESKTOP_KEY_URL) + end +end Added: binding/ruby/glib-3.1.1/test/test_mkenums.rb (+39 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/test/test_mkenums.rb 2017-02-15 13:19:47 +0900 (61a6855) @@ -0,0 +1,39 @@ +# Copyright (C) 2015 Ruby-GNOME2 Project Team +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +require 'glib-mkenums' + +class TestGLibMkEnums < Test::Unit::TestCase + def test_parse_flags + source = <<-EOS + G_MARKUP_COLLECT_INVALID, + G_MARKUP_COLLECT_STRING, + G_MARKUP_COLLECT_STRDUP, + G_MARKUP_COLLECT_BOOLEAN, + G_MARKUP_COLLECT_TRISTATE, + + G_MARKUP_COLLECT_OPTIONAL = (1 << 16) +EOS + enum = GLib::EnumDefinition.new("GMarkupCollectType", source, 'G_TYPE_') + assert_equal([["G_MARKUP_COLLECT_INVALID", "invalid"], + ["G_MARKUP_COLLECT_STRING", "string"], + ["G_MARKUP_COLLECT_STRDUP", "strdup"], + ["G_MARKUP_COLLECT_BOOLEAN", "boolean"], + ["G_MARKUP_COLLECT_TRISTATE", "tristate"], + ["G_MARKUP_COLLECT_OPTIONAL", "optional"]], + enum.constants) + end +end Added: binding/ruby/glib-3.1.1/test/test_poll_fd.rb (+26 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/test/test_poll_fd.rb 2017-02-15 13:19:47 +0900 (9a15717) @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2013-2015 Ruby-GNOME2 Project Team +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +class TestGLibPollFD < Test::Unit::TestCase + include GLibTestUtils + + def test_fd + poll_fd = GLib::PollFD.new(0, GLib::IOChannel::IN, 0) + assert_equal(0, poll_fd.fd) + end +end Added: binding/ruby/glib-3.1.1/test/test_signal.rb (+34 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/test/test_signal.rb 2017-02-15 13:19:47 +0900 (161fc15) @@ -0,0 +1,34 @@ +# Copyright (C) 2015 Ruby-GNOME2 Project Team +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +class TestSignal < Test::Unit::TestCase + def test_signal_flags + assert_const_defined(GLib, :SignalFlags) + assert_kind_of(GLib::SignalFlags, GLib::Signal::RUN_FIRST) + assert_equal(GLib::SignalFlags::MASK, GLib::Signal::FLAGS_MASK) + end + + def test_connect_flags + assert_const_defined(GLib, :ConnectFlags) + assert_kind_of(GLib::ConnectFlags, GLib::Signal::CONNECT_AFTER) + end + + def test_signal_match_type + assert_const_defined(GLib, :SignalMatchType) + assert_kind_of(GLib::SignalMatchType, GLib::Signal::MATCH_ID) + assert_equal(GLib::SignalMatchType::MASK, GLib::Signal::MATCH_MASK) + end +end Added: binding/ruby/glib-3.1.1/test/test_source.rb (+74 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/test/test_source.rb 2017-02-15 13:19:47 +0900 (3a92ed8) @@ -0,0 +1,74 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2013-2015 Ruby-GNOME2 Project Team +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +class TestGLibSource < Test::Unit::TestCase + include GLibTestUtils + + def test_time + context = GLib::MainContext.default + source = GLib::Idle.source_new + id = source.attach(context) + begin + time = source.time + assert_operator(0, :<, time) + ensure + GLib::Source.remove(id) + end + end + + def test_destroy + # only_glib_version(2, 35, 4) + # GMainContext may be freed before GSource by Ruby's GC. + # If GMainContext is freed before GSource, GLib 2.35.3 or earlier is + # crashed. + # + # See also: + # * https://bugzilla.gnome.org/show_bug.cgi?id=661767 + # * https://git.gnome.org/browse/glib/commit/?id=26056558be4656ee6e891a4fae5d4198de7519cf + + context = GLib::MainContext.new + source = GLib::Idle.source_new + id = source.attach(context) + assert_not_nil(context.find_source(id)) + source.destroy + assert_nil(context.find_source(id)) + source = nil + GC.start + end + + def test_name + only_glib_version(2, 26, 0) + + source = GLib::Idle.source_new + assert_nil(source.name) + + source_name = "glib source" + source.name = source_name + assert_equal(source_name, source.name) + end + + def test_ready_time + only_glib_version(2, 36, 0) + + source = GLib::Idle.source_new + + ready_time = 5 + source.ready_time = 5 + assert_equal(ready_time, source.ready_time) + end +end Added: binding/ruby/glib-3.1.1/test/test_spawn.rb (+48 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/test/test_spawn.rb 2017-02-15 13:19:47 +0900 (5e42995) @@ -0,0 +1,48 @@ +# Copyright (C) 2015 Ruby-GNOME2 Project Team +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +require 'rbconfig' + +class TestGLibSpawn < Test::Unit::TestCase + include GLibTestUtils + + def setup + end + + def teardown + end + + def test_async_keep_environment + if File.exist?('/bin/true') + assert_nothing_raised do + GLib::Spawn.async(Dir.pwd, ['/bin/true'], nil, 0) + end + end + end + + def test_async_clear_environment + if RbConfig.respond_to?(:ruby) + ruby = RbConfig.ruby + else + ruby = File.join(RbConfig::CONFIG['bindir'], + RbConfig::CONFIG['RUBY_INSTALL_NAME'] + + RbConfig::CONFIG['EXEEXT']) + end + pid = GLib::Spawn.async(Dir.pwd, [ruby, '-e', 'exit 1 unless ENV.empty?'], [], GLib::Spawn::DO_NOT_REAP_CHILD) + _, status = *Process.waitpid2(pid) + assert status.success? + end +end Added: binding/ruby/glib-3.1.1/test/test_timeout.rb (+42 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/test/test_timeout.rb 2017-02-15 13:19:47 +0900 (c87307e) @@ -0,0 +1,42 @@ +# Copyright (C) 2015 Ruby-GNOME2 Project Team +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +class TestGLibTimeout < Test::Unit::TestCase + include GLibTestUtils + + def setup + @id = nil + end + + def teardown + GLib::Source.remove(@id) if @id + end + + def test_timeout_add_priority + priority = GLib::PRIORITY_HIGH + @id = GLib::Timeout.add(10, priority) + source = GLib::MainContext.default.find_source(@id) + assert_equal(priority, source.priority) + end + + def test_timeout_add_seconds_priority + only_glib_version(2, 14, 0) + priority = GLib::PRIORITY_HIGH + @id = GLib::Timeout.add_seconds(10, priority) + source = GLib::MainContext.default.find_source(@id) + assert_equal(priority, source.priority) + end +end Added: binding/ruby/glib-3.1.1/test/test_unicode.rb (+408 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/test/test_unicode.rb 2017-02-15 13:19:47 +0900 (df959b7) @@ -0,0 +1,408 @@ +# Copyright (C) 2015 Ruby-GNOME2 Project Team +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +class TestGLibUnicode < Test::Unit::TestCase + include GLibTestUtils + + def test_gunicode_type + assert_nothing_raised do + GLib::Unicode::CONTROL + end + end + + def test_gunicode_break_type + assert_nothing_raised do + GLib::Unicode::BREAK_MANDATORY + end + end + + def test_unichar_alnum? + assert(GLib::UniChar.alnum?(unichar("a"))) + assert(GLib::UniChar.alnum?(unichar("1"))) + assert(!GLib::UniChar.alnum?(unichar("!"))) + end + + def test_unichar_alpha? + assert(GLib::UniChar.alpha?(unichar("a"))) + assert(GLib::UniChar.alpha?(unichar("A"))) + assert(!GLib::UniChar.alpha?(unichar("1"))) + end + + def test_unichar_cntrl? + assert(GLib::UniChar.cntrl?(unichar("\t"))) + assert(!GLib::UniChar.cntrl?(unichar("\h"))) + assert(!GLib::UniChar.cntrl?(unichar("a"))) + assert(!GLib::UniChar.cntrl?(unichar("1"))) + end + + def test_unichar_digit? + assert(GLib::UniChar.digit?(unichar("1"))) + assert(!GLib::UniChar.digit?(unichar("a"))) + end + + def test_unichar_graph? + assert(GLib::UniChar.graph?(unichar("a"))) + assert(!GLib::UniChar.graph?(unichar(" "))) + assert(!GLib::UniChar.graph?(unichar("\t"))) + end + + def test_unichar_lower? + assert(GLib::UniChar.lower?(unichar("a"))) + assert(!GLib::UniChar.lower?(unichar("A"))) + assert(!GLib::UniChar.lower?(unichar("1"))) + end + + def test_unichar_print? + assert(GLib::UniChar.print?(unichar("a"))) + assert(GLib::UniChar.print?(unichar(" "))) + assert(!GLib::UniChar.print?(unichar("\t"))) + end + + def test_unichar_punct? + assert(GLib::UniChar.punct?(unichar(","))) + assert(GLib::UniChar.punct?(unichar("."))) + assert(!GLib::UniChar.punct?(unichar("a"))) + assert(!GLib::UniChar.punct?(unichar("\t"))) + end + + def test_unichar_space? + assert(GLib::UniChar.space?(unichar(" "))) + assert(GLib::UniChar.space?(unichar("\t"))) + assert(GLib::UniChar.space?(unichar("\r"))) + assert(GLib::UniChar.space?(unichar("\n"))) + assert(!GLib::UniChar.space?(unichar("a"))) + end + + def test_unichar_upper? + assert(GLib::UniChar.upper?(unichar("A"))) + assert(!GLib::UniChar.upper?(unichar("a"))) + assert(!GLib::UniChar.upper?(unichar("1"))) + end + + def test_unichar_xdigit? + assert(GLib::UniChar.xdigit?(unichar("1"))) + assert(GLib::UniChar.xdigit?(unichar("a"))) + assert(GLib::UniChar.xdigit?(unichar("A"))) + assert(GLib::UniChar.xdigit?(unichar("F"))) + assert(!GLib::UniChar.xdigit?(unichar("X"))) + end + + def test_unichar_title? + end + + def test_unichar_defined? + end + + def test_unichar_wide? + assert(GLib::UniChar.wide?(unichar("あ"))) + assert(GLib::UniChar.wide?(unichar("A"))) + assert(!GLib::UniChar.wide?(unichar("a"))) + end + + def test_unichar_wide_cjk? + only_glib_version(2, 12, 0) + assert(GLib::UniChar.wide_cjk?(unichar("あ"))) + assert(GLib::UniChar.wide_cjk?(0xD55C)) # HANGUL SYLLABLE HAN + assert(!GLib::UniChar.wide_cjk?(unichar("a"))) + end + + def test_unichar_to_upper + assert_equal(unichar("A"), GLib::UniChar.to_upper(unichar("a"))) + assert_equal(unichar("A"), GLib::UniChar.to_upper(unichar("A"))) + assert_equal(unichar("*"), GLib::UniChar.to_title(unichar("*"))) + end + + def test_unichar_to_lower + assert_equal(unichar("a"), GLib::UniChar.to_lower(unichar("A"))) + assert_equal(unichar("a"), GLib::UniChar.to_lower(unichar("a"))) + assert_equal(unichar("*"), GLib::UniChar.to_title(unichar("*"))) + end + + def test_unichar_to_title + assert_equal(unichar("A"), GLib::UniChar.to_title(unichar("a"))) + assert_equal(unichar("A"), GLib::UniChar.to_title(unichar("A"))) + assert_equal(unichar("*"), GLib::UniChar.to_title(unichar("*"))) + end + + def test_unichar_digit_value + assert_equal(0, GLib::UniChar.digit_value(unichar("0"))) + assert_equal(9, GLib::UniChar.digit_value(unichar("9"))) + assert_equal(-1, GLib::UniChar.digit_value(unichar("a"))) + end + + def test_unichar_xdigit_value + assert_equal(0, GLib::UniChar.xdigit_value(unichar("0"))) + assert_equal(9, GLib::UniChar.xdigit_value(unichar("9"))) + assert_equal(10, GLib::UniChar.xdigit_value(unichar("a"))) + assert_equal(15, GLib::UniChar.xdigit_value(unichar("F"))) + assert_equal(-1, GLib::UniChar.xdigit_value(unichar("g"))) + end + + def test_unichar_type + assert_equal(GLib::Unicode::DECIMAL_NUMBER, + GLib::UniChar.type(unichar("0"))) + assert_equal(GLib::Unicode::LOWERCASE_LETTER, + GLib::UniChar.type(unichar("a"))) + assert_equal(GLib::Unicode::UPPERCASE_LETTER, + GLib::UniChar.type(unichar("A"))) + end + + def test_unichar_break_type + assert_equal(GLib::Unicode::BREAK_HYPHEN, + GLib::UniChar.break_type(unichar("-"))) + assert_equal(GLib::Unicode::BREAK_NUMERIC, + GLib::UniChar.break_type(unichar("0"))) + end + + def test_unicode_canonical_ordering + original = [unichar("a"), 0x0308, 0x0323, + unichar("e"), 0x0304, 0x0301, 0x0323].pack("U*") + expected = [unichar("a"), 0x0323, 0x0308, + unichar("e"), 0x0323, 0x0304, 0x0301].pack("U*") + assert_equal(utf8_to_utf32(expected), + GLib::Unicode.canonical_ordering(utf8_to_utf32(original))) + end + + def test_unicode_canonical_decomposition + a_with_acute = 0x00E1 + expected = [unichar("a"), 0x0301].pack("U*") + assert_equal(utf8_to_utf32(expected), + GLib::Unicode.canonical_decomposition(a_with_acute)) + + hiragana_ga = 0x304C + hiragana_ka = 0x304B + expected = [hiragana_ka, 0x3099].pack("U*") + assert_equal(utf8_to_utf32(expected), + GLib::Unicode.canonical_decomposition(hiragana_ga)) + end + + def test_unichar_get_mirror_char + assert_equal(unichar("("), GLib::UniChar.get_mirror_char(unichar(")"))) + assert_equal(unichar(")"), GLib::UniChar.get_mirror_char(unichar("("))) + assert_equal(unichar("x"), GLib::UniChar.get_mirror_char(unichar("x"))) + end + + def test_unichar_get_script + only_glib_version(2, 14, 0) + assert_equal(GLib::Unicode::SCRIPT_HIRAGANA, + GLib::UniChar.get_script(unichar("あ"))) + end + + def test_utf8_get_char + assert_equal(utf8_to_utf32("あ").unpack("L*")[0], + GLib::UTF8.get_char("あ")) + + assert_equal(utf8_to_utf32("あ").unpack("L*")[0], + GLib::UTF8.get_char("あ", true)) + partial_input = "あ".unpack("c*")[0..-2].pack("c*") + assert_equal(-2, GLib::UTF8.get_char(partial_input, true)) + invalid_input = "あ".unpack("c*")[2..-1].pack("c*") + assert_equal(-1, GLib::UTF8.get_char(invalid_input, true)) + end + + def test_utf8_size + assert_equal(1, GLib::UTF8.size("あ")) + assert_equal(2, GLib::UTF8.size("あい")) + end + + def test_utf8_reverse + assert_equal("おえういあ", GLib::UTF8.reverse("あいうえお")) + end + + def test_utf8_validate + assert(GLib::UTF8.validate("あ")) + assert(!GLib::UTF8.validate(binary("あ")[1..-1])) + end + + def test_utf8_upcase + assert_equal("ABCあいう", GLib::UTF8.upcase("aBcあいう")) + end + + def test_utf8_downcase + assert_equal("abcあいう", GLib::UTF8.downcase("aBcあいう")) + end + + def test_utf8_casefold + assert_equal(GLib::UTF8.casefold("AbCあいう"), + GLib::UTF8.casefold("aBcあいう")) + end + + def test_utf8_normalize + original = [0x00c1].pack("U*") # A with acute + + nfd = [0x0041, 0x0301].pack("U*") + assert_equal(nfd, + GLib::UTF8.normalize(original, GLib::NormalizeMode::NFD)) + + nfc = [0x00c1].pack("U*") + assert_equal(nfc, + GLib::UTF8.normalize(original, GLib::NormalizeMode::NFC)) + + nfkd = [0x0041, 0x0301].pack("U*") + assert_equal(nfkd, + GLib::UTF8.normalize(original, GLib::NormalizeMode::NFKD)) + + nfkc = [0x00c1].pack("U*") + assert_equal(nfkc, + GLib::UTF8.normalize(original, GLib::NormalizeMode::NFKC)) + end + + def test_utf8_collate + only_glib_version(2, 16, 0) + assert_operator(0, :>, GLib::UTF8.collate("あ", "い")) + assert_operator(0, :<, GLib::UTF8.collate("い", "あ")) + assert_equal(0, GLib::UTF8.collate("あ", "あ")) + end + + def test_utf8_collate_key + only_glib_version(2, 16, 0) + assert_operator(0, :>, + GLib::UTF8.collate_key("あ") <=> + GLib::UTF8.collate_key("い")) + assert_operator(0, :<, + GLib::UTF8.collate_key("い") <=> + GLib::UTF8.collate_key("あ")) + assert_equal(0, + GLib::UTF8.collate_key("あ") <=> + GLib::UTF8.collate_key("あ")) + end + + def test_utf8_collate_key_for_filename + assert_equal(["event.c", "event.h", "eventgenerator.c"], + ["event.c", "eventgenerator.c", "event.h"].sort_by do |f| + GLib::UTF8.collate_key(f, true) + end) + + assert_equal(["file1", "file5", "file10"], + ["file1", "file10", "file5"].sort_by do |f| + GLib::UTF8.collate_key(f, true) + end) + end + + def test_utf8_to_utf16 + assert_equal(utf8_to_utf16("あいうえお"), + GLib::UTF8.to_utf16("あいうえお")) + end + + def test_utf8_to_ucs4 + assert_equal(utf8_to_utf32("あいうえお"), + GLib::UTF8.to_ucs4("あいうえお")) + + assert_raise(GLib::ConvertError) do + GLib::UTF8.to_ucs4(binary("あいうえお")[1..-1]) + end + assert_nothing_raised do + GLib::UTF8.to_ucs4(binary("あいうえお")[1..-1], true) + end + end + + def test_utf16_to_ucs4 + assert_equal(utf8_to_utf32("あいうえお"), + GLib::UTF16.to_ucs4(utf8_to_utf16("あいうえお"))) + end + + def test_utf16_to_utf8 + assert_equal("あいうえお", + GLib::UTF16.to_utf8(utf8_to_utf16("あいうえお"))) + end + + + def test_ucs4_to_utf16 + assert_equal(utf8_to_utf16("あいうえお"), + GLib::UCS4.to_utf16(utf8_to_utf32("あいうえお"))) + + assert_raise(GLib::ConvertError) do + GLib::UCS4.to_utf16(binary(utf8_to_utf32("あいうえお"))[1..-1]) + end + end + + def test_ucs4_to_utf8 + assert_equal("あいうえお", + GLib::UCS4.to_utf8(utf8_to_utf32("あいうえお"))) + end + + def test_unichar_to_utf8 + assert_equal("あ", + GLib::UniChar.to_utf8(utf8_to_utf32("あ").unpack("L*")[0])) + end + + def test_unichar_combining_class + only_glib_version(2, 14, 0) + assert_equal(0, GLib::UniChar.combining_class(unichar("a"))) + assert_equal(230, GLib::UniChar.combining_class(unichar("́"))) + end + + def test_unichar_mark? + only_glib_version(2, 14, 0) + assert(!GLib::UniChar.mark?(unichar("a"))) + assert(!GLib::UniChar.mark?(0x200E)) # LEFT-TO-RIGHT MARK + assert(GLib::UniChar.mark?(0x1DC3)) # COMBINING SUSPENSION MARK + end + + def test_unichar_zero_width? + only_glib_version(2, 14, 0) + assert(!GLib::UniChar.zero_width?(unichar("a"))) + assert(GLib::UniChar.zero_width?(0x200B)) # ZERO WIDTH SPACE + end + + private + def unichar(char) + GLib::UTF8.get_char(char) + end + + def utf8_to_utf32(string) + if string.respond_to?(:encode) + if little_endian? + string.encode("UTF-32LE") + else + string.encode("UTF-32BE") + end + else + require_uconv + Uconv.u8tou4(string) + end + end + + def utf8_to_utf16(string) + if string.respond_to?(:encode) + if little_endian? + string.encode("UTF-16LE") + else + string.encode("UTF-16BE") + end + else + require_uconv + Uconv.u8tou16(string) + end + end + + def require_uconv + require 'uconv' + rescue LoadError + omit("Need uconv to run this test.") + end + + def binary(string) + if string.respond_to?(:force_encoding) + string.force_encoding("ascii-8bit") + end + string + end + + def little_endian? + [1].pack("v") == [1].pack("S") + end +end Added: binding/ruby/glib-3.1.1/test/test_utils.rb (+51 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/test/test_utils.rb 2017-02-15 13:19:47 +0900 (4d03666) @@ -0,0 +1,51 @@ +# Copyright (C) 2015 Ruby-GNOME2 Project Team +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +class TestGLibUtils < Test::Unit::TestCase + include GLibTestUtils + + def test_user_cache_dir + only_glib_version(2, 6, 0) + assert_kind_of(String, GLib.user_cache_dir) + end + + def test_user_data_dir + only_glib_version(2, 6, 0) + assert_kind_of(String, GLib.user_data_dir) + end + + def test_user_config_dir + only_glib_version(2, 6, 0) + assert_kind_of(String, GLib.user_config_dir) + end + + def test_system_data_dirs + only_glib_version(2, 6, 0) + assert_kind_of(Array, GLib.system_data_dirs) + end + + def test_system_config_dirs + only_glib_version(2, 6, 0) + assert_kind_of(Array, GLib.system_config_dirs) + end + + def test_get_user_special_dir + only_glib_version(2, 14, 0) + assert_nothing_raised do + GLib.get_user_special_dir(GLib::UserDirectory::DESKTOP) + end + end +end Added: binding/ruby/glib-3.1.1/test/test_value.rb (+36 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/test/test_value.rb 2017-02-15 13:19:47 +0900 (4b54203) @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2013-2015 Ruby-GNOME2 Project Team +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +class TestGLibValue < Test::Unit::TestCase + include GLibTestUtils + + def test_type + value = GLib::Value.new(GLib::Type::UINT, 29) + assert_equal(GLib::Type::UINT, value.type) + end + + def test_value + value = GLib::Value.new(GLib::Type::UINT, 29) + assert_equal(29, value.value) + end + + def test_no_value + value = GLib::Value.new(GLib::Type::UINT) + assert_equal(0, value.value) + end +end Added: binding/ruby/glib-3.1.1/test/test_win32.rb (+27 -0) 100644 =================================================================== --- /dev/null +++ binding/ruby/glib-3.1.1/test/test_win32.rb 2017-02-15 13:19:47 +0900 (6683976) @@ -0,0 +1,27 @@ +# Copyright (C) 2015 Ruby-GNOME2 Project Team +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +class TestGLibWin32 < Test::Unit::TestCase + include GLibTestUtils + + def test_get_package_install_directory_of_module + only_win32 + only_glib_version(2, 16, 0) + + assert_equal("FIXME", + GLib::Win32.get_package_installation_directory_of_module) + end +end